[parisc-linux-cvs] DIFF 2.5.53-pa2 new DMA and device model

James Bottomley James.Bottomley@steeleye.com
Tue, 24 Dec 2002 18:39:22 -0600


This is a multipart MIME message.

--==_Exmh_-8072902840
Content-Type: text/plain; charset=us-ascii

This (rather large) diff adds the necessary generic device model components to 
parisc devices and drivers.  You can now see the entire parisc device tree 
just by mounting sysfs.  (this necessitated the introduction of an extra 
asm/parisc-device.h file to untangle the #include dependencies).

It also abandons the use of pci_dev->sysdata in favour of generic dev->
platform_data for caching iommu information.  The iommu is now found by 
walking up the device tree and caching the result in platform_data.

All of the parisc DMA operations are now done in terms of the generic dma_ 
APIs.

I bet there are a few cases I can't test that are broken, let me know how it 
goes.

James


--==_Exmh_-8072902840
Content-Type: text/plain ; name="tmp.diff"; charset=us-ascii
Content-Description: tmp.diff
Content-Disposition: attachment; filename="tmp.diff"

diff -Nru a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
--- a/arch/parisc/kernel/drivers.c	Tue Dec 24 17:51:15 2002
+++ b/arch/parisc/kernel/drivers.c	Tue Dec 24 17:51:15 2002
@@ -24,21 +24,13 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/pdc.h>
+#include <asm/parisc-device.h>
 
 /* See comments in include/asm-parisc/pci.h */
-struct pci_dma_ops *hppa_dma_ops;
+struct hppa_dma_ops *hppa_dma_ops;
 
-static struct parisc_driver *pa_drivers;
 static struct parisc_device root;
 
-/* This lock protects the pa_drivers list _only_ since all parisc_devices
- * are registered before smp_init() is called.  If you wish to add devices
- * after that, this muct be serialised somehow.  I recommend a semaphore
- * rather than a spinlock since driver ->probe functions are allowed to
- * sleep (for example when allocating memory).
- */
-static spinlock_t pa_lock = SPIN_LOCK_UNLOCKED;
-
 #define for_each_padev(dev) \
 	for (dev = root.child; dev != NULL; dev = next_dev(dev))
 
@@ -103,43 +95,63 @@
 	request_mem_region(dev->hpa, 0x1000, driver->name);
 }
 
+static int parisc_driver_probe(struct device *dev)
+{
+	int rc;
+	struct parisc_device *pa_dev = to_parisc_device(dev);
+	struct parisc_driver *pa_drv = to_parisc_driver(dev->driver);
+
+	rc = pa_drv->probe(pa_dev);
+
+	if(!rc)
+		claim_device(pa_drv, pa_dev);
+
+	return rc;
+}
+
+static int parisc_driver_remove(struct device *dev)
+{
+	struct parisc_device *pa_dev = to_parisc_device(dev);
+
+	release_mem_region(pa_dev->hpa, 0x1000);
+
+	return 0;
+}
+	
+
 /**
  * register_parisc_driver - Register this driver if it can handle a device
  * @driver: the PA-RISC driver to try
  */
 int register_parisc_driver(struct parisc_driver *driver)
 {
-	struct parisc_device *device;
+	/* FIXME: we need this because apparently the sti
+	 * driver can be registered twice */
+	if(driver->drv.name) {
+		printk(KERN_WARNING 
+		       "BUG: skipping previously registered driver %s\n",
+		       driver->name);
+		return 1;
+	}
 
-	if (driver->next) {
+	if (!driver->probe) {
 		printk(KERN_WARNING 
-		       "BUG: Skipping previously registered driver: %s\n",
+		       "BUG: driver %s has no probe routine\n",
 		       driver->name);
 		return 1;
 	}
 
-	for_each_padev(device) {
-		if (device->driver)
-			continue;
-		if (!match_device(driver, device))
-			continue;
+	driver->drv.bus = &parisc_bus_type;
 
-		if (driver->probe(device) < 0)
-			continue;
-		claim_device(driver, device);
-	}
+	/* We install our own probe and remove routines */
+	WARN_ON(driver->drv.probe != NULL);
+	WARN_ON(driver->drv.remove != NULL);
 
-	/* Note that the list is in reverse order of registration.  This
-	 * may be significant if we ever actually support hotplug and have
-	 * multiple drivers capable of claiming the same chip.
-	 */
-
-	spin_lock(&pa_lock);
-	driver->next = pa_drivers;
-	pa_drivers = driver;
-	spin_unlock(&pa_lock);
+	driver->drv.probe = parisc_driver_probe;
+	driver->drv.remove = parisc_driver_remove;
+	driver->drv.name = driver->name;
 
-	return 0;
+	return driver_register(&driver->drv);
 }
 
 /**
@@ -170,39 +182,7 @@
  */
 int unregister_parisc_driver(struct parisc_driver *driver)
 {
-	struct parisc_device *dev;
-
-	spin_lock(&pa_lock);
-
-	if (pa_drivers == driver) {
-		/* was head of list - update head */
-		pa_drivers = driver->next;
-	} else {
-		struct parisc_driver *prev = pa_drivers;
-
-		while (prev && driver != prev->next) {
-			prev = prev->next;
-		}
-
-		if (!prev) {
-			printk(KERN_WARNING "unregister_parisc_driver: %s wasn't registered\n", driver->name);
-		} else {
-			/* Drop driver from list */
-			prev->next = driver->next;
-			driver->next = NULL;
-		}
-
-	}
-
-	spin_unlock(&pa_lock);
-
-	for_each_padev(dev) {
-		if (dev->driver != driver)
-			continue;
-		dev->driver = NULL;
-		release_mem_region(dev->hpa, 0x1000);
-	}
-
+	driver_unregister(&driver->drv);
 	return 0;
 }
 
@@ -301,7 +281,7 @@
 		path->bc[i--] = PCI_SLOT(devfn) | (PCI_FUNC(devfn) << 5);
 	}
 
-	padev = HBA_DATA(bus->sysdata)->dev;
+	padev = HBA_DATA(bus->dev->platform_data)->dev;
 	while (padev != &root) {
 		path->bc[i--] = padev->hw_path;
 		padev = padev->parent;
@@ -424,6 +404,16 @@
 	return dev;
 }
 
+static int parisc_generic_match(struct device *dev, struct device_driver *drv)
+{
+	return  match_device(to_parisc_driver(drv), to_parisc_device(dev));
+}
+
+struct bus_type parisc_bus_type = {
+	.name = "parisc",
+	.match = parisc_generic_match,
+};
+
 /**
  * register_parisc_device - Locate a driver to manage this device.
  * @dev: The parisc device.
@@ -433,29 +423,13 @@
  */
 int register_parisc_device(struct parisc_device *dev)
 {
-	struct parisc_driver *driver;
-
 	if (!dev)
 		return 0;
 
 	if (dev->driver)
 		return 1;
-	
-	spin_lock(&pa_lock);
 
-	/* Locate a driver which agrees to manage this device.  */
-	for (driver = pa_drivers; driver; driver = driver->next) {
-		if (!match_device(driver,dev))
-			continue;
-		if (driver->probe(dev) == 0)
-			break;
-	}
-
-	if (driver != NULL) {
-		claim_device(driver, dev);
-	}
-	spin_unlock(&pa_lock);
-	return driver != NULL;
+	return 0;
 }
 
 #define BC_PORT_MASK 0x8
