X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fparisc%2Feisa.c;h=e97cecbc4d183e6b0772e824747e2de8d4341e69;hb=refs%2Fheads%2Fvserver;hp=5ebc32b77f0ed00338d5b934916503e3eb94de11;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c index 5ebc32b77..e97cecbc4 100644 --- a/drivers/parisc/eisa.c +++ b/drivers/parisc/eisa.c @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include #include @@ -44,6 +44,7 @@ #include #include #include +#include #if 0 #define EISA_DBG(msg, arg... ) printk(KERN_DEBUG "eisa: " msg , ## arg ) @@ -54,7 +55,9 @@ #define SNAKES_EEPROM_BASE_ADDR 0xF0810400 #define MIRAGE_EEPROM_BASE_ADDR 0xF00C0400 -static spinlock_t eisa_irq_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(eisa_irq_lock); + +void __iomem *eisa_eeprom_addr __read_mostly; /* We can only have one EISA adapter in the system because neither * implementation can be flexed. @@ -138,11 +141,11 @@ static int slave_mask; * in the furure. */ /* irq 13,8,2,1,0 must be edge */ -static unsigned int eisa_irq_level; /* default to edge triggered */ +static unsigned int eisa_irq_level __read_mostly; /* default to edge triggered */ /* called by free irq */ -static void eisa_disable_irq(void *irq_dev, int irq) +static void eisa_disable_irq(unsigned int irq) { unsigned long flags; @@ -162,7 +165,7 @@ static void eisa_disable_irq(void *irq_dev, int irq) } /* called by request irq */ -static void eisa_enable_irq(void *irq_dev, int irq) +static void eisa_enable_irq(unsigned int irq) { unsigned long flags; EISA_DBG("enable irq %d\n", irq); @@ -180,52 +183,24 @@ static void eisa_enable_irq(void *irq_dev, int irq) EISA_DBG("pic1 mask %02x\n", eisa_in8(0xa1)); } -static void eisa_mask_irq(void *irq_dev, int irq) +static unsigned int eisa_startup_irq(unsigned int irq) { - unsigned long flags; - EISA_DBG("mask irq %d\n", irq); - - /* mask irq */ - spin_lock_irqsave(&eisa_irq_lock, flags); - if (irq & 8) { - slave_mask |= (1 << (irq&7)); - eisa_out8(slave_mask, 0xa1); - } else { - master_mask |= (1 << (irq&7)); - eisa_out8(master_mask, 0x21); - } - spin_unlock_irqrestore(&eisa_irq_lock, flags); -} - -static void eisa_unmask_irq(void *irq_dev, int irq) -{ - unsigned long flags; - EISA_DBG("unmask irq %d\n", irq); - - /* unmask */ - spin_lock_irqsave(&eisa_irq_lock, flags); - if (irq & 8) { - slave_mask &= ~(1 << (irq&7)); - eisa_out8(slave_mask, 0xa1); - } else { - master_mask &= ~(1 << (irq&7)); - eisa_out8(master_mask, 0x21); - } - spin_unlock_irqrestore(&eisa_irq_lock, flags); + eisa_enable_irq(irq); + return 0; } -static struct irqaction action[IRQ_PER_REGION]; - -/* EISA needs to be fixed at IRQ region #0 (EISA_IRQ_REGION) */ -static struct irq_region eisa_irq_region = { - .ops = { eisa_disable_irq, eisa_enable_irq, eisa_mask_irq, eisa_unmask_irq }, - .data = { .name = "EISA", .irqbase = 0 }, - .action = action, +static struct hw_interrupt_type eisa_interrupt_type = { + .typename = "EISA", + .startup = eisa_startup_irq, + .shutdown = eisa_disable_irq, + .enable = eisa_enable_irq, + .disable = eisa_disable_irq, + .ack = no_ack_irq, + .end = no_end_irq, }; -static irqreturn_t eisa_irq(int _, void *intr_dev, struct pt_regs *regs) +static irqreturn_t eisa_irq(int wax_irq, void *intr_dev) { - extern void do_irq(struct irqaction *a, int i, struct pt_regs *p); int irq = gsc_readb(0xfc01f000); /* EISA supports 16 irqs */ unsigned long flags; @@ -259,8 +234,7 @@ static irqreturn_t eisa_irq(int _, void *intr_dev, struct pt_regs *regs) } spin_unlock_irqrestore(&eisa_irq_lock, flags); - - do_irq(&eisa_irq_region.action[irq], EISA_IRQ_REGION + irq, regs); + __do_IRQ(irq); spin_lock_irqsave(&eisa_irq_lock, flags); /* unmask */ @@ -275,12 +249,17 @@ static irqreturn_t eisa_irq(int _, void *intr_dev, struct pt_regs *regs) return IRQ_HANDLED; } -static irqreturn_t dummy_irq2_handler(int _, void *dev, struct pt_regs *regs) +static irqreturn_t dummy_irq2_handler(int _, void *dev) { printk(KERN_ALERT "eisa: uhh, irq2?\n"); return IRQ_HANDLED; } +static struct irqaction irq2_action = { + .handler = dummy_irq2_handler, + .name = "cascade", +}; + static void init_eisa_pic(void) { unsigned long flags; @@ -331,12 +310,12 @@ static void init_eisa_pic(void) static int __devinit eisa_probe(struct parisc_device *dev) { - int result; + int i, result; char *name = is_mongoose(dev) ? "Mongoose" : "Wax"; printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n", - name, dev->hpa); + name, dev->hpa.start); eisa_dev.hba.dev = dev; eisa_dev.hba.iommu = ccio_get_iommu(dev); @@ -361,20 +340,21 @@ static int __devinit eisa_probe(struct parisc_device *dev) } pcibios_register_hba(&eisa_dev.hba); - result = request_irq(dev->irq, eisa_irq, SA_SHIRQ, "EISA", NULL); + result = request_irq(dev->irq, eisa_irq, IRQF_SHARED, "EISA", &eisa_dev); if (result) { printk(KERN_ERR "EISA: request_irq failed!\n"); return result; } /* Reserve IRQ2 */ - action[2].handler = dummy_irq2_handler; - action[2].name = "cascade"; + irq_desc[2].action = &irq2_action; - eisa_irq_region.data.dev = dev; - irq_region[0] = &eisa_irq_region; + for (i = 0; i < 16; i++) { + irq_desc[i].chip = &eisa_interrupt_type; + } EISA_bus = 1; + if (dev->num_addrs) { /* newer firmware hand out the eeprom address */ eisa_dev.eeprom_addr = dev->addr[0]; @@ -386,8 +366,9 @@ static int __devinit eisa_probe(struct parisc_device *dev) eisa_dev.eeprom_addr = MIRAGE_EEPROM_BASE_ADDR; } } - eisa_eeprom_init(eisa_dev.eeprom_addr); - result = eisa_enumerator(eisa_dev.eeprom_addr, &eisa_dev.hba.io_space, &eisa_dev.hba.lmmio_space); + eisa_eeprom_addr = ioremap_nocache(eisa_dev.eeprom_addr, HPEE_MAX_LENGTH); + result = eisa_enumerator(eisa_dev.eeprom_addr, &eisa_dev.hba.io_space, + &eisa_dev.hba.lmmio_space); init_eisa_pic(); if (result >= 0) { @@ -416,7 +397,7 @@ static struct parisc_device_id eisa_tbl[] = { MODULE_DEVICE_TABLE(parisc, eisa_tbl); static struct parisc_driver eisa_driver = { - .name = "EISA Bus Adapter", + .name = "eisa_ba", .id_table = eisa_tbl, .probe = eisa_probe, };