]>
Commit | Line | Data |
---|---|---|
09d62646 TL |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: Thomas Zimmermann <tzimmermann@suse.de> | |
3 | Date: Tue, 25 Jan 2022 10:12:21 +0100 | |
4 | Subject: [PATCH] fbdev/simplefb: Request memory region in driver | |
5 | ||
6 | Requesting the framebuffer memory in simpledrm marks the memory | |
7 | range as busy. This used to be done by the firmware sysfb code, | |
8 | but the driver is the correct place. | |
9 | ||
10 | v2: | |
11 | * store memory region in struct for later cleanup (Javier) | |
12 | ||
13 | Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> | |
14 | Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> | |
15 | Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com> | |
16 | --- | |
17 | drivers/video/fbdev/simplefb.c | 65 +++++++++++++++++++++++----------- | |
18 | 1 file changed, 45 insertions(+), 20 deletions(-) | |
19 | ||
20 | diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c | |
96f7973c | 21 | index a2e3a4690025..8acfb12abfee 100644 |
09d62646 TL |
22 | --- a/drivers/video/fbdev/simplefb.c |
23 | +++ b/drivers/video/fbdev/simplefb.c | |
96f7973c | 24 | @@ -66,7 +66,21 @@ static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, |
09d62646 TL |
25 | return 0; |
26 | } | |
27 | ||
28 | -struct simplefb_par; | |
29 | +struct simplefb_par { | |
30 | + u32 palette[PSEUDO_PALETTE_SIZE]; | |
31 | + struct resource *mem; | |
32 | +#if defined CONFIG_OF && defined CONFIG_COMMON_CLK | |
33 | + bool clks_enabled; | |
34 | + unsigned int clk_count; | |
35 | + struct clk **clks; | |
36 | +#endif | |
37 | +#if defined CONFIG_OF && defined CONFIG_REGULATOR | |
38 | + bool regulators_enabled; | |
39 | + u32 regulator_count; | |
40 | + struct regulator **regulators; | |
41 | +#endif | |
42 | +}; | |
43 | + | |
44 | static void simplefb_clocks_destroy(struct simplefb_par *par); | |
45 | static void simplefb_regulators_destroy(struct simplefb_par *par); | |
46 | ||
96f7973c TL |
47 | @@ -76,12 +90,18 @@ static void simplefb_regulators_destroy(struct simplefb_par *par); |
48 | */ | |
09d62646 TL |
49 | static void simplefb_destroy(struct fb_info *info) |
50 | { | |
51 | + struct simplefb_par *par = info->par; | |
52 | + struct resource *mem = par->mem; | |
53 | + | |
54 | simplefb_regulators_destroy(info->par); | |
55 | simplefb_clocks_destroy(info->par); | |
56 | if (info->screen_base) | |
57 | iounmap(info->screen_base); | |
96f7973c TL |
58 | |
59 | framebuffer_release(info); | |
09d62646 TL |
60 | + |
61 | + if (mem) | |
62 | + release_mem_region(mem->start, resource_size(mem)); | |
63 | } | |
64 | ||
65 | static const struct fb_ops simplefb_ops = { | |
96f7973c | 66 | @@ -175,20 +195,6 @@ static int simplefb_parse_pd(struct platform_device *pdev, |
09d62646 TL |
67 | return 0; |
68 | } | |
69 | ||
70 | -struct simplefb_par { | |
71 | - u32 palette[PSEUDO_PALETTE_SIZE]; | |
72 | -#if defined CONFIG_OF && defined CONFIG_COMMON_CLK | |
73 | - bool clks_enabled; | |
74 | - unsigned int clk_count; | |
75 | - struct clk **clks; | |
76 | -#endif | |
77 | -#if defined CONFIG_OF && defined CONFIG_REGULATOR | |
78 | - bool regulators_enabled; | |
79 | - u32 regulator_count; | |
80 | - struct regulator **regulators; | |
81 | -#endif | |
82 | -}; | |
83 | - | |
84 | #if defined CONFIG_OF && defined CONFIG_COMMON_CLK | |
85 | /* | |
86 | * Clock handling code. | |
96f7973c | 87 | @@ -411,7 +417,7 @@ static int simplefb_probe(struct platform_device *pdev) |
09d62646 TL |
88 | struct simplefb_params params; |
89 | struct fb_info *info; | |
90 | struct simplefb_par *par; | |
91 | - struct resource *mem; | |
92 | + struct resource *res, *mem; | |
93 | ||
94 | /* | |
95 | * Generic drivers must not be registered if a framebuffer exists. | |
96f7973c | 96 | @@ -436,15 +442,28 @@ static int simplefb_probe(struct platform_device *pdev) |
09d62646 TL |
97 | if (ret) |
98 | return ret; | |
99 | ||
100 | - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
101 | - if (!mem) { | |
102 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
103 | + if (!res) { | |
104 | dev_err(&pdev->dev, "No memory resource\n"); | |
105 | return -EINVAL; | |
106 | } | |
107 | ||
108 | + mem = request_mem_region(res->start, resource_size(res), "simplefb"); | |
109 | + if (!mem) { | |
110 | + /* | |
111 | + * We cannot make this fatal. Sometimes this comes from magic | |
112 | + * spaces our resource handlers simply don't know about. Use | |
113 | + * the I/O-memory resource as-is and try to map that instead. | |
114 | + */ | |
115 | + dev_warn(&pdev->dev, "simplefb: cannot reserve video memory at %pR\n", res); | |
116 | + mem = res; | |
117 | + } | |
118 | + | |
119 | info = framebuffer_alloc(sizeof(struct simplefb_par), &pdev->dev); | |
120 | - if (!info) | |
121 | - return -ENOMEM; | |
122 | + if (!info) { | |
123 | + ret = -ENOMEM; | |
124 | + goto error_release_mem_region; | |
125 | + } | |
126 | platform_set_drvdata(pdev, info); | |
127 | ||
128 | par = info->par; | |
96f7973c | 129 | @@ -501,6 +520,9 @@ static int simplefb_probe(struct platform_device *pdev) |
09d62646 TL |
130 | info->var.xres, info->var.yres, |
131 | info->var.bits_per_pixel, info->fix.line_length); | |
132 | ||
133 | + if (mem != res) | |
134 | + par->mem = mem; /* release in clean-up handler */ | |
135 | + | |
136 | ret = register_framebuffer(info); | |
137 | if (ret < 0) { | |
138 | dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret); | |
96f7973c | 139 | @@ -519,6 +541,9 @@ static int simplefb_probe(struct platform_device *pdev) |
09d62646 TL |
140 | iounmap(info->screen_base); |
141 | error_fb_release: | |
142 | framebuffer_release(info); | |
143 | +error_release_mem_region: | |
144 | + if (mem != res) | |
145 | + release_mem_region(mem->start, resource_size(mem)); | |
146 | return ret; | |
147 | } | |
148 |