summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/ecard.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-05-07 02:55:41 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-05-07 02:55:41 +0000
commitdcec8a13bf565e47942a1751a9cec21bec5648fe (patch)
tree548b69625b18cc2e88c3e68d0923be546c9ebb03 /arch/arm/kernel/ecard.c
parent2e0f55e79c49509b7ff70ff1a10e1e9e90a3dfd4 (diff)
o Merge with Linux 2.1.99.
o Fix ancient bug in the ELF loader making ldd crash. o Fix ancient bug in the keyboard code for SGI, SNI and Jazz.
Diffstat (limited to 'arch/arm/kernel/ecard.c')
-rw-r--r--arch/arm/kernel/ecard.c100
1 files changed, 56 insertions, 44 deletions
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index cc18252b3..f03147e66 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -13,6 +13,7 @@
* now register their own routine to control interrupts (recommended).
* 29-Sep-1997 RMK Expansion card interrupt hardware not being re-enabled on reset from
* Linux. (Caused cards not to respond under RiscOS without hard reset).
+ * 15-Feb-1998 RMK Added DMA support
*/
#define ECARD_C
@@ -24,13 +25,14 @@
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/malloc.h>
+#include <linux/init.h>
-#include <asm/irq-no.h>
-#include <asm/ecard.h>
-#include <asm/irq.h>
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/arch/irq.h>
+#include <asm/ecard.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
#ifdef CONFIG_ARCH_ARC
#include <asm/arch/oldlatches.h>
@@ -59,9 +61,11 @@ static const struct expcard_blacklist {
BLACKLIST_LOADER(MANU_ATOMWIDE, PROD_ATOMWIDE_3PSERIAL, atomwide_serial_loader),
BLACKLIST_LOADER(MANU_OAK, PROD_OAK_SCSI, oak_scsi_loader),
+/* Supported cards with broken loader */
+ { MANU_ALSYSTEMS, PROD_ALSYS_SCSIATAPI, noloader, "AlSystems PowerTec SCSI (loader blacklisted)" },
+
/* Unsupported cards with no loader */
-BLACKLIST_NOLOADER(MANU_ALSYSTEMS, PROD_ALSYS_SCSIATAPI),
-BLACKLIST_NOLOADER(MANU_MCS, PROD_MCS_CONNECT32)
+ BLACKLIST_NOLOADER(MANU_MCS, PROD_MCS_CONNECT32)
};
extern int setup_arm_irq(int, struct irqaction *);
@@ -75,7 +79,6 @@ static ecard_t expcard[MAX_ECARDS];
static signed char irqno_to_expcard[16];
static unsigned int ecard_numcards, ecard_numirqcards;
static unsigned int have_expmask;
-static unsigned long kmem;
static void ecard_def_irq_enable (ecard_t *ec, int irqnr)
{
@@ -178,20 +181,6 @@ void ecard_disablefiq (unsigned int fiqnr)
}
}
-static void *ecard_malloc(int len)
-{
- int r;
-
- len = (len + 3) & ~3;
-
- if (kmem) {
- r = kmem;
- kmem += len;
- return (void *)r;
- } else
- return kmalloc(len, GFP_KERNEL);
-}
-
static void ecard_irq_noexpmask(int intr_no, void *dev_id, struct pt_regs *regs)
{
const int num_cards = ecard_numirqcards;
@@ -301,13 +290,13 @@ static void ecard_readbytes (void *addr, ecard_t *ec, int off, int len, int usel
lowaddress = 0;
}
while (lowaddress <= laddr) {
- byte = inb (ec->podaddr + haddr);
+ byte = inb(ec->podaddr + haddr);
lowaddress += 1;
}
while (len--) {
*a++ = byte;
if (len) {
- byte = inb (ec->podaddr + haddr);
+ byte = inb(ec->podaddr + haddr);
lowaddress += 1;
}
}
@@ -417,7 +406,7 @@ int ecard_readchunk (struct in_chunk_dir *cd, ecard_t *ec, int id, int num)
}
if (c_id(&excd) == 0x80) { /* loader */
if (!ec->loader) {
- ec->loader = (loader_t)ecard_malloc(c_len(&excd));
+ ec->loader = (loader_t)kmalloc(c_len(&excd), GFP_KERNEL);
ecard_readbytes(ec->loader, ec, (int)c_start(&excd), c_len(&excd), useld);
}
continue;
@@ -441,20 +430,39 @@ int ecard_readchunk (struct in_chunk_dir *cd, ecard_t *ec, int id, int num)
return 1;
}
-unsigned int ecard_address (ecard_t *ec, card_type_t memc, card_speed_t speed)
+unsigned int ecard_address (ecard_t *ec, card_type_t type, card_speed_t speed)
{
switch (ec->slot_no) {
case 0:
case 1:
case 2:
case 3:
- return (memc ? MEMCECIO_BASE : IOCECIO_BASE + (speed << 17)) + (ec->slot_no << 12);
+ switch (type) {
+ case ECARD_MEMC:
+ return MEMCECIO_BASE + (ec->slot_no << 12);
+
+ case ECARD_IOC:
+ return IOCECIO_BASE + (speed << 17) + (ec->slot_no << 12);
+
+ default:
+ return 0;
+ }
+
#ifdef IOCEC4IO_BASE
case 4:
case 5:
case 6:
case 7:
- return (memc ? 0 : IOCEC4IO_BASE + (speed << 17)) + ((ec->slot_no - 4) << 12);
+ switch (type) {
+ case ECARD_MEMC:
+ return 0;
+
+ case ECARD_IOC:
+ return IOCEC4IO_BASE + (speed << 17) + ((ec->slot_no - 4) << 12);
+
+ default:
+ return 0;
+ }
#endif
#ifdef MEMCEC8IO_BASE
case 8:
@@ -470,7 +478,7 @@ unsigned int ecard_address (ecard_t *ec, card_type_t memc, card_speed_t speed)
* If bit 1 of the first byte of the card is set,
* then the card does not exist.
*/
-static int ecard_probe (int card, int freeslot)
+__initfunc(static int ecard_probe (int card, int freeslot))
{
ecard_t *ec = expcard + freeslot;
struct ex_ecld excld;
@@ -480,7 +488,7 @@ static int ecard_probe (int card, int freeslot)
irqno_to_expcard[card] = -1;
ec->slot_no = card;
- if ((ec->podaddr = ecard_address (ec, 0, ECARD_SYNC)) == 0)
+ if ((ec->podaddr = ecard_address (ec, ECARD_IOC, ECARD_SYNC)) == 0)
return 0;
excld.r_ecld = 2;
@@ -490,8 +498,9 @@ static int ecard_probe (int card, int freeslot)
irqno_to_expcard[card] = freeslot;
- ec->irq = -1;
- ec->fiq = -1;
+ ec->irq = NO_IRQ;
+ ec->fiq = NO_IRQ;
+ ec->dma = NO_DMA;
ec->cld.ecld = e_ecld(&excld);
ec->cld.manufacturer = e_manu(&excld);
ec->cld.product = e_prod(&excld);
@@ -514,15 +523,20 @@ static int ecard_probe (int card, int freeslot)
break;
}
- if (card != 8) {
- ec->irq = 32 + card;
+ ec->irq = 32 + card;
#if 0
- ec->fiq = 96 + card;
+ /* We don't support FIQs on expansion cards at the moment */
+ ec->fiq = 96 + card;
#endif
- } else {
+#ifdef CONFIG_ARCH_RPC
+ if (card != 8) {
+ /* On RiscPC, only first two slots have DMA capability
+ */
+ if (card < 2)
+ ec->dma = 2 + card;
+ } else
ec->irq = 11;
- ec->fiq = -1;
- }
+#endif
if ((ec->cld.ecld & 0x78) == 0) {
struct in_chunk_dir incd;
@@ -551,11 +565,10 @@ static struct irqaction irqexpansioncard = { ecard_irq_noexpmask, SA_INTERRUPT,
* Locate all hardware - interrupt management and
* actual cards.
*/
-unsigned long ecard_init(unsigned long start_mem)
+__initfunc(void ecard_init(void))
{
int i, nc = 0;
- kmem = (start_mem | 3) & ~3;
memset (expcard, 0, sizeof (expcard));
#ifdef HAS_EXPMASK
@@ -565,6 +578,7 @@ unsigned long ecard_init(unsigned long start_mem)
have_expmask = -1;
}
#endif
+
printk("Installed expansion cards:");
/*
@@ -578,27 +592,25 @@ unsigned long ecard_init(unsigned long start_mem)
ecard_numirqcards = nc;
- /*
- * Now probe other cards with different interrupt lines
+ /* Now probe other cards with different interrupt lines
*/
#ifdef MEMCEC8IO_BASE
if (ecard_probe (8, nc))
nc += 1;
#endif
+
printk("\n");
ecard_numcards = nc;
if (nc && setup_arm_irq(IRQ_EXPANSIONCARD, &irqexpansioncard)) {
printk ("Could not allocate interrupt for expansion cards\n");
- return kmem;
+ return;
}
#ifdef HAS_EXPMASK
if (nc && have_expmask)
EXPMASK_ENABLE = have_expmask;
#endif
+
oldlatch_init ();
- start_mem = kmem;
- kmem = 0;
- return start_mem;
}