* [PATCH v5 0/5] Fix, extend and support OF to mc13xxx pwrbutton
@ 2025-10-08  6:43 Alexander Kurz
  2025-10-08  6:43 ` [PATCH v5 1/5] Input: mc13783-pwrbutton: use managed resources Alexander Kurz
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Alexander Kurz @ 2025-10-08  6:43 UTC (permalink / raw)
  To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Dzmitry Sankouski, Dr. David Alan Gilbert,
	Heiko Stuebner, Uwe Kleine-König, devicetree, linux-input
  Cc: linux-kernel, Alexander Kurz
Goal of this patch series is to make the mc13892 PWRON1 button usable,
found e.g. on amazon kindle D01100/D01200/EY21 readers.
A ten-year-old IRQ issue needed a fix, mc13783-pwrbutton had to be
extended to the other to mc13xxx PMIC as well and adding OF support.
The implementation has been tested only with PWRON1 on an mc13892.
Changes in v5:
- Link to v4: https://lore.kernel.org/linux-input/20250914193723.10544-1-akurz@blala.de/
- Rebase to current to include already merged dt-schema patches and
  a different mc13xxx related patch.
- Drop patch to use devm_mfd_add_devices and devm_regmap_add_irq_chip -
  won't like to do the proposed mutex-cleanup now.
- While adding OF support, remove the platform_data configuration
  interface as proposed by Dmitry Torokhov. Also drop the change
  to use module_platform_driver_probe.
Changes in v4:
- Link to v3: https://lore.kernel.org/linux-input/20250829201517.15374-1-akurz@blala.de/
- Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git
  tags/ib-mfd-input-rtc-v6.18 in order to include a different mc13xxx
  related patch (sorry for that).
- Re-ordered commits since dt-bindings changes already go reviewes by
  Rob Herring.
- Following Dmitrys suggestions, resources for irq are now passed from
  mfd to input allowing a more simple implementation. Work on other mfd
  cells with irq usage might still be a future project.
- Input-related differences between the mc13xxx variants are encoded
  in data structures, making the implementation of mc13892 PWRON3 a
  simple task.
Changes in v3:
- Link to v2: https://lore.kernel.org/linux-input/20250823144441.12654-1-akurz@blala.de/
- Undo all changes to led-control (rename to fsl,led-control), thanks Rob
- Restructured the new buttons node for unevaluatedProperties: false
- Various other remarks from Rob
- Rebase to current state
Changes in v2:
- Link to v1: https://lore.kernel.org/linux-input/20250817102751.29709-1-akurz@blala.de/
- Convert dt-bindings from txt to fsl,mc13xxx.yaml and add vendor prefix
  to led-control property, causing changes in dts and driver.
- Change node name from pwrbuttons to buttons
- Change property debounce-delay-value to debounce-delay-ms
- Fixed a section mismatch error
- Fixed https://lore.kernel.org/r/202508210551.VzAtE5re-lkp@intel.com/
  (wrong index used when converting to array access)
- Usage of generic device properties API in mc13783-pwrbutton.c
- Provide chip-specific max button id via platform_device_id, therefore
  swap patches 3 and 4.
Alexander Kurz (5):
  Input: mc13783-pwrbutton: use managed resources
  Input: mc13783-pwrbutton: fix irq mixup and use resources
  Input: mc13783-pwrbutton: convert pdata members to array
  Input: mc13783-pwrbutton: enable other mc13xxx PMIC
  Input: mc13783-pwrbutton: add OF support and drop platform_data
 drivers/input/misc/Kconfig             |   4 +-
 drivers/input/misc/mc13783-pwrbutton.c | 278 ++++++++++++++-----------
 drivers/mfd/mc13xxx-core.c             |  49 ++++-
 drivers/mfd/mc13xxx.h                  |   2 +
 include/linux/mfd/mc13783.h            |   4 +-
 include/linux/mfd/mc13892.h            |   1 +
 include/linux/mfd/mc13xxx.h            |  20 +-
 7 files changed, 207 insertions(+), 151 deletions(-)
-- 
2.39.5
^ permalink raw reply	[flat|nested] 6+ messages in thread
* [PATCH v5 1/5] Input: mc13783-pwrbutton: use managed resources
  2025-10-08  6:43 [PATCH v5 0/5] Fix, extend and support OF to mc13xxx pwrbutton Alexander Kurz
@ 2025-10-08  6:43 ` Alexander Kurz
  2025-10-08  6:43 ` [PATCH v5 2/5] Input: mc13783-pwrbutton: fix irq mixup and use resources Alexander Kurz
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Alexander Kurz @ 2025-10-08  6:43 UTC (permalink / raw)
  To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Dzmitry Sankouski, Dr. David Alan Gilbert,
	Heiko Stuebner, Uwe Kleine-König, devicetree, linux-input
  Cc: linux-kernel, Alexander Kurz
Use devres functionality to simplify resource freeing, dev.parent will
be set by devm_input_allocate_device().
Signed-off-by: Alexander Kurz <akurz@blala.de>
---
 drivers/input/misc/mc13783-pwrbutton.c | 28 ++++++++------------------
 1 file changed, 8 insertions(+), 20 deletions(-)
diff --git a/drivers/input/misc/mc13783-pwrbutton.c b/drivers/input/misc/mc13783-pwrbutton.c
index b83d762ae2e9..82434ea9cca5 100644
--- a/drivers/input/misc/mc13783-pwrbutton.c
+++ b/drivers/input/misc/mc13783-pwrbutton.c
@@ -21,6 +21,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
@@ -102,18 +103,13 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	pwr = input_allocate_device();
-	if (!pwr) {
-		dev_dbg(&pdev->dev, "Can't allocate power button\n");
+	pwr = devm_input_allocate_device(&pdev->dev);
+	if (!pwr)
 		return -ENOMEM;
-	}
 
-	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-	if (!priv) {
-		err = -ENOMEM;
-		dev_dbg(&pdev->dev, "Can't allocate power button\n");
-		goto free_input_dev;
-	}
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
 
 	reg |= (pdata->b1on_flags & 0x3) << MC13783_POWER_CONTROL_2_ON1BDBNC;
 	reg |= (pdata->b2on_flags & 0x3) << MC13783_POWER_CONTROL_2_ON2BDBNC;
@@ -139,7 +135,7 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 					  button_irq, "b1on", priv);
 		if (err) {
 			dev_dbg(&pdev->dev, "Can't request irq\n");
-			goto free_priv;
+			goto free_mc13xxx_lock;
 		}
 	}
 
@@ -187,7 +183,6 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 
 	pwr->name = "mc13783_pwrbutton";
 	pwr->phys = "mc13783_pwrbutton/input0";
-	pwr->dev.parent = &pdev->dev;
 
 	pwr->keycode = priv->keymap;
 	pwr->keycodemax = ARRAY_SIZE(priv->keymap);
@@ -218,12 +213,8 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 	if (pdata->b1on_flags & MC13783_BUTTON_ENABLE)
 		mc13xxx_irq_free(mc13783, MC13783_IRQ_ONOFD1, priv);
 
-free_priv:
+free_mc13xxx_lock:
 	mc13xxx_unlock(mc13783);
-	kfree(priv);
-
-free_input_dev:
-	input_free_device(pwr);
 
 	return err;
 }
@@ -245,9 +236,6 @@ static void mc13783_pwrbutton_remove(struct platform_device *pdev)
 		mc13xxx_irq_free(priv->mc13783, MC13783_IRQ_ONOFD1, priv);
 
 	mc13xxx_unlock(priv->mc13783);
-
-	input_unregister_device(priv->pwr);
-	kfree(priv);
 }
 
 static struct platform_driver mc13783_pwrbutton_driver = {
-- 
2.39.5
^ permalink raw reply related	[flat|nested] 6+ messages in thread
* [PATCH v5 2/5] Input: mc13783-pwrbutton: fix irq mixup and use resources
  2025-10-08  6:43 [PATCH v5 0/5] Fix, extend and support OF to mc13xxx pwrbutton Alexander Kurz
  2025-10-08  6:43 ` [PATCH v5 1/5] Input: mc13783-pwrbutton: use managed resources Alexander Kurz
