diff options
author | Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com> | 2008-02-15 02:41:06 -0500 |
---|---|---|
committer | Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com> | 2008-03-31 02:17:01 -0400 |
commit | 724ce5ee15ff4c4f3035110b683b990a3b33c832 (patch) | |
tree | 7b07d25bf64d2e6dad4495c847d1b24d9d5dca43 /arch/arm/mach-ns9xxx/gpio.c | |
parent | 3a581349b961f225893103a0fbbd065a831c5184 (diff) |
ns9xxx: prepare for adding support for Digi ns921x processors
The hardware team changed some things that were taken as being common to
all ns9xxx processors up to now.
This patch addresses:
- irqs: s/IRQ_/IRQ_NS9360_/
- system module registers: some registers are still general, their
definition lives now in include/asm-arm/arch-ns9xxx/regs-sys-common.h.
The ns9360 specific ones are in .../regs-sys-ns9360.h
As a result ns9360_systemclock cannot be static inline any more as its
definition needs regs-sys-ns9360.h. This becomes a real problem when
adding support for ns9215 as this will need regs-sys-ns9215.h and
including both files will not work. For the same reason
ns9360_reset() is now non-inline and gpio functions live in their own
file.
- register mapping: s/ns9xxx_map_io/ns9360_map_io/
- timer registers: move time.c to time-ns9360.c;
s/ns9xxx_timer/ns9360_timer/
Signed-off-by: Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
Diffstat (limited to 'arch/arm/mach-ns9xxx/gpio.c')
-rw-r--r-- | arch/arm/mach-ns9xxx/gpio.c | 141 |
1 files changed, 48 insertions, 93 deletions
diff --git a/arch/arm/mach-ns9xxx/gpio.c b/arch/arm/mach-ns9xxx/gpio.c index 5286e9fc1d30..b3c963b0c8f5 100644 --- a/arch/arm/mach-ns9xxx/gpio.c +++ b/arch/arm/mach-ns9xxx/gpio.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * arch/arm/mach-ns9xxx/gpio.c | 2 | * arch/arm/mach-ns9xxx/gpio.c |
3 | * | 3 | * |
4 | * Copyright (C) 2006 by Digi International Inc. | 4 | * Copyright (C) 2006,2007 by Digi International Inc. |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
@@ -15,12 +15,13 @@ | |||
15 | 15 | ||
16 | #include <asm/arch-ns9xxx/gpio.h> | 16 | #include <asm/arch-ns9xxx/gpio.h> |
17 | #include <asm/arch-ns9xxx/processor.h> | 17 | #include <asm/arch-ns9xxx/processor.h> |
18 | #include <asm/arch-ns9xxx/regs-bbu.h> | 18 | #include <asm/arch-ns9xxx/processor-ns9360.h> |
19 | #include <asm/io.h> | ||
20 | #include <asm/bug.h> | 19 | #include <asm/bug.h> |
21 | #include <asm/types.h> | 20 | #include <asm/types.h> |
22 | #include <asm/bitops.h> | 21 | #include <asm/bitops.h> |
23 | 22 | ||
23 | #include "gpio-ns9360.h" | ||
24 | |||
24 | #if defined(CONFIG_PROCESSOR_NS9360) | 25 | #if defined(CONFIG_PROCESSOR_NS9360) |
25 | #define GPIO_MAX 72 | 26 | #define GPIO_MAX 72 |
26 | #elif defined(CONFIG_PROCESSOR_NS9750) | 27 | #elif defined(CONFIG_PROCESSOR_NS9750) |
@@ -45,41 +46,10 @@ static inline int ns9xxx_valid_gpio(unsigned gpio) | |||
45 | return gpio <= 49; | 46 | return gpio <= 49; |
46 | else | 47 | else |
47 | #endif | 48 | #endif |
49 | { | ||
48 | BUG(); | 50 | BUG(); |
49 | } | 51 | return 0; |
50 | 52 | } | |
51 | static inline void __iomem *ns9xxx_gpio_get_gconfaddr(unsigned gpio) | ||
52 | { | ||
53 | if (gpio < 56) | ||
54 | return BBU_GCONFb1(gpio / 8); | ||
55 | else | ||
56 | /* | ||
57 | * this could be optimised away on | ||
58 | * ns9750 only builds, but it isn't ... | ||
59 | */ | ||
60 | return BBU_GCONFb2((gpio - 56) / 8); | ||
61 | } | ||
62 | |||
63 | static inline void __iomem *ns9xxx_gpio_get_gctrladdr(unsigned gpio) | ||
64 | { | ||
65 | if (gpio < 32) | ||
66 | return BBU_GCTRL1; | ||
67 | else if (gpio < 64) | ||
68 | return BBU_GCTRL2; | ||
69 | else | ||
70 | /* this could be optimised away on ns9750 only builds */ | ||
71 | return BBU_GCTRL3; | ||
72 | } | ||
73 | |||
74 | static inline void __iomem *ns9xxx_gpio_get_gstataddr(unsigned gpio) | ||
75 | { | ||
76 | if (gpio < 32) | ||
77 | return BBU_GSTAT1; | ||
78 | else if (gpio < 64) | ||
79 | return BBU_GSTAT2; | ||
80 | else | ||
81 | /* this could be optimised away on ns9750 only builds */ | ||
82 | return BBU_GSTAT3; | ||
83 | } | 53 | } |
84 | 54 | ||
85 | int gpio_request(unsigned gpio, const char *label) | 55 | int gpio_request(unsigned gpio, const char *label) |
@@ -98,49 +68,24 @@ void gpio_free(unsigned gpio) | |||
98 | } | 68 | } |
99 | EXPORT_SYMBOL(gpio_free); | 69 | EXPORT_SYMBOL(gpio_free); |
100 | 70 | ||
101 | /* | 71 | int gpio_direction_input(unsigned gpio) |
102 | * each gpio can serve for 4 different purposes [0..3]. These are called | ||
103 | * "functions" and passed in the parameter func. Functions 0-2 are always some | ||
104 | * special things, function 3 is GPIO. If func == 3 dir specifies input or | ||
105 | * output, and with inv you can enable an inverter (independent of func). | ||
106 | */ | ||
107 | static int __ns9xxx_gpio_configure(unsigned gpio, int dir, int inv, int func) | ||
108 | { | 72 | { |
109 | void __iomem *conf = ns9xxx_gpio_get_gconfaddr(gpio); | 73 | if (likely(ns9xxx_valid_gpio(gpio))) { |
110 | u32 confval; | 74 | int ret = -EINVAL; |
111 | unsigned long flags; | 75 | unsigned long flags; |
112 | |||
113 | spin_lock_irqsave(&gpio_lock, flags); | ||
114 | |||
115 | confval = __raw_readl(conf); | ||
116 | REGSETIM_IDX(confval, BBU_GCONFx, DIR, gpio & 7, dir); | ||
117 | REGSETIM_IDX(confval, BBU_GCONFx, INV, gpio & 7, inv); | ||
118 | REGSETIM_IDX(confval, BBU_GCONFx, FUNC, gpio & 7, func); | ||
119 | __raw_writel(confval, conf); | ||
120 | 76 | ||
121 | spin_unlock_irqrestore(&gpio_lock, flags); | 77 | spin_lock_irqsave(&gpio_lock, flags); |
78 | #if defined(CONFIG_PROCESSOR_NS9360) | ||
79 | if (processor_is_ns9360()) | ||
80 | ret = __ns9360_gpio_configure(gpio, 0, 0, 3); | ||
81 | else | ||
82 | #endif | ||
83 | BUG(); | ||
122 | 84 | ||
123 | return 0; | 85 | spin_unlock_irqrestore(&gpio_lock, flags); |
124 | } | ||
125 | 86 | ||
126 | int ns9xxx_gpio_configure(unsigned gpio, int inv, int func) | 87 | return ret; |
127 | { | ||
128 | if (likely(ns9xxx_valid_gpio(gpio))) { | ||
129 | if (func == 3) { | ||
130 | printk(KERN_WARNING "use gpio_direction_input " | ||
131 | "or gpio_direction_output\n"); | ||
132 | return -EINVAL; | ||
133 | } else | ||
134 | return __ns9xxx_gpio_configure(gpio, 0, inv, func); | ||
135 | } else | ||
136 | return -EINVAL; | ||
137 | } | ||
138 | EXPORT_SYMBOL(ns9xxx_gpio_configure); | ||
139 | 88 | ||
140 | int gpio_direction_input(unsigned gpio) | ||
141 | { | ||
142 | if (likely(ns9xxx_valid_gpio(gpio))) { | ||
143 | return __ns9xxx_gpio_configure(gpio, 0, 0, 3); | ||
144 | } else | 89 | } else |
145 | return -EINVAL; | 90 | return -EINVAL; |
146 | } | 91 | } |
@@ -149,9 +94,22 @@ EXPORT_SYMBOL(gpio_direction_input); | |||
149 | int gpio_direction_output(unsigned gpio, int value) | 94 | int gpio_direction_output(unsigned gpio, int value) |
150 | { | 95 | { |
151 | if (likely(ns9xxx_valid_gpio(gpio))) { | 96 | if (likely(ns9xxx_valid_gpio(gpio))) { |
97 | int ret = -EINVAL; | ||
98 | unsigned long flags; | ||
99 | |||
152 | gpio_set_value(gpio, value); | 100 | gpio_set_value(gpio, value); |
153 | 101 | ||
154 | return __ns9xxx_gpio_configure(gpio, 1, 0, 3); | 102 | spin_lock_irqsave(&gpio_lock, flags); |
103 | #if defined(CONFIG_PROCESSOR_NS9360) | ||
104 | if (processor_is_ns9360()) | ||
105 | ret = __ns9360_gpio_configure(gpio, 1, 0, 3); | ||
106 | else | ||
107 | #endif | ||
108 | BUG(); | ||
109 | |||
110 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
111 | |||
112 | return ret; | ||
155 | } else | 113 | } else |
156 | return -EINVAL; | 114 | return -EINVAL; |
157 | } | 115 | } |
@@ -159,31 +117,28 @@ EXPORT_SYMBOL(gpio_direction_output); | |||
159 | 117 | ||
160 | int gpio_get_value(unsigned gpio) | 118 | int gpio_get_value(unsigned gpio) |
161 | { | 119 | { |
162 | void __iomem *stat = ns9xxx_gpio_get_gstataddr(gpio); | 120 | #if defined(CONFIG_PROCESSOR_NS9360) |
163 | int ret; | 121 | if (processor_is_ns9360()) |
164 | 122 | return ns9360_gpio_get_value(gpio); | |
165 | ret = 1 & (__raw_readl(stat) >> (gpio & 31)); | 123 | else |
166 | 124 | #endif | |
167 | return ret; | 125 | { |
126 | BUG(); | ||
127 | return -EINVAL; | ||
128 | } | ||
168 | } | 129 | } |
169 | EXPORT_SYMBOL(gpio_get_value); | 130 | EXPORT_SYMBOL(gpio_get_value); |
170 | 131 | ||
171 | void gpio_set_value(unsigned gpio, int value) | 132 | void gpio_set_value(unsigned gpio, int value) |
172 | { | 133 | { |
173 | void __iomem *ctrl = ns9xxx_gpio_get_gctrladdr(gpio); | ||
174 | u32 ctrlval; | ||
175 | unsigned long flags; | 134 | unsigned long flags; |
176 | |||
177 | spin_lock_irqsave(&gpio_lock, flags); | 135 | spin_lock_irqsave(&gpio_lock, flags); |
178 | 136 | #if defined(CONFIG_PROCESSOR_NS9360) | |
179 | ctrlval = __raw_readl(ctrl); | 137 | if (processor_is_ns9360()) |
180 | 138 | ns9360_gpio_set_value(gpio, value); | |
181 | if (value) | ||
182 | ctrlval |= 1 << (gpio & 31); | ||
183 | else | 139 | else |
184 | ctrlval &= ~(1 << (gpio & 31)); | 140 | #endif |
185 | 141 | BUG(); | |
186 | __raw_writel(ctrlval, ctrl); | ||
187 | 142 | ||
188 | spin_unlock_irqrestore(&gpio_lock, flags); | 143 | spin_unlock_irqrestore(&gpio_lock, flags); |
189 | } | 144 | } |