@@ -596,6 +570,36 @@
 	struct parisc_device *dev;
 	for (dev = parent->child; dev != parent->sibling; dev = next_dev(dev)) {
 		print_parisc_device(dev);
+	}
+}
+
+void parisc_generic_device_register(void)
+{
+	struct parisc_device *dev;
+	char tmp1[32], tmp2[32];
+
+	bus_register(&parisc_bus_type);
+
+	for_each_padev(dev) {
+		/* set up the generic device tree for this */
+		snprintf(tmp1, sizeof(tmp1), "%d", dev->hw_path);
+		if(dev->parent && dev->parent != &root) {
+			struct parisc_device *ndev;
+
+			dev->dev.parent = &dev->parent->dev;
+			for(ndev = dev->parent; ndev != &root;
+			    ndev = ndev->parent) {
+				snprintf(tmp2, sizeof(tmp2), "%d:%s",
+					 ndev->hw_path, tmp1);
+				strncpy(tmp1, tmp2, sizeof(tmp1));
+			}
+		}
+		dev->dev.bus = &parisc_bus_type;
+		snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), "parisc%s",
+			 tmp1);
+		/* make the generic dma mask a pointer to the parisc one */
+		dev->dev.dma_mask = &dev->dma_mask;
+		device_register(&dev->dev);
 	}
 }
 
diff -Nru a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c
--- a/arch/parisc/kernel/inventory.c	Tue Dec 24 17:51:15 2002
+++ b/arch/parisc/kernel/inventory.c	Tue Dec 24 17:51:15 2002
@@ -28,6 +28,7 @@
 #include <asm/pdc.h>
 #include <asm/processor.h>
 #include <asm/page.h>
+#include <asm/parisc-device.h>
 
 /*
 ** Debug options
@@ -588,6 +589,8 @@
 
 void __init do_device_inventory(void)
 {
+	extern void parisc_generic_device_register(void);
+
 	printk(KERN_INFO "Searching for devices...\n");
 
 	switch (pdc_type) {
@@ -607,7 +610,7 @@
 	default:
 		panic("Unknown PDC type!\n");
 	}
-
+	parisc_generic_device_register();
 	printk(KERN_INFO "Found devices:\n");
 	print_parisc_devices();
 }
diff -Nru a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
--- a/arch/parisc/kernel/pci-dma.c	Tue Dec 24 17:51:15 2002
+++ b/arch/parisc/kernel/pci-dma.c	Tue Dec 24 17:51:15 2002
@@ -71,7 +71,7 @@
 static inline void dump_resmap(void) {;}
 #endif
 
-static int pa11_dma_supported( struct pci_dev *dev, u64 mask)
+static int pa11_dma_supported( struct device *dev, u64 mask)
 {
 	return 1;
 }
@@ -349,7 +349,7 @@
 
 __initcall(pcxl_dma_init);
 
-static void * pa11_dma_alloc_consistent (struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
+static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_addr_t *dma_handle)
 {
 	unsigned long vaddr;
 	unsigned long paddr;
@@ -369,13 +369,13 @@
 ** ISA cards will certainly only support 24-bit DMA addressing.
 ** Not clear if we can, want, or need to support ISA.
 */
-	if (!hwdev || hwdev->dma_mask != 0xffffffff)
+	if (!dev || *dev->dma_mask != 0xffffffff)
 		gfp |= GFP_DMA;
 #endif
 	return (void *)vaddr;
 }
 
-static void pa11_dma_free_consistent (struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+static void pa11_dma_free_consistent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)
 {
 	int order;
 
@@ -386,9 +386,9 @@
 	free_pages((unsigned long)__va(dma_handle), order);
 }
 
-static dma_addr_t pa11_dma_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
+static dma_addr_t pa11_dma_map_single(struct device *dev, void *addr, size_t size, enum dma_data_direction direction)
 {
-	if (direction == PCI_DMA_NONE) {
+	if (direction == DMA_NONE) {
 		printk(KERN_ERR "pa11_dma_map_single(PCI_DMA_NONE) called by %p\n", __builtin_return_address(0));
 		BUG();
 	}
@@ -397,14 +397,14 @@
 	return virt_to_phys(addr);
 }
 
-static void pa11_dma_unmap_single(struct pci_dev *dev, dma_addr_t dma_handle, size_t size, int direction)
+static void pa11_dma_unmap_single(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
 {
-	if (direction == PCI_DMA_NONE) {
+	if (direction == DMA_NONE) {
 		printk(KERN_ERR "pa11_dma_unmap_single(PCI_DMA_NONE) called by %p\n", __builtin_return_address(0));
 		BUG();
 	}
 
-	if (direction == PCI_DMA_TODEVICE)
+	if (direction == DMA_TO_DEVICE)
 	    return;
 
 	/*
@@ -417,11 +417,11 @@
 	return;
 }
 
-static int pa11_dma_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+static int pa11_dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction)
 {
 	int i;
 
-	if (direction == PCI_DMA_NONE)
+	if (direction == DMA_NONE)
 	    BUG();
 
 	for (i = 0; i < nents; i++, sglist++ ) {
@@ -433,14 +433,14 @@
 	return nents;
 }
 
-static void pa11_dma_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+static void pa11_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction)
 {
 	int i;
 
-	if (direction == PCI_DMA_NONE)
+	if (direction == DMA_NONE)
 	    BUG();
 
-	if (direction == PCI_DMA_TODEVICE)
+	if (direction == DMA_TO_DEVICE)
 	    return;
 
 	/* once we do combining we'll need to use phys_to_virt(sg_dma_address(sglist)) */
@@ -450,15 +450,15 @@
 	return;
 }
 
-static void pa11_dma_sync_single(struct pci_dev *dev, dma_addr_t dma_handle, size_t size, int direction)
+static void pa11_dma_sync_single(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction)
 {
-	if (direction == PCI_DMA_NONE)
+	if (direction == DMA_NONE)
 	    BUG();
 
-	flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle), size);
+	flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle) + offset, size);
 }
 
-static void pa11_dma_sync_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+static void pa11_dma_sync_sg(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction)
 {
 	int i;
 
@@ -468,40 +468,56 @@
 		flush_kernel_dcache_range(sg_virt_addr(sglist), sglist->length);
 }
 
-struct pci_dma_ops pcxl_dma_ops = {
-	pa11_dma_supported,			/* dma_support */
-	pa11_dma_alloc_consistent,
-	pa11_dma_free_consistent,
-	pa11_dma_map_single,			/* map_single */
-	pa11_dma_unmap_single,			/* unmap_single */
-	pa11_dma_map_sg,			/* map_sg */
-	pa11_dma_unmap_sg,			/* unmap_sg */
-	pa11_dma_sync_single,			/* dma_sync_single */
-	pa11_dma_sync_sg			/* dma_sync_sg */
+struct hppa_dma_ops pcxl_dma_ops = {
+	.dma_supported =	pa11_dma_supported,
+	.alloc_consistent =	pa11_dma_alloc_consistent,
+	.alloc_noncoherent =	pa11_dma_alloc_consistent,
+	.free_consistent =	pa11_dma_free_consistent,
+	.map_single =		pa11_dma_map_single,
+	.unmap_single =		pa11_dma_unmap_single,
+	.map_sg =		pa11_dma_map_sg,
+	.unmap_sg =		pa11_dma_unmap_sg,
+	.dma_sync_single =	pa11_dma_sync_single,
+	.dma_sync_sg =		pa11_dma_sync_sg,
 };
 
-static void *fail_alloc_consistent(struct pci_dev *hwdev, size_t size,
-		dma_addr_t *dma_handle)
+static void *fail_alloc_consistent(struct device *dev, size_t size,
+				   dma_addr_t *dma_handle)
 {
 	return NULL;
 }
 
-static void fail_free_consistent(struct pci_dev *dev, size_t size,
-		void *vaddr, dma_addr_t iova)
+static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
+					  dma_addr_t *dma_handle)
+{
+	void *addr = NULL;
+
+	/* rely on kmalloc to be cacheline aligned */
+	addr = kmalloc(size, GFP_KERNEL);
+	if(addr)
+		*dma_handle = (dma_addr_t)virt_to_phys(addr);
+
+	return addr;
+}
+
+static void pa11_dma_free_noncoherent(struct device *dev, size_t size,
+					void *vaddr, dma_addr_t iova)
 {
+	kfree(vaddr);
 	return;
 }
 