@ 2025-10-08  6:43 ` Alexander Kurz
  2025-10-08  6:43 ` [PATCH v5 3/5] Input: mc13783-pwrbutton: convert pdata members to array Alexander Kurz
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Alexander Kurz @ 2025-10-08  6:43 UTC (permalink / raw)
  To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Dzmitry Sankouski, Dr. David Alan Gilbert,
	Heiko Stuebner, Uwe Kleine-König, devicetree, linux-input
  Cc: linux-kernel, Alexander Kurz
The mfd mc13xxx interrupt handling was migrated to regmap with commit
10f9edaeaa30 ("mfd: mc13xxx: Use regmap irq framework for interrupts").
As a consequence, button_irq() got get called with virtual irq instead
of chip-internal irq.
Make use of mfd_cell resources to pass interrupts from mfd so that
platform_get_irq_byname() can be used in mc13783-pwrbutton. The
amount of required interrupt related cleanup can be reduced this way.
Note, that mc13783-pwrbutton is still considered to support only the
model mc13783.
Signed-off-by: Alexander Kurz <akurz@blala.de>
---
 drivers/input/misc/mc13783-pwrbutton.c | 103 +++++++++++--------------
 drivers/mfd/mc13xxx-core.c             |  39 ++++++++--
 drivers/mfd/mc13xxx.h                  |   2 +
 3 files changed, 79 insertions(+), 65 deletions(-)
diff --git a/drivers/input/misc/mc13783-pwrbutton.c b/drivers/input/misc/mc13783-pwrbutton.c
index 82434ea9cca5..20f68aab6edf 100644
--- a/drivers/input/misc/mc13783-pwrbutton.c
+++ b/drivers/input/misc/mc13783-pwrbutton.c
@@ -33,13 +33,15 @@
 struct mc13783_pwrb {
 	struct input_dev *pwr;
 	struct mc13xxx *mc13783;
-#define MC13783_PWRB_B1_POL_INVERT	(1 << 0)
-#define MC13783_PWRB_B2_POL_INVERT	(1 << 1)
-#define MC13783_PWRB_B3_POL_INVERT	(1 << 2)
 	int flags;
 	unsigned short keymap[3];
+	int irq[3];
 };
 
+#define MC13783_PWRB_B1_POL_INVERT	(1 << 0)
+#define MC13783_PWRB_B2_POL_INVERT	(1 << 1)
+#define MC13783_PWRB_B3_POL_INVERT	(1 << 2)
+
 #define MC13783_REG_INTERRUPT_SENSE_1		5
 #define MC13783_IRQSENSE1_ONOFD1S		(1 << 3)
 #define MC13783_IRQSENSE1_ONOFD2S		(1 << 4)
@@ -60,27 +62,21 @@ static irqreturn_t button_irq(int irq, void *_priv)
 
 	mc13xxx_reg_read(priv->mc13783, MC13783_REG_INTERRUPT_SENSE_1, &val);
 
