Merge tag 'fbdev-for-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev

Pull fbdev updates from Helge Deller:
 "One potential buffer overflow fix in the framebuffer registration
  function, some fixes for the imxfb, nvidiafb and simplefb drivers, and
  a bunch of cleanups for fbcon, kyrofb and svgalib.

  Framework fixes:
   - fix potential buffer overflow in do_register_framebuffer() [Yongzhen Zhang]

  Driver fixes:
   - imxfb: prevent null-ptr-deref [Chenyuan Yang]
   - nvidiafb: fix build on 32-bit ARCH=um [Johannes Berg]
   - nvidiafb: add depends on HAS_IOPORT [Randy Dunlap]
   - simplefb: Use of_reserved_mem_region_to_resource() for "memory-region" [Rob Herring]

  Cleanups:
   - fbcon: various code cleanups wrt blinking [Ville Syrjälä]
   - kyrofb: Convert to devm_*() functions [Giovanni Di Santi]
   - svgalib: Coding style cleanups [Darshan R.]
   - Fix typo in Kconfig text for FB_DEVICE [Daniel Palmer]"

* tag 'fbdev-for-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev:
  fbcon: Use 'bool' where appopriate
  fbcon: Introduce get_{fg,bg}_color()
  fbcon: fbcon_is_inactive() -> fbcon_is_active()
  fbcon: fbcon_cursor_noblink -> fbcon_cursor_blink
  fbdev: Fix typo in Kconfig text for FB_DEVICE
  fbdev: imxfb: Check fb_add_videomode to prevent null-ptr-deref
  fbdev: svgalib: Clean up coding style
  fbdev: kyro: Use devm_ioremap_wc() for screen mem
  fbdev: kyro: Use devm_ioremap() for mmio registers
  fbdev: kyro: Add missing PCI memory region request
  fbdev: simplefb: Use of_reserved_mem_region_to_resource() for "memory-region"
  fbdev: fix potential buffer overflow in do_register_framebuffer()
  fbdev: nvidiafb: add depends on HAS_IOPORT
  fbdev: nvidiafb: fix build on 32-bit ARCH=um