-struct pci_dma_ops pcx_dma_ops = {
-	pa11_dma_supported,			/* dma_support */
-	fail_alloc_consistent,
-	fail_free_consistent,
-	pa11_dma_map_single,			/* map_single */
-	pa11_dma_unmap_single,			/* unmap_single */
-	pa11_dma_map_sg,			/* map_sg */
-	pa11_dma_unmap_sg,			/* unmap_sg */
-	pa11_dma_sync_single,			/* dma_sync_single */
-	pa11_dma_sync_sg			/* dma_sync_sg */
+struct hppa_dma_ops pcx_dma_ops = {
+	.dma_supported =	pa11_dma_supported,
+	.alloc_consistent =	fail_alloc_consistent,
+	.alloc_noncoherent =	pa11_dma_alloc_noncoherent,
+	.free_consistent =	pa11_dma_free_noncoherent,
+	.map_single =		pa11_dma_map_single,
+	.unmap_single =		pa11_dma_unmap_single,
+	.map_sg =		pa11_dma_map_sg,
+	.unmap_sg =		pa11_dma_unmap_sg,
+	.dma_sync_single =	pa11_dma_sync_single,
+	.dma_sync_sg =		pa11_dma_sync_sg,
 };
 
 
diff -Nru a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
--- a/arch/parisc/kernel/pci.c	Tue Dec 24 17:51:15 2002
+++ b/arch/parisc/kernel/pci.c	Tue Dec 24 17:51:15 2002
@@ -238,7 +238,7 @@
 	if (res->flags & IORESOURCE_IO) {
 		barval = PCI_PORT_ADDR(res->start);
 	} else if (res->flags & IORESOURCE_MEM) {
-		barval = PCI_BUS_ADDR(HBA_DATA(dev->bus->sysdata), res->start);
+		barval = PCI_BUS_ADDR(HBA_DATA(dev->bus->dev->platform_data), res->start);
 	} else {
 		panic("pcibios_update_resource() WTF? flags not IO or MEM");
 	}
@@ -350,7 +350,7 @@
 	struct pbus_set_ranges_data *ranges
 	)
 {
-	struct pci_hba_data *hba = HBA_DATA(bus->sysdata);
+	struct pci_hba_data *hba = HBA_DATA(bus->dev->platform_data);
 
 	/*
 	** I/O space may see busnumbers here. Something
diff -Nru a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
--- a/arch/parisc/kernel/processor.c	Tue Dec 24 17:51:15 2002
+++ b/arch/parisc/kernel/processor.c	Tue Dec 24 17:51:15 2002
@@ -42,6 +42,7 @@
 #include <asm/page.h>
 #include <asm/pdc.h>
 #include <asm/irq.h>		/* for struct irq_region */
+#include <asm/parisc-device.h>
 
 struct system_cpuinfo_parisc boot_cpu_data;
 struct cpuinfo_parisc cpu_data[NR_CPUS];
diff -Nru a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c
--- a/drivers/input/serio/hp_sdc.c	Tue Dec 24 17:51:15 2002
+++ b/drivers/input/serio/hp_sdc.c	Tue Dec 24 17:51:15 2002
@@ -72,6 +72,7 @@
 #include <linux/hil.h>
 #include <asm/io.h>
 #include <asm/system.h>
+#include <asm/parisc-device.h>
 
 #define PREFIX "HP SDC: "
 
diff -Nru a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
--- a/drivers/net/lasi_82596.c	Tue Dec 24 17:51:15 2002
+++ b/drivers/net/lasi_82596.c	Tue Dec 24 17:51:15 2002
@@ -91,6 +91,7 @@
 #include <asm/irq.h>
 #include <asm/pdc.h>
 #include <asm/cache.h>
+#include <asm/parisc-device.h>
 
 static char version[] __devinitdata =
 	"82596.c $Revision: 1.29 $\n";
diff -Nru a/drivers/parisc/asp.c b/drivers/parisc/asp.c
--- a/drivers/parisc/asp.c	Tue Dec 24 17:51:15 2002
+++ b/drivers/parisc/asp.c	Tue Dec 24 17:51:15 2002
@@ -76,6 +76,8 @@
 
 	printk(KERN_INFO "%s version %d at 0x%lx found.\n", 
 		asp->name, asp->version, dev->hpa);
+	snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %d",
+		 asp->name, asp->version);
 
 	/* the IRQ ASP should use */
 	ret = -EBUSY;
diff -Nru a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
--- a/drivers/parisc/ccio-dma.c	Tue Dec 24 17:51:15 2002
+++ b/drivers/parisc/ccio-dma.c	Tue Dec 24 17:51:15 2002
@@ -50,6 +50,7 @@
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/hardware.h>       /* for register_module() */
+#include <asm/parisc-device.h>
 
 /* 
 ** Choose "ccio" since that's what HP-UX calls it.
@@ -599,7 +600,7 @@
  * This function implements the pci_dma_supported function.
  */
 static int 
