Pull fbdev updates from Bartlomiej Zolnierkiewicz: - remove fbdev notifier usage for fbcon (as prep work to clean up the fbcon locking), add locking checks in vt/console code and make assorted cleanups in fbdev and backlight code (Daniel Vetter) - add COMPILE_TEST support to atmel_lcdfb, da8xx-fb, gbefb, imxfb, pvr2fb and pxa168fb drivers (me) - fix DMA API abuse in au1200fb and jz4740_fb drivers (Christoph Hellwig) - add check for new BGRT status field rotation bits in efifb driver (Hans de Goede) - mark expected switch fall-throughs in s3c-fb driver (Gustavo A. R. Silva) - remove fbdev mxsfb driver in favour of the drm version (Fabio Estevam) - remove broken rfbi code from omap2fb driver (me) - misc fixes (Arnd Bergmann, Shobhit Kukreti, Wei Yongjun, me) - misc cleanups (Gustavo A. R. Silva, Colin Ian King, me) * tag 'fbdev-v5.3' of git://github.com/bzolnier/linux: (62 commits) video: fbdev: imxfb: fix a typo in imxfb_probe() video: fbdev: s3c-fb: Mark expected switch fall-throughs video: fbdev: s3c-fb: fix sparse warnings about using incorrect types video: fbdev: don't print error message on framebuffer_alloc() failure video: fbdev: intelfb: return -ENOMEM on framebuffer_alloc() failure video: fbdev: s3c-fb: return -ENOMEM on framebuffer_alloc() failure vga_switcheroo: Depend upon fbcon being built-in, if enabled video: fbdev: omap2: remove rfbi video: fbdev: atmel_lcdfb: remove redundant initialization to variable ret video: fbdev-MMP: Use struct_size() in devm_kzalloc() video: fbdev: controlfb: fix warnings about comparing pointer to 0 efifb: BGRT: Add check for new BGRT status field rotation bits jz4740_fb: fix DMA API abuse video: fbdev: pvr2fb: fix link error for pvr2fb_pci_exit video: fbdev: s3c-fb: add COMPILE_TEST support video: fbdev: imxfb: fix sparse warnings about using incorrect types video: fbdev: pvr2fb: fix build warning when compiling as module fbcon: Export fbcon_update_vcs backlight: simplify lcd notifier staging/olpc_dcon: Add drm conversion to TODO ...
Unified · Split
| @@ -347,8 +347,17 @@ int __init am200_init(void) · 346 unmodified lines | ||
| 347 | 347 | { |
| 348 | 348 | int ret; |
| 349 | 349 | |
| 350 | − /* before anything else, we request notification for any fb | |
| 351 | − * creation events */ | |
| 350 | + /* | |
| 351 | + * Before anything else, we request notification for any fb | |
| 352 | + * creation events. | |
| 353 | + * | |
| 354 | + * FIXME: This is terrible and needs to be nuked. The notifier is used | |
| 355 | + * to get at the fb base address from the boot splash fb driver, which | |
| 356 | + * is then passed to metronomefb. Instaed of metronomfb or this board | |
| 357 | + * support file here figuring this out on their own. | |
| 358 | + * | |
| 359 | + * See also the #ifdef in fbmem.c. | |
| 360 | + */ | |
| 352 | 361 | fb_register_client(&am200_fb_notif); |
| 353 | 362 | |
| 354 | 363 | pxa2xx_mfp_config(ARRAY_AND_SIZE(am200_pin_config)); |
| @@ -23,6 +23,7 @@ config VGA_SWITCHEROO · 22 unmodified lines | ||
| 23 | 23 | depends on X86 |
| 24 | 24 | depends on ACPI |
| 25 | 25 | depends on PCI |
| 26 | + depends on (FRAMEBUFFER_CONSOLE=n || FB=y) | |
| 26 | 27 | select VGA_ARB |
| 27 | 28 | help |
| 28 | 29 | Many laptops released in 2008/9/10 have two GPUs with a multiplexer |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | #include <linux/debugfs.h> |
| 36 | 36 | #include <linux/fb.h> |
| 37 | 37 | #include <linux/fs.h> |
| 38 | +#include <linux/fbcon.h> | |
| 38 | 39 | #include <linux/module.h> |
| 39 | 40 | #include <linux/pci.h> |
| 40 | 41 | #include <linux/pm_domain.h> |
| @@ -736,14 +737,8 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) · 695 unmodified lines | ||
| 736 | 737 | if (!active->driver_power_control) |
| 737 | 738 | set_audio_state(active->id, VGA_SWITCHEROO_OFF); |
| 738 | 739 | |
| 739 | − if (new_client->fb_info) { | |
| 740 | − struct fb_event event; | |
| 741 | − | |
| 742 | − console_lock(); | |
| 743 | − event.info = new_client->fb_info; | |
| 744 | − fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event); | |
| 745 | − console_unlock(); | |
| 746 | − } | |
| 740 | + if (new_client->fb_info) | |
| 741 | + fbcon_remap_all(new_client->fb_info); | |
| 747 | 742 | |
| 748 | 743 | mutex_lock(&vgasr_priv.mux_hw_lock); |
| 749 | 744 | ret = vgasr_priv.handler->switchto(new_client->id); |
| @@ -512,10 +512,8 @@ int picolcd_init_framebuffer(struct picolcd_data *data) · 511 unmodified lines | ||
| 512 | 512 | sizeof(struct fb_deferred_io) + |
| 513 | 513 | sizeof(struct picolcd_fb_data) + |
| 514 | 514 | PICOLCDFB_SIZE, dev); |
| 515 | − if (info == NULL) { | |
| 516 | − dev_err(dev, "failed to allocate a framebuffer\n"); | |
| 515 | + if (!info) | |
| 517 | 516 | goto err_nomem; |
| 518 | − } | |
| 519 | 517 | |
| 520 | 518 | info->fbdefio = info->par; |
| 521 | 519 | *info->fbdefio = picolcd_fb_defio; |
| @@ -1256,11 +1256,7 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p) · 1255 unmodified lines | ||
| 1256 | 1256 | itv->streams[IVTV_DEC_STREAM_TYPE_MPG].vdev.device_caps &= |
| 1257 | 1257 | ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY; |
| 1258 | 1258 | itv->v4l2_cap &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY; |
| 1259 | − if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) { | |
| 1260 | − IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n", | |
| 1261 | − itv->instance); | |
| 1262 | − return 0; | |
| 1263 | − } | |
| 1259 | + unregister_framebuffer(&itv->osd_info->ivtvfb_info); | |
| 1264 | 1260 | IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance); |
| 1265 | 1261 | itv->ivtvfb_restore = NULL; |
| 1266 | 1262 | ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info); |
| @@ -891,7 +891,9 @@ int fbtft_unregister_framebuffer(struct fb_info *fb_info) · 890 unmodified lines | ||
| 891 | 891 | if (par->fbtftops.unregister_backlight) |
| 892 | 892 | par->fbtftops.unregister_backlight(par); |
| 893 | 893 | fbtft_sysfs_exit(par); |
| 894 | − return unregister_framebuffer(fb_info); | |
| 894 | + unregister_framebuffer(fb_info); | |
| 895 | + | |
| 896 | + return 0; | |
| 895 | 897 | } |
| 896 | 898 | EXPORT_SYMBOL(fbtft_unregister_framebuffer); |
| 897 | 899 | |
| @@ -1,4 +1,11 @@ | ||
| 1 | 1 | TODO: |
| 2 | + - complete rewrite: | |
| 3 | + 1. The underlying fbdev drivers need to be converted into drm kernel | |
| 4 | + modesetting drivers. | |
| 5 | + 2. The dcon low-power display mode can then be integrated using the | |
| 6 | + drm damage tracking and self-refresh helpers. | |
| 7 | + This bolted-on self-refresh support that digs around in fbdev | |
| 8 | + internals, but isn't properly integrated, is not the correct solution. | |
| 2 | 9 | - see if vx855 gpio API can be made similar enough to cs5535 so we can |
| 3 | 10 | share more code |
| 4 | 11 | - convert all uses of the old GPIO API from <linux/gpio.h> to the |
| @@ -250,11 +250,7 @@ static bool dcon_blank_fb(struct dcon_priv *dcon, bool blank) · 249 unmodified lines | ||
| 250 | 250 | int err; |
| 251 | 251 | |
| 252 | 252 | console_lock(); |
| 253 | − if (!lock_fb_info(dcon->fbinfo)) { | |
| 254 | − console_unlock(); | |
| 255 | − dev_err(&dcon->client->dev, "unable to lock framebuffer\n"); | |
| 256 | − return false; | |
| 257 | − } | |
| 253 | + lock_fb_info(dcon->fbinfo); | |
| 258 | 254 | |
| 259 | 255 | dcon->ignore_fb_events = true; |
| 260 | 256 | err = fb_blank(dcon->fbinfo, |
| @@ -3822,6 +3822,8 @@ int con_is_bound(const struct consw *csw) · 3821 unmodified lines | ||
| 3822 | 3822 | { |
| 3823 | 3823 | int i, bound = 0; |
| 3824 | 3824 | |
| 3825 | + WARN_CONSOLE_UNLOCKED(); | |
| 3826 | + | |
| 3825 | 3827 | for (i = 0; i < MAX_NR_CONSOLES; i++) { |
| 3826 | 3828 | if (con_driver_map[i] == csw) { |
| 3827 | 3829 | bound = 1; |
| @@ -3833,6 +3835,20 @@ int con_is_bound(const struct consw *csw) · 5 unmodified lines | ||
| 3833 | 3835 | } |
| 3834 | 3836 | EXPORT_SYMBOL(con_is_bound); |
| 3835 | 3837 | |
| 3838 | +/** | |
| 3839 | + * con_is_visible - checks whether the current console is visible | |
| 3840 | + * @vc: virtual console | |
| 3841 | + * | |
| 3842 | + * RETURNS: zero if not visible, nonzero if visible | |
| 3843 | + */ | |
| 3844 | +bool con_is_visible(const struct vc_data *vc) | |
| 3845 | +{ | |
| 3846 | + WARN_CONSOLE_UNLOCKED(); | |
| 3847 | + | |
| 3848 | + return *vc->vc_display_fg == vc; | |
| 3849 | +} | |
| 3850 | +EXPORT_SYMBOL(con_is_visible); | |
| 3851 | + | |
| 3836 | 3852 | /** |
| 3837 | 3853 | * con_debug_enter - prepare the console for the kernel debugger |
| 3838 | 3854 | * @sw: console driver |
| @@ -4166,6 +4182,8 @@ void do_blank_screen(int entering_gfx) · 327 unmodified lines | ||
| 4166 | 4182 | struct vc_data *vc = vc_cons[fg_console].d; |
| 4167 | 4183 | int i; |
| 4168 | 4184 | |
| 4185 | + might_sleep(); | |
| 4186 | + | |
| 4169 | 4187 | WARN_CONSOLE_UNLOCKED(); |
| 4170 | 4188 | |
| 4171 | 4189 | if (console_blanked) { |
| @@ -47,7 +47,7 @@ static int fb_notifier_callback(struct notifier_block *self, · 46 unmodified lines | ||
| 47 | 47 | int fb_blank = 0; |
| 48 | 48 | |
| 49 | 49 | /* If we aren't interested in this event, skip it immediately ... */ |
| 50 | − if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK) | |
| 50 | + if (event != FB_EVENT_BLANK) | |
| 51 | 51 | return 0; |
| 52 | 52 | |
| 53 | 53 | bd = container_of(self, struct backlight_device, fb_notif); |
| @@ -30,18 +30,6 @@ static int fb_notifier_callback(struct notifier_block *self, · 29 unmodified lines | ||
| 30 | 30 | struct lcd_device *ld; |
| 31 | 31 | struct fb_event *evdata = data; |
| 32 | 32 | |
| 33 | − /* If we aren't interested in this event, skip it immediately ... */ | |
| 34 | − switch (event) { | |
| 35 | − case FB_EVENT_BLANK: | |
| 36 | − case FB_EVENT_MODE_CHANGE: | |
| 37 | − case FB_EVENT_MODE_CHANGE_ALL: | |
| 38 | − case FB_EARLY_EVENT_BLANK: | |
| 39 | − case FB_R_EARLY_EVENT_BLANK: | |
| 40 | − break; | |
| 41 | − default: | |
| 42 | − return 0; | |
| 43 | − } | |
| 44 | − | |
| 45 | 33 | ld = container_of(self, struct lcd_device, fb_notif); |
| 46 | 34 | if (!ld->ops) |
| 47 | 35 | return 0; |
| @@ -34,6 +34,8 @@ static bool dummycon_putc_called; · 33 unmodified lines | ||
| 34 | 34 | |
| 35 | 35 | void dummycon_register_output_notifier(struct notifier_block *nb) |
| 36 | 36 | { |
| 37 | + WARN_CONSOLE_UNLOCKED(); | |
| 38 | + | |
| 37 | 39 | raw_notifier_chain_register(&dummycon_output_nh, nb); |
| 38 | 40 | |
| 39 | 41 | if (dummycon_putc_called) |
| @@ -42,11 +44,15 @@ void dummycon_register_output_notifier(struct notifier_block *nb) · 2 unmodified lines | ||
| 42 | 44 | |
| 43 | 45 | void dummycon_unregister_output_notifier(struct notifier_block *nb) |
| 44 | 46 | { |
| 47 | + WARN_CONSOLE_UNLOCKED(); | |
| 48 | + | |
| 45 | 49 | raw_notifier_chain_unregister(&dummycon_output_nh, nb); |
| 46 | 50 | } |
| 47 | 51 | |
| 48 | 52 | static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos) |
| 49 | 53 | { |
| 54 | + WARN_CONSOLE_UNLOCKED(); | |
| 55 | + | |
| 50 | 56 | dummycon_putc_called = true; |
| 51 | 57 | raw_notifier_call_chain(&dummycon_output_nh, 0, NULL); |
| 52 | 58 | } |
| @@ -332,7 +332,8 @@ config FB_SA1100 · 331 unmodified lines | ||
| 332 | 332 | |
| 333 | 333 | config FB_IMX |
| 334 | 334 | tristate "Freescale i.MX1/21/25/27 LCD support" |
| 335 | − depends on FB && ARCH_MXC | |
| 335 | + depends on FB && HAVE_CLK && HAS_IOMEM | |
| 336 | + depends on ARCH_MXC || COMPILE_TEST | |
| 336 | 337 | select LCD_CLASS_DEVICE |
| 337 | 338 | select FB_CFB_FILLRECT |
| 338 | 339 | select FB_CFB_COPYAREA |
| @@ -670,7 +671,8 @@ config FB_HGA · 331 unmodified lines | ||
| 670 | 671 | |
| 671 | 672 | config FB_GBE |
| 672 | 673 | bool "SGI Graphics Backend frame buffer support" |
| 673 | − depends on (FB = y) && SGI_IP32 | |
| 674 | + depends on (FB = y) && HAS_IOMEM | |
| 675 | + depends on SGI_IP32 || COMPILE_TEST | |
| 674 | 676 | select FB_CFB_FILLRECT |
| 675 | 677 | select FB_CFB_COPYAREA |
| 676 | 678 | select FB_CFB_IMAGEBLIT |
| @@ -808,7 +810,8 @@ config FB_XVR1000 · 131 unmodified lines | ||
| 808 | 810 | |
| 809 | 811 | config FB_PVR2 |
| 810 | 812 | tristate "NEC PowerVR 2 display support" |
| 811 | − depends on FB && SH_DREAMCAST | |
| 813 | + depends on FB && HAS_IOMEM | |
| 814 | + depends on SH_DREAMCAST || COMPILE_TEST | |
| 812 | 815 | select FB_CFB_FILLRECT |
| 813 | 816 | select FB_CFB_COPYAREA |
| 814 | 817 | select FB_CFB_IMAGEBLIT |
| @@ -856,7 +859,8 @@ config FB_S1D13XXX · 41 unmodified lines | ||
| 856 | 859 | |
| 857 | 860 | config FB_ATMEL |
| 858 | 861 | tristate "AT91 LCD Controller support" |
| 859 | − depends on FB && OF && HAVE_FB_ATMEL | |
| 862 | + depends on FB && OF && HAVE_CLK && HAS_IOMEM | |
| 863 | + depends on HAVE_FB_ATMEL || COMPILE_TEST | |
| 860 | 864 | select FB_BACKLIGHT |
| 861 | 865 | select FB_CFB_FILLRECT |
| 862 | 866 | select FB_CFB_COPYAREA |
| @@ -1729,7 +1733,8 @@ config FB_68328 · 866 unmodified lines | ||
| 1729 | 1733 | |
| 1730 | 1734 | config FB_PXA168 |
| 1731 | 1735 | tristate "PXA168/910 LCD framebuffer support" |
| 1732 | − depends on FB && (CPU_PXA168 || CPU_PXA910) | |
| 1736 | + depends on FB && HAVE_CLK && HAS_IOMEM | |
| 1737 | + depends on CPU_PXA168 || CPU_PXA910 || COMPILE_TEST | |
| 1733 | 1738 | select FB_CFB_FILLRECT |
| 1734 | 1739 | select FB_CFB_COPYAREA |
| 1735 | 1740 | select FB_CFB_IMAGEBLIT |
| @@ -1873,7 +1878,8 @@ config FB_TMIO_ACCELL · 137 unmodified lines | ||
| 1873 | 1878 | |
| 1874 | 1879 | config FB_S3C |
| 1875 | 1880 | tristate "Samsung S3C framebuffer support" |
| 1876 | − depends on FB && (CPU_S3C2416 || ARCH_S3C64XX) | |
| 1881 | + depends on FB && HAVE_CLK && HAS_IOMEM | |
| 1882 | + depends on (CPU_S3C2416 || ARCH_S3C64XX) || COMPILE_TEST | |
| 1877 | 1883 | select FB_CFB_FILLRECT |
| 1878 | 1884 | select FB_CFB_COPYAREA |
| 1879 | 1885 | select FB_CFB_IMAGEBLIT |
| @@ -2055,7 +2061,8 @@ config FB_SH7760 · 175 unmodified lines | ||
| 2055 | 2061 | |
| 2056 | 2062 | config FB_DA8XX |
| 2057 | 2063 | tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support" |
| 2058 | − depends on FB && (ARCH_DAVINCI_DA8XX || SOC_AM33XX) | |
| 2064 | + depends on FB && HAVE_CLK && HAS_IOMEM | |
| 2065 | + depends on ARCH_DAVINCI_DA8XX || SOC_AM33XX || COMPILE_TEST | |
| 2059 | 2066 | select FB_CFB_FILLRECT |
| 2060 | 2067 | select FB_CFB_COPYAREA |
| 2061 | 2068 | select FB_CFB_IMAGEBLIT |
| @@ -2172,7 +2179,7 @@ config FB_EP93XX · 110 unmodified lines | ||
| 2172 | 2179 | |
| 2173 | 2180 | config FB_PRE_INIT_FB |
| 2174 | 2181 | bool "Don't reinitialize, use bootloader's GDC/Display configuration" |
| 2175 | − depends on FB && (FB_MB862XX_LIME || FB_MXS) | |
| 2182 | + depends on FB && FB_MB862XX_LIME | |
| 2176 | 2183 | ---help--- |
| 2177 | 2184 | Select this option if display contents should be inherited as set by |
| 2178 | 2185 | the bootloader. |
| @@ -2213,17 +2220,6 @@ config FB_JZ4740 · 34 unmodified lines | ||
| 2213 | 2220 | help |
| 2214 | 2221 | Framebuffer support for the JZ4740 SoC. |
| 2215 | 2222 | |
| 2216 | −config FB_MXS | |
| 2217 | − tristate "MXS LCD framebuffer support" | |
| 2218 | − depends on FB && (ARCH_MXS || ARCH_MXC) | |
| 2219 | − select FB_CFB_FILLRECT | |
| 2220 | − select FB_CFB_COPYAREA | |
| 2221 | − select FB_CFB_IMAGEBLIT | |
| 2222 | − select FB_MODE_HELPERS | |
| 2223 | − select VIDEOMODE_HELPERS | |
| 2224 | − help | |
| 2225 | − Framebuffer support for the MXS SoC. | |
| 2226 | − | |
| 2227 | 2223 | config FB_PUV3_UNIGFX |
| 2228 | 2224 | tristate "PKUnity v3 Unigfx framebuffer support" |
| 2229 | 2225 | depends on FB && UNICORE32 && ARCH_PUV3 |
| @@ -131,7 +131,6 @@ obj-$(CONFIG_FB_VGA16) += vga16fb.o · 130 unmodified lines | ||
| 131 | 131 | obj-$(CONFIG_FB_OF) += offb.o |
| 132 | 132 | obj-$(CONFIG_FB_MX3) += mx3fb.o |
| 133 | 133 | obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o |
| 134 | −obj-$(CONFIG_FB_MXS) += mxsfb.o | |
| 135 | 134 | obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o |
| 136 | 135 | obj-$(CONFIG_FB_SIMPLE) += simplefb.o |
| 137 | 136 | |
| @@ -3554,10 +3554,8 @@ static int __init amifb_probe(struct platform_device *pdev) · 3553 unmodified lines | ||
| 3554 | 3554 | custom.dmacon = DMAF_ALL | DMAF_MASTER; |
| 3555 | 3555 | |
| 3556 | 3556 | info = framebuffer_alloc(sizeof(struct amifb_par), &pdev->dev); |
| 3557 | − if (!info) { | |
| 3558 | − dev_err(&pdev->dev, "framebuffer_alloc failed\n"); | |
| 3557 | + if (!info) | |
| 3559 | 3558 | return -ENOMEM; |
| 3560 | − } | |
| 3561 | 3559 | |
| 3562 | 3560 | strcpy(info->fix.id, "Amiga "); |
| 3563 | 3561 | info->fix.visual = FB_VISUAL_PSEUDOCOLOR; |
| @@ -954,10 +954,8 @@ static int ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) · 953 unmodified lines | ||
| 954 | 954 | |
| 955 | 955 | /* Allocate and fill driver data structure */ |
| 956 | 956 | info = framebuffer_alloc(sizeof(struct arkfb_info), &(dev->dev)); |
| 957 | − if (! info) { | |
| 958 | − dev_err(&(dev->dev), "cannot allocate memory\n"); | |
| 957 | + if (!info) | |
| 959 | 958 | return -ENOMEM; |
| 960 | − } | |
| 961 | 959 | |
| 962 | 960 | par = info->par; |
| 963 | 961 | mutex_init(&par->open_lock); |
| @@ -77,29 +77,8 @@ · 76 unmodified lines | ||
| 77 | 77 | #define SWITCH_SND7 0x80 |
| 78 | 78 | #define SWITCH_NONE 0x00 |
| 79 | 79 | |
| 80 | − | |
| 81 | 80 | #define up(x, r) (((x) + (r) - 1) & ~((r)-1)) |
| 82 | 81 | |
| 83 | − /* | |
| 84 | − * Interface to the world | |
| 85 | − */ | |
| 86 | − | |
| 87 | −static int atafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info); | |
| 88 | −static int atafb_set_par(struct fb_info *info); | |
| 89 | −static int atafb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, | |
| 90 | − unsigned int blue, unsigned int transp, | |
| 91 | − struct fb_info *info); | |
| 92 | −static int atafb_blank(int blank, struct fb_info *info); | |
| 93 | −static int atafb_pan_display(struct fb_var_screeninfo *var, | |
| 94 | − struct fb_info *info); | |
| 95 | −static void atafb_fillrect(struct fb_info *info, | |
| 96 | − const struct fb_fillrect *rect); | |
| 97 | −static void atafb_copyarea(struct fb_info *info, | |
| 98 | − const struct fb_copyarea *region); | |
| 99 | −static void atafb_imageblit(struct fb_info *info, const struct fb_image *image); | |
| 100 | −static int atafb_ioctl(struct fb_info *info, unsigned int cmd, | |
| 101 | − unsigned long arg); | |
| 102 | − | |
| 103 | 82 | |
| 104 | 83 | static int default_par; /* default resolution (0=none) */ |
| 105 | 84 | |
| @@ -673,7 +673,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) · 672 unmodified lines | ||
| 673 | 673 | lcdc_writel(sinfo, ATMEL_LCDC_MVAL, 0); |
| 674 | 674 | |
| 675 | 675 | /* Disable all interrupts */ |
| 676 | − lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL); | |
| 676 | + lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0U); | |
| 677 | 677 | /* Enable FIFO & DMA errors */ |
| 678 | 678 | lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI | ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI); |
| 679 | 679 | |
| @@ -950,7 +950,7 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo) · 270 unmodified lines | ||
| 950 | 950 | struct fb_videomode fb_vm; |
| 951 | 951 | struct gpio_desc *gpiod; |
| 952 | 952 | struct videomode vm; |
| 953 | − int ret = -ENOENT; | |
| 953 | + int ret; | |
| 954 | 954 | int i; |
| 955 | 955 | |
| 956 | 956 | sinfo->config = (struct atmel_lcdfb_config*) |
| @@ -1053,10 +1053,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) · 96 unmodified lines | ||
| 1053 | 1053 | |
| 1054 | 1054 | ret = -ENOMEM; |
| 1055 | 1055 | info = framebuffer_alloc(sizeof(struct atmel_lcdfb_info), dev); |
| 1056 | − if (!info) { | |
| 1057 | − dev_err(dev, "cannot allocate memory\n"); | |
| 1056 | + if (!info) | |
| 1058 | 1057 | goto out; |
| 1059 | − } | |
| 1060 | 1058 | |
| 1061 | 1059 | sinfo = info->par; |
| 1062 | 1060 | sinfo->pdev = pdev; |
| @@ -1291,7 +1289,7 @@ static int atmel_lcdfb_suspend(struct platform_device *pdev, pm_message_t mesg) · 228 unmodified lines | ||
| 1291 | 1289 | * We don't want to handle interrupts while the clock is |
| 1292 | 1290 | * stopped. It may take forever. |
| 1293 | 1291 | */ |
| 1294 | − lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL); | |
| 1292 | + lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0U); | |
| 1295 | 1293 | |
| 1296 | 1294 | sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_CTR); |
| 1297 | 1295 | lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0); |
| @@ -2103,10 +2103,9 @@ static int aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 2102 unmodified lines | ||
| 2103 | 2103 | |
| 2104 | 2104 | /* We have the resources. Now virtualize them */ |
| 2105 | 2105 | info = framebuffer_alloc(sizeof(struct aty128fb_par), &pdev->dev); |
| 2106 | − if (info == NULL) { | |
| 2107 | − printk(KERN_ERR "aty128fb: can't alloc fb_info_aty128\n"); | |
| 2106 | + if (!info) | |
| 2108 | 2107 | goto err_free_mmio; |
| 2109 | − } | |
| 2108 | + | |
| 2110 | 2109 | par = info->par; |
| 2111 | 2110 | |
| 2112 | 2111 | info->pseudo_palette = par->pseudo_palette; |
| @@ -2350,70 +2349,6 @@ static int aty128fb_ioctl(struct fb_info *info, u_int cmd, u_long arg) · 237 unmodified lines | ||
| 2350 | 2349 | return -EINVAL; |
| 2351 | 2350 | } |
| 2352 | 2351 | |
| 2353 | −#if 0 | |
| 2354 | − /* | |
| 2355 | − * Accelerated functions | |
| 2356 | − */ | |
| 2357 | − | |
| 2358 | −static inline void aty128_rectcopy(int srcx, int srcy, int dstx, int dsty, | |
| 2359 | − u_int width, u_int height, | |
| 2360 | − struct fb_info_aty128 *par) | |
| 2361 | −{ | |
| 2362 | − u32 save_dp_datatype, save_dp_cntl, dstval; | |
| 2363 | − | |
| 2364 | − if (!width || !height) | |
| 2365 | − return; | |
| 2366 | − | |
| 2367 | − dstval = depth_to_dst(par->current_par.crtc.depth); | |
| 2368 | − if (dstval == DST_24BPP) { | |
| 2369 | − srcx *= 3; | |
| 2370 | − dstx *= 3; | |
| 2371 | − width *= 3; | |
| 2372 | − } else if (dstval == -EINVAL) { | |
| 2373 | − printk("aty128fb: invalid depth or RGBA\n"); | |
| 2374 | − return; | |
| 2375 | − } | |
| 2376 | − | |
| 2377 | − wait_for_fifo(2, par); | |
| 2378 | − save_dp_datatype = aty_ld_le32(DP_DATATYPE); | |
| 2379 | − save_dp_cntl = aty_ld_le32(DP_CNTL); | |
| 2380 | − | |
| 2381 | − wait_for_fifo(6, par); | |
| 2382 | − aty_st_le32(SRC_Y_X, (srcy << 16) | srcx); | |
| 2383 | − aty_st_le32(DP_MIX, ROP3_SRCCOPY | DP_SRC_RECT); | |
| 2384 | − aty_st_le32(DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM); | |
| 2385 | − aty_st_le32(DP_DATATYPE, save_dp_datatype | dstval | SRC_DSTCOLOR); | |
| 2386 | − | |
| 2387 | − aty_st_le32(DST_Y_X, (dsty << 16) | dstx); | |
| 2388 | − aty_st_le32(DST_HEIGHT_WIDTH, (height << 16) | width); | |
| 2389 | − | |
| 2390 | − par->blitter_may_be_busy = 1; | |
| 2391 | − | |
| 2392 | − wait_for_fifo(2, par); | |
| 2393 | − aty_st_le32(DP_DATATYPE, save_dp_datatype); | |
| 2394 | − aty_st_le32(DP_CNTL, save_dp_cntl); | |
| 2395 | −} | |
| 2396 | − | |
| 2397 | − | |
| 2398 | − /* | |
| 2399 | − * Text mode accelerated functions | |
| 2400 | − */ | |
| 2401 | − | |
| 2402 | −static void fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy, | |
| 2403 | − int dx, int height, int width) | |
| 2404 | −{ | |
| 2405 | − sx *= fontwidth(p); | |
| 2406 | − sy *= fontheight(p); | |
| 2407 | − dx *= fontwidth(p); | |
| 2408 | − dy *= fontheight(p); | |
| 2409 | − width *= fontwidth(p); | |
| 2410 | − height *= fontheight(p); | |
| 2411 | − | |
| 2412 | − aty128_rectcopy(sx, sy, dx, dy, width, height, | |
| 2413 | − (struct fb_info_aty128 *)p->fb_info); | |
| 2414 | −} | |
| 2415 | −#endif /* 0 */ | |
| 2416 | − | |
| 2417 | 2352 | static void aty128_set_suspend(struct aty128fb_par *par, int suspend) |
| 2418 | 2353 | { |
| 2419 | 2354 | u32 pmgt; |
| @@ -3550,10 +3550,9 @@ static int atyfb_pci_probe(struct pci_dev *pdev, · 3549 unmodified lines | ||
| 3550 | 3550 | |
| 3551 | 3551 | /* Allocate framebuffer */ |
| 3552 | 3552 | info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev); |
| 3553 | − if (!info) { | |
| 3554 | − PRINTKE("atyfb_pci_probe() can't alloc fb_info\n"); | |
| 3553 | + if (!info) | |
| 3555 | 3554 | return -ENOMEM; |
| 3556 | − } | |
| 3555 | + | |
| 3557 | 3556 | par = info->par; |
| 3558 | 3557 | par->bus_type = PCI; |
| 3559 | 3558 | info->fix = atyfb_fix; |
| @@ -3643,10 +3642,9 @@ static int __init atyfb_atari_probe(void) · 83 unmodified lines | ||
| 3643 | 3642 | } |
| 3644 | 3643 | |
| 3645 | 3644 | info = framebuffer_alloc(sizeof(struct atyfb_par), NULL); |
| 3646 | − if (!info) { | |
| 3647 | − PRINTKE("atyfb_atari_probe() can't alloc fb_info\n"); | |
| 3645 | + if (!info) | |
| 3648 | 3646 | return -ENOMEM; |
| 3649 | − } | |
| 3647 | + | |
| 3650 | 3648 | par = info->par; |
| 3651 | 3649 | |
| 3652 | 3650 | info->fix = atyfb_fix; |
| @@ -3916,8 +3914,7 @@ static int atyfb_reboot_notify(struct notifier_block *nb, · 263 unmodified lines | ||
| 3916 | 3914 | if (!reboot_info) |
| 3917 | 3915 | goto out; |
| 3918 | 3916 | |
| 3919 | − if (!lock_fb_info(reboot_info)) | |
| 3920 | − goto out; | |
| 3917 | + lock_fb_info(reboot_info); | |
| 3921 | 3918 | |
| 3922 | 3919 | par = reboot_info->par; |
| 3923 | 3920 | |
| @@ -2294,8 +2294,6 @@ static int radeonfb_pci_register(struct pci_dev *pdev, · 2293 unmodified lines | ||
| 2294 | 2294 | |
| 2295 | 2295 | info = framebuffer_alloc(sizeof(struct radeonfb_info), &pdev->dev); |
| 2296 | 2296 | if (!info) { |
| 2297 | − printk (KERN_ERR "radeonfb (%s): could not allocate memory\n", | |
| 2298 | − pci_name(pdev)); | |
| 2299 | 2297 | ret = -ENOMEM; |
| 2300 | 2298 | goto err_disable; |
| 2301 | 2299 | } |
| @@ -147,6 +147,7 @@ struct au1200_lcd_iodata_t { · 146 unmodified lines | ||
| 147 | 147 | struct au1200fb_device { |
| 148 | 148 | struct fb_info *fb_info; /* FB driver info record */ |
| 149 | 149 | struct au1200fb_platdata *pd; |
| 150 | + struct device *dev; | |
| 150 | 151 | |
| 151 | 152 | int plane; |
| 152 | 153 | unsigned char* fb_mem; /* FrameBuffer memory map */ |
| @@ -1232,10 +1233,8 @@ static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) · 1079 unmodified lines | ||
| 1232 | 1233 | { |
| 1233 | 1234 | struct au1200fb_device *fbdev = info->par; |
| 1234 | 1235 | |
| 1235 | − vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | |
| 1236 | − pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */ | |
| 1237 | − | |
| 1238 | − return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len); | |
| 1236 | + return dma_mmap_attrs(fbdev->dev, vma, fbdev->fb_mem, fbdev->fb_phys, | |
| 1237 | + fbdev->fb_len, DMA_ATTR_NON_CONSISTENT); | |
| 1239 | 1238 | } |
| 1240 | 1239 | |
| 1241 | 1240 | static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) |
| @@ -1647,7 +1646,6 @@ static int au1200fb_drv_probe(struct platform_device *dev) · 405 unmodified lines | ||
| 1647 | 1646 | struct au1200fb_device *fbdev; |
| 1648 | 1647 | struct au1200fb_platdata *pd; |
| 1649 | 1648 | struct fb_info *fbi = NULL; |
| 1650 | − unsigned long page; | |
| 1651 | 1649 | int bpp, plane, ret, irq; |
| 1652 | 1650 | |
| 1653 | 1651 | print_info("" DRIVER_DESC ""); |
| @@ -1685,6 +1683,7 @@ static int au1200fb_drv_probe(struct platform_device *dev) · 31 unmodified lines | ||
| 1685 | 1683 | fbdev = fbi->par; |
| 1686 | 1684 | fbdev->fb_info = fbi; |
| 1687 | 1685 | fbdev->pd = pd; |
| 1686 | + fbdev->dev = &dev->dev; | |
| 1688 | 1687 | |
| 1689 | 1688 | fbdev->plane = plane; |
| 1690 | 1689 | |
| @@ -1702,16 +1701,6 @@ static int au1200fb_drv_probe(struct platform_device *dev) · 11 unmodified lines | ||
| 1702 | 1701 | goto failed; |
| 1703 | 1702 | } |
| 1704 | 1703 | |
| 1705 | − /* | |
| 1706 | − * Set page reserved so that mmap will work. This is necessary | |
| 1707 | − * since we'll be remapping normal memory. | |
| 1708 | − */ | |
| 1709 | − for (page = (unsigned long)fbdev->fb_phys; | |
| 1710 | − page < PAGE_ALIGN((unsigned long)fbdev->fb_phys + | |
| 1711 | − fbdev->fb_len); | |
| 1712 | − page += PAGE_SIZE) { | |
| 1713 | − SetPageReserved(pfn_to_page(page >> PAGE_SHIFT)); /* LCD DMA is NOT coherent on Au1200 */ | |
| 1714 | − } | |
| 1715 | 1704 | print_dbg("Framebuffer memory map at %p", fbdev->fb_mem); |
| 1716 | 1705 | print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024); |
| 1717 | 1706 | |
| @@ -366,7 +366,6 @@ static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent) · 365 unmodified lines | ||
| 366 | 366 | |
| 367 | 367 | p = framebuffer_alloc(0, &dp->dev); |
| 368 | 368 | if (p == NULL) { |
| 369 | − dev_err(&dp->dev, "Cannot allocate framebuffer structure\n"); | |
| 370 | 369 | rc = -ENOMEM; |
| 371 | 370 | goto err_disable; |
| 372 | 371 | } |
| @@ -2093,7 +2093,6 @@ static int cirrusfb_pci_register(struct pci_dev *pdev, · 2092 unmodified lines | ||
| 2093 | 2093 | |
| 2094 | 2094 | info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev); |
| 2095 | 2095 | if (!info) { |
| 2096 | − printk(KERN_ERR "cirrusfb: could not allocate memory\n"); | |
| 2097 | 2096 | ret = -ENOMEM; |
| 2098 | 2097 | goto err_out; |
| 2099 | 2098 | } |
| @@ -2206,10 +2205,8 @@ static int cirrusfb_zorro_register(struct zorro_dev *z, · 106 unmodified lines | ||
| 2206 | 2205 | struct cirrusfb_info *cinfo; |
| 2207 | 2206 | |
| 2208 | 2207 | info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev); |
| 2209 | − if (!info) { | |
| 2210 | − printk(KERN_ERR "cirrusfb: could not allocate memory\n"); | |
| 2208 | + if (!info) | |
| 2211 | 2209 | return -ENOMEM; |
| 2212 | − } | |
| 2213 | 2210 | |
| 2214 | 2211 | zcl = (const struct zorrocl *)ent->driver_data; |
| 2215 | 2212 | btype = zcl->type; |
| @@ -182,7 +182,7 @@ int init_module(void) · 181 unmodified lines | ||
| 182 | 182 | int ret = -ENXIO; |
| 183 | 183 | |
| 184 | 184 | dp = of_find_node_by_name(NULL, "control"); |
| 185 | − if (dp != 0 && !control_of_init(dp)) | |
| 185 | + if (dp && !control_of_init(dp)) | |
| 186 | 186 | ret = 0; |
| 187 | 187 | of_node_put(dp); |
| 188 | 188 | |
| @@ -580,7 +580,7 @@ static int __init control_init(void) · 391 unmodified lines | ||
| 580 | 580 | control_setup(option); |
| 581 | 581 | |
| 582 | 582 | dp = of_find_node_by_name(NULL, "control"); |
| 583 | − if (dp != 0 && !control_of_init(dp)) | |
| 583 | + if (dp && !control_of_init(dp)) | |
| 584 | 584 | ret = 0; |
| 585 | 585 | of_node_put(dp); |
| 586 | 586 | |
| @@ -683,8 +683,8 @@ static int __init control_of_init(struct device_node *dp) · 96 unmodified lines | ||
| 683 | 683 | return -ENXIO; |
| 684 | 684 | } |
| 685 | 685 | p = kzalloc(sizeof(*p), GFP_KERNEL); |
| 686 | − if (p == 0) | |
| 687 | − return -ENXIO; | |
| 686 | + if (!p) | |
| 687 | + return -ENOMEM; | |
| 688 | 688 | control_fb = p; /* save it for cleanups */ |
| 689 | 689 | |
| 690 | 690 | /* Map in frame buffer and registers */ |
| @@ -285,11 +285,7 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) · 284 unmodified lines | ||
| 285 | 285 | goto out; |
| 286 | 286 | } |
| 287 | 287 | umap.start = cmap->start; |
| 288 | − if (!lock_fb_info(info)) { | |
| 289 | − rc = -ENODEV; | |
| 290 | − goto out; | |
| 291 | − } | |
| 292 | − | |
| 288 | + lock_fb_info(info); | |
| 293 | 289 | rc = fb_set_cmap(&umap, info); |
| 294 | 290 | unlock_fb_info(info); |
| 295 | 291 | out: |
| @@ -76,6 +76,7 @@ · 75 unmodified lines | ||
| 76 | 76 | #include <linux/init.h> |
| 77 | 77 | #include <linux/interrupt.h> |
| 78 | 78 | #include <linux/crc32.h> /* For counting font checksums */ |
| 79 | +#include <linux/uaccess.h> | |
| 79 | 80 | #include <asm/fb.h> |
| 80 | 81 | #include <asm/irq.h> |
| 81 | 82 | |
| @@ -87,13 +88,32 @@ · 5 unmodified lines | ||
| 87 | 88 | # define DPRINTK(fmt, args...) |
| 88 | 89 | #endif |
| 89 | 90 | |
| 91 | +/* | |
| 92 | + * FIXME: Locking | |
| 93 | + * | |
| 94 | + * - fbcon state itself is protected by the console_lock, and the code does a | |
| 95 | + * pretty good job at making sure that lock is held everywhere it's needed. | |
| 96 | + * | |
| 97 | + * - access to the registered_fb array is entirely unprotected. This should use | |
| 98 | + * proper object lifetime handling, i.e. get/put_fb_info. This also means | |
| 99 | + * switching from indices to proper pointers for fb_info everywhere. | |
| 100 | + * | |
| 101 | + * - fbcon doesn't bother with fb_lock/unlock at all. This is buggy, since it | |
| 102 | + * means concurrent access to the same fbdev from both fbcon and userspace | |
| 103 | + * will blow up. To fix this all fbcon calls from fbmem.c need to be moved out | |
| 104 | + * of fb_lock/unlock protected sections, since otherwise we'll recurse and | |
| 105 | + * deadlock eventually. Aside: Due to these deadlock issues the fbdev code in | |
| 106 | + * fbmem.c cannot use locking asserts, and there's lots of callers which get | |
| 107 | + * the rules wrong, e.g. fbsysfs.c entirely missed fb_lock/unlock calls too. | |
| 108 | + */ | |
| 109 | + | |
| 90 | 110 | enum { |
| 91 | 111 | FBCON_LOGO_CANSHOW = -1, /* the logo can be shown */ |
| 92 | 112 | FBCON_LOGO_DRAW = -2, /* draw the logo to a console */ |
| 93 | 113 | FBCON_LOGO_DONTSHOW = -3 /* do not show the logo */ |
| 94 | 114 | }; |
| 95 | 115 | |
| 96 | −static struct display fb_display[MAX_NR_CONSOLES]; | |
| 116 | +static struct fbcon_display fb_display[MAX_NR_CONSOLES]; | |
| 97 | 117 | |
| 98 | 118 | static signed char con2fb_map[MAX_NR_CONSOLES]; |
| 99 | 119 | static signed char con2fb_map_boot[MAX_NR_CONSOLES]; |
| @@ -112,7 +132,6 @@ static int softback_lines; · 12 unmodified lines | ||
| 112 | 132 | static int first_fb_vc; |
| 113 | 133 | static int last_fb_vc = MAX_NR_CONSOLES - 1; |
| 114 | 134 | static int fbcon_is_default = 1; |
| 115 | −static int fbcon_has_exited; | |
| 116 | 135 | static int primary_device = -1; |
| 117 | 136 | static int fbcon_has_console_bind; |
| 118 | 137 | |
| @@ -185,11 +204,11 @@ static __inline__ void ywrap_up(struct vc_data *vc, int count); · 66 unmodified lines | ||
| 185 | 204 | static __inline__ void ywrap_down(struct vc_data *vc, int count); |
| 186 | 205 | static __inline__ void ypan_up(struct vc_data *vc, int count); |
| 187 | 206 | static __inline__ void ypan_down(struct vc_data *vc, int count); |
| 188 | −static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, | |
| 207 | +static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy, int sx, | |
| 189 | 208 | int dy, int dx, int height, int width, u_int y_break); |
| 190 | 209 | static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, |
| 191 | 210 | int unit); |
| 192 | −static void fbcon_redraw_move(struct vc_data *vc, struct display *p, | |
| 211 | +static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p, | |
| 193 | 212 | int line, int count, int dy); |
| 194 | 213 | static void fbcon_modechanged(struct fb_info *info); |
| 195 | 214 | static void fbcon_set_all_vcs(struct fb_info *info); |
| @@ -220,7 +239,7 @@ static void fbcon_rotate(struct fb_info *info, u32 rotate) · 24 unmodified lines | ||
| 220 | 239 | fb_info = registered_fb[con2fb_map[ops->currcon]]; |
| 221 | 240 | |
| 222 | 241 | if (info == fb_info) { |
| 223 | − struct display *p = &fb_display[ops->currcon]; | |
| 242 | + struct fbcon_display *p = &fb_display[ops->currcon]; | |
| 224 | 243 | |
| 225 | 244 | if (rotate < 4) |
| 226 | 245 | p->con_rotate = rotate; |
| @@ -235,7 +254,7 @@ static void fbcon_rotate_all(struct fb_info *info, u32 rotate) · 8 unmodified lines | ||
| 235 | 254 | { |
| 236 | 255 | struct fbcon_ops *ops = info->fbcon_par; |
| 237 | 256 | struct vc_data *vc; |
| 238 | − struct display *p; | |
| 257 | + struct fbcon_display *p; | |
| 239 | 258 | int i; |
| 240 | 259 | |
| 241 | 260 | if (!ops || ops->currcon < 0 || rotate > 3) |
| @@ -900,7 +919,7 @@ static int set_con2fb_map(int unit, int newidx, int user) · 658 unmodified lines | ||
| 900 | 919 | * Low Level Operations |
| 901 | 920 | */ |
| 902 | 921 | /* NOTE: fbcon cannot be __init: it may be called from do_take_over_console later */ |
| 903 | −static int var_to_display(struct display *disp, | |
| 922 | +static int var_to_display(struct fbcon_display *disp, | |
| 904 | 923 | struct fb_var_screeninfo *var, |
| 905 | 924 | struct fb_info *info) |
| 906 | 925 | { |
| @@ -925,7 +944,7 @@ static int var_to_display(struct display *disp, · 18 unmodified lines | ||
| 925 | 944 | } |
| 926 | 945 | |
| 927 | 946 | static void display_to_var(struct fb_var_screeninfo *var, |
| 928 | − struct display *disp) | |
| 947 | + struct fbcon_display *disp) | |
| 929 | 948 | { |
| 930 | 949 | fb_videomode_to_var(var, disp->mode); |
| 931 | 950 | var->xres_virtual = disp->xres_virtual; |
| @@ -946,7 +965,7 @@ static void display_to_var(struct fb_var_screeninfo *var, · 14 unmodified lines | ||
| 946 | 965 | static const char *fbcon_startup(void) |
| 947 | 966 | { |
| 948 | 967 | const char *display_desc = "frame buffer device"; |
| 949 | − struct display *p = &fb_display[fg_console]; | |
| 968 | + struct fbcon_display *p = &fb_display[fg_console]; | |
| 950 | 969 | struct vc_data *vc = vc_cons[fg_console].d; |
| 951 | 970 | const struct font_desc *font = NULL; |
| 952 | 971 | struct module *owner; |
| @@ -1050,23 +1069,26 @@ static const char *fbcon_startup(void) · 97 unmodified lines | ||
| 1050 | 1069 | info->var.bits_per_pixel); |
| 1051 | 1070 | |
| 1052 | 1071 | fbcon_add_cursor_timer(info); |
| 1053 | − fbcon_has_exited = 0; | |
| 1054 | 1072 | return display_desc; |
| 1055 | 1073 | } |
| 1056 | 1074 | |
| 1057 | 1075 | static void fbcon_init(struct vc_data *vc, int init) |
| 1058 | 1076 | { |
| 1059 | − struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; | |
| 1077 | + struct fb_info *info; | |
| 1060 | 1078 | struct fbcon_ops *ops; |
| 1061 | 1079 | struct vc_data **default_mode = vc->vc_display_fg; |
| 1062 | 1080 | struct vc_data *svc = *default_mode; |
| 1063 | − struct display *t, *p = &fb_display[vc->vc_num]; | |
| 1081 | + struct fbcon_display *t, *p = &fb_display[vc->vc_num]; | |
| 1064 | 1082 | int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256; |
| 1065 | 1083 | int cap, ret; |
| 1066 | 1084 | |
| 1067 | − if (info_idx == -1 || info == NULL) | |
| 1085 | + if (WARN_ON(info_idx == -1)) | |
| 1068 | 1086 | return; |
| 1069 | 1087 | |
| 1088 | + if (con2fb_map[vc->vc_num] == -1) | |
| 1089 | + con2fb_map[vc->vc_num] = info_idx; | |
| 1090 | + | |
| 1091 | + info = registered_fb[con2fb_map[vc->vc_num]]; | |
| 1070 | 1092 | cap = info->flags; |
| 1071 | 1093 | |
| 1072 | 1094 | if (logo_shown < 0 && console_loglevel <= CONSOLE_LOGLEVEL_QUIET) |
| @@ -1203,7 +1225,7 @@ static void fbcon_init(struct vc_data *vc, int init) · 130 unmodified lines | ||
| 1203 | 1225 | ops->p = &fb_display[fg_console]; |
| 1204 | 1226 | } |
| 1205 | 1227 | |
| 1206 | −static void fbcon_free_font(struct display *p, bool freefont) | |
| 1228 | +static void fbcon_free_font(struct fbcon_display *p, bool freefont) | |
| 1207 | 1229 | { |
| 1208 | 1230 | if (freefont && p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) |
| 1209 | 1231 | kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int)); |
| @@ -1215,7 +1237,7 @@ static void set_vc_hi_font(struct vc_data *vc, bool set); · 5 unmodified lines | ||
| 1215 | 1237 | |
| 1216 | 1238 | static void fbcon_deinit(struct vc_data *vc) |
| 1217 | 1239 | { |
| 1218 | − struct display *p = &fb_display[vc->vc_num]; | |
| 1240 | + struct fbcon_display *p = &fb_display[vc->vc_num]; | |
| 1219 | 1241 | struct fb_info *info; |
| 1220 | 1242 | struct fbcon_ops *ops; |
| 1221 | 1243 | int idx; |
| @@ -1288,7 +1310,7 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, · 66 unmodified lines | ||
| 1288 | 1310 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
| 1289 | 1311 | struct fbcon_ops *ops = info->fbcon_par; |
| 1290 | 1312 | |
| 1291 | − struct display *p = &fb_display[vc->vc_num]; | |
| 1313 | + struct fbcon_display *p = &fb_display[vc->vc_num]; | |
| 1292 | 1314 | u_int y_break; |
| 1293 | 1315 | |
| 1294 | 1316 | if (fbcon_is_inactive(vc, info)) |
| @@ -1324,7 +1346,7 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, · 29 unmodified lines | ||
| 1324 | 1346 | int count, int ypos, int xpos) |
| 1325 | 1347 | { |
| 1326 | 1348 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
| 1327 | − struct display *p = &fb_display[vc->vc_num]; | |
| 1349 | + struct fbcon_display *p = &fb_display[vc->vc_num]; | |
| 1328 | 1350 | struct fbcon_ops *ops = info->fbcon_par; |
| 1329 | 1351 | |
| 1330 | 1352 | if (!fbcon_is_inactive(vc, info)) |
| @@ -1388,7 +1410,7 @@ static int scrollback_current = 0; · 57 unmodified lines | ||
| 1388 | 1410 | static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, |
| 1389 | 1411 | int unit) |
| 1390 | 1412 | { |
| 1391 | − struct display *p, *t; | |
| 1413 | + struct fbcon_display *p, *t; | |
| 1392 | 1414 | struct vc_data **default_mode, *vc; |
| 1393 | 1415 | struct vc_data *svc; |
| 1394 | 1416 | struct fbcon_ops *ops = info->fbcon_par; |
| @@ -1457,7 +1479,7 @@ static __inline__ void ywrap_up(struct vc_data *vc, int count) · 62 unmodified lines | ||
| 1457 | 1479 | { |
| 1458 | 1480 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
| 1459 | 1481 | struct fbcon_ops *ops = info->fbcon_par; |
| 1460 | − struct display *p = &fb_display[vc->vc_num]; | |
| 1482 | + struct fbcon_display *p = &fb_display[vc->vc_num]; | |
| 1461 | 1483 | |
| 1462 | 1484 | p->yscroll += count; |
| 1463 | 1485 | if (p->yscroll >= p->vrows) /* Deal with wrap */ |
| @@ -1476,7 +1498,7 @@ static __inline__ void ywrap_down(struct vc_data *vc, int count) · 12 unmodified lines | ||
| 1476 | 1498 | { |
| 1477 | 1499 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
| 1478 | 1500 | struct fbcon_ops *ops = info->fbcon_par; |
| 1479 | − struct display *p = &fb_display[vc->vc_num]; | |
| 1501 | + struct fbcon_display *p = &fb_display[vc->vc_num]; | |
| 1480 | 1502 | |
| 1481 | 1503 | p->yscroll -= count; |
| 1482 | 1504 | if (p->yscroll < 0) /* Deal with wrap */ |
| @@ -1494,7 +1516,7 @@ static __inline__ void ywrap_down(struct vc_data *vc, int count) · 11 unmodified lines | ||
| 1494 | 1516 | static __inline__ void ypan_up(struct vc_data *vc, int count) |
| 1495 | 1517 | { |
| 1496 | 1518 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
| 1497 | − struct display *p = &fb_display[vc->vc_num]; | |
| 1519 | + struct fbcon_display *p = &fb_display[vc->vc_num]; | |
| 1498 | 1520 | struct fbcon_ops *ops = info->fbcon_par; |
| 1499 | 1521 | |
| 1500 | 1522 | p->yscroll += count; |
| @@ -1519,7 +1541,7 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count) · 18 unmodified lines | ||
| 1519 | 1541 | { |
| 1520 | 1542 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
| 1521 | 1543 | struct fbcon_ops *ops = info->fbcon_par; |
| 1522 | − struct display *p = &fb_display[vc->vc_num]; | |
| 1544 | + struct fbcon_display *p = &fb_display[vc->vc_num]; | |
| 1523 | 1545 | |
| 1524 | 1546 | p->yscroll += count; |
| 1525 | 1547 | |
| @@ -1542,7 +1564,7 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count) · 16 unmodified lines | ||
| 1542 | 1564 | static __inline__ void ypan_down(struct vc_data *vc, int count) |
| 1543 | 1565 | { |
| 1544 | 1566 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
| 1545 | − struct display *p = &fb_display[vc->vc_num]; | |
| 1567 | + struct fbcon_display *p = &fb_display[vc->vc_num]; | |
| 1546 | 1568 | struct fbcon_ops *ops = info->fbcon_par; |
| 1547 | 1569 | |
| 1548 | 1570 | p->yscroll -= count; |
| @@ -1567,7 +1589,7 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count) · 18 unmodified lines | ||
| 1567 | 1589 | { |
| 1568 | 1590 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
| 1569 | 1591 | struct fbcon_ops *ops = info->fbcon_par; |
| 1570 | − struct display *p = &fb_display[vc->vc_num]; | |
| 1592 | + struct fbcon_display *p = &fb_display[vc->vc_num]; | |
| 1571 | 1593 | |
| 1572 | 1594 | p->yscroll -= count; |
| 1573 | 1595 | |
| @@ -1587,7 +1609,7 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count) · 13 unmodified lines | ||
| 1587 | 1609 | scrollback_current = 0; |
| 1588 | 1610 | } |
| 1589 | 1611 | |
| 1590 | −static void fbcon_redraw_softback(struct vc_data *vc, struct display *p, | |
| 1612 | +static void fbcon_redraw_softback(struct vc_data *vc, struct fbcon_display *p, | |
| 1591 | 1613 | long delta) |
| 1592 | 1614 | { |
| 1593 | 1615 | int count = vc->vc_rows; |
| @@ -1680,7 +1702,7 @@ static void fbcon_redraw_softback(struct vc_data *vc, struct display *p, · 86 unmodified lines | ||
| 1680 | 1702 | } |
| 1681 | 1703 | } |
| 1682 | 1704 | |
| 1683 | −static void fbcon_redraw_move(struct vc_data *vc, struct display *p, | |
| 1705 | +static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p, | |
| 1684 | 1706 | int line, int count, int dy) |
| 1685 | 1707 | { |
| 1686 | 1708 | unsigned short *s = (unsigned short *) |
| @@ -1715,7 +1737,7 @@ static void fbcon_redraw_move(struct vc_data *vc, struct display *p, · 28 unmodified lines | ||
| 1715 | 1737 | } |
| 1716 | 1738 | |
| 1717 | 1739 | static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info, |
| 1718 | − struct display *p, int line, int count, int ycount) | |
| 1740 | + struct fbcon_display *p, int line, int count, int ycount) | |
| 1719 | 1741 | { |
| 1720 | 1742 | int offset = ycount * vc->vc_cols; |
| 1721 | 1743 | unsigned short *d = (unsigned short *) |
| @@ -1764,7 +1786,7 @@ static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info, · 42 unmodified lines | ||
| 1764 | 1786 | } |
| 1765 | 1787 | } |
| 1766 | 1788 | |
| 1767 | −static void fbcon_redraw(struct vc_data *vc, struct display *p, | |
| 1789 | +static void fbcon_redraw(struct vc_data *vc, struct fbcon_display *p, | |
| 1768 | 1790 | int line, int count, int offset) |
| 1769 | 1791 | { |
| 1770 | 1792 | unsigned short *d = (unsigned short *) |
| @@ -1848,7 +1870,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, · 77 unmodified lines | ||
| 1848 | 1870 | enum con_scroll dir, unsigned int count) |
| 1849 | 1871 | { |
| 1850 | 1872 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
| 1851 | − struct display *p = &fb_display[vc->vc_num]; | |
| 1873 | + struct fbcon_display *p = &fb_display[vc->vc_num]; | |
| 1852 | 1874 | int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK; |
| 1853 | 1875 | |
| 1854 | 1876 | if (fbcon_is_inactive(vc, info)) |
| @@ -2052,7 +2074,7 @@ static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, · 197 unmodified lines | ||
| 2052 | 2074 | int height, int width) |
| 2053 | 2075 | { |
| 2054 | 2076 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
| 2055 | − struct display *p = &fb_display[vc->vc_num]; | |
| 2077 | + struct fbcon_display *p = &fb_display[vc->vc_num]; | |
| 2056 | 2078 | |
| 2057 | 2079 | if (fbcon_is_inactive(vc, info)) |
| 2058 | 2080 | return; |
| @@ -2071,7 +2093,7 @@ static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, · 12 unmodified lines | ||
| 2071 | 2093 | p->vrows - p->yscroll); |
| 2072 | 2094 | } |
| 2073 | 2095 | |
| 2074 | −static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, | |
| 2096 | +static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy, int sx, | |
| 2075 | 2097 | int dy, int dx, int height, int width, u_int y_break) |
| 2076 | 2098 | { |
| 2077 | 2099 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
| @@ -2113,7 +2135,7 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s · 35 unmodified lines | ||
| 2113 | 2135 | height, width); |
| 2114 | 2136 | } |
| 2115 | 2137 | |
| 2116 | −static void updatescrollmode(struct display *p, | |
| 2138 | +static void updatescrollmode(struct fbcon_display *p, | |
| 2117 | 2139 | struct fb_info *info, |
| 2118 | 2140 | struct vc_data *vc) |
| 2119 | 2141 | { |
| @@ -2165,7 +2187,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, · 45 unmodified lines | ||
| 2165 | 2187 | { |
| 2166 | 2188 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
| 2167 | 2189 | struct fbcon_ops *ops = info->fbcon_par; |
| 2168 | − struct display *p = &fb_display[vc->vc_num]; | |
| 2190 | + struct fbcon_display *p = &fb_display[vc->vc_num]; | |
| 2169 | 2191 | struct fb_var_screeninfo var = info->var; |
| 2170 | 2192 | int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh; |
| 2171 | 2193 | |
| @@ -2210,7 +2232,7 @@ static int fbcon_switch(struct vc_data *vc) · 38 unmodified lines | ||
| 2210 | 2232 | { |
| 2211 | 2233 | struct fb_info *info, *old_info = NULL; |
| 2212 | 2234 | struct fbcon_ops *ops; |
| 2213 | − struct display *p = &fb_display[vc->vc_num]; | |
| 2235 | + struct fbcon_display *p = &fb_display[vc->vc_num]; | |
| 2214 | 2236 | struct fb_var_screeninfo var; |
| 2215 | 2237 | int i, ret, prev_console, charcnt = 256; |
| 2216 | 2238 | |
| @@ -2348,8 +2370,6 @@ static int fbcon_switch(struct vc_data *vc) · 131 unmodified lines | ||
| 2348 | 2370 | static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info, |
| 2349 | 2371 | int blank) |
| 2350 | 2372 | { |
| 2351 | − struct fb_event event; | |
| 2352 | − | |
| 2353 | 2373 | if (blank) { |
| 2354 | 2374 | unsigned short charmask = vc->vc_hi_font_mask ? |
| 2355 | 2375 | 0x1ff : 0xff; |
| @@ -2360,14 +2380,6 @@ static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info, · 4 unmodified lines | ||
| 2360 | 2380 | fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols); |
| 2361 | 2381 | vc->vc_video_erase_char = oldc; |
| 2362 | 2382 | } |
| 2363 | − | |
| 2364 | − | |
| 2365 | − if (!lock_fb_info(info)) | |
| 2366 | − return; | |
| 2367 | − event.info = info; | |
| 2368 | − event.data = ␣ | |
| 2369 | − fb_notifier_call_chain(FB_EVENT_CONBLANK, &event); | |
| 2370 | − unlock_fb_info(info); | |
| 2371 | 2383 | } |
| 2372 | 2384 | |
| 2373 | 2385 | static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) |
| @@ -2394,9 +2406,8 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) · 20 unmodified lines | ||
| 2394 | 2406 | fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); |
| 2395 | 2407 | ops->cursor_flash = (!blank); |
| 2396 | 2408 | |
| 2397 | − if (!(info->flags & FBINFO_MISC_USEREVENT)) | |
| 2398 | − if (fb_blank(info, blank)) | |
| 2399 | − fbcon_generic_blank(vc, info, blank); | |
| 2409 | + if (fb_blank(info, blank)) | |
| 2410 | + fbcon_generic_blank(vc, info, blank); | |
| 2400 | 2411 | } |
| 2401 | 2412 | |
| 2402 | 2413 | if (!blank) |
| @@ -2553,7 +2564,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, · 150 unmodified lines | ||
| 2553 | 2564 | { |
| 2554 | 2565 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
| 2555 | 2566 | struct fbcon_ops *ops = info->fbcon_par; |
| 2556 | − struct display *p = &fb_display[vc->vc_num]; | |
| 2567 | + struct fbcon_display *p = &fb_display[vc->vc_num]; | |
| 2557 | 2568 | int resize; |
| 2558 | 2569 | int cnt; |
| 2559 | 2570 | char *old_data = NULL; |
| @@ -2601,7 +2612,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, · 41 unmodified lines | ||
| 2601 | 2612 | |
| 2602 | 2613 | static int fbcon_copy_font(struct vc_data *vc, int con) |
| 2603 | 2614 | { |
| 2604 | − struct display *od = &fb_display[con]; | |
| 2615 | + struct fbcon_display *od = &fb_display[con]; | |
| 2605 | 2616 | struct console_font *f = &vc->vc_font; |
| 2606 | 2617 | |
| 2607 | 2618 | if (od->fontdata == f->data) |
| @@ -2826,7 +2837,7 @@ static void fbcon_scrolldelta(struct vc_data *vc, int lines) · 218 unmodified lines | ||
| 2826 | 2837 | { |
| 2827 | 2838 | struct fb_info *info = registered_fb[con2fb_map[fg_console]]; |
| 2828 | 2839 | struct fbcon_ops *ops = info->fbcon_par; |
| 2829 | − struct display *disp = &fb_display[fg_console]; | |
| 2840 | + struct fbcon_display *disp = &fb_display[fg_console]; | |
| 2830 | 2841 | int offset, limit, scrollback_old; |
| 2831 | 2842 | |
| 2832 | 2843 | if (softback_top) { |
| @@ -2918,7 +2929,7 @@ static int fbcon_set_origin(struct vc_data *vc) · 85 unmodified lines | ||
| 2918 | 2929 | return 0; |
| 2919 | 2930 | } |
| 2920 | 2931 | |
| 2921 | −static void fbcon_suspended(struct fb_info *info) | |
| 2932 | +void fbcon_suspended(struct fb_info *info) | |
| 2922 | 2933 | { |
| 2923 | 2934 | struct vc_data *vc = NULL; |
| 2924 | 2935 | struct fbcon_ops *ops = info->fbcon_par; |
| @@ -2931,7 +2942,7 @@ static void fbcon_suspended(struct fb_info *info) · 6 unmodified lines | ||
| 2931 | 2942 | fbcon_cursor(vc, CM_ERASE); |
| 2932 | 2943 | } |
| 2933 | 2944 | |
| 2934 | −static void fbcon_resumed(struct fb_info *info) | |
| 2945 | +void fbcon_resumed(struct fb_info *info) | |
| 2935 | 2946 | { |
| 2936 | 2947 | struct vc_data *vc; |
| 2937 | 2948 | struct fbcon_ops *ops = info->fbcon_par; |
| @@ -2947,7 +2958,7 @@ static void fbcon_modechanged(struct fb_info *info) · 9 unmodified lines | ||
| 2947 | 2958 | { |
| 2948 | 2959 | struct fbcon_ops *ops = info->fbcon_par; |
| 2949 | 2960 | struct vc_data *vc; |
| 2950 | − struct display *p; | |
| 2961 | + struct fbcon_display *p; | |
| 2951 | 2962 | int rows, cols; |
| 2952 | 2963 | |
| 2953 | 2964 | if (!ops || ops->currcon < 0) |
| @@ -2987,7 +2998,7 @@ static void fbcon_set_all_vcs(struct fb_info *info) · 33 unmodified lines | ||
| 2987 | 2998 | { |
| 2988 | 2999 | struct fbcon_ops *ops = info->fbcon_par; |
| 2989 | 3000 | struct vc_data *vc; |
| 2990 | − struct display *p; | |
| 3001 | + struct fbcon_display *p; | |
| 2991 | 3002 | int i, rows, cols, fg = -1; |
| 2992 | 3003 | |
| 2993 | 3004 | if (!ops || ops->currcon < 0) |
| @@ -3018,11 +3029,21 @@ static void fbcon_set_all_vcs(struct fb_info *info) · 24 unmodified lines | ||
| 3018 | 3029 | fbcon_modechanged(info); |
| 3019 | 3030 | } |
| 3020 | 3031 | |
| 3021 | −static int fbcon_mode_deleted(struct fb_info *info, | |
| 3022 | − struct fb_videomode *mode) | |
| 3032 | + | |
| 3033 | +void fbcon_update_vcs(struct fb_info *info, bool all) | |
| 3034 | +{ | |
| 3035 | + if (all) | |
| 3036 | + fbcon_set_all_vcs(info); | |
| 3037 | + else | |
| 3038 | + fbcon_modechanged(info); | |
| 3039 | +} | |
| 3040 | +EXPORT_SYMBOL(fbcon_update_vcs); | |
| 3041 | + | |
| 3042 | +int fbcon_mode_deleted(struct fb_info *info, | |
| 3043 | + struct fb_videomode *mode) | |
| 3023 | 3044 | { |
| 3024 | 3045 | struct fb_info *fb_info; |
| 3025 | − struct display *p; | |
| 3046 | + struct fbcon_display *p; | |
| 3026 | 3047 | int i, j, found = 0; |
| 3027 | 3048 | |
| 3028 | 3049 | /* before deletion, ensure that mode is not in use */ |
| @@ -3045,7 +3066,7 @@ static int fbcon_mode_deleted(struct fb_info *info, · 16 unmodified lines | ||
| 3045 | 3066 | } |
| 3046 | 3067 | |
| 3047 | 3068 | #ifdef CONFIG_VT_HW_CONSOLE_BINDING |
| 3048 | −static int fbcon_unbind(void) | |
| 3069 | +static void fbcon_unbind(void) | |
| 3049 | 3070 | { |
| 3050 | 3071 | int ret; |
| 3051 | 3072 | |
| @@ -3054,25 +3075,21 @@ static int fbcon_unbind(void) · 2 unmodified lines | ||
| 3054 | 3075 | |
| 3055 | 3076 | if (!ret) |
| 3056 | 3077 | fbcon_has_console_bind = 0; |
| 3057 | − | |
| 3058 | − return ret; | |
| 3059 | 3078 | } |
| 3060 | 3079 | #else |
| 3061 | −static inline int fbcon_unbind(void) | |
| 3062 | −{ | |
| 3063 | − return -EINVAL; | |
| 3064 | −} | |
| 3080 | +static inline void fbcon_unbind(void) {} | |
| 3065 | 3081 | #endif /* CONFIG_VT_HW_CONSOLE_BINDING */ |
| 3066 | 3082 | |
| 3067 | 3083 | /* called with console_lock held */ |
| 3068 | −static int fbcon_fb_unbind(int idx) | |
| 3084 | +void fbcon_fb_unbind(struct fb_info *info) | |
| 3069 | 3085 | { |
| 3070 | 3086 | int i, new_idx = -1, ret = 0; |
| 3087 | + int idx = info->node; | |
| 3071 | 3088 | |
| 3072 | 3089 | WARN_CONSOLE_UNLOCKED(); |
| 3073 | 3090 | |
| 3074 | 3091 | if (!fbcon_has_console_bind) |
| 3075 | − return 0; | |
| 3092 | + return; | |
| 3076 | 3093 | |
| 3077 | 3094 | for (i = first_fb_vc; i <= last_fb_vc; i++) { |
| 3078 | 3095 | if (con2fb_map[i] != idx && |
| @@ -3105,26 +3122,24 @@ static int fbcon_fb_unbind(int idx) · 26 unmodified lines | ||
| 3105 | 3122 | idx, 0); |
| 3106 | 3123 | if (ret) { |
| 3107 | 3124 | con2fb_map[i] = idx; |
| 3108 | − return ret; | |
| 3125 | + return; | |
| 3109 | 3126 | } |
| 3110 | 3127 | } |
| 3111 | 3128 | } |
| 3112 | 3129 | } |
| 3113 | − ret = fbcon_unbind(); | |
| 3130 | + fbcon_unbind(); | |
| 3114 | 3131 | } |
| 3115 | − | |
| 3116 | − return ret; | |
| 3117 | 3132 | } |
| 3118 | 3133 | |
| 3119 | 3134 | /* called with console_lock held */ |
| 3120 | −static int fbcon_fb_unregistered(struct fb_info *info) | |
| 3135 | +void fbcon_fb_unregistered(struct fb_info *info) | |
| 3121 | 3136 | { |
| 3122 | 3137 | int i, idx; |
| 3123 | 3138 | |
| 3124 | 3139 | WARN_CONSOLE_UNLOCKED(); |
| 3125 | 3140 | |
| 3126 | 3141 | if (deferred_takeover) |
| 3127 | − return 0; | |
| 3142 | + return; | |
| 3128 | 3143 | |
| 3129 | 3144 | idx = info->node; |
| 3130 | 3145 | for (i = first_fb_vc; i <= last_fb_vc; i++) { |
| @@ -3153,21 +3168,18 @@ static int fbcon_fb_unregistered(struct fb_info *info) · 22 unmodified lines | ||
| 3153 | 3168 | |
| 3154 | 3169 | if (!num_registered_fb) |
| 3155 | 3170 | do_unregister_con_driver(&fb_con); |
| 3156 | − | |
| 3157 | − return 0; | |
| 3158 | 3171 | } |
| 3159 | 3172 | |
| 3160 | −/* called with console_lock held */ | |
| 3161 | −static void fbcon_remap_all(int idx) | |
| 3173 | +void fbcon_remap_all(struct fb_info *info) | |
| 3162 | 3174 | { |
| 3163 | − int i; | |
| 3164 | − | |
| 3165 | − WARN_CONSOLE_UNLOCKED(); | |
| 3175 | + int i, idx = info->node; | |
| 3166 | 3176 | |
| 3177 | + console_lock(); | |
| 3167 | 3178 | if (deferred_takeover) { |
| 3168 | 3179 | for (i = first_fb_vc; i <= last_fb_vc; i++) |
| 3169 | 3180 | con2fb_map_boot[i] = idx; |
| 3170 | 3181 | fbcon_map_override(); |
| 3182 | + console_unlock(); | |
| 3171 | 3183 | return; |
| 3172 | 3184 | } |
| 3173 | 3185 | |
| @@ -3180,6 +3192,7 @@ static void fbcon_remap_all(int idx) · 6 unmodified lines | ||
| 3180 | 3192 | first_fb_vc + 1, last_fb_vc + 1); |
| 3181 | 3193 | info_idx = idx; |
| 3182 | 3194 | } |
| 3195 | + console_unlock(); | |
| 3183 | 3196 | } |
| 3184 | 3197 | |
| 3185 | 3198 | #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY |
| @@ -3213,7 +3226,7 @@ static inline void fbcon_select_primary(struct fb_info *info) · 27 unmodified lines | ||
| 3213 | 3226 | #endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */ |
| 3214 | 3227 | |
| 3215 | 3228 | /* called with console_lock held */ |
| 3216 | −static int fbcon_fb_registered(struct fb_info *info) | |
| 3229 | +int fbcon_fb_registered(struct fb_info *info) | |
| 3217 | 3230 | { |
| 3218 | 3231 | int ret = 0, i, idx; |
| 3219 | 3232 | |
| @@ -3247,7 +3260,7 @@ static int fbcon_fb_registered(struct fb_info *info) · 27 unmodified lines | ||
| 3247 | 3260 | return ret; |
| 3248 | 3261 | } |
| 3249 | 3262 | |
| 3250 | −static void fbcon_fb_blanked(struct fb_info *info, int blank) | |
| 3263 | +void fbcon_fb_blanked(struct fb_info *info, int blank) | |
| 3251 | 3264 | { |
| 3252 | 3265 | struct fbcon_ops *ops = info->fbcon_par; |
| 3253 | 3266 | struct vc_data *vc; |
| @@ -3269,7 +3282,7 @@ static void fbcon_fb_blanked(struct fb_info *info, int blank) · 15 unmodified lines | ||
| 3269 | 3282 | ops->blank_state = blank; |
| 3270 | 3283 | } |
| 3271 | 3284 | |
| 3272 | −static void fbcon_new_modelist(struct fb_info *info) | |
| 3285 | +void fbcon_new_modelist(struct fb_info *info) | |
| 3273 | 3286 | { |
| 3274 | 3287 | int i; |
| 3275 | 3288 | struct vc_data *vc; |
| @@ -3290,11 +3303,11 @@ static void fbcon_new_modelist(struct fb_info *info) · 14 unmodified lines | ||
| 3290 | 3303 | } |
| 3291 | 3304 | } |
| 3292 | 3305 | |
| 3293 | −static void fbcon_get_requirement(struct fb_info *info, | |
| 3294 | − struct fb_blit_caps *caps) | |
| 3306 | +void fbcon_get_requirement(struct fb_info *info, | |
| 3307 | + struct fb_blit_caps *caps) | |
| 3295 | 3308 | { |
| 3296 | 3309 | struct vc_data *vc; |
| 3297 | − struct display *p; | |
| 3310 | + struct fbcon_display *p; | |
| 3298 | 3311 | |
| 3299 | 3312 | if (caps->flags) { |
| 3300 | 3313 | int i, charcnt; |
| @@ -3326,80 +3339,47 @@ static void fbcon_get_requirement(struct fb_info *info, · 25 unmodified lines | ||
| 3326 | 3339 | } |
| 3327 | 3340 | } |
| 3328 | 3341 | |
| 3329 | −static int fbcon_event_notify(struct notifier_block *self, | |
| 3330 | − unsigned long action, void *data) | |
| 3342 | +int fbcon_set_con2fb_map_ioctl(void __user *argp) | |
| 3331 | 3343 | { |
| 3332 | − struct fb_event *event = data; | |
| 3333 | − struct fb_info *info = event->info; | |
| 3334 | − struct fb_videomode *mode; | |
| 3335 | − struct fb_con2fbmap *con2fb; | |
| 3336 | − struct fb_blit_caps *caps; | |
| 3337 | − int idx, ret = 0; | |
| 3338 | − | |
| 3339 | − /* | |
| 3340 | − * ignore all events except driver registration and deregistration | |
| 3341 | − * if fbcon is not active | |
| 3342 | − */ | |
| 3343 | − if (fbcon_has_exited && !(action == FB_EVENT_FB_REGISTERED || | |
| 3344 | − action == FB_EVENT_FB_UNREGISTERED)) | |
| 3345 | − goto done; | |
| 3344 | + struct fb_con2fbmap con2fb; | |
| 3345 | + int ret; | |
| 3346 | 3346 | |
| 3347 | − switch(action) { | |
| 3348 | − case FB_EVENT_SUSPEND: | |
| 3349 | − fbcon_suspended(info); | |
| 3350 | − break; | |
| 3351 | − case FB_EVENT_RESUME: | |
| 3352 | − fbcon_resumed(info); | |
| 3353 | − break; | |
| 3354 | − case FB_EVENT_MODE_CHANGE: | |
| 3355 | − fbcon_modechanged(info); | |
| 3356 | − break; | |
| 3357 | − case FB_EVENT_MODE_CHANGE_ALL: | |
| 3358 | − fbcon_set_all_vcs(info); | |
| 3359 | − break; | |
| 3360 | − case FB_EVENT_MODE_DELETE: | |
| 3361 | − mode = event->data; | |
| 3362 | − ret = fbcon_mode_deleted(info, mode); | |
| 3363 | − break; | |
| 3364 | − case FB_EVENT_FB_UNBIND: | |
| 3365 | − idx = info->node; | |
| 3366 | − ret = fbcon_fb_unbind(idx); | |
| 3367 | − break; | |
| 3368 | − case FB_EVENT_FB_REGISTERED: | |
| 3369 | − ret = fbcon_fb_registered(info); | |
| 3370 | − break; | |
| 3371 | − case FB_EVENT_FB_UNREGISTERED: | |
| 3372 | − ret = fbcon_fb_unregistered(info); | |
| 3373 | − break; | |
| 3374 | − case FB_EVENT_SET_CONSOLE_MAP: | |
| 3375 | − /* called with console lock held */ | |
| 3376 | − con2fb = event->data; | |
| 3377 | − ret = set_con2fb_map(con2fb->console - 1, | |
| 3378 | − con2fb->framebuffer, 1); | |
| 3379 | − break; | |
| 3380 | − case FB_EVENT_GET_CONSOLE_MAP: | |
| 3381 | − con2fb = event->data; | |
| 3382 | − con2fb->framebuffer = con2fb_map[con2fb->console - 1]; | |
| 3383 | − break; | |
| 3384 | − case FB_EVENT_BLANK: | |
| 3385 | − fbcon_fb_blanked(info, *(int *)event->data); | |
| 3386 | − break; | |
| 3387 | − case FB_EVENT_NEW_MODELIST: | |
| 3388 | − fbcon_new_modelist(info); | |
| 3389 | − break; | |
| 3390 | − case FB_EVENT_GET_REQ: | |
| 3391 | − caps = event->data; | |
| 3392 | − fbcon_get_requirement(info, caps); | |
| 3393 | − break; | |
| 3394 | − case FB_EVENT_REMAP_ALL_CONSOLE: | |
| 3395 | − idx = info->node; | |
| 3396 | − fbcon_remap_all(idx); | |
| 3397 | − break; | |
| 3347 | + if (copy_from_user(&con2fb, argp, sizeof(con2fb))) | |
| 3348 | + return -EFAULT; | |
| 3349 | + if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) | |
| 3350 | + return -EINVAL; | |
| 3351 | + if (con2fb.framebuffer >= FB_MAX) | |
| 3352 | + return -EINVAL; | |
| 3353 | + if (!registered_fb[con2fb.framebuffer]) | |
| 3354 | + request_module("fb%d", con2fb.framebuffer); | |
| 3355 | + if (!registered_fb[con2fb.framebuffer]) { | |
| 3356 | + return -EINVAL; | |
| 3398 | 3357 | } |
| 3399 | −done: | |
| 3358 | + | |
| 3359 | + console_lock(); | |
| 3360 | + ret = set_con2fb_map(con2fb.console - 1, | |
| 3361 | + con2fb.framebuffer, 1); | |
| 3362 | + console_unlock(); | |
| 3363 | + | |
| 3400 | 3364 | return ret; |
| 3401 | 3365 | } |
| 3402 | 3366 | |
| 3367 | +int fbcon_get_con2fb_map_ioctl(void __user *argp) | |
| 3368 | +{ | |
| 3369 | + struct fb_con2fbmap con2fb; | |
| 3370 | + | |
| 3371 | + if (copy_from_user(&con2fb, argp, sizeof(con2fb))) | |
| 3372 | + return -EFAULT; | |
| 3373 | + if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) | |
| 3374 | + return -EINVAL; | |
| 3375 | + | |
| 3376 | + console_lock(); | |
| 3377 | + con2fb.framebuffer = con2fb_map[con2fb.console - 1]; | |
| 3378 | + console_unlock(); | |
| 3379 | + | |
| 3380 | + return copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0; | |
| 3381 | +} | |
| 3382 | + | |
| 3403 | 3383 | /* |
| 3404 | 3384 | * The console `switch' structure for the frame buffer based console |
| 3405 | 3385 | */ |
| @@ -3431,10 +3411,6 @@ static const struct consw fb_con = { · 25 unmodified lines | ||
| 3431 | 3411 | .con_debug_leave = fbcon_debug_leave, |
| 3432 | 3412 | }; |
| 3433 | 3413 | |
| 3434 | −static struct notifier_block fbcon_event_notifier = { | |
| 3435 | − .notifier_call = fbcon_event_notify, | |
| 3436 | −}; | |
| 3437 | − | |
| 3438 | 3414 | static ssize_t store_rotate(struct device *device, |
| 3439 | 3415 | struct device_attribute *attr, const char *buf, |
| 3440 | 3416 | size_t count) |
| @@ -3443,9 +3419,6 @@ static ssize_t store_rotate(struct device *device, · 2 unmodified lines | ||
| 3443 | 3419 | int rotate, idx; |
| 3444 | 3420 | char **last = NULL; |
| 3445 | 3421 | |
| 3446 | − if (fbcon_has_exited) | |
| 3447 | − return count; | |
| 3448 | − | |
| 3449 | 3422 | console_lock(); |
| 3450 | 3423 | idx = con2fb_map[fg_console]; |
| 3451 | 3424 | |
| @@ -3468,9 +3441,6 @@ static ssize_t store_rotate_all(struct device *device, · 16 unmodified lines | ||
| 3468 | 3441 | int rotate, idx; |
| 3469 | 3442 | char **last = NULL; |
| 3470 | 3443 | |
| 3471 | − if (fbcon_has_exited) | |
| 3472 | − return count; | |
| 3473 | − | |
| 3474 | 3444 | console_lock(); |
| 3475 | 3445 | idx = con2fb_map[fg_console]; |
| 3476 | 3446 | |
| @@ -3491,9 +3461,6 @@ static ssize_t show_rotate(struct device *device, · 14 unmodified lines | ||
| 3491 | 3461 | struct fb_info *info; |
| 3492 | 3462 | int rotate = 0, idx; |
| 3493 | 3463 | |
| 3494 | − if (fbcon_has_exited) | |
| 3495 | − return 0; | |
| 3496 | − | |
| 3497 | 3464 | console_lock(); |
| 3498 | 3465 | idx = con2fb_map[fg_console]; |
| 3499 | 3466 | |
| @@ -3514,9 +3481,6 @@ static ssize_t show_cursor_blink(struct device *device, · 14 unmodified lines | ||
| 3514 | 3481 | struct fbcon_ops *ops; |
| 3515 | 3482 | int idx, blink = -1; |
| 3516 | 3483 | |
| 3517 | − if (fbcon_has_exited) | |
| 3518 | − return 0; | |
| 3519 | − | |
| 3520 | 3484 | console_lock(); |
| 3521 | 3485 | idx = con2fb_map[fg_console]; |
| 3522 | 3486 | |
| @@ -3543,9 +3507,6 @@ static ssize_t store_cursor_blink(struct device *device, · 20 unmodified lines | ||
| 3543 | 3507 | int blink, idx; |
| 3544 | 3508 | char **last = NULL; |
| 3545 | 3509 | |
| 3546 | − if (fbcon_has_exited) | |
| 3547 | − return count; | |
| 3548 | − | |
| 3549 | 3510 | console_lock(); |
| 3550 | 3511 | idx = con2fb_map[fg_console]; |
| 3551 | 3512 | |
| @@ -3668,9 +3629,6 @@ static void fbcon_exit(void) · 116 unmodified lines | ||
| 3668 | 3629 | struct fb_info *info; |
| 3669 | 3630 | int i, j, mapped; |
| 3670 | 3631 | |
| 3671 | − if (fbcon_has_exited) | |
| 3672 | − return; | |
| 3673 | − | |
| 3674 | 3632 | #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER |
| 3675 | 3633 | if (deferred_takeover) { |
| 3676 | 3634 | dummycon_unregister_output_notifier(&fbcon_output_nb); |
| @@ -3695,7 +3653,7 @@ static void fbcon_exit(void) · 18 unmodified lines | ||
| 3695 | 3653 | for (j = first_fb_vc; j <= last_fb_vc; j++) { |
| 3696 | 3654 | if (con2fb_map[j] == i) { |
| 3697 | 3655 | mapped = 1; |
| 3698 | − break; | |
| 3656 | + con2fb_map[j] = -1; | |
| 3699 | 3657 | } |
| 3700 | 3658 | } |
| 3701 | 3659 | |
| @@ -3718,8 +3676,6 @@ static void fbcon_exit(void) · 16 unmodified lines | ||
| 3718 | 3676 | info->queue.func = NULL; |
| 3719 | 3677 | } |
| 3720 | 3678 | } |
| 3721 | − | |
| 3722 | − fbcon_has_exited = 1; | |
| 3723 | 3679 | } |
| 3724 | 3680 | |
| 3725 | 3681 | void __init fb_console_init(void) |
| @@ -3727,7 +3683,6 @@ void __init fb_console_init(void) · 1 unmodified line | ||
| 3727 | 3683 | int i; |
| 3728 | 3684 | |
| 3729 | 3685 | console_lock(); |
| 3730 | − fb_register_client(&fbcon_event_notifier); | |
| 3731 | 3686 | fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL, |
| 3732 | 3687 | "fbcon"); |
| 3733 | 3688 | |
| @@ -3763,7 +3718,6 @@ static void __exit fbcon_deinit_device(void) · 29 unmodified lines | ||
| 3763 | 3718 | void __exit fb_console_exit(void) |
| 3764 | 3719 | { |
| 3765 | 3720 | console_lock(); |
| 3766 | − fb_unregister_client(&fbcon_event_notifier); | |
| 3767 | 3721 | fbcon_deinit_device(); |
| 3768 | 3722 | device_destroy(fb_class, MKDEV(0, 0)); |
| 3769 | 3723 | fbcon_exit(); |
| @@ -25,7 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | * low-level frame buffer device |
| 26 | 26 | */ |
| 27 | 27 | |
| 28 | −struct display { | |
| 28 | +struct fbcon_display { | |
| 29 | 29 | /* Filled in by the low-level console driver */ |
| 30 | 30 | const u_char *fontdata; |
| 31 | 31 | int userfont; /* != 0 if fontdata kmalloc()ed */ |
| @@ -68,7 +68,7 @@ struct fbcon_ops { · 36 unmodified lines | ||
| 68 | 68 | struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */ |
| 69 | 69 | struct timer_list cursor_timer; /* Cursor timer */ |
| 70 | 70 | struct fb_cursor cursor_state; |
| 71 | − struct display *p; | |
| 71 | + struct fbcon_display *p; | |
| 72 | 72 | struct fb_info *info; |
| 73 | 73 | int currcon; /* Current VC. */ |
| 74 | 74 | int cur_blink_jiffies; |
| @@ -225,7 +225,7 @@ extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor); · 150 unmodified lines | ||
| 225 | 225 | #define FBCON_ATTRIBUTE_REVERSE 2 |
| 226 | 226 | #define FBCON_ATTRIBUTE_BOLD 4 |
| 227 | 227 | |
| 228 | −static inline int real_y(struct display *p, int ypos) | |
| 228 | +static inline int real_y(struct fbcon_display *p, int ypos) | |
| 229 | 229 | { |
| 230 | 230 | int rows = p->vrows; |
| 231 | 231 | |
| @@ -80,17 +80,6 @@ static void put_fb_info(struct fb_info *fb_info) · 79 unmodified lines | ||
| 80 | 80 | fb_info->fbops->fb_destroy(fb_info); |
| 81 | 81 | } |
| 82 | 82 | |
| 83 | −int lock_fb_info(struct fb_info *info) | |
| 84 | −{ | |
| 85 | − mutex_lock(&info->lock); | |
| 86 | − if (!info->fbops) { | |
| 87 | − mutex_unlock(&info->lock); | |
| 88 | − return 0; | |
| 89 | − } | |
| 90 | − return 1; | |
| 91 | −} | |
| 92 | −EXPORT_SYMBOL(lock_fb_info); | |
| 93 | − | |
| 94 | 83 | /* |
| 95 | 84 | * Helpers |
| 96 | 85 | */ |
| @@ -943,16 +932,13 @@ EXPORT_SYMBOL(fb_pan_display); · 846 unmodified lines | ||
| 943 | 932 | static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var, |
| 944 | 933 | u32 activate) |
| 945 | 934 | { |
| 946 | − struct fb_event event; | |
| 947 | 935 | struct fb_blit_caps caps, fbcaps; |
| 948 | 936 | int err = 0; |
| 949 | 937 | |
| 950 | 938 | memset(&caps, 0, sizeof(caps)); |
| 951 | 939 | memset(&fbcaps, 0, sizeof(fbcaps)); |
| 952 | 940 | caps.flags = (activate & FB_ACTIVATE_ALL) ? 1 : 0; |
| 953 | − event.info = info; | |
| 954 | − event.data = ∩︀ | |
| 955 | − fb_notifier_call_chain(FB_EVENT_GET_REQ, &event); | |
| 941 | + fbcon_get_requirement(info, &caps); | |
| 956 | 942 | info->fbops->fb_get_caps(info, &fbcaps, var); |
| 957 | 943 | |
| 958 | 944 | if (((fbcaps.x ^ caps.x) & caps.x) || |
| @@ -968,6 +954,10 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) · 9 unmodified lines | ||
| 968 | 954 | { |
| 969 | 955 | int flags = info->flags; |
| 970 | 956 | int ret = 0; |
| 957 | + u32 activate; | |
| 958 | + struct fb_var_screeninfo old_var; | |
| 959 | + struct fb_videomode mode; | |
| 960 | + struct fb_event event; | |
| 971 | 961 | |
| 972 | 962 | if (var->activate & FB_ACTIVATE_INV_MODE) { |
| 973 | 963 | struct fb_videomode mode1, mode2; |
| @@ -977,100 +967,90 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) · 3 unmodified lines | ||
| 977 | 967 | /* make sure we don't delete the videomode of current var */ |
| 978 | 968 | ret = fb_mode_is_equal(&mode1, &mode2); |
| 979 | 969 | |
| 980 | − if (!ret) { | |
| 981 | − struct fb_event event; | |
| 982 | − | |
| 983 | − event.info = info; | |
| 984 | − event.data = &mode1; | |
| 985 | − ret = fb_notifier_call_chain(FB_EVENT_MODE_DELETE, &event); | |
| 986 | − } | |
| 970 | + if (!ret) | |
| 971 | + fbcon_mode_deleted(info, &mode1); | |
| 987 | 972 | |
| 988 | 973 | if (!ret) |
| 989 | − fb_delete_videomode(&mode1, &info->modelist); | |
| 974 | + fb_delete_videomode(&mode1, &info->modelist); | |
| 990 | 975 | |
| 991 | 976 | |
| 992 | − ret = (ret) ? -EINVAL : 0; | |
| 993 | − goto done; | |
| 977 | + return ret ? -EINVAL : 0; | |
| 994 | 978 | } |
| 995 | 979 | |
| 996 | − if ((var->activate & FB_ACTIVATE_FORCE) || | |
| 997 | − memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) { | |
| 998 | − u32 activate = var->activate; | |
| 980 | + if (!(var->activate & FB_ACTIVATE_FORCE) && | |
| 981 | + !memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) | |
| 982 | + return 0; | |
| 999 | 983 | |
| 1000 | − /* When using FOURCC mode, make sure the red, green, blue and | |
| 1001 | − * transp fields are set to 0. | |
| 1002 | − */ | |
| 1003 | − if ((info->fix.capabilities & FB_CAP_FOURCC) && | |
| 1004 | − var->grayscale > 1) { | |
| 1005 | − if (var->red.offset || var->green.offset || | |
| 1006 | − var->blue.offset || var->transp.offset || | |
| 1007 | − var->red.length || var->green.length || | |
| 1008 | − var->blue.length || var->transp.length || | |
| 1009 | − var->red.msb_right || var->green.msb_right || | |
| 1010 | − var->blue.msb_right || var->transp.msb_right) | |
| 1011 | − return -EINVAL; | |
| 1012 | − } | |
| 984 | + activate = var->activate; | |
| 1013 | 985 | |
| 1014 | − if (!info->fbops->fb_check_var) { | |
| 1015 | − *var = info->var; | |
| 1016 | − goto done; | |
| 1017 | − } | |
| 986 | + /* When using FOURCC mode, make sure the red, green, blue and | |
| 987 | + * transp fields are set to 0. | |
| 988 | + */ | |
| 989 | + if ((info->fix.capabilities & FB_CAP_FOURCC) && | |
| 990 | + var->grayscale > 1) { | |
| 991 | + if (var->red.offset || var->green.offset || | |
| 992 | + var->blue.offset || var->transp.offset || | |
| 993 | + var->red.length || var->green.length || | |
| 994 | + var->blue.length || var->transp.length || | |
| 995 | + var->red.msb_right || var->green.msb_right || | |
| 996 | + var->blue.msb_right || var->transp.msb_right) | |
| 997 | + return -EINVAL; | |
| 998 | + } | |
| 1018 | 999 | |
| 1019 | − ret = info->fbops->fb_check_var(var, info); | |
| 1000 | + if (!info->fbops->fb_check_var) { | |
| 1001 | + *var = info->var; | |
| 1002 | + return 0; | |
| 1003 | + } | |
| 1020 | 1004 | |
| 1021 | − if (ret) | |
| 1022 | − goto done; | |
| 1005 | + ret = info->fbops->fb_check_var(var, info); | |
| 1023 | 1006 | |
| 1024 | − if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { | |
| 1025 | − struct fb_var_screeninfo old_var; | |
| 1026 | − struct fb_videomode mode; | |
| 1007 | + if (ret) | |
| 1008 | + return ret; | |
| 1027 | 1009 | |
| 1028 | − if (info->fbops->fb_get_caps) { | |
| 1029 | − ret = fb_check_caps(info, var, activate); | |
| 1010 | + if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) | |
| 1011 | + return 0; | |
| 1030 | 1012 | |
| 1031 | − if (ret) | |
| 1032 | − goto done; | |
| 1033 | − } | |
| 1013 | + if (info->fbops->fb_get_caps) { | |
| 1014 | + ret = fb_check_caps(info, var, activate); | |
| 1034 | 1015 | |
| 1035 | − old_var = info->var; | |
| 1036 | − info->var = *var; | |
| 1016 | + if (ret) | |
| 1017 | + return ret; | |
| 1018 | + } | |
| 1037 | 1019 | |
| 1038 | − if (info->fbops->fb_set_par) { | |
| 1039 | − ret = info->fbops->fb_set_par(info); | |
| 1020 | + old_var = info->var; | |
| 1021 | + info->var = *var; | |
| 1040 | 1022 | |
| 1041 | − if (ret) { | |
| 1042 | − info->var = old_var; | |
| 1043 | − printk(KERN_WARNING "detected " | |
| 1044 | − "fb_set_par error, " | |
| 1045 | − "error code: %d\n", ret); | |
| 1046 | − goto done; | |
| 1047 | − } | |
| 1048 | − } | |
| 1023 | + if (info->fbops->fb_set_par) { | |
| 1024 | + ret = info->fbops->fb_set_par(info); | |
| 1049 | 1025 | |
| 1050 | − fb_pan_display(info, &info->var); | |
| 1051 | − fb_set_cmap(&info->cmap, info); | |
| 1052 | − fb_var_to_videomode(&mode, &info->var); | |
| 1026 | + if (ret) { | |
| 1027 | + info->var = old_var; | |
| 1028 | + printk(KERN_WARNING "detected " | |
| 1029 | + "fb_set_par error, " | |
| 1030 | + "error code: %d\n", ret); | |
| 1031 | + return ret; | |
| 1032 | + } | |
| 1033 | + } | |
| 1053 | 1034 | |
| 1054 | − if (info->modelist.prev && info->modelist.next && | |
| 1055 | − !list_empty(&info->modelist)) | |
| 1056 | − ret = fb_add_videomode(&mode, &info->modelist); | |
| 1035 | + fb_pan_display(info, &info->var); | |
| 1036 | + fb_set_cmap(&info->cmap, info); | |
| 1037 | + fb_var_to_videomode(&mode, &info->var); | |
| 1057 | 1038 | |
| 1058 | − if (!ret && (flags & FBINFO_MISC_USEREVENT)) { | |
| 1059 | − struct fb_event event; | |
| 1060 | − int evnt = (activate & FB_ACTIVATE_ALL) ? | |
| 1061 | − FB_EVENT_MODE_CHANGE_ALL : | |
| 1062 | − FB_EVENT_MODE_CHANGE; | |
| 1039 | + if (info->modelist.prev && info->modelist.next && | |
| 1040 | + !list_empty(&info->modelist)) | |
| 1041 | + ret = fb_add_videomode(&mode, &info->modelist); | |
| 1063 | 1042 | |
| 1064 | − info->flags &= ~FBINFO_MISC_USEREVENT; | |
| 1065 | − event.info = info; | |
| 1066 | − event.data = &mode; | |
| 1067 | − fb_notifier_call_chain(evnt, &event); | |
| 1068 | − } | |
| 1069 | − } | |
| 1070 | − } | |
| 1043 | + if (ret) | |
| 1044 | + return ret; | |
| 1071 | 1045 | |
| 1072 | − done: | |
| 1073 | − return ret; | |
| 1046 | + event.info = info; | |
| 1047 | + event.data = &mode; | |
| 1048 | + fb_notifier_call_chain(FB_EVENT_MODE_CHANGE, &event); | |
| 1049 | + | |
| 1050 | + if (flags & FBINFO_MISC_USEREVENT) | |
| 1051 | + fbcon_update_vcs(info, activate & FB_ACTIVATE_ALL); | |
| 1052 | + | |
| 1053 | + return 0; | |
| 1074 | 1054 | } |
| 1075 | 1055 | EXPORT_SYMBOL(fb_set_var); |
| 1076 | 1056 | |
| @@ -1112,17 +1092,14 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, · 35 unmodified lines | ||
| 1112 | 1092 | struct fb_ops *fb; |
| 1113 | 1093 | struct fb_var_screeninfo var; |
| 1114 | 1094 | struct fb_fix_screeninfo fix; |
| 1115 | − struct fb_con2fbmap con2fb; | |
| 1116 | 1095 | struct fb_cmap cmap_from; |
| 1117 | 1096 | struct fb_cmap_user cmap; |
| 1118 | − struct fb_event event; | |
| 1119 | 1097 | void __user *argp = (void __user *)arg; |
| 1120 | 1098 | long ret = 0; |
| 1121 | 1099 | |
| 1122 | 1100 | switch (cmd) { |
| 1123 | 1101 | case FBIOGET_VSCREENINFO: |
| 1124 | − if (!lock_fb_info(info)) | |
| 1125 | − return -ENODEV; | |
| 1102 | + lock_fb_info(info); | |
| 1126 | 1103 | var = info->var; |
| 1127 | 1104 | unlock_fb_info(info); |
| 1128 | 1105 | |
| @@ -1132,10 +1109,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, · 3 unmodified lines | ||
| 1132 | 1109 | if (copy_from_user(&var, argp, sizeof(var))) |
| 1133 | 1110 | return -EFAULT; |
| 1134 | 1111 | console_lock(); |
| 1135 | − if (!lock_fb_info(info)) { | |
| 1136 | − console_unlock(); | |
| 1137 | − return -ENODEV; | |
| 1138 | − } | |
| 1112 | + lock_fb_info(info); | |
| 1139 | 1113 | info->flags |= FBINFO_MISC_USEREVENT; |
| 1140 | 1114 | ret = fb_set_var(info, &var); |
| 1141 | 1115 | info->flags &= ~FBINFO_MISC_USEREVENT; |
| @@ -1145,8 +1119,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, · 3 unmodified lines | ||
| 1145 | 1119 | ret = -EFAULT; |
| 1146 | 1120 | break; |
| 1147 | 1121 | case FBIOGET_FSCREENINFO: |
| 1148 | − if (!lock_fb_info(info)) | |
| 1149 | − return -ENODEV; | |
| 1122 | + lock_fb_info(info); | |
| 1150 | 1123 | fix = info->fix; |
| 1151 | 1124 | if (info->flags & FBINFO_HIDE_SMEM_START) |
| 1152 | 1125 | fix.smem_start = 0; |
| @@ -1162,8 +1135,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, · 9 unmodified lines | ||
| 1162 | 1135 | case FBIOGETCMAP: |
| 1163 | 1136 | if (copy_from_user(&cmap, argp, sizeof(cmap))) |
| 1164 | 1137 | return -EFAULT; |
| 1165 | − if (!lock_fb_info(info)) | |
| 1166 | − return -ENODEV; | |
| 1138 | + lock_fb_info(info); | |
| 1167 | 1139 | cmap_from = info->cmap; |
| 1168 | 1140 | unlock_fb_info(info); |
| 1169 | 1141 | ret = fb_cmap_to_user(&cmap_from, &cmap); |
| @@ -1172,10 +1144,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, · 2 unmodified lines | ||
| 1172 | 1144 | if (copy_from_user(&var, argp, sizeof(var))) |
| 1173 | 1145 | return -EFAULT; |
| 1174 | 1146 | console_lock(); |
| 1175 | − if (!lock_fb_info(info)) { | |
| 1176 | − console_unlock(); | |
| 1177 | − return -ENODEV; | |
| 1178 | − } | |
| 1147 | + lock_fb_info(info); | |
| 1179 | 1148 | ret = fb_pan_display(info, &var); |
| 1180 | 1149 | unlock_fb_info(info); |
| 1181 | 1150 | console_unlock(); |
| @@ -1186,58 +1155,22 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, · 4 unmodified lines | ||
| 1186 | 1155 | ret = -EINVAL; |
| 1187 | 1156 | break; |
| 1188 | 1157 | case FBIOGET_CON2FBMAP: |
| 1189 | − if (copy_from_user(&con2fb, argp, sizeof(con2fb))) | |
| 1190 | − return -EFAULT; | |
| 1191 | − if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) | |
| 1192 | − return -EINVAL; | |
| 1193 | − con2fb.framebuffer = -1; | |
| 1194 | − event.data = &con2fb; | |
| 1195 | − if (!lock_fb_info(info)) | |
| 1196 | − return -ENODEV; | |
| 1197 | − event.info = info; | |
| 1198 | − fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event); | |
| 1199 | − unlock_fb_info(info); | |
| 1200 | − ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0; | |
| 1158 | + ret = fbcon_get_con2fb_map_ioctl(argp); | |
| 1201 | 1159 | break; |
| 1202 | 1160 | case FBIOPUT_CON2FBMAP: |
| 1203 | − if (copy_from_user(&con2fb, argp, sizeof(con2fb))) | |
| 1204 | − return -EFAULT; | |
| 1205 | − if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) | |
| 1206 | − return -EINVAL; | |
| 1207 | − if (con2fb.framebuffer >= FB_MAX) | |
| 1208 | − return -EINVAL; | |
| 1209 | − if (!registered_fb[con2fb.framebuffer]) | |
| 1210 | − request_module("fb%d", con2fb.framebuffer); | |
| 1211 | − if (!registered_fb[con2fb.framebuffer]) { | |
| 1212 | − ret = -EINVAL; | |
| 1213 | − break; | |
| 1214 | − } | |
| 1215 | − event.data = &con2fb; | |
| 1216 | − console_lock(); | |
| 1217 | − if (!lock_fb_info(info)) { | |
| 1218 | − console_unlock(); | |
| 1219 | − return -ENODEV; | |
| 1220 | − } | |
| 1221 | − event.info = info; | |
| 1222 | − ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event); | |
| 1223 | − unlock_fb_info(info); | |
| 1224 | − console_unlock(); | |
| 1161 | + ret = fbcon_set_con2fb_map_ioctl(argp); | |
| 1225 | 1162 | break; |
| 1226 | 1163 | case FBIOBLANK: |
| 1227 | 1164 | console_lock(); |
| 1228 | − if (!lock_fb_info(info)) { | |
| 1229 | − console_unlock(); | |
| 1230 | − return -ENODEV; | |
| 1231 | − } | |
| 1232 | − info->flags |= FBINFO_MISC_USEREVENT; | |
| 1165 | + lock_fb_info(info); | |
| 1233 | 1166 | ret = fb_blank(info, arg); |
| 1234 | − info->flags &= ~FBINFO_MISC_USEREVENT; | |
| 1167 | + /* might again call into fb_blank */ | |
| 1168 | + fbcon_fb_blanked(info, arg); | |
| 1235 | 1169 | unlock_fb_info(info); |
| 1236 | 1170 | console_unlock(); |
| 1237 | 1171 | break; |
| 1238 | 1172 | default: |
| 1239 | − if (!lock_fb_info(info)) | |
| 1240 | − return -ENODEV; | |
| 1173 | + lock_fb_info(info); | |
| 1241 | 1174 | fb = info->fbops; |
| 1242 | 1175 | if (fb->fb_ioctl) |
| 1243 | 1176 | ret = fb->fb_ioctl(info, cmd, arg); |
| @@ -1357,8 +1290,7 @@ static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd, · 113 unmodified lines | ||
| 1357 | 1290 | { |
| 1358 | 1291 | struct fb_fix_screeninfo fix; |
| 1359 | 1292 | |
| 1360 | − if (!lock_fb_info(info)) | |
| 1361 | − return -ENODEV; | |
| 1293 | + lock_fb_info(info); | |
| 1362 | 1294 | fix = info->fix; |
| 1363 | 1295 | if (info->flags & FBINFO_HIDE_SMEM_START) |
| 1364 | 1296 | fix.smem_start = 0; |
| @@ -1418,8 +1350,6 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) · 53 unmodified lines | ||
| 1418 | 1350 | if (!info) |
| 1419 | 1351 | return -ENODEV; |
| 1420 | 1352 | fb = info->fbops; |
| 1421 | − if (!fb) | |
| 1422 | − return -ENODEV; | |
| 1423 | 1353 | mutex_lock(&info->mm_lock); |
| 1424 | 1354 | if (fb->fb_mmap) { |
| 1425 | 1355 | int res; |
| @@ -1483,7 +1413,7 @@ __releases(&info->lock) · 57 unmodified lines | ||
| 1483 | 1413 | if (IS_ERR(info)) |
| 1484 | 1414 | return PTR_ERR(info); |
| 1485 | 1415 | |
| 1486 | − mutex_lock(&info->lock); | |
| 1416 | + lock_fb_info(info); | |
| 1487 | 1417 | if (!try_module_get(info->fbops->owner)) { |
| 1488 | 1418 | res = -ENODEV; |
| 1489 | 1419 | goto out; |
| @@ -1499,7 +1429,7 @@ __releases(&info->lock) · 9 unmodified lines | ||
| 1499 | 1429 | fb_deferred_io_open(info, inode, file); |
| 1500 | 1430 | #endif |
| 1501 | 1431 | out: |
| 1502 | − mutex_unlock(&info->lock); | |
| 1432 | + unlock_fb_info(info); | |
| 1503 | 1433 | if (res) |
| 1504 | 1434 | put_fb_info(info); |
| 1505 | 1435 | return res; |
| @@ -1512,11 +1442,11 @@ __releases(&info->lock) · 6 unmodified lines | ||
| 1512 | 1442 | { |
| 1513 | 1443 | struct fb_info * const info = file->private_data; |
| 1514 | 1444 | |
| 1515 | − mutex_lock(&info->lock); | |
| 1445 | + lock_fb_info(info); | |
| 1516 | 1446 | if (info->fbops->fb_release) |
| 1517 | 1447 | info->fbops->fb_release(info,1); |
| 1518 | 1448 | module_put(info->fbops->owner); |
| 1519 | − mutex_unlock(&info->lock); | |
| 1449 | + unlock_fb_info(info); | |
| 1520 | 1450 | put_fb_info(info); |
| 1521 | 1451 | return 0; |
| 1522 | 1452 | } |
| @@ -1621,13 +1551,13 @@ static bool fb_do_apertures_overlap(struct apertures_struct *gena, · 98 unmodified lines | ||
| 1621 | 1551 | return false; |
| 1622 | 1552 | } |
| 1623 | 1553 | |
| 1624 | −static int do_unregister_framebuffer(struct fb_info *fb_info); | |
| 1554 | +static void do_unregister_framebuffer(struct fb_info *fb_info); | |
| 1625 | 1555 | |
| 1626 | 1556 | #define VGA_FB_PHYS 0xA0000 |
| 1627 | −static int do_remove_conflicting_framebuffers(struct apertures_struct *a, | |
| 1628 | − const char *name, bool primary) | |
| 1557 | +static void do_remove_conflicting_framebuffers(struct apertures_struct *a, | |
| 1558 | + const char *name, bool primary) | |
| 1629 | 1559 | { |
| 1630 | − int i, ret; | |
| 1560 | + int i; | |
| 1631 | 1561 | |
| 1632 | 1562 | /* check all firmware fbs and kick off if the base addr overlaps */ |
| 1633 | 1563 | for_each_registered_fb(i) { |
| @@ -1643,13 +1573,9 @@ static int do_remove_conflicting_framebuffers(struct apertures_struct *a, · 9 unmodified lines | ||
| 1643 | 1573 | |
| 1644 | 1574 | printk(KERN_INFO "fb%d: switching to %s from %s\n", |
| 1645 | 1575 | i, name, registered_fb[i]->fix.id); |
| 1646 | − ret = do_unregister_framebuffer(registered_fb[i]); | |
| 1647 | − if (ret) | |
| 1648 | − return ret; | |
| 1576 | + do_unregister_framebuffer(registered_fb[i]); | |
| 1649 | 1577 | } |
| 1650 | 1578 | } |
| 1651 | − | |
| 1652 | − return 0; | |
| 1653 | 1579 | } |
| 1654 | 1580 | |
| 1655 | 1581 | static bool lockless_register_fb; |
| @@ -1660,17 +1586,14 @@ MODULE_PARM_DESC(lockless_register_fb, · 4 unmodified lines | ||
| 1660 | 1586 | static int do_register_framebuffer(struct fb_info *fb_info) |
| 1661 | 1587 | { |
| 1662 | 1588 | int i, ret; |
| 1663 | − struct fb_event event; | |
| 1664 | 1589 | struct fb_videomode mode; |
| 1665 | 1590 | |
| 1666 | 1591 | if (fb_check_foreignness(fb_info)) |
| 1667 | 1592 | return -ENOSYS; |
| 1668 | 1593 | |
| 1669 | − ret = do_remove_conflicting_framebuffers(fb_info->apertures, | |
| 1670 | − fb_info->fix.id, | |
| 1671 | − fb_is_primary_device(fb_info)); | |
| 1672 | − if (ret) | |
| 1673 | − return ret; | |
| 1594 | + do_remove_conflicting_framebuffers(fb_info->apertures, | |
| 1595 | + fb_info->fix.id, | |
| 1596 | + fb_is_primary_device(fb_info)); | |
| 1674 | 1597 | |
| 1675 | 1598 | if (num_registered_fb == FB_MAX) |
| 1676 | 1599 | return -ENXIO; |
| @@ -1723,20 +1646,22 @@ static int do_register_framebuffer(struct fb_info *fb_info) · 46 unmodified lines | ||
| 1723 | 1646 | fb_add_videomode(&mode, &fb_info->modelist); |
| 1724 | 1647 | registered_fb[i] = fb_info; |
| 1725 | 1648 | |
| 1726 | − event.info = fb_info; | |
| 1649 | +#ifdef CONFIG_GUMSTIX_AM200EPD | |
| 1650 | + { | |
| 1651 | + struct fb_event event; | |
| 1652 | + event.info = fb_info; | |
| 1653 | + fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event); | |
| 1654 | + } | |
| 1655 | +#endif | |
| 1656 | + | |
| 1727 | 1657 | if (!lockless_register_fb) |
| 1728 | 1658 | console_lock(); |
| 1729 | 1659 | else |
| 1730 | 1660 | atomic_inc(&ignore_console_lock_warning); |
| 1731 | − if (!lock_fb_info(fb_info)) { | |
| 1732 | − ret = -ENODEV; | |
| 1733 | − goto unlock_console; | |
| 1734 | − } | |
| 1735 | − ret = 0; | |
| 1736 | − | |
| 1737 | − fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event); | |
| 1661 | + lock_fb_info(fb_info); | |
| 1662 | + ret = fbcon_fb_registered(fb_info); | |
| 1738 | 1663 | unlock_fb_info(fb_info); |
| 1739 | −unlock_console: | |
| 1664 | + | |
| 1740 | 1665 | if (!lockless_register_fb) |
| 1741 | 1666 | console_unlock(); |
| 1742 | 1667 | else |
| @@ -1744,44 +1669,44 @@ unlock_console: · 1 unmodified line | ||
| 1744 | 1669 | return ret; |
| 1745 | 1670 | } |
| 1746 | 1671 | |
| 1747 | −static int unbind_console(struct fb_info *fb_info) | |
| 1672 | +static void unbind_console(struct fb_info *fb_info) | |
| 1748 | 1673 | { |
| 1749 | − struct fb_event event; | |
| 1750 | − int ret; | |
| 1751 | 1674 | int i = fb_info->node; |
| 1752 | 1675 | |
| 1753 | − if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info) | |
| 1754 | − return -EINVAL; | |
| 1676 | + if (WARN_ON(i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)) | |
| 1677 | + return; | |
| 1755 | 1678 | |
| 1756 | 1679 | console_lock(); |
| 1757 | − if (!lock_fb_info(fb_info)) { | |
| 1758 | − console_unlock(); | |
| 1759 | − return -ENODEV; | |
| 1760 | − } | |
| 1761 | − | |
| 1762 | − event.info = fb_info; | |
| 1763 | − ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); | |
| 1680 | + lock_fb_info(fb_info); | |
| 1681 | + fbcon_fb_unbind(fb_info); | |
| 1764 | 1682 | unlock_fb_info(fb_info); |
| 1765 | 1683 | console_unlock(); |
| 1766 | − | |
| 1767 | − return ret; | |
| 1768 | 1684 | } |
| 1769 | 1685 | |
| 1770 | −static int __unlink_framebuffer(struct fb_info *fb_info); | |
| 1771 | − | |
| 1772 | −static int do_unregister_framebuffer(struct fb_info *fb_info) | |
| 1686 | +void unlink_framebuffer(struct fb_info *fb_info) | |
| 1773 | 1687 | { |
| 1774 | − struct fb_event event; | |
| 1775 | − int ret; | |
| 1688 | + int i; | |
| 1689 | + | |
| 1690 | + i = fb_info->node; | |
| 1691 | + if (WARN_ON(i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)) | |
| 1692 | + return; | |
| 1776 | 1693 | |
| 1777 | − ret = unbind_console(fb_info); | |
| 1694 | + if (!fb_info->dev) | |
| 1695 | + return; | |
| 1778 | 1696 | |
| 1779 | − if (ret) | |
| 1780 | − return -EINVAL; | |
| 1697 | + device_destroy(fb_class, MKDEV(FB_MAJOR, i)); | |
| 1781 | 1698 | |
| 1782 | 1699 | pm_vt_switch_unregister(fb_info->dev); |
| 1783 | 1700 | |
| 1784 | − __unlink_framebuffer(fb_info); | |
| 1701 | + unbind_console(fb_info); | |
| 1702 | + | |
| 1703 | + fb_info->dev = NULL; | |
| 1704 | +} | |
| 1705 | +EXPORT_SYMBOL(unlink_framebuffer); | |
| 1706 | + | |
| 1707 | +static void do_unregister_framebuffer(struct fb_info *fb_info) | |
| 1708 | +{ | |
| 1709 | + unlink_framebuffer(fb_info); | |
| 1785 | 1710 | if (fb_info->pixmap.addr && |
| 1786 | 1711 | (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) |
| 1787 | 1712 | kfree(fb_info->pixmap.addr); |
| @@ -1789,46 +1714,21 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) · 1 unmodified line | ||
| 1789 | 1714 | registered_fb[fb_info->node] = NULL; |
| 1790 | 1715 | num_registered_fb--; |
| 1791 | 1716 | fb_cleanup_device(fb_info); |
| 1792 | − event.info = fb_info; | |
| 1717 | +#ifdef CONFIG_GUMSTIX_AM200EPD | |
| 1718 | + { | |
| 1719 | + struct fb_event event; | |
| 1720 | + event.info = fb_info; | |
| 1721 | + fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); | |
| 1722 | + } | |
| 1723 | +#endif | |
| 1793 | 1724 | console_lock(); |
| 1794 | − fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); | |
| 1725 | + fbcon_fb_unregistered(fb_info); | |
| 1795 | 1726 | console_unlock(); |
| 1796 | 1727 | |
| 1797 | 1728 | /* this may free fb info */ |
| 1798 | 1729 | put_fb_info(fb_info); |
| 1799 | − return 0; | |
| 1800 | 1730 | } |
| 1801 | 1731 | |
| 1802 | −static int __unlink_framebuffer(struct fb_info *fb_info) | |
| 1803 | −{ | |
| 1804 | − int i; | |
| 1805 | − | |
| 1806 | − i = fb_info->node; | |
| 1807 | − if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info) | |
| 1808 | − return -EINVAL; | |
| 1809 | − | |
| 1810 | − if (fb_info->dev) { | |
| 1811 | − device_destroy(fb_class, MKDEV(FB_MAJOR, i)); | |
| 1812 | − fb_info->dev = NULL; | |
| 1813 | − } | |
| 1814 | − | |
| 1815 | − return 0; | |
| 1816 | −} | |
| 1817 | − | |
| 1818 | −int unlink_framebuffer(struct fb_info *fb_info) | |
| 1819 | −{ | |
| 1820 | − int ret; | |
| 1821 | − | |
| 1822 | − ret = __unlink_framebuffer(fb_info); | |
| 1823 | − if (ret) | |
| 1824 | − return ret; | |
| 1825 | − | |
| 1826 | − unbind_console(fb_info); | |
| 1827 | − | |
| 1828 | − return 0; | |
| 1829 | −} | |
| 1830 | −EXPORT_SYMBOL(unlink_framebuffer); | |
| 1831 | − | |
| 1832 | 1732 | /** |
| 1833 | 1733 | * remove_conflicting_framebuffers - remove firmware-configured framebuffers |
| 1834 | 1734 | * @a: memory range, users of which are to be removed |
| @@ -1842,7 +1742,6 @@ EXPORT_SYMBOL(unlink_framebuffer); · 7 unmodified lines | ||
| 1842 | 1742 | int remove_conflicting_framebuffers(struct apertures_struct *a, |
| 1843 | 1743 | const char *name, bool primary) |
| 1844 | 1744 | { |
| 1845 | − int ret; | |
| 1846 | 1745 | bool do_free = false; |
| 1847 | 1746 | |
| 1848 | 1747 | if (!a) { |
| @@ -1856,13 +1755,13 @@ int remove_conflicting_framebuffers(struct apertures_struct *a, · 7 unmodified lines | ||
| 1856 | 1755 | } |
| 1857 | 1756 | |
| 1858 | 1757 | mutex_lock(®istration_lock); |
| 1859 | − ret = do_remove_conflicting_framebuffers(a, name, primary); | |
| 1758 | + do_remove_conflicting_framebuffers(a, name, primary); | |
| 1860 | 1759 | mutex_unlock(®istration_lock); |
| 1861 | 1760 | |
| 1862 | 1761 | if (do_free) |
| 1863 | 1762 | kfree(a); |
| 1864 | 1763 | |
| 1865 | − return ret; | |
| 1764 | + return 0; | |
| 1866 | 1765 | } |
| 1867 | 1766 | EXPORT_SYMBOL(remove_conflicting_framebuffers); |
| 1868 | 1767 | |
| @@ -1959,16 +1858,12 @@ EXPORT_SYMBOL(register_framebuffer); · 90 unmodified lines | ||
| 1959 | 1858 | * that the driver implements fb_open() and fb_release() to |
| 1960 | 1859 | * check that no processes are using the device. |
| 1961 | 1860 | */ |
| 1962 | −int | |
| 1861 | +void | |
| 1963 | 1862 | unregister_framebuffer(struct fb_info *fb_info) |
| 1964 | 1863 | { |
| 1965 | − int ret; | |
| 1966 | − | |
| 1967 | 1864 | mutex_lock(®istration_lock); |
| 1968 | − ret = do_unregister_framebuffer(fb_info); | |
| 1865 | + do_unregister_framebuffer(fb_info); | |
| 1969 | 1866 | mutex_unlock(®istration_lock); |
| 1970 | − | |
| 1971 | − return ret; | |
| 1972 | 1867 | } |
| 1973 | 1868 | EXPORT_SYMBOL(unregister_framebuffer); |
| 1974 | 1869 | |
| @@ -1983,15 +1878,14 @@ EXPORT_SYMBOL(unregister_framebuffer); · 8 unmodified lines | ||
| 1983 | 1878 | */ |
| 1984 | 1879 | void fb_set_suspend(struct fb_info *info, int state) |
| 1985 | 1880 | { |
| 1986 | − struct fb_event event; | |
| 1881 | + WARN_CONSOLE_UNLOCKED(); | |
| 1987 | 1882 | |
| 1988 | − event.info = info; | |
| 1989 | 1883 | if (state) { |
| 1990 | − fb_notifier_call_chain(FB_EVENT_SUSPEND, &event); | |
| 1884 | + fbcon_suspended(info); | |
| 1991 | 1885 | info->state = FBINFO_STATE_SUSPENDED; |
| 1992 | 1886 | } else { |
| 1993 | 1887 | info->state = FBINFO_STATE_RUNNING; |
| 1994 | − fb_notifier_call_chain(FB_EVENT_RESUME, &event); | |
| 1888 | + fbcon_resumed(info); | |
| 1995 | 1889 | } |
| 1996 | 1890 | } |
| 1997 | 1891 | EXPORT_SYMBOL(fb_set_suspend); |
| @@ -2059,7 +1953,6 @@ subsys_initcall(fbmem_init); · 61 unmodified lines | ||
| 2059 | 1953 | |
| 2060 | 1954 | int fb_new_modelist(struct fb_info *info) |
| 2061 | 1955 | { |
| 2062 | − struct fb_event event; | |
| 2063 | 1956 | struct fb_var_screeninfo var = info->var; |
| 2064 | 1957 | struct list_head *pos, *n; |
| 2065 | 1958 | struct fb_modelist *modelist; |
| @@ -2079,14 +1972,12 @@ int fb_new_modelist(struct fb_info *info) · 13 unmodified lines | ||
| 2079 | 1972 | } |
| 2080 | 1973 | } |
| 2081 | 1974 | |
| 2082 | − err = 1; | |
| 1975 | + if (list_empty(&info->modelist)) | |
| 1976 | + return 1; | |
| 2083 | 1977 | |
| 2084 | − if (!list_empty(&info->modelist)) { | |
| 2085 | − event.info = info; | |
| 2086 | − err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event); | |
| 2087 | − } | |
| 1978 | + fbcon_new_modelist(info); | |
| 2088 | 1979 | |
| 2089 | − return err; | |
| 1980 | + return 0; | |
| 2090 | 1981 | } |
| 2091 | 1982 | |
| 2092 | 1983 | MODULE_LICENSE("GPL"); |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/kernel.h> |
| 15 | 15 | #include <linux/slab.h> |
| 16 | 16 | #include <linux/fb.h> |
| 17 | +#include <linux/fbcon.h> | |
| 17 | 18 | #include <linux/console.h> |
| 18 | 19 | #include <linux/module.h> |
| 19 | 20 | |
| @@ -175,10 +176,7 @@ static ssize_t store_modes(struct device *device, · 155 unmodified lines | ||
| 175 | 176 | return -EINVAL; |
| 176 | 177 | |
| 177 | 178 | console_lock(); |
| 178 | − if (!lock_fb_info(fb_info)) { | |
| 179 | − console_unlock(); | |
| 180 | − return -ENODEV; | |
| 181 | − } | |
| 179 | + lock_fb_info(fb_info); | |
| 182 | 180 | |
| 183 | 181 | list_splice(&fb_info->modelist, &old_list); |
| 184 | 182 | fb_videomode_to_modelist((const struct fb_videomode *)buf, i, |
| @@ -304,12 +302,13 @@ static ssize_t store_blank(struct device *device, · 119 unmodified lines | ||
| 304 | 302 | { |
| 305 | 303 | struct fb_info *fb_info = dev_get_drvdata(device); |
| 306 | 304 | char *last = NULL; |
| 307 | − int err; | |
| 305 | + int err, arg; | |
| 308 | 306 | |
| 307 | + arg = simple_strtoul(buf, &last, 0); | |
| 309 | 308 | console_lock(); |
| 310 | − fb_info->flags |= FBINFO_MISC_USEREVENT; | |
| 311 | − err = fb_blank(fb_info, simple_strtoul(buf, &last, 0)); | |
| 312 | − fb_info->flags &= ~FBINFO_MISC_USEREVENT; | |
| 309 | + err = fb_blank(fb_info, arg); | |
| 310 | + /* might again call into fb_blank */ | |
| 311 | + fbcon_fb_blanked(fb_info, arg); | |
| 313 | 312 | console_unlock(); |
| 314 | 313 | if (err < 0) |
| 315 | 314 | return err; |
| @@ -405,10 +404,7 @@ static ssize_t store_fbstate(struct device *device, · 89 unmodified lines | ||
| 405 | 404 | state = simple_strtoul(buf, &last, 0); |
| 406 | 405 | |
| 407 | 406 | console_lock(); |
| 408 | − if (!lock_fb_info(fb_info)) { | |
| 409 | − console_unlock(); | |
| 410 | − return -ENODEV; | |
| 411 | − } | |
| 407 | + lock_fb_info(fb_info); | |
| 412 | 408 | |
| 413 | 409 | fb_set_suspend(fb_info, (int)state); |
| 414 | 410 | |
| @@ -58,7 +58,6 @@ · 57 unmodified lines | ||
| 58 | 58 | struct cfb_info { |
| 59 | 59 | struct fb_info fb; |
| 60 | 60 | struct display_switch *dispsw; |
| 61 | − struct display *display; | |
| 62 | 61 | unsigned char __iomem *region; |
| 63 | 62 | unsigned char __iomem *regs; |
| 64 | 63 | u_int id; |
| @@ -1638,10 +1637,6 @@ static void cyberpro_common_resume(struct cfb_info *cfb) · 1573 unmodified lines | ||
| 1638 | 1637 | cyber2000fb_set_par(&cfb->fb); |
| 1639 | 1638 | } |
| 1640 | 1639 | |
| 1641 | −/* | |
| 1642 | − * PCI specific support. | |
| 1643 | − */ | |
| 1644 | −#ifdef CONFIG_PCI | |
| 1645 | 1640 | /* |
| 1646 | 1641 | * We need to wake up the CyberPro, and make sure its in linear memory |
| 1647 | 1642 | * mode. Unfortunately, this is specific to the platform and card that |
| @@ -1858,7 +1853,6 @@ static struct pci_driver cyberpro_driver = { · 210 unmodified lines | ||
| 1858 | 1853 | .resume = cyberpro_pci_resume, |
| 1859 | 1854 | .id_table = cyberpro_pci_table |
| 1860 | 1855 | }; |
| 1861 | −#endif | |
| 1862 | 1856 | |
| 1863 | 1857 | /* |
| 1864 | 1858 | * I don't think we can use the "module_init" stuff here because |
| @@ -1387,7 +1387,6 @@ static int fb_probe(struct platform_device *device) · 1386 unmodified lines | ||
| 1387 | 1387 | da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par), |
| 1388 | 1388 | &device->dev); |
| 1389 | 1389 | if (!da8xx_fb_info) { |
| 1390 | − dev_dbg(&device->dev, "Memory allocation failed for fb_info\n"); | |
| 1391 | 1390 | ret = -ENOMEM; |
| 1392 | 1391 | goto err_pm_runtime_disable; |
| 1393 | 1392 | } |
| @@ -169,6 +169,11 @@ static void efifb_show_boot_graphics(struct fb_info *info) · 168 unmodified lines | ||
| 169 | 169 | return; |
| 170 | 170 | } |
| 171 | 171 | |
| 172 | + if (bgrt_tab.status & 0x06) { | |
| 173 | + pr_info("efifb: BGRT rotation bits set, not showing boot graphics\n"); | |
| 174 | + return; | |
| 175 | + } | |
| 176 | + | |
| 172 | 177 | /* Avoid flashing the logo if we're going to print std probe messages */ |
| 173 | 178 | if (console_loglevel > CONSOLE_LOGLEVEL_QUIET) |
| 174 | 179 | return; |
| @@ -448,7 +453,6 @@ static int efifb_probe(struct platform_device *dev) · 273 unmodified lines | ||
| 448 | 453 | |
| 449 | 454 | info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev); |
| 450 | 455 | if (!info) { |
| 451 | − pr_err("efifb: cannot allocate framebuffer\n"); | |
| 452 | 456 | err = -ENOMEM; |
| 453 | 457 | goto err_release_mem; |
| 454 | 458 | } |
| @@ -39,9 +39,7 @@ struct gbefb_par { · 38 unmodified lines | ||
| 39 | 39 | int valid; |
| 40 | 40 | }; |
| 41 | 41 | |
| 42 | −#ifdef CONFIG_SGI_IP32 | |
| 43 | 42 | #define GBE_BASE 0x16000000 /* SGI O2 */ |
| 44 | −#endif | |
| 45 | 43 | |
| 46 | 44 | /* macro for fastest write-though access to the framebuffer */ |
| 47 | 45 | #ifdef CONFIG_MIPS |
| @@ -51,10 +49,6 @@ struct gbefb_par { · 3 unmodified lines | ||
| 51 | 49 | #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_CACHABLE_NO_WA) |
| 52 | 50 | #endif |
| 53 | 51 | #endif |
| 54 | −#ifdef CONFIG_X86 | |
| 55 | −#define pgprot_fb(_prot) (((_prot) & ~_PAGE_CACHE_MASK) | \ | |
| 56 | − cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS)) | |
| 57 | −#endif | |
| 58 | 52 | |
| 59 | 53 | /* |
| 60 | 54 | * RAM we reserve for the frame buffer. This defines the maximum screen |
| @@ -279,7 +273,7 @@ static void gbe_turn_off(void) · 218 unmodified lines | ||
| 279 | 273 | val = 0; |
| 280 | 274 | SET_GBE_FIELD(VT_XY, FREEZE, val, 1); |
| 281 | 275 | gbe->vt_xy = val; |
| 282 | − udelay(10000); | |
| 276 | + mdelay(10); | |
| 283 | 277 | for (i = 0; i < 10000; i++) { |
| 284 | 278 | val = gbe->vt_xy; |
| 285 | 279 | if (GET_GBE_FIELD(VT_XY, FREEZE, val) != 1) |
| @@ -294,7 +288,7 @@ static void gbe_turn_off(void) · 8 unmodified lines | ||
| 294 | 288 | val = gbe->dotclock; |
| 295 | 289 | SET_GBE_FIELD(DOTCLK, RUN, val, 0); |
| 296 | 290 | gbe->dotclock = val; |
| 297 | − udelay(10000); | |
| 291 | + mdelay(10); | |
| 298 | 292 | for (i = 0; i < 10000; i++) { |
| 299 | 293 | val = gbe->dotclock; |
| 300 | 294 | if (GET_GBE_FIELD(DOTCLK, RUN, val)) |
| @@ -331,7 +325,7 @@ static void gbe_turn_on(void) · 30 unmodified lines | ||
| 331 | 325 | val = gbe->dotclock; |
| 332 | 326 | SET_GBE_FIELD(DOTCLK, RUN, val, 1); |
| 333 | 327 | gbe->dotclock = val; |
| 334 | − udelay(10000); | |
| 328 | + mdelay(10); | |
| 335 | 329 | for (i = 0; i < 10000; i++) { |
| 336 | 330 | val = gbe->dotclock; |
| 337 | 331 | if (GET_GBE_FIELD(DOTCLK, RUN, val) != 1) |
| @@ -346,7 +340,7 @@ static void gbe_turn_on(void) · 8 unmodified lines | ||
| 346 | 340 | val = 0; |
| 347 | 341 | SET_GBE_FIELD(VT_XY, FREEZE, val, 0); |
| 348 | 342 | gbe->vt_xy = val; |
| 349 | − udelay(10000); | |
| 343 | + mdelay(10); | |
| 350 | 344 | for (i = 0; i < 10000; i++) { |
| 351 | 345 | val = gbe->vt_xy; |
| 352 | 346 | if (GET_GBE_FIELD(VT_XY, FREEZE, val)) |
| @@ -547,7 +541,7 @@ static void gbe_set_timing_info(struct gbe_timing_info *timing) · 194 unmodified lines | ||
| 547 | 541 | SET_GBE_FIELD(DOTCLK, P, val, timing->pll_p); |
| 548 | 542 | SET_GBE_FIELD(DOTCLK, RUN, val, 0); /* do not start yet */ |
| 549 | 543 | gbe->dotclock = val; |
| 550 | − udelay(10000); | |
| 544 | + mdelay(10); | |
| 551 | 545 | |
| 552 | 546 | /* setup pixel counter */ |
| 553 | 547 | val = 0; |
| @@ -1018,9 +1012,10 @@ static int gbefb_mmap(struct fb_info *info, · 464 unmodified lines | ||
| 1018 | 1012 | |
| 1019 | 1013 | /* remap using the fastest write-through mode on architecture */ |
| 1020 | 1014 | /* try not polluting the cache when possible */ |
| 1015 | +#ifdef CONFIG_MIPS | |
| 1021 | 1016 | pgprot_val(vma->vm_page_prot) = |
| 1022 | 1017 | pgprot_fb(pgprot_val(vma->vm_page_prot)); |
| 1023 | − | |
| 1018 | +#endif | |
| 1024 | 1019 | /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */ |
| 1025 | 1020 | |
| 1026 | 1021 | /* look for the starting tile */ |
| @@ -336,10 +336,8 @@ static int grvga_probe(struct platform_device *dev) · 335 unmodified lines | ||
| 336 | 336 | char *options = NULL, *mode_opt = NULL; |
| 337 | 337 | |
| 338 | 338 | info = framebuffer_alloc(sizeof(struct grvga_par), &dev->dev); |
| 339 | − if (!info) { | |
| 340 | − dev_err(&dev->dev, "framebuffer_alloc failed\n"); | |
| 339 | + if (!info) | |
| 341 | 340 | return -ENOMEM; |
| 342 | − } | |
| 343 | 341 | |
| 344 | 342 | /* Expecting: "grvga: modestring, [addr:<framebuffer physical address>], [size:<framebuffer size>] |
| 345 | 343 | * |
| @@ -643,10 +643,9 @@ static int gxt4500_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 642 unmodified lines | ||
| 643 | 643 | } |
| 644 | 644 | |
| 645 | 645 | info = framebuffer_alloc(sizeof(struct gxt4500_par), &pdev->dev); |
| 646 | − if (!info) { | |
| 647 | − dev_err(&pdev->dev, "gxt4500: cannot alloc FB info record\n"); | |
| 646 | + if (!info) | |
| 648 | 647 | goto err_free_fb; |
| 649 | − } | |
| 648 | + | |
| 650 | 649 | par = info->par; |
| 651 | 650 | cardtype = ent->driver_data; |
| 652 | 651 | par->refclk_ps = cardinfo[cardtype].refclk_ps; |
| @@ -762,10 +762,8 @@ static int hvfb_probe(struct hv_device *hdev, · 761 unmodified lines | ||
| 762 | 762 | int ret; |
| 763 | 763 | |
| 764 | 764 | info = framebuffer_alloc(sizeof(struct hvfb_par), &hdev->device); |
| 765 | − if (!info) { | |
| 766 | − pr_err("No memory for framebuffer info\n"); | |
| 765 | + if (!info) | |
| 767 | 766 | return -ENOMEM; |
| 768 | − } | |
| 769 | 767 | |
| 770 | 768 | par = info->par; |
| 771 | 769 | par->info = info; |
| @@ -1006,10 +1006,8 @@ static int i740fb_probe(struct pci_dev *dev, const struct pci_device_id *ent) · 1005 unmodified lines | ||
| 1006 | 1006 | u8 *edid; |
| 1007 | 1007 | |
| 1008 | 1008 | info = framebuffer_alloc(sizeof(struct i740fb_par), &(dev->dev)); |
| 1009 | − if (!info) { | |
| 1010 | − dev_err(&(dev->dev), "cannot allocate framebuffer\n"); | |
| 1009 | + if (!info) | |
| 1011 | 1010 | return -ENOMEM; |
| 1012 | − } | |
| 1013 | 1011 | |
| 1014 | 1012 | par = info->par; |
| 1015 | 1013 | mutex_init(&par->open_lock); |
| @@ -1477,11 +1477,8 @@ static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 1476 unmodified lines | ||
| 1477 | 1477 | printk(KERN_ERR "imsttfb: no OF node for pci device\n"); |
| 1478 | 1478 | |
| 1479 | 1479 | info = framebuffer_alloc(sizeof(struct imstt_par), &pdev->dev); |
| 1480 | − | |
| 1481 | − if (!info) { | |
| 1482 | − printk(KERN_ERR "imsttfb: Can't allocate memory\n"); | |
| 1480 | + if (!info) | |
| 1483 | 1481 | return -ENOMEM; |
| 1484 | − } | |
| 1485 | 1482 | |
| 1486 | 1483 | par = info->par; |
| 1487 | 1484 | |
| @@ -974,10 +974,9 @@ static int imxfb_probe(struct platform_device *pdev) · 973 unmodified lines | ||
| 974 | 974 | } |
| 975 | 975 | |
| 976 | 976 | fbi->map_size = PAGE_ALIGN(info->fix.smem_len); |
| 977 | − info->screen_base = dma_alloc_wc(&pdev->dev, fbi->map_size, | |
| 978 | − &fbi->map_dma, GFP_KERNEL); | |
| 979 | − | |
| 980 | − if (!info->screen_base) { | |
| 977 | + info->screen_buffer = dma_alloc_wc(&pdev->dev, fbi->map_size, | |
| 978 | + &fbi->map_dma, GFP_KERNEL); | |
| 979 | + if (!info->screen_buffer) { | |
| 981 | 980 | dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret); |
| 982 | 981 | ret = -ENOMEM; |
| 983 | 982 | goto failed_map; |
| @@ -1046,7 +1045,7 @@ failed_cmap: · 62 unmodified lines | ||
| 1046 | 1045 | if (pdata && pdata->exit) |
| 1047 | 1046 | pdata->exit(fbi->pdev); |
| 1048 | 1047 | failed_platform_init: |
| 1049 | − dma_free_wc(&pdev->dev, fbi->map_size, info->screen_base, | |
| 1048 | + dma_free_wc(&pdev->dev, fbi->map_size, info->screen_buffer, | |
| 1050 | 1049 | fbi->map_dma); |
| 1051 | 1050 | failed_map: |
| 1052 | 1051 | iounmap(fbi->regs); |
| @@ -1077,7 +1076,7 @@ static int imxfb_remove(struct platform_device *pdev) · 24 unmodified lines | ||
| 1077 | 1076 | pdata = dev_get_platdata(&pdev->dev); |
| 1078 | 1077 | if (pdata && pdata->exit) |
| 1079 | 1078 | pdata->exit(fbi->pdev); |
| 1080 | − dma_free_wc(&pdev->dev, fbi->map_size, info->screen_base, | |
| 1079 | + dma_free_wc(&pdev->dev, fbi->map_size, info->screen_buffer, | |
| 1081 | 1080 | fbi->map_dma); |
| 1082 | 1081 | iounmap(fbi->regs); |
| 1083 | 1082 | release_mem_region(res->start, resource_size(res)); |
| @@ -491,10 +491,9 @@ static int intelfb_pci_register(struct pci_dev *pdev, · 490 unmodified lines | ||
| 491 | 491 | } |
| 492 | 492 | |
| 493 | 493 | info = framebuffer_alloc(sizeof(struct intelfb_info), &pdev->dev); |
| 494 | − if (!info) { | |
| 495 | − ERR_MSG("Could not allocate memory for intelfb_info.\n"); | |
| 496 | − return -ENODEV; | |
| 497 | − } | |
| 494 | + if (!info) | |
| 495 | + return -ENOMEM; | |
| 496 | + | |
| 498 | 497 | if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) { |
| 499 | 498 | ERR_MSG("Could not allocate cmap for intelfb_info.\n"); |
| 500 | 499 | goto err_out_cmap; |
| @@ -457,7 +457,6 @@ static int jzfb_alloc_devmem(struct jzfb *jzfb) · 456 unmodified lines | ||
| 457 | 457 | { |
| 458 | 458 | int max_videosize = 0; |
| 459 | 459 | struct fb_videomode *mode = jzfb->pdata->modes; |
| 460 | − void *page; | |
| 461 | 460 | int i; |
| 462 | 461 | |
| 463 | 462 | for (i = 0; i < jzfb->pdata->num_modes; ++mode, ++i) { |
| @@ -482,12 +481,6 @@ static int jzfb_alloc_devmem(struct jzfb *jzfb) · 18 unmodified lines | ||
| 482 | 481 | if (!jzfb->vidmem) |
| 483 | 482 | goto err_free_framedesc; |
| 484 | 483 | |
| 485 | − for (page = jzfb->vidmem; | |
| 486 | − page < jzfb->vidmem + PAGE_ALIGN(jzfb->vidmem_size); | |
| 487 | − page += PAGE_SIZE) { | |
| 488 | − SetPageReserved(virt_to_page(page)); | |
| 489 | − } | |
| 490 | − | |
| 491 | 484 | jzfb->framedesc->next = jzfb->framedesc_phys; |
| 492 | 485 | jzfb->framedesc->addr = jzfb->vidmem_phys; |
| 493 | 486 | jzfb->framedesc->id = 0xdeafbead; |
| @@ -535,10 +528,8 @@ static int jzfb_probe(struct platform_device *pdev) · 41 unmodified lines | ||
| 535 | 528 | } |
| 536 | 529 | |
| 537 | 530 | fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev); |
| 538 | − if (!fb) { | |
| 539 | − dev_err(&pdev->dev, "Failed to allocate framebuffer device\n"); | |
| 531 | + if (!fb) | |
| 540 | 532 | return -ENOMEM; |
| 541 | − } | |
| 542 | 533 | |
| 543 | 534 | fb->fbops = &jzfb_ops; |
| 544 | 535 | fb->flags = FBINFO_DEFAULT; |
| @@ -680,10 +680,8 @@ static int of_platform_mb862xx_probe(struct platform_device *ofdev) · 679 unmodified lines | ||
| 680 | 680 | } |
| 681 | 681 | |
| 682 | 682 | info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev); |
| 683 | − if (info == NULL) { | |
| 684 | − dev_err(dev, "cannot allocate framebuffer\n"); | |
| 683 | + if (!info) | |
| 685 | 684 | return -ENOMEM; |
| 686 | − } | |
| 687 | 685 | |
| 688 | 686 | par = info->par; |
| 689 | 687 | par->info = info; |
| @@ -1005,7 +1003,6 @@ static int mb862xx_pci_probe(struct pci_dev *pdev, · 315 unmodified lines | ||
| 1005 | 1003 | |
| 1006 | 1004 | info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev); |
| 1007 | 1005 | if (!info) { |
| 1008 | − dev_err(dev, "framebuffer alloc failed\n"); | |
| 1009 | 1006 | ret = -ENOMEM; |
| 1010 | 1007 | goto dis_dev; |
| 1011 | 1008 | } |
| @@ -899,10 +899,8 @@ static int mbxfb_probe(struct platform_device *dev) · 898 unmodified lines | ||
| 899 | 899 | } |
| 900 | 900 | |
| 901 | 901 | fbi = framebuffer_alloc(sizeof(struct mbxfb_info), &dev->dev); |
| 902 | − if (fbi == NULL) { | |
| 903 | − dev_err(&dev->dev, "framebuffer_alloc failed\n"); | |
| 902 | + if (!fbi) | |
| 904 | 903 | return -ENOMEM; |
| 905 | − } | |
| 906 | 904 | |
| 907 | 905 | mfbi = fbi->par; |
| 908 | 906 | fbi->pseudo_palette = mfbi->pseudo_palette; |
| @@ -433,7 +433,7 @@ static int mmphw_probe(struct platform_device *pdev) · 432 unmodified lines | ||
| 433 | 433 | { |
| 434 | 434 | struct mmp_mach_plat_info *mi; |
| 435 | 435 | struct resource *res; |
| 436 | − int ret, i, size, irq; | |
| 436 | + int ret, i, irq; | |
| 437 | 437 | struct mmphw_path_plat *path_plat; |
| 438 | 438 | struct mmphw_ctrl *ctrl = NULL; |
| 439 | 439 | |
| @@ -461,9 +461,9 @@ static int mmphw_probe(struct platform_device *pdev) · 21 unmodified lines | ||
| 461 | 461 | } |
| 462 | 462 | |
| 463 | 463 | /* allocate */ |
| 464 | − size = sizeof(struct mmphw_ctrl) + sizeof(struct mmphw_path_plat) * | |
| 465 | − mi->path_num; | |
| 466 | − ctrl = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); | |
| 464 | + ctrl = devm_kzalloc(&pdev->dev, | |
| 465 | + struct_size(ctrl, path_plats, mi->path_num), | |
| 466 | + GFP_KERNEL); | |
| 467 | 467 | if (!ctrl) { |
| 468 | 468 | ret = -ENOMEM; |
| 469 | 469 | goto failed; |
| @@ -1,1028 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0-or-later | |
| 2 | −/* | |
| 3 | − * Copyright (C) 2010 Juergen Beisert, Pengutronix | |
| 4 | − * | |
| 5 | − * This code is based on: | |
| 6 | − * Author: Vitaly Wool <vital@embeddedalley.com> | |
| 7 | − * | |
| 8 | − * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. | |
| 9 | − * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. | |
| 10 | − */ | |
| 11 | − | |
| 12 | −#define DRIVER_NAME "mxsfb" | |
| 13 | − | |
| 14 | −/** | |
| 15 | − * @file | |
| 16 | − * @brief LCDIF driver for i.MX23 and i.MX28 | |
| 17 | − * | |
| 18 | − * The LCDIF support four modes of operation | |
| 19 | − * - MPU interface (to drive smart displays) -> not supported yet | |
| 20 | − * - VSYNC interface (like MPU interface plus Vsync) -> not supported yet | |
| 21 | − * - Dotclock interface (to drive LC displays with RGB data and sync signals) | |
| 22 | − * - DVI (to drive ITU-R BT656) -> not supported yet | |
| 23 | − * | |
| 24 | − * This driver depends on a correct setup of the pins used for this purpose | |
| 25 | − * (platform specific). | |
| 26 | − * | |
| 27 | − * For the developer: Don't forget to set the data bus width to the display | |
| 28 | − * in the imx_fb_videomode structure. You will else end up with ugly colours. | |
| 29 | − * If you fight against jitter you can vary the clock delay. This is a feature | |
| 30 | − * of the i.MX28 and you can vary it between 2 ns ... 8 ns in 2 ns steps. Give | |
| 31 | − * the required value in the imx_fb_videomode structure. | |
| 32 | − */ | |
| 33 | − | |
| 34 | −#include <linux/module.h> | |
| 35 | −#include <linux/kernel.h> | |
| 36 | −#include <linux/of_device.h> | |
| 37 | −#include <linux/platform_device.h> | |
| 38 | −#include <linux/clk.h> | |
| 39 | −#include <linux/dma-mapping.h> | |
| 40 | −#include <linux/io.h> | |
| 41 | −#include <linux/fb.h> | |
| 42 | −#include <linux/regulator/consumer.h> | |
| 43 | −#include <video/of_display_timing.h> | |
| 44 | −#include <video/of_videomode.h> | |
| 45 | −#include <video/videomode.h> | |
| 46 | − | |
| 47 | −#define REG_SET 4 | |
| 48 | −#define REG_CLR 8 | |
| 49 | − | |
| 50 | −#define LCDC_CTRL 0x00 | |
| 51 | −#define LCDC_CTRL1 0x10 | |
| 52 | −#define LCDC_V4_CTRL2 0x20 | |
| 53 | −#define LCDC_V3_TRANSFER_COUNT 0x20 | |
| 54 | −#define LCDC_V4_TRANSFER_COUNT 0x30 | |
| 55 | −#define LCDC_V4_CUR_BUF 0x40 | |
| 56 | −#define LCDC_V4_NEXT_BUF 0x50 | |
| 57 | −#define LCDC_V3_CUR_BUF 0x30 | |
| 58 | −#define LCDC_V3_NEXT_BUF 0x40 | |
| 59 | −#define LCDC_TIMING 0x60 | |
| 60 | −#define LCDC_VDCTRL0 0x70 | |
| 61 | −#define LCDC_VDCTRL1 0x80 | |
| 62 | −#define LCDC_VDCTRL2 0x90 | |
| 63 | −#define LCDC_VDCTRL3 0xa0 | |
| 64 | −#define LCDC_VDCTRL4 0xb0 | |
| 65 | −#define LCDC_DVICTRL0 0xc0 | |
| 66 | −#define LCDC_DVICTRL1 0xd0 | |
| 67 | −#define LCDC_DVICTRL2 0xe0 | |
| 68 | −#define LCDC_DVICTRL3 0xf0 | |
| 69 | −#define LCDC_DVICTRL4 0x100 | |
| 70 | −#define LCDC_V4_DATA 0x180 | |
| 71 | −#define LCDC_V3_DATA 0x1b0 | |
| 72 | −#define LCDC_V4_DEBUG0 0x1d0 | |
| 73 | −#define LCDC_V3_DEBUG0 0x1f0 | |
| 74 | − | |
| 75 | −#define CTRL_SFTRST (1 << 31) | |
| 76 | −#define CTRL_CLKGATE (1 << 30) | |
| 77 | −#define CTRL_BYPASS_COUNT (1 << 19) | |
| 78 | −#define CTRL_VSYNC_MODE (1 << 18) | |
| 79 | −#define CTRL_DOTCLK_MODE (1 << 17) | |
| 80 | −#define CTRL_DATA_SELECT (1 << 16) | |
| 81 | −#define CTRL_SET_BUS_WIDTH(x) (((x) & 0x3) << 10) | |
| 82 | −#define CTRL_GET_BUS_WIDTH(x) (((x) >> 10) & 0x3) | |
| 83 | −#define CTRL_SET_WORD_LENGTH(x) (((x) & 0x3) << 8) | |
| 84 | −#define CTRL_GET_WORD_LENGTH(x) (((x) >> 8) & 0x3) | |
| 85 | −#define CTRL_MASTER (1 << 5) | |
| 86 | −#define CTRL_DF16 (1 << 3) | |
| 87 | −#define CTRL_DF18 (1 << 2) | |
| 88 | −#define CTRL_DF24 (1 << 1) | |
| 89 | −#define CTRL_RUN (1 << 0) | |
| 90 | − | |
| 91 | −#define CTRL1_FIFO_CLEAR (1 << 21) | |
| 92 | −#define CTRL1_SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16) | |
| 93 | −#define CTRL1_GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf) | |
| 94 | − | |
| 95 | −#define TRANSFER_COUNT_SET_VCOUNT(x) (((x) & 0xffff) << 16) | |
| 96 | −#define TRANSFER_COUNT_GET_VCOUNT(x) (((x) >> 16) & 0xffff) | |
| 97 | −#define TRANSFER_COUNT_SET_HCOUNT(x) ((x) & 0xffff) | |
| 98 | −#define TRANSFER_COUNT_GET_HCOUNT(x) ((x) & 0xffff) | |
| 99 | − | |
| 100 | − | |
| 101 | −#define VDCTRL0_ENABLE_PRESENT (1 << 28) | |
| 102 | −#define VDCTRL0_VSYNC_ACT_HIGH (1 << 27) | |
| 103 | −#define VDCTRL0_HSYNC_ACT_HIGH (1 << 26) | |
| 104 | −#define VDCTRL0_DOTCLK_ACT_FALLING (1 << 25) | |
| 105 | −#define VDCTRL0_ENABLE_ACT_HIGH (1 << 24) | |
| 106 | −#define VDCTRL0_VSYNC_PERIOD_UNIT (1 << 21) | |
| 107 | −#define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20) | |
| 108 | −#define VDCTRL0_HALF_LINE (1 << 19) | |
| 109 | −#define VDCTRL0_HALF_LINE_MODE (1 << 18) | |
| 110 | −#define VDCTRL0_SET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff) | |
| 111 | −#define VDCTRL0_GET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff) | |
| 112 | − | |
| 113 | −#define VDCTRL2_SET_HSYNC_PERIOD(x) ((x) & 0x3ffff) | |
| 114 | −#define VDCTRL2_GET_HSYNC_PERIOD(x) ((x) & 0x3ffff) | |
| 115 | − | |
| 116 | −#define VDCTRL3_MUX_SYNC_SIGNALS (1 << 29) | |
| 117 | −#define VDCTRL3_VSYNC_ONLY (1 << 28) | |
| 118 | −#define SET_HOR_WAIT_CNT(x) (((x) & 0xfff) << 16) | |
| 119 | −#define GET_HOR_WAIT_CNT(x) (((x) >> 16) & 0xfff) | |
| 120 | −#define SET_VERT_WAIT_CNT(x) ((x) & 0xffff) | |
| 121 | −#define GET_VERT_WAIT_CNT(x) ((x) & 0xffff) | |
| 122 | − | |
| 123 | −#define VDCTRL4_SET_DOTCLK_DLY(x) (((x) & 0x7) << 29) /* v4 only */ | |
| 124 | −#define VDCTRL4_GET_DOTCLK_DLY(x) (((x) >> 29) & 0x7) /* v4 only */ | |
| 125 | −#define VDCTRL4_SYNC_SIGNALS_ON (1 << 18) | |
| 126 | −#define SET_DOTCLK_H_VALID_DATA_CNT(x) ((x) & 0x3ffff) | |
| 127 | − | |
| 128 | −#define DEBUG0_HSYNC (1 < 26) | |
| 129 | −#define DEBUG0_VSYNC (1 < 25) | |
| 130 | − | |
| 131 | −#define MIN_XRES 120 | |
| 132 | −#define MIN_YRES 120 | |
| 133 | − | |
| 134 | −#define RED 0 | |
| 135 | −#define GREEN 1 | |
| 136 | −#define BLUE 2 | |
| 137 | −#define TRANSP 3 | |
| 138 | − | |
| 139 | −#define STMLCDIF_8BIT 1 /** pixel data bus to the display is of 8 bit width */ | |
| 140 | −#define STMLCDIF_16BIT 0 /** pixel data bus to the display is of 16 bit width */ | |
| 141 | −#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */ | |
| 142 | −#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */ | |
| 143 | − | |
| 144 | −#define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6) | |
| 145 | −#define MXSFB_SYNC_DOTCLK_FALLING_ACT (1 << 7) /* negative edge sampling */ | |
| 146 | − | |
| 147 | −enum mxsfb_devtype { | |
| 148 | − MXSFB_V3, | |
| 149 | − MXSFB_V4, | |
| 150 | −}; | |
| 151 | − | |
| 152 | −/* CPU dependent register offsets */ | |
| 153 | −struct mxsfb_devdata { | |
| 154 | − unsigned transfer_count; | |
| 155 | − unsigned cur_buf; | |
| 156 | − unsigned next_buf; | |
| 157 | − unsigned debug0; | |
| 158 | − unsigned hs_wdth_mask; | |
| 159 | − unsigned hs_wdth_shift; | |
| 160 | − unsigned ipversion; | |
| 161 | −}; | |
| 162 | − | |
| 163 | −struct mxsfb_info { | |
| 164 | − struct platform_device *pdev; | |
| 165 | − struct clk *clk; | |
| 166 | − struct clk *clk_axi; | |
| 167 | − struct clk *clk_disp_axi; | |
| 168 | − void __iomem *base; /* registers */ | |
| 169 | − unsigned allocated_size; | |
| 170 | − int enabled; | |
| 171 | − unsigned ld_intf_width; | |
| 172 | − unsigned dotclk_delay; | |
| 173 | − const struct mxsfb_devdata *devdata; | |
| 174 | − u32 sync; | |
| 175 | − struct regulator *reg_lcd; | |
| 176 | − int pre_init; | |
| 177 | −}; | |
| 178 | − | |
| 179 | −#define mxsfb_is_v3(host) (host->devdata->ipversion == 3) | |
| 180 | −#define mxsfb_is_v4(host) (host->devdata->ipversion == 4) | |
| 181 | − | |
| 182 | −static const struct mxsfb_devdata mxsfb_devdata[] = { | |
| 183 | − [MXSFB_V3] = { | |
| 184 | − .transfer_count = LCDC_V3_TRANSFER_COUNT, | |
| 185 | − .cur_buf = LCDC_V3_CUR_BUF, | |
| 186 | − .next_buf = LCDC_V3_NEXT_BUF, | |
| 187 | − .debug0 = LCDC_V3_DEBUG0, | |
| 188 | − .hs_wdth_mask = 0xff, | |
| 189 | − .hs_wdth_shift = 24, | |
| 190 | − .ipversion = 3, | |
| 191 | − }, | |
| 192 | − [MXSFB_V4] = { | |
| 193 | − .transfer_count = LCDC_V4_TRANSFER_COUNT, | |
| 194 | − .cur_buf = LCDC_V4_CUR_BUF, | |
| 195 | − .next_buf = LCDC_V4_NEXT_BUF, | |
| 196 | − .debug0 = LCDC_V4_DEBUG0, | |
| 197 | − .hs_wdth_mask = 0x3fff, | |
| 198 | − .hs_wdth_shift = 18, | |
| 199 | − .ipversion = 4, | |
| 200 | − }, | |
| 201 | −}; | |
| 202 | − | |
| 203 | −/* mask and shift depends on architecture */ | |
| 204 | −static inline u32 set_hsync_pulse_width(struct mxsfb_info *host, unsigned val) | |
| 205 | −{ | |
| 206 | − return (val & host->devdata->hs_wdth_mask) << | |
| 207 | − host->devdata->hs_wdth_shift; | |
| 208 | −} | |
| 209 | − | |
| 210 | −static inline u32 get_hsync_pulse_width(struct mxsfb_info *host, unsigned val) | |
| 211 | −{ | |
| 212 | − return (val >> host->devdata->hs_wdth_shift) & | |
| 213 | − host->devdata->hs_wdth_mask; | |
| 214 | −} | |
| 215 | − | |
| 216 | −static const struct fb_bitfield def_rgb565[] = { | |
| 217 | − [RED] = { | |
| 218 | − .offset = 11, | |
| 219 | − .length = 5, | |
| 220 | − }, | |
| 221 | − [GREEN] = { | |
| 222 | − .offset = 5, | |
| 223 | − .length = 6, | |
| 224 | − }, | |
| 225 | − [BLUE] = { | |
| 226 | − .offset = 0, | |
| 227 | − .length = 5, | |
| 228 | − }, | |
| 229 | − [TRANSP] = { /* no support for transparency */ | |
| 230 | − .length = 0, | |
| 231 | − } | |
| 232 | −}; | |
| 233 | − | |
| 234 | −static const struct fb_bitfield def_rgb888[] = { | |
| 235 | − [RED] = { | |
| 236 | − .offset = 16, | |
| 237 | − .length = 8, | |
| 238 | − }, | |
| 239 | − [GREEN] = { | |
| 240 | − .offset = 8, | |
| 241 | − .length = 8, | |
| 242 | − }, | |
| 243 | − [BLUE] = { | |
| 244 | − .offset = 0, | |
| 245 | − .length = 8, | |
| 246 | − }, | |
| 247 | − [TRANSP] = { /* no support for transparency */ | |
| 248 | − .length = 0, | |
| 249 | − } | |
| 250 | −}; | |
| 251 | − | |
| 252 | −static inline unsigned chan_to_field(unsigned chan, struct fb_bitfield *bf) | |
| 253 | −{ | |
| 254 | − chan &= 0xffff; | |
| 255 | − chan >>= 16 - bf->length; | |
| 256 | − return chan << bf->offset; | |
| 257 | −} | |
| 258 | − | |
| 259 | −static int mxsfb_check_var(struct fb_var_screeninfo *var, | |
| 260 | − struct fb_info *fb_info) | |
| 261 | −{ | |
| 262 | − struct mxsfb_info *host = fb_info->par; | |
| 263 | − const struct fb_bitfield *rgb = NULL; | |
| 264 | − | |
| 265 | − if (var->xres < MIN_XRES) | |
| 266 | − var->xres = MIN_XRES; | |
| 267 | − if (var->yres < MIN_YRES) | |
| 268 | − var->yres = MIN_YRES; | |
| 269 | − | |
| 270 | − var->xres_virtual = var->xres; | |
| 271 | − | |
| 272 | − var->yres_virtual = var->yres; | |
| 273 | − | |
| 274 | − switch (var->bits_per_pixel) { | |
| 275 | − case 16: | |
| 276 | − /* always expect RGB 565 */ | |
| 277 | − rgb = def_rgb565; | |
| 278 | − break; | |
| 279 | − case 32: | |
| 280 | − switch (host->ld_intf_width) { | |
| 281 | − case STMLCDIF_8BIT: | |
| 282 | − pr_debug("Unsupported LCD bus width mapping\n"); | |
| 283 | − break; | |
| 284 | − case STMLCDIF_16BIT: | |
| 285 | − case STMLCDIF_18BIT: | |
| 286 | − case STMLCDIF_24BIT: | |
| 287 | − /* real 24 bit */ | |
| 288 | − rgb = def_rgb888; | |
| 289 | − break; | |
| 290 | − } | |
| 291 | − break; | |
| 292 | − default: | |
| 293 | − pr_err("Unsupported colour depth: %u\n", var->bits_per_pixel); | |
| 294 | − return -EINVAL; | |
| 295 | − } | |
| 296 | − | |
| 297 | − /* | |
| 298 | − * Copy the RGB parameters for this display | |
| 299 | − * from the machine specific parameters. | |
| 300 | − */ | |
| 301 | − var->red = rgb[RED]; | |
| 302 | − var->green = rgb[GREEN]; | |
| 303 | − var->blue = rgb[BLUE]; | |
| 304 | − var->transp = rgb[TRANSP]; | |
| 305 | − | |
| 306 | − return 0; | |
| 307 | −} | |
| 308 | − | |
| 309 | −static inline void mxsfb_enable_axi_clk(struct mxsfb_info *host) | |
| 310 | −{ | |
| 311 | − if (host->clk_axi) | |
| 312 | − clk_prepare_enable(host->clk_axi); | |
| 313 | −} | |
| 314 | − | |
| 315 | −static inline void mxsfb_disable_axi_clk(struct mxsfb_info *host) | |
| 316 | −{ | |
| 317 | − if (host->clk_axi) | |
| 318 | − clk_disable_unprepare(host->clk_axi); | |
| 319 | −} | |
| 320 | − | |
| 321 | −static void mxsfb_enable_controller(struct fb_info *fb_info) | |
| 322 | −{ | |
| 323 | − struct mxsfb_info *host = fb_info->par; | |
| 324 | − u32 reg; | |
| 325 | − int ret; | |
| 326 | − | |
| 327 | − dev_dbg(&host->pdev->dev, "%s\n", __func__); | |
| 328 | − | |
| 329 | − if (host->reg_lcd) { | |
| 330 | − ret = regulator_enable(host->reg_lcd); | |
| 331 | − if (ret) { | |
| 332 | − dev_err(&host->pdev->dev, | |
| 333 | − "lcd regulator enable failed: %d\n", ret); | |
| 334 | − return; | |
| 335 | − } | |
| 336 | − } | |
| 337 | − | |
| 338 | − if (host->clk_disp_axi) | |
| 339 | − clk_prepare_enable(host->clk_disp_axi); | |
| 340 | − clk_prepare_enable(host->clk); | |
| 341 | − clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U); | |
| 342 | − | |
| 343 | − mxsfb_enable_axi_clk(host); | |
| 344 | − | |
| 345 | − /* if it was disabled, re-enable the mode again */ | |
| 346 | − writel(CTRL_DOTCLK_MODE, host->base + LCDC_CTRL + REG_SET); | |
| 347 | − | |
| 348 | − /* enable the SYNC signals first, then the DMA engine */ | |
| 349 | − reg = readl(host->base + LCDC_VDCTRL4); | |
| 350 | − reg |= VDCTRL4_SYNC_SIGNALS_ON; | |
| 351 | − writel(reg, host->base + LCDC_VDCTRL4); | |
| 352 | − | |
| 353 | − writel(CTRL_RUN, host->base + LCDC_CTRL + REG_SET); | |
| 354 | − | |
| 355 | − host->enabled = 1; | |
| 356 | −} | |
| 357 | − | |
| 358 | −static void mxsfb_disable_controller(struct fb_info *fb_info) | |
| 359 | −{ | |
| 360 | − struct mxsfb_info *host = fb_info->par; | |
| 361 | − unsigned loop; | |
| 362 | − u32 reg; | |
| 363 | − int ret; | |
| 364 | − | |
| 365 | − dev_dbg(&host->pdev->dev, "%s\n", __func__); | |
| 366 | − | |
| 367 | − /* | |
| 368 | − * Even if we disable the controller here, it will still continue | |
| 369 | − * until its FIFOs are running out of data | |
| 370 | − */ | |
| 371 | − writel(CTRL_DOTCLK_MODE, host->base + LCDC_CTRL + REG_CLR); | |
| 372 | − | |
| 373 | − loop = 1000; | |
| 374 | − while (loop) { | |
| 375 | − reg = readl(host->base + LCDC_CTRL); | |
| 376 | − if (!(reg & CTRL_RUN)) | |
| 377 | − break; | |
| 378 | − loop--; | |
| 379 | − } | |
| 380 | − | |
| 381 | − reg = readl(host->base + LCDC_VDCTRL4); | |
| 382 | − writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4); | |
| 383 | − | |
| 384 | − mxsfb_disable_axi_clk(host); | |
| 385 | − | |
| 386 | − clk_disable_unprepare(host->clk); | |
| 387 | − if (host->clk_disp_axi) | |
| 388 | − clk_disable_unprepare(host->clk_disp_axi); | |
| 389 | − | |
| 390 | − host->enabled = 0; | |
| 391 | − | |
| 392 | − if (host->reg_lcd) { | |
| 393 | − ret = regulator_disable(host->reg_lcd); | |
| 394 | − if (ret) | |
| 395 | − dev_err(&host->pdev->dev, | |
| 396 | − "lcd regulator disable failed: %d\n", ret); | |
| 397 | − } | |
| 398 | −} | |
| 399 | − | |
| 400 | −static int mxsfb_set_par(struct fb_info *fb_info) | |
| 401 | −{ | |
| 402 | − struct mxsfb_info *host = fb_info->par; | |
| 403 | − u32 ctrl, vdctrl0, vdctrl4; | |
| 404 | − int line_size, fb_size; | |
| 405 | − int reenable = 0; | |
| 406 | − | |
| 407 | − line_size = fb_info->var.xres * (fb_info->var.bits_per_pixel >> 3); | |
| 408 | − fb_size = fb_info->var.yres_virtual * line_size; | |
| 409 | − | |
| 410 | − if (fb_size > fb_info->fix.smem_len) | |
| 411 | − return -ENOMEM; | |
| 412 | − | |
| 413 | − fb_info->fix.line_length = line_size; | |
| 414 | − | |
| 415 | − if (host->pre_init) { | |
| 416 | − mxsfb_enable_controller(fb_info); | |
| 417 | − host->pre_init = 0; | |
| 418 | − return 0; | |
| 419 | − } | |
| 420 | − | |
| 421 | − /* | |
| 422 | − * It seems, you can't re-program the controller if it is still running. | |
| 423 | − * This may lead into shifted pictures (FIFO issue?). | |
| 424 | − * So, first stop the controller and drain its FIFOs | |
| 425 | − */ | |
| 426 | − if (host->enabled) { | |
| 427 | − reenable = 1; | |
| 428 | − mxsfb_disable_controller(fb_info); | |
| 429 | − } | |
| 430 | − | |
| 431 | − mxsfb_enable_axi_clk(host); | |
| 432 | − | |
| 433 | − /* clear the FIFOs */ | |
| 434 | − writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET); | |
| 435 | − | |
| 436 | − ctrl = CTRL_BYPASS_COUNT | CTRL_MASTER | | |
| 437 | − CTRL_SET_BUS_WIDTH(host->ld_intf_width); | |
| 438 | − | |
| 439 | − switch (fb_info->var.bits_per_pixel) { | |
| 440 | − case 16: | |
| 441 | − dev_dbg(&host->pdev->dev, "Setting up RGB565 mode\n"); | |
| 442 | − ctrl |= CTRL_SET_WORD_LENGTH(0); | |
| 443 | − writel(CTRL1_SET_BYTE_PACKAGING(0xf), host->base + LCDC_CTRL1); | |
| 444 | − break; | |
| 445 | − case 32: | |
| 446 | − dev_dbg(&host->pdev->dev, "Setting up RGB888/666 mode\n"); | |
| 447 | − ctrl |= CTRL_SET_WORD_LENGTH(3); | |
| 448 | − switch (host->ld_intf_width) { | |
| 449 | − case STMLCDIF_8BIT: | |
| 450 | − mxsfb_disable_axi_clk(host); | |
| 451 | − dev_err(&host->pdev->dev, | |
| 452 | − "Unsupported LCD bus width mapping\n"); | |
| 453 | − return -EINVAL; | |
| 454 | − case STMLCDIF_16BIT: | |
| 455 | − case STMLCDIF_18BIT: | |
| 456 | − case STMLCDIF_24BIT: | |
| 457 | − /* real 24 bit */ | |
| 458 | − break; | |
| 459 | − } | |
| 460 | − /* do not use packed pixels = one pixel per word instead */ | |
| 461 | − writel(CTRL1_SET_BYTE_PACKAGING(0x7), host->base + LCDC_CTRL1); | |
| 462 | − break; | |
| 463 | − default: | |
| 464 | − mxsfb_disable_axi_clk(host); | |
| 465 | − dev_err(&host->pdev->dev, "Unhandled color depth of %u\n", | |
| 466 | − fb_info->var.bits_per_pixel); | |
| 467 | − return -EINVAL; | |
| 468 | − } | |
| 469 | − | |
| 470 | − writel(ctrl, host->base + LCDC_CTRL); | |
| 471 | − | |
| 472 | − writel(TRANSFER_COUNT_SET_VCOUNT(fb_info->var.yres) | | |
| 473 | − TRANSFER_COUNT_SET_HCOUNT(fb_info->var.xres), | |
| 474 | − host->base + host->devdata->transfer_count); | |
| 475 | − | |
| 476 | − vdctrl0 = VDCTRL0_ENABLE_PRESENT | /* always in DOTCLOCK mode */ | |
| 477 | − VDCTRL0_VSYNC_PERIOD_UNIT | | |
| 478 | − VDCTRL0_VSYNC_PULSE_WIDTH_UNIT | | |
| 479 | − VDCTRL0_SET_VSYNC_PULSE_WIDTH(fb_info->var.vsync_len); | |
| 480 | − if (fb_info->var.sync & FB_SYNC_HOR_HIGH_ACT) | |
| 481 | − vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH; | |
| 482 | − if (fb_info->var.sync & FB_SYNC_VERT_HIGH_ACT) | |
| 483 | − vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH; | |
| 484 | − if (host->sync & MXSFB_SYNC_DATA_ENABLE_HIGH_ACT) | |
| 485 | − vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH; | |
| 486 | − if (host->sync & MXSFB_SYNC_DOTCLK_FALLING_ACT) | |
| 487 | − vdctrl0 |= VDCTRL0_DOTCLK_ACT_FALLING; | |
| 488 | − | |
| 489 | − writel(vdctrl0, host->base + LCDC_VDCTRL0); | |
| 490 | − | |
| 491 | − /* frame length in lines */ | |
| 492 | − writel(fb_info->var.upper_margin + fb_info->var.vsync_len + | |
| 493 | − fb_info->var.lower_margin + fb_info->var.yres, | |
| 494 | − host->base + LCDC_VDCTRL1); | |
| 495 | − | |
| 496 | − /* line length in units of clocks or pixels */ | |
| 497 | − writel(set_hsync_pulse_width(host, fb_info->var.hsync_len) | | |
| 498 | − VDCTRL2_SET_HSYNC_PERIOD(fb_info->var.left_margin + | |
| 499 | − fb_info->var.hsync_len + fb_info->var.right_margin + | |
| 500 | − fb_info->var.xres), | |
| 501 | − host->base + LCDC_VDCTRL2); | |
| 502 | − | |
| 503 | − writel(SET_HOR_WAIT_CNT(fb_info->var.left_margin + | |
| 504 | − fb_info->var.hsync_len) | | |
| 505 | − SET_VERT_WAIT_CNT(fb_info->var.upper_margin + | |
| 506 | − fb_info->var.vsync_len), | |
| 507 | − host->base + LCDC_VDCTRL3); | |
| 508 | − | |
| 509 | − vdctrl4 = SET_DOTCLK_H_VALID_DATA_CNT(fb_info->var.xres); | |
| 510 | − if (mxsfb_is_v4(host)) | |
| 511 | − vdctrl4 |= VDCTRL4_SET_DOTCLK_DLY(host->dotclk_delay); | |
| 512 | − writel(vdctrl4, host->base + LCDC_VDCTRL4); | |
| 513 | − | |
| 514 | − writel(fb_info->fix.smem_start + | |
| 515 | − fb_info->fix.line_length * fb_info->var.yoffset, | |
| 516 | − host->base + host->devdata->next_buf); | |
| 517 | − | |
| 518 | − mxsfb_disable_axi_clk(host); | |
| 519 | − | |
| 520 | − if (reenable) | |
| 521 | − mxsfb_enable_controller(fb_info); | |
| 522 | − | |
| 523 | − return 0; | |
| 524 | −} | |
| 525 | − | |
| 526 | −static int mxsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |
| 527 | − u_int transp, struct fb_info *fb_info) | |
| 528 | −{ | |
| 529 | − unsigned int val; | |
| 530 | − int ret = -EINVAL; | |
| 531 | − | |
| 532 | − /* | |
| 533 | − * If greyscale is true, then we convert the RGB value | |
| 534 | − * to greyscale no matter what visual we are using. | |
| 535 | − */ | |
| 536 | − if (fb_info->var.grayscale) | |
| 537 | − red = green = blue = (19595 * red + 38470 * green + | |
| 538 | − 7471 * blue) >> 16; | |
| 539 | − | |
| 540 | − switch (fb_info->fix.visual) { | |
| 541 | − case FB_VISUAL_TRUECOLOR: | |
| 542 | − /* | |
| 543 | − * 12 or 16-bit True Colour. We encode the RGB value | |
| 544 | − * according to the RGB bitfield information. | |
| 545 | − */ | |
| 546 | − if (regno < 16) { | |
| 547 | − u32 *pal = fb_info->pseudo_palette; | |
| 548 | − | |
| 549 | − val = chan_to_field(red, &fb_info->var.red); | |
| 550 | − val |= chan_to_field(green, &fb_info->var.green); | |
| 551 | − val |= chan_to_field(blue, &fb_info->var.blue); | |
| 552 | − | |
| 553 | − pal[regno] = val; | |
| 554 | − ret = 0; | |
| 555 | − } | |
| 556 | − break; | |
| 557 | − | |
| 558 | − case FB_VISUAL_STATIC_PSEUDOCOLOR: | |
| 559 | − case FB_VISUAL_PSEUDOCOLOR: | |
| 560 | − break; | |
| 561 | − } | |
| 562 | − | |
| 563 | − return ret; | |
| 564 | −} | |
| 565 | − | |
| 566 | −static int mxsfb_blank(int blank, struct fb_info *fb_info) | |
| 567 | −{ | |
| 568 | − struct mxsfb_info *host = fb_info->par; | |
| 569 | − | |
| 570 | − switch (blank) { | |
| 571 | − case FB_BLANK_POWERDOWN: | |
| 572 | − case FB_BLANK_VSYNC_SUSPEND: | |
| 573 | − case FB_BLANK_HSYNC_SUSPEND: | |
| 574 | − case FB_BLANK_NORMAL: | |
| 575 | − if (host->enabled) | |
| 576 | − mxsfb_disable_controller(fb_info); | |
| 577 | − break; | |
| 578 | − | |
| 579 | − case FB_BLANK_UNBLANK: | |
| 580 | − if (!host->enabled) | |
| 581 | − mxsfb_enable_controller(fb_info); | |
| 582 | − break; | |
| 583 | − } | |
| 584 | − return 0; | |
| 585 | −} | |
| 586 | − | |
| 587 | −static int mxsfb_pan_display(struct fb_var_screeninfo *var, | |
| 588 | − struct fb_info *fb_info) | |
| 589 | −{ | |
| 590 | − struct mxsfb_info *host = fb_info->par; | |
| 591 | − unsigned offset; | |
| 592 | − | |
| 593 | − if (var->xoffset != 0) | |
| 594 | − return -EINVAL; | |
| 595 | − | |
| 596 | − offset = fb_info->fix.line_length * var->yoffset; | |
| 597 | − | |
| 598 | − mxsfb_enable_axi_clk(host); | |
| 599 | − | |
| 600 | − /* update on next VSYNC */ | |
| 601 | − writel(fb_info->fix.smem_start + offset, | |
| 602 | − host->base + host->devdata->next_buf); | |
| 603 | − | |
| 604 | − mxsfb_disable_axi_clk(host); | |
| 605 | − | |
| 606 | − return 0; | |
| 607 | −} | |
| 608 | − | |
| 609 | −static struct fb_ops mxsfb_ops = { | |
| 610 | − .owner = THIS_MODULE, | |
| 611 | − .fb_check_var = mxsfb_check_var, | |
| 612 | − .fb_set_par = mxsfb_set_par, | |
| 613 | − .fb_setcolreg = mxsfb_setcolreg, | |
| 614 | − .fb_blank = mxsfb_blank, | |
| 615 | − .fb_pan_display = mxsfb_pan_display, | |
| 616 | − .fb_fillrect = cfb_fillrect, | |
| 617 | − .fb_copyarea = cfb_copyarea, | |
| 618 | − .fb_imageblit = cfb_imageblit, | |
| 619 | −}; | |
| 620 | − | |
| 621 | −static int mxsfb_restore_mode(struct fb_info *fb_info, | |
| 622 | − struct fb_videomode *vmode) | |
| 623 | −{ | |
| 624 | − struct mxsfb_info *host = fb_info->par; | |
| 625 | − unsigned period; | |
| 626 | − unsigned long pa, fbsize; | |
| 627 | − int bits_per_pixel, ofs, ret = 0; | |
| 628 | − u32 transfer_count, vdctrl0, vdctrl2, vdctrl3, vdctrl4, ctrl; | |
| 629 | − | |
| 630 | − mxsfb_enable_axi_clk(host); | |
| 631 | − | |
| 632 | − /* Only restore the mode when the controller is running */ | |
| 633 | − ctrl = readl(host->base + LCDC_CTRL); | |
| 634 | − if (!(ctrl & CTRL_RUN)) { | |
| 635 | − ret = -EINVAL; | |
| 636 | − goto err; | |
| 637 | − } | |
| 638 | − | |
| 639 | − vdctrl0 = readl(host->base + LCDC_VDCTRL0); | |
| 640 | − vdctrl2 = readl(host->base + LCDC_VDCTRL2); | |
| 641 | − vdctrl3 = readl(host->base + LCDC_VDCTRL3); | |
| 642 | − vdctrl4 = readl(host->base + LCDC_VDCTRL4); | |
| 643 | − | |
| 644 | − transfer_count = readl(host->base + host->devdata->transfer_count); | |
| 645 | − | |
| 646 | − vmode->xres = TRANSFER_COUNT_GET_HCOUNT(transfer_count); | |
| 647 | − vmode->yres = TRANSFER_COUNT_GET_VCOUNT(transfer_count); | |
| 648 | − | |
| 649 | − switch (CTRL_GET_WORD_LENGTH(ctrl)) { | |
| 650 | − case 0: | |
| 651 | − bits_per_pixel = 16; | |
| 652 | − break; | |
| 653 | − case 3: | |
| 654 | − bits_per_pixel = 32; | |
| 655 | − break; | |
| 656 | − case 1: | |
| 657 | − default: | |
| 658 | − ret = -EINVAL; | |
| 659 | − goto err; | |
| 660 | − } | |
| 661 | − | |
| 662 | − fb_info->var.bits_per_pixel = bits_per_pixel; | |
| 663 | − | |
| 664 | − vmode->pixclock = KHZ2PICOS(clk_get_rate(host->clk) / 1000U); | |
| 665 | − vmode->hsync_len = get_hsync_pulse_width(host, vdctrl2); | |
| 666 | − vmode->left_margin = GET_HOR_WAIT_CNT(vdctrl3) - vmode->hsync_len; | |
| 667 | − vmode->right_margin = VDCTRL2_GET_HSYNC_PERIOD(vdctrl2) - | |
| 668 | − vmode->hsync_len - vmode->left_margin - vmode->xres; | |
| 669 | − vmode->vsync_len = VDCTRL0_GET_VSYNC_PULSE_WIDTH(vdctrl0); | |
| 670 | − period = readl(host->base + LCDC_VDCTRL1); | |
| 671 | − vmode->upper_margin = GET_VERT_WAIT_CNT(vdctrl3) - vmode->vsync_len; | |
| 672 | − vmode->lower_margin = period - vmode->vsync_len - | |
| 673 | − vmode->upper_margin - vmode->yres; | |
| 674 | − | |
| 675 | − vmode->vmode = FB_VMODE_NONINTERLACED; | |
| 676 | − | |
| 677 | − vmode->sync = 0; | |
| 678 | − if (vdctrl0 & VDCTRL0_HSYNC_ACT_HIGH) | |
| 679 | − vmode->sync |= FB_SYNC_HOR_HIGH_ACT; | |
| 680 | − if (vdctrl0 & VDCTRL0_VSYNC_ACT_HIGH) | |
| 681 | − vmode->sync |= FB_SYNC_VERT_HIGH_ACT; | |
| 682 | − | |
| 683 | − pr_debug("Reconstructed video mode:\n"); | |
| 684 | − pr_debug("%dx%d, hsync: %u left: %u, right: %u, vsync: %u, upper: %u, lower: %u\n", | |
| 685 | − vmode->xres, vmode->yres, vmode->hsync_len, vmode->left_margin, | |
| 686 | − vmode->right_margin, vmode->vsync_len, vmode->upper_margin, | |
| 687 | − vmode->lower_margin); | |
| 688 | − pr_debug("pixclk: %ldkHz\n", PICOS2KHZ(vmode->pixclock)); | |
| 689 | − | |
| 690 | − host->ld_intf_width = CTRL_GET_BUS_WIDTH(ctrl); | |
| 691 | − host->dotclk_delay = VDCTRL4_GET_DOTCLK_DLY(vdctrl4); | |
| 692 | − | |
| 693 | − fb_info->fix.line_length = vmode->xres * (bits_per_pixel >> 3); | |
| 694 | − | |
| 695 | − pa = readl(host->base + host->devdata->cur_buf); | |
| 696 | − fbsize = fb_info->fix.line_length * vmode->yres; | |
| 697 | − if (pa < fb_info->fix.smem_start) { | |
| 698 | − ret = -EINVAL; | |
| 699 | − goto err; | |
| 700 | − } | |
| 701 | − if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len) { | |
| 702 | − ret = -EINVAL; | |
| 703 | − goto err; | |
| 704 | − } | |
| 705 | − ofs = pa - fb_info->fix.smem_start; | |
| 706 | − if (ofs) { | |
| 707 | − memmove(fb_info->screen_base, fb_info->screen_base + ofs, fbsize); | |
| 708 | − writel(fb_info->fix.smem_start, host->base + host->devdata->next_buf); | |
| 709 | − } | |
| 710 | − | |
| 711 | − fb_info->fix.ypanstep = 1; | |
| 712 | − | |
| 713 | − clk_prepare_enable(host->clk); | |
| 714 | − host->enabled = 1; | |
| 715 | − | |
| 716 | −err: | |
| 717 | − if (ret) | |
| 718 | − mxsfb_disable_axi_clk(host); | |
| 719 | − | |
| 720 | − return ret; | |
| 721 | −} | |
| 722 | − | |
| 723 | −static int mxsfb_init_fbinfo_dt(struct fb_info *fb_info, | |
| 724 | − struct fb_videomode *vmode) | |
| 725 | −{ | |
| 726 | − struct mxsfb_info *host = fb_info->par; | |
| 727 | − struct fb_var_screeninfo *var = &fb_info->var; | |
| 728 | − struct device *dev = &host->pdev->dev; | |
| 729 | − struct device_node *np = host->pdev->dev.of_node; | |
| 730 | − struct device_node *display_np; | |
| 731 | − struct videomode vm; | |
| 732 | − u32 width; | |
| 733 | − int ret; | |
| 734 | − | |
| 735 | − display_np = of_parse_phandle(np, "display", 0); | |
| 736 | − if (!display_np) { | |
| 737 | − dev_err(dev, "failed to find display phandle\n"); | |
| 738 | − return -ENOENT; | |
| 739 | − } | |
| 740 | − | |
| 741 | − ret = of_property_read_u32(display_np, "bus-width", &width); | |
| 742 | − if (ret < 0) { | |
| 743 | − dev_err(dev, "failed to get property bus-width\n"); | |
| 744 | − goto put_display_node; | |
| 745 | − } | |
| 746 | − | |
| 747 | − switch (width) { | |
| 748 | − case 8: | |
| 749 | − host->ld_intf_width = STMLCDIF_8BIT; | |
| 750 | − break; | |
| 751 | − case 16: | |
| 752 | − host->ld_intf_width = STMLCDIF_16BIT; | |
| 753 | − break; | |
| 754 | − case 18: | |
| 755 | − host->ld_intf_width = STMLCDIF_18BIT; | |
| 756 | − break; | |
| 757 | − case 24: | |
| 758 | − host->ld_intf_width = STMLCDIF_24BIT; | |
| 759 | − break; | |
| 760 | − default: | |
| 761 | − dev_err(dev, "invalid bus-width value\n"); | |
| 762 | − ret = -EINVAL; | |
| 763 | − goto put_display_node; | |
| 764 | − } | |
| 765 | − | |
| 766 | − ret = of_property_read_u32(display_np, "bits-per-pixel", | |
| 767 | − &var->bits_per_pixel); | |
| 768 | − if (ret < 0) { | |
| 769 | − dev_err(dev, "failed to get property bits-per-pixel\n"); | |
| 770 | − goto put_display_node; | |
| 771 | − } | |
| 772 | − | |
| 773 | − ret = of_get_videomode(display_np, &vm, OF_USE_NATIVE_MODE); | |
| 774 | − if (ret) { | |
| 775 | − dev_err(dev, "failed to get videomode from DT\n"); | |
| 776 | − goto put_display_node; | |
| 777 | − } | |
| 778 | − | |
| 779 | − ret = fb_videomode_from_videomode(&vm, vmode); | |
| 780 | − if (ret < 0) | |
| 781 | − goto put_display_node; | |
| 782 | − | |
| 783 | − if (vm.flags & DISPLAY_FLAGS_DE_HIGH) | |
| 784 | − host->sync |= MXSFB_SYNC_DATA_ENABLE_HIGH_ACT; | |
| 785 | − | |
| 786 | − /* | |
| 787 | − * The PIXDATA flags of the display_flags enum are controller | |
| 788 | − * centric, e.g. NEGEDGE means drive data on negative edge. | |
| 789 | − * However, the drivers flag is display centric: Sample the | |
| 790 | − * data on negative (falling) edge. Therefore, check for the | |
| 791 | − * POSEDGE flag: | |
| 792 | − * drive on positive edge => sample on negative edge | |
| 793 | − */ | |
| 794 | − if (vm.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) | |
| 795 | − host->sync |= MXSFB_SYNC_DOTCLK_FALLING_ACT; | |
| 796 | − | |
| 797 | −put_display_node: | |
| 798 | − of_node_put(display_np); | |
| 799 | − return ret; | |
| 800 | −} | |
| 801 | − | |
| 802 | −static int mxsfb_init_fbinfo(struct fb_info *fb_info, | |
| 803 | − struct fb_videomode *vmode) | |
| 804 | −{ | |
| 805 | − int ret; | |
| 806 | − struct mxsfb_info *host = fb_info->par; | |
| 807 | − struct device *dev = &host->pdev->dev; | |
| 808 | − struct fb_var_screeninfo *var = &fb_info->var; | |
| 809 | − dma_addr_t fb_phys; | |
| 810 | − void *fb_virt; | |
| 811 | − unsigned fb_size; | |
| 812 | − | |
| 813 | − fb_info->fbops = &mxsfb_ops; | |
| 814 | − fb_info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST; | |
| 815 | − strlcpy(fb_info->fix.id, "mxs", sizeof(fb_info->fix.id)); | |
| 816 | − fb_info->fix.type = FB_TYPE_PACKED_PIXELS; | |
| 817 | − fb_info->fix.ypanstep = 1; | |
| 818 | − fb_info->fix.visual = FB_VISUAL_TRUECOLOR, | |
| 819 | − fb_info->fix.accel = FB_ACCEL_NONE; | |
| 820 | − | |
| 821 | − ret = mxsfb_init_fbinfo_dt(fb_info, vmode); | |
| 822 | − if (ret) | |
| 823 | − return ret; | |
| 824 | − | |
| 825 | − var->nonstd = 0; | |
| 826 | − var->activate = FB_ACTIVATE_NOW; | |
| 827 | − var->accel_flags = 0; | |
| 828 | − var->vmode = FB_VMODE_NONINTERLACED; | |
| 829 | − | |
| 830 | − /* Memory allocation for framebuffer */ | |
| 831 | − fb_size = SZ_2M; | |
| 832 | − fb_virt = dma_alloc_wc(dev, PAGE_ALIGN(fb_size), &fb_phys, GFP_KERNEL); | |
| 833 | − if (!fb_virt) | |
| 834 | − return -ENOMEM; | |
| 835 | − | |
| 836 | − fb_info->fix.smem_start = fb_phys; | |
| 837 | − fb_info->screen_base = fb_virt; | |
| 838 | − fb_info->screen_size = fb_info->fix.smem_len = fb_size; | |
| 839 | − | |
| 840 | − if (mxsfb_restore_mode(fb_info, vmode)) | |
| 841 | − memset(fb_virt, 0, fb_size); | |
| 842 | − | |
| 843 | − return 0; | |
| 844 | −} | |
| 845 | − | |
| 846 | −static void mxsfb_free_videomem(struct fb_info *fb_info) | |
| 847 | −{ | |
| 848 | − struct mxsfb_info *host = fb_info->par; | |
| 849 | − struct device *dev = &host->pdev->dev; | |
| 850 | − | |
| 851 | − dma_free_wc(dev, fb_info->screen_size, fb_info->screen_base, | |
| 852 | − fb_info->fix.smem_start); | |
| 853 | −} | |
| 854 | − | |
| 855 | −static const struct platform_device_id mxsfb_devtype[] = { | |
| 856 | − { | |
| 857 | − .name = "imx23-fb", | |
| 858 | − .driver_data = MXSFB_V3, | |
| 859 | − }, { | |
| 860 | − .name = "imx28-fb", | |
| 861 | − .driver_data = MXSFB_V4, | |
| 862 | − }, { | |
| 863 | − /* sentinel */ | |
| 864 | − } | |
| 865 | −}; | |
| 866 | −MODULE_DEVICE_TABLE(platform, mxsfb_devtype); | |
| 867 | − | |
| 868 | −static const struct of_device_id mxsfb_dt_ids[] = { | |
| 869 | − { .compatible = "fsl,imx23-lcdif", .data = &mxsfb_devtype[0], }, | |
| 870 | − { .compatible = "fsl,imx28-lcdif", .data = &mxsfb_devtype[1], }, | |
| 871 | − { /* sentinel */ } | |
| 872 | −}; | |
| 873 | −MODULE_DEVICE_TABLE(of, mxsfb_dt_ids); | |
| 874 | − | |
| 875 | −static int mxsfb_probe(struct platform_device *pdev) | |
| 876 | −{ | |
| 877 | − const struct of_device_id *of_id = | |
| 878 | − of_match_device(mxsfb_dt_ids, &pdev->dev); | |
| 879 | − struct resource *res; | |
| 880 | − struct mxsfb_info *host; | |
| 881 | − struct fb_info *fb_info; | |
| 882 | − struct fb_videomode *mode; | |
| 883 | − int ret; | |
| 884 | − | |
| 885 | − if (of_id) | |
| 886 | − pdev->id_entry = of_id->data; | |
| 887 | − | |
| 888 | − fb_info = framebuffer_alloc(sizeof(struct mxsfb_info), &pdev->dev); | |
| 889 | − if (!fb_info) { | |
| 890 | − dev_err(&pdev->dev, "Failed to allocate fbdev\n"); | |
| 891 | − return -ENOMEM; | |
| 892 | − } | |
| 893 | − | |
| 894 | − mode = devm_kzalloc(&pdev->dev, sizeof(struct fb_videomode), | |
| 895 | − GFP_KERNEL); | |
| 896 | − if (mode == NULL) | |
| 897 | − return -ENOMEM; | |
| 898 | − | |
| 899 | − host = fb_info->par; | |
| 900 | − | |
| 901 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 902 | − host->base = devm_ioremap_resource(&pdev->dev, res); | |
| 903 | − if (IS_ERR(host->base)) { | |
| 904 | − ret = PTR_ERR(host->base); | |
| 905 | − goto fb_release; | |
| 906 | − } | |
| 907 | − | |
| 908 | − host->pdev = pdev; | |
| 909 | − platform_set_drvdata(pdev, host); | |
| 910 | − | |
| 911 | − host->devdata = &mxsfb_devdata[pdev->id_entry->driver_data]; | |
| 912 | − | |
| 913 | − host->clk = devm_clk_get(&host->pdev->dev, NULL); | |
| 914 | − if (IS_ERR(host->clk)) { | |
| 915 | − ret = PTR_ERR(host->clk); | |
| 916 | − goto fb_release; | |
| 917 | − } | |
| 918 | − | |
| 919 | − host->clk_axi = devm_clk_get(&host->pdev->dev, "axi"); | |
| 920 | − if (IS_ERR(host->clk_axi)) | |
| 921 | − host->clk_axi = NULL; | |
| 922 | − | |
| 923 | − host->clk_disp_axi = devm_clk_get(&host->pdev->dev, "disp_axi"); | |
| 924 | − if (IS_ERR(host->clk_disp_axi)) | |
| 925 | − host->clk_disp_axi = NULL; | |
| 926 | − | |
| 927 | − host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd"); | |
| 928 | − if (IS_ERR(host->reg_lcd)) | |
| 929 | − host->reg_lcd = NULL; | |
| 930 | − | |
| 931 | −#if defined(CONFIG_FB_PRE_INIT_FB) | |
| 932 | − host->pre_init = 1; | |
| 933 | −#endif | |
| 934 | − | |
| 935 | − fb_info->pseudo_palette = devm_kcalloc(&pdev->dev, 16, sizeof(u32), | |
| 936 | − GFP_KERNEL); | |
| 937 | − if (!fb_info->pseudo_palette) { | |
| 938 | − ret = -ENOMEM; | |
| 939 | − goto fb_release; | |
| 940 | − } | |
| 941 | − | |
| 942 | − ret = mxsfb_init_fbinfo(fb_info, mode); | |
| 943 | − if (ret != 0) | |
| 944 | − goto fb_release; | |
| 945 | − | |
| 946 | − fb_videomode_to_var(&fb_info->var, mode); | |
| 947 | − | |
| 948 | − /* init the color fields */ | |
| 949 | − mxsfb_check_var(&fb_info->var, fb_info); | |
| 950 | − | |
| 951 | − platform_set_drvdata(pdev, fb_info); | |
| 952 | − | |
| 953 | − ret = register_framebuffer(fb_info); | |
| 954 | − if (ret != 0) { | |
| 955 | − dev_err(&pdev->dev,"Failed to register framebuffer\n"); | |
| 956 | − goto fb_destroy; | |
| 957 | − } | |
| 958 | − | |
| 959 | − if (!host->enabled) { | |
| 960 | − mxsfb_enable_axi_clk(host); | |
| 961 | − writel(0, host->base + LCDC_CTRL); | |
| 962 | − mxsfb_disable_axi_clk(host); | |
| 963 | − mxsfb_set_par(fb_info); | |
| 964 | − mxsfb_enable_controller(fb_info); | |
| 965 | − } | |
| 966 | − | |
| 967 | − host->pre_init = 0; | |
| 968 | − dev_info(&pdev->dev, "initialized\n"); | |
| 969 | − | |
| 970 | − return 0; | |
| 971 | − | |
| 972 | −fb_destroy: | |
| 973 | − if (host->enabled) | |
| 974 | − clk_disable_unprepare(host->clk); | |
| 975 | −fb_release: | |
| 976 | − framebuffer_release(fb_info); | |
| 977 | − | |
| 978 | − return ret; | |
| 979 | −} | |
| 980 | − | |
| 981 | −static int mxsfb_remove(struct platform_device *pdev) | |
| 982 | −{ | |
| 983 | − struct fb_info *fb_info = platform_get_drvdata(pdev); | |
| 984 | − struct mxsfb_info *host = fb_info->par; | |
| 985 | − | |
| 986 | − if (host->enabled) | |
| 987 | − mxsfb_disable_controller(fb_info); | |
| 988 | − | |
| 989 | − unregister_framebuffer(fb_info); | |
| 990 | − mxsfb_free_videomem(fb_info); | |
| 991 | − | |
| 992 | − framebuffer_release(fb_info); | |
| 993 | − | |
| 994 | − return 0; | |
| 995 | −} | |
| 996 | − | |
| 997 | −static void mxsfb_shutdown(struct platform_device *pdev) | |
| 998 | −{ | |
| 999 | − struct fb_info *fb_info = platform_get_drvdata(pdev); | |
| 1000 | − struct mxsfb_info *host = fb_info->par; | |
| 1001 | − | |
| 1002 | − mxsfb_enable_axi_clk(host); | |
| 1003 | − | |
| 1004 | − /* | |
| 1005 | − * Force stop the LCD controller as keeping it running during reboot | |
| 1006 | − * might interfere with the BootROM's boot mode pads sampling. | |
| 1007 | − */ | |
| 1008 | − writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR); | |
| 1009 | − | |
| 1010 | − mxsfb_disable_axi_clk(host); | |
| 1011 | −} | |
| 1012 | − | |
| 1013 | −static struct platform_driver mxsfb_driver = { | |
| 1014 | − .probe = mxsfb_probe, | |
| 1015 | − .remove = mxsfb_remove, | |
| 1016 | − .shutdown = mxsfb_shutdown, | |
| 1017 | − .id_table = mxsfb_devtype, | |
| 1018 | − .driver = { | |
| 1019 | − .name = DRIVER_NAME, | |
| 1020 | − .of_match_table = mxsfb_dt_ids, | |
| 1021 | − }, | |
| 1022 | −}; | |
| 1023 | − | |
| 1024 | −module_platform_driver(mxsfb_driver); | |
| 1025 | − | |
| 1026 | −MODULE_DESCRIPTION("Freescale mxs framebuffer driver"); | |
| 1027 | −MODULE_AUTHOR("Sascha Hauer, Pengutronix"); | |
| 1028 | −MODULE_LICENSE("GPL"); | |
| @@ -2122,14 +2122,7 @@ static void neofb_remove(struct pci_dev *dev) · 2121 unmodified lines | ||
| 2122 | 2122 | DBG("neofb_remove"); |
| 2123 | 2123 | |
| 2124 | 2124 | if (info) { |
| 2125 | − /* | |
| 2126 | − * If unregister_framebuffer fails, then | |
| 2127 | − * we will be leaving hooks that could cause | |
| 2128 | − * oopsen laying around. | |
| 2129 | − */ | |
| 2130 | − if (unregister_framebuffer(info)) | |
| 2131 | − printk(KERN_WARNING | |
| 2132 | − "neofb: danger danger! Oopsen imminent!\n"); | |
| 2125 | + unregister_framebuffer(info); | |
| 2133 | 2126 | |
| 2134 | 2127 | neo_unmap_video(info); |
| 2135 | 2128 | fb_destroy_modedb(info->monspecs.modedb); |
| @@ -1502,8 +1502,6 @@ static int planes_init(struct omapfb_device *fbdev) · 1501 unmodified lines | ||
| 1502 | 1502 | fbi = framebuffer_alloc(sizeof(struct omapfb_plane_struct), |
| 1503 | 1503 | fbdev->dev); |
| 1504 | 1504 | if (fbi == NULL) { |
| 1505 | − dev_err(fbdev->dev, | |
| 1506 | − "unable to allocate memory for plane info\n"); | |
| 1507 | 1505 | planes_cleanup(fbdev); |
| 1508 | 1506 | return -ENOMEM; |
| 1509 | 1507 | } |
| @@ -39,18 +39,6 @@ config FB_OMAP2_DSS_DPI · 38 unmodified lines | ||
| 39 | 39 | help |
| 40 | 40 | DPI Interface. This is the Parallel Display Interface. |
| 41 | 41 | |
| 42 | −config FB_OMAP2_DSS_RFBI | |
| 43 | − bool "RFBI support" | |
| 44 | − depends on BROKEN | |
| 45 | − help | |
| 46 | − MIPI DBI support (RFBI, Remote Framebuffer Interface, in Texas | |
| 47 | − Instrument's terminology). | |
| 48 | − | |
| 49 | − DBI is a bus between the host processor and a peripheral, | |
| 50 | − such as a display or a framebuffer chip. | |
| 51 | − | |
| 52 | − See http://www.mipi.org/ for DBI specifications. | |
| 53 | − | |
| 54 | 42 | config FB_OMAP2_DSS_VENC |
| 55 | 43 | bool "VENC support" |
| 56 | 44 | default y |
| @@ -8,7 +8,6 @@ omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ · 7 unmodified lines | ||
| 8 | 8 | omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \ |
| 9 | 9 | dispc-compat.o display-sysfs.o |
| 10 | 10 | omapdss-$(CONFIG_FB_OMAP2_DSS_DPI) += dpi.o |
| 11 | −omapdss-$(CONFIG_FB_OMAP2_DSS_RFBI) += rfbi.o | |
| 12 | 11 | omapdss-$(CONFIG_FB_OMAP2_DSS_VENC) += venc.o |
| 13 | 12 | omapdss-$(CONFIG_FB_OMAP2_DSS_SDI) += sdi.o |
| 14 | 13 | omapdss-$(CONFIG_FB_OMAP2_DSS_DSI) += dsi.o |
| @@ -207,9 +207,6 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = { · 206 unmodified lines | ||
| 207 | 207 | #ifdef CONFIG_FB_OMAP2_DSS_SDI |
| 208 | 208 | sdi_init_platform_driver, |
| 209 | 209 | #endif |
| 210 | −#ifdef CONFIG_FB_OMAP2_DSS_RFBI | |
| 211 | − rfbi_init_platform_driver, | |
| 212 | −#endif | |
| 213 | 210 | #ifdef CONFIG_FB_OMAP2_DSS_VENC |
| 214 | 211 | venc_init_platform_driver, |
| 215 | 212 | #endif |
| @@ -231,9 +228,6 @@ static void (*dss_output_drv_unreg_funcs[])(void) = { · 15 unmodified lines | ||
| 231 | 228 | #ifdef CONFIG_FB_OMAP2_DSS_VENC |
| 232 | 229 | venc_uninit_platform_driver, |
| 233 | 230 | #endif |
| 234 | −#ifdef CONFIG_FB_OMAP2_DSS_RFBI | |
| 235 | − rfbi_uninit_platform_driver, | |
| 236 | −#endif | |
| 237 | 231 | #ifdef CONFIG_FB_OMAP2_DSS_SDI |
| 238 | 232 | sdi_uninit_platform_driver, |
| 239 | 233 | #endif |
| @@ -461,10 +461,6 @@ void hdmi4_uninit_platform_driver(void); · 460 unmodified lines | ||
| 461 | 461 | int hdmi5_init_platform_driver(void) __init; |
| 462 | 462 | void hdmi5_uninit_platform_driver(void); |
| 463 | 463 | |
| 464 | −/* RFBI */ | |
| 465 | −int rfbi_init_platform_driver(void) __init; | |
| 466 | −void rfbi_uninit_platform_driver(void); | |
| 467 | − | |
| 468 | 464 | |
| 469 | 465 | #ifdef CONFIG_FB_OMAP2_DSS_COLLECT_IRQ_STATS |
| 470 | 466 | static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr) |
| @@ -1,1067 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0-only | |
| 2 | −/* | |
| 3 | − * linux/drivers/video/omap2/dss/rfbi.c | |
| 4 | − * | |
| 5 | − * Copyright (C) 2009 Nokia Corporation | |
| 6 | − * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> | |
| 7 | − * | |
| 8 | − * Some code and ideas taken from drivers/video/omap/ driver | |
| 9 | − * by Imre Deak. | |
| 10 | − */ | |
| 11 | − | |
| 12 | −#define DSS_SUBSYS_NAME "RFBI" | |
| 13 | − | |
| 14 | −#include <linux/kernel.h> | |
| 15 | −#include <linux/dma-mapping.h> | |
| 16 | −#include <linux/export.h> | |
| 17 | −#include <linux/vmalloc.h> | |
| 18 | −#include <linux/clk.h> | |
| 19 | −#include <linux/io.h> | |
| 20 | −#include <linux/delay.h> | |
| 21 | −#include <linux/kfifo.h> | |
| 22 | −#include <linux/ktime.h> | |
| 23 | −#include <linux/hrtimer.h> | |
| 24 | −#include <linux/seq_file.h> | |
| 25 | −#include <linux/semaphore.h> | |
| 26 | −#include <linux/platform_device.h> | |
| 27 | −#include <linux/pm_runtime.h> | |
| 28 | −#include <linux/component.h> | |
| 29 | − | |
| 30 | −#include <video/omapfb_dss.h> | |
| 31 | −#include "dss.h" | |
| 32 | − | |
| 33 | −struct rfbi_reg { u16 idx; }; | |
| 34 | − | |
| 35 | −#define RFBI_REG(idx) ((const struct rfbi_reg) { idx }) | |
| 36 | − | |
| 37 | −#define RFBI_REVISION RFBI_REG(0x0000) | |
| 38 | −#define RFBI_SYSCONFIG RFBI_REG(0x0010) | |
| 39 | −#define RFBI_SYSSTATUS RFBI_REG(0x0014) | |
| 40 | −#define RFBI_CONTROL RFBI_REG(0x0040) | |
| 41 | −#define RFBI_PIXEL_CNT RFBI_REG(0x0044) | |
| 42 | −#define RFBI_LINE_NUMBER RFBI_REG(0x0048) | |
| 43 | −#define RFBI_CMD RFBI_REG(0x004c) | |
| 44 | −#define RFBI_PARAM RFBI_REG(0x0050) | |
| 45 | −#define RFBI_DATA RFBI_REG(0x0054) | |
| 46 | −#define RFBI_READ RFBI_REG(0x0058) | |
| 47 | −#define RFBI_STATUS RFBI_REG(0x005c) | |
| 48 | − | |
| 49 | −#define RFBI_CONFIG(n) RFBI_REG(0x0060 + (n)*0x18) | |
| 50 | −#define RFBI_ONOFF_TIME(n) RFBI_REG(0x0064 + (n)*0x18) | |
| 51 | −#define RFBI_CYCLE_TIME(n) RFBI_REG(0x0068 + (n)*0x18) | |
| 52 | −#define RFBI_DATA_CYCLE1(n) RFBI_REG(0x006c + (n)*0x18) | |
| 53 | −#define RFBI_DATA_CYCLE2(n) RFBI_REG(0x0070 + (n)*0x18) | |
| 54 | −#define RFBI_DATA_CYCLE3(n) RFBI_REG(0x0074 + (n)*0x18) | |
| 55 | − | |
| 56 | −#define RFBI_VSYNC_WIDTH RFBI_REG(0x0090) | |
| 57 | −#define RFBI_HSYNC_WIDTH RFBI_REG(0x0094) | |
| 58 | − | |
| 59 | −#define REG_FLD_MOD(idx, val, start, end) \ | |
| 60 | − rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end)) | |
| 61 | − | |
| 62 | −enum omap_rfbi_cycleformat { | |
| 63 | − OMAP_DSS_RFBI_CYCLEFORMAT_1_1 = 0, | |
| 64 | − OMAP_DSS_RFBI_CYCLEFORMAT_2_1 = 1, | |
| 65 | − OMAP_DSS_RFBI_CYCLEFORMAT_3_1 = 2, | |
| 66 | − OMAP_DSS_RFBI_CYCLEFORMAT_3_2 = 3, | |
| 67 | −}; | |
| 68 | − | |
| 69 | −enum omap_rfbi_datatype { | |
| 70 | − OMAP_DSS_RFBI_DATATYPE_12 = 0, | |
| 71 | − OMAP_DSS_RFBI_DATATYPE_16 = 1, | |
| 72 | − OMAP_DSS_RFBI_DATATYPE_18 = 2, | |
| 73 | − OMAP_DSS_RFBI_DATATYPE_24 = 3, | |
| 74 | −}; | |
| 75 | − | |
| 76 | −enum omap_rfbi_parallelmode { | |
| 77 | − OMAP_DSS_RFBI_PARALLELMODE_8 = 0, | |
| 78 | − OMAP_DSS_RFBI_PARALLELMODE_9 = 1, | |
| 79 | − OMAP_DSS_RFBI_PARALLELMODE_12 = 2, | |
| 80 | − OMAP_DSS_RFBI_PARALLELMODE_16 = 3, | |
| 81 | −}; | |
| 82 | − | |
| 83 | −static int rfbi_convert_timings(struct rfbi_timings *t); | |
| 84 | −static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); | |
| 85 | − | |
| 86 | −static struct { | |
| 87 | − struct platform_device *pdev; | |
| 88 | − void __iomem *base; | |
| 89 | − | |
| 90 | − unsigned long l4_khz; | |
| 91 | − | |
| 92 | − enum omap_rfbi_datatype datatype; | |
| 93 | − enum omap_rfbi_parallelmode parallelmode; | |
| 94 | − | |
| 95 | − enum omap_rfbi_te_mode te_mode; | |
| 96 | − int te_enabled; | |
| 97 | − | |
| 98 | − void (*framedone_callback)(void *data); | |
| 99 | − void *framedone_callback_data; | |
| 100 | − | |
| 101 | − struct omap_dss_device *dssdev[2]; | |
| 102 | − | |
| 103 | − struct semaphore bus_lock; | |
| 104 | − | |
| 105 | − struct omap_video_timings timings; | |
| 106 | − int pixel_size; | |
| 107 | − int data_lines; | |
| 108 | − struct rfbi_timings intf_timings; | |
| 109 | − | |
| 110 | − struct omap_dss_device output; | |
| 111 | −} rfbi; | |
| 112 | − | |
| 113 | −static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val) | |
| 114 | −{ | |
| 115 | − __raw_writel(val, rfbi.base + idx.idx); | |
| 116 | −} | |
| 117 | − | |
| 118 | −static inline u32 rfbi_read_reg(const struct rfbi_reg idx) | |
| 119 | −{ | |
| 120 | − return __raw_readl(rfbi.base + idx.idx); | |
| 121 | −} | |
| 122 | − | |
| 123 | −static int rfbi_runtime_get(void) | |
| 124 | −{ | |
| 125 | − int r; | |
| 126 | − | |
| 127 | − DSSDBG("rfbi_runtime_get\n"); | |
| 128 | − | |
| 129 | − r = pm_runtime_get_sync(&rfbi.pdev->dev); | |
| 130 | − WARN_ON(r < 0); | |
| 131 | − return r < 0 ? r : 0; | |
| 132 | −} | |
| 133 | − | |
| 134 | −static void rfbi_runtime_put(void) | |
| 135 | −{ | |
| 136 | − int r; | |
| 137 | − | |
| 138 | − DSSDBG("rfbi_runtime_put\n"); | |
| 139 | − | |
| 140 | − r = pm_runtime_put_sync(&rfbi.pdev->dev); | |
| 141 | − WARN_ON(r < 0 && r != -ENOSYS); | |
| 142 | −} | |
| 143 | − | |
| 144 | −static void rfbi_bus_lock(void) | |
| 145 | −{ | |
| 146 | − down(&rfbi.bus_lock); | |
| 147 | −} | |
| 148 | − | |
| 149 | −static void rfbi_bus_unlock(void) | |
| 150 | −{ | |
| 151 | − up(&rfbi.bus_lock); | |
| 152 | −} | |
| 153 | − | |
| 154 | −static void rfbi_write_command(const void *buf, u32 len) | |
| 155 | −{ | |
| 156 | − switch (rfbi.parallelmode) { | |
| 157 | − case OMAP_DSS_RFBI_PARALLELMODE_8: | |
| 158 | − { | |
| 159 | − const u8 *b = buf; | |
| 160 | − for (; len; len--) | |
| 161 | − rfbi_write_reg(RFBI_CMD, *b++); | |
| 162 | − break; | |
| 163 | − } | |
| 164 | − | |
| 165 | − case OMAP_DSS_RFBI_PARALLELMODE_16: | |
| 166 | − { | |
| 167 | − const u16 *w = buf; | |
| 168 | − BUG_ON(len & 1); | |
| 169 | − for (; len; len -= 2) | |
| 170 | − rfbi_write_reg(RFBI_CMD, *w++); | |
| 171 | − break; | |
| 172 | − } | |
| 173 | − | |
| 174 | − case OMAP_DSS_RFBI_PARALLELMODE_9: | |
| 175 | − case OMAP_DSS_RFBI_PARALLELMODE_12: | |
| 176 | − default: | |
| 177 | − BUG(); | |
| 178 | − } | |
| 179 | −} | |
| 180 | − | |
| 181 | −static void rfbi_read_data(void *buf, u32 len) | |
| 182 | −{ | |
| 183 | − switch (rfbi.parallelmode) { | |
| 184 | − case OMAP_DSS_RFBI_PARALLELMODE_8: | |
| 185 | − { | |
| 186 | − u8 *b = buf; | |
| 187 | − for (; len; len--) { | |
| 188 | − rfbi_write_reg(RFBI_READ, 0); | |
| 189 | − *b++ = rfbi_read_reg(RFBI_READ); | |
| 190 | − } | |
| 191 | − break; | |
| 192 | − } | |
| 193 | − | |
| 194 | − case OMAP_DSS_RFBI_PARALLELMODE_16: | |
| 195 | − { | |
| 196 | − u16 *w = buf; | |
| 197 | − BUG_ON(len & ~1); | |
| 198 | − for (; len; len -= 2) { | |
| 199 | − rfbi_write_reg(RFBI_READ, 0); | |
| 200 | − *w++ = rfbi_read_reg(RFBI_READ); | |
| 201 | − } | |
| 202 | − break; | |
| 203 | − } | |
| 204 | − | |
| 205 | − case OMAP_DSS_RFBI_PARALLELMODE_9: | |
| 206 | − case OMAP_DSS_RFBI_PARALLELMODE_12: | |
| 207 | − default: | |
| 208 | − BUG(); | |
| 209 | − } | |
| 210 | −} | |
| 211 | − | |
| 212 | −static void rfbi_write_data(const void *buf, u32 len) | |
| 213 | −{ | |
| 214 | − switch (rfbi.parallelmode) { | |
| 215 | − case OMAP_DSS_RFBI_PARALLELMODE_8: | |
| 216 | − { | |
| 217 | − const u8 *b = buf; | |
| 218 | − for (; len; len--) | |
| 219 | − rfbi_write_reg(RFBI_PARAM, *b++); | |
| 220 | − break; | |
| 221 | − } | |
| 222 | − | |
| 223 | − case OMAP_DSS_RFBI_PARALLELMODE_16: | |
| 224 | − { | |
| 225 | − const u16 *w = buf; | |
| 226 | − BUG_ON(len & 1); | |
| 227 | − for (; len; len -= 2) | |
| 228 | − rfbi_write_reg(RFBI_PARAM, *w++); | |
| 229 | − break; | |
| 230 | − } | |
| 231 | − | |
| 232 | − case OMAP_DSS_RFBI_PARALLELMODE_9: | |
| 233 | − case OMAP_DSS_RFBI_PARALLELMODE_12: | |
| 234 | − default: | |
| 235 | − BUG(); | |
| 236 | − | |
| 237 | − } | |
| 238 | −} | |
| 239 | − | |
| 240 | −static void rfbi_write_pixels(const void __iomem *buf, int scr_width, | |
| 241 | − u16 x, u16 y, | |
| 242 | − u16 w, u16 h) | |
| 243 | −{ | |
| 244 | − int start_offset = scr_width * y + x; | |
| 245 | − int horiz_offset = scr_width - w; | |
| 246 | − int i; | |
| 247 | − | |
| 248 | − if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 && | |
| 249 | − rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) { | |
| 250 | − const u16 __iomem *pd = buf; | |
| 251 | − pd += start_offset; | |
| 252 | − | |
| 253 | − for (; h; --h) { | |
| 254 | − for (i = 0; i < w; ++i) { | |
| 255 | − const u8 __iomem *b = (const u8 __iomem *)pd; | |
| 256 | − rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1)); | |
| 257 | − rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0)); | |
| 258 | − ++pd; | |
| 259 | − } | |
| 260 | − pd += horiz_offset; | |
| 261 | − } | |
| 262 | − } else if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_24 && | |
| 263 | − rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) { | |
| 264 | − const u32 __iomem *pd = buf; | |
| 265 | − pd += start_offset; | |
| 266 | − | |
| 267 | − for (; h; --h) { | |
| 268 | − for (i = 0; i < w; ++i) { | |
| 269 | − const u8 __iomem *b = (const u8 __iomem *)pd; | |
| 270 | − rfbi_write_reg(RFBI_PARAM, __raw_readb(b+2)); | |
| 271 | − rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1)); | |
| 272 | − rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0)); | |
| 273 | − ++pd; | |
| 274 | − } | |
| 275 | − pd += horiz_offset; | |
| 276 | − } | |
| 277 | − } else if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 && | |
| 278 | − rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_16) { | |
| 279 | − const u16 __iomem *pd = buf; | |
| 280 | − pd += start_offset; | |
| 281 | − | |
| 282 | − for (; h; --h) { | |
| 283 | − for (i = 0; i < w; ++i) { | |
| 284 | − rfbi_write_reg(RFBI_PARAM, __raw_readw(pd)); | |
| 285 | − ++pd; | |
| 286 | − } | |
| 287 | − pd += horiz_offset; | |
| 288 | − } | |
| 289 | − } else { | |
| 290 | − BUG(); | |
| 291 | − } | |
| 292 | −} | |
| 293 | − | |
| 294 | −static int rfbi_transfer_area(struct omap_dss_device *dssdev, | |
| 295 | − void (*callback)(void *data), void *data) | |
| 296 | −{ | |
| 297 | − u32 l; | |
| 298 | − int r; | |
| 299 | − struct omap_overlay_manager *mgr = rfbi.output.manager; | |
| 300 | − u16 width = rfbi.timings.x_res; | |
| 301 | − u16 height = rfbi.timings.y_res; | |
| 302 | − | |
| 303 | − /*BUG_ON(callback == 0);*/ | |
| 304 | − BUG_ON(rfbi.framedone_callback != NULL); | |
| 305 | − | |
| 306 | − DSSDBG("rfbi_transfer_area %dx%d\n", width, height); | |
| 307 | − | |
| 308 | − dss_mgr_set_timings(mgr, &rfbi.timings); | |
| 309 | − | |
| 310 | − r = dss_mgr_enable(mgr); | |
| 311 | − if (r) | |
| 312 | − return r; | |
| 313 | − | |
| 314 | − rfbi.framedone_callback = callback; | |
| 315 | − rfbi.framedone_callback_data = data; | |
| 316 | − | |
| 317 | − rfbi_write_reg(RFBI_PIXEL_CNT, width * height); | |
| 318 | − | |
| 319 | − l = rfbi_read_reg(RFBI_CONTROL); | |
| 320 | − l = FLD_MOD(l, 1, 0, 0); /* enable */ | |
| 321 | − if (!rfbi.te_enabled) | |
| 322 | − l = FLD_MOD(l, 1, 4, 4); /* ITE */ | |
| 323 | − | |
| 324 | − rfbi_write_reg(RFBI_CONTROL, l); | |
| 325 | − | |
| 326 | − return 0; | |
| 327 | −} | |
| 328 | − | |
| 329 | −static void framedone_callback(void *data) | |
| 330 | −{ | |
| 331 | − void (*callback)(void *data); | |
| 332 | − | |
| 333 | − DSSDBG("FRAMEDONE\n"); | |
| 334 | − | |
| 335 | − REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0); | |
| 336 | − | |
| 337 | − callback = rfbi.framedone_callback; | |
| 338 | − rfbi.framedone_callback = NULL; | |
| 339 | − | |
| 340 | − if (callback != NULL) | |
| 341 | − callback(rfbi.framedone_callback_data); | |
| 342 | −} | |
| 343 | − | |
| 344 | −#if 1 /* VERBOSE */ | |
| 345 | −static void rfbi_print_timings(void) | |
| 346 | −{ | |
| 347 | − u32 l; | |
| 348 | − u32 time; | |
| 349 | − | |
| 350 | − l = rfbi_read_reg(RFBI_CONFIG(0)); | |
| 351 | − time = 1000000000 / rfbi.l4_khz; | |
| 352 | − if (l & (1 << 4)) | |
| 353 | − time *= 2; | |
| 354 | − | |
| 355 | − DSSDBG("Tick time %u ps\n", time); | |
| 356 | − l = rfbi_read_reg(RFBI_ONOFF_TIME(0)); | |
| 357 | − DSSDBG("CSONTIME %d, CSOFFTIME %d, WEONTIME %d, WEOFFTIME %d, " | |
| 358 | − "REONTIME %d, REOFFTIME %d\n", | |
| 359 | − l & 0x0f, (l >> 4) & 0x3f, (l >> 10) & 0x0f, (l >> 14) & 0x3f, | |
| 360 | − (l >> 20) & 0x0f, (l >> 24) & 0x3f); | |
| 361 | − | |
| 362 | − l = rfbi_read_reg(RFBI_CYCLE_TIME(0)); | |
| 363 | − DSSDBG("WECYCLETIME %d, RECYCLETIME %d, CSPULSEWIDTH %d, " | |
| 364 | − "ACCESSTIME %d\n", | |
| 365 | − (l & 0x3f), (l >> 6) & 0x3f, (l >> 12) & 0x3f, | |
| 366 | − (l >> 22) & 0x3f); | |
| 367 | −} | |
| 368 | −#else | |
| 369 | −static void rfbi_print_timings(void) {} | |
| 370 | −#endif | |
| 371 | − | |
| 372 | − | |
| 373 | − | |
| 374 | − | |
| 375 | −static u32 extif_clk_period; | |
| 376 | − | |
| 377 | −static inline unsigned long round_to_extif_ticks(unsigned long ps, int div) | |
| 378 | −{ | |
| 379 | − int bus_tick = extif_clk_period * div; | |
| 380 | − return (ps + bus_tick - 1) / bus_tick * bus_tick; | |
| 381 | −} | |
| 382 | − | |
| 383 | −static int calc_reg_timing(struct rfbi_timings *t, int div) | |
| 384 | −{ | |
| 385 | − t->clk_div = div; | |
| 386 | − | |
| 387 | − t->cs_on_time = round_to_extif_ticks(t->cs_on_time, div); | |
| 388 | − | |
| 389 | − t->we_on_time = round_to_extif_ticks(t->we_on_time, div); | |
| 390 | − t->we_off_time = round_to_extif_ticks(t->we_off_time, div); | |
| 391 | − t->we_cycle_time = round_to_extif_ticks(t->we_cycle_time, div); | |
| 392 | − | |
| 393 | − t->re_on_time = round_to_extif_ticks(t->re_on_time, div); | |
| 394 | − t->re_off_time = round_to_extif_ticks(t->re_off_time, div); | |
| 395 | − t->re_cycle_time = round_to_extif_ticks(t->re_cycle_time, div); | |
| 396 | − | |
| 397 | − t->access_time = round_to_extif_ticks(t->access_time, div); | |
| 398 | − t->cs_off_time = round_to_extif_ticks(t->cs_off_time, div); | |
| 399 | − t->cs_pulse_width = round_to_extif_ticks(t->cs_pulse_width, div); | |
| 400 | − | |
| 401 | − DSSDBG("[reg]cson %d csoff %d reon %d reoff %d\n", | |
| 402 | − t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time); | |
| 403 | − DSSDBG("[reg]weon %d weoff %d recyc %d wecyc %d\n", | |
| 404 | − t->we_on_time, t->we_off_time, t->re_cycle_time, | |
| 405 | − t->we_cycle_time); | |
| 406 | − DSSDBG("[reg]rdaccess %d cspulse %d\n", | |
| 407 | − t->access_time, t->cs_pulse_width); | |
| 408 | − | |
| 409 | − return rfbi_convert_timings(t); | |
| 410 | −} | |
| 411 | − | |
| 412 | −static int calc_extif_timings(struct rfbi_timings *t) | |
| 413 | −{ | |
| 414 | − u32 max_clk_div; | |
| 415 | − int div; | |
| 416 | − | |
| 417 | − rfbi_get_clk_info(&extif_clk_period, &max_clk_div); | |
| 418 | − for (div = 1; div <= max_clk_div; div++) { | |
| 419 | − if (calc_reg_timing(t, div) == 0) | |
| 420 | − break; | |
| 421 | − } | |
| 422 | − | |
| 423 | − if (div <= max_clk_div) | |
| 424 | − return 0; | |
| 425 | − | |
| 426 | − DSSERR("can't setup timings\n"); | |
| 427 | − return -1; | |
| 428 | −} | |
| 429 | − | |
| 430 | − | |
| 431 | −static void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t) | |
| 432 | −{ | |
| 433 | − int r; | |
| 434 | − | |
| 435 | − if (!t->converted) { | |
| 436 | − r = calc_extif_timings(t); | |
| 437 | − if (r < 0) | |
| 438 | − DSSERR("Failed to calc timings\n"); | |
| 439 | − } | |
| 440 | − | |
| 441 | − BUG_ON(!t->converted); | |
| 442 | − | |
| 443 | − rfbi_write_reg(RFBI_ONOFF_TIME(rfbi_module), t->tim[0]); | |
| 444 | − rfbi_write_reg(RFBI_CYCLE_TIME(rfbi_module), t->tim[1]); | |
| 445 | − | |
| 446 | − /* TIMEGRANULARITY */ | |
| 447 | − REG_FLD_MOD(RFBI_CONFIG(rfbi_module), | |
| 448 | − (t->tim[2] ? 1 : 0), 4, 4); | |
| 449 | − | |
| 450 | − rfbi_print_timings(); | |
| 451 | −} | |
| 452 | − | |
| 453 | −static int ps_to_rfbi_ticks(int time, int div) | |
| 454 | −{ | |
| 455 | − unsigned long tick_ps; | |
| 456 | − int ret; | |
| 457 | − | |
| 458 | − /* Calculate in picosecs to yield more exact results */ | |
| 459 | − tick_ps = 1000000000 / (rfbi.l4_khz) * div; | |
| 460 | − | |
| 461 | − ret = (time + tick_ps - 1) / tick_ps; | |
| 462 | − | |
| 463 | − return ret; | |
| 464 | −} | |
| 465 | − | |
| 466 | −static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div) | |
| 467 | −{ | |
| 468 | − *clk_period = 1000000000 / rfbi.l4_khz; | |
| 469 | − *max_clk_div = 2; | |
| 470 | −} | |
| 471 | − | |
| 472 | −static int rfbi_convert_timings(struct rfbi_timings *t) | |
| 473 | −{ | |
| 474 | − u32 l; | |
| 475 | − int reon, reoff, weon, weoff, cson, csoff, cs_pulse; | |
| 476 | − int actim, recyc, wecyc; | |
| 477 | − int div = t->clk_div; | |
| 478 | − | |
| 479 | − if (div <= 0 || div > 2) | |
| 480 | − return -1; | |
| 481 | − | |
| 482 | − /* Make sure that after conversion it still holds that: | |
| 483 | − * weoff > weon, reoff > reon, recyc >= reoff, wecyc >= weoff, | |
| 484 | − * csoff > cson, csoff >= max(weoff, reoff), actim > reon | |
| 485 | − */ | |
| 486 | − weon = ps_to_rfbi_ticks(t->we_on_time, div); | |
| 487 | − weoff = ps_to_rfbi_ticks(t->we_off_time, div); | |
| 488 | − if (weoff <= weon) | |
| 489 | − weoff = weon + 1; | |
| 490 | − if (weon > 0x0f) | |
| 491 | − return -1; | |
| 492 | − if (weoff > 0x3f) | |
| 493 | − return -1; | |
| 494 | − | |
| 495 | − reon = ps_to_rfbi_ticks(t->re_on_time, div); | |
| 496 | − reoff = ps_to_rfbi_ticks(t->re_off_time, div); | |
| 497 | − if (reoff <= reon) | |
| 498 | − reoff = reon + 1; | |
| 499 | − if (reon > 0x0f) | |
| 500 | − return -1; | |
| 501 | − if (reoff > 0x3f) | |
| 502 | − return -1; | |
| 503 | − | |
| 504 | − cson = ps_to_rfbi_ticks(t->cs_on_time, div); | |
| 505 | − csoff = ps_to_rfbi_ticks(t->cs_off_time, div); | |
| 506 | − if (csoff <= cson) | |
| 507 | − csoff = cson + 1; | |
| 508 | − if (csoff < max(weoff, reoff)) | |
| 509 | − csoff = max(weoff, reoff); | |
| 510 | − if (cson > 0x0f) | |
| 511 | − return -1; | |
| 512 | − if (csoff > 0x3f) | |
| 513 | − return -1; | |
| 514 | − | |
| 515 | − l = cson; | |
| 516 | − l |= csoff << 4; | |
| 517 | − l |= weon << 10; | |
| 518 | − l |= weoff << 14; | |
| 519 | − l |= reon << 20; | |
| 520 | − l |= reoff << 24; | |
| 521 | − | |
| 522 | − t->tim[0] = l; | |
| 523 | − | |
| 524 | − actim = ps_to_rfbi_ticks(t->access_time, div); | |
| 525 | − if (actim <= reon) | |
| 526 | − actim = reon + 1; | |
| 527 | − if (actim > 0x3f) | |
| 528 | − return -1; | |
| 529 | − | |
| 530 | − wecyc = ps_to_rfbi_ticks(t->we_cycle_time, div); | |
| 531 | − if (wecyc < weoff) | |
| 532 | − wecyc = weoff; | |
| 533 | − if (wecyc > 0x3f) | |
| 534 | − return -1; | |
| 535 | − | |
| 536 | − recyc = ps_to_rfbi_ticks(t->re_cycle_time, div); | |
| 537 | − if (recyc < reoff) | |
| 538 | − recyc = reoff; | |
| 539 | − if (recyc > 0x3f) | |
| 540 | − return -1; | |
| 541 | − | |
| 542 | − cs_pulse = ps_to_rfbi_ticks(t->cs_pulse_width, div); | |
| 543 | − if (cs_pulse > 0x3f) | |
| 544 | − return -1; | |
| 545 | − | |
| 546 | − l = wecyc; | |
| 547 | − l |= recyc << 6; | |
| 548 | − l |= cs_pulse << 12; | |
| 549 | − l |= actim << 22; | |
| 550 | − | |
| 551 | − t->tim[1] = l; | |
| 552 | − | |
| 553 | − t->tim[2] = div - 1; | |
| 554 | − | |
| 555 | − t->converted = 1; | |
| 556 | − | |
| 557 | − return 0; | |
| 558 | −} | |
| 559 | − | |
| 560 | −/* xxx FIX module selection missing */ | |
| 561 | −static int rfbi_setup_te(enum omap_rfbi_te_mode mode, | |
| 562 | − unsigned hs_pulse_time, unsigned vs_pulse_time, | |
| 563 | − int hs_pol_inv, int vs_pol_inv, int extif_div) | |
| 564 | −{ | |
| 565 | − int hs, vs; | |
| 566 | − int min; | |
| 567 | − u32 l; | |
| 568 | − | |
| 569 | − hs = ps_to_rfbi_ticks(hs_pulse_time, 1); | |
| 570 | − vs = ps_to_rfbi_ticks(vs_pulse_time, 1); | |
| 571 | − if (hs < 2) | |
| 572 | − return -EDOM; | |
| 573 | − if (mode == OMAP_DSS_RFBI_TE_MODE_2) | |
| 574 | − min = 2; | |
| 575 | − else /* OMAP_DSS_RFBI_TE_MODE_1 */ | |
| 576 | − min = 4; | |
| 577 | − if (vs < min) | |
| 578 | − return -EDOM; | |
| 579 | − if (vs == hs) | |
| 580 | − return -EINVAL; | |
| 581 | − rfbi.te_mode = mode; | |
| 582 | − DSSDBG("setup_te: mode %d hs %d vs %d hs_inv %d vs_inv %d\n", | |
| 583 | − mode, hs, vs, hs_pol_inv, vs_pol_inv); | |
| 584 | − | |
| 585 | − rfbi_write_reg(RFBI_HSYNC_WIDTH, hs); | |
| 586 | − rfbi_write_reg(RFBI_VSYNC_WIDTH, vs); | |
| 587 | − | |
| 588 | − l = rfbi_read_reg(RFBI_CONFIG(0)); | |
| 589 | − if (hs_pol_inv) | |
| 590 | − l &= ~(1 << 21); | |
| 591 | − else | |
| 592 | − l |= 1 << 21; | |
| 593 | − if (vs_pol_inv) | |
| 594 | − l &= ~(1 << 20); | |
| 595 | − else | |
| 596 | − l |= 1 << 20; | |
| 597 | − | |
| 598 | − return 0; | |
| 599 | −} | |
| 600 | − | |
| 601 | −/* xxx FIX module selection missing */ | |
| 602 | −static int rfbi_enable_te(bool enable, unsigned line) | |
| 603 | −{ | |
| 604 | − u32 l; | |
| 605 | − | |
| 606 | − DSSDBG("te %d line %d mode %d\n", enable, line, rfbi.te_mode); | |
| 607 | − if (line > (1 << 11) - 1) | |
| 608 | − return -EINVAL; | |
| 609 | − | |
| 610 | − l = rfbi_read_reg(RFBI_CONFIG(0)); | |
| 611 | − l &= ~(0x3 << 2); | |
| 612 | − if (enable) { | |
| 613 | − rfbi.te_enabled = 1; | |
| 614 | − l |= rfbi.te_mode << 2; | |
| 615 | − } else | |
| 616 | − rfbi.te_enabled = 0; | |
| 617 | − rfbi_write_reg(RFBI_CONFIG(0), l); | |
| 618 | − rfbi_write_reg(RFBI_LINE_NUMBER, line); | |
| 619 | − | |
| 620 | − return 0; | |
| 621 | −} | |
| 622 | − | |
| 623 | −static int rfbi_configure_bus(int rfbi_module, int bpp, int lines) | |
| 624 | −{ | |
| 625 | − u32 l; | |
| 626 | − int cycle1 = 0, cycle2 = 0, cycle3 = 0; | |
| 627 | − enum omap_rfbi_cycleformat cycleformat; | |
| 628 | − enum omap_rfbi_datatype datatype; | |
| 629 | − enum omap_rfbi_parallelmode parallelmode; | |
| 630 | − | |
| 631 | − switch (bpp) { | |
| 632 | − case 12: | |
| 633 | − datatype = OMAP_DSS_RFBI_DATATYPE_12; | |
| 634 | − break; | |
| 635 | − case 16: | |
| 636 | − datatype = OMAP_DSS_RFBI_DATATYPE_16; | |
| 637 | − break; | |
| 638 | − case 18: | |
| 639 | − datatype = OMAP_DSS_RFBI_DATATYPE_18; | |
| 640 | − break; | |
| 641 | − case 24: | |
| 642 | − datatype = OMAP_DSS_RFBI_DATATYPE_24; | |
| 643 | − break; | |
| 644 | − default: | |
| 645 | − BUG(); | |
| 646 | − return 1; | |
| 647 | − } | |
| 648 | − rfbi.datatype = datatype; | |
| 649 | − | |
| 650 | − switch (lines) { | |
| 651 | − case 8: | |
| 652 | − parallelmode = OMAP_DSS_RFBI_PARALLELMODE_8; | |
| 653 | − break; | |
| 654 | − case 9: | |
| 655 | − parallelmode = OMAP_DSS_RFBI_PARALLELMODE_9; | |
| 656 | − break; | |
| 657 | − case 12: | |
| 658 | − parallelmode = OMAP_DSS_RFBI_PARALLELMODE_12; | |
| 659 | − break; | |
| 660 | − case 16: | |
| 661 | − parallelmode = OMAP_DSS_RFBI_PARALLELMODE_16; | |
| 662 | − break; | |
| 663 | − default: | |
| 664 | − BUG(); | |
| 665 | − return 1; | |
| 666 | − } | |
| 667 | − rfbi.parallelmode = parallelmode; | |
| 668 | − | |
| 669 | − if ((bpp % lines) == 0) { | |
| 670 | − switch (bpp / lines) { | |
| 671 | − case 1: | |
| 672 | − cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_1_1; | |
| 673 | − break; | |
| 674 | − case 2: | |
| 675 | − cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_2_1; | |
| 676 | − break; | |
| 677 | − case 3: | |
| 678 | − cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_3_1; | |
| 679 | − break; | |
| 680 | − default: | |
| 681 | − BUG(); | |
| 682 | − return 1; | |
| 683 | − } | |
| 684 | − } else if ((2 * bpp % lines) == 0) { | |
| 685 | − if ((2 * bpp / lines) == 3) | |
| 686 | − cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_3_2; | |
| 687 | − else { | |
| 688 | − BUG(); | |
| 689 | − return 1; | |
| 690 | − } | |
| 691 | − } else { | |
| 692 | − BUG(); | |
| 693 | − return 1; | |
| 694 | − } | |
| 695 | − | |
| 696 | − switch (cycleformat) { | |
| 697 | − case OMAP_DSS_RFBI_CYCLEFORMAT_1_1: | |
| 698 | − cycle1 = lines; | |
| 699 | − break; | |
| 700 | − | |
| 701 | − case OMAP_DSS_RFBI_CYCLEFORMAT_2_1: | |
| 702 | − cycle1 = lines; | |
| 703 | − cycle2 = lines; | |
| 704 | − break; | |
| 705 | − | |
| 706 | − case OMAP_DSS_RFBI_CYCLEFORMAT_3_1: | |
| 707 | − cycle1 = lines; | |
| 708 | − cycle2 = lines; | |
| 709 | − cycle3 = lines; | |
| 710 | − break; | |
| 711 | − | |
| 712 | − case OMAP_DSS_RFBI_CYCLEFORMAT_3_2: | |
| 713 | − cycle1 = lines; | |
| 714 | − cycle2 = (lines / 2) | ((lines / 2) << 16); | |
| 715 | − cycle3 = (lines << 16); | |
| 716 | − break; | |
| 717 | − } | |
| 718 | − | |
| 719 | − REG_FLD_MOD(RFBI_CONTROL, 0, 3, 2); /* clear CS */ | |
| 720 | − | |
| 721 | − l = 0; | |
| 722 | − l |= FLD_VAL(parallelmode, 1, 0); | |
| 723 | − l |= FLD_VAL(0, 3, 2); /* TRIGGERMODE: ITE */ | |
| 724 | − l |= FLD_VAL(0, 4, 4); /* TIMEGRANULARITY */ | |
| 725 | − l |= FLD_VAL(datatype, 6, 5); | |
| 726 | − /* l |= FLD_VAL(2, 8, 7); */ /* L4FORMAT, 2pix/L4 */ | |
| 727 | − l |= FLD_VAL(0, 8, 7); /* L4FORMAT, 1pix/L4 */ | |
| 728 | − l |= FLD_VAL(cycleformat, 10, 9); | |
| 729 | − l |= FLD_VAL(0, 12, 11); /* UNUSEDBITS */ | |
| 730 | − l |= FLD_VAL(0, 16, 16); /* A0POLARITY */ | |
| 731 | − l |= FLD_VAL(0, 17, 17); /* REPOLARITY */ | |
| 732 | − l |= FLD_VAL(0, 18, 18); /* WEPOLARITY */ | |
| 733 | − l |= FLD_VAL(0, 19, 19); /* CSPOLARITY */ | |
| 734 | − l |= FLD_VAL(1, 20, 20); /* TE_VSYNC_POLARITY */ | |
| 735 | − l |= FLD_VAL(1, 21, 21); /* HSYNCPOLARITY */ | |
| 736 | − rfbi_write_reg(RFBI_CONFIG(rfbi_module), l); | |
| 737 | − | |
| 738 | − rfbi_write_reg(RFBI_DATA_CYCLE1(rfbi_module), cycle1); | |
| 739 | − rfbi_write_reg(RFBI_DATA_CYCLE2(rfbi_module), cycle2); | |
| 740 | − rfbi_write_reg(RFBI_DATA_CYCLE3(rfbi_module), cycle3); | |
| 741 | − | |
| 742 | − | |
| 743 | − l = rfbi_read_reg(RFBI_CONTROL); | |
| 744 | − l = FLD_MOD(l, rfbi_module+1, 3, 2); /* Select CSx */ | |
| 745 | − l = FLD_MOD(l, 0, 1, 1); /* clear bypass */ | |
| 746 | − rfbi_write_reg(RFBI_CONTROL, l); | |
| 747 | − | |
| 748 | − | |
| 749 | − DSSDBG("RFBI config: bpp %d, lines %d, cycles: 0x%x 0x%x 0x%x\n", | |
| 750 | − bpp, lines, cycle1, cycle2, cycle3); | |
| 751 | − | |
| 752 | − return 0; | |
| 753 | −} | |
| 754 | − | |
| 755 | −static int rfbi_configure(struct omap_dss_device *dssdev) | |
| 756 | −{ | |
| 757 | − return rfbi_configure_bus(dssdev->phy.rfbi.channel, rfbi.pixel_size, | |
| 758 | − rfbi.data_lines); | |
| 759 | −} | |
| 760 | − | |
| 761 | −static int rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *), | |
| 762 | − void *data) | |
| 763 | −{ | |
| 764 | − return rfbi_transfer_area(dssdev, callback, data); | |
| 765 | −} | |
| 766 | − | |
| 767 | −static void rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h) | |
| 768 | −{ | |
| 769 | − rfbi.timings.x_res = w; | |
| 770 | − rfbi.timings.y_res = h; | |
| 771 | −} | |
| 772 | − | |
| 773 | −static void rfbi_set_pixel_size(struct omap_dss_device *dssdev, int pixel_size) | |
| 774 | −{ | |
| 775 | − rfbi.pixel_size = pixel_size; | |
| 776 | −} | |
| 777 | − | |
| 778 | −static void rfbi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) | |
| 779 | −{ | |
| 780 | − rfbi.data_lines = data_lines; | |
| 781 | −} | |
| 782 | − | |
| 783 | −static void rfbi_set_interface_timings(struct omap_dss_device *dssdev, | |
| 784 | − struct rfbi_timings *timings) | |
| 785 | −{ | |
| 786 | − rfbi.intf_timings = *timings; | |
| 787 | −} | |
| 788 | − | |
| 789 | −static void rfbi_dump_regs(struct seq_file *s) | |
| 790 | −{ | |
| 791 | −#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r)) | |
| 792 | − | |
| 793 | − if (rfbi_runtime_get()) | |
| 794 | − return; | |
| 795 | − | |
| 796 | − DUMPREG(RFBI_REVISION); | |
| 797 | − DUMPREG(RFBI_SYSCONFIG); | |
| 798 | − DUMPREG(RFBI_SYSSTATUS); | |
| 799 | − DUMPREG(RFBI_CONTROL); | |
| 800 | − DUMPREG(RFBI_PIXEL_CNT); | |
| 801 | − DUMPREG(RFBI_LINE_NUMBER); | |
| 802 | − DUMPREG(RFBI_CMD); | |
| 803 | − DUMPREG(RFBI_PARAM); | |
| 804 | − DUMPREG(RFBI_DATA); | |
| 805 | − DUMPREG(RFBI_READ); | |
| 806 | − DUMPREG(RFBI_STATUS); | |
| 807 | − | |
| 808 | − DUMPREG(RFBI_CONFIG(0)); | |
| 809 | − DUMPREG(RFBI_ONOFF_TIME(0)); | |
| 810 | − DUMPREG(RFBI_CYCLE_TIME(0)); | |
| 811 | − DUMPREG(RFBI_DATA_CYCLE1(0)); | |
| 812 | − DUMPREG(RFBI_DATA_CYCLE2(0)); | |
| 813 | − DUMPREG(RFBI_DATA_CYCLE3(0)); | |
| 814 | − | |
| 815 | − DUMPREG(RFBI_CONFIG(1)); | |
| 816 | − DUMPREG(RFBI_ONOFF_TIME(1)); | |
| 817 | − DUMPREG(RFBI_CYCLE_TIME(1)); | |
| 818 | − DUMPREG(RFBI_DATA_CYCLE1(1)); | |
| 819 | − DUMPREG(RFBI_DATA_CYCLE2(1)); | |
| 820 | − DUMPREG(RFBI_DATA_CYCLE3(1)); | |
| 821 | − | |
| 822 | − DUMPREG(RFBI_VSYNC_WIDTH); | |
| 823 | − DUMPREG(RFBI_HSYNC_WIDTH); | |
| 824 | − | |
| 825 | − rfbi_runtime_put(); | |
| 826 | −#undef DUMPREG | |
| 827 | −} | |
| 828 | − | |
| 829 | −static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev) | |
| 830 | −{ | |
| 831 | − struct omap_overlay_manager *mgr = rfbi.output.manager; | |
| 832 | − struct dss_lcd_mgr_config mgr_config; | |
| 833 | − | |
| 834 | − mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI; | |
| 835 | − | |
| 836 | − mgr_config.stallmode = true; | |
| 837 | − /* Do we need fifohandcheck for RFBI? */ | |
| 838 | − mgr_config.fifohandcheck = false; | |
| 839 | − | |
| 840 | − mgr_config.video_port_width = rfbi.pixel_size; | |
| 841 | − mgr_config.lcden_sig_polarity = 0; | |
| 842 | − | |
| 843 | − dss_mgr_set_lcd_config(mgr, &mgr_config); | |
| 844 | − | |
| 845 | − /* | |
| 846 | − * Set rfbi.timings with default values, the x_res and y_res fields | |
| 847 | − * are expected to be already configured by the panel driver via | |
| 848 | − * omapdss_rfbi_set_size() | |
| 849 | − */ | |
| 850 | − rfbi.timings.hsw = 1; | |
| 851 | − rfbi.timings.hfp = 1; | |
| 852 | − rfbi.timings.hbp = 1; | |
| 853 | − rfbi.timings.vsw = 1; | |
| 854 | − rfbi.timings.vfp = 0; | |
| 855 | − rfbi.timings.vbp = 0; | |
| 856 | − | |
| 857 | − rfbi.timings.interlace = false; | |
| 858 | − rfbi.timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH; | |
| 859 | − rfbi.timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH; | |
| 860 | − rfbi.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; | |
| 861 | − rfbi.timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH; | |
| 862 | − rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE; | |
| 863 | − | |
| 864 | − dss_mgr_set_timings(mgr, &rfbi.timings); | |
| 865 | −} | |
| 866 | − | |
| 867 | −static int rfbi_display_enable(struct omap_dss_device *dssdev) | |
| 868 | −{ | |
| 869 | − struct omap_dss_device *out = &rfbi.output; | |
| 870 | − int r; | |
| 871 | − | |
| 872 | − if (out->manager == NULL) { | |
| 873 | − DSSERR("failed to enable display: no output/manager\n"); | |
| 874 | − return -ENODEV; | |
| 875 | − } | |
| 876 | − | |
| 877 | − r = rfbi_runtime_get(); | |
| 878 | − if (r) | |
| 879 | − return r; | |
| 880 | − | |
| 881 | − r = dss_mgr_register_framedone_handler(out->manager, | |
| 882 | − framedone_callback, NULL); | |
| 883 | − if (r) { | |
| 884 | − DSSERR("can't get FRAMEDONE irq\n"); | |
| 885 | − goto err1; | |
| 886 | − } | |
| 887 | − | |
| 888 | − rfbi_config_lcd_manager(dssdev); | |
| 889 | − | |
| 890 | − rfbi_configure_bus(dssdev->phy.rfbi.channel, rfbi.pixel_size, | |
| 891 | − rfbi.data_lines); | |
| 892 | − | |
| 893 | − rfbi_set_timings(dssdev->phy.rfbi.channel, &rfbi.intf_timings); | |
| 894 | − | |
| 895 | − return 0; | |
| 896 | −err1: | |
| 897 | − rfbi_runtime_put(); | |
| 898 | − return r; | |
| 899 | −} | |
| 900 | − | |
| 901 | −static void rfbi_display_disable(struct omap_dss_device *dssdev) | |
| 902 | −{ | |
| 903 | − struct omap_dss_device *out = &rfbi.output; | |
| 904 | − | |
| 905 | − dss_mgr_unregister_framedone_handler(out->manager, | |
| 906 | − framedone_callback, NULL); | |
| 907 | − | |
| 908 | − rfbi_runtime_put(); | |
| 909 | −} | |
| 910 | − | |
| 911 | −static int rfbi_init_display(struct omap_dss_device *dssdev) | |
| 912 | −{ | |
| 913 | − rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev; | |
| 914 | − return 0; | |
| 915 | −} | |
| 916 | − | |
| 917 | −static void rfbi_init_output(struct platform_device *pdev) | |
| 918 | −{ | |
| 919 | − struct omap_dss_device *out = &rfbi.output; | |
| 920 | − | |
| 921 | − out->dev = &pdev->dev; | |
| 922 | − out->id = OMAP_DSS_OUTPUT_DBI; | |
| 923 | − out->output_type = OMAP_DISPLAY_TYPE_DBI; | |
| 924 | − out->name = "rfbi.0"; | |
| 925 | − out->dispc_channel = OMAP_DSS_CHANNEL_LCD; | |
| 926 | − out->owner = THIS_MODULE; | |
| 927 | − | |
| 928 | − omapdss_register_output(out); | |
| 929 | −} | |
| 930 | − | |
| 931 | −static void rfbi_uninit_output(struct platform_device *pdev) | |
| 932 | −{ | |
| 933 | − struct omap_dss_device *out = &rfbi.output; | |
| 934 | − | |
| 935 | − omapdss_unregister_output(out); | |
| 936 | −} | |
| 937 | − | |
| 938 | −/* RFBI HW IP initialisation */ | |
| 939 | −static int rfbi_bind(struct device *dev, struct device *master, void *data) | |
| 940 | −{ | |
| 941 | − struct platform_device *pdev = to_platform_device(dev); | |
| 942 | − u32 rev; | |
| 943 | − struct resource *rfbi_mem; | |
| 944 | − struct clk *clk; | |
| 945 | − int r; | |
| 946 | − | |
| 947 | − rfbi.pdev = pdev; | |
| 948 | − | |
| 949 | − sema_init(&rfbi.bus_lock, 1); | |
| 950 | − | |
| 951 | − rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0); | |
| 952 | − if (!rfbi_mem) { | |
| 953 | − DSSERR("can't get IORESOURCE_MEM RFBI\n"); | |
| 954 | − return -EINVAL; | |
| 955 | − } | |
| 956 | − | |
| 957 | − rfbi.base = devm_ioremap(&pdev->dev, rfbi_mem->start, | |
| 958 | − resource_size(rfbi_mem)); | |
| 959 | − if (!rfbi.base) { | |
| 960 | − DSSERR("can't ioremap RFBI\n"); | |
| 961 | − return -ENOMEM; | |
| 962 | − } | |
| 963 | − | |
| 964 | − clk = clk_get(&pdev->dev, "ick"); | |
| 965 | − if (IS_ERR(clk)) { | |
| 966 | − DSSERR("can't get ick\n"); | |
| 967 | − return PTR_ERR(clk); | |
| 968 | − } | |
| 969 | − | |
| 970 | − rfbi.l4_khz = clk_get_rate(clk) / 1000; | |
| 971 | − | |
| 972 | − clk_put(clk); | |
| 973 | − | |
| 974 | − pm_runtime_enable(&pdev->dev); | |
| 975 | − | |
| 976 | − r = rfbi_runtime_get(); | |
| 977 | − if (r) | |
| 978 | − goto err_runtime_get; | |
| 979 | − | |
| 980 | − msleep(10); | |
| 981 | − | |
| 982 | − rev = rfbi_read_reg(RFBI_REVISION); | |
| 983 | − dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n", | |
| 984 | − FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); | |
| 985 | − | |
| 986 | − rfbi_runtime_put(); | |
| 987 | − | |
| 988 | − dss_debugfs_create_file("rfbi", rfbi_dump_regs); | |
| 989 | − | |
| 990 | − rfbi_init_output(pdev); | |
| 991 | − | |
| 992 | − return 0; | |
| 993 | − | |
| 994 | −err_runtime_get: | |
| 995 | − pm_runtime_disable(&pdev->dev); | |
| 996 | − return r; | |
| 997 | −} | |
| 998 | − | |
| 999 | −static void rfbi_unbind(struct device *dev, struct device *master, void *data) | |
| 1000 | −{ | |
| 1001 | − struct platform_device *pdev = to_platform_device(dev); | |
| 1002 | − | |
| 1003 | − rfbi_uninit_output(pdev); | |
| 1004 | − | |
| 1005 | − pm_runtime_disable(&pdev->dev); | |
| 1006 | − | |
| 1007 | − return 0; | |
| 1008 | −} | |
| 1009 | − | |
| 1010 | −static const struct component_ops rfbi_component_ops = { | |
| 1011 | − .bind = rfbi_bind, | |
| 1012 | − .unbind = rfbi_unbind, | |
| 1013 | −}; | |
| 1014 | − | |
| 1015 | −static int rfbi_probe(struct platform_device *pdev) | |
| 1016 | −{ | |
| 1017 | − return component_add(&pdev->dev, &rfbi_component_ops); | |
| 1018 | −} | |
| 1019 | − | |
| 1020 | −static int rfbi_remove(struct platform_device *pdev) | |
| 1021 | −{ | |
| 1022 | − component_del(&pdev->dev, &rfbi_component_ops); | |
| 1023 | − return 0; | |
| 1024 | −} | |
| 1025 | − | |
| 1026 | −static int rfbi_runtime_suspend(struct device *dev) | |
| 1027 | −{ | |
| 1028 | − dispc_runtime_put(); | |
| 1029 | − | |
| 1030 | − return 0; | |
| 1031 | −} | |
| 1032 | − | |
| 1033 | −static int rfbi_runtime_resume(struct device *dev) | |
| 1034 | −{ | |
| 1035 | − int r; | |
| 1036 | − | |
| 1037 | − r = dispc_runtime_get(); | |
| 1038 | − if (r < 0) | |
| 1039 | − return r; | |
| 1040 | − | |
| 1041 | − return 0; | |
| 1042 | −} | |
| 1043 | − | |
| 1044 | −static const struct dev_pm_ops rfbi_pm_ops = { | |
| 1045 | − .runtime_suspend = rfbi_runtime_suspend, | |
| 1046 | − .runtime_resume = rfbi_runtime_resume, | |
| 1047 | −}; | |
| 1048 | − | |
| 1049 | −static struct platform_driver omap_rfbihw_driver = { | |
| 1050 | − .probe = rfbi_probe, | |
| 1051 | − .remove = rfbi_remove, | |
| 1052 | − .driver = { | |
| 1053 | − .name = "omapdss_rfbi", | |
| 1054 | − .pm = &rfbi_pm_ops, | |
| 1055 | − .suppress_bind_attrs = true, | |
| 1056 | − }, | |
| 1057 | −}; | |
| 1058 | − | |
| 1059 | −int __init rfbi_init_platform_driver(void) | |
| 1060 | −{ | |
| 1061 | − return platform_driver_register(&omap_rfbihw_driver); | |
| 1062 | −} | |
| 1063 | − | |
| 1064 | −void rfbi_uninit_platform_driver(void) | |
| 1065 | −{ | |
| 1066 | − platform_driver_unregister(&omap_rfbihw_driver); | |
| 1067 | −} | |
| @@ -1881,12 +1881,8 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) · 1880 unmodified lines | ||
| 1881 | 1881 | |
| 1882 | 1882 | fbi = framebuffer_alloc(sizeof(struct omapfb_info), |
| 1883 | 1883 | fbdev->dev); |
| 1884 | − | |
| 1885 | − if (fbi == NULL) { | |
| 1886 | − dev_err(fbdev->dev, | |
| 1887 | − "unable to allocate memory for plane info\n"); | |
| 1884 | + if (!fbi) | |
| 1888 | 1885 | return -ENOMEM; |
| 1889 | − } | |
| 1890 | 1886 | |
| 1891 | 1887 | clear_fb_info(fbi); |
| 1892 | 1888 | |
| @@ -49,8 +49,7 @@ static ssize_t store_rotate_type(struct device *dev, · 48 unmodified lines | ||
| 49 | 49 | if (rot_type != OMAP_DSS_ROT_DMA && rot_type != OMAP_DSS_ROT_VRFB) |
| 50 | 50 | return -EINVAL; |
| 51 | 51 | |
| 52 | − if (!lock_fb_info(fbi)) | |
| 53 | − return -ENODEV; | |
| 52 | + lock_fb_info(fbi); | |
| 54 | 53 | |
| 55 | 54 | r = 0; |
| 56 | 55 | if (rot_type == ofbi->rotation_type) |
| @@ -101,8 +100,7 @@ static ssize_t store_mirror(struct device *dev, · 44 unmodified lines | ||
| 101 | 100 | if (r) |
| 102 | 101 | return r; |
| 103 | 102 | |
| 104 | − if (!lock_fb_info(fbi)) | |
| 105 | − return -ENODEV; | |
| 103 | + lock_fb_info(fbi); | |
| 106 | 104 | |
| 107 | 105 | ofbi->mirror = mirror; |
| 108 | 106 | |
| @@ -138,8 +136,7 @@ static ssize_t show_overlays(struct device *dev, · 29 unmodified lines | ||
| 138 | 136 | ssize_t l = 0; |
| 139 | 137 | int t; |
| 140 | 138 | |
| 141 | − if (!lock_fb_info(fbi)) | |
| 142 | − return -ENODEV; | |
| 139 | + lock_fb_info(fbi); | |
| 143 | 140 | omapfb_lock(fbdev); |
| 144 | 141 | |
| 145 | 142 | for (t = 0; t < ofbi->num_overlays; t++) { |
| @@ -197,8 +194,7 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr, · 51 unmodified lines | ||
| 197 | 194 | if (buf[len - 1] == '\n') |
| 198 | 195 | len = len - 1; |
| 199 | 196 | |
| 200 | − if (!lock_fb_info(fbi)) | |
| 201 | − return -ENODEV; | |
| 197 | + lock_fb_info(fbi); | |
| 202 | 198 | omapfb_lock(fbdev); |
| 203 | 199 | |
| 204 | 200 | if (len > 0) { |
| @@ -329,8 +325,7 @@ static ssize_t show_overlays_rotate(struct device *dev, · 124 unmodified lines | ||
| 329 | 325 | ssize_t l = 0; |
| 330 | 326 | int t; |
| 331 | 327 | |
| 332 | − if (!lock_fb_info(fbi)) | |
| 333 | − return -ENODEV; | |
| 328 | + lock_fb_info(fbi); | |
| 334 | 329 | |
| 335 | 330 | for (t = 0; t < ofbi->num_overlays; t++) { |
| 336 | 331 | l += snprintf(buf + l, PAGE_SIZE - l, "%s%d", |
| @@ -358,8 +353,7 @@ static ssize_t store_overlays_rotate(struct device *dev, · 21 unmodified lines | ||
| 358 | 353 | if (buf[len - 1] == '\n') |
| 359 | 354 | len = len - 1; |
| 360 | 355 | |
| 361 | − if (!lock_fb_info(fbi)) | |
| 362 | − return -ENODEV; | |
| 356 | + lock_fb_info(fbi); | |
| 363 | 357 | |
| 364 | 358 | if (len > 0) { |
| 365 | 359 | char *p = (char *)buf; |
| @@ -442,8 +436,7 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr, · 76 unmodified lines | ||
| 442 | 436 | |
| 443 | 437 | size = PAGE_ALIGN(size); |
| 444 | 438 | |
| 445 | − if (!lock_fb_info(fbi)) | |
| 446 | − return -ENODEV; | |
| 439 | + lock_fb_info(fbi); | |
| 447 | 440 | |
| 448 | 441 | if (display && display->driver->sync) |
| 449 | 442 | display->driver->sync(display); |
| @@ -538,10 +538,9 @@ static int platinumfb_probe(struct platform_device* odev) · 537 unmodified lines | ||
| 538 | 538 | dev_info(&odev->dev, "Found Apple Platinum video hardware\n"); |
| 539 | 539 | |
| 540 | 540 | info = framebuffer_alloc(sizeof(*pinfo), &odev->dev); |
| 541 | − if (info == NULL) { | |
| 542 | − dev_err(&odev->dev, "Failed to allocate fbdev !\n"); | |
| 541 | + if (!info) | |
| 543 | 542 | return -ENOMEM; |
| 544 | − } | |
| 543 | + | |
| 545 | 544 | pinfo = info->par; |
| 546 | 545 | |
| 547 | 546 | if (of_address_to_resource(dp, 0, &pinfo->rsrc_reg) || |
| @@ -165,10 +165,8 @@ static int pmagaafb_probe(struct device *dev) · 164 unmodified lines | ||
| 165 | 165 | int err; |
| 166 | 166 | |
| 167 | 167 | info = framebuffer_alloc(sizeof(struct aafb_par), dev); |
| 168 | − if (!info) { | |
| 169 | − printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev)); | |
| 168 | + if (!info) | |
| 170 | 169 | return -ENOMEM; |
| 171 | − } | |
| 172 | 170 | |
| 173 | 171 | par = info->par; |
| 174 | 172 | dev_set_drvdata(dev, info); |
| @@ -150,10 +150,8 @@ static int pmagbafb_probe(struct device *dev) · 149 unmodified lines | ||
| 150 | 150 | int err; |
| 151 | 151 | |
| 152 | 152 | info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev); |
| 153 | − if (!info) { | |
| 154 | − printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev)); | |
| 153 | + if (!info) | |
| 155 | 154 | return -ENOMEM; |
| 156 | − } | |
| 157 | 155 | |
| 158 | 156 | par = info->par; |
| 159 | 157 | dev_set_drvdata(dev, info); |
| @@ -257,10 +257,8 @@ static int pmagbbfb_probe(struct device *dev) · 256 unmodified lines | ||
| 257 | 257 | int err; |
| 258 | 258 | |
| 259 | 259 | info = framebuffer_alloc(sizeof(struct pmagbbfb_par), dev); |
| 260 | − if (!info) { | |
| 261 | − printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev)); | |
| 260 | + if (!info) | |
| 262 | 261 | return -ENOMEM; |
| 263 | − } | |
| 264 | 262 | |
| 265 | 263 | par = info->par; |
| 266 | 264 | dev_set_drvdata(dev, info); |
| @@ -140,7 +140,7 @@ static struct pvr2fb_par { · 139 unmodified lines | ||
| 140 | 140 | unsigned char is_doublescan; /* Are scanlines output twice? (doublescan) */ |
| 141 | 141 | unsigned char is_lowres; /* Is horizontal pixel-doubling enabled? */ |
| 142 | 142 | |
| 143 | − unsigned long mmio_base; /* MMIO base */ | |
| 143 | + void __iomem *mmio_base; /* MMIO base */ | |
| 144 | 144 | u32 palette[16]; |
| 145 | 145 | } *currentpar; |
| 146 | 146 | |
| @@ -194,39 +194,6 @@ static unsigned int shdma = PVR2_CASCADE_CHAN; · 47 unmodified lines | ||
| 194 | 194 | static unsigned int pvr2dma = ONCHIP_NR_DMA_CHANNELS; |
| 195 | 195 | #endif |
| 196 | 196 | |
| 197 | −static int pvr2fb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue, | |
| 198 | − unsigned int transp, struct fb_info *info); | |
| 199 | −static int pvr2fb_blank(int blank, struct fb_info *info); | |
| 200 | −static unsigned long get_line_length(int xres_virtual, int bpp); | |
| 201 | −static void set_color_bitfields(struct fb_var_screeninfo *var); | |
| 202 | −static int pvr2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info); | |
| 203 | −static int pvr2fb_set_par(struct fb_info *info); | |
| 204 | −static void pvr2_update_display(struct fb_info *info); | |
| 205 | −static void pvr2_init_display(struct fb_info *info); | |
| 206 | −static void pvr2_do_blank(void); | |
| 207 | −static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id); | |
| 208 | −static int pvr2_init_cable(void); | |
| 209 | −static int pvr2_get_param(const struct pvr2_params *p, const char *s, | |
| 210 | − int val, int size); | |
| 211 | −#ifdef CONFIG_PVR2_DMA | |
| 212 | −static ssize_t pvr2fb_write(struct fb_info *info, const char *buf, | |
| 213 | − size_t count, loff_t *ppos); | |
| 214 | −#endif | |
| 215 | − | |
| 216 | −static struct fb_ops pvr2fb_ops = { | |
| 217 | − .owner = THIS_MODULE, | |
| 218 | − .fb_setcolreg = pvr2fb_setcolreg, | |
| 219 | − .fb_blank = pvr2fb_blank, | |
| 220 | − .fb_check_var = pvr2fb_check_var, | |
| 221 | − .fb_set_par = pvr2fb_set_par, | |
| 222 | −#ifdef CONFIG_PVR2_DMA | |
| 223 | − .fb_write = pvr2fb_write, | |
| 224 | −#endif | |
| 225 | − .fb_fillrect = cfb_fillrect, | |
| 226 | − .fb_copyarea = cfb_copyarea, | |
| 227 | − .fb_imageblit = cfb_imageblit, | |
| 228 | −}; | |
| 229 | − | |
| 230 | 197 | static struct fb_videomode pvr2_modedb[] = { |
| 231 | 198 | /* |
| 232 | 199 | * Broadcast video modes (PAL and NTSC). I'm unfamiliar with |
| @@ -354,6 +321,36 @@ static int pvr2fb_setcolreg(unsigned int regno, unsigned int red, · 121 unmodified lines | ||
| 354 | 321 | return 0; |
| 355 | 322 | } |
| 356 | 323 | |
| 324 | +/* | |
| 325 | + * Determine the cable type and initialize the cable output format. Don't do | |
| 326 | + * anything if the cable type has been overidden (via "cable:XX"). | |
| 327 | + */ | |
| 328 | + | |
| 329 | +#define PCTRA ((void __iomem *)0xff80002c) | |
| 330 | +#define PDTRA ((void __iomem *)0xff800030) | |
| 331 | +#define VOUTC ((void __iomem *)0xa0702c00) | |
| 332 | + | |
| 333 | +static int pvr2_init_cable(void) | |
| 334 | +{ | |
| 335 | + if (cable_type < 0) { | |
| 336 | + fb_writel((fb_readl(PCTRA) & 0xfff0ffff) | 0x000a0000, | |
| 337 | + PCTRA); | |
| 338 | + cable_type = (fb_readw(PDTRA) >> 8) & 3; | |
| 339 | + } | |
| 340 | + | |
| 341 | + /* Now select the output format (either composite or other) */ | |
| 342 | + /* XXX: Save the previous val first, as this reg is also AICA | |
| 343 | + related */ | |
| 344 | + if (cable_type == CT_COMPOSITE) | |
| 345 | + fb_writel(3 << 8, VOUTC); | |
| 346 | + else if (cable_type == CT_RGB) | |
| 347 | + fb_writel(1 << 9, VOUTC); | |
| 348 | + else | |
| 349 | + fb_writel(0, VOUTC); | |
| 350 | + | |
| 351 | + return cable_type; | |
| 352 | +} | |
| 353 | + | |
| 357 | 354 | static int pvr2fb_set_par(struct fb_info *info) |
| 358 | 355 | { |
| 359 | 356 | struct pvr2fb_par *par = (struct pvr2fb_par *)info->par; |
| @@ -623,7 +620,7 @@ static void pvr2_do_blank(void) · 263 unmodified lines | ||
| 623 | 620 | is_blanked = do_blank > 0 ? do_blank : 0; |
| 624 | 621 | } |
| 625 | 622 | |
| 626 | −static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id) | |
| 623 | +static irqreturn_t __maybe_unused pvr2fb_interrupt(int irq, void *dev_id) | |
| 627 | 624 | { |
| 628 | 625 | struct fb_info *info = dev_id; |
| 629 | 626 | |
| @@ -642,36 +639,6 @@ static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id) · 12 unmodified lines | ||
| 642 | 639 | return IRQ_HANDLED; |
| 643 | 640 | } |
| 644 | 641 | |
| 645 | −/* | |
| 646 | − * Determine the cable type and initialize the cable output format. Don't do | |
| 647 | − * anything if the cable type has been overidden (via "cable:XX"). | |
| 648 | − */ | |
| 649 | − | |
| 650 | −#define PCTRA 0xff80002c | |
| 651 | −#define PDTRA 0xff800030 | |
| 652 | −#define VOUTC 0xa0702c00 | |
| 653 | − | |
| 654 | −static int pvr2_init_cable(void) | |
| 655 | −{ | |
| 656 | − if (cable_type < 0) { | |
| 657 | − fb_writel((fb_readl(PCTRA) & 0xfff0ffff) | 0x000a0000, | |
| 658 | − PCTRA); | |
| 659 | − cable_type = (fb_readw(PDTRA) >> 8) & 3; | |
| 660 | − } | |
| 661 | − | |
| 662 | − /* Now select the output format (either composite or other) */ | |
| 663 | − /* XXX: Save the previous val first, as this reg is also AICA | |
| 664 | − related */ | |
| 665 | − if (cable_type == CT_COMPOSITE) | |
| 666 | − fb_writel(3 << 8, VOUTC); | |
| 667 | − else if (cable_type == CT_RGB) | |
| 668 | − fb_writel(1 << 9, VOUTC); | |
| 669 | − else | |
| 670 | − fb_writel(0, VOUTC); | |
| 671 | − | |
| 672 | − return cable_type; | |
| 673 | −} | |
| 674 | − | |
| 675 | 642 | #ifdef CONFIG_PVR2_DMA |
| 676 | 643 | static ssize_t pvr2fb_write(struct fb_info *info, const char *buf, |
| 677 | 644 | size_t count, loff_t *ppos) |
| @@ -742,6 +709,46 @@ out_unmap: · 64 unmodified lines | ||
| 742 | 709 | } |
| 743 | 710 | #endif /* CONFIG_PVR2_DMA */ |
| 744 | 711 | |
| 712 | +static struct fb_ops pvr2fb_ops = { | |
| 713 | + .owner = THIS_MODULE, | |
| 714 | + .fb_setcolreg = pvr2fb_setcolreg, | |
| 715 | + .fb_blank = pvr2fb_blank, | |
| 716 | + .fb_check_var = pvr2fb_check_var, | |
| 717 | + .fb_set_par = pvr2fb_set_par, | |
| 718 | +#ifdef CONFIG_PVR2_DMA | |
| 719 | + .fb_write = pvr2fb_write, | |
| 720 | +#endif | |
| 721 | + .fb_fillrect = cfb_fillrect, | |
| 722 | + .fb_copyarea = cfb_copyarea, | |
| 723 | + .fb_imageblit = cfb_imageblit, | |
| 724 | +}; | |
| 725 | + | |
| 726 | +#ifndef MODULE | |
| 727 | +static int pvr2_get_param_val(const struct pvr2_params *p, const char *s, | |
| 728 | + int size) | |
| 729 | +{ | |
| 730 | + int i; | |
| 731 | + | |
| 732 | + for (i = 0; i < size; i++) { | |
| 733 | + if (!strncasecmp(p[i].name, s, strlen(s))) | |
| 734 | + return p[i].val; | |
| 735 | + } | |
| 736 | + return -1; | |
| 737 | +} | |
| 738 | +#endif | |
| 739 | + | |
| 740 | +static char *pvr2_get_param_name(const struct pvr2_params *p, int val, | |
| 741 | + int size) | |
| 742 | +{ | |
| 743 | + int i; | |
| 744 | + | |
| 745 | + for (i = 0; i < size; i++) { | |
| 746 | + if (p[i].val == val) | |
| 747 | + return p[i].name; | |
| 748 | + } | |
| 749 | + return NULL; | |
| 750 | +} | |
| 751 | + | |
| 745 | 752 | /** |
| 746 | 753 | * pvr2fb_common_init |
| 747 | 754 | * |
| @@ -760,7 +767,7 @@ out_unmap: · 12 unmodified lines | ||
| 760 | 767 | * in for flexibility anyways. Who knows, maybe someone has tv-out on a |
| 761 | 768 | * PCI-based version of these things ;-) |
| 762 | 769 | */ |
| 763 | −static int pvr2fb_common_init(void) | |
| 770 | +static int __maybe_unused pvr2fb_common_init(void) | |
| 764 | 771 | { |
| 765 | 772 | struct pvr2fb_par *par = currentpar; |
| 766 | 773 | unsigned long modememused, rev; |
| @@ -773,8 +780,8 @@ static int pvr2fb_common_init(void) · 6 unmodified lines | ||
| 773 | 780 | goto out_err; |
| 774 | 781 | } |
| 775 | 782 | |
| 776 | − par->mmio_base = (unsigned long)ioremap_nocache(pvr2_fix.mmio_start, | |
| 777 | − pvr2_fix.mmio_len); | |
| 783 | + par->mmio_base = ioremap_nocache(pvr2_fix.mmio_start, | |
| 784 | + pvr2_fix.mmio_len); | |
| 778 | 785 | if (!par->mmio_base) { |
| 779 | 786 | printk(KERN_ERR "pvr2fb: Failed to remap mmio space\n"); |
| 780 | 787 | goto out_err; |
| @@ -822,8 +829,8 @@ static int pvr2fb_common_init(void) · 41 unmodified lines | ||
| 822 | 829 | fb_info->var.xres, fb_info->var.yres, |
| 823 | 830 | fb_info->var.bits_per_pixel, |
| 824 | 831 | get_line_length(fb_info->var.xres, fb_info->var.bits_per_pixel), |
| 825 | − (char *)pvr2_get_param(cables, NULL, cable_type, 3), | |
| 826 | − (char *)pvr2_get_param(outputs, NULL, video_output, 3)); | |
| 832 | + pvr2_get_param_name(cables, cable_type, 3), | |
| 833 | + pvr2_get_param_name(outputs, video_output, 3)); | |
| 827 | 834 | |
| 828 | 835 | #ifdef CONFIG_SH_STORE_QUEUES |
| 829 | 836 | fb_notice(fb_info, "registering with SQ API\n"); |
| @@ -841,7 +848,7 @@ out_err: · 11 unmodified lines | ||
| 841 | 848 | if (fb_info->screen_base) |
| 842 | 849 | iounmap(fb_info->screen_base); |
| 843 | 850 | if (par->mmio_base) |
| 844 | − iounmap((void *)par->mmio_base); | |
| 851 | + iounmap(par->mmio_base); | |
| 845 | 852 | |
| 846 | 853 | return -ENXIO; |
| 847 | 854 | } |
| @@ -901,15 +908,15 @@ static int __init pvr2fb_dc_init(void) · 53 unmodified lines | ||
| 901 | 908 | return pvr2fb_common_init(); |
| 902 | 909 | } |
| 903 | 910 | |
| 904 | −static void __exit pvr2fb_dc_exit(void) | |
| 911 | +static void pvr2fb_dc_exit(void) | |
| 905 | 912 | { |
| 906 | 913 | if (fb_info->screen_base) { |
| 907 | 914 | iounmap(fb_info->screen_base); |
| 908 | 915 | fb_info->screen_base = NULL; |
| 909 | 916 | } |
| 910 | 917 | if (currentpar->mmio_base) { |
| 911 | − iounmap((void *)currentpar->mmio_base); | |
| 912 | − currentpar->mmio_base = 0; | |
| 918 | + iounmap(currentpar->mmio_base); | |
| 919 | + currentpar->mmio_base = NULL; | |
| 913 | 920 | } |
| 914 | 921 | |
| 915 | 922 | free_irq(HW_EVENT_VSYNC, fb_info); |
| @@ -958,8 +965,8 @@ static void pvr2fb_pci_remove(struct pci_dev *pdev) · 42 unmodified lines | ||
| 958 | 965 | fb_info->screen_base = NULL; |
| 959 | 966 | } |
| 960 | 967 | if (currentpar->mmio_base) { |
| 961 | − iounmap((void *)currentpar->mmio_base); | |
| 962 | − currentpar->mmio_base = 0; | |
| 968 | + iounmap(currentpar->mmio_base); | |
| 969 | + currentpar->mmio_base = NULL; | |
| 963 | 970 | } |
| 964 | 971 | |
| 965 | 972 | pci_release_regions(pdev); |
| @@ -985,29 +992,12 @@ static int __init pvr2fb_pci_init(void) · 19 unmodified lines | ||
| 985 | 992 | return pci_register_driver(&pvr2fb_pci_driver); |
| 986 | 993 | } |
| 987 | 994 | |
| 988 | −static void __exit pvr2fb_pci_exit(void) | |
| 995 | +static void pvr2fb_pci_exit(void) | |
| 989 | 996 | { |
| 990 | 997 | pci_unregister_driver(&pvr2fb_pci_driver); |
| 991 | 998 | } |
| 992 | 999 | #endif /* CONFIG_PCI */ |
| 993 | 1000 | |
| 994 | −static int pvr2_get_param(const struct pvr2_params *p, const char *s, int val, | |
| 995 | − int size) | |
| 996 | −{ | |
| 997 | − int i; | |
| 998 | − | |
| 999 | − for (i = 0 ; i < size ; i++ ) { | |
| 1000 | − if (s != NULL) { | |
| 1001 | − if (!strncasecmp(p[i].name, s, strlen(s))) | |
| 1002 | − return p[i].val; | |
| 1003 | − } else { | |
| 1004 | − if (p[i].val == val) | |
| 1005 | − return (int)p[i].name; | |
| 1006 | − } | |
| 1007 | − } | |
| 1008 | − return -1; | |
| 1009 | −} | |
| 1010 | − | |
| 1011 | 1001 | /* |
| 1012 | 1002 | * Parse command arguments. Supported arguments are: |
| 1013 | 1003 | * inverse Use inverse color maps |
| @@ -1047,9 +1037,9 @@ static int __init pvr2fb_setup(char *options) · 33 unmodified lines | ||
| 1047 | 1037 | } |
| 1048 | 1038 | |
| 1049 | 1039 | if (*cable_arg) |
| 1050 | − cable_type = pvr2_get_param(cables, cable_arg, 0, 3); | |
| 1040 | + cable_type = pvr2_get_param_val(cables, cable_arg, 3); | |
| 1051 | 1041 | if (*output_arg) |
| 1052 | − video_output = pvr2_get_param(outputs, output_arg, 0, 3); | |
| 1042 | + video_output = pvr2_get_param_val(outputs, output_arg, 3); | |
| 1053 | 1043 | |
| 1054 | 1044 | return 0; |
| 1055 | 1045 | } |
| @@ -1082,12 +1072,8 @@ static int __init pvr2fb_init(void) · 26 unmodified lines | ||
| 1082 | 1072 | #endif |
| 1083 | 1073 | |
| 1084 | 1074 | fb_info = framebuffer_alloc(sizeof(struct pvr2fb_par), NULL); |
| 1085 | − | |
| 1086 | − if (!fb_info) { | |
| 1087 | − printk(KERN_ERR "Failed to allocate memory for fb_info\n"); | |
| 1075 | + if (!fb_info) | |
| 1088 | 1076 | return -ENOMEM; |
| 1089 | − } | |
| 1090 | − | |
| 1091 | 1077 | |
| 1092 | 1078 | currentpar = fb_info->par; |
| 1093 | 1079 | |
| @@ -1902,7 +1902,6 @@ static int rivafb_probe(struct pci_dev *pd, const struct pci_device_id *ent) · 1901 unmodified lines | ||
| 1902 | 1902 | |
| 1903 | 1903 | info = framebuffer_alloc(sizeof(struct riva_par), &pd->dev); |
| 1904 | 1904 | if (!info) { |
| 1905 | − printk (KERN_ERR PFX "could not allocate memory\n"); | |
| 1906 | 1905 | ret = -ENOMEM; |
| 1907 | 1906 | goto err_ret; |
| 1908 | 1907 | } |
| @@ -284,7 +284,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var, · 283 unmodified lines | ||
| 284 | 284 | /* 666 with one bit alpha/transparency */ |
| 285 | 285 | var->transp.offset = 18; |
| 286 | 286 | var->transp.length = 1; |
| 287 | − /* drop through */ | |
| 287 | + /* fall through */ | |
| 288 | 288 | case 18: |
| 289 | 289 | var->bits_per_pixel = 32; |
| 290 | 290 | |
| @@ -312,7 +312,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var, · 21 unmodified lines | ||
| 312 | 312 | case 25: |
| 313 | 313 | var->transp.length = var->bits_per_pixel - 24; |
| 314 | 314 | var->transp.offset = 24; |
| 315 | − /* drop through */ | |
| 315 | + /* fall through */ | |
| 316 | 316 | case 24: |
| 317 | 317 | /* our 24bpp is unpacked, so 32bpp */ |
| 318 | 318 | var->bits_per_pixel = 32; |
| @@ -809,7 +809,7 @@ static int s3c_fb_blank(int blank_mode, struct fb_info *info) · 490 unmodified lines | ||
| 809 | 809 | case FB_BLANK_POWERDOWN: |
| 810 | 810 | wincon &= ~WINCONx_ENWIN; |
| 811 | 811 | sfb->enabled &= ~(1 << index); |
| 812 | − /* fall through to FB_BLANK_NORMAL */ | |
| 812 | + /* fall through - to FB_BLANK_NORMAL */ | |
| 813 | 813 | |
| 814 | 814 | case FB_BLANK_NORMAL: |
| 815 | 815 | /* disable the DMA and display 0x0 (black) */ |
| @@ -1102,14 +1102,14 @@ static int s3c_fb_alloc_memory(struct s3c_fb *sfb, struct s3c_fb_win *win) · 286 unmodified lines | ||
| 1102 | 1102 | |
| 1103 | 1103 | dev_dbg(sfb->dev, "want %u bytes for window\n", size); |
| 1104 | 1104 | |
| 1105 | − fbi->screen_base = dma_alloc_wc(sfb->dev, size, &map_dma, GFP_KERNEL); | |
| 1106 | − if (!fbi->screen_base) | |
| 1105 | + fbi->screen_buffer = dma_alloc_wc(sfb->dev, size, &map_dma, GFP_KERNEL); | |
| 1106 | + if (!fbi->screen_buffer) | |
| 1107 | 1107 | return -ENOMEM; |
| 1108 | 1108 | |
| 1109 | 1109 | dev_dbg(sfb->dev, "mapped %x to %p\n", |
| 1110 | − (unsigned int)map_dma, fbi->screen_base); | |
| 1110 | + (unsigned int)map_dma, fbi->screen_buffer); | |
| 1111 | 1111 | |
| 1112 | − memset(fbi->screen_base, 0x0, size); | |
| 1112 | + memset(fbi->screen_buffer, 0x0, size); | |
| 1113 | 1113 | fbi->fix.smem_start = map_dma; |
| 1114 | 1114 | |
| 1115 | 1115 | return 0; |
| @@ -1126,9 +1126,9 @@ static void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win) · 10 unmodified lines | ||
| 1126 | 1126 | { |
| 1127 | 1127 | struct fb_info *fbi = win->fbinfo; |
| 1128 | 1128 | |
| 1129 | − if (fbi->screen_base) | |
| 1129 | + if (fbi->screen_buffer) | |
| 1130 | 1130 | dma_free_wc(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len), |
| 1131 | − fbi->screen_base, fbi->fix.smem_start); | |
| 1131 | + fbi->screen_buffer, fbi->fix.smem_start); | |
| 1132 | 1132 | } |
| 1133 | 1133 | |
| 1134 | 1134 | /** |
| @@ -1186,10 +1186,8 @@ static int s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, · 51 unmodified lines | ||
| 1186 | 1186 | |
| 1187 | 1187 | fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) + |
| 1188 | 1188 | palette_size * sizeof(u32), sfb->dev); |
| 1189 | − if (!fbinfo) { | |
| 1190 | − dev_err(sfb->dev, "failed to allocate framebuffer\n"); | |
| 1191 | − return -ENOENT; | |
| 1192 | − } | |
| 1189 | + if (!fbinfo) | |
| 1190 | + return -ENOMEM; | |
| 1193 | 1191 | |
| 1194 | 1192 | windata = sfb->pdata->win[win_no]; |
| 1195 | 1193 | initmode = *sfb->pdata->vtiming; |
| @@ -1128,10 +1128,8 @@ static int s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) · 1127 unmodified lines | ||
| 1128 | 1128 | |
| 1129 | 1129 | /* Allocate and fill driver data structure */ |
| 1130 | 1130 | info = framebuffer_alloc(sizeof(struct s3fb_info), &(dev->dev)); |
| 1131 | − if (!info) { | |
| 1132 | − dev_err(&(dev->dev), "cannot allocate memory\n"); | |
| 1131 | + if (!info) | |
| 1133 | 1132 | return -ENOMEM; |
| 1134 | − } | |
| 1135 | 1133 | |
| 1136 | 1134 | par = info->par; |
| 1137 | 1135 | mutex_init(&par->open_lock); |
| @@ -974,35 +974,10 @@ static void sa1100fb_task(struct work_struct *w) · 973 unmodified lines | ||
| 974 | 974 | */ |
| 975 | 975 | static unsigned int sa1100fb_min_dma_period(struct sa1100fb_info *fbi) |
| 976 | 976 | { |
| 977 | −#if 0 | |
| 978 | − unsigned int min_period = (unsigned int)-1; | |
| 979 | − int i; | |
| 980 | − | |
| 981 | − for (i = 0; i < MAX_NR_CONSOLES; i++) { | |
| 982 | − struct display *disp = &fb_display[i]; | |
| 983 | − unsigned int period; | |
| 984 | − | |
| 985 | − /* | |
| 986 | − * Do we own this display? | |
| 987 | − */ | |
| 988 | − if (disp->fb_info != &fbi->fb) | |
| 989 | − continue; | |
| 990 | − | |
| 991 | − /* | |
| 992 | − * Ok, calculate its DMA period | |
| 993 | − */ | |
| 994 | − period = sa1100fb_display_dma_period(&disp->var); | |
| 995 | − if (period < min_period) | |
| 996 | − min_period = period; | |
| 997 | − } | |
| 998 | − | |
| 999 | − return min_period; | |
| 1000 | −#else | |
| 1001 | 977 | /* |
| 1002 | 978 | * FIXME: we need to verify _all_ consoles. |
| 1003 | 979 | */ |
| 1004 | 980 | return sa1100fb_display_dma_period(&fbi->fb.var); |
| 1005 | −#endif | |
| 1006 | 981 | } |
| 1007 | 982 | |
| 1008 | 983 | /* |
| @@ -2333,14 +2333,7 @@ static void savagefb_remove(struct pci_dev *dev) · 2332 unmodified lines | ||
| 2333 | 2333 | DBG("savagefb_remove"); |
| 2334 | 2334 | |
| 2335 | 2335 | if (info) { |
| 2336 | − /* | |
| 2337 | − * If unregister_framebuffer fails, then | |
| 2338 | − * we will be leaving hooks that could cause | |
| 2339 | − * oopsen laying around. | |
| 2340 | − */ | |
| 2341 | − if (unregister_framebuffer(info)) | |
| 2342 | − printk(KERN_WARNING "savagefb: danger danger! " | |
| 2343 | − "Oopsen imminent!\n"); | |
| 2336 | + unregister_framebuffer(info); | |
| 2344 | 2337 | |
| 2345 | 2338 | #ifdef CONFIG_FB_SAVAGE_I2C |
| 2346 | 2339 | savagefb_delete_i2c_busses(info); |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/ctype.h> |
| 16 | 16 | #include <linux/dma-mapping.h> |
| 17 | 17 | #include <linux/delay.h> |
| 18 | +#include <linux/fbcon.h> | |
| 18 | 19 | #include <linux/gpio.h> |
| 19 | 20 | #include <linux/init.h> |
| 20 | 21 | #include <linux/interrupt.h> |
| @@ -213,7 +214,6 @@ struct sh_mobile_lcdc_priv { · 192 unmodified lines | ||
| 213 | 214 | struct sh_mobile_lcdc_chan ch[2]; |
| 214 | 215 | struct sh_mobile_lcdc_overlay overlays[4]; |
| 215 | 216 | |
| 216 | − struct notifier_block notifier; | |
| 217 | 217 | int started; |
| 218 | 218 | int forced_fourcc; /* 2 channel LCDC must share fourcc setting */ |
| 219 | 219 | }; |
| @@ -534,89 +534,9 @@ static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch) · 314 unmodified lines | ||
| 534 | 534 | ch->tx_dev->ops->display_off(ch->tx_dev); |
| 535 | 535 | } |
| 536 | 536 | |
| 537 | −static bool | |
| 538 | −sh_mobile_lcdc_must_reconfigure(struct sh_mobile_lcdc_chan *ch, | |
| 539 | − const struct fb_videomode *new_mode) | |
| 540 | −{ | |
| 541 | − dev_dbg(ch->info->dev, "Old %ux%u, new %ux%u\n", | |
| 542 | − ch->display.mode.xres, ch->display.mode.yres, | |
| 543 | − new_mode->xres, new_mode->yres); | |
| 544 | − | |
| 545 | − /* It can be a different monitor with an equal video-mode */ | |
| 546 | − if (fb_mode_is_equal(&ch->display.mode, new_mode)) | |
| 547 | − return false; | |
| 548 | − | |
| 549 | − dev_dbg(ch->info->dev, "Switching %u -> %u lines\n", | |
| 550 | − ch->display.mode.yres, new_mode->yres); | |
| 551 | − ch->display.mode = *new_mode; | |
| 552 | − | |
| 553 | − return true; | |
| 554 | −} | |
| 555 | − | |
| 556 | 537 | static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var, |
| 557 | 538 | struct fb_info *info); |
| 558 | 539 | |
| 559 | −static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch, | |
| 560 | − enum sh_mobile_lcdc_entity_event event, | |
| 561 | − const struct fb_videomode *mode, | |
| 562 | − const struct fb_monspecs *monspec) | |
| 563 | −{ | |
| 564 | − struct fb_info *info = ch->info; | |
| 565 | − struct fb_var_screeninfo var; | |
| 566 | − int ret = 0; | |
| 567 | − | |
| 568 | − switch (event) { | |
| 569 | − case SH_MOBILE_LCDC_EVENT_DISPLAY_CONNECT: | |
| 570 | − /* HDMI plug in */ | |
| 571 | − console_lock(); | |
| 572 | − if (lock_fb_info(info)) { | |
| 573 | − | |
| 574 | − | |
| 575 | − ch->display.width = monspec->max_x * 10; | |
| 576 | − ch->display.height = monspec->max_y * 10; | |
| 577 | − | |
| 578 | − if (!sh_mobile_lcdc_must_reconfigure(ch, mode) && | |
| 579 | − info->state == FBINFO_STATE_RUNNING) { | |
| 580 | − /* First activation with the default monitor. | |
| 581 | − * Just turn on, if we run a resume here, the | |
| 582 | − * logo disappears. | |
| 583 | − */ | |
| 584 | − info->var.width = ch->display.width; | |
| 585 | − info->var.height = ch->display.height; | |
| 586 | − sh_mobile_lcdc_display_on(ch); | |
| 587 | − } else { | |
| 588 | − /* New monitor or have to wake up */ | |
| 589 | − fb_set_suspend(info, 0); | |
| 590 | − } | |
| 591 | − | |
| 592 | − | |
| 593 | − unlock_fb_info(info); | |
| 594 | − } | |
| 595 | − console_unlock(); | |
| 596 | − break; | |
| 597 | − | |
| 598 | − case SH_MOBILE_LCDC_EVENT_DISPLAY_DISCONNECT: | |
| 599 | − /* HDMI disconnect */ | |
| 600 | − console_lock(); | |
| 601 | − if (lock_fb_info(info)) { | |
| 602 | − fb_set_suspend(info, 1); | |
| 603 | − unlock_fb_info(info); | |
| 604 | − } | |
| 605 | − console_unlock(); | |
| 606 | − break; | |
| 607 | − | |
| 608 | − case SH_MOBILE_LCDC_EVENT_DISPLAY_MODE: | |
| 609 | − /* Validate a proposed new mode */ | |
| 610 | − fb_videomode_to_var(&var, mode); | |
| 611 | − var.bits_per_pixel = info->var.bits_per_pixel; | |
| 612 | − var.grayscale = info->var.grayscale; | |
| 613 | − ret = sh_mobile_lcdc_check_var(&var, info); | |
| 614 | − break; | |
| 615 | − } | |
| 616 | − | |
| 617 | − return ret; | |
| 618 | −} | |
| 619 | − | |
| 620 | 540 | /* ----------------------------------------------------------------------------- |
| 621 | 541 | * Format helpers |
| 622 | 542 | */ |
| @@ -1644,10 +1564,8 @@ sh_mobile_lcdc_overlay_fb_init(struct sh_mobile_lcdc_overlay *ovl) · 1021 unmodified lines | ||
| 1644 | 1564 | |
| 1645 | 1565 | /* Allocate and initialize the frame buffer device. */ |
| 1646 | 1566 | info = framebuffer_alloc(0, priv->dev); |
| 1647 | − if (info == NULL) { | |
| 1648 | − dev_err(priv->dev, "unable to allocate fb_info\n"); | |
| 1567 | + if (!info) | |
| 1649 | 1568 | return -ENOMEM; |
| 1650 | − } | |
| 1651 | 1569 | |
| 1652 | 1570 | ovl->info = info; |
| 1653 | 1571 | |
| @@ -1838,8 +1756,6 @@ static void sh_mobile_fb_reconfig(struct fb_info *info) · 184 unmodified lines | ||
| 1838 | 1756 | struct sh_mobile_lcdc_chan *ch = info->par; |
| 1839 | 1757 | struct fb_var_screeninfo var; |
| 1840 | 1758 | struct fb_videomode mode; |
| 1841 | − struct fb_event event; | |
| 1842 | − int evnt = FB_EVENT_MODE_CHANGE_ALL; | |
| 1843 | 1759 | |
| 1844 | 1760 | if (ch->use_count > 1 || (ch->use_count == 1 && !info->fbcon_par)) |
| 1845 | 1761 | /* More framebuffer users are active */ |
| @@ -1861,14 +1777,7 @@ static void sh_mobile_fb_reconfig(struct fb_info *info) · 15 unmodified lines | ||
| 1861 | 1777 | /* Couldn't reconfigure, hopefully, can continue as before */ |
| 1862 | 1778 | return; |
| 1863 | 1779 | |
| 1864 | − /* | |
| 1865 | − * fb_set_var() calls the notifier change internally, only if | |
| 1866 | − * FBINFO_MISC_USEREVENT flag is set. Since we do not want to fake a | |
| 1867 | − * user event, we have to call the chain ourselves. | |
| 1868 | − */ | |
| 1869 | − event.info = info; | |
| 1870 | − event.data = &ch->display.mode; | |
| 1871 | − fb_notifier_call_chain(evnt, &event); | |
| 1780 | + fbcon_update_vcs(info, true); | |
| 1872 | 1781 | } |
| 1873 | 1782 | |
| 1874 | 1783 | /* |
| @@ -2138,10 +2047,8 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch, · 263 unmodified lines | ||
| 2138 | 2047 | * list and allocate the color map. |
| 2139 | 2048 | */ |
| 2140 | 2049 | info = framebuffer_alloc(0, priv->dev); |
| 2141 | − if (info == NULL) { | |
| 2142 | − dev_err(priv->dev, "unable to allocate fb_info\n"); | |
| 2050 | + if (!info) | |
| 2143 | 2051 | return -ENOMEM; |
| 2144 | − } | |
| 2145 | 2052 | |
| 2146 | 2053 | ch->info = info; |
| 2147 | 2054 | |
| @@ -2319,37 +2226,6 @@ static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { · 171 unmodified lines | ||
| 2319 | 2226 | * Framebuffer notifier |
| 2320 | 2227 | */ |
| 2321 | 2228 | |
| 2322 | −/* locking: called with info->lock held */ | |
| 2323 | −static int sh_mobile_lcdc_notify(struct notifier_block *nb, | |
| 2324 | − unsigned long action, void *data) | |
| 2325 | −{ | |
| 2326 | − struct fb_event *event = data; | |
| 2327 | − struct fb_info *info = event->info; | |
| 2328 | − struct sh_mobile_lcdc_chan *ch = info->par; | |
| 2329 | − | |
| 2330 | − if (&ch->lcdc->notifier != nb) | |
| 2331 | − return NOTIFY_DONE; | |
| 2332 | − | |
| 2333 | − dev_dbg(info->dev, "%s(): action = %lu, data = %p\n", | |
| 2334 | − __func__, action, event->data); | |
| 2335 | − | |
| 2336 | − switch(action) { | |
| 2337 | − case FB_EVENT_SUSPEND: | |
| 2338 | − sh_mobile_lcdc_display_off(ch); | |
| 2339 | − sh_mobile_lcdc_stop(ch->lcdc); | |
| 2340 | − break; | |
| 2341 | − case FB_EVENT_RESUME: | |
| 2342 | − mutex_lock(&ch->open_lock); | |
| 2343 | − sh_mobile_fb_reconfig(info); | |
| 2344 | − mutex_unlock(&ch->open_lock); | |
| 2345 | − | |
| 2346 | − sh_mobile_lcdc_display_on(ch); | |
| 2347 | − sh_mobile_lcdc_start(ch->lcdc); | |
| 2348 | − } | |
| 2349 | − | |
| 2350 | − return NOTIFY_OK; | |
| 2351 | −} | |
| 2352 | − | |
| 2353 | 2229 | /* ----------------------------------------------------------------------------- |
| 2354 | 2230 | * Probe/remove and driver init/exit |
| 2355 | 2231 | */ |
| @@ -2377,8 +2253,6 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev) · 21 unmodified lines | ||
| 2377 | 2253 | struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev); |
| 2378 | 2254 | unsigned int i; |
| 2379 | 2255 | |
| 2380 | − fb_unregister_client(&priv->notifier); | |
| 2381 | − | |
| 2382 | 2256 | for (i = 0; i < ARRAY_SIZE(priv->overlays); i++) |
| 2383 | 2257 | sh_mobile_lcdc_overlay_fb_unregister(&priv->overlays[i]); |
| 2384 | 2258 | for (i = 0; i < ARRAY_SIZE(priv->ch); i++) |
| @@ -2540,8 +2414,6 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch) · 155 unmodified lines | ||
| 2540 | 2414 | unsigned int max_size; |
| 2541 | 2415 | unsigned int i; |
| 2542 | 2416 | |
| 2543 | − ch->notify = sh_mobile_lcdc_display_notify; | |
| 2544 | − | |
| 2545 | 2417 | /* Validate the format. */ |
| 2546 | 2418 | format = sh_mobile_format_info(cfg->fourcc); |
| 2547 | 2419 | if (format == NULL) { |
| @@ -2770,10 +2642,6 @@ static int sh_mobile_lcdc_probe(struct platform_device *pdev) · 222 unmodified lines | ||
| 2770 | 2642 | goto err1; |
| 2771 | 2643 | } |
| 2772 | 2644 | |
| 2773 | − /* Failure ignored */ | |
| 2774 | − priv->notifier.notifier_call = sh_mobile_lcdc_notify; | |
| 2775 | − fb_register_client(&priv->notifier); | |
| 2776 | − | |
| 2777 | 2645 | return 0; |
| 2778 | 2646 | err1: |
| 2779 | 2647 | sh_mobile_lcdc_remove(pdev); |
| @@ -87,11 +87,6 @@ struct sh_mobile_lcdc_chan { · 86 unmodified lines | ||
| 87 | 87 | unsigned long base_addr_c; |
| 88 | 88 | unsigned int line_size; |
| 89 | 89 | |
| 90 | − int (*notify)(struct sh_mobile_lcdc_chan *ch, | |
| 91 | − enum sh_mobile_lcdc_entity_event event, | |
| 92 | − const struct fb_videomode *mode, | |
| 93 | − const struct fb_monspecs *monspec); | |
| 94 | − | |
| 95 | 90 | /* Backlight */ |
| 96 | 91 | struct backlight_device *bl; |
| 97 | 92 | unsigned int bl_brightness; |
| @@ -1865,10 +1865,8 @@ static int sm501fb_probe_one(struct sm501fb_info *info, · 1864 unmodified lines | ||
| 1865 | 1865 | } |
| 1866 | 1866 | |
| 1867 | 1867 | fbi = framebuffer_alloc(sizeof(struct sm501fb_par), info->dev); |
| 1868 | − if (fbi == NULL) { | |
| 1869 | − dev_err(info->dev, "cannot allocate %s framebuffer\n", name); | |
| 1868 | + if (!fbi) | |
| 1870 | 1869 | return -ENOMEM; |
| 1871 | − } | |
| 1872 | 1870 | |
| 1873 | 1871 | par = fbi->par; |
| 1874 | 1872 | par->info = info; |
| @@ -1538,7 +1538,6 @@ static int smtcfb_pci_probe(struct pci_dev *pdev, · 1537 unmodified lines | ||
| 1538 | 1538 | |
| 1539 | 1539 | info = framebuffer_alloc(sizeof(*sfb), &pdev->dev); |
| 1540 | 1540 | if (!info) { |
| 1541 | − dev_err(&pdev->dev, "framebuffer_alloc failed\n"); | |
| 1542 | 1541 | err = -ENOMEM; |
| 1543 | 1542 | goto failed_free; |
| 1544 | 1543 | } |
| @@ -1650,10 +1650,8 @@ static int ufx_usb_probe(struct usb_interface *interface, · 1649 unmodified lines | ||
| 1650 | 1650 | |
| 1651 | 1651 | /* allocates framebuffer driver structure, not framebuffer memory */ |
| 1652 | 1652 | info = framebuffer_alloc(0, &usbdev->dev); |
| 1653 | − if (!info) { | |
| 1654 | − dev_err(dev->gdev, "framebuffer_alloc failed\n"); | |
| 1653 | + if (!info) | |
| 1655 | 1654 | goto e_nomem; |
| 1656 | − } | |
| 1657 | 1655 | |
| 1658 | 1656 | dev->info = info; |
| 1659 | 1657 | info->par = dev; |
| @@ -555,10 +555,8 @@ static int ssd1307fb_probe(struct i2c_client *client, · 554 unmodified lines | ||
| 555 | 555 | } |
| 556 | 556 | |
| 557 | 557 | info = framebuffer_alloc(sizeof(struct ssd1307fb_par), &client->dev); |
| 558 | − if (!info) { | |
| 559 | − dev_err(&client->dev, "Couldn't allocate framebuffer.\n"); | |
| 558 | + if (!info) | |
| 560 | 559 | return -ENOMEM; |
| 561 | − } | |
| 562 | 560 | |
| 563 | 561 | par = info->par; |
| 564 | 562 | par->info = info; |
| @@ -121,7 +121,6 @@ static int gfb_probe(struct platform_device *op) · 120 unmodified lines | ||
| 121 | 121 | |
| 122 | 122 | info = framebuffer_alloc(sizeof(struct gfb_info), &op->dev); |
| 123 | 123 | if (!info) { |
| 124 | − printk(KERN_ERR "gfb: Cannot allocate fb_info\n"); | |
| 125 | 124 | err = -ENOMEM; |
| 126 | 125 | goto err_out; |
| 127 | 126 | } |
| @@ -132,7 +132,6 @@ static int s3d_pci_register(struct pci_dev *pdev, · 131 unmodified lines | ||
| 132 | 132 | |
| 133 | 133 | info = framebuffer_alloc(sizeof(struct s3d_info), &pdev->dev); |
| 134 | 134 | if (!info) { |
| 135 | − printk(KERN_ERR "s3d: Cannot allocate fb_info\n"); | |
| 136 | 135 | err = -ENOMEM; |
| 137 | 136 | goto err_disable; |
| 138 | 137 | } |
| @@ -272,7 +272,6 @@ static int e3d_pci_register(struct pci_dev *pdev, · 271 unmodified lines | ||
| 272 | 272 | |
| 273 | 273 | info = framebuffer_alloc(sizeof(struct e3d_info), &pdev->dev); |
| 274 | 274 | if (!info) { |
| 275 | − printk(KERN_ERR "e3d: Cannot allocate fb_info\n"); | |
| 276 | 275 | err = -ENOMEM; |
| 277 | 276 | goto err_disable; |
| 278 | 277 | } |
| @@ -1416,10 +1416,8 @@ static int tgafb_register(struct device *dev) · 1415 unmodified lines | ||
| 1416 | 1416 | |
| 1417 | 1417 | /* Allocate the fb and par structures. */ |
| 1418 | 1418 | info = framebuffer_alloc(sizeof(struct tga_par), dev); |
| 1419 | − if (!info) { | |
| 1420 | − printk(KERN_ERR "tgafb: Cannot allocate memory\n"); | |
| 1419 | + if (!info) | |
| 1421 | 1420 | return -ENOMEM; |
| 1422 | − } | |
| 1423 | 1421 | |
| 1424 | 1422 | par = info->par; |
| 1425 | 1423 | dev_set_drvdata(dev, info); |
| @@ -1686,10 +1686,8 @@ static int dlfb_usb_probe(struct usb_interface *intf, · 1685 unmodified lines | ||
| 1686 | 1686 | |
| 1687 | 1687 | /* allocates framebuffer driver structure, not framebuffer memory */ |
| 1688 | 1688 | info = framebuffer_alloc(0, &dlfb->udev->dev); |
| 1689 | − if (!info) { | |
| 1690 | − dev_err(&dlfb->udev->dev, "framebuffer_alloc failed\n"); | |
| 1689 | + if (!info) | |
| 1691 | 1690 | goto error; |
| 1692 | − } | |
| 1693 | 1691 | |
| 1694 | 1692 | dlfb->info = info; |
| 1695 | 1693 | info->par = dlfb; |
| @@ -1742,10 +1742,8 @@ int via_fb_pci_probe(struct viafb_dev *vdev) · 1741 unmodified lines | ||
| 1742 | 1742 | viafbinfo = framebuffer_alloc(viafb_par_length + |
| 1743 | 1743 | ALIGN(sizeof(struct viafb_shared), BITS_PER_LONG/8), |
| 1744 | 1744 | &vdev->pdev->dev); |
| 1745 | − if (!viafbinfo) { | |
| 1746 | − printk(KERN_ERR"Could not allocate memory for viafb_info.\n"); | |
| 1745 | + if (!viafbinfo) | |
| 1747 | 1746 | return -ENOMEM; |
| 1748 | − } | |
| 1749 | 1747 | |
| 1750 | 1748 | viaparinfo = (struct viafb_par *)viafbinfo->par; |
| 1751 | 1749 | viaparinfo->shared = viafbinfo->par + viafb_par_length; |
| @@ -1820,8 +1818,6 @@ int via_fb_pci_probe(struct viafb_dev *vdev) · 68 unmodified lines | ||
| 1820 | 1818 | viafbinfo1 = framebuffer_alloc(viafb_par_length, |
| 1821 | 1819 | &vdev->pdev->dev); |
| 1822 | 1820 | if (!viafbinfo1) { |
| 1823 | − printk(KERN_ERR | |
| 1824 | − "allocate the second framebuffer struct error\n"); | |
| 1825 | 1821 | rc = -ENOMEM; |
| 1826 | 1822 | goto out_fb_release; |
| 1827 | 1823 | } |
| @@ -669,10 +669,8 @@ static int vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) · 668 unmodified lines | ||
| 669 | 669 | |
| 670 | 670 | /* Allocate and fill driver data structure */ |
| 671 | 671 | info = framebuffer_alloc(sizeof(struct vt8623fb_info), &(dev->dev)); |
| 672 | − if (! info) { | |
| 673 | − dev_err(&(dev->dev), "cannot allocate memory\n"); | |
| 672 | + if (!info) | |
| 674 | 673 | return -ENOMEM; |
| 675 | − } | |
| 676 | 674 | |
| 677 | 675 | par = info->par; |
| 678 | 676 | mutex_init(&par->open_lock); |
| @@ -168,9 +168,6 @@ extern void vc_SAK(struct work_struct *work); · 167 unmodified lines | ||
| 168 | 168 | |
| 169 | 169 | #define CUR_DEFAULT CUR_UNDERLINE |
| 170 | 170 | |
| 171 | −static inline bool con_is_visible(const struct vc_data *vc) | |
| 172 | −{ | |
| 173 | − return *vc->vc_display_fg == vc; | |
| 174 | −} | |
| 171 | +bool con_is_visible(const struct vc_data *vc); | |
| 175 | 172 | |
| 176 | 173 | #endif /* _LINUX_CONSOLE_STRUCT_H */ |
| @@ -126,39 +126,15 @@ struct fb_cursor_user { · 125 unmodified lines | ||
| 126 | 126 | |
| 127 | 127 | /* The resolution of the passed in fb_info about to change */ |
| 128 | 128 | #define FB_EVENT_MODE_CHANGE 0x01 |
| 129 | −/* The display on this fb_info is being suspended, no access to the | |
| 130 | − * framebuffer is allowed any more after that call returns | |
| 131 | − */ | |
| 132 | −#define FB_EVENT_SUSPEND 0x02 | |
| 133 | −/* The display on this fb_info was resumed, you can restore the display | |
| 134 | − * if you own it | |
| 135 | − */ | |
| 136 | −#define FB_EVENT_RESUME 0x03 | |
| 137 | −/* An entry from the modelist was removed */ | |
| 138 | −#define FB_EVENT_MODE_DELETE 0x04 | |
| 139 | −/* A driver registered itself */ | |
| 129 | + | |
| 130 | +#ifdef CONFIG_GUMSTIX_AM200EPD | |
| 131 | +/* only used by mach-pxa/am200epd.c */ | |
| 140 | 132 | #define FB_EVENT_FB_REGISTERED 0x05 |
| 141 | −/* A driver unregistered itself */ | |
| 142 | 133 | #define FB_EVENT_FB_UNREGISTERED 0x06 |
| 143 | −/* CONSOLE-SPECIFIC: get console to framebuffer mapping */ | |
| 144 | −#define FB_EVENT_GET_CONSOLE_MAP 0x07 | |
| 145 | −/* CONSOLE-SPECIFIC: set console to framebuffer mapping */ | |
| 146 | −#define FB_EVENT_SET_CONSOLE_MAP 0x08 | |
| 147 | −/* A hardware display blank change occurred */ | |
| 134 | +#endif | |
| 135 | + | |
| 136 | +/* A display blank is requested */ | |
| 148 | 137 | #define FB_EVENT_BLANK 0x09 |
| 149 | −/* Private modelist is to be replaced */ | |
| 150 | −#define FB_EVENT_NEW_MODELIST 0x0A | |
| 151 | −/* The resolution of the passed in fb_info about to change and | |
| 152 | − all vc's should be changed */ | |
| 153 | −#define FB_EVENT_MODE_CHANGE_ALL 0x0B | |
| 154 | −/* A software display blank change occurred */ | |
| 155 | −#define FB_EVENT_CONBLANK 0x0C | |
| 156 | −/* Get drawing requirements */ | |
| 157 | −#define FB_EVENT_GET_REQ 0x0D | |
| 158 | −/* Unbind from the console if possible */ | |
| 159 | −#define FB_EVENT_FB_UNBIND 0x0E | |
| 160 | −/* CONSOLE-SPECIFIC: remap all consoles to new fb - for vga_switcheroo */ | |
| 161 | −#define FB_EVENT_REMAP_ALL_CONSOLE 0x0F | |
| 162 | 138 | /* A hardware display blank early change occurred */ |
| 163 | 139 | #define FB_EARLY_EVENT_BLANK 0x10 |
| 164 | 140 | /* A hardware display blank revert early change occurred */ |
| @@ -633,8 +609,8 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, · 468 unmodified lines | ||
| 633 | 609 | |
| 634 | 610 | /* drivers/video/fbmem.c */ |
| 635 | 611 | extern int register_framebuffer(struct fb_info *fb_info); |
| 636 | −extern int unregister_framebuffer(struct fb_info *fb_info); | |
| 637 | −extern int unlink_framebuffer(struct fb_info *fb_info); | |
| 612 | +extern void unregister_framebuffer(struct fb_info *fb_info); | |
| 613 | +extern void unlink_framebuffer(struct fb_info *fb_info); | |
| 638 | 614 | extern int remove_conflicting_pci_framebuffers(struct pci_dev *pdev, int res_id, |
| 639 | 615 | const char *name); |
| 640 | 616 | extern int remove_conflicting_framebuffers(struct apertures_struct *a, |
| @@ -660,7 +636,10 @@ extern struct class *fb_class; · 19 unmodified lines | ||
| 660 | 636 | for (i = 0; i < FB_MAX; i++) \ |
| 661 | 637 | if (!registered_fb[i]) {} else |
| 662 | 638 | |
| 663 | −extern int lock_fb_info(struct fb_info *info); | |
| 639 | +static inline void lock_fb_info(struct fb_info *info) | |
| 640 | +{ | |
| 641 | + mutex_lock(&info->lock); | |
| 642 | +} | |
| 664 | 643 | |
| 665 | 644 | static inline void unlock_fb_info(struct fb_info *info) |
| 666 | 645 | { |
| @@ -4,9 +4,39 @@ · 3 unmodified lines | ||
| 4 | 4 | #ifdef CONFIG_FRAMEBUFFER_CONSOLE |
| 5 | 5 | void __init fb_console_init(void); |
| 6 | 6 | void __exit fb_console_exit(void); |
| 7 | +int fbcon_fb_registered(struct fb_info *info); | |
| 8 | +void fbcon_fb_unregistered(struct fb_info *info); | |
| 9 | +void fbcon_fb_unbind(struct fb_info *info); | |
| 10 | +void fbcon_suspended(struct fb_info *info); | |
| 11 | +void fbcon_resumed(struct fb_info *info); | |
| 12 | +int fbcon_mode_deleted(struct fb_info *info, | |
| 13 | + struct fb_videomode *mode); | |
| 14 | +void fbcon_new_modelist(struct fb_info *info); | |
| 15 | +void fbcon_get_requirement(struct fb_info *info, | |
| 16 | + struct fb_blit_caps *caps); | |
| 17 | +void fbcon_fb_blanked(struct fb_info *info, int blank); | |
| 18 | +void fbcon_update_vcs(struct fb_info *info, bool all); | |
| 19 | +void fbcon_remap_all(struct fb_info *info); | |
| 20 | +int fbcon_set_con2fb_map_ioctl(void __user *argp); | |
| 21 | +int fbcon_get_con2fb_map_ioctl(void __user *argp); | |
| 7 | 22 | #else |
| 8 | 23 | static inline void fb_console_init(void) {} |
| 9 | 24 | static inline void fb_console_exit(void) {} |
| 25 | +static inline int fbcon_fb_registered(struct fb_info *info) { return 0; } | |
| 26 | +static inline void fbcon_fb_unregistered(struct fb_info *info) {} | |
| 27 | +static inline void fbcon_fb_unbind(struct fb_info *info) {} | |
| 28 | +static inline void fbcon_suspended(struct fb_info *info) {} | |
| 29 | +static inline void fbcon_resumed(struct fb_info *info) {} | |
| 30 | +static inline int fbcon_mode_deleted(struct fb_info *info, | |
| 31 | + struct fb_videomode *mode) { return 0; } | |
| 32 | +static inline void fbcon_new_modelist(struct fb_info *info) {} | |
| 33 | +static inline void fbcon_get_requirement(struct fb_info *info, | |
| 34 | + struct fb_blit_caps *caps) {} | |
| 35 | +static inline void fbcon_fb_blanked(struct fb_info *info, int blank) {} | |
| 36 | +static inline void fbcon_update_vcs(struct fb_info *info, bool all) {} | |
| 37 | +static inline void fbcon_remap_all(struct fb_info *info) {} | |
| 38 | +static inline int fbcon_set_con2fb_map_ioctl(void __user *argp) { return 0; } | |
| 39 | +static inline int fbcon_get_con2fb_map_ioctl(void __user *argp) { return 0; } | |
| 10 | 40 | #endif |
| 11 | 41 | |
| 12 | 42 | #endif /* _LINUX_FBCON_H */ |
| @@ -114,11 +114,6 @@ enum omap_dss_trans_key_type { · 113 unmodified lines | ||
| 114 | 114 | OMAP_DSS_COLOR_KEY_VID_SRC = 1, |
| 115 | 115 | }; |
| 116 | 116 | |
| 117 | −enum omap_rfbi_te_mode { | |
| 118 | − OMAP_DSS_RFBI_TE_MODE_1 = 1, | |
| 119 | − OMAP_DSS_RFBI_TE_MODE_2 = 2, | |
| 120 | −}; | |
| 121 | − | |
| 122 | 117 | enum omap_dss_signal_level { |
| 123 | 118 | OMAPDSS_SIG_ACTIVE_LOW, |
| 124 | 119 | OMAPDSS_SIG_ACTIVE_HIGH, |
| @@ -189,27 +184,6 @@ enum omap_dss_output_id { · 64 unmodified lines | ||
| 189 | 184 | OMAP_DSS_OUTPUT_HDMI = 1 << 6, |
| 190 | 185 | }; |
| 191 | 186 | |
| 192 | −/* RFBI */ | |
| 193 | − | |
| 194 | −struct rfbi_timings { | |
| 195 | − int cs_on_time; | |
| 196 | − int cs_off_time; | |
| 197 | − int we_on_time; | |
| 198 | − int we_off_time; | |
| 199 | − int re_on_time; | |
| 200 | − int re_off_time; | |
| 201 | − int we_cycle_time; | |
| 202 | − int re_cycle_time; | |
| 203 | − int cs_pulse_width; | |
| 204 | − int access_time; | |
| 205 | − | |
| 206 | − int clk_div; | |
| 207 | − | |
| 208 | − u32 tim[5]; /* set by rfbi_convert_timings() */ | |
| 209 | − | |
| 210 | − int converted; | |
| 211 | −}; | |
| 212 | − | |
| 213 | 187 | /* DSI */ |
| 214 | 188 | |
| 215 | 189 | enum omap_dss_dsi_trans_mode { |
| @@ -640,11 +614,6 @@ struct omap_dss_device { · 424 unmodified lines | ||
| 640 | 614 | u8 data_lines; |
| 641 | 615 | } dpi; |
| 642 | 616 | |
| 643 | − struct { | |
| 644 | − u8 channel; | |
| 645 | − u8 data_lines; | |
| 646 | − } rfbi; | |
| 647 | − | |
| 648 | 617 | struct { |
| 649 | 618 | u8 datapairs; |
| 650 | 619 | } sdi; |
| @@ -668,7 +637,6 @@ struct omap_dss_device { · 17 unmodified lines | ||
| 668 | 637 | |
| 669 | 638 | struct { |
| 670 | 639 | u8 pixel_size; |
| 671 | − struct rfbi_timings rfbi_timings; | |
| 672 | 640 | } ctrl; |
| 673 | 641 | |
| 674 | 642 | const char *name; |