-	switch (irq) {
-	case MC13783_IRQ_ONOFD1:
+	if (irq == priv->irq[0]) {
 		val = val & MC13783_IRQSENSE1_ONOFD1S ? 1 : 0;
 		if (priv->flags & MC13783_PWRB_B1_POL_INVERT)
 			val ^= 1;
 		input_report_key(priv->pwr, priv->keymap[0], val);
-		break;
-
-	case MC13783_IRQ_ONOFD2:
+	} else if (irq == priv->irq[1]) {
 		val = val & MC13783_IRQSENSE1_ONOFD2S ? 1 : 0;
 		if (priv->flags & MC13783_PWRB_B2_POL_INVERT)
 			val ^= 1;
 		input_report_key(priv->pwr, priv->keymap[1], val);
-		break;
-
-	case MC13783_IRQ_ONOFD3:
+	} else if (irq == priv->irq[2]) {
 		val = val & MC13783_IRQSENSE1_ONOFD3S ? 1 : 0;
 		if (priv->flags & MC13783_PWRB_B3_POL_INVERT)
 			val ^= 1;
 		input_report_key(priv->pwr, priv->keymap[2], val);
-		break;
 	}
 
 	input_sync(priv->pwr);
@@ -96,6 +92,7 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 	struct mc13783_pwrb *priv;
 	int err = 0;
 	int reg = 0;
+	int irq = 0;
 
 	pdata = dev_get_platdata(&pdev->dev);
 	if (!pdata) {
@@ -131,12 +128,20 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 		if (pdata->b1on_flags & MC13783_BUTTON_RESET_EN)
 			reg |= MC13783_POWER_CONTROL_2_ON1BRSTEN;
 
-		err = mc13xxx_irq_request(mc13783, MC13783_IRQ_ONOFD1,
-					  button_irq, "b1on", priv);
-		if (err) {
+		irq = platform_get_irq_byname(pdev, "b1on");
+
+		if (irq < 0) {
 			dev_dbg(&pdev->dev, "Can't request irq\n");
 			goto free_mc13xxx_lock;
 		}
+
+		err = devm_request_any_context_irq(&pdev->dev, irq, button_irq,
+						   IRQF_ONESHOT, "b1on",
+						   priv);
+		if (err < 0)
+			goto free_mc13xxx_lock;
+
+		priv->irq[0] = irq;
 	}
 
 	if (pdata->b2on_flags & MC13783_BUTTON_ENABLE) {
@@ -150,12 +155,20 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 		if (pdata->b2on_flags & MC13783_BUTTON_RESET_EN)
 			reg |= MC13783_POWER_CONTROL_2_ON2BRSTEN;
 
-		err = mc13xxx_irq_request(mc13783, MC13783_IRQ_ONOFD2,
-					  button_irq, "b2on", priv);
-		if (err) {
+		irq = platform_get_irq_byname(pdev, "b2on");
+
+		if (irq < 0) {
 			dev_dbg(&pdev->dev, "Can't request irq\n");
-			goto free_irq_b1;
+			goto free_mc13xxx_lock;
 		}
+
+		err = devm_request_any_context_irq(&pdev->dev, irq, button_irq,
+						   IRQF_ONESHOT, "b2on",
+						   priv);
+		if (err < 0)
+			goto free_mc13xxx_lock;
+
+		priv->irq[1] = irq;
 	}
 
 	if (pdata->b3on_flags & MC13783_BUTTON_ENABLE) {
@@ -169,12 +182,20 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 		if (pdata->b3on_flags & MC13783_BUTTON_RESET_EN)
 			reg |= MC13783_POWER_CONTROL_2_ON3BRSTEN;
 
-		err = mc13xxx_irq_request(mc13783, MC13783_IRQ_ONOFD3,
-					  button_irq, "b3on", priv);
-		if (err) {
+		irq = platform_get_irq_byname(pdev, "b3on");
+
+		if (irq < 0) {
 			dev_dbg(&pdev->dev, "Can't request irq: %d\n", err);
-			goto free_irq_b2;
+			goto free_mc13xxx_lock;
 		}
+
+		err = devm_request_any_context_irq(&pdev->dev, irq, button_irq,
+						   IRQF_ONESHOT, "b3on",
+						   priv);
+		if (err < 0)
+			goto free_mc13xxx_lock;
+
+		priv->irq[2] = irq;
 	}
 
 	mc13xxx_reg_rmw(mc13783, MC13783_REG_POWER_CONTROL_2, 0x3FE, reg);
@@ -192,55 +213,21 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 	err = input_register_device(pwr);
 	if (err) {
 		dev_dbg(&pdev->dev, "Can't register power button: %d\n", err);
-		goto free_irq;
+		return err;
 	}
 
 	platform_set_drvdata(pdev, priv);
 
 	return 0;
 
-free_irq:
-	mc13xxx_lock(mc13783);
-
-	if (pdata->b3on_flags & MC13783_BUTTON_ENABLE)
-		mc13xxx_irq_free(mc13783, MC13783_IRQ_ONOFD3, priv);
-
-free_irq_b2:
-	if (pdata->b2on_flags & MC13783_BUTTON_ENABLE)
-		mc13xxx_irq_free(mc13783, MC13783_IRQ_ONOFD2, priv);
-
-free_irq_b1:
-	if (pdata->b1on_flags & MC13783_BUTTON_ENABLE)
-		mc13xxx_irq_free(mc13783, MC13783_IRQ_ONOFD1, priv);
-
 free_mc13xxx_lock:
 	mc13xxx_unlock(mc13783);
 
 	return err;
 }
 
-static void mc13783_pwrbutton_remove(struct platform_device *pdev)
-{
-	struct mc13783_pwrb *priv = platform_get_drvdata(pdev);
-	const struct mc13xxx_buttons_platform_data *pdata;
-
-	pdata = dev_get_platdata(&pdev->dev);
-
-	mc13xxx_lock(priv->mc13783);
-
-	if (pdata->b3on_flags & MC13783_BUTTON_ENABLE)
-		mc13xxx_irq_free(priv->mc13783, MC13783_IRQ_ONOFD3, priv);
-	if (pdata->b2on_flags & MC13783_BUTTON_ENABLE)
-		mc13xxx_irq_free(priv->mc13783, MC13783_IRQ_ONOFD2, priv);
-	if (pdata->b1on_flags & MC13783_BUTTON_ENABLE)
-		mc13xxx_irq_free(priv->mc13783, MC13783_IRQ_ONOFD1, priv);
-
-	mc13xxx_unlock(priv->mc13783);
-}
-
 static struct platform_driver mc13783_pwrbutton_driver = {
 	.probe		= mc13783_pwrbutton_probe,
-	.remove		= mc13783_pwrbutton_remove,
 	.driver		= {
 		.name	= "mc13783-pwrbutton",
 	},
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index 920797b806ce..1756c8d47d5e 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -13,6 +13,7 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/core.h>
+#include <linux/mfd/mc13783.h>
 
 #include "mc13xxx.h"
 
@@ -46,6 +47,12 @@
 
 #define MC13XXX_ADC2		45
 
+static const struct resource mc13783_button_resources[] = {
+	DEFINE_RES_IRQ_NAMED(MC13783_IRQ_ONOFD1, "b1on"),
+	DEFINE_RES_IRQ_NAMED(MC13783_IRQ_ONOFD2, "b2on"),
+	DEFINE_RES_IRQ_NAMED(MC13783_IRQ_ONOFD3, "b3on"),
+};
+
 void mc13xxx_lock(struct mc13xxx *mc13xxx)
 {
 	if (!mutex_trylock(&mc13xxx->lock)) {
@@ -201,18 +208,22 @@ static void mc34708_print_revision(struct mc13xxx *mc13xxx, u32 revision)
 /* These are only exported for mc13xxx-i2c and mc13xxx-spi */
 struct mc13xxx_variant mc13xxx_variant_mc13783 = {
 	.name = "mc13783",
+	.button_resources = mc13783_button_resources,
+	.button_resources_size = ARRAY_SIZE(mc13783_button_resources),
 	.print_revision = mc13xxx_print_revision,
 };
 EXPORT_SYMBOL_GPL(mc13xxx_variant_mc13783);
 
 struct mc13xxx_variant mc13xxx_variant_mc13892 = {
 	.name = "mc13892",
+	.button_resources_size = 0,
 	.print_revision = mc13xxx_print_revision,
 };
 EXPORT_SYMBOL_GPL(mc13xxx_variant_mc13892);
 
 struct mc13xxx_variant mc13xxx_variant_mc34708 = {
 	.name = "mc34708",
+	.button_resources_size = 0,
 	.print_revision = mc34708_print_revision,
 };
 EXPORT_SYMBOL_GPL(mc13xxx_variant_mc34708);
@@ -362,15 +373,18 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
 }
 EXPORT_SYMBOL_GPL(mc13xxx_adc_do_conversion);
 
-static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
-		const char *format, void *pdata, size_t pdata_size)
+static int mc13xxx_add_subdevice_pdata_res(struct mc13xxx *mc13xxx,
+		const char *format, void *pdata, size_t pdata_size,
+		const struct resource *resources, int num_resources)
 {
 	char buf[30];
 	const char *name = mc13xxx_get_chipname(mc13xxx);
 
 	struct mfd_cell cell = {
-		.platform_data = pdata,
-		.pdata_size = pdata_size,
+		.platform_data	= pdata,
+		.pdata_size	= pdata_size,
+		.resources	= resources,
+		.num_resources	= num_resources,
 	};
 
 	/* there is no asnprintf in the kernel :-( */
@@ -385,6 +399,12 @@ static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
 			       regmap_irq_get_domain(mc13xxx->irq_data));
 }
 
+static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
+		const char *format, void *pdata, size_t pdata_size)
+{
+	return mc13xxx_add_subdevice_pdata_res(mc13xxx, format, pdata, pdata_size, NULL, 0);
+}
+
 static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format)
 {
 	return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL, 0);
@@ -470,8 +490,10 @@ int mc13xxx_common_init(struct device *dev)
 			&pdata->regulators, sizeof(pdata->regulators));
 		mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led",
 				pdata->leds, sizeof(*pdata->leds));
-		mc13xxx_add_subdevice_pdata(mc13xxx, "%s-pwrbutton",
-				pdata->buttons, sizeof(*pdata->buttons));
+		mc13xxx_add_subdevice_pdata_res(mc13xxx, "%s-pwrbutton",
+				pdata->buttons, sizeof(*pdata->buttons),
+				mc13xxx->variant->button_resources,
+				mc13xxx->variant->button_resources_size);
 		if (mc13xxx->flags & MC13XXX_USE_CODEC)
 			mc13xxx_add_subdevice_pdata(mc13xxx, "%s-codec",
 				pdata->codec, sizeof(*pdata->codec));
@@ -481,7 +503,10 @@ int mc13xxx_common_init(struct device *dev)
 	} else {
 		mc13xxx_add_subdevice(mc13xxx, "%s-regulator");
 		mc13xxx_add_subdevice(mc13xxx, "%s-led");
-		mc13xxx_add_subdevice(mc13xxx, "%s-pwrbutton");
+		mc13xxx_add_subdevice_pdata_res(mc13xxx, "%s-pwrbutton",
+				NULL, 0,
+				mc13xxx->variant->button_resources,
+				mc13xxx->variant->button_resources_size);
 		if (mc13xxx->flags & MC13XXX_USE_CODEC)
 			mc13xxx_add_subdevice(mc13xxx, "%s-codec");
 		if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN)
