mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-22 00:40:03 +00:00
fbdev/simplefb: Request memory region in driver
Requesting the framebuffer memory in simpledrm marks the memory range as busy. This used to be done by the firmware sysfb code, but the driver is the correct place. v2: * store memory region in struct for later cleanup (Javier) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20220125091222.21457-5-tzimmermann@suse.de
This commit is contained in:
parent
8ec6a72da6
commit
748bd5873d
1 changed files with 45 additions and 20 deletions
|
@ -66,16 +66,36 @@ static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct simplefb_par;
|
||||
struct simplefb_par {
|
||||
u32 palette[PSEUDO_PALETTE_SIZE];
|
||||
struct resource *mem;
|
||||
#if defined CONFIG_OF && defined CONFIG_COMMON_CLK
|
||||
bool clks_enabled;
|
||||
unsigned int clk_count;
|
||||
struct clk **clks;
|
||||
#endif
|
||||
#if defined CONFIG_OF && defined CONFIG_REGULATOR
|
||||
bool regulators_enabled;
|
||||
u32 regulator_count;
|
||||
struct regulator **regulators;
|
||||
#endif
|
||||
};
|
||||
|
||||
static void simplefb_clocks_destroy(struct simplefb_par *par);
|
||||
static void simplefb_regulators_destroy(struct simplefb_par *par);
|
||||
|
||||
static void simplefb_destroy(struct fb_info *info)
|
||||
{
|
||||
struct simplefb_par *par = info->par;
|
||||
struct resource *mem = par->mem;
|
||||
|
||||
simplefb_regulators_destroy(info->par);
|
||||
simplefb_clocks_destroy(info->par);
|
||||
if (info->screen_base)
|
||||
iounmap(info->screen_base);
|
||||
|
||||
if (mem)
|
||||
release_mem_region(mem->start, resource_size(mem));
|
||||
}
|
||||
|
||||
static const struct fb_ops simplefb_ops = {
|
||||
|
@ -169,20 +189,6 @@ static int simplefb_parse_pd(struct platform_device *pdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct simplefb_par {
|
||||
u32 palette[PSEUDO_PALETTE_SIZE];
|
||||
#if defined CONFIG_OF && defined CONFIG_COMMON_CLK
|
||||
bool clks_enabled;
|
||||
unsigned int clk_count;
|
||||
struct clk **clks;
|
||||
#endif
|
||||
#if defined CONFIG_OF && defined CONFIG_REGULATOR
|
||||
bool regulators_enabled;
|
||||
u32 regulator_count;
|
||||
struct regulator **regulators;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined CONFIG_OF && defined CONFIG_COMMON_CLK
|
||||
/*
|
||||
* Clock handling code.
|
||||
|
@ -405,7 +411,7 @@ static int simplefb_probe(struct platform_device *pdev)
|
|||
struct simplefb_params params;
|
||||
struct fb_info *info;
|
||||
struct simplefb_par *par;
|
||||
struct resource *mem;
|
||||
struct resource *res, *mem;
|
||||
|
||||
/*
|
||||
* Generic drivers must not be registered if a framebuffer exists.
|
||||
|
@ -430,15 +436,28 @@ static int simplefb_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!mem) {
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "No memory resource\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mem = request_mem_region(res->start, resource_size(res), "simplefb");
|
||||
if (!mem) {
|
||||
/*
|
||||
* We cannot make this fatal. Sometimes this comes from magic
|
||||
* spaces our resource handlers simply don't know about. Use
|
||||
* the I/O-memory resource as-is and try to map that instead.
|
||||
*/
|
||||
dev_warn(&pdev->dev, "simplefb: cannot reserve video memory at %pR\n", res);
|
||||
mem = res;
|
||||
}
|
||||
|
||||
info = framebuffer_alloc(sizeof(struct simplefb_par), &pdev->dev);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
if (!info) {
|
||||
ret = -ENOMEM;
|
||||
goto error_release_mem_region;
|
||||
}
|
||||
platform_set_drvdata(pdev, info);
|
||||
|
||||
par = info->par;
|
||||
|
@ -495,6 +514,9 @@ static int simplefb_probe(struct platform_device *pdev)
|
|||
info->var.xres, info->var.yres,
|
||||
info->var.bits_per_pixel, info->fix.line_length);
|
||||
|
||||
if (mem != res)
|
||||
par->mem = mem; /* release in clean-up handler */
|
||||
|
||||
ret = register_framebuffer(info);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret);
|
||||
|
@ -513,6 +535,9 @@ static int simplefb_probe(struct platform_device *pdev)
|
|||
iounmap(info->screen_base);
|
||||
error_fb_release:
|
||||
framebuffer_release(info);
|
||||
error_release_mem_region:
|
||||
if (mem != res)
|
||||
release_mem_region(mem->start, resource_size(mem));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue