bios: fix driver binding order
spi-aspeed-smc driver was bound but spi-nor driver was not bound which
created problems for systems with more than one spi device on the bus.
Update the code to bind spi-nor driver as well for the desired device
and not unbind spi-aspeed-smc driver at the end since other spi devices
may still be in use on that bus.
Tested: bios update proceeds normally
Config which was used:
```
{
"FirmwareInfo": {
"CompatibleHardware": "com.tyan.Hardware.S8030.SPI.Host",
"VendorIANA": 6653
},
"MuxOutputs": [
{
"Name": "BMC_SPI_SEL",
"Polarity": "High"
}
],
"Name": "HostSPIFlash",
"SPIControllerIndex": 1,
"SPIDeviceIndex": 0,
"Type": "SPIFlash",
}
```
SPI controller driver says bound throughout the update process
```
root@s8030-bmc-30303035c0c1:/sys/bus/platform# ls /sys/bus/platform/drivers/spi-aspeed-smc/
1e620000.spi 1e630000.spi bind uevent unbind
```
and SPI flash driver (spi-nor) is bound and then unbound after the
update process.
```
root@s8030-bmc-30303035c0c1:/sys/bus/platform# ls /sys/bus/spi/drivers/spi-nor/
bind spi0.0 spi1.0 uevent unbind
root@s8030-bmc-30303035c0c1:/sys/bus/platform# ls /sys/bus/spi/drivers/spi-nor/
bind spi0.0 uevent unbind
```
Change-Id: I874670f9fd27f6642359ea078e6e9db4c1b9e249
Signed-off-by: Alexander Hansen <alexander.hansen@9elements.com>
diff --git a/bios/spi_device.cpp b/bios/spi_device.cpp
index f68446f..7372c40 100644
--- a/bios/spi_device.cpp
+++ b/bios/spi_device.cpp
@@ -134,51 +134,61 @@
}
const std::string spiAspeedSMCPath = "/sys/bus/platform/drivers/spi-aspeed-smc";
+const std::string spiNorPath = "/sys/bus/spi/drivers/spi-nor";
// NOLINTBEGIN(readability-static-accessed-through-instance)
sdbusplus::async::task<bool> SPIDevice::bindSPIFlash()
// NOLINTEND(readability-static-accessed-through-instance)
{
- debug("binding flash to SMC");
-
- if (SPIDevice::isSPIFlashBound())
+ if (!SPIDevice::isSPIControllerBound())
{
- debug("flash was already bound, unbinding it now");
- bool success = co_await SPIDevice::unbindSPIFlash();
-
- if (!success)
- {
- error("error unbinding spi flash");
- co_return false;
- }
+ debug("binding flash to SMC");
+ std::ofstream ofbind(spiAspeedSMCPath + "/bind", std::ofstream::out);
+ ofbind << spiDev;
+ ofbind.close();
}
- std::ofstream ofbind(spiAspeedSMCPath + "/bind", std::ofstream::out);
- ofbind << spiDev;
- ofbind.close();
-
const int driverBindSleepDuration = 2;
co_await sdbusplus::async::sleep_for(
ctx, std::chrono::seconds(driverBindSleepDuration));
- const bool isBound = isSPIFlashBound();
-
- if (!isBound)
+ if (!isSPIControllerBound())
{
- error("failed to bind spi device");
+ error("failed to bind spi controller");
+ co_return false;
}
- co_return isBound;
+ const std::string name =
+ std::format("spi{}.{}", spiControllerIndex, spiDeviceIndex);
+
+ std::ofstream ofbindSPINor(spiNorPath + "/bind", std::ofstream::out);
+ ofbindSPINor << name;
+ ofbindSPINor.close();
+
+ co_await sdbusplus::async::sleep_for(
+ ctx, std::chrono::seconds(driverBindSleepDuration));
+
+ if (!isSPIFlashBound())
+ {
+ error("failed to bind spi flash (spi-nor driver)");
+ co_return false;
+ }
+
+ co_return true;
}
// NOLINTBEGIN(readability-static-accessed-through-instance)
sdbusplus::async::task<bool> SPIDevice::unbindSPIFlash()
// NOLINTEND(readability-static-accessed-through-instance)
{
- debug("unbinding flash from SMC");
- std::ofstream ofunbind(spiAspeedSMCPath + "/unbind", std::ofstream::out);
- ofunbind << spiDev;
+ debug("unbinding flash");
+
+ const std::string name =
+ std::format("spi{}.{}", spiControllerIndex, spiDeviceIndex);
+
+ std::ofstream ofunbind(spiNorPath + "/unbind", std::ofstream::out);
+ ofunbind << name;
ofunbind.close();
// wait for kernel
@@ -187,13 +197,22 @@
co_return !isSPIFlashBound();
}
-bool SPIDevice::isSPIFlashBound()
+bool SPIDevice::isSPIControllerBound()
{
std::string path = spiAspeedSMCPath + "/" + spiDev;
return std::filesystem::exists(path);
}
+bool SPIDevice::isSPIFlashBound()
+{
+ const std::string name =
+ std::format("spi{}.{}", spiControllerIndex, spiDeviceIndex);
+ std::string path = spiNorPath + "/" + name;
+
+ return std::filesystem::exists(path);
+}
+
static std::unique_ptr<::gpiod::line_bulk> requestMuxGPIOs(
const std::vector<std::string>& gpioLines,
const std::vector<int>& gpioValues, bool inverted)
diff --git a/bios/spi_device.hpp b/bios/spi_device.hpp
index d05ab89..4a9e6fc 100644
--- a/bios/spi_device.hpp
+++ b/bios/spi_device.hpp
@@ -81,6 +81,7 @@
// @returns true on success
sdbusplus::async::task<bool> unbindSPIFlash();
+ bool isSPIControllerBound();
bool isSPIFlashBound();
// @description preconditions: