aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2008-12-25 04:17:34 -0500
committerPaul Mundt <lethal@linux-sh.org>2009-01-27 00:49:10 -0500
commit69edbba0021a48fe034849501513930f6175cb5d (patch)
tree51499128883b2e84bce5dcaa78e6e943c37eeb40
parent3292094e88ce6b76714dad8ec4b43d7c5c12ada2 (diff)
sh: use gpiolib
This patch updates the SuperH gpio code to make use of gpiolib. The gpiolib callbacks get() and set() are lockless, but we use our own spinlock for the other operations to make sure hardware register bitfield accesses stay atomic. Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/sh/Kconfig7
-rw-r--r--arch/sh/boards/Kconfig4
-rw-r--r--arch/sh/include/asm/gpio.h61
-rw-r--r--arch/sh/kernel/Makefile_322
-rw-r--r--arch/sh/kernel/Makefile_642
-rw-r--r--arch/sh/kernel/gpio.c106
-rw-r--r--drivers/serial/sh-sci.h2
7 files changed, 100 insertions, 84 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index ebabe518e729..3a2be2278944 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -126,6 +126,13 @@ config ARCH_HAS_ILOG2_U64
126config ARCH_NO_VIRT_TO_BUS 126config ARCH_NO_VIRT_TO_BUS
127 def_bool y 127 def_bool y
128 128
129config ARCH_WANT_OPTIONAL_GPIOLIB
130 def_bool y
131 depends on !ARCH_REQUIRE_GPIOLIB
132
133config ARCH_REQUIRE_GPIOLIB
134 def_bool n
135
129config IO_TRAPPED 136config IO_TRAPPED
130 bool 137 bool
131 138
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 861914747e4e..802d5c475a7d 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -165,7 +165,7 @@ config SH_SH7785LCR_29BIT_PHYSMAPS
165config SH_MIGOR 165config SH_MIGOR
166 bool "Migo-R" 166 bool "Migo-R"
167 depends on CPU_SUBTYPE_SH7722 167 depends on CPU_SUBTYPE_SH7722
168 select GENERIC_GPIO 168 select ARCH_REQUIRE_GPIOLIB
169 help 169 help
170 Select Migo-R if configuring for the SH7722 Migo-R platform 170 Select Migo-R if configuring for the SH7722 Migo-R platform
171 by Renesas System Solutions Asia Pte. Ltd. 171 by Renesas System Solutions Asia Pte. Ltd.
@@ -173,7 +173,7 @@ config SH_MIGOR
173config SH_AP325RXA 173config SH_AP325RXA
174 bool "AP-325RXA" 174 bool "AP-325RXA"
175 depends on CPU_SUBTYPE_SH7723 175 depends on CPU_SUBTYPE_SH7723
176 select GENERIC_GPIO 176 select ARCH_REQUIRE_GPIOLIB
177 help 177 help
178 Renesas "AP-325RXA" support. 178 Renesas "AP-325RXA" support.
179 Compatible with ALGO SYSTEM CO.,LTD. "AP-320A" 179 Compatible with ALGO SYSTEM CO.,LTD. "AP-320A"
diff --git a/arch/sh/include/asm/gpio.h b/arch/sh/include/asm/gpio.h
index 46a6d7914df7..61f93da2c62e 100644
--- a/arch/sh/include/asm/gpio.h
+++ b/arch/sh/include/asm/gpio.h
@@ -19,6 +19,40 @@
19#include <cpu/gpio.h> 19#include <cpu/gpio.h>
20#endif 20#endif
21 21
22#define ARCH_NR_GPIOS 512
23#include <asm-generic/gpio.h>
24
25#ifdef CONFIG_GPIOLIB
26
27static inline int gpio_get_value(unsigned gpio)
28{
29 return __gpio_get_value(gpio);
30}
31
32static inline void gpio_set_value(unsigned gpio, int value)
33{
34 __gpio_set_value(gpio, value);
35}
36
37static inline int gpio_cansleep(unsigned gpio)
38{
39 return __gpio_cansleep(gpio);
40}
41
42static inline int gpio_to_irq(unsigned gpio)
43{
44 WARN_ON(1);
45 return -ENOSYS;
46}
47
48static inline int irq_to_gpio(unsigned int irq)
49{
50 WARN_ON(1);
51 return -EINVAL;
52}
53
54#endif /* CONFIG_GPIOLIB */
55
22typedef unsigned short pinmux_enum_t; 56typedef unsigned short pinmux_enum_t;
23typedef unsigned short pinmux_flag_t; 57typedef unsigned short pinmux_flag_t;
24 58
@@ -94,34 +128,9 @@ struct pinmux_info {
94 unsigned int gpio_data_size; 128 unsigned int gpio_data_size;
95 129
96 unsigned long *gpio_in_use; 130 unsigned long *gpio_in_use;
131 struct gpio_chip chip;
97}; 132};
98 133
99int register_pinmux(struct pinmux_info *pip); 134int register_pinmux(struct pinmux_info *pip);
100 135
101int __gpio_request(unsigned gpio);
102static inline int gpio_request(unsigned gpio, const char *label)
103{
104 return __gpio_request(gpio);
105}
106void gpio_free(unsigned gpio);
107int gpio_direction_input(unsigned gpio);
108int gpio_direction_output(unsigned gpio, int value);
109int gpio_get_value(unsigned gpio);
110void gpio_set_value(unsigned gpio, int value);
111
112/* IRQ modes are unspported */
113static inline int gpio_to_irq(unsigned gpio)
114{
115 WARN_ON(1);
116 return -EINVAL;
117}
118
119static inline int irq_to_gpio(unsigned irq)
120{
121 WARN_ON(1);
122 return -EINVAL;
123}
124
125#include <asm-generic/gpio.h>
126
127#endif /* __ASM_SH_GPIO_H */ 136#endif /* __ASM_SH_GPIO_H */
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32
index 2e1b86e16ab5..7e7d22b5b4ca 100644
--- a/arch/sh/kernel/Makefile_32
+++ b/arch/sh/kernel/Makefile_32
@@ -27,7 +27,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
27obj-$(CONFIG_STACKTRACE) += stacktrace.o 27obj-$(CONFIG_STACKTRACE) += stacktrace.o
28obj-$(CONFIG_IO_TRAPPED) += io_trapped.o 28obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
29obj-$(CONFIG_KPROBES) += kprobes.o 29obj-$(CONFIG_KPROBES) += kprobes.o
30obj-$(CONFIG_GENERIC_GPIO) += gpio.o 30obj-$(CONFIG_ARCH_REQUIRE_GPIOLIB) += gpio.o
31obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 31obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
32obj-$(CONFIG_DUMP_CODE) += disassemble.o 32obj-$(CONFIG_DUMP_CODE) += disassemble.o
33 33
diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64
index fe425d7f6871..cbcbbb6c0497 100644
--- a/arch/sh/kernel/Makefile_64
+++ b/arch/sh/kernel/Makefile_64
@@ -15,6 +15,6 @@ obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
15obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 15obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
16obj-$(CONFIG_STACKTRACE) += stacktrace.o 16obj-$(CONFIG_STACKTRACE) += stacktrace.o
17obj-$(CONFIG_IO_TRAPPED) += io_trapped.o 17obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
18obj-$(CONFIG_GENERIC_GPIO) += gpio.o 18obj-$(CONFIG_ARCH_REQUIRE_GPIOLIB) += gpio.o
19 19
20EXTRA_CFLAGS += -Werror 20EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/gpio.c b/arch/sh/kernel/gpio.c
index 280135673726..d22e5af699f9 100644
--- a/arch/sh/kernel/gpio.c
+++ b/arch/sh/kernel/gpio.c
@@ -19,22 +19,6 @@
19#include <linux/bitops.h> 19#include <linux/bitops.h>
20#include <linux/gpio.h> 20#include <linux/gpio.h>
21 21
22static struct pinmux_info *registered_gpio;
23
24static struct pinmux_info *gpio_controller(unsigned gpio)
25{
26 if (!registered_gpio)
27 return NULL;
28
29 if (gpio < registered_gpio->first_gpio)
30 return NULL;
31
32 if (gpio > registered_gpio->last_gpio)
33 return NULL;
34
35 return registered_gpio;
36}
37
38static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) 22static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
39{ 23{
40 if (enum_id < r->begin) 24 if (enum_id < r->begin)
@@ -398,9 +382,14 @@ static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
398 382
399static DEFINE_SPINLOCK(gpio_lock); 383static DEFINE_SPINLOCK(gpio_lock);
400 384
401int __gpio_request(unsigned gpio) 385static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip)
402{ 386{
403 struct pinmux_info *gpioc = gpio_controller(gpio); 387 return container_of(chip, struct pinmux_info, chip);
388}
389
390static int sh_gpio_request(struct gpio_chip *chip, unsigned offset)
391{
392 struct pinmux_info *gpioc = chip_to_pinmux(chip);
404 struct pinmux_data_reg *dummy; 393 struct pinmux_data_reg *dummy;
405 unsigned long flags; 394 unsigned long flags;
406 int i, ret, pinmux_type; 395 int i, ret, pinmux_type;
@@ -412,30 +401,30 @@ int __gpio_request(unsigned gpio)
412 401
413 spin_lock_irqsave(&gpio_lock, flags); 402 spin_lock_irqsave(&gpio_lock, flags);
414 403
415 if ((gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE) 404 if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
416 goto err_unlock; 405 goto err_unlock;
417 406
418 /* setup pin function here if no data is associated with pin */ 407 /* setup pin function here if no data is associated with pin */
419 408
420 if (get_data_reg(gpioc, gpio, &dummy, &i) != 0) 409 if (get_data_reg(gpioc, offset, &dummy, &i) != 0)
421 pinmux_type = PINMUX_TYPE_FUNCTION; 410 pinmux_type = PINMUX_TYPE_FUNCTION;
422 else 411 else
423 pinmux_type = PINMUX_TYPE_GPIO; 412 pinmux_type = PINMUX_TYPE_GPIO;
424 413
425 if (pinmux_type == PINMUX_TYPE_FUNCTION) { 414 if (pinmux_type == PINMUX_TYPE_FUNCTION) {
426 if (pinmux_config_gpio(gpioc, gpio, 415 if (pinmux_config_gpio(gpioc, offset,
427 pinmux_type, 416 pinmux_type,
428 GPIO_CFG_DRYRUN) != 0) 417 GPIO_CFG_DRYRUN) != 0)
429 goto err_unlock; 418 goto err_unlock;
430 419
431 if (pinmux_config_gpio(gpioc, gpio, 420 if (pinmux_config_gpio(gpioc, offset,
432 pinmux_type, 421 pinmux_type,
433 GPIO_CFG_REQ) != 0) 422 GPIO_CFG_REQ) != 0)
434 BUG(); 423 BUG();
435 } 424 }
436 425
437 gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE; 426 gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
438 gpioc->gpios[gpio].flags |= pinmux_type; 427 gpioc->gpios[offset].flags |= pinmux_type;
439 428
440 ret = 0; 429 ret = 0;
441 err_unlock: 430 err_unlock:
@@ -443,11 +432,10 @@ int __gpio_request(unsigned gpio)
443 err_out: 432 err_out:
444 return ret; 433 return ret;
445} 434}
446EXPORT_SYMBOL(__gpio_request);
447 435
448void gpio_free(unsigned gpio) 436static void sh_gpio_free(struct gpio_chip *chip, unsigned offset)
449{ 437{
450 struct pinmux_info *gpioc = gpio_controller(gpio); 438 struct pinmux_info *gpioc = chip_to_pinmux(chip);
451 unsigned long flags; 439 unsigned long flags;
452 int pinmux_type; 440 int pinmux_type;
453 441
@@ -456,14 +444,13 @@ void gpio_free(unsigned gpio)
456 444
457 spin_lock_irqsave(&gpio_lock, flags); 445 spin_lock_irqsave(&gpio_lock, flags);
458 446
459 pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE; 447 pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE;
460 pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE); 448 pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE);
461 gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE; 449 gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
462 gpioc->gpios[gpio].flags |= PINMUX_TYPE_NONE; 450 gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE;
463 451
464 spin_unlock_irqrestore(&gpio_lock, flags); 452 spin_unlock_irqrestore(&gpio_lock, flags);
465} 453}
466EXPORT_SYMBOL(gpio_free);
467 454
468static int pinmux_direction(struct pinmux_info *gpioc, 455static int pinmux_direction(struct pinmux_info *gpioc,
469 unsigned gpio, int new_pinmux_type) 456 unsigned gpio, int new_pinmux_type)
@@ -507,21 +494,20 @@ static int pinmux_direction(struct pinmux_info *gpioc,
507 return ret; 494 return ret;
508} 495}
509 496
510int gpio_direction_input(unsigned gpio) 497static int sh_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
511{ 498{
512 struct pinmux_info *gpioc = gpio_controller(gpio); 499 struct pinmux_info *gpioc = chip_to_pinmux(chip);
513 unsigned long flags; 500 unsigned long flags;
514 int ret; 501 int ret;
515 502
516 spin_lock_irqsave(&gpio_lock, flags); 503 spin_lock_irqsave(&gpio_lock, flags);
517 ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_INPUT); 504 ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT);
518 spin_unlock_irqrestore(&gpio_lock, flags); 505 spin_unlock_irqrestore(&gpio_lock, flags);
519 506
520 return ret; 507 return ret;
521} 508}
522EXPORT_SYMBOL(gpio_direction_input);
523 509
524static void __gpio_set_value(struct pinmux_info *gpioc, 510static void sh_gpio_set_value(struct pinmux_info *gpioc,
525 unsigned gpio, int value) 511 unsigned gpio, int value)
526{ 512{
527 struct pinmux_data_reg *dr = NULL; 513 struct pinmux_data_reg *dr = NULL;
@@ -533,22 +519,22 @@ static void __gpio_set_value(struct pinmux_info *gpioc,
533 gpio_write_bit(dr, bit, value); 519 gpio_write_bit(dr, bit, value);
534} 520}
535 521
536int gpio_direction_output(unsigned gpio, int value) 522static int sh_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
523 int value)
537{ 524{
538 struct pinmux_info *gpioc = gpio_controller(gpio); 525 struct pinmux_info *gpioc = chip_to_pinmux(chip);
539 unsigned long flags; 526 unsigned long flags;
540 int ret; 527 int ret;
541 528
542 __gpio_set_value(gpioc, gpio, value); 529 sh_gpio_set_value(gpioc, offset, value);
543 spin_lock_irqsave(&gpio_lock, flags); 530 spin_lock_irqsave(&gpio_lock, flags);
544 ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_OUTPUT); 531 ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT);
545 spin_unlock_irqrestore(&gpio_lock, flags); 532 spin_unlock_irqrestore(&gpio_lock, flags);
546 533
547 return ret; 534 return ret;
548} 535}
549EXPORT_SYMBOL(gpio_direction_output);
550 536
551static int __gpio_get_value(struct pinmux_info *gpioc, unsigned gpio) 537static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
552{ 538{
553 struct pinmux_data_reg *dr = NULL; 539 struct pinmux_data_reg *dr = NULL;
554 int bit = 0; 540 int bit = 0;
@@ -561,24 +547,38 @@ static int __gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
561 return gpio_read_reg(dr->reg, dr->reg_width, 1, bit); 547 return gpio_read_reg(dr->reg, dr->reg_width, 1, bit);
562} 548}
563 549
564int gpio_get_value(unsigned gpio) 550static int sh_gpio_get(struct gpio_chip *chip, unsigned offset)
565{ 551{
566 return __gpio_get_value(gpio_controller(gpio), gpio); 552 return sh_gpio_get_value(chip_to_pinmux(chip), offset);
567} 553}
568EXPORT_SYMBOL(gpio_get_value);
569 554
570void gpio_set_value(unsigned gpio, int value) 555static void sh_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
571{ 556{
572 __gpio_set_value(gpio_controller(gpio), gpio, value); 557 sh_gpio_set_value(chip_to_pinmux(chip), offset, value);
573} 558}
574EXPORT_SYMBOL(gpio_set_value);
575 559
576int register_pinmux(struct pinmux_info *pip) 560int register_pinmux(struct pinmux_info *pip)
577{ 561{
578 registered_gpio = pip; 562 struct gpio_chip *chip = &pip->chip;
579 setup_data_regs(pip); 563
580 pr_info("pinmux: %s handling gpio %d -> %d\n", 564 pr_info("sh pinmux: %s handling gpio %d -> %d\n",
581 pip->name, pip->first_gpio, pip->last_gpio); 565 pip->name, pip->first_gpio, pip->last_gpio);
582 566
583 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);
584} 584}
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 3599828b9766..6a7cd498023d 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -1,6 +1,6 @@
1#include <linux/serial_core.h> 1#include <linux/serial_core.h>
2#include <asm/io.h> 2#include <asm/io.h>
3#include <asm/gpio.h> 3#include <linux/gpio.h>
4 4
5#if defined(CONFIG_H83007) || defined(CONFIG_H83068) 5#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
6#include <asm/regs306x.h> 6#include <asm/regs306x.h>