summary refs log tree commit diff
path: root/drivers/net/sunhme.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sunhme.c')
-rw-r--r--drivers/net/sunhme.c322
1 files changed, 128 insertions, 194 deletions
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();