[PATCH v1 4/4] gpio: phytium: add ACPI support for SGPIO

From: Zhu Ling

Date: Sun Mar 01 2026 - 20:48:56 EST


Add ACPI match support for the Phytium SGPIO controller and allow
fetching the APB clock frequency from firmware properties when running
under ACPI.

Keep the device-tree clock path intact for non-ACPI systems.

Signed-off-by: Zhu Ling <1536943441@xxxxxx>
---
drivers/gpio/gpio-phytium-sgpio.c | 44 +++++++++++++++++++++++--------
1 file changed, 33 insertions(+), 11 deletions(-)

diff --git a/drivers/gpio/gpio-phytium-sgpio.c b/drivers/gpio/gpio-phytium-sgpio.c
index 397244bbf..b52531f3c 100644
--- a/drivers/gpio/gpio-phytium-sgpio.c
+++ b/drivers/gpio/gpio-phytium-sgpio.c
@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/string.h>
+#include <linux/acpi.h>

#define SGPIO_CTL0_REG 0x00
#define SGPIO_CTL0_REG_ENABLE BIT(0)
@@ -42,17 +43,21 @@
#define SGPIO_RDATA_REG(x) (SGPIO_RDATA0_REG + (x) * 4)

#define DEFAULT_L3_L0 0
+#define DEFAULT_CLK 50000000

#define GPIO_GROUP(x) ((x) >> 6)
#define GPIO_OFFSET(x) ((x) & GENMASK(5, 0))
#define GPIO_BIT(x) BIT(GPIO_OFFSET(x) >> 1)

+#define GPIO_SGPIO_DRIVER_VERSION "1.1.0"
+
struct phytium_sgpio {
struct gpio_chip gc;
void __iomem *regs;
unsigned int ngpios;
struct clk *pclk;

+ /* Serialize value access with IRQ completion flow. */
struct mutex lock;
struct completion completion;
};
@@ -154,7 +159,7 @@ static int phytium_sgpio_get(struct gpio_chip *gc, unsigned int offset)
rc = !!(val & GPIO_BIT(offset));

err:
- /* Disalbe Rx to hold the value */
+ /* Disable Rx to hold the value */
writel(ctl0 | SGPIO_CTL0_REG_RX_DISABLE, gpio->regs + SGPIO_CTL0_REG);
mutex_unlock(&gpio->lock);

@@ -229,17 +234,26 @@ static int phytium_sgpio_probe(struct platform_device *pdev)
return -EINVAL;
}

- gpio->pclk = devm_clk_get(dev, NULL);
- if (IS_ERR(gpio->pclk)) {
- dev_err(dev, "Could not get the APB clock property\n");
- return PTR_ERR(gpio->pclk);
- }
- rc = clk_prepare_enable(gpio->pclk);
- if (rc) {
- dev_err(dev, "failed to enable pclk: %d\n", rc);
- return rc;
+ if (has_acpi_companion(dev)) {
+ device_property_read_u32(dev, "pclk_freq", &pclk_freq);
+ if (!pclk_freq || pclk_freq != 50000000) {
+ dev_err(dev, "Could not get APB clock property from acpi, use default clk!\n");
+ pclk_freq = DEFAULT_CLK;
+ }
+
+ } else {
+ gpio->pclk = devm_clk_get(dev, NULL);
+ if (IS_ERR(gpio->pclk)) {
+ dev_err(dev, "Could not get the APB clock property\n");
+ return PTR_ERR(gpio->pclk);
+ }
+ rc = clk_prepare_enable(gpio->pclk);
+ if (rc) {
+ dev_err(dev, "failed to enable pclk: %d\n", rc);
+ return rc;
+ }
+ pclk_freq = clk_get_rate(gpio->pclk);
}
- pclk_freq = clk_get_rate(gpio->pclk);

/*
* From the datasheet:
@@ -287,10 +301,17 @@ static const struct of_device_id phytium_sgpio_of_match[] = {
};
MODULE_DEVICE_TABLE(of, phytium_sgpio_of_match);

+static const struct acpi_device_id phytium_sgpio_acpi_match[] = {
+ { "PHYT0031", 0},
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, phytium_sgpio_acpi_match);
+
static struct platform_driver phytium_sgpio_driver = {
.driver = {
.name = KBUILD_MODNAME,
.of_match_table = of_match_ptr(phytium_sgpio_of_match),
+ .acpi_match_table = ACPI_PTR(phytium_sgpio_acpi_match),
},
.probe = phytium_sgpio_probe,
};
@@ -299,3 +320,4 @@ module_platform_driver(phytium_sgpio_driver);
MODULE_AUTHOR("Chen Baozi <chenbaozi@xxxxxxxxxxxxxx>");
MODULE_DESCRIPTION("Phytium SGPIO driver");
MODULE_LICENSE("GPL");
+MODULE_VERSION(GPIO_SGPIO_DRIVER_VERSION);
--
2.34.1