<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-stable.git/drivers/input/keyboard/Kconfig, branch linux-3.5.y</title>
<subtitle>Linux kernel stable tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/'/>
<entry>
<title>Input: matrix-keymap - uninline and prepare for device tree support</title>
<updated>2012-05-11T05:38:47+00:00</updated>
<author>
<name>Dmitry Torokhov</name>
<email>dmitry.torokhov@gmail.com</email>
</author>
<published>2012-05-11T05:37:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=1932811f426fee71b7ece67e70aeba7e1b0ebb6d'/>
<id>1932811f426fee71b7ece67e70aeba7e1b0ebb6d</id>
<content type='text'>
Change matrix-keymap helper to be out-of-line, like sparse keymap,
allow the helper perform basic keymap validation and return errors,
and prepare for device tree support.

Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Change matrix-keymap helper to be out-of-line, like sparse keymap,
allow the helper perform basic keymap validation and return errors,
and prepare for device tree support.

Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Input: omap-keypad - dynamically handle register offsets</title>
<updated>2012-05-11T05:33:58+00:00</updated>
<author>
<name>Poddar, Sourav</name>
<email>sourav.poddar@ti.com</email>
</author>
<published>2012-05-11T05:32:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=f77621cc640a7c50b3d8c5254ecc5d91eaa99d0d'/>
<id>f77621cc640a7c50b3d8c5254ecc5d91eaa99d0d</id>
<content type='text'>
Hi Dmitry,

