[parisc-linux-cvs] fix problems with new device model on hppa

Helge Deller deller@gmx.de
Sun, 29 Dec 2002 21:08:31 +0100


--Boundary-00=_/Y1D+dnQS0IranA
Content-Type: text/plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On Sunday 29 December 2002 21:08, Helge Deller wrote:
> CVSROOT:	/var/cvs
> Module name:	linux-2.5
> Changes by:	deller	02/12/29 13:08:13
>
> Modified files:
> 	arch/parisc/kernel: drivers.c
>
> Log message:
> Bugfix: ensure all parent devices are registered before we register
> child devices.
> E.g. in the following list the devices marked with "*" were never
> registered in the old routine and thus crashed the kernel in
> drivers/base/core.c:188
>
> This patch makes 2.5.53 boot again my 715/64.
>
> device_register(parisc1)
> device_register(parisc2)
> device_register(parisc2)
> device_register(parisc2:0)	*
> device_register(parisc2:0:1)
> device_register(parisc2:0:2)
> device_register(parisc2:0:4)
> device_register(parisc2:0:6)
> device_register(parisc2:0:8)
> device_register(parisc2:0:10)
> device_register(parisc2:0:11)
> device_register(parisc2:0:12)
> device_register(parisc4)
> device_register(parisc5)
> device_register(parisc5)
> device_register(parisc5:0)	*
> device_register(parisc5:0:1)
> device_register(parisc5:0:2)
> device_register(parisc8)
> device_register(parisc9)


--Boundary-00=_/Y1D+dnQS0IranA
Content-Type: text/plain;
  charset="iso-8859-1";
  name="diff1"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="diff1"

Index: drivers.c
===================================================================
RCS file: /var/cvs/linux-2.5/arch/parisc/kernel/drivers.c,v
retrieving revision 1.6
diff -u -p -r1.6 drivers.c
--- drivers.c	25 Dec 2002 00:39:09 -0000	1.6
+++ drivers.c	29 Dec 2002 20:04:18 -0000
@@ -573,33 +573,58 @@ void print_subdevices(struct parisc_devi
 	}
 }
 
+
+/*
+ * parisc_generic_device_register_recursive() - internal function to recursively
+ * 	register all parisc devices
+ */
+static void parisc_generic_device_register_recursive( struct parisc_device *dev )
+{
+	char tmp1[32];
+	
+	/* has this device been registered already ? */
+	if (dev->dev.parent)
+		return;
+	
+	/* register all parents recursively */
+	if (dev->parent && dev->parent!=&root)
+		parisc_generic_device_register_recursive(dev->parent);
+	
+	/* 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;
+		char tmp2[32];
+
+		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;
+	pr_debug("device_register(%s)\n", dev->dev.bus_id);
+	device_register(&dev->dev);
+}
+
+/*
+ * parisc_generic_device_register() - register all parisc devices
+ */
 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);
+		parisc_generic_device_register_recursive( dev );
 	}
 }
 

--Boundary-00=_/Y1D+dnQS0IranA--