-ccio_dma_supported(struct pci_dev *dev, u64 mask)
+ccio_dma_supported(struct device *dev, u64 mask)
 {
 	if(dev == NULL) {
 		printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
@@ -621,7 +622,8 @@
  * This function implements the pci_map_single function.
  */
 static dma_addr_t 
-ccio_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
+ccio_map_single(struct device *dev, void *addr, size_t size,
+		enum dma_data_direction direction)
 {
 	int idx;
 	struct ioc *ioc;
@@ -629,11 +631,9 @@
 	dma_addr_t iovp;
 	dma_addr_t offset;
 	u64 *pdir_start;
-	unsigned long hint = hint_lookup[direction];
+	unsigned long hint = hint_lookup[(int)direction];
 
-	ASSERT(dev);
-	ASSERT(dev->sysdata);
-	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	BUG_ON(!dev);
 	ioc = GET_IOC(dev);
 
 	ASSERT(size > 0);
@@ -690,16 +690,14 @@
  * This function implements the pci_unmap_single function.
  */
 static void 
-ccio_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, 
-		  int direction)
+ccio_unmap_single(struct device *dev, dma_addr_t iova, size_t size, 
+		  enum dma_data_direction direction)
 {
 	struct ioc *ioc;
 	unsigned long flags; 
 	dma_addr_t offset = iova & ~IOVP_MASK;
 	
-	ASSERT(dev);
-	ASSERT(dev->sysdata);
-	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	BUG_ON(!dev);
 	ioc = GET_IOC(dev);
 
 	DBG_RUN("%s() iovp 0x%lx/%x\n",
@@ -730,7 +728,7 @@
  * This function implements the pci_alloc_consistent function.
  */
 static void * 
-ccio_alloc_consistent(struct pci_dev *dev, size_t size, dma_addr_t *dma_handle)
+ccio_alloc_consistent(struct device *dev, size_t size, dma_addr_t *dma_handle)
 {
       void *ret;
 #if 0
@@ -763,7 +761,7 @@
  * This function implements the pci_free_consistent function.
  */
 static void 
-ccio_free_consistent(struct pci_dev *dev, size_t size, void *cpu_addr, 
+ccio_free_consistent(struct device *dev, size_t size, void *cpu_addr, 
 		     dma_addr_t dma_handle)
 {
 	ccio_unmap_single(dev, dma_handle, size, 0);
@@ -962,17 +960,15 @@
  * This function implements the pci_map_sg function.
  */
 static int
-ccio_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, 
-	    int direction)
+ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents, 
+	    enum dma_data_direction direction)
 {
 	struct ioc *ioc;
 	int coalesced, filled = 0;
 	unsigned long flags;
-	unsigned long hint = hint_lookup[direction];
+	unsigned long hint = hint_lookup[(int)direction];
 	
-	ASSERT(dev);
-	ASSERT(dev->sysdata);
-	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	BUG_ON(!dev);
 	ioc = GET_IOC(dev);
 	
 	DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents);
@@ -1030,14 +1026,12 @@
  * This function implements the pci_unmap_sg function.
  */
 static void 
-ccio_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, 
-	      int direction)
+ccio_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents, 
+	      enum dma_data_direction direction)
 {
 	struct ioc *ioc;
 
-	ASSERT(dev);
-	ASSERT(dev->sysdata);
-	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	BUG_ON(!dev);
 	ioc = GET_IOC(dev);
 
 	DBG_RUN_SG("%s() START %d entries,  %08lx,%x\n",
@@ -1060,16 +1054,17 @@
 	DBG_RUN_SG("%s() DONE (nents %d)\n", __FUNCTION__, nents);
 }
 
-static struct pci_dma_ops ccio_ops = {
-	ccio_dma_supported,
-	ccio_alloc_consistent,
-	ccio_free_consistent,
-	ccio_map_single,
-	ccio_unmap_single,
-	ccio_map_sg,
-	ccio_unmap_sg,
-	NULL,                   /* dma_sync_single : NOP for U2/Uturn */
-	NULL,                   /* dma_sync_sg     : ditto */
+static struct hppa_dma_ops ccio_ops = {
+	.dma_supported =	ccio_dma_supported,
+	.alloc_consistent =	ccio_alloc_consistent,
+	.alloc_noncoherent =	ccio_alloc_consistent,
+	.free_consistent =	ccio_free_consistent,
+	.map_single =		ccio_map_single,
+	.unmap_single =		ccio_unmap_single,
+	.map_sg = 		ccio_map_sg,
+	.unmap_sg = 		ccio_unmap_sg,
+	.dma_sync_single =	NULL,	/* NOP for U2/Uturn */
+	.dma_sync_sg =		NULL,	/* ditto */
 };
 
 #ifdef CONFIG_PROC_FS
@@ -1527,6 +1522,7 @@
 	memset(ioc, 0, sizeof(struct ioc));
 
 	ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
+	strncpy(dev->dev.name, ioc->name, sizeof(dev->dev.name));
 
 	printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa);
 
@@ -1540,6 +1536,12 @@
 	ccio_ioc_init(ioc);
 	ccio_init_resources(ioc);
 	hppa_dma_ops = &ccio_ops;
+	dev->dev.platform_data = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL);
+
+	/* if this fails, no I/O cards will work, so may as well bug */
+	BUG_ON(dev->dev.platform_data == NULL);
+	HBA_DATA(dev->dev.platform_data)->iommu = ioc;
+	
 
 	if (ioc_count == 0) {
 		/* XXX: Create separate entries for each ioc */
@@ -1575,13 +1577,13 @@
 	}
 	memset(ioc->fake_pci_dev, 0, sizeof(struct pci_dev));
 
-	ioc->fake_pci_dev->sysdata = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL);
-	if(ioc->fake_pci_dev->sysdata == NULL) {
+	ioc->fake_pci_dev->dev.platform_data = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL);
+	if(ioc->fake_pci_dev->dev.platform_data == NULL) {
 		printk(KERN_ERR MODULE_NAME ": memory allocation failure\n");
 		return NULL;
 	}
 
-	HBA_DATA(ioc->fake_pci_dev->sysdata)->iommu = ioc;
+	HBA_DATA(ioc->fake_pci_dev->dev.platform_data)->iommu = ioc;
 	return ioc->fake_pci_dev;
 }
 
@@ -1593,7 +1595,7 @@
 };
 
 static struct parisc_driver ccio_driver = {
-	.name =		"U2/Uturn",
+	.name =		"U2:Uturn",
 	.id_table =	ccio_tbl,
 	.probe =	ccio_probe,
 };
diff -Nru a/drivers/parisc/dino.c b/drivers/parisc/dino.c
--- a/drivers/parisc/dino.c	Tue Dec 24 17:51:15 2002
+++ b/drivers/parisc/dino.c	Tue Dec 24 17:51:15 2002
@@ -168,7 +168,7 @@
 static int dino_cfg_read(struct pci_bus *bus, unsigned int devfn, int where,
 		int size, u32 *val)
 {
-	struct dino_device *d = DINO_DEV(bus->sysdata);
+	struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->dev));
 	u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
 	u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
 	unsigned long base_addr = d->hba.base_addr;
@@ -202,7 +202,7 @@
 static int dino_cfg_write(struct pci_bus *bus, unsigned int devfn, int where,
 	int size, u32 val)
 {
-	struct dino_device *d = DINO_DEV(bus->sysdata);
+	struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->dev));
 	u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
 	u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
 	unsigned long base_addr = d->hba.base_addr;
@@ -475,7 +475,7 @@
 dino_card_setup(struct pci_bus *bus, unsigned long base_addr)
 {
 	int i;
-	struct dino_device *dino_dev = DINO_DEV(bus->sysdata);
+	struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->dev));
 	struct resource *res;
 
 	res = &dino_dev->hba.lmmio_space;
@@ -545,11 +545,11 @@
 {
 	struct list_head *ln;
         struct pci_dev *dev;
-        struct dino_device *dino_dev = DINO_DEV(bus->sysdata);
+        struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->dev));
 	int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num);
 
 	DBG(KERN_WARNING "%s(0x%p) bus %d sysdata 0x%p\n",
-			__FUNCTION__, bus, bus->secondary, bus->sysdata);
+			__FUNCTION__, bus, bus->secondary, bus->dev->platform_data);
 
 	/* Firmware doesn't set up card-mode dino, so we have to */
 	if (is_card_dino(&dino_dev->hba.dev->id))
@@ -836,6 +836,8 @@
 	}
 
 	printk("%s version %s found at 0x%lx\n", name, version, dev->hpa);
+	snprintf(dev->dev.name, sizeof(dev->dev.name), 
+		 "%s version %s", name, version);
 
 	if (!request_mem_region(dev->hpa, PAGE_SIZE, name)) {
 		printk(KERN_ERR "DINO: Hey! Someone took my MMIO space (0x%ld)!\n",
@@ -891,13 +893,15 @@
 	if (dino_common_init(dev, dino_dev, name))
 		return 1;
 
+	dev->dev.platform_data = dino_dev;
+
 	/*
 	** It's not used to avoid chicken/egg problems
 	** with configuration accessor functions.
 	*/
-	dino_dev->hba.hba_bus = pci_scan_bus(dino_dev->hba.hba_num,
-			&dino_cfg_ops, dino_dev);
-
+	dino_dev->hba.hba_bus = 
+		pci_scan_bus_parented(&dev->dev, dino_dev->hba.hba_num,
+				      &dino_cfg_ops, NULL);
 	return 0;
 }
 
diff -Nru a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
--- a/drivers/parisc/eisa.c	Tue Dec 24 17:51:15 2002
+++ b/drivers/parisc/eisa.c	Tue Dec 24 17:51:15 2002
@@ -40,6 +40,7 @@
 #include <asm/io.h>
 #include <asm/hardware.h>
 #include <asm/processor.h>
+#include <asm/parisc-device.h>
 #include <asm/delay.h>
 #include <asm/eisa_bus.h>
 
@@ -322,6 +323,7 @@
 
 	printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n", 
 		name, dev->hpa);
+	snprintf(dev->dev.name, sizeof(dev->dev.name), "%s EISA", name);
 
 	eisa_dev.hba.dev = dev;
 	eisa_dev.hba.iommu = ccio_get_iommu(dev);
diff -Nru a/drivers/parisc/gsc.h b/drivers/parisc/gsc.h
--- a/drivers/parisc/gsc.h	Tue Dec 24 17:51:15 2002
+++ b/drivers/parisc/gsc.h	Tue Dec 24 17:51:15 2002
@@ -8,6 +8,7 @@
 
 #include <linux/interrupt.h>
 #include <asm/hardware.h>
+#include <asm/parisc-device.h>
 
 #define OFFSET_IRR 0x0000   /* Interrupt request register */
 #define OFFSET_IMR 0x0004   /* Interrupt mask register */
