aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/xilinxfb.c133
1 files changed, 80 insertions, 53 deletions
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
index 9aa754a25218..12d91279996d 100644
--- a/drivers/video/xilinxfb.c
+++ b/drivers/video/xilinxfb.c
@@ -196,23 +196,17 @@ static struct fb_ops xilinxfb_ops =
196 .fb_imageblit = cfb_imageblit, 196 .fb_imageblit = cfb_imageblit,
197}; 197};
198 198
199/* === The device driver === */ 199/* ---------------------------------------------------------------------
200 * Bus independent setup/teardown
201 */
200 202
201static int 203static int xilinxfb_assign(struct device *dev, unsigned long physaddr,
202xilinxfb_drv_probe(struct device *dev) 204 int width_mm, int height_mm, int rotate)
203{ 205{
204 struct platform_device *pdev;
205 struct xilinxfb_platform_data *pdata;
206 struct xilinxfb_drvdata *drvdata; 206 struct xilinxfb_drvdata *drvdata;
207 struct resource *regs_res; 207 int rc;
208 int retval;
209
210 if (!dev)
211 return -EINVAL;
212
213 pdev = to_platform_device(dev);
214 pdata = pdev->dev.platform_data;
215 208
209 /* Allocate the driver data region */
216 drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); 210 drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
217 if (!drvdata) { 211 if (!drvdata) {
218 dev_err(dev, "Couldn't allocate device private record\n"); 212 dev_err(dev, "Couldn't allocate device private record\n");
@@ -221,40 +215,39 @@ xilinxfb_drv_probe(struct device *dev)
221 dev_set_drvdata(dev, drvdata); 215 dev_set_drvdata(dev, drvdata);
222 216
223 /* Map the control registers in */ 217 /* Map the control registers in */
224 regs_res = platform_get_resource(pdev, IORESOURCE_IO, 0); 218 if (!request_mem_region(physaddr, 8, DRIVER_NAME)) {
225 if (!regs_res || (regs_res->end - regs_res->start + 1 < 8)) { 219 dev_err(dev, "Couldn't lock memory region at 0x%08lX\n",
226 dev_err(dev, "Couldn't get registers resource\n"); 220 physaddr);
227 retval = -EFAULT; 221 rc = -ENODEV;
228 goto err_region; 222 goto err_region;
229 } 223 }
230 224 drvdata->regs_phys = physaddr;
231 if (!request_mem_region(regs_res->start, 8, DRIVER_NAME)) { 225 drvdata->regs = ioremap(physaddr, 8);
232 dev_err(dev, "Couldn't lock memory region at 0x%08X\n", 226 if (!drvdata->regs) {
233 regs_res->start); 227 dev_err(dev, "Couldn't lock memory region at 0x%08lX\n",
234 retval = -EBUSY; 228 physaddr);
235 goto err_region; 229 rc = -ENODEV;
230 goto err_map;
236 } 231 }
237 drvdata->regs = (u32 __iomem*) ioremap(regs_res->start, 8);
238 drvdata->regs_phys = regs_res->start;
239 232
240 /* Allocate the framebuffer memory */ 233 /* Allocate the framebuffer memory */
241 drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(FB_SIZE), 234 drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(FB_SIZE),
242 &drvdata->fb_phys, GFP_KERNEL); 235 &drvdata->fb_phys, GFP_KERNEL);
243 if (!drvdata->fb_virt) { 236 if (!drvdata->fb_virt) {
244 dev_err(dev, "Could not allocate frame buffer memory\n"); 237 dev_err(dev, "Could not allocate frame buffer memory\n");
245 retval = -ENOMEM; 238 rc = -ENOMEM;
246 goto err_fbmem; 239 goto err_fbmem;
247 } 240 }
248 241
249 /* Clear (turn to black) the framebuffer */ 242 /* Clear (turn to black) the framebuffer */
250 memset_io((void *) drvdata->fb_virt, 0, FB_SIZE); 243 memset_io(drvdata->fb_virt, 0, FB_SIZE);
251 244
252 /* Tell the hardware where the frame buffer is */ 245 /* Tell the hardware where the frame buffer is */
253 xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys); 246 xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys);
254 247
255 /* Turn on the display */ 248 /* Turn on the display */
256 drvdata->reg_ctrl_default = REG_CTRL_ENABLE; 249 drvdata->reg_ctrl_default = REG_CTRL_ENABLE;
257 if (pdata && pdata->rotate_screen) 250 if (rotate)
258 drvdata->reg_ctrl_default |= REG_CTRL_ROTATE; 251 drvdata->reg_ctrl_default |= REG_CTRL_ROTATE;
259 xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default); 252 xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
260 253
@@ -265,31 +258,29 @@ xilinxfb_drv_probe(struct device *dev)
265 drvdata->info.fix = xilinx_fb_fix; 258 drvdata->info.fix = xilinx_fb_fix;
266 drvdata->info.fix.smem_start = drvdata->fb_phys; 259 drvdata->info.fix.smem_start = drvdata->fb_phys;
267 drvdata->info.pseudo_palette = drvdata->pseudo_palette; 260 drvdata->info.pseudo_palette = drvdata->pseudo_palette;
261 drvdata->info.flags = FBINFO_DEFAULT;
262 drvdata->info.var = xilinx_fb_var;
263
264 xilinx_fb_var.height = height_mm;
265 xilinx_fb_var.width = width_mm;
268 266
269 if (fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0) < 0) { 267 /* Allocate a colour map */
268 rc = fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0);
269 if (rc) {
270 dev_err(dev, "Fail to allocate colormap (%d entries)\n", 270 dev_err(dev, "Fail to allocate colormap (%d entries)\n",
271 PALETTE_ENTRIES_NO); 271 PALETTE_ENTRIES_NO);
272 retval = -EFAULT;
273 goto err_cmap; 272 goto err_cmap;
274 } 273 }
275 274
276 drvdata->info.flags = FBINFO_DEFAULT;
277 if (pdata) {
278 xilinx_fb_var.height = pdata->screen_height_mm;
279 xilinx_fb_var.width = pdata->screen_width_mm;
280 }
281 drvdata->info.var = xilinx_fb_var;
282
283 /* Register new frame buffer */ 275 /* Register new frame buffer */
284 if (register_framebuffer(&drvdata->info) < 0) { 276 rc = register_framebuffer(&drvdata->info);
277 if (rc) {
285 dev_err(dev, "Could not register frame buffer\n"); 278 dev_err(dev, "Could not register frame buffer\n");
286 retval = -EINVAL;
287 goto err_regfb; 279 goto err_regfb;
288 } 280 }
289 281
290 /* Put a banner in the log (for DEBUG) */ 282 /* Put a banner in the log (for DEBUG) */
291 dev_dbg(dev, "regs: phys=%x, virt=%p\n", 283 dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, drvdata->regs);
292 drvdata->regs_phys, drvdata->regs);
293 dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n", 284 dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n",
294 (void*)drvdata->fb_phys, drvdata->fb_virt, FB_SIZE); 285 (void*)drvdata->fb_phys, drvdata->fb_virt, FB_SIZE);
295 return 0; /* success */ 286 return 0; /* success */
@@ -300,30 +291,25 @@ err_regfb:
300err_cmap: 291err_cmap:
301 dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt, 292 dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt,
302 drvdata->fb_phys); 293 drvdata->fb_phys);
303
304 /* Turn off the display */ 294 /* Turn off the display */
305 xilinx_fb_out_be32(drvdata, REG_CTRL, 0); 295 xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
306 iounmap(drvdata->regs);
307 296
308err_fbmem: 297err_fbmem:
309 release_mem_region(regs_res->start, 8); 298 iounmap(drvdata->regs);
299
300err_map:
301 release_mem_region(physaddr, 8);
310 302
311err_region: 303err_region:
312 kfree(drvdata); 304 kfree(drvdata);
313 dev_set_drvdata(dev, NULL); 305 dev_set_drvdata(dev, NULL);
314 306
315 return retval; 307 return rc;
316} 308}
317 309
318static int 310static int xilinxfb_release(struct device *dev)
319xilinxfb_drv_remove(struct device *dev)
320{ 311{
321 struct xilinxfb_drvdata *drvdata; 312 struct xilinxfb_drvdata *drvdata = dev_get_drvdata(dev);
322
323 if (!dev)
324 return -ENODEV;
325
326 drvdata = (struct xilinxfb_drvdata *) dev_get_drvdata(dev);
327 313
328#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) 314#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
329 xilinx_fb_blank(VESA_POWERDOWN, &drvdata->info); 315 xilinx_fb_blank(VESA_POWERDOWN, &drvdata->info);
@@ -348,6 +334,47 @@ xilinxfb_drv_remove(struct device *dev)
348 return 0; 334 return 0;
349} 335}
350 336
337/* ---------------------------------------------------------------------
338 * Platform bus binding
339 */
340
341static int
342xilinxfb_drv_probe(struct device *dev)
343{
344 struct platform_device *pdev;
345 struct xilinxfb_platform_data *pdata;
346 struct resource *res;
347 int width_mm;
348 int height_mm;
349 int rotate;
350
351 pdev = to_platform_device(dev);
352 pdata = pdev->dev.platform_data;
353 if (!pdata) {
354 dev_err(dev, "Missing pdata structure\n");
355 return -ENODEV;
356 }
357
358 /* Find the registers address */
359 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
360 if (!res) {
361 dev_err(dev, "Couldn't get registers resource\n");
362 return -ENODEV;
363 }
364
365 height_mm = pdata->screen_height_mm;
366 width_mm = pdata->screen_width_mm;
367 rotate = pdata->rotate_screen ? 1 : 0;
368
369 return xilinxfb_assign(dev, res->start, width_mm, height_mm, rotate);
370}
371
372static int
373xilinxfb_drv_remove(struct device *dev)
374{
375 return xilinxfb_release(dev);
376}
377
351 378
352static struct device_driver xilinxfb_driver = { 379static struct device_driver xilinxfb_driver = {
353 .name = DRIVER_NAME, 380 .name = DRIVER_NAME,