This commit is contained in:
Linus Torvalds
2025-08-02 09:58:11 -07:00
9 changed files with 116 additions and 115 deletions
+1 -1
View File
@@ -660,7 +660,7 @@ config FB_ATMEL
config FB_NVIDIA
tristate "nVidia Framebuffer Support"
depends on FB && PCI
depends on FB && PCI && HAS_IOPORT
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+1 -1
View File
@@ -16,7 +16,7 @@ config FB_DEVICE
default FB
help
Say Y here if you want the legacy /dev/fb* device file and
interfaces within sysfs anc procfs. It is only required if you
interfaces within sysfs and procfs. It is only required if you
have userspace programs that depend on fbdev for graphics output.
This does not affect the framebuffer console. If unsure, say N.
+45 -32
View File
@@ -135,9 +135,9 @@ static int logo_shown = FBCON_LOGO_CANSHOW;
/* console mappings */
static unsigned int first_fb_vc;
static unsigned int last_fb_vc = MAX_NR_CONSOLES - 1;
static int fbcon_is_default = 1;
static bool fbcon_is_default = true;
static int primary_device = -1;
static int fbcon_has_console_bind;
static bool fbcon_has_console_bind;
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
static int map_override;
@@ -172,7 +172,7 @@ static const struct consw fb_con;
#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row)
static int fbcon_cursor_noblink;
static bool fbcon_cursor_blink = true;
#define divides(a, b) ((!(a) || (b)%(a)) ? 0 : 1)
@@ -289,16 +289,16 @@ static bool fbcon_skip_panic(struct fb_info *info)
#endif
}
static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
static inline bool fbcon_is_active(struct vc_data *vc, struct fb_info *info)
{
struct fbcon_ops *ops = info->fbcon_par;
return (info->state != FBINFO_STATE_RUNNING ||
vc->vc_mode != KD_TEXT || ops->graphics || fbcon_skip_panic(info));
return info->state == FBINFO_STATE_RUNNING &&
vc->vc_mode == KD_TEXT && !ops->graphics && !fbcon_skip_panic(info);
}
static int get_color(struct vc_data *vc, struct fb_info *info,
u16 c, int is_fg)
u16 c, bool is_fg)
{
int depth = fb_get_color_depth(&info->var, &info->fix);
int color = 0;
@@ -364,6 +364,16 @@ static int get_color(struct vc_data *vc, struct fb_info *info,
return color;
}
static int get_fg_color(struct vc_data *vc, struct fb_info *info, u16 c)
{
return get_color(vc, info, c, true);
}
static int get_bg_color(struct vc_data *vc, struct fb_info *info, u16 c)
{
return get_color(vc, info, c, false);
}
static void fb_flashcursor(struct work_struct *work)
{
struct fbcon_ops *ops = container_of(work, struct fbcon_ops, cursor_work.work);
@@ -395,8 +405,9 @@ static void fb_flashcursor(struct work_struct *work)
c = scr_readw((u16 *) vc->vc_pos);
enable = ops->cursor_flash && !ops->cursor_state.enable;
ops->cursor(vc, info, enable, get_color(vc, info, c, 1),
get_color(vc, info, c, 0));
ops->cursor(vc, info, enable,
get_fg_color(vc, info, c),
get_bg_color(vc, info, c));
console_unlock();
queue_delayed_work(system_power_efficient_wq, &ops->cursor_work,
@@ -407,7 +418,7 @@ static void fbcon_add_cursor_work(struct fb_info *info)
{
struct fbcon_ops *ops = info->fbcon_par;
if (!fbcon_cursor_noblink)
if (fbcon_cursor_blink)
queue_delayed_work(system_power_efficient_wq, &ops->cursor_work,
ops->cur_blink_jiffies);
}
@@ -464,7 +475,7 @@ static int __init fb_console_setup(char *this_opt)
last_fb_vc = simple_strtoul(options, &options, 10) - 1;
if (last_fb_vc < first_fb_vc || last_fb_vc >= MAX_NR_CONSOLES)
last_fb_vc = MAX_NR_CONSOLES - 1;
fbcon_is_default = 0;
fbcon_is_default = false;
continue;
}
@@ -559,7 +570,7 @@ static int do_fbcon_takeover(int show_logo)
con2fb_map[i] = -1;
info_idx = -1;
} else {
fbcon_has_console_bind = 1;
fbcon_has_console_bind = true;
}
return err;
@@ -1267,7 +1278,7 @@ static void __fbcon_clear(struct vc_data *vc, unsigned int sy, unsigned int sx,
struct fbcon_display *p = &fb_display[vc->vc_num];
u_int y_break;
if (fbcon_is_inactive(vc, info))
if (!fbcon_is_active(vc, info))
return;
if (!height || !width)
@@ -1311,10 +1322,10 @@ static void fbcon_putcs(struct vc_data *vc, const u16 *s, unsigned int count,
struct fbcon_display *p = &fb_display[vc->vc_num];
struct fbcon_ops *ops = info->fbcon_par;
if (!fbcon_is_inactive(vc, info))
if (fbcon_is_active(vc, info))
ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
get_color(vc, info, scr_readw(s), 1),
get_color(vc, info, scr_readw(s), 0));
get_fg_color(vc, info, scr_readw(s)),
get_bg_color(vc, info, scr_readw(s)));
}
static void fbcon_clear_margins(struct vc_data *vc, int bottom_only)
@@ -1322,7 +1333,7 @@ static void fbcon_clear_margins(struct vc_data *vc, int bottom_only)
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
struct fbcon_ops *ops = info->fbcon_par;
if (!fbcon_is_inactive(vc, info))
if (fbcon_is_active(vc, info))
ops->clear_margins(vc, info, margin_color, bottom_only);
}
@@ -1334,7 +1345,7 @@ static void fbcon_cursor(struct vc_data *vc, bool enable)
ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
if (fbcon_is_inactive(vc, info) || vc->vc_deccm != 1)
if (!fbcon_is_active(vc, info) || vc->vc_deccm != 1)
return;
if (vc->vc_cursor_type & CUR_SW)
@@ -1347,8 +1358,9 @@ static void fbcon_cursor(struct vc_data *vc, bool enable)
if (!ops->cursor)
return;
ops->cursor(vc, info, enable, get_color(vc, info, c, 1),
get_color(vc, info, c, 0));
ops->cursor(vc, info, enable,
get_fg_color(vc, info, c),
get_bg_color(vc, info, c));
}
static int scrollback_phys_max = 0;
@@ -1740,7 +1752,7 @@ static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
struct fbcon_display *p = &fb_display[vc->vc_num];
if (fbcon_is_inactive(vc, info))
if (!fbcon_is_active(vc, info))
return;
if (!width || !height)
@@ -1764,7 +1776,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
struct fbcon_display *p = &fb_display[vc->vc_num];
int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;
if (fbcon_is_inactive(vc, info))
if (!fbcon_is_active(vc, info))
return true;
fbcon_cursor(vc, false);
@@ -2148,7 +2160,7 @@ static bool fbcon_switch(struct vc_data *vc)
fbcon_del_cursor_work(old_info);
}
if (fbcon_is_inactive(vc, info) ||
if (!fbcon_is_active(vc, info) ||
ops->blank_state != FB_BLANK_UNBLANK)
fbcon_del_cursor_work(info);
else
@@ -2188,7 +2200,7 @@ static bool fbcon_switch(struct vc_data *vc)
scrollback_max = 0;
scrollback_current = 0;
if (!fbcon_is_inactive(vc, info)) {
if (fbcon_is_active(vc, info)) {
ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
ops->update_start(info);
}
@@ -2244,7 +2256,7 @@ static bool fbcon_blank(struct vc_data *vc, enum vesa_blank_mode blank,
}
}
if (!fbcon_is_inactive(vc, info)) {
if (fbcon_is_active(vc, info)) {
if (ops->blank_state != blank) {
ops->blank_state = blank;
fbcon_cursor(vc, !blank);
@@ -2258,7 +2270,7 @@ static bool fbcon_blank(struct vc_data *vc, enum vesa_blank_mode blank,
update_screen(vc);
}
if (mode_switch || fbcon_is_inactive(vc, info) ||
if (mode_switch || !fbcon_is_active(vc, info) ||
ops->blank_state != FB_BLANK_UNBLANK)
fbcon_del_cursor_work(info);
else
@@ -2588,7 +2600,7 @@ static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table)
int i, j, k, depth;
u8 val;
if (fbcon_is_inactive(vc, info))
if (!fbcon_is_active(vc, info))
return;
if (!con_is_visible(vc))
@@ -2688,7 +2700,7 @@ static void fbcon_modechanged(struct fb_info *info)
scrollback_max = 0;
scrollback_current = 0;
if (!fbcon_is_inactive(vc, info)) {
if (fbcon_is_active(vc, info)) {
ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
ops->update_start(info);
}
@@ -2806,7 +2818,7 @@ static void fbcon_unbind(void)
fbcon_is_default);
if (!ret)
fbcon_has_console_bind = 0;
fbcon_has_console_bind = false;
}
#else
static inline void fbcon_unbind(void) {}
@@ -3257,8 +3269,9 @@ static ssize_t cursor_blink_store(struct device *device,
const char *buf, size_t count)
{
struct fb_info *info;
int blink, idx;
char **last = NULL;
bool blink;
int idx;
console_lock();
idx = con2fb_map[fg_console];
@@ -3274,10 +3287,10 @@ static ssize_t cursor_blink_store(struct device *device,
blink = simple_strtoul(buf, last, 0);
if (blink) {
fbcon_cursor_noblink = 0;
fbcon_cursor_blink = true;
fbcon_add_cursor_work(info);
} else {
fbcon_cursor_noblink = 1;
fbcon_cursor_blink = false;
fbcon_del_cursor_work(info);
}
+3
View File
@@ -449,6 +449,9 @@ static int do_register_framebuffer(struct fb_info *fb_info)
if (!registered_fb[i])
break;
if (i >= FB_MAX)
return -ENXIO;
if (!fb_info->modelist.prev || !fb_info->modelist.next)
INIT_LIST_HEAD(&fb_info->modelist);
+42 -53
View File
@@ -20,7 +20,6 @@
#include <asm/types.h>
#include <asm/io.h>
/* Write a CRT register value spread across multiple registers */
void svga_wcrt_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value)
{
@@ -32,12 +31,13 @@ void svga_wcrt_multi(void __iomem *regbase, const struct vga_regset *regset, u32
while (bitnum <= regset->highbit) {
bitval = 1 << bitnum;
regval = regval & ~bitval;
if (value & 1) regval = regval | bitval;
bitnum ++;
if (value & 1)
regval = regval | bitval;
bitnum++;
value = value >> 1;
}
vga_wcrt(regbase, regset->regnum, regval);
regset ++;
regset++;
}
}
@@ -52,12 +52,13 @@ void svga_wseq_multi(void __iomem *regbase, const struct vga_regset *regset, u32
while (bitnum <= regset->highbit) {
bitval = 1 << bitnum;
regval = regval & ~bitval;
if (value & 1) regval = regval | bitval;
bitnum ++;
if (value & 1)
regval = regval | bitval;
bitnum++;
value = value >> 1;
}
vga_wseq(regbase, regset->regnum, regval);
regset ++;
regset++;
}
}
@@ -67,15 +68,13 @@ static unsigned int svga_regset_size(const struct vga_regset *regset)
while (regset->regnum != VGA_REGSET_END_VAL) {
count += regset->highbit - regset->lowbit + 1;
regset ++;
regset++;
}
return 1 << count;
}
/* ------------------------------------------------------------------------- */
/* Set graphics controller registers to sane values */
void svga_set_default_gfx_regs(void __iomem *regbase)
{
@@ -103,7 +102,7 @@ void svga_set_default_atc_regs(void __iomem *regbase)
vga_w(regbase, VGA_ATT_W, 0x00);
/* All standard ATC registers (AR00 - AR14) */
for (count = 0; count <= 0xF; count ++)
for (count = 0; count <= 0xF; count++)
svga_wattr(regbase, count, count);
svga_wattr(regbase, VGA_ATC_MODE, 0x01);
@@ -188,10 +187,8 @@ void svga_dump_var(struct fb_var_screeninfo *var, int node)
}
#endif /* 0 */
/* ------------------------------------------------------------------------- */
void svga_settile(struct fb_info *info, struct fb_tilemap *map)
{
const u8 *font = map->data;
@@ -230,7 +227,7 @@ void svga_tilecopy(struct fb_info *info, struct fb_tilearea *area)
((area->sy == area->dy) && (area->sx > area->dx))) {
src = fb + area->sx * colstride + area->sy * rowstride;
dst = fb + area->dx * colstride + area->dy * rowstride;
} else {
} else {
src = fb + (area->sx + area->width - 1) * colstride
+ (area->sy + area->height - 1) * rowstride;
dst = fb + (area->dx + area->width - 1) * colstride
@@ -238,7 +235,7 @@ void svga_tilecopy(struct fb_info *info, struct fb_tilearea *area)
colstride = -colstride;
rowstride = -rowstride;
}
}
for (dy = 0; dy < area->height; dy++) {
u16 __iomem *src2 = src;
@@ -285,19 +282,19 @@ void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit)
u8 __iomem *fb = (u8 __iomem *)info->screen_base;
fb += blit->sx * colstride + blit->sy * rowstride;
i=0;
for (dy=0; dy < blit->height; dy ++) {
i = 0;
for (dy = 0; dy < blit->height; dy++) {
u8 __iomem *fb2 = fb;
for (dx = 0; dx < blit->width; dx ++) {
for (dx = 0; dx < blit->width; dx++) {
fb_writeb(blit->indices[i], fb2);
fb_writeb(attr, fb2 + 1);
fb2 += colstride;
i ++;
if (i == blit->length) return;
i++;
if (i == blit->length)
return;
}
fb += rowstride;
}
}
/* Set cursor in text (tileblit) mode */
@@ -309,15 +306,15 @@ void svga_tilecursor(void __iomem *regbase, struct fb_info *info, struct fb_tile
+ (cursor->sy + (info->var.yoffset / 16))
* (info->var.xres_virtual / 8);
if (! cursor -> mode)
if (!cursor->mode)
return;
svga_wcrt_mask(regbase, 0x0A, 0x20, 0x20); /* disable cursor */
if (cursor -> shape == FB_TILE_CURSOR_NONE)
if (cursor->shape == FB_TILE_CURSOR_NONE)
return;
switch (cursor -> shape) {
switch (cursor->shape) {
case FB_TILE_CURSOR_UNDERLINE:
cs = 0x0d;
break;
@@ -375,7 +372,6 @@ EXPORT_SYMBOL(svga_get_caps);
/* ------------------------------------------------------------------------- */
/*
* Compute PLL settings (M, N, R)
* F_VCO = (F_BASE * M) / N
@@ -386,7 +382,7 @@ int svga_compute_pll(const struct svga_pll *pll, u32 f_wanted, u16 *m, u16 *n, u
u16 am, an, ar;
u32 f_vco, f_current, delta_current, delta_best;
pr_debug("fb%d: ideal frequency: %d kHz\n", node, (unsigned int) f_wanted);
pr_debug("fb%d: ideal frequency: %d kHz\n", node, (unsigned int)f_wanted);
ar = pll->r_max;
f_vco = f_wanted << ar;
@@ -417,7 +413,7 @@ int svga_compute_pll(const struct svga_pll *pll, u32 f_wanted, u16 *m, u16 *n, u
while ((am <= pll->m_max) && (an <= pll->n_max)) {
f_current = (pll->f_base * am) / an;
delta_current = abs_diff (f_current, f_vco);
delta_current = abs_diff(f_current, f_vco);
if (delta_current < delta_best) {
delta_best = delta_current;
@@ -425,58 +421,55 @@ int svga_compute_pll(const struct svga_pll *pll, u32 f_wanted, u16 *m, u16 *n, u
*n = an;
}
if (f_current <= f_vco) {
am ++;
} else {
an ++;
}
if (f_current <= f_vco)
am++;
else
an++;
}
f_current = (pll->f_base * *m) / *n;
pr_debug("fb%d: found frequency: %d kHz (VCO %d kHz)\n", node, (int) (f_current >> ar), (int) f_current);
pr_debug("fb%d: m = %d n = %d r = %d\n", node, (unsigned int) *m, (unsigned int) *n, (unsigned int) *r);
pr_debug("fb%d: found frequency: %d kHz (VCO %d kHz)\n", node, (int)(f_current >> ar), (int)f_current);
pr_debug("fb%d: m = %d n = %d r = %d\n", node, (unsigned int)*m, (unsigned int)*n, (unsigned int)*r);
return 0;
}
/* ------------------------------------------------------------------------- */
/* Check CRT timing values */
int svga_check_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, int node)
{
u32 value;
var->xres = (var->xres+7)&~7;
var->left_margin = (var->left_margin+7)&~7;
var->right_margin = (var->right_margin+7)&~7;
var->hsync_len = (var->hsync_len+7)&~7;
var->xres = (var->xres + 7) & ~7;
var->left_margin = (var->left_margin + 7) & ~7;
var->right_margin = (var->right_margin + 7) & ~7;
var->hsync_len = (var->hsync_len + 7) & ~7;
/* Check horizontal total */
value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
if (((value / 8) - 5) >= svga_regset_size (tm->h_total_regs))
if (((value / 8) - 5) >= svga_regset_size(tm->h_total_regs))
return -EINVAL;
/* Check horizontal display and blank start */
value = var->xres;
if (((value / 8) - 1) >= svga_regset_size (tm->h_display_regs))
if (((value / 8) - 1) >= svga_regset_size(tm->h_display_regs))
return -EINVAL;
if (((value / 8) - 1) >= svga_regset_size (tm->h_blank_start_regs))
if (((value / 8) - 1) >= svga_regset_size(tm->h_blank_start_regs))
return -EINVAL;
/* Check horizontal sync start */
value = var->xres + var->right_margin;
if (((value / 8) - 1) >= svga_regset_size (tm->h_sync_start_regs))
if (((value / 8) - 1) >= svga_regset_size(tm->h_sync_start_regs))
return -EINVAL;
/* Check horizontal blank end (or length) */
value = var->left_margin + var->right_margin + var->hsync_len;
if ((value == 0) || ((value / 8) >= svga_regset_size (tm->h_blank_end_regs)))
if ((value == 0) || ((value / 8) >= svga_regset_size(tm->h_blank_end_regs)))
return -EINVAL;
/* Check horizontal sync end (or length) */
value = var->hsync_len;
if ((value == 0) || ((value / 8) >= svga_regset_size (tm->h_sync_end_regs)))
if ((value == 0) || ((value / 8) >= svga_regset_size(tm->h_sync_end_regs)))
return -EINVAL;
/* Check vertical total */
@@ -498,12 +491,12 @@ int svga_check_timings(const struct svga_timing_regs *tm, struct fb_var_screenin
/* Check vertical blank end (or length) */
value = var->upper_margin + var->lower_margin + var->vsync_len;
if ((value == 0) || (value >= svga_regset_size (tm->v_blank_end_regs)))
if ((value == 0) || (value >= svga_regset_size(tm->v_blank_end_regs)))
return -EINVAL;
/* Check vertical sync end (or length) */
value = var->vsync_len;
if ((value == 0) || (value >= svga_regset_size (tm->v_sync_end_regs)))
if ((value == 0) || (value >= svga_regset_size(tm->v_sync_end_regs)))
return -EINVAL;
return 0;
@@ -597,18 +590,15 @@ void svga_set_timings(void __iomem *regbase, const struct svga_timing_regs *tm,
vga_w(regbase, VGA_MIS_W, regval);
}
/* ------------------------------------------------------------------------- */
static inline int match_format(const struct svga_fb_format *frm,
struct fb_var_screeninfo *var)
{
int i = 0;
int stored = -EINVAL;
while (frm->bits_per_pixel != SVGA_FORMAT_END_VAL)
{
while (frm->bits_per_pixel != SVGA_FORMAT_END_VAL) {
if ((var->bits_per_pixel == frm->bits_per_pixel) &&
(var->red.length <= frm->red.length) &&
(var->green.length <= frm->green.length) &&
@@ -648,7 +638,6 @@ int svga_match_format(const struct svga_fb_format *frm,
return i;
}
EXPORT_SYMBOL(svga_wcrt_multi);
EXPORT_SYMBOL(svga_wseq_multi);
+7 -2
View File
@@ -996,8 +996,13 @@ static int imxfb_probe(struct platform_device *pdev)
info->fix.smem_start = fbi->map_dma;
INIT_LIST_HEAD(&info->modelist);
for (i = 0; i < fbi->num_modes; i++)
fb_add_videomode(&fbi->mode[i].mode, &info->modelist);
for (i = 0; i < fbi->num_modes; i++) {
ret = fb_add_videomode(&fbi->mode[i].mode, &info->modelist);
if (ret) {
dev_err(&pdev->dev, "Failed to add videomode\n");
goto failed_cmap;
}
}
/*
* This makes sure that our colour bitfield
+12 -12
View File
@@ -679,7 +679,8 @@ static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
return err;
if ((err = pci_enable_device(pdev))) {
err = pcim_enable_device(pdev);
if (err) {
printk(KERN_WARNING "kyrofb: Can't enable pdev: %d\n", err);
return err;
}
@@ -688,6 +689,10 @@ static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (!info)
return -ENOMEM;
err = pcim_request_all_regions(pdev, "kyrofb");
if (err)
goto out_free_fb;
currentpar = info->par;
kyro_fix.smem_start = pci_resource_start(pdev, 0);
@@ -696,13 +701,15 @@ static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
kyro_fix.mmio_len = pci_resource_len(pdev, 1);
currentpar->regbase = deviceInfo.pSTGReg =
ioremap(kyro_fix.mmio_start, kyro_fix.mmio_len);
devm_ioremap(&pdev->dev, kyro_fix.mmio_start,
kyro_fix.mmio_len);
if (!currentpar->regbase)
goto out_free_fb;
info->screen_base = pci_ioremap_wc_bar(pdev, 0);
info->screen_base = devm_ioremap_wc(&pdev->dev, kyro_fix.smem_start,
kyro_fix.smem_len);
if (!info->screen_base)
goto out_unmap_regs;
goto out_free_fb;
if (!nomtrr)
currentpar->wc_cookie = arch_phys_wc_add(kyro_fix.smem_start,
@@ -737,7 +744,7 @@ static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
fb_memset_io(info->screen_base, 0, size);
if (register_framebuffer(info) < 0)
goto out_unmap;
goto out_free_fb;
fb_info(info, "%s frame buffer device, at %dx%d@%d using %ldk/%ldk of VRAM\n",
info->fix.id,
@@ -748,10 +755,6 @@ static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0;
out_unmap:
iounmap(info->screen_base);
out_unmap_regs:
iounmap(currentpar->regbase);
out_free_fb:
framebuffer_release(info);
@@ -773,9 +776,6 @@ static void kyrofb_remove(struct pci_dev *pdev)
deviceInfo.ulNextFreeVidMem = 0;
deviceInfo.ulOverlayOffset = 0;
iounmap(info->screen_base);
iounmap(par->regbase);
arch_phys_wc_del(par->wc_cookie);
unregister_framebuffer(info);
+1 -1
View File
@@ -80,7 +80,7 @@
(par)->dmaFree -= ((size) + 1); \
}
#if defined(__i386__)
#if defined(__i386__) && !defined(CONFIG_UML)
#define _NV_FENCE() outb(0, 0x3D0);
#else
#define _NV_FENCE() mb();
+4 -13
View File
@@ -21,9 +21,9 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_clk.h>
#include <linux/of_platform.h>
#include <linux/of_reserved_mem.h>
#include <linux/parser.h>
#include <linux/pm_domain.h>
#include <linux/regulator/consumer.h>
@@ -134,7 +134,7 @@ struct simplefb_params {
static int simplefb_parse_dt(struct platform_device *pdev,
struct simplefb_params *params)
{
struct device_node *np = pdev->dev.of_node, *mem;
struct device_node *np = pdev->dev.of_node;
int ret;
const char *format;
int i;
@@ -174,19 +174,10 @@ static int simplefb_parse_dt(struct platform_device *pdev,
return -EINVAL;
}
mem = of_parse_phandle(np, "memory-region", 0);
if (mem) {
ret = of_address_to_resource(mem, 0, &params->memory);
if (ret < 0) {
dev_err(&pdev->dev, "failed to parse memory-region\n");
of_node_put(mem);
return ret;
}
ret = of_reserved_mem_region_to_resource(np, 0, &params->memory);
if (!ret) {
if (of_property_present(np, "reg"))
dev_warn(&pdev->dev, "preferring \"memory-region\" over \"reg\" property\n");
of_node_put(mem);
} else {
memset(&params->memory, 0, sizeof(params->memory));
}