diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-12-29 00:01:32 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-31 17:06:05 -0500 |
commit | e3a411a3dfc1d633504aa63efab32b7e00318454 (patch) | |
tree | 2ba6117448edd7056c8fa48cc6a696ae73a6c21a /drivers/video/tcx.c | |
parent | 6fc5bae797a6632bbccdd49a1b6a96121368a4b9 (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>
Diffstat (limited to 'drivers/video/tcx.c')
-rw-r--r-- | drivers/video/tcx.c | 33 |
1 files changed, 19 insertions, 14 deletions
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 | ||
353 | static void tcx_unmap_regs(struct all_info *all) | 353 | static 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 | ||
367 | static int __devinit tcx_init_one(struct of_device *op) | 372 | static 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 | ||
498 | static int __devexit tcx_remove(struct of_device *dev) | 503 | static 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 | } |