Commit f647a274 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/home/rmk/linux-2.6-arm

parents 75043cb5 2966207c
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <asm/arch/gpio.h>
static DEFINE_SPINLOCK(ixp2000_slowport_lock); static DEFINE_SPINLOCK(ixp2000_slowport_lock);
static unsigned long ixp2000_slowport_irq_flags; static unsigned long ixp2000_slowport_irq_flags;
...@@ -238,33 +240,38 @@ void __init ixp2000_init_time(unsigned long tick_rate) ...@@ -238,33 +240,38 @@ void __init ixp2000_init_time(unsigned long tick_rate)
/************************************************************************* /*************************************************************************
* GPIO helpers * GPIO helpers
*************************************************************************/ *************************************************************************/
static unsigned long GPIO_IRQ_rising_edge;
static unsigned long GPIO_IRQ_falling_edge; static unsigned long GPIO_IRQ_falling_edge;
static unsigned long GPIO_IRQ_rising_edge;
static unsigned long GPIO_IRQ_level_low; static unsigned long GPIO_IRQ_level_low;
static unsigned long GPIO_IRQ_level_high; static unsigned long GPIO_IRQ_level_high;
void gpio_line_config(int line, int style) static void update_gpio_int_csrs(void)
{
ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge);
ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge);
ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low);
ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
}
void gpio_line_config(int line, int direction)
{ {
unsigned long flags; unsigned long flags;
local_irq_save(flags); local_irq_save(flags);
if (direction == GPIO_OUT) {
irq_desc[line + IRQ_IXP2000_GPIO0].valid = 0;
if(style == GPIO_OUT) {
/* if it's an output, it ain't an interrupt anymore */ /* if it's an output, it ain't an interrupt anymore */
ixp2000_reg_write(IXP2000_GPIO_PDSR, (1 << line));
GPIO_IRQ_falling_edge &= ~(1 << line); GPIO_IRQ_falling_edge &= ~(1 << line);
GPIO_IRQ_rising_edge &= ~(1 << line); GPIO_IRQ_rising_edge &= ~(1 << line);
GPIO_IRQ_level_low &= ~(1 << line); GPIO_IRQ_level_low &= ~(1 << line);
GPIO_IRQ_level_high &= ~(1 << line); GPIO_IRQ_level_high &= ~(1 << line);
ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge); update_gpio_int_csrs();
ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge);
ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low);
irq_desc[line+IRQ_IXP2000_GPIO0].valid = 0;
} else if(style == GPIO_IN) {
ixp2000_reg_write(IXP2000_GPIO_PDCR, (1 << line));
}
ixp2000_reg_write(IXP2000_GPIO_PDSR, 1 << line);
} else if (direction == GPIO_IN) {
ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line);
}
local_irq_restore(flags); local_irq_restore(flags);
} }
...@@ -285,9 +292,50 @@ static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc, str ...@@ -285,9 +292,50 @@ static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc, str
} }
} }
static int ixp2000_GPIO_irq_type(unsigned int irq, unsigned int type)
{
int line = irq - IRQ_IXP2000_GPIO0;
/*
* First, configure this GPIO line as an input.
*/
ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line);
/*
* Then, set the proper trigger type.
*/
if (type & IRQT_FALLING)
GPIO_IRQ_falling_edge |= 1 << line;
else
GPIO_IRQ_falling_edge &= ~(1 << line);
if (type & IRQT_RISING)
GPIO_IRQ_rising_edge |= 1 << line;
else
GPIO_IRQ_rising_edge &= ~(1 << line);
if (type & IRQT_LOW)
GPIO_IRQ_level_low |= 1 << line;
else
GPIO_IRQ_level_low &= ~(1 << line);
if (type & IRQT_HIGH)
GPIO_IRQ_level_high |= 1 << line;
else
GPIO_IRQ_level_high &= ~(1 << line);
update_gpio_int_csrs();
/*
* Finally, mark the corresponding IRQ as valid.
*/
irq_desc[irq].valid = 1;
return 0;
}
static void ixp2000_GPIO_irq_mask_ack(unsigned int irq) static void ixp2000_GPIO_irq_mask_ack(unsigned int irq)
{ {
ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0))); ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
ixp2000_reg_write(IXP2000_GPIO_LDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
ixp2000_reg_write(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0))); ixp2000_reg_write(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0)));
} }
...@@ -302,6 +350,7 @@ static void ixp2000_GPIO_irq_unmask(unsigned int irq) ...@@ -302,6 +350,7 @@ static void ixp2000_GPIO_irq_unmask(unsigned int irq)
} }
static struct irqchip ixp2000_GPIO_irq_chip = { static struct irqchip ixp2000_GPIO_irq_chip = {
.type = ixp2000_GPIO_irq_type,
.ack = ixp2000_GPIO_irq_mask_ack, .ack = ixp2000_GPIO_irq_mask_ack,
.mask = ixp2000_GPIO_irq_mask, .mask = ixp2000_GPIO_irq_mask,
.unmask = ixp2000_GPIO_irq_unmask .unmask = ixp2000_GPIO_irq_unmask
...@@ -375,7 +424,7 @@ void __init ixp2000_init_irq(void) ...@@ -375,7 +424,7 @@ void __init ixp2000_init_irq(void)
* our mask/unmask code much simpler. * our mask/unmask code much simpler.
*/ */
for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) { for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) {
if((1 << irq) & IXP2000_VALID_IRQ_MASK) { if ((1 << irq) & IXP2000_VALID_IRQ_MASK) {
set_irq_chip(irq, &ixp2000_irq_chip); set_irq_chip(irq, &ixp2000_irq_chip);
set_irq_handler(irq, do_level_IRQ); set_irq_handler(irq, do_level_IRQ);
set_irq_flags(irq, IRQF_VALID); set_irq_flags(irq, IRQF_VALID);
...@@ -384,7 +433,7 @@ void __init ixp2000_init_irq(void) ...@@ -384,7 +433,7 @@ void __init ixp2000_init_irq(void)
/* /*
* GPIO IRQs are invalid until someone sets the interrupt mode * GPIO IRQs are invalid until someone sets the interrupt mode
* by calling gpio_line_set(); * by calling set_irq_type().
*/ */
for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) { for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) {
set_irq_chip(irq, &ixp2000_GPIO_irq_chip); set_irq_chip(irq, &ixp2000_GPIO_irq_chip);
......
...@@ -141,7 +141,15 @@ static struct map_desc ixp4xx_io_desc[] __initdata = { ...@@ -141,7 +141,15 @@ static struct map_desc ixp4xx_io_desc[] __initdata = {
.physical = IXP4XX_PCI_CFG_BASE_PHYS, .physical = IXP4XX_PCI_CFG_BASE_PHYS,
.length = IXP4XX_PCI_CFG_REGION_SIZE, .length = IXP4XX_PCI_CFG_REGION_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
},
#ifdef CONFIG_DEBUG_LL
{ /* Debug UART mapping */
.virtual = IXP4XX_DEBUG_UART_BASE_VIRT,
.physical = IXP4XX_DEBUG_UART_BASE_PHYS,
.length = IXP4XX_DEBUG_UART_REGION_SIZE,
.type = MT_DEVICE
} }
#endif
}; };
void __init ixp4xx_map_io(void) void __init ixp4xx_map_io(void)
......
...@@ -132,8 +132,8 @@ ENTRY(cpu_v6_switch_mm) ...@@ -132,8 +132,8 @@ ENTRY(cpu_v6_switch_mm)
* 100x 1 0 1 r/o no acc * 100x 1 0 1 r/o no acc
* 10x0 1 0 1 r/o no acc * 10x0 1 0 1 r/o no acc
* 1011 0 0 1 r/w no acc * 1011 0 0 1 r/w no acc
* 110x 1 1 0 r/o r/o * 110x 0 1 0 r/w r/o
* 11x0 1 1 0 r/o r/o * 11x0 0 1 0 r/w r/o
* 1111 0 1 1 r/w r/w * 1111 0 1 1 r/w r/w
*/ */
ENTRY(cpu_v6_set_pte) ENTRY(cpu_v6_set_pte)
...@@ -150,7 +150,7 @@ ENTRY(cpu_v6_set_pte) ...@@ -150,7 +150,7 @@ ENTRY(cpu_v6_set_pte)
tst r1, #L_PTE_USER tst r1, #L_PTE_USER
orrne r2, r2, #AP1 | nG orrne r2, r2, #AP1 | nG
tstne r2, #APX tstne r2, #APX
eorne r2, r2, #AP0 bicne r2, r2, #APX | AP0
tst r1, #L_PTE_YOUNG tst r1, #L_PTE_YOUNG
biceq r2, r2, #APX | AP1 | AP0 biceq r2, r2, #APX | AP1 | AP0
......
...@@ -33,7 +33,8 @@ ...@@ -33,7 +33,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-algo-bit.h> #include <linux/i2c-algo-bit.h>
#include <asm/hardware.h> /* Pick up IXP42000-specific bits */ #include <asm/hardware.h> /* Pick up IXP2000-specific bits */
#include <asm/arch/gpio.h>
static inline int ixp2000_scl_pin(void *data) static inline int ixp2000_scl_pin(void *data)
{ {
......
/* /*
* include/asm-arm/arch-ixp2000/ixp2000-gpio.h * include/asm-arm/arch-ixp2000/gpio.h
* *
* Copyright (C) 2002 Intel Corporation. * Copyright (C) 2002 Intel Corporation.
* *
...@@ -16,26 +16,18 @@ ...@@ -16,26 +16,18 @@
* Use this instead of directly setting the GPIO registers. * Use this instead of directly setting the GPIO registers.
* GPIOs may also be used as GPIOs (e.g. for emulating i2c/smb) * GPIOs may also be used as GPIOs (e.g. for emulating i2c/smb)
*/ */
#ifndef _ASM_ARCH_IXP2000_GPIO_H_ #ifndef __ASM_ARCH_GPIO_H
#define _ASM_ARCH_IXP2000_GPIO_H_ #define __ASM_ARCH_GPIO_H
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#define GPIO_OUT 0x0
#define GPIO_IN 0x80 #define GPIO_IN 0
#define GPIO_OUT 1
#define IXP2000_GPIO_LOW 0 #define IXP2000_GPIO_LOW 0
#define IXP2000_GPIO_HIGH 1 #define IXP2000_GPIO_HIGH 1
#define GPIO_NO_EDGES 0 extern void gpio_line_config(int line, int direction);
#define GPIO_FALLING_EDGE 1
#define GPIO_RISING_EDGE 2
#define GPIO_BOTH_EDGES 3
#define GPIO_LEVEL_LOW 4
#define GPIO_LEVEL_HIGH 8
extern void set_GPIO_IRQ_edge(int gpio_nr, int edge);
extern void set_GPIO_IRQ_level(int gpio_nr, int level);
extern void gpio_line_config(int line, int style);
static inline int gpio_line_get(int line) static inline int gpio_line_get(int line)
{ {
...@@ -45,11 +37,12 @@ static inline int gpio_line_get(int line) ...@@ -45,11 +37,12 @@ static inline int gpio_line_get(int line)
static inline void gpio_line_set(int line, int value) static inline void gpio_line_set(int line, int value)
{ {
if (value == IXP2000_GPIO_HIGH) { if (value == IXP2000_GPIO_HIGH) {
ixp_reg_write(IXP2000_GPIO_POSR, BIT(line)); ixp2000_reg_write(IXP2000_GPIO_POSR, 1 << line);
} else if (value == IXP2000_GPIO_LOW) } else if (value == IXP2000_GPIO_LOW) {
ixp_reg_write(IXP2000_GPIO_POCR, BIT(line)); ixp2000_reg_write(IXP2000_GPIO_POCR, 1 << line);
}
} }
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#endif /* ASM_ARCH_IXP2000_GPIO_H_ */
#endif /* ASM_ARCH_IXP2000_GPIO_H_ */
...@@ -27,8 +27,8 @@ ...@@ -27,8 +27,8 @@
* since that isn't available on the A? revisions we just keep doing * since that isn't available on the A? revisions we just keep doing
* things manually. * things manually.
*/ */
#define alignb(addr) (void __iomem *)((unsigned long)addr ^ 3) #define alignb(addr) (void __iomem *)((unsigned long)(addr) ^ 3)
#define alignw(addr) (void __iomem *)((unsigned long)addr ^ 2) #define alignw(addr) (void __iomem *)((unsigned long)(addr) ^ 2)
#define outb(v,p) __raw_writeb((v),alignb(___io(p))) #define outb(v,p) __raw_writeb((v),alignb(___io(p)))
#define outw(v,p) __raw_writew((v),alignw(___io(p))) #define outw(v,p) __raw_writew((v),alignw(___io(p)))
...@@ -48,6 +48,78 @@ ...@@ -48,6 +48,78 @@
#define insw(p,d,l) __raw_readsw(alignw(___io(p)),d,l) #define insw(p,d,l) __raw_readsw(alignw(___io(p)),d,l)
#define insl(p,d,l) __raw_readsl(___io(p),d,l) #define insl(p,d,l) __raw_readsl(___io(p),d,l)
#define __is_io_address(p) ((((unsigned long)(p)) & ~(IXP2000_PCI_IO_SIZE - 1)) == IXP2000_PCI_IO_VIRT_BASE)
#define ioread8(p) \
({ \
unsigned int __v; \
\
if (__is_io_address(p)) { \
__v = __raw_readb(alignb(p)); \
} else { \
__v = __raw_readb(p); \
} \
\
__v; \
}) \
#define ioread16(p) \
({ \
unsigned int __v; \
\
if (__is_io_address(p)) { \
__v = __raw_readw(alignw(p)); \
} else { \
__v = le16_to_cpu(__raw_readw(p)); \
} \
\
__v; \
})
#define ioread32(p) \
({ \
unsigned int __v; \
\
if (__is_io_address(p)) { \
__v = __raw_readl(p); \
} else { \
__v = le32_to_cpu(__raw_readl(p)); \
} \
\
__v; \
})
#define iowrite8(v,p) \
({ \
if (__is_io_address(p)) { \
__raw_writeb((v), alignb(p)); \
} else { \
__raw_writeb((v), p); \
} \
})
#define iowrite16(v,p) \
({ \
if (__is_io_address(p)) { \
__raw_writew((v), alignw(p)); \
} else { \
__raw_writew(cpu_to_le16(v), p); \
} \
})
#define iowrite32(v,p) \
({ \
if (__is_io_address(p)) { \
__raw_writel((v), p); \
} else { \
__raw_writel(cpu_to_le32(v), p); \
} \
})
#define ioport_map(port, nr) ___io(port)
#define ioport_unmap(addr)
#ifdef CONFIG_ARCH_IXDP2X01 #ifdef CONFIG_ARCH_IXDP2X01
/* /*
......
...@@ -138,30 +138,10 @@ struct ixp2000_flash_data { ...@@ -138,30 +138,10 @@ struct ixp2000_flash_data {
unsigned long (*bank_setup)(unsigned long); unsigned long (*bank_setup)(unsigned long);
}; };
/*
* GPIO helper functions
*/
#define GPIO_IN 0
#define GPIO_OUT 1
extern void gpio_line_config(int line, int style);
static inline int gpio_line_get(int line)
{
return (((*IXP2000_GPIO_PLR) >> line) & 1);
}
static inline void gpio_line_set(int line, int value)
{
if (value)
ixp2000_reg_write(IXP2000_GPIO_POSR, (1 << line));
else
ixp2000_reg_write(IXP2000_GPIO_POCR, (1 << line));
}
struct ixp2000_i2c_pins { struct ixp2000_i2c_pins {
unsigned long sda_pin; unsigned long sda_pin;
unsigned long scl_pin; unsigned long scl_pin;
}; };
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
mrc p15, 0, \rx, c1, c0 mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ MMU enabled? tst \rx, #1 @ MMU enabled?
moveq \rx, #0xc8000000 moveq \rx, #0xc8000000
orrne \rx, \rx, #0x00b00000
movne \rx, #0xff000000 movne \rx, #0xff000000
add \rx,\rx,#3 @ Uart regs are at off set of 3 if add \rx,\rx,#3 @ Uart regs are at off set of 3 if
@ byte writes used - Big Endian. @ byte writes used - Big Endian.
......
...@@ -69,6 +69,16 @@ ...@@ -69,6 +69,16 @@
#define IXP4XX_PERIPHERAL_BASE_VIRT (0xFFBF2000) #define IXP4XX_PERIPHERAL_BASE_VIRT (0xFFBF2000)
#define IXP4XX_PERIPHERAL_REGION_SIZE (0x0000C000) #define IXP4XX_PERIPHERAL_REGION_SIZE (0x0000C000)
/*
* Debug UART
*
* This is basically a remap of UART1 into a region that is section
* aligned so that it * can be used with the low-level debug code.
*/
#define IXP4XX_DEBUG_UART_BASE_PHYS (0xC8000000)
#define IXP4XX_DEBUG_UART_BASE_VIRT (0xffb00000)
#define IXP4XX_DEBUG_UART_REGION_SIZE (0x00001000)
#define IXP4XX_EXP_CS0_OFFSET 0x00 #define IXP4XX_EXP_CS0_OFFSET 0x00
#define IXP4XX_EXP_CS1_OFFSET 0x04 #define IXP4XX_EXP_CS1_OFFSET 0x04
#define IXP4XX_EXP_CS2_OFFSET 0x08 #define IXP4XX_EXP_CS2_OFFSET 0x08
......
...@@ -275,6 +275,7 @@ extern void __iounmap(void __iomem *addr); ...@@ -275,6 +275,7 @@ extern void __iounmap(void __iomem *addr);
/* /*
* io{read,write}{8,16,32} macros * io{read,write}{8,16,32} macros
*/ */
#ifndef ioread8
#define ioread8(p) ({ unsigned int __v = __raw_readb(p); __v; }) #define ioread8(p) ({ unsigned int __v = __raw_readb(p); __v; })
#define ioread16(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(p)); __v; }) #define ioread16(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(p)); __v; })
#define ioread32(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(p)); __v; }) #define ioread32(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(p)); __v; })
...@@ -293,6 +294,7 @@ extern void __iounmap(void __iomem *addr); ...@@ -293,6 +294,7 @@ extern void __iounmap(void __iomem *addr);
extern void __iomem *ioport_map(unsigned long port, unsigned int nr); extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
extern void ioport_unmap(void __iomem *addr); extern void ioport_unmap(void __iomem *addr);
#endif
struct pci_dev; struct pci_dev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment