Commit e5ff4440cf5206fbb99d9a354ed9024eb3da047d
1 parent
9942da0e4b
Exists in
master
and in
4 other branches
gpio/omap: cleanup show revision, remove cpu_is checks, display only once
Remove cpu_is_* checks from gpio_show_revision() by passing in the revision address offset from platform data. SoCs with no revision register (15xx, 7xx, and all MPUIOs) use -1 (actually, USHRT_MAX) to signify no register. While here, all GPIO banks are assumed to be the same revision, so fix show_revision() to only show the revision for the first bank it finds. This removes duplicate GPIO revision prints during boot. Thanks to Charulatha V <charu@ti.com> for finding/fixing a few -1s that were missed in the original patch. Signed-off-by: Kevin Hilman <khilman@ti.com>
Showing 6 changed files with 15 additions and 8 deletions Inline Diff
arch/arm/mach-omap1/gpio15xx.c
1 | /* | 1 | /* |
2 | * OMAP15xx specific gpio init | 2 | * OMAP15xx specific gpio init |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ | 4 | * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ |
5 | * | 5 | * |
6 | * Author: | 6 | * Author: |
7 | * Charulatha V <charu@ti.com> | 7 | * Charulatha V <charu@ti.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU General Public License as | 10 | * modify it under the terms of the GNU General Public License as |
11 | * published by the Free Software Foundation version 2. | 11 | * published by the Free Software Foundation version 2. |
12 | * | 12 | * |
13 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | 13 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any |
14 | * kind, whether express or implied; without even the implied warranty | 14 | * kind, whether express or implied; without even the implied warranty |
15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
20 | 20 | ||
21 | #define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE | 21 | #define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE |
22 | #define OMAP1510_GPIO_BASE 0xFFFCE000 | 22 | #define OMAP1510_GPIO_BASE 0xFFFCE000 |
23 | 23 | ||
24 | /* gpio1 */ | 24 | /* gpio1 */ |
25 | static struct __initdata resource omap15xx_mpu_gpio_resources[] = { | 25 | static struct __initdata resource omap15xx_mpu_gpio_resources[] = { |
26 | { | 26 | { |
27 | .start = OMAP1_MPUIO_VBASE, | 27 | .start = OMAP1_MPUIO_VBASE, |
28 | .end = OMAP1_MPUIO_VBASE + SZ_2K - 1, | 28 | .end = OMAP1_MPUIO_VBASE + SZ_2K - 1, |
29 | .flags = IORESOURCE_MEM, | 29 | .flags = IORESOURCE_MEM, |
30 | }, | 30 | }, |
31 | { | 31 | { |
32 | .start = INT_MPUIO, | 32 | .start = INT_MPUIO, |
33 | .flags = IORESOURCE_IRQ, | 33 | .flags = IORESOURCE_IRQ, |
34 | }, | 34 | }, |
35 | }; | 35 | }; |
36 | 36 | ||
37 | static struct omap_gpio_reg_offs omap15xx_mpuio_regs = { | 37 | static struct omap_gpio_reg_offs omap15xx_mpuio_regs = { |
38 | .revision = USHRT_MAX, | ||
38 | .direction = OMAP_MPUIO_IO_CNTL, | 39 | .direction = OMAP_MPUIO_IO_CNTL, |
39 | .datain = OMAP_MPUIO_INPUT_LATCH, | 40 | .datain = OMAP_MPUIO_INPUT_LATCH, |
40 | .dataout = OMAP_MPUIO_OUTPUT, | 41 | .dataout = OMAP_MPUIO_OUTPUT, |
41 | .irqstatus = OMAP_MPUIO_GPIO_INT, | 42 | .irqstatus = OMAP_MPUIO_GPIO_INT, |
42 | .irqenable = OMAP_MPUIO_GPIO_MASKIT, | 43 | .irqenable = OMAP_MPUIO_GPIO_MASKIT, |
43 | .irqenable_inv = true, | 44 | .irqenable_inv = true, |
44 | }; | 45 | }; |
45 | 46 | ||
46 | static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = { | 47 | static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = { |
47 | .virtual_irq_start = IH_MPUIO_BASE, | 48 | .virtual_irq_start = IH_MPUIO_BASE, |
48 | .bank_type = METHOD_MPUIO, | 49 | .bank_type = METHOD_MPUIO, |
49 | .bank_width = 16, | 50 | .bank_width = 16, |
50 | .bank_stride = 1, | 51 | .bank_stride = 1, |
51 | .regs = &omap15xx_mpuio_regs, | 52 | .regs = &omap15xx_mpuio_regs, |
52 | }; | 53 | }; |
53 | 54 | ||
54 | static struct __initdata platform_device omap15xx_mpu_gpio = { | 55 | static struct __initdata platform_device omap15xx_mpu_gpio = { |
55 | .name = "omap_gpio", | 56 | .name = "omap_gpio", |
56 | .id = 0, | 57 | .id = 0, |
57 | .dev = { | 58 | .dev = { |
58 | .platform_data = &omap15xx_mpu_gpio_config, | 59 | .platform_data = &omap15xx_mpu_gpio_config, |
59 | }, | 60 | }, |
60 | .num_resources = ARRAY_SIZE(omap15xx_mpu_gpio_resources), | 61 | .num_resources = ARRAY_SIZE(omap15xx_mpu_gpio_resources), |
61 | .resource = omap15xx_mpu_gpio_resources, | 62 | .resource = omap15xx_mpu_gpio_resources, |
62 | }; | 63 | }; |
63 | 64 | ||
64 | /* gpio2 */ | 65 | /* gpio2 */ |
65 | static struct __initdata resource omap15xx_gpio_resources[] = { | 66 | static struct __initdata resource omap15xx_gpio_resources[] = { |
66 | { | 67 | { |
67 | .start = OMAP1510_GPIO_BASE, | 68 | .start = OMAP1510_GPIO_BASE, |
68 | .end = OMAP1510_GPIO_BASE + SZ_2K - 1, | 69 | .end = OMAP1510_GPIO_BASE + SZ_2K - 1, |
69 | .flags = IORESOURCE_MEM, | 70 | .flags = IORESOURCE_MEM, |
70 | }, | 71 | }, |
71 | { | 72 | { |
72 | .start = INT_GPIO_BANK1, | 73 | .start = INT_GPIO_BANK1, |
73 | .flags = IORESOURCE_IRQ, | 74 | .flags = IORESOURCE_IRQ, |
74 | }, | 75 | }, |
75 | }; | 76 | }; |
76 | 77 | ||
77 | static struct omap_gpio_reg_offs omap15xx_gpio_regs = { | 78 | static struct omap_gpio_reg_offs omap15xx_gpio_regs = { |
79 | .revision = USHRT_MAX, | ||
78 | .direction = OMAP1510_GPIO_DIR_CONTROL, | 80 | .direction = OMAP1510_GPIO_DIR_CONTROL, |
79 | .datain = OMAP1510_GPIO_DATA_INPUT, | 81 | .datain = OMAP1510_GPIO_DATA_INPUT, |
80 | .dataout = OMAP1510_GPIO_DATA_OUTPUT, | 82 | .dataout = OMAP1510_GPIO_DATA_OUTPUT, |
81 | .irqstatus = OMAP1510_GPIO_INT_STATUS, | 83 | .irqstatus = OMAP1510_GPIO_INT_STATUS, |
82 | .irqenable = OMAP1510_GPIO_INT_MASK, | 84 | .irqenable = OMAP1510_GPIO_INT_MASK, |
83 | .irqenable_inv = true, | 85 | .irqenable_inv = true, |
84 | }; | 86 | }; |
85 | 87 | ||
86 | static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = { | 88 | static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = { |
87 | .virtual_irq_start = IH_GPIO_BASE, | 89 | .virtual_irq_start = IH_GPIO_BASE, |
88 | .bank_type = METHOD_GPIO_1510, | 90 | .bank_type = METHOD_GPIO_1510, |
89 | .bank_width = 16, | 91 | .bank_width = 16, |
90 | .regs = &omap15xx_gpio_regs, | 92 | .regs = &omap15xx_gpio_regs, |
91 | }; | 93 | }; |
92 | 94 | ||
93 | static struct __initdata platform_device omap15xx_gpio = { | 95 | static struct __initdata platform_device omap15xx_gpio = { |
94 | .name = "omap_gpio", | 96 | .name = "omap_gpio", |
95 | .id = 1, | 97 | .id = 1, |
96 | .dev = { | 98 | .dev = { |
97 | .platform_data = &omap15xx_gpio_config, | 99 | .platform_data = &omap15xx_gpio_config, |
98 | }, | 100 | }, |
99 | .num_resources = ARRAY_SIZE(omap15xx_gpio_resources), | 101 | .num_resources = ARRAY_SIZE(omap15xx_gpio_resources), |
100 | .resource = omap15xx_gpio_resources, | 102 | .resource = omap15xx_gpio_resources, |
101 | }; | 103 | }; |
102 | 104 | ||
103 | /* | 105 | /* |
104 | * omap15xx_gpio_init needs to be done before | 106 | * omap15xx_gpio_init needs to be done before |
105 | * machine_init functions access gpio APIs. | 107 | * machine_init functions access gpio APIs. |
106 | * Hence omap15xx_gpio_init is a postcore_initcall. | 108 | * Hence omap15xx_gpio_init is a postcore_initcall. |
107 | */ | 109 | */ |
108 | static int __init omap15xx_gpio_init(void) | 110 | static int __init omap15xx_gpio_init(void) |
109 | { | 111 | { |
110 | if (!cpu_is_omap15xx()) | 112 | if (!cpu_is_omap15xx()) |
111 | return -EINVAL; | 113 | return -EINVAL; |
112 | 114 | ||
113 | platform_device_register(&omap15xx_mpu_gpio); | 115 | platform_device_register(&omap15xx_mpu_gpio); |
114 | platform_device_register(&omap15xx_gpio); | 116 | platform_device_register(&omap15xx_gpio); |
115 | 117 | ||
116 | gpio_bank_count = 2; | 118 | gpio_bank_count = 2; |
117 | return 0; | 119 | return 0; |
118 | } | 120 | } |
119 | postcore_initcall(omap15xx_gpio_init); | 121 | postcore_initcall(omap15xx_gpio_init); |
120 | 122 |
arch/arm/mach-omap1/gpio16xx.c
1 | /* | 1 | /* |
2 | * OMAP16xx specific gpio init | 2 | * OMAP16xx specific gpio init |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ | 4 | * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ |
5 | * | 5 | * |
6 | * Author: | 6 | * Author: |
7 | * Charulatha V <charu@ti.com> | 7 | * Charulatha V <charu@ti.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU General Public License as | 10 | * modify it under the terms of the GNU General Public License as |
11 | * published by the Free Software Foundation version 2. | 11 | * published by the Free Software Foundation version 2. |
12 | * | 12 | * |
13 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | 13 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any |
14 | * kind, whether express or implied; without even the implied warranty | 14 | * kind, whether express or implied; without even the implied warranty |
15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
20 | 20 | ||
21 | #define OMAP1610_GPIO1_BASE 0xfffbe400 | 21 | #define OMAP1610_GPIO1_BASE 0xfffbe400 |
22 | #define OMAP1610_GPIO2_BASE 0xfffbec00 | 22 | #define OMAP1610_GPIO2_BASE 0xfffbec00 |
23 | #define OMAP1610_GPIO3_BASE 0xfffbb400 | 23 | #define OMAP1610_GPIO3_BASE 0xfffbb400 |
24 | #define OMAP1610_GPIO4_BASE 0xfffbbc00 | 24 | #define OMAP1610_GPIO4_BASE 0xfffbbc00 |
25 | #define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE | 25 | #define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE |
26 | 26 | ||
27 | /* mpu gpio */ | 27 | /* mpu gpio */ |
28 | static struct __initdata resource omap16xx_mpu_gpio_resources[] = { | 28 | static struct __initdata resource omap16xx_mpu_gpio_resources[] = { |
29 | { | 29 | { |
30 | .start = OMAP1_MPUIO_VBASE, | 30 | .start = OMAP1_MPUIO_VBASE, |
31 | .end = OMAP1_MPUIO_VBASE + SZ_2K - 1, | 31 | .end = OMAP1_MPUIO_VBASE + SZ_2K - 1, |
32 | .flags = IORESOURCE_MEM, | 32 | .flags = IORESOURCE_MEM, |
33 | }, | 33 | }, |
34 | { | 34 | { |
35 | .start = INT_MPUIO, | 35 | .start = INT_MPUIO, |
36 | .flags = IORESOURCE_IRQ, | 36 | .flags = IORESOURCE_IRQ, |
37 | }, | 37 | }, |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static struct omap_gpio_reg_offs omap16xx_mpuio_regs = { | 40 | static struct omap_gpio_reg_offs omap16xx_mpuio_regs = { |
41 | .revision = USHRT_MAX, | ||
41 | .direction = OMAP_MPUIO_IO_CNTL, | 42 | .direction = OMAP_MPUIO_IO_CNTL, |
42 | .datain = OMAP_MPUIO_INPUT_LATCH, | 43 | .datain = OMAP_MPUIO_INPUT_LATCH, |
43 | .dataout = OMAP_MPUIO_OUTPUT, | 44 | .dataout = OMAP_MPUIO_OUTPUT, |
44 | .irqstatus = OMAP_MPUIO_GPIO_INT, | 45 | .irqstatus = OMAP_MPUIO_GPIO_INT, |
45 | .irqenable = OMAP_MPUIO_GPIO_MASKIT, | 46 | .irqenable = OMAP_MPUIO_GPIO_MASKIT, |
46 | .irqenable_inv = true, | 47 | .irqenable_inv = true, |
47 | }; | 48 | }; |
48 | 49 | ||
49 | static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = { | 50 | static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = { |
50 | .virtual_irq_start = IH_MPUIO_BASE, | 51 | .virtual_irq_start = IH_MPUIO_BASE, |
51 | .bank_type = METHOD_MPUIO, | 52 | .bank_type = METHOD_MPUIO, |
52 | .bank_width = 16, | 53 | .bank_width = 16, |
53 | .bank_stride = 1, | 54 | .bank_stride = 1, |
54 | .regs = &omap16xx_mpuio_regs, | 55 | .regs = &omap16xx_mpuio_regs, |
55 | }; | 56 | }; |
56 | 57 | ||
57 | static struct __initdata platform_device omap16xx_mpu_gpio = { | 58 | static struct __initdata platform_device omap16xx_mpu_gpio = { |
58 | .name = "omap_gpio", | 59 | .name = "omap_gpio", |
59 | .id = 0, | 60 | .id = 0, |
60 | .dev = { | 61 | .dev = { |
61 | .platform_data = &omap16xx_mpu_gpio_config, | 62 | .platform_data = &omap16xx_mpu_gpio_config, |
62 | }, | 63 | }, |
63 | .num_resources = ARRAY_SIZE(omap16xx_mpu_gpio_resources), | 64 | .num_resources = ARRAY_SIZE(omap16xx_mpu_gpio_resources), |
64 | .resource = omap16xx_mpu_gpio_resources, | 65 | .resource = omap16xx_mpu_gpio_resources, |
65 | }; | 66 | }; |
66 | 67 | ||
67 | /* gpio1 */ | 68 | /* gpio1 */ |
68 | static struct __initdata resource omap16xx_gpio1_resources[] = { | 69 | static struct __initdata resource omap16xx_gpio1_resources[] = { |
69 | { | 70 | { |
70 | .start = OMAP1610_GPIO1_BASE, | 71 | .start = OMAP1610_GPIO1_BASE, |
71 | .end = OMAP1610_GPIO1_BASE + SZ_2K - 1, | 72 | .end = OMAP1610_GPIO1_BASE + SZ_2K - 1, |
72 | .flags = IORESOURCE_MEM, | 73 | .flags = IORESOURCE_MEM, |
73 | }, | 74 | }, |
74 | { | 75 | { |
75 | .start = INT_GPIO_BANK1, | 76 | .start = INT_GPIO_BANK1, |
76 | .flags = IORESOURCE_IRQ, | 77 | .flags = IORESOURCE_IRQ, |
77 | }, | 78 | }, |
78 | }; | 79 | }; |
79 | 80 | ||
80 | static struct omap_gpio_reg_offs omap16xx_gpio_regs = { | 81 | static struct omap_gpio_reg_offs omap16xx_gpio_regs = { |
82 | .revision = OMAP1610_GPIO_REVISION, | ||
81 | .direction = OMAP1610_GPIO_DIRECTION, | 83 | .direction = OMAP1610_GPIO_DIRECTION, |
82 | .set_dataout = OMAP1610_GPIO_SET_DATAOUT, | 84 | .set_dataout = OMAP1610_GPIO_SET_DATAOUT, |
83 | .clr_dataout = OMAP1610_GPIO_CLEAR_DATAOUT, | 85 | .clr_dataout = OMAP1610_GPIO_CLEAR_DATAOUT, |
84 | .datain = OMAP1610_GPIO_DATAIN, | 86 | .datain = OMAP1610_GPIO_DATAIN, |
85 | .dataout = OMAP1610_GPIO_DATAOUT, | 87 | .dataout = OMAP1610_GPIO_DATAOUT, |
86 | .irqstatus = OMAP1610_GPIO_IRQSTATUS1, | 88 | .irqstatus = OMAP1610_GPIO_IRQSTATUS1, |
87 | .irqenable = OMAP1610_GPIO_IRQENABLE1, | 89 | .irqenable = OMAP1610_GPIO_IRQENABLE1, |
88 | .set_irqenable = OMAP1610_GPIO_SET_IRQENABLE1, | 90 | .set_irqenable = OMAP1610_GPIO_SET_IRQENABLE1, |
89 | .clr_irqenable = OMAP1610_GPIO_CLEAR_IRQENABLE1, | 91 | .clr_irqenable = OMAP1610_GPIO_CLEAR_IRQENABLE1, |
90 | }; | 92 | }; |
91 | 93 | ||
92 | static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = { | 94 | static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = { |
93 | .virtual_irq_start = IH_GPIO_BASE, | 95 | .virtual_irq_start = IH_GPIO_BASE, |
94 | .bank_type = METHOD_GPIO_1610, | 96 | .bank_type = METHOD_GPIO_1610, |
95 | .bank_width = 16, | 97 | .bank_width = 16, |
96 | .regs = &omap16xx_gpio_regs, | 98 | .regs = &omap16xx_gpio_regs, |
97 | }; | 99 | }; |
98 | 100 | ||
99 | static struct __initdata platform_device omap16xx_gpio1 = { | 101 | static struct __initdata platform_device omap16xx_gpio1 = { |
100 | .name = "omap_gpio", | 102 | .name = "omap_gpio", |
101 | .id = 1, | 103 | .id = 1, |
102 | .dev = { | 104 | .dev = { |
103 | .platform_data = &omap16xx_gpio1_config, | 105 | .platform_data = &omap16xx_gpio1_config, |
104 | }, | 106 | }, |
105 | .num_resources = ARRAY_SIZE(omap16xx_gpio1_resources), | 107 | .num_resources = ARRAY_SIZE(omap16xx_gpio1_resources), |
106 | .resource = omap16xx_gpio1_resources, | 108 | .resource = omap16xx_gpio1_resources, |
107 | }; | 109 | }; |
108 | 110 | ||
109 | /* gpio2 */ | 111 | /* gpio2 */ |
110 | static struct __initdata resource omap16xx_gpio2_resources[] = { | 112 | static struct __initdata resource omap16xx_gpio2_resources[] = { |
111 | { | 113 | { |
112 | .start = OMAP1610_GPIO2_BASE, | 114 | .start = OMAP1610_GPIO2_BASE, |
113 | .end = OMAP1610_GPIO2_BASE + SZ_2K - 1, | 115 | .end = OMAP1610_GPIO2_BASE + SZ_2K - 1, |
114 | .flags = IORESOURCE_MEM, | 116 | .flags = IORESOURCE_MEM, |
115 | }, | 117 | }, |
116 | { | 118 | { |
117 | .start = INT_1610_GPIO_BANK2, | 119 | .start = INT_1610_GPIO_BANK2, |
118 | .flags = IORESOURCE_IRQ, | 120 | .flags = IORESOURCE_IRQ, |
119 | }, | 121 | }, |
120 | }; | 122 | }; |
121 | 123 | ||
122 | static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = { | 124 | static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = { |
123 | .virtual_irq_start = IH_GPIO_BASE + 16, | 125 | .virtual_irq_start = IH_GPIO_BASE + 16, |
124 | .bank_type = METHOD_GPIO_1610, | 126 | .bank_type = METHOD_GPIO_1610, |
125 | .bank_width = 16, | 127 | .bank_width = 16, |
126 | .regs = &omap16xx_gpio_regs, | 128 | .regs = &omap16xx_gpio_regs, |
127 | }; | 129 | }; |
128 | 130 | ||
129 | static struct __initdata platform_device omap16xx_gpio2 = { | 131 | static struct __initdata platform_device omap16xx_gpio2 = { |
130 | .name = "omap_gpio", | 132 | .name = "omap_gpio", |
131 | .id = 2, | 133 | .id = 2, |
132 | .dev = { | 134 | .dev = { |
133 | .platform_data = &omap16xx_gpio2_config, | 135 | .platform_data = &omap16xx_gpio2_config, |
134 | }, | 136 | }, |
135 | .num_resources = ARRAY_SIZE(omap16xx_gpio2_resources), | 137 | .num_resources = ARRAY_SIZE(omap16xx_gpio2_resources), |
136 | .resource = omap16xx_gpio2_resources, | 138 | .resource = omap16xx_gpio2_resources, |
137 | }; | 139 | }; |
138 | 140 | ||
139 | /* gpio3 */ | 141 | /* gpio3 */ |
140 | static struct __initdata resource omap16xx_gpio3_resources[] = { | 142 | static struct __initdata resource omap16xx_gpio3_resources[] = { |
141 | { | 143 | { |
142 | .start = OMAP1610_GPIO3_BASE, | 144 | .start = OMAP1610_GPIO3_BASE, |
143 | .end = OMAP1610_GPIO3_BASE + SZ_2K - 1, | 145 | .end = OMAP1610_GPIO3_BASE + SZ_2K - 1, |
144 | .flags = IORESOURCE_MEM, | 146 | .flags = IORESOURCE_MEM, |
145 | }, | 147 | }, |
146 | { | 148 | { |
147 | .start = INT_1610_GPIO_BANK3, | 149 | .start = INT_1610_GPIO_BANK3, |
148 | .flags = IORESOURCE_IRQ, | 150 | .flags = IORESOURCE_IRQ, |
149 | }, | 151 | }, |
150 | }; | 152 | }; |
151 | 153 | ||
152 | static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = { | 154 | static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = { |
153 | .virtual_irq_start = IH_GPIO_BASE + 32, | 155 | .virtual_irq_start = IH_GPIO_BASE + 32, |
154 | .bank_type = METHOD_GPIO_1610, | 156 | .bank_type = METHOD_GPIO_1610, |
155 | .bank_width = 16, | 157 | .bank_width = 16, |
156 | .regs = &omap16xx_gpio_regs, | 158 | .regs = &omap16xx_gpio_regs, |
157 | }; | 159 | }; |
158 | 160 | ||
159 | static struct __initdata platform_device omap16xx_gpio3 = { | 161 | static struct __initdata platform_device omap16xx_gpio3 = { |
160 | .name = "omap_gpio", | 162 | .name = "omap_gpio", |
161 | .id = 3, | 163 | .id = 3, |
162 | .dev = { | 164 | .dev = { |
163 | .platform_data = &omap16xx_gpio3_config, | 165 | .platform_data = &omap16xx_gpio3_config, |
164 | }, | 166 | }, |
165 | .num_resources = ARRAY_SIZE(omap16xx_gpio3_resources), | 167 | .num_resources = ARRAY_SIZE(omap16xx_gpio3_resources), |
166 | .resource = omap16xx_gpio3_resources, | 168 | .resource = omap16xx_gpio3_resources, |
167 | }; | 169 | }; |
168 | 170 | ||
169 | /* gpio4 */ | 171 | /* gpio4 */ |
170 | static struct __initdata resource omap16xx_gpio4_resources[] = { | 172 | static struct __initdata resource omap16xx_gpio4_resources[] = { |
171 | { | 173 | { |
172 | .start = OMAP1610_GPIO4_BASE, | 174 | .start = OMAP1610_GPIO4_BASE, |
173 | .end = OMAP1610_GPIO4_BASE + SZ_2K - 1, | 175 | .end = OMAP1610_GPIO4_BASE + SZ_2K - 1, |
174 | .flags = IORESOURCE_MEM, | 176 | .flags = IORESOURCE_MEM, |
175 | }, | 177 | }, |
176 | { | 178 | { |
177 | .start = INT_1610_GPIO_BANK4, | 179 | .start = INT_1610_GPIO_BANK4, |
178 | .flags = IORESOURCE_IRQ, | 180 | .flags = IORESOURCE_IRQ, |
179 | }, | 181 | }, |
180 | }; | 182 | }; |
181 | 183 | ||
182 | static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = { | 184 | static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = { |
183 | .virtual_irq_start = IH_GPIO_BASE + 48, | 185 | .virtual_irq_start = IH_GPIO_BASE + 48, |
184 | .bank_type = METHOD_GPIO_1610, | 186 | .bank_type = METHOD_GPIO_1610, |
185 | .bank_width = 16, | 187 | .bank_width = 16, |
186 | .regs = &omap16xx_gpio_regs, | 188 | .regs = &omap16xx_gpio_regs, |
187 | }; | 189 | }; |
188 | 190 | ||
189 | static struct __initdata platform_device omap16xx_gpio4 = { | 191 | static struct __initdata platform_device omap16xx_gpio4 = { |
190 | .name = "omap_gpio", | 192 | .name = "omap_gpio", |
191 | .id = 4, | 193 | .id = 4, |
192 | .dev = { | 194 | .dev = { |
193 | .platform_data = &omap16xx_gpio4_config, | 195 | .platform_data = &omap16xx_gpio4_config, |
194 | }, | 196 | }, |
195 | .num_resources = ARRAY_SIZE(omap16xx_gpio4_resources), | 197 | .num_resources = ARRAY_SIZE(omap16xx_gpio4_resources), |
196 | .resource = omap16xx_gpio4_resources, | 198 | .resource = omap16xx_gpio4_resources, |
197 | }; | 199 | }; |
198 | 200 | ||
199 | static struct __initdata platform_device * omap16xx_gpio_dev[] = { | 201 | static struct __initdata platform_device * omap16xx_gpio_dev[] = { |
200 | &omap16xx_mpu_gpio, | 202 | &omap16xx_mpu_gpio, |
201 | &omap16xx_gpio1, | 203 | &omap16xx_gpio1, |
202 | &omap16xx_gpio2, | 204 | &omap16xx_gpio2, |
203 | &omap16xx_gpio3, | 205 | &omap16xx_gpio3, |
204 | &omap16xx_gpio4, | 206 | &omap16xx_gpio4, |
205 | }; | 207 | }; |
206 | 208 | ||
207 | /* | 209 | /* |
208 | * omap16xx_gpio_init needs to be done before | 210 | * omap16xx_gpio_init needs to be done before |
209 | * machine_init functions access gpio APIs. | 211 | * machine_init functions access gpio APIs. |
210 | * Hence omap16xx_gpio_init is a postcore_initcall. | 212 | * Hence omap16xx_gpio_init is a postcore_initcall. |
211 | */ | 213 | */ |
212 | static int __init omap16xx_gpio_init(void) | 214 | static int __init omap16xx_gpio_init(void) |
213 | { | 215 | { |
214 | int i; | 216 | int i; |
215 | 217 | ||
216 | if (!cpu_is_omap16xx()) | 218 | if (!cpu_is_omap16xx()) |
217 | return -EINVAL; | 219 | return -EINVAL; |
218 | 220 | ||
219 | for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++) | 221 | for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++) |
220 | platform_device_register(omap16xx_gpio_dev[i]); | 222 | platform_device_register(omap16xx_gpio_dev[i]); |
221 | 223 | ||
222 | gpio_bank_count = ARRAY_SIZE(omap16xx_gpio_dev); | 224 | gpio_bank_count = ARRAY_SIZE(omap16xx_gpio_dev); |
223 | 225 | ||
224 | return 0; | 226 | return 0; |
225 | } | 227 | } |
226 | postcore_initcall(omap16xx_gpio_init); | 228 | postcore_initcall(omap16xx_gpio_init); |
227 | 229 |
arch/arm/mach-omap1/gpio7xx.c
1 | /* | 1 | /* |
2 | * OMAP7xx specific gpio init | 2 | * OMAP7xx specific gpio init |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ | 4 | * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ |
5 | * | 5 | * |
6 | * Author: | 6 | * Author: |
7 | * Charulatha V <charu@ti.com> | 7 | * Charulatha V <charu@ti.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU General Public License as | 10 | * modify it under the terms of the GNU General Public License as |
11 | * published by the Free Software Foundation version 2. | 11 | * published by the Free Software Foundation version 2. |
12 | * | 12 | * |
13 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | 13 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any |
14 | * kind, whether express or implied; without even the implied warranty | 14 | * kind, whether express or implied; without even the implied warranty |
15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
20 | 20 | ||
21 | #define OMAP7XX_GPIO1_BASE 0xfffbc000 | 21 | #define OMAP7XX_GPIO1_BASE 0xfffbc000 |
22 | #define OMAP7XX_GPIO2_BASE 0xfffbc800 | 22 | #define OMAP7XX_GPIO2_BASE 0xfffbc800 |
23 | #define OMAP7XX_GPIO3_BASE 0xfffbd000 | 23 | #define OMAP7XX_GPIO3_BASE 0xfffbd000 |
24 | #define OMAP7XX_GPIO4_BASE 0xfffbd800 | 24 | #define OMAP7XX_GPIO4_BASE 0xfffbd800 |
25 | #define OMAP7XX_GPIO5_BASE 0xfffbe000 | 25 | #define OMAP7XX_GPIO5_BASE 0xfffbe000 |
26 | #define OMAP7XX_GPIO6_BASE 0xfffbe800 | 26 | #define OMAP7XX_GPIO6_BASE 0xfffbe800 |
27 | #define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE | 27 | #define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE |
28 | 28 | ||
29 | /* mpu gpio */ | 29 | /* mpu gpio */ |
30 | static struct __initdata resource omap7xx_mpu_gpio_resources[] = { | 30 | static struct __initdata resource omap7xx_mpu_gpio_resources[] = { |
31 | { | 31 | { |
32 | .start = OMAP1_MPUIO_VBASE, | 32 | .start = OMAP1_MPUIO_VBASE, |
33 | .end = OMAP1_MPUIO_VBASE + SZ_2K - 1, | 33 | .end = OMAP1_MPUIO_VBASE + SZ_2K - 1, |
34 | .flags = IORESOURCE_MEM, | 34 | .flags = IORESOURCE_MEM, |
35 | }, | 35 | }, |
36 | { | 36 | { |
37 | .start = INT_7XX_MPUIO, | 37 | .start = INT_7XX_MPUIO, |
38 | .flags = IORESOURCE_IRQ, | 38 | .flags = IORESOURCE_IRQ, |
39 | }, | 39 | }, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | static struct omap_gpio_reg_offs omap7xx_mpuio_regs = { | 42 | static struct omap_gpio_reg_offs omap7xx_mpuio_regs = { |
43 | .revision = USHRT_MAX, | ||
43 | .direction = OMAP_MPUIO_IO_CNTL / 2, | 44 | .direction = OMAP_MPUIO_IO_CNTL / 2, |
44 | .datain = OMAP_MPUIO_INPUT_LATCH / 2, | 45 | .datain = OMAP_MPUIO_INPUT_LATCH / 2, |
45 | .dataout = OMAP_MPUIO_OUTPUT / 2, | 46 | .dataout = OMAP_MPUIO_OUTPUT / 2, |
46 | .irqstatus = OMAP_MPUIO_GPIO_INT / 2, | 47 | .irqstatus = OMAP_MPUIO_GPIO_INT / 2, |
47 | .irqenable = OMAP_MPUIO_GPIO_MASKIT / 2, | 48 | .irqenable = OMAP_MPUIO_GPIO_MASKIT / 2, |
48 | .irqenable_inv = true, | 49 | .irqenable_inv = true, |
49 | }; | 50 | }; |
50 | 51 | ||
51 | static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = { | 52 | static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = { |
52 | .virtual_irq_start = IH_MPUIO_BASE, | 53 | .virtual_irq_start = IH_MPUIO_BASE, |
53 | .bank_type = METHOD_MPUIO, | 54 | .bank_type = METHOD_MPUIO, |
54 | .bank_width = 32, | 55 | .bank_width = 32, |
55 | .bank_stride = 2, | 56 | .bank_stride = 2, |
56 | .regs = &omap7xx_mpuio_regs, | 57 | .regs = &omap7xx_mpuio_regs, |
57 | }; | 58 | }; |
58 | 59 | ||
59 | static struct __initdata platform_device omap7xx_mpu_gpio = { | 60 | static struct __initdata platform_device omap7xx_mpu_gpio = { |
60 | .name = "omap_gpio", | 61 | .name = "omap_gpio", |
61 | .id = 0, | 62 | .id = 0, |
62 | .dev = { | 63 | .dev = { |
63 | .platform_data = &omap7xx_mpu_gpio_config, | 64 | .platform_data = &omap7xx_mpu_gpio_config, |
64 | }, | 65 | }, |
65 | .num_resources = ARRAY_SIZE(omap7xx_mpu_gpio_resources), | 66 | .num_resources = ARRAY_SIZE(omap7xx_mpu_gpio_resources), |
66 | .resource = omap7xx_mpu_gpio_resources, | 67 | .resource = omap7xx_mpu_gpio_resources, |
67 | }; | 68 | }; |
68 | 69 | ||
69 | /* gpio1 */ | 70 | /* gpio1 */ |
70 | static struct __initdata resource omap7xx_gpio1_resources[] = { | 71 | static struct __initdata resource omap7xx_gpio1_resources[] = { |
71 | { | 72 | { |
72 | .start = OMAP7XX_GPIO1_BASE, | 73 | .start = OMAP7XX_GPIO1_BASE, |
73 | .end = OMAP7XX_GPIO1_BASE + SZ_2K - 1, | 74 | .end = OMAP7XX_GPIO1_BASE + SZ_2K - 1, |
74 | .flags = IORESOURCE_MEM, | 75 | .flags = IORESOURCE_MEM, |
75 | }, | 76 | }, |
76 | { | 77 | { |
77 | .start = INT_7XX_GPIO_BANK1, | 78 | .start = INT_7XX_GPIO_BANK1, |
78 | .flags = IORESOURCE_IRQ, | 79 | .flags = IORESOURCE_IRQ, |
79 | }, | 80 | }, |
80 | }; | 81 | }; |
81 | 82 | ||
82 | static struct omap_gpio_reg_offs omap7xx_gpio_regs = { | 83 | static struct omap_gpio_reg_offs omap7xx_gpio_regs = { |
84 | .revision = USHRT_MAX, | ||
83 | .direction = OMAP7XX_GPIO_DIR_CONTROL, | 85 | .direction = OMAP7XX_GPIO_DIR_CONTROL, |
84 | .datain = OMAP7XX_GPIO_DATA_INPUT, | 86 | .datain = OMAP7XX_GPIO_DATA_INPUT, |
85 | .dataout = OMAP7XX_GPIO_DATA_OUTPUT, | 87 | .dataout = OMAP7XX_GPIO_DATA_OUTPUT, |
86 | .irqstatus = OMAP7XX_GPIO_INT_STATUS, | 88 | .irqstatus = OMAP7XX_GPIO_INT_STATUS, |
87 | .irqenable = OMAP7XX_GPIO_INT_MASK, | 89 | .irqenable = OMAP7XX_GPIO_INT_MASK, |
88 | .irqenable_inv = true, | 90 | .irqenable_inv = true, |
89 | }; | 91 | }; |
90 | 92 | ||
91 | static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = { | 93 | static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = { |
92 | .virtual_irq_start = IH_GPIO_BASE, | 94 | .virtual_irq_start = IH_GPIO_BASE, |
93 | .bank_type = METHOD_GPIO_7XX, | 95 | .bank_type = METHOD_GPIO_7XX, |
94 | .bank_width = 32, | 96 | .bank_width = 32, |
95 | .regs = &omap7xx_gpio_regs, | 97 | .regs = &omap7xx_gpio_regs, |
96 | }; | 98 | }; |
97 | 99 | ||
98 | static struct __initdata platform_device omap7xx_gpio1 = { | 100 | static struct __initdata platform_device omap7xx_gpio1 = { |
99 | .name = "omap_gpio", | 101 | .name = "omap_gpio", |
100 | .id = 1, | 102 | .id = 1, |
101 | .dev = { | 103 | .dev = { |
102 | .platform_data = &omap7xx_gpio1_config, | 104 | .platform_data = &omap7xx_gpio1_config, |
103 | }, | 105 | }, |
104 | .num_resources = ARRAY_SIZE(omap7xx_gpio1_resources), | 106 | .num_resources = ARRAY_SIZE(omap7xx_gpio1_resources), |
105 | .resource = omap7xx_gpio1_resources, | 107 | .resource = omap7xx_gpio1_resources, |
106 | }; | 108 | }; |
107 | 109 | ||
108 | /* gpio2 */ | 110 | /* gpio2 */ |
109 | static struct __initdata resource omap7xx_gpio2_resources[] = { | 111 | static struct __initdata resource omap7xx_gpio2_resources[] = { |
110 | { | 112 | { |
111 | .start = OMAP7XX_GPIO2_BASE, | 113 | .start = OMAP7XX_GPIO2_BASE, |
112 | .end = OMAP7XX_GPIO2_BASE + SZ_2K - 1, | 114 | .end = OMAP7XX_GPIO2_BASE + SZ_2K - 1, |
113 | .flags = IORESOURCE_MEM, | 115 | .flags = IORESOURCE_MEM, |
114 | }, | 116 | }, |
115 | { | 117 | { |
116 | .start = INT_7XX_GPIO_BANK2, | 118 | .start = INT_7XX_GPIO_BANK2, |
117 | .flags = IORESOURCE_IRQ, | 119 | .flags = IORESOURCE_IRQ, |
118 | }, | 120 | }, |
119 | }; | 121 | }; |
120 | 122 | ||
121 | static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = { | 123 | static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = { |
122 | .virtual_irq_start = IH_GPIO_BASE + 32, | 124 | .virtual_irq_start = IH_GPIO_BASE + 32, |
123 | .bank_type = METHOD_GPIO_7XX, | 125 | .bank_type = METHOD_GPIO_7XX, |
124 | .bank_width = 32, | 126 | .bank_width = 32, |
125 | .regs = &omap7xx_gpio_regs, | 127 | .regs = &omap7xx_gpio_regs, |
126 | }; | 128 | }; |
127 | 129 | ||
128 | static struct __initdata platform_device omap7xx_gpio2 = { | 130 | static struct __initdata platform_device omap7xx_gpio2 = { |
129 | .name = "omap_gpio", | 131 | .name = "omap_gpio", |
130 | .id = 2, | 132 | .id = 2, |
131 | .dev = { | 133 | .dev = { |
132 | .platform_data = &omap7xx_gpio2_config, | 134 | .platform_data = &omap7xx_gpio2_config, |
133 | }, | 135 | }, |
134 | .num_resources = ARRAY_SIZE(omap7xx_gpio2_resources), | 136 | .num_resources = ARRAY_SIZE(omap7xx_gpio2_resources), |
135 | .resource = omap7xx_gpio2_resources, | 137 | .resource = omap7xx_gpio2_resources, |
136 | }; | 138 | }; |
137 | 139 | ||
138 | /* gpio3 */ | 140 | /* gpio3 */ |
139 | static struct __initdata resource omap7xx_gpio3_resources[] = { | 141 | static struct __initdata resource omap7xx_gpio3_resources[] = { |
140 | { | 142 | { |
141 | .start = OMAP7XX_GPIO3_BASE, | 143 | .start = OMAP7XX_GPIO3_BASE, |
142 | .end = OMAP7XX_GPIO3_BASE + SZ_2K - 1, | 144 | .end = OMAP7XX_GPIO3_BASE + SZ_2K - 1, |
143 | .flags = IORESOURCE_MEM, | 145 | .flags = IORESOURCE_MEM, |
144 | }, | 146 | }, |
145 | { | 147 | { |
146 | .start = INT_7XX_GPIO_BANK3, | 148 | .start = INT_7XX_GPIO_BANK3, |
147 | .flags = IORESOURCE_IRQ, | 149 | .flags = IORESOURCE_IRQ, |
148 | }, | 150 | }, |
149 | }; | 151 | }; |
150 | 152 | ||
151 | static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = { | 153 | static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = { |
152 | .virtual_irq_start = IH_GPIO_BASE + 64, | 154 | .virtual_irq_start = IH_GPIO_BASE + 64, |
153 | .bank_type = METHOD_GPIO_7XX, | 155 | .bank_type = METHOD_GPIO_7XX, |
154 | .bank_width = 32, | 156 | .bank_width = 32, |
155 | .regs = &omap7xx_gpio_regs, | 157 | .regs = &omap7xx_gpio_regs, |
156 | }; | 158 | }; |
157 | 159 | ||
158 | static struct __initdata platform_device omap7xx_gpio3 = { | 160 | static struct __initdata platform_device omap7xx_gpio3 = { |
159 | .name = "omap_gpio", | 161 | .name = "omap_gpio", |
160 | .id = 3, | 162 | .id = 3, |
161 | .dev = { | 163 | .dev = { |
162 | .platform_data = &omap7xx_gpio3_config, | 164 | .platform_data = &omap7xx_gpio3_config, |
163 | }, | 165 | }, |
164 | .num_resources = ARRAY_SIZE(omap7xx_gpio3_resources), | 166 | .num_resources = ARRAY_SIZE(omap7xx_gpio3_resources), |
165 | .resource = omap7xx_gpio3_resources, | 167 | .resource = omap7xx_gpio3_resources, |
166 | }; | 168 | }; |
167 | 169 | ||
168 | /* gpio4 */ | 170 | /* gpio4 */ |
169 | static struct __initdata resource omap7xx_gpio4_resources[] = { | 171 | static struct __initdata resource omap7xx_gpio4_resources[] = { |
170 | { | 172 | { |
171 | .start = OMAP7XX_GPIO4_BASE, | 173 | .start = OMAP7XX_GPIO4_BASE, |
172 | .end = OMAP7XX_GPIO4_BASE + SZ_2K - 1, | 174 | .end = OMAP7XX_GPIO4_BASE + SZ_2K - 1, |
173 | .flags = IORESOURCE_MEM, | 175 | .flags = IORESOURCE_MEM, |
174 | }, | 176 | }, |
175 | { | 177 | { |
176 | .start = INT_7XX_GPIO_BANK4, | 178 | .start = INT_7XX_GPIO_BANK4, |
177 | .flags = IORESOURCE_IRQ, | 179 | .flags = IORESOURCE_IRQ, |
178 | }, | 180 | }, |
179 | }; | 181 | }; |
180 | 182 | ||
181 | static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = { | 183 | static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = { |
182 | .virtual_irq_start = IH_GPIO_BASE + 96, | 184 | .virtual_irq_start = IH_GPIO_BASE + 96, |
183 | .bank_type = METHOD_GPIO_7XX, | 185 | .bank_type = METHOD_GPIO_7XX, |
184 | .bank_width = 32, | 186 | .bank_width = 32, |
185 | .regs = &omap7xx_gpio_regs, | 187 | .regs = &omap7xx_gpio_regs, |
186 | }; | 188 | }; |
187 | 189 | ||
188 | static struct __initdata platform_device omap7xx_gpio4 = { | 190 | static struct __initdata platform_device omap7xx_gpio4 = { |
189 | .name = "omap_gpio", | 191 | .name = "omap_gpio", |
190 | .id = 4, | 192 | .id = 4, |
191 | .dev = { | 193 | .dev = { |
192 | .platform_data = &omap7xx_gpio4_config, | 194 | .platform_data = &omap7xx_gpio4_config, |
193 | }, | 195 | }, |
194 | .num_resources = ARRAY_SIZE(omap7xx_gpio4_resources), | 196 | .num_resources = ARRAY_SIZE(omap7xx_gpio4_resources), |
195 | .resource = omap7xx_gpio4_resources, | 197 | .resource = omap7xx_gpio4_resources, |
196 | }; | 198 | }; |
197 | 199 | ||
198 | /* gpio5 */ | 200 | /* gpio5 */ |
199 | static struct __initdata resource omap7xx_gpio5_resources[] = { | 201 | static struct __initdata resource omap7xx_gpio5_resources[] = { |
200 | { | 202 | { |
201 | .start = OMAP7XX_GPIO5_BASE, | 203 | .start = OMAP7XX_GPIO5_BASE, |
202 | .end = OMAP7XX_GPIO5_BASE + SZ_2K - 1, | 204 | .end = OMAP7XX_GPIO5_BASE + SZ_2K - 1, |
203 | .flags = IORESOURCE_MEM, | 205 | .flags = IORESOURCE_MEM, |
204 | }, | 206 | }, |
205 | { | 207 | { |
206 | .start = INT_7XX_GPIO_BANK5, | 208 | .start = INT_7XX_GPIO_BANK5, |
207 | .flags = IORESOURCE_IRQ, | 209 | .flags = IORESOURCE_IRQ, |
208 | }, | 210 | }, |
209 | }; | 211 | }; |
210 | 212 | ||
211 | static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = { | 213 | static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = { |
212 | .virtual_irq_start = IH_GPIO_BASE + 128, | 214 | .virtual_irq_start = IH_GPIO_BASE + 128, |
213 | .bank_type = METHOD_GPIO_7XX, | 215 | .bank_type = METHOD_GPIO_7XX, |
214 | .bank_width = 32, | 216 | .bank_width = 32, |
215 | .regs = &omap7xx_gpio_regs, | 217 | .regs = &omap7xx_gpio_regs, |
216 | }; | 218 | }; |
217 | 219 | ||
218 | static struct __initdata platform_device omap7xx_gpio5 = { | 220 | static struct __initdata platform_device omap7xx_gpio5 = { |
219 | .name = "omap_gpio", | 221 | .name = "omap_gpio", |
220 | .id = 5, | 222 | .id = 5, |
221 | .dev = { | 223 | .dev = { |
222 | .platform_data = &omap7xx_gpio5_config, | 224 | .platform_data = &omap7xx_gpio5_config, |
223 | }, | 225 | }, |
224 | .num_resources = ARRAY_SIZE(omap7xx_gpio5_resources), | 226 | .num_resources = ARRAY_SIZE(omap7xx_gpio5_resources), |
225 | .resource = omap7xx_gpio5_resources, | 227 | .resource = omap7xx_gpio5_resources, |
226 | }; | 228 | }; |
227 | 229 | ||
228 | /* gpio6 */ | 230 | /* gpio6 */ |
229 | static struct __initdata resource omap7xx_gpio6_resources[] = { | 231 | static struct __initdata resource omap7xx_gpio6_resources[] = { |
230 | { | 232 | { |
231 | .start = OMAP7XX_GPIO6_BASE, | 233 | .start = OMAP7XX_GPIO6_BASE, |
232 | .end = OMAP7XX_GPIO6_BASE + SZ_2K - 1, | 234 | .end = OMAP7XX_GPIO6_BASE + SZ_2K - 1, |
233 | .flags = IORESOURCE_MEM, | 235 | .flags = IORESOURCE_MEM, |
234 | }, | 236 | }, |
235 | { | 237 | { |
236 | .start = INT_7XX_GPIO_BANK6, | 238 | .start = INT_7XX_GPIO_BANK6, |
237 | .flags = IORESOURCE_IRQ, | 239 | .flags = IORESOURCE_IRQ, |
238 | }, | 240 | }, |
239 | }; | 241 | }; |
240 | 242 | ||
241 | static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = { | 243 | static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = { |
242 | .virtual_irq_start = IH_GPIO_BASE + 160, | 244 | .virtual_irq_start = IH_GPIO_BASE + 160, |
243 | .bank_type = METHOD_GPIO_7XX, | 245 | .bank_type = METHOD_GPIO_7XX, |
244 | .bank_width = 32, | 246 | .bank_width = 32, |
245 | .regs = &omap7xx_gpio_regs, | 247 | .regs = &omap7xx_gpio_regs, |
246 | }; | 248 | }; |
247 | 249 | ||
248 | static struct __initdata platform_device omap7xx_gpio6 = { | 250 | static struct __initdata platform_device omap7xx_gpio6 = { |
249 | .name = "omap_gpio", | 251 | .name = "omap_gpio", |
250 | .id = 6, | 252 | .id = 6, |
251 | .dev = { | 253 | .dev = { |
252 | .platform_data = &omap7xx_gpio6_config, | 254 | .platform_data = &omap7xx_gpio6_config, |
253 | }, | 255 | }, |
254 | .num_resources = ARRAY_SIZE(omap7xx_gpio6_resources), | 256 | .num_resources = ARRAY_SIZE(omap7xx_gpio6_resources), |
255 | .resource = omap7xx_gpio6_resources, | 257 | .resource = omap7xx_gpio6_resources, |
256 | }; | 258 | }; |
257 | 259 | ||
258 | static struct __initdata platform_device * omap7xx_gpio_dev[] = { | 260 | static struct __initdata platform_device * omap7xx_gpio_dev[] = { |
259 | &omap7xx_mpu_gpio, | 261 | &omap7xx_mpu_gpio, |
260 | &omap7xx_gpio1, | 262 | &omap7xx_gpio1, |
261 | &omap7xx_gpio2, | 263 | &omap7xx_gpio2, |
262 | &omap7xx_gpio3, | 264 | &omap7xx_gpio3, |
263 | &omap7xx_gpio4, | 265 | &omap7xx_gpio4, |
264 | &omap7xx_gpio5, | 266 | &omap7xx_gpio5, |
265 | &omap7xx_gpio6, | 267 | &omap7xx_gpio6, |
266 | }; | 268 | }; |
267 | 269 | ||
268 | /* | 270 | /* |
269 | * omap7xx_gpio_init needs to be done before | 271 | * omap7xx_gpio_init needs to be done before |
270 | * machine_init functions access gpio APIs. | 272 | * machine_init functions access gpio APIs. |
271 | * Hence omap7xx_gpio_init is a postcore_initcall. | 273 | * Hence omap7xx_gpio_init is a postcore_initcall. |
272 | */ | 274 | */ |
273 | static int __init omap7xx_gpio_init(void) | 275 | static int __init omap7xx_gpio_init(void) |
274 | { | 276 | { |
275 | int i; | 277 | int i; |
276 | 278 | ||
277 | if (!cpu_is_omap7xx()) | 279 | if (!cpu_is_omap7xx()) |
278 | return -EINVAL; | 280 | return -EINVAL; |
279 | 281 | ||
280 | for (i = 0; i < ARRAY_SIZE(omap7xx_gpio_dev); i++) | 282 | for (i = 0; i < ARRAY_SIZE(omap7xx_gpio_dev); i++) |
281 | platform_device_register(omap7xx_gpio_dev[i]); | 283 | platform_device_register(omap7xx_gpio_dev[i]); |
282 | 284 | ||
283 | gpio_bank_count = ARRAY_SIZE(omap7xx_gpio_dev); | 285 | gpio_bank_count = ARRAY_SIZE(omap7xx_gpio_dev); |
284 | 286 | ||
285 | return 0; | 287 | return 0; |
286 | } | 288 | } |
287 | postcore_initcall(omap7xx_gpio_init); | 289 | postcore_initcall(omap7xx_gpio_init); |
288 | 290 |
arch/arm/mach-omap2/gpio.c
1 | /* | 1 | /* |
2 | * OMAP2+ specific gpio initialization | 2 | * OMAP2+ specific gpio initialization |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ | 4 | * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ |
5 | * | 5 | * |
6 | * Author: | 6 | * Author: |
7 | * Charulatha V <charu@ti.com> | 7 | * Charulatha V <charu@ti.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU General Public License as | 10 | * modify it under the terms of the GNU General Public License as |
11 | * published by the Free Software Foundation version 2. | 11 | * published by the Free Software Foundation version 2. |
12 | * | 12 | * |
13 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | 13 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any |
14 | * kind, whether express or implied; without even the implied warranty | 14 | * kind, whether express or implied; without even the implied warranty |
15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | 23 | ||
24 | #include <plat/omap_hwmod.h> | 24 | #include <plat/omap_hwmod.h> |
25 | #include <plat/omap_device.h> | 25 | #include <plat/omap_device.h> |
26 | 26 | ||
27 | static struct omap_device_pm_latency omap_gpio_latency[] = { | 27 | static struct omap_device_pm_latency omap_gpio_latency[] = { |
28 | [0] = { | 28 | [0] = { |
29 | .deactivate_func = omap_device_idle_hwmods, | 29 | .deactivate_func = omap_device_idle_hwmods, |
30 | .activate_func = omap_device_enable_hwmods, | 30 | .activate_func = omap_device_enable_hwmods, |
31 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | 31 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, |
32 | }, | 32 | }, |
33 | }; | 33 | }; |
34 | 34 | ||
35 | static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) | 35 | static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) |
36 | { | 36 | { |
37 | struct omap_device *od; | 37 | struct omap_device *od; |
38 | struct omap_gpio_platform_data *pdata; | 38 | struct omap_gpio_platform_data *pdata; |
39 | struct omap_gpio_dev_attr *dev_attr; | 39 | struct omap_gpio_dev_attr *dev_attr; |
40 | char *name = "omap_gpio"; | 40 | char *name = "omap_gpio"; |
41 | int id; | 41 | int id; |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * extract the device id from name field available in the | 44 | * extract the device id from name field available in the |
45 | * hwmod database and use the same for constructing ids for | 45 | * hwmod database and use the same for constructing ids for |
46 | * gpio devices. | 46 | * gpio devices. |
47 | * CAUTION: Make sure the name in the hwmod database does | 47 | * CAUTION: Make sure the name in the hwmod database does |
48 | * not change. If changed, make corresponding change here | 48 | * not change. If changed, make corresponding change here |
49 | * or make use of static variable mechanism to handle this. | 49 | * or make use of static variable mechanism to handle this. |
50 | */ | 50 | */ |
51 | sscanf(oh->name, "gpio%d", &id); | 51 | sscanf(oh->name, "gpio%d", &id); |
52 | 52 | ||
53 | pdata = kzalloc(sizeof(struct omap_gpio_platform_data), GFP_KERNEL); | 53 | pdata = kzalloc(sizeof(struct omap_gpio_platform_data), GFP_KERNEL); |
54 | if (!pdata) { | 54 | if (!pdata) { |
55 | pr_err("gpio%d: Memory allocation failed\n", id); | 55 | pr_err("gpio%d: Memory allocation failed\n", id); |
56 | return -ENOMEM; | 56 | return -ENOMEM; |
57 | } | 57 | } |
58 | 58 | ||
59 | dev_attr = (struct omap_gpio_dev_attr *)oh->dev_attr; | 59 | dev_attr = (struct omap_gpio_dev_attr *)oh->dev_attr; |
60 | pdata->bank_width = dev_attr->bank_width; | 60 | pdata->bank_width = dev_attr->bank_width; |
61 | pdata->dbck_flag = dev_attr->dbck_flag; | 61 | pdata->dbck_flag = dev_attr->dbck_flag; |
62 | pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1); | 62 | pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1); |
63 | 63 | ||
64 | pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL); | 64 | pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL); |
65 | if (!pdata) { | 65 | if (!pdata) { |
66 | pr_err("gpio%d: Memory allocation failed\n", id); | 66 | pr_err("gpio%d: Memory allocation failed\n", id); |
67 | return -ENOMEM; | 67 | return -ENOMEM; |
68 | } | 68 | } |
69 | 69 | ||
70 | switch (oh->class->rev) { | 70 | switch (oh->class->rev) { |
71 | case 0: | 71 | case 0: |
72 | case 1: | 72 | case 1: |
73 | pdata->bank_type = METHOD_GPIO_24XX; | 73 | pdata->bank_type = METHOD_GPIO_24XX; |
74 | pdata->regs->revision = OMAP24XX_GPIO_REVISION; | ||
74 | pdata->regs->direction = OMAP24XX_GPIO_OE; | 75 | pdata->regs->direction = OMAP24XX_GPIO_OE; |
75 | pdata->regs->datain = OMAP24XX_GPIO_DATAIN; | 76 | pdata->regs->datain = OMAP24XX_GPIO_DATAIN; |
76 | pdata->regs->dataout = OMAP24XX_GPIO_DATAOUT; | 77 | pdata->regs->dataout = OMAP24XX_GPIO_DATAOUT; |
77 | pdata->regs->set_dataout = OMAP24XX_GPIO_SETDATAOUT; | 78 | pdata->regs->set_dataout = OMAP24XX_GPIO_SETDATAOUT; |
78 | pdata->regs->clr_dataout = OMAP24XX_GPIO_CLEARDATAOUT; | 79 | pdata->regs->clr_dataout = OMAP24XX_GPIO_CLEARDATAOUT; |
79 | pdata->regs->irqstatus = OMAP24XX_GPIO_IRQSTATUS1; | 80 | pdata->regs->irqstatus = OMAP24XX_GPIO_IRQSTATUS1; |
80 | pdata->regs->irqstatus2 = OMAP24XX_GPIO_IRQSTATUS2; | 81 | pdata->regs->irqstatus2 = OMAP24XX_GPIO_IRQSTATUS2; |
81 | pdata->regs->irqenable = OMAP24XX_GPIO_IRQENABLE1; | 82 | pdata->regs->irqenable = OMAP24XX_GPIO_IRQENABLE1; |
82 | pdata->regs->set_irqenable = OMAP24XX_GPIO_SETIRQENABLE1; | 83 | pdata->regs->set_irqenable = OMAP24XX_GPIO_SETIRQENABLE1; |
83 | pdata->regs->clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1; | 84 | pdata->regs->clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1; |
84 | pdata->regs->debounce = OMAP24XX_GPIO_DEBOUNCE_VAL; | 85 | pdata->regs->debounce = OMAP24XX_GPIO_DEBOUNCE_VAL; |
85 | pdata->regs->debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN; | 86 | pdata->regs->debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN; |
86 | break; | 87 | break; |
87 | case 2: | 88 | case 2: |
88 | pdata->bank_type = METHOD_GPIO_44XX; | 89 | pdata->bank_type = METHOD_GPIO_44XX; |
90 | pdata->regs->revision = OMAP4_GPIO_REVISION; | ||
89 | pdata->regs->direction = OMAP4_GPIO_OE; | 91 | pdata->regs->direction = OMAP4_GPIO_OE; |
90 | pdata->regs->datain = OMAP4_GPIO_DATAIN; | 92 | pdata->regs->datain = OMAP4_GPIO_DATAIN; |
91 | pdata->regs->dataout = OMAP4_GPIO_DATAOUT; | 93 | pdata->regs->dataout = OMAP4_GPIO_DATAOUT; |
92 | pdata->regs->set_dataout = OMAP4_GPIO_SETDATAOUT; | 94 | pdata->regs->set_dataout = OMAP4_GPIO_SETDATAOUT; |
93 | pdata->regs->clr_dataout = OMAP4_GPIO_CLEARDATAOUT; | 95 | pdata->regs->clr_dataout = OMAP4_GPIO_CLEARDATAOUT; |
94 | pdata->regs->irqstatus = OMAP4_GPIO_IRQSTATUS0; | 96 | pdata->regs->irqstatus = OMAP4_GPIO_IRQSTATUS0; |
95 | pdata->regs->irqstatus2 = OMAP4_GPIO_IRQSTATUS1; | 97 | pdata->regs->irqstatus2 = OMAP4_GPIO_IRQSTATUS1; |
96 | pdata->regs->irqenable = OMAP4_GPIO_IRQSTATUSSET0; | 98 | pdata->regs->irqenable = OMAP4_GPIO_IRQSTATUSSET0; |
97 | pdata->regs->set_irqenable = OMAP4_GPIO_IRQSTATUSSET0; | 99 | pdata->regs->set_irqenable = OMAP4_GPIO_IRQSTATUSSET0; |
98 | pdata->regs->clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0; | 100 | pdata->regs->clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0; |
99 | pdata->regs->debounce = OMAP4_GPIO_DEBOUNCINGTIME; | 101 | pdata->regs->debounce = OMAP4_GPIO_DEBOUNCINGTIME; |
100 | pdata->regs->debounce_en = OMAP4_GPIO_DEBOUNCENABLE; | 102 | pdata->regs->debounce_en = OMAP4_GPIO_DEBOUNCENABLE; |
101 | break; | 103 | break; |
102 | default: | 104 | default: |
103 | WARN(1, "Invalid gpio bank_type\n"); | 105 | WARN(1, "Invalid gpio bank_type\n"); |
104 | kfree(pdata); | 106 | kfree(pdata); |
105 | return -EINVAL; | 107 | return -EINVAL; |
106 | } | 108 | } |
107 | 109 | ||
108 | od = omap_device_build(name, id - 1, oh, pdata, | 110 | od = omap_device_build(name, id - 1, oh, pdata, |
109 | sizeof(*pdata), omap_gpio_latency, | 111 | sizeof(*pdata), omap_gpio_latency, |
110 | ARRAY_SIZE(omap_gpio_latency), | 112 | ARRAY_SIZE(omap_gpio_latency), |
111 | false); | 113 | false); |
112 | kfree(pdata); | 114 | kfree(pdata); |
113 | 115 | ||
114 | if (IS_ERR(od)) { | 116 | if (IS_ERR(od)) { |
115 | WARN(1, "Can't build omap_device for %s:%s.\n", | 117 | WARN(1, "Can't build omap_device for %s:%s.\n", |
116 | name, oh->name); | 118 | name, oh->name); |
117 | return PTR_ERR(od); | 119 | return PTR_ERR(od); |
118 | } | 120 | } |
119 | 121 | ||
120 | gpio_bank_count++; | 122 | gpio_bank_count++; |
121 | return 0; | 123 | return 0; |
122 | } | 124 | } |
123 | 125 | ||
124 | /* | 126 | /* |
125 | * gpio_init needs to be done before | 127 | * gpio_init needs to be done before |
126 | * machine_init functions access gpio APIs. | 128 | * machine_init functions access gpio APIs. |
127 | * Hence gpio_init is a postcore_initcall. | 129 | * Hence gpio_init is a postcore_initcall. |
128 | */ | 130 | */ |
129 | static int __init omap2_gpio_init(void) | 131 | static int __init omap2_gpio_init(void) |
130 | { | 132 | { |
131 | return omap_hwmod_for_each_by_class("gpio", omap2_gpio_dev_init, | 133 | return omap_hwmod_for_each_by_class("gpio", omap2_gpio_dev_init, |
132 | NULL); | 134 | NULL); |
133 | } | 135 | } |
134 | postcore_initcall(omap2_gpio_init); | 136 | postcore_initcall(omap2_gpio_init); |
135 | 137 |
arch/arm/plat-omap/include/plat/gpio.h
1 | /* | 1 | /* |
2 | * arch/arm/plat-omap/include/mach/gpio.h | 2 | * arch/arm/plat-omap/include/mach/gpio.h |
3 | * | 3 | * |
4 | * OMAP GPIO handling defines and functions | 4 | * OMAP GPIO handling defines and functions |
5 | * | 5 | * |
6 | * Copyright (C) 2003-2005 Nokia Corporation | 6 | * Copyright (C) 2003-2005 Nokia Corporation |
7 | * | 7 | * |
8 | * Written by Juha Yrjรถlรค <juha.yrjola@nokia.com> | 8 | * Written by Juha Yrjรถlรค <juha.yrjola@nokia.com> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation; either version 2 of the License, or | 12 | * the Free Software Foundation; either version 2 of the License, or |
13 | * (at your option) any later version. | 13 | * (at your option) any later version. |
14 | * | 14 | * |
15 | * This program is distributed in the hope that it will be useful, | 15 | * This program is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | * GNU General Public License for more details. | 18 | * GNU General Public License for more details. |
19 | * | 19 | * |
20 | * You should have received a copy of the GNU General Public License | 20 | * You should have received a copy of the GNU General Public License |
21 | * along with this program; if not, write to the Free Software | 21 | * along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #ifndef __ASM_ARCH_OMAP_GPIO_H | 26 | #ifndef __ASM_ARCH_OMAP_GPIO_H |
27 | #define __ASM_ARCH_OMAP_GPIO_H | 27 | #define __ASM_ARCH_OMAP_GPIO_H |
28 | 28 | ||
29 | #include <linux/io.h> | 29 | #include <linux/io.h> |
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <mach/irqs.h> | 31 | #include <mach/irqs.h> |
32 | 32 | ||
33 | #define OMAP1_MPUIO_BASE 0xfffb5000 | 33 | #define OMAP1_MPUIO_BASE 0xfffb5000 |
34 | 34 | ||
35 | /* | 35 | /* |
36 | * These are the omap15xx/16xx offsets. The omap7xx offset are | 36 | * These are the omap15xx/16xx offsets. The omap7xx offset are |
37 | * OMAP_MPUIO_ / 2 offsets below. | 37 | * OMAP_MPUIO_ / 2 offsets below. |
38 | */ | 38 | */ |
39 | #define OMAP_MPUIO_INPUT_LATCH 0x00 | 39 | #define OMAP_MPUIO_INPUT_LATCH 0x00 |
40 | #define OMAP_MPUIO_OUTPUT 0x04 | 40 | #define OMAP_MPUIO_OUTPUT 0x04 |
41 | #define OMAP_MPUIO_IO_CNTL 0x08 | 41 | #define OMAP_MPUIO_IO_CNTL 0x08 |
42 | #define OMAP_MPUIO_KBR_LATCH 0x10 | 42 | #define OMAP_MPUIO_KBR_LATCH 0x10 |
43 | #define OMAP_MPUIO_KBC 0x14 | 43 | #define OMAP_MPUIO_KBC 0x14 |
44 | #define OMAP_MPUIO_GPIO_EVENT_MODE 0x18 | 44 | #define OMAP_MPUIO_GPIO_EVENT_MODE 0x18 |
45 | #define OMAP_MPUIO_GPIO_INT_EDGE 0x1c | 45 | #define OMAP_MPUIO_GPIO_INT_EDGE 0x1c |
46 | #define OMAP_MPUIO_KBD_INT 0x20 | 46 | #define OMAP_MPUIO_KBD_INT 0x20 |
47 | #define OMAP_MPUIO_GPIO_INT 0x24 | 47 | #define OMAP_MPUIO_GPIO_INT 0x24 |
48 | #define OMAP_MPUIO_KBD_MASKIT 0x28 | 48 | #define OMAP_MPUIO_KBD_MASKIT 0x28 |
49 | #define OMAP_MPUIO_GPIO_MASKIT 0x2c | 49 | #define OMAP_MPUIO_GPIO_MASKIT 0x2c |
50 | #define OMAP_MPUIO_GPIO_DEBOUNCING 0x30 | 50 | #define OMAP_MPUIO_GPIO_DEBOUNCING 0x30 |
51 | #define OMAP_MPUIO_LATCH 0x34 | 51 | #define OMAP_MPUIO_LATCH 0x34 |
52 | 52 | ||
53 | #define OMAP34XX_NR_GPIOS 6 | 53 | #define OMAP34XX_NR_GPIOS 6 |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * OMAP1510 GPIO registers | 56 | * OMAP1510 GPIO registers |
57 | */ | 57 | */ |
58 | #define OMAP1510_GPIO_DATA_INPUT 0x00 | 58 | #define OMAP1510_GPIO_DATA_INPUT 0x00 |
59 | #define OMAP1510_GPIO_DATA_OUTPUT 0x04 | 59 | #define OMAP1510_GPIO_DATA_OUTPUT 0x04 |
60 | #define OMAP1510_GPIO_DIR_CONTROL 0x08 | 60 | #define OMAP1510_GPIO_DIR_CONTROL 0x08 |
61 | #define OMAP1510_GPIO_INT_CONTROL 0x0c | 61 | #define OMAP1510_GPIO_INT_CONTROL 0x0c |
62 | #define OMAP1510_GPIO_INT_MASK 0x10 | 62 | #define OMAP1510_GPIO_INT_MASK 0x10 |
63 | #define OMAP1510_GPIO_INT_STATUS 0x14 | 63 | #define OMAP1510_GPIO_INT_STATUS 0x14 |
64 | #define OMAP1510_GPIO_PIN_CONTROL 0x18 | 64 | #define OMAP1510_GPIO_PIN_CONTROL 0x18 |
65 | 65 | ||
66 | #define OMAP1510_IH_GPIO_BASE 64 | 66 | #define OMAP1510_IH_GPIO_BASE 64 |
67 | 67 | ||
68 | /* | 68 | /* |
69 | * OMAP1610 specific GPIO registers | 69 | * OMAP1610 specific GPIO registers |
70 | */ | 70 | */ |
71 | #define OMAP1610_GPIO_REVISION 0x0000 | 71 | #define OMAP1610_GPIO_REVISION 0x0000 |
72 | #define OMAP1610_GPIO_SYSCONFIG 0x0010 | 72 | #define OMAP1610_GPIO_SYSCONFIG 0x0010 |
73 | #define OMAP1610_GPIO_SYSSTATUS 0x0014 | 73 | #define OMAP1610_GPIO_SYSSTATUS 0x0014 |
74 | #define OMAP1610_GPIO_IRQSTATUS1 0x0018 | 74 | #define OMAP1610_GPIO_IRQSTATUS1 0x0018 |
75 | #define OMAP1610_GPIO_IRQENABLE1 0x001c | 75 | #define OMAP1610_GPIO_IRQENABLE1 0x001c |
76 | #define OMAP1610_GPIO_WAKEUPENABLE 0x0028 | 76 | #define OMAP1610_GPIO_WAKEUPENABLE 0x0028 |
77 | #define OMAP1610_GPIO_DATAIN 0x002c | 77 | #define OMAP1610_GPIO_DATAIN 0x002c |
78 | #define OMAP1610_GPIO_DATAOUT 0x0030 | 78 | #define OMAP1610_GPIO_DATAOUT 0x0030 |
79 | #define OMAP1610_GPIO_DIRECTION 0x0034 | 79 | #define OMAP1610_GPIO_DIRECTION 0x0034 |
80 | #define OMAP1610_GPIO_EDGE_CTRL1 0x0038 | 80 | #define OMAP1610_GPIO_EDGE_CTRL1 0x0038 |
81 | #define OMAP1610_GPIO_EDGE_CTRL2 0x003c | 81 | #define OMAP1610_GPIO_EDGE_CTRL2 0x003c |
82 | #define OMAP1610_GPIO_CLEAR_IRQENABLE1 0x009c | 82 | #define OMAP1610_GPIO_CLEAR_IRQENABLE1 0x009c |
83 | #define OMAP1610_GPIO_CLEAR_WAKEUPENA 0x00a8 | 83 | #define OMAP1610_GPIO_CLEAR_WAKEUPENA 0x00a8 |
84 | #define OMAP1610_GPIO_CLEAR_DATAOUT 0x00b0 | 84 | #define OMAP1610_GPIO_CLEAR_DATAOUT 0x00b0 |
85 | #define OMAP1610_GPIO_SET_IRQENABLE1 0x00dc | 85 | #define OMAP1610_GPIO_SET_IRQENABLE1 0x00dc |
86 | #define OMAP1610_GPIO_SET_WAKEUPENA 0x00e8 | 86 | #define OMAP1610_GPIO_SET_WAKEUPENA 0x00e8 |
87 | #define OMAP1610_GPIO_SET_DATAOUT 0x00f0 | 87 | #define OMAP1610_GPIO_SET_DATAOUT 0x00f0 |
88 | 88 | ||
89 | /* | 89 | /* |
90 | * OMAP7XX specific GPIO registers | 90 | * OMAP7XX specific GPIO registers |
91 | */ | 91 | */ |
92 | #define OMAP7XX_GPIO_DATA_INPUT 0x00 | 92 | #define OMAP7XX_GPIO_DATA_INPUT 0x00 |
93 | #define OMAP7XX_GPIO_DATA_OUTPUT 0x04 | 93 | #define OMAP7XX_GPIO_DATA_OUTPUT 0x04 |
94 | #define OMAP7XX_GPIO_DIR_CONTROL 0x08 | 94 | #define OMAP7XX_GPIO_DIR_CONTROL 0x08 |
95 | #define OMAP7XX_GPIO_INT_CONTROL 0x0c | 95 | #define OMAP7XX_GPIO_INT_CONTROL 0x0c |
96 | #define OMAP7XX_GPIO_INT_MASK 0x10 | 96 | #define OMAP7XX_GPIO_INT_MASK 0x10 |
97 | #define OMAP7XX_GPIO_INT_STATUS 0x14 | 97 | #define OMAP7XX_GPIO_INT_STATUS 0x14 |
98 | 98 | ||
99 | /* | 99 | /* |
100 | * omap2+ specific GPIO registers | 100 | * omap2+ specific GPIO registers |
101 | */ | 101 | */ |
102 | #define OMAP24XX_GPIO_REVISION 0x0000 | 102 | #define OMAP24XX_GPIO_REVISION 0x0000 |
103 | #define OMAP24XX_GPIO_IRQSTATUS1 0x0018 | 103 | #define OMAP24XX_GPIO_IRQSTATUS1 0x0018 |
104 | #define OMAP24XX_GPIO_IRQSTATUS2 0x0028 | 104 | #define OMAP24XX_GPIO_IRQSTATUS2 0x0028 |
105 | #define OMAP24XX_GPIO_IRQENABLE2 0x002c | 105 | #define OMAP24XX_GPIO_IRQENABLE2 0x002c |
106 | #define OMAP24XX_GPIO_IRQENABLE1 0x001c | 106 | #define OMAP24XX_GPIO_IRQENABLE1 0x001c |
107 | #define OMAP24XX_GPIO_WAKE_EN 0x0020 | 107 | #define OMAP24XX_GPIO_WAKE_EN 0x0020 |
108 | #define OMAP24XX_GPIO_CTRL 0x0030 | 108 | #define OMAP24XX_GPIO_CTRL 0x0030 |
109 | #define OMAP24XX_GPIO_OE 0x0034 | 109 | #define OMAP24XX_GPIO_OE 0x0034 |
110 | #define OMAP24XX_GPIO_DATAIN 0x0038 | 110 | #define OMAP24XX_GPIO_DATAIN 0x0038 |
111 | #define OMAP24XX_GPIO_DATAOUT 0x003c | 111 | #define OMAP24XX_GPIO_DATAOUT 0x003c |
112 | #define OMAP24XX_GPIO_LEVELDETECT0 0x0040 | 112 | #define OMAP24XX_GPIO_LEVELDETECT0 0x0040 |
113 | #define OMAP24XX_GPIO_LEVELDETECT1 0x0044 | 113 | #define OMAP24XX_GPIO_LEVELDETECT1 0x0044 |
114 | #define OMAP24XX_GPIO_RISINGDETECT 0x0048 | 114 | #define OMAP24XX_GPIO_RISINGDETECT 0x0048 |
115 | #define OMAP24XX_GPIO_FALLINGDETECT 0x004c | 115 | #define OMAP24XX_GPIO_FALLINGDETECT 0x004c |
116 | #define OMAP24XX_GPIO_DEBOUNCE_EN 0x0050 | 116 | #define OMAP24XX_GPIO_DEBOUNCE_EN 0x0050 |
117 | #define OMAP24XX_GPIO_DEBOUNCE_VAL 0x0054 | 117 | #define OMAP24XX_GPIO_DEBOUNCE_VAL 0x0054 |
118 | #define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0060 | 118 | #define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0060 |
119 | #define OMAP24XX_GPIO_SETIRQENABLE1 0x0064 | 119 | #define OMAP24XX_GPIO_SETIRQENABLE1 0x0064 |
120 | #define OMAP24XX_GPIO_CLEARWKUENA 0x0080 | 120 | #define OMAP24XX_GPIO_CLEARWKUENA 0x0080 |
121 | #define OMAP24XX_GPIO_SETWKUENA 0x0084 | 121 | #define OMAP24XX_GPIO_SETWKUENA 0x0084 |
122 | #define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 | 122 | #define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 |
123 | #define OMAP24XX_GPIO_SETDATAOUT 0x0094 | 123 | #define OMAP24XX_GPIO_SETDATAOUT 0x0094 |
124 | 124 | ||
125 | #define OMAP4_GPIO_REVISION 0x0000 | 125 | #define OMAP4_GPIO_REVISION 0x0000 |
126 | #define OMAP4_GPIO_EOI 0x0020 | 126 | #define OMAP4_GPIO_EOI 0x0020 |
127 | #define OMAP4_GPIO_IRQSTATUSRAW0 0x0024 | 127 | #define OMAP4_GPIO_IRQSTATUSRAW0 0x0024 |
128 | #define OMAP4_GPIO_IRQSTATUSRAW1 0x0028 | 128 | #define OMAP4_GPIO_IRQSTATUSRAW1 0x0028 |
129 | #define OMAP4_GPIO_IRQSTATUS0 0x002c | 129 | #define OMAP4_GPIO_IRQSTATUS0 0x002c |
130 | #define OMAP4_GPIO_IRQSTATUS1 0x0030 | 130 | #define OMAP4_GPIO_IRQSTATUS1 0x0030 |
131 | #define OMAP4_GPIO_IRQSTATUSSET0 0x0034 | 131 | #define OMAP4_GPIO_IRQSTATUSSET0 0x0034 |
132 | #define OMAP4_GPIO_IRQSTATUSSET1 0x0038 | 132 | #define OMAP4_GPIO_IRQSTATUSSET1 0x0038 |
133 | #define OMAP4_GPIO_IRQSTATUSCLR0 0x003c | 133 | #define OMAP4_GPIO_IRQSTATUSCLR0 0x003c |
134 | #define OMAP4_GPIO_IRQSTATUSCLR1 0x0040 | 134 | #define OMAP4_GPIO_IRQSTATUSCLR1 0x0040 |
135 | #define OMAP4_GPIO_IRQWAKEN0 0x0044 | 135 | #define OMAP4_GPIO_IRQWAKEN0 0x0044 |
136 | #define OMAP4_GPIO_IRQWAKEN1 0x0048 | 136 | #define OMAP4_GPIO_IRQWAKEN1 0x0048 |
137 | #define OMAP4_GPIO_IRQENABLE1 0x011c | 137 | #define OMAP4_GPIO_IRQENABLE1 0x011c |
138 | #define OMAP4_GPIO_WAKE_EN 0x0120 | 138 | #define OMAP4_GPIO_WAKE_EN 0x0120 |
139 | #define OMAP4_GPIO_IRQSTATUS2 0x0128 | 139 | #define OMAP4_GPIO_IRQSTATUS2 0x0128 |
140 | #define OMAP4_GPIO_IRQENABLE2 0x012c | 140 | #define OMAP4_GPIO_IRQENABLE2 0x012c |
141 | #define OMAP4_GPIO_CTRL 0x0130 | 141 | #define OMAP4_GPIO_CTRL 0x0130 |
142 | #define OMAP4_GPIO_OE 0x0134 | 142 | #define OMAP4_GPIO_OE 0x0134 |
143 | #define OMAP4_GPIO_DATAIN 0x0138 | 143 | #define OMAP4_GPIO_DATAIN 0x0138 |
144 | #define OMAP4_GPIO_DATAOUT 0x013c | 144 | #define OMAP4_GPIO_DATAOUT 0x013c |
145 | #define OMAP4_GPIO_LEVELDETECT0 0x0140 | 145 | #define OMAP4_GPIO_LEVELDETECT0 0x0140 |
146 | #define OMAP4_GPIO_LEVELDETECT1 0x0144 | 146 | #define OMAP4_GPIO_LEVELDETECT1 0x0144 |
147 | #define OMAP4_GPIO_RISINGDETECT 0x0148 | 147 | #define OMAP4_GPIO_RISINGDETECT 0x0148 |
148 | #define OMAP4_GPIO_FALLINGDETECT 0x014c | 148 | #define OMAP4_GPIO_FALLINGDETECT 0x014c |
149 | #define OMAP4_GPIO_DEBOUNCENABLE 0x0150 | 149 | #define OMAP4_GPIO_DEBOUNCENABLE 0x0150 |
150 | #define OMAP4_GPIO_DEBOUNCINGTIME 0x0154 | 150 | #define OMAP4_GPIO_DEBOUNCINGTIME 0x0154 |
151 | #define OMAP4_GPIO_CLEARIRQENABLE1 0x0160 | 151 | #define OMAP4_GPIO_CLEARIRQENABLE1 0x0160 |
152 | #define OMAP4_GPIO_SETIRQENABLE1 0x0164 | 152 | #define OMAP4_GPIO_SETIRQENABLE1 0x0164 |
153 | #define OMAP4_GPIO_CLEARWKUENA 0x0180 | 153 | #define OMAP4_GPIO_CLEARWKUENA 0x0180 |
154 | #define OMAP4_GPIO_SETWKUENA 0x0184 | 154 | #define OMAP4_GPIO_SETWKUENA 0x0184 |
155 | #define OMAP4_GPIO_CLEARDATAOUT 0x0190 | 155 | #define OMAP4_GPIO_CLEARDATAOUT 0x0190 |
156 | #define OMAP4_GPIO_SETDATAOUT 0x0194 | 156 | #define OMAP4_GPIO_SETDATAOUT 0x0194 |
157 | 157 | ||
158 | #define OMAP_MPUIO(nr) (OMAP_MAX_GPIO_LINES + (nr)) | 158 | #define OMAP_MPUIO(nr) (OMAP_MAX_GPIO_LINES + (nr)) |
159 | #define OMAP_GPIO_IS_MPUIO(nr) ((nr) >= OMAP_MAX_GPIO_LINES) | 159 | #define OMAP_GPIO_IS_MPUIO(nr) ((nr) >= OMAP_MAX_GPIO_LINES) |
160 | 160 | ||
161 | #define OMAP_GPIO_IRQ(nr) (OMAP_GPIO_IS_MPUIO(nr) ? \ | 161 | #define OMAP_GPIO_IRQ(nr) (OMAP_GPIO_IS_MPUIO(nr) ? \ |
162 | IH_MPUIO_BASE + ((nr) & 0x0f) : \ | 162 | IH_MPUIO_BASE + ((nr) & 0x0f) : \ |
163 | IH_GPIO_BASE + (nr)) | 163 | IH_GPIO_BASE + (nr)) |
164 | 164 | ||
165 | #define METHOD_MPUIO 0 | 165 | #define METHOD_MPUIO 0 |
166 | #define METHOD_GPIO_1510 1 | 166 | #define METHOD_GPIO_1510 1 |
167 | #define METHOD_GPIO_1610 2 | 167 | #define METHOD_GPIO_1610 2 |
168 | #define METHOD_GPIO_7XX 3 | 168 | #define METHOD_GPIO_7XX 3 |
169 | #define METHOD_GPIO_24XX 5 | 169 | #define METHOD_GPIO_24XX 5 |
170 | #define METHOD_GPIO_44XX 6 | 170 | #define METHOD_GPIO_44XX 6 |
171 | 171 | ||
172 | struct omap_gpio_dev_attr { | 172 | struct omap_gpio_dev_attr { |
173 | int bank_width; /* GPIO bank width */ | 173 | int bank_width; /* GPIO bank width */ |
174 | bool dbck_flag; /* dbck required or not - True for OMAP3&4 */ | 174 | bool dbck_flag; /* dbck required or not - True for OMAP3&4 */ |
175 | }; | 175 | }; |
176 | 176 | ||
177 | struct omap_gpio_reg_offs { | 177 | struct omap_gpio_reg_offs { |
178 | u16 revision; | ||
178 | u16 direction; | 179 | u16 direction; |
179 | u16 datain; | 180 | u16 datain; |
180 | u16 dataout; | 181 | u16 dataout; |
181 | u16 set_dataout; | 182 | u16 set_dataout; |
182 | u16 clr_dataout; | 183 | u16 clr_dataout; |
183 | u16 irqstatus; | 184 | u16 irqstatus; |
184 | u16 irqstatus2; | 185 | u16 irqstatus2; |
185 | u16 irqenable; | 186 | u16 irqenable; |
186 | u16 set_irqenable; | 187 | u16 set_irqenable; |
187 | u16 clr_irqenable; | 188 | u16 clr_irqenable; |
188 | u16 debounce; | 189 | u16 debounce; |
189 | u16 debounce_en; | 190 | u16 debounce_en; |
190 | 191 | ||
191 | bool irqenable_inv; | 192 | bool irqenable_inv; |
192 | }; | 193 | }; |
193 | 194 | ||
194 | struct omap_gpio_platform_data { | 195 | struct omap_gpio_platform_data { |
195 | u16 virtual_irq_start; | 196 | u16 virtual_irq_start; |
196 | int bank_type; | 197 | int bank_type; |
197 | int bank_width; /* GPIO bank width */ | 198 | int bank_width; /* GPIO bank width */ |
198 | int bank_stride; /* Only needed for omap1 MPUIO */ | 199 | int bank_stride; /* Only needed for omap1 MPUIO */ |
199 | bool dbck_flag; /* dbck required or not - True for OMAP3&4 */ | 200 | bool dbck_flag; /* dbck required or not - True for OMAP3&4 */ |
200 | 201 | ||
201 | struct omap_gpio_reg_offs *regs; | 202 | struct omap_gpio_reg_offs *regs; |
202 | }; | 203 | }; |
203 | 204 | ||
204 | /* TODO: Analyze removing gpio_bank_count usage from driver code */ | 205 | /* TODO: Analyze removing gpio_bank_count usage from driver code */ |
205 | extern int gpio_bank_count; | 206 | extern int gpio_bank_count; |
206 | 207 | ||
207 | extern void omap2_gpio_prepare_for_idle(int off_mode); | 208 | extern void omap2_gpio_prepare_for_idle(int off_mode); |
208 | extern void omap2_gpio_resume_after_idle(void); | 209 | extern void omap2_gpio_resume_after_idle(void); |
209 | extern void omap_set_gpio_debounce(int gpio, int enable); | 210 | extern void omap_set_gpio_debounce(int gpio, int enable); |
210 | extern void omap_set_gpio_debounce_time(int gpio, int enable); | 211 | extern void omap_set_gpio_debounce_time(int gpio, int enable); |
211 | extern void omap_gpio_save_context(void); | 212 | extern void omap_gpio_save_context(void); |
212 | extern void omap_gpio_restore_context(void); | 213 | extern void omap_gpio_restore_context(void); |
213 | /*-------------------------------------------------------------------------*/ | 214 | /*-------------------------------------------------------------------------*/ |
214 | 215 | ||
215 | /* Wrappers for "new style" GPIO calls, using the new infrastructure | 216 | /* Wrappers for "new style" GPIO calls, using the new infrastructure |
216 | * which lets us plug in FPGA, I2C, and other implementations. | 217 | * which lets us plug in FPGA, I2C, and other implementations. |
217 | * * | 218 | * * |
218 | * The original OMAP-specific calls should eventually be removed. | 219 | * The original OMAP-specific calls should eventually be removed. |
219 | */ | 220 | */ |
220 | 221 | ||
221 | #include <linux/errno.h> | 222 | #include <linux/errno.h> |
222 | #include <asm-generic/gpio.h> | 223 | #include <asm-generic/gpio.h> |
223 | 224 | ||
224 | static inline int gpio_get_value(unsigned gpio) | 225 | static inline int gpio_get_value(unsigned gpio) |
225 | { | 226 | { |
226 | return __gpio_get_value(gpio); | 227 | return __gpio_get_value(gpio); |
227 | } | 228 | } |
228 | 229 | ||
229 | static inline void gpio_set_value(unsigned gpio, int value) | 230 | static inline void gpio_set_value(unsigned gpio, int value) |
230 | { | 231 | { |
231 | __gpio_set_value(gpio, value); | 232 | __gpio_set_value(gpio, value); |
232 | } | 233 | } |
233 | 234 | ||
234 | static inline int gpio_cansleep(unsigned gpio) | 235 | static inline int gpio_cansleep(unsigned gpio) |
235 | { | 236 | { |
236 | return __gpio_cansleep(gpio); | 237 | return __gpio_cansleep(gpio); |
237 | } | 238 | } |
238 | 239 | ||
239 | static inline int gpio_to_irq(unsigned gpio) | 240 | static inline int gpio_to_irq(unsigned gpio) |
240 | { | 241 | { |
241 | return __gpio_to_irq(gpio); | 242 | return __gpio_to_irq(gpio); |
242 | } | 243 | } |
243 | 244 | ||
244 | static inline int irq_to_gpio(unsigned irq) | 245 | static inline int irq_to_gpio(unsigned irq) |
245 | { | 246 | { |
246 | int tmp; | 247 | int tmp; |
247 | 248 | ||
248 | /* omap1 SOC mpuio */ | 249 | /* omap1 SOC mpuio */ |
249 | if (cpu_class_is_omap1() && (irq < (IH_MPUIO_BASE + 16))) | 250 | if (cpu_class_is_omap1() && (irq < (IH_MPUIO_BASE + 16))) |
250 | return (irq - IH_MPUIO_BASE) + OMAP_MAX_GPIO_LINES; | 251 | return (irq - IH_MPUIO_BASE) + OMAP_MAX_GPIO_LINES; |
251 | 252 | ||
252 | /* SOC gpio */ | 253 | /* SOC gpio */ |
253 | tmp = irq - IH_GPIO_BASE; | 254 | tmp = irq - IH_GPIO_BASE; |
254 | if (tmp < OMAP_MAX_GPIO_LINES) | 255 | if (tmp < OMAP_MAX_GPIO_LINES) |
255 | return tmp; | 256 | return tmp; |
256 | 257 | ||
257 | /* we don't supply reverse mappings for non-SOC gpios */ | 258 | /* we don't supply reverse mappings for non-SOC gpios */ |
258 | return -EIO; | 259 | return -EIO; |
259 | } | 260 | } |
260 | 261 | ||
261 | #endif | 262 | #endif |
262 | 263 |
drivers/gpio/gpio-omap.c
1 | /* | 1 | /* |
2 | * Support functions for OMAP GPIO | 2 | * Support functions for OMAP GPIO |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2005 Nokia Corporation | 4 | * Copyright (C) 2003-2005 Nokia Corporation |
5 | * Written by Juha Yrjรถlรค <juha.yrjola@nokia.com> | 5 | * Written by Juha Yrjรถlรค <juha.yrjola@nokia.com> |
6 | * | 6 | * |
7 | * Copyright (C) 2009 Texas Instruments | 7 | * Copyright (C) 2009 Texas Instruments |
8 | * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> | 8 | * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/syscore_ops.h> | 18 | #include <linux/syscore_ops.h> |
19 | #include <linux/err.h> | 19 | #include <linux/err.h> |
20 | #include <linux/clk.h> | 20 | #include <linux/clk.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/pm_runtime.h> | 23 | #include <linux/pm_runtime.h> |
24 | 24 | ||
25 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
26 | #include <asm/irq.h> | 26 | #include <asm/irq.h> |
27 | #include <mach/irqs.h> | 27 | #include <mach/irqs.h> |
28 | #include <mach/gpio.h> | 28 | #include <mach/gpio.h> |
29 | #include <asm/mach/irq.h> | 29 | #include <asm/mach/irq.h> |
30 | 30 | ||
31 | struct gpio_bank { | 31 | struct gpio_bank { |
32 | unsigned long pbase; | 32 | unsigned long pbase; |
33 | void __iomem *base; | 33 | void __iomem *base; |
34 | u16 irq; | 34 | u16 irq; |
35 | u16 virtual_irq_start; | 35 | u16 virtual_irq_start; |
36 | int method; | 36 | int method; |
37 | #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) | 37 | #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) |
38 | u32 suspend_wakeup; | 38 | u32 suspend_wakeup; |
39 | u32 saved_wakeup; | 39 | u32 saved_wakeup; |
40 | #endif | 40 | #endif |
41 | u32 non_wakeup_gpios; | 41 | u32 non_wakeup_gpios; |
42 | u32 enabled_non_wakeup_gpios; | 42 | u32 enabled_non_wakeup_gpios; |
43 | 43 | ||
44 | u32 saved_datain; | 44 | u32 saved_datain; |
45 | u32 saved_fallingdetect; | 45 | u32 saved_fallingdetect; |
46 | u32 saved_risingdetect; | 46 | u32 saved_risingdetect; |
47 | u32 level_mask; | 47 | u32 level_mask; |
48 | u32 toggle_mask; | 48 | u32 toggle_mask; |
49 | spinlock_t lock; | 49 | spinlock_t lock; |
50 | struct gpio_chip chip; | 50 | struct gpio_chip chip; |
51 | struct clk *dbck; | 51 | struct clk *dbck; |
52 | u32 mod_usage; | 52 | u32 mod_usage; |
53 | u32 dbck_enable_mask; | 53 | u32 dbck_enable_mask; |
54 | struct device *dev; | 54 | struct device *dev; |
55 | bool dbck_flag; | 55 | bool dbck_flag; |
56 | int stride; | 56 | int stride; |
57 | u32 width; | 57 | u32 width; |
58 | 58 | ||
59 | void (*set_dataout)(struct gpio_bank *bank, int gpio, int enable); | 59 | void (*set_dataout)(struct gpio_bank *bank, int gpio, int enable); |
60 | 60 | ||
61 | struct omap_gpio_reg_offs *regs; | 61 | struct omap_gpio_reg_offs *regs; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | #ifdef CONFIG_ARCH_OMAP3 | 64 | #ifdef CONFIG_ARCH_OMAP3 |
65 | struct omap3_gpio_regs { | 65 | struct omap3_gpio_regs { |
66 | u32 irqenable1; | 66 | u32 irqenable1; |
67 | u32 irqenable2; | 67 | u32 irqenable2; |
68 | u32 wake_en; | 68 | u32 wake_en; |
69 | u32 ctrl; | 69 | u32 ctrl; |
70 | u32 oe; | 70 | u32 oe; |
71 | u32 leveldetect0; | 71 | u32 leveldetect0; |
72 | u32 leveldetect1; | 72 | u32 leveldetect1; |
73 | u32 risingdetect; | 73 | u32 risingdetect; |
74 | u32 fallingdetect; | 74 | u32 fallingdetect; |
75 | u32 dataout; | 75 | u32 dataout; |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS]; | 78 | static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS]; |
79 | #endif | 79 | #endif |
80 | 80 | ||
81 | /* | 81 | /* |
82 | * TODO: Cleanup gpio_bank usage as it is having information | 82 | * TODO: Cleanup gpio_bank usage as it is having information |
83 | * related to all instances of the device | 83 | * related to all instances of the device |
84 | */ | 84 | */ |
85 | static struct gpio_bank *gpio_bank; | 85 | static struct gpio_bank *gpio_bank; |
86 | 86 | ||
87 | /* TODO: Analyze removing gpio_bank_count usage from driver code */ | 87 | /* TODO: Analyze removing gpio_bank_count usage from driver code */ |
88 | int gpio_bank_count; | 88 | int gpio_bank_count; |
89 | 89 | ||
90 | #define GPIO_INDEX(bank, gpio) (gpio % bank->width) | 90 | #define GPIO_INDEX(bank, gpio) (gpio % bank->width) |
91 | #define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio)) | 91 | #define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio)) |
92 | 92 | ||
93 | static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) | 93 | static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) |
94 | { | 94 | { |
95 | void __iomem *reg = bank->base; | 95 | void __iomem *reg = bank->base; |
96 | u32 l; | 96 | u32 l; |
97 | 97 | ||
98 | reg += bank->regs->direction; | 98 | reg += bank->regs->direction; |
99 | l = __raw_readl(reg); | 99 | l = __raw_readl(reg); |
100 | if (is_input) | 100 | if (is_input) |
101 | l |= 1 << gpio; | 101 | l |= 1 << gpio; |
102 | else | 102 | else |
103 | l &= ~(1 << gpio); | 103 | l &= ~(1 << gpio); |
104 | __raw_writel(l, reg); | 104 | __raw_writel(l, reg); |
105 | } | 105 | } |
106 | 106 | ||
107 | 107 | ||
108 | /* set data out value using dedicate set/clear register */ | 108 | /* set data out value using dedicate set/clear register */ |
109 | static void _set_gpio_dataout_reg(struct gpio_bank *bank, int gpio, int enable) | 109 | static void _set_gpio_dataout_reg(struct gpio_bank *bank, int gpio, int enable) |
110 | { | 110 | { |
111 | void __iomem *reg = bank->base; | 111 | void __iomem *reg = bank->base; |
112 | u32 l = GPIO_BIT(bank, gpio); | 112 | u32 l = GPIO_BIT(bank, gpio); |
113 | 113 | ||
114 | if (enable) | 114 | if (enable) |
115 | reg += bank->regs->set_dataout; | 115 | reg += bank->regs->set_dataout; |
116 | else | 116 | else |
117 | reg += bank->regs->clr_dataout; | 117 | reg += bank->regs->clr_dataout; |
118 | 118 | ||
119 | __raw_writel(l, reg); | 119 | __raw_writel(l, reg); |
120 | } | 120 | } |
121 | 121 | ||
122 | /* set data out value using mask register */ | 122 | /* set data out value using mask register */ |
123 | static void _set_gpio_dataout_mask(struct gpio_bank *bank, int gpio, int enable) | 123 | static void _set_gpio_dataout_mask(struct gpio_bank *bank, int gpio, int enable) |
124 | { | 124 | { |
125 | void __iomem *reg = bank->base + bank->regs->dataout; | 125 | void __iomem *reg = bank->base + bank->regs->dataout; |
126 | u32 gpio_bit = GPIO_BIT(bank, gpio); | 126 | u32 gpio_bit = GPIO_BIT(bank, gpio); |
127 | u32 l; | 127 | u32 l; |
128 | 128 | ||
129 | l = __raw_readl(reg); | 129 | l = __raw_readl(reg); |
130 | if (enable) | 130 | if (enable) |
131 | l |= gpio_bit; | 131 | l |= gpio_bit; |
132 | else | 132 | else |
133 | l &= ~gpio_bit; | 133 | l &= ~gpio_bit; |
134 | __raw_writel(l, reg); | 134 | __raw_writel(l, reg); |
135 | } | 135 | } |
136 | 136 | ||
137 | static int _get_gpio_datain(struct gpio_bank *bank, int gpio) | 137 | static int _get_gpio_datain(struct gpio_bank *bank, int gpio) |
138 | { | 138 | { |
139 | void __iomem *reg = bank->base + bank->regs->datain; | 139 | void __iomem *reg = bank->base + bank->regs->datain; |
140 | 140 | ||
141 | return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0; | 141 | return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0; |
142 | } | 142 | } |
143 | 143 | ||
144 | static int _get_gpio_dataout(struct gpio_bank *bank, int gpio) | 144 | static int _get_gpio_dataout(struct gpio_bank *bank, int gpio) |
145 | { | 145 | { |
146 | void __iomem *reg = bank->base + bank->regs->dataout; | 146 | void __iomem *reg = bank->base + bank->regs->dataout; |
147 | 147 | ||
148 | return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0; | 148 | return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0; |
149 | } | 149 | } |
150 | 150 | ||
151 | #define MOD_REG_BIT(reg, bit_mask, set) \ | 151 | #define MOD_REG_BIT(reg, bit_mask, set) \ |
152 | do { \ | 152 | do { \ |
153 | int l = __raw_readl(base + reg); \ | 153 | int l = __raw_readl(base + reg); \ |
154 | if (set) l |= bit_mask; \ | 154 | if (set) l |= bit_mask; \ |
155 | else l &= ~bit_mask; \ | 155 | else l &= ~bit_mask; \ |
156 | __raw_writel(l, base + reg); \ | 156 | __raw_writel(l, base + reg); \ |
157 | } while(0) | 157 | } while(0) |
158 | 158 | ||
159 | /** | 159 | /** |
160 | * _set_gpio_debounce - low level gpio debounce time | 160 | * _set_gpio_debounce - low level gpio debounce time |
161 | * @bank: the gpio bank we're acting upon | 161 | * @bank: the gpio bank we're acting upon |
162 | * @gpio: the gpio number on this @gpio | 162 | * @gpio: the gpio number on this @gpio |
163 | * @debounce: debounce time to use | 163 | * @debounce: debounce time to use |
164 | * | 164 | * |
165 | * OMAP's debounce time is in 31us steps so we need | 165 | * OMAP's debounce time is in 31us steps so we need |
166 | * to convert and round up to the closest unit. | 166 | * to convert and round up to the closest unit. |
167 | */ | 167 | */ |
168 | static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, | 168 | static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, |
169 | unsigned debounce) | 169 | unsigned debounce) |
170 | { | 170 | { |
171 | void __iomem *reg; | 171 | void __iomem *reg; |
172 | u32 val; | 172 | u32 val; |
173 | u32 l; | 173 | u32 l; |
174 | 174 | ||
175 | if (!bank->dbck_flag) | 175 | if (!bank->dbck_flag) |
176 | return; | 176 | return; |
177 | 177 | ||
178 | if (debounce < 32) | 178 | if (debounce < 32) |
179 | debounce = 0x01; | 179 | debounce = 0x01; |
180 | else if (debounce > 7936) | 180 | else if (debounce > 7936) |
181 | debounce = 0xff; | 181 | debounce = 0xff; |
182 | else | 182 | else |
183 | debounce = (debounce / 0x1f) - 1; | 183 | debounce = (debounce / 0x1f) - 1; |
184 | 184 | ||
185 | l = GPIO_BIT(bank, gpio); | 185 | l = GPIO_BIT(bank, gpio); |
186 | 186 | ||
187 | reg = bank->base + bank->regs->debounce; | 187 | reg = bank->base + bank->regs->debounce; |
188 | __raw_writel(debounce, reg); | 188 | __raw_writel(debounce, reg); |
189 | 189 | ||
190 | reg = bank->base + bank->regs->debounce_en; | 190 | reg = bank->base + bank->regs->debounce_en; |
191 | val = __raw_readl(reg); | 191 | val = __raw_readl(reg); |
192 | 192 | ||
193 | if (debounce) { | 193 | if (debounce) { |
194 | val |= l; | 194 | val |= l; |
195 | clk_enable(bank->dbck); | 195 | clk_enable(bank->dbck); |
196 | } else { | 196 | } else { |
197 | val &= ~l; | 197 | val &= ~l; |
198 | clk_disable(bank->dbck); | 198 | clk_disable(bank->dbck); |
199 | } | 199 | } |
200 | bank->dbck_enable_mask = val; | 200 | bank->dbck_enable_mask = val; |
201 | 201 | ||
202 | __raw_writel(val, reg); | 202 | __raw_writel(val, reg); |
203 | } | 203 | } |
204 | 204 | ||
205 | #ifdef CONFIG_ARCH_OMAP2PLUS | 205 | #ifdef CONFIG_ARCH_OMAP2PLUS |
206 | static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, | 206 | static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, |
207 | int trigger) | 207 | int trigger) |
208 | { | 208 | { |
209 | void __iomem *base = bank->base; | 209 | void __iomem *base = bank->base; |
210 | u32 gpio_bit = 1 << gpio; | 210 | u32 gpio_bit = 1 << gpio; |
211 | 211 | ||
212 | if (cpu_is_omap44xx()) { | 212 | if (cpu_is_omap44xx()) { |
213 | MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT0, gpio_bit, | 213 | MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT0, gpio_bit, |
214 | trigger & IRQ_TYPE_LEVEL_LOW); | 214 | trigger & IRQ_TYPE_LEVEL_LOW); |
215 | MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT1, gpio_bit, | 215 | MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT1, gpio_bit, |
216 | trigger & IRQ_TYPE_LEVEL_HIGH); | 216 | trigger & IRQ_TYPE_LEVEL_HIGH); |
217 | MOD_REG_BIT(OMAP4_GPIO_RISINGDETECT, gpio_bit, | 217 | MOD_REG_BIT(OMAP4_GPIO_RISINGDETECT, gpio_bit, |
218 | trigger & IRQ_TYPE_EDGE_RISING); | 218 | trigger & IRQ_TYPE_EDGE_RISING); |
219 | MOD_REG_BIT(OMAP4_GPIO_FALLINGDETECT, gpio_bit, | 219 | MOD_REG_BIT(OMAP4_GPIO_FALLINGDETECT, gpio_bit, |
220 | trigger & IRQ_TYPE_EDGE_FALLING); | 220 | trigger & IRQ_TYPE_EDGE_FALLING); |
221 | } else { | 221 | } else { |
222 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, | 222 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, |
223 | trigger & IRQ_TYPE_LEVEL_LOW); | 223 | trigger & IRQ_TYPE_LEVEL_LOW); |
224 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, | 224 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, |
225 | trigger & IRQ_TYPE_LEVEL_HIGH); | 225 | trigger & IRQ_TYPE_LEVEL_HIGH); |
226 | MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, | 226 | MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, |
227 | trigger & IRQ_TYPE_EDGE_RISING); | 227 | trigger & IRQ_TYPE_EDGE_RISING); |
228 | MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, | 228 | MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, |
229 | trigger & IRQ_TYPE_EDGE_FALLING); | 229 | trigger & IRQ_TYPE_EDGE_FALLING); |
230 | } | 230 | } |
231 | if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { | 231 | if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { |
232 | if (cpu_is_omap44xx()) { | 232 | if (cpu_is_omap44xx()) { |
233 | MOD_REG_BIT(OMAP4_GPIO_IRQWAKEN0, gpio_bit, | 233 | MOD_REG_BIT(OMAP4_GPIO_IRQWAKEN0, gpio_bit, |
234 | trigger != 0); | 234 | trigger != 0); |
235 | } else { | 235 | } else { |
236 | /* | 236 | /* |
237 | * GPIO wakeup request can only be generated on edge | 237 | * GPIO wakeup request can only be generated on edge |
238 | * transitions | 238 | * transitions |
239 | */ | 239 | */ |
240 | if (trigger & IRQ_TYPE_EDGE_BOTH) | 240 | if (trigger & IRQ_TYPE_EDGE_BOTH) |
241 | __raw_writel(1 << gpio, bank->base | 241 | __raw_writel(1 << gpio, bank->base |
242 | + OMAP24XX_GPIO_SETWKUENA); | 242 | + OMAP24XX_GPIO_SETWKUENA); |
243 | else | 243 | else |
244 | __raw_writel(1 << gpio, bank->base | 244 | __raw_writel(1 << gpio, bank->base |
245 | + OMAP24XX_GPIO_CLEARWKUENA); | 245 | + OMAP24XX_GPIO_CLEARWKUENA); |
246 | } | 246 | } |
247 | } | 247 | } |
248 | /* This part needs to be executed always for OMAP34xx */ | 248 | /* This part needs to be executed always for OMAP34xx */ |
249 | if (cpu_is_omap34xx() || (bank->non_wakeup_gpios & gpio_bit)) { | 249 | if (cpu_is_omap34xx() || (bank->non_wakeup_gpios & gpio_bit)) { |
250 | /* | 250 | /* |
251 | * Log the edge gpio and manually trigger the IRQ | 251 | * Log the edge gpio and manually trigger the IRQ |
252 | * after resume if the input level changes | 252 | * after resume if the input level changes |
253 | * to avoid irq lost during PER RET/OFF mode | 253 | * to avoid irq lost during PER RET/OFF mode |
254 | * Applies for omap2 non-wakeup gpio and all omap3 gpios | 254 | * Applies for omap2 non-wakeup gpio and all omap3 gpios |
255 | */ | 255 | */ |
256 | if (trigger & IRQ_TYPE_EDGE_BOTH) | 256 | if (trigger & IRQ_TYPE_EDGE_BOTH) |
257 | bank->enabled_non_wakeup_gpios |= gpio_bit; | 257 | bank->enabled_non_wakeup_gpios |= gpio_bit; |
258 | else | 258 | else |
259 | bank->enabled_non_wakeup_gpios &= ~gpio_bit; | 259 | bank->enabled_non_wakeup_gpios &= ~gpio_bit; |
260 | } | 260 | } |
261 | 261 | ||
262 | if (cpu_is_omap44xx()) { | 262 | if (cpu_is_omap44xx()) { |
263 | bank->level_mask = | 263 | bank->level_mask = |
264 | __raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT0) | | 264 | __raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT0) | |
265 | __raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT1); | 265 | __raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT1); |
266 | } else { | 266 | } else { |
267 | bank->level_mask = | 267 | bank->level_mask = |
268 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) | | 268 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) | |
269 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); | 269 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); |
270 | } | 270 | } |
271 | } | 271 | } |
272 | #endif | 272 | #endif |
273 | 273 | ||
274 | #ifdef CONFIG_ARCH_OMAP1 | 274 | #ifdef CONFIG_ARCH_OMAP1 |
275 | /* | 275 | /* |
276 | * This only applies to chips that can't do both rising and falling edge | 276 | * This only applies to chips that can't do both rising and falling edge |
277 | * detection at once. For all other chips, this function is a noop. | 277 | * detection at once. For all other chips, this function is a noop. |
278 | */ | 278 | */ |
279 | static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) | 279 | static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) |
280 | { | 280 | { |
281 | void __iomem *reg = bank->base; | 281 | void __iomem *reg = bank->base; |
282 | u32 l = 0; | 282 | u32 l = 0; |
283 | 283 | ||
284 | switch (bank->method) { | 284 | switch (bank->method) { |
285 | case METHOD_MPUIO: | 285 | case METHOD_MPUIO: |
286 | reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride; | 286 | reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride; |
287 | break; | 287 | break; |
288 | #ifdef CONFIG_ARCH_OMAP15XX | 288 | #ifdef CONFIG_ARCH_OMAP15XX |
289 | case METHOD_GPIO_1510: | 289 | case METHOD_GPIO_1510: |
290 | reg += OMAP1510_GPIO_INT_CONTROL; | 290 | reg += OMAP1510_GPIO_INT_CONTROL; |
291 | break; | 291 | break; |
292 | #endif | 292 | #endif |
293 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | 293 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) |
294 | case METHOD_GPIO_7XX: | 294 | case METHOD_GPIO_7XX: |
295 | reg += OMAP7XX_GPIO_INT_CONTROL; | 295 | reg += OMAP7XX_GPIO_INT_CONTROL; |
296 | break; | 296 | break; |
297 | #endif | 297 | #endif |
298 | default: | 298 | default: |
299 | return; | 299 | return; |
300 | } | 300 | } |
301 | 301 | ||
302 | l = __raw_readl(reg); | 302 | l = __raw_readl(reg); |
303 | if ((l >> gpio) & 1) | 303 | if ((l >> gpio) & 1) |
304 | l &= ~(1 << gpio); | 304 | l &= ~(1 << gpio); |
305 | else | 305 | else |
306 | l |= 1 << gpio; | 306 | l |= 1 << gpio; |
307 | 307 | ||
308 | __raw_writel(l, reg); | 308 | __raw_writel(l, reg); |
309 | } | 309 | } |
310 | #endif | 310 | #endif |
311 | 311 | ||
312 | static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) | 312 | static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) |
313 | { | 313 | { |
314 | void __iomem *reg = bank->base; | 314 | void __iomem *reg = bank->base; |
315 | u32 l = 0; | 315 | u32 l = 0; |
316 | 316 | ||
317 | switch (bank->method) { | 317 | switch (bank->method) { |
318 | #ifdef CONFIG_ARCH_OMAP1 | 318 | #ifdef CONFIG_ARCH_OMAP1 |
319 | case METHOD_MPUIO: | 319 | case METHOD_MPUIO: |
320 | reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride; | 320 | reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride; |
321 | l = __raw_readl(reg); | 321 | l = __raw_readl(reg); |
322 | if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) | 322 | if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) |
323 | bank->toggle_mask |= 1 << gpio; | 323 | bank->toggle_mask |= 1 << gpio; |
324 | if (trigger & IRQ_TYPE_EDGE_RISING) | 324 | if (trigger & IRQ_TYPE_EDGE_RISING) |
325 | l |= 1 << gpio; | 325 | l |= 1 << gpio; |
326 | else if (trigger & IRQ_TYPE_EDGE_FALLING) | 326 | else if (trigger & IRQ_TYPE_EDGE_FALLING) |
327 | l &= ~(1 << gpio); | 327 | l &= ~(1 << gpio); |
328 | else | 328 | else |
329 | goto bad; | 329 | goto bad; |
330 | break; | 330 | break; |
331 | #endif | 331 | #endif |
332 | #ifdef CONFIG_ARCH_OMAP15XX | 332 | #ifdef CONFIG_ARCH_OMAP15XX |
333 | case METHOD_GPIO_1510: | 333 | case METHOD_GPIO_1510: |
334 | reg += OMAP1510_GPIO_INT_CONTROL; | 334 | reg += OMAP1510_GPIO_INT_CONTROL; |
335 | l = __raw_readl(reg); | 335 | l = __raw_readl(reg); |
336 | if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) | 336 | if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) |
337 | bank->toggle_mask |= 1 << gpio; | 337 | bank->toggle_mask |= 1 << gpio; |
338 | if (trigger & IRQ_TYPE_EDGE_RISING) | 338 | if (trigger & IRQ_TYPE_EDGE_RISING) |
339 | l |= 1 << gpio; | 339 | l |= 1 << gpio; |
340 | else if (trigger & IRQ_TYPE_EDGE_FALLING) | 340 | else if (trigger & IRQ_TYPE_EDGE_FALLING) |
341 | l &= ~(1 << gpio); | 341 | l &= ~(1 << gpio); |
342 | else | 342 | else |
343 | goto bad; | 343 | goto bad; |
344 | break; | 344 | break; |
345 | #endif | 345 | #endif |
346 | #ifdef CONFIG_ARCH_OMAP16XX | 346 | #ifdef CONFIG_ARCH_OMAP16XX |
347 | case METHOD_GPIO_1610: | 347 | case METHOD_GPIO_1610: |
348 | if (gpio & 0x08) | 348 | if (gpio & 0x08) |
349 | reg += OMAP1610_GPIO_EDGE_CTRL2; | 349 | reg += OMAP1610_GPIO_EDGE_CTRL2; |
350 | else | 350 | else |
351 | reg += OMAP1610_GPIO_EDGE_CTRL1; | 351 | reg += OMAP1610_GPIO_EDGE_CTRL1; |
352 | gpio &= 0x07; | 352 | gpio &= 0x07; |
353 | l = __raw_readl(reg); | 353 | l = __raw_readl(reg); |
354 | l &= ~(3 << (gpio << 1)); | 354 | l &= ~(3 << (gpio << 1)); |
355 | if (trigger & IRQ_TYPE_EDGE_RISING) | 355 | if (trigger & IRQ_TYPE_EDGE_RISING) |
356 | l |= 2 << (gpio << 1); | 356 | l |= 2 << (gpio << 1); |
357 | if (trigger & IRQ_TYPE_EDGE_FALLING) | 357 | if (trigger & IRQ_TYPE_EDGE_FALLING) |
358 | l |= 1 << (gpio << 1); | 358 | l |= 1 << (gpio << 1); |
359 | if (trigger) | 359 | if (trigger) |
360 | /* Enable wake-up during idle for dynamic tick */ | 360 | /* Enable wake-up during idle for dynamic tick */ |
361 | __raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_SET_WAKEUPENA); | 361 | __raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_SET_WAKEUPENA); |
362 | else | 362 | else |
363 | __raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA); | 363 | __raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA); |
364 | break; | 364 | break; |
365 | #endif | 365 | #endif |
366 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | 366 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) |
367 | case METHOD_GPIO_7XX: | 367 | case METHOD_GPIO_7XX: |
368 | reg += OMAP7XX_GPIO_INT_CONTROL; | 368 | reg += OMAP7XX_GPIO_INT_CONTROL; |
369 | l = __raw_readl(reg); | 369 | l = __raw_readl(reg); |
370 | if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) | 370 | if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) |
371 | bank->toggle_mask |= 1 << gpio; | 371 | bank->toggle_mask |= 1 << gpio; |
372 | if (trigger & IRQ_TYPE_EDGE_RISING) | 372 | if (trigger & IRQ_TYPE_EDGE_RISING) |
373 | l |= 1 << gpio; | 373 | l |= 1 << gpio; |
374 | else if (trigger & IRQ_TYPE_EDGE_FALLING) | 374 | else if (trigger & IRQ_TYPE_EDGE_FALLING) |
375 | l &= ~(1 << gpio); | 375 | l &= ~(1 << gpio); |
376 | else | 376 | else |
377 | goto bad; | 377 | goto bad; |
378 | break; | 378 | break; |
379 | #endif | 379 | #endif |
380 | #ifdef CONFIG_ARCH_OMAP2PLUS | 380 | #ifdef CONFIG_ARCH_OMAP2PLUS |
381 | case METHOD_GPIO_24XX: | 381 | case METHOD_GPIO_24XX: |
382 | case METHOD_GPIO_44XX: | 382 | case METHOD_GPIO_44XX: |
383 | set_24xx_gpio_triggering(bank, gpio, trigger); | 383 | set_24xx_gpio_triggering(bank, gpio, trigger); |
384 | return 0; | 384 | return 0; |
385 | #endif | 385 | #endif |
386 | default: | 386 | default: |
387 | goto bad; | 387 | goto bad; |
388 | } | 388 | } |
389 | __raw_writel(l, reg); | 389 | __raw_writel(l, reg); |
390 | return 0; | 390 | return 0; |
391 | bad: | 391 | bad: |
392 | return -EINVAL; | 392 | return -EINVAL; |
393 | } | 393 | } |
394 | 394 | ||
395 | static int gpio_irq_type(struct irq_data *d, unsigned type) | 395 | static int gpio_irq_type(struct irq_data *d, unsigned type) |
396 | { | 396 | { |
397 | struct gpio_bank *bank; | 397 | struct gpio_bank *bank; |
398 | unsigned gpio; | 398 | unsigned gpio; |
399 | int retval; | 399 | int retval; |
400 | unsigned long flags; | 400 | unsigned long flags; |
401 | 401 | ||
402 | if (!cpu_class_is_omap2() && d->irq > IH_MPUIO_BASE) | 402 | if (!cpu_class_is_omap2() && d->irq > IH_MPUIO_BASE) |
403 | gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE); | 403 | gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE); |
404 | else | 404 | else |
405 | gpio = d->irq - IH_GPIO_BASE; | 405 | gpio = d->irq - IH_GPIO_BASE; |
406 | 406 | ||
407 | if (type & ~IRQ_TYPE_SENSE_MASK) | 407 | if (type & ~IRQ_TYPE_SENSE_MASK) |
408 | return -EINVAL; | 408 | return -EINVAL; |
409 | 409 | ||
410 | /* OMAP1 allows only only edge triggering */ | 410 | /* OMAP1 allows only only edge triggering */ |
411 | if (!cpu_class_is_omap2() | 411 | if (!cpu_class_is_omap2() |
412 | && (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))) | 412 | && (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))) |
413 | return -EINVAL; | 413 | return -EINVAL; |
414 | 414 | ||
415 | bank = irq_data_get_irq_chip_data(d); | 415 | bank = irq_data_get_irq_chip_data(d); |
416 | spin_lock_irqsave(&bank->lock, flags); | 416 | spin_lock_irqsave(&bank->lock, flags); |
417 | retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type); | 417 | retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type); |
418 | spin_unlock_irqrestore(&bank->lock, flags); | 418 | spin_unlock_irqrestore(&bank->lock, flags); |
419 | 419 | ||
420 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) | 420 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) |
421 | __irq_set_handler_locked(d->irq, handle_level_irq); | 421 | __irq_set_handler_locked(d->irq, handle_level_irq); |
422 | else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | 422 | else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) |
423 | __irq_set_handler_locked(d->irq, handle_edge_irq); | 423 | __irq_set_handler_locked(d->irq, handle_edge_irq); |
424 | 424 | ||
425 | return retval; | 425 | return retval; |
426 | } | 426 | } |
427 | 427 | ||
428 | static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) | 428 | static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) |
429 | { | 429 | { |
430 | void __iomem *reg = bank->base; | 430 | void __iomem *reg = bank->base; |
431 | 431 | ||
432 | reg += bank->regs->irqstatus; | 432 | reg += bank->regs->irqstatus; |
433 | __raw_writel(gpio_mask, reg); | 433 | __raw_writel(gpio_mask, reg); |
434 | 434 | ||
435 | /* Workaround for clearing DSP GPIO interrupts to allow retention */ | 435 | /* Workaround for clearing DSP GPIO interrupts to allow retention */ |
436 | if (bank->regs->irqstatus2) { | 436 | if (bank->regs->irqstatus2) { |
437 | reg = bank->base + bank->regs->irqstatus2; | 437 | reg = bank->base + bank->regs->irqstatus2; |
438 | __raw_writel(gpio_mask, reg); | 438 | __raw_writel(gpio_mask, reg); |
439 | } | 439 | } |
440 | 440 | ||
441 | /* Flush posted write for the irq status to avoid spurious interrupts */ | 441 | /* Flush posted write for the irq status to avoid spurious interrupts */ |
442 | __raw_readl(reg); | 442 | __raw_readl(reg); |
443 | } | 443 | } |
444 | 444 | ||
445 | static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) | 445 | static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) |
446 | { | 446 | { |
447 | _clear_gpio_irqbank(bank, GPIO_BIT(bank, gpio)); | 447 | _clear_gpio_irqbank(bank, GPIO_BIT(bank, gpio)); |
448 | } | 448 | } |
449 | 449 | ||
450 | static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) | 450 | static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) |
451 | { | 451 | { |
452 | void __iomem *reg = bank->base; | 452 | void __iomem *reg = bank->base; |
453 | u32 l; | 453 | u32 l; |
454 | u32 mask = (1 << bank->width) - 1; | 454 | u32 mask = (1 << bank->width) - 1; |
455 | 455 | ||
456 | reg += bank->regs->irqenable; | 456 | reg += bank->regs->irqenable; |
457 | l = __raw_readl(reg); | 457 | l = __raw_readl(reg); |
458 | if (bank->regs->irqenable_inv) | 458 | if (bank->regs->irqenable_inv) |
459 | l = ~l; | 459 | l = ~l; |
460 | l &= mask; | 460 | l &= mask; |
461 | return l; | 461 | return l; |
462 | } | 462 | } |
463 | 463 | ||
464 | static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) | 464 | static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) |
465 | { | 465 | { |
466 | void __iomem *reg = bank->base; | 466 | void __iomem *reg = bank->base; |
467 | u32 l; | 467 | u32 l; |
468 | 468 | ||
469 | if (bank->regs->set_irqenable) { | 469 | if (bank->regs->set_irqenable) { |
470 | reg += bank->regs->set_irqenable; | 470 | reg += bank->regs->set_irqenable; |
471 | l = gpio_mask; | 471 | l = gpio_mask; |
472 | } else { | 472 | } else { |
473 | reg += bank->regs->irqenable; | 473 | reg += bank->regs->irqenable; |
474 | l = __raw_readl(reg); | 474 | l = __raw_readl(reg); |
475 | if (bank->regs->irqenable_inv) | 475 | if (bank->regs->irqenable_inv) |
476 | l &= ~gpio_mask; | 476 | l &= ~gpio_mask; |
477 | else | 477 | else |
478 | l |= gpio_mask; | 478 | l |= gpio_mask; |
479 | } | 479 | } |
480 | 480 | ||
481 | __raw_writel(l, reg); | 481 | __raw_writel(l, reg); |
482 | } | 482 | } |
483 | 483 | ||
484 | static void _disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) | 484 | static void _disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) |
485 | { | 485 | { |
486 | void __iomem *reg = bank->base; | 486 | void __iomem *reg = bank->base; |
487 | u32 l; | 487 | u32 l; |
488 | 488 | ||
489 | if (bank->regs->clr_irqenable) { | 489 | if (bank->regs->clr_irqenable) { |
490 | reg += bank->regs->clr_irqenable; | 490 | reg += bank->regs->clr_irqenable; |
491 | l = gpio_mask; | 491 | l = gpio_mask; |
492 | } else { | 492 | } else { |
493 | reg += bank->regs->irqenable; | 493 | reg += bank->regs->irqenable; |
494 | l = __raw_readl(reg); | 494 | l = __raw_readl(reg); |
495 | if (bank->regs->irqenable_inv) | 495 | if (bank->regs->irqenable_inv) |
496 | l |= gpio_mask; | 496 | l |= gpio_mask; |
497 | else | 497 | else |
498 | l &= ~gpio_mask; | 498 | l &= ~gpio_mask; |
499 | } | 499 | } |
500 | 500 | ||
501 | __raw_writel(l, reg); | 501 | __raw_writel(l, reg); |
502 | } | 502 | } |
503 | 503 | ||
504 | static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable) | 504 | static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable) |
505 | { | 505 | { |
506 | _enable_gpio_irqbank(bank, GPIO_BIT(bank, gpio)); | 506 | _enable_gpio_irqbank(bank, GPIO_BIT(bank, gpio)); |
507 | } | 507 | } |
508 | 508 | ||
509 | /* | 509 | /* |
510 | * Note that ENAWAKEUP needs to be enabled in GPIO_SYSCONFIG register. | 510 | * Note that ENAWAKEUP needs to be enabled in GPIO_SYSCONFIG register. |
511 | * 1510 does not seem to have a wake-up register. If JTAG is connected | 511 | * 1510 does not seem to have a wake-up register. If JTAG is connected |
512 | * to the target, system will wake up always on GPIO events. While | 512 | * to the target, system will wake up always on GPIO events. While |
513 | * system is running all registered GPIO interrupts need to have wake-up | 513 | * system is running all registered GPIO interrupts need to have wake-up |
514 | * enabled. When system is suspended, only selected GPIO interrupts need | 514 | * enabled. When system is suspended, only selected GPIO interrupts need |
515 | * to have wake-up enabled. | 515 | * to have wake-up enabled. |
516 | */ | 516 | */ |
517 | static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) | 517 | static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) |
518 | { | 518 | { |
519 | u32 gpio_bit = GPIO_BIT(bank, gpio); | 519 | u32 gpio_bit = GPIO_BIT(bank, gpio); |
520 | unsigned long flags; | 520 | unsigned long flags; |
521 | 521 | ||
522 | if (bank->non_wakeup_gpios & gpio_bit) { | 522 | if (bank->non_wakeup_gpios & gpio_bit) { |
523 | dev_err(bank->dev, | 523 | dev_err(bank->dev, |
524 | "Unable to modify wakeup on non-wakeup GPIO%d\n", gpio); | 524 | "Unable to modify wakeup on non-wakeup GPIO%d\n", gpio); |
525 | return -EINVAL; | 525 | return -EINVAL; |
526 | } | 526 | } |
527 | 527 | ||
528 | spin_lock_irqsave(&bank->lock, flags); | 528 | spin_lock_irqsave(&bank->lock, flags); |
529 | if (enable) | 529 | if (enable) |
530 | bank->suspend_wakeup |= gpio_bit; | 530 | bank->suspend_wakeup |= gpio_bit; |
531 | else | 531 | else |
532 | bank->suspend_wakeup &= ~gpio_bit; | 532 | bank->suspend_wakeup &= ~gpio_bit; |
533 | 533 | ||
534 | spin_unlock_irqrestore(&bank->lock, flags); | 534 | spin_unlock_irqrestore(&bank->lock, flags); |
535 | 535 | ||
536 | return 0; | 536 | return 0; |
537 | } | 537 | } |
538 | 538 | ||
539 | static void _reset_gpio(struct gpio_bank *bank, int gpio) | 539 | static void _reset_gpio(struct gpio_bank *bank, int gpio) |
540 | { | 540 | { |
541 | _set_gpio_direction(bank, GPIO_INDEX(bank, gpio), 1); | 541 | _set_gpio_direction(bank, GPIO_INDEX(bank, gpio), 1); |
542 | _set_gpio_irqenable(bank, gpio, 0); | 542 | _set_gpio_irqenable(bank, gpio, 0); |
543 | _clear_gpio_irqstatus(bank, gpio); | 543 | _clear_gpio_irqstatus(bank, gpio); |
544 | _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE); | 544 | _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE); |
545 | } | 545 | } |
546 | 546 | ||
547 | /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ | 547 | /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ |
548 | static int gpio_wake_enable(struct irq_data *d, unsigned int enable) | 548 | static int gpio_wake_enable(struct irq_data *d, unsigned int enable) |
549 | { | 549 | { |
550 | unsigned int gpio = d->irq - IH_GPIO_BASE; | 550 | unsigned int gpio = d->irq - IH_GPIO_BASE; |
551 | struct gpio_bank *bank; | 551 | struct gpio_bank *bank; |
552 | int retval; | 552 | int retval; |
553 | 553 | ||
554 | bank = irq_data_get_irq_chip_data(d); | 554 | bank = irq_data_get_irq_chip_data(d); |
555 | retval = _set_gpio_wakeup(bank, gpio, enable); | 555 | retval = _set_gpio_wakeup(bank, gpio, enable); |
556 | 556 | ||
557 | return retval; | 557 | return retval; |
558 | } | 558 | } |
559 | 559 | ||
560 | static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) | 560 | static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) |
561 | { | 561 | { |
562 | struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); | 562 | struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); |
563 | unsigned long flags; | 563 | unsigned long flags; |
564 | 564 | ||
565 | spin_lock_irqsave(&bank->lock, flags); | 565 | spin_lock_irqsave(&bank->lock, flags); |
566 | 566 | ||
567 | /* Set trigger to none. You need to enable the desired trigger with | 567 | /* Set trigger to none. You need to enable the desired trigger with |
568 | * request_irq() or set_irq_type(). | 568 | * request_irq() or set_irq_type(). |
569 | */ | 569 | */ |
570 | _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); | 570 | _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); |
571 | 571 | ||
572 | #ifdef CONFIG_ARCH_OMAP15XX | 572 | #ifdef CONFIG_ARCH_OMAP15XX |
573 | if (bank->method == METHOD_GPIO_1510) { | 573 | if (bank->method == METHOD_GPIO_1510) { |
574 | void __iomem *reg; | 574 | void __iomem *reg; |
575 | 575 | ||
576 | /* Claim the pin for MPU */ | 576 | /* Claim the pin for MPU */ |
577 | reg = bank->base + OMAP1510_GPIO_PIN_CONTROL; | 577 | reg = bank->base + OMAP1510_GPIO_PIN_CONTROL; |
578 | __raw_writel(__raw_readl(reg) | (1 << offset), reg); | 578 | __raw_writel(__raw_readl(reg) | (1 << offset), reg); |
579 | } | 579 | } |
580 | #endif | 580 | #endif |
581 | if (!cpu_class_is_omap1()) { | 581 | if (!cpu_class_is_omap1()) { |
582 | if (!bank->mod_usage) { | 582 | if (!bank->mod_usage) { |
583 | void __iomem *reg = bank->base; | 583 | void __iomem *reg = bank->base; |
584 | u32 ctrl; | 584 | u32 ctrl; |
585 | 585 | ||
586 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) | 586 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) |
587 | reg += OMAP24XX_GPIO_CTRL; | 587 | reg += OMAP24XX_GPIO_CTRL; |
588 | else if (cpu_is_omap44xx()) | 588 | else if (cpu_is_omap44xx()) |
589 | reg += OMAP4_GPIO_CTRL; | 589 | reg += OMAP4_GPIO_CTRL; |
590 | ctrl = __raw_readl(reg); | 590 | ctrl = __raw_readl(reg); |
591 | /* Module is enabled, clocks are not gated */ | 591 | /* Module is enabled, clocks are not gated */ |
592 | ctrl &= 0xFFFFFFFE; | 592 | ctrl &= 0xFFFFFFFE; |
593 | __raw_writel(ctrl, reg); | 593 | __raw_writel(ctrl, reg); |
594 | } | 594 | } |
595 | bank->mod_usage |= 1 << offset; | 595 | bank->mod_usage |= 1 << offset; |
596 | } | 596 | } |
597 | spin_unlock_irqrestore(&bank->lock, flags); | 597 | spin_unlock_irqrestore(&bank->lock, flags); |
598 | 598 | ||
599 | return 0; | 599 | return 0; |
600 | } | 600 | } |
601 | 601 | ||
602 | static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) | 602 | static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) |
603 | { | 603 | { |
604 | struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); | 604 | struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); |
605 | unsigned long flags; | 605 | unsigned long flags; |
606 | 606 | ||
607 | spin_lock_irqsave(&bank->lock, flags); | 607 | spin_lock_irqsave(&bank->lock, flags); |
608 | #ifdef CONFIG_ARCH_OMAP16XX | 608 | #ifdef CONFIG_ARCH_OMAP16XX |
609 | if (bank->method == METHOD_GPIO_1610) { | 609 | if (bank->method == METHOD_GPIO_1610) { |
610 | /* Disable wake-up during idle for dynamic tick */ | 610 | /* Disable wake-up during idle for dynamic tick */ |
611 | void __iomem *reg = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; | 611 | void __iomem *reg = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; |
612 | __raw_writel(1 << offset, reg); | 612 | __raw_writel(1 << offset, reg); |
613 | } | 613 | } |
614 | #endif | 614 | #endif |
615 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | 615 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) |
616 | if (bank->method == METHOD_GPIO_24XX) { | 616 | if (bank->method == METHOD_GPIO_24XX) { |
617 | /* Disable wake-up during idle for dynamic tick */ | 617 | /* Disable wake-up during idle for dynamic tick */ |
618 | void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA; | 618 | void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA; |
619 | __raw_writel(1 << offset, reg); | 619 | __raw_writel(1 << offset, reg); |
620 | } | 620 | } |
621 | #endif | 621 | #endif |
622 | #ifdef CONFIG_ARCH_OMAP4 | 622 | #ifdef CONFIG_ARCH_OMAP4 |
623 | if (bank->method == METHOD_GPIO_44XX) { | 623 | if (bank->method == METHOD_GPIO_44XX) { |
624 | /* Disable wake-up during idle for dynamic tick */ | 624 | /* Disable wake-up during idle for dynamic tick */ |
625 | void __iomem *reg = bank->base + OMAP4_GPIO_IRQWAKEN0; | 625 | void __iomem *reg = bank->base + OMAP4_GPIO_IRQWAKEN0; |
626 | __raw_writel(1 << offset, reg); | 626 | __raw_writel(1 << offset, reg); |
627 | } | 627 | } |
628 | #endif | 628 | #endif |
629 | if (!cpu_class_is_omap1()) { | 629 | if (!cpu_class_is_omap1()) { |
630 | bank->mod_usage &= ~(1 << offset); | 630 | bank->mod_usage &= ~(1 << offset); |
631 | if (!bank->mod_usage) { | 631 | if (!bank->mod_usage) { |
632 | void __iomem *reg = bank->base; | 632 | void __iomem *reg = bank->base; |
633 | u32 ctrl; | 633 | u32 ctrl; |
634 | 634 | ||
635 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) | 635 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) |
636 | reg += OMAP24XX_GPIO_CTRL; | 636 | reg += OMAP24XX_GPIO_CTRL; |
637 | else if (cpu_is_omap44xx()) | 637 | else if (cpu_is_omap44xx()) |
638 | reg += OMAP4_GPIO_CTRL; | 638 | reg += OMAP4_GPIO_CTRL; |
639 | ctrl = __raw_readl(reg); | 639 | ctrl = __raw_readl(reg); |
640 | /* Module is disabled, clocks are gated */ | 640 | /* Module is disabled, clocks are gated */ |
641 | ctrl |= 1; | 641 | ctrl |= 1; |
642 | __raw_writel(ctrl, reg); | 642 | __raw_writel(ctrl, reg); |
643 | } | 643 | } |
644 | } | 644 | } |
645 | _reset_gpio(bank, bank->chip.base + offset); | 645 | _reset_gpio(bank, bank->chip.base + offset); |
646 | spin_unlock_irqrestore(&bank->lock, flags); | 646 | spin_unlock_irqrestore(&bank->lock, flags); |
647 | } | 647 | } |
648 | 648 | ||
649 | /* | 649 | /* |
650 | * We need to unmask the GPIO bank interrupt as soon as possible to | 650 | * We need to unmask the GPIO bank interrupt as soon as possible to |
651 | * avoid missing GPIO interrupts for other lines in the bank. | 651 | * avoid missing GPIO interrupts for other lines in the bank. |
652 | * Then we need to mask-read-clear-unmask the triggered GPIO lines | 652 | * Then we need to mask-read-clear-unmask the triggered GPIO lines |
653 | * in the bank to avoid missing nested interrupts for a GPIO line. | 653 | * in the bank to avoid missing nested interrupts for a GPIO line. |
654 | * If we wait to unmask individual GPIO lines in the bank after the | 654 | * If we wait to unmask individual GPIO lines in the bank after the |
655 | * line's interrupt handler has been run, we may miss some nested | 655 | * line's interrupt handler has been run, we may miss some nested |
656 | * interrupts. | 656 | * interrupts. |
657 | */ | 657 | */ |
658 | static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | 658 | static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) |
659 | { | 659 | { |
660 | void __iomem *isr_reg = NULL; | 660 | void __iomem *isr_reg = NULL; |
661 | u32 isr; | 661 | u32 isr; |
662 | unsigned int gpio_irq, gpio_index; | 662 | unsigned int gpio_irq, gpio_index; |
663 | struct gpio_bank *bank; | 663 | struct gpio_bank *bank; |
664 | u32 retrigger = 0; | 664 | u32 retrigger = 0; |
665 | int unmasked = 0; | 665 | int unmasked = 0; |
666 | struct irq_chip *chip = irq_desc_get_chip(desc); | 666 | struct irq_chip *chip = irq_desc_get_chip(desc); |
667 | 667 | ||
668 | chained_irq_enter(chip, desc); | 668 | chained_irq_enter(chip, desc); |
669 | 669 | ||
670 | bank = irq_get_handler_data(irq); | 670 | bank = irq_get_handler_data(irq); |
671 | isr_reg = bank->base + bank->regs->irqstatus; | 671 | isr_reg = bank->base + bank->regs->irqstatus; |
672 | 672 | ||
673 | if (WARN_ON(!isr_reg)) | 673 | if (WARN_ON(!isr_reg)) |
674 | goto exit; | 674 | goto exit; |
675 | 675 | ||
676 | while(1) { | 676 | while(1) { |
677 | u32 isr_saved, level_mask = 0; | 677 | u32 isr_saved, level_mask = 0; |
678 | u32 enabled; | 678 | u32 enabled; |
679 | 679 | ||
680 | enabled = _get_gpio_irqbank_mask(bank); | 680 | enabled = _get_gpio_irqbank_mask(bank); |
681 | isr_saved = isr = __raw_readl(isr_reg) & enabled; | 681 | isr_saved = isr = __raw_readl(isr_reg) & enabled; |
682 | 682 | ||
683 | if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO)) | 683 | if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO)) |
684 | isr &= 0x0000ffff; | 684 | isr &= 0x0000ffff; |
685 | 685 | ||
686 | if (cpu_class_is_omap2()) { | 686 | if (cpu_class_is_omap2()) { |
687 | level_mask = bank->level_mask & enabled; | 687 | level_mask = bank->level_mask & enabled; |
688 | } | 688 | } |
689 | 689 | ||
690 | /* clear edge sensitive interrupts before handler(s) are | 690 | /* clear edge sensitive interrupts before handler(s) are |
691 | called so that we don't miss any interrupt occurred while | 691 | called so that we don't miss any interrupt occurred while |
692 | executing them */ | 692 | executing them */ |
693 | _disable_gpio_irqbank(bank, isr_saved & ~level_mask); | 693 | _disable_gpio_irqbank(bank, isr_saved & ~level_mask); |
694 | _clear_gpio_irqbank(bank, isr_saved & ~level_mask); | 694 | _clear_gpio_irqbank(bank, isr_saved & ~level_mask); |
695 | _enable_gpio_irqbank(bank, isr_saved & ~level_mask); | 695 | _enable_gpio_irqbank(bank, isr_saved & ~level_mask); |
696 | 696 | ||
697 | /* if there is only edge sensitive GPIO pin interrupts | 697 | /* if there is only edge sensitive GPIO pin interrupts |
698 | configured, we could unmask GPIO bank interrupt immediately */ | 698 | configured, we could unmask GPIO bank interrupt immediately */ |
699 | if (!level_mask && !unmasked) { | 699 | if (!level_mask && !unmasked) { |
700 | unmasked = 1; | 700 | unmasked = 1; |
701 | chained_irq_exit(chip, desc); | 701 | chained_irq_exit(chip, desc); |
702 | } | 702 | } |
703 | 703 | ||
704 | isr |= retrigger; | 704 | isr |= retrigger; |
705 | retrigger = 0; | 705 | retrigger = 0; |
706 | if (!isr) | 706 | if (!isr) |
707 | break; | 707 | break; |
708 | 708 | ||
709 | gpio_irq = bank->virtual_irq_start; | 709 | gpio_irq = bank->virtual_irq_start; |
710 | for (; isr != 0; isr >>= 1, gpio_irq++) { | 710 | for (; isr != 0; isr >>= 1, gpio_irq++) { |
711 | gpio_index = GPIO_INDEX(bank, irq_to_gpio(gpio_irq)); | 711 | gpio_index = GPIO_INDEX(bank, irq_to_gpio(gpio_irq)); |
712 | 712 | ||
713 | if (!(isr & 1)) | 713 | if (!(isr & 1)) |
714 | continue; | 714 | continue; |
715 | 715 | ||
716 | #ifdef CONFIG_ARCH_OMAP1 | 716 | #ifdef CONFIG_ARCH_OMAP1 |
717 | /* | 717 | /* |
718 | * Some chips can't respond to both rising and falling | 718 | * Some chips can't respond to both rising and falling |
719 | * at the same time. If this irq was requested with | 719 | * at the same time. If this irq was requested with |
720 | * both flags, we need to flip the ICR data for the IRQ | 720 | * both flags, we need to flip the ICR data for the IRQ |
721 | * to respond to the IRQ for the opposite direction. | 721 | * to respond to the IRQ for the opposite direction. |
722 | * This will be indicated in the bank toggle_mask. | 722 | * This will be indicated in the bank toggle_mask. |
723 | */ | 723 | */ |
724 | if (bank->toggle_mask & (1 << gpio_index)) | 724 | if (bank->toggle_mask & (1 << gpio_index)) |
725 | _toggle_gpio_edge_triggering(bank, gpio_index); | 725 | _toggle_gpio_edge_triggering(bank, gpio_index); |
726 | #endif | 726 | #endif |
727 | 727 | ||
728 | generic_handle_irq(gpio_irq); | 728 | generic_handle_irq(gpio_irq); |
729 | } | 729 | } |
730 | } | 730 | } |
731 | /* if bank has any level sensitive GPIO pin interrupt | 731 | /* if bank has any level sensitive GPIO pin interrupt |
732 | configured, we must unmask the bank interrupt only after | 732 | configured, we must unmask the bank interrupt only after |
733 | handler(s) are executed in order to avoid spurious bank | 733 | handler(s) are executed in order to avoid spurious bank |
734 | interrupt */ | 734 | interrupt */ |
735 | exit: | 735 | exit: |
736 | if (!unmasked) | 736 | if (!unmasked) |
737 | chained_irq_exit(chip, desc); | 737 | chained_irq_exit(chip, desc); |
738 | } | 738 | } |
739 | 739 | ||
740 | static void gpio_irq_shutdown(struct irq_data *d) | 740 | static void gpio_irq_shutdown(struct irq_data *d) |
741 | { | 741 | { |
742 | unsigned int gpio = d->irq - IH_GPIO_BASE; | 742 | unsigned int gpio = d->irq - IH_GPIO_BASE; |
743 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 743 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
744 | unsigned long flags; | 744 | unsigned long flags; |
745 | 745 | ||
746 | spin_lock_irqsave(&bank->lock, flags); | 746 | spin_lock_irqsave(&bank->lock, flags); |
747 | _reset_gpio(bank, gpio); | 747 | _reset_gpio(bank, gpio); |
748 | spin_unlock_irqrestore(&bank->lock, flags); | 748 | spin_unlock_irqrestore(&bank->lock, flags); |
749 | } | 749 | } |
750 | 750 | ||
751 | static void gpio_ack_irq(struct irq_data *d) | 751 | static void gpio_ack_irq(struct irq_data *d) |
752 | { | 752 | { |
753 | unsigned int gpio = d->irq - IH_GPIO_BASE; | 753 | unsigned int gpio = d->irq - IH_GPIO_BASE; |
754 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 754 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
755 | 755 | ||
756 | _clear_gpio_irqstatus(bank, gpio); | 756 | _clear_gpio_irqstatus(bank, gpio); |
757 | } | 757 | } |
758 | 758 | ||
759 | static void gpio_mask_irq(struct irq_data *d) | 759 | static void gpio_mask_irq(struct irq_data *d) |
760 | { | 760 | { |
761 | unsigned int gpio = d->irq - IH_GPIO_BASE; | 761 | unsigned int gpio = d->irq - IH_GPIO_BASE; |
762 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 762 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
763 | unsigned long flags; | 763 | unsigned long flags; |
764 | 764 | ||
765 | spin_lock_irqsave(&bank->lock, flags); | 765 | spin_lock_irqsave(&bank->lock, flags); |
766 | _set_gpio_irqenable(bank, gpio, 0); | 766 | _set_gpio_irqenable(bank, gpio, 0); |
767 | _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE); | 767 | _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE); |
768 | spin_unlock_irqrestore(&bank->lock, flags); | 768 | spin_unlock_irqrestore(&bank->lock, flags); |
769 | } | 769 | } |
770 | 770 | ||
771 | static void gpio_unmask_irq(struct irq_data *d) | 771 | static void gpio_unmask_irq(struct irq_data *d) |
772 | { | 772 | { |
773 | unsigned int gpio = d->irq - IH_GPIO_BASE; | 773 | unsigned int gpio = d->irq - IH_GPIO_BASE; |
774 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 774 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
775 | unsigned int irq_mask = GPIO_BIT(bank, gpio); | 775 | unsigned int irq_mask = GPIO_BIT(bank, gpio); |
776 | u32 trigger = irqd_get_trigger_type(d); | 776 | u32 trigger = irqd_get_trigger_type(d); |
777 | unsigned long flags; | 777 | unsigned long flags; |
778 | 778 | ||
779 | spin_lock_irqsave(&bank->lock, flags); | 779 | spin_lock_irqsave(&bank->lock, flags); |
780 | if (trigger) | 780 | if (trigger) |
781 | _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), trigger); | 781 | _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), trigger); |
782 | 782 | ||
783 | /* For level-triggered GPIOs, the clearing must be done after | 783 | /* For level-triggered GPIOs, the clearing must be done after |
784 | * the HW source is cleared, thus after the handler has run */ | 784 | * the HW source is cleared, thus after the handler has run */ |
785 | if (bank->level_mask & irq_mask) { | 785 | if (bank->level_mask & irq_mask) { |
786 | _set_gpio_irqenable(bank, gpio, 0); | 786 | _set_gpio_irqenable(bank, gpio, 0); |
787 | _clear_gpio_irqstatus(bank, gpio); | 787 | _clear_gpio_irqstatus(bank, gpio); |
788 | } | 788 | } |
789 | 789 | ||
790 | _set_gpio_irqenable(bank, gpio, 1); | 790 | _set_gpio_irqenable(bank, gpio, 1); |
791 | spin_unlock_irqrestore(&bank->lock, flags); | 791 | spin_unlock_irqrestore(&bank->lock, flags); |
792 | } | 792 | } |
793 | 793 | ||
794 | static struct irq_chip gpio_irq_chip = { | 794 | static struct irq_chip gpio_irq_chip = { |
795 | .name = "GPIO", | 795 | .name = "GPIO", |
796 | .irq_shutdown = gpio_irq_shutdown, | 796 | .irq_shutdown = gpio_irq_shutdown, |
797 | .irq_ack = gpio_ack_irq, | 797 | .irq_ack = gpio_ack_irq, |
798 | .irq_mask = gpio_mask_irq, | 798 | .irq_mask = gpio_mask_irq, |
799 | .irq_unmask = gpio_unmask_irq, | 799 | .irq_unmask = gpio_unmask_irq, |
800 | .irq_set_type = gpio_irq_type, | 800 | .irq_set_type = gpio_irq_type, |
801 | .irq_set_wake = gpio_wake_enable, | 801 | .irq_set_wake = gpio_wake_enable, |
802 | }; | 802 | }; |
803 | 803 | ||
804 | /*---------------------------------------------------------------------*/ | 804 | /*---------------------------------------------------------------------*/ |
805 | 805 | ||
806 | #ifdef CONFIG_ARCH_OMAP1 | 806 | #ifdef CONFIG_ARCH_OMAP1 |
807 | 807 | ||
808 | #define bank_is_mpuio(bank) ((bank)->method == METHOD_MPUIO) | 808 | #define bank_is_mpuio(bank) ((bank)->method == METHOD_MPUIO) |
809 | 809 | ||
810 | #ifdef CONFIG_ARCH_OMAP16XX | 810 | #ifdef CONFIG_ARCH_OMAP16XX |
811 | 811 | ||
812 | #include <linux/platform_device.h> | 812 | #include <linux/platform_device.h> |
813 | 813 | ||
814 | static int omap_mpuio_suspend_noirq(struct device *dev) | 814 | static int omap_mpuio_suspend_noirq(struct device *dev) |
815 | { | 815 | { |
816 | struct platform_device *pdev = to_platform_device(dev); | 816 | struct platform_device *pdev = to_platform_device(dev); |
817 | struct gpio_bank *bank = platform_get_drvdata(pdev); | 817 | struct gpio_bank *bank = platform_get_drvdata(pdev); |
818 | void __iomem *mask_reg = bank->base + | 818 | void __iomem *mask_reg = bank->base + |
819 | OMAP_MPUIO_GPIO_MASKIT / bank->stride; | 819 | OMAP_MPUIO_GPIO_MASKIT / bank->stride; |
820 | unsigned long flags; | 820 | unsigned long flags; |
821 | 821 | ||
822 | spin_lock_irqsave(&bank->lock, flags); | 822 | spin_lock_irqsave(&bank->lock, flags); |
823 | bank->saved_wakeup = __raw_readl(mask_reg); | 823 | bank->saved_wakeup = __raw_readl(mask_reg); |
824 | __raw_writel(0xffff & ~bank->suspend_wakeup, mask_reg); | 824 | __raw_writel(0xffff & ~bank->suspend_wakeup, mask_reg); |
825 | spin_unlock_irqrestore(&bank->lock, flags); | 825 | spin_unlock_irqrestore(&bank->lock, flags); |
826 | 826 | ||
827 | return 0; | 827 | return 0; |
828 | } | 828 | } |
829 | 829 | ||
830 | static int omap_mpuio_resume_noirq(struct device *dev) | 830 | static int omap_mpuio_resume_noirq(struct device *dev) |
831 | { | 831 | { |
832 | struct platform_device *pdev = to_platform_device(dev); | 832 | struct platform_device *pdev = to_platform_device(dev); |
833 | struct gpio_bank *bank = platform_get_drvdata(pdev); | 833 | struct gpio_bank *bank = platform_get_drvdata(pdev); |
834 | void __iomem *mask_reg = bank->base + | 834 | void __iomem *mask_reg = bank->base + |
835 | OMAP_MPUIO_GPIO_MASKIT / bank->stride; | 835 | OMAP_MPUIO_GPIO_MASKIT / bank->stride; |
836 | unsigned long flags; | 836 | unsigned long flags; |
837 | 837 | ||
838 | spin_lock_irqsave(&bank->lock, flags); | 838 | spin_lock_irqsave(&bank->lock, flags); |
839 | __raw_writel(bank->saved_wakeup, mask_reg); | 839 | __raw_writel(bank->saved_wakeup, mask_reg); |
840 | spin_unlock_irqrestore(&bank->lock, flags); | 840 | spin_unlock_irqrestore(&bank->lock, flags); |
841 | 841 | ||
842 | return 0; | 842 | return 0; |
843 | } | 843 | } |
844 | 844 | ||
845 | static const struct dev_pm_ops omap_mpuio_dev_pm_ops = { | 845 | static const struct dev_pm_ops omap_mpuio_dev_pm_ops = { |
846 | .suspend_noirq = omap_mpuio_suspend_noirq, | 846 | .suspend_noirq = omap_mpuio_suspend_noirq, |
847 | .resume_noirq = omap_mpuio_resume_noirq, | 847 | .resume_noirq = omap_mpuio_resume_noirq, |
848 | }; | 848 | }; |
849 | 849 | ||
850 | /* use platform_driver for this. */ | 850 | /* use platform_driver for this. */ |
851 | static struct platform_driver omap_mpuio_driver = { | 851 | static struct platform_driver omap_mpuio_driver = { |
852 | .driver = { | 852 | .driver = { |
853 | .name = "mpuio", | 853 | .name = "mpuio", |
854 | .pm = &omap_mpuio_dev_pm_ops, | 854 | .pm = &omap_mpuio_dev_pm_ops, |
855 | }, | 855 | }, |
856 | }; | 856 | }; |
857 | 857 | ||
858 | static struct platform_device omap_mpuio_device = { | 858 | static struct platform_device omap_mpuio_device = { |
859 | .name = "mpuio", | 859 | .name = "mpuio", |
860 | .id = -1, | 860 | .id = -1, |
861 | .dev = { | 861 | .dev = { |
862 | .driver = &omap_mpuio_driver.driver, | 862 | .driver = &omap_mpuio_driver.driver, |
863 | } | 863 | } |
864 | /* could list the /proc/iomem resources */ | 864 | /* could list the /proc/iomem resources */ |
865 | }; | 865 | }; |
866 | 866 | ||
867 | static inline void mpuio_init(void) | 867 | static inline void mpuio_init(void) |
868 | { | 868 | { |
869 | struct gpio_bank *bank = &gpio_bank[0]; | 869 | struct gpio_bank *bank = &gpio_bank[0]; |
870 | platform_set_drvdata(&omap_mpuio_device, bank); | 870 | platform_set_drvdata(&omap_mpuio_device, bank); |
871 | 871 | ||
872 | if (platform_driver_register(&omap_mpuio_driver) == 0) | 872 | if (platform_driver_register(&omap_mpuio_driver) == 0) |
873 | (void) platform_device_register(&omap_mpuio_device); | 873 | (void) platform_device_register(&omap_mpuio_device); |
874 | } | 874 | } |
875 | 875 | ||
876 | #else | 876 | #else |
877 | static inline void mpuio_init(void) {} | 877 | static inline void mpuio_init(void) {} |
878 | #endif /* 16xx */ | 878 | #endif /* 16xx */ |
879 | 879 | ||
880 | #else | 880 | #else |
881 | 881 | ||
882 | #define bank_is_mpuio(bank) 0 | 882 | #define bank_is_mpuio(bank) 0 |
883 | static inline void mpuio_init(void) {} | 883 | static inline void mpuio_init(void) {} |
884 | 884 | ||
885 | #endif | 885 | #endif |
886 | 886 | ||
887 | /*---------------------------------------------------------------------*/ | 887 | /*---------------------------------------------------------------------*/ |
888 | 888 | ||
889 | /* REVISIT these are stupid implementations! replace by ones that | 889 | /* REVISIT these are stupid implementations! replace by ones that |
890 | * don't switch on METHOD_* and which mostly avoid spinlocks | 890 | * don't switch on METHOD_* and which mostly avoid spinlocks |
891 | */ | 891 | */ |
892 | 892 | ||
893 | static int gpio_input(struct gpio_chip *chip, unsigned offset) | 893 | static int gpio_input(struct gpio_chip *chip, unsigned offset) |
894 | { | 894 | { |
895 | struct gpio_bank *bank; | 895 | struct gpio_bank *bank; |
896 | unsigned long flags; | 896 | unsigned long flags; |
897 | 897 | ||
898 | bank = container_of(chip, struct gpio_bank, chip); | 898 | bank = container_of(chip, struct gpio_bank, chip); |
899 | spin_lock_irqsave(&bank->lock, flags); | 899 | spin_lock_irqsave(&bank->lock, flags); |
900 | _set_gpio_direction(bank, offset, 1); | 900 | _set_gpio_direction(bank, offset, 1); |
901 | spin_unlock_irqrestore(&bank->lock, flags); | 901 | spin_unlock_irqrestore(&bank->lock, flags); |
902 | return 0; | 902 | return 0; |
903 | } | 903 | } |
904 | 904 | ||
905 | static int gpio_is_input(struct gpio_bank *bank, int mask) | 905 | static int gpio_is_input(struct gpio_bank *bank, int mask) |
906 | { | 906 | { |
907 | void __iomem *reg = bank->base + bank->regs->direction; | 907 | void __iomem *reg = bank->base + bank->regs->direction; |
908 | 908 | ||
909 | return __raw_readl(reg) & mask; | 909 | return __raw_readl(reg) & mask; |
910 | } | 910 | } |
911 | 911 | ||
912 | static int gpio_get(struct gpio_chip *chip, unsigned offset) | 912 | static int gpio_get(struct gpio_chip *chip, unsigned offset) |
913 | { | 913 | { |
914 | struct gpio_bank *bank; | 914 | struct gpio_bank *bank; |
915 | void __iomem *reg; | 915 | void __iomem *reg; |
916 | int gpio; | 916 | int gpio; |
917 | u32 mask; | 917 | u32 mask; |
918 | 918 | ||
919 | gpio = chip->base + offset; | 919 | gpio = chip->base + offset; |
920 | bank = container_of(chip, struct gpio_bank, chip); | 920 | bank = container_of(chip, struct gpio_bank, chip); |
921 | reg = bank->base; | 921 | reg = bank->base; |
922 | mask = GPIO_BIT(bank, gpio); | 922 | mask = GPIO_BIT(bank, gpio); |
923 | 923 | ||
924 | if (gpio_is_input(bank, mask)) | 924 | if (gpio_is_input(bank, mask)) |
925 | return _get_gpio_datain(bank, gpio); | 925 | return _get_gpio_datain(bank, gpio); |
926 | else | 926 | else |
927 | return _get_gpio_dataout(bank, gpio); | 927 | return _get_gpio_dataout(bank, gpio); |
928 | } | 928 | } |
929 | 929 | ||
930 | static int gpio_output(struct gpio_chip *chip, unsigned offset, int value) | 930 | static int gpio_output(struct gpio_chip *chip, unsigned offset, int value) |
931 | { | 931 | { |
932 | struct gpio_bank *bank; | 932 | struct gpio_bank *bank; |
933 | unsigned long flags; | 933 | unsigned long flags; |
934 | 934 | ||
935 | bank = container_of(chip, struct gpio_bank, chip); | 935 | bank = container_of(chip, struct gpio_bank, chip); |
936 | spin_lock_irqsave(&bank->lock, flags); | 936 | spin_lock_irqsave(&bank->lock, flags); |
937 | bank->set_dataout(bank, offset, value); | 937 | bank->set_dataout(bank, offset, value); |
938 | _set_gpio_direction(bank, offset, 0); | 938 | _set_gpio_direction(bank, offset, 0); |
939 | spin_unlock_irqrestore(&bank->lock, flags); | 939 | spin_unlock_irqrestore(&bank->lock, flags); |
940 | return 0; | 940 | return 0; |
941 | } | 941 | } |
942 | 942 | ||
943 | static int gpio_debounce(struct gpio_chip *chip, unsigned offset, | 943 | static int gpio_debounce(struct gpio_chip *chip, unsigned offset, |
944 | unsigned debounce) | 944 | unsigned debounce) |
945 | { | 945 | { |
946 | struct gpio_bank *bank; | 946 | struct gpio_bank *bank; |
947 | unsigned long flags; | 947 | unsigned long flags; |
948 | 948 | ||
949 | bank = container_of(chip, struct gpio_bank, chip); | 949 | bank = container_of(chip, struct gpio_bank, chip); |
950 | 950 | ||
951 | if (!bank->dbck) { | 951 | if (!bank->dbck) { |
952 | bank->dbck = clk_get(bank->dev, "dbclk"); | 952 | bank->dbck = clk_get(bank->dev, "dbclk"); |
953 | if (IS_ERR(bank->dbck)) | 953 | if (IS_ERR(bank->dbck)) |
954 | dev_err(bank->dev, "Could not get gpio dbck\n"); | 954 | dev_err(bank->dev, "Could not get gpio dbck\n"); |
955 | } | 955 | } |
956 | 956 | ||
957 | spin_lock_irqsave(&bank->lock, flags); | 957 | spin_lock_irqsave(&bank->lock, flags); |
958 | _set_gpio_debounce(bank, offset, debounce); | 958 | _set_gpio_debounce(bank, offset, debounce); |
959 | spin_unlock_irqrestore(&bank->lock, flags); | 959 | spin_unlock_irqrestore(&bank->lock, flags); |
960 | 960 | ||
961 | return 0; | 961 | return 0; |
962 | } | 962 | } |
963 | 963 | ||
964 | static void gpio_set(struct gpio_chip *chip, unsigned offset, int value) | 964 | static void gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
965 | { | 965 | { |
966 | struct gpio_bank *bank; | 966 | struct gpio_bank *bank; |
967 | unsigned long flags; | 967 | unsigned long flags; |
968 | 968 | ||
969 | bank = container_of(chip, struct gpio_bank, chip); | 969 | bank = container_of(chip, struct gpio_bank, chip); |
970 | spin_lock_irqsave(&bank->lock, flags); | 970 | spin_lock_irqsave(&bank->lock, flags); |
971 | bank->set_dataout(bank, offset, value); | 971 | bank->set_dataout(bank, offset, value); |
972 | spin_unlock_irqrestore(&bank->lock, flags); | 972 | spin_unlock_irqrestore(&bank->lock, flags); |
973 | } | 973 | } |
974 | 974 | ||
975 | static int gpio_2irq(struct gpio_chip *chip, unsigned offset) | 975 | static int gpio_2irq(struct gpio_chip *chip, unsigned offset) |
976 | { | 976 | { |
977 | struct gpio_bank *bank; | 977 | struct gpio_bank *bank; |
978 | 978 | ||
979 | bank = container_of(chip, struct gpio_bank, chip); | 979 | bank = container_of(chip, struct gpio_bank, chip); |
980 | return bank->virtual_irq_start + offset; | 980 | return bank->virtual_irq_start + offset; |
981 | } | 981 | } |
982 | 982 | ||
983 | /*---------------------------------------------------------------------*/ | 983 | /*---------------------------------------------------------------------*/ |
984 | 984 | ||
985 | static void __init omap_gpio_show_rev(struct gpio_bank *bank) | 985 | static void __init omap_gpio_show_rev(struct gpio_bank *bank) |
986 | { | 986 | { |
987 | static bool called; | ||
987 | u32 rev; | 988 | u32 rev; |
988 | 989 | ||
989 | if (cpu_is_omap16xx() && !(bank->method != METHOD_MPUIO)) | 990 | if (called || bank->regs->revision == USHRT_MAX) |
990 | rev = __raw_readw(bank->base + OMAP1610_GPIO_REVISION); | ||
991 | else if (cpu_is_omap24xx() || cpu_is_omap34xx()) | ||
992 | rev = __raw_readl(bank->base + OMAP24XX_GPIO_REVISION); | ||
993 | else if (cpu_is_omap44xx()) | ||
994 | rev = __raw_readl(bank->base + OMAP4_GPIO_REVISION); | ||
995 | else | ||
996 | return; | 991 | return; |
997 | 992 | ||
998 | printk(KERN_INFO "OMAP GPIO hardware version %d.%d\n", | 993 | rev = __raw_readw(bank->base + bank->regs->revision); |
994 | pr_info("OMAP GPIO hardware version %d.%d\n", | ||
999 | (rev >> 4) & 0x0f, rev & 0x0f); | 995 | (rev >> 4) & 0x0f, rev & 0x0f); |
996 | |||
997 | called = true; | ||
1000 | } | 998 | } |
1001 | 999 | ||
1002 | /* This lock class tells lockdep that GPIO irqs are in a different | 1000 | /* This lock class tells lockdep that GPIO irqs are in a different |
1003 | * category than their parents, so it won't report false recursion. | 1001 | * category than their parents, so it won't report false recursion. |
1004 | */ | 1002 | */ |
1005 | static struct lock_class_key gpio_lock_class; | 1003 | static struct lock_class_key gpio_lock_class; |
1006 | 1004 | ||
1007 | static inline int init_gpio_info(struct platform_device *pdev) | 1005 | static inline int init_gpio_info(struct platform_device *pdev) |
1008 | { | 1006 | { |
1009 | /* TODO: Analyze removing gpio_bank_count usage from driver code */ | 1007 | /* TODO: Analyze removing gpio_bank_count usage from driver code */ |
1010 | gpio_bank = kzalloc(gpio_bank_count * sizeof(struct gpio_bank), | 1008 | gpio_bank = kzalloc(gpio_bank_count * sizeof(struct gpio_bank), |
1011 | GFP_KERNEL); | 1009 | GFP_KERNEL); |
1012 | if (!gpio_bank) { | 1010 | if (!gpio_bank) { |
1013 | dev_err(&pdev->dev, "Memory alloc failed for gpio_bank\n"); | 1011 | dev_err(&pdev->dev, "Memory alloc failed for gpio_bank\n"); |
1014 | return -ENOMEM; | 1012 | return -ENOMEM; |
1015 | } | 1013 | } |
1016 | return 0; | 1014 | return 0; |
1017 | } | 1015 | } |
1018 | 1016 | ||
1019 | /* TODO: Cleanup cpu_is_* checks */ | 1017 | /* TODO: Cleanup cpu_is_* checks */ |
1020 | static void omap_gpio_mod_init(struct gpio_bank *bank, int id) | 1018 | static void omap_gpio_mod_init(struct gpio_bank *bank, int id) |
1021 | { | 1019 | { |
1022 | if (cpu_class_is_omap2()) { | 1020 | if (cpu_class_is_omap2()) { |
1023 | if (cpu_is_omap44xx()) { | 1021 | if (cpu_is_omap44xx()) { |
1024 | __raw_writel(0xffffffff, bank->base + | 1022 | __raw_writel(0xffffffff, bank->base + |
1025 | OMAP4_GPIO_IRQSTATUSCLR0); | 1023 | OMAP4_GPIO_IRQSTATUSCLR0); |
1026 | __raw_writel(0x00000000, bank->base + | 1024 | __raw_writel(0x00000000, bank->base + |
1027 | OMAP4_GPIO_DEBOUNCENABLE); | 1025 | OMAP4_GPIO_DEBOUNCENABLE); |
1028 | /* Initialize interface clk ungated, module enabled */ | 1026 | /* Initialize interface clk ungated, module enabled */ |
1029 | __raw_writel(0, bank->base + OMAP4_GPIO_CTRL); | 1027 | __raw_writel(0, bank->base + OMAP4_GPIO_CTRL); |
1030 | } else if (cpu_is_omap34xx()) { | 1028 | } else if (cpu_is_omap34xx()) { |
1031 | __raw_writel(0x00000000, bank->base + | 1029 | __raw_writel(0x00000000, bank->base + |
1032 | OMAP24XX_GPIO_IRQENABLE1); | 1030 | OMAP24XX_GPIO_IRQENABLE1); |
1033 | __raw_writel(0xffffffff, bank->base + | 1031 | __raw_writel(0xffffffff, bank->base + |
1034 | OMAP24XX_GPIO_IRQSTATUS1); | 1032 | OMAP24XX_GPIO_IRQSTATUS1); |
1035 | __raw_writel(0x00000000, bank->base + | 1033 | __raw_writel(0x00000000, bank->base + |
1036 | OMAP24XX_GPIO_DEBOUNCE_EN); | 1034 | OMAP24XX_GPIO_DEBOUNCE_EN); |
1037 | 1035 | ||
1038 | /* Initialize interface clk ungated, module enabled */ | 1036 | /* Initialize interface clk ungated, module enabled */ |
1039 | __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL); | 1037 | __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL); |
1040 | } else if (cpu_is_omap24xx()) { | 1038 | } else if (cpu_is_omap24xx()) { |
1041 | static const u32 non_wakeup_gpios[] = { | 1039 | static const u32 non_wakeup_gpios[] = { |
1042 | 0xe203ffc0, 0x08700040 | 1040 | 0xe203ffc0, 0x08700040 |
1043 | }; | 1041 | }; |
1044 | if (id < ARRAY_SIZE(non_wakeup_gpios)) | 1042 | if (id < ARRAY_SIZE(non_wakeup_gpios)) |
1045 | bank->non_wakeup_gpios = non_wakeup_gpios[id]; | 1043 | bank->non_wakeup_gpios = non_wakeup_gpios[id]; |
1046 | } | 1044 | } |
1047 | } else if (cpu_class_is_omap1()) { | 1045 | } else if (cpu_class_is_omap1()) { |
1048 | if (bank_is_mpuio(bank)) | 1046 | if (bank_is_mpuio(bank)) |
1049 | __raw_writew(0xffff, bank->base + | 1047 | __raw_writew(0xffff, bank->base + |
1050 | OMAP_MPUIO_GPIO_MASKIT / bank->stride); | 1048 | OMAP_MPUIO_GPIO_MASKIT / bank->stride); |
1051 | if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) { | 1049 | if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) { |
1052 | __raw_writew(0xffff, bank->base | 1050 | __raw_writew(0xffff, bank->base |
1053 | + OMAP1510_GPIO_INT_MASK); | 1051 | + OMAP1510_GPIO_INT_MASK); |
1054 | __raw_writew(0x0000, bank->base | 1052 | __raw_writew(0x0000, bank->base |
1055 | + OMAP1510_GPIO_INT_STATUS); | 1053 | + OMAP1510_GPIO_INT_STATUS); |
1056 | } | 1054 | } |
1057 | if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) { | 1055 | if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) { |
1058 | __raw_writew(0x0000, bank->base | 1056 | __raw_writew(0x0000, bank->base |
1059 | + OMAP1610_GPIO_IRQENABLE1); | 1057 | + OMAP1610_GPIO_IRQENABLE1); |
1060 | __raw_writew(0xffff, bank->base | 1058 | __raw_writew(0xffff, bank->base |
1061 | + OMAP1610_GPIO_IRQSTATUS1); | 1059 | + OMAP1610_GPIO_IRQSTATUS1); |
1062 | __raw_writew(0x0014, bank->base | 1060 | __raw_writew(0x0014, bank->base |
1063 | + OMAP1610_GPIO_SYSCONFIG); | 1061 | + OMAP1610_GPIO_SYSCONFIG); |
1064 | 1062 | ||
1065 | /* | 1063 | /* |
1066 | * Enable system clock for GPIO module. | 1064 | * Enable system clock for GPIO module. |
1067 | * The CAM_CLK_CTRL *is* really the right place. | 1065 | * The CAM_CLK_CTRL *is* really the right place. |
1068 | */ | 1066 | */ |
1069 | omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, | 1067 | omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, |
1070 | ULPD_CAM_CLK_CTRL); | 1068 | ULPD_CAM_CLK_CTRL); |
1071 | } | 1069 | } |
1072 | if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) { | 1070 | if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) { |
1073 | __raw_writel(0xffffffff, bank->base | 1071 | __raw_writel(0xffffffff, bank->base |
1074 | + OMAP7XX_GPIO_INT_MASK); | 1072 | + OMAP7XX_GPIO_INT_MASK); |
1075 | __raw_writel(0x00000000, bank->base | 1073 | __raw_writel(0x00000000, bank->base |
1076 | + OMAP7XX_GPIO_INT_STATUS); | 1074 | + OMAP7XX_GPIO_INT_STATUS); |
1077 | } | 1075 | } |
1078 | } | 1076 | } |
1079 | } | 1077 | } |
1080 | 1078 | ||
1081 | static __init void | 1079 | static __init void |
1082 | omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, | 1080 | omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, |
1083 | unsigned int num) | 1081 | unsigned int num) |
1084 | { | 1082 | { |
1085 | struct irq_chip_generic *gc; | 1083 | struct irq_chip_generic *gc; |
1086 | struct irq_chip_type *ct; | 1084 | struct irq_chip_type *ct; |
1087 | 1085 | ||
1088 | gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base, | 1086 | gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base, |
1089 | handle_simple_irq); | 1087 | handle_simple_irq); |
1090 | ct = gc->chip_types; | 1088 | ct = gc->chip_types; |
1091 | 1089 | ||
1092 | /* NOTE: No ack required, reading IRQ status clears it. */ | 1090 | /* NOTE: No ack required, reading IRQ status clears it. */ |
1093 | ct->chip.irq_mask = irq_gc_mask_set_bit; | 1091 | ct->chip.irq_mask = irq_gc_mask_set_bit; |
1094 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; | 1092 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; |
1095 | ct->chip.irq_set_type = gpio_irq_type; | 1093 | ct->chip.irq_set_type = gpio_irq_type; |
1096 | /* REVISIT: assuming only 16xx supports MPUIO wake events */ | 1094 | /* REVISIT: assuming only 16xx supports MPUIO wake events */ |
1097 | if (cpu_is_omap16xx()) | 1095 | if (cpu_is_omap16xx()) |
1098 | ct->chip.irq_set_wake = gpio_wake_enable, | 1096 | ct->chip.irq_set_wake = gpio_wake_enable, |
1099 | 1097 | ||
1100 | ct->regs.mask = OMAP_MPUIO_GPIO_INT / bank->stride; | 1098 | ct->regs.mask = OMAP_MPUIO_GPIO_INT / bank->stride; |
1101 | irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, | 1099 | irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, |
1102 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | 1100 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); |
1103 | } | 1101 | } |
1104 | 1102 | ||
1105 | static void __devinit omap_gpio_chip_init(struct gpio_bank *bank) | 1103 | static void __devinit omap_gpio_chip_init(struct gpio_bank *bank) |
1106 | { | 1104 | { |
1107 | int j; | 1105 | int j; |
1108 | static int gpio; | 1106 | static int gpio; |
1109 | 1107 | ||
1110 | bank->mod_usage = 0; | 1108 | bank->mod_usage = 0; |
1111 | /* | 1109 | /* |
1112 | * REVISIT eventually switch from OMAP-specific gpio structs | 1110 | * REVISIT eventually switch from OMAP-specific gpio structs |
1113 | * over to the generic ones | 1111 | * over to the generic ones |
1114 | */ | 1112 | */ |
1115 | bank->chip.request = omap_gpio_request; | 1113 | bank->chip.request = omap_gpio_request; |
1116 | bank->chip.free = omap_gpio_free; | 1114 | bank->chip.free = omap_gpio_free; |
1117 | bank->chip.direction_input = gpio_input; | 1115 | bank->chip.direction_input = gpio_input; |
1118 | bank->chip.get = gpio_get; | 1116 | bank->chip.get = gpio_get; |
1119 | bank->chip.direction_output = gpio_output; | 1117 | bank->chip.direction_output = gpio_output; |
1120 | bank->chip.set_debounce = gpio_debounce; | 1118 | bank->chip.set_debounce = gpio_debounce; |
1121 | bank->chip.set = gpio_set; | 1119 | bank->chip.set = gpio_set; |
1122 | bank->chip.to_irq = gpio_2irq; | 1120 | bank->chip.to_irq = gpio_2irq; |
1123 | if (bank_is_mpuio(bank)) { | 1121 | if (bank_is_mpuio(bank)) { |
1124 | bank->chip.label = "mpuio"; | 1122 | bank->chip.label = "mpuio"; |
1125 | #ifdef CONFIG_ARCH_OMAP16XX | 1123 | #ifdef CONFIG_ARCH_OMAP16XX |
1126 | bank->chip.dev = &omap_mpuio_device.dev; | 1124 | bank->chip.dev = &omap_mpuio_device.dev; |
1127 | #endif | 1125 | #endif |
1128 | bank->chip.base = OMAP_MPUIO(0); | 1126 | bank->chip.base = OMAP_MPUIO(0); |
1129 | } else { | 1127 | } else { |
1130 | bank->chip.label = "gpio"; | 1128 | bank->chip.label = "gpio"; |
1131 | bank->chip.base = gpio; | 1129 | bank->chip.base = gpio; |
1132 | gpio += bank->width; | 1130 | gpio += bank->width; |
1133 | } | 1131 | } |
1134 | bank->chip.ngpio = bank->width; | 1132 | bank->chip.ngpio = bank->width; |
1135 | 1133 | ||
1136 | gpiochip_add(&bank->chip); | 1134 | gpiochip_add(&bank->chip); |
1137 | 1135 | ||
1138 | for (j = bank->virtual_irq_start; | 1136 | for (j = bank->virtual_irq_start; |
1139 | j < bank->virtual_irq_start + bank->width; j++) { | 1137 | j < bank->virtual_irq_start + bank->width; j++) { |
1140 | irq_set_lockdep_class(j, &gpio_lock_class); | 1138 | irq_set_lockdep_class(j, &gpio_lock_class); |
1141 | irq_set_chip_data(j, bank); | 1139 | irq_set_chip_data(j, bank); |
1142 | if (bank_is_mpuio(bank)) { | 1140 | if (bank_is_mpuio(bank)) { |
1143 | omap_mpuio_alloc_gc(bank, j, bank->width); | 1141 | omap_mpuio_alloc_gc(bank, j, bank->width); |
1144 | } else { | 1142 | } else { |
1145 | irq_set_chip(j, &gpio_irq_chip); | 1143 | irq_set_chip(j, &gpio_irq_chip); |
1146 | irq_set_handler(j, handle_simple_irq); | 1144 | irq_set_handler(j, handle_simple_irq); |
1147 | set_irq_flags(j, IRQF_VALID); | 1145 | set_irq_flags(j, IRQF_VALID); |
1148 | } | 1146 | } |
1149 | } | 1147 | } |
1150 | irq_set_chained_handler(bank->irq, gpio_irq_handler); | 1148 | irq_set_chained_handler(bank->irq, gpio_irq_handler); |
1151 | irq_set_handler_data(bank->irq, bank); | 1149 | irq_set_handler_data(bank->irq, bank); |
1152 | } | 1150 | } |
1153 | 1151 | ||
1154 | static int __devinit omap_gpio_probe(struct platform_device *pdev) | 1152 | static int __devinit omap_gpio_probe(struct platform_device *pdev) |
1155 | { | 1153 | { |
1156 | static int gpio_init_done; | 1154 | static int gpio_init_done; |
1157 | struct omap_gpio_platform_data *pdata; | 1155 | struct omap_gpio_platform_data *pdata; |
1158 | struct resource *res; | 1156 | struct resource *res; |
1159 | int id; | 1157 | int id; |
1160 | struct gpio_bank *bank; | 1158 | struct gpio_bank *bank; |
1161 | 1159 | ||
1162 | if (!pdev->dev.platform_data) | 1160 | if (!pdev->dev.platform_data) |
1163 | return -EINVAL; | 1161 | return -EINVAL; |
1164 | 1162 | ||
1165 | pdata = pdev->dev.platform_data; | 1163 | pdata = pdev->dev.platform_data; |
1166 | 1164 | ||
1167 | if (!gpio_init_done) { | 1165 | if (!gpio_init_done) { |
1168 | int ret; | 1166 | int ret; |
1169 | 1167 | ||
1170 | ret = init_gpio_info(pdev); | 1168 | ret = init_gpio_info(pdev); |
1171 | if (ret) | 1169 | if (ret) |
1172 | return ret; | 1170 | return ret; |
1173 | } | 1171 | } |
1174 | 1172 | ||
1175 | id = pdev->id; | 1173 | id = pdev->id; |
1176 | bank = &gpio_bank[id]; | 1174 | bank = &gpio_bank[id]; |
1177 | 1175 | ||
1178 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 1176 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
1179 | if (unlikely(!res)) { | 1177 | if (unlikely(!res)) { |
1180 | dev_err(&pdev->dev, "GPIO Bank %i Invalid IRQ resource\n", id); | 1178 | dev_err(&pdev->dev, "GPIO Bank %i Invalid IRQ resource\n", id); |
1181 | return -ENODEV; | 1179 | return -ENODEV; |
1182 | } | 1180 | } |
1183 | 1181 | ||
1184 | bank->irq = res->start; | 1182 | bank->irq = res->start; |
1185 | bank->virtual_irq_start = pdata->virtual_irq_start; | 1183 | bank->virtual_irq_start = pdata->virtual_irq_start; |
1186 | bank->method = pdata->bank_type; | 1184 | bank->method = pdata->bank_type; |
1187 | bank->dev = &pdev->dev; | 1185 | bank->dev = &pdev->dev; |
1188 | bank->dbck_flag = pdata->dbck_flag; | 1186 | bank->dbck_flag = pdata->dbck_flag; |
1189 | bank->stride = pdata->bank_stride; | 1187 | bank->stride = pdata->bank_stride; |
1190 | bank->width = pdata->bank_width; | 1188 | bank->width = pdata->bank_width; |
1191 | 1189 | ||
1192 | bank->regs = pdata->regs; | 1190 | bank->regs = pdata->regs; |
1193 | 1191 | ||
1194 | if (bank->regs->set_dataout && bank->regs->clr_dataout) | 1192 | if (bank->regs->set_dataout && bank->regs->clr_dataout) |
1195 | bank->set_dataout = _set_gpio_dataout_reg; | 1193 | bank->set_dataout = _set_gpio_dataout_reg; |
1196 | else | 1194 | else |
1197 | bank->set_dataout = _set_gpio_dataout_mask; | 1195 | bank->set_dataout = _set_gpio_dataout_mask; |
1198 | 1196 | ||
1199 | spin_lock_init(&bank->lock); | 1197 | spin_lock_init(&bank->lock); |
1200 | 1198 | ||
1201 | /* Static mapping, never released */ | 1199 | /* Static mapping, never released */ |
1202 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1200 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1203 | if (unlikely(!res)) { | 1201 | if (unlikely(!res)) { |
1204 | dev_err(&pdev->dev, "GPIO Bank %i Invalid mem resource\n", id); | 1202 | dev_err(&pdev->dev, "GPIO Bank %i Invalid mem resource\n", id); |
1205 | return -ENODEV; | 1203 | return -ENODEV; |
1206 | } | 1204 | } |
1207 | 1205 | ||
1208 | bank->base = ioremap(res->start, resource_size(res)); | 1206 | bank->base = ioremap(res->start, resource_size(res)); |
1209 | if (!bank->base) { | 1207 | if (!bank->base) { |
1210 | dev_err(&pdev->dev, "Could not ioremap gpio bank%i\n", id); | 1208 | dev_err(&pdev->dev, "Could not ioremap gpio bank%i\n", id); |
1211 | return -ENOMEM; | 1209 | return -ENOMEM; |
1212 | } | 1210 | } |
1213 | 1211 | ||
1214 | pm_runtime_enable(bank->dev); | 1212 | pm_runtime_enable(bank->dev); |
1215 | pm_runtime_get_sync(bank->dev); | 1213 | pm_runtime_get_sync(bank->dev); |
1216 | 1214 | ||
1217 | omap_gpio_mod_init(bank, id); | 1215 | omap_gpio_mod_init(bank, id); |
1218 | omap_gpio_chip_init(bank); | 1216 | omap_gpio_chip_init(bank); |
1219 | omap_gpio_show_rev(bank); | 1217 | omap_gpio_show_rev(bank); |
1220 | 1218 | ||
1221 | if (!gpio_init_done) | 1219 | if (!gpio_init_done) |
1222 | gpio_init_done = 1; | 1220 | gpio_init_done = 1; |
1223 | 1221 | ||
1224 | return 0; | 1222 | return 0; |
1225 | } | 1223 | } |
1226 | 1224 | ||
1227 | #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) | 1225 | #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) |
1228 | static int omap_gpio_suspend(void) | 1226 | static int omap_gpio_suspend(void) |
1229 | { | 1227 | { |
1230 | int i; | 1228 | int i; |
1231 | 1229 | ||
1232 | if (!cpu_class_is_omap2() && !cpu_is_omap16xx()) | 1230 | if (!cpu_class_is_omap2() && !cpu_is_omap16xx()) |
1233 | return 0; | 1231 | return 0; |
1234 | 1232 | ||
1235 | for (i = 0; i < gpio_bank_count; i++) { | 1233 | for (i = 0; i < gpio_bank_count; i++) { |
1236 | struct gpio_bank *bank = &gpio_bank[i]; | 1234 | struct gpio_bank *bank = &gpio_bank[i]; |
1237 | void __iomem *wake_status; | 1235 | void __iomem *wake_status; |
1238 | void __iomem *wake_clear; | 1236 | void __iomem *wake_clear; |
1239 | void __iomem *wake_set; | 1237 | void __iomem *wake_set; |
1240 | unsigned long flags; | 1238 | unsigned long flags; |
1241 | 1239 | ||
1242 | switch (bank->method) { | 1240 | switch (bank->method) { |
1243 | #ifdef CONFIG_ARCH_OMAP16XX | 1241 | #ifdef CONFIG_ARCH_OMAP16XX |
1244 | case METHOD_GPIO_1610: | 1242 | case METHOD_GPIO_1610: |
1245 | wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE; | 1243 | wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE; |
1246 | wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; | 1244 | wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; |
1247 | wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; | 1245 | wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; |
1248 | break; | 1246 | break; |
1249 | #endif | 1247 | #endif |
1250 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | 1248 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) |
1251 | case METHOD_GPIO_24XX: | 1249 | case METHOD_GPIO_24XX: |
1252 | wake_status = bank->base + OMAP24XX_GPIO_WAKE_EN; | 1250 | wake_status = bank->base + OMAP24XX_GPIO_WAKE_EN; |
1253 | wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; | 1251 | wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; |
1254 | wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; | 1252 | wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; |
1255 | break; | 1253 | break; |
1256 | #endif | 1254 | #endif |
1257 | #ifdef CONFIG_ARCH_OMAP4 | 1255 | #ifdef CONFIG_ARCH_OMAP4 |
1258 | case METHOD_GPIO_44XX: | 1256 | case METHOD_GPIO_44XX: |
1259 | wake_status = bank->base + OMAP4_GPIO_IRQWAKEN0; | 1257 | wake_status = bank->base + OMAP4_GPIO_IRQWAKEN0; |
1260 | wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0; | 1258 | wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0; |
1261 | wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0; | 1259 | wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0; |
1262 | break; | 1260 | break; |
1263 | #endif | 1261 | #endif |
1264 | default: | 1262 | default: |
1265 | continue; | 1263 | continue; |
1266 | } | 1264 | } |
1267 | 1265 | ||
1268 | spin_lock_irqsave(&bank->lock, flags); | 1266 | spin_lock_irqsave(&bank->lock, flags); |
1269 | bank->saved_wakeup = __raw_readl(wake_status); | 1267 | bank->saved_wakeup = __raw_readl(wake_status); |
1270 | __raw_writel(0xffffffff, wake_clear); | 1268 | __raw_writel(0xffffffff, wake_clear); |
1271 | __raw_writel(bank->suspend_wakeup, wake_set); | 1269 | __raw_writel(bank->suspend_wakeup, wake_set); |
1272 | spin_unlock_irqrestore(&bank->lock, flags); | 1270 | spin_unlock_irqrestore(&bank->lock, flags); |
1273 | } | 1271 | } |
1274 | 1272 | ||
1275 | return 0; | 1273 | return 0; |
1276 | } | 1274 | } |
1277 | 1275 | ||
1278 | static void omap_gpio_resume(void) | 1276 | static void omap_gpio_resume(void) |
1279 | { | 1277 | { |
1280 | int i; | 1278 | int i; |
1281 | 1279 | ||
1282 | if (!cpu_class_is_omap2() && !cpu_is_omap16xx()) | 1280 | if (!cpu_class_is_omap2() && !cpu_is_omap16xx()) |
1283 | return; | 1281 | return; |
1284 | 1282 | ||
1285 | for (i = 0; i < gpio_bank_count; i++) { | 1283 | for (i = 0; i < gpio_bank_count; i++) { |
1286 | struct gpio_bank *bank = &gpio_bank[i]; | 1284 | struct gpio_bank *bank = &gpio_bank[i]; |
1287 | void __iomem *wake_clear; | 1285 | void __iomem *wake_clear; |
1288 | void __iomem *wake_set; | 1286 | void __iomem *wake_set; |
1289 | unsigned long flags; | 1287 | unsigned long flags; |
1290 | 1288 | ||
1291 | switch (bank->method) { | 1289 | switch (bank->method) { |
1292 | #ifdef CONFIG_ARCH_OMAP16XX | 1290 | #ifdef CONFIG_ARCH_OMAP16XX |
1293 | case METHOD_GPIO_1610: | 1291 | case METHOD_GPIO_1610: |
1294 | wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; | 1292 | wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; |
1295 | wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; | 1293 | wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; |
1296 | break; | 1294 | break; |
1297 | #endif | 1295 | #endif |
1298 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | 1296 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) |
1299 | case METHOD_GPIO_24XX: | 1297 | case METHOD_GPIO_24XX: |
1300 | wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; | 1298 | wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; |
1301 | wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; | 1299 | wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; |
1302 | break; | 1300 | break; |
1303 | #endif | 1301 | #endif |
1304 | #ifdef CONFIG_ARCH_OMAP4 | 1302 | #ifdef CONFIG_ARCH_OMAP4 |
1305 | case METHOD_GPIO_44XX: | 1303 | case METHOD_GPIO_44XX: |
1306 | wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0; | 1304 | wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0; |
1307 | wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0; | 1305 | wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0; |
1308 | break; | 1306 | break; |
1309 | #endif | 1307 | #endif |
1310 | default: | 1308 | default: |
1311 | continue; | 1309 | continue; |
1312 | } | 1310 | } |
1313 | 1311 | ||
1314 | spin_lock_irqsave(&bank->lock, flags); | 1312 | spin_lock_irqsave(&bank->lock, flags); |
1315 | __raw_writel(0xffffffff, wake_clear); | 1313 | __raw_writel(0xffffffff, wake_clear); |
1316 | __raw_writel(bank->saved_wakeup, wake_set); | 1314 | __raw_writel(bank->saved_wakeup, wake_set); |
1317 | spin_unlock_irqrestore(&bank->lock, flags); | 1315 | spin_unlock_irqrestore(&bank->lock, flags); |
1318 | } | 1316 | } |
1319 | } | 1317 | } |
1320 | 1318 | ||
1321 | static struct syscore_ops omap_gpio_syscore_ops = { | 1319 | static struct syscore_ops omap_gpio_syscore_ops = { |
1322 | .suspend = omap_gpio_suspend, | 1320 | .suspend = omap_gpio_suspend, |
1323 | .resume = omap_gpio_resume, | 1321 | .resume = omap_gpio_resume, |
1324 | }; | 1322 | }; |
1325 | 1323 | ||
1326 | #endif | 1324 | #endif |
1327 | 1325 | ||
1328 | #ifdef CONFIG_ARCH_OMAP2PLUS | 1326 | #ifdef CONFIG_ARCH_OMAP2PLUS |
1329 | 1327 | ||
1330 | static int workaround_enabled; | 1328 | static int workaround_enabled; |
1331 | 1329 | ||
1332 | void omap2_gpio_prepare_for_idle(int off_mode) | 1330 | void omap2_gpio_prepare_for_idle(int off_mode) |
1333 | { | 1331 | { |
1334 | int i, c = 0; | 1332 | int i, c = 0; |
1335 | int min = 0; | 1333 | int min = 0; |
1336 | 1334 | ||
1337 | if (cpu_is_omap34xx()) | 1335 | if (cpu_is_omap34xx()) |
1338 | min = 1; | 1336 | min = 1; |
1339 | 1337 | ||
1340 | for (i = min; i < gpio_bank_count; i++) { | 1338 | for (i = min; i < gpio_bank_count; i++) { |
1341 | struct gpio_bank *bank = &gpio_bank[i]; | 1339 | struct gpio_bank *bank = &gpio_bank[i]; |
1342 | u32 l1 = 0, l2 = 0; | 1340 | u32 l1 = 0, l2 = 0; |
1343 | int j; | 1341 | int j; |
1344 | 1342 | ||
1345 | for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++) | 1343 | for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++) |
1346 | clk_disable(bank->dbck); | 1344 | clk_disable(bank->dbck); |
1347 | 1345 | ||
1348 | if (!off_mode) | 1346 | if (!off_mode) |
1349 | continue; | 1347 | continue; |
1350 | 1348 | ||
1351 | /* If going to OFF, remove triggering for all | 1349 | /* If going to OFF, remove triggering for all |
1352 | * non-wakeup GPIOs. Otherwise spurious IRQs will be | 1350 | * non-wakeup GPIOs. Otherwise spurious IRQs will be |
1353 | * generated. See OMAP2420 Errata item 1.101. */ | 1351 | * generated. See OMAP2420 Errata item 1.101. */ |
1354 | if (!(bank->enabled_non_wakeup_gpios)) | 1352 | if (!(bank->enabled_non_wakeup_gpios)) |
1355 | continue; | 1353 | continue; |
1356 | 1354 | ||
1357 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) { | 1355 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) { |
1358 | bank->saved_datain = __raw_readl(bank->base + | 1356 | bank->saved_datain = __raw_readl(bank->base + |
1359 | OMAP24XX_GPIO_DATAIN); | 1357 | OMAP24XX_GPIO_DATAIN); |
1360 | l1 = __raw_readl(bank->base + | 1358 | l1 = __raw_readl(bank->base + |
1361 | OMAP24XX_GPIO_FALLINGDETECT); | 1359 | OMAP24XX_GPIO_FALLINGDETECT); |
1362 | l2 = __raw_readl(bank->base + | 1360 | l2 = __raw_readl(bank->base + |
1363 | OMAP24XX_GPIO_RISINGDETECT); | 1361 | OMAP24XX_GPIO_RISINGDETECT); |
1364 | } | 1362 | } |
1365 | 1363 | ||
1366 | if (cpu_is_omap44xx()) { | 1364 | if (cpu_is_omap44xx()) { |
1367 | bank->saved_datain = __raw_readl(bank->base + | 1365 | bank->saved_datain = __raw_readl(bank->base + |
1368 | OMAP4_GPIO_DATAIN); | 1366 | OMAP4_GPIO_DATAIN); |
1369 | l1 = __raw_readl(bank->base + | 1367 | l1 = __raw_readl(bank->base + |
1370 | OMAP4_GPIO_FALLINGDETECT); | 1368 | OMAP4_GPIO_FALLINGDETECT); |
1371 | l2 = __raw_readl(bank->base + | 1369 | l2 = __raw_readl(bank->base + |
1372 | OMAP4_GPIO_RISINGDETECT); | 1370 | OMAP4_GPIO_RISINGDETECT); |
1373 | } | 1371 | } |
1374 | 1372 | ||
1375 | bank->saved_fallingdetect = l1; | 1373 | bank->saved_fallingdetect = l1; |
1376 | bank->saved_risingdetect = l2; | 1374 | bank->saved_risingdetect = l2; |
1377 | l1 &= ~bank->enabled_non_wakeup_gpios; | 1375 | l1 &= ~bank->enabled_non_wakeup_gpios; |
1378 | l2 &= ~bank->enabled_non_wakeup_gpios; | 1376 | l2 &= ~bank->enabled_non_wakeup_gpios; |
1379 | 1377 | ||
1380 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) { | 1378 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) { |
1381 | __raw_writel(l1, bank->base + | 1379 | __raw_writel(l1, bank->base + |
1382 | OMAP24XX_GPIO_FALLINGDETECT); | 1380 | OMAP24XX_GPIO_FALLINGDETECT); |
1383 | __raw_writel(l2, bank->base + | 1381 | __raw_writel(l2, bank->base + |
1384 | OMAP24XX_GPIO_RISINGDETECT); | 1382 | OMAP24XX_GPIO_RISINGDETECT); |
1385 | } | 1383 | } |
1386 | 1384 | ||
1387 | if (cpu_is_omap44xx()) { | 1385 | if (cpu_is_omap44xx()) { |
1388 | __raw_writel(l1, bank->base + OMAP4_GPIO_FALLINGDETECT); | 1386 | __raw_writel(l1, bank->base + OMAP4_GPIO_FALLINGDETECT); |
1389 | __raw_writel(l2, bank->base + OMAP4_GPIO_RISINGDETECT); | 1387 | __raw_writel(l2, bank->base + OMAP4_GPIO_RISINGDETECT); |
1390 | } | 1388 | } |
1391 | 1389 | ||
1392 | c++; | 1390 | c++; |
1393 | } | 1391 | } |
1394 | if (!c) { | 1392 | if (!c) { |
1395 | workaround_enabled = 0; | 1393 | workaround_enabled = 0; |
1396 | return; | 1394 | return; |
1397 | } | 1395 | } |
1398 | workaround_enabled = 1; | 1396 | workaround_enabled = 1; |
1399 | } | 1397 | } |
1400 | 1398 | ||
1401 | void omap2_gpio_resume_after_idle(void) | 1399 | void omap2_gpio_resume_after_idle(void) |
1402 | { | 1400 | { |
1403 | int i; | 1401 | int i; |
1404 | int min = 0; | 1402 | int min = 0; |
1405 | 1403 | ||
1406 | if (cpu_is_omap34xx()) | 1404 | if (cpu_is_omap34xx()) |
1407 | min = 1; | 1405 | min = 1; |
1408 | for (i = min; i < gpio_bank_count; i++) { | 1406 | for (i = min; i < gpio_bank_count; i++) { |
1409 | struct gpio_bank *bank = &gpio_bank[i]; | 1407 | struct gpio_bank *bank = &gpio_bank[i]; |
1410 | u32 l = 0, gen, gen0, gen1; | 1408 | u32 l = 0, gen, gen0, gen1; |
1411 | int j; | 1409 | int j; |
1412 | 1410 | ||
1413 | for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++) | 1411 | for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++) |
1414 | clk_enable(bank->dbck); | 1412 | clk_enable(bank->dbck); |
1415 | 1413 | ||
1416 | if (!workaround_enabled) | 1414 | if (!workaround_enabled) |
1417 | continue; | 1415 | continue; |
1418 | 1416 | ||
1419 | if (!(bank->enabled_non_wakeup_gpios)) | 1417 | if (!(bank->enabled_non_wakeup_gpios)) |
1420 | continue; | 1418 | continue; |
1421 | 1419 | ||
1422 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) { | 1420 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) { |
1423 | __raw_writel(bank->saved_fallingdetect, | 1421 | __raw_writel(bank->saved_fallingdetect, |
1424 | bank->base + OMAP24XX_GPIO_FALLINGDETECT); | 1422 | bank->base + OMAP24XX_GPIO_FALLINGDETECT); |
1425 | __raw_writel(bank->saved_risingdetect, | 1423 | __raw_writel(bank->saved_risingdetect, |
1426 | bank->base + OMAP24XX_GPIO_RISINGDETECT); | 1424 | bank->base + OMAP24XX_GPIO_RISINGDETECT); |
1427 | l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN); | 1425 | l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN); |
1428 | } | 1426 | } |
1429 | 1427 | ||
1430 | if (cpu_is_omap44xx()) { | 1428 | if (cpu_is_omap44xx()) { |
1431 | __raw_writel(bank->saved_fallingdetect, | 1429 | __raw_writel(bank->saved_fallingdetect, |
1432 | bank->base + OMAP4_GPIO_FALLINGDETECT); | 1430 | bank->base + OMAP4_GPIO_FALLINGDETECT); |
1433 | __raw_writel(bank->saved_risingdetect, | 1431 | __raw_writel(bank->saved_risingdetect, |
1434 | bank->base + OMAP4_GPIO_RISINGDETECT); | 1432 | bank->base + OMAP4_GPIO_RISINGDETECT); |
1435 | l = __raw_readl(bank->base + OMAP4_GPIO_DATAIN); | 1433 | l = __raw_readl(bank->base + OMAP4_GPIO_DATAIN); |
1436 | } | 1434 | } |
1437 | 1435 | ||
1438 | /* Check if any of the non-wakeup interrupt GPIOs have changed | 1436 | /* Check if any of the non-wakeup interrupt GPIOs have changed |
1439 | * state. If so, generate an IRQ by software. This is | 1437 | * state. If so, generate an IRQ by software. This is |
1440 | * horribly racy, but it's the best we can do to work around | 1438 | * horribly racy, but it's the best we can do to work around |
1441 | * this silicon bug. */ | 1439 | * this silicon bug. */ |
1442 | l ^= bank->saved_datain; | 1440 | l ^= bank->saved_datain; |
1443 | l &= bank->enabled_non_wakeup_gpios; | 1441 | l &= bank->enabled_non_wakeup_gpios; |
1444 | 1442 | ||
1445 | /* | 1443 | /* |
1446 | * No need to generate IRQs for the rising edge for gpio IRQs | 1444 | * No need to generate IRQs for the rising edge for gpio IRQs |
1447 | * configured with falling edge only; and vice versa. | 1445 | * configured with falling edge only; and vice versa. |
1448 | */ | 1446 | */ |
1449 | gen0 = l & bank->saved_fallingdetect; | 1447 | gen0 = l & bank->saved_fallingdetect; |
1450 | gen0 &= bank->saved_datain; | 1448 | gen0 &= bank->saved_datain; |
1451 | 1449 | ||
1452 | gen1 = l & bank->saved_risingdetect; | 1450 | gen1 = l & bank->saved_risingdetect; |
1453 | gen1 &= ~(bank->saved_datain); | 1451 | gen1 &= ~(bank->saved_datain); |
1454 | 1452 | ||
1455 | /* FIXME: Consider GPIO IRQs with level detections properly! */ | 1453 | /* FIXME: Consider GPIO IRQs with level detections properly! */ |
1456 | gen = l & (~(bank->saved_fallingdetect) & | 1454 | gen = l & (~(bank->saved_fallingdetect) & |
1457 | ~(bank->saved_risingdetect)); | 1455 | ~(bank->saved_risingdetect)); |
1458 | /* Consider all GPIO IRQs needed to be updated */ | 1456 | /* Consider all GPIO IRQs needed to be updated */ |
1459 | gen |= gen0 | gen1; | 1457 | gen |= gen0 | gen1; |
1460 | 1458 | ||
1461 | if (gen) { | 1459 | if (gen) { |
1462 | u32 old0, old1; | 1460 | u32 old0, old1; |
1463 | 1461 | ||
1464 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) { | 1462 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) { |
1465 | old0 = __raw_readl(bank->base + | 1463 | old0 = __raw_readl(bank->base + |
1466 | OMAP24XX_GPIO_LEVELDETECT0); | 1464 | OMAP24XX_GPIO_LEVELDETECT0); |
1467 | old1 = __raw_readl(bank->base + | 1465 | old1 = __raw_readl(bank->base + |
1468 | OMAP24XX_GPIO_LEVELDETECT1); | 1466 | OMAP24XX_GPIO_LEVELDETECT1); |
1469 | __raw_writel(old0 | gen, bank->base + | 1467 | __raw_writel(old0 | gen, bank->base + |
1470 | OMAP24XX_GPIO_LEVELDETECT0); | 1468 | OMAP24XX_GPIO_LEVELDETECT0); |
1471 | __raw_writel(old1 | gen, bank->base + | 1469 | __raw_writel(old1 | gen, bank->base + |
1472 | OMAP24XX_GPIO_LEVELDETECT1); | 1470 | OMAP24XX_GPIO_LEVELDETECT1); |
1473 | __raw_writel(old0, bank->base + | 1471 | __raw_writel(old0, bank->base + |
1474 | OMAP24XX_GPIO_LEVELDETECT0); | 1472 | OMAP24XX_GPIO_LEVELDETECT0); |
1475 | __raw_writel(old1, bank->base + | 1473 | __raw_writel(old1, bank->base + |
1476 | OMAP24XX_GPIO_LEVELDETECT1); | 1474 | OMAP24XX_GPIO_LEVELDETECT1); |
1477 | } | 1475 | } |
1478 | 1476 | ||
1479 | if (cpu_is_omap44xx()) { | 1477 | if (cpu_is_omap44xx()) { |
1480 | old0 = __raw_readl(bank->base + | 1478 | old0 = __raw_readl(bank->base + |
1481 | OMAP4_GPIO_LEVELDETECT0); | 1479 | OMAP4_GPIO_LEVELDETECT0); |
1482 | old1 = __raw_readl(bank->base + | 1480 | old1 = __raw_readl(bank->base + |
1483 | OMAP4_GPIO_LEVELDETECT1); | 1481 | OMAP4_GPIO_LEVELDETECT1); |
1484 | __raw_writel(old0 | l, bank->base + | 1482 | __raw_writel(old0 | l, bank->base + |
1485 | OMAP4_GPIO_LEVELDETECT0); | 1483 | OMAP4_GPIO_LEVELDETECT0); |
1486 | __raw_writel(old1 | l, bank->base + | 1484 | __raw_writel(old1 | l, bank->base + |
1487 | OMAP4_GPIO_LEVELDETECT1); | 1485 | OMAP4_GPIO_LEVELDETECT1); |
1488 | __raw_writel(old0, bank->base + | 1486 | __raw_writel(old0, bank->base + |
1489 | OMAP4_GPIO_LEVELDETECT0); | 1487 | OMAP4_GPIO_LEVELDETECT0); |
1490 | __raw_writel(old1, bank->base + | 1488 | __raw_writel(old1, bank->base + |
1491 | OMAP4_GPIO_LEVELDETECT1); | 1489 | OMAP4_GPIO_LEVELDETECT1); |
1492 | } | 1490 | } |
1493 | } | 1491 | } |
1494 | } | 1492 | } |
1495 | 1493 | ||
1496 | } | 1494 | } |
1497 | 1495 | ||
1498 | #endif | 1496 | #endif |
1499 | 1497 | ||
1500 | #ifdef CONFIG_ARCH_OMAP3 | 1498 | #ifdef CONFIG_ARCH_OMAP3 |
1501 | /* save the registers of bank 2-6 */ | 1499 | /* save the registers of bank 2-6 */ |
1502 | void omap_gpio_save_context(void) | 1500 | void omap_gpio_save_context(void) |
1503 | { | 1501 | { |
1504 | int i; | 1502 | int i; |
1505 | 1503 | ||
1506 | /* saving banks from 2-6 only since GPIO1 is in WKUP */ | 1504 | /* saving banks from 2-6 only since GPIO1 is in WKUP */ |
1507 | for (i = 1; i < gpio_bank_count; i++) { | 1505 | for (i = 1; i < gpio_bank_count; i++) { |
1508 | struct gpio_bank *bank = &gpio_bank[i]; | 1506 | struct gpio_bank *bank = &gpio_bank[i]; |
1509 | gpio_context[i].irqenable1 = | 1507 | gpio_context[i].irqenable1 = |
1510 | __raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1); | 1508 | __raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1); |
1511 | gpio_context[i].irqenable2 = | 1509 | gpio_context[i].irqenable2 = |
1512 | __raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE2); | 1510 | __raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE2); |
1513 | gpio_context[i].wake_en = | 1511 | gpio_context[i].wake_en = |
1514 | __raw_readl(bank->base + OMAP24XX_GPIO_WAKE_EN); | 1512 | __raw_readl(bank->base + OMAP24XX_GPIO_WAKE_EN); |
1515 | gpio_context[i].ctrl = | 1513 | gpio_context[i].ctrl = |
1516 | __raw_readl(bank->base + OMAP24XX_GPIO_CTRL); | 1514 | __raw_readl(bank->base + OMAP24XX_GPIO_CTRL); |
1517 | gpio_context[i].oe = | 1515 | gpio_context[i].oe = |
1518 | __raw_readl(bank->base + OMAP24XX_GPIO_OE); | 1516 | __raw_readl(bank->base + OMAP24XX_GPIO_OE); |
1519 | gpio_context[i].leveldetect0 = | 1517 | gpio_context[i].leveldetect0 = |
1520 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0); | 1518 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0); |
1521 | gpio_context[i].leveldetect1 = | 1519 | gpio_context[i].leveldetect1 = |
1522 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); | 1520 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); |
1523 | gpio_context[i].risingdetect = | 1521 | gpio_context[i].risingdetect = |
1524 | __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT); | 1522 | __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT); |
1525 | gpio_context[i].fallingdetect = | 1523 | gpio_context[i].fallingdetect = |
1526 | __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT); | 1524 | __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT); |
1527 | gpio_context[i].dataout = | 1525 | gpio_context[i].dataout = |
1528 | __raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT); | 1526 | __raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT); |
1529 | } | 1527 | } |
1530 | } | 1528 | } |
1531 | 1529 | ||
1532 | /* restore the required registers of bank 2-6 */ | 1530 | /* restore the required registers of bank 2-6 */ |
1533 | void omap_gpio_restore_context(void) | 1531 | void omap_gpio_restore_context(void) |
1534 | { | 1532 | { |
1535 | int i; | 1533 | int i; |
1536 | 1534 | ||
1537 | for (i = 1; i < gpio_bank_count; i++) { | 1535 | for (i = 1; i < gpio_bank_count; i++) { |
1538 | struct gpio_bank *bank = &gpio_bank[i]; | 1536 | struct gpio_bank *bank = &gpio_bank[i]; |
1539 | __raw_writel(gpio_context[i].irqenable1, | 1537 | __raw_writel(gpio_context[i].irqenable1, |
1540 | bank->base + OMAP24XX_GPIO_IRQENABLE1); | 1538 | bank->base + OMAP24XX_GPIO_IRQENABLE1); |
1541 | __raw_writel(gpio_context[i].irqenable2, | 1539 | __raw_writel(gpio_context[i].irqenable2, |
1542 | bank->base + OMAP24XX_GPIO_IRQENABLE2); | 1540 | bank->base + OMAP24XX_GPIO_IRQENABLE2); |
1543 | __raw_writel(gpio_context[i].wake_en, | 1541 | __raw_writel(gpio_context[i].wake_en, |
1544 | bank->base + OMAP24XX_GPIO_WAKE_EN); | 1542 | bank->base + OMAP24XX_GPIO_WAKE_EN); |
1545 | __raw_writel(gpio_context[i].ctrl, | 1543 | __raw_writel(gpio_context[i].ctrl, |
1546 | bank->base + OMAP24XX_GPIO_CTRL); | 1544 | bank->base + OMAP24XX_GPIO_CTRL); |
1547 | __raw_writel(gpio_context[i].oe, | 1545 | __raw_writel(gpio_context[i].oe, |
1548 | bank->base + OMAP24XX_GPIO_OE); | 1546 | bank->base + OMAP24XX_GPIO_OE); |
1549 | __raw_writel(gpio_context[i].leveldetect0, | 1547 | __raw_writel(gpio_context[i].leveldetect0, |
1550 | bank->base + OMAP24XX_GPIO_LEVELDETECT0); | 1548 | bank->base + OMAP24XX_GPIO_LEVELDETECT0); |
1551 | __raw_writel(gpio_context[i].leveldetect1, | 1549 | __raw_writel(gpio_context[i].leveldetect1, |
1552 | bank->base + OMAP24XX_GPIO_LEVELDETECT1); | 1550 | bank->base + OMAP24XX_GPIO_LEVELDETECT1); |
1553 | __raw_writel(gpio_context[i].risingdetect, | 1551 | __raw_writel(gpio_context[i].risingdetect, |
1554 | bank->base + OMAP24XX_GPIO_RISINGDETECT); | 1552 | bank->base + OMAP24XX_GPIO_RISINGDETECT); |
1555 | __raw_writel(gpio_context[i].fallingdetect, | 1553 | __raw_writel(gpio_context[i].fallingdetect, |
1556 | bank->base + OMAP24XX_GPIO_FALLINGDETECT); | 1554 | bank->base + OMAP24XX_GPIO_FALLINGDETECT); |
1557 | __raw_writel(gpio_context[i].dataout, | 1555 | __raw_writel(gpio_context[i].dataout, |
1558 | bank->base + OMAP24XX_GPIO_DATAOUT); | 1556 | bank->base + OMAP24XX_GPIO_DATAOUT); |
1559 | } | 1557 | } |
1560 | } | 1558 | } |
1561 | #endif | 1559 | #endif |
1562 | 1560 | ||
1563 | static struct platform_driver omap_gpio_driver = { | 1561 | static struct platform_driver omap_gpio_driver = { |
1564 | .probe = omap_gpio_probe, | 1562 | .probe = omap_gpio_probe, |
1565 | .driver = { | 1563 | .driver = { |
1566 | .name = "omap_gpio", | 1564 | .name = "omap_gpio", |
1567 | }, | 1565 | }, |
1568 | }; | 1566 | }; |
1569 | 1567 | ||
1570 | /* | 1568 | /* |
1571 | * gpio driver register needs to be done before | 1569 | * gpio driver register needs to be done before |
1572 | * machine_init functions access gpio APIs. | 1570 | * machine_init functions access gpio APIs. |
1573 | * Hence omap_gpio_drv_reg() is a postcore_initcall. | 1571 | * Hence omap_gpio_drv_reg() is a postcore_initcall. |
1574 | */ | 1572 | */ |
1575 | static int __init omap_gpio_drv_reg(void) | 1573 | static int __init omap_gpio_drv_reg(void) |
1576 | { | 1574 | { |
1577 | return platform_driver_register(&omap_gpio_driver); | 1575 | return platform_driver_register(&omap_gpio_driver); |
1578 | } | 1576 | } |
1579 | postcore_initcall(omap_gpio_drv_reg); | 1577 | postcore_initcall(omap_gpio_drv_reg); |
1580 | 1578 | ||
1581 | static int __init omap_gpio_sysinit(void) | 1579 | static int __init omap_gpio_sysinit(void) |
1582 | { | 1580 | { |
1583 | mpuio_init(); | 1581 | mpuio_init(); |
1584 | 1582 | ||
1585 | #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) | 1583 | #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) |
1586 | if (cpu_is_omap16xx() || cpu_class_is_omap2()) | 1584 | if (cpu_is_omap16xx() || cpu_class_is_omap2()) |
1587 | register_syscore_ops(&omap_gpio_syscore_ops); | 1585 | register_syscore_ops(&omap_gpio_syscore_ops); |
1588 | #endif | 1586 | #endif |
1589 | 1587 | ||
1590 | return 0; | 1588 | return 0; |