diff options
author | Cyril Chemparathy <cyril@ti.com> | 2010-05-01 18:37:53 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2010-05-06 18:02:08 -0400 |
commit | c12f415a9144a76dc99df34f56ce3022207ad1d0 (patch) | |
tree | 6fa81f4b2494ab8d0bf4f6bd7f71b5c0bdae8ecb | |
parent | 99e9e52de635728d7c89a0fdf79b307f3082cf3a (diff) |
Davinci: gpio - register layout invariant inlines
This patch renders the inlined gpio accessors in gpio.h independent of the
underlying controller's register layout. This is done by including three new
fields in davinci_gpio_controller to hold the addresses of the set, clear, and
in data registers.
Other changes:
1. davinci_gpio_regs structure definition moved to gpio.c. This structure is
no longer common across all davinci socs (davinci_gpio_controller is).
2. controller base address calculation code (gpio2controller()) moved to
gpio.c as this was no longer necessary for the inline implementation.
3. modified inline range checks to use davinci_soc_info.gpio_num instead of
DAVINCI_N_GPIO.
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Tested-by: Sandeep Paulraj <s-paulraj@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
-rw-r--r-- | arch/arm/mach-davinci/gpio.c | 41 | ||||
-rw-r--r-- | arch/arm/mach-davinci/include/mach/common.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-davinci/include/mach/gpio.h | 65 |
3 files changed, 65 insertions, 45 deletions
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index c77683c3c3d2..d241b4f2abe2 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c | |||
@@ -20,6 +20,19 @@ | |||
20 | 20 | ||
21 | #include <asm/mach/irq.h> | 21 | #include <asm/mach/irq.h> |
22 | 22 | ||
23 | struct davinci_gpio_regs { | ||
24 | u32 dir; | ||
25 | u32 out_data; | ||
26 | u32 set_data; | ||
27 | u32 clr_data; | ||
28 | u32 in_data; | ||
29 | u32 set_rising; | ||
30 | u32 clr_rising; | ||
31 | u32 set_falling; | ||
32 | u32 clr_falling; | ||
33 | u32 intstat; | ||
34 | }; | ||
35 | |||
23 | static DEFINE_SPINLOCK(gpio_lock); | 36 | static DEFINE_SPINLOCK(gpio_lock); |
24 | 37 | ||
25 | #define chip2controller(chip) \ | 38 | #define chip2controller(chip) \ |
@@ -27,10 +40,24 @@ static DEFINE_SPINLOCK(gpio_lock); | |||
27 | 40 | ||
28 | static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; | 41 | static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; |
29 | 42 | ||
30 | /* create a non-inlined version */ | ||
31 | static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio) | 43 | static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio) |
32 | { | 44 | { |
33 | return __gpio_to_controller(gpio); | 45 | void __iomem *ptr; |
46 | void __iomem *base = davinci_soc_info.gpio_base; | ||
47 | |||
48 | if (gpio < 32 * 1) | ||
49 | ptr = base + 0x10; | ||
50 | else if (gpio < 32 * 2) | ||
51 | ptr = base + 0x38; | ||
52 | else if (gpio < 32 * 3) | ||
53 | ptr = base + 0x60; | ||
54 | else if (gpio < 32 * 4) | ||
55 | ptr = base + 0x88; | ||
56 | else if (gpio < 32 * 5) | ||
57 | ptr = base + 0xb0; | ||
58 | else | ||
59 | ptr = NULL; | ||
60 | return ptr; | ||
34 | } | 61 | } |
35 | 62 | ||
36 | static inline struct davinci_gpio_regs __iomem *irq2regs(int irq) | 63 | static inline struct davinci_gpio_regs __iomem *irq2regs(int irq) |
@@ -116,6 +143,7 @@ static int __init davinci_gpio_setup(void) | |||
116 | int i, base; | 143 | int i, base; |
117 | unsigned ngpio; | 144 | unsigned ngpio; |
118 | struct davinci_soc_info *soc_info = &davinci_soc_info; | 145 | struct davinci_soc_info *soc_info = &davinci_soc_info; |
146 | struct davinci_gpio_regs *regs; | ||
119 | 147 | ||
120 | /* | 148 | /* |
121 | * The gpio banks conceptually expose a segmented bitmap, | 149 | * The gpio banks conceptually expose a segmented bitmap, |
@@ -144,11 +172,18 @@ static int __init davinci_gpio_setup(void) | |||
144 | if (chips[i].chip.ngpio > 32) | 172 | if (chips[i].chip.ngpio > 32) |
145 | chips[i].chip.ngpio = 32; | 173 | chips[i].chip.ngpio = 32; |
146 | 174 | ||
147 | chips[i].regs = gpio2regs(base); | 175 | regs = gpio2regs(base); |
176 | chips[i].regs = regs; | ||
177 | chips[i].set_data = ®s->set_data; | ||
178 | chips[i].clr_data = ®s->clr_data; | ||
179 | chips[i].in_data = ®s->in_data; | ||
148 | 180 | ||
149 | gpiochip_add(&chips[i].chip); | 181 | gpiochip_add(&chips[i].chip); |
150 | } | 182 | } |
151 | 183 | ||
184 | soc_info->gpio_ctlrs = chips; | ||
185 | soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32); | ||
186 | |||
152 | davinci_gpio_irq_setup(); | 187 | davinci_gpio_irq_setup(); |
153 | return 0; | 188 | return 0; |
154 | } | 189 | } |
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 884dc726e9b9..1d72883f593e 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h | |||
@@ -37,6 +37,8 @@ struct davinci_timer_info { | |||
37 | unsigned int clocksource_id; | 37 | unsigned int clocksource_id; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | struct davinci_gpio_controller; | ||
41 | |||
40 | /* SoC specific init support */ | 42 | /* SoC specific init support */ |
41 | struct davinci_soc_info { | 43 | struct davinci_soc_info { |
42 | struct map_desc *io_desc; | 44 | struct map_desc *io_desc; |
@@ -61,6 +63,8 @@ struct davinci_soc_info { | |||
61 | unsigned gpio_num; | 63 | unsigned gpio_num; |
62 | unsigned gpio_irq; | 64 | unsigned gpio_irq; |
63 | unsigned gpio_unbanked; | 65 | unsigned gpio_unbanked; |
66 | struct davinci_gpio_controller *gpio_ctlrs; | ||
67 | int gpio_ctlrs_num; | ||
64 | struct platform_device *serial_dev; | 68 | struct platform_device *serial_dev; |
65 | struct emac_platform_data *emac_pdata; | 69 | struct emac_platform_data *emac_pdata; |
66 | dma_addr_t sram_dma; | 70 | dma_addr_t sram_dma; |
diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h index bdab001950ba..82591d0d48fb 100644 --- a/arch/arm/mach-davinci/include/mach/gpio.h +++ b/arch/arm/mach-davinci/include/mach/gpio.h | |||
@@ -45,23 +45,13 @@ | |||
45 | /* Convert GPIO signal to GPIO pin number */ | 45 | /* Convert GPIO signal to GPIO pin number */ |
46 | #define GPIO_TO_PIN(bank, gpio) (16 * (bank) + (gpio)) | 46 | #define GPIO_TO_PIN(bank, gpio) (16 * (bank) + (gpio)) |
47 | 47 | ||
48 | struct davinci_gpio_regs { | ||
49 | u32 dir; | ||
50 | u32 out_data; | ||
51 | u32 set_data; | ||
52 | u32 clr_data; | ||
53 | u32 in_data; | ||
54 | u32 set_rising; | ||
55 | u32 clr_rising; | ||
56 | u32 set_falling; | ||
57 | u32 clr_falling; | ||
58 | u32 intstat; | ||
59 | }; | ||
60 | |||
61 | struct davinci_gpio_controller { | 48 | struct davinci_gpio_controller { |
62 | struct davinci_gpio_regs __iomem *regs; | ||
63 | struct gpio_chip chip; | 49 | struct gpio_chip chip; |
64 | int irq_base; | 50 | int irq_base; |
51 | void __iomem *regs; | ||
52 | void __iomem *set_data; | ||
53 | void __iomem *clr_data; | ||
54 | void __iomem *in_data; | ||
65 | }; | 55 | }; |
66 | 56 | ||
67 | /* The __gpio_to_controller() and __gpio_mask() functions inline to constants | 57 | /* The __gpio_to_controller() and __gpio_mask() functions inline to constants |
@@ -73,25 +63,16 @@ struct davinci_gpio_controller { | |||
73 | * | 63 | * |
74 | * These are NOT part of the cross-platform GPIO interface | 64 | * These are NOT part of the cross-platform GPIO interface |
75 | */ | 65 | */ |
76 | static inline struct davinci_gpio_regs __iomem * | 66 | static inline struct davinci_gpio_controller * |
77 | __gpio_to_controller(unsigned gpio) | 67 | __gpio_to_controller(unsigned gpio) |
78 | { | 68 | { |
79 | void __iomem *ptr; | 69 | struct davinci_gpio_controller *ctlrs = davinci_soc_info.gpio_ctlrs; |
80 | void __iomem *base = davinci_soc_info.gpio_base; | 70 | int index = gpio / 32; |
81 | 71 | ||
82 | if (gpio < 32 * 1) | 72 | if (!ctlrs || index >= davinci_soc_info.gpio_ctlrs_num) |
83 | ptr = base + 0x10; | 73 | return NULL; |
84 | else if (gpio < 32 * 2) | 74 | |
85 | ptr = base + 0x38; | 75 | return ctlrs + index; |
86 | else if (gpio < 32 * 3) | ||
87 | ptr = base + 0x60; | ||
88 | else if (gpio < 32 * 4) | ||
89 | ptr = base + 0x88; | ||
90 | else if (gpio < 32 * 5) | ||
91 | ptr = base + 0xb0; | ||
92 | else | ||
93 | ptr = NULL; | ||
94 | return ptr; | ||
95 | } | 76 | } |
96 | 77 | ||
97 | static inline u32 __gpio_mask(unsigned gpio) | 78 | static inline u32 __gpio_mask(unsigned gpio) |
@@ -107,16 +88,16 @@ static inline u32 __gpio_mask(unsigned gpio) | |||
107 | */ | 88 | */ |
108 | static inline void gpio_set_value(unsigned gpio, int value) | 89 | static inline void gpio_set_value(unsigned gpio, int value) |
109 | { | 90 | { |
110 | if (__builtin_constant_p(value) && gpio < DAVINCI_N_GPIO) { | 91 | if (__builtin_constant_p(value) && gpio < davinci_soc_info.gpio_num) { |
111 | struct davinci_gpio_regs __iomem *g; | 92 | struct davinci_gpio_controller *ctlr; |
112 | u32 mask; | 93 | u32 mask; |
113 | 94 | ||
114 | g = __gpio_to_controller(gpio); | 95 | ctlr = __gpio_to_controller(gpio); |
115 | mask = __gpio_mask(gpio); | 96 | mask = __gpio_mask(gpio); |
116 | if (value) | 97 | if (value) |
117 | __raw_writel(mask, &g->set_data); | 98 | __raw_writel(mask, ctlr->set_data); |
118 | else | 99 | else |
119 | __raw_writel(mask, &g->clr_data); | 100 | __raw_writel(mask, ctlr->clr_data); |
120 | return; | 101 | return; |
121 | } | 102 | } |
122 | 103 | ||
@@ -134,18 +115,18 @@ static inline void gpio_set_value(unsigned gpio, int value) | |||
134 | */ | 115 | */ |
135 | static inline int gpio_get_value(unsigned gpio) | 116 | static inline int gpio_get_value(unsigned gpio) |
136 | { | 117 | { |
137 | struct davinci_gpio_regs __iomem *g; | 118 | struct davinci_gpio_controller *ctlr; |
138 | 119 | ||
139 | if (!__builtin_constant_p(gpio) || gpio >= DAVINCI_N_GPIO) | 120 | if (!__builtin_constant_p(gpio) || gpio >= davinci_soc_info.gpio_num) |
140 | return __gpio_get_value(gpio); | 121 | return __gpio_get_value(gpio); |
141 | 122 | ||
142 | g = __gpio_to_controller(gpio); | 123 | ctlr = __gpio_to_controller(gpio); |
143 | return __gpio_mask(gpio) & __raw_readl(&g->in_data); | 124 | return __gpio_mask(gpio) & __raw_readl(ctlr->in_data); |
144 | } | 125 | } |
145 | 126 | ||
146 | static inline int gpio_cansleep(unsigned gpio) | 127 | static inline int gpio_cansleep(unsigned gpio) |
147 | { | 128 | { |
148 | if (__builtin_constant_p(gpio) && gpio < DAVINCI_N_GPIO) | 129 | if (__builtin_constant_p(gpio) && gpio < davinci_soc_info.gpio_num) |
149 | return 0; | 130 | return 0; |
150 | else | 131 | else |
151 | return __gpio_cansleep(gpio); | 132 | return __gpio_cansleep(gpio); |