diff -Nru a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c
--- a/drivers/parisc/hppb.c	Tue Dec 24 17:51:15 2002
+++ b/drivers/parisc/hppb.c	Tue Dec 24 17:51:15 2002
@@ -25,7 +25,9 @@
 
 #include <asm/io.h>
 #include <asm/hardware.h>
-#include <asm/pci.h>
+#include <asm/parisc-device.h>
+
+#include <linux/pci.h>
 
 struct hppb_card {
 	unsigned long hpa;
@@ -68,6 +70,7 @@
 		card = card->next;
 	}
         printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa);
+	snprintf(dev->dev.name, sizeof(dev->dev.name), "GeckoBoa");
 
 	card->hpa = dev->hpa;
 	card->mmio_region.name = "HP-PB Bus";
@@ -94,7 +97,7 @@
 static struct parisc_driver hppb_driver = {
         .name =         "Gecko Boa",
         .id_table =     hppb_tbl,
-        .probe =        hppb_probe,
+	.probe =        hppb_probe,
 };
 
 /**
diff -Nru a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c
--- a/drivers/parisc/lasi.c	Tue Dec 24 17:51:15 2002
+++ b/drivers/parisc/lasi.c	Tue Dec 24 17:51:15 2002
@@ -185,6 +185,8 @@
 	lasi->version = gsc_readl(lasi->hpa + LASI_VER) & 0xf;
 	printk(KERN_INFO "%s version %d at 0x%lx found.\n",
 		lasi->name, lasi->version, lasi->hpa);
+	snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %d",
+		 lasi->name, lasi->version);
 
 	/* initialize the chassis LEDs really early */ 
 	lasi_led_init(lasi->hpa);
diff -Nru a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
--- a/drivers/parisc/lba_pci.c	Tue Dec 24 17:51:15 2002
+++ b/drivers/parisc/lba_pci.c	Tue Dec 24 17:51:15 2002
@@ -48,6 +48,7 @@
 #include <asm/system.h>
 
 #include <asm/hardware.h>	/* for register_parisc_driver() stuff */
+#include <asm/parisc-device.h>
 #include <asm/iosapic.h>	/* for iosapic_register() */
 #include <asm/io.h>		/* read/write stuff */
 
@@ -507,7 +508,7 @@
 
 static int lba_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data)
 {
-	struct lba_device *d = LBA_DEV(bus->sysdata);
+	struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->dev));
 	u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
 	u32 tok = LBA_CFG_TOK(local_bus, devfn);
 
@@ -591,7 +592,7 @@
 
 static int lba_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data)
 {
-	struct lba_device *d = LBA_DEV(bus->sysdata);
+	struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->dev));
 	u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
 	u32 tok = LBA_CFG_TOK(local_bus,devfn);
 
@@ -697,11 +698,11 @@
 	u16 fbb_enable = PCI_STATUS_FAST_BACK;
 	u16 status;
 #endif
