--- v3
+++ v2
@@ -4,10 +4,10 @@
Acked-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
---
- drivers/input/misc/Kconfig | 10 ++++
+ drivers/input/misc/Kconfig | 10 +++
drivers/input/misc/Makefile | 1 +
- drivers/input/misc/retu-pwrbutton.c | 102 +++++++++++++++++++++++++++++++++++
- 3 files changed, 113 insertions(+), 0 deletions(-)
+ drivers/input/misc/retu-pwrbutton.c | 118 +++++++++++++++++++++++++++++++++++
+ 3 files changed, 129 insertions(+), 0 deletions(-)
create mode 100644 drivers/input/misc/retu-pwrbutton.c
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
@@ -45,10 +45,10 @@
obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
diff --git a/drivers/input/misc/retu-pwrbutton.c b/drivers/input/misc/retu-pwrbutton.c
new file mode 100644
-index 0000000..043a12b
+index 0000000..51e94a7
--- /dev/null
+++ b/drivers/input/misc/retu-pwrbutton.c
-@@ -0,0 +1,102 @@
+@@ -0,0 +1,118 @@
+/*
+ * Retu power button driver.
+ *
@@ -80,15 +80,26 @@
+
+#define RETU_STATUS_PWRONX (1 << 5)
+
++struct retu_pwrbutton {
++ struct input_dev *idev;
++ struct retu_dev *rdev;
++ struct device *dev;
++ bool pressed;
++ int irq;
++};
++
+static irqreturn_t retu_pwrbutton_irq(int irq, void *_pwr)
+{
++ struct retu_pwrbutton *pwr = _pwr;
+ bool state;
-+ struct input_dev *idev = _pwr;
-+ struct retu_dev *rdev = input_get_drvdata(idev);
+
-+ state = !(retu_read(rdev, RETU_REG_STATUS) & RETU_STATUS_PWRONX);
-+ input_report_key(idev, KEY_POWER, state);
-+ input_sync(idev);
++ state = !(retu_read(pwr->rdev, RETU_REG_STATUS) & RETU_STATUS_PWRONX);
++
++ if (pwr->pressed != state) {
++ input_report_key(pwr->idev, KEY_POWER, state);
++ input_sync(pwr->idev);
++ pwr->pressed = state;
++ }
+
+ return IRQ_HANDLED;
+}
@@ -96,41 +107,47 @@
+static int __devinit retu_pwrbutton_probe(struct platform_device *pdev)
+{
+ struct retu_dev *rdev = dev_get_drvdata(pdev->dev.parent);
-+ struct input_dev *idev;
++ struct retu_pwrbutton *pwr;
+ int ret;
+
-+ idev = input_allocate_device();
-+ if (!idev)
++ pwr = devm_kzalloc(&pdev->dev, sizeof(*pwr), GFP_KERNEL);
++ if (!pwr)
+ return -ENOMEM;
+
-+ idev->evbit[0] = BIT_MASK(EV_KEY);
-+ idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
-+ idev->name = "retu-pwrbutton";
++ pwr->rdev = rdev;
++ pwr->dev = &pdev->dev;
++ pwr->irq = platform_get_irq(pdev, 0);
++ platform_set_drvdata(pdev, pwr);
+
-+ platform_set_drvdata(pdev, idev);
-+ input_set_drvdata(idev, rdev);
++ ret = devm_request_threaded_irq(&pdev->dev, pwr->irq, NULL,
++ retu_pwrbutton_irq, 0, "retu-pwrbutton",
++ pwr);
++ if (ret < 0)
++ return ret;
+
-+ ret = input_register_device(idev);
++ pwr->idev = input_allocate_device();
++ if (!pwr->idev)
++ return -ENOMEM;
++
++ pwr->idev->evbit[0] = BIT_MASK(EV_KEY);
++ pwr->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
++ pwr->idev->name = "retu-pwrbutton";
++
++ ret = input_register_device(pwr->idev);
+ if (ret < 0) {
-+ input_free_device(idev);
++ input_free_device(pwr->idev);
+ return ret;
+ }
+
-+ ret = devm_request_threaded_irq(&pdev->dev, platform_get_irq(pdev, 0),
-+ NULL, retu_pwrbutton_irq, 0,
-+ "retu-pwrbutton", idev);
-+ if (ret < 0)
-+ input_unregister_device(idev);
-+
-+ return ret;
++ return 0;
+}
+
+static int __devexit retu_pwrbutton_remove(struct platform_device *pdev)
+{
-+ struct input_dev *idev = platform_get_drvdata(pdev);
++ struct retu_pwrbutton *pwr = platform_get_drvdata(pdev);
+
-+ disable_irq(platform_get_irq(pdev, 0));
-+ input_unregister_device(idev);
++ input_unregister_device(pwr->idev);
++ input_free_device(pwr->idev);
+
+ return 0;
+}
@@ -140,7 +157,6 @@
+ .remove = __devexit_p(retu_pwrbutton_remove),
+ .driver = {
+ .name = "retu-pwrbutton",
-+ .owner = THIS_MODULE,
+ },
+};
+module_platform_driver(retu_pwrbutton_driver);