diff --git a/drivers/mfd/mc13xxx.h b/drivers/mfd/mc13xxx.h
index bd5ba9a0e14f..b13ae652f4ec 100644
--- a/drivers/mfd/mc13xxx.h
+++ b/drivers/mfd/mc13xxx.h
@@ -18,6 +18,8 @@ struct mc13xxx;
 
 struct mc13xxx_variant {
 	const char *name;
+	const struct resource *button_resources;
+	int button_resources_size;
 	void (*print_revision)(struct mc13xxx *mc13xxx, u32 revision);
 };
 
-- 
2.39.5
^ permalink raw reply related	[flat|nested] 6+ messages in thread
* [PATCH v5 3/5] Input: mc13783-pwrbutton: convert pdata members to array
  2025-10-08  6:43 [PATCH v5 0/5] Fix, extend and support OF to mc13xxx pwrbutton Alexander Kurz
  2025-10-08  6:43 ` [PATCH v5 1/5] Input: mc13783-pwrbutton: use managed resources Alexander Kurz
  2025-10-08  6:43 ` [PATCH v5 2/5] Input: mc13783-pwrbutton: fix irq mixup and use resources Alexander Kurz
@ 2025-10-08  6:43 ` Alexander Kurz
  2025-10-08  6:44 ` [PATCH v5 4/5] Input: mc13783-pwrbutton: enable other mc13xxx PMIC Alexander Kurz
  2025-10-08  6:44 ` [PATCH v5 5/5] Input: mc13783-pwrbutton: add OF support and drop platform_data Alexander Kurz
  4 siblings, 0 replies; 6+ messages in thread
From: Alexander Kurz @ 2025-10-08  6:43 UTC (permalink / raw)
  To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Dzmitry Sankouski, Dr. David Alan Gilbert,
	Heiko Stuebner, Uwe Kleine-König, devicetree, linux-input
  Cc: linux-kernel, Alexander Kurz
As preparation for the extension of support for all three mc13xxx
variants, convert the members of mc13xxx_buttons_platform_data to
arrays to allow index access within the next commit.
Signed-off-by: Alexander Kurz <akurz@blala.de>
---
 drivers/input/misc/mc13783-pwrbutton.c | 42 +++++++++++++-------------
 include/linux/mfd/mc13xxx.h            |  8 ++---
 2 files changed, 23 insertions(+), 27 deletions(-)
diff --git a/drivers/input/misc/mc13783-pwrbutton.c b/drivers/input/misc/mc13783-pwrbutton.c
index 20f68aab6edf..2ee115d77b1c 100644
--- a/drivers/input/misc/mc13783-pwrbutton.c
+++ b/drivers/input/misc/mc13783-pwrbutton.c
@@ -108,24 +108,24 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 	if (!priv)
 		return -ENOMEM;
 
-	reg |= (pdata->b1on_flags & 0x3) << MC13783_POWER_CONTROL_2_ON1BDBNC;
-	reg |= (pdata->b2on_flags & 0x3) << MC13783_POWER_CONTROL_2_ON2BDBNC;
-	reg |= (pdata->b3on_flags & 0x3) << MC13783_POWER_CONTROL_2_ON3BDBNC;
+	reg |= (pdata->b_on_flags[0] & 0x3) << MC13783_POWER_CONTROL_2_ON1BDBNC;
+	reg |= (pdata->b_on_flags[1] & 0x3) << MC13783_POWER_CONTROL_2_ON2BDBNC;
+	reg |= (pdata->b_on_flags[2] & 0x3) << MC13783_POWER_CONTROL_2_ON3BDBNC;
 
 	priv->pwr = pwr;
 	priv->mc13783 = mc13783;
 
 	mc13xxx_lock(mc13783);
 
-	if (pdata->b1on_flags & MC13783_BUTTON_ENABLE) {
-		priv->keymap[0] = pdata->b1on_key;
-		if (pdata->b1on_key != KEY_RESERVED)
-			__set_bit(pdata->b1on_key, pwr->keybit);
+	if (pdata->b_on_flags[0] & MC13783_BUTTON_ENABLE) {
+		priv->keymap[0] = pdata->b_on_key[0];
+		if (pdata->b_on_key[0] != KEY_RESERVED)
+			__set_bit(pdata->b_on_key[0], pwr->keybit);
 
-		if (pdata->b1on_flags & MC13783_BUTTON_POL_INVERT)
+		if (pdata->b_on_flags[0] & MC13783_BUTTON_POL_INVERT)
 			priv->flags |= MC13783_PWRB_B1_POL_INVERT;
 
-		if (pdata->b1on_flags & MC13783_BUTTON_RESET_EN)
+		if (pdata->b_on_flags[0] & MC13783_BUTTON_RESET_EN)
 			reg |= MC13783_POWER_CONTROL_2_ON1BRSTEN;
 
 		irq = platform_get_irq_byname(pdev, "b1on");
@@ -144,15 +144,15 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 		priv->irq[0] = irq;
 	}
 
-	if (pdata->b2on_flags & MC13783_BUTTON_ENABLE) {
-		priv->keymap[1] = pdata->b2on_key;
-		if (pdata->b2on_key != KEY_RESERVED)
-			__set_bit(pdata->b2on_key, pwr->keybit);
+	if (pdata->b_on_flags[1] & MC13783_BUTTON_ENABLE) {
+		priv->keymap[1] = pdata->b_on_key[1];
+		if (pdata->b_on_key[1] != KEY_RESERVED)
+			__set_bit(pdata->b_on_key[1], pwr->keybit);
 
-		if (pdata->b2on_flags & MC13783_BUTTON_POL_INVERT)
+		if (pdata->b_on_flags[1] & MC13783_BUTTON_POL_INVERT)
 			priv->flags |= MC13783_PWRB_B2_POL_INVERT;
 
-		if (pdata->b2on_flags & MC13783_BUTTON_RESET_EN)
+		if (pdata->b_on_flags[1] & MC13783_BUTTON_RESET_EN)
 			reg |= MC13783_POWER_CONTROL_2_ON2BRSTEN;
 
 		irq = platform_get_irq_byname(pdev, "b2on");
@@ -171,15 +171,15 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 		priv->irq[1] = irq;
 	}
 
-	if (pdata->b3on_flags & MC13783_BUTTON_ENABLE) {
-		priv->keymap[2] = pdata->b3on_key;
-		if (pdata->b3on_key != KEY_RESERVED)
-			__set_bit(pdata->b3on_key, pwr->keybit);
+	if (pdata->b_on_flags[2] & MC13783_BUTTON_ENABLE) {
+		priv->keymap[2] = pdata->b_on_key[2];
+		if (pdata->b_on_key[2] != KEY_RESERVED)
+			__set_bit(pdata->b_on_key[2], pwr->keybit);
 
-		if (pdata->b3on_flags & MC13783_BUTTON_POL_INVERT)
+		if (pdata->b_on_flags[2] & MC13783_BUTTON_POL_INVERT)
 			priv->flags |= MC13783_PWRB_B3_POL_INVERT;
 
-		if (pdata->b3on_flags & MC13783_BUTTON_RESET_EN)
+		if (pdata->b_on_flags[2] & MC13783_BUTTON_RESET_EN)
 			reg |= MC13783_POWER_CONTROL_2_ON3BRSTEN;
 
 		irq = platform_get_irq_byname(pdev, "b3on");
diff --git a/include/linux/mfd/mc13xxx.h b/include/linux/mfd/mc13xxx.h
index dd46fe424a80..4437ab80fcf8 100644
--- a/include/linux/mfd/mc13xxx.h
+++ b/include/linux/mfd/mc13xxx.h
@@ -181,12 +181,8 @@ struct mc13xxx_leds_platform_data {
 #define MC13783_BUTTON_RESET_EN		(1 << 4)
 
 struct mc13xxx_buttons_platform_data {
-	int b1on_flags;
-	unsigned short b1on_key;
-	int b2on_flags;
-	unsigned short b2on_key;
-	int b3on_flags;
-	unsigned short b3on_key;
+	int b_on_flags[3];
+	unsigned int b_on_key[3];
 };
 
 #define MC13783_TS_ATO_FIRST	false
-- 
2.39.5
^ permalink raw reply related	[flat|nested] 6+ messages in thread
* [PATCH v5 4/5] Input: mc13783-pwrbutton: enable other mc13xxx PMIC
  2025-10-08  6:43 [PATCH v5 0/5] Fix, extend and support OF to mc13xxx pwrbutton Alexander Kurz
                   ` (2 preceding siblings ...)
  2025-10-08  6:43 ` [PATCH v5 3/5] Input: mc13783-pwrbutton: convert pdata members to array Alexander Kurz
@ 2025-10-08  6:44 ` Alexander Kurz
  2025-10-08  6:44 ` [PATCH v5 5/5] Input: mc13783-pwrbutton: add OF support and drop platform_data Alexander Kurz
  4 siblings, 0 replies; 6+ messages in thread
From: Alexander Kurz @ 2025-10-08  6:44 UTC (permalink / raw)
  To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Dzmitry Sankouski, Dr. David Alan Gilbert,
	Heiko Stuebner, Uwe Kleine-König, devicetree, linux-input
  Cc: linux-kernel, Alexander Kurz
All three mc13xxx types feature two common power buttons referred in
the datasheets as ONOFD[12] (mc13783) and PWRON[12] (mc13892/mc34708).
A third button is available on the mc13783 and mc13892 models, which
however uses distinct interrupt register bits.
Add support for mc13892/mc34708 to support all available power buttons
in the mc13xxx series.
Signed-off-by: Alexander Kurz <akurz@blala.de>
---
 drivers/input/misc/Kconfig             |   4 +-
 drivers/input/misc/mc13783-pwrbutton.c | 131 +++++++++++--------------
 drivers/mfd/mc13xxx-core.c             |  22 ++++-
 include/linux/mfd/mc13783.h            |   4 +-
 include/linux/mfd/mc13892.h            |   1 +
 include/linux/mfd/mc13xxx.h            |   2 +
 6 files changed, 84 insertions(+), 80 deletions(-)
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 0e6b49fb54bc..c36c575f11e5 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -286,8 +286,8 @@ config INPUT_MC13783_PWRBUTTON
 	tristate "MC13783 ON buttons"
 	depends on MFD_MC13XXX
 	help
-	  Support the ON buttons of MC13783 PMIC as an input device
-	  reporting power button status.
+	  Support the ON buttons of MC13783/MC13892/MC34708 PMIC as an input
+	  device reporting power button status.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called mc13783-pwrbutton.
diff --git a/drivers/input/misc/mc13783-pwrbutton.c b/drivers/input/misc/mc13783-pwrbutton.c
index 2ee115d77b1c..08618c59197f 100644
--- a/drivers/input/misc/mc13783-pwrbutton.c
+++ b/drivers/input/misc/mc13783-pwrbutton.c
@@ -30,9 +30,16 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 
+struct mc13xxx_button_devtype {
+	int button_id_max;
+	const char *irq_name[3];
+	int irq_sense_reg[3];
+};
+
 struct mc13783_pwrb {
 	struct input_dev *pwr;
 	struct mc13xxx *mc13783;
+	const struct mc13xxx_button_devtype *devtype;
 	int flags;
 	unsigned short keymap[3];
 	int irq[3];
@@ -43,9 +50,6 @@ struct mc13783_pwrb {
 #define MC13783_PWRB_B3_POL_INVERT	(1 << 2)
 
 #define MC13783_REG_INTERRUPT_SENSE_1		5
-#define MC13783_IRQSENSE1_ONOFD1S		(1 << 3)
-#define MC13783_IRQSENSE1_ONOFD2S		(1 << 4)
-#define MC13783_IRQSENSE1_ONOFD3S		(1 << 5)
 
 #define MC13783_REG_POWER_CONTROL_2		15
 #define MC13783_POWER_CONTROL_2_ON1BDBNC	4
@@ -63,17 +67,17 @@ static irqreturn_t button_irq(int irq, void *_priv)
 	mc13xxx_reg_read(priv->mc13783, MC13783_REG_INTERRUPT_SENSE_1, &val);
 
 	if (irq == priv->irq[0]) {
-		val = val & MC13783_IRQSENSE1_ONOFD1S ? 1 : 0;
+		val = val & (1 << priv->devtype->irq_sense_reg[0]) ? 1 : 0;
 		if (priv->flags & MC13783_PWRB_B1_POL_INVERT)
 			val ^= 1;
 		input_report_key(priv->pwr, priv->keymap[0], val);
 	} else if (irq == priv->irq[1]) {
-		val = val & MC13783_IRQSENSE1_ONOFD2S ? 1 : 0;
+		val = val & (1 << priv->devtype->irq_sense_reg[1]) ? 1 : 0;
 		if (priv->flags & MC13783_PWRB_B2_POL_INVERT)
 			val ^= 1;
 		input_report_key(priv->pwr, priv->keymap[1], val);
-	} else if (irq == priv->irq[2]) {
-		val = val & MC13783_IRQSENSE1_ONOFD3S ? 1 : 0;
+	} else if (irq == priv->irq[2] && priv->devtype->button_id_max >= 2) {
+		val = val & (1 << priv->devtype->irq_sense_reg[2]) ? 1 : 0;
 		if (priv->flags & MC13783_PWRB_B3_POL_INVERT)
 			val ^= 1;
 		input_report_key(priv->pwr, priv->keymap[2], val);
@@ -88,6 +92,8 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 {
 	const struct mc13xxx_buttons_platform_data *pdata;
 	struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent);
+	struct mc13xxx_button_devtype *devtype =
+		(struct mc13xxx_button_devtype *)pdev->id_entry->driver_data;
 	struct input_dev *pwr;
 	struct mc13783_pwrb *priv;
 	int err = 0;
@@ -108,54 +114,36 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 	if (!priv)
 		return -ENOMEM;
 
+	if (devtype->button_id_max < 2 && pdata->b_on_flags[2] & 0x3) {
+		dev_err(&pdev->dev, "button not supported\n");
+		return -ENODEV;
+	}
+
 	reg |= (pdata->b_on_flags[0] & 0x3) << MC13783_POWER_CONTROL_2_ON1BDBNC;
 	reg |= (pdata->b_on_flags[1] & 0x3) << MC13783_POWER_CONTROL_2_ON2BDBNC;
 	reg |= (pdata->b_on_flags[2] & 0x3) << MC13783_POWER_CONTROL_2_ON3BDBNC;
 
 	priv->pwr = pwr;
 	priv->mc13783 = mc13783;
+	priv->devtype = devtype;
 
 	mc13xxx_lock(mc13783);
 
-	if (pdata->b_on_flags[0] & MC13783_BUTTON_ENABLE) {
-		priv->keymap[0] = pdata->b_on_key[0];
-		if (pdata->b_on_key[0] != KEY_RESERVED)
-			__set_bit(pdata->b_on_key[0], pwr->keybit);
+	for (int i = 0; i < devtype->button_id_max; i++) {
+		if ((pdata->b_on_flags[i] & MC13783_BUTTON_ENABLE) == 0)
+			continue;
 
-		if (pdata->b_on_flags[0] & MC13783_BUTTON_POL_INVERT)
-			priv->flags |= MC13783_PWRB_B1_POL_INVERT;
+		priv->keymap[i] = pdata->b_on_key[i];
+		if (pdata->b_on_key[i] != KEY_RESERVED)
+			__set_bit(pdata->b_on_key[i], pwr->keybit);
 
-		if (pdata->b_on_flags[0] & MC13783_BUTTON_RESET_EN)
-			reg |= MC13783_POWER_CONTROL_2_ON1BRSTEN;
+		if (pdata->b_on_flags[i] & MC13783_BUTTON_POL_INVERT)
+			priv->flags |= (MC13783_PWRB_B1_POL_INVERT << i);
 
-		irq = platform_get_irq_byname(pdev, "b1on");
+		if (pdata->b_on_flags[i] & MC13783_BUTTON_RESET_EN)
+			reg |= (MC13783_POWER_CONTROL_2_ON1BRSTEN << i);
 
-		if (irq < 0) {
-			dev_dbg(&pdev->dev, "Can't request irq\n");
-			goto free_mc13xxx_lock;
-		}
-
-		err = devm_request_any_context_irq(&pdev->dev, irq, button_irq,
-						   IRQF_ONESHOT, "b1on",
-						   priv);
-		if (err < 0)
-			goto free_mc13xxx_lock;
-
-		priv->irq[0] = irq;
-	}
-
-	if (pdata->b_on_flags[1] & MC13783_BUTTON_ENABLE) {
-		priv->keymap[1] = pdata->b_on_key[1];
-		if (pdata->b_on_key[1] != KEY_RESERVED)
-			__set_bit(pdata->b_on_key[1], pwr->keybit);
-
-		if (pdata->b_on_flags[1] & MC13783_BUTTON_POL_INVERT)
-			priv->flags |= MC13783_PWRB_B2_POL_INVERT;
-
-		if (pdata->b_on_flags[1] & MC13783_BUTTON_RESET_EN)
-			reg |= MC13783_POWER_CONTROL_2_ON2BRSTEN;
-
-		irq = platform_get_irq_byname(pdev, "b2on");
+		irq = platform_get_irq_byname(pdev, devtype->irq_name[i]);
 
 		if (irq < 0) {
 			dev_dbg(&pdev->dev, "Can't request irq\n");
@@ -163,39 +151,12 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 		}
 
 		err = devm_request_any_context_irq(&pdev->dev, irq, button_irq,
-						   IRQF_ONESHOT, "b2on",
-						   priv);
+					   IRQF_ONESHOT, devtype->irq_name[i],
+					   priv);
 		if (err < 0)
 			goto free_mc13xxx_lock;
 
-		priv->irq[1] = irq;
-	}
-
-	if (pdata->b_on_flags[2] & MC13783_BUTTON_ENABLE) {
-		priv->keymap[2] = pdata->b_on_key[2];
-		if (pdata->b_on_key[2] != KEY_RESERVED)
-			__set_bit(pdata->b_on_key[2], pwr->keybit);
-
-		if (pdata->b_on_flags[2] & MC13783_BUTTON_POL_INVERT)
-			priv->flags |= MC13783_PWRB_B3_POL_INVERT;
-
-		if (pdata->b_on_flags[2] & MC13783_BUTTON_RESET_EN)
-			reg |= MC13783_POWER_CONTROL_2_ON3BRSTEN;
-
-		irq = platform_get_irq_byname(pdev, "b3on");
-
-		if (irq < 0) {
-			dev_dbg(&pdev->dev, "Can't request irq: %d\n", err);
-			goto free_mc13xxx_lock;
-		}
-
-		err = devm_request_any_context_irq(&pdev->dev, irq, button_irq,
-						   IRQF_ONESHOT, "b3on",
-						   priv);
-		if (err < 0)
-			goto free_mc13xxx_lock;
-
-		priv->irq[2] = irq;
+		priv->irq[i] = irq;
 	}
 
 	mc13xxx_reg_rmw(mc13783, MC13783_REG_POWER_CONTROL_2, 0x3FE, reg);
@@ -226,7 +187,33 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 	return err;
 }
 
+static const struct mc13xxx_button_devtype mc13783_button_devtype = {
+	.button_id_max	= 2,
+	.irq_name = { "b1on", "b2on", "b3on" },
+	.irq_sense_reg = { 3, 4, 5 },
+};
+
+static const struct mc13xxx_button_devtype mc13892_button_devtype = {
+	.button_id_max	= 2,
+	.irq_name = { "b1on", "b2on", "b3on" },
+	.irq_sense_reg = { 3, 4, 2 },
+};
+
+static const struct mc13xxx_button_devtype mc34708_button_devtype = {
+	.button_id_max	= 1,
+	.irq_name = { "b1on", "b2on" },
+	.irq_sense_reg = { 3, 4 },
+};
+
+static const struct platform_device_id mc13xxx_pwrbutton_idtable[] = {
+	{ "mc13783-pwrbutton", (kernel_ulong_t)&mc13783_button_devtype },
+	{ "mc13892-pwrbutton", (kernel_ulong_t)&mc13892_button_devtype },
+	{ "mc34708-pwrbutton", (kernel_ulong_t)&mc34708_button_devtype },
+	{ /* sentinel */ }
+};
+
 static struct platform_driver mc13783_pwrbutton_driver = {
+	.id_table	= mc13xxx_pwrbutton_idtable,
 	.probe		= mc13783_pwrbutton_probe,
 	.driver		= {
 		.name	= "mc13783-pwrbutton",
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index 1756c8d47d5e..c29974722704 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/mc13783.h>
+#include <linux/mfd/mc13892.h>
 
 #include "mc13xxx.h"
 
@@ -48,11 +49,22 @@
 #define MC13XXX_ADC2		45
 
 static const struct resource mc13783_button_resources[] = {
-	DEFINE_RES_IRQ_NAMED(MC13783_IRQ_ONOFD1, "b1on"),
-	DEFINE_RES_IRQ_NAMED(MC13783_IRQ_ONOFD2, "b2on"),
+	DEFINE_RES_IRQ_NAMED(MC13XXX_IRQ_PWRON1, "b1on"),
+	DEFINE_RES_IRQ_NAMED(MC13XXX_IRQ_PWRON2, "b2on"),
 	DEFINE_RES_IRQ_NAMED(MC13783_IRQ_ONOFD3, "b3on"),
 };
 
+static const struct resource mc13892_button_resources[] = {
+	DEFINE_RES_IRQ_NAMED(MC13XXX_IRQ_PWRON1, "b1on"),
+	DEFINE_RES_IRQ_NAMED(MC13XXX_IRQ_PWRON2, "b2on"),
+	DEFINE_RES_IRQ_NAMED(MC13892_IRQ_PWRON3, "b3on"),
+};
+
+static const struct resource mc34708_button_resources[] = {
+	DEFINE_RES_IRQ_NAMED(MC13XXX_IRQ_PWRON1, "b1on"),
+	DEFINE_RES_IRQ_NAMED(MC13XXX_IRQ_PWRON2, "b2on"),
+};
+
 void mc13xxx_lock(struct mc13xxx *mc13xxx)
 {
 	if (!mutex_trylock(&mc13xxx->lock)) {
@@ -216,14 +228,16 @@ EXPORT_SYMBOL_GPL(mc13xxx_variant_mc13783);
 
 struct mc13xxx_variant mc13xxx_variant_mc13892 = {
 	.name = "mc13892",
-	.button_resources_size = 0,
+	.button_resources = mc13892_button_resources,
+	.button_resources_size = ARRAY_SIZE(mc13892_button_resources),
 	.print_revision = mc13xxx_print_revision,
 };
 EXPORT_SYMBOL_GPL(mc13xxx_variant_mc13892);
 
 struct mc13xxx_variant mc13xxx_variant_mc34708 = {
 	.name = "mc34708",
-	.button_resources_size = 0,
+	.button_resources = mc34708_button_resources,
+	.button_resources_size = ARRAY_SIZE(mc34708_button_resources),
 	.print_revision = mc34708_print_revision,
 };
 EXPORT_SYMBOL_GPL(mc13xxx_variant_mc34708);
diff --git a/include/linux/mfd/mc13783.h b/include/linux/mfd/mc13783.h
index c25b1676741b..ab6db774e1fa 100644
--- a/include/linux/mfd/mc13783.h
+++ b/include/linux/mfd/mc13783.h
@@ -65,8 +65,8 @@
 #define MC13783_IRQ_UDM		23
 #define MC13783_IRQ_1HZ		MC13XXX_IRQ_1HZ
 #define MC13783_IRQ_TODA	MC13XXX_IRQ_TODA
-#define MC13783_IRQ_ONOFD1	27
-#define MC13783_IRQ_ONOFD2	28
+#define MC13783_IRQ_ONOFD1	MC13XXX_IRQ_PWRON1
+#define MC13783_IRQ_ONOFD2	MC13XXX_IRQ_PWRON2
 #define MC13783_IRQ_ONOFD3	29
 #define MC13783_IRQ_SYSRST	MC13XXX_IRQ_SYSRST
 #define MC13783_IRQ_RTCRST	MC13XXX_IRQ_RTCRST
diff --git a/include/linux/mfd/mc13892.h b/include/linux/mfd/mc13892.h
index 880cd949d12a..567d527825df 100644
--- a/include/linux/mfd/mc13892.h
+++ b/include/linux/mfd/mc13892.h
@@ -33,4 +33,5 @@
 #define MC13892_PWGT2SPI	22
 #define MC13892_VCOINCELL	23
 
+#define MC13892_IRQ_PWRON3	26
 #endif
diff --git a/include/linux/mfd/mc13xxx.h b/include/linux/mfd/mc13xxx.h
index 4437ab80fcf8..71c7d3614d4c 100644
--- a/include/linux/mfd/mc13xxx.h
+++ b/include/linux/mfd/mc13xxx.h
@@ -61,6 +61,8 @@ int mc13xxx_irq_unmask(struct mc13xxx *mc13xxx, int irq);
 #define MC13XXX_IRQ_LOBATH	14
 #define MC13XXX_IRQ_1HZ		24
 #define MC13XXX_IRQ_TODA	25
+#define MC13XXX_IRQ_PWRON1	27
+#define MC13XXX_IRQ_PWRON2	28
 #define MC13XXX_IRQ_SYSRST	30
 #define MC13XXX_IRQ_RTCRST	31
 #define MC13XXX_IRQ_PC		32
-- 
2.39.5
^ permalink raw reply related	[flat|nested] 6+ messages in thread
* [PATCH v5 5/5] Input: mc13783-pwrbutton: add OF support and drop platform_data
  2025-10-08  6:43 [PATCH v5 0/5] Fix, extend and support OF to mc13xxx pwrbutton Alexander Kurz
                   ` (3 preceding siblings ...)
  2025-10-08  6:44 ` [PATCH v5 4/5] Input: mc13783-pwrbutton: enable other mc13xxx PMIC Alexander Kurz
@ 2025-10-08  6:44 ` Alexander Kurz
  4 siblings, 0 replies; 6+ messages in thread
