The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH] mfd: rohm: Factor out power button registration
@ 2026-06-18 18:58 Dmitry Torokhov
  0 siblings, 0 replies; only message in thread
From: Dmitry Torokhov @ 2026-06-18 18:58 UTC (permalink / raw)
  To: Lee Jones; +Cc: Matti Vaittinen, linux-kernel

Factor out the power button registration logic using software nodes
from rohm-bd718x7 and rohm-bd71828 drivers into a shared module
rohm-pwrbutton.

This reduces duplication and makes it easier to support other ROHM
PMICs with similar power button configurations.

Suggested-by: Lee Jones <lee@kernel.org>
Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 MAINTAINERS                  |   2 +
 drivers/mfd/Kconfig          |   6 ++
 drivers/mfd/Makefile         |   1 +
 drivers/mfd/rohm-bd71828.c   |  84 ++------------------------
 drivers/mfd/rohm-bd718x7.c   |  84 ++------------------------
 drivers/mfd/rohm-pwrbutton.c | 112 +++++++++++++++++++++++++++++++++++
 drivers/mfd/rohm-pwrbutton.h |  12 ++++
 7 files changed, 141 insertions(+), 160 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index f1caa6e5198b..40c46a7363fb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -23524,6 +23524,8 @@ F:	drivers/mfd/rohm-bd71828.c
 F:	drivers/mfd/rohm-bd718x7.c
 F:	drivers/mfd/rohm-bd9576.c
 F:	drivers/mfd/rohm-bd96801.c
+F:	drivers/mfd/rohm-pwrbutton.c
+F:	drivers/mfd/rohm-pwrbutton.h
 F:	drivers/regulator/bd71815-regulator.c
 F:	drivers/regulator/bd71828-regulator.c
 F:	drivers/regulator/bd718x7-regulator.c
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 763ce6a34782..8d04e1b1f8c8 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -2208,6 +2208,10 @@ config MFD_STW481X
 	  in various ST Microelectronics and ST-Ericsson embedded
 	  Nomadik series.
 
+config MFD_ROHM_PWRBUTTON
+	tristate
+	select MFD_CORE
+
 config MFD_ROHM_BD718XX
 	tristate "ROHM BD71837 Power Management IC"
 	depends on I2C=y
@@ -2215,6 +2219,7 @@ config MFD_ROHM_BD718XX
 	select REGMAP_I2C
 	select REGMAP_IRQ
 	select MFD_CORE
+	select MFD_ROHM_PWRBUTTON
 	help
 	  Select this option to get support for the ROHM BD71837
 	  Power Management ICs. BD71837 is designed to power processors like
@@ -2228,6 +2233,7 @@ config MFD_ROHM_BD71828
 	select REGMAP_I2C
 	select REGMAP_IRQ
 	select MFD_CORE
+	select MFD_ROHM_PWRBUTTON
 	help
 	  Select this option to get support for the ROHM BD71815, BD71828,
 	  BD71879, BD72720 and BD73900 Power Management ICs (PMICs). These are
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index dd4bb7e77c33..72d3944b0ad8 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -273,6 +273,7 @@ obj-$(CONFIG_MFD_STM32_TIMERS) 	+= stm32-timers.o
 obj-$(CONFIG_MFD_MXS_LRADC)     += mxs-lradc.o
 obj-$(CONFIG_MFD_SC27XX_PMIC)	+= sprd-sc27xx-spi.o
 obj-$(CONFIG_RAVE_SP_CORE)	+= rave-sp.o
+obj-$(CONFIG_MFD_ROHM_PWRBUTTON)	+= rohm-pwrbutton.o
 obj-$(CONFIG_MFD_ROHM_BD71828)	+= rohm-bd71828.o
 obj-$(CONFIG_MFD_ROHM_BD718XX)	+= rohm-bd718x7.o
 obj-$(CONFIG_MFD_ROHM_BD957XMUF)	+= rohm-bd9576.o
diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c
index 5fb6142cf087..dfc23cd13ef2 100644
--- a/drivers/mfd/rohm-bd71828.c
+++ b/drivers/mfd/rohm-bd71828.c
@@ -5,8 +5,6 @@
  * ROHM BD718[15/28/79] and BD72720 PMIC driver
  */
 
-#include <linux/device/devres.h>
-#include <linux/gfp_types.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
@@ -19,10 +17,11 @@
 #include <linux/mfd/rohm-generic.h>
 #include <linux/module.h>
 #include <linux/of.h>
-#include <linux/property.h>
 #include <linux/regmap.h>
 #include <linux/types.h>
 
