From b6d2a3e6ff6a7019b4a240b6bc4a4d74ce82d533 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 28 Apr 2011 09:32:44 -0700 Subject: [PATCH] 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 Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/sh_keysc.c | 40 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index d7dafd9..429ac2b 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include @@ -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; } -- 2.7.4