diff options
author | Magnus Damm <damm@igel.co.jp> | 2008-10-31 07:21:23 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-12-22 04:42:51 -0500 |
commit | 090d951b69f29a8d5777c63570d4cd61d7efeb22 (patch) | |
tree | 6ef4951714d79b704141dced8e730895af5608ff /drivers/input | |
parent | a5616bd0f19730a780c354110454ce37209f1ded (diff) |
sh: sh_mobile keysc clock framework support
Add clock framework support to the sh_mobile keysc driver and
adjust the board specific code accordingly.
Signed-off-by: Magnus Damm <damm@igel.co.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/keyboard/sh_keysc.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index c600ab7f93e8..5c8a1bcf7ca7 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/input.h> | 20 | #include <linux/input.h> |
21 | #include <linux/clk.h> | ||
21 | #include <linux/io.h> | 22 | #include <linux/io.h> |
22 | #include <asm/sh_keysc.h> | 23 | #include <asm/sh_keysc.h> |
23 | 24 | ||
@@ -39,6 +40,7 @@ static const struct { | |||
39 | 40 | ||
40 | struct sh_keysc_priv { | 41 | struct sh_keysc_priv { |
41 | void __iomem *iomem_base; | 42 | void __iomem *iomem_base; |
43 | struct clk *clk; | ||
42 | unsigned long last_keys; | 44 | unsigned long last_keys; |
43 | struct input_dev *input; | 45 | struct input_dev *input; |
44 | struct sh_keysc_info pdata; | 46 | struct sh_keysc_info pdata; |
@@ -125,6 +127,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
125 | struct sh_keysc_info *pdata; | 127 | struct sh_keysc_info *pdata; |
126 | struct resource *res; | 128 | struct resource *res; |
127 | struct input_dev *input; | 129 | struct input_dev *input; |
130 | char clk_name[8]; | ||
128 | int i, k; | 131 | int i, k; |
129 | int irq, error; | 132 | int irq, error; |
130 | 133 | ||
@@ -165,11 +168,19 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
165 | goto err1; | 168 | goto err1; |
166 | } | 169 | } |
167 | 170 | ||
171 | snprintf(clk_name, sizeof(clk_name), "keysc%d", pdev->id); | ||
172 | priv->clk = clk_get(&pdev->dev, clk_name); | ||
173 | if (IS_ERR(priv->clk)) { | ||
174 | dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); | ||
175 | error = PTR_ERR(priv->clk); | ||
176 | goto err2; | ||
177 | } | ||
178 | |||
168 | priv->input = input_allocate_device(); | 179 | priv->input = input_allocate_device(); |
169 | if (!priv->input) { | 180 | if (!priv->input) { |
170 | dev_err(&pdev->dev, "failed to allocate input device\n"); | 181 | dev_err(&pdev->dev, "failed to allocate input device\n"); |
171 | error = -ENOMEM; | 182 | error = -ENOMEM; |
172 | goto err2; | 183 | goto err3; |
173 | } | 184 | } |
174 | 185 | ||
175 | input = priv->input; | 186 | input = priv->input; |
@@ -187,7 +198,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
187 | error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev); | 198 | error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev); |
188 | if (error) { | 199 | if (error) { |
189 | dev_err(&pdev->dev, "failed to request IRQ\n"); | 200 | dev_err(&pdev->dev, "failed to request IRQ\n"); |
190 | goto err3; | 201 | goto err4; |
191 | } | 202 | } |
192 | 203 | ||
193 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { | 204 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { |
@@ -199,18 +210,22 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
199 | error = input_register_device(input); | 210 | error = input_register_device(input); |
200 | if (error) { | 211 | if (error) { |
201 | dev_err(&pdev->dev, "failed to register input device\n"); | 212 | dev_err(&pdev->dev, "failed to register input device\n"); |
202 | goto err4; | 213 | goto err5; |
203 | } | 214 | } |
204 | 215 | ||
216 | clk_enable(priv->clk); | ||
217 | |||
205 | iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) | | 218 | iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) | |
206 | pdata->scan_timing, priv->iomem_base + KYCR1_OFFS); | 219 | pdata->scan_timing, priv->iomem_base + KYCR1_OFFS); |
207 | iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); | 220 | iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); |
208 | iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); | 221 | iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); |
209 | return 0; | 222 | return 0; |
210 | err4: | 223 | err5: |
211 | free_irq(irq, pdev); | 224 | free_irq(irq, pdev); |
212 | err3: | 225 | err4: |
213 | input_free_device(input); | 226 | input_free_device(input); |
227 | err3: | ||
228 | clk_put(priv->clk); | ||
214 | err2: | 229 | err2: |
215 | iounmap(priv->iomem_base); | 230 | iounmap(priv->iomem_base); |
216 | err1: | 231 | err1: |
@@ -230,6 +245,9 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) | |||
230 | free_irq(platform_get_irq(pdev, 0), pdev); | 245 | free_irq(platform_get_irq(pdev, 0), pdev); |
231 | iounmap(priv->iomem_base); | 246 | iounmap(priv->iomem_base); |
232 | 247 | ||
248 | clk_disable(priv->clk); | ||
249 | clk_put(priv->clk); | ||
250 | |||
233 | platform_set_drvdata(pdev, NULL); | 251 | platform_set_drvdata(pdev, NULL); |
234 | kfree(priv); | 252 | kfree(priv); |
235 | return 0; | 253 | return 0; |