diff options
author | KV Sujith <sujithkv@ti.com> | 2013-08-18 01:18:58 -0400 |
---|---|---|
committer | Sekhar Nori <nsekhar@ti.com> | 2013-09-24 01:01:51 -0400 |
commit | 118150f22d6b4431a1fe2e715de314a5d93836f5 (patch) | |
tree | 080754912ca05cd7dc93fd177e435582b5671f1b /drivers/gpio/gpio-davinci.c | |
parent | 131a10a39545cce2f569a760e4470ebd988132b0 (diff) |
gpio: davinci: move to platform device
Modify DaVinci GPIO driver to become a platform device
driver.
The driver does not have platform driver structure or
a probe. Instead, it has pure_initcall function for
initialization. The platform specific informaiton is
obtained using the DaVinci specific davinci_soc_info
structure. This is a problem for Device Tree (DT)
implementation.
As a first stage of DT conversion, we implement a probe.
Additional notes:
- The driver registration happens as postcore_initcall.
This is required since machine init functions like
da850_lcd_hw_init() make use of GPIO.
- Start using devres APIs for simpler error handling.
Signed-off-by: KV Sujith <sujithkv@ti.com>
[avinashphilip@ti.com: Move global definition of
"davinci_gpio_controller" to local]
Signed-off-by: Philip Avinash <avinashphilip@ti.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
[nsekhar@ti.com: drop unused structure member, rebase to new
clean-up patch and fix error messages]
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
Diffstat (limited to 'drivers/gpio/gpio-davinci.c')
-rw-r--r-- | drivers/gpio/gpio-davinci.c | 119 |
1 files changed, 81 insertions, 38 deletions
diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index cb947a1266ae..8847adf392b7 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c | |||
@@ -15,8 +15,9 @@ | |||
15 | #include <linux/clk.h> | 15 | #include <linux/clk.h> |
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | 18 | #include <linux/irq.h> | |
19 | #include <asm/mach/irq.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/platform_data/gpio-davinci.h> | ||
20 | 21 | ||
21 | struct davinci_gpio_regs { | 22 | struct davinci_gpio_regs { |
22 | u32 dir; | 23 | u32 dir; |
@@ -36,10 +37,9 @@ struct davinci_gpio_regs { | |||
36 | #define chip2controller(chip) \ | 37 | #define chip2controller(chip) \ |
37 | container_of(chip, struct davinci_gpio_controller, chip) | 38 | container_of(chip, struct davinci_gpio_controller, chip) |
38 | 39 | ||
39 | static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; | ||
40 | static void __iomem *gpio_base; | 40 | static void __iomem *gpio_base; |
41 | 41 | ||
42 | static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio) | 42 | static struct davinci_gpio_regs __iomem *gpio2regs(unsigned gpio) |
43 | { | 43 | { |
44 | void __iomem *ptr; | 44 | void __iomem *ptr; |
45 | 45 | ||
@@ -67,7 +67,7 @@ static inline struct davinci_gpio_regs __iomem *irq2regs(int irq) | |||
67 | return g; | 67 | return g; |
68 | } | 68 | } |
69 | 69 | ||
70 | static int __init davinci_gpio_irq_setup(void); | 70 | static int davinci_gpio_irq_setup(struct platform_device *pdev); |
71 | 71 | ||
72 | /*--------------------------------------------------------------------------*/ | 72 | /*--------------------------------------------------------------------------*/ |
73 | 73 | ||
@@ -133,33 +133,53 @@ davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
133 | __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data); | 133 | __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data); |
134 | } | 134 | } |
135 | 135 | ||
136 | static int __init davinci_gpio_setup(void) | 136 | static int davinci_gpio_probe(struct platform_device *pdev) |
137 | { | 137 | { |
138 | int i, base; | 138 | int i, base; |
139 | unsigned ngpio; | 139 | unsigned ngpio; |
140 | struct davinci_soc_info *soc_info = &davinci_soc_info; | 140 | struct davinci_gpio_controller *chips; |
141 | struct davinci_gpio_regs *regs; | 141 | struct davinci_gpio_platform_data *pdata; |
142 | 142 | struct davinci_gpio_regs __iomem *regs; | |
143 | if (soc_info->gpio_type != GPIO_TYPE_DAVINCI) | 143 | struct device *dev = &pdev->dev; |
144 | return 0; | 144 | struct resource *res; |
145 | |||
146 | pdata = dev->platform_data; | ||
147 | if (!pdata) { | ||
148 | dev_err(dev, "No platform data found\n"); | ||
149 | return -EINVAL; | ||
150 | } | ||
145 | 151 | ||
146 | /* | 152 | /* |
147 | * The gpio banks conceptually expose a segmented bitmap, | 153 | * The gpio banks conceptually expose a segmented bitmap, |
148 | * and "ngpio" is one more than the largest zero-based | 154 | * and "ngpio" is one more than the largest zero-based |
149 | * bit index that's valid. | 155 | * bit index that's valid. |
150 | */ | 156 | */ |
151 | ngpio = soc_info->gpio_num; | 157 | ngpio = pdata->ngpio; |
152 | if (ngpio == 0) { | 158 | if (ngpio == 0) { |
153 | pr_err("GPIO setup: how many GPIOs?\n"); | 159 | dev_err(dev, "How many GPIOs?\n"); |
154 | return -EINVAL; | 160 | return -EINVAL; |
155 | } | 161 | } |
156 | 162 | ||
157 | if (WARN_ON(DAVINCI_N_GPIO < ngpio)) | 163 | if (WARN_ON(DAVINCI_N_GPIO < ngpio)) |
158 | ngpio = DAVINCI_N_GPIO; | 164 | ngpio = DAVINCI_N_GPIO; |
159 | 165 | ||
160 | gpio_base = ioremap(soc_info->gpio_base, SZ_4K); | 166 | chips = devm_kzalloc(dev, |
161 | if (WARN_ON(!gpio_base)) | 167 | ngpio * sizeof(struct davinci_gpio_controller), |
168 | GFP_KERNEL); | ||
169 | if (!chips) { | ||
170 | dev_err(dev, "Memory allocation failed\n"); | ||
162 | return -ENOMEM; | 171 | return -ENOMEM; |
172 | } | ||
173 | |||
174 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
175 | if (!res) { | ||
176 | dev_err(dev, "Invalid memory resource\n"); | ||
177 | return -EBUSY; | ||
178 | } | ||
179 | |||
180 | gpio_base = devm_ioremap_resource(dev, res); | ||
181 | if (IS_ERR(gpio_base)) | ||
182 | return PTR_ERR(gpio_base); | ||
163 | 183 | ||
164 | for (i = 0, base = 0; base < ngpio; i++, base += 32) { | 184 | for (i = 0, base = 0; base < ngpio; i++, base += 32) { |
165 | chips[i].chip.label = "DaVinci"; | 185 | chips[i].chip.label = "DaVinci"; |
@@ -185,13 +205,10 @@ static int __init davinci_gpio_setup(void) | |||
185 | gpiochip_add(&chips[i].chip); | 205 | gpiochip_add(&chips[i].chip); |
186 | } | 206 | } |
187 | 207 | ||
188 | soc_info->gpio_ctlrs = chips; | 208 | platform_set_drvdata(pdev, chips); |
189 | soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32); | 209 | davinci_gpio_irq_setup(pdev); |
190 | |||
191 | davinci_gpio_irq_setup(); | ||
192 | return 0; | 210 | return 0; |
193 | } | 211 | } |
194 | pure_initcall(davinci_gpio_setup); | ||
195 | 212 | ||
196 | /*--------------------------------------------------------------------------*/ | 213 | /*--------------------------------------------------------------------------*/ |
197 | /* | 214 | /* |
@@ -304,14 +321,14 @@ static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset) | |||
304 | 321 | ||
305 | static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset) | 322 | static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset) |
306 | { | 323 | { |
307 | struct davinci_soc_info *soc_info = &davinci_soc_info; | 324 | struct davinci_gpio_controller *d = chip2controller(chip); |
308 | 325 | ||
309 | /* | 326 | /* |
310 | * NOTE: we assume for now that only irqs in the first gpio_chip | 327 | * NOTE: we assume for now that only irqs in the first gpio_chip |
311 | * can provide direct-mapped IRQs to AINTC (up to 32 GPIOs). | 328 | * can provide direct-mapped IRQs to AINTC (up to 32 GPIOs). |
312 | */ | 329 | */ |
313 | if (offset < soc_info->gpio_unbanked) | 330 | if (offset < d->irq_base) |
314 | return soc_info->gpio_irq + offset; | 331 | return d->gpio_irq + offset; |
315 | else | 332 | else |
316 | return -ENODEV; | 333 | return -ENODEV; |
317 | } | 334 | } |
@@ -320,12 +337,11 @@ static int gpio_irq_type_unbanked(struct irq_data *data, unsigned trigger) | |||
320 | { | 337 | { |
321 | struct davinci_gpio_controller *d; | 338 | struct davinci_gpio_controller *d; |
322 | struct davinci_gpio_regs __iomem *g; | 339 | struct davinci_gpio_regs __iomem *g; |
323 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
324 | u32 mask; | 340 | u32 mask; |
325 | 341 | ||
326 | d = (struct davinci_gpio_controller *)data->handler_data; | 342 | d = (struct davinci_gpio_controller *)data->handler_data; |
327 | g = (struct davinci_gpio_regs __iomem *)d->regs; | 343 | g = (struct davinci_gpio_regs __iomem *)d->regs; |
328 | mask = __gpio_mask(data->irq - soc_info->gpio_irq); | 344 | mask = __gpio_mask(data->irq - d->gpio_irq); |
329 | 345 | ||
330 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | 346 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) |
331 | return -EINVAL; | 347 | return -EINVAL; |
@@ -346,24 +362,33 @@ static int gpio_irq_type_unbanked(struct irq_data *data, unsigned trigger) | |||
346 | * (dm6446) can be set appropriately for GPIOV33 pins. | 362 | * (dm6446) can be set appropriately for GPIOV33 pins. |
347 | */ | 363 | */ |
348 | 364 | ||
349 | static int __init davinci_gpio_irq_setup(void) | 365 | static int davinci_gpio_irq_setup(struct platform_device *pdev) |
350 | { | 366 | { |
351 | unsigned gpio, irq, bank; | 367 | unsigned gpio, irq, bank; |
352 | struct clk *clk; | 368 | struct clk *clk; |
353 | u32 binten = 0; | 369 | u32 binten = 0; |
354 | unsigned ngpio, bank_irq; | 370 | unsigned ngpio, bank_irq; |
355 | struct davinci_soc_info *soc_info = &davinci_soc_info; | 371 | struct device *dev = &pdev->dev; |
356 | struct davinci_gpio_regs __iomem *g; | 372 | struct resource *res; |
373 | struct davinci_gpio_controller *chips = platform_get_drvdata(pdev); | ||
374 | struct davinci_gpio_platform_data *pdata = dev->platform_data; | ||
375 | struct davinci_gpio_regs __iomem *g; | ||
357 | 376 | ||
358 | ngpio = soc_info->gpio_num; | 377 | ngpio = pdata->ngpio; |
378 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
379 | if (!res) { | ||
380 | dev_err(dev, "Invalid IRQ resource\n"); | ||
381 | return -EBUSY; | ||
382 | } | ||
359 | 383 | ||
360 | bank_irq = soc_info->gpio_irq; | 384 | bank_irq = res->start; |
361 | if (bank_irq == 0) { | 385 | |
362 | printk(KERN_ERR "Don't know first GPIO bank IRQ.\n"); | 386 | if (!bank_irq) { |
363 | return -EINVAL; | 387 | dev_err(dev, "Invalid IRQ resource\n"); |
388 | return -ENODEV; | ||
364 | } | 389 | } |
365 | 390 | ||
366 | clk = clk_get(NULL, "gpio"); | 391 | clk = devm_clk_get(dev, "gpio"); |
367 | if (IS_ERR(clk)) { | 392 | if (IS_ERR(clk)) { |
368 | printk(KERN_ERR "Error %ld getting gpio clock?\n", | 393 | printk(KERN_ERR "Error %ld getting gpio clock?\n", |
369 | PTR_ERR(clk)); | 394 | PTR_ERR(clk)); |
@@ -379,9 +404,9 @@ static int __init davinci_gpio_irq_setup(void) | |||
379 | */ | 404 | */ |
380 | for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) { | 405 | for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) { |
381 | chips[bank].chip.to_irq = gpio_to_irq_banked; | 406 | chips[bank].chip.to_irq = gpio_to_irq_banked; |
382 | chips[bank].irq_base = soc_info->gpio_unbanked | 407 | chips[bank].irq_base = pdata->gpio_unbanked |
383 | ? -EINVAL | 408 | ? -EINVAL |
384 | : (soc_info->intc_irq_num + gpio); | 409 | : (pdata->intc_irq_num + gpio); |
385 | } | 410 | } |
386 | 411 | ||
387 | /* | 412 | /* |
@@ -389,7 +414,7 @@ static int __init davinci_gpio_irq_setup(void) | |||
389 | * controller only handling trigger modes. We currently assume no | 414 | * controller only handling trigger modes. We currently assume no |
390 | * IRQ mux conflicts; gpio_irq_type_unbanked() is only for GPIOs. | 415 | * IRQ mux conflicts; gpio_irq_type_unbanked() is only for GPIOs. |
391 | */ | 416 | */ |
392 | if (soc_info->gpio_unbanked) { | 417 | if (pdata->gpio_unbanked) { |
393 | static struct irq_chip_type gpio_unbanked; | 418 | static struct irq_chip_type gpio_unbanked; |
394 | 419 | ||
395 | /* pass "bank 0" GPIO IRQs to AINTC */ | 420 | /* pass "bank 0" GPIO IRQs to AINTC */ |
@@ -409,7 +434,7 @@ static int __init davinci_gpio_irq_setup(void) | |||
409 | __raw_writel(~0, &g->set_rising); | 434 | __raw_writel(~0, &g->set_rising); |
410 | 435 | ||
411 | /* set the direct IRQs up to use that irqchip */ | 436 | /* set the direct IRQs up to use that irqchip */ |
412 | for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) { | 437 | for (gpio = 0; gpio < pdata->gpio_unbanked; gpio++, irq++) { |
413 | irq_set_chip(irq, &gpio_unbanked.chip); | 438 | irq_set_chip(irq, &gpio_unbanked.chip); |
414 | irq_set_handler_data(irq, &chips[gpio / 32]); | 439 | irq_set_handler_data(irq, &chips[gpio / 32]); |
415 | irq_set_status_flags(irq, IRQ_TYPE_EDGE_BOTH); | 440 | irq_set_status_flags(irq, IRQ_TYPE_EDGE_BOTH); |
@@ -464,3 +489,21 @@ done: | |||
464 | 489 | ||
465 | return 0; | 490 | return 0; |
466 | } | 491 | } |
492 | |||
493 | static struct platform_driver davinci_gpio_driver = { | ||
494 | .probe = davinci_gpio_probe, | ||
495 | .driver = { | ||
496 | .name = "davinci_gpio", | ||
497 | .owner = THIS_MODULE, | ||
498 | }, | ||
499 | }; | ||
500 | |||
501 | /** | ||
502 | * GPIO driver registration needs to be done before machine_init functions | ||
503 | * access GPIO. Hence davinci_gpio_drv_reg() is a postcore_initcall. | ||
504 | */ | ||
505 | static int __init davinci_gpio_drv_reg(void) | ||
506 | { | ||
507 | return platform_driver_register(&davinci_gpio_driver); | ||
508 | } | ||
509 | postcore_initcall(davinci_gpio_drv_reg); | ||