* turn external definitions of gsc_{read,write}[bwlq] into inline __raw_{read,write}[bwlq] * Add compatibility macros so I don't have to change all the drivers * Change eisa.c to have the same types as io.h has. * Move contents of busdevice.c into gsc.c. Delete busdevice.c. * Rename busdevice_init to gsc_init. The function returns! :-) * Change fb to use readb instead of gsc_readb (et al) * More void * -> unsigned long conversion * Remove warning from extable.c Index: arch/parisc/kernel/lba_pci.c =================================================================== RCS file: /var/cvs/linux/arch/parisc/kernel/lba_pci.c,v retrieving revision 1.42 diff -u -p -r1.42 lba_pci.c --- arch/parisc/kernel/lba_pci.c 2001/11/03 21:15:26 1.42 +++ arch/parisc/kernel/lba_pci.c 2001/11/03 22:45:17 @@ -1469,7 +1469,7 @@ void __init lba_init(void) void __init lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask) { - char * base_addr = lba->hpa; + unsigned long base_addr = lba->hpa; imask <<= 2; /* adjust for hints - 2 more bits */ Index: arch/parisc/kernel/parisc_ksyms.c =================================================================== RCS file: /var/cvs/linux/arch/parisc/kernel/parisc_ksyms.c,v retrieving revision 1.30 diff -u -p -r1.30 parisc_ksyms.c --- arch/parisc/kernel/parisc_ksyms.c 2001/10/29 19:06:49 1.30 +++ arch/parisc/kernel/parisc_ksyms.c 2001/11/03 22:45:17 @@ -80,16 +80,12 @@ EXPORT_SYMBOL_NOVERS($global$); #endif #include -EXPORT_SYMBOL(_gsc_writeb); -EXPORT_SYMBOL(_gsc_writew); -EXPORT_SYMBOL(_gsc_writel); -EXPORT_SYMBOL(_gsc_readb); -EXPORT_SYMBOL(_gsc_readw); -EXPORT_SYMBOL(_gsc_readl); EXPORT_SYMBOL(register_parisc_driver); EXPORT_SYMBOL(unregister_parisc_driver); -EXPORT_SYMBOL(gsc_alloc_irq); EXPORT_SYMBOL(pdc_iodc_read); +#ifdef CONFIG_GSC +EXPORT_SYMBOL(gsc_alloc_irq); +#endif #include EXPORT_SYMBOL(__ioremap); Index: arch/parisc/kernel/perf.c =================================================================== RCS file: /var/cvs/linux/arch/parisc/kernel/perf.c,v retrieving revision 1.4 diff -u -p -r1.4 perf.c --- arch/parisc/kernel/perf.c 2001/10/25 20:52:14 1.4 +++ arch/parisc/kernel/perf.c 2001/11/03 22:45:17 @@ -796,13 +796,13 @@ static int perf_write_image(uint64_t *me /* Merge intrigue bits into Runway STATUS 0 */ ptr64 = (uint64_t *)(proc_hpa + 0x10); /* Runway STATUS 0 */ - tmp64 = gsc_readq((u64 *)ptr64) & 0xffecffffffffffff; - gsc_writeq(tmp64 | (*memaddr++ & 0x0013000000000000), (u64 *)ptr64); + tmp64 = __raw_readq((u64 *)ptr64) & 0xffecffffffffffff; + __raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000), (u64 *)ptr64); /* Write RUNWAY DEBUG registers */ ptr64 = (uint64_t *)(proc_hpa + 0x40); /* Runway DEBUG 0 */ for (i = 0; i < 8; i++) { - gsc_writeq(*memaddr++, (u64 *)ptr64); + __raw_writeq(*memaddr++, (u64 *)ptr64); ptr64++; } Index: arch/parisc/kernel/sba_iommu.c =================================================================== RCS file: /var/cvs/linux/arch/parisc/kernel/sba_iommu.c,v retrieving revision 1.56 diff -u -p -r1.56 sba_iommu.c --- arch/parisc/kernel/sba_iommu.c 2001/11/03 21:15:26 1.56 +++ arch/parisc/kernel/sba_iommu.c 2001/11/03 22:45:17 @@ -197,7 +197,7 @@ struct ioc { - char *ioc_hpa; /* I/O MMU base address */ + unsigned long ioc_hpa; /* I/O MMU base address */ char *res_map; /* resource map, bit == pdir entry */ u64 *pdir_base; /* physical base address */ @@ -272,10 +272,10 @@ static unsigned long sba_mem_ratio = 4; ** ** Superdome (in particular, REO) allows only 64-bit CSR accesses. */ -#define READ_REG32(addr) le32_to_cpu(gsc_readl((u32 *) (addr))) -#define READ_REG64(addr) le64_to_cpu(gsc_readq((u64 *) (addr))) -#define WRITE_REG32(value, addr) gsc_writel(cpu_to_le32(value), (u32 *) (addr)) -#define WRITE_REG64(value, addr) gsc_writeq(cpu_to_le64(value), (u64 *) (addr)) +#define READ_REG32(addr) le32_to_cpu(__raw_readl(addr)) +#define READ_REG64(addr) le64_to_cpu(__raw_readq(addr)) +#define WRITE_REG32(val, addr) __raw_writel(cpu_to_le32(val), addr) +#define WRITE_REG64(val, addr) __raw_writeq(cpu_to_le64(val), addr) #ifdef __LP64__ #define READ_REG(addr) READ_REG64(addr) @@ -570,7 +570,7 @@ sba_alloc_range(struct ioc *ioc, size_t if (pide >= (ioc->res_size << 3)) { pide = sba_search_bitmap(ioc, pages_needed); if (pide >= (ioc->res_size << 3)) - panic(__FILE__ ": I/O MMU @ %p is out of mapping resources\n", ioc->ioc_hpa); + panic(__FILE__ ": I/O MMU @ %lx is out of mapping resources\n", ioc->ioc_hpa); } #ifdef ASSERT_PDIR_SANITY @@ -1490,7 +1490,7 @@ sba_ioc_init(struct parisc_device *sba, ioc->hint_shift_pdir, ioc->hint_mask_pdir); ASSERT((((unsigned long) pdir_base) & PAGE_MASK) == (unsigned long) pdir_base); - WRITE_REG64(virt_to_phys(pdir_base), (u64 *)(ioc->ioc_hpa+IOC_PDIR_BASE)); + WRITE_REG64(virt_to_phys(pdir_base), ioc->ioc_hpa + IOC_PDIR_BASE); DBG_INIT(" base %p\n", pdir_base); @@ -1576,7 +1576,7 @@ sba_hw_init(struct sba_device *sba_dev) if (IS_ASTRO(sba_dev->iodc)) { /* PAT_PDC (L-class) also reports the same goofy base */ - sba_dev->ioc[0].ioc_hpa = (char *) ASTRO_IOC_OFFSET; + sba_dev->ioc[0].ioc_hpa = ASTRO_IOC_OFFSET; num_ioc = 1; } else { sba_dev->ioc[0].ioc_hpa = sba_dev->ioc[1].ioc_hpa = 0; @@ -1585,7 +1585,7 @@ sba_hw_init(struct sba_device *sba_dev) sba_dev->num_ioc = num_ioc; for (i = 0; i < num_ioc; i++) { - (unsigned long) sba_dev->ioc[i].ioc_hpa += (unsigned long) sba_dev->sba_hpa + IKE_IOC_OFFSET(i); + sba_dev->ioc[i].ioc_hpa += sba_dev->sba_hpa + IKE_IOC_OFFSET(i); /* ** Make sure the box crashes if we get any errors on a rope. Index: arch/parisc/kernel/setup.c =================================================================== RCS file: /var/cvs/linux/arch/parisc/kernel/setup.c,v retrieving revision 1.95 diff -u -p -r1.95 setup.c --- arch/parisc/kernel/setup.c 2001/10/27 06:32:27 1.95 +++ arch/parisc/kernel/setup.c 2001/11/03 22:45:18 @@ -174,7 +174,7 @@ static void parisc_proc_mkdir(void) } } -extern void busdevices_init(void); +extern void gsc_init(void); extern void processor_init(void); extern void ccio_init(void); extern void dino_init(void); @@ -205,6 +205,8 @@ void __init parisc_init(void) #if defined(CONFIG_PCI_LBA) lba_init(); #endif + + /* CCIO before any potential subdevices */ #if defined(CONFIG_IOMMU_CCIO) ccio_init(); #endif @@ -214,9 +216,8 @@ void __init parisc_init(void) * regions. EISA must come before PCI to be sure it gets IRQ region * 0. */ -#if defined(CONFIG_GSC_LASI) || defined(CONFIG_GSC_DINO) \ - || defined(CONFIG_GSC_WAX) - busdevices_init(); +#if defined(CONFIG_GSC_LASI) || defined(CONFIG_GSC_WAX) + gsc_init(); #endif #ifdef CONFIG_EISA eisa_init(); Index: arch/parisc/kernel/smp.c =================================================================== RCS file: /var/cvs/linux/arch/parisc/kernel/smp.c,v retrieving revision 1.12 diff -u -p -r1.12 smp.c --- arch/parisc/kernel/smp.c 2001/09/06 09:44:07 1.12 +++ arch/parisc/kernel/smp.c 2001/11/03 22:45:18 @@ -268,7 +268,7 @@ ipi_send(int cpu, enum ipi_message_type spin_lock_irqsave(&(p->lock),flags); p->pending_ipi |= 1 << op; - gsc_writel(IRQ_OFFSET(IPI_IRQ), cpu_data[cpu].hpa); + __raw_writel(IRQ_OFFSET(IPI_IRQ), cpu_data[cpu].hpa); spin_unlock_irqrestore(&(p->lock),flags); } @@ -580,7 +580,7 @@ static int smp_boot_one_cpu(int cpuid, i ** This gets PDC to release the CPU from a very tight loop. ** See MEM_RENDEZ comments in head.S. */ - gsc_writel(IRQ_OFFSET(TIMER_IRQ), cpu_data[cpunum].hpa); + __raw_writel(IRQ_OFFSET(TIMER_IRQ), cpu_data[cpunum].hpa); mb(); /* Index: arch/parisc/mm/extable.c =================================================================== RCS file: /var/cvs/linux/arch/parisc/mm/extable.c,v retrieving revision 1.2 diff -u -p -r1.2 extable.c --- arch/parisc/mm/extable.c 2001/09/06 22:19:41 1.2 +++ arch/parisc/mm/extable.c 2001/11/03 22:45:18 @@ -52,11 +52,11 @@ search_exception_table (unsigned long ad __stop___ex_table - 1, addr); #else - struct exception_table_entry *ret; /* The kernel is the last "module" -- no need to treat it special. */ struct module *mp; for (mp = module_list; mp ; mp = mp->next) { + const struct exception_table_entry *ret; if (!mp->ex_table_start) continue; ret = search_one_table(mp->ex_table_start, mp->ex_table_end - 1, Index: drivers/gsc/Makefile =================================================================== RCS file: /var/cvs/linux/drivers/gsc/Makefile,v retrieving revision 1.12 diff -u -p -r1.12 Makefile --- drivers/gsc/Makefile 2001/10/17 20:02:29 1.12 +++ drivers/gsc/Makefile 2001/11/03 22:45:18 @@ -1,5 +1,5 @@ # -# Makefile for the HP Gecko (GSC) bus specific drivers. +# Makefile for most of the non-PCI devices in PA-RISC machines # # Note! Dependencies are done automagically by 'make dep', which also # removes any old dependencies. DON'T put your own dependencies here @@ -16,10 +16,9 @@ obj-m := obj-n := obj- := -obj-$(CONFIG_SUPERIO) += busdevice.o -obj-$(CONFIG_GSC_DINO) += busdevice.o dino.o -obj-$(CONFIG_GSC_LASI) += busdevice.o lasi.o asp.o -obj-$(CONFIG_GSC_WAX) += busdevice.o wax.o +obj-$(CONFIG_GSC_DINO) += dino.o +obj-$(CONFIG_GSC_LASI) += lasi.o asp.o +obj-$(CONFIG_GSC_WAX) += wax.o obj-$(CONFIG_SERIAL_GSC) += serial.o obj-$(CONFIG_EISA) += eisa.o Index: drivers/gsc/busdevice.c =================================================================== RCS file: busdevice.c diff -N busdevice.c --- /tmp/cvsLSoluv Sat Nov 3 15:45:21 2001 +++ /dev/null Thu Nov 30 14:01:38 2000 @@ -1,181 +0,0 @@ -/* - * LASI/ASP/WAX/EISA interrupt manager - * - * (c) Copyright 1999 Red Hat Software - * Portions (c) Copyright 1999 The Puffin Group Inc. - * Portions (c) Copyright 1999 Hewlett-Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * by Alan Cox and - * Alex deVries - * Helge Deller - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "busdevice.h" - - -#undef DEBUG - -#ifdef DEBUG -#define DEBPRINTK printk -#else -#define DEBPRINTK(x,...) -#endif - - -/* IRQ bits must be numbered from Most Significant Bit */ -#define BUSDEV_FIX_IRQ(x) (31-(x)) -#define BUSDEV_MASK_IRQ(x) (1<<(BUSDEV_FIX_IRQ(x))) - -/* Common interrupt demultiplexer used by Asp, Lasi & Wax. */ -void busdev_barked(int busdev_irq, void *dev, struct pt_regs *regs) -{ - unsigned long irq; - struct busdevice *busdev = (struct busdevice *) dev; - - /* - Don't need to protect OFFSET_IRR with spinlock since this is - the only place it's touched. - Protect busdev_region by disabling this region's interrupts, - modifying the region, and then re-enabling the region. - */ - - irq = gsc_readl(busdev->hpa+OFFSET_IRR); - if (irq == 0) { - printk(KERN_ERR "%s: barking without apparent reason.\n", busdev->name); - } else { - DEBPRINTK ("%s (0x%x) barked, mask=0x%x, irq=%d\n", - busdev->name, busdev->busdev_region->data.irqbase, - irq, BUSDEV_FIX_IRQ(ffs(irq))+1 ); - - do_irq_mask(irq, busdev->busdev_region, regs); - } -} - -static void -busdev_disable_irq(void *irq_dev, int irq) -{ - /* Disable the IRQ line by clearing the bit in the IMR */ - u32 imr = gsc_readl(BUSDEV_DEV(irq_dev)->hpa+OFFSET_IMR); - imr &= ~(BUSDEV_MASK_IRQ(irq)); - - DEBPRINTK( KERN_WARNING "%s(%p, %d) %s: IMR 0x%x\n", - __FUNCTION__, irq_dev, irq, BUSDEV_DEV(irq_dev)->name, imr); - - gsc_writel(imr, BUSDEV_DEV(irq_dev)->hpa+OFFSET_IMR); -} - - -static void -busdev_enable_irq(void *irq_dev, int irq) -{ - /* Enable the IRQ line by setting the bit in the IMR */ - char *addr = (char*) (BUSDEV_DEV(irq_dev)->hpa + OFFSET_IMR); - u32 imr = gsc_readl(addr); - imr |= BUSDEV_MASK_IRQ(irq); - - DEBPRINTK (KERN_WARNING "%s(%p, %d) %s: IMR 0x%x\n", - __FUNCTION__, irq_dev, irq, BUSDEV_DEV(irq_dev)->name, imr); - - gsc_writel(imr, addr); -// gsc_writel(~0L, addr); - -/* FIXME: read IPR to make sure the IRQ isn't already pending. -** If so, we need to read IRR and manually call do_irq_mask(). -** This code should be shared with busdev_unmask_irq(). -*/ -} - -static void -busdev_mask_irq(void *irq_dev, int irq) -{ -/* FIXME: Clear the IMR bit in busdev for that IRQ */ -} - -static void -busdev_unmask_irq(void *irq_dev, int irq) -{ -/* FIXME: Read IPR. Set the IMR bit in busdev for that IRQ. - call do_irq_mask() if IPR is non-zero -*/ -} - -struct irq_region_ops busdev_irq_ops = { - disable_irq: busdev_disable_irq, - enable_irq: busdev_enable_irq, - mask_irq: busdev_mask_irq, - unmask_irq: busdev_unmask_irq -}; - - -#define DEBUG_BUSDEVICE( dev ) \ - do { \ - printk(KERN_WARNING "%s IRQ %d EIM 0x%x", dev->name, dev->parent_irq, dev->eim); \ - if (gsc_readl(dev->hpa + OFFSET_IMR)) \ - printk(KERN_WARNING " IMR is non-zero! (0x%x)", gsc_readl(dev->hpa + OFFSET_IMR)); \ - printk("\n"); \ - } while (0) - - -int register_busdevice(struct parisc_device *gsc_parent, - struct busdevice *busdev) -{ - struct resource *res; - - busdev->gsc = gsc_parent; - - /* the IRQs we simulate */ - busdev->busdev_region = alloc_irq_region(32, &busdev_irq_ops, - IRQ_REG_MASK|IRQ_REG_DIS, busdev->name, busdev); - if (!busdev->busdev_region) - return (-ENOMEM); - - /* allocate resource region */ - res = kmalloc(sizeof(struct resource), GFP_KERNEL); - if (res) { - res->name = busdev->name; - res->start = busdev->hpa; - res->end = res->start + 0x100000 - 1; - res->flags = IORESOURCE_MEM; /* do not mark it busy ! */ - res->child = NULL; - request_resource(&iomem_resource, res); - request_mem_region(res->start, OFFSET_IAR + sizeof(int), "reserved"); - } - -#if 0 - DEBUG_BUSDEVICE( busdev ); -#endif - - return 0; -} - -extern struct parisc_driver lasi_driver; -extern struct parisc_driver asp_driver; -extern struct parisc_driver wax_driver; - -void __init busdevices_init(void) -{ -#ifdef CONFIG_GSC_LASI - register_parisc_driver(&lasi_driver); - register_parisc_driver(&asp_driver); -#endif -#ifdef CONFIG_GSC_WAX - register_parisc_driver(&wax_driver); -#endif -} Index: drivers/gsc/eisa.c =================================================================== RCS file: /var/cvs/linux/drivers/gsc/eisa.c,v retrieving revision 1.8 diff -u -p -r1.8 eisa.c --- drivers/gsc/eisa.c 2001/10/29 18:38:21 1.8 +++ drivers/gsc/eisa.c 2001/11/03 22:45:18 @@ -37,7 +37,7 @@ struct eisa_ba { /* Port ops */ -static inline unsigned long eisa_permute(u16 port) +static inline unsigned long eisa_permute(unsigned short port) { if (port & 0x300) { return 0xfc000000 | ((port & 0xfc00) >> 6) @@ -47,40 +47,40 @@ static inline unsigned long eisa_permute } } -u8 eisa_in8(u16 port) +unsigned char eisa_in8(unsigned short port) { if (EISA_bus) return gsc_readb(eisa_permute(port)); return 0xff; } -u16 eisa_in16(u16 port) +unsigned short eisa_in16(unsigned short port) { if (EISA_bus) return le16_to_cpu(gsc_readw(eisa_permute(port))); return 0xffff; } -u32 eisa_in32(u16 port) +unsigned int eisa_in32(unsigned short port) { if (EISA_bus) return le32_to_cpu(gsc_readl(eisa_permute(port))); return 0xffffffff; } -void eisa_out8(u8 data, u16 port) +void eisa_out8(unsigned char data, unsigned short port) { if (EISA_bus) gsc_writeb(data, eisa_permute(port)); } -void eisa_out16(u16 data, u16 port) +void eisa_out16(unsigned short data, unsigned short port) { if (EISA_bus) gsc_writew(cpu_to_le16(data), eisa_permute(port)); } -void eisa_out32(u32 data, u16 port) +void eisa_out32(unsigned int data, unsigned short port) { if (EISA_bus) gsc_writel(cpu_to_le32(data), eisa_permute(port)); Index: drivers/gsc/gsc.c =================================================================== RCS file: /var/cvs/linux/drivers/gsc/gsc.c,v retrieving revision 1.26 diff -u -p -r1.26 gsc.c --- drivers/gsc/gsc.c 2001/09/17 22:13:51 1.26 +++ drivers/gsc/gsc.c 2001/11/03 22:45:18 @@ -1,129 +1,46 @@ /* - * The Gecko device driver + * Interrupt management for most GSC and related devices. * - * (c) Copyright 1999 The Puffin Group Inc. - * (c) Copyright 1999 SuSE GmbH (Philipp Rumpf, prumpf@tux.org) + * (c) Copyright 1999 Alex deVries for The Puffin Group + * (c) Copyright 1999 Grant Grundler for Hewlett-Packard + * (c) Copyright 1999 Matthew Wilcox + * (c) Copyright 2000 Helge Deller + * (c) Copyright 2001 Matthew Wilcox for Hewlett-Packard * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * - * This is the GSC code. - * - * by Alex deVries - * */ +#include #include +#include #include -#include +#include +#include +#include +#include -#include +#include +#include #include #include -#include /* for boot_cpu_data */ - -u8 _gsc_readb(void *addr) -{ - long flags; - u8 ret; - - asm volatile( - " rsm 2,%0\n" - " ldbx 0(%2),%1\n" - " mtsm %0\n" - : "=&r" (flags), "=r" (ret) : "r" (addr) ); - - return ret; -} - -u16 _gsc_readw(void *addr) -{ - long flags; - u16 ret; - - asm volatile( - " rsm 2,%0\n" - " ldhx 0(%2),%1\n" - " mtsm %0\n" - : "=&r" (flags), "=r" (ret) : "r" (addr) ); - - return ret; -} - -u32 _gsc_readl(void *addr) -{ - u32 ret; - - asm volatile( - " ldwax 0(%1),%0\n" - : "=r" (ret) : "r" (addr) ); - - return ret; -} - -u64 _gsc_readq(void *addr) -{ - u64 ret; -#ifdef __LP64__ - asm volatile( - " ldda 0(%1),%0\n" - : "=r" (ret) : "r" (addr) ); -#else - /* two reads may have side effects.. */ - ret = _gsc_readl(addr); - ret <<= 32; - ret |= _gsc_readl(addr+4); -#endif - return ret; -} -void _gsc_writeb(u8 val, void *addr) -{ - long flags; - asm volatile( - " rsm 2,%0\n" - " stbs %1,0(%2)\n" - " mtsm %0\n" - : "=&r" (flags) : "r" (val), "r" (addr) ); -} - -void _gsc_writew(u16 val, void *addr) -{ - long flags; - asm volatile( - " rsm 2,%0\n" - " sths %1,0(%2)\n" - " mtsm %0\n" - : "=&r" (flags) : "r" (val), "r" (addr) ); -} +#include "busdevice.h" -void _gsc_writel(u32 val, void *addr) -{ - asm volatile( - " stwas %0,0(%1)\n" - : : "r" (val), "r" (addr) ); -} +#undef DEBUG -void _gsc_writeq(u64 val, void *addr) -{ -#ifdef __LP64__ - asm volatile( - " stda %0,0(%1)\n" - : : "r" (val), "r" (addr) ); +#ifdef DEBUG +#define DEBPRINTK printk #else - /* two writes may have side effects.. */ - _gsc_writel(val>>32, addr); - _gsc_writel(val, addr+4); +#define DEBPRINTK(x,...) #endif -} - int gsc_alloc_irq(struct gsc_irq *i) { int irq = txn_alloc_irq(); - if(irq < 0) { + if (irq < 0) { printk("cannot get irq\n"); return irq; } @@ -143,7 +60,7 @@ int gsc_claim_irq(struct gsc_irq *i, int irq += IRQ_FROM_REGION(CPU_IRQ_REGION); /* virtualize the IRQ first */ irq = txn_claim_irq(irq); - if(irq < 0) { + if (irq < 0) { printk("cannot claim irq %d\n", c); return irq; } @@ -153,4 +70,142 @@ int gsc_claim_irq(struct gsc_irq *i, int i->irq = irq; return irq; +} + + +/* IRQ bits must be numbered from Most Significant Bit */ +#define BUSDEV_FIX_IRQ(x) (31-(x)) +#define BUSDEV_MASK_IRQ(x) (1<<(BUSDEV_FIX_IRQ(x))) + +/* Common interrupt demultiplexer used by Asp, Lasi & Wax. */ +void busdev_barked(int busdev_irq, void *dev, struct pt_regs *regs) +{ + unsigned long irq; + struct busdevice *busdev = (struct busdevice *) dev; + + /* + Don't need to protect OFFSET_IRR with spinlock since this is + the only place it's touched. + Protect busdev_region by disabling this region's interrupts, + modifying the region, and then re-enabling the region. + */ + + irq = gsc_readl(busdev->hpa+OFFSET_IRR); + if (irq == 0) { + printk(KERN_ERR "%s: barking without apparent reason.\n", busdev->name); + } else { + DEBPRINTK ("%s (0x%x) barked, mask=0x%x, irq=%d\n", + busdev->name, busdev->busdev_region->data.irqbase, + irq, BUSDEV_FIX_IRQ(ffs(irq))+1 ); + + do_irq_mask(irq, busdev->busdev_region, regs); + } +} + +static void +busdev_disable_irq(void *irq_dev, int irq) +{ + /* Disable the IRQ line by clearing the bit in the IMR */ + u32 imr = gsc_readl(BUSDEV_DEV(irq_dev)->hpa+OFFSET_IMR); + imr &= ~(BUSDEV_MASK_IRQ(irq)); + + DEBPRINTK( KERN_WARNING "%s(%p, %d) %s: IMR 0x%x\n", + __FUNCTION__, irq_dev, irq, BUSDEV_DEV(irq_dev)->name, imr); + + gsc_writel(imr, BUSDEV_DEV(irq_dev)->hpa+OFFSET_IMR); +} + + +static void +busdev_enable_irq(void *irq_dev, int irq) +{ + /* Enable the IRQ line by setting the bit in the IMR */ + unsigned long addr = BUSDEV_DEV(irq_dev)->hpa + OFFSET_IMR; + u32 imr = gsc_readl(addr); + imr |= BUSDEV_MASK_IRQ(irq); + + DEBPRINTK (KERN_WARNING "%s(%p, %d) %s: IMR 0x%x\n", + __FUNCTION__, irq_dev, irq, BUSDEV_DEV(irq_dev)->name, imr); + + gsc_writel(imr, addr); +// gsc_writel(~0L, addr); + +/* FIXME: read IPR to make sure the IRQ isn't already pending. +** If so, we need to read IRR and manually call do_irq_mask(). +** This code should be shared with busdev_unmask_irq(). +*/ +} + +static void +busdev_mask_irq(void *irq_dev, int irq) +{ +/* FIXME: Clear the IMR bit in busdev for that IRQ */ +} + +static void +busdev_unmask_irq(void *irq_dev, int irq) +{ +/* FIXME: Read IPR. Set the IMR bit in busdev for that IRQ. + call do_irq_mask() if IPR is non-zero +*/ +} + +struct irq_region_ops busdev_irq_ops = { + disable_irq: busdev_disable_irq, + enable_irq: busdev_enable_irq, + mask_irq: busdev_mask_irq, + unmask_irq: busdev_unmask_irq +}; + + +int register_busdevice(struct parisc_device *gsc_parent, + struct busdevice *busdev) +{ + struct resource *res; + + busdev->gsc = gsc_parent; + + /* the IRQs we simulate */ + busdev->busdev_region = alloc_irq_region(32, &busdev_irq_ops, + IRQ_REG_MASK|IRQ_REG_DIS, busdev->name, busdev); + if (!busdev->busdev_region) + return -ENOMEM; + + /* allocate resource region */ + res = kmalloc(sizeof(struct resource), GFP_KERNEL); + if (res) { + res->name = busdev->name; + res->start = busdev->hpa; + res->end = res->start + 0xfffff; + res->flags = IORESOURCE_MEM; /* do not mark it busy ! */ + res->child = NULL; + request_resource(&iomem_resource, res); + request_mem_region(res->start, OFFSET_IAR + sizeof(int), "reserved"); + } + +#if 0 + printk(KERN_WARNING "%s IRQ %d EIM 0x%x", busdev->name, + busdev->parent_irq, busdev->eim); + if (gsc_readl(busdev->hpa + OFFSET_IMR)) + printk(" IMR is non-zero! (0x%x)", + gsc_readl(busdev->hpa + OFFSET_IMR)); + printk("\n"); +#endif + + return 0; +} + +extern struct parisc_driver lasi_driver; +extern struct parisc_driver asp_driver; +extern struct parisc_driver wax_driver; + +void __init gsc_init(void) +{ +#ifdef CONFIG_GSC_LASI + register_parisc_driver(&lasi_driver); + register_parisc_driver(&asp_driver); +#endif +#ifdef CONFIG_GSC_WAX + register_parisc_driver(&wax_driver); +#endif } Index: drivers/video/fbcon-sti.c =================================================================== RCS file: /var/cvs/linux/drivers/video/fbcon-sti.c,v retrieving revision 1.7 diff -u -p -r1.7 fbcon-sti.c --- drivers/video/fbcon-sti.c 2001/08/24 14:45:06 1.7 +++ drivers/video/fbcon-sti.c 2001/11/03 22:45:18 @@ -17,6 +17,7 @@ #include #include #include +#include /* for gsc_read/write */ #include #include