On Wed, May 9, 2012 at 3:14 PM, Poddar, Sourav &lt;sourav.poddar@ti.com&gt; wrote:
&gt; Hi Dmitry,
&gt;
&gt; I did some minor fixes to the patch which you suggested above and
&gt; the keypad is functional now.
&gt;
&gt; Changes:
&gt; - Move "pm_runtime_enable" before using "pm_runtime_get_sync".
&gt;
&gt; Sending the patch inlined..(also attached).
&gt;
&gt; From: G, Manjunath Kondaiah &lt;manjugk@ti.com&gt;
&gt; Date: Mon, 10 Oct 2011 20:52:05 +0530
&gt; Subject: [PATCH] Input: omap-keypad: dynamically handle register offsets
&gt;
&gt; Keypad controller register offsets are different for omap4
&gt; and omap5. Handle these offsets through static mapping and
&gt; assign these mappings during run time.
&gt;
&gt; Tested on omap4430 sdp with 3.4-rc3.
&gt; Tested on omap5430evm with 3.1-custom kernel.
&gt;
&gt; Cc: Andrew Morton &lt;akpm@linux-foundation.org&gt;
&gt; Signed-off-by: Felipe Balbi &lt;balbi@ti.com&gt;
&gt; Signed-off-by: G, Manjunath Kondaiah &lt;manjugk@ti.com&gt;
&gt; Signed-off-by: Sourav Poddar &lt;sourav.poddar@ti.com&gt;
&gt; Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
&gt; ---
&gt;  drivers/input/keyboard/Kconfig        |    4 +-
&gt;  drivers/input/keyboard/omap4-keypad.c |  120 +++++++++++++++++++++++++-------
&gt;  2 files changed, 95 insertions(+), 29 deletions(-)
&gt;
&gt; diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
&gt; index f354813..33bbdee 100644
&gt; --- a/drivers/input/keyboard/Kconfig
&gt; +++ b/drivers/input/keyboard/Kconfig
&gt; @@ -512,9 +512,9 @@ config KEYBOARD_OMAP
&gt;          module will be called omap-keypad.
&gt;
&gt;  config KEYBOARD_OMAP4
&gt; -       tristate "TI OMAP4 keypad support"
&gt; +       tristate "TI OMAP4+ keypad support"
&gt;        help
&gt; -         Say Y here if you want to use the OMAP4 keypad.
&gt; +         Say Y here if you want to use the OMAP4+ keypad.
&gt;
&gt;          To compile this driver as a module, choose M here: the
&gt;          module will be called omap4-keypad.
&gt; diff --git a/drivers/input/keyboard/omap4-keypad.c
&gt; b/drivers/input/keyboard/omap4-keypad.c
&gt; index e809ac0..d7102e8 100644
&gt; --- a/drivers/input/keyboard/omap4-keypad.c
&gt; +++ b/drivers/input/keyboard/omap4-keypad.c
&gt; @@ -68,19 +68,52 @@
&gt;
&gt;  #define OMAP4_MASK_IRQSTATUSDISABLE    0xFFFF
&gt;
&gt; +enum {
&gt; +       KBD_REVISION_OMAP4 = 0,
&gt; +       KBD_REVISION_OMAP5,
&gt; +};
&gt; +
&gt;  struct omap4_keypad {
&gt;        struct input_dev *input;
&gt;
&gt;        void __iomem *base;
&gt; -       int irq;
&gt; +       unsigned int irq;
&gt;
&gt;        unsigned int rows;
&gt;        unsigned int cols;
&gt; +       u32 reg_offset;
&gt; +       u32 irqreg_offset;
&gt;        unsigned int row_shift;
&gt;        unsigned char key_state[8];
&gt;        unsigned short keymap[];
&gt;  };
&gt;
&gt; +static int kbd_readl(struct omap4_keypad *keypad_data, u32 offset)
&gt; +{
&gt; +       return __raw_readl(keypad_data-&gt;base +
&gt; +                               keypad_data-&gt;reg_offset + offset);
&gt; +}
&gt; +
&gt; +static void kbd_writel(struct omap4_keypad *keypad_data, u32 offset, u32 value)
&gt; +{
&gt; +       __raw_writel(value,
&gt; +                    keypad_data-&gt;base + keypad_data-&gt;reg_offset + offset);
&gt; +}
&gt; +
&gt; +static int kbd_read_irqreg(struct omap4_keypad *keypad_data, u32 offset)
&gt; +{
&gt; +       return __raw_readl(keypad_data-&gt;base +
&gt; +                               keypad_data-&gt;irqreg_offset + offset);
&gt; +}
&gt; +
&gt; +static void kbd_write_irqreg(struct omap4_keypad *keypad_data,
&gt; +                            u32 offset, u32 value)
&gt; +{
&gt; +       __raw_writel(value,
&gt; +                    keypad_data-&gt;base + keypad_data-&gt;irqreg_offset + offset);
&gt; +}
&gt; +
&gt; +
&gt;  /* Interrupt handler */
&gt;  static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id)
&gt;  {
&gt; @@ -91,12 +124,11 @@ static irqreturn_t omap4_keypad_interrupt(int
&gt; irq, void *dev_id)
&gt;        u32 *new_state = (u32 *) key_state;
&gt;
&gt;        /* Disable interrupts */
&gt; -       __raw_writel(OMAP4_VAL_IRQDISABLE,
&gt; -                    keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
&gt; +                        OMAP4_VAL_IRQDISABLE);
&gt;
&gt; -       *new_state = __raw_readl(keypad_data-&gt;base + OMAP4_KBD_FULLCODE31_0);
&gt; -       *(new_state + 1) = __raw_readl(keypad_data-&gt;base
&gt; -                                               + OMAP4_KBD_FULLCODE63_32);
&gt; +       *new_state = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE31_0);
&gt; +       *(new_state + 1) = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE63_32);
&gt;
&gt;        for (row = 0; row &lt; keypad_data-&gt;rows; row++) {
&gt;                changed = key_state[row] ^ keypad_data-&gt;key_state[row];
&gt; @@ -121,12 +153,13 @@ static irqreturn_t omap4_keypad_interrupt(int
&gt; irq, void *dev_id)
&gt;                sizeof(keypad_data-&gt;key_state));
&gt;
&gt;        /* clear pending interrupts */
&gt; -       __raw_writel(__raw_readl(keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS),
&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS);
&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS,
&gt; +                        kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS));
&gt;
&gt;        /* enable interrupts */
&gt; -       __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY,
&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
&gt; +               OMAP4_DEF_IRQENABLE_EVENTEN |
&gt; +                               OMAP4_DEF_IRQENABLE_LONGKEY);
&gt;
&gt;        return IRQ_HANDLED;
&gt;  }
&gt; @@ -139,16 +172,17 @@ static int omap4_keypad_open(struct input_dev *input)
&gt;
&gt;        disable_irq(keypad_data-&gt;irq);
&gt;
&gt; -       __raw_writel(OMAP4_VAL_FUNCTIONALCFG,
&gt; -                       keypad_data-&gt;base + OMAP4_KBD_CTRL);
&gt; -       __raw_writel(OMAP4_VAL_DEBOUNCINGTIME,
&gt; -                       keypad_data-&gt;base + OMAP4_KBD_DEBOUNCINGTIME);
&gt; -       __raw_writel(OMAP4_VAL_IRQDISABLE,
&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS);
&gt; -       __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY,
&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt; -       __raw_writel(OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA,
&gt; -                       keypad_data-&gt;base + OMAP4_KBD_WAKEUPENABLE);
&gt; +       kbd_writel(keypad_data, OMAP4_KBD_CTRL,
&gt; +                       OMAP4_VAL_FUNCTIONALCFG);
&gt; +       kbd_writel(keypad_data, OMAP4_KBD_DEBOUNCINGTIME,
&gt; +                       OMAP4_VAL_DEBOUNCINGTIME);
&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS,
&gt; +                       OMAP4_VAL_IRQDISABLE);
&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
&gt; +                       OMAP4_DEF_IRQENABLE_EVENTEN |
&gt; +                               OMAP4_DEF_IRQENABLE_LONGKEY);
&gt; +       kbd_writel(keypad_data, OMAP4_KBD_WAKEUPENABLE,
&gt; +                       OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA);
&gt;
&gt;        enable_irq(keypad_data-&gt;irq);
&gt;
&gt; @@ -162,12 +196,12 @@ static void omap4_keypad_close(struct input_dev *input)
&gt;        disable_irq(keypad_data-&gt;irq);
&gt;
&gt;        /* Disable interrupts */
&gt; -       __raw_writel(OMAP4_VAL_IRQDISABLE,
&gt; -                    keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
&gt; +                        OMAP4_VAL_IRQDISABLE);
&gt;
&gt;        /* clear pending interrupts */
&gt; -       __raw_writel(__raw_readl(keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS),
&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS);
&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS,
&gt; +                        kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS));
&gt;
&gt;        enable_irq(keypad_data-&gt;irq);
&gt;
&gt; @@ -182,6 +216,7 @@ static int __devinit omap4_keypad_probe(struct
&gt; platform_device *pdev)
&gt;        struct resource *res;
&gt;        resource_size_t size;
&gt;        unsigned int row_shift, max_keys;
&gt; +       int rev;
&gt;        int irq;
&gt;        int error;
&gt;
&gt; @@ -241,11 +276,40 @@ static int __devinit omap4_keypad_probe(struct
&gt; platform_device *pdev)
&gt;        keypad_data-&gt;rows = pdata-&gt;rows;
&gt;        keypad_data-&gt;cols = pdata-&gt;cols;
&gt;
&gt; +       /*
&gt; +       * Enable clocks for the keypad module so that we can read
&gt; +       * revision register.
&gt; +       */
&gt; +       pm_runtime_enable(&amp;pdev-&gt;dev);
&gt; +       error = pm_runtime_get_sync(&amp;pdev-&gt;dev);
&gt; +       if (error) {
&gt; +               dev_err(&amp;pdev-&gt;dev, "pm_runtime_get_sync() failed\n");
&gt; +               goto err_unmap;
&gt; +       }
&gt; +       rev = __raw_readl(keypad_data-&gt;base + OMAP4_KBD_REVISION);
&gt; +       rev &amp;= 0x03 &lt;&lt; 30;
&gt; +       rev &gt;&gt;= 30;
&gt; +       switch (rev) {
&gt; +       case KBD_REVISION_OMAP4:
&gt; +               keypad_data-&gt;reg_offset = 0x00;
&gt; +               keypad_data-&gt;irqreg_offset = 0x00;
&gt; +               break;
&gt; +       case KBD_REVISION_OMAP5:
&gt; +               keypad_data-&gt;reg_offset = 0x10;
&gt; +               keypad_data-&gt;irqreg_offset = 0x0c;
&gt; +               break;
&gt; +       default:
&gt; +               dev_err(&amp;pdev-&gt;dev,
&gt; +                       "Keypad reports unsupported revision %d", rev);
&gt; +               error = -EINVAL;
&gt; +               goto err_pm_put_sync;
&gt; +       }
&gt; +
&gt;        /* input device allocation */
&gt;        keypad_data-&gt;input = input_dev = input_allocate_device();
&gt;        if (!input_dev) {
&gt;                error = -ENOMEM;
&gt; -               goto err_unmap;
&gt; +               goto err_pm_put_sync;
&gt;        }
&gt;
&gt;        input_dev-&gt;name = pdev-&gt;name;
&gt; @@ -273,14 +337,14 @@ static int __devinit omap4_keypad_probe(struct
&gt; platform_device *pdev)
&gt;                        input_dev-&gt;keycode, input_dev-&gt;keybit);
&gt;
&gt;        error = request_irq(keypad_data-&gt;irq, omap4_keypad_interrupt,
&gt; -                            IRQF_TRIGGER_RISING,
&gt; +                           IRQF_DISABLED | IRQF_TRIGGER_RISING,
Sorry, " IRQF_DISABLED" got included by mistake.
Removing this stray change and sending it again.

&gt;                             "omap4-keypad", keypad_data);
&gt;        if (error) {
&gt;                dev_err(&amp;pdev-&gt;dev, "failed to register interrupt\n");
&gt;                goto err_free_input;
&gt;        }
&gt;
&gt; -       pm_runtime_enable(&amp;pdev-&gt;dev);
&gt; +       pm_runtime_put_sync(&amp;pdev-&gt;dev);
&gt;
&gt;        error = input_register_device(keypad_data-&gt;input);
&gt;        if (error &lt; 0) {
&gt; @@ -296,6 +360,8 @@ err_pm_disable:
&gt;        free_irq(keypad_data-&gt;irq, keypad_data);
&gt;  err_free_input:
&gt;        input_free_device(input_dev);
&gt; +err_pm_put_sync:
&gt; +       pm_runtime_put_sync(&amp;pdev-&gt;dev);
&gt;  err_unmap:
&gt;        iounmap(keypad_data-&gt;base);
&gt;  err_release_mem:
&gt;
&gt;
&gt; ~Sourav
&gt;
&gt; On Wed, May 9, 2012 at 1:15 PM, Dmitry Torokhov
&gt; &lt;dmitry.torokhov@gmail.com&gt; wrote:
&gt;&gt;&gt; Hi Dmitry ,
&gt;&gt;&gt;
&gt;&gt;&gt;
&gt;&gt;&gt; On Wed, May 9, 2012 at 10:48 AM, Dmitry Torokhov
&gt;&gt;&gt; &lt;dmitry.torokhov@gmail.com&gt; wrote:
&gt;&gt;&gt; &gt; Ho Sourav,
&gt;&gt;&gt; &gt;
&gt;&gt;&gt; &gt; On Thu, Apr 26, 2012 at 11:24:37AM +0530, Sourav Poddar wrote:
&gt;&gt;&gt; &gt;&gt;
&gt;&gt;&gt; &gt;&gt; -config KEYBOARD_OMAP4
&gt;&gt;&gt; &gt;&gt; -     tristate "TI OMAP4 keypad support"
&gt;&gt;&gt; &gt;&gt; +config KEYBOARD_OMAP4+
&gt;&gt;&gt; &gt;
&gt;&gt;&gt; &gt; I think this works purely by accident - '+' sign getting dropped by
&gt;&gt;&gt; &gt; parser...
&gt;&gt;&gt; &gt;
&gt;&gt;&gt; &gt;&gt; @@ -139,16 +192,33 @@ static int omap4_keypad_open(struct input_dev *input)
&gt;&gt;&gt; &gt;&gt;
&gt;&gt;&gt; &gt;&gt;       disable_irq(keypad_data-&gt;irq);
&gt;&gt;&gt; &gt;&gt;
&gt;&gt;&gt; &gt;&gt; -     __raw_writel(OMAP4_VAL_FUNCTIONALCFG,
&gt;&gt;&gt; &gt;&gt; -                     keypad_data-&gt;base + OMAP4_KBD_CTRL);
&gt;&gt;&gt; &gt;&gt; -     __raw_writel(OMAP4_VAL_DEBOUNCINGTIME,
&gt;&gt;&gt; &gt;&gt; -                     keypad_data-&gt;base + OMAP4_KBD_DEBOUNCINGTIME);
&gt;&gt;&gt; &gt;&gt; -     __raw_writel(OMAP4_VAL_IRQDISABLE,
&gt;&gt;&gt; &gt;&gt; -                     keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS);
&gt;&gt;&gt; &gt;&gt; -     __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY,
&gt;&gt;&gt; &gt;&gt; -                     keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt;&gt;&gt; &gt;&gt; -     __raw_writel(OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA,
&gt;&gt;&gt; &gt;&gt; -                     keypad_data-&gt;base + OMAP4_KBD_WAKEUPENABLE);
&gt;&gt;&gt; &gt;&gt; +     keypad_data-&gt;revision = kbd_read_revision(keypad_data,
&gt;&gt;&gt; &gt;&gt; +                     OMAP4_KBD_REVISION);
&gt;&gt;&gt; &gt;&gt; +     switch (keypad_data-&gt;revision) {
&gt;&gt;&gt; &gt;&gt; +     case 1:
&gt;&gt;&gt; &gt;&gt; +             keypad_data-&gt;irqstatus = OMAP4_KBD_IRQSTATUS + 0x0c;
&gt;&gt;&gt; &gt;&gt; +             keypad_data-&gt;irqenable = OMAP4_KBD_IRQENABLE + 0x0c;
&gt;&gt;&gt; &gt;&gt; +             keypad_data-&gt;reg_offset = 0x10;
&gt;&gt;&gt; &gt;&gt; +             break;
&gt;&gt;&gt; &gt;
&gt;&gt;&gt; &gt; This should be done in probe().
&gt;&gt;&gt; &gt;
&gt;&gt;&gt; Dont we then require "pm_runtime_put_sync" in probe, since we are trying
&gt;&gt;&gt; to read the keypad revision register.?
&gt;&gt;
&gt;&gt; Ah, indeed, but I think not pm_runtime_get_sync() but
&gt;&gt; pm_runtime_set_active().
&gt;&gt;
&gt;&gt; Not sure if this will fix the crash...
&gt;&gt;
&gt;&gt; --
&gt;&gt; Dmitry
&gt;&gt;
&gt;&gt;
&gt;&gt; Input: omap-keypad - dynamically handle register offsets
&gt;&gt;
&gt;&gt; From: G, Manjunath Kondaiah &lt;manjugk@ti.com&gt;
&gt;&gt;
&gt;&gt; Keypad controller register offsets are different for omap4
&gt;&gt; and omap5. Handle these offsets through static mapping and
&gt;&gt; assign these mappings during run time.
&gt;&gt;
&gt;&gt; Tested on omap4430 sdp with 3.4-rc3.
&gt;&gt; Tested on omap5430evm with 3.1-custom kernel.
&gt;&gt;
&gt;&gt; Signed-off-by: Felipe Balbi &lt;balbi@ti.com&gt;
&gt;&gt; Signed-off-by: G, Manjunath Kondaiah &lt;manjugk@ti.com&gt;
&gt;&gt; Signed-off-by: Sourav Poddar &lt;sourav.poddar@ti.com&gt;
&gt;&gt; Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
&gt;&gt; ---
&gt;&gt;
&gt;&gt;  drivers/input/keyboard/Kconfig        |    4 +
&gt;&gt;  drivers/input/keyboard/omap4-keypad.c |  117 ++++++++++++++++++++++++++-------
&gt;&gt;  2 files changed, 94 insertions(+), 27 deletions(-)
&gt;&gt;
&gt;&gt;
&gt;&gt; diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
&gt;&gt; index 20a3753..84ee155 100644
&gt;&gt; --- a/drivers/input/keyboard/Kconfig
&gt;&gt; +++ b/drivers/input/keyboard/Kconfig
&gt;&gt; @@ -531,9 +531,9 @@ config KEYBOARD_OMAP
&gt;&gt;          module will be called omap-keypad.
&gt;&gt;
&gt;&gt;  config KEYBOARD_OMAP4
&gt;&gt; -       tristate "TI OMAP4 keypad support"
&gt;&gt; +       tristate "TI OMAP4+ keypad support"
&gt;&gt;        help
&gt;&gt; -         Say Y here if you want to use the OMAP4 keypad.
&gt;&gt; +         Say Y here if you want to use the OMAP4+ keypad.
&gt;&gt;
&gt;&gt;          To compile this driver as a module, choose M here: the
&gt;&gt;          module will be called omap4-keypad.
&gt;&gt; diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c
&gt;&gt; index e809ac0..c9fd0df 100644
&gt;&gt; --- a/drivers/input/keyboard/omap4-keypad.c
&gt;&gt; +++ b/drivers/input/keyboard/omap4-keypad.c
&gt;&gt; @@ -68,19 +68,52 @@
&gt;&gt;
&gt;&gt;  #define OMAP4_MASK_IRQSTATUSDISABLE    0xFFFF
&gt;&gt;
&gt;&gt; +enum {
&gt;&gt; +       KBD_REVISION_OMAP4 = 0,
&gt;&gt; +       KBD_REVISION_OMAP5,
&gt;&gt; +};
&gt;&gt; +
&gt;&gt;  struct omap4_keypad {
&gt;&gt;        struct input_dev *input;
&gt;&gt;
&gt;&gt;        void __iomem *base;
&gt;&gt; -       int irq;
&gt;&gt; +       unsigned int irq;
&gt;&gt;
&gt;&gt;        unsigned int rows;
&gt;&gt;        unsigned int cols;
&gt;&gt; +       u32 reg_offset;
&gt;&gt; +       u32 irqreg_offset;
&gt;&gt;        unsigned int row_shift;
&gt;&gt;        unsigned char key_state[8];
&gt;&gt;        unsigned short keymap[];
&gt;&gt;  };
&gt;&gt;
&gt;&gt; +static int kbd_readl(struct omap4_keypad *keypad_data, u32 offset)
&gt;&gt; +{
&gt;&gt; +       return __raw_readl(keypad_data-&gt;base +
&gt;&gt; +                               keypad_data-&gt;reg_offset + offset);
&gt;&gt; +}
&gt;&gt; +
&gt;&gt; +static void kbd_writel(struct omap4_keypad *keypad_data, u32 offset, u32 value)
&gt;&gt; +{
&gt;&gt; +       __raw_writel(value,
&gt;&gt; +                    keypad_data-&gt;base + keypad_data-&gt;reg_offset + offset);
&gt;&gt; +}
&gt;&gt; +
&gt;&gt; +static int kbd_read_irqreg(struct omap4_keypad *keypad_data, u32 offset)
&gt;&gt; +{
&gt;&gt; +       return __raw_readl(keypad_data-&gt;base +
&gt;&gt; +                               keypad_data-&gt;irqreg_offset + offset);
&gt;&gt; +}
&gt;&gt; +
&gt;&gt; +static void kbd_write_irqreg(struct omap4_keypad *keypad_data,
&gt;&gt; +                            u32 offset, u32 value)
&gt;&gt; +{
&gt;&gt; +       __raw_writel(value,
&gt;&gt; +                    keypad_data-&gt;base + keypad_data-&gt;irqreg_offset + offset);
&gt;&gt; +}
&gt;&gt; +
&gt;&gt; +
&gt;&gt;  /* Interrupt handler */
&gt;&gt;  static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id)
&gt;&gt;  {
&gt;&gt; @@ -91,12 +124,11 @@ static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id)
&gt;&gt;        u32 *new_state = (u32 *) key_state;
&gt;&gt;
&gt;&gt;        /* Disable interrupts */
&gt;&gt; -       __raw_writel(OMAP4_VAL_IRQDISABLE,
&gt;&gt; -                    keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt;&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
&gt;&gt; +                        OMAP4_VAL_IRQDISABLE);
&gt;&gt;
&gt;&gt; -       *new_state = __raw_readl(keypad_data-&gt;base + OMAP4_KBD_FULLCODE31_0);
&gt;&gt; -       *(new_state + 1) = __raw_readl(keypad_data-&gt;base
&gt;&gt; -                                               + OMAP4_KBD_FULLCODE63_32);
&gt;&gt; +       *new_state = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE31_0);
&gt;&gt; +       *(new_state + 1) = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE63_32);
&gt;&gt;
&gt;&gt;        for (row = 0; row &lt; keypad_data-&gt;rows; row++) {
&gt;&gt;                changed = key_state[row] ^ keypad_data-&gt;key_state[row];
&gt;&gt; @@ -121,12 +153,13 @@ static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id)
&gt;&gt;                sizeof(keypad_data-&gt;key_state));
&gt;&gt;
&gt;&gt;        /* clear pending interrupts */
&gt;&gt; -       __raw_writel(__raw_readl(keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS),
&gt;&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS);
&gt;&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS,
&gt;&gt; +                        kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS));
&gt;&gt;
&gt;&gt;        /* enable interrupts */
&gt;&gt; -       __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY,
&gt;&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt;&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
&gt;&gt; +               OMAP4_DEF_IRQENABLE_EVENTEN |
&gt;&gt; +                               OMAP4_DEF_IRQENABLE_LONGKEY);
&gt;&gt;
&gt;&gt;        return IRQ_HANDLED;
&gt;&gt;  }
&gt;&gt; @@ -139,16 +172,17 @@ static int omap4_keypad_open(struct input_dev *input)
&gt;&gt;
&gt;&gt;        disable_irq(keypad_data-&gt;irq);
&gt;&gt;
&gt;&gt; -       __raw_writel(OMAP4_VAL_FUNCTIONALCFG,
&gt;&gt; -                       keypad_data-&gt;base + OMAP4_KBD_CTRL);
&gt;&gt; -       __raw_writel(OMAP4_VAL_DEBOUNCINGTIME,
&gt;&gt; -                       keypad_data-&gt;base + OMAP4_KBD_DEBOUNCINGTIME);
&gt;&gt; -       __raw_writel(OMAP4_VAL_IRQDISABLE,
&gt;&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS);
&gt;&gt; -       __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY,
&gt;&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt;&gt; -       __raw_writel(OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA,
&gt;&gt; -                       keypad_data-&gt;base + OMAP4_KBD_WAKEUPENABLE);
&gt;&gt; +       kbd_writel(keypad_data, OMAP4_KBD_CTRL,
&gt;&gt; +                       OMAP4_VAL_FUNCTIONALCFG);
&gt;&gt; +       kbd_writel(keypad_data, OMAP4_KBD_DEBOUNCINGTIME,
&gt;&gt; +                       OMAP4_VAL_DEBOUNCINGTIME);
&gt;&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS,
&gt;&gt; +                       OMAP4_VAL_IRQDISABLE);
&gt;&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
&gt;&gt; +                       OMAP4_DEF_IRQENABLE_EVENTEN |
&gt;&gt; +                               OMAP4_DEF_IRQENABLE_LONGKEY);
&gt;&gt; +       kbd_writel(keypad_data, OMAP4_KBD_WAKEUPENABLE,
&gt;&gt; +                       OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA);
&gt;&gt;
&gt;&gt;        enable_irq(keypad_data-&gt;irq);
&gt;&gt;
&gt;&gt; @@ -162,12 +196,12 @@ static void omap4_keypad_close(struct input_dev *input)
&gt;&gt;        disable_irq(keypad_data-&gt;irq);
&gt;&gt;
&gt;&gt;        /* Disable interrupts */
&gt;&gt; -       __raw_writel(OMAP4_VAL_IRQDISABLE,
&gt;&gt; -                    keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt;&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
&gt;&gt; +                        OMAP4_VAL_IRQDISABLE);
&gt;&gt;
&gt;&gt;        /* clear pending interrupts */
&gt;&gt; -       __raw_writel(__raw_readl(keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS),
&gt;&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS);
&gt;&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS,
&gt;&gt; +                        kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS));
&gt;&gt;
&gt;&gt;        enable_irq(keypad_data-&gt;irq);
&gt;&gt;
&gt;&gt; @@ -182,6 +216,7 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev)
&gt;&gt;        struct resource *res;
&gt;&gt;        resource_size_t size;
&gt;&gt;        unsigned int row_shift, max_keys;
&gt;&gt; +       int rev;
&gt;&gt;        int irq;
&gt;&gt;        int error;
&gt;&gt;
&gt;&gt; @@ -241,11 +276,40 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev)
&gt;&gt;        keypad_data-&gt;rows = pdata-&gt;rows;
&gt;&gt;        keypad_data-&gt;cols = pdata-&gt;cols;
&gt;&gt;
&gt;&gt; +       /*
&gt;&gt; +        * Mark device as active (and wake up its parent) so we can read
&gt;&gt; +        * revision register.
&gt;&gt; +        */
&gt;&gt; +       error = pm_runtime_set_active(&amp;pdev-&gt;dev);
&gt;&gt; +       if (error) {
&gt;&gt; +               dev_err(&amp;pdev-&gt;dev, "pm_runtime_set_active() failed\n");
&gt;&gt; +               goto err_unmap;
&gt;&gt; +       }
&gt;&gt; +
&gt;&gt; +       rev = __raw_readl(keypad_data-&gt;base + OMAP4_KBD_REVISION);
&gt;&gt; +       rev &amp;= 0x03 &lt;&lt; 30;
&gt;&gt; +       rev &gt;&gt;= 30;
&gt;&gt; +       switch (rev) {
&gt;&gt; +       case KBD_REVISION_OMAP4:
&gt;&gt; +               keypad_data-&gt;reg_offset = 0x00;
&gt;&gt; +               keypad_data-&gt;irqreg_offset = 0x00;
&gt;&gt; +               break;
&gt;&gt; +       case KBD_REVISION_OMAP5:
&gt;&gt; +               keypad_data-&gt;reg_offset = 0x10;
&gt;&gt; +               keypad_data-&gt;irqreg_offset = 0x0c;
&gt;&gt; +               break;
&gt;&gt; +       default:
&gt;&gt; +               dev_err(&amp;pdev-&gt;dev,
&gt;&gt; +                       "Keypad reports unsupported revision %d", rev);
&gt;&gt; +               error = -EINVAL;
&gt;&gt; +               goto err_pm_suspended;
&gt;&gt; +       }
&gt;&gt; +
&gt;&gt;        /* input device allocation */
&gt;&gt;        keypad_data-&gt;input = input_dev = input_allocate_device();
&gt;&gt;        if (!input_dev) {
&gt;&gt;                error = -ENOMEM;
&gt;&gt; -               goto err_unmap;
&gt;&gt; +               goto err_pm_suspended;
&gt;&gt;        }
&gt;&gt;
&gt;&gt;        input_dev-&gt;name = pdev-&gt;name;
&gt;&gt; @@ -281,6 +345,7 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev)
&gt;&gt;        }
&gt;&gt;
&gt;&gt;        pm_runtime_enable(&amp;pdev-&gt;dev);
&gt;&gt; +       pm_runtime_put_sync(&amp;pdev-&gt;dev);
&gt;&gt;
&gt;&gt;        error = input_register_device(keypad_data-&gt;input);
&gt;&gt;        if (error &lt; 0) {
&gt;&gt; @@ -296,6 +361,8 @@ err_pm_disable:
&gt;&gt;        free_irq(keypad_data-&gt;irq, keypad_data);
&gt;&gt;  err_free_input:
&gt;&gt;        input_free_device(input_dev);
&gt;&gt; +err_pm_suspended:
&gt;&gt; +       pm_runtime_set_suspended(&amp;pdev-&gt;dev);
&gt;&gt;  err_unmap:
&gt;&gt;        iounmap(keypad_data-&gt;base);
&gt;&gt;  err_release_mem:

From: G, Manjunath Kondaiah &lt;manjugk@ti.com&gt;
Date: Mon, 10 Oct 2011 20:52:05 +0530
Subject: [PATCH] Input: omap-keypad: dynamically handle register offsets

Keypad controller register offsets are different for omap4
and omap5. Handle these offsets through static mapping and
assign these mappings during run time.

Tested on omap4430 sdp with 3.4-rc3.
Tested on omap5430evm with 3.1-custom kernel.

Cc: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Felipe Balbi &lt;balbi@ti.com&gt;
Signed-off-by: G, Manjunath Kondaiah &lt;manjugk@ti.com&gt;
Signed-off-by: Sourav Poddar &lt;sourav.poddar@ti.com&gt;
Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Hi Dmitry,

On Wed, May 9, 2012 at 3:14 PM, Poddar, Sourav &lt;sourav.poddar@ti.com&gt; wrote:
&gt; Hi Dmitry,
&gt;
&gt; I did some minor fixes to the patch which you suggested above and
&gt; the keypad is functional now.
&gt;
&gt; Changes:
&gt; - Move "pm_runtime_enable" before using "pm_runtime_get_sync".
&gt;
&gt; Sending the patch inlined..(also attached).
&gt;
&gt; From: G, Manjunath Kondaiah &lt;manjugk@ti.com&gt;
&gt; Date: Mon, 10 Oct 2011 20:52:05 +0530
&gt; Subject: [PATCH] Input: omap-keypad: dynamically handle register offsets
&gt;
&gt; Keypad controller register offsets are different for omap4
&gt; and omap5. Handle these offsets through static mapping and
&gt; assign these mappings during run time.
&gt;
&gt; Tested on omap4430 sdp with 3.4-rc3.
&gt; Tested on omap5430evm with 3.1-custom kernel.
&gt;
&gt; Cc: Andrew Morton &lt;akpm@linux-foundation.org&gt;
&gt; Signed-off-by: Felipe Balbi &lt;balbi@ti.com&gt;
&gt; Signed-off-by: G, Manjunath Kondaiah &lt;manjugk@ti.com&gt;
&gt; Signed-off-by: Sourav Poddar &lt;sourav.poddar@ti.com&gt;
&gt; Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
&gt; ---
&gt;  drivers/input/keyboard/Kconfig        |    4 +-
&gt;  drivers/input/keyboard/omap4-keypad.c |  120 +++++++++++++++++++++++++-------
&gt;  2 files changed, 95 insertions(+), 29 deletions(-)
&gt;
&gt; diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
&gt; index f354813..33bbdee 100644
&gt; --- a/drivers/input/keyboard/Kconfig
&gt; +++ b/drivers/input/keyboard/Kconfig
&gt; @@ -512,9 +512,9 @@ config KEYBOARD_OMAP
&gt;          module will be called omap-keypad.
&gt;
&gt;  config KEYBOARD_OMAP4
&gt; -       tristate "TI OMAP4 keypad support"
&gt; +       tristate "TI OMAP4+ keypad support"
&gt;        help
&gt; -         Say Y here if you want to use the OMAP4 keypad.
&gt; +         Say Y here if you want to use the OMAP4+ keypad.
&gt;
&gt;          To compile this driver as a module, choose M here: the
&gt;          module will be called omap4-keypad.
&gt; diff --git a/drivers/input/keyboard/omap4-keypad.c
&gt; b/drivers/input/keyboard/omap4-keypad.c
&gt; index e809ac0..d7102e8 100644
&gt; --- a/drivers/input/keyboard/omap4-keypad.c
&gt; +++ b/drivers/input/keyboard/omap4-keypad.c
&gt; @@ -68,19 +68,52 @@
&gt;
&gt;  #define OMAP4_MASK_IRQSTATUSDISABLE    0xFFFF
&gt;
&gt; +enum {
&gt; +       KBD_REVISION_OMAP4 = 0,
&gt; +       KBD_REVISION_OMAP5,
&gt; +};
&gt; +
&gt;  struct omap4_keypad {
&gt;        struct input_dev *input;
&gt;
&gt;        void __iomem *base;
&gt; -       int irq;
&gt; +       unsigned int irq;
&gt;
&gt;        unsigned int rows;
&gt;        unsigned int cols;
&gt; +       u32 reg_offset;
&gt; +       u32 irqreg_offset;
&gt;        unsigned int row_shift;
&gt;        unsigned char key_state[8];
&gt;        unsigned short keymap[];
&gt;  };
&gt;
&gt; +static int kbd_readl(struct omap4_keypad *keypad_data, u32 offset)
&gt; +{
&gt; +       return __raw_readl(keypad_data-&gt;base +
&gt; +                               keypad_data-&gt;reg_offset + offset);
&gt; +}
&gt; +
&gt; +static void kbd_writel(struct omap4_keypad *keypad_data, u32 offset, u32 value)
&gt; +{
&gt; +       __raw_writel(value,
&gt; +                    keypad_data-&gt;base + keypad_data-&gt;reg_offset + offset);
&gt; +}
&gt; +
&gt; +static int kbd_read_irqreg(struct omap4_keypad *keypad_data, u32 offset)
&gt; +{
&gt; +       return __raw_readl(keypad_data-&gt;base +
&gt; +                               keypad_data-&gt;irqreg_offset + offset);
&gt; +}
&gt; +
&gt; +static void kbd_write_irqreg(struct omap4_keypad *keypad_data,
&gt; +                            u32 offset, u32 value)
&gt; +{
&gt; +       __raw_writel(value,
&gt; +                    keypad_data-&gt;base + keypad_data-&gt;irqreg_offset + offset);
&gt; +}
&gt; +
&gt; +
&gt;  /* Interrupt handler */
&gt;  static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id)
&gt;  {
&gt; @@ -91,12 +124,11 @@ static irqreturn_t omap4_keypad_interrupt(int
&gt; irq, void *dev_id)
&gt;        u32 *new_state = (u32 *) key_state;
&gt;
&gt;        /* Disable interrupts */
&gt; -       __raw_writel(OMAP4_VAL_IRQDISABLE,
&gt; -                    keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
&gt; +                        OMAP4_VAL_IRQDISABLE);
&gt;
&gt; -       *new_state = __raw_readl(keypad_data-&gt;base + OMAP4_KBD_FULLCODE31_0);
&gt; -       *(new_state + 1) = __raw_readl(keypad_data-&gt;base
&gt; -                                               + OMAP4_KBD_FULLCODE63_32);
&gt; +       *new_state = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE31_0);
&gt; +       *(new_state + 1) = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE63_32);
&gt;
&gt;        for (row = 0; row &lt; keypad_data-&gt;rows; row++) {
&gt;                changed = key_state[row] ^ keypad_data-&gt;key_state[row];
&gt; @@ -121,12 +153,13 @@ static irqreturn_t omap4_keypad_interrupt(int
&gt; irq, void *dev_id)
&gt;                sizeof(keypad_data-&gt;key_state));
&gt;
&gt;        /* clear pending interrupts */
&gt; -       __raw_writel(__raw_readl(keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS),
&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS);
&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS,
&gt; +                        kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS));
&gt;
&gt;        /* enable interrupts */
&gt; -       __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY,
&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
&gt; +               OMAP4_DEF_IRQENABLE_EVENTEN |
&gt; +                               OMAP4_DEF_IRQENABLE_LONGKEY);
&gt;
&gt;        return IRQ_HANDLED;
&gt;  }
&gt; @@ -139,16 +172,17 @@ static int omap4_keypad_open(struct input_dev *input)
&gt;
&gt;        disable_irq(keypad_data-&gt;irq);
&gt;
&gt; -       __raw_writel(OMAP4_VAL_FUNCTIONALCFG,
&gt; -                       keypad_data-&gt;base + OMAP4_KBD_CTRL);
&gt; -       __raw_writel(OMAP4_VAL_DEBOUNCINGTIME,
&gt; -                       keypad_data-&gt;base + OMAP4_KBD_DEBOUNCINGTIME);
&gt; -       __raw_writel(OMAP4_VAL_IRQDISABLE,
&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS);
&gt; -       __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY,
&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt; -       __raw_writel(OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA,
&gt; -                       keypad_data-&gt;base + OMAP4_KBD_WAKEUPENABLE);
&gt; +       kbd_writel(keypad_data, OMAP4_KBD_CTRL,
&gt; +                       OMAP4_VAL_FUNCTIONALCFG);
&gt; +       kbd_writel(keypad_data, OMAP4_KBD_DEBOUNCINGTIME,
&gt; +                       OMAP4_VAL_DEBOUNCINGTIME);
&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS,
&gt; +                       OMAP4_VAL_IRQDISABLE);
&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
&gt; +                       OMAP4_DEF_IRQENABLE_EVENTEN |
&gt; +                               OMAP4_DEF_IRQENABLE_LONGKEY);
&gt; +       kbd_writel(keypad_data, OMAP4_KBD_WAKEUPENABLE,
&gt; +                       OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA);
&gt;
&gt;        enable_irq(keypad_data-&gt;irq);
&gt;
&gt; @@ -162,12 +196,12 @@ static void omap4_keypad_close(struct input_dev *input)
&gt;        disable_irq(keypad_data-&gt;irq);
&gt;
&gt;        /* Disable interrupts */
&gt; -       __raw_writel(OMAP4_VAL_IRQDISABLE,
&gt; -                    keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
&gt; +                        OMAP4_VAL_IRQDISABLE);
&gt;
&gt;        /* clear pending interrupts */
&gt; -       __raw_writel(__raw_readl(keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS),
&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS);
&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS,
&gt; +                        kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS));
&gt;
&gt;        enable_irq(keypad_data-&gt;irq);
&gt;
&gt; @@ -182,6 +216,7 @@ static int __devinit omap4_keypad_probe(struct
&gt; platform_device *pdev)
&gt;        struct resource *res;
&gt;        resource_size_t size;
&gt;        unsigned int row_shift, max_keys;
&gt; +       int rev;
&gt;        int irq;
&gt;        int error;
&gt;
&gt; @@ -241,11 +276,40 @@ static int __devinit omap4_keypad_probe(struct
&gt; platform_device *pdev)
&gt;        keypad_data-&gt;rows = pdata-&gt;rows;
&gt;        keypad_data-&gt;cols = pdata-&gt;cols;
&gt;
&gt; +       /*
&gt; +       * Enable clocks for the keypad module so that we can read
&gt; +       * revision register.
&gt; +       */
&gt; +       pm_runtime_enable(&amp;pdev-&gt;dev);
&gt; +       error = pm_runtime_get_sync(&amp;pdev-&gt;dev);
&gt; +       if (error) {
&gt; +               dev_err(&amp;pdev-&gt;dev, "pm_runtime_get_sync() failed\n");
&gt; +               goto err_unmap;
&gt; +       }
&gt; +       rev = __raw_readl(keypad_data-&gt;base + OMAP4_KBD_REVISION);
&gt; +       rev &amp;= 0x03 &lt;&lt; 30;
&gt; +       rev &gt;&gt;= 30;
&gt; +       switch (rev) {
&gt; +       case KBD_REVISION_OMAP4:
&gt; +               keypad_data-&gt;reg_offset = 0x00;
&gt; +               keypad_data-&gt;irqreg_offset = 0x00;
&gt; +               break;
&gt; +       case KBD_REVISION_OMAP5:
&gt; +               keypad_data-&gt;reg_offset = 0x10;
&gt; +               keypad_data-&gt;irqreg_offset = 0x0c;
&gt; +               break;
&gt; +       default:
&gt; +               dev_err(&amp;pdev-&gt;dev,
&gt; +                       "Keypad reports unsupported revision %d", rev);
&gt; +               error = -EINVAL;
&gt; +               goto err_pm_put_sync;
&gt; +       }
&gt; +
&gt;        /* input device allocation */
&gt;        keypad_data-&gt;input = input_dev = input_allocate_device();
&gt;        if (!input_dev) {
&gt;                error = -ENOMEM;
&gt; -               goto err_unmap;
&gt; +               goto err_pm_put_sync;
&gt;        }
&gt;
&gt;        input_dev-&gt;name = pdev-&gt;name;
&gt; @@ -273,14 +337,14 @@ static int __devinit omap4_keypad_probe(struct
&gt; platform_device *pdev)
&gt;                        input_dev-&gt;keycode, input_dev-&gt;keybit);
&gt;
&gt;        error = request_irq(keypad_data-&gt;irq, omap4_keypad_interrupt,
&gt; -                            IRQF_TRIGGER_RISING,
&gt; +                           IRQF_DISABLED | IRQF_TRIGGER_RISING,
Sorry, " IRQF_DISABLED" got included by mistake.
Removing this stray change and sending it again.

&gt;                             "omap4-keypad", keypad_data);
&gt;        if (error) {
&gt;                dev_err(&amp;pdev-&gt;dev, "failed to register interrupt\n");
&gt;                goto err_free_input;
&gt;        }
&gt;
&gt; -       pm_runtime_enable(&amp;pdev-&gt;dev);
&gt; +       pm_runtime_put_sync(&amp;pdev-&gt;dev);
&gt;
&gt;        error = input_register_device(keypad_data-&gt;input);
&gt;        if (error &lt; 0) {
&gt; @@ -296,6 +360,8 @@ err_pm_disable:
&gt;        free_irq(keypad_data-&gt;irq, keypad_data);
&gt;  err_free_input:
&gt;        input_free_device(input_dev);
&gt; +err_pm_put_sync:
&gt; +       pm_runtime_put_sync(&amp;pdev-&gt;dev);
&gt;  err_unmap:
&gt;        iounmap(keypad_data-&gt;base);
&gt;  err_release_mem:
&gt;
&gt;
&gt; ~Sourav
&gt;
&gt; On Wed, May 9, 2012 at 1:15 PM, Dmitry Torokhov
&gt; &lt;dmitry.torokhov@gmail.com&gt; wrote:
&gt;&gt;&gt; Hi Dmitry ,
&gt;&gt;&gt;
&gt;&gt;&gt;
&gt;&gt;&gt; On Wed, May 9, 2012 at 10:48 AM, Dmitry Torokhov
&gt;&gt;&gt; &lt;dmitry.torokhov@gmail.com&gt; wrote:
&gt;&gt;&gt; &gt; Ho Sourav,
&gt;&gt;&gt; &gt;
&gt;&gt;&gt; &gt; On Thu, Apr 26, 2012 at 11:24:37AM +0530, Sourav Poddar wrote:
&gt;&gt;&gt; &gt;&gt;
&gt;&gt;&gt; &gt;&gt; -config KEYBOARD_OMAP4
&gt;&gt;&gt; &gt;&gt; -     tristate "TI OMAP4 keypad support"
&gt;&gt;&gt; &gt;&gt; +config KEYBOARD_OMAP4+
&gt;&gt;&gt; &gt;
&gt;&gt;&gt; &gt; I think this works purely by accident - '+' sign getting dropped by
&gt;&gt;&gt; &gt; parser...
&gt;&gt;&gt; &gt;
&gt;&gt;&gt; &gt;&gt; @@ -139,16 +192,33 @@ static int omap4_keypad_open(struct input_dev *input)
&gt;&gt;&gt; &gt;&gt;
&gt;&gt;&gt; &gt;&gt;       disable_irq(keypad_data-&gt;irq);
&gt;&gt;&gt; &gt;&gt;
&gt;&gt;&gt; &gt;&gt; -     __raw_writel(OMAP4_VAL_FUNCTIONALCFG,
&gt;&gt;&gt; &gt;&gt; -                     keypad_data-&gt;base + OMAP4_KBD_CTRL);
&gt;&gt;&gt; &gt;&gt; -     __raw_writel(OMAP4_VAL_DEBOUNCINGTIME,
&gt;&gt;&gt; &gt;&gt; -                     keypad_data-&gt;base + OMAP4_KBD_DEBOUNCINGTIME);
&gt;&gt;&gt; &gt;&gt; -     __raw_writel(OMAP4_VAL_IRQDISABLE,
&gt;&gt;&gt; &gt;&gt; -                     keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS);
&gt;&gt;&gt; &gt;&gt; -     __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY,
&gt;&gt;&gt; &gt;&gt; -                     keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt;&gt;&gt; &gt;&gt; -     __raw_writel(OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA,
&gt;&gt;&gt; &gt;&gt; -                     keypad_data-&gt;base + OMAP4_KBD_WAKEUPENABLE);
&gt;&gt;&gt; &gt;&gt; +     keypad_data-&gt;revision = kbd_read_revision(keypad_data,
&gt;&gt;&gt; &gt;&gt; +                     OMAP4_KBD_REVISION);
&gt;&gt;&gt; &gt;&gt; +     switch (keypad_data-&gt;revision) {
&gt;&gt;&gt; &gt;&gt; +     case 1:
&gt;&gt;&gt; &gt;&gt; +             keypad_data-&gt;irqstatus = OMAP4_KBD_IRQSTATUS + 0x0c;
&gt;&gt;&gt; &gt;&gt; +             keypad_data-&gt;irqenable = OMAP4_KBD_IRQENABLE + 0x0c;
&gt;&gt;&gt; &gt;&gt; +             keypad_data-&gt;reg_offset = 0x10;
&gt;&gt;&gt; &gt;&gt; +             break;
&gt;&gt;&gt; &gt;
&gt;&gt;&gt; &gt; This should be done in probe().
&gt;&gt;&gt; &gt;
&gt;&gt;&gt; Dont we then require "pm_runtime_put_sync" in probe, since we are trying
&gt;&gt;&gt; to read the keypad revision register.?
&gt;&gt;
&gt;&gt; Ah, indeed, but I think not pm_runtime_get_sync() but
&gt;&gt; pm_runtime_set_active().
&gt;&gt;
&gt;&gt; Not sure if this will fix the crash...
&gt;&gt;
&gt;&gt; --
&gt;&gt; Dmitry
&gt;&gt;
&gt;&gt;
&gt;&gt; Input: omap-keypad - dynamically handle register offsets
&gt;&gt;
&gt;&gt; From: G, Manjunath Kondaiah &lt;manjugk@ti.com&gt;
&gt;&gt;
&gt;&gt; Keypad controller register offsets are different for omap4
&gt;&gt; and omap5. Handle these offsets through static mapping and
&gt;&gt; assign these mappings during run time.
&gt;&gt;
&gt;&gt; Tested on omap4430 sdp with 3.4-rc3.
&gt;&gt; Tested on omap5430evm with 3.1-custom kernel.
&gt;&gt;
&gt;&gt; Signed-off-by: Felipe Balbi &lt;balbi@ti.com&gt;
&gt;&gt; Signed-off-by: G, Manjunath Kondaiah &lt;manjugk@ti.com&gt;
&gt;&gt; Signed-off-by: Sourav Poddar &lt;sourav.poddar@ti.com&gt;
&gt;&gt; Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
&gt;&gt; ---
&gt;&gt;
&gt;&gt;  drivers/input/keyboard/Kconfig        |    4 +
&gt;&gt;  drivers/input/keyboard/omap4-keypad.c |  117 ++++++++++++++++++++++++++-------
&gt;&gt;  2 files changed, 94 insertions(+), 27 deletions(-)
&gt;&gt;
&gt;&gt;
&gt;&gt; diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
&gt;&gt; index 20a3753..84ee155 100644
&gt;&gt; --- a/drivers/input/keyboard/Kconfig
&gt;&gt; +++ b/drivers/input/keyboard/Kconfig
&gt;&gt; @@ -531,9 +531,9 @@ config KEYBOARD_OMAP
&gt;&gt;          module will be called omap-keypad.
&gt;&gt;
&gt;&gt;  config KEYBOARD_OMAP4
&gt;&gt; -       tristate "TI OMAP4 keypad support"
&gt;&gt; +       tristate "TI OMAP4+ keypad support"
&gt;&gt;        help
&gt;&gt; -         Say Y here if you want to use the OMAP4 keypad.
&gt;&gt; +         Say Y here if you want to use the OMAP4+ keypad.
&gt;&gt;
&gt;&gt;          To compile this driver as a module, choose M here: the
&gt;&gt;          module will be called omap4-keypad.
&gt;&gt; diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c
&gt;&gt; index e809ac0..c9fd0df 100644
&gt;&gt; --- a/drivers/input/keyboard/omap4-keypad.c
&gt;&gt; +++ b/drivers/input/keyboard/omap4-keypad.c
&gt;&gt; @@ -68,19 +68,52 @@
&gt;&gt;
&gt;&gt;  #define OMAP4_MASK_IRQSTATUSDISABLE    0xFFFF
&gt;&gt;
&gt;&gt; +enum {
&gt;&gt; +       KBD_REVISION_OMAP4 = 0,
&gt;&gt; +       KBD_REVISION_OMAP5,
&gt;&gt; +};
&gt;&gt; +
&gt;&gt;  struct omap4_keypad {
&gt;&gt;        struct input_dev *input;
&gt;&gt;
&gt;&gt;        void __iomem *base;
&gt;&gt; -       int irq;
&gt;&gt; +       unsigned int irq;
&gt;&gt;
&gt;&gt;        unsigned int rows;
&gt;&gt;        unsigned int cols;
&gt;&gt; +       u32 reg_offset;
&gt;&gt; +       u32 irqreg_offset;
&gt;&gt;        unsigned int row_shift;
&gt;&gt;        unsigned char key_state[8];
&gt;&gt;        unsigned short keymap[];
&gt;&gt;  };
&gt;&gt;
&gt;&gt; +static int kbd_readl(struct omap4_keypad *keypad_data, u32 offset)
&gt;&gt; +{
&gt;&gt; +       return __raw_readl(keypad_data-&gt;base +
&gt;&gt; +                               keypad_data-&gt;reg_offset + offset);
&gt;&gt; +}
&gt;&gt; +
&gt;&gt; +static void kbd_writel(struct omap4_keypad *keypad_data, u32 offset, u32 value)
&gt;&gt; +{
&gt;&gt; +       __raw_writel(value,
&gt;&gt; +                    keypad_data-&gt;base + keypad_data-&gt;reg_offset + offset);
&gt;&gt; +}
&gt;&gt; +
&gt;&gt; +static int kbd_read_irqreg(struct omap4_keypad *keypad_data, u32 offset)
&gt;&gt; +{
&gt;&gt; +       return __raw_readl(keypad_data-&gt;base +
&gt;&gt; +                               keypad_data-&gt;irqreg_offset + offset);
&gt;&gt; +}
&gt;&gt; +
&gt;&gt; +static void kbd_write_irqreg(struct omap4_keypad *keypad_data,
&gt;&gt; +                            u32 offset, u32 value)
&gt;&gt; +{
&gt;&gt; +       __raw_writel(value,
&gt;&gt; +                    keypad_data-&gt;base + keypad_data-&gt;irqreg_offset + offset);
&gt;&gt; +}
&gt;&gt; +
&gt;&gt; +
&gt;&gt;  /* Interrupt handler */
&gt;&gt;  static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id)
&gt;&gt;  {
&gt;&gt; @@ -91,12 +124,11 @@ static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id)
&gt;&gt;        u32 *new_state = (u32 *) key_state;
&gt;&gt;
&gt;&gt;        /* Disable interrupts */
&gt;&gt; -       __raw_writel(OMAP4_VAL_IRQDISABLE,
&gt;&gt; -                    keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt;&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
&gt;&gt; +                        OMAP4_VAL_IRQDISABLE);
&gt;&gt;
&gt;&gt; -       *new_state = __raw_readl(keypad_data-&gt;base + OMAP4_KBD_FULLCODE31_0);
&gt;&gt; -       *(new_state + 1) = __raw_readl(keypad_data-&gt;base
&gt;&gt; -                                               + OMAP4_KBD_FULLCODE63_32);
&gt;&gt; +       *new_state = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE31_0);
&gt;&gt; +       *(new_state + 1) = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE63_32);
&gt;&gt;
&gt;&gt;        for (row = 0; row &lt; keypad_data-&gt;rows; row++) {
&gt;&gt;                changed = key_state[row] ^ keypad_data-&gt;key_state[row];
&gt;&gt; @@ -121,12 +153,13 @@ static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id)
&gt;&gt;                sizeof(keypad_data-&gt;key_state));
&gt;&gt;
&gt;&gt;        /* clear pending interrupts */
&gt;&gt; -       __raw_writel(__raw_readl(keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS),
&gt;&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS);
&gt;&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS,
&gt;&gt; +                        kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS));
&gt;&gt;
&gt;&gt;        /* enable interrupts */
&gt;&gt; -       __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY,
&gt;&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt;&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
&gt;&gt; +               OMAP4_DEF_IRQENABLE_EVENTEN |
&gt;&gt; +                               OMAP4_DEF_IRQENABLE_LONGKEY);
&gt;&gt;
&gt;&gt;        return IRQ_HANDLED;
&gt;&gt;  }
&gt;&gt; @@ -139,16 +172,17 @@ static int omap4_keypad_open(struct input_dev *input)
&gt;&gt;
&gt;&gt;        disable_irq(keypad_data-&gt;irq);
&gt;&gt;
&gt;&gt; -       __raw_writel(OMAP4_VAL_FUNCTIONALCFG,
&gt;&gt; -                       keypad_data-&gt;base + OMAP4_KBD_CTRL);
&gt;&gt; -       __raw_writel(OMAP4_VAL_DEBOUNCINGTIME,
&gt;&gt; -                       keypad_data-&gt;base + OMAP4_KBD_DEBOUNCINGTIME);
&gt;&gt; -       __raw_writel(OMAP4_VAL_IRQDISABLE,
&gt;&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS);
&gt;&gt; -       __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY,
&gt;&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt;&gt; -       __raw_writel(OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA,
&gt;&gt; -                       keypad_data-&gt;base + OMAP4_KBD_WAKEUPENABLE);
&gt;&gt; +       kbd_writel(keypad_data, OMAP4_KBD_CTRL,
&gt;&gt; +                       OMAP4_VAL_FUNCTIONALCFG);
&gt;&gt; +       kbd_writel(keypad_data, OMAP4_KBD_DEBOUNCINGTIME,
&gt;&gt; +                       OMAP4_VAL_DEBOUNCINGTIME);
&gt;&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS,
&gt;&gt; +                       OMAP4_VAL_IRQDISABLE);
&gt;&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
&gt;&gt; +                       OMAP4_DEF_IRQENABLE_EVENTEN |
&gt;&gt; +                               OMAP4_DEF_IRQENABLE_LONGKEY);
&gt;&gt; +       kbd_writel(keypad_data, OMAP4_KBD_WAKEUPENABLE,
&gt;&gt; +                       OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA);
&gt;&gt;
&gt;&gt;        enable_irq(keypad_data-&gt;irq);
&gt;&gt;
&gt;&gt; @@ -162,12 +196,12 @@ static void omap4_keypad_close(struct input_dev *input)
&gt;&gt;        disable_irq(keypad_data-&gt;irq);
&gt;&gt;
&gt;&gt;        /* Disable interrupts */
&gt;&gt; -       __raw_writel(OMAP4_VAL_IRQDISABLE,
&gt;&gt; -                    keypad_data-&gt;base + OMAP4_KBD_IRQENABLE);
&gt;&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
&gt;&gt; +                        OMAP4_VAL_IRQDISABLE);
&gt;&gt;
&gt;&gt;        /* clear pending interrupts */
&gt;&gt; -       __raw_writel(__raw_readl(keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS),
&gt;&gt; -                       keypad_data-&gt;base + OMAP4_KBD_IRQSTATUS);
&gt;&gt; +       kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS,
&gt;&gt; +                        kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS));
&gt;&gt;
&gt;&gt;        enable_irq(keypad_data-&gt;irq);
&gt;&gt;
&gt;&gt; @@ -182,6 +216,7 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev)
&gt;&gt;        struct resource *res;
&gt;&gt;        resource_size_t size;
&gt;&gt;        unsigned int row_shift, max_keys;
&gt;&gt; +       int rev;
&gt;&gt;        int irq;
&gt;&gt;        int error;
&gt;&gt;
&gt;&gt; @@ -241,11 +276,40 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev)
&gt;&gt;        keypad_data-&gt;rows = pdata-&gt;rows;
&gt;&gt;        keypad_data-&gt;cols = pdata-&gt;cols;
&gt;&gt;
&gt;&gt; +       /*
&gt;&gt; +        * Mark device as active (and wake up its parent) so we can read
&gt;&gt; +        * revision register.
&gt;&gt; +        */
&gt;&gt; +       error = pm_runtime_set_active(&amp;pdev-&gt;dev);
&gt;&gt; +       if (error) {
&gt;&gt; +               dev_err(&amp;pdev-&gt;dev, "pm_runtime_set_active() failed\n");
&gt;&gt; +               goto err_unmap;
&gt;&gt; +       }
&gt;&gt; +
&gt;&gt; +       rev = __raw_readl(keypad_data-&gt;base + OMAP4_KBD_REVISION);
&gt;&gt; +       rev &amp;= 0x03 &lt;&lt; 30;
&gt;&gt; +       rev &gt;&gt;= 30;
&gt;&gt; +       switch (rev) {
&gt;&gt; +       case KBD_REVISION_OMAP4:
&gt;&gt; +               keypad_data-&gt;reg_offset = 0x00;
&gt;&gt; +               keypad_data-&gt;irqreg_offset = 0x00;
&gt;&gt; +               break;
&gt;&gt; +       case KBD_REVISION_OMAP5:
&gt;&gt; +               keypad_data-&gt;reg_offset = 0x10;
&gt;&gt; +               keypad_data-&gt;irqreg_offset = 0x0c;
&gt;&gt; +               break;
&gt;&gt; +       default:
&gt;&gt; +               dev_err(&amp;pdev-&gt;dev,
&gt;&gt; +                       "Keypad reports unsupported revision %d", rev);
&gt;&gt; +               error = -EINVAL;
&gt;&gt; +               goto err_pm_suspended;
&gt;&gt; +       }
&gt;&gt; +
&gt;&gt;        /* input device allocation */
&gt;&gt;        keypad_data-&gt;input = input_dev = input_allocate_device();
&gt;&gt;        if (!input_dev) {
&gt;&gt;                error = -ENOMEM;
&gt;&gt; -               goto err_unmap;
&gt;&gt; +               goto err_pm_suspended;
&gt;&gt;        }
&gt;&gt;
&gt;&gt;        input_dev-&gt;name = pdev-&gt;name;
&gt;&gt; @@ -281,6 +345,7 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev)
&gt;&gt;        }
&gt;&gt;
&gt;&gt;        pm_runtime_enable(&amp;pdev-&gt;dev);
&gt;&gt; +       pm_runtime_put_sync(&amp;pdev-&gt;dev);
&gt;&gt;
&gt;&gt;        error = input_register_device(keypad_data-&gt;input);
&gt;&gt;        if (error &lt; 0) {
&gt;&gt; @@ -296,6 +361,8 @@ err_pm_disable:
&gt;&gt;        free_irq(keypad_data-&gt;irq, keypad_data);
&gt;&gt;  err_free_input:
&gt;&gt;        input_free_device(input_dev);
&gt;&gt; +err_pm_suspended:
&gt;&gt; +       pm_runtime_set_suspended(&amp;pdev-&gt;dev);
&gt;&gt;  err_unmap:
&gt;&gt;        iounmap(keypad_data-&gt;base);
&gt;&gt;  err_release_mem:

From: G, Manjunath Kondaiah &lt;manjugk@ti.com&gt;
Date: Mon, 10 Oct 2011 20:52:05 +0530
Subject: [PATCH] Input: omap-keypad: dynamically handle register offsets

Keypad controller register offsets are different for omap4
and omap5. Handle these offsets through static mapping and
assign these mappings during run time.

Tested on omap4430 sdp with 3.4-rc3.
Tested on omap5430evm with 3.1-custom kernel.

Cc: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Felipe Balbi &lt;balbi@ti.com&gt;
Signed-off-by: G, Manjunath Kondaiah &lt;manjugk@ti.com&gt;
Signed-off-by: Sourav Poddar &lt;sourav.poddar@ti.com&gt;
Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Input: add support for LM8333 keypads</title>
<updated>2012-04-04T16:25:39+00:00</updated>
<author>
<name>Wolfram Sang</name>
<email>w.sang@pengutronix.de</email>
</author>
<published>2012-04-03T20:39:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=0bf25a45386f284d591530ef174eaa9e44d84956'/>
<id>0bf25a45386f284d591530ef174eaa9e44d84956</id>
<content type='text'>
This driver adds support for the keypad part of the LM8333 and is
prepared for possible GPIO/PWM drivers. Note that this is not a MFD
because you cannot disable the keypad functionality which, thus,
has to be handled by the core anyhow.

Signed-off-by: Wolfram Sang &lt;w.sang@pengutronix.de&gt;
Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This driver adds support for the keypad part of the LM8333 and is
prepared for possible GPIO/PWM drivers. Note that this is not a MFD
because you cannot disable the keypad functionality which, thus,
has to be handled by the core anyhow.

Signed-off-by: Wolfram Sang &lt;w.sang@pengutronix.de&gt;
Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Input: omap4-keypad - move platform_data to &lt;linux/platform_data&gt;</title>
<updated>2012-03-17T05:49:46+00:00</updated>
<author>
<name>Felipe Balbi</name>
<email>balbi@ti.com</email>
</author>
<published>2012-03-17T05:47:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=0f1142a514e101076bc01de2f93b242693d0f16f'/>
<id>0f1142a514e101076bc01de2f93b242693d0f16f</id>
<content type='text'>
This patch allows us to drop the OMAP dependency from the OMAP4 keypad
driver.

Signed-off-by: Felipe Balbi &lt;balbi@ti.com&gt;
Signed-off-by: Sourav Poddar &lt;sourav.poddar@ti.com&gt;
Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This patch allows us to drop the OMAP dependency from the OMAP4 keypad
driver.

Signed-off-by: Felipe Balbi &lt;balbi@ti.com&gt;
Signed-off-by: Sourav Poddar &lt;sourav.poddar@ti.com&gt;
Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Input: of_keymap - add device tree bindings for simple key matrices</title>
<updated>2012-03-14T04:37:04+00:00</updated>
<author>
<name>Olof Johansson</name>
<email>olof@lixom.net</email>
</author>
<published>2012-03-14T04:35:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=2cd36877ad1c61429e00c099b6903ebcd936ca00'/>
<id>2cd36877ad1c61429e00c099b6903ebcd936ca00</id>
<content type='text'>
This adds a simple device tree binding for simple key matrix data and
a helper to fill in the platform data.

Signed-off-by: Olof Johansson &lt;olof@lixom.net&gt;
Acked-by: Stephen Warren &lt;swarren@nvidia.com&gt;
Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This adds a simple device tree binding for simple key matrix data and
a helper to fill in the platform data.

Signed-off-by: Olof Johansson &lt;olof@lixom.net&gt;
Acked-by: Stephen Warren &lt;swarren@nvidia.com&gt;
Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Input: samsung-keypad - enable compiling on other platforms</title>
<updated>2011-11-15T17:46:14+00:00</updated>
<author>
<name>Dmitry Torokhov</name>
<email>dmitry.torokhov@gmail.com</email>
</author>
<published>2011-11-08T07:59:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=8d964a2872ea0914e00bc7798e68899e01715185'/>
<id>8d964a2872ea0914e00bc7798e68899e01715185</id>
<content type='text'>
There is nothing in keypad platform definitions that requires
the driver be complied on Samsung platform only, so let's move them
out of the platform subdirectory and relax the dependencies.

Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
There is nothing in keypad platform definitions that requires
the driver be complied on Samsung platform only, so let's move them
out of the platform subdirectory and relax the dependencies.

Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Input: tca8418_keypad - initial driver release</title>
<updated>2011-10-29T19:32:24+00:00</updated>
<author>
<name>Kyle Manna</name>
<email>kyle.manna@fuel7.com</email>
</author>
<published>2011-10-29T19:31:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=fb6c721b69d4ac518b9be6de8f44ba87a0c0d235'/>
<id>fb6c721b69d4ac518b9be6de8f44ba87a0c0d235</id>
<content type='text'>
This driver has been tested with hardware and works as expected.  To use
it add the platform data as appropriate and register it with the
corresponding I2C bus.

Signed-off-by: Kyle Manna &lt;kyle.manna@fuel7.com&gt;
Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This driver has been tested with hardware and works as expected.  To use
it add the platform data as appropriate and register it with the
corresponding I2C bus.

Signed-off-by: Kyle Manna &lt;kyle.manna@fuel7.com&gt;
Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Input: adp5589-keys - add support for the ADP5585 derivatives</title>
<updated>2011-10-19T04:26:55+00:00</updated>
<author>
<name>Michael Hennerich</name>
<email>michael.hennerich@analog.com</email>
</author>
<published>2011-10-19T04:12:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=3f48e7354358519e5b93f7f755ec270b3f8eafa0'/>
<id>3f48e7354358519e5b93f7f755ec270b3f8eafa0</id>
<content type='text'>
The ADP5585 family keypad decoder and IO expander is similar to the ADP5589,
however it features less IO pins, and lacks hardware assisted key-lock
functionality. Unfortunately the register addresses are different, as well as
the event codes and bit organization within the port related registers.

Move ADP5589 Register defines from the header file into the main source file.
Add new defines while making sure we don't break existing platform_data.
Add register address translation, and turn device specific defines into variables.
Introduce some helper functions and disable functions that doesn't
exist on the added devices.

Signed-off-by: Michael Hennerich &lt;michael.hennerich@analog.com&gt;
Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The ADP5585 family keypad decoder and IO expander is similar to the ADP5589,
however it features less IO pins, and lacks hardware assisted key-lock
functionality. Unfortunately the register addresses are different, as well as
the event codes and bit organization within the port related registers.

Move ADP5589 Register defines from the header file into the main source file.
Add new defines while making sure we don't break existing platform_data.
Add register address translation, and turn device specific defines into variables.
Introduce some helper functions and disable functions that doesn't
exist on the added devices.

Signed-off-by: Michael Hennerich &lt;michael.hennerich@analog.com&gt;
Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>input: Add Qualcomm pm8xxx keypad controller driver</title>
<updated>2011-05-26T17:45:53+00:00</updated>
<author>
<name>Trilok Soni</name>
<email>tsoni@codeaurora.org</email>
</author>
<published>2011-05-19T05:24:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=39325b59d88b42ba2ccf2e62c234059e9941a47c'/>
<id>39325b59d88b42ba2ccf2e62c234059e9941a47c</id>
<content type='text'>
Add Qualcomm PMIC8XXX based keypad controller driver
supporting upto 18x8 matrix configuration.

Acked-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
Signed-off-by: Trilok Soni &lt;tsoni@codeaurora.org&gt;
Signed-off-by: Anirudh Ghayal &lt;aghayal@codeaurora.org&gt;
Signed-off-by: Samuel Ortiz &lt;sameo@linux.intel.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Add Qualcomm PMIC8XXX based keypad controller driver
supporting upto 18x8 matrix configuration.

Acked-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
Signed-off-by: Trilok Soni &lt;tsoni@codeaurora.org&gt;
Signed-off-by: Anirudh Ghayal &lt;aghayal@codeaurora.org&gt;
Signed-off-by: Samuel Ortiz &lt;sameo@linux.intel.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Input: ADP5589 - new driver for I2C Keypad Decoder and I/O Expander</title>
<updated>2011-05-19T07:59:55+00:00</updated>
<author>
<name>Michael Hennerich</name>
<email>michael.hennerich@analog.com</email>
</author>
<published>2011-05-19T07:59:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=9d2e173644bb5c42ff1b280fbdda3f195a7cf1f7'/>
<id>9d2e173644bb5c42ff1b280fbdda3f195a7cf1f7</id>
<content type='text'>
From http://www.analog.com/ADP5589:
The ADP5589 is an I/O port expander and keypad matrix decoder designed
for QWERTY type phones that require a large keypad matrix and expanded
I/O lines.

Signed-off-by: Michael Hennerich &lt;michael.hennerich@analog.com&gt;
Signed-off-by: Mike Frysinger &lt;vapier@gentoo.org&gt;
Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
From http://www.analog.com/ADP5589:
The ADP5589 is an I/O port expander and keypad matrix decoder designed
for QWERTY type phones that require a large keypad matrix and expanded
I/O lines.

Signed-off-by: Michael Hennerich &lt;michael.hennerich@analog.com&gt;
Signed-off-by: Mike Frysinger &lt;vapier@gentoo.org&gt;
Signed-off-by: Dmitry Torokhov &lt;dtor@mail.ru&gt;
</pre>
</div>
</content>
</entry>
</feed>
