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
machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
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)
ifeq ($(incdir-y),)
incdir-y := $(machine-y)
......
......@@ -139,7 +139,11 @@ EXPORT_SYMBOL(__writel);
((p) >> 3) == (0x2f8 >> 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;
......@@ -162,7 +166,31 @@ u8 __inb(int port)
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;
......@@ -185,17 +213,27 @@ u16 __inw(int port)
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();
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(__inl);
void __outb(u8 val, int port)
void __outb8(u8 val, unsigned int port)
{
/*
* The SuperIO registers use sane addressing techniques...
......@@ -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;
......@@ -225,7 +280,7 @@ void __outw(u16 val, int port)
if (SUPERIO_PORT(port))
off = port << 2;
else {
off = (port & ~1) << 1;
off = port << 1;
if (port & 1)
BUG();
......@@ -233,12 +288,13 @@ void __outw(u16 val, int port)
__raw_writew(val, ISAIO_BASE + off);
}
void __outl(u32 val, int port)
void __outl(u32 val, unsigned int port)
{
BUG();
}
EXPORT_SYMBOL(__outb);
EXPORT_SYMBOL(__outb8);
EXPORT_SYMBOL(__outb16);
EXPORT_SYMBOL(__outw);
EXPORT_SYMBOL(__outl);
......@@ -315,12 +371,29 @@ void insw(unsigned int port, void *from, int len)
EXPORT_SYMBOL(outsw);
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)
{
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)
{
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 @@
#define IO_SPACE_LIMIT 0xffff
u8 __inb(int port);
u16 __inw(int port);
u32 __inl(int port);
u8 __inb8(unsigned int port);
void __outb8(u8 val, unsigned int port);
#define inb(p) __inb(p)
#define inw(p) __inw(p)
#define inl(p) __inl(p)
u8 __inb16(unsigned int port);
void __outb16(u8 val, unsigned int port);
void __outb(u8 val, int port);
void __outw(u16 val, int port);
void __outl(u32 val, int port);
u16 __inw(unsigned int port);
void __outw(u16 val, unsigned int port);
#define outb(v,p) __outb(v,p)
#define outw(v,p) __outw(v,p)
#define outl(v,p) __outl(v,p)
u32 __inl(unsigned int port);
void __outl(u32 val, unsigned int port);
u8 __readb(void *addr);
u16 __readw(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 readw(b) __readw(b)
#define readl(b) __readl(b)
......@@ -42,10 +60,6 @@ u32 __readl(void *addr);
#define readw_relaxed(addr) readw(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 writew(v,b) __writew(v,b)
#define writel(v,b) __writel(v,b)
......@@ -53,4 +67,12 @@ void __writel(u32 val, void *addr);
#define __arch_ioremap(cookie,sz,c,a) ((void *)(cookie))
#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
......@@ -13,6 +13,7 @@
*/
static void puts(const char *s)
{
unsigned long tmp1, tmp2;
__asm__ __volatile__(
"ldrb %0, [%2], #1\n"
" teq %0, #0\n"
......@@ -32,7 +33,8 @@ static void puts(const char *s)
" and %1, %1, #0x60\n"
" teq %1, #0x60\n"
" 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