diff options
Diffstat (limited to 'arch/arm/plat-nomadik/gpio.c')
-rw-r--r-- | arch/arm/plat-nomadik/gpio.c | 316 |
1 files changed, 262 insertions, 54 deletions
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 5a6ef252c38b..977c8f9a07a2 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | 25 | ||
26 | #include <plat/pincfg.h> | ||
26 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
27 | #include <mach/gpio.h> | 28 | #include <mach/gpio.h> |
28 | 29 | ||
@@ -46,28 +47,217 @@ struct nmk_gpio_chip { | |||
46 | u32 edge_falling; | 47 | u32 edge_falling; |
47 | }; | 48 | }; |
48 | 49 | ||
50 | static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip, | ||
51 | unsigned offset, int gpio_mode) | ||
52 | { | ||
53 | u32 bit = 1 << offset; | ||
54 | u32 afunc, bfunc; | ||
55 | |||
56 | afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit; | ||
57 | bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit; | ||
58 | if (gpio_mode & NMK_GPIO_ALT_A) | ||
59 | afunc |= bit; | ||
60 | if (gpio_mode & NMK_GPIO_ALT_B) | ||
61 | bfunc |= bit; | ||
62 | writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA); | ||
63 | writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB); | ||
64 | } | ||
65 | |||
66 | static void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip, | ||
67 | unsigned offset, enum nmk_gpio_slpm mode) | ||
68 | { | ||
69 | u32 bit = 1 << offset; | ||
70 | u32 slpm; | ||
71 | |||
72 | slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC); | ||
73 | if (mode == NMK_GPIO_SLPM_NOCHANGE) | ||
74 | slpm |= bit; | ||
75 | else | ||
76 | slpm &= ~bit; | ||
77 | writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC); | ||
78 | } | ||
79 | |||
80 | static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip, | ||
81 | unsigned offset, enum nmk_gpio_pull pull) | ||
82 | { | ||
83 | u32 bit = 1 << offset; | ||
84 | u32 pdis; | ||
85 | |||
86 | pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS); | ||
87 | if (pull == NMK_GPIO_PULL_NONE) | ||
88 | pdis |= bit; | ||
89 | else | ||
90 | pdis &= ~bit; | ||
91 | writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS); | ||
92 | |||
93 | if (pull == NMK_GPIO_PULL_UP) | ||
94 | writel(bit, nmk_chip->addr + NMK_GPIO_DATS); | ||
95 | else if (pull == NMK_GPIO_PULL_DOWN) | ||
96 | writel(bit, nmk_chip->addr + NMK_GPIO_DATC); | ||
97 | } | ||
98 | |||
99 | static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip, | ||
100 | unsigned offset) | ||
101 | { | ||
102 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC); | ||
103 | } | ||
104 | |||
105 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | ||
106 | pin_cfg_t cfg) | ||
107 | { | ||
108 | static const char *afnames[] = { | ||
109 | [NMK_GPIO_ALT_GPIO] = "GPIO", | ||
110 | [NMK_GPIO_ALT_A] = "A", | ||
111 | [NMK_GPIO_ALT_B] = "B", | ||
112 | [NMK_GPIO_ALT_C] = "C" | ||
113 | }; | ||
114 | static const char *pullnames[] = { | ||
115 | [NMK_GPIO_PULL_NONE] = "none", | ||
116 | [NMK_GPIO_PULL_UP] = "up", | ||
117 | [NMK_GPIO_PULL_DOWN] = "down", | ||
118 | [3] /* illegal */ = "??" | ||
119 | }; | ||
120 | static const char *slpmnames[] = { | ||
121 | [NMK_GPIO_SLPM_INPUT] = "input", | ||
122 | [NMK_GPIO_SLPM_NOCHANGE] = "no-change", | ||
123 | }; | ||
124 | |||
125 | int pin = PIN_NUM(cfg); | ||
126 | int pull = PIN_PULL(cfg); | ||
127 | int af = PIN_ALT(cfg); | ||
128 | int slpm = PIN_SLPM(cfg); | ||
129 | |||
130 | dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s\n", | ||
131 | pin, afnames[af], pullnames[pull], slpmnames[slpm]); | ||
132 | |||
133 | __nmk_gpio_make_input(nmk_chip, offset); | ||
134 | __nmk_gpio_set_pull(nmk_chip, offset, pull); | ||
135 | __nmk_gpio_set_slpm(nmk_chip, offset, slpm); | ||
136 | __nmk_gpio_set_mode(nmk_chip, offset, af); | ||
137 | } | ||
138 | |||
139 | /** | ||
140 | * nmk_config_pin - configure a pin's mux attributes | ||
141 | * @cfg: pin confguration | ||
142 | * | ||
143 | * Configures a pin's mode (alternate function or GPIO), its pull up status, | ||
144 | * and its sleep mode based on the specified configuration. The @cfg is | ||
145 | * usually one of the SoC specific macros defined in mach/<soc>-pins.h. These | ||
146 | * are constructed using, and can be further enhanced with, the macros in | ||
147 | * plat/pincfg.h. | ||
148 | * | ||
149 | * If a pin's mode is set to GPIO, it is configured as an input to avoid | ||
150 | * side-effects. The gpio can be manipulated later using standard GPIO API | ||
151 | * calls. | ||
152 | */ | ||
153 | int nmk_config_pin(pin_cfg_t cfg) | ||
154 | { | ||
155 | struct nmk_gpio_chip *nmk_chip; | ||
156 | int gpio = PIN_NUM(cfg); | ||
157 | unsigned long flags; | ||
158 | |||
159 | nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); | ||
160 | if (!nmk_chip) | ||
161 | return -EINVAL; | ||
162 | |||
163 | spin_lock_irqsave(&nmk_chip->lock, flags); | ||
164 | __nmk_config_pin(nmk_chip, gpio - nmk_chip->chip.base, cfg); | ||
165 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | EXPORT_SYMBOL(nmk_config_pin); | ||
170 | |||
171 | /** | ||
172 | * nmk_config_pins - configure several pins at once | ||
173 | * @cfgs: array of pin configurations | ||
174 | * @num: number of elments in the array | ||
175 | * | ||
176 | * Configures several pins using nmk_config_pin(). Refer to that function for | ||
177 | * further information. | ||
178 | */ | ||
179 | int nmk_config_pins(pin_cfg_t *cfgs, int num) | ||
180 | { | ||
181 | int ret = 0; | ||
182 | int i; | ||
183 | |||
184 | for (i = 0; i < num; i++) { | ||
185 | int ret = nmk_config_pin(cfgs[i]); | ||
186 | if (ret) | ||
187 | break; | ||
188 | } | ||
189 | |||
190 | return ret; | ||
191 | } | ||
192 | EXPORT_SYMBOL(nmk_config_pins); | ||
193 | |||
194 | /** | ||
195 | * nmk_gpio_set_slpm() - configure the sleep mode of a pin | ||
196 | * @gpio: pin number | ||
197 | * @mode: NMK_GPIO_SLPM_INPUT or NMK_GPIO_SLPM_NOCHANGE, | ||
198 | * | ||
199 | * Sets the sleep mode of a pin. If @mode is NMK_GPIO_SLPM_INPUT, the pin is | ||
200 | * changed to an input (with pullup/down enabled) in sleep and deep sleep. If | ||
201 | * @mode is NMK_GPIO_SLPM_NOCHANGE, the pin remains in the state it was | ||
202 | * configured even when in sleep and deep sleep. | ||
203 | */ | ||
204 | int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode) | ||
205 | { | ||
206 | struct nmk_gpio_chip *nmk_chip; | ||
207 | unsigned long flags; | ||
208 | |||
209 | nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); | ||
210 | if (!nmk_chip) | ||
211 | return -EINVAL; | ||
212 | |||
213 | spin_lock_irqsave(&nmk_chip->lock, flags); | ||
214 | __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base, mode); | ||
215 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | ||
216 | |||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | /** | ||
221 | * nmk_gpio_set_pull() - enable/disable pull up/down on a gpio | ||
222 | * @gpio: pin number | ||
223 | * @pull: one of NMK_GPIO_PULL_DOWN, NMK_GPIO_PULL_UP, and NMK_GPIO_PULL_NONE | ||
224 | * | ||
225 | * Enables/disables pull up/down on a specified pin. This only takes effect if | ||
226 | * the pin is configured as an input (either explicitly or by the alternate | ||
227 | * function). | ||
228 | * | ||
229 | * NOTE: If enabling the pull up/down, the caller must ensure that the GPIO is | ||
230 | * configured as an input. Otherwise, due to the way the controller registers | ||
231 | * work, this function will change the value output on the pin. | ||
232 | */ | ||
233 | int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull) | ||
234 | { | ||
235 | struct nmk_gpio_chip *nmk_chip; | ||
236 | unsigned long flags; | ||
237 | |||
238 | nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); | ||
239 | if (!nmk_chip) | ||
240 | return -EINVAL; | ||
241 | |||
242 | spin_lock_irqsave(&nmk_chip->lock, flags); | ||
243 | __nmk_gpio_set_pull(nmk_chip, gpio - nmk_chip->chip.base, pull); | ||
244 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
49 | /* Mode functions */ | 249 | /* Mode functions */ |
50 | int nmk_gpio_set_mode(int gpio, int gpio_mode) | 250 | int nmk_gpio_set_mode(int gpio, int gpio_mode) |
51 | { | 251 | { |
52 | struct nmk_gpio_chip *nmk_chip; | 252 | struct nmk_gpio_chip *nmk_chip; |
53 | unsigned long flags; | 253 | unsigned long flags; |
54 | u32 afunc, bfunc, bit; | ||
55 | 254 | ||
56 | nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); | 255 | nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); |
57 | if (!nmk_chip) | 256 | if (!nmk_chip) |
58 | return -EINVAL; | 257 | return -EINVAL; |
59 | 258 | ||
60 | bit = 1 << (gpio - nmk_chip->chip.base); | ||
61 | |||
62 | spin_lock_irqsave(&nmk_chip->lock, flags); | 259 | spin_lock_irqsave(&nmk_chip->lock, flags); |
63 | afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit; | 260 | __nmk_gpio_set_mode(nmk_chip, gpio - nmk_chip->chip.base, gpio_mode); |
64 | bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit; | ||
65 | if (gpio_mode & NMK_GPIO_ALT_A) | ||
66 | afunc |= bit; | ||
67 | if (gpio_mode & NMK_GPIO_ALT_B) | ||
68 | bfunc |= bit; | ||
69 | writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA); | ||
70 | writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB); | ||
71 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | 261 | spin_unlock_irqrestore(&nmk_chip->lock, flags); |
72 | 262 | ||
73 | return 0; | 263 | return 0; |
@@ -111,32 +301,41 @@ static void nmk_gpio_irq_ack(unsigned int irq) | |||
111 | writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC); | 301 | writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC); |
112 | } | 302 | } |
113 | 303 | ||
304 | enum nmk_gpio_irq_type { | ||
305 | NORMAL, | ||
306 | WAKE, | ||
307 | }; | ||
308 | |||
114 | static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip, | 309 | static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip, |
115 | int gpio, bool enable) | 310 | int gpio, enum nmk_gpio_irq_type which, |
311 | bool enable) | ||
116 | { | 312 | { |
313 | u32 rimsc = which == WAKE ? NMK_GPIO_RWIMSC : NMK_GPIO_RIMSC; | ||
314 | u32 fimsc = which == WAKE ? NMK_GPIO_FWIMSC : NMK_GPIO_FIMSC; | ||
117 | u32 bitmask = nmk_gpio_get_bitmask(gpio); | 315 | u32 bitmask = nmk_gpio_get_bitmask(gpio); |
118 | u32 reg; | 316 | u32 reg; |
119 | 317 | ||
120 | /* we must individually set/clear the two edges */ | 318 | /* we must individually set/clear the two edges */ |
121 | if (nmk_chip->edge_rising & bitmask) { | 319 | if (nmk_chip->edge_rising & bitmask) { |
122 | reg = readl(nmk_chip->addr + NMK_GPIO_RIMSC); | 320 | reg = readl(nmk_chip->addr + rimsc); |
123 | if (enable) | 321 | if (enable) |
124 | reg |= bitmask; | 322 | reg |= bitmask; |
125 | else | 323 | else |
126 | reg &= ~bitmask; | 324 | reg &= ~bitmask; |
127 | writel(reg, nmk_chip->addr + NMK_GPIO_RIMSC); | 325 | writel(reg, nmk_chip->addr + rimsc); |
128 | } | 326 | } |
129 | if (nmk_chip->edge_falling & bitmask) { | 327 | if (nmk_chip->edge_falling & bitmask) { |
130 | reg = readl(nmk_chip->addr + NMK_GPIO_FIMSC); | 328 | reg = readl(nmk_chip->addr + fimsc); |
131 | if (enable) | 329 | if (enable) |
132 | reg |= bitmask; | 330 | reg |= bitmask; |
133 | else | 331 | else |
134 | reg &= ~bitmask; | 332 | reg &= ~bitmask; |
135 | writel(reg, nmk_chip->addr + NMK_GPIO_FIMSC); | 333 | writel(reg, nmk_chip->addr + fimsc); |
136 | } | 334 | } |
137 | } | 335 | } |
138 | 336 | ||
139 | static void nmk_gpio_irq_modify(unsigned int irq, bool enable) | 337 | static int nmk_gpio_irq_modify(unsigned int irq, enum nmk_gpio_irq_type which, |
338 | bool enable) | ||
140 | { | 339 | { |
141 | int gpio; | 340 | int gpio; |
142 | struct nmk_gpio_chip *nmk_chip; | 341 | struct nmk_gpio_chip *nmk_chip; |
@@ -147,26 +346,35 @@ static void nmk_gpio_irq_modify(unsigned int irq, bool enable) | |||
147 | nmk_chip = get_irq_chip_data(irq); | 346 | nmk_chip = get_irq_chip_data(irq); |
148 | bitmask = nmk_gpio_get_bitmask(gpio); | 347 | bitmask = nmk_gpio_get_bitmask(gpio); |
149 | if (!nmk_chip) | 348 | if (!nmk_chip) |
150 | return; | 349 | return -EINVAL; |
151 | 350 | ||
152 | spin_lock_irqsave(&nmk_chip->lock, flags); | 351 | spin_lock_irqsave(&nmk_chip->lock, flags); |
153 | __nmk_gpio_irq_modify(nmk_chip, gpio, enable); | 352 | __nmk_gpio_irq_modify(nmk_chip, gpio, which, enable); |
154 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | 353 | spin_unlock_irqrestore(&nmk_chip->lock, flags); |
354 | |||
355 | return 0; | ||
155 | } | 356 | } |
156 | 357 | ||
157 | static void nmk_gpio_irq_mask(unsigned int irq) | 358 | static void nmk_gpio_irq_mask(unsigned int irq) |
158 | { | 359 | { |
159 | nmk_gpio_irq_modify(irq, false); | 360 | nmk_gpio_irq_modify(irq, NORMAL, false); |
160 | }; | 361 | } |
161 | 362 | ||
162 | static void nmk_gpio_irq_unmask(unsigned int irq) | 363 | static void nmk_gpio_irq_unmask(unsigned int irq) |
163 | { | 364 | { |
164 | nmk_gpio_irq_modify(irq, true); | 365 | nmk_gpio_irq_modify(irq, NORMAL, true); |
366 | } | ||
367 | |||
368 | static int nmk_gpio_irq_set_wake(unsigned int irq, unsigned int on) | ||
369 | { | ||
370 | return nmk_gpio_irq_modify(irq, WAKE, on); | ||
165 | } | 371 | } |
166 | 372 | ||
167 | static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) | 373 | static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) |
168 | { | 374 | { |
169 | bool enabled = !(irq_to_desc(irq)->status & IRQ_DISABLED); | 375 | struct irq_desc *desc = irq_to_desc(irq); |
376 | bool enabled = !(desc->status & IRQ_DISABLED); | ||
377 | bool wake = desc->wake_depth; | ||
170 | int gpio; | 378 | int gpio; |
171 | struct nmk_gpio_chip *nmk_chip; | 379 | struct nmk_gpio_chip *nmk_chip; |
172 | unsigned long flags; | 380 | unsigned long flags; |
@@ -186,7 +394,10 @@ static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) | |||
186 | spin_lock_irqsave(&nmk_chip->lock, flags); | 394 | spin_lock_irqsave(&nmk_chip->lock, flags); |
187 | 395 | ||
188 | if (enabled) | 396 | if (enabled) |
189 | __nmk_gpio_irq_modify(nmk_chip, gpio, false); | 397 | __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, false); |
398 | |||
399 | if (wake) | ||
400 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, false); | ||
190 | 401 | ||
191 | nmk_chip->edge_rising &= ~bitmask; | 402 | nmk_chip->edge_rising &= ~bitmask; |
192 | if (type & IRQ_TYPE_EDGE_RISING) | 403 | if (type & IRQ_TYPE_EDGE_RISING) |
@@ -197,7 +408,10 @@ static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) | |||
197 | nmk_chip->edge_falling |= bitmask; | 408 | nmk_chip->edge_falling |= bitmask; |
198 | 409 | ||
199 | if (enabled) | 410 | if (enabled) |
200 | __nmk_gpio_irq_modify(nmk_chip, gpio, true); | 411 | __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, true); |
412 | |||
413 | if (wake) | ||
414 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, true); | ||
201 | 415 | ||
202 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | 416 | spin_unlock_irqrestore(&nmk_chip->lock, flags); |
203 | 417 | ||
@@ -210,6 +424,7 @@ static struct irq_chip nmk_gpio_irq_chip = { | |||
210 | .mask = nmk_gpio_irq_mask, | 424 | .mask = nmk_gpio_irq_mask, |
211 | .unmask = nmk_gpio_irq_unmask, | 425 | .unmask = nmk_gpio_irq_unmask, |
212 | .set_type = nmk_gpio_irq_set_type, | 426 | .set_type = nmk_gpio_irq_set_type, |
427 | .set_wake = nmk_gpio_irq_set_wake, | ||
213 | }; | 428 | }; |
214 | 429 | ||
215 | static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | 430 | static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) |
@@ -266,16 +481,6 @@ static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset) | |||
266 | return 0; | 481 | return 0; |
267 | } | 482 | } |
268 | 483 | ||
269 | static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, | ||
270 | int val) | ||
271 | { | ||
272 | struct nmk_gpio_chip *nmk_chip = | ||
273 | container_of(chip, struct nmk_gpio_chip, chip); | ||
274 | |||
275 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS); | ||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset) | 484 | static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset) |
280 | { | 485 | { |
281 | struct nmk_gpio_chip *nmk_chip = | 486 | struct nmk_gpio_chip *nmk_chip = |
@@ -298,12 +503,33 @@ static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset, | |||
298 | writel(bit, nmk_chip->addr + NMK_GPIO_DATC); | 503 | writel(bit, nmk_chip->addr + NMK_GPIO_DATC); |
299 | } | 504 | } |
300 | 505 | ||
506 | static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, | ||
507 | int val) | ||
508 | { | ||
509 | struct nmk_gpio_chip *nmk_chip = | ||
510 | container_of(chip, struct nmk_gpio_chip, chip); | ||
511 | |||
512 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS); | ||
513 | nmk_gpio_set_output(chip, offset, val); | ||
514 | |||
515 | return 0; | ||
516 | } | ||
517 | |||
518 | static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
519 | { | ||
520 | struct nmk_gpio_chip *nmk_chip = | ||
521 | container_of(chip, struct nmk_gpio_chip, chip); | ||
522 | |||
523 | return NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base) + offset; | ||
524 | } | ||
525 | |||
301 | /* This structure is replicated for each GPIO block allocated at probe time */ | 526 | /* This structure is replicated for each GPIO block allocated at probe time */ |
302 | static struct gpio_chip nmk_gpio_template = { | 527 | static struct gpio_chip nmk_gpio_template = { |
303 | .direction_input = nmk_gpio_make_input, | 528 | .direction_input = nmk_gpio_make_input, |
304 | .get = nmk_gpio_get_input, | 529 | .get = nmk_gpio_get_input, |
305 | .direction_output = nmk_gpio_make_output, | 530 | .direction_output = nmk_gpio_make_output, |
306 | .set = nmk_gpio_set_output, | 531 | .set = nmk_gpio_set_output, |
532 | .to_irq = nmk_gpio_to_irq, | ||
307 | .ngpio = NMK_GPIO_PER_CHIP, | 533 | .ngpio = NMK_GPIO_PER_CHIP, |
308 | .can_sleep = 0, | 534 | .can_sleep = 0, |
309 | }; | 535 | }; |
@@ -393,30 +619,12 @@ out: | |||
393 | return ret; | 619 | return ret; |
394 | } | 620 | } |
395 | 621 | ||
396 | static int __exit nmk_gpio_remove(struct platform_device *dev) | ||
397 | { | ||
398 | struct nmk_gpio_chip *nmk_chip; | ||
399 | struct resource *res; | ||
400 | |||
401 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
402 | |||
403 | nmk_chip = platform_get_drvdata(dev); | ||
404 | gpiochip_remove(&nmk_chip->chip); | ||
405 | clk_disable(nmk_chip->clk); | ||
406 | clk_put(nmk_chip->clk); | ||
407 | kfree(nmk_chip); | ||
408 | release_mem_region(res->start, resource_size(res)); | ||
409 | return 0; | ||
410 | } | ||
411 | |||
412 | |||
413 | static struct platform_driver nmk_gpio_driver = { | 622 | static struct platform_driver nmk_gpio_driver = { |
414 | .driver = { | 623 | .driver = { |
415 | .owner = THIS_MODULE, | 624 | .owner = THIS_MODULE, |
416 | .name = "gpio", | 625 | .name = "gpio", |
417 | }, | 626 | }, |
418 | .probe = nmk_gpio_probe, | 627 | .probe = nmk_gpio_probe, |
419 | .remove = __exit_p(nmk_gpio_remove), | ||
420 | .suspend = NULL, /* to be done */ | 628 | .suspend = NULL, /* to be done */ |
421 | .resume = NULL, | 629 | .resume = NULL, |
422 | }; | 630 | }; |
@@ -426,7 +634,7 @@ static int __init nmk_gpio_init(void) | |||
426 | return platform_driver_register(&nmk_gpio_driver); | 634 | return platform_driver_register(&nmk_gpio_driver); |
427 | } | 635 | } |
428 | 636 | ||
429 | arch_initcall(nmk_gpio_init); | 637 | core_initcall(nmk_gpio_init); |
430 | 638 | ||
431 | MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini"); | 639 | MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini"); |
432 | MODULE_DESCRIPTION("Nomadik GPIO Driver"); | 640 | MODULE_DESCRIPTION("Nomadik GPIO Driver"); |