diff options
| -rw-r--r-- | arch/arm/mach-ixp2000/core.c | 85 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-ixp2000.c | 3 | ||||
| -rw-r--r-- | include/asm-arm/arch-ixp2000/gpio.h | 31 | ||||
| -rw-r--r-- | include/asm-arm/arch-ixp2000/platform.h | 22 |
4 files changed, 82 insertions, 59 deletions
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index fc0555596d6d..0ee34acb8d7b 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c | |||
| @@ -40,6 +40,8 @@ | |||
| 40 | #include <asm/mach/time.h> | 40 | #include <asm/mach/time.h> |
| 41 | #include <asm/mach/irq.h> | 41 | #include <asm/mach/irq.h> |
| 42 | 42 | ||
| 43 | #include <asm/arch/gpio.h> | ||
| 44 | |||
| 43 | static DEFINE_SPINLOCK(ixp2000_slowport_lock); | 45 | static DEFINE_SPINLOCK(ixp2000_slowport_lock); |
| 44 | static unsigned long ixp2000_slowport_irq_flags; | 46 | static unsigned long ixp2000_slowport_irq_flags; |
| 45 | 47 | ||
| @@ -179,7 +181,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
| 179 | 181 | ||
| 180 | /* clear timer 1 */ | 182 | /* clear timer 1 */ |
| 181 | ixp2000_reg_write(IXP2000_T1_CLR, 1); | 183 | ixp2000_reg_write(IXP2000_T1_CLR, 1); |
| 182 | 184 | ||
| 183 | while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) { | 185 | while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) { |
| 184 | timer_tick(regs); | 186 | timer_tick(regs); |
| 185 | next_jiffy_time -= ticks_per_jiffy; | 187 | next_jiffy_time -= ticks_per_jiffy; |
| @@ -238,35 +240,40 @@ void __init ixp2000_init_time(unsigned long tick_rate) | |||
| 238 | /************************************************************************* | 240 | /************************************************************************* |
| 239 | * GPIO helpers | 241 | * GPIO helpers |
| 240 | *************************************************************************/ | 242 | *************************************************************************/ |
| 241 | static unsigned long GPIO_IRQ_rising_edge; | ||
| 242 | static unsigned long GPIO_IRQ_falling_edge; | 243 | static unsigned long GPIO_IRQ_falling_edge; |
| 244 | static unsigned long GPIO_IRQ_rising_edge; | ||
| 243 | static unsigned long GPIO_IRQ_level_low; | 245 | static unsigned long GPIO_IRQ_level_low; |
| 244 | static unsigned long GPIO_IRQ_level_high; | 246 | static unsigned long GPIO_IRQ_level_high; |
| 245 | 247 | ||
| 246 | void gpio_line_config(int line, int style) | 248 | static void update_gpio_int_csrs(void) |
| 249 | { | ||
| 250 | ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge); | ||
| 251 | ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge); | ||
| 252 | ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low); | ||
| 253 | ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high); | ||
| 254 | } | ||
| 255 | |||
| 256 | void gpio_line_config(int line, int direction) | ||
| 247 | { | 257 | { |
| 248 | unsigned long flags; | 258 | unsigned long flags; |
| 249 | 259 | ||
| 250 | local_irq_save(flags); | 260 | local_irq_save(flags); |
| 261 | if (direction == GPIO_OUT) { | ||
| 262 | irq_desc[line + IRQ_IXP2000_GPIO0].valid = 0; | ||
| 251 | 263 | ||
| 252 | if(style == GPIO_OUT) { | ||
| 253 | /* if it's an output, it ain't an interrupt anymore */ | 264 | /* if it's an output, it ain't an interrupt anymore */ |
| 254 | ixp2000_reg_write(IXP2000_GPIO_PDSR, (1 << line)); | ||
| 255 | GPIO_IRQ_falling_edge &= ~(1 << line); | 265 | GPIO_IRQ_falling_edge &= ~(1 << line); |
| 256 | GPIO_IRQ_rising_edge &= ~(1 << line); | 266 | GPIO_IRQ_rising_edge &= ~(1 << line); |
| 257 | GPIO_IRQ_level_low &= ~(1 << line); | 267 | GPIO_IRQ_level_low &= ~(1 << line); |
| 258 | GPIO_IRQ_level_high &= ~(1 << line); | 268 | GPIO_IRQ_level_high &= ~(1 << line); |
| 259 | ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge); | 269 | update_gpio_int_csrs(); |
| 260 | ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge); | 270 | |
| 261 | ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high); | 271 | ixp2000_reg_write(IXP2000_GPIO_PDSR, 1 << line); |
| 262 | ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low); | 272 | } else if (direction == GPIO_IN) { |
| 263 | irq_desc[line+IRQ_IXP2000_GPIO0].valid = 0; | 273 | ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line); |
| 264 | } else if(style == GPIO_IN) { | ||
| 265 | ixp2000_reg_write(IXP2000_GPIO_PDCR, (1 << line)); | ||
| 266 | } | 274 | } |
| 267 | |||
| 268 | local_irq_restore(flags); | 275 | local_irq_restore(flags); |
| 269 | } | 276 | } |
| 270 | 277 | ||
| 271 | 278 | ||
| 272 | /************************************************************************* | 279 | /************************************************************************* |
| @@ -285,9 +292,50 @@ static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc, str | |||
| 285 | } | 292 | } |
| 286 | } | 293 | } |
| 287 | 294 | ||
| 295 | static int ixp2000_GPIO_irq_type(unsigned int irq, unsigned int type) | ||
| 296 | { | ||
| 297 | int line = irq - IRQ_IXP2000_GPIO0; | ||
| 298 | |||
| 299 | /* | ||
| 300 | * First, configure this GPIO line as an input. | ||
| 301 | */ | ||
| 302 | ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line); | ||
| 303 | |||
| 304 | /* | ||
| 305 | * Then, set the proper trigger type. | ||
| 306 | */ | ||
| 307 | if (type & IRQT_FALLING) | ||
| 308 | GPIO_IRQ_falling_edge |= 1 << line; | ||
| 309 | else | ||
| 310 | GPIO_IRQ_falling_edge &= ~(1 << line); | ||
| 311 | if (type & IRQT_RISING) | ||
| 312 | GPIO_IRQ_rising_edge |= 1 << line; | ||
| 313 | else | ||
| 314 | GPIO_IRQ_rising_edge &= ~(1 << line); | ||
| 315 | if (type & IRQT_LOW) | ||
| 316 | GPIO_IRQ_level_low |= 1 << line; | ||
| 317 | else | ||
| 318 | GPIO_IRQ_level_low &= ~(1 << line); | ||
| 319 | if (type & IRQT_HIGH) | ||
| 320 | GPIO_IRQ_level_high |= 1 << line; | ||
| 321 | else | ||
| 322 | GPIO_IRQ_level_high &= ~(1 << line); | ||
| 323 | update_gpio_int_csrs(); | ||
| 324 | |||
| 325 | /* | ||
| 326 | * Finally, mark the corresponding IRQ as valid. | ||
| 327 | */ | ||
| 328 | irq_desc[irq].valid = 1; | ||
| 329 | |||
| 330 | return 0; | ||
| 331 | } | ||
| 332 | |||
| 288 | static void ixp2000_GPIO_irq_mask_ack(unsigned int irq) | 333 | static void ixp2000_GPIO_irq_mask_ack(unsigned int irq) |
| 289 | { | 334 | { |
| 290 | ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0))); | 335 | ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0))); |
| 336 | |||
| 337 | ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0))); | ||
| 338 | ixp2000_reg_write(IXP2000_GPIO_LDSR, (1 << (irq - IRQ_IXP2000_GPIO0))); | ||
| 291 | ixp2000_reg_write(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0))); | 339 | ixp2000_reg_write(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0))); |
| 292 | } | 340 | } |
| 293 | 341 | ||
| @@ -302,6 +350,7 @@ static void ixp2000_GPIO_irq_unmask(unsigned int irq) | |||
| 302 | } | 350 | } |
| 303 | 351 | ||
| 304 | static struct irqchip ixp2000_GPIO_irq_chip = { | 352 | static struct irqchip ixp2000_GPIO_irq_chip = { |
| 353 | .type = ixp2000_GPIO_irq_type, | ||
| 305 | .ack = ixp2000_GPIO_irq_mask_ack, | 354 | .ack = ixp2000_GPIO_irq_mask_ack, |
| 306 | .mask = ixp2000_GPIO_irq_mask, | 355 | .mask = ixp2000_GPIO_irq_mask, |
| 307 | .unmask = ixp2000_GPIO_irq_unmask | 356 | .unmask = ixp2000_GPIO_irq_unmask |
| @@ -338,7 +387,7 @@ static void ixp2000_irq_mask(unsigned int irq) | |||
| 338 | 387 | ||
| 339 | static void ixp2000_irq_unmask(unsigned int irq) | 388 | static void ixp2000_irq_unmask(unsigned int irq) |
| 340 | { | 389 | { |
| 341 | ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << irq)); | 390 | ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << irq)); |
| 342 | } | 391 | } |
| 343 | 392 | ||
| 344 | static struct irqchip ixp2000_irq_chip = { | 393 | static struct irqchip ixp2000_irq_chip = { |
| @@ -375,16 +424,16 @@ void __init ixp2000_init_irq(void) | |||
| 375 | * our mask/unmask code much simpler. | 424 | * our mask/unmask code much simpler. |
| 376 | */ | 425 | */ |
| 377 | for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) { | 426 | for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) { |
| 378 | if((1 << irq) & IXP2000_VALID_IRQ_MASK) { | 427 | if ((1 << irq) & IXP2000_VALID_IRQ_MASK) { |
| 379 | set_irq_chip(irq, &ixp2000_irq_chip); | 428 | set_irq_chip(irq, &ixp2000_irq_chip); |
| 380 | set_irq_handler(irq, do_level_IRQ); | 429 | set_irq_handler(irq, do_level_IRQ); |
| 381 | set_irq_flags(irq, IRQF_VALID); | 430 | set_irq_flags(irq, IRQF_VALID); |
| 382 | } else set_irq_flags(irq, 0); | 431 | } else set_irq_flags(irq, 0); |
| 383 | } | 432 | } |
| 384 | 433 | ||
| 385 | /* | 434 | /* |
| 386 | * GPIO IRQs are invalid until someone sets the interrupt mode | 435 | * GPIO IRQs are invalid until someone sets the interrupt mode |
| 387 | * by calling gpio_line_set(); | 436 | * by calling set_irq_type(). |
| 388 | */ | 437 | */ |
| 389 | for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) { | 438 | for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) { |
| 390 | set_irq_chip(irq, &ixp2000_GPIO_irq_chip); | 439 | set_irq_chip(irq, &ixp2000_GPIO_irq_chip); |
diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c index ec943cad2314..1956af382cd8 100644 --- a/drivers/i2c/busses/i2c-ixp2000.c +++ b/drivers/i2c/busses/i2c-ixp2000.c | |||
| @@ -33,7 +33,8 @@ | |||
| 33 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
| 34 | #include <linux/i2c-algo-bit.h> | 34 | #include <linux/i2c-algo-bit.h> |
| 35 | 35 | ||
| 36 | #include <asm/hardware.h> /* Pick up IXP42000-specific bits */ | 36 | #include <asm/hardware.h> /* Pick up IXP2000-specific bits */ |
| 37 | #include <asm/arch/gpio.h> | ||
| 37 | 38 | ||
| 38 | static inline int ixp2000_scl_pin(void *data) | 39 | static inline int ixp2000_scl_pin(void *data) |
| 39 | { | 40 | { |
diff --git a/include/asm-arm/arch-ixp2000/gpio.h b/include/asm-arm/arch-ixp2000/gpio.h index 84634af5cc64..03cbbe1fd9d8 100644 --- a/include/asm-arm/arch-ixp2000/gpio.h +++ b/include/asm-arm/arch-ixp2000/gpio.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * include/asm-arm/arch-ixp2000/ixp2000-gpio.h | 2 | * include/asm-arm/arch-ixp2000/gpio.h |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2002 Intel Corporation. | 4 | * Copyright (C) 2002 Intel Corporation. |
| 5 | * | 5 | * |
| @@ -16,26 +16,18 @@ | |||
| 16 | * Use this instead of directly setting the GPIO registers. | 16 | * Use this instead of directly setting the GPIO registers. |
| 17 | * GPIOs may also be used as GPIOs (e.g. for emulating i2c/smb) | 17 | * GPIOs may also be used as GPIOs (e.g. for emulating i2c/smb) |
| 18 | */ | 18 | */ |
| 19 | #ifndef _ASM_ARCH_IXP2000_GPIO_H_ | 19 | #ifndef __ASM_ARCH_GPIO_H |
| 20 | #define _ASM_ARCH_IXP2000_GPIO_H_ | 20 | #define __ASM_ARCH_GPIO_H |
| 21 | 21 | ||
| 22 | #ifndef __ASSEMBLY__ | 22 | #ifndef __ASSEMBLY__ |
| 23 | #define GPIO_OUT 0x0 | 23 | |
| 24 | #define GPIO_IN 0x80 | 24 | #define GPIO_IN 0 |
| 25 | #define GPIO_OUT 1 | ||
| 25 | 26 | ||
| 26 | #define IXP2000_GPIO_LOW 0 | 27 | #define IXP2000_GPIO_LOW 0 |
| 27 | #define IXP2000_GPIO_HIGH 1 | 28 | #define IXP2000_GPIO_HIGH 1 |
| 28 | 29 | ||
| 29 | #define GPIO_NO_EDGES 0 | 30 | extern void gpio_line_config(int line, int direction); |
| 30 | #define GPIO_FALLING_EDGE 1 | ||
| 31 | #define GPIO_RISING_EDGE 2 | ||
| 32 | #define GPIO_BOTH_EDGES 3 | ||
| 33 | #define GPIO_LEVEL_LOW 4 | ||
| 34 | #define GPIO_LEVEL_HIGH 8 | ||
| 35 | |||
| 36 | extern void set_GPIO_IRQ_edge(int gpio_nr, int edge); | ||
| 37 | extern void set_GPIO_IRQ_level(int gpio_nr, int level); | ||
| 38 | extern void gpio_line_config(int line, int style); | ||
| 39 | 31 | ||
| 40 | static inline int gpio_line_get(int line) | 32 | static inline int gpio_line_get(int line) |
| 41 | { | 33 | { |
| @@ -45,11 +37,12 @@ static inline int gpio_line_get(int line) | |||
| 45 | static inline void gpio_line_set(int line, int value) | 37 | static inline void gpio_line_set(int line, int value) |
| 46 | { | 38 | { |
| 47 | if (value == IXP2000_GPIO_HIGH) { | 39 | if (value == IXP2000_GPIO_HIGH) { |
| 48 | ixp_reg_write(IXP2000_GPIO_POSR, BIT(line)); | 40 | ixp2000_reg_write(IXP2000_GPIO_POSR, 1 << line); |
| 49 | } else if (value == IXP2000_GPIO_LOW) | 41 | } else if (value == IXP2000_GPIO_LOW) { |
| 50 | ixp_reg_write(IXP2000_GPIO_POCR, BIT(line)); | 42 | ixp2000_reg_write(IXP2000_GPIO_POCR, 1 << line); |
| 43 | } | ||
| 51 | } | 44 | } |
| 52 | 45 | ||
| 53 | #endif /* !__ASSEMBLY__ */ | 46 | #endif /* !__ASSEMBLY__ */ |
| 54 | #endif /* ASM_ARCH_IXP2000_GPIO_H_ */ | ||
| 55 | 47 | ||
| 48 | #endif /* ASM_ARCH_IXP2000_GPIO_H_ */ | ||
diff --git a/include/asm-arm/arch-ixp2000/platform.h b/include/asm-arm/arch-ixp2000/platform.h index 901bba6d02b4..52ded516ea5c 100644 --- a/include/asm-arm/arch-ixp2000/platform.h +++ b/include/asm-arm/arch-ixp2000/platform.h | |||
| @@ -138,30 +138,10 @@ struct ixp2000_flash_data { | |||
| 138 | unsigned long (*bank_setup)(unsigned long); | 138 | unsigned long (*bank_setup)(unsigned long); |
| 139 | }; | 139 | }; |
| 140 | 140 | ||
| 141 | /* | ||
| 142 | * GPIO helper functions | ||
| 143 | */ | ||
| 144 | #define GPIO_IN 0 | ||
| 145 | #define GPIO_OUT 1 | ||
| 146 | |||
| 147 | extern void gpio_line_config(int line, int style); | ||
| 148 | |||
| 149 | static inline int gpio_line_get(int line) | ||
| 150 | { | ||
| 151 | return (((*IXP2000_GPIO_PLR) >> line) & 1); | ||
| 152 | } | ||
| 153 | |||
| 154 | static inline void gpio_line_set(int line, int value) | ||
| 155 | { | ||
| 156 | if (value) | ||
| 157 | ixp2000_reg_write(IXP2000_GPIO_POSR, (1 << line)); | ||
| 158 | else | ||
| 159 | ixp2000_reg_write(IXP2000_GPIO_POCR, (1 << line)); | ||
| 160 | } | ||
| 161 | |||
| 162 | struct ixp2000_i2c_pins { | 141 | struct ixp2000_i2c_pins { |
| 163 | unsigned long sda_pin; | 142 | unsigned long sda_pin; |
| 164 | unsigned long scl_pin; | 143 | unsigned long scl_pin; |
| 165 | }; | 144 | }; |
| 166 | 145 | ||
| 146 | |||
| 167 | #endif /* !__ASSEMBLY__ */ | 147 | #endif /* !__ASSEMBLY__ */ |
