summaryrefslogtreecommitdiff
path: root/drivers/input/misc/sirfsoc-onkey.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2014-02-13 23:38:43 -0800
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-02-15 13:08:40 -0800
commit864d3c0fe41c5e9ea4a477509b670e7503bda84c (patch)
tree0dfac0b110bfed007c1733c2ed9448f592213433 /drivers/input/misc/sirfsoc-onkey.c
parent1560a838f1a6402bdb2006cf30221e83106b0d02 (diff)
Input: sirfsoc-onkey - implement open and close methods
We can control whetehr device generates interrupts or not so let's implement open and close methods of input device so that we do not do any processing until there are users. Tested-by: Xianglong Du <Xianglong.Du@csr.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/misc/sirfsoc-onkey.c')
-rw-r--r--drivers/input/misc/sirfsoc-onkey.c53
1 files changed, 43 insertions, 10 deletions
diff --git a/drivers/input/misc/sirfsoc-onkey.c b/drivers/input/misc/sirfsoc-onkey.c
index e8897c36d21b..0755614c8ee5 100644
--- a/drivers/input/misc/sirfsoc-onkey.c
+++ b/drivers/input/misc/sirfsoc-onkey.c
@@ -49,6 +49,35 @@ static irqreturn_t sirfsoc_pwrc_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static void sirfsoc_pwrc_toggle_interrupts(struct sirfsoc_pwrc_drvdata *pwrcdrv,
+ bool enable)
+{
+ u32 int_mask;
+
+ int_mask = sirfsoc_rtc_iobrg_readl(pwrcdrv->pwrc_base + PWRC_INT_MASK);
+ if (enable)
+ int_mask |= PWRC_ON_KEY_BIT;
+ else
+ int_mask &= ~PWRC_ON_KEY_BIT;
+ sirfsoc_rtc_iobrg_writel(int_mask, pwrcdrv->pwrc_base + PWRC_INT_MASK);
+}
+
+static int sirfsoc_pwrc_open(struct input_dev *input)
+{
+ struct sirfsoc_pwrc_drvdata *pwrcdrv = input_get_drvdata(input);
+
+ sirfsoc_pwrc_toggle_interrupts(pwrcdrv, true);
+
+ return 0;
+}
+
+static void sirfsoc_pwrc_close(struct input_dev *input)
+{
+ struct sirfsoc_pwrc_drvdata *pwrcdrv = input_get_drvdata(input);
+
+ sirfsoc_pwrc_toggle_interrupts(pwrcdrv, false);
+}
+
static const struct of_device_id sirfsoc_pwrc_of_match[] = {
{ .compatible = "sirf,prima2-pwrc" },
{},
@@ -70,7 +99,7 @@ static int sirfsoc_pwrc_probe(struct platform_device *pdev)
}
/*
- * we can't use of_iomap because pwrc is not mapped in memory,
+ * We can't use of_iomap because pwrc is not mapped in memory,
* the so-called base address is only offset in rtciobrg
*/
error = of_property_read_u32(np, "reg", &pwrcdrv->pwrc_base);
@@ -88,6 +117,14 @@ static int sirfsoc_pwrc_probe(struct platform_device *pdev)
pwrcdrv->input->phys = "pwrc/input0";
pwrcdrv->input->evbit[0] = BIT_MASK(EV_PWR);
+ pwrcdrv->input->open = sirfsoc_pwrc_open;
+ pwrcdrv->input->close = sirfsoc_pwrc_close;
+
+ input_set_drvdata(pwrcdrv->input, pwrcdrv);
+
+ /* Make sure the device is quiesced */
+ sirfsoc_pwrc_toggle_interrupts(pwrcdrv, false);
+
irq = platform_get_irq(pdev, 0);
error = devm_request_irq(&pdev->dev, irq,
sirfsoc_pwrc_isr, IRQF_SHARED,
@@ -98,11 +135,6 @@ static int sirfsoc_pwrc_probe(struct platform_device *pdev)
return error;
}
- sirfsoc_rtc_iobrg_writel(
- sirfsoc_rtc_iobrg_readl(pwrcdrv->pwrc_base + PWRC_INT_MASK) |
- PWRC_ON_KEY_BIT,
- pwrcdrv->pwrc_base + PWRC_INT_MASK);
-
error = input_register_device(pwrcdrv->input);
if (error) {
dev_err(&pdev->dev,
@@ -129,15 +161,16 @@ static int pwrc_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct sirfsoc_pwrc_drvdata *pwrcdrv = platform_get_drvdata(pdev);
+ struct input_dev *input = pwrcdrv->input;
/*
* Do not mask pwrc interrupt as we want pwrc work as a wakeup source
* if users touch X_ONKEY_B, see arch/arm/mach-prima2/pm.c
*/
- sirfsoc_rtc_iobrg_writel(
- sirfsoc_rtc_iobrg_readl(
- pwrcdrv->pwrc_base + PWRC_INT_MASK) | PWRC_ON_KEY_BIT,
- pwrcdrv->pwrc_base + PWRC_INT_MASK);
+ mutex_lock(&input->mutex);
+ if (input->users)
+ sirfsoc_pwrc_toggle_interrupts(pwrcdrv, true);
+ mutex_unlock(&input->mutex);
return 0;
}