blob: eb1f62cd524019aef3aeca52e3f15c61ada6edbc [file] [log] [blame]
Brad Bishopc7d1cd92020-09-09 09:57:07 -04001From 707a3a52d5884078e2173571d421829449b54225 Mon Sep 17 00:00:00 2001
2From: Supreeth Venkatesh <supreeth.venkatesh@amd.com>
3Date: Tue, 18 Aug 2020 13:47:55 -0500
4Subject: [PATCH 1/1] Amd power control modifications for EthanolX
5Content-Type: text/plain; charset="us-ascii"
6Content-Transfer-Encoding: 7bit
7
8This patch modifies recipes-x86 chassis manager code to support AMD
9EthanolX customer reference board.
10The configuration Json file is updated with the GPIO signals present on
11AMD EthanolX file.
12The Service file is updated to indicate this is modified version of x86
13power control suitable for AMD platforms.
14The source file is modified to remove Intel specific SIO signals and
15functions, modify it to support AMD specific GPIO signals.
16
17Further, Beep() is replaced by lighting up Fault LED, as AMD CRBs does
18not have a beeper.
19
20Signed-off-by: Supreeth Venkatesh <supreeth.venkatesh@amd.com>
21---
22 .../config/power-config-host0.json | 23 +-
23 ...nbmc_project.Chassis.Control.Power.service | 2 +-
24 power-control-x86/src/power_control.cpp | 335 ++----------------
25 3 files changed, 44 insertions(+), 316 deletions(-)
26
27diff --git a/power-control-x86/config/power-config-host0.json b/power-control-x86/config/power-config-host0.json
28index 567f419..9e1a54a 100644
29--- a/power-control-x86/config/power-config-host0.json
30+++ b/power-control-x86/config/power-config-host0.json
31@@ -1,15 +1,14 @@
32 {
33- "IdButton": "ID_BUTTON",
34- "NMIButton": "NMI_BUTTON",
35- "NMIOut": "NMI_OUT",
36- "PostComplete": "POST_COMPLETE",
37- "PwrButton": "POWER_BUTTON",
38- "PwrOK": "PS_PWROK",
39- "PwrOut": "POWER_OUT",
40- "RstButton": "RESET_BUTTON",
41- "RstOut": "RESET_OUT",
42- "SIOOnCtl": "SIO_ONCONTROL",
43- "SIOPwrGd": "SIO_POWER_GOOD",
44- "SIOS5": "SIO_S5"
45+ "IdButton": "CHASSIS_ID_BTN",
46+ "NMIButton": "MON_P0_NMI_BTN",
47+ "NMIOut": "ASSERT_NMI_BTN",
48+ "PostComplete": "MON_PWROK",
49+ "PwrButton": "MON_P0_PWR_BTN",
50+ "PwrOK": "MON_P0_PWR_GOOD",
51+ "PwrOut": "ASSERT_PWR_BTN",
52+ "RstButton": "MON_P0_RST_BTN",
53+ "RstOut": "ASSERT_RST_BTN",
54+ "BmcReady": "ASSERT_BMC_READY",
55+ "FaultLed": "FAULT_LED"
56 }
57
58diff --git a/power-control-x86/service_files/xyz.openbmc_project.Chassis.Control.Power.service b/power-control-x86/service_files/xyz.openbmc_project.Chassis.Control.Power.service
59index a80235e..43cf1a7 100644
60--- a/power-control-x86/service_files/xyz.openbmc_project.Chassis.Control.Power.service
61+++ b/power-control-x86/service_files/xyz.openbmc_project.Chassis.Control.Power.service
62@@ -1,5 +1,5 @@
63 [Unit]
64-Description=Intel Power Control
65+Description=Amd Power Control
66
67 [Service]
68 Restart=always
69diff --git a/power-control-x86/src/power_control.cpp b/power-control-x86/src/power_control.cpp
70index b8bb313..73ddf71 100644
71--- a/power-control-x86/src/power_control.cpp
72+++ b/power-control-x86/src/power_control.cpp
73@@ -42,9 +42,8 @@ static std::string powerOutName;
74 static std::string powerOkName;
75 static std::string resetOutName;
76 static std::string nmiOutName;
77-static std::string sioPwrGoodName;
78-static std::string sioOnControlName;
79-static std::string sioS5Name;
80+static std::string bmcReadyName;
81+static std::string faultLedName;
82 static std::string postCompleteName;
83 static std::string powerButtonName;
84 static std::string resetButtonName;
85@@ -70,11 +69,9 @@ const static constexpr int powerPulseTimeMs = 200;
86 const static constexpr int forceOffPulseTimeMs = 15000;
87 const static constexpr int resetPulseTimeMs = 500;
88 const static constexpr int powerCycleTimeMs = 5000;
89-const static constexpr int sioPowerGoodWatchdogTimeMs = 1000;
90 const static constexpr int psPowerOKWatchdogTimeMs = 8000;
91 const static constexpr int gracefulPowerOffTimeMs = 60000;
92 const static constexpr int warmResetCheckTimeMs = 500;
93-const static constexpr int buttonMaskTimeMs = 60000;
94 const static constexpr int powerOffSaveTimeMs = 7000;
95
96 const static std::filesystem::path powerControlDir = "/var/lib/power-control";
97@@ -93,24 +90,14 @@ static boost::asio::steady_timer gracefulPowerOffTimer(io);
98 static boost::asio::steady_timer warmResetCheckTimer(io);
99 // Time power supply power OK assertion on power-on
100 static boost::asio::steady_timer psPowerOKWatchdogTimer(io);
101-// Time SIO power good assertion on power-on
102-static boost::asio::steady_timer sioPowerGoodWatchdogTimer(io);
103 // Time power-off state save for power loss tracking
104 static boost::asio::steady_timer powerStateSaveTimer(io);
105 // POH timer
106 static boost::asio::steady_timer pohCounterTimer(io);
107-// Time when to allow restart cause updates
108-static boost::asio::steady_timer restartCauseTimer(io);
109
110 // GPIO Lines and Event Descriptors
111 static gpiod::line psPowerOKLine;
112 static boost::asio::posix::stream_descriptor psPowerOKEvent(io);
113-static gpiod::line sioPowerGoodLine;
114-static boost::asio::posix::stream_descriptor sioPowerGoodEvent(io);
115-static gpiod::line sioOnControlLine;
116-static boost::asio::posix::stream_descriptor sioOnControlEvent(io);
117-static gpiod::line sioS5Line;
118-static boost::asio::posix::stream_descriptor sioS5Event(io);
119 static gpiod::line powerButtonLine;
120 static boost::asio::posix::stream_descriptor powerButtonEvent(io);
121 static gpiod::line resetButtonLine;
122@@ -123,31 +110,10 @@ static gpiod::line postCompleteLine;
123 static boost::asio::posix::stream_descriptor postCompleteEvent(io);
124 static gpiod::line nmiOutLine;
125
126-static constexpr uint8_t beepPowerFail = 8;
127-
128-static void beep(const uint8_t& beepPriority)
129-{
130- std::cerr << "Beep with priority: " << (unsigned)beepPriority << "\n";
131-
132- conn->async_method_call(
133- [](boost::system::error_code ec) {
134- if (ec)
135- {
136- std::cerr << "beep returned error with "
137- "async_method_call (ec = "
138- << ec << ")\n";
139- return;
140- }
141- },
142- "xyz.openbmc_project.BeepCode", "/xyz/openbmc_project/BeepCode",
143- "xyz.openbmc_project.BeepCode", "Beep", uint8_t(beepPriority));
144-}
145-
146 enum class PowerState
147 {
148 on,
149 waitForPSPowerOK,
150- waitForSIOPowerGood,
151 off,
152 transitionToOff,
153 gracefulTransitionToOff,
154@@ -167,9 +133,6 @@ static std::string getPowerStateName(PowerState state)
155 case PowerState::waitForPSPowerOK:
156 return "Wait for Power Supply Power OK";
157 break;
158- case PowerState::waitForSIOPowerGood:
159- return "Wait for SIO Power Good";
160- break;
161 case PowerState::off:
162 return "Off";
163 break;
164@@ -210,17 +173,12 @@ enum class Event
165 {
166 psPowerOKAssert,
167 psPowerOKDeAssert,
168- sioPowerGoodAssert,
169- sioPowerGoodDeAssert,
170- sioS5Assert,
171- sioS5DeAssert,
172 postCompleteAssert,
173 postCompleteDeAssert,
174 powerButtonPressed,
175 resetButtonPressed,
176 powerCycleTimerExpired,
177 psPowerOKWatchdogTimerExpired,
178- sioPowerGoodWatchdogTimerExpired,
179 gracefulPowerOffTimerExpired,
180 powerOnRequest,
181 powerOffRequest,
182@@ -240,18 +198,6 @@ static std::string getEventName(Event event)
183 case Event::psPowerOKDeAssert:
184 return "power supply power OK de-assert";
185 break;
186- case Event::sioPowerGoodAssert:
187- return "SIO power good assert";
188- break;
189- case Event::sioPowerGoodDeAssert:
190- return "SIO power good de-assert";
191- break;
192- case Event::sioS5Assert:
193- return "SIO S5 assert";
194- break;
195- case Event::sioS5DeAssert:
196- return "SIO S5 de-assert";
197- break;
198 case Event::postCompleteAssert:
199 return "POST Complete assert";
200 break;
201@@ -270,9 +216,6 @@ static std::string getEventName(Event event)
202 case Event::psPowerOKWatchdogTimerExpired:
203 return "power supply power OK watchdog timer expired";
204 break;
205- case Event::sioPowerGoodWatchdogTimerExpired:
206- return "SIO power good watchdog timer expired";
207- break;
208 case Event::gracefulPowerOffTimerExpired:
209 return "graceful power-off timer expired";
210 break;
211@@ -314,7 +257,6 @@ static void logEvent(const std::string_view stateHandler, const Event event)
212 // Power state handlers
213 static void powerStateOn(const Event event);
214 static void powerStateWaitForPSPowerOK(const Event event);
215-static void powerStateWaitForSIOPowerGood(const Event event);
216 static void powerStateOff(const Event event);
217 static void powerStateTransitionToOff(const Event event);
218 static void powerStateGracefulTransitionToOff(const Event event);
219@@ -333,9 +275,6 @@ static std::function<void(const Event)> getPowerStateHandler(PowerState state)
220 case PowerState::waitForPSPowerOK:
221 return powerStateWaitForPSPowerOK;
222 break;
223- case PowerState::waitForSIOPowerGood:
224- return powerStateWaitForSIOPowerGood;
225- break;
226 case PowerState::off:
227 return powerStateOff;
228 break;
229@@ -399,7 +338,6 @@ static constexpr std::string_view getHostState(const PowerState state)
230 return "xyz.openbmc_project.State.Host.HostState.Running";
231 break;
232 case PowerState::waitForPSPowerOK:
233- case PowerState::waitForSIOPowerGood:
234 case PowerState::off:
235 case PowerState::transitionToOff:
236 case PowerState::transitionToCycleOff:
237@@ -425,7 +363,6 @@ static constexpr std::string_view getChassisState(const PowerState state)
238 return "xyz.openbmc_project.State.Chassis.PowerState.On";
239 break;
240 case PowerState::waitForPSPowerOK:
241- case PowerState::waitForSIOPowerGood:
242 case PowerState::off:
243 case PowerState::cycleOff:
244 return "xyz.openbmc_project.State.Chassis.PowerState.Off";
245@@ -593,7 +530,7 @@ static void systemPowerGoodFailedLog()
246 "MESSAGE=PowerControl: system power good failed to assert (VR failure)",
247 "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
248 "OpenBMC.0.1.SystemPowerGoodFailed", "REDFISH_MESSAGE_ARGS=%d",
249- sioPowerGoodWatchdogTimeMs, NULL);
250+ psPowerOKWatchdogTimeMs, NULL);
251 }
252
253 static void psPowerOKFailedLog()
254@@ -1081,54 +1018,24 @@ static int setGPIOOutputForMs(const std::string& name, const int value,
255
256 static void powerOn()
257 {
258- setGPIOOutputForMs(power_control::powerOutName, 0, powerPulseTimeMs);
259+ setGPIOOutputForMs(power_control::powerOutName, 1, powerPulseTimeMs);
260 }
261
262 static void gracefulPowerOff()
263 {
264- setGPIOOutputForMs(power_control::powerOutName, 0, powerPulseTimeMs);
265+ setGPIOOutputForMs(power_control::powerOutName, 1, powerPulseTimeMs);
266 }
267
268 static void forcePowerOff()
269 {
270- if (setGPIOOutputForMs(power_control::powerOutName, 0,
271- forceOffPulseTimeMs) < 0)
272- {
273- return;
274- }
275+ setGPIOOutputForMs(power_control::powerOutName, 1, forceOffPulseTimeMs);
276
277- // If the force off timer expires, then the PCH power-button override
278- // failed, so attempt the Unconditional Powerdown SMBus command.
279- gpioAssertTimer.async_wait([](const boost::system::error_code ec) {
280- if (ec)
281- {
282- // operation_aborted is expected if timer is canceled before
283- // completion.
284- if (ec != boost::asio::error::operation_aborted)
285- {
286- std::cerr << "Force power off async_wait failed: "
287- << ec.message() << "\n";
288- }
289- return;
290- }
291- std::cerr << "PCH Power-button override failed. Issuing Unconditional "
292- "Powerdown SMBus command.\n";
293- const static constexpr size_t pchDevBusAddress = 3;
294- const static constexpr size_t pchDevSlaveAddress = 0x44;
295- const static constexpr size_t pchCmdReg = 0;
296- const static constexpr size_t pchPowerDownCmd = 0x02;
297- if (i2cSet(pchDevBusAddress, pchDevSlaveAddress, pchCmdReg,
298- pchPowerDownCmd) < 0)
299- {
300- std::cerr << "Unconditional Powerdown command failed! Not sure "
301- "what to do now.\n";
302- }
303- });
304+ return;
305 }
306
307 static void reset()
308 {
309- setGPIOOutputForMs(power_control::resetOutName, 0, resetPulseTimeMs);
310+ setGPIOOutputForMs(power_control::resetOutName, 1, resetPulseTimeMs);
311 }
312
313 static void gracefulPowerOffTimerStart()
314@@ -1373,43 +1280,16 @@ static void currentHostStateMonitor()
315 });
316 }
317
318-static void sioPowerGoodWatchdogTimerStart()
319-{
320- std::cerr << "SIO power good watchdog timer started\n";
321- sioPowerGoodWatchdogTimer.expires_after(
322- std::chrono::milliseconds(sioPowerGoodWatchdogTimeMs));
323- sioPowerGoodWatchdogTimer.async_wait(
324- [](const boost::system::error_code ec) {
325- if (ec)
326- {
327- // operation_aborted is expected if timer is canceled before
328- // completion.
329- if (ec != boost::asio::error::operation_aborted)
330- {
331- std::cerr << "SIO power good watchdog async_wait failed: "
332- << ec.message() << "\n";
333- }
334- std::cerr << "SIO power good watchdog timer canceled\n";
335- return;
336- }
337- std::cerr << "SIO power good watchdog timer completed\n";
338- sendPowerControlEvent(Event::sioPowerGoodWatchdogTimerExpired);
339- });
340-}
341-
342 static void powerStateOn(const Event event)
343 {
344+ gpiod::line line;
345 logEvent(__FUNCTION__, event);
346 switch (event)
347 {
348 case Event::psPowerOKDeAssert:
349 setPowerState(PowerState::off);
350- // DC power is unexpectedly lost, beep
351- beep(beepPowerFail);
352- break;
353- case Event::sioS5Assert:
354- setPowerState(PowerState::transitionToOff);
355- addRestartCause(RestartCause::softReset);
356+ // DC power is unexpectedly lost, Light Up fault LED
357+ power_control::setGPIOOutput(power_control::faultLedName, 1, line);
358 break;
359 case Event::postCompleteDeAssert:
360 setPowerState(PowerState::checkForWarmReset);
361@@ -1461,37 +1341,12 @@ static void powerStateWaitForPSPowerOK(const Event event)
362 // Cancel any GPIO assertions held during the transition
363 gpioAssertTimer.cancel();
364 psPowerOKWatchdogTimer.cancel();
365- sioPowerGoodWatchdogTimerStart();
366- setPowerState(PowerState::waitForSIOPowerGood);
367+ setPowerState(PowerState::on);
368 break;
369 case Event::psPowerOKWatchdogTimerExpired:
370 setPowerState(PowerState::off);
371 psPowerOKFailedLog();
372 break;
373- case Event::sioPowerGoodAssert:
374- psPowerOKWatchdogTimer.cancel();
375- setPowerState(PowerState::on);
376- break;
377- default:
378- phosphor::logging::log<phosphor::logging::level::INFO>(
379- "No action taken.");
380- break;
381- }
382-}
383-
384-static void powerStateWaitForSIOPowerGood(const Event event)
385-{
386- logEvent(__FUNCTION__, event);
387- switch (event)
388- {
389- case Event::sioPowerGoodAssert:
390- sioPowerGoodWatchdogTimer.cancel();
391- setPowerState(PowerState::on);
392- break;
393- case Event::sioPowerGoodWatchdogTimerExpired:
394- setPowerState(PowerState::off);
395- systemPowerGoodFailedLog();
396- break;
397 default:
398 phosphor::logging::log<phosphor::logging::level::INFO>(
399 "No action taken.");
400@@ -1505,12 +1360,6 @@ static void powerStateOff(const Event event)
401 switch (event)
402 {
403 case Event::psPowerOKAssert:
404- setPowerState(PowerState::waitForSIOPowerGood);
405- break;
406- case Event::sioS5DeAssert:
407- setPowerState(PowerState::waitForPSPowerOK);
408- break;
409- case Event::sioPowerGoodAssert:
410 setPowerState(PowerState::on);
411 break;
412 case Event::powerButtonPressed:
413@@ -1572,11 +1421,11 @@ static void powerStateCycleOff(const Event event)
414 {
415 case Event::psPowerOKAssert:
416 powerCycleTimer.cancel();
417- setPowerState(PowerState::waitForSIOPowerGood);
418+ setPowerState(PowerState::on);
419 break;
420- case Event::sioS5DeAssert:
421+ case Event::psPowerOKDeAssert:
422 powerCycleTimer.cancel();
423- setPowerState(PowerState::waitForPSPowerOK);
424+ setPowerState(PowerState::off);
425 break;
426 case Event::powerButtonPressed:
427 powerCycleTimer.cancel();
428@@ -1635,21 +1484,18 @@ static void powerStateGracefulTransitionToCycleOff(const Event event)
429
430 static void powerStateCheckForWarmReset(const Event event)
431 {
432+ gpiod::line line;
433 logEvent(__FUNCTION__, event);
434 switch (event)
435 {
436- case Event::sioS5Assert:
437- warmResetCheckTimer.cancel();
438- setPowerState(PowerState::transitionToOff);
439- break;
440 case Event::warmResetDetected:
441 setPowerState(PowerState::on);
442 break;
443 case Event::psPowerOKDeAssert:
444 warmResetCheckTimer.cancel();
445 setPowerState(PowerState::off);
446- // DC power is unexpectedly lost, beep
447- beep(beepPowerFail);
448+ // DC power is unexpectedly lost, Light up Fault LED
449+ power_control::setGPIOOutput(power_control::faultLedName, 1, line);
450 break;
451 default:
452 phosphor::logging::log<phosphor::logging::level::INFO>(
453@@ -1681,71 +1527,6 @@ static void psPowerOKHandler()
454 });
455 }
456
457-static void sioPowerGoodHandler()
458-{
459- gpiod::line_event gpioLineEvent = sioPowerGoodLine.event_read();
460-
461- Event powerControlEvent =
462- gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE
463- ? Event::sioPowerGoodAssert
464- : Event::sioPowerGoodDeAssert;
465-
466- sendPowerControlEvent(powerControlEvent);
467- sioPowerGoodEvent.async_wait(
468- boost::asio::posix::stream_descriptor::wait_read,
469- [](const boost::system::error_code ec) {
470- if (ec)
471- {
472- std::cerr << "SIO power good handler error: " << ec.message()
473- << "\n";
474- return;
475- }
476- sioPowerGoodHandler();
477- });
478-}
479-
480-static void sioOnControlHandler()
481-{
482- gpiod::line_event gpioLineEvent = sioOnControlLine.event_read();
483-
484- bool sioOnControl =
485- gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE;
486- std::cerr << "SIO_ONCONTROL value changed: " << sioOnControl << "\n";
487- sioOnControlEvent.async_wait(
488- boost::asio::posix::stream_descriptor::wait_read,
489- [](const boost::system::error_code ec) {
490- if (ec)
491- {
492- std::cerr << "SIO ONCONTROL handler error: " << ec.message()
493- << "\n";
494- return;
495- }
496- sioOnControlHandler();
497- });
498-}
499-
500-static void sioS5Handler()
501-{
502- gpiod::line_event gpioLineEvent = sioS5Line.event_read();
503-
504- Event powerControlEvent =
505- gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE
506- ? Event::sioS5Assert
507- : Event::sioS5DeAssert;
508-
509- sendPowerControlEvent(powerControlEvent);
510- sioS5Event.async_wait(boost::asio::posix::stream_descriptor::wait_read,
511- [](const boost::system::error_code ec) {
512- if (ec)
513- {
514- std::cerr << "SIO S5 handler error: "
515- << ec.message() << "\n";
516- return;
517- }
518- sioS5Handler();
519- });
520-}
521-
522 static void powerButtonHandler()
523 {
524 gpiod::line_event gpioLineEvent = powerButtonLine.event_read();
525@@ -2007,7 +1788,7 @@ static void postCompleteHandler()
526 gpiod::line_event gpioLineEvent = postCompleteLine.event_read();
527
528 bool postComplete =
529- gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE;
530+ gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE;
531 if (postComplete)
532 {
533 sendPowerControlEvent(Event::postCompleteAssert);
534@@ -2095,19 +1876,14 @@ static int loadConfigValues()
535 resetOutName = data["RstOut"];
536 }
537
538- if (data.contains("SIOOnCtl"))
539- {
540- sioOnControlName = data["SIOOnCtl"];
541- }
542-
543- if (data.contains("SIOPwrGd"))
544+ if (data.contains("BmcReady"))
545 {
546- sioPwrGoodName = data["SIOPwrGd"];
547+ bmcReadyName = data["BmcReady"];
548 }
549
550- if (data.contains("SIOS5"))
551+ if (data.contains("FaultLed"))
552 {
553- sioS5Name = data["SIOS5"];
554+ faultLedName = data["FaultLed"];
555 }
556
557 return 0;
558@@ -2155,60 +1931,6 @@ int main(int argc, char* argv[])
559 return -1;
560 }
561
562- // Request SIO_POWER_GOOD GPIO events
563- if (!power_control::sioPwrGoodName.empty())
564- {
565- if (!power_control::requestGPIOEvents(
566- power_control::sioPwrGoodName,
567- power_control::sioPowerGoodHandler,
568- power_control::sioPowerGoodLine,
569- power_control::sioPowerGoodEvent))
570- {
571- return -1;
572- }
573- }
574- else
575- {
576- std::cerr
577- << "sioPwrGood name should be configured from json config file\n";
578- return -1;
579- }
580-
581- // Request SIO_ONCONTROL GPIO events
582- if (!power_control::sioOnControlName.empty())
583- {
584- if (!power_control::requestGPIOEvents(
585- power_control::sioOnControlName,
586- power_control::sioOnControlHandler,
587- power_control::sioOnControlLine,
588- power_control::sioOnControlEvent))
589- {
590- return -1;
591- }
592- }
593- else
594- {
595- std::cerr
596- << "sioOnControl name should be configured from json config file\n";
597- return -1;
598- }
599-
600- // Request SIO_S5 GPIO events
601- if (!power_control::sioS5Name.empty())
602- {
603- if (!power_control::requestGPIOEvents(
604- power_control::sioS5Name, power_control::sioS5Handler,
605- power_control::sioS5Line, power_control::sioS5Event))
606- {
607- return -1;
608- }
609- }
610- else
611- {
612- std::cerr << "sioS5 name should be configured from json config file\n";
613- return -1;
614- }
615-
616 // Request POWER_BUTTON GPIO events
617 if (!power_control::powerButtonName.empty())
618 {
619@@ -2286,12 +2008,12 @@ int main(int argc, char* argv[])
620
621 // Initialize POWER_OUT and RESET_OUT GPIO.
622 gpiod::line line;
623- if (!power_control::setGPIOOutput(power_control::powerOutName, 1, line))
624+ if (!power_control::setGPIOOutput(power_control::powerOutName, 0, line))
625 {
626 return -1;
627 }
628
629- if (!power_control::setGPIOOutput(power_control::resetOutName, 1, line))
630+ if (!power_control::setGPIOOutput(power_control::resetOutName, 0, line))
631 {
632 return -1;
633 }
634@@ -2299,6 +2021,13 @@ int main(int argc, char* argv[])
635 // Release line
636 line.reset();
637
638+ // DRIVE BMC_READY HIGH
639+ gpiod::line bmcReadyline;
640+ if (!power_control::setGPIOOutput(power_control::bmcReadyName, 1, bmcReadyline))
641+ {
642+ return -1;
643+ }
644+
645 // Initialize the power state
646 power_control::powerState = power_control::PowerState::off;
647 // Check power good
648--
6492.17.1
650