+#include "rohm-pwrbutton.h"
+
 #define BD72720_TYPED_IRQ_REG(_irq, _stat_offset, _mask, _type_offset)     \
 	[_irq] = {							   \
 		.reg_offset = (_stat_offset),				   \
@@ -859,83 +858,7 @@ static int set_clk_mode(struct device *dev, struct regmap *regmap,
 				  OUT32K_MODE_CMOS);
 }
 
-static const struct property_entry bd71828_powerkey_parent_props[] = {
-	PROPERTY_ENTRY_STRING("label", "bd71828-pwrkey"),
-	{ }
-};
-
-static const struct property_entry bd71828_powerkey_props[] = {
-	PROPERTY_ENTRY_U32("linux,code", KEY_POWER),
-	PROPERTY_ENTRY_BOOL("wakeup-source"),
-	{ }
-};
-
-#define GPIO_KEYS  0	/* Node corresponding to gpio-keys device itself */
-#define PWRON_KEY  1	/* Node describing power button in gpio-keys */
-
-static int bd71828_i2c_register_swnodes(const struct software_node *nodes)
-{
-	const struct software_node * const node_group[] = {
-		&nodes[GPIO_KEYS], &nodes[PWRON_KEY], NULL
-	};
-
-	return software_node_register_node_group(node_group);
-}
-
-static void bd71828_i2c_unregister_swnodes(void *data)
-{
-	const struct software_node *nodes = data;
-	const struct software_node * const node_group[] = {
-		&nodes[GPIO_KEYS], &nodes[PWRON_KEY], NULL
-	};
-
-	software_node_unregister_node_group(node_group);
-}
-
-static int bd71828_i2c_register_pwrbutton(struct device *dev, int button_irq,
-					  struct irq_domain *irq_domain)
-{
-	const struct resource res[] = {
-		DEFINE_RES_IRQ_NAMED(button_irq, "bd71828-pwrkey"),
-	};
-	struct mfd_cell gpio_keys_cell = {
-		.name = "gpio-keys",
-		.resources = res,
-		.num_resources = ARRAY_SIZE(res),
-	};
-	struct software_node *nodes;
-	int ret;
 
-	nodes = devm_kcalloc(dev, 2, sizeof(*nodes), GFP_KERNEL);
-	if (!nodes)
-		return -ENOMEM;
-
-	nodes[GPIO_KEYS].name = devm_kasprintf(dev, GFP_KERNEL, "%s-power-key", dev_name(dev));
-	if (!nodes[GPIO_KEYS].name)
-		return -ENOMEM;
-
-	nodes[GPIO_KEYS].properties = bd71828_powerkey_parent_props;
-
-	nodes[PWRON_KEY].parent = &nodes[GPIO_KEYS];
-	nodes[PWRON_KEY].properties = bd71828_powerkey_props;
-
-	ret = bd71828_i2c_register_swnodes(nodes);
-	if (ret)
-		return ret;
-
-	ret = devm_add_action_or_reset(dev, bd71828_i2c_unregister_swnodes, nodes);
-	if (ret)
-		return ret;
-
-	gpio_keys_cell.swnode = &nodes[GPIO_KEYS];
-
-	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, &gpio_keys_cell, 1,
-				   NULL, 0, irq_domain);
-	if (ret)
-		return dev_err_probe(dev, ret, "Failed to register power-button");
-
-	return 0;
-}
 
 static struct i2c_client *bd71828_dev;
 static void bd71828_power_off(void)
