summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev/sm501fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/fbdev/sm501fb.c')
-rw-r--r--drivers/video/fbdev/sm501fb.c105
1 files changed, 52 insertions, 53 deletions
diff --git a/drivers/video/fbdev/sm501fb.c b/drivers/video/fbdev/sm501fb.c
index 67e314fdd947..ed6f4f43e2d5 100644
--- a/drivers/video/fbdev/sm501fb.c
+++ b/drivers/video/fbdev/sm501fb.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
/* linux/drivers/video/sm501fb.c
*
* Copyright (c) 2006 Simtec Electronics
* Vincent Sanders <vince@simtec.co.uk>
* Ben Dooks <ben@simtec.co.uk>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
* Framebuffer driver for the Silicon Motion SM501
*/
@@ -30,6 +27,7 @@
#include <linux/clk.h>
#include <linux/console.h>
#include <linux/io.h>
+#include <linux/string_choices.h>
#include <linux/uaccess.h>
#include <asm/div64.h>
@@ -46,7 +44,7 @@
static char *fb_mode = "640x480-16@60";
static unsigned long default_bpp = 16;
-static struct fb_videomode sm501_default_mode = {
+static const struct fb_videomode sm501_default_mode = {
.refresh = 60,
.xres = 640,
.yres = 480,
@@ -329,6 +327,13 @@ static int sm501fb_check_var(struct fb_var_screeninfo *var,
if (var->xres_virtual > 4096 || var->yres_virtual > 2048)
return -EINVAL;
+ /* geometry sanity checks */
+ if (var->xres + var->xoffset > var->xres_virtual)
+ return -EINVAL;
+
+ if (var->yres + var->yoffset > var->yres_virtual)
+ return -EINVAL;
+
/* can cope with 8,16 or 32bpp */
if (var->bits_per_pixel <= 8)
@@ -1008,6 +1013,7 @@ static int sm501fb_blank_crt(int blank_mode, struct fb_info *info)
case FB_BLANK_POWERDOWN:
ctrl &= ~SM501_DC_CRT_CONTROL_ENABLE;
sm501_misc_control(fbi->dev->parent, SM501_MISC_DAC_POWER, 0);
+ fallthrough;
case FB_BLANK_NORMAL:
ctrl |= SM501_DC_CRT_CONTROL_BLANK;
@@ -1168,7 +1174,7 @@ static ssize_t sm501fb_crtsrc_show(struct device *dev,
ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
ctrl &= SM501_DC_CRT_CONTROL_SEL;
- return snprintf(buf, PAGE_SIZE, "%s\n", ctrl ? "crt" : "panel");
+ return sysfs_emit(buf, "%s\n", ctrl ? "crt" : "panel");
}
/* sm501fb_crtsrc_show
@@ -1273,6 +1279,14 @@ static ssize_t sm501fb_debug_show_pnl(struct device *dev,
static DEVICE_ATTR(fbregs_pnl, 0444, sm501fb_debug_show_pnl, NULL);
+static struct attribute *sm501fb_attrs[] = {
+ &dev_attr_crt_src.attr,
+ &dev_attr_fbregs_pnl.attr,
+ &dev_attr_fbregs_crt.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(sm501fb);
+
/* acceleration operations */
static int sm501fb_sync(struct fb_info *info)
{
@@ -1287,7 +1301,7 @@ static int sm501fb_sync(struct fb_info *info)
count--;
if (count <= 0) {
- dev_err(info->dev, "Timeout waiting for 2d engine sync\n");
+ fb_err(info, "Timeout waiting for 2d engine sync\n");
return 1;
}
return 0;
@@ -1446,6 +1460,7 @@ static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rec
static struct fb_ops sm501fb_ops_crt = {
.owner = THIS_MODULE,
+ __FB_DEFAULT_IOMEM_OPS_RDWR,
.fb_check_var = sm501fb_check_var_crt,
.fb_set_par = sm501fb_set_par_crt,
.fb_blank = sm501fb_blank_crt,
@@ -1456,10 +1471,12 @@ static struct fb_ops sm501fb_ops_crt = {
.fb_copyarea = sm501fb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_sync = sm501fb_sync,
+ __FB_DEFAULT_IOMEM_OPS_MMAP,
};
static struct fb_ops sm501fb_ops_pnl = {
.owner = THIS_MODULE,
+ __FB_DEFAULT_IOMEM_OPS_RDWR,
.fb_check_var = sm501fb_check_var_pnl,
.fb_set_par = sm501fb_set_par_pnl,
.fb_pan_display = sm501fb_pan_pnl,
@@ -1470,6 +1487,7 @@ static struct fb_ops sm501fb_ops_pnl = {
.fb_copyarea = sm501fb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_sync = sm501fb_sync,
+ __FB_DEFAULT_IOMEM_OPS_MMAP,
};
/* sm501_init_cursor
@@ -1702,8 +1720,8 @@ static int sm501fb_init_fb(struct fb_info *fb, enum sm501_controller head,
BUG();
}
- dev_info(info->dev, "fb %s %sabled at start\n",
- fbname, enable ? "en" : "dis");
+ dev_info(info->dev, "fb %s %s at start\n",
+ fbname, str_enabled_disabled(enable));
/* check to see if our routing allows this */
@@ -1713,7 +1731,7 @@ static int sm501fb_init_fb(struct fb_info *fb, enum sm501_controller head,
enable = 0;
}
- strlcpy(fb->fix.id, fbname, sizeof(fb->fix.id));
+ strscpy(fb->fix.id, fbname, sizeof(fb->fix.id));
memcpy(&par->ops,
(head == HEAD_CRT) ? &sm501fb_ops_crt : &sm501fb_ops_pnl,
@@ -1725,16 +1743,16 @@ static int sm501fb_init_fb(struct fb_info *fb, enum sm501_controller head,
par->ops.fb_cursor = NULL;
fb->fbops = &par->ops;
- fb->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST |
+ fb->flags = FBINFO_READS_FAST |
FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
#if defined(CONFIG_OF)
#ifdef __BIG_ENDIAN
- if (of_get_property(info->dev->parent->of_node, "little-endian", NULL))
+ if (of_property_read_bool(info->dev->parent->of_node, "little-endian"))
fb->flags |= FBINFO_FOREIGN_ENDIAN;
#else
- if (of_get_property(info->dev->parent->of_node, "big-endian", NULL))
+ if (of_property_read_bool(info->dev->parent->of_node, "big-endian"))
fb->flags |= FBINFO_FOREIGN_ENDIAN;
#endif
#endif
@@ -1867,10 +1885,8 @@ static int sm501fb_probe_one(struct sm501fb_info *info,
}
fbi = framebuffer_alloc(sizeof(struct sm501fb_par), info->dev);
- if (fbi == NULL) {
- dev_err(info->dev, "cannot allocate %s framebuffer\n", name);
+ if (!fbi)
return -ENOMEM;
- }
par = fbi->par;
par->info = info;
@@ -1889,6 +1905,9 @@ static void sm501_free_init_fb(struct sm501fb_info *info,
{
struct fb_info *fbi = info->fb[head];
+ if (!fbi)
+ return;
+
fb_dealloc_cmap(&fbi->cmap);
}
@@ -1928,8 +1947,7 @@ static int sm501fb_probe(struct platform_device *pdev)
int ret;
/* allocate our framebuffers */
-
- info = kzalloc(sizeof(struct sm501fb_info), GFP_KERNEL);
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
dev_err(dev, "failed to allocate state\n");
return -ENOMEM;
@@ -2013,33 +2031,9 @@ static int sm501fb_probe(struct platform_device *pdev)
goto err_started_crt;
}
- /* create device files */
-
- ret = device_create_file(dev, &dev_attr_crt_src);
- if (ret)
- goto err_started_panel;
-
- ret = device_create_file(dev, &dev_attr_fbregs_pnl);
- if (ret)
- goto err_attached_crtsrc_file;
-
- ret = device_create_file(dev, &dev_attr_fbregs_crt);
- if (ret)
- goto err_attached_pnlregs_file;
-
/* we registered, return ok */
return 0;
-err_attached_pnlregs_file:
- device_remove_file(dev, &dev_attr_fbregs_pnl);
-
-err_attached_crtsrc_file:
- device_remove_file(dev, &dev_attr_crt_src);
-
-err_started_panel:
- unregister_framebuffer(info->fb[HEAD_PANEL]);
- sm501_free_init_fb(info, HEAD_PANEL);
-
err_started_crt:
unregister_framebuffer(info->fb[HEAD_CRT]);
sm501_free_init_fb(info, HEAD_CRT);
@@ -2063,29 +2057,25 @@ err_alloc:
/*
* Cleanup
*/
-static int sm501fb_remove(struct platform_device *pdev)
+static void sm501fb_remove(struct platform_device *pdev)
{
struct sm501fb_info *info = platform_get_drvdata(pdev);
struct fb_info *fbinfo_crt = info->fb[0];
struct fb_info *fbinfo_pnl = info->fb[1];
- device_remove_file(&pdev->dev, &dev_attr_fbregs_crt);
- device_remove_file(&pdev->dev, &dev_attr_fbregs_pnl);
- device_remove_file(&pdev->dev, &dev_attr_crt_src);
-
sm501_free_init_fb(info, HEAD_CRT);
sm501_free_init_fb(info, HEAD_PANEL);
- unregister_framebuffer(fbinfo_crt);
- unregister_framebuffer(fbinfo_pnl);
+ if (fbinfo_crt)
+ unregister_framebuffer(fbinfo_crt);
+ if (fbinfo_pnl)
+ unregister_framebuffer(fbinfo_pnl);
sm501fb_stop(info);
kfree(info);
framebuffer_release(fbinfo_pnl);
framebuffer_release(fbinfo_crt);
-
- return 0;
}
#ifdef CONFIG_PM
@@ -2094,8 +2084,12 @@ static int sm501fb_suspend_fb(struct sm501fb_info *info,
enum sm501_controller head)
{
struct fb_info *fbi = info->fb[head];
- struct sm501fb_par *par = fbi->par;
+ struct sm501fb_par *par;
+ if (!fbi)
+ return 0;
+
+ par = fbi->par;
if (par->screen.size == 0)
return 0;
@@ -2141,8 +2135,12 @@ static void sm501fb_resume_fb(struct sm501fb_info *info,
enum sm501_controller head)
{
struct fb_info *fbi = info->fb[head];
- struct sm501fb_par *par = fbi->par;
+ struct sm501fb_par *par;
+ if (!fbi)
+ return;
+
+ par = fbi->par;
if (par->screen.size == 0)
return;
@@ -2226,6 +2224,7 @@ static struct platform_driver sm501fb_driver = {
.resume = sm501fb_resume,
.driver = {
.name = "sm501-fb",
+ .dev_groups = sm501fb_groups,
},
};