]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-next' of git://github.com/rydberg/linux into next
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Fri, 28 Jun 2013 06:00:25 +0000 (23:00 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Fri, 28 Jun 2013 06:00:25 +0000 (23:00 -0700)
Pull in changes from Henrik: "a trivial MT documentation fix".

79 files changed:
Documentation/devicetree/bindings/input/pxa27x-keypad.txt [new file with mode: 0644]
Documentation/devicetree/bindings/input/ti,nspire-keypad.txt [new file with mode: 0644]
arch/arm/mach-mmp/aspenite.c
arch/arm/mach-mmp/teton_bga.c
arch/arm/mach-pxa/em-x270.c
arch/arm/mach-pxa/ezx.c
arch/arm/mach-pxa/littleton.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/mioa701.c
arch/arm/mach-pxa/palmld.c
arch/arm/mach-pxa/palmt5.c
arch/arm/mach-pxa/palmtreo.c
arch/arm/mach-pxa/palmtx.c
arch/arm/mach-pxa/palmz72.c
arch/arm/mach-pxa/tavorevb.c
arch/arm/mach-pxa/z2.c
arch/arm/mach-pxa/zylonite.c
drivers/input/evdev.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/Makefile
drivers/input/keyboard/amikbd.c
drivers/input/keyboard/bf54x-keys.c
drivers/input/keyboard/davinci_keyscan.c
drivers/input/keyboard/ep93xx_keypad.c
drivers/input/keyboard/gpio_keys.c
drivers/input/keyboard/gpio_keys_polled.c
drivers/input/keyboard/jornada680_kbd.c
drivers/input/keyboard/jornada720_kbd.c
drivers/input/keyboard/matrix_keypad.c
drivers/input/keyboard/nspire-keypad.c [new file with mode: 0644]
drivers/input/keyboard/omap4-keypad.c
drivers/input/keyboard/opencores-kbd.c
drivers/input/keyboard/pmic8xxx-keypad.c
drivers/input/keyboard/pxa27x_keypad.c
drivers/input/keyboard/pxa930_rotary.c
drivers/input/keyboard/samsung-keypad.c
drivers/input/keyboard/sh_keysc.c
drivers/input/keyboard/spear-keyboard.c
drivers/input/keyboard/tnetv107x-keypad.c
drivers/input/keyboard/twl4030_keypad.c
drivers/input/keyboard/w90p910_keypad.c
drivers/input/misc/Kconfig
drivers/input/misc/Makefile
drivers/input/misc/ab8500-ponkey.c
drivers/input/misc/bfin_rotary.c
drivers/input/misc/gpio_tilt_polled.c
drivers/input/misc/ixp4xx-beeper.c
drivers/input/misc/m68kspkr.c
drivers/input/misc/max8925_onkey.c
drivers/input/misc/mc13783-pwrbutton.c
drivers/input/misc/pcspkr.c
drivers/input/misc/pm8xxx-vibrator.c
drivers/input/misc/pmic8xxx-pwrkey.c
drivers/input/misc/pwm-beeper.c
drivers/input/misc/rotary_encoder.c
drivers/input/misc/sgi_btns.c
drivers/input/misc/sirfsoc-onkey.c [new file with mode: 0644]
drivers/input/misc/sparcspkr.c
drivers/input/mouse/amimouse.c
drivers/input/mouse/gpio_mouse.c
drivers/input/mouse/navpoint.c
drivers/input/serio/altera_ps2.c
drivers/input/serio/at32psif.c
drivers/input/serio/q40kbd.c
drivers/input/serio/xilinx_ps2.c
drivers/input/touchscreen/88pm860x-ts.c
drivers/input/touchscreen/atmel-wm97xx.c
drivers/input/touchscreen/atmel_tsadcc.c
drivers/input/touchscreen/da9052_tsi.c
drivers/input/touchscreen/egalax_ts.c
drivers/input/touchscreen/intel-mid-touch.c
drivers/input/touchscreen/jornada720_ts.c
drivers/input/touchscreen/mc13783_ts.c
drivers/input/touchscreen/ti_am335x_tsc.c
drivers/input/touchscreen/tnetv107x-ts.c
drivers/input/touchscreen/w90p910_ts.c
drivers/input/touchscreen/wacom_i2c.c
drivers/tty/sysrq.c
include/linux/platform_data/keypad-pxa27x.h

diff --git a/Documentation/devicetree/bindings/input/pxa27x-keypad.txt b/Documentation/devicetree/bindings/input/pxa27x-keypad.txt
new file mode 100644 (file)
index 0000000..f8674f7
--- /dev/null
@@ -0,0 +1,60 @@
+* Marvell PXA Keypad controller
+
+Required Properties
+- compatible : should be "marvell,pxa27x-keypad"
+- reg : Address and length of the register set for the device
+- interrupts : The interrupt for the keypad controller
+- marvell,debounce-interval : How long time the key will be
+  recognized when it is pressed. It is a u32 value, and bit[31:16]
+  is debounce interval for direct key and bit[15:0] is debounce
+  interval for matrix key. The value is in binary number of 2ms
+
+Optional Properties For Matrix Keyes
+Please refer to matrix-keymap.txt
+
+Optional Properties for Direct Keyes
+- marvell,direct-key-count : How many direct keyes are used.
+- marvell,direct-key-mask : The mask indicates which keyes
+  are used. If bit[X] of the mask is set, the direct key X
+  is used.
+- marvell,direct-key-low-active : Direct key status register
+  tells the level of pins that connects to the direct keyes.
+  When this property is set, it means that when the pin level
+  is low, the key is pressed(active).
+- marvell,direct-key-map : It is a u16 array. Each item indicates
+  the linux key-code for the direct key.
+
+Optional Properties For Rotary
+- marvell,rotary0 : It is a u32 value. Bit[31:16] is the
+  linux key-code for rotary up. Bit[15:0] is the linux key-code
+  for rotary down. It is for rotary 0.
+- marvell,rotary1 : Same as marvell,rotary0. It is for rotary 1.
+- marvell,rotary-rel-key : When rotary is used for relative axes
+  in the device, the value indicates the key-code for relative
+  axes measurement in the device. It is a u32 value. Bit[31:16]
+  is for rotary 1, and Bit[15:0] is for rotary 0.
+
+Examples:
+       keypad: keypad@d4012000 {
+               keypad,num-rows = <3>;
+               keypad,num-columns = <5>;
+               linux,keymap = <0x0000000e      /* KEY_BACKSPACE */
+                               0x0001006b      /* KEY_END */
+                               0x00020061      /* KEY_RIGHTCTRL */
+                               0x0003000b      /* KEY_0 */
+                               0x00040002      /* KEY_1 */
+                               0x0100008b      /* KEY_MENU */
+                               0x01010066      /* KEY_HOME */
+                               0x010200e7      /* KEY_SEND */
+                               0x01030009      /* KEY_8 */
+                               0x0104000a      /* KEY_9 */
+                               0x02000160      /* KEY_OK */
+                               0x02010003      /* KEY_2 */
+                               0x02020004      /* KEY_3 */
+                               0x02030005      /* KEY_4 */
+                               0x02040006>;    /* KEY_5 */
+               marvell,rotary0 = <0x006c0067>; /* KEY_UP & KEY_DOWN */
+               marvell,direct-key-count = <1>;
+               marvell,direct-key-map = <0x001c>;
+               marvell,debounce-interval = <0x001e001e>;
+       };
diff --git a/Documentation/devicetree/bindings/input/ti,nspire-keypad.txt b/Documentation/devicetree/bindings/input/ti,nspire-keypad.txt
new file mode 100644 (file)
index 0000000..513d94d
--- /dev/null
@@ -0,0 +1,60 @@
+TI-NSPIRE Keypad
+
+Required properties:
+- compatible: Compatible property value should be "ti,nspire-keypad".
+
+- reg: Physical base address of the peripheral and length of memory mapped
+  region.
+
+- interrupts: The interrupt number for the peripheral.
+
+- scan-interval: How often to scan in us. Based on a APB speed of 33MHz, the
+       maximum and minimum delay time is ~2000us and ~500us respectively
+
+- row-delay: How long to wait before scanning each row.
+
+- clocks: The clock this peripheral is attached to.
+
+- linux,keymap: The keymap to use
+       (see Documentation/devicetree/bindings/input/matrix-keymap.txt)
+
+Optional properties:
+- active-low: Specify that the keypad is active low (i.e. logical low signifies
+       a key press).
+
+Example:
+
+input {
+       compatible = "ti,nspire-keypad";
+       reg = <0x900E0000 0x1000>;
+       interrupts = <16>;
+
+       scan-interval = <1000>;
+       row-delay = <200>;
+
+       clocks = <&apb_pclk>;
+
+       linux,keymap = <
+       0x0000001c      0x0001001c      0x00040039
+       0x0005002c      0x00060015      0x0007000b
+       0x0008000f      0x0100002d      0x01010011
+       0x0102002f      0x01030004      0x01040016
+       0x01050014      0x0106001f      0x01070002
+       0x010a006a      0x02000013      0x02010010
+       0x02020019      0x02030007      0x02040018
+       0x02050031      0x02060032      0x02070005
+       0x02080028      0x0209006c      0x03000026
+       0x03010025      0x03020024      0x0303000a
+       0x03040017      0x03050023      0x03060022
+       0x03070008      0x03080035      0x03090069
+       0x04000021      0x04010012      0x04020020
+       0x0404002e      0x04050030      0x0406001e
+       0x0407000d      0x04080037      0x04090067
+       0x05010038      0x0502000c      0x0503001b
+       0x05040034      0x0505001a      0x05060006
+       0x05080027      0x0509000e      0x050a006f
+       0x0600002b      0x0602004e      0x06030068
+       0x06040003      0x0605006d      0x06060009
+       0x06070001      0x0609000f      0x0708002a
+       0x0709001d      0x070a0033      >;
+};
index 5b660ec09ef52da82afe5b51176cfec4a4f8d4af..0c002099c3a39e60babe8fffff9634322c8015e4 100644 (file)
@@ -210,7 +210,7 @@ struct pxa168fb_mach_info aspenite_lcd_info = {
        .invert_pixclock        = 0,
 };
 
-static unsigned int aspenite_matrix_key_map[] = {
+static const unsigned int aspenite_matrix_key_map[] = {
        KEY(0, 6, KEY_UP),      /* SW 4 */
        KEY(0, 7, KEY_DOWN),    /* SW 5 */
        KEY(1, 6, KEY_LEFT),    /* SW 6 */
@@ -219,11 +219,15 @@ static unsigned int aspenite_matrix_key_map[] = {
        KEY(4, 7, KEY_ESC),     /* SW 9 */
 };
 
+static struct matrix_keymap_data aspenite_matrix_keymap_data = {
+       .keymap                 = aspenite_matrix_key_map,
+       .keymap_size            = ARRAY_SIZE(aspenite_matrix_key_map),
+};
+
 static struct pxa27x_keypad_platform_data aspenite_keypad_info __initdata = {
        .matrix_key_rows        = 5,
        .matrix_key_cols        = 8,
-       .matrix_key_map         = aspenite_matrix_key_map,
-       .matrix_key_map_size    = ARRAY_SIZE(aspenite_matrix_key_map),
+       .matrix_keymap_data     = &aspenite_matrix_keymap_data,
        .debounce_interval      = 30,
 };
 
index e4d95b4c6bb272a427c5e4d6dae3cb7676b11ae9..6aa53fb29d2663c58add1cf9139dd65ed6642eb9 100644 (file)
@@ -61,11 +61,15 @@ static unsigned int teton_bga_matrix_key_map[] = {
        KEY(1, 7, KEY_RIGHT),
 };
 
+static struct matrix_keymap_data teton_bga_matrix_keymap_data = {
+       .keymap                 = teton_bga_matrix_key_map,
+       .keymap_size            = ARRAY_SIZE(teton_bga_matrix_key_map),
+};
+
 static struct pxa27x_keypad_platform_data teton_bga_keypad_info __initdata = {
        .matrix_key_rows        = 2,
        .matrix_key_cols        = 8,
-       .matrix_key_map         = teton_bga_matrix_key_map,
-       .matrix_key_map_size    = ARRAY_SIZE(teton_bga_matrix_key_map),
+       .matrix_keymap_data     = &teton_bga_matrix_keymap_data,
        .debounce_interval      = 30,
 };
 
index 446563a7d1ada5c7654bfc6761f58eacb37caca0..f6726bb4eb954bf1cdaf073b4940269137673916 100644 (file)
@@ -833,21 +833,25 @@ static inline void em_x270_init_ac97(void) {}
 #endif
 
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int em_x270_module_matrix_keys[] = {
+static const unsigned int em_x270_module_matrix_keys[] = {
        KEY(0, 0, KEY_A), KEY(1, 0, KEY_UP), KEY(2, 1, KEY_B),
        KEY(0, 2, KEY_LEFT), KEY(1, 1, KEY_ENTER), KEY(2, 0, KEY_RIGHT),
        KEY(0, 1, KEY_C), KEY(1, 2, KEY_DOWN), KEY(2, 2, KEY_D),
 };
 
+static struct matrix_keymap_data em_x270_matrix_keymap_data = {
+       .keymap                 = em_x270_module_matrix_keys,
+       .keymap_size            = ARRAY_SIZE(em_x270_module_matrix_keys),
+};
+
 struct pxa27x_keypad_platform_data em_x270_module_keypad_info = {
        /* code map for the matrix keys */
        .matrix_key_rows        = 3,
        .matrix_key_cols        = 3,
-       .matrix_key_map         = em_x270_module_matrix_keys,
-       .matrix_key_map_size    = ARRAY_SIZE(em_x270_module_matrix_keys),
+       .matrix_keymap_data     = &em_x270_matrix_keymap_data,
 };
 
-static unsigned int em_x270_exeda_matrix_keys[] = {
+static const unsigned int em_x270_exeda_matrix_keys[] = {
        KEY(0, 0, KEY_RIGHTSHIFT), KEY(0, 1, KEY_RIGHTCTRL),
        KEY(0, 2, KEY_RIGHTALT), KEY(0, 3, KEY_SPACE),
        KEY(0, 4, KEY_LEFTALT), KEY(0, 5, KEY_LEFTCTRL),
@@ -889,12 +893,16 @@ static unsigned int em_x270_exeda_matrix_keys[] = {
        KEY(7, 6, 0), KEY(7, 7, 0),
 };
 
+static struct matrix_keymap_data em_x270_exeda_matrix_keymap_data = {
+       .keymap                 = em_x270_exeda_matrix_keys,
+       .keymap_size            = ARRAY_SIZE(em_x270_exeda_matrix_keys),
+};
+
 struct pxa27x_keypad_platform_data em_x270_exeda_keypad_info = {
        /* code map for the matrix keys */
        .matrix_key_rows        = 8,
        .matrix_key_cols        = 8,
-       .matrix_key_map         = em_x270_exeda_matrix_keys,
-       .matrix_key_map_size    = ARRAY_SIZE(em_x270_exeda_matrix_keys),
+       .matrix_keymap_data     = &em_x270_exeda_matrix_keymap_data,
 };
 
 static void __init em_x270_init_keypad(void)
index dca10709be8f41db70bcd173b02e94a4d91f5d42..fe2eb8394dffe9c289a0a3a2214efc4af24bdb0b 100644 (file)
@@ -392,7 +392,7 @@ static unsigned long e6_pin_config[] __initdata = {
 
 /* KEYPAD */
 #ifdef CONFIG_MACH_EZX_A780
-static unsigned int a780_key_map[] = {
+static const unsigned int a780_key_map[] = {
        KEY(0, 0, KEY_SEND),
        KEY(0, 1, KEY_BACK),
        KEY(0, 2, KEY_END),
@@ -424,11 +424,15 @@ static unsigned int a780_key_map[] = {
        KEY(4, 4, KEY_DOWN),
 };
 
+static struct matrix_keymap_data a780_matrix_keymap_data = {
+       .keymap                 = a780_key_map,
+       .keymap_size            = ARRAY_SIZE(a780_key_map),
+};
+
 static struct pxa27x_keypad_platform_data a780_keypad_platform_data = {
        .matrix_key_rows = 5,
        .matrix_key_cols = 5,
-       .matrix_key_map = a780_key_map,
-       .matrix_key_map_size = ARRAY_SIZE(a780_key_map),
+       .matrix_keymap_data = &a780_matrix_keymap_data,
 
        .direct_key_map = { KEY_CAMERA },
        .direct_key_num = 1,
@@ -438,7 +442,7 @@ static struct pxa27x_keypad_platform_data a780_keypad_platform_data = {
 #endif /* CONFIG_MACH_EZX_A780 */
 
 #ifdef CONFIG_MACH_EZX_E680
-static unsigned int e680_key_map[] = {
+static const unsigned int e680_key_map[] = {
        KEY(0, 0, KEY_UP),
        KEY(0, 1, KEY_RIGHT),
        KEY(0, 2, KEY_RESERVED),
@@ -455,11 +459,15 @@ static unsigned int e680_key_map[] = {
        KEY(2, 3, KEY_KPENTER),
 };
 
+static struct matrix_keymap_data e680_matrix_keymap_data = {
+       .keymap                 = e680_key_map,
+       .keymap_size            = ARRAY_SIZE(e680_key_map),
+};
+
 static struct pxa27x_keypad_platform_data e680_keypad_platform_data = {
        .matrix_key_rows = 3,
        .matrix_key_cols = 4,
-       .matrix_key_map = e680_key_map,
-       .matrix_key_map_size = ARRAY_SIZE(e680_key_map),
+       .matrix_keymap_data = &e680_matrix_keymap_data,
 
        .direct_key_map = {
                KEY_CAMERA,
@@ -476,7 +484,7 @@ static struct pxa27x_keypad_platform_data e680_keypad_platform_data = {
 #endif /* CONFIG_MACH_EZX_E680 */
 
 #ifdef CONFIG_MACH_EZX_A1200
-static unsigned int a1200_key_map[] = {
+static const unsigned int a1200_key_map[] = {
        KEY(0, 0, KEY_RESERVED),
        KEY(0, 1, KEY_RIGHT),
        KEY(0, 2, KEY_PAGEDOWN),
@@ -513,18 +521,22 @@ static unsigned int a1200_key_map[] = {
        KEY(4, 5, KEY_RESERVED),
 };
 
+static struct matrix_keymap_data a1200_matrix_keymap_data = {
+       .keymap                 = a1200_key_map,
+       .keymap_size            = ARRAY_SIZE(a1200_key_map),
+};
+
 static struct pxa27x_keypad_platform_data a1200_keypad_platform_data = {
        .matrix_key_rows = 5,
        .matrix_key_cols = 6,
-       .matrix_key_map = a1200_key_map,
-       .matrix_key_map_size = ARRAY_SIZE(a1200_key_map),
+       .matrix_keymap_data = &a1200_matrix_keymap_data,
 
        .debounce_interval = 30,
 };
 #endif /* CONFIG_MACH_EZX_A1200 */
 
 #ifdef CONFIG_MACH_EZX_E6
-static unsigned int e6_key_map[] = {
+static const unsigned int e6_key_map[] = {
        KEY(0, 0, KEY_RESERVED),
        KEY(0, 1, KEY_RIGHT),
        KEY(0, 2, KEY_PAGEDOWN),
@@ -561,18 +573,22 @@ static unsigned int e6_key_map[] = {
        KEY(4, 5, KEY_PREVIOUSSONG),
 };
 
+static struct matrix_keymap_data e6_keymap_data = {
+       .keymap                 = e6_key_map,
+       .keymap_size            = ARRAY_SIZE(e6_key_map),
+};
+
 static struct pxa27x_keypad_platform_data e6_keypad_platform_data = {
        .matrix_key_rows = 5,
        .matrix_key_cols = 6,
-       .matrix_key_map = e6_key_map,
-       .matrix_key_map_size = ARRAY_SIZE(e6_key_map),
+       .matrix_keymap_data = &e6_keymap_data,
 
        .debounce_interval = 30,
 };
 #endif /* CONFIG_MACH_EZX_E6 */
 
 #ifdef CONFIG_MACH_EZX_A910
-static unsigned int a910_key_map[] = {
+static const unsigned int a910_key_map[] = {
        KEY(0, 0, KEY_NUMERIC_6),
        KEY(0, 1, KEY_RIGHT),
        KEY(0, 2, KEY_PAGEDOWN),
@@ -609,18 +625,22 @@ static unsigned int a910_key_map[] = {
        KEY(4, 5, KEY_RESERVED),
 };
 
+static struct matrix_keymap_data a910_matrix_keymap_data = {
+       .keymap                 = a910_key_map,
+       .keymap_size            = ARRAY_SIZE(a910_key_map),
+};
+
 static struct pxa27x_keypad_platform_data a910_keypad_platform_data = {
        .matrix_key_rows = 5,
        .matrix_key_cols = 6,
-       .matrix_key_map = a910_key_map,
-       .matrix_key_map_size = ARRAY_SIZE(a910_key_map),
+       .matrix_keymap_data = &a910_matrix_keymap_data,
 
        .debounce_interval = 30,
 };
 #endif /* CONFIG_MACH_EZX_A910 */
 
 #ifdef CONFIG_MACH_EZX_E2
-static unsigned int e2_key_map[] = {
+static const unsigned int e2_key_map[] = {
        KEY(0, 0, KEY_NUMERIC_6),
        KEY(0, 1, KEY_RIGHT),
        KEY(0, 2, KEY_NUMERIC_9),
@@ -657,11 +677,15 @@ static unsigned int e2_key_map[] = {
        KEY(4, 5, KEY_RESERVED),
 };
 
+static struct matrix_keymap_data e2_matrix_keymap_data = {
+       .keymap                 = e2_key_map,
+       .keymap_size            = ARRAY_SIZE(e2_key_map),
+};
+
 static struct pxa27x_keypad_platform_data e2_keypad_platform_data = {
        .matrix_key_rows = 5,
        .matrix_key_cols = 6,
-       .matrix_key_map = e2_key_map,
-       .matrix_key_map_size = ARRAY_SIZE(e2_key_map),
+       .matrix_keymap_data = &e2_matrix_keymap_data,
 
        .debounce_interval = 30,
 };
index e848c4607bafa48c8b62ad37052f7937e4e03b08..5d665588c7eba5a75180d7c515d0852ecc55951e 100644 (file)
@@ -222,7 +222,7 @@ static inline void littleton_init_spi(void) {}
 #endif
 
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int littleton_matrix_key_map[] = {
+static const unsigned int littleton_matrix_key_map[] = {
        /* KEY(row, col, key_code) */
        KEY(1, 3, KEY_0), KEY(0, 0, KEY_1), KEY(1, 0, KEY_2), KEY(2, 0, KEY_3),
        KEY(0, 1, KEY_4), KEY(1, 1, KEY_5), KEY(2, 1, KEY_6), KEY(0, 2, KEY_7),
@@ -249,11 +249,15 @@ static unsigned int littleton_matrix_key_map[] = {
        KEY(3, 1, KEY_F23),     /* soft2 */
 };
 
+static struct matrix_keymap_data littleton_matrix_keymap_data = {
+       .keymap                 = littleton_matrix_key_map,
+       .keymap_size            = ARRAY_SIZE(littleton_matrix_key_map),
+};
+
 static struct pxa27x_keypad_platform_data littleton_keypad_info = {
        .matrix_key_rows        = 6,
        .matrix_key_cols        = 5,
-       .matrix_key_map         = littleton_matrix_key_map,
-       .matrix_key_map_size    = ARRAY_SIZE(littleton_matrix_key_map),
+       .matrix_keymap_data     = &littleton_matrix_keymap_data,
 
        .enable_rotary0         = 1,
        .rotary0_up_key         = KEY_UP,
index 7a12c1ba90ff76b02fde8c4474d6d2b42d76b70a..d2c6523183764c2e809076bca2fc527826a209b1 100644 (file)
@@ -498,7 +498,7 @@ static struct pxaohci_platform_data mainstone_ohci_platform_data = {
 };
 
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int mainstone_matrix_keys[] = {
+static const unsigned int mainstone_matrix_keys[] = {
        KEY(0, 0, KEY_A), KEY(1, 0, KEY_B), KEY(2, 0, KEY_C),
        KEY(3, 0, KEY_D), KEY(4, 0, KEY_E), KEY(5, 0, KEY_F),
        KEY(0, 1, KEY_G), KEY(1, 1, KEY_H), KEY(2, 1, KEY_I),
@@ -527,11 +527,15 @@ static unsigned int mainstone_matrix_keys[] = {
        KEY(4, 6, KEY_SELECT),
 };
 
+static struct matrix_keymap_data mainstone_matrix_keymap_data = {
+       .keymap                 = mainstone_matrix_keys,
+       .keymap_size            = ARRAY_SIZE(mainstone_matrix_keys),
+};
+
 struct pxa27x_keypad_platform_data mainstone_keypad_info = {
        .matrix_key_rows        = 6,
        .matrix_key_cols        = 7,
-       .matrix_key_map         = mainstone_matrix_keys,
-       .matrix_key_map_size    = ARRAY_SIZE(mainstone_matrix_keys),
+       .matrix_keymap_data     = &mainstone_matrix_keymap_data,
 
        .enable_rotary0         = 1,
        .rotary0_up_key         = KEY_UP,
index f8979b943cbfa628d03aa56e9bdb90a7208162fa..654b0ac84dea7683b43698c68bc6e0dc84ec18a0 100644 (file)
@@ -222,7 +222,7 @@ static struct pxafb_mach_info mioa701_pxafb_info = {
 /*
  * Keyboard configuration
  */
-static unsigned int mioa701_matrix_keys[] = {
+static const unsigned int mioa701_matrix_keys[] = {
        KEY(0, 0, KEY_UP),
        KEY(0, 1, KEY_RIGHT),
        KEY(0, 2, KEY_MEDIA),
@@ -233,11 +233,16 @@ static unsigned int mioa701_matrix_keys[] = {
        KEY(2, 1, KEY_PHONE),   /* Phone Green key */
        KEY(2, 2, KEY_CAMERA)   /* Camera key */
 };
+
+static struct matrix_keymap_data mioa701_matrix_keymap_data = {
+       .keymap                 = mioa701_matrix_keys,
+       .keymap_size            = ARRAY_SIZE(mioa701_matrix_keys),
+};
+
 static struct pxa27x_keypad_platform_data mioa701_keypad_info = {
        .matrix_key_rows = 3,
        .matrix_key_cols = 3,
-       .matrix_key_map = mioa701_matrix_keys,
-       .matrix_key_map_size = ARRAY_SIZE(mioa701_matrix_keys),
+       .matrix_keymap_data = &mioa701_matrix_keymap_data,
 };
 
 /*
index 909b713e578985444264e71d6bdd9f9e1e26a445..cf210b11ffcc510ac5ebc81e7091b06a05ef9a22 100644 (file)
@@ -173,7 +173,7 @@ static inline void palmld_nor_init(void) {}
  * GPIO keyboard
  ******************************************************************************/
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int palmld_matrix_keys[] = {
+static const unsigned int palmld_matrix_keys[] = {
        KEY(0, 1, KEY_F2),
        KEY(0, 2, KEY_UP),
 
@@ -190,11 +190,15 @@ static unsigned int palmld_matrix_keys[] = {
        KEY(3, 2, KEY_LEFT),
 };
 
+static struct matrix_keymap_data palmld_matrix_keymap_data = {
+       .keymap                 = palmld_matrix_keys,
+       .keymap_size            = ARRAY_SIZE(palmld_matrix_keys),
+};
+
 static struct pxa27x_keypad_platform_data palmld_keypad_platform_data = {
        .matrix_key_rows        = 4,
        .matrix_key_cols        = 3,
-       .matrix_key_map         = palmld_matrix_keys,
-       .matrix_key_map_size    = ARRAY_SIZE(palmld_matrix_keys),
+       .matrix_keymap_data     = &palmld_matrix_keymap_data,
 
        .debounce_interval      = 30,
 };
index 5033fd07968f5cf92d39da046727ca37a9ca1352..3ed9b029428b8291c912816968b0881de8ee48f9 100644 (file)
@@ -108,7 +108,7 @@ static unsigned long palmt5_pin_config[] __initdata = {
  * GPIO keyboard
  ******************************************************************************/
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int palmt5_matrix_keys[] = {
+static const unsigned int palmt5_matrix_keys[] = {
        KEY(0, 0, KEY_POWER),
        KEY(0, 1, KEY_F1),
        KEY(0, 2, KEY_ENTER),
@@ -124,11 +124,15 @@ static unsigned int palmt5_matrix_keys[] = {
        KEY(3, 2, KEY_LEFT),
 };
 
+static struct matrix_keymap_data palmt5_matrix_keymap_data = {
+       .keymap                 = palmt5_matrix_keys,
+       .keymap_size            = ARRAY_SIZE(palmt5_matrix_keys),
+};
+
 static struct pxa27x_keypad_platform_data palmt5_keypad_platform_data = {
        .matrix_key_rows        = 4,
        .matrix_key_cols        = 3,
-       .matrix_key_map         = palmt5_matrix_keys,
-       .matrix_key_map_size    = ARRAY_SIZE(palmt5_matrix_keys),
+       .matrix_keymap_data     = &palmt5_matrix_keymap_data,
 
        .debounce_interval      = 30,
 };
index d82a50b4a8037c77cfbb4dd1a146a3240d6d6a89..d8b937c870de1b26ff814d690f5a4a2a17f72ee7 100644 (file)
@@ -168,7 +168,7 @@ static unsigned long centro685_pin_config[] __initdata = {
  * GPIO keyboard
  ******************************************************************************/
 #if IS_ENABLED(CONFIG_KEYBOARD_PXA27x)
-static unsigned int treo680_matrix_keys[] = {
+static const unsigned int treo680_matrix_keys[] = {
        KEY(0, 0, KEY_F8),              /* Red/Off/Power */
        KEY(0, 1, KEY_LEFT),
        KEY(0, 2, KEY_LEFTCTRL),        /* Alternate */
@@ -227,7 +227,7 @@ static unsigned int treo680_matrix_keys[] = {
        KEY(7, 5, KEY_I),
 };
 
-static unsigned int centro_matrix_keys[] = {
+static const unsigned int centro_matrix_keys[] = {
        KEY(0, 0, KEY_F9),              /* Home */
        KEY(0, 1, KEY_LEFT),
        KEY(0, 2, KEY_LEFTCTRL),        /* Alternate */
@@ -286,11 +286,20 @@ static unsigned int centro_matrix_keys[] = {
        KEY(7, 5, KEY_I),
 };
 
+static struct matrix_keymap_data treo680_matrix_keymap_data = {
+       .keymap                 = treo680_matrix_keys,
+       .keymap_size            = ARRAY_SIZE(treo680_matrix_keys),
+};
+
+static struct matrix_keymap_data centro_matrix_keymap_data = {
+       .keymap                 = centro_matrix_keys,
+       .keymap_size            = ARRAY_SIZE(centro_matrix_keys),
+};
+
 static struct pxa27x_keypad_platform_data treo680_keypad_pdata = {
        .matrix_key_rows        = 8,
        .matrix_key_cols        = 7,
-       .matrix_key_map         = treo680_matrix_keys,
-       .matrix_key_map_size    = ARRAY_SIZE(treo680_matrix_keys),
+       .matrix_keymap_data     = &treo680_matrix_keymap_data,
        .direct_key_map         = { KEY_CONNECT },
        .direct_key_num         = 1,
 
@@ -301,10 +310,8 @@ static void __init palmtreo_kpc_init(void)
 {
        static struct pxa27x_keypad_platform_data *data = &treo680_keypad_pdata;
 
-       if (machine_is_centro()) {
-               data->matrix_key_map = centro_matrix_keys;
-               data->matrix_key_map_size = ARRAY_SIZE(centro_matrix_keys);
-       }
+       if (machine_is_centro())
+               data->matrix_keymap_data = &centro_matrix_keymap_data;
 
        pxa_set_keypad_info(&treo680_keypad_pdata);
 }
index 627c93a7364c186164ee4bdf9b872a038b1d12ba..83f830dd8ad89fc6bdab7efafbde791cfeaf5915 100644 (file)
@@ -176,7 +176,7 @@ static inline void palmtx_nor_init(void) {}
  * GPIO keyboard
  ******************************************************************************/
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int palmtx_matrix_keys[] = {
+static const unsigned int palmtx_matrix_keys[] = {
        KEY(0, 0, KEY_POWER),
        KEY(0, 1, KEY_F1),
        KEY(0, 2, KEY_ENTER),
@@ -192,11 +192,15 @@ static unsigned int palmtx_matrix_keys[] = {
        KEY(3, 2, KEY_LEFT),
 };
 
+static struct matrix_keymap_data palmtx_matrix_keymap_data = {
+       .keymap                 = palmtx_matrix_keys,
+       .keymap_size            = ARRAY_SIZE(palmtx_matrix_keys),
+};
+
 static struct pxa27x_keypad_platform_data palmtx_keypad_platform_data = {
        .matrix_key_rows        = 4,
        .matrix_key_cols        = 3,
-       .matrix_key_map         = palmtx_matrix_keys,
-       .matrix_key_map_size    = ARRAY_SIZE(palmtx_matrix_keys),
+       .matrix_keymap_data     = &palmtx_matrix_keymap_data,
 
        .debounce_interval      = 30,
 };
index 18b7fcd98592669114ce121229783d5193a4bc58..1a35ddf218dad44994213f97a1e288fcb76245e5 100644 (file)
@@ -140,7 +140,7 @@ static unsigned long palmz72_pin_config[] __initdata = {
  * GPIO keyboard
  ******************************************************************************/
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int palmz72_matrix_keys[] = {
+static const unsigned int palmz72_matrix_keys[] = {
        KEY(0, 0, KEY_POWER),
        KEY(0, 1, KEY_F1),
        KEY(0, 2, KEY_ENTER),
@@ -156,11 +156,15 @@ static unsigned int palmz72_matrix_keys[] = {
        KEY(3, 2, KEY_LEFT),
 };
 
+static struct matrix_keymap_data almz72_matrix_keymap_data = {
+       .keymap                 = palmz72_matrix_keys,
+       .keymap_size            = ARRAY_SIZE(palmz72_matrix_keys),
+};
+
 static struct pxa27x_keypad_platform_data palmz72_keypad_platform_data = {
        .matrix_key_rows        = 4,
        .matrix_key_cols        = 3,
-       .matrix_key_map         = palmz72_matrix_keys,
-       .matrix_key_map_size    = ARRAY_SIZE(palmz72_matrix_keys),
+       .matrix_keymap_data     = &almz72_matrix_keymap_data,
 
        .debounce_interval      = 30,
 };
index f55979c09a5fb506984168a39dc1ce6f53aa506d..4680efe553459bd6c98e3d4c771d7633c3a840a1 100644 (file)
@@ -106,7 +106,7 @@ static struct platform_device smc91x_device = {
 };
 
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int tavorevb_matrix_key_map[] = {
+static const unsigned int tavorevb_matrix_key_map[] = {
        /* KEY(row, col, key_code) */
        KEY(0, 4, KEY_A), KEY(0, 5, KEY_B), KEY(0, 6, KEY_C),
        KEY(1, 4, KEY_E), KEY(1, 5, KEY_F), KEY(1, 6, KEY_G),
@@ -147,11 +147,15 @@ static unsigned int tavorevb_matrix_key_map[] = {
        KEY(3, 3, KEY_F23),     /* soft2 */
 };
 
+static struct matrix_keymap_data tavorevb_matrix_keymap_data = {
+       .keymap         = tavorevb_matrix_key_map,
+       .keymap_size    = ARRAY_SIZE(tavorevb_matrix_key_map),
+};
+
 static struct pxa27x_keypad_platform_data tavorevb_keypad_info = {
        .matrix_key_rows        = 7,
        .matrix_key_cols        = 7,
-       .matrix_key_map         = tavorevb_matrix_key_map,
-       .matrix_key_map_size    = ARRAY_SIZE(tavorevb_matrix_key_map),
+       .matrix_keymap_data     = &tavorevb_matrix_keymap_data,
        .debounce_interval      = 30,
 };
 
index 989903a7e467c2451a2594970c87492046f723d4..2513d8f4931f49675dfd8322edd03c2ffbd3ca0f 100644 (file)
@@ -345,7 +345,7 @@ static inline void z2_leds_init(void) {}
  * GPIO keyboard
  ******************************************************************************/
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int z2_matrix_keys[] = {
+static const unsigned int z2_matrix_keys[] = {
        KEY(0, 0, KEY_OPTION),
        KEY(1, 0, KEY_UP),
        KEY(2, 0, KEY_DOWN),
@@ -405,11 +405,15 @@ static unsigned int z2_matrix_keys[] = {
        KEY(5, 7, KEY_DOT),
 };
 
+static struct matrix_keymap_data z2_matrix_keymap_data = {
+       .keymap                 = z2_matrix_keys,
+       .keymap_size            = ARRAY_SIZE(z2_matrix_keys),
+};
+
 static struct pxa27x_keypad_platform_data z2_keypad_platform_data = {
        .matrix_key_rows        = 7,
        .matrix_key_cols        = 8,
-       .matrix_key_map         = z2_matrix_keys,
-       .matrix_key_map_size    = ARRAY_SIZE(z2_matrix_keys),
+       .matrix_keymap_data     = &z2_matrix_keymap_data,
 
        .debounce_interval      = 30,
 };
index 1f00d650ac27088f836473237aaee1113b446cca..36cf7cf95ec1d5d4fe2fd764067b7d640247aa2e 100644 (file)
@@ -263,7 +263,7 @@ static inline void zylonite_init_mmc(void) {}
 #endif
 
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int zylonite_matrix_key_map[] = {
+static const unsigned int zylonite_matrix_key_map[] = {
        /* KEY(row, col, key_code) */
        KEY(0, 0, KEY_A), KEY(0, 1, KEY_B), KEY(0, 2, KEY_C), KEY(0, 5, KEY_D),
        KEY(1, 0, KEY_E), KEY(1, 1, KEY_F), KEY(1, 2, KEY_G), KEY(1, 5, KEY_H),
@@ -306,11 +306,15 @@ static unsigned int zylonite_matrix_key_map[] = {
        KEY(0, 3, KEY_AUX),     /* contact */
 };
 
+static struct matrix_keymap_data zylonite_matrix_keymap_data = {
+       .keymap                 = zylonite_matrix_key_map,
+       .keymap_size            = ARRAY_SIZE(zylonite_matrix_key_map),
+};
+
 static struct pxa27x_keypad_platform_data zylonite_keypad_info = {
        .matrix_key_rows        = 8,
        .matrix_key_cols        = 8,
-       .matrix_key_map         = zylonite_matrix_key_map,
-       .matrix_key_map_size    = ARRAY_SIZE(zylonite_matrix_key_map),
+       .matrix_keymap_data     = &zylonite_matrix_keymap_data,
 
        .enable_rotary0         = 1,
        .rotary0_up_key         = KEY_UP,
index f0f8928b3c8a2902295ccfdf4803b43e00f3a0c9..d2b34fbbc42e78ed6b7a59c7ff2a63a6d32b5bf0 100644 (file)
@@ -52,6 +52,82 @@ struct evdev_client {
        struct input_event buffer[];
 };
 
+/* flush queued events of type @type, caller must hold client->buffer_lock */
+static void __evdev_flush_queue(struct evdev_client *client, unsigned int type)
+{
+       unsigned int i, head, num;
+       unsigned int mask = client->bufsize - 1;
+       bool is_report;
+       struct input_event *ev;
+
+       BUG_ON(type == EV_SYN);
+
+       head = client->tail;
+       client->packet_head = client->tail;
+
+       /* init to 1 so a leading SYN_REPORT will not be dropped */
+       num = 1;
+
+       for (i = client->tail; i != client->head; i = (i + 1) & mask) {
+               ev = &client->buffer[i];
+               is_report = ev->type == EV_SYN && ev->code == SYN_REPORT;
+
+               if (ev->type == type) {
+                       /* drop matched entry */
+                       continue;
+               } else if (is_report && !num) {
+                       /* drop empty SYN_REPORT groups */
+                       continue;
+               } else if (head != i) {
+                       /* move entry to fill the gap */
+                       client->buffer[head].time = ev->time;
+                       client->buffer[head].type = ev->type;
+                       client->buffer[head].code = ev->code;
+                       client->buffer[head].value = ev->value;
+               }
+
+               num++;
+               head = (head + 1) & mask;
+
+               if (is_report) {
+                       num = 0;
+                       client->packet_head = head;
+               }
+       }
+
+       client->head = head;
+}
+
+/* queue SYN_DROPPED event */
+static void evdev_queue_syn_dropped(struct evdev_client *client)
+{
+       unsigned long flags;
+       struct input_event ev;
+       ktime_t time;
+
+       time = ktime_get();
+       if (client->clkid != CLOCK_MONOTONIC)
+               time = ktime_sub(time, ktime_get_monotonic_offset());
+
+       ev.time = ktime_to_timeval(time);
+       ev.type = EV_SYN;
+       ev.code = SYN_DROPPED;
+       ev.value = 0;
+
+       spin_lock_irqsave(&client->buffer_lock, flags);
+
+       client->buffer[client->head++] = ev;
+       client->head &= client->bufsize - 1;
+
+       if (unlikely(client->head == client->tail)) {
+               /* drop queue but keep our SYN_DROPPED event */
+               client->tail = (client->head - 1) & (client->bufsize - 1);
+               client->packet_head = client->tail;
+       }
+
+       spin_unlock_irqrestore(&client->buffer_lock, flags);
+}
+
 static void __pass_event(struct evdev_client *client,
                         const struct input_event *event)
 {
@@ -650,6 +726,51 @@ static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p)
        return input_set_keycode(dev, &ke);
 }
 
+/*
+ * If we transfer state to the user, we should flush all pending events
+ * of the same type from the client's queue. Otherwise, they might end up
+ * with duplicate events, which can screw up client's state tracking.
+ * If bits_to_user fails after flushing the queue, we queue a SYN_DROPPED
+ * event so user-space will notice missing events.
+ *
+ * LOCKING:
+ * We need to take event_lock before buffer_lock to avoid dead-locks. But we
+ * need the even_lock only to guarantee consistent state. We can safely release
+ * it while flushing the queue. This allows input-core to handle filters while
+ * we flush the queue.
+ */
+static int evdev_handle_get_val(struct evdev_client *client,
+                               struct input_dev *dev, unsigned int type,
+                               unsigned long *bits, unsigned int max,
+                               unsigned int size, void __user *p, int compat)
+{
+       int ret;
+       unsigned long *mem;
+
+       mem = kmalloc(sizeof(unsigned long) * max, GFP_KERNEL);
+       if (!mem)
+               return -ENOMEM;
+
+       spin_lock_irq(&dev->event_lock);
+       spin_lock(&client->buffer_lock);
+
+       memcpy(mem, bits, sizeof(unsigned long) * max);
+
+       spin_unlock(&dev->event_lock);
+
+       __evdev_flush_queue(client, type);
+
+       spin_unlock_irq(&client->buffer_lock);
+
+       ret = bits_to_user(mem, max, size, p, compat);
+       if (ret < 0)
+               evdev_queue_syn_dropped(client);
+
+       kfree(mem);
+
+       return ret;
+}
+
 static int evdev_handle_mt_request(struct input_dev *dev,
                                   unsigned int size,
                                   int __user *ip)
@@ -771,16 +892,20 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
                return evdev_handle_mt_request(dev, size, ip);
 
        case EVIOCGKEY(0):
-               return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode);
+               return evdev_handle_get_val(client, dev, EV_KEY, dev->key,
+                                           KEY_MAX, size, p, compat_mode);
 
        case EVIOCGLED(0):
-               return bits_to_user(dev->led, LED_MAX, size, p, compat_mode);
+               return evdev_handle_get_val(client, dev, EV_LED, dev->led,
+                                           LED_MAX, size, p, compat_mode);
 
        case EVIOCGSND(0):
-               return bits_to_user(dev->snd, SND_MAX, size, p, compat_mode);
+               return evdev_handle_get_val(client, dev, EV_SND, dev->snd,
+                                           SND_MAX, size, p, compat_mode);
 
        case EVIOCGSW(0):
-               return bits_to_user(dev->sw, SW_MAX, size, p, compat_mode);
+               return evdev_handle_get_val(client, dev, EV_SW, dev->sw,
+                                           SW_MAX, size, p, compat_mode);
 
        case EVIOCGNAME(0):
                return str_to_user(dev->name, size, p);
index 62a2c0e4cc998774e1c12185b4f04369bbde4d28..77412d8249632d549de2583b66408bbfd946bb33 100644 (file)
@@ -418,6 +418,16 @@ config KEYBOARD_NOMADIK
          To compile this driver as a module, choose M here: the
          module will be called nmk-ske-keypad.
 
+config KEYBOARD_NSPIRE
+       tristate "TI-NSPIRE built-in keyboard"
+       depends on ARCH_NSPIRE && OF
+       select INPUT_MATRIXKMAP
+       help
+         Say Y here if you want to use the built-in keypad on TI-NSPIRE.
+
+         To compile this driver as a module, choose M here: the
+         module will be called nspire-keypad.
+
 config KEYBOARD_TEGRA
        tristate "NVIDIA Tegra internal matrix keyboard controller support"
        depends on ARCH_TEGRA && OF
@@ -441,6 +451,7 @@ config KEYBOARD_OPENCORES
 config KEYBOARD_PXA27x
        tristate "PXA27x/PXA3xx keypad support"
        depends on PXA27x || PXA3xx || ARCH_MMP
+       select INPUT_MATRIXKMAP
        help
          Enable support for PXA27x/PXA3xx keypad controller.
 
index 0c43e8cf8d0ec253b78f68ea175985dba09c9244..a699b617230383510727cc3c4a45611eed1c58d7 100644 (file)
@@ -36,6 +36,7 @@ obj-$(CONFIG_KEYBOARD_MCS)            += mcs_touchkey.o
 obj-$(CONFIG_KEYBOARD_MPR121)          += mpr121_touchkey.o
 obj-$(CONFIG_KEYBOARD_NEWTON)          += newtonkbd.o
 obj-$(CONFIG_KEYBOARD_NOMADIK)         += nomadik-ske-keypad.o
+obj-$(CONFIG_KEYBOARD_NSPIRE)          += nspire-keypad.o
 obj-$(CONFIG_KEYBOARD_OMAP)            += omap-keypad.o
 obj-$(CONFIG_KEYBOARD_OMAP4)           += omap4-keypad.o
 obj-$(CONFIG_KEYBOARD_OPENCORES)       += opencores-kbd.o
index ba0b36f7daeafe1ee4f582e1b4fdd31325f9e42a..096d6067ae1f890fce38033e0c4321a55f5e15f4 100644 (file)
@@ -246,7 +246,6 @@ static int __exit amikbd_remove(struct platform_device *pdev)
 {
        struct input_dev *dev = platform_get_drvdata(pdev);
 
-       platform_set_drvdata(pdev, NULL);
        free_irq(IRQ_AMIGA_CIAA_SP, dev);
        input_unregister_device(dev);
        return 0;
index 20b9fa91fb9e615ac918d020c99ec6e4c1b6aad9..fc88fb48d70d6740ef96f8fdbe9afc32760218c5 100644 (file)
@@ -326,7 +326,6 @@ out0:
        kfree(bf54x_kpad->keycode);
 out:
        kfree(bf54x_kpad);
-       platform_set_drvdata(pdev, NULL);
 
        return error;
 }
@@ -346,7 +345,6 @@ static int bfin_kpad_remove(struct platform_device *pdev)
 
        kfree(bf54x_kpad->keycode);
        kfree(bf54x_kpad);
-       platform_set_drvdata(pdev, NULL);
 
        return 0;
 }
index 829753702b629dba6ae8081d3b6d409846e80919..d15977a8361ea5b007fa19e3a653600252a99cbd 100644 (file)
@@ -314,8 +314,6 @@ static int davinci_ks_remove(struct platform_device *pdev)
        iounmap(davinci_ks->base);
        release_mem_region(davinci_ks->pbase, davinci_ks->base_size);
 
-       platform_set_drvdata(pdev, NULL);
-
        kfree(davinci_ks);
 
        return 0;
index 9857e8fd09871ae279d736254dca89f0cef08c7f..47206bdba4113a54db431d581a62b84da93b28ed 100644 (file)
@@ -329,8 +329,7 @@ static int ep93xx_keypad_probe(struct platform_device *pdev)
        return 0;
 
 failed_free_irq:
-       free_irq(keypad->irq, pdev);
-       platform_set_drvdata(pdev, NULL);
+       free_irq(keypad->irq, keypad);
 failed_free_dev:
        input_free_device(input_dev);
 failed_put_clk:
@@ -351,9 +350,7 @@ static int ep93xx_keypad_remove(struct platform_device *pdev)
        struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
        struct resource *res;
 
-       free_irq(keypad->irq, pdev);
-
-       platform_set_drvdata(pdev, NULL);
+       free_irq(keypad->irq, keypad);
 
        if (keypad->enabled)
                clk_disable(keypad->clk);
index b29ca651a3951e568527e4c7a041f101bba06c3a..440ce32462baefafcabdda55c5c168c27753757c 100644 (file)
@@ -767,7 +767,6 @@ static int gpio_keys_probe(struct platform_device *pdev)
        while (--i >= 0)
                gpio_remove_key(&ddata->data[i]);
 
-       platform_set_drvdata(pdev, NULL);
  fail1:
        input_free_device(input);
        kfree(ddata);
index 21147164874d8592227d92a96a5c97f59e217ca5..cd5ed9e221686625ba2ef92916c155c84732cb81 100644 (file)
@@ -324,7 +324,6 @@ err_free_gpio:
 
 err_free_bdev:
        kfree(bdev);
-       platform_set_drvdata(pdev, NULL);
 
 err_free_pdata:
        /* If we have no platform_data, we allocated pdata dynamically.  */
@@ -355,7 +354,6 @@ static int gpio_keys_polled_remove(struct platform_device *pdev)
                kfree(pdata);
 
        kfree(bdev);
-       platform_set_drvdata(pdev, NULL);
 
        return 0;
 }
index 74e75a6e8debca3a9e5c75df7ca3bccb534fb666..a2a034c25f0b59906b270af4ff88c2af0aee7b52 100644 (file)
@@ -233,7 +233,6 @@ static int jornada680kbd_probe(struct platform_device *pdev)
  failed:
        printk(KERN_ERR "Jornadakbd: failed to register driver, error: %d\n",
                error);
-       platform_set_drvdata(pdev, NULL);
        input_free_polled_device(poll_dev);
        kfree(jornadakbd);
        return error;
@@ -244,7 +243,6 @@ static int jornada680kbd_remove(struct platform_device *pdev)
 {
        struct jornadakbd *jornadakbd = platform_get_drvdata(pdev);
 
-       platform_set_drvdata(pdev, NULL);
        input_unregister_polled_device(jornadakbd->poll_dev);
        input_free_polled_device(jornadakbd->poll_dev);
        kfree(jornadakbd);
index 5ceef636df2f8f345d143833e4059c3b18510776..b0ad457ca9d8ede1a5411e940b3dae7f0c2e57a1 100644 (file)
@@ -146,7 +146,6 @@ static int jornada720_kbd_probe(struct platform_device *pdev)
  fail2:        /* IRQ, DEVICE, MEMORY */
        free_irq(IRQ_GPIO0, pdev);
  fail1:        /* DEVICE, MEMORY */
-       platform_set_drvdata(pdev, NULL);
        input_free_device(input_dev);
        kfree(jornadakbd);
        return err;
@@ -157,7 +156,6 @@ static int jornada720_kbd_remove(struct platform_device *pdev)
        struct jornadakbd *jornadakbd = platform_get_drvdata(pdev);
 
        free_irq(IRQ_GPIO0, pdev);
-       platform_set_drvdata(pdev, NULL);
        input_unregister_device(jornadakbd->input);
        kfree(jornadakbd);
 
index 71d77192ac1ef7a1dfa48317b737493a1ac4cffc..90ff73ace42496a26fbec96081847d4f23fcfae6 100644 (file)
@@ -549,8 +549,6 @@ static int matrix_keypad_remove(struct platform_device *pdev)
        input_unregister_device(keypad->input_dev);
        kfree(keypad);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
diff --git a/drivers/input/keyboard/nspire-keypad.c b/drivers/input/keyboard/nspire-keypad.c
new file mode 100644 (file)
index 0000000..1b0d04c
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ *  Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/input/matrix_keypad.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of.h>
+
+#define KEYPAD_SCAN_MODE       0x00
+#define KEYPAD_CNTL            0x04
+#define KEYPAD_INT             0x08
+#define KEYPAD_INTMSK          0x0C
+
+#define KEYPAD_DATA            0x10
+#define KEYPAD_GPIO            0x30
+
+#define KEYPAD_UNKNOWN_INT     0x40
+#define KEYPAD_UNKNOWN_INT_STS 0x44
+
+#define KEYPAD_BITMASK_COLS    11
+#define KEYPAD_BITMASK_ROWS    8
+
+struct nspire_keypad {
+       void __iomem *reg_base;
+       u32 int_mask;
+
+       struct input_dev *input;
+       struct clk *clk;
+
+       struct matrix_keymap_data *keymap;
+       int row_shift;
+
+       /* Maximum delay estimated assuming 33MHz APB */
+       u32 scan_interval;      /* In microseconds (~2000us max) */
+       u32 row_delay;          /* In microseconds (~500us max) */
+
+       u16 state[KEYPAD_BITMASK_ROWS];
+
+       bool active_low;
+};
+
+static irqreturn_t nspire_keypad_irq(int irq, void *dev_id)
+{
+       struct nspire_keypad *keypad = dev_id;
+       struct input_dev *input = keypad->input;
+       unsigned short *keymap = input->keycode;
+       unsigned int code;
+       int row, col;
+       u32 int_sts;
+       u16 state[8];
+       u16 bits, changed;
+
+       int_sts = readl(keypad->reg_base + KEYPAD_INT) & keypad->int_mask;
+       if (!int_sts)
+               return IRQ_NONE;
+
+       memcpy_fromio(state, keypad->reg_base + KEYPAD_DATA, sizeof(state));
+
+       for (row = 0; row < KEYPAD_BITMASK_ROWS; row++) {
+               bits = state[row];
+               if (keypad->active_low)
+                       bits = ~bits;
+
+               changed = bits ^ keypad->state[row];
+               if (!changed)
+                       continue;
+
+               keypad->state[row] = bits;
+
+               for (col = 0; col < KEYPAD_BITMASK_COLS; col++) {
+                       if (!(changed & (1U << col)))
+                               continue;
+
+                       code = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
+                       input_event(input, EV_MSC, MSC_SCAN, code);
+                       input_report_key(input, keymap[code],
+                                        bits & (1U << col));
+               }
+       }
+
+       input_sync(input);
+
+       writel(0x3, keypad->reg_base + KEYPAD_INT);
+
+       return IRQ_HANDLED;
+}
+
+static int nspire_keypad_chip_init(struct nspire_keypad *keypad)
+{
+       unsigned long val = 0, cycles_per_us, delay_cycles, row_delay_cycles;
+
+       cycles_per_us = (clk_get_rate(keypad->clk) / 1000000);
+       if (cycles_per_us == 0)
+               cycles_per_us = 1;
+
+       delay_cycles = cycles_per_us * keypad->scan_interval;
+       WARN_ON(delay_cycles >= (1 << 16)); /* Overflow */
+       delay_cycles &= 0xffff;
+
+       row_delay_cycles = cycles_per_us * keypad->row_delay;
+       WARN_ON(row_delay_cycles >= (1 << 14)); /* Overflow */
+       row_delay_cycles &= 0x3fff;
+
+       val |= 3 << 0; /* Set scan mode to 3 (continuous scan) */
+       val |= row_delay_cycles << 2; /* Delay between scanning each row */
+       val |= delay_cycles << 16; /* Delay between scans */
+       writel(val, keypad->reg_base + KEYPAD_SCAN_MODE);
+
+       val = (KEYPAD_BITMASK_ROWS & 0xff) | (KEYPAD_BITMASK_COLS & 0xff)<<8;
+       writel(val, keypad->reg_base + KEYPAD_CNTL);
+
+       /* Enable interrupts */
+       keypad->int_mask = 1 << 1;
+       writel(keypad->int_mask, keypad->reg_base + 0xc);
+
+       /* Disable GPIO interrupts to prevent hanging on touchpad */
+       /* Possibly used to detect touchpad events */
+       writel(0, keypad->reg_base + KEYPAD_UNKNOWN_INT);
+       /* Acknowledge existing interrupts */
+       writel(~0, keypad->reg_base + KEYPAD_UNKNOWN_INT_STS);
+
+       return 0;
+}
+
+static int nspire_keypad_open(struct input_dev *input)
+{
+       struct nspire_keypad *keypad = input_get_drvdata(input);
+       int error;
+
+       error = clk_prepare_enable(keypad->clk);
+       if (error)
+               return error;
+
+       error = nspire_keypad_chip_init(keypad);
+       if (error)
+               return error;
+
+       return 0;
+}
+
+static void nspire_keypad_close(struct input_dev *input)
+{
+       struct nspire_keypad *keypad = input_get_drvdata(input);
+
+       clk_disable_unprepare(keypad->clk);
+}
+
+static int nspire_keypad_probe(struct platform_device *pdev)
+{
+       const struct device_node *of_node = pdev->dev.of_node;
+       struct nspire_keypad *keypad;
+       struct input_dev *input;
+       struct resource *res;
+       int irq;
+       int error;
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(&pdev->dev, "failed to get keypad irq\n");
+               return -EINVAL;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "missing platform resources\n");
+               return -EINVAL;
+       }
+
+       keypad = devm_kzalloc(&pdev->dev, sizeof(struct nspire_keypad),
+                             GFP_KERNEL);
+       if (!keypad) {
+               dev_err(&pdev->dev, "failed to allocate keypad memory\n");
+               return -ENOMEM;
+       }
+
+       keypad->row_shift = get_count_order(KEYPAD_BITMASK_COLS);
+
+       error = of_property_read_u32(of_node, "scan-interval",
+                                    &keypad->scan_interval);
+       if (error) {
+               dev_err(&pdev->dev, "failed to get scan-interval\n");
+               return error;
+       }
+
+       error = of_property_read_u32(of_node, "row-delay",
+                                    &keypad->row_delay);
+       if (error) {
+               dev_err(&pdev->dev, "failed to get row-delay\n");
+               return error;
+       }
+
+       keypad->active_low = of_property_read_bool(of_node, "active-low");
+
+       keypad->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(keypad->clk)) {
+               dev_err(&pdev->dev, "unable to get clock\n");
+               return PTR_ERR(keypad->clk);
+       }
+
+       keypad->reg_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(keypad->reg_base)) {
+               dev_err(&pdev->dev, "failed to remap I/O memory\n");
+               return PTR_ERR(keypad->reg_base);
+       }
+
+       keypad->input = input = devm_input_allocate_device(&pdev->dev);
+       if (!input) {
+               dev_err(&pdev->dev, "failed to allocate input device\n");
+               return -ENOMEM;
+       }
+
+       input_set_drvdata(input, keypad);
+
+       input->id.bustype = BUS_HOST;
+       input->name = "nspire-keypad";
+       input->open = nspire_keypad_open;
+       input->close = nspire_keypad_close;
+
+       __set_bit(EV_KEY, input->evbit);
+       __set_bit(EV_REP, input->evbit);
+       input_set_capability(input, EV_MSC, MSC_SCAN);
+
+       error = matrix_keypad_build_keymap(NULL, NULL,
+                                          KEYPAD_BITMASK_ROWS,
+                                          KEYPAD_BITMASK_COLS,
+                                          NULL, input);
+       if (error) {
+               dev_err(&pdev->dev, "building keymap failed\n");
+               return error;
+       }
+
+       error = devm_request_irq(&pdev->dev, irq, nspire_keypad_irq, 0,
+                                "nspire_keypad", keypad);
+       if (error) {
+               dev_err(&pdev->dev, "allocate irq %d failed\n", irq);
+               return error;
+       }
+
+       error = input_register_device(input);
+       if (error) {
+               dev_err(&pdev->dev,
+                       "unable to register input device: %d\n", error);
+               return error;
+       }
+
+       platform_set_drvdata(pdev, keypad);
+
+       dev_dbg(&pdev->dev,
+               "TI-NSPIRE keypad at %pR (scan_interval=%uus, row_delay=%uus%s)\n",
+               res, keypad->row_delay, keypad->scan_interval,
+               keypad->active_low ? ", active_low" : "");
+
+       return 0;
+}
+
+static const struct of_device_id nspire_keypad_dt_match[] = {
+       { .compatible = "ti,nspire-keypad" },
+       { },
+};
+MODULE_DEVICE_TABLE(of, nspire_keypad_dt_match);
+
+static struct platform_driver nspire_keypad_driver = {
+       .driver = {
+               .name = "nspire-keypad",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(nspire_keypad_dt_match),
+       },
+       .probe = nspire_keypad_probe,
+};
+
+module_platform_driver(nspire_keypad_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TI-NSPIRE Keypad Driver");
index 1b289092f4e30915ce9005678f8ca84991435b3b..f4aa53a1fd69bb70f0e680e95688e251f355f1e9 100644 (file)
@@ -419,8 +419,6 @@ static int omap4_keypad_remove(struct platform_device *pdev)
        kfree(keypad_data->keymap);
        kfree(keypad_data);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 7ac5f174c6f76a5507c6873f8ac01eae65abff68..7b9b44158ad1426453c733aae94c774e5dc0eca1 100644 (file)
@@ -151,8 +151,6 @@ static int opencores_kbd_remove(struct platform_device *pdev)
        input_unregister_device(opencores_kbd->input);
        kfree(opencores_kbd);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 74339e139d431c83e553d8e0fcf2a10726b4f40d..2c9f19ac35ea098a4749ded573c20c3f53d7bc34 100644 (file)
@@ -707,7 +707,6 @@ err_gpio_config:
 err_get_irq:
        input_free_device(kp->input);
 err_alloc_device:
-       platform_set_drvdata(pdev, NULL);
        kfree(kp);
        return rc;
 }
@@ -722,7 +721,6 @@ static int pmic8xxx_kp_remove(struct platform_device *pdev)
        input_unregister_device(kp->input);
        kfree(kp);
 
-       platform_set_drvdata(pdev, NULL);
        return 0;
 }
 
index 5330d8fbf6c05a4d4c9e67d0a970beca8c3a076e..134c3b404a54d22a5b7b425c22fc88ea4949cecf 100644 (file)
 #define MAX_KEYPAD_KEYS                (MAX_MATRIX_KEY_NUM + MAX_DIRECT_KEY_NUM)
 
 struct pxa27x_keypad {
-       struct pxa27x_keypad_platform_data *pdata;
+       const struct pxa27x_keypad_platform_data *pdata;
 
        struct clk *clk;
        struct input_dev *input_dev;
@@ -118,25 +118,254 @@ struct pxa27x_keypad {
        unsigned int direct_key_mask;
 };
 
-static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad)
+#ifdef CONFIG_OF
+static int pxa27x_keypad_matrix_key_parse_dt(struct pxa27x_keypad *keypad,
+                               struct pxa27x_keypad_platform_data *pdata)
 {
-       struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
        struct input_dev *input_dev = keypad->input_dev;
-       unsigned short keycode;
+       struct device *dev = input_dev->dev.parent;
+       u32 rows, cols;
+       int error;
+
+       error = matrix_keypad_parse_of_params(dev, &rows, &cols);
+       if (error)
+               return error;
+
+       if (rows > MAX_MATRIX_KEY_ROWS || cols > MAX_MATRIX_KEY_COLS) {
+               dev_err(dev, "rows or cols exceeds maximum value\n");
+               return -EINVAL;
+       }
+
+       pdata->matrix_key_rows = rows;
+       pdata->matrix_key_cols = cols;
+
+       error = matrix_keypad_build_keymap(NULL, NULL,
+                                          pdata->matrix_key_rows,
+                                          pdata->matrix_key_cols,
+                                          keypad->keycodes, input_dev);
+       if (error)
+               return error;
+
+       return 0;
+}
+
+static int pxa27x_keypad_direct_key_parse_dt(struct pxa27x_keypad *keypad,
+                               struct pxa27x_keypad_platform_data *pdata)
+{
+       struct input_dev *input_dev = keypad->input_dev;
+       struct device *dev = input_dev->dev.parent;
+       struct device_node *np = dev->of_node;
+       const __be16 *prop;
+       unsigned short code;
+       unsigned int proplen, size;
        int i;
+       int error;
 
-       for (i = 0; i < pdata->matrix_key_map_size; i++) {
-               unsigned int key = pdata->matrix_key_map[i];
-               unsigned int row = KEY_ROW(key);
-               unsigned int col = KEY_COL(key);
-               unsigned int scancode = MATRIX_SCAN_CODE(row, col,
-                                                        MATRIX_ROW_SHIFT);
+       error = of_property_read_u32(np, "marvell,direct-key-count",
+                                    &pdata->direct_key_num);
+       if (error) {
+               /*
+                * If do not have marvel,direct-key-count defined,
+                * it means direct key is not supported.
+                */
+               return error == -EINVAL ? 0 : error;
+       }
 
-               keycode = KEY_VAL(key);
-               keypad->keycodes[scancode] = keycode;
-               __set_bit(keycode, input_dev->keybit);
+       error = of_property_read_u32(np, "marvell,direct-key-mask",
+                                    &pdata->direct_key_mask);
+       if (error) {
+               if (error != -EINVAL)
+                       return error;
+
+               /*
+                * If marvell,direct-key-mask is not defined, driver will use
+                * default value. Default value is set when configure the keypad.
+                */
+               pdata->direct_key_mask = 0;
+       }
+
+       pdata->direct_key_low_active = of_property_read_bool(np,
+                                       "marvell,direct-key-low-active");
+
+       prop = of_get_property(np, "marvell,direct-key-map", &proplen);
+       if (!prop)
+               return -EINVAL;
+
+       if (proplen % sizeof(u16))
+               return -EINVAL;
+
+       size = proplen / sizeof(u16);
+
+       /* Only MAX_DIRECT_KEY_NUM is accepted.*/
+       if (size > MAX_DIRECT_KEY_NUM)
+               return -EINVAL;
+
+       for (i = 0; i < size; i++) {
+               code = be16_to_cpup(prop + i);
+               keypad->keycodes[MAX_MATRIX_KEY_NUM + i] = code;
+               __set_bit(code, input_dev->keybit);
+       }
+
+       return 0;
+}
+
+static int pxa27x_keypad_rotary_parse_dt(struct pxa27x_keypad *keypad,
+                               struct pxa27x_keypad_platform_data *pdata)
+{
+       const __be32 *prop;
+       int i, relkey_ret;
+       unsigned int code, proplen;
+       const char *rotaryname[2] = {
+                       "marvell,rotary0", "marvell,rotary1"};
+       const char relkeyname[] = {"marvell,rotary-rel-key"};
+       struct input_dev *input_dev = keypad->input_dev;
+       struct device *dev = input_dev->dev.parent;
+       struct device_node *np = dev->of_node;
+
+       relkey_ret = of_property_read_u32(np, relkeyname, &code);
+       /* if can read correct rotary key-code, we do not need this. */
+       if (relkey_ret == 0) {
+               unsigned short relcode;
+
+               /* rotary0 taks lower half, rotary1 taks upper half. */
+               relcode = code & 0xffff;
+               pdata->rotary0_rel_code = (code & 0xffff);
+               __set_bit(relcode, input_dev->relbit);
+
+               relcode = code >> 16;
+               pdata->rotary1_rel_code = relcode;
+               __set_bit(relcode, input_dev->relbit);
+       }
+
+       for (i = 0; i < 2; i++) {
+               prop = of_get_property(np, rotaryname[i], &proplen);
+               /*
+                * If the prop is not set, it means keypad does not need
+                * initialize the rotaryX.
+                */
+               if (!prop)
+                       continue;
+
+               code = be32_to_cpup(prop);
+               /*
+                * Not all up/down key code are valid.
+                * Now we depends on direct-rel-code.
+                */
+               if ((!(code & 0xffff) || !(code >> 16)) && relkey_ret) {
+                       return relkey_ret;
+               } else {
+                       unsigned int n = MAX_MATRIX_KEY_NUM + (i << 1);
+                       unsigned short keycode;
+
+                       keycode = code & 0xffff;
+                       keypad->keycodes[n] = keycode;
+                       __set_bit(keycode, input_dev->keybit);
+
+                       keycode = code >> 16;
+                       keypad->keycodes[n + 1] = keycode;
+                       __set_bit(keycode, input_dev->keybit);
+
+                       if (i == 0)
+                               pdata->rotary0_rel_code = -1;
+                       else
+                               pdata->rotary1_rel_code = -1;
+               }
+               if (i == 0)
+                       pdata->enable_rotary0 = 1;
+               else
+                       pdata->enable_rotary1 = 1;
+       }
+
+       keypad->rotary_rel_code[0] = pdata->rotary0_rel_code;
+       keypad->rotary_rel_code[1] = pdata->rotary1_rel_code;
+
+       return 0;
+}
+
+static int pxa27x_keypad_build_keycode_from_dt(struct pxa27x_keypad *keypad)
+{
+       struct input_dev *input_dev = keypad->input_dev;
+       struct device *dev = input_dev->dev.parent;
+       struct device_node *np = dev->of_node;
+       struct pxa27x_keypad_platform_data *pdata;
+       int error;
+
+       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata) {
+               dev_err(dev, "failed to allocate memory for pdata\n");
+               return -ENOMEM;
+       }
+
+       error = pxa27x_keypad_matrix_key_parse_dt(keypad, pdata);
+       if (error) {
+               dev_err(dev, "failed to parse matrix key\n");
+               return error;
+       }
+
+       error = pxa27x_keypad_direct_key_parse_dt(keypad, pdata);
+       if (error) {
+               dev_err(dev, "failed to parse direct key\n");
+               return error;
+       }
+
+       error = pxa27x_keypad_rotary_parse_dt(keypad, pdata);
+       if (error) {
+               dev_err(dev, "failed to parse rotary key\n");
+               return error;
+       }
+
+       error = of_property_read_u32(np, "marvell,debounce-interval",
+                                    &pdata->debounce_interval);
+       if (error) {
+               dev_err(dev, "failed to parse debpunce-interval\n");
+               return error;
        }
 
+       /*
+        * The keycodes may not only includes matrix key but also the direct
+        * key or rotary key.
+        */
+       input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes);
+
+       keypad->pdata = pdata;
+       return 0;
+}
+
+#else
+
+static int pxa27x_keypad_build_keycode_from_dt(struct pxa27x_keypad *keypad)
+{
+       dev_info(keypad->input_dev->dev.parent, "missing platform data\n");
+
+       return -EINVAL;
+}
+
+#endif
+
+static int pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad)
+{
+       const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+       struct input_dev *input_dev = keypad->input_dev;
+       const struct matrix_keymap_data *keymap_data =
+                               pdata ? pdata->matrix_keymap_data : NULL;
+       unsigned short keycode;
+       int i;
+       int error;
+
+       error = matrix_keypad_build_keymap(keymap_data, NULL,
+                                          pdata->matrix_key_rows,
+                                          pdata->matrix_key_cols,
+                                          keypad->keycodes, input_dev);
+       if (error)
+               return error;
+
+       /*
+        * The keycodes may not only include matrix keys but also the direct
+        * or rotary keys.
+        */
+       input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes);
+
+       /* For direct keys. */
        for (i = 0; i < pdata->direct_key_num; i++) {
                keycode = pdata->direct_key_map[i];
                keypad->keycodes[MAX_MATRIX_KEY_NUM + i] = keycode;
@@ -178,11 +407,13 @@ static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad)
        }
 
        __clear_bit(KEY_RESERVED, input_dev->keybit);
+
+       return 0;
 }
 
 static void pxa27x_keypad_scan_matrix(struct pxa27x_keypad *keypad)
 {
-       struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+       const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
        struct input_dev *input_dev = keypad->input_dev;
        int row, col, num_keys_pressed = 0;
        uint32_t new_state[MAX_MATRIX_KEY_COLS];
@@ -284,7 +515,7 @@ static void report_rotary_event(struct pxa27x_keypad *keypad, int r, int delta)
 
 static void pxa27x_keypad_scan_rotary(struct pxa27x_keypad *keypad)
 {
-       struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+       const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
        uint32_t kprec;
 
        /* read and reset to default count value */
@@ -300,7 +531,7 @@ static void pxa27x_keypad_scan_rotary(struct pxa27x_keypad *keypad)
 
 static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad)
 {
-       struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+       const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
        struct input_dev *input_dev = keypad->input_dev;
        unsigned int new_state;
        uint32_t kpdk, bits_changed;
@@ -340,7 +571,7 @@ static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad)
 
 static void clear_wakeup_event(struct pxa27x_keypad *keypad)
 {
-       struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+       const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
 
        if (pdata->clear_wakeup_event)
                (pdata->clear_wakeup_event)();
@@ -364,7 +595,7 @@ static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id)
 
 static void pxa27x_keypad_config(struct pxa27x_keypad *keypad)
 {
-       struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+       const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
        unsigned int mask = 0, direct_key_num = 0;
        unsigned long kpc = 0;
 
@@ -431,7 +662,7 @@ static void pxa27x_keypad_close(struct input_dev *dev)
        clk_disable_unprepare(keypad->clk);
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int pxa27x_keypad_suspend(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
@@ -475,25 +706,25 @@ static int pxa27x_keypad_resume(struct device *dev)
 
        return 0;
 }
-
-static const struct dev_pm_ops pxa27x_keypad_pm_ops = {
-       .suspend        = pxa27x_keypad_suspend,
-       .resume         = pxa27x_keypad_resume,
-};
 #endif
 
+static SIMPLE_DEV_PM_OPS(pxa27x_keypad_pm_ops,
+                        pxa27x_keypad_suspend, pxa27x_keypad_resume);
+
+
 static int pxa27x_keypad_probe(struct platform_device *pdev)
 {
-       struct pxa27x_keypad_platform_data *pdata = pdev->dev.platform_data;
+       const struct pxa27x_keypad_platform_data *pdata =
+                                       dev_get_platdata(&pdev->dev);
+       struct device_node *np = pdev->dev.of_node;
        struct pxa27x_keypad *keypad;
        struct input_dev *input_dev;
        struct resource *res;
        int irq, error;
 
-       if (pdata == NULL) {
-               dev_err(&pdev->dev, "no platform data defined\n");
+       /* Driver need build keycode from device tree or pdata */
+       if (!np && !pdata)
                return -EINVAL;
-       }
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
@@ -555,7 +786,14 @@ static int pxa27x_keypad_probe(struct platform_device *pdev)
        input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
        input_set_capability(input_dev, EV_MSC, MSC_SCAN);
 
-       pxa27x_keypad_build_keycode(keypad);
+       if (pdata)
+               error = pxa27x_keypad_build_keycode(keypad);
+       else
+               error = pxa27x_keypad_build_keycode_from_dt(keypad);
+       if (error) {
+               dev_err(&pdev->dev, "failed to build keycode\n");
+               goto failed_put_clk;
+       }
 
        if ((pdata->enable_rotary0 && keypad->rotary_rel_code[0] != -1) ||
            (pdata->enable_rotary1 && keypad->rotary_rel_code[1] != -1)) {
@@ -582,7 +820,7 @@ static int pxa27x_keypad_probe(struct platform_device *pdev)
        return 0;
 
 failed_free_irq:
-       free_irq(irq, pdev);
+       free_irq(irq, keypad);
 failed_put_clk:
        clk_put(keypad->clk);
 failed_free_io:
@@ -600,7 +838,7 @@ static int pxa27x_keypad_remove(struct platform_device *pdev)
        struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
        struct resource *res;
 
-       free_irq(keypad->irq, pdev);
+       free_irq(keypad->irq, keypad);
        clk_put(keypad->clk);
 
        input_unregister_device(keypad->input_dev);
@@ -609,7 +847,6 @@ static int pxa27x_keypad_remove(struct platform_device *pdev)
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        release_mem_region(res->start, resource_size(res));
 
-       platform_set_drvdata(pdev, NULL);
        kfree(keypad);
 
        return 0;
@@ -618,15 +855,22 @@ static int pxa27x_keypad_remove(struct platform_device *pdev)
 /* work with hotplug and coldplug */
 MODULE_ALIAS("platform:pxa27x-keypad");
 
+#ifdef CONFIG_OF
+static const struct of_device_id pxa27x_keypad_dt_match[] = {
+       { .compatible = "marvell,pxa27x-keypad" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, pxa27x_keypad_dt_match);
+#endif
+
 static struct platform_driver pxa27x_keypad_driver = {
        .probe          = pxa27x_keypad_probe,
        .remove         = pxa27x_keypad_remove,
        .driver         = {
                .name   = "pxa27x-keypad",
+               .of_match_table = of_match_ptr(pxa27x_keypad_dt_match),
                .owner  = THIS_MODULE,
-#ifdef CONFIG_PM
                .pm     = &pxa27x_keypad_pm_ops,
-#endif
        },
 };
 module_platform_driver(pxa27x_keypad_driver);
index bcad95be73aaea053eef65168a9cdcea28a350db..248cdcf952965c616b4de79fca4dfe87f79e38b3 100644 (file)
@@ -181,7 +181,6 @@ static int pxa930_rotary_remove(struct platform_device *pdev)
        free_irq(platform_get_irq(pdev, 0), r);
        input_unregister_device(r->input_dev);
        iounmap(r->mmio_base);
-       platform_set_drvdata(pdev, NULL);
        kfree(r);
 
        return 0;
index 22e357b51024ee59668689e8b0d92965d83d4e59..7b938b481bd5626566bba8d3b69a29709a40fd2f 100644 (file)
@@ -487,7 +487,6 @@ static int samsung_keypad_probe(struct platform_device *pdev)
 err_disable_runtime_pm:
        pm_runtime_disable(&pdev->dev);
        device_init_wakeup(&pdev->dev, 0);
-       platform_set_drvdata(pdev, NULL);
 err_unprepare_clk:
        clk_unprepare(keypad->clk);
        return error;
@@ -499,7 +498,6 @@ static int samsung_keypad_remove(struct platform_device *pdev)
 
        pm_runtime_disable(&pdev->dev);
        device_init_wakeup(&pdev->dev, 0);
-       platform_set_drvdata(pdev, NULL);
 
        input_unregister_device(keypad->input_dev);
 
index fdb9eb2df380c4e50e1fe58bb5f33c6d7cc04897..fe0e498d24794e557c5c63f67059103dd105fcca 100644 (file)
@@ -266,7 +266,6 @@ static int sh_keysc_probe(struct platform_device *pdev)
  err2:
        iounmap(priv->iomem_base);
  err1:
-       platform_set_drvdata(pdev, NULL);
        kfree(priv);
  err0:
        return error;
@@ -285,7 +284,6 @@ static int sh_keysc_remove(struct platform_device *pdev)
        pm_runtime_put_sync(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
 
-       platform_set_drvdata(pdev, NULL);
        kfree(priv);
 
        return 0;
index cb1e8f614631582b342546458d9c1fc462b55df7..7111124b53621de7c5de1df601f1d1fba6f8505f 100644 (file)
@@ -290,7 +290,6 @@ static int spear_kbd_remove(struct platform_device *pdev)
        clk_unprepare(kbd->clk);
 
        device_init_wakeup(&pdev->dev, 0);
-       platform_set_drvdata(pdev, NULL);
 
        return 0;
 }
index ee163501129210f0959779978d0aeae5e3ef0271..5f7b427dd7ed06e48b53aa6f0ae6c236af82dcfa 100644 (file)
@@ -296,7 +296,6 @@ error_clk:
 error_map:
        release_mem_region(kp->res->start, resource_size(kp->res));
 error_res:
-       platform_set_drvdata(pdev, NULL);
        kfree(kp);
        return error;
 }
@@ -311,7 +310,6 @@ static int keypad_remove(struct platform_device *pdev)
        clk_put(kp->clk);
        iounmap(kp->regs);
        release_mem_region(kp->res->start, resource_size(kp->res));
-       platform_set_drvdata(pdev, NULL);
        kfree(kp);
 
        return 0;
index 04f84fd57173228671ca77a28cf4a0f12af65907..d2d178c84ea7584467badbfc2a79ba35afbdb726 100644 (file)
@@ -422,7 +422,7 @@ static int twl4030_kp_probe(struct platform_device *pdev)
 err3:
        /* mask all events - we don't care about the result */
        (void) twl4030_kpwrite_u8(kp, 0xff, KEYP_IMR1);
-       free_irq(kp->irq, NULL);
+       free_irq(kp->irq, kp);
 err2:
        input_unregister_device(input);
        input = NULL;
@@ -438,7 +438,6 @@ static int twl4030_kp_remove(struct platform_device *pdev)
 
        free_irq(kp->irq, kp);
        input_unregister_device(kp->input);
-       platform_set_drvdata(pdev, NULL);
        kfree(kp);
 
        return 0;
index ee163bee8cce3c32e2ec3a50181dd4d1c56fafdb..7b039162a3f833485239274e613aad5cd6ad8710 100644 (file)
@@ -221,7 +221,7 @@ static int w90p910_keypad_probe(struct platform_device *pdev)
        return 0;
 
 failed_free_irq:
-       free_irq(irq, pdev);
+       free_irq(irq, keypad);
 failed_put_clk:
        clk_put(keypad->clk);
 failed_free_io:
@@ -239,7 +239,7 @@ static int w90p910_keypad_remove(struct platform_device *pdev)
        struct w90p910_keypad *keypad = platform_get_drvdata(pdev);
        struct resource *res;
 
-       free_irq(keypad->irq, pdev);
+       free_irq(keypad->irq, keypad);
 
        clk_put(keypad->clk);
 
@@ -249,7 +249,6 @@ static int w90p910_keypad_remove(struct platform_device *pdev)
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        release_mem_region(res->start, resource_size(res));
 
-       platform_set_drvdata(pdev, NULL);
        kfree(keypad);
 
        return 0;
index bb698e1f9e429b1c5d6dee2b59f0603807918d84..0b541cdf9b8e69f238c2f7fcd5eadebe644ec3e3 100644 (file)
@@ -637,4 +637,14 @@ config INPUT_XEN_KBDDEV_FRONTEND
          To compile this driver as a module, choose M here: the
          module will be called xen-kbdfront.
 
+config INPUT_SIRFSOC_ONKEY
+       bool "CSR SiRFSoC power on/off/suspend key support"
+       depends on ARCH_SIRF && OF
+       default y
+       help
+         Say Y here if you want to support for the SiRFSoC power on/off/suspend key
+         in Linux, after you press the onkey, system will suspend.
+
+         If unsure, say N.
+
 endif
index d7fc17f11d77aa70fdac018aa146e126d1e65e8c..829de43a2427933b72bbef8e32ed5a4072ff8e4a 100644 (file)
@@ -51,6 +51,7 @@ obj-$(CONFIG_INPUT_RB532_BUTTON)      += rb532_button.o
 obj-$(CONFIG_INPUT_RETU_PWRBUTTON)     += retu-pwrbutton.o
 obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)        += rotary_encoder.o
 obj-$(CONFIG_INPUT_SGI_BTNS)           += sgi_btns.o
+obj-$(CONFIG_INPUT_SIRFSOC_ONKEY)      += sirfsoc-onkey.o
 obj-$(CONFIG_INPUT_SPARCSPKR)          += sparcspkr.o
 obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON)  += twl4030-pwrbutton.o
 obj-$(CONFIG_INPUT_TWL4030_VIBRA)      += twl4030-vibra.o
index 2f090b46e71646e1635e54264e4fb5ad54933e0f..f2fbdd88ed20a03830ba10244d0ef20b810d922f 100644 (file)
@@ -127,8 +127,6 @@ static int ab8500_ponkey_remove(struct platform_device *pdev)
        input_unregister_device(ponkey->idev);
        kfree(ponkey);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index a6666e142a91b04719efcc4f7721a66df06cad23..cd139cb17e326dd6a740db877a2b85ef18344963 100644 (file)
@@ -208,7 +208,6 @@ static int bfin_rotary_remove(struct platform_device *pdev)
        peripheral_free_list(per_cnt);
 
        kfree(rotary);
-       platform_set_drvdata(pdev, NULL);
 
        return 0;
 }
index da05cca8b5622a3576be39b44149ca3cb02ebf11..714c68369134be4939b166421c0dcd5fbd38eeb8 100644 (file)
@@ -184,8 +184,6 @@ static int gpio_tilt_polled_remove(struct platform_device *pdev)
        struct gpio_tilt_polled_dev *tdev = platform_get_drvdata(pdev);
        const struct gpio_tilt_platform_data *pdata = tdev->pdata;
 
-       platform_set_drvdata(pdev, NULL);
-
        input_unregister_polled_device(tdev->poll_dev);
        input_free_polled_device(tdev->poll_dev);
 
index 6ab3decc86e6f15ce11fca3c3d0da3355aa66ef7..f34beb228d3689e055fb1c39ecc5fe41509f9fe8 100644 (file)
@@ -125,7 +125,7 @@ static int ixp4xx_spkr_probe(struct platform_device *dev)
        return 0;
 
  err_free_irq:
-       free_irq(IRQ_IXP4XX_TIMER2, dev);
+       free_irq(IRQ_IXP4XX_TIMER2, (void *)dev->id);
  err_free_device:
        input_free_device(input_dev);
 
@@ -138,13 +138,12 @@ static int ixp4xx_spkr_remove(struct platform_device *dev)
        unsigned int pin = (unsigned int) input_get_drvdata(input_dev);
 
        input_unregister_device(input_dev);
-       platform_set_drvdata(dev, NULL);
 
        /* turn the speaker off */
        disable_irq(IRQ_IXP4XX_TIMER2);
        ixp4xx_spkr_control(pin, 0);
 
-       free_irq(IRQ_IXP4XX_TIMER2, dev);
+       free_irq(IRQ_IXP4XX_TIMER2, (void *)dev->id);
 
        return 0;
 }
index b40ee4b47f4ffdfb18dbfad13771b73307c4dd28..def21dc84522c1d5ee0c0a842693d9dc4417a8d0 100644 (file)
@@ -85,7 +85,6 @@ static int m68kspkr_remove(struct platform_device *dev)
        struct input_dev *input_dev = platform_get_drvdata(dev);
 
        input_unregister_device(input_dev);
-       platform_set_drvdata(dev, NULL);
        /* turn off the speaker */
        m68kspkr_event(NULL, EV_SND, SND_BELL, 0);
 
index f9179b2585a90e5b80f0715da13dbfefdec1cece..eef41cfc054da0833a4767501ad229c93311c21f 100644 (file)
@@ -148,8 +148,6 @@ static int max8925_onkey_remove(struct platform_device *pdev)
        input_unregister_device(info->idev);
        kfree(info);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 0906ca593d5f3a90b751f23ace4380269fdabd7b..d0277a7b1579ffdb891135bc71b8c55bf35f723a 100644 (file)
@@ -250,7 +250,6 @@ static int mc13783_pwrbutton_remove(struct platform_device *pdev)
 
        input_unregister_device(priv->pwr);
        kfree(priv);
-       platform_set_drvdata(pdev, NULL);
 
        return 0;
 }
index 199db78acc4fa152494929efbf1e8c40e522ca99..7288b267613d3177829593b43c6927b6121d445f 100644 (file)
@@ -100,7 +100,6 @@ static int pcspkr_remove(struct platform_device *dev)
        struct input_dev *pcspkr_dev = platform_get_drvdata(dev);
 
        input_unregister_device(pcspkr_dev);
-       platform_set_drvdata(dev, NULL);
        /* turn off the speaker */
        pcspkr_event(NULL, EV_SND, SND_BELL, 0);
 
index a9da65e41c5b6773c3301ef93a7367b5bb5d19a6..ec086f6f3cc3e9f4efb38466580169a389f61a36 100644 (file)
@@ -249,8 +249,6 @@ static int pm8xxx_vib_remove(struct platform_device *pdev)
        input_unregister_device(vib->vib_input_dev);
        kfree(vib);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 4b811be739742fc6d29a2a0290de8b951a334f0d..b49b738aa9c69c5eb62207bc69b518b4fbe18af0 100644 (file)
@@ -175,9 +175,8 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev)
        return 0;
 
 free_press_irq:
-       free_irq(key_press_irq, NULL);
+       free_irq(key_press_irq, pwrkey);
 unreg_input_dev:
-       platform_set_drvdata(pdev, NULL);
        input_unregister_device(pwr);
        pwr = NULL;
 free_input_dev:
@@ -198,7 +197,6 @@ static int pmic8xxx_pwrkey_remove(struct platform_device *pdev)
        free_irq(key_press_irq, pwrkey);
        free_irq(key_release_irq, pwrkey);
        input_unregister_device(pwrkey->pwr);
-       platform_set_drvdata(pdev, NULL);
        kfree(pwrkey);
 
        return 0;
index 0808868461de0d4bfc1fc67ac5b4d5e377d23ce3..a37f0c909aba7ad34ce95eaa9c23f3bdedd96b4b 100644 (file)
@@ -133,7 +133,6 @@ static int pwm_beeper_remove(struct platform_device *pdev)
 {
        struct pwm_beeper *beeper = platform_get_drvdata(pdev);
 
-       platform_set_drvdata(pdev, NULL);
        input_unregister_device(beeper->input);
 
        pwm_disable(beeper->pwm);
index aff47b2c38ff8d2daea9747b7cbdbadc6d739af3..5b1aff825138a1b9db5d2b216f7389168bb7bf9f 100644 (file)
@@ -317,8 +317,6 @@ static int rotary_encoder_remove(struct platform_device *pdev)
        if (!dev_get_platdata(&pdev->dev))
                kfree(pdata);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index ad6415ceaf5f7c7efcefca4abd44e63cfd588b6c..95cf299ef9a308a12b09d7e3c6ea9f7903928abd 100644 (file)
@@ -128,7 +128,7 @@ static int sgi_buttons_probe(struct platform_device *pdev)
        __clear_bit(KEY_RESERVED, input->keybit);
 
        bdev->poll_dev = poll_dev;
-       dev_set_drvdata(&pdev->dev, bdev);
+       platform_set_drvdata(pdev, bdev);
 
        error = input_register_polled_device(poll_dev);
        if (error)
@@ -139,19 +139,16 @@ static int sgi_buttons_probe(struct platform_device *pdev)
  err_free_mem:
        input_free_polled_device(poll_dev);
        kfree(bdev);
-       dev_set_drvdata(&pdev->dev, NULL);
        return error;
 }
 
 static int sgi_buttons_remove(struct platform_device *pdev)
 {
-       struct device *dev = &pdev->dev;
-       struct buttons_dev *bdev = dev_get_drvdata(dev);
+       struct buttons_dev *bdev = platform_get_drvdata(pdev);
 
        input_unregister_polled_device(bdev->poll_dev);
        input_free_polled_device(bdev->poll_dev);
        kfree(bdev);
-       dev_set_drvdata(dev, NULL);
 
        return 0;
 }
diff --git a/drivers/input/misc/sirfsoc-onkey.c b/drivers/input/misc/sirfsoc-onkey.c
new file mode 100644 (file)
index 0000000..0621c36
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Power key driver for SiRF PrimaII
+ *
+ * Copyright (c) 2013 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/rtc/sirfsoc_rtciobrg.h>
+#include <linux/of.h>
+
+struct sirfsoc_pwrc_drvdata {
+       u32                     pwrc_base;
+       struct input_dev        *input;
+};
+
+#define PWRC_ON_KEY_BIT                        (1 << 0)
+
+#define PWRC_INT_STATUS                        0xc
+#define PWRC_INT_MASK                  0x10
+
+static irqreturn_t sirfsoc_pwrc_isr(int irq, void *dev_id)
+{
+       struct sirfsoc_pwrc_drvdata *pwrcdrv = dev_id;
+       u32 int_status;
+
+       int_status = sirfsoc_rtc_iobrg_readl(pwrcdrv->pwrc_base +
+                                                       PWRC_INT_STATUS);
+       sirfsoc_rtc_iobrg_writel(int_status & ~PWRC_ON_KEY_BIT,
+                                pwrcdrv->pwrc_base + PWRC_INT_STATUS);
+
+       /*
+        * For a typical Linux system, we report KEY_SUSPEND to trigger apm-power.c
+        * to queue a SUSPEND APM event
+        */
+       input_event(pwrcdrv->input, EV_PWR, KEY_SUSPEND, 1);
+       input_sync(pwrcdrv->input);
+
+       /*
+        * Todo: report KEY_POWER event for Android platforms, Android PowerManager
+        * will handle the suspend and powerdown/hibernation
+        */
+
+       return IRQ_HANDLED;
+}
+
+static const struct of_device_id sirfsoc_pwrc_of_match[] = {
+       { .compatible = "sirf,prima2-pwrc" },
+       {},
+}
+MODULE_DEVICE_TABLE(of, sirfsoc_pwrc_of_match);
+
+static int sirfsoc_pwrc_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct sirfsoc_pwrc_drvdata *pwrcdrv;
+       int irq;
+       int error;
+
+       pwrcdrv = devm_kzalloc(&pdev->dev, sizeof(struct sirfsoc_pwrc_drvdata),
+                              GFP_KERNEL);
+       if (!pwrcdrv) {
+               dev_info(&pdev->dev, "Not enough memory for the device data\n");
+               return -ENOMEM;
+       }
+
+       /*
+        * we can't use of_iomap because pwrc is not mapped in memory,
+        * the so-called base address is only offset in rtciobrg
+        */
+       error = of_property_read_u32(np, "reg", &pwrcdrv->pwrc_base);
+       if (error) {
+               dev_err(&pdev->dev,
+                       "unable to find base address of pwrc node in dtb\n");
+               return error;
+       }
+
+       pwrcdrv->input = devm_input_allocate_device(&pdev->dev);
+       if (!pwrcdrv->input)
+               return -ENOMEM;
+
+       pwrcdrv->input->name = "sirfsoc pwrckey";
+       pwrcdrv->input->phys = "pwrc/input0";
+       pwrcdrv->input->evbit[0] = BIT_MASK(EV_PWR);
+
+       irq = platform_get_irq(pdev, 0);
+       error = devm_request_irq(&pdev->dev, irq,
+                                sirfsoc_pwrc_isr, IRQF_SHARED,
+                                "sirfsoc_pwrc_int", pwrcdrv);
+       if (error) {
+               dev_err(&pdev->dev, "unable to claim irq %d, error: %d\n",
+                       irq, error);
+               return error;
+       }
+
+       sirfsoc_rtc_iobrg_writel(
+               sirfsoc_rtc_iobrg_readl(pwrcdrv->pwrc_base + PWRC_INT_MASK) |
+                       PWRC_ON_KEY_BIT,
+               pwrcdrv->pwrc_base + PWRC_INT_MASK);
+
+       error = input_register_device(pwrcdrv->input);
+       if (error) {
+               dev_err(&pdev->dev,
+                       "unable to register input device, error: %d\n",
+                       error);
+               return error;
+       }
+
+       platform_set_drvdata(pdev, pwrcdrv);
+       device_init_wakeup(&pdev->dev, 1);
+
+       return 0;
+}
+
+static int sirfsoc_pwrc_remove(struct platform_device *pdev)
+{
+       device_init_wakeup(&pdev->dev, 0);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pwrc_resume(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct sirfsoc_pwrc_drvdata *pwrcdrv = platform_get_drvdata(pdev);
+
+       /*
+        * Do not mask pwrc interrupt as we want pwrc work as a wakeup source
+        * if users touch X_ONKEY_B, see arch/arm/mach-prima2/pm.c
+        */
+       sirfsoc_rtc_iobrg_writel(
+               sirfsoc_rtc_iobrg_readl(
+               pwrcdrv->pwrc_base + PWRC_INT_MASK) | PWRC_ON_KEY_BIT,
+               pwrcdrv->pwrc_base + PWRC_INT_MASK);
+
+       return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(sirfsoc_pwrc_pm_ops, NULL, pwrc_resume);
+
+static struct platform_driver sirfsoc_pwrc_driver = {
+       .probe          = sirfsoc_pwrc_probe,
+       .remove         = sirfsoc_pwrc_remove,
+       .driver         = {
+               .name   = "sirfsoc-pwrc",
+               .owner  = THIS_MODULE,
+               .pm     = &sirfsoc_pwrc_pm_ops,
+               .of_match_table = of_match_ptr(sirfsoc_pwrc_of_match),
+       }
+};
+
+module_platform_driver(sirfsoc_pwrc_driver);
+
+MODULE_LICENSE("GPLv2");
+MODULE_AUTHOR("Binghua Duan <Binghua.Duan@csr.com>, Xianglong Du <Xianglong.Du@csr.com>");
+MODULE_DESCRIPTION("CSR Prima2 PWRC Driver");
+MODULE_ALIAS("platform:sirfsoc-pwrc");
index a53586a7fbdb68c9deff6745629e16642ab6aa7d..65fd3150919bee56a00efc310b84764d1f00f00a 100644 (file)
@@ -175,7 +175,7 @@ static int sparcspkr_probe(struct device *dev)
 
 static void sparcspkr_shutdown(struct platform_device *dev)
 {
-       struct sparcspkr_state *state = dev_get_drvdata(&dev->dev);
+       struct sparcspkr_state *state = platform_get_drvdata(dev);
        struct input_dev *input_dev = state->input_dev;
 
        /* turn off the speaker */
@@ -211,7 +211,7 @@ static int bbc_beep_probe(struct platform_device *op)
        if (!info->regs)
                goto out_free;
 
-       dev_set_drvdata(&op->dev, state);
+       platform_set_drvdata(op, state);
 
        err = sparcspkr_probe(&op->dev);
        if (err)
@@ -220,7 +220,6 @@ static int bbc_beep_probe(struct platform_device *op)
        return 0;
 
 out_clear_drvdata:
-       dev_set_drvdata(&op->dev, NULL);
        of_iounmap(&op->resource[0], info->regs, 6);
 
 out_free:
@@ -231,7 +230,7 @@ out_err:
 
 static int bbc_remove(struct platform_device *op)
 {
-       struct sparcspkr_state *state = dev_get_drvdata(&op->dev);
+       struct sparcspkr_state *state = platform_get_drvdata(op);
        struct input_dev *input_dev = state->input_dev;
        struct bbc_beep_info *info = &state->u.bbc;
 
@@ -242,7 +241,6 @@ static int bbc_remove(struct platform_device *op)
 
        of_iounmap(&op->resource[0], info->regs, 6);
 
-       dev_set_drvdata(&op->dev, NULL);
        kfree(state);
 
        return 0;
@@ -290,7 +288,7 @@ static int grover_beep_probe(struct platform_device *op)
        if (!info->enable_reg)
                goto out_unmap_freq_regs;
 
-       dev_set_drvdata(&op->dev, state);
+       platform_set_drvdata(op, state);
 
        err = sparcspkr_probe(&op->dev);
        if (err)
@@ -299,7 +297,6 @@ static int grover_beep_probe(struct platform_device *op)
        return 0;
 
 out_clear_drvdata:
-       dev_set_drvdata(&op->dev, NULL);
        of_iounmap(&op->resource[3], info->enable_reg, 1);
 
 out_unmap_freq_regs:
@@ -312,7 +309,7 @@ out_err:
 
 static int grover_remove(struct platform_device *op)
 {
-       struct sparcspkr_state *state = dev_get_drvdata(&op->dev);
+       struct sparcspkr_state *state = platform_get_drvdata(op);
        struct grover_beep_info *info = &state->u.grover;
        struct input_dev *input_dev = state->input_dev;
 
@@ -324,7 +321,6 @@ static int grover_remove(struct platform_device *op)
        of_iounmap(&op->resource[3], info->enable_reg, 1);
        of_iounmap(&op->resource[2], info->freq_regs, 2);
 
-       dev_set_drvdata(&op->dev, NULL);
        kfree(state);
 
        return 0;
index b55d5af217a777e3a470ad651398c0e7218d11de..62ec52b2e3471e71a6c240ea59f4b962c47f9526 100644 (file)
@@ -133,7 +133,6 @@ static int __exit amimouse_remove(struct platform_device *pdev)
 {
        struct input_dev *dev = platform_get_drvdata(pdev);
 
-       platform_set_drvdata(pdev, NULL);
        input_unregister_device(dev);
        return 0;
 }
index 532eaca4cc56d1452ea75024dd416c7e93032e5e..6b44413f54e357cd9201af5dc011bed845e1377d 100644 (file)
@@ -138,7 +138,6 @@ static int gpio_mouse_probe(struct platform_device *pdev)
 
  out_free_polldev:
        input_free_polled_device(input_poll);
-       platform_set_drvdata(pdev, NULL);
 
  out_free_gpios:
        while (--i >= 0) {
@@ -165,8 +164,6 @@ static int gpio_mouse_remove(struct platform_device *pdev)
                        gpio_free(pin);
        }
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 8e1b98ea56482cc89ffcdb49f386bcef33b94878..0b8d33591dee7e2eed5816753b4c2b636204da29 100644 (file)
@@ -287,7 +287,7 @@ static int navpoint_probe(struct platform_device *pdev)
        return 0;
 
 err_free_irq:
-       free_irq(ssp->irq, &pdev->dev);
+       free_irq(ssp->irq, navpoint);
 err_free_mem:
        input_free_device(input);
        kfree(navpoint);
index 479ce5fe8955df596fca5d2bca77afc7e6711a59..a0a2657e31ffa1a5622a6192d15d4e6746f6e23c 100644 (file)
@@ -163,7 +163,6 @@ static int altera_ps2_remove(struct platform_device *pdev)
 {
        struct ps2if *ps2if = platform_get_drvdata(pdev);
 
-       platform_set_drvdata(pdev, NULL);
        serio_unregister_port(ps2if->io);
        free_irq(ps2if->irq, ps2if);
        iounmap(ps2if->base);
index 190ce35af7df76f43d5a86e32c094237e8855070..3290b287ac4b5cd02a51f7a5b7f82891ed3412fe 100644 (file)
@@ -314,8 +314,6 @@ static int __exit psif_remove(struct platform_device *pdev)
        clk_put(psif->pclk);
        kfree(psif);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 436a3433f8e55e5a3dedcb111614e74d928cbb3e..7a65a1bc5226ddabfd558b98545fb81085d16519 100644 (file)
@@ -181,7 +181,6 @@ static int q40kbd_remove(struct platform_device *pdev)
        free_irq(Q40_IRQ_KEYBOARD, q40kbd);
        kfree(q40kbd);
 
-       platform_set_drvdata(pdev, NULL);
        return 0;
 }
 
index 17be85948ffd850a3684531cdaa0fbd890634faa..4b7662a17ae90226bce968651f0a084f3c90826f 100644 (file)
@@ -349,8 +349,6 @@ static int xps2_of_remove(struct platform_device *of_dev)
 
        kfree(drvdata);
 
-       platform_set_drvdata(of_dev, NULL);
-
        return 0;
 }
 
index c7068942ebe8e2237f92b056dff8adeb29f896d3..f7de14a268bfc577b5dbc62abcccb3294de33f85 100644 (file)
@@ -237,7 +237,7 @@ static int pm860x_touch_probe(struct platform_device *pdev)
        touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL);
        if (touch == NULL)
                return -ENOMEM;
-       dev_set_drvdata(&pdev->dev, touch);
+       platform_set_drvdata(pdev, touch);
 
        touch->idev = input_allocate_device();
        if (touch->idev == NULL) {
@@ -299,7 +299,6 @@ static int pm860x_touch_remove(struct platform_device *pdev)
 
        input_unregister_device(touch->idev);
        free_irq(touch->irq, touch);
-       platform_set_drvdata(pdev, NULL);
        kfree(touch);
        return 0;
 }
index 2c1e46b7e45bfa73120796af2898855240f5b6cc..268a35e55d7f160fd632a673276f67ee6672665f 100644 (file)
@@ -372,7 +372,6 @@ static int __init atmel_wm97xx_probe(struct platform_device *pdev)
 err_irq:
        free_irq(atmel_wm97xx->ac97c_irq, atmel_wm97xx);
 err:
-       platform_set_drvdata(pdev, NULL);
        kfree(atmel_wm97xx);
        return ret;
 }
@@ -386,7 +385,6 @@ static int __exit atmel_wm97xx_remove(struct platform_device *pdev)
        free_irq(atmel_wm97xx->ac97c_irq, atmel_wm97xx);
        del_timer_sync(&atmel_wm97xx->pen_timer);
        wm97xx_unregister_mach_ops(wm);
-       platform_set_drvdata(pdev, NULL);
        kfree(atmel_wm97xx);
 
        return 0;
index 95f6785a94b02ecf6ef64be0d638a7ef7a82c063..bddabc5950778a793f04cdf6cbb9d3fe24bebcd1 100644 (file)
@@ -183,10 +183,13 @@ static int atmel_tsadcc_probe(struct platform_device *pdev)
        struct input_dev        *input_dev;
        struct resource         *res;
        struct at91_tsadcc_data *pdata = pdev->dev.platform_data;
-       int             err = 0;
+       int             err;
        unsigned int    prsc;
        unsigned int    reg;
 
+       if (!pdata)
+               return -EINVAL;
+
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                dev_err(&pdev->dev, "no mmio resource defined.\n");
@@ -265,9 +268,6 @@ static int atmel_tsadcc_probe(struct platform_device *pdev)
        prsc = clk_get_rate(ts_dev->clk);
        dev_info(&pdev->dev, "Master clock is set at: %d Hz\n", prsc);
 
-       if (!pdata)
-               goto err_fail;
-
        if (!pdata->adc_clock)
                pdata->adc_clock = ADC_DEFAULT_CLOCK;
 
@@ -325,7 +325,7 @@ err_free_mem:
 
 static int atmel_tsadcc_remove(struct platform_device *pdev)
 {
-       struct atmel_tsadcc *ts_dev = dev_get_drvdata(&pdev->dev);
+       struct atmel_tsadcc *ts_dev = platform_get_drvdata(pdev);
        struct resource *res;
 
        free_irq(ts_dev->irq, ts_dev);
index 8f561e22bdd498dacb85375773cad52f50388f46..ab64d58c3ac03ca8a403da32cd5540d0d54d79b0 100644 (file)
@@ -329,8 +329,6 @@ static int  da9052_ts_remove(struct platform_device *pdev)
        input_unregister_device(tsi->dev);
        kfree(tsi);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 39f3df8670c311ec2373ec4ddad585ce4217743b..ef5fcb0945e910b11918b26159a2860cec2cba2a 100644 (file)
@@ -166,24 +166,22 @@ static int egalax_firmware_version(struct i2c_client *client)
 }
 
 static int egalax_ts_probe(struct i2c_client *client,
-                                      const struct i2c_device_id *id)
+                          const struct i2c_device_id *id)
 {
        struct egalax_ts *ts;
        struct input_dev *input_dev;
-       int ret;
        int error;
 
-       ts = kzalloc(sizeof(struct egalax_ts), GFP_KERNEL);
+       ts = devm_kzalloc(&client->dev, sizeof(struct egalax_ts), GFP_KERNEL);
        if (!ts) {
                dev_err(&client->dev, "Failed to allocate memory\n");
                return -ENOMEM;
        }
 
-       input_dev = input_allocate_device();
+       input_dev = devm_input_allocate_device(&client->dev);
        if (!input_dev) {
                dev_err(&client->dev, "Failed to allocate memory\n");
-               error = -ENOMEM;
-               goto err_free_ts;
+               return -ENOMEM;
        }
 
        ts->client = client;
@@ -193,19 +191,17 @@ static int egalax_ts_probe(struct i2c_client *client,
        error = egalax_wake_up_device(client);
        if (error) {
                dev_err(&client->dev, "Failed to wake up the controller\n");
-               goto err_free_dev;
+               return error;
        }
 
-       ret = egalax_firmware_version(client);
-       if (ret < 0) {
+       error = egalax_firmware_version(client);
+       if (error < 0) {
                dev_err(&client->dev, "Failed to read firmware version\n");
-               error = -EIO;
-               goto err_free_dev;
+               return error;
        }
 
        input_dev->name = "EETI eGalax Touch Screen";
        input_dev->id.bustype = BUS_I2C;
-       input_dev->dev.parent = &client->dev;
 
        __set_bit(EV_ABS, input_dev->evbit);
        __set_bit(EV_KEY, input_dev->evbit);
@@ -221,41 +217,21 @@ static int egalax_ts_probe(struct i2c_client *client,
 
        input_set_drvdata(input_dev, ts);
 
-       error = request_threaded_irq(client->irq, NULL, egalax_ts_interrupt,
-                                    IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-                                    "egalax_ts", ts);
+       error = devm_request_threaded_irq(&client->dev, client->irq, NULL,
+                                         egalax_ts_interrupt,
+                                         IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+                                         "egalax_ts", ts);
        if (error < 0) {
                dev_err(&client->dev, "Failed to register interrupt\n");
-               goto err_free_dev;
+               return error;
        }
 
        error = input_register_device(ts->input_dev);
        if (error)
-               goto err_free_irq;
+               return error;
 
        i2c_set_clientdata(client, ts);
        return 0;
-
-err_free_irq:
-       free_irq(client->irq, ts);
-err_free_dev:
-       input_free_device(input_dev);
-err_free_ts:
-       kfree(ts);
-
-       return error;
-}
-
-static int egalax_ts_remove(struct i2c_client *client)
-{
-       struct egalax_ts *ts = i2c_get_clientdata(client);
-
-       free_irq(client->irq, ts);
-
-       input_unregister_device(ts->input_dev);
-       kfree(ts);
-
-       return 0;
 }
 
 static const struct i2c_device_id egalax_ts_id[] = {
@@ -301,7 +277,6 @@ static struct i2c_driver egalax_ts_driver = {
        },
        .id_table       = egalax_ts_id,
        .probe          = egalax_ts_probe,
-       .remove         = egalax_ts_remove,
 };
 
 module_i2c_driver(egalax_ts_driver);
index 465db5dba8b4a20a4c0f0eb3b6ae89d9ab6e9feb..e30d837dae2f12a130b91c6a620637b0e663fa72 100644 (file)
@@ -651,8 +651,6 @@ static int mrstouch_remove(struct platform_device *pdev)
        input_unregister_device(tsdev->input);
        kfree(tsdev);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 282d7c7ad2fcf0ba15516bbdd400791f29310efc..e463a79ffecc0a3873cf4c3941b1c2c3dbdcab24 100644 (file)
@@ -145,7 +145,6 @@ static int jornada720_ts_probe(struct platform_device *pdev)
  fail2:
        free_irq(IRQ_GPIO9, pdev);
  fail1:
-       platform_set_drvdata(pdev, NULL);
        input_free_device(input_dev);
        kfree(jornada_ts);
        return error;
@@ -156,7 +155,6 @@ static int jornada720_ts_remove(struct platform_device *pdev)
        struct jornada_ts *jornada_ts = platform_get_drvdata(pdev);
 
        free_irq(IRQ_GPIO9, pdev);
-       platform_set_drvdata(pdev, NULL);
        input_unregister_device(jornada_ts->dev);
        kfree(jornada_ts);
 
index 89308fe38752f220662680285ecb913dc1acaa9c..d6f099c47f84b09ab484f0df3628cdaefb5bc1a8 100644 (file)
@@ -233,8 +233,6 @@ static int mc13783_ts_remove(struct platform_device *pdev)
 {
        struct mc13783_ts_priv *priv = platform_get_drvdata(pdev);
 
-       platform_set_drvdata(pdev, NULL);
-
        destroy_workqueue(priv->workq);
        input_unregister_device(priv->idev);
        kfree(priv);
index 51e7b87827a45ff0bd1c5335d2dc7b7b0ce70d8a..50fb1293874e56053435f55a312b7e869ddfb6f8 100644 (file)
@@ -336,7 +336,6 @@ static int titsc_remove(struct platform_device *pdev)
 
        input_unregister_device(ts_dev->input);
 
-       platform_set_drvdata(pdev, NULL);
        kfree(ts_dev);
        return 0;
 }
index acfb87607b878f03098857dabed8452b98e83b3d..c47827a26e3ce1e612023aa3afcd473658fb22bc 100644 (file)
@@ -351,7 +351,6 @@ error_clk:
 error_map:
        release_mem_region(ts->res->start, resource_size(ts->res));
 error_res:
-       platform_set_drvdata(pdev, NULL);
        kfree(ts);
 
        return error;
@@ -366,7 +365,6 @@ static int tsc_remove(struct platform_device *pdev)
        clk_put(ts->clk);
        iounmap(ts->regs);
        release_mem_region(ts->res->start, resource_size(ts->res));
-       platform_set_drvdata(pdev, NULL);
        kfree(ts);
 
        return 0;
index d2ef8f05c66ec968b382c054861db1b3e49d0ae9..003d0c3b5d08f091a32f97e401e83b59550de9a6 100644 (file)
@@ -318,8 +318,6 @@ static int w90x900ts_remove(struct platform_device *pdev)
        input_unregister_device(w90p910_ts->input);
        kfree(w90p910_ts);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index bf0d07620bac705d9e892fa816ae8bc97925f20f..7ccaa1b12b05b27377d91253aac2c2aab1639056 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Wacom Penabled Driver for I2C
  *
- * Copyright (c) 2011 Tatsunosuke Tobita, Wacom.
+ * Copyright (c) 2011 - 2013 Tatsunosuke Tobita, Wacom.
  * <tobita.tatsunosuke@wacom.co.jp>
  *
  * This program is free software; you can redistribute it
@@ -27,7 +27,6 @@
 #define WACOM_CMD_THROW0       0x05
 #define WACOM_CMD_THROW1       0x00
 #define WACOM_QUERY_SIZE       19
-#define WACOM_RETRY_CNT                100
 
 struct wacom_features {
        int x_max;
@@ -40,6 +39,8 @@ struct wacom_i2c {
        struct i2c_client *client;
        struct input_dev *input;
        u8 data[WACOM_QUERY_SIZE];
+       bool prox;
+       int tool;
 };
 
 static int wacom_query_device(struct i2c_client *client,
@@ -112,9 +113,14 @@ static irqreturn_t wacom_i2c_irq(int irq, void *dev_id)
        y = le16_to_cpup((__le16 *)&data[6]);
        pressure = le16_to_cpup((__le16 *)&data[8]);
 
+       if (!wac_i2c->prox)
+               wac_i2c->tool = (data[3] & 0x0c) ?
+                       BTN_TOOL_RUBBER : BTN_TOOL_PEN;
+
+       wac_i2c->prox = data[3] & 0x20;
+
        input_report_key(input, BTN_TOUCH, tsw || ers);
-       input_report_key(input, BTN_TOOL_PEN, tsw);
-       input_report_key(input, BTN_TOOL_RUBBER, ers);
+       input_report_key(input, wac_i2c->tool, wac_i2c->prox);
        input_report_key(input, BTN_STYLUS, f1);
        input_report_key(input, BTN_STYLUS2, f2);
        input_report_abs(input, ABS_X, x);
index b51c15408ff317980205880dae4961e1db793eb4..55ba46f6207d257137bbbace7f3fda43f1797d26 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/uaccess.h>
 #include <linux/moduleparam.h>
 #include <linux/jiffies.h>
+#include <linux/syscalls.h>
 
 #include <asm/ptrace.h>
 #include <asm/irq_regs.h>
@@ -586,6 +587,7 @@ struct sysrq_state {
 
        /* reset sequence handling */
        bool reset_canceled;
+       bool reset_requested;
        unsigned long reset_keybit[BITS_TO_LONGS(KEY_CNT)];
        int reset_seq_len;
        int reset_seq_cnt;
@@ -624,18 +626,26 @@ static void sysrq_parse_reset_sequence(struct sysrq_state *state)
        state->reset_seq_version = sysrq_reset_seq_version;
 }
 
-static void sysrq_do_reset(unsigned long dummy)
+static void sysrq_do_reset(unsigned long _state)
 {
-       __handle_sysrq(sysrq_xlate[KEY_B], false);
+       struct sysrq_state *state = (struct sysrq_state *) _state;
+
+       state->reset_requested = true;
+
+       sys_sync();
+       kernel_restart(NULL);
 }
 
 static void sysrq_handle_reset_request(struct sysrq_state *state)
 {
+       if (state->reset_requested)
+               __handle_sysrq(sysrq_xlate[KEY_B], false);
+
        if (sysrq_reset_downtime_ms)
                mod_timer(&state->keyreset_timer,
                        jiffies + msecs_to_jiffies(sysrq_reset_downtime_ms));
        else
-               sysrq_do_reset(0);
+               sysrq_do_reset((unsigned long)state);
 }
 
 static void sysrq_detect_reset_sequence(struct sysrq_state *state,
@@ -837,7 +847,8 @@ static int sysrq_connect(struct input_handler *handler,
        sysrq->handle.handler = handler;
        sysrq->handle.name = "sysrq";
        sysrq->handle.private = sysrq;
-       setup_timer(&sysrq->keyreset_timer, sysrq_do_reset, 0);
+       setup_timer(&sysrq->keyreset_timer,
+                   sysrq_do_reset, (unsigned long)sysrq);
 
        error = input_register_handle(&sysrq->handle);
        if (error) {
index 5ce8d5e6ea518e7f4d0303b4d4ac066dcd294224..24625569d16df600ed258a9c23c7c69be89fbaca 100644 (file)
 struct pxa27x_keypad_platform_data {
 
        /* code map for the matrix keys */
+       const struct matrix_keymap_data *matrix_keymap_data;
        unsigned int    matrix_key_rows;
        unsigned int    matrix_key_cols;
-       unsigned int    *matrix_key_map;
-       int             matrix_key_map_size;
 
        /* direct keys */
        int             direct_key_num;