Commit d5a309c2 authored by Russell King's avatar Russell King

[ARM] EBSA110 I/O and decompressor fixes.

This fixes the buggy decompressor assembly, and fixes PCMCIA IO
to use the correct byte lane when accessing certain PCMCIA cards.
parent b4c06129
...@@ -94,6 +94,13 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000 ...@@ -94,6 +94,13 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000
machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
machine-$(CONFIG_ARCH_VERSATILE_PB) := versatile machine-$(CONFIG_ARCH_VERSATILE_PB) := versatile
ifeq ($(CONFIG_ARCH_EBSA110),y)
# This is what happens if you forget the IOCS16 line.
# PCMCIA cards stop working.
CFLAGS_3c589_cs.o :=-DISA_SIXTEEN_BIT_PERIPHERAL
export CFLAGS_3c589_cs.o
endif
TEXTADDR := $(textaddr-y) TEXTADDR := $(textaddr-y)
ifeq ($(incdir-y),) ifeq ($(incdir-y),)
incdir-y := $(machine-y) incdir-y := $(machine-y)
......
...@@ -139,7 +139,11 @@ EXPORT_SYMBOL(__writel); ...@@ -139,7 +139,11 @@ EXPORT_SYMBOL(__writel);
((p) >> 3) == (0x2f8 >> 3) || \ ((p) >> 3) == (0x2f8 >> 3) || \
((p) >> 3) == (0x378 >> 3)) ((p) >> 3) == (0x378 >> 3))
u8 __inb(int port) /*
* We're addressing an 8 or 16-bit peripheral which tranfers
* odd addresses on the low ISA byte lane.
*/
u8 __inb8(unsigned int port)
{ {
u32 ret; u32 ret;
...@@ -162,7 +166,31 @@ u8 __inb(int port) ...@@ -162,7 +166,31 @@ u8 __inb(int port)
return ret; return ret;
} }
u16 __inw(int port) /*
* We're addressing a 16-bit peripheral which transfers odd
* addresses on the high ISA byte lane.
*/
u8 __inb16(unsigned int port)
{
u32 ret;
/*
* The SuperIO registers use sane addressing techniques...
*/
if (SUPERIO_PORT(port))
ret = __raw_readb(ISAIO_BASE + (port << 2));
else {
u32 a = ISAIO_BASE + ((port & ~1) << 1);
/*
* Shame nothing else does
*/
ret = __raw_readb(a + (port & 1));
}
return ret;
}
u16 __inw(unsigned int port)
{ {
u32 ret; u32 ret;
...@@ -185,17 +213,27 @@ u16 __inw(int port) ...@@ -185,17 +213,27 @@ u16 __inw(int port)
return ret; return ret;
} }
u32 __inl(int port) /*
* Fake a 32-bit read with two 16-bit reads. Needed for 3c589.
*/
u32 __inl(unsigned int port)
{ {
u32 a;
if (SUPERIO_PORT(port) || port & 3)
BUG(); BUG();
return 0;
a = ISAIO_BASE + (port << 1);
return __raw_readw(a) | __raw_readw(a + 4) << 16;
} }
EXPORT_SYMBOL(__inb); EXPORT_SYMBOL(__inb8);
EXPORT_SYMBOL(__inb16);
EXPORT_SYMBOL(__inw); EXPORT_SYMBOL(__inw);
EXPORT_SYMBOL(__inl); EXPORT_SYMBOL(__inl);
void __outb(u8 val, int port) void __outb8(u8 val, unsigned int port)
{ {
/* /*
* The SuperIO registers use sane addressing techniques... * The SuperIO registers use sane addressing techniques...
...@@ -215,7 +253,24 @@ void __outb(u8 val, int port) ...@@ -215,7 +253,24 @@ void __outb(u8 val, int port)
} }
} }
void __outw(u16 val, int port) void __outb16(u8 val, unsigned int port)
{
/*
* The SuperIO registers use sane addressing techniques...
*/
if (SUPERIO_PORT(port))
__raw_writeb(val, ISAIO_BASE + (port << 2));
else {
u32 a = ISAIO_BASE + ((port & ~1) << 1);
/*
* Shame nothing else does
*/
__raw_writeb(val, a + (port & 1));
}
}
void __outw(u16 val, unsigned int port)
{ {
u32 off; u32 off;
...@@ -225,7 +280,7 @@ void __outw(u16 val, int port) ...@@ -225,7 +280,7 @@ void __outw(u16 val, int port)
if (SUPERIO_PORT(port)) if (SUPERIO_PORT(port))
off = port << 2; off = port << 2;
else { else {
off = (port & ~1) << 1; off = port << 1;
if (port & 1) if (port & 1)
BUG(); BUG();
...@@ -233,12 +288,13 @@ void __outw(u16 val, int port) ...@@ -233,12 +288,13 @@ void __outw(u16 val, int port)
__raw_writew(val, ISAIO_BASE + off); __raw_writew(val, ISAIO_BASE + off);
} }
void __outl(u32 val, int port) void __outl(u32 val, unsigned int port)
{ {
BUG(); BUG();
} }
EXPORT_SYMBOL(__outb); EXPORT_SYMBOL(__outb8);
EXPORT_SYMBOL(__outb16);
EXPORT_SYMBOL(__outw); EXPORT_SYMBOL(__outw);
EXPORT_SYMBOL(__outl); EXPORT_SYMBOL(__outl);
...@@ -315,12 +371,29 @@ void insw(unsigned int port, void *from, int len) ...@@ -315,12 +371,29 @@ void insw(unsigned int port, void *from, int len)
EXPORT_SYMBOL(outsw); EXPORT_SYMBOL(outsw);
EXPORT_SYMBOL(insw); EXPORT_SYMBOL(insw);
/*
* We implement these as 16-bit insw/outsw, mainly for
* 3c589 cards.
*/
void outsl(unsigned int port, const void *from, int len) void outsl(unsigned int port, const void *from, int len)
{ {
panic("outsl not supported on this architecture"); u32 off = port << 1;
if (SUPERIO_PORT(port) || port & 3)
BUG();
__raw_writesw(ISAIO_BASE + off, from, len << 1);
} }
void insl(unsigned int port, void *from, int len) void insl(unsigned int port, void *from, int len)
{ {
panic("insl not supported on this architecture"); u32 off = port << 1;
if (SUPERIO_PORT(port) || port & 3)
BUG();
__raw_readsw(ISAIO_BASE + off, from, len << 1);
} }
EXPORT_SYMBOL(outsl);
EXPORT_SYMBOL(insl);
...@@ -15,26 +15,44 @@ ...@@ -15,26 +15,44 @@
#define IO_SPACE_LIMIT 0xffff #define IO_SPACE_LIMIT 0xffff
u8 __inb(int port); u8 __inb8(unsigned int port);
u16 __inw(int port); void __outb8(u8 val, unsigned int port);
u32 __inl(int port);
#define inb(p) __inb(p) u8 __inb16(unsigned int port);
#define inw(p) __inw(p) void __outb16(u8 val, unsigned int port);
#define inl(p) __inl(p)
void __outb(u8 val, int port); u16 __inw(unsigned int port);
void __outw(u16 val, int port); void __outw(u16 val, unsigned int port);
void __outl(u32 val, int port);
#define outb(v,p) __outb(v,p) u32 __inl(unsigned int port);
#define outw(v,p) __outw(v,p) void __outl(u32 val, unsigned int port);
#define outl(v,p) __outl(v,p)
u8 __readb(void *addr); u8 __readb(void *addr);
u16 __readw(void *addr); u16 __readw(void *addr);
u32 __readl(void *addr); u32 __readl(void *addr);
void __writeb(u8 val, void *addr);
void __writew(u16 val, void *addr);
void __writel(u32 val, void *addr);
/*
* Argh, someone forgot the IOCS16 line. We therefore have to handle
* the byte stearing by selecting the correct byte IO functions here.
*/
#ifdef ISA_SIXTEEN_BIT_PERIPHERAL
#define inb(p) __inb16(p)
#define outb(v,p) __outb16(v,p)
#else
#define inb(p) __inb8(p)
#define outb(v,p) __outb8(v,p)
#endif
#define inw(p) __inw(p)
#define outw(v,p) __outw(v,p)
#define inl(p) __inl(p)
#define outl(v,p) __outl(v,p)
#define readb(b) __readb(b) #define readb(b) __readb(b)
#define readw(b) __readw(b) #define readw(b) __readw(b)
#define readl(b) __readl(b) #define readl(b) __readl(b)
...@@ -42,10 +60,6 @@ u32 __readl(void *addr); ...@@ -42,10 +60,6 @@ u32 __readl(void *addr);
#define readw_relaxed(addr) readw(addr) #define readw_relaxed(addr) readw(addr)
#define readl_relaxed(addr) readl(addr) #define readl_relaxed(addr) readl(addr)
void __writeb(u8 val, void *addr);
void __writew(u16 val, void *addr);
void __writel(u32 val, void *addr);
#define writeb(v,b) __writeb(v,b) #define writeb(v,b) __writeb(v,b)
#define writew(v,b) __writew(v,b) #define writew(v,b) __writew(v,b)
#define writel(v,b) __writel(v,b) #define writel(v,b) __writel(v,b)
...@@ -53,4 +67,12 @@ void __writel(u32 val, void *addr); ...@@ -53,4 +67,12 @@ void __writel(u32 val, void *addr);
#define __arch_ioremap(cookie,sz,c,a) ((void *)(cookie)) #define __arch_ioremap(cookie,sz,c,a) ((void *)(cookie))
#define __arch_iounmap(cookie) do { } while (0) #define __arch_iounmap(cookie) do { } while (0)
extern void insb(unsigned int port, void *buf, int sz);
extern void insw(unsigned int port, void *buf, int sz);
extern void insl(unsigned int port, void *buf, int sz);
extern void outsb(unsigned int port, const void *buf, int sz);
extern void outsw(unsigned int port, const void *buf, int sz);
extern void outsl(unsigned int port, const void *buf, int sz);
#endif #endif
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
*/ */
static void puts(const char *s) static void puts(const char *s)
{ {
unsigned long tmp1, tmp2;
__asm__ __volatile__( __asm__ __volatile__(
"ldrb %0, [%2], #1\n" "ldrb %0, [%2], #1\n"
" teq %0, #0\n" " teq %0, #0\n"
...@@ -32,7 +33,8 @@ static void puts(const char *s) ...@@ -32,7 +33,8 @@ static void puts(const char *s)
" and %1, %1, #0x60\n" " and %1, %1, #0x60\n"
" teq %1, #0x60\n" " teq %1, #0x60\n"
" bne 3b" " bne 3b"
: : "r" (0), "r" (0), "r" (s), "r" (0xf0000be0) : "cc"); : "=&r" (tmp1), "=&r" (tmp2)
: "r" (s), "r" (0xf0000be0) : "cc");
} }
/* /*
......
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