From: Alexander Kurz @ 2025-10-08  6:44 UTC (permalink / raw)
  To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Dzmitry Sankouski, Dr. David Alan Gilbert,
	Heiko Stuebner, Uwe Kleine-König, devicetree, linux-input
  Cc: linux-kernel, Alexander Kurz
Add OF support for the mc13783-pwrbutton so that it can be used with
modern DT based systems, dropping support for platform_data.
Signed-off-by: Alexander Kurz <akurz@blala.de>
---
 drivers/input/misc/mc13783-pwrbutton.c | 104 +++++++++++++++++++++----
 drivers/mfd/mc13xxx-core.c             |   4 -
 include/linux/mfd/mc13xxx.h            |  14 ----
 3 files changed, 88 insertions(+), 34 deletions(-)
diff --git a/drivers/input/misc/mc13783-pwrbutton.c b/drivers/input/misc/mc13783-pwrbutton.c
index 08618c59197f..0fa630adff19 100644
--- a/drivers/input/misc/mc13783-pwrbutton.c
+++ b/drivers/input/misc/mc13783-pwrbutton.c
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/mc13783.h>
+#include <linux/property.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 
@@ -41,10 +42,20 @@ struct mc13783_pwrb {
 	struct mc13xxx *mc13783;
 	const struct mc13xxx_button_devtype *devtype;
 	int flags;
+	int b_on_flags[3];
+	unsigned int b_on_key[3];
 	unsigned short keymap[3];
 	int irq[3];
 };
 
