From 0674e2cd7f4049d0028681cc8f1f4b550327e54f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 6 Jul 2026 22:01:30 -0700 Subject: [PATCH] mfd: ucb1x00: Register software node for GPIO controller Define a static software node for the UCB1x00 GPIO controller and attach it to the core MFD device in ucb1x00_probe(). This node will also be used by the created GPIO chip. This allows machine subdrivers (such as Assabet evaluation board support) to reference the UCB1x00 GPIO controller in property entries when converting legacy platform data to software nodes, resolving pin bindings directly via the attached firmware node without relying on name matching. Assisted-by: Antigravity:gemini-3.5-flash Signed-off-by: Dmitry Torokhov Acked-by: Arnd Bergmann Reviewed-by: Bartosz Golaszewski Link: https://patch.msgid.link/20260706-ucb1x00-assabet-swnode-v2-1-e6271ea3d3dc@gmail.com Signed-off-by: Lee Jones --- drivers/mfd/ucb1x00-core.c | 16 +++++++++++++++- include/linux/mfd/ucb1x00.h | 3 +++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c index 16f64e2b2f77..90edf0352d05 100644 --- a/drivers/mfd/ucb1x00-core.c +++ b/drivers/mfd/ucb1x00-core.c @@ -25,6 +25,7 @@ #include #include #include +#include #include static DEFINE_MUTEX(ucb1x00_mutex); @@ -492,6 +493,11 @@ static struct class ucb1x00_class = { .dev_release = ucb1x00_release, }; +const struct software_node ucb1x00_gpiochip_node = { + .name = "ucb1x00-gpio", +}; +EXPORT_SYMBOL_GPL(ucb1x00_gpiochip_node); + static int ucb1x00_probe(struct mcp *mcp) { struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data; @@ -530,6 +536,10 @@ static int ucb1x00_probe(struct mcp *mcp) ucb->id = id; ucb->mcp = mcp; + ret = device_add_software_node(&ucb->dev, &ucb1x00_gpiochip_node); + if (ret) + goto err_swnode_add; + ret = device_add(&ucb->dev); if (ret) goto err_dev_add; @@ -604,6 +614,8 @@ static int ucb1x00_probe(struct mcp *mcp) err_no_irq: device_del(&ucb->dev); err_dev_add: + device_remove_software_node(&ucb->dev); + err_swnode_add: put_device(&ucb->dev); out: if (pdata && pdata->reset) @@ -630,7 +642,9 @@ static void ucb1x00_remove(struct mcp *mcp) irq_set_chained_handler(ucb->irq, NULL); irq_free_descs(ucb->irq_base, 16); - device_unregister(&ucb->dev); + device_del(&ucb->dev); + device_remove_software_node(&ucb->dev); + put_device(&ucb->dev); if (pdata && pdata->reset) pdata->reset(UCB_RST_REMOVE); diff --git a/include/linux/mfd/ucb1x00.h b/include/linux/mfd/ucb1x00.h index ede237384723..214c71a12e84 100644 --- a/include/linux/mfd/ucb1x00.h +++ b/include/linux/mfd/ucb1x00.h @@ -103,6 +103,9 @@ #define UCB_MODE_DYN_VFLAG_ENA (1 << 12) #define UCB_MODE_AUD_OFF_CAN (1 << 13) +struct software_node; +extern const struct software_node ucb1x00_gpiochip_node; + enum ucb1x00_reset { UCB_RST_PROBE, UCB_RST_RESUME,