* [PATCH RFC v2 1/7] mfd: ls2kbmc: Make a copy when parsing mode string
2026-07-07 21:16 [PATCH RFC v2 0/7] mfd: ls2kbmc: multiple fixes for this driver Miao Wang via B4 Relay
@ 2026-07-07 21:16 ` Miao Wang via B4 Relay
2026-07-07 21:16 ` [PATCH RFC v2 2/7] mfd: ls2kbmc: Sanity check for the connected pci port Miao Wang via B4 Relay
` (5 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Miao Wang via B4 Relay @ 2026-07-07 21:16 UTC (permalink / raw)
To: Binbin Zhou, Chong Qiao, Lee Jones, Huacai Chen, Corey Minyard,
Linus Walleij, Bartosz Golaszewski
Cc: Xi Ruoyao, WANG Xuerui, Yinbo Zhu, Jiaxun Yang, mfd, linux-kernel,
linux-gpio, openipmi-developer, Miao Wang
From: Miao Wang <shankerwangmiao@gmail.com>
When parsing the mode string from BMC, the string is manipulated
in-place with strsep(), preventing from parsing it again. Make a copy of
the original string and manipulate the copy instead to fix this.
Fixes: 0d64f6d1ffe9 ("mfd: ls2kbmc: Introduce Loongson-2K BMC core driver")
Signed-off-by: Miao Wang <shankerwangmiao@gmail.com>
---
drivers/mfd/ls2k-bmc-core.c | 30 +++++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/drivers/mfd/ls2k-bmc-core.c b/drivers/mfd/ls2k-bmc-core.c
index 408056bfb2fe757a5bde43775a483a48352e706d..27f6e096404d67459038a0607378057ec7ef69ab 100644
--- a/drivers/mfd/ls2k-bmc-core.c
+++ b/drivers/mfd/ls2k-bmc-core.c
@@ -427,34 +427,54 @@ static int ls2k_bmc_init(struct ls2k_bmc_ddata *ddata)
*/
static int ls2k_bmc_parse_mode(struct pci_dev *pdev, struct simplefb_platform_data *pd)
{
- char *mode;
+ /* Assume 64 bytes is enough for the resolution string */
+ char mode_buf[64], mode_buf_orig[64];
+ char *mode = mode_buf;
+ const void __iomem *mode_base;
int depth, ret;
/* The last 16M of PCI BAR0 is used to store the resolution string. */
- mode = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0) + SZ_16M, SZ_16M);
- if (!mode)
+ mode_base = ioremap(pci_resource_start(pdev, 0) + SZ_16M,
+ sizeof(mode_buf));
+ if (!mode_base)
return -ENOMEM;
+ memcpy_fromio(mode_buf, mode_base, sizeof(mode_buf) - 1);
+ mode_buf[sizeof(mode_buf) - 1] = '\0';
+ iounmap((void __iomem *)mode_base);
+ memcpy(mode_buf_orig, mode_buf, sizeof(mode_buf_orig));
/* The resolution field starts with the flag "video=". */
if (!strncmp(mode, "video=", 6))
mode = mode + 6;
+ else
+ goto invalid_mode;
- ret = kstrtoint(strsep(&mode, "x"), 10, &pd->width);
+ ret = kstrtouint(strsep(&mode, "x"), 10, &pd->width);
if (ret)
return ret;
+ if (mode == NULL)
+ goto invalid_mode;
- ret = kstrtoint(strsep(&mode, "-"), 10, &pd->height);
+ ret = kstrtouint(strsep(&mode, "-"), 10, &pd->height);
if (ret)
return ret;
+ if (mode == NULL)
+ goto invalid_mode;
ret = kstrtoint(strsep(&mode, "@"), 10, &depth);
if (ret)
return ret;
+ if (mode == NULL)
+ goto invalid_mode;
pd->stride = pd->width * depth / 8;
pd->format = depth == 32 ? "a8r8g8b8" : "r5g6b5";
return 0;
+
+invalid_mode:
+ dev_err(&pdev->dev, "Invalid resolution string: %s\n", mode_buf_orig);
+ return -EINVAL;
}
static int ls2k_bmc_probe(struct pci_dev *dev, const struct pci_device_id *id)
--
2.49.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH RFC v2 2/7] mfd: ls2kbmc: Sanity check for the connected pci port
2026-07-07 21:16 [PATCH RFC v2 0/7] mfd: ls2kbmc: multiple fixes for this driver Miao Wang via B4 Relay
2026-07-07 21:16 ` [PATCH RFC v2 1/7] mfd: ls2kbmc: Make a copy when parsing mode string Miao Wang via B4 Relay
@ 2026-07-07 21:16 ` Miao Wang via B4 Relay
2026-07-07 21:16 ` [PATCH RFC v2 3/7] mfd: ls2kbmc: Redraw using exported functions Miao Wang via B4 Relay
` (4 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Miao Wang via B4 Relay @ 2026-07-07 21:16 UTC (permalink / raw)
To: Binbin Zhou, Chong Qiao, Lee Jones, Huacai Chen, Corey Minyard,
Linus Walleij, Bartosz Golaszewski
Cc: Xi Ruoyao, WANG Xuerui, Yinbo Zhu, Jiaxun Yang, mfd, linux-kernel,
linux-gpio, openipmi-developer, Miao Wang
From: Miao Wang <shankerwangmiao@gmail.com>
When the bmc resets, the recovery procedure require to reconfigure the
parent device. The driver assumes that the parent device should be LS7A.
Add a sanity check on initialization to ensure this and prevent from
accidentally operating on non-LS7A ports.
Fixes: d952bba3fbb5 ("mfd: ls2kbmc: Add Loongson-2K BMC reset function support")
Signed-off-by: Miao Wang <shankerwangmiao@gmail.com>
---
drivers/mfd/ls2k-bmc-core.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/drivers/mfd/ls2k-bmc-core.c b/drivers/mfd/ls2k-bmc-core.c
index 27f6e096404d67459038a0607378057ec7ef69ab..b02e4955e9b04f517892a18b2ef103b5e481a238 100644
--- a/drivers/mfd/ls2k-bmc-core.c
+++ b/drivers/mfd/ls2k-bmc-core.c
@@ -35,6 +35,15 @@
#define LS2K_IPMI3_RES_START (LS2K_IPMI2_RES_START + LS2K_IPMI_RES_SIZE)
#define LS2K_IPMI4_RES_START (LS2K_IPMI3_RES_START + LS2K_IPMI_RES_SIZE)
+/* LS7A port Device IDs */
+#define DEV_LS7A1K_PCIE_PORT0 0x7a09
+#define DEV_LS7A1K_PCIE_PORT1 0x7a19
+#define DEV_LS7A1K_PCIE_PORT2 0x7a29
+#define DEV_LS7A2K_PCIE_PORT0 0x7a39
+#define DEV_LS7A2K_PCIE_PORT1 0x7a49
+#define DEV_LS7A2K_PCIE_PORT2 0x7a59
+#define DEV_LS7A2K_PCIE_PORT3 0x7a69
+
#define LS7A_PCI_CFG_SIZE 0x100
/* LS7A bridge registers */
@@ -477,6 +486,24 @@ static int ls2k_bmc_parse_mode(struct pci_dev *pdev, struct simplefb_platform_da
return -EINVAL;
}
+static const struct pci_device_id ls7a_ports[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, DEV_LS7A1K_PCIE_PORT0) },
+ { PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, DEV_LS7A1K_PCIE_PORT1) },
+ { PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, DEV_LS7A1K_PCIE_PORT2) },
+ { PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, DEV_LS7A2K_PCIE_PORT0) },
+ { PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, DEV_LS7A2K_PCIE_PORT1) },
+ { PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, DEV_LS7A2K_PCIE_PORT2) },
+ { PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, DEV_LS7A2K_PCIE_PORT3) },
+ { }
+};
+
+static bool ls2k_check_parent(struct pci_dev *dev)
+{
+ struct pci_dev *parent = dev->bus->self;
+
+ return parent && pci_match_id(ls7a_ports, parent) != NULL;
+}
+
static int ls2k_bmc_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct simplefb_platform_data pd;
@@ -488,6 +515,11 @@ static int ls2k_bmc_probe(struct pci_dev *dev, const struct pci_device_id *id)
if (ret)
return ret;
+ if (!ls2k_check_parent(dev)) {
+ dev_err(&dev->dev, "Expected to be connected to LS7A PCI-E port\n");
+ return -ENODEV;
+ }
+
ddata = devm_kzalloc(&dev->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
--
2.49.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH RFC v2 3/7] mfd: ls2kbmc: Redraw using exported functions
2026-07-07 21:16 [PATCH RFC v2 0/7] mfd: ls2kbmc: multiple fixes for this driver Miao Wang via B4 Relay
2026-07-07 21:16 ` [PATCH RFC v2 1/7] mfd: ls2kbmc: Make a copy when parsing mode string Miao Wang via B4 Relay
2026-07-07 21:16 ` [PATCH RFC v2 2/7] mfd: ls2kbmc: Sanity check for the connected pci port Miao Wang via B4 Relay
@ 2026-07-07 21:16 ` Miao Wang via B4 Relay
2026-07-07 21:16 ` [PATCH RFC v2 4/7] mfd: ls2kbmc: Cancel the work queue on removal Miao Wang via B4 Relay
` (3 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Miao Wang via B4 Relay @ 2026-07-07 21:16 UTC (permalink / raw)
To: Binbin Zhou, Chong Qiao, Lee Jones, Huacai Chen, Corey Minyard,
Linus Walleij, Bartosz Golaszewski
Cc: Xi Ruoyao, WANG Xuerui, Yinbo Zhu, Jiaxun Yang, mfd, linux-kernel,
linux-gpio, openipmi-developer, Miao Wang
From: Miao Wang <shankerwangmiao@gmail.com>
Use update_screen, i.e. redraw_screen() to trigger the redraw of the
current vt.
Fixes: d952bba3fbb5 ("mfd: ls2kbmc: Add Loongson-2K BMC reset function support")
Signed-off-by: Miao Wang <shankerwangmiao@gmail.com>
---
drivers/mfd/ls2k-bmc-core.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/mfd/ls2k-bmc-core.c b/drivers/mfd/ls2k-bmc-core.c
index b02e4955e9b04f517892a18b2ef103b5e481a238..a5465c42a77b8b7b81e3ad787d6036679c6ba6df 100644
--- a/drivers/mfd/ls2k-bmc-core.c
+++ b/drivers/mfd/ls2k-bmc-core.c
@@ -25,6 +25,7 @@
#include <linux/platform_device.h>
#include <linux/stop_machine.h>
#include <linux/vt_kern.h>
+#include <linux/console.h>
/* LS2K BMC resources */
#define LS2K_DISPLAY_RES_START (SZ_16M + SZ_2M)
@@ -310,7 +311,9 @@ static void ls2k_bmc_events_fn(struct work_struct *work)
if (IS_ENABLED(CONFIG_VT)) {
/* Re-push the display due to previous PCI-E loss. */
- set_console(vt_move_to_console(MAX_NR_CONSOLES - 1, 1));
+ console_lock();
+ update_screen(vc_cons[fg_console].d);
+ console_unlock();
}
}
--
2.49.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH RFC v2 4/7] mfd: ls2kbmc: Cancel the work queue on removal
2026-07-07 21:16 [PATCH RFC v2 0/7] mfd: ls2kbmc: multiple fixes for this driver Miao Wang via B4 Relay
` (2 preceding siblings ...)
2026-07-07 21:16 ` [PATCH RFC v2 3/7] mfd: ls2kbmc: Redraw using exported functions Miao Wang via B4 Relay
@ 2026-07-07 21:16 ` Miao Wang via B4 Relay
2026-07-07 21:16 ` [PATCH RFC v2 5/7] ipmi: ls2k: Relax the dependency to its mfd driver Miao Wang via B4 Relay
` (2 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Miao Wang via B4 Relay @ 2026-07-07 21:16 UTC (permalink / raw)
To: Binbin Zhou, Chong Qiao, Lee Jones, Huacai Chen, Corey Minyard,
Linus Walleij, Bartosz Golaszewski
Cc: Xi Ruoyao, WANG Xuerui, Yinbo Zhu, Jiaxun Yang, mfd, linux-kernel,
linux-gpio, openipmi-developer, Miao Wang
From: Miao Wang <shankerwangmiao@gmail.com>
When the device is being removeed, the work queue should be canceled to
avoid any pending work to be executed after the device is removed.
Fixes: d952bba3fbb5 ("mfd: ls2kbmc: Add Loongson-2K BMC reset function support")
Signed-off-by: Miao Wang <shankerwangmiao@gmail.com>
---
drivers/mfd/ls2k-bmc-core.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/mfd/ls2k-bmc-core.c b/drivers/mfd/ls2k-bmc-core.c
index a5465c42a77b8b7b81e3ad787d6036679c6ba6df..f87224105b3720cca97dcef089dad63fe57bc8c2 100644
--- a/drivers/mfd/ls2k-bmc-core.c
+++ b/drivers/mfd/ls2k-bmc-core.c
@@ -375,6 +375,12 @@ static void ls2k_bmc_save_pci_data(struct pci_dev *pdev, struct ls2k_bmc_ddata *
pci_read_config_dword(pdev, PCI_INTERRUPT_LINE, &ddata->bmc_pci_data.interrupt_line);
}
+static void ls2k_bmc_cancel_wq(void *data)
+{
+ struct ls2k_bmc_ddata *ddata = data;
+ (void) cancel_work_sync(&ddata->bmc_reset_work);
+}
+
static int ls2k_bmc_init(struct ls2k_bmc_ddata *ddata)
{
struct pci_dev *pdev = to_pci_dev(ddata->dev);
@@ -385,6 +391,8 @@ static int ls2k_bmc_init(struct ls2k_bmc_ddata *ddata)
INIT_WORK(&ddata->bmc_reset_work, ls2k_bmc_events_fn);
+ devm_add_action_or_reset(ddata->dev, ls2k_bmc_cancel_wq, ddata);
+
ret = devm_request_irq(&pdev->dev, pdev->irq, ls2k_bmc_interrupt,
IRQF_SHARED | IRQF_TRIGGER_FALLING, "ls2kbmc pcie", ddata);
if (ret) {
--
2.49.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH RFC v2 5/7] ipmi: ls2k: Relax the dependency to its mfd driver
2026-07-07 21:16 [PATCH RFC v2 0/7] mfd: ls2kbmc: multiple fixes for this driver Miao Wang via B4 Relay
` (3 preceding siblings ...)
2026-07-07 21:16 ` [PATCH RFC v2 4/7] mfd: ls2kbmc: Cancel the work queue on removal Miao Wang via B4 Relay
@ 2026-07-07 21:16 ` Miao Wang via B4 Relay
2026-07-07 21:16 ` [PATCH RFC v2 6/7] mfd: ls2kbmc: Able to be compiled as a module Miao Wang via B4 Relay
2026-07-07 21:16 ` [PATCH RFC v2 7/7] mfd: ls2kbmc: Capture the reset event of BMC through GPIO Miao Wang via B4 Relay
6 siblings, 0 replies; 13+ messages in thread
From: Miao Wang via B4 Relay @ 2026-07-07 21:16 UTC (permalink / raw)
To: Binbin Zhou, Chong Qiao, Lee Jones, Huacai Chen, Corey Minyard,
Linus Walleij, Bartosz Golaszewski
Cc: Xi Ruoyao, WANG Xuerui, Yinbo Zhu, Jiaxun Yang, mfd, linux-kernel,
linux-gpio, openipmi-developer, Miao Wang
From: Miao Wang <shankerwangmiao@gmail.com>
There is no strong dependency between the IPMI driver and its mfd
driver. Although the IPMI driver will not work without the mfd driver,
it is not a hard dependency. The IPMI driver can actually be compiled
without the mfd driver, and it will just fail to probe. When the mfd
driver is loaded, the IPMI driver will probe successfully. Therefore,
the dependency of the IPMI driver on its mfd driver should be relaxed
to "imply" from "select". This will allow the mfd driver to be compiled
as a module and the IPMI driver to be compiled as a part of the ipmi_si
module.
Fixes: d46651d4e3c0 ("ipmi: Add Loongson-2K BMC support")
Signed-off-by: Miao Wang <shankerwangmiao@gmail.com>
---
drivers/char/ipmi/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
index 669f7600019747bcd2b37563477cf336f19a0407..f456e3e89416932f0d21bb742153a503aeb24267 100644
--- a/drivers/char/ipmi/Kconfig
+++ b/drivers/char/ipmi/Kconfig
@@ -87,7 +87,7 @@ config IPMI_IPMB
config IPMI_LS2K
bool 'Loongson-2K IPMI interface'
depends on LOONGARCH
- select MFD_LS2K_BMC_CORE
+ imply MFD_LS2K_BMC_CORE
help
Provides a driver for Loongson-2K IPMI interfaces.
--
2.49.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH RFC v2 6/7] mfd: ls2kbmc: Able to be compiled as a module
2026-07-07 21:16 [PATCH RFC v2 0/7] mfd: ls2kbmc: multiple fixes for this driver Miao Wang via B4 Relay
` (4 preceding siblings ...)
2026-07-07 21:16 ` [PATCH RFC v2 5/7] ipmi: ls2k: Relax the dependency to its mfd driver Miao Wang via B4 Relay
@ 2026-07-07 21:16 ` Miao Wang via B4 Relay
2026-07-07 21:16 ` [PATCH RFC v2 7/7] mfd: ls2kbmc: Capture the reset event of BMC through GPIO Miao Wang via B4 Relay
6 siblings, 0 replies; 13+ messages in thread
From: Miao Wang via B4 Relay @ 2026-07-07 21:16 UTC (permalink / raw)
To: Binbin Zhou, Chong Qiao, Lee Jones, Huacai Chen, Corey Minyard,
Linus Walleij, Bartosz Golaszewski
Cc: Xi Ruoyao, WANG Xuerui, Yinbo Zhu, Jiaxun Yang, mfd, linux-kernel,
linux-gpio, openipmi-developer, Miao Wang
From: Miao Wang <shankerwangmiao@gmail.com>
Make ls2kmc able to be compiled as a module
Signed-off-by: Miao Wang <shankerwangmiao@gmail.com>
---
drivers/mfd/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 763ce6a34782bdd5d2b1a4d840c75b040092d83e..a7a9f97af248c88489dc1203a1ba05f2ce4827df 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -2494,7 +2494,7 @@ config MFD_LOONGSON_SE
which will forward them to the corresponding engine.
config MFD_LS2K_BMC_CORE
- bool "Loongson-2K Board Management Controller Support"
+ tristate "Loongson-2K Board Management Controller Support"
depends on PCI && ACPI_GENERIC_GSI
select MFD_CORE
help
--
2.49.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH RFC v2 7/7] mfd: ls2kbmc: Capture the reset event of BMC through GPIO
2026-07-07 21:16 [PATCH RFC v2 0/7] mfd: ls2kbmc: multiple fixes for this driver Miao Wang via B4 Relay
` (5 preceding siblings ...)
2026-07-07 21:16 ` [PATCH RFC v2 6/7] mfd: ls2kbmc: Able to be compiled as a module Miao Wang via B4 Relay
@ 2026-07-07 21:16 ` Miao Wang via B4 Relay
2026-07-08 11:36 ` Bartosz Golaszewski
2026-07-08 13:14 ` Xi Ruoyao
6 siblings, 2 replies; 13+ messages in thread
From: Miao Wang via B4 Relay @ 2026-07-07 21:16 UTC (permalink / raw)
To: Binbin Zhou, Chong Qiao, Lee Jones, Huacai Chen, Corey Minyard,
Linus Walleij, Bartosz Golaszewski
Cc: Xi Ruoyao, WANG Xuerui, Yinbo Zhu, Jiaxun Yang, mfd, linux-kernel,
linux-gpio, openipmi-developer, Miao Wang
From: Miao Wang <shankerwangmiao@gmail.com>
The reset event of BMC is captured through GPIO. However, this driver
bypasses the GPIO framework and directly accesses the GPIO controller
through the fixed address. When the same GPIO controller is also
exposed through ACPI and probed by the corresponding GPIO driver,
there would be a conflict between the two drivers.
This patch will try to find the GPIO through declared GPIO pin in the
_CRS resources of the ACPI node. If no such delaration is found, the
driver will fall back to search for the correct GPIO controller and pin
according to the fixed address and pin number. A possible DSDT
declaration for the GPIO pin might be as follows:
Device (BMC0) {
Name (_ADR, ...) // Match the PCI address of the BMC device
// \_SB.GPO1 is the ACPI path of the GPIO controller
Name (_CRS, ResourceTemplate () {
GpioInt (Edge, ActiveLow, Exclusive, PullNone, 0,
"\\_SB.GPO1", 0) {
14 // 14 is the GPIO pin number
}
}
Signed-off-by: Miao Wang <shankerwangmiao@gmail.com>
---
drivers/mfd/ls2k-bmc-core.c | 162 +++++++++++++++++++++++++++++++-------------
1 file changed, 115 insertions(+), 47 deletions(-)
diff --git a/drivers/mfd/ls2k-bmc-core.c b/drivers/mfd/ls2k-bmc-core.c
index f87224105b3720cca97dcef089dad63fe57bc8c2..7187b2dfddc3acfb9fdf3cb3b4675299928dd03a 100644
--- a/drivers/mfd/ls2k-bmc-core.c
+++ b/drivers/mfd/ls2k-bmc-core.c
@@ -26,6 +26,9 @@
#include <linux/stop_machine.h>
#include <linux/vt_kern.h>
#include <linux/console.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+#include <linux/gpio.h>
/* LS2K BMC resources */
#define LS2K_DISPLAY_RES_START (SZ_16M + SZ_2M)
@@ -81,18 +84,6 @@
#define PCI_REG_STRIDE 0x4
-#define LS2K_BMC_RESET_GPIO 14
-#define LOONGSON_GPIO_REG_BASE 0x1FE00500
-#define LOONGSON_GPIO_REG_SIZE 0x18
-#define LOONGSON_GPIO_OEN 0x0
-#define LOONGSON_GPIO_FUNC 0x4
-#define LOONGSON_GPIO_INTPOL 0x10
-#define LOONGSON_GPIO_INTEN 0x14
-
-#define LOONGSON_IO_INT_BASE 16
-#define LS2K_BMC_RESET_GPIO_INT_VEC (LS2K_BMC_RESET_GPIO % 8)
-#define LS2K_BMC_RESET_GPIO_GSI (LOONGSON_IO_INT_BASE + LS2K_BMC_RESET_GPIO_INT_VEC)
-
enum {
LS2K_BMC_DISPLAY,
LS2K_BMC_IPMI0,
@@ -186,6 +177,7 @@ struct ls2k_bmc_ddata {
struct work_struct bmc_reset_work;
struct ls2k_bmc_pci_data bmc_pci_data;
struct ls2k_bmc_bridge_pci_data bridge_pci_data;
+ struct gpio_desc *reset_gpio;
};
static bool ls2k_bmc_bar0_addr_is_set(struct pci_dev *pdev)
@@ -334,6 +326,22 @@ static irqreturn_t ls2k_bmc_interrupt(int irq, void *arg)
return IRQ_HANDLED;
}
+static irqreturn_t ls2k_bmc_gpio_interrupt(int irq, void *arg)
+{
+ struct ls2k_bmc_ddata *ddata = arg;
+
+ int val = gpiod_get_raw_value(ddata->reset_gpio);
+
+ /*
+ * The GPIO is active low, so when the value is 0,
+ * it indicates a reset event.
+ */
+ if (val == 0)
+ return ls2k_bmc_interrupt(irq, arg);
+
+ return IRQ_NONE;
+}
+
/*
* Saves the BMC parent device (LS7A) and its own PCI configuration space registers
* that need to be restored after BMC reset.
@@ -375,6 +383,79 @@ static void ls2k_bmc_save_pci_data(struct pci_dev *pdev, struct ls2k_bmc_ddata *
pci_read_config_dword(pdev, PCI_INTERRUPT_LINE, &ddata->bmc_pci_data.interrupt_line);
}
+static int ls2k_bmc_gpiochip_find(struct gpio_chip *gc, const void *data)
+{
+ struct acpi_device *adev;
+ struct list_head resource_list;
+ struct resource_entry *rentry;
+ struct fwnode_handle *fwnode = gc->fwnode ?: gc->parent ? gc->parent->fwnode : NULL;
+ phys_addr_t start_addr = (phys_addr_t) data;
+ int ret, found = 0;
+
+ if (!is_acpi_node(fwnode))
+ goto out;
+
+ adev = to_acpi_device_node(fwnode);
+ if (!adev)
+ goto out;
+
+ INIT_LIST_HEAD(&resource_list);
+
+ ret = acpi_dev_get_memory_resources(adev, &resource_list);
+ if (ret < 0)
+ goto out;
+ rentry = list_first_entry_or_null(&resource_list, struct resource_entry, node);
+ if (!rentry)
+ goto free_resource_list;
+ if (rentry->res->start == start_addr)
+ found = 1;
+
+free_resource_list:
+ acpi_dev_free_resource_list(&resource_list);
+out:
+ return found;
+}
+
+static struct gpio_desc *ls2k_bmc_find_gpio(struct ls2k_bmc_ddata *ddata)
+{
+ /*
+ * In conventional way, the GPIO should be obtained through ACPI or
+ * device tree. However, when the information is not available,
+ * we should find the GPIO according to the convention of the server
+ * boards with LS2K BMC, the gpio signal relelecting the reset event
+ * of the BMC should be connected to pin 14 of the GPIO input of
+ * the first CPU node. The address of that GPIO controller is fixed.
+ */
+ static const phys_addr_t LOONGSON_GPIO_REG_BASE = 0x1FE00500;
+ static const unsigned int LS2K_BMC_RESET_GPIO = 14;
+ struct gpio_desc *desc;
+ unsigned int legacy_gpio;
+ int ret;
+ struct gpio_device *gdev __free(gpio_device_put) = NULL;
+
+ dev_dbg(ddata->dev, "Searching for GPIO chip at address %pa\n", &LOONGSON_GPIO_REG_BASE);
+
+ gdev = gpio_device_find((void *)LOONGSON_GPIO_REG_BASE, ls2k_bmc_gpiochip_find);
+
+ if (!gdev) {
+ dev_dbg(ddata->dev, "cannot find GPIO chip at address %pa, deferring\n",
+ &LOONGSON_GPIO_REG_BASE);
+ return ERR_PTR(-EPROBE_DEFER);
+ }
+
+ desc = gpio_device_get_desc(gdev, LS2K_BMC_RESET_GPIO);
+ if (IS_ERR(desc))
+ return desc;
+
+ // XXX: might be better to use gpiod_request()
+ legacy_gpio = desc_to_gpio(desc);
+ ret = devm_gpio_request_one(ddata->dev, legacy_gpio, GPIOF_IN, dev_name(ddata->dev));
+ if (ret < 0)
+ return ERR_PTR(ret);
+
+ return gpio_to_desc(legacy_gpio);
+}
+
static void ls2k_bmc_cancel_wq(void *data)
{
struct ls2k_bmc_ddata *ddata = data;
@@ -384,8 +465,7 @@ static void ls2k_bmc_cancel_wq(void *data)
static int ls2k_bmc_init(struct ls2k_bmc_ddata *ddata)
{
struct pci_dev *pdev = to_pci_dev(ddata->dev);
- void __iomem *gpio_base;
- int gpio_irq, ret, val;
+ int gpio_irq, ret;
ls2k_bmc_save_pci_data(pdev, ddata);
@@ -400,44 +480,32 @@ static int ls2k_bmc_init(struct ls2k_bmc_ddata *ddata)
return ret;
}
- gpio_base = ioremap(LOONGSON_GPIO_REG_BASE, LOONGSON_GPIO_REG_SIZE);
- if (!gpio_base)
- return -ENOMEM;
-
- /* Disable GPIO output */
- val = readl(gpio_base + LOONGSON_GPIO_OEN);
- writel(val | BIT(LS2K_BMC_RESET_GPIO), gpio_base + LOONGSON_GPIO_OEN);
-
- /* Enable GPIO functionality */
- val = readl(gpio_base + LOONGSON_GPIO_FUNC);
- writel(val & ~BIT(LS2K_BMC_RESET_GPIO), gpio_base + LOONGSON_GPIO_FUNC);
-
- /* Set GPIO interrupts to low-level active */
- val = readl(gpio_base + LOONGSON_GPIO_INTPOL);
- writel(val & ~BIT(LS2K_BMC_RESET_GPIO), gpio_base + LOONGSON_GPIO_INTPOL);
-
- /* Enable GPIO interrupts */
- val = readl(gpio_base + LOONGSON_GPIO_INTEN);
- writel(val | BIT(LS2K_BMC_RESET_GPIO), gpio_base + LOONGSON_GPIO_INTEN);
+ ddata->reset_gpio = devm_gpiod_get_index_optional(&pdev->dev, NULL, 0, GPIOD_IN);
+ if (IS_ERR(ddata->reset_gpio)) {
+ ret = PTR_ERR(ddata->reset_gpio);
+ ddata->reset_gpio = NULL;
+ return dev_err_probe(ddata->dev, ret, "Failed to get reset GPIO\n");
+ }
+ if (ddata->reset_gpio == NULL) {
+ ddata->reset_gpio = ls2k_bmc_find_gpio(ddata);
+ if (IS_ERR(ddata->reset_gpio)) {
+ ret = PTR_ERR(ddata->reset_gpio);
+ ddata->reset_gpio = NULL;
+ return dev_err_probe(ddata->dev, ret, "Failed to find reset GPIO\n");
+ }
+ }
- iounmap(gpio_base);
+ gpio_irq = gpiod_to_irq(ddata->reset_gpio);
- /*
- * Since gpio_chip->to_irq is not implemented in the Loongson-3 GPIO driver,
- * acpi_register_gsi() is used to obtain the GPIO IRQ. The GPIO interrupt is a
- * watchdog interrupt that is triggered when the BMC resets.
- */
- gpio_irq = acpi_register_gsi(NULL, LS2K_BMC_RESET_GPIO_GSI, ACPI_EDGE_SENSITIVE,
- ACPI_ACTIVE_LOW);
if (gpio_irq < 0)
- return gpio_irq;
+ return dev_err_probe(ddata->dev, gpio_irq, "Failed to get GPIO IRQ\n");
- ret = devm_request_irq(ddata->dev, gpio_irq, ls2k_bmc_interrupt,
- IRQF_SHARED | IRQF_TRIGGER_FALLING, "ls2kbmc gpio", ddata);
- if (ret)
- dev_err(ddata->dev, "Failed to request LS2KBMC GPIO IRQ %d.\n", gpio_irq);
+ ret = devm_request_irq(&pdev->dev, gpio_irq, ls2k_bmc_gpio_interrupt,
+ IRQF_SHARED | IRQF_TRIGGER_FALLING, "ls2kbmc reset", ddata);
+
+ if (ret != 0)
+ return dev_err_probe(ddata->dev, ret, "Failed to request GPIO IRQ %d.\n", gpio_irq);
- acpi_unregister_gsi(LS2K_BMC_RESET_GPIO_GSI);
return ret;
}
--
2.49.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH RFC v2 7/7] mfd: ls2kbmc: Capture the reset event of BMC through GPIO
2026-07-07 21:16 ` [PATCH RFC v2 7/7] mfd: ls2kbmc: Capture the reset event of BMC through GPIO Miao Wang via B4 Relay
@ 2026-07-08 11:36 ` Bartosz Golaszewski
2026-07-08 12:15 ` Miao Wang
2026-07-08 13:14 ` Xi Ruoyao
1 sibling, 1 reply; 13+ messages in thread
From: Bartosz Golaszewski @ 2026-07-08 11:36 UTC (permalink / raw)
To: shankerwangmiao
Cc: Miao Wang via B4 Relay, Xi Ruoyao, WANG Xuerui, Yinbo Zhu,
Jiaxun Yang, mfd, linux-kernel, linux-gpio, openipmi-developer,
Binbin Zhou, Chong Qiao, Lee Jones, Huacai Chen, Corey Minyard,
Linus Walleij, Bartosz Golaszewski
On Tue, 7 Jul 2026 23:16:31 +0200, Miao Wang via B4 Relay
<devnull+shankerwangmiao.gmail.com@kernel.org> said:
> From: Miao Wang <shankerwangmiao@gmail.com>
>
> The reset event of BMC is captured through GPIO. However, this driver
> bypasses the GPIO framework and directly accesses the GPIO controller
> through the fixed address. When the same GPIO controller is also
> exposed through ACPI and probed by the corresponding GPIO driver,
> there would be a conflict between the two drivers.
>
> This patch will try to find the GPIO through declared GPIO pin in the
> _CRS resources of the ACPI node. If no such delaration is found, the
> driver will fall back to search for the correct GPIO controller and pin
> according to the fixed address and pin number. A possible DSDT
> declaration for the GPIO pin might be as follows:
>
> Device (BMC0) {
> Name (_ADR, ...) // Match the PCI address of the BMC device
> // \_SB.GPO1 is the ACPI path of the GPIO controller
> Name (_CRS, ResourceTemplate () {
> GpioInt (Edge, ActiveLow, Exclusive, PullNone, 0,
> "\\_SB.GPO1", 0) {
> 14 // 14 is the GPIO pin number
> }
> }
>
> Signed-off-by: Miao Wang <shankerwangmiao@gmail.com>
> ---
> drivers/mfd/ls2k-bmc-core.c | 162 +++++++++++++++++++++++++++++++-------------
> 1 file changed, 115 insertions(+), 47 deletions(-)
>
> diff --git a/drivers/mfd/ls2k-bmc-core.c b/drivers/mfd/ls2k-bmc-core.c
> index f87224105b3720cca97dcef089dad63fe57bc8c2..7187b2dfddc3acfb9fdf3cb3b4675299928dd03a 100644
> --- a/drivers/mfd/ls2k-bmc-core.c
> +++ b/drivers/mfd/ls2k-bmc-core.c
> @@ -26,6 +26,9 @@
> #include <linux/stop_machine.h>
> #include <linux/vt_kern.h>
> #include <linux/console.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/gpio/driver.h>
> +#include <linux/gpio.h>
I've stopped here because this is a legacy header that must not be included
and none of the interfaces in it must be used, as per the - very loud - comment
at the top of that file.
Bart
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH RFC v2 7/7] mfd: ls2kbmc: Capture the reset event of BMC through GPIO
2026-07-08 11:36 ` Bartosz Golaszewski
@ 2026-07-08 12:15 ` Miao Wang
2026-07-08 12:55 ` Bartosz Golaszewski
0 siblings, 1 reply; 13+ messages in thread
From: Miao Wang @ 2026-07-08 12:15 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Miao Wang via B4 Relay, Xi Ruoyao, WANG Xuerui, Yinbo Zhu,
Jiaxun Yang, mfd, linux-kernel, linux-gpio, openipmi-developer,
Binbin Zhou, Chong Qiao, Lee Jones, Huacai Chen, Corey Minyard,
Linus Walleij
Hi
> 2026年7月8日 19:36,Bartosz Golaszewski <brgl@kernel.org> 写道:
>
> On Tue, 7 Jul 2026 23:16:31 +0200, Miao Wang via B4 Relay
> <devnull+shankerwangmiao.gmail.com@kernel.org> said:
>> From: Miao Wang <shankerwangmiao@gmail.com>
>>
>> The reset event of BMC is captured through GPIO. However, this driver
>> bypasses the GPIO framework and directly accesses the GPIO controller
>> through the fixed address. When the same GPIO controller is also
>> exposed through ACPI and probed by the corresponding GPIO driver,
>> there would be a conflict between the two drivers.
>>
>> This patch will try to find the GPIO through declared GPIO pin in the
>> _CRS resources of the ACPI node. If no such delaration is found, the
>> driver will fall back to search for the correct GPIO controller and pin
>> according to the fixed address and pin number. A possible DSDT
>> declaration for the GPIO pin might be as follows:
>>
>> Device (BMC0) {
>> Name (_ADR, ...) // Match the PCI address of the BMC device
>> // \_SB.GPO1 is the ACPI path of the GPIO controller
>> Name (_CRS, ResourceTemplate () {
>> GpioInt (Edge, ActiveLow, Exclusive, PullNone, 0,
>> "\\_SB.GPO1", 0) {
>> 14 // 14 is the GPIO pin number
>> }
>> }
>>
>> Signed-off-by: Miao Wang <shankerwangmiao@gmail.com>
>> ---
>> drivers/mfd/ls2k-bmc-core.c | 162 +++++++++++++++++++++++++++++++-------------
>> 1 file changed, 115 insertions(+), 47 deletions(-)
>>
>> diff --git a/drivers/mfd/ls2k-bmc-core.c b/drivers/mfd/ls2k-bmc-core.c
>> index f87224105b3720cca97dcef089dad63fe57bc8c2..7187b2dfddc3acfb9fdf3cb3b4675299928dd03a 100644
>> --- a/drivers/mfd/ls2k-bmc-core.c
>> +++ b/drivers/mfd/ls2k-bmc-core.c
>> @@ -26,6 +26,9 @@
>> #include <linux/stop_machine.h>
>> #include <linux/vt_kern.h>
>> #include <linux/console.h>
>> +#include <linux/gpio/consumer.h>
>> +#include <linux/gpio/driver.h>
>> +#include <linux/gpio.h>
>
> I've stopped here because this is a legacy header that must not be included
> and none of the interfaces in it must be used, as per the - very loud - comment
> at the top of that file.
I fully understand using the legacy interface is deprecated. However, there
seems no other way to obtain a gpio line description after a gpio device
is found using gpio_device_find(). As the comment shows in the code below,
the only place I use the legacy interface is:
gdev = gpio_device_find(...);
desc = gpio_device_get_desc(gdev, LS2K_BMC_RESET_GPIO);
// XXX: might be better to use gpiod_request()
legacy_gpio = desc_to_gpio(desc);
devm_gpio_request_one(..., legacy_gpio, ...);
return gpio_to_desc(legacy_gpio);
I just borrowed the legacy gpio interface to request the irq description. I
think that gpiod_request() should be better to be used here, but it is not
an interface that is exposed. As a result, I post this patch as a PoC here
to discuss and find a better way to achieve this.
Cheers,
Miao Wang
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH RFC v2 7/7] mfd: ls2kbmc: Capture the reset event of BMC through GPIO
2026-07-08 12:15 ` Miao Wang
@ 2026-07-08 12:55 ` Bartosz Golaszewski
0 siblings, 0 replies; 13+ messages in thread
From: Bartosz Golaszewski @ 2026-07-08 12:55 UTC (permalink / raw)
To: Miao Wang
Cc: Miao Wang via B4 Relay, Xi Ruoyao, WANG Xuerui, Yinbo Zhu,
Jiaxun Yang, mfd, linux-kernel, linux-gpio, openipmi-developer,
Binbin Zhou, Chong Qiao, Lee Jones, Huacai Chen, Corey Minyard,
Linus Walleij, Bartosz Golaszewski
On Wed, 8 Jul 2026 14:15:55 +0200, Miao Wang <shankerwangmiao@gmail.com> said:
> Hi
>
>> 2026年7月8日 19:36,Bartosz Golaszewski <brgl@kernel.org> 写道:
>>
>> On Tue, 7 Jul 2026 23:16:31 +0200, Miao Wang via B4 Relay
>> <devnull+shankerwangmiao.gmail.com@kernel.org> said:
>>> From: Miao Wang <shankerwangmiao@gmail.com>
>>>
>>> The reset event of BMC is captured through GPIO. However, this driver
>>> bypasses the GPIO framework and directly accesses the GPIO controller
>>> through the fixed address. When the same GPIO controller is also
>>> exposed through ACPI and probed by the corresponding GPIO driver,
>>> there would be a conflict between the two drivers.
>>>
>>> This patch will try to find the GPIO through declared GPIO pin in the
>>> _CRS resources of the ACPI node. If no such delaration is found, the
>>> driver will fall back to search for the correct GPIO controller and pin
>>> according to the fixed address and pin number. A possible DSDT
>>> declaration for the GPIO pin might be as follows:
>>>
>>> Device (BMC0) {
>>> Name (_ADR, ...) // Match the PCI address of the BMC device
>>> // \_SB.GPO1 is the ACPI path of the GPIO controller
>>> Name (_CRS, ResourceTemplate () {
>>> GpioInt (Edge, ActiveLow, Exclusive, PullNone, 0,
>>> "\\_SB.GPO1", 0) {
>>> 14 // 14 is the GPIO pin number
>>> }
>>> }
>>>
>>> Signed-off-by: Miao Wang <shankerwangmiao@gmail.com>
>>> ---
>>> drivers/mfd/ls2k-bmc-core.c | 162 +++++++++++++++++++++++++++++++-------------
>>> 1 file changed, 115 insertions(+), 47 deletions(-)
>>>
>>> diff --git a/drivers/mfd/ls2k-bmc-core.c b/drivers/mfd/ls2k-bmc-core.c
>>> index f87224105b3720cca97dcef089dad63fe57bc8c2..7187b2dfddc3acfb9fdf3cb3b4675299928dd03a 100644
>>> --- a/drivers/mfd/ls2k-bmc-core.c
>>> +++ b/drivers/mfd/ls2k-bmc-core.c
>>> @@ -26,6 +26,9 @@
>>> #include <linux/stop_machine.h>
>>> #include <linux/vt_kern.h>
>>> #include <linux/console.h>
>>> +#include <linux/gpio/consumer.h>
>>> +#include <linux/gpio/driver.h>
>>> +#include <linux/gpio.h>
>>
>> I've stopped here because this is a legacy header that must not be included
>> and none of the interfaces in it must be used, as per the - very loud - comment
>> at the top of that file.
>
> I fully understand using the legacy interface is deprecated. However, there
> seems no other way to obtain a gpio line description after a gpio device
> is found using gpio_device_find(). As the comment shows in the code below,
> the only place I use the legacy interface is:
>
> gdev = gpio_device_find(...);
> desc = gpio_device_get_desc(gdev, LS2K_BMC_RESET_GPIO);
>
No, new code using legacy API is *not* acceptable. That's an official NAK.
> // XXX: might be better to use gpiod_request()
> legacy_gpio = desc_to_gpio(desc);
> devm_gpio_request_one(..., legacy_gpio, ...);
> return gpio_to_desc(legacy_gpio);
>
> I just borrowed the legacy gpio interface to request the irq description. I
> think that gpiod_request() should be better to be used here, but it is not
> an interface that is exposed. As a result, I post this patch as a PoC here
> to discuss and find a better way to achieve this.
>
If the firmware doesn't describe the GPIO, you have at least two alternatives.
Please look at Documentation/driver-api/gpio/legacy-boards.rst. You should be
able to use either software nodes or GPIO lookup tables. This document
describes the conversion from the latter to the former but - while software
nodes are preferred - lookup tables are not deprecated so feel free to use
it to set up the descriptors.
Bart
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH RFC v2 7/7] mfd: ls2kbmc: Capture the reset event of BMC through GPIO
2026-07-07 21:16 ` [PATCH RFC v2 7/7] mfd: ls2kbmc: Capture the reset event of BMC through GPIO Miao Wang via B4 Relay
2026-07-08 11:36 ` Bartosz Golaszewski
@ 2026-07-08 13:14 ` Xi Ruoyao
2026-07-08 14:16 ` Miao Wang
1 sibling, 1 reply; 13+ messages in thread
From: Xi Ruoyao @ 2026-07-08 13:14 UTC (permalink / raw)
To: shankerwangmiao, Binbin Zhou, Chong Qiao, Lee Jones, Huacai Chen,
Corey Minyard, Linus Walleij, Bartosz Golaszewski
Cc: WANG Xuerui, Yinbo Zhu, Jiaxun Yang, mfd, linux-kernel,
linux-gpio, openipmi-developer
On Wed, 2026-07-08 at 05:16 +0800, Miao Wang via B4 Relay wrote:
> From: Miao Wang <shankerwangmiao@gmail.com>
>
> The reset event of BMC is captured through GPIO. However, this driver
> bypasses the GPIO framework and directly accesses the GPIO controller
> through the fixed address. When the same GPIO controller is also
> exposed through ACPI and probed by the corresponding GPIO driver,
> there would be a conflict between the two drivers.
>
> This patch will try to find the GPIO through declared GPIO pin in the
> _CRS resources of the ACPI node. If no such delaration is found, the
> driver will fall back to search for the correct GPIO controller and pin
> according to the fixed address and pin number. A possible DSDT
> declaration for the GPIO pin might be as follows:
>
> Device (BMC0) {
> Name (_ADR, ...) // Match the PCI address of the BMC device
> // \_SB.GPO1 is the ACPI path of the GPIO controller
> Name (_CRS, ResourceTemplate () {
> GpioInt (Edge, ActiveLow, Exclusive, PullNone, 0,
> "\\_SB.GPO1", 0) {
> 14 // 14 is the GPIO pin number
> }
> }
I think this is a proposal without real implementation yet? If so...
/* snip */
> + adev = to_acpi_device_node(fwnode);
> + if (!adev)
> + goto out;
> +
> + INIT_LIST_HEAD(&resource_list);
> +
> + ret = acpi_dev_get_memory_resources(adev, &resource_list);
> + if (ret < 0)
> + goto out;
> + rentry = list_first_entry_or_null(&resource_list, struct resource_entry, node);
> + if (!rentry)
> + goto free_resource_list;
> + if (rentry->res->start == start_addr)
> + found = 1;
> +
> +free_resource_list:
> + acpi_dev_free_resource_list(&resource_list);
... consider adding a _DSD method to label (like "bmc-reset") the GPIO
for the proposed BMC0 device so you can use devm_gpiod_get to get the
GPIO, instead of using the hand-brew code to parse the ACPI node.
See https://www.kernel.org/doc/html/latest/firmware-guide/acpi/gpio-properties.html.
Combining this with Bartosz's comment, the logic would be like:
if (missing the ACPI node)
assign a swnode to label "gpio14" as "bmc-reset";
gpio_desc = devm_gpiod_get(&dev, "bmc-reset", GPIOD_IN);
And such a proposal will need to be discussed with Loongson. Yes I know
people may hate the "control" from the vendor, but having some
effectively dead code (i.e. supporting some non-exist firmware) in the
kernel is worse.
--
Xi Ruoyao <xry111@xry111.site>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH RFC v2 7/7] mfd: ls2kbmc: Capture the reset event of BMC through GPIO
2026-07-08 13:14 ` Xi Ruoyao
@ 2026-07-08 14:16 ` Miao Wang
0 siblings, 0 replies; 13+ messages in thread
From: Miao Wang @ 2026-07-08 14:16 UTC (permalink / raw)
To: Xi Ruoyao
Cc: Binbin Zhou, Chong Qiao, Lee Jones, Huacai Chen, Corey Minyard,
Linus Walleij, Bartosz Golaszewski, WANG Xuerui, Yinbo Zhu,
Jiaxun Yang, mfd, linux-kernel, linux-gpio, openipmi-developer
Hi,
> 2026年7月8日 21:14,Xi Ruoyao <xry111@xry111.site> 写道:
>
> On Wed, 2026-07-08 at 05:16 +0800, Miao Wang via B4 Relay wrote:
>> From: Miao Wang <shankerwangmiao@gmail.com>
>>
>> The reset event of BMC is captured through GPIO. However, this driver
>> bypasses the GPIO framework and directly accesses the GPIO controller
>> through the fixed address. When the same GPIO controller is also
>> exposed through ACPI and probed by the corresponding GPIO driver,
>> there would be a conflict between the two drivers.
>>
>> This patch will try to find the GPIO through declared GPIO pin in the
>> _CRS resources of the ACPI node. If no such delaration is found, the
>> driver will fall back to search for the correct GPIO controller and pin
>> according to the fixed address and pin number. A possible DSDT
>> declaration for the GPIO pin might be as follows:
>>
>> Device (BMC0) {
>> Name (_ADR, ...) // Match the PCI address of the BMC device
>> // \_SB.GPO1 is the ACPI path of the GPIO controller
>> Name (_CRS, ResourceTemplate () {
>> GpioInt (Edge, ActiveLow, Exclusive, PullNone, 0,
>> "\\_SB.GPO1", 0) {
>> 14 // 14 is the GPIO pin number
>> }
>> }
>
> I think this is a proposal without real implementation yet? If so...
>
> /* snip */
>
>> + adev = to_acpi_device_node(fwnode);
>> + if (!adev)
>> + goto out;
>> +
>> + INIT_LIST_HEAD(&resource_list);
>> +
>> + ret = acpi_dev_get_memory_resources(adev, &resource_list);
>> + if (ret < 0)
>> + goto out;
>> + rentry = list_first_entry_or_null(&resource_list, struct resource_entry, node);
>> + if (!rentry)
>> + goto free_resource_list;
>> + if (rentry->res->start == start_addr)
>> + found = 1;
>> +
>> +free_resource_list:
>> + acpi_dev_free_resource_list(&resource_list);
>
> ... consider adding a _DSD method to label (like "bmc-reset") the GPIO
> for the proposed BMC0 device so you can use devm_gpiod_get to get the
> GPIO, instead of using the hand-brew code to parse the ACPI node.
> See https://www.kernel.org/doc/html/latest/firmware-guide/acpi/gpio-properties.html.
Yes, it is a proposal. GpioInt() in the _CRS() should be at least
required to associate the BMC device to the GPIO pin. Having a _DSD
might be better to label the gpio pin with human readable label. I
however don't think _DSD is important because there is only one pin
needed, and devm_gpiod_get_index can be used to obtain the gpio line
description using the index in _CRS()
>
> Combining this with Bartosz's comment, the logic would be like:
>
> if (missing the ACPI node)
> assign a swnode to label "gpio14" as "bmc-reset";
I'll further look into whether swnode can be used.
> gpio_desc = devm_gpiod_get(&dev, "bmc-reset", GPIOD_IN);
>
> And such a proposal will need to be discussed with Loongson. Yes I know
> people may hate the "control" from the vendor, but having some
> effectively dead code (i.e. supporting some non-exist firmware) in the
> kernel is worse.
I'm open with such discussions.
Cheers,
Miao Wang
^ permalink raw reply [flat|nested] 13+ messages in thread