From 17f2e8e1dbe2cae66e99fd1a684db10bde792570 Mon Sep 17 00:00:00 2001 From: Dan Carpenter <dan.carpenter@oracle.com> Date: Sat, 30 Jan 2016 17:44:32 +0300 Subject: [PATCH 01/21] video: fbdev: metronomefb: two harmless off by one bugs par->metromem_cmd->args[] is an array of 31 elements of size u16. Here we have initialized the first "i" elements and want to set the rest to zero. The issue here is that ARRAY_SIZE(par->metromem_cmd->args) is 31 and not 32 as in the original code. It means that we set ->csum to zero, but that is harmless because we immediately set it to the correct value on the next line. Still, the buffer overflow upsets static checkers so let's correct the math. Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/metronomefb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/metronomefb.c b/drivers/video/fbdev/metronomefb.c index ad04a01e2761b..abb6bbf226d52 100644 --- a/drivers/video/fbdev/metronomefb.c +++ b/drivers/video/fbdev/metronomefb.c @@ -354,7 +354,8 @@ static int metronome_powerup_cmd(struct metronomefb_par *par) } /* the rest are 0 */ - memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2); + memset(&par->metromem_cmd->args[i], 0, + (ARRAY_SIZE(par->metromem_cmd->args) - i) * 2); par->metromem_cmd->csum = cs; @@ -376,7 +377,8 @@ static int metronome_config_cmd(struct metronomefb_par *par) memcpy(par->metromem_cmd->args, epd_frame_table[par->dt].config, sizeof(epd_frame_table[par->dt].config)); /* the rest are 0 */ - memset((u8 *) (par->metromem_cmd->args + 4), 0, (32-4)*2); + memset(&par->metromem_cmd->args[4], 0, + (ARRAY_SIZE(par->metromem_cmd->args) - 4) * 2); par->metromem_cmd->csum = 0xCC10; par->metromem_cmd->csum += calc_img_cksum(par->metromem_cmd->args, 4); From 206fc20598157ce15597822cf01b94377e30075b Mon Sep 17 00:00:00 2001 From: Daniel Wagner <daniel.wagner@bmw-carit.de> Date: Tue, 9 Feb 2016 10:18:32 +0100 Subject: [PATCH 02/21] video: Use bool instead int pointer for get_opt_bool() argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the function name already indicates that get_opt_bool() parses for a bool. It is not a surprise that compiler is complaining about it when -Werror=incompatible-pointer-types is used: drivers/video/fbdev/intelfb/intelfbdrv.c: In function ‘intelfb_setup’: drivers/video/fbdev/intelfb/intelfbdrv.c:353:39: error: passing argument 3 of ‘get_opt_bool’ from incompatible pointer type [-Werror=incompatible-pointer-types] if (get_opt_bool(this_opt, "accel", &accel)) Signed-off-by: Daniel Wagner <daniel.wagner@bmw-carit.de> Reported-by: Fengguang Wu <fengguang.wu@intel.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/intelfb/intelfbdrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/intelfb/intelfbdrv.c b/drivers/video/fbdev/intelfb/intelfbdrv.c index bbec737eef302..bf207444ba0c6 100644 --- a/drivers/video/fbdev/intelfb/intelfbdrv.c +++ b/drivers/video/fbdev/intelfb/intelfbdrv.c @@ -302,7 +302,7 @@ static __inline__ int get_opt_int(const char *this_opt, const char *name, } static __inline__ int get_opt_bool(const char *this_opt, const char *name, - int *ret) + bool *ret) { if (!ret) return 0; From f059c4b220b821f8ed7b1b12387cce86373f666e Mon Sep 17 00:00:00 2001 From: Andrzej Hajda <a.hajda@samsung.com> Date: Mon, 15 Feb 2016 15:35:24 +0100 Subject: [PATCH 03/21] fbdev: exynos: fix IS_ERR_VALUE usage IS_ERR_VALUE macro should be used only with unsigned long type. For signed types comparison 'ret < 0' should be used. The patch follows conclusion from discussion on LKML [1][2]. [1]: http://permalink.gmane.org/gmane.linux.kernel/2120927 [2]: http://permalink.gmane.org/gmane.linux.kernel/2150581 Signed-off-by: Andrzej Hajda <a.hajda@samsung.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/exynos/exynos_mipi_dsi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/exynos/exynos_mipi_dsi.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c index b527fe4646285..951b592794e34 100644 --- a/drivers/video/fbdev/exynos/exynos_mipi_dsi.c +++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c @@ -402,12 +402,12 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev) goto error; } - dsim->irq = platform_get_irq(pdev, 0); - if (IS_ERR_VALUE(dsim->irq)) { + ret = platform_get_irq(pdev, 0); + if (ret < 0) { dev_err(&pdev->dev, "failed to request dsim irq resource\n"); - ret = -EINVAL; goto error; } + dsim->irq = ret; init_completion(&dsim_wr_comp); init_completion(&dsim_rd_comp); From 7fdfc702d301a127d875e5608342a249201fdb4a Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee <sudipm.mukherjee@gmail.com> Date: Tue, 23 Feb 2016 18:14:17 +0530 Subject: [PATCH 04/21] fbdev: n411: check return value We were not checking the return value of platform_device_add_data() which can fail. Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/n411.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/n411.c b/drivers/video/fbdev/n411.c index 935830fea7b62..053deacad7cc1 100644 --- a/drivers/video/fbdev/n411.c +++ b/drivers/video/fbdev/n411.c @@ -165,16 +165,22 @@ static int __init n411_init(void) if (!n411_device) return -ENOMEM; - platform_device_add_data(n411_device, &n411_board, sizeof(n411_board)); + ret = platform_device_add_data(n411_device, &n411_board, + sizeof(n411_board)); + if (ret) + goto put_plat_device; /* this _add binds hecubafb to n411. hecubafb refcounts n411 */ ret = platform_device_add(n411_device); if (ret) - platform_device_put(n411_device); + goto put_plat_device; - return ret; + return 0; +put_plat_device: + platform_device_put(n411_device); + return ret; } static void __exit n411_exit(void) From 8b4c78a35adb19be89c9e8829074289e16d0bb4b Mon Sep 17 00:00:00 2001 From: Simon Horman <horms+renesas@verge.net.au> Date: Mon, 22 Feb 2016 10:59:51 +0900 Subject: [PATCH 05/21] fbdev: sh_mobile_lcdc: Use ARCH_RENESAS Make use of ARCH_RENESAS in place of ARCH_SHMOBILE. This is part of an ongoing process to migrate from ARCH_SHMOBILE to ARCH_RENESAS the motivation for which being that RENESAS seems to be a more appropriate name than SHMOBILE for the majority of Renesas ARM based SoCs. Signed-off-by: Simon Horman <horms+renesas@verge.net.au> Acked-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 8ea45a5cd806e..936ebd4bcf73e 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1985,7 +1985,7 @@ config FB_W100 config FB_SH_MOBILE_LCDC tristate "SuperH Mobile LCDC framebuffer support" - depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK + depends on FB && (SUPERH || ARCH_RENESAS) && HAVE_CLK depends on FB_SH_MOBILE_MERAM || !FB_SH_MOBILE_MERAM select FB_SYS_FILLRECT select FB_SYS_COPYAREA From af22f647b4a0b4a549ccbbc55a324edc54089564 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" <macro@linux-mips.org> Date: Mon, 22 Feb 2016 01:54:46 +0000 Subject: [PATCH 06/21] video: fbdev: pmag-ba-fb: Fix the lower margin size According to the board specification[1] the width of the vertical sync front porch is 12 pixels or the same as the width of the horizontal sync front porch. This in turn means the size of the lower margin is 0, because the vertical sync starts as soon as the start of the horizontal sync terminates the last line. References: [1] "PMAG-BA TURBOchannel Color Frame Buffer Functional Specification", Revision 1.2, Workstation Systems Engineering, Digital Equipment Corporation, August 27, 1990, Table 3-5: "Video Timing" Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/pmag-ba-fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/pmag-ba-fb.c b/drivers/video/fbdev/pmag-ba-fb.c index 914a52ba84776..5872bc4af3cee 100644 --- a/drivers/video/fbdev/pmag-ba-fb.c +++ b/drivers/video/fbdev/pmag-ba-fb.c @@ -60,7 +60,7 @@ static struct fb_var_screeninfo pmagbafb_defined = { .left_margin = 116, .right_margin = 12, .upper_margin = 34, - .lower_margin = 12, + .lower_margin = 0, .hsync_len = 128, .vsync_len = 3, .sync = FB_SYNC_ON_GREEN, From 90c83176e5cfa666bb2e7643d74ca87e08e171cb Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" <macro@linux-mips.org> Date: Mon, 22 Feb 2016 01:54:59 +0000 Subject: [PATCH 07/21] video: fbdev: pmag-aa-fb: Adapt to current APIs Rework the driver to use the current frambuffer and TURBOchannel APIs, including proper resource management and using the new framework for hardware cursor support. NB two Bt431 cursor generators are included onboard, both responding at the same TURBOchannel bus addresses and with their host data buses wired to byte lanes #0 and #1 respectively of the 32-bit bus. Therefore both can be accessed simultaneously with 16-bit data transfers. Cursor outputs of the chip wired to lane #0 drive the respective overlay select inputs of the Bt455 RAMDAC, whereas cursor outputs of the chip wired to lane #1 drive the respective P3 pixel select inputs of the RAMDAC. So 5 (out of 17) Bt455 color registers are usable with this board: palette entries #0 and #1 for frame buffer pixel data driven while neither cursor generator is active, palette entries #8 and #9 for frame buffer pixel data driven while cursor generator #1 is active only and the overlay entry while cursor generator #0 is active. Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/bt431.h | 41 ++- drivers/video/fbdev/pmag-aa-fb.c | 595 ++++++++++--------------------- 2 files changed, 215 insertions(+), 421 deletions(-) diff --git a/drivers/video/fbdev/bt431.h b/drivers/video/fbdev/bt431.h index 04e0cfbba5387..108fab39fd788 100644 --- a/drivers/video/fbdev/bt431.h +++ b/drivers/video/fbdev/bt431.h @@ -2,6 +2,7 @@ * linux/drivers/video/bt431.h * * Copyright 2003 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de> + * Copyright 2016 Maciej W. Rozycki <macro@linux-mips.org> * * This file is subject to the terms and conditions of the GNU General * Public License. See the file COPYING in the main directory of this @@ -9,6 +10,8 @@ */ #include <linux/types.h> +#define BT431_CURSOR_SIZE 64 + /* * Bt431 cursor generator registers, 32-bit aligned. * Two twin Bt431 are used on the DECstation's PMAG-AA. @@ -196,28 +199,30 @@ static inline void bt431_position_cursor(struct bt431_regs *regs, u16 x, u16 y) bt431_write_reg_inc(regs, (y >> 8) & 0x0f); /* BT431_REG_CYHI */ } -static inline void bt431_set_font(struct bt431_regs *regs, u8 fgc, - u16 width, u16 height) +static inline void bt431_set_cursor(struct bt431_regs *regs, + const char *data, const char *mask, + u16 rop, u16 width, u16 height) { + u16 x, y; int i; - u16 fgp = fgc ? 0xffff : 0x0000; - u16 bgp = fgc ? 0x0000 : 0xffff; + i = 0; + width = DIV_ROUND_UP(width, 8); bt431_select_reg(regs, BT431_REG_CRAM_BASE); - for (i = BT431_REG_CRAM_BASE; i <= BT431_REG_CRAM_END; i++) { - u16 value; - - if (height << 6 <= i << 3) - value = bgp; - else if (width <= i % 8 << 3) - value = bgp; - else if (((width >> 3) & 0xffff) > i % 8) - value = fgp; - else - value = fgp & ~(bgp << (width % 8 << 1)); - - bt431_write_cmap_inc(regs, value); - } + for (y = 0; y < BT431_CURSOR_SIZE; y++) + for (x = 0; x < BT431_CURSOR_SIZE / 8; x++) { + u16 val = 0; + + if (y < height && x < width) { + val = mask[i]; + if (rop == ROP_XOR) + val = (val << 8) | (val ^ data[i]); + else + val = (val << 8) | (val & data[i]); + i++; + } + bt431_write_cmap_inc(regs, val); + } } static inline void bt431_init_cursor(struct bt431_regs *regs) diff --git a/drivers/video/fbdev/pmag-aa-fb.c b/drivers/video/fbdev/pmag-aa-fb.c index 838424817de23..3920b4ec8fc41 100644 --- a/drivers/video/fbdev/pmag-aa-fb.c +++ b/drivers/video/fbdev/pmag-aa-fb.c @@ -8,6 +8,7 @@ * and Harald Koerfgen <hkoerfg@web.de>, which itself is derived from * "HP300 Topcat framebuffer support (derived from macfb of all things) * Phil Blundell <philb@gnu.org> 1998" + * Copyright (c) 2016 Maciej W. Rozycki * * This file is subject to the terms and conditions of the GNU General * Public License. See the file COPYING in the main directory of this @@ -21,37 +22,29 @@ * * 2003-09-21 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de> * Hardware cursor support. + * + * 2016-02-21 Maciej W. Rozycki <macro@linux-mips.org> + * Version 0.03: Rewritten for the new FB and TC APIs. */ -#include <linux/module.h> -#include <linux/kernel.h> + +#include <linux/compiler.h> #include <linux/errno.h> -#include <linux/string.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/delay.h> -#include <linux/init.h> #include <linux/fb.h> -#include <linux/console.h> - -#include <asm/bootinfo.h> -#include <asm/dec/machtype.h> -#include <asm/dec/tc.h> - -#include <video/fbcon.h> -#include <video/fbcon-cfb8.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/tc.h> +#include <linux/timer.h> #include "bt455.h" #include "bt431.h" /* Version information */ -#define DRIVER_VERSION "0.02" +#define DRIVER_VERSION "0.03" #define DRIVER_AUTHOR "Karsten Merker <merker@linuxtag.org>" #define DRIVER_DESCRIPTION "PMAG-AA Framebuffer Driver" -/* Prototypes */ -static int aafb_set_var(struct fb_var_screeninfo *var, int con, - struct fb_info *info); - /* * Bt455 RAM DAC register base offset (rel. to TC slot base address). */ @@ -68,443 +61,239 @@ static int aafb_set_var(struct fb_var_screeninfo *var, int con, */ #define PMAG_AA_ONBOARD_FBMEM_OFFSET 0x200000 -struct aafb_cursor { - struct timer_list timer; - int enable; - int on; - int vbl_cnt; - int blink_rate; - u16 x, y, width, height; +struct aafb_par { + void __iomem *mmio; + struct bt455_regs __iomem *bt455; + struct bt431_regs __iomem *bt431; }; -#define CURSOR_TIMER_FREQ (HZ / 50) -#define CURSOR_BLINK_RATE (20) -#define CURSOR_DRAW_DELAY (2) - -struct aafb_info { - struct fb_info info; - struct display disp; - struct aafb_cursor cursor; - struct bt455_regs *bt455; - struct bt431_regs *bt431; - unsigned long fb_start; - unsigned long fb_size; - unsigned long fb_line_length; +static struct fb_var_screeninfo aafb_defined = { + .xres = 1280, + .yres = 1024, + .xres_virtual = 2048, + .yres_virtual = 1024, + .bits_per_pixel = 8, + .grayscale = 1, + .red.length = 0, + .green.length = 1, + .blue.length = 0, + .activate = FB_ACTIVATE_NOW, + .accel_flags = FB_ACCEL_NONE, + .sync = FB_SYNC_ON_GREEN, + .vmode = FB_VMODE_NONINTERLACED, }; -/* - * Max 3 TURBOchannel slots -> max 3 PMAG-AA. - */ -static struct aafb_info my_fb_info[3]; - -static struct aafb_par { -} current_par; - -static int currcon = -1; - -static void aafb_set_cursor(struct aafb_info *info, int on) -{ - struct aafb_cursor *c = &info->cursor; - - if (on) { - bt431_position_cursor(info->bt431, c->x, c->y); - bt431_enable_cursor(info->bt431); - } else - bt431_erase_cursor(info->bt431); -} - -static void aafbcon_cursor(struct display *disp, int mode, int x, int y) -{ - struct aafb_info *info = (struct aafb_info *)disp->fb_info; - struct aafb_cursor *c = &info->cursor; - - x *= fontwidth(disp); - y *= fontheight(disp); - - if (c->x == x && c->y == y && (mode == CM_ERASE) == !c->enable) - return; - - c->enable = 0; - if (c->on) - aafb_set_cursor(info, 0); - c->x = x - disp->var.xoffset; - c->y = y - disp->var.yoffset; - - switch (mode) { - case CM_ERASE: - c->on = 0; - break; - case CM_DRAW: - case CM_MOVE: - if (c->on) - aafb_set_cursor(info, c->on); - else - c->vbl_cnt = CURSOR_DRAW_DELAY; - c->enable = 1; - break; - } -} +static struct fb_fix_screeninfo aafb_fix = { + .id = "PMAG-AA", + .smem_len = (2048 * 1024), + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_MONO10, + .ypanstep = 1, + .ywrapstep = 1, + .line_length = 2048, + .mmio_len = PMAG_AA_ONBOARD_FBMEM_OFFSET - PMAG_AA_BT455_OFFSET, +}; -static int aafbcon_set_font(struct display *disp, int width, int height) +static int aafb_cursor(struct fb_info *info, struct fb_cursor *cursor) { - struct aafb_info *info = (struct aafb_info *)disp->fb_info; - struct aafb_cursor *c = &info->cursor; - u8 fgc = ~attr_bgcol_ec(disp, disp->conp, &info->info); + struct aafb_par *par = info->par; - if (width > 64 || height > 64 || width < 0 || height < 0) + if (cursor->image.height > BT431_CURSOR_SIZE || + cursor->image.width > BT431_CURSOR_SIZE) { + bt431_erase_cursor(par->bt431); return -EINVAL; - - c->height = height; - c->width = width; - - bt431_set_font(info->bt431, fgc, width, height); - - return 1; -} - -static void aafb_cursor_timer_handler(unsigned long data) -{ - struct aafb_info *info = (struct aafb_info *)data; - struct aafb_cursor *c = &info->cursor; - - if (!c->enable) - goto out; - - if (c->vbl_cnt && --c->vbl_cnt == 0) { - c->on ^= 1; - aafb_set_cursor(info, c->on); - c->vbl_cnt = c->blink_rate; } -out: - c->timer.expires = jiffies + CURSOR_TIMER_FREQ; - add_timer(&c->timer); -} - -static void __init aafb_cursor_init(struct aafb_info *info) -{ - struct aafb_cursor *c = &info->cursor; - - c->enable = 1; - c->on = 1; - c->x = c->y = 0; - c->width = c->height = 0; - c->vbl_cnt = CURSOR_DRAW_DELAY; - c->blink_rate = CURSOR_BLINK_RATE; - - init_timer(&c->timer); - c->timer.data = (unsigned long)info; - c->timer.function = aafb_cursor_timer_handler; - mod_timer(&c->timer, jiffies + CURSOR_TIMER_FREQ); -} - -static void __exit aafb_cursor_exit(struct aafb_info *info) -{ - struct aafb_cursor *c = &info->cursor; - - del_timer_sync(&c->timer); -} - -static struct display_switch aafb_switch8 = { - .setup = fbcon_cfb8_setup, - .bmove = fbcon_cfb8_bmove, - .clear = fbcon_cfb8_clear, - .putc = fbcon_cfb8_putc, - .putcs = fbcon_cfb8_putcs, - .revc = fbcon_cfb8_revc, - .cursor = aafbcon_cursor, - .set_font = aafbcon_set_font, - .clear_margins = fbcon_cfb8_clear_margins, - .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) -}; - -static void aafb_get_par(struct aafb_par *par) -{ - *par = current_par; -} - -static int aafb_get_fix(struct fb_fix_screeninfo *fix, int con, - struct fb_info *info) -{ - struct aafb_info *ip = (struct aafb_info *)info; - - memset(fix, 0, sizeof(struct fb_fix_screeninfo)); - strcpy(fix->id, "PMAG-AA"); - fix->smem_start = ip->fb_start; - fix->smem_len = ip->fb_size; - fix->type = FB_TYPE_PACKED_PIXELS; - fix->ypanstep = 1; - fix->ywrapstep = 1; - fix->visual = FB_VISUAL_MONO10; - fix->line_length = 1280; - fix->accel = FB_ACCEL_NONE; + if (!cursor->enable) + bt431_erase_cursor(par->bt431); - return 0; -} + if (cursor->set & FB_CUR_SETPOS) + bt431_position_cursor(par->bt431, + cursor->image.dx, cursor->image.dy); + if (cursor->set & FB_CUR_SETCMAP) { + u8 fg = cursor->image.fg_color ? 0xf : 0x0; + u8 bg = cursor->image.bg_color ? 0xf : 0x0; -static void aafb_set_disp(struct display *disp, int con, - struct aafb_info *info) -{ - struct fb_fix_screeninfo fix; - - disp->fb_info = &info->info; - aafb_set_var(&disp->var, con, &info->info); - if (disp->conp && disp->conp->vc_sw && disp->conp->vc_sw->con_cursor) - disp->conp->vc_sw->con_cursor(disp->conp, CM_ERASE); - disp->dispsw = &aafb_switch8; - disp->dispsw_data = 0; - - aafb_get_fix(&fix, con, &info->info); - disp->screen_base = (u8 *) fix.smem_start; - disp->visual = fix.visual; - disp->type = fix.type; - disp->type_aux = fix.type_aux; - disp->ypanstep = fix.ypanstep; - disp->ywrapstep = fix.ywrapstep; - disp->line_length = fix.line_length; - disp->next_line = 2048; - disp->can_soft_blank = 1; - disp->inverse = 0; - disp->scrollmode = SCROLL_YREDRAW; - - aafbcon_set_font(disp, fontwidth(disp), fontheight(disp)); -} + bt455_write_cmap_entry(par->bt455, 8, 0, bg, 0); + bt455_write_cmap_entry(par->bt455, 9, 0, bg, 0); + bt455_write_ovly_entry(par->bt455, 0, 0, fg, 0); + } + if (cursor->set & (FB_CUR_SETSIZE | FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) + bt431_set_cursor(par->bt431, + cursor->image.data, cursor->mask, cursor->rop, + cursor->image.width, cursor->image.height); -static int aafb_get_cmap(struct fb_cmap *cmap, int kspc, int con, - struct fb_info *info) -{ - static u16 color[2] = {0x0000, 0x000f}; - static struct fb_cmap aafb_cmap = {0, 2, color, color, color, NULL}; + if (cursor->enable) + bt431_enable_cursor(par->bt431); - fb_copy_cmap(&aafb_cmap, cmap, kspc ? 0 : 2); return 0; } -static int aafb_set_cmap(struct fb_cmap *cmap, int kspc, int con, - struct fb_info *info) -{ - u16 color[2] = {0x0000, 0x000f}; - - if (cmap->start == 0 - && cmap->len == 2 - && memcmp(cmap->red, color, sizeof(color)) == 0 - && memcmp(cmap->green, color, sizeof(color)) == 0 - && memcmp(cmap->blue, color, sizeof(color)) == 0 - && cmap->transp == NULL) - return 0; - else - return -EINVAL; -} - -static int aafb_ioctl(struct fb_info *info, u32 cmd, unsigned long arg) -{ - /* TODO: Not yet implemented */ - return -ENOIOCTLCMD; -} +/* 0 unblanks, any other blanks. */ -static int aafb_switch(int con, struct fb_info *info) +static int aafb_blank(int blank, struct fb_info *info) { - struct aafb_info *ip = (struct aafb_info *)info; - struct display *old = (currcon < 0) ? &ip->disp : (fb_display + currcon); - struct display *new = (con < 0) ? &ip->disp : (fb_display + con); - - if (old->conp && old->conp->vc_sw && old->conp->vc_sw->con_cursor) - old->conp->vc_sw->con_cursor(old->conp, CM_ERASE); - - /* Set the current console. */ - currcon = con; - aafb_set_disp(new, con, ip); + struct aafb_par *par = info->par; + u8 val = blank ? 0x00 : 0x0f; + bt455_write_cmap_entry(par->bt455, 1, val, val, val); return 0; } -static void aafb_encode_var(struct fb_var_screeninfo *var, - struct aafb_par *par) -{ - var->xres = 1280; - var->yres = 1024; - var->xres_virtual = 2048; - var->yres_virtual = 1024; - var->xoffset = 0; - var->yoffset = 0; - var->bits_per_pixel = 8; - var->grayscale = 1; - var->red.offset = 0; - var->red.length = 0; - var->red.msb_right = 0; - var->green.offset = 0; - var->green.length = 1; - var->green.msb_right = 0; - var->blue.offset = 0; - var->blue.length = 0; - var->blue.msb_right = 0; - var->transp.offset = 0; - var->transp.length = 0; - var->transp.msb_right = 0; - var->nonstd = 0; - var->activate &= ~FB_ACTIVATE_MASK & FB_ACTIVATE_NOW; - var->accel_flags = 0; - var->sync = FB_SYNC_ON_GREEN; - var->vmode &= ~FB_VMODE_MASK & FB_VMODE_NONINTERLACED; -} +static struct fb_ops aafb_ops = { + .owner = THIS_MODULE, + .fb_blank = aafb_blank, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_cursor = aafb_cursor, +}; -static int aafb_get_var(struct fb_var_screeninfo *var, int con, - struct fb_info *info) +static int pmagaafb_probe(struct device *dev) { - if (con < 0) { - struct aafb_par par; - - memset(var, 0, sizeof(struct fb_var_screeninfo)); - aafb_get_par(&par); - aafb_encode_var(var, &par); - } else - *var = info->var; + struct tc_dev *tdev = to_tc_dev(dev); + resource_size_t start, len; + struct fb_info *info; + struct aafb_par *par; + int err; + + info = framebuffer_alloc(sizeof(struct aafb_par), dev); + if (!info) { + printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev)); + return -ENOMEM; + } - return 0; -} + par = info->par; + dev_set_drvdata(dev, info); + + info->fbops = &aafb_ops; + info->fix = aafb_fix; + info->var = aafb_defined; + info->flags = FBINFO_DEFAULT; + + /* Request the I/O MEM resource. */ + start = tdev->resource.start; + len = tdev->resource.end - start + 1; + if (!request_mem_region(start, len, dev_name(dev))) { + printk(KERN_ERR "%s: Cannot reserve FB region\n", + dev_name(dev)); + err = -EBUSY; + goto err_alloc; + } -static int aafb_set_var(struct fb_var_screeninfo *var, int con, - struct fb_info *info) -{ - struct aafb_par par; + /* MMIO mapping setup. */ + info->fix.mmio_start = start + PMAG_AA_BT455_OFFSET; + par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); + if (!par->mmio) { + printk(KERN_ERR "%s: Cannot map MMIO\n", dev_name(dev)); + err = -ENOMEM; + goto err_resource; + } + par->bt455 = par->mmio - PMAG_AA_BT455_OFFSET + PMAG_AA_BT455_OFFSET; + par->bt431 = par->mmio - PMAG_AA_BT455_OFFSET + PMAG_AA_BT431_OFFSET; + + /* Frame buffer mapping setup. */ + info->fix.smem_start = start + PMAG_AA_ONBOARD_FBMEM_OFFSET; + info->screen_base = ioremap_nocache(info->fix.smem_start, + info->fix.smem_len); + if (!info->screen_base) { + printk(KERN_ERR "%s: Cannot map FB\n", dev_name(dev)); + err = -ENOMEM; + goto err_mmio_map; + } + info->screen_size = info->fix.smem_len; - aafb_get_par(&par); - aafb_encode_var(var, &par); - info->var = *var; + /* Init colormap. */ + bt455_write_cmap_entry(par->bt455, 0, 0x00, 0x00, 0x00); + bt455_write_cmap_entry(par->bt455, 1, 0x0f, 0x0f, 0x0f); - return 0; -} + /* Init hardware cursor. */ + bt431_erase_cursor(par->bt431); + bt431_init_cursor(par->bt431); + + err = register_framebuffer(info); + if (err < 0) { + printk(KERN_ERR "%s: Cannot register framebuffer\n", + dev_name(dev)); + goto err_smem_map; + } -static int aafb_update_var(int con, struct fb_info *info) -{ - struct aafb_info *ip = (struct aafb_info *)info; - struct display *disp = (con < 0) ? &ip->disp : (fb_display + con); + get_device(dev); - if (con == currcon) - aafbcon_cursor(disp, CM_ERASE, ip->cursor.x, ip->cursor.y); + pr_info("fb%d: %s frame buffer device at %s\n", + info->node, info->fix.id, dev_name(dev)); return 0; -} -/* 0 unblanks, any other blanks. */ -static void aafb_blank(int blank, struct fb_info *info) -{ - struct aafb_info *ip = (struct aafb_info *)info; - u8 val = blank ? 0x00 : 0x0f; +err_smem_map: + iounmap(info->screen_base); - bt455_write_cmap_entry(ip->bt455, 1, val, val, val); - aafbcon_cursor(&ip->disp, CM_ERASE, ip->cursor.x, ip->cursor.y); -} +err_mmio_map: + iounmap(par->mmio); -static struct fb_ops aafb_ops = { - .owner = THIS_MODULE, - .fb_get_fix = aafb_get_fix, - .fb_get_var = aafb_get_var, - .fb_set_var = aafb_set_var, - .fb_get_cmap = aafb_get_cmap, - .fb_set_cmap = aafb_set_cmap, - .fb_ioctl = aafb_ioctl -}; +err_resource: + release_mem_region(start, len); -static int __init init_one(int slot) -{ - unsigned long base_addr = CKSEG1ADDR(get_tc_base_addr(slot)); - struct aafb_info *ip = &my_fb_info[slot]; - - memset(ip, 0, sizeof(struct aafb_info)); - - /* - * Framebuffer display memory base address and friends. - */ - ip->bt455 = (struct bt455_regs *) (base_addr + PMAG_AA_BT455_OFFSET); - ip->bt431 = (struct bt431_regs *) (base_addr + PMAG_AA_BT431_OFFSET); - ip->fb_start = base_addr + PMAG_AA_ONBOARD_FBMEM_OFFSET; - ip->fb_size = 2048 * 1024; /* fb_fix_screeninfo.smem_length - seems to be physical */ - ip->fb_line_length = 2048; - - /* - * Let there be consoles.. - */ - strcpy(ip->info.modename, "PMAG-AA"); - ip->info.node = -1; - ip->info.flags = FBINFO_FLAG_DEFAULT; - ip->info.fbops = &aafb_ops; - ip->info.disp = &ip->disp; - ip->info.changevar = NULL; - ip->info.switch_con = &aafb_switch; - ip->info.updatevar = &aafb_update_var; - ip->info.blank = &aafb_blank; - - aafb_set_disp(&ip->disp, currcon, ip); - - /* - * Configure the RAM DACs. - */ - bt455_erase_cursor(ip->bt455); - - /* Init colormap. */ - bt455_write_cmap_entry(ip->bt455, 0, 0x00, 0x00, 0x00); - bt455_write_cmap_entry(ip->bt455, 1, 0x0f, 0x0f, 0x0f); - - /* Init hardware cursor. */ - bt431_init_cursor(ip->bt431); - aafb_cursor_init(ip); - - /* Clear the screen. */ - memset ((void *)ip->fb_start, 0, ip->fb_size); - - if (register_framebuffer(&ip->info) < 0) - return -EINVAL; - - printk(KERN_INFO "fb%d: %s frame buffer in TC slot %d\n", - GET_FB_IDX(ip->info.node), ip->info.modename, slot); - - return 0; +err_alloc: + framebuffer_release(info); + return err; } -static int __exit exit_one(int slot) +static int __exit pmagaafb_remove(struct device *dev) { - struct aafb_info *ip = &my_fb_info[slot]; - - if (unregister_framebuffer(&ip->info) < 0) - return -EINVAL; - + struct tc_dev *tdev = to_tc_dev(dev); + struct fb_info *info = dev_get_drvdata(dev); + struct aafb_par *par = info->par; + resource_size_t start, len; + + put_device(dev); + unregister_framebuffer(info); + iounmap(info->screen_base); + iounmap(par->mmio); + start = tdev->resource.start; + len = tdev->resource.end - start + 1; + release_mem_region(start, len); + framebuffer_release(info); return 0; } /* * Initialise the framebuffer. */ -int __init pmagaafb_init(void) -{ - int sid; - int found = 0; - - while ((sid = search_tc_card("PMAG-AA")) >= 0) { - found = 1; - claim_tc_card(sid); - init_one(sid); - } +static const struct tc_device_id pmagaafb_tc_table[] = { + { "DEC ", "PMAG-AA " }, + { } +}; +MODULE_DEVICE_TABLE(tc, pmagaafb_tc_table); + +static struct tc_driver pmagaafb_driver = { + .id_table = pmagaafb_tc_table, + .driver = { + .name = "pmagaafb", + .bus = &tc_bus_type, + .probe = pmagaafb_probe, + .remove = __exit_p(pmagaafb_remove), + }, +}; - return found ? 0 : -ENXIO; +static int __init pmagaafb_init(void) +{ +#ifndef MODULE + if (fb_get_options("pmagaafb", NULL)) + return -ENXIO; +#endif + return tc_register_driver(&pmagaafb_driver); } static void __exit pmagaafb_exit(void) { - int sid; - - while ((sid = search_tc_card("PMAG-AA")) >= 0) { - exit_one(sid); - release_tc_card(sid); - } + tc_unregister_driver(&pmagaafb_driver); } +module_init(pmagaafb_init); +module_exit(pmagaafb_exit); + MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESCRIPTION); MODULE_LICENSE("GPL"); -#ifdef MODULE -module_init(pmagaafb_init); -module_exit(pmagaafb_exit); -#endif From 60821fec1c8c1e703d350a09a201a86b88e30e34 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" <macro@linux-mips.org> Date: Mon, 22 Feb 2016 01:55:07 +0000 Subject: [PATCH 08/21] video: fbdev: pmag-aa-fb: Enable building as a module With the current TURBOchannel API support is automagical. Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 936ebd4bcf73e..18f1853529fc0 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1808,8 +1808,8 @@ config FB_HIT frame buffer card. config FB_PMAG_AA - bool "PMAG-AA TURBOchannel framebuffer support" - depends on (FB = y) && TC + tristate "PMAG-AA TURBOchannel framebuffer support" + depends on FB && TC select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT From df0821043f05cef211db34fca25a218f8c6b4b48 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" <macro@linux-mips.org> Date: Mon, 22 Feb 2016 01:55:12 +0000 Subject: [PATCH 09/21] video: fbdev: pmag-aa-fb: Report video timings The board uses hardwired timings compatible with 72Hz DEC VR319-DA and VRM17-AA monitors, according to the board owner's manual[1]. These timings are accordingly taken from the VR319 manual[2]. References: [1] "The Monochrome Frame Buffer TURBOchannel Module", Digital Equipment Corporation, Order Number: EK-MFBOM-TC-001, December 1991 [2] "Installing and Using the VR319 Monochrome Monitor", Digital Equipment Corporation, Order Number: EK-VR319-IN-001, First Edition, January 1990, Table 6-1 "Video Timing--1280 x 1024 Resolution" Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/pmag-aa-fb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/video/fbdev/pmag-aa-fb.c b/drivers/video/fbdev/pmag-aa-fb.c index 3920b4ec8fc41..def86f7d412f7 100644 --- a/drivers/video/fbdev/pmag-aa-fb.c +++ b/drivers/video/fbdev/pmag-aa-fb.c @@ -79,6 +79,13 @@ static struct fb_var_screeninfo aafb_defined = { .blue.length = 0, .activate = FB_ACTIVATE_NOW, .accel_flags = FB_ACCEL_NONE, + .pixclock = 7645, + .left_margin = 224, + .right_margin = 32, + .upper_margin = 33, + .lower_margin = 3, + .hsync_len = 160, + .vsync_len = 3, .sync = FB_SYNC_ON_GREEN, .vmode = FB_VMODE_NONINTERLACED, }; From e26d682e929d2e4141a4e08d7acc320896289b62 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" <macro@linux-mips.org> Date: Mon, 22 Feb 2016 01:55:17 +0000 Subject: [PATCH 10/21] video: fbdev: bt455: Remove unneeded colormap helpers for cursor support Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/bt455.h | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/drivers/video/fbdev/bt455.h b/drivers/video/fbdev/bt455.h index 80f61b03e9ae1..9d584f99867b5 100644 --- a/drivers/video/fbdev/bt455.h +++ b/drivers/video/fbdev/bt455.h @@ -67,28 +67,3 @@ static inline void bt455_write_ovly_entry(struct bt455_regs *regs, int cr, wmb(); regs->addr_ovly = blue & 0x0f; } - -static inline void bt455_set_cursor(struct bt455_regs *regs) -{ - mb(); - regs->addr_ovly = 0x0f; - wmb(); - regs->addr_ovly = 0x0f; - wmb(); - regs->addr_ovly = 0x0f; -} - -static inline void bt455_erase_cursor(struct bt455_regs *regs) -{ - /* bt455_write_cmap_entry(regs, 8, 0x00, 0x00, 0x00); */ - /* bt455_write_cmap_entry(regs, 9, 0x00, 0x00, 0x00); */ - bt455_write_ovly_entry(regs, 8, 0x03, 0x03, 0x03); - bt455_write_ovly_entry(regs, 9, 0x07, 0x07, 0x07); - - wmb(); - regs->addr_ovly = 0x09; - wmb(); - regs->addr_ovly = 0x09; - wmb(); - regs->addr_ovly = 0x09; -} From 01ac59c34420d5807724a5bb21c1464e6dfb7a92 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" <macro@linux-mips.org> Date: Mon, 22 Feb 2016 01:55:21 +0000 Subject: [PATCH 11/21] video: fbdev: pmag-ba-fb: Fix and rework Bt455 colormap handling The Bt455 is a greyscale RAMDAC, using the green color palette entries only while still providing registers for the red and blue components, all the three of which have to be loaded on palette updates. Chip documentation [1] mandates that the unused red and blue registers are written with 0. Therefore update code to follow this requirement and given that it makes the red and blue components unusable remove them from internal API calls altogether. References: [1] "Bt454 Bt455 170 MHz Monolithic CMOS 16 Color Palette RAMDAC", Brooktree Corporation, Document Number: L454001, Rev. I Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/bt455.h | 31 ++++++++++++++++--------------- drivers/video/fbdev/pmag-aa-fb.c | 12 ++++++------ 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/drivers/video/fbdev/bt455.h b/drivers/video/fbdev/bt455.h index 9d584f99867b5..a4bba5a49d774 100644 --- a/drivers/video/fbdev/bt455.h +++ b/drivers/video/fbdev/bt455.h @@ -2,6 +2,7 @@ * linux/drivers/video/bt455.h * * Copyright 2003 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de> + * Copyright 2016 Maciej W. Rozycki <macro@linux-mips.org> * * This file is subject to the terms and conditions of the GNU General * Public License. See the file COPYING in the main directory of this @@ -32,38 +33,38 @@ static inline void bt455_select_reg(struct bt455_regs *regs, int ir) /* * Read/write to a Bt455 color map register. */ -static inline void bt455_read_cmap_entry(struct bt455_regs *regs, int cr, - u8* red, u8* green, u8* blue) +static inline void bt455_read_cmap_entry(struct bt455_regs *regs, + int cr, u8 *grey) { bt455_select_reg(regs, cr); mb(); - *red = regs->addr_cmap_data & 0x0f; + regs->addr_cmap_data; rmb(); - *green = regs->addr_cmap_data & 0x0f; + *grey = regs->addr_cmap_data & 0xf; rmb(); - *blue = regs->addr_cmap_data & 0x0f; + regs->addr_cmap_data; } -static inline void bt455_write_cmap_entry(struct bt455_regs *regs, int cr, - u8 red, u8 green, u8 blue) +static inline void bt455_write_cmap_entry(struct bt455_regs *regs, + int cr, u8 grey) { bt455_select_reg(regs, cr); wmb(); - regs->addr_cmap_data = red & 0x0f; + regs->addr_cmap_data = 0x0; wmb(); - regs->addr_cmap_data = green & 0x0f; + regs->addr_cmap_data = grey & 0xf; wmb(); - regs->addr_cmap_data = blue & 0x0f; + regs->addr_cmap_data = 0x0; } -static inline void bt455_write_ovly_entry(struct bt455_regs *regs, int cr, - u8 red, u8 green, u8 blue) +static inline void bt455_write_ovly_entry(struct bt455_regs *regs, + int cr, u8 grey) { bt455_select_reg(regs, cr); wmb(); - regs->addr_ovly = red & 0x0f; + regs->addr_ovly = 0x0; wmb(); - regs->addr_ovly = green & 0x0f; + regs->addr_ovly = grey & 0xf; wmb(); - regs->addr_ovly = blue & 0x0f; + regs->addr_ovly = 0x0; } diff --git a/drivers/video/fbdev/pmag-aa-fb.c b/drivers/video/fbdev/pmag-aa-fb.c index def86f7d412f7..6f4466c39529f 100644 --- a/drivers/video/fbdev/pmag-aa-fb.c +++ b/drivers/video/fbdev/pmag-aa-fb.c @@ -121,9 +121,9 @@ static int aafb_cursor(struct fb_info *info, struct fb_cursor *cursor) u8 fg = cursor->image.fg_color ? 0xf : 0x0; u8 bg = cursor->image.bg_color ? 0xf : 0x0; - bt455_write_cmap_entry(par->bt455, 8, 0, bg, 0); - bt455_write_cmap_entry(par->bt455, 9, 0, bg, 0); - bt455_write_ovly_entry(par->bt455, 0, 0, fg, 0); + bt455_write_cmap_entry(par->bt455, 8, bg); + bt455_write_cmap_entry(par->bt455, 9, bg); + bt455_write_ovly_entry(par->bt455, 0, fg); } if (cursor->set & (FB_CUR_SETSIZE | FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) bt431_set_cursor(par->bt431, @@ -143,7 +143,7 @@ static int aafb_blank(int blank, struct fb_info *info) struct aafb_par *par = info->par; u8 val = blank ? 0x00 : 0x0f; - bt455_write_cmap_entry(par->bt455, 1, val, val, val); + bt455_write_cmap_entry(par->bt455, 1, val); return 0; } @@ -211,8 +211,8 @@ static int pmagaafb_probe(struct device *dev) info->screen_size = info->fix.smem_len; /* Init colormap. */ - bt455_write_cmap_entry(par->bt455, 0, 0x00, 0x00, 0x00); - bt455_write_cmap_entry(par->bt455, 1, 0x0f, 0x0f, 0x0f); + bt455_write_cmap_entry(par->bt455, 0, 0x0); + bt455_write_cmap_entry(par->bt455, 1, 0xf); /* Init hardware cursor. */ bt431_erase_cursor(par->bt431); From 5832706e8b50bab3fce1b4bad62b356554b851e4 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" <macro@linux-mips.org> Date: Mon, 22 Feb 2016 01:55:27 +0000 Subject: [PATCH 12/21] video: fbdev: pmag-ba-fb: Optimize Bt455 colormap addressing Use the address autoincrement feature when accessing successive palette entries and also skip loading a palette address in overlay register assesses which do not use that address. Provide a red/green/blue register sequencer reset helper for use in overlay register assesses where the state of the sequencer is not known. References: [1] "Bt454 Bt455 170 MHz Monolithic CMOS 16 Color Palette RAMDAC", Brooktree Corporation, Document Number: L454001, Rev. I Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/bt455.h | 38 ++++++++++++++++++++++++-------- drivers/video/fbdev/pmag-aa-fb.c | 6 ++--- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/drivers/video/fbdev/bt455.h b/drivers/video/fbdev/bt455.h index a4bba5a49d774..dd1404b40611d 100644 --- a/drivers/video/fbdev/bt455.h +++ b/drivers/video/fbdev/bt455.h @@ -30,13 +30,17 @@ static inline void bt455_select_reg(struct bt455_regs *regs, int ir) regs->addr_cmap = ir & 0x0f; } +static inline void bt455_reset_reg(struct bt455_regs *regs) +{ + mb(); + regs->addr_clr = 0; +} + /* * Read/write to a Bt455 color map register. */ -static inline void bt455_read_cmap_entry(struct bt455_regs *regs, - int cr, u8 *grey) +static inline void bt455_read_cmap_next(struct bt455_regs *regs, u8 *grey) { - bt455_select_reg(regs, cr); mb(); regs->addr_cmap_data; rmb(); @@ -45,10 +49,8 @@ static inline void bt455_read_cmap_entry(struct bt455_regs *regs, regs->addr_cmap_data; } -static inline void bt455_write_cmap_entry(struct bt455_regs *regs, - int cr, u8 grey) +static inline void bt455_write_cmap_next(struct bt455_regs *regs, u8 grey) { - bt455_select_reg(regs, cr); wmb(); regs->addr_cmap_data = 0x0; wmb(); @@ -57,10 +59,8 @@ static inline void bt455_write_cmap_entry(struct bt455_regs *regs, regs->addr_cmap_data = 0x0; } -static inline void bt455_write_ovly_entry(struct bt455_regs *regs, - int cr, u8 grey) +static inline void bt455_write_ovly_next(struct bt455_regs *regs, u8 grey) { - bt455_select_reg(regs, cr); wmb(); regs->addr_ovly = 0x0; wmb(); @@ -68,3 +68,23 @@ static inline void bt455_write_ovly_entry(struct bt455_regs *regs, wmb(); regs->addr_ovly = 0x0; } + +static inline void bt455_read_cmap_entry(struct bt455_regs *regs, + int cr, u8 *grey) +{ + bt455_select_reg(regs, cr); + bt455_read_cmap_next(regs, grey); +} + +static inline void bt455_write_cmap_entry(struct bt455_regs *regs, + int cr, u8 grey) +{ + bt455_select_reg(regs, cr); + bt455_write_cmap_next(regs, grey); +} + +static inline void bt455_write_ovly_entry(struct bt455_regs *regs, u8 grey) +{ + bt455_reset_reg(regs); + bt455_write_ovly_next(regs, grey); +} diff --git a/drivers/video/fbdev/pmag-aa-fb.c b/drivers/video/fbdev/pmag-aa-fb.c index 6f4466c39529f..ffe2dd482f840 100644 --- a/drivers/video/fbdev/pmag-aa-fb.c +++ b/drivers/video/fbdev/pmag-aa-fb.c @@ -122,8 +122,8 @@ static int aafb_cursor(struct fb_info *info, struct fb_cursor *cursor) u8 bg = cursor->image.bg_color ? 0xf : 0x0; bt455_write_cmap_entry(par->bt455, 8, bg); - bt455_write_cmap_entry(par->bt455, 9, bg); - bt455_write_ovly_entry(par->bt455, 0, fg); + bt455_write_cmap_next(par->bt455, bg); + bt455_write_ovly_next(par->bt455, fg); } if (cursor->set & (FB_CUR_SETSIZE | FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) bt431_set_cursor(par->bt431, @@ -212,7 +212,7 @@ static int pmagaafb_probe(struct device *dev) /* Init colormap. */ bt455_write_cmap_entry(par->bt455, 0, 0x0); - bt455_write_cmap_entry(par->bt455, 1, 0xf); + bt455_write_cmap_next(par->bt455, 0xf); /* Init hardware cursor. */ bt431_erase_cursor(par->bt431); From e29f0d55e2b98f630d86892688a00a9d820b9989 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" <macro@linux-mips.org> Date: Mon, 22 Feb 2016 01:55:34 +0000 Subject: [PATCH 13/21] video: fbdev: bt431: Correct cursor format control macro The Bt431 cursor generator supports simultaneous generation of a 64 x 64 and a cross hair cursor in which the cursor format control bit (bit D4) of the command register "specifies whether the contents of the cursor RAM are to be logically exclusive-ORed (logical zero) or ORed (logical one) with the cross hair cursor". Rename the relevant macro accordingly. References: [1] "Bt431 Monolithic CMOS 64 x 64 Pixel Cursor Generator", Brooktree Corporation, Document Number: L431001, Rev. J Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/bt431.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/bt431.h b/drivers/video/fbdev/bt431.h index 108fab39fd788..3929602f58676 100644 --- a/drivers/video/fbdev/bt431.h +++ b/drivers/video/fbdev/bt431.h @@ -63,7 +63,7 @@ static inline u8 bt431_get_value(u16 val) #define BT431_CMD_CURS_ENABLE 0x40 #define BT431_CMD_XHAIR_ENABLE 0x20 #define BT431_CMD_OR_CURSORS 0x10 -#define BT431_CMD_AND_CURSORS 0x00 +#define BT431_CMD_XOR_CURSORS 0x00 #define BT431_CMD_1_1_MUX 0x00 #define BT431_CMD_4_1_MUX 0x04 #define BT431_CMD_5_1_MUX 0x08 From 2f9ba65d9d79311119470d9a5280b335c2fb023c Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes <linux@rasmusvillemoes.dk> Date: Tue, 9 Feb 2016 19:56:11 +0100 Subject: [PATCH 14/21] fbdev: kill fb_rotate The fb_rotate method in struct fb_ops is never actually invoked, and it's been that way in the entire history of git (in fact, the last occurrence of the string '->fb_rotate' vanished over 10 years ago, with b4d8aea6d6, and that merely tested whether the callback existed). So remove some dead code and make struct fb_obs a little smaller. Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/atafb.c | 3 --- drivers/video/fbdev/au1100fb.c | 22 ---------------------- drivers/video/fbdev/bf537-lq035.c | 23 ----------------------- drivers/video/fbdev/omap/omapfb_main.c | 22 ---------------------- drivers/video/fbdev/skeletonfb.c | 17 ----------------- include/linux/fb.h | 3 --- 6 files changed, 90 deletions(-) diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c index d6ce613e12ade..fcd2dd670a658 100644 --- a/drivers/video/fbdev/atafb.c +++ b/drivers/video/fbdev/atafb.c @@ -313,9 +313,6 @@ extern unsigned char fontdata_8x16[]; * * Draws cursor * * int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor); * - * * Rotates the display * - * void (*fb_rotate)(struct fb_info *info, int angle); - * * * wait for blit idle, optional * * int (*fb_sync)(struct fb_info *info); * diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c index 59560189b24ae..35df2c1a8a63c 100644 --- a/drivers/video/fbdev/au1100fb.c +++ b/drivers/video/fbdev/au1100fb.c @@ -334,27 +334,6 @@ int au1100fb_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi) return 0; } -/* fb_rotate - * Rotate the display of this angle. This doesn't seems to be used by the core, - * but as our hardware supports it, so why not implementing it... - */ -void au1100fb_fb_rotate(struct fb_info *fbi, int angle) -{ - struct au1100fb_device *fbdev = to_au1100fb_device(fbi); - - print_dbg("fb_rotate %p %d", fbi, angle); - - if (fbdev && (angle > 0) && !(angle % 90)) { - - fbdev->regs->lcd_control &= ~LCD_CONTROL_GO; - - fbdev->regs->lcd_control &= ~(LCD_CONTROL_SM_MASK); - fbdev->regs->lcd_control |= ((angle/90) << LCD_CONTROL_SM_BIT); - - fbdev->regs->lcd_control |= LCD_CONTROL_GO; - } -} - /* fb_mmap * Map video memory in user space. We don't use the generic fb_mmap method mainly * to allow the use of the TLB streaming flag (CCA=6) @@ -380,7 +359,6 @@ static struct fb_ops au1100fb_ops = .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_rotate = au1100fb_fb_rotate, .fb_mmap = au1100fb_fb_mmap, }; diff --git a/drivers/video/fbdev/bf537-lq035.c b/drivers/video/fbdev/bf537-lq035.c index 7db3052b471d0..ef29fb425122c 100644 --- a/drivers/video/fbdev/bf537-lq035.c +++ b/drivers/video/fbdev/bf537-lq035.c @@ -554,28 +554,6 @@ static int bfin_lq035_fb_check_var(struct fb_var_screeninfo *var, return 0; } -/* fb_rotate - * Rotate the display of this angle. This doesn't seems to be used by the core, - * but as our hardware supports it, so why not implementing it... - */ -static void bfin_lq035_fb_rotate(struct fb_info *fbi, int angle) -{ - pr_debug("%s: %p %d", __func__, fbi, angle); -#if (defined(UD) && defined(LBR)) - switch (angle) { - - case 180: - gpio_set_value(LBR, 0); - gpio_set_value(UD, 1); - break; - default: - gpio_set_value(LBR, 1); - gpio_set_value(UD, 0); - break; - } -#endif -} - static int bfin_lq035_fb_cursor(struct fb_info *info, struct fb_cursor *cursor) { if (nocursor) @@ -623,7 +601,6 @@ static struct fb_ops bfin_lq035_fb_ops = { .fb_open = bfin_lq035_fb_open, .fb_release = bfin_lq035_fb_release, .fb_check_var = bfin_lq035_fb_check_var, - .fb_rotate = bfin_lq035_fb_rotate, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, diff --git a/drivers/video/fbdev/omap/omapfb_main.c b/drivers/video/fbdev/omap/omapfb_main.c index 393ae1bc07e8f..6429f33167f5e 100644 --- a/drivers/video/fbdev/omap/omapfb_main.c +++ b/drivers/video/fbdev/omap/omapfb_main.c @@ -594,27 +594,6 @@ static int set_fb_var(struct fb_info *fbi, } -/* Set rotation (0, 90, 180, 270 degree), and switch to the new mode. */ -static void omapfb_rotate(struct fb_info *fbi, int rotate) -{ - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_device *fbdev = plane->fbdev; - - omapfb_rqueue_lock(fbdev); - if (rotate != fbi->var.rotate) { - struct fb_var_screeninfo *new_var = &fbdev->new_var; - - memcpy(new_var, &fbi->var, sizeof(*new_var)); - new_var->rotate = rotate; - if (set_fb_var(fbi, new_var) == 0 && - memcmp(new_var, &fbi->var, sizeof(*new_var))) { - memcpy(&fbi->var, new_var, sizeof(*new_var)); - ctrl_change_mode(fbi); - } - } - omapfb_rqueue_unlock(fbdev); -} - /* * Set new x,y offsets in the virtual display for the visible area and switch * to the new mode. @@ -1256,7 +1235,6 @@ static struct fb_ops omapfb_ops = { .fb_ioctl = omapfb_ioctl, .fb_check_var = omapfb_check_var, .fb_set_par = omapfb_set_par, - .fb_rotate = omapfb_rotate, .fb_pan_display = omapfb_pan_display, }; diff --git a/drivers/video/fbdev/skeletonfb.c b/drivers/video/fbdev/skeletonfb.c index fefde7c6add72..f948baa16d829 100644 --- a/drivers/video/fbdev/skeletonfb.c +++ b/drivers/video/fbdev/skeletonfb.c @@ -613,22 +613,6 @@ int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor) */ } -/** - * xxxfb_rotate - NOT a required function. If your hardware - * supports rotation the whole screen then - * you would provide a hook for this. - * - * @info: frame buffer structure that represents a single frame buffer - * @angle: The angle we rotate the screen. - * - * This operation is used to set or alter the properities of the - * cursor. - */ -void xxxfb_rotate(struct fb_info *info, int angle) -{ -/* Will be deprecated */ -} - /** * xxxfb_sync - NOT a required function. Normally the accel engine * for a graphics card take a specific amount of time. @@ -665,7 +649,6 @@ static struct fb_ops xxxfb_ops = { .fb_copyarea = xxxfb_copyarea, /* Needed !!! */ .fb_imageblit = xxxfb_imageblit, /* Needed !!! */ .fb_cursor = xxxfb_cursor, /* Optional !!! */ - .fb_rotate = xxxfb_rotate, .fb_sync = xxxfb_sync, .fb_ioctl = xxxfb_ioctl, .fb_mmap = xxxfb_mmap, diff --git a/include/linux/fb.h b/include/linux/fb.h index 55433f86f0a32..dfe88351341fa 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -296,9 +296,6 @@ struct fb_ops { /* Draws cursor */ int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor); - /* Rotates the display */ - void (*fb_rotate)(struct fb_info *info, int angle); - /* wait for blit idle, optional */ int (*fb_sync)(struct fb_info *info); From 713fced8d10fa1c759c8fb6bf9aaa681bae68cad Mon Sep 17 00:00:00 2001 From: Sushaanth Srirangapathi <sushaanth.s@ti.com> Date: Mon, 29 Feb 2016 18:42:19 +0530 Subject: [PATCH 15/21] fbdev: da8xx-fb: fix videomodes of lcd panels Commit 028cd86b794f4a ("video: da8xx-fb: fix the polarities of the hsync/vsync pulse") fixes polarities of HSYNC/VSYNC pulse but forgot to update known_lcd_panels[] which had sync values according to old logic. This breaks LCD at least on DA850 EVM. This patch fixes this issue and I have tested this for panel "Sharp_LK043T1DG01" using DA850 EVM board. Fixes: 028cd86b794f4a ("video: da8xx-fb: fix the polarities of the hsync/vsync pulse") Signed-off-by: Sushaanth Srirangapathi <sushaanth.s@ti.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/da8xx-fb.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c index 6b2a06d09f2b6..d8d583d32a37b 100644 --- a/drivers/video/fbdev/da8xx-fb.c +++ b/drivers/video/fbdev/da8xx-fb.c @@ -209,8 +209,7 @@ static struct fb_videomode known_lcd_panels[] = { .lower_margin = 2, .hsync_len = 0, .vsync_len = 0, - .sync = FB_SYNC_CLK_INVERT | - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .sync = FB_SYNC_CLK_INVERT, }, /* Sharp LK043T1DG01 */ [1] = { @@ -224,7 +223,7 @@ static struct fb_videomode known_lcd_panels[] = { .lower_margin = 2, .hsync_len = 41, .vsync_len = 10, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .sync = 0, .flag = 0, }, [2] = { @@ -239,7 +238,7 @@ static struct fb_videomode known_lcd_panels[] = { .lower_margin = 10, .hsync_len = 10, .vsync_len = 10, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .sync = 0, .flag = 0, }, [3] = { From 5a63ddf60ee105a484501fd0d569923080592c0a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann <arnd@arndb.de> Date: Fri, 26 Feb 2016 13:38:08 +0100 Subject: [PATCH 16/21] video: exynos: fix modular build The s6e8ax0 driver has a dependency on BACKLIGHT_CLASS_DEVICE, which can be configured as a loadable module, so we have to make the driver a tristate symbol as well, to avoid this error: drivers/built-in.o: In function `s6e8ax0_probe': :(.text+0x23a48): undefined reference to `devm_backlight_device_register' This also means we get another error from a missing export, which this fixes as well: ERROR: "exynos_mipi_dsi_register_lcd_driver" [drivers/video/fbdev/exynos/s6e8ax0.ko] undefined! The drivers are all written to be loadable modules already, except the Kconfig options for that are missing, which makes the patch really easy. Finally, the EXYNOS_VIDEO option is turned into tristate as well for good measure, as all framebuffer drivers should be configurable as modules, though this change is not strictly necessary. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/exynos/Kconfig | 6 +++--- drivers/video/fbdev/exynos/Makefile | 6 ++++-- drivers/video/fbdev/exynos/exynos_mipi_dsi.c | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/video/fbdev/exynos/Kconfig b/drivers/video/fbdev/exynos/Kconfig index 1f16b4678c714..d916bef94f25e 100644 --- a/drivers/video/fbdev/exynos/Kconfig +++ b/drivers/video/fbdev/exynos/Kconfig @@ -3,7 +3,7 @@ # menuconfig EXYNOS_VIDEO - bool "Exynos Video driver support" + tristate "Exynos Video driver support" depends on ARCH_S5PV210 || ARCH_EXYNOS help This enables support for EXYNOS Video device. @@ -15,13 +15,13 @@ if EXYNOS_VIDEO # config EXYNOS_MIPI_DSI - bool "EXYNOS MIPI DSI driver support." + tristate "EXYNOS MIPI DSI driver support." select GENERIC_PHY help This enables support for MIPI-DSI device. config EXYNOS_LCD_S6E8AX0 - bool "S6E8AX0 MIPI AMOLED LCD Driver" + tristate "S6E8AX0 MIPI AMOLED LCD Driver" depends on EXYNOS_MIPI_DSI && BACKLIGHT_CLASS_DEVICE depends on (LCD_CLASS_DEVICE = y) default n diff --git a/drivers/video/fbdev/exynos/Makefile b/drivers/video/fbdev/exynos/Makefile index b5b1bd228abb8..02d8dc522fea6 100644 --- a/drivers/video/fbdev/exynos/Makefile +++ b/drivers/video/fbdev/exynos/Makefile @@ -2,6 +2,8 @@ # Makefile for the exynos video drivers. # -obj-$(CONFIG_EXYNOS_MIPI_DSI) += exynos_mipi_dsi.o exynos_mipi_dsi_common.o \ - exynos_mipi_dsi_lowlevel.o +obj-$(CONFIG_EXYNOS_MIPI_DSI) += exynos-mipi-dsi-mod.o + +exynos-mipi-dsi-mod-objs += exynos_mipi_dsi.o exynos_mipi_dsi_common.o \ + exynos_mipi_dsi_lowlevel.o obj-$(CONFIG_EXYNOS_LCD_S6E8AX0) += s6e8ax0.o diff --git a/drivers/video/fbdev/exynos/exynos_mipi_dsi.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c index 951b592794e34..92e4af3caaf8f 100644 --- a/drivers/video/fbdev/exynos/exynos_mipi_dsi.c +++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c @@ -263,6 +263,7 @@ int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_drv) return 0; } +EXPORT_SYMBOL_GPL(exynos_mipi_dsi_register_lcd_driver); static struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi( struct mipi_dsim_device *dsim, From d61b0ef7184f3b5a7e068f503ccaa6e2701c00ea Mon Sep 17 00:00:00 2001 From: Paul Gortmaker <paul.gortmaker@windriver.com> Date: Sun, 21 Feb 2016 22:13:10 -0500 Subject: [PATCH 17/21] drivers/video: make fbdev/sunxvr500.c explicitly non-modular The Kconfig currently controlling compilation of this code is: config FB_XVR500 bool "Sun XVR-500 3DLABS Wildcat support" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. We explicitly disallow a driver unbind, since that doesn't have a sensible use case anyway, and it allows us to drop the ".remove" code for non-modular drivers. Since module_init translates to device_initcall in the non-modular case, the init ordering remains unchanged with this commit. We don't replace module.h with init.h since the file already has that. We also delete the MODULE_LICENSE tag etc. since all that information was (or is now) contained at the top of the file in the comments. Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com> Cc: Tomi Valkeinen <tomi.valkeinen@ti.com> Cc: "David S. Miller" <davem@davemloft.net> Cc: sparclinux@vger.kernel.org Cc: linux-fbdev@vger.kernel.org Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/sunxvr500.c | 42 ++++++--------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/drivers/video/fbdev/sunxvr500.c b/drivers/video/fbdev/sunxvr500.c index 387350d004df7..dc0d886e4e7ef 100644 --- a/drivers/video/fbdev/sunxvr500.c +++ b/drivers/video/fbdev/sunxvr500.c @@ -1,9 +1,10 @@ -/* sunxvr500.c: Sun 3DLABS XVR-500 Expert3D driver for sparc64 systems +/* sunxvr500.c: Sun 3DLABS XVR-500 Expert3D fb driver for sparc64 systems + * + * License: GPL * * Copyright (C) 2007 David S. Miller (davem@davemloft.net) */ -#include <linux/module.h> #include <linux/kernel.h> #include <linux/fb.h> #include <linux/pci.h> @@ -392,25 +393,6 @@ static int e3d_pci_register(struct pci_dev *pdev, return err; } -static void e3d_pci_unregister(struct pci_dev *pdev) -{ - struct fb_info *info = pci_get_drvdata(pdev); - struct e3d_info *ep = info->par; - - unregister_framebuffer(info); - - iounmap(ep->ramdac); - iounmap(ep->fb_base); - - pci_release_region(pdev, 0); - pci_release_region(pdev, 1); - - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - - pci_disable_device(pdev); -} - static struct pci_device_id e3d_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a0), }, { PCI_DEVICE(0x1091, 0x7a0), }, @@ -434,10 +416,12 @@ static struct pci_device_id e3d_pci_table[] = { }; static struct pci_driver e3d_driver = { + .driver = { + .suppress_bind_attrs = true, + }, .name = "e3d", .id_table = e3d_pci_table, .probe = e3d_pci_register, - .remove = e3d_pci_unregister, }; static int __init e3d_init(void) @@ -447,16 +431,4 @@ static int __init e3d_init(void) return pci_register_driver(&e3d_driver); } - -static void __exit e3d_exit(void) -{ - pci_unregister_driver(&e3d_driver); -} - -module_init(e3d_init); -module_exit(e3d_exit); - -MODULE_DESCRIPTION("framebuffer driver for Sun XVR-500 graphics"); -MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL"); +device_initcall(e3d_init); From 27844cb8101f1ea60984e04c70126dc754ae97a1 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker <paul.gortmaker@windriver.com> Date: Sun, 21 Feb 2016 22:13:11 -0500 Subject: [PATCH 18/21] drivers/video: make fbdev/sunxvr1000.c explicitly non-modular The Kconfig currently controlling compilation of this code is: config FB_XVR1000 bool "Sun XVR-1000 support" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. Since module_init translates to device_initcall in the non-modular case, the init ordering remains unchanged with this commit. We explicitly disallow a driver unbind, since that doesn't have a sensible use case anyway, and it allows us to drop the ".remove" code for non-modular drivers. We don't replace module.h with init.h since the file already has that. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We also delete the MODULE_LICENSE tag etc. since all that information was (or is now) contained at the top of the file in the comments. Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com> Cc: Tomi Valkeinen <tomi.valkeinen@ti.com> Cc: "David S. Miller" <davem@davemloft.net> Cc: sparclinux@vger.kernel.org Cc: linux-fbdev@vger.kernel.org Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/sunxvr1000.c | 42 ++++++-------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/drivers/video/fbdev/sunxvr1000.c b/drivers/video/fbdev/sunxvr1000.c index 08879bdfad35f..fb37f6e053915 100644 --- a/drivers/video/fbdev/sunxvr1000.c +++ b/drivers/video/fbdev/sunxvr1000.c @@ -1,9 +1,10 @@ -/* sunxvr1000.c: Sun XVR-1000 driver for sparc64 systems +/* sunxvr1000.c: Sun XVR-1000 fb driver for sparc64 systems + * + * License: GPL * * Copyright (C) 2010 David S. Miller (davem@davemloft.net) */ -#include <linux/module.h> #include <linux/kernel.h> #include <linux/fb.h> #include <linux/init.h> @@ -173,36 +174,19 @@ static int gfb_probe(struct platform_device *op) return err; } -static int gfb_remove(struct platform_device *op) -{ - struct fb_info *info = dev_get_drvdata(&op->dev); - struct gfb_info *gp = info->par; - - unregister_framebuffer(info); - - iounmap(gp->fb_base); - - of_iounmap(&op->resource[6], gp->fb_base, gp->fb_size); - - framebuffer_release(info); - - return 0; -} - static const struct of_device_id gfb_match[] = { { .name = "SUNW,gfb", }, {}, }; -MODULE_DEVICE_TABLE(of, ffb_match); static struct platform_driver gfb_driver = { .probe = gfb_probe, - .remove = gfb_remove, .driver = { - .name = "gfb", - .of_match_table = gfb_match, + .name = "gfb", + .of_match_table = gfb_match, + .suppress_bind_attrs = true, }, }; @@ -213,16 +197,4 @@ static int __init gfb_init(void) return platform_driver_register(&gfb_driver); } - -static void __exit gfb_exit(void) -{ - platform_driver_unregister(&gfb_driver); -} - -module_init(gfb_init); -module_exit(gfb_exit); - -MODULE_DESCRIPTION("framebuffer driver for Sun XVR-1000 graphics"); -MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL"); +device_initcall(gfb_init); From c15222bdec75890d2523479615bc175956a9eadb Mon Sep 17 00:00:00 2001 From: Paul Gortmaker <paul.gortmaker@windriver.com> Date: Sun, 21 Feb 2016 22:13:12 -0500 Subject: [PATCH 19/21] drivers/video: make fbdev/sunxvr2500.c explicitly non-modular The Kconfig currently controlling compilation of this code is: config FB_XVR2500 bool "Sun XVR-2500 3DLABS Wildcat support" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. Since module_init translates to device_initcall in the non-modular case, the init ordering remains unchanged with this commit. We explicitly disallow a driver unbind, since that doesn't have a sensible use case anyway, and it allows us to drop the ".remove" code for non-modular drivers. We don't replace module.h with init.h since the file already has that. We also delete the MODULE_LICENSE tag etc. since all that information was (or is now) contained at the top of the file in the comments. Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com> Cc: Tomi Valkeinen <tomi.valkeinen@ti.com> Cc: "David S. Miller" <davem@davemloft.net> Cc: sparclinux@vger.kernel.org Cc: linux-fbdev@vger.kernel.org Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/sunxvr2500.c | 39 ++++++-------------------------- 1 file changed, 7 insertions(+), 32 deletions(-) diff --git a/drivers/video/fbdev/sunxvr2500.c b/drivers/video/fbdev/sunxvr2500.c index 843b6bab0483b..1a053292f2eb1 100644 --- a/drivers/video/fbdev/sunxvr2500.c +++ b/drivers/video/fbdev/sunxvr2500.c @@ -1,9 +1,10 @@ -/* s3d.c: Sun 3DLABS XVR-2500 et al. driver for sparc64 systems +/* sunxvr2500.c: Sun 3DLABS XVR-2500 et al. fb driver for sparc64 systems + * + * License: GPL * * Copyright (C) 2007 David S. Miller (davem@davemloft.net) */ -#include <linux/module.h> #include <linux/kernel.h> #include <linux/fb.h> #include <linux/pci.h> @@ -219,22 +220,6 @@ static int s3d_pci_register(struct pci_dev *pdev, return err; } -static void s3d_pci_unregister(struct pci_dev *pdev) -{ - struct fb_info *info = pci_get_drvdata(pdev); - struct s3d_info *sp = info->par; - - unregister_framebuffer(info); - - iounmap(sp->fb_base); - - pci_release_region(pdev, 1); - - framebuffer_release(info); - - pci_disable_device(pdev); -} - static struct pci_device_id s3d_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x002c), }, { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x002d), }, @@ -248,10 +233,12 @@ static struct pci_device_id s3d_pci_table[] = { }; static struct pci_driver s3d_driver = { + .driver = { + .suppress_bind_attrs = true, + }, .name = "s3d", .id_table = s3d_pci_table, .probe = s3d_pci_register, - .remove = s3d_pci_unregister, }; static int __init s3d_init(void) @@ -261,16 +248,4 @@ static int __init s3d_init(void) return pci_register_driver(&s3d_driver); } - -static void __exit s3d_exit(void) -{ - pci_unregister_driver(&s3d_driver); -} - -module_init(s3d_init); -module_exit(s3d_exit); - -MODULE_DESCRIPTION("framebuffer driver for Sun XVR-2500 graphics"); -MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL"); +device_initcall(s3d_init); From 32ad61951574d011d363694d6037592e99da9421 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee <sudipm.mukherjee@gmail.com> Date: Mon, 29 Feb 2016 23:32:29 +0530 Subject: [PATCH 20/21] video: fbdev: sis: remove unused variable The variables modeflag and resinfo were only assigned some value but were never used. Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/sis/init301.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/video/fbdev/sis/init301.c b/drivers/video/fbdev/sis/init301.c index 295e0dedaf1fe..20f7234e809ef 100644 --- a/drivers/video/fbdev/sis/init301.c +++ b/drivers/video/fbdev/sis/init301.c @@ -2151,17 +2151,15 @@ SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor unsigned short RefreshRateTableIndex) { unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0; - unsigned short modeflag, resinfo, tempbx; + unsigned short resinfo, tempbx; const unsigned char *CHTVVCLKPtr = NULL; if(ModeNo <= 0x13) { - modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03; VCLKIndexGENCRT = VCLKIndexGEN; } else { - modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; @@ -7270,7 +7268,7 @@ SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift) static void SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) { - unsigned short temp, temp1, resinfo = 0; + unsigned short temp, temp1; unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return; @@ -7282,10 +7280,6 @@ SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned if(!(ROMAddr[0x61] & 0x04)) return; } - if(ModeNo > 0x13) { - resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; - } - SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08); temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a); if(!(temp & 0x01)) { From 13aa38e291bdd4e4018f40dd2f75e464814dcbf3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann <arnd@arndb.de> Date: Tue, 16 Feb 2016 16:03:23 +0100 Subject: [PATCH 21/21] xen kconfig: don't "select INPUT_XEN_KBDDEV_FRONTEND" The Xen framebuffer driver selects the xen keyboard driver, so the latter will be built-in if XEN_FBDEV_FRONTEND=y. However, when CONFIG_INPUT is a loadable module, this configuration cannot work. On mainline kernels, the symbol will be enabled but not used, while in combination with a patch I have to detect such useless configurations, we get the expected link failure: drivers/input/built-in.o: In function `xenkbd_remove': xen-kbdfront.c:(.text+0x2f0): undefined reference to `input_unregister_device' xen-kbdfront.c:(.text+0x30e): undefined reference to `input_unregister_device' This removes the extra "select", as it just causes more trouble than it helps. In theory, some defconfig file might break if it has XEN_FBDEV_FRONTEND in it but not INPUT_XEN_KBDDEV_FRONTEND. The Kconfig fragment we ship in the kernel (kernel/configs/xen.config) however already enables both, and anyone using an old .config file would keep having both enabled. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Suggested-by: David Vrabel <david.vrabel@citrix.com> Fixes: 36c1132e34bd ("xen kconfig: fix select INPUT_XEN_KBDDEV_FRONTEND") Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/fbdev/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 18f1853529fc0..983280e8d93f3 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -2246,7 +2246,6 @@ config XEN_FBDEV_FRONTEND select FB_SYS_IMAGEBLIT select FB_SYS_FOPS select FB_DEFERRED_IO - select INPUT_XEN_KBDDEV_FRONTEND if INPUT_MISC select XEN_XENBUS_FRONTEND default y help