-	struct lba_device *ldev = LBA_DEV(bus->sysdata);
+	struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->dev));
 	int lba_portbase = HBA_PORT_BASE(ldev->hba.hba_num);
 
 	DBG("lba_fixup_bus(0x%p) bus %d sysdata 0x%p\n",
-		bus, bus->secondary, bus->sysdata);
+		bus, bus->secondary, bus->dev->platform_data);
 
 	/*
 	** Properly Setup MMIO resources for this bus.
@@ -1357,6 +1358,8 @@
 
 	printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
 		MODULE_NAME, version, func_class & 0xf, dev->hpa);
+	snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %s",
+		 MODULE_NAME, version);
 
 	/* Just in case we find some prototypes... */
 	if (func_class < 2) {
@@ -1425,8 +1428,10 @@
 	** Tell PCI support another PCI bus was found.
 	** Walks PCI bus for us too.
 	*/
+	dev->dev.platform_data = lba_dev;
 	lba_bus = lba_dev->hba.hba_bus =
-		pci_scan_bus(lba_dev->hba.bus_num.start, &lba_cfg_ops, (void *) lba_dev);
+		pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start,
+				      &lba_cfg_ops, NULL);
 
 #ifdef __LP64__
 	if (is_pdc_pat()) {
@@ -1464,7 +1469,7 @@
 static struct parisc_driver lba_driver = {
 	.name =		MODULE_NAME,
 	.id_table =	lba_tbl,
-	.probe =	lba_driver_callback
+	.probe =	lba_driver_callback,
 };
 
 /*
diff -Nru a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
--- a/drivers/parisc/sba_iommu.c	Tue Dec 24 17:51:15 2002
+++ b/drivers/parisc/sba_iommu.c	Tue Dec 24 17:51:15 2002
@@ -40,6 +40,7 @@
 #include <linux/proc_fs.h>
 #include <asm/runway.h>		/* for proc_runway_root */
 #include <asm/pdc.h>		/* for PDC_MODEL_* */
+#include <asm/parisc-device.h>
 
 #define MODULE_NAME "SBA"
 
@@ -803,7 +804,7 @@
  * See Documentation/DMA-mapping.txt
  */
 static int
-sba_dma_supported( struct pci_dev *dev, u64 mask)
+sba_dma_supported( struct device *dev, u64 mask)
 {
 	if (dev == NULL) {
 		printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
@@ -826,7 +827,8 @@
  * See Documentation/DMA-mapping.txt
  */
 static dma_addr_t
-sba_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
+sba_map_single(struct device *dev, void *addr, size_t size,
+	       enum dma_data_direction direction)
 {
 	struct ioc *ioc;
 	unsigned long flags; 
@@ -838,7 +840,6 @@
 	ASSERT(size > 0);
 	ASSERT(size <= DMA_CHUNK_SIZE);
 
-	ASSERT(dev->sysdata);
 	ioc = GET_IOC(dev);
 	ASSERT(ioc);
 
@@ -904,7 +905,8 @@
  * See Documentation/DMA-mapping.txt
  */
 static void
-sba_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, int direction)
+sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
+		 enum dma_data_direction direction)
 {
 	struct ioc *ioc;
 #if DELAYED_RESOURCE_CNT > 0
@@ -913,7 +915,6 @@
 	unsigned long flags; 
 	dma_addr_t offset;
 
-	ASSERT(dev->sysdata);
 	ioc = GET_IOC(dev);
 	ASSERT(ioc);
 
@@ -974,7 +975,7 @@
  * See Documentation/DMA-mapping.txt
  */
 static void *
-sba_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
+sba_alloc_consistent(struct device *hwdev, size_t size, dma_addr_t *dma_handle)
 {
 	void *ret;
 
@@ -1005,7 +1006,8 @@
  * See Documentation/DMA-mapping.txt
  */
 static void
-sba_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+sba_free_consistent(struct device *hwdev, size_t size, void *vaddr,
+		    dma_addr_t dma_handle)
 {
 	sba_unmap_single(hwdev, dma_handle, size, 0);
 	free_pages((unsigned long) vaddr, get_order(size));
@@ -1267,7 +1269,8 @@
  * See Documentation/DMA-mapping.txt
  */
 static int
-sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
+	   enum dma_data_direction direction)
 {
 	struct ioc *ioc;
 	int coalesced, filled = 0;
@@ -1275,7 +1278,6 @@
 
 	DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents);
 
-	ASSERT(dev->sysdata);
 	ioc = GET_IOC(dev);
 	ASSERT(ioc);
 
@@ -1349,7 +1351,8 @@
  * See Documentation/DMA-mapping.txt
  */
 static void 
-sba_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
+	     enum dma_data_direction direction)
 {
 	struct ioc *ioc;
 #ifdef ASSERT_PDIR_SANITY
@@ -1359,7 +1362,6 @@
 	DBG_RUN_SG("%s() START %d entries,  %p,%x\n",
 		__FUNCTION__, nents, sg_virt_addr(sglist), sglist->length);
 
-	ASSERT(dev->sysdata);
 	ioc = GET_IOC(dev);
 	ASSERT(ioc);
 
@@ -1393,16 +1395,17 @@
 
 }
 
-static struct pci_dma_ops sba_ops = {
-	sba_dma_supported,
-	sba_alloc_consistent,	/* allocate cacheable host mem */
-	sba_free_consistent,	/* release cacheable host mem */
-	sba_map_single,
-	sba_unmap_single,
-	sba_map_sg,
-	sba_unmap_sg,
-	NULL,			/* dma_sync_single */
-	NULL			/* dma_sync_sg */
+static struct hppa_dma_ops sba_ops = {
+	.dma_supported =	sba_dma_supported,
+	.alloc_consistent =	sba_alloc_consistent,
+	.alloc_noncoherent =	sba_alloc_consistent,
+	.free_consistent =	sba_free_consistent,
+	.map_single =		sba_map_single,
+	.unmap_single =		sba_unmap_single,
+	.map_sg =		sba_map_sg,
+	.unmap_sg =		sba_unmap_sg,
+	.dma_sync_single =	NULL,
+	.dma_sync_sg =		NULL,
 };
 
 
@@ -1975,6 +1978,8 @@
 
 	printk(KERN_INFO "%s found %s at 0x%lx\n",
 		MODULE_NAME, version, dev->hpa);
+	snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %s",
+		 MODULE_NAME, version);
 
 #ifdef DEBUG_SBA_INIT
 	sba_dump_tlb(dev->hpa);
diff -Nru a/drivers/parisc/wax.c b/drivers/parisc/wax.c
--- a/drivers/parisc/wax.c	Tue Dec 24 17:51:15 2002
+++ b/drivers/parisc/wax.c	Tue Dec 24 17:51:15 2002
@@ -83,6 +83,8 @@
 
 	wax->version = 0;   /* gsc_readb(wax->hpa+WAX_VER); */
 	printk(KERN_INFO "%s at 0x%lx found.\n", wax->name, wax->hpa);
+	snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %d",
+		 wax->name, wax->version);
 
 	/* Stop wax hissing for a bit */
 	wax_init_irq(wax);
diff -Nru a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c
--- a/drivers/parport/parport_gsc.c	Tue Dec 24 17:51:15 2002
+++ b/drivers/parport/parport_gsc.c	Tue Dec 24 17:51:15 2002
@@ -40,6 +40,7 @@
 
 #include <linux/parport.h>
 #include <asm/pdc.h>
+#include <asm/parisc-device.h>
 #include <asm/hardware.h>
 #include <asm/parport_gsc.h>
 
diff -Nru a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
--- a/drivers/scsi/lasi700.c	Tue Dec 24 17:51:15 2002
+++ b/drivers/scsi/lasi700.c	Tue Dec 24 17:51:15 2002
@@ -50,6 +50,7 @@
 #include <asm/pgtable.h>
 #include <asm/irq.h>
 #include <asm/hardware.h>
+#include <asm/parisc-device.h>
 #include <asm/delay.h>
 
 #include <linux/module.h>
diff -Nru a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
--- a/drivers/serial/8250_gsc.c	Tue Dec 24 17:51:15 2002
+++ b/drivers/serial/8250_gsc.c	Tue Dec 24 17:51:15 2002
@@ -20,6 +20,7 @@
 #include <linux/types.h>
 
 #include <asm/hardware.h>
+#include <asm/parisc-device.h>
 #include <asm/io.h>
 #include <asm/serial.h>
 
diff -Nru a/drivers/serial/mux.c b/drivers/serial/mux.c
--- a/drivers/serial/mux.c	Tue Dec 24 17:51:15 2002
+++ b/drivers/serial/mux.c	Tue Dec 24 17:51:15 2002
@@ -25,6 +25,7 @@
 #include <linux/console.h>
 #include <linux/slab.h>
 #include <asm/io.h>
+#include <asm/parisc-device.h>
 
 #ifdef CONFIG_MAGIC_SYSRQ
 #include <linux/sysrq.h>
diff -Nru a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
--- a/drivers/video/console/sticore.c	Tue Dec 24 17:51:15 2002
+++ b/drivers/video/console/sticore.c	Tue Dec 24 17:51:15 2002
@@ -25,6 +25,7 @@
 
 #include <asm/pgalloc.h>
 #include <asm/hardware.h>
+#include <asm/parisc-device.h>
 
 #include "../sticore.h"
 
diff -Nru a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-parisc/dma-mapping.h	Tue Dec 24 17:51:15 2002
@@ -0,0 +1,226 @@
+#ifndef _PARISC_DMA_MAPPING_H
+#define _PARISC_DMA_MAPPING_H
+
+#include <linux/mm.h>
+#include <asm/cacheflush.h>
+
+/*
+** See Documentation/DMA-mapping.txt
+*/
+struct hppa_dma_ops {
+	int  (*dma_supported)(struct device *dev, u64 mask);
+	void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *iova);
+	void *(*alloc_noncoherent)(struct device *dev, size_t size, dma_addr_t *iova);
+	void (*free_consistent)(struct device *dev, size_t size, void *vaddr, dma_addr_t iova);
+	dma_addr_t (*map_single)(struct device *dev, void *addr, size_t size, enum dma_data_direction direction);
+	void (*unmap_single)(struct device *dev, dma_addr_t iova, size_t size, enum dma_data_direction direction);
+	int  (*map_sg)(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction direction);
+	void (*unmap_sg)(struct device *dev, struct scatterlist *sg, int nhwents, enum dma_data_direction direction);
+	void (*dma_sync_single)(struct device *dev, dma_addr_t iova, unsigned long offset, size_t size, enum dma_data_direction direction);
+	void (*dma_sync_sg)(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction);
+};
+
+/*
+** We could live without the hppa_dma_ops indirection if we didn't want
+** to support 4 different coherent dma models with one binary (they will
+** someday be loadable modules):
+**     I/O MMU        consistent method           dma_sync behavior
+**  =============   ======================       =======================
+**  a) PA-7x00LC    uncachable host memory          flush/purge
+**  b) U2/Uturn      cachable host memory              NOP
+**  c) Ike/Astro     cachable host memory              NOP
+**  d) EPIC/SAGA     memory on EPIC/SAGA         flush/reset DMA channel
+**
+** PA-7[13]00LC processors have a GSC bus interface and no I/O MMU.
+**
+** Systems (eg PCX-T workstations) that don't fall into the above
+** categories will need to modify the needed drivers to perform
+** flush/purge and allocate "regular" cacheable pages for everything.
+*/
+
+#ifdef CONFIG_PA11
+extern struct hppa_dma_ops pcxl_dma_ops;
+extern struct hppa_dma_ops pcx_dma_ops;
+#endif
+
+extern struct hppa_dma_ops *hppa_dma_ops;
+
+static inline void *
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle)
+{
+	return hppa_dma_ops->alloc_consistent(dev, size, dma_handle);
+}
+
+static inline void *
+dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *dma_handle)
+{
+	return hppa_dma_ops->alloc_noncoherent(dev, size, dma_handle);
+}
+
+static inline void
+dma_free_coherent(struct device *dev, size_t size, 
+		    void *vaddr, dma_addr_t dma_handle)
+{
+	hppa_dma_ops->free_consistent(dev, size, vaddr, dma_handle);
+}
+
+static inline void
+dma_free_noncoherent(struct device *dev, size_t size, 
+		    void *vaddr, dma_addr_t dma_handle)
+{
+	hppa_dma_ops->free_consistent(dev, size, vaddr, dma_handle);
+}
+
+static inline dma_addr_t
+dma_map_single(struct device *dev, void *ptr, size_t size,
+	       enum dma_data_direction direction)
+{
+	return hppa_dma_ops->map_single(dev, ptr, size, direction);
+}
+
+static inline void
+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+		 enum dma_data_direction direction)
+{
+	hppa_dma_ops->unmap_single(dev, dma_addr, size, direction);
+}
+
+static inline int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	   enum dma_data_direction direction)
+{
+	return hppa_dma_ops->map_sg(dev, sg, nents, direction);
+}
+
+static inline void
+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+	     enum dma_data_direction direction)
+{
+	hppa_dma_ops->unmap_sg(dev, sg, nhwentries, direction);
+}
+
+static inline dma_addr_t
+dma_map_page(struct device *dev, struct page *page, unsigned long offset,
+	     size_t size, enum dma_data_direction direction)
+{
+	return dma_map_single(dev, (page_address(page) + (offset)), size, direction);
+}
+
+static inline void
+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+	       enum dma_data_direction direction)
+{
+	dma_unmap_single(dev, dma_address, size, direction);
+}
+
+
+static inline void
+dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size,
+		enum dma_data_direction direction)
+{
+	if(hppa_dma_ops->dma_sync_single)
+		hppa_dma_ops->dma_sync_single(dev, dma_handle, 0, size, direction);
+}
+
+static inline void
+dma_sync_single_range(struct device *dev, dma_addr_t dma_handle,
+		      unsigned long offset, size_t size,
+		      enum dma_data_direction direction)
+{
+	if(hppa_dma_ops->dma_sync_single)
+		hppa_dma_ops->dma_sync_single(dev, dma_handle, offset, size, direction);
+}
+
+static inline void
+dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems,
+		 enum dma_data_direction direction)
+{
+	if(hppa_dma_ops->dma_sync_sg)
+		hppa_dma_ops->dma_sync_sg(dev, sg, nelems, direction);
+}
+
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+	return hppa_dma_ops->dma_supported(dev, mask);
+}
+
+static inline int
+dma_set_mask(struct device *dev, u64 mask)
+{
+	if(!dev->dma_mask || !dma_supported(dev, mask))
+		return -EIO;
+
+	*dev->dma_mask = mask;
+
+	return 0;
+}
+
+static inline int
+dma_get_cache_alignment(void)
+{
+	return dcache_stride;
+}
+
+static inline int
+dma_is_consistent(dma_addr_t dma_addr)
+{
+	return (hppa_dma_ops->dma_sync_single == NULL);
+}
+
+static inline void
+dma_cache_sync(void *vaddr, size_t size,
+	       enum dma_data_direction direction)
+{
+	if(hppa_dma_ops->dma_sync_single)
+		flush_kernel_dcache_range((unsigned long)vaddr, size);
+}
+
+static inline void *
+parisc_walk_tree(struct device *dev)
+{
+	struct device *otherdev;
+	if(likely(dev->platform_data != NULL))
+		return dev->platform_data;
+	/* OK, just traverse the bus to find it */
+	for(otherdev = dev->parent; otherdev;
+	    otherdev = otherdev->parent) {
+		if(otherdev->platform_data) {
+			dev->platform_data = otherdev->platform_data;
+			break;
+		}
+	}
+	BUG_ON(!dev->platform_data);
+	return dev->platform_data;
+}
+		
+#define GET_IOC(dev) (HBA_DATA(parisc_walk_tree(dev))->iommu);	
+	
+
+#ifdef CONFIG_IOMMU_CCIO
+struct parisc_device;
+struct ioc;
+void * ccio_get_iommu(const struct parisc_device *dev);
+struct pci_dev * ccio_get_fake(const struct parisc_device *dev);
+int ccio_request_resource(const struct parisc_device *dev,
+		struct resource *res);
+int ccio_allocate_resource(const struct parisc_device *dev,
+		struct resource *res, unsigned long size,
+		unsigned long min, unsigned long max, unsigned long align,
+		void (*alignf)(void *, struct resource *, unsigned long, unsigned long),
+		void *alignf_data);
+#else /* !CONFIG_IOMMU_CCIO */
+#define ccio_get_iommu(dev) NULL
+#define ccio_get_fake(dev) NULL
+#define ccio_request_resource(dev, res) request_resource(&iomem_resource, res)
+#define ccio_allocate_resource(dev, res, size, min, max, align, alignf, data) \
+		allocate_resource(&iomem_resource, res, size, min, max, \
+				align, alignf, data)
+#endif /* !CONFIG_IOMMU_CCIO */
+
+#ifdef CONFIG_IOMMU_SBA
+struct parisc_device;
+void * sba_get_iommu(struct parisc_device *dev);
+#endif
+
+#endif
diff -Nru a/include/asm-parisc/hardware.h b/include/asm-parisc/hardware.h
--- a/include/asm-parisc/hardware.h	Tue Dec 24 17:51:15 2002
+++ b/include/asm-parisc/hardware.h	Tue Dec 24 17:51:15 2002
@@ -23,31 +23,7 @@
 	const char	name[80];	/* The hardware description */
 };
 
