Add support for the onkey of the pf1550 PMIC.
Signed-off-by: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
---
drivers/input/keyboard/Kconfig | 8 ++
drivers/input/keyboard/Makefile | 1 +
drivers/input/keyboard/pf1550_onkey.c | 200 ++++++++++++++++++++++++++
3 files changed, 209 insertions(+)
create mode 100644 drivers/input/keyboard/pf1550_onkey.c
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 721ab69e84ac..b01decc03ab9 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -444,6 +444,14 @@ config KEYBOARD_SNVS_PWRKEY
To compile this driver as a module, choose M here; the
module will be called snvs_pwrkey.
+config KEYBOARD_PF1550_ONKEY
+ tristate "PF1550 OnKey Driver"
+ depends on MFD_PF1550
+ depends on OF
+ help
+ This is onkey driver for PF1550 pmic, onkey can trigger release
+ and 1s(push hold), 2s, 3s, 4s, 8s interrupt for long press detect
+
config KEYBOARD_IMX
tristate "IMX keypad support"
depends on ARCH_MXC || COMPILE_TEST
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 1e0721c30709..8a6feae3ddb1 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o
obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o
obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o
obj-$(CONFIG_KEYBOARD_SNVS_PWRKEY) += snvs_pwrkey.o
+obj-$(CONFIG_KEYBOARD_PF1550_ONKEY) += pf1550_onkey.o
obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o
obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o
obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
diff --git a/drivers/input/keyboard/pf1550_onkey.c b/drivers/input/keyboard/pf1550_onkey.c
new file mode 100644
index 000000000000..b0601acf893d
--- /dev/null
+++ b/drivers/input/keyboard/pf1550_onkey.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for the PF1550 ON_KEY
+ * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mfd/pf1550.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+struct onkey_drv_data {
+ struct device *dev;
+ struct pf1550_dev *pf1550;
+ int irq;
+ int keycode;
+ int wakeup;
+ struct input_dev *input;
+};
+
+static struct pf1550_irq_info pf1550_onkey_irqs[] = {
+ { PF1550_ONKEY_IRQ_PUSHI, "release" },
+ { PF1550_ONKEY_IRQ_1SI, "1S" },
+ { PF1550_ONKEY_IRQ_2SI, "2S" },
+ { PF1550_ONKEY_IRQ_3SI, "3S" },
+ { PF1550_ONKEY_IRQ_4SI, "4S" },
+ { PF1550_ONKEY_IRQ_8SI, "8S" },
+};
+
+static irqreturn_t pf1550_onkey_irq_handler(int irq, void *data)
+{
+ struct onkey_drv_data *onkey = data;
+ int i, state, irq_type = -1;
+
+ onkey->irq = irq;
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_onkey_irqs); i++)
+ if (onkey->irq == pf1550_onkey_irqs[i].virq)
+ irq_type = pf1550_onkey_irqs[i].irq;
+ switch (irq_type) {
+ case PF1550_ONKEY_IRQ_PUSHI:
+ state = 0;
+ break;
+ case PF1550_ONKEY_IRQ_1SI:
+ case PF1550_ONKEY_IRQ_2SI:
+ case PF1550_ONKEY_IRQ_3SI:
+ case PF1550_ONKEY_IRQ_4SI:
+ case PF1550_ONKEY_IRQ_8SI:
+ state = 1;
+ break;
+ default:
+ dev_err(onkey->dev, "onkey interrupt: irq %d occurred\n",
+ irq_type);
+ return IRQ_HANDLED;
+ }
+
+ input_event(onkey->input, EV_KEY, onkey->keycode, state);
+ input_sync(onkey->input);
+
+ return IRQ_HANDLED;
+}
+
+static int pf1550_onkey_probe(struct platform_device *pdev)
+{
+ struct onkey_drv_data *onkey;
+ struct input_dev *input = NULL;
+ struct device_node *np = pdev->dev.of_node;
+ struct pf1550_dev *pf1550 = dev_get_drvdata(pdev->dev.parent);
+ int i, error;
+
+ if (!np)
+ return -ENODEV;
+
+ onkey = devm_kzalloc(&pdev->dev, sizeof(*onkey), GFP_KERNEL);
+ if (!onkey)
+ return -ENOMEM;
+
+ if (of_property_read_u32(np, "linux,keycodes", &onkey->keycode)) {
+ onkey->keycode = KEY_POWER;
+ dev_warn(&pdev->dev, "KEY_POWER without setting in dts\n");
+ }
+
+ onkey->wakeup = of_property_read_bool(np, "wakeup-source");
+
+ input = devm_input_allocate_device(&pdev->dev);
+ if (!input) {
+ dev_err(&pdev->dev, "failed to allocate the input device\n");
+ return -ENOMEM;
+ }
+
+ input->name = pdev->name;
+ input->phys = "pf1550-onkey/input0";
+ input->id.bustype = BUS_HOST;
+
+ input_set_capability(input, EV_KEY, onkey->keycode);
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_onkey_irqs); i++) {
+ struct pf1550_irq_info *onkey_irq =
+ &pf1550_onkey_irqs[i];
+ unsigned int virq = 0;
+
+ virq = regmap_irq_get_virq(pf1550->irq_data_onkey,
+ onkey_irq->irq);
+ if (!virq)
+ return -EINVAL;
+
+ onkey_irq->virq = virq;
+
+ error = devm_request_threaded_irq(&pdev->dev, virq, NULL,
+ pf1550_onkey_irq_handler,
+ IRQF_NO_SUSPEND,
+ onkey_irq->name, onkey);
+ if (error) {
+ dev_err(&pdev->dev,
+ "failed: irq request (IRQ: %d, error :%d)\n",
+ onkey_irq->irq, error);
+ return error;
+ }
+ }
+
+ error = input_register_device(input);
+ if (error < 0) {
+ dev_err(&pdev->dev, "failed to register input device\n");
+ input_free_device(input);
+ return error;
+ }
+
+ onkey->input = input;
+ onkey->pf1550 = pf1550;
+ platform_set_drvdata(pdev, onkey);
+
+ device_init_wakeup(&pdev->dev, onkey->wakeup);
+
+ return 0;
+}
+
+static int pf1550_onkey_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct onkey_drv_data *onkey = platform_get_drvdata(pdev);
+
+ if (!device_may_wakeup(&pdev->dev))
+ regmap_write(onkey->pf1550->regmap,
+ PF1550_PMIC_REG_ONKEY_INT_MASK0,
+ ONKEY_IRQ_PUSHI | ONKEY_IRQ_1SI | ONKEY_IRQ_2SI |
+ ONKEY_IRQ_3SI | ONKEY_IRQ_4SI | ONKEY_IRQ_8SI);
+ else
+ enable_irq_wake(onkey->pf1550->irq);
+
+ return 0;
+}
+
+static int pf1550_onkey_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct onkey_drv_data *onkey = platform_get_drvdata(pdev);
+
+ if (!device_may_wakeup(&pdev->dev))
+ regmap_write(onkey->pf1550->regmap,
+ PF1550_PMIC_REG_ONKEY_INT_MASK0,
+ ~(ONKEY_IRQ_PUSHI | ONKEY_IRQ_1SI | ONKEY_IRQ_2SI |
+ ONKEY_IRQ_3SI | ONKEY_IRQ_4SI | ONKEY_IRQ_8SI));
+ else
+ disable_irq_wake(onkey->pf1550->irq);
+
+ return 0;
+}
+
+static const struct of_device_id pf1550_onkey_ids[] = {
+ { .compatible = "fsl,pf1550-onkey" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, pf1550_onkey_ids);
+
+static SIMPLE_DEV_PM_OPS(pf1550_onkey_pm_ops, pf1550_onkey_suspend,
+ pf1550_onkey_resume);
+
+static struct platform_driver pf1550_onkey_driver = {
+ .driver = {
+ .name = "pf1550-onkey",
+ .pm = &pf1550_onkey_pm_ops,
+ .of_match_table = pf1550_onkey_ids,
+ },
+ .probe = pf1550_onkey_probe,
+};
+module_platform_driver(pf1550_onkey_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor");
+MODULE_DESCRIPTION("PF1550 onkey Driver");
+MODULE_LICENSE("GPL v2");
--
2.49.0
Hi Samuel,
kernel test robot noticed the following build warnings:
[auto build test WARNING on b1d8766052eb0534b27edda8af1865d53621bd6a]
url: https://github.com/intel-lab-lkp/linux/commits/Samuel-Kayode/dt-bindings-power-supply-add-pf1550/20250517-030259
base: b1d8766052eb0534b27edda8af1865d53621bd6a
patch link: https://lore.kernel.org/r/7d80afedf1ad9e98c9739163751bcb2785009e74.1747409892.git.samuel.kayode%40savoirfairelinux.com
patch subject: [PATCH v2 7/9] input: pf1550: add onkey support
config: loongarch-allyesconfig (https://download.01.org/0day-ci/archive/20250518/202505182355.Of8g2bwa-lkp@intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250518/202505182355.Of8g2bwa-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505182355.Of8g2bwa-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/input/keyboard/pf1550_onkey.c: In function 'pf1550_onkey_resume':
>> drivers/input/keyboard/pf1550_onkey.c:171:30: warning: conversion from 'long unsigned int' to 'unsigned int' changes value from '18446744073709551552' to '4294967232' [-Woverflow]
171 | ~(ONKEY_IRQ_PUSHI | ONKEY_IRQ_1SI | ONKEY_IRQ_2SI |
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
172 | ONKEY_IRQ_3SI | ONKEY_IRQ_4SI | ONKEY_IRQ_8SI));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vim +171 drivers/input/keyboard/pf1550_onkey.c
162
163 static int pf1550_onkey_resume(struct device *dev)
164 {
165 struct platform_device *pdev = to_platform_device(dev);
166 struct onkey_drv_data *onkey = platform_get_drvdata(pdev);
167
168 if (!device_may_wakeup(&pdev->dev))
169 regmap_write(onkey->pf1550->regmap,
170 PF1550_PMIC_REG_ONKEY_INT_MASK0,
> 171 ~(ONKEY_IRQ_PUSHI | ONKEY_IRQ_1SI | ONKEY_IRQ_2SI |
172 ONKEY_IRQ_3SI | ONKEY_IRQ_4SI | ONKEY_IRQ_8SI));
173 else
174 disable_irq_wake(onkey->pf1550->irq);
175
176 return 0;
177 }
178
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Samuel,
On Fri, May 16, 2025 at 02:57:28PM -0400, Samuel Kayode wrote:
> Add support for the onkey of the pf1550 PMIC.
>
> Signed-off-by: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
> ---
> drivers/input/keyboard/Kconfig | 8 ++
> drivers/input/keyboard/Makefile | 1 +
> drivers/input/keyboard/pf1550_onkey.c | 200 ++++++++++++++++++++++++++
> 3 files changed, 209 insertions(+)
> create mode 100644 drivers/input/keyboard/pf1550_onkey.c
>
> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> index 721ab69e84ac..b01decc03ab9 100644
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -444,6 +444,14 @@ config KEYBOARD_SNVS_PWRKEY
> To compile this driver as a module, choose M here; the
> module will be called snvs_pwrkey.
With the exception of snvs-pwrkey, all other onkey/pwrkey drivers live
in drivers/input/misc, please move them there. drivers/input/keyboard is
really for real keyboard devices.
>
> +config KEYBOARD_PF1550_ONKEY
> + tristate "PF1550 OnKey Driver"
> + depends on MFD_PF1550
> + depends on OF
I do not think your driver has any direct dependencies on OF, especially
if you switch to using generic device properties (device_property_read_*).
> + help
> + This is onkey driver for PF1550 pmic, onkey can trigger release
> + and 1s(push hold), 2s, 3s, 4s, 8s interrupt for long press detect
> +
> config KEYBOARD_IMX
> tristate "IMX keypad support"
> depends on ARCH_MXC || COMPILE_TEST
> diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
> index 1e0721c30709..8a6feae3ddb1 100644
> --- a/drivers/input/keyboard/Makefile
> +++ b/drivers/input/keyboard/Makefile
> @@ -59,6 +59,7 @@ obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o
> obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o
> obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o
> obj-$(CONFIG_KEYBOARD_SNVS_PWRKEY) += snvs_pwrkey.o
> +obj-$(CONFIG_KEYBOARD_PF1550_ONKEY) += pf1550_onkey.o
> obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o
> obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o
> obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
> diff --git a/drivers/input/keyboard/pf1550_onkey.c b/drivers/input/keyboard/pf1550_onkey.c
> new file mode 100644
> index 000000000000..b0601acf893d
> --- /dev/null
> +++ b/drivers/input/keyboard/pf1550_onkey.c
> @@ -0,0 +1,200 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Driver for the PF1550 ON_KEY
> + * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/input.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
I don't think you actually need io.h
> +#include <linux/jiffies.h>
and neither jiffies.h. Please audit your includes.
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mfd/pf1550.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +struct onkey_drv_data {
> + struct device *dev;
> + struct pf1550_dev *pf1550;
> + int irq;
> + int keycode;
> + int wakeup;
> + struct input_dev *input;
> +};
> +
> +static struct pf1550_irq_info pf1550_onkey_irqs[] = {
> + { PF1550_ONKEY_IRQ_PUSHI, "release" },
> + { PF1550_ONKEY_IRQ_1SI, "1S" },
> + { PF1550_ONKEY_IRQ_2SI, "2S" },
> + { PF1550_ONKEY_IRQ_3SI, "3S" },
> + { PF1550_ONKEY_IRQ_4SI, "4S" },
> + { PF1550_ONKEY_IRQ_8SI, "8S" },
> +};
> +
> +static irqreturn_t pf1550_onkey_irq_handler(int irq, void *data)
> +{
> + struct onkey_drv_data *onkey = data;
> + int i, state, irq_type = -1;
> +
> + onkey->irq = irq;
> +
> + for (i = 0; i < ARRAY_SIZE(pf1550_onkey_irqs); i++)
> + if (onkey->irq == pf1550_onkey_irqs[i].virq)
> + irq_type = pf1550_onkey_irqs[i].irq;
> + switch (irq_type) {
> + case PF1550_ONKEY_IRQ_PUSHI:
> + state = 0;
> + break;
> + case PF1550_ONKEY_IRQ_1SI:
> + case PF1550_ONKEY_IRQ_2SI:
> + case PF1550_ONKEY_IRQ_3SI:
> + case PF1550_ONKEY_IRQ_4SI:
> + case PF1550_ONKEY_IRQ_8SI:
> + state = 1;
> + break;
> + default:
> + dev_err(onkey->dev, "onkey interrupt: irq %d occurred\n",
> + irq_type);
> + return IRQ_HANDLED;
> + }
> +
> + input_event(onkey->input, EV_KEY, onkey->keycode, state);
> + input_sync(onkey->input);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int pf1550_onkey_probe(struct platform_device *pdev)
> +{
> + struct onkey_drv_data *onkey;
> + struct input_dev *input = NULL;
This initialization is not needed.
> + struct device_node *np = pdev->dev.of_node;
Please switch to generic device properties and stop referencing of_node.
> + struct pf1550_dev *pf1550 = dev_get_drvdata(pdev->dev.parent);
> + int i, error;
> +
> + if (!np)
> + return -ENODEV;
> +
> + onkey = devm_kzalloc(&pdev->dev, sizeof(*onkey), GFP_KERNEL);
> + if (!onkey)
> + return -ENOMEM;
> +
> + if (of_property_read_u32(np, "linux,keycodes", &onkey->keycode)) {
> + onkey->keycode = KEY_POWER;
> + dev_warn(&pdev->dev, "KEY_POWER without setting in dts\n");
Maybe make this property mandatory?
> + }
> +
> + onkey->wakeup = of_property_read_bool(np, "wakeup-source");
> +
> + input = devm_input_allocate_device(&pdev->dev);
> + if (!input) {
> + dev_err(&pdev->dev, "failed to allocate the input device\n");
> + return -ENOMEM;
> + }
> +
> + input->name = pdev->name;
> + input->phys = "pf1550-onkey/input0";
> + input->id.bustype = BUS_HOST;
> +
> + input_set_capability(input, EV_KEY, onkey->keycode);
> +
> + for (i = 0; i < ARRAY_SIZE(pf1550_onkey_irqs); i++) {
> + struct pf1550_irq_info *onkey_irq =
> + &pf1550_onkey_irqs[i];
> + unsigned int virq = 0;
> +
> + virq = regmap_irq_get_virq(pf1550->irq_data_onkey,
> + onkey_irq->irq);
> + if (!virq)
> + return -EINVAL;
> +
> + onkey_irq->virq = virq;
I think this kind of mapping needs to be done in the core part of your
driver.
> +
> + error = devm_request_threaded_irq(&pdev->dev, virq, NULL,
> + pf1550_onkey_irq_handler,
> + IRQF_NO_SUSPEND,
> + onkey_irq->name, onkey);
> + if (error) {
> + dev_err(&pdev->dev,
> + "failed: irq request (IRQ: %d, error :%d)\n",
> + onkey_irq->irq, error);
> + return error;
> + }
> + }
> +
> + error = input_register_device(input);
> + if (error < 0) {
Input API return 0 or negative, so simply "if (error) { ... }"
> + dev_err(&pdev->dev, "failed to register input device\n");
> + input_free_device(input);
You are using devm, so no need to free it manually.
> + return error;
> + }
> +
> + onkey->input = input;
You are too late. Interrupts are already active and you may dereference
onkey->input from your ISR.
> + onkey->pf1550 = pf1550;
> + platform_set_drvdata(pdev, onkey);
> +
> + device_init_wakeup(&pdev->dev, onkey->wakeup);
> +
> + return 0;
> +}
> +
> +static int pf1550_onkey_suspend(struct device *dev)
> +{
> + struct platform_device *pdev = to_platform_device(dev);
> + struct onkey_drv_data *onkey = platform_get_drvdata(pdev);
> +
> + if (!device_may_wakeup(&pdev->dev))
> + regmap_write(onkey->pf1550->regmap,
> + PF1550_PMIC_REG_ONKEY_INT_MASK0,
> + ONKEY_IRQ_PUSHI | ONKEY_IRQ_1SI | ONKEY_IRQ_2SI |
> + ONKEY_IRQ_3SI | ONKEY_IRQ_4SI | ONKEY_IRQ_8SI);
> + else
> + enable_irq_wake(onkey->pf1550->irq);
This is suspicious that you need to twiddle the state of the main
interrupt line. I'd expect you manipulate your own interrupts and this
all cascades up.
> +
> + return 0;
> +}
> +
> +static int pf1550_onkey_resume(struct device *dev)
> +{
> + struct platform_device *pdev = to_platform_device(dev);
> + struct onkey_drv_data *onkey = platform_get_drvdata(pdev);
> +
> + if (!device_may_wakeup(&pdev->dev))
> + regmap_write(onkey->pf1550->regmap,
> + PF1550_PMIC_REG_ONKEY_INT_MASK0,
> + ~(ONKEY_IRQ_PUSHI | ONKEY_IRQ_1SI | ONKEY_IRQ_2SI |
> + ONKEY_IRQ_3SI | ONKEY_IRQ_4SI | ONKEY_IRQ_8SI));
> + else
> + disable_irq_wake(onkey->pf1550->irq);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id pf1550_onkey_ids[] = {
> + { .compatible = "fsl,pf1550-onkey" },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, pf1550_onkey_ids);
> +
> +static SIMPLE_DEV_PM_OPS(pf1550_onkey_pm_ops, pf1550_onkey_suspend,
> + pf1550_onkey_resume);
> +
> +static struct platform_driver pf1550_onkey_driver = {
> + .driver = {
> + .name = "pf1550-onkey",
> + .pm = &pf1550_onkey_pm_ops,
> + .of_match_table = pf1550_onkey_ids,
> + },
> + .probe = pf1550_onkey_probe,
> +};
> +module_platform_driver(pf1550_onkey_driver);
> +
> +MODULE_AUTHOR("Freescale Semiconductor");
> +MODULE_DESCRIPTION("PF1550 onkey Driver");
> +MODULE_LICENSE("GPL v2");
Thanks.
--
Dmitry
On Fri, May 16, 2025 at 03:55:02PM -0700, Dmitry Torokhov wrote:
> > + input->name = pdev->name;
> > + input->phys = "pf1550-onkey/input0";
> > + input->id.bustype = BUS_HOST;
> > +
> > + input_set_capability(input, EV_KEY, onkey->keycode);
> > +
> > + for (i = 0; i < ARRAY_SIZE(pf1550_onkey_irqs); i++) {
> > + struct pf1550_irq_info *onkey_irq =
> > + &pf1550_onkey_irqs[i];
> > + unsigned int virq = 0;
> > +
> > + virq = regmap_irq_get_virq(pf1550->irq_data_onkey,
> > + onkey_irq->irq);
> > + if (!virq)
> > + return -EINVAL;
> > +
> > + onkey_irq->virq = virq;
>
> I think this kind of mapping needs to be done in the core part of your
> driver.
>
Without doing the mapping in the MFD children, a list of all virqs for the PMIC
would have to be maintained in addition to the (regmap_irq) irqs. Perhaps,
there is a better way to implement this?
> > +
> > + error = devm_request_threaded_irq(&pdev->dev, virq, NULL,
> > + pf1550_onkey_irq_handler,
> > + IRQF_NO_SUSPEND,
> > + onkey_irq->name, onkey);
Thanks,
Sam
© 2016 - 2025 Red Hat, Inc.