+#define MC13783_BUTTON_DBNC_0MS         0
+#define MC13783_BUTTON_DBNC_30MS        1
+#define MC13783_BUTTON_DBNC_150MS       2
+#define MC13783_BUTTON_DBNC_750MS       3
+#define MC13783_BUTTON_ENABLE           (1 << 2)
+#define MC13783_BUTTON_POL_INVERT       (1 << 3)
+#define MC13783_BUTTON_RESET_EN         (1 << 4)
+
 #define MC13783_PWRB_B1_POL_INVERT	(1 << 0)
 #define MC13783_PWRB_B2_POL_INVERT	(1 << 1)
 #define MC13783_PWRB_B3_POL_INVERT	(1 << 2)
@@ -88,9 +99,69 @@ static irqreturn_t button_irq(int irq, void *_priv)
 	return IRQ_HANDLED;
 }
 
+static int mc13xxx_pwrbutton_parse_properties(struct platform_device *pdev,
+					      struct mc13783_pwrb *priv)
+{
+	struct fwnode_handle *child;
+	struct device *dev = &pdev->dev;
+	struct mc13xxx_button_devtype *devtype =
+		(struct mc13xxx_button_devtype *)platform_get_device_id(pdev)->driver_data;
+
+	struct fwnode_handle *parent __free(fwnode_handle) =
+		device_get_named_child_node(dev->parent, "buttons");
+	if (!parent)
+		return -ENODATA;
+
+	fwnode_for_each_named_child_node(parent, child, "onkey") {
+		u32 idx;
+		u8 dbnc = MC13783_BUTTON_DBNC_30MS;
+		u16 dbnc_ms;
+
+		if (fwnode_property_read_u32(child, "reg", &idx))
+			continue;
+
+		if (idx > devtype->button_id_max) {
+			dev_warn(dev, "reg out of range\n");
+			continue;
+		}
+
+		fwnode_property_read_u16(child, "debounce-delay-ms", &dbnc_ms);
+		switch (dbnc_ms) {
+		case 0:
+			dbnc = MC13783_BUTTON_DBNC_0MS;
+			break;
+		case 30:
+			dbnc = MC13783_BUTTON_DBNC_30MS;
+			break;
+		case 150:
+			dbnc = MC13783_BUTTON_DBNC_150MS;
+			break;
+		case 750:
+			dbnc = MC13783_BUTTON_DBNC_750MS;
+			break;
+		default:
+			dev_warn(dev, "invalid debounce-delay-ms value\n");
+			continue;
+		}
+
+		if (fwnode_property_read_u32(child, "linux,code", &priv->b_on_key[idx]))
+			continue;
+
+		if (fwnode_property_read_bool(child, "active-low"))
+			priv->b_on_flags[idx] |= MC13783_BUTTON_POL_INVERT;
+
+		if (fwnode_property_read_bool(child, "fsl,enable-reset"))
+			priv->b_on_flags[idx] |= MC13783_BUTTON_RESET_EN;
+
+		priv->b_on_flags[idx] |= MC13783_BUTTON_ENABLE | dbnc;
+	}
+
+	return 0;
+}
+
 static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 {
-	const struct mc13xxx_buttons_platform_data *pdata;
+	struct device *dev = &pdev->dev;
 	struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent);
 	struct mc13xxx_button_devtype *devtype =
 		(struct mc13xxx_button_devtype *)pdev->id_entry->driver_data;
