.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * framebuffer driver for VBE 2.0 compliant graphic boards |
---|
3 | 4 | * |
---|
.. | .. |
---|
31 | 32 | struct vesafb_par { |
---|
32 | 33 | u32 pseudo_palette[256]; |
---|
33 | 34 | int wc_cookie; |
---|
| 35 | + struct resource *region; |
---|
34 | 36 | }; |
---|
35 | 37 | |
---|
36 | 38 | static struct fb_var_screeninfo vesafb_defined = { |
---|
.. | .. |
---|
336 | 338 | printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal); |
---|
337 | 339 | if (pmi_base[3]) { |
---|
338 | 340 | printk(KERN_INFO "vesafb: pmi: ports = "); |
---|
339 | | - for (i = pmi_base[3]/2; pmi_base[i] != 0xffff; i++) |
---|
340 | | - printk("%x ",pmi_base[i]); |
---|
| 341 | + for (i = pmi_base[3]/2; pmi_base[i] != 0xffff; i++) |
---|
| 342 | + printk("%x ", pmi_base[i]); |
---|
341 | 343 | printk("\n"); |
---|
342 | 344 | if (pmi_base[i] != 0xffff) { |
---|
343 | 345 | /* |
---|
.. | .. |
---|
410 | 412 | |
---|
411 | 413 | /* request failure does not faze us, as vgacon probably has this |
---|
412 | 414 | * region already (FIXME) */ |
---|
413 | | - request_region(0x3c0, 32, "vesafb"); |
---|
| 415 | + par->region = request_region(0x3c0, 32, "vesafb"); |
---|
414 | 416 | |
---|
415 | 417 | if (mtrr == 3) { |
---|
416 | 418 | unsigned int temp_size = size_total; |
---|
.. | .. |
---|
438 | 440 | "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n", |
---|
439 | 441 | vesafb_fix.smem_len, vesafb_fix.smem_start); |
---|
440 | 442 | err = -EIO; |
---|
441 | | - goto err; |
---|
| 443 | + goto err_release_region; |
---|
442 | 444 | } |
---|
443 | 445 | |
---|
444 | 446 | printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, " |
---|
.. | .. |
---|
446 | 448 | vesafb_fix.smem_start, info->screen_base, |
---|
447 | 449 | size_remap/1024, size_total/1024); |
---|
448 | 450 | |
---|
| 451 | + if (!ypan) |
---|
| 452 | + vesafb_ops.fb_pan_display = NULL; |
---|
| 453 | + |
---|
449 | 454 | info->fbops = &vesafb_ops; |
---|
450 | 455 | info->var = vesafb_defined; |
---|
451 | 456 | info->fix = vesafb_fix; |
---|
452 | 457 | info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE | |
---|
453 | 458 | (ypan ? FBINFO_HWACCEL_YPAN : 0); |
---|
454 | 459 | |
---|
455 | | - if (!ypan) |
---|
456 | | - info->fbops->fb_pan_display = NULL; |
---|
457 | | - |
---|
458 | 460 | if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { |
---|
459 | 461 | err = -ENOMEM; |
---|
460 | | - goto err; |
---|
| 462 | + goto err_release_region; |
---|
461 | 463 | } |
---|
462 | 464 | if (register_framebuffer(info)<0) { |
---|
463 | 465 | err = -EINVAL; |
---|
464 | 466 | fb_dealloc_cmap(&info->cmap); |
---|
465 | | - goto err; |
---|
| 467 | + goto err_release_region; |
---|
466 | 468 | } |
---|
467 | 469 | fb_info(info, "%s frame buffer device\n", info->fix.id); |
---|
468 | 470 | return 0; |
---|
469 | | -err: |
---|
| 471 | +err_release_region: |
---|
470 | 472 | arch_phys_wc_del(par->wc_cookie); |
---|
471 | 473 | if (info->screen_base) |
---|
472 | 474 | iounmap(info->screen_base); |
---|
| 475 | + if (par->region) |
---|
| 476 | + release_region(0x3c0, 32); |
---|
| 477 | +err: |
---|
473 | 478 | framebuffer_release(info); |
---|
474 | 479 | release_mem_region(vesafb_fix.smem_start, size_total); |
---|
475 | 480 | return err; |
---|
.. | .. |
---|
480 | 485 | struct fb_info *info = platform_get_drvdata(pdev); |
---|
481 | 486 | |
---|
482 | 487 | unregister_framebuffer(info); |
---|
| 488 | + if (((struct vesafb_par *)(info->par))->region) |
---|
| 489 | + release_region(0x3c0, 32); |
---|
483 | 490 | framebuffer_release(info); |
---|
484 | 491 | |
---|
485 | 492 | return 0; |
---|