| .. | .. |
|---|
| 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; |
|---|