aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2014-02-14 02:38:43 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-02-15 16:08:40 -0500
commit864d3c0fe41c5e9ea4a477509b670e7503bda84c (patch)
tree0dfac0b110bfed007c1733c2ed9448f592213433 /drivers/input/misc
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')
-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)
49 return IRQ_HANDLED; 49 return IRQ_HANDLED;
50} 50}
51 51
52static void sirfsoc_pwrc_toggle_interrupts(struct sirfsoc_pwrc_drvdata *pwrcdrv,
53 bool enable)
54{
55 u32 int_mask;
56
57 int_mask = sirfsoc_rtc_iobrg_readl(pwrcdrv->pwrc_base + PWRC_INT_MASK);
58 if (enable)
59 int_mask |= PWRC_ON_KEY_BIT;
60 else
61 int_mask &= ~PWRC_ON_KEY_BIT;
62 sirfsoc_rtc_iobrg_writel(int_mask, pwrcdrv->pwrc_base + PWRC_INT_MASK);
63}
64
65static int sirfsoc_pwrc_open(struct input_dev *input)
66{
67 struct sirfsoc_pwrc_drvdata *pwrcdrv = input_get_drvdata(input);
68
69 sirfsoc_pwrc_toggle_interrupts(pwrcdrv, true);
70
71 return 0;
72}
73
74static void sirfsoc_pwrc_close(struct input_dev *input)
75{
76 struct sirfsoc_pwrc_drvdata *pwrcdrv = input_get_drvdata(input);
77
78 sirfsoc_pwrc_toggle_interrupts(pwrcdrv, false);
79}
80
52static const struct of_device_id sirfsoc_pwrc_of_match[] = { 81static const struct of_device_id sirfsoc_pwrc_of_match[] = {
53 { .compatible = "sirf,prima2-pwrc" }, 82 { .compatible = "sirf,prima2-pwrc" },
54 {}, 83 {},
@@ -70,7 +99,7 @@ static int sirfsoc_pwrc_probe(struct platform_device *pdev)
70 } 99 }
71 100
72 /* 101 /*
73 * we can't use of_iomap because pwrc is not mapped in memory, 102 * We can't use of_iomap because pwrc is not mapped in memory,
74 * the so-called base address is only offset in rtciobrg 103 * the so-called base address is only offset in rtciobrg
75 */ 104 */
76 error = of_property_read_u32(np, "reg", &pwrcdrv->pwrc_base); 105 error = of_property_read_u32(np, "reg", &pwrcdrv->pwrc_base);
@@ -88,6 +117,14 @@ static int sirfsoc_pwrc_probe(struct platform_device *pdev)
88 pwrcdrv->input->phys = "pwrc/input0"; 117 pwrcdrv->input->phys = "pwrc/input0";
89 pwrcdrv->input->evbit[0] = BIT_MASK(EV_PWR); 118 pwrcdrv->input->evbit[0] = BIT_MASK(EV_PWR);
90 119
120 pwrcdrv->input->open = sirfsoc_pwrc_open;
121 pwrcdrv->input->close = sirfsoc_pwrc_close;
122
123 input_set_drvdata(pwrcdrv->input, pwrcdrv);
124
125 /* Make sure the device is quiesced */
126 sirfsoc_pwrc_toggle_interrupts(pwrcdrv, false);
127
91 irq = platform_get_irq(pdev, 0); 128 irq = platform_get_irq(pdev, 0);
92 error = devm_request_irq(&pdev->dev, irq, 129 error = devm_request_irq(&pdev->dev, irq,
93 sirfsoc_pwrc_isr, IRQF_SHARED, 130 sirfsoc_pwrc_isr, IRQF_SHARED,
@@ -98,11 +135,6 @@ static int sirfsoc_pwrc_probe(struct platform_device *pdev)
98 return error; 135 return error;
99 } 136 }
100 137
101 sirfsoc_rtc_iobrg_writel(
102 sirfsoc_rtc_iobrg_readl(pwrcdrv->pwrc_base + PWRC_INT_MASK) |
103 PWRC_ON_KEY_BIT,
104 pwrcdrv->pwrc_base + PWRC_INT_MASK);
105
106 error = input_register_device(pwrcdrv->input); 138 error = input_register_device(pwrcdrv->input);
107 if (error) { 139 if (error) {
108 dev_err(&pdev->dev, 140 dev_err(&pdev->dev,
@@ -129,15 +161,16 @@ static int pwrc_resume(struct device *dev)
129{ 161{
130 struct platform_device *pdev = to_platform_device(dev); 162 struct platform_device *pdev = to_platform_device(dev);
131 struct sirfsoc_pwrc_drvdata *pwrcdrv = platform_get_drvdata(pdev); 163 struct sirfsoc_pwrc_drvdata *pwrcdrv = platform_get_drvdata(pdev);
164 struct input_dev *input = pwrcdrv->input;
132 165
133 /* 166 /*
134 * Do not mask pwrc interrupt as we want pwrc work as a wakeup source 167 * Do not mask pwrc interrupt as we want pwrc work as a wakeup source
135 * if users touch X_ONKEY_B, see arch/arm/mach-prima2/pm.c 168 * if users touch X_ONKEY_B, see arch/arm/mach-prima2/pm.c
136 */ 169 */
137 sirfsoc_rtc_iobrg_writel( 170 mutex_lock(&input->mutex);
138 sirfsoc_rtc_iobrg_readl( 171 if (input->users)
139 pwrcdrv->pwrc_base + PWRC_INT_MASK) | PWRC_ON_KEY_BIT, 172 sirfsoc_pwrc_toggle_interrupts(pwrcdrv, true);
140 pwrcdrv->pwrc_base + PWRC_INT_MASK); 173 mutex_unlock(&input->mutex);
141 174
142 return 0; 175 return 0;
143} 176}