diff options
author | Shawn Guo <shawn.guo@linaro.org> | 2012-05-03 11:32:52 -0400 |
---|---|---|
committer | Shawn Guo <shawn.guo@linaro.org> | 2012-05-12 01:32:18 -0400 |
commit | 164387d2b4ae206f6275f5f6857aee74654918c4 (patch) | |
tree | 5929dc7a0caa3883183a8031b4d54f6fbabba4db | |
parent | 940a4f7b51f7ad600821e389e80d216baf9e1df8 (diff) |
gpio/mxs: get rid of the use of cpu_is_xxx
It removes the use of cpu_is_xxx from gpio-mxs driver and instead use
platform_device_id to identify the device. Accordingly, mxs platform
code is changed to register gpio device with different names, and
the registeration are done in soc specific initialization functions
now, so postcore_initcall(mxs_add_mxs_gpio) gets removed.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | arch/arm/mach-mxs/devices/platform-gpio-mxs.c | 24 | ||||
-rw-r--r-- | arch/arm/mach-mxs/include/mach/common.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-mxs/mm.c | 10 | ||||
-rw-r--r-- | drivers/gpio/gpio-mxs.c | 74 |
4 files changed, 66 insertions, 46 deletions
diff --git a/arch/arm/mach-mxs/devices/platform-gpio-mxs.c b/arch/arm/mach-mxs/devices/platform-gpio-mxs.c index ed0885e414e0..cd99f19ec637 100644 --- a/arch/arm/mach-mxs/devices/platform-gpio-mxs.c +++ b/arch/arm/mach-mxs/devices/platform-gpio-mxs.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <mach/devices-common.h> | 14 | #include <mach/devices-common.h> |
15 | 15 | ||
16 | struct platform_device *__init mxs_add_gpio( | 16 | struct platform_device *__init mxs_add_gpio( |
17 | int id, resource_size_t iobase, int irq) | 17 | char *name, int id, resource_size_t iobase, int irq) |
18 | { | 18 | { |
19 | struct resource res[] = { | 19 | struct resource res[] = { |
20 | { | 20 | { |
@@ -29,25 +29,5 @@ struct platform_device *__init mxs_add_gpio( | |||
29 | }; | 29 | }; |
30 | 30 | ||
31 | return platform_device_register_resndata(&mxs_apbh_bus, | 31 | return platform_device_register_resndata(&mxs_apbh_bus, |
32 | "gpio-mxs", id, res, ARRAY_SIZE(res), NULL, 0); | 32 | name, id, res, ARRAY_SIZE(res), NULL, 0); |
33 | } | 33 | } |
34 | |||
35 | static int __init mxs_add_mxs_gpio(void) | ||
36 | { | ||
37 | if (cpu_is_mx23()) { | ||
38 | mxs_add_gpio(0, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO0); | ||
39 | mxs_add_gpio(1, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO1); | ||
40 | mxs_add_gpio(2, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO2); | ||
41 | } | ||
42 | |||
43 | if (cpu_is_mx28()) { | ||
44 | mxs_add_gpio(0, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO0); | ||
45 | mxs_add_gpio(1, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO1); | ||
46 | mxs_add_gpio(2, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO2); | ||
47 | mxs_add_gpio(3, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO3); | ||
48 | mxs_add_gpio(4, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO4); | ||
49 | } | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | postcore_initcall(mxs_add_mxs_gpio); | ||
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h index 5f9a3583266c..de6c7ba42544 100644 --- a/arch/arm/mach-mxs/include/mach/common.h +++ b/arch/arm/mach-mxs/include/mach/common.h | |||
@@ -18,13 +18,11 @@ extern void mxs_restart(char, const char *); | |||
18 | extern int mxs_saif_clkmux_select(unsigned int clkmux); | 18 | extern int mxs_saif_clkmux_select(unsigned int clkmux); |
19 | 19 | ||
20 | extern void mx23_soc_init(void); | 20 | extern void mx23_soc_init(void); |
21 | extern int mx23_register_gpios(void); | ||
22 | extern int mx23_clocks_init(void); | 21 | extern int mx23_clocks_init(void); |
23 | extern void mx23_map_io(void); | 22 | extern void mx23_map_io(void); |
24 | extern void mx23_init_irq(void); | 23 | extern void mx23_init_irq(void); |
25 | 24 | ||
26 | extern void mx28_soc_init(void); | 25 | extern void mx28_soc_init(void); |
27 | extern int mx28_register_gpios(void); | ||
28 | extern int mx28_clocks_init(void); | 26 | extern int mx28_clocks_init(void); |
29 | extern void mx28_map_io(void); | 27 | extern void mx28_map_io(void); |
30 | extern void mx28_init_irq(void); | 28 | extern void mx28_init_irq(void); |
@@ -33,5 +31,7 @@ extern void icoll_init_irq(void); | |||
33 | 31 | ||
34 | extern struct platform_device *mxs_add_dma(const char *devid, | 32 | extern struct platform_device *mxs_add_dma(const char *devid, |
35 | resource_size_t base); | 33 | resource_size_t base); |
34 | extern struct platform_device *mxs_add_gpio(char *name, int id, | ||
35 | resource_size_t iobase, int irq); | ||
36 | 36 | ||
37 | #endif /* __MACH_MXS_COMMON_H__ */ | 37 | #endif /* __MACH_MXS_COMMON_H__ */ |
diff --git a/arch/arm/mach-mxs/mm.c b/arch/arm/mach-mxs/mm.c index 6af4371ec829..dccb67a9e7c4 100644 --- a/arch/arm/mach-mxs/mm.c +++ b/arch/arm/mach-mxs/mm.c | |||
@@ -69,6 +69,10 @@ void __init mx23_soc_init(void) | |||
69 | 69 | ||
70 | mxs_add_dma("imx23-dma-apbh", MX23_APBH_DMA_BASE_ADDR); | 70 | mxs_add_dma("imx23-dma-apbh", MX23_APBH_DMA_BASE_ADDR); |
71 | mxs_add_dma("imx23-dma-apbx", MX23_APBX_DMA_BASE_ADDR); | 71 | mxs_add_dma("imx23-dma-apbx", MX23_APBX_DMA_BASE_ADDR); |
72 | |||
73 | mxs_add_gpio("imx23-gpio", 0, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO0); | ||
74 | mxs_add_gpio("imx23-gpio", 1, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO1); | ||
75 | mxs_add_gpio("imx23-gpio", 2, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO2); | ||
72 | } | 76 | } |
73 | 77 | ||
74 | void __init mx28_soc_init(void) | 78 | void __init mx28_soc_init(void) |
@@ -77,4 +81,10 @@ void __init mx28_soc_init(void) | |||
77 | 81 | ||
78 | mxs_add_dma("imx28-dma-apbh", MX23_APBH_DMA_BASE_ADDR); | 82 | mxs_add_dma("imx28-dma-apbh", MX23_APBH_DMA_BASE_ADDR); |
79 | mxs_add_dma("imx28-dma-apbx", MX23_APBX_DMA_BASE_ADDR); | 83 | mxs_add_dma("imx28-dma-apbx", MX23_APBX_DMA_BASE_ADDR); |
84 | |||
85 | mxs_add_gpio("imx28-gpio", 0, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO0); | ||
86 | mxs_add_gpio("imx28-gpio", 1, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO1); | ||
87 | mxs_add_gpio("imx28-gpio", 2, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO2); | ||
88 | mxs_add_gpio("imx28-gpio", 3, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO3); | ||
89 | mxs_add_gpio("imx28-gpio", 4, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO4); | ||
80 | } | 90 | } |
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c index 95a11dba285c..38ae56f17916 100644 --- a/drivers/gpio/gpio-mxs.c +++ b/drivers/gpio/gpio-mxs.c | |||
@@ -29,19 +29,18 @@ | |||
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/basic_mmio_gpio.h> | 30 | #include <linux/basic_mmio_gpio.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <mach/mxs.h> | ||
33 | 32 | ||
34 | #define MXS_SET 0x4 | 33 | #define MXS_SET 0x4 |
35 | #define MXS_CLR 0x8 | 34 | #define MXS_CLR 0x8 |
36 | 35 | ||
37 | #define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10) | 36 | #define PINCTRL_DOUT(p) ((is_imx23_gpio(p) ? 0x0500 : 0x0700) + (p->id) * 0x10) |
38 | #define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10) | 37 | #define PINCTRL_DIN(p) ((is_imx23_gpio(p) ? 0x0600 : 0x0900) + (p->id) * 0x10) |
39 | #define PINCTRL_DOE(n) ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10) | 38 | #define PINCTRL_DOE(p) ((is_imx23_gpio(p) ? 0x0700 : 0x0b00) + (p->id) * 0x10) |
40 | #define PINCTRL_PIN2IRQ(n) ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10) | 39 | #define PINCTRL_PIN2IRQ(p) ((is_imx23_gpio(p) ? 0x0800 : 0x1000) + (p->id) * 0x10) |
41 | #define PINCTRL_IRQEN(n) ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10) | 40 | #define PINCTRL_IRQEN(p) ((is_imx23_gpio(p) ? 0x0900 : 0x1100) + (p->id) * 0x10) |
42 | #define PINCTRL_IRQLEV(n) ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10) | 41 | #define PINCTRL_IRQLEV(p) ((is_imx23_gpio(p) ? 0x0a00 : 0x1200) + (p->id) * 0x10) |
43 | #define PINCTRL_IRQPOL(n) ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10) | 42 | #define PINCTRL_IRQPOL(p) ((is_imx23_gpio(p) ? 0x0b00 : 0x1300) + (p->id) * 0x10) |
44 | #define PINCTRL_IRQSTAT(n) ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10) | 43 | #define PINCTRL_IRQSTAT(p) ((is_imx23_gpio(p) ? 0x0c00 : 0x1400) + (p->id) * 0x10) |
45 | 44 | ||
46 | #define GPIO_INT_FALL_EDGE 0x0 | 45 | #define GPIO_INT_FALL_EDGE 0x0 |
47 | #define GPIO_INT_LOW_LEV 0x1 | 46 | #define GPIO_INT_LOW_LEV 0x1 |
@@ -52,14 +51,30 @@ | |||
52 | 51 | ||
53 | #define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START) | 52 | #define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START) |
54 | 53 | ||
54 | enum mxs_gpio_id { | ||
55 | IMX23_GPIO, | ||
56 | IMX28_GPIO, | ||
57 | }; | ||
58 | |||
55 | struct mxs_gpio_port { | 59 | struct mxs_gpio_port { |
56 | void __iomem *base; | 60 | void __iomem *base; |
57 | int id; | 61 | int id; |
58 | int irq; | 62 | int irq; |
59 | int virtual_irq_start; | 63 | int virtual_irq_start; |
60 | struct bgpio_chip bgc; | 64 | struct bgpio_chip bgc; |
65 | enum mxs_gpio_id devid; | ||
61 | }; | 66 | }; |
62 | 67 | ||
68 | static inline int is_imx23_gpio(struct mxs_gpio_port *port) | ||
69 | { | ||
70 | return port->devid == IMX23_GPIO; | ||
71 | } | ||
72 | |||
73 | static inline int is_imx28_gpio(struct mxs_gpio_port *port) | ||
74 | { | ||
75 | return port->devid == IMX28_GPIO; | ||
76 | } | ||
77 | |||
63 | /* Note: This driver assumes 32 GPIOs are handled in one register */ | 78 | /* Note: This driver assumes 32 GPIOs are handled in one register */ |
64 | 79 | ||
65 | static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type) | 80 | static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type) |
@@ -89,21 +104,21 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type) | |||
89 | } | 104 | } |
90 | 105 | ||
91 | /* set level or edge */ | 106 | /* set level or edge */ |
92 | pin_addr = port->base + PINCTRL_IRQLEV(port->id); | 107 | pin_addr = port->base + PINCTRL_IRQLEV(port); |
93 | if (edge & GPIO_INT_LEV_MASK) | 108 | if (edge & GPIO_INT_LEV_MASK) |
94 | writel(pin_mask, pin_addr + MXS_SET); | 109 | writel(pin_mask, pin_addr + MXS_SET); |
95 | else | 110 | else |
96 | writel(pin_mask, pin_addr + MXS_CLR); | 111 | writel(pin_mask, pin_addr + MXS_CLR); |
97 | 112 | ||
98 | /* set polarity */ | 113 | /* set polarity */ |
99 | pin_addr = port->base + PINCTRL_IRQPOL(port->id); | 114 | pin_addr = port->base + PINCTRL_IRQPOL(port); |
100 | if (edge & GPIO_INT_POL_MASK) | 115 | if (edge & GPIO_INT_POL_MASK) |
101 | writel(pin_mask, pin_addr + MXS_SET); | 116 | writel(pin_mask, pin_addr + MXS_SET); |
102 | else | 117 | else |
103 | writel(pin_mask, pin_addr + MXS_CLR); | 118 | writel(pin_mask, pin_addr + MXS_CLR); |
104 | 119 | ||
105 | writel(1 << (gpio & 0x1f), | 120 | writel(1 << (gpio & 0x1f), |
106 | port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR); | 121 | port->base + PINCTRL_IRQSTAT(port) + MXS_CLR); |
107 | 122 | ||
108 | return 0; | 123 | return 0; |
109 | } | 124 | } |
@@ -117,8 +132,8 @@ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc) | |||
117 | 132 | ||
118 | desc->irq_data.chip->irq_ack(&desc->irq_data); | 133 | desc->irq_data.chip->irq_ack(&desc->irq_data); |
119 | 134 | ||
120 | irq_stat = readl(port->base + PINCTRL_IRQSTAT(port->id)) & | 135 | irq_stat = readl(port->base + PINCTRL_IRQSTAT(port)) & |
121 | readl(port->base + PINCTRL_IRQEN(port->id)); | 136 | readl(port->base + PINCTRL_IRQEN(port)); |
122 | 137 | ||
123 | while (irq_stat != 0) { | 138 | while (irq_stat != 0) { |
124 | int irqoffset = fls(irq_stat) - 1; | 139 | int irqoffset = fls(irq_stat) - 1; |
@@ -164,8 +179,8 @@ static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port) | |||
164 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | 179 | ct->chip.irq_unmask = irq_gc_mask_set_bit; |
165 | ct->chip.irq_set_type = mxs_gpio_set_irq_type; | 180 | ct->chip.irq_set_type = mxs_gpio_set_irq_type; |
166 | ct->chip.irq_set_wake = mxs_gpio_set_wake_irq; | 181 | ct->chip.irq_set_wake = mxs_gpio_set_wake_irq; |
167 | ct->regs.ack = PINCTRL_IRQSTAT(port->id) + MXS_CLR; | 182 | ct->regs.ack = PINCTRL_IRQSTAT(port) + MXS_CLR; |
168 | ct->regs.mask = PINCTRL_IRQEN(port->id); | 183 | ct->regs.mask = PINCTRL_IRQEN(port); |
169 | 184 | ||
170 | irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0); | 185 | irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0); |
171 | } | 186 | } |
@@ -179,6 +194,19 @@ static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | |||
179 | return port->virtual_irq_start + offset; | 194 | return port->virtual_irq_start + offset; |
180 | } | 195 | } |
181 | 196 | ||
197 | static struct platform_device_id mxs_gpio_ids[] = { | ||
198 | { | ||
199 | .name = "imx23-gpio", | ||
200 | .driver_data = IMX23_GPIO, | ||
201 | }, { | ||
202 | .name = "imx28-gpio", | ||
203 | .driver_data = IMX28_GPIO, | ||
204 | }, { | ||
205 | /* sentinel */ | ||
206 | } | ||
207 | }; | ||
208 | MODULE_DEVICE_TABLE(platform, mxs_gpio_ids); | ||
209 | |||
182 | static int __devinit mxs_gpio_probe(struct platform_device *pdev) | 210 | static int __devinit mxs_gpio_probe(struct platform_device *pdev) |
183 | { | 211 | { |
184 | static void __iomem *base; | 212 | static void __iomem *base; |
@@ -191,6 +219,7 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev) | |||
191 | return -ENOMEM; | 219 | return -ENOMEM; |
192 | 220 | ||
193 | port->id = pdev->id; | 221 | port->id = pdev->id; |
222 | port->devid = pdev->id_entry->driver_data; | ||
194 | port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32; | 223 | port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32; |
195 | 224 | ||
196 | port->irq = platform_get_irq(pdev, 0); | 225 | port->irq = platform_get_irq(pdev, 0); |
@@ -213,11 +242,11 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev) | |||
213 | * select the pin interrupt functionality but initially | 242 | * select the pin interrupt functionality but initially |
214 | * disable the interrupts | 243 | * disable the interrupts |
215 | */ | 244 | */ |
216 | writel(~0U, port->base + PINCTRL_PIN2IRQ(port->id)); | 245 | writel(~0U, port->base + PINCTRL_PIN2IRQ(port)); |
217 | writel(0, port->base + PINCTRL_IRQEN(port->id)); | 246 | writel(0, port->base + PINCTRL_IRQEN(port)); |
218 | 247 | ||
219 | /* clear address has to be used to clear IRQSTAT bits */ | 248 | /* clear address has to be used to clear IRQSTAT bits */ |
220 | writel(~0U, port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR); | 249 | writel(~0U, port->base + PINCTRL_IRQSTAT(port) + MXS_CLR); |
221 | 250 | ||
222 | /* gpio-mxs can be a generic irq chip */ | 251 | /* gpio-mxs can be a generic irq chip */ |
223 | mxs_gpio_init_gc(port); | 252 | mxs_gpio_init_gc(port); |
@@ -227,9 +256,9 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev) | |||
227 | irq_set_handler_data(port->irq, port); | 256 | irq_set_handler_data(port->irq, port); |
228 | 257 | ||
229 | err = bgpio_init(&port->bgc, &pdev->dev, 4, | 258 | err = bgpio_init(&port->bgc, &pdev->dev, 4, |
230 | port->base + PINCTRL_DIN(port->id), | 259 | port->base + PINCTRL_DIN(port), |
231 | port->base + PINCTRL_DOUT(port->id), NULL, | 260 | port->base + PINCTRL_DOUT(port), NULL, |
232 | port->base + PINCTRL_DOE(port->id), NULL, false); | 261 | port->base + PINCTRL_DOE(port), NULL, false); |
233 | if (err) | 262 | if (err) |
234 | return err; | 263 | return err; |
235 | 264 | ||
@@ -251,6 +280,7 @@ static struct platform_driver mxs_gpio_driver = { | |||
251 | .owner = THIS_MODULE, | 280 | .owner = THIS_MODULE, |
252 | }, | 281 | }, |
253 | .probe = mxs_gpio_probe, | 282 | .probe = mxs_gpio_probe, |
283 | .id_table = mxs_gpio_ids, | ||
254 | }; | 284 | }; |
255 | 285 | ||
256 | static int __init mxs_gpio_init(void) | 286 | static int __init mxs_gpio_init(void) |