diff options
author | Olof Johansson <olof@lixom.net> | 2012-09-21 00:16:43 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2012-09-21 00:16:43 -0400 |
commit | ea832c41dacbc4a5f3888d9ef7c38213914aba2a (patch) | |
tree | bee97817d9a55f000e2bec5fa5d62d325050e6a6 /drivers/gpio | |
parent | b74aae9a2074e1caa2e40bf119f3a633f77c94e4 (diff) | |
parent | 84bae6c379e362aa017efd417199f51d5c2273ac (diff) |
Merge branch 'next/dt' into next/multiplatform
* next/dt: (182 commits)
ARM: tegra: Add Avionic Design Tamonten Evaluation Carrier support
ARM: tegra: Add Avionic Design Medcom-Wide support
ARM: tegra: Add Avionic Design Plutux support
ARM: tegra: Add Avionic Design Tamonten support
ARM: tegra: dts: Add pwm label
ARM: dt: tegra: whistler: configure power off
ARM: mxs: m28evk: Disable OCOTP OUI loading
ARM: imx6q: use pll2_pfd2_396m as the enfc_sel's parent
ARM: dts: imx6q-sabrelite: add usbotg pinctrl support
ARM: dts: imx23-olinuxino: Add USB host support
ARM: dts: imx6q-sabrelite: add usbmisc device
ARM: dts: mx23: Add USB resources
ARM: dts: mxs: Add ethernetX to macX aliases
ARM: msm: Remove non-DT targets from 8960
ARM: msm: Add DT support for 8960
ARM: msm: Move io mapping prototypes to common.h
ARM: msm: Rename board-msm8x60 to signify its DT only status
ARM: msm: Make 8660 a DT only target
ARM: msm: Move 8660 to DT timer
ARM: msm: Add DT support to msm_timer
...
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-pxa.c | 77 | ||||
-rw-r--r-- | drivers/gpio/gpio-samsung.c | 63 | ||||
-rw-r--r-- | drivers/gpio/gpio-twl4030.c | 77 |
3 files changed, 138 insertions, 79 deletions
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 9cac88a65f78..9528779ca463 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/syscore_ops.h> | 26 | #include <linux/syscore_ops.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | 28 | ||
29 | #include <asm/mach/irq.h> | ||
30 | |||
29 | #include <mach/irqs.h> | 31 | #include <mach/irqs.h> |
30 | 32 | ||
31 | /* | 33 | /* |
@@ -59,6 +61,7 @@ | |||
59 | #define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) | 61 | #define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) |
60 | 62 | ||
61 | int pxa_last_gpio; | 63 | int pxa_last_gpio; |
64 | static int irq_base; | ||
62 | 65 | ||
63 | #ifdef CONFIG_OF | 66 | #ifdef CONFIG_OF |
64 | static struct irq_domain *domain; | 67 | static struct irq_domain *domain; |
@@ -167,63 +170,14 @@ static inline int __gpio_is_occupied(unsigned gpio) | |||
167 | return ret; | 170 | return ret; |
168 | } | 171 | } |
169 | 172 | ||
170 | #ifdef CONFIG_ARCH_PXA | ||
171 | static inline int __pxa_gpio_to_irq(int gpio) | ||
172 | { | ||
173 | if (gpio_is_pxa_type(gpio_type)) | ||
174 | return PXA_GPIO_TO_IRQ(gpio); | ||
175 | return -1; | ||
176 | } | ||
177 | |||
178 | static inline int __pxa_irq_to_gpio(int irq) | ||
179 | { | ||
180 | if (gpio_is_pxa_type(gpio_type)) | ||
181 | return irq - PXA_GPIO_TO_IRQ(0); | ||
182 | return -1; | ||
183 | } | ||
184 | #else | ||
185 | static inline int __pxa_gpio_to_irq(int gpio) { return -1; } | ||
186 | static inline int __pxa_irq_to_gpio(int irq) { return -1; } | ||
187 | #endif | ||
188 | |||
189 | #ifdef CONFIG_ARCH_MMP | ||
190 | static inline int __mmp_gpio_to_irq(int gpio) | ||
191 | { | ||
192 | if (gpio_is_mmp_type(gpio_type)) | ||
193 | return MMP_GPIO_TO_IRQ(gpio); | ||
194 | return -1; | ||
195 | } | ||
196 | |||
197 | static inline int __mmp_irq_to_gpio(int irq) | ||
198 | { | ||
199 | if (gpio_is_mmp_type(gpio_type)) | ||
200 | return irq - MMP_GPIO_TO_IRQ(0); | ||
201 | return -1; | ||
202 | } | ||
203 | #else | ||
204 | static inline int __mmp_gpio_to_irq(int gpio) { return -1; } | ||
205 | static inline int __mmp_irq_to_gpio(int irq) { return -1; } | ||
206 | #endif | ||
207 | |||
208 | static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | 173 | static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset) |
209 | { | 174 | { |
210 | int gpio, ret; | 175 | return chip->base + offset + irq_base; |
211 | |||
212 | gpio = chip->base + offset; | ||
213 | ret = __pxa_gpio_to_irq(gpio); | ||
214 | if (ret >= 0) | ||
215 | return ret; | ||
216 | return __mmp_gpio_to_irq(gpio); | ||
217 | } | 176 | } |
218 | 177 | ||
219 | int pxa_irq_to_gpio(int irq) | 178 | int pxa_irq_to_gpio(int irq) |
220 | { | 179 | { |
221 | int ret; | 180 | return irq - irq_base; |
222 | |||
223 | ret = __pxa_irq_to_gpio(irq); | ||
224 | if (ret >= 0) | ||
225 | return ret; | ||
226 | return __mmp_irq_to_gpio(irq); | ||
227 | } | 181 | } |
228 | 182 | ||
229 | static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 183 | static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
@@ -403,6 +357,9 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) | |||
403 | struct pxa_gpio_chip *c; | 357 | struct pxa_gpio_chip *c; |
404 | int loop, gpio, gpio_base, n; | 358 | int loop, gpio, gpio_base, n; |
405 | unsigned long gedr; | 359 | unsigned long gedr; |
360 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
361 | |||
362 | chained_irq_enter(chip, desc); | ||
406 | 363 | ||
407 | do { | 364 | do { |
408 | loop = 0; | 365 | loop = 0; |
@@ -422,6 +379,8 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) | |||
422 | } | 379 | } |
423 | } | 380 | } |
424 | } while (loop); | 381 | } while (loop); |
382 | |||
383 | chained_irq_exit(chip, desc); | ||
425 | } | 384 | } |
426 | 385 | ||
427 | static void pxa_ack_muxed_gpio(struct irq_data *d) | 386 | static void pxa_ack_muxed_gpio(struct irq_data *d) |
@@ -535,7 +494,7 @@ const struct irq_domain_ops pxa_irq_domain_ops = { | |||
535 | 494 | ||
536 | static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) | 495 | static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) |
537 | { | 496 | { |
538 | int ret, nr_banks, nr_gpios, irq_base; | 497 | int ret, nr_banks, nr_gpios; |
539 | struct device_node *prev, *next, *np = pdev->dev.of_node; | 498 | struct device_node *prev, *next, *np = pdev->dev.of_node; |
540 | const struct of_device_id *of_id = | 499 | const struct of_device_id *of_id = |
541 | of_match_device(pxa_gpio_dt_ids, &pdev->dev); | 500 | of_match_device(pxa_gpio_dt_ids, &pdev->dev); |
@@ -590,10 +549,20 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) | |||
590 | int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; | 549 | int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; |
591 | 550 | ||
592 | ret = pxa_gpio_probe_dt(pdev); | 551 | ret = pxa_gpio_probe_dt(pdev); |
593 | if (ret < 0) | 552 | if (ret < 0) { |
594 | pxa_last_gpio = pxa_gpio_nums(); | 553 | pxa_last_gpio = pxa_gpio_nums(); |
595 | else | 554 | #ifdef CONFIG_ARCH_PXA |
555 | if (gpio_is_pxa_type(gpio_type)) | ||
556 | irq_base = PXA_GPIO_TO_IRQ(0); | ||
557 | #endif | ||
558 | #ifdef CONFIG_ARCH_MMP | ||
559 | if (gpio_is_mmp_type(gpio_type)) | ||
560 | irq_base = MMP_GPIO_TO_IRQ(0); | ||
561 | #endif | ||
562 | } else { | ||
596 | use_of = 1; | 563 | use_of = 1; |
564 | } | ||
565 | |||
597 | if (!pxa_last_gpio) | 566 | if (!pxa_last_gpio) |
598 | return -EINVAL; | 567 | return -EINVAL; |
599 | 568 | ||
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index 1c169324e357..8af4b06e80f7 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c | |||
@@ -938,6 +938,67 @@ static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip) | |||
938 | s3c_gpiolib_track(chip); | 938 | s3c_gpiolib_track(chip); |
939 | } | 939 | } |
940 | 940 | ||
941 | #if defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF) | ||
942 | static int s3c24xx_gpio_xlate(struct gpio_chip *gc, | ||
943 | const struct of_phandle_args *gpiospec, u32 *flags) | ||
944 | { | ||
945 | unsigned int pin; | ||
946 | |||
947 | if (WARN_ON(gc->of_gpio_n_cells < 3)) | ||
948 | return -EINVAL; | ||
949 | |||
950 | if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) | ||
951 | return -EINVAL; | ||
952 | |||
953 | if (gpiospec->args[0] > gc->ngpio) | ||
954 | return -EINVAL; | ||
955 | |||
956 | pin = gc->base + gpiospec->args[0]; | ||
957 | |||
958 | if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1]))) | ||
959 | pr_warn("gpio_xlate: failed to set pin function\n"); | ||
960 | if (s3c_gpio_setpull(pin, gpiospec->args[2] & 0xffff)) | ||
961 | pr_warn("gpio_xlate: failed to set pin pull up/down\n"); | ||
962 | |||
963 | if (flags) | ||
964 | *flags = gpiospec->args[2] >> 16; | ||
965 | |||
966 | return gpiospec->args[0]; | ||
967 | } | ||
968 | |||
969 | static const struct of_device_id s3c24xx_gpio_dt_match[] __initdata = { | ||
970 | { .compatible = "samsung,s3c24xx-gpio", }, | ||
971 | {} | ||
972 | }; | ||
973 | |||
974 | static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip, | ||
975 | u64 base, u64 offset) | ||
976 | { | ||
977 | struct gpio_chip *gc = &chip->chip; | ||
978 | u64 address; | ||
979 | |||
980 | if (!of_have_populated_dt()) | ||
981 | return; | ||
982 | |||
983 | address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset; | ||
984 | gc->of_node = of_find_matching_node_by_address(NULL, | ||
985 | s3c24xx_gpio_dt_match, address); | ||
986 | if (!gc->of_node) { | ||
987 | pr_info("gpio: device tree node not found for gpio controller" | ||
988 | " with base address %08llx\n", address); | ||
989 | return; | ||
990 | } | ||
991 | gc->of_gpio_n_cells = 3; | ||
992 | gc->of_xlate = s3c24xx_gpio_xlate; | ||
993 | } | ||
994 | #else | ||
995 | static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip, | ||
996 | u64 base, u64 offset) | ||
997 | { | ||
998 | return; | ||
999 | } | ||
1000 | #endif /* defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF) */ | ||
1001 | |||
941 | static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip, | 1002 | static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip, |
942 | int nr_chips, void __iomem *base) | 1003 | int nr_chips, void __iomem *base) |
943 | { | 1004 | { |
@@ -962,6 +1023,8 @@ static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip, | |||
962 | gc->direction_output = samsung_gpiolib_2bit_output; | 1023 | gc->direction_output = samsung_gpiolib_2bit_output; |
963 | 1024 | ||
964 | samsung_gpiolib_add(chip); | 1025 | samsung_gpiolib_add(chip); |
1026 | |||
1027 | s3c24xx_gpiolib_attach_ofnode(chip, S3C24XX_PA_GPIO, i * 0x10); | ||
965 | } | 1028 | } |
966 | } | 1029 | } |
967 | 1030 | ||
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c index f030880bc9bb..c5f8ca233e1f 100644 --- a/drivers/gpio/gpio-twl4030.c +++ b/drivers/gpio/gpio-twl4030.c | |||
@@ -396,6 +396,29 @@ static int __devinit gpio_twl4030_debounce(u32 debounce, u8 mmc_cd) | |||
396 | 396 | ||
397 | static int gpio_twl4030_remove(struct platform_device *pdev); | 397 | static int gpio_twl4030_remove(struct platform_device *pdev); |
398 | 398 | ||
399 | static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev) | ||
400 | { | ||
401 | struct twl4030_gpio_platform_data *omap_twl_info; | ||
402 | |||
403 | omap_twl_info = devm_kzalloc(dev, sizeof(*omap_twl_info), GFP_KERNEL); | ||
404 | if (!omap_twl_info) | ||
405 | return NULL; | ||
406 | |||
407 | omap_twl_info->use_leds = of_property_read_bool(dev->of_node, | ||
408 | "ti,use-leds"); | ||
409 | |||
410 | of_property_read_u32(dev->of_node, "ti,debounce", | ||
411 | &omap_twl_info->debounce); | ||
412 | of_property_read_u32(dev->of_node, "ti,mmc-cd", | ||
413 | (u32 *)&omap_twl_info->mmc_cd); | ||
414 | of_property_read_u32(dev->of_node, "ti,pullups", | ||
415 | &omap_twl_info->pullups); | ||
416 | of_property_read_u32(dev->of_node, "ti,pulldowns", | ||
417 | &omap_twl_info->pulldowns); | ||
418 | |||
419 | return omap_twl_info; | ||
420 | } | ||
421 | |||
399 | static int __devinit gpio_twl4030_probe(struct platform_device *pdev) | 422 | static int __devinit gpio_twl4030_probe(struct platform_device *pdev) |
400 | { | 423 | { |
401 | struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; | 424 | struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; |
@@ -428,33 +451,37 @@ no_irqs: | |||
428 | twl_gpiochip.ngpio = TWL4030_GPIO_MAX; | 451 | twl_gpiochip.ngpio = TWL4030_GPIO_MAX; |
429 | twl_gpiochip.dev = &pdev->dev; | 452 | twl_gpiochip.dev = &pdev->dev; |
430 | 453 | ||
431 | if (pdata) { | 454 | if (node) |
432 | /* | 455 | pdata = of_gpio_twl4030(&pdev->dev); |
433 | * NOTE: boards may waste power if they don't set pullups | 456 | |
434 | * and pulldowns correctly ... default for non-ULPI pins is | 457 | if (pdata == NULL) { |
435 | * pulldown, and some other pins may have external pullups | 458 | dev_err(&pdev->dev, "Platform data is missing\n"); |
436 | * or pulldowns. Careful! | 459 | return -ENXIO; |
437 | */ | ||
438 | ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns); | ||
439 | if (ret) | ||
440 | dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n", | ||
441 | pdata->pullups, pdata->pulldowns, | ||
442 | ret); | ||
443 | |||
444 | ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd); | ||
445 | if (ret) | ||
446 | dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n", | ||
447 | pdata->debounce, pdata->mmc_cd, | ||
448 | ret); | ||
449 | |||
450 | /* | ||
451 | * NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE, | ||
452 | * is (still) clear if use_leds is set. | ||
453 | */ | ||
454 | if (pdata->use_leds) | ||
455 | twl_gpiochip.ngpio += 2; | ||
456 | } | 460 | } |
457 | 461 | ||
462 | /* | ||
463 | * NOTE: boards may waste power if they don't set pullups | ||
464 | * and pulldowns correctly ... default for non-ULPI pins is | ||
465 | * pulldown, and some other pins may have external pullups | ||
466 | * or pulldowns. Careful! | ||
467 | */ | ||
468 | ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns); | ||
469 | if (ret) | ||
470 | dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n", | ||
471 | pdata->pullups, pdata->pulldowns, ret); | ||
472 | |||
473 | ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd); | ||
474 | if (ret) | ||
475 | dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n", | ||
476 | pdata->debounce, pdata->mmc_cd, ret); | ||
477 | |||
478 | /* | ||
479 | * NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE, | ||
480 | * is (still) clear if use_leds is set. | ||
481 | */ | ||
482 | if (pdata->use_leds) | ||
483 | twl_gpiochip.ngpio += 2; | ||
484 | |||
458 | ret = gpiochip_add(&twl_gpiochip); | 485 | ret = gpiochip_add(&twl_gpiochip); |
459 | if (ret < 0) { | 486 | if (ret < 0) { |
460 | dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret); | 487 | dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret); |