aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2012-07-12 11:35:02 -0400
committerJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2012-10-12 21:21:43 -0400
commit6732ae5cb47c4f9a72727585956f2a5e069d1637 (patch)
tree8d350c462f7b29e6bd033aadd7a2607bc160a487 /arch
parent97e5e625248e588de234aa5134cebbf969618dcf (diff)
ARM: at91: add pinctrl support
This is also include the gpio controller as the IP share both. Each soc will have to describe the SoC limitation and pin configuration via DT. This will allow to do not need to touch the C code when adding new SoC if the IP version is supported. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/mach-at91/board-dt.c2
-rw-r--r--arch/arm/mach-at91/gpio.c165
3 files changed, 7 insertions, 162 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 431c3753145a..3d7f11fe610d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -329,6 +329,8 @@ config ARCH_AT91
329 select IRQ_DOMAIN 329 select IRQ_DOMAIN
330 select NEED_MACH_GPIO_H 330 select NEED_MACH_GPIO_H
331 select NEED_MACH_IO_H if PCCARD 331 select NEED_MACH_IO_H if PCCARD
332 select PINCTRL
333 select PINCTRL_AT91 if USE_OF
332 help 334 help
333 This enables support for systems based on Atmel 335 This enables support for systems based on Atmel
334 AT91RM9200 and AT91SAM9* processors. 336 AT91RM9200 and AT91SAM9* processors.
diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c
index e8f45c4e0ea8..3b6a94820fa0 100644
--- a/arch/arm/mach-at91/board-dt.c
+++ b/arch/arm/mach-at91/board-dt.c
@@ -30,8 +30,6 @@
30static const struct of_device_id irq_of_match[] __initconst = { 30static const struct of_device_id irq_of_match[] __initconst = {
31 31
32 { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init }, 32 { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
33 { .compatible = "atmel,at91rm9200-gpio", .data = at91_gpio_of_irq_setup },
34 { .compatible = "atmel,at91sam9x5-gpio", .data = at91_gpio_of_irq_setup },
35 { /*sentinel*/ } 33 { /*sentinel*/ }
36}; 34};
37 35
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index a34f0ed291c0..c5d7e1e9d757 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -23,8 +23,6 @@
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/irqdomain.h> 24#include <linux/irqdomain.h>
25#include <linux/of_address.h> 25#include <linux/of_address.h>
26#include <linux/of_irq.h>
27#include <linux/of_gpio.h>
28 26
29#include <asm/mach/irq.h> 27#include <asm/mach/irq.h>
30 28
@@ -717,80 +715,6 @@ postcore_initcall(at91_gpio_debugfs_init);
717 */ 715 */
718static struct lock_class_key gpio_lock_class; 716static struct lock_class_key gpio_lock_class;
719 717
720#if defined(CONFIG_OF)
721static int at91_gpio_irq_map(struct irq_domain *h, unsigned int virq,
722 irq_hw_number_t hw)
723{
724 struct at91_gpio_chip *at91_gpio = h->host_data;
725
726 irq_set_lockdep_class(virq, &gpio_lock_class);
727
728 /*
729 * Can use the "simple" and not "edge" handler since it's
730 * shorter, and the AIC handles interrupts sanely.
731 */
732 irq_set_chip_and_handler(virq, &gpio_irqchip,
733 handle_simple_irq);
734 set_irq_flags(virq, IRQF_VALID);
735 irq_set_chip_data(virq, at91_gpio);
736
737 return 0;
738}
739
740static struct irq_domain_ops at91_gpio_ops = {
741 .map = at91_gpio_irq_map,
742 .xlate = irq_domain_xlate_twocell,
743};
744
745int __init at91_gpio_of_irq_setup(struct device_node *node,
746 struct device_node *parent)
747{
748 struct at91_gpio_chip *prev = NULL;
749 int alias_idx = of_alias_get_id(node, "gpio");
750 struct at91_gpio_chip *at91_gpio = &gpio_chip[alias_idx];
751
752 /* Setup proper .irq_set_type function */
753 if (has_pio3())
754 gpio_irqchip.irq_set_type = alt_gpio_irq_type;
755 else
756 gpio_irqchip.irq_set_type = gpio_irq_type;
757
758 /* Disable irqs of this PIO controller */
759 __raw_writel(~0, at91_gpio->regbase + PIO_IDR);
760
761 /* Setup irq domain */
762 at91_gpio->domain = irq_domain_add_linear(node, at91_gpio->chip.ngpio,
763 &at91_gpio_ops, at91_gpio);
764 if (!at91_gpio->domain)
765 panic("at91_gpio.%d: couldn't allocate irq domain (DT).\n",
766 at91_gpio->pioc_idx);
767
768 /* Setup chained handler */
769 if (at91_gpio->pioc_idx)
770 prev = &gpio_chip[at91_gpio->pioc_idx - 1];
771
772 /* The toplevel handler handles one bank of GPIOs, except
773 * on some SoC it can handles up to three...
774 * We only set up the handler for the first of the list.
775 */
776 if (prev && prev->next == at91_gpio)
777 return 0;
778
779 at91_gpio->pioc_virq = irq_create_mapping(irq_find_host(parent),
780 at91_gpio->pioc_hwirq);
781 irq_set_chip_data(at91_gpio->pioc_virq, at91_gpio);
782 irq_set_chained_handler(at91_gpio->pioc_virq, gpio_irq_handler);
783
784 return 0;
785}
786#else
787int __init at91_gpio_of_irq_setup(struct device_node *node,
788 struct device_node *parent)
789{
790 return -EINVAL;
791}
792#endif
793
794/* 718/*
795 * irqdomain initialization: pile up irqdomains on top of AIC range 719 * irqdomain initialization: pile up irqdomains on top of AIC range
796 */ 720 */
@@ -989,85 +913,6 @@ err:
989 return -EINVAL; 913 return -EINVAL;
990} 914}
991 915
992#ifdef CONFIG_OF_GPIO
993static void __init of_at91_gpio_init_one(struct device_node *np)
994{
995 int alias_idx;
996 struct at91_gpio_chip *at91_gpio;
997 uint32_t ngpio;
998
999 if (!np)
1000 return;
1001
1002 alias_idx = of_alias_get_id(np, "gpio");
1003 if (alias_idx >= MAX_GPIO_BANKS) {
1004 pr_err("at91_gpio, failed alias idx(%d) > MAX_GPIO_BANKS(%d), ignoring.\n",
1005 alias_idx, MAX_GPIO_BANKS);
1006 return;
1007 }
1008
1009 at91_gpio = &gpio_chip[alias_idx];
1010 at91_gpio->chip.base = alias_idx * MAX_NB_GPIO_PER_BANK;
1011
1012 at91_gpio->regbase = of_iomap(np, 0);
1013 if (!at91_gpio->regbase) {
1014 pr_err("at91_gpio.%d, failed to map registers, ignoring.\n",
1015 alias_idx);
1016 return;
1017 }
1018
1019 /* Get the interrupts property */
1020 if (of_property_read_u32(np, "interrupts", &at91_gpio->pioc_hwirq)) {
1021 pr_err("at91_gpio.%d, failed to get interrupts property, ignoring.\n",
1022 alias_idx);
1023 goto ioremap_err;
1024 }
1025
1026 /* Get capabilities from compatibility property */
1027 if (of_device_is_compatible(np, "atmel,at91sam9x5-gpio"))
1028 at91_gpio_caps |= AT91_GPIO_CAP_PIO3;
1029
1030 if (!of_property_read_u32(np, "#gpio-lines", &ngpio)) {
1031 if (ngpio >= MAX_NB_GPIO_PER_BANK)
1032 pr_err("at91_gpio.%d, gpio-nb >= %d failback to %d\n",
1033 alias_idx, MAX_NB_GPIO_PER_BANK, MAX_NB_GPIO_PER_BANK);
1034 else
1035 at91_gpio->chip.ngpio = ngpio;
1036 }
1037
1038 /* Setup clock */
1039 if (at91_gpio_setup_clk(alias_idx))
1040 goto ioremap_err;
1041
1042 at91_gpio->chip.of_node = np;
1043 gpio_banks = max(gpio_banks, alias_idx + 1);
1044 at91_gpio->pioc_idx = alias_idx;
1045 return;
1046
1047ioremap_err:
1048 iounmap(at91_gpio->regbase);
1049}
1050
1051static int __init of_at91_gpio_init(void)
1052{
1053 struct device_node *np = NULL;
1054
1055 /*
1056 * This isn't ideal, but it gets things hooked up until this
1057 * driver is converted into a platform_device
1058 */
1059 for_each_compatible_node(np, NULL, "atmel,at91rm9200-gpio")
1060 of_at91_gpio_init_one(np);
1061
1062 return gpio_banks > 0 ? 0 : -EINVAL;
1063}
1064#else
1065static int __init of_at91_gpio_init(void)
1066{
1067 return -EINVAL;
1068}
1069#endif
1070
1071static void __init at91_gpio_init_one(int idx, u32 regbase, int pioc_hwirq) 916static void __init at91_gpio_init_one(int idx, u32 regbase, int pioc_hwirq)
1072{ 917{
1073 struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; 918 struct at91_gpio_chip *at91_gpio = &gpio_chip[idx];
@@ -1102,11 +947,11 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
1102 947
1103 BUG_ON(nr_banks > MAX_GPIO_BANKS); 948 BUG_ON(nr_banks > MAX_GPIO_BANKS);
1104 949
1105 if (of_at91_gpio_init() < 0) { 950 if (of_have_populated_dt())
1106 /* No GPIO controller found in device tree */ 951 return;
1107 for (i = 0; i < nr_banks; i++) 952
1108 at91_gpio_init_one(i, data[i].regbase, data[i].id); 953 for (i = 0; i < nr_banks; i++)
1109 } 954 at91_gpio_init_one(i, data[i].regbase, data[i].id);
1110 955
1111 for (i = 0; i < gpio_banks; i++) { 956 for (i = 0; i < gpio_banks; i++) {
1112 at91_gpio = &gpio_chip[i]; 957 at91_gpio = &gpio_chip[i];