Add the hooks for runtime pm to the keypad driver.  While this
is a no-op from the keypad driver's perspective, it actually isn't
to the rest of the system, since this creates the side effect of
letting the pci subsystem tell the mrst pmu driver that this
device is idle.

Signed-off-by: Kristen Carlson Accardi <[email protected]>
---
 drivers/input/keyboard/intel_mid_keypad.c |   39 +++++++++++++++++++++++++++++
 1 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/drivers/input/keyboard/intel_mid_keypad.c 
b/drivers/input/keyboard/intel_mid_keypad.c
index 1a9536f..ea56302 100644
--- a/drivers/input/keyboard/intel_mid_keypad.c
+++ b/drivers/input/keyboard/intel_mid_keypad.c
@@ -39,6 +39,8 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/pm_runtime.h>
+
 #include <linux/input/intel_mid_keypad.h>
 
 /*
@@ -171,6 +173,8 @@ static void mrst_keypad_scan_matrix(struct mrst_keypad 
*keypad)
        uint32_t new_state[MAX_MATRIX_KEY_COLS];
        uint32_t kpas = keypad_readl(KPAS);
 
+       pm_runtime_get(keypad->input_dev->dev.parent);
+
        num_keys_pressed = KPAS_MUKP(kpas);
 
        memset(new_state, 0, sizeof(new_state));
@@ -219,6 +223,7 @@ static void mrst_keypad_scan_matrix(struct mrst_keypad 
*keypad)
        }
        input_sync(keypad->input_dev);
        memcpy(keypad->matrix_key_state, new_state, sizeof(new_state));
+       pm_runtime_put(keypad->input_dev->dev.parent);
 }
 
 static irqreturn_t mrst_keypad_irq_handler(int irq, void *dev_id)
@@ -371,6 +376,9 @@ static int __devinit mrst_keypad_probe(struct pci_dev *pdev,
                goto failed_free_input;
        }
        pci_set_drvdata(pdev, keypad);
+
+       pm_runtime_put_noidle(&pdev->dev);
+       pm_runtime_allow(&pdev->dev);
        return 0;
 
 failed_free_input:
@@ -394,6 +402,9 @@ static void __devexit mrst_keypad_remove(struct pci_dev 
*pdev)
 {
        struct mrst_keypad *keypad = pci_get_drvdata(pdev);
 
+       pm_runtime_forbid(&pdev->dev);
+       pm_runtime_get_noresume(&pdev->dev);
+
        free_irq(pdev->irq, keypad);
 
        input_unregister_device(keypad->input_dev);
@@ -428,6 +439,31 @@ static int mrst_keypad_resume(struct pci_dev *pdev)
 }
 #endif
 
+static int mrst_keypad_runtime_idle(struct device *dev)
+{
+       int err = pm_schedule_suspend(dev, 500);
+
+       if (err != 0)
+               return 0;
+       return -EBUSY;
+}
+
+static int mrst_keypad_runtime_suspend(struct device *dev)
+{
+       return 0;
+}
+
+static int mrst_keypad_runtime_resume(struct device *dev)
+{
+       return 0;
+}
+
+static const struct dev_pm_ops mrst_keypad_pm = {
+       .runtime_suspend = mrst_keypad_runtime_suspend,
+       .runtime_resume = mrst_keypad_runtime_resume,
+       .runtime_idle = mrst_keypad_runtime_idle,
+};
+
 static struct pci_driver mrst_keypad_driver = {
        .name           = DRV_NAME,
        .id_table       = keypad_pci_tbl,
@@ -437,6 +473,9 @@ static struct pci_driver mrst_keypad_driver = {
        .suspend        = mrst_keypad_suspend,
        .resume         = mrst_keypad_resume,
 #endif /* CONFIG_PM */
+       .driver         = {
+               .pm     = &mrst_keypad_pm,
+       },
 };
 
 static int __init mrst_keypad_init(void)
-- 
1.7.3.1

_______________________________________________
MeeGo-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to