diff options
-rw-r--r-- | drivers/video/xilinxfb.c | 107 |
1 files changed, 98 insertions, 9 deletions
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index e482bb519635..dbb23a9fef7b 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c | |||
@@ -6,9 +6,12 @@ | |||
6 | * Author: MontaVista Software, Inc. | 6 | * Author: MontaVista Software, Inc. |
7 | * source@mvista.com | 7 | * source@mvista.com |
8 | * | 8 | * |
9 | * 2002-2007 (c) MontaVista Software, Inc. This file is licensed under the | 9 | * 2002-2007 (c) MontaVista Software, Inc. |
10 | * terms of the GNU General Public License version 2. This program is licensed | 10 | * 2007 (c) Secret Lab Technologies, Ltd. |
11 | * "as is" without any warranty of any kind, whether express or implied. | 11 | * |
12 | * This file is licensed under the terms of the GNU General Public License | ||
13 | * version 2. This program is licensed "as is" without any warranty of any | ||
14 | * kind, whether express or implied. | ||
12 | */ | 15 | */ |
13 | 16 | ||
14 | /* | 17 | /* |
@@ -29,7 +32,10 @@ | |||
29 | #include <linux/init.h> | 32 | #include <linux/init.h> |
30 | #include <linux/dma-mapping.h> | 33 | #include <linux/dma-mapping.h> |
31 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
32 | 35 | #if defined(CONFIG_OF) | |
36 | #include <linux/of_device.h> | ||
37 | #include <linux/of_platform.h> | ||
38 | #endif | ||
33 | #include <asm/io.h> | 39 | #include <asm/io.h> |
34 | #include <linux/xilinxfb.h> | 40 | #include <linux/xilinxfb.h> |
35 | 41 | ||
@@ -384,20 +390,103 @@ static struct platform_driver xilinxfb_platform_driver = { | |||
384 | }, | 390 | }, |
385 | }; | 391 | }; |
386 | 392 | ||
393 | /* --------------------------------------------------------------------- | ||
394 | * OF bus binding | ||
395 | */ | ||
396 | |||
397 | #if defined(CONFIG_OF) | ||
398 | static int __devinit | ||
399 | xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) | ||
400 | { | ||
401 | struct resource res; | ||
402 | const u32 *prop; | ||
403 | int width = 0, height = 0, rotate = 0; | ||
404 | int size, rc; | ||
405 | |||
406 | dev_dbg(&op->dev, "xilinxfb_of_probe(%p, %p)\n", op, match); | ||
407 | |||
408 | rc = of_address_to_resource(op->node, 0, &res); | ||
409 | if (rc) { | ||
410 | dev_err(&op->dev, "invalid address\n"); | ||
411 | return rc; | ||
412 | } | ||
413 | |||
414 | prop = of_get_property(op->node, "display-number", &size); | ||
415 | if ((prop) && (size >= sizeof(u32)*2)) { | ||
416 | width = prop[0]; | ||
417 | height = prop[1]; | ||
418 | } | ||
419 | |||
420 | if (of_find_property(op->node, "rotate-display", NULL)) | ||
421 | rotate = 1; | ||
422 | |||
423 | return xilinxfb_assign(&op->dev, res.start, width, height, rotate); | ||
424 | } | ||
425 | |||
426 | static int __devexit xilinxfb_of_remove(struct of_device *op) | ||
427 | { | ||
428 | return xilinxfb_release(&op->dev); | ||
429 | } | ||
430 | |||
431 | /* Match table for of_platform binding */ | ||
432 | static struct of_device_id __devinit xilinxfb_of_match[] = { | ||
433 | { .compatible = "xilinx,ml300-fb", }, | ||
434 | {}, | ||
435 | }; | ||
436 | MODULE_DEVICE_TABLE(of, xilinxfb_of_match); | ||
437 | |||
438 | static struct of_platform_driver xilinxfb_of_driver = { | ||
439 | .owner = THIS_MODULE, | ||
440 | .name = DRIVER_NAME, | ||
441 | .match_table = xilinxfb_of_match, | ||
442 | .probe = xilinxfb_of_probe, | ||
443 | .remove = __devexit_p(xilinxfb_of_remove), | ||
444 | .driver = { | ||
445 | .name = DRIVER_NAME, | ||
446 | }, | ||
447 | }; | ||
448 | |||
449 | /* Registration helpers to keep the number of #ifdefs to a minimum */ | ||
450 | static inline int __init xilinxfb_of_register(void) | ||
451 | { | ||
452 | pr_debug("xilinxfb: calling of_register_platform_driver()\n"); | ||
453 | return of_register_platform_driver(&xilinxfb_of_driver); | ||
454 | } | ||
455 | |||
456 | static inline void __exit xilinxfb_of_unregister(void) | ||
457 | { | ||
458 | of_unregister_platform_driver(&xilinxfb_of_driver); | ||
459 | } | ||
460 | #else /* CONFIG_OF */ | ||
461 | /* CONFIG_OF not enabled; do nothing helpers */ | ||
462 | static inline int __init xilinxfb_of_register(void) { return 0; } | ||
463 | static inline void __exit xilinxfb_of_unregister(void) { } | ||
464 | #endif /* CONFIG_OF */ | ||
465 | |||
466 | /* --------------------------------------------------------------------- | ||
467 | * Module setup and teardown | ||
468 | */ | ||
469 | |||
387 | static int __init | 470 | static int __init |
388 | xilinxfb_init(void) | 471 | xilinxfb_init(void) |
389 | { | 472 | { |
390 | /* | 473 | int rc; |
391 | * No kernel boot options used, | 474 | rc = xilinxfb_of_register(); |
392 | * so we just need to register the driver | 475 | if (rc) |
393 | */ | 476 | return rc; |
394 | return platform_driver_register(&xilinxfb_platform_driver); | 477 | |
478 | rc = platform_driver_register(&xilinxfb_platform_driver); | ||
479 | if (rc) | ||
480 | xilinxfb_of_unregister(); | ||
481 | |||
482 | return rc; | ||
395 | } | 483 | } |
396 | 484 | ||
397 | static void __exit | 485 | static void __exit |
398 | xilinxfb_cleanup(void) | 486 | xilinxfb_cleanup(void) |
399 | { | 487 | { |
400 | platform_driver_unregister(&xilinxfb_platform_driver); | 488 | platform_driver_unregister(&xilinxfb_platform_driver); |
489 | xilinxfb_of_unregister(); | ||
401 | } | 490 | } |
402 | 491 | ||
403 | module_init(xilinxfb_init); | 492 | module_init(xilinxfb_init); |