-struct parisc_device {
-	unsigned long   hpa;		/* Hard Physical Address */
-	struct parisc_device_id id;
-	struct parisc_device *parent;
-	struct parisc_device *sibling;
-	struct parisc_device *child;
-	struct parisc_driver *driver;	/* Driver for this device */
-	void		*sysdata;	/* Driver instance private data */
-	char		name[80];	/* The hardware description */
-	int		irq;
-
-	char		hw_path;        /* The module number on this bus */
-	unsigned int	num_addrs;	/* some devices have additional address ranges. */
-	unsigned long	*addr;          /* which will be stored here */
- 
-#ifdef __LP64__
-	/* parms for pdc_pat_cell_module() call */
-	unsigned long	pcell_loc;	/* Physical Cell location */
-	unsigned long	mod_index;	/* PAT specific - Misc Module info */
-
-	/* generic info returned from pdc_pat_cell_module() */
-	unsigned long	mod_info;	/* PAT specific - Misc Module info */
-	unsigned long	pmod_loc;	/* physical Module location */
-#endif
-};
+struct parisc_device;
 
 enum cpu_type {
 	pcx	= 0, /* pa7000		pa 1.0  */
@@ -65,12 +41,7 @@
 
 extern char *cpu_name_version[][2]; /* mapping from enum cpu_type to strings */
 
-struct parisc_driver {
-	struct parisc_driver *next;
-	char *name; 
-	const struct parisc_device_id *id_table;
-	int (*probe) (struct parisc_device *dev); /* New device discovered */
-};
+struct parisc_driver;
 
 struct io_module {
         volatile uint32_t nothing;		/* reg 0 */
diff -Nru a/include/asm-parisc/parisc-device.h b/include/asm-parisc/parisc-device.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-parisc/parisc-device.h	Tue Dec 24 17:51:15 2002
@@ -0,0 +1,43 @@
+#include <linux/device.h>
+
+struct parisc_device {
+	unsigned long   hpa;		/* Hard Physical Address */
+	struct parisc_device_id id;
+	struct parisc_device *parent;
+	struct parisc_device *sibling;
+	struct parisc_device *child;
+	struct parisc_driver *driver;	/* Driver for this device */
+	void		*sysdata;	/* Driver instance private data */
+	char		name[80];	/* The hardware description */
+	int		irq;
+
+	char		hw_path;        /* The module number on this bus */
+	unsigned int	num_addrs;	/* some devices have additional address ranges. */
+	unsigned long	*addr;          /* which will be stored here */
+ 
+#ifdef __LP64__
+	/* parms for pdc_pat_cell_module() call */
+	unsigned long	pcell_loc;	/* Physical Cell location */
+	unsigned long	mod_index;	/* PAT specific - Misc Module info */
+
+	/* generic info returned from pdc_pat_cell_module() */
+	unsigned long	mod_info;	/* PAT specific - Misc Module info */
+	unsigned long	pmod_loc;	/* physical Module location */
+#endif
+	u64		dma_mask;	/* DMA mask for I/O */
+	struct device 	dev;
+};
+
+struct parisc_driver {
+	struct parisc_driver *next;
+	char *name; 
+	const struct parisc_device_id *id_table;
+	int (*probe) (struct parisc_device *dev); /* New device discovered */
+	struct device_driver drv;
+};
+
+
+#define to_parisc_device(d)	container_of(d, struct parisc_device, dev)
+#define to_parisc_driver(d)	container_of(d, struct parisc_driver, drv)
+
+extern struct bus_type parisc_bus_type;
diff -Nru a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h
--- a/include/asm-parisc/pci.h	Tue Dec 24 17:51:15 2002
+++ b/include/asm-parisc/pci.h	Tue Dec 24 17:51:15 2002
@@ -131,74 +131,6 @@
 	void (*fixup_bus)(struct pci_bus *bus);
 };
 
-/*
-** See Documentation/DMA-mapping.txt
-*/
-struct pci_dma_ops {
-	int  (*dma_supported)(struct pci_dev *dev, u64 mask);
-	void *(*alloc_consistent)(struct pci_dev *dev, size_t size, dma_addr_t *iova);
-	void (*free_consistent)(struct pci_dev *dev, size_t size, void *vaddr, dma_addr_t iova);
-	dma_addr_t (*map_single)(struct pci_dev *dev, void *addr, size_t size, int direction);
-	void (*unmap_single)(struct pci_dev *dev, dma_addr_t iova, size_t size, int direction);
-	int  (*map_sg)(struct pci_dev *dev, struct scatterlist *sg, int nents, int direction);
-	void (*unmap_sg)(struct pci_dev *dev, struct scatterlist *sg, int nhwents, int direction);
-	void (*dma_sync_single)(struct pci_dev *dev, dma_addr_t iova, size_t size, int direction);
-	void (*dma_sync_sg)(struct pci_dev *dev, struct scatterlist *sg, int nelems, int direction);
-};
-
-
-/*
-** We could live without the hppa_dma_ops indirection if we didn't want
-** to support 4 different coherent dma models with one binary (they will
-** someday be loadable modules):
-**     I/O MMU        consistent method           dma_sync behavior
-**  =============   ======================       =======================
-**  a) PA-7x00LC    uncachable host memory          flush/purge
-**  b) U2/Uturn      cachable host memory              NOP
-**  c) Ike/Astro     cachable host memory              NOP
-**  d) EPIC/SAGA     memory on EPIC/SAGA         flush/reset DMA channel
-**
-** PA-7[13]00LC processors have a GSC bus interface and no I/O MMU.
-**
-** Systems (eg PCX-T workstations) that don't fall into the above
-** categories will need to modify the needed drivers to perform
-** flush/purge and allocate "regular" cacheable pages for everything.
-*/
-
-extern struct pci_dma_ops *hppa_dma_ops;
-
-#ifdef CONFIG_PA11
-extern struct pci_dma_ops pcxl_dma_ops;
-extern struct pci_dma_ops pcx_dma_ops;
-#endif
-
-/*
-** Oops hard if we haven't setup hppa_dma_ops by the time the first driver
-** attempts to initialize.
-** Since panic() is a (void)(), pci_dma_panic() is needed to satisfy
-** the (int)() required by pci_dma_supported() interface.
-*/
-static inline int pci_dma_panic(char *msg)
-{
-	extern void panic(const char *, ...);	/* linux/kernel.h */
-	panic(msg);
-	/* NOTREACHED */
-	return -1;
-}
-
-#define pci_dma_supported(p, m)	( \
-	(NULL == hppa_dma_ops) \
-	?  pci_dma_panic("Dynamic DMA support missing...OOPS!\n(Hint: was Astro/Ike/U2/Uturn not claimed?)\n") \
-	: hppa_dma_ops->dma_supported(p,m) \
-)
-
-#define pci_alloc_consistent(p, s, a)	hppa_dma_ops->alloc_consistent(p,s,a)
-#define pci_free_consistent(p, s, v, a)	hppa_dma_ops->free_consistent(p,s,v,a)
-#define pci_map_single(p, v, s, d)	hppa_dma_ops->map_single(p, v, s, d)
-#define pci_unmap_single(p, a, s, d)	hppa_dma_ops->unmap_single(p, a, s, d)
-#define pci_map_sg(p, sg, n, d)		hppa_dma_ops->map_sg(p, sg, n, d)
-#define pci_unmap_sg(p, sg, n, d)	hppa_dma_ops->unmap_sg(p, sg, n, d)
-
 /* pci_unmap_{single,page} is not a nop, thus... */
 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)	\
 	dma_addr_t ADDR_NAME;