@@ -100,11 +171,8 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 	int reg = 0;
 	int irq = 0;
 
-	pdata = dev_get_platdata(&pdev->dev);
-	if (!pdata) {
-		dev_err(&pdev->dev, "missing platform data\n");
-		return -ENODEV;
-	}
+	if (!dev->parent->of_node)
+		return -ENODATA;
 
 	pwr = devm_input_allocate_device(&pdev->dev);
 	if (!pwr)
@@ -114,14 +182,18 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 	if (!priv)
 		return -ENOMEM;
 
-	if (devtype->button_id_max < 2 && pdata->b_on_flags[2] & 0x3) {
+	err = mc13xxx_pwrbutton_parse_properties(pdev, priv);
+	if (err)
+		return err;
+
+	if (devtype->button_id_max < 2 && priv->b_on_flags[2] & 0x3) {
 		dev_err(&pdev->dev, "button not supported\n");
 		return -ENODEV;
 	}
 
-	reg |= (pdata->b_on_flags[0] & 0x3) << MC13783_POWER_CONTROL_2_ON1BDBNC;
-	reg |= (pdata->b_on_flags[1] & 0x3) << MC13783_POWER_CONTROL_2_ON2BDBNC;
-	reg |= (pdata->b_on_flags[2] & 0x3) << MC13783_POWER_CONTROL_2_ON3BDBNC;
+	reg |= (priv->b_on_flags[0] & 0x3) << MC13783_POWER_CONTROL_2_ON1BDBNC;
+	reg |= (priv->b_on_flags[1] & 0x3) << MC13783_POWER_CONTROL_2_ON2BDBNC;
+	reg |= (priv->b_on_flags[2] & 0x3) << MC13783_POWER_CONTROL_2_ON3BDBNC;
 
 	priv->pwr = pwr;
 	priv->mc13783 = mc13783;
@@ -130,17 +202,17 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
 	mc13xxx_lock(mc13783);
 
 	for (int i = 0; i < devtype->button_id_max; i++) {
-		if ((pdata->b_on_flags[i] & MC13783_BUTTON_ENABLE) == 0)
+		if ((priv->b_on_flags[i] & MC13783_BUTTON_ENABLE) == 0)
 			continue;
 
-		priv->keymap[i] = pdata->b_on_key[i];
-		if (pdata->b_on_key[i] != KEY_RESERVED)
-			__set_bit(pdata->b_on_key[i], pwr->keybit);
+		priv->keymap[i] = priv->b_on_key[i];
+		if (priv->b_on_key[i] != KEY_RESERVED)
+			__set_bit(priv->b_on_key[i], pwr->keybit);
 
-		if (pdata->b_on_flags[i] & MC13783_BUTTON_POL_INVERT)
+		if (priv->b_on_flags[i] & MC13783_BUTTON_POL_INVERT)
 			priv->flags |= (MC13783_PWRB_B1_POL_INVERT << i);
 
-		if (pdata->b_on_flags[i] & MC13783_BUTTON_RESET_EN)
+		if (priv->b_on_flags[i] & MC13783_BUTTON_RESET_EN)
 			reg |= (MC13783_POWER_CONTROL_2_ON1BRSTEN << i);
 
 		irq = platform_get_irq_byname(pdev, devtype->irq_name[i]);
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index c29974722704..9512136e821b 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -504,10 +504,6 @@ int mc13xxx_common_init(struct device *dev)
 			&pdata->regulators, sizeof(pdata->regulators));
 		mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led",
 				pdata->leds, sizeof(*pdata->leds));
