diff --git a/debian/changelog b/debian/changelog index 84771de67..f83199d59 100644 --- a/debian/changelog +++ b/debian/changelog @@ -48,6 +48,10 @@ linux-2.6 (2.6.23-1~experimental.1) UNRELEASED; urgency=low * [arm/iop32x] Enable Intel IOP ADMA support. * [arm] Mark BCM43XX as broken on ARM. * [mips/r4k-ip22] Disable EARLY PRINTK because it breaks serial console. + * Add some IP22 fixes from Thomas Bogendoerfer: + - Fix broken EISA interrupt setup by switching to generic i8259 + - Fix modules for 64bit kernels by using a CKSEG2 MAP_BASE + - Fix broken eeprom access by using __raw_readl/__raw_writel [ Bastian Blank ] * Add unpriviledged only Xen support. diff --git a/debian/patches/bugfix/mips/ip22-fix-64bit-modules.patch b/debian/patches/bugfix/mips/ip22-fix-64bit-modules.patch new file mode 100644 index 000000000..755334e2d --- /dev/null +++ b/debian/patches/bugfix/mips/ip22-fix-64bit-modules.patch @@ -0,0 +1,22 @@ + +Signed-off-by: Thomas Bogendoerfer +--- + include/asm-mips/mach-ip22/spaces.h | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/include/asm-mips/mach-ip22/spaces.h b/include/asm-mips/mach-ip22/spaces.h +index 7f9fa6f..8264d0a 100644 +--- a/include/asm-mips/mach-ip22/spaces.h ++++ b/include/asm-mips/mach-ip22/spaces.h +@@ -18,7 +18,7 @@ + #define CAC_BASE 0xffffffff80000000 + #define IO_BASE 0xffffffffa0000000 + #define UNCAC_BASE 0xffffffffa0000000 +-#define MAP_BASE 0xc000000000000000 ++#define MAP_BASE 0xffffffffc0000000 + + #endif /* CONFIG_64BIT */ + +-- +1.4.4.4 + diff --git a/debian/patches/bugfix/mips/ip22-fix-eisa-interrupt-setup.patch b/debian/patches/bugfix/mips/ip22-fix-eisa-interrupt-setup.patch new file mode 100644 index 000000000..b3ebe057a --- /dev/null +++ b/debian/patches/bugfix/mips/ip22-fix-eisa-interrupt-setup.patch @@ -0,0 +1,192 @@ + +Signed-off-by: Thomas Bogendoerfer +--- + arch/mips/Kconfig | 1 + + arch/mips/sgi-ip22/ip22-eisa.c | 134 +--------------------------------------- + 2 files changed, 3 insertions(+), 132 deletions(-) + +diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig +index 2f2ce0c..84059da 100644 +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -385,6 +385,7 @@ config SGI_IP22 + select DMA_NONCOHERENT + select HW_HAS_EISA + select I8253 ++ select I8259 + select IP22_CPU_SCACHE + select IRQ_CPU + select GENERIC_ISA_DMA_SUPPORT_BROKEN +diff --git a/arch/mips/sgi-ip22/ip22-eisa.c b/arch/mips/sgi-ip22/ip22-eisa.c +index 26854fb..1617241 100644 +--- a/arch/mips/sgi-ip22/ip22-eisa.c ++++ b/arch/mips/sgi-ip22/ip22-eisa.c +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + + /* I2 has four EISA slots. */ + #define IP22_EISA_MAX_SLOTS 4 +@@ -93,126 +94,11 @@ static irqreturn_t ip22_eisa_intr(int irq, void *dev_id) + return IRQ_NONE; + } + +-static void enable_eisa1_irq(unsigned int irq) +-{ +- u8 mask; +- +- mask = inb(EISA_INT1_MASK); +- mask &= ~((u8) (1 << irq)); +- outb(mask, EISA_INT1_MASK); +-} +- +-static unsigned int startup_eisa1_irq(unsigned int irq) +-{ +- u8 edge; +- +- /* Only use edge interrupts for EISA */ +- +- edge = inb(EISA_INT1_EDGE_LEVEL); +- edge &= ~((u8) (1 << irq)); +- outb(edge, EISA_INT1_EDGE_LEVEL); +- +- enable_eisa1_irq(irq); +- return 0; +-} +- +-static void disable_eisa1_irq(unsigned int irq) +-{ +- u8 mask; +- +- mask = inb(EISA_INT1_MASK); +- mask |= ((u8) (1 << irq)); +- outb(mask, EISA_INT1_MASK); +-} +- +-static void mask_and_ack_eisa1_irq(unsigned int irq) +-{ +- disable_eisa1_irq(irq); +- +- outb(0x20, EISA_INT1_CTRL); +-} +- +-static void end_eisa1_irq(unsigned int irq) +-{ +- if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) +- enable_eisa1_irq(irq); +-} +- +-static struct irq_chip ip22_eisa1_irq_type = { +- .name = "IP22 EISA", +- .startup = startup_eisa1_irq, +- .ack = mask_and_ack_eisa1_irq, +- .mask = disable_eisa1_irq, +- .mask_ack = mask_and_ack_eisa1_irq, +- .unmask = enable_eisa1_irq, +- .end = end_eisa1_irq, +-}; +- +-static void enable_eisa2_irq(unsigned int irq) +-{ +- u8 mask; +- +- mask = inb(EISA_INT2_MASK); +- mask &= ~((u8) (1 << (irq - 8))); +- outb(mask, EISA_INT2_MASK); +-} +- +-static unsigned int startup_eisa2_irq(unsigned int irq) +-{ +- u8 edge; +- +- /* Only use edge interrupts for EISA */ +- +- edge = inb(EISA_INT2_EDGE_LEVEL); +- edge &= ~((u8) (1 << (irq - 8))); +- outb(edge, EISA_INT2_EDGE_LEVEL); +- +- enable_eisa2_irq(irq); +- return 0; +-} +- +-static void disable_eisa2_irq(unsigned int irq) +-{ +- u8 mask; +- +- mask = inb(EISA_INT2_MASK); +- mask |= ((u8) (1 << (irq - 8))); +- outb(mask, EISA_INT2_MASK); +-} +- +-static void mask_and_ack_eisa2_irq(unsigned int irq) +-{ +- disable_eisa2_irq(irq); +- +- outb(0x20, EISA_INT2_CTRL); +-} +- +-static void end_eisa2_irq(unsigned int irq) +-{ +- if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) +- enable_eisa2_irq(irq); +-} +- +-static struct irq_chip ip22_eisa2_irq_type = { +- .name = "IP22 EISA", +- .startup = startup_eisa2_irq, +- .ack = mask_and_ack_eisa2_irq, +- .mask = disable_eisa2_irq, +- .mask_ack = mask_and_ack_eisa2_irq, +- .unmask = enable_eisa2_irq, +- .end = end_eisa2_irq, +-}; +- + static struct irqaction eisa_action = { + .handler = ip22_eisa_intr, + .name = "EISA", + }; + +-static struct irqaction cascade_action = { +- .handler = no_action, +- .name = "EISA cascade", +-}; +- + int __init ip22_eisa_init(void) + { + int i, c; +@@ -248,29 +134,13 @@ int __init ip22_eisa_init(void) + outb(1, EISA_EXT_NMI_RESET_CTRL); + udelay(50); /* Wait long enough for the dust to settle */ + outb(0, EISA_EXT_NMI_RESET_CTRL); +- outb(0x11, EISA_INT1_CTRL); +- outb(0x11, EISA_INT2_CTRL); +- outb(0, EISA_INT1_MASK); +- outb(8, EISA_INT2_MASK); +- outb(4, EISA_INT1_MASK); +- outb(2, EISA_INT2_MASK); +- outb(1, EISA_INT1_MASK); +- outb(1, EISA_INT2_MASK); +- outb(0xfb, EISA_INT1_MASK); +- outb(0xff, EISA_INT2_MASK); + outb(0, EISA_DMA2_WRITE_SINGLE); + +- for (i = SGINT_EISA; i < (SGINT_EISA + EISA_MAX_IRQ); i++) { +- if (i < (SGINT_EISA + 8)) +- set_irq_chip(i, &ip22_eisa1_irq_type); +- else +- set_irq_chip(i, &ip22_eisa2_irq_type); +- } ++ init_i8259_irqs(); + + /* Cannot use request_irq because of kmalloc not being ready at such + * an early stage. Yes, I've been bitten... */ + setup_irq(SGI_EISA_IRQ, &eisa_action); +- setup_irq(SGINT_EISA + 2, &cascade_action); + + EISA_bus = 1; + return 0; +-- +1.4.4.4 + diff --git a/debian/patches/bugfix/mips/ip22-fix-eprom-access.patch b/debian/patches/bugfix/mips/ip22-fix-eprom-access.patch new file mode 100644 index 000000000..2248588e4 --- /dev/null +++ b/debian/patches/bugfix/mips/ip22-fix-eprom-access.patch @@ -0,0 +1,89 @@ + +Signed-off-by: Thomas Bogendoerfer +--- + arch/mips/sgi-ip22/ip22-nvram.c | 40 ++++++++++++++++++++------------------ + 1 files changed, 21 insertions(+), 19 deletions(-) + +diff --git a/arch/mips/sgi-ip22/ip22-nvram.c b/arch/mips/sgi-ip22/ip22-nvram.c +index e19d60d..0177566 100644 +--- a/arch/mips/sgi-ip22/ip22-nvram.c ++++ b/arch/mips/sgi-ip22/ip22-nvram.c +@@ -32,19 +32,19 @@ + for (x=0; x<100000; x++) __asm__ __volatile__(""); }) + + #define eeprom_cs_on(ptr) ({ \ +- *ptr &= ~EEPROM_DATO; \ +- *ptr &= ~EEPROM_ECLK; \ +- *ptr &= ~EEPROM_EPROT; \ +- delay(); \ +- *ptr |= EEPROM_CSEL; \ +- *ptr |= EEPROM_ECLK; }) ++ __raw_writel(__raw_readl(ptr) & ~EEPROM_DATO, ptr); \ ++ __raw_writel(__raw_readl(ptr) & ~EEPROM_ECLK, ptr); \ ++ __raw_writel(__raw_readl(ptr) & ~EEPROM_EPROT, ptr); \ ++ delay(); \ ++ __raw_writel(__raw_readl(ptr) | EEPROM_CSEL, ptr); \ ++ __raw_writel(__raw_readl(ptr) | EEPROM_ECLK, ptr); }) + + + #define eeprom_cs_off(ptr) ({ \ +- *ptr &= ~EEPROM_ECLK; \ +- *ptr &= ~EEPROM_CSEL; \ +- *ptr |= EEPROM_EPROT; \ +- *ptr |= EEPROM_ECLK; }) ++ __raw_writel(__raw_readl(ptr) & ~EEPROM_ECLK, ptr); \ ++ __raw_writel(__raw_readl(ptr) & ~EEPROM_CSEL, ptr); \ ++ __raw_writel(__raw_readl(ptr) | EEPROM_EPROT, ptr); \ ++ __raw_writel(__raw_readl(ptr) | EEPROM_ECLK, ptr); }) + + #define BITS_IN_COMMAND 11 + /* +@@ -60,15 +60,17 @@ static inline void eeprom_cmd(unsigned int *ctrl, unsigned cmd, unsigned reg) + ser_cmd = cmd | (reg << (16 - BITS_IN_COMMAND)); + for (i = 0; i < BITS_IN_COMMAND; i++) { + if (ser_cmd & (1<<15)) /* if high order bit set */ +- writel(readl(ctrl) | EEPROM_DATO, ctrl); ++ __raw_writel(__raw_readl(ctrl) | EEPROM_DATO, ctrl); + else +- writel(readl(ctrl) & ~EEPROM_DATO, ctrl); +- writel(readl(ctrl) & ~EEPROM_ECLK, ctrl); +- writel(readl(ctrl) | EEPROM_ECLK, ctrl); ++ __raw_writel(__raw_readl(ctrl) & ~EEPROM_DATO, ctrl); ++ __raw_writel(__raw_readl(ctrl) & ~EEPROM_ECLK, ctrl); ++ delay(); ++ __raw_writel(__raw_readl(ctrl) | EEPROM_ECLK, ctrl); ++ delay(); + ser_cmd <<= 1; + } + /* see data sheet timing diagram */ +- writel(readl(ctrl) & ~EEPROM_DATO, ctrl); ++ __raw_writel(__raw_readl(ctrl) & ~EEPROM_DATO, ctrl); + } + + unsigned short ip22_eeprom_read(unsigned int *ctrl, int reg) +@@ -76,18 +78,18 @@ unsigned short ip22_eeprom_read(unsigned int *ctrl, int reg) + unsigned short res = 0; + int i; + +- writel(readl(ctrl) & ~EEPROM_EPROT, ctrl); ++ __raw_writel(__raw_readl(ctrl) & ~EEPROM_EPROT, ctrl); + eeprom_cs_on(ctrl); + eeprom_cmd(ctrl, EEPROM_READ, reg); + + /* clock the data ouf of serial mem */ + for (i = 0; i < 16; i++) { +- writel(readl(ctrl) & ~EEPROM_ECLK, ctrl); ++ __raw_writel(__raw_readl(ctrl) & ~EEPROM_ECLK, ctrl); + delay(); +- writel(readl(ctrl) | EEPROM_ECLK, ctrl); ++ __raw_writel(__raw_readl(ctrl) | EEPROM_ECLK, ctrl); + delay(); + res <<= 1; +- if (readl(ctrl) & EEPROM_DATI) ++ if (__raw_readl(ctrl) & EEPROM_DATI) + res |= 1; + } + +-- +1.4.4.4 + diff --git a/debian/patches/series/1~experimental.1 b/debian/patches/series/1~experimental.1 index f49d81403..c7bcf8b9e 100644 --- a/debian/patches/series/1~experimental.1 +++ b/debian/patches/series/1~experimental.1 @@ -18,6 +18,9 @@ + bugfix/mips/cobalt-ide-resources.patch + bugfix/mips/bcm1480-pci-build-fix.patch + bugfix/mips/ip22-disable-early-printk.patch ++ bugfix/mips/ip22-fix-eisa-interrupt-setup.patch ++ bugfix/mips/ip22-fix-64bit-modules.patch ++ bugfix/mips/ip22-fix-eprom-access.patch + features/arm/ixp4xx-npe-driver-0.3.1.patch + features/arm/ixp4xx-net-driver-improve-mac-handling.patch + features/arm/nslu2-i2c-gpio-driver-support.patch