aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-12-29 00:01:32 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-31 17:06:05 -0500
commite3a411a3dfc1d633504aa63efab32b7e00318454 (patch)
tree2ba6117448edd7056c8fa48cc6a696ae73a6c21a
parent6fc5bae797a6632bbccdd49a1b6a96121368a4b9 (diff)
[SPARC64]: Fix of_iounmap() region release.
We need to pass in the resource otherwise we cannot release the region properly. We must know whether it is an I/O or MEM resource. Spotted by Eric Brower. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc/kernel/ioport.c2
-rw-r--r--arch/sparc64/kernel/of_device.c7
-rw-r--r--drivers/input/serio/i8042-sparcio.h6
-rw-r--r--drivers/serial/sunsab.c11
-rw-r--r--drivers/serial/sunsu.c10
-rw-r--r--drivers/serial/sunzilog.c14
-rw-r--r--drivers/video/bw2.c18
-rw-r--r--drivers/video/cg14.c28
-rw-r--r--drivers/video/cg3.c22
-rw-r--r--drivers/video/cg6.c33
-rw-r--r--drivers/video/ffb.c25
-rw-r--r--drivers/video/leo.c29
-rw-r--r--drivers/video/p9100.c25
-rw-r--r--drivers/video/tcx.c33
-rw-r--r--include/asm-sparc/of_device.h2
-rw-r--r--include/asm-sparc64/of_device.h2
16 files changed, 155 insertions, 112 deletions
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 00a39760877b..987ec6782f99 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -153,7 +153,7 @@ void __iomem *of_ioremap(struct resource *res, unsigned long offset,
153} 153}
154EXPORT_SYMBOL(of_ioremap); 154EXPORT_SYMBOL(of_ioremap);
155 155
156void of_iounmap(void __iomem *base, unsigned long size) 156void of_iounmap(struct resource *res, void __iomem *base, unsigned long size)
157{ 157{
158 iounmap(base); 158 iounmap(base);
159} 159}
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
index cec0eceae552..b0f3e0082a0d 100644
--- a/arch/sparc64/kernel/of_device.c
+++ b/arch/sparc64/kernel/of_device.c
@@ -144,9 +144,12 @@ void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned lo
144} 144}
145EXPORT_SYMBOL(of_ioremap); 145EXPORT_SYMBOL(of_ioremap);
146 146
147void of_iounmap(void __iomem *base, unsigned long size) 147void of_iounmap(struct resource *res, void __iomem *base, unsigned long size)
148{ 148{
149 release_region((unsigned long) base, size); 149 if (res->flags & IORESOURCE_MEM)
150 release_mem_region((unsigned long) base, size);
151 else
152 release_region((unsigned long) base, size);
150} 153}
151EXPORT_SYMBOL(of_iounmap); 154EXPORT_SYMBOL(of_iounmap);
152 155
diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h
index 54adba2d8ed5..d9ca55891cd7 100644
--- a/drivers/input/serio/i8042-sparcio.h
+++ b/drivers/input/serio/i8042-sparcio.h
@@ -16,6 +16,7 @@ static int i8042_aux_irq = -1;
16#define I8042_MUX_PHYS_DESC "sparcps2/serio%d" 16#define I8042_MUX_PHYS_DESC "sparcps2/serio%d"
17 17
18static void __iomem *kbd_iobase; 18static void __iomem *kbd_iobase;
19static struct resource *kbd_res;
19 20
20#define I8042_COMMAND_REG (kbd_iobase + 0x64UL) 21#define I8042_COMMAND_REG (kbd_iobase + 0x64UL)
21#define I8042_DATA_REG (kbd_iobase + 0x60UL) 22#define I8042_DATA_REG (kbd_iobase + 0x60UL)
@@ -60,6 +61,7 @@ static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_dev
60 i8042_kbd_irq = irq; 61 i8042_kbd_irq = irq;
61 kbd_iobase = of_ioremap(&kbd->resource[0], 62 kbd_iobase = of_ioremap(&kbd->resource[0],
62 0, 8, "kbd"); 63 0, 8, "kbd");
64 kbd_res = &kbd->resource[0];
63 } else if (!strcmp(dp->name, OBP_PS2MS_NAME1) || 65 } else if (!strcmp(dp->name, OBP_PS2MS_NAME1) ||
64 !strcmp(dp->name, OBP_PS2MS_NAME2)) { 66 !strcmp(dp->name, OBP_PS2MS_NAME2)) {
65 struct of_device *ms = of_find_device_by_node(dp); 67 struct of_device *ms = of_find_device_by_node(dp);
@@ -77,7 +79,7 @@ static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_dev
77 79
78static int __devexit sparc_i8042_remove(struct of_device *op) 80static int __devexit sparc_i8042_remove(struct of_device *op)
79{ 81{
80 of_iounmap(kbd_iobase, 8); 82 of_iounmap(kbd_res, kbd_iobase, 8);
81 83
82 return 0; 84 return 0;
83} 85}
@@ -119,7 +121,7 @@ static int __init i8042_platform_init(void)
119 if (i8042_kbd_irq == -1 || 121 if (i8042_kbd_irq == -1 ||
120 i8042_aux_irq == -1) { 122 i8042_aux_irq == -1) {
121 if (kbd_iobase) { 123 if (kbd_iobase) {
122 of_iounmap(kbd_iobase, 8); 124 of_iounmap(kbd_res, kbd_iobase, 8);
123 kbd_iobase = (void __iomem *) NULL; 125 kbd_iobase = (void __iomem *) NULL;
124 } 126 }
125 return -ENODEV; 127 return -ENODEV;
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 493d5bbb661b..145d6236954b 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -1037,7 +1037,8 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up,
1037 err = request_irq(up->port.irq, sunsab_interrupt, 1037 err = request_irq(up->port.irq, sunsab_interrupt,
1038 IRQF_SHARED, "sab", up); 1038 IRQF_SHARED, "sab", up);
1039 if (err) { 1039 if (err) {
1040 of_iounmap(up->port.membase, 1040 of_iounmap(&op->resource[0],
1041 up->port.membase,
1041 sizeof(union sab82532_async_regs)); 1042 sizeof(union sab82532_async_regs));
1042 return err; 1043 return err;
1043 } 1044 }
@@ -1064,7 +1065,8 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id *
1064 sizeof(union sab82532_async_regs), 1065 sizeof(union sab82532_async_regs),
1065 (inst * 2) + 1); 1066 (inst * 2) + 1);
1066 if (err) { 1067 if (err) {
1067 of_iounmap(up[0].port.membase, 1068 of_iounmap(&op->resource[0],
1069 up[0].port.membase,
1068 sizeof(union sab82532_async_regs)); 1070 sizeof(union sab82532_async_regs));
1069 free_irq(up[0].port.irq, &up[0]); 1071 free_irq(up[0].port.irq, &up[0]);
1070 return err; 1072 return err;
@@ -1082,10 +1084,13 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id *
1082 1084
1083static void __devexit sab_remove_one(struct uart_sunsab_port *up) 1085static void __devexit sab_remove_one(struct uart_sunsab_port *up)
1084{ 1086{
1087 struct of_device *op = to_of_device(up->port.dev);
1088
1085 uart_remove_one_port(&sunsab_reg, &up->port); 1089 uart_remove_one_port(&sunsab_reg, &up->port);
1086 if (!(up->port.line & 1)) 1090 if (!(up->port.line & 1))
1087 free_irq(up->port.irq, up); 1091 free_irq(up->port.irq, up);
1088 of_iounmap(up->port.membase, 1092 of_iounmap(&op->resource[0],
1093 up->port.membase,
1089 sizeof(union sab82532_async_regs)); 1094 sizeof(union sab82532_async_regs));
1090} 1095}
1091 1096
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 564592b2b2ba..3ec3df21816b 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1480,13 +1480,13 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
1480 return 0; 1480 return 0;
1481 1481
1482out_unmap: 1482out_unmap:
1483 of_iounmap(up->port.membase, up->reg_size); 1483 of_iounmap(&op->resource[0], up->port.membase, up->reg_size);
1484 return err; 1484 return err;
1485} 1485}
1486 1486
1487static int __devexit su_remove(struct of_device *dev) 1487static int __devexit su_remove(struct of_device *op)
1488{ 1488{
1489 struct uart_sunsu_port *up = dev_get_drvdata(&dev->dev);; 1489 struct uart_sunsu_port *up = dev_get_drvdata(&op->dev);
1490 1490
1491 if (up->su_type == SU_PORT_MS || 1491 if (up->su_type == SU_PORT_MS ||
1492 up->su_type == SU_PORT_KBD) { 1492 up->su_type == SU_PORT_KBD) {
@@ -1499,9 +1499,9 @@ static int __devexit su_remove(struct of_device *dev)
1499 } 1499 }
1500 1500
1501 if (up->port.membase) 1501 if (up->port.membase)
1502 of_iounmap(up->port.membase, up->reg_size); 1502 of_iounmap(&op->resource[0], up->port.membase, up->reg_size);
1503 1503
1504 dev_set_drvdata(&dev->dev, NULL); 1504 dev_set_drvdata(&op->dev, NULL);
1505 1505
1506 return 0; 1506 return 0;
1507} 1507}
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 75de919a9471..244f796dc625 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1379,13 +1379,15 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
1379 if (!keyboard_mouse) { 1379 if (!keyboard_mouse) {
1380 err = uart_add_one_port(&sunzilog_reg, &up[0].port); 1380 err = uart_add_one_port(&sunzilog_reg, &up[0].port);
1381 if (err) { 1381 if (err) {
1382 of_iounmap(rp, sizeof(struct zilog_layout)); 1382 of_iounmap(&op->resource[0],
1383 rp, sizeof(struct zilog_layout));
1383 return err; 1384 return err;
1384 } 1385 }
1385 err = uart_add_one_port(&sunzilog_reg, &up[1].port); 1386 err = uart_add_one_port(&sunzilog_reg, &up[1].port);
1386 if (err) { 1387 if (err) {
1387 uart_remove_one_port(&sunzilog_reg, &up[0].port); 1388 uart_remove_one_port(&sunzilog_reg, &up[0].port);
1388 of_iounmap(rp, sizeof(struct zilog_layout)); 1389 of_iounmap(&op->resource[0],
1390 rp, sizeof(struct zilog_layout));
1389 return err; 1391 return err;
1390 } 1392 }
1391 } else { 1393 } else {
@@ -1414,18 +1416,18 @@ static void __devexit zs_remove_one(struct uart_sunzilog_port *up)
1414 uart_remove_one_port(&sunzilog_reg, &up->port); 1416 uart_remove_one_port(&sunzilog_reg, &up->port);
1415} 1417}
1416 1418
1417static int __devexit zs_remove(struct of_device *dev) 1419static int __devexit zs_remove(struct of_device *op)
1418{ 1420{
1419 struct uart_sunzilog_port *up = dev_get_drvdata(&dev->dev); 1421 struct uart_sunzilog_port *up = dev_get_drvdata(&op->dev);
1420 struct zilog_layout __iomem *regs; 1422 struct zilog_layout __iomem *regs;
1421 1423
1422 zs_remove_one(&up[0]); 1424 zs_remove_one(&up[0]);
1423 zs_remove_one(&up[1]); 1425 zs_remove_one(&up[1]);
1424 1426
1425 regs = sunzilog_chip_regs[up[0].port.line / 2]; 1427 regs = sunzilog_chip_regs[up[0].port.line / 2];
1426 of_iounmap(regs, sizeof(struct zilog_layout)); 1428 of_iounmap(&op->resource[0], regs, sizeof(struct zilog_layout));
1427 1429
1428 dev_set_drvdata(&dev->dev, NULL); 1430 dev_set_drvdata(&op->dev, NULL);
1429 1431
1430 return 0; 1432 return 0;
1431} 1433}
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index c66e3d52cbf3..9bb6257d6918 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -320,7 +320,7 @@ static int __devinit bw2_init_one(struct of_device *op)
320 all->info.fbops = &bw2_ops; 320 all->info.fbops = &bw2_ops;
321 321
322 all->info.screen_base = 322 all->info.screen_base =
323 sbus_ioremap(&op->resource[0], 0, all->par.fbsize, "bw2 ram"); 323 of_ioremap(&op->resource[0], 0, all->par.fbsize, "bw2 ram");
324 all->info.par = &all->par; 324 all->info.par = &all->par;
325 325
326 bw2_blank(0, &all->info); 326 bw2_blank(0, &all->info);
@@ -329,8 +329,10 @@ static int __devinit bw2_init_one(struct of_device *op)
329 329
330 err= register_framebuffer(&all->info); 330 err= register_framebuffer(&all->info);
331 if (err < 0) { 331 if (err < 0) {
332 of_iounmap(all->par.regs, sizeof(struct bw2_regs)); 332 of_iounmap(&op->resource[0],
333 of_iounmap(all->info.screen_base, all->par.fbsize); 333 all->par.regs, sizeof(struct bw2_regs));
334 of_iounmap(&op->resource[0],
335 all->info.screen_base, all->par.fbsize);
334 kfree(all); 336 kfree(all);
335 return err; 337 return err;
336 } 338 }
@@ -351,18 +353,18 @@ static int __devinit bw2_probe(struct of_device *dev, const struct of_device_id
351 return bw2_init_one(op); 353 return bw2_init_one(op);
352} 354}
353 355
354static int __devexit bw2_remove(struct of_device *dev) 356static int __devexit bw2_remove(struct of_device *op)
355{ 357{
356 struct all_info *all = dev_get_drvdata(&dev->dev); 358 struct all_info *all = dev_get_drvdata(&op->dev);
357 359
358 unregister_framebuffer(&all->info); 360 unregister_framebuffer(&all->info);
359 361
360 of_iounmap(all->par.regs, sizeof(struct bw2_regs)); 362 of_iounmap(&op->resource[0], all->par.regs, sizeof(struct bw2_regs));
361 of_iounmap(all->info.screen_base, all->par.fbsize); 363 of_iounmap(&op->resource[0], all->info.screen_base, all->par.fbsize);
362 364
363 kfree(all); 365 kfree(all);
364 366
365 dev_set_drvdata(&dev->dev, NULL); 367 dev_set_drvdata(&op->dev, NULL);
366 368
367 return 0; 369 return 0;
368} 370}
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index 7f926c619b61..ec6a51a5822d 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -452,16 +452,20 @@ struct all_info {
452 struct cg14_par par; 452 struct cg14_par par;
453}; 453};
454 454
455static void cg14_unmap_regs(struct all_info *all) 455static void cg14_unmap_regs(struct of_device *op, struct all_info *all)
456{ 456{
457 if (all->par.regs) 457 if (all->par.regs)
458 of_iounmap(all->par.regs, sizeof(struct cg14_regs)); 458 of_iounmap(&op->resource[0],
459 all->par.regs, sizeof(struct cg14_regs));
459 if (all->par.clut) 460 if (all->par.clut)
460 of_iounmap(all->par.clut, sizeof(struct cg14_clut)); 461 of_iounmap(&op->resource[0],
462 all->par.clut, sizeof(struct cg14_clut));
461 if (all->par.cursor) 463 if (all->par.cursor)
462 of_iounmap(all->par.cursor, sizeof(struct cg14_cursor)); 464 of_iounmap(&op->resource[0],
465 all->par.cursor, sizeof(struct cg14_cursor));
463 if (all->info.screen_base) 466 if (all->info.screen_base)
464 of_iounmap(all->info.screen_base, all->par.fbsize); 467 of_iounmap(&op->resource[1],
468 all->info.screen_base, all->par.fbsize);
465} 469}
466 470
467static int __devinit cg14_init_one(struct of_device *op) 471static int __devinit cg14_init_one(struct of_device *op)
@@ -506,7 +510,7 @@ static int __devinit cg14_init_one(struct of_device *op)
506 510
507 if (!all->par.regs || !all->par.clut || !all->par.cursor || 511 if (!all->par.regs || !all->par.clut || !all->par.cursor ||
508 !all->info.screen_base) 512 !all->info.screen_base)
509 cg14_unmap_regs(all); 513 cg14_unmap_regs(op, all);
510 514
511 is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) == 515 is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) ==
512 (8 * 1024 * 1024)); 516 (8 * 1024 * 1024));
@@ -541,7 +545,7 @@ static int __devinit cg14_init_one(struct of_device *op)
541 __cg14_reset(&all->par); 545 __cg14_reset(&all->par);
542 546
543 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 547 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
544 cg14_unmap_regs(all); 548 cg14_unmap_regs(op, all);
545 kfree(all); 549 kfree(all);
546 return -ENOMEM; 550 return -ENOMEM;
547 } 551 }
@@ -552,7 +556,7 @@ static int __devinit cg14_init_one(struct of_device *op)
552 err = register_framebuffer(&all->info); 556 err = register_framebuffer(&all->info);
553 if (err < 0) { 557 if (err < 0) {
554 fb_dealloc_cmap(&all->info.cmap); 558 fb_dealloc_cmap(&all->info.cmap);
555 cg14_unmap_regs(all); 559 cg14_unmap_regs(op, all);
556 kfree(all); 560 kfree(all);
557 return err; 561 return err;
558 } 562 }
@@ -574,18 +578,18 @@ static int __devinit cg14_probe(struct of_device *dev, const struct of_device_id
574 return cg14_init_one(op); 578 return cg14_init_one(op);
575} 579}
576 580
577static int __devexit cg14_remove(struct of_device *dev) 581static int __devexit cg14_remove(struct of_device *op)
578{ 582{
579 struct all_info *all = dev_get_drvdata(&dev->dev); 583 struct all_info *all = dev_get_drvdata(&op->dev);
580 584
581 unregister_framebuffer(&all->info); 585 unregister_framebuffer(&all->info);
582 fb_dealloc_cmap(&all->info.cmap); 586 fb_dealloc_cmap(&all->info.cmap);
583 587
584 cg14_unmap_regs(all); 588 cg14_unmap_regs(op, all);
585 589
586 kfree(all); 590 kfree(all);
587 591
588 dev_set_drvdata(&dev->dev, NULL); 592 dev_set_drvdata(&op->dev, NULL);
589 593
590 return 0; 594 return 0;
591} 595}
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index 9c8c753ef454..ada6f7e3a891 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -403,8 +403,10 @@ static int __devinit cg3_init_one(struct of_device *op)
403 cg3_do_default_mode(&all->par); 403 cg3_do_default_mode(&all->par);
404 404
405 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 405 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
406 of_iounmap(all->par.regs, sizeof(struct cg3_regs)); 406 of_iounmap(&op->resource[0],
407 of_iounmap(all->info.screen_base, all->par.fbsize); 407 all->par.regs, sizeof(struct cg3_regs));
408 of_iounmap(&op->resource[0],
409 all->info.screen_base, all->par.fbsize);
408 kfree(all); 410 kfree(all);
409 return -ENOMEM; 411 return -ENOMEM;
410 } 412 }
@@ -415,8 +417,10 @@ static int __devinit cg3_init_one(struct of_device *op)
415 err = register_framebuffer(&all->info); 417 err = register_framebuffer(&all->info);
416 if (err < 0) { 418 if (err < 0) {
417 fb_dealloc_cmap(&all->info.cmap); 419 fb_dealloc_cmap(&all->info.cmap);
418 of_iounmap(all->par.regs, sizeof(struct cg3_regs)); 420 of_iounmap(&op->resource[0],
419 of_iounmap(all->info.screen_base, all->par.fbsize); 421 all->par.regs, sizeof(struct cg3_regs));
422 of_iounmap(&op->resource[0],
423 all->info.screen_base, all->par.fbsize);
420 kfree(all); 424 kfree(all);
421 return err; 425 return err;
422 } 426 }
@@ -436,19 +440,19 @@ static int __devinit cg3_probe(struct of_device *dev, const struct of_device_id
436 return cg3_init_one(op); 440 return cg3_init_one(op);
437} 441}
438 442
439static int __devexit cg3_remove(struct of_device *dev) 443static int __devexit cg3_remove(struct of_device *op)
440{ 444{
441 struct all_info *all = dev_get_drvdata(&dev->dev); 445 struct all_info *all = dev_get_drvdata(&op->dev);
442 446
443 unregister_framebuffer(&all->info); 447 unregister_framebuffer(&all->info);
444 fb_dealloc_cmap(&all->info.cmap); 448 fb_dealloc_cmap(&all->info.cmap);
445 449
446 of_iounmap(all->par.regs, sizeof(struct cg3_regs)); 450 of_iounmap(&op->resource[0], all->par.regs, sizeof(struct cg3_regs));
447 of_iounmap(all->info.screen_base, all->par.fbsize); 451 of_iounmap(&op->resource[0], all->info.screen_base, all->par.fbsize);
448 452
449 kfree(all); 453 kfree(all);
450 454
451 dev_set_drvdata(&dev->dev, NULL); 455 dev_set_drvdata(&op->dev, NULL);
452 456
453 return 0; 457 return 0;
454} 458}
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 64146be2eeb0..4dad23a28f58 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -658,21 +658,26 @@ struct all_info {
658 struct cg6_par par; 658 struct cg6_par par;
659}; 659};
660 660
661static void cg6_unmap_regs(struct all_info *all) 661static void cg6_unmap_regs(struct of_device *op, struct all_info *all)
662{ 662{
663 if (all->par.fbc) 663 if (all->par.fbc)
664 of_iounmap(all->par.fbc, 4096); 664 of_iounmap(&op->resource[0], all->par.fbc, 4096);
665 if (all->par.tec) 665 if (all->par.tec)
666 of_iounmap(all->par.tec, sizeof(struct cg6_tec)); 666 of_iounmap(&op->resource[0],
667 all->par.tec, sizeof(struct cg6_tec));
667 if (all->par.thc) 668 if (all->par.thc)
668 of_iounmap(all->par.thc, sizeof(struct cg6_thc)); 669 of_iounmap(&op->resource[0],
670 all->par.thc, sizeof(struct cg6_thc));
669 if (all->par.bt) 671 if (all->par.bt)
670 of_iounmap(all->par.bt, sizeof(struct bt_regs)); 672 of_iounmap(&op->resource[0],
673 all->par.bt, sizeof(struct bt_regs));
671 if (all->par.fhc) 674 if (all->par.fhc)
672 of_iounmap(all->par.fhc, sizeof(u32)); 675 of_iounmap(&op->resource[0],
676 all->par.fhc, sizeof(u32));
673 677
674 if (all->info.screen_base) 678 if (all->info.screen_base)
675 of_iounmap(all->info.screen_base, all->par.fbsize); 679 of_iounmap(&op->resource[0],
680 all->info.screen_base, all->par.fbsize);
676} 681}
677 682
678static int __devinit cg6_init_one(struct of_device *op) 683static int __devinit cg6_init_one(struct of_device *op)
@@ -720,7 +725,7 @@ static int __devinit cg6_init_one(struct of_device *op)
720 all->par.fbsize, "cgsix ram"); 725 all->par.fbsize, "cgsix ram");
721 if (!all->par.fbc || !all->par.tec || !all->par.thc || 726 if (!all->par.fbc || !all->par.tec || !all->par.thc ||
722 !all->par.bt || !all->par.fhc || !all->info.screen_base) { 727 !all->par.bt || !all->par.fhc || !all->info.screen_base) {
723 cg6_unmap_regs(all); 728 cg6_unmap_regs(op, all);
724 kfree(all); 729 kfree(all);
725 return -ENOMEM; 730 return -ENOMEM;
726 } 731 }
@@ -734,7 +739,7 @@ static int __devinit cg6_init_one(struct of_device *op)
734 cg6_blank(0, &all->info); 739 cg6_blank(0, &all->info);
735 740
736 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 741 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
737 cg6_unmap_regs(all); 742 cg6_unmap_regs(op, all);
738 kfree(all); 743 kfree(all);
739 return -ENOMEM; 744 return -ENOMEM;
740 } 745 }
@@ -744,7 +749,7 @@ static int __devinit cg6_init_one(struct of_device *op)
744 749
745 err = register_framebuffer(&all->info); 750 err = register_framebuffer(&all->info);
746 if (err < 0) { 751 if (err < 0) {
747 cg6_unmap_regs(all); 752 cg6_unmap_regs(op, all);
748 fb_dealloc_cmap(&all->info.cmap); 753 fb_dealloc_cmap(&all->info.cmap);
749 kfree(all); 754 kfree(all);
750 return err; 755 return err;
@@ -767,18 +772,18 @@ static int __devinit cg6_probe(struct of_device *dev, const struct of_device_id
767 return cg6_init_one(op); 772 return cg6_init_one(op);
768} 773}
769 774
770static int __devexit cg6_remove(struct of_device *dev) 775static int __devexit cg6_remove(struct of_device *op)
771{ 776{
772 struct all_info *all = dev_get_drvdata(&dev->dev); 777 struct all_info *all = dev_get_drvdata(&op->dev);
773 778
774 unregister_framebuffer(&all->info); 779 unregister_framebuffer(&all->info);
775 fb_dealloc_cmap(&all->info.cmap); 780 fb_dealloc_cmap(&all->info.cmap);
776 781
777 cg6_unmap_regs(all); 782 cg6_unmap_regs(op, all);
778 783
779 kfree(all); 784 kfree(all);
780 785
781 dev_set_drvdata(&dev->dev, NULL); 786 dev_set_drvdata(&op->dev, NULL);
782 787
783 return 0; 788 return 0;
784} 789}
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 949141bd44d4..15854aec3180 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -910,7 +910,8 @@ static int ffb_init_one(struct of_device *op)
910 all->par.dac = of_ioremap(&op->resource[1], 0, 910 all->par.dac = of_ioremap(&op->resource[1], 0,
911 sizeof(struct ffb_dac), "ffb dac"); 911 sizeof(struct ffb_dac), "ffb dac");
912 if (!all->par.dac) { 912 if (!all->par.dac) {
913 of_iounmap(all->par.fbc, sizeof(struct ffb_fbc)); 913 of_iounmap(&op->resource[2],
914 all->par.fbc, sizeof(struct ffb_fbc));
914 kfree(all); 915 kfree(all);
915 return -ENOMEM; 916 return -ENOMEM;
916 } 917 }
@@ -968,8 +969,10 @@ static int ffb_init_one(struct of_device *op)
968 969
969 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 970 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
970 printk(KERN_ERR "ffb: Could not allocate color map.\n"); 971 printk(KERN_ERR "ffb: Could not allocate color map.\n");
971 of_iounmap(all->par.fbc, sizeof(struct ffb_fbc)); 972 of_iounmap(&op->resource[2],
972 of_iounmap(all->par.dac, sizeof(struct ffb_dac)); 973 all->par.fbc, sizeof(struct ffb_fbc));
974 of_iounmap(&op->resource[1],
975 all->par.dac, sizeof(struct ffb_dac));
973 kfree(all); 976 kfree(all);
974 return -ENOMEM; 977 return -ENOMEM;
975 } 978 }
@@ -980,8 +983,10 @@ static int ffb_init_one(struct of_device *op)
980 if (err < 0) { 983 if (err < 0) {
981 printk(KERN_ERR "ffb: Could not register framebuffer.\n"); 984 printk(KERN_ERR "ffb: Could not register framebuffer.\n");
982 fb_dealloc_cmap(&all->info.cmap); 985 fb_dealloc_cmap(&all->info.cmap);
983 of_iounmap(all->par.fbc, sizeof(struct ffb_fbc)); 986 of_iounmap(&op->resource[2],
984 of_iounmap(all->par.dac, sizeof(struct ffb_dac)); 987 all->par.fbc, sizeof(struct ffb_fbc));
988 of_iounmap(&op->resource[1],
989 all->par.dac, sizeof(struct ffb_dac));
985 kfree(all); 990 kfree(all);
986 return err; 991 return err;
987 } 992 }
@@ -1003,19 +1008,19 @@ static int __devinit ffb_probe(struct of_device *dev, const struct of_device_id
1003 return ffb_init_one(op); 1008 return ffb_init_one(op);
1004} 1009}
1005 1010
1006static int __devexit ffb_remove(struct of_device *dev) 1011static int __devexit ffb_remove(struct of_device *op)
1007{ 1012{
1008 struct all_info *all = dev_get_drvdata(&dev->dev); 1013 struct all_info *all = dev_get_drvdata(&op->dev);
1009 1014
1010 unregister_framebuffer(&all->info); 1015 unregister_framebuffer(&all->info);
1011 fb_dealloc_cmap(&all->info.cmap); 1016 fb_dealloc_cmap(&all->info.cmap);
1012 1017
1013 of_iounmap(all->par.fbc, sizeof(struct ffb_fbc)); 1018 of_iounmap(&op->resource[2], all->par.fbc, sizeof(struct ffb_fbc));
1014 of_iounmap(all->par.dac, sizeof(struct ffb_dac)); 1019 of_iounmap(&op->resource[1], all->par.dac, sizeof(struct ffb_dac));
1015 1020
1016 kfree(all); 1021 kfree(all);
1017 1022
1018 dev_set_drvdata(&dev->dev, NULL); 1023 dev_set_drvdata(&op->dev, NULL);
1019 1024
1020 return 0; 1025 return 0;
1021} 1026}
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index f3a24338d9ac..a038aa5a9e1c 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -530,20 +530,21 @@ struct all_info {
530 struct leo_par par; 530 struct leo_par par;
531}; 531};
532 532
533static void leo_unmap_regs(struct all_info *all) 533static void leo_unmap_regs(struct of_device *op, struct all_info *all)
534{ 534{
535 if (all->par.lc_ss0_usr) 535 if (all->par.lc_ss0_usr)
536 of_iounmap(all->par.lc_ss0_usr, 0x1000); 536 of_iounmap(&op->resource[0], all->par.lc_ss0_usr, 0x1000);
537 if (all->par.ld_ss0) 537 if (all->par.ld_ss0)
538 of_iounmap(all->par.ld_ss0, 0x1000); 538 of_iounmap(&op->resource[0], all->par.ld_ss0, 0x1000);
539 if (all->par.ld_ss1) 539 if (all->par.ld_ss1)
540 of_iounmap(all->par.ld_ss1, 0x1000); 540 of_iounmap(&op->resource[0], all->par.ld_ss1, 0x1000);
541 if (all->par.lx_krn) 541 if (all->par.lx_krn)
542 of_iounmap(all->par.lx_krn, 0x1000); 542 of_iounmap(&op->resource[0], all->par.lx_krn, 0x1000);
543 if (all->par.cursor) 543 if (all->par.cursor)
544 of_iounmap(all->par.cursor, sizeof(struct leo_cursor)); 544 of_iounmap(&op->resource[0],
545 all->par.cursor, sizeof(struct leo_cursor));
545 if (all->info.screen_base) 546 if (all->info.screen_base)
546 of_iounmap(all->info.screen_base, 0x800000); 547 of_iounmap(&op->resource[0], all->info.screen_base, 0x800000);
547} 548}
548 549
549static int __devinit leo_init_one(struct of_device *op) 550static int __devinit leo_init_one(struct of_device *op)
@@ -592,7 +593,7 @@ static int __devinit leo_init_one(struct of_device *op)
592 !all->par.lx_krn || 593 !all->par.lx_krn ||
593 !all->par.cursor || 594 !all->par.cursor ||
594 !all->info.screen_base) { 595 !all->info.screen_base) {
595 leo_unmap_regs(all); 596 leo_unmap_regs(op, all);
596 kfree(all); 597 kfree(all);
597 return -ENOMEM; 598 return -ENOMEM;
598 } 599 }
@@ -607,7 +608,7 @@ static int __devinit leo_init_one(struct of_device *op)
607 leo_blank(0, &all->info); 608 leo_blank(0, &all->info);
608 609
609 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 610 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
610 leo_unmap_regs(all); 611 leo_unmap_regs(op, all);
611 kfree(all); 612 kfree(all);
612 return -ENOMEM;; 613 return -ENOMEM;;
613 } 614 }
@@ -617,7 +618,7 @@ static int __devinit leo_init_one(struct of_device *op)
617 err = register_framebuffer(&all->info); 618 err = register_framebuffer(&all->info);
618 if (err < 0) { 619 if (err < 0) {
619 fb_dealloc_cmap(&all->info.cmap); 620 fb_dealloc_cmap(&all->info.cmap);
620 leo_unmap_regs(all); 621 leo_unmap_regs(op, all);
621 kfree(all); 622 kfree(all);
622 return err; 623 return err;
623 } 624 }
@@ -638,18 +639,18 @@ static int __devinit leo_probe(struct of_device *dev, const struct of_device_id
638 return leo_init_one(op); 639 return leo_init_one(op);
639} 640}
640 641
641static int __devexit leo_remove(struct of_device *dev) 642static int __devexit leo_remove(struct of_device *op)
642{ 643{
643 struct all_info *all = dev_get_drvdata(&dev->dev); 644 struct all_info *all = dev_get_drvdata(&op->dev);
644 645
645 unregister_framebuffer(&all->info); 646 unregister_framebuffer(&all->info);
646 fb_dealloc_cmap(&all->info.cmap); 647 fb_dealloc_cmap(&all->info.cmap);
647 648
648 leo_unmap_regs(all); 649 leo_unmap_regs(op, all);
649 650
650 kfree(all); 651 kfree(all);
651 652
652 dev_set_drvdata(&dev->dev, NULL); 653 dev_set_drvdata(&op->dev, NULL);
653 654
654 return 0; 655 return 0;
655} 656}
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index 56ac51d6a7f3..637b78bb4bf7 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -297,7 +297,8 @@ static int __devinit p9100_init_one(struct of_device *op)
297 all->info.screen_base = of_ioremap(&op->resource[2], 0, 297 all->info.screen_base = of_ioremap(&op->resource[2], 0,
298 all->par.fbsize, "p9100 ram"); 298 all->par.fbsize, "p9100 ram");
299 if (!all->info.screen_base) { 299 if (!all->info.screen_base) {
300 of_iounmap(all->par.regs, sizeof(struct p9100_regs)); 300 of_iounmap(&op->resource[0],
301 all->par.regs, sizeof(struct p9100_regs));
301 kfree(all); 302 kfree(all);
302 return -ENOMEM; 303 return -ENOMEM;
303 } 304 }
@@ -306,8 +307,10 @@ static int __devinit p9100_init_one(struct of_device *op)
306 p9100_blank(0, &all->info); 307 p9100_blank(0, &all->info);
307 308
308 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 309 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
309 of_iounmap(all->par.regs, sizeof(struct p9100_regs)); 310 of_iounmap(&op->resource[0],
310 of_iounmap(all->info.screen_base, all->par.fbsize); 311 all->par.regs, sizeof(struct p9100_regs));
312 of_iounmap(&op->resource[2],
313 all->info.screen_base, all->par.fbsize);
311 kfree(all); 314 kfree(all);
312 return -ENOMEM; 315 return -ENOMEM;
313 } 316 }
@@ -317,8 +320,10 @@ static int __devinit p9100_init_one(struct of_device *op)
317 err = register_framebuffer(&all->info); 320 err = register_framebuffer(&all->info);
318 if (err < 0) { 321 if (err < 0) {
319 fb_dealloc_cmap(&all->info.cmap); 322 fb_dealloc_cmap(&all->info.cmap);
320 of_iounmap(all->par.regs, sizeof(struct p9100_regs)); 323 of_iounmap(&op->resource[0],
321 of_iounmap(all->info.screen_base, all->par.fbsize); 324 all->par.regs, sizeof(struct p9100_regs));
325 of_iounmap(&op->resource[2],
326 all->info.screen_base, all->par.fbsize);
322 kfree(all); 327 kfree(all);
323 return err; 328 return err;
324 } 329 }
@@ -340,19 +345,19 @@ static int __devinit p9100_probe(struct of_device *dev, const struct of_device_i
340 return p9100_init_one(op); 345 return p9100_init_one(op);
341} 346}
342 347
343static int __devexit p9100_remove(struct of_device *dev) 348static int __devexit p9100_remove(struct of_device *op)
344{ 349{
345 struct all_info *all = dev_get_drvdata(&dev->dev); 350 struct all_info *all = dev_get_drvdata(&op->dev);
346 351
347 unregister_framebuffer(&all->info); 352 unregister_framebuffer(&all->info);
348 fb_dealloc_cmap(&all->info.cmap); 353 fb_dealloc_cmap(&all->info.cmap);
349 354
350 of_iounmap(all->par.regs, sizeof(struct p9100_regs)); 355 of_iounmap(&op->resource[0], all->par.regs, sizeof(struct p9100_regs));
351 of_iounmap(all->info.screen_base, all->par.fbsize); 356 of_iounmap(&op->resource[2], all->info.screen_base, all->par.fbsize);
352 357
353 kfree(all); 358 kfree(all);
354 359
355 dev_set_drvdata(&dev->dev, NULL); 360 dev_set_drvdata(&op->dev, NULL);
356 361
357 return 0; 362 return 0;
358} 363}
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 6990ab11cd06..5a99669232ce 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -350,18 +350,23 @@ struct all_info {
350 struct tcx_par par; 350 struct tcx_par par;
351}; 351};
352 352
353static void tcx_unmap_regs(struct all_info *all) 353static void tcx_unmap_regs(struct of_device *op, struct all_info *all)
354{ 354{
355 if (all->par.tec) 355 if (all->par.tec)
356 of_iounmap(all->par.tec, sizeof(struct tcx_tec)); 356 of_iounmap(&op->resource[7],
357 all->par.tec, sizeof(struct tcx_tec));
357 if (all->par.thc) 358 if (all->par.thc)
358 of_iounmap(all->par.thc, sizeof(struct tcx_thc)); 359 of_iounmap(&op->resource[9],
360 all->par.thc, sizeof(struct tcx_thc));
359 if (all->par.bt) 361 if (all->par.bt)
360 of_iounmap(all->par.bt, sizeof(struct bt_regs)); 362 of_iounmap(&op->resource[8],
363 all->par.bt, sizeof(struct bt_regs));
361 if (all->par.cplane) 364 if (all->par.cplane)
362 of_iounmap(all->par.cplane, all->par.fbsize * sizeof(u32)); 365 of_iounmap(&op->resource[4],
366 all->par.cplane, all->par.fbsize * sizeof(u32));
363 if (all->info.screen_base) 367 if (all->info.screen_base)
364 of_iounmap(all->info.screen_base, all->par.fbsize); 368 of_iounmap(&op->resource[0],
369 all->info.screen_base, all->par.fbsize);
365} 370}
366 371
367static int __devinit tcx_init_one(struct of_device *op) 372static int __devinit tcx_init_one(struct of_device *op)
@@ -398,7 +403,7 @@ static int __devinit tcx_init_one(struct of_device *op)
398 all->par.fbsize, "tcx ram"); 403 all->par.fbsize, "tcx ram");
399 if (!all->par.tec || !all->par.thc || 404 if (!all->par.tec || !all->par.thc ||
400 !all->par.bt || !all->info.screen_base) { 405 !all->par.bt || !all->info.screen_base) {
401 tcx_unmap_regs(all); 406 tcx_unmap_regs(op, all);
402 kfree(all); 407 kfree(all);
403 return -ENOMEM; 408 return -ENOMEM;
404 } 409 }
@@ -409,7 +414,7 @@ static int __devinit tcx_init_one(struct of_device *op)
409 all->par.fbsize * sizeof(u32), 414 all->par.fbsize * sizeof(u32),
410 "tcx cplane"); 415 "tcx cplane");
411 if (!all->par.cplane) { 416 if (!all->par.cplane) {
412 tcx_unmap_regs(all); 417 tcx_unmap_regs(op, all);
413 kfree(all); 418 kfree(all);
414 return -ENOMEM; 419 return -ENOMEM;
415 } 420 }
@@ -461,7 +466,7 @@ static int __devinit tcx_init_one(struct of_device *op)
461 tcx_blank(FB_BLANK_UNBLANK, &all->info); 466 tcx_blank(FB_BLANK_UNBLANK, &all->info);
462 467
463 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 468 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
464 tcx_unmap_regs(all); 469 tcx_unmap_regs(op, all);
465 kfree(all); 470 kfree(all);
466 return -ENOMEM; 471 return -ENOMEM;
467 } 472 }
@@ -472,7 +477,7 @@ static int __devinit tcx_init_one(struct of_device *op)
472 err = register_framebuffer(&all->info); 477 err = register_framebuffer(&all->info);
473 if (err < 0) { 478 if (err < 0) {
474 fb_dealloc_cmap(&all->info.cmap); 479 fb_dealloc_cmap(&all->info.cmap);
475 tcx_unmap_regs(all); 480 tcx_unmap_regs(op, all);
476 kfree(all); 481 kfree(all);
477 return err; 482 return err;
478 } 483 }
@@ -495,18 +500,18 @@ static int __devinit tcx_probe(struct of_device *dev, const struct of_device_id
495 return tcx_init_one(op); 500 return tcx_init_one(op);
496} 501}
497 502
498static int __devexit tcx_remove(struct of_device *dev) 503static int __devexit tcx_remove(struct of_device *op)
499{ 504{
500 struct all_info *all = dev_get_drvdata(&dev->dev); 505 struct all_info *all = dev_get_drvdata(&op->dev);
501 506
502 unregister_framebuffer(&all->info); 507 unregister_framebuffer(&all->info);
503 fb_dealloc_cmap(&all->info.cmap); 508 fb_dealloc_cmap(&all->info.cmap);
504 509
505 tcx_unmap_regs(all); 510 tcx_unmap_regs(op, all);
506 511
507 kfree(all); 512 kfree(all);
508 513
509 dev_set_drvdata(&dev->dev, NULL); 514 dev_set_drvdata(&op->dev, NULL);
510 515
511 return 0; 516 return 0;
512} 517}
diff --git a/include/asm-sparc/of_device.h b/include/asm-sparc/of_device.h
index 80ea31f6e17f..7cb00c1b09c6 100644
--- a/include/asm-sparc/of_device.h
+++ b/include/asm-sparc/of_device.h
@@ -33,7 +33,7 @@ struct of_device
33#define to_of_device(d) container_of(d, struct of_device, dev) 33#define to_of_device(d) container_of(d, struct of_device, dev)
34 34
35extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); 35extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
36extern void of_iounmap(void __iomem *base, unsigned long size); 36extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
37 37
38extern struct of_device *of_find_device_by_node(struct device_node *); 38extern struct of_device *of_find_device_by_node(struct device_node *);
39 39
diff --git a/include/asm-sparc64/of_device.h b/include/asm-sparc64/of_device.h
index a62c7b997d66..60e9173c9acb 100644
--- a/include/asm-sparc64/of_device.h
+++ b/include/asm-sparc64/of_device.h
@@ -34,7 +34,7 @@ struct of_device
34#define to_of_device(d) container_of(d, struct of_device, dev) 34#define to_of_device(d) container_of(d, struct of_device, dev)
35 35
36extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); 36extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
37extern void of_iounmap(void __iomem *base, unsigned long size); 37extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
38 38
39extern struct of_device *of_find_device_by_node(struct device_node *); 39extern struct of_device *of_find_device_by_node(struct device_node *);
40 40