-		mc13xxx_add_subdevice_pdata_res(mc13xxx, "%s-pwrbutton",
-				pdata->buttons, sizeof(*pdata->buttons),
-				mc13xxx->variant->button_resources,
-				mc13xxx->variant->button_resources_size);
 		if (mc13xxx->flags & MC13XXX_USE_CODEC)
 			mc13xxx_add_subdevice_pdata(mc13xxx, "%s-codec",
 				pdata->codec, sizeof(*pdata->codec));
diff --git a/include/linux/mfd/mc13xxx.h b/include/linux/mfd/mc13xxx.h
index 71c7d3614d4c..ac3765df341d 100644
--- a/include/linux/mfd/mc13xxx.h
+++ b/include/linux/mfd/mc13xxx.h
@@ -174,19 +174,6 @@ struct mc13xxx_leds_platform_data {
 	u32 led_control[MAX_LED_CONTROL_REGS];
 };
 
-#define MC13783_BUTTON_DBNC_0MS		0
-#define MC13783_BUTTON_DBNC_30MS	1
-#define MC13783_BUTTON_DBNC_150MS	2
-#define MC13783_BUTTON_DBNC_750MS	3
-#define MC13783_BUTTON_ENABLE		(1 << 2)
-#define MC13783_BUTTON_POL_INVERT	(1 << 3)
-#define MC13783_BUTTON_RESET_EN		(1 << 4)
-
-struct mc13xxx_buttons_platform_data {
-	int b_on_flags[3];
-	unsigned int b_on_key[3];
-};
-
 #define MC13783_TS_ATO_FIRST	false
 #define MC13783_TS_ATO_EACH	true
 
@@ -219,7 +206,6 @@ struct mc13xxx_platform_data {
 
 	struct mc13xxx_regulator_platform_data regulators;
 	struct mc13xxx_leds_platform_data *leds;
-	struct mc13xxx_buttons_platform_data *buttons;
 	struct mc13xxx_ts_platform_data touch;
 	struct mc13xxx_codec_platform_data *codec;
 };
-- 
2.39.5
^ permalink raw reply related	[flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-10-08  6:45 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-08  6:43 [PATCH v5 0/5] Fix, extend and support OF to mc13xxx pwrbutton Alexander Kurz
2025-10-08  6:43 ` [PATCH v5 1/5] Input: mc13783-pwrbutton: use managed resources Alexander Kurz
2025-10-08  6:43 ` [PATCH v5 2/5] Input: mc13783-pwrbutton: fix irq mixup and use resources Alexander Kurz
2025-10-08  6:43 ` [PATCH v5 3/5] Input: mc13783-pwrbutton: convert pdata members to array Alexander Kurz
2025-10-08  6:44 ` [PATCH v5 4/5] Input: mc13783-pwrbutton: enable other mc13xxx PMIC Alexander Kurz
2025-10-08  6:44 ` [PATCH v5 5/5] Input: mc13783-pwrbutton: add OF support and drop platform_data Alexander Kurz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).