Files
OpenBMC/meta-luxshare/meta-bhs/recipes-phosphor/chassis/x86-power-control/0005-Implement-power-reset-control.patch
T
2026-04-23 17:07:55 +08:00

165 lines
4.0 KiB
Diff
Executable File

From fa312c462de18b25a67f08c8f7be51f9fbdc4df5 Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Thu, 19 Sep 2024 15:11:18 +0800
Subject: [PATCH] Implement power reset control
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
src/power_control.cpp | 128 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 126 insertions(+), 2 deletions(-)
diff --git a/src/power_control.cpp b/src/power_control.cpp
index 7a47957..586d1e3 100644
--- a/src/power_control.cpp
+++ b/src/power_control.cpp
@@ -27,10 +27,18 @@
#include <nlohmann/json.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/asio/object_server.hpp>
-
#include <filesystem>
#include <fstream>
#include <string_view>
+#include <thread>
+#include <chrono>
+#include <iostream>
+
+extern "C"
+{
+#include <i2c/smbus.h>
+#include <linux/i2c-dev.h>
+}
namespace power_control
{
@@ -1408,9 +1416,125 @@ static void forcePowerOff()
});
}
+int i2cWriteRead(std::string& i2cDev, const uint8_t slaveAddr,
+ std::vector<uint8_t> writeData,
+ std::vector<uint8_t>& readBuf)
+{
+ int fd = open(i2cDev.c_str(), O_RDWR | O_CLOEXEC);
+ if (fd < 0)
+ {
+ lg2::error("unable to open i2c device");
+ return -1;
+ }
+
+ const size_t writeCount = writeData.size();
+ const size_t readCount = readBuf.size();
+
+ int msgCount = 0;
+ struct i2c_msg i2cmsg[2];
+
+ memset(i2cmsg, 0, sizeof(i2cmsg));
+
+ if (writeCount)
+ {
+ // Data will be writtern to the slave address
+ i2cmsg[msgCount].addr = slaveAddr;
+ i2cmsg[msgCount].flags = 0x00;
+ i2cmsg[msgCount].len = writeCount;
+ i2cmsg[msgCount].buf = writeData.data();
+ msgCount++;
+ }
+
+ if (readCount)
+ {
+ // Data will be read into the buffer from the slave address
+ i2cmsg[msgCount].addr = slaveAddr;
+ i2cmsg[msgCount].flags = I2C_M_RD;
+ i2cmsg[msgCount].len = readCount;
+ i2cmsg[msgCount].buf = readBuf.data();
+ msgCount++;
+ }
+
+ struct i2c_rdwr_ioctl_data msgReadWrite;
+ memset((void*)&msgReadWrite, 0, sizeof(msgReadWrite));
+ msgReadWrite.msgs = i2cmsg;
+ msgReadWrite.nmsgs = msgCount;
+
+ int ret = ioctl(fd, I2C_RDWR, &msgReadWrite);
+ close(fd);
+ if (ret < 0)
+ {
+ lg2::error("I2C Read Write Failed.");
+ return -1;
+ }
+
+ if (readCount)
+ {
+ readBuf.resize(msgReadWrite.msgs[msgCount - 1].len);
+ }
+
+ return 0;
+}
+
+#define BIT2 (1 << 2)
+void luxResetChassis()
+{
+ int ret = 0;
+ std::string i2cDev = "/dev/i2c-0";
+ // Perform the combined write/read
+
+ std::vector<uint8_t> readBuf(1);
+ std::vector<uint8_t> writeData = {0x30, 0x01};
+ const uint8_t slaveAddr = 0x0D;
+ uint8_t regVal, tmp;
+
+ ret = i2cWriteRead(i2cDev, slaveAddr, writeData, readBuf);
+ if (ret < 0)
+ {
+ lg2::error("i2c failed to read regVal.");
+ goto err;
+ }
+
+ regVal = readBuf[0];
+ readBuf.resize(0);
+ tmp = regVal & (~BIT2);
+ writeData.push_back(tmp);
+
+ ret = i2cWriteRead(i2cDev, slaveAddr, writeData, readBuf);
+ if (ret < 0)
+ {
+ lg2::error("i2c WriteRead failed.");
+ goto err;
+ }
+
+ writeData.pop_back();
+ tmp = regVal | BIT2;
+ writeData.push_back(tmp);
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(400));
+
+ ret = i2cWriteRead(i2cDev, slaveAddr, writeData, readBuf);
+ if (ret < 0)
+ {
+ lg2::error("i2c WriteRead failed.");
+ goto err;
+ }
+
+ lg2::error("Success to reset Host.");
+ return;
+err:
+ lg2::error("Fail to reset Host.");
+ return;
+}
+
static void reset()
{
- assertGPIOForMs(resetOutConfig, TimerMap["ResetPulseMs"]);
+ if (!resetOutConfig.lineName.empty())
+ assertGPIOForMs(resetOutConfig, TimerMap["ResetPulseMs"]);
+ else {
+ std::thread myThread(luxResetChassis);
+ myThread.join();
+ }
}
static void gracefulPowerOffTimerStart()
--
2.34.1