@@ -213,24 +145,6 @@
 #define pci_unmap_len_set(PTR, LEN_NAME, VAL)		\
 	(((PTR)->LEN_NAME) = (VAL))
 
-/* For U2/Astro/Ike based platforms (which are fully I/O coherent)
-** dma_sync is a NOP. Let's keep the performance path short here.
-*/
-#define pci_dma_sync_single(p, a, s, d)	{ if (hppa_dma_ops->dma_sync_single) \
-	hppa_dma_ops->dma_sync_single(p, a, s, d); \
-	}
-#define pci_dma_sync_sg(p, sg, n, d)	{ if (hppa_dma_ops->dma_sync_sg) \
-	hppa_dma_ops->dma_sync_sg(p, sg, n, d); \
-	}
-
-/* No highmem on parisc, plus we have an IOMMU, so mapping pages is easy. */
-#define pci_map_page(dev, page, off, size, dir) \
-	pci_map_single(dev, (page_address(page) + (off)), size, dir)
-#define pci_unmap_page(dev,addr,sz,dir) pci_unmap_single(dev,addr,sz,dir)
-
-/* Don't support DAC yet. */
-#define pci_dac_dma_supported(pci_dev, mask)	(0)
-
 /*
 ** Stuff declared in arch/parisc/kernel/pci.c
 */
@@ -263,35 +177,13 @@
 #define PCIBIOS_MIN_IO          0x10
 #define PCIBIOS_MIN_MEM         0x1000 /* NBPG - but pci/setup-res.c dies */
 
-/* Return the index of the PCI controller for device PDEV. */
-#define pci_controller_num(PDEV)	(0)
+/* Don't support DAC yet. */
+#define pci_dac_dma_supported(pci_dev, mask)   (0)
 
-#define GET_IOC(dev) ((struct ioc *)(HBA_DATA(dev->sysdata)->iommu))
+/* Return the index of the PCI controller for device PDEV. */
+#define	pci_controller_num(PDEV)	(0)
 
-#ifdef CONFIG_IOMMU_CCIO
-struct parisc_device;
-struct ioc;
-void * ccio_get_iommu(const struct parisc_device *dev);
-struct pci_dev * ccio_get_fake(const struct parisc_device *dev);
-int ccio_request_resource(const struct parisc_device *dev,
-		struct resource *res);
-int ccio_allocate_resource(const struct parisc_device *dev,
-		struct resource *res, unsigned long size,
-		unsigned long min, unsigned long max, unsigned long align,
-		void (*alignf)(void *, struct resource *, unsigned long, unsigned long),
-		void *alignf_data);
-#else /* !CONFIG_IOMMU_CCIO */
-#define ccio_get_iommu(dev) NULL
-#define ccio_get_fake(dev) NULL
-#define ccio_request_resource(dev, res) request_resource(&iomem_resource, res)
-#define ccio_allocate_resource(dev, res, size, min, max, align, alignf, data) \
-		allocate_resource(&iomem_resource, res, size, min, max, \
-				align, alignf, data)
-#endif /* !CONFIG_IOMMU_CCIO */
-
-#ifdef CONFIG_IOMMU_SBA
-struct parisc_device;
-void * sba_get_iommu(struct parisc_device *dev);
-#endif
+/* export the pci_ DMA API in terms of the dma_ one */
+#include <asm-generic/pci-dma-compat.h>
 
 #endif /* __ASM_PARISC_PCI_H */

--==_Exmh_-8072902840--