@@ -1096,7 +1019,8 @@ static int bd71828_i2c_probe(struct i2c_client *i2c)
 		return dev_err_probe(&i2c->dev, ret, "Failed to create subdevices\n");
 
 	if (button_irq) {
-		ret = bd71828_i2c_register_pwrbutton(&i2c->dev, button_irq, irq_domain);
+		ret = rohm_mfd_register_pwrbutton(&i2c->dev, button_irq,
+						  "bd71828-pwrkey", true, irq_domain);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c
index be2acc429fe3..bab3b1c2445b 100644
--- a/drivers/mfd/rohm-bd718x7.c
+++ b/drivers/mfd/rohm-bd718x7.c
@@ -7,8 +7,6 @@
 // Datasheet for BD71837MWV available from
 // https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e
 
-#include <linux/device/devres.h>
-#include <linux/gfp_types.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
@@ -16,10 +14,11 @@
 #include <linux/mfd/core.h>
 #include <linux/module.h>
 #include <linux/of.h>
-#include <linux/property.h>
 #include <linux/regmap.h>
 #include <linux/types.h>
 
+#include "rohm-pwrbutton.h"
+
 static struct mfd_cell bd71837_mfd_cells[] = {
 	{ .name = "bd71837-clk", },
 	{ .name = "bd71837-pmic", },
@@ -105,83 +104,7 @@ static int bd718xx_init_press_duration(struct regmap *regmap,
 	return 0;
 }
 
-static const struct property_entry bd718xx_powerkey_parent_props[] = {
-	PROPERTY_ENTRY_STRING("label", "bd718xx-pwrkey"),
-	{ }
-};
-
-static const struct property_entry bd718xx_powerkey_props[] = {
-	PROPERTY_ENTRY_U32("linux,code", KEY_POWER),
-	{ }
-};
-
-static const struct resource bd718xx_powerkey_resources[] = {
-	DEFINE_RES_IRQ_NAMED(BD718XX_INT_PWRBTN_S, "bd718xx-pwrkey"),
-};
-
-#define GPIO_KEYS  0	/* Node corresponding to gpio-keys device itself */
-#define PWRON_KEY  1	/* Node describing power button in gpio-keys */
-
-static int bd718xx_i2c_register_swnodes(const struct software_node *nodes)
-{
-	const struct software_node * const node_group[] = {
-		&nodes[GPIO_KEYS], &nodes[PWRON_KEY], NULL
-	};
-
-	return software_node_register_node_group(node_group);
-}
-
-static void bd718xx_i2c_unregister_swnodes(void *data)
-{
-	const struct software_node *nodes = data;
-	const struct software_node * const node_group[] = {
-		&nodes[GPIO_KEYS], &nodes[PWRON_KEY], NULL
-	};
-
-	software_node_unregister_node_group(node_group);
-}
 
-static int bd718xx_i2c_register_pwrbutton(struct device *dev,
-					  struct irq_domain *irq_domain)
-{
-	struct mfd_cell gpio_keys_cell = {
-		.name = "gpio-keys",
-		.resources = bd718xx_powerkey_resources,
-		.num_resources = ARRAY_SIZE(bd718xx_powerkey_resources),
-	};
-	struct software_node *nodes;
-	int ret;
-
-	nodes = devm_kcalloc(dev, 2, sizeof(*nodes), GFP_KERNEL);
-	if (!nodes)
-		return -ENOMEM;
-
-	nodes[GPIO_KEYS].name = devm_kasprintf(dev, GFP_KERNEL, "%s-power-key", dev_name(dev));
-	if (!nodes[GPIO_KEYS].name)
-		return -ENOMEM;
-
-	nodes[GPIO_KEYS].properties = bd718xx_powerkey_parent_props;
-
-	nodes[PWRON_KEY].parent = &nodes[GPIO_KEYS];
-	nodes[PWRON_KEY].properties = bd718xx_powerkey_props;
-
-	ret = bd718xx_i2c_register_swnodes(nodes);
-	if (ret)
-		return ret;
-
-	ret = devm_add_action_or_reset(dev, bd718xx_i2c_unregister_swnodes, nodes);
-	if (ret)
-		return ret;
-
-	gpio_keys_cell.swnode = &nodes[GPIO_KEYS];
-
-	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, &gpio_keys_cell, 1,
-				   NULL, 0, irq_domain);
-	if (ret)
-		return dev_err_probe(dev, ret, "Failed to register power-button");
-
-	return 0;
-}
 
 static int bd718xx_i2c_probe(struct i2c_client *i2c)
 {
@@ -235,7 +158,8 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c)
 	if (ret)
 		return dev_err_probe(&i2c->dev, ret, "Failed to create subdevices\n");
 
-	ret = bd718xx_i2c_register_pwrbutton(&i2c->dev, irq_domain);
+	ret = rohm_mfd_register_pwrbutton(&i2c->dev, BD718XX_INT_PWRBTN_S,
+					  "bd718xx-pwrkey", false, irq_domain);
 	if (ret)
 		return ret;
 
diff --git a/drivers/mfd/rohm-pwrbutton.c b/drivers/mfd/rohm-pwrbutton.c
new file mode 100644
index 000000000000..e0cb74fdd73c
--- /dev/null
+++ b/drivers/mfd/rohm-pwrbutton.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Shared helper for ROHM PMIC power button registration
+ *
+ * Copyright 2018, 2019 ROHM Semiconductors
+ * Copyright 2026 Google LLC
+ */
+
+#include <linux/device/devres.h>
+#include <linux/gfp_types.h>
+#include <linux/input.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/slab.h>
+
+#include "rohm-pwrbutton.h"
+
+#define GPIO_KEYS  0	/* Node corresponding to gpio-keys device itself */
+#define PWRON_KEY  1	/* Node describing power button in gpio-keys */
+
+static int rohm_mfd_pwrbutton_register_swnodes(const struct software_node *nodes)
+{
+	const struct software_node * const node_group[] = {
+		&nodes[GPIO_KEYS], &nodes[PWRON_KEY], NULL
+	};
+
+	return software_node_register_node_group(node_group);
+}
+
+static void rohm_mfd_pwrbutton_unregister_swnodes(void *data)
+{
+	const struct software_node *nodes = data;
+	const struct software_node * const node_group[] = {
+		&nodes[GPIO_KEYS], &nodes[PWRON_KEY], NULL
+	};
+
+	software_node_unregister_node_group(node_group);
+}
+
+int rohm_mfd_register_pwrbutton(struct device *dev, int irq, const char *name,
+				bool wakeup, struct irq_domain *irq_domain)
+{
+	const struct resource res[] = {
+		DEFINE_RES_IRQ_NAMED(irq, name),
+	};
+	struct mfd_cell gpio_keys_cell = {
+		.name = "gpio-keys",
+		.resources = res,
+		.num_resources = ARRAY_SIZE(res),
+	};
+	struct property_entry *parent_props;
+	struct property_entry *child_props;
+	struct software_node *nodes;
+	int n_props;
+	int ret;
+
+	if (irq <= 0)
+		return -EINVAL;
+
+	nodes = devm_kcalloc(dev, 2, sizeof(*nodes), GFP_KERNEL);
+	if (!nodes)
+		return -ENOMEM;
+
+	nodes[GPIO_KEYS].name = devm_kasprintf(dev, GFP_KERNEL, "%s-power-key", dev_name(dev));
+	if (!nodes[GPIO_KEYS].name)
+		return -ENOMEM;
+
+	parent_props = devm_kcalloc(dev, 2, sizeof(*parent_props), GFP_KERNEL);
+	if (!parent_props)
+		return -ENOMEM;
+
+	parent_props[0] = PROPERTY_ENTRY_STRING("label", name);
+	nodes[GPIO_KEYS].properties = parent_props;
+
+	n_props = 2; /* linux,code and terminator */
+	if (wakeup)
+		n_props++;
+
+	child_props = devm_kcalloc(dev, n_props, sizeof(*child_props), GFP_KERNEL);
+	if (!child_props)
+		return -ENOMEM;
+
+	child_props[0] = PROPERTY_ENTRY_U32("linux,code", KEY_POWER);
+	if (wakeup)
+		child_props[1] = PROPERTY_ENTRY_BOOL("wakeup-source");
+
+	nodes[PWRON_KEY].parent = &nodes[GPIO_KEYS];
+	nodes[PWRON_KEY].properties = child_props;
+
+	ret = rohm_mfd_pwrbutton_register_swnodes(nodes);
+	if (ret)
+		return ret;
+
+	ret = devm_add_action_or_reset(dev, rohm_mfd_pwrbutton_unregister_swnodes, nodes);
+	if (ret)
+		return ret;
+
+	gpio_keys_cell.swnode = &nodes[GPIO_KEYS];
+
+	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, &gpio_keys_cell, 1,
+				   NULL, 0, irq_domain);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to register power-button");
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rohm_mfd_register_pwrbutton);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dmitry Torokhov <dmitry.torokhov@gmail.com>");
+MODULE_DESCRIPTION("Shared helper for ROHM PMIC power button registration");
diff --git a/drivers/mfd/rohm-pwrbutton.h b/drivers/mfd/rohm-pwrbutton.h
new file mode 100644
index 000000000000..985bd37a4ad0
--- /dev/null
+++ b/drivers/mfd/rohm-pwrbutton.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef __LINUX_MFD_ROHM_PWRBUTTON_H__
+#define __LINUX_MFD_ROHM_PWRBUTTON_H__
+
+struct device;
+struct irq_domain;
+
+int rohm_mfd_register_pwrbutton(struct device *dev, int irq, const char *name,
+				bool wakeup, struct irq_domain *irq_domain);
+
+#endif /* __LINUX_MFD_ROHM_PWRBUTTON_H__ */
-- 
2.55.0.rc0.738.g0c8ab3ebcc-goog


-- 
Dmitry

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-06-18 18:58 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-18 18:58 [PATCH] mfd: rohm: Factor out power button registration Dmitry Torokhov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox