diff options
author | Shawn Guo <shawn.guo@linaro.org> | 2012-06-25 07:54:35 -0400 |
---|---|---|
committer | Shawn Guo <shawn.guo@linaro.org> | 2012-07-03 01:22:37 -0400 |
commit | 73fc610f9a891fd777040bbb1854ae0b58edee9c (patch) | |
tree | 881ac7ce1909aa23d73d00c4060351c00f512cd9 /drivers/video/mxsfb.c | |
parent | ce4409b5821f170c018b94bacb36df1ffadb751f (diff) |
video: mxsfb: add simple device tree probe
Add a simple device tree probe support for mxsfb driver. Before
a common binding for struct fb_videomode is available, the driver will
keep using struct mxsfb_platform_data. That said, platform code will
use auxdata to attach mxsfb_platform_data for device tree boot.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Diffstat (limited to 'drivers/video/mxsfb.c')
-rw-r--r-- | drivers/video/mxsfb.c | 60 |
1 files changed, 47 insertions, 13 deletions
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index 08dad8d8abba..49619b441500 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c | |||
@@ -41,6 +41,8 @@ | |||
41 | 41 | ||
42 | #include <linux/module.h> | 42 | #include <linux/module.h> |
43 | #include <linux/kernel.h> | 43 | #include <linux/kernel.h> |
44 | #include <linux/of_device.h> | ||
45 | #include <linux/of_gpio.h> | ||
44 | #include <linux/platform_device.h> | 46 | #include <linux/platform_device.h> |
45 | #include <linux/clk.h> | 47 | #include <linux/clk.h> |
46 | #include <linux/dma-mapping.h> | 48 | #include <linux/dma-mapping.h> |
@@ -750,16 +752,43 @@ static void __devexit mxsfb_free_videomem(struct mxsfb_info *host) | |||
750 | } | 752 | } |
751 | } | 753 | } |
752 | 754 | ||
755 | static struct platform_device_id mxsfb_devtype[] = { | ||
756 | { | ||
757 | .name = "imx23-fb", | ||
758 | .driver_data = MXSFB_V3, | ||
759 | }, { | ||
760 | .name = "imx28-fb", | ||
761 | .driver_data = MXSFB_V4, | ||
762 | }, { | ||
763 | /* sentinel */ | ||
764 | } | ||
765 | }; | ||
766 | MODULE_DEVICE_TABLE(platform, mxsfb_devtype); | ||
767 | |||
768 | static const struct of_device_id mxsfb_dt_ids[] = { | ||
769 | { .compatible = "fsl,imx23-lcdif", .data = &mxsfb_devtype[0], }, | ||
770 | { .compatible = "fsl,imx28-lcdif", .data = &mxsfb_devtype[1], }, | ||
771 | { /* sentinel */ } | ||
772 | }; | ||
773 | MODULE_DEVICE_TABLE(of, mxsfb_dt_ids); | ||
774 | |||
753 | static int __devinit mxsfb_probe(struct platform_device *pdev) | 775 | static int __devinit mxsfb_probe(struct platform_device *pdev) |
754 | { | 776 | { |
777 | const struct of_device_id *of_id = | ||
778 | of_match_device(mxsfb_dt_ids, &pdev->dev); | ||
755 | struct mxsfb_platform_data *pdata = pdev->dev.platform_data; | 779 | struct mxsfb_platform_data *pdata = pdev->dev.platform_data; |
756 | struct resource *res; | 780 | struct resource *res; |
757 | struct mxsfb_info *host; | 781 | struct mxsfb_info *host; |
758 | struct fb_info *fb_info; | 782 | struct fb_info *fb_info; |
759 | struct fb_modelist *modelist; | 783 | struct fb_modelist *modelist; |
760 | struct pinctrl *pinctrl; | 784 | struct pinctrl *pinctrl; |
785 | int panel_enable; | ||
786 | enum of_gpio_flags flags; | ||
761 | int i, ret; | 787 | int i, ret; |
762 | 788 | ||
789 | if (of_id) | ||
790 | pdev->id_entry = of_id->data; | ||
791 | |||
763 | if (!pdata) { | 792 | if (!pdata) { |
764 | dev_err(&pdev->dev, "No platformdata. Giving up\n"); | 793 | dev_err(&pdev->dev, "No platformdata. Giving up\n"); |
765 | return -ENODEV; | 794 | return -ENODEV; |
@@ -807,6 +836,22 @@ static int __devinit mxsfb_probe(struct platform_device *pdev) | |||
807 | goto error_getclock; | 836 | goto error_getclock; |
808 | } | 837 | } |
809 | 838 | ||
839 | panel_enable = of_get_named_gpio_flags(pdev->dev.of_node, | ||
840 | "panel-enable-gpios", 0, &flags); | ||
841 | if (gpio_is_valid(panel_enable)) { | ||
842 | unsigned long f = GPIOF_OUT_INIT_HIGH; | ||
843 | if (flags == OF_GPIO_ACTIVE_LOW) | ||
844 | f = GPIOF_OUT_INIT_LOW; | ||
845 | ret = devm_gpio_request_one(&pdev->dev, panel_enable, | ||
846 | f, "panel-enable"); | ||
847 | if (ret) { | ||
848 | dev_err(&pdev->dev, | ||
849 | "failed to request gpio %d: %d\n", | ||
850 | panel_enable, ret); | ||
851 | goto error_panel_enable; | ||
852 | } | ||
853 | } | ||
854 | |||
810 | fb_info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); | 855 | fb_info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); |
811 | if (!fb_info->pseudo_palette) { | 856 | if (!fb_info->pseudo_palette) { |
812 | ret = -ENOMEM; | 857 | ret = -ENOMEM; |
@@ -854,6 +899,7 @@ error_register: | |||
854 | error_init_fb: | 899 | error_init_fb: |
855 | kfree(fb_info->pseudo_palette); | 900 | kfree(fb_info->pseudo_palette); |
856 | error_pseudo_pallette: | 901 | error_pseudo_pallette: |
902 | error_panel_enable: | ||
857 | clk_put(host->clk); | 903 | clk_put(host->clk); |
858 | error_getclock: | 904 | error_getclock: |
859 | error_getpin: | 905 | error_getpin: |
@@ -901,19 +947,6 @@ static void mxsfb_shutdown(struct platform_device *pdev) | |||
901 | writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR); | 947 | writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR); |
902 | } | 948 | } |
903 | 949 | ||
904 | static struct platform_device_id mxsfb_devtype[] = { | ||
905 | { | ||
906 | .name = "imx23-fb", | ||
907 | .driver_data = MXSFB_V3, | ||
908 | }, { | ||
909 | .name = "imx28-fb", | ||
910 | .driver_data = MXSFB_V4, | ||
911 | }, { | ||
912 | /* sentinel */ | ||
913 | } | ||
914 | }; | ||
915 | MODULE_DEVICE_TABLE(platform, mxsfb_devtype); | ||
916 | |||
917 | static struct platform_driver mxsfb_driver = { | 950 | static struct platform_driver mxsfb_driver = { |
918 | .probe = mxsfb_probe, | 951 | .probe = mxsfb_probe, |
919 | .remove = __devexit_p(mxsfb_remove), | 952 | .remove = __devexit_p(mxsfb_remove), |
@@ -921,6 +954,7 @@ static struct platform_driver mxsfb_driver = { | |||
921 | .id_table = mxsfb_devtype, | 954 | .id_table = mxsfb_devtype, |
922 | .driver = { | 955 | .driver = { |
923 | .name = DRIVER_NAME, | 956 | .name = DRIVER_NAME, |
957 | .of_match_table = mxsfb_dt_ids, | ||
924 | }, | 958 | }, |
925 | }; | 959 | }; |
926 | 960 | ||