diff options
author | Magnus Damm <damm@opensource.se> | 2011-04-28 09:32:44 -0700 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-04-28 09:36:43 -0700 |
commit | b6d2a3e6ff6a7019b4a240b6bc4a4d74ce82d533 (patch) | |
tree | 90cde4dc7ed09a55316aa471c46bd44c8bcdcf7d /drivers/input/keyboard | |
parent | e490ebdc3ce1a58e66aeacc485294a45710067f5 (diff) | |
download | linux-b6d2a3e6ff6a7019b4a240b6bc4a4d74ce82d533.tar.bz2 |
Input: sh_keysc - implement runtime PM support
Convert the KEYSC driver from MSTP bit control through a magic clock
string to making use of Runtime PM.
Also, update the system suspend/resume callbacks to drop the Runtime
PM reference in the case of wakeup disabled.
Signed-off-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r-- | drivers/input/keyboard/sh_keysc.c | 40 |
1 files changed, 15 insertions, 25 deletions
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index d7dafd9425b6..429ac2b77438 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c @@ -20,7 +20,7 @@ #include <linux/input.h> #include <linux/input/sh_keysc.h> #include <linux/bitmap.h> -#include <linux/clk.h> +#include <linux/pm_runtime.h> #include <linux/io.h> #include <linux/slab.h> @@ -37,7 +37,6 @@ static const struct { struct sh_keysc_priv { void __iomem *iomem_base; - struct clk *clk; DECLARE_BITMAP(last_keys, SH_KEYSC_MAXKEYS); struct input_dev *input; struct sh_keysc_info pdata; @@ -169,7 +168,6 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) struct sh_keysc_info *pdata; struct resource *res; struct input_dev *input; - char clk_name[8]; int i; int irq, error; @@ -210,19 +208,11 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) goto err1; } - snprintf(clk_name, sizeof(clk_name), "keysc%d", pdev->id); - priv->clk = clk_get(&pdev->dev, clk_name); - if (IS_ERR(priv->clk)) { - dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); - error = PTR_ERR(priv->clk); - goto err2; - } - priv->input = input_allocate_device(); if (!priv->input) { dev_err(&pdev->dev, "failed to allocate input device\n"); error = -ENOMEM; - goto err3; + goto err2; } input = priv->input; @@ -244,7 +234,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev); if (error) { dev_err(&pdev->dev, "failed to request IRQ\n"); - goto err4; + goto err3; } for (i = 0; i < SH_KEYSC_MAXKEYS; i++) @@ -254,10 +244,11 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) error = input_register_device(input); if (error) { dev_err(&pdev->dev, "failed to register input device\n"); - goto err5; + goto err4; } - clk_enable(priv->clk); + pm_runtime_enable(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); sh_keysc_write(priv, KYCR1, (sh_keysc_mode[pdata->mode].kymd << 8) | pdata->scan_timing); @@ -267,12 +258,10 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) return 0; - err5: - free_irq(irq, pdev); err4: - input_free_device(input); + free_irq(irq, pdev); err3: - clk_put(priv->clk); + input_free_device(input); err2: iounmap(priv->iomem_base); err1: @@ -292,8 +281,8 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) free_irq(platform_get_irq(pdev, 0), pdev); iounmap(priv->iomem_base); - clk_disable(priv->clk); - clk_put(priv->clk); + pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); platform_set_drvdata(pdev, NULL); kfree(priv); @@ -311,14 +300,13 @@ static int sh_keysc_suspend(struct device *dev) value = sh_keysc_read(priv, KYCR1); if (device_may_wakeup(dev)) { - value |= 0x80; + sh_keysc_write(priv, KYCR1, value | 0x80); enable_irq_wake(irq); } else { - value &= ~0x80; + sh_keysc_write(priv, KYCR1, value & ~0x80); + pm_runtime_put_sync(dev); } - sh_keysc_write(priv, KYCR1, value); - return 0; } @@ -329,6 +317,8 @@ static int sh_keysc_resume(struct device *dev) if (device_may_wakeup(dev)) disable_irq_wake(irq); + else + pm_runtime_get_sync(dev); return 0; } |