aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/video/simple-framebuffer-sunxi.txt33
-rw-r--r--Documentation/devicetree/bindings/video/simple-framebuffer.txt68
-rw-r--r--MAINTAINERS8
-rw-r--r--drivers/video/console/fbcon.c2
-rw-r--r--drivers/video/fbdev/Kconfig2
-rw-r--r--drivers/video/fbdev/amba-clcd.c1
-rw-r--r--drivers/video/fbdev/arkfb.c2
-rw-r--r--drivers/video/fbdev/mmp/core.c6
-rw-r--r--drivers/video/fbdev/mmp/hw/mmp_ctrl.c3
-rw-r--r--drivers/video/fbdev/mx3fb.c3
-rw-r--r--drivers/video/fbdev/mxsfb.c19
-rw-r--r--drivers/video/fbdev/omap2/displays-new/connector-dvi.c9
-rw-r--r--drivers/video/fbdev/s3fb.c2
-rw-r--r--drivers/video/fbdev/sh_mobile_lcdcfb.c3
-rw-r--r--drivers/video/fbdev/simplefb.c162
-rw-r--r--drivers/video/fbdev/sis/sis_main.c14
-rw-r--r--drivers/video/fbdev/sm501fb.c1
-rw-r--r--drivers/video/fbdev/smscufx.c6
-rw-r--r--drivers/video/fbdev/udlfb.c9
-rw-r--r--drivers/video/fbdev/uvesafb.c6
-rw-r--r--drivers/video/fbdev/via/viafbdev.c3
-rw-r--r--drivers/video/fbdev/vt8623fb.c2
-rw-r--r--include/linux/of.h3
23 files changed, 304 insertions, 63 deletions
diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer-sunxi.txt b/Documentation/devicetree/bindings/video/simple-framebuffer-sunxi.txt
new file mode 100644
index 000000000000..c46ba641a1df
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/simple-framebuffer-sunxi.txt
@@ -0,0 +1,33 @@
1Sunxi specific Simple Framebuffer bindings
2
3This binding documents sunxi specific extensions to the simple-framebuffer
4bindings. The sunxi simplefb u-boot code relies on the devicetree containing
5pre-populated simplefb nodes.
6
7These extensions are intended so that u-boot can select the right node based
8on which pipeline is being used. As such they are solely intended for
9firmware / bootloader use, and the OS should ignore them.
10
11Required properties:
12- compatible: "allwinner,simple-framebuffer"
13- allwinner,pipeline, one of:
14 "de_be0-lcd0"
15 "de_be1-lcd1"
16 "de_be0-lcd0-hdmi"
17 "de_be1-lcd1-hdmi"
18
19Example:
20
21chosen {
22 #address-cells = <1>;
23 #size-cells = <1>;
24 ranges;
25
26 framebuffer@0 {
27 compatible = "allwinner,simple-framebuffer", "simple-framebuffer";
28 allwinner,pipeline = "de_be0-lcd0-hdmi";
29 clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>,
30 <&ahb_gates 44>;
31 status = "disabled";
32 };
33};
diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer.txt b/Documentation/devicetree/bindings/video/simple-framebuffer.txt
index 70c26f3a5b9a..4474ef6e0b95 100644
--- a/Documentation/devicetree/bindings/video/simple-framebuffer.txt
+++ b/Documentation/devicetree/bindings/video/simple-framebuffer.txt
@@ -1,8 +1,40 @@
1Simple Framebuffer 1Simple Framebuffer
2 2
3A simple frame-buffer describes a raw memory region that may be rendered to, 3A simple frame-buffer describes a frame-buffer setup by firmware or
4with the assumption that the display hardware has already been set up to scan 4the bootloader, with the assumption that the display hardware has already
5out from that buffer. 5been set up to scan out from the memory pointed to by the reg property.
6
7Since simplefb nodes represent runtime information they must be sub-nodes of
8the chosen node (*). Simplefb nodes must be named "framebuffer@<address>".
9
10If the devicetree contains nodes for the display hardware used by a simplefb,
11then the simplefb node must contain a property called "display", which
12contains a phandle pointing to the primary display hw node, so that the OS
13knows which simplefb to disable when handing over control to a driver for the
14real hardware. The bindings for the hw nodes must specify which node is
15considered the primary node.
16
17It is advised to add display# aliases to help the OS determine how to number
18things. If display# aliases are used, then if the simplefb node contains a
19"display" property then the /aliases/display# path must point to the display
20hw node the "display" property points to, otherwise it must point directly
21to the simplefb node.
22
23If a simplefb node represents the preferred console for user interaction,
24then the chosen node's stdout-path property should point to it, or to the
25primary display hw node, as with display# aliases. If display aliases are
26used then it should be set to the alias instead.
27
28It is advised that devicetree files contain pre-filled, disabled framebuffer
29nodes, so that the firmware only needs to update the mode information and
30enable them. This way if e.g. later on support for more display clocks get
31added, the simplefb nodes will already contain this info and the firmware
32does not need to be updated.
33
34If pre-filled framebuffer nodes are used, the firmware may need extra
35information to find the right node. In that case an extra platform specific
36compatible and platform specific properties should be used and documented,
37see e.g. simple-framebuffer-sunxi.txt .
6 38
7Required properties: 39Required properties:
8- compatible: "simple-framebuffer" 40- compatible: "simple-framebuffer"
@@ -14,13 +46,41 @@ Required properties:
14 - r5g6b5 (16-bit pixels, d[15:11]=r, d[10:5]=g, d[4:0]=b). 46 - r5g6b5 (16-bit pixels, d[15:11]=r, d[10:5]=g, d[4:0]=b).
15 - a8b8g8r8 (32-bit pixels, d[31:24]=a, d[23:16]=b, d[15:8]=g, d[7:0]=r). 47 - a8b8g8r8 (32-bit pixels, d[31:24]=a, d[23:16]=b, d[15:8]=g, d[7:0]=r).
16 48
49Optional properties:
50- clocks : List of clocks used by the framebuffer. Clocks listed here
51 are expected to already be configured correctly. The OS must
52 ensure these clocks are not modified or disabled while the
53 simple framebuffer remains active.
54- display : phandle pointing to the primary display hardware node
55
17Example: 56Example:
18 57
19 framebuffer { 58aliases {
59 display0 = &lcdc0;
60}
61
62chosen {
63 framebuffer0: framebuffer@1d385000 {
20 compatible = "simple-framebuffer"; 64 compatible = "simple-framebuffer";
21 reg = <0x1d385000 (1600 * 1200 * 2)>; 65 reg = <0x1d385000 (1600 * 1200 * 2)>;
22 width = <1600>; 66 width = <1600>;
23 height = <1200>; 67 height = <1200>;
24 stride = <(1600 * 2)>; 68 stride = <(1600 * 2)>;
25 format = "r5g6b5"; 69 format = "r5g6b5";
70 clocks = <&ahb_gates 36>, <&ahb_gates 43>, <&ahb_gates 44>;
71 display = <&lcdc0>;
72 };
73 stdout-path = "display0";
74};
75
76soc@01c00000 {
77 lcdc0: lcdc@1c0c000 {
78 compatible = "allwinner,sun4i-a10-lcdc";
79 ...
26 }; 80 };
81};
82
83
84*) Older devicetree files may have a compatible = "simple-framebuffer" node
85in a different place, operating systems must first enumerate any compatible
86nodes found under chosen and then check for other compatible nodes.
diff --git a/MAINTAINERS b/MAINTAINERS
index 3c6427190be2..d348ccc162fb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8442,6 +8442,14 @@ F: drivers/media/usb/siano/
8442F: drivers/media/usb/siano/ 8442F: drivers/media/usb/siano/
8443F: drivers/media/mmc/siano/ 8443F: drivers/media/mmc/siano/
8444 8444
8445SIMPLEFB FB DRIVER
8446M: Hans de Goede <hdegoede@redhat.com>
8447L: linux-fbdev@vger.kernel.org
8448S: Maintained
8449F: Documentation/devicetree/bindings/video/simple-framebuffer.txt
8450F: drivers/video/fbdev/simplefb.c
8451F: include/linux/platform_data/simplefb.h
8452
8445SH_VEU V4L2 MEM2MEM DRIVER 8453SH_VEU V4L2 MEM2MEM DRIVER
8446L: linux-media@vger.kernel.org 8454L: linux-media@vger.kernel.org
8447S: Orphan 8455S: Orphan
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index eb976ee3a02f..ea437245562e 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -3624,7 +3624,7 @@ static int __init fb_console_init(void)
3624 return 0; 3624 return 0;
3625} 3625}
3626 3626
3627module_init(fb_console_init); 3627fs_initcall(fb_console_init);
3628 3628
3629#ifdef MODULE 3629#ifdef MODULE
3630 3630
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index c7bf606a8706..025b439d4fe1 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -2425,7 +2425,7 @@ config FB_JZ4740
2425 2425
2426config FB_MXS 2426config FB_MXS
2427 tristate "MXS LCD framebuffer support" 2427 tristate "MXS LCD framebuffer support"
2428 depends on FB && ARCH_MXS 2428 depends on FB && (ARCH_MXS || ARCH_MXC)
2429 select FB_CFB_FILLRECT 2429 select FB_CFB_FILLRECT
2430 select FB_CFB_COPYAREA 2430 select FB_CFB_COPYAREA
2431 select FB_CFB_IMAGEBLIT 2431 select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c
index 6ad23bd3523a..32c0b6b28097 100644
--- a/drivers/video/fbdev/amba-clcd.c
+++ b/drivers/video/fbdev/amba-clcd.c
@@ -27,7 +27,6 @@
27#include <linux/bitops.h> 27#include <linux/bitops.h>
28#include <linux/clk.h> 28#include <linux/clk.h>
29#include <linux/hardirq.h> 29#include <linux/hardirq.h>
30#include <linux/dma-mapping.h>
31#include <linux/of.h> 30#include <linux/of.h>
32#include <linux/of_address.h> 31#include <linux/of_address.h>
33#include <linux/of_graph.h> 32#include <linux/of_graph.h>
diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c
index adc4ea2cc5a0..b305a1e7cc76 100644
--- a/drivers/video/fbdev/arkfb.c
+++ b/drivers/video/fbdev/arkfb.c
@@ -1016,7 +1016,7 @@ static int ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
1016 1016
1017 pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg); 1017 pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg);
1018 1018
1019 par->state.vgabase = (void __iomem *) vga_res.start; 1019 par->state.vgabase = (void __iomem *) (unsigned long) vga_res.start;
1020 1020
1021 /* FIXME get memsize */ 1021 /* FIXME get memsize */
1022 regval = vga_rseq(par->state.vgabase, 0x10); 1022 regval = vga_rseq(par->state.vgabase, 0x10);
diff --git a/drivers/video/fbdev/mmp/core.c b/drivers/video/fbdev/mmp/core.c
index b563b920f159..a0f496049db7 100644
--- a/drivers/video/fbdev/mmp/core.c
+++ b/drivers/video/fbdev/mmp/core.c
@@ -223,10 +223,10 @@ struct mmp_path *mmp_register_path(struct mmp_path_info *info)
223EXPORT_SYMBOL_GPL(mmp_register_path); 223EXPORT_SYMBOL_GPL(mmp_register_path);
224 224
225/* 225/*
226 * mmp_unregister_path - unregister and destory path 226 * mmp_unregister_path - unregister and destroy path
227 * @p: path to be destoried. 227 * @p: path to be destroyed.
228 * 228 *
229 * this function registers path and destorys it. 229 * this function registers path and destroys it.
230 */ 230 */
231void mmp_unregister_path(struct mmp_path *path) 231void mmp_unregister_path(struct mmp_path *path)
232{ 232{
diff --git a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
index 8621a9f2bdcc..3c12bd83b561 100644
--- a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
+++ b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
@@ -441,8 +441,7 @@ static void path_deinit(struct mmphw_path_plat *path_plat)
441 if (!path_plat) 441 if (!path_plat)
442 return; 442 return;
443 443
444 if (path_plat->path) 444 mmp_unregister_path(path_plat->path);
445 mmp_unregister_path(path_plat->path);
446} 445}
447 446
448static int mmphw_probe(struct platform_device *pdev) 447static int mmphw_probe(struct platform_device *pdev)
diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c
index 23ec781e9a61..f23fca0be9d7 100644
--- a/drivers/video/fbdev/mx3fb.c
+++ b/drivers/video/fbdev/mx3fb.c
@@ -334,8 +334,7 @@ static void mx3fb_init_backlight(struct mx3fb_data *fbd)
334 334
335static void mx3fb_exit_backlight(struct mx3fb_data *fbd) 335static void mx3fb_exit_backlight(struct mx3fb_data *fbd)
336{ 336{
337 if (fbd->bl) 337 backlight_device_unregister(fbd->bl);
338 backlight_device_unregister(fbd->bl);
339} 338}
340 339
341static void mx3fb_dma_done(void *); 340static void mx3fb_dma_done(void *);
diff --git a/drivers/video/fbdev/mxsfb.c b/drivers/video/fbdev/mxsfb.c
index accf48a2cce4..f8ac4a452f26 100644
--- a/drivers/video/fbdev/mxsfb.c
+++ b/drivers/video/fbdev/mxsfb.c
@@ -172,6 +172,8 @@ struct mxsfb_info {
172 struct fb_info fb_info; 172 struct fb_info fb_info;
173 struct platform_device *pdev; 173 struct platform_device *pdev;
174 struct clk *clk; 174 struct clk *clk;
175 struct clk *clk_axi;
176 struct clk *clk_disp_axi;
175 void __iomem *base; /* registers */ 177 void __iomem *base; /* registers */
176 unsigned allocated_size; 178 unsigned allocated_size;
177 int enabled; 179 int enabled;
@@ -331,6 +333,11 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
331 } 333 }
332 } 334 }
333 335
336 if (host->clk_axi)
337 clk_prepare_enable(host->clk_axi);
338
339 if (host->clk_disp_axi)
340 clk_prepare_enable(host->clk_disp_axi);
334 clk_prepare_enable(host->clk); 341 clk_prepare_enable(host->clk);
335 clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U); 342 clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
336 343
@@ -374,6 +381,10 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
374 writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4); 381 writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4);
375 382
376 clk_disable_unprepare(host->clk); 383 clk_disable_unprepare(host->clk);
384 if (host->clk_disp_axi)
385 clk_disable_unprepare(host->clk_disp_axi);
386 if (host->clk_axi)
387 clk_disable_unprepare(host->clk_axi);
377 388
378 host->enabled = 0; 389 host->enabled = 0;
379 390
@@ -867,6 +878,14 @@ static int mxsfb_probe(struct platform_device *pdev)
867 goto fb_release; 878 goto fb_release;
868 } 879 }
869 880
881 host->clk_axi = devm_clk_get(&host->pdev->dev, "axi");
882 if (IS_ERR(host->clk_axi))
883 host->clk_axi = NULL;
884
885 host->clk_disp_axi = devm_clk_get(&host->pdev->dev, "disp_axi");
886 if (IS_ERR(host->clk_disp_axi))
887 host->clk_disp_axi = NULL;
888
870 host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd"); 889 host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");
871 if (IS_ERR(host->reg_lcd)) 890 if (IS_ERR(host->reg_lcd))
872 host->reg_lcd = NULL; 891 host->reg_lcd = NULL;
diff --git a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
index 2dfb6e5ff0cc..3d38e478bc64 100644
--- a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
@@ -262,8 +262,7 @@ static int dvic_probe_pdata(struct platform_device *pdev)
262 262
263 in = omap_dss_find_output(pdata->source); 263 in = omap_dss_find_output(pdata->source);
264 if (in == NULL) { 264 if (in == NULL) {
265 if (ddata->i2c_adapter) 265 i2c_put_adapter(ddata->i2c_adapter);
266 i2c_put_adapter(ddata->i2c_adapter);
267 266
268 dev_err(&pdev->dev, "Failed to find video source\n"); 267 dev_err(&pdev->dev, "Failed to find video source\n");
269 return -EPROBE_DEFER; 268 return -EPROBE_DEFER;
@@ -352,8 +351,7 @@ static int dvic_probe(struct platform_device *pdev)
352err_reg: 351err_reg:
353 omap_dss_put_device(ddata->in); 352 omap_dss_put_device(ddata->in);
354 353
355 if (ddata->i2c_adapter) 354 i2c_put_adapter(ddata->i2c_adapter);
356 i2c_put_adapter(ddata->i2c_adapter);
357 355
358 return r; 356 return r;
359} 357}
@@ -371,8 +369,7 @@ static int __exit dvic_remove(struct platform_device *pdev)
371 369
372 omap_dss_put_device(in); 370 omap_dss_put_device(in);
373 371
374 if (ddata->i2c_adapter) 372 i2c_put_adapter(ddata->i2c_adapter);
375 i2c_put_adapter(ddata->i2c_adapter);
376 373
377 return 0; 374 return 0;
378} 375}
diff --git a/drivers/video/fbdev/s3fb.c b/drivers/video/fbdev/s3fb.c
index c43b969e1e23..f0ae61a37f04 100644
--- a/drivers/video/fbdev/s3fb.c
+++ b/drivers/video/fbdev/s3fb.c
@@ -1182,7 +1182,7 @@ static int s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
1182 1182
1183 pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg); 1183 pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg);
1184 1184
1185 par->state.vgabase = (void __iomem *) vga_res.start; 1185 par->state.vgabase = (void __iomem *) (unsigned long) vga_res.start;
1186 1186
1187 /* Unlock regs */ 1187 /* Unlock regs */
1188 cr38 = vga_rcrt(par->state.vgabase, 0x38); 1188 cr38 = vga_rcrt(par->state.vgabase, 0x38);
diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c
index 2bcc84ac18c7..cfde21d81c15 100644
--- a/drivers/video/fbdev/sh_mobile_lcdcfb.c
+++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c
@@ -2181,8 +2181,7 @@ sh_mobile_lcdc_channel_fb_cleanup(struct sh_mobile_lcdc_chan *ch)
2181 if (!info || !info->device) 2181 if (!info || !info->device)
2182 return; 2182 return;
2183 2183
2184 if (ch->sglist) 2184 vfree(ch->sglist);
2185 vfree(ch->sglist);
2186 2185
2187 fb_dealloc_cmap(&info->cmap); 2186 fb_dealloc_cmap(&info->cmap);
2188 framebuffer_release(info); 2187 framebuffer_release(info);
diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c
index 210f3a02121a..b2ae9254fd75 100644
--- a/drivers/video/fbdev/simplefb.c
+++ b/drivers/video/fbdev/simplefb.c
@@ -26,6 +26,8 @@
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/platform_data/simplefb.h> 27#include <linux/platform_data/simplefb.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/clk-provider.h>
30#include <linux/of_platform.h>
29 31
30static struct fb_fix_screeninfo simplefb_fix = { 32static struct fb_fix_screeninfo simplefb_fix = {
31 .id = "simple", 33 .id = "simple",
@@ -41,6 +43,8 @@ static struct fb_var_screeninfo simplefb_var = {
41 .vmode = FB_VMODE_NONINTERLACED, 43 .vmode = FB_VMODE_NONINTERLACED,
42}; 44};
43 45
46#define PSEUDO_PALETTE_SIZE 16
47
44static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 48static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
45 u_int transp, struct fb_info *info) 49 u_int transp, struct fb_info *info)
46{ 50{
@@ -50,7 +54,7 @@ static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
50 u32 cb = blue >> (16 - info->var.blue.length); 54 u32 cb = blue >> (16 - info->var.blue.length);
51 u32 value; 55 u32 value;
52 56
53 if (regno >= 16) 57 if (regno >= PSEUDO_PALETTE_SIZE)
54 return -EINVAL; 58 return -EINVAL;
55 59
56 value = (cr << info->var.red.offset) | 60 value = (cr << info->var.red.offset) |
@@ -163,11 +167,113 @@ static int simplefb_parse_pd(struct platform_device *pdev,
163 return 0; 167 return 0;
164} 168}
165 169
170struct simplefb_par {
171 u32 palette[PSEUDO_PALETTE_SIZE];
172#if defined CONFIG_OF && defined CONFIG_COMMON_CLK
173 int clk_count;
174 struct clk **clks;
175#endif
176};
177
178#if defined CONFIG_OF && defined CONFIG_COMMON_CLK
179/*
180 * Clock handling code.
181 *
182 * Here we handle the clocks property of our "simple-framebuffer" dt node.
183 * This is necessary so that we can make sure that any clocks needed by
184 * the display engine that the bootloader set up for us (and for which it
185 * provided a simplefb dt node), stay up, for the life of the simplefb
186 * driver.
187 *
188 * When the driver unloads, we cleanly disable, and then release the clocks.
189 *
190 * We only complain about errors here, no action is taken as the most likely
191 * error can only happen due to a mismatch between the bootloader which set
192 * up simplefb, and the clock definitions in the device tree. Chances are
193 * that there are no adverse effects, and if there are, a clean teardown of
194 * the fb probe will not help us much either. So just complain and carry on,
195 * and hope that the user actually gets a working fb at the end of things.
196 */
197static int simplefb_clocks_init(struct simplefb_par *par,
198 struct platform_device *pdev)
199{
200 struct device_node *np = pdev->dev.of_node;
201 struct clk *clock;
202 int i, ret;
203
204 if (dev_get_platdata(&pdev->dev) || !np)
205 return 0;
206
207 par->clk_count = of_clk_get_parent_count(np);
208 if (par->clk_count <= 0)
209 return 0;
210
211 par->clks = kcalloc(par->clk_count, sizeof(struct clk *), GFP_KERNEL);
212 if (!par->clks)
213 return -ENOMEM;
214
215 for (i = 0; i < par->clk_count; i++) {
216 clock = of_clk_get(np, i);
217 if (IS_ERR(clock)) {
218 if (PTR_ERR(clock) == -EPROBE_DEFER) {
219 while (--i >= 0) {
220 if (par->clks[i])
221 clk_put(par->clks[i]);
222 }
223 kfree(par->clks);
224 return -EPROBE_DEFER;
225 }
226 dev_err(&pdev->dev, "%s: clock %d not found: %ld\n",
227 __func__, i, PTR_ERR(clock));
228 continue;
229 }
230 par->clks[i] = clock;
231 }
232
233 for (i = 0; i < par->clk_count; i++) {
234 if (par->clks[i]) {
235 ret = clk_prepare_enable(par->clks[i]);
236 if (ret) {
237 dev_err(&pdev->dev,
238 "%s: failed to enable clock %d: %d\n",
239 __func__, i, ret);
240 clk_put(par->clks[i]);
241 par->clks[i] = NULL;
242 }
243 }
244 }
245
246 return 0;
247}
248
249static void simplefb_clocks_destroy(struct simplefb_par *par)
250{
251 int i;
252
253 if (!par->clks)
254 return;
255
256 for (i = 0; i < par->clk_count; i++) {
257 if (par->clks[i]) {
258 clk_disable_unprepare(par->clks[i]);
259 clk_put(par->clks[i]);
260 }
261 }
262
263 kfree(par->clks);
264}
265#else
266static int simplefb_clocks_init(struct simplefb_par *par,
267 struct platform_device *pdev) { return 0; }
268static void simplefb_clocks_destroy(struct simplefb_par *par) { }
269#endif
270
166static int simplefb_probe(struct platform_device *pdev) 271static int simplefb_probe(struct platform_device *pdev)
167{ 272{
168 int ret; 273 int ret;
169 struct simplefb_params params; 274 struct simplefb_params params;
170 struct fb_info *info; 275 struct fb_info *info;
276 struct simplefb_par *par;
171 struct resource *mem; 277 struct resource *mem;
172 278
173 if (fb_get_options("simplefb", NULL)) 279 if (fb_get_options("simplefb", NULL))
@@ -188,11 +294,13 @@ static int simplefb_probe(struct platform_device *pdev)
188 return -EINVAL; 294 return -EINVAL;
189 } 295 }
190 296
191 info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev); 297 info = framebuffer_alloc(sizeof(struct simplefb_par), &pdev->dev);
192 if (!info) 298 if (!info)
193 return -ENOMEM; 299 return -ENOMEM;
194 platform_set_drvdata(pdev, info); 300 platform_set_drvdata(pdev, info);
195 301
302 par = info->par;
303
196 info->fix = simplefb_fix; 304 info->fix = simplefb_fix;
197 info->fix.smem_start = mem->start; 305 info->fix.smem_start = mem->start;
198 info->fix.smem_len = resource_size(mem); 306 info->fix.smem_len = resource_size(mem);
@@ -211,8 +319,8 @@ static int simplefb_probe(struct platform_device *pdev)
211 319
212 info->apertures = alloc_apertures(1); 320 info->apertures = alloc_apertures(1);
213 if (!info->apertures) { 321 if (!info->apertures) {
214 framebuffer_release(info); 322 ret = -ENOMEM;
215 return -ENOMEM; 323 goto error_fb_release;
216 } 324 }
217 info->apertures->ranges[0].base = info->fix.smem_start; 325 info->apertures->ranges[0].base = info->fix.smem_start;
218 info->apertures->ranges[0].size = info->fix.smem_len; 326 info->apertures->ranges[0].size = info->fix.smem_len;
@@ -222,10 +330,14 @@ static int simplefb_probe(struct platform_device *pdev)
222 info->screen_base = ioremap_wc(info->fix.smem_start, 330 info->screen_base = ioremap_wc(info->fix.smem_start,
223 info->fix.smem_len); 331 info->fix.smem_len);
224 if (!info->screen_base) { 332 if (!info->screen_base) {
225 framebuffer_release(info); 333 ret = -ENOMEM;
226 return -ENODEV; 334 goto error_fb_release;
227 } 335 }
228 info->pseudo_palette = (void *)(info + 1); 336 info->pseudo_palette = par->palette;
337
338 ret = simplefb_clocks_init(par, pdev);
339 if (ret < 0)
340 goto error_unmap;
229 341
230 dev_info(&pdev->dev, "framebuffer at 0x%lx, 0x%x bytes, mapped to 0x%p\n", 342 dev_info(&pdev->dev, "framebuffer at 0x%lx, 0x%x bytes, mapped to 0x%p\n",
231 info->fix.smem_start, info->fix.smem_len, 343 info->fix.smem_start, info->fix.smem_len,
@@ -238,21 +350,29 @@ static int simplefb_probe(struct platform_device *pdev)
238 ret = register_framebuffer(info); 350 ret = register_framebuffer(info);
239 if (ret < 0) { 351 if (ret < 0) {
240 dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret); 352 dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret);
241 iounmap(info->screen_base); 353 goto error_clocks;
242 framebuffer_release(info);
243 return ret;
244 } 354 }
245 355
246 dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node); 356 dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node);
247 357
248 return 0; 358 return 0;
359
360error_clocks:
361 simplefb_clocks_destroy(par);
362error_unmap:
363 iounmap(info->screen_base);
364error_fb_release:
365 framebuffer_release(info);
366 return ret;
249} 367}
250 368
251static int simplefb_remove(struct platform_device *pdev) 369static int simplefb_remove(struct platform_device *pdev)
252{ 370{
253 struct fb_info *info = platform_get_drvdata(pdev); 371 struct fb_info *info = platform_get_drvdata(pdev);
372 struct simplefb_par *par = info->par;
254 373
255 unregister_framebuffer(info); 374 unregister_framebuffer(info);
375 simplefb_clocks_destroy(par);
256 framebuffer_release(info); 376 framebuffer_release(info);
257 377
258 return 0; 378 return 0;
@@ -273,7 +393,27 @@ static struct platform_driver simplefb_driver = {
273 .probe = simplefb_probe, 393 .probe = simplefb_probe,
274 .remove = simplefb_remove, 394 .remove = simplefb_remove,
275}; 395};
276module_platform_driver(simplefb_driver); 396
397static int __init simplefb_init(void)
398{
399 int ret;
400 struct device_node *np;
401
402 ret = platform_driver_register(&simplefb_driver);
403 if (ret)
404 return ret;
405
406 if (IS_ENABLED(CONFIG_OF) && of_chosen) {
407 for_each_child_of_node(of_chosen, np) {
408 if (of_device_is_compatible(np, "simple-framebuffer"))
409 of_platform_device_create(np, NULL, NULL);
410 }
411 }
412
413 return 0;
414}
415
416fs_initcall(simplefb_init);
277 417
278MODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>"); 418MODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>");
279MODULE_DESCRIPTION("Simple framebuffer driver"); 419MODULE_DESCRIPTION("Simple framebuffer driver");
diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c
index e5d11b1892e8..fcf610edf217 100644
--- a/drivers/video/fbdev/sis/sis_main.c
+++ b/drivers/video/fbdev/sis/sis_main.c
@@ -5989,7 +5989,7 @@ static int sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
5989 5989
5990 if(!ivideo->sisvga_enabled) { 5990 if(!ivideo->sisvga_enabled) {
5991 if(pci_enable_device(pdev)) { 5991 if(pci_enable_device(pdev)) {
5992 if(ivideo->nbridge) pci_dev_put(ivideo->nbridge); 5992 pci_dev_put(ivideo->nbridge);
5993 framebuffer_release(sis_fb_info); 5993 framebuffer_release(sis_fb_info);
5994 return -EIO; 5994 return -EIO;
5995 } 5995 }
@@ -6202,10 +6202,8 @@ error_0: iounmap(ivideo->video_vbase);
6202error_1: release_mem_region(ivideo->video_base, ivideo->video_size); 6202error_1: release_mem_region(ivideo->video_base, ivideo->video_size);
6203error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size); 6203error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
6204error_3: vfree(ivideo->bios_abase); 6204error_3: vfree(ivideo->bios_abase);
6205 if(ivideo->lpcdev) 6205 pci_dev_put(ivideo->lpcdev);
6206 pci_dev_put(ivideo->lpcdev); 6206 pci_dev_put(ivideo->nbridge);
6207 if(ivideo->nbridge)
6208 pci_dev_put(ivideo->nbridge);
6209 if(!ivideo->sisvga_enabled) 6207 if(!ivideo->sisvga_enabled)
6210 pci_disable_device(pdev); 6208 pci_disable_device(pdev);
6211 framebuffer_release(sis_fb_info); 6209 framebuffer_release(sis_fb_info);
@@ -6505,11 +6503,9 @@ static void sisfb_remove(struct pci_dev *pdev)
6505 6503
6506 vfree(ivideo->bios_abase); 6504 vfree(ivideo->bios_abase);
6507 6505
6508 if(ivideo->lpcdev) 6506 pci_dev_put(ivideo->lpcdev);
6509 pci_dev_put(ivideo->lpcdev);
6510 6507
6511 if(ivideo->nbridge) 6508 pci_dev_put(ivideo->nbridge);
6512 pci_dev_put(ivideo->nbridge);
6513 6509
6514#ifdef CONFIG_MTRR 6510#ifdef CONFIG_MTRR
6515 /* Release MTRR region */ 6511 /* Release MTRR region */
diff --git a/drivers/video/fbdev/sm501fb.c b/drivers/video/fbdev/sm501fb.c
index 9e74e8fbe074..8b98b011fc04 100644
--- a/drivers/video/fbdev/sm501fb.c
+++ b/drivers/video/fbdev/sm501fb.c
@@ -1988,6 +1988,7 @@ static int sm501fb_probe(struct platform_device *pdev)
1988 if (info->fb[HEAD_PANEL] == NULL && 1988 if (info->fb[HEAD_PANEL] == NULL &&
1989 info->fb[HEAD_CRT] == NULL) { 1989 info->fb[HEAD_CRT] == NULL) {
1990 dev_err(dev, "no framebuffers found\n"); 1990 dev_err(dev, "no framebuffers found\n");
1991 ret = -ENODEV;
1991 goto err_alloc; 1992 goto err_alloc;
1992 } 1993 }
1993 1994
diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
index d513ed6a49f2..9279e5f6696e 100644
--- a/drivers/video/fbdev/smscufx.c
+++ b/drivers/video/fbdev/smscufx.c
@@ -1142,8 +1142,7 @@ static void ufx_free_framebuffer_work(struct work_struct *work)
1142 fb_dealloc_cmap(&info->cmap); 1142 fb_dealloc_cmap(&info->cmap);
1143 if (info->monspecs.modedb) 1143 if (info->monspecs.modedb)
1144 fb_destroy_modedb(info->monspecs.modedb); 1144 fb_destroy_modedb(info->monspecs.modedb);
1145 if (info->screen_base) 1145 vfree(info->screen_base);
1146 vfree(info->screen_base);
1147 1146
1148 fb_destroy_modelist(&info->modelist); 1147 fb_destroy_modelist(&info->modelist);
1149 1148
@@ -1743,8 +1742,7 @@ error:
1743 fb_dealloc_cmap(&info->cmap); 1742 fb_dealloc_cmap(&info->cmap);
1744 if (info->monspecs.modedb) 1743 if (info->monspecs.modedb)
1745 fb_destroy_modedb(info->monspecs.modedb); 1744 fb_destroy_modedb(info->monspecs.modedb);
1746 if (info->screen_base) 1745 vfree(info->screen_base);
1747 vfree(info->screen_base);
1748 1746
1749 fb_destroy_modelist(&info->modelist); 1747 fb_destroy_modelist(&info->modelist);
1750 1748
diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c
index 046d51d83d74..ff2b8731a2dc 100644
--- a/drivers/video/fbdev/udlfb.c
+++ b/drivers/video/fbdev/udlfb.c
@@ -922,8 +922,7 @@ static void dlfb_free(struct kref *kref)
922{ 922{
923 struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref); 923 struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref);
924 924
925 if (dev->backing_buffer) 925 vfree(dev->backing_buffer);
926 vfree(dev->backing_buffer);
927 926
928 kfree(dev->edid); 927 kfree(dev->edid);
929 928
@@ -953,8 +952,7 @@ static void dlfb_free_framebuffer(struct dlfb_data *dev)
953 fb_dealloc_cmap(&info->cmap); 952 fb_dealloc_cmap(&info->cmap);
954 if (info->monspecs.modedb) 953 if (info->monspecs.modedb)
955 fb_destroy_modedb(info->monspecs.modedb); 954 fb_destroy_modedb(info->monspecs.modedb);
956 if (info->screen_base) 955 vfree(info->screen_base);
957 vfree(info->screen_base);
958 956
959 fb_destroy_modelist(&info->modelist); 957 fb_destroy_modelist(&info->modelist);
960 958
@@ -1203,8 +1201,7 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info)
1203 if (!new_back) 1201 if (!new_back)
1204 pr_info("No shadow/backing buffer allocated\n"); 1202 pr_info("No shadow/backing buffer allocated\n");
1205 else { 1203 else {
1206 if (dev->backing_buffer) 1204 vfree(dev->backing_buffer);
1207 vfree(dev->backing_buffer);
1208 dev->backing_buffer = new_back; 1205 dev->backing_buffer = new_back;
1209 } 1206 }
1210 } 1207 }
diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index 509d452e8f91..d32d1c4d1b99 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -1219,8 +1219,7 @@ static int uvesafb_release(struct fb_info *info, int user)
1219 uvesafb_vbe_state_restore(par, par->vbe_state_orig); 1219 uvesafb_vbe_state_restore(par, par->vbe_state_orig);
1220out: 1220out:
1221 atomic_dec(&par->ref_count); 1221 atomic_dec(&par->ref_count);
1222 if (task) 1222 uvesafb_free(task);
1223 uvesafb_free(task);
1224 return 0; 1223 return 0;
1225} 1224}
1226 1225
@@ -1923,8 +1922,7 @@ static int uvesafb_init(void)
1923 err = -ENOMEM; 1922 err = -ENOMEM;
1924 1923
1925 if (err) { 1924 if (err) {
1926 if (uvesafb_device) 1925 platform_device_put(uvesafb_device);
1927 platform_device_put(uvesafb_device);
1928 platform_driver_unregister(&uvesafb_driver); 1926 platform_driver_unregister(&uvesafb_driver);
1929 cn_del_callback(&uvesafb_cn_id); 1927 cn_del_callback(&uvesafb_cn_id);
1930 return err; 1928 return err;
diff --git a/drivers/video/fbdev/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c
index 325c43c6ff97..f9718f012aae 100644
--- a/drivers/video/fbdev/via/viafbdev.c
+++ b/drivers/video/fbdev/via/viafbdev.c
@@ -1937,8 +1937,7 @@ out_fb1_unreg_lcd_cle266:
1937out_dealloc_cmap: 1937out_dealloc_cmap:
1938 fb_dealloc_cmap(&viafbinfo->cmap); 1938 fb_dealloc_cmap(&viafbinfo->cmap);
1939out_fb1_release: 1939out_fb1_release:
1940 if (viafbinfo1) 1940 framebuffer_release(viafbinfo1);
1941 framebuffer_release(viafbinfo1);
1942out_fb_release: 1941out_fb_release:
1943 i2c_bus_free(viaparinfo->shared); 1942 i2c_bus_free(viaparinfo->shared);
1944 framebuffer_release(viafbinfo); 1943 framebuffer_release(viafbinfo);
diff --git a/drivers/video/fbdev/vt8623fb.c b/drivers/video/fbdev/vt8623fb.c
index 5c7cbc6c6236..ea7f056ed5fe 100644
--- a/drivers/video/fbdev/vt8623fb.c
+++ b/drivers/video/fbdev/vt8623fb.c
@@ -731,7 +731,7 @@ static int vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
731 731
732 pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg); 732 pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg);
733 733
734 par->state.vgabase = (void __iomem *) vga_res.start; 734 par->state.vgabase = (void __iomem *) (unsigned long) vga_res.start;
735 735
736 /* Find how many physical memory there is on card */ 736 /* Find how many physical memory there is on card */
737 memsize1 = (vga_rseq(par->state.vgabase, 0x34) + 1) >> 1; 737 memsize1 = (vga_rseq(par->state.vgabase, 0x34) + 1) >> 1;
diff --git a/include/linux/of.h b/include/linux/of.h
index 6545e7aec7bb..f83ca9dddcba 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -105,8 +105,6 @@ static inline struct device_node *of_node_get(struct device_node *node)
105static inline void of_node_put(struct device_node *node) { } 105static inline void of_node_put(struct device_node *node) { }
106#endif /* !CONFIG_OF_DYNAMIC */ 106#endif /* !CONFIG_OF_DYNAMIC */
107 107
108#ifdef CONFIG_OF
109
110/* Pointer for first entry in chain of all nodes. */ 108/* Pointer for first entry in chain of all nodes. */
111extern struct device_node *of_allnodes; 109extern struct device_node *of_allnodes;
112extern struct device_node *of_chosen; 110extern struct device_node *of_chosen;
@@ -114,6 +112,7 @@ extern struct device_node *of_aliases;
114extern struct device_node *of_stdout; 112extern struct device_node *of_stdout;
115extern raw_spinlock_t devtree_lock; 113extern raw_spinlock_t devtree_lock;
116 114
115#ifdef CONFIG_OF
117static inline bool of_have_populated_dt(void) 116static inline bool of_have_populated_dt(void)
118{ 117{
119 return of_allnodes != NULL; 118 return of_allnodes != NULL;