aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert@linux-m68k.org>2011-09-22 15:47:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-09-22 15:59:35 -0400
commita7f4d00a82feb5b311f765bf9522bc55bee0684f (patch)
treeb24166c4ecc34abfb34b900fb10dd2f0e5297298
parentfae3f6f2eed147092e4612177972d46e542cab71 (diff)
zorro: Defer device_register() until all devices have been identified
As the Amiga Zorro II address space is limited to 8.5 MiB and Zorro devices can contain only one BAR, several Amiga Zorro II expansion boards (mainly graphics cards) contain multiple Zorro devices: a small one for the control registers and one (or more) for the graphics memory. The conversion of cirrusfb to the new driver framework introduced a regression: the driver contains a zorro_driver for the first Zorro device, and uses the (old) zorro_find_device() call to find the second Zorro device. However, as the Zorro core calls device_register() as soon as a Zorro device is identified, it may not have identified the second Zorro device belonging to the same physical Zorro expansion card. Hence cirrusfb could no longer find the second part of the Picasso II graphics card, causing a NULL pointer dereference. Defer the registration of Zorro devices with the driver framework until all Zorro devices have been identified to fix this. Note that the alternative solution (modifying cirrusfb to register a zorro_driver for all Zorro devices belonging to a graphics card, instead of only for the first one, and adding a synchronization mechanism to defer initialization until all have been found), is not an option, as on some cards one device may be optional (e.g. the second bank of 2 MiB of graphics memory on the Picasso IV in Zorro II mode). Reported-by: Ingo Jürgensmann <ij@2011.bluespice.org> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org> Cc: stable@kernel.org Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/zorro/zorro.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c
index e0c2807b0970..181fa8158a8b 100644
--- a/drivers/zorro/zorro.c
+++ b/drivers/zorro/zorro.c
@@ -148,10 +148,10 @@ static int __init amiga_zorro_probe(struct platform_device *pdev)
148 } 148 }
149 platform_set_drvdata(pdev, bus); 149 platform_set_drvdata(pdev, bus);
150 150
151 /* Register all devices */
152 pr_info("Zorro: Probing AutoConfig expansion devices: %u device%s\n", 151 pr_info("Zorro: Probing AutoConfig expansion devices: %u device%s\n",
153 zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s"); 152 zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
154 153
154 /* First identify all devices ... */
155 for (i = 0; i < zorro_num_autocon; i++) { 155 for (i = 0; i < zorro_num_autocon; i++) {
156 z = &zorro_autocon[i]; 156 z = &zorro_autocon[i];
157 z->id = (z->rom.er_Manufacturer<<16) | (z->rom.er_Product<<8); 157 z->id = (z->rom.er_Manufacturer<<16) | (z->rom.er_Product<<8);
@@ -172,6 +172,11 @@ static int __init amiga_zorro_probe(struct platform_device *pdev)
172 dev_set_name(&z->dev, "%02x", i); 172 dev_set_name(&z->dev, "%02x", i);
173 z->dev.parent = &bus->dev; 173 z->dev.parent = &bus->dev;
174 z->dev.bus = &zorro_bus_type; 174 z->dev.bus = &zorro_bus_type;
175 }
176
177 /* ... then register them */
178 for (i = 0; i < zorro_num_autocon; i++) {
179 z = &zorro_autocon[i];
175 error = device_register(&z->dev); 180 error = device_register(&z->dev);
176 if (error) { 181 if (error) {
177 dev_err(&bus->dev, "Error registering device %s\n", 182 dev_err(&bus->dev, "Error registering device %s\n",