summaryrefslogtreecommitdiff
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 @@
+Sunxi specific Simple Framebuffer bindings
+
+This binding documents sunxi specific extensions to the simple-framebuffer
+bindings. The sunxi simplefb u-boot code relies on the devicetree containing
+pre-populated simplefb nodes.
+
+These extensions are intended so that u-boot can select the right node based
+on which pipeline is being used. As such they are solely intended for
+firmware / bootloader use, and the OS should ignore them.
+
+Required properties:
+- compatible: "allwinner,simple-framebuffer"
+- allwinner,pipeline, one of:
+ "de_be0-lcd0"
+ "de_be1-lcd1"
+ "de_be0-lcd0-hdmi"
+ "de_be1-lcd1-hdmi"
+
+Example:
+
+chosen {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ framebuffer@0 {
+ compatible = "allwinner,simple-framebuffer", "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0-hdmi";
+ clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>,
+ <&ahb_gates 44>;
+ status = "disabled";
+ };
+};
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 @@
Simple Framebuffer
-A simple frame-buffer describes a raw memory region that may be rendered to,
-with the assumption that the display hardware has already been set up to scan
-out from that buffer.
+A simple frame-buffer describes a frame-buffer setup by firmware or
+the bootloader, with the assumption that the display hardware has already
+been set up to scan out from the memory pointed to by the reg property.
+
+Since simplefb nodes represent runtime information they must be sub-nodes of
+the chosen node (*). Simplefb nodes must be named "framebuffer@<address>".
+
+If the devicetree contains nodes for the display hardware used by a simplefb,
+then the simplefb node must contain a property called "display", which
+contains a phandle pointing to the primary display hw node, so that the OS
+knows which simplefb to disable when handing over control to a driver for the
+real hardware. The bindings for the hw nodes must specify which node is
+considered the primary node.
+
+It is advised to add display# aliases to help the OS determine how to number
+things. If display# aliases are used, then if the simplefb node contains a
+"display" property then the /aliases/display# path must point to the display
+hw node the "display" property points to, otherwise it must point directly
+to the simplefb node.
+
+If a simplefb node represents the preferred console for user interaction,
+then the chosen node's stdout-path property should point to it, or to the
+primary display hw node, as with display# aliases. If display aliases are
+used then it should be set to the alias instead.
+
+It is advised that devicetree files contain pre-filled, disabled framebuffer
+nodes, so that the firmware only needs to update the mode information and
+enable them. This way if e.g. later on support for more display clocks get
+added, the simplefb nodes will already contain this info and the firmware
+does not need to be updated.
+
+If pre-filled framebuffer nodes are used, the firmware may need extra
+information to find the right node. In that case an extra platform specific
+compatible and platform specific properties should be used and documented,
+see e.g. simple-framebuffer-sunxi.txt .
Required properties:
- compatible: "simple-framebuffer"
@@ -14,13 +46,41 @@ Required properties:
- r5g6b5 (16-bit pixels, d[15:11]=r, d[10:5]=g, d[4:0]=b).
- a8b8g8r8 (32-bit pixels, d[31:24]=a, d[23:16]=b, d[15:8]=g, d[7:0]=r).
+Optional properties:
+- clocks : List of clocks used by the framebuffer. Clocks listed here
+ are expected to already be configured correctly. The OS must
+ ensure these clocks are not modified or disabled while the
+ simple framebuffer remains active.
+- display : phandle pointing to the primary display hardware node
+
Example:
- framebuffer {
+aliases {
+ display0 = &lcdc0;
+}
+
+chosen {
+ framebuffer0: framebuffer@1d385000 {
compatible = "simple-framebuffer";
reg = <0x1d385000 (1600 * 1200 * 2)>;
width = <1600>;
height = <1200>;
stride = <(1600 * 2)>;
format = "r5g6b5";
+ clocks = <&ahb_gates 36>, <&ahb_gates 43>, <&ahb_gates 44>;
+ display = <&lcdc0>;
+ };
+ stdout-path = "display0";
+};
+
+soc@01c00000 {
+ lcdc0: lcdc@1c0c000 {
+ compatible = "allwinner,sun4i-a10-lcdc";
+ ...
};
+};
+
+
+*) Older devicetree files may have a compatible = "simple-framebuffer" node
+in a different place, operating systems must first enumerate any compatible
+nodes 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/
F: drivers/media/usb/siano/
F: drivers/media/mmc/siano/
+SIMPLEFB FB DRIVER
+M: Hans de Goede <hdegoede@redhat.com>
+L: linux-fbdev@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/video/simple-framebuffer.txt
+F: drivers/video/fbdev/simplefb.c
+F: include/linux/platform_data/simplefb.h
+
SH_VEU V4L2 MEM2MEM DRIVER
L: linux-media@vger.kernel.org
S: 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)
return 0;
}
-module_init(fb_console_init);
+fs_initcall(fb_console_init);
#ifdef MODULE
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
config FB_MXS
tristate "MXS LCD framebuffer support"
- depends on FB && ARCH_MXS
+ depends on FB && (ARCH_MXS || ARCH_MXC)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
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 @@
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/hardirq.h>
-#include <linux/dma-mapping.h>
#include <linux/of.h>
#include <linux/of_address.h>
#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)
pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg);
- par->state.vgabase = (void __iomem *) vga_res.start;
+ par->state.vgabase = (void __iomem *) (unsigned long) vga_res.start;
/* FIXME get memsize */
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)
EXPORT_SYMBOL_GPL(mmp_register_path);
/*
- * mmp_unregister_path - unregister and destory path
- * @p: path to be destoried.
+ * mmp_unregister_path - unregister and destroy path
+ * @p: path to be destroyed.
*
- * this function registers path and destorys it.
+ * this function registers path and destroys it.
*/
void mmp_unregister_path(struct mmp_path *path)
{
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)
if (!path_plat)
return;
- if (path_plat->path)
- mmp_unregister_path(path_plat->path);
+ mmp_unregister_path(path_plat->path);
}
static 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)
static void mx3fb_exit_backlight(struct mx3fb_data *fbd)
{
- if (fbd->bl)
- backlight_device_unregister(fbd->bl);
+ backlight_device_unregister(fbd->bl);
}
static 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 {
struct fb_info fb_info;
struct platform_device *pdev;
struct clk *clk;
+ struct clk *clk_axi;
+ struct clk *clk_disp_axi;
void __iomem *base; /* registers */
unsigned allocated_size;
int enabled;
@@ -331,6 +333,11 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
}
}
+ if (host->clk_axi)
+ clk_prepare_enable(host->clk_axi);
+
+ if (host->clk_disp_axi)
+ clk_prepare_enable(host->clk_disp_axi);
clk_prepare_enable(host->clk);
clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
@@ -374,6 +381,10 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4);
clk_disable_unprepare(host->clk);
+ if (host->clk_disp_axi)
+ clk_disable_unprepare(host->clk_disp_axi);
+ if (host->clk_axi)
+ clk_disable_unprepare(host->clk_axi);
host->enabled = 0;
@@ -867,6 +878,14 @@ static int mxsfb_probe(struct platform_device *pdev)
goto fb_release;
}
+ host->clk_axi = devm_clk_get(&host->pdev->dev, "axi");
+ if (IS_ERR(host->clk_axi))
+ host->clk_axi = NULL;
+
+ host->clk_disp_axi = devm_clk_get(&host->pdev->dev, "disp_axi");
+ if (IS_ERR(host->clk_disp_axi))
+ host->clk_disp_axi = NULL;
+
host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");
if (IS_ERR(host->reg_lcd))
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)
in = omap_dss_find_output(pdata->source);
if (in == NULL) {
- if (ddata->i2c_adapter)
- i2c_put_adapter(ddata->i2c_adapter);
+ i2c_put_adapter(ddata->i2c_adapter);
dev_err(&pdev->dev, "Failed to find video source\n");
return -EPROBE_DEFER;
@@ -352,8 +351,7 @@ static int dvic_probe(struct platform_device *pdev)
err_reg:
omap_dss_put_device(ddata->in);
- if (ddata->i2c_adapter)
- i2c_put_adapter(ddata->i2c_adapter);
+ i2c_put_adapter(ddata->i2c_adapter);
return r;
}
@@ -371,8 +369,7 @@ static int __exit dvic_remove(struct platform_device *pdev)
omap_dss_put_device(in);
- if (ddata->i2c_adapter)
- i2c_put_adapter(ddata->i2c_adapter);
+ i2c_put_adapter(ddata->i2c_adapter);
return 0;
}
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)
pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg);
- par->state.vgabase = (void __iomem *) vga_res.start;
+ par->state.vgabase = (void __iomem *) (unsigned long) vga_res.start;
/* Unlock regs */
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)
if (!info || !info->device)
return;
- if (ch->sglist)
- vfree(ch->sglist);
+ vfree(ch->sglist);
fb_dealloc_cmap(&info->cmap);
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 @@
#include <linux/module.h>
#include <linux/platform_data/simplefb.h>
#include <linux/platform_device.h>
+#include <linux/clk-provider.h>
+#include <linux/of_platform.h>
static struct fb_fix_screeninfo simplefb_fix = {
.id = "simple",
@@ -41,6 +43,8 @@ static struct fb_var_screeninfo simplefb_var = {
.vmode = FB_VMODE_NONINTERLACED,
};
+#define PSEUDO_PALETTE_SIZE 16
+
static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info)
{
@@ -50,7 +54,7 @@ static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u32 cb = blue >> (16 - info->var.blue.length);
u32 value;
- if (regno >= 16)
+ if (regno >= PSEUDO_PALETTE_SIZE)
return -EINVAL;
value = (cr << info->var.red.offset) |
@@ -163,11 +167,113 @@ static int simplefb_parse_pd(struct platform_device *pdev,
return 0;
}
+struct simplefb_par {
+ u32 palette[PSEUDO_PALETTE_SIZE];
+#if defined CONFIG_OF && defined CONFIG_COMMON_CLK
+ int clk_count;
+ struct clk **clks;
+#endif
+};
+
+#if defined CONFIG_OF && defined CONFIG_COMMON_CLK
+/*
+ * Clock handling code.
+ *
+ * Here we handle the clocks property of our "simple-framebuffer" dt node.
+ * This is necessary so that we can make sure that any clocks needed by
+ * the display engine that the bootloader set up for us (and for which it
+ * provided a simplefb dt node), stay up, for the life of the simplefb
+ * driver.
+ *
+ * When the driver unloads, we cleanly disable, and then release the clocks.
+ *
+ * We only complain about errors here, no action is taken as the most likely
+ * error can only happen due to a mismatch between the bootloader which set
+ * up simplefb, and the clock definitions in the device tree. Chances are
+ * that there are no adverse effects, and if there are, a clean teardown of
+ * the fb probe will not help us much either. So just complain and carry on,
+ * and hope that the user actually gets a working fb at the end of things.
+ */
+static int simplefb_clocks_init(struct simplefb_par *par,
+ struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct clk *clock;
+ int i, ret;
+
+ if (dev_get_platdata(&pdev->dev) || !np)
+ return 0;
+
+ par->clk_count = of_clk_get_parent_count(np);
+ if (par->clk_count <= 0)
+ return 0;
+
+ par->clks = kcalloc(par->clk_count, sizeof(struct clk *), GFP_KERNEL);
+ if (!par->clks)
+ return -ENOMEM;
+
+ for (i = 0; i < par->clk_count; i++) {
+ clock = of_clk_get(np, i);
+ if (IS_ERR(clock)) {
+ if (PTR_ERR(clock) == -EPROBE_DEFER) {
+ while (--i >= 0) {
+ if (par->clks[i])
+ clk_put(par->clks[i]);
+ }
+ kfree(par->clks);
+ return -EPROBE_DEFER;
+ }
+ dev_err(&pdev->dev, "%s: clock %d not found: %ld\n",
+ __func__, i, PTR_ERR(clock));
+ continue;
+ }
+ par->clks[i] = clock;
+ }
+
+ for (i = 0; i < par->clk_count; i++) {
+ if (par->clks[i]) {
+ ret = clk_prepare_enable(par->clks[i]);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "%s: failed to enable clock %d: %d\n",
+ __func__, i, ret);
+ clk_put(par->clks[i]);
+ par->clks[i] = NULL;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void simplefb_clocks_destroy(struct simplefb_par *par)
+{
+ int i;
+
+ if (!par->clks)
+ return;
+
+ for (i = 0; i < par->clk_count; i++) {
+ if (par->clks[i]) {
+ clk_disable_unprepare(par->clks[i]);
+ clk_put(par->clks[i]);
+ }
+ }
+
+ kfree(par->clks);
+}
+#else
+static int simplefb_clocks_init(struct simplefb_par *par,
+ struct platform_device *pdev) { return 0; }
+static void simplefb_clocks_destroy(struct simplefb_par *par) { }
+#endif
+
static int simplefb_probe(struct platform_device *pdev)
{
int ret;
struct simplefb_params params;
struct fb_info *info;
+ struct simplefb_par *par;
struct resource *mem;
if (fb_get_options("simplefb", NULL))
@@ -188,11 +294,13 @@ static int simplefb_probe(struct platform_device *pdev)
return -EINVAL;
}
- info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev);
+ info = framebuffer_alloc(sizeof(struct simplefb_par), &pdev->dev);
if (!info)
return -ENOMEM;
platform_set_drvdata(pdev, info);
+ par = info->par;
+
info->fix = simplefb_fix;
info->fix.smem_start = mem->start;
info->fix.smem_len = resource_size(mem);
@@ -211,8 +319,8 @@ static int simplefb_probe(struct platform_device *pdev)
info->apertures = alloc_apertures(1);
if (!info->apertures) {
- framebuffer_release(info);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto error_fb_release;
}
info->apertures->ranges[0].base = info->fix.smem_start;
info->apertures->ranges[0].size = info->fix.smem_len;
@@ -222,10 +330,14 @@ static int simplefb_probe(struct platform_device *pdev)
info->screen_base = ioremap_wc(info->fix.smem_start,
info->fix.smem_len);
if (!info->screen_base) {
- framebuffer_release(info);
- return -ENODEV;
+ ret = -ENOMEM;
+ goto error_fb_release;
}
- info->pseudo_palette = (void *)(info + 1);
+ info->pseudo_palette = par->palette;
+
+ ret = simplefb_clocks_init(par, pdev);
+ if (ret < 0)
+ goto error_unmap;
dev_info(&pdev->dev, "framebuffer at 0x%lx, 0x%x bytes, mapped to 0x%p\n",
info->fix.smem_start, info->fix.smem_len,
@@ -238,21 +350,29 @@ static int simplefb_probe(struct platform_device *pdev)
ret = register_framebuffer(info);
if (ret < 0) {
dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret);
- iounmap(info->screen_base);
- framebuffer_release(info);
- return ret;
+ goto error_clocks;
}
dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node);
return 0;
+
+error_clocks:
+ simplefb_clocks_destroy(par);
+error_unmap:
+ iounmap(info->screen_base);
+error_fb_release:
+ framebuffer_release(info);
+ return ret;
}
static int simplefb_remove(struct platform_device *pdev)
{
struct fb_info *info = platform_get_drvdata(pdev);
+ struct simplefb_par *par = info->par;
unregister_framebuffer(info);
+ simplefb_clocks_destroy(par);
framebuffer_release(info);
return 0;
@@ -273,7 +393,27 @@ static struct platform_driver simplefb_driver = {
.probe = simplefb_probe,
.remove = simplefb_remove,
};
-module_platform_driver(simplefb_driver);
+
+static int __init simplefb_init(void)
+{
+ int ret;
+ struct device_node *np;
+
+ ret = platform_driver_register(&simplefb_driver);
+ if (ret)
+ return ret;
+
+ if (IS_ENABLED(CONFIG_OF) && of_chosen) {
+ for_each_child_of_node(of_chosen, np) {
+ if (of_device_is_compatible(np, "simple-framebuffer"))
+ of_platform_device_create(np, NULL, NULL);
+ }
+ }
+
+ return 0;
+}
+
+fs_initcall(simplefb_init);
MODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>");
MODULE_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)
if(!ivideo->sisvga_enabled) {
if(pci_enable_device(pdev)) {
- if(ivideo->nbridge) pci_dev_put(ivideo->nbridge);
+ pci_dev_put(ivideo->nbridge);
framebuffer_release(sis_fb_info);
return -EIO;
}
@@ -6202,10 +6202,8 @@ error_0: iounmap(ivideo->video_vbase);
error_1: release_mem_region(ivideo->video_base, ivideo->video_size);
error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
error_3: vfree(ivideo->bios_abase);
- if(ivideo->lpcdev)
- pci_dev_put(ivideo->lpcdev);
- if(ivideo->nbridge)
- pci_dev_put(ivideo->nbridge);
+ pci_dev_put(ivideo->lpcdev);
+ pci_dev_put(ivideo->nbridge);
if(!ivideo->sisvga_enabled)
pci_disable_device(pdev);
framebuffer_release(sis_fb_info);
@@ -6505,11 +6503,9 @@ static void sisfb_remove(struct pci_dev *pdev)
vfree(ivideo->bios_abase);
- if(ivideo->lpcdev)
- pci_dev_put(ivideo->lpcdev);
+ pci_dev_put(ivideo->lpcdev);
- if(ivideo->nbridge)
- pci_dev_put(ivideo->nbridge);
+ pci_dev_put(ivideo->nbridge);
#ifdef CONFIG_MTRR
/* 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)
if (info->fb[HEAD_PANEL] == NULL &&
info->fb[HEAD_CRT] == NULL) {
dev_err(dev, "no framebuffers found\n");
+ ret = -ENODEV;
goto err_alloc;
}
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)
fb_dealloc_cmap(&info->cmap);
if (info->monspecs.modedb)
fb_destroy_modedb(info->monspecs.modedb);
- if (info->screen_base)
- vfree(info->screen_base);
+ vfree(info->screen_base);
fb_destroy_modelist(&info->modelist);
@@ -1743,8 +1742,7 @@ error:
fb_dealloc_cmap(&info->cmap);
if (info->monspecs.modedb)
fb_destroy_modedb(info->monspecs.modedb);
- if (info->screen_base)
- vfree(info->screen_base);
+ vfree(info->screen_base);
fb_destroy_modelist(&info->modelist);
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)
{
struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref);
- if (dev->backing_buffer)
- vfree(dev->backing_buffer);
+ vfree(dev->backing_buffer);
kfree(dev->edid);
@@ -953,8 +952,7 @@ static void dlfb_free_framebuffer(struct dlfb_data *dev)
fb_dealloc_cmap(&info->cmap);
if (info->monspecs.modedb)
fb_destroy_modedb(info->monspecs.modedb);
- if (info->screen_base)
- vfree(info->screen_base);
+ vfree(info->screen_base);
fb_destroy_modelist(&info->modelist);
@@ -1203,8 +1201,7 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info)
if (!new_back)
pr_info("No shadow/backing buffer allocated\n");
else {
- if (dev->backing_buffer)
- vfree(dev->backing_buffer);
+ vfree(dev->backing_buffer);
dev->backing_buffer = new_back;
}
}
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)
uvesafb_vbe_state_restore(par, par->vbe_state_orig);
out:
atomic_dec(&par->ref_count);
- if (task)
- uvesafb_free(task);
+ uvesafb_free(task);
return 0;
}
@@ -1923,8 +1922,7 @@ static int uvesafb_init(void)
err = -ENOMEM;
if (err) {
- if (uvesafb_device)
- platform_device_put(uvesafb_device);
+ platform_device_put(uvesafb_device);
platform_driver_unregister(&uvesafb_driver);
cn_del_callback(&uvesafb_cn_id);
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:
out_dealloc_cmap:
fb_dealloc_cmap(&viafbinfo->cmap);
out_fb1_release:
- if (viafbinfo1)
- framebuffer_release(viafbinfo1);
+ framebuffer_release(viafbinfo1);
out_fb_release:
i2c_bus_free(viaparinfo->shared);
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)
pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg);
- par->state.vgabase = (void __iomem *) vga_res.start;
+ par->state.vgabase = (void __iomem *) (unsigned long) vga_res.start;
/* Find how many physical memory there is on card */
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)
static inline void of_node_put(struct device_node *node) { }
#endif /* !CONFIG_OF_DYNAMIC */
-#ifdef CONFIG_OF
-
/* Pointer for first entry in chain of all nodes. */
extern struct device_node *of_allnodes;
extern struct device_node *of_chosen;
@@ -114,6 +112,7 @@ extern struct device_node *of_aliases;
extern struct device_node *of_stdout;
extern raw_spinlock_t devtree_lock;
+#ifdef CONFIG_OF
static inline bool of_have_populated_dt(void)
{
return of_allnodes != NULL;