[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--