summary refs log tree commit diff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/Kconfig1
-rw-r--r--drivers/atm/fore200e.c410
-rw-r--r--drivers/atm/fore200e.h7
-rw-r--r--drivers/block/sunvdc.c4
-rw-r--r--drivers/char/hw_random/n2-drv.c2
-rw-r--r--drivers/char/rtc.c30
-rw-r--r--drivers/hwmon/Kconfig7
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/ultra45_env.c320
-rw-r--r--drivers/input/misc/sparcspkr.c4
-rw-r--r--drivers/input/serio/i8042-sparcio.h2
-rw-r--r--drivers/leds/Kconfig8
-rw-r--r--drivers/leds/Makefile1
-rw-r--r--drivers/leds/leds-sunfire.c273
-rw-r--r--drivers/mtd/maps/sun_uflash.c75
-rw-r--r--drivers/net/myri_sbus.c196
-rw-r--r--drivers/net/myri_sbus.h2
-rw-r--r--drivers/net/niu.c2
-rw-r--r--drivers/net/sunbmac.c204
-rw-r--r--drivers/net/sunbmac.h4
-rw-r--r--drivers/net/sunhme.c322
-rw-r--r--drivers/net/sunhme.h7
-rw-r--r--drivers/net/sunlance.c180
-rw-r--r--drivers/net/sunqe.c162
-rw-r--r--drivers/net/sunqe.h4
-rw-r--r--drivers/net/sunvnet.c4
-rw-r--r--drivers/parport/parport_sunbpp.c49
-rw-r--r--drivers/rtc/Kconfig32
-rw-r--r--drivers/rtc/Makefile3
-rw-r--r--drivers/rtc/rtc-bq4802.c230
-rw-r--r--drivers/rtc/rtc-cmos.c5
-rw-r--r--drivers/rtc/rtc-m48t59.c68
-rw-r--r--drivers/rtc/rtc-starfire.c120
-rw-r--r--drivers/rtc/rtc-sun4v.c153
-rw-r--r--drivers/sbus/Makefile4
-rw-r--r--drivers/sbus/char/Kconfig29
-rw-r--r--drivers/sbus/char/Makefile6
-rw-r--r--drivers/sbus/char/bbc_envctrl.c121
-rw-r--r--drivers/sbus/char/bbc_i2c.c267
-rw-r--r--drivers/sbus/char/bbc_i2c.h75
-rw-r--r--drivers/sbus/char/bpp.c1055
-rw-r--r--drivers/sbus/char/cpwatchdog.c858
-rw-r--r--drivers/sbus/char/display7seg.c251
-rw-r--r--drivers/sbus/char/envctrl.c147
-rw-r--r--drivers/sbus/char/flash.c130
-rw-r--r--drivers/sbus/char/rtc.c275
-rw-r--r--drivers/sbus/char/uctrl.c216
-rw-r--r--drivers/sbus/char/vfc.h171
-rw-r--r--drivers/sbus/char/vfc_dev.c736
-rw-r--r--drivers/sbus/char/vfc_i2c.c335
-rw-r--r--drivers/sbus/char/vfc_i2c.h44
-rw-r--r--drivers/sbus/dvma.c136
-rw-r--r--drivers/sbus/sbus.c316
-rw-r--r--drivers/scsi/esp_scsi.h3
-rw-r--r--drivers/scsi/qlogicpti.c146
-rw-r--r--drivers/scsi/qlogicpti.h2
-rw-r--r--drivers/scsi/sun_esp.c267
-rw-r--r--drivers/serial/sunhv.c2
-rw-r--r--drivers/serial/sunsab.c2
-rw-r--r--drivers/serial/sunsu.c2
-rw-r--r--drivers/serial/sunzilog.c2
-rw-r--r--drivers/video/bw2.c2
-rw-r--r--drivers/video/cg14.c2
-rw-r--r--drivers/video/cg3.c2
-rw-r--r--drivers/video/cg6.c38
-rw-r--r--drivers/video/ffb.c2
-rw-r--r--drivers/video/leo.c96
-rw-r--r--drivers/video/p9100.c2
-rw-r--r--drivers/video/tcx.c2
-rw-r--r--drivers/watchdog/Makefile3
-rw-r--r--drivers/watchdog/cpwd.c695
-rw-r--r--drivers/watchdog/riowd.c (renamed from drivers/sbus/char/riowatchdog.c)236
72 files changed, 3677 insertions, 5893 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index f17cd4b572f8..78fbec8ceda0 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -7,7 +7,6 @@ menuconfig ATA
 	depends on HAS_IOMEM
 	depends on BLOCK
 	depends on !(M32R || M68K) || BROKEN
-	depends on !SUN4 || BROKEN
 	select SCSI
 	---help---
 	  If you want to use a ATA hard disk, ATA tape drive, ATA CD-ROM or
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 73338d231db9..937c9c0ef4c9 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -47,8 +47,9 @@
 #include <asm/atomic.h>
 
 #ifdef CONFIG_SBUS
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <asm/idprom.h>
-#include <asm/sbus.h>
 #include <asm/openprom.h>
 #include <asm/oplib.h>
 #include <asm/pgtable.h>
@@ -661,249 +662,189 @@ fore200e_pca_proc_read(struct fore200e* fore200e, char *page)
 
 #ifdef CONFIG_SBUS
 
-static u32
-fore200e_sba_read(volatile u32 __iomem *addr)
+static u32 fore200e_sba_read(volatile u32 __iomem *addr)
 {
     return sbus_readl(addr);
 }
 
-
-static void
-fore200e_sba_write(u32 val, volatile u32 __iomem *addr)
+static void fore200e_sba_write(u32 val, volatile u32 __iomem *addr)
 {
     sbus_writel(val, addr);
 }
 
-
-static u32
-fore200e_sba_dma_map(struct fore200e* fore200e, void* virt_addr, int size, int direction)
+static u32 fore200e_sba_dma_map(struct fore200e *fore200e, void* virt_addr, int size, int direction)
 {
-    u32 dma_addr = sbus_map_single((struct sbus_dev*)fore200e->bus_dev, virt_addr, size, direction);
+	struct of_device *op = fore200e->bus_dev;
+	u32 dma_addr;
 
-    DPRINTK(3, "SBUS DVMA mapping: virt_addr = 0x%p, size = %d, direction = %d --> dma_addr = 0x%08x\n",
-	    virt_addr, size, direction, dma_addr);
+	dma_addr = dma_map_single(&op->dev, virt_addr, size, direction);
+
+	DPRINTK(3, "SBUS DVMA mapping: virt_addr = 0x%p, size = %d, direction = %d --> dma_addr = 0x%08x\n",
+		virt_addr, size, direction, dma_addr);
     
-    return dma_addr;
+	return dma_addr;
 }
 
-
-static void
-fore200e_sba_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size, int direction)
+static void fore200e_sba_dma_unmap(struct fore200e *fore200e, u32 dma_addr, int size, int direction)
 {
-    DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d,\n",
-	    dma_addr, size, direction);
+	struct of_device *op = fore200e->bus_dev;
 
-    sbus_unmap_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction);
-}
+	DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d,\n",
+		dma_addr, size, direction);
 
+	dma_unmap_single(&op->dev, dma_addr, size, direction);
+}
 
-static void
-fore200e_sba_dma_sync_for_cpu(struct fore200e* fore200e, u32 dma_addr, int size, int direction)
+static void fore200e_sba_dma_sync_for_cpu(struct fore200e *fore200e, u32 dma_addr, int size, int direction)
 {
-    DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction);
+	struct of_device *op = fore200e->bus_dev;
+
+	DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction);
     
-    sbus_dma_sync_single_for_cpu((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction);
+	dma_sync_single_for_cpu(&op->dev, dma_addr, size, direction);
 }
 
-static void
-fore200e_sba_dma_sync_for_device(struct fore200e* fore200e, u32 dma_addr, int size, int direction)
+static void fore200e_sba_dma_sync_for_device(struct fore200e *fore200e, u32 dma_addr, int size, int direction)
 {
-    DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction);
-
-    sbus_dma_sync_single_for_device((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction);
-}
+	struct of_device *op = fore200e->bus_dev;
 
+	DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction);
 
-/* allocate a DVMA consistent chunk of memory intended to act as a communication mechanism
-   (to hold descriptors, status, queues, etc.) shared by the driver and the adapter */
+	dma_sync_single_for_device(&op->dev, dma_addr, size, direction);
+}
 
-static int
-fore200e_sba_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk,
-			     int size, int nbr, int alignment)
+/* Allocate a DVMA consistent chunk of memory intended to act as a communication mechanism
+ * (to hold descriptors, status, queues, etc.) shared by the driver and the adapter.
+ */
+static int fore200e_sba_dma_chunk_alloc(struct fore200e *fore200e, struct chunk *chunk,
+					int size, int nbr, int alignment)
 {
-    chunk->alloc_size = chunk->align_size = size * nbr;
+	struct of_device *op = fore200e->bus_dev;
 
-    /* returned chunks are page-aligned */
-    chunk->alloc_addr = sbus_alloc_consistent((struct sbus_dev*)fore200e->bus_dev,
-					      chunk->alloc_size,
-					      &chunk->dma_addr);
+	chunk->alloc_size = chunk->align_size = size * nbr;
 
-    if ((chunk->alloc_addr == NULL) || (chunk->dma_addr == 0))
-	return -ENOMEM;
+	/* returned chunks are page-aligned */
+	chunk->alloc_addr = dma_alloc_coherent(&op->dev, chunk->alloc_size,
+					       &chunk->dma_addr, GFP_ATOMIC);
 
-    chunk->align_addr = chunk->alloc_addr;
+	if ((chunk->alloc_addr == NULL) || (chunk->dma_addr == 0))
+		return -ENOMEM;
+
+	chunk->align_addr = chunk->alloc_addr;
     
-    return 0;
+	return 0;
 }
 
-
 /* free a DVMA consistent chunk of memory */
-
-static void
-fore200e_sba_dma_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
+static void fore200e_sba_dma_chunk_free(struct fore200e *fore200e, struct chunk *chunk)
 {
-    sbus_free_consistent((struct sbus_dev*)fore200e->bus_dev,
-			 chunk->alloc_size,
-			 chunk->alloc_addr,
-			 chunk->dma_addr);
-}
+	struct of_device *op = fore200e->bus_dev;
 
+	dma_free_coherent(&op->dev, chunk->alloc_size,
+			  chunk->alloc_addr, chunk->dma_addr);
+}
 
-static void
-fore200e_sba_irq_enable(struct fore200e* fore200e)
+static void fore200e_sba_irq_enable(struct fore200e *fore200e)
 {
-    u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
-    fore200e->bus->write(hcr | SBA200E_HCR_INTR_ENA, fore200e->regs.sba.hcr);
+	u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
+	fore200e->bus->write(hcr | SBA200E_HCR_INTR_ENA, fore200e->regs.sba.hcr);
 }
 
-
-static int
-fore200e_sba_irq_check(struct fore200e* fore200e)
+static int fore200e_sba_irq_check(struct fore200e *fore200e)
 {
-    return fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_INTR_REQ;
+	return fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_INTR_REQ;
 }
 
-
-static void
-fore200e_sba_irq_ack(struct fore200e* fore200e)
+static void fore200e_sba_irq_ack(struct fore200e *fore200e)
 {
-    u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
-    fore200e->bus->write(hcr | SBA200E_HCR_INTR_CLR, fore200e->regs.sba.hcr);
+	u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
+	fore200e->bus->write(hcr | SBA200E_HCR_INTR_CLR, fore200e->regs.sba.hcr);
 }
 
-
-static void
-fore200e_sba_reset(struct fore200e* fore200e)
+static void fore200e_sba_reset(struct fore200e *fore200e)
 {
-    fore200e->bus->write(SBA200E_HCR_RESET, fore200e->regs.sba.hcr);
-    fore200e_spin(10);
-    fore200e->bus->write(0, fore200e->regs.sba.hcr);
+	fore200e->bus->write(SBA200E_HCR_RESET, fore200e->regs.sba.hcr);
+	fore200e_spin(10);
+	fore200e->bus->write(0, fore200e->regs.sba.hcr);
 }
 
-
-static int __init
-fore200e_sba_map(struct fore200e* fore200e)
+static int __init fore200e_sba_map(struct fore200e *fore200e)
 {
-    struct sbus_dev* sbus_dev = (struct sbus_dev*)fore200e->bus_dev;
-    unsigned int bursts;
+	struct of_device *op = fore200e->bus_dev;
+	unsigned int bursts;
 
-    /* gain access to the SBA specific registers  */
-    fore200e->regs.sba.hcr = sbus_ioremap(&sbus_dev->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR");
-    fore200e->regs.sba.bsr = sbus_ioremap(&sbus_dev->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR");
-    fore200e->regs.sba.isr = sbus_ioremap(&sbus_dev->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR");
-    fore200e->virt_base    = sbus_ioremap(&sbus_dev->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM");
+	/* gain access to the SBA specific registers  */
+	fore200e->regs.sba.hcr = of_ioremap(&op->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR");
+	fore200e->regs.sba.bsr = of_ioremap(&op->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR");
+	fore200e->regs.sba.isr = of_ioremap(&op->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR");
+	fore200e->virt_base    = of_ioremap(&op->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM");
 
-    if (fore200e->virt_base == NULL) {
-	printk(FORE200E "unable to map RAM of device %s\n", fore200e->name);
-	return -EFAULT;
-    }
+	if (!fore200e->virt_base) {
+		printk(FORE200E "unable to map RAM of device %s\n", fore200e->name);
+		return -EFAULT;
+	}
 
-    DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base);
+	DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base);
     
-    fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */
+	fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */
 
-    /* get the supported DVMA burst sizes */
-    bursts = prom_getintdefault(sbus_dev->bus->prom_node, "burst-sizes", 0x00);
+	/* get the supported DVMA burst sizes */
+	bursts = of_getintprop_default(op->node->parent, "burst-sizes", 0x00);
 
-    if (sbus_can_dma_64bit(sbus_dev))
-	sbus_set_sbus64(sbus_dev, bursts);
+	if (sbus_can_dma_64bit())
+		sbus_set_sbus64(&op->dev, bursts);
 
-    fore200e->state = FORE200E_STATE_MAP;
-    return 0;
+	fore200e->state = FORE200E_STATE_MAP;
+	return 0;
 }
 
-
-static void
-fore200e_sba_unmap(struct fore200e* fore200e)
+static void fore200e_sba_unmap(struct fore200e *fore200e)
 {
-    sbus_iounmap(fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH);
-    sbus_iounmap(fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH);
-    sbus_iounmap(fore200e->regs.sba.isr, SBA200E_ISR_LENGTH);
-    sbus_iounmap(fore200e->virt_base,    SBA200E_RAM_LENGTH);
-}
+	struct of_device *op = fore200e->bus_dev;
 
+	of_iounmap(&op->resource[0], fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH);
+	of_iounmap(&op->resource[1], fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH);
+	of_iounmap(&op->resource[2], fore200e->regs.sba.isr, SBA200E_ISR_LENGTH);
+	of_iounmap(&op->resource[3], fore200e->virt_base,    SBA200E_RAM_LENGTH);
+}
 
-static int __init
-fore200e_sba_configure(struct fore200e* fore200e)
+static int __init fore200e_sba_configure(struct fore200e *fore200e)
 {
-    fore200e->state = FORE200E_STATE_CONFIGURE;
-    return 0;
+	fore200e->state = FORE200E_STATE_CONFIGURE;
+	return 0;
 }
 
-
-static struct fore200e* __init
-fore200e_sba_detect(const struct fore200e_bus* bus, int index)
+static int __init fore200e_sba_prom_read(struct fore200e *fore200e, struct prom_data *prom)
 {
-    struct fore200e*          fore200e;
-    struct sbus_bus* sbus_bus;
-    struct sbus_dev* sbus_dev = NULL;
-    
-    unsigned int     count = 0;
-    
-    for_each_sbus (sbus_bus) {
-	for_each_sbusdev (sbus_dev, sbus_bus) {
-	    if (strcmp(sbus_dev->prom_name, SBA200E_PROM_NAME) == 0) {
-		if (count >= index)
-		    goto found;
-		count++;
-	    }
-	}
-    }
-    return NULL;
-    
-  found:
-    if (sbus_dev->num_registers != 4) {
-	printk(FORE200E "this %s device has %d instead of 4 registers\n",
-	       bus->model_name, sbus_dev->num_registers);
-	return NULL;
-    }
-
-    fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL);
-    if (fore200e == NULL)
-	return NULL;
+	struct of_device *op = fore200e->bus_dev;
+	const u8 *prop;
+	int len;
 
-    fore200e->bus     = bus;
-    fore200e->bus_dev = sbus_dev;
-    fore200e->irq     = sbus_dev->irqs[ 0 ];
+	prop = of_get_property(op->node, "madaddrlo2", &len);
+	if (!prop)
+		return -ENODEV;
+	memcpy(&prom->mac_addr[4], prop, 4);
 
-    fore200e->phys_base = (unsigned long)sbus_dev;
+	prop = of_get_property(op->node, "madaddrhi4", &len);
+	if (!prop)
+		return -ENODEV;
+	memcpy(&prom->mac_addr[2], prop, 4);
 
-    sprintf(fore200e->name, "%s-%d", bus->model_name, index - 1);
+	prom->serial_number = of_getintprop_default(op->node, "serialnumber", 0);
+	prom->hw_revision = of_getintprop_default(op->node, "promversion", 0);
     
-    return fore200e;
+	return 0;
 }
 
-
-static int __init
-fore200e_sba_prom_read(struct fore200e* fore200e, struct prom_data* prom)
+static int fore200e_sba_proc_read(struct fore200e *fore200e, char *page)
 {
-    struct sbus_dev* sbus_dev = (struct sbus_dev*) fore200e->bus_dev;
-    int                       len;
-
-    len = prom_getproperty(sbus_dev->prom_node, "macaddrlo2", &prom->mac_addr[ 4 ], 4);
-    if (len < 0)
-	return -EBUSY;
-
-    len = prom_getproperty(sbus_dev->prom_node, "macaddrhi4", &prom->mac_addr[ 2 ], 4);
-    if (len < 0)
-	return -EBUSY;
-    
-    prom_getproperty(sbus_dev->prom_node, "serialnumber",
-		     (char*)&prom->serial_number, sizeof(prom->serial_number));
-    
-    prom_getproperty(sbus_dev->prom_node, "promversion",
-		     (char*)&prom->hw_revision, sizeof(prom->hw_revision));
-    
-    return 0;
-}
+	struct of_device *op = fore200e->bus_dev;
+	const struct linux_prom_registers *regs;
 
+	regs = of_get_property(op->node, "reg", NULL);
 
-static int
-fore200e_sba_proc_read(struct fore200e* fore200e, char *page)
-{
-    struct sbus_dev* sbus_dev = (struct sbus_dev*)fore200e->bus_dev;
-
-    return sprintf(page, "   SBUS slot/device:\t\t%d/'%s'\n", sbus_dev->slot, sbus_dev->prom_name);
+	return sprintf(page, "   SBUS slot/device:\t\t%d/'%s'\n",
+		       (regs ? regs->which_io : 0), op->node->name);
 }
 #endif /* CONFIG_SBUS */
 
@@ -2572,7 +2513,7 @@ fore200e_load_and_start_fw(struct fore200e* fore200e)
 	device = &((struct pci_dev *) fore200e->bus_dev)->dev;
 #ifdef CONFIG_SBUS
     else if (strcmp(fore200e->bus->model_name, "SBA-200E") == 0)
-	device = &((struct sbus_dev *) fore200e->bus_dev)->ofdev.dev;
+	device = &((struct of_device *) fore200e->bus_dev)->dev;
 #endif
     else
 	return err;
@@ -2701,6 +2642,66 @@ fore200e_init(struct fore200e* fore200e)
     return 0;
 }
 
+#ifdef CONFIG_SBUS
+static int __devinit fore200e_sba_probe(struct of_device *op,
+					const struct of_device_id *match)
+{
+	const struct fore200e_bus *bus = match->data;
+	struct fore200e *fore200e;
+	static int index = 0;
+	int err;
+
+	fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL);
+	if (!fore200e)
+		return -ENOMEM;
+
+	fore200e->bus = bus;
+	fore200e->bus_dev = op;
+	fore200e->irq = op->irqs[0];
+	fore200e->phys_base = op->resource[0].start;
+
+	sprintf(fore200e->name, "%s-%d", bus->model_name, index);
+
+	err = fore200e_init(fore200e);
+	if (err < 0) {
+		fore200e_shutdown(fore200e);
+		kfree(fore200e);
+		return err;
+	}
+
+	index++;
+	dev_set_drvdata(&op->dev, fore200e);
+
+	return 0;
+}
+
+static int __devexit fore200e_sba_remove(struct of_device *op)
+{
+	struct fore200e *fore200e = dev_get_drvdata(&op->dev);
+
+	fore200e_shutdown(fore200e);
+	kfree(fore200e);
+
+	return 0;
+}
+
+static const struct of_device_id fore200e_sba_match[] = {
+	{
+		.name = SBA200E_PROM_NAME,
+		.data = (void *) &fore200e_bus[1],
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, fore200e_sba_match);
+
+static struct of_platform_driver fore200e_sba_driver = {
+	.name		= "fore_200e",
+	.match_table	= fore200e_sba_match,
+	.probe		= fore200e_sba_probe,
+	.remove		= __devexit_p(fore200e_sba_remove),
+};
+#endif
+
 #ifdef CONFIG_PCI
 static int __devinit
 fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
@@ -2784,67 +2785,40 @@ static struct pci_driver fore200e_pca_driver = {
 };
 #endif
 
-
-static int __init
-fore200e_module_init(void)
+static int __init fore200e_module_init(void)
 {
-    const struct fore200e_bus* bus;
-    struct       fore200e*     fore200e;
-    int                        index;
-
-    printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n");
+	int err;
 
-    /* for each configured bus interface */
-    for (bus = fore200e_bus; bus->model_name; bus++) {
+	printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n");
 
-	/* detect all boards present on that bus */
-	for (index = 0; bus->detect && (fore200e = bus->detect(bus, index)); index++) {
-	    
-	    printk(FORE200E "device %s found at 0x%lx, IRQ %s\n",
-		   fore200e->bus->model_name, 
-		   fore200e->phys_base, fore200e_irq_itoa(fore200e->irq));
-
-	    sprintf(fore200e->name, "%s-%d", bus->model_name, index);
-
-	    if (fore200e_init(fore200e) < 0) {
-
-		fore200e_shutdown(fore200e);
-		break;
-	    }
-
-	    list_add(&fore200e->entry, &fore200e_boards);
-	}
-    }
+#ifdef CONFIG_SBUS
+	err = of_register_driver(&fore200e_sba_driver, &of_bus_type);
+	if (err)
+		return err;
+#endif
 
 #ifdef CONFIG_PCI
-    if (!pci_register_driver(&fore200e_pca_driver))
-	return 0;
+	err = pci_register_driver(&fore200e_pca_driver);
 #endif
 
-    if (!list_empty(&fore200e_boards))
-	return 0;
+#ifdef CONFIG_SBUS
+	if (err)
+		of_unregister_driver(&fore200e_sba_driver);
+#endif
 
-    return -ENODEV;
+	return err;
 }
 
-
-static void __exit
-fore200e_module_cleanup(void)
+static void __exit fore200e_module_cleanup(void)
 {
-    struct fore200e *fore200e, *next;
-
 #ifdef CONFIG_PCI
-    pci_unregister_driver(&fore200e_pca_driver);
+	pci_unregister_driver(&fore200e_pca_driver);
+#endif
+#ifdef CONFIG_SBUS
+	of_unregister_driver(&fore200e_sba_driver);
 #endif
-
-    list_for_each_entry_safe(fore200e, next, &fore200e_boards, entry) {
-	fore200e_shutdown(fore200e);
-	kfree(fore200e);
-    }
-    DPRINTK(1, "module being removed\n");
 }
 
-
 static int
 fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
 {
@@ -3163,7 +3137,6 @@ static const struct fore200e_bus fore200e_bus[] = {
       fore200e_pca_dma_sync_for_device,
       fore200e_pca_dma_chunk_alloc,
       fore200e_pca_dma_chunk_free,
-      NULL,
       fore200e_pca_configure,
       fore200e_pca_map,
       fore200e_pca_reset,
@@ -3185,7 +3158,6 @@ static const struct fore200e_bus fore200e_bus[] = {
       fore200e_sba_dma_sync_for_device,
       fore200e_sba_dma_chunk_alloc,
       fore200e_sba_dma_chunk_free,
-      fore200e_sba_detect, 
       fore200e_sba_configure,
       fore200e_sba_map,
       fore200e_sba_reset,
diff --git a/drivers/atm/fore200e.h b/drivers/atm/fore200e.h
index 5c6e7adcb19c..7f97c09aaea5 100644
--- a/drivers/atm/fore200e.h
+++ b/drivers/atm/fore200e.h
@@ -778,9 +778,9 @@ typedef struct fore200e_pca_regs {
 /* SBA-200E registers */
 
 typedef struct fore200e_sba_regs {
-    volatile u32 __iomem *hcr;    /* address of host control register              */
-    volatile u32 __iomem *bsr;    /* address of burst transfer size register       */
-    volatile u32 __iomem *isr;    /* address of interrupt level selection register */
+    u32 __iomem *hcr;    /* address of host control register              */
+    u32 __iomem *bsr;    /* address of burst transfer size register       */
+    u32 __iomem *isr;    /* address of interrupt level selection register */
 } fore200e_sba_regs_t;
 
 
@@ -810,7 +810,6 @@ typedef struct fore200e_bus {
     void                 (*dma_sync_for_device)(struct fore200e*, u32, int, int);
     int                  (*dma_chunk_alloc)(struct fore200e*, struct chunk*, int, int, int);
     void                 (*dma_chunk_free)(struct fore200e*, struct chunk*);
-    struct fore200e*     (*detect)(const struct fore200e_bus*, int);
     int                  (*configure)(struct fore200e*); 
     int                  (*map)(struct fore200e*); 
     void                 (*reset)(struct fore200e*);
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index a8de037ecd4a..953c0b83d758 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -1,6 +1,6 @@
 /* sunvdc.c: Sun LDOM Virtual Disk Client.
  *
- * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
+ * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
  */
 
 #include <linux/module.h>
@@ -834,7 +834,7 @@ static int vdc_port_remove(struct vio_dev *vdev)
 	return 0;
 }
 
-static struct vio_device_id vdc_port_match[] = {
+static const struct vio_device_id vdc_port_match[] = {
 	{
 		.type = "vdc-port",
 	},
diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c
index 5220f541df25..8859aeac2d25 100644
--- a/drivers/char/hw_random/n2-drv.c
+++ b/drivers/char/hw_random/n2-drv.c
@@ -736,7 +736,7 @@ static int __devexit n2rng_remove(struct of_device *op)
 	return 0;
 }
 
-static struct of_device_id n2rng_match[] = {
+static const struct of_device_id n2rng_match[] = {
 	{
 		.name		= "random-number-generator",
 		.compatible	= "SUNW,n2-rng",
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index f53d4d00faf0..b47710c17885 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -88,12 +88,12 @@
 #endif
 
 #ifdef CONFIG_SPARC32
-#include <linux/pci.h>
-#include <linux/jiffies.h>
-#include <asm/ebus.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <asm/io.h>
 
 static unsigned long rtc_port;
-static int rtc_irq = PCI_IRQ_NONE;
+static int rtc_irq;
 #endif
 
 #ifdef	CONFIG_HPET_RTC_IRQ
@@ -973,8 +973,8 @@ static int __init rtc_init(void)
 	char *guess = NULL;
 #endif
 #ifdef CONFIG_SPARC32
-	struct linux_ebus *ebus;
-	struct linux_ebus_device *edev;
+	struct device_node *ebus_dp;
+	struct of_device *op;
 #else
 	void *r;
 #ifdef RTC_IRQ
@@ -983,12 +983,16 @@ static int __init rtc_init(void)
 #endif
 
 #ifdef CONFIG_SPARC32
-	for_each_ebus(ebus) {
-		for_each_ebusdev(edev, ebus) {
-			if (strcmp(edev->prom_node->name, "rtc") == 0) {
-				rtc_port = edev->resource[0].start;
-				rtc_irq = edev->irqs[0];
-				goto found;
+	for_each_node_by_name(ebus_dp, "ebus") {
+		struct device_node *dp;
+		for (dp = ebus_dp; dp; dp = dp->sibling) {
+			if (!strcmp(dp->name, "rtc")) {
+				op = of_find_device_by_node(dp);
+				if (op) {
+					rtc_port = op->resource[0].start;
+					rtc_irq = op->irqs[0];
+					goto found;
+				}
 			}
 		}
 	}
@@ -997,7 +1001,7 @@ static int __init rtc_init(void)
 	return -EIO;
 
 found:
-	if (rtc_irq == PCI_IRQ_NONE) {
+	if (!rtc_irq) {
 		rtc_has_irq = 0;
 		goto no_irq;
 	}
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 3309e862f317..ebacc0af40fe 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -800,6 +800,13 @@ config SENSORS_W83627EHF
 	  This driver can also be built as a module.  If so, the module
 	  will be called w83627ehf.
 
+config SENSORS_ULTRA45
+	tristate "Sun Ultra45 PIC16F747"
+	depends on SPARC64
+	help
+	  This driver provides support for the Ultra45 workstation environmental
+	  sensors.
+
 config SENSORS_HDAPS
 	tristate "IBM Hard Drive Active Protection System (hdaps)"
 	depends on INPUT && X86
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 6babc801b348..042d5a78622e 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_SENSORS_FSCHMD)	+= fschmd.o
 obj-$(CONFIG_SENSORS_FSCPOS)	+= fscpos.o
 obj-$(CONFIG_SENSORS_GL518SM)	+= gl518sm.o
 obj-$(CONFIG_SENSORS_GL520SM)	+= gl520sm.o
+obj-$(CONFIG_SENSORS_ULTRA45)	+= ultra45_env.o
 obj-$(CONFIG_SENSORS_HDAPS)	+= hdaps.o
 obj-$(CONFIG_SENSORS_I5K_AMB)	+= i5k_amb.o
 obj-$(CONFIG_SENSORS_IBMAEM)	+= ibmaem.o
diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c
new file mode 100644
index 000000000000..68e90abeba96
--- /dev/null
+++ b/drivers/hwmon/ultra45_env.c
@@ -0,0 +1,320 @@
+/* ultra45_env.c: Driver for Ultra45 PIC16F747 environmental monitor.
+ *
+ * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/of_device.h>
+#include <linux/io.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+
+#define DRV_MODULE_VERSION	"0.1"
+
+MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
+MODULE_DESCRIPTION("Ultra45 environmental monitor driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_MODULE_VERSION);
+
+/* PIC device registers */
+#define REG_CMD		0x00UL
+#define  REG_CMD_RESET	0x80
+#define  REG_CMD_ESTAR	0x01
+#define REG_STAT	0x01UL
+#define  REG_STAT_FWVER	0xf0
+#define  REG_STAT_TGOOD	0x08
+#define  REG_STAT_STALE	0x04
+#define  REG_STAT_BUSY	0x02
+#define  REG_STAT_FAULT	0x01
+#define REG_DATA	0x40UL
+#define REG_ADDR	0x41UL
+#define REG_SIZE	0x42UL
+
+/* Registers accessed indirectly via REG_DATA/REG_ADDR */
+#define IREG_FAN0		0x00
+#define IREG_FAN1		0x01
+#define IREG_FAN2		0x02
+#define IREG_FAN3		0x03
+#define IREG_FAN4		0x04
+#define IREG_FAN5		0x05
+#define IREG_LCL_TEMP		0x06
+#define IREG_RMT1_TEMP		0x07
+#define IREG_RMT2_TEMP		0x08
+#define IREG_RMT3_TEMP		0x09
+#define IREG_LM95221_TEMP	0x0a
+#define IREG_FIRE_TEMP		0x0b
+#define IREG_LSI1064_TEMP	0x0c
+#define IREG_FRONT_TEMP		0x0d
+#define IREG_FAN_STAT		0x0e
+#define IREG_VCORE0		0x0f
+#define IREG_VCORE1		0x10
+#define IREG_VMEM0		0x11
+#define IREG_VMEM1		0x12
+#define IREG_PSU_TEMP		0x13
+
+struct env {
+	void __iomem	*regs;
+	spinlock_t	lock;
+
+	struct device	*hwmon_dev;
+};
+
+static u8 env_read(struct env *p, u8 ireg)
+{
+	u8 ret;
+
+	spin_lock(&p->lock);
+	writeb(ireg, p->regs + REG_ADDR);
+	ret = readb(p->regs + REG_DATA);
+	spin_unlock(&p->lock);
+
+	return ret;
+}
+
+static void env_write(struct env *p, u8 ireg, u8 val)
+{
+	spin_lock(&p->lock);
+	writeb(ireg, p->regs + REG_ADDR);
+	writeb(val, p->regs + REG_DATA);
+	spin_unlock(&p->lock);
+}
+
+/* There seems to be a adr7462 providing these values, thus a lot
+ * of these calculations are borrowed from the adt7470 driver.
+ */
+#define FAN_PERIOD_TO_RPM(x)	((90000 * 60) / (x))
+#define FAN_RPM_TO_PERIOD	FAN_PERIOD_TO_RPM
+#define FAN_PERIOD_INVALID	(0xff << 8)
+#define FAN_DATA_VALID(x)	((x) && (x) != FAN_PERIOD_INVALID)
+
+static ssize_t show_fan_speed(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int fan_nr = to_sensor_dev_attr(attr)->index;
+	struct env *p = dev_get_drvdata(dev);
+	int rpm, period;
+	u8 val;
+
+	val = env_read(p, IREG_FAN0 + fan_nr);
+	period = (int) val << 8;
+	if (FAN_DATA_VALID(period))
+		rpm = FAN_PERIOD_TO_RPM(period);
+	else
+		rpm = 0;
+
+	return sprintf(buf, "%d\n", rpm);
+}
+
+static ssize_t set_fan_speed(struct device *dev, struct device_attribute *attr,
+			     const char *buf, size_t count)
+{
+	int fan_nr = to_sensor_dev_attr(attr)->index;
+	int rpm = simple_strtol(buf, NULL, 10);
+	struct env *p = dev_get_drvdata(dev);
+	int period;
+	u8 val;
+
+	if (!rpm)
+		return -EINVAL;
+
+	period = FAN_RPM_TO_PERIOD(rpm);
+	val = period >> 8;
+	env_write(p, IREG_FAN0 + fan_nr, val);
+
+	return count;
+}
+
+static ssize_t show_fan_fault(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int fan_nr = to_sensor_dev_attr(attr)->index;
+	struct env *p = dev_get_drvdata(dev);
+	u8 val = env_read(p, IREG_FAN_STAT);
+	return sprintf(buf, "%d\n", (val & (1 << fan_nr)) ? 1 : 0);
+}
+
+#define fan(index)							\
+static SENSOR_DEVICE_ATTR(fan##index##_speed, S_IRUGO | S_IWUSR,	\
+		show_fan_speed, set_fan_speed, index);			\
+static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO,			\
+		show_fan_fault, NULL, index)
+
+fan(0);
+fan(1);
+fan(2);
+fan(3);
+fan(4);
+
+static SENSOR_DEVICE_ATTR(psu_fan_fault, S_IRUGO, show_fan_fault, NULL, 6);
+
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int temp_nr = to_sensor_dev_attr(attr)->index;
+	struct env *p = dev_get_drvdata(dev);
+	s8 val;
+
+	val = env_read(p, IREG_LCL_TEMP + temp_nr);
+	return sprintf(buf, "%d\n", ((int) val) - 64);
+}
+
+static SENSOR_DEVICE_ATTR(adt7462_local_temp, S_IRUGO, show_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(cpu0_temp, S_IRUGO, show_temp, NULL, 1);
+static SENSOR_DEVICE_ATTR(cpu1_temp, S_IRUGO, show_temp, NULL, 2);
+static SENSOR_DEVICE_ATTR(motherboard_temp, S_IRUGO, show_temp, NULL, 3);
+static SENSOR_DEVICE_ATTR(lm95221_local_temp, S_IRUGO, show_temp, NULL, 4);
+static SENSOR_DEVICE_ATTR(fire_temp, S_IRUGO, show_temp, NULL, 5);
+static SENSOR_DEVICE_ATTR(lsi1064_local_temp, S_IRUGO, show_temp, NULL, 6);
+static SENSOR_DEVICE_ATTR(front_panel_temp, S_IRUGO, show_temp, NULL, 7);
+static SENSOR_DEVICE_ATTR(psu_temp, S_IRUGO, show_temp, NULL, 13);
+
+static ssize_t show_stat_bit(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int index = to_sensor_dev_attr(attr)->index;
+	struct env *p = dev_get_drvdata(dev);
+	u8 val;
+
+	val = readb(p->regs + REG_STAT);
+	return sprintf(buf, "%d\n", (val & (1 << index)) ? 1 : 0);
+}
+
+static SENSOR_DEVICE_ATTR(fan_failure, S_IRUGO, show_stat_bit, NULL, 0);
+static SENSOR_DEVICE_ATTR(env_bus_busy, S_IRUGO, show_stat_bit, NULL, 1);
+static SENSOR_DEVICE_ATTR(env_data_stale, S_IRUGO, show_stat_bit, NULL, 2);
+static SENSOR_DEVICE_ATTR(tpm_self_test_passed, S_IRUGO, show_stat_bit, NULL, 3);
+
+static ssize_t show_fwver(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct env *p = dev_get_drvdata(dev);
+	u8 val;
+
+	val = readb(p->regs + REG_STAT);
+	return sprintf(buf, "%d\n", val >> 4);
+}
+
+static SENSOR_DEVICE_ATTR(firmware_version, S_IRUGO, show_fwver, NULL, 0);
+
+static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "ultra45\n");
+}
+
+static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
+
+static struct attribute *env_attributes[] = {
+	&sensor_dev_attr_fan0_speed.dev_attr.attr,
+	&sensor_dev_attr_fan0_fault.dev_attr.attr,
+	&sensor_dev_attr_fan1_speed.dev_attr.attr,
+	&sensor_dev_attr_fan1_fault.dev_attr.attr,
+	&sensor_dev_attr_fan2_speed.dev_attr.attr,
+	&sensor_dev_attr_fan2_fault.dev_attr.attr,
+	&sensor_dev_attr_fan3_speed.dev_attr.attr,
+	&sensor_dev_attr_fan3_fault.dev_attr.attr,
+	&sensor_dev_attr_fan4_speed.dev_attr.attr,
+	&sensor_dev_attr_fan4_fault.dev_attr.attr,
+	&sensor_dev_attr_psu_fan_fault.dev_attr.attr,
+	&sensor_dev_attr_adt7462_local_temp.dev_attr.attr,
+	&sensor_dev_attr_cpu0_temp.dev_attr.attr,
+	&sensor_dev_attr_cpu1_temp.dev_attr.attr,
+	&sensor_dev_attr_motherboard_temp.dev_attr.attr,
+	&sensor_dev_attr_lm95221_local_temp.dev_attr.attr,
+	&sensor_dev_attr_fire_temp.dev_attr.attr,
+	&sensor_dev_attr_lsi1064_local_temp.dev_attr.attr,
+	&sensor_dev_attr_front_panel_temp.dev_attr.attr,
+	&sensor_dev_attr_psu_temp.dev_attr.attr,
+	&sensor_dev_attr_fan_failure.dev_attr.attr,
+	&sensor_dev_attr_env_bus_busy.dev_attr.attr,
+	&sensor_dev_attr_env_data_stale.dev_attr.attr,
+	&sensor_dev_attr_tpm_self_test_passed.dev_attr.attr,
+	&sensor_dev_attr_firmware_version.dev_attr.attr,
+	&sensor_dev_attr_name.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group env_group = {
+	.attrs = env_attributes,
+};
+
+static int __devinit env_probe(struct of_device *op,
+			       const struct of_device_id *match)
+{
+	struct env *p = kzalloc(sizeof(*p), GFP_KERNEL);
+	int err = -ENOMEM;
+
+	if (!p)
+		goto out;
+
+	spin_lock_init(&p->lock);
+
+	p->regs = of_ioremap(&op->resource[0], 0, REG_SIZE, "pic16f747");
+	if (!p->regs)
+		goto out_free;
+
+	err = sysfs_create_group(&op->dev.kobj, &env_group);
+	if (err)
+		goto out_iounmap;
+
+	p->hwmon_dev = hwmon_device_register(&op->dev);
+	if (IS_ERR(p->hwmon_dev)) {
+		err = PTR_ERR(p->hwmon_dev);
+		goto out_sysfs_remove_group;
+	}
+
+	dev_set_drvdata(&op->dev, p);
+	err = 0;
+
+out:
+	return err;
+
+out_sysfs_remove_group:
+	sysfs_remove_group(&op->dev.kobj, &env_group);
+
+out_iounmap:
+	of_iounmap(&op->resource[0], p->regs, REG_SIZE);
+
+out_free:
+	kfree(p);
+	goto out;
+}
+
+static int __devexit env_remove(struct of_device *op)
+{
+	struct env *p = dev_get_drvdata(&op->dev);
+
+	if (p) {
+		sysfs_remove_group(&op->dev.kobj, &env_group);
+		hwmon_device_unregister(p->hwmon_dev);
+		of_iounmap(&op->resource[0], p->regs, REG_SIZE);
+		kfree(p);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id env_match[] = {
+	{
+		.name = "env-monitor",
+		.compatible = "SUNW,ebus-pic16f747-env",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, env_match);
+
+static struct of_platform_driver env_driver = {
+	.name		= "ultra45_env",
+	.match_table	= env_match,
+	.probe		= env_probe,
+	.remove		= __devexit_p(env_remove),
+};
+
+static int __init env_init(void)
+{
+	return of_register_driver(&env_driver, &of_bus_type);
+}
+
+static void __exit env_exit(void)
+{
+	of_unregister_driver(&env_driver);
+}
+
+module_init(env_init);
+module_exit(env_exit);
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index d8765cc93d27..c4f42311fdec 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -249,7 +249,7 @@ static int bbc_remove(struct of_device *op)
 	return 0;
 }
 
-static struct of_device_id bbc_beep_match[] = {
+static const struct of_device_id bbc_beep_match[] = {
 	{
 		.name = "beep",
 		.compatible = "SUNW,bbc-beep",
@@ -328,7 +328,7 @@ static int grover_remove(struct of_device *op)
 	return 0;
 }
 
-static struct of_device_id grover_beep_match[] = {
+static const struct of_device_id grover_beep_match[] = {
 	{
 		.name = "beep",
 		.compatible = "SUNW,smbus-beep",
diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h
index 692a79ec2a22..5071af2c0604 100644
--- a/drivers/input/serio/i8042-sparcio.h
+++ b/drivers/input/serio/i8042-sparcio.h
@@ -87,7 +87,7 @@ static int __devexit sparc_i8042_remove(struct of_device *op)
 	return 0;
 }
 
-static struct of_device_id sparc_i8042_match[] = {
+static const struct of_device_id sparc_i8042_match[] = {
 	{
 		.name = "8042",
 	},
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 5b14262af017..e3e40427e00e 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -82,6 +82,14 @@ config LEDS_COBALT_RAQ
 	help
 	  This option enables support for the Cobalt Raq series LEDs.
 
+config LEDS_SUNFIRE
+	tristate "LED support for SunFire servers."
+	depends on LEDS_CLASS && SPARC64
+	select LEDS_TRIGGERS
+	help
+	  This option enables support for the Left, Middle, and Right
+	  LEDs on the I/O and CPU boards of SunFire UltraSPARC servers.
+
 config LEDS_HP6XX
 	tristate "LED Support for the HP Jornada 6xx"
 	depends on LEDS_CLASS && SH_HP6XX
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 3a8e6a04363c..eb186c351a1c 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_LEDS_WRAP)			+= leds-wrap.o
 obj-$(CONFIG_LEDS_H1940)		+= leds-h1940.o
 obj-$(CONFIG_LEDS_COBALT_QUBE)		+= leds-cobalt-qube.o
 obj-$(CONFIG_LEDS_COBALT_RAQ)		+= leds-cobalt-raq.o
+obj-$(CONFIG_LEDS_SUNFIRE)		+= leds-sunfire.o
 obj-$(CONFIG_LEDS_PCA9532)		+= leds-pca9532.o
 obj-$(CONFIG_LEDS_GPIO)			+= leds-gpio.o
 obj-$(CONFIG_LEDS_CM_X270)              += leds-cm-x270.o
diff --git a/drivers/leds/leds-sunfire.c b/drivers/leds/leds-sunfire.c
new file mode 100644
index 000000000000..6b008f0c3f62
--- /dev/null
+++ b/drivers/leds/leds-sunfire.c
@@ -0,0 +1,273 @@
+/* leds-sunfire.c: SUNW,Ultra-Enterprise LED driver.
+ *
+ * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/leds.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include <asm/fhc.h>
+#include <asm/upa.h>
+
+#define DRIVER_NAME	"leds-sunfire"
+#define PFX		DRIVER_NAME ": "
+
+MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
+MODULE_DESCRIPTION("Sun Fire LED driver");
+MODULE_LICENSE("GPL");
+
+struct sunfire_led {
+	struct led_classdev	led_cdev;
+	void __iomem		*reg;
+};
+#define	to_sunfire_led(d) container_of(d, struct sunfire_led, led_cdev)
+
+static void __clockboard_set(struct led_classdev *led_cdev,
+			     enum led_brightness led_val, u8 bit)
+{
+	struct sunfire_led *p = to_sunfire_led(led_cdev);
+	u8 reg = upa_readb(p->reg);
+
+	switch (bit) {
+	case CLOCK_CTRL_LLED:
+		if (led_val)
+			reg &= ~bit;
+		else
+			reg |= bit;
+		break;
+
+	default:
+		if (led_val)
+			reg |= bit;
+		else
+			reg &= ~bit;
+		break;
+	}
+	upa_writeb(reg, p->reg);
+}
+
+static void clockboard_left_set(struct led_classdev *led_cdev,
+				enum led_brightness led_val)
+{
+	__clockboard_set(led_cdev, led_val, CLOCK_CTRL_LLED);
+}
+
+static void clockboard_middle_set(struct led_classdev *led_cdev,
+				  enum led_brightness led_val)
+{
+	__clockboard_set(led_cdev, led_val, CLOCK_CTRL_MLED);
+}
+
+static void clockboard_right_set(struct led_classdev *led_cdev,
+				 enum led_brightness led_val)
+{
+	__clockboard_set(led_cdev, led_val, CLOCK_CTRL_RLED);
+}
+
+static void __fhc_set(struct led_classdev *led_cdev,
+			     enum led_brightness led_val, u32 bit)
+{
+	struct sunfire_led *p = to_sunfire_led(led_cdev);
+	u32 reg = upa_readl(p->reg);
+
+	switch (bit) {
+	case FHC_CONTROL_LLED:
+		if (led_val)
+			reg &= ~bit;
+		else
+			reg |= bit;
+		break;
+
+	default:
+		if (led_val)
+			reg |= bit;
+		else
+			reg &= ~bit;
+		break;
+	}
+	upa_writel(reg, p->reg);
+}
+
+static void fhc_left_set(struct led_classdev *led_cdev,
+			 enum led_brightness led_val)
+{
+	__fhc_set(led_cdev, led_val, FHC_CONTROL_LLED);
+}
+
+static void fhc_middle_set(struct led_classdev *led_cdev,
+			   enum led_brightness led_val)
+{
+	__fhc_set(led_cdev, led_val, FHC_CONTROL_MLED);
+}
+
+static void fhc_right_set(struct led_classdev *led_cdev,
+			  enum led_brightness led_val)
+{
+	__fhc_set(led_cdev, led_val, FHC_CONTROL_RLED);
+}
+
+typedef void (*set_handler)(struct led_classdev *, enum led_brightness);
+struct led_type {
+	const char	*name;
+	set_handler	handler;
+	const char	*default_trigger;
+};
+
+#define NUM_LEDS_PER_BOARD	3
+struct sunfire_drvdata {
+	struct sunfire_led	leds[NUM_LEDS_PER_BOARD];
+};
+
+static int __devinit sunfire_led_generic_probe(struct platform_device *pdev,
+					       struct led_type *types)
+{
+	struct sunfire_drvdata *p;
+	int i, err = -EINVAL;
+
+	if (pdev->num_resources != 1) {
+		printk(KERN_ERR PFX "Wrong number of resources %d, should be 1\n",
+		       pdev->num_resources);
+		goto out;
+	}
+
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	if (!p) {
+		printk(KERN_ERR PFX "Could not allocate struct sunfire_drvdata\n");
+		goto out;
+	}
+
+	for (i = 0; i < NUM_LEDS_PER_BOARD; i++) {
+		struct led_classdev *lp = &p->leds[i].led_cdev;
+
+		p->leds[i].reg = (void __iomem *) pdev->resource[0].start;
+		lp->name = types[i].name;
+		lp->brightness = LED_FULL;
+		lp->brightness_set = types[i].handler;
+		lp->default_trigger = types[i].default_trigger;
+
+		err = led_classdev_register(&pdev->dev, lp);
+		if (err) {
+			printk(KERN_ERR PFX "Could not register %s LED\n",
+			       lp->name);
+			goto out_unregister_led_cdevs;
+		}
+	}
+
+	dev_set_drvdata(&pdev->dev, p);
+
+	err = 0;
+out:
+	return err;
+
+out_unregister_led_cdevs:
+	for (i--; i >= 0; i--)
+		led_classdev_unregister(&p->leds[i].led_cdev);
+	goto out;
+}
+
+static int __devexit sunfire_led_generic_remove(struct platform_device *pdev)
+{
+	struct sunfire_drvdata *p = dev_get_drvdata(&pdev->dev);
+	int i;
+
+	for (i = 0; i < NUM_LEDS_PER_BOARD; i++)
+		led_classdev_unregister(&p->leds[i].led_cdev);
+
+	kfree(p);
+
+	return 0;
+}
+
+static struct led_type clockboard_led_types[NUM_LEDS_PER_BOARD] = {
+	{
+		.name		= "clockboard-left",
+		.handler	= clockboard_left_set,
+	},
+	{
+		.name		= "clockboard-middle",
+		.handler	= clockboard_middle_set,
+	},
+	{
+		.name		= "clockboard-right",
+		.handler	= clockboard_right_set,
+		.default_trigger= "heartbeat",
+	},
+};
+
+static int __devinit sunfire_clockboard_led_probe(struct platform_device *pdev)
+{
+	return sunfire_led_generic_probe(pdev, clockboard_led_types);
+}
+
+static struct led_type fhc_led_types[NUM_LEDS_PER_BOARD] = {
+	{
+		.name		= "fhc-left",
+		.handler	= fhc_left_set,
+	},
+	{
+		.name		= "fhc-middle",
+		.handler	= fhc_middle_set,
+	},
+	{
+		.name		= "fhc-right",
+		.handler	= fhc_right_set,
+		.default_trigger= "heartbeat",
+	},
+};
+
+static int __devinit sunfire_fhc_led_probe(struct platform_device *pdev)
+{
+	return sunfire_led_generic_probe(pdev, fhc_led_types);
+}
+
+MODULE_ALIAS("platform:sunfire-clockboard-leds");
+MODULE_ALIAS("platform:sunfire-fhc-leds");
+
+static struct platform_driver sunfire_clockboard_led_driver = {
+	.probe		= sunfire_clockboard_led_probe,
+	.remove		= __devexit_p(sunfire_led_generic_remove),
+	.driver		= {
+		.name	= "sunfire-clockboard-leds",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static struct platform_driver sunfire_fhc_led_driver = {
+	.probe		= sunfire_fhc_led_probe,
+	.remove		= __devexit_p(sunfire_led_generic_remove),
+	.driver		= {
+		.name	= "sunfire-fhc-leds",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init sunfire_leds_init(void)
+{
+	int err = platform_driver_register(&sunfire_clockboard_led_driver);
+
+	if (err) {
+		printk(KERN_ERR PFX "Could not register clock board LED driver\n");
+		return err;
+	}
+
+	err = platform_driver_register(&sunfire_fhc_led_driver);
+	if (err) {
+		printk(KERN_ERR PFX "Could not register FHC LED driver\n");
+		platform_driver_unregister(&sunfire_clockboard_led_driver);
+	}
+
+	return err;
+}
+
+static void __exit sunfire_leds_exit(void)
+{
+	platform_driver_unregister(&sunfire_clockboard_led_driver);
+	platform_driver_unregister(&sunfire_fhc_led_driver);
+}
+
+module_init(sunfire_leds_init);
+module_exit(sunfire_leds_exit);
diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c
index 0d7c88396c88..fd7a1017399a 100644
--- a/drivers/mtd/maps/sun_uflash.c
+++ b/drivers/mtd/maps/sun_uflash.c
@@ -1,13 +1,10 @@
-/*
- *
- * sun_uflash - Driver implementation for user-programmable flash
- * present on many Sun Microsystems SME boardsets.
+/* sun_uflash.c - Driver for user-programmable flash on
+ *                Sun Microsystems SME boardsets.
  *
  * This driver does NOT provide access to the OBP-flash for
  * safety reasons-- use <linux>/drivers/sbus/char/flash.c instead.
  *
  * Copyright (c) 2001 Eric Brower (ebrower@usa.net)
- *
  */
 
 #include <linux/kernel.h>
@@ -16,8 +13,8 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <asm/ebus.h>
-#include <asm/oplib.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <asm/prom.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -26,67 +23,65 @@
 #include <linux/mtd/map.h>
 
 #define UFLASH_OBPNAME	"flashprom"
-#define UFLASH_DEVNAME 	"userflash"
+#define DRIVER_NAME	"sun_uflash"
+#define PFX		DRIVER_NAME ": "
 
 #define UFLASH_WINDOW_SIZE	0x200000
 #define UFLASH_BUSWIDTH		1			/* EBus is 8-bit */
 
 MODULE_AUTHOR("Eric Brower <ebrower@usa.net>");
 MODULE_DESCRIPTION("User-programmable flash device on Sun Microsystems boardsets");
-MODULE_SUPPORTED_DEVICE("userflash");
+MODULE_SUPPORTED_DEVICE(DRIVER_NAME);
 MODULE_LICENSE("GPL");
-MODULE_VERSION("2.0");
+MODULE_VERSION("2.1");
 
-static LIST_HEAD(device_list);
 struct uflash_dev {
 	const char		*name;	/* device name */
 	struct map_info 	map;	/* mtd map info */
 	struct mtd_info		*mtd;	/* mtd info */
 };
 
-
 struct map_info uflash_map_templ = {
 	.name =		"SUNW,???-????",
 	.size =		UFLASH_WINDOW_SIZE,
 	.bankwidth =	UFLASH_BUSWIDTH,
 };
 
-int uflash_devinit(struct linux_ebus_device *edev, struct device_node *dp)
+int uflash_devinit(struct of_device *op, struct device_node *dp)
 {
 	struct uflash_dev *up;
-	struct resource *res;
 
-	res = &edev->resource[0];
-
-	if (edev->num_addrs != 1) {
+	if (op->resource[1].flags) {
 		/* Non-CFI userflash device-- once I find one we
 		 * can work on supporting it.
 		 */
-		printk("%s: unsupported device at 0x%llx (%d regs): " \
-			"email ebrower@usa.net\n",
-		       dp->full_name, (unsigned long long)res->start,
-		       edev->num_addrs);
+		printk(KERN_ERR PFX "Unsupported device at %s, 0x%llx\n",
+		       dp->full_name, (unsigned long long)op->resource[0].start);
 
 		return -ENODEV;
 	}
 
 	up = kzalloc(sizeof(struct uflash_dev), GFP_KERNEL);
-	if (!up)
+	if (!up) {
+		printk(KERN_ERR PFX "Cannot allocate struct uflash_dev\n");
 		return -ENOMEM;
+	}
 
 	/* copy defaults and tweak parameters */
 	memcpy(&up->map, &uflash_map_templ, sizeof(uflash_map_templ));
-	up->map.size = (res->end - res->start) + 1UL;
+
+	up->map.size = resource_size(&op->resource[0]);
 
 	up->name = of_get_property(dp, "model", NULL);
 	if (up->name && 0 < strlen(up->name))
 		up->map.name = (char *)up->name;
 
-	up->map.phys = res->start;
+	up->map.phys = op->resource[0].start;
 
-	up->map.virt = ioremap_nocache(res->start, up->map.size);
+	up->map.virt = of_ioremap(&op->resource[0], 0, up->map.size,
+				  DRIVER_NAME);
 	if (!up->map.virt) {
-		printk("%s: Failed to map device.\n", dp->full_name);
+		printk(KERN_ERR PFX "Failed to map device.\n");
 		kfree(up);
 
 		return -EINVAL;
@@ -97,7 +92,7 @@ int uflash_devinit(struct linux_ebus_device *edev, struct device_node *dp)
 	/* MTD registration */
 	up->mtd = do_map_probe("cfi_probe", &up->map);
 	if (!up->mtd) {
-		iounmap(up->map.virt);
+		of_iounmap(&op->resource[0], up->map.virt, up->map.size);
 		kfree(up);
 
 		return -ENXIO;
@@ -107,32 +102,34 @@ int uflash_devinit(struct linux_ebus_device *edev, struct device_node *dp)
 
 	add_mtd_device(up->mtd);
 
-	dev_set_drvdata(&edev->ofdev.dev, up);
+	dev_set_drvdata(&op->dev, up);
 
 	return 0;
 }
 
-static int __devinit uflash_probe(struct of_device *dev, const struct of_device_id *match)
+static int __devinit uflash_probe(struct of_device *op, const struct of_device_id *match)
 {
-	struct linux_ebus_device *edev = to_ebus_device(&dev->dev);
-	struct device_node *dp = dev->node;
+	struct device_node *dp = op->node;
 
-	if (of_find_property(dp, "user", NULL))
+	/* Flashprom must have the "user" property in order to
+	 * be used by this driver.
+	 */
+	if (!of_find_property(dp, "user", NULL))
 		return -ENODEV;
 
-	return uflash_devinit(edev, dp);
+	return uflash_devinit(op, dp);
 }
 
-static int __devexit uflash_remove(struct of_device *dev)
+static int __devexit uflash_remove(struct of_device *op)
 {
-	struct uflash_dev *up = dev_get_drvdata(&dev->dev);
+	struct uflash_dev *up = dev_get_drvdata(&op->dev);
 
 	if (up->mtd) {
 		del_mtd_device(up->mtd);
 		map_destroy(up->mtd);
 	}
 	if (up->map.virt) {
-		iounmap(up->map.virt);
+		of_iounmap(&op->resource[0], up->map.virt, up->map.size);
 		up->map.virt = NULL;
 	}
 
@@ -141,7 +138,7 @@ static int __devexit uflash_remove(struct of_device *dev)
 	return 0;
 }
 
-static struct of_device_id uflash_match[] = {
+static const struct of_device_id uflash_match[] = {
 	{
 		.name = UFLASH_OBPNAME,
 	},
@@ -151,7 +148,7 @@ static struct of_device_id uflash_match[] = {
 MODULE_DEVICE_TABLE(of, uflash_match);
 
 static struct of_platform_driver uflash_driver = {
-	.name		= UFLASH_DEVNAME,
+	.name		= DRIVER_NAME,
 	.match_table	= uflash_match,
 	.probe		= uflash_probe,
 	.remove		= __devexit_p(uflash_remove),
@@ -159,7 +156,7 @@ static struct of_platform_driver uflash_driver = {
 
 static int __init uflash_init(void)
 {
-	return of_register_driver(&uflash_driver, &ebus_bus_type);
+	return of_register_driver(&uflash_driver, &of_bus_type);
 }
 
 static void __exit uflash_exit(void)
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index 06e682334c7e..3ad7589d6a1c 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -1,6 +1,6 @@
 /* myri_sbus.c: MyriCOM MyriNET SBUS card driver.
  *
- * Copyright (C) 1996, 1999, 2006 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1996, 1999, 2006, 2008 David S. Miller (davem@davemloft.net)
  */
 
 static char version[] =
@@ -22,6 +22,9 @@ static char version[] =
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <net/dst.h>
 #include <net/arp.h>
@@ -33,7 +36,6 @@ static char version[] =
 #include <asm/dma.h>
 #include <asm/byteorder.h>
 #include <asm/idprom.h>
-#include <asm/sbus.h>
 #include <asm/openprom.h>
 #include <asm/oplib.h>
 #include <asm/auxio.h>
@@ -243,7 +245,8 @@ static void myri_clean_rings(struct myri_eth *mp)
 			u32 dma_addr;
 
 			dma_addr = sbus_readl(&rxd->myri_scatters[0].addr);
-			sbus_unmap_single(mp->myri_sdev, dma_addr, RX_ALLOC_SIZE, SBUS_DMA_FROMDEVICE);
+			dma_unmap_single(&mp->myri_op->dev, dma_addr,
+					 RX_ALLOC_SIZE, DMA_FROM_DEVICE);
 			dev_kfree_skb(mp->rx_skbs[i]);
 			mp->rx_skbs[i] = NULL;
 		}
@@ -259,7 +262,9 @@ static void myri_clean_rings(struct myri_eth *mp)
 			u32 dma_addr;
 
 			dma_addr = sbus_readl(&txd->myri_gathers[0].addr);
-			sbus_unmap_single(mp->myri_sdev, dma_addr, (skb->len + 3) & ~3, SBUS_DMA_TODEVICE);
+			dma_unmap_single(&mp->myri_op->dev, dma_addr,
+					 (skb->len + 3) & ~3,
+					 DMA_TO_DEVICE);
 			dev_kfree_skb(mp->tx_skbs[i]);
 			mp->tx_skbs[i] = NULL;
 		}
@@ -288,7 +293,9 @@ static void myri_init_rings(struct myri_eth *mp, int from_irq)
 		skb->dev = dev;
 		skb_put(skb, RX_ALLOC_SIZE);
 
-		dma_addr = sbus_map_single(mp->myri_sdev, skb->data, RX_ALLOC_SIZE, SBUS_DMA_FROMDEVICE);
+		dma_addr = dma_map_single(&mp->myri_op->dev,
+					  skb->data, RX_ALLOC_SIZE,
+					  DMA_FROM_DEVICE);
 		sbus_writel(dma_addr, &rxd[i].myri_scatters[0].addr);
 		sbus_writel(RX_ALLOC_SIZE, &rxd[i].myri_scatters[0].len);
 		sbus_writel(i, &rxd[i].ctx);
@@ -344,7 +351,8 @@ static void myri_tx(struct myri_eth *mp, struct net_device *dev)
 
 		DTX(("SKB[%d] ", entry));
 		dma_addr = sbus_readl(&sq->myri_txd[entry].myri_gathers[0].addr);
-		sbus_unmap_single(mp->myri_sdev, dma_addr, skb->len, SBUS_DMA_TODEVICE);
+		dma_unmap_single(&mp->myri_op->dev, dma_addr,
+				 skb->len, DMA_TO_DEVICE);
 		dev_kfree_skb(skb);
 		mp->tx_skbs[entry] = NULL;
 		dev->stats.tx_packets++;
@@ -423,9 +431,9 @@ static void myri_rx(struct myri_eth *mp, struct net_device *dev)
 
 		/* Check for errors. */
 		DRX(("rxd[%d]: %p len[%d] csum[%08x] ", entry, rxd, len, csum));
-		sbus_dma_sync_single_for_cpu(mp->myri_sdev,
-					     sbus_readl(&rxd->myri_scatters[0].addr),
-					     RX_ALLOC_SIZE, SBUS_DMA_FROMDEVICE);
+		dma_sync_single_for_cpu(&mp->myri_op->dev,
+					sbus_readl(&rxd->myri_scatters[0].addr),
+					RX_ALLOC_SIZE, DMA_FROM_DEVICE);
 		if (len < (ETH_HLEN + MYRI_PAD_LEN) || (skb->data[0] != MYRI_PAD_LEN)) {
 			DRX(("ERROR["));
 			dev->stats.rx_errors++;
@@ -442,10 +450,10 @@ static void myri_rx(struct myri_eth *mp, struct net_device *dev)
 			drops++;
 			DRX(("DROP "));
 			dev->stats.rx_dropped++;
-			sbus_dma_sync_single_for_device(mp->myri_sdev,
-							sbus_readl(&rxd->myri_scatters[0].addr),
-							RX_ALLOC_SIZE,
-							SBUS_DMA_FROMDEVICE);
+			dma_sync_single_for_device(&mp->myri_op->dev,
+						   sbus_readl(&rxd->myri_scatters[0].addr),
+						   RX_ALLOC_SIZE,
+						   DMA_FROM_DEVICE);
 			sbus_writel(RX_ALLOC_SIZE, &rxd->myri_scatters[0].len);
 			sbus_writel(index, &rxd->ctx);
 			sbus_writel(1, &rxd->num_sg);
@@ -464,17 +472,17 @@ static void myri_rx(struct myri_eth *mp, struct net_device *dev)
 				DRX(("skb_alloc(FAILED) "));
 				goto drop_it;
 			}
-			sbus_unmap_single(mp->myri_sdev,
-					  sbus_readl(&rxd->myri_scatters[0].addr),
-					  RX_ALLOC_SIZE,
-					  SBUS_DMA_FROMDEVICE);
+			dma_unmap_single(&mp->myri_op->dev,
+					 sbus_readl(&rxd->myri_scatters[0].addr),
+					 RX_ALLOC_SIZE,
+					 DMA_FROM_DEVICE);
 			mp->rx_skbs[index] = new_skb;
 			new_skb->dev = dev;
 			skb_put(new_skb, RX_ALLOC_SIZE);
-			dma_addr = sbus_map_single(mp->myri_sdev,
-						   new_skb->data,
-						   RX_ALLOC_SIZE,
-						   SBUS_DMA_FROMDEVICE);
+			dma_addr = dma_map_single(&mp->myri_op->dev,
+						  new_skb->data,
+						  RX_ALLOC_SIZE,
+						  DMA_FROM_DEVICE);
 			sbus_writel(dma_addr, &rxd->myri_scatters[0].addr);
 			sbus_writel(RX_ALLOC_SIZE, &rxd->myri_scatters[0].len);
 			sbus_writel(index, &rxd->ctx);
@@ -500,10 +508,10 @@ static void myri_rx(struct myri_eth *mp, struct net_device *dev)
 
 			/* Reuse original ring buffer. */
 			DRX(("reuse "));
-			sbus_dma_sync_single_for_device(mp->myri_sdev,
-							sbus_readl(&rxd->myri_scatters[0].addr),
-							RX_ALLOC_SIZE,
-							SBUS_DMA_FROMDEVICE);
+			dma_sync_single_for_device(&mp->myri_op->dev,
+						   sbus_readl(&rxd->myri_scatters[0].addr),
+						   RX_ALLOC_SIZE,
+						   DMA_FROM_DEVICE);
 			sbus_writel(RX_ALLOC_SIZE, &rxd->myri_scatters[0].len);
 			sbus_writel(index, &rxd->ctx);
 			sbus_writel(1, &rxd->num_sg);
@@ -652,7 +660,8 @@ static int myri_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		sbus_writew((skb->data[4] << 8) | skb->data[5], &txd->addr[3]);
 	}
 
-	dma_addr = sbus_map_single(mp->myri_sdev, skb->data, len, SBUS_DMA_TODEVICE);
+	dma_addr = dma_map_single(&mp->myri_op->dev, skb->data,
+				  len, DMA_TO_DEVICE);
 	sbus_writel(dma_addr, &txd->myri_gathers[0].addr);
 	sbus_writel(len, &txd->myri_gathers[0].len);
 	sbus_writel(1, &txd->num_sg);
@@ -891,30 +900,30 @@ static const struct header_ops myri_header_ops = {
 	.cache_update	= myri_header_cache_update,
 };
 
-static int __devinit myri_ether_init(struct sbus_dev *sdev)
+static int __devinit myri_sbus_probe(struct of_device *op, const struct of_device_id *match)
 {
-	static int num;
+	struct device_node *dp = op->node;
 	static unsigned version_printed;
 	struct net_device *dev;
-	struct myri_eth *mp;
-	unsigned char prop_buf[32];
-	int i;
 	DECLARE_MAC_BUF(mac);
+	struct myri_eth *mp;
+	const void *prop;
+	static int num;
+	int i, len;
 
-	DET(("myri_ether_init(%p,%d):\n", sdev, num));
+	DET(("myri_ether_init(%p,%d):\n", op, num));
 	dev = alloc_etherdev(sizeof(struct myri_eth));
-
 	if (!dev)
 		return -ENOMEM;
 
 	if (version_printed++ == 0)
 		printk(version);
 
-	SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
+	SET_NETDEV_DEV(dev, &op->dev);
 
-	mp = (struct myri_eth *) dev->priv;
+	mp = netdev_priv(dev);
 	spin_lock_init(&mp->irq_lock);
-	mp->myri_sdev = sdev;
+	mp->myri_op = op;
 
 	/* Clean out skb arrays. */
 	for (i = 0; i < (RX_RING_SIZE + 1); i++)
@@ -924,55 +933,44 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev)
 		mp->tx_skbs[i] = NULL;
 
 	/* First check for EEPROM information. */
-	i = prom_getproperty(sdev->prom_node, "myrinet-eeprom-info",
-			     (char *)&mp->eeprom, sizeof(struct myri_eeprom));
-	DET(("prom_getprop(myrinet-eeprom-info) returns %d\n", i));
-	if (i == 0 || i == -1) {
+	prop = of_get_property(dp, "myrinet-eeprom-info", &len);
+
+	if (prop)
+		memcpy(&mp->eeprom, prop, sizeof(struct myri_eeprom));
+	if (!prop) {
 		/* No eeprom property, must cook up the values ourselves. */
 		DET(("No EEPROM: "));
 		mp->eeprom.bus_type = BUS_TYPE_SBUS;
-		mp->eeprom.cpuvers = prom_getintdefault(sdev->prom_node,"cpu_version",0);
-		mp->eeprom.cval = prom_getintdefault(sdev->prom_node,"clock_value",0);
-		mp->eeprom.ramsz = prom_getintdefault(sdev->prom_node,"sram_size",0);
-		DET(("cpuvers[%d] cval[%d] ramsz[%d]\n", mp->eeprom.cpuvers,
-		     mp->eeprom.cval, mp->eeprom.ramsz));
-		if (mp->eeprom.cpuvers == 0) {
-			DET(("EEPROM: cpuvers was zero, setting to %04x\n",CPUVERS_2_3));
+		mp->eeprom.cpuvers =
+			of_getintprop_default(dp, "cpu_version", 0);
+		mp->eeprom.cval =
+			of_getintprop_default(dp, "clock_value", 0);
+		mp->eeprom.ramsz = of_getintprop_default(dp, "sram_size", 0);
+		if (!mp->eeprom.cpuvers)
 			mp->eeprom.cpuvers = CPUVERS_2_3;
-		}
-		if (mp->eeprom.cpuvers < CPUVERS_3_0) {
-			DET(("EEPROM: cpuvers < CPUVERS_3_0, clockval set to zero.\n"));
+		if (mp->eeprom.cpuvers < CPUVERS_3_0)
 			mp->eeprom.cval = 0;
-		}
-		if (mp->eeprom.ramsz == 0) {
-			DET(("EEPROM: ramsz == 0, setting to 128k\n"));
+		if (!mp->eeprom.ramsz)
 			mp->eeprom.ramsz = (128 * 1024);
-		}
-		i = prom_getproperty(sdev->prom_node, "myrinet-board-id",
-				     &prop_buf[0], 10);
-		DET(("EEPROM: prom_getprop(myrinet-board-id) returns %d\n", i));
-		if ((i != 0) && (i != -1))
-			memcpy(&mp->eeprom.id[0], &prop_buf[0], 6);
+
+		prop = of_get_property(dp, "myrinet-board-id", &len);
+		if (prop)
+			memcpy(&mp->eeprom.id[0], prop, 6);
 		else
 			set_boardid_from_idprom(mp, num);
-		i = prom_getproperty(sdev->prom_node, "fpga_version",
-				     &mp->eeprom.fvers[0], 32);
-		DET(("EEPROM: prom_getprop(fpga_version) returns %d\n", i));
-		if (i == 0 || i == -1)
+
+		prop = of_get_property(dp, "fpga_version", &len);
+		if (prop)
+			memcpy(&mp->eeprom.fvers[0], prop, 32);
+		else
 			memset(&mp->eeprom.fvers[0], 0, 32);
 
 		if (mp->eeprom.cpuvers == CPUVERS_4_1) {
-			DET(("EEPROM: cpuvers CPUVERS_4_1, "));
-			if (mp->eeprom.ramsz == (128 * 1024)) {
-				DET(("ramsize 128k, setting to 256k, "));
+			if (mp->eeprom.ramsz == (128 * 1024))
 				mp->eeprom.ramsz = (256 * 1024);
-			}
-			if ((mp->eeprom.cval==0x40414041)||(mp->eeprom.cval==0x90449044)){
-				DET(("changing cval from %08x to %08x ",
-				     mp->eeprom.cval, 0x50e450e4));
+			if ((mp->eeprom.cval == 0x40414041) ||
+			    (mp->eeprom.cval == 0x90449044))
 				mp->eeprom.cval = 0x50e450e4;
-			}
-			DET(("\n"));
 		}
 	}
 #ifdef DEBUG_DETECT
@@ -991,8 +989,8 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev)
 		 * XXX only a valid version for PCI cards?  Ask feldy...
 		 */
 		DET(("Mapping regs for cpuvers < CPUVERS_4_0\n"));
-		mp->regs = sbus_ioremap(&sdev->resource[0], 0,
-					mp->reg_size, "MyriCOM Regs");
+		mp->regs = of_ioremap(&op->resource[0], 0,
+				      mp->reg_size, "MyriCOM Regs");
 		if (!mp->regs) {
 			printk("MyriCOM: Cannot map MyriCOM registers.\n");
 			goto err;
@@ -1001,13 +999,12 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev)
 		mp->lregs = mp->lanai + (0x10000 * 2);
 	} else {
 		DET(("Mapping regs for cpuvers >= CPUVERS_4_0\n"));
-		mp->cregs = sbus_ioremap(&sdev->resource[0], 0,
-					 PAGE_SIZE, "MyriCOM Control Regs");
-		mp->lregs = sbus_ioremap(&sdev->resource[0], (256 * 1024),
+		mp->cregs = of_ioremap(&op->resource[0], 0,
+				       PAGE_SIZE, "MyriCOM Control Regs");
+		mp->lregs = of_ioremap(&op->resource[0], (256 * 1024),
 					 PAGE_SIZE, "MyriCOM LANAI Regs");
-		mp->lanai =
-			sbus_ioremap(&sdev->resource[0], (512 * 1024),
-				     mp->eeprom.ramsz, "MyriCOM SRAM");
+		mp->lanai = of_ioremap(&op->resource[0], (512 * 1024),
+				       mp->eeprom.ramsz, "MyriCOM SRAM");
 	}
 	DET(("Registers mapped: cregs[%p] lregs[%p] lanai[%p]\n",
 	     mp->cregs, mp->lregs, mp->lanai));
@@ -1039,16 +1036,15 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev)
 	myri_reset_on(mp->cregs);
 
 	/* Get the supported DVMA burst sizes from our SBUS. */
-	mp->myri_bursts = prom_getintdefault(mp->myri_sdev->bus->prom_node,
-					     "burst-sizes", 0x00);
-
-	if (!sbus_can_burst64(sdev))
+	mp->myri_bursts = of_getintprop_default(dp->parent,
+						"burst-sizes", 0x00);
+	if (!sbus_can_burst64())
 		mp->myri_bursts &= ~(DMA_BURST64);
 
 	DET(("MYRI bursts %02x\n", mp->myri_bursts));
 
 	/* Encode SBUS interrupt level in second control register. */
-	i = prom_getint(sdev->prom_node, "interrupts");
+	i = of_getintprop_default(dp, "interrupts", 0);
 	if (i == 0)
 		i = 4;
 	DET(("prom_getint(interrupts)==%d, irqlvl set to %04x\n",
@@ -1063,7 +1059,7 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev)
 	dev->tx_timeout = &myri_tx_timeout;
 	dev->watchdog_timeo = 5*HZ;
 	dev->set_multicast_list = &myri_set_multicast;
-	dev->irq = sdev->irqs[0];
+	dev->irq = op->irqs[0];
 
 	/* Register interrupt handler now. */
 	DET(("Requesting MYRIcom IRQ line.\n"));
@@ -1088,7 +1084,7 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev)
 		goto err_free_irq;
 	}
 
-	dev_set_drvdata(&sdev->ofdev.dev, mp);
+	dev_set_drvdata(&op->dev, mp);
 
 	num++;
 
@@ -1105,17 +1101,9 @@ err:
 	return -ENODEV;
 }
 
-
-static int __devinit myri_sbus_probe(struct of_device *dev, const struct of_device_id *match)
-{
-	struct sbus_dev *sdev = to_sbus_device(&dev->dev);
-
-	return myri_ether_init(sdev);
-}
-
-static int __devexit myri_sbus_remove(struct of_device *dev)
+static int __devexit myri_sbus_remove(struct of_device *op)
 {
-	struct myri_eth *mp = dev_get_drvdata(&dev->dev);
+	struct myri_eth *mp = dev_get_drvdata(&op->dev);
 	struct net_device *net_dev = mp->dev;
 
 	unregister_netdev(net_dev);
@@ -1123,21 +1111,21 @@ static int __devexit myri_sbus_remove(struct of_device *dev)
 	free_irq(net_dev->irq, net_dev);
 
 	if (mp->eeprom.cpuvers < CPUVERS_4_0) {
-		sbus_iounmap(mp->regs, mp->reg_size);
+		of_iounmap(&op->resource[0], mp->regs, mp->reg_size);
 	} else {
-		sbus_iounmap(mp->cregs, PAGE_SIZE);
-		sbus_iounmap(mp->lregs, (256 * 1024));
-		sbus_iounmap(mp->lanai, (512 * 1024));
+		of_iounmap(&op->resource[0], mp->cregs, PAGE_SIZE);
+		of_iounmap(&op->resource[0], mp->lregs, (256 * 1024));
+		of_iounmap(&op->resource[0], mp->lanai, (512 * 1024));
 	}
 
 	free_netdev(net_dev);
 
-	dev_set_drvdata(&dev->dev, NULL);
+	dev_set_drvdata(&op->dev, NULL);
 
 	return 0;
 }
 
-static struct of_device_id myri_sbus_match[] = {
+static const struct of_device_id myri_sbus_match[] = {
 	{
 		.name = "MYRICOM,mlanai",
 	},
@@ -1158,7 +1146,7 @@ static struct of_platform_driver myri_sbus_driver = {
 
 static int __init myri_sbus_init(void)
 {
-	return of_register_driver(&myri_sbus_driver, &sbus_bus_type);
+	return of_register_driver(&myri_sbus_driver, &of_bus_type);
 }
 
 static void __exit myri_sbus_exit(void)
diff --git a/drivers/net/myri_sbus.h b/drivers/net/myri_sbus.h
index 5d93fcc95d55..ff363e95d9cf 100644
--- a/drivers/net/myri_sbus.h
+++ b/drivers/net/myri_sbus.h
@@ -288,7 +288,7 @@ struct myri_eth {
 	struct myri_eeprom		eeprom;		/* Local copy of EEPROM.      */
 	unsigned int			reg_size;	/* Size of register space.    */
 	unsigned int			shmem_base;	/* Offset to shared ram.      */
-	struct sbus_dev			*myri_sdev;	/* Our SBUS device struct.    */
+	struct of_device		*myri_op;	/* Our OF device struct.    */
 };
 
 /* We use this to acquire receive skb's that we can DMA directly into. */
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index e3be81eba8a4..ebc812702903 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -9130,7 +9130,7 @@ static int __devexit niu_of_remove(struct of_device *op)
 	return 0;
 }
 
-static struct of_device_id niu_match[] = {
+static const struct of_device_id niu_match[] = {
 	{
 		.name = "network",
 		.compatible = "SUNW,niusl",
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index 31e7384e312a..018d0fca9422 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -1,7 +1,6 @@
-/* $Id: sunbmac.c,v 1.30 2002/01/15 06:48:55 davem Exp $
- * sunbmac.c: Driver for Sparc BigMAC 100baseT ethernet adapters.
+/* sunbmac.c: Driver for Sparc BigMAC 100baseT ethernet adapters.
  *
- * Copyright (C) 1997, 1998, 1999, 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1997, 1998, 1999, 2003, 2008 David S. Miller (davem@davemloft.net)
  */
 
 #include <linux/module.h>
@@ -23,6 +22,9 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <asm/auxio.h>
 #include <asm/byteorder.h>
@@ -32,15 +34,14 @@
 #include <asm/openprom.h>
 #include <asm/oplib.h>
 #include <asm/pgtable.h>
-#include <asm/sbus.h>
 #include <asm/system.h>
 
 #include "sunbmac.h"
 
 #define DRV_NAME	"sunbmac"
-#define DRV_VERSION	"2.0"
-#define DRV_RELDATE	"11/24/03"
-#define DRV_AUTHOR	"David S. Miller (davem@redhat.com)"
+#define DRV_VERSION	"2.1"
+#define DRV_RELDATE	"August 26, 2008"
+#define DRV_AUTHOR	"David S. Miller (davem@davemloft.net)"
 
 static char version[] =
 	DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
@@ -96,8 +97,8 @@ static int qec_global_reset(void __iomem *gregs)
 
 static void qec_init(struct bigmac *bp)
 {
+	struct of_device *qec_op = bp->qec_op;
 	void __iomem *gregs = bp->gregs;
-	struct sbus_dev *qec_sdev = bp->qec_sdev;
 	u8 bsizes = bp->bigmac_bursts;
 	u32 regval;
 
@@ -112,13 +113,13 @@ static void qec_init(struct bigmac *bp)
 	sbus_writel(GLOB_PSIZE_2048, gregs + GLOB_PSIZE);
 
 	/* All of memsize is given to bigmac. */
-	sbus_writel(qec_sdev->reg_addrs[1].reg_size,
+	sbus_writel(resource_size(&qec_op->resource[1]),
 		    gregs + GLOB_MSIZE);
 
 	/* Half to the transmitter, half to the receiver. */
-	sbus_writel(qec_sdev->reg_addrs[1].reg_size >> 1,
+	sbus_writel(resource_size(&qec_op->resource[1]) >> 1,
 		    gregs + GLOB_TSIZE);
-	sbus_writel(qec_sdev->reg_addrs[1].reg_size >> 1,
+	sbus_writel(resource_size(&qec_op->resource[1]) >> 1,
 		    gregs + GLOB_RSIZE);
 }
 
@@ -239,9 +240,10 @@ static void bigmac_init_rings(struct bigmac *bp, int from_irq)
 		skb_reserve(skb, 34);
 
 		bb->be_rxd[i].rx_addr =
-			sbus_map_single(bp->bigmac_sdev, skb->data,
-					RX_BUF_ALLOC_SIZE - 34,
-					SBUS_DMA_FROMDEVICE);
+			dma_map_single(&bp->bigmac_op->dev,
+				       skb->data,
+				       RX_BUF_ALLOC_SIZE - 34,
+				       DMA_FROM_DEVICE);
 		bb->be_rxd[i].rx_flags =
 			(RXD_OWN | ((RX_BUF_ALLOC_SIZE - 34) & RXD_LENGTH));
 	}
@@ -776,9 +778,9 @@ static void bigmac_tx(struct bigmac *bp)
 		skb = bp->tx_skbs[elem];
 		bp->enet_stats.tx_packets++;
 		bp->enet_stats.tx_bytes += skb->len;
-		sbus_unmap_single(bp->bigmac_sdev,
-				  this->tx_addr, skb->len,
-				  SBUS_DMA_TODEVICE);
+		dma_unmap_single(&bp->bigmac_op->dev,
+				 this->tx_addr, skb->len,
+				 DMA_TO_DEVICE);
 
 		DTX(("skb(%p) ", skb));
 		bp->tx_skbs[elem] = NULL;
@@ -831,18 +833,19 @@ static void bigmac_rx(struct bigmac *bp)
 				drops++;
 				goto drop_it;
 			}
-			sbus_unmap_single(bp->bigmac_sdev,
-					  this->rx_addr,
-					  RX_BUF_ALLOC_SIZE - 34,
-					  SBUS_DMA_FROMDEVICE);
+			dma_unmap_single(&bp->bigmac_op->dev,
+					 this->rx_addr,
+					 RX_BUF_ALLOC_SIZE - 34,
+					 DMA_FROM_DEVICE);
 			bp->rx_skbs[elem] = new_skb;
 			new_skb->dev = bp->dev;
 			skb_put(new_skb, ETH_FRAME_LEN);
 			skb_reserve(new_skb, 34);
-			this->rx_addr = sbus_map_single(bp->bigmac_sdev,
-							new_skb->data,
-							RX_BUF_ALLOC_SIZE - 34,
-							SBUS_DMA_FROMDEVICE);
+			this->rx_addr =
+				dma_map_single(&bp->bigmac_op->dev,
+					       new_skb->data,
+					       RX_BUF_ALLOC_SIZE - 34,
+					       DMA_FROM_DEVICE);
 			this->rx_flags =
 				(RXD_OWN | ((RX_BUF_ALLOC_SIZE - 34) & RXD_LENGTH));
 
@@ -857,13 +860,13 @@ static void bigmac_rx(struct bigmac *bp)
 			}
 			skb_reserve(copy_skb, 2);
 			skb_put(copy_skb, len);
-			sbus_dma_sync_single_for_cpu(bp->bigmac_sdev,
-						     this->rx_addr, len,
-						     SBUS_DMA_FROMDEVICE);
+			dma_sync_single_for_cpu(&bp->bigmac_op->dev,
+						this->rx_addr, len,
+						DMA_FROM_DEVICE);
 			skb_copy_to_linear_data(copy_skb, (unsigned char *)skb->data, len);
-			sbus_dma_sync_single_for_device(bp->bigmac_sdev,
-							this->rx_addr, len,
-							SBUS_DMA_FROMDEVICE);
+			dma_sync_single_for_device(&bp->bigmac_op->dev,
+						   this->rx_addr, len,
+						   DMA_FROM_DEVICE);
 
 			/* Reuse original ring buffer. */
 			this->rx_flags =
@@ -959,7 +962,8 @@ static int bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	u32 mapping;
 
 	len = skb->len;
-	mapping = sbus_map_single(bp->bigmac_sdev, skb->data, len, SBUS_DMA_TODEVICE);
+	mapping = dma_map_single(&bp->bigmac_op->dev, skb->data,
+				 len, DMA_TO_DEVICE);
 
 	/* Avoid a race... */
 	spin_lock_irq(&bp->lock);
@@ -1051,12 +1055,8 @@ static void bigmac_set_multicast(struct net_device *dev)
 /* Ethtool support... */
 static void bigmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-	struct bigmac *bp = dev->priv;
-
 	strcpy(info->driver, "sunbmac");
 	strcpy(info->version, "2.0");
-	sprintf(info->bus_info, "SBUS:%d",
-		bp->qec_sdev->slot);
 }
 
 static u32 bigmac_get_link(struct net_device *dev)
@@ -1075,14 +1075,15 @@ static const struct ethtool_ops bigmac_ethtool_ops = {
 	.get_link		= bigmac_get_link,
 };
 
-static int __devinit bigmac_ether_init(struct sbus_dev *qec_sdev)
+static int __devinit bigmac_ether_init(struct of_device *op,
+				       struct of_device *qec_op)
 {
-	struct net_device *dev;
 	static int version_printed;
-	struct bigmac *bp;
+	struct net_device *dev;
 	u8 bsizes, bsizes_more;
-	int i;
 	DECLARE_MAC_BUF(mac);
+	struct bigmac *bp;
+	int i;
 
 	/* Get a new device struct for this interface. */
 	dev = alloc_etherdev(sizeof(struct bigmac));
@@ -1092,32 +1093,21 @@ static int __devinit bigmac_ether_init(struct sbus_dev *qec_sdev)
 	if (version_printed++ == 0)
 		printk(KERN_INFO "%s", version);
 
-	dev->base_addr = (long) qec_sdev;
 	for (i = 0; i < 6; i++)
 		dev->dev_addr[i] = idprom->id_ethaddr[i];
 
 	/* Setup softc, with backpointers to QEC and BigMAC SBUS device structs. */
-	bp = dev->priv;
-	bp->qec_sdev = qec_sdev;
-	bp->bigmac_sdev = qec_sdev->child;
+	bp = netdev_priv(dev);
+	bp->qec_op = qec_op;
+	bp->bigmac_op = op;
 
-	SET_NETDEV_DEV(dev, &bp->bigmac_sdev->ofdev.dev);
+	SET_NETDEV_DEV(dev, &op->dev);
 
 	spin_lock_init(&bp->lock);
 
-	/* Verify the registers we expect, are actually there. */
-	if ((bp->bigmac_sdev->num_registers != 3) ||
-	   (bp->qec_sdev->num_registers != 2)) {
-		printk(KERN_ERR "BIGMAC: Device does not have 2 and 3 regs, it has %d and %d.\n",
-		       bp->qec_sdev->num_registers,
-		       bp->bigmac_sdev->num_registers);
-		printk(KERN_ERR "BIGMAC: Would you like that for here or to go?\n");
-		goto fail_and_cleanup;
-	}
-
 	/* Map in QEC global control registers. */
-	bp->gregs = sbus_ioremap(&bp->qec_sdev->resource[0], 0,
-				 GLOB_REG_SIZE, "BigMAC QEC GLobal Regs");
+	bp->gregs = of_ioremap(&qec_op->resource[0], 0,
+			       GLOB_REG_SIZE, "BigMAC QEC GLobal Regs");
 	if (!bp->gregs) {
 		printk(KERN_ERR "BIGMAC: Cannot map QEC global registers.\n");
 		goto fail_and_cleanup;
@@ -1134,13 +1124,8 @@ static int __devinit bigmac_ether_init(struct sbus_dev *qec_sdev)
 		goto fail_and_cleanup;
 
 	/* Get supported SBUS burst sizes. */
-	bsizes = prom_getintdefault(bp->qec_sdev->prom_node,
-				    "burst-sizes",
-				    0xff);
-
-	bsizes_more = prom_getintdefault(bp->qec_sdev->bus->prom_node,
-					 "burst-sizes",
-					 0xff);
+	bsizes = of_getintprop_default(qec_op->node, "burst-sizes", 0xff);
+	bsizes_more = of_getintprop_default(qec_op->node, "burst-sizes", 0xff);
 
 	bsizes &= 0xff;
 	if (bsizes_more != 0xff)
@@ -1154,16 +1139,16 @@ static int __devinit bigmac_ether_init(struct sbus_dev *qec_sdev)
 	qec_init(bp);
 
 	/* Map in the BigMAC channel registers. */
-	bp->creg = sbus_ioremap(&bp->bigmac_sdev->resource[0], 0,
-				CREG_REG_SIZE, "BigMAC QEC Channel Regs");
+	bp->creg = of_ioremap(&op->resource[0], 0,
+			      CREG_REG_SIZE, "BigMAC QEC Channel Regs");
 	if (!bp->creg) {
 		printk(KERN_ERR "BIGMAC: Cannot map QEC channel registers.\n");
 		goto fail_and_cleanup;
 	}
 
 	/* Map in the BigMAC control registers. */
-	bp->bregs = sbus_ioremap(&bp->bigmac_sdev->resource[1], 0,
-				 BMAC_REG_SIZE, "BigMAC Primary Regs");
+	bp->bregs = of_ioremap(&op->resource[1], 0,
+			       BMAC_REG_SIZE, "BigMAC Primary Regs");
 	if (!bp->bregs) {
 		printk(KERN_ERR "BIGMAC: Cannot map BigMAC primary registers.\n");
 		goto fail_and_cleanup;
@@ -1172,8 +1157,8 @@ static int __devinit bigmac_ether_init(struct sbus_dev *qec_sdev)
 	/* Map in the BigMAC transceiver registers, this is how you poke at
 	 * the BigMAC's PHY.
 	 */
-	bp->tregs = sbus_ioremap(&bp->bigmac_sdev->resource[2], 0,
-				 TCVR_REG_SIZE, "BigMAC Transceiver Regs");
+	bp->tregs = of_ioremap(&op->resource[2], 0,
+			       TCVR_REG_SIZE, "BigMAC Transceiver Regs");
 	if (!bp->tregs) {
 		printk(KERN_ERR "BIGMAC: Cannot map BigMAC transceiver registers.\n");
 		goto fail_and_cleanup;
@@ -1183,17 +1168,17 @@ static int __devinit bigmac_ether_init(struct sbus_dev *qec_sdev)
 	bigmac_stop(bp);
 
 	/* Allocate transmit/receive descriptor DVMA block. */
-	bp->bmac_block = sbus_alloc_consistent(bp->bigmac_sdev,
-					       PAGE_SIZE,
-					       &bp->bblock_dvma);
+	bp->bmac_block = dma_alloc_coherent(&bp->bigmac_op->dev,
+					    PAGE_SIZE,
+					    &bp->bblock_dvma, GFP_ATOMIC);
 	if (bp->bmac_block == NULL || bp->bblock_dvma == 0) {
 		printk(KERN_ERR "BIGMAC: Cannot allocate consistent DMA.\n");
 		goto fail_and_cleanup;
 	}
 
 	/* Get the board revision of this BigMAC. */
-	bp->board_rev = prom_getintdefault(bp->bigmac_sdev->prom_node,
-					   "board-version", 1);
+	bp->board_rev = of_getintprop_default(bp->bigmac_op->node,
+					      "board-version", 1);
 
 	/* Init auto-negotiation timer state. */
 	init_timer(&bp->bigmac_timer);
@@ -1217,7 +1202,7 @@ static int __devinit bigmac_ether_init(struct sbus_dev *qec_sdev)
 	dev->watchdog_timeo = 5*HZ;
 
 	/* Finish net device registration. */
-	dev->irq = bp->bigmac_sdev->irqs[0];
+	dev->irq = bp->bigmac_op->irqs[0];
 	dev->dma = 0;
 
 	if (register_netdev(dev)) {
@@ -1225,7 +1210,7 @@ static int __devinit bigmac_ether_init(struct sbus_dev *qec_sdev)
 		goto fail_and_cleanup;
 	}
 
-	dev_set_drvdata(&bp->bigmac_sdev->ofdev.dev, bp);
+	dev_set_drvdata(&bp->bigmac_op->dev, bp);
 
 	printk(KERN_INFO "%s: BigMAC 100baseT Ethernet %s\n",
 	       dev->name, print_mac(mac, dev->dev_addr));
@@ -1236,66 +1221,67 @@ fail_and_cleanup:
 	/* Something went wrong, undo whatever we did so far. */
 	/* Free register mappings if any. */
 	if (bp->gregs)
-		sbus_iounmap(bp->gregs, GLOB_REG_SIZE);
+		of_iounmap(&qec_op->resource[0], bp->gregs, GLOB_REG_SIZE);
 	if (bp->creg)
-		sbus_iounmap(bp->creg, CREG_REG_SIZE);
+		of_iounmap(&op->resource[0], bp->creg, CREG_REG_SIZE);
 	if (bp->bregs)
-		sbus_iounmap(bp->bregs, BMAC_REG_SIZE);
+		of_iounmap(&op->resource[1], bp->bregs, BMAC_REG_SIZE);
 	if (bp->tregs)
-		sbus_iounmap(bp->tregs, TCVR_REG_SIZE);
+		of_iounmap(&op->resource[2], bp->tregs, TCVR_REG_SIZE);
 
 	if (bp->bmac_block)
-		sbus_free_consistent(bp->bigmac_sdev,
-				     PAGE_SIZE,
-				     bp->bmac_block,
-				     bp->bblock_dvma);
+		dma_free_coherent(&bp->bigmac_op->dev,
+				  PAGE_SIZE,
+				  bp->bmac_block,
+				  bp->bblock_dvma);
 
 	/* This also frees the co-located 'dev->priv' */
 	free_netdev(dev);
 	return -ENODEV;
 }
 
-/* QEC can be the parent of either QuadEthernet or
- * a BigMAC.  We want the latter.
+/* QEC can be the parent of either QuadEthernet or a BigMAC.  We want
+ * the latter.
  */
-static int __devinit bigmac_sbus_probe(struct of_device *dev, const struct of_device_id *match)
+static int __devinit bigmac_sbus_probe(struct of_device *op,
+				       const struct of_device_id *match)
 {
-	struct sbus_dev *sdev = to_sbus_device(&dev->dev);
-	struct device_node *dp = dev->node;
+	struct device *parent = op->dev.parent;
+	struct of_device *qec_op;
 
-	if (!strcmp(dp->name, "be"))
-		sdev = sdev->parent;
+	qec_op = to_of_device(parent);
 
-	return bigmac_ether_init(sdev);
+	return bigmac_ether_init(op, qec_op);
 }
 
-static int __devexit bigmac_sbus_remove(struct of_device *dev)
+static int __devexit bigmac_sbus_remove(struct of_device *op)
 {
-	struct bigmac *bp = dev_get_drvdata(&dev->dev);
+	struct bigmac *bp = dev_get_drvdata(&op->dev);
+	struct device *parent = op->dev.parent;
 	struct net_device *net_dev = bp->dev;
+	struct of_device *qec_op;
+
+	qec_op = to_of_device(parent);
 
 	unregister_netdev(net_dev);
 
-	sbus_iounmap(bp->gregs, GLOB_REG_SIZE);
-	sbus_iounmap(bp->creg, CREG_REG_SIZE);
-	sbus_iounmap(bp->bregs, BMAC_REG_SIZE);
-	sbus_iounmap(bp->tregs, TCVR_REG_SIZE);
-	sbus_free_consistent(bp->bigmac_sdev,
-			     PAGE_SIZE,
-			     bp->bmac_block,
-			     bp->bblock_dvma);
+	of_iounmap(&qec_op->resource[0], bp->gregs, GLOB_REG_SIZE);
+	of_iounmap(&op->resource[0], bp->creg, CREG_REG_SIZE);
+	of_iounmap(&op->resource[1], bp->bregs, BMAC_REG_SIZE);
+	of_iounmap(&op->resource[2], bp->tregs, TCVR_REG_SIZE);
+	dma_free_coherent(&op->dev,
+			  PAGE_SIZE,
+			  bp->bmac_block,
+			  bp->bblock_dvma);
 
 	free_netdev(net_dev);
 
-	dev_set_drvdata(&dev->dev, NULL);
+	dev_set_drvdata(&op->dev, NULL);
 
 	return 0;
 }
 
-static struct of_device_id bigmac_sbus_match[] = {
-	{
-		.name = "qec",
-	},
+static const struct of_device_id bigmac_sbus_match[] = {
 	{
 		.name = "be",
 	},
@@ -1313,7 +1299,7 @@ static struct of_platform_driver bigmac_sbus_driver = {
 
 static int __init bigmac_init(void)
 {
-	return of_register_driver(&bigmac_sbus_driver, &sbus_bus_type);
+	return of_register_driver(&bigmac_sbus_driver, &of_bus_type);
 }
 
 static void __exit bigmac_exit(void)
diff --git a/drivers/net/sunbmac.h b/drivers/net/sunbmac.h
index b563d3c2993e..8840bc0b840b 100644
--- a/drivers/net/sunbmac.h
+++ b/drivers/net/sunbmac.h
@@ -329,8 +329,8 @@ struct bigmac {
 	unsigned int		timer_ticks;
 
 	struct net_device_stats	enet_stats;
-	struct sbus_dev		*qec_sdev;
-	struct sbus_dev		*bigmac_sdev;
+	struct of_device	*qec_op;
+	struct of_device	*bigmac_op;
 	struct net_device	*dev;
 };
 
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index b79d5f018f79..f1ebeb5f65b2 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -3,7 +3,7 @@
  *           "Happy Meal Ethernet" found on SunSwift SBUS cards.
  *
  * Copyright (C) 1996, 1998, 1999, 2002, 2003,
-		 2006 David S. Miller (davem@davemloft.net)
+ *		2006, 2008 David S. Miller (davem@davemloft.net)
  *
  * Changes :
  * 2000/11/11 Willy Tarreau <willy AT meta-x.org>
@@ -34,6 +34,7 @@
 #include <linux/skbuff.h>
 #include <linux/mm.h>
 #include <linux/bitops.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -41,8 +42,9 @@
 #include <asm/byteorder.h>
 
 #ifdef CONFIG_SPARC
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <asm/idprom.h>
-#include <asm/sbus.h>
 #include <asm/openprom.h>
 #include <asm/oplib.h>
 #include <asm/prom.h>
@@ -60,8 +62,8 @@
 #include "sunhme.h"
 
 #define DRV_NAME	"sunhme"
-#define DRV_VERSION	"3.00"
-#define DRV_RELDATE	"June 23, 2006"
+#define DRV_VERSION	"3.10"
+#define DRV_RELDATE	"August 26, 2008"
 #define DRV_AUTHOR	"David S. Miller (davem@davemloft.net)"
 
 static char version[] =
@@ -251,13 +253,13 @@ static u32 pci_hme_read_desc32(hme32 *p)
 #define hme_read_desc32(__hp, __p) \
 	((__hp)->read_desc32(__p))
 #define hme_dma_map(__hp, __ptr, __size, __dir) \
-	((__hp)->dma_map((__hp)->happy_dev, (__ptr), (__size), (__dir)))
+	((__hp)->dma_map((__hp)->dma_dev, (__ptr), (__size), (__dir)))
 #define hme_dma_unmap(__hp, __addr, __size, __dir) \
-	((__hp)->dma_unmap((__hp)->happy_dev, (__addr), (__size), (__dir)))
+	((__hp)->dma_unmap((__hp)->dma_dev, (__addr), (__size), (__dir)))
 #define hme_dma_sync_for_cpu(__hp, __addr, __size, __dir) \
-	((__hp)->dma_sync_for_cpu((__hp)->happy_dev, (__addr), (__size), (__dir)))
+	((__hp)->dma_sync_for_cpu((__hp)->dma_dev, (__addr), (__size), (__dir)))
 #define hme_dma_sync_for_device(__hp, __addr, __size, __dir) \
-	((__hp)->dma_sync_for_device((__hp)->happy_dev, (__addr), (__size), (__dir)))
+	((__hp)->dma_sync_for_device((__hp)->dma_dev, (__addr), (__size), (__dir)))
 #else
 #ifdef CONFIG_SBUS
 /* SBUS only compilation */
@@ -277,13 +279,13 @@ do {	(__txd)->tx_addr = (__force hme32)(u32)(__addr); \
 } while(0)
 #define hme_read_desc32(__hp, __p)	((__force u32)(hme32)*(__p))
 #define hme_dma_map(__hp, __ptr, __size, __dir) \
-	sbus_map_single((__hp)->happy_dev, (__ptr), (__size), (__dir))
+	dma_map_single((__hp)->dma_dev, (__ptr), (__size), (__dir))
 #define hme_dma_unmap(__hp, __addr, __size, __dir) \
-	sbus_unmap_single((__hp)->happy_dev, (__addr), (__size), (__dir))
+	dma_unmap_single((__hp)->dma_dev, (__addr), (__size), (__dir))
 #define hme_dma_sync_for_cpu(__hp, __addr, __size, __dir) \
-	sbus_dma_sync_single_for_cpu((__hp)->happy_dev, (__addr), (__size), (__dir))
+	dma_dma_sync_single_for_cpu((__hp)->dma_dev, (__addr), (__size), (__dir))
 #define hme_dma_sync_for_device(__hp, __addr, __size, __dir) \
-	sbus_dma_sync_single_for_device((__hp)->happy_dev, (__addr), (__size), (__dir))
+	dma_dma_sync_single_for_device((__hp)->dma_dev, (__addr), (__size), (__dir))
 #else
 /* PCI only compilation */
 #define hme_write32(__hp, __reg, __val) \
@@ -305,36 +307,17 @@ static inline u32 hme_read_desc32(struct happy_meal *hp, hme32 *p)
 	return le32_to_cpup((__le32 *)p);
 }
 #define hme_dma_map(__hp, __ptr, __size, __dir) \
-	pci_map_single((__hp)->happy_dev, (__ptr), (__size), (__dir))
+	pci_map_single((__hp)->dma_dev, (__ptr), (__size), (__dir))
 #define hme_dma_unmap(__hp, __addr, __size, __dir) \
-	pci_unmap_single((__hp)->happy_dev, (__addr), (__size), (__dir))
+	pci_unmap_single((__hp)->dma_dev, (__addr), (__size), (__dir))
 #define hme_dma_sync_for_cpu(__hp, __addr, __size, __dir) \
-	pci_dma_sync_single_for_cpu((__hp)->happy_dev, (__addr), (__size), (__dir))
+	pci_dma_sync_single_for_cpu((__hp)->dma_dev, (__addr), (__size), (__dir))
 #define hme_dma_sync_for_device(__hp, __addr, __size, __dir) \
-	pci_dma_sync_single_for_device((__hp)->happy_dev, (__addr), (__size), (__dir))
+	pci_dma_sync_single_for_device((__hp)->dma_dev, (__addr), (__size), (__dir))
 #endif
 #endif
 
 
-#ifdef SBUS_DMA_BIDIRECTIONAL
-#	define DMA_BIDIRECTIONAL	SBUS_DMA_BIDIRECTIONAL
-#else
-#	define DMA_BIDIRECTIONAL	0
-#endif
-
-#ifdef SBUS_DMA_FROMDEVICE
-#	define DMA_FROMDEVICE		SBUS_DMA_FROMDEVICE
-#else
-#	define DMA_TODEVICE		1
-#endif
-
-#ifdef SBUS_DMA_TODEVICE
-#	define DMA_TODEVICE		SBUS_DMA_TODEVICE
-#else
-#	define DMA_FROMDEVICE		2
-#endif
-
-
 /* Oh yes, the MIF BitBang is mighty fun to program.  BitBucket is more like it. */
 static void BB_PUT_BIT(struct happy_meal *hp, void __iomem *tregs, int bit)
 {
@@ -1224,7 +1207,8 @@ static void happy_meal_clean_rings(struct happy_meal *hp)
 
 			rxd = &hp->happy_block->happy_meal_rxd[i];
 			dma_addr = hme_read_desc32(hp, &rxd->rx_addr);
-			hme_dma_unmap(hp, dma_addr, RX_BUF_ALLOC_SIZE, DMA_FROMDEVICE);
+			dma_unmap_single(hp->dma_dev, dma_addr,
+					 RX_BUF_ALLOC_SIZE, DMA_FROM_DEVICE);
 			dev_kfree_skb_any(skb);
 			hp->rx_skbs[i] = NULL;
 		}
@@ -1242,10 +1226,10 @@ static void happy_meal_clean_rings(struct happy_meal *hp)
 			for (frag = 0; frag <= skb_shinfo(skb)->nr_frags; frag++) {
 				txd = &hp->happy_block->happy_meal_txd[i];
 				dma_addr = hme_read_desc32(hp, &txd->tx_addr);
-				hme_dma_unmap(hp, dma_addr,
-					      (hme_read_desc32(hp, &txd->tx_flags)
-					       & TXFLAG_SIZE),
-					      DMA_TODEVICE);
+				dma_unmap_single(hp->dma_dev, dma_addr,
+						 (hme_read_desc32(hp, &txd->tx_flags)
+						  & TXFLAG_SIZE),
+						 DMA_TO_DEVICE);
 
 				if (frag != skb_shinfo(skb)->nr_frags)
 					i++;
@@ -1287,7 +1271,8 @@ static void happy_meal_init_rings(struct happy_meal *hp)
 		skb_put(skb, (ETH_FRAME_LEN + RX_OFFSET + 4));
 		hme_write_rxd(hp, &hb->happy_meal_rxd[i],
 			      (RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16)),
-			      hme_dma_map(hp, skb->data, RX_BUF_ALLOC_SIZE, DMA_FROMDEVICE));
+			      dma_map_single(hp->dma_dev, skb->data, RX_BUF_ALLOC_SIZE,
+					     DMA_FROM_DEVICE));
 		skb_reserve(skb, RX_OFFSET);
 	}
 
@@ -1593,7 +1578,7 @@ static int happy_meal_init(struct happy_meal *hp)
 	if ((hp->happy_bursts & DMA_BURST64) &&
 	    ((hp->happy_flags & HFLAG_PCI) != 0
 #ifdef CONFIG_SBUS
-	     || sbus_can_burst64(hp->happy_dev)
+	     || sbus_can_burst64()
 #endif
 	     || 0)) {
 		u32 gcfg = GREG_CFG_BURST64;
@@ -1603,11 +1588,13 @@ static int happy_meal_init(struct happy_meal *hp)
 		 * do not.  -DaveM
 		 */
 #ifdef CONFIG_SBUS
-		if ((hp->happy_flags & HFLAG_PCI) == 0 &&
-		    sbus_can_dma_64bit(hp->happy_dev)) {
-			sbus_set_sbus64(hp->happy_dev,
-					hp->happy_bursts);
-			gcfg |= GREG_CFG_64BIT;
+		if ((hp->happy_flags & HFLAG_PCI) == 0) {
+			struct of_device *op = hp->happy_dev;
+			if (sbus_can_dma_64bit()) {
+				sbus_set_sbus64(&op->dev,
+						hp->happy_bursts);
+				gcfg |= GREG_CFG_64BIT;
+			}
 		}
 #endif
 
@@ -1966,7 +1953,7 @@ static void happy_meal_tx(struct happy_meal *hp)
 			dma_len = hme_read_desc32(hp, &this->tx_flags);
 
 			dma_len &= TXFLAG_SIZE;
-			hme_dma_unmap(hp, dma_addr, dma_len, DMA_TODEVICE);
+			dma_unmap_single(hp->dma_dev, dma_addr, dma_len, DMA_TO_DEVICE);
 
 			elem = NEXT_TX(elem);
 			this = &txbase[elem];
@@ -2044,13 +2031,14 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
 				drops++;
 				goto drop_it;
 			}
-			hme_dma_unmap(hp, dma_addr, RX_BUF_ALLOC_SIZE, DMA_FROMDEVICE);
+			dma_unmap_single(hp->dma_dev, dma_addr, RX_BUF_ALLOC_SIZE, DMA_FROM_DEVICE);
 			hp->rx_skbs[elem] = new_skb;
 			new_skb->dev = dev;
 			skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET + 4));
 			hme_write_rxd(hp, this,
 				      (RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),
-				      hme_dma_map(hp, new_skb->data, RX_BUF_ALLOC_SIZE, DMA_FROMDEVICE));
+				      dma_map_single(hp->dma_dev, new_skb->data, RX_BUF_ALLOC_SIZE,
+						     DMA_FROM_DEVICE));
 			skb_reserve(new_skb, RX_OFFSET);
 
 			/* Trim the original skb for the netif. */
@@ -2065,10 +2053,9 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
 
 			skb_reserve(copy_skb, 2);
 			skb_put(copy_skb, len);
-			hme_dma_sync_for_cpu(hp, dma_addr, len, DMA_FROMDEVICE);
+			dma_sync_single_for_cpu(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE);
 			skb_copy_from_linear_data(skb, copy_skb->data, len);
-			hme_dma_sync_for_device(hp, dma_addr, len, DMA_FROMDEVICE);
-
+			dma_sync_single_for_device(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE);
 			/* Reuse original ring buffer. */
 			hme_write_rxd(hp, this,
 				      (RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),
@@ -2300,7 +2287,7 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		u32 mapping, len;
 
 		len = skb->len;
-		mapping = hme_dma_map(hp, skb->data, len, DMA_TODEVICE);
+		mapping = dma_map_single(hp->dma_dev, skb->data, len, DMA_TO_DEVICE);
 		tx_flags |= (TXFLAG_SOP | TXFLAG_EOP);
 		hme_write_txd(hp, &hp->happy_block->happy_meal_txd[entry],
 			      (tx_flags | (len & TXFLAG_SIZE)),
@@ -2314,7 +2301,8 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		 * Otherwise we could race with the device.
 		 */
 		first_len = skb_headlen(skb);
-		first_mapping = hme_dma_map(hp, skb->data, first_len, DMA_TODEVICE);
+		first_mapping = dma_map_single(hp->dma_dev, skb->data, first_len,
+					       DMA_TO_DEVICE);
 		entry = NEXT_TX(entry);
 
 		for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
@@ -2322,10 +2310,9 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			u32 len, mapping, this_txflags;
 
 			len = this_frag->size;
-			mapping = hme_dma_map(hp,
-					      ((void *) page_address(this_frag->page) +
-					       this_frag->page_offset),
-					      len, DMA_TODEVICE);
+			mapping = dma_map_page(hp->dma_dev, this_frag->page,
+					       this_frag->page_offset, len,
+					       DMA_TO_DEVICE);
 			this_txflags = tx_flags;
 			if (frag == skb_shinfo(skb)->nr_frags - 1)
 				this_txflags |= TXFLAG_EOP;
@@ -2493,9 +2480,12 @@ static void hme_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info
 	}
 #ifdef CONFIG_SBUS
 	else {
-		struct sbus_dev *sdev = hp->happy_dev;
-		sprintf(info->bus_info, "SBUS:%d",
-			sdev->slot);
+		const struct linux_prom_registers *regs;
+		struct of_device *op = hp->happy_dev;
+		regs = of_get_property(op->node, "regs", NULL);
+		if (regs)
+			sprintf(info->bus_info, "SBUS:%d",
+				regs->which_io);
 	}
 #endif
 }
@@ -2521,63 +2511,21 @@ static const struct ethtool_ops hme_ethtool_ops = {
 static int hme_version_printed;
 
 #ifdef CONFIG_SBUS
-void __devinit quattro_get_ranges(struct quattro *qp)
-{
-	struct sbus_dev *sdev = qp->quattro_dev;
-	int err;
-
-	err = prom_getproperty(sdev->prom_node,
-			       "ranges",
-			       (char *)&qp->ranges[0],
-			       sizeof(qp->ranges));
-	if (err == 0 || err == -1) {
-		qp->nranges = 0;
-		return;
-	}
-	qp->nranges = (err / sizeof(struct linux_prom_ranges));
-}
-
-static void __devinit quattro_apply_ranges(struct quattro *qp, struct happy_meal *hp)
-{
-	struct sbus_dev *sdev = hp->happy_dev;
-	int rng;
-
-	for (rng = 0; rng < qp->nranges; rng++) {
-		struct linux_prom_ranges *rngp = &qp->ranges[rng];
-		int reg;
-
-		for (reg = 0; reg < 5; reg++) {
-			if (sdev->reg_addrs[reg].which_io ==
-			    rngp->ot_child_space)
-				break;
-		}
-		if (reg == 5)
-			continue;
-
-		sdev->reg_addrs[reg].which_io = rngp->ot_parent_space;
-		sdev->reg_addrs[reg].phys_addr += rngp->ot_parent_base;
-	}
-}
-
 /* Given a happy meal sbus device, find it's quattro parent.
  * If none exist, allocate and return a new one.
  *
  * Return NULL on failure.
  */
-static struct quattro * __devinit quattro_sbus_find(struct sbus_dev *goal_sdev)
+static struct quattro * __devinit quattro_sbus_find(struct of_device *child)
 {
-	struct sbus_dev *sdev;
+	struct device *parent = child->dev.parent;
+	struct of_device *op;
 	struct quattro *qp;
-	int i;
 
-	for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
-		for (i = 0, sdev = qp->quattro_dev;
-		     (sdev != NULL) && (i < 4);
-		     sdev = sdev->next, i++) {
-			if (sdev == goal_sdev)
-				return qp;
-		}
-	}
+	op = to_of_device(parent);
+	qp = dev_get_drvdata(&op->dev);
+	if (qp)
+		return qp;
 
 	qp = kmalloc(sizeof(struct quattro), GFP_KERNEL);
 	if (qp != NULL) {
@@ -2586,10 +2534,11 @@ static struct quattro * __devinit quattro_sbus_find(struct sbus_dev *goal_sdev)
 		for (i = 0; i < 4; i++)
 			qp->happy_meals[i] = NULL;
 
-		qp->quattro_dev = goal_sdev;
+		qp->quattro_dev = child;
 		qp->next = qfe_sbus_list;
 		qfe_sbus_list = qp;
-		quattro_get_ranges(qp);
+
+		dev_set_drvdata(&op->dev, qp);
 	}
 	return qp;
 }
@@ -2602,10 +2551,10 @@ static void __init quattro_sbus_register_irqs(void)
 	struct quattro *qp;
 
 	for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
-		struct sbus_dev *sdev = qp->quattro_dev;
+		struct of_device *op = qp->quattro_dev;
 		int err;
 
-		err = request_irq(sdev->irqs[0],
+		err = request_irq(op->irqs[0],
 				  quattro_sbus_interrupt,
 				  IRQF_SHARED, "Quattro",
 				  qp);
@@ -2621,9 +2570,9 @@ static void quattro_sbus_free_irqs(void)
 	struct quattro *qp;
 
 	for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
-		struct sbus_dev *sdev = qp->quattro_dev;
+		struct of_device *op = qp->quattro_dev;
 
-		free_irq(sdev->irqs[0], qp);
+		free_irq(op->irqs[0], qp);
 	}
 }
 #endif /* CONFIG_SBUS */
@@ -2660,9 +2609,9 @@ static struct quattro * __devinit quattro_pci_find(struct pci_dev *pdev)
 #endif /* CONFIG_PCI */
 
 #ifdef CONFIG_SBUS
-static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe)
+static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe)
 {
-	struct device_node *dp = sdev->ofdev.node;
+	struct device_node *dp = op->node, *sbus_dp;
 	struct quattro *qp = NULL;
 	struct happy_meal *hp;
 	struct net_device *dev;
@@ -2671,7 +2620,7 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe
 	DECLARE_MAC_BUF(mac);
 
 	if (is_qfe) {
-		qp = quattro_sbus_find(sdev);
+		qp = quattro_sbus_find(op);
 		if (qp == NULL)
 			goto err_out;
 		for (qfe_slot = 0; qfe_slot < 4; qfe_slot++)
@@ -2685,7 +2634,7 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe
 	dev = alloc_etherdev(sizeof(struct happy_meal));
 	if (!dev)
 		goto err_out;
-	SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
+	SET_NETDEV_DEV(dev, &op->dev);
 
 	if (hme_version_printed++ == 0)
 		printk(KERN_INFO "%s", version);
@@ -2713,56 +2662,50 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe
 			memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
 	}
 
-	hp = dev->priv;
+	hp = netdev_priv(dev);
 
-	hp->happy_dev = sdev;
+	hp->happy_dev = op;
+	hp->dma_dev = &op->dev;
 
 	spin_lock_init(&hp->happy_lock);
 
 	err = -ENODEV;
-	if (sdev->num_registers != 5) {
-		printk(KERN_ERR "happymeal: Device needs 5 regs, has %d.\n",
-		       sdev->num_registers);
-		goto err_out_free_netdev;
-	}
-
 	if (qp != NULL) {
 		hp->qfe_parent = qp;
 		hp->qfe_ent = qfe_slot;
 		qp->happy_meals[qfe_slot] = dev;
-		quattro_apply_ranges(qp, hp);
 	}
 
-	hp->gregs = sbus_ioremap(&sdev->resource[0], 0,
-				 GREG_REG_SIZE, "HME Global Regs");
+	hp->gregs = of_ioremap(&op->resource[0], 0,
+			       GREG_REG_SIZE, "HME Global Regs");
 	if (!hp->gregs) {
 		printk(KERN_ERR "happymeal: Cannot map global registers.\n");
 		goto err_out_free_netdev;
 	}
 
-	hp->etxregs = sbus_ioremap(&sdev->resource[1], 0,
-				   ETX_REG_SIZE, "HME TX Regs");
+	hp->etxregs = of_ioremap(&op->resource[1], 0,
+				 ETX_REG_SIZE, "HME TX Regs");
 	if (!hp->etxregs) {
 		printk(KERN_ERR "happymeal: Cannot map MAC TX registers.\n");
 		goto err_out_iounmap;
 	}
 
-	hp->erxregs = sbus_ioremap(&sdev->resource[2], 0,
-				   ERX_REG_SIZE, "HME RX Regs");
+	hp->erxregs = of_ioremap(&op->resource[2], 0,
+				 ERX_REG_SIZE, "HME RX Regs");
 	if (!hp->erxregs) {
 		printk(KERN_ERR "happymeal: Cannot map MAC RX registers.\n");
 		goto err_out_iounmap;
 	}
 
-	hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0,
-				      BMAC_REG_SIZE, "HME BIGMAC Regs");
+	hp->bigmacregs = of_ioremap(&op->resource[3], 0,
+				    BMAC_REG_SIZE, "HME BIGMAC Regs");
 	if (!hp->bigmacregs) {
 		printk(KERN_ERR "happymeal: Cannot map BIGMAC registers.\n");
 		goto err_out_iounmap;
 	}
 
-	hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0,
-				   TCVR_REG_SIZE, "HME Tranceiver Regs");
+	hp->tcvregs = of_ioremap(&op->resource[4], 0,
+				 TCVR_REG_SIZE, "HME Tranceiver Regs");
 	if (!hp->tcvregs) {
 		printk(KERN_ERR "happymeal: Cannot map TCVR registers.\n");
 		goto err_out_iounmap;
@@ -2781,13 +2724,18 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe
 	if (qp != NULL)
 		hp->happy_flags |= HFLAG_QUATTRO;
 
+	sbus_dp = to_of_device(op->dev.parent)->node;
+	if (is_qfe)
+		sbus_dp = to_of_device(op->dev.parent->parent)->node;
+
 	/* Get the supported DVMA burst sizes from our Happy SBUS. */
-	hp->happy_bursts = of_getintprop_default(sdev->bus->ofdev.node,
+	hp->happy_bursts = of_getintprop_default(sbus_dp,
 						 "burst-sizes", 0x00);
 
-	hp->happy_block = sbus_alloc_consistent(hp->happy_dev,
-						PAGE_SIZE,
-						&hp->hblock_dvma);
+	hp->happy_block = dma_alloc_coherent(hp->dma_dev,
+					     PAGE_SIZE,
+					     &hp->hblock_dvma,
+					     GFP_ATOMIC);
 	err = -ENOMEM;
 	if (!hp->happy_block) {
 		printk(KERN_ERR "happymeal: Cannot allocate descriptors.\n");
@@ -2816,19 +2764,13 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe
 	/* Happy Meal can do it all... */
 	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
 
-	dev->irq = sdev->irqs[0];
+	dev->irq = op->irqs[0];
 
 #if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
-	/* Hook up PCI register/dma accessors. */
+	/* Hook up SBUS register/descriptor accessors. */
 	hp->read_desc32 = sbus_hme_read_desc32;
 	hp->write_txd = sbus_hme_write_txd;
 	hp->write_rxd = sbus_hme_write_rxd;
-	hp->dma_map = (u32 (*)(void *, void *, long, int))sbus_map_single;
-	hp->dma_unmap = (void (*)(void *, u32, long, int))sbus_unmap_single;
-	hp->dma_sync_for_cpu = (void (*)(void *, u32, long, int))
-		sbus_dma_sync_single_for_cpu;
-	hp->dma_sync_for_device = (void (*)(void *, u32, long, int))
-		sbus_dma_sync_single_for_device;
 	hp->read32 = sbus_hme_read32;
 	hp->write32 = sbus_hme_write32;
 #endif
@@ -2843,10 +2785,10 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe
 	if (register_netdev(hp->dev)) {
 		printk(KERN_ERR "happymeal: Cannot register net device, "
 		       "aborting.\n");
-		goto err_out_free_consistent;
+		goto err_out_free_coherent;
 	}
 
-	dev_set_drvdata(&sdev->ofdev.dev, hp);
+	dev_set_drvdata(&op->dev, hp);
 
 	if (qfe_slot != -1)
 		printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ",
@@ -2859,23 +2801,23 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe
 
 	return 0;
 
-err_out_free_consistent:
-	sbus_free_consistent(hp->happy_dev,
-			     PAGE_SIZE,
-			     hp->happy_block,
-			     hp->hblock_dvma);
+err_out_free_coherent:
+	dma_free_coherent(hp->dma_dev,
+			  PAGE_SIZE,
+			  hp->happy_block,
+			  hp->hblock_dvma);
 
 err_out_iounmap:
 	if (hp->gregs)
-		sbus_iounmap(hp->gregs, GREG_REG_SIZE);
+		of_iounmap(&op->resource[0], hp->gregs, GREG_REG_SIZE);
 	if (hp->etxregs)
-		sbus_iounmap(hp->etxregs, ETX_REG_SIZE);
+		of_iounmap(&op->resource[1], hp->etxregs, ETX_REG_SIZE);
 	if (hp->erxregs)
-		sbus_iounmap(hp->erxregs, ERX_REG_SIZE);
+		of_iounmap(&op->resource[2], hp->erxregs, ERX_REG_SIZE);
 	if (hp->bigmacregs)
-		sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE);
+		of_iounmap(&op->resource[3], hp->bigmacregs, BMAC_REG_SIZE);
 	if (hp->tcvregs)
-		sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE);
+		of_iounmap(&op->resource[4], hp->tcvregs, TCVR_REG_SIZE);
 
 err_out_free_netdev:
 	free_netdev(dev);
@@ -3035,6 +2977,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
 	memset(hp, 0, sizeof(*hp));
 
 	hp->happy_dev = pdev;
+	hp->dma_dev = &pdev->dev;
 
 	spin_lock_init(&hp->happy_lock);
 
@@ -3121,7 +3064,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
 #endif
 
 	hp->happy_block = (struct hmeal_init_block *)
-		pci_alloc_consistent(pdev, PAGE_SIZE, &hp->hblock_dvma);
+		dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &hp->hblock_dvma, GFP_KERNEL);
 
 	err = -ENODEV;
 	if (!hp->happy_block) {
@@ -3151,16 +3094,10 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
 	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
 
 #if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
-	/* Hook up PCI register/dma accessors. */
+	/* Hook up PCI register/descriptor accessors. */
 	hp->read_desc32 = pci_hme_read_desc32;
 	hp->write_txd = pci_hme_write_txd;
 	hp->write_rxd = pci_hme_write_rxd;
-	hp->dma_map = (u32 (*)(void *, void *, long, int))pci_map_single;
-	hp->dma_unmap = (void (*)(void *, u32, long, int))pci_unmap_single;
-	hp->dma_sync_for_cpu = (void (*)(void *, u32, long, int))
-		pci_dma_sync_single_for_cpu;
-	hp->dma_sync_for_device = (void (*)(void *, u32, long, int))
-		pci_dma_sync_single_for_device;
 	hp->read32 = pci_hme_read32;
 	hp->write32 = pci_hme_write32;
 #endif
@@ -3231,10 +3168,8 @@ static void __devexit happy_meal_pci_remove(struct pci_dev *pdev)
 
 	unregister_netdev(net_dev);
 
-	pci_free_consistent(hp->happy_dev,
-			    PAGE_SIZE,
-			    hp->happy_block,
-			    hp->hblock_dvma);
+	dma_free_coherent(hp->dma_dev, PAGE_SIZE,
+			  hp->happy_block, hp->hblock_dvma);
 	iounmap(hp->gregs);
 	pci_release_regions(hp->happy_dev);
 
@@ -3279,46 +3214,45 @@ static void happy_meal_pci_exit(void)
 #endif
 
 #ifdef CONFIG_SBUS
-static int __devinit hme_sbus_probe(struct of_device *dev, const struct of_device_id *match)
+static int __devinit hme_sbus_probe(struct of_device *op, const struct of_device_id *match)
 {
-	struct sbus_dev *sdev = to_sbus_device(&dev->dev);
-	struct device_node *dp = dev->node;
+	struct device_node *dp = op->node;
 	const char *model = of_get_property(dp, "model", NULL);
 	int is_qfe = (match->data != NULL);
 
 	if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe"))
 		is_qfe = 1;
 
-	return happy_meal_sbus_probe_one(sdev, is_qfe);
+	return happy_meal_sbus_probe_one(op, is_qfe);
 }
 
-static int __devexit hme_sbus_remove(struct of_device *dev)
+static int __devexit hme_sbus_remove(struct of_device *op)
 {
-	struct happy_meal *hp = dev_get_drvdata(&dev->dev);
+	struct happy_meal *hp = dev_get_drvdata(&op->dev);
 	struct net_device *net_dev = hp->dev;
 
 	unregister_netdev(net_dev);
 
 	/* XXX qfe parent interrupt... */
 
-	sbus_iounmap(hp->gregs, GREG_REG_SIZE);
-	sbus_iounmap(hp->etxregs, ETX_REG_SIZE);
-	sbus_iounmap(hp->erxregs, ERX_REG_SIZE);
-	sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE);
-	sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE);
-	sbus_free_consistent(hp->happy_dev,
-			     PAGE_SIZE,
-			     hp->happy_block,
-			     hp->hblock_dvma);
+	of_iounmap(&op->resource[0], hp->gregs, GREG_REG_SIZE);
+	of_iounmap(&op->resource[1], hp->etxregs, ETX_REG_SIZE);
+	of_iounmap(&op->resource[2], hp->erxregs, ERX_REG_SIZE);
+	of_iounmap(&op->resource[3], hp->bigmacregs, BMAC_REG_SIZE);
+	of_iounmap(&op->resource[4], hp->tcvregs, TCVR_REG_SIZE);
+	dma_free_coherent(hp->dma_dev,
+			  PAGE_SIZE,
+			  hp->happy_block,
+			  hp->hblock_dvma);
 
 	free_netdev(net_dev);
 
-	dev_set_drvdata(&dev->dev, NULL);
+	dev_set_drvdata(&op->dev, NULL);
 
 	return 0;
 }
 
-static struct of_device_id hme_sbus_match[] = {
+static const struct of_device_id hme_sbus_match[] = {
 	{
 		.name = "SUNW,hme",
 	},
@@ -3346,7 +3280,7 @@ static int __init happy_meal_sbus_init(void)
 {
 	int err;
 
-	err = of_register_driver(&hme_sbus_driver, &sbus_bus_type);
+	err = of_register_driver(&hme_sbus_driver, &of_bus_type);
 	if (!err)
 		quattro_sbus_register_irqs();
 
diff --git a/drivers/net/sunhme.h b/drivers/net/sunhme.h
index 4da5539fac7b..efd2ca0fcad3 100644
--- a/drivers/net/sunhme.h
+++ b/drivers/net/sunhme.h
@@ -405,14 +405,11 @@ struct happy_meal {
 	u32 (*read_desc32)(hme32 *);
 	void (*write_txd)(struct happy_meal_txd *, u32, u32);
 	void (*write_rxd)(struct happy_meal_rxd *, u32, u32);
-	u32 (*dma_map)(void *, void *, long, int);
-	void (*dma_unmap)(void *, u32, long, int);
-	void (*dma_sync_for_cpu)(void *, u32, long, int);
-	void (*dma_sync_for_device)(void *, u32, long, int);
 #endif
 
-	/* This is either a sbus_dev or a pci_dev. */
+	/* This is either an of_device or a pci_dev. */
 	void			  *happy_dev;
+	struct device		  *dma_dev;
 
 	spinlock_t		  happy_lock;
 
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 4e994f87469e..704301a5a7ff 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -91,6 +91,9 @@ static char lancestr[] = "LANCE";
 #include <linux/skbuff.h>
 #include <linux/ethtool.h>
 #include <linux/bitops.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -98,7 +101,6 @@ static char lancestr[] = "LANCE";
 #include <asm/pgtable.h>
 #include <asm/byteorder.h>	/* Used by the checksum routines */
 #include <asm/idprom.h>
-#include <asm/sbus.h>
 #include <asm/prom.h>
 #include <asm/auxio.h>		/* For tpe-link-test? setting */
 #include <asm/irq.h>
@@ -248,7 +250,7 @@ struct lance_private {
 	int		rx_new, tx_new;
 	int		rx_old, tx_old;
 
-	struct sbus_dma *ledma;	/* If set this points to ledma	*/
+	struct of_device *ledma;	/* If set this points to ledma	*/
 	char		tpe;		/* cable-selection is TPE	*/
 	char		auto_select;	/* cable-selection by carrier	*/
 	char		burst_sizes;	/* ledma SBus burst sizes	*/
@@ -263,7 +265,8 @@ struct lance_private {
 	char	       	       *name;
 	dma_addr_t		init_block_dvma;
 	struct net_device      *dev;		  /* Backpointer	*/
-	struct sbus_dev	       *sdev;
+	struct of_device       *op;
+	struct of_device       *lebuffer;
 	struct timer_list       multicast_timer;
 };
 
@@ -1272,27 +1275,29 @@ static void lance_set_multicast_retry(unsigned long _opaque)
 static void lance_free_hwresources(struct lance_private *lp)
 {
 	if (lp->lregs)
-		sbus_iounmap(lp->lregs, LANCE_REG_SIZE);
+		of_iounmap(&lp->op->resource[0], lp->lregs, LANCE_REG_SIZE);
+	if (lp->dregs) {
+		struct of_device *ledma = lp->ledma;
+
+		of_iounmap(&ledma->resource[0], lp->dregs,
+			   resource_size(&ledma->resource[0]));
+	}
 	if (lp->init_block_iomem) {
-		sbus_iounmap(lp->init_block_iomem,
-			     sizeof(struct lance_init_block));
+		of_iounmap(&lp->lebuffer->resource[0], lp->init_block_iomem,
+			   sizeof(struct lance_init_block));
 	} else if (lp->init_block_mem) {
-		sbus_free_consistent(lp->sdev,
-				     sizeof(struct lance_init_block),
-				     lp->init_block_mem,
-				     lp->init_block_dvma);
+		dma_free_coherent(&lp->op->dev,
+				  sizeof(struct lance_init_block),
+				  lp->init_block_mem,
+				  lp->init_block_dvma);
 	}
 }
 
 /* Ethtool support... */
 static void sparc_lance_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-	struct lance_private *lp = netdev_priv(dev);
-
 	strcpy(info->driver, "sunlance");
 	strcpy(info->version, "2.02");
-	sprintf(info->bus_info, "SBUS:%d",
-		lp->sdev->slot);
 }
 
 static u32 sparc_lance_get_link(struct net_device *dev)
@@ -1308,16 +1313,16 @@ static const struct ethtool_ops sparc_lance_ethtool_ops = {
 	.get_link		= sparc_lance_get_link,
 };
 
-static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
-					   struct sbus_dma *ledma,
-					   struct sbus_dev *lebuffer)
+static int __devinit sparc_lance_probe_one(struct of_device *op,
+					   struct of_device *ledma,
+					   struct of_device *lebuffer)
 {
+	struct device_node *dp = op->node;
 	static unsigned version_printed;
-	struct device_node *dp = sdev->ofdev.node;
-	struct net_device *dev;
 	struct lance_private *lp;
-	int    i;
+	struct net_device *dev;
 	DECLARE_MAC_BUF(mac);
+	int    i;
 
 	dev = alloc_etherdev(sizeof(struct lance_private) + 8);
 	if (!dev)
@@ -1338,14 +1343,27 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
 		dev->dev_addr[i] = idprom->id_ethaddr[i];
 
 	/* Get the IO region */
-	lp->lregs = sbus_ioremap(&sdev->resource[0], 0,
-				 LANCE_REG_SIZE, lancestr);
+	lp->lregs = of_ioremap(&op->resource[0], 0,
+			       LANCE_REG_SIZE, lancestr);
 	if (!lp->lregs) {
 		printk(KERN_ERR "SunLance: Cannot map registers.\n");
 		goto fail;
 	}
 
-	lp->sdev = sdev;
+	lp->ledma = ledma;
+	if (lp->ledma) {
+		lp->dregs = of_ioremap(&ledma->resource[0], 0,
+				       resource_size(&ledma->resource[0]),
+				       "ledma");
+		if (!lp->dregs) {
+			printk(KERN_ERR "SunLance: Cannot map "
+			       "ledma registers.\n");
+			goto fail;
+		}
+	}
+
+	lp->op = op;
+	lp->lebuffer = lebuffer;
 	if (lebuffer) {
 		/* sanity check */
 		if (lebuffer->resource[0].start & 7) {
@@ -1353,8 +1371,8 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
 			goto fail;
 		}
 		lp->init_block_iomem =
-			sbus_ioremap(&lebuffer->resource[0], 0,
-				     sizeof(struct lance_init_block), "lebuffer");
+			of_ioremap(&lebuffer->resource[0], 0,
+				   sizeof(struct lance_init_block), "lebuffer");
 		if (!lp->init_block_iomem) {
 			printk(KERN_ERR "SunLance: Cannot map PIO buffer.\n");
 			goto fail;
@@ -1366,9 +1384,10 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
 		lp->tx = lance_tx_pio;
 	} else {
 		lp->init_block_mem =
-			sbus_alloc_consistent(sdev, sizeof(struct lance_init_block),
-					      &lp->init_block_dvma);
-		if (!lp->init_block_mem || lp->init_block_dvma == 0) {
+			dma_alloc_coherent(&op->dev,
+					   sizeof(struct lance_init_block),
+					   &lp->init_block_dvma, GFP_ATOMIC);
+		if (!lp->init_block_mem) {
 			printk(KERN_ERR "SunLance: Cannot allocate consistent DMA memory.\n");
 			goto fail;
 		}
@@ -1383,13 +1402,13 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
 						      LE_C3_BCON));
 
 	lp->name = lancestr;
-	lp->ledma = ledma;
 
 	lp->burst_sizes = 0;
 	if (lp->ledma) {
-		struct device_node *ledma_dp = ledma->sdev->ofdev.node;
-		const char *prop;
+		struct device_node *ledma_dp = ledma->node;
+		struct device_node *sbus_dp;
 		unsigned int sbmask;
+		const char *prop;
 		u32 csr;
 
 		/* Find burst-size property for ledma */
@@ -1397,7 +1416,8 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
 							"burst-sizes", 0);
 
 		/* ledma may be capable of fast bursts, but sbus may not. */
-		sbmask = of_getintprop_default(ledma_dp, "burst-sizes",
+		sbus_dp = ledma_dp->parent;
+		sbmask = of_getintprop_default(sbus_dp, "burst-sizes",
 					       DMA_BURSTBITS);
 		lp->burst_sizes &= sbmask;
 
@@ -1435,8 +1455,6 @@ no_link_test:
 			lp->tpe = 1;
 		}
 
-		lp->dregs = ledma->regs;
-
 		/* Reset ledma */
 		csr = sbus_readl(lp->dregs + DMA_CSR);
 		sbus_writel(csr | DMA_RST_ENET, lp->dregs + DMA_CSR);
@@ -1446,7 +1464,7 @@ no_link_test:
 		lp->dregs = NULL;
 
 	lp->dev = dev;
-	SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
+	SET_NETDEV_DEV(dev, &op->dev);
 	dev->open = &lance_open;
 	dev->stop = &lance_close;
 	dev->hard_start_xmit = &lance_start_xmit;
@@ -1455,9 +1473,7 @@ no_link_test:
 	dev->set_multicast_list = &lance_set_multicast;
 	dev->ethtool_ops = &sparc_lance_ethtool_ops;
 
-	dev->irq = sdev->irqs[0];
-
-	dev->dma = 0;
+	dev->irq = op->irqs[0];
 
 	/* We cannot sleep if the chip is busy during a
 	 * multicast list update event, because such events
@@ -1473,7 +1489,7 @@ no_link_test:
 		goto fail;
 	}
 
-	dev_set_drvdata(&sdev->ofdev.dev, lp);
+	dev_set_drvdata(&op->dev, lp);
 
 	printk(KERN_INFO "%s: LANCE %s\n",
 	       dev->name, print_mac(mac, dev->dev_addr));
@@ -1486,80 +1502,25 @@ fail:
 	return -ENODEV;
 }
 
-/* On 4m, find the associated dma for the lance chip */
-static struct sbus_dma * __devinit find_ledma(struct sbus_dev *sdev)
-{
-	struct sbus_dma *p;
-
-	for_each_dvma(p) {
-		if (p->sdev == sdev)
-			return p;
-	}
-	return NULL;
-}
-
-#ifdef CONFIG_SUN4
-
-#include <asm/sun4paddr.h>
-#include <asm/machines.h>
-
-/* Find all the lance cards on the system and initialize them */
-static struct sbus_dev sun4_sdev;
-static int __devinit sparc_lance_init(void)
-{
-	if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) ||
-	    (idprom->id_machtype == (SM_SUN4|SM_4_470))) {
-		memset(&sun4_sdev, 0, sizeof(struct sbus_dev));
-		sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr;
-		sun4_sdev.irqs[0] = 6;
-		return sparc_lance_probe_one(&sun4_sdev, NULL, NULL);
-	}
-	return -ENODEV;
-}
-
-static int __exit sunlance_sun4_remove(void)
+static int __devinit sunlance_sbus_probe(struct of_device *op, const struct of_device_id *match)
 {
-	struct lance_private *lp = dev_get_drvdata(&sun4_sdev.ofdev.dev);
-	struct net_device *net_dev = lp->dev;
-
-	unregister_netdev(net_dev);
-
-	lance_free_hwresources(lp);
-
-	free_netdev(net_dev);
-
-	dev_set_drvdata(&sun4_sdev.ofdev.dev, NULL);
-
-	return 0;
-}
-
-#else /* !CONFIG_SUN4 */
-
-static int __devinit sunlance_sbus_probe(struct of_device *dev, const struct of_device_id *match)
-{
-	struct sbus_dev *sdev = to_sbus_device(&dev->dev);
+	struct of_device *parent = to_of_device(op->dev.parent);
+	struct device_node *parent_dp = parent->node;
 	int err;
 
-	if (sdev->parent) {
-		struct of_device *parent = &sdev->parent->ofdev;
-
-		if (!strcmp(parent->node->name, "ledma")) {
-			struct sbus_dma *ledma = find_ledma(to_sbus_device(&parent->dev));
-
-			err = sparc_lance_probe_one(sdev, ledma, NULL);
-		} else if (!strcmp(parent->node->name, "lebuffer")) {
-			err = sparc_lance_probe_one(sdev, NULL, to_sbus_device(&parent->dev));
-		} else
-			err = sparc_lance_probe_one(sdev, NULL, NULL);
+	if (!strcmp(parent_dp->name, "ledma")) {
+		err = sparc_lance_probe_one(op, parent, NULL);
+	} else if (!strcmp(parent_dp->name, "lebuffer")) {
+		err = sparc_lance_probe_one(op, NULL, parent);
 	} else
-		err = sparc_lance_probe_one(sdev, NULL, NULL);
+		err = sparc_lance_probe_one(op, NULL, NULL);
 
 	return err;
 }
 
-static int __devexit sunlance_sbus_remove(struct of_device *dev)
+static int __devexit sunlance_sbus_remove(struct of_device *op)
 {
-	struct lance_private *lp = dev_get_drvdata(&dev->dev);
+	struct lance_private *lp = dev_get_drvdata(&op->dev);
 	struct net_device *net_dev = lp->dev;
 
 	unregister_netdev(net_dev);
@@ -1568,12 +1529,12 @@ static int __devexit sunlance_sbus_remove(struct of_device *dev)
 
 	free_netdev(net_dev);
 
-	dev_set_drvdata(&dev->dev, NULL);
+	dev_set_drvdata(&op->dev, NULL);
 
 	return 0;
 }
 
-static struct of_device_id sunlance_sbus_match[] = {
+static const struct of_device_id sunlance_sbus_match[] = {
 	{
 		.name = "le",
 	},
@@ -1593,17 +1554,12 @@ static struct of_platform_driver sunlance_sbus_driver = {
 /* Find all the lance cards on the system and initialize them */
 static int __init sparc_lance_init(void)
 {
-	return of_register_driver(&sunlance_sbus_driver, &sbus_bus_type);
+	return of_register_driver(&sunlance_sbus_driver, &of_bus_type);
 }
-#endif /* !CONFIG_SUN4 */
 
 static void __exit sparc_lance_exit(void)
 {
-#ifdef CONFIG_SUN4
-	sunlance_sun4_remove();
-#else
 	of_unregister_driver(&sunlance_sbus_driver);
-#endif
 }
 
 module_init(sparc_lance_init);
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index e811331d4608..f63644744ff9 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -3,7 +3,7 @@
  *          controller out there can be most efficiently programmed
  *          if you make it look like a LANCE.
  *
- * Copyright (C) 1996, 1999, 2003, 2006 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1996, 1999, 2003, 2006, 2008 David S. Miller (davem@davemloft.net)
  */
 
 #include <linux/module.h>
@@ -24,13 +24,15 @@
 #include <linux/skbuff.h>
 #include <linux/ethtool.h>
 #include <linux/bitops.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/byteorder.h>
 #include <asm/idprom.h>
-#include <asm/sbus.h>
 #include <asm/openprom.h>
 #include <asm/oplib.h>
 #include <asm/auxio.h>
@@ -40,8 +42,8 @@
 #include "sunqe.h"
 
 #define DRV_NAME	"sunqe"
-#define DRV_VERSION	"4.0"
-#define DRV_RELDATE	"June 23, 2006"
+#define DRV_VERSION	"4.1"
+#define DRV_RELDATE	"August 27, 2008"
 #define DRV_AUTHOR	"David S. Miller (davem@davemloft.net)"
 
 static char version[] =
@@ -690,12 +692,18 @@ static void qe_set_multicast(struct net_device *dev)
 /* Ethtool support... */
 static void qe_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
+	const struct linux_prom_registers *regs;
 	struct sunqe *qep = dev->priv;
+	struct of_device *op;
 
 	strcpy(info->driver, "sunqe");
 	strcpy(info->version, "3.0");
-	sprintf(info->bus_info, "SBUS:%d",
-		qep->qe_sdev->slot);
+
+	op = qep->op;
+	regs = of_get_property(op->node, "reg", NULL);
+	if (regs)
+		sprintf(info->bus_info, "SBUS:%d", regs->which_io);
+
 }
 
 static u32 qe_get_link(struct net_device *dev)
@@ -717,11 +725,11 @@ static const struct ethtool_ops qe_ethtool_ops = {
 };
 
 /* This is only called once at boot time for each card probed. */
-static inline void qec_init_once(struct sunqec *qecp, struct sbus_dev *qsdev)
+static void qec_init_once(struct sunqec *qecp, struct of_device *op)
 {
 	u8 bsizes = qecp->qec_bursts;
 
-	if (sbus_can_burst64(qsdev) && (bsizes & DMA_BURST64)) {
+	if (sbus_can_burst64() && (bsizes & DMA_BURST64)) {
 		sbus_writel(GLOB_CTRL_B64, qecp->gregs + GLOB_CTRL);
 	} else if (bsizes & DMA_BURST32) {
 		sbus_writel(GLOB_CTRL_B32, qecp->gregs + GLOB_CTRL);
@@ -735,15 +743,15 @@ static inline void qec_init_once(struct sunqec *qecp, struct sbus_dev *qsdev)
 	sbus_writel(GLOB_PSIZE_2048, qecp->gregs + GLOB_PSIZE);
 
 	/* Set the local memsize register, divided up to one piece per QE channel. */
-	sbus_writel((qsdev->reg_addrs[1].reg_size >> 2),
+	sbus_writel((resource_size(&op->resource[1]) >> 2),
 		    qecp->gregs + GLOB_MSIZE);
 
 	/* Divide up the local QEC memory amongst the 4 QE receiver and
 	 * transmitter FIFOs.  Basically it is (total / 2 / num_channels).
 	 */
-	sbus_writel((qsdev->reg_addrs[1].reg_size >> 2) >> 1,
+	sbus_writel((resource_size(&op->resource[1]) >> 2) >> 1,
 		    qecp->gregs + GLOB_TSIZE);
-	sbus_writel((qsdev->reg_addrs[1].reg_size >> 2) >> 1,
+	sbus_writel((resource_size(&op->resource[1]) >> 2) >> 1,
 		    qecp->gregs + GLOB_RSIZE);
 }
 
@@ -767,24 +775,21 @@ static u8 __devinit qec_get_burst(struct device_node *dp)
 	return bsizes;
 }
 
-static struct sunqec * __devinit get_qec(struct sbus_dev *child_sdev)
+static struct sunqec * __devinit get_qec(struct of_device *child)
 {
-	struct sbus_dev *qec_sdev = child_sdev->parent;
+	struct of_device *op = to_of_device(child->dev.parent);
 	struct sunqec *qecp;
 
-	for (qecp = root_qec_dev; qecp; qecp = qecp->next_module) {
-		if (qecp->qec_sdev == qec_sdev)
-			break;
-	}
+	qecp = dev_get_drvdata(&op->dev);
 	if (!qecp) {
 		qecp = kzalloc(sizeof(struct sunqec), GFP_KERNEL);
 		if (qecp) {
 			u32 ctrl;
 
-			qecp->qec_sdev = qec_sdev;
-			qecp->gregs = sbus_ioremap(&qec_sdev->resource[0], 0,
-						   GLOB_REG_SIZE,
-						   "QEC Global Registers");
+			qecp->op = op;
+			qecp->gregs = of_ioremap(&op->resource[0], 0,
+						 GLOB_REG_SIZE,
+						 "QEC Global Registers");
 			if (!qecp->gregs)
 				goto fail;
 
@@ -799,16 +804,18 @@ static struct sunqec * __devinit get_qec(struct sbus_dev *child_sdev)
 			if (qec_global_reset(qecp->gregs))
 				goto fail;
 
-			qecp->qec_bursts = qec_get_burst(qec_sdev->ofdev.node);
+			qecp->qec_bursts = qec_get_burst(op->node);
 
-			qec_init_once(qecp, qec_sdev);
+			qec_init_once(qecp, op);
 
-			if (request_irq(qec_sdev->irqs[0], &qec_interrupt,
+			if (request_irq(op->irqs[0], &qec_interrupt,
 					IRQF_SHARED, "qec", (void *) qecp)) {
 				printk(KERN_ERR "qec: Can't register irq.\n");
 				goto fail;
 			}
 
+			dev_set_drvdata(&op->dev, qecp);
+
 			qecp->next_module = root_qec_dev;
 			root_qec_dev = qecp;
 		}
@@ -818,17 +825,17 @@ static struct sunqec * __devinit get_qec(struct sbus_dev *child_sdev)
 
 fail:
 	if (qecp->gregs)
-		sbus_iounmap(qecp->gregs, GLOB_REG_SIZE);
+		of_iounmap(&op->resource[0], qecp->gregs, GLOB_REG_SIZE);
 	kfree(qecp);
 	return NULL;
 }
 
-static int __devinit qec_ether_init(struct sbus_dev *sdev)
+static int __devinit qec_ether_init(struct of_device *op)
 {
 	static unsigned version_printed;
 	struct net_device *dev;
-	struct sunqe *qe;
 	struct sunqec *qecp;
+	struct sunqe *qe;
 	int i, res;
 
 	if (version_printed++ == 0)
@@ -842,49 +849,42 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev)
 
 	qe = netdev_priv(dev);
 
-	i = of_getintprop_default(sdev->ofdev.node, "channel#", -1);
-	if (i == -1) {
-		struct sbus_dev *td = sdev->parent->child;
-		i = 0;
-		while (td != sdev) {
-			td = td->next;
-			i++;
-		}
-	}
+	res = -ENODEV;
+
+	i = of_getintprop_default(op->node, "channel#", -1);
+	if (i == -1)
+		goto fail;
 	qe->channel = i;
 	spin_lock_init(&qe->lock);
 
-	res = -ENODEV;
-	qecp = get_qec(sdev);
+	qecp = get_qec(op);
 	if (!qecp)
 		goto fail;
 
 	qecp->qes[qe->channel] = qe;
 	qe->dev = dev;
 	qe->parent = qecp;
-	qe->qe_sdev = sdev;
+	qe->op = op;
 
 	res = -ENOMEM;
-	qe->qcregs = sbus_ioremap(&qe->qe_sdev->resource[0], 0,
-				  CREG_REG_SIZE, "QEC Channel Registers");
+	qe->qcregs = of_ioremap(&op->resource[0], 0,
+				CREG_REG_SIZE, "QEC Channel Registers");
 	if (!qe->qcregs) {
 		printk(KERN_ERR "qe: Cannot map channel registers.\n");
 		goto fail;
 	}
 
-	qe->mregs = sbus_ioremap(&qe->qe_sdev->resource[1], 0,
-				 MREGS_REG_SIZE, "QE MACE Registers");
+	qe->mregs = of_ioremap(&op->resource[1], 0,
+			       MREGS_REG_SIZE, "QE MACE Registers");
 	if (!qe->mregs) {
 		printk(KERN_ERR "qe: Cannot map MACE registers.\n");
 		goto fail;
 	}
 
-	qe->qe_block = sbus_alloc_consistent(qe->qe_sdev,
-					     PAGE_SIZE,
-					     &qe->qblock_dvma);
-	qe->buffers = sbus_alloc_consistent(qe->qe_sdev,
-					    sizeof(struct sunqe_buffers),
-					    &qe->buffers_dvma);
+	qe->qe_block = dma_alloc_coherent(&op->dev, PAGE_SIZE,
+					  &qe->qblock_dvma, GFP_ATOMIC);
+	qe->buffers = dma_alloc_coherent(&op->dev, sizeof(struct sunqe_buffers),
+					 &qe->buffers_dvma, GFP_ATOMIC);
 	if (qe->qe_block == NULL || qe->qblock_dvma == 0 ||
 	    qe->buffers == NULL || qe->buffers_dvma == 0)
 		goto fail;
@@ -892,7 +892,7 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev)
 	/* Stop this QE. */
 	qe_stop(qe);
 
-	SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
+	SET_NETDEV_DEV(dev, &op->dev);
 
 	dev->open = qe_open;
 	dev->stop = qe_close;
@@ -900,7 +900,7 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev)
 	dev->set_multicast_list = qe_set_multicast;
 	dev->tx_timeout = qe_tx_timeout;
 	dev->watchdog_timeo = 5*HZ;
-	dev->irq = sdev->irqs[0];
+	dev->irq = op->irqs[0];
 	dev->dma = 0;
 	dev->ethtool_ops = &qe_ethtool_ops;
 
@@ -908,7 +908,7 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev)
 	if (res)
 		goto fail;
 
-	dev_set_drvdata(&sdev->ofdev.dev, qe);
+	dev_set_drvdata(&op->dev, qe);
 
 	printk(KERN_INFO "%s: qe channel[%d] ", dev->name, qe->channel);
 	for (i = 0; i < 6; i++)
@@ -922,58 +922,50 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev)
 
 fail:
 	if (qe->qcregs)
-		sbus_iounmap(qe->qcregs, CREG_REG_SIZE);
+		of_iounmap(&op->resource[0], qe->qcregs, CREG_REG_SIZE);
 	if (qe->mregs)
-		sbus_iounmap(qe->mregs, MREGS_REG_SIZE);
+		of_iounmap(&op->resource[1], qe->mregs, MREGS_REG_SIZE);
 	if (qe->qe_block)
-		sbus_free_consistent(qe->qe_sdev,
-				     PAGE_SIZE,
-				     qe->qe_block,
-				     qe->qblock_dvma);
+		dma_free_coherent(&op->dev, PAGE_SIZE,
+				  qe->qe_block, qe->qblock_dvma);
 	if (qe->buffers)
-		sbus_free_consistent(qe->qe_sdev,
-				     sizeof(struct sunqe_buffers),
-				     qe->buffers,
-				     qe->buffers_dvma);
+		dma_free_coherent(&op->dev,
+				  sizeof(struct sunqe_buffers),
+				  qe->buffers,
+				  qe->buffers_dvma);
 
 	free_netdev(dev);
 
 	return res;
 }
 
-static int __devinit qec_sbus_probe(struct of_device *dev, const struct of_device_id *match)
+static int __devinit qec_sbus_probe(struct of_device *op, const struct of_device_id *match)
 {
-	struct sbus_dev *sdev = to_sbus_device(&dev->dev);
-
-	return qec_ether_init(sdev);
+	return qec_ether_init(op);
 }
 
-static int __devexit qec_sbus_remove(struct of_device *dev)
+static int __devexit qec_sbus_remove(struct of_device *op)
 {
-	struct sunqe *qp = dev_get_drvdata(&dev->dev);
+	struct sunqe *qp = dev_get_drvdata(&op->dev);
 	struct net_device *net_dev = qp->dev;
 
 	unregister_netdev(net_dev);
 
-	sbus_iounmap(qp->qcregs, CREG_REG_SIZE);
-	sbus_iounmap(qp->mregs, MREGS_REG_SIZE);
-	sbus_free_consistent(qp->qe_sdev,
-			     PAGE_SIZE,
-			     qp->qe_block,
-			     qp->qblock_dvma);
-	sbus_free_consistent(qp->qe_sdev,
-			     sizeof(struct sunqe_buffers),
-			     qp->buffers,
-			     qp->buffers_dvma);
+	of_iounmap(&op->resource[0], qp->qcregs, CREG_REG_SIZE);
+	of_iounmap(&op->resource[1], qp->mregs, MREGS_REG_SIZE);
+	dma_free_coherent(&op->dev, PAGE_SIZE,
+			  qp->qe_block, qp->qblock_dvma);
+	dma_free_coherent(&op->dev, sizeof(struct sunqe_buffers),
+			  qp->buffers, qp->buffers_dvma);
 
 	free_netdev(net_dev);
 
-	dev_set_drvdata(&dev->dev, NULL);
+	dev_set_drvdata(&op->dev, NULL);
 
 	return 0;
 }
 
-static struct of_device_id qec_sbus_match[] = {
+static const struct of_device_id qec_sbus_match[] = {
 	{
 		.name = "qe",
 	},
@@ -991,7 +983,7 @@ static struct of_platform_driver qec_sbus_driver = {
 
 static int __init qec_init(void)
 {
-	return of_register_driver(&qec_sbus_driver, &sbus_bus_type);
+	return of_register_driver(&qec_sbus_driver, &of_bus_type);
 }
 
 static void __exit qec_exit(void)
@@ -1000,11 +992,11 @@ static void __exit qec_exit(void)
 
 	while (root_qec_dev) {
 		struct sunqec *next = root_qec_dev->next_module;
+		struct of_device *op = root_qec_dev->op;
 
-		free_irq(root_qec_dev->qec_sdev->irqs[0],
-			 (void *) root_qec_dev);
-		sbus_iounmap(root_qec_dev->gregs, GLOB_REG_SIZE);
-
+		free_irq(op->irqs[0], (void *) root_qec_dev);
+		of_iounmap(&op->resource[0], root_qec_dev->gregs,
+			   GLOB_REG_SIZE);
 		kfree(root_qec_dev);
 
 		root_qec_dev = next;
diff --git a/drivers/net/sunqe.h b/drivers/net/sunqe.h
index 347c8ddc1592..5813a7b2faa5 100644
--- a/drivers/net/sunqe.h
+++ b/drivers/net/sunqe.h
@@ -314,7 +314,7 @@ struct sunqec {
 	void __iomem		*gregs;		/* QEC Global Registers         */
 	struct sunqe		*qes[4];	/* Each child MACE              */
 	unsigned int            qec_bursts;	/* Support burst sizes          */
-	struct sbus_dev		*qec_sdev;	/* QEC's SBUS device            */
+	struct of_device	*op;		/* QEC's OF device              */
 	struct sunqec		*next_module;	/* List of all QECs in system   */
 };
 
@@ -342,7 +342,7 @@ struct sunqe {
 	__u32				buffers_dvma;	/* DVMA visible address.       */
 	struct sunqec			*parent;
 	u8				mconfig;	/* Base MACE mconfig value     */
-	struct sbus_dev			*qe_sdev;	/* QE's SBUS device struct     */
+	struct of_device		*op;		/* QE's OF device struct       */
 	struct net_device		*dev;		/* QE's netdevice struct       */
 	int				channel;	/* Who am I?                   */
 };
diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c
index 6415ce15c2ef..a720065553df 100644
--- a/drivers/net/sunvnet.c
+++ b/drivers/net/sunvnet.c
@@ -1,6 +1,6 @@
 /* sunvnet.c: Sun LDOM Virtual Network Driver.
  *
- * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
+ * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
  */
 
 #include <linux/module.h>
@@ -1260,7 +1260,7 @@ static int vnet_port_remove(struct vio_dev *vdev)
 	return 0;
 }
 
-static struct vio_device_id vnet_port_match[] = {
+static const struct vio_device_id vnet_port_match[] = {
 	{
 		.type = "vnet-port",
 	},
diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c
index 9d595aa91e46..065f229580d5 100644
--- a/drivers/parport/parport_sunbpp.c
+++ b/drivers/parport/parport_sunbpp.c
@@ -26,6 +26,8 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <linux/parport.h>
 
@@ -34,7 +36,6 @@
 
 #include <asm/io.h>
 #include <asm/oplib.h>           /* OpenProm Library */
-#include <asm/sbus.h>
 #include <asm/dma.h>             /* BPP uses LSI 64854 for DMA */
 #include <asm/irq.h>
 #include <asm/sunbpp.h>
@@ -285,38 +286,37 @@ static struct parport_operations parport_sunbpp_ops =
 	.owner		= THIS_MODULE,
 };
 
-static int __devinit init_one_port(struct sbus_dev *sdev)
+static int __devinit bpp_probe(struct of_device *op, const struct of_device_id *match)
 {
-	struct parport *p;
-	/* at least in theory there may be a "we don't dma" case */
 	struct parport_operations *ops;
-	void __iomem *base;
-	int irq, dma, err = 0, size;
 	struct bpp_regs __iomem *regs;
+	int irq, dma, err = 0, size;
 	unsigned char value_tcr;
+	void __iomem *base;
+	struct parport *p;
 
-	irq = sdev->irqs[0];
-	base = sbus_ioremap(&sdev->resource[0], 0,
-			    sdev->reg_addrs[0].reg_size, 
-			    "sunbpp");
+	irq = op->irqs[0];
+	base = of_ioremap(&op->resource[0], 0,
+			  resource_size(&op->resource[0]),
+			  "sunbpp");
 	if (!base)
 		return -ENODEV;
 
-	size = sdev->reg_addrs[0].reg_size;
+	size = resource_size(&op->resource[0]);
 	dma = PARPORT_DMA_NONE;
 
 	ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL);
         if (!ops)
 		goto out_unmap;
 
-        memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations));
+        memcpy (ops, &parport_sunbpp_ops, sizeof(struct parport_operations));
 
 	dprintk(("register_port\n"));
 	if (!(p = parport_register_port((unsigned long)base, irq, dma, ops)))
 		goto out_free_ops;
 
 	p->size = size;
-	p->dev = &sdev->ofdev.dev;
+	p->dev = &op->dev;
 
 	if ((err = request_irq(p->irq, parport_irq_handler,
 			       IRQF_SHARED, p->name, p)) != 0) {
@@ -333,7 +333,7 @@ static int __devinit init_one_port(struct sbus_dev *sdev)
 
 	printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base);
 
-	dev_set_drvdata(&sdev->ofdev.dev, p);
+	dev_set_drvdata(&op->dev, p);
 
 	parport_announce_port(p);
 
@@ -346,21 +346,14 @@ out_free_ops:
 	kfree(ops);
 
 out_unmap:
-	sbus_iounmap(base, size);
+	of_iounmap(&op->resource[0], base, size);
 
 	return err;
 }
 
-static int __devinit bpp_probe(struct of_device *dev, const struct of_device_id *match)
-{
-	struct sbus_dev *sdev = to_sbus_device(&dev->dev);
-
-	return init_one_port(sdev);
-}
-
-static int __devexit bpp_remove(struct of_device *dev)
+static int __devexit bpp_remove(struct of_device *op)
 {
-	struct parport *p = dev_get_drvdata(&dev->dev);
+	struct parport *p = dev_get_drvdata(&op->dev);
 	struct parport_operations *ops = p->ops;
 
 	parport_remove_port(p);
@@ -370,16 +363,16 @@ static int __devexit bpp_remove(struct of_device *dev)
 		free_irq(p->irq, p);
 	}
 
-	sbus_iounmap((void __iomem *) p->base, p->size);
+	of_iounmap(&op->resource[0], (void __iomem *) p->base, p->size);
 	parport_put_port(p);
 	kfree(ops);
 
-	dev_set_drvdata(&dev->dev, NULL);
+	dev_set_drvdata(&op->dev, NULL);
 
 	return 0;
 }
 
-static struct of_device_id bpp_match[] = {
+static const struct of_device_id bpp_match[] = {
 	{
 		.name = "SUNW,bpp",
 	},
@@ -397,7 +390,7 @@ static struct of_platform_driver bpp_sbus_driver = {
 
 static int __init parport_sunbpp_init(void)
 {
-	return of_register_driver(&bpp_sbus_driver, &sbus_bus_type);
+	return of_register_driver(&bpp_sbus_driver, &of_bus_type);
 }
 
 static void __exit parport_sunbpp_exit(void)
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 9a9755c92fad..b57fba5c6d02 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -329,7 +329,7 @@ comment "Platform RTC drivers"
 
 config RTC_DRV_CMOS
 	tristate "PC-style 'CMOS'"
-	depends on X86 || ALPHA || ARM || M32R || ATARI || PPC || MIPS
+	depends on X86 || ALPHA || ARM || M32R || ATARI || PPC || MIPS || SPARC64
 	default y if X86
 	help
 	  Say "yes" here to get direct support for the real time clock
@@ -406,14 +406,26 @@ config RTC_DRV_M48T86
 	  will be called rtc-m48t86.
 
 config RTC_DRV_M48T59
-	tristate "ST M48T59"
+	tristate "ST M48T59/M48T08/M48T02"
 	help
 	  If you say Y here you will get support for the
-	  ST M48T59 RTC chip.
+	  ST M48T59 RTC chip and compatible ST M48T08 and M48T02.
+
+	  These chips are usually found in Sun SPARC and UltraSPARC
+	  workstations.
 
 	  This driver can also be built as a module, if so, the module
 	  will be called "rtc-m48t59".
 
+config RTC_DRV_BQ4802
+	tristate "TI BQ4802"
+	help
+	  If you say Y here you will get support for the TI
+	  BQ4802 RTC chip.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-bq4802.
+
 config RTC_DRV_V3020
 	tristate "EM Microelectronic V3020"
 	help
@@ -583,4 +595,18 @@ config RTC_DRV_PPC
 	 the RTC. This exposes that functionality through the generic RTC
 	 class.
 
+config RTC_DRV_SUN4V
+	bool "SUN4V Hypervisor RTC"
+	depends on SPARC64
+	help
+	  If you say Y here you will get support for the Hypervisor
+	  based RTC on SUN4V systems.
+
+config RTC_DRV_STARFIRE
+	bool "Starfire RTC"
+	depends on SPARC64
+	help
+	  If you say Y here you will get support for the RTC found on
+	  Starfire systems.
+
 endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 18622ef84cab..10f41f85c38a 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -38,6 +38,9 @@ obj-$(CONFIG_RTC_DRV_M41T80)	+= rtc-m41t80.o
 obj-$(CONFIG_RTC_DRV_M41T94)	+= rtc-m41t94.o
 obj-$(CONFIG_RTC_DRV_M48T59)	+= rtc-m48t59.o
 obj-$(CONFIG_RTC_DRV_M48T86)	+= rtc-m48t86.o
+obj-$(CONFIG_RTC_DRV_BQ4802)	+= rtc-bq4802.o
+obj-$(CONFIG_RTC_DRV_SUN4V)	+= rtc-sun4v.o
+obj-$(CONFIG_RTC_DRV_STARFIRE)	+= rtc-starfire.o
 obj-$(CONFIG_RTC_DRV_MAX6900)	+= rtc-max6900.o
 obj-$(CONFIG_RTC_DRV_MAX6902)	+= rtc-max6902.o
 obj-$(CONFIG_RTC_DRV_OMAP)	+= rtc-omap.o
diff --git a/drivers/rtc/rtc-bq4802.c b/drivers/rtc/rtc-bq4802.c
new file mode 100644
index 000000000000..189a018bdf34
--- /dev/null
+++ b/drivers/rtc/rtc-bq4802.c
@@ -0,0 +1,230 @@
+/* rtc-bq4802.c: TI BQ4802 RTC driver.
+ *
+ * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_DESCRIPTION("TI BQ4802 RTC driver");
+MODULE_LICENSE("GPL");
+
+struct bq4802 {
+	void __iomem		*regs;
+	unsigned long		ioport;
+	struct rtc_device	*rtc;
+	spinlock_t		lock;
+	struct resource		*r;
+	u8 (*read)(struct bq4802 *, int);
+	void (*write)(struct bq4802 *, int, u8);
+};
+
+static u8 bq4802_read_io(struct bq4802 *p, int off)
+{
+	return inb(p->ioport + off);
+}
+
+static void bq4802_write_io(struct bq4802 *p, int off, u8 val)
+{
+	outb(val, p->ioport + off);
+}
+
+static u8 bq4802_read_mem(struct bq4802 *p, int off)
+{
+	return readb(p->regs + off);
+}
+
+static void bq4802_write_mem(struct bq4802 *p, int off, u8 val)
+{
+	writeb(val, p->regs + off);
+}
+
+static int bq4802_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct bq4802 *p = platform_get_drvdata(pdev);
+	unsigned long flags;
+	unsigned int century;
+	u8 val;
+
+	spin_lock_irqsave(&p->lock, flags);
+
+	val = p->read(p, 0x0e);
+	p->write(p, 0xe, val | 0x08);
+
+	tm->tm_sec = p->read(p, 0x00);
+	tm->tm_min = p->read(p, 0x02);
+	tm->tm_hour = p->read(p, 0x04);
+	tm->tm_mday = p->read(p, 0x06);
+	tm->tm_mon = p->read(p, 0x09);
+	tm->tm_year = p->read(p, 0x0a);
+	tm->tm_wday = p->read(p, 0x08);
+	century = p->read(p, 0x0f);
+
+	p->write(p, 0x0e, val);
+
+	spin_unlock_irqrestore(&p->lock, flags);
+
+	BCD_TO_BIN(tm->tm_sec);
+	BCD_TO_BIN(tm->tm_min);
+	BCD_TO_BIN(tm->tm_hour);
+	BCD_TO_BIN(tm->tm_mday);
+	BCD_TO_BIN(tm->tm_mon);
+	BCD_TO_BIN(tm->tm_year);
+	BCD_TO_BIN(tm->tm_wday);
+	BCD_TO_BIN(century);
+
+	tm->tm_year += (century * 100);
+	tm->tm_year -= 1900;
+
+	tm->tm_mon--;
+
+	return 0;
+}
+
+static int bq4802_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct bq4802 *p = platform_get_drvdata(pdev);
+	u8 sec, min, hrs, day, mon, yrs, century, val;
+	unsigned long flags;
+	unsigned int year;
+
+	year = tm->tm_year + 1900;
+	century = year / 100;
+	yrs = year % 100;
+
+	mon = tm->tm_mon + 1;   /* tm_mon starts at zero */
+	day = tm->tm_mday;
+	hrs = tm->tm_hour;
+	min = tm->tm_min;
+	sec = tm->tm_sec;
+
+	BIN_TO_BCD(sec);
+	BIN_TO_BCD(min);
+	BIN_TO_BCD(hrs);
+	BIN_TO_BCD(day);
+	BIN_TO_BCD(mon);
+	BIN_TO_BCD(yrs);
+	BIN_TO_BCD(century);
+
+	spin_lock_irqsave(&p->lock, flags);
+
+	val = p->read(p, 0x0e);
+	p->write(p, 0x0e, val | 0x08);
+
+	p->write(p, 0x00, sec);
+	p->write(p, 0x02, min);
+	p->write(p, 0x04, hrs);
+	p->write(p, 0x06, day);
+	p->write(p, 0x09, mon);
+	p->write(p, 0x0a, yrs);
+	p->write(p, 0x0f, century);
+
+	p->write(p, 0x0e, val);
+
+	spin_unlock_irqrestore(&p->lock, flags);
+
+	return 0;
+}
+
+static const struct rtc_class_ops bq4802_ops = {
+	.read_time	= bq4802_read_time,
+	.set_time	= bq4802_set_time,
+};
+
+static int __devinit bq4802_probe(struct platform_device *pdev)
+{
+	struct bq4802 *p = kzalloc(sizeof(*p), GFP_KERNEL);
+	int err = -ENOMEM;
+
+	if (!p)
+		goto out;
+
+	spin_lock_init(&p->lock);
+
+	p->r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!p->r) {
+		p->r = platform_get_resource(pdev, IORESOURCE_IO, 0);
+		err = -EINVAL;
+		if (!p->r)
+			goto out_free;
+	}
+	if (p->r->flags & IORESOURCE_IO) {
+		p->ioport = p->r->start;
+		p->read = bq4802_read_io;
+		p->write = bq4802_write_io;
+	} else if (p->r->flags & IORESOURCE_MEM) {
+		p->regs = ioremap(p->r->start, resource_size(p->r));
+		p->read = bq4802_read_mem;
+		p->write = bq4802_write_mem;
+	} else {
+		err = -EINVAL;
+		goto out_free;
+	}
+
+	p->rtc = rtc_device_register("bq4802", &pdev->dev,
+				     &bq4802_ops, THIS_MODULE);
+	if (IS_ERR(p->rtc)) {
+		err = PTR_ERR(p->rtc);
+		goto out_iounmap;
+	}
+
+	platform_set_drvdata(pdev, p);
+	err = 0;
+out:
+	return err;
+
+out_iounmap:
+	if (p->r->flags & IORESOURCE_MEM)
+		iounmap(p->regs);
+out_free:
+	kfree(p);
+	goto out;
+}
+
+static int __devexit bq4802_remove(struct platform_device *pdev)
+{
+	struct bq4802 *p = platform_get_drvdata(pdev);
+
+	rtc_device_unregister(p->rtc);
+	if (p->r->flags & IORESOURCE_MEM)
+		iounmap(p->regs);
+
+	platform_set_drvdata(pdev, NULL);
+
+	kfree(p);
+
+	return 0;
+}
+
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:rtc-bq4802");
+
+static struct platform_driver bq4802_driver = {
+	.driver		= {
+		.name	= "rtc-bq4802",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= bq4802_probe,
+	.remove		= __devexit_p(bq4802_remove),
+};
+
+static int __init bq4802_init(void)
+{
+	return platform_driver_register(&bq4802_driver);
+}
+
+static void __exit bq4802_exit(void)
+{
+	platform_driver_unregister(&bq4802_driver);
+}
+
+module_init(bq4802_init);
+module_exit(bq4802_exit);
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index b184367637d0..b23af0c2a869 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -636,7 +636,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
 	 */
 #if	defined(CONFIG_ATARI)
 	address_space = 64;
-#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__)
+#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__sparc__)
 	address_space = 128;
 #else
 #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes.
@@ -699,7 +699,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
 	/* FIXME teach the alarm code how to handle binary mode;
 	 * <asm-generic/rtc.h> doesn't know 12-hour mode either.
 	 */
-	if (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY))) {
+	if (is_valid_irq(rtc_irq) &&
+	    (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) {
 		dev_dbg(dev, "only 24-hr BCD mode supported\n");
 		retval = -ENXIO;
 		goto cleanup1;
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c
index 013e6c103b9c..ce4eff6a8d51 100644
--- a/drivers/rtc/rtc-m48t59.c
+++ b/drivers/rtc/rtc-m48t59.c
@@ -24,8 +24,9 @@
 #define NO_IRQ	(-1)
 #endif
 
-#define M48T59_READ(reg)	pdata->read_byte(dev, reg)
-#define M48T59_WRITE(val, reg)	pdata->write_byte(dev, reg, val)
+#define M48T59_READ(reg) (pdata->read_byte(dev, pdata->offset + reg))
+#define M48T59_WRITE(val, reg) \
+	(pdata->write_byte(dev, pdata->offset + reg, val))
 
 #define M48T59_SET_BITS(mask, reg)	\
 	M48T59_WRITE((M48T59_READ(reg) | (mask)), (reg))
@@ -34,7 +35,6 @@
 
 struct m48t59_private {
 	void __iomem *ioaddr;
-	unsigned int size; /* iomem size */
 	int irq;
 	struct rtc_device *rtc;
 	spinlock_t lock; /* serialize the NVRAM and RTC access */
@@ -82,7 +82,8 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm)
 	tm->tm_mday	= BCD2BIN(M48T59_READ(M48T59_MDAY));
 
 	val = M48T59_READ(M48T59_WDAY);
-	if ((val & M48T59_WDAY_CEB) && (val & M48T59_WDAY_CB)) {
+	if ((pdata->type == M48T59RTC_TYPE_M48T59) &&
+	    (val & M48T59_WDAY_CEB) && (val & M48T59_WDAY_CB)) {
 		dev_dbg(dev, "Century bit is enabled\n");
 		tm->tm_year += 100;	/* one century */
 	}
@@ -126,7 +127,7 @@ static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	M48T59_WRITE((BIN2BCD(tm->tm_mon + 1) & 0x1F), M48T59_MONTH);
 	M48T59_WRITE(BIN2BCD(tm->tm_year % 100), M48T59_YEAR);
 
-	if (tm->tm_year/100)
+	if (pdata->type == M48T59RTC_TYPE_M48T59 && (tm->tm_year / 100))
 		val = (M48T59_WDAY_CEB | M48T59_WDAY_CB);
 	val |= (BIN2BCD(tm->tm_wday) & 0x07);
 	M48T59_WRITE(val, M48T59_WDAY);
@@ -310,6 +311,11 @@ static const struct rtc_class_ops m48t59_rtc_ops = {
 	.proc		= m48t59_rtc_proc,
 };
 
+static const struct rtc_class_ops m48t02_rtc_ops = {
+	.read_time	= m48t59_rtc_read_time,
+	.set_time	= m48t59_rtc_set_time,
+};
+
 static ssize_t m48t59_nvram_read(struct kobject *kobj,
 				struct bin_attribute *bin_attr,
 				char *buf, loff_t pos, size_t size)
@@ -321,7 +327,7 @@ static ssize_t m48t59_nvram_read(struct kobject *kobj,
 	ssize_t cnt = 0;
 	unsigned long flags;
 
-	for (; size > 0 && pos < M48T59_NVRAM_SIZE; cnt++, size--) {
+	for (; size > 0 && pos < pdata->offset; cnt++, size--) {
 		spin_lock_irqsave(&m48t59->lock, flags);
 		*buf++ = M48T59_READ(cnt);
 		spin_unlock_irqrestore(&m48t59->lock, flags);
@@ -341,7 +347,7 @@ static ssize_t m48t59_nvram_write(struct kobject *kobj,
 	ssize_t cnt = 0;
 	unsigned long flags;
 
-	for (; size > 0 && pos < M48T59_NVRAM_SIZE; cnt++, size--) {
+	for (; size > 0 && pos < pdata->offset; cnt++, size--) {
 		spin_lock_irqsave(&m48t59->lock, flags);
 		M48T59_WRITE(*buf++, cnt);
 		spin_unlock_irqrestore(&m48t59->lock, flags);
@@ -358,7 +364,6 @@ static struct bin_attribute m48t59_nvram_attr = {
 	},
 	.read = m48t59_nvram_read,
 	.write = m48t59_nvram_write,
-	.size = M48T59_NVRAM_SIZE,
 };
 
 static int __devinit m48t59_rtc_probe(struct platform_device *pdev)
@@ -367,6 +372,8 @@ static int __devinit m48t59_rtc_probe(struct platform_device *pdev)
 	struct m48t59_private *m48t59 = NULL;
 	struct resource *res;
 	int ret = -ENOMEM;
+	char *name;
+	const struct rtc_class_ops *ops;
 
 	/* This chip could be memory-mapped or I/O-mapped */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -391,6 +398,8 @@ static int __devinit m48t59_rtc_probe(struct platform_device *pdev)
 			/* Ensure we only kmalloc platform data once */
 			pdev->dev.platform_data = pdata;
 		}
+		if (!pdata->type)
+			pdata->type = M48T59RTC_TYPE_M48T59;
 
 		/* Try to use the generic memory read/write ops */
 		if (!pdata->write_byte)
@@ -403,10 +412,14 @@ static int __devinit m48t59_rtc_probe(struct platform_device *pdev)
 	if (!m48t59)
 		return -ENOMEM;
 
-	m48t59->size = res->end - res->start + 1;
-	m48t59->ioaddr = ioremap(res->start, m48t59->size);
-	if (!m48t59->ioaddr)
-		goto out;
+	m48t59->ioaddr = pdata->ioaddr;
+
+	if (!m48t59->ioaddr) {
+		/* ioaddr not mapped externally */
+		m48t59->ioaddr = ioremap(res->start, res->end - res->start + 1);
+		if (!m48t59->ioaddr)
+			goto out;
+	}
 
 	/* Try to get irq number. We also can work in
 	 * the mode without IRQ.
@@ -421,14 +434,36 @@ static int __devinit m48t59_rtc_probe(struct platform_device *pdev)
 		if (ret)
 			goto out;
 	}
+	switch (pdata->type) {
+	case M48T59RTC_TYPE_M48T59:
+		name = "m48t59";
+		ops = &m48t59_rtc_ops;
+		pdata->offset = 0x1ff0;
+		break;
+	case M48T59RTC_TYPE_M48T02:
+		name = "m48t02";
+		ops = &m48t02_rtc_ops;
+		pdata->offset = 0x7f0;
+		break;
+	case M48T59RTC_TYPE_M48T08:
+		name = "m48t08";
+		ops = &m48t02_rtc_ops;
+		pdata->offset = 0x1ff0;
+		break;
+	default:
+		dev_err(&pdev->dev, "Unknown RTC type\n");
+		ret = -ENODEV;
+		goto out;
+	}
 
-	m48t59->rtc = rtc_device_register("m48t59", &pdev->dev,
-				&m48t59_rtc_ops, THIS_MODULE);
+	m48t59->rtc = rtc_device_register(name, &pdev->dev, ops, THIS_MODULE);
 	if (IS_ERR(m48t59->rtc)) {
 		ret = PTR_ERR(m48t59->rtc);
 		goto out;
 	}
 
+	m48t59_nvram_attr.size = pdata->offset;
+
 	ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
 	if (ret)
 		goto out;
@@ -452,11 +487,12 @@ out:
 static int __devexit m48t59_rtc_remove(struct platform_device *pdev)
 {
 	struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
+	struct m48t59_plat_data *pdata = pdev->dev.platform_data;
 
 	sysfs_remove_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
 	if (!IS_ERR(m48t59->rtc))
 		rtc_device_unregister(m48t59->rtc);
-	if (m48t59->ioaddr)
+	if (m48t59->ioaddr && !pdata->ioaddr)
 		iounmap(m48t59->ioaddr);
 	if (m48t59->irq != NO_IRQ)
 		free_irq(m48t59->irq, &pdev->dev);
@@ -491,5 +527,5 @@ module_init(m48t59_rtc_init);
 module_exit(m48t59_rtc_exit);
 
 MODULE_AUTHOR("Mark Zhan <rongkai.zhan@windriver.com>");
-MODULE_DESCRIPTION("M48T59 RTC driver");
+MODULE_DESCRIPTION("M48T59/M48T02/M48T08 RTC driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-starfire.c b/drivers/rtc/rtc-starfire.c
new file mode 100644
index 000000000000..7ccb0dd700af
--- /dev/null
+++ b/drivers/rtc/rtc-starfire.c
@@ -0,0 +1,120 @@
+/* rtc-starfire.c: Starfire platform RTC driver.
+ *
+ * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+
+#include <asm/oplib.h>
+
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_DESCRIPTION("Starfire RTC driver");
+MODULE_LICENSE("GPL");
+
+struct starfire_rtc {
+	struct rtc_device	*rtc;
+	spinlock_t		lock;
+};
+
+static u32 starfire_get_time(void)
+{
+	static char obp_gettod[32];
+	static u32 unix_tod;
+
+	sprintf(obp_gettod, "h# %08x unix-gettod",
+		(unsigned int) (long) &unix_tod);
+	prom_feval(obp_gettod);
+
+	return unix_tod;
+}
+
+static int starfire_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct starfire_rtc *p = dev_get_drvdata(dev);
+	unsigned long flags, secs;
+
+	spin_lock_irqsave(&p->lock, flags);
+	secs = starfire_get_time();
+	spin_unlock_irqrestore(&p->lock, flags);
+
+	rtc_time_to_tm(secs, tm);
+
+	return 0;
+}
+
+static int starfire_set_time(struct device *dev, struct rtc_time *tm)
+{
+	unsigned long secs;
+	int err;
+
+	err = rtc_tm_to_time(tm, &secs);
+	if (err)
+		return err;
+
+	/* Do nothing, time is set using the service processor
+	 * console on this platform.
+	 */
+	return 0;
+}
+
+static const struct rtc_class_ops starfire_rtc_ops = {
+	.read_time	= starfire_read_time,
+	.set_time	= starfire_set_time,
+};
+
+static int __devinit starfire_rtc_probe(struct platform_device *pdev)
+{
+	struct starfire_rtc *p = kzalloc(sizeof(*p), GFP_KERNEL);
+
+	if (!p)
+		return -ENOMEM;
+
+	spin_lock_init(&p->lock);
+
+	p->rtc = rtc_device_register("starfire", &pdev->dev,
+				     &starfire_rtc_ops, THIS_MODULE);
+	if (IS_ERR(p->rtc)) {
+		int err = PTR_ERR(p->rtc);
+		kfree(p);
+		return err;
+	}
+	platform_set_drvdata(pdev, p);
+	return 0;
+}
+
+static int __devexit starfire_rtc_remove(struct platform_device *pdev)
+{
+	struct starfire_rtc *p = platform_get_drvdata(pdev);
+
+	rtc_device_unregister(p->rtc);
+	kfree(p);
+
+	return 0;
+}
+
+static struct platform_driver starfire_rtc_driver = {
+	.driver		= {
+		.name	= "rtc-starfire",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= starfire_rtc_probe,
+	.remove		= __devexit_p(starfire_rtc_remove),
+};
+
+static int __init starfire_rtc_init(void)
+{
+	return platform_driver_register(&starfire_rtc_driver);
+}
+
+static void __exit starfire_rtc_exit(void)
+{
+	platform_driver_unregister(&starfire_rtc_driver);
+}
+
+module_init(starfire_rtc_init);
+module_exit(starfire_rtc_exit);
diff --git a/drivers/rtc/rtc-sun4v.c b/drivers/rtc/rtc-sun4v.c
new file mode 100644
index 000000000000..2012ccbb4a53
--- /dev/null
+++ b/drivers/rtc/rtc-sun4v.c
@@ -0,0 +1,153 @@
+/* rtc-sun4c.c: Hypervisor based RTC for SUN4V systems.
+ *
+ * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+
+#include <asm/hypervisor.h>
+
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_DESCRIPTION("SUN4V RTC driver");
+MODULE_LICENSE("GPL");
+
+struct sun4v_rtc {
+	struct rtc_device	*rtc;
+	spinlock_t		lock;
+};
+
+static unsigned long hypervisor_get_time(void)
+{
+	unsigned long ret, time;
+	int retries = 10000;
+
+retry:
+	ret = sun4v_tod_get(&time);
+	if (ret == HV_EOK)
+		return time;
+	if (ret == HV_EWOULDBLOCK) {
+		if (--retries > 0) {
+			udelay(100);
+			goto retry;
+		}
+		printk(KERN_WARNING "SUN4V: tod_get() timed out.\n");
+		return 0;
+	}
+	printk(KERN_WARNING "SUN4V: tod_get() not supported.\n");
+	return 0;
+}
+
+static int sun4v_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct sun4v_rtc *p = dev_get_drvdata(dev);
+	unsigned long flags, secs;
+
+	spin_lock_irqsave(&p->lock, flags);
+	secs = hypervisor_get_time();
+	spin_unlock_irqrestore(&p->lock, flags);
+
+	rtc_time_to_tm(secs, tm);
+
+	return 0;
+}
+
+static int hypervisor_set_time(unsigned long secs)
+{
+	unsigned long ret;
+	int retries = 10000;
+
+retry:
+	ret = sun4v_tod_set(secs);
+	if (ret == HV_EOK)
+		return 0;
+	if (ret == HV_EWOULDBLOCK) {
+		if (--retries > 0) {
+			udelay(100);
+			goto retry;
+		}
+		printk(KERN_WARNING "SUN4V: tod_set() timed out.\n");
+		return -EAGAIN;
+	}
+	printk(KERN_WARNING "SUN4V: tod_set() not supported.\n");
+	return -EOPNOTSUPP;
+}
+
+static int sun4v_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct sun4v_rtc *p = dev_get_drvdata(dev);
+	unsigned long flags, secs;
+	int err;
+
+	err = rtc_tm_to_time(tm, &secs);
+	if (err)
+		return err;
+
+	spin_lock_irqsave(&p->lock, flags);
+	err = hypervisor_set_time(secs);
+	spin_unlock_irqrestore(&p->lock, flags);
+
+	return err;
+}
+
+static const struct rtc_class_ops sun4v_rtc_ops = {
+	.read_time	= sun4v_read_time,
+	.set_time	= sun4v_set_time,
+};
+
+static int __devinit sun4v_rtc_probe(struct platform_device *pdev)
+{
+	struct sun4v_rtc *p = kzalloc(sizeof(*p), GFP_KERNEL);
+
+	if (!p)
+		return -ENOMEM;
+
+	spin_lock_init(&p->lock);
+
+	p->rtc = rtc_device_register("sun4v", &pdev->dev,
+				     &sun4v_rtc_ops, THIS_MODULE);
+	if (IS_ERR(p->rtc)) {
+		int err = PTR_ERR(p->rtc);
+		kfree(p);
+		return err;
+	}
+	platform_set_drvdata(pdev, p);
+	return 0;
+}
+
+static int __devexit sun4v_rtc_remove(struct platform_device *pdev)
+{
+	struct sun4v_rtc *p = platform_get_drvdata(pdev);
+
+	rtc_device_unregister(p->rtc);
+	kfree(p);
+
+	return 0;
+}
+
+static struct platform_driver sun4v_rtc_driver = {
+	.driver		= {
+		.name	= "rtc-sun4v",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= sun4v_rtc_probe,
+	.remove		= __devexit_p(sun4v_rtc_remove),
+};
+
+static int __init sun4v_rtc_init(void)
+{
+	return platform_driver_register(&sun4v_rtc_driver);
+}
+
+static void __exit sun4v_rtc_exit(void)
+{
+	platform_driver_unregister(&sun4v_rtc_driver);
+}
+
+module_init(sun4v_rtc_init);
+module_exit(sun4v_rtc_exit);
diff --git a/drivers/sbus/Makefile b/drivers/sbus/Makefile
index 7b1d24d95308..e94dc25805f9 100644
--- a/drivers/sbus/Makefile
+++ b/drivers/sbus/Makefile
@@ -2,8 +2,4 @@
 # Makefile for the linux kernel.
 #
 
-ifneq ($(ARCH),m68k)
-obj-y    := sbus.o dvma.o
-endif
-
 obj-$(CONFIG_SBUSCHAR) += char/
diff --git a/drivers/sbus/char/Kconfig b/drivers/sbus/char/Kconfig
index 400c65bfb8c7..73cde85d04d8 100644
--- a/drivers/sbus/char/Kconfig
+++ b/drivers/sbus/char/Kconfig
@@ -13,16 +13,6 @@ config SUN_OPENPROMIO
 
 	  If unsure, say Y.
 
-config SUN_MOSTEK_RTC
-	tristate "Mostek real time clock support"
-	depends on SPARC32
-	help
-	  The Mostek RTC chip is used on all known Sun computers except
-	  some JavaStations. For a JavaStation you need to say Y both here
-	  and to "Enhanced Real Time Clock Support".
-
-	  Say Y here unless you are building a special purpose kernel.
-
 config OBP_FLASH
 	tristate "OBP Flash Device support"
 	depends on SPARC64
@@ -30,26 +20,9 @@ config OBP_FLASH
 	  The OpenBoot PROM on Ultra systems is flashable. If you want to be
 	  able to upgrade the OBP firmware, say Y here.
 
-config SUN_BPP
-	tristate "Bidirectional parallel port support (OBSOLETE)"
-	depends on EXPERIMENTAL
-	help
-	  Say Y here to support Sun's obsolete variant of IEEE1284
-	  bidirectional parallel port protocol as /dev/bppX.  Can be built on
-	  x86 machines.
-
-config SUN_VIDEOPIX
-	tristate "Videopix Frame Grabber (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && (BROKEN || !64BIT)
-	help
-	  Say Y here to support the Videopix Frame Grabber from Sun
-	  Microsystems, commonly found on SPARCstations.  This card, which is
-	  based on the Phillips SAA9051, can handle NTSC and PAL/SECAM and
-	  SVIDEO signals.
-
 config TADPOLE_TS102_UCTRL
 	tristate "Tadpole TS102 Microcontroller support (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && SPARC32
+	depends on EXPERIMENTAL
 	help
 	  Say Y here to directly support the TS102 Microcontroller interface
 	  on the Tadpole Sparcbook 3.  This device handles power-management
diff --git a/drivers/sbus/char/Makefile b/drivers/sbus/char/Makefile
index 7ab060e9a5fe..78b6183c9866 100644
--- a/drivers/sbus/char/Makefile
+++ b/drivers/sbus/char/Makefile
@@ -7,18 +7,12 @@
 # Rewritten to use lists instead of if-statements.
 #
 
-vfc-objs := vfc_dev.o vfc_i2c.o
 bbc-objs := bbc_i2c.o bbc_envctrl.o
 
 obj-$(CONFIG_ENVCTRL)			+= envctrl.o
 obj-$(CONFIG_DISPLAY7SEG)		+= display7seg.o
-obj-$(CONFIG_WATCHDOG_CP1XXX)		+= cpwatchdog.o
-obj-$(CONFIG_WATCHDOG_RIO)		+= riowatchdog.o
 obj-$(CONFIG_OBP_FLASH)			+= flash.o
 obj-$(CONFIG_SUN_OPENPROMIO)		+= openprom.o
-obj-$(CONFIG_SUN_MOSTEK_RTC)		+= rtc.o
-obj-$(CONFIG_SUN_BPP)			+= bpp.o
-obj-$(CONFIG_SUN_VIDEOPIX)		+= vfc.o
 obj-$(CONFIG_TADPOLE_TS102_UCTRL)	+= uctrl.o
 obj-$(CONFIG_SUN_JSFLASH)		+= jsflash.o
 obj-$(CONFIG_BBC_I2C)			+= bbc.o
diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c
index 0bde26989a23..15dab96d05e3 100644
--- a/drivers/sbus/char/bbc_envctrl.c
+++ b/drivers/sbus/char/bbc_envctrl.c
@@ -1,15 +1,15 @@
-/* $Id: bbc_envctrl.c,v 1.4 2001/04/06 16:48:08 davem Exp $
- * bbc_envctrl.c: UltraSPARC-III environment control driver.
+/* bbc_envctrl.c: UltraSPARC-III environment control driver.
  *
- * Copyright (C) 2001 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2001, 2008 David S. Miller (davem@davemloft.net)
  */
 
 #include <linux/kthread.h>
 #include <linux/delay.h>
 #include <linux/kmod.h>
 #include <linux/reboot.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <asm/oplib.h>
-#include <asm/ebus.h>
 
 #include "bbc_i2c.h"
 #include "max1617.h"
@@ -75,43 +75,8 @@ static struct temp_limits amb_temp_limits[2] = {
 	{ 65, 55, 40, 5, -5, -10 },
 };
 
-enum fan_action { FAN_SLOWER, FAN_SAME, FAN_FASTER, FAN_FULLBLAST, FAN_STATE_MAX };
-
-struct bbc_cpu_temperature {
-	struct bbc_cpu_temperature	*next;
-
-	struct bbc_i2c_client		*client;
-	int				index;
-
-	/* Current readings, and history. */
-	s8				curr_cpu_temp;
-	s8				curr_amb_temp;
-	s8				prev_cpu_temp;
-	s8				prev_amb_temp;
-	s8				avg_cpu_temp;
-	s8				avg_amb_temp;
-
-	int				sample_tick;
-
-	enum fan_action			fan_todo[2];
-#define FAN_AMBIENT	0
-#define FAN_CPU		1
-};
-
-struct bbc_cpu_temperature *all_bbc_temps;
-
-struct bbc_fan_control {
-	struct bbc_fan_control 	*next;
-
-	struct bbc_i2c_client 	*client;
-	int 			index;
-
-	int			psupply_fan_on;
-	int			cpu_fan_speed;
-	int			system_fan_speed;
-};
-
-struct bbc_fan_control *all_bbc_fans;
+static LIST_HEAD(all_temps);
+static LIST_HEAD(all_fans);
 
 #define CPU_FAN_REG	0xf0
 #define SYS_FAN_REG	0xf2
@@ -330,7 +295,7 @@ static enum fan_action prioritize_fan_action(int which_fan)
 	 * recommend we do, and perform that action on all the
 	 * fans.
 	 */
-	for (tp = all_bbc_temps; tp; tp = tp->next) {
+	list_for_each_entry(tp, &all_temps, glob_list) {
 		if (tp->fan_todo[which_fan] == FAN_FULLBLAST) {
 			decision = FAN_FULLBLAST;
 			break;
@@ -439,7 +404,7 @@ static void fans_full_blast(void)
 	/* Since we will not be monitoring things anymore, put
 	 * the fans on full blast.
 	 */
-	for (fp = all_bbc_fans; fp; fp = fp->next) {
+	list_for_each_entry(fp, &all_fans, glob_list) {
 		fp->cpu_fan_speed = FAN_SPEED_MAX;
 		fp->system_fan_speed = FAN_SPEED_MAX;
 		fp->psupply_fan_on = 1;
@@ -463,11 +428,11 @@ static int kenvctrld(void *__unused)
 		if (kthread_should_stop())
 			break;
 
-		for (tp = all_bbc_temps; tp; tp = tp->next) {
+		list_for_each_entry(tp, &all_temps, glob_list) {
 			get_current_temps(tp);
 			analyze_temps(tp, &last_warning_jiffies);
 		}
-		for (fp = all_bbc_fans; fp; fp = fp->next)
+		list_for_each_entry(fp, &all_fans, glob_list)
 			maybe_new_fan_speeds(fp);
 	}
 	printk(KERN_INFO "bbc_envctrl: kenvctrld exiting...\n");
@@ -477,7 +442,8 @@ static int kenvctrld(void *__unused)
 	return 0;
 }
 
-static void attach_one_temp(struct linux_ebus_child *echild, int temp_idx)
+static void attach_one_temp(struct bbc_i2c_bus *bp, struct of_device *op,
+			    int temp_idx)
 {
 	struct bbc_cpu_temperature *tp;
 
@@ -485,20 +451,17 @@ static void attach_one_temp(struct linux_ebus_child *echild, int temp_idx)
 	if (!tp)
 		return;
 
-	tp->client = bbc_i2c_attach(echild);
+	tp->client = bbc_i2c_attach(bp, op);
 	if (!tp->client) {
 		kfree(tp);
 		return;
 	}
 
+
 	tp->index = temp_idx;
-	{
-		struct bbc_cpu_temperature **tpp = &all_bbc_temps;
-		while (*tpp)
-			tpp = &((*tpp)->next);
-		tp->next = NULL;
-		*tpp = tp;
-	}
+
+	list_add(&tp->glob_list, &all_temps);
+	list_add(&tp->bp_list, &bp->temps);
 
 	/* Tell it to convert once every 5 seconds, clear all cfg
 	 * bits.
@@ -524,7 +487,8 @@ static void attach_one_temp(struct linux_ebus_child *echild, int temp_idx)
 	tp->fan_todo[FAN_CPU] = FAN_SAME;
 }
 
-static void attach_one_fan(struct linux_ebus_child *echild, int fan_idx)
+static void attach_one_fan(struct bbc_i2c_bus *bp, struct of_device *op,
+			   int fan_idx)
 {
 	struct bbc_fan_control *fp;
 
@@ -532,7 +496,7 @@ static void attach_one_fan(struct linux_ebus_child *echild, int fan_idx)
 	if (!fp)
 		return;
 
-	fp->client = bbc_i2c_attach(echild);
+	fp->client = bbc_i2c_attach(bp, op);
 	if (!fp->client) {
 		kfree(fp);
 		return;
@@ -540,13 +504,8 @@ static void attach_one_fan(struct linux_ebus_child *echild, int fan_idx)
 
 	fp->index = fan_idx;
 
-	{
-		struct bbc_fan_control **fpp = &all_bbc_fans;
-		while (*fpp)
-			fpp = &((*fpp)->next);
-		fp->next = NULL;
-		*fpp = fp;
-	}
+	list_add(&fp->glob_list, &all_fans);
+	list_add(&fp->bp_list, &bp->fans);
 
 	/* The i2c device controlling the fans is write-only.
 	 * So the only way to keep track of the current power
@@ -563,18 +522,18 @@ static void attach_one_fan(struct linux_ebus_child *echild, int fan_idx)
 	set_fan_speeds(fp);
 }
 
-int bbc_envctrl_init(void)
+int bbc_envctrl_init(struct bbc_i2c_bus *bp)
 {
-	struct linux_ebus_child *echild;
+	struct of_device *op;
 	int temp_index = 0;
 	int fan_index = 0;
 	int devidx = 0;
 
-	while ((echild = bbc_i2c_getdev(devidx++)) != NULL) {
-		if (!strcmp(echild->prom_node->name, "temperature"))
-			attach_one_temp(echild, temp_index++);
-		if (!strcmp(echild->prom_node->name, "fan-control"))
-			attach_one_fan(echild, fan_index++);
+	while ((op = bbc_i2c_getdev(bp, devidx++)) != NULL) {
+		if (!strcmp(op->node->name, "temperature"))
+			attach_one_temp(bp, op, temp_index++);
+		if (!strcmp(op->node->name, "fan-control"))
+			attach_one_fan(bp, op, fan_index++);
 	}
 	if (temp_index != 0 && fan_index != 0) {
 		kenvctrld_task = kthread_run(kenvctrld, NULL, "kenvctrld");
@@ -597,26 +556,22 @@ static void destroy_one_fan(struct bbc_fan_control *fp)
 	kfree(fp);
 }
 
-void bbc_envctrl_cleanup(void)
+void bbc_envctrl_cleanup(struct bbc_i2c_bus *bp)
 {
-	struct bbc_cpu_temperature *tp;
-	struct bbc_fan_control *fp;
+	struct bbc_cpu_temperature *tp, *tpos;
+	struct bbc_fan_control *fp, *fpos;
 
 	kthread_stop(kenvctrld_task);
 
-	tp = all_bbc_temps;
-	while (tp != NULL) {
-		struct bbc_cpu_temperature *next = tp->next;
+	list_for_each_entry_safe(tp, tpos, &bp->temps, bp_list) {
+		list_del(&tp->bp_list);
+		list_del(&tp->glob_list);
 		destroy_one_temp(tp);
-		tp = next;
 	}
-	all_bbc_temps = NULL;
 
-	fp = all_bbc_fans;
-	while (fp != NULL) {
-		struct bbc_fan_control *next = fp->next;
+	list_for_each_entry_safe(fp, fpos, &bp->fans, bp_list) {
+		list_del(&fp->bp_list);
+		list_del(&fp->glob_list);
 		destroy_one_fan(fp);
-		fp = next;
 	}
-	all_bbc_fans = NULL;
 }
diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c
index ac8ef2ce07fb..f08e169ba1b5 100644
--- a/drivers/sbus/char/bbc_i2c.c
+++ b/drivers/sbus/char/bbc_i2c.c
@@ -1,8 +1,7 @@
-/* $Id: bbc_i2c.c,v 1.2 2001/04/02 09:59:08 davem Exp $
- * bbc_i2c.c: I2C low-level driver for BBC device on UltraSPARC-III
+/* bbc_i2c.c: I2C low-level driver for BBC device on UltraSPARC-III
  *            platforms.
  *
- * Copyright (C) 2001 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2001, 2008 David S. Miller (davem@davemloft.net)
  */
 
 #include <linux/module.h>
@@ -14,9 +13,8 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/oplib.h>
-#include <asm/ebus.h>
-#include <asm/spitfire.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <asm/bbc.h>
 #include <asm/io.h>
 
@@ -53,54 +51,12 @@
  * The second controller also connects to the smartcard reader, if present.
  */
 
-#define NUM_CHILDREN	8
-struct bbc_i2c_bus {
-	struct bbc_i2c_bus		*next;
-	int				index;
-	spinlock_t			lock;
-	void				__iomem *i2c_bussel_reg;
-	void				__iomem *i2c_control_regs;
-	unsigned char			own, clock;
-
-	wait_queue_head_t		wq;
-	volatile int			waiting;
-
-	struct linux_ebus_device	*bus_edev;
-	struct {
-		struct linux_ebus_child	*device;
-		int			client_claimed;
-	} devs[NUM_CHILDREN];
-};
-
-static struct bbc_i2c_bus *all_bbc_i2c;
-
-struct bbc_i2c_client {
-	struct bbc_i2c_bus	*bp;
-	struct linux_ebus_child	*echild;
-	int			bus;
-	int			address;
-};
-
-static int find_device(struct bbc_i2c_bus *bp, struct linux_ebus_child *echild)
+static void set_device_claimage(struct bbc_i2c_bus *bp, struct of_device *op, int val)
 {
 	int i;
 
 	for (i = 0; i < NUM_CHILDREN; i++) {
-		if (bp->devs[i].device == echild) {
-			if (bp->devs[i].client_claimed)
-				return 0;
-			return 1;
-		}
-	}
-	return 0;
-}
-
-static void set_device_claimage(struct bbc_i2c_bus *bp, struct linux_ebus_child *echild, int val)
-{
-	int i;
-
-	for (i = 0; i < NUM_CHILDREN; i++) {
-		if (bp->devs[i].device == echild) {
+		if (bp->devs[i].device == op) {
 			bp->devs[i].client_claimed = val;
 			return;
 		}
@@ -110,61 +66,47 @@ static void set_device_claimage(struct bbc_i2c_bus *bp, struct linux_ebus_child
 #define claim_device(BP,ECHILD)		set_device_claimage(BP,ECHILD,1)
 #define release_device(BP,ECHILD)	set_device_claimage(BP,ECHILD,0)
 
-static struct bbc_i2c_bus *find_bus_for_device(struct linux_ebus_child *echild)
+struct of_device *bbc_i2c_getdev(struct bbc_i2c_bus *bp, int index)
 {
-	struct bbc_i2c_bus *bp = all_bbc_i2c;
+	struct of_device *op = NULL;
+	int curidx = 0, i;
 
-	while (bp != NULL) {
-		if (find_device(bp, echild) != 0)
+	for (i = 0; i < NUM_CHILDREN; i++) {
+		if (!(op = bp->devs[i].device))
 			break;
-		bp = bp->next;
+		if (curidx == index)
+			goto out;
+		op = NULL;
+		curidx++;
 	}
 
-	return bp;
-}
-
-struct linux_ebus_child *bbc_i2c_getdev(int index)
-{
-	struct bbc_i2c_bus *bp = all_bbc_i2c;
-	struct linux_ebus_child *echild = NULL;
-	int curidx = 0;
-
-	while (bp != NULL) {
-		struct bbc_i2c_bus *next = bp->next;
-		int i;
-
-		for (i = 0; i < NUM_CHILDREN; i++) {
-			if (!(echild = bp->devs[i].device))
-				break;
-			if (curidx == index)
-				goto out;
-			echild = NULL;
-			curidx++;
-		}
-		bp = next;
-	}
 out:
 	if (curidx == index)
-		return echild;
+		return op;
 	return NULL;
 }
 
-struct bbc_i2c_client *bbc_i2c_attach(struct linux_ebus_child *echild)
+struct bbc_i2c_client *bbc_i2c_attach(struct bbc_i2c_bus *bp, struct of_device *op)
 {
-	struct bbc_i2c_bus *bp = find_bus_for_device(echild);
 	struct bbc_i2c_client *client;
+	const u32 *reg;
 
-	if (!bp)
-		return NULL;
 	client = kzalloc(sizeof(*client), GFP_KERNEL);
 	if (!client)
 		return NULL;
 	client->bp = bp;
-	client->echild = echild;
-	client->bus = echild->resource[0].start;
-	client->address = echild->resource[1].start;
+	client->op = op;
+
+	reg = of_get_property(op->node, "reg", NULL);
+	if (!reg) {
+		kfree(client);
+		return NULL;
+	}
 
-	claim_device(bp, echild);
+	client->bus = reg[0];
+	client->address = reg[1];
+
+	claim_device(bp, op);
 
 	return client;
 }
@@ -172,9 +114,9 @@ struct bbc_i2c_client *bbc_i2c_attach(struct linux_ebus_child *echild)
 void bbc_i2c_detach(struct bbc_i2c_client *client)
 {
 	struct bbc_i2c_bus *bp = client->bp;
-	struct linux_ebus_child *echild = client->echild;
+	struct of_device *op = client->op;
 
-	release_device(bp, echild);
+	release_device(bp, op);
 	kfree(client);
 }
 
@@ -355,44 +297,43 @@ static void __init reset_one_i2c(struct bbc_i2c_bus *bp)
 	writeb(I2C_PCF_IDLE, bp->i2c_control_regs + 0x0);
 }
 
-static int __init attach_one_i2c(struct linux_ebus_device *edev, int index)
+static struct bbc_i2c_bus * __init attach_one_i2c(struct of_device *op, int index)
 {
 	struct bbc_i2c_bus *bp;
-	struct linux_ebus_child *echild;
+	struct device_node *dp;
 	int entry;
 
 	bp = kzalloc(sizeof(*bp), GFP_KERNEL);
 	if (!bp)
-		return -ENOMEM;
+		return NULL;
 
-	bp->i2c_control_regs = ioremap(edev->resource[0].start, 0x2);
+	bp->i2c_control_regs = of_ioremap(&op->resource[0], 0, 0x2, "bbc_i2c_regs");
 	if (!bp->i2c_control_regs)
 		goto fail;
 
-	if (edev->num_addrs == 2) {
-		bp->i2c_bussel_reg = ioremap(edev->resource[1].start, 0x1);
-		if (!bp->i2c_bussel_reg)
-			goto fail;
-	}
+	bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, "bbc_i2c_bussel");
+	if (!bp->i2c_bussel_reg)
+		goto fail;
 
 	bp->waiting = 0;
 	init_waitqueue_head(&bp->wq);
-	if (request_irq(edev->irqs[0], bbc_i2c_interrupt,
+	if (request_irq(op->irqs[0], bbc_i2c_interrupt,
 			IRQF_SHARED, "bbc_i2c", bp))
 		goto fail;
 
 	bp->index = index;
-	bp->bus_edev = edev;
+	bp->op = op;
 
 	spin_lock_init(&bp->lock);
-	bp->next = all_bbc_i2c;
-	all_bbc_i2c = bp;
 
 	entry = 0;
-	for (echild = edev->children;
-	     echild && entry < 8;
-	     echild = echild->next, entry++) {
-		bp->devs[entry].device = echild;
+	for (dp = op->node->child;
+	     dp && entry < 8;
+	     dp = dp->sibling, entry++) {
+		struct of_device *child_op;
+
+		child_op = of_find_device_by_node(dp);
+		bp->devs[entry].device = child_op;
 		bp->devs[entry].client_claimed = 0;
 	}
 
@@ -406,86 +347,90 @@ static int __init attach_one_i2c(struct linux_ebus_device *edev, int index)
 
 	reset_one_i2c(bp);
 
-	return 0;
+	return bp;
 
 fail:
 	if (bp->i2c_bussel_reg)
-		iounmap(bp->i2c_bussel_reg);
+		of_iounmap(&op->resource[1], bp->i2c_bussel_reg, 1);
 	if (bp->i2c_control_regs)
-		iounmap(bp->i2c_control_regs);
+		of_iounmap(&op->resource[0], bp->i2c_control_regs, 2);
 	kfree(bp);
-	return -EINVAL;
-}
-
-static int __init bbc_present(void)
-{
-	struct linux_ebus *ebus = NULL;
-	struct linux_ebus_device *edev = NULL;
-
-	for_each_ebus(ebus) {
-		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_node->name, "bbc"))
-				return 1;
-		}
-	}
-	return 0;
+	return NULL;
 }
 
-extern int bbc_envctrl_init(void);
-extern void bbc_envctrl_cleanup(void);
-static void bbc_i2c_cleanup(void);
+extern int bbc_envctrl_init(struct bbc_i2c_bus *bp);
+extern void bbc_envctrl_cleanup(struct bbc_i2c_bus *bp);
 
-static int __init bbc_i2c_init(void)
+static int __devinit bbc_i2c_probe(struct of_device *op,
+				   const struct of_device_id *match)
 {
-	struct linux_ebus *ebus = NULL;
-	struct linux_ebus_device *edev = NULL;
+	struct bbc_i2c_bus *bp;
 	int err, index = 0;
 
-	if ((tlb_type != cheetah && tlb_type != cheetah_plus) ||
-	    !bbc_present())
-		return -ENODEV;
+	bp = attach_one_i2c(op, index);
+	if (!bp)
+		return -EINVAL;
 
-	for_each_ebus(ebus) {
-		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_node->name, "i2c")) {
-				if (!attach_one_i2c(edev, index))
-					index++;
-			}
-		}
+	err = bbc_envctrl_init(bp);
+	if (err) {
+		free_irq(op->irqs[0], bp);
+		if (bp->i2c_bussel_reg)
+			of_iounmap(&op->resource[0], bp->i2c_bussel_reg, 1);
+		if (bp->i2c_control_regs)
+			of_iounmap(&op->resource[1], bp->i2c_control_regs, 2);
+		kfree(bp);
+	} else {
+		dev_set_drvdata(&op->dev, bp);
 	}
 
-	if (!index)
-		return -ENODEV;
-
-	err = bbc_envctrl_init();
-	if (err)
-		bbc_i2c_cleanup();
 	return err;
 }
 
-static void bbc_i2c_cleanup(void)
+static int __devexit bbc_i2c_remove(struct of_device *op)
 {
-	struct bbc_i2c_bus *bp = all_bbc_i2c;
+	struct bbc_i2c_bus *bp = dev_get_drvdata(&op->dev);
+
+	bbc_envctrl_cleanup(bp);
+
+	free_irq(op->irqs[0], bp);
 
-	bbc_envctrl_cleanup();
+	if (bp->i2c_bussel_reg)
+		of_iounmap(&op->resource[0], bp->i2c_bussel_reg, 1);
+	if (bp->i2c_control_regs)
+		of_iounmap(&op->resource[1], bp->i2c_control_regs, 2);
 
-	while (bp != NULL) {
-		struct bbc_i2c_bus *next = bp->next;
+	kfree(bp);
 
-		free_irq(bp->bus_edev->irqs[0], bp);
+	return 0;
+}
 
-		if (bp->i2c_bussel_reg)
-			iounmap(bp->i2c_bussel_reg);
-		if (bp->i2c_control_regs)
-			iounmap(bp->i2c_control_regs);
+static const struct of_device_id bbc_i2c_match[] = {
+	{
+		.name = "i2c",
+		.compatible = "SUNW,bbc-i2c",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, bbc_i2c_match);
 
-		kfree(bp);
+static struct of_platform_driver bbc_i2c_driver = {
+	.name		= "bbc_i2c",
+	.match_table	= bbc_i2c_match,
+	.probe		= bbc_i2c_probe,
+	.remove		= __devexit_p(bbc_i2c_remove),
+};
 
-		bp = next;
-	}
-	all_bbc_i2c = NULL;
+static int __init bbc_i2c_init(void)
+{
+	return of_register_driver(&bbc_i2c_driver, &of_bus_type);
+}
+
+static void __exit bbc_i2c_exit(void)
+{
+	of_unregister_driver(&bbc_i2c_driver);
 }
 
 module_init(bbc_i2c_init);
-module_exit(bbc_i2c_cleanup);
+module_exit(bbc_i2c_exit);
+
 MODULE_LICENSE("GPL");
diff --git a/drivers/sbus/char/bbc_i2c.h b/drivers/sbus/char/bbc_i2c.h
index fb01bd17704b..83c4811b7b5e 100644
--- a/drivers/sbus/char/bbc_i2c.h
+++ b/drivers/sbus/char/bbc_i2c.h
@@ -1,14 +1,79 @@
-/* $Id: bbc_i2c.h,v 1.2 2001/04/02 09:59:25 davem Exp $ */
 #ifndef _BBC_I2C_H
 #define _BBC_I2C_H
 
-#include <asm/ebus.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/list.h>
 
-struct bbc_i2c_client;
+struct bbc_i2c_client {
+	struct bbc_i2c_bus		*bp;
+	struct of_device		*op;
+	int				bus;
+	int				address;
+};
+
+enum fan_action { FAN_SLOWER, FAN_SAME, FAN_FASTER, FAN_FULLBLAST, FAN_STATE_MAX };
+
+struct bbc_cpu_temperature {
+	struct list_head		bp_list;
+	struct list_head		glob_list;
+
+	struct bbc_i2c_client		*client;
+	int				index;
+
+	/* Current readings, and history. */
+	s8				curr_cpu_temp;
+	s8				curr_amb_temp;
+	s8				prev_cpu_temp;
+	s8				prev_amb_temp;
+	s8				avg_cpu_temp;
+	s8				avg_amb_temp;
+
+	int				sample_tick;
+
+	enum fan_action			fan_todo[2];
+#define FAN_AMBIENT	0
+#define FAN_CPU		1
+};
+
+struct bbc_fan_control {
+	struct list_head		bp_list;
+	struct list_head		glob_list;
+
+	struct bbc_i2c_client 		*client;
+	int 				index;
+
+	int				psupply_fan_on;
+	int				cpu_fan_speed;
+	int				system_fan_speed;
+};
+
+#define NUM_CHILDREN	8
+
+struct bbc_i2c_bus {
+	struct bbc_i2c_bus		*next;
+	int				index;
+	spinlock_t			lock;
+	void				__iomem *i2c_bussel_reg;
+	void				__iomem *i2c_control_regs;
+	unsigned char			own, clock;
+
+	wait_queue_head_t		wq;
+	volatile int			waiting;
+
+	struct list_head		temps;
+	struct list_head		fans;
+
+	struct of_device		*op;
+	struct {
+		struct of_device	*device;
+		int			client_claimed;
+	} devs[NUM_CHILDREN];
+};
 
 /* Probing and attachment. */
-extern struct linux_ebus_child *bbc_i2c_getdev(int);
-extern struct bbc_i2c_client *bbc_i2c_attach(struct linux_ebus_child *);
+extern struct of_device *bbc_i2c_getdev(struct bbc_i2c_bus *, int);
+extern struct bbc_i2c_client *bbc_i2c_attach(struct bbc_i2c_bus *bp, struct of_device *);
 extern void bbc_i2c_detach(struct bbc_i2c_client *);
 
 /* Register read/write.  NOTE: Blocking! */
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
deleted file mode 100644
index bba21e053a1b..000000000000
--- a/drivers/sbus/char/bpp.c
+++ /dev/null
@@ -1,1055 +0,0 @@
-/*
- * drivers/sbus/char/bpp.c
- *
- * Copyright (c) 1995 Picture Elements
- *      Stephen Williams (steve@icarus.com)
- *      Gus Baldauf (gbaldauf@ix.netcom.com)
- *
- * Linux/SPARC port by Peter Zaitcev.
- * Integration into SPARC tree by Tom Dyas.
- */
-
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <linux/major.h>
-#include <linux/smp_lock.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-#if defined(__i386__)
-# include <asm/system.h>
-#endif
-
-#if defined(__sparc__)
-# include <linux/init.h>
-# include <linux/delay.h>         /* udelay() */
-
-# include <asm/oplib.h>           /* OpenProm Library */
-# include <asm/sbus.h>
-#endif
-
-#include <asm/bpp.h>
-
-#define BPP_PROBE_CODE 0x55
-#define BPP_DELAY 100
-
-static const unsigned  BPP_MAJOR = LP_MAJOR;
-static const char *bpp_dev_name = "bpp";
-
-/* When switching from compatibility to a mode where I can read, try
-   the following mode first. */
-
-/* const unsigned char DEFAULT_ECP = 0x10; */
-static const unsigned char DEFAULT_ECP = 0x30;
-static const unsigned char DEFAULT_NIBBLE = 0x00;
-
-/*
- * These are 1284 time constraints, in units of jiffies.
- */
-
-static const unsigned long TIME_PSetup = 1;
-static const unsigned long TIME_PResponse = 6;
-static const unsigned long TIME_IDLE_LIMIT = 2000;
-
-/*
- * One instance per supported subdevice...
- */
-# define BPP_NO 3
-
-enum IEEE_Mode { COMPATIBILITY, NIBBLE, ECP, ECP_RLE, EPP };
-
-struct inst {
-      unsigned present  : 1; /* True if the hardware exists */
-      unsigned enhanced : 1; /* True if the hardware in "enhanced" */
-      unsigned opened   : 1; /* True if the device is opened already */
-      unsigned run_flag : 1; /* True if waiting for a repeate byte */
-
-      unsigned char direction; /* 0 --> out, 0x20 --> IN */
-      unsigned char pp_state; /* State of host controlled pins. */
-      enum IEEE_Mode mode;
-
-      unsigned char run_length;
-      unsigned char repeat_byte;
-};
-
-static struct inst instances[BPP_NO];
-
-#if defined(__i386__)
-
-static const unsigned short base_addrs[BPP_NO] = { 0x278, 0x378, 0x3bc };
-
-/*
- * These are for data access.
- * Control lines accesses are hidden in set_bits() and get_bits().
- * The exception is the probe procedure, which is system-dependent.
- */
-#define bpp_outb_p(data, base)  outb_p((data), (base))
-#define bpp_inb(base)  inb(base)
-#define bpp_inb_p(base)  inb_p(base)
-
-/*
- * This method takes the pin values mask and sets the hardware pins to
- * the requested value: 1 == high voltage, 0 == low voltage. This
- * burries the annoying PC bit inversion and preserves the direction
- * flag.
- */
-static void set_pins(unsigned short pins, unsigned minor)
-{
-      unsigned char bits = instances[minor].direction;  /* == 0x20 */
-
-      if (! (pins & BPP_PP_nStrobe))   bits |= 1;
-      if (! (pins & BPP_PP_nAutoFd))   bits |= 2;
-      if (   pins & BPP_PP_nInit)      bits |= 4;
-      if (! (pins & BPP_PP_nSelectIn)) bits |= 8;
-
-      instances[minor].pp_state = bits;
-
-      outb_p(bits, base_addrs[minor]+2);
-}
-
-static unsigned short get_pins(unsigned minor)
-{
-      unsigned short bits = 0;
-
-      unsigned value = instances[minor].pp_state;
-      if (! (value & 0x01)) bits |= BPP_PP_nStrobe;
-      if (! (value & 0x02)) bits |= BPP_PP_nAutoFd;
-      if (value & 0x04)     bits |= BPP_PP_nInit;
-      if (! (value & 0x08)) bits |= BPP_PP_nSelectIn;
-
-      value = inb_p(base_addrs[minor]+1);
-      if (value & 0x08)     bits |= BPP_GP_nFault;
-      if (value & 0x10)     bits |= BPP_GP_Select;
-      if (value & 0x20)     bits |= BPP_GP_PError;
-      if (value & 0x40)     bits |= BPP_GP_nAck;
-      if (! (value & 0x80)) bits |= BPP_GP_Busy;
-
-      return bits;
-}
-
-#endif /* __i386__ */
-
-#if defined(__sparc__)
-
-/*
- * Register block
- */
-      /* DMA registers */
-#define BPP_CSR      0x00
-#define BPP_ADDR     0x04
-#define BPP_BCNT     0x08
-#define BPP_TST_CSR  0x0C
-      /* Parallel Port registers */
-#define BPP_HCR      0x10
-#define BPP_OCR      0x12
-#define BPP_DR       0x14
-#define BPP_TCR      0x15
-#define BPP_OR       0x16
-#define BPP_IR       0x17
-#define BPP_ICR      0x18
-#define BPP_SIZE     0x1A
-
-/* BPP_CSR.  Bits of type RW1 are cleared with writing '1'. */
-#define P_DEV_ID_MASK   0xf0000000      /* R   */
-#define P_DEV_ID_ZEBRA  0x40000000
-#define P_DEV_ID_L64854 0xa0000000      /*      == NCR 89C100+89C105. Pity. */
-#define P_NA_LOADED     0x08000000      /* R    NA wirtten but was not used */
-#define P_A_LOADED      0x04000000      /* R    */
-#define P_DMA_ON        0x02000000      /* R    DMA is not disabled */
-#define P_EN_NEXT       0x01000000      /* RW   */
-#define P_TCI_DIS       0x00800000      /* RW   TCI forbidden from interrupts */
-#define P_DIAG          0x00100000      /* RW   Disables draining and resetting
-                                                of P-FIFO on loading of P_ADDR*/
-#define P_BURST_SIZE    0x000c0000      /* RW   SBus burst size */
-#define P_BURST_8       0x00000000
-#define P_BURST_4       0x00040000
-#define P_BURST_1       0x00080000      /*      "No burst" write */
-#define P_TC            0x00004000      /* RW1  Term Count, can be cleared when
-                                           P_EN_NEXT=1 */
-#define P_EN_CNT        0x00002000      /* RW   */
-#define P_EN_DMA        0x00000200      /* RW   */
-#define P_WRITE         0x00000100      /* R    DMA dir, 1=to ram, 0=to port */
-#define P_RESET         0x00000080      /* RW   */
-#define P_SLAVE_ERR     0x00000040      /* RW1  Access size error */
-#define P_INVALIDATE    0x00000020      /* W    Drop P-FIFO */
-#define P_INT_EN        0x00000010      /* RW   OK to P_INT_PEND||P_ERR_PEND */
-#define P_DRAINING      0x0000000c      /* R    P-FIFO is draining to memory */
-#define P_ERR_PEND      0x00000002      /* R    */
-#define P_INT_PEND      0x00000001      /* R    */
-
-/* BPP_HCR. Time is in increments of SBus clock. */
-#define P_HCR_TEST      0x8000      /* Allows buried counters to be read */
-#define P_HCR_DSW       0x7f00      /* Data strobe width (in ticks) */
-#define P_HCR_DDS       0x007f      /* Data setup before strobe (in ticks) */
-
-/* BPP_OCR. */
-#define P_OCR_MEM_CLR   0x8000
-#define P_OCR_DATA_SRC  0x4000      /* )                  */
-#define P_OCR_DS_DSEL   0x2000      /* )  Bidirectional      */
-#define P_OCR_BUSY_DSEL 0x1000      /* )    selects            */
-#define P_OCR_ACK_DSEL  0x0800      /* )                  */
-#define P_OCR_EN_DIAG   0x0400
-#define P_OCR_BUSY_OP   0x0200      /* Busy operation */
-#define P_OCR_ACK_OP    0x0100      /* Ack operation */
-#define P_OCR_SRST      0x0080      /* Reset state machines. Not selfcleaning. */
-#define P_OCR_IDLE      0x0008      /* PP data transfer state machine is idle */
-#define P_OCR_V_ILCK    0x0002      /* Versatec faded. Zebra only. */
-#define P_OCR_EN_VER    0x0001      /* Enable Versatec (0 - enable). Zebra only. */
-
-/* BPP_TCR */
-#define P_TCR_DIR       0x08
-#define P_TCR_BUSY      0x04
-#define P_TCR_ACK       0x02
-#define P_TCR_DS        0x01        /* Strobe */
-
-/* BPP_OR */
-#define P_OR_V3         0x20        /* )                 */
-#define P_OR_V2         0x10        /* ) on Zebra only   */
-#define P_OR_V1         0x08        /* )                 */
-#define P_OR_INIT       0x04
-#define P_OR_AFXN       0x02        /* Auto Feed */
-#define P_OR_SLCT_IN    0x01
-
-/* BPP_IR */
-#define P_IR_PE         0x04
-#define P_IR_SLCT       0x02
-#define P_IR_ERR        0x01
-
-/* BPP_ICR */
-#define P_DS_IRQ        0x8000      /* RW1  */
-#define P_ACK_IRQ       0x4000      /* RW1  */
-#define P_BUSY_IRQ      0x2000      /* RW1  */
-#define P_PE_IRQ        0x1000      /* RW1  */
-#define P_SLCT_IRQ      0x0800      /* RW1  */
-#define P_ERR_IRQ       0x0400      /* RW1  */
-#define P_DS_IRQ_EN     0x0200      /* RW   Always on rising edge */
-#define P_ACK_IRQ_EN    0x0100      /* RW   Always on rising edge */
-#define P_BUSY_IRP      0x0080      /* RW   1= rising edge */
-#define P_BUSY_IRQ_EN   0x0040      /* RW   */
-#define P_PE_IRP        0x0020      /* RW   1= rising edge */
-#define P_PE_IRQ_EN     0x0010      /* RW   */
-#define P_SLCT_IRP      0x0008      /* RW   1= rising edge */
-#define P_SLCT_IRQ_EN   0x0004      /* RW   */
-#define P_ERR_IRP       0x0002      /* RW1  1= rising edge */
-#define P_ERR_IRQ_EN    0x0001      /* RW   */
-
-static void __iomem *base_addrs[BPP_NO];
-
-#define bpp_outb_p(data, base)	sbus_writeb(data, (base) + BPP_DR)
-#define bpp_inb_p(base)		sbus_readb((base) + BPP_DR)
-#define bpp_inb(base)		sbus_readb((base) + BPP_DR)
-
-static void set_pins(unsigned short pins, unsigned minor)
-{
-      void __iomem *base = base_addrs[minor];
-      unsigned char bits_tcr = 0, bits_or = 0;
-
-      if (instances[minor].direction & 0x20) bits_tcr |= P_TCR_DIR;
-      if (   pins & BPP_PP_nStrobe)          bits_tcr |= P_TCR_DS;
-
-      if (   pins & BPP_PP_nAutoFd)          bits_or |= P_OR_AFXN;
-      if (! (pins & BPP_PP_nInit))           bits_or |= P_OR_INIT;
-      if (! (pins & BPP_PP_nSelectIn))       bits_or |= P_OR_SLCT_IN;
-
-      sbus_writeb(bits_or, base + BPP_OR);
-      sbus_writeb(bits_tcr, base + BPP_TCR);
-}
-
-/*
- * i386 people read output pins from a software image.
- * We may get them back from hardware.
- * Again, inversion of pins must he buried here.
- */
-static unsigned short get_pins(unsigned minor)
-{
-      void __iomem *base = base_addrs[minor];
-      unsigned short bits = 0;
-      unsigned value_tcr = sbus_readb(base + BPP_TCR);
-      unsigned value_ir = sbus_readb(base + BPP_IR);
-      unsigned value_or = sbus_readb(base + BPP_OR);
-
-      if (value_tcr & P_TCR_DS)         bits |= BPP_PP_nStrobe;
-      if (value_or & P_OR_AFXN)         bits |= BPP_PP_nAutoFd;
-      if (! (value_or & P_OR_INIT))     bits |= BPP_PP_nInit;
-      if (! (value_or & P_OR_SLCT_IN))  bits |= BPP_PP_nSelectIn;
-
-      if (value_ir & P_IR_ERR)          bits |= BPP_GP_nFault;
-      if (! (value_ir & P_IR_SLCT))     bits |= BPP_GP_Select;
-      if (! (value_ir & P_IR_PE))       bits |= BPP_GP_PError;
-      if (! (value_tcr & P_TCR_ACK))    bits |= BPP_GP_nAck;
-      if (value_tcr & P_TCR_BUSY)       bits |= BPP_GP_Busy;
-
-      return bits;
-}
-
-#endif /* __sparc__ */
-
-static void snooze(unsigned long snooze_time, unsigned minor)
-{
-	schedule_timeout_uninterruptible(snooze_time + 1);
-}
-
-static int wait_for(unsigned short set, unsigned short clr,
-               unsigned long delay, unsigned minor)
-{
-      unsigned short pins = get_pins(minor);
-
-      unsigned long extime = 0;
-
-      /*
-       * Try a real fast scan for the first jiffy, in case the device
-       * responds real good. The first while loop guesses an expire
-       * time accounting for possible wraparound of jiffies.
-       */
-      while (time_after_eq(jiffies, extime)) extime = jiffies + 1;
-      while ( (time_before(jiffies, extime))
-              && (((pins & set) != set) || ((pins & clr) != 0)) ) {
-            pins = get_pins(minor);
-      }
-
-      delay -= 1;
-
-      /*
-       * If my delay expired or the pins are still not where I want
-       * them, then resort to using the timer and greatly reduce my
-       * sample rate. If the peripheral is going to be slow, this will
-       * give the CPU up to some more worthy process.
-       */
-      while ( delay && (((pins & set) != set) || ((pins & clr) != 0)) ) {
-
-            snooze(1, minor);
-            pins = get_pins(minor);
-            delay -= 1;
-      }
-
-      if (delay == 0) return -1;
-      else return pins;
-}
-
-/*
- * Return ZERO(0) If the negotiation succeeds, an errno otherwise. An
- * errno means something broke, and I do not yet know how to fix it.
- */
-static int negotiate(unsigned char mode, unsigned minor)
-{
-      int rc;
-      unsigned short pins = get_pins(minor);
-      if (pins & BPP_PP_nSelectIn) return -EIO;
-
-
-        /* Event 0: Write the mode to the data lines */
-      bpp_outb_p(mode, base_addrs[minor]);
-
-      snooze(TIME_PSetup, minor);
-
-        /* Event 1: Strobe the mode code into the peripheral */
-      set_pins(BPP_PP_nSelectIn|BPP_PP_nStrobe|BPP_PP_nInit, minor);
-
-        /* Wait for Event 2: Peripheral responds as a 1284 device. */
-      rc = wait_for(BPP_GP_PError|BPP_GP_Select|BPP_GP_nFault,
-                BPP_GP_nAck,
-                TIME_PResponse,
-                minor);
-
-      if (rc == -1) return -ETIMEDOUT;
-
-        /* Event 3: latch extensibility request */
-      set_pins(BPP_PP_nSelectIn|BPP_PP_nInit, minor);
-
-        /* ... quick nap while peripheral ponders the byte i'm sending...*/
-      snooze(1, minor);
-
-        /* Event 4: restore strobe, to ACK peripheral's response. */
-      set_pins(BPP_PP_nSelectIn|BPP_PP_nAutoFd|BPP_PP_nStrobe|BPP_PP_nInit, minor);
-
-        /* Wait for Event 6: Peripheral latches response bits */
-      rc = wait_for(BPP_GP_nAck, 0, TIME_PSetup+TIME_PResponse, minor);
-      if (rc == -1) return -EIO;
-
-        /* A 1284 device cannot refuse nibble mode */
-      if (mode == DEFAULT_NIBBLE) return 0;
-
-      if (pins & BPP_GP_Select) return 0;
-
-      return -EPROTONOSUPPORT;
-}
-
-static int terminate(unsigned minor)
-{
-      int rc;
-
-        /* Event 22: Request termination of 1284 mode */
-      set_pins(BPP_PP_nAutoFd|BPP_PP_nStrobe|BPP_PP_nInit, minor);
-
-        /* Wait for Events 23 and 24: ACK termination request. */
-      rc = wait_for(BPP_GP_Busy|BPP_GP_nFault,
-                BPP_GP_nAck,
-                TIME_PSetup+TIME_PResponse,
-                minor);
-
-      instances[minor].direction = 0;
-      instances[minor].mode = COMPATIBILITY;
-
-      if (rc == -1) {
-          return -EIO;
-      }
-
-        /* Event 25: Handshake by lowering nAutoFd */
-      set_pins(BPP_PP_nStrobe|BPP_PP_nInit, minor);
-
-        /* Event 26: Peripheral wiggles lines... */
-
-        /* Event 27: Peripheral sets nAck HIGH to ack handshake */
-      rc = wait_for(BPP_GP_nAck, 0, TIME_PResponse, minor);
-      if (rc == -1) {
-          set_pins(BPP_PP_nAutoFd|BPP_PP_nStrobe|BPP_PP_nInit, minor);
-          return -EIO;
-      }
-
-        /* Event 28: Finish phase by raising nAutoFd */
-      set_pins(BPP_PP_nAutoFd|BPP_PP_nStrobe|BPP_PP_nInit, minor);
-
-      return 0;
-}
-
-static DEFINE_SPINLOCK(bpp_open_lock);
-
-/*
- * Allow only one process to open the device at a time.
- */
-static int bpp_open(struct inode *inode, struct file *f)
-{
-      unsigned minor = iminor(inode);
-      int ret;
-
-      lock_kernel();
-      spin_lock(&bpp_open_lock);
-      ret = 0;
-      if (minor >= BPP_NO) {
-	      ret = -ENODEV;
-      } else {
-	      if (! instances[minor].present) {
-		      ret = -ENODEV;
-	      } else {
-		      if (instances[minor].opened) 
-			      ret = -EBUSY;
-		      else
-			      instances[minor].opened = 1;
-	      }
-      }
-      spin_unlock(&bpp_open_lock);
-      unlock_kernel();
-
-      return ret;
-}
-
-/*
- * When the process closes the device, this method is called to clean
- * up and reset the hardware. Always leave the device in compatibility
- * mode as this is a reasonable place to clean up from messes made by
- * ioctls, or other mayhem.
- */
-static int bpp_release(struct inode *inode, struct file *f)
-{
-      unsigned minor = iminor(inode);
-
-      spin_lock(&bpp_open_lock);
-      instances[minor].opened = 0;
-
-      if (instances[minor].mode != COMPATIBILITY)
-	      terminate(minor);
-
-      spin_unlock(&bpp_open_lock);
-
-      return 0;
-}
-
-static long read_nibble(unsigned minor, char __user *c, unsigned long cnt)
-{
-      unsigned long remaining = cnt;
-      long rc;
-
-      while (remaining > 0) {
-          unsigned char byte = 0;
-          int pins;
-
-          /* Event 7: request nibble */
-          set_pins(BPP_PP_nSelectIn|BPP_PP_nStrobe, minor);
-
-          /* Wait for event 9: Peripher strobes first nibble */
-          pins = wait_for(0, BPP_GP_nAck, TIME_IDLE_LIMIT, minor);
-          if (pins == -1) return -ETIMEDOUT;
-
-          /* Event 10: I handshake nibble */
-          set_pins(BPP_PP_nSelectIn|BPP_PP_nStrobe|BPP_PP_nAutoFd, minor);
-          if (pins & BPP_GP_nFault) byte |= 0x01;
-          if (pins & BPP_GP_Select) byte |= 0x02;
-          if (pins & BPP_GP_PError) byte |= 0x04;
-          if (pins & BPP_GP_Busy)   byte |= 0x08;
-
-          /* Wait for event 11: Peripheral handshakes nibble */
-          rc = wait_for(BPP_GP_nAck, 0, TIME_PResponse, minor);
-
-          /* Event 7: request nibble */
-          set_pins(BPP_PP_nSelectIn|BPP_PP_nStrobe, minor);
-
-          /* Wait for event 9: Peripher strobes first nibble */
-          pins = wait_for(0, BPP_GP_nAck, TIME_PResponse, minor);
-          if (rc == -1) return -ETIMEDOUT;
-
-          /* Event 10: I handshake nibble */
-          set_pins(BPP_PP_nSelectIn|BPP_PP_nStrobe|BPP_PP_nAutoFd, minor);
-          if (pins & BPP_GP_nFault) byte |= 0x10;
-          if (pins & BPP_GP_Select) byte |= 0x20;
-          if (pins & BPP_GP_PError) byte |= 0x40;
-          if (pins & BPP_GP_Busy)   byte |= 0x80;
-
-          if (put_user(byte, c))
-		  return -EFAULT;
-          c += 1;
-          remaining -= 1;
-
-          /* Wait for event 11: Peripheral handshakes nibble */
-          rc = wait_for(BPP_GP_nAck, 0, TIME_PResponse, minor);
-          if (rc == -1) return -EIO;
-      }
-
-      return cnt - remaining;
-}
-
-static long read_ecp(unsigned minor, char __user *c, unsigned long cnt)
-{
-      unsigned long remaining;
-      long rc;
-
-        /* Turn ECP mode from forward to reverse if needed. */
-      if (! instances[minor].direction) {
-          unsigned short pins = get_pins(minor);
-
-            /* Event 38: Turn the bus around */
-          instances[minor].direction = 0x20;
-          pins &= ~BPP_PP_nAutoFd;
-          set_pins(pins, minor);
-
-            /* Event 39: Set pins for reverse mode. */
-          snooze(TIME_PSetup, minor);
-          set_pins(BPP_PP_nStrobe|BPP_PP_nSelectIn, minor);
-
-            /* Wait for event 40: Peripheral ready to be strobed */
-          rc = wait_for(0, BPP_GP_PError, TIME_PResponse, minor);
-          if (rc == -1) return -ETIMEDOUT;
-      }
-
-      remaining = cnt;
-
-      while (remaining > 0) {
-
-            /* If there is a run length for a repeated byte, repeat */
-            /* that byte a few times. */
-          if (instances[minor].run_length && !instances[minor].run_flag) {
-
-              char buffer[128];
-              unsigned idx;
-              unsigned repeat = remaining < instances[minor].run_length
-                                     ? remaining
-                               : instances[minor].run_length;
-
-              for (idx = 0 ;  idx < repeat ;  idx += 1)
-                buffer[idx] = instances[minor].repeat_byte;
-
-              if (copy_to_user(c, buffer, repeat))
-		      return -EFAULT;
-              remaining -= repeat;
-              c += repeat;
-              instances[minor].run_length -= repeat;
-          }
-
-          if (remaining == 0) break;
-
-
-            /* Wait for Event 43: Data active on the bus. */
-          rc = wait_for(0, BPP_GP_nAck, TIME_IDLE_LIMIT, minor);
-          if (rc == -1) break;
-
-          if (rc & BPP_GP_Busy) {
-                /* OK, this is data. read it in. */
-              unsigned char byte = bpp_inb(base_addrs[minor]);
-              if (put_user(byte, c))
-		      return -EFAULT;
-              c += 1;
-              remaining -= 1;
-
-              if (instances[minor].run_flag) {
-                  instances[minor].repeat_byte = byte;
-                  instances[minor].run_flag = 0;
-              }
-
-          } else {
-              unsigned char byte = bpp_inb(base_addrs[minor]);
-              if (byte & 0x80) {
-                  printk("bpp%d: "
-                         "Ignoring ECP channel %u from device.\n",
-                         minor, byte & 0x7f);
-              } else {
-                  instances[minor].run_length = byte;
-                  instances[minor].run_flag = 1;
-              }
-          }
-
-            /* Event 44: I got it. */
-          set_pins(BPP_PP_nStrobe|BPP_PP_nAutoFd|BPP_PP_nSelectIn, minor);
-
-            /* Wait for event 45: peripheral handshake */
-          rc = wait_for(BPP_GP_nAck, 0, TIME_PResponse, minor);
-          if (rc == -1) return -ETIMEDOUT;
-
-             /* Event 46: Finish handshake */
-          set_pins(BPP_PP_nStrobe|BPP_PP_nSelectIn, minor);
-
-      }
-
-
-      return cnt - remaining;
-}
-
-static ssize_t bpp_read(struct file *f, char __user *c, size_t cnt, loff_t * ppos)
-{
-      long rc;
-      unsigned minor = iminor(f->f_path.dentry->d_inode);
-      if (minor >= BPP_NO) return -ENODEV;
-      if (!instances[minor].present) return -ENODEV;
-
-      switch (instances[minor].mode) {
-
-        default:
-          if (instances[minor].mode != COMPATIBILITY)
-            terminate(minor);
-
-          if (instances[minor].enhanced) {
-              /* For now, do all reads with ECP-RLE mode */
-              unsigned short pins;
-
-              rc = negotiate(DEFAULT_ECP, minor);
-              if (rc < 0) break;
-
-              instances[minor].mode = ECP_RLE;
-
-              /* Event 30: set nAutoFd low to setup for ECP mode */
-              pins = get_pins(minor);
-              pins &= ~BPP_PP_nAutoFd;
-              set_pins(pins, minor);
-
-              /* Wait for Event 31: peripheral ready */
-              rc = wait_for(BPP_GP_PError, 0, TIME_PResponse, minor);
-              if (rc == -1) return -ETIMEDOUT;
-
-              rc = read_ecp(minor, c, cnt);
-
-          } else {
-              rc = negotiate(DEFAULT_NIBBLE, minor);
-              if (rc < 0) break;
-
-              instances[minor].mode = NIBBLE;
-
-              rc = read_nibble(minor, c, cnt);
-          }
-          break;
-
-        case NIBBLE:
-          rc = read_nibble(minor, c, cnt);
-          break;
-
-        case ECP:
-        case ECP_RLE:
-          rc = read_ecp(minor, c, cnt);
-          break;
-
-      }
-
-
-      return rc;
-}
-
-/*
- * Compatibility mode handshaking is a matter of writing data,
- * strobing it, and waiting for the printer to stop being busy.
- */
-static long write_compat(unsigned minor, const char __user *c, unsigned long cnt)
-{
-      long rc;
-      unsigned short pins = get_pins(minor);
-
-      unsigned long remaining = cnt;
-
-
-      while (remaining > 0) {
-            unsigned char byte;
-
-            if (get_user(byte, c))
-		    return -EFAULT;
-            c += 1;
-
-            rc = wait_for(BPP_GP_nAck, BPP_GP_Busy, TIME_IDLE_LIMIT, minor);
-            if (rc == -1) return -ETIMEDOUT;
-
-            bpp_outb_p(byte, base_addrs[minor]);
-            remaining -= 1;
-          /* snooze(1, minor); */
-
-          pins &= ~BPP_PP_nStrobe;
-          set_pins(pins, minor);
-
-          rc = wait_for(BPP_GP_Busy, 0, TIME_PResponse, minor);
-
-          pins |= BPP_PP_nStrobe;
-          set_pins(pins, minor);
-      }
-
-      return cnt - remaining;
-}
-
-/*
- * Write data using ECP mode. Watch out that the port may be set up
- * for reading. If so, turn the port around.
- */
-static long write_ecp(unsigned minor, const char __user *c, unsigned long cnt)
-{
-      unsigned short pins = get_pins(minor);
-      unsigned long remaining = cnt;
-
-      if (instances[minor].direction) {
-          int rc;
-
-            /* Event 47 Request bus be turned around */
-          pins |= BPP_PP_nInit;
-          set_pins(pins, minor);
-
-            /* Wait for Event 49: Peripheral relinquished bus */
-          rc = wait_for(BPP_GP_PError, 0, TIME_PResponse, minor);
-
-          pins |= BPP_PP_nAutoFd;
-          instances[minor].direction = 0;
-          set_pins(pins, minor);
-      }
-
-      while (remaining > 0) {
-          unsigned char byte;
-          int rc;
-
-          if (get_user(byte, c))
-		  return -EFAULT;
-
-          rc = wait_for(0, BPP_GP_Busy, TIME_PResponse, minor);
-          if (rc == -1) return -ETIMEDOUT;
-
-          c += 1;
-
-          bpp_outb_p(byte, base_addrs[minor]);
-
-          pins &= ~BPP_PP_nStrobe;
-          set_pins(pins, minor);
-
-          pins |= BPP_PP_nStrobe;
-          rc = wait_for(BPP_GP_Busy, 0, TIME_PResponse, minor);
-          if (rc == -1) return -EIO;
-
-          set_pins(pins, minor);
-      }
-
-      return cnt - remaining;
-}
-
-/*
- * Write to the peripheral. Be sensitive of the current mode. If I'm
- * in a mode that can be turned around (ECP) then just do
- * that. Otherwise, terminate and do my writing in compat mode. This
- * is the safest course as any device can handle it.
- */
-static ssize_t bpp_write(struct file *f, const char __user *c, size_t cnt, loff_t * ppos)
-{
-      long errno = 0;
-      unsigned minor = iminor(f->f_path.dentry->d_inode);
-      if (minor >= BPP_NO) return -ENODEV;
-      if (!instances[minor].present) return -ENODEV;
-
-      switch (instances[minor].mode) {
-
-        case ECP:
-        case ECP_RLE:
-          errno = write_ecp(minor, c, cnt);
-          break;
-        case COMPATIBILITY:
-          errno = write_compat(minor, c, cnt);
-          break;
-        default:
-          terminate(minor);
-          errno = write_compat(minor, c, cnt);
-      }
-
-      return errno;
-}
-
-static int bpp_ioctl(struct inode *inode, struct file *f, unsigned int cmd,
-		 unsigned long arg)
-{
-      int errno = 0;
-
-      unsigned minor = iminor(inode);
-      if (minor >= BPP_NO) return -ENODEV;
-      if (!instances[minor].present) return -ENODEV;
-
-
-      switch (cmd) {
-
-        case BPP_PUT_PINS:
-          set_pins(arg, minor);
-          break;
-
-        case BPP_GET_PINS:
-          errno = get_pins(minor);
-          break;
-
-        case BPP_PUT_DATA:
-          bpp_outb_p(arg, base_addrs[minor]);
-          break;
-
-        case BPP_GET_DATA:
-          errno = bpp_inb_p(base_addrs[minor]);
-          break;
-
-        case BPP_SET_INPUT:
-          if (arg)
-            if (instances[minor].enhanced) {
-                unsigned short bits = get_pins(minor);
-                instances[minor].direction = 0x20;
-                set_pins(bits, minor);
-            } else {
-                errno = -ENOTTY;
-            }
-          else {
-              unsigned short bits = get_pins(minor);
-              instances[minor].direction = 0x00;
-              set_pins(bits, minor);
-          }
-          break;
-
-        default:
-            errno = -EINVAL;
-      }
-
-      return errno;
-}
-
-static const struct file_operations bpp_fops = {
-	.owner =	THIS_MODULE,
-	.read =		bpp_read,
-	.write =	bpp_write,
-	.ioctl =	bpp_ioctl,
-	.open =		bpp_open,
-	.release =	bpp_release,
-};
-
-#if defined(__i386__)
-
-#define collectLptPorts()  {}
-
-static void probeLptPort(unsigned idx)
-{
-      unsigned int testvalue;
-      const unsigned short lpAddr = base_addrs[idx];
-
-      instances[idx].present = 0;
-      instances[idx].enhanced = 0;
-      instances[idx].direction = 0;
-      instances[idx].mode = COMPATIBILITY;
-      instances[idx].run_length = 0;
-      instances[idx].run_flag = 0;
-      if (!request_region(lpAddr,3, bpp_dev_name)) return;
-
-      /*
-       * First, make sure the instance exists. Do this by writing to
-       * the data latch and reading the value back. If the port *is*
-       * present, test to see if it supports extended-mode
-       * operation. This will be required for IEEE1284 reverse
-       * transfers.
-       */
-
-      outb_p(BPP_PROBE_CODE, lpAddr);
-      for (testvalue=0; testvalue<BPP_DELAY; testvalue++)
-            ;
-      testvalue = inb_p(lpAddr);
-      if (testvalue == BPP_PROBE_CODE) {
-            unsigned save;
-            instances[idx].present = 1;
-
-            save = inb_p(lpAddr+2);
-            for (testvalue=0; testvalue<BPP_DELAY; testvalue++)
-                  ;
-            outb_p(save|0x20, lpAddr+2);
-            for (testvalue=0; testvalue<BPP_DELAY; testvalue++)
-                  ;
-            outb_p(~BPP_PROBE_CODE, lpAddr);
-            for (testvalue=0; testvalue<BPP_DELAY; testvalue++)
-                  ;
-            testvalue = inb_p(lpAddr);
-            if ((testvalue&0xff) == (0xff&~BPP_PROBE_CODE))
-                  instances[idx].enhanced = 0;
-            else
-                  instances[idx].enhanced = 1;
-            outb_p(save, lpAddr+2);
-      }
-      else {
-            release_region(lpAddr,3);
-      }
-      /*
-       * Leave the port in compat idle mode.
-       */
-      set_pins(BPP_PP_nAutoFd|BPP_PP_nStrobe|BPP_PP_nInit, idx);
-
-      printk("bpp%d: Port at 0x%03x: Enhanced mode %s\n", idx, base_addrs[idx],
-            instances[idx].enhanced? "SUPPORTED" : "UNAVAILABLE");
-}
-
-static inline void freeLptPort(int idx)
-{
-      release_region(base_addrs[idx], 3);
-}
-
-#endif
-
-#if defined(__sparc__)
-
-static void __iomem *map_bpp(struct sbus_dev *dev, int idx)
-{
-      return sbus_ioremap(&dev->resource[0], 0, BPP_SIZE, "bpp");
-}
-
-static int collectLptPorts(void)
-{
-	struct sbus_bus *bus;
-	struct sbus_dev *dev;
-	int count;
-
-	count = 0;
-	for_all_sbusdev(dev, bus) {
-		if (strcmp(dev->prom_name, "SUNW,bpp") == 0) {
-			if (count >= BPP_NO) {
-				printk(KERN_NOTICE
-				       "bpp: More than %d bpp ports,"
-				       " rest is ignored\n", BPP_NO);
-				return count;
-			}
-			base_addrs[count] = map_bpp(dev, count);
-			count++;
-		}
-	}
-	return count;
-}
-
-static void probeLptPort(unsigned idx)
-{
-      void __iomem *rp = base_addrs[idx];
-      __u32 csr;
-      char *brand;
-
-      instances[idx].present = 0;
-      instances[idx].enhanced = 0;
-      instances[idx].direction = 0;
-      instances[idx].mode = COMPATIBILITY;
-      instances[idx].run_length = 0;
-      instances[idx].run_flag = 0;
-
-      if (!rp) return;
-
-      instances[idx].present = 1;
-      instances[idx].enhanced = 1;   /* Sure */
-
-      csr = sbus_readl(rp + BPP_CSR);
-      if ((csr & P_DRAINING) != 0 && (csr & P_ERR_PEND) == 0) {
-            udelay(20);
-            csr = sbus_readl(rp + BPP_CSR);
-            if ((csr & P_DRAINING) != 0 && (csr & P_ERR_PEND) == 0) {
-                  printk("bpp%d: DRAINING still active (0x%08x)\n", idx, csr);
-            }
-      }
-      printk("bpp%d: reset with 0x%08x ..", idx, csr);
-      sbus_writel((csr | P_RESET) & ~P_INT_EN, rp + BPP_CSR);
-      udelay(500);
-      sbus_writel(sbus_readl(rp + BPP_CSR) & ~P_RESET, rp + BPP_CSR);
-      csr = sbus_readl(rp + BPP_CSR);
-      printk(" done with csr=0x%08x ocr=0x%04x\n",
-         csr, sbus_readw(rp + BPP_OCR));
-
-      switch (csr & P_DEV_ID_MASK) {
-      case P_DEV_ID_ZEBRA:
-            brand = "Zebra";
-            break;
-      case P_DEV_ID_L64854:
-            brand = "DMA2";
-            break;
-      default:
-            brand = "Unknown";
-      }
-      printk("bpp%d: %s at %p\n", idx, brand, rp);
-
-      /*
-       * Leave the port in compat idle mode.
-       */
-      set_pins(BPP_PP_nAutoFd|BPP_PP_nStrobe|BPP_PP_nInit, idx);
-
-      return;
-}
-
-static inline void freeLptPort(int idx)
-{
-      sbus_iounmap(base_addrs[idx], BPP_SIZE);
-}
-
-#endif
-
-static int __init bpp_init(void)
-{
-	int rc;
-	unsigned idx;
-
-	rc = collectLptPorts();
-	if (rc == 0)
-		return -ENODEV;
-
-	rc = register_chrdev(BPP_MAJOR, bpp_dev_name, &bpp_fops);
-	if (rc < 0)
-		return rc;
-
-	for (idx = 0; idx < BPP_NO; idx++) {
-		instances[idx].opened = 0;
-		probeLptPort(idx);
-	}
-
-	return 0;
-}
-
-static void __exit bpp_cleanup(void)
-{
-	unsigned idx;
-
-	unregister_chrdev(BPP_MAJOR, bpp_dev_name);
-
-	for (idx = 0;  idx < BPP_NO; idx++) {
-		if (instances[idx].present)
-			freeLptPort(idx);
-	}
-}
-
-module_init(bpp_init);
-module_exit(bpp_cleanup);
-
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c
deleted file mode 100644
index 23abfdfb44f1..000000000000
--- a/drivers/sbus/char/cpwatchdog.c
+++ /dev/null
@@ -1,858 +0,0 @@
-/* cpwatchdog.c - driver implementation for hardware watchdog
- * timers found on Sun Microsystems CP1400 and CP1500 boards.
- *
- * This device supports both the generic Linux watchdog 
- * interface and Solaris-compatible ioctls as best it is
- * able.
- *
- * NOTE: 	CP1400 systems appear to have a defective intr_mask
- * 			register on the PLD, preventing the disabling of
- * 			timer interrupts.  We use a timer to periodically 
- * 			reset 'stopped' watchdogs on affected platforms.
- *
- * Copyright (c) 2000 Eric Brower (ebrower@usa.net)
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/errno.h>
-#include <linux/major.h>
-#include <linux/init.h>
-#include <linux/miscdevice.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/timer.h>
-#include <linux/smp_lock.h>
-#include <linux/io.h>
-#include <asm/irq.h>
-#include <asm/ebus.h>
-#include <asm/oplib.h>
-#include <asm/uaccess.h>
-
-#include <asm/watchdog.h>
-
-#define WD_OBPNAME	"watchdog"
-#define WD_BADMODEL "SUNW,501-5336"
-#define WD_BTIMEOUT	(jiffies + (HZ * 1000))
-#define WD_BLIMIT	0xFFFF
-
-#define WD0_DEVNAME "watchdog0"
-#define WD1_DEVNAME "watchdog1"
-#define WD2_DEVNAME "watchdog2"
-
-#define WD0_MINOR	212
-#define WD1_MINOR	213	
-#define WD2_MINOR	214	
-
-
-/* Internal driver definitions
- */
-#define WD0_ID			0		/* Watchdog0						*/
-#define WD1_ID			1		/* Watchdog1						*/
-#define WD2_ID			2		/* Watchdog2						*/
-#define WD_NUMDEVS		3		/* Device contains 3 timers			*/
-
-#define WD_INTR_OFF		0		/* Interrupt disable value			*/
-#define WD_INTR_ON		1		/* Interrupt enable value			*/
-
-#define WD_STAT_INIT	0x01	/* Watchdog timer is initialized	*/
-#define WD_STAT_BSTOP	0x02	/* Watchdog timer is brokenstopped	*/
-#define WD_STAT_SVCD	0x04	/* Watchdog interrupt occurred		*/
-
-/* Register value definitions
- */
-#define WD0_INTR_MASK	0x01	/* Watchdog device interrupt masks	*/
-#define WD1_INTR_MASK	0x02
-#define WD2_INTR_MASK	0x04
-
-#define WD_S_RUNNING	0x01	/* Watchdog device status running	*/
-#define WD_S_EXPIRED	0x02	/* Watchdog device status expired	*/
-
-/* Sun uses Altera PLD EPF8820ATC144-4 
- * providing three hardware watchdogs:
- *
- * 	1) RIC - sends an interrupt when triggered
- * 	2) XIR - asserts XIR_B_RESET when triggered, resets CPU
- * 	3) POR - asserts POR_B_RESET when triggered, resets CPU, backplane, board
- *
- *** Timer register block definition (struct wd_timer_regblk)
- *
- * dcntr and limit registers (halfword access):      
- * -------------------
- * | 15 | ...| 1 | 0 |
- * -------------------
- * |-  counter val  -|
- * -------------------
- * dcntr - 	Current 16-bit downcounter value.
- * 			When downcounter reaches '0' watchdog expires.
- * 			Reading this register resets downcounter with 'limit' value.
- * limit - 	16-bit countdown value in 1/10th second increments.
- * 			Writing this register begins countdown with input value.
- * 			Reading from this register does not affect counter.
- * NOTES:	After watchdog reset, dcntr and limit contain '1'
- *
- * status register (byte access):
- * ---------------------------
- * | 7 | ... | 2 |  1  |  0  |
- * --------------+------------
- * |-   UNUSED  -| EXP | RUN |
- * ---------------------------
- * status-	Bit 0 - Watchdog is running
- * 			Bit 1 - Watchdog has expired
- *
- *** PLD register block definition (struct wd_pld_regblk)
- *
- * intr_mask register (byte access):
- * ---------------------------------
- * | 7 | ... | 3 |  2  |  1  |  0  |
- * +-------------+------------------
- * |-   UNUSED  -| WD3 | WD2 | WD1 |
- * ---------------------------------
- * WD3 -  1 == Interrupt disabled for watchdog 3
- * WD2 -  1 == Interrupt disabled for watchdog 2
- * WD1 -  1 == Interrupt disabled for watchdog 1
- *
- * pld_status register (byte access):
- * UNKNOWN, MAGICAL MYSTERY REGISTER
- *
- */
-#define WD_TIMER_REGSZ	16
-#define WD0_OFF		0
-#define WD1_OFF		(WD_TIMER_REGSZ * 1)
-#define WD2_OFF		(WD_TIMER_REGSZ * 2)
-#define PLD_OFF		(WD_TIMER_REGSZ * 3)
-
-#define WD_DCNTR	0x00
-#define WD_LIMIT	0x04
-#define WD_STATUS	0x08
-
-#define PLD_IMASK	(PLD_OFF + 0x00)
-#define PLD_STATUS	(PLD_OFF + 0x04)
-
-/* Individual timer structure 
- */
-struct wd_timer {
-	__u16			timeout;
-	__u8			intr_mask;
-	unsigned char		runstatus;
-	void __iomem		*regs;
-};
-
-/* Device structure
- */
-struct wd_device {
-	int				irq;
-	spinlock_t		lock;
-	unsigned char	isbaddoggie;	/* defective PLD */
-	unsigned char	opt_enable;
-	unsigned char	opt_reboot;
-	unsigned short	opt_timeout;
-	unsigned char	initialized;
-	struct wd_timer	watchdog[WD_NUMDEVS];
-	void __iomem	*regs;
-};
-
-static struct wd_device wd_dev = { 
-		0, __SPIN_LOCK_UNLOCKED(wd_dev.lock), 0, 0, 0, 0,
-};
-
-static struct timer_list wd_timer;
-
-static int wd0_timeout = 0;
-static int wd1_timeout = 0;
-static int wd2_timeout = 0;
-
-#ifdef MODULE
-module_param	(wd0_timeout, int, 0);
-MODULE_PARM_DESC(wd0_timeout, "Default watchdog0 timeout in 1/10secs");
-module_param 	(wd1_timeout, int, 0);
-MODULE_PARM_DESC(wd1_timeout, "Default watchdog1 timeout in 1/10secs");
-module_param 	(wd2_timeout, int, 0);
-MODULE_PARM_DESC(wd2_timeout, "Default watchdog2 timeout in 1/10secs");
-
-MODULE_AUTHOR
-	("Eric Brower <ebrower@usa.net>");
-MODULE_DESCRIPTION
-	("Hardware watchdog driver for Sun Microsystems CP1400/1500");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE
-	("watchdog");
-#endif /* ifdef MODULE */
-
-/* Forward declarations of internal methods
- */
-#ifdef WD_DEBUG
-static void wd_dumpregs(void);
-#endif
-static irqreturn_t wd_interrupt(int irq, void *dev_id);
-static void wd_toggleintr(struct wd_timer* pTimer, int enable);
-static void wd_pingtimer(struct wd_timer* pTimer);
-static void wd_starttimer(struct wd_timer* pTimer);
-static void wd_resetbrokentimer(struct wd_timer* pTimer);
-static void wd_stoptimer(struct wd_timer* pTimer);
-static void wd_brokentimer(unsigned long data);
-static int  wd_getstatus(struct wd_timer* pTimer);
-
-/* PLD expects words to be written in LSB format,
- * so we must flip all words prior to writing them to regs
- */
-static inline unsigned short flip_word(unsigned short word)
-{
-	return ((word & 0xff) << 8) | ((word >> 8) & 0xff);
-}
-
-#define wd_writew(val, addr) 	(writew(flip_word(val), addr))
-#define wd_readw(addr) 			(flip_word(readw(addr)))
-#define wd_writeb(val, addr) 	(writeb(val, addr))
-#define wd_readb(addr) 			(readb(addr))
-
-
-/* CP1400s seem to have broken PLD implementations--
- * the interrupt_mask register cannot be written, so
- * no timer interrupts can be masked within the PLD.
- */
-static inline int wd_isbroken(void)
-{
-	/* we could test this by read/write/read/restore
-	 * on the interrupt mask register only if OBP
-	 * 'watchdog-enable?' == FALSE, but it seems 
-	 * ubiquitous on CP1400s
-	 */
-	char val[32];
-	prom_getproperty(prom_root_node, "model", val, sizeof(val));
-	return((!strcmp(val, WD_BADMODEL)) ? 1 : 0);
-}
-		
-/* Retrieve watchdog-enable? option from OBP
- * Returns 0 if false, 1 if true
- */
-static inline int wd_opt_enable(void)
-{
-	int opt_node;
-
-	opt_node = prom_getchild(prom_root_node);
-	opt_node = prom_searchsiblings(opt_node, "options");
-	return((-1 == prom_getint(opt_node, "watchdog-enable?")) ? 0 : 1);
-}
-
-/* Retrieve watchdog-reboot? option from OBP
- * Returns 0 if false, 1 if true
- */
-static inline int wd_opt_reboot(void)
-{
-	int opt_node;
-
-	opt_node = prom_getchild(prom_root_node);
-	opt_node = prom_searchsiblings(opt_node, "options");
-	return((-1 == prom_getint(opt_node, "watchdog-reboot?")) ? 0 : 1);
-}
-
-/* Retrieve watchdog-timeout option from OBP
- * Returns OBP value, or 0 if not located
- */
-static inline int wd_opt_timeout(void)
-{
-	int opt_node;
-	char value[32];
-	char *p = value;
-
-	opt_node = prom_getchild(prom_root_node);
-	opt_node = prom_searchsiblings(opt_node, "options");
-	opt_node = prom_getproperty(opt_node, 
-								"watchdog-timeout", 
-								value, 
-								sizeof(value));
-	if(-1 != opt_node) {
-		/* atoi implementation */
-		for(opt_node = 0; /* nop */; p++) {
-			if(*p >= '0' && *p <= '9') {
-				opt_node = (10*opt_node)+(*p-'0');
-			}
-			else {
-				break;
-			}
-		}
-	}
-	return((-1 == opt_node) ? (0) : (opt_node)); 
-}
-
-static int wd_open(struct inode *inode, struct file *f)
-{
-	lock_kernel();
-	switch(iminor(inode))
-	{
-		case WD0_MINOR:
-			f->private_data = &wd_dev.watchdog[WD0_ID];
-			break;
-		case WD1_MINOR:
-			f->private_data = &wd_dev.watchdog[WD1_ID];
-			break;
-		case WD2_MINOR:
-			f->private_data = &wd_dev.watchdog[WD2_ID];
-			break;
-		default:
-			unlock_kernel();
-			return(-ENODEV);
-	}
-
-	/* Register IRQ on first open of device */
-	if(0 == wd_dev.initialized)
-	{	
-		if (request_irq(wd_dev.irq, 
-						&wd_interrupt, 
-						IRQF_SHARED,
-						WD_OBPNAME,
-						(void *)wd_dev.regs)) {
-			printk("%s: Cannot register IRQ %d\n", 
-				WD_OBPNAME, wd_dev.irq);
-			unlock_kernel();
-			return(-EBUSY);
-		}
-		wd_dev.initialized = 1;
-	}
-
-	unlock_kernel();
-	return(nonseekable_open(inode, f));
-}
-
-static int wd_release(struct inode *inode, struct file *file)
-{
-	return 0;
-}
-
-static int wd_ioctl(struct inode *inode, struct file *file, 
-		     unsigned int cmd, unsigned long arg)
-{
-	int 	setopt 				= 0;
-	struct 	wd_timer* pTimer 	= (struct wd_timer*)file->private_data;
-	void __user *argp = (void __user *)arg;
-	struct 	watchdog_info info 	= {
-		0,
-		0,
-		"Altera EPF8820ATC144-4"
-	};
-
-	if(NULL == pTimer) {
-		return(-EINVAL);
-	}
-
-	switch(cmd)
-	{
-		/* Generic Linux IOCTLs */
-		case WDIOC_GETSUPPORT:
-			if(copy_to_user(argp, &info, sizeof(struct watchdog_info))) {
-				return(-EFAULT);
-			}
-			break;
-		case WDIOC_GETSTATUS:
-		case WDIOC_GETBOOTSTATUS:
-			if (put_user(0, (int __user *)argp))
-				return -EFAULT;
-			break;
-		case WDIOC_KEEPALIVE:
-			wd_pingtimer(pTimer);
-			break;
-		case WDIOC_SETOPTIONS:
-			if(copy_from_user(&setopt, argp, sizeof(unsigned int))) {
-				return -EFAULT;
-			}
-			if(setopt & WDIOS_DISABLECARD) {
-				if(wd_dev.opt_enable) {
-					printk(
-						"%s: cannot disable watchdog in ENABLED mode\n",
-						WD_OBPNAME);
-					return(-EINVAL);
-				}
-				wd_stoptimer(pTimer);
-			}
-			else if(setopt & WDIOS_ENABLECARD) {
-				wd_starttimer(pTimer);
-			}
-			else {
-				return(-EINVAL);
-			}	
-			break;
-		/* Solaris-compatible IOCTLs */
-		case WIOCGSTAT:
-			setopt = wd_getstatus(pTimer);
-			if(copy_to_user(argp, &setopt, sizeof(unsigned int))) {
-				return(-EFAULT);
-			}
-			break;
-		case WIOCSTART:
-			wd_starttimer(pTimer);
-			break;
-		case WIOCSTOP:
-			if(wd_dev.opt_enable) {
-				printk("%s: cannot disable watchdog in ENABLED mode\n",
-					WD_OBPNAME);
-				return(-EINVAL);
-			}
-			wd_stoptimer(pTimer);
-			break;
-		default:
-			return(-EINVAL);
-	}
-	return(0);
-}
-
-static long wd_compat_ioctl(struct file *file, unsigned int cmd,
-		unsigned long arg)
-{
-	int rval = -ENOIOCTLCMD;
-
-	switch (cmd) {
-	/* solaris ioctls are specific to this driver */
-	case WIOCSTART:
-	case WIOCSTOP:
-	case WIOCGSTAT:
-		lock_kernel();
-		rval = wd_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
-		unlock_kernel();
-		break;
-	/* everything else is handled by the generic compat layer */
-	default:
-		break;
-	}
-
-	return rval;
-}
-
-static ssize_t wd_write(struct file 	*file, 
-			const char	__user *buf, 
-			size_t 		count, 
-			loff_t 		*ppos)
-{
-	struct wd_timer* pTimer = (struct wd_timer*)file->private_data;
-
-	if(NULL == pTimer) {
-		return(-EINVAL);
-	}
-
-	if (count) {
-		wd_pingtimer(pTimer);
-		return 1;
-	}
-	return 0;
-}
-
-static ssize_t wd_read(struct file * file, char __user *buffer,
-		        size_t count, loff_t *ppos)
-{
-#ifdef WD_DEBUG
-	wd_dumpregs();
-	return(0);
-#else
-	return(-EINVAL);
-#endif /* ifdef WD_DEBUG */
-}
-
-static irqreturn_t wd_interrupt(int irq, void *dev_id)
-{
-	/* Only WD0 will interrupt-- others are NMI and we won't
-	 * see them here....
-	 */
-	spin_lock_irq(&wd_dev.lock);
-	if((unsigned long)wd_dev.regs == (unsigned long)dev_id)
-	{
-		wd_stoptimer(&wd_dev.watchdog[WD0_ID]);
-		wd_dev.watchdog[WD0_ID].runstatus |=  WD_STAT_SVCD;
-	}
-	spin_unlock_irq(&wd_dev.lock);
-	return IRQ_HANDLED;
-}
-
-static const struct file_operations wd_fops = {
-	.owner =	THIS_MODULE,
-	.ioctl =	wd_ioctl,
-	.compat_ioctl =	wd_compat_ioctl,
-	.open =		wd_open,
-	.write =	wd_write,
-	.read =		wd_read,
-	.release =	wd_release,
-};
-
-static struct miscdevice wd0_miscdev = { WD0_MINOR, WD0_DEVNAME, &wd_fops };
-static struct miscdevice wd1_miscdev = { WD1_MINOR, WD1_DEVNAME, &wd_fops };
-static struct miscdevice wd2_miscdev = { WD2_MINOR, WD2_DEVNAME, &wd_fops };
-
-#ifdef WD_DEBUG
-static void wd_dumpregs(void)
-{
-	/* Reading from downcounters initiates watchdog countdown--
-	 * Example is included below for illustration purposes.
-	 */
-	int i;
-	printk("%s: dumping register values\n", WD_OBPNAME);
-	for(i = WD0_ID; i < WD_NUMDEVS; ++i) {
-			/* printk("\t%s%i: dcntr  at 0x%lx: 0x%x\n", 
-			 * 	WD_OBPNAME,
-		 	 *	i,
-			 *	(unsigned long)(&wd_dev.watchdog[i].regs->dcntr), 
-			 *	readw(&wd_dev.watchdog[i].regs->dcntr));
-			 */
-			printk("\t%s%i: limit  at 0x%lx: 0x%x\n", 
-				WD_OBPNAME,
-				i,
-				(unsigned long)(&wd_dev.watchdog[i].regs->limit), 
-				readw(&wd_dev.watchdog[i].regs->limit));
-			printk("\t%s%i: status at 0x%lx: 0x%x\n", 
-				WD_OBPNAME,
-				i,
-				(unsigned long)(&wd_dev.watchdog[i].regs->status), 
-				readb(&wd_dev.watchdog[i].regs->status));
-			printk("\t%s%i: driver status: 0x%x\n",
-				WD_OBPNAME,
-				i,
-				wd_getstatus(&wd_dev.watchdog[i]));
-	}
-	printk("\tintr_mask  at %p: 0x%x\n", 
-		wd_dev.regs + PLD_IMASK,
-		readb(wd_dev.regs + PLD_IMASK));
-	printk("\tpld_status at %p: 0x%x\n", 
-		wd_dev.regs + PLD_STATUS, 
-		readb(wd_dev.regs + PLD_STATUS));
-}
-#endif
-
-/* Enable or disable watchdog interrupts
- * Because of the CP1400 defect this should only be
- * called during initialzation or by wd_[start|stop]timer()
- *
- * pTimer 	- pointer to timer device, or NULL to indicate all timers 
- * enable	- non-zero to enable interrupts, zero to disable
- */
-static void wd_toggleintr(struct wd_timer* pTimer, int enable)
-{
-	unsigned char curregs = wd_readb(wd_dev.regs + PLD_IMASK);
-	unsigned char setregs = 
-		(NULL == pTimer) ? 
-			(WD0_INTR_MASK | WD1_INTR_MASK | WD2_INTR_MASK) : 
-			(pTimer->intr_mask);
-
-	(WD_INTR_ON == enable) ?
-		(curregs &= ~setregs):
-		(curregs |=  setregs);
-
-	wd_writeb(curregs, wd_dev.regs + PLD_IMASK);
-	return;
-}
-
-/* Reset countdown timer with 'limit' value and continue countdown.
- * This will not start a stopped timer.
- *
- * pTimer	- pointer to timer device
- */
-static void wd_pingtimer(struct wd_timer* pTimer)
-{
-	if (wd_readb(pTimer->regs + WD_STATUS) & WD_S_RUNNING) {
-		wd_readw(pTimer->regs + WD_DCNTR);
-	}
-}
-
-/* Stop a running watchdog timer-- the timer actually keeps
- * running, but the interrupt is masked so that no action is
- * taken upon expiration.
- *
- * pTimer	- pointer to timer device
- */
-static void wd_stoptimer(struct wd_timer* pTimer)
-{
-	if(wd_readb(pTimer->regs + WD_STATUS) & WD_S_RUNNING) {
-		wd_toggleintr(pTimer, WD_INTR_OFF);
-
-		if(wd_dev.isbaddoggie) {
-			pTimer->runstatus |= WD_STAT_BSTOP;
-			wd_brokentimer((unsigned long)&wd_dev);
-		}
-	}
-}
-
-/* Start a watchdog timer with the specified limit value
- * If the watchdog is running, it will be restarted with
- * the provided limit value.
- *
- * This function will enable interrupts on the specified
- * watchdog.
- *
- * pTimer	- pointer to timer device
- * limit	- limit (countdown) value in 1/10th seconds
- */
-static void wd_starttimer(struct wd_timer* pTimer)
-{
-	if(wd_dev.isbaddoggie) {
-		pTimer->runstatus &= ~WD_STAT_BSTOP;
-	}
-	pTimer->runstatus &= ~WD_STAT_SVCD;
-
-	wd_writew(pTimer->timeout, pTimer->regs + WD_LIMIT);
-	wd_toggleintr(pTimer, WD_INTR_ON);
-}
-
-/* Restarts timer with maximum limit value and
- * does not unset 'brokenstop' value.
- */
-static void wd_resetbrokentimer(struct wd_timer* pTimer)
-{
-	wd_toggleintr(pTimer, WD_INTR_ON);
-	wd_writew(WD_BLIMIT, pTimer->regs + WD_LIMIT);
-}
-
-/* Timer device initialization helper.
- * Returns 0 on success, other on failure
- */
-static int wd_inittimer(int whichdog)
-{
-	struct miscdevice 				*whichmisc;
-	void __iomem *whichregs;
-	char 							whichident[8];
-	int								whichmask;
-	__u16							whichlimit;
-
-	switch(whichdog)
-	{
-		case WD0_ID:
-			whichmisc = &wd0_miscdev;
-			strcpy(whichident, "RIC");
-			whichregs = wd_dev.regs + WD0_OFF;
-			whichmask = WD0_INTR_MASK;
-			whichlimit= (0 == wd0_timeout) 	? 
-						(wd_dev.opt_timeout): 
-						(wd0_timeout);
-			break;
-		case WD1_ID:
-			whichmisc = &wd1_miscdev;
-			strcpy(whichident, "XIR");
-			whichregs = wd_dev.regs + WD1_OFF;
-			whichmask = WD1_INTR_MASK;
-			whichlimit= (0 == wd1_timeout) 	? 
-						(wd_dev.opt_timeout): 
-						(wd1_timeout);
-			break;
-		case WD2_ID:
-			whichmisc = &wd2_miscdev;
-			strcpy(whichident, "POR");
-			whichregs = wd_dev.regs + WD2_OFF;
-			whichmask = WD2_INTR_MASK;
-			whichlimit= (0 == wd2_timeout) 	? 
-						(wd_dev.opt_timeout): 
-						(wd2_timeout);
-			break;
-		default:
-			printk("%s: %s: invalid watchdog id: %i\n",
-				WD_OBPNAME, __func__, whichdog);
-			return(1);
-	}
-	if(0 != misc_register(whichmisc))
-	{
-		return(1);
-	}
-	wd_dev.watchdog[whichdog].regs			= whichregs;
-	wd_dev.watchdog[whichdog].timeout 		= whichlimit;
-	wd_dev.watchdog[whichdog].intr_mask		= whichmask;
-	wd_dev.watchdog[whichdog].runstatus 	&= ~WD_STAT_BSTOP;
-	wd_dev.watchdog[whichdog].runstatus 	|= WD_STAT_INIT;
-
-	printk("%s%i: %s hardware watchdog [%01i.%i sec] %s\n", 
-		WD_OBPNAME, 
-		whichdog, 
-		whichident, 
-		wd_dev.watchdog[whichdog].timeout / 10,
-		wd_dev.watchdog[whichdog].timeout % 10,
-		(0 != wd_dev.opt_enable) ? "in ENABLED mode" : "");
-	return(0);
-}
-
-/* Timer method called to reset stopped watchdogs--
- * because of the PLD bug on CP1400, we cannot mask
- * interrupts within the PLD so me must continually
- * reset the timers ad infinitum.
- */
-static void wd_brokentimer(unsigned long data)
-{
-	struct wd_device* pDev = (struct wd_device*)data;
-	int id, tripped = 0;
-
-	/* kill a running timer instance, in case we
-	 * were called directly instead of by kernel timer
-	 */
-	if(timer_pending(&wd_timer)) {
-		del_timer(&wd_timer);
-	}
-
-	for(id = WD0_ID; id < WD_NUMDEVS; ++id) {
-		if(pDev->watchdog[id].runstatus & WD_STAT_BSTOP) {
-			++tripped;
-			wd_resetbrokentimer(&pDev->watchdog[id]);
-		}
-	}
-
-	if(tripped) {
-		/* there is at least one timer brokenstopped-- reschedule */
-		init_timer(&wd_timer);
-		wd_timer.expires = WD_BTIMEOUT;
-		add_timer(&wd_timer);
-	}
-}
-
-static int wd_getstatus(struct wd_timer* pTimer)
-{
-	unsigned char stat = wd_readb(pTimer->regs + WD_STATUS);
-	unsigned char intr = wd_readb(wd_dev.regs + PLD_IMASK);
-	unsigned char ret  = WD_STOPPED;
-
-	/* determine STOPPED */
-	if(0 == stat ) { 
-		return(ret);
-	}
-	/* determine EXPIRED vs FREERUN vs RUNNING */
-	else if(WD_S_EXPIRED & stat) {
-		ret = WD_EXPIRED;
-	}
-	else if(WD_S_RUNNING & stat) {
-		if(intr & pTimer->intr_mask) {
-			ret = WD_FREERUN;
-		}
-		else {
-			/* Fudge WD_EXPIRED status for defective CP1400--
-			 * IF timer is running 
-			 * 	AND brokenstop is set 
-			 * 	AND an interrupt has been serviced
-			 * we are WD_EXPIRED.
-			 *
-			 * IF timer is running 
-			 * 	AND brokenstop is set 
-			 * 	AND no interrupt has been serviced
-			 * we are WD_FREERUN.
-			 */
-			if(wd_dev.isbaddoggie && (pTimer->runstatus & WD_STAT_BSTOP)) {
-				if(pTimer->runstatus & WD_STAT_SVCD) {
-					ret = WD_EXPIRED;
-				}
-				else {
-					/* we could as well pretend we are expired */
-					ret = WD_FREERUN;
-				}
-			}
-			else {
-				ret = WD_RUNNING;
-			}
-		}
-	}
-
-	/* determine SERVICED */
-	if(pTimer->runstatus & WD_STAT_SVCD) {
-		ret |= WD_SERVICED;
-	}
-
-	return(ret);
-}
-
-static int __init wd_init(void)
-{
-	int 	id;
-	struct 	linux_ebus *ebus = NULL;
-	struct 	linux_ebus_device *edev = NULL;
-
-	for_each_ebus(ebus) {
-		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->ofdev.node->name, WD_OBPNAME))
-				goto ebus_done;
-		}
-	}
-
-ebus_done:
-	if(!edev) {
-		printk("%s: unable to locate device\n", WD_OBPNAME);
-		return -ENODEV;
-	}
-
-	wd_dev.regs = 
-		ioremap(edev->resource[0].start, 4 * WD_TIMER_REGSZ); /* ? */
-
-	if(NULL == wd_dev.regs) {
-		printk("%s: unable to map registers\n", WD_OBPNAME);
-		return(-ENODEV);
-	}
-
-	/* initialize device structure from OBP parameters */
-	wd_dev.irq 			= edev->irqs[0];
-	wd_dev.opt_enable	= wd_opt_enable();
-	wd_dev.opt_reboot	= wd_opt_reboot();
-	wd_dev.opt_timeout	= wd_opt_timeout();
-	wd_dev.isbaddoggie	= wd_isbroken();
-
-	/* disable all interrupts unless watchdog-enabled? == true */
-	if(! wd_dev.opt_enable) {
-		wd_toggleintr(NULL, WD_INTR_OFF);
-	}
-
-	/* register miscellaneous devices */
-	for(id = WD0_ID; id < WD_NUMDEVS; ++id) {
-		if(0 != wd_inittimer(id)) {
-			printk("%s%i: unable to initialize\n", WD_OBPNAME, id);
-		}
-	}
-
-	/* warn about possible defective PLD */
-	if(wd_dev.isbaddoggie) {
-		init_timer(&wd_timer);
-		wd_timer.function 	= wd_brokentimer;
-		wd_timer.data		= (unsigned long)&wd_dev;
-		wd_timer.expires	= WD_BTIMEOUT;
-
-		printk("%s: PLD defect workaround enabled for model %s\n",
-			WD_OBPNAME, WD_BADMODEL);
-	}
-	return(0);
-}
-
-static void __exit wd_cleanup(void)
-{
-	int id;
-
-	/* if 'watchdog-enable?' == TRUE, timers are not stopped 
-	 * when module is unloaded.  All brokenstopped timers will
-	 * also now eventually trip. 
-	 */
-	for(id = WD0_ID; id < WD_NUMDEVS; ++id) {
-		if(WD_S_RUNNING == wd_readb(wd_dev.watchdog[id].regs + WD_STATUS)) {
-			if(wd_dev.opt_enable) {
-				printk(KERN_WARNING "%s%i: timer not stopped at release\n",
-					WD_OBPNAME, id);
-			}
-			else {
-				wd_stoptimer(&wd_dev.watchdog[id]);
-				if(wd_dev.watchdog[id].runstatus & WD_STAT_BSTOP) {
-					wd_resetbrokentimer(&wd_dev.watchdog[id]);
-					printk(KERN_WARNING 
-							"%s%i: defect workaround disabled at release, "\
-							"timer expires in ~%01i sec\n",
-							WD_OBPNAME, id, 
-							wd_readw(wd_dev.watchdog[id].regs + WD_LIMIT) / 10);
-				}
-			}
-		}
-	}
-
-	if(wd_dev.isbaddoggie && timer_pending(&wd_timer)) {
-		del_timer(&wd_timer);
-	}
-	if(0 != (wd_dev.watchdog[WD0_ID].runstatus & WD_STAT_INIT)) {
-		misc_deregister(&wd0_miscdev);
-	}
-	if(0 != (wd_dev.watchdog[WD1_ID].runstatus & WD_STAT_INIT)) {
-		misc_deregister(&wd1_miscdev);
-	}
-	if(0 != (wd_dev.watchdog[WD2_ID].runstatus & WD_STAT_INIT)) {
-		misc_deregister(&wd2_miscdev);
-	}
-	if(0 != wd_dev.initialized) {
-		free_irq(wd_dev.irq, (void *)wd_dev.regs);
-	}
-	iounmap(wd_dev.regs);
-}
-
-module_init(wd_init);
-module_exit(wd_cleanup);
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index d8f5c0ca236d..2550af4ae432 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -1,10 +1,7 @@
-/* $Id: display7seg.c,v 1.6 2002/01/08 16:00:16 davem Exp $
- *
- * display7seg - Driver implementation for the 7-segment display
- * present on Sun Microsystems CP1400 and CP1500
+/* display7seg.c - Driver implementation for the 7-segment display
+ *                 present on Sun Microsystems CP1400 and CP1500
  *
  * Copyright (c) 2000 Eric Brower (ebrower@usa.net)
- *
  */
 
 #include <linux/kernel.h>
@@ -16,22 +13,20 @@
 #include <linux/miscdevice.h>
 #include <linux/ioport.h>		/* request_region */
 #include <linux/smp_lock.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <asm/atomic.h>
-#include <asm/ebus.h>			/* EBus device					*/
-#include <asm/oplib.h>			/* OpenProm Library 			*/
 #include <asm/uaccess.h>		/* put_/get_user			*/
 #include <asm/io.h>
 
 #include <asm/display7seg.h>
 
 #define D7S_MINOR	193
-#define D7S_OBPNAME	"display7seg"
-#define D7S_DEVNAME "d7s"
+#define DRIVER_NAME	"d7s"
+#define PFX		DRIVER_NAME ": "
 
 static int sol_compat = 0;		/* Solaris compatibility mode	*/
 
-#ifdef MODULE
-
 /* Solaris compatibility flag -
  * The Solaris implementation omits support for several
  * documented driver features (ref Sun doc 806-0180-03).  
@@ -46,20 +41,20 @@ static int sol_compat = 0;		/* Solaris compatibility mode	*/
  * If you wish the device to operate as under Solaris,
  * omitting above features, set this parameter to non-zero.
  */
-module_param
-	(sol_compat, int, 0);
-MODULE_PARM_DESC
-	(sol_compat, 
-	 "Disables documented functionality omitted from Solaris driver");
-
-MODULE_AUTHOR
-	("Eric Brower <ebrower@usa.net>");
-MODULE_DESCRIPTION
-	("7-Segment Display driver for Sun Microsystems CP1400/1500");
+module_param(sol_compat, int, 0);
+MODULE_PARM_DESC(sol_compat, 
+		 "Disables documented functionality omitted from Solaris driver");
+
+MODULE_AUTHOR("Eric Brower <ebrower@usa.net>");
+MODULE_DESCRIPTION("7-Segment Display driver for Sun Microsystems CP1400/1500");
 MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE
-	("d7s");
-#endif /* ifdef MODULE */
+MODULE_SUPPORTED_DEVICE("d7s");
+
+struct d7s {
+	void __iomem	*regs;
+	bool		flipped;
+};
+struct d7s *d7s_device;
 
 /*
  * Register block address- see header for details
@@ -72,22 +67,6 @@ MODULE_SUPPORTED_DEVICE
  * FLIP		- Inverts display for upside-down mounted board
  * bits 0-4	- 7-segment display contents
  */
-static void __iomem* d7s_regs;
-
-static inline void d7s_free(void)
-{
-	iounmap(d7s_regs);
-}
-
-static inline int d7s_obpflipped(void)
-{
-	int opt_node;
-
-	opt_node = prom_getchild(prom_root_node);
-	opt_node = prom_searchsiblings(opt_node, "options");
-	return ((-1 != prom_getintdefault(opt_node, "d7s-flipped?", -1)) ? 0 : 1);
-}
-
 static atomic_t d7s_users = ATOMIC_INIT(0);
 
 static int d7s_open(struct inode *inode, struct file *f)
@@ -106,12 +85,15 @@ static int d7s_release(struct inode *inode, struct file *f)
 	 * are not operating in solaris-compat mode
 	 */
 	if (atomic_dec_and_test(&d7s_users) && !sol_compat) {
-		int regval = 0;
-
-		regval = readb(d7s_regs);
-		(0 == d7s_obpflipped())	? 
-			writeb(regval |= D7S_FLIP,  d7s_regs): 
-			writeb(regval &= ~D7S_FLIP, d7s_regs);
+		struct d7s *p = d7s_device;
+		u8 regval = 0;
+
+		regval = readb(p->regs);
+		if (p->flipped)
+			regval |= D7S_FLIP;
+		else
+			regval &= ~D7S_FLIP;
+		writeb(regval, p->regs);
 	}
 
 	return 0;
@@ -119,9 +101,10 @@ static int d7s_release(struct inode *inode, struct file *f)
 
 static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	__u8 regs = readb(d7s_regs);
-	__u8 ireg = 0;
+	struct d7s *p = d7s_device;
+	u8 regs = readb(p->regs);
 	int error = 0;
+	u8 ireg = 0;
 
 	if (D7S_MINOR != iminor(file->f_path.dentry->d_inode))
 		return -ENODEV;
@@ -129,18 +112,20 @@ static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	lock_kernel();
 	switch (cmd) {
 	case D7SIOCWR:
-		/* assign device register values
-		 * we mask-out D7S_FLIP if in sol_compat mode
+		/* assign device register values we mask-out D7S_FLIP
+		 * if in sol_compat mode
 		 */
 		if (get_user(ireg, (int __user *) arg)) {
 			error = -EFAULT;
 			break;
 		}
-		if (0 != sol_compat) {
-			(regs & D7S_FLIP) ? 
-				(ireg |= D7S_FLIP) : (ireg &= ~D7S_FLIP);
+		if (sol_compat) {
+			if (regs & D7S_FLIP)
+				ireg |= D7S_FLIP;
+			else
+				ireg &= ~D7S_FLIP;
 		}
-		writeb(ireg, d7s_regs);
+		writeb(ireg, p->regs);
 		break;
 
 	case D7SIOCRD:
@@ -158,9 +143,11 @@ static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 
 	case D7SIOCTM:
 		/* toggle device mode-- flip display orientation */
-		(regs & D7S_FLIP) ? 
-			(regs &= ~D7S_FLIP) : (regs |= D7S_FLIP);
-		writeb(regs, d7s_regs);
+		if (regs & D7S_FLIP)
+			regs &= ~D7S_FLIP;
+		else
+			regs |= D7S_FLIP;
+		writeb(regs, p->regs);
 		break;
 	};
 	unlock_kernel();
@@ -176,69 +163,123 @@ static const struct file_operations d7s_fops = {
 	.release =		d7s_release,
 };
 
-static struct miscdevice d7s_miscdev = { D7S_MINOR, D7S_DEVNAME, &d7s_fops };
+static struct miscdevice d7s_miscdev = {
+	.minor		= D7S_MINOR,
+	.name		= DRIVER_NAME,
+	.fops		= &d7s_fops
+};
 
-static int __init d7s_init(void)
+static int __devinit d7s_probe(struct of_device *op,
+			       const struct of_device_id *match)
 {
-	struct linux_ebus *ebus = NULL;
-	struct linux_ebus_device *edev = NULL;
-	int iTmp = 0, regs = 0;
-
-	for_each_ebus(ebus) {
-		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_node->name, D7S_OBPNAME))
-				goto ebus_done;
-		}
+	struct device_node *opts;
+	int err = -EINVAL;
+	struct d7s *p;
+	u8 regs;
+
+	if (d7s_device)
+		goto out;
+
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	err = -ENOMEM;
+	if (!p)
+		goto out;
+
+	p->regs = of_ioremap(&op->resource[0], 0, sizeof(u8), "d7s");
+	if (!p->regs) {
+		printk(KERN_ERR PFX "Cannot map chip registers\n");
+		goto out_free;
 	}
 
-ebus_done:
-	if(!edev) {
-		printk("%s: unable to locate device\n", D7S_DEVNAME);
-		return -ENODEV;
+	err = misc_register(&d7s_miscdev);
+	if (err) {
+		printk(KERN_ERR PFX "Unable to acquire miscdevice minor %i\n",
+		       D7S_MINOR);
+		goto out_iounmap;
 	}
 
-	d7s_regs = ioremap(edev->resource[0].start, sizeof(__u8));
-
-	iTmp = misc_register(&d7s_miscdev);
-	if (0 != iTmp) {
-		printk("%s: unable to acquire miscdevice minor %i\n",
-		       D7S_DEVNAME, D7S_MINOR);
-		iounmap(d7s_regs);
-		return iTmp;
-	}
-
-	/* OBP option "d7s-flipped?" is honored as default
-	 * for the device, and reset default when detached
+	/* OBP option "d7s-flipped?" is honored as default for the
+	 * device, and reset default when detached
 	 */
-	regs = readb(d7s_regs);
-	iTmp = d7s_obpflipped();
-	(0 == iTmp) ? 
-		writeb(regs |= D7S_FLIP,  d7s_regs): 
-		writeb(regs &= ~D7S_FLIP, d7s_regs);
-
-	printk("%s: 7-Segment Display%s at 0x%lx %s\n", 
-	       D7S_DEVNAME,
-	       (0 == iTmp) ? (" (FLIPPED)") : (""),
-	       edev->resource[0].start,
-	       (0 != sol_compat) ? ("in sol_compat mode") : (""));
-
-	return 0;
+	regs = readb(p->regs);
+	opts = of_find_node_by_path("/options");
+	if (opts &&
+	    of_get_property(opts, "d7s-flipped?", NULL))
+		p->flipped = true;
+
+	if (p->flipped)
+		regs |= D7S_FLIP;
+	else
+		regs &= ~D7S_FLIP;
+
+	writeb(regs,  p->regs);
+
+	printk(KERN_INFO PFX "7-Segment Display%s at [%s:0x%lx] %s\n", 
+	       op->node->full_name,
+	       (regs & D7S_FLIP) ? " (FLIPPED)" : "",
+	       op->resource[0].start,
+	       sol_compat ? "in sol_compat mode" : "");
+
+	dev_set_drvdata(&op->dev, p);
+	d7s_device = p;
+	err = 0;
+
+out:
+	return err;
+
+out_iounmap:
+	of_iounmap(&op->resource[0], p->regs, sizeof(u8));
+
+out_free:
+	kfree(p);
+	goto out;
 }
 
-static void __exit d7s_cleanup(void)
+static int __devexit d7s_remove(struct of_device *op)
 {
-	int regs = readb(d7s_regs);
+	struct d7s *p = dev_get_drvdata(&op->dev);
+	u8 regs = readb(p->regs);
 
 	/* Honor OBP d7s-flipped? unless operating in solaris-compat mode */
-	if (0 == sol_compat) {
-		(0 == d7s_obpflipped())	? 
-			writeb(regs |= D7S_FLIP,  d7s_regs):
-			writeb(regs &= ~D7S_FLIP, d7s_regs);
+	if (sol_compat) {
+		if (p->flipped)
+			regs |= D7S_FLIP;
+		else
+			regs &= ~D7S_FLIP;
+		writeb(regs, p->regs);
 	}
 
 	misc_deregister(&d7s_miscdev);
-	d7s_free();
+	of_iounmap(&op->resource[0], p->regs, sizeof(u8));
+	kfree(p);
+
+	return 0;
+}
+
+static const struct of_device_id d7s_match[] = {
+	{
+		.name = "display7seg",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, d7s_match);
+
+static struct of_platform_driver d7s_driver = {
+	.name		= DRIVER_NAME,
+	.match_table	= d7s_match,
+	.probe		= d7s_probe,
+	.remove		= __devexit_p(d7s_remove),
+};
+
+static int __init d7s_init(void)
+{
+	return of_register_driver(&d7s_driver, &of_bus_type);
+}
+
+static void __exit d7s_exit(void)
+{
+	of_unregister_driver(&d7s_driver);
 }
 
 module_init(d7s_init);
-module_exit(d7s_cleanup);
+module_exit(d7s_exit);
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index a408402426f8..58e583b61e60 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -1,5 +1,4 @@
-/* $Id: envctrl.c,v 1.25 2002/01/15 09:01:26 davem Exp $
- * envctrl.c: Temperature and Fan monitoring on Machines providing it.
+/* envctrl.c: Temperature and Fan monitoring on Machines providing it.
  *
  * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
  * Copyright (C) 2000  Vinh Truong    (vinh.truong@eng.sun.com)
@@ -28,12 +27,16 @@
 #include <linux/kmod.h>
 #include <linux/reboot.h>
 #include <linux/smp_lock.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
-#include <asm/ebus.h>
 #include <asm/uaccess.h>
 #include <asm/envctrl.h>
 #include <asm/io.h>
 
+#define DRIVER_NAME	"envctrl"
+#define PFX		DRIVER_NAME ": "
+
 #define ENVCTRL_MINOR	162
 
 #define PCF8584_ADDRESS	0x55
@@ -193,7 +196,7 @@ static void envtrl_i2c_test_pin(void)
 	} 
 
 	if (limit <= 0)
-		printk(KERN_INFO "envctrl: Pin status will not clear.\n");
+		printk(KERN_INFO PFX "Pin status will not clear.\n");
 }
 
 /* Function Description: Test busy bit.
@@ -211,7 +214,7 @@ static void envctrl_i2c_test_bb(void)
 	} 
 
 	if (limit <= 0)
-		printk(KERN_INFO "envctrl: Busy bit will not clear.\n");
+		printk(KERN_INFO PFX "Busy bit will not clear.\n");
 }
 
 /* Function Description: Send the address for a read access.
@@ -858,11 +861,10 @@ static void envctrl_init_voltage_status(struct i2c_child_t *pchild)
 /* Function Description: Initialize i2c child device.
  * Return: None.
  */
-static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child,
+static void envctrl_init_i2c_child(struct device_node *dp,
 				   struct i2c_child_t *pchild)
 {
 	int len, i, tbls_size = 0;
-	struct device_node *dp = edev_child->prom_node;
 	const void *pval;
 
 	/* Get device address. */
@@ -882,12 +884,12 @@ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child,
 
                 pchild->tables = kmalloc(tbls_size, GFP_KERNEL);
 		if (pchild->tables == NULL){
-			printk("envctrl: Failed to allocate table.\n");
+			printk(KERN_ERR PFX "Failed to allocate table.\n");
 			return;
 		}
 		pval = of_get_property(dp, "tables", &len);
                 if (!pval || len <= 0) {
-			printk("envctrl: Failed to get table.\n");
+			printk(KERN_ERR PFX "Failed to get table.\n");
 			return;
 		}
 		memcpy(pchild->tables, pval, len);
@@ -993,14 +995,14 @@ static int kenvctrld(void *__unused)
 	struct i2c_child_t *cputemp;
 
 	if (NULL == (cputemp = envctrl_get_i2c_child(ENVCTRL_CPUTEMP_MON))) {
-		printk(KERN_ERR 
-		       "envctrl: kenvctrld unable to monitor CPU temp-- exiting\n");
+		printk(KERN_ERR  PFX
+		       "kenvctrld unable to monitor CPU temp-- exiting\n");
 		return -ENODEV;
 	}
 
 	poll_interval = 5000; /* TODO env_mon_interval */
 
-	printk(KERN_INFO "envctrl: %s starting...\n", current->comm);
+	printk(KERN_INFO PFX "%s starting...\n", current->comm);
 	for (;;) {
 		msleep_interruptible(poll_interval);
 
@@ -1022,54 +1024,35 @@ static int kenvctrld(void *__unused)
 			}
 		}
 	}
-	printk(KERN_INFO "envctrl: %s exiting...\n", current->comm);
+	printk(KERN_INFO PFX "%s exiting...\n", current->comm);
 	return 0;
 }
 
-static int __init envctrl_init(void)
+static int __devinit envctrl_probe(struct of_device *op,
+				   const struct of_device_id *match)
 {
-	struct linux_ebus *ebus = NULL;
-	struct linux_ebus_device *edev = NULL;
-	struct linux_ebus_child *edev_child = NULL;
-	int err, i = 0;
-
-	for_each_ebus(ebus) {
-		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_node->name, "bbc")) {
-				/* If we find a boot-bus controller node,
-				 * then this envctrl driver is not for us.
-				 */
-				return -ENODEV;
-			}
-		}
-	}
+	struct device_node *dp;
+	int index, err;
 
-	/* Traverse through ebus and ebus device list for i2c device and
-	 * adc and gpio nodes.
-	 */
-	for_each_ebus(ebus) {
-		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_node->name, "i2c")) {
-				i2c = ioremap(edev->resource[0].start, 0x2);
-				for_each_edevchild(edev, edev_child) {
-					if (!strcmp("gpio", edev_child->prom_node->name)) {
-						i2c_childlist[i].i2ctype = I2C_GPIO;
-						envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++]));
-					}
-					if (!strcmp("adc", edev_child->prom_node->name)) {
-						i2c_childlist[i].i2ctype = I2C_ADC;
-						envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++]));
-					}
-				}
-				goto done;
-			}
+	if (i2c)
+		return -EINVAL;
+
+	i2c = of_ioremap(&op->resource[0], 0, 0x2, DRIVER_NAME);
+	if (!i2c)
+		return -ENOMEM;
+
+	index = 0;
+	dp = op->node->child;
+	while (dp) {
+		if (!strcmp(dp->name, "gpio")) {
+			i2c_childlist[index].i2ctype = I2C_GPIO;
+			envctrl_init_i2c_child(dp, &(i2c_childlist[index++]));
+		} else if (!strcmp(dp->name, "adc")) {
+			i2c_childlist[index].i2ctype = I2C_ADC;
+			envctrl_init_i2c_child(dp, &(i2c_childlist[index++]));
 		}
-	}
 
-done:
-	if (!edev) {
-		printk("envctrl: I2C device not found.\n");
-		return -ENODEV;
+		dp = dp->sibling;
 	}
 
 	/* Set device address. */
@@ -1087,7 +1070,7 @@ done:
 	/* Register the device as a minor miscellaneous device. */
 	err = misc_register(&envctrl_dev);
 	if (err) {
-		printk("envctrl: Unable to get misc minor %d\n",
+		printk(KERN_ERR PFX "Unable to get misc minor %d\n",
 		       envctrl_dev.minor);
 		goto out_iounmap;
 	}
@@ -1096,12 +1079,12 @@ done:
 	 * a next child device, so we decrement before reverse-traversal of
 	 * child devices.
 	 */
-	printk("envctrl: initialized ");
-	for (--i; i >= 0; --i) {
+	printk(KERN_INFO PFX "Initialized ");
+	for (--index; index >= 0; --index) {
 		printk("[%s 0x%lx]%s", 
-			(I2C_ADC == i2c_childlist[i].i2ctype) ? ("adc") : 
-			((I2C_GPIO == i2c_childlist[i].i2ctype) ? ("gpio") : ("unknown")), 
-			i2c_childlist[i].addr, (0 == i) ? ("\n") : (" "));
+			(I2C_ADC == i2c_childlist[index].i2ctype) ? "adc" : 
+			((I2C_GPIO == i2c_childlist[index].i2ctype) ? "gpio" : "unknown"), 
+			i2c_childlist[index].addr, (0 == index) ? "\n" : " ");
 	}
 
 	kenvctrld_task = kthread_run(kenvctrld, NULL, "kenvctrld");
@@ -1115,26 +1098,54 @@ done:
 out_deregister:
 	misc_deregister(&envctrl_dev);
 out_iounmap:
-	iounmap(i2c);
-	for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++)
-		kfree(i2c_childlist[i].tables);
+	of_iounmap(&op->resource[0], i2c, 0x2);
+	for (index = 0; index < ENVCTRL_MAX_CPU * 2; index++)
+		kfree(i2c_childlist[index].tables);
 
 	return err;
 }
 
-static void __exit envctrl_cleanup(void)
+static int __devexit envctrl_remove(struct of_device *op)
 {
-	int i;
+	int index;
 
 	kthread_stop(kenvctrld_task);
 
-	iounmap(i2c);
+	of_iounmap(&op->resource[0], i2c, 0x2);
 	misc_deregister(&envctrl_dev);
 
-	for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++)
-		kfree(i2c_childlist[i].tables);
+	for (index = 0; index < ENVCTRL_MAX_CPU * 2; index++)
+		kfree(i2c_childlist[index].tables);
+
+	return 0;
+}
+
+static const struct of_device_id envctrl_match[] = {
+	{
+		.name = "i2c",
+		.compatible = "i2cpcf,8584",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, envctrl_match);
+
+static struct of_platform_driver envctrl_driver = {
+	.name		= DRIVER_NAME,
+	.match_table	= envctrl_match,
+	.probe		= envctrl_probe,
+	.remove		= __devexit_p(envctrl_remove),
+};
+
+static int __init envctrl_init(void)
+{
+	return of_register_driver(&envctrl_driver, &of_bus_type);
+}
+
+static void __exit envctrl_exit(void)
+{
+	of_unregister_driver(&envctrl_driver);
 }
 
 module_init(envctrl_init);
-module_exit(envctrl_cleanup);
+module_exit(envctrl_exit);
 MODULE_LICENSE("GPL");
diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c
index 7d95e151513a..41083472ff4f 100644
--- a/drivers/sbus/char/flash.c
+++ b/drivers/sbus/char/flash.c
@@ -1,5 +1,4 @@
-/* $Id: flash.c,v 1.25 2001/12/21 04:56:16 davem Exp $
- * flash.c: Allow mmap access to the OBP Flash, for OBP updates.
+/* flash.c: Allow mmap access to the OBP Flash, for OBP updates.
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
  */
@@ -15,13 +14,13 @@
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 #include <linux/mm.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
-#include <asm/sbus.h>
-#include <asm/ebus.h>
 #include <asm/upa.h>
 
 static DEFINE_SPINLOCK(flash_lock);
@@ -161,97 +160,68 @@ static const struct file_operations flash_fops = {
 
 static struct miscdevice flash_dev = { FLASH_MINOR, "flash", &flash_fops };
 
-static int __init flash_init(void)
+static int __devinit flash_probe(struct of_device *op,
+				 const struct of_device_id *match)
 {
-	struct sbus_bus *sbus;
-	struct sbus_dev *sdev = NULL;
-#ifdef CONFIG_PCI
-	struct linux_ebus *ebus;
-	struct linux_ebus_device *edev = NULL;
-	struct linux_prom_registers regs[2];
-	int len, nregs;
-#endif
-	int err;
-
-	for_all_sbusdev(sdev, sbus) {
-		if (!strcmp(sdev->prom_name, "flashprom")) {
-			if (sdev->reg_addrs[0].phys_addr == sdev->reg_addrs[1].phys_addr) {
-				flash.read_base = ((unsigned long)sdev->reg_addrs[0].phys_addr) |
-					(((unsigned long)sdev->reg_addrs[0].which_io)<<32UL);
-				flash.read_size = sdev->reg_addrs[0].reg_size;
-				flash.write_base = flash.read_base;
-				flash.write_size = flash.read_size;
-			} else {
-				flash.read_base = ((unsigned long)sdev->reg_addrs[0].phys_addr) |
-					(((unsigned long)sdev->reg_addrs[0].which_io)<<32UL);
-				flash.read_size = sdev->reg_addrs[0].reg_size;
-				flash.write_base = ((unsigned long)sdev->reg_addrs[1].phys_addr) |
-					(((unsigned long)sdev->reg_addrs[1].which_io)<<32UL);
-				flash.write_size = sdev->reg_addrs[1].reg_size;
-			}
-			flash.busy = 0;
-			break;
-		}
-	}
-	if (!sdev) {
-#ifdef CONFIG_PCI
-		const struct linux_prom_registers *ebus_regs;
-
-		for_each_ebus(ebus) {
-			for_each_ebusdev(edev, ebus) {
-				if (!strcmp(edev->prom_node->name, "flashprom"))
-					goto ebus_done;
-			}
-		}
-	ebus_done:
-		if (!edev)
-			return -ENODEV;
-
-		ebus_regs = of_get_property(edev->prom_node, "reg", &len);
-		if (!ebus_regs || (len % sizeof(regs[0])) != 0) {
-			printk("flash: Strange reg property size %d\n", len);
-			return -ENODEV;
-		}
-
-		nregs = len / sizeof(ebus_regs[0]);
+	struct device_node *dp = op->node;
+	struct device_node *parent;
 
-		flash.read_base = edev->resource[0].start;
-		flash.read_size = ebus_regs[0].reg_size;
+	parent = dp->parent;
 
-		if (nregs == 1) {
-			flash.write_base = edev->resource[0].start;
-			flash.write_size = ebus_regs[0].reg_size;
-		} else if (nregs == 2) {
-			flash.write_base = edev->resource[1].start;
-			flash.write_size = ebus_regs[1].reg_size;
-		} else {
-			printk("flash: Strange number of regs %d\n", nregs);
-			return -ENODEV;
-		}
-
-		flash.busy = 0;
-
-#else
+	if (strcmp(parent->name, "sbus") &&
+	    strcmp(parent->name, "sbi") &&
+	    strcmp(parent->name, "ebus"))
 		return -ENODEV;
-#endif
+
+	flash.read_base = op->resource[0].start;
+	flash.read_size = resource_size(&op->resource[0]);
+	if (op->resource[1].flags) {
+		flash.write_base = op->resource[1].start;
+		flash.write_size = resource_size(&op->resource[1]);
+	} else {
+		flash.write_base = op->resource[0].start;
+		flash.write_size = resource_size(&op->resource[0]);
 	}
+	flash.busy = 0;
 
-	printk("OBP Flash: RD %lx[%lx] WR %lx[%lx]\n",
+	printk(KERN_INFO "%s: OBP Flash, RD %lx[%lx] WR %lx[%lx]\n",
+	       op->node->full_name,
 	       flash.read_base, flash.read_size,
 	       flash.write_base, flash.write_size);
 
-	err = misc_register(&flash_dev);
-	if (err) {
-		printk(KERN_ERR "flash: unable to get misc minor\n");
-		return err;
-	}
+	return misc_register(&flash_dev);
+}
+
+static int __devexit flash_remove(struct of_device *op)
+{
+	misc_deregister(&flash_dev);
 
 	return 0;
 }
 
+static const struct of_device_id flash_match[] = {
+	{
+		.name = "flashprom",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, flash_match);
+
+static struct of_platform_driver flash_driver = {
+	.name		= "flash",
+	.match_table	= flash_match,
+	.probe		= flash_probe,
+	.remove		= __devexit_p(flash_remove),
+};
+
+static int __init flash_init(void)
+{
+	return of_register_driver(&flash_driver, &of_bus_type);
+}
+
 static void __exit flash_cleanup(void)
 {
-	misc_deregister(&flash_dev);
+	of_unregister_driver(&flash_driver);
 }
 
 module_init(flash_init);
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
deleted file mode 100644
index b0429917154d..000000000000
--- a/drivers/sbus/char/rtc.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/* $Id: rtc.c,v 1.28 2001/10/08 22:19:51 davem Exp $
- *
- * Linux/SPARC Real Time Clock Driver
- * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
- *
- * This is a little driver that lets a user-level program access
- * the SPARC Mostek real time clock chip. It is no use unless you
- * use the modified clock utility.
- *
- * Get the modified clock utility from:
- *   ftp://vger.kernel.org/pub/linux/Sparc/userland/clock.c
- */
-
-#include <linux/module.h>
-#include <linux/smp_lock.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <linux/fcntl.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <asm/mostek.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/rtc.h>
-
-static int rtc_busy = 0;
-
-/* This is the structure layout used by drivers/char/rtc.c, we
- * support that driver's ioctls so that things are less messy in
- * userspace.
- */
-struct rtc_time_generic {
-	int tm_sec;
-	int tm_min;
-	int tm_hour;
-	int tm_mday;
-	int tm_mon;
-	int tm_year;
-	int tm_wday;
-	int tm_yday;
-	int tm_isdst;
-};
-#define RTC_AIE_ON	_IO('p', 0x01)	/* Alarm int. enable on		*/
-#define RTC_AIE_OFF	_IO('p', 0x02)	/* ... off			*/
-#define RTC_UIE_ON	_IO('p', 0x03)	/* Update int. enable on	*/
-#define RTC_UIE_OFF	_IO('p', 0x04)	/* ... off			*/
-#define RTC_PIE_ON	_IO('p', 0x05)	/* Periodic int. enable on	*/
-#define RTC_PIE_OFF	_IO('p', 0x06)	/* ... off			*/
-#define RTC_WIE_ON	_IO('p', 0x0f)  /* Watchdog int. enable on	*/
-#define RTC_WIE_OFF	_IO('p', 0x10)  /* ... off			*/
-#define RTC_RD_TIME	_IOR('p', 0x09, struct rtc_time_generic) /* Read RTC time   */
-#define RTC_SET_TIME	_IOW('p', 0x0a, struct rtc_time_generic) /* Set RTC time    */
-#define RTC_ALM_SET	_IOW('p', 0x07, struct rtc_time) /* Set alarm time  */
-#define RTC_ALM_READ	_IOR('p', 0x08, struct rtc_time) /* Read alarm time */
-#define RTC_IRQP_READ	_IOR('p', 0x0b, unsigned long)	 /* Read IRQ rate   */
-#define RTC_IRQP_SET	_IOW('p', 0x0c, unsigned long)	 /* Set IRQ rate    */
-#define RTC_EPOCH_READ	_IOR('p', 0x0d, unsigned long)	 /* Read epoch      */
-#define RTC_EPOCH_SET	_IOW('p', 0x0e, unsigned long)	 /* Set epoch       */
-#define RTC_WKALM_SET	_IOW('p', 0x0f, struct rtc_wkalrm)/* Set wakeup alarm*/
-#define RTC_WKALM_RD	_IOR('p', 0x10, struct rtc_wkalrm)/* Get wakeup alarm*/
-#define RTC_PLL_GET	_IOR('p', 0x11, struct rtc_pll_info)  /* Get PLL correction */
-#define RTC_PLL_SET	_IOW('p', 0x12, struct rtc_pll_info)  /* Set PLL correction */
-
-/* Retrieve the current date and time from the real time clock. */
-static void get_rtc_time(struct rtc_time *t)
-{
-	void __iomem *regs = mstk48t02_regs;
-	u8 tmp;
-
-	spin_lock_irq(&mostek_lock);
-
-	tmp = mostek_read(regs + MOSTEK_CREG);
-	tmp |= MSTK_CREG_READ;
-	mostek_write(regs + MOSTEK_CREG, tmp);
-
-	t->sec = MSTK_REG_SEC(regs);
-	t->min = MSTK_REG_MIN(regs);
-	t->hour = MSTK_REG_HOUR(regs);
-	t->dow = MSTK_REG_DOW(regs);
-	t->dom = MSTK_REG_DOM(regs);
-	t->month = MSTK_REG_MONTH(regs);
-	t->year = MSTK_CVT_YEAR( MSTK_REG_YEAR(regs) );
-
-	tmp = mostek_read(regs + MOSTEK_CREG);
-	tmp &= ~MSTK_CREG_READ;
-	mostek_write(regs + MOSTEK_CREG, tmp);
-
-	spin_unlock_irq(&mostek_lock);
-}
-
-/* Set the current date and time inthe real time clock. */
-void set_rtc_time(struct rtc_time *t)
-{
-	void __iomem *regs = mstk48t02_regs;
-	u8 tmp;
-
-	spin_lock_irq(&mostek_lock);
-
-	tmp = mostek_read(regs + MOSTEK_CREG);
-	tmp |= MSTK_CREG_WRITE;
-	mostek_write(regs + MOSTEK_CREG, tmp);
-
-	MSTK_SET_REG_SEC(regs,t->sec);
-	MSTK_SET_REG_MIN(regs,t->min);
-	MSTK_SET_REG_HOUR(regs,t->hour);
-	MSTK_SET_REG_DOW(regs,t->dow);
-	MSTK_SET_REG_DOM(regs,t->dom);
-	MSTK_SET_REG_MONTH(regs,t->month);
-	MSTK_SET_REG_YEAR(regs,t->year - MSTK_YEAR_ZERO);
-
-	tmp = mostek_read(regs + MOSTEK_CREG);
-	tmp &= ~MSTK_CREG_WRITE;
-	mostek_write(regs + MOSTEK_CREG, tmp);
-
-	spin_unlock_irq(&mostek_lock);
-}
-
-static int put_rtc_time_generic(void __user *argp, struct rtc_time *tm)
-{
-	struct rtc_time_generic __user *utm = argp;
-
-	if (__put_user(tm->sec, &utm->tm_sec) ||
-	    __put_user(tm->min, &utm->tm_min) ||
-	    __put_user(tm->hour, &utm->tm_hour) ||
-	    __put_user(tm->dom, &utm->tm_mday) ||
-	    __put_user(tm->month, &utm->tm_mon) ||
-	    __put_user(tm->year, &utm->tm_year) ||
-	    __put_user(tm->dow, &utm->tm_wday) ||
-	    __put_user(0, &utm->tm_yday) ||
-	    __put_user(0, &utm->tm_isdst))
-		return -EFAULT;
-
-	return 0;
-}
-
-static int get_rtc_time_generic(struct rtc_time *tm, void __user *argp)
-{
-	struct rtc_time_generic __user *utm = argp;
-
-	if (__get_user(tm->sec, &utm->tm_sec) ||
-	    __get_user(tm->min, &utm->tm_min) ||
-	    __get_user(tm->hour, &utm->tm_hour) ||
-	    __get_user(tm->dom, &utm->tm_mday) ||
-	    __get_user(tm->month, &utm->tm_mon) ||
-	    __get_user(tm->year, &utm->tm_year) ||
-	    __get_user(tm->dow, &utm->tm_wday))
-		return -EFAULT;
-
-	return 0;
-}
-
-static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-	unsigned long arg)
-{
-	struct rtc_time rtc_tm;
-	void __user *argp = (void __user *)arg;
-
-	switch (cmd) {
-	/* No interrupt support, return an error
-	 * compatible with drivers/char/rtc.c
-	 */
-	case RTC_AIE_OFF:
-	case RTC_AIE_ON:
-	case RTC_PIE_OFF:
-	case RTC_PIE_ON:
-	case RTC_UIE_OFF:
-	case RTC_UIE_ON:
-	case RTC_IRQP_READ:
-	case RTC_IRQP_SET:
-	case RTC_EPOCH_SET:
-	case RTC_EPOCH_READ:
-		return -EINVAL;
-
-	case RTCGET:
-	case RTC_RD_TIME:
-		memset(&rtc_tm, 0, sizeof(struct rtc_time));
-		get_rtc_time(&rtc_tm);
-
-		if (cmd == RTCGET) {
-			if (copy_to_user(argp, &rtc_tm,
-					 sizeof(struct rtc_time)))
-				return -EFAULT;
-		} else if (put_rtc_time_generic(argp, &rtc_tm))
-			return -EFAULT;
-
-		return 0;
-
-
-	case RTCSET:
-	case RTC_SET_TIME:
-		if (!capable(CAP_SYS_TIME))
-			return -EPERM;
-
-		if (cmd == RTCSET) {
-			if (copy_from_user(&rtc_tm, argp,
-					   sizeof(struct rtc_time)))
-				return -EFAULT;
-		} else if (get_rtc_time_generic(&rtc_tm, argp))
-			return -EFAULT;
-
-		set_rtc_time(&rtc_tm);
-
-		return 0;
-
-	default:
-		return -EINVAL;
-	}
-}
-
-static int rtc_open(struct inode *inode, struct file *file)
-{
-	int ret;
-
-	lock_kernel();
-	spin_lock_irq(&mostek_lock);
-	if (rtc_busy) {
-		ret = -EBUSY;
-	} else {
-		rtc_busy = 1;
-		ret = 0;
-	}
-	spin_unlock_irq(&mostek_lock);
-	unlock_kernel();
-
-	return ret;
-}
-
-static int rtc_release(struct inode *inode, struct file *file)
-{
-	rtc_busy = 0;
-
-	return 0;
-}
-
-static const struct file_operations rtc_fops = {
-	.owner =	THIS_MODULE,
-	.llseek =	no_llseek,
-	.ioctl =	rtc_ioctl,
-	.open =		rtc_open,
-	.release =	rtc_release,
-};
-
-static struct miscdevice rtc_dev = { RTC_MINOR, "rtc", &rtc_fops };
-
-static int __init rtc_sun_init(void)
-{
-	int error;
-
-	/* It is possible we are being driven by some other RTC chip
-	 * and thus another RTC driver is handling things.
-	 */
-	if (!mstk48t02_regs)
-		return -ENODEV;
-
-	error = misc_register(&rtc_dev);
-	if (error) {
-		printk(KERN_ERR "rtc: unable to get misc minor for Mostek\n");
-		return error;
-	}
-	printk("rtc_sun_init: Registered Mostek RTC driver.\n");
-
-	return 0;
-}
-
-static void __exit rtc_sun_cleanup(void)
-{
-	misc_deregister(&rtc_dev);
-}
-
-module_init(rtc_sun_init);
-module_exit(rtc_sun_cleanup);
-MODULE_LICENSE("GPL");
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c
index 777637594acd..27993c37775d 100644
--- a/drivers/sbus/char/uctrl.c
+++ b/drivers/sbus/char/uctrl.c
@@ -1,7 +1,7 @@
-/* $Id: uctrl.c,v 1.12 2001/10/08 22:19:51 davem Exp $
- * uctrl.c: TS102 Microcontroller interface on Tadpole Sparcbook 3
+/* uctrl.c: TS102 Microcontroller interface on Tadpole Sparcbook 3
  *
  * Copyright 1999 Derrick J Brashear (shadow@dementia.org)
+ * Copyright 2008 David S. Miller (davem@davemloft.net)
  */
 
 #include <linux/module.h>
@@ -14,6 +14,8 @@
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/mm.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <asm/openprom.h>
 #include <asm/oplib.h>
@@ -21,7 +23,6 @@
 #include <asm/irq.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
-#include <asm/sbus.h>
 
 #define UCTRL_MINOR	174
 
@@ -33,26 +34,26 @@
 #endif
 
 struct uctrl_regs {
-	volatile u32 uctrl_intr;
-	volatile u32 uctrl_data;
-	volatile u32 uctrl_stat;
-	volatile u32 uctrl_xxx[5];
+	u32 uctrl_intr;
+	u32 uctrl_data;
+	u32 uctrl_stat;
+	u32 uctrl_xxx[5];
 };
 
 struct ts102_regs {
-	volatile u32 card_a_intr;
-	volatile u32 card_a_stat;
-	volatile u32 card_a_ctrl;
-	volatile u32 card_a_xxx;
-	volatile u32 card_b_intr;
-	volatile u32 card_b_stat;
-	volatile u32 card_b_ctrl;
-	volatile u32 card_b_xxx;
-	volatile u32 uctrl_intr;
-	volatile u32 uctrl_data;
-	volatile u32 uctrl_stat;
-	volatile u32 uctrl_xxx;
-	volatile u32 ts102_xxx[4];
+	u32 card_a_intr;
+	u32 card_a_stat;
+	u32 card_a_ctrl;
+	u32 card_a_xxx;
+	u32 card_b_intr;
+	u32 card_b_stat;
+	u32 card_b_ctrl;
+	u32 card_b_xxx;
+	u32 uctrl_intr;
+	u32 uctrl_data;
+	u32 uctrl_stat;
+	u32 uctrl_xxx;
+	u32 ts102_xxx[4];
 };
 
 /* Bits for uctrl_intr register */
@@ -186,17 +187,15 @@ enum uctrl_opcode {
   POWER_RESTART=0x83,
 };
 
-struct uctrl_driver {
-	struct uctrl_regs *regs;
+static struct uctrl_driver {
+	struct uctrl_regs __iomem *regs;
 	int irq;
 	int pending;
 	struct uctrl_status status;
-};
-
-static struct uctrl_driver drv;
+} *global_driver;
 
-static void uctrl_get_event_status(void);
-static void uctrl_get_external_status(void);
+static void uctrl_get_event_status(struct uctrl_driver *);
+static void uctrl_get_external_status(struct uctrl_driver *);
 
 static int
 uctrl_ioctl(struct inode *inode, struct file *file,
@@ -213,16 +212,14 @@ static int
 uctrl_open(struct inode *inode, struct file *file)
 {
 	lock_kernel();
-	uctrl_get_event_status();
-	uctrl_get_external_status();
+	uctrl_get_event_status(global_driver);
+	uctrl_get_external_status(global_driver);
 	unlock_kernel();
 	return 0;
 }
 
 static irqreturn_t uctrl_interrupt(int irq, void *dev_id)
 {
-	struct uctrl_driver *driver = (struct uctrl_driver *)dev_id;
-	printk("in uctrl_interrupt\n");
 	return IRQ_HANDLED;
 }
 
@@ -244,11 +241,11 @@ static struct miscdevice uctrl_dev = {
 { \
   unsigned int i; \
   for (i = 0; i < 10000; i++) { \
-    if (UCTRL_STAT_TXNF_STA & driver->regs->uctrl_stat) \
+      if (UCTRL_STAT_TXNF_STA & sbus_readl(&driver->regs->uctrl_stat)) \
       break; \
   } \
   dprintk(("write data 0x%02x\n", value)); \
-  driver->regs->uctrl_data = value; \
+  sbus_writel(value, &driver->regs->uctrl_data); \
 }
 
 /* Wait for something to read, read it, then clear the bit */
@@ -257,24 +254,23 @@ static struct miscdevice uctrl_dev = {
   unsigned int i; \
   value = 0; \
   for (i = 0; i < 10000; i++) { \
-    if ((UCTRL_STAT_RXNE_STA & driver->regs->uctrl_stat) == 0) \
+      if ((UCTRL_STAT_RXNE_STA & sbus_readl(&driver->regs->uctrl_stat)) == 0) \
       break; \
     udelay(1); \
   } \
-  value = driver->regs->uctrl_data; \
+  value = sbus_readl(&driver->regs->uctrl_data); \
   dprintk(("read data 0x%02x\n", value)); \
-  driver->regs->uctrl_stat = UCTRL_STAT_RXNE_STA; \
+  sbus_writel(UCTRL_STAT_RXNE_STA, &driver->regs->uctrl_stat); \
 }
 
-static void uctrl_do_txn(struct uctrl_txn *txn)
+static void uctrl_do_txn(struct uctrl_driver *driver, struct uctrl_txn *txn)
 {
-	struct uctrl_driver *driver = &drv;
 	int stat, incnt, outcnt, bytecnt, intr;
 	u32 byte;
 
-	stat = driver->regs->uctrl_stat;
-	intr = driver->regs->uctrl_intr;
-	driver->regs->uctrl_stat = stat;
+	stat = sbus_readl(&driver->regs->uctrl_stat);
+	intr = sbus_readl(&driver->regs->uctrl_intr);
+	sbus_writel(stat, &driver->regs->uctrl_stat);
 
 	dprintk(("interrupt stat 0x%x int 0x%x\n", stat, intr));
 
@@ -305,9 +301,8 @@ static void uctrl_do_txn(struct uctrl_txn *txn)
 	}
 }
 
-static void uctrl_get_event_status(void)
+static void uctrl_get_event_status(struct uctrl_driver *driver)
 {
-	struct uctrl_driver *driver = &drv;
 	struct uctrl_txn txn;
 	u8 outbits[2];
 
@@ -317,7 +312,7 @@ static void uctrl_get_event_status(void)
 	txn.inbuf = NULL;
 	txn.outbuf = outbits;
 
-	uctrl_do_txn(&txn);
+	uctrl_do_txn(driver, &txn);
 
 	dprintk(("bytes %x %x\n", (outbits[0] & 0xff), (outbits[1] & 0xff)));
 	driver->status.event_status = 
@@ -325,9 +320,8 @@ static void uctrl_get_event_status(void)
 	dprintk(("ev is %x\n", driver->status.event_status));
 }
 
-static void uctrl_get_external_status(void)
+static void uctrl_get_external_status(struct uctrl_driver *driver)
 {
-	struct uctrl_driver *driver = &drv;
 	struct uctrl_txn txn;
 	u8 outbits[2];
 	int i, v;
@@ -338,7 +332,7 @@ static void uctrl_get_external_status(void)
 	txn.inbuf = NULL;
 	txn.outbuf = outbits;
 
-	uctrl_do_txn(&txn);
+	uctrl_do_txn(driver, &txn);
 
 	dprintk(("bytes %x %x\n", (outbits[0] & 0xff), (outbits[1] & 0xff)));
 	driver->status.external_status = 
@@ -354,71 +348,101 @@ static void uctrl_get_external_status(void)
 	
 }
 
-static int __init ts102_uctrl_init(void)
+static int __devinit uctrl_probe(struct of_device *op,
+				 const struct of_device_id *match)
 {
-	struct uctrl_driver *driver = &drv;
-	int len;
-	struct linux_prom_irqs tmp_irq[2];
-        unsigned int vaddr[2] = { 0, 0 };
-	int tmpnode, uctrlnode = prom_getchild(prom_root_node);
-	int err;
+	struct uctrl_driver *p;
+	int err = -ENOMEM;
 
-	tmpnode = prom_searchsiblings(uctrlnode, "obio");
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	if (!p) {
+		printk(KERN_ERR "uctrl: Unable to allocate device struct.\n");
+		goto out;
+	}
 
-	if (tmpnode)
-	  uctrlnode = prom_getchild(tmpnode);
+	p->regs = of_ioremap(&op->resource[0], 0,
+			     resource_size(&op->resource[0]),
+			     "uctrl");
+	if (!p->regs) {
+		printk(KERN_ERR "uctrl: Unable to map registers.\n");
+		goto out_free;
+	}
 
-	uctrlnode = prom_searchsiblings(uctrlnode, "uctrl");
+	p->irq = op->irqs[0];
+	err = request_irq(p->irq, uctrl_interrupt, 0, "uctrl", p);
+	if (err) {
+		printk(KERN_ERR "uctrl: Unable to register irq.\n");
+		goto out_iounmap;
+	}
 
-	if (!uctrlnode)
-		return -ENODEV;
+	err = misc_register(&uctrl_dev);
+	if (err) {
+		printk(KERN_ERR "uctrl: Unable to register misc device.\n");
+		goto out_free_irq;
+	}
 
-	/* the prom mapped it for us */
-	len = prom_getproperty(uctrlnode, "address", (void *) vaddr,
-			       sizeof(vaddr));
-	driver->regs = (struct uctrl_regs *)vaddr[0];
+	sbus_writel(UCTRL_INTR_RXNE_REQ|UCTRL_INTR_RXNE_MSK, &p->regs->uctrl_intr);
+	printk(KERN_INFO "%s: uctrl regs[0x%p] (irq %d)\n",
+	       op->node->full_name, p->regs, p->irq);
+	uctrl_get_event_status(p);
+	uctrl_get_external_status(p);
 
-	len = prom_getproperty(uctrlnode, "intr", (char *) tmp_irq,
-			       sizeof(tmp_irq));
+	dev_set_drvdata(&op->dev, p);
+	global_driver = p;
 
-	/* Flush device */
-	READUCTLDATA(len);
+out:
+	return err;
 
-	if(!driver->irq) 
-		driver->irq = tmp_irq[0].pri;
+out_free_irq:
+	free_irq(p->irq, p);
 
-	err = request_irq(driver->irq, uctrl_interrupt, 0, "uctrl", driver);
-	if (err) {
-		printk("%s: unable to register irq %d\n",
-		       __func__, driver->irq);
-		return err;
-	}
+out_iounmap:
+	of_iounmap(&op->resource[0], p->regs, resource_size(&op->resource[0]));
 
-	if (misc_register(&uctrl_dev)) {
-		printk("%s: unable to get misc minor %d\n",
-		       __func__, uctrl_dev.minor);
-		free_irq(driver->irq, driver);
-		return -ENODEV;
-	}
+out_free:
+	kfree(p);
+	goto out;
+}
 
-	driver->regs->uctrl_intr = UCTRL_INTR_RXNE_REQ|UCTRL_INTR_RXNE_MSK;
-	printk("uctrl: 0x%p (irq %d)\n", driver->regs, driver->irq);
-	uctrl_get_event_status();
-	uctrl_get_external_status();
-        return 0;
+static int __devexit uctrl_remove(struct of_device *op)
+{
+	struct uctrl_driver *p = dev_get_drvdata(&op->dev);
+
+	if (p) {
+		misc_deregister(&uctrl_dev);
+		free_irq(p->irq, p);
+		of_iounmap(&op->resource[0], p->regs, resource_size(&op->resource[0]));
+		kfree(p);
+	}
+	return 0;
 }
 
-static void __exit ts102_uctrl_cleanup(void)
+static const struct of_device_id uctrl_match[] = {
+	{
+		.name = "uctrl",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, uctrl_match);
+
+static struct of_platform_driver uctrl_driver = {
+	.name		= "uctrl",
+	.match_table	= uctrl_match,
+	.probe		= uctrl_probe,
+	.remove		= __devexit_p(uctrl_remove),
+};
+
+
+static int __init uctrl_init(void)
 {
-	struct uctrl_driver *driver = &drv;
+	return of_register_driver(&uctrl_driver, &of_bus_type);
+}
 
-	misc_deregister(&uctrl_dev);
-	if (driver->irq)
-		free_irq(driver->irq, driver);
-	if (driver->regs)
-		driver->regs = NULL;
+static void __exit uctrl_exit(void)
+{
+	of_unregister_driver(&uctrl_driver);
 }
 
-module_init(ts102_uctrl_init);
-module_exit(ts102_uctrl_cleanup);
+module_init(uctrl_init);
+module_exit(uctrl_exit);
 MODULE_LICENSE("GPL");
diff --git a/drivers/sbus/char/vfc.h b/drivers/sbus/char/vfc.h
deleted file mode 100644
index a5240c52aa0b..000000000000
--- a/drivers/sbus/char/vfc.h
+++ /dev/null
@@ -1,171 +0,0 @@
-#ifndef _LINUX_VFC_H_
-#define _LINUX_VFC_H_
-
-/*
- * The control register for the vfc is at offset 0x4000
- * The first field ram bank is located at offset 0x5000
- * The second field ram bank is at offset 0x7000
- * i2c_reg address the Phillips PCF8584(see notes in vfc_i2c.c) 
- *    data and transmit register.
- * i2c_s1 controls register s1 of the PCF8584
- * i2c_write seems to be similar to i2c_write but I am not 
- *    quite sure why sun uses it
- * 
- * I am also not sure whether or not you can read the fram bank as a
- * whole or whether you must read each word individually from offset
- * 0x5000 as soon as I figure it out I will update this file */
-
-struct vfc_regs {
-	char pad1[0x4000];
-	unsigned int control;  /* Offset 0x4000 */
-	char pad2[0xffb];      /* from offset 0x4004 to 0x5000 */
-	unsigned int fram_bank1; /* Offset 0x5000 */
-	char pad3[0xffb];        /* from offset 0x5004 to 0x6000 */
-	unsigned int i2c_reg; /* Offset 0x6000 */
-	unsigned int i2c_magic2; /* Offset 0x6004 */
-	unsigned int i2c_s1;  /* Offset 0x6008 */
-	unsigned int i2c_write; /* Offset 0x600c */
-	char pad4[0xff0];     /* from offset 0x6010 to 0x7000 */
-	unsigned int fram_bank2; /* Offset 0x7000 */
-	char pad5[0x1000];
-};
-
-#define VFC_SAA9051_NR (13)
-#define VFC_SAA9051_ADDR (0x8a)
-	/* The saa9051 returns the following for its status 
-	 * bit 0 - 0
-	 * bit 1 - SECAM color detected (1=found,0=not found)
-	 * bit 2 - COLOR detected (1=found,0=not found)
-	 * bit 3 - 0
-	 * bit 4 - Field frequency bit (1=60Hz (NTSC), 0=50Hz (PAL))
-	 * bit 5 - 1
-	 * bit 6 - horizontal frequency lock (1=transmitter found,
-	 *                                    0=no transmitter)
-	 * bit 7 - Power on reset bit (1=reset,0=at least one successful 
-	 *                                       read of the status byte)
-	 */
-
-#define VFC_SAA9051_PONRES (0x80)
-#define VFC_SAA9051_HLOCK (0x40)
-#define VFC_SAA9051_FD (0x10)
-#define VFC_SAA9051_CD (0x04)
-#define VFC_SAA9051_CS (0x02)
-
-
-/* The various saa9051 sub addresses */
-
-#define VFC_SAA9051_IDEL (0) 
-#define VFC_SAA9051_HSY_START (1)
-#define VFC_SAA9051_HSY_STOP (2)
-#define VFC_SAA9051_HC_START (3)
-#define VFC_SAA9051_HC_STOP (4)
-#define VFC_SAA9051_HS_START (5)
-#define VFC_SAA9051_HORIZ_PEAK (6)
-#define VFC_SAA9051_HUE (7)
-#define VFC_SAA9051_C1 (8)
-#define VFC_SAA9051_C2 (9)
-#define VFC_SAA9051_C3 (0xa)
-#define VFC_SAA9051_SECAM_DELAY (0xb)
-
-
-/* Bit settings for saa9051 sub address 0x06 */
-
-#define VFC_SAA9051_AP1 (0x01)
-#define VFC_SAA9051_AP2 (0x02)
-#define VFC_SAA9051_COR1 (0x04)
-#define VFC_SAA9051_COR2 (0x08)
-#define VFC_SAA9051_BP1 (0x10)
-#define VFC_SAA9051_BP2 (0x20)
-#define VFC_SAA9051_PF (0x40)
-#define VFC_SAA9051_BY (0x80)
-
-
-/* Bit settings for saa9051 sub address 0x08 */
-
-#define VFC_SAA9051_CCFR0 (0x01)
-#define VFC_SAA9051_CCFR1 (0x02)
-#define VFC_SAA9051_YPN (0x04)
-#define VFC_SAA9051_ALT (0x08)
-#define VFC_SAA9051_CO (0x10)
-#define VFC_SAA9051_VTR (0x20)
-#define VFC_SAA9051_FS (0x40)
-#define VFC_SAA9051_HPLL (0x80)
-
-
-/* Bit settings for saa9051 sub address 9 */
-
-#define VFC_SAA9051_SS0 (0x01)
-#define VFC_SAA9051_SS1 (0x02)
-#define VFC_SAA9051_AFCC (0x04)
-#define VFC_SAA9051_CI (0x08)
-#define VFC_SAA9051_SA9D4 (0x10) /* Don't care bit */
-#define VFC_SAA9051_OEC (0x20)
-#define VFC_SAA9051_OEY (0x40)
-#define VFC_SAA9051_VNL (0x80)
-
-
-/* Bit settings for saa9051 sub address 0x0A */
-
-#define VFC_SAA9051_YDL0 (0x01)
-#define VFC_SAA9051_YDL1 (0x02)
-#define VFC_SAA9051_YDL2 (0x04)
-#define VFC_SAA9051_SS2 (0x08)
-#define VFC_SAA9051_SS3 (0x10)
-#define VFC_SAA9051_YC (0x20)
-#define VFC_SAA9051_CT (0x40)
-#define VFC_SAA9051_SYC (0x80)
-
-
-#define VFC_SAA9051_SA(a,b) ((a)->saa9051_state_array[(b)+1])
-#define vfc_update_saa9051(a) (vfc_i2c_sendbuf((a),VFC_SAA9051_ADDR,\
-					    (a)->saa9051_state_array,\
-					    VFC_SAA9051_NR))
-
-
-struct vfc_dev {
-	volatile struct vfc_regs __iomem *regs;
-	struct vfc_regs *phys_regs;
-	unsigned int control_reg;
-	struct mutex device_lock_mtx;
-	int instance;
-	int busy;
-	unsigned long which_io;
-	unsigned char saa9051_state_array[VFC_SAA9051_NR];
-};
-
-void captstat_reset(struct vfc_dev *);
-void memptr_reset(struct vfc_dev *);
-
-int vfc_pcf8584_init(struct vfc_dev *);
-void vfc_i2c_delay_no_busy(struct vfc_dev *, unsigned long);
-void vfc_i2c_delay(struct vfc_dev *);
-int vfc_i2c_sendbuf(struct vfc_dev *, unsigned char, char *, int) ;
-int vfc_i2c_recvbuf(struct vfc_dev *, unsigned char, char *, int) ;
-int vfc_i2c_reset_bus(struct vfc_dev *);
-int vfc_init_i2c_bus(struct vfc_dev *);
-
-#define VFC_CONTROL_DIAGMODE  0x10000000
-#define VFC_CONTROL_MEMPTR    0x20000000
-#define VFC_CONTROL_CAPTURE   0x02000000
-#define VFC_CONTROL_CAPTRESET 0x04000000
-
-#define VFC_STATUS_CAPTURE    0x08000000
-
-#ifdef VFC_IOCTL_DEBUG
-#define VFC_IOCTL_DEBUG_PRINTK(a) printk a
-#else
-#define VFC_IOCTL_DEBUG_PRINTK(a)
-#endif
-
-#ifdef VFC_I2C_DEBUG
-#define VFC_I2C_DEBUG_PRINTK(a) printk a
-#else
-#define VFC_I2C_DEBUG_PRINTK(a)
-#endif
-
-#endif /* _LINUX_VFC_H_ */
-
-
-
-
-
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
deleted file mode 100644
index 25181bb7d627..000000000000
--- a/drivers/sbus/char/vfc_dev.c
+++ /dev/null
@@ -1,736 +0,0 @@
-/*
- * drivers/sbus/char/vfc_dev.c
- *
- * Driver for the Videopix Frame Grabber.
- * 
- * In order to use the VFC you need to program the video controller
- * chip. This chip is the Phillips SAA9051.  You need to call their
- * documentation ordering line to get the docs.
- *
- * There is very little documentation on the VFC itself.  There is
- * some useful info that can be found in the manuals that come with
- * the card.  I will hopefully write some better docs at a later date.
- *
- * Copyright (C) 1996 Manish Vachharajani (mvachhar@noc.rutgers.edu)
- * */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-#include <linux/mm.h>
-#include <linux/smp_lock.h>
-
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/sbus.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-
-#define VFC_MAJOR (60)
-
-#if 0
-#define VFC_IOCTL_DEBUG
-#endif
-
-#include "vfc.h"
-#include <asm/vfc_ioctls.h>
-
-static const struct file_operations vfc_fops;
-static struct vfc_dev **vfc_dev_lst;
-static char vfcstr[]="vfc";
-static unsigned char saa9051_init_array[VFC_SAA9051_NR] = {
-	0x00, 0x64, 0x72, 0x52,
-	0x36, 0x18, 0xff, 0x20,
-	0xfc, 0x77, 0xe3, 0x50,
-	0x3e
-};
-
-static void vfc_lock_device(struct vfc_dev *dev)
-{
-	mutex_lock(&dev->device_lock_mtx);
-}
-
-static void vfc_unlock_device(struct vfc_dev *dev)
-{
-	mutex_unlock(&dev->device_lock_mtx);
-}
-
-
-static void vfc_captstat_reset(struct vfc_dev *dev)
-{
-	dev->control_reg |= VFC_CONTROL_CAPTRESET;
-	sbus_writel(dev->control_reg, &dev->regs->control);
-	dev->control_reg &= ~VFC_CONTROL_CAPTRESET;
-	sbus_writel(dev->control_reg, &dev->regs->control);
-	dev->control_reg |= VFC_CONTROL_CAPTRESET;
-	sbus_writel(dev->control_reg, &dev->regs->control);
-}
-
-static void vfc_memptr_reset(struct vfc_dev *dev)
-{
-	dev->control_reg |= VFC_CONTROL_MEMPTR;
-	sbus_writel(dev->control_reg, &dev->regs->control);
-	dev->control_reg &= ~VFC_CONTROL_MEMPTR;
-	sbus_writel(dev->control_reg, &dev->regs->control);
-	dev->control_reg |= VFC_CONTROL_MEMPTR; 
-	sbus_writel(dev->control_reg, &dev->regs->control);
-}
-
-static int vfc_csr_init(struct vfc_dev *dev)
-{
-	dev->control_reg = 0x80000000;
-	sbus_writel(dev->control_reg, &dev->regs->control);
-	udelay(200); 
-	dev->control_reg &= ~0x80000000;
-	sbus_writel(dev->control_reg, &dev->regs->control);
-	udelay(100); 
-	sbus_writel(0x0f000000, &dev->regs->i2c_magic2);
-
-	vfc_memptr_reset(dev);
-
-	dev->control_reg &= ~VFC_CONTROL_DIAGMODE;
-	dev->control_reg &= ~VFC_CONTROL_CAPTURE;
-	dev->control_reg |= 0x40000000;
-	sbus_writel(dev->control_reg, &dev->regs->control);
-
-	vfc_captstat_reset(dev);
-
-	return 0;
-}
-
-static int vfc_saa9051_init(struct vfc_dev *dev)
-{
-	int i;
-
-	for (i = 0; i < VFC_SAA9051_NR; i++)
-		dev->saa9051_state_array[i] = saa9051_init_array[i];
-
-	vfc_i2c_sendbuf(dev,VFC_SAA9051_ADDR,
-			dev->saa9051_state_array, VFC_SAA9051_NR);
-	return 0;
-}
-
-static int init_vfc_hw(struct vfc_dev *dev)
-{
-	vfc_lock_device(dev);
-	vfc_csr_init(dev);
-
-	vfc_pcf8584_init(dev);
-	vfc_init_i2c_bus(dev); /* hopefully this doesn't undo the magic
-				  sun code above*/
-	vfc_saa9051_init(dev);
-	vfc_unlock_device(dev);
-	return 0; 
-}
-
-static int init_vfc_devstruct(struct vfc_dev *dev, int instance)
-{
-	dev->instance=instance;
-	mutex_init(&dev->device_lock_mtx);
-	dev->control_reg=0;
-	dev->busy=0;
-	return 0;
-}
-
-static int init_vfc_device(struct sbus_dev *sdev,struct vfc_dev *dev,
-			   int instance)
-{
-	if(dev == NULL) {
-		printk(KERN_ERR "VFC: Bogus pointer passed\n");
-		return -ENOMEM;
-	}
-	printk("Initializing vfc%d\n",instance);
-	dev->regs = NULL;
-	dev->regs = (volatile struct vfc_regs __iomem *)
-		sbus_ioremap(&sdev->resource[0], 0,
-			     sizeof(struct vfc_regs), vfcstr);
-	dev->which_io = sdev->reg_addrs[0].which_io;
-	dev->phys_regs = (struct vfc_regs *) sdev->reg_addrs[0].phys_addr;
-	if (dev->regs == NULL)
-		return -EIO;
-
-	printk("vfc%d: registers mapped at phys_addr: 0x%lx\n    virt_addr: 0x%lx\n",
-	       instance,(unsigned long)sdev->reg_addrs[0].phys_addr,(unsigned long)dev->regs);
-
-	if (init_vfc_devstruct(dev, instance))
-		return -EINVAL;
-	if (init_vfc_hw(dev))
-		return -EIO;
-	return 0;
-}
-
-
-static struct vfc_dev *vfc_get_dev_ptr(int instance)
-{
-	return vfc_dev_lst[instance];
-}
-
-static DEFINE_SPINLOCK(vfc_dev_lock);
-
-static int vfc_open(struct inode *inode, struct file *file) 
-{
-	struct vfc_dev *dev;
-
-	lock_kernel();
-	spin_lock(&vfc_dev_lock);
-	dev = vfc_get_dev_ptr(iminor(inode));
-	if (dev == NULL) {
-		spin_unlock(&vfc_dev_lock);
-		unlock_kernel();
-		return -ENODEV;
-	}
-	if (dev->busy) {
-		spin_unlock(&vfc_dev_lock);
-		unlock_kernel();
-		return -EBUSY;
-	}
-
-	dev->busy = 1;
-	spin_unlock(&vfc_dev_lock);
-
-	vfc_lock_device(dev);
-	
-	vfc_csr_init(dev);
-	vfc_pcf8584_init(dev);
-	vfc_init_i2c_bus(dev);
-	vfc_saa9051_init(dev);
-	vfc_memptr_reset(dev);
-	vfc_captstat_reset(dev);
-	
-	vfc_unlock_device(dev);
-	unlock_kernel();
-	return 0;
-}
-
-static int vfc_release(struct inode *inode,struct file *file) 
-{
-	struct vfc_dev *dev;
-
-	spin_lock(&vfc_dev_lock);
-	dev = vfc_get_dev_ptr(iminor(inode));
-	if (!dev || !dev->busy) {
-		spin_unlock(&vfc_dev_lock);
-		return -EINVAL;
-	}
-	dev->busy = 0;
-	spin_unlock(&vfc_dev_lock);
-	return 0;
-}
-
-static int vfc_debug(struct vfc_dev *dev, int cmd, void __user *argp)
-{
-	struct vfc_debug_inout inout;
-	unsigned char *buffer;
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	switch(cmd) {
-	case VFC_I2C_SEND:
-		if(copy_from_user(&inout, argp, sizeof(inout)))
-			return -EFAULT;
-
-		buffer = kmalloc(inout.len, GFP_KERNEL);
-		if (buffer == NULL)
-			return -ENOMEM;
-
-		if(copy_from_user(buffer, inout.buffer, inout.len)) {
-			kfree(buffer);
-			return -EFAULT;
-		}
-		
-
-		vfc_lock_device(dev);
-		inout.ret=
-			vfc_i2c_sendbuf(dev,inout.addr & 0xff,
-					buffer,inout.len);
-
-		if (copy_to_user(argp,&inout,sizeof(inout))) {
-			vfc_unlock_device(dev);
-			kfree(buffer);
-			return -EFAULT;
-		}
-		vfc_unlock_device(dev);
-
-		break;
-	case VFC_I2C_RECV:
-		if (copy_from_user(&inout, argp, sizeof(inout)))
-			return -EFAULT;
-
-		buffer = kzalloc(inout.len, GFP_KERNEL);
-		if (buffer == NULL)
-			return -ENOMEM;
-
-		vfc_lock_device(dev);
-		inout.ret=
-			vfc_i2c_recvbuf(dev,inout.addr & 0xff
-					,buffer,inout.len);
-		vfc_unlock_device(dev);
-		
-		if (copy_to_user(inout.buffer, buffer, inout.len)) {
-			kfree(buffer);
-			return -EFAULT;
-		}
-		if (copy_to_user(argp,&inout,sizeof(inout))) {
-			kfree(buffer);
-			return -EFAULT;
-		}
-		kfree(buffer);
-		break;
-	default:
-		return -EINVAL;
-	};
-
-	return 0;
-}
-
-static int vfc_capture_start(struct vfc_dev *dev)
-{
-	vfc_captstat_reset(dev);
-	dev->control_reg = sbus_readl(&dev->regs->control);
-	if((dev->control_reg & VFC_STATUS_CAPTURE)) {
-		printk(KERN_ERR "vfc%d: vfc capture status not reset\n",
-		       dev->instance);
-		return -EIO;
-	}
-
-	vfc_lock_device(dev);
-	dev->control_reg &= ~VFC_CONTROL_CAPTURE;
-	sbus_writel(dev->control_reg, &dev->regs->control);
-	dev->control_reg |= VFC_CONTROL_CAPTURE;
-	sbus_writel(dev->control_reg, &dev->regs->control);
-	dev->control_reg &= ~VFC_CONTROL_CAPTURE;
-	sbus_writel(dev->control_reg, &dev->regs->control);
-	vfc_unlock_device(dev);
-
-	return 0;
-}
-
-static int vfc_capture_poll(struct vfc_dev *dev)
-{
-	int timeout = 1000;
-
-	while (!timeout--) {
-		if (sbus_readl(&dev->regs->control) & VFC_STATUS_CAPTURE)
-			break;
-		vfc_i2c_delay_no_busy(dev, 100);
-	}
-	if(!timeout) {
-		printk(KERN_WARNING "vfc%d: capture timed out\n",
-		       dev->instance);
-		return -ETIMEDOUT;
-	}
-	return 0;
-}
-
-
-
-static int vfc_set_control_ioctl(struct inode *inode, struct file *file, 
-			  struct vfc_dev *dev, unsigned long arg) 
-{
-	int setcmd, ret = 0;
-
-	if (copy_from_user(&setcmd,(void __user *)arg,sizeof(unsigned int)))
-		return -EFAULT;
-
-	VFC_IOCTL_DEBUG_PRINTK(("vfc%d: IOCTL(VFCSCTRL) arg=0x%x\n",
-				dev->instance,setcmd));
-
-	switch(setcmd) {
-	case MEMPRST:
-		vfc_lock_device(dev);
-		vfc_memptr_reset(dev);
-		vfc_unlock_device(dev);
-		ret=0;
-		break;
-	case CAPTRCMD:
-		vfc_capture_start(dev);
-		vfc_capture_poll(dev);
-		break;
-	case DIAGMODE:
-		if(capable(CAP_SYS_ADMIN)) {
-			vfc_lock_device(dev);
-			dev->control_reg |= VFC_CONTROL_DIAGMODE;
-			sbus_writel(dev->control_reg, &dev->regs->control);
-			vfc_unlock_device(dev);
-			ret = 0;
-		} else {
-			ret = -EPERM; 
-		}
-		break;
-	case NORMMODE:
-		vfc_lock_device(dev);
-		dev->control_reg &= ~VFC_CONTROL_DIAGMODE;
-		sbus_writel(dev->control_reg, &dev->regs->control);
-		vfc_unlock_device(dev);
-		ret = 0;
-		break;
-	case CAPTRSTR:
-		vfc_capture_start(dev);
-		ret = 0;
-		break;
-	case CAPTRWAIT:
-		vfc_capture_poll(dev);
-		ret = 0;
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	};
-
-	return ret;
-}
-
-
-static int vfc_port_change_ioctl(struct inode *inode, struct file *file,
-				 struct vfc_dev *dev, unsigned long arg)
-{
-	int ret = 0;
-	int cmd;
-
-	if(copy_from_user(&cmd, (void __user *)arg, sizeof(unsigned int))) {
-		VFC_IOCTL_DEBUG_PRINTK(("vfc%d: User passed bogus pointer to "
-					"vfc_port_change_ioctl\n",
-					dev->instance));
-		return -EFAULT;
-	}
-	
-	VFC_IOCTL_DEBUG_PRINTK(("vfc%d: IOCTL(VFCPORTCHG) arg=0x%x\n",
-				dev->instance, cmd));
-
-	switch(cmd) {
-	case 1:
-	case 2:
-		VFC_SAA9051_SA(dev,VFC_SAA9051_HSY_START) = 0x72; 
-		VFC_SAA9051_SA(dev,VFC_SAA9051_HSY_STOP) = 0x52;
-		VFC_SAA9051_SA(dev,VFC_SAA9051_HC_START) = 0x36;
-		VFC_SAA9051_SA(dev,VFC_SAA9051_HC_STOP) = 0x18;
-		VFC_SAA9051_SA(dev,VFC_SAA9051_HORIZ_PEAK) = VFC_SAA9051_BP2;
-		VFC_SAA9051_SA(dev,VFC_SAA9051_C3) = VFC_SAA9051_CT | VFC_SAA9051_SS3;
-		VFC_SAA9051_SA(dev,VFC_SAA9051_SECAM_DELAY) = 0x3e;
-		break;
-	case 3:
-		VFC_SAA9051_SA(dev,VFC_SAA9051_HSY_START) = 0x3a;
-		VFC_SAA9051_SA(dev,VFC_SAA9051_HSY_STOP) = 0x17;
-		VFC_SAA9051_SA(dev,VFC_SAA9051_HC_START) = 0xfa;
-		VFC_SAA9051_SA(dev,VFC_SAA9051_HC_STOP) = 0xde;
-		VFC_SAA9051_SA(dev,VFC_SAA9051_HORIZ_PEAK) =
-			VFC_SAA9051_BY | VFC_SAA9051_PF | VFC_SAA9051_BP2;
-		VFC_SAA9051_SA(dev,VFC_SAA9051_C3) = VFC_SAA9051_YC;
-		VFC_SAA9051_SA(dev,VFC_SAA9051_SECAM_DELAY) = 0;
-		VFC_SAA9051_SA(dev,VFC_SAA9051_C2) &=
-			~(VFC_SAA9051_SS0 | VFC_SAA9051_SS1);
-		break;
-	default:
-		ret = -EINVAL;
-		return ret;
-		break;
-	}
-
-	switch(cmd) {
-	case 1:
-		VFC_SAA9051_SA(dev,VFC_SAA9051_C2) |=
-			(VFC_SAA9051_SS0 | VFC_SAA9051_SS1);
-		break;
-	case 2:
-		VFC_SAA9051_SA(dev,VFC_SAA9051_C2) &=
-			~(VFC_SAA9051_SS0 | VFC_SAA9051_SS1);
-		VFC_SAA9051_SA(dev,VFC_SAA9051_C2) |= VFC_SAA9051_SS0; 
-		break;
-	case 3:
-		break;
-	default:
-		ret = -EINVAL;
-		return ret;
-		break;
-	}
-	VFC_SAA9051_SA(dev,VFC_SAA9051_C3) &= ~(VFC_SAA9051_SS2);
-	ret=vfc_update_saa9051(dev);
-	udelay(500);
-	VFC_SAA9051_SA(dev,VFC_SAA9051_C3) |= (VFC_SAA9051_SS2);
-	ret=vfc_update_saa9051(dev);
-	return ret;
-}
-
-static int vfc_set_video_ioctl(struct inode *inode, struct file *file,
-			       struct vfc_dev *dev, unsigned long arg)
-{
-	int ret = 0;
-	int cmd;
-
-	if(copy_from_user(&cmd, (void __user *)arg, sizeof(unsigned int))) {
-		VFC_IOCTL_DEBUG_PRINTK(("vfc%d: User passed bogus pointer to "
-					"vfc_set_video_ioctl\n",
-					dev->instance));
-		return ret;
-	}
-	
-	VFC_IOCTL_DEBUG_PRINTK(("vfc%d: IOCTL(VFCSVID) arg=0x%x\n",
-				dev->instance, cmd));
-	switch(cmd) {
-	case STD_NTSC:
-		VFC_SAA9051_SA(dev,VFC_SAA9051_C1) &= ~VFC_SAA9051_ALT;
-		VFC_SAA9051_SA(dev,VFC_SAA9051_C1) |= VFC_SAA9051_YPN | 
-			VFC_SAA9051_CCFR0 | VFC_SAA9051_CCFR1 | VFC_SAA9051_FS;
-		ret = vfc_update_saa9051(dev);
-		break;
-	case STD_PAL:
-		VFC_SAA9051_SA(dev,VFC_SAA9051_C1) &= ~(VFC_SAA9051_YPN | 
-							VFC_SAA9051_CCFR1 | 
-							VFC_SAA9051_CCFR0 |
-							VFC_SAA9051_FS);
-		VFC_SAA9051_SA(dev,VFC_SAA9051_C1) |= VFC_SAA9051_ALT;
-		ret = vfc_update_saa9051(dev);
-		break;
-
-	case COLOR_ON:
-		VFC_SAA9051_SA(dev,VFC_SAA9051_C1) |= VFC_SAA9051_CO;
-		VFC_SAA9051_SA(dev,VFC_SAA9051_HORIZ_PEAK) &=
-			~(VFC_SAA9051_BY | VFC_SAA9051_PF);
-		ret = vfc_update_saa9051(dev);
-		break;
-	case MONO:
-		VFC_SAA9051_SA(dev,VFC_SAA9051_C1) &= ~(VFC_SAA9051_CO);
-		VFC_SAA9051_SA(dev,VFC_SAA9051_HORIZ_PEAK) |=
-			(VFC_SAA9051_BY | VFC_SAA9051_PF);
-		ret = vfc_update_saa9051(dev);
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	};
-
-	return ret;
-}
-
-static int vfc_get_video_ioctl(struct inode *inode, struct file *file,
-			       struct vfc_dev *dev, unsigned long arg)
-{
-	int ret = 0;
-	unsigned int status = NO_LOCK;
-	unsigned char buf[1];
-
-	if(vfc_i2c_recvbuf(dev, VFC_SAA9051_ADDR, buf, 1)) {
-		printk(KERN_ERR "vfc%d: Unable to get status\n",
-		       dev->instance);
-		return -EIO;
-	}
-
-	if(buf[0] & VFC_SAA9051_HLOCK) {
-		status = NO_LOCK;
-	} else if(buf[0] & VFC_SAA9051_FD) {
-		if(buf[0] & VFC_SAA9051_CD)
-			status = NTSC_COLOR;
-		else
-			status = NTSC_NOCOLOR;
-	} else {
-		if(buf[0] & VFC_SAA9051_CD)
-			status = PAL_COLOR;
-		else
-			status = PAL_NOCOLOR;
-	}
-	VFC_IOCTL_DEBUG_PRINTK(("vfc%d: IOCTL(VFCGVID) returning status 0x%x; "
-				"buf[0]=%x\n", dev->instance, status, buf[0]));
-
-	if (copy_to_user((void __user *)arg,&status,sizeof(unsigned int))) {
-		VFC_IOCTL_DEBUG_PRINTK(("vfc%d: User passed bogus pointer to "
-					"vfc_get_video_ioctl\n",
-					dev->instance));
-		return ret;
-	}
-	return ret;
-}
-
-static int vfc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-	      unsigned long arg) 
-{
-	int ret = 0;
-	unsigned int tmp;
-	struct vfc_dev *dev;
-	void __user *argp = (void __user *)arg;
-
-	dev = vfc_get_dev_ptr(iminor(inode));
-	if(dev == NULL)
-		return -ENODEV;
-	
-	switch(cmd & 0x0000ffff) {
-	case VFCGCTRL:
-#if 0
-		VFC_IOCTL_DEBUG_PRINTK(("vfc%d: IOCTL(VFCGCTRL)\n", dev->instance));
-#endif
-		tmp = sbus_readl(&dev->regs->control);
-		if(copy_to_user(argp, &tmp, sizeof(unsigned int))) {
-			ret = -EFAULT;
-			break;
-		}
-		ret = 0;
-		break;
-	case VFCSCTRL:
-		ret = vfc_set_control_ioctl(inode, file, dev, arg);
-		break;
-	case VFCGVID:
-		ret = vfc_get_video_ioctl(inode, file, dev, arg);
-		break;
-	case VFCSVID:
-		ret = vfc_set_video_ioctl(inode, file, dev, arg);
-		break;
-	case VFCHUE:
-		VFC_IOCTL_DEBUG_PRINTK(("vfc%d: IOCTL(VFCHUE)\n", dev->instance));
-		if(copy_from_user(&tmp,argp,sizeof(unsigned int))) {
-			VFC_IOCTL_DEBUG_PRINTK(("vfc%d: User passed bogus pointer "
-						"to IOCTL(VFCHUE)", dev->instance));
-			ret = -EFAULT;
-		} else {
-			VFC_SAA9051_SA(dev,VFC_SAA9051_HUE) = tmp;
-			vfc_update_saa9051(dev);
-			ret = 0;
-		}
-		break;
-	case VFCPORTCHG:
-		ret = vfc_port_change_ioctl(inode, file, dev, arg);
-		break;
-	case VFCRDINFO:
-		ret = -EINVAL;
-		VFC_IOCTL_DEBUG_PRINTK(("vfc%d: IOCTL(VFCRDINFO)\n", dev->instance));
-		break;
-	default:
-		ret = vfc_debug(vfc_get_dev_ptr(iminor(inode)), cmd, argp);
-		break;
-	};
-
-	return ret;
-}
-
-static int vfc_mmap(struct file *file, struct vm_area_struct *vma) 
-{
-	unsigned int map_size, ret, map_offset;
-	struct vfc_dev *dev;
-	
-	dev = vfc_get_dev_ptr(iminor(file->f_path.dentry->d_inode));
-	if(dev == NULL)
-		return -ENODEV;
-
-	map_size = vma->vm_end - vma->vm_start;
-	if(map_size > sizeof(struct vfc_regs)) 
-		map_size = sizeof(struct vfc_regs);
-
-	vma->vm_flags |=
-		(VM_MAYREAD | VM_MAYWRITE | VM_MAYSHARE);
-	map_offset = (unsigned int) (long)dev->phys_regs;
-	ret = io_remap_pfn_range(vma, vma->vm_start,
-				  MK_IOSPACE_PFN(dev->which_io,
-					map_offset >> PAGE_SHIFT),
-				  map_size, vma->vm_page_prot);
-
-	if(ret)
-		return -EAGAIN;
-
-	return 0;
-}
-
-
-static const struct file_operations vfc_fops = {
-	.owner =	THIS_MODULE,
-	.llseek =	no_llseek,
-	.ioctl =	vfc_ioctl,
-	.mmap =		vfc_mmap,
-	.open =		vfc_open,
-	.release =	vfc_release,
-};
-
-static int vfc_probe(void)
-{
-	struct sbus_bus *sbus;
-	struct sbus_dev *sdev = NULL;
-	int ret;
-	int instance = 0, cards = 0;
-
-	for_all_sbusdev(sdev, sbus) {
-		if (strcmp(sdev->prom_name, "vfc") == 0) {
-			cards++;
-			continue;
-		}
-	}
-
-	if (!cards)
-		return -ENODEV;
-
-	vfc_dev_lst = kcalloc(cards + 1, sizeof(struct vfc_dev*), GFP_KERNEL);
-	if (vfc_dev_lst == NULL)
-		return -ENOMEM;
-	vfc_dev_lst[cards] = NULL;
-
-	ret = register_chrdev(VFC_MAJOR, vfcstr, &vfc_fops);
-	if(ret) {
-		printk(KERN_ERR "Unable to get major number %d\n", VFC_MAJOR);
-		kfree(vfc_dev_lst);
-		return -EIO;
-	}
-	instance = 0;
-	for_all_sbusdev(sdev, sbus) {
-		if (strcmp(sdev->prom_name, "vfc") == 0) {
-			vfc_dev_lst[instance]=(struct vfc_dev *)
-				kmalloc(sizeof(struct vfc_dev), GFP_KERNEL);
-			if (vfc_dev_lst[instance] == NULL)
-				return -ENOMEM;
-			ret = init_vfc_device(sdev,
-					      vfc_dev_lst[instance],
-					      instance);
-			if(ret) {
-				printk(KERN_ERR "Unable to initialize"
-				       " vfc%d device\n",
-				       instance);
-			} else {
-			}
-		
-			instance++;
-			continue;
-		}
-	}
-
-	return 0;
-}
-
-#ifdef MODULE
-int init_module(void)
-#else 
-int vfc_init(void)
-#endif
-{
-	return vfc_probe();
-}
-
-#ifdef MODULE
-static void deinit_vfc_device(struct vfc_dev *dev)
-{
-	if(dev == NULL)
-		return;
-	sbus_iounmap(dev->regs, sizeof(struct vfc_regs));
-	kfree(dev);
-}
-
-void cleanup_module(void)
-{
-	struct vfc_dev **devp;
-
-	unregister_chrdev(VFC_MAJOR,vfcstr);
-
-	for (devp = vfc_dev_lst; *devp; devp++)
-		deinit_vfc_device(*devp);
-
-	kfree(vfc_dev_lst);
-	return;
-}
-#endif
-
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/sbus/char/vfc_i2c.c b/drivers/sbus/char/vfc_i2c.c
deleted file mode 100644
index 32b986e0ed78..000000000000
--- a/drivers/sbus/char/vfc_i2c.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * drivers/sbus/char/vfc_i2c.c
- *
- * Driver for the Videopix Frame Grabber.
- * 
- * Functions that support the Phillips i2c(I squared C) bus on the vfc
- *  Documentation for the Phillips I2C bus can be found on the 
- *  phillips home page
- *
- * Copyright (C) 1996 Manish Vachharajani (mvachhar@noc.rutgers.edu)
- *
- */
-
-/* NOTE: It seems to me that the documentation regarding the
-pcd8584t/pcf8584 does not show the correct way to address the i2c bus.
-Based on the information on the I2C bus itself and the remainder of
-the Phillips docs the following algorithms appear to be correct.  I am
-fairly certain that the flowcharts in the phillips docs are wrong. */
-
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/sbus.h>
-
-#if 0 
-#define VFC_I2C_DEBUG
-#endif
-
-#include "vfc.h"
-#include "vfc_i2c.h"
-
-#define WRITE_S1(__val) \
-	sbus_writel(__val, &dev->regs->i2c_s1)
-#define WRITE_REG(__val) \
-	sbus_writel(__val, &dev->regs->i2c_reg)
-
-#define VFC_I2C_READ (0x1)
-#define VFC_I2C_WRITE (0x0)
-     
-/****** 
-  The i2c bus controller chip on the VFC is a pcd8584t, but
-  phillips claims it doesn't exist.  As far as I can tell it is
-  identical to the PCF8584 so I treat it like it is the pcf8584.
-  
-  NOTE: The pcf8584 only cares
-  about the msb of the word you feed it 
-*****/
-
-int vfc_pcf8584_init(struct vfc_dev *dev) 
-{
-	/* This will also choose register S0_OWN so we can set it. */
-	WRITE_S1(RESET);
-
-	/* The pcf8584 shifts this value left one bit and uses
-	 * it as its i2c bus address.
-	 */
-	WRITE_REG(0x55000000);
-
-	/* This will set the i2c bus at the same speed sun uses,
-	 * and set another magic bit.
-	 */
-	WRITE_S1(SELECT(S2));
-	WRITE_REG(0x14000000);
-	
-	/* Enable the serial port, idle the i2c bus and set
-	 * the data reg to s0.
-	 */
-	WRITE_S1(CLEAR_I2C_BUS);
-	udelay(100);
-	return 0;
-}
-
-void vfc_i2c_delay_no_busy(struct vfc_dev *dev, unsigned long usecs) 
-{
-	schedule_timeout_uninterruptible(usecs_to_jiffies(usecs));
-}
-
-void inline vfc_i2c_delay(struct vfc_dev *dev) 
-{ 
-	vfc_i2c_delay_no_busy(dev, 100);
-}
-
-int vfc_init_i2c_bus(struct vfc_dev *dev)
-{
-	WRITE_S1(ENABLE_SERIAL | SELECT(S0) | ACK);
-	vfc_i2c_reset_bus(dev);
-	return 0;
-}
-
-int vfc_i2c_reset_bus(struct vfc_dev *dev) 
-{
-	VFC_I2C_DEBUG_PRINTK((KERN_DEBUG "vfc%d: Resetting the i2c bus\n",
-			      dev->instance));
-	if(dev == NULL)
-		return -EINVAL;
-	if(dev->regs == NULL)
-		return -EINVAL;
-	WRITE_S1(SEND_I2C_STOP);
-	WRITE_S1(SEND_I2C_STOP | ACK);
-	vfc_i2c_delay(dev);
-	WRITE_S1(CLEAR_I2C_BUS);
-	VFC_I2C_DEBUG_PRINTK((KERN_DEBUG "vfc%d: I2C status %x\n",
-			      dev->instance,
-			      sbus_readl(&dev->regs->i2c_s1)));
-	return 0;
-}
-
-static int vfc_i2c_wait_for_bus(struct vfc_dev *dev)
-{
-	int timeout = 1000; 
-
-	while(!(sbus_readl(&dev->regs->i2c_s1) & BB)) {
-		if(!(timeout--))
-			return -ETIMEDOUT;
-		vfc_i2c_delay(dev);
-	}
-	return 0;
-}
-
-static int vfc_i2c_wait_for_pin(struct vfc_dev *dev, int ack)
-{
-	int timeout = 1000; 
-	int s1;
-
-	while ((s1 = sbus_readl(&dev->regs->i2c_s1)) & PIN) {
-		if (!(timeout--))
-			return -ETIMEDOUT;
-		vfc_i2c_delay(dev);
-	}
-	if (ack == VFC_I2C_ACK_CHECK) {
-		if(s1 & LRB)
-			return -EIO; 
-	}
-	return 0;
-}
-
-#define SHIFT(a) ((a) << 24)
-static int vfc_i2c_xmit_addr(struct vfc_dev *dev, unsigned char addr,
-			     char mode)
-{ 
-	int ret, raddr;
-#if 1
-	WRITE_S1(SEND_I2C_STOP | ACK);
-	WRITE_S1(SELECT(S0) | ENABLE_SERIAL);
-	vfc_i2c_delay(dev);
-#endif
-
-	switch(mode) {
-	case VFC_I2C_READ:
-		raddr = SHIFT(((unsigned int)addr | 0x1));
-		WRITE_REG(raddr);
-		VFC_I2C_DEBUG_PRINTK(("vfc%d: receiving from i2c addr 0x%x\n",
-				      dev->instance, addr | 0x1));
-		break;
-	case VFC_I2C_WRITE:
-		raddr = SHIFT((unsigned int)addr & ~0x1);
-		WRITE_REG(raddr);
-		VFC_I2C_DEBUG_PRINTK(("vfc%d: sending to i2c addr 0x%x\n",
-				      dev->instance, addr & ~0x1));
-		break;
-	default:
-		return -EINVAL;
-	};
-
-	WRITE_S1(SEND_I2C_START);
-	vfc_i2c_delay(dev);
-	ret = vfc_i2c_wait_for_pin(dev,VFC_I2C_ACK_CHECK); /* We wait
-							      for the
-							      i2c send
-							      to finish
-							      here but
-							      Sun
-							      doesn't,
-							      hmm */
-	if (ret) {
-		printk(KERN_ERR "vfc%d: VFC xmit addr timed out or no ack\n",
-		       dev->instance);
-		return ret;
-	} else if (mode == VFC_I2C_READ) {
-		if ((ret = sbus_readl(&dev->regs->i2c_reg) & 0xff000000) != raddr) {
-			printk(KERN_WARNING 
-			       "vfc%d: returned slave address "
-			       "mismatch(%x,%x)\n",
-			       dev->instance, raddr, ret);
-		}
-	}	
-	return 0;
-}
-
-static int vfc_i2c_xmit_byte(struct vfc_dev *dev,unsigned char *byte)
-{
-	int ret;
-	u32 val = SHIFT((unsigned int)*byte);
-
-	WRITE_REG(val);
-
-	ret = vfc_i2c_wait_for_pin(dev, VFC_I2C_ACK_CHECK); 
-	switch(ret) {
-	case -ETIMEDOUT: 
-		printk(KERN_ERR "vfc%d: VFC xmit byte timed out or no ack\n",
-		       dev->instance);
-		break;
-	case -EIO:
-		ret = XMIT_LAST_BYTE;
-		break;
-	default:
-		break;
-	};
-
-	return ret;
-}
-
-static int vfc_i2c_recv_byte(struct vfc_dev *dev, unsigned char *byte,
-			     int last)
-{
-	int ret;
-
-	if (last) {
-		WRITE_REG(NEGATIVE_ACK);
-		VFC_I2C_DEBUG_PRINTK(("vfc%d: sending negative ack\n",
-				      dev->instance));
-	} else {
-		WRITE_S1(ACK);
-	}
-
-	ret = vfc_i2c_wait_for_pin(dev, VFC_I2C_NO_ACK_CHECK);
-	if(ret) {
-		printk(KERN_ERR "vfc%d: "
-		       "VFC recv byte timed out\n",
-		       dev->instance);
-	}
-	*byte = (sbus_readl(&dev->regs->i2c_reg)) >> 24;
-	return ret;
-}
-
-int vfc_i2c_recvbuf(struct vfc_dev *dev, unsigned char addr,
-		    char *buf, int count)
-{
-	int ret, last;
-
-	if(!(count && buf && dev && dev->regs) )
-		return -EINVAL;
-
-	if ((ret = vfc_i2c_wait_for_bus(dev))) {
-		printk(KERN_ERR "vfc%d: VFC I2C bus busy\n", dev->instance);
-		return ret;
-	}
-
-	if ((ret = vfc_i2c_xmit_addr(dev, addr, VFC_I2C_READ))) {
-		WRITE_S1(SEND_I2C_STOP);
-		vfc_i2c_delay(dev);
-		return ret;
-	}
-	
-	last = 0;
-	while (count--) {
-		if (!count)
-			last = 1;
-		if ((ret = vfc_i2c_recv_byte(dev, buf, last))) {
-			printk(KERN_ERR "vfc%d: "
-			       "VFC error while receiving byte\n",
-			       dev->instance);
-			WRITE_S1(SEND_I2C_STOP);
-			ret = -EINVAL;
-		}
-		buf++;
-	}
-	WRITE_S1(SEND_I2C_STOP | ACK);
-	vfc_i2c_delay(dev);
-	return ret;
-}
-
-int vfc_i2c_sendbuf(struct vfc_dev *dev, unsigned char addr, 
-		    char *buf, int count) 
-{
-	int ret;
-	
-	if (!(buf && dev && dev->regs))
-		return -EINVAL;
-	
-	if ((ret = vfc_i2c_wait_for_bus(dev))) {
-		printk(KERN_ERR "vfc%d: VFC I2C bus busy\n", dev->instance);
-		return ret;
-	}
-	
-	if ((ret = vfc_i2c_xmit_addr(dev, addr, VFC_I2C_WRITE))) {
-		WRITE_S1(SEND_I2C_STOP);
-		vfc_i2c_delay(dev);
-		return ret;
-	}
-	
-	while(count--) {
-		ret = vfc_i2c_xmit_byte(dev, buf);
-		switch(ret) {
-		case XMIT_LAST_BYTE:
-			VFC_I2C_DEBUG_PRINTK(("vfc%d: "
-					      "Receiver ended transmission with "
-					      " %d bytes remaining\n",
-					      dev->instance, count));
-			ret = 0;
-			goto done;
-			break;
-		case 0:
-			break;
-		default:
-			printk(KERN_ERR "vfc%d: "
-			       "VFC error while sending byte\n", dev->instance);
-			break;
-		};
-
-		buf++;
-	}
-done:
-	WRITE_S1(SEND_I2C_STOP | ACK);
-	vfc_i2c_delay(dev);
-	return ret;
-}
-
-
-
-
-
-
-
-
-
diff --git a/drivers/sbus/char/vfc_i2c.h b/drivers/sbus/char/vfc_i2c.h
deleted file mode 100644
index a2e6973209d5..000000000000
--- a/drivers/sbus/char/vfc_i2c.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef _LINUX_VFC_I2C_H_
-#define _LINUX_VFC_I2C_H_
-
-/* control bits */
-#define PIN  (0x80000000)
-#define ESO  (0x40000000)
-#define ES1  (0x20000000)
-#define ES2  (0x10000000)
-#define ENI  (0x08000000)
-#define STA  (0x04000000)
-#define STO  (0x02000000)
-#define ACK  (0x01000000)
-
-/* status bits */
-#define STS  (0x20000000)
-#define BER  (0x10000000)
-#define LRB  (0x08000000)
-#define AAS  (0x04000000)
-#define LAB  (0x02000000)
-#define BB   (0x01000000)
-
-#define SEND_I2C_START (PIN | ESO | STA)
-#define SEND_I2C_STOP (PIN | ESO | STO)
-#define CLEAR_I2C_BUS (PIN | ESO | ACK)
-#define NEGATIVE_ACK ((ESO) & ~ACK)
-
-#define SELECT(a) (a)
-#define S0 (PIN | ESO | ES1)
-#define S0_OWN (PIN)
-#define S2 (PIN | ES1)
-#define S3 (PIN | ES2)
-
-#define ENABLE_SERIAL (PIN | ESO)
-#define DISABLE_SERIAL (PIN)
-#define RESET (PIN)
-
-#define XMIT_LAST_BYTE (1)
-#define VFC_I2C_ACK_CHECK (1)
-#define VFC_I2C_NO_ACK_CHECK (0)
-
-#endif /* _LINUX_VFC_I2C_H_ */
-
-
-
diff --git a/drivers/sbus/dvma.c b/drivers/sbus/dvma.c
deleted file mode 100644
index ab0d2de3324c..000000000000
--- a/drivers/sbus/dvma.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* dvma.c:  Routines that are used to access DMA on the Sparc SBus.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-
-#include <asm/oplib.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/sbus.h>
-
-struct sbus_dma *dma_chain;
-
-static void __init init_one_dvma(struct sbus_dma *dma, int num_dma)
-{
-	printk("dma%d: ", num_dma);
-	
-	dma->next = NULL;
-	dma->running = 0;      /* No transfers going on as of yet */
-	dma->allocated = 0;    /* No one has allocated us yet */
-	switch(sbus_readl(dma->regs + DMA_CSR)&DMA_DEVICE_ID) {
-	case DMA_VERS0:
-		dma->revision = dvmarev0;
-		printk("Revision 0 ");
-		break;
-	case DMA_ESCV1:
-		dma->revision = dvmaesc1;
-		printk("ESC Revision 1 ");
-		break;
-	case DMA_VERS1:
-		dma->revision = dvmarev1;
-		printk("Revision 1 ");
-		break;
-	case DMA_VERS2:
-		dma->revision = dvmarev2;
-		printk("Revision 2 ");
-		break;
-	case DMA_VERHME:
-		dma->revision = dvmahme;
-		printk("HME DVMA gate array ");
-		break;
-	case DMA_VERSPLUS:
-		dma->revision = dvmarevplus;
-		printk("Revision 1 PLUS ");
-		break;
-	default:
-		printk("unknown dma version %08x",
-		       sbus_readl(dma->regs + DMA_CSR) & DMA_DEVICE_ID);
-		dma->allocated = 1;
-		break;
-	}
-	printk("\n");
-}
-
-/* Probe this SBus DMA module(s) */
-void __init dvma_init(struct sbus_bus *sbus)
-{
-	struct sbus_dev *this_dev;
-	struct sbus_dma *dma;
-	struct sbus_dma *dchain;
-	static int num_dma = 0;
-
-	for_each_sbusdev(this_dev, sbus) {
-		char *name = this_dev->prom_name;
-		int hme = 0;
-
-		if(!strcmp(name, "SUNW,fas"))
-			hme = 1;
-		else if(strcmp(name, "dma") &&
-			strcmp(name, "ledma") &&
-			strcmp(name, "espdma"))
-			continue;
-
-		/* Found one... */
-		dma = kmalloc(sizeof(struct sbus_dma), GFP_ATOMIC);
-
-		dma->sdev = this_dev;
-
-		/* Put at end of dma chain */
-		dchain = dma_chain;
-		if(dchain) {
-			while(dchain->next)
-				dchain = dchain->next;
-			dchain->next = dma;
-		} else {
-			/* We're the first in line */
-			dma_chain = dma;
-		}
-
-		dma->regs = sbus_ioremap(&dma->sdev->resource[0], 0,
-					 dma->sdev->resource[0].end - dma->sdev->resource[0].start + 1,
-					 "dma");
-
-		dma->node = dma->sdev->prom_node;
-		
-		init_one_dvma(dma, num_dma++);
-	}
-}
-
-#ifdef CONFIG_SUN4
-
-#include <asm/sun4paddr.h>
-
-void __init sun4_dvma_init(void)
-{
-	struct sbus_dma *dma;
-	struct resource r;
-
-	if(sun4_dma_physaddr) {
-		dma = kmalloc(sizeof(struct sbus_dma), GFP_ATOMIC);
-
-		/* No SBUS */
-		dma->sdev = NULL;
-
-		/* Only one DMA device */
-		dma_chain = dma;
-
-		memset(&r, 0, sizeof(r));
-		r.start = sun4_dma_physaddr;
-		dma->regs = sbus_ioremap(&r, 0, PAGE_SIZE, "dma");
-
-		/* No prom node */
-		dma->node = 0x0;
-
-		init_one_dvma(dma, 0);
-	} else {
-	  	dma_chain = NULL;
-	}
-}
-
-#endif
diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c
deleted file mode 100644
index 9c129248466c..000000000000
--- a/drivers/sbus/sbus.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/* sbus.c: SBus support routines.
- *
- * Copyright (C) 1995, 2006 David S. Miller (davem@davemloft.net)
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/of_device.h>
-
-#include <asm/system.h>
-#include <asm/sbus.h>
-#include <asm/dma.h>
-#include <asm/oplib.h>
-#include <asm/prom.h>
-#include <asm/bpp.h>
-#include <asm/irq.h>
-
-static ssize_t
-show_sbusobppath_attr(struct device * dev, struct device_attribute * attr, char * buf)
-{
-	struct sbus_dev *sbus;
-
-	sbus = to_sbus_device(dev);
-
-	return snprintf (buf, PAGE_SIZE, "%s\n", sbus->ofdev.node->full_name);
-}
-
-static DEVICE_ATTR(obppath, S_IRUSR | S_IRGRP | S_IROTH, show_sbusobppath_attr, NULL);
-
-struct sbus_bus *sbus_root;
-
-static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sdev)
-{
-	struct dev_archdata *sd;
-	unsigned long base;
-	const void *pval;
-	int len, err;
-
-	sdev->prom_node = dp->node;
-	strcpy(sdev->prom_name, dp->name);
-
-	pval = of_get_property(dp, "reg", &len);
-	sdev->num_registers = 0;
-	if (pval) {
-		memcpy(sdev->reg_addrs, pval, len);
-
-		sdev->num_registers =
-			len / sizeof(struct linux_prom_registers);
-
-		base = (unsigned long) sdev->reg_addrs[0].phys_addr;
-
-		/* Compute the slot number. */
-		if (base >= SUN_SBUS_BVADDR && sparc_cpu_model == sun4m)
-			sdev->slot = sbus_dev_slot(base);
-		else
-			sdev->slot = sdev->reg_addrs[0].which_io;
-	}
-
-	pval = of_get_property(dp, "ranges", &len);
-	sdev->num_device_ranges = 0;
-	if (pval) {
-		memcpy(sdev->device_ranges, pval, len);
-		sdev->num_device_ranges =
-			len / sizeof(struct linux_prom_ranges);
-	}
-
-	sbus_fill_device_irq(sdev);
-
-	sd = &sdev->ofdev.dev.archdata;
-	sd->prom_node = dp;
-	sd->op = &sdev->ofdev;
-
-	sdev->ofdev.node = dp;
-	if (sdev->parent)
-		sdev->ofdev.dev.parent = &sdev->parent->ofdev.dev;
-	else
-		sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev;
-	sdev->ofdev.dev.bus = &sbus_bus_type;
-	dev_set_name(&sdev->ofdev.dev, "sbus[%08x]", dp->node);
-
-	if (of_device_register(&sdev->ofdev) != 0)
-		printk(KERN_DEBUG "sbus: device registration error for %s!\n",
-		       dp->path_component_name);
-
-	/* WE HAVE BEEN INVADED BY ALIENS! */
-	err = sysfs_create_file(&sdev->ofdev.dev.kobj, &dev_attr_obppath.attr);
-}
-
-static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus)
-{
-	const void *pval;
-	int len;
-
-	pval = of_get_property(dp, "ranges", &len);
-	sbus->num_sbus_ranges = 0;
-	if (pval) {
-		memcpy(sbus->sbus_ranges, pval, len);
-		sbus->num_sbus_ranges =
-			len / sizeof(struct linux_prom_ranges);
-
-		sbus_arch_bus_ranges_init(dp->parent, sbus);
-	}
-}
-
-static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges,
-					  int num_ranges,
-					  struct linux_prom_registers *regs,
-					  int num_regs)
-{
-	if (num_ranges) {
-		int regnum;
-
-		for (regnum = 0; regnum < num_regs; regnum++) {
-			int rngnum;
-
-			for (rngnum = 0; rngnum < num_ranges; rngnum++) {
-				if (regs[regnum].which_io == ranges[rngnum].ot_child_space)
-					break;
-			}
-			if (rngnum == num_ranges) {
-				/* We used to flag this as an error.  Actually
-				 * some devices do not report the regs as we expect.
-				 * For example, see SUNW,pln device.  In that case
-				 * the reg property is in a format internal to that
-				 * node, ie. it is not in the SBUS register space
-				 * per se. -DaveM
-				 */
-				return;
-			}
-			regs[regnum].which_io = ranges[rngnum].ot_parent_space;
-			regs[regnum].phys_addr -= ranges[rngnum].ot_child_base;
-			regs[regnum].phys_addr += ranges[rngnum].ot_parent_base;
-		}
-	}
-}
-
-static void __init __fixup_regs_sdev(struct sbus_dev *sdev)
-{
-	if (sdev->num_registers != 0) {
-		struct sbus_dev *parent = sdev->parent;
-		int i;
-
-		while (parent != NULL) {
-			__apply_ranges_to_regs(parent->device_ranges,
-					       parent->num_device_ranges,
-					       sdev->reg_addrs,
-					       sdev->num_registers);
-
-			parent = parent->parent;
-		}
-
-		__apply_ranges_to_regs(sdev->bus->sbus_ranges,
-				       sdev->bus->num_sbus_ranges,
-				       sdev->reg_addrs,
-				       sdev->num_registers);
-
-		for (i = 0; i < sdev->num_registers; i++) {
-			struct resource *res = &sdev->resource[i];
-
-			res->start = sdev->reg_addrs[i].phys_addr;
-			res->end = (res->start +
-				    (unsigned long)sdev->reg_addrs[i].reg_size - 1UL);
-			res->flags = IORESOURCE_IO |
-				(sdev->reg_addrs[i].which_io & 0xff);
-		}
-	}
-}
-
-static void __init sbus_fixup_all_regs(struct sbus_dev *first_sdev)
-{
-	struct sbus_dev *sdev;
-
-	for (sdev = first_sdev; sdev; sdev = sdev->next) {
-		if (sdev->child)
-			sbus_fixup_all_regs(sdev->child);
-		__fixup_regs_sdev(sdev);
-	}
-}
-
-/* We preserve the "probe order" of these bus and device lists to give
- * the same ordering as the old code.
- */
-static void __init sbus_insert(struct sbus_bus *sbus, struct sbus_bus **root)
-{
-	while (*root)
-		root = &(*root)->next;
-	*root = sbus;
-	sbus->next = NULL;
-}
-
-static void __init sdev_insert(struct sbus_dev *sdev, struct sbus_dev **root)
-{
-	while (*root)
-		root = &(*root)->next;
-	*root = sdev;
-	sdev->next = NULL;
-}
-
-static void __init walk_children(struct device_node *dp, struct sbus_dev *parent, struct sbus_bus *sbus)
-{
-	dp = dp->child;
-	while (dp) {
-		struct sbus_dev *sdev;
-
-		sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC);
-		if (sdev) {
-			sdev_insert(sdev, &parent->child);
-
-			sdev->bus = sbus;
-			sdev->parent = parent;
-			sdev->ofdev.dev.archdata.iommu =
-				sbus->ofdev.dev.archdata.iommu;
-			sdev->ofdev.dev.archdata.stc =
-				sbus->ofdev.dev.archdata.stc;
-
-			fill_sbus_device(dp, sdev);
-
-			walk_children(dp, sdev, sbus);
-		}
-		dp = dp->sibling;
-	}
-}
-
-static void __init build_one_sbus(struct device_node *dp, int num_sbus)
-{
-	struct sbus_bus *sbus;
-	unsigned int sbus_clock;
-	struct device_node *dev_dp;
-
-	sbus = kzalloc(sizeof(struct sbus_bus), GFP_ATOMIC);
-	if (!sbus)
-		return;
-
-	sbus_insert(sbus, &sbus_root);
-	sbus->prom_node = dp->node;
-
-	sbus_setup_iommu(sbus, dp);
-
-	printk("sbus%d: ", num_sbus);
-
-	sbus_clock = of_getintprop_default(dp, "clock-frequency",
-					   (25*1000*1000));
-	sbus->clock_freq = sbus_clock;
-
-	printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000),
-	       (int) (((sbus_clock/1000)%1000 != 0) ? 
-		      (((sbus_clock/1000)%1000) + 1000) : 0));
-
-	strcpy(sbus->prom_name, dp->name);
-
-	sbus_setup_arch_props(sbus, dp);
-
-	sbus_bus_ranges_init(dp, sbus);
-
-	sbus->ofdev.node = dp;
-	sbus->ofdev.dev.parent = NULL;
-	sbus->ofdev.dev.bus = &sbus_bus_type;
-	dev_set_name(&sbus->ofdev.dev, "sbus%d", num_sbus);
-
-	if (of_device_register(&sbus->ofdev) != 0)
-		printk(KERN_DEBUG "sbus: device registration error for %s!\n",
-		       dev_name(&sbus->ofdev.dev));
-
-	dev_dp = dp->child;
-	while (dev_dp) {
-		struct sbus_dev *sdev;
-
-		sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC);
-		if (sdev) {
-			sdev_insert(sdev, &sbus->devices);
-
-			sdev->bus = sbus;
-			sdev->parent = NULL;
-			sdev->ofdev.dev.archdata.iommu =
-				sbus->ofdev.dev.archdata.iommu;
-			sdev->ofdev.dev.archdata.stc =
-				sbus->ofdev.dev.archdata.stc;
-
-			fill_sbus_device(dev_dp, sdev);
-
-			walk_children(dev_dp, sdev, sbus);
-		}
-		dev_dp = dev_dp->sibling;
-	}
-
-	sbus_fixup_all_regs(sbus->devices);
-
-	dvma_init(sbus);
-}
-
-static int __init sbus_init(void)
-{
-	struct device_node *dp;
-	const char *sbus_name = "sbus";
-	int num_sbus = 0;
-
-	if (sbus_arch_preinit())
-		return 0;
-
-	if (sparc_cpu_model == sun4d)
-		sbus_name = "sbi";
-
-	for_each_node_by_name(dp, sbus_name) {
-		build_one_sbus(dp, num_sbus);
-		num_sbus++;
-
-	}
-
-	sbus_arch_postinit();
-
-	return 0;
-}
-
-subsys_initcall(sbus_init);
diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h
index bb43a1388188..28e22acf87ea 100644
--- a/drivers/scsi/esp_scsi.h
+++ b/drivers/scsi/esp_scsi.h
@@ -521,7 +521,8 @@ struct esp {
 
 	struct completion	*eh_reset;
 
-	struct sbus_dma		*dma;
+	void			*dma;
+	int			dmarev;
 };
 
 /* A front-end driver for the ESP chip should do the following in
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index 905350896725..69d6ad862b60 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -1,6 +1,6 @@
 /* qlogicpti.c: Performance Technologies QlogicISP sbus card driver.
  *
- * Copyright (C) 1996, 2006 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1996, 2006, 2008 David S. Miller (davem@davemloft.net)
  *
  * A lot of this driver was directly stolen from Erik H. Moe's PCI
  * Qlogic ISP driver.  Mucho kudos to him for this code.
@@ -25,12 +25,14 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/jiffies.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <asm/byteorder.h>
 
 #include "qlogicpti.h"
 
-#include <asm/sbus.h>
 #include <asm/dma.h>
 #include <asm/system.h>
 #include <asm/ptrace.h>
@@ -157,7 +159,7 @@ static inline void set_sbus_cfg1(struct qlogicpti *qpti)
 	 * is a nop and the chip ends up using the smallest burst
 	 * size. -DaveM
 	 */
-	if (sbus_can_burst64(qpti->sdev) && (bursts & DMA_BURST64)) {
+	if (sbus_can_burst64() && (bursts & DMA_BURST64)) {
 		val = (SBUS_CFG1_BENAB | SBUS_CFG1_B64);
 	} else
 #endif
@@ -684,19 +686,19 @@ static void __devexit qpti_chain_del(struct qlogicpti *qpti)
 
 static int __devinit qpti_map_regs(struct qlogicpti *qpti)
 {
-	struct sbus_dev *sdev = qpti->sdev;
+	struct of_device *op = qpti->op;
 
-	qpti->qregs = sbus_ioremap(&sdev->resource[0], 0,
-				   sdev->reg_addrs[0].reg_size,
-				   "PTI Qlogic/ISP");
+	qpti->qregs = of_ioremap(&op->resource[0], 0,
+				 resource_size(&op->resource[0]),
+				 "PTI Qlogic/ISP");
 	if (!qpti->qregs) {
 		printk("PTI: Qlogic/ISP registers are unmappable\n");
 		return -1;
 	}
 	if (qpti->is_pti) {
-		qpti->sreg = sbus_ioremap(&sdev->resource[0], (16 * 4096),
-					  sizeof(unsigned char),
-					  "PTI Qlogic/ISP statreg");
+		qpti->sreg = of_ioremap(&op->resource[0], (16 * 4096),
+					sizeof(unsigned char),
+					"PTI Qlogic/ISP statreg");
 		if (!qpti->sreg) {
 			printk("PTI: Qlogic/ISP status register is unmappable\n");
 			return -1;
@@ -707,9 +709,9 @@ static int __devinit qpti_map_regs(struct qlogicpti *qpti)
 
 static int __devinit qpti_register_irq(struct qlogicpti *qpti)
 {
-	struct sbus_dev *sdev = qpti->sdev;
+	struct of_device *op = qpti->op;
 
-	qpti->qhost->irq = qpti->irq = sdev->irqs[0];
+	qpti->qhost->irq = qpti->irq = op->irqs[0];
 
 	/* We used to try various overly-clever things to
 	 * reduce the interrupt processing overhead on
@@ -732,17 +734,19 @@ fail:
 
 static void __devinit qpti_get_scsi_id(struct qlogicpti *qpti)
 {
-	qpti->scsi_id = prom_getintdefault(qpti->prom_node,
-					   "initiator-id",
-					   -1);
+	struct of_device *op = qpti->op;
+	struct device_node *dp;
+
+	dp = op->node;
+
+	qpti->scsi_id = of_getintprop_default(dp, "initiator-id", -1);
 	if (qpti->scsi_id == -1)
-		qpti->scsi_id = prom_getintdefault(qpti->prom_node,
-						   "scsi-initiator-id",
-						   -1);
+		qpti->scsi_id = of_getintprop_default(dp, "scsi-initiator-id",
+						      -1);
 	if (qpti->scsi_id == -1)
 		qpti->scsi_id =
-			prom_getintdefault(qpti->sdev->bus->prom_node,
-					   "scsi-initiator-id", 7);
+			of_getintprop_default(dp->parent,
+					      "scsi-initiator-id", 7);
 	qpti->qhost->this_id = qpti->scsi_id;
 	qpti->qhost->max_sectors = 64;
 
@@ -751,12 +755,11 @@ static void __devinit qpti_get_scsi_id(struct qlogicpti *qpti)
 
 static void qpti_get_bursts(struct qlogicpti *qpti)
 {
-	struct sbus_dev *sdev = qpti->sdev;
+	struct of_device *op = qpti->op;
 	u8 bursts, bmask;
 
-	bursts = prom_getintdefault(qpti->prom_node, "burst-sizes", 0xff);
-	bmask = prom_getintdefault(sdev->bus->prom_node,
-				   "burst-sizes", 0xff);
+	bursts = of_getintprop_default(op->node, "burst-sizes", 0xff);
+	bmask = of_getintprop_default(op->node->parent, "burst-sizes", 0xff);
 	if (bmask != 0xff)
 		bursts &= bmask;
 	if (bursts == 0xff ||
@@ -785,25 +788,25 @@ static void qpti_get_clock(struct qlogicpti *qpti)
  */
 static int __devinit qpti_map_queues(struct qlogicpti *qpti)
 {
-	struct sbus_dev *sdev = qpti->sdev;
+	struct of_device *op = qpti->op;
 
 #define QSIZE(entries)	(((entries) + 1) * QUEUE_ENTRY_LEN)
-	qpti->res_cpu = sbus_alloc_consistent(sdev,
-					      QSIZE(RES_QUEUE_LEN),
-					      &qpti->res_dvma);
+	qpti->res_cpu = dma_alloc_coherent(&op->dev,
+					   QSIZE(RES_QUEUE_LEN),
+					   &qpti->res_dvma, GFP_ATOMIC);
 	if (qpti->res_cpu == NULL ||
 	    qpti->res_dvma == 0) {
 		printk("QPTI: Cannot map response queue.\n");
 		return -1;
 	}
 
-	qpti->req_cpu = sbus_alloc_consistent(sdev,
-					      QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
-					      &qpti->req_dvma);
+	qpti->req_cpu = dma_alloc_coherent(&op->dev,
+					   QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
+					   &qpti->req_dvma, GFP_ATOMIC);
 	if (qpti->req_cpu == NULL ||
 	    qpti->req_dvma == 0) {
-		sbus_free_consistent(sdev, QSIZE(RES_QUEUE_LEN),
-				     qpti->res_cpu, qpti->res_dvma);
+		dma_free_coherent(&op->dev, QSIZE(RES_QUEUE_LEN),
+				  qpti->res_cpu, qpti->res_dvma);
 		printk("QPTI: Cannot map request queue.\n");
 		return -1;
 	}
@@ -875,8 +878,9 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
 		int sg_count;
 
 		sg = scsi_sglist(Cmnd);
-		sg_count = sbus_map_sg(qpti->sdev, sg, scsi_sg_count(Cmnd),
-		                                      Cmnd->sc_data_direction);
+		sg_count = dma_map_sg(&qpti->op->dev, sg,
+				      scsi_sg_count(Cmnd),
+				      Cmnd->sc_data_direction);
 
 		ds = cmd->dataseg;
 		cmd->segment_cnt = sg_count;
@@ -1152,9 +1156,9 @@ static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti)
 			Cmnd->result = DID_ERROR << 16;
 
 		if (scsi_bufflen(Cmnd))
-			sbus_unmap_sg(qpti->sdev,
-				      scsi_sglist(Cmnd), scsi_sg_count(Cmnd),
-				      Cmnd->sc_data_direction);
+			dma_unmap_sg(&qpti->op->dev,
+				     scsi_sglist(Cmnd), scsi_sg_count(Cmnd),
+				     Cmnd->sc_data_direction);
 
 		qpti->cmd_count[Cmnd->device->id]--;
 		sbus_writew(out_ptr, qpti->qregs + MBOX5);
@@ -1268,34 +1272,32 @@ static struct scsi_host_template qpti_template = {
 	.use_clustering		= ENABLE_CLUSTERING,
 };
 
-static int __devinit qpti_sbus_probe(struct of_device *dev, const struct of_device_id *match)
+static int __devinit qpti_sbus_probe(struct of_device *op, const struct of_device_id *match)
 {
-	static int nqptis;
-	struct sbus_dev *sdev = to_sbus_device(&dev->dev);
-	struct device_node *dp = dev->node;
 	struct scsi_host_template *tpnt = match->data;
+	struct device_node *dp = op->node;
 	struct Scsi_Host *host;
 	struct qlogicpti *qpti;
+	static int nqptis;
 	const char *fcode;
 
 	/* Sometimes Antares cards come up not completely
 	 * setup, and we get a report of a zero IRQ.
 	 */
-	if (sdev->irqs[0] == 0)
+	if (op->irqs[0] == 0)
 		return -ENODEV;
 
 	host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti));
 	if (!host)
 		return -ENOMEM;
 
-	qpti = (struct qlogicpti *) host->hostdata;
+	qpti = shost_priv(host);
 
 	host->max_id = MAX_TARGETS;
 	qpti->qhost = host;
-	qpti->sdev = sdev;
+	qpti->op = op;
 	qpti->qpti_id = nqptis;
-	qpti->prom_node = sdev->prom_node;
-	strcpy(qpti->prom_name, sdev->ofdev.node->name);
+	strcpy(qpti->prom_name, op->node->name);
 	qpti->is_pti = strcmp(qpti->prom_name, "QLGC,isp");
 
 	if (qpti_map_regs(qpti) < 0)
@@ -1341,12 +1343,12 @@ static int __devinit qpti_sbus_probe(struct of_device *dev, const struct of_devi
 		(qpti->ultra ? "Ultra" : "Fast"),
 		(qpti->differential ? "differential" : "single ended"));
 
-	if (scsi_add_host(host, &dev->dev)) {
+	if (scsi_add_host(host, &op->dev)) {
 		printk("qlogicpti%d: Failed scsi_add_host\n", qpti->qpti_id);
 		goto fail_unmap_queues;
 	}
 
-	dev_set_drvdata(&sdev->ofdev.dev, qpti);
+	dev_set_drvdata(&op->dev, qpti);
 
 	qpti_chain_add(qpti);
 
@@ -1357,19 +1359,20 @@ static int __devinit qpti_sbus_probe(struct of_device *dev, const struct of_devi
 
 fail_unmap_queues:
 #define QSIZE(entries)	(((entries) + 1) * QUEUE_ENTRY_LEN)
-	sbus_free_consistent(qpti->sdev,
-			     QSIZE(RES_QUEUE_LEN),
-			     qpti->res_cpu, qpti->res_dvma);
-	sbus_free_consistent(qpti->sdev,
-			     QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
-			     qpti->req_cpu, qpti->req_dvma);
+	dma_free_coherent(&op->dev,
+			  QSIZE(RES_QUEUE_LEN),
+			  qpti->res_cpu, qpti->res_dvma);
+	dma_free_coherent(&op->dev,
+			  QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
+			  qpti->req_cpu, qpti->req_dvma);
 #undef QSIZE
 
 fail_unmap_regs:
-	sbus_iounmap(qpti->qregs,
-		     qpti->sdev->reg_addrs[0].reg_size);
+	of_iounmap(&op->resource[0], qpti->qregs,
+		   resource_size(&op->resource[0]));
 	if (qpti->is_pti)
-		sbus_iounmap(qpti->sreg, sizeof(unsigned char));
+		of_iounmap(&op->resource[0], qpti->sreg,
+			   sizeof(unsigned char));
 
 fail_free_irq:
 	free_irq(qpti->irq, qpti);
@@ -1380,9 +1383,9 @@ fail_unlink:
 	return -ENODEV;
 }
 
-static int __devexit qpti_sbus_remove(struct of_device *dev)
+static int __devexit qpti_sbus_remove(struct of_device *op)
 {
-	struct qlogicpti *qpti = dev_get_drvdata(&dev->dev);
+	struct qlogicpti *qpti = dev_get_drvdata(&op->dev);
 
 	qpti_chain_del(qpti);
 
@@ -1395,24 +1398,25 @@ static int __devexit qpti_sbus_remove(struct of_device *dev)
 	free_irq(qpti->irq, qpti);
 
 #define QSIZE(entries)	(((entries) + 1) * QUEUE_ENTRY_LEN)
-	sbus_free_consistent(qpti->sdev,
-			     QSIZE(RES_QUEUE_LEN),
-			     qpti->res_cpu, qpti->res_dvma);
-	sbus_free_consistent(qpti->sdev,
-			     QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
-			     qpti->req_cpu, qpti->req_dvma);
+	dma_free_coherent(&op->dev,
+			  QSIZE(RES_QUEUE_LEN),
+			  qpti->res_cpu, qpti->res_dvma);
+	dma_free_coherent(&op->dev,
+			  QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
+			  qpti->req_cpu, qpti->req_dvma);
 #undef QSIZE
 
-	sbus_iounmap(qpti->qregs, qpti->sdev->reg_addrs[0].reg_size);
+	of_iounmap(&op->resource[0], qpti->qregs,
+		   resource_size(&op->resource[0]));
 	if (qpti->is_pti)
-		sbus_iounmap(qpti->sreg, sizeof(unsigned char));
+		of_iounmap(&op->resource[0], qpti->sreg, sizeof(unsigned char));
 
 	scsi_host_put(qpti->qhost);
 
 	return 0;
 }
 
-static struct of_device_id qpti_match[] = {
+static const struct of_device_id qpti_match[] = {
 	{
 		.name = "ptisp",
 		.data = &qpti_template,
@@ -1442,7 +1446,7 @@ static struct of_platform_driver qpti_sbus_driver = {
 
 static int __init qpti_init(void)
 {
-	return of_register_driver(&qpti_sbus_driver, &sbus_bus_type);
+	return of_register_driver(&qpti_sbus_driver, &of_bus_type);
 }
 
 static void __exit qpti_exit(void)
@@ -1453,7 +1457,7 @@ static void __exit qpti_exit(void)
 MODULE_DESCRIPTION("QlogicISP SBUS driver");
 MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("2.0");
+MODULE_VERSION("2.1");
 
 module_init(qpti_init);
 module_exit(qpti_exit);
diff --git a/drivers/scsi/qlogicpti.h b/drivers/scsi/qlogicpti.h
index ef6da2df584b..9c053bbaa877 100644
--- a/drivers/scsi/qlogicpti.h
+++ b/drivers/scsi/qlogicpti.h
@@ -342,7 +342,7 @@ struct qlogicpti {
 	u_int	                  req_in_ptr;		/* index of next request slot */
 	u_int	                  res_out_ptr;		/* index of next result slot  */
 	long	                  send_marker;		/* must we send a marker?     */
-	struct sbus_dev		 *sdev;
+	struct of_device	 *op;
 	unsigned long		  __pad;
 
 	int                       cmd_count[MAX_TARGETS];
diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c
index f9cf70151366..3d73aad4bc82 100644
--- a/drivers/scsi/sun_esp.c
+++ b/drivers/scsi/sun_esp.c
@@ -1,6 +1,6 @@
 /* sun_esp.c: ESP front-end for Sparc SBUS systems.
  *
- * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 2007, 2008 David S. Miller (davem@davemloft.net)
  */
 
 #include <linux/kernel.h>
@@ -9,60 +9,70 @@
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <asm/irq.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 
-#include <asm/sbus.h>
-
 #include <scsi/scsi_host.h>
 
 #include "esp_scsi.h"
 
 #define DRV_MODULE_NAME		"sun_esp"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_VERSION		"1.000"
-#define DRV_MODULE_RELDATE	"April 19, 2007"
+#define DRV_VERSION		"1.100"
+#define DRV_MODULE_RELDATE	"August 27, 2008"
 
 #define dma_read32(REG) \
 	sbus_readl(esp->dma_regs + (REG))
 #define dma_write32(VAL, REG) \
 	sbus_writel((VAL), esp->dma_regs + (REG))
 
-static int __devinit esp_sbus_find_dma(struct esp *esp, struct sbus_dev *dma_sdev)
-{
-	struct sbus_dev *sdev = esp->dev;
-	struct sbus_dma *dma;
+/* DVMA chip revisions */
+enum dvma_rev {
+	dvmarev0,
+	dvmaesc1,
+	dvmarev1,
+	dvmarev2,
+	dvmarev3,
+	dvmarevplus,
+	dvmahme
+};
 
-	if (dma_sdev != NULL) {
-		for_each_dvma(dma) {
-			if (dma->sdev == dma_sdev)
-				break;
-		}
-	} else {
-		for_each_dvma(dma) {
-			if (dma->sdev == NULL)
-				break;
+static int __devinit esp_sbus_setup_dma(struct esp *esp,
+					struct of_device *dma_of)
+{
+	esp->dma = dma_of;
 
-			/* If bus + slot are the same and it has the
-			 * correct OBP name, it's ours.
-			 */
-			if (sdev->bus == dma->sdev->bus &&
-			    sdev->slot == dma->sdev->slot &&
-			    (!strcmp(dma->sdev->prom_name, "dma") ||
-			     !strcmp(dma->sdev->prom_name, "espdma")))
-				break;
-		}
-	}
+	esp->dma_regs = of_ioremap(&dma_of->resource[0], 0,
+				   resource_size(&dma_of->resource[0]),
+				   "espdma");
+	if (!esp->dma_regs)
+		return -ENOMEM;
 
-	if (dma == NULL) {
-		printk(KERN_ERR PFX "[%s] Cannot find dma.\n",
-		       sdev->ofdev.node->full_name);
-		return -ENODEV;
+	switch (dma_read32(DMA_CSR) & DMA_DEVICE_ID) {
+	case DMA_VERS0:
+		esp->dmarev = dvmarev0;
+		break;
+	case DMA_ESCV1:
+		esp->dmarev = dvmaesc1;
+		break;
+	case DMA_VERS1:
+		esp->dmarev = dvmarev1;
+		break;
+	case DMA_VERS2:
+		esp->dmarev = dvmarev2;
+		break;
+	case DMA_VERHME:
+		esp->dmarev = dvmahme;
+		break;
+	case DMA_VERSPLUS:
+		esp->dmarev = dvmarevplus;
+		break;
 	}
-	esp->dma = dma;
-	esp->dma_regs = dma->regs;
 
 	return 0;
 
@@ -70,18 +80,18 @@ static int __devinit esp_sbus_find_dma(struct esp *esp, struct sbus_dev *dma_sde
 
 static int __devinit esp_sbus_map_regs(struct esp *esp, int hme)
 {
-	struct sbus_dev *sdev = esp->dev;
+	struct of_device *op = esp->dev;
 	struct resource *res;
 
 	/* On HME, two reg sets exist, first is DVMA,
 	 * second is ESP registers.
 	 */
 	if (hme)
-		res = &sdev->resource[1];
+		res = &op->resource[1];
 	else
-		res = &sdev->resource[0];
+		res = &op->resource[0];
 
-	esp->regs = sbus_ioremap(res, 0, SBUS_ESP_REG_SIZE, "ESP");
+	esp->regs = of_ioremap(res, 0, SBUS_ESP_REG_SIZE, "ESP");
 	if (!esp->regs)
 		return -ENOMEM;
 
@@ -90,10 +100,11 @@ static int __devinit esp_sbus_map_regs(struct esp *esp, int hme)
 
 static int __devinit esp_sbus_map_command_block(struct esp *esp)
 {
-	struct sbus_dev *sdev = esp->dev;
+	struct of_device *op = esp->dev;
 
-	esp->command_block = sbus_alloc_consistent(sdev, 16,
-						   &esp->command_block_dma);
+	esp->command_block = dma_alloc_coherent(&op->dev, 16,
+						&esp->command_block_dma,
+						GFP_ATOMIC);
 	if (!esp->command_block)
 		return -ENOMEM;
 	return 0;
@@ -102,17 +113,18 @@ static int __devinit esp_sbus_map_command_block(struct esp *esp)
 static int __devinit esp_sbus_register_irq(struct esp *esp)
 {
 	struct Scsi_Host *host = esp->host;
-	struct sbus_dev *sdev = esp->dev;
+	struct of_device *op = esp->dev;
 
-	host->irq = sdev->irqs[0];
+	host->irq = op->irqs[0];
 	return request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp);
 }
 
-static void __devinit esp_get_scsi_id(struct esp *esp)
+static void __devinit esp_get_scsi_id(struct esp *esp, struct of_device *espdma)
 {
-	struct sbus_dev *sdev = esp->dev;
-	struct device_node *dp = sdev->ofdev.node;
+	struct of_device *op = esp->dev;
+	struct device_node *dp;
 
+	dp = op->node;
 	esp->scsi_id = of_getintprop_default(dp, "initiator-id", 0xff);
 	if (esp->scsi_id != 0xff)
 		goto done;
@@ -121,13 +133,7 @@ static void __devinit esp_get_scsi_id(struct esp *esp)
 	if (esp->scsi_id != 0xff)
 		goto done;
 
-	if (!sdev->bus) {
-		/* SUN4 */
-		esp->scsi_id = 7;
-		goto done;
-	}
-
-	esp->scsi_id = of_getintprop_default(sdev->bus->ofdev.node,
+	esp->scsi_id = of_getintprop_default(espdma->node,
 					     "scsi-initiator-id", 7);
 
 done:
@@ -137,9 +143,10 @@ done:
 
 static void __devinit esp_get_differential(struct esp *esp)
 {
-	struct sbus_dev *sdev = esp->dev;
-	struct device_node *dp = sdev->ofdev.node;
+	struct of_device *op = esp->dev;
+	struct device_node *dp;
 
+	dp = op->node;
 	if (of_find_property(dp, "differential", NULL))
 		esp->flags |= ESP_FLAG_DIFFERENTIAL;
 	else
@@ -148,43 +155,36 @@ static void __devinit esp_get_differential(struct esp *esp)
 
 static void __devinit esp_get_clock_params(struct esp *esp)
 {
-	struct sbus_dev *sdev = esp->dev;
-	struct device_node *dp = sdev->ofdev.node;
-	struct device_node *bus_dp;
+	struct of_device *op = esp->dev;
+	struct device_node *bus_dp, *dp;
 	int fmhz;
 
-	bus_dp = NULL;
-	if (sdev != NULL && sdev->bus != NULL)
-		bus_dp = sdev->bus->ofdev.node;
+	dp = op->node;
+	bus_dp = dp->parent;
 
 	fmhz = of_getintprop_default(dp, "clock-frequency", 0);
 	if (fmhz == 0)
-		fmhz = (!bus_dp) ? 0 :
-			of_getintprop_default(bus_dp, "clock-frequency", 0);
+		fmhz = of_getintprop_default(bus_dp, "clock-frequency", 0);
 
 	esp->cfreq = fmhz;
 }
 
-static void __devinit esp_get_bursts(struct esp *esp, struct sbus_dev *dma)
+static void __devinit esp_get_bursts(struct esp *esp, struct of_device *dma_of)
 {
-	struct sbus_dev *sdev = esp->dev;
-	struct device_node *dp = sdev->ofdev.node;
-	u8 bursts;
+	struct device_node *dma_dp = dma_of->node;
+	struct of_device *op = esp->dev;
+	struct device_node *dp;
+	u8 bursts, val;
 
+	dp = op->node;
 	bursts = of_getintprop_default(dp, "burst-sizes", 0xff);
-	if (dma) {
-		struct device_node *dma_dp = dma->ofdev.node;
-		u8 val = of_getintprop_default(dma_dp, "burst-sizes", 0xff);
-		if (val != 0xff)
-			bursts &= val;
-	}
+	val = of_getintprop_default(dma_dp, "burst-sizes", 0xff);
+	if (val != 0xff)
+		bursts &= val;
 
-	if (sdev->bus) {
-		u8 val = of_getintprop_default(sdev->bus->ofdev.node,
-					       "burst-sizes", 0xff);
-		if (val != 0xff)
-			bursts &= val;
-	}
+	val = of_getintprop_default(dma_dp->parent, "burst-sizes", 0xff);
+	if (val != 0xff)
+		bursts &= val;
 
 	if (bursts == 0xff ||
 	    (bursts & DMA_BURST16) == 0 ||
@@ -194,9 +194,9 @@ static void __devinit esp_get_bursts(struct esp *esp, struct sbus_dev *dma)
 	esp->bursts = bursts;
 }
 
-static void __devinit esp_sbus_get_props(struct esp *esp, struct sbus_dev *espdma)
+static void __devinit esp_sbus_get_props(struct esp *esp, struct of_device *espdma)
 {
-	esp_get_scsi_id(esp);
+	esp_get_scsi_id(esp, espdma);
 	esp_get_differential(esp);
 	esp_get_clock_params(esp);
 	esp_get_bursts(esp, espdma);
@@ -215,25 +215,33 @@ static u8 sbus_esp_read8(struct esp *esp, unsigned long reg)
 static dma_addr_t sbus_esp_map_single(struct esp *esp, void *buf,
 				      size_t sz, int dir)
 {
-	return sbus_map_single(esp->dev, buf, sz, dir);
+	struct of_device *op = esp->dev;
+
+	return dma_map_single(&op->dev, buf, sz, dir);
 }
 
 static int sbus_esp_map_sg(struct esp *esp, struct scatterlist *sg,
 				  int num_sg, int dir)
 {
-	return sbus_map_sg(esp->dev, sg, num_sg, dir);
+	struct of_device *op = esp->dev;
+
+	return dma_map_sg(&op->dev, sg, num_sg, dir);
 }
 
 static void sbus_esp_unmap_single(struct esp *esp, dma_addr_t addr,
 				  size_t sz, int dir)
 {
-	sbus_unmap_single(esp->dev, addr, sz, dir);
+	struct of_device *op = esp->dev;
+
+	dma_unmap_single(&op->dev, addr, sz, dir);
 }
 
 static void sbus_esp_unmap_sg(struct esp *esp, struct scatterlist *sg,
 			      int num_sg, int dir)
 {
-	sbus_unmap_sg(esp->dev, sg, num_sg, dir);
+	struct of_device *op = esp->dev;
+
+	dma_unmap_sg(&op->dev, sg, num_sg, dir);
 }
 
 static int sbus_esp_irq_pending(struct esp *esp)
@@ -247,24 +255,26 @@ static void sbus_esp_reset_dma(struct esp *esp)
 {
 	int can_do_burst16, can_do_burst32, can_do_burst64;
 	int can_do_sbus64, lim;
+	struct of_device *op;
 	u32 val;
 
 	can_do_burst16 = (esp->bursts & DMA_BURST16) != 0;
 	can_do_burst32 = (esp->bursts & DMA_BURST32) != 0;
 	can_do_burst64 = 0;
 	can_do_sbus64 = 0;
-	if (sbus_can_dma_64bit(esp->dev))
+	op = esp->dev;
+	if (sbus_can_dma_64bit())
 		can_do_sbus64 = 1;
-	if (sbus_can_burst64(esp->sdev))
+	if (sbus_can_burst64())
 		can_do_burst64 = (esp->bursts & DMA_BURST64) != 0;
 
 	/* Put the DVMA into a known state. */
-	if (esp->dma->revision != dvmahme) {
+	if (esp->dmarev != dvmahme) {
 		val = dma_read32(DMA_CSR);
 		dma_write32(val | DMA_RST_SCSI, DMA_CSR);
 		dma_write32(val & ~DMA_RST_SCSI, DMA_CSR);
 	}
-	switch (esp->dma->revision) {
+	switch (esp->dmarev) {
 	case dvmahme:
 		dma_write32(DMA_RESET_FAS366, DMA_CSR);
 		dma_write32(DMA_RST_SCSI, DMA_CSR);
@@ -282,7 +292,7 @@ static void sbus_esp_reset_dma(struct esp *esp)
 
 		if (can_do_sbus64) {
 			esp->prev_hme_dmacsr |= DMA_SCSI_SBUS64;
-			sbus_set_sbus64(esp->dev, esp->bursts);
+			sbus_set_sbus64(&op->dev, esp->bursts);
 		}
 
 		lim = 1000;
@@ -346,14 +356,14 @@ static void sbus_esp_dma_drain(struct esp *esp)
 	u32 csr;
 	int lim;
 
-	if (esp->dma->revision == dvmahme)
+	if (esp->dmarev == dvmahme)
 		return;
 
 	csr = dma_read32(DMA_CSR);
 	if (!(csr & DMA_FIFO_ISDRAIN))
 		return;
 
-	if (esp->dma->revision != dvmarev3 && esp->dma->revision != dvmaesc1)
+	if (esp->dmarev != dvmarev3 && esp->dmarev != dvmaesc1)
 		dma_write32(csr | DMA_FIFO_STDRAIN, DMA_CSR);
 
 	lim = 1000;
@@ -369,7 +379,7 @@ static void sbus_esp_dma_drain(struct esp *esp)
 
 static void sbus_esp_dma_invalidate(struct esp *esp)
 {
-	if (esp->dma->revision == dvmahme) {
+	if (esp->dmarev == dvmahme) {
 		dma_write32(DMA_RST_SCSI, DMA_CSR);
 
 		esp->prev_hme_dmacsr = ((esp->prev_hme_dmacsr |
@@ -440,7 +450,7 @@ static void sbus_esp_send_dma_cmd(struct esp *esp, u32 addr, u32 esp_count,
 		else
 			csr &= ~DMA_ST_WRITE;
 		dma_write32(csr, DMA_CSR);
-		if (esp->dma->revision == dvmaesc1) {
+		if (esp->dmarev == dvmaesc1) {
 			u32 end = PAGE_ALIGN(addr + dma_count + 16U);
 			dma_write32(end - addr, DMA_COUNT);
 		}
@@ -476,10 +486,8 @@ static const struct esp_driver_ops sbus_esp_ops = {
 	.dma_error	=	sbus_esp_dma_error,
 };
 
-static int __devinit esp_sbus_probe_one(struct device *dev,
-					struct sbus_dev *esp_dev,
-					struct sbus_dev *espdma,
-					struct sbus_bus *sbus,
+static int __devinit esp_sbus_probe_one(struct of_device *op,
+					struct of_device *espdma,
 					int hme)
 {
 	struct scsi_host_template *tpnt = &scsi_esp_template;
@@ -497,13 +505,13 @@ static int __devinit esp_sbus_probe_one(struct device *dev,
 	esp = shost_priv(host);
 
 	esp->host = host;
-	esp->dev = esp_dev;
+	esp->dev = op;
 	esp->ops = &sbus_esp_ops;
 
 	if (hme)
 		esp->flags |= ESP_FLAG_WIDE_CAPABLE;
 
-	err = esp_sbus_find_dma(esp, espdma);
+	err = esp_sbus_setup_dma(esp, espdma);
 	if (err < 0)
 		goto fail_unlink;
 
@@ -525,15 +533,15 @@ static int __devinit esp_sbus_probe_one(struct device *dev,
 	 * come up with the reset bit set, so make sure that
 	 * is clear first.
 	 */
-	if (esp->dma->revision == dvmaesc1) {
+	if (esp->dmarev == dvmaesc1) {
 		u32 val = dma_read32(DMA_CSR);
 
 		dma_write32(val & ~DMA_RST_SCSI, DMA_CSR);
 	}
 
-	dev_set_drvdata(&esp_dev->ofdev.dev, esp);
+	dev_set_drvdata(&op->dev, esp);
 
-	err = scsi_esp_register(esp, dev);
+	err = scsi_esp_register(esp, &op->dev);
 	if (err)
 		goto fail_free_irq;
 
@@ -542,41 +550,46 @@ static int __devinit esp_sbus_probe_one(struct device *dev,
 fail_free_irq:
 	free_irq(host->irq, esp);
 fail_unmap_command_block:
-	sbus_free_consistent(esp->dev, 16,
-			     esp->command_block,
-			     esp->command_block_dma);
+	dma_free_coherent(&op->dev, 16,
+			  esp->command_block,
+			  esp->command_block_dma);
 fail_unmap_regs:
-	sbus_iounmap(esp->regs, SBUS_ESP_REG_SIZE);
+	of_iounmap(&op->resource[(hme ? 1 : 0)], esp->regs, SBUS_ESP_REG_SIZE);
 fail_unlink:
 	scsi_host_put(host);
 fail:
 	return err;
 }
 
-static int __devinit esp_sbus_probe(struct of_device *dev, const struct of_device_id *match)
+static int __devinit esp_sbus_probe(struct of_device *op, const struct of_device_id *match)
 {
-	struct sbus_dev *sdev = to_sbus_device(&dev->dev);
-	struct device_node *dp = dev->node;
-	struct sbus_dev *dma_sdev = NULL;
+	struct device_node *dma_node = NULL;
+	struct device_node *dp = op->node;
+	struct of_device *dma_of = NULL;
 	int hme = 0;
 
 	if (dp->parent &&
 	    (!strcmp(dp->parent->name, "espdma") ||
 	     !strcmp(dp->parent->name, "dma")))
-		dma_sdev = sdev->parent;
+		dma_node = dp->parent;
 	else if (!strcmp(dp->name, "SUNW,fas")) {
-		dma_sdev = sdev;
+		dma_node = op->node;
 		hme = 1;
 	}
+	if (dma_node)
+		dma_of = of_find_device_by_node(dma_node);
+	if (!dma_of)
+		return -ENODEV;
 
-	return esp_sbus_probe_one(&dev->dev, sdev, dma_sdev,
-				  sdev->bus, hme);
+	return esp_sbus_probe_one(op, dma_of, hme);
 }
 
-static int __devexit esp_sbus_remove(struct of_device *dev)
+static int __devexit esp_sbus_remove(struct of_device *op)
 {
-	struct esp *esp = dev_get_drvdata(&dev->dev);
+	struct esp *esp = dev_get_drvdata(&op->dev);
+	struct of_device *dma_of = esp->dma;
 	unsigned int irq = esp->host->irq;
+	bool is_hme;
 	u32 val;
 
 	scsi_esp_unregister(esp);
@@ -586,17 +599,25 @@ static int __devexit esp_sbus_remove(struct of_device *dev)
 	dma_write32(val & ~DMA_INT_ENAB, DMA_CSR);
 
 	free_irq(irq, esp);
-	sbus_free_consistent(esp->dev, 16,
-			     esp->command_block,
-			     esp->command_block_dma);
-	sbus_iounmap(esp->regs, SBUS_ESP_REG_SIZE);
+
+	is_hme = (esp->dmarev == dvmahme);
+
+	dma_free_coherent(&op->dev, 16,
+			  esp->command_block,
+			  esp->command_block_dma);
+	of_iounmap(&op->resource[(is_hme ? 1 : 0)], esp->regs,
+		   SBUS_ESP_REG_SIZE);
+	of_iounmap(&dma_of->resource[0], esp->dma_regs,
+		   resource_size(&dma_of->resource[0]));
 
 	scsi_host_put(esp->host);
 
+	dev_set_drvdata(&op->dev, NULL);
+
 	return 0;
 }
 
-static struct of_device_id esp_match[] = {
+static const struct of_device_id esp_match[] = {
 	{
 		.name = "SUNW,esp",
 	},
@@ -619,7 +640,7 @@ static struct of_platform_driver esp_sbus_driver = {
 
 static int __init sunesp_init(void)
 {
-	return of_register_driver(&esp_sbus_driver, &sbus_bus_type);
+	return of_register_driver(&esp_sbus_driver, &of_bus_type);
 }
 
 static void __exit sunesp_exit(void)
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
index e41766d08035..a94a2ab4b571 100644
--- a/drivers/serial/sunhv.c
+++ b/drivers/serial/sunhv.c
@@ -616,7 +616,7 @@ static int __devexit hv_remove(struct of_device *dev)
 	return 0;
 }
 
-static struct of_device_id hv_match[] = {
+static const struct of_device_id hv_match[] = {
 	{
 		.name = "console",
 		.compatible = "qcn",
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 29b4458abf74..0355efe115d9 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -1078,7 +1078,7 @@ static int __devexit sab_remove(struct of_device *op)
 	return 0;
 }
 
-static struct of_device_id sab_match[] = {
+static const struct of_device_id sab_match[] = {
 	{
 		.name = "se",
 	},
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index a378464f9292..a4dc79b1d7ab 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1506,7 +1506,7 @@ static int __devexit su_remove(struct of_device *op)
 	return 0;
 }
 
-static struct of_device_id su_match[] = {
+static const struct of_device_id su_match[] = {
 	{
 		.name = "su",
 	},
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 3cb4c8aee13f..45a299f35617 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1480,7 +1480,7 @@ static int __devexit zs_remove(struct of_device *op)
 	return 0;
 }
 
-static struct of_device_id zs_match[] = {
+static const struct of_device_id zs_match[] = {
 	{
 		.name = "zs",
 	},
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index e721644bad74..1e35ba6f18e0 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -372,7 +372,7 @@ static int __devexit bw2_remove(struct of_device *op)
 	return 0;
 }
 
-static struct of_device_id bw2_match[] = {
+static const struct of_device_id bw2_match[] = {
 	{
 		.name = "bwtwo",
 	},
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index b17e74671779..a2d1882791a5 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -589,7 +589,7 @@ static int __devexit cg14_remove(struct of_device *op)
 	return 0;
 }
 
-static struct of_device_id cg14_match[] = {
+static const struct of_device_id cg14_match[] = {
 	{
 		.name = "cgfourteen",
 	},
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index 3aa7b6cb0268..99f87fb61d05 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -456,7 +456,7 @@ static int __devexit cg3_remove(struct of_device *op)
 	return 0;
 }
 
-static struct of_device_id cg3_match[] = {
+static const struct of_device_id cg3_match[] = {
 	{
 		.name = "cgthree",
 	},
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 2f64bb3bd254..940ec04f0f1b 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -34,10 +34,11 @@ static int cg6_blank(int, struct fb_info *);
 
 static void cg6_imageblit(struct fb_info *, const struct fb_image *);
 static void cg6_fillrect(struct fb_info *, const struct fb_fillrect *);
+static void cg6_copyarea(struct fb_info *info, const struct fb_copyarea *area);
 static int cg6_sync(struct fb_info *);
 static int cg6_mmap(struct fb_info *, struct vm_area_struct *);
 static int cg6_ioctl(struct fb_info *, unsigned int, unsigned long);
-static void cg6_copyarea(struct fb_info *info, const struct fb_copyarea *area);
+static int cg6_pan_display(struct fb_var_screeninfo *, struct fb_info *);
 
 /*
  *  Frame buffer operations
@@ -47,6 +48,7 @@ static struct fb_ops cg6_ops = {
 	.owner			= THIS_MODULE,
 	.fb_setcolreg		= cg6_setcolreg,
 	.fb_blank		= cg6_blank,
+	.fb_pan_display		= cg6_pan_display,
 	.fb_fillrect		= cg6_fillrect,
 	.fb_copyarea		= cg6_copyarea,
 	.fb_imageblit		= cg6_imageblit,
@@ -161,6 +163,7 @@ static struct fb_ops cg6_ops = {
 #define CG6_THC_MISC_INT_ENAB		(1 << 5)
 #define CG6_THC_MISC_INT		(1 << 4)
 #define CG6_THC_MISC_INIT		0x9f
+#define CG6_THC_CURSOFF			((65536-32) | ((65536-32) << 16))
 
 /* The contents are unknown */
 struct cg6_tec {
@@ -280,6 +283,33 @@ static int cg6_sync(struct fb_info *info)
 	return 0;
 }
 
+static void cg6_switch_from_graph(struct cg6_par *par)
+{
+	struct cg6_thc __iomem *thc = par->thc;
+	unsigned long flags;
+
+	spin_lock_irqsave(&par->lock, flags);
+
+	/* Hide the cursor. */
+	sbus_writel(CG6_THC_CURSOFF, &thc->thc_cursxy);
+
+	spin_unlock_irqrestore(&par->lock, flags);
+}
+
+static int cg6_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	struct cg6_par *par = (struct cg6_par *)info->par;
+
+	/* We just use this to catch switches out of
+	 * graphics mode.
+	 */
+	cg6_switch_from_graph(par);
+
+	if (var->xoffset || var->yoffset || var->vmode)
+		return -EINVAL;
+	return 0;
+}
+
 /**
  *	cg6_fillrect -	Draws a rectangle on the screen.
  *
@@ -643,9 +673,13 @@ static void __devinit cg6_chip_init(struct fb_info *info)
 	struct cg6_par *par = (struct cg6_par *)info->par;
 	struct cg6_tec __iomem *tec = par->tec;
 	struct cg6_fbc __iomem *fbc = par->fbc;
+	struct cg6_thc __iomem *thc = par->thc;
 	u32 rev, conf, mode;
 	int i;
 
+	/* Hide the cursor. */
+	sbus_writel(CG6_THC_CURSOFF, &thc->thc_cursxy);
+
 	/* Turn off stuff in the Transform Engine. */
 	sbus_writel(0, &tec->tec_matrix);
 	sbus_writel(0, &tec->tec_clip);
@@ -814,7 +848,7 @@ static int __devexit cg6_remove(struct of_device *op)
 	return 0;
 }
 
-static struct of_device_id cg6_match[] = {
+static const struct of_device_id cg6_match[] = {
 	{
 		.name = "cgsix",
 	},
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 7992b13ee68f..9dbb9646081f 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -1042,7 +1042,7 @@ static int __devexit ffb_remove(struct of_device *op)
 	return 0;
 }
 
-static struct of_device_id ffb_match[] = {
+static const struct of_device_id ffb_match[] = {
 	{
 		.name = "SUNW,ffb",
 	},
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index 13fea61d6ae4..7c7e8c2da9d9 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -33,6 +33,7 @@ static int leo_blank(int, struct fb_info *);
 
 static int leo_mmap(struct fb_info *, struct vm_area_struct *);
 static int leo_ioctl(struct fb_info *, unsigned int, unsigned long);
+static int leo_pan_display(struct fb_var_screeninfo *, struct fb_info *);
 
 /*
  *  Frame buffer operations
@@ -42,6 +43,7 @@ static struct fb_ops leo_ops = {
 	.owner			= THIS_MODULE,
 	.fb_setcolreg		= leo_setcolreg,
 	.fb_blank		= leo_blank,
+	.fb_pan_display		= leo_pan_display,
 	.fb_fillrect		= cfb_fillrect,
 	.fb_copyarea		= cfb_copyarea,
 	.fb_imageblit		= cfb_imageblit,
@@ -206,6 +208,60 @@ static void leo_wait(struct leo_lx_krn __iomem *lx_krn)
 	return;
 }
 
+static void leo_switch_from_graph(struct fb_info *info)
+{
+	struct leo_par *par = (struct leo_par *) info->par;
+	struct leo_ld_ss0 __iomem *ss = par->ld_ss0;
+	struct leo_cursor __iomem *cursor = par->cursor;
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&par->lock, flags);
+
+	par->extent = ((info->var.xres - 1) |
+		       ((info->var.yres - 1) << 16));
+
+	sbus_writel(0xffffffff, &ss->wid);
+	sbus_writel(0xffff, &ss->wmask);
+	sbus_writel(0, &ss->vclipmin);
+	sbus_writel(par->extent, &ss->vclipmax);
+	sbus_writel(0, &ss->fg);
+	sbus_writel(0xff000000, &ss->planemask);
+	sbus_writel(0x310850, &ss->rop);
+	sbus_writel(0, &ss->widclip);
+	sbus_writel((info->var.xres-1) | ((info->var.yres-1) << 11),
+		    &par->lc_ss0_usr->extent);
+	sbus_writel(4, &par->lc_ss0_usr->addrspace);
+	sbus_writel(0x80000000, &par->lc_ss0_usr->fill);
+	sbus_writel(0, &par->lc_ss0_usr->fontt);
+	do {
+		val = sbus_readl(&par->lc_ss0_usr->csr);
+	} while (val & 0x20000000);
+
+	/* setup screen buffer for cfb_* functions */
+	sbus_writel(1, &ss->wid);
+	sbus_writel(0x00ffffff, &ss->planemask);
+	sbus_writel(0x310b90, &ss->rop);
+	sbus_writel(0, &par->lc_ss0_usr->addrspace);
+
+	/* hide cursor */
+	sbus_writel(sbus_readl(&cursor->cur_misc) & ~LEO_CUR_ENABLE, &cursor->cur_misc);
+
+	spin_unlock_irqrestore(&par->lock, flags);
+}
+
+static int leo_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	/* We just use this to catch switches out of
+	 * graphics mode.
+	 */
+	leo_switch_from_graph(info);
+
+	if (var->xoffset || var->yoffset || var->vmode)
+		return -EINVAL;
+	return 0;
+}
+
 /**
  *      leo_setcolreg - Optional function. Sets a color register.
  *      @regno: boolean, 0 copy local, 1 get_user() function
@@ -454,44 +510,6 @@ static void leo_init_wids(struct fb_info *info)
 	leo_wid_put(info, &wl);
 }
 
-static void leo_switch_from_graph(struct fb_info *info)
-{
-	struct leo_par *par = (struct leo_par *) info->par;
-	struct leo_ld_ss0 __iomem *ss = par->ld_ss0;
-	unsigned long flags;
-	u32 val;
-
-	spin_lock_irqsave(&par->lock, flags);
-
-	par->extent = ((info->var.xres - 1) |
-		       ((info->var.yres - 1) << 16));
-
-	sbus_writel(0xffffffff, &ss->wid);
-	sbus_writel(0xffff, &ss->wmask);
-	sbus_writel(0, &ss->vclipmin);
-	sbus_writel(par->extent, &ss->vclipmax);
-	sbus_writel(0, &ss->fg);
-	sbus_writel(0xff000000, &ss->planemask);
-	sbus_writel(0x310850, &ss->rop);
-	sbus_writel(0, &ss->widclip);
-	sbus_writel((info->var.xres-1) | ((info->var.yres-1) << 11),
-		    &par->lc_ss0_usr->extent);
-	sbus_writel(4, &par->lc_ss0_usr->addrspace);
-	sbus_writel(0x80000000, &par->lc_ss0_usr->fill);
-	sbus_writel(0, &par->lc_ss0_usr->fontt);
-	do {
-		val = sbus_readl(&par->lc_ss0_usr->csr);
-	} while (val & 0x20000000);
-
-	/* setup screen buffer for cfb_* functions */
-	sbus_writel(1, &ss->wid);
-	sbus_writel(0x00ffffff, &ss->planemask);
-	sbus_writel(0x310b90, &ss->rop);
-	sbus_writel(0, &par->lc_ss0_usr->addrspace);
-
-	spin_unlock_irqrestore(&par->lock, flags);
-}
-
 static void leo_init_hw(struct fb_info *info)
 {
 	struct leo_par *par = (struct leo_par *) info->par;
@@ -641,7 +659,7 @@ static int __devexit leo_remove(struct of_device *op)
 	return 0;
 }
 
-static struct of_device_id leo_match[] = {
+static const struct of_device_id leo_match[] = {
 	{
 		.name = "SUNW,leo",
 	},
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index 9e903454ffc1..7000f2cd5854 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -349,7 +349,7 @@ static int __devexit p9100_remove(struct of_device *op)
 	return 0;
 }
 
-static struct of_device_id p9100_match[] = {
+static const struct of_device_id p9100_match[] = {
 	{
 		.name = "p9100",
 	},
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 2a03f78bbb0d..643afbfe8277 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -505,7 +505,7 @@ static int __devexit tcx_remove(struct of_device *op)
 	return 0;
 }
 
-static struct of_device_id tcx_match[] = {
+static const struct of_device_id tcx_match[] = {
 	{
 		.name = "SUNW,tcx",
 	},
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index e0ef123fbdea..6702d2ef0434 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -123,6 +123,9 @@ obj-$(CONFIG_SH_WDT) += shwdt.o
 
 # SPARC64 Architecture
 
+obj-$(CONFIG_WATCHDOG_RIO)		+= riowd.o
+obj-$(CONFIG_WATCHDOG_CP1XXX)		+= cpwd.o
+
 # XTENSA Architecture
 
 # Architecture Independant
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c
new file mode 100644
index 000000000000..084dfe9cecfb
--- /dev/null
+++ b/drivers/watchdog/cpwd.c
@@ -0,0 +1,695 @@
+/* cpwd.c - driver implementation for hardware watchdog
+ * timers found on Sun Microsystems CP1400 and CP1500 boards.
+ *
+ * This device supports both the generic Linux watchdog 
+ * interface and Solaris-compatible ioctls as best it is
+ * able.
+ *
+ * NOTE: 	CP1400 systems appear to have a defective intr_mask
+ * 			register on the PLD, preventing the disabling of
+ * 			timer interrupts.  We use a timer to periodically 
+ * 			reset 'stopped' watchdogs on affected platforms.
+ *
+ * Copyright (c) 2000 Eric Brower (ebrower@usa.net)
+ * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timer.h>
+#include <linux/smp_lock.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include <asm/watchdog.h>
+
+#define DRIVER_NAME	"cpwd"
+#define PFX		DRIVER_NAME ": "
+
+#define WD_OBPNAME	"watchdog"
+#define WD_BADMODEL	"SUNW,501-5336"
+#define WD_BTIMEOUT	(jiffies + (HZ * 1000))
+#define WD_BLIMIT	0xFFFF
+
+#define WD0_MINOR	212
+#define WD1_MINOR	213	
+#define WD2_MINOR	214	
+
+/* Internal driver definitions.  */
+#define WD0_ID			0
+#define WD1_ID			1
+#define WD2_ID			2
+#define WD_NUMDEVS		3
+
+#define WD_INTR_OFF		0
+#define WD_INTR_ON		1
+
+#define WD_STAT_INIT	0x01	/* Watchdog timer is initialized	*/
+#define WD_STAT_BSTOP	0x02	/* Watchdog timer is brokenstopped	*/
+#define WD_STAT_SVCD	0x04	/* Watchdog interrupt occurred		*/
+
+/* Register value definitions
+ */
+#define WD0_INTR_MASK	0x01	/* Watchdog device interrupt masks	*/
+#define WD1_INTR_MASK	0x02
+#define WD2_INTR_MASK	0x04
+
+#define WD_S_RUNNING	0x01	/* Watchdog device status running	*/
+#define WD_S_EXPIRED	0x02	/* Watchdog device status expired	*/
+
+struct cpwd {
+	void __iomem	*regs;
+	spinlock_t	lock;
+
+	unsigned int	irq;
+
+	unsigned long	timeout;
+	bool		enabled;
+	bool		reboot;
+	bool		broken;
+	bool		initialized;
+
+	struct {
+		struct miscdevice	misc;
+		void __iomem		*regs;
+		u8			intr_mask;
+		u8			runstatus;
+		u16			timeout;
+	} devs[WD_NUMDEVS];
+};
+
+static struct cpwd *cpwd_device;
+
+/* Sun uses Altera PLD EPF8820ATC144-4 
+ * providing three hardware watchdogs:
+ *
+ * 	1) RIC - sends an interrupt when triggered
+ * 	2) XIR - asserts XIR_B_RESET when triggered, resets CPU
+ * 	3) POR - asserts POR_B_RESET when triggered, resets CPU, backplane, board
+ *
+ *** Timer register block definition (struct wd_timer_regblk)
+ *
+ * dcntr and limit registers (halfword access):      
+ * -------------------
+ * | 15 | ...| 1 | 0 |
+ * -------------------
+ * |-  counter val  -|
+ * -------------------
+ * dcntr - 	Current 16-bit downcounter value.
+ * 			When downcounter reaches '0' watchdog expires.
+ * 			Reading this register resets downcounter with 'limit' value.
+ * limit - 	16-bit countdown value in 1/10th second increments.
+ * 			Writing this register begins countdown with input value.
+ * 			Reading from this register does not affect counter.
+ * NOTES:	After watchdog reset, dcntr and limit contain '1'
+ *
+ * status register (byte access):
+ * ---------------------------
+ * | 7 | ... | 2 |  1  |  0  |
+ * --------------+------------
+ * |-   UNUSED  -| EXP | RUN |
+ * ---------------------------
+ * status-	Bit 0 - Watchdog is running
+ * 			Bit 1 - Watchdog has expired
+ *
+ *** PLD register block definition (struct wd_pld_regblk)
+ *
+ * intr_mask register (byte access):
+ * ---------------------------------
+ * | 7 | ... | 3 |  2  |  1  |  0  |
+ * +-------------+------------------
+ * |-   UNUSED  -| WD3 | WD2 | WD1 |
+ * ---------------------------------
+ * WD3 -  1 == Interrupt disabled for watchdog 3
+ * WD2 -  1 == Interrupt disabled for watchdog 2
+ * WD1 -  1 == Interrupt disabled for watchdog 1
+ *
+ * pld_status register (byte access):
+ * UNKNOWN, MAGICAL MYSTERY REGISTER
+ *
+ */
+#define WD_TIMER_REGSZ	16
+#define WD0_OFF		0
+#define WD1_OFF		(WD_TIMER_REGSZ * 1)
+#define WD2_OFF		(WD_TIMER_REGSZ * 2)
+#define PLD_OFF		(WD_TIMER_REGSZ * 3)
+
+#define WD_DCNTR	0x00
+#define WD_LIMIT	0x04
+#define WD_STATUS	0x08
+
+#define PLD_IMASK	(PLD_OFF + 0x00)
+#define PLD_STATUS	(PLD_OFF + 0x04)
+
+static struct timer_list cpwd_timer;
+
+static int wd0_timeout = 0;
+static int wd1_timeout = 0;
+static int wd2_timeout = 0;
+
+module_param	(wd0_timeout, int, 0);
+MODULE_PARM_DESC(wd0_timeout, "Default watchdog0 timeout in 1/10secs");
+module_param 	(wd1_timeout, int, 0);
+MODULE_PARM_DESC(wd1_timeout, "Default watchdog1 timeout in 1/10secs");
+module_param 	(wd2_timeout, int, 0);
+MODULE_PARM_DESC(wd2_timeout, "Default watchdog2 timeout in 1/10secs");
+
+MODULE_AUTHOR("Eric Brower <ebrower@usa.net>");
+MODULE_DESCRIPTION("Hardware watchdog driver for Sun Microsystems CP1400/1500");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("watchdog");
+
+static void cpwd_writew(u16 val, void __iomem *addr)
+{
+	writew(cpu_to_le16(val), addr);
+}
+static u16 cpwd_readw(void __iomem *addr)
+{
+	u16 val = readw(addr);
+
+	return le16_to_cpu(val);
+}
+
+static void cpwd_writeb(u8 val, void __iomem *addr)
+{
+	writeb(val, addr);
+}
+
+static u8 cpwd_readb(void __iomem *addr)
+{
+	return readb(addr);
+}
+
+/* Enable or disable watchdog interrupts
+ * Because of the CP1400 defect this should only be
+ * called during initialzation or by wd_[start|stop]timer()
+ *
+ * index 	- sub-device index, or -1 for 'all'
+ * enable	- non-zero to enable interrupts, zero to disable
+ */
+static void cpwd_toggleintr(struct cpwd *p, int index, int enable)
+{
+	unsigned char curregs = cpwd_readb(p->regs + PLD_IMASK);
+	unsigned char setregs = 
+		(index == -1) ? 
+		(WD0_INTR_MASK | WD1_INTR_MASK | WD2_INTR_MASK) : 
+		(p->devs[index].intr_mask);
+
+	if (enable == WD_INTR_ON)
+		curregs &= ~setregs;
+	else
+		curregs |= setregs;
+
+	cpwd_writeb(curregs, p->regs + PLD_IMASK);
+}
+
+/* Restarts timer with maximum limit value and
+ * does not unset 'brokenstop' value.
+ */
+static void cpwd_resetbrokentimer(struct cpwd *p, int index)
+{
+	cpwd_toggleintr(p, index, WD_INTR_ON);
+	cpwd_writew(WD_BLIMIT, p->devs[index].regs + WD_LIMIT);
+}
+
+/* Timer method called to reset stopped watchdogs--
+ * because of the PLD bug on CP1400, we cannot mask
+ * interrupts within the PLD so me must continually
+ * reset the timers ad infinitum.
+ */
+static void cpwd_brokentimer(unsigned long data)
+{
+	struct cpwd *p = (struct cpwd *) data;
+	int id, tripped = 0;
+
+	/* kill a running timer instance, in case we
+	 * were called directly instead of by kernel timer
+	 */
+	if (timer_pending(&cpwd_timer))
+		del_timer(&cpwd_timer);
+
+	for (id = 0; id < WD_NUMDEVS; id++) {
+		if (p->devs[id].runstatus & WD_STAT_BSTOP) {
+			++tripped;
+			cpwd_resetbrokentimer(p, id);
+		}
+	}
+
+	if (tripped) {
+		/* there is at least one timer brokenstopped-- reschedule */
+		cpwd_timer.expires = WD_BTIMEOUT;
+		add_timer(&cpwd_timer);
+	}
+}
+
+/* Reset countdown timer with 'limit' value and continue countdown.
+ * This will not start a stopped timer.
+ */
+static void cpwd_pingtimer(struct cpwd *p, int index)
+{
+	if (cpwd_readb(p->devs[index].regs + WD_STATUS) & WD_S_RUNNING)
+		cpwd_readw(p->devs[index].regs + WD_DCNTR);
+}
+
+/* Stop a running watchdog timer-- the timer actually keeps
+ * running, but the interrupt is masked so that no action is
+ * taken upon expiration.
+ */
+static void cpwd_stoptimer(struct cpwd *p, int index)
+{
+	if (cpwd_readb(p->devs[index].regs + WD_STATUS) & WD_S_RUNNING) {
+		cpwd_toggleintr(p, index, WD_INTR_OFF);
+
+		if (p->broken) {
+			p->devs[index].runstatus |= WD_STAT_BSTOP;
+			cpwd_brokentimer((unsigned long) p);
+		}
+	}
+}
+
+/* Start a watchdog timer with the specified limit value
+ * If the watchdog is running, it will be restarted with
+ * the provided limit value.
+ *
+ * This function will enable interrupts on the specified
+ * watchdog.
+ */
+static void cpwd_starttimer(struct cpwd *p, int index)
+{
+	if (p->broken)
+		p->devs[index].runstatus &= ~WD_STAT_BSTOP;
+
+	p->devs[index].runstatus &= ~WD_STAT_SVCD;
+
+	cpwd_writew(p->devs[index].timeout, p->devs[index].regs + WD_LIMIT);
+	cpwd_toggleintr(p, index, WD_INTR_ON);
+}
+
+static int cpwd_getstatus(struct cpwd *p, int index)
+{
+	unsigned char stat = cpwd_readb(p->devs[index].regs + WD_STATUS);
+	unsigned char intr = cpwd_readb(p->devs[index].regs + PLD_IMASK);
+	unsigned char ret  = WD_STOPPED;
+
+	/* determine STOPPED */
+	if (!stat) 
+		return ret;
+
+	/* determine EXPIRED vs FREERUN vs RUNNING */
+	else if (WD_S_EXPIRED & stat) {
+		ret = WD_EXPIRED;
+	} else if(WD_S_RUNNING & stat) {
+		if (intr & p->devs[index].intr_mask) {
+			ret = WD_FREERUN;
+		} else {
+			/* Fudge WD_EXPIRED status for defective CP1400--
+			 * IF timer is running 
+			 * 	AND brokenstop is set 
+			 * 	AND an interrupt has been serviced
+			 * we are WD_EXPIRED.
+			 *
+			 * IF timer is running 
+			 * 	AND brokenstop is set 
+			 * 	AND no interrupt has been serviced
+			 * we are WD_FREERUN.
+			 */
+			if (p->broken &&
+			    (p->devs[index].runstatus & WD_STAT_BSTOP)) {
+				if (p->devs[index].runstatus & WD_STAT_SVCD) {
+					ret = WD_EXPIRED;
+				} else {
+					/* we could as well pretend we are expired */
+					ret = WD_FREERUN;
+				}
+			} else {
+				ret = WD_RUNNING;
+			}
+		}
+	}
+
+	/* determine SERVICED */
+	if (p->devs[index].runstatus & WD_STAT_SVCD)
+		ret |= WD_SERVICED;
+
+	return(ret);
+}
+
+static irqreturn_t cpwd_interrupt(int irq, void *dev_id)
+{
+	struct cpwd *p = dev_id;
+
+	/* Only WD0 will interrupt-- others are NMI and we won't
+	 * see them here....
+	 */
+	spin_lock_irq(&p->lock);
+
+	cpwd_stoptimer(p, WD0_ID);
+	p->devs[WD0_ID].runstatus |=  WD_STAT_SVCD;
+
+	spin_unlock_irq(&p->lock);
+
+	return IRQ_HANDLED;
+}
+
+static int cpwd_open(struct inode *inode, struct file *f)
+{
+	struct cpwd *p = cpwd_device;
+
+	lock_kernel();
+	switch(iminor(inode)) {
+		case WD0_MINOR:
+		case WD1_MINOR:
+		case WD2_MINOR:
+			break;
+
+		default:
+			unlock_kernel();
+			return -ENODEV;
+	}
+
+	/* Register IRQ on first open of device */
+	if (!p->initialized) {
+		if (request_irq(p->irq, &cpwd_interrupt, 
+				IRQF_SHARED, DRIVER_NAME, p)) {
+			printk(KERN_ERR PFX "Cannot register IRQ %d\n", 
+				p->irq);
+			unlock_kernel();
+			return -EBUSY;
+		}
+		p->initialized = true;
+	}
+
+	unlock_kernel();
+
+	return nonseekable_open(inode, f);
+}
+
+static int cpwd_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static int cpwd_ioctl(struct inode *inode, struct file *file, 
+		      unsigned int cmd, unsigned long arg)
+{
+	static struct watchdog_info info = {
+		.options		= WDIOF_SETTIMEOUT,
+		.firmware_version	= 1,
+		.identity		= DRIVER_NAME,
+	};
+	void __user *argp = (void __user *)arg;
+	int index = iminor(inode) - WD0_MINOR;
+	struct cpwd *p = cpwd_device;
+	int setopt = 0;
+
+	switch (cmd) {
+	/* Generic Linux IOCTLs */
+	case WDIOC_GETSUPPORT:
+		if (copy_to_user(argp, &info, sizeof(struct watchdog_info)))
+			return -EFAULT;
+		break;
+
+	case WDIOC_GETSTATUS:
+	case WDIOC_GETBOOTSTATUS:
+		if (put_user(0, (int __user *)argp))
+			return -EFAULT;
+		break;
+
+	case WDIOC_KEEPALIVE:
+		cpwd_pingtimer(p, index);
+		break;
+
+	case WDIOC_SETOPTIONS:
+		if (copy_from_user(&setopt, argp, sizeof(unsigned int)))
+			return -EFAULT;
+
+		if (setopt & WDIOS_DISABLECARD) {
+			if (p->enabled)
+				return -EINVAL;
+			cpwd_stoptimer(p, index);
+		} else if (setopt & WDIOS_ENABLECARD) {
+			cpwd_starttimer(p, index);
+		} else {
+			return -EINVAL;
+		}	
+		break;
+
+	/* Solaris-compatible IOCTLs */
+	case WIOCGSTAT:
+		setopt = cpwd_getstatus(p, index);
+		if (copy_to_user(argp, &setopt, sizeof(unsigned int)))
+			return -EFAULT;
+		break;
+
+	case WIOCSTART:
+		cpwd_starttimer(p, index);
+		break;
+
+	case WIOCSTOP:
+		if (p->enabled)
+			return(-EINVAL);
+
+		cpwd_stoptimer(p, index);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static long cpwd_compat_ioctl(struct file *file, unsigned int cmd,
+			      unsigned long arg)
+{
+	int rval = -ENOIOCTLCMD;
+
+	switch (cmd) {
+	/* solaris ioctls are specific to this driver */
+	case WIOCSTART:
+	case WIOCSTOP:
+	case WIOCGSTAT:
+		lock_kernel();
+		rval = cpwd_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
+		unlock_kernel();
+		break;
+
+	/* everything else is handled by the generic compat layer */
+	default:
+		break;
+	}
+
+	return rval;
+}
+
+static ssize_t cpwd_write(struct file *file, const char __user *buf, 
+			  size_t count, loff_t *ppos)
+{
+	struct inode *inode = file->f_path.dentry->d_inode;
+	struct cpwd *p = cpwd_device;
+	int index = iminor(inode);
+
+	if (count) {
+		cpwd_pingtimer(p, index);
+		return 1;
+	}
+
+	return 0;
+}
+
+static ssize_t cpwd_read(struct file * file, char __user *buffer,
+			 size_t count, loff_t *ppos)
+{
+	return -EINVAL;
+}
+
+static const struct file_operations cpwd_fops = {
+	.owner =	THIS_MODULE,
+	.ioctl =	cpwd_ioctl,
+	.compat_ioctl =	cpwd_compat_ioctl,
+	.open =		cpwd_open,
+	.write =	cpwd_write,
+	.read =		cpwd_read,
+	.release =	cpwd_release,
+};
+
+static int __devinit cpwd_probe(struct of_device *op,
+				const struct of_device_id *match)
+{
+	struct device_node *options;
+	const char *str_prop;
+	const void *prop_val;
+	int i, err = -EINVAL;
+	struct cpwd *p;
+
+	if (cpwd_device)
+		return -EINVAL;
+
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	err = -ENOMEM;
+	if (!p) {
+		printk(KERN_ERR PFX "Unable to allocate struct cpwd.\n");
+		goto out;
+	}
+
+	p->irq = op->irqs[0];
+
+	spin_lock_init(&p->lock);
+
+	p->regs = of_ioremap(&op->resource[0], 0,
+			     4 * WD_TIMER_REGSZ, DRIVER_NAME);
+	if (!p->regs) {
+		printk(KERN_ERR PFX "Unable to map registers.\n");
+		goto out_free;
+	}
+
+	options = of_find_node_by_path("/options");
+	err = -ENODEV;
+	if (!options) {
+		printk(KERN_ERR PFX "Unable to find /options node.\n");
+		goto out_iounmap;
+	}
+
+	prop_val = of_get_property(options, "watchdog-enable?", NULL);
+	p->enabled = (prop_val ? true : false);
+
+	prop_val = of_get_property(options, "watchdog-reboot?", NULL);
+	p->reboot = (prop_val ? true : false);
+
+	str_prop = of_get_property(options, "watchdog-timeout", NULL);
+	if (str_prop)
+		p->timeout = simple_strtoul(str_prop, NULL, 10);
+
+	/* CP1400s seem to have broken PLD implementations-- the
+	 * interrupt_mask register cannot be written, so no timer
+	 * interrupts can be masked within the PLD.
+	 */
+	str_prop = of_get_property(op->node, "model", NULL);
+	p->broken = (str_prop && !strcmp(str_prop, WD_BADMODEL));
+
+	if (!p->enabled)
+		cpwd_toggleintr(p, -1, WD_INTR_OFF);
+
+	for (i = 0; i < WD_NUMDEVS; i++) {
+		static const char *cpwd_names[] = { "RIC", "XIR", "POR" };
+		static int *parms[] = { &wd0_timeout,
+					&wd1_timeout,
+					&wd2_timeout };
+		struct miscdevice *mp = &p->devs[i].misc;
+
+		mp->minor = WD0_MINOR + i;
+		mp->name = cpwd_names[i];
+		mp->fops = &cpwd_fops;
+
+		p->devs[i].regs = p->regs + (i * WD_TIMER_REGSZ);
+		p->devs[i].intr_mask = (WD0_INTR_MASK << i);
+		p->devs[i].runstatus &= ~WD_STAT_BSTOP;
+		p->devs[i].runstatus |= WD_STAT_INIT;
+		p->devs[i].timeout = p->timeout;
+		if (*parms[i])
+			p->devs[i].timeout = *parms[i];
+
+		err = misc_register(&p->devs[i].misc);
+		if (err) {
+			printk(KERN_ERR "Could not register misc device for "
+			       "dev %d\n", i);
+			goto out_unregister;
+		}
+	}
+
+	if (p->broken) {
+		init_timer(&cpwd_timer);
+		cpwd_timer.function 	= cpwd_brokentimer;
+		cpwd_timer.data		= (unsigned long) p;
+		cpwd_timer.expires	= WD_BTIMEOUT;
+
+		printk(KERN_INFO PFX "PLD defect workaround enabled for "
+		       "model " WD_BADMODEL ".\n");
+	}
+
+	dev_set_drvdata(&op->dev, p);
+	cpwd_device = p;
+	err = 0;
+
+out:
+	return err;
+
+out_unregister:
+	for (i--; i >= 0; i--)
+		misc_deregister(&p->devs[i].misc);
+
+out_iounmap:
+	of_iounmap(&op->resource[0], p->regs, 4 * WD_TIMER_REGSZ);
+
+out_free:
+	kfree(p);
+	goto out;
+}
+
+static int __devexit cpwd_remove(struct of_device *op)
+{
+	struct cpwd *p = dev_get_drvdata(&op->dev);
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		misc_deregister(&p->devs[i].misc);
+
+		if (!p->enabled) {
+			cpwd_stoptimer(p, i);
+			if (p->devs[i].runstatus & WD_STAT_BSTOP)
+				cpwd_resetbrokentimer(p, i);
+		}
+	}
+
+	if (p->broken)
+		del_timer_sync(&cpwd_timer);
+
+	if (p->initialized)
+		free_irq(p->irq, p);
+
+	of_iounmap(&op->resource[0], p->regs, 4 * WD_TIMER_REGSZ);
+	kfree(p);
+
+	cpwd_device = NULL;
+
+	return 0;
+}
+
+static const struct of_device_id cpwd_match[] = {
+	{
+		.name = "watchdog",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, cpwd_match);
+
+static struct of_platform_driver cpwd_driver = {
+	.name		= DRIVER_NAME,
+	.match_table	= cpwd_match,
+	.probe		= cpwd_probe,
+	.remove		= __devexit_p(cpwd_remove),
+};
+
+static int __init cpwd_init(void)
+{
+	return of_register_driver(&cpwd_driver, &of_bus_type);
+}
+
+static void __exit cpwd_exit(void)
+{
+	of_unregister_driver(&cpwd_driver);
+}
+
+module_init(cpwd_init);
+module_exit(cpwd_exit);
diff --git a/drivers/sbus/char/riowatchdog.c b/drivers/watchdog/riowd.c
index 88c0fc6395e1..09cb1833ea27 100644
--- a/drivers/sbus/char/riowatchdog.c
+++ b/drivers/watchdog/riowd.c
@@ -1,7 +1,6 @@
-/* $Id: riowatchdog.c,v 1.3.2.2 2002/01/23 18:48:02 davem Exp $
- * riowatchdog.c - driver for hw watchdog inside Super I/O of RIO
+/* riowd.c - driver for hw watchdog inside Super I/O of RIO
  *
- * Copyright (C) 2001 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2001, 2008 David S. Miller (davem@davemloft.net)
  */
 
 #include <linux/kernel.h>
@@ -12,14 +11,13 @@
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/smp_lock.h>
+#include <linux/watchdog.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/ebus.h>
-#include <asm/bbc.h>
-#include <asm/oplib.h>
 #include <asm/uaccess.h>
 
-#include <asm/watchdog.h>
 
 /* RIO uses the NatSemi Super I/O power management logical device
  * as its' watchdog.
@@ -45,74 +43,35 @@
  * The watchdog device generates no interrupts.
  */
 
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
 MODULE_DESCRIPTION("Hardware watchdog driver for Sun RIO");
 MODULE_SUPPORTED_DEVICE("watchdog");
 MODULE_LICENSE("GPL");
 
-#define RIOWD_NAME	"pmc"
-#define RIOWD_MINOR	215
+#define DRIVER_NAME	"riowd"
+#define PFX		DRIVER_NAME ": "
 
-static DEFINE_SPINLOCK(riowd_lock);
+struct riowd {
+	void __iomem		*regs;
+	spinlock_t		lock;
+};
+
+static struct riowd *riowd_device;
 
-static void __iomem *bbc_regs;
-static void __iomem *riowd_regs;
 #define WDTO_INDEX	0x05
 
 static int riowd_timeout = 1;		/* in minutes */
 module_param(riowd_timeout, int, 0);
 MODULE_PARM_DESC(riowd_timeout, "Watchdog timeout in minutes");
 
-#if 0 /* Currently unused. */
-static u8 riowd_readreg(int index)
+static void riowd_writereg(struct riowd *p, u8 val, int index)
 {
 	unsigned long flags;
-	u8 ret;
 
-	spin_lock_irqsave(&riowd_lock, flags);
-	writeb(index, riowd_regs + 0);
-	ret = readb(riowd_regs + 1);
-	spin_unlock_irqrestore(&riowd_lock, flags);
-
-	return ret;
-}
-#endif
-
-static void riowd_writereg(u8 val, int index)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&riowd_lock, flags);
-	writeb(index, riowd_regs + 0);
-	writeb(val, riowd_regs + 1);
-	spin_unlock_irqrestore(&riowd_lock, flags);
-}
-
-static void riowd_pingtimer(void)
-{
-	riowd_writereg(riowd_timeout, WDTO_INDEX);
-}
-
-static void riowd_stoptimer(void)
-{
-	u8 val;
-
-	riowd_writereg(0, WDTO_INDEX);
-
-	val = readb(bbc_regs + BBC_WDACTION);
-	val &= ~BBC_WDACTION_RST;
-	writeb(val, bbc_regs + BBC_WDACTION);
-}
-
-static void riowd_starttimer(void)
-{
-	u8 val;
-
-	riowd_writereg(riowd_timeout, WDTO_INDEX);
-
-	val = readb(bbc_regs + BBC_WDACTION);
-	val |= BBC_WDACTION_RST;
-	writeb(val, bbc_regs + BBC_WDACTION);
+	spin_lock_irqsave(&p->lock, flags);
+	writeb(index, p->regs + 0);
+	writeb(val, p->regs + 1);
+	spin_unlock_irqrestore(&p->lock, flags);
 }
 
 static int riowd_open(struct inode *inode, struct file *filp)
@@ -131,9 +90,12 @@ static int riowd_ioctl(struct inode *inode, struct file *filp,
 		       unsigned int cmd, unsigned long arg)
 {
 	static struct watchdog_info info = {
-	       	WDIOF_SETTIMEOUT, 0, "Natl. Semiconductor PC97317"
+		.options		= WDIOF_SETTIMEOUT,
+		.firmware_version	= 1,
+		.identity		= DRIVER_NAME,
 	};
 	void __user *argp = (void __user *)arg;
+	struct riowd *p = riowd_device;
 	unsigned int options;
 	int new_margin;
 
@@ -150,7 +112,7 @@ static int riowd_ioctl(struct inode *inode, struct file *filp,
 		break;
 
 	case WDIOC_KEEPALIVE:
-		riowd_pingtimer();
+		riowd_writereg(p, riowd_timeout, WDTO_INDEX);
 		break;
 
 	case WDIOC_SETOPTIONS:
@@ -158,9 +120,9 @@ static int riowd_ioctl(struct inode *inode, struct file *filp,
 			return -EFAULT;
 
 		if (options & WDIOS_DISABLECARD)
-			riowd_stoptimer();
+			riowd_writereg(p, 0, WDTO_INDEX);
 		else if (options & WDIOS_ENABLECARD)
-			riowd_starttimer();
+			riowd_writereg(p, riowd_timeout, WDTO_INDEX);
 		else
 			return -EINVAL;
 
@@ -170,9 +132,9 @@ static int riowd_ioctl(struct inode *inode, struct file *filp,
 		if (get_user(new_margin, (int __user *)argp))
 			return -EFAULT;
 		if ((new_margin < 60) || (new_margin > (255 * 60)))
-		    return -EINVAL;
+			return -EINVAL;
 		riowd_timeout = (new_margin + 59) / 60;
-		riowd_pingtimer();
+		riowd_writereg(p, riowd_timeout, WDTO_INDEX);
 		/* Fall */
 
 	case WDIOC_GETTIMEOUT:
@@ -187,8 +149,10 @@ static int riowd_ioctl(struct inode *inode, struct file *filp,
 
 static ssize_t riowd_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
+	struct riowd *p = riowd_device;
+
 	if (count) {
-		riowd_pingtimer();
+		riowd_writereg(p, riowd_timeout, WDTO_INDEX);
 		return 1;
 	}
 
@@ -197,99 +161,99 @@ static ssize_t riowd_write(struct file *file, const char __user *buf, size_t cou
 
 static const struct file_operations riowd_fops = {
 	.owner =	THIS_MODULE,
+	.llseek =	no_llseek,
 	.ioctl =	riowd_ioctl,
 	.open =		riowd_open,
 	.write =	riowd_write,
 	.release =	riowd_release,
 };
 
-static struct miscdevice riowd_miscdev = { RIOWD_MINOR, RIOWD_NAME, &riowd_fops };
+static struct miscdevice riowd_miscdev = {
+	.minor	= WATCHDOG_MINOR,
+	.name	= "watchdog",
+	.fops	= &riowd_fops
+};
 
-static int __init riowd_bbc_init(void)
+static int __devinit riowd_probe(struct of_device *op,
+				 const struct of_device_id *match)
 {
-	struct 	linux_ebus *ebus = NULL;
-	struct 	linux_ebus_device *edev = NULL;
-	u8 val;
-
-	for_each_ebus(ebus) {
-		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->ofdev.node->name, "bbc"))
-				goto found_bbc;
-		}
-	}
+	struct riowd *p;
+	int err = -EINVAL;
 
-found_bbc:
-	if (!edev)
-		return -ENODEV;
-	bbc_regs = ioremap(edev->resource[0].start, BBC_REGS_SIZE);
-	if (!bbc_regs)
-		return -ENODEV;
+	if (riowd_device)
+		goto out;
 
-	/* Turn it off. */
-	val = readb(bbc_regs + BBC_WDACTION);
-	val &= ~BBC_WDACTION_RST;
-	writeb(val, bbc_regs + BBC_WDACTION);
+	err = -ENOMEM;
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	if (!p)
+		goto out;
 
-	return 0;
-}
+	spin_lock_init(&p->lock);
 
-static int __init riowd_init(void)
-{
-	struct 	linux_ebus *ebus = NULL;
-	struct 	linux_ebus_device *edev = NULL;
-
-	for_each_ebus(ebus) {
-		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->ofdev.node->name, RIOWD_NAME))
-				goto ebus_done;
-		}
+	p->regs = of_ioremap(&op->resource[0], 0, 2, DRIVER_NAME);
+	if (!p->regs) {
+		printk(KERN_ERR PFX "Cannot map registers.\n");
+		goto out_free;
 	}
 
-ebus_done:
-	if (!edev)
-		goto fail;
-
-	riowd_regs = ioremap(edev->resource[0].start, 2);
-	if (riowd_regs == NULL) {
-		printk(KERN_ERR "pmc: Cannot map registers.\n");
-		return -ENODEV;
+	err = misc_register(&riowd_miscdev);
+	if (err) {
+		printk(KERN_ERR PFX "Cannot register watchdog misc device.\n");
+		goto out_iounmap;
 	}
 
-	if (riowd_bbc_init()) {
-		printk(KERN_ERR "pmc: Failure initializing BBC config.\n");
-		goto fail;
-	}
+	printk(KERN_INFO PFX "Hardware watchdog [%i minutes], "
+	       "regs at %p\n", riowd_timeout, p->regs);
 
-	if (misc_register(&riowd_miscdev)) {
-		printk(KERN_ERR "pmc: Cannot register watchdog misc device.\n");
-		goto fail;
-	}
+	dev_set_drvdata(&op->dev, p);
+	riowd_device = p;
+	err = 0;
 
-	printk(KERN_INFO "pmc: Hardware watchdog [%i minutes], "
-	       "regs at %p\n", riowd_timeout, riowd_regs);
+out_iounmap:
+	of_iounmap(&op->resource[0], p->regs, 2);
 
-	return 0;
+out_free:
+	kfree(p);
 
-fail:
-	if (riowd_regs) {
-		iounmap(riowd_regs);
-		riowd_regs = NULL;
-	}
-	if (bbc_regs) {
-		iounmap(bbc_regs);
-		bbc_regs = NULL;
-	}
-	return -ENODEV;
+out:
+	return err;
 }
 
-static void __exit riowd_cleanup(void)
+static int __devexit riowd_remove(struct of_device *op)
 {
+	struct riowd *p = dev_get_drvdata(&op->dev);
+
 	misc_deregister(&riowd_miscdev);
-	iounmap(riowd_regs);
-	riowd_regs = NULL;
-	iounmap(bbc_regs);
-	bbc_regs = NULL;
+	of_iounmap(&op->resource[0], p->regs, 2);
+	kfree(p);
+
+	return 0;
+}
+
+static const struct of_device_id riowd_match[] = {
+	{
+		.name = "pmc",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, riowd_match);
+
+static struct of_platform_driver riowd_driver = {
+	.name		= DRIVER_NAME,
+	.match_table	= riowd_match,
+	.probe		= riowd_probe,
+	.remove		= __devexit_p(riowd_remove),
+};
+
+static int __init riowd_init(void)
+{
+	return of_register_driver(&riowd_driver, &of_bus_type);
+}
+
+static void __exit riowd_exit(void)
+{
+	of_unregister_driver(&riowd_driver);
 }
 
 module_init(riowd_init);
-module_exit(riowd_cleanup);
+module_exit(riowd_exit);