diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/plat-s5pc1xx/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/plat-s5pc1xx/gpiolib.c | 96 |
2 files changed, 10 insertions, 87 deletions
diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig index 79d3be721dde..98bbaf9d2219 100644 --- a/arch/arm/plat-s5pc1xx/Kconfig +++ b/arch/arm/plat-s5pc1xx/Kconfig | |||
@@ -19,6 +19,7 @@ config PLAT_S5PC1XX | |||
19 | select S5P_GPIO_DRVSTR | 19 | select S5P_GPIO_DRVSTR |
20 | select S3C_GPIO_CFG_S3C24XX | 20 | select S3C_GPIO_CFG_S3C24XX |
21 | select S3C_GPIO_CFG_S3C64XX | 21 | select S3C_GPIO_CFG_S3C64XX |
22 | select SAMSUNG_GPIOLIB_4BIT | ||
22 | help | 23 | help |
23 | Base platform code for any Samsung S5PC1XX device | 24 | Base platform code for any Samsung S5PC1XX device |
24 | 25 | ||
diff --git a/arch/arm/plat-s5pc1xx/gpiolib.c b/arch/arm/plat-s5pc1xx/gpiolib.c index 1ffc57ac293d..5a97a8f8e368 100644 --- a/arch/arm/plat-s5pc1xx/gpiolib.c +++ b/arch/arm/plat-s5pc1xx/gpiolib.c | |||
@@ -61,74 +61,6 @@ | |||
61 | * L3 8 4Bit None | 61 | * L3 8 4Bit None |
62 | */ | 62 | */ |
63 | 63 | ||
64 | #define OFF_GPCON (0x00) | ||
65 | #define OFF_GPDAT (0x04) | ||
66 | |||
67 | #define con_4bit_shift(__off) ((__off) * 4) | ||
68 | |||
69 | #if 1 | ||
70 | #define gpio_dbg(x...) do { } while (0) | ||
71 | #else | ||
72 | #define gpio_dbg(x...) printk(KERN_DEBUG x) | ||
73 | #endif | ||
74 | |||
75 | /* The s5pc1xx_gpiolib routines are to control the gpio banks where | ||
76 | * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the | ||
77 | * following example: | ||
78 | * | ||
79 | * base + 0x00: Control register, 4 bits per gpio | ||
80 | * gpio n: 4 bits starting at (4*n) | ||
81 | * 0000 = input, 0001 = output, others mean special-function | ||
82 | * base + 0x04: Data register, 1 bit per gpio | ||
83 | * bit n: data bit n | ||
84 | * | ||
85 | * Note, since the data register is one bit per gpio and is at base + 0x4 | ||
86 | * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of | ||
87 | * the output. | ||
88 | */ | ||
89 | |||
90 | static int s5pc1xx_gpiolib_input(struct gpio_chip *chip, unsigned offset) | ||
91 | { | ||
92 | struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); | ||
93 | void __iomem *base = ourchip->base; | ||
94 | unsigned long con; | ||
95 | |||
96 | con = __raw_readl(base + OFF_GPCON); | ||
97 | con &= ~(0xf << con_4bit_shift(offset)); | ||
98 | __raw_writel(con, base + OFF_GPCON); | ||
99 | |||
100 | gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con); | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static int s5pc1xx_gpiolib_output(struct gpio_chip *chip, | ||
106 | unsigned offset, int value) | ||
107 | { | ||
108 | struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); | ||
109 | void __iomem *base = ourchip->base; | ||
110 | unsigned long con; | ||
111 | unsigned long dat; | ||
112 | |||
113 | con = __raw_readl(base + OFF_GPCON); | ||
114 | con &= ~(0xf << con_4bit_shift(offset)); | ||
115 | con |= 0x1 << con_4bit_shift(offset); | ||
116 | |||
117 | dat = __raw_readl(base + OFF_GPDAT); | ||
118 | if (value) | ||
119 | dat |= 1 << offset; | ||
120 | else | ||
121 | dat &= ~(1 << offset); | ||
122 | |||
123 | __raw_writel(dat, base + OFF_GPDAT); | ||
124 | __raw_writel(con, base + OFF_GPCON); | ||
125 | __raw_writel(dat, base + OFF_GPDAT); | ||
126 | |||
127 | gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static int s5pc1xx_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) | 64 | static int s5pc1xx_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) |
133 | { | 65 | { |
134 | return S3C_IRQ_GPIO(chip->base + offset); | 66 | return S3C_IRQ_GPIO(chip->base + offset); |
@@ -452,11 +384,8 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = { | |||
452 | extern struct irq_chip s5pc1xx_gpioint; | 384 | extern struct irq_chip s5pc1xx_gpioint; |
453 | extern void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc); | 385 | extern void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc); |
454 | 386 | ||
455 | static __init void s5pc1xx_gpiolib_link(struct s3c_gpio_chip *chip) | 387 | static __init void s5pc100_gpiolib_link(struct s3c_gpio_chip *chip) |
456 | { | 388 | { |
457 | chip->chip.direction_input = s5pc1xx_gpiolib_input; | ||
458 | chip->chip.direction_output = s5pc1xx_gpiolib_output; | ||
459 | chip->pm = __gpio_pm(&s3c_gpio_pm_4bit); | ||
460 | 389 | ||
461 | /* Interrupt */ | 390 | /* Interrupt */ |
462 | if (chip->config == &gpio_cfg) { | 391 | if (chip->config == &gpio_cfg) { |
@@ -475,26 +404,19 @@ static __init void s5pc1xx_gpiolib_link(struct s3c_gpio_chip *chip) | |||
475 | chip->chip.to_irq = s5pc1xx_gpiolib_to_eint; | 404 | chip->chip.to_irq = s5pc1xx_gpiolib_to_eint; |
476 | } | 405 | } |
477 | 406 | ||
478 | static __init void s5pc1xx_gpiolib_add(struct s3c_gpio_chip *chips, | ||
479 | int nr_chips, | ||
480 | void (*fn)(struct s3c_gpio_chip *)) | ||
481 | { | ||
482 | for (; nr_chips > 0; nr_chips--, chips++) { | ||
483 | if (fn) | ||
484 | (fn)(chips); | ||
485 | s3c_gpiolib_add(chips); | ||
486 | } | ||
487 | } | ||
488 | |||
489 | static __init int s5pc1xx_gpiolib_init(void) | 407 | static __init int s5pc1xx_gpiolib_init(void) |
490 | { | 408 | { |
491 | struct s3c_gpio_chip *chips; | 409 | struct s3c_gpio_chip *chip; |
492 | int nr_chips; | 410 | int nr_chips; |
493 | 411 | ||
494 | chips = s5pc100_gpio_chips; | 412 | chip = s5pc100_gpio_chips; |
495 | nr_chips = ARRAY_SIZE(s5pc100_gpio_chips); | 413 | nr_chips = ARRAY_SIZE(s5pc100_gpio_chips); |
414 | |||
415 | for (; nr_chips > 0; nr_chips--, chip++) | ||
416 | s5pc100_gpiolib_link(chip); | ||
496 | 417 | ||
497 | s5pc1xx_gpiolib_add(chips, nr_chips, s5pc1xx_gpiolib_link); | 418 | samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, |
419 | ARRAY_SIZE(s5pc100_gpio_chips)); | ||
498 | /* Interrupt */ | 420 | /* Interrupt */ |
499 | set_irq_chained_handler(IRQ_GPIOINT, s5pc1xx_irq_gpioint_handler); | 421 | set_irq_chained_handler(IRQ_GPIOINT, s5pc1xx_irq_gpioint_handler); |
500 | 422 | ||