diff options
Diffstat (limited to 'arch/sh/kernel/gpio.c')
-rw-r--r-- | arch/sh/kernel/gpio.c | 338 |
1 files changed, 210 insertions, 128 deletions
diff --git a/arch/sh/kernel/gpio.c b/arch/sh/kernel/gpio.c index d37165361034..d22e5af699f9 100644 --- a/arch/sh/kernel/gpio.c +++ b/arch/sh/kernel/gpio.c | |||
@@ -19,36 +19,75 @@ | |||
19 | #include <linux/bitops.h> | 19 | #include <linux/bitops.h> |
20 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
21 | 21 | ||
22 | static struct pinmux_info *registered_gpio; | 22 | static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) |
23 | { | ||
24 | if (enum_id < r->begin) | ||
25 | return 0; | ||
23 | 26 | ||
24 | static struct pinmux_info *gpio_controller(unsigned gpio) | 27 | if (enum_id > r->end) |
28 | return 0; | ||
29 | |||
30 | return 1; | ||
31 | } | ||
32 | |||
33 | static unsigned long gpio_read_raw_reg(unsigned long reg, | ||
34 | unsigned long reg_width) | ||
25 | { | 35 | { |
26 | if (!registered_gpio) | 36 | switch (reg_width) { |
27 | return NULL; | 37 | case 8: |
38 | return ctrl_inb(reg); | ||
39 | case 16: | ||
40 | return ctrl_inw(reg); | ||
41 | case 32: | ||
42 | return ctrl_inl(reg); | ||
43 | } | ||
28 | 44 | ||
29 | if (gpio < registered_gpio->first_gpio) | 45 | BUG(); |
30 | return NULL; | 46 | return 0; |
47 | } | ||
31 | 48 | ||
32 | if (gpio > registered_gpio->last_gpio) | 49 | static void gpio_write_raw_reg(unsigned long reg, |
33 | return NULL; | 50 | unsigned long reg_width, |
51 | unsigned long data) | ||
52 | { | ||
53 | switch (reg_width) { | ||
54 | case 8: | ||
55 | ctrl_outb(data, reg); | ||
56 | return; | ||
57 | case 16: | ||
58 | ctrl_outw(data, reg); | ||
59 | return; | ||
60 | case 32: | ||
61 | ctrl_outl(data, reg); | ||
62 | return; | ||
63 | } | ||
34 | 64 | ||
35 | return registered_gpio; | 65 | BUG(); |
36 | } | 66 | } |
37 | 67 | ||
38 | static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) | 68 | static void gpio_write_bit(struct pinmux_data_reg *dr, |
69 | unsigned long in_pos, unsigned long value) | ||
39 | { | 70 | { |
40 | if (enum_id < r->begin) | 71 | unsigned long pos; |
41 | return 0; | ||
42 | 72 | ||
43 | if (enum_id > r->end) | 73 | pos = dr->reg_width - (in_pos + 1); |
44 | return 0; | ||
45 | 74 | ||
46 | return 1; | 75 | #ifdef DEBUG |
76 | pr_info("write_bit addr = %lx, value = %ld, pos = %ld, " | ||
77 | "r_width = %ld\n", | ||
78 | dr->reg, !!value, pos, dr->reg_width); | ||
79 | #endif | ||
80 | |||
81 | if (value) | ||
82 | set_bit(pos, &dr->reg_shadow); | ||
83 | else | ||
84 | clear_bit(pos, &dr->reg_shadow); | ||
85 | |||
86 | gpio_write_raw_reg(dr->reg, dr->reg_width, dr->reg_shadow); | ||
47 | } | 87 | } |
48 | 88 | ||
49 | static int read_write_reg(unsigned long reg, unsigned long reg_width, | 89 | static int gpio_read_reg(unsigned long reg, unsigned long reg_width, |
50 | unsigned long field_width, unsigned long in_pos, | 90 | unsigned long field_width, unsigned long in_pos) |
51 | unsigned long value, int do_write) | ||
52 | { | 91 | { |
53 | unsigned long data, mask, pos; | 92 | unsigned long data, mask, pos; |
54 | 93 | ||
@@ -57,52 +96,53 @@ static int read_write_reg(unsigned long reg, unsigned long reg_width, | |||
57 | pos = reg_width - ((in_pos + 1) * field_width); | 96 | pos = reg_width - ((in_pos + 1) * field_width); |
58 | 97 | ||
59 | #ifdef DEBUG | 98 | #ifdef DEBUG |
60 | pr_info("%s, addr = %lx, value = %ld, pos = %ld, " | 99 | pr_info("read_reg: addr = %lx, pos = %ld, " |
61 | "r_width = %ld, f_width = %ld\n", | 100 | "r_width = %ld, f_width = %ld\n", |
62 | do_write ? "write" : "read", reg, value, pos, | 101 | reg, pos, reg_width, field_width); |
63 | reg_width, field_width); | ||
64 | #endif | 102 | #endif |
65 | 103 | ||
66 | switch (reg_width) { | 104 | data = gpio_read_raw_reg(reg, reg_width); |
67 | case 8: | 105 | return (data >> pos) & mask; |
68 | data = ctrl_inb(reg); | 106 | } |
69 | break; | ||
70 | case 16: | ||
71 | data = ctrl_inw(reg); | ||
72 | break; | ||
73 | case 32: | ||
74 | data = ctrl_inl(reg); | ||
75 | break; | ||
76 | } | ||
77 | 107 | ||
78 | if (!do_write) | 108 | static void gpio_write_reg(unsigned long reg, unsigned long reg_width, |
79 | return (data >> pos) & mask; | 109 | unsigned long field_width, unsigned long in_pos, |
110 | unsigned long value) | ||
111 | { | ||
112 | unsigned long mask, pos; | ||
80 | 113 | ||
81 | data &= ~(mask << pos); | 114 | mask = (1 << field_width) - 1; |
82 | data |= value << pos; | 115 | pos = reg_width - ((in_pos + 1) * field_width); |
116 | |||
117 | #ifdef DEBUG | ||
118 | pr_info("write_reg addr = %lx, value = %ld, pos = %ld, " | ||
119 | "r_width = %ld, f_width = %ld\n", | ||
120 | reg, value, pos, reg_width, field_width); | ||
121 | #endif | ||
122 | |||
123 | mask = ~(mask << pos); | ||
124 | value = value << pos; | ||
83 | 125 | ||
84 | switch (reg_width) { | 126 | switch (reg_width) { |
85 | case 8: | 127 | case 8: |
86 | ctrl_outb(data, reg); | 128 | ctrl_outb((ctrl_inb(reg) & mask) | value, reg); |
87 | break; | 129 | break; |
88 | case 16: | 130 | case 16: |
89 | ctrl_outw(data, reg); | 131 | ctrl_outw((ctrl_inw(reg) & mask) | value, reg); |
90 | break; | 132 | break; |
91 | case 32: | 133 | case 32: |
92 | ctrl_outl(data, reg); | 134 | ctrl_outl((ctrl_inl(reg) & mask) | value, reg); |
93 | break; | 135 | break; |
94 | } | 136 | } |
95 | return 0; | ||
96 | } | 137 | } |
97 | 138 | ||
98 | static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio, | 139 | static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio) |
99 | struct pinmux_data_reg **drp, int *bitp) | ||
100 | { | 140 | { |
101 | pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id; | 141 | struct pinmux_gpio *gpiop = &gpioc->gpios[gpio]; |
102 | struct pinmux_data_reg *data_reg; | 142 | struct pinmux_data_reg *data_reg; |
103 | int k, n; | 143 | int k, n; |
104 | 144 | ||
105 | if (!enum_in_range(enum_id, &gpioc->data)) | 145 | if (!enum_in_range(gpiop->enum_id, &gpioc->data)) |
106 | return -1; | 146 | return -1; |
107 | 147 | ||
108 | k = 0; | 148 | k = 0; |
@@ -113,19 +153,58 @@ static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio, | |||
113 | break; | 153 | break; |
114 | 154 | ||
115 | for (n = 0; n < data_reg->reg_width; n++) { | 155 | for (n = 0; n < data_reg->reg_width; n++) { |
116 | if (data_reg->enum_ids[n] == enum_id) { | 156 | if (data_reg->enum_ids[n] == gpiop->enum_id) { |
117 | *drp = data_reg; | 157 | gpiop->flags &= ~PINMUX_FLAG_DREG; |
118 | *bitp = n; | 158 | gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT); |
159 | gpiop->flags &= ~PINMUX_FLAG_DBIT; | ||
160 | gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT); | ||
119 | return 0; | 161 | return 0; |
120 | |||
121 | } | 162 | } |
122 | } | 163 | } |
123 | k++; | 164 | k++; |
124 | } | 165 | } |
125 | 166 | ||
167 | BUG(); | ||
168 | |||
126 | return -1; | 169 | return -1; |
127 | } | 170 | } |
128 | 171 | ||
172 | static void setup_data_regs(struct pinmux_info *gpioc) | ||
173 | { | ||
174 | struct pinmux_data_reg *drp; | ||
175 | int k; | ||
176 | |||
177 | for (k = gpioc->first_gpio; k <= gpioc->last_gpio; k++) | ||
178 | setup_data_reg(gpioc, k); | ||
179 | |||
180 | k = 0; | ||
181 | while (1) { | ||
182 | drp = gpioc->data_regs + k; | ||
183 | |||
184 | if (!drp->reg_width) | ||
185 | break; | ||
186 | |||
187 | drp->reg_shadow = gpio_read_raw_reg(drp->reg, drp->reg_width); | ||
188 | k++; | ||
189 | } | ||
190 | } | ||
191 | |||
192 | static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio, | ||
193 | struct pinmux_data_reg **drp, int *bitp) | ||
194 | { | ||
195 | struct pinmux_gpio *gpiop = &gpioc->gpios[gpio]; | ||
196 | int k, n; | ||
197 | |||
198 | if (!enum_in_range(gpiop->enum_id, &gpioc->data)) | ||
199 | return -1; | ||
200 | |||
201 | k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT; | ||
202 | n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT; | ||
203 | *drp = gpioc->data_regs + k; | ||
204 | *bitp = n; | ||
205 | return 0; | ||
206 | } | ||
207 | |||
129 | static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id, | 208 | static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id, |
130 | struct pinmux_cfg_reg **crp, int *indexp, | 209 | struct pinmux_cfg_reg **crp, int *indexp, |
131 | unsigned long **cntp) | 210 | unsigned long **cntp) |
@@ -187,9 +266,9 @@ static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio, | |||
187 | return -1; | 266 | return -1; |
188 | } | 267 | } |
189 | 268 | ||
190 | static int write_config_reg(struct pinmux_info *gpioc, | 269 | static void write_config_reg(struct pinmux_info *gpioc, |
191 | struct pinmux_cfg_reg *crp, | 270 | struct pinmux_cfg_reg *crp, |
192 | int index) | 271 | int index) |
193 | { | 272 | { |
194 | unsigned long ncomb, pos, value; | 273 | unsigned long ncomb, pos, value; |
195 | 274 | ||
@@ -197,8 +276,7 @@ static int write_config_reg(struct pinmux_info *gpioc, | |||
197 | pos = index / ncomb; | 276 | pos = index / ncomb; |
198 | value = index % ncomb; | 277 | value = index % ncomb; |
199 | 278 | ||
200 | return read_write_reg(crp->reg, crp->reg_width, | 279 | gpio_write_reg(crp->reg, crp->reg_width, crp->field_width, pos, value); |
201 | crp->field_width, pos, value, 1); | ||
202 | } | 280 | } |
203 | 281 | ||
204 | static int check_config_reg(struct pinmux_info *gpioc, | 282 | static int check_config_reg(struct pinmux_info *gpioc, |
@@ -211,8 +289,8 @@ static int check_config_reg(struct pinmux_info *gpioc, | |||
211 | pos = index / ncomb; | 289 | pos = index / ncomb; |
212 | value = index % ncomb; | 290 | value = index % ncomb; |
213 | 291 | ||
214 | if (read_write_reg(crp->reg, crp->reg_width, | 292 | if (gpio_read_reg(crp->reg, crp->reg_width, |
215 | crp->field_width, pos, 0, 0) == value) | 293 | crp->field_width, pos) == value) |
216 | return 0; | 294 | return 0; |
217 | 295 | ||
218 | return -1; | 296 | return -1; |
@@ -220,8 +298,8 @@ static int check_config_reg(struct pinmux_info *gpioc, | |||
220 | 298 | ||
221 | enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE }; | 299 | enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE }; |
222 | 300 | ||
223 | int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio, | 301 | static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio, |
224 | int pinmux_type, int cfg_mode) | 302 | int pinmux_type, int cfg_mode) |
225 | { | 303 | { |
226 | struct pinmux_cfg_reg *cr = NULL; | 304 | struct pinmux_cfg_reg *cr = NULL; |
227 | pinmux_enum_t enum_id; | 305 | pinmux_enum_t enum_id; |
@@ -287,8 +365,7 @@ int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio, | |||
287 | break; | 365 | break; |
288 | 366 | ||
289 | case GPIO_CFG_REQ: | 367 | case GPIO_CFG_REQ: |
290 | if (write_config_reg(gpioc, cr, index) != 0) | 368 | write_config_reg(gpioc, cr, index); |
291 | goto out_err; | ||
292 | *cntp = *cntp + 1; | 369 | *cntp = *cntp + 1; |
293 | break; | 370 | break; |
294 | 371 | ||
@@ -305,9 +382,14 @@ int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio, | |||
305 | 382 | ||
306 | static DEFINE_SPINLOCK(gpio_lock); | 383 | static DEFINE_SPINLOCK(gpio_lock); |
307 | 384 | ||
308 | int __gpio_request(unsigned gpio) | 385 | static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip) |
309 | { | 386 | { |
310 | struct pinmux_info *gpioc = gpio_controller(gpio); | 387 | return container_of(chip, struct pinmux_info, chip); |
388 | } | ||
389 | |||
390 | static int sh_gpio_request(struct gpio_chip *chip, unsigned offset) | ||
391 | { | ||
392 | struct pinmux_info *gpioc = chip_to_pinmux(chip); | ||
311 | struct pinmux_data_reg *dummy; | 393 | struct pinmux_data_reg *dummy; |
312 | unsigned long flags; | 394 | unsigned long flags; |
313 | int i, ret, pinmux_type; | 395 | int i, ret, pinmux_type; |
@@ -319,29 +401,30 @@ int __gpio_request(unsigned gpio) | |||
319 | 401 | ||
320 | spin_lock_irqsave(&gpio_lock, flags); | 402 | spin_lock_irqsave(&gpio_lock, flags); |
321 | 403 | ||
322 | if ((gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE) | 404 | if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE) |
323 | goto err_unlock; | 405 | goto err_unlock; |
324 | 406 | ||
325 | /* setup pin function here if no data is associated with pin */ | 407 | /* setup pin function here if no data is associated with pin */ |
326 | 408 | ||
327 | if (get_data_reg(gpioc, gpio, &dummy, &i) != 0) | 409 | if (get_data_reg(gpioc, offset, &dummy, &i) != 0) |
328 | pinmux_type = PINMUX_TYPE_FUNCTION; | 410 | pinmux_type = PINMUX_TYPE_FUNCTION; |
329 | else | 411 | else |
330 | pinmux_type = PINMUX_TYPE_GPIO; | 412 | pinmux_type = PINMUX_TYPE_GPIO; |
331 | 413 | ||
332 | if (pinmux_type == PINMUX_TYPE_FUNCTION) { | 414 | if (pinmux_type == PINMUX_TYPE_FUNCTION) { |
333 | if (pinmux_config_gpio(gpioc, gpio, | 415 | if (pinmux_config_gpio(gpioc, offset, |
334 | pinmux_type, | 416 | pinmux_type, |
335 | GPIO_CFG_DRYRUN) != 0) | 417 | GPIO_CFG_DRYRUN) != 0) |
336 | goto err_unlock; | 418 | goto err_unlock; |
337 | 419 | ||
338 | if (pinmux_config_gpio(gpioc, gpio, | 420 | if (pinmux_config_gpio(gpioc, offset, |
339 | pinmux_type, | 421 | pinmux_type, |
340 | GPIO_CFG_REQ) != 0) | 422 | GPIO_CFG_REQ) != 0) |
341 | BUG(); | 423 | BUG(); |
342 | } | 424 | } |
343 | 425 | ||
344 | gpioc->gpios[gpio].flags = pinmux_type; | 426 | gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE; |
427 | gpioc->gpios[offset].flags |= pinmux_type; | ||
345 | 428 | ||
346 | ret = 0; | 429 | ret = 0; |
347 | err_unlock: | 430 | err_unlock: |
@@ -349,11 +432,10 @@ int __gpio_request(unsigned gpio) | |||
349 | err_out: | 432 | err_out: |
350 | return ret; | 433 | return ret; |
351 | } | 434 | } |
352 | EXPORT_SYMBOL(__gpio_request); | ||
353 | 435 | ||
354 | void gpio_free(unsigned gpio) | 436 | static void sh_gpio_free(struct gpio_chip *chip, unsigned offset) |
355 | { | 437 | { |
356 | struct pinmux_info *gpioc = gpio_controller(gpio); | 438 | struct pinmux_info *gpioc = chip_to_pinmux(chip); |
357 | unsigned long flags; | 439 | unsigned long flags; |
358 | int pinmux_type; | 440 | int pinmux_type; |
359 | 441 | ||
@@ -362,20 +444,23 @@ void gpio_free(unsigned gpio) | |||
362 | 444 | ||
363 | spin_lock_irqsave(&gpio_lock, flags); | 445 | spin_lock_irqsave(&gpio_lock, flags); |
364 | 446 | ||
365 | pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE; | 447 | pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE; |
366 | pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE); | 448 | pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE); |
367 | gpioc->gpios[gpio].flags = PINMUX_TYPE_NONE; | 449 | gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE; |
450 | gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE; | ||
368 | 451 | ||
369 | spin_unlock_irqrestore(&gpio_lock, flags); | 452 | spin_unlock_irqrestore(&gpio_lock, flags); |
370 | } | 453 | } |
371 | EXPORT_SYMBOL(gpio_free); | ||
372 | 454 | ||
373 | static int pinmux_direction(struct pinmux_info *gpioc, | 455 | static int pinmux_direction(struct pinmux_info *gpioc, |
374 | unsigned gpio, int new_pinmux_type) | 456 | unsigned gpio, int new_pinmux_type) |
375 | { | 457 | { |
376 | int ret, pinmux_type; | 458 | int pinmux_type; |
459 | int ret = -EINVAL; | ||
460 | |||
461 | if (!gpioc) | ||
462 | goto err_out; | ||
377 | 463 | ||
378 | ret = -EINVAL; | ||
379 | pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE; | 464 | pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE; |
380 | 465 | ||
381 | switch (pinmux_type) { | 466 | switch (pinmux_type) { |
@@ -401,102 +486,99 @@ static int pinmux_direction(struct pinmux_info *gpioc, | |||
401 | GPIO_CFG_REQ) != 0) | 486 | GPIO_CFG_REQ) != 0) |
402 | BUG(); | 487 | BUG(); |
403 | 488 | ||
404 | gpioc->gpios[gpio].flags = new_pinmux_type; | 489 | gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE; |
490 | gpioc->gpios[gpio].flags |= new_pinmux_type; | ||
405 | 491 | ||
406 | ret = 0; | 492 | ret = 0; |
407 | err_out: | 493 | err_out: |
408 | return ret; | 494 | return ret; |
409 | } | 495 | } |
410 | 496 | ||
411 | int gpio_direction_input(unsigned gpio) | 497 | static int sh_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
412 | { | 498 | { |
413 | struct pinmux_info *gpioc = gpio_controller(gpio); | 499 | struct pinmux_info *gpioc = chip_to_pinmux(chip); |
414 | unsigned long flags; | 500 | unsigned long flags; |
415 | int ret = -EINVAL; | 501 | int ret; |
416 | |||
417 | if (!gpioc) | ||
418 | goto err_out; | ||
419 | 502 | ||
420 | spin_lock_irqsave(&gpio_lock, flags); | 503 | spin_lock_irqsave(&gpio_lock, flags); |
421 | ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_INPUT); | 504 | ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT); |
422 | spin_unlock_irqrestore(&gpio_lock, flags); | 505 | spin_unlock_irqrestore(&gpio_lock, flags); |
423 | err_out: | 506 | |
424 | return ret; | 507 | return ret; |
425 | } | 508 | } |
426 | EXPORT_SYMBOL(gpio_direction_input); | ||
427 | 509 | ||
428 | static int __gpio_get_set_value(struct pinmux_info *gpioc, | 510 | static void sh_gpio_set_value(struct pinmux_info *gpioc, |
429 | unsigned gpio, int value, | 511 | unsigned gpio, int value) |
430 | int do_write) | ||
431 | { | 512 | { |
432 | struct pinmux_data_reg *dr = NULL; | 513 | struct pinmux_data_reg *dr = NULL; |
433 | int bit = 0; | 514 | int bit = 0; |
434 | 515 | ||
435 | if (get_data_reg(gpioc, gpio, &dr, &bit) != 0) | 516 | if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) |
436 | BUG(); | 517 | BUG(); |
437 | else | 518 | else |
438 | value = read_write_reg(dr->reg, dr->reg_width, | 519 | gpio_write_bit(dr, bit, value); |
439 | 1, bit, !!value, do_write); | ||
440 | |||
441 | return value; | ||
442 | } | 520 | } |
443 | 521 | ||
444 | int gpio_direction_output(unsigned gpio, int value) | 522 | static int sh_gpio_direction_output(struct gpio_chip *chip, unsigned offset, |
523 | int value) | ||
445 | { | 524 | { |
446 | struct pinmux_info *gpioc = gpio_controller(gpio); | 525 | struct pinmux_info *gpioc = chip_to_pinmux(chip); |
447 | unsigned long flags; | 526 | unsigned long flags; |
448 | int ret = -EINVAL; | 527 | int ret; |
449 | |||
450 | if (!gpioc) | ||
451 | goto err_out; | ||
452 | 528 | ||
529 | sh_gpio_set_value(gpioc, offset, value); | ||
453 | spin_lock_irqsave(&gpio_lock, flags); | 530 | spin_lock_irqsave(&gpio_lock, flags); |
454 | __gpio_get_set_value(gpioc, gpio, value, 1); | 531 | ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT); |
455 | ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_OUTPUT); | ||
456 | spin_unlock_irqrestore(&gpio_lock, flags); | 532 | spin_unlock_irqrestore(&gpio_lock, flags); |
457 | err_out: | 533 | |
458 | return ret; | 534 | return ret; |
459 | } | 535 | } |
460 | EXPORT_SYMBOL(gpio_direction_output); | ||
461 | 536 | ||
462 | int gpio_get_value(unsigned gpio) | 537 | static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio) |
463 | { | 538 | { |
464 | struct pinmux_info *gpioc = gpio_controller(gpio); | 539 | struct pinmux_data_reg *dr = NULL; |
465 | unsigned long flags; | 540 | int bit = 0; |
466 | int value = 0; | ||
467 | 541 | ||
468 | if (!gpioc) | 542 | if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) { |
469 | BUG(); | 543 | BUG(); |
470 | else { | 544 | return 0; |
471 | spin_lock_irqsave(&gpio_lock, flags); | ||
472 | value = __gpio_get_set_value(gpioc, gpio, 0, 0); | ||
473 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
474 | } | 545 | } |
475 | 546 | ||
476 | return value; | 547 | return gpio_read_reg(dr->reg, dr->reg_width, 1, bit); |
477 | } | 548 | } |
478 | EXPORT_SYMBOL(gpio_get_value); | ||
479 | 549 | ||
480 | void gpio_set_value(unsigned gpio, int value) | 550 | static int sh_gpio_get(struct gpio_chip *chip, unsigned offset) |
481 | { | 551 | { |
482 | struct pinmux_info *gpioc = gpio_controller(gpio); | 552 | return sh_gpio_get_value(chip_to_pinmux(chip), offset); |
483 | unsigned long flags; | 553 | } |
484 | 554 | ||
485 | if (!gpioc) | 555 | static void sh_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
486 | BUG(); | 556 | { |
487 | else { | 557 | sh_gpio_set_value(chip_to_pinmux(chip), offset, value); |
488 | spin_lock_irqsave(&gpio_lock, flags); | ||
489 | __gpio_get_set_value(gpioc, gpio, value, 1); | ||
490 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
491 | } | ||
492 | } | 558 | } |
493 | EXPORT_SYMBOL(gpio_set_value); | ||
494 | 559 | ||
495 | int register_pinmux(struct pinmux_info *pip) | 560 | int register_pinmux(struct pinmux_info *pip) |
496 | { | 561 | { |
497 | registered_gpio = pip; | 562 | struct gpio_chip *chip = &pip->chip; |
498 | pr_info("pinmux: %s handling gpio %d -> %d\n", | 563 | |
564 | pr_info("sh pinmux: %s handling gpio %d -> %d\n", | ||
499 | pip->name, pip->first_gpio, pip->last_gpio); | 565 | pip->name, pip->first_gpio, pip->last_gpio); |
500 | 566 | ||
501 | return 0; | 567 | setup_data_regs(pip); |
568 | |||
569 | chip->request = sh_gpio_request; | ||
570 | chip->free = sh_gpio_free; | ||
571 | chip->direction_input = sh_gpio_direction_input; | ||
572 | chip->get = sh_gpio_get; | ||
573 | chip->direction_output = sh_gpio_direction_output; | ||
574 | chip->set = sh_gpio_set; | ||
575 | |||
576 | WARN_ON(pip->first_gpio != 0); /* needs testing */ | ||
577 | |||
578 | chip->label = pip->name; | ||
579 | chip->owner = THIS_MODULE; | ||
580 | chip->base = pip->first_gpio; | ||
581 | chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1; | ||
582 | |||
583 | return gpiochip_add(chip); | ||
502 | } | 584 | } |