diff options
-rw-r--r-- | arch/arm/mach-msm/board-halibut.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-msm/board-msm7x30.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-msm/board-qsd8x50.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-msm/board-trout.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-msm/devices-msm7x00.c | 31 | ||||
-rw-r--r-- | arch/arm/mach-msm/devices-msm7x30.c | 31 | ||||
-rw-r--r-- | arch/arm/mach-msm/devices-qsd8x50.c | 31 | ||||
-rw-r--r-- | arch/arm/mach-msm/devices.h | 4 | ||||
-rw-r--r-- | drivers/gpio/gpio-msm-v1.c | 220 |
9 files changed, 250 insertions, 71 deletions
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c index 84d720af34ab..82eaf88d2026 100644 --- a/arch/arm/mach-msm/board-halibut.c +++ b/arch/arm/mach-msm/board-halibut.c | |||
@@ -59,6 +59,7 @@ static struct platform_device smc91x_device = { | |||
59 | }; | 59 | }; |
60 | 60 | ||
61 | static struct platform_device *devices[] __initdata = { | 61 | static struct platform_device *devices[] __initdata = { |
62 | &msm_device_gpio_7201, | ||
62 | &msm_device_uart3, | 63 | &msm_device_uart3, |
63 | &msm_device_smd, | 64 | &msm_device_smd, |
64 | &msm_device_nand, | 65 | &msm_device_nand, |
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c index 7bc3f82e3ec9..520c141acd03 100644 --- a/arch/arm/mach-msm/board-msm7x30.c +++ b/arch/arm/mach-msm/board-msm7x30.c | |||
@@ -89,6 +89,7 @@ struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = { | |||
89 | }; | 89 | }; |
90 | 90 | ||
91 | static struct platform_device *devices[] __initdata = { | 91 | static struct platform_device *devices[] __initdata = { |
92 | &msm_device_gpio_7x30, | ||
92 | #if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER) | 93 | #if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER) |
93 | &msm_device_uart2, | 94 | &msm_device_uart2, |
94 | #endif | 95 | #endif |
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c index 686e7949a73a..38a532d6937c 100644 --- a/arch/arm/mach-msm/board-qsd8x50.c +++ b/arch/arm/mach-msm/board-qsd8x50.c | |||
@@ -89,6 +89,7 @@ static struct msm_otg_platform_data msm_otg_pdata = { | |||
89 | }; | 89 | }; |
90 | 90 | ||
91 | static struct platform_device *devices[] __initdata = { | 91 | static struct platform_device *devices[] __initdata = { |
92 | &msm_device_gpio_8x50, | ||
92 | &msm_device_uart3, | 93 | &msm_device_uart3, |
93 | &msm_device_smd, | 94 | &msm_device_smd, |
94 | &msm_device_otg, | 95 | &msm_device_otg, |
diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c index 919bfa32871a..80fe1c5ff5c1 100644 --- a/arch/arm/mach-msm/board-trout.c +++ b/arch/arm/mach-msm/board-trout.c | |||
@@ -36,6 +36,7 @@ | |||
36 | extern int trout_init_mmc(unsigned int); | 36 | extern int trout_init_mmc(unsigned int); |
37 | 37 | ||
38 | static struct platform_device *devices[] __initdata = { | 38 | static struct platform_device *devices[] __initdata = { |
39 | &msm_device_gpio_7201, | ||
39 | &msm_device_uart3, | 40 | &msm_device_uart3, |
40 | &msm_device_smd, | 41 | &msm_device_smd, |
41 | &msm_device_nand, | 42 | &msm_device_nand, |
diff --git a/arch/arm/mach-msm/devices-msm7x00.c b/arch/arm/mach-msm/devices-msm7x00.c index f66ee6ea8720..1a0a2306b115 100644 --- a/arch/arm/mach-msm/devices-msm7x00.c +++ b/arch/arm/mach-msm/devices-msm7x00.c | |||
@@ -29,6 +29,37 @@ | |||
29 | #include "clock-pcom.h" | 29 | #include "clock-pcom.h" |
30 | #include <linux/platform_data/mmc-msm_sdcc.h> | 30 | #include <linux/platform_data/mmc-msm_sdcc.h> |
31 | 31 | ||
32 | static struct resource msm_gpio_resources[] = { | ||
33 | { | ||
34 | .start = 32 + 0, | ||
35 | .end = 32 + 0, | ||
36 | .flags = IORESOURCE_IRQ, | ||
37 | }, | ||
38 | { | ||
39 | .start = 32 + 1, | ||
40 | .end = 32 + 1, | ||
41 | .flags = IORESOURCE_IRQ, | ||
42 | }, | ||
43 | { | ||
44 | .start = 0xa9200800, | ||
45 | .end = 0xa9200800 + SZ_4K - 1, | ||
46 | .flags = IORESOURCE_MEM, | ||
47 | .name = "gpio1" | ||
48 | }, | ||
49 | { | ||
50 | .start = 0xa9300C00, | ||
51 | .end = 0xa9300C00 + SZ_4K - 1, | ||
52 | .flags = IORESOURCE_MEM, | ||
53 | .name = "gpio2" | ||
54 | }, | ||
55 | }; | ||
56 | |||
57 | struct platform_device msm_device_gpio_7201 = { | ||
58 | .name = "gpio-msm-7201", | ||
59 | .num_resources = ARRAY_SIZE(msm_gpio_resources), | ||
60 | .resource = msm_gpio_resources, | ||
61 | }; | ||
62 | |||
32 | static struct resource resources_uart1[] = { | 63 | static struct resource resources_uart1[] = { |
33 | { | 64 | { |
34 | .start = INT_UART1, | 65 | .start = INT_UART1, |
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c index e90ab5938c5f..12f482c07740 100644 --- a/arch/arm/mach-msm/devices-msm7x30.c +++ b/arch/arm/mach-msm/devices-msm7x30.c | |||
@@ -33,6 +33,37 @@ | |||
33 | 33 | ||
34 | #include <linux/platform_data/mmc-msm_sdcc.h> | 34 | #include <linux/platform_data/mmc-msm_sdcc.h> |
35 | 35 | ||
36 | static struct resource msm_gpio_resources[] = { | ||
37 | { | ||
38 | .start = 32 + 18, | ||
39 | .end = 32 + 18, | ||
40 | .flags = IORESOURCE_IRQ, | ||
41 | }, | ||
42 | { | ||
43 | .start = 32 + 19, | ||
44 | .end = 32 + 19, | ||
45 | .flags = IORESOURCE_IRQ, | ||
46 | }, | ||
47 | { | ||
48 | .start = 0xac001000, | ||
49 | .end = 0xac001000 + SZ_4K - 1, | ||
50 | .flags = IORESOURCE_MEM, | ||
51 | .name = "gpio1" | ||
52 | }, | ||
53 | { | ||
54 | .start = 0xac101400, | ||
55 | .end = 0xac101400 + SZ_4K - 1, | ||
56 | .flags = IORESOURCE_MEM, | ||
57 | .name = "gpio2" | ||
58 | }, | ||
59 | }; | ||
60 | |||
61 | struct platform_device msm_device_gpio_7x30 = { | ||
62 | .name = "gpio-msm-7x30", | ||
63 | .num_resources = ARRAY_SIZE(msm_gpio_resources), | ||
64 | .resource = msm_gpio_resources, | ||
65 | }; | ||
66 | |||
36 | static struct resource resources_uart2[] = { | 67 | static struct resource resources_uart2[] = { |
37 | { | 68 | { |
38 | .start = INT_UART2, | 69 | .start = INT_UART2, |
diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c index 4db61d5fe317..2e1b3ec9dfc7 100644 --- a/arch/arm/mach-msm/devices-qsd8x50.c +++ b/arch/arm/mach-msm/devices-qsd8x50.c | |||
@@ -30,6 +30,37 @@ | |||
30 | #include <linux/platform_data/mmc-msm_sdcc.h> | 30 | #include <linux/platform_data/mmc-msm_sdcc.h> |
31 | #include "clock-pcom.h" | 31 | #include "clock-pcom.h" |
32 | 32 | ||
33 | static struct resource msm_gpio_resources[] = { | ||
34 | { | ||
35 | .start = 64 + 165 + 9, | ||
36 | .end = 64 + 165 + 9, | ||
37 | .flags = IORESOURCE_IRQ, | ||
38 | }, | ||
39 | { | ||
40 | .start = 64 + 165 + 10, | ||
41 | .end = 64 + 165 + 10, | ||
42 | .flags = IORESOURCE_IRQ, | ||
43 | }, | ||
44 | { | ||
45 | .start = 0xa9000800, | ||
46 | .end = 0xa9000800 + SZ_4K - 1, | ||
47 | .flags = IORESOURCE_MEM, | ||
48 | .name = "gpio1" | ||
49 | }, | ||
50 | { | ||
51 | .start = 0xa9100C00, | ||
52 | .end = 0xa9100C00 + SZ_4K - 1, | ||
53 | .flags = IORESOURCE_MEM, | ||
54 | .name = "gpio2" | ||
55 | }, | ||
56 | }; | ||
57 | |||
58 | struct platform_device msm_device_gpio_8x50 = { | ||
59 | .name = "gpio-msm-8x50", | ||
60 | .num_resources = ARRAY_SIZE(msm_gpio_resources), | ||
61 | .resource = msm_gpio_resources, | ||
62 | }; | ||
63 | |||
33 | static struct resource resources_uart3[] = { | 64 | static struct resource resources_uart3[] = { |
34 | { | 65 | { |
35 | .start = INT_UART3, | 66 | .start = INT_UART3, |
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h index 9545c196c6e8..da902cf51161 100644 --- a/arch/arm/mach-msm/devices.h +++ b/arch/arm/mach-msm/devices.h | |||
@@ -20,6 +20,10 @@ | |||
20 | 20 | ||
21 | #include "clock.h" | 21 | #include "clock.h" |
22 | 22 | ||
23 | extern struct platform_device msm_device_gpio_7201; | ||
24 | extern struct platform_device msm_device_gpio_7x30; | ||
25 | extern struct platform_device msm_device_gpio_8x50; | ||
26 | |||
23 | extern struct platform_device msm_device_uart1; | 27 | extern struct platform_device msm_device_uart1; |
24 | extern struct platform_device msm_device_uart2; | 28 | extern struct platform_device msm_device_uart2; |
25 | extern struct platform_device msm_device_uart3; | 29 | extern struct platform_device msm_device_uart3; |
diff --git a/drivers/gpio/gpio-msm-v1.c b/drivers/gpio/gpio-msm-v1.c index 52a4d4286eba..c798585a3fe5 100644 --- a/drivers/gpio/gpio-msm-v1.c +++ b/drivers/gpio/gpio-msm-v1.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2007 Google, Inc. | 2 | * Copyright (C) 2007 Google, Inc. |
3 | * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved. | 3 | * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. |
4 | * | 4 | * |
5 | * This software is licensed under the terms of the GNU General Public | 5 | * This software is licensed under the terms of the GNU General Public |
6 | * License version 2, as published by the Free Software Foundation, and | 6 | * License version 2, as published by the Free Software Foundation, and |
@@ -19,9 +19,10 @@ | |||
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <mach/cpu.h> | 22 | #include <linux/device.h> |
23 | #include <linux/platform_device.h> | ||
24 | |||
23 | #include <mach/msm_gpiomux.h> | 25 | #include <mach/msm_gpiomux.h> |
24 | #include <mach/msm_iomap.h> | ||
25 | 26 | ||
26 | /* see 80-VA736-2 Rev C pp 695-751 | 27 | /* see 80-VA736-2 Rev C pp 695-751 |
27 | ** | 28 | ** |
@@ -34,10 +35,10 @@ | |||
34 | ** macros. | 35 | ** macros. |
35 | */ | 36 | */ |
36 | 37 | ||
37 | #define MSM_GPIO1_REG(off) (MSM_GPIO1_BASE + (off)) | 38 | #define MSM_GPIO1_REG(off) (off) |
38 | #define MSM_GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off)) | 39 | #define MSM_GPIO2_REG(off) (off) |
39 | #define MSM_GPIO1_SHADOW_REG(off) (MSM_GPIO1_BASE + 0x800 + (off)) | 40 | #define MSM_GPIO1_SHADOW_REG(off) (off) |
40 | #define MSM_GPIO2_SHADOW_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off)) | 41 | #define MSM_GPIO2_SHADOW_REG(off) (off) |
41 | 42 | ||
42 | /* | 43 | /* |
43 | * MSM7X00 registers | 44 | * MSM7X00 registers |
@@ -276,16 +277,14 @@ | |||
276 | 277 | ||
277 | #define MSM_GPIO_BANK(soc, bank, first, last) \ | 278 | #define MSM_GPIO_BANK(soc, bank, first, last) \ |
278 | { \ | 279 | { \ |
279 | .regs = { \ | 280 | .regs[MSM_GPIO_OUT] = soc##_GPIO_OUT_##bank, \ |
280 | .out = soc##_GPIO_OUT_##bank, \ | 281 | .regs[MSM_GPIO_IN] = soc##_GPIO_IN_##bank, \ |
281 | .in = soc##_GPIO_IN_##bank, \ | 282 | .regs[MSM_GPIO_INT_STATUS] = soc##_GPIO_INT_STATUS_##bank, \ |
282 | .int_status = soc##_GPIO_INT_STATUS_##bank, \ | 283 | .regs[MSM_GPIO_INT_CLEAR] = soc##_GPIO_INT_CLEAR_##bank, \ |
283 | .int_clear = soc##_GPIO_INT_CLEAR_##bank, \ | 284 | .regs[MSM_GPIO_INT_EN] = soc##_GPIO_INT_EN_##bank, \ |
284 | .int_en = soc##_GPIO_INT_EN_##bank, \ | 285 | .regs[MSM_GPIO_INT_EDGE] = soc##_GPIO_INT_EDGE_##bank, \ |
285 | .int_edge = soc##_GPIO_INT_EDGE_##bank, \ | 286 | .regs[MSM_GPIO_INT_POS] = soc##_GPIO_INT_POS_##bank, \ |
286 | .int_pos = soc##_GPIO_INT_POS_##bank, \ | 287 | .regs[MSM_GPIO_OE] = soc##_GPIO_OE_##bank, \ |
287 | .oe = soc##_GPIO_OE_##bank, \ | ||
288 | }, \ | ||
289 | .chip = { \ | 288 | .chip = { \ |
290 | .base = (first), \ | 289 | .base = (first), \ |
291 | .ngpio = (last) - (first) + 1, \ | 290 | .ngpio = (last) - (first) + 1, \ |
@@ -301,39 +300,57 @@ | |||
301 | 300 | ||
302 | #define MSM_GPIO_BROKEN_INT_CLEAR 1 | 301 | #define MSM_GPIO_BROKEN_INT_CLEAR 1 |
303 | 302 | ||
304 | struct msm_gpio_regs { | 303 | enum msm_gpio_reg { |
305 | void __iomem *out; | 304 | MSM_GPIO_IN, |
306 | void __iomem *in; | 305 | MSM_GPIO_OUT, |
307 | void __iomem *int_status; | 306 | MSM_GPIO_INT_STATUS, |
308 | void __iomem *int_clear; | 307 | MSM_GPIO_INT_CLEAR, |
309 | void __iomem *int_en; | 308 | MSM_GPIO_INT_EN, |
310 | void __iomem *int_edge; | 309 | MSM_GPIO_INT_EDGE, |
311 | void __iomem *int_pos; | 310 | MSM_GPIO_INT_POS, |
312 | void __iomem *oe; | 311 | MSM_GPIO_OE, |
312 | MSM_GPIO_REG_NR | ||
313 | }; | 313 | }; |
314 | 314 | ||
315 | struct msm_gpio_chip { | 315 | struct msm_gpio_chip { |
316 | spinlock_t lock; | 316 | spinlock_t lock; |
317 | struct gpio_chip chip; | 317 | struct gpio_chip chip; |
318 | struct msm_gpio_regs regs; | 318 | unsigned long regs[MSM_GPIO_REG_NR]; |
319 | #if MSM_GPIO_BROKEN_INT_CLEAR | 319 | #if MSM_GPIO_BROKEN_INT_CLEAR |
320 | unsigned int_status_copy; | 320 | unsigned int_status_copy; |
321 | #endif | 321 | #endif |
322 | unsigned int both_edge_detect; | 322 | unsigned int both_edge_detect; |
323 | unsigned int int_enable[2]; /* 0: awake, 1: sleep */ | 323 | unsigned int int_enable[2]; /* 0: awake, 1: sleep */ |
324 | void __iomem *base; | ||
325 | }; | ||
326 | |||
327 | struct msm_gpio_initdata { | ||
328 | struct msm_gpio_chip *chips; | ||
329 | int count; | ||
324 | }; | 330 | }; |
325 | 331 | ||
332 | static void msm_gpio_writel(struct msm_gpio_chip *chip, u32 val, | ||
333 | enum msm_gpio_reg reg) | ||
334 | { | ||
335 | writel(val, chip->base + chip->regs[reg]); | ||
336 | } | ||
337 | |||
338 | static u32 msm_gpio_readl(struct msm_gpio_chip *chip, enum msm_gpio_reg reg) | ||
339 | { | ||
340 | return readl(chip->base + chip->regs[reg]); | ||
341 | } | ||
342 | |||
326 | static int msm_gpio_write(struct msm_gpio_chip *msm_chip, | 343 | static int msm_gpio_write(struct msm_gpio_chip *msm_chip, |
327 | unsigned offset, unsigned on) | 344 | unsigned offset, unsigned on) |
328 | { | 345 | { |
329 | unsigned mask = BIT(offset); | 346 | unsigned mask = BIT(offset); |
330 | unsigned val; | 347 | unsigned val; |
331 | 348 | ||
332 | val = readl(msm_chip->regs.out); | 349 | val = msm_gpio_readl(msm_chip, MSM_GPIO_OUT); |
333 | if (on) | 350 | if (on) |
334 | writel(val | mask, msm_chip->regs.out); | 351 | msm_gpio_writel(msm_chip, val | mask, MSM_GPIO_OUT); |
335 | else | 352 | else |
336 | writel(val & ~mask, msm_chip->regs.out); | 353 | msm_gpio_writel(msm_chip, val & ~mask, MSM_GPIO_OUT); |
337 | return 0; | 354 | return 0; |
338 | } | 355 | } |
339 | 356 | ||
@@ -342,13 +359,13 @@ static void msm_gpio_update_both_edge_detect(struct msm_gpio_chip *msm_chip) | |||
342 | int loop_limit = 100; | 359 | int loop_limit = 100; |
343 | unsigned pol, val, val2, intstat; | 360 | unsigned pol, val, val2, intstat; |
344 | do { | 361 | do { |
345 | val = readl(msm_chip->regs.in); | 362 | val = msm_gpio_readl(msm_chip, MSM_GPIO_IN); |
346 | pol = readl(msm_chip->regs.int_pos); | 363 | pol = msm_gpio_readl(msm_chip, MSM_GPIO_INT_POS); |
347 | pol = (pol & ~msm_chip->both_edge_detect) | | 364 | pol = (pol & ~msm_chip->both_edge_detect) | |
348 | (~val & msm_chip->both_edge_detect); | 365 | (~val & msm_chip->both_edge_detect); |
349 | writel(pol, msm_chip->regs.int_pos); | 366 | msm_gpio_writel(msm_chip, pol, MSM_GPIO_INT_POS); |
350 | intstat = readl(msm_chip->regs.int_status); | 367 | intstat = msm_gpio_readl(msm_chip, MSM_GPIO_INT_STATUS); |
351 | val2 = readl(msm_chip->regs.in); | 368 | val2 = msm_gpio_readl(msm_chip, MSM_GPIO_IN); |
352 | if (((val ^ val2) & msm_chip->both_edge_detect & ~intstat) == 0) | 369 | if (((val ^ val2) & msm_chip->both_edge_detect & ~intstat) == 0) |
353 | return; | 370 | return; |
354 | } while (loop_limit-- > 0); | 371 | } while (loop_limit-- > 0); |
@@ -365,10 +382,11 @@ static int msm_gpio_clear_detect_status(struct msm_gpio_chip *msm_chip, | |||
365 | /* Save interrupts that already triggered before we loose them. */ | 382 | /* Save interrupts that already triggered before we loose them. */ |
366 | /* Any interrupt that triggers between the read of int_status */ | 383 | /* Any interrupt that triggers between the read of int_status */ |
367 | /* and the write to int_clear will still be lost though. */ | 384 | /* and the write to int_clear will still be lost though. */ |
368 | msm_chip->int_status_copy |= readl(msm_chip->regs.int_status); | 385 | msm_chip->int_status_copy |= |
386 | msm_gpio_readl(msm_chip, MSM_GPIO_INT_STATUS); | ||
369 | msm_chip->int_status_copy &= ~bit; | 387 | msm_chip->int_status_copy &= ~bit; |
370 | #endif | 388 | #endif |
371 | writel(bit, msm_chip->regs.int_clear); | 389 | msm_gpio_writel(msm_chip, bit, MSM_GPIO_INT_CLEAR); |
372 | msm_gpio_update_both_edge_detect(msm_chip); | 390 | msm_gpio_update_both_edge_detect(msm_chip); |
373 | return 0; | 391 | return 0; |
374 | } | 392 | } |
@@ -377,10 +395,12 @@ static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | |||
377 | { | 395 | { |
378 | struct msm_gpio_chip *msm_chip; | 396 | struct msm_gpio_chip *msm_chip; |
379 | unsigned long irq_flags; | 397 | unsigned long irq_flags; |
398 | u32 val; | ||
380 | 399 | ||
381 | msm_chip = container_of(chip, struct msm_gpio_chip, chip); | 400 | msm_chip = container_of(chip, struct msm_gpio_chip, chip); |
382 | spin_lock_irqsave(&msm_chip->lock, irq_flags); | 401 | spin_lock_irqsave(&msm_chip->lock, irq_flags); |
383 | writel(readl(msm_chip->regs.oe) & ~BIT(offset), msm_chip->regs.oe); | 402 | val = msm_gpio_readl(msm_chip, MSM_GPIO_OE) & ~BIT(offset); |
403 | msm_gpio_writel(msm_chip, val, MSM_GPIO_OE); | ||
384 | spin_unlock_irqrestore(&msm_chip->lock, irq_flags); | 404 | spin_unlock_irqrestore(&msm_chip->lock, irq_flags); |
385 | return 0; | 405 | return 0; |
386 | } | 406 | } |
@@ -390,11 +410,13 @@ msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value) | |||
390 | { | 410 | { |
391 | struct msm_gpio_chip *msm_chip; | 411 | struct msm_gpio_chip *msm_chip; |
392 | unsigned long irq_flags; | 412 | unsigned long irq_flags; |
413 | u32 val; | ||
393 | 414 | ||
394 | msm_chip = container_of(chip, struct msm_gpio_chip, chip); | 415 | msm_chip = container_of(chip, struct msm_gpio_chip, chip); |
395 | spin_lock_irqsave(&msm_chip->lock, irq_flags); | 416 | spin_lock_irqsave(&msm_chip->lock, irq_flags); |
396 | msm_gpio_write(msm_chip, offset, value); | 417 | msm_gpio_write(msm_chip, offset, value); |
397 | writel(readl(msm_chip->regs.oe) | BIT(offset), msm_chip->regs.oe); | 418 | val = msm_gpio_readl(msm_chip, MSM_GPIO_OE) | BIT(offset); |
419 | msm_gpio_writel(msm_chip, val, MSM_GPIO_OE); | ||
398 | spin_unlock_irqrestore(&msm_chip->lock, irq_flags); | 420 | spin_unlock_irqrestore(&msm_chip->lock, irq_flags); |
399 | return 0; | 421 | return 0; |
400 | } | 422 | } |
@@ -404,7 +426,7 @@ static int msm_gpio_get(struct gpio_chip *chip, unsigned offset) | |||
404 | struct msm_gpio_chip *msm_chip; | 426 | struct msm_gpio_chip *msm_chip; |
405 | 427 | ||
406 | msm_chip = container_of(chip, struct msm_gpio_chip, chip); | 428 | msm_chip = container_of(chip, struct msm_gpio_chip, chip); |
407 | return (readl(msm_chip->regs.in) & (1U << offset)) ? 1 : 0; | 429 | return (msm_gpio_readl(msm_chip, MSM_GPIO_IN) & (1U << offset)) ? 1 : 0; |
408 | } | 430 | } |
409 | 431 | ||
410 | static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | 432 | static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
@@ -450,6 +472,11 @@ static struct msm_gpio_chip msm_gpio_chips_msm7x01[] = { | |||
450 | MSM_GPIO_BANK(MSM7X00, 5, 107, 121), | 472 | MSM_GPIO_BANK(MSM7X00, 5, 107, 121), |
451 | }; | 473 | }; |
452 | 474 | ||
475 | static struct msm_gpio_initdata msm_gpio_7x01_init = { | ||
476 | .chips = msm_gpio_chips_msm7x01, | ||
477 | .count = ARRAY_SIZE(msm_gpio_chips_msm7x01), | ||
478 | }; | ||
479 | |||
453 | static struct msm_gpio_chip msm_gpio_chips_msm7x30[] = { | 480 | static struct msm_gpio_chip msm_gpio_chips_msm7x30[] = { |
454 | MSM_GPIO_BANK(MSM7X30, 0, 0, 15), | 481 | MSM_GPIO_BANK(MSM7X30, 0, 0, 15), |
455 | MSM_GPIO_BANK(MSM7X30, 1, 16, 43), | 482 | MSM_GPIO_BANK(MSM7X30, 1, 16, 43), |
@@ -461,6 +488,11 @@ static struct msm_gpio_chip msm_gpio_chips_msm7x30[] = { | |||
461 | MSM_GPIO_BANK(MSM7X30, 7, 151, 181), | 488 | MSM_GPIO_BANK(MSM7X30, 7, 151, 181), |
462 | }; | 489 | }; |
463 | 490 | ||
491 | static struct msm_gpio_initdata msm_gpio_7x30_init = { | ||
492 | .chips = msm_gpio_chips_msm7x30, | ||
493 | .count = ARRAY_SIZE(msm_gpio_chips_msm7x30), | ||
494 | }; | ||
495 | |||
464 | static struct msm_gpio_chip msm_gpio_chips_qsd8x50[] = { | 496 | static struct msm_gpio_chip msm_gpio_chips_qsd8x50[] = { |
465 | MSM_GPIO_BANK(QSD8X50, 0, 0, 15), | 497 | MSM_GPIO_BANK(QSD8X50, 0, 0, 15), |
466 | MSM_GPIO_BANK(QSD8X50, 1, 16, 42), | 498 | MSM_GPIO_BANK(QSD8X50, 1, 16, 42), |
@@ -472,6 +504,11 @@ static struct msm_gpio_chip msm_gpio_chips_qsd8x50[] = { | |||
472 | MSM_GPIO_BANK(QSD8X50, 7, 153, 164), | 504 | MSM_GPIO_BANK(QSD8X50, 7, 153, 164), |
473 | }; | 505 | }; |
474 | 506 | ||
507 | static struct msm_gpio_initdata msm_gpio_8x50_init = { | ||
508 | .chips = msm_gpio_chips_qsd8x50, | ||
509 | .count = ARRAY_SIZE(msm_gpio_chips_qsd8x50), | ||
510 | }; | ||
511 | |||
475 | static void msm_gpio_irq_ack(struct irq_data *d) | 512 | static void msm_gpio_irq_ack(struct irq_data *d) |
476 | { | 513 | { |
477 | unsigned long irq_flags; | 514 | unsigned long irq_flags; |
@@ -490,10 +527,10 @@ static void msm_gpio_irq_mask(struct irq_data *d) | |||
490 | 527 | ||
491 | spin_lock_irqsave(&msm_chip->lock, irq_flags); | 528 | spin_lock_irqsave(&msm_chip->lock, irq_flags); |
492 | /* level triggered interrupts are also latched */ | 529 | /* level triggered interrupts are also latched */ |
493 | if (!(readl(msm_chip->regs.int_edge) & BIT(offset))) | 530 | if (!(msm_gpio_readl(msm_chip, MSM_GPIO_INT_EDGE) & BIT(offset))) |
494 | msm_gpio_clear_detect_status(msm_chip, offset); | 531 | msm_gpio_clear_detect_status(msm_chip, offset); |
495 | msm_chip->int_enable[0] &= ~BIT(offset); | 532 | msm_chip->int_enable[0] &= ~BIT(offset); |
496 | writel(msm_chip->int_enable[0], msm_chip->regs.int_en); | 533 | msm_gpio_writel(msm_chip, msm_chip->int_enable[0], MSM_GPIO_INT_EN); |
497 | spin_unlock_irqrestore(&msm_chip->lock, irq_flags); | 534 | spin_unlock_irqrestore(&msm_chip->lock, irq_flags); |
498 | } | 535 | } |
499 | 536 | ||
@@ -505,10 +542,10 @@ static void msm_gpio_irq_unmask(struct irq_data *d) | |||
505 | 542 | ||
506 | spin_lock_irqsave(&msm_chip->lock, irq_flags); | 543 | spin_lock_irqsave(&msm_chip->lock, irq_flags); |
507 | /* level triggered interrupts are also latched */ | 544 | /* level triggered interrupts are also latched */ |
508 | if (!(readl(msm_chip->regs.int_edge) & BIT(offset))) | 545 | if (!(msm_gpio_readl(msm_chip, MSM_GPIO_INT_EDGE) & BIT(offset))) |
509 | msm_gpio_clear_detect_status(msm_chip, offset); | 546 | msm_gpio_clear_detect_status(msm_chip, offset); |
510 | msm_chip->int_enable[0] |= BIT(offset); | 547 | msm_chip->int_enable[0] |= BIT(offset); |
511 | writel(msm_chip->int_enable[0], msm_chip->regs.int_en); | 548 | msm_gpio_writel(msm_chip, msm_chip->int_enable[0], MSM_GPIO_INT_EN); |
512 | spin_unlock_irqrestore(&msm_chip->lock, irq_flags); | 549 | spin_unlock_irqrestore(&msm_chip->lock, irq_flags); |
513 | } | 550 | } |
514 | 551 | ||
@@ -537,12 +574,12 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type) | |||
537 | unsigned val, mask = BIT(offset); | 574 | unsigned val, mask = BIT(offset); |
538 | 575 | ||
539 | spin_lock_irqsave(&msm_chip->lock, irq_flags); | 576 | spin_lock_irqsave(&msm_chip->lock, irq_flags); |
540 | val = readl(msm_chip->regs.int_edge); | 577 | val = msm_gpio_readl(msm_chip, MSM_GPIO_INT_EDGE); |
541 | if (flow_type & IRQ_TYPE_EDGE_BOTH) { | 578 | if (flow_type & IRQ_TYPE_EDGE_BOTH) { |
542 | writel(val | mask, msm_chip->regs.int_edge); | 579 | msm_gpio_writel(msm_chip, val | mask, MSM_GPIO_INT_EDGE); |
543 | __irq_set_handler_locked(d->irq, handle_edge_irq); | 580 | __irq_set_handler_locked(d->irq, handle_edge_irq); |
544 | } else { | 581 | } else { |
545 | writel(val & ~mask, msm_chip->regs.int_edge); | 582 | msm_gpio_writel(msm_chip, val & ~mask, MSM_GPIO_INT_EDGE); |
546 | __irq_set_handler_locked(d->irq, handle_level_irq); | 583 | __irq_set_handler_locked(d->irq, handle_level_irq); |
547 | } | 584 | } |
548 | if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) { | 585 | if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) { |
@@ -550,11 +587,12 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type) | |||
550 | msm_gpio_update_both_edge_detect(msm_chip); | 587 | msm_gpio_update_both_edge_detect(msm_chip); |
551 | } else { | 588 | } else { |
552 | msm_chip->both_edge_detect &= ~mask; | 589 | msm_chip->both_edge_detect &= ~mask; |
553 | val = readl(msm_chip->regs.int_pos); | 590 | val = msm_gpio_readl(msm_chip, MSM_GPIO_INT_POS); |
554 | if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH)) | 591 | if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH)) |
555 | writel(val | mask, msm_chip->regs.int_pos); | 592 | val |= mask; |
556 | else | 593 | else |
557 | writel(val & ~mask, msm_chip->regs.int_pos); | 594 | val &= ~mask; |
595 | msm_gpio_writel(msm_chip, val, MSM_GPIO_INT_POS); | ||
558 | } | 596 | } |
559 | spin_unlock_irqrestore(&msm_chip->lock, irq_flags); | 597 | spin_unlock_irqrestore(&msm_chip->lock, irq_flags); |
560 | return 0; | 598 | return 0; |
@@ -567,7 +605,7 @@ static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
567 | 605 | ||
568 | for (i = 0; i < msm_gpio_count; i++) { | 606 | for (i = 0; i < msm_gpio_count; i++) { |
569 | struct msm_gpio_chip *msm_chip = &msm_gpio_chips[i]; | 607 | struct msm_gpio_chip *msm_chip = &msm_gpio_chips[i]; |
570 | val = readl(msm_chip->regs.int_status); | 608 | val = msm_gpio_readl(msm_chip, MSM_GPIO_INT_STATUS); |
571 | val &= msm_chip->int_enable[0]; | 609 | val &= msm_chip->int_enable[0]; |
572 | while (val) { | 610 | while (val) { |
573 | mask = val & -val; | 611 | mask = val & -val; |
@@ -592,22 +630,36 @@ static struct irq_chip msm_gpio_irq_chip = { | |||
592 | .irq_set_type = msm_gpio_irq_set_type, | 630 | .irq_set_type = msm_gpio_irq_set_type, |
593 | }; | 631 | }; |
594 | 632 | ||
595 | static int __init msm_init_gpio(void) | 633 | static int __devinit gpio_msm_v1_probe(struct platform_device *pdev) |
596 | { | 634 | { |
597 | int i, j = 0; | 635 | int i, j = 0; |
598 | 636 | const struct platform_device_id *dev_id = platform_get_device_id(pdev); | |
599 | if (cpu_is_msm7x01()) { | 637 | struct msm_gpio_initdata *data; |
600 | msm_gpio_chips = msm_gpio_chips_msm7x01; | 638 | int irq1, irq2; |
601 | msm_gpio_count = ARRAY_SIZE(msm_gpio_chips_msm7x01); | 639 | struct resource *res; |
602 | } else if (cpu_is_msm7x30()) { | 640 | void __iomem *base1, __iomem *base2; |
603 | msm_gpio_chips = msm_gpio_chips_msm7x30; | 641 | |
604 | msm_gpio_count = ARRAY_SIZE(msm_gpio_chips_msm7x30); | 642 | data = (struct msm_gpio_initdata *)dev_id->driver_data; |
605 | } else if (cpu_is_qsd8x50()) { | 643 | msm_gpio_chips = data->chips; |
606 | msm_gpio_chips = msm_gpio_chips_qsd8x50; | 644 | msm_gpio_count = data->count; |
607 | msm_gpio_count = ARRAY_SIZE(msm_gpio_chips_qsd8x50); | 645 | |
608 | } else { | 646 | irq1 = platform_get_irq(pdev, 0); |
609 | return 0; | 647 | if (irq1 < 0) |
610 | } | 648 | return irq1; |
649 | |||
650 | irq2 = platform_get_irq(pdev, 1); | ||
651 | if (irq2 < 0) | ||
652 | return irq2; | ||
653 | |||
654 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
655 | base1 = devm_request_and_ioremap(&pdev->dev, res); | ||
656 | if (!base1) | ||
657 | return -EADDRNOTAVAIL; | ||
658 | |||
659 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
660 | base2 = devm_request_and_ioremap(&pdev->dev, res); | ||
661 | if (!base2) | ||
662 | return -EADDRNOTAVAIL; | ||
611 | 663 | ||
612 | for (i = FIRST_GPIO_IRQ; i < FIRST_GPIO_IRQ + NR_GPIO_IRQS; i++) { | 664 | for (i = FIRST_GPIO_IRQ; i < FIRST_GPIO_IRQ + NR_GPIO_IRQS; i++) { |
613 | if (i - FIRST_GPIO_IRQ >= | 665 | if (i - FIRST_GPIO_IRQ >= |
@@ -621,16 +673,42 @@ static int __init msm_init_gpio(void) | |||
621 | } | 673 | } |
622 | 674 | ||
623 | for (i = 0; i < msm_gpio_count; i++) { | 675 | for (i = 0; i < msm_gpio_count; i++) { |
676 | if (i == 1) | ||
677 | msm_gpio_chips[i].base = base2; | ||
678 | else | ||
679 | msm_gpio_chips[i].base = base1; | ||
624 | spin_lock_init(&msm_gpio_chips[i].lock); | 680 | spin_lock_init(&msm_gpio_chips[i].lock); |
625 | writel(0, msm_gpio_chips[i].regs.int_en); | 681 | msm_gpio_writel(&msm_gpio_chips[i], 0, MSM_GPIO_INT_EN); |
626 | gpiochip_add(&msm_gpio_chips[i].chip); | 682 | gpiochip_add(&msm_gpio_chips[i].chip); |
627 | } | 683 | } |
628 | 684 | ||
629 | irq_set_chained_handler(INT_GPIO_GROUP1, msm_gpio_irq_handler); | 685 | irq_set_chained_handler(irq1, msm_gpio_irq_handler); |
630 | irq_set_chained_handler(INT_GPIO_GROUP2, msm_gpio_irq_handler); | 686 | irq_set_chained_handler(irq2, msm_gpio_irq_handler); |
631 | irq_set_irq_wake(INT_GPIO_GROUP1, 1); | 687 | irq_set_irq_wake(irq1, 1); |
632 | irq_set_irq_wake(INT_GPIO_GROUP2, 2); | 688 | irq_set_irq_wake(irq2, 2); |
633 | return 0; | 689 | return 0; |
634 | } | 690 | } |
635 | 691 | ||
636 | postcore_initcall(msm_init_gpio); | 692 | static struct platform_device_id gpio_msm_v1_device_ids[] = { |
693 | { "gpio-msm-7201", (unsigned long)&msm_gpio_7x01_init }, | ||
694 | { "gpio-msm-7x30", (unsigned long)&msm_gpio_7x30_init }, | ||
695 | { "gpio-msm-8x50", (unsigned long)&msm_gpio_8x50_init }, | ||
696 | { } | ||
697 | }; | ||
698 | MODULE_DEVICE_TABLE(platform, gpio_msm_v1_device_ids); | ||
699 | |||
700 | static struct platform_driver gpio_msm_v1_driver = { | ||
701 | .driver = { | ||
702 | .name = "gpio-msm-v1", | ||
703 | .owner = THIS_MODULE, | ||
704 | }, | ||
705 | .probe = gpio_msm_v1_probe, | ||
706 | .id_table = gpio_msm_v1_device_ids, | ||
707 | }; | ||
708 | |||
709 | static int __init gpio_msm_v1_init(void) | ||
710 | { | ||
711 | return platform_driver_register(&gpio_msm_v1_driver); | ||
712 | } | ||
713 | postcore_initcall(gpio_msm_v1_init); | ||
714 | MODULE_LICENSE("GPL v2"); | ||