
 * 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 <asm/gsc.h>
-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 <asm/io.h>
 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 <alan@redhat.com> and 
- * 	   Alex deVries <adevries@thepuffingroup.com>
- *	   Helge Deller <deller@gmx.de>
- */
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/bitops.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <asm/io.h>
-#include <asm/hardware.h>
-#include <asm/gsc.h>
-
-#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 <adevries@thepuffingroup.com>
- * 
  */
 
+#include <linux/bitops.h>
 #include <linux/config.h>
+#include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/proc_fs.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/types.h>
 
-#include <asm/led.h>
+#include <asm/gsc.h>
+#include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/processor.h>	/* 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 <linux/string.h>
 #include <linux/fb.h>
 #include <linux/delay.h>
+#include <asm/gsc.h>		/* for gsc_read/write */
 #include <asm/types.h>
 
 #include <video/fbcon.h>
Index: drivers/video/sti/sticore.c
===================================================================
RCS file: /var/cvs/linux/drivers/video/sti/sticore.c,v
retrieving revision 1.26
diff -u -p -r1.26 sticore.c
--- drivers/video/sti/sticore.c	2001/10/15 00:46:01	1.26
+++ drivers/video/sti/sticore.c	2001/11/03 22:45:18
@@ -26,7 +26,7 @@
 #include <video/font.h>
 
 #include <asm/pgalloc.h>
-#include <asm/io.h>
+#include <asm/gsc.h>
 #include <asm/hardware.h>
 
 #include "sticore.h"
Index: drivers/video/sti/stifb.c
===================================================================
RCS file: /var/cvs/linux/drivers/video/sti/stifb.c,v
retrieving revision 1.23
diff -u -p -r1.23 stifb.c
--- drivers/video/sti/stifb.c	2001/10/14 18:28:33	1.23
+++ drivers/video/sti/stifb.c	2001/11/03 22:45:18
@@ -72,6 +72,7 @@
 #include <video/fbcon-cfb32.h>
 
 #include <asm/grfioctl.h>	/* for HP-UX compatibility */
+#include <asm/gsc.h>		/* for gsc_readb */
 
 #include "sticore.h"
 
Index: include/asm-parisc/gsc.h
===================================================================
RCS file: /var/cvs/linux/include/asm-parisc/gsc.h,v
retrieving revision 1.12
diff -u -p -r1.12 gsc.h
--- include/asm-parisc/gsc.h	2001/10/29 18:38:21	1.12
+++ include/asm-parisc/gsc.h	2001/11/03 22:45:19
@@ -3,42 +3,17 @@
 #ifdef __KERNEL__
 
 #include <linux/types.h>
-#include <asm/hardware.h>	/* for struct parisc_device */
+#include <asm/io.h> /* temporary for __raw_{read,write} */
 
-/*
- * The convention used for inb/outb etc. is that names starting with
- * two underscores are the inline versions, names starting with a
- * single underscore are proper functions, and names starting with a
- * letter are macros that map in some way to inline or proper function
- * versions.  Not all that pretty, but before you change it, be sure
- * to convince yourself that it won't break anything (in particular
- * module support).
+/* Please, call ioremap and use {read,write}[bwl] instead.  These functions
+ * are not very fast.
  */
-extern   u8 _gsc_readb(void *);
-extern  u16 _gsc_readw(void *);
-extern  u32 _gsc_readl(void *);
-extern  u64 _gsc_readq(void *);
-extern void _gsc_writeb(u8, void *);
-extern void _gsc_writew(u16,void *);
-extern void _gsc_writel(u32,void *);
-extern void _gsc_writeq(u64,void *);
-
-#define gsc_readb(a)	_gsc_readb((void *)(a))
-#define gsc_readw(a)	_gsc_readw((void *)(a))
-#define gsc_readl(a)	_gsc_readl((void *)(a))
-#define gsc_readq(a)	_gsc_readq((void *)(a))
-#define gsc_writeb(v,a)	_gsc_writeb((v),(void *)(a))
-#define gsc_writew(v,a)	_gsc_writew((v),(void *)(a))
-#define gsc_writel(v,a)	_gsc_writel((v),(void *)(a))
-#define gsc_writeq(v,a)	_gsc_writeq((v),(void *)(a))
-
-static __inline__ void *gsc_memset_io(void *s, int c, size_t n)
-{
-	while (n--) {
-		gsc_writeb(c,s++);
-	}
-	return NULL;
-}
+#define gsc_readb(x) __raw_readb((unsigned long)x)
+#define gsc_readw(x) __raw_readw((unsigned long)x)
+#define gsc_readl(x) __raw_readl((unsigned long)x)
+#define gsc_writeb(x, y) __raw_writeb(x, (unsigned long)y)
+#define gsc_writew(x, y) __raw_writew(x, (unsigned long)y)
+#define gsc_writel(x, y) __raw_writel(x, (unsigned long)y)
 
 struct gsc_irq {
 	unsigned long txn_addr;	/* IRQ "target" */
Index: include/asm-parisc/io.h
===================================================================
RCS file: /var/cvs/linux/include/asm-parisc/io.h,v
retrieving revision 1.24
diff -u -p -r1.24 io.h
--- include/asm-parisc/io.h	2001/10/29 20:28:39	1.24
+++ include/asm-parisc/io.h	2001/11/03 22:45:19
@@ -12,20 +12,132 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include <asm/pgtable.h>
-#include <asm/gsc.h>
 
 #define virt_to_phys(a) ((unsigned long)__pa(a))
 #define phys_to_virt(a) __va(a)
 #define virt_to_bus virt_to_phys
 #define bus_to_virt phys_to_virt
 
-#define inb_p inb
-#define inw_p inw
-#define inl_p inl
-#define outb_p outb
-#define outw_p outw
-#define outl_p outl
+/* Memory mapped IO */
+
+extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
 
+extern inline void * ioremap(unsigned long offset, unsigned long size)
+{
+	return __ioremap(offset, size, 0);
+}
+
+/*
+ * This one maps high address device memory and turns off caching for that area.
+ * it's useful if some control registers are in such an area and write combining
+ * or read caching is not desirable:
+ */
+extern inline void * ioremap_nocache (unsigned long offset, unsigned long size)
+{
+        return __ioremap(offset, size, _PAGE_NO_CACHE /* _PAGE_PCD */);
+}
+
+extern void iounmap(void *addr);
+
+/*
+ * __raw_ variants have no defined meaning.  on hppa, it means `i was
+ * too lazy to ioremap first'.  kind of like isa_, except that there's
+ * no additional base address to add on.
+ */
+extern __inline__ unsigned char __raw_readb(unsigned long addr)
+{
+	long flags;
+	unsigned char ret;
+
+	__asm__ __volatile__(
+	"	rsm	2,%0\n"
+	"	ldbx	0(%2),%1\n"
+	"	mtsm	%0\n"
+	: "=&r" (flags), "=r" (ret) : "r" (addr) );
+
+	return ret;
+}
+
+extern __inline__ unsigned short __raw_readw(unsigned long addr)
+{
+	long flags;
+	unsigned short ret;
+
+	__asm__ __volatile__(
+	"	rsm	2,%0\n"
+	"	ldhx	0(%2),%1\n"
+	"	mtsm	%0\n"
+	: "=&r" (flags), "=r" (ret) : "r" (addr) );
+
+	return ret;
+}
+
+extern __inline__ unsigned int __raw_readl(unsigned long addr)
+{
+	u32 ret;
+
+	__asm__ __volatile__(
+	"	ldwax	0(%1),%0\n"
+	: "=r" (ret) : "r" (addr) );
+
+	return ret;
+}
+
+extern __inline__ unsigned long long __raw_readq(unsigned long addr)
+{
+	unsigned long long ret;
+#ifdef __LP64__
+	__asm__ __volatile__(
+	"	ldda	0(%1),%0\n"
+	:  "=r" (ret) : "r" (addr) );
+#else
+	/* two reads may have side effects.. */
+	ret = (unsigned long long) __raw_readl(addr) << 32;
+	ret |= __raw_readl(addr+4);
+#endif
+	return ret;
+}
+
+extern __inline__ void __raw_writeb(unsigned char val, unsigned long addr)
+{
+	long flags;
+	__asm__ __volatile__(
+	"	rsm	2,%0\n"
+	"	stbs	%1,0(%2)\n"
+	"	mtsm	%0\n"
+	: "=&r" (flags) :  "r" (val), "r" (addr) );
+}
+
+extern __inline__ void __raw_writew(unsigned short val, unsigned long addr)
+{
+	long flags;
+	__asm__ __volatile__(
+	"	rsm	2,%0\n"
+	"	sths	%1,0(%2)\n"
+	"	mtsm	%0\n"
+	: "=&r" (flags) :  "r" (val), "r" (addr) );
+}
+
+extern __inline__ void __raw_writel(unsigned int val, unsigned long addr)
+{
+	__asm__ __volatile__(
+	"	stwas	%0,0(%1)\n"
+	: :  "r" (val), "r" (addr) );
+}
+
+extern __inline__ void __raw_writeq(unsigned long long val, unsigned long addr)
+{
+#ifdef __LP64__
+	__asm__ __volatile__(
+	"	stda	%0,0(%1)\n"
+	: :  "r" (val), "r" (addr) );
+#else
+	/* two writes may have side effects.. */
+	__raw_writel(val >> 32, addr);
+	__raw_writel(val, addr+4);
+#endif
+}
+
 #if USE_HPPA_IOREMAP
 #define readb(addr) (*(volatile unsigned char *) (addr))
 #define readw(addr) (*(volatile unsigned short *) (addr))
@@ -33,22 +145,51 @@
 #define writeb(b,addr) (*(volatile unsigned char *) (addr) = (b))
 #define writew(b,addr) (*(volatile unsigned short *) (addr) = (b))
 #define writel(b,addr) (*(volatile unsigned int *) (addr) = (b))
-#else /* USE_HPPA_IOREMAP */
-#define readb(addr) gsc_readb(addr)
-#define readw(addr) gsc_readw(addr)
-#define readl(addr) gsc_readl(addr)
-#define writeb(b,addr) gsc_writeb(b,addr)
-#define writew(b,addr) gsc_writew(b,addr)
-#define writel(b,addr) gsc_writel(b,addr)
-#endif /* USE_HPPA_IOREMAP */
-
-extern char eisa_in8(short port);
-extern short eisa_in16(short port);
-extern int eisa_in32(short port);
-extern void eisa_out8(char data, short port);
-extern void eisa_out16(short data, short port);
-extern void eisa_out32(int data, short port);
+#else /* !USE_HPPA_IOREMAP */
+#define readb(addr) __raw_readb((unsigned long)addr)
+#define readw(addr) __raw_readw((unsigned long)addr)
+#define readl(addr) __raw_readl((unsigned long)addr)
+#define writeb(b,addr) __raw_writeb(b,(unsigned long)addr)
+#define writew(b,addr) __raw_writew(b,(unsigned long)addr)
+#define writel(b,addr) __raw_writel(b,(unsigned long)addr)
+#endif /* !USE_HPPA_IOREMAP */
+
+extern void memcpy_fromio(void *dest, unsigned long src, int count);
+extern void memcpy_toio(unsigned long dest, const void *src, int count);
+extern void memset_io(unsigned long dest, char fill, int count);
 
+/* Support old drivers which don't ioremap.
+ * NB this interface is scheduled to disappear in 2.5
+ */
+
+#define EISA_BASE 0xfffffffffc000000UL
+#define isa_readb(a) readb(EISA_BASE | (a))
+#define isa_readw(a) readw(EISA_BASE | (a))
+#define isa_readl(a) readl(EISA_BASE | (a))
+#define isa_writeb(b,a) writeb((b), EISA_BASE | (a))
+#define isa_writew(b,a) writew((b), EISA_BASE | (a))
+#define isa_writel(b,a) writel((b), EISA_BASE | (a))
+#define isa_memset_io(a,b,c) memset_io(EISA_BASE | (a), (b), (c))
+#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a), EISA_BASE | (b), (c))
+#define isa_memcpy_toio(a,b,c) memcpy_toio(EISA_BASE | (a), (b), (c))
+
+
+/* Port-space IO */
+
+#define inb_p inb
+#define inw_p inw
+#define inl_p inl
+#define outb_p outb
+#define outw_p outw
+#define outl_p outl
+
+extern unsigned char eisa_in8(unsigned short port);
+extern unsigned short eisa_in16(unsigned short port);
+extern unsigned int eisa_in32(unsigned short port);
+extern void eisa_out8(unsigned char data, unsigned short port);
+extern void eisa_out16(unsigned short data, unsigned short port);
+extern void eisa_out32(unsigned int data, unsigned short port);
+
 #if defined(CONFIG_PCI)
 extern unsigned char inb(int addr);
 extern unsigned short inw(int addr);
@@ -88,10 +229,6 @@ static inline int inl(unsigned long addr
 #define outl(x, y)	BUG()
 #endif
 
-extern void memcpy_fromio(void *dest, unsigned long src, int count);
-extern void memcpy_toio(unsigned long dest, const void *src, int count);
-extern void memset_io(unsigned long dest, char fill, int count);
-
 /*
  * String versions of in/out ops:
  */
@@ -105,43 +242,6 @@ extern void outsl (unsigned long port, c
 
 /* IO Port space is :      BBiiii   where BB is HBA number. */
 #define IO_SPACE_LIMIT 0x00ffffff
-
-/* Support old drivers which don't ioremap.
- * NB this interface is scheduled to disappear in 2.5
- */
-
-#define EISA_BASE 0xfffffffffc000000UL
-#define isa_readb(a) readb(EISA_BASE | (a))
-#define isa_readw(a) readw(EISA_BASE | (a))
-#define isa_readl(a) readl(EISA_BASE | (a))
-#define isa_writeb(b,a) writeb((b), EISA_BASE | (a))
-#define isa_writew(b,a) writew((b), EISA_BASE | (a))
-#define isa_writel(b,a) writel((b), EISA_BASE | (a))
-#define isa_memset_io(a,b,c) memset_io(EISA_BASE | (a), (b), (c))
-#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a), EISA_BASE | (b), (c))
-#define isa_memcpy_toio(a,b,c) memcpy_toio(EISA_BASE | (a), (b), (c))
-
-/* Right now we don't support Dino-on-a-card and V class which do PCI MMIO
- * through address/data registers. */
-
-extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
-
-extern inline void * ioremap(unsigned long offset, unsigned long size)
-{
-	return __ioremap(offset, size, 0);
-}
-
-/*
- * This one maps high address device memory and turns off caching for that area.
- * it's useful if some control registers are in such an area and write combining
- * or read caching is not desirable:
- */
-extern inline void * ioremap_nocache (unsigned long offset, unsigned long size)
-{
-        return __ioremap(offset, size, _PAGE_NO_CACHE /* _PAGE_PCD */);
-}
-
-extern void iounmap(void *addr);
 
 
 #define dma_cache_inv(_start,_size)		do { flush_kernel_dcache_range(_start,_size); } while(0)
Index: include/video/fbcon.h
===================================================================
RCS file: /var/cvs/linux/include/video/fbcon.h,v
retrieving revision 1.8
diff -u -p -r1.8 fbcon.h
--- include/video/fbcon.h	2001/07/06 04:55:45	1.8
+++ include/video/fbcon.h	2001/11/03 22:45:20
@@ -206,18 +206,16 @@ extern int set_all_vcs(int fbidx, struct
 #define fb_writel sbus_writel
 #define fb_memset sbus_memset_io
 
-#elif defined(__hppa__) && !(USE_HPPA_IOREMAP)
+#elif defined(__hppa__)
 
-/* When we switch to ioremap() usage the following defines will
- * be removed and we'll use the arch-independend generic 
- * functions below instead. */
-#define fb_readb gsc_readb
-#define fb_readw gsc_readw
-#define fb_readl gsc_readl
-#define fb_writeb gsc_writeb
-#define fb_writew gsc_writew
-#define fb_writel gsc_writel
-#define fb_memset gsc_memset_io
+/* This is generic.  Why isn't it the defaut? */
+#define fb_readb readb
+#define fb_readw readw
+#define fb_readl readl
+#define fb_writeb writeb
+#define fb_writew writew
+#define fb_writel writel
+#define fb_memset memset_io
 	
 #elif defined(__i386__) || defined(__alpha__)
 
