summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2013-05-01 15:47:44 (GMT)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2013-05-01 15:47:44 (GMT)
commitbf61c8840efe60fd8f91446860b63338fb424158 (patch)
tree7a71832407a4f0d6346db773343f4c3ae2257b19 /drivers/video
parent5846115b30f3a881e542c8bfde59a699c1c13740 (diff)
parent0c6a61657da78098472fd0eb71cc01f2387fa1bb (diff)
downloadlinux-fsl-qoriq-bf61c8840efe60fd8f91446860b63338fb424158.tar.xz
Merge branch 'next' into for-linus
Prepare first set of updates for 3.10 merge window.
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig92
-rw-r--r--drivers/video/Makefile8
-rw-r--r--drivers/video/acornfb.c22
-rw-r--r--drivers/video/arcfb.c10
-rw-r--r--drivers/video/arkfb.c10
-rw-r--r--drivers/video/asiliantfb.c18
-rw-r--r--drivers/video/atmel_lcdfb.c2
-rw-r--r--drivers/video/aty/aty128fb.c57
-rw-r--r--drivers/video/aty/atyfb_base.c84
-rw-r--r--drivers/video/aty/mach64_ct.c6
-rw-r--r--drivers/video/aty/mach64_cursor.c2
-rw-r--r--drivers/video/aty/radeon_base.c20
-rw-r--r--drivers/video/aty/radeon_monitor.c24
-rw-r--r--drivers/video/au1100fb.c6
-rw-r--r--drivers/video/au1200fb.c6
-rw-r--r--drivers/video/auo_k1900fb.c6
-rw-r--r--drivers/video/auo_k1901fb.c6
-rw-r--r--drivers/video/auo_k190x.c7
-rw-r--r--drivers/video/backlight/88pm860x_bl.c23
-rw-r--r--drivers/video/backlight/Kconfig30
-rw-r--r--drivers/video/backlight/Makefile90
-rw-r--r--drivers/video/backlight/aat2870_bl.c2
-rw-r--r--drivers/video/backlight/adp5520_bl.c6
-rw-r--r--drivers/video/backlight/adp8860_bl.c16
-rw-r--r--drivers/video/backlight/adp8870_bl.c16
-rw-r--r--drivers/video/backlight/ams369fg06.c112
-rw-r--r--drivers/video/backlight/apple_bl.c4
-rw-r--r--drivers/video/backlight/as3711_bl.c380
-rw-r--r--drivers/video/backlight/atmel-pwm-bl.c7
-rw-r--r--drivers/video/backlight/backlight.c29
-rw-r--r--drivers/video/backlight/corgi_lcd.c44
-rw-r--r--drivers/video/backlight/da903x_bl.c15
-rw-r--r--drivers/video/backlight/da9052_bl.c2
-rw-r--r--drivers/video/backlight/ep93xx_bl.c2
-rw-r--r--drivers/video/backlight/generic_bl.c4
-rw-r--r--drivers/video/backlight/hp680_bl.c6
-rw-r--r--drivers/video/backlight/hx8357.c497
-rw-r--r--drivers/video/backlight/ili9320.c18
-rw-r--r--drivers/video/backlight/ili9320.h2
-rw-r--r--drivers/video/backlight/jornada720_bl.c31
-rw-r--r--drivers/video/backlight/l4f00242t03.c45
-rw-r--r--drivers/video/backlight/lcd.c8
-rw-r--r--drivers/video/backlight/ld9040.c113
-rw-r--r--drivers/video/backlight/lm3533_bl.c8
-rw-r--r--drivers/video/backlight/lm3630_bl.c14
-rw-r--r--drivers/video/backlight/lm3639_bl.c15
-rw-r--r--drivers/video/backlight/lms283gf05.c27
-rw-r--r--drivers/video/backlight/lms501kf03.c441
-rw-r--r--drivers/video/backlight/locomolcd.c38
-rw-r--r--drivers/video/backlight/lp855x_bl.c222
-rw-r--r--drivers/video/backlight/lp8788_bl.c333
-rw-r--r--drivers/video/backlight/ltv350qv.c16
-rw-r--r--drivers/video/backlight/max8925_bl.c48
-rw-r--r--drivers/video/backlight/omap1_bl.c14
-rw-r--r--drivers/video/backlight/ot200_bl.c1
-rw-r--r--drivers/video/backlight/pandora_bl.c8
-rw-r--r--drivers/video/backlight/pcf50633-backlight.c14
-rw-r--r--drivers/video/backlight/platform_lcd.c8
-rw-r--r--drivers/video/backlight/pwm_bl.c28
-rw-r--r--drivers/video/backlight/s6e63m0.c161
-rw-r--r--drivers/video/backlight/tdo24m.c49
-rw-r--r--drivers/video/backlight/tosa_bl.c15
-rw-r--r--drivers/video/backlight/tosa_lcd.c42
-rw-r--r--drivers/video/backlight/vgg2432a4.c25
-rw-r--r--drivers/video/bf537-lq035.c18
-rw-r--r--drivers/video/bf54x-lq043fb.c6
-rw-r--r--drivers/video/bfin-lq035q1-fb.c14
-rw-r--r--drivers/video/bfin-t350mcqb-fb.c6
-rw-r--r--drivers/video/bfin_adv7393fb.c10
-rw-r--r--drivers/video/broadsheetfb.c16
-rw-r--r--drivers/video/bw2.c23
-rw-r--r--drivers/video/carminefb.c16
-rw-r--r--drivers/video/cg14.c12
-rw-r--r--drivers/video/cg3.c26
-rw-r--r--drivers/video/cg6.c12
-rw-r--r--drivers/video/chipsfb.c13
-rw-r--r--drivers/video/cirrusfb.c44
-rw-r--r--drivers/video/clps711xfb.c157
-rw-r--r--drivers/video/cobalt_lcdfb.c8
-rw-r--r--drivers/video/console/Kconfig2
-rw-r--r--drivers/video/console/fbcon.c68
-rw-r--r--drivers/video/console/newport_con.c11
-rw-r--r--drivers/video/console/softcursor.c3
-rw-r--r--drivers/video/console/sticore.c83
-rw-r--r--drivers/video/console/vgacon.c22
-rw-r--r--drivers/video/cyber2000fb.c23
-rw-r--r--drivers/video/da8xx-fb.c180
-rw-r--r--drivers/video/display_timing.c24
-rw-r--r--drivers/video/dnfb.c6
-rw-r--r--drivers/video/efifb.c4
-rw-r--r--drivers/video/ep93xx-fb.c8
-rw-r--r--drivers/video/exynos/exynos_dp_core.c716
-rw-r--r--drivers/video/exynos/exynos_dp_core.h21
-rw-r--r--drivers/video/exynos/exynos_dp_reg.c77
-rw-r--r--drivers/video/exynos/exynos_dp_reg.h3
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi.c74
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi_common.c1
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi_lowlevel.c1
-rw-r--r--drivers/video/exynos/s6e8ax0.c14
-rw-r--r--drivers/video/fb_defio.c2
-rw-r--r--drivers/video/fbmem.c13
-rw-r--r--drivers/video/fbmon.c94
-rw-r--r--drivers/video/fbsysfs.c3
-rw-r--r--drivers/video/ffb.c6
-rw-r--r--drivers/video/fm2fb.c14
-rw-r--r--drivers/video/fsl-diu-fb.c229
-rw-r--r--drivers/video/gbefb.c24
-rw-r--r--drivers/video/geode/Kconfig14
-rw-r--r--drivers/video/geode/gx1fb_core.c14
-rw-r--r--drivers/video/geode/gxfb_core.c20
-rw-r--r--drivers/video/geode/lxfb_core.c20
-rw-r--r--drivers/video/goldfishfb.c318
-rw-r--r--drivers/video/grvga.c12
-rw-r--r--drivers/video/gxt4500.c28
-rw-r--r--drivers/video/hdmi.c308
-rw-r--r--drivers/video/hecubafb.c10
-rw-r--r--drivers/video/hgafb.c12
-rw-r--r--drivers/video/hitfb.c10
-rw-r--r--drivers/video/hpfb.c9
-rw-r--r--drivers/video/i740fb.c15
-rw-r--r--drivers/video/i810/i810_main.c72
-rw-r--r--drivers/video/i810/i810_main.h2
-rw-r--r--drivers/video/igafb.c2
-rw-r--r--drivers/video/imsttfb.c17
-rw-r--r--drivers/video/imxfb.c53
-rw-r--r--drivers/video/intelfb/intelfbdrv.c29
-rw-r--r--drivers/video/jz4740_fb.c14
-rw-r--r--drivers/video/kyro/fbdev.c21
-rw-r--r--drivers/video/leo.c6
-rw-r--r--drivers/video/mb862xx/mb862xxfbdrv.c20
-rw-r--r--drivers/video/mbx/mbxdebugfs.c4
-rw-r--r--drivers/video/mbx/mbxfb.c18
-rw-r--r--drivers/video/metronomefb.c22
-rw-r--r--drivers/video/mmp/Kconfig11
-rw-r--r--drivers/video/mmp/Makefile1
-rw-r--r--drivers/video/mmp/core.c258
-rw-r--r--drivers/video/mmp/fb/Kconfig13
-rw-r--r--drivers/video/mmp/fb/Makefile1
-rw-r--r--drivers/video/mmp/fb/mmpfb.c685
-rw-r--r--drivers/video/mmp/fb/mmpfb.h54
-rw-r--r--drivers/video/mmp/hw/Kconfig20
-rw-r--r--drivers/video/mmp/hw/Makefile2
-rw-r--r--drivers/video/mmp/hw/mmp_ctrl.c591
-rw-r--r--drivers/video/mmp/hw/mmp_ctrl.h1974
-rw-r--r--drivers/video/mmp/hw/mmp_spi.c180
-rw-r--r--drivers/video/mmp/panel/Kconfig6
-rw-r--r--drivers/video/mmp/panel/Makefile1
-rw-r--r--drivers/video/mmp/panel/tpo_tj032md01bw.c186
-rw-r--r--drivers/video/msm/mddi.c9
-rw-r--r--drivers/video/msm/mdp.c2
-rw-r--r--drivers/video/mx3fb.c5
-rw-r--r--drivers/video/mxsfb.c15
-rw-r--r--drivers/video/neofb.c26
-rw-r--r--drivers/video/nuc900fb.c4
-rw-r--r--drivers/video/nvidia/nvidia.c49
-rw-r--r--drivers/video/of_display_timing.c239
-rw-r--r--drivers/video/of_videomode.c54
-rw-r--r--drivers/video/omap/Kconfig2
-rw-r--r--drivers/video/omap/lcd_ams_delta.c1
-rw-r--r--drivers/video/omap/lcd_inn1510.c7
-rw-r--r--drivers/video/omap/lcd_mipid.c2
-rw-r--r--drivers/video/omap/lcd_osk.c3
-rw-r--r--drivers/video/omap/lcdc.c2
-rw-r--r--drivers/video/omap/omapfb_main.c2
-rw-r--r--drivers/video/omap/sossi.c2
-rw-r--r--drivers/video/omap2/Kconfig7
-rw-r--r--drivers/video/omap2/Makefile1
-rw-r--r--drivers/video/omap2/displays/panel-acx565akm.c25
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c60
-rw-r--r--drivers/video/omap2/displays/panel-lgphilips-lb035q02.c40
-rw-r--r--drivers/video/omap2/displays/panel-n8x0.c91
-rw-r--r--drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c26
-rw-r--r--drivers/video/omap2/displays/panel-picodlp.c45
-rw-r--r--drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c17
-rw-r--r--drivers/video/omap2/displays/panel-taal.c72
-rw-r--r--drivers/video/omap2/displays/panel-tfp410.c33
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c24
-rw-r--r--drivers/video/omap2/dss/Kconfig35
-rw-r--r--drivers/video/omap2/dss/Makefile7
-rw-r--r--drivers/video/omap2/dss/apply.c331
-rw-r--r--drivers/video/omap2/dss/core.c72
-rw-r--r--drivers/video/omap2/dss/dispc-compat.c667
-rw-r--r--drivers/video/omap2/dss/dispc-compat.h30
-rw-r--r--drivers/video/omap2/dss/dispc.c1102
-rw-r--r--drivers/video/omap2/dss/display-sysfs.c321
-rw-r--r--drivers/video/omap2/dss/display.c386
-rw-r--r--drivers/video/omap2/dss/dpi.c126
-rw-r--r--drivers/video/omap2/dss/dsi.c260
-rw-r--r--drivers/video/omap2/dss/dss.c150
-rw-r--r--drivers/video/omap2/dss/dss.h124
-rw-r--r--drivers/video/omap2/dss/dss_features.c80
-rw-r--r--drivers/video/omap2/dss/dss_features.h12
-rw-r--r--drivers/video/omap2/dss/hdmi.c168
-rw-r--r--drivers/video/omap2/dss/hdmi_panel.c82
-rw-r--r--drivers/video/omap2/dss/manager.c39
-rw-r--r--drivers/video/omap2/dss/output.c90
-rw-r--r--drivers/video/omap2/dss/overlay.c17
-rw-r--r--drivers/video/omap2/dss/rfbi.c23
-rw-r--r--drivers/video/omap2/dss/sdi.c11
-rw-r--r--drivers/video/omap2/dss/ti_hdmi.h3
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c11
-rw-r--r--drivers/video/omap2/dss/venc.c11
-rw-r--r--drivers/video/omap2/dss/venc_panel.c19
-rw-r--r--drivers/video/omap2/omapfb/Kconfig1
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c50
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c212
-rw-r--r--drivers/video/omap2/omapfb/omapfb-sysfs.c6
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h20
-rw-r--r--drivers/video/omap2/vram.c514
-rw-r--r--drivers/video/omap2/vrfb.c141
-rw-r--r--drivers/video/p9100.c6
-rw-r--r--drivers/video/platinumfb.c11
-rw-r--r--drivers/video/pm2fb.c17
-rw-r--r--drivers/video/pm3fb.c17
-rw-r--r--drivers/video/pmag-ba-fb.c6
-rw-r--r--drivers/video/pmagb-b-fb.c12
-rw-r--r--drivers/video/ps3fb.c4
-rw-r--r--drivers/video/pvr2fb.c28
-rw-r--r--drivers/video/pxa168fb.c8
-rw-r--r--drivers/video/pxa3xx-gcu.c8
-rw-r--r--drivers/video/pxafb.c33
-rw-r--r--drivers/video/q40fb.c6
-rw-r--r--drivers/video/riva/fbdev.c45
-rw-r--r--drivers/video/riva/rivafb-i2c.c9
-rw-r--r--drivers/video/s1d13xxxfb.c10
-rw-r--r--drivers/video/s3c-fb.c46
-rw-r--r--drivers/video/s3c2410fb.c16
-rw-r--r--drivers/video/s3fb.c16
-rw-r--r--drivers/video/sa1100fb.c8
-rw-r--r--drivers/video/savage/savagefb_driver.c23
-rw-r--r--drivers/video/sgivwfb.c12
-rw-r--r--drivers/video/sh7760fb.c6
-rw-r--r--drivers/video/sh_mipi_dsi.c73
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c92
-rw-r--r--drivers/video/sh_mobile_lcdcfb.h1
-rw-r--r--drivers/video/sh_mobile_meram.c2
-rw-r--r--drivers/video/sis/sis_main.c140
-rw-r--r--drivers/video/sis/sis_main.h20
-rw-r--r--drivers/video/skeletonfb.c17
-rw-r--r--drivers/video/sm501fb.c16
-rw-r--r--drivers/video/ssd1307fb.c397
-rw-r--r--drivers/video/sstfb.c33
-rw-r--r--drivers/video/sunxvr1000.c10
-rw-r--r--drivers/video/sunxvr2500.c12
-rw-r--r--drivers/video/sunxvr500.c12
-rw-r--r--drivers/video/tcx.c6
-rw-r--r--drivers/video/tdfxfb.c30
-rw-r--r--drivers/video/tgafb.c45
-rw-r--r--drivers/video/tmiofb.c8
-rw-r--r--drivers/video/tridentfb.c28
-rw-r--r--drivers/video/uvesafb.c74
-rw-r--r--drivers/video/vermilion/vermilion.c7
-rw-r--r--drivers/video/vfb.c6
-rw-r--r--drivers/video/vga16fb.c10
-rw-r--r--drivers/video/via/dvi.c10
-rw-r--r--drivers/video/via/dvi.h4
-rw-r--r--drivers/video/via/hw.c22
-rw-r--r--drivers/video/via/hw.h6
-rw-r--r--drivers/video/via/lcd.c12
-rw-r--r--drivers/video/via/lcd.h6
-rw-r--r--drivers/video/via/share.h2
-rw-r--r--drivers/video/via/via-core.c19
-rw-r--r--drivers/video/via/via-gpio.c2
-rw-r--r--drivers/video/via/via_modesetting.c8
-rw-r--r--drivers/video/via/via_modesetting.h6
-rw-r--r--drivers/video/via/viafbdev.c12
-rw-r--r--drivers/video/videomode.c39
-rw-r--r--drivers/video/vt8500lcdfb.c6
-rw-r--r--drivers/video/vt8623fb.c8
-rw-r--r--drivers/video/w100fb.c10
-rw-r--r--drivers/video/wm8505fb.c6
-rw-r--r--drivers/video/wmt_ge_rops.c6
-rw-r--r--drivers/video/xen-fbfront.c7
-rw-r--r--drivers/video/xilinxfb.c8
274 files changed, 12572 insertions, 5574 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index d08d799..4c1546f 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -21,8 +21,6 @@ source "drivers/gpu/vga/Kconfig"
source "drivers/gpu/drm/Kconfig"
-source "drivers/gpu/stub/Kconfig"
-
config VGASTATE
tristate
default n
@@ -33,6 +31,30 @@ config VIDEO_OUTPUT_CONTROL
This framework adds support for low-level control of the video
output switch.
+config DISPLAY_TIMING
+ bool
+
+config VIDEOMODE
+ bool
+
+config OF_DISPLAY_TIMING
+ bool "Enable device tree display timing support"
+ depends on OF
+ select DISPLAY_TIMING
+ help
+ helper to parse display timings from the devicetree
+
+config OF_VIDEOMODE
+ bool "Enable device tree videomode support"
+ depends on OF
+ select VIDEOMODE
+ select OF_DISPLAY_TIMING
+ help
+ helper to get videomodes from the devicetree
+
+config HDMI
+ bool
+
menuconfig FB
tristate "Support for frame buffer devices"
---help---
@@ -364,7 +386,7 @@ config FB_SA1100
Y here.
config FB_IMX
- tristate "Freescale i.MX LCD support"
+ tristate "Freescale i.MX1/21/25/27 LCD support"
depends on FB && IMX_HAVE_PLATFORM_IMX_FB
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -1112,8 +1134,8 @@ config FB_RIVA_BACKLIGHT
Say Y here if you want to control the backlight of your display.
config FB_I740
- tristate "Intel740 support (EXPERIMENTAL)"
- depends on EXPERIMENTAL && FB && PCI
+ tristate "Intel740 support"
+ depends on FB && PCI
select FB_MODE_HELPERS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -1124,8 +1146,8 @@ config FB_I740
This driver supports graphics cards based on Intel740 chip.
config FB_I810
- tristate "Intel 810/815 support (EXPERIMENTAL)"
- depends on EXPERIMENTAL && FB && PCI && X86_32 && AGP_INTEL
+ tristate "Intel 810/815 support"
+ depends on FB && PCI && X86_32 && AGP_INTEL
select FB_MODE_HELPERS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -1187,8 +1209,8 @@ config FB_CARILLO_RANCH
This driver supports the LE80578 (Carillo Ranch) board
config FB_INTEL
- tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support (EXPERIMENTAL)"
- depends on EXPERIMENTAL && FB && PCI && X86 && AGP_INTEL && EXPERT
+ tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support"
+ depends on FB && PCI && X86 && AGP_INTEL && EXPERT
select FB_MODE_HELPERS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -1432,7 +1454,7 @@ config FB_ATY_CT
is at <http://support.ati.com/products/pc/mach64/mach64.html>.
config FB_ATY_GENERIC_LCD
- bool "Mach64 generic LCD support (EXPERIMENTAL)"
+ bool "Mach64 generic LCD support"
depends on FB_ATY_CT
help
Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility,
@@ -1479,7 +1501,7 @@ config FB_S3_DDC
config FB_SAVAGE
tristate "S3 Savage support"
- depends on FB && PCI && EXPERIMENTAL
+ depends on FB && PCI
select FB_MODE_HELPERS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -1633,15 +1655,15 @@ config FB_3DFX
module will be called tdfxfb.
config FB_3DFX_ACCEL
- bool "3Dfx Acceleration functions (EXPERIMENTAL)"
- depends on FB_3DFX && EXPERIMENTAL
+ bool "3Dfx Acceleration functions"
+ depends on FB_3DFX
---help---
This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer
device driver with acceleration functions.
config FB_3DFX_I2C
bool "Enable DDC/I2C support"
- depends on FB_3DFX && EXPERIMENTAL
+ depends on FB_3DFX
select FB_DDC
default y
help
@@ -1714,8 +1736,8 @@ config FB_ARK
and ICS 5342 RAMDAC.
config FB_PM3
- tristate "Permedia3 support (EXPERIMENTAL)"
- depends on FB && PCI && EXPERIMENTAL
+ tristate "Permedia3 support"
+ depends on FB && PCI
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -2025,7 +2047,8 @@ config FB_TMIO_ACCELL
config FB_S3C
tristate "Samsung S3C framebuffer support"
- depends on FB && (S3C_DEV_FB || S5P_DEV_FIMD0)
+ depends on FB && (CPU_S3C2416 || ARCH_S3C64XX || ARCH_S5P64X0 || \
+ ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -2045,7 +2068,7 @@ config FB_S3C_DEBUG_REGWRITE
bool "Debug register writes"
depends on FB_S3C
---help---
- Show all register writes via printk(KERN_DEBUG)
+ Show all register writes via pr_debug()
config FB_S3C2410
tristate "S3C2410 LCD framebuffer support"
@@ -2140,14 +2163,16 @@ config FB_UDL
To compile as a module, choose M here: the module name is udlfb.
config FB_IBM_GXT4500
- tristate "Framebuffer support for IBM GXT4500P adaptor"
+ tristate "Framebuffer support for IBM GXT4000P/4500P/6000P/6500P adaptors"
depends on FB && PPC
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
---help---
- Say Y here to enable support for the IBM GXT4500P display
- adaptor, found on some IBM System P (pSeries) machines.
+ Say Y here to enable support for the IBM GXT4000P/6000P and
+ GXT4500P/6500P display adaptor based on Raster Engine RC1000,
+ found on some IBM System P (pSeries) machines. This driver
+ doesn't use Geometry Engine GT1000.
config FB_PS3
tristate "PS3 GPU framebuffer driver"
@@ -2181,6 +2206,15 @@ config FB_XILINX
framebuffer. ML300 carries a 640*480 LCD display on the board,
ML403 uses a standard DB15 VGA connector.
+config FB_GOLDFISH
+ tristate "Goldfish Framebuffer"
+ depends on FB
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Framebuffer driver for Goldfish Virtual Platform
+
config FB_COBALT
tristate "Cobalt server LCD frame buffer support"
depends on FB && (MIPS_COBALT || MIPS_SEAD3)
@@ -2420,6 +2454,7 @@ config FB_PUV3_UNIGFX
source "drivers/video/omap/Kconfig"
source "drivers/video/omap2/Kconfig"
source "drivers/video/exynos/Kconfig"
+source "drivers/video/mmp/Kconfig"
source "drivers/video/backlight/Kconfig"
if VT
@@ -2442,4 +2477,19 @@ config FB_SH_MOBILE_MERAM
Up to 4 memory channels can be configured, allowing 4 RGB or
2 YCbCr framebuffers to be configured.
+config FB_SSD1307
+ tristate "Solomon SSD1307 framebuffer support"
+ depends on FB && I2C
+ depends on OF
+ depends on GENERIC_GPIO
+ select FB_SYS_FOPS
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_DEFERRED_IO
+ select PWM
+ help
+ This driver implements support for the Solomon SSD1307
+ OLED controller over I2C.
+
endmenu
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 23e948e..9df3873 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -5,6 +5,7 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_VGASTATE) += vgastate.o
+obj-$(CONFIG_HDMI) += hdmi.o
obj-y += fb_notify.o
obj-$(CONFIG_FB) += fb.o
fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
@@ -98,6 +99,7 @@ obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o
obj-$(CONFIG_FB_PVR2) += pvr2fb.o
obj-$(CONFIG_FB_VOODOO1) += sstfb.o
obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
+obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o
obj-$(CONFIG_FB_68328) += 68328fb.o
obj-$(CONFIG_FB_GBE) += gbefb.o
obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
@@ -105,6 +107,7 @@ obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
obj-$(CONFIG_FB_PXA) += pxafb.o
obj-$(CONFIG_FB_PXA168) += pxa168fb.o
obj-$(CONFIG_PXA3XX_GCU) += pxa3xx-gcu.o
+obj-$(CONFIG_MMP_DISP) += mmp/
obj-$(CONFIG_FB_W100) += w100fb.o
obj-$(CONFIG_FB_TMIO) += tmiofb.o
obj-$(CONFIG_FB_AU1100) += au1100fb.o
@@ -161,9 +164,14 @@ obj-$(CONFIG_FB_BFIN_7393) += bfin_adv7393fb.o
obj-$(CONFIG_FB_MX3) += mx3fb.o
obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o
obj-$(CONFIG_FB_MXS) += mxsfb.o
+obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o
# the test framebuffer is last
obj-$(CONFIG_FB_VIRTUAL) += vfb.o
#video output switch sysfs driver
obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
+obj-$(CONFIG_DISPLAY_TIMING) += display_timing.o
+obj-$(CONFIG_OF_DISPLAY_TIMING) += of_display_timing.o
+obj-$(CONFIG_VIDEOMODE) += videomode.o
+obj-$(CONFIG_OF_VIDEOMODE) += of_videomode.o
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index b303f17..6488a73 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -66,7 +66,7 @@
* have. Allow 1% either way on the nominal for TVs.
*/
#define NR_MONTYPES 6
-static struct fb_monspecs monspecs[NR_MONTYPES] __devinitdata = {
+static struct fb_monspecs monspecs[NR_MONTYPES] = {
{ /* TV */
.hfmin = 15469,
.hfmax = 15781,
@@ -874,7 +874,7 @@ static struct fb_ops acornfb_ops = {
/*
* Everything after here is initialisation!!!
*/
-static struct fb_videomode modedb[] __devinitdata = {
+static struct fb_videomode modedb[] = {
{ /* 320x256 @ 50Hz */
NULL, 50, 320, 256, 125000, 92, 62, 35, 19, 38, 2,
FB_SYNC_COMP_HIGH_ACT,
@@ -926,7 +926,7 @@ static struct fb_videomode modedb[] __devinitdata = {
}
};
-static struct fb_videomode acornfb_default_mode __devinitdata = {
+static struct fb_videomode acornfb_default_mode = {
.name = NULL,
.refresh = 60,
.xres = 640,
@@ -942,7 +942,7 @@ static struct fb_videomode acornfb_default_mode __devinitdata = {
.vmode = FB_VMODE_NONINTERLACED
};
-static void __devinit acornfb_init_fbinfo(void)
+static void acornfb_init_fbinfo(void)
{
static int first = 1;
@@ -1018,7 +1018,7 @@ static void __devinit acornfb_init_fbinfo(void)
* size can optionally be followed by 'M' or 'K' for
* MB or KB respectively.
*/
-static void __devinit acornfb_parse_mon(char *opt)
+static void acornfb_parse_mon(char *opt)
{
char *p = opt;
@@ -1065,7 +1065,7 @@ bad:
current_par.montype = -1;
}
-static void __devinit acornfb_parse_montype(char *opt)
+static void acornfb_parse_montype(char *opt)
{
current_par.montype = -2;
@@ -1106,7 +1106,7 @@ static void __devinit acornfb_parse_montype(char *opt)
}
}
-static void __devinit acornfb_parse_dram(char *opt)
+static void acornfb_parse_dram(char *opt)
{
unsigned int size;
@@ -1131,14 +1131,14 @@ static void __devinit acornfb_parse_dram(char *opt)
static struct options {
char *name;
void (*parse)(char *opt);
-} opt_table[] __devinitdata = {
+} opt_table[] = {
{ "mon", acornfb_parse_mon },
{ "montype", acornfb_parse_montype },
{ "dram", acornfb_parse_dram },
{ NULL, NULL }
};
-static int __devinit acornfb_setup(char *options)
+static int acornfb_setup(char *options)
{
struct options *optp;
char *opt;
@@ -1175,7 +1175,7 @@ static int __devinit acornfb_setup(char *options)
* Detect type of monitor connected
* For now, we just assume SVGA
*/
-static int __devinit acornfb_detect_monitortype(void)
+static int acornfb_detect_monitortype(void)
{
return 4;
}
@@ -1216,7 +1216,7 @@ free_unused_pages(unsigned int virtual_start, unsigned int virtual_end)
printk("acornfb: freed %dK memory\n", mb_freed);
}
-static int __devinit acornfb_probe(struct platform_device *dev)
+static int acornfb_probe(struct platform_device *dev)
{
unsigned long size;
u_int h_sync, v_sync;
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index 4659d5d..e43401a 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -79,7 +79,7 @@ struct arcfb_par {
spinlock_t lock;
};
-static struct fb_fix_screeninfo arcfb_fix __devinitdata = {
+static struct fb_fix_screeninfo arcfb_fix = {
.id = "arcfb",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_MONO01,
@@ -89,7 +89,7 @@ static struct fb_fix_screeninfo arcfb_fix __devinitdata = {
.accel = FB_ACCEL_NONE,
};
-static struct fb_var_screeninfo arcfb_var __devinitdata = {
+static struct fb_var_screeninfo arcfb_var = {
.xres = 128,
.yres = 64,
.xres_virtual = 128,
@@ -502,7 +502,7 @@ static struct fb_ops arcfb_ops = {
.fb_ioctl = arcfb_ioctl,
};
-static int __devinit arcfb_probe(struct platform_device *dev)
+static int arcfb_probe(struct platform_device *dev)
{
struct fb_info *info;
int retval = -ENOMEM;
@@ -587,7 +587,7 @@ err:
return retval;
}
-static int __devexit arcfb_remove(struct platform_device *dev)
+static int arcfb_remove(struct platform_device *dev)
{
struct fb_info *info = platform_get_drvdata(dev);
@@ -601,7 +601,7 @@ static int __devexit arcfb_remove(struct platform_device *dev)
static struct platform_driver arcfb_driver = {
.probe = arcfb_probe,
- .remove = __devexit_p(arcfb_remove),
+ .remove = arcfb_remove,
.driver = {
.name = "arcfb",
},
diff --git a/drivers/video/arkfb.c b/drivers/video/arkfb.c
index 555dd4c..94a51f1 100644
--- a/drivers/video/arkfb.c
+++ b/drivers/video/arkfb.c
@@ -100,7 +100,7 @@ static const struct svga_timing_regs ark_timing_regs = {
/* Module parameters */
-static char *mode_option __devinitdata = "640x480-8@60";
+static char *mode_option = "640x480-8@60";
#ifdef CONFIG_MTRR
static int mtrr = 1;
@@ -950,7 +950,7 @@ static struct fb_ops arkfb_ops = {
/* PCI probe */
-static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+static int ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct pci_bus_region bus_reg;
struct resource vga_res;
@@ -1086,7 +1086,7 @@ err_enable_device:
/* PCI remove */
-static void __devexit ark_pci_remove(struct pci_dev *dev)
+static void ark_pci_remove(struct pci_dev *dev)
{
struct fb_info *info = pci_get_drvdata(dev);
@@ -1184,7 +1184,7 @@ fail:
/* List of boards that we are trying to support */
-static struct pci_device_id ark_devices[] __devinitdata = {
+static struct pci_device_id ark_devices[] = {
{PCI_DEVICE(0xEDD8, 0xA099)},
{0, 0, 0, 0, 0, 0, 0}
};
@@ -1196,7 +1196,7 @@ static struct pci_driver arkfb_pci_driver = {
.name = "arkfb",
.id_table = ark_devices,
.probe = ark_pci_probe,
- .remove = __devexit_p(ark_pci_remove),
+ .remove = ark_pci_remove,
.suspend = ark_pci_suspend,
.resume = ark_pci_resume,
};
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c
index 8cdf88e..d5a37d6 100644
--- a/drivers/video/asiliantfb.c
+++ b/drivers/video/asiliantfb.c
@@ -451,7 +451,7 @@ static struct chips_init_reg chips_init_xr[] =
{0xd1, 0x01},
};
-static void __devinit chips_hw_init(struct fb_info *p)
+static void chips_hw_init(struct fb_info *p)
{
int i;
@@ -474,7 +474,7 @@ static void __devinit chips_hw_init(struct fb_info *p)
write_fr(chips_init_fr[i].addr, chips_init_fr[i].data);
}
-static struct fb_fix_screeninfo asiliantfb_fix __devinitdata = {
+static struct fb_fix_screeninfo asiliantfb_fix = {
.id = "Asiliant 69000",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
@@ -483,7 +483,7 @@ static struct fb_fix_screeninfo asiliantfb_fix __devinitdata = {
.smem_len = 0x200000, /* 2MB */
};
-static struct fb_var_screeninfo asiliantfb_var __devinitdata = {
+static struct fb_var_screeninfo asiliantfb_var = {
.xres = 640,
.yres = 480,
.xres_virtual = 640,
@@ -504,7 +504,7 @@ static struct fb_var_screeninfo asiliantfb_var __devinitdata = {
.vsync_len = 2,
};
-static int __devinit init_asiliant(struct fb_info *p, unsigned long addr)
+static int init_asiliant(struct fb_info *p, unsigned long addr)
{
int err;
@@ -535,8 +535,8 @@ static int __devinit init_asiliant(struct fb_info *p, unsigned long addr)
return 0;
}
-static int __devinit
-asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
+static int asiliantfb_pci_init(struct pci_dev *dp,
+ const struct pci_device_id *ent)
{
unsigned long addr, size;
struct fb_info *p;
@@ -581,7 +581,7 @@ asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
return 0;
}
-static void __devexit asiliantfb_remove(struct pci_dev *dp)
+static void asiliantfb_remove(struct pci_dev *dp)
{
struct fb_info *p = pci_get_drvdata(dp);
@@ -593,7 +593,7 @@ static void __devexit asiliantfb_remove(struct pci_dev *dp)
framebuffer_release(p);
}
-static struct pci_device_id asiliantfb_pci_tbl[] __devinitdata = {
+static struct pci_device_id asiliantfb_pci_tbl[] = {
{ PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69000, PCI_ANY_ID, PCI_ANY_ID },
{ 0 }
};
@@ -604,7 +604,7 @@ static struct pci_driver asiliantfb_driver = {
.name = "asiliantfb",
.id_table = asiliantfb_pci_tbl,
.probe = asiliantfb_pci_init,
- .remove = __devexit_p(asiliantfb_remove),
+ .remove = asiliantfb_remove,
};
static int __init asiliantfb_init(void)
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 94cac9f..12cf5f3 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -19,8 +19,8 @@
#include <linux/backlight.h>
#include <linux/gfp.h>
#include <linux/module.h>
+#include <linux/platform_data/atmel.h>
-#include <mach/board.h>
#include <mach/cpu.h>
#include <asm/gpio.h>
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 0fefa84..8c55011 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -98,7 +98,7 @@
#ifndef CONFIG_PPC_PMAC
/* default mode */
-static struct fb_var_screeninfo default_var __devinitdata = {
+static struct fb_var_screeninfo default_var = {
/* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
640, 480, 640, 480, 0, 0, 8, 0,
{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
@@ -121,7 +121,7 @@ static struct fb_var_screeninfo default_var = {
/* default modedb mode */
/* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
-static struct fb_videomode defaultmode __devinitdata = {
+static struct fb_videomode defaultmode = {
.refresh = 60,
.xres = 640,
.yres = 480,
@@ -149,7 +149,7 @@ enum {
};
/* Must match above enum */
-static char * const r128_family[] __devinitconst = {
+static char * const r128_family[] = {
"AGP",
"PCI",
"PRO AGP",
@@ -275,7 +275,7 @@ static struct pci_driver aty128fb_driver = {
.name = "aty128fb",
.id_table = aty128_pci_tbl,
.probe = aty128_probe,
- .remove = __devexit_p(aty128_remove),
+ .remove = aty128_remove,
.suspend = aty128_pci_suspend,
.resume = aty128_pci_resume,
};
@@ -333,7 +333,7 @@ static const struct aty128_meminfo sdr_sgram =
static const struct aty128_meminfo ddr_sgram =
{ 4, 4, 3, 3, 2, 3, 1, 16, 31, 16, "64-bit DDR SGRAM" };
-static struct fb_fix_screeninfo aty128fb_fix __devinitdata = {
+static struct fb_fix_screeninfo aty128fb_fix = {
.id = "ATY Rage128",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
@@ -343,24 +343,24 @@ static struct fb_fix_screeninfo aty128fb_fix __devinitdata = {
.accel = FB_ACCEL_ATI_RAGE128,
};
-static char *mode_option __devinitdata = NULL;
+static char *mode_option = NULL;
#ifdef CONFIG_PPC_PMAC
-static int default_vmode __devinitdata = VMODE_1024_768_60;
-static int default_cmode __devinitdata = CMODE_8;
+static int default_vmode = VMODE_1024_768_60;
+static int default_cmode = CMODE_8;
#endif
-static int default_crt_on __devinitdata = 0;
-static int default_lcd_on __devinitdata = 1;
+static int default_crt_on = 0;
+static int default_lcd_on = 1;
#ifdef CONFIG_MTRR
static bool mtrr = true;
#endif
#ifdef CONFIG_PMAC_BACKLIGHT
-static int backlight __devinitdata = 1;
+static int backlight = 1;
#else
-static int backlight __devinitdata = 0;
+static int backlight = 0;
#endif
/* PLL constants */
@@ -449,10 +449,9 @@ static int aty128_encode_var(struct fb_var_screeninfo *var,
static int aty128_decode_var(struct fb_var_screeninfo *var,
struct aty128fb_par *par);
#if 0
-static void __devinit aty128_get_pllinfo(struct aty128fb_par *par,
- void __iomem *bios);
-static void __devinit __iomem *aty128_map_ROM(struct pci_dev *pdev,
- const struct aty128fb_par *par);
+static void aty128_get_pllinfo(struct aty128fb_par *par, void __iomem *bios);
+static void __iomem *aty128_map_ROM(struct pci_dev *pdev,
+ const struct aty128fb_par *par);
#endif
static void aty128_timings(struct aty128fb_par *par);
static void aty128_init_engine(struct aty128fb_par *par);
@@ -582,7 +581,7 @@ static void aty_pll_writeupdate(const struct aty128fb_par *par)
/* write to the scratch register to test r/w functionality */
-static int __devinit register_test(const struct aty128fb_par *par)
+static int register_test(const struct aty128fb_par *par)
{
u32 val;
int flag = 0;
@@ -781,8 +780,8 @@ static u32 depth_to_dst(u32 depth)
#ifndef __sparc__
-static void __iomem * __devinit aty128_map_ROM(const struct aty128fb_par *par,
- struct pci_dev *dev)
+static void __iomem *aty128_map_ROM(const struct aty128fb_par *par,
+ struct pci_dev *dev)
{
u16 dptr;
u8 rom_type;
@@ -868,8 +867,8 @@ static void __iomem * __devinit aty128_map_ROM(const struct aty128fb_par *par,
return NULL;
}
-static void __devinit aty128_get_pllinfo(struct aty128fb_par *par,
- unsigned char __iomem *bios)
+static void aty128_get_pllinfo(struct aty128fb_par *par,
+ unsigned char __iomem *bios)
{
unsigned int bios_hdr;
unsigned int bios_pll;
@@ -891,7 +890,7 @@ static void __devinit aty128_get_pllinfo(struct aty128fb_par *par,
}
#ifdef CONFIG_X86
-static void __iomem * __devinit aty128_find_mem_vbios(struct aty128fb_par *par)
+static void __iomem *aty128_find_mem_vbios(struct aty128fb_par *par)
{
/* I simplified this code as we used to miss the signatures in
* a lot of case. It's now closer to XFree, we just don't check
@@ -916,7 +915,7 @@ static void __iomem * __devinit aty128_find_mem_vbios(struct aty128fb_par *par)
#endif /* ndef(__sparc__) */
/* fill in known card constants if pll_block is not available */
-static void __devinit aty128_timings(struct aty128fb_par *par)
+static void aty128_timings(struct aty128fb_par *par)
{
#ifdef CONFIG_PPC_OF
/* instead of a table lookup, assume OF has properly
@@ -1658,7 +1657,7 @@ static int aty128fb_sync(struct fb_info *info)
}
#ifndef MODULE
-static int __devinit aty128fb_setup(char *options)
+static int aty128fb_setup(char *options)
{
char *this_opt;
@@ -1888,8 +1887,7 @@ static void aty128_early_resume(void *data)
}
#endif /* CONFIG_PPC_PMAC */
-static int __devinit aty128_init(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct aty128fb_par *par = info->par;
@@ -2039,8 +2037,7 @@ static int __devinit aty128_init(struct pci_dev *pdev,
#ifdef CONFIG_PCI
/* register a card ++ajoshi */
-static int __devinit aty128_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
unsigned long fb_addr, reg_addr;
struct aty128fb_par *par;
@@ -2156,7 +2153,7 @@ err_free_fb:
return -ENODEV;
}
-static void __devexit aty128_remove(struct pci_dev *pdev)
+static void aty128_remove(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct aty128fb_par *par;
@@ -2558,7 +2555,7 @@ static int aty128_pci_resume(struct pci_dev *pdev)
}
-static int __devinit aty128fb_init(void)
+static int aty128fb_init(void)
{
#ifndef MODULE
char *option = NULL;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 868932f..4f27fdc 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -214,7 +214,7 @@ struct pci_mmap_map {
unsigned long prot_mask;
};
-static struct fb_fix_screeninfo atyfb_fix __devinitdata = {
+static struct fb_fix_screeninfo atyfb_fix = {
.id = "ATY Mach64",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
@@ -309,18 +309,18 @@ static int vram;
static int pll;
static int mclk;
static int xclk;
-static int comp_sync __devinitdata = -1;
+static int comp_sync = -1;
static char *mode;
#ifdef CONFIG_PMAC_BACKLIGHT
-static int backlight __devinitdata = 1;
+static int backlight = 1;
#else
-static int backlight __devinitdata = 0;
+static int backlight = 0;
#endif
#ifdef CONFIG_PPC
-static int default_vmode __devinitdata = VMODE_CHOOSE;
-static int default_cmode __devinitdata = CMODE_CHOOSE;
+static int default_vmode = VMODE_CHOOSE;
+static int default_cmode = CMODE_CHOOSE;
module_param_named(vmode, default_vmode, int, 0);
MODULE_PARM_DESC(vmode, "int: video mode for mac");
@@ -329,10 +329,10 @@ MODULE_PARM_DESC(cmode, "int: color mode for mac");
#endif
#ifdef CONFIG_ATARI
-static unsigned int mach64_count __devinitdata = 0;
-static unsigned long phys_vmembase[FB_MAX] __devinitdata = { 0, };
-static unsigned long phys_size[FB_MAX] __devinitdata = { 0, };
-static unsigned long phys_guiregbase[FB_MAX] __devinitdata = { 0, };
+static unsigned int mach64_count = 0;
+static unsigned long phys_vmembase[FB_MAX] = { 0, };
+static unsigned long phys_size[FB_MAX] = { 0, };
+static unsigned long phys_guiregbase[FB_MAX] = { 0, };
#endif
/* top -> down is an evolution of mach64 chipset, any corrections? */
@@ -371,7 +371,7 @@ static struct {
const char *name;
int pll, mclk, xclk, ecp_max;
u32 features;
-} aty_chips[] __devinitdata = {
+} aty_chips[] = {
#ifdef CONFIG_FB_ATY_GX
/* Mach64 GX */
{ PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, 0, ATI_CHIP_88800GX },
@@ -426,7 +426,7 @@ static struct {
#endif /* CONFIG_FB_ATY_CT */
};
-static int __devinit correct_chipset(struct atyfb_par *par)
+static int correct_chipset(struct atyfb_par *par)
{
u8 rev;
u16 type;
@@ -531,34 +531,34 @@ static int __devinit correct_chipset(struct atyfb_par *par)
return 0;
}
-static char ram_dram[] __devinitdata = "DRAM";
-static char ram_resv[] __devinitdata = "RESV";
+static char ram_dram[] = "DRAM";
+static char ram_resv[] = "RESV";
#ifdef CONFIG_FB_ATY_GX
-static char ram_vram[] __devinitdata = "VRAM";
+static char ram_vram[] = "VRAM";
#endif /* CONFIG_FB_ATY_GX */
#ifdef CONFIG_FB_ATY_CT
-static char ram_edo[] __devinitdata = "EDO";
-static char ram_sdram[] __devinitdata = "SDRAM (1:1)";
-static char ram_sgram[] __devinitdata = "SGRAM (1:1)";
-static char ram_sdram32[] __devinitdata = "SDRAM (2:1) (32-bit)";
-static char ram_wram[] __devinitdata = "WRAM";
-static char ram_off[] __devinitdata = "OFF";
+static char ram_edo[] = "EDO";
+static char ram_sdram[] = "SDRAM (1:1)";
+static char ram_sgram[] = "SGRAM (1:1)";
+static char ram_sdram32[] = "SDRAM (2:1) (32-bit)";
+static char ram_wram[] = "WRAM";
+static char ram_off[] = "OFF";
#endif /* CONFIG_FB_ATY_CT */
#ifdef CONFIG_FB_ATY_GX
-static char *aty_gx_ram[8] __devinitdata = {
+static char *aty_gx_ram[8] = {
ram_dram, ram_vram, ram_vram, ram_dram,
ram_dram, ram_vram, ram_vram, ram_resv
};
#endif /* CONFIG_FB_ATY_GX */
#ifdef CONFIG_FB_ATY_CT
-static char *aty_ct_ram[8] __devinitdata = {
+static char *aty_ct_ram[8] = {
ram_off, ram_dram, ram_edo, ram_edo,
ram_sdram, ram_sgram, ram_wram, ram_resv
};
-static char *aty_xl_ram[8] __devinitdata = {
+static char *aty_xl_ram[8] = {
ram_off, ram_dram, ram_edo, ram_edo,
ram_sdram, ram_sgram, ram_sdram32, ram_resv
};
@@ -588,7 +588,7 @@ static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var,
* Apple monitor sense
*/
-static int __devinit read_aty_sense(const struct atyfb_par *par)
+static int read_aty_sense(const struct atyfb_par *par)
{
int sense, i;
@@ -2273,7 +2273,7 @@ static void aty_bl_exit(struct backlight_device *bd)
#endif /* CONFIG_FB_ATY_BACKLIGHT */
-static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
+static void aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
{
const int ragepro_tbl[] = {
44, 50, 55, 66, 75, 80, 100
@@ -2307,8 +2307,8 @@ static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
static struct fb_info *fb_list = NULL;
#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
-static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par,
- struct fb_var_screeninfo *var)
+static int atyfb_get_timings_from_lcd(struct atyfb_par *par,
+ struct fb_var_screeninfo *var)
{
int ret = -EINVAL;
@@ -2333,7 +2333,7 @@ static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par,
}
#endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */
-static int __devinit aty_init(struct fb_info *info)
+static int aty_init(struct fb_info *info)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
const char *ramname = NULL, *xtal;
@@ -2787,7 +2787,7 @@ aty_init_exit:
}
#if defined(CONFIG_ATARI) && !defined(MODULE)
-static int __devinit store_video_par(char *video_str, unsigned char m64_num)
+static int store_video_par(char *video_str, unsigned char m64_num)
{
char *p;
unsigned long vmembase, size, guiregbase;
@@ -2961,9 +2961,8 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
#ifdef __sparc__
-static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
- struct fb_info *info,
- unsigned long addr)
+static int atyfb_setup_sparc(struct pci_dev *pdev, struct fb_info *info,
+ unsigned long addr)
{
struct atyfb_par *par = info->par;
struct device_node *dp;
@@ -3161,7 +3160,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
#ifdef __i386__
#ifdef CONFIG_FB_ATY_GENERIC_LCD
-static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base)
+static void aty_init_lcd(struct atyfb_par *par, u32 bios_base)
{
u32 driv_inf_tab, sig;
u16 lcd_ofs;
@@ -3392,7 +3391,7 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base)
}
#endif /* CONFIG_FB_ATY_GENERIC_LCD */
-static int __devinit init_from_bios(struct atyfb_par *par)
+static int init_from_bios(struct atyfb_par *par)
{
u32 bios_base, rom_addr;
int ret;
@@ -3445,9 +3444,8 @@ static int __devinit init_from_bios(struct atyfb_par *par)
}
#endif /* __i386__ */
-static int __devinit atyfb_setup_generic(struct pci_dev *pdev,
- struct fb_info *info,
- unsigned long addr)
+static int atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info,
+ unsigned long addr)
{
struct atyfb_par *par = info->par;
u16 tmp;
@@ -3525,8 +3523,8 @@ atyfb_setup_generic_fail:
#endif /* !__sparc__ */
-static int __devinit atyfb_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int atyfb_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
unsigned long addr, res_start, res_size;
struct fb_info *info;
@@ -3714,7 +3712,7 @@ static int __init atyfb_atari_probe(void)
#ifdef CONFIG_PCI
-static void __devexit atyfb_remove(struct fb_info *info)
+static void atyfb_remove(struct fb_info *info)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
@@ -3762,7 +3760,7 @@ static void __devexit atyfb_remove(struct fb_info *info)
}
-static void __devexit atyfb_pci_remove(struct pci_dev *pdev)
+static void atyfb_pci_remove(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
@@ -3834,7 +3832,7 @@ static struct pci_driver atyfb_driver = {
.name = "atyfb",
.id_table = atyfb_pci_tbl,
.probe = atyfb_pci_probe,
- .remove = __devexit_p(atyfb_pci_remove),
+ .remove = atyfb_pci_remove,
#ifdef CONFIG_PM
.suspend = atyfb_pci_suspend,
.resume = atyfb_pci_resume,
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c
index 2745b85..51f29d6 100644
--- a/drivers/video/aty/mach64_ct.c
+++ b/drivers/video/aty/mach64_ct.c
@@ -373,8 +373,7 @@ void aty_set_pll_ct(const struct fb_info *info, const union aty_pll *pll)
#endif
}
-static void __devinit aty_get_pll_ct(const struct fb_info *info,
- union aty_pll *pll)
+static void aty_get_pll_ct(const struct fb_info *info, union aty_pll *pll)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
u8 tmp, clock;
@@ -397,8 +396,7 @@ static void __devinit aty_get_pll_ct(const struct fb_info *info,
}
}
-static int __devinit aty_init_pll_ct(const struct fb_info *info,
- union aty_pll *pll)
+static int aty_init_pll_ct(const struct fb_info *info, union aty_pll *pll)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
u8 mpost_div, xpost_div, sclk_post_div_real;
diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c
index 46f72ed..95ec042 100644
--- a/drivers/video/aty/mach64_cursor.c
+++ b/drivers/video/aty/mach64_cursor.c
@@ -183,7 +183,7 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
return 0;
}
-int __devinit aty_init_cursor(struct fb_info *info)
+int aty_init_cursor(struct fb_info *info)
{
unsigned long addr;
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 9e279ee..1e30b2b 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -293,7 +293,7 @@ static void radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev)
pci_unmap_rom(dev, rinfo->bios_seg);
}
-static int __devinit radeon_map_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev)
+static int radeon_map_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev)
{
void __iomem *rom;
u16 dptr;
@@ -388,7 +388,7 @@ static int __devinit radeon_map_ROM(struct radeonfb_info *rinfo, struct pci_dev
}
#ifdef CONFIG_X86
-static int __devinit radeon_find_mem_vbios(struct radeonfb_info *rinfo)
+static int radeon_find_mem_vbios(struct radeonfb_info *rinfo)
{
/* I simplified this code as we used to miss the signatures in
* a lot of case. It's now closer to XFree, we just don't check
@@ -423,7 +423,7 @@ static int __devinit radeon_find_mem_vbios(struct radeonfb_info *rinfo)
* Read XTAL (ref clock), SCLK and MCLK from Open Firmware device
* tree. Hopefully, ATI OF driver is kind enough to fill these
*/
-static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo)
+static int radeon_read_xtal_OF(struct radeonfb_info *rinfo)
{
struct device_node *dp = rinfo->of_node;
const u32 *val;
@@ -453,7 +453,7 @@ static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo)
/*
* Read PLL infos from chip registers
*/
-static int __devinit radeon_probe_pll_params(struct radeonfb_info *rinfo)
+static int radeon_probe_pll_params(struct radeonfb_info *rinfo)
{
unsigned char ppll_div_sel;
unsigned Ns, Nm, M;
@@ -591,7 +591,7 @@ static int __devinit radeon_probe_pll_params(struct radeonfb_info *rinfo)
/*
* Retrieve PLL infos by different means (BIOS, Open Firmware, register probing...)
*/
-static void __devinit radeon_get_pllinfo(struct radeonfb_info *rinfo)
+static void radeon_get_pllinfo(struct radeonfb_info *rinfo)
{
/*
* In the case nothing works, these are defaults; they are mostly
@@ -1868,7 +1868,7 @@ static struct fb_ops radeonfb_ops = {
};
-static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
+static int radeon_set_fbinfo(struct radeonfb_info *rinfo)
{
struct fb_info *info = rinfo->info;
@@ -2143,8 +2143,8 @@ static struct bin_attribute edid2_attr = {
};
-static int __devinit radeonfb_pci_register (struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int radeonfb_pci_register(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
struct fb_info *info;
struct radeonfb_info *rinfo;
@@ -2407,7 +2407,7 @@ err_out:
-static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
+static void radeonfb_pci_unregister(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct radeonfb_info *rinfo = info->par;
@@ -2465,7 +2465,7 @@ static struct pci_driver radeonfb_driver = {
.name = "radeonfb",
.id_table = radeonfb_pci_table,
.probe = radeonfb_pci_register,
- .remove = __devexit_p(radeonfb_pci_unregister),
+ .remove = radeonfb_pci_unregister,
#ifdef CONFIG_PM
.suspend = radeonfb_pci_suspend,
.resume = radeonfb_pci_resume,
diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c
index 5c23eac..bc078d5 100644
--- a/drivers/video/aty/radeon_monitor.c
+++ b/drivers/video/aty/radeon_monitor.c
@@ -62,8 +62,8 @@ static char *radeon_get_mon_name(int type)
* models with broken OF probing by hard-coding known EDIDs for some Mac
* laptops internal LVDS panel. (XXX: not done yet)
*/
-static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_EDID,
- int hdno)
+static int radeon_parse_montype_prop(struct device_node *dp, u8 **out_EDID,
+ int hdno)
{
static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID",
"EDID1", "EDID2", NULL };
@@ -115,8 +115,8 @@ static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_
return mt;
}
-static int __devinit radeon_probe_OF_head(struct radeonfb_info *rinfo, int head_no,
- u8 **out_EDID)
+static int radeon_probe_OF_head(struct radeonfb_info *rinfo, int head_no,
+ u8 **out_EDID)
{
struct device_node *dp;
@@ -163,7 +163,7 @@ static int __devinit radeon_probe_OF_head(struct radeonfb_info *rinfo, int head_
#endif /* CONFIG_PPC_OF || CONFIG_SPARC */
-static int __devinit radeon_get_panel_info_BIOS(struct radeonfb_info *rinfo)
+static int radeon_get_panel_info_BIOS(struct radeonfb_info *rinfo)
{
unsigned long tmp, tmp0;
char stmp[30];
@@ -251,7 +251,7 @@ static int __devinit radeon_get_panel_info_BIOS(struct radeonfb_info *rinfo)
* doesn't quite work yet, but it's output is still useful for
* debugging
*/
-static void __devinit radeon_parse_connector_info(struct radeonfb_info *rinfo)
+static void radeon_parse_connector_info(struct radeonfb_info *rinfo)
{
int offset, chips, connectors, tmp, i, conn, type;
@@ -297,7 +297,7 @@ static void __devinit radeon_parse_connector_info(struct radeonfb_info *rinfo)
* as well and currently is only implemented for the CRT DAC, the
* code for the TVDAC is commented out in XFree as "non working"
*/
-static int __devinit radeon_crt_is_connected(struct radeonfb_info *rinfo, int is_crt_dac)
+static int radeon_crt_is_connected(struct radeonfb_info *rinfo, int is_crt_dac)
{
int connected = 0;
@@ -369,8 +369,8 @@ static int __devinit radeon_crt_is_connected(struct radeonfb_info *rinfo, int is
* Parse the "monitor_layout" string if any. This code is mostly
* copied from XFree's radeon driver
*/
-static int __devinit radeon_parse_monitor_layout(struct radeonfb_info *rinfo,
- const char *monitor_layout)
+static int radeon_parse_monitor_layout(struct radeonfb_info *rinfo,
+ const char *monitor_layout)
{
char s1[5], s2[5];
int i = 0, second = 0;
@@ -433,8 +433,8 @@ static int __devinit radeon_parse_monitor_layout(struct radeonfb_info *rinfo,
* try to retrieve EDID. The algorithm here comes from XFree's radeon
* driver
*/
-void __devinit radeon_probe_screens(struct radeonfb_info *rinfo,
- const char *monitor_layout, int ignore_edid)
+void radeon_probe_screens(struct radeonfb_info *rinfo,
+ const char *monitor_layout, int ignore_edid)
{
#ifdef CONFIG_FB_RADEON_I2C
int ddc_crt2_used = 0;
@@ -753,7 +753,7 @@ static int is_powerblade(const char *model)
* Build the modedb for head 1 (head 2 will come later), check panel infos
* from either BIOS or EDID, and pick up the default mode
*/
-void __devinit radeon_check_modes(struct radeonfb_info *rinfo, const char *mode_option)
+void radeon_check_modes(struct radeonfb_info *rinfo, const char *mode_option)
{
struct fb_info * info = rinfo->info;
int has_default_mode = 0;
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index fe3b6ec..ddabaa8 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -83,7 +83,7 @@ struct fb_bitfield rgb_bitfields[][4] =
{ { 8, 4, 0 }, { 4, 4, 0 }, { 0, 4, 0 }, { 0, 0, 0 } },
};
-static struct fb_fix_screeninfo au1100fb_fix __devinitdata = {
+static struct fb_fix_screeninfo au1100fb_fix = {
.id = "AU1100 FB",
.xpanstep = 1,
.ypanstep = 1,
@@ -91,7 +91,7 @@ static struct fb_fix_screeninfo au1100fb_fix __devinitdata = {
.accel = FB_ACCEL_NONE,
};
-static struct fb_var_screeninfo au1100fb_var __devinitdata = {
+static struct fb_var_screeninfo au1100fb_var = {
.activate = FB_ACTIVATE_NOW,
.height = -1,
.width = -1,
@@ -469,7 +469,7 @@ static int au1100fb_setup(struct au1100fb_device *fbdev)
return 0;
}
-static int __devinit au1100fb_drv_probe(struct platform_device *dev)
+static int au1100fb_drv_probe(struct platform_device *dev)
{
struct au1100fb_device *fbdev = NULL;
struct resource *regs_res;
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 7ca79f0..1b59054 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1673,7 +1673,7 @@ out:
}
/* AU1200 LCD controller device driver */
-static int __devinit au1200fb_drv_probe(struct platform_device *dev)
+static int au1200fb_drv_probe(struct platform_device *dev)
{
struct au1200fb_device *fbdev;
struct au1200fb_platdata *pd;
@@ -1798,7 +1798,7 @@ failed:
return ret;
}
-static int __devexit au1200fb_drv_remove(struct platform_device *dev)
+static int au1200fb_drv_remove(struct platform_device *dev)
{
struct au1200fb_platdata *pd = platform_get_drvdata(dev);
struct au1200fb_device *fbdev;
@@ -1876,7 +1876,7 @@ static struct platform_driver au1200fb_driver = {
.pm = AU1200FB_PMOPS,
},
.probe = au1200fb_drv_probe,
- .remove = __devexit_p(au1200fb_drv_remove),
+ .remove = au1200fb_drv_remove,
};
/*-------------------------------------------------------------------------*/
diff --git a/drivers/video/auo_k1900fb.c b/drivers/video/auo_k1900fb.c
index c36cf96..1a9ac6e 100644
--- a/drivers/video/auo_k1900fb.c
+++ b/drivers/video/auo_k1900fb.c
@@ -156,7 +156,7 @@ static bool auok1900fb_need_refresh(struct auok190xfb_par *par)
return (par->update_cnt > 10);
}
-static int __devinit auok1900fb_probe(struct platform_device *pdev)
+static int auok1900fb_probe(struct platform_device *pdev)
{
struct auok190x_init_data init;
struct auok190x_board *board;
@@ -177,14 +177,14 @@ static int __devinit auok1900fb_probe(struct platform_device *pdev)
return auok190x_common_probe(pdev, &init);
}
-static int __devexit auok1900fb_remove(struct platform_device *pdev)
+static int auok1900fb_remove(struct platform_device *pdev)
{
return auok190x_common_remove(pdev);
}
static struct platform_driver auok1900fb_driver = {
.probe = auok1900fb_probe,
- .remove = __devexit_p(auok1900fb_remove),
+ .remove = auok1900fb_remove,
.driver = {
.owner = THIS_MODULE,
.name = "auo_k1900fb",
diff --git a/drivers/video/auo_k1901fb.c b/drivers/video/auo_k1901fb.c
index 1c054c1..d1db165 100644
--- a/drivers/video/auo_k1901fb.c
+++ b/drivers/video/auo_k1901fb.c
@@ -209,7 +209,7 @@ static bool auok1901fb_need_refresh(struct auok190xfb_par *par)
return (par->update_cnt > 10);
}
-static int __devinit auok1901fb_probe(struct platform_device *pdev)
+static int auok1901fb_probe(struct platform_device *pdev)
{
struct auok190x_init_data init;
struct auok190x_board *board;
@@ -230,14 +230,14 @@ static int __devinit auok1901fb_probe(struct platform_device *pdev)
return auok190x_common_probe(pdev, &init);
}
-static int __devexit auok1901fb_remove(struct platform_device *pdev)
+static int auok1901fb_remove(struct platform_device *pdev)
{
return auok190x_common_remove(pdev);
}
static struct platform_driver auok1901fb_driver = {
.probe = auok1901fb_probe,
- .remove = __devexit_p(auok1901fb_remove),
+ .remove = auok1901fb_remove,
.driver = {
.owner = THIS_MODULE,
.name = "auo_k1901fb",
diff --git a/drivers/video/auo_k190x.c b/drivers/video/auo_k190x.c
index c03ecdd..53846cb 100644
--- a/drivers/video/auo_k190x.c
+++ b/drivers/video/auo_k190x.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/gpio.h>
+#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/fb.h>
#include <linux/delay.h>
@@ -773,8 +774,8 @@ EXPORT_SYMBOL_GPL(auok190x_pm);
* Common probe and remove code
*/
-int __devinit auok190x_common_probe(struct platform_device *pdev,
- struct auok190x_init_data *init)
+int auok190x_common_probe(struct platform_device *pdev,
+ struct auok190x_init_data *init)
{
struct auok190x_board *board = init->board;
struct auok190xfb_par *par;
@@ -1006,7 +1007,7 @@ err_reg:
}
EXPORT_SYMBOL_GPL(auok190x_common_probe);
-int __devexit auok190x_common_remove(struct platform_device *pdev)
+int auok190x_common_remove(struct platform_device *pdev)
{
struct fb_info *info = platform_get_drvdata(pdev);
struct auok190xfb_par *par = info->par;
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index b7ec34c..2cd6350 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -117,8 +117,8 @@ static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
data->current_brightness = value;
return 0;
out:
- dev_dbg(chip->dev, "set brightness %d failure with return "
- "value:%d\n", value, ret);
+ dev_dbg(chip->dev, "set brightness %d failure with return value: %d\n",
+ value, ret);
return ret;
}
@@ -165,8 +165,10 @@ static int pm860x_backlight_dt_init(struct platform_device *pdev,
struct pm860x_backlight_data *data,
char *name)
{
- struct device_node *nproot = pdev->dev.parent->of_node, *np;
+ struct device_node *nproot, *np;
int iset = 0;
+
+ nproot = of_node_get(pdev->dev.parent->of_node);
if (!nproot)
return -ENODEV;
nproot = of_find_node_by_name(nproot, "backlights");
@@ -184,6 +186,7 @@ static int pm860x_backlight_dt_init(struct platform_device *pdev,
break;
}
}
+ of_node_put(nproot);
return 0;
}
#else
@@ -208,22 +211,19 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
res = platform_get_resource_byname(pdev, IORESOURCE_REG, "duty cycle");
if (!res) {
dev_err(&pdev->dev, "No REG resource for duty cycle\n");
- ret = -ENXIO;
- goto out;
+ return -ENXIO;
}
data->reg_duty_cycle = res->start;
res = platform_get_resource_byname(pdev, IORESOURCE_REG, "always on");
if (!res) {
dev_err(&pdev->dev, "No REG resorce for always on\n");
- ret = -ENXIO;
- goto out;
+ return -ENXIO;
}
data->reg_always_on = res->start;
res = platform_get_resource_byname(pdev, IORESOURCE_REG, "current");
if (!res) {
dev_err(&pdev->dev, "No REG resource for current\n");
- ret = -ENXIO;
- goto out;
+ return -ENXIO;
}
data->reg_current = res->start;
@@ -231,8 +231,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
sprintf(name, "backlight-%d", pdev->id);
data->port = pdev->id;
data->chip = chip;
- data->i2c = (chip->id == CHIP_PM8606) ? chip->client \
- : chip->companion;
+ data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
data->current_brightness = MAX_BRIGHTNESS;
if (pm860x_backlight_dt_init(pdev, data, name)) {
if (pdata) {
@@ -263,8 +262,6 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
return 0;
out_brt:
backlight_device_unregister(bl);
-out:
- devm_kfree(&pdev->dev, data);
return ret;
}
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 765a945..db10d01 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -126,6 +126,21 @@ config LCD_AMS369FG06
If you have an AMS369FG06 AMOLED Panel, say Y to enable its
LCD control driver.
+config LCD_LMS501KF03
+ tristate "LMS501KF03 LCD Driver"
+ depends on SPI
+ default n
+ help
+ If you have an LMS501KF03 LCD Panel, say Y to enable its
+ LCD control driver.
+
+config LCD_HX8357
+ tristate "Himax HX-8357 LCD Driver"
+ depends on SPI
+ help
+ If you have a HX-8357 LCD panel, say Y to enable its LCD control
+ driver.
+
endif # LCD_CLASS_DEVICE
#
@@ -366,9 +381,15 @@ config BACKLIGHT_LP855X
tristate "Backlight driver for TI LP855X"
depends on BACKLIGHT_CLASS_DEVICE && I2C
help
- This supports TI LP8550, LP8551, LP8552, LP8553 and LP8556
+ This supports TI LP8550, LP8551, LP8552, LP8553, LP8556 and LP8557
backlight driver.
+config BACKLIGHT_LP8788
+ tristate "Backlight driver for TI LP8788 MFD"
+ depends on BACKLIGHT_CLASS_DEVICE && MFD_LP8788
+ help
+ This supports TI LP8788 backlight driver.
+
config BACKLIGHT_OT200
tristate "Backlight driver for ot200 visualisation device"
depends on BACKLIGHT_CLASS_DEVICE && CS5535_MFGPT && GPIO_CS5535
@@ -390,6 +411,13 @@ config BACKLIGHT_TPS65217
If you have a Texas Instruments TPS65217 say Y to enable the
backlight driver.
+config BACKLIGHT_AS3711
+ tristate "AS3711 Backlight"
+ depends on BACKLIGHT_CLASS_DEVICE && MFD_AS3711
+ help
+ If you have an Austrian Microsystems AS3711 say Y to enable the
+ backlight driver.
+
endif # BACKLIGHT_CLASS_DEVICE
endif # BACKLIGHT_LCD_SUPPORT
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index e7ce729..96c4d62 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -1,47 +1,51 @@
# Backlight & LCD drivers
-obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
-obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o
-obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o
-obj-$(CONFIG_LCD_L4F00242T03) += l4f00242t03.o
-obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o
-obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
-obj-$(CONFIG_LCD_ILI9320) += ili9320.o
-obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o
-obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o
-obj-$(CONFIG_LCD_TDO24M) += tdo24m.o
-obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o
-obj-$(CONFIG_LCD_S6E63M0) += s6e63m0.o
-obj-$(CONFIG_LCD_LD9040) += ld9040.o
-obj-$(CONFIG_LCD_AMS369FG06) += ams369fg06.o
+obj-$(CONFIG_LCD_AMS369FG06) += ams369fg06.o
+obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
+obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o
+obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o
+obj-$(CONFIG_LCD_HX8357) += hx8357.o
+obj-$(CONFIG_LCD_ILI9320) += ili9320.o
+obj-$(CONFIG_LCD_L4F00242T03) += l4f00242t03.o
+obj-$(CONFIG_LCD_LD9040) += ld9040.o
+obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o
+obj-$(CONFIG_LCD_LMS501KF03) += lms501kf03.o
+obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
+obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o
+obj-$(CONFIG_LCD_S6E63M0) += s6e63m0.o
+obj-$(CONFIG_LCD_TDO24M) += tdo24m.o
+obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o
+obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o
-obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
-obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o
-obj-$(CONFIG_BACKLIGHT_EP93XX) += ep93xx_bl.o
-obj-$(CONFIG_BACKLIGHT_GENERIC) += generic_bl.o
-obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o
-obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
-obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o
-obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
-obj-$(CONFIG_BACKLIGHT_LM3630) += lm3630_bl.o
-obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o
-obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o
-obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
-obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o
-obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
-obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
-obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
-obj-$(CONFIG_BACKLIGHT_DA9052) += da9052_bl.o
-obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o
-obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o
-obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
-obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
-obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
-obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o
-obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o
-obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o
-obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
+obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
+obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o
+obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o
+obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o
+obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o
+obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o
+obj-$(CONFIG_BACKLIGHT_AS3711) += as3711_bl.o
+obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o
+obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
+obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
+obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
+obj-$(CONFIG_BACKLIGHT_DA9052) += da9052_bl.o
+obj-$(CONFIG_BACKLIGHT_EP93XX) += ep93xx_bl.o
+obj-$(CONFIG_BACKLIGHT_GENERIC) += generic_bl.o
+obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
+obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o
+obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o
+obj-$(CONFIG_BACKLIGHT_LM3630) += lm3630_bl.o
+obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o
+obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
+obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o
+obj-$(CONFIG_BACKLIGHT_LP8788) += lp8788_bl.o
+obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o
+obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
+obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o
+obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o
obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o
-obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o
-obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o
-obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o
+obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
+obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
+obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
+obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o
+obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
diff --git a/drivers/video/backlight/aat2870_bl.c b/drivers/video/backlight/aat2870_bl.c
index 7ff7522..c6fc668 100644
--- a/drivers/video/backlight/aat2870_bl.c
+++ b/drivers/video/backlight/aat2870_bl.c
@@ -74,7 +74,7 @@ static int aat2870_bl_get_brightness(struct backlight_device *bd)
static int aat2870_bl_update_status(struct backlight_device *bd)
{
- struct aat2870_bl_driver_data *aat2870_bl = dev_get_drvdata(&bd->dev);
+ struct aat2870_bl_driver_data *aat2870_bl = bl_get_data(bd);
struct aat2870_data *aat2870 =
dev_get_drvdata(aat2870_bl->pdev->dev.parent);
int brightness = bd->props.brightness;
diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c
index df5db99..a1e41d4 100644
--- a/drivers/video/backlight/adp5520_bl.c
+++ b/drivers/video/backlight/adp5520_bl.c
@@ -282,7 +282,7 @@ static const struct attribute_group adp5520_bl_attr_group = {
.attrs = adp5520_bl_attributes,
};
-static int __devinit adp5520_bl_probe(struct platform_device *pdev)
+static int adp5520_bl_probe(struct platform_device *pdev)
{
struct backlight_properties props;
struct backlight_device *bl;
@@ -333,7 +333,7 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit adp5520_bl_remove(struct platform_device *pdev)
+static int adp5520_bl_remove(struct platform_device *pdev)
{
struct backlight_device *bl = platform_get_drvdata(pdev);
struct adp5520_bl *data = bl_get_data(bl);
@@ -375,7 +375,7 @@ static struct platform_driver adp5520_bl_driver = {
.owner = THIS_MODULE,
},
.probe = adp5520_bl_probe,
- .remove = __devexit_p(adp5520_bl_remove),
+ .remove = adp5520_bl_remove,
.suspend = adp5520_bl_suspend,
.resume = adp5520_bl_resume,
};
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c
index 77d1fdb..a77c9ca 100644
--- a/drivers/video/backlight/adp8860_bl.c
+++ b/drivers/video/backlight/adp8860_bl.c
@@ -213,7 +213,7 @@ static int adp8860_led_setup(struct adp8860_led *led)
return ret;
}
-static int __devinit adp8860_led_probe(struct i2c_client *client)
+static int adp8860_led_probe(struct i2c_client *client)
{
struct adp8860_backlight_platform_data *pdata =
client->dev.platform_data;
@@ -295,7 +295,7 @@ static int __devinit adp8860_led_probe(struct i2c_client *client)
return ret;
}
-static int __devexit adp8860_led_remove(struct i2c_client *client)
+static int adp8860_led_remove(struct i2c_client *client)
{
struct adp8860_backlight_platform_data *pdata =
client->dev.platform_data;
@@ -310,12 +310,12 @@ static int __devexit adp8860_led_remove(struct i2c_client *client)
return 0;
}
#else
-static int __devinit adp8860_led_probe(struct i2c_client *client)
+static int adp8860_led_probe(struct i2c_client *client)
{
return 0;
}
-static int __devexit adp8860_led_remove(struct i2c_client *client)
+static int adp8860_led_remove(struct i2c_client *client)
{
return 0;
}
@@ -650,7 +650,7 @@ static const struct attribute_group adp8860_bl_attr_group = {
.attrs = adp8860_bl_attributes,
};
-static int __devinit adp8860_probe(struct i2c_client *client,
+static int adp8860_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct backlight_device *bl;
@@ -755,7 +755,7 @@ out1:
return ret;
}
-static int __devexit adp8860_remove(struct i2c_client *client)
+static int adp8860_remove(struct i2c_client *client)
{
struct adp8860_bl *data = i2c_get_clientdata(client);
@@ -783,7 +783,7 @@ static int adp8860_i2c_suspend(struct i2c_client *client, pm_message_t message)
static int adp8860_i2c_resume(struct i2c_client *client)
{
- adp8860_set_bits(client, ADP8860_MDCR, NSTBY);
+ adp8860_set_bits(client, ADP8860_MDCR, NSTBY | BLEN);
return 0;
}
@@ -805,7 +805,7 @@ static struct i2c_driver adp8860_driver = {
.name = KBUILD_MODNAME,
},
.probe = adp8860_probe,
- .remove = __devexit_p(adp8860_remove),
+ .remove = adp8860_remove,
.suspend = adp8860_i2c_suspend,
.resume = adp8860_i2c_resume,
.id_table = adp8860_id,
diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c
index edf7f91..712c25a 100644
--- a/drivers/video/backlight/adp8870_bl.c
+++ b/drivers/video/backlight/adp8870_bl.c
@@ -235,7 +235,7 @@ static int adp8870_led_setup(struct adp8870_led *led)
return ret;
}
-static int __devinit adp8870_led_probe(struct i2c_client *client)
+static int adp8870_led_probe(struct i2c_client *client)
{
struct adp8870_backlight_platform_data *pdata =
client->dev.platform_data;
@@ -320,7 +320,7 @@ static int __devinit adp8870_led_probe(struct i2c_client *client)
return ret;
}
-static int __devexit adp8870_led_remove(struct i2c_client *client)
+static int adp8870_led_remove(struct i2c_client *client)
{
struct adp8870_backlight_platform_data *pdata =
client->dev.platform_data;
@@ -335,12 +335,12 @@ static int __devexit adp8870_led_remove(struct i2c_client *client)
return 0;
}
#else
-static int __devinit adp8870_led_probe(struct i2c_client *client)
+static int adp8870_led_probe(struct i2c_client *client)
{
return 0;
}
-static int __devexit adp8870_led_remove(struct i2c_client *client)
+static int adp8870_led_remove(struct i2c_client *client)
{
return 0;
}
@@ -839,7 +839,7 @@ static const struct attribute_group adp8870_bl_attr_group = {
.attrs = adp8870_bl_attributes,
};
-static int __devinit adp8870_probe(struct i2c_client *client,
+static int adp8870_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct backlight_properties props;
@@ -929,7 +929,7 @@ out1:
return ret;
}
-static int __devexit adp8870_remove(struct i2c_client *client)
+static int adp8870_remove(struct i2c_client *client)
{
struct adp8870_bl *data = i2c_get_clientdata(client);
@@ -957,7 +957,7 @@ static int adp8870_i2c_suspend(struct i2c_client *client, pm_message_t message)
static int adp8870_i2c_resume(struct i2c_client *client)
{
- adp8870_set_bits(client, ADP8870_MDCR, NSTBY);
+ adp8870_set_bits(client, ADP8870_MDCR, NSTBY | BLEN);
return 0;
}
@@ -977,7 +977,7 @@ static struct i2c_driver adp8870_driver = {
.name = KBUILD_MODNAME,
},
.probe = adp8870_probe,
- .remove = __devexit_p(adp8870_remove),
+ .remove = adp8870_remove,
.suspend = adp8870_i2c_suspend,
.resume = adp8870_i2c_resume,
.id_table = adp8870_id,
diff --git a/drivers/video/backlight/ams369fg06.c b/drivers/video/backlight/ams369fg06.c
index 3729238..c02aa2c 100644
--- a/drivers/video/backlight/ams369fg06.c
+++ b/drivers/video/backlight/ams369fg06.c
@@ -10,25 +10,16 @@
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <linux/fb.h>
+#include <linux/backlight.h>
#include <linux/delay.h>
+#include <linux/fb.h>
#include <linux/gpio.h>
-#include <linux/spi/spi.h>
#include <linux/lcd.h>
-#include <linux/backlight.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/wait.h>
#define SLEEPMSEC 0x1000
#define ENDDEF 0x2000
@@ -210,8 +201,9 @@ static int ams369fg06_panel_send_sequence(struct ams369fg06 *lcd,
ret = ams369fg06_spi_write(lcd, wbuf[i], wbuf[i+1]);
if (ret)
break;
- } else
- mdelay(wbuf[i+1]);
+ } else {
+ msleep(wbuf[i+1]);
+ }
i += 2;
}
@@ -313,41 +305,29 @@ static int ams369fg06_ldi_disable(struct ams369fg06 *lcd)
static int ams369fg06_power_is_on(int power)
{
- return ((power) <= FB_BLANK_NORMAL);
+ return power <= FB_BLANK_NORMAL;
}
static int ams369fg06_power_on(struct ams369fg06 *lcd)
{
int ret = 0;
- struct lcd_platform_data *pd = NULL;
- struct backlight_device *bd = NULL;
+ struct lcd_platform_data *pd;
+ struct backlight_device *bd;
pd = lcd->lcd_pd;
- if (!pd) {
- dev_err(lcd->dev, "platform data is NULL.\n");
- return -EFAULT;
- }
-
bd = lcd->bd;
- if (!bd) {
- dev_err(lcd->dev, "backlight device is NULL.\n");
- return -EFAULT;
- }
- if (!pd->power_on) {
- dev_err(lcd->dev, "power_on is NULL.\n");
- return -EFAULT;
- } else {
+ if (pd->power_on) {
pd->power_on(lcd->ld, 1);
- mdelay(pd->power_on_delay);
+ msleep(pd->power_on_delay);
}
if (!pd->reset) {
dev_err(lcd->dev, "reset is NULL.\n");
- return -EFAULT;
+ return -EINVAL;
} else {
pd->reset(lcd->ld);
- mdelay(pd->reset_delay);
+ msleep(pd->reset_delay);
}
ret = ams369fg06_ldi_init(lcd);
@@ -374,14 +354,10 @@ static int ams369fg06_power_on(struct ams369fg06 *lcd)
static int ams369fg06_power_off(struct ams369fg06 *lcd)
{
- int ret = 0;
- struct lcd_platform_data *pd = NULL;
+ int ret;
+ struct lcd_platform_data *pd;
pd = lcd->lcd_pd;
- if (!pd) {
- dev_err(lcd->dev, "platform data is NULL\n");
- return -EFAULT;
- }
ret = ams369fg06_ldi_disable(lcd);
if (ret) {
@@ -389,12 +365,9 @@ static int ams369fg06_power_off(struct ams369fg06 *lcd)
return -EIO;
}
- mdelay(pd->power_off_delay);
+ msleep(pd->power_off_delay);
- if (!pd->power_on) {
- dev_err(lcd->dev, "power_on is NULL.\n");
- return -EFAULT;
- } else
+ if (pd->power_on)
pd->power_on(lcd->ld, 0);
return 0;
@@ -446,7 +419,7 @@ static int ams369fg06_set_brightness(struct backlight_device *bd)
{
int ret = 0;
int brightness = bd->props.brightness;
- struct ams369fg06 *lcd = dev_get_drvdata(&bd->dev);
+ struct ams369fg06 *lcd = bl_get_data(bd);
if (brightness < MIN_BRIGHTNESS ||
brightness > bd->props.max_brightness) {
@@ -474,7 +447,7 @@ static const struct backlight_ops ams369fg06_backlight_ops = {
.update_status = ams369fg06_set_brightness,
};
-static int __devinit ams369fg06_probe(struct spi_device *spi)
+static int ams369fg06_probe(struct spi_device *spi)
{
int ret = 0;
struct ams369fg06 *lcd = NULL;
@@ -501,7 +474,7 @@ static int __devinit ams369fg06_probe(struct spi_device *spi)
lcd->lcd_pd = spi->dev.platform_data;
if (!lcd->lcd_pd) {
dev_err(&spi->dev, "platform data is NULL\n");
- return -EFAULT;
+ return -EINVAL;
}
ld = lcd_device_register("ams369fg06", &spi->dev, lcd,
@@ -534,10 +507,11 @@ static int __devinit ams369fg06_probe(struct spi_device *spi)
lcd->power = FB_BLANK_POWERDOWN;
ams369fg06_power(lcd, FB_BLANK_UNBLANK);
- } else
+ } else {
lcd->power = FB_BLANK_UNBLANK;
+ }
- dev_set_drvdata(&spi->dev, lcd);
+ spi_set_drvdata(spi, lcd);
dev_info(&spi->dev, "ams369fg06 panel driver has been probed.\n");
@@ -548,9 +522,9 @@ out_lcd_unregister:
return ret;
}
-static int __devexit ams369fg06_remove(struct spi_device *spi)
+static int ams369fg06_remove(struct spi_device *spi)
{
- struct ams369fg06 *lcd = dev_get_drvdata(&spi->dev);
+ struct ams369fg06 *lcd = spi_get_drvdata(spi);
ams369fg06_power(lcd, FB_BLANK_POWERDOWN);
backlight_device_unregister(lcd->bd);
@@ -560,44 +534,26 @@ static int __devexit ams369fg06_remove(struct spi_device *spi)
}
#if defined(CONFIG_PM)
-static unsigned int before_power;
-
static int ams369fg06_suspend(struct spi_device *spi, pm_message_t mesg)
{
- int ret = 0;
- struct ams369fg06 *lcd = dev_get_drvdata(&spi->dev);
+ struct ams369fg06 *lcd = spi_get_drvdata(spi);
dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
- before_power = lcd->power;
-
/*
* when lcd panel is suspend, lcd panel becomes off
* regardless of status.
*/
- ret = ams369fg06_power(lcd, FB_BLANK_POWERDOWN);
-
- return ret;
+ return ams369fg06_power(lcd, FB_BLANK_POWERDOWN);
}
static int ams369fg06_resume(struct spi_device *spi)
{
- int ret = 0;
- struct ams369fg06 *lcd = dev_get_drvdata(&spi->dev);
+ struct ams369fg06 *lcd = spi_get_drvdata(spi);
- /*
- * after suspended, if lcd panel status is FB_BLANK_UNBLANK
- * (at that time, before_power is FB_BLANK_UNBLANK) then
- * it changes that status to FB_BLANK_POWERDOWN to get lcd on.
- */
- if (before_power == FB_BLANK_UNBLANK)
- lcd->power = FB_BLANK_POWERDOWN;
-
- dev_dbg(&spi->dev, "before_power = %d\n", before_power);
+ lcd->power = FB_BLANK_POWERDOWN;
- ret = ams369fg06_power(lcd, before_power);
-
- return ret;
+ return ams369fg06_power(lcd, FB_BLANK_UNBLANK);
}
#else
#define ams369fg06_suspend NULL
@@ -606,7 +562,7 @@ static int ams369fg06_resume(struct spi_device *spi)
static void ams369fg06_shutdown(struct spi_device *spi)
{
- struct ams369fg06 *lcd = dev_get_drvdata(&spi->dev);
+ struct ams369fg06 *lcd = spi_get_drvdata(spi);
ams369fg06_power(lcd, FB_BLANK_POWERDOWN);
}
@@ -617,7 +573,7 @@ static struct spi_driver ams369fg06_driver = {
.owner = THIS_MODULE,
},
.probe = ams369fg06_probe,
- .remove = __devexit_p(ams369fg06_remove),
+ .remove = ams369fg06_remove,
.shutdown = ams369fg06_shutdown,
.suspend = ams369fg06_suspend,
.resume = ams369fg06_resume,
diff --git a/drivers/video/backlight/apple_bl.c b/drivers/video/backlight/apple_bl.c
index 9dc73ac..d843296 100644
--- a/drivers/video/backlight/apple_bl.c
+++ b/drivers/video/backlight/apple_bl.c
@@ -137,7 +137,7 @@ static const struct hw_data nvidia_chipset_data = {
.set_brightness = nvidia_chipset_set_brightness,
};
-static int __devinit apple_bl_add(struct acpi_device *dev)
+static int apple_bl_add(struct acpi_device *dev)
{
struct backlight_properties props;
struct pci_dev *host;
@@ -196,7 +196,7 @@ static int __devinit apple_bl_add(struct acpi_device *dev)
return 0;
}
-static int __devexit apple_bl_remove(struct acpi_device *dev, int type)
+static int apple_bl_remove(struct acpi_device *dev)
{
backlight_device_unregister(apple_backlight_device);
diff --git a/drivers/video/backlight/as3711_bl.c b/drivers/video/backlight/as3711_bl.c
new file mode 100644
index 0000000..41d52fe
--- /dev/null
+++ b/drivers/video/backlight/as3711_bl.c
@@ -0,0 +1,380 @@
+/*
+ * AS3711 PMIC backlight driver, using DCDC Step Up Converters
+ *
+ * Copyright (C) 2012 Renesas Electronics Corporation
+ * Author: Guennadi Liakhovetski, <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License as
+ * published by the Free Software Foundation
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/kernel.h>
+#include <linux/mfd/as3711.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+enum as3711_bl_type {
+ AS3711_BL_SU1,
+ AS3711_BL_SU2,
+};
+
+struct as3711_bl_data {
+ bool powered;
+ const char *fb_name;
+ struct device *fb_dev;
+ enum as3711_bl_type type;
+ int brightness;
+ struct backlight_device *bl;
+};
+
+struct as3711_bl_supply {
+ struct as3711_bl_data su1;
+ struct as3711_bl_data su2;
+ const struct as3711_bl_pdata *pdata;
+ struct as3711 *as3711;
+};
+
+static struct as3711_bl_supply *to_supply(struct as3711_bl_data *su)
+{
+ switch (su->type) {
+ case AS3711_BL_SU1:
+ return container_of(su, struct as3711_bl_supply, su1);
+ case AS3711_BL_SU2:
+ return container_of(su, struct as3711_bl_supply, su2);
+ }
+ return NULL;
+}
+
+static int as3711_set_brightness_auto_i(struct as3711_bl_data *data,
+ unsigned int brightness)
+{
+ struct as3711_bl_supply *supply = to_supply(data);
+ struct as3711 *as3711 = supply->as3711;
+ const struct as3711_bl_pdata *pdata = supply->pdata;
+ int ret = 0;
+
+ /* Only all equal current values are supported */
+ if (pdata->su2_auto_curr1)
+ ret = regmap_write(as3711->regmap, AS3711_CURR1_VALUE,
+ brightness);
+ if (!ret && pdata->su2_auto_curr2)
+ ret = regmap_write(as3711->regmap, AS3711_CURR2_VALUE,
+ brightness);
+ if (!ret && pdata->su2_auto_curr3)
+ ret = regmap_write(as3711->regmap, AS3711_CURR3_VALUE,
+ brightness);
+
+ return ret;
+}
+
+static int as3711_set_brightness_v(struct as3711 *as3711,
+ unsigned int brightness,
+ unsigned int reg)
+{
+ if (brightness > 31)
+ return -EINVAL;
+
+ return regmap_update_bits(as3711->regmap, reg, 0xf0,
+ brightness << 4);
+}
+
+static int as3711_bl_su2_reset(struct as3711_bl_supply *supply)
+{
+ struct as3711 *as3711 = supply->as3711;
+ int ret = regmap_update_bits(as3711->regmap, AS3711_STEPUP_CONTROL_5,
+ 3, supply->pdata->su2_fbprot);
+ if (!ret)
+ ret = regmap_update_bits(as3711->regmap,
+ AS3711_STEPUP_CONTROL_2, 1, 0);
+ if (!ret)
+ ret = regmap_update_bits(as3711->regmap,
+ AS3711_STEPUP_CONTROL_2, 1, 1);
+ return ret;
+}
+
+/*
+ * Someone with less fragile or less expensive hardware could try to simplify
+ * the brightness adjustment procedure.
+ */
+static int as3711_bl_update_status(struct backlight_device *bl)
+{
+ struct as3711_bl_data *data = bl_get_data(bl);
+ struct as3711_bl_supply *supply = to_supply(data);
+ struct as3711 *as3711 = supply->as3711;
+ int brightness = bl->props.brightness;
+ int ret = 0;
+
+ dev_dbg(&bl->dev, "%s(): brightness %u, pwr %x, blank %x, state %x\n",
+ __func__, bl->props.brightness, bl->props.power,
+ bl->props.fb_blank, bl->props.state);
+
+ if (bl->props.power != FB_BLANK_UNBLANK ||
+ bl->props.fb_blank != FB_BLANK_UNBLANK ||
+ bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
+ brightness = 0;
+
+ if (data->type == AS3711_BL_SU1) {
+ ret = as3711_set_brightness_v(as3711, brightness,
+ AS3711_STEPUP_CONTROL_1);
+ } else {
+ const struct as3711_bl_pdata *pdata = supply->pdata;
+
+ switch (pdata->su2_feedback) {
+ case AS3711_SU2_VOLTAGE:
+ ret = as3711_set_brightness_v(as3711, brightness,
+ AS3711_STEPUP_CONTROL_2);
+ break;
+ case AS3711_SU2_CURR_AUTO:
+ ret = as3711_set_brightness_auto_i(data, brightness / 4);
+ if (ret < 0)
+ return ret;
+ if (brightness) {
+ ret = as3711_bl_su2_reset(supply);
+ if (ret < 0)
+ return ret;
+ udelay(500);
+ ret = as3711_set_brightness_auto_i(data, brightness);
+ } else {
+ ret = regmap_update_bits(as3711->regmap,
+ AS3711_STEPUP_CONTROL_2, 1, 0);
+ }
+ break;
+ /* Manual one current feedback pin below */
+ case AS3711_SU2_CURR1:
+ ret = regmap_write(as3711->regmap, AS3711_CURR1_VALUE,
+ brightness);
+ break;
+ case AS3711_SU2_CURR2:
+ ret = regmap_write(as3711->regmap, AS3711_CURR2_VALUE,
+ brightness);
+ break;
+ case AS3711_SU2_CURR3:
+ ret = regmap_write(as3711->regmap, AS3711_CURR3_VALUE,
+ brightness);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ }
+ if (!ret)
+ data->brightness = brightness;
+
+ return ret;
+}
+
+static int as3711_bl_get_brightness(struct backlight_device *bl)
+{
+ struct as3711_bl_data *data = bl_get_data(bl);
+
+ return data->brightness;
+}
+
+static const struct backlight_ops as3711_bl_ops = {
+ .update_status = as3711_bl_update_status,
+ .get_brightness = as3711_bl_get_brightness,
+};
+
+static int as3711_bl_init_su2(struct as3711_bl_supply *supply)
+{
+ struct as3711 *as3711 = supply->as3711;
+ const struct as3711_bl_pdata *pdata = supply->pdata;
+ u8 ctl = 0;
+ int ret;
+
+ dev_dbg(as3711->dev, "%s(): use %u\n", __func__, pdata->su2_feedback);
+
+ /* Turn SU2 off */
+ ret = regmap_write(as3711->regmap, AS3711_STEPUP_CONTROL_2, 0);
+ if (ret < 0)
+ return ret;
+
+ switch (pdata->su2_feedback) {
+ case AS3711_SU2_VOLTAGE:
+ ret = regmap_update_bits(as3711->regmap, AS3711_STEPUP_CONTROL_4, 3, 0);
+ break;
+ case AS3711_SU2_CURR1:
+ ctl = 1;
+ ret = regmap_update_bits(as3711->regmap, AS3711_STEPUP_CONTROL_4, 3, 1);
+ break;
+ case AS3711_SU2_CURR2:
+ ctl = 4;
+ ret = regmap_update_bits(as3711->regmap, AS3711_STEPUP_CONTROL_4, 3, 2);
+ break;
+ case AS3711_SU2_CURR3:
+ ctl = 0x10;
+ ret = regmap_update_bits(as3711->regmap, AS3711_STEPUP_CONTROL_4, 3, 3);
+ break;
+ case AS3711_SU2_CURR_AUTO:
+ if (pdata->su2_auto_curr1)
+ ctl = 2;
+ if (pdata->su2_auto_curr2)
+ ctl |= 8;
+ if (pdata->su2_auto_curr3)
+ ctl |= 0x20;
+ ret = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (!ret)
+ ret = regmap_write(as3711->regmap, AS3711_CURR_CONTROL, ctl);
+
+ return ret;
+}
+
+static int as3711_bl_register(struct platform_device *pdev,
+ unsigned int max_brightness, struct as3711_bl_data *su)
+{
+ struct backlight_properties props = {.type = BACKLIGHT_RAW,};
+ struct backlight_device *bl;
+
+ /* max tuning I = 31uA for voltage- and 38250uA for current-feedback */
+ props.max_brightness = max_brightness;
+
+ bl = backlight_device_register(su->type == AS3711_BL_SU1 ?
+ "as3711-su1" : "as3711-su2",
+ &pdev->dev, su,
+ &as3711_bl_ops, &props);
+ if (IS_ERR(bl)) {
+ dev_err(&pdev->dev, "failed to register backlight\n");
+ return PTR_ERR(bl);
+ }
+
+ bl->props.brightness = props.max_brightness;
+
+ backlight_update_status(bl);
+
+ su->bl = bl;
+
+ return 0;
+}
+
+static int as3711_backlight_probe(struct platform_device *pdev)
+{
+ struct as3711_bl_pdata *pdata = dev_get_platdata(&pdev->dev);
+ struct as3711 *as3711 = dev_get_drvdata(pdev->dev.parent);
+ struct as3711_bl_supply *supply;
+ struct as3711_bl_data *su;
+ unsigned int max_brightness;
+ int ret;
+
+ if (!pdata || (!pdata->su1_fb && !pdata->su2_fb)) {
+ dev_err(&pdev->dev, "No platform data, exiting...\n");
+ return -ENODEV;
+ }
+
+ /*
+ * Due to possible hardware damage I chose to block all modes,
+ * unsupported on my hardware. Anyone, wishing to use any of those modes
+ * will have to first review the code, then activate and test it.
+ */
+ if (pdata->su1_fb ||
+ pdata->su2_fbprot != AS3711_SU2_GPIO4 ||
+ pdata->su2_feedback != AS3711_SU2_CURR_AUTO) {
+ dev_warn(&pdev->dev,
+ "Attention! An untested mode has been chosen!\n"
+ "Please, review the code, enable, test, and report success:-)\n");
+ return -EINVAL;
+ }
+
+ supply = devm_kzalloc(&pdev->dev, sizeof(*supply), GFP_KERNEL);
+ if (!supply)
+ return -ENOMEM;
+
+ supply->as3711 = as3711;
+ supply->pdata = pdata;
+
+ if (pdata->su1_fb) {
+ su = &supply->su1;
+ su->fb_name = pdata->su1_fb;
+ su->type = AS3711_BL_SU1;
+
+ max_brightness = min(pdata->su1_max_uA, 31);
+ ret = as3711_bl_register(pdev, max_brightness, su);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (pdata->su2_fb) {
+ su = &supply->su2;
+ su->fb_name = pdata->su2_fb;
+ su->type = AS3711_BL_SU2;
+
+ switch (pdata->su2_fbprot) {
+ case AS3711_SU2_GPIO2:
+ case AS3711_SU2_GPIO3:
+ case AS3711_SU2_GPIO4:
+ case AS3711_SU2_LX_SD4:
+ break;
+ default:
+ ret = -EINVAL;
+ goto esu2;
+ }
+
+ switch (pdata->su2_feedback) {
+ case AS3711_SU2_VOLTAGE:
+ max_brightness = min(pdata->su2_max_uA, 31);
+ break;
+ case AS3711_SU2_CURR1:
+ case AS3711_SU2_CURR2:
+ case AS3711_SU2_CURR3:
+ case AS3711_SU2_CURR_AUTO:
+ max_brightness = min(pdata->su2_max_uA / 150, 255);
+ break;
+ default:
+ ret = -EINVAL;
+ goto esu2;
+ }
+
+ ret = as3711_bl_init_su2(supply);
+ if (ret < 0)
+ return ret;
+
+ ret = as3711_bl_register(pdev, max_brightness, su);
+ if (ret < 0)
+ goto esu2;
+ }
+
+ platform_set_drvdata(pdev, supply);
+
+ return 0;
+
+esu2:
+ backlight_device_unregister(supply->su1.bl);
+ return ret;
+}
+
+static int as3711_backlight_remove(struct platform_device *pdev)
+{
+ struct as3711_bl_supply *supply = platform_get_drvdata(pdev);
+
+ backlight_device_unregister(supply->su1.bl);
+ backlight_device_unregister(supply->su2.bl);
+
+ return 0;
+}
+
+static struct platform_driver as3711_backlight_driver = {
+ .driver = {
+ .name = "as3711-backlight",
+ .owner = THIS_MODULE,
+ },
+ .probe = as3711_backlight_probe,
+ .remove = as3711_backlight_remove,
+};
+
+module_platform_driver(as3711_backlight_driver);
+
+MODULE_DESCRIPTION("Backlight Driver for AS3711 PMICs");
+MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:as3711-backlight");
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index df1cbb7..de5e5e7 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -106,10 +106,9 @@ static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl)
pwm_channel_writel(&pwmbl->pwmc, PWM_CPRD,
pwmbl->pdata->pwm_compare_max);
- dev_info(&pwmbl->pdev->dev, "Atmel PWM backlight driver "
- "(%lu Hz)\n", pwmbl->pwmc.mck /
- pwmbl->pdata->pwm_compare_max /
- (1 << prescale));
+ dev_info(&pwmbl->pdev->dev, "Atmel PWM backlight driver (%lu Hz)\n",
+ pwmbl->pwmc.mck / pwmbl->pdata->pwm_compare_max /
+ (1 << prescale));
return pwm_channel_enable(&pwmbl->pwmc);
}
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 297db2f..c74e7aa 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -370,6 +370,35 @@ void backlight_device_unregister(struct backlight_device *bd)
}
EXPORT_SYMBOL(backlight_device_unregister);
+#ifdef CONFIG_OF
+static int of_parent_match(struct device *dev, const void *data)
+{
+ return dev->parent && dev->parent->of_node == data;
+}
+
+/**
+ * of_find_backlight_by_node() - find backlight device by device-tree node
+ * @node: device-tree node of the backlight device
+ *
+ * Returns a pointer to the backlight device corresponding to the given DT
+ * node or NULL if no such backlight device exists or if the device hasn't
+ * been probed yet.
+ *
+ * This function obtains a reference on the backlight device and it is the
+ * caller's responsibility to drop the reference by calling put_device() on
+ * the backlight device's .dev field.
+ */
+struct backlight_device *of_find_backlight_by_node(struct device_node *node)
+{
+ struct device *dev;
+
+ dev = class_find_device(backlight_class, NULL, node, of_parent_match);
+
+ return dev ? to_backlight_device(dev) : NULL;
+}
+EXPORT_SYMBOL(of_find_backlight_by_node);
+#endif
+
static void __exit backlight_class_exit(void)
{
class_destroy(backlight_class);
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c
index c781768..aa782f3 100644
--- a/drivers/video/backlight/corgi_lcd.c
+++ b/drivers/video/backlight/corgi_lcd.c
@@ -6,8 +6,8 @@
* Based on Sharp's 2.4 Backlight Driver
*
* Copyright (c) 2008 Marvell International Ltd.
- * Converted to SPI device based LCD/Backlight device driver
- * by Eric Miao <eric.miao@marvell.com>
+ * Converted to SPI device based LCD/Backlight device driver
+ * by Eric Miao <eric.miao@marvell.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -192,7 +192,7 @@ static void lcdtg_set_phadadj(struct corgi_lcd *lcd, int mode)
{
int adj;
- switch(mode) {
+ switch (mode) {
case CORGI_LCD_MODE_VGA:
/* Setting for VGA */
adj = sharpsl_param.phadadj;
@@ -337,7 +337,7 @@ static void corgi_lcd_power_off(struct corgi_lcd *lcd)
static int corgi_lcd_set_mode(struct lcd_device *ld, struct fb_videomode *m)
{
- struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev);
+ struct corgi_lcd *lcd = lcd_get_data(ld);
int mode = CORGI_LCD_MODE_QVGA;
if (m->xres == 640 || m->xres == 480)
@@ -364,7 +364,7 @@ static int corgi_lcd_set_mode(struct lcd_device *ld, struct fb_videomode *m)
static int corgi_lcd_set_power(struct lcd_device *ld, int power)
{
- struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev);
+ struct corgi_lcd *lcd = lcd_get_data(ld);
if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
corgi_lcd_power_on(lcd);
@@ -378,7 +378,7 @@ static int corgi_lcd_set_power(struct lcd_device *ld, int power)
static int corgi_lcd_get_power(struct lcd_device *ld)
{
- struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev);
+ struct corgi_lcd *lcd = lcd_get_data(ld);
return lcd->power;
}
@@ -391,7 +391,7 @@ static struct lcd_ops corgi_lcd_ops = {
static int corgi_bl_get_intensity(struct backlight_device *bd)
{
- struct corgi_lcd *lcd = dev_get_drvdata(&bd->dev);
+ struct corgi_lcd *lcd = bl_get_data(bd);
return lcd->intensity;
}
@@ -409,10 +409,10 @@ static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity)
cont = !!(intensity & 0x20) ^ lcd->gpio_backlight_cont_inverted;
if (gpio_is_valid(lcd->gpio_backlight_cont))
- gpio_set_value(lcd->gpio_backlight_cont, cont);
+ gpio_set_value_cansleep(lcd->gpio_backlight_cont, cont);
if (gpio_is_valid(lcd->gpio_backlight_on))
- gpio_set_value(lcd->gpio_backlight_on, intensity);
+ gpio_set_value_cansleep(lcd->gpio_backlight_on, intensity);
if (lcd->kick_battery)
lcd->kick_battery();
@@ -423,7 +423,7 @@ static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity)
static int corgi_bl_update_status(struct backlight_device *bd)
{
- struct corgi_lcd *lcd = dev_get_drvdata(&bd->dev);
+ struct corgi_lcd *lcd = bl_get_data(bd);
int intensity = bd->props.brightness;
if (bd->props.power != FB_BLANK_UNBLANK)
@@ -460,7 +460,7 @@ static const struct backlight_ops corgi_bl_ops = {
#ifdef CONFIG_PM
static int corgi_lcd_suspend(struct spi_device *spi, pm_message_t state)
{
- struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev);
+ struct corgi_lcd *lcd = spi_get_drvdata(spi);
corgibl_flags |= CORGIBL_SUSPENDED;
corgi_bl_set_intensity(lcd, 0);
@@ -470,7 +470,7 @@ static int corgi_lcd_suspend(struct spi_device *spi, pm_message_t state)
static int corgi_lcd_resume(struct spi_device *spi)
{
- struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev);
+ struct corgi_lcd *lcd = spi_get_drvdata(spi);
corgibl_flags &= ~CORGIBL_SUSPENDED;
corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK);
@@ -495,8 +495,9 @@ static int setup_gpio_backlight(struct corgi_lcd *lcd,
err = devm_gpio_request(&spi->dev, pdata->gpio_backlight_on,
"BL_ON");
if (err) {
- dev_err(&spi->dev, "failed to request GPIO%d for "
- "backlight_on\n", pdata->gpio_backlight_on);
+ dev_err(&spi->dev,
+ "failed to request GPIO%d for backlight_on\n",
+ pdata->gpio_backlight_on);
return err;
}
@@ -508,8 +509,9 @@ static int setup_gpio_backlight(struct corgi_lcd *lcd,
err = devm_gpio_request(&spi->dev, pdata->gpio_backlight_cont,
"BL_CONT");
if (err) {
- dev_err(&spi->dev, "failed to request GPIO%d for "
- "backlight_cont\n", pdata->gpio_backlight_cont);
+ dev_err(&spi->dev,
+ "failed to request GPIO%d for backlight_cont\n",
+ pdata->gpio_backlight_cont);
return err;
}
@@ -529,7 +531,7 @@ static int setup_gpio_backlight(struct corgi_lcd *lcd,
return 0;
}
-static int __devinit corgi_lcd_probe(struct spi_device *spi)
+static int corgi_lcd_probe(struct spi_device *spi)
{
struct backlight_properties props;
struct corgi_lcd_platform_data *pdata = spi->dev.platform_data;
@@ -575,7 +577,7 @@ static int __devinit corgi_lcd_probe(struct spi_device *spi)
lcd->kick_battery = pdata->kick_battery;
- dev_set_drvdata(&spi->dev, lcd);
+ spi_set_drvdata(spi, lcd);
corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK);
backlight_update_status(lcd->bl_dev);
@@ -590,9 +592,9 @@ err_unregister_lcd:
return ret;
}
-static int __devexit corgi_lcd_remove(struct spi_device *spi)
+static int corgi_lcd_remove(struct spi_device *spi)
{
- struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev);
+ struct corgi_lcd *lcd = spi_get_drvdata(spi);
lcd->bl_dev->props.power = FB_BLANK_UNBLANK;
lcd->bl_dev->props.brightness = 0;
@@ -611,7 +613,7 @@ static struct spi_driver corgi_lcd_driver = {
.owner = THIS_MODULE,
},
.probe = corgi_lcd_probe,
- .remove = __devexit_p(corgi_lcd_remove),
+ .remove = corgi_lcd_remove,
.suspend = corgi_lcd_suspend,
.resume = corgi_lcd_resume,
};
diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c
index 573c7ec..8179cef 100644
--- a/drivers/video/backlight/da903x_bl.c
+++ b/drivers/video/backlight/da903x_bl.c
@@ -2,10 +2,10 @@
* Backlight driver for Dialog Semiconductor DA9030/DA9034
*
* Copyright (C) 2008 Compulab, Ltd.
- * Mike Rapoport <mike@compulab.co.il>
+ * Mike Rapoport <mike@compulab.co.il>
*
* Copyright (C) 2006-2008 Marvell International Ltd.
- * Eric Miao <eric.miao@marvell.com>
+ * Eric Miao <eric.miao@marvell.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -164,15 +164,14 @@ static int da903x_backlight_remove(struct platform_device *pdev)
#ifdef CONFIG_PM
static int da903x_backlight_suspend(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct backlight_device *bl = platform_get_drvdata(pdev);
+ struct backlight_device *bl = dev_get_drvdata(dev);
+
return da903x_backlight_set(bl, 0);
}
static int da903x_backlight_resume(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct backlight_device *bl = platform_get_drvdata(pdev);
+ struct backlight_device *bl = dev_get_drvdata(dev);
backlight_update_status(bl);
return 0;
@@ -199,7 +198,7 @@ static struct platform_driver da903x_backlight_driver = {
module_platform_driver(da903x_backlight_driver);
MODULE_DESCRIPTION("Backlight Driver for Dialog Semiconductor DA9030/DA9034");
-MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
- "Mike Rapoport <mike@compulab.co.il>");
+MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
+MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:da903x-backlight");
diff --git a/drivers/video/backlight/da9052_bl.c b/drivers/video/backlight/da9052_bl.c
index ac19618..842da5a 100644
--- a/drivers/video/backlight/da9052_bl.c
+++ b/drivers/video/backlight/da9052_bl.c
@@ -34,7 +34,7 @@ enum {
DA9052_TYPE_WLED3,
};
-static unsigned char wled_bank[] = {
+static const unsigned char wled_bank[] = {
DA9052_LED1_CONF_REG,
DA9052_LED2_CONF_REG,
DA9052_LED3_CONF_REG,
diff --git a/drivers/video/backlight/ep93xx_bl.c b/drivers/video/backlight/ep93xx_bl.c
index 08214e1..ef3e21e 100644
--- a/drivers/video/backlight/ep93xx_bl.c
+++ b/drivers/video/backlight/ep93xx_bl.c
@@ -141,7 +141,7 @@ static struct platform_driver ep93xxbl_driver = {
.owner = THIS_MODULE,
},
.probe = ep93xxbl_probe,
- .remove = __devexit_p(ep93xxbl_remove),
+ .remove = ep93xxbl_remove,
.suspend = ep93xxbl_suspend,
.resume = ep93xxbl_resume,
};
diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c
index 8c660fc..0ae155b 100644
--- a/drivers/video/backlight/generic_bl.c
+++ b/drivers/video/backlight/generic_bl.c
@@ -97,8 +97,8 @@ static int genericbl_probe(struct platform_device *pdev)
props.max_brightness = machinfo->max_intensity;
bd = backlight_device_register(name, &pdev->dev, NULL, &genericbl_ops,
&props);
- if (IS_ERR (bd))
- return PTR_ERR (bd);
+ if (IS_ERR(bd))
+ return PTR_ERR(bd);
platform_set_drvdata(pdev, bd);
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index 38aa002..5cefd73 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -26,7 +26,7 @@
#define HP680_DEFAULT_INTENSITY 10
static int hp680bl_suspended;
-static int current_intensity = 0;
+static int current_intensity;
static DEFINE_SPINLOCK(bl_lock);
static void hp680bl_send_intensity(struct backlight_device *bd)
@@ -103,7 +103,7 @@ static const struct backlight_ops hp680bl_ops = {
.update_status = hp680bl_set_intensity,
};
-static int __devinit hp680bl_probe(struct platform_device *pdev)
+static int hp680bl_probe(struct platform_device *pdev)
{
struct backlight_properties props;
struct backlight_device *bd;
@@ -168,7 +168,7 @@ static int __init hp680bl_init(void)
static void __exit hp680bl_exit(void)
{
platform_device_unregister(hp680bl_device);
- platform_driver_unregister(&hp680bl_driver);
+ platform_driver_unregister(&hp680bl_driver);
}
module_init(hp680bl_init);
diff --git a/drivers/video/backlight/hx8357.c b/drivers/video/backlight/hx8357.c
new file mode 100644
index 0000000..a0482b5
--- /dev/null
+++ b/drivers/video/backlight/hx8357.c
@@ -0,0 +1,497 @@
+/*
+ * Driver for the Himax HX-8357 LCD Controller
+ *
+ * Copyright 2012 Free Electrons
+ *
+ * Licensed under the GPLv2 or later.
+ */
+
+#include <linux/delay.h>
+#include <linux/lcd.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/spi/spi.h>
+
+#define HX8357_NUM_IM_PINS 3
+
+#define HX8357_SWRESET 0x01
+#define HX8357_GET_RED_CHANNEL 0x06
+#define HX8357_GET_GREEN_CHANNEL 0x07
+#define HX8357_GET_BLUE_CHANNEL 0x08
+#define HX8357_GET_POWER_MODE 0x0a
+#define HX8357_GET_MADCTL 0x0b
+#define HX8357_GET_PIXEL_FORMAT 0x0c
+#define HX8357_GET_DISPLAY_MODE 0x0d
+#define HX8357_GET_SIGNAL_MODE 0x0e
+#define HX8357_GET_DIAGNOSTIC_RESULT 0x0f
+#define HX8357_ENTER_SLEEP_MODE 0x10
+#define HX8357_EXIT_SLEEP_MODE 0x11
+#define HX8357_ENTER_PARTIAL_MODE 0x12
+#define HX8357_ENTER_NORMAL_MODE 0x13
+#define HX8357_EXIT_INVERSION_MODE 0x20
+#define HX8357_ENTER_INVERSION_MODE 0x21
+#define HX8357_SET_DISPLAY_OFF 0x28
+#define HX8357_SET_DISPLAY_ON 0x29
+#define HX8357_SET_COLUMN_ADDRESS 0x2a
+#define HX8357_SET_PAGE_ADDRESS 0x2b
+#define HX8357_WRITE_MEMORY_START 0x2c
+#define HX8357_READ_MEMORY_START 0x2e
+#define HX8357_SET_PARTIAL_AREA 0x30
+#define HX8357_SET_SCROLL_AREA 0x33
+#define HX8357_SET_TEAR_OFF 0x34
+#define HX8357_SET_TEAR_ON 0x35
+#define HX8357_SET_ADDRESS_MODE 0x36
+#define HX8357_SET_SCROLL_START 0x37
+#define HX8357_EXIT_IDLE_MODE 0x38
+#define HX8357_ENTER_IDLE_MODE 0x39
+#define HX8357_SET_PIXEL_FORMAT 0x3a
+#define HX8357_SET_PIXEL_FORMAT_DBI_3BIT (0x1)
+#define HX8357_SET_PIXEL_FORMAT_DBI_16BIT (0x5)
+#define HX8357_SET_PIXEL_FORMAT_DBI_18BIT (0x6)
+#define HX8357_SET_PIXEL_FORMAT_DPI_3BIT (0x1 << 4)
+#define HX8357_SET_PIXEL_FORMAT_DPI_16BIT (0x5 << 4)
+#define HX8357_SET_PIXEL_FORMAT_DPI_18BIT (0x6 << 4)
+#define HX8357_WRITE_MEMORY_CONTINUE 0x3c
+#define HX8357_READ_MEMORY_CONTINUE 0x3e
+#define HX8357_SET_TEAR_SCAN_LINES 0x44
+#define HX8357_GET_SCAN_LINES 0x45
+#define HX8357_READ_DDB_START 0xa1
+#define HX8357_SET_DISPLAY_MODE 0xb4
+#define HX8357_SET_DISPLAY_MODE_RGB_THROUGH (0x3)
+#define HX8357_SET_DISPLAY_MODE_RGB_INTERFACE (1 << 4)
+#define HX8357_SET_PANEL_DRIVING 0xc0
+#define HX8357_SET_DISPLAY_FRAME 0xc5
+#define HX8357_SET_RGB 0xc6
+#define HX8357_SET_RGB_ENABLE_HIGH (1 << 1)
+#define HX8357_SET_GAMMA 0xc8
+#define HX8357_SET_POWER 0xd0
+#define HX8357_SET_VCOM 0xd1
+#define HX8357_SET_POWER_NORMAL 0xd2
+#define HX8357_SET_PANEL_RELATED 0xe9
+
+struct hx8357_data {
+ unsigned im_pins[HX8357_NUM_IM_PINS];
+ unsigned reset;
+ struct spi_device *spi;
+ int state;
+};
+
+static u8 hx8357_seq_power[] = {
+ HX8357_SET_POWER, 0x44, 0x41, 0x06,
+};
+
+static u8 hx8357_seq_vcom[] = {
+ HX8357_SET_VCOM, 0x40, 0x10,
+};
+
+static u8 hx8357_seq_power_normal[] = {
+ HX8357_SET_POWER_NORMAL, 0x05, 0x12,
+};
+
+static u8 hx8357_seq_panel_driving[] = {
+ HX8357_SET_PANEL_DRIVING, 0x14, 0x3b, 0x00, 0x02, 0x11,
+};
+
+static u8 hx8357_seq_display_frame[] = {
+ HX8357_SET_DISPLAY_FRAME, 0x0c,
+};
+
+static u8 hx8357_seq_panel_related[] = {
+ HX8357_SET_PANEL_RELATED, 0x01,
+};
+
+static u8 hx8357_seq_undefined1[] = {
+ 0xea, 0x03, 0x00, 0x00,
+};
+
+static u8 hx8357_seq_undefined2[] = {
+ 0xeb, 0x40, 0x54, 0x26, 0xdb,
+};
+
+static u8 hx8357_seq_gamma[] = {
+ HX8357_SET_GAMMA, 0x00, 0x15, 0x00, 0x22, 0x00,
+ 0x08, 0x77, 0x26, 0x77, 0x22, 0x04, 0x00,
+};
+
+static u8 hx8357_seq_address_mode[] = {
+ HX8357_SET_ADDRESS_MODE, 0xc0,
+};
+
+static u8 hx8357_seq_pixel_format[] = {
+ HX8357_SET_PIXEL_FORMAT,
+ HX8357_SET_PIXEL_FORMAT_DPI_18BIT |
+ HX8357_SET_PIXEL_FORMAT_DBI_18BIT,
+};
+
+static u8 hx8357_seq_column_address[] = {
+ HX8357_SET_COLUMN_ADDRESS, 0x00, 0x00, 0x01, 0x3f,
+};
+
+static u8 hx8357_seq_page_address[] = {
+ HX8357_SET_PAGE_ADDRESS, 0x00, 0x00, 0x01, 0xdf,
+};
+
+static u8 hx8357_seq_rgb[] = {
+ HX8357_SET_RGB, 0x02,
+};
+
+static u8 hx8357_seq_display_mode[] = {
+ HX8357_SET_DISPLAY_MODE,
+ HX8357_SET_DISPLAY_MODE_RGB_THROUGH |
+ HX8357_SET_DISPLAY_MODE_RGB_INTERFACE,
+};
+
+static int hx8357_spi_write_then_read(struct lcd_device *lcdev,
+ u8 *txbuf, u16 txlen,
+ u8 *rxbuf, u16 rxlen)
+{
+ struct hx8357_data *lcd = lcd_get_data(lcdev);
+ struct spi_message msg;
+ struct spi_transfer xfer[2];
+ u16 *local_txbuf = NULL;
+ int ret = 0;
+
+ memset(xfer, 0, sizeof(xfer));
+ spi_message_init(&msg);
+
+ if (txlen) {
+ int i;
+
+ local_txbuf = kcalloc(txlen, sizeof(*local_txbuf), GFP_KERNEL);
+
+ if (!local_txbuf)
+ return -ENOMEM;
+
+ for (i = 0; i < txlen; i++) {
+ local_txbuf[i] = txbuf[i];
+ if (i > 0)
+ local_txbuf[i] |= 1 << 8;
+ }
+
+ xfer[0].len = 2 * txlen;
+ xfer[0].bits_per_word = 9;
+ xfer[0].tx_buf = local_txbuf;
+ spi_message_add_tail(&xfer[0], &msg);
+ }
+
+ if (rxlen) {
+ xfer[1].len = rxlen;
+ xfer[1].bits_per_word = 8;
+ xfer[1].rx_buf = rxbuf;
+ spi_message_add_tail(&xfer[1], &msg);
+ }
+
+ ret = spi_sync(lcd->spi, &msg);
+ if (ret < 0)
+ dev_err(&lcdev->dev, "Couldn't send SPI data\n");
+
+ if (txlen)
+ kfree(local_txbuf);
+
+ return ret;
+}
+
+static inline int hx8357_spi_write_array(struct lcd_device *lcdev,
+ u8 *value, u8 len)
+{
+ return hx8357_spi_write_then_read(lcdev, value, len, NULL, 0);
+}
+
+static inline int hx8357_spi_write_byte(struct lcd_device *lcdev,
+ u8 value)
+{
+ return hx8357_spi_write_then_read(lcdev, &value, 1, NULL, 0);
+}
+
+static int hx8357_enter_standby(struct lcd_device *lcdev)
+{
+ int ret;
+
+ ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_OFF);
+ if (ret < 0)
+ return ret;
+
+ usleep_range(10000, 12000);
+
+ ret = hx8357_spi_write_byte(lcdev, HX8357_ENTER_SLEEP_MODE);
+ if (ret < 0)
+ return ret;
+
+ msleep(120);
+
+ return 0;
+}
+
+static int hx8357_exit_standby(struct lcd_device *lcdev)
+{
+ int ret;
+
+ ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
+ if (ret < 0)
+ return ret;
+
+ msleep(120);
+
+ ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int hx8357_lcd_init(struct lcd_device *lcdev)
+{
+ struct hx8357_data *lcd = lcd_get_data(lcdev);
+ int ret;
+
+ /*
+ * Set the interface selection pins to SPI mode, with three
+ * wires
+ */
+ gpio_set_value_cansleep(lcd->im_pins[0], 1);
+ gpio_set_value_cansleep(lcd->im_pins[1], 0);
+ gpio_set_value_cansleep(lcd->im_pins[2], 1);
+
+ /* Reset the screen */
+ gpio_set_value(lcd->reset, 1);
+ usleep_range(10000, 12000);
+ gpio_set_value(lcd->reset, 0);
+ usleep_range(10000, 12000);
+ gpio_set_value(lcd->reset, 1);
+ msleep(120);
+
+ ret = hx8357_spi_write_array(lcdev, hx8357_seq_power,
+ ARRAY_SIZE(hx8357_seq_power));
+ if (ret < 0)
+ return ret;
+
+ ret = hx8357_spi_write_array(lcdev, hx8357_seq_vcom,
+ ARRAY_SIZE(hx8357_seq_vcom));
+ if (ret < 0)
+ return ret;
+
+ ret = hx8357_spi_write_array(lcdev, hx8357_seq_power_normal,
+ ARRAY_SIZE(hx8357_seq_power_normal));
+ if (ret < 0)
+ return ret;
+
+ ret = hx8357_spi_write_array(lcdev, hx8357_seq_panel_driving,
+ ARRAY_SIZE(hx8357_seq_panel_driving));
+ if (ret < 0)
+ return ret;
+
+ ret = hx8357_spi_write_array(lcdev, hx8357_seq_display_frame,
+ ARRAY_SIZE(hx8357_seq_display_frame));
+ if (ret < 0)
+ return ret;
+
+ ret = hx8357_spi_write_array(lcdev, hx8357_seq_panel_related,
+ ARRAY_SIZE(hx8357_seq_panel_related));
+ if (ret < 0)
+ return ret;
+
+ ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined1,
+ ARRAY_SIZE(hx8357_seq_undefined1));
+ if (ret < 0)
+ return ret;
+
+ ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined2,
+ ARRAY_SIZE(hx8357_seq_undefined2));
+ if (ret < 0)
+ return ret;
+
+ ret = hx8357_spi_write_array(lcdev, hx8357_seq_gamma,
+ ARRAY_SIZE(hx8357_seq_gamma));
+ if (ret < 0)
+ return ret;
+
+ ret = hx8357_spi_write_array(lcdev, hx8357_seq_address_mode,
+ ARRAY_SIZE(hx8357_seq_address_mode));
+ if (ret < 0)
+ return ret;
+
+ ret = hx8357_spi_write_array(lcdev, hx8357_seq_pixel_format,
+ ARRAY_SIZE(hx8357_seq_pixel_format));
+ if (ret < 0)
+ return ret;
+
+ ret = hx8357_spi_write_array(lcdev, hx8357_seq_column_address,
+ ARRAY_SIZE(hx8357_seq_column_address));
+ if (ret < 0)
+ return ret;
+
+ ret = hx8357_spi_write_array(lcdev, hx8357_seq_page_address,
+ ARRAY_SIZE(hx8357_seq_page_address));
+ if (ret < 0)
+ return ret;
+
+ ret = hx8357_spi_write_array(lcdev, hx8357_seq_rgb,
+ ARRAY_SIZE(hx8357_seq_rgb));
+ if (ret < 0)
+ return ret;
+
+ ret = hx8357_spi_write_array(lcdev, hx8357_seq_display_mode,
+ ARRAY_SIZE(hx8357_seq_display_mode));
+ if (ret < 0)
+ return ret;
+
+ ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
+ if (ret < 0)
+ return ret;
+
+ msleep(120);
+
+ ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
+ if (ret < 0)
+ return ret;
+
+ usleep_range(5000, 7000);
+
+ ret = hx8357_spi_write_byte(lcdev, HX8357_WRITE_MEMORY_START);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
+
+static int hx8357_set_power(struct lcd_device *lcdev, int power)
+{
+ struct hx8357_data *lcd = lcd_get_data(lcdev);
+ int ret = 0;
+
+ if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->state))
+ ret = hx8357_exit_standby(lcdev);
+ else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->state))
+ ret = hx8357_enter_standby(lcdev);
+
+ if (ret == 0)
+ lcd->state = power;
+ else
+ dev_warn(&lcdev->dev, "failed to set power mode %d\n", power);
+
+ return ret;
+}
+
+static int hx8357_get_power(struct lcd_device *lcdev)
+{
+ struct hx8357_data *lcd = lcd_get_data(lcdev);
+
+ return lcd->state;
+}
+
+static struct lcd_ops hx8357_ops = {
+ .set_power = hx8357_set_power,
+ .get_power = hx8357_get_power,
+};
+
+static int hx8357_probe(struct spi_device *spi)
+{
+ struct lcd_device *lcdev;
+ struct hx8357_data *lcd;
+ int i, ret;
+
+ lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL);
+ if (!lcd) {
+ dev_err(&spi->dev, "Couldn't allocate lcd internal structure!\n");
+ return -ENOMEM;
+ }
+
+ ret = spi_setup(spi);
+ if (ret < 0) {
+ dev_err(&spi->dev, "SPI setup failed.\n");
+ return ret;
+ }
+
+ lcd->spi = spi;
+
+ lcd->reset = of_get_named_gpio(spi->dev.of_node, "gpios-reset", 0);
+ if (!gpio_is_valid(lcd->reset)) {
+ dev_err(&spi->dev, "Missing dt property: gpios-reset\n");
+ return -EINVAL;
+ }
+
+ ret = devm_gpio_request_one(&spi->dev, lcd->reset,
+ GPIOF_OUT_INIT_HIGH,
+ "hx8357-reset");
+ if (ret) {
+ dev_err(&spi->dev,
+ "failed to request gpio %d: %d\n",
+ lcd->reset, ret);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < HX8357_NUM_IM_PINS; i++) {
+ lcd->im_pins[i] = of_get_named_gpio(spi->dev.of_node,
+ "im-gpios", i);
+ if (lcd->im_pins[i] == -EPROBE_DEFER) {
+ dev_info(&spi->dev, "GPIO requested is not here yet, deferring the probe\n");
+ return -EPROBE_DEFER;
+ }
+ if (!gpio_is_valid(lcd->im_pins[i])) {
+ dev_err(&spi->dev, "Missing dt property: im-gpios\n");
+ return -EINVAL;
+ }
+
+ ret = devm_gpio_request_one(&spi->dev, lcd->im_pins[i],
+ GPIOF_OUT_INIT_LOW, "im_pins");
+ if (ret) {
+ dev_err(&spi->dev, "failed to request gpio %d: %d\n",
+ lcd->im_pins[i], ret);
+ return -EINVAL;
+ }
+ }
+
+ lcdev = lcd_device_register("mxsfb", &spi->dev, lcd, &hx8357_ops);
+ if (IS_ERR(lcdev)) {
+ ret = PTR_ERR(lcdev);
+ return ret;
+ }
+ spi_set_drvdata(spi, lcdev);
+
+ ret = hx8357_lcd_init(lcdev);
+ if (ret) {
+ dev_err(&spi->dev, "Couldn't initialize panel\n");
+ goto init_error;
+ }
+
+ dev_info(&spi->dev, "Panel probed\n");
+
+ return 0;
+
+init_error:
+ lcd_device_unregister(lcdev);
+ return ret;
+}
+
+static int hx8357_remove(struct spi_device *spi)
+{
+ struct lcd_device *lcdev = spi_get_drvdata(spi);
+
+ lcd_device_unregister(lcdev);
+ return 0;
+}
+
+static const struct of_device_id hx8357_dt_ids[] = {
+ { .compatible = "himax,hx8357" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, hx8357_dt_ids);
+
+static struct spi_driver hx8357_driver = {
+ .probe = hx8357_probe,
+ .remove = hx8357_remove,
+ .driver = {
+ .name = "hx8357",
+ .of_match_table = of_match_ptr(hx8357_dt_ids),
+ },
+};
+
+module_spi_driver(hx8357_driver);
+
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
+MODULE_DESCRIPTION("Himax HX-8357 LCD Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/ili9320.c b/drivers/video/backlight/ili9320.c
index 9327cd1..1235bf9 100644
--- a/drivers/video/backlight/ili9320.c
+++ b/drivers/video/backlight/ili9320.c
@@ -45,7 +45,7 @@ static inline int ili9320_write_spi(struct ili9320 *ili,
/* second message is the data to transfer */
data[0] = spi->id | ILI9320_SPI_DATA | ILI9320_SPI_WRITE;
- data[1] = value >> 8;
+ data[1] = value >> 8;
data[2] = value;
return spi_sync(spi->dev, &spi->message);
@@ -56,11 +56,10 @@ int ili9320_write(struct ili9320 *ili, unsigned int reg, unsigned int value)
dev_dbg(ili->dev, "write: reg=%02x, val=%04x\n", reg, value);
return ili->write(ili, reg, value);
}
-
EXPORT_SYMBOL_GPL(ili9320_write);
int ili9320_write_regs(struct ili9320 *ili,
- struct ili9320_reg *values,
+ const struct ili9320_reg *values,
int nr_values)
{
int index;
@@ -74,7 +73,6 @@ int ili9320_write_regs(struct ili9320 *ili,
return 0;
}
-
EXPORT_SYMBOL_GPL(ili9320_write_regs);
static void ili9320_reset(struct ili9320 *lcd)
@@ -171,7 +169,7 @@ static struct lcd_ops ili9320_ops = {
.set_power = ili9320_set_power,
};
-static void __devinit ili9320_setup_spi(struct ili9320 *ili,
+static void ili9320_setup_spi(struct ili9320 *ili,
struct spi_device *dev)
{
struct ili9320_spi *spi = &ili->access.spi;
@@ -197,7 +195,7 @@ static void __devinit ili9320_setup_spi(struct ili9320 *ili,
spi_message_add_tail(&spi->xfer[1], &spi->message);
}
-int __devinit ili9320_probe_spi(struct spi_device *spi,
+int ili9320_probe_spi(struct spi_device *spi,
struct ili9320_client *client)
{
struct ili9320_platdata *cfg = spi->dev.platform_data;
@@ -260,7 +258,6 @@ int __devinit ili9320_probe_spi(struct spi_device *spi,
return ret;
}
-
EXPORT_SYMBOL_GPL(ili9320_probe_spi);
int ili9320_remove(struct ili9320 *ili)
@@ -271,7 +268,6 @@ int ili9320_remove(struct ili9320 *ili)
return 0;
}
-
EXPORT_SYMBOL_GPL(ili9320_remove);
#ifdef CONFIG_PM
@@ -296,20 +292,17 @@ int ili9320_suspend(struct ili9320 *lcd, pm_message_t state)
return 0;
}
-
EXPORT_SYMBOL_GPL(ili9320_suspend);
int ili9320_resume(struct ili9320 *lcd)
{
dev_info(lcd->dev, "resuming from power state %d\n", lcd->power);
- if (lcd->platdata->suspend == ILI9320_SUSPEND_DEEP) {
+ if (lcd->platdata->suspend == ILI9320_SUSPEND_DEEP)
ili9320_write(lcd, ILI9320_POWER1, 0x00);
- }
return ili9320_power(lcd, FB_BLANK_UNBLANK);
}
-
EXPORT_SYMBOL_GPL(ili9320_resume);
#endif
@@ -318,7 +311,6 @@ void ili9320_shutdown(struct ili9320 *lcd)
{
ili9320_power(lcd, FB_BLANK_POWERDOWN);
}
-
EXPORT_SYMBOL_GPL(ili9320_shutdown);
MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
diff --git a/drivers/video/backlight/ili9320.h b/drivers/video/backlight/ili9320.h
index e388eca..e0db738 100644
--- a/drivers/video/backlight/ili9320.h
+++ b/drivers/video/backlight/ili9320.h
@@ -63,7 +63,7 @@ extern int ili9320_write(struct ili9320 *ili,
unsigned int reg, unsigned int value);
extern int ili9320_write_regs(struct ili9320 *ili,
- struct ili9320_reg *values,
+ const struct ili9320_reg *values,
int nr_values);
/* Device probe */
diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c
index 16f593b..fef6ce4 100644
--- a/drivers/video/backlight/jornada720_bl.c
+++ b/drivers/video/backlight/jornada720_bl.c
@@ -48,7 +48,7 @@ static int jornada_bl_get_brightness(struct backlight_device *bd)
jornada_ssp_end();
- return (BL_MAX_BRIGHT - ret);
+ return BL_MAX_BRIGHT - ret;
}
static int jornada_bl_update_status(struct backlight_device *bd)
@@ -77,18 +77,23 @@ static int jornada_bl_update_status(struct backlight_device *bd)
goto out;
}
- /* at this point we expect that the mcu has accepted
- our command and is waiting for our new value
- please note that maximum brightness is 255,
- but due to physical layout it is equal to 0, so we simply
- invert the value (MAX VALUE - NEW VALUE). */
- if (jornada_ssp_byte(BL_MAX_BRIGHT - bd->props.brightness) != TXDUMMY) {
+ /*
+ * at this point we expect that the mcu has accepted
+ * our command and is waiting for our new value
+ * please note that maximum brightness is 255,
+ * but due to physical layout it is equal to 0, so we simply
+ * invert the value (MAX VALUE - NEW VALUE).
+ */
+ if (jornada_ssp_byte(BL_MAX_BRIGHT - bd->props.brightness)
+ != TXDUMMY) {
pr_err("set brightness failed\n");
ret = -ETIMEDOUT;
}
- /* If infact we get an TXDUMMY as output we are happy and dont
- make any further comments about it */
+ /*
+ * If infact we get an TXDUMMY as output we are happy and dont
+ * make any further comments about it
+ */
out:
jornada_ssp_end();
@@ -121,9 +126,11 @@ static int jornada_bl_probe(struct platform_device *pdev)
bd->props.power = FB_BLANK_UNBLANK;
bd->props.brightness = BL_DEF_BRIGHT;
- /* note. make sure max brightness is set otherwise
- you will get seemingly non-related errors when
- trying to change brightness */
+ /*
+ * note. make sure max brightness is set otherwise
+ * you will get seemingly non-related errors when
+ * trying to change brightness
+ */
jornada_bl_update_status(bd);
platform_set_drvdata(pdev, bd);
diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c
index 2d90c06..fb61557 100644
--- a/drivers/video/backlight/l4f00242t03.c
+++ b/drivers/video/backlight/l4f00242t03.c
@@ -4,7 +4,7 @@
* Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
*
* Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
- * Inspired by Marek Vasut work in l4f00242t03.c
+ * Inspired by Marek Vasut work in l4f00242t03.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -33,7 +33,6 @@ struct l4f00242t03_priv {
struct regulator *core_reg;
};
-
static void l4f00242t03_reset(unsigned int gpio)
{
pr_debug("l4f00242t03_reset.\n");
@@ -50,7 +49,7 @@ static void l4f00242t03_reset(unsigned int gpio)
static void l4f00242t03_lcd_init(struct spi_device *spi)
{
struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
- struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
+ struct l4f00242t03_priv *priv = spi_get_drvdata(spi);
const u16 cmd[] = { 0x36, param(0), 0x3A, param(0x60) };
dev_dbg(&spi->dev, "initializing LCD\n");
@@ -71,7 +70,7 @@ static void l4f00242t03_lcd_init(struct spi_device *spi)
static void l4f00242t03_lcd_powerdown(struct spi_device *spi)
{
struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
- struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
+ struct l4f00242t03_priv *priv = spi_get_drvdata(spi);
dev_dbg(&spi->dev, "Powering down LCD\n");
@@ -150,7 +149,7 @@ static struct lcd_ops l4f_ops = {
.get_power = l4f00242t03_lcd_power_get,
};
-static int __devinit l4f00242t03_probe(struct spi_device *spi)
+static int l4f00242t03_probe(struct spi_device *spi)
{
struct l4f00242t03_priv *priv;
struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
@@ -169,7 +168,7 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi)
return -ENOMEM;
}
- dev_set_drvdata(&spi->dev, priv);
+ spi_set_drvdata(spi, priv);
spi->bits_per_word = 9;
spi_setup(spi);
@@ -191,27 +190,24 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi)
return ret;
}
- priv->io_reg = regulator_get(&spi->dev, "vdd");
+ priv->io_reg = devm_regulator_get(&spi->dev, "vdd");
if (IS_ERR(priv->io_reg)) {
dev_err(&spi->dev, "%s: Unable to get the IO regulator\n",
__func__);
return PTR_ERR(priv->io_reg);
}
- priv->core_reg = regulator_get(&spi->dev, "vcore");
+ priv->core_reg = devm_regulator_get(&spi->dev, "vcore");
if (IS_ERR(priv->core_reg)) {
- ret = PTR_ERR(priv->core_reg);
dev_err(&spi->dev, "%s: Unable to get the core regulator\n",
__func__);
- goto err1;
+ return PTR_ERR(priv->core_reg);
}
priv->ld = lcd_device_register("l4f00242t03",
&spi->dev, priv, &l4f_ops);
- if (IS_ERR(priv->ld)) {
- ret = PTR_ERR(priv->ld);
- goto err2;
- }
+ if (IS_ERR(priv->ld))
+ return PTR_ERR(priv->ld);
/* Init the LCD */
l4f00242t03_lcd_init(spi);
@@ -221,33 +217,22 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi)
dev_info(&spi->dev, "Epson l4f00242t03 lcd probed.\n");
return 0;
-
-err2:
- regulator_put(priv->core_reg);
-err1:
- regulator_put(priv->io_reg);
-
- return ret;
}
-static int __devexit l4f00242t03_remove(struct spi_device *spi)
+static int l4f00242t03_remove(struct spi_device *spi)
{
- struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
+ struct l4f00242t03_priv *priv = spi_get_drvdata(spi);
l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN);
lcd_device_unregister(priv->ld);
-
- dev_set_drvdata(&spi->dev, NULL);
-
- regulator_put(priv->io_reg);
- regulator_put(priv->core_reg);
+ spi_set_drvdata(spi, NULL);
return 0;
}
static void l4f00242t03_shutdown(struct spi_device *spi)
{
- struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
+ struct l4f00242t03_priv *priv = spi_get_drvdata(spi);
if (priv)
l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN);
@@ -260,7 +245,7 @@ static struct spi_driver l4f00242t03_driver = {
.owner = THIS_MODULE,
},
.probe = l4f00242t03_probe,
- .remove = __devexit_p(l4f00242t03_remove),
+ .remove = l4f00242t03_remove,
.shutdown = l4f00242t03_shutdown,
};
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index a5d0d02..34fb6bd 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -108,7 +108,7 @@ static ssize_t lcd_show_power(struct device *dev, struct device_attribute *attr,
static ssize_t lcd_store_power(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
- int rc = -ENXIO;
+ int rc;
struct lcd_device *ld = to_lcd_device(dev);
unsigned long power;
@@ -116,6 +116,8 @@ static ssize_t lcd_store_power(struct device *dev,
if (rc)
return rc;
+ rc = -ENXIO;
+
mutex_lock(&ld->ops_lock);
if (ld->ops && ld->ops->set_power) {
pr_debug("set power to %lu\n", power);
@@ -144,7 +146,7 @@ static ssize_t lcd_show_contrast(struct device *dev,
static ssize_t lcd_store_contrast(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
- int rc = -ENXIO;
+ int rc;
struct lcd_device *ld = to_lcd_device(dev);
unsigned long contrast;
@@ -152,6 +154,8 @@ static ssize_t lcd_store_contrast(struct device *dev,
if (rc)
return rc;
+ rc = -ENXIO;
+
mutex_lock(&ld->ops_lock);
if (ld->ops && ld->ops->set_contrast) {
pr_debug("set contrast to %lu\n", contrast);
diff --git a/drivers/video/backlight/ld9040.c b/drivers/video/backlight/ld9040.c
index 58f517f..1b642f5 100644
--- a/drivers/video/backlight/ld9040.c
+++ b/drivers/video/backlight/ld9040.c
@@ -9,29 +9,20 @@
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#include <linux/wait.h>
-#include <linux/fb.h>
+#include <linux/backlight.h>
#include <linux/delay.h>
+#include <linux/fb.h>
#include <linux/gpio.h>
-#include <linux/spi/spi.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/lcd.h>
-#include <linux/backlight.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+#include <linux/wait.h>
#include "ld9040_gamma.h"
@@ -43,7 +34,6 @@
#define MIN_BRIGHTNESS 0
#define MAX_BRIGHTNESS 24
-#define power_is_on(pwr) ((pwr) <= FB_BLANK_NORMAL)
struct ld9040 {
struct device *dev;
@@ -78,7 +68,7 @@ static void ld9040_regulator_enable(struct ld9040 *lcd)
lcd->enabled = true;
}
- mdelay(pd->power_on_delay);
+ msleep(pd->power_on_delay);
out:
mutex_unlock(&lcd->lock);
}
@@ -474,8 +464,9 @@ static int ld9040_panel_send_sequence(struct ld9040 *lcd,
ret = ld9040_spi_write(lcd, wbuf[i], wbuf[i+1]);
if (ret)
break;
- } else
- udelay(wbuf[i+1]*1000);
+ } else {
+ msleep(wbuf[i+1]);
+ }
i += 2;
}
@@ -513,14 +504,9 @@ gamma_err:
static int ld9040_gamma_ctl(struct ld9040 *lcd, int gamma)
{
- int ret = 0;
-
- ret = _ld9040_gamma_ctl(lcd, gamma_table.gamma_22_table[gamma]);
-
- return ret;
+ return _ld9040_gamma_ctl(lcd, gamma_table.gamma_22_table[gamma]);
}
-
static int ld9040_ldi_init(struct ld9040 *lcd)
{
int ret, i;
@@ -539,7 +525,7 @@ static int ld9040_ldi_init(struct ld9040 *lcd)
for (i = 0; i < ARRAY_SIZE(init_seq); i++) {
ret = ld9040_panel_send_sequence(lcd, init_seq[i]);
/* workaround: minimum delay time for transferring CMD */
- udelay(300);
+ usleep_range(300, 310);
if (ret)
break;
}
@@ -549,11 +535,7 @@ static int ld9040_ldi_init(struct ld9040 *lcd)
static int ld9040_ldi_enable(struct ld9040 *lcd)
{
- int ret = 0;
-
- ret = ld9040_panel_send_sequence(lcd, seq_display_on);
-
- return ret;
+ return ld9040_panel_send_sequence(lcd, seq_display_on);
}
static int ld9040_ldi_disable(struct ld9040 *lcd)
@@ -566,25 +548,27 @@ static int ld9040_ldi_disable(struct ld9040 *lcd)
return ret;
}
+static int ld9040_power_is_on(int power)
+{
+ return power <= FB_BLANK_NORMAL;
+}
+
static int ld9040_power_on(struct ld9040 *lcd)
{
int ret = 0;
- struct lcd_platform_data *pd = NULL;
+ struct lcd_platform_data *pd;
+
pd = lcd->lcd_pd;
- if (!pd) {
- dev_err(lcd->dev, "platform data is NULL.\n");
- return -EFAULT;
- }
/* lcd power on */
ld9040_regulator_enable(lcd);
if (!pd->reset) {
dev_err(lcd->dev, "reset is NULL.\n");
- return -EFAULT;
+ return -EINVAL;
} else {
pd->reset(lcd->ld);
- mdelay(pd->reset_delay);
+ msleep(pd->reset_delay);
}
ret = ld9040_ldi_init(lcd);
@@ -604,14 +588,10 @@ static int ld9040_power_on(struct ld9040 *lcd)
static int ld9040_power_off(struct ld9040 *lcd)
{
- int ret = 0;
- struct lcd_platform_data *pd = NULL;
+ int ret;
+ struct lcd_platform_data *pd;
pd = lcd->lcd_pd;
- if (!pd) {
- dev_err(lcd->dev, "platform data is NULL.\n");
- return -EFAULT;
- }
ret = ld9040_ldi_disable(lcd);
if (ret) {
@@ -619,7 +599,7 @@ static int ld9040_power_off(struct ld9040 *lcd)
return -EIO;
}
- mdelay(pd->power_off_delay);
+ msleep(pd->power_off_delay);
/* lcd power off */
ld9040_regulator_disable(lcd);
@@ -631,9 +611,9 @@ static int ld9040_power(struct ld9040 *lcd, int power)
{
int ret = 0;
- if (power_is_on(power) && !power_is_on(lcd->power))
+ if (ld9040_power_is_on(power) && !ld9040_power_is_on(lcd->power))
ret = ld9040_power_on(lcd);
- else if (!power_is_on(power) && power_is_on(lcd->power))
+ else if (!ld9040_power_is_on(power) && ld9040_power_is_on(lcd->power))
ret = ld9040_power_off(lcd);
if (!ret)
@@ -698,7 +678,6 @@ static const struct backlight_ops ld9040_backlight_ops = {
.update_status = ld9040_set_brightness,
};
-
static int ld9040_probe(struct spi_device *spi)
{
int ret = 0;
@@ -726,22 +705,20 @@ static int ld9040_probe(struct spi_device *spi)
lcd->lcd_pd = spi->dev.platform_data;
if (!lcd->lcd_pd) {
dev_err(&spi->dev, "platform data is NULL.\n");
- return -EFAULT;
+ return -EINVAL;
}
mutex_init(&lcd->lock);
- ret = regulator_bulk_get(lcd->dev, ARRAY_SIZE(supplies), supplies);
+ ret = devm_regulator_bulk_get(lcd->dev, ARRAY_SIZE(supplies), supplies);
if (ret) {
dev_err(lcd->dev, "Failed to get regulators: %d\n", ret);
return ret;
}
ld = lcd_device_register("ld9040", &spi->dev, lcd, &ld9040_lcd_ops);
- if (IS_ERR(ld)) {
- ret = PTR_ERR(ld);
- goto out_free_regulator;
- }
+ if (IS_ERR(ld))
+ return PTR_ERR(ld);
lcd->ld = ld;
@@ -772,30 +749,28 @@ static int ld9040_probe(struct spi_device *spi)
lcd->power = FB_BLANK_POWERDOWN;
ld9040_power(lcd, FB_BLANK_UNBLANK);
- } else
+ } else {
lcd->power = FB_BLANK_UNBLANK;
+ }
- dev_set_drvdata(&spi->dev, lcd);
+ spi_set_drvdata(spi, lcd);
dev_info(&spi->dev, "ld9040 panel driver has been probed.\n");
return 0;
out_unregister_lcd:
lcd_device_unregister(lcd->ld);
-out_free_regulator:
- regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
return ret;
}
-static int __devexit ld9040_remove(struct spi_device *spi)
+static int ld9040_remove(struct spi_device *spi)
{
- struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
+ struct ld9040 *lcd = spi_get_drvdata(spi);
ld9040_power(lcd, FB_BLANK_POWERDOWN);
backlight_device_unregister(lcd->bd);
lcd_device_unregister(lcd->ld);
- regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
return 0;
}
@@ -803,8 +778,7 @@ static int __devexit ld9040_remove(struct spi_device *spi)
#if defined(CONFIG_PM)
static int ld9040_suspend(struct spi_device *spi, pm_message_t mesg)
{
- int ret = 0;
- struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
+ struct ld9040 *lcd = spi_get_drvdata(spi);
dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
@@ -812,21 +786,16 @@ static int ld9040_suspend(struct spi_device *spi, pm_message_t mesg)
* when lcd panel is suspend, lcd panel becomes off
* regardless of status.
*/
- ret = ld9040_power(lcd, FB_BLANK_POWERDOWN);
-
- return ret;
+ return ld9040_power(lcd, FB_BLANK_POWERDOWN);
}
static int ld9040_resume(struct spi_device *spi)
{
- int ret = 0;
- struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
+ struct ld9040 *lcd = spi_get_drvdata(spi);
lcd->power = FB_BLANK_POWERDOWN;
- ret = ld9040_power(lcd, FB_BLANK_UNBLANK);
-
- return ret;
+ return ld9040_power(lcd, FB_BLANK_UNBLANK);
}
#else
#define ld9040_suspend NULL
@@ -836,7 +805,7 @@ static int ld9040_resume(struct spi_device *spi)
/* Power down all displays on reboot, poweroff or halt. */
static void ld9040_shutdown(struct spi_device *spi)
{
- struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
+ struct ld9040 *lcd = spi_get_drvdata(spi);
ld9040_power(lcd, FB_BLANK_POWERDOWN);
}
@@ -847,7 +816,7 @@ static struct spi_driver ld9040_driver = {
.owner = THIS_MODULE,
},
.probe = ld9040_probe,
- .remove = __devexit_p(ld9040_remove),
+ .remove = ld9040_remove,
.shutdown = ld9040_shutdown,
.suspend = ld9040_suspend,
.resume = ld9040_resume,
diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c
index 18dca0c..5d18d4d 100644
--- a/drivers/video/backlight/lm3533_bl.c
+++ b/drivers/video/backlight/lm3533_bl.c
@@ -257,7 +257,7 @@ static struct attribute_group lm3533_bl_attribute_group = {
.attrs = lm3533_bl_attributes
};
-static int __devinit lm3533_bl_setup(struct lm3533_bl *bl,
+static int lm3533_bl_setup(struct lm3533_bl *bl,
struct lm3533_bl_platform_data *pdata)
{
int ret;
@@ -269,7 +269,7 @@ static int __devinit lm3533_bl_setup(struct lm3533_bl *bl,
return lm3533_ctrlbank_set_pwm(&bl->cb, pdata->pwm);
}
-static int __devinit lm3533_bl_probe(struct platform_device *pdev)
+static int lm3533_bl_probe(struct platform_device *pdev)
{
struct lm3533 *lm3533;
struct lm3533_bl_platform_data *pdata;
@@ -351,7 +351,7 @@ err_unregister:
return ret;
}
-static int __devexit lm3533_bl_remove(struct platform_device *pdev)
+static int lm3533_bl_remove(struct platform_device *pdev)
{
struct lm3533_bl *bl = platform_get_drvdata(pdev);
struct backlight_device *bd = bl->bd;
@@ -406,7 +406,7 @@ static struct platform_driver lm3533_bl_driver = {
.owner = THIS_MODULE,
},
.probe = lm3533_bl_probe,
- .remove = __devexit_p(lm3533_bl_remove),
+ .remove = lm3533_bl_remove,
.shutdown = lm3533_bl_shutdown,
.suspend = lm3533_bl_suspend,
.resume = lm3533_bl_resume,
diff --git a/drivers/video/backlight/lm3630_bl.c b/drivers/video/backlight/lm3630_bl.c
index dc19144..76a62e9 100644
--- a/drivers/video/backlight/lm3630_bl.c
+++ b/drivers/video/backlight/lm3630_bl.c
@@ -37,7 +37,7 @@ enum lm3630_leds {
BLED_2
};
-static const char *bled_name[] = {
+static const char * const bled_name[] = {
[BLED_ALL] = "lm3630_bled", /*Bank1 controls all string */
[BLED_1] = "lm3630_bled1", /*Bank1 controls bled1 */
[BLED_2] = "lm3630_bled2", /*Bank1 or 2 controls bled2 */
@@ -55,7 +55,7 @@ struct lm3630_chip_data {
};
/* initialize chip */
-static int __devinit lm3630_chip_init(struct lm3630_chip_data *pchip)
+static int lm3630_chip_init(struct lm3630_chip_data *pchip)
{
int ret;
unsigned int reg_val;
@@ -320,7 +320,7 @@ static int lm3630_backlight_register(struct lm3630_chip_data *pchip,
backlight_device_register(name, pchip->dev, pchip,
&lm3630_bank_a_ops, &props);
if (IS_ERR(pchip->bled1))
- return -EIO;
+ return PTR_ERR(pchip->bled1);
break;
case BLED_2:
props.brightness = pdata->init_brt_led2;
@@ -329,7 +329,7 @@ static int lm3630_backlight_register(struct lm3630_chip_data *pchip,
backlight_device_register(name, pchip->dev, pchip,
&lm3630_bank_b_ops, &props);
if (IS_ERR(pchip->bled2))
- return -EIO;
+ return PTR_ERR(pchip->bled2);
break;
}
return 0;
@@ -349,7 +349,7 @@ static const struct regmap_config lm3630_regmap = {
.max_register = REG_MAX,
};
-static int __devinit lm3630_probe(struct i2c_client *client,
+static int lm3630_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct lm3630_platform_data *pdata = client->dev.platform_data;
@@ -429,7 +429,7 @@ err_chip_init:
return ret;
}
-static int __devexit lm3630_remove(struct i2c_client *client)
+static int lm3630_remove(struct i2c_client *client)
{
int ret;
struct lm3630_chip_data *pchip = i2c_get_clientdata(client);
@@ -463,7 +463,7 @@ static struct i2c_driver lm3630_i2c_driver = {
.name = LM3630_NAME,
},
.probe = lm3630_probe,
- .remove = __devexit_p(lm3630_remove),
+ .remove = lm3630_remove,
.id_table = lm3630_id,
};
diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c
index 585949b..053964d 100644
--- a/drivers/video/backlight/lm3639_bl.c
+++ b/drivers/video/backlight/lm3639_bl.c
@@ -48,7 +48,7 @@ struct lm3639_chip_data {
};
/* initialize chip */
-static int __devinit lm3639_chip_init(struct lm3639_chip_data *pchip)
+static int lm3639_chip_init(struct lm3639_chip_data *pchip)
{
int ret;
unsigned int reg_val;
@@ -214,7 +214,7 @@ out_input:
}
-static DEVICE_ATTR(bled_mode, 0666, NULL, lm3639_bled_mode_store);
+static DEVICE_ATTR(bled_mode, S_IWUSR, NULL, lm3639_bled_mode_store);
/* torch */
static void lm3639_torch_brightness_set(struct led_classdev *cdev,
@@ -299,7 +299,7 @@ static const struct regmap_config lm3639_regmap = {
.max_register = REG_MAX,
};
-static int __devinit lm3639_probe(struct i2c_client *client,
+static int lm3639_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret;
@@ -350,14 +350,13 @@ static int __devinit lm3639_probe(struct i2c_client *client,
&lm3639_bled_ops, &props);
if (IS_ERR(pchip->bled)) {
dev_err(&client->dev, "fail : backlight register\n");
- ret = -EIO;
+ ret = PTR_ERR(pchip->bled);
goto err_out;
}
ret = device_create_file(&(pchip->bled->dev), &dev_attr_bled_mode);
if (ret < 0) {
dev_err(&client->dev, "failed : add sysfs entries\n");
- ret = -EIO;
goto err_bled_mode;
}
@@ -369,7 +368,6 @@ static int __devinit lm3639_probe(struct i2c_client *client,
&client->dev, &pchip->cdev_flash);
if (ret < 0) {
dev_err(&client->dev, "fail : flash register\n");
- ret = -EIO;
goto err_flash;
}
@@ -381,7 +379,6 @@ static int __devinit lm3639_probe(struct i2c_client *client,
&client->dev, &pchip->cdev_torch);
if (ret < 0) {
dev_err(&client->dev, "fail : torch register\n");
- ret = -EIO;
goto err_torch;
}
@@ -397,7 +394,7 @@ err_out:
return ret;
}
-static int __devexit lm3639_remove(struct i2c_client *client)
+static int lm3639_remove(struct i2c_client *client)
{
struct lm3639_chip_data *pchip = i2c_get_clientdata(client);
@@ -425,7 +422,7 @@ static struct i2c_driver lm3639_i2c_driver = {
.name = LM3639_NAME,
},
.probe = lm3639_probe,
- .remove = __devexit_p(lm3639_remove),
+ .remove = lm3639_remove,
.id_table = lm3639_id,
};
diff --git a/drivers/video/backlight/lms283gf05.c b/drivers/video/backlight/lms283gf05.c
index ea43f22..4eec472 100644
--- a/drivers/video/backlight/lms283gf05.c
+++ b/drivers/video/backlight/lms283gf05.c
@@ -31,7 +31,7 @@ struct lms283gf05_seq {
};
/* Magic sequences supplied by manufacturer, for details refer to datasheet */
-static struct lms283gf05_seq disp_initseq[] = {
+static const struct lms283gf05_seq disp_initseq[] = {
/* REG, VALUE, DELAY */
{ 0x07, 0x0000, 0 },
{ 0x13, 0x0000, 10 },
@@ -78,7 +78,7 @@ static struct lms283gf05_seq disp_initseq[] = {
{ 0x22, 0x0000, 0 }
};
-static struct lms283gf05_seq disp_pdwnseq[] = {
+static const struct lms283gf05_seq disp_pdwnseq[] = {
{ 0x07, 0x0016, 30 },
{ 0x07, 0x0004, 0 },
@@ -104,7 +104,7 @@ static void lms283gf05_reset(unsigned long gpio, bool inverted)
}
static void lms283gf05_toggle(struct spi_device *spi,
- struct lms283gf05_seq *seq, int sz)
+ const struct lms283gf05_seq *seq, int sz)
{
char buf[3];
int i;
@@ -150,7 +150,7 @@ static struct lcd_ops lms_ops = {
.get_power = NULL,
};
-static int __devinit lms283gf05_probe(struct spi_device *spi)
+static int lms283gf05_probe(struct spi_device *spi)
{
struct lms283gf05_state *st;
struct lms283gf05_pdata *pdata = spi->dev.platform_data;
@@ -158,13 +158,10 @@ static int __devinit lms283gf05_probe(struct spi_device *spi)
int ret = 0;
if (pdata != NULL) {
- ret = devm_gpio_request(&spi->dev, pdata->reset_gpio,
- "LMS285GF05 RESET");
- if (ret)
- return ret;
-
- ret = gpio_direction_output(pdata->reset_gpio,
- !pdata->reset_inverted);
+ ret = devm_gpio_request_one(&spi->dev, pdata->reset_gpio,
+ GPIOF_DIR_OUT | (!pdata->reset_inverted ?
+ GPIOF_INIT_HIGH : GPIOF_INIT_LOW),
+ "LMS285GF05 RESET");
if (ret)
return ret;
}
@@ -183,7 +180,7 @@ static int __devinit lms283gf05_probe(struct spi_device *spi)
st->spi = spi;
st->ld = ld;
- dev_set_drvdata(&spi->dev, st);
+ spi_set_drvdata(spi, st);
/* kick in the LCD */
if (pdata)
@@ -193,9 +190,9 @@ static int __devinit lms283gf05_probe(struct spi_device *spi)
return 0;
}
-static int __devexit lms283gf05_remove(struct spi_device *spi)
+static int lms283gf05_remove(struct spi_device *spi)
{
- struct lms283gf05_state *st = dev_get_drvdata(&spi->dev);
+ struct lms283gf05_state *st = spi_get_drvdata(spi);
lcd_device_unregister(st->ld);
@@ -208,7 +205,7 @@ static struct spi_driver lms283gf05_driver = {
.owner = THIS_MODULE,
},
.probe = lms283gf05_probe,
- .remove = __devexit_p(lms283gf05_remove),
+ .remove = lms283gf05_remove,
};
module_spi_driver(lms283gf05_driver);
diff --git a/drivers/video/backlight/lms501kf03.c b/drivers/video/backlight/lms501kf03.c
new file mode 100644
index 0000000..b43882a
--- /dev/null
+++ b/drivers/video/backlight/lms501kf03.c
@@ -0,0 +1,441 @@
+/*
+ * lms501kf03 TFT LCD panel driver.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <jg1.han@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/lcd.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/wait.h>
+
+#define COMMAND_ONLY 0x00
+#define DATA_ONLY 0x01
+
+struct lms501kf03 {
+ struct device *dev;
+ struct spi_device *spi;
+ unsigned int power;
+ struct lcd_device *ld;
+ struct lcd_platform_data *lcd_pd;
+};
+
+static const unsigned char seq_password[] = {
+ 0xb9, 0xff, 0x83, 0x69,
+};
+
+static const unsigned char seq_power[] = {
+ 0xb1, 0x01, 0x00, 0x34, 0x06, 0x00, 0x14, 0x14, 0x20, 0x28,
+ 0x12, 0x12, 0x17, 0x0a, 0x01, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+};
+
+static const unsigned char seq_display[] = {
+ 0xb2, 0x00, 0x2b, 0x03, 0x03, 0x70, 0x00, 0xff, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0x03, 0x00, 0x01,
+};
+
+static const unsigned char seq_rgb_if[] = {
+ 0xb3, 0x09,
+};
+
+static const unsigned char seq_display_inv[] = {
+ 0xb4, 0x01, 0x08, 0x77, 0x0e, 0x06,
+};
+
+static const unsigned char seq_vcom[] = {
+ 0xb6, 0x4c, 0x2e,
+};
+
+static const unsigned char seq_gate[] = {
+ 0xd5, 0x00, 0x05, 0x03, 0x29, 0x01, 0x07, 0x17, 0x68, 0x13,
+ 0x37, 0x20, 0x31, 0x8a, 0x46, 0x9b, 0x57, 0x13, 0x02, 0x75,
+ 0xb9, 0x64, 0xa8, 0x07, 0x0f, 0x04, 0x07,
+};
+
+static const unsigned char seq_panel[] = {
+ 0xcc, 0x02,
+};
+
+static const unsigned char seq_col_mod[] = {
+ 0x3a, 0x77,
+};
+
+static const unsigned char seq_w_gamma[] = {
+ 0xe0, 0x00, 0x04, 0x09, 0x0f, 0x1f, 0x3f, 0x1f, 0x2f, 0x0a,
+ 0x0f, 0x10, 0x16, 0x18, 0x16, 0x17, 0x0d, 0x15, 0x00, 0x04,
+ 0x09, 0x0f, 0x38, 0x3f, 0x20, 0x39, 0x0a, 0x0f, 0x10, 0x16,
+ 0x18, 0x16, 0x17, 0x0d, 0x15,
+};
+
+static const unsigned char seq_rgb_gamma[] = {
+ 0xc1, 0x01, 0x03, 0x07, 0x0f, 0x1a, 0x22, 0x2c, 0x33, 0x3c,
+ 0x46, 0x4f, 0x58, 0x60, 0x69, 0x71, 0x79, 0x82, 0x89, 0x92,
+ 0x9a, 0xa1, 0xa9, 0xb1, 0xb9, 0xc1, 0xc9, 0xcf, 0xd6, 0xde,
+ 0xe5, 0xec, 0xf3, 0xf9, 0xff, 0xdd, 0x39, 0x07, 0x1c, 0xcb,
+ 0xab, 0x5f, 0x49, 0x80, 0x03, 0x07, 0x0f, 0x19, 0x20, 0x2a,
+ 0x31, 0x39, 0x42, 0x4b, 0x53, 0x5b, 0x63, 0x6b, 0x73, 0x7b,
+ 0x83, 0x8a, 0x92, 0x9b, 0xa2, 0xaa, 0xb2, 0xba, 0xc2, 0xca,
+ 0xd0, 0xd8, 0xe1, 0xe8, 0xf0, 0xf8, 0xff, 0xf7, 0xd8, 0xbe,
+ 0xa7, 0x39, 0x40, 0x85, 0x8c, 0xc0, 0x04, 0x07, 0x0c, 0x17,
+ 0x1c, 0x23, 0x2b, 0x34, 0x3b, 0x43, 0x4c, 0x54, 0x5b, 0x63,
+ 0x6a, 0x73, 0x7a, 0x82, 0x8a, 0x91, 0x98, 0xa1, 0xa8, 0xb0,
+ 0xb7, 0xc1, 0xc9, 0xcf, 0xd9, 0xe3, 0xea, 0xf4, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static const unsigned char seq_up_dn[] = {
+ 0x36, 0x10,
+};
+
+static const unsigned char seq_sleep_in[] = {
+ 0x10,
+};
+
+static const unsigned char seq_sleep_out[] = {
+ 0x11,
+};
+
+static const unsigned char seq_display_on[] = {
+ 0x29,
+};
+
+static const unsigned char seq_display_off[] = {
+ 0x10,
+};
+
+static int lms501kf03_spi_write_byte(struct lms501kf03 *lcd, int addr, int data)
+{
+ u16 buf[1];
+ struct spi_message msg;
+
+ struct spi_transfer xfer = {
+ .len = 2,
+ .tx_buf = buf,
+ };
+
+ buf[0] = (addr << 8) | data;
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+
+ return spi_sync(lcd->spi, &msg);
+}
+
+static int lms501kf03_spi_write(struct lms501kf03 *lcd, unsigned char address,
+ unsigned char command)
+{
+ return lms501kf03_spi_write_byte(lcd, address, command);
+}
+
+static int lms501kf03_panel_send_sequence(struct lms501kf03 *lcd,
+ const unsigned char *wbuf,
+ unsigned int len)
+{
+ int ret = 0, i = 0;
+
+ while (i < len) {
+ if (i == 0)
+ ret = lms501kf03_spi_write(lcd, COMMAND_ONLY, wbuf[i]);
+ else
+ ret = lms501kf03_spi_write(lcd, DATA_ONLY, wbuf[i]);
+ if (ret)
+ break;
+ i += 1;
+ }
+
+ return ret;
+}
+
+static int lms501kf03_ldi_init(struct lms501kf03 *lcd)
+{
+ int ret, i;
+ static const unsigned char *init_seq[] = {
+ seq_password,
+ seq_power,
+ seq_display,
+ seq_rgb_if,
+ seq_display_inv,
+ seq_vcom,
+ seq_gate,
+ seq_panel,
+ seq_col_mod,
+ seq_w_gamma,
+ seq_rgb_gamma,
+ seq_sleep_out,
+ };
+
+ static const unsigned int size_seq[] = {
+ ARRAY_SIZE(seq_password),
+ ARRAY_SIZE(seq_power),
+ ARRAY_SIZE(seq_display),
+ ARRAY_SIZE(seq_rgb_if),
+ ARRAY_SIZE(seq_display_inv),
+ ARRAY_SIZE(seq_vcom),
+ ARRAY_SIZE(seq_gate),
+ ARRAY_SIZE(seq_panel),
+ ARRAY_SIZE(seq_col_mod),
+ ARRAY_SIZE(seq_w_gamma),
+ ARRAY_SIZE(seq_rgb_gamma),
+ ARRAY_SIZE(seq_sleep_out),
+ };
+
+ for (i = 0; i < ARRAY_SIZE(init_seq); i++) {
+ ret = lms501kf03_panel_send_sequence(lcd, init_seq[i],
+ size_seq[i]);
+ if (ret)
+ break;
+ }
+ /*
+ * According to the datasheet, 120ms delay time is required.
+ * After sleep out sequence, command is blocked for 120ms.
+ * Thus, LDI should wait for 120ms.
+ */
+ msleep(120);
+
+ return ret;
+}
+
+static int lms501kf03_ldi_enable(struct lms501kf03 *lcd)
+{
+ return lms501kf03_panel_send_sequence(lcd, seq_display_on,
+ ARRAY_SIZE(seq_display_on));
+}
+
+static int lms501kf03_ldi_disable(struct lms501kf03 *lcd)
+{
+ return lms501kf03_panel_send_sequence(lcd, seq_display_off,
+ ARRAY_SIZE(seq_display_off));
+}
+
+static int lms501kf03_power_is_on(int power)
+{
+ return (power) <= FB_BLANK_NORMAL;
+}
+
+static int lms501kf03_power_on(struct lms501kf03 *lcd)
+{
+ int ret = 0;
+ struct lcd_platform_data *pd;
+
+ pd = lcd->lcd_pd;
+
+ if (!pd->power_on) {
+ dev_err(lcd->dev, "power_on is NULL.\n");
+ return -EINVAL;
+ } else {
+ pd->power_on(lcd->ld, 1);
+ msleep(pd->power_on_delay);
+ }
+
+ if (!pd->reset) {
+ dev_err(lcd->dev, "reset is NULL.\n");
+ return -EINVAL;
+ } else {
+ pd->reset(lcd->ld);
+ msleep(pd->reset_delay);
+ }
+
+ ret = lms501kf03_ldi_init(lcd);
+ if (ret) {
+ dev_err(lcd->dev, "failed to initialize ldi.\n");
+ return ret;
+ }
+
+ ret = lms501kf03_ldi_enable(lcd);
+ if (ret) {
+ dev_err(lcd->dev, "failed to enable ldi.\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int lms501kf03_power_off(struct lms501kf03 *lcd)
+{
+ int ret = 0;
+ struct lcd_platform_data *pd;
+
+ pd = lcd->lcd_pd;
+
+ ret = lms501kf03_ldi_disable(lcd);
+ if (ret) {
+ dev_err(lcd->dev, "lcd setting failed.\n");
+ return -EIO;
+ }
+
+ msleep(pd->power_off_delay);
+
+ pd->power_on(lcd->ld, 0);
+
+ return 0;
+}
+
+static int lms501kf03_power(struct lms501kf03 *lcd, int power)
+{
+ int ret = 0;
+
+ if (lms501kf03_power_is_on(power) &&
+ !lms501kf03_power_is_on(lcd->power))
+ ret = lms501kf03_power_on(lcd);
+ else if (!lms501kf03_power_is_on(power) &&
+ lms501kf03_power_is_on(lcd->power))
+ ret = lms501kf03_power_off(lcd);
+
+ if (!ret)
+ lcd->power = power;
+
+ return ret;
+}
+
+static int lms501kf03_get_power(struct lcd_device *ld)
+{
+ struct lms501kf03 *lcd = lcd_get_data(ld);
+
+ return lcd->power;
+}
+
+static int lms501kf03_set_power(struct lcd_device *ld, int power)
+{
+ struct lms501kf03 *lcd = lcd_get_data(ld);
+
+ if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
+ power != FB_BLANK_NORMAL) {
+ dev_err(lcd->dev, "power value should be 0, 1 or 4.\n");
+ return -EINVAL;
+ }
+
+ return lms501kf03_power(lcd, power);
+}
+
+static struct lcd_ops lms501kf03_lcd_ops = {
+ .get_power = lms501kf03_get_power,
+ .set_power = lms501kf03_set_power,
+};
+
+static int lms501kf03_probe(struct spi_device *spi)
+{
+ struct lms501kf03 *lcd = NULL;
+ struct lcd_device *ld = NULL;
+ int ret = 0;
+
+ lcd = devm_kzalloc(&spi->dev, sizeof(struct lms501kf03), GFP_KERNEL);
+ if (!lcd)
+ return -ENOMEM;
+
+ /* lms501kf03 lcd panel uses 3-wire 9-bit SPI Mode. */
+ spi->bits_per_word = 9;
+
+ ret = spi_setup(spi);
+ if (ret < 0) {
+ dev_err(&spi->dev, "spi setup failed.\n");
+ return ret;
+ }
+
+ lcd->spi = spi;
+ lcd->dev = &spi->dev;
+
+ lcd->lcd_pd = spi->dev.platform_data;
+ if (!lcd->lcd_pd) {
+ dev_err(&spi->dev, "platform data is NULL\n");
+ return -EINVAL;
+ }
+
+ ld = lcd_device_register("lms501kf03", &spi->dev, lcd,
+ &lms501kf03_lcd_ops);
+ if (IS_ERR(ld))
+ return PTR_ERR(ld);
+
+ lcd->ld = ld;
+
+ if (!lcd->lcd_pd->lcd_enabled) {
+ /*
+ * if lcd panel was off from bootloader then
+ * current lcd status is powerdown and then
+ * it enables lcd panel.
+ */
+ lcd->power = FB_BLANK_POWERDOWN;
+
+ lms501kf03_power(lcd, FB_BLANK_UNBLANK);
+ } else {
+ lcd->power = FB_BLANK_UNBLANK;
+ }
+
+ spi_set_drvdata(spi, lcd);
+
+ dev_info(&spi->dev, "lms501kf03 panel driver has been probed.\n");
+
+ return 0;
+}
+
+static int lms501kf03_remove(struct spi_device *spi)
+{
+ struct lms501kf03 *lcd = spi_get_drvdata(spi);
+
+ lms501kf03_power(lcd, FB_BLANK_POWERDOWN);
+ lcd_device_unregister(lcd->ld);
+
+ return 0;
+}
+
+#if defined(CONFIG_PM)
+
+static int lms501kf03_suspend(struct spi_device *spi, pm_message_t mesg)
+{
+ struct lms501kf03 *lcd = spi_get_drvdata(spi);
+
+ dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
+
+ /*
+ * when lcd panel is suspend, lcd panel becomes off
+ * regardless of status.
+ */
+ return lms501kf03_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static int lms501kf03_resume(struct spi_device *spi)
+{
+ struct lms501kf03 *lcd = spi_get_drvdata(spi);
+
+ lcd->power = FB_BLANK_POWERDOWN;
+
+ return lms501kf03_power(lcd, FB_BLANK_UNBLANK);
+}
+#else
+#define lms501kf03_suspend NULL
+#define lms501kf03_resume NULL
+#endif
+
+static void lms501kf03_shutdown(struct spi_device *spi)
+{
+ struct lms501kf03 *lcd = spi_get_drvdata(spi);
+
+ lms501kf03_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct spi_driver lms501kf03_driver = {
+ .driver = {
+ .name = "lms501kf03",
+ .owner = THIS_MODULE,
+ },
+ .probe = lms501kf03_probe,
+ .remove = lms501kf03_remove,
+ .shutdown = lms501kf03_shutdown,
+ .suspend = lms501kf03_suspend,
+ .resume = lms501kf03_resume,
+};
+
+module_spi_driver(lms501kf03_driver);
+
+MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_DESCRIPTION("lms501kf03 LCD Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
index 3a6d541..146fea8 100644
--- a/drivers/video/backlight/locomolcd.c
+++ b/drivers/video/backlight/locomolcd.c
@@ -107,7 +107,6 @@ void locomolcd_power(int on)
}
EXPORT_SYMBOL(locomolcd_power);
-
static int current_intensity;
static int locomolcd_set_intensity(struct backlight_device *bd)
@@ -122,13 +121,25 @@ static int locomolcd_set_intensity(struct backlight_device *bd)
intensity = 0;
switch (intensity) {
- /* AC and non-AC are handled differently, but produce same results in sharp code? */
- case 0: locomo_frontlight_set(locomolcd_dev, 0, 0, 161); break;
- case 1: locomo_frontlight_set(locomolcd_dev, 117, 0, 161); break;
- case 2: locomo_frontlight_set(locomolcd_dev, 163, 0, 148); break;
- case 3: locomo_frontlight_set(locomolcd_dev, 194, 0, 161); break;
- case 4: locomo_frontlight_set(locomolcd_dev, 194, 1, 161); break;
-
+ /*
+ * AC and non-AC are handled differently,
+ * but produce same results in sharp code?
+ */
+ case 0:
+ locomo_frontlight_set(locomolcd_dev, 0, 0, 161);
+ break;
+ case 1:
+ locomo_frontlight_set(locomolcd_dev, 117, 0, 161);
+ break;
+ case 2:
+ locomo_frontlight_set(locomolcd_dev, 163, 0, 148);
+ break;
+ case 3:
+ locomo_frontlight_set(locomolcd_dev, 194, 0, 161);
+ break;
+ case 4:
+ locomo_frontlight_set(locomolcd_dev, 194, 1, 161);
+ break;
default:
return -ENODEV;
}
@@ -175,9 +186,11 @@ static int locomolcd_probe(struct locomo_dev *ldev)
locomo_gpio_set_dir(ldev->dev.parent, LOCOMO_GPIO_FL_VR, 0);
- /* the poodle_lcd_power function is called for the first time
+ /*
+ * the poodle_lcd_power function is called for the first time
* from fs_initcall, which is before locomo is activated.
- * We need to recall poodle_lcd_power here*/
+ * We need to recall poodle_lcd_power here
+ */
if (machine_is_poodle())
locomolcd_power(1);
@@ -190,8 +203,8 @@ static int locomolcd_probe(struct locomo_dev *ldev)
&ldev->dev, NULL,
&locomobl_data, &props);
- if (IS_ERR (locomolcd_bl_device))
- return PTR_ERR (locomolcd_bl_device);
+ if (IS_ERR(locomolcd_bl_device))
+ return PTR_ERR(locomolcd_bl_device);
/* Set up frontlight so that screen is readable */
locomolcd_bl_device->props.brightness = 2;
@@ -226,7 +239,6 @@ static struct locomo_driver poodle_lcd_driver = {
.resume = locomolcd_resume,
};
-
static int __init locomolcd_init(void)
{
return locomo_driver_register(&poodle_lcd_driver);
diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c
index aa6d4f7..7ae9ae6 100644
--- a/drivers/video/backlight/lp855x_bl.c
+++ b/drivers/video/backlight/lp855x_bl.c
@@ -15,55 +15,78 @@
#include <linux/backlight.h>
#include <linux/err.h>
#include <linux/platform_data/lp855x.h>
-
-/* Registers */
-#define BRIGHTNESS_CTRL 0x00
-#define DEVICE_CTRL 0x01
-#define EEPROM_START 0xA0
-#define EEPROM_END 0xA7
-#define EPROM_START 0xA0
-#define EPROM_END 0xAF
+#include <linux/pwm.h>
+
+/* LP8550/1/2/3/6 Registers */
+#define LP855X_BRIGHTNESS_CTRL 0x00
+#define LP855X_DEVICE_CTRL 0x01
+#define LP855X_EEPROM_START 0xA0
+#define LP855X_EEPROM_END 0xA7
+#define LP8556_EPROM_START 0xA0
+#define LP8556_EPROM_END 0xAF
+
+/* LP8557 Registers */
+#define LP8557_BL_CMD 0x00
+#define LP8557_BL_MASK 0x01
+#define LP8557_BL_ON 0x01
+#define LP8557_BL_OFF 0x00
+#define LP8557_BRIGHTNESS_CTRL 0x04
+#define LP8557_CONFIG 0x10
+#define LP8557_EPROM_START 0x10
+#define LP8557_EPROM_END 0x1E
#define BUF_SIZE 20
#define DEFAULT_BL_NAME "lcd-backlight"
#define MAX_BRIGHTNESS 255
+struct lp855x;
+
+/*
+ * struct lp855x_device_config
+ * @pre_init_device: init device function call before updating the brightness
+ * @reg_brightness: register address for brigthenss control
+ * @reg_devicectrl: register address for device control
+ * @post_init_device: late init device function call
+ */
+struct lp855x_device_config {
+ int (*pre_init_device)(struct lp855x *);
+ u8 reg_brightness;
+ u8 reg_devicectrl;
+ int (*post_init_device)(struct lp855x *);
+};
+
struct lp855x {
const char *chipname;
enum lp855x_chip_id chip_id;
+ struct lp855x_device_config *cfg;
struct i2c_client *client;
struct backlight_device *bl;
struct device *dev;
- struct mutex xfer_lock;
struct lp855x_platform_data *pdata;
+ struct pwm_device *pwm;
};
-static int lp855x_read_byte(struct lp855x *lp, u8 reg, u8 *data)
+static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data)
+{
+ return i2c_smbus_write_byte_data(lp->client, reg, data);
+}
+
+static int lp855x_update_bit(struct lp855x *lp, u8 reg, u8 mask, u8 data)
{
int ret;
+ u8 tmp;
- mutex_lock(&lp->xfer_lock);
ret = i2c_smbus_read_byte_data(lp->client, reg);
if (ret < 0) {
- mutex_unlock(&lp->xfer_lock);
dev_err(lp->dev, "failed to read 0x%.2x\n", reg);
return ret;
}
- mutex_unlock(&lp->xfer_lock);
- *data = (u8)ret;
- return 0;
-}
+ tmp = (u8)ret;
+ tmp &= ~mask;
+ tmp |= data & mask;
-static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data)
-{
- int ret;
-
- mutex_lock(&lp->xfer_lock);
- ret = i2c_smbus_write_byte_data(lp->client, reg, data);
- mutex_unlock(&lp->xfer_lock);
-
- return ret;
+ return lp855x_write_byte(lp, reg, tmp);
}
static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
@@ -75,12 +98,16 @@ static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
case LP8551:
case LP8552:
case LP8553:
- start = EEPROM_START;
- end = EEPROM_END;
+ start = LP855X_EEPROM_START;
+ end = LP855X_EEPROM_END;
break;
case LP8556:
- start = EPROM_START;
- end = EPROM_END;
+ start = LP8556_EPROM_START;
+ end = LP8556_EPROM_END;
+ break;
+ case LP8557:
+ start = LP8557_EPROM_START;
+ end = LP8557_EPROM_END;
break;
default:
return false;
@@ -89,21 +116,76 @@ static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
return (addr >= start && addr <= end);
}
-static int lp855x_init_registers(struct lp855x *lp)
+static int lp8557_bl_off(struct lp855x *lp)
+{
+ /* BL_ON = 0 before updating EPROM settings */
+ return lp855x_update_bit(lp, LP8557_BL_CMD, LP8557_BL_MASK,
+ LP8557_BL_OFF);
+}
+
+static int lp8557_bl_on(struct lp855x *lp)
+{
+ /* BL_ON = 1 after updating EPROM settings */
+ return lp855x_update_bit(lp, LP8557_BL_CMD, LP8557_BL_MASK,
+ LP8557_BL_ON);
+}
+
+static struct lp855x_device_config lp855x_dev_cfg = {
+ .reg_brightness = LP855X_BRIGHTNESS_CTRL,
+ .reg_devicectrl = LP855X_DEVICE_CTRL,
+};
+
+static struct lp855x_device_config lp8557_dev_cfg = {
+ .reg_brightness = LP8557_BRIGHTNESS_CTRL,
+ .reg_devicectrl = LP8557_CONFIG,
+ .pre_init_device = lp8557_bl_off,
+ .post_init_device = lp8557_bl_on,
+};
+
+/*
+ * Device specific configuration flow
+ *
+ * a) pre_init_device(optional)
+ * b) update the brightness register
+ * c) update device control register
+ * d) update ROM area(optional)
+ * e) post_init_device(optional)
+ *
+ */
+static int lp855x_configure(struct lp855x *lp)
{
u8 val, addr;
int i, ret;
struct lp855x_platform_data *pd = lp->pdata;
+ switch (lp->chip_id) {
+ case LP8550 ... LP8556:
+ lp->cfg = &lp855x_dev_cfg;
+ break;
+ case LP8557:
+ lp->cfg = &lp8557_dev_cfg;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (lp->cfg->pre_init_device) {
+ ret = lp->cfg->pre_init_device(lp);
+ if (ret) {
+ dev_err(lp->dev, "pre init device err: %d\n", ret);
+ goto err;
+ }
+ }
+
val = pd->initial_brightness;
- ret = lp855x_write_byte(lp, BRIGHTNESS_CTRL, val);
+ ret = lp855x_write_byte(lp, lp->cfg->reg_brightness, val);
if (ret)
- return ret;
+ goto err;
val = pd->device_control;
- ret = lp855x_write_byte(lp, DEVICE_CTRL, val);
+ ret = lp855x_write_byte(lp, lp->cfg->reg_devicectrl, val);
if (ret)
- return ret;
+ goto err;
if (pd->load_new_rom_data && pd->size_program) {
for (i = 0; i < pd->size_program; i++) {
@@ -114,13 +196,46 @@ static int lp855x_init_registers(struct lp855x *lp)
ret = lp855x_write_byte(lp, addr, val);
if (ret)
- return ret;
+ goto err;
}
}
+ if (lp->cfg->post_init_device) {
+ ret = lp->cfg->post_init_device(lp);
+ if (ret) {
+ dev_err(lp->dev, "post init device err: %d\n", ret);
+ goto err;
+ }
+ }
+
+ return 0;
+
+err:
return ret;
}
+static void lp855x_pwm_ctrl(struct lp855x *lp, int br, int max_br)
+{
+ unsigned int period = lp->pdata->period_ns;
+ unsigned int duty = br * period / max_br;
+ struct pwm_device *pwm;
+
+ /* request pwm device with the consumer name */
+ if (!lp->pwm) {
+ pwm = devm_pwm_get(lp->dev, lp->chipname);
+ if (IS_ERR(pwm))
+ return;
+
+ lp->pwm = pwm;
+ }
+
+ pwm_config(lp->pwm, duty, period);
+ if (duty)
+ pwm_enable(lp->pwm);
+ else
+ pwm_disable(lp->pwm);
+}
+
static int lp855x_bl_update_status(struct backlight_device *bl)
{
struct lp855x *lp = bl_get_data(bl);
@@ -130,16 +245,14 @@ static int lp855x_bl_update_status(struct backlight_device *bl)
bl->props.brightness = 0;
if (mode == PWM_BASED) {
- struct lp855x_pwm_data *pd = &lp->pdata->pwm_data;
int br = bl->props.brightness;
int max_br = bl->props.max_brightness;
- if (pd->pwm_set_intensity)
- pd->pwm_set_intensity(br, max_br);
+ lp855x_pwm_ctrl(lp, br, max_br);
} else if (mode == REGISTER_BASED) {
u8 val = bl->props.brightness;
- lp855x_write_byte(lp, BRIGHTNESS_CTRL, val);
+ lp855x_write_byte(lp, lp->cfg->reg_brightness, val);
}
return 0;
@@ -147,23 +260,6 @@ static int lp855x_bl_update_status(struct backlight_device *bl)
static int lp855x_bl_get_brightness(struct backlight_device *bl)
{
- struct lp855x *lp = bl_get_data(bl);
- enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
-
- if (mode == PWM_BASED) {
- struct lp855x_pwm_data *pd = &lp->pdata->pwm_data;
- int max_br = bl->props.max_brightness;
-
- if (pd->pwm_get_intensity)
- bl->props.brightness = pd->pwm_get_intensity(max_br);
-
- } else if (mode == REGISTER_BASED) {
- u8 val = 0;
-
- lp855x_read_byte(lp, BRIGHTNESS_CTRL, &val);
- bl->props.brightness = val;
- }
-
return bl->props.brightness;
}
@@ -266,13 +362,10 @@ static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
lp->chip_id = id->driver_data;
i2c_set_clientdata(cl, lp);
- mutex_init(&lp->xfer_lock);
-
- ret = lp855x_init_registers(lp);
+ ret = lp855x_configure(lp);
if (ret) {
- dev_err(lp->dev, "i2c communication err: %d", ret);
- if (mode == REGISTER_BASED)
- goto err_dev;
+ dev_err(lp->dev, "device config err: %d", ret);
+ goto err_dev;
}
ret = lp855x_backlight_register(lp);
@@ -297,7 +390,7 @@ err_dev:
return ret;
}
-static int __devexit lp855x_remove(struct i2c_client *cl)
+static int lp855x_remove(struct i2c_client *cl)
{
struct lp855x *lp = i2c_get_clientdata(cl);
@@ -315,6 +408,7 @@ static const struct i2c_device_id lp855x_ids[] = {
{"lp8552", LP8552},
{"lp8553", LP8553},
{"lp8556", LP8556},
+ {"lp8557", LP8557},
{ }
};
MODULE_DEVICE_TABLE(i2c, lp855x_ids);
@@ -324,7 +418,7 @@ static struct i2c_driver lp855x_driver = {
.name = "lp855x",
},
.probe = lp855x_probe,
- .remove = __devexit_p(lp855x_remove),
+ .remove = lp855x_remove,
.id_table = lp855x_ids,
};
diff --git a/drivers/video/backlight/lp8788_bl.c b/drivers/video/backlight/lp8788_bl.c
new file mode 100644
index 0000000..4bb8b4f
--- /dev/null
+++ b/drivers/video/backlight/lp8788_bl.c
@@ -0,0 +1,333 @@
+/*
+ * TI LP8788 MFD - backlight driver
+ *
+ * Copyright 2012 Texas Instruments
+ *
+ * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/mfd/lp8788.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+
+/* Register address */
+#define LP8788_BL_CONFIG 0x96
+#define LP8788_BL_EN BIT(0)
+#define LP8788_BL_PWM_INPUT_EN BIT(5)
+#define LP8788_BL_FULLSCALE_SHIFT 2
+#define LP8788_BL_DIM_MODE_SHIFT 1
+#define LP8788_BL_PWM_POLARITY_SHIFT 6
+
+#define LP8788_BL_BRIGHTNESS 0x97
+
+#define LP8788_BL_RAMP 0x98
+#define LP8788_BL_RAMP_RISE_SHIFT 4
+
+#define MAX_BRIGHTNESS 127
+#define DEFAULT_BL_NAME "lcd-backlight"
+
+struct lp8788_bl_config {
+ enum lp8788_bl_ctrl_mode bl_mode;
+ enum lp8788_bl_dim_mode dim_mode;
+ enum lp8788_bl_full_scale_current full_scale;
+ enum lp8788_bl_ramp_step rise_time;
+ enum lp8788_bl_ramp_step fall_time;
+ enum pwm_polarity pwm_pol;
+};
+
+struct lp8788_bl {
+ struct lp8788 *lp;
+ struct backlight_device *bl_dev;
+ struct lp8788_backlight_platform_data *pdata;
+ enum lp8788_bl_ctrl_mode mode;
+ struct pwm_device *pwm;
+};
+
+struct lp8788_bl_config default_bl_config = {
+ .bl_mode = LP8788_BL_REGISTER_ONLY,
+ .dim_mode = LP8788_DIM_EXPONENTIAL,
+ .full_scale = LP8788_FULLSCALE_1900uA,
+ .rise_time = LP8788_RAMP_8192us,
+ .fall_time = LP8788_RAMP_8192us,
+ .pwm_pol = PWM_POLARITY_NORMAL,
+};
+
+static inline bool is_brightness_ctrl_by_pwm(enum lp8788_bl_ctrl_mode mode)
+{
+ return (mode == LP8788_BL_COMB_PWM_BASED);
+}
+
+static inline bool is_brightness_ctrl_by_register(enum lp8788_bl_ctrl_mode mode)
+{
+ return (mode == LP8788_BL_REGISTER_ONLY ||
+ mode == LP8788_BL_COMB_REGISTER_BASED);
+}
+
+static int lp8788_backlight_configure(struct lp8788_bl *bl)
+{
+ struct lp8788_backlight_platform_data *pdata = bl->pdata;
+ struct lp8788_bl_config *cfg = &default_bl_config;
+ int ret;
+ u8 val;
+
+ /*
+ * Update chip configuration if platform data exists,
+ * otherwise use the default settings.
+ */
+ if (pdata) {
+ cfg->bl_mode = pdata->bl_mode;
+ cfg->dim_mode = pdata->dim_mode;
+ cfg->full_scale = pdata->full_scale;
+ cfg->rise_time = pdata->rise_time;
+ cfg->fall_time = pdata->fall_time;
+ cfg->pwm_pol = pdata->pwm_pol;
+ }
+
+ /* Brightness ramp up/down */
+ val = (cfg->rise_time << LP8788_BL_RAMP_RISE_SHIFT) | cfg->fall_time;
+ ret = lp8788_write_byte(bl->lp, LP8788_BL_RAMP, val);
+ if (ret)
+ return ret;
+
+ /* Fullscale current setting */
+ val = (cfg->full_scale << LP8788_BL_FULLSCALE_SHIFT) |
+ (cfg->dim_mode << LP8788_BL_DIM_MODE_SHIFT);
+
+ /* Brightness control mode */
+ switch (cfg->bl_mode) {
+ case LP8788_BL_REGISTER_ONLY:
+ val |= LP8788_BL_EN;
+ break;
+ case LP8788_BL_COMB_PWM_BASED:
+ case LP8788_BL_COMB_REGISTER_BASED:
+ val |= LP8788_BL_EN | LP8788_BL_PWM_INPUT_EN |
+ (cfg->pwm_pol << LP8788_BL_PWM_POLARITY_SHIFT);
+ break;
+ default:
+ dev_err(bl->lp->dev, "invalid mode: %d\n", cfg->bl_mode);
+ return -EINVAL;
+ }
+
+ bl->mode = cfg->bl_mode;
+
+ return lp8788_write_byte(bl->lp, LP8788_BL_CONFIG, val);
+}
+
+static void lp8788_pwm_ctrl(struct lp8788_bl *bl, int br, int max_br)
+{
+ unsigned int period;
+ unsigned int duty;
+ struct device *dev;
+ struct pwm_device *pwm;
+
+ if (!bl->pdata)
+ return;
+
+ period = bl->pdata->period_ns;
+ duty = br * period / max_br;
+ dev = bl->lp->dev;
+
+ /* request PWM device with the consumer name */
+ if (!bl->pwm) {
+ pwm = devm_pwm_get(dev, LP8788_DEV_BACKLIGHT);
+ if (IS_ERR(pwm)) {
+ dev_err(dev, "can not get PWM device\n");
+ return;
+ }
+
+ bl->pwm = pwm;
+ }
+
+ pwm_config(bl->pwm, duty, period);
+ if (duty)
+ pwm_enable(bl->pwm);
+ else
+ pwm_disable(bl->pwm);
+}
+
+static int lp8788_bl_update_status(struct backlight_device *bl_dev)
+{
+ struct lp8788_bl *bl = bl_get_data(bl_dev);
+ enum lp8788_bl_ctrl_mode mode = bl->mode;
+
+ if (bl_dev->props.state & BL_CORE_SUSPENDED)
+ bl_dev->props.brightness = 0;
+
+ if (is_brightness_ctrl_by_pwm(mode)) {
+ int brt = bl_dev->props.brightness;
+ int max = bl_dev->props.max_brightness;
+
+ lp8788_pwm_ctrl(bl, brt, max);
+ } else if (is_brightness_ctrl_by_register(mode)) {
+ u8 brt = bl_dev->props.brightness;
+
+ lp8788_write_byte(bl->lp, LP8788_BL_BRIGHTNESS, brt);
+ }
+
+ return 0;
+}
+
+static int lp8788_bl_get_brightness(struct backlight_device *bl_dev)
+{
+ return bl_dev->props.brightness;
+}
+
+static const struct backlight_ops lp8788_bl_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = lp8788_bl_update_status,
+ .get_brightness = lp8788_bl_get_brightness,
+};
+
+static int lp8788_backlight_register(struct lp8788_bl *bl)
+{
+ struct backlight_device *bl_dev;
+ struct backlight_properties props;
+ struct lp8788_backlight_platform_data *pdata = bl->pdata;
+ int init_brt;
+ char *name;
+
+ props.type = BACKLIGHT_PLATFORM;
+ props.max_brightness = MAX_BRIGHTNESS;
+
+ /* Initial brightness */
+ if (pdata)
+ init_brt = min_t(int, pdata->initial_brightness,
+ props.max_brightness);
+ else
+ init_brt = 0;
+
+ props.brightness = init_brt;
+
+ /* Backlight device name */
+ if (!pdata || !pdata->name)
+ name = DEFAULT_BL_NAME;
+ else
+ name = pdata->name;
+
+ bl_dev = backlight_device_register(name, bl->lp->dev, bl,
+ &lp8788_bl_ops, &props);
+ if (IS_ERR(bl_dev))
+ return PTR_ERR(bl_dev);
+
+ bl->bl_dev = bl_dev;
+
+ return 0;
+}
+
+static void lp8788_backlight_unregister(struct lp8788_bl *bl)
+{
+ struct backlight_device *bl_dev = bl->bl_dev;
+
+ if (bl_dev)
+ backlight_device_unregister(bl_dev);
+}
+
+static ssize_t lp8788_get_bl_ctl_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8788_bl *bl = dev_get_drvdata(dev);
+ enum lp8788_bl_ctrl_mode mode = bl->mode;
+ char *strmode;
+
+ if (is_brightness_ctrl_by_pwm(mode))
+ strmode = "PWM based";
+ else if (is_brightness_ctrl_by_register(mode))
+ strmode = "Register based";
+ else
+ strmode = "Invalid mode";
+
+ return scnprintf(buf, PAGE_SIZE, "%s\n", strmode);
+}
+
+static DEVICE_ATTR(bl_ctl_mode, S_IRUGO, lp8788_get_bl_ctl_mode, NULL);
+
+static struct attribute *lp8788_attributes[] = {
+ &dev_attr_bl_ctl_mode.attr,
+ NULL,
+};
+
+static const struct attribute_group lp8788_attr_group = {
+ .attrs = lp8788_attributes,
+};
+
+static int lp8788_backlight_probe(struct platform_device *pdev)
+{
+ struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
+ struct lp8788_bl *bl;
+ int ret;
+
+ bl = devm_kzalloc(lp->dev, sizeof(struct lp8788_bl), GFP_KERNEL);
+ if (!bl)
+ return -ENOMEM;
+
+ bl->lp = lp;
+ if (lp->pdata)
+ bl->pdata = lp->pdata->bl_pdata;
+
+ platform_set_drvdata(pdev, bl);
+
+ ret = lp8788_backlight_configure(bl);
+ if (ret) {
+ dev_err(lp->dev, "backlight config err: %d\n", ret);
+ goto err_dev;
+ }
+
+ ret = lp8788_backlight_register(bl);
+ if (ret) {
+ dev_err(lp->dev, "register backlight err: %d\n", ret);
+ goto err_dev;
+ }
+
+ ret = sysfs_create_group(&pdev->dev.kobj, &lp8788_attr_group);
+ if (ret) {
+ dev_err(lp->dev, "register sysfs err: %d\n", ret);
+ goto err_sysfs;
+ }
+
+ backlight_update_status(bl->bl_dev);
+
+ return 0;
+
+err_sysfs:
+ lp8788_backlight_unregister(bl);
+err_dev:
+ return ret;
+}
+
+static int lp8788_backlight_remove(struct platform_device *pdev)
+{
+ struct lp8788_bl *bl = platform_get_drvdata(pdev);
+ struct backlight_device *bl_dev = bl->bl_dev;
+
+ bl_dev->props.brightness = 0;
+ backlight_update_status(bl_dev);
+ sysfs_remove_group(&pdev->dev.kobj, &lp8788_attr_group);
+ lp8788_backlight_unregister(bl);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver lp8788_bl_driver = {
+ .probe = lp8788_backlight_probe,
+ .remove = lp8788_backlight_remove,
+ .driver = {
+ .name = LP8788_DEV_BACKLIGHT,
+ .owner = THIS_MODULE,
+ },
+};
+module_platform_driver(lp8788_bl_driver);
+
+MODULE_DESCRIPTION("Texas Instruments LP8788 Backlight Driver");
+MODULE_AUTHOR("Milo Kim");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:lp8788-backlight");
diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c
index 4066a5b..c0b4b8f 100644
--- a/drivers/video/backlight/ltv350qv.c
+++ b/drivers/video/backlight/ltv350qv.c
@@ -226,7 +226,7 @@ static struct lcd_ops ltv_ops = {
.set_power = ltv350qv_set_power,
};
-static int __devinit ltv350qv_probe(struct spi_device *spi)
+static int ltv350qv_probe(struct spi_device *spi)
{
struct ltv350qv *lcd;
struct lcd_device *ld;
@@ -252,7 +252,7 @@ static int __devinit ltv350qv_probe(struct spi_device *spi)
if (ret)
goto out_unregister;
- dev_set_drvdata(&spi->dev, lcd);
+ spi_set_drvdata(spi, lcd);
return 0;
@@ -261,9 +261,9 @@ out_unregister:
return ret;
}
-static int __devexit ltv350qv_remove(struct spi_device *spi)
+static int ltv350qv_remove(struct spi_device *spi)
{
- struct ltv350qv *lcd = dev_get_drvdata(&spi->dev);
+ struct ltv350qv *lcd = spi_get_drvdata(spi);
ltv350qv_power(lcd, FB_BLANK_POWERDOWN);
lcd_device_unregister(lcd->ld);
@@ -274,14 +274,14 @@ static int __devexit ltv350qv_remove(struct spi_device *spi)
#ifdef CONFIG_PM
static int ltv350qv_suspend(struct spi_device *spi, pm_message_t state)
{
- struct ltv350qv *lcd = dev_get_drvdata(&spi->dev);
+ struct ltv350qv *lcd = spi_get_drvdata(spi);
return ltv350qv_power(lcd, FB_BLANK_POWERDOWN);
}
static int ltv350qv_resume(struct spi_device *spi)
{
- struct ltv350qv *lcd = dev_get_drvdata(&spi->dev);
+ struct ltv350qv *lcd = spi_get_drvdata(spi);
return ltv350qv_power(lcd, FB_BLANK_UNBLANK);
}
@@ -293,7 +293,7 @@ static int ltv350qv_resume(struct spi_device *spi)
/* Power down all displays on reboot, poweroff or halt */
static void ltv350qv_shutdown(struct spi_device *spi)
{
- struct ltv350qv *lcd = dev_get_drvdata(&spi->dev);
+ struct ltv350qv *lcd = spi_get_drvdata(spi);
ltv350qv_power(lcd, FB_BLANK_POWERDOWN);
}
@@ -305,7 +305,7 @@ static struct spi_driver ltv350qv_driver = {
},
.probe = ltv350qv_probe,
- .remove = __devexit_p(ltv350qv_remove),
+ .remove = ltv350qv_remove,
.shutdown = ltv350qv_shutdown,
.suspend = ltv350qv_suspend,
.resume = ltv350qv_resume,
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c
index f72ba54..5ca11b0 100644
--- a/drivers/video/backlight/max8925_bl.c
+++ b/drivers/video/backlight/max8925_bl.c
@@ -101,7 +101,30 @@ static const struct backlight_ops max8925_backlight_ops = {
.get_brightness = max8925_backlight_get_brightness,
};
-static int __devinit max8925_backlight_probe(struct platform_device *pdev)
+#ifdef CONFIG_OF
+static int max8925_backlight_dt_init(struct platform_device *pdev,
+ struct max8925_backlight_pdata *pdata)
+{
+ struct device_node *nproot = pdev->dev.parent->of_node, *np;
+ int dual_string;
+
+ if (!nproot)
+ return -ENODEV;
+ np = of_find_node_by_name(nproot, "backlight");
+ if (!np) {
+ dev_err(&pdev->dev, "failed to find backlight node\n");
+ return -ENODEV;
+ }
+
+ of_property_read_u32(np, "maxim,max8925-dual-string", &dual_string);
+ pdata->dual_string = dual_string;
+ return 0;
+}
+#else
+#define max8925_backlight_dt_init(x, y) (-1)
+#endif
+
+static int max8925_backlight_probe(struct platform_device *pdev)
{
struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
struct max8925_backlight_pdata *pdata = pdev->dev.platform_data;
@@ -120,15 +143,13 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_REG, 0);
if (!res) {
dev_err(&pdev->dev, "No REG resource for mode control!\n");
- ret = -ENXIO;
- goto out;
+ return -ENXIO;
}
data->reg_mode_cntl = res->start;
res = platform_get_resource(pdev, IORESOURCE_REG, 1);
if (!res) {
dev_err(&pdev->dev, "No REG resource for control!\n");
- ret = -ENXIO;
- goto out;
+ return -ENXIO;
}
data->reg_cntl = res->start;
@@ -142,14 +163,20 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
&max8925_backlight_ops, &props);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
- ret = PTR_ERR(bl);
- goto out;
+ return PTR_ERR(bl);
}
bl->props.brightness = MAX_BRIGHTNESS;
platform_set_drvdata(pdev, bl);
value = 0;
+ if (pdev->dev.parent->of_node && !pdata) {
+ pdata = devm_kzalloc(&pdev->dev,
+ sizeof(struct max8925_backlight_pdata),
+ GFP_KERNEL);
+ max8925_backlight_dt_init(pdev, pdata);
+ }
+
if (pdata) {
if (pdata->lxw_scl)
value |= (1 << 7);
@@ -161,17 +188,14 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 0xfe, value);
if (ret < 0)
goto out_brt;
-
backlight_update_status(bl);
return 0;
out_brt:
backlight_device_unregister(bl);
-out:
- devm_kfree(&pdev->dev, data);
return ret;
}
-static int __devexit max8925_backlight_remove(struct platform_device *pdev)
+static int max8925_backlight_remove(struct platform_device *pdev)
{
struct backlight_device *bl = platform_get_drvdata(pdev);
@@ -185,7 +209,7 @@ static struct platform_driver max8925_backlight_driver = {
.owner = THIS_MODULE,
},
.probe = max8925_backlight_probe,
- .remove = __devexit_p(max8925_backlight_remove),
+ .remove = max8925_backlight_remove,
};
module_platform_driver(max8925_backlight_driver);
diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c
index 9a046a4..6271101 100644
--- a/drivers/video/backlight/omap1_bl.c
+++ b/drivers/video/backlight/omap1_bl.c
@@ -42,12 +42,12 @@ struct omap_backlight {
struct omap_backlight_config *pdata;
};
-static void inline omapbl_send_intensity(int intensity)
+static inline void omapbl_send_intensity(int intensity)
{
omap_writeb(intensity, OMAP_PWL_ENABLE);
}
-static void inline omapbl_send_enable(int enable)
+static inline void omapbl_send_enable(int enable)
{
omap_writeb(enable, OMAP_PWL_CLK_ENABLE);
}
@@ -77,7 +77,7 @@ static void omapbl_blank(struct omap_backlight *bl, int mode)
static int omapbl_suspend(struct platform_device *pdev, pm_message_t state)
{
struct backlight_device *dev = platform_get_drvdata(pdev);
- struct omap_backlight *bl = dev_get_drvdata(&dev->dev);
+ struct omap_backlight *bl = bl_get_data(dev);
omapbl_blank(bl, FB_BLANK_POWERDOWN);
return 0;
@@ -86,7 +86,7 @@ static int omapbl_suspend(struct platform_device *pdev, pm_message_t state)
static int omapbl_resume(struct platform_device *pdev)
{
struct backlight_device *dev = platform_get_drvdata(pdev);
- struct omap_backlight *bl = dev_get_drvdata(&dev->dev);
+ struct omap_backlight *bl = bl_get_data(dev);
omapbl_blank(bl, bl->powermode);
return 0;
@@ -98,7 +98,7 @@ static int omapbl_resume(struct platform_device *pdev)
static int omapbl_set_power(struct backlight_device *dev, int state)
{
- struct omap_backlight *bl = dev_get_drvdata(&dev->dev);
+ struct omap_backlight *bl = bl_get_data(dev);
omapbl_blank(bl, state);
bl->powermode = state;
@@ -108,7 +108,7 @@ static int omapbl_set_power(struct backlight_device *dev, int state)
static int omapbl_update_status(struct backlight_device *dev)
{
- struct omap_backlight *bl = dev_get_drvdata(&dev->dev);
+ struct omap_backlight *bl = bl_get_data(dev);
if (bl->current_intensity != dev->props.brightness) {
if (bl->powermode == FB_BLANK_UNBLANK)
@@ -124,7 +124,7 @@ static int omapbl_update_status(struct backlight_device *dev)
static int omapbl_get_intensity(struct backlight_device *dev)
{
- struct omap_backlight *bl = dev_get_drvdata(&dev->dev);
+ struct omap_backlight *bl = bl_get_data(dev);
return bl->current_intensity;
}
diff --git a/drivers/video/backlight/ot200_bl.c b/drivers/video/backlight/ot200_bl.c
index 469cf0f..fdbb6ee 100644
--- a/drivers/video/backlight/ot200_bl.c
+++ b/drivers/video/backlight/ot200_bl.c
@@ -14,6 +14,7 @@
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/gpio.h>
+#include <linux/platform_device.h>
#include <linux/cs5535.h>
static struct cs5535_mfgpt_timer *pwm_timer;
diff --git a/drivers/video/backlight/pandora_bl.c b/drivers/video/backlight/pandora_bl.c
index 4ec3074..633b0a2 100644
--- a/drivers/video/backlight/pandora_bl.c
+++ b/drivers/video/backlight/pandora_bl.c
@@ -71,8 +71,7 @@ static int pandora_backlight_update_status(struct backlight_device *bl)
* set PWM duty cycle to max. TPS61161 seems to use this
* to calibrate it's PWM sensitivity when it starts.
*/
- twl_i2c_write_u8(TWL4030_MODULE_PWM0, MAX_VALUE,
- TWL_PWM0_OFF);
+ twl_i2c_write_u8(TWL_MODULE_PWM, MAX_VALUE, TWL_PWM0_OFF);
/* first enable clock, then PWM0 out */
twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_GPBR1);
@@ -90,8 +89,7 @@ static int pandora_backlight_update_status(struct backlight_device *bl)
usleep_range(2000, 10000);
}
- twl_i2c_write_u8(TWL4030_MODULE_PWM0, MIN_VALUE + brightness,
- TWL_PWM0_OFF);
+ twl_i2c_write_u8(TWL_MODULE_PWM, MIN_VALUE + brightness, TWL_PWM0_OFF);
done:
if (brightness != 0)
@@ -132,7 +130,7 @@ static int pandora_backlight_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, bl);
/* 64 cycle period, ON position 0 */
- twl_i2c_write_u8(TWL4030_MODULE_PWM0, 0x80, TWL_PWM0_ON);
+ twl_i2c_write_u8(TWL_MODULE_PWM, 0x80, TWL_PWM0_ON);
bl->props.state |= PANDORABL_WAS_OFF;
bl->props.brightness = MAX_USER_VALUE;
diff --git a/drivers/video/backlight/pcf50633-backlight.c b/drivers/video/backlight/pcf50633-backlight.c
index c092159..e87c7a3 100644
--- a/drivers/video/backlight/pcf50633-backlight.c
+++ b/drivers/video/backlight/pcf50633-backlight.c
@@ -52,7 +52,7 @@ int pcf50633_bl_set_brightness_limit(struct pcf50633 *pcf, unsigned int limit)
pcf_bl->brightness_limit = limit & 0x3f;
backlight_update_status(pcf_bl->bl);
- return 0;
+ return 0;
}
static int pcf50633_bl_update_status(struct backlight_device *bl)
@@ -99,7 +99,7 @@ static const struct backlight_ops pcf50633_bl_ops = {
.options = BL_CORE_SUSPENDRESUME,
};
-static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
+static int pcf50633_bl_probe(struct platform_device *pdev)
{
struct pcf50633_bl *pcf_bl;
struct device *parent = pdev->dev.parent;
@@ -136,8 +136,10 @@ static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
pcf50633_reg_write(pcf_bl->pcf, PCF50633_REG_LEDDIM, pdata->ramp_time);
- /* Should be different from bl_props.brightness, so we do not exit
- * update_status early the first time it's called */
+ /*
+ * Should be different from bl_props.brightness, so we do not exit
+ * update_status early the first time it's called
+ */
pcf_bl->brightness = pcf_bl->bl->props.brightness + 1;
backlight_update_status(pcf_bl->bl);
@@ -145,7 +147,7 @@ static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit pcf50633_bl_remove(struct platform_device *pdev)
+static int pcf50633_bl_remove(struct platform_device *pdev)
{
struct pcf50633_bl *pcf_bl = platform_get_drvdata(pdev);
@@ -158,7 +160,7 @@ static int __devexit pcf50633_bl_remove(struct platform_device *pdev)
static struct platform_driver pcf50633_bl_driver = {
.probe = pcf50633_bl_probe,
- .remove = __devexit_p(pcf50633_bl_remove),
+ .remove = pcf50633_bl_remove,
.driver = {
.name = "pcf50633-backlight",
},
diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c
index ca4f5d70..17a6b83 100644
--- a/drivers/video/backlight/platform_lcd.c
+++ b/drivers/video/backlight/platform_lcd.c
@@ -27,7 +27,7 @@ struct platform_lcd {
struct plat_lcd_data *pdata;
unsigned int power;
- unsigned int suspended : 1;
+ unsigned int suspended:1;
};
static inline struct platform_lcd *to_our_lcd(struct lcd_device *lcd)
@@ -73,7 +73,7 @@ static struct lcd_ops platform_lcd_ops = {
.check_fb = platform_lcd_match,
};
-static int __devinit platform_lcd_probe(struct platform_device *pdev)
+static int platform_lcd_probe(struct platform_device *pdev)
{
struct plat_lcd_data *pdata;
struct platform_lcd *plcd;
@@ -112,7 +112,7 @@ static int __devinit platform_lcd_probe(struct platform_device *pdev)
return err;
}
-static int __devexit platform_lcd_remove(struct platform_device *pdev)
+static int platform_lcd_remove(struct platform_device *pdev)
{
struct platform_lcd *plcd = platform_get_drvdata(pdev);
@@ -164,7 +164,7 @@ static struct platform_driver platform_lcd_driver = {
.of_match_table = of_match_ptr(platform_lcd_of_match),
},
.probe = platform_lcd_probe,
- .remove = __devexit_p(platform_lcd_remove),
+ .remove = platform_lcd_remove,
};
module_platform_driver(platform_lcd_driver);
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 069983c..fa00304 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -37,14 +37,13 @@ struct pwm_bl_data {
static int pwm_backlight_update_status(struct backlight_device *bl)
{
- struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
+ struct pwm_bl_data *pb = bl_get_data(bl);
int brightness = bl->props.brightness;
int max = bl->props.max_brightness;
- if (bl->props.power != FB_BLANK_UNBLANK)
- brightness = 0;
-
- if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+ if (bl->props.power != FB_BLANK_UNBLANK ||
+ bl->props.fb_blank != FB_BLANK_UNBLANK ||
+ bl->props.state & BL_CORE_FBBLANK)
brightness = 0;
if (pb->notify)
@@ -83,7 +82,7 @@ static int pwm_backlight_get_brightness(struct backlight_device *bl)
static int pwm_backlight_check_fb(struct backlight_device *bl,
struct fb_info *info)
{
- struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
+ struct pwm_bl_data *pb = bl_get_data(bl);
return !pb->check_fb || pb->check_fb(pb->dev, info);
}
@@ -135,12 +134,6 @@ static int pwm_backlight_parse_dt(struct device *dev,
if (ret < 0)
return ret;
- if (value >= data->max_brightness) {
- dev_warn(dev, "invalid default brightness level: %u, using %u\n",
- value, data->max_brightness - 1);
- value = data->max_brightness - 1;
- }
-
data->dft_brightness = value;
data->max_brightness--;
}
@@ -249,6 +242,13 @@ static int pwm_backlight_probe(struct platform_device *pdev)
goto err_alloc;
}
+ if (data->dft_brightness > data->max_brightness) {
+ dev_warn(&pdev->dev,
+ "invalid default brightness level: %u, using %u\n",
+ data->dft_brightness, data->max_brightness);
+ data->dft_brightness = data->max_brightness;
+ }
+
bl->props.brightness = data->dft_brightness;
backlight_update_status(bl);
@@ -264,7 +264,7 @@ err_alloc:
static int pwm_backlight_remove(struct platform_device *pdev)
{
struct backlight_device *bl = platform_get_drvdata(pdev);
- struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
+ struct pwm_bl_data *pb = bl_get_data(bl);
backlight_device_unregister(bl);
pwm_config(pb->pwm, 0, pb->period);
@@ -278,7 +278,7 @@ static int pwm_backlight_remove(struct platform_device *pdev)
static int pwm_backlight_suspend(struct device *dev)
{
struct backlight_device *bl = dev_get_drvdata(dev);
- struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
+ struct pwm_bl_data *pb = bl_get_data(bl);
if (pb->notify)
pb->notify(pb->dev, 0);
diff --git a/drivers/video/backlight/s6e63m0.c b/drivers/video/backlight/s6e63m0.c
index 6437ae4..9c2677f 100644
--- a/drivers/video/backlight/s6e63m0.c
+++ b/drivers/video/backlight/s6e63m0.c
@@ -9,28 +9,19 @@
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#include <linux/wait.h>
-#include <linux/fb.h>
+#include <linux/backlight.h>
#include <linux/delay.h>
+#include <linux/fb.h>
#include <linux/gpio.h>
-#include <linux/spi/spi.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/lcd.h>
-#include <linux/backlight.h>
#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/wait.h>
#include "s6e63m0_gamma.h"
@@ -43,8 +34,6 @@
#define MIN_BRIGHTNESS 0
#define MAX_BRIGHTNESS 10
-#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
-
struct s6e63m0 {
struct device *dev;
struct spi_device *spi;
@@ -57,7 +46,7 @@ struct s6e63m0 {
struct lcd_platform_data *lcd_pd;
};
-static const unsigned short SEQ_PANEL_CONDITION_SET[] = {
+static const unsigned short seq_panel_condition_set[] = {
0xF8, 0x01,
DATA_ONLY, 0x27,
DATA_ONLY, 0x27,
@@ -76,7 +65,7 @@ static const unsigned short SEQ_PANEL_CONDITION_SET[] = {
ENDDEF, 0x0000
};
-static const unsigned short SEQ_DISPLAY_CONDITION_SET[] = {
+static const unsigned short seq_display_condition_set[] = {
0xf2, 0x02,
DATA_ONLY, 0x03,
DATA_ONLY, 0x1c,
@@ -90,7 +79,7 @@ static const unsigned short SEQ_DISPLAY_CONDITION_SET[] = {
ENDDEF, 0x0000
};
-static const unsigned short SEQ_GAMMA_SETTING[] = {
+static const unsigned short seq_gamma_setting[] = {
0xfa, 0x00,
DATA_ONLY, 0x18,
DATA_ONLY, 0x08,
@@ -119,7 +108,7 @@ static const unsigned short SEQ_GAMMA_SETTING[] = {
ENDDEF, 0x0000
};
-static const unsigned short SEQ_ETC_CONDITION_SET[] = {
+static const unsigned short seq_etc_condition_set[] = {
0xf6, 0x00,
DATA_ONLY, 0x8c,
DATA_ONLY, 0x07,
@@ -318,47 +307,47 @@ static const unsigned short SEQ_ETC_CONDITION_SET[] = {
ENDDEF, 0x0000
};
-static const unsigned short SEQ_ACL_ON[] = {
+static const unsigned short seq_acl_on[] = {
/* ACL on */
0xc0, 0x01,
ENDDEF, 0x0000
};
-static const unsigned short SEQ_ACL_OFF[] = {
+static const unsigned short seq_acl_off[] = {
/* ACL off */
0xc0, 0x00,
ENDDEF, 0x0000
};
-static const unsigned short SEQ_ELVSS_ON[] = {
+static const unsigned short seq_elvss_on[] = {
/* ELVSS on */
0xb1, 0x0b,
ENDDEF, 0x0000
};
-static const unsigned short SEQ_ELVSS_OFF[] = {
+static const unsigned short seq_elvss_off[] = {
/* ELVSS off */
0xb1, 0x0a,
ENDDEF, 0x0000
};
-static const unsigned short SEQ_STAND_BY_OFF[] = {
+static const unsigned short seq_stand_by_off[] = {
0x11, COMMAND_ONLY,
ENDDEF, 0x0000
};
-static const unsigned short SEQ_STAND_BY_ON[] = {
+static const unsigned short seq_stand_by_on[] = {
0x10, COMMAND_ONLY,
ENDDEF, 0x0000
};
-static const unsigned short SEQ_DISPLAY_ON[] = {
+static const unsigned short seq_display_on[] = {
0x29, COMMAND_ONLY,
ENDDEF, 0x0000
@@ -406,8 +395,9 @@ static int s6e63m0_panel_send_sequence(struct s6e63m0 *lcd,
ret = s6e63m0_spi_write(lcd, wbuf[i], wbuf[i+1]);
if (ret)
break;
- } else
- udelay(wbuf[i+1]*1000);
+ } else {
+ msleep(wbuf[i+1]);
+ }
i += 2;
}
@@ -457,12 +447,12 @@ static int s6e63m0_ldi_init(struct s6e63m0 *lcd)
{
int ret, i;
const unsigned short *init_seq[] = {
- SEQ_PANEL_CONDITION_SET,
- SEQ_DISPLAY_CONDITION_SET,
- SEQ_GAMMA_SETTING,
- SEQ_ETC_CONDITION_SET,
- SEQ_ACL_ON,
- SEQ_ELVSS_ON,
+ seq_panel_condition_set,
+ seq_display_condition_set,
+ seq_gamma_setting,
+ seq_etc_condition_set,
+ seq_acl_on,
+ seq_elvss_on,
};
for (i = 0; i < ARRAY_SIZE(init_seq); i++) {
@@ -478,8 +468,8 @@ static int s6e63m0_ldi_enable(struct s6e63m0 *lcd)
{
int ret = 0, i;
const unsigned short *enable_seq[] = {
- SEQ_STAND_BY_OFF,
- SEQ_DISPLAY_ON,
+ seq_stand_by_off,
+ seq_display_on,
};
for (i = 0; i < ARRAY_SIZE(enable_seq); i++) {
@@ -495,43 +485,39 @@ static int s6e63m0_ldi_disable(struct s6e63m0 *lcd)
{
int ret;
- ret = s6e63m0_panel_send_sequence(lcd, SEQ_STAND_BY_ON);
+ ret = s6e63m0_panel_send_sequence(lcd, seq_stand_by_on);
return ret;
}
+static int s6e63m0_power_is_on(int power)
+{
+ return power <= FB_BLANK_NORMAL;
+}
+
static int s6e63m0_power_on(struct s6e63m0 *lcd)
{
int ret = 0;
- struct lcd_platform_data *pd = NULL;
- struct backlight_device *bd = NULL;
+ struct lcd_platform_data *pd;
+ struct backlight_device *bd;
pd = lcd->lcd_pd;
- if (!pd) {
- dev_err(lcd->dev, "platform data is NULL.\n");
- return -EFAULT;
- }
-
bd = lcd->bd;
- if (!bd) {
- dev_err(lcd->dev, "backlight device is NULL.\n");
- return -EFAULT;
- }
if (!pd->power_on) {
dev_err(lcd->dev, "power_on is NULL.\n");
- return -EFAULT;
+ return -EINVAL;
} else {
pd->power_on(lcd->ld, 1);
- mdelay(pd->power_on_delay);
+ msleep(pd->power_on_delay);
}
if (!pd->reset) {
dev_err(lcd->dev, "reset is NULL.\n");
- return -EFAULT;
+ return -EINVAL;
} else {
pd->reset(lcd->ld);
- mdelay(pd->reset_delay);
+ msleep(pd->reset_delay);
}
ret = s6e63m0_ldi_init(lcd);
@@ -558,14 +544,10 @@ static int s6e63m0_power_on(struct s6e63m0 *lcd)
static int s6e63m0_power_off(struct s6e63m0 *lcd)
{
- int ret = 0;
- struct lcd_platform_data *pd = NULL;
+ int ret;
+ struct lcd_platform_data *pd;
pd = lcd->lcd_pd;
- if (!pd) {
- dev_err(lcd->dev, "platform data is NULL.\n");
- return -EFAULT;
- }
ret = s6e63m0_ldi_disable(lcd);
if (ret) {
@@ -573,13 +555,9 @@ static int s6e63m0_power_off(struct s6e63m0 *lcd)
return -EIO;
}
- mdelay(pd->power_off_delay);
+ msleep(pd->power_off_delay);
- if (!pd->power_on) {
- dev_err(lcd->dev, "power_on is NULL.\n");
- return -EFAULT;
- } else
- pd->power_on(lcd->ld, 0);
+ pd->power_on(lcd->ld, 0);
return 0;
}
@@ -588,9 +566,9 @@ static int s6e63m0_power(struct s6e63m0 *lcd, int power)
{
int ret = 0;
- if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+ if (s6e63m0_power_is_on(power) && !s6e63m0_power_is_on(lcd->power))
ret = s6e63m0_power_on(lcd);
- else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+ else if (!s6e63m0_power_is_on(power) && s6e63m0_power_is_on(lcd->power))
ret = s6e63m0_power_off(lcd);
if (!ret)
@@ -733,7 +711,7 @@ static ssize_t s6e63m0_sysfs_show_gamma_table(struct device *dev,
static DEVICE_ATTR(gamma_table, 0444,
s6e63m0_sysfs_show_gamma_table, NULL);
-static int __devinit s6e63m0_probe(struct spi_device *spi)
+static int s6e63m0_probe(struct spi_device *spi)
{
int ret = 0;
struct s6e63m0 *lcd = NULL;
@@ -757,10 +735,10 @@ static int __devinit s6e63m0_probe(struct spi_device *spi)
lcd->spi = spi;
lcd->dev = &spi->dev;
- lcd->lcd_pd = (struct lcd_platform_data *)spi->dev.platform_data;
+ lcd->lcd_pd = spi->dev.platform_data;
if (!lcd->lcd_pd) {
dev_err(&spi->dev, "platform data is NULL.\n");
- return -EFAULT;
+ return -EINVAL;
}
ld = lcd_device_register("s6e63m0", &spi->dev, lcd, &s6e63m0_lcd_ops);
@@ -788,7 +766,7 @@ static int __devinit s6e63m0_probe(struct spi_device *spi)
* know that.
*/
lcd->gamma_table_count =
- sizeof(gamma_table) / (MAX_GAMMA_LEVEL * sizeof(int));
+ sizeof(gamma_table) / (MAX_GAMMA_LEVEL * sizeof(int *));
ret = device_create_file(&(spi->dev), &dev_attr_gamma_mode);
if (ret < 0)
@@ -811,10 +789,11 @@ static int __devinit s6e63m0_probe(struct spi_device *spi)
lcd->power = FB_BLANK_POWERDOWN;
s6e63m0_power(lcd, FB_BLANK_UNBLANK);
- } else
+ } else {
lcd->power = FB_BLANK_UNBLANK;
+ }
- dev_set_drvdata(&spi->dev, lcd);
+ spi_set_drvdata(spi, lcd);
dev_info(&spi->dev, "s6e63m0 panel driver has been probed.\n");
@@ -825,9 +804,9 @@ out_lcd_unregister:
return ret;
}
-static int __devexit s6e63m0_remove(struct spi_device *spi)
+static int s6e63m0_remove(struct spi_device *spi)
{
- struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev);
+ struct s6e63m0 *lcd = spi_get_drvdata(spi);
s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
device_remove_file(&spi->dev, &dev_attr_gamma_table);
@@ -839,44 +818,26 @@ static int __devexit s6e63m0_remove(struct spi_device *spi)
}
#if defined(CONFIG_PM)
-static unsigned int before_power;
-
static int s6e63m0_suspend(struct spi_device *spi, pm_message_t mesg)
{
- int ret = 0;
- struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev);
+ struct s6e63m0 *lcd = spi_get_drvdata(spi);
dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
- before_power = lcd->power;
-
/*
* when lcd panel is suspend, lcd panel becomes off
* regardless of status.
*/
- ret = s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
-
- return ret;
+ return s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
}
static int s6e63m0_resume(struct spi_device *spi)
{
- int ret = 0;
- struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev);
-
- /*
- * after suspended, if lcd panel status is FB_BLANK_UNBLANK
- * (at that time, before_power is FB_BLANK_UNBLANK) then
- * it changes that status to FB_BLANK_POWERDOWN to get lcd on.
- */
- if (before_power == FB_BLANK_UNBLANK)
- lcd->power = FB_BLANK_POWERDOWN;
+ struct s6e63m0 *lcd = spi_get_drvdata(spi);
- dev_dbg(&spi->dev, "before_power = %d\n", before_power);
+ lcd->power = FB_BLANK_POWERDOWN;
- ret = s6e63m0_power(lcd, before_power);
-
- return ret;
+ return s6e63m0_power(lcd, FB_BLANK_UNBLANK);
}
#else
#define s6e63m0_suspend NULL
@@ -886,7 +847,7 @@ static int s6e63m0_resume(struct spi_device *spi)
/* Power down all displays on reboot, poweroff or halt. */
static void s6e63m0_shutdown(struct spi_device *spi)
{
- struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev);
+ struct s6e63m0 *lcd = spi_get_drvdata(spi);
s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
}
@@ -897,7 +858,7 @@ static struct spi_driver s6e63m0_driver = {
.owner = THIS_MODULE,
},
.probe = s6e63m0_probe,
- .remove = __devexit_p(s6e63m0_remove),
+ .remove = s6e63m0_remove,
.shutdown = s6e63m0_shutdown,
.suspend = s6e63m0_suspend,
.resume = s6e63m0_resume,
diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c
index 02444d0..0016208 100644
--- a/drivers/video/backlight/tdo24m.c
+++ b/drivers/video/backlight/tdo24m.c
@@ -2,7 +2,7 @@
* tdo24m - SPI-based drivers for Toppoly TDO24M series LCD panels
*
* Copyright (C) 2008 Marvell International Ltd.
- * Eric Miao <eric.miao@marvell.com>
+ * Eric Miao <eric.miao@marvell.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -47,7 +47,7 @@ struct tdo24m {
((x1) << 9) | 0x100 | (x2))
#define CMD_NULL (-1)
-static uint32_t lcd_panel_reset[] = {
+static const uint32_t lcd_panel_reset[] = {
CMD0(0x1), /* reset */
CMD0(0x0), /* nop */
CMD0(0x0), /* nop */
@@ -55,7 +55,7 @@ static uint32_t lcd_panel_reset[] = {
CMD_NULL,
};
-static uint32_t lcd_panel_on[] = {
+static const uint32_t lcd_panel_on[] = {
CMD0(0x29), /* Display ON */
CMD2(0xB8, 0xFF, 0xF9), /* Output Control */
CMD0(0x11), /* Sleep out */
@@ -63,7 +63,7 @@ static uint32_t lcd_panel_on[] = {
CMD_NULL,
};
-static uint32_t lcd_panel_off[] = {
+static const uint32_t lcd_panel_off[] = {
CMD0(0x28), /* Display OFF */
CMD2(0xB8, 0x80, 0x02), /* Output Control */
CMD0(0x10), /* Sleep in */
@@ -71,7 +71,7 @@ static uint32_t lcd_panel_off[] = {
CMD_NULL,
};
-static uint32_t lcd_vga_pass_through_tdo24m[] = {
+static const uint32_t lcd_vga_pass_through_tdo24m[] = {
CMD1(0xB0, 0x16),
CMD1(0xBC, 0x80),
CMD1(0xE1, 0x00),
@@ -80,7 +80,7 @@ static uint32_t lcd_vga_pass_through_tdo24m[] = {
CMD_NULL,
};
-static uint32_t lcd_qvga_pass_through_tdo24m[] = {
+static const uint32_t lcd_qvga_pass_through_tdo24m[] = {
CMD1(0xB0, 0x16),
CMD1(0xBC, 0x81),
CMD1(0xE1, 0x00),
@@ -89,8 +89,8 @@ static uint32_t lcd_qvga_pass_through_tdo24m[] = {
CMD_NULL,
};
-static uint32_t lcd_vga_transfer_tdo24m[] = {
- CMD1(0xcf, 0x02), /* Blanking period control (1) */
+static const uint32_t lcd_vga_transfer_tdo24m[] = {
+ CMD1(0xcf, 0x02), /* Blanking period control (1) */
CMD2(0xd0, 0x08, 0x04), /* Blanking period control (2) */
CMD1(0xd1, 0x01), /* CKV timing control on/off */
CMD2(0xd2, 0x14, 0x00), /* CKV 1,2 timing control */
@@ -102,7 +102,7 @@ static uint32_t lcd_vga_transfer_tdo24m[] = {
CMD_NULL,
};
-static uint32_t lcd_qvga_transfer[] = {
+static const uint32_t lcd_qvga_transfer[] = {
CMD1(0xd6, 0x02), /* Blanking period control (1) */
CMD2(0xd7, 0x08, 0x04), /* Blanking period control (2) */
CMD1(0xd8, 0x01), /* CKV timing control on/off */
@@ -115,7 +115,7 @@ static uint32_t lcd_qvga_transfer[] = {
CMD_NULL,
};
-static uint32_t lcd_vga_pass_through_tdo35s[] = {
+static const uint32_t lcd_vga_pass_through_tdo35s[] = {
CMD1(0xB0, 0x16),
CMD1(0xBC, 0x80),
CMD1(0xE1, 0x00),
@@ -123,7 +123,7 @@ static uint32_t lcd_vga_pass_through_tdo35s[] = {
CMD_NULL,
};
-static uint32_t lcd_qvga_pass_through_tdo35s[] = {
+static const uint32_t lcd_qvga_pass_through_tdo35s[] = {
CMD1(0xB0, 0x16),
CMD1(0xBC, 0x81),
CMD1(0xE1, 0x00),
@@ -131,8 +131,8 @@ static uint32_t lcd_qvga_pass_through_tdo35s[] = {
CMD_NULL,
};
-static uint32_t lcd_vga_transfer_tdo35s[] = {
- CMD1(0xcf, 0x02), /* Blanking period control (1) */
+static const uint32_t lcd_vga_transfer_tdo35s[] = {
+ CMD1(0xcf, 0x02), /* Blanking period control (1) */
CMD2(0xd0, 0x08, 0x04), /* Blanking period control (2) */
CMD1(0xd1, 0x01), /* CKV timing control on/off */
CMD2(0xd2, 0x00, 0x1e), /* CKV 1,2 timing control */
@@ -144,7 +144,7 @@ static uint32_t lcd_vga_transfer_tdo35s[] = {
CMD_NULL,
};
-static uint32_t lcd_panel_config[] = {
+static const uint32_t lcd_panel_config[] = {
CMD2(0xb8, 0xff, 0xf9), /* Output control */
CMD0(0x11), /* sleep out */
CMD1(0xba, 0x01), /* Display mode (1) */
@@ -175,10 +175,11 @@ static uint32_t lcd_panel_config[] = {
CMD_NULL,
};
-static int tdo24m_writes(struct tdo24m *lcd, uint32_t *array)
+static int tdo24m_writes(struct tdo24m *lcd, const uint32_t *array)
{
struct spi_transfer *x = &lcd->xfer;
- uint32_t data, *p = array;
+ const uint32_t *p = array;
+ uint32_t data;
int nparams, err = 0;
for (; *p != CMD_NULL; p++) {
@@ -328,7 +329,7 @@ static struct lcd_ops tdo24m_ops = {
.set_mode = tdo24m_set_mode,
};
-static int __devinit tdo24m_probe(struct spi_device *spi)
+static int tdo24m_probe(struct spi_device *spi)
{
struct tdo24m *lcd;
struct spi_message *m;
@@ -389,7 +390,7 @@ static int __devinit tdo24m_probe(struct spi_device *spi)
if (IS_ERR(lcd->lcd_dev))
return PTR_ERR(lcd->lcd_dev);
- dev_set_drvdata(&spi->dev, lcd);
+ spi_set_drvdata(spi, lcd);
err = tdo24m_power(lcd, FB_BLANK_UNBLANK);
if (err)
goto out_unregister;
@@ -401,9 +402,9 @@ out_unregister:
return err;
}
-static int __devexit tdo24m_remove(struct spi_device *spi)
+static int tdo24m_remove(struct spi_device *spi)
{
- struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
+ struct tdo24m *lcd = spi_get_drvdata(spi);
tdo24m_power(lcd, FB_BLANK_POWERDOWN);
lcd_device_unregister(lcd->lcd_dev);
@@ -414,14 +415,14 @@ static int __devexit tdo24m_remove(struct spi_device *spi)
#ifdef CONFIG_PM
static int tdo24m_suspend(struct spi_device *spi, pm_message_t state)
{
- struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
+ struct tdo24m *lcd = spi_get_drvdata(spi);
return tdo24m_power(lcd, FB_BLANK_POWERDOWN);
}
static int tdo24m_resume(struct spi_device *spi)
{
- struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
+ struct tdo24m *lcd = spi_get_drvdata(spi);
return tdo24m_power(lcd, FB_BLANK_UNBLANK);
}
@@ -433,7 +434,7 @@ static int tdo24m_resume(struct spi_device *spi)
/* Power down all displays on reboot, poweroff or halt */
static void tdo24m_shutdown(struct spi_device *spi)
{
- struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
+ struct tdo24m *lcd = spi_get_drvdata(spi);
tdo24m_power(lcd, FB_BLANK_POWERDOWN);
}
@@ -444,7 +445,7 @@ static struct spi_driver tdo24m_driver = {
.owner = THIS_MODULE,
},
.probe = tdo24m_probe,
- .remove = __devexit_p(tdo24m_remove),
+ .remove = tdo24m_remove,
.shutdown = tdo24m_shutdown,
.suspend = tdo24m_suspend,
.resume = tdo24m_resume,
diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c
index 49342e1..2326fa8 100644
--- a/drivers/video/backlight/tosa_bl.c
+++ b/drivers/video/backlight/tosa_bl.c
@@ -54,7 +54,7 @@ static void tosa_bl_set_backlight(struct tosa_bl_data *data, int brightness)
static int tosa_bl_update_status(struct backlight_device *dev)
{
struct backlight_properties *props = &dev->props;
- struct tosa_bl_data *data = dev_get_drvdata(&dev->dev);
+ struct tosa_bl_data *data = bl_get_data(dev);
int power = max(props->power, props->fb_blank);
int brightness = props->brightness;
@@ -78,7 +78,7 @@ static const struct backlight_ops bl_ops = {
.update_status = tosa_bl_update_status,
};
-static int __devinit tosa_bl_probe(struct i2c_client *client,
+static int tosa_bl_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct backlight_properties props;
@@ -92,14 +92,12 @@ static int __devinit tosa_bl_probe(struct i2c_client *client,
data->comadj = sharpsl_param.comadj == -1 ? COMADJ_DEFAULT : sharpsl_param.comadj;
- ret = devm_gpio_request(&client->dev, TOSA_GPIO_BL_C20MA, "backlight");
+ ret = devm_gpio_request_one(&client->dev, TOSA_GPIO_BL_C20MA,
+ GPIOF_OUT_INIT_LOW, "backlight");
if (ret) {
dev_dbg(&data->bl->dev, "Unable to request gpio!\n");
return ret;
}
- ret = gpio_direction_output(TOSA_GPIO_BL_C20MA, 0);
- if (ret)
- return ret;
i2c_set_clientdata(client, data);
data->i2c = client;
@@ -126,7 +124,7 @@ err_reg:
return ret;
}
-static int __devexit tosa_bl_remove(struct i2c_client *client)
+static int tosa_bl_remove(struct i2c_client *client)
{
struct tosa_bl_data *data = i2c_get_clientdata(client);
@@ -163,14 +161,13 @@ static const struct i2c_device_id tosa_bl_id[] = {
{ },
};
-
static struct i2c_driver tosa_bl_driver = {
.driver = {
.name = "tosa-bl",
.owner = THIS_MODULE,
},
.probe = tosa_bl_probe,
- .remove = __devexit_p(tosa_bl_remove),
+ .remove = tosa_bl_remove,
.suspend = tosa_bl_suspend,
.resume = tosa_bl_resume,
.id_table = tosa_bl_id,
diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c
index 33047a66..666fe25 100644
--- a/drivers/video/backlight/tosa_lcd.c
+++ b/drivers/video/backlight/tosa_lcd.c
@@ -63,7 +63,7 @@ static int tosa_tg_send(struct spi_device *spi, int adrs, uint8_t data)
int tosa_bl_enable(struct spi_device *spi, int enable)
{
/* bl_enable GP04=1 otherwise GP04=0*/
- return tosa_tg_send(spi, TG_GPODR2, enable? 0x01 : 0x00);
+ return tosa_tg_send(spi, TG_GPODR2, enable ? 0x01 : 0x00);
}
EXPORT_SYMBOL(tosa_bl_enable);
@@ -91,15 +91,17 @@ static void tosa_lcd_tg_on(struct tosa_lcd_data *data)
tosa_tg_send(spi, TG_PNLCTL, value);
/* TG LCD pannel power up */
- tosa_tg_send(spi, TG_PINICTL,0x4);
+ tosa_tg_send(spi, TG_PINICTL, 0x4);
mdelay(50);
/* TG LCD GVSS */
- tosa_tg_send(spi, TG_PINICTL,0x0);
+ tosa_tg_send(spi, TG_PINICTL, 0x0);
if (!data->i2c) {
- /* after the pannel is powered up the first time, we can access the i2c bus */
- /* so probe for the DAC */
+ /*
+ * after the pannel is powered up the first time,
+ * we can access the i2c bus so probe for the DAC
+ */
struct i2c_adapter *adap = i2c_get_adapter(0);
struct i2c_board_info info = {
.type = "tosa-bl",
@@ -115,11 +117,11 @@ static void tosa_lcd_tg_off(struct tosa_lcd_data *data)
struct spi_device *spi = data->spi;
/* TG LCD VHSA off */
- tosa_tg_send(spi, TG_PINICTL,0x4);
+ tosa_tg_send(spi, TG_PINICTL, 0x4);
mdelay(50);
/* TG LCD signal off */
- tosa_tg_send(spi, TG_PINICTL,0x6);
+ tosa_tg_send(spi, TG_PINICTL, 0x6);
mdelay(50);
/* TG Off */
@@ -169,7 +171,7 @@ static struct lcd_ops tosa_lcd_ops = {
.set_mode = tosa_lcd_set_mode,
};
-static int __devinit tosa_lcd_probe(struct spi_device *spi)
+static int tosa_lcd_probe(struct spi_device *spi)
{
int ret;
struct tosa_lcd_data *data;
@@ -191,19 +193,15 @@ static int __devinit tosa_lcd_probe(struct spi_device *spi)
return ret;
data->spi = spi;
- dev_set_drvdata(&spi->dev, data);
+ spi_set_drvdata(spi, data);
- ret = devm_gpio_request(&spi->dev, TOSA_GPIO_TG_ON, "tg #pwr");
+ ret = devm_gpio_request_one(&spi->dev, TOSA_GPIO_TG_ON,
+ GPIOF_OUT_INIT_LOW, "tg #pwr");
if (ret < 0)
goto err_gpio_tg;
mdelay(60);
- ret = gpio_direction_output(TOSA_GPIO_TG_ON, 0);
- if (ret < 0)
- goto err_gpio_tg;
-
- mdelay(60);
tosa_lcd_tg_init(data);
tosa_lcd_tg_on(data);
@@ -222,13 +220,13 @@ static int __devinit tosa_lcd_probe(struct spi_device *spi)
err_register:
tosa_lcd_tg_off(data);
err_gpio_tg:
- dev_set_drvdata(&spi->dev, NULL);
+ spi_set_drvdata(spi, NULL);
return ret;
}
-static int __devexit tosa_lcd_remove(struct spi_device *spi)
+static int tosa_lcd_remove(struct spi_device *spi)
{
- struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev);
+ struct tosa_lcd_data *data = spi_get_drvdata(spi);
lcd_device_unregister(data->lcd);
@@ -237,7 +235,7 @@ static int __devexit tosa_lcd_remove(struct spi_device *spi)
tosa_lcd_tg_off(data);
- dev_set_drvdata(&spi->dev, NULL);
+ spi_set_drvdata(spi, NULL);
return 0;
}
@@ -245,7 +243,7 @@ static int __devexit tosa_lcd_remove(struct spi_device *spi)
#ifdef CONFIG_PM
static int tosa_lcd_suspend(struct spi_device *spi, pm_message_t state)
{
- struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev);
+ struct tosa_lcd_data *data = spi_get_drvdata(spi);
tosa_lcd_tg_off(data);
@@ -254,7 +252,7 @@ static int tosa_lcd_suspend(struct spi_device *spi, pm_message_t state)
static int tosa_lcd_resume(struct spi_device *spi)
{
- struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev);
+ struct tosa_lcd_data *data = spi_get_drvdata(spi);
tosa_lcd_tg_init(data);
if (POWER_IS_ON(data->lcd_power))
@@ -275,7 +273,7 @@ static struct spi_driver tosa_lcd_driver = {
.owner = THIS_MODULE,
},
.probe = tosa_lcd_probe,
- .remove = __devexit_p(tosa_lcd_remove),
+ .remove = tosa_lcd_remove,
.suspend = tosa_lcd_suspend,
.resume = tosa_lcd_resume,
};
diff --git a/drivers/video/backlight/vgg2432a4.c b/drivers/video/backlight/vgg2432a4.c
index b617fae..84d582f 100644
--- a/drivers/video/backlight/vgg2432a4.c
+++ b/drivers/video/backlight/vgg2432a4.c
@@ -26,7 +26,7 @@
/* Device initialisation sequences */
-static struct ili9320_reg vgg_init1[] = {
+static const struct ili9320_reg vgg_init1[] = {
{
.address = ILI9320_POWER1,
.value = ILI9320_POWER1_AP(0) | ILI9320_POWER1_BT(0),
@@ -43,7 +43,7 @@ static struct ili9320_reg vgg_init1[] = {
},
};
-static struct ili9320_reg vgg_init2[] = {
+static const struct ili9320_reg vgg_init2[] = {
{
.address = ILI9320_POWER1,
.value = (ILI9320_POWER1_AP(3) | ILI9320_POWER1_APE |
@@ -54,7 +54,7 @@ static struct ili9320_reg vgg_init2[] = {
}
};
-static struct ili9320_reg vgg_gamma[] = {
+static const struct ili9320_reg vgg_gamma[] = {
{
.address = ILI9320_GAMMA1,
.value = 0x0000,
@@ -89,7 +89,7 @@ static struct ili9320_reg vgg_gamma[] = {
};
-static struct ili9320_reg vgg_init0[] = {
+static const struct ili9320_reg vgg_init0[] = {
[0] = {
/* set direction and scan mode gate */
.address = ILI9320_DRIVER,
@@ -208,16 +208,15 @@ static int vgg2432a4_lcd_init(struct ili9320 *lcd,
#ifdef CONFIG_PM
static int vgg2432a4_suspend(struct spi_device *spi, pm_message_t state)
{
- return ili9320_suspend(dev_get_drvdata(&spi->dev), state);
+ return ili9320_suspend(spi_get_drvdata(spi), state);
}
-
static int vgg2432a4_resume(struct spi_device *spi)
{
- return ili9320_resume(dev_get_drvdata(&spi->dev));
+ return ili9320_resume(spi_get_drvdata(spi));
}
#else
#define vgg2432a4_suspend NULL
-#define vgg2432a4_resume NULL
+#define vgg2432a4_resume NULL
#endif
static struct ili9320_client vgg2432a4_client = {
@@ -227,7 +226,7 @@ static struct ili9320_client vgg2432a4_client = {
/* Device probe */
-static int __devinit vgg2432a4_probe(struct spi_device *spi)
+static int vgg2432a4_probe(struct spi_device *spi)
{
int ret;
@@ -240,14 +239,14 @@ static int __devinit vgg2432a4_probe(struct spi_device *spi)
return 0;
}
-static int __devexit vgg2432a4_remove(struct spi_device *spi)
+static int vgg2432a4_remove(struct spi_device *spi)
{
- return ili9320_remove(dev_get_drvdata(&spi->dev));
+ return ili9320_remove(spi_get_drvdata(spi));
}
static void vgg2432a4_shutdown(struct spi_device *spi)
{
- ili9320_shutdown(dev_get_drvdata(&spi->dev));
+ ili9320_shutdown(spi_get_drvdata(spi));
}
static struct spi_driver vgg2432a4_driver = {
@@ -256,7 +255,7 @@ static struct spi_driver vgg2432a4_driver = {
.owner = THIS_MODULE,
},
.probe = vgg2432a4_probe,
- .remove = __devexit_p(vgg2432a4_remove),
+ .remove = vgg2432a4_remove,
.shutdown = vgg2432a4_shutdown,
.suspend = vgg2432a4_suspend,
.resume = vgg2432a4_resume,
diff --git a/drivers/video/bf537-lq035.c b/drivers/video/bf537-lq035.c
index 7347aa1..a82d257 100644
--- a/drivers/video/bf537-lq035.c
+++ b/drivers/video/bf537-lq035.c
@@ -87,8 +87,8 @@ static void set_vcomm(void)
pr_err("i2c_smbus_write_byte_data fail: %d\n", nr);
}
-static int __devinit ad5280_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int ad5280_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int ret;
if (!i2c_check_functionality(client->adapter,
@@ -108,7 +108,7 @@ static int __devinit ad5280_probe(struct i2c_client *client,
return 0;
}
-static int __devexit ad5280_remove(struct i2c_client *client)
+static int ad5280_remove(struct i2c_client *client)
{
ad5280_client = NULL;
return 0;
@@ -126,7 +126,7 @@ static struct i2c_driver ad5280_driver = {
.name = "bf537-lq035-ad5280",
},
.probe = ad5280_probe,
- .remove = __devexit_p(ad5280_remove),
+ .remove = ad5280_remove,
.id_table = ad5280_id,
};
@@ -360,7 +360,7 @@ static int config_dma(void)
return 0;
}
-static int __devinit request_ports(void)
+static int request_ports(void)
{
u16 tmr_req[] = TIMERS;
@@ -443,7 +443,7 @@ static struct fb_var_screeninfo bfin_lq035_fb_defined = {
.transp = {0, 0, 0},
};
-static struct fb_fix_screeninfo bfin_lq035_fb_fix __devinitdata = {
+static struct fb_fix_screeninfo bfin_lq035_fb_fix = {
.id = KBUILD_MODNAME,
.smem_len = ACTIVE_VIDEO_MEM_SIZE,
.type = FB_TYPE_PACKED_PIXELS,
@@ -686,7 +686,7 @@ static struct lcd_ops bfin_lcd_ops = {
static struct lcd_device *lcd_dev;
-static int __devinit bfin_lq035_probe(struct platform_device *pdev)
+static int bfin_lq035_probe(struct platform_device *pdev)
{
struct backlight_properties props;
dma_addr_t dma_handle;
@@ -816,7 +816,7 @@ out_ports:
return ret;
}
-static int __devexit bfin_lq035_remove(struct platform_device *pdev)
+static int bfin_lq035_remove(struct platform_device *pdev)
{
if (fb_buffer != NULL)
dma_free_coherent(NULL, TOTAL_VIDEO_MEM_SIZE, fb_buffer, 0);
@@ -889,7 +889,7 @@ static int bfin_lq035_resume(struct platform_device *pdev)
static struct platform_driver bfin_lq035_driver = {
.probe = bfin_lq035_probe,
- .remove = __devexit_p(bfin_lq035_remove),
+ .remove = bfin_lq035_remove,
.suspend = bfin_lq035_suspend,
.resume = bfin_lq035_resume,
.driver = {
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
index ff5663f..2726a5b 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/bf54x-lq043fb.c
@@ -497,7 +497,7 @@ static irqreturn_t bfin_bf54x_irq_error(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
+static int bfin_bf54x_probe(struct platform_device *pdev)
{
#ifndef NO_BL_SUPPORT
struct backlight_properties props;
@@ -686,7 +686,7 @@ out1:
return ret;
}
-static int __devexit bfin_bf54x_remove(struct platform_device *pdev)
+static int bfin_bf54x_remove(struct platform_device *pdev)
{
struct fb_info *fbinfo = platform_get_drvdata(pdev);
@@ -754,7 +754,7 @@ static int bfin_bf54x_resume(struct platform_device *pdev)
static struct platform_driver bfin_bf54x_driver = {
.probe = bfin_bf54x_probe,
- .remove = __devexit_p(bfin_bf54x_remove),
+ .remove = bfin_bf54x_remove,
.suspend = bfin_bf54x_suspend,
.resume = bfin_bf54x_resume,
.driver = {
diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c
index 6fbc75c..29d8c04 100644
--- a/drivers/video/bfin-lq035q1-fb.c
+++ b/drivers/video/bfin-lq035q1-fb.c
@@ -137,7 +137,7 @@ static int lq035q1_control(struct spi_device *spi, unsigned char reg, unsigned s
return ret;
}
-static int __devinit lq035q1_spidev_probe(struct spi_device *spi)
+static int lq035q1_spidev_probe(struct spi_device *spi)
{
int ret;
struct spi_control *ctl;
@@ -358,8 +358,8 @@ static inline void bfin_lq035q1_free_ports(unsigned ppi16)
gpio_free(P_IDENT(P_PPI0_FS3));
}
-static int __devinit bfin_lq035q1_request_ports(struct platform_device *pdev,
- unsigned ppi16)
+static int bfin_lq035q1_request_ports(struct platform_device *pdev,
+ unsigned ppi16)
{
int ret;
/* ANOMALY_05000400 - PPI Does Not Start Properly In Specific Mode:
@@ -555,7 +555,7 @@ static irqreturn_t bfin_lq035q1_irq_error(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int __devinit bfin_lq035q1_probe(struct platform_device *pdev)
+static int bfin_lq035q1_probe(struct platform_device *pdev)
{
struct bfin_lq035q1fb_info *info;
struct fb_info *fbinfo;
@@ -706,7 +706,7 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev)
info->spidrv.driver.name = DRIVER_NAME"-spi";
info->spidrv.probe = lq035q1_spidev_probe;
- info->spidrv.remove = __devexit_p(lq035q1_spidev_remove);
+ info->spidrv.remove = lq035q1_spidev_remove;
info->spidrv.shutdown = lq035q1_spidev_shutdown;
info->spidrv.suspend = lq035q1_spidev_suspend;
info->spidrv.resume = lq035q1_spidev_resume;
@@ -764,7 +764,7 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit bfin_lq035q1_remove(struct platform_device *pdev)
+static int bfin_lq035q1_remove(struct platform_device *pdev)
{
struct fb_info *fbinfo = platform_get_drvdata(pdev);
struct bfin_lq035q1fb_info *info = fbinfo->par;
@@ -845,7 +845,7 @@ static struct dev_pm_ops bfin_lq035q1_dev_pm_ops = {
static struct platform_driver bfin_lq035q1_driver = {
.probe = bfin_lq035q1_probe,
- .remove = __devexit_p(bfin_lq035q1_remove),
+ .remove = bfin_lq035q1_remove,
.driver = {
.name = DRIVER_NAME,
#ifdef CONFIG_PM
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c
index ae0fb24..d46da01 100644
--- a/drivers/video/bfin-t350mcqb-fb.c
+++ b/drivers/video/bfin-t350mcqb-fb.c
@@ -418,7 +418,7 @@ static irqreturn_t bfin_t350mcqb_irq_error(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
+static int bfin_t350mcqb_probe(struct platform_device *pdev)
{
#ifndef NO_BL_SUPPORT
struct backlight_properties props;
@@ -583,7 +583,7 @@ out1:
return ret;
}
-static int __devexit bfin_t350mcqb_remove(struct platform_device *pdev)
+static int bfin_t350mcqb_remove(struct platform_device *pdev)
{
struct fb_info *fbinfo = platform_get_drvdata(pdev);
@@ -658,7 +658,7 @@ static int bfin_t350mcqb_resume(struct platform_device *pdev)
static struct platform_driver bfin_t350mcqb_driver = {
.probe = bfin_t350mcqb_probe,
- .remove = __devexit_p(bfin_t350mcqb_remove),
+ .remove = bfin_t350mcqb_remove,
.suspend = bfin_t350mcqb_suspend,
.resume = bfin_t350mcqb_resume,
.driver = {
diff --git a/drivers/video/bfin_adv7393fb.c b/drivers/video/bfin_adv7393fb.c
index d0f121b..8d411a3 100644
--- a/drivers/video/bfin_adv7393fb.c
+++ b/drivers/video/bfin_adv7393fb.c
@@ -88,7 +88,7 @@ static struct fb_var_screeninfo bfin_adv7393_fb_defined = {
.transp = {0, 0, 0},
};
-static struct fb_fix_screeninfo bfin_adv7393_fb_fix __devinitdata = {
+static struct fb_fix_screeninfo bfin_adv7393_fb_fix = {
.id = "BFIN ADV7393",
.smem_len = 720 * 480 * 2,
.type = FB_TYPE_PACKED_PIXELS,
@@ -368,8 +368,8 @@ adv7393_write_proc(struct file *file, const char __user * buffer,
return count;
}
-static int __devinit bfin_adv7393_fb_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int bfin_adv7393_fb_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int ret = 0;
struct proc_dir_entry *entry;
@@ -719,7 +719,7 @@ static int bfin_adv7393_fb_setcolreg(u_int regno, u_int red, u_int green,
return 0;
}
-static int __devexit bfin_adv7393_fb_remove(struct i2c_client *client)
+static int bfin_adv7393_fb_remove(struct i2c_client *client)
{
struct adv7393fb_device *fbdev = i2c_get_clientdata(client);
@@ -794,7 +794,7 @@ static struct i2c_driver bfin_adv7393_fb_driver = {
#endif
},
.probe = bfin_adv7393_fb_probe,
- .remove = __devexit_p(bfin_adv7393_fb_remove),
+ .remove = bfin_adv7393_fb_remove,
.id_table = bfin_adv7393_id,
};
diff --git a/drivers/video/broadsheetfb.c b/drivers/video/broadsheetfb.c
index c95b417..b09701c 100644
--- a/drivers/video/broadsheetfb.c
+++ b/drivers/video/broadsheetfb.c
@@ -91,7 +91,7 @@ static struct panel_info panel_table[] = {
#define DPY_W 800
#define DPY_H 600
-static struct fb_fix_screeninfo broadsheetfb_fix __devinitdata = {
+static struct fb_fix_screeninfo broadsheetfb_fix = {
.id = "broadsheetfb",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_STATIC_PSEUDOCOLOR,
@@ -102,7 +102,7 @@ static struct fb_fix_screeninfo broadsheetfb_fix __devinitdata = {
.accel = FB_ACCEL_NONE,
};
-static struct fb_var_screeninfo broadsheetfb_var __devinitdata = {
+static struct fb_var_screeninfo broadsheetfb_var = {
.xres = DPY_W,
.yres = DPY_H,
.xres_virtual = DPY_W,
@@ -774,7 +774,7 @@ static DEVICE_ATTR(loadstore_waveform, S_IWUSR, NULL,
broadsheet_loadstore_waveform);
/* upper level functions that manipulate the display and other stuff */
-static void __devinit broadsheet_init_display(struct broadsheetfb_par *par)
+static void broadsheet_init_display(struct broadsheetfb_par *par)
{
u16 args[5];
int xres = par->info->var.xres;
@@ -834,7 +834,7 @@ static void __devinit broadsheet_init_display(struct broadsheetfb_par *par)
par->board->wait_for_rdy(par);
}
-static void __devinit broadsheet_identify(struct broadsheetfb_par *par)
+static void broadsheet_identify(struct broadsheetfb_par *par)
{
u16 rev, prc;
struct device *dev = par->info->device;
@@ -849,7 +849,7 @@ static void __devinit broadsheet_identify(struct broadsheetfb_par *par)
dev_warn(dev, "Unrecognized Broadsheet Revision\n");
}
-static void __devinit broadsheet_init(struct broadsheetfb_par *par)
+static void broadsheet_init(struct broadsheetfb_par *par)
{
broadsheet_send_command(par, BS_CMD_INIT_SYS_RUN);
/* the controller needs a second */
@@ -1058,7 +1058,7 @@ static struct fb_deferred_io broadsheetfb_defio = {
.deferred_io = broadsheetfb_dpy_deferred_io,
};
-static int __devinit broadsheetfb_probe(struct platform_device *dev)
+static int broadsheetfb_probe(struct platform_device *dev)
{
struct fb_info *info;
struct broadsheet_board *board;
@@ -1190,7 +1190,7 @@ err:
}
-static int __devexit broadsheetfb_remove(struct platform_device *dev)
+static int broadsheetfb_remove(struct platform_device *dev)
{
struct fb_info *info = platform_get_drvdata(dev);
@@ -1211,7 +1211,7 @@ static int __devexit broadsheetfb_remove(struct platform_device *dev)
static struct platform_driver broadsheetfb_driver = {
.probe = broadsheetfb_probe,
- .remove = __devexit_p(broadsheetfb_remove),
+ .remove = broadsheetfb_remove,
.driver = {
.owner = THIS_MODULE,
.name = "broadsheetfb",
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index 6bea9a9..60017fc 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -179,7 +179,7 @@ static int bw2_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
* Initialisation
*/
-static void __devinit bw2_init_fix(struct fb_info *info, int linebytes)
+static void bw2_init_fix(struct fb_info *info, int linebytes)
{
strlcpy(info->fix.id, "bwtwo", sizeof(info->fix.id));
@@ -191,44 +191,43 @@ static void __devinit bw2_init_fix(struct fb_info *info, int linebytes)
info->fix.accel = FB_ACCEL_SUN_BWTWO;
}
-static u8 bw2regs_1600[] __devinitdata = {
+static u8 bw2regs_1600[] = {
0x14, 0x8b, 0x15, 0x28, 0x16, 0x03, 0x17, 0x13,
0x18, 0x7b, 0x19, 0x05, 0x1a, 0x34, 0x1b, 0x2e,
0x1c, 0x00, 0x1d, 0x0a, 0x1e, 0xff, 0x1f, 0x01,
0x10, 0x21, 0
};
-static u8 bw2regs_ecl[] __devinitdata = {
+static u8 bw2regs_ecl[] = {
0x14, 0x65, 0x15, 0x1e, 0x16, 0x04, 0x17, 0x0c,
0x18, 0x5e, 0x19, 0x03, 0x1a, 0xa7, 0x1b, 0x23,
0x1c, 0x00, 0x1d, 0x08, 0x1e, 0xff, 0x1f, 0x01,
0x10, 0x20, 0
};
-static u8 bw2regs_analog[] __devinitdata = {
+static u8 bw2regs_analog[] = {
0x14, 0xbb, 0x15, 0x2b, 0x16, 0x03, 0x17, 0x13,
0x18, 0xb0, 0x19, 0x03, 0x1a, 0xa6, 0x1b, 0x22,
0x1c, 0x01, 0x1d, 0x05, 0x1e, 0xff, 0x1f, 0x01,
0x10, 0x20, 0
};
-static u8 bw2regs_76hz[] __devinitdata = {
+static u8 bw2regs_76hz[] = {
0x14, 0xb7, 0x15, 0x27, 0x16, 0x03, 0x17, 0x0f,
0x18, 0xae, 0x19, 0x03, 0x1a, 0xae, 0x1b, 0x2a,
0x1c, 0x01, 0x1d, 0x09, 0x1e, 0xff, 0x1f, 0x01,
0x10, 0x24, 0
};
-static u8 bw2regs_66hz[] __devinitdata = {
+static u8 bw2regs_66hz[] = {
0x14, 0xbb, 0x15, 0x2b, 0x16, 0x04, 0x17, 0x14,
0x18, 0xae, 0x19, 0x03, 0x1a, 0xa8, 0x1b, 0x24,
0x1c, 0x01, 0x1d, 0x05, 0x1e, 0xff, 0x1f, 0x01,
0x10, 0x20, 0
};
-static int __devinit bw2_do_default_mode(struct bw2_par *par,
- struct fb_info *info,
- int *linebytes)
+static int bw2_do_default_mode(struct bw2_par *par, struct fb_info *info,
+ int *linebytes)
{
u8 status, mon;
u8 *p;
@@ -273,7 +272,7 @@ static int __devinit bw2_do_default_mode(struct bw2_par *par,
return 0;
}
-static int __devinit bw2_probe(struct platform_device *op)
+static int bw2_probe(struct platform_device *op)
{
struct device_node *dp = op->dev.of_node;
struct fb_info *info;
@@ -352,7 +351,7 @@ out_err:
return err;
}
-static int __devexit bw2_remove(struct platform_device *op)
+static int bw2_remove(struct platform_device *op)
{
struct fb_info *info = dev_get_drvdata(&op->dev);
struct bw2_par *par = info->par;
@@ -384,7 +383,7 @@ static struct platform_driver bw2_driver = {
.of_match_table = bw2_match,
},
.probe = bw2_probe,
- .remove = __devexit_p(bw2_remove),
+ .remove = bw2_remove,
};
static int __init bw2_init(void)
diff --git a/drivers/video/carminefb.c b/drivers/video/carminefb.c
index 2c76fdf..153dd65 100644
--- a/drivers/video/carminefb.c
+++ b/drivers/video/carminefb.c
@@ -78,7 +78,7 @@ struct carmine_fb {
u32 pseudo_palette[16];
};
-static struct fb_fix_screeninfo carminefb_fix __devinitdata = {
+static struct fb_fix_screeninfo carminefb_fix = {
.id = "Carmine",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_TRUECOLOR,
@@ -537,8 +537,9 @@ static struct fb_ops carminefb_ops = {
.fb_setcolreg = carmine_setcolreg,
};
-static int __devinit alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base,
- int smem_offset, struct device *device, struct fb_info **rinfo)
+static int alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base,
+ int smem_offset, struct device *device,
+ struct fb_info **rinfo)
{
int ret;
struct fb_info *info;
@@ -606,8 +607,7 @@ static void cleanup_fb_device(struct fb_info *info)
}
}
-static int __devinit carminefb_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+static int carminefb_probe(struct pci_dev *dev, const struct pci_device_id *ent)
{
struct carmine_hw *hw;
struct device *device = &dev->dev;
@@ -721,7 +721,7 @@ err_enable_pci:
return ret;
}
-static void __devexit carminefb_remove(struct pci_dev *dev)
+static void carminefb_remove(struct pci_dev *dev)
{
struct carmine_hw *hw = pci_get_drvdata(dev);
struct fb_fix_screeninfo fix;
@@ -752,7 +752,7 @@ static void __devexit carminefb_remove(struct pci_dev *dev)
}
#define PCI_VENDOR_ID_FUJITU_LIMITED 0x10cf
-static struct pci_device_id carmine_devices[] __devinitdata = {
+static struct pci_device_id carmine_devices[] = {
{
PCI_DEVICE(PCI_VENDOR_ID_FUJITU_LIMITED, 0x202b)},
{0, 0, 0, 0, 0, 0, 0}
@@ -764,7 +764,7 @@ static struct pci_driver carmine_pci_driver = {
.name = "carminefb",
.id_table = carmine_devices,
.probe = carminefb_probe,
- .remove = __devexit_p(carminefb_remove),
+ .remove = carminefb_remove,
};
static int __init carminefb_init(void)
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index f188950..ed3b889 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -352,8 +352,8 @@ static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
* Initialisation
*/
-static void __devinit cg14_init_fix(struct fb_info *info, int linebytes,
- struct device_node *dp)
+static void cg14_init_fix(struct fb_info *info, int linebytes,
+ struct device_node *dp)
{
const char *name = dp->name;
@@ -367,7 +367,7 @@ static void __devinit cg14_init_fix(struct fb_info *info, int linebytes,
info->fix.accel = FB_ACCEL_SUN_CG14;
}
-static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] __devinitdata = {
+static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] = {
{
.voff = CG14_REGS,
.poff = 0x80000000,
@@ -463,7 +463,7 @@ static void cg14_unmap_regs(struct platform_device *op, struct fb_info *info,
info->screen_base, info->fix.smem_len);
}
-static int __devinit cg14_probe(struct platform_device *op)
+static int cg14_probe(struct platform_device *op)
{
struct device_node *dp = op->dev.of_node;
struct fb_info *info;
@@ -571,7 +571,7 @@ out_err:
return err;
}
-static int __devexit cg14_remove(struct platform_device *op)
+static int cg14_remove(struct platform_device *op)
{
struct fb_info *info = dev_get_drvdata(&op->dev);
struct cg14_par *par = info->par;
@@ -603,7 +603,7 @@ static struct platform_driver cg14_driver = {
.of_match_table = cg14_match,
},
.probe = cg14_probe,
- .remove = __devexit_p(cg14_remove),
+ .remove = cg14_remove,
};
static int __init cg14_init(void)
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index c5e7612..9f63507 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -243,8 +243,8 @@ static int cg3_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
* Initialisation
*/
-static void __devinit cg3_init_fix(struct fb_info *info, int linebytes,
- struct device_node *dp)
+static void cg3_init_fix(struct fb_info *info, int linebytes,
+ struct device_node *dp)
{
strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
@@ -256,8 +256,8 @@ static void __devinit cg3_init_fix(struct fb_info *info, int linebytes,
info->fix.accel = FB_ACCEL_SUN_CGTHREE;
}
-static void __devinit cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var,
- struct device_node *dp)
+static void cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var,
+ struct device_node *dp)
{
const char *params;
char *p;
@@ -279,36 +279,36 @@ static void __devinit cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var,
}
}
-static u8 cg3regvals_66hz[] __devinitdata = { /* 1152 x 900, 66 Hz */
+static u8 cg3regvals_66hz[] = { /* 1152 x 900, 66 Hz */
0x14, 0xbb, 0x15, 0x2b, 0x16, 0x04, 0x17, 0x14,
0x18, 0xae, 0x19, 0x03, 0x1a, 0xa8, 0x1b, 0x24,
0x1c, 0x01, 0x1d, 0x05, 0x1e, 0xff, 0x1f, 0x01,
0x10, 0x20, 0
};
-static u8 cg3regvals_76hz[] __devinitdata = { /* 1152 x 900, 76 Hz */
+static u8 cg3regvals_76hz[] = { /* 1152 x 900, 76 Hz */
0x14, 0xb7, 0x15, 0x27, 0x16, 0x03, 0x17, 0x0f,
0x18, 0xae, 0x19, 0x03, 0x1a, 0xae, 0x1b, 0x2a,
0x1c, 0x01, 0x1d, 0x09, 0x1e, 0xff, 0x1f, 0x01,
0x10, 0x24, 0
};
-static u8 cg3regvals_rdi[] __devinitdata = { /* 640 x 480, cgRDI */
+static u8 cg3regvals_rdi[] = { /* 640 x 480, cgRDI */
0x14, 0x70, 0x15, 0x20, 0x16, 0x08, 0x17, 0x10,
0x18, 0x06, 0x19, 0x02, 0x1a, 0x31, 0x1b, 0x51,
0x1c, 0x06, 0x1d, 0x0c, 0x1e, 0xff, 0x1f, 0x01,
0x10, 0x22, 0
};
-static u8 *cg3_regvals[] __devinitdata = {
+static u8 *cg3_regvals[] = {
cg3regvals_66hz, cg3regvals_76hz, cg3regvals_rdi
};
-static u_char cg3_dacvals[] __devinitdata = {
+static u_char cg3_dacvals[] = {
4, 0xff, 5, 0x00, 6, 0x70, 7, 0x00, 0
};
-static int __devinit cg3_do_default_mode(struct cg3_par *par)
+static int cg3_do_default_mode(struct cg3_par *par)
{
enum cg3_type type;
u8 *p;
@@ -346,7 +346,7 @@ static int __devinit cg3_do_default_mode(struct cg3_par *par)
return 0;
}
-static int __devinit cg3_probe(struct platform_device *op)
+static int cg3_probe(struct platform_device *op)
{
struct device_node *dp = op->dev.of_node;
struct fb_info *info;
@@ -433,7 +433,7 @@ out_err:
return err;
}
-static int __devexit cg3_remove(struct platform_device *op)
+static int cg3_remove(struct platform_device *op)
{
struct fb_info *info = dev_get_drvdata(&op->dev);
struct cg3_par *par = info->par;
@@ -469,7 +469,7 @@ static struct platform_driver cg3_driver = {
.of_match_table = cg3_match,
},
.probe = cg3_probe,
- .remove = __devexit_p(cg3_remove),
+ .remove = cg3_remove,
};
static int __init cg3_init(void)
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 179e96c..3545dec 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -607,7 +607,7 @@ static int cg6_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
* Initialisation
*/
-static void __devinit cg6_init_fix(struct fb_info *info, int linebytes)
+static void cg6_init_fix(struct fb_info *info, int linebytes)
{
struct cg6_par *par = (struct cg6_par *)info->par;
const char *cg6_cpu_name, *cg6_card_name;
@@ -649,7 +649,7 @@ static void __devinit cg6_init_fix(struct fb_info *info, int linebytes)
}
/* Initialize Brooktree DAC */
-static void __devinit cg6_bt_init(struct cg6_par *par)
+static void cg6_bt_init(struct cg6_par *par)
{
struct bt_regs __iomem *bt = par->bt;
@@ -663,7 +663,7 @@ static void __devinit cg6_bt_init(struct cg6_par *par)
sbus_writel(0x00 << 24, &bt->control);
}
-static void __devinit cg6_chip_init(struct fb_info *info)
+static void cg6_chip_init(struct fb_info *info)
{
struct cg6_par *par = (struct cg6_par *)info->par;
struct cg6_tec __iomem *tec = par->tec;
@@ -737,7 +737,7 @@ static void cg6_unmap_regs(struct platform_device *op, struct fb_info *info,
info->fix.smem_len);
}
-static int __devinit cg6_probe(struct platform_device *op)
+static int cg6_probe(struct platform_device *op)
{
struct device_node *dp = op->dev.of_node;
struct fb_info *info;
@@ -827,7 +827,7 @@ out_err:
return err;
}
-static int __devexit cg6_remove(struct platform_device *op)
+static int cg6_remove(struct platform_device *op)
{
struct fb_info *info = dev_get_drvdata(&op->dev);
struct cg6_par *par = info->par;
@@ -862,7 +862,7 @@ static struct platform_driver cg6_driver = {
.of_match_table = cg6_match,
},
.probe = cg6_probe,
- .remove = __devexit_p(cg6_remove),
+ .remove = cg6_remove,
};
static int __init cg6_init(void)
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index cff742a..206a66b 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -292,7 +292,7 @@ static void __init chips_hw_init(void)
write_fr(chips_init_fr[i].addr, chips_init_fr[i].data);
}
-static struct fb_fix_screeninfo chipsfb_fix __devinitdata = {
+static struct fb_fix_screeninfo chipsfb_fix = {
.id = "C&T 65550",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
@@ -309,7 +309,7 @@ static struct fb_fix_screeninfo chipsfb_fix __devinitdata = {
.smem_len = 0x100000, /* 1MB */
};
-static struct fb_var_screeninfo chipsfb_var __devinitdata = {
+static struct fb_var_screeninfo chipsfb_var = {
.xres = 800,
.yres = 600,
.xres_virtual = 800,
@@ -330,7 +330,7 @@ static struct fb_var_screeninfo chipsfb_var __devinitdata = {
.vsync_len = 8,
};
-static void __devinit init_chips(struct fb_info *p, unsigned long addr)
+static void init_chips(struct fb_info *p, unsigned long addr)
{
memset(p->screen_base, 0, 0x100000);
@@ -347,8 +347,7 @@ static void __devinit init_chips(struct fb_info *p, unsigned long addr)
chips_hw_init();
}
-static int __devinit
-chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
+static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
{
struct fb_info *p;
unsigned long addr, size;
@@ -438,7 +437,7 @@ chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
return rc;
}
-static void __devexit chipsfb_remove(struct pci_dev *dp)
+static void chipsfb_remove(struct pci_dev *dp)
{
struct fb_info *p = pci_get_drvdata(dp);
@@ -495,7 +494,7 @@ static struct pci_driver chipsfb_driver = {
.name = "chipsfb",
.id_table = chipsfb_pci_tbl,
.probe = chipsfb_pci_init,
- .remove = __devexit_p(chipsfb_remove),
+ .remove = chipsfb_remove,
#ifdef CONFIG_PM
.suspend = chipsfb_pci_suspend,
.resume = chipsfb_pci_resume,
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index bc67d05..c3dbbe6 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -290,34 +290,34 @@ struct zorrocl {
zorro_id ramid2; /* Zorro ID of optional second RAM device */
};
-static const struct zorrocl zcl_sd64 __devinitconst = {
+static const struct zorrocl zcl_sd64 = {
.type = BT_SD64,
.ramid = ZORRO_PROD_HELFRICH_SD64_RAM,
};
-static const struct zorrocl zcl_piccolo __devinitconst = {
+static const struct zorrocl zcl_piccolo = {
.type = BT_PICCOLO,
.ramid = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
};
-static const struct zorrocl zcl_picasso __devinitconst = {
+static const struct zorrocl zcl_picasso = {
.type = BT_PICASSO,
.ramid = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
};
-static const struct zorrocl zcl_spectrum __devinitconst = {
+static const struct zorrocl zcl_spectrum = {
.type = BT_SPECTRUM,
.ramid = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
};
-static const struct zorrocl zcl_picasso4_z3 __devinitconst = {
+static const struct zorrocl zcl_picasso4_z3 = {
.type = BT_PICASSO4,
.regoffset = 0x00600000,
.ramsize = 4 * MB_,
.ramoffset = 0x01000000, /* 0x02000000 for 64 MiB boards */
};
-static const struct zorrocl zcl_picasso4_z2 __devinitconst = {
+static const struct zorrocl zcl_picasso4_z2 = {
.type = BT_PICASSO4,
.regoffset = 0x10000,
.ramid = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM1,
@@ -325,7 +325,7 @@ static const struct zorrocl zcl_picasso4_z2 __devinitconst = {
};
-static const struct zorro_device_id cirrusfb_zorro_table[] __devinitconst = {
+static const struct zorro_device_id cirrusfb_zorro_table[] = {
{
.id = ZORRO_PROD_HELFRICH_SD64_REG,
.driver_data = (unsigned long)&zcl_sd64,
@@ -372,8 +372,8 @@ struct cirrusfb_info {
void (*unmap)(struct fb_info *info);
};
-static bool noaccel __devinitdata;
-static char *mode_option __devinitdata = "640x480@60";
+static bool noaccel;
+static char *mode_option = "640x480@60";
/****************************************************************************/
/**** BEGIN PROTOTYPES ******************************************************/
@@ -1892,8 +1892,8 @@ static int release_io_ports;
* based on the DRAM bandwidth bit and DRAM bank switching bit. This
* works with 1MB, 2MB and 4MB configurations (which the Motorola boards
* seem to have. */
-static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info,
- u8 __iomem *regbase)
+static unsigned int cirrusfb_get_memsize(struct fb_info *info,
+ u8 __iomem *regbase)
{
unsigned long mem;
struct cirrusfb_info *cinfo = info->par;
@@ -2003,7 +2003,7 @@ static struct fb_ops cirrusfb_ops = {
.fb_imageblit = cirrusfb_imageblit,
};
-static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
+static int cirrusfb_set_fbinfo(struct fb_info *info)
{
struct cirrusfb_info *cinfo = info->par;
struct fb_var_screeninfo *var = &info->var;
@@ -2052,7 +2052,7 @@ static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
return 0;
}
-static int __devinit cirrusfb_register(struct fb_info *info)
+static int cirrusfb_register(struct fb_info *info)
{
struct cirrusfb_info *cinfo = info->par;
int err;
@@ -2096,7 +2096,7 @@ err_dealloc_cmap:
return err;
}
-static void __devexit cirrusfb_cleanup(struct fb_info *info)
+static void cirrusfb_cleanup(struct fb_info *info)
{
struct cirrusfb_info *cinfo = info->par;
@@ -2109,8 +2109,8 @@ static void __devexit cirrusfb_cleanup(struct fb_info *info)
}
#ifdef CONFIG_PCI
-static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int cirrusfb_pci_register(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
struct cirrusfb_info *cinfo;
struct fb_info *info;
@@ -2215,7 +2215,7 @@ err_out:
return ret;
}
-static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev)
+static void cirrusfb_pci_unregister(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
@@ -2226,7 +2226,7 @@ static struct pci_driver cirrusfb_pci_driver = {
.name = "cirrusfb",
.id_table = cirrusfb_pci_table,
.probe = cirrusfb_pci_register,
- .remove = __devexit_p(cirrusfb_pci_unregister),
+ .remove = cirrusfb_pci_unregister,
#ifdef CONFIG_PM
#if 0
.suspend = cirrusfb_pci_suspend,
@@ -2237,8 +2237,8 @@ static struct pci_driver cirrusfb_pci_driver = {
#endif /* CONFIG_PCI */
#ifdef CONFIG_ZORRO
-static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
- const struct zorro_device_id *ent)
+static int cirrusfb_zorro_register(struct zorro_dev *z,
+ const struct zorro_device_id *ent)
{
struct fb_info *info;
int error;
@@ -2352,7 +2352,7 @@ err_release_fb:
return error;
}
-void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
+void cirrusfb_zorro_unregister(struct zorro_dev *z)
{
struct fb_info *info = zorro_get_drvdata(z);
@@ -2364,7 +2364,7 @@ static struct zorro_driver cirrusfb_zorro_driver = {
.name = "cirrusfb",
.id_table = cirrusfb_zorro_table,
.probe = cirrusfb_zorro_register,
- .remove = __devexit_p(cirrusfb_zorro_unregister),
+ .remove = cirrusfb_zorro_unregister,
};
#endif /* CONFIG_ZORRO */
diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c
index f994c8b..f009806 100644
--- a/drivers/video/clps711xfb.c
+++ b/drivers/video/clps711xfb.c
@@ -22,19 +22,16 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/fb.h>
#include <linux/init.h>
-#include <linux/proc_fs.h>
#include <linux/delay.h>
+#include <linux/platform_device.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <linux/uaccess.h>
-#include <mach/syspld.h>
-
struct fb_info *cfb;
#define CMAP_MAX_SIZE 16
@@ -162,44 +159,12 @@ clps7111fb_set_par(struct fb_info *info)
static int clps7111fb_blank(int blank, struct fb_info *info)
{
- if (blank) {
- if (machine_is_edb7211()) {
- /* Turn off the LCD backlight. */
- clps_writeb(clps_readb(PDDR) & ~EDB_PD3_LCDBL, PDDR);
-
- /* Power off the LCD DC-DC converter. */
- clps_writeb(clps_readb(PDDR) & ~EDB_PD1_LCD_DC_DC_EN, PDDR);
-
- /* Delay for a little while (half a second). */
- udelay(100);
-
- /* Power off the LCD panel. */
- clps_writeb(clps_readb(PDDR) & ~EDB_PD2_LCDEN, PDDR);
-
- /* Power off the LCD controller. */
- clps_writel(clps_readl(SYSCON1) & ~SYSCON1_LCDEN,
- SYSCON1);
- }
- } else {
- if (machine_is_edb7211()) {
- /* Power up the LCD controller. */
- clps_writel(clps_readl(SYSCON1) | SYSCON1_LCDEN,
- SYSCON1);
-
- /* Power up the LCD panel. */
- clps_writeb(clps_readb(PDDR) | EDB_PD2_LCDEN, PDDR);
-
- /* Delay for a little while. */
- udelay(100);
+ /* Enable/Disable LCD controller. */
+ if (blank)
+ clps_writel(clps_readl(SYSCON1) & ~SYSCON1_LCDEN, SYSCON1);
+ else
+ clps_writel(clps_readl(SYSCON1) | SYSCON1_LCDEN, SYSCON1);
- /* Power up the LCD DC-DC converter. */
- clps_writeb(clps_readb(PDDR) | EDB_PD1_LCD_DC_DC_EN,
- PDDR);
-
- /* Turn on the LCD backlight. */
- clps_writeb(clps_readb(PDDR) | EDB_PD3_LCDBL, PDDR);
- }
- }
return 0;
}
@@ -214,63 +179,7 @@ static struct fb_ops clps7111fb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static int backlight_proc_show(struct seq_file *m, void *v)
-{
- if (machine_is_edb7211()) {
- seq_printf(m, "%d\n",
- (clps_readb(PDDR) & EDB_PD3_LCDBL) ? 1 : 0);
- }
-
- return 0;
-}
-
-static int backlight_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, backlight_proc_show, NULL);
-}
-
-static ssize_t backlight_proc_write(struct file *file, const char *buffer,
- size_t count, loff_t *pos)
-{
- unsigned char char_value;
- int value;
-
- if (count < 1) {
- return -EINVAL;
- }
-
- if (copy_from_user(&char_value, buffer, 1))
- return -EFAULT;
-
- value = char_value - '0';
-
- if (machine_is_edb7211()) {
- unsigned char port_d;
-
- port_d = clps_readb(PDDR);
-
- if (value) {
- port_d |= EDB_PD3_LCDBL;
- } else {
- port_d &= ~EDB_PD3_LCDBL;
- }
-
- clps_writeb(port_d, PDDR);
- }
-
- return count;
-}
-
-static const struct file_operations backlight_proc_fops = {
- .owner = THIS_MODULE,
- .open = backlight_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = backlight_proc_write,
-};
-
-static void __init clps711x_guess_lcd_params(struct fb_info *info)
+static void clps711x_guess_lcd_params(struct fb_info *info)
{
unsigned int lcdcon, syscon, size;
unsigned long phys_base = PAGE_OFFSET;
@@ -358,7 +267,7 @@ static void __init clps711x_guess_lcd_params(struct fb_info *info)
info->fix.type = FB_TYPE_PACKED_PIXELS;
}
-int __init clps711xfb_init(void)
+static int clps711x_fb_probe(struct platform_device *pdev)
{
int err = -ENOMEM;
@@ -378,55 +287,29 @@ int __init clps711xfb_init(void)
fb_alloc_cmap(&cfb->cmap, CMAP_MAX_SIZE, 0);
- if (!proc_create("backlight", 0444, NULL, &backlight_proc_fops)) {
- printk("Couldn't create the /proc entry for the backlight.\n");
- return -EINVAL;
- }
-
- /*
- * Power up the LCD
- */
- if (machine_is_p720t()) {
- PLD_LCDEN = PLD_LCDEN_EN;
- PLD_PWR |= (PLD_S4_ON|PLD_S3_ON|PLD_S2_ON|PLD_S1_ON);
- }
-
- if (machine_is_edb7211()) {
- /* Power up the LCD panel. */
- clps_writeb(clps_readb(PDDR) | EDB_PD2_LCDEN, PDDR);
-
- /* Delay for a little while. */
- udelay(100);
-
- /* Power up the LCD DC-DC converter. */
- clps_writeb(clps_readb(PDDR) | EDB_PD1_LCD_DC_DC_EN, PDDR);
-
- /* Turn on the LCD backlight. */
- clps_writeb(clps_readb(PDDR) | EDB_PD3_LCDBL, PDDR);
- }
-
err = register_framebuffer(cfb);
out: return err;
}
-static void __exit clps711xfb_exit(void)
+static int clps711x_fb_remove(struct platform_device *pdev)
{
unregister_framebuffer(cfb);
kfree(cfb);
- /*
- * Power down the LCD
- */
- if (machine_is_p720t()) {
- PLD_LCDEN = 0;
- PLD_PWR &= ~(PLD_S4_ON|PLD_S3_ON|PLD_S2_ON|PLD_S1_ON);
- }
+ return 0;
}
-module_init(clps711xfb_init);
-module_exit(clps711xfb_exit);
+static struct platform_driver clps711x_fb_driver = {
+ .driver = {
+ .name = "video-clps711x",
+ .owner = THIS_MODULE,
+ },
+ .probe = clps711x_fb_probe,
+ .remove = clps711x_fb_remove,
+};
+module_platform_driver(clps711x_fb_driver);
MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-MODULE_DESCRIPTION("CLPS711x framebuffer driver");
+MODULE_DESCRIPTION("CLPS711X framebuffer driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/cobalt_lcdfb.c b/drivers/video/cobalt_lcdfb.c
index 01a4ee7..a903149 100644
--- a/drivers/video/cobalt_lcdfb.c
+++ b/drivers/video/cobalt_lcdfb.c
@@ -167,7 +167,7 @@ static void lcd_clear(struct fb_info *info)
lcd_write_control(info, LCD_RESET);
}
-static struct fb_fix_screeninfo cobalt_lcdfb_fix __devinitdata = {
+static struct fb_fix_screeninfo cobalt_lcdfb_fix = {
.id = "cobalt-lcd",
.type = FB_TYPE_TEXT,
.type_aux = FB_AUX_TEXT_MDA,
@@ -331,7 +331,7 @@ static struct fb_ops cobalt_lcd_fbops = {
.fb_cursor = cobalt_lcdfb_cursor,
};
-static int __devinit cobalt_lcdfb_probe(struct platform_device *dev)
+static int cobalt_lcdfb_probe(struct platform_device *dev)
{
struct fb_info *info;
struct resource *res;
@@ -374,7 +374,7 @@ static int __devinit cobalt_lcdfb_probe(struct platform_device *dev)
return 0;
}
-static int __devexit cobalt_lcdfb_remove(struct platform_device *dev)
+static int cobalt_lcdfb_remove(struct platform_device *dev)
{
struct fb_info *info;
@@ -389,7 +389,7 @@ static int __devexit cobalt_lcdfb_remove(struct platform_device *dev)
static struct platform_driver cobalt_lcdfb_driver = {
.probe = cobalt_lcdfb_probe,
- .remove = __devexit_p(cobalt_lcdfb_remove),
+ .remove = cobalt_lcdfb_remove,
.driver = {
.name = "cobalt-lcd",
.owner = THIS_MODULE,
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index e2c96d0..bc922c4 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -46,7 +46,7 @@ config VGACON_SOFT_SCROLLBACK_SIZE
config MDA_CONSOLE
depends on !M68K && !PARISC && ISA
- tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
+ tristate "MDA text console (dual-headed)"
---help---
Say Y here if you have an old MDA or monochrome Hercules graphics
adapter in your system acting as a second head ( = video card). You
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index fdefa8f..3cd6759 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -529,6 +529,33 @@ static int search_for_mapped_con(void)
return retval;
}
+static int do_fbcon_takeover(int show_logo)
+{
+ int err, i;
+
+ if (!num_registered_fb)
+ return -ENODEV;
+
+ if (!show_logo)
+ logo_shown = FBCON_LOGO_DONTSHOW;
+
+ for (i = first_fb_vc; i <= last_fb_vc; i++)
+ con2fb_map[i] = info_idx;
+
+ err = do_take_over_console(&fb_con, first_fb_vc, last_fb_vc,
+ fbcon_is_default);
+
+ if (err) {
+ for (i = first_fb_vc; i <= last_fb_vc; i++)
+ con2fb_map[i] = -1;
+ info_idx = -1;
+ } else {
+ fbcon_has_console_bind = 1;
+ }
+
+ return err;
+}
+
static int fbcon_takeover(int show_logo)
{
int err, i;
@@ -815,6 +842,8 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
*
* Maps a virtual console @unit to a frame buffer device
* @newidx.
+ *
+ * This should be called with the console lock held.
*/
static int set_con2fb_map(int unit, int newidx, int user)
{
@@ -832,7 +861,7 @@ static int set_con2fb_map(int unit, int newidx, int user)
if (!search_for_mapped_con() || !con_is_bound(&fb_con)) {
info_idx = newidx;
- return fbcon_takeover(0);
+ return do_fbcon_takeover(0);
}
if (oldidx != -1)
@@ -840,7 +869,6 @@ static int set_con2fb_map(int unit, int newidx, int user)
found = search_fb_in_map(newidx);
- console_lock();
con2fb_map[unit] = newidx;
if (!err && !found)
err = con2fb_acquire_newinfo(vc, info, unit, oldidx);
@@ -867,7 +895,6 @@ static int set_con2fb_map(int unit, int newidx, int user)
if (!search_fb_in_map(info_idx))
info_idx = newidx;
- console_unlock();
return err;
}
@@ -990,7 +1017,7 @@ static const char *fbcon_startup(void)
}
/* Setup default font */
- if (!p->fontdata) {
+ if (!p->fontdata && !vc->vc_font.data) {
if (!fontname[0] || !(font = find_font(fontname)))
font = get_default_font(info->var.xres,
info->var.yres,
@@ -1000,6 +1027,8 @@ static const char *fbcon_startup(void)
vc->vc_font.height = font->height;
vc->vc_font.data = (void *)(p->fontdata = font->data);
vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */
+ } else {
+ p->fontdata = vc->vc_font.data;
}
cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
@@ -1159,9 +1188,9 @@ static void fbcon_init(struct vc_data *vc, int init)
ops->p = &fb_display[fg_console];
}
-static void fbcon_free_font(struct display *p)
+static void fbcon_free_font(struct display *p, bool freefont)
{
- if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))
+ if (freefont && p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))
kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int));
p->fontdata = NULL;
p->userfont = 0;
@@ -1173,8 +1202,8 @@ static void fbcon_deinit(struct vc_data *vc)
struct fb_info *info;
struct fbcon_ops *ops;
int idx;
+ bool free_font = true;
- fbcon_free_font(p);
idx = con2fb_map[vc->vc_num];
if (idx == -1)
@@ -1185,6 +1214,8 @@ static void fbcon_deinit(struct vc_data *vc)
if (!info)
goto finished;
+ if (info->flags & FBINFO_MISC_FIRMWARE)
+ free_font = false;
ops = info->fbcon_par;
if (!ops)
@@ -1196,6 +1227,8 @@ static void fbcon_deinit(struct vc_data *vc)
ops->flags &= ~FBCON_FLAGS_INIT;
finished:
+ fbcon_free_font(p, free_font);
+
if (!con_is_bound(&fb_con))
fbcon_exit();
@@ -1242,8 +1275,16 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
if (!height || !width)
return;
- if (sy < vc->vc_top && vc->vc_top == logo_lines)
+ if (sy < vc->vc_top && vc->vc_top == logo_lines) {
vc->vc_top = 0;
+ /*
+ * If the font dimensions are not an integral of the display
+ * dimensions then the ops->clear below won't end up clearing
+ * the margins. Call clear_margins here in case the logo
+ * bitmap stretched into the margin area.
+ */
+ fbcon_clear_margins(vc, 0);
+ }
/* Split blits that cross physical y_wrap boundary */
@@ -2977,7 +3018,7 @@ static int fbcon_unbind(void)
{
int ret;
- ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
+ ret = do_unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
fbcon_is_default);
if (!ret)
@@ -2992,6 +3033,7 @@ static inline int fbcon_unbind(void)
}
#endif /* CONFIG_VT_HW_CONSOLE_BINDING */
+/* called with console_lock held */
static int fbcon_fb_unbind(int idx)
{
int i, new_idx = -1, ret = 0;
@@ -3018,6 +3060,7 @@ static int fbcon_fb_unbind(int idx)
return ret;
}
+/* called with console_lock held */
static int fbcon_fb_unregistered(struct fb_info *info)
{
int i, idx;
@@ -3050,11 +3093,12 @@ static int fbcon_fb_unregistered(struct fb_info *info)
primary_device = -1;
if (!num_registered_fb)
- unregister_con_driver(&fb_con);
+ do_unregister_con_driver(&fb_con);
return 0;
}
+/* called with console_lock held */
static void fbcon_remap_all(int idx)
{
int i;
@@ -3099,6 +3143,7 @@ static inline void fbcon_select_primary(struct fb_info *info)
}
#endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */
+/* called with console_lock held */
static int fbcon_fb_registered(struct fb_info *info)
{
int ret = 0, i, idx;
@@ -3115,7 +3160,7 @@ static int fbcon_fb_registered(struct fb_info *info)
}
if (info_idx != -1)
- ret = fbcon_takeover(1);
+ ret = do_fbcon_takeover(1);
} else {
for (i = first_fb_vc; i <= last_fb_vc; i++) {
if (con2fb_map_boot[i] == idx)
@@ -3251,6 +3296,7 @@ static int fbcon_event_notify(struct notifier_block *self,
ret = fbcon_fb_unregistered(info);
break;
case FB_EVENT_SET_CONSOLE_MAP:
+ /* called with console lock held */
con2fb = event->data;
ret = set_con2fb_map(con2fb->console - 1,
con2fb->framebuffer, 1);
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index 6d15966..b05afd0 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -327,9 +327,16 @@ out_unmap:
static void newport_init(struct vc_data *vc, int init)
{
- vc->vc_cols = newport_xsize / 8;
- vc->vc_rows = newport_ysize / 16;
+ int cols, rows;
+
+ cols = newport_xsize / 8;
+ rows = newport_ysize / 16;
vc->vc_can_do_color = 1;
+ if (init) {
+ vc->vc_cols = cols;
+ vc->vc_rows = rows;
+ } else
+ vc_resize(vc, cols, rows);
}
static void newport_deinit(struct vc_data *c)
diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c
index 25f835b..46dd8f5 100644
--- a/drivers/video/console/softcursor.c
+++ b/drivers/video/console/softcursor.c
@@ -35,8 +35,7 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
dsize = s_pitch * cursor->image.height;
if (dsize + sizeof(struct fb_image) != ops->cursor_size) {
- if (ops->cursor_src != NULL)
- kfree(ops->cursor_src);
+ kfree(ops->cursor_src);
ops->cursor_size = dsize + sizeof(struct fb_image);
ops->cursor_src = kmalloc(ops->cursor_size, GFP_ATOMIC);
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
index 39571f9..35687fd 100644
--- a/drivers/video/console/sticore.c
+++ b/drivers/video/console/sticore.c
@@ -238,8 +238,7 @@ static void sti_flush(unsigned long start, unsigned long end)
flush_icache_range(start, end);
}
-static void __devinit sti_rom_copy(unsigned long base, unsigned long count,
- void *dest)
+static void sti_rom_copy(unsigned long base, unsigned long count, void *dest)
{
unsigned long dest_start = (unsigned long) dest;
@@ -266,7 +265,7 @@ static void __devinit sti_rom_copy(unsigned long base, unsigned long count,
static char default_sti_path[21] __read_mostly;
#ifndef MODULE
-static int __devinit sti_setup(char *str)
+static int sti_setup(char *str)
{
if (str)
strlcpy (default_sti_path, str, sizeof (default_sti_path));
@@ -285,12 +284,12 @@ __setup("sti=", sti_setup);
-static char __devinitdata *font_name[MAX_STI_ROMS] = { "VGA8x16", };
-static int __devinitdata font_index[MAX_STI_ROMS],
- font_height[MAX_STI_ROMS],
- font_width[MAX_STI_ROMS];
+static char *font_name[MAX_STI_ROMS] = { "VGA8x16", };
+static int font_index[MAX_STI_ROMS],
+ font_height[MAX_STI_ROMS],
+ font_width[MAX_STI_ROMS];
#ifndef MODULE
-static int __devinit sti_font_setup(char *str)
+static int sti_font_setup(char *str)
{
char *x;
int i = 0;
@@ -343,8 +342,8 @@ __setup("sti_font=", sti_font_setup);
-static void __devinit
-sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, unsigned int sti_mem_request)
+static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg,
+ unsigned int sti_mem_request)
{
struct sti_glob_cfg_ext *cfg;
@@ -383,8 +382,7 @@ sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, unsigned int sti_mem_request)
cfg->sti_mem_addr, sti_mem_request));
}
-static void __devinit
-sti_dump_outptr(struct sti_struct *sti)
+static void sti_dump_outptr(struct sti_struct *sti)
{
DPRINTK((KERN_INFO
"%d bits per pixel\n"
@@ -397,9 +395,8 @@ sti_dump_outptr(struct sti_struct *sti)
sti->outptr.attributes));
}
-static int __devinit
-sti_init_glob_cfg(struct sti_struct *sti,
- unsigned long rom_address, unsigned long hpa)
+static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
+ unsigned long hpa)
{
struct sti_glob_cfg *glob_cfg;
struct sti_glob_cfg_ext *glob_cfg_ext;
@@ -479,8 +476,8 @@ sti_init_glob_cfg(struct sti_struct *sti,
}
#ifdef CONFIG_FB
-static struct sti_cooked_font __devinit
-*sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
+static struct sti_cooked_font *
+sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
{
const struct font_desc *fbfont;
unsigned int size, bpc;
@@ -535,16 +532,15 @@ static struct sti_cooked_font __devinit
return cooked_font;
}
#else
-static struct sti_cooked_font __devinit
-*sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
+static struct sti_cooked_font *
+sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
{
return NULL;
}
#endif
-static struct sti_cooked_font __devinit
-*sti_select_font(struct sti_cooked_rom *rom,
- int (*search_font_fnc)(struct sti_cooked_rom *, int, int))
+static struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom,
+ int (*search_font_fnc)(struct sti_cooked_rom *, int, int))
{
struct sti_cooked_font *font;
int i;
@@ -569,8 +565,7 @@ static struct sti_cooked_font __devinit
}
-static void __devinit
-sti_dump_rom(struct sti_rom *rom)
+static void sti_dump_rom(struct sti_rom *rom)
{
printk(KERN_INFO " id %04x-%04x, conforms to spec rev. %d.%02x\n",
rom->graphics_id[0],
@@ -587,9 +582,8 @@ sti_dump_rom(struct sti_rom *rom)
}
-static int __devinit
-sti_cook_fonts(struct sti_cooked_rom *cooked_rom,
- struct sti_rom *raw_rom)
+static int sti_cook_fonts(struct sti_cooked_rom *cooked_rom,
+ struct sti_rom *raw_rom)
{
struct sti_rom_font *raw_font, *font_start;
struct sti_cooked_font *cooked_font;
@@ -622,8 +616,7 @@ sti_cook_fonts(struct sti_cooked_rom *cooked_rom,
}
-static int __devinit
-sti_search_font(struct sti_cooked_rom *rom, int height, int width)
+static int sti_search_font(struct sti_cooked_rom *rom, int height, int width)
{
struct sti_cooked_font *font;
int i = 0;
@@ -639,8 +632,7 @@ sti_search_font(struct sti_cooked_rom *rom, int height, int width)
#define BMODE_RELOCATE(offset) offset = (offset) / 4;
#define BMODE_LAST_ADDR_OFFS 0x50
-static void * __devinit
-sti_bmode_font_raw(struct sti_cooked_font *f)
+static void *sti_bmode_font_raw(struct sti_cooked_font *f)
{
unsigned char *n, *p, *q;
int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font);
@@ -657,8 +649,8 @@ sti_bmode_font_raw(struct sti_cooked_font *f)
return n + 3;
}
-static void __devinit
-sti_bmode_rom_copy(unsigned long base, unsigned long count, void *dest)
+static void sti_bmode_rom_copy(unsigned long base, unsigned long count,
+ void *dest)
{
unsigned long dest_start = (unsigned long) dest;
@@ -672,8 +664,7 @@ sti_bmode_rom_copy(unsigned long base, unsigned long count, void *dest)
sti_flush(dest_start, (unsigned long)dest);
}
-static struct sti_rom * __devinit
-sti_get_bmode_rom (unsigned long address)
+static struct sti_rom *sti_get_bmode_rom (unsigned long address)
{
struct sti_rom *raw;
u32 size;
@@ -708,7 +699,7 @@ sti_get_bmode_rom (unsigned long address)
return raw;
}
-static struct sti_rom __devinit *sti_get_wmode_rom(unsigned long address)
+static struct sti_rom *sti_get_wmode_rom(unsigned long address)
{
struct sti_rom *raw;
unsigned long size;
@@ -723,8 +714,8 @@ static struct sti_rom __devinit *sti_get_wmode_rom(unsigned long address)
return raw;
}
-static int __devinit sti_read_rom(int wordmode, struct sti_struct *sti,
- unsigned long address)
+static int sti_read_rom(int wordmode, struct sti_struct *sti,
+ unsigned long address)
{
struct sti_cooked_rom *cooked;
struct sti_rom *raw = NULL;
@@ -806,8 +797,9 @@ out_err:
return 0;
}
-static struct sti_struct * __devinit
-sti_try_rom_generic(unsigned long address, unsigned long hpa, struct pci_dev *pd)
+static struct sti_struct *sti_try_rom_generic(unsigned long address,
+ unsigned long hpa,
+ struct pci_dev *pd)
{
struct sti_struct *sti;
int ok;
@@ -921,7 +913,7 @@ out_err:
return NULL;
}
-static void __devinit sticore_check_for_default_sti(struct sti_struct *sti, char *path)
+static void sticore_check_for_default_sti(struct sti_struct *sti, char *path)
{
if (strcmp (path, default_sti_path) == 0)
default_sti = sti;
@@ -932,7 +924,7 @@ static void __devinit sticore_check_for_default_sti(struct sti_struct *sti, char
* in the additional address field addr[1] while on
* older Systems the PDC stores it in page0->proc_sti
*/
-static int __devinit sticore_pa_init(struct parisc_device *dev)
+static int sticore_pa_init(struct parisc_device *dev)
{
char pa_path[21];
struct sti_struct *sti = NULL;
@@ -953,8 +945,7 @@ static int __devinit sticore_pa_init(struct parisc_device *dev)
}
-static int __devinit sticore_pci_init(struct pci_dev *pd,
- const struct pci_device_id *ent)
+static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent)
{
#ifdef CONFIG_PCI
unsigned long fb_base, rom_base;
@@ -1001,7 +992,7 @@ static int __devinit sticore_pci_init(struct pci_dev *pd,
}
-static void __devexit sticore_pci_remove(struct pci_dev *pd)
+static void sticore_pci_remove(struct pci_dev *pd)
{
BUG();
}
@@ -1043,7 +1034,7 @@ static struct parisc_driver pa_sti_driver = {
static int sticore_initialized __read_mostly;
-static void __devinit sti_init_roms(void)
+static void sti_init_roms(void)
{
if (sticore_initialized)
return;
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index d449a74..5855d17 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -1064,7 +1064,7 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
unsigned short video_port_status = vga_video_port_reg + 6;
int font_select = 0x00, beg, i;
char *charmap;
-
+ bool clear_attribs = false;
if (vga_video_type != VIDEO_TYPE_EGAM) {
charmap = (char *) VGA_MAP_MEM(colourmap, 0);
beg = 0x0e;
@@ -1169,12 +1169,6 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
/* if 512 char mode is already enabled don't re-enable it. */
if ((set) && (ch512 != vga_512_chars)) {
- /* attribute controller */
- for (i = 0; i < MAX_NR_CONSOLES; i++) {
- struct vc_data *c = vc_cons[i].d;
- if (c && c->vc_sw == &vga_con)
- c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
- }
vga_512_chars = ch512;
/* 256-char: enable intensity bit
512-char: disable intensity bit */
@@ -1185,8 +1179,22 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
it means, but it works, and it appears necessary */
inb_p(video_port_status);
vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0);
+ clear_attribs = true;
}
raw_spin_unlock_irq(&vga_lock);
+
+ if (clear_attribs) {
+ for (i = 0; i < MAX_NR_CONSOLES; i++) {
+ struct vc_data *c = vc_cons[i].d;
+ if (c && c->vc_sw == &vga_con) {
+ /* force hi font mask to 0, so we always clear
+ the bit on either transition */
+ c->vc_hi_font_mask = 0x00;
+ clear_buffer_attributes(c);
+ c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
+ }
+ }
+ }
return 0;
}
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index e40125c..5788678 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -1230,7 +1230,7 @@ static int cyber2000fb_ddc_getsda(void *data)
return retval;
}
-static int __devinit cyber2000fb_setup_ddc_bus(struct cfb_info *cfb)
+static int cyber2000fb_setup_ddc_bus(struct cfb_info *cfb)
{
strlcpy(cfb->ddc_adapter.name, cfb->fb.fix.id,
sizeof(cfb->ddc_adapter.name));
@@ -1305,7 +1305,7 @@ static int cyber2000fb_i2c_getscl(void *data)
return ret;
}
-static int __devinit cyber2000fb_i2c_register(struct cfb_info *cfb)
+static int cyber2000fb_i2c_register(struct cfb_info *cfb)
{
strlcpy(cfb->i2c_adapter.name, cfb->fb.fix.id,
sizeof(cfb->i2c_adapter.name));
@@ -1336,7 +1336,7 @@ static void cyber2000fb_i2c_unregister(struct cfb_info *cfb)
* These parameters give
* 640x480, hsync 31.5kHz, vsync 60Hz
*/
-static struct fb_videomode __devinitdata cyber2000fb_default_mode = {
+static struct fb_videomode cyber2000fb_default_mode = {
.refresh = 60,
.xres = 640,
.yres = 480,
@@ -1404,8 +1404,7 @@ static void cyberpro_init_hw(struct cfb_info *cfb)
}
}
-static struct cfb_info __devinit *cyberpro_alloc_fb_info(unsigned int id,
- char *name)
+static struct cfb_info *cyberpro_alloc_fb_info(unsigned int id, char *name)
{
struct cfb_info *cfb;
@@ -1524,7 +1523,7 @@ static int cyber2000fb_setup(char *options)
* - memory mapped access to the registers
* - initialised mem_ctl1 and mem_ctl2 appropriately.
*/
-static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
+static int cyberpro_common_probe(struct cfb_info *cfb)
{
u_long smem_size;
u_int h_sync, v_sync;
@@ -1615,7 +1614,7 @@ failed:
return err;
}
-static void __devexit cyberpro_common_remove(struct cfb_info *cfb)
+static void cyberpro_common_remove(struct cfb_info *cfb)
{
unregister_framebuffer(&cfb->fb);
#ifdef CONFIG_FB_CYBER2000_DDC
@@ -1646,7 +1645,7 @@ static void cyberpro_common_resume(struct cfb_info *cfb)
#include <mach/framebuffer.h>
-static int __devinit cyberpro_vl_probe(void)
+static int cyberpro_vl_probe(void)
{
struct cfb_info *cfb;
int err = -ENOMEM;
@@ -1780,8 +1779,8 @@ static int cyberpro_pci_enable_mmio(struct cfb_info *cfb)
return 0;
}
-static int __devinit
-cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+static int cyberpro_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
{
struct cfb_info *cfb;
char name[16];
@@ -1863,7 +1862,7 @@ failed_release:
return err;
}
-static void __devexit cyberpro_pci_remove(struct pci_dev *dev)
+static void cyberpro_pci_remove(struct pci_dev *dev)
{
struct cfb_info *cfb = pci_get_drvdata(dev);
@@ -1923,7 +1922,7 @@ MODULE_DEVICE_TABLE(pci, cyberpro_pci_table);
static struct pci_driver cyberpro_driver = {
.name = "CyberPro",
.probe = cyberpro_pci_probe,
- .remove = __devexit_p(cyberpro_pci_remove),
+ .remove = cyberpro_pci_remove,
.suspend = cyberpro_pci_suspend,
.resume = cyberpro_pci_resume,
.id_table = cyberpro_pci_table
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 80665f6..0810939 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -185,7 +185,7 @@ struct da8xx_fb_par {
};
/* Variable Screen Information */
-static struct fb_var_screeninfo da8xx_fb_var __devinitdata = {
+static struct fb_var_screeninfo da8xx_fb_var = {
.xoffset = 0,
.yoffset = 0,
.transp = {0, 0, 0},
@@ -202,7 +202,7 @@ static struct fb_var_screeninfo da8xx_fb_var __devinitdata = {
.vmode = FB_VMODE_NONINTERLACED
};
-static struct fb_fix_screeninfo da8xx_fb_fix __devinitdata = {
+static struct fb_fix_screeninfo da8xx_fb_fix = {
.id = "DA8xx FB Drv",
.type = FB_TYPE_PACKED_PIXELS,
.type_aux = 0,
@@ -213,62 +213,51 @@ static struct fb_fix_screeninfo da8xx_fb_fix __devinitdata = {
.accel = FB_ACCEL_NONE
};
-struct da8xx_panel {
- const char name[25]; /* Full name <vendor>_<model> */
- unsigned short width;
- unsigned short height;
- int hfp; /* Horizontal front porch */
- int hbp; /* Horizontal back porch */
- int hsw; /* Horizontal Sync Pulse Width */
- int vfp; /* Vertical front porch */
- int vbp; /* Vertical back porch */
- int vsw; /* Vertical Sync Pulse Width */
- unsigned int pxl_clk; /* Pixel clock */
- unsigned char invert_pxl_clk; /* Invert Pixel clock */
-};
-
-static struct da8xx_panel known_lcd_panels[] = {
+static struct fb_videomode known_lcd_panels[] = {
/* Sharp LCD035Q3DG01 */
[0] = {
- .name = "Sharp_LCD035Q3DG01",
- .width = 320,
- .height = 240,
- .hfp = 8,
- .hbp = 6,
- .hsw = 0,
- .vfp = 2,
- .vbp = 2,
- .vsw = 0,
- .pxl_clk = 4608000,
- .invert_pxl_clk = 1,
+ .name = "Sharp_LCD035Q3DG01",
+ .xres = 320,
+ .yres = 240,
+ .pixclock = 4608000,
+ .left_margin = 6,
+ .right_margin = 8,
+ .upper_margin = 2,
+ .lower_margin = 2,
+ .hsync_len = 0,
+ .vsync_len = 0,
+ .sync = FB_SYNC_CLK_INVERT |
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
},
/* Sharp LK043T1DG01 */
[1] = {
- .name = "Sharp_LK043T1DG01",
- .width = 480,
- .height = 272,
- .hfp = 2,
- .hbp = 2,
- .hsw = 41,
- .vfp = 2,
- .vbp = 2,
- .vsw = 10,
- .pxl_clk = 7833600,
- .invert_pxl_clk = 0,
+ .name = "Sharp_LK043T1DG01",
+ .xres = 480,
+ .yres = 272,
+ .pixclock = 7833600,
+ .left_margin = 2,
+ .right_margin = 2,
+ .upper_margin = 2,
+ .lower_margin = 2,
+ .hsync_len = 41,
+ .vsync_len = 10,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .flag = 0,
},
[2] = {
/* Hitachi SP10Q010 */
- .name = "SP10Q010",
- .width = 320,
- .height = 240,
- .hfp = 10,
- .hbp = 10,
- .hsw = 10,
- .vfp = 10,
- .vbp = 10,
- .vsw = 10,
- .pxl_clk = 7833600,
- .invert_pxl_clk = 0,
+ .name = "SP10Q010",
+ .xres = 320,
+ .yres = 240,
+ .pixclock = 7833600,
+ .left_margin = 10,
+ .right_margin = 10,
+ .upper_margin = 10,
+ .lower_margin = 10,
+ .hsync_len = 10,
+ .vsync_len = 10,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .flag = 0,
},
};
@@ -399,10 +388,9 @@ static int lcd_cfg_dma(int burst_size, int fifo_th)
reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_8);
break;
case 16:
+ default:
reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16);
break;
- default:
- return -EINVAL;
}
reg |= (fifo_th << 8);
@@ -447,7 +435,8 @@ static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
}
-static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
+static int lcd_cfg_display(const struct lcd_ctrl_config *cfg,
+ struct fb_videomode *panel)
{
u32 reg;
u32 reg_int;
@@ -456,7 +445,7 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
LCD_MONO_8BIT_MODE |
LCD_MONOCHROME_MODE);
- switch (cfg->p_disp_panel->panel_shade) {
+ switch (cfg->panel_shade) {
case MONOCHROME:
reg |= LCD_MONOCHROME_MODE;
if (cfg->mono_8bit_mode)
@@ -469,7 +458,9 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
break;
case COLOR_PASSIVE:
- if (cfg->stn_565_mode)
+ /* AC bias applicable only for Pasive panels */
+ lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt);
+ if (cfg->bpp == 12 && cfg->stn_565_mode)
reg |= LCD_STN_565_ENABLE;
break;
@@ -490,22 +481,19 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
reg = lcdc_read(LCD_RASTER_TIMING_2_REG);
- if (cfg->sync_ctrl)
- reg |= LCD_SYNC_CTRL;
- else
- reg &= ~LCD_SYNC_CTRL;
+ reg |= LCD_SYNC_CTRL;
if (cfg->sync_edge)
reg |= LCD_SYNC_EDGE;
else
reg &= ~LCD_SYNC_EDGE;
- if (cfg->invert_line_clock)
+ if (panel->sync & FB_SYNC_HOR_HIGH_ACT)
reg |= LCD_INVERT_LINE_CLOCK;
else
reg &= ~LCD_INVERT_LINE_CLOCK;
- if (cfg->invert_frm_clock)
+ if (panel->sync & FB_SYNC_VERT_HIGH_ACT)
reg |= LCD_INVERT_FRAME_CLOCK;
else
reg &= ~LCD_INVERT_FRAME_CLOCK;
@@ -728,7 +716,7 @@ static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
}
static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
- struct da8xx_panel *panel)
+ struct fb_videomode *panel)
{
u32 bpp;
int ret = 0;
@@ -738,7 +726,7 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
/* Calculate the divider */
lcd_calc_clk_divider(par);
- if (panel->invert_pxl_clk)
+ if (panel->sync & FB_SYNC_CLK_INVERT)
lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) |
LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG);
else
@@ -750,30 +738,23 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
if (ret < 0)
return ret;
- /* Configure the AC bias properties. */
- lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt);
-
/* Configure the vertical and horizontal sync properties. */
- lcd_cfg_vertical_sync(panel->vbp, panel->vsw, panel->vfp);
- lcd_cfg_horizontal_sync(panel->hbp, panel->hsw, panel->hfp);
+ lcd_cfg_vertical_sync(panel->lower_margin, panel->vsync_len,
+ panel->upper_margin);
+ lcd_cfg_horizontal_sync(panel->right_margin, panel->hsync_len,
+ panel->left_margin);
/* Configure for disply */
- ret = lcd_cfg_display(cfg);
+ ret = lcd_cfg_display(cfg, panel);
if (ret < 0)
return ret;
- if (QVGA != cfg->p_disp_panel->panel_type)
- return -EINVAL;
+ bpp = cfg->bpp;
- if (cfg->bpp <= cfg->p_disp_panel->max_bpp &&
- cfg->bpp >= cfg->p_disp_panel->min_bpp)
- bpp = cfg->bpp;
- else
- bpp = cfg->p_disp_panel->max_bpp;
if (bpp == 12)
bpp = 16;
- ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->width,
- (unsigned int)panel->height, bpp,
+ ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->xres,
+ (unsigned int)panel->yres, bpp,
cfg->raster_order);
if (ret < 0)
return ret;
@@ -1012,7 +993,7 @@ static inline void lcd_da8xx_cpufreq_deregister(struct da8xx_fb_par *par)
}
#endif
-static int __devexit fb_remove(struct platform_device *dev)
+static int fb_remove(struct platform_device *dev)
{
struct fb_info *info = dev_get_drvdata(&dev->dev);
@@ -1230,12 +1211,12 @@ static unsigned int da8xxfb_pixel_clk_period(struct da8xx_fb_par *par)
return pix_clk_period_picosec;
}
-static int __devinit fb_probe(struct platform_device *device)
+static int fb_probe(struct platform_device *device)
{
struct da8xx_lcdc_platform_data *fb_pdata =
device->dev.platform_data;
struct lcd_ctrl_config *lcd_cfg;
- struct da8xx_panel *lcdc_info;
+ struct fb_videomode *lcdc_info;
struct fb_info *da8xx_fb_info;
struct clk *fb_clk = NULL;
struct da8xx_fb_par *par;
@@ -1267,7 +1248,7 @@ static int __devinit fb_probe(struct platform_device *device)
goto err_request_mem;
}
- fb_clk = clk_get(&device->dev, NULL);
+ fb_clk = clk_get(&device->dev, "fck");
if (IS_ERR(fb_clk)) {
dev_err(&device->dev, "Can not get device clock\n");
ret = -ENODEV;
@@ -1283,6 +1264,7 @@ static int __devinit fb_probe(struct platform_device *device)
lcd_revision = LCD_VERSION_1;
break;
case 0x4F200800:
+ case 0x4F201000:
lcd_revision = LCD_VERSION_2;
break;
default:
@@ -1323,7 +1305,7 @@ static int __devinit fb_probe(struct platform_device *device)
#ifdef CONFIG_CPU_FREQ
par->lcd_fck_rate = clk_get_rate(fb_clk);
#endif
- par->pxl_clk = lcdc_info->pxl_clk;
+ par->pxl_clk = lcdc_info->pixclock;
if (fb_pdata->panel_power_ctrl) {
par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
par->panel_power_ctrl(1);
@@ -1336,8 +1318,8 @@ static int __devinit fb_probe(struct platform_device *device)
}
/* allocate frame buffer */
- par->vram_size = lcdc_info->width * lcdc_info->height * lcd_cfg->bpp;
- ulcm = lcm((lcdc_info->width * lcd_cfg->bpp)/8, PAGE_SIZE);
+ par->vram_size = lcdc_info->xres * lcdc_info->yres * lcd_cfg->bpp;
+ ulcm = lcm((lcdc_info->xres * lcd_cfg->bpp)/8, PAGE_SIZE);
par->vram_size = roundup(par->vram_size/8, ulcm);
par->vram_size = par->vram_size * LCD_NUM_BUFFERS;
@@ -1355,10 +1337,10 @@ static int __devinit fb_probe(struct platform_device *device)
da8xx_fb_info->screen_base = (char __iomem *) par->vram_virt;
da8xx_fb_fix.smem_start = par->vram_phys;
da8xx_fb_fix.smem_len = par->vram_size;
- da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8;
+ da8xx_fb_fix.line_length = (lcdc_info->xres * lcd_cfg->bpp) / 8;
par->dma_start = par->vram_phys;
- par->dma_end = par->dma_start + lcdc_info->height *
+ par->dma_end = par->dma_start + lcdc_info->yres *
da8xx_fb_fix.line_length - 1;
/* allocate palette buffer */
@@ -1384,22 +1366,22 @@ static int __devinit fb_probe(struct platform_device *device)
/* Initialize par */
da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp;
- da8xx_fb_var.xres = lcdc_info->width;
- da8xx_fb_var.xres_virtual = lcdc_info->width;
+ da8xx_fb_var.xres = lcdc_info->xres;
+ da8xx_fb_var.xres_virtual = lcdc_info->xres;
- da8xx_fb_var.yres = lcdc_info->height;
- da8xx_fb_var.yres_virtual = lcdc_info->height * LCD_NUM_BUFFERS;
+ da8xx_fb_var.yres = lcdc_info->yres;
+ da8xx_fb_var.yres_virtual = lcdc_info->yres * LCD_NUM_BUFFERS;
da8xx_fb_var.grayscale =
- lcd_cfg->p_disp_panel->panel_shade == MONOCHROME ? 1 : 0;
+ lcd_cfg->panel_shade == MONOCHROME ? 1 : 0;
da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp;
- da8xx_fb_var.hsync_len = lcdc_info->hsw;
- da8xx_fb_var.vsync_len = lcdc_info->vsw;
- da8xx_fb_var.right_margin = lcdc_info->hfp;
- da8xx_fb_var.left_margin = lcdc_info->hbp;
- da8xx_fb_var.lower_margin = lcdc_info->vfp;
- da8xx_fb_var.upper_margin = lcdc_info->vbp;
+ da8xx_fb_var.hsync_len = lcdc_info->hsync_len;
+ da8xx_fb_var.vsync_len = lcdc_info->vsync_len;
+ da8xx_fb_var.right_margin = lcdc_info->right_margin;
+ da8xx_fb_var.left_margin = lcdc_info->left_margin;
+ da8xx_fb_var.lower_margin = lcdc_info->lower_margin;
+ da8xx_fb_var.upper_margin = lcdc_info->upper_margin;
da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par);
/* Initialize fbinfo */
@@ -1598,7 +1580,7 @@ static int fb_resume(struct platform_device *dev)
static struct platform_driver da8xx_fb_driver = {
.probe = fb_probe,
- .remove = __devexit_p(fb_remove),
+ .remove = fb_remove,
.suspend = fb_suspend,
.resume = fb_resume,
.driver = {
diff --git a/drivers/video/display_timing.c b/drivers/video/display_timing.c
new file mode 100644
index 0000000..5e1822c
--- /dev/null
+++ b/drivers/video/display_timing.c
@@ -0,0 +1,24 @@
+/*
+ * generic display timing functions
+ *
+ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * This file is released under the GPLv2
+ */
+
+#include <linux/export.h>
+#include <linux/slab.h>
+#include <video/display_timing.h>
+
+void display_timings_release(struct display_timings *disp)
+{
+ if (disp->timings) {
+ unsigned int i;
+
+ for (i = 0; i < disp->num_timings; i++)
+ kfree(disp->timings[i]);
+ kfree(disp->timings);
+ }
+ kfree(disp);
+}
+EXPORT_SYMBOL_GPL(display_timings_release);
diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c
index 49e3dda..3526899 100644
--- a/drivers/video/dnfb.c
+++ b/drivers/video/dnfb.c
@@ -115,7 +115,7 @@ static struct fb_ops dn_fb_ops = {
.fb_imageblit = cfb_imageblit,
};
-struct fb_var_screeninfo dnfb_var __devinitdata = {
+struct fb_var_screeninfo dnfb_var = {
.xres = 1280,
.yres = 1024,
.xres_virtual = 2048,
@@ -126,7 +126,7 @@ struct fb_var_screeninfo dnfb_var __devinitdata = {
.vmode = FB_VMODE_NONINTERLACED,
};
-static struct fb_fix_screeninfo dnfb_fix __devinitdata = {
+static struct fb_fix_screeninfo dnfb_fix = {
.id = "Apollo Mono",
.smem_start = (FRAME_BUFFER_START + IO_BASE),
.smem_len = FRAME_BUFFER_LEN,
@@ -224,7 +224,7 @@ void dnfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
* Initialization
*/
-static int __devinit dnfb_probe(struct platform_device *dev)
+static int dnfb_probe(struct platform_device *dev)
{
struct fb_info *info;
int err = 0;
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index 932abaa..50fe668 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -20,7 +20,7 @@ static bool request_mem_succeeded = false;
static struct pci_dev *default_vga;
-static struct fb_var_screeninfo efifb_defined __devinitdata = {
+static struct fb_var_screeninfo efifb_defined = {
.activate = FB_ACTIVATE_NOW,
.height = -1,
.width = -1,
@@ -31,7 +31,7 @@ static struct fb_var_screeninfo efifb_defined __devinitdata = {
.vmode = FB_VMODE_NONINTERLACED,
};
-static struct fb_fix_screeninfo efifb_fix __devinitdata = {
+static struct fb_fix_screeninfo efifb_fix = {
.id = "EFI VGA",
.type = FB_TYPE_PACKED_PIXELS,
.accel = FB_ACCEL_NONE,
diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c
index 755ef3e..3f2519d 100644
--- a/drivers/video/ep93xx-fb.c
+++ b/drivers/video/ep93xx-fb.c
@@ -484,7 +484,7 @@ static void ep93xxfb_dealloc_videomem(struct fb_info *info)
info->screen_base, info->fix.smem_start);
}
-static int __devinit ep93xxfb_probe(struct platform_device *pdev)
+static int ep93xxfb_probe(struct platform_device *pdev)
{
struct ep93xxfb_mach_info *mach_info = pdev->dev.platform_data;
struct fb_info *info;
@@ -599,7 +599,7 @@ failed_cmap:
return err;
}
-static int __devexit ep93xxfb_remove(struct platform_device *pdev)
+static int ep93xxfb_remove(struct platform_device *pdev)
{
struct fb_info *info = platform_get_drvdata(pdev);
struct ep93xx_fbi *fbi = info->par;
@@ -620,14 +620,14 @@ static int __devexit ep93xxfb_remove(struct platform_device *pdev)
static struct platform_driver ep93xxfb_driver = {
.probe = ep93xxfb_probe,
- .remove = __devexit_p(ep93xxfb_remove),
+ .remove = ep93xxfb_remove,
.driver = {
.name = "ep93xx-fb",
.owner = THIS_MODULE,
},
};
-static int __devinit ep93xxfb_init(void)
+static int ep93xxfb_init(void)
{
return platform_driver_register(&ep93xxfb_driver);
}
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index d55470e..de9d4da 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -18,6 +18,7 @@
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/of.h>
#include <video/exynos_dp.h>
@@ -48,10 +49,6 @@ static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
{
int timeout_loop = 0;
- exynos_dp_init_hpd(dp);
-
- usleep_range(200, 210);
-
while (exynos_dp_get_plug_in_status(dp) != 0) {
timeout_loop++;
if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
@@ -90,9 +87,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
*/
/* Read Extension Flag, Number of 128-byte EDID extension blocks */
- exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
+ retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
EDID_EXTENSION_FLAG,
&extend_block);
+ if (retval)
+ return retval;
if (extend_block > 0) {
dev_dbg(dp->dev, "EDID data includes a single extension!\n");
@@ -181,14 +180,15 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
int retval;
/* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */
- exynos_dp_read_bytes_from_dpcd(dp,
- DPCD_ADDR_DPCD_REV,
- 12, buf);
+ retval = exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_DPCD_REV,
+ 12, buf);
+ if (retval)
+ return retval;
/* Read EDID */
for (i = 0; i < 3; i++) {
retval = exynos_dp_read_edid(dp);
- if (retval == 0)
+ if (!retval)
break;
}
@@ -261,11 +261,10 @@ static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
}
}
-static void exynos_dp_link_start(struct exynos_dp_device *dp)
+static int exynos_dp_link_start(struct exynos_dp_device *dp)
{
u8 buf[4];
- int lane;
- int lane_count;
+ int lane, lane_count, pll_tries, retval;
lane_count = dp->link_train.lane_count;
@@ -275,10 +274,6 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
for (lane = 0; lane < lane_count; lane++)
dp->link_train.cr_loop[lane] = 0;
- /* Set sink to D0 (Sink Not Ready) mode. */
- exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_SINK_POWER_STATE,
- DPCD_SET_POWER_STATE_D0);
-
/* Set link rate and count as you want to establish*/
exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
exynos_dp_set_lane_count(dp, dp->link_train.lane_count);
@@ -286,29 +281,46 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
/* Setup RX configuration */
buf[0] = dp->link_train.link_rate;
buf[1] = dp->link_train.lane_count;
- exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET,
+ retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET,
2, buf);
+ if (retval)
+ return retval;
/* Set TX pre-emphasis to minimum */
for (lane = 0; lane < lane_count; lane++)
exynos_dp_set_lane_lane_pre_emphasis(dp,
PRE_EMPHASIS_LEVEL_0, lane);
+ /* Wait for PLL lock */
+ pll_tries = 0;
+ while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
+ if (pll_tries == DP_TIMEOUT_LOOP_COUNT) {
+ dev_err(dp->dev, "Wait for PLL lock timed out\n");
+ return -ETIMEDOUT;
+ }
+
+ pll_tries++;
+ usleep_range(90, 120);
+ }
+
/* Set training pattern 1 */
exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
/* Set RX training pattern */
- exynos_dp_write_byte_to_dpcd(dp,
- DPCD_ADDR_TRAINING_PATTERN_SET,
- DPCD_SCRAMBLING_DISABLED |
- DPCD_TRAINING_PATTERN_1);
+ retval = exynos_dp_write_byte_to_dpcd(dp,
+ DPCD_ADDR_TRAINING_PATTERN_SET,
+ DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_1);
+ if (retval)
+ return retval;
for (lane = 0; lane < lane_count; lane++)
buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0;
- exynos_dp_write_bytes_to_dpcd(dp,
- DPCD_ADDR_TRAINING_LANE0_SET,
- lane_count, buf);
+
+ retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_TRAINING_LANE0_SET,
+ lane_count, buf);
+
+ return retval;
}
static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
@@ -332,18 +344,17 @@ static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
return 0;
}
-static int exynos_dp_channel_eq_ok(u8 link_align[3], int lane_count)
+static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
+ int lane_count)
{
int lane;
- u8 lane_align;
u8 lane_status;
- lane_align = link_align[2];
- if ((lane_align & DPCD_INTERLANE_ALIGN_DONE) == 0)
+ if ((link_align & DPCD_INTERLANE_ALIGN_DONE) == 0)
return -EINVAL;
for (lane = 0; lane < lane_count; lane++) {
- lane_status = exynos_dp_get_lane_status(link_align, lane);
+ lane_status = exynos_dp_get_lane_status(link_status, lane);
lane_status &= DPCD_CHANNEL_EQ_BITS;
if (lane_status != DPCD_CHANNEL_EQ_BITS)
return -EINVAL;
@@ -427,60 +438,60 @@ static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
dp->link_train.lt_state = FAILED;
}
-static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
+static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp,
+ u8 adjust_request[2])
{
- u8 link_status[2];
- int lane;
- int lane_count;
+ int lane, lane_count;
+ u8 voltage_swing, pre_emphasis, training_lane;
- u8 adjust_request[2];
- u8 voltage_swing;
- u8 pre_emphasis;
- u8 training_lane;
+ lane_count = dp->link_train.lane_count;
+ for (lane = 0; lane < lane_count; lane++) {
+ voltage_swing = exynos_dp_get_adjust_request_voltage(
+ adjust_request, lane);
+ pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
+ adjust_request, lane);
+ training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
+ DPCD_PRE_EMPHASIS_SET(pre_emphasis);
+
+ if (voltage_swing == VOLTAGE_LEVEL_3)
+ training_lane |= DPCD_MAX_SWING_REACHED;
+ if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
+ training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
+
+ dp->link_train.training_lane[lane] = training_lane;
+ }
+}
+
+static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
+{
+ int lane, lane_count, retval;
+ u8 voltage_swing, pre_emphasis, training_lane;
+ u8 link_status[2], adjust_request[2];
usleep_range(100, 101);
lane_count = dp->link_train.lane_count;
- exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
- 2, link_status);
+ retval = exynos_dp_read_bytes_from_dpcd(dp,
+ DPCD_ADDR_LANE0_1_STATUS, 2, link_status);
+ if (retval)
+ return retval;
+
+ retval = exynos_dp_read_bytes_from_dpcd(dp,
+ DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
+ if (retval)
+ return retval;
if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
/* set training pattern 2 for EQ */
exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
- for (lane = 0; lane < lane_count; lane++) {
- exynos_dp_read_bytes_from_dpcd(dp,
- DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
- 2, adjust_request);
- voltage_swing = exynos_dp_get_adjust_request_voltage(
- adjust_request, lane);
- pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
- adjust_request, lane);
- training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
- DPCD_PRE_EMPHASIS_SET(pre_emphasis);
-
- if (voltage_swing == VOLTAGE_LEVEL_3)
- training_lane |= DPCD_MAX_SWING_REACHED;
- if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
- training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
-
- dp->link_train.training_lane[lane] = training_lane;
-
- exynos_dp_set_lane_link_training(dp,
- dp->link_train.training_lane[lane],
- lane);
- }
-
- exynos_dp_write_byte_to_dpcd(dp,
- DPCD_ADDR_TRAINING_PATTERN_SET,
- DPCD_SCRAMBLING_DISABLED |
- DPCD_TRAINING_PATTERN_2);
-
- exynos_dp_write_bytes_to_dpcd(dp,
- DPCD_ADDR_TRAINING_LANE0_SET,
- lane_count,
- dp->link_train.training_lane);
+ retval = exynos_dp_write_byte_to_dpcd(dp,
+ DPCD_ADDR_TRAINING_PATTERN_SET,
+ DPCD_SCRAMBLING_DISABLED |
+ DPCD_TRAINING_PATTERN_2);
+ if (retval)
+ return retval;
dev_info(dp->dev, "Link Training Clock Recovery success\n");
dp->link_train.lt_state = EQUALIZER_TRAINING;
@@ -488,152 +499,116 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
for (lane = 0; lane < lane_count; lane++) {
training_lane = exynos_dp_get_lane_link_training(
dp, lane);
- exynos_dp_read_bytes_from_dpcd(dp,
- DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
- 2, adjust_request);
voltage_swing = exynos_dp_get_adjust_request_voltage(
adjust_request, lane);
pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
adjust_request, lane);
- if (voltage_swing == VOLTAGE_LEVEL_3 ||
- pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
- dev_err(dp->dev, "voltage or pre emphasis reached max level\n");
- goto reduce_link_rate;
- }
-
- if ((DPCD_VOLTAGE_SWING_GET(training_lane) ==
- voltage_swing) &&
- (DPCD_PRE_EMPHASIS_GET(training_lane) ==
- pre_emphasis)) {
+ if (DPCD_VOLTAGE_SWING_GET(training_lane) ==
+ voltage_swing &&
+ DPCD_PRE_EMPHASIS_GET(training_lane) ==
+ pre_emphasis)
dp->link_train.cr_loop[lane]++;
- if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP) {
- dev_err(dp->dev, "CR Max loop\n");
- goto reduce_link_rate;
- }
- }
-
- training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
- DPCD_PRE_EMPHASIS_SET(pre_emphasis);
- if (voltage_swing == VOLTAGE_LEVEL_3)
- training_lane |= DPCD_MAX_SWING_REACHED;
- if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
- training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
+ if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP ||
+ voltage_swing == VOLTAGE_LEVEL_3 ||
+ pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
+ dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n",
+ dp->link_train.cr_loop[lane],
+ voltage_swing, pre_emphasis);
+ exynos_dp_reduce_link_rate(dp);
+ return -EIO;
+ }
+ }
+ }
- dp->link_train.training_lane[lane] = training_lane;
+ exynos_dp_get_adjust_training_lane(dp, adjust_request);
- exynos_dp_set_lane_link_training(dp,
- dp->link_train.training_lane[lane], lane);
- }
+ for (lane = 0; lane < lane_count; lane++)
+ exynos_dp_set_lane_link_training(dp,
+ dp->link_train.training_lane[lane], lane);
- exynos_dp_write_bytes_to_dpcd(dp,
- DPCD_ADDR_TRAINING_LANE0_SET,
- lane_count,
+ retval = exynos_dp_write_bytes_to_dpcd(dp,
+ DPCD_ADDR_TRAINING_LANE0_SET, lane_count,
dp->link_train.training_lane);
- }
-
- return 0;
+ if (retval)
+ return retval;
-reduce_link_rate:
- exynos_dp_reduce_link_rate(dp);
- return -EIO;
+ return retval;
}
static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
{
- u8 link_status[2];
- u8 link_align[3];
- int lane;
- int lane_count;
+ int lane, lane_count, retval;
u32 reg;
-
- u8 adjust_request[2];
- u8 voltage_swing;
- u8 pre_emphasis;
- u8 training_lane;
+ u8 link_align, link_status[2], adjust_request[2];
usleep_range(400, 401);
lane_count = dp->link_train.lane_count;
- exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
- 2, link_status);
+ retval = exynos_dp_read_bytes_from_dpcd(dp,
+ DPCD_ADDR_LANE0_1_STATUS, 2, link_status);
+ if (retval)
+ return retval;
- if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
- link_align[0] = link_status[0];
- link_align[1] = link_status[1];
+ if (exynos_dp_clock_recovery_ok(link_status, lane_count)) {
+ exynos_dp_reduce_link_rate(dp);
+ return -EIO;
+ }
- exynos_dp_read_byte_from_dpcd(dp,
- DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED,
- &link_align[2]);
+ retval = exynos_dp_read_bytes_from_dpcd(dp,
+ DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
+ if (retval)
+ return retval;
- for (lane = 0; lane < lane_count; lane++) {
- exynos_dp_read_bytes_from_dpcd(dp,
- DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
- 2, adjust_request);
- voltage_swing = exynos_dp_get_adjust_request_voltage(
- adjust_request, lane);
- pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
- adjust_request, lane);
- training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
- DPCD_PRE_EMPHASIS_SET(pre_emphasis);
+ retval = exynos_dp_read_byte_from_dpcd(dp,
+ DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED, &link_align);
+ if (retval)
+ return retval;
- if (voltage_swing == VOLTAGE_LEVEL_3)
- training_lane |= DPCD_MAX_SWING_REACHED;
- if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
- training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
+ exynos_dp_get_adjust_training_lane(dp, adjust_request);
- dp->link_train.training_lane[lane] = training_lane;
- }
+ if (!exynos_dp_channel_eq_ok(link_status, link_align, lane_count)) {
+ /* traing pattern Set to Normal */
+ exynos_dp_training_pattern_dis(dp);
- if (exynos_dp_channel_eq_ok(link_align, lane_count) == 0) {
- /* traing pattern Set to Normal */
- exynos_dp_training_pattern_dis(dp);
+ dev_info(dp->dev, "Link Training success!\n");
- dev_info(dp->dev, "Link Training success!\n");
-
- exynos_dp_get_link_bandwidth(dp, &reg);
- dp->link_train.link_rate = reg;
- dev_dbg(dp->dev, "final bandwidth = %.2x\n",
- dp->link_train.link_rate);
+ exynos_dp_get_link_bandwidth(dp, &reg);
+ dp->link_train.link_rate = reg;
+ dev_dbg(dp->dev, "final bandwidth = %.2x\n",
+ dp->link_train.link_rate);
- exynos_dp_get_lane_count(dp, &reg);
- dp->link_train.lane_count = reg;
- dev_dbg(dp->dev, "final lane count = %.2x\n",
- dp->link_train.lane_count);
+ exynos_dp_get_lane_count(dp, &reg);
+ dp->link_train.lane_count = reg;
+ dev_dbg(dp->dev, "final lane count = %.2x\n",
+ dp->link_train.lane_count);
- /* set enhanced mode if available */
- exynos_dp_set_enhanced_mode(dp);
- dp->link_train.lt_state = FINISHED;
- } else {
- /* not all locked */
- dp->link_train.eq_loop++;
+ /* set enhanced mode if available */
+ exynos_dp_set_enhanced_mode(dp);
+ dp->link_train.lt_state = FINISHED;
- if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
- dev_err(dp->dev, "EQ Max loop\n");
- goto reduce_link_rate;
- }
+ return 0;
+ }
- for (lane = 0; lane < lane_count; lane++)
- exynos_dp_set_lane_link_training(dp,
- dp->link_train.training_lane[lane],
- lane);
+ /* not all locked */
+ dp->link_train.eq_loop++;
- exynos_dp_write_bytes_to_dpcd(dp,
- DPCD_ADDR_TRAINING_LANE0_SET,
- lane_count,
- dp->link_train.training_lane);
- }
- } else {
- goto reduce_link_rate;
+ if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
+ dev_err(dp->dev, "EQ Max loop\n");
+ exynos_dp_reduce_link_rate(dp);
+ return -EIO;
}
- return 0;
+ for (lane = 0; lane < lane_count; lane++)
+ exynos_dp_set_lane_link_training(dp,
+ dp->link_train.training_lane[lane], lane);
+
+ retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_TRAINING_LANE0_SET,
+ lane_count, dp->link_train.training_lane);
-reduce_link_rate:
- exynos_dp_reduce_link_rate(dp);
- return -EIO;
+ return retval;
}
static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
@@ -701,16 +676,17 @@ static void exynos_dp_init_training(struct exynos_dp_device *dp,
static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
{
- int retval = 0;
- int training_finished = 0;
+ int retval = 0, training_finished = 0;
dp->link_train.lt_state = START;
/* Process here */
- while (!training_finished) {
+ while (!retval && !training_finished) {
switch (dp->link_train.lt_state) {
case START:
- exynos_dp_link_start(dp);
+ retval = exynos_dp_link_start(dp);
+ if (retval)
+ dev_err(dp->dev, "LT link start failed!\n");
break;
case CLOCK_RECOVERY:
retval = exynos_dp_process_clock_recovery(dp);
@@ -729,6 +705,8 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
return -EREMOTEIO;
}
}
+ if (retval)
+ dev_err(dp->dev, "eDP link training failed (%d)\n", retval);
return retval;
}
@@ -752,19 +730,15 @@ static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
return retval;
}
-static int exynos_dp_config_video(struct exynos_dp_device *dp,
- struct video_info *video_info)
+static int exynos_dp_config_video(struct exynos_dp_device *dp)
{
int retval = 0;
int timeout_loop = 0;
int done_count = 0;
- exynos_dp_config_video_slave_mode(dp, video_info);
+ exynos_dp_config_video_slave_mode(dp);
- exynos_dp_set_video_color_format(dp, video_info->color_depth,
- video_info->color_space,
- video_info->dynamic_range,
- video_info->ycbcr_coeff);
+ exynos_dp_set_video_color_format(dp);
if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
dev_err(dp->dev, "PLL is not locked yet.\n");
@@ -852,24 +826,228 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
{
struct exynos_dp_device *dp = arg;
- dev_err(dp->dev, "exynos_dp_irq_handler\n");
+ enum dp_irq_type irq_type;
+
+ irq_type = exynos_dp_get_irq_type(dp);
+ switch (irq_type) {
+ case DP_IRQ_TYPE_HP_CABLE_IN:
+ dev_dbg(dp->dev, "Received irq - cable in\n");
+ schedule_work(&dp->hotplug_work);
+ exynos_dp_clear_hotplug_interrupts(dp);
+ break;
+ case DP_IRQ_TYPE_HP_CABLE_OUT:
+ dev_dbg(dp->dev, "Received irq - cable out\n");
+ exynos_dp_clear_hotplug_interrupts(dp);
+ break;
+ case DP_IRQ_TYPE_HP_CHANGE:
+ /*
+ * We get these change notifications once in a while, but there
+ * is nothing we can do with them. Just ignore it for now and
+ * only handle cable changes.
+ */
+ dev_dbg(dp->dev, "Received irq - hotplug change; ignoring.\n");
+ exynos_dp_clear_hotplug_interrupts(dp);
+ break;
+ default:
+ dev_err(dp->dev, "Received irq - unknown type!\n");
+ break;
+ }
return IRQ_HANDLED;
}
-static int __devinit exynos_dp_probe(struct platform_device *pdev)
+static void exynos_dp_hotplug(struct work_struct *work)
{
- struct resource *res;
struct exynos_dp_device *dp;
- struct exynos_dp_platdata *pdata;
+ int ret;
+
+ dp = container_of(work, struct exynos_dp_device, hotplug_work);
+
+ ret = exynos_dp_detect_hpd(dp);
+ if (ret) {
+ /* Cable has been disconnected, we're done */
+ return;
+ }
+
+ ret = exynos_dp_handle_edid(dp);
+ if (ret) {
+ dev_err(dp->dev, "unable to handle edid\n");
+ return;
+ }
+
+ ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
+ dp->video_info->link_rate);
+ if (ret) {
+ dev_err(dp->dev, "unable to do link train\n");
+ return;
+ }
+
+ exynos_dp_enable_scramble(dp, 1);
+ exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
+ exynos_dp_enable_enhanced_mode(dp, 1);
+
+ exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
+ exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
+
+ exynos_dp_init_video(dp);
+ ret = exynos_dp_config_video(dp);
+ if (ret)
+ dev_err(dp->dev, "unable to config video\n");
+}
+
+#ifdef CONFIG_OF
+static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+ struct device_node *dp_node = dev->of_node;
+ struct exynos_dp_platdata *pd;
+ struct video_info *dp_video_config;
+
+ pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+ if (!pd) {
+ dev_err(dev, "memory allocation for pdata failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ dp_video_config = devm_kzalloc(dev,
+ sizeof(*dp_video_config), GFP_KERNEL);
+
+ if (!dp_video_config) {
+ dev_err(dev, "memory allocation for video config failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ pd->video_info = dp_video_config;
+
+ dp_video_config->h_sync_polarity =
+ of_property_read_bool(dp_node, "hsync-active-high");
+ dp_video_config->v_sync_polarity =
+ of_property_read_bool(dp_node, "vsync-active-high");
+
+ dp_video_config->interlaced =
+ of_property_read_bool(dp_node, "interlaced");
+
+ if (of_property_read_u32(dp_node, "samsung,color-space",
+ &dp_video_config->color_space)) {
+ dev_err(dev, "failed to get color-space\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,dynamic-range",
+ &dp_video_config->dynamic_range)) {
+ dev_err(dev, "failed to get dynamic-range\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
+ &dp_video_config->ycbcr_coeff)) {
+ dev_err(dev, "failed to get ycbcr-coeff\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,color-depth",
+ &dp_video_config->color_depth)) {
+ dev_err(dev, "failed to get color-depth\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,link-rate",
+ &dp_video_config->link_rate)) {
+ dev_err(dev, "failed to get link-rate\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,lane-count",
+ &dp_video_config->lane_count)) {
+ dev_err(dev, "failed to get lane-count\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ return pd;
+}
+
+static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+ struct device_node *dp_phy_node = of_node_get(dp->dev->of_node);
+ u32 phy_base;
int ret = 0;
- pdata = pdev->dev.platform_data;
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data\n");
- return -EINVAL;
+ dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy");
+ if (!dp_phy_node) {
+ dev_err(dp->dev, "could not find dptx-phy node\n");
+ return -ENODEV;
+ }
+
+ if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
+ dev_err(dp->dev, "faild to get reg for dptx-phy\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
+ &dp->enable_mask)) {
+ dev_err(dp->dev, "faild to get enable-mask for dptx-phy\n");
+ ret = -EINVAL;
+ goto err;
}
+ dp->phy_addr = ioremap(phy_base, SZ_4);
+ if (!dp->phy_addr) {
+ dev_err(dp->dev, "failed to ioremap dp-phy\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+err:
+ of_node_put(dp_phy_node);
+
+ return ret;
+}
+
+static void exynos_dp_phy_init(struct exynos_dp_device *dp)
+{
+ u32 reg;
+
+ reg = __raw_readl(dp->phy_addr);
+ reg |= dp->enable_mask;
+ __raw_writel(reg, dp->phy_addr);
+}
+
+static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+{
+ u32 reg;
+
+ reg = __raw_readl(dp->phy_addr);
+ reg &= ~(dp->enable_mask);
+ __raw_writel(reg, dp->phy_addr);
+}
+#else
+static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+ return NULL;
+}
+
+static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+ return -EINVAL;
+}
+
+static void exynos_dp_phy_init(struct exynos_dp_device *dp)
+{
+ return;
+}
+
+static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+{
+ return;
+}
+#endif /* CONFIG_OF */
+
+static int exynos_dp_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct exynos_dp_device *dp;
+ struct exynos_dp_platdata *pdata;
+
+ int ret = 0;
+
dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
GFP_KERNEL);
if (!dp) {
@@ -879,6 +1057,22 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
dp->dev = &pdev->dev;
+ if (pdev->dev.of_node) {
+ pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+
+ ret = exynos_dp_dt_parse_phydata(dp);
+ if (ret)
+ return ret;
+ } else {
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ dev_err(&pdev->dev, "no platform data\n");
+ return -EINVAL;
+ }
+ }
+
dp->clock = devm_clk_get(&pdev->dev, "dp");
if (IS_ERR(dp->clock)) {
dev_err(&pdev->dev, "failed to get clock\n");
@@ -889,57 +1083,34 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- dp->reg_base = devm_request_and_ioremap(&pdev->dev, res);
- if (!dp->reg_base) {
- dev_err(&pdev->dev, "failed to ioremap\n");
- return -ENOMEM;
- }
+ dp->reg_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(dp->reg_base))
+ return PTR_ERR(dp->reg_base);
dp->irq = platform_get_irq(pdev, 0);
- if (!dp->irq) {
+ if (dp->irq == -ENXIO) {
dev_err(&pdev->dev, "failed to get irq\n");
return -ENODEV;
}
- ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0,
- "exynos-dp", dp);
- if (ret) {
- dev_err(&pdev->dev, "failed to request irq\n");
- return ret;
- }
+ INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug);
dp->video_info = pdata->video_info;
- if (pdata->phy_init)
- pdata->phy_init();
-
- exynos_dp_init_dp(dp);
-
- ret = exynos_dp_detect_hpd(dp);
- if (ret) {
- dev_err(&pdev->dev, "unable to detect hpd\n");
- return ret;
- }
- exynos_dp_handle_edid(dp);
-
- ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
- dp->video_info->link_rate);
- if (ret) {
- dev_err(&pdev->dev, "unable to do link train\n");
- return ret;
+ if (pdev->dev.of_node) {
+ if (dp->phy_addr)
+ exynos_dp_phy_init(dp);
+ } else {
+ if (pdata->phy_init)
+ pdata->phy_init();
}
- exynos_dp_enable_scramble(dp, 1);
- exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
- exynos_dp_enable_enhanced_mode(dp, 1);
-
- exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
- exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
+ exynos_dp_init_dp(dp);
- exynos_dp_init_video(dp);
- ret = exynos_dp_config_video(dp, dp->video_info);
+ ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0,
+ "exynos-dp", dp);
if (ret) {
- dev_err(&pdev->dev, "unable to config video\n");
+ dev_err(&pdev->dev, "failed to request irq\n");
return ret;
}
@@ -948,28 +1119,44 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit exynos_dp_remove(struct platform_device *pdev)
+static int exynos_dp_remove(struct platform_device *pdev)
{
struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
struct exynos_dp_device *dp = platform_get_drvdata(pdev);
- if (pdata && pdata->phy_exit)
- pdata->phy_exit();
+ flush_work(&dp->hotplug_work);
+
+ if (pdev->dev.of_node) {
+ if (dp->phy_addr)
+ exynos_dp_phy_exit(dp);
+ } else {
+ if (pdata->phy_exit)
+ pdata->phy_exit();
+ }
clk_disable_unprepare(dp->clock);
+
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int exynos_dp_suspend(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
- struct exynos_dp_device *dp = platform_get_drvdata(pdev);
+ struct exynos_dp_platdata *pdata = dev->platform_data;
+ struct exynos_dp_device *dp = dev_get_drvdata(dev);
+
+ disable_irq(dp->irq);
- if (pdata && pdata->phy_exit)
- pdata->phy_exit();
+ flush_work(&dp->hotplug_work);
+
+ if (dev->of_node) {
+ if (dp->phy_addr)
+ exynos_dp_phy_exit(dp);
+ } else {
+ if (pdata->phy_exit)
+ pdata->phy_exit();
+ }
clk_disable_unprepare(dp->clock);
@@ -978,32 +1165,22 @@ static int exynos_dp_suspend(struct device *dev)
static int exynos_dp_resume(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
- struct exynos_dp_device *dp = platform_get_drvdata(pdev);
+ struct exynos_dp_platdata *pdata = dev->platform_data;
+ struct exynos_dp_device *dp = dev_get_drvdata(dev);
- if (pdata && pdata->phy_init)
- pdata->phy_init();
+ if (dev->of_node) {
+ if (dp->phy_addr)
+ exynos_dp_phy_init(dp);
+ } else {
+ if (pdata->phy_init)
+ pdata->phy_init();
+ }
clk_prepare_enable(dp->clock);
exynos_dp_init_dp(dp);
- exynos_dp_detect_hpd(dp);
- exynos_dp_handle_edid(dp);
-
- exynos_dp_set_link_train(dp, dp->video_info->lane_count,
- dp->video_info->link_rate);
-
- exynos_dp_enable_scramble(dp, 1);
- exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
- exynos_dp_enable_enhanced_mode(dp, 1);
-
- exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
- exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
-
- exynos_dp_init_video(dp);
- exynos_dp_config_video(dp, dp->video_info);
+ enable_irq(dp->irq);
return 0;
}
@@ -1013,13 +1190,20 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
};
+static const struct of_device_id exynos_dp_match[] = {
+ { .compatible = "samsung,exynos5-dp" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_match);
+
static struct platform_driver exynos_dp_driver = {
.probe = exynos_dp_probe,
- .remove = __devexit_p(exynos_dp_remove),
+ .remove = exynos_dp_remove,
.driver = {
.name = "exynos-dp",
.owner = THIS_MODULE,
.pm = &exynos_dp_pm_ops,
+ .of_match_table = of_match_ptr(exynos_dp_match),
},
};
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 57b8a65..6c567bbf 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -13,6 +13,13 @@
#ifndef _EXYNOS_DP_CORE_H
#define _EXYNOS_DP_CORE_H
+enum dp_irq_type {
+ DP_IRQ_TYPE_HP_CABLE_IN,
+ DP_IRQ_TYPE_HP_CABLE_OUT,
+ DP_IRQ_TYPE_HP_CHANGE,
+ DP_IRQ_TYPE_UNKNOWN,
+};
+
struct link_train {
int eq_loop;
int cr_loop[4];
@@ -29,9 +36,12 @@ struct exynos_dp_device {
struct clk *clock;
unsigned int irq;
void __iomem *reg_base;
+ void __iomem *phy_addr;
+ unsigned int enable_mask;
struct video_info *video_info;
struct link_train link_train;
+ struct work_struct hotplug_work;
};
/* exynos_dp_reg.c */
@@ -50,6 +60,8 @@ void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
bool enable);
void exynos_dp_init_analog_func(struct exynos_dp_device *dp);
void exynos_dp_init_hpd(struct exynos_dp_device *dp);
+enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp);
+void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp);
void exynos_dp_reset_aux(struct exynos_dp_device *dp);
void exynos_dp_init_aux(struct exynos_dp_device *dp);
int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp);
@@ -107,11 +119,7 @@ u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp);
void exynos_dp_reset_macro(struct exynos_dp_device *dp);
void exynos_dp_init_video(struct exynos_dp_device *dp);
-void exynos_dp_set_video_color_format(struct exynos_dp_device *dp,
- u32 color_depth,
- u32 color_space,
- u32 dynamic_range,
- u32 ycbcr_coeff);
+void exynos_dp_set_video_color_format(struct exynos_dp_device *dp);
int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp);
void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
enum clock_recovery_m_value_type type,
@@ -121,8 +129,7 @@ void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type);
void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable);
void exynos_dp_start_video(struct exynos_dp_device *dp);
int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp);
-void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp,
- struct video_info *video_info);
+void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp);
void exynos_dp_enable_scrambling(struct exynos_dp_device *dp);
void exynos_dp_disable_scrambling(struct exynos_dp_device *dp);
diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
index 3f5ca8a..29d9d03 100644
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -19,11 +19,11 @@
#include "exynos_dp_core.h"
#include "exynos_dp_reg.h"
-#define COMMON_INT_MASK_1 (0)
-#define COMMON_INT_MASK_2 (0)
-#define COMMON_INT_MASK_3 (0)
-#define COMMON_INT_MASK_4 (0)
-#define INT_STA_MASK (0)
+#define COMMON_INT_MASK_1 0
+#define COMMON_INT_MASK_2 0
+#define COMMON_INT_MASK_3 0
+#define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG)
+#define INT_STA_MASK INT_HPD
void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable)
{
@@ -88,7 +88,7 @@ void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
{
/* Set interrupt pin assertion polarity as high */
- writel(INT_POL, dp->reg_base + EXYNOS_DP_INT_CTL);
+ writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL);
/* Clear pending regisers */
writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
@@ -324,7 +324,7 @@ void exynos_dp_init_analog_func(struct exynos_dp_device *dp)
writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
}
-void exynos_dp_init_hpd(struct exynos_dp_device *dp)
+void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp)
{
u32 reg;
@@ -333,12 +333,38 @@ void exynos_dp_init_hpd(struct exynos_dp_device *dp)
reg = INT_HPD;
writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
+}
+
+void exynos_dp_init_hpd(struct exynos_dp_device *dp)
+{
+ u32 reg;
+
+ exynos_dp_clear_hotplug_interrupts(dp);
reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
reg &= ~(F_HPD | HPD_CTRL);
writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
}
+enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp)
+{
+ u32 reg;
+
+ /* Parse hotplug interrupt status register */
+ reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
+
+ if (reg & PLUG)
+ return DP_IRQ_TYPE_HP_CABLE_IN;
+
+ if (reg & HPD_LOST)
+ return DP_IRQ_TYPE_HP_CABLE_OUT;
+
+ if (reg & HOTPLUG_CHG)
+ return DP_IRQ_TYPE_HP_CHANGE;
+
+ return DP_IRQ_TYPE_UNKNOWN;
+}
+
void exynos_dp_reset_aux(struct exynos_dp_device *dp)
{
u32 reg;
@@ -491,7 +517,7 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
int i;
int retval;
- for (i = 0; i < 10; i++) {
+ for (i = 0; i < 3; i++) {
/* Clear AUX CH data buffer */
reg = BUF_CLR;
writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
@@ -552,7 +578,7 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
else
cur_data_count = count - start_offset;
- for (i = 0; i < 10; i++) {
+ for (i = 0; i < 3; i++) {
/* Select DPCD device address */
reg = AUX_ADDR_7_0(reg_addr + start_offset);
writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
@@ -617,7 +643,7 @@ int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
cur_data_count = count - start_offset;
/* AUX CH Request Transaction process */
- for (i = 0; i < 10; i++) {
+ for (i = 0; i < 3; i++) {
/* Select DPCD device address */
reg = AUX_ADDR_7_0(reg_addr + start_offset);
writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
@@ -700,17 +726,15 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
int i;
int retval;
- for (i = 0; i < 10; i++) {
+ for (i = 0; i < 3; i++) {
/* Clear AUX CH data buffer */
reg = BUF_CLR;
writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
/* Select EDID device */
retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr);
- if (retval != 0) {
- dev_err(dp->dev, "Select EDID device fail!\n");
+ if (retval != 0)
continue;
- }
/*
* Set I2C transaction and read data
@@ -750,7 +774,7 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
int retval = 0;
for (i = 0; i < count; i += 16) {
- for (j = 0; j < 100; j++) {
+ for (j = 0; j < 3; j++) {
/* Clear AUX CH data buffer */
reg = BUF_CLR;
writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
@@ -1034,24 +1058,20 @@ void exynos_dp_init_video(struct exynos_dp_device *dp)
writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8);
}
-void exynos_dp_set_video_color_format(struct exynos_dp_device *dp,
- u32 color_depth,
- u32 color_space,
- u32 dynamic_range,
- u32 ycbcr_coeff)
+void exynos_dp_set_video_color_format(struct exynos_dp_device *dp)
{
u32 reg;
/* Configure the input color depth, color space, dynamic range */
- reg = (dynamic_range << IN_D_RANGE_SHIFT) |
- (color_depth << IN_BPC_SHIFT) |
- (color_space << IN_COLOR_F_SHIFT);
+ reg = (dp->video_info->dynamic_range << IN_D_RANGE_SHIFT) |
+ (dp->video_info->color_depth << IN_BPC_SHIFT) |
+ (dp->video_info->color_space << IN_COLOR_F_SHIFT);
writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2);
/* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
reg &= ~IN_YC_COEFFI_MASK;
- if (ycbcr_coeff)
+ if (dp->video_info->ycbcr_coeff)
reg |= IN_YC_COEFFI_ITU709;
else
reg |= IN_YC_COEFFI_ITU601;
@@ -1178,8 +1198,7 @@ int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp)
return 0;
}
-void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp,
- struct video_info *video_info)
+void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp)
{
u32 reg;
@@ -1190,17 +1209,17 @@ void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp,
reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
reg &= ~INTERACE_SCAN_CFG;
- reg |= (video_info->interlaced << 2);
+ reg |= (dp->video_info->interlaced << 2);
writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
reg &= ~VSYNC_POLARITY_CFG;
- reg |= (video_info->v_sync_polarity << 1);
+ reg |= (dp->video_info->v_sync_polarity << 1);
writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
reg &= ~HSYNC_POLARITY_CFG;
- reg |= (video_info->h_sync_polarity << 0);
+ reg |= (dp->video_info->h_sync_polarity << 0);
writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
index 1f2f014c..2e9bd0e 100644
--- a/drivers/video/exynos/exynos_dp_reg.h
+++ b/drivers/video/exynos/exynos_dp_reg.h
@@ -242,7 +242,8 @@
/* EXYNOS_DP_INT_CTL */
#define SOFT_INT_CTRL (0x1 << 2)
-#define INT_POL (0x1 << 0)
+#define INT_POL1 (0x1 << 1)
+#define INT_POL0 (0x1 << 0)
/* EXYNOS_DP_SYS_CTL_1 */
#define DET_STA (0x1 << 2)
diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
index 07d70a3..fac7df6 100644
--- a/drivers/video/exynos/exynos_mipi_dsi.c
+++ b/drivers/video/exynos/exynos_mipi_dsi.c
@@ -338,7 +338,8 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
struct mipi_dsim_ddi *dsim_ddi;
int ret = -EINVAL;
- dsim = kzalloc(sizeof(struct mipi_dsim_device), GFP_KERNEL);
+ dsim = devm_kzalloc(&pdev->dev, sizeof(struct mipi_dsim_device),
+ GFP_KERNEL);
if (!dsim) {
dev_err(&pdev->dev, "failed to allocate dsim object.\n");
return -ENOMEM;
@@ -352,13 +353,13 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
dsim_pd = (struct mipi_dsim_platform_data *)dsim->pd;
if (dsim_pd == NULL) {
dev_err(&pdev->dev, "failed to get platform data for dsim.\n");
- goto err_clock_get;
+ return -EINVAL;
}
/* get mipi_dsim_config. */
dsim_config = dsim_pd->dsim_config;
if (dsim_config == NULL) {
dev_err(&pdev->dev, "failed to get dsim config data.\n");
- goto err_clock_get;
+ return -EINVAL;
}
dsim->dsim_config = dsim_config;
@@ -366,41 +367,28 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
mutex_init(&dsim->lock);
- ret = regulator_bulk_get(&pdev->dev, ARRAY_SIZE(supplies), supplies);
+ ret = devm_regulator_bulk_get(&pdev->dev, ARRAY_SIZE(supplies),
+ supplies);
if (ret) {
dev_err(&pdev->dev, "Failed to get regulators: %d\n", ret);
- goto err_clock_get;
+ return ret;
}
- dsim->clock = clk_get(&pdev->dev, "dsim0");
+ dsim->clock = devm_clk_get(&pdev->dev, "dsim0");
if (IS_ERR(dsim->clock)) {
dev_err(&pdev->dev, "failed to get dsim clock source\n");
- ret = -ENODEV;
- goto err_clock_get;
+ return -ENODEV;
}
clk_enable(dsim->clock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "failed to get io memory region\n");
- ret = -ENODEV;
- goto err_platform_get;
- }
-
- dsim->res = request_mem_region(res->start, resource_size(res),
- dev_name(&pdev->dev));
- if (!dsim->res) {
- dev_err(&pdev->dev, "failed to request io memory region\n");
- ret = -ENOMEM;
- goto err_mem_region;
- }
- dsim->reg_base = ioremap(res->start, resource_size(res));
+ dsim->reg_base = devm_request_and_ioremap(&pdev->dev, res);
if (!dsim->reg_base) {
dev_err(&pdev->dev, "failed to remap io region\n");
ret = -ENOMEM;
- goto err_ioremap;
+ goto error;
}
mutex_init(&dsim->lock);
@@ -410,26 +398,27 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
if (!dsim_ddi) {
dev_err(&pdev->dev, "mipi_dsim_ddi object not found.\n");
ret = -EINVAL;
- goto err_bind;
+ goto error;
}
dsim->irq = platform_get_irq(pdev, 0);
- if (dsim->irq < 0) {
+ if (IS_ERR_VALUE(dsim->irq)) {
dev_err(&pdev->dev, "failed to request dsim irq resource\n");
ret = -EINVAL;
- goto err_platform_get_irq;
+ goto error;
}
init_completion(&dsim_wr_comp);
init_completion(&dsim_rd_comp);
platform_set_drvdata(pdev, dsim);
- ret = request_irq(dsim->irq, exynos_mipi_dsi_interrupt_handler,
+ ret = devm_request_irq(&pdev->dev, dsim->irq,
+ exynos_mipi_dsi_interrupt_handler,
IRQF_SHARED, dev_name(&pdev->dev), dsim);
if (ret != 0) {
dev_err(&pdev->dev, "failed to request dsim irq\n");
ret = -EINVAL;
- goto err_bind;
+ goto error;
}
/* enable interrupts */
@@ -471,38 +460,18 @@ done:
return 0;
-err_bind:
- iounmap(dsim->reg_base);
-
-err_ioremap:
- release_mem_region(dsim->res->start, resource_size(dsim->res));
-
-err_mem_region:
- release_resource(dsim->res);
-
-err_platform_get:
+error:
clk_disable(dsim->clock);
- clk_put(dsim->clock);
-err_clock_get:
- kfree(dsim);
-
-err_platform_get_irq:
return ret;
}
-static int __devexit exynos_mipi_dsi_remove(struct platform_device *pdev)
+static int exynos_mipi_dsi_remove(struct platform_device *pdev)
{
struct mipi_dsim_device *dsim = platform_get_drvdata(pdev);
struct mipi_dsim_ddi *dsim_ddi, *next;
struct mipi_dsim_lcd_driver *dsim_lcd_drv;
- iounmap(dsim->reg_base);
-
clk_disable(dsim->clock);
- clk_put(dsim->clock);
-
- release_resource(dsim->res);
- release_mem_region(dsim->res->start, resource_size(dsim->res));
list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
if (dsim_ddi) {
@@ -518,9 +487,6 @@ static int __devexit exynos_mipi_dsi_remove(struct platform_device *pdev)
}
}
- regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
- kfree(dsim);
-
return 0;
}
@@ -595,7 +561,7 @@ static const struct dev_pm_ops exynos_mipi_dsi_pm_ops = {
static struct platform_driver exynos_mipi_dsi_driver = {
.probe = exynos_mipi_dsi_probe,
- .remove = __devexit_p(exynos_mipi_dsi_remove),
+ .remove = exynos_mipi_dsi_remove,
.driver = {
.name = "exynos-mipi-dsim",
.owner = THIS_MODULE,
diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c b/drivers/video/exynos/exynos_mipi_dsi_common.c
index 3cd29a4..c70cb89 100644
--- a/drivers/video/exynos/exynos_mipi_dsi_common.c
+++ b/drivers/video/exynos/exynos_mipi_dsi_common.c
@@ -25,6 +25,7 @@
#include <linux/io.h>
#include <linux/memory.h>
#include <linux/delay.h>
+#include <linux/irqreturn.h>
#include <linux/kthread.h>
#include <video/mipi_display.h>
diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
index 0ef38ce..95cb99a 100644
--- a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
+++ b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
@@ -21,6 +21,7 @@
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/ctype.h>
+#include <linux/platform_device.h>
#include <linux/io.h>
#include <video/exynos_mipi_dsim.h>
diff --git a/drivers/video/exynos/s6e8ax0.c b/drivers/video/exynos/s6e8ax0.c
index 05d080b..ca26024 100644
--- a/drivers/video/exynos/s6e8ax0.c
+++ b/drivers/video/exynos/s6e8ax0.c
@@ -776,7 +776,7 @@ static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)
int ret;
u8 mtp_id[3] = {0, };
- lcd = kzalloc(sizeof(struct s6e8ax0), GFP_KERNEL);
+ lcd = devm_kzalloc(&dsim_dev->dev, sizeof(struct s6e8ax0), GFP_KERNEL);
if (!lcd) {
dev_err(&dsim_dev->dev, "failed to allocate s6e8ax0 structure.\n");
return -ENOMEM;
@@ -788,18 +788,17 @@ static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)
mutex_init(&lcd->lock);
- ret = regulator_bulk_get(lcd->dev, ARRAY_SIZE(supplies), supplies);
+ ret = devm_regulator_bulk_get(lcd->dev, ARRAY_SIZE(supplies), supplies);
if (ret) {
dev_err(lcd->dev, "Failed to get regulators: %d\n", ret);
- goto err_lcd_register;
+ return ret;
}
lcd->ld = lcd_device_register("s6e8ax0", lcd->dev, lcd,
&s6e8ax0_lcd_ops);
if (IS_ERR(lcd->ld)) {
dev_err(lcd->dev, "failed to register lcd ops.\n");
- ret = PTR_ERR(lcd->ld);
- goto err_lcd_register;
+ return PTR_ERR(lcd->ld);
}
lcd->bd = backlight_device_register("s6e8ax0-bl", lcd->dev, lcd,
@@ -838,11 +837,6 @@ static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)
err_backlight_register:
lcd_device_unregister(lcd->ld);
-
-err_lcd_register:
- regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
- kfree(lcd);
-
return ret;
}
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 88cad6b..900aa4e 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -69,7 +69,7 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma,
int fb_deferred_io_fsync(struct file *file, loff_t start, loff_t end, int datasync)
{
struct fb_info *info = file->private_data;
- struct inode *inode = file->f_path.dentry->d_inode;
+ struct inode *inode = file_inode(file);
int err = filemap_write_and_wait_range(inode->i_mapping, start, end);
if (err)
return err;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 3ff0105..7c25408 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -727,7 +727,7 @@ static const struct file_operations fb_proc_fops = {
*/
static struct fb_info *file_fb_info(struct file *file)
{
- struct inode *inode = file->f_path.dentry->d_inode;
+ struct inode *inode = file_inode(file);
int fbidx = iminor(inode);
struct fb_info *info = registered_fb[fbidx];
@@ -1177,8 +1177,10 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
event.data = &con2fb;
if (!lock_fb_info(info))
return -ENODEV;
+ console_lock();
event.info = info;
ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);
+ console_unlock();
unlock_fb_info(info);
break;
case FBIOBLANK:
@@ -1650,7 +1652,9 @@ static int do_register_framebuffer(struct fb_info *fb_info)
event.info = fb_info;
if (!lock_fb_info(fb_info))
return -ENODEV;
+ console_lock();
fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
+ console_unlock();
unlock_fb_info(fb_info);
return 0;
}
@@ -1666,8 +1670,10 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
if (!lock_fb_info(fb_info))
return -ENODEV;
+ console_lock();
event.info = fb_info;
ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
+ console_unlock();
unlock_fb_info(fb_info);
if (ret)
@@ -1682,7 +1688,9 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
num_registered_fb--;
fb_cleanup_device(fb_info);
event.info = fb_info;
+ console_lock();
fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
+ console_unlock();
/* this may free fb info */
put_fb_info(fb_info);
@@ -1853,11 +1861,8 @@ int fb_new_modelist(struct fb_info *info)
err = 1;
if (!list_empty(&info->modelist)) {
- if (!lock_fb_info(info))
- return -ENODEV;
event.info = info;
err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event);
- unlock_fb_info(info);
}
return err;
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index cef6557..94ad0f7 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -31,6 +31,8 @@
#include <linux/pci.h>
#include <linux/slab.h>
#include <video/edid.h>
+#include <video/of_videomode.h>
+#include <video/videomode.h>
#ifdef CONFIG_PPC_OF
#include <asm/prom.h>
#include <asm/pci-bridge.h>
@@ -1373,6 +1375,98 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf
kfree(timings);
return err;
}
+
+#if IS_ENABLED(CONFIG_VIDEOMODE)
+int fb_videomode_from_videomode(const struct videomode *vm,
+ struct fb_videomode *fbmode)
+{
+ unsigned int htotal, vtotal;
+
+ fbmode->xres = vm->hactive;
+ fbmode->left_margin = vm->hback_porch;
+ fbmode->right_margin = vm->hfront_porch;
+ fbmode->hsync_len = vm->hsync_len;
+
+ fbmode->yres = vm->vactive;
+ fbmode->upper_margin = vm->vback_porch;
+ fbmode->lower_margin = vm->vfront_porch;
+ fbmode->vsync_len = vm->vsync_len;
+
+ /* prevent division by zero in KHZ2PICOS macro */
+ fbmode->pixclock = vm->pixelclock ?
+ KHZ2PICOS(vm->pixelclock / 1000) : 0;
+
+ fbmode->sync = 0;
+ fbmode->vmode = 0;
+ if (vm->dmt_flags & VESA_DMT_HSYNC_HIGH)
+ fbmode->sync |= FB_SYNC_HOR_HIGH_ACT;
+ if (vm->dmt_flags & VESA_DMT_HSYNC_HIGH)
+ fbmode->sync |= FB_SYNC_VERT_HIGH_ACT;
+ if (vm->data_flags & DISPLAY_FLAGS_INTERLACED)
+ fbmode->vmode |= FB_VMODE_INTERLACED;
+ if (vm->data_flags & DISPLAY_FLAGS_DOUBLESCAN)
+ fbmode->vmode |= FB_VMODE_DOUBLE;
+ fbmode->flag = 0;
+
+ htotal = vm->hactive + vm->hfront_porch + vm->hback_porch +
+ vm->hsync_len;
+ vtotal = vm->vactive + vm->vfront_porch + vm->vback_porch +
+ vm->vsync_len;
+ /* prevent division by zero */
+ if (htotal && vtotal) {
+ fbmode->refresh = vm->pixelclock / (htotal * vtotal);
+ /* a mode must have htotal and vtotal != 0 or it is invalid */
+ } else {
+ fbmode->refresh = 0;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fb_videomode_from_videomode);
+#endif
+
+#if IS_ENABLED(CONFIG_OF_VIDEOMODE)
+static inline void dump_fb_videomode(const struct fb_videomode *m)
+{
+ pr_debug("fb_videomode = %ux%u@%uHz (%ukHz) %u %u %u %u %u %u %u %u %u\n",
+ m->xres, m->yres, m->refresh, m->pixclock, m->left_margin,
+ m->right_margin, m->upper_margin, m->lower_margin,
+ m->hsync_len, m->vsync_len, m->sync, m->vmode, m->flag);
+}
+
+/**
+ * of_get_fb_videomode - get a fb_videomode from devicetree
+ * @np: device_node with the timing specification
+ * @fb: will be set to the return value
+ * @index: index into the list of display timings in devicetree
+ *
+ * DESCRIPTION:
+ * This function is expensive and should only be used, if only one mode is to be
+ * read from DT. To get multiple modes start with of_get_display_timings ond
+ * work with that instead.
+ */
+int of_get_fb_videomode(struct device_node *np, struct fb_videomode *fb,
+ int index)
+{
+ struct videomode vm;
+ int ret;
+
+ ret = of_get_videomode(np, &vm, index);
+ if (ret)
+ return ret;
+
+ fb_videomode_from_videomode(&vm, fb);
+
+ pr_debug("%s: got %dx%d display mode from %s\n",
+ of_node_full_name(np), vm.hactive, vm.vactive, np->name);
+ dump_fb_videomode(fb);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_get_fb_videomode);
+#endif
+
#else
int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
{
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index a55e366..ef476b0 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -177,6 +177,8 @@ static ssize_t store_modes(struct device *device,
if (i * sizeof(struct fb_videomode) != count)
return -EINVAL;
+ if (!lock_fb_info(fb_info))
+ return -ENODEV;
console_lock();
list_splice(&fb_info->modelist, &old_list);
fb_videomode_to_modelist((const struct fb_videomode *)buf, i,
@@ -188,6 +190,7 @@ static ssize_t store_modes(struct device *device,
fb_destroy_modelist(&old_list);
console_unlock();
+ unlock_fb_info(fb_info);
return 0;
}
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 14102a3..6d27447 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -893,7 +893,7 @@ static void ffb_init_fix(struct fb_info *info)
info->fix.accel = FB_ACCEL_SUN_CREATOR;
}
-static int __devinit ffb_probe(struct platform_device *op)
+static int ffb_probe(struct platform_device *op)
{
struct device_node *dp = op->dev.of_node;
struct ffb_fbc __iomem *fbc;
@@ -1022,7 +1022,7 @@ out_err:
return err;
}
-static int __devexit ffb_remove(struct platform_device *op)
+static int ffb_remove(struct platform_device *op)
{
struct fb_info *info = dev_get_drvdata(&op->dev);
struct ffb_par *par = info->par;
@@ -1058,7 +1058,7 @@ static struct platform_driver ffb_driver = {
.of_match_table = ffb_match,
},
.probe = ffb_probe,
- .remove = __devexit_p(ffb_remove),
+ .remove = ffb_remove,
};
static int __init ffb_init(void)
diff --git a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c
index d0533b7..c99c967 100644
--- a/drivers/video/fm2fb.c
+++ b/drivers/video/fm2fb.c
@@ -127,7 +127,7 @@
static volatile unsigned char *fm2fb_reg;
-static struct fb_fix_screeninfo fb_fix __devinitdata = {
+static struct fb_fix_screeninfo fb_fix = {
.smem_len = FRAMEMASTER_REG,
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_TRUECOLOR,
@@ -136,12 +136,12 @@ static struct fb_fix_screeninfo fb_fix __devinitdata = {
.accel = FB_ACCEL_NONE,
};
-static int fm2fb_mode __devinitdata = -1;
+static int fm2fb_mode = -1;
#define FM2FB_MODE_PAL 0
#define FM2FB_MODE_NTSC 1
-static struct fb_var_screeninfo fb_var_modes[] __devinitdata = {
+static struct fb_var_screeninfo fb_var_modes[] = {
{
/* 768 x 576, 32 bpp (PAL) */
768, 576, 768, 576, 0, 0, 32, 0,
@@ -211,10 +211,9 @@ static int fm2fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
* Initialisation
*/
-static int __devinit fm2fb_probe(struct zorro_dev *z,
- const struct zorro_device_id *id);
+static int fm2fb_probe(struct zorro_dev *z, const struct zorro_device_id *id);
-static struct zorro_device_id fm2fb_devices[] __devinitdata = {
+static struct zorro_device_id fm2fb_devices[] = {
{ ZORRO_PROD_BSC_FRAMEMASTER_II },
{ ZORRO_PROD_HELFRICH_RAINBOW_II },
{ 0 }
@@ -227,8 +226,7 @@ static struct zorro_driver fm2fb_driver = {
.probe = fm2fb_probe,
};
-static int __devinit fm2fb_probe(struct zorro_dev *z,
- const struct zorro_device_id *id)
+static int fm2fb_probe(struct zorro_dev *z, const struct zorro_device_id *id)
{
struct fb_info *info;
unsigned long *ptr;
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index ede9e55..41fbd94 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -55,7 +55,7 @@
* order if increasing resolution and frequency. The 320x240-60 mode is
* the initial AOI for the second and third planes.
*/
-static struct fb_videomode __devinitdata fsl_diu_mode_db[] = {
+static struct fb_videomode fsl_diu_mode_db[] = {
{
.refresh = 60,
.xres = 1024,
@@ -337,13 +337,11 @@ struct mfb_info {
int registered;
unsigned long pseudo_palette[16];
struct diu_ad *ad;
- int cursor_reset;
unsigned char g_alpha;
unsigned int count;
int x_aoi_d; /* aoi display x offset to physical screen */
int y_aoi_d; /* aoi display y offset to physical screen */
struct fsl_diu_data *parent;
- u8 *edid_data;
};
/**
@@ -378,6 +376,8 @@ struct fsl_diu_data {
struct diu_ad ad[NUM_AOIS] __aligned(8);
u8 gamma[256 * 3] __aligned(32);
u8 cursor[MAX_CURS * MAX_CURS * 2] __aligned(32);
+ uint8_t edid_data[EDID_LENGTH];
+ bool has_edid;
} __aligned(32);
/* Determine the DMA address of a member of the fsl_diu_data structure */
@@ -430,6 +430,22 @@ static struct mfb_info mfb_template[] = {
},
};
+#ifdef DEBUG
+static void __attribute__ ((unused)) fsl_diu_dump(struct diu __iomem *hw)
+{
+ mb();
+ pr_debug("DIU: desc=%08x,%08x,%08x, gamma=%08x pallete=%08x "
+ "cursor=%08x curs_pos=%08x diu_mode=%08x bgnd=%08x "
+ "disp_size=%08x hsyn_para=%08x vsyn_para=%08x syn_pol=%08x "
+ "thresholds=%08x int_mask=%08x plut=%08x\n",
+ hw->desc[0], hw->desc[1], hw->desc[2], hw->gamma,
+ hw->pallete, hw->cursor, hw->curs_pos, hw->diu_mode,
+ hw->bgnd, hw->disp_size, hw->hsyn_para, hw->vsyn_para,
+ hw->syn_pol, hw->thresholds, hw->int_mask, hw->plut);
+ rmb();
+}
+#endif
+
/**
* fsl_diu_name_to_port - convert a port name to a monitor port enum
*
@@ -481,8 +497,7 @@ static void fsl_diu_enable_panel(struct fb_info *info)
switch (mfbi->index) {
case PLANE0:
- if (hw->desc[0] != ad->paddr)
- wr_reg_wa(&hw->desc[0], ad->paddr);
+ wr_reg_wa(&hw->desc[0], ad->paddr);
break;
case PLANE1_AOI0:
cmfbi = &data->mfb[2];
@@ -534,8 +549,7 @@ static void fsl_diu_disable_panel(struct fb_info *info)
switch (mfbi->index) {
case PLANE0:
- if (hw->desc[0] != data->dummy_ad.paddr)
- wr_reg_wa(&hw->desc[0], data->dummy_ad.paddr);
+ wr_reg_wa(&hw->desc[0], 0);
break;
case PLANE1_AOI0:
cmfbi = &data->mfb[2];
@@ -792,7 +806,8 @@ static void update_lcdc(struct fb_info *info)
hw = data->diu_reg;
- diu_ops.set_monitor_port(data->monitor_port);
+ if (diu_ops.set_monitor_port)
+ diu_ops.set_monitor_port(data->monitor_port);
gamma_table_base = data->gamma;
/* Prep for DIU init - gamma table, cursor table */
@@ -811,12 +826,8 @@ static void update_lcdc(struct fb_info *info)
out_be32(&hw->gamma, DMA_ADDR(data, gamma));
out_be32(&hw->cursor, DMA_ADDR(data, cursor));
- out_be32(&hw->bgnd, 0x007F7F7F); /* BGND */
- out_be32(&hw->bgnd_wb, 0); /* BGND_WB */
- out_be32(&hw->disp_size, (var->yres << 16 | var->xres));
- /* DISP SIZE */
- out_be32(&hw->wb_size, 0); /* WB SIZE */
- out_be32(&hw->wb_mem_addr, 0); /* WB MEM ADDR */
+ out_be32(&hw->bgnd, 0x007F7F7F); /* Set background to grey */
+ out_be32(&hw->disp_size, (var->yres << 16) | var->xres);
/* Horizontal and vertical configuration register */
temp = var->left_margin << 22 | /* BP_H */
@@ -833,9 +844,20 @@ static void update_lcdc(struct fb_info *info)
diu_ops.set_pixel_clock(var->pixclock);
- out_be32(&hw->syn_pol, 0); /* SYNC SIGNALS POLARITY */
- out_be32(&hw->int_status, 0); /* INTERRUPT STATUS */
+#ifndef CONFIG_PPC_MPC512x
+ /*
+ * The PLUT register is defined differently on the MPC5121 than it
+ * is on other SOCs. Unfortunately, there's no documentation that
+ * explains how it's supposed to be programmed, so for now, we leave
+ * it at the default value on the MPC5121.
+ *
+ * For other SOCs, program it for the highest priority, which will
+ * reduce the chance of underrun. Technically, we should scale the
+ * priority to match the screen resolution, but doing that properly
+ * requires delicate fine-tuning for each use-case.
+ */
out_be32(&hw->plut, 0x01F5F666);
+#endif
/* Enable the DIU */
enable_lcdc(info);
@@ -922,7 +944,7 @@ static u32 fsl_diu_get_pixel_format(unsigned int bits_per_pixel)
#define PF_COMP_0_MASK 0x0000000F
#define PF_COMP_0_SHIFT 0
-#define MAKE_PF(alpha, red, blue, green, size, c0, c1, c2, c3) \
+#define MAKE_PF(alpha, red, green, blue, size, c0, c1, c2, c3) \
cpu_to_le32(PF_BYTE_F | (alpha << PF_ALPHA_C_SHIFT) | \
(blue << PF_BLUE_C_SHIFT) | (green << PF_GREEN_C_SHIFT) | \
(red << PF_RED_C_SHIFT) | (c3 << PF_COMP_3_SHIFT) | \
@@ -932,10 +954,10 @@ static u32 fsl_diu_get_pixel_format(unsigned int bits_per_pixel)
switch (bits_per_pixel) {
case 32:
/* 0x88883316 */
- return MAKE_PF(3, 2, 0, 1, 3, 8, 8, 8, 8);
+ return MAKE_PF(3, 2, 1, 0, 3, 8, 8, 8, 8);
case 24:
/* 0x88082219 */
- return MAKE_PF(4, 0, 1, 2, 2, 0, 8, 8, 8);
+ return MAKE_PF(4, 0, 1, 2, 2, 8, 8, 8, 0);
case 16:
/* 0x65053118 */
return MAKE_PF(4, 2, 1, 0, 1, 5, 6, 5, 0);
@@ -965,7 +987,6 @@ static int fsl_diu_set_par(struct fb_info *info)
hw = data->diu_reg;
set_fix(info);
- mfbi->cursor_reset = 1;
len = info->var.yres_virtual * info->fix.line_length;
/* Alloc & dealloc each time resolution/bpp change */
@@ -1107,6 +1128,12 @@ static int fsl_diu_ioctl(struct fb_info *info, unsigned int cmd,
if (!arg)
return -EINVAL;
+
+ dev_dbg(info->dev, "ioctl %08x (dir=%s%s type=%u nr=%u size=%u)\n", cmd,
+ _IOC_DIR(cmd) & _IOC_READ ? "R" : "",
+ _IOC_DIR(cmd) & _IOC_WRITE ? "W" : "",
+ _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
+
switch (cmd) {
case MFB_SET_PIXFMT_OLD:
dev_warn(info->dev,
@@ -1180,6 +1207,23 @@ static int fsl_diu_ioctl(struct fb_info *info, unsigned int cmd,
ad->ckmin_b = ck.blue_min;
}
break;
+#ifdef CONFIG_PPC_MPC512x
+ case MFB_SET_GAMMA: {
+ struct fsl_diu_data *data = mfbi->parent;
+
+ if (copy_from_user(data->gamma, buf, sizeof(data->gamma)))
+ return -EFAULT;
+ setbits32(&data->diu_reg->gamma, 0); /* Force table reload */
+ break;
+ }
+ case MFB_GET_GAMMA: {
+ struct fsl_diu_data *data = mfbi->parent;
+
+ if (copy_to_user(buf, data->gamma, sizeof(data->gamma)))
+ return -EFAULT;
+ break;
+ }
+#endif
default:
dev_err(info->dev, "unknown ioctl command (0x%08X)\n", cmd);
return -ENOIOCTLCMD;
@@ -1188,6 +1232,16 @@ static int fsl_diu_ioctl(struct fb_info *info, unsigned int cmd,
return 0;
}
+static inline void fsl_diu_enable_interrupts(struct fsl_diu_data *data)
+{
+ u32 int_mask = INT_UNDRUN; /* enable underrun detection */
+
+ if (IS_ENABLED(CONFIG_NOT_COHERENT_CACHE))
+ int_mask |= INT_VSYNC; /* enable vertical sync */
+
+ clrbits32(&data->diu_reg->int_mask, int_mask);
+}
+
/* turn on fb if count == 1
*/
static int fsl_diu_open(struct fb_info *info, int user)
@@ -1206,8 +1260,10 @@ static int fsl_diu_open(struct fb_info *info, int user)
res = fsl_diu_set_par(info);
if (res < 0)
mfbi->count--;
- else
+ else {
+ fsl_diu_enable_interrupts(mfbi->parent);
fsl_diu_enable_panel(info);
+ }
}
spin_unlock(&diu_lock);
@@ -1223,8 +1279,22 @@ static int fsl_diu_release(struct fb_info *info, int user)
spin_lock(&diu_lock);
mfbi->count--;
- if (mfbi->count == 0)
+ if (mfbi->count == 0) {
+ struct fsl_diu_data *data = mfbi->parent;
+ bool disable = true;
+ int i;
+
+ /* Disable interrupts only if all AOIs are closed */
+ for (i = 0; i < NUM_AOIS; i++) {
+ struct mfb_info *mi = data->fsl_diu_info[i].par;
+
+ if (mi->count)
+ disable = false;
+ }
+ if (disable)
+ out_be32(&data->diu_reg->int_mask, 0xffffffff);
fsl_diu_disable_panel(info);
+ }
spin_unlock(&diu_lock);
return res;
@@ -1244,10 +1314,11 @@ static struct fb_ops fsl_diu_ops = {
.fb_release = fsl_diu_release,
};
-static int __devinit install_fb(struct fb_info *info)
+static int install_fb(struct fb_info *info)
{
int rc;
struct mfb_info *mfbi = info->par;
+ struct fsl_diu_data *data = mfbi->parent;
const char *aoi_mode, *init_aoi_mode = "320x240";
struct fb_videomode *db = fsl_diu_mode_db;
unsigned int dbsize = ARRAY_SIZE(fsl_diu_mode_db);
@@ -1264,9 +1335,9 @@ static int __devinit install_fb(struct fb_info *info)
return rc;
if (mfbi->index == PLANE0) {
- if (mfbi->edid_data) {
+ if (data->has_edid) {
/* Now build modedb from EDID */
- fb_edid_to_monspecs(mfbi->edid_data, &info->monspecs);
+ fb_edid_to_monspecs(data->edid_data, &info->monspecs);
fb_videomode_to_modelist(info->monspecs.modedb,
info->monspecs.modedb_len,
&info->modelist);
@@ -1284,7 +1355,7 @@ static int __devinit install_fb(struct fb_info *info)
* For plane 0 we continue and look into
* driver's internal modedb.
*/
- if ((mfbi->index == PLANE0) && mfbi->edid_data)
+ if ((mfbi->index == PLANE0) && data->has_edid)
has_default_mode = 0;
else
return -EINVAL;
@@ -1348,9 +1419,6 @@ static void uninstall_fb(struct fb_info *info)
if (!mfbi->registered)
return;
- if (mfbi->index == PLANE0)
- kfree(mfbi->edid_data);
-
unregister_framebuffer(info);
unmap_video_memory(info);
if (&info->cmap)
@@ -1362,7 +1430,7 @@ static void uninstall_fb(struct fb_info *info)
static irqreturn_t fsl_diu_isr(int irq, void *dev_id)
{
struct diu __iomem *hw = dev_id;
- unsigned int status = in_be32(&hw->int_status);
+ uint32_t status = in_be32(&hw->int_status);
if (status) {
/* This is the workaround for underrun */
@@ -1387,40 +1455,6 @@ static irqreturn_t fsl_diu_isr(int irq, void *dev_id)
return IRQ_NONE;
}
-static int request_irq_local(struct fsl_diu_data *data)
-{
- struct diu __iomem *hw = data->diu_reg;
- u32 ints;
- int ret;
-
- /* Read to clear the status */
- in_be32(&hw->int_status);
-
- ret = request_irq(data->irq, fsl_diu_isr, 0, "fsl-diu-fb", hw);
- if (!ret) {
- ints = INT_PARERR | INT_LS_BF_VS;
-#if !defined(CONFIG_NOT_COHERENT_CACHE)
- ints |= INT_VSYNC;
-#endif
-
- /* Read to clear the status */
- in_be32(&hw->int_status);
- out_be32(&hw->int_mask, ints);
- }
-
- return ret;
-}
-
-static void free_irq_local(struct fsl_diu_data *data)
-{
- struct diu __iomem *hw = data->diu_reg;
-
- /* Disable all LCDC interrupt */
- out_be32(&hw->int_mask, 0x1f);
-
- free_irq(data->irq, NULL);
-}
-
#ifdef CONFIG_PM
/*
* Power management hooks. Note that we won't be called from IRQ context,
@@ -1491,13 +1525,13 @@ static ssize_t show_monitor(struct device *device,
return 0;
}
-static int __devinit fsl_diu_probe(struct platform_device *pdev)
+static int fsl_diu_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct mfb_info *mfbi;
struct fsl_diu_data *data;
- int diu_mode;
dma_addr_t dma_addr; /* DMA addr of fsl_diu_data struct */
+ const void *prop;
unsigned int i;
int ret;
@@ -1541,17 +1575,13 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
memcpy(mfbi, &mfb_template[i], sizeof(struct mfb_info));
mfbi->parent = data;
mfbi->ad = &data->ad[i];
+ }
- if (mfbi->index == PLANE0) {
- const u8 *prop;
- int len;
-
- /* Get EDID */
- prop = of_get_property(np, "edid", &len);
- if (prop && len == EDID_LENGTH)
- mfbi->edid_data = kmemdup(prop, EDID_LENGTH,
- GFP_KERNEL);
- }
+ /* Get the EDID data from the device tree, if present */
+ prop = of_get_property(np, "edid", &ret);
+ if (prop && ret == EDID_LENGTH) {
+ memcpy(data->edid_data, prop, EDID_LENGTH);
+ data->has_edid = true;
}
data->diu_reg = of_iomap(np, 0);
@@ -1561,10 +1591,6 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
goto error;
}
- diu_mode = in_be32(&data->diu_reg->diu_mode);
- if (diu_mode == MFB_MODE0)
- out_be32(&data->diu_reg->diu_mode, 0); /* disable DIU */
-
/* Get the IRQ of the DIU */
data->irq = irq_of_parse_and_map(np, 0);
@@ -1586,28 +1612,38 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
data->dummy_ad.paddr = DMA_ADDR(data, dummy_ad);
/*
- * Let DIU display splash screen if it was pre-initialized
- * by the bootloader, set dummy area descriptor otherwise.
+ * Let DIU continue to display splash screen if it was pre-initialized
+ * by the bootloader; otherwise, clear the display.
*/
- if (diu_mode == MFB_MODE0)
- out_be32(&data->diu_reg->desc[0], data->dummy_ad.paddr);
+ if (in_be32(&data->diu_reg->diu_mode) == MFB_MODE0)
+ out_be32(&data->diu_reg->desc[0], 0);
out_be32(&data->diu_reg->desc[1], data->dummy_ad.paddr);
out_be32(&data->diu_reg->desc[2], data->dummy_ad.paddr);
+ /*
+ * Older versions of U-Boot leave interrupts enabled, so disable
+ * all of them and clear the status register.
+ */
+ out_be32(&data->diu_reg->int_mask, 0xffffffff);
+ in_be32(&data->diu_reg->int_status);
+
+ ret = request_irq(data->irq, fsl_diu_isr, 0, "fsl-diu-fb",
+ data->diu_reg);
+ if (ret) {
+ dev_err(&pdev->dev, "could not claim irq\n");
+ goto error;
+ }
+
for (i = 0; i < NUM_AOIS; i++) {
ret = install_fb(&data->fsl_diu_info[i]);
if (ret) {
dev_err(&pdev->dev, "could not register fb %d\n", i);
+ free_irq(data->irq, data->diu_reg);
goto error;
}
}
- if (request_irq_local(data)) {
- dev_err(&pdev->dev, "could not claim irq\n");
- goto error;
- }
-
sysfs_attr_init(&data->dev_attr.attr);
data->dev_attr.attr.name = "monitor";
data->dev_attr.attr.mode = S_IRUGO|S_IWUSR;
@@ -1638,7 +1674,8 @@ static int fsl_diu_remove(struct platform_device *pdev)
data = dev_get_drvdata(&pdev->dev);
disable_lcdc(&data->fsl_diu_info[0]);
- free_irq_local(data);
+
+ free_irq(data->irq, data->diu_reg);
for (i = 0; i < NUM_AOIS; i++)
uninstall_fb(&data->fsl_diu_info[i]);
@@ -1741,6 +1778,9 @@ static int __init fsl_diu_init(void)
coherence_data_size = be32_to_cpup(prop) * 13;
coherence_data_size /= 8;
+ pr_debug("fsl-diu-fb: coherence data size is %zu bytes\n",
+ coherence_data_size);
+
prop = of_get_property(np, "d-cache-line-size", NULL);
if (prop == NULL) {
pr_err("fsl-diu-fb: missing 'd-cache-line-size' property' "
@@ -1750,10 +1790,17 @@ static int __init fsl_diu_init(void)
}
d_cache_line_size = be32_to_cpup(prop);
+ pr_debug("fsl-diu-fb: cache lines size is %u bytes\n",
+ d_cache_line_size);
+
of_node_put(np);
coherence_data = vmalloc(coherence_data_size);
- if (!coherence_data)
+ if (!coherence_data) {
+ pr_err("fsl-diu-fb: could not allocate coherence data "
+ "(size=%zu)\n", coherence_data_size);
return -ENOMEM;
+ }
+
#endif
ret = platform_driver_register(&fsl_diu_driver);
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index 3dad319..bda5e39 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -91,10 +91,10 @@ static uint32_t pseudo_palette[16];
static uint32_t gbe_cmap[256];
static int gbe_turned_on; /* 0 turned off, 1 turned on */
-static char *mode_option __devinitdata = NULL;
+static char *mode_option = NULL;
/* default CRT mode */
-static struct fb_var_screeninfo default_var_CRT __devinitdata = {
+static struct fb_var_screeninfo default_var_CRT = {
/* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
.xres = 640,
.yres = 480,
@@ -125,7 +125,7 @@ static struct fb_var_screeninfo default_var_CRT __devinitdata = {
};
/* default LCD mode */
-static struct fb_var_screeninfo default_var_LCD __devinitdata = {
+static struct fb_var_screeninfo default_var_LCD = {
/* 1600x1024, 8 bpp */
.xres = 1600,
.yres = 1024,
@@ -157,7 +157,7 @@ static struct fb_var_screeninfo default_var_LCD __devinitdata = {
/* default modedb mode */
/* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
-static struct fb_videomode default_mode_CRT __devinitdata = {
+static struct fb_videomode default_mode_CRT = {
.refresh = 60,
.xres = 640,
.yres = 480,
@@ -172,7 +172,7 @@ static struct fb_videomode default_mode_CRT __devinitdata = {
.vmode = FB_VMODE_NONINTERLACED,
};
/* 1600x1024 SGI flatpanel 1600sw */
-static struct fb_videomode default_mode_LCD __devinitdata = {
+static struct fb_videomode default_mode_LCD = {
/* 1600x1024, 8 bpp */
.xres = 1600,
.yres = 1024,
@@ -186,8 +186,8 @@ static struct fb_videomode default_mode_LCD __devinitdata = {
.vmode = FB_VMODE_NONINTERLACED,
};
-static struct fb_videomode *default_mode __devinitdata = &default_mode_CRT;
-static struct fb_var_screeninfo *default_var __devinitdata = &default_var_CRT;
+static struct fb_videomode *default_mode = &default_mode_CRT;
+static struct fb_var_screeninfo *default_var = &default_var_CRT;
static int flat_panel_enabled = 0;
@@ -1082,7 +1082,7 @@ static ssize_t gbefb_show_rev(struct device *device, struct device_attribute *at
static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL);
-static void __devexit gbefb_remove_sysfs(struct device *dev)
+static void gbefb_remove_sysfs(struct device *dev)
{
device_remove_file(dev, &dev_attr_size);
device_remove_file(dev, &dev_attr_revision);
@@ -1098,7 +1098,7 @@ static void gbefb_create_sysfs(struct device *dev)
* Initialization
*/
-static int __devinit gbefb_setup(char *options)
+static int gbefb_setup(char *options)
{
char *this_opt;
@@ -1129,7 +1129,7 @@ static int __devinit gbefb_setup(char *options)
return 0;
}
-static int __devinit gbefb_probe(struct platform_device *p_dev)
+static int gbefb_probe(struct platform_device *p_dev)
{
int i, ret = 0;
struct fb_info *info;
@@ -1254,7 +1254,7 @@ out_release_framebuffer:
return ret;
}
-static int __devexit gbefb_remove(struct platform_device* p_dev)
+static int gbefb_remove(struct platform_device* p_dev)
{
struct fb_info *info = platform_get_drvdata(p_dev);
@@ -1273,7 +1273,7 @@ static int __devexit gbefb_remove(struct platform_device* p_dev)
static struct platform_driver gbefb_driver = {
.probe = gbefb_probe,
- .remove = __devexit_p(gbefb_remove),
+ .remove = gbefb_remove,
.driver = {
.name = "gbefb",
},
diff --git a/drivers/video/geode/Kconfig b/drivers/video/geode/Kconfig
index c5d8ba4..21e351a 100644
--- a/drivers/video/geode/Kconfig
+++ b/drivers/video/geode/Kconfig
@@ -2,14 +2,14 @@
# Geode family framebuffer configuration
#
config FB_GEODE
- bool "AMD Geode family framebuffer support (EXPERIMENTAL)"
- depends on FB && PCI && EXPERIMENTAL && X86
+ bool "AMD Geode family framebuffer support"
+ depends on FB && PCI && X86
---help---
Say 'Y' here to allow you to select framebuffer drivers for
the AMD Geode family of processors.
config FB_GEODE_LX
- tristate "AMD Geode LX framebuffer support (EXPERIMENTAL)"
+ tristate "AMD Geode LX framebuffer support"
depends on FB && FB_GEODE
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -24,8 +24,8 @@ config FB_GEODE_LX
If unsure, say N.
config FB_GEODE_GX
- tristate "AMD Geode GX framebuffer support (EXPERIMENTAL)"
- depends on FB && FB_GEODE && EXPERIMENTAL
+ tristate "AMD Geode GX framebuffer support"
+ depends on FB && FB_GEODE
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -39,8 +39,8 @@ config FB_GEODE_GX
If unsure, say N.
config FB_GEODE_GX1
- tristate "AMD Geode GX1 framebuffer support (EXPERIMENTAL)"
- depends on FB && FB_GEODE && EXPERIMENTAL
+ tristate "AMD Geode GX1 framebuffer support"
+ depends on FB && FB_GEODE
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c
index 265c5ed..ebbaada 100644
--- a/drivers/video/geode/gx1fb_core.c
+++ b/drivers/video/geode/gx1fb_core.c
@@ -29,7 +29,7 @@ static int crt_option = 1;
static char panel_option[32] = "";
/* Modes relevant to the GX1 (taken from modedb.c) */
-static const struct fb_videomode __devinitconst gx1_modedb[] = {
+static const struct fb_videomode gx1_modedb[] = {
/* 640x480-60 VESA */
{ NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2,
0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
@@ -195,7 +195,7 @@ static int gx1fb_blank(int blank_mode, struct fb_info *info)
return par->vid_ops->blank_display(info, blank_mode);
}
-static int __devinit gx1fb_map_video_memory(struct fb_info *info, struct pci_dev *dev)
+static int gx1fb_map_video_memory(struct fb_info *info, struct pci_dev *dev)
{
struct geodefb_par *par = info->par;
unsigned gx_base;
@@ -268,7 +268,7 @@ static struct fb_ops gx1fb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static struct fb_info * __devinit gx1fb_init_fbinfo(struct device *dev)
+static struct fb_info *gx1fb_init_fbinfo(struct device *dev)
{
struct geodefb_par *par;
struct fb_info *info;
@@ -318,7 +318,7 @@ static struct fb_info * __devinit gx1fb_init_fbinfo(struct device *dev)
return info;
}
-static int __devinit gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+static int gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct geodefb_par *par;
struct fb_info *info;
@@ -382,7 +382,7 @@ static int __devinit gx1fb_probe(struct pci_dev *pdev, const struct pci_device_i
return ret;
}
-static void __devexit gx1fb_remove(struct pci_dev *pdev)
+static void gx1fb_remove(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct geodefb_par *par = info->par;
@@ -441,7 +441,7 @@ static struct pci_driver gx1fb_driver = {
.name = "gx1fb",
.id_table = gx1fb_id_table,
.probe = gx1fb_probe,
- .remove = __devexit_p(gx1fb_remove),
+ .remove = gx1fb_remove,
};
static int __init gx1fb_init(void)
@@ -456,7 +456,7 @@ static int __init gx1fb_init(void)
return pci_register_driver(&gx1fb_driver);
}
-static void __devexit gx1fb_cleanup(void)
+static void gx1fb_cleanup(void)
{
pci_unregister_driver(&gx1fb_driver);
}
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c
index b4f19db..19f0c1ad 100644
--- a/drivers/video/geode/gxfb_core.c
+++ b/drivers/video/geode/gxfb_core.c
@@ -40,7 +40,7 @@ static int vram;
static int vt_switch;
/* Modes relevant to the GX (taken from modedb.c) */
-static struct fb_videomode gx_modedb[] __devinitdata = {
+static struct fb_videomode gx_modedb[] = {
/* 640x480-60 VESA */
{ NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2,
0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
@@ -110,15 +110,14 @@ static struct fb_videomode gx_modedb[] __devinitdata = {
#ifdef CONFIG_OLPC
#include <asm/olpc.h>
-static struct fb_videomode gx_dcon_modedb[] __devinitdata = {
+static struct fb_videomode gx_dcon_modedb[] = {
/* The only mode the DCON has is 1200x900 */
{ NULL, 50, 1200, 900, 17460, 24, 8, 4, 5, 8, 3,
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
FB_VMODE_NONINTERLACED, 0 }
};
-static void __devinit get_modedb(struct fb_videomode **modedb,
- unsigned int *size)
+static void get_modedb(struct fb_videomode **modedb, unsigned int *size)
{
if (olpc_has_dcon()) {
*modedb = (struct fb_videomode *) gx_dcon_modedb;
@@ -130,8 +129,7 @@ static void __devinit get_modedb(struct fb_videomode **modedb,
}
#else
-static void __devinit get_modedb(struct fb_videomode **modedb,
- unsigned int *size)
+static void get_modedb(struct fb_videomode **modedb, unsigned int *size)
{
*modedb = (struct fb_videomode *) gx_modedb;
*size = ARRAY_SIZE(gx_modedb);
@@ -228,8 +226,7 @@ static int gxfb_blank(int blank_mode, struct fb_info *info)
return gx_blank_display(info, blank_mode);
}
-static int __devinit gxfb_map_video_memory(struct fb_info *info,
- struct pci_dev *dev)
+static int gxfb_map_video_memory(struct fb_info *info, struct pci_dev *dev)
{
struct gxfb_par *par = info->par;
int ret;
@@ -293,7 +290,7 @@ static struct fb_ops gxfb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static struct fb_info *__devinit gxfb_init_fbinfo(struct device *dev)
+static struct fb_info *gxfb_init_fbinfo(struct device *dev)
{
struct gxfb_par *par;
struct fb_info *info;
@@ -374,8 +371,7 @@ static int gxfb_resume(struct pci_dev *pdev)
}
#endif
-static int __devinit gxfb_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
+static int gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct gxfb_par *par;
struct fb_info *info;
@@ -455,7 +451,7 @@ static int __devinit gxfb_probe(struct pci_dev *pdev,
return ret;
}
-static void __devexit gxfb_remove(struct pci_dev *pdev)
+static void gxfb_remove(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct gxfb_par *par = info->par;
diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/geode/lxfb_core.c
index 416851c..4dd7b55 100644
--- a/drivers/video/geode/lxfb_core.c
+++ b/drivers/video/geode/lxfb_core.c
@@ -35,7 +35,7 @@ static int vt_switch;
* we try to make it something sane - 640x480-60 is sane
*/
-static struct fb_videomode geode_modedb[] __devinitdata = {
+static struct fb_videomode geode_modedb[] = {
/* 640x480-60 */
{ NULL, 60, 640, 480, 39682, 48, 8, 25, 2, 88, 2,
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
@@ -219,15 +219,14 @@ static struct fb_videomode geode_modedb[] __devinitdata = {
#ifdef CONFIG_OLPC
#include <asm/olpc.h>
-static struct fb_videomode olpc_dcon_modedb[] __devinitdata = {
+static struct fb_videomode olpc_dcon_modedb[] = {
/* The only mode the DCON has is 1200x900 */
{ NULL, 50, 1200, 900, 17460, 24, 8, 4, 5, 8, 3,
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
FB_VMODE_NONINTERLACED, 0 }
};
-static void __devinit get_modedb(struct fb_videomode **modedb,
- unsigned int *size)
+static void get_modedb(struct fb_videomode **modedb, unsigned int *size)
{
if (olpc_has_dcon()) {
*modedb = (struct fb_videomode *) olpc_dcon_modedb;
@@ -239,8 +238,7 @@ static void __devinit get_modedb(struct fb_videomode **modedb,
}
#else
-static void __devinit get_modedb(struct fb_videomode **modedb,
- unsigned int *size)
+static void get_modedb(struct fb_videomode **modedb, unsigned int *size)
{
*modedb = (struct fb_videomode *) geode_modedb;
*size = ARRAY_SIZE(geode_modedb);
@@ -336,8 +334,7 @@ static int lxfb_blank(int blank_mode, struct fb_info *info)
}
-static int __devinit lxfb_map_video_memory(struct fb_info *info,
- struct pci_dev *dev)
+static int lxfb_map_video_memory(struct fb_info *info, struct pci_dev *dev)
{
struct lxfb_par *par = info->par;
int ret;
@@ -414,7 +411,7 @@ static struct fb_ops lxfb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static struct fb_info * __devinit lxfb_init_fbinfo(struct device *dev)
+static struct fb_info *lxfb_init_fbinfo(struct device *dev)
{
struct lxfb_par *par;
struct fb_info *info;
@@ -498,8 +495,7 @@ static int lxfb_resume(struct pci_dev *pdev)
#define lxfb_resume NULL
#endif
-static int __devinit lxfb_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
+static int lxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct lxfb_par *par;
struct fb_info *info;
@@ -590,7 +586,7 @@ err:
return ret;
}
-static void __devexit lxfb_remove(struct pci_dev *pdev)
+static void lxfb_remove(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct lxfb_par *par = info->par;
diff --git a/drivers/video/goldfishfb.c b/drivers/video/goldfishfb.c
new file mode 100644
index 0000000..489abb3
--- /dev/null
+++ b/drivers/video/goldfishfb.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (C) 2012 Intel, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+enum {
+ FB_GET_WIDTH = 0x00,
+ FB_GET_HEIGHT = 0x04,
+ FB_INT_STATUS = 0x08,
+ FB_INT_ENABLE = 0x0c,
+ FB_SET_BASE = 0x10,
+ FB_SET_ROTATION = 0x14,
+ FB_SET_BLANK = 0x18,
+ FB_GET_PHYS_WIDTH = 0x1c,
+ FB_GET_PHYS_HEIGHT = 0x20,
+
+ FB_INT_VSYNC = 1U << 0,
+ FB_INT_BASE_UPDATE_DONE = 1U << 1
+};
+
+struct goldfish_fb {
+ void __iomem *reg_base;
+ int irq;
+ spinlock_t lock;
+ wait_queue_head_t wait;
+ int base_update_count;
+ int rotation;
+ struct fb_info fb;
+ u32 cmap[16];
+};
+
+static irqreturn_t goldfish_fb_interrupt(int irq, void *dev_id)
+{
+ unsigned long irq_flags;
+ struct goldfish_fb *fb = dev_id;
+ u32 status;
+
+ spin_lock_irqsave(&fb->lock, irq_flags);
+ status = readl(fb->reg_base + FB_INT_STATUS);
+ if (status & FB_INT_BASE_UPDATE_DONE) {
+ fb->base_update_count++;
+ wake_up(&fb->wait);
+ }
+ spin_unlock_irqrestore(&fb->lock, irq_flags);
+ return status ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static inline u32 convert_bitfield(int val, struct fb_bitfield *bf)
+{
+ unsigned int mask = (1 << bf->length) - 1;
+
+ return (val >> (16 - bf->length) & mask) << bf->offset;
+}
+
+static int
+goldfish_fb_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
+ unsigned int blue, unsigned int transp, struct fb_info *info)
+{
+ struct goldfish_fb *fb = container_of(info, struct goldfish_fb, fb);
+
+ if (regno < 16) {
+ fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) |
+ convert_bitfield(blue, &fb->fb.var.blue) |
+ convert_bitfield(green, &fb->fb.var.green) |
+ convert_bitfield(red, &fb->fb.var.red);
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+static int goldfish_fb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ if ((var->rotate & 1) != (info->var.rotate & 1)) {
+ if ((var->xres != info->var.yres) ||
+ (var->yres != info->var.xres) ||
+ (var->xres_virtual != info->var.yres) ||
+ (var->yres_virtual > info->var.xres * 2) ||
+ (var->yres_virtual < info->var.xres)) {
+ return -EINVAL;
+ }
+ } else {
+ if ((var->xres != info->var.xres) ||
+ (var->yres != info->var.yres) ||
+ (var->xres_virtual != info->var.xres) ||
+ (var->yres_virtual > info->var.yres * 2) ||
+ (var->yres_virtual < info->var.yres)) {
+ return -EINVAL;
+ }
+ }
+ if ((var->xoffset != info->var.xoffset) ||
+ (var->bits_per_pixel != info->var.bits_per_pixel) ||
+ (var->grayscale != info->var.grayscale)) {
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int goldfish_fb_set_par(struct fb_info *info)
+{
+ struct goldfish_fb *fb = container_of(info, struct goldfish_fb, fb);
+ if (fb->rotation != fb->fb.var.rotate) {
+ info->fix.line_length = info->var.xres * 2;
+ fb->rotation = fb->fb.var.rotate;
+ writel(fb->rotation, fb->reg_base + FB_SET_ROTATION);
+ }
+ return 0;
+}
+
+
+static int goldfish_fb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ unsigned long irq_flags;
+ int base_update_count;
+ struct goldfish_fb *fb = container_of(info, struct goldfish_fb, fb);
+
+ spin_lock_irqsave(&fb->lock, irq_flags);
+ base_update_count = fb->base_update_count;
+ writel(fb->fb.fix.smem_start + fb->fb.var.xres * 2 * var->yoffset,
+ fb->reg_base + FB_SET_BASE);
+ spin_unlock_irqrestore(&fb->lock, irq_flags);
+ wait_event_timeout(fb->wait,
+ fb->base_update_count != base_update_count, HZ / 15);
+ if (fb->base_update_count == base_update_count)
+ pr_err("goldfish_fb_pan_display: timeout wating for base update\n");
+ return 0;
+}
+
+static int goldfish_fb_blank(int blank, struct fb_info *info)
+{
+ struct goldfish_fb *fb = container_of(info, struct goldfish_fb, fb);
+ switch (blank) {
+ case FB_BLANK_NORMAL:
+ writel(1, fb->reg_base + FB_SET_BLANK);
+ break;
+ case FB_BLANK_UNBLANK:
+ writel(0, fb->reg_base + FB_SET_BLANK);
+ break;
+ }
+ return 0;
+}
+
+static struct fb_ops goldfish_fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = goldfish_fb_check_var,
+ .fb_set_par = goldfish_fb_set_par,
+ .fb_setcolreg = goldfish_fb_setcolreg,
+ .fb_pan_display = goldfish_fb_pan_display,
+ .fb_blank = goldfish_fb_blank,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+
+static int goldfish_fb_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct resource *r;
+ struct goldfish_fb *fb;
+ size_t framesize;
+ u32 width, height;
+ dma_addr_t fbpaddr;
+
+ fb = kzalloc(sizeof(*fb), GFP_KERNEL);
+ if (fb == NULL) {
+ ret = -ENOMEM;
+ goto err_fb_alloc_failed;
+ }
+ spin_lock_init(&fb->lock);
+ init_waitqueue_head(&fb->wait);
+ platform_set_drvdata(pdev, fb);
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (r == NULL) {
+ ret = -ENODEV;
+ goto err_no_io_base;
+ }
+ fb->reg_base = ioremap(r->start, PAGE_SIZE);
+ if (fb->reg_base == NULL) {
+ ret = -ENOMEM;
+ goto err_no_io_base;
+ }
+
+ fb->irq = platform_get_irq(pdev, 0);
+ if (fb->irq <= 0) {
+ ret = -ENODEV;
+ goto err_no_irq;
+ }
+
+ width = readl(fb->reg_base + FB_GET_WIDTH);
+ height = readl(fb->reg_base + FB_GET_HEIGHT);
+
+ fb->fb.fbops = &goldfish_fb_ops;
+ fb->fb.flags = FBINFO_FLAG_DEFAULT;
+ fb->fb.pseudo_palette = fb->cmap;
+ fb->fb.fix.type = FB_TYPE_PACKED_PIXELS;
+ fb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
+ fb->fb.fix.line_length = width * 2;
+ fb->fb.fix.accel = FB_ACCEL_NONE;
+ fb->fb.fix.ypanstep = 1;
+
+ fb->fb.var.xres = width;
+ fb->fb.var.yres = height;
+ fb->fb.var.xres_virtual = width;
+ fb->fb.var.yres_virtual = height * 2;
+ fb->fb.var.bits_per_pixel = 16;
+ fb->fb.var.activate = FB_ACTIVATE_NOW;
+ fb->fb.var.height = readl(fb->reg_base + FB_GET_PHYS_HEIGHT);
+ fb->fb.var.width = readl(fb->reg_base + FB_GET_PHYS_WIDTH);
+ fb->fb.var.pixclock = 10000;
+
+ fb->fb.var.red.offset = 11;
+ fb->fb.var.red.length = 5;
+ fb->fb.var.green.offset = 5;
+ fb->fb.var.green.length = 6;
+ fb->fb.var.blue.offset = 0;
+ fb->fb.var.blue.length = 5;
+
+ framesize = width * height * 2 * 2;
+ fb->fb.screen_base = (char __force __iomem *)dma_alloc_coherent(
+ &pdev->dev, framesize,
+ &fbpaddr, GFP_KERNEL);
+ pr_debug("allocating frame buffer %d * %d, got %p\n",
+ width, height, fb->fb.screen_base);
+ if (fb->fb.screen_base == NULL) {
+ ret = -ENOMEM;
+ goto err_alloc_screen_base_failed;
+ }
+ fb->fb.fix.smem_start = fbpaddr;
+ fb->fb.fix.smem_len = framesize;
+
+ ret = fb_set_var(&fb->fb, &fb->fb.var);
+ if (ret)
+ goto err_fb_set_var_failed;
+
+ ret = request_irq(fb->irq, goldfish_fb_interrupt, IRQF_SHARED,
+ pdev->name, fb);
+ if (ret)
+ goto err_request_irq_failed;
+
+ writel(FB_INT_BASE_UPDATE_DONE, fb->reg_base + FB_INT_ENABLE);
+ goldfish_fb_pan_display(&fb->fb.var, &fb->fb); /* updates base */
+
+ ret = register_framebuffer(&fb->fb);
+ if (ret)
+ goto err_register_framebuffer_failed;
+ return 0;
+
+err_register_framebuffer_failed:
+ free_irq(fb->irq, fb);
+err_request_irq_failed:
+err_fb_set_var_failed:
+ dma_free_coherent(&pdev->dev, framesize,
+ (void *)fb->fb.screen_base,
+ fb->fb.fix.smem_start);
+err_alloc_screen_base_failed:
+err_no_irq:
+ iounmap(fb->reg_base);
+err_no_io_base:
+ kfree(fb);
+err_fb_alloc_failed:
+ return ret;
+}
+
+static int goldfish_fb_remove(struct platform_device *pdev)
+{
+ size_t framesize;
+ struct goldfish_fb *fb = platform_get_drvdata(pdev);
+
+ framesize = fb->fb.var.xres_virtual * fb->fb.var.yres_virtual * 2;
+ unregister_framebuffer(&fb->fb);
+ free_irq(fb->irq, fb);
+
+ dma_free_coherent(&pdev->dev, framesize, (void *)fb->fb.screen_base,
+ fb->fb.fix.smem_start);
+ iounmap(fb->reg_base);
+ return 0;
+}
+
+
+static struct platform_driver goldfish_fb_driver = {
+ .probe = goldfish_fb_probe,
+ .remove = goldfish_fb_remove,
+ .driver = {
+ .name = "goldfish_fb"
+ }
+};
+
+module_platform_driver(goldfish_fb_driver);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/grvga.c b/drivers/video/grvga.c
index 5245f9a..861109e 100644
--- a/drivers/video/grvga.c
+++ b/drivers/video/grvga.c
@@ -70,7 +70,7 @@ static const struct fb_videomode grvga_modedb[] = {
}
};
-static struct fb_fix_screeninfo grvga_fix __devinitdata = {
+static struct fb_fix_screeninfo grvga_fix = {
.id = "AG SVGACTRL",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
@@ -267,8 +267,8 @@ static struct fb_ops grvga_ops = {
.fb_imageblit = cfb_imageblit
};
-static int __devinit grvga_parse_custom(char *options,
- struct fb_var_screeninfo *screendata)
+static int grvga_parse_custom(char *options,
+ struct fb_var_screeninfo *screendata)
{
char *this_opt;
int count = 0;
@@ -329,7 +329,7 @@ static int __devinit grvga_parse_custom(char *options,
return 0;
}
-static int __devinit grvga_probe(struct platform_device *dev)
+static int grvga_probe(struct platform_device *dev)
{
struct fb_info *info;
int retval = -ENOMEM;
@@ -512,7 +512,7 @@ free_fb:
return retval;
}
-static int __devexit grvga_remove(struct platform_device *device)
+static int grvga_remove(struct platform_device *device)
{
struct fb_info *info = dev_get_drvdata(&device->dev);
struct grvga_par *par = info->par;
@@ -554,7 +554,7 @@ static struct platform_driver grvga_driver = {
.of_match_table = svgactrl_of_match,
},
.probe = grvga_probe,
- .remove = __devexit_p(grvga_remove),
+ .remove = grvga_remove,
};
diff --git a/drivers/video/gxt4500.c b/drivers/video/gxt4500.c
index 0e9afa4..c35663f 100644
--- a/drivers/video/gxt4500.c
+++ b/drivers/video/gxt4500.c
@@ -1,5 +1,6 @@
/*
- * Frame buffer device for IBM GXT4500P and GXT6000P display adaptors
+ * Frame buffer device for IBM GXT4500P/6500P and GXT4000P/6000P
+ * display adaptors
*
* Copyright (C) 2006 Paul Mackerras, IBM Corp. <paulus@samba.org>
*/
@@ -14,6 +15,8 @@
#include <linux/string.h>
#define PCI_DEVICE_ID_IBM_GXT4500P 0x21c
+#define PCI_DEVICE_ID_IBM_GXT6500P 0x21b
+#define PCI_DEVICE_ID_IBM_GXT4000P 0x16e
#define PCI_DEVICE_ID_IBM_GXT6000P 0x170
/* GXT4500P registers */
@@ -156,7 +159,7 @@ struct gxt4500_par {
static char *mode_option;
/* default mode: 1280x1024 @ 60 Hz, 8 bpp */
-static const struct fb_videomode defaultmode __devinitconst = {
+static const struct fb_videomode defaultmode = {
.refresh = 60,
.xres = 1280,
.yres = 1024,
@@ -173,6 +176,8 @@ static const struct fb_videomode defaultmode __devinitconst = {
/* List of supported cards */
enum gxt_cards {
GXT4500P,
+ GXT6500P,
+ GXT4000P,
GXT6000P
};
@@ -182,6 +187,8 @@ static const struct cardinfo {
const char *cardname;
} cardinfo[] = {
[GXT4500P] = { .refclk_ps = 9259, .cardname = "IBM GXT4500P" },
+ [GXT6500P] = { .refclk_ps = 9259, .cardname = "IBM GXT6500P" },
+ [GXT4000P] = { .refclk_ps = 40000, .cardname = "IBM GXT4000P" },
[GXT6000P] = { .refclk_ps = 40000, .cardname = "IBM GXT6000P" },
};
@@ -581,7 +588,7 @@ static int gxt4500_blank(int blank, struct fb_info *info)
return 0;
}
-static const struct fb_fix_screeninfo gxt4500_fix __devinitconst = {
+static const struct fb_fix_screeninfo gxt4500_fix = {
.id = "IBM GXT4500P",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
@@ -603,8 +610,7 @@ static struct fb_ops gxt4500_ops = {
};
/* PCI functions */
-static int __devinit gxt4500_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int gxt4500_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int err;
unsigned long reg_phys, fb_phys;
@@ -713,7 +719,7 @@ static int __devinit gxt4500_probe(struct pci_dev *pdev,
return -ENODEV;
}
-static void __devexit gxt4500_remove(struct pci_dev *pdev)
+static void gxt4500_remove(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct gxt4500_par *par;
@@ -736,6 +742,10 @@ static void __devexit gxt4500_remove(struct pci_dev *pdev)
static const struct pci_device_id gxt4500_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_GXT4500P),
.driver_data = GXT4500P },
+ { PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_GXT6500P),
+ .driver_data = GXT6500P },
+ { PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_GXT4000P),
+ .driver_data = GXT4000P },
{ PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_GXT6000P),
.driver_data = GXT6000P },
{ 0 }
@@ -747,10 +757,10 @@ static struct pci_driver gxt4500_driver = {
.name = "gxt4500",
.id_table = gxt4500_pci_tbl,
.probe = gxt4500_probe,
- .remove = __devexit_p(gxt4500_remove),
+ .remove = gxt4500_remove,
};
-static int __devinit gxt4500_init(void)
+static int gxt4500_init(void)
{
#ifndef MODULE
if (fb_get_options("gxt4500", &mode_option))
@@ -768,7 +778,7 @@ static void __exit gxt4500_exit(void)
module_exit(gxt4500_exit);
MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
-MODULE_DESCRIPTION("FBDev driver for IBM GXT4500P/6000P");
+MODULE_DESCRIPTION("FBDev driver for IBM GXT4500P/6500P and GXT4000P/6000P");
MODULE_LICENSE("GPL");
module_param(mode_option, charp, 0);
MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\"");
diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
new file mode 100644
index 0000000..ab23c9b
--- /dev/null
+++ b/drivers/video/hdmi.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2012 Avionic Design GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/hdmi.h>
+#include <linux/string.h>
+
+static void hdmi_infoframe_checksum(void *buffer, size_t size)
+{
+ u8 *ptr = buffer;
+ u8 csum = 0;
+ size_t i;
+
+ /* compute checksum */
+ for (i = 0; i < size; i++)
+ csum += ptr[i];
+
+ ptr[3] = 256 - csum;
+}
+
+/**
+ * hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe
+ * @frame: HDMI AVI infoframe
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
+{
+ memset(frame, 0, sizeof(*frame));
+
+ frame->type = HDMI_INFOFRAME_TYPE_AVI;
+ frame->version = 2;
+ frame->length = 13;
+
+ return 0;
+}
+EXPORT_SYMBOL(hdmi_avi_infoframe_init);
+
+/**
+ * hdmi_avi_infoframe_pack() - write HDMI AVI infoframe to binary buffer
+ * @frame: HDMI AVI infoframe
+ * @buffer: destination buffer
+ * @size: size of buffer
+ *
+ * Packs the information contained in the @frame structure into a binary
+ * representation that can be written into the corresponding controller
+ * registers. Also computes the checksum as required by section 5.3.5 of
+ * the HDMI 1.4 specification.
+ *
+ * Returns the number of bytes packed into the binary buffer or a negative
+ * error code on failure.
+ */
+ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
+ size_t size)
+{
+ u8 *ptr = buffer;
+ size_t length;
+
+ length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
+
+ if (size < length)
+ return -ENOSPC;
+
+ memset(buffer, 0, length);
+
+ ptr[0] = frame->type;
+ ptr[1] = frame->version;
+ ptr[2] = frame->length;
+ ptr[3] = 0; /* checksum */
+
+ /* start infoframe payload */
+ ptr += HDMI_INFOFRAME_HEADER_SIZE;
+
+ ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3);
+
+ if (frame->active_info_valid)
+ ptr[0] |= BIT(4);
+
+ if (frame->horizontal_bar_valid)
+ ptr[0] |= BIT(3);
+
+ if (frame->vertical_bar_valid)
+ ptr[0] |= BIT(2);
+
+ ptr[1] = ((frame->colorimetry & 0x3) << 6) |
+ ((frame->picture_aspect & 0x3) << 4) |
+ (frame->active_aspect & 0xf);
+
+ ptr[2] = ((frame->extended_colorimetry & 0x7) << 4) |
+ ((frame->quantization_range & 0x3) << 2) |
+ (frame->nups & 0x3);
+
+ if (frame->itc)
+ ptr[2] |= BIT(7);
+
+ ptr[3] = frame->video_code & 0x7f;
+
+ ptr[4] = ((frame->ycc_quantization_range & 0x3) << 6) |
+ ((frame->content_type & 0x3) << 4) |
+ (frame->pixel_repeat & 0xf);
+
+ ptr[5] = frame->top_bar & 0xff;
+ ptr[6] = (frame->top_bar >> 8) & 0xff;
+ ptr[7] = frame->bottom_bar & 0xff;
+ ptr[8] = (frame->bottom_bar >> 8) & 0xff;
+ ptr[9] = frame->left_bar & 0xff;
+ ptr[10] = (frame->left_bar >> 8) & 0xff;
+ ptr[11] = frame->right_bar & 0xff;
+ ptr[12] = (frame->right_bar >> 8) & 0xff;
+
+ hdmi_infoframe_checksum(buffer, length);
+
+ return length;
+}
+EXPORT_SYMBOL(hdmi_avi_infoframe_pack);
+
+/**
+ * hdmi_spd_infoframe_init() - initialize an HDMI SPD infoframe
+ * @frame: HDMI SPD infoframe
+ * @vendor: vendor string
+ * @product: product string
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
+ const char *vendor, const char *product)
+{
+ memset(frame, 0, sizeof(*frame));
+
+ frame->type = HDMI_INFOFRAME_TYPE_SPD;
+ frame->version = 1;
+ frame->length = 25;
+
+ strncpy(frame->vendor, vendor, sizeof(frame->vendor));
+ strncpy(frame->product, product, sizeof(frame->product));
+
+ return 0;
+}
+EXPORT_SYMBOL(hdmi_spd_infoframe_init);
+
+/**
+ * hdmi_spd_infoframe_pack() - write HDMI SPD infoframe to binary buffer
+ * @frame: HDMI SPD infoframe
+ * @buffer: destination buffer
+ * @size: size of buffer
+ *
+ * Packs the information contained in the @frame structure into a binary
+ * representation that can be written into the corresponding controller
+ * registers. Also computes the checksum as required by section 5.3.5 of
+ * the HDMI 1.4 specification.
+ *
+ * Returns the number of bytes packed into the binary buffer or a negative
+ * error code on failure.
+ */
+ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
+ size_t size)
+{
+ u8 *ptr = buffer;
+ size_t length;
+
+ length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
+
+ if (size < length)
+ return -ENOSPC;
+
+ memset(buffer, 0, length);
+
+ ptr[0] = frame->type;
+ ptr[1] = frame->version;
+ ptr[2] = frame->length;
+ ptr[3] = 0; /* checksum */
+
+ /* start infoframe payload */
+ ptr += HDMI_INFOFRAME_HEADER_SIZE;
+
+ memcpy(ptr, frame->vendor, sizeof(frame->vendor));
+ memcpy(ptr + 8, frame->product, sizeof(frame->product));
+
+ ptr[24] = frame->sdi;
+
+ hdmi_infoframe_checksum(buffer, length);
+
+ return length;
+}
+EXPORT_SYMBOL(hdmi_spd_infoframe_pack);
+
+/**
+ * hdmi_audio_infoframe_init() - initialize an HDMI audio infoframe
+ * @frame: HDMI audio infoframe
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame)
+{
+ memset(frame, 0, sizeof(*frame));
+
+ frame->type = HDMI_INFOFRAME_TYPE_AUDIO;
+ frame->version = 1;
+ frame->length = 10;
+
+ return 0;
+}
+EXPORT_SYMBOL(hdmi_audio_infoframe_init);
+
+/**
+ * hdmi_audio_infoframe_pack() - write HDMI audio infoframe to binary buffer
+ * @frame: HDMI audio infoframe
+ * @buffer: destination buffer
+ * @size: size of buffer
+ *
+ * Packs the information contained in the @frame structure into a binary
+ * representation that can be written into the corresponding controller
+ * registers. Also computes the checksum as required by section 5.3.5 of
+ * the HDMI 1.4 specification.
+ *
+ * Returns the number of bytes packed into the binary buffer or a negative
+ * error code on failure.
+ */
+ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
+ void *buffer, size_t size)
+{
+ unsigned char channels;
+ u8 *ptr = buffer;
+ size_t length;
+
+ length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
+
+ if (size < length)
+ return -ENOSPC;
+
+ memset(buffer, 0, length);
+
+ if (frame->channels >= 2)
+ channels = frame->channels - 1;
+ else
+ channels = 0;
+
+ ptr[0] = frame->type;
+ ptr[1] = frame->version;
+ ptr[2] = frame->length;
+ ptr[3] = 0; /* checksum */
+
+ /* start infoframe payload */
+ ptr += HDMI_INFOFRAME_HEADER_SIZE;
+
+ ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
+ ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
+ (frame->sample_size & 0x3);
+ ptr[2] = frame->coding_type_ext & 0x1f;
+ ptr[3] = frame->channel_allocation;
+ ptr[4] = (frame->level_shift_value & 0xf) << 3;
+
+ if (frame->downmix_inhibit)
+ ptr[4] |= BIT(7);
+
+ hdmi_infoframe_checksum(buffer, length);
+
+ return length;
+}
+EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
+
+/**
+ * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary
+ * buffer
+ * @frame: HDMI vendor infoframe
+ * @buffer: destination buffer
+ * @size: size of buffer
+ *
+ * Packs the information contained in the @frame structure into a binary
+ * representation that can be written into the corresponding controller
+ * registers. Also computes the checksum as required by section 5.3.5 of
+ * the HDMI 1.4 specification.
+ *
+ * Returns the number of bytes packed into the binary buffer or a negative
+ * error code on failure.
+ */
+ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
+ void *buffer, size_t size)
+{
+ u8 *ptr = buffer;
+ size_t length;
+
+ length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
+
+ if (size < length)
+ return -ENOSPC;
+
+ memset(buffer, 0, length);
+
+ ptr[0] = frame->type;
+ ptr[1] = frame->version;
+ ptr[2] = frame->length;
+ ptr[3] = 0; /* checksum */
+
+ memcpy(&ptr[HDMI_INFOFRAME_HEADER_SIZE], frame->data, frame->length);
+
+ hdmi_infoframe_checksum(buffer, length);
+
+ return length;
+}
+EXPORT_SYMBOL(hdmi_vendor_infoframe_pack);
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c
index 614251a..59d2318 100644
--- a/drivers/video/hecubafb.c
+++ b/drivers/video/hecubafb.c
@@ -47,7 +47,7 @@
#define DPY_W 600
#define DPY_H 800
-static struct fb_fix_screeninfo hecubafb_fix __devinitdata = {
+static struct fb_fix_screeninfo hecubafb_fix = {
.id = "hecubafb",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_MONO01,
@@ -58,7 +58,7 @@ static struct fb_fix_screeninfo hecubafb_fix __devinitdata = {
.accel = FB_ACCEL_NONE,
};
-static struct fb_var_screeninfo hecubafb_var __devinitdata = {
+static struct fb_var_screeninfo hecubafb_var = {
.xres = DPY_W,
.yres = DPY_H,
.xres_virtual = DPY_W,
@@ -211,7 +211,7 @@ static struct fb_deferred_io hecubafb_defio = {
.deferred_io = hecubafb_dpy_deferred_io,
};
-static int __devinit hecubafb_probe(struct platform_device *dev)
+static int hecubafb_probe(struct platform_device *dev)
{
struct fb_info *info;
struct hecuba_board *board;
@@ -280,7 +280,7 @@ err_videomem_alloc:
return retval;
}
-static int __devexit hecubafb_remove(struct platform_device *dev)
+static int hecubafb_remove(struct platform_device *dev)
{
struct fb_info *info = platform_get_drvdata(dev);
@@ -299,7 +299,7 @@ static int __devexit hecubafb_remove(struct platform_device *dev)
static struct platform_driver hecubafb_driver = {
.probe = hecubafb_probe,
- .remove = __devexit_p(hecubafb_remove),
+ .remove = hecubafb_remove,
.driver = {
.owner = THIS_MODULE,
.name = "hecubafb",
diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c
index c645f92..1e9e2d8 100644
--- a/drivers/video/hgafb.c
+++ b/drivers/video/hgafb.c
@@ -106,7 +106,7 @@ static DEFINE_SPINLOCK(hga_reg_lock);
/* Framebuffer driver structures */
-static struct fb_var_screeninfo hga_default_var __devinitdata = {
+static struct fb_var_screeninfo hga_default_var = {
.xres = 720,
.yres = 348,
.xres_virtual = 720,
@@ -120,7 +120,7 @@ static struct fb_var_screeninfo hga_default_var __devinitdata = {
.width = -1,
};
-static struct fb_fix_screeninfo hga_fix __devinitdata = {
+static struct fb_fix_screeninfo hga_fix = {
.id = "HGA",
.type = FB_TYPE_PACKED_PIXELS, /* (not sure) */
.visual = FB_VISUAL_MONO10,
@@ -276,7 +276,7 @@ static void hga_blank(int blank_mode)
spin_unlock_irqrestore(&hga_reg_lock, flags);
}
-static int __devinit hga_card_detect(void)
+static int hga_card_detect(void)
{
int count = 0;
void __iomem *p, *q;
@@ -546,7 +546,7 @@ static struct fb_ops hgafb_ops = {
* Initialization
*/
-static int __devinit hgafb_probe(struct platform_device *pdev)
+static int hgafb_probe(struct platform_device *pdev)
{
struct fb_info *info;
@@ -592,7 +592,7 @@ static int __devinit hgafb_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit hgafb_remove(struct platform_device *pdev)
+static int hgafb_remove(struct platform_device *pdev)
{
struct fb_info *info = platform_get_drvdata(pdev);
@@ -617,7 +617,7 @@ static int __devexit hgafb_remove(struct platform_device *pdev)
static struct platform_driver hgafb_driver = {
.probe = hgafb_probe,
- .remove = __devexit_p(hgafb_remove),
+ .remove = hgafb_remove,
.driver = {
.name = "hgafb",
},
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c
index cfb8d64..c2414d6 100644
--- a/drivers/video/hitfb.c
+++ b/drivers/video/hitfb.c
@@ -30,14 +30,14 @@
#define WIDTH 640
-static struct fb_var_screeninfo hitfb_var __devinitdata = {
+static struct fb_var_screeninfo hitfb_var = {
.activate = FB_ACTIVATE_NOW,
.height = -1,
.width = -1,
.vmode = FB_VMODE_NONINTERLACED,
};
-static struct fb_fix_screeninfo hitfb_fix __devinitdata = {
+static struct fb_fix_screeninfo hitfb_fix = {
.id = "Hitachi HD64461",
.type = FB_TYPE_PACKED_PIXELS,
.accel = FB_ACCEL_NONE,
@@ -324,7 +324,7 @@ static struct fb_ops hitfb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static int __devinit hitfb_probe(struct platform_device *dev)
+static int hitfb_probe(struct platform_device *dev)
{
unsigned short lcdclor, ldr3, ldvndr;
struct fb_info *info;
@@ -417,7 +417,7 @@ err_fb:
return ret;
}
-static int __devexit hitfb_remove(struct platform_device *dev)
+static int hitfb_remove(struct platform_device *dev)
{
struct fb_info *info = platform_get_drvdata(dev);
@@ -462,7 +462,7 @@ static const struct dev_pm_ops hitfb_dev_pm_ops = {
static struct platform_driver hitfb_driver = {
.probe = hitfb_probe,
- .remove = __devexit_p(hitfb_remove),
+ .remove = hitfb_remove,
.driver = {
.name = "hitfb",
.owner = THIS_MODULE,
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index 7324865..b802f93 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -206,8 +206,7 @@ static struct fb_ops hpfb_ops = {
#define HPFB_FBOMSB 0x5d /* Frame buffer offset */
#define HPFB_FBOLSB 0x5f
-static int __devinit hpfb_init_one(unsigned long phys_base,
- unsigned long virt_base)
+static int hpfb_init_one(unsigned long phys_base, unsigned long virt_base)
{
unsigned long fboff, fb_width, fb_height, fb_start;
int ret;
@@ -327,7 +326,7 @@ unmap_screen_base:
/*
* Initialise the framebuffer
*/
-static int __devinit hpfb_dio_probe(struct dio_dev * d, const struct dio_device_id * ent)
+static int hpfb_dio_probe(struct dio_dev *d, const struct dio_device_id *ent)
{
unsigned long paddr, vaddr;
@@ -350,7 +349,7 @@ static int __devinit hpfb_dio_probe(struct dio_dev * d, const struct dio_device_
return 0;
}
-static void __devexit hpfb_remove_one(struct dio_dev *d)
+static void hpfb_remove_one(struct dio_dev *d)
{
unregister_framebuffer(&fb_info);
if (d->scode >= DIOII_SCBASE)
@@ -373,7 +372,7 @@ static struct dio_driver hpfb_driver = {
.name = "hpfb",
.id_table = hpfb_dio_tbl,
.probe = hpfb_dio_probe,
- .remove = __devexit_p(hpfb_remove_one),
+ .remove = hpfb_remove_one,
};
int __init hpfb_init(void)
diff --git a/drivers/video/i740fb.c b/drivers/video/i740fb.c
index ff3f880..cfd0c52 100644
--- a/drivers/video/i740fb.c
+++ b/drivers/video/i740fb.c
@@ -33,10 +33,10 @@
#include "i740_reg.h"
-static char *mode_option __devinitdata;
+static char *mode_option;
#ifdef CONFIG_MTRR
-static int mtrr __devinitdata = 1;
+static int mtrr = 1;
#endif
struct i740fb_par {
@@ -91,7 +91,7 @@ struct i740fb_par {
#define DACSPEED24_SD 128
#define DACSPEED32 86
-static struct fb_fix_screeninfo i740fb_fix __devinitdata = {
+static struct fb_fix_screeninfo i740fb_fix = {
.id = "i740fb",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_TRUECOLOR,
@@ -163,7 +163,7 @@ static int i740fb_ddc_getsda(void *data)
return !!(i740inreg(par, XRX, REG_DDC_STATE) & DDC_SDA);
}
-static int __devinit i740fb_setup_ddc_bus(struct fb_info *info)
+static int i740fb_setup_ddc_bus(struct fb_info *info)
{
struct i740fb_par *par = info->par;
@@ -1007,8 +1007,7 @@ static struct fb_ops i740fb_ops = {
/* ------------------------------------------------------------------------- */
-static int __devinit i740fb_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+static int i740fb_probe(struct pci_dev *dev, const struct pci_device_id *ent)
{
struct fb_info *info;
struct i740fb_par *par;
@@ -1174,7 +1173,7 @@ err_enable_device:
return ret;
}
-static void __devexit i740fb_remove(struct pci_dev *dev)
+static void i740fb_remove(struct pci_dev *dev)
{
struct fb_info *info = pci_get_drvdata(dev);
@@ -1275,7 +1274,7 @@ static struct pci_driver i740fb_driver = {
.name = "i740fb",
.id_table = i740fb_id_table,
.probe = i740fb_probe,
- .remove = __devexit_p(i740fb_remove),
+ .remove = i740fb_remove,
.suspend = i740fb_suspend,
.resume = i740fb_resume,
};
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index 5c06781..4ce3438 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -74,12 +74,12 @@
*
* Experiment with v_offset to find out which works best for you.
*/
-static u32 v_offset_default __devinitdata; /* For 32 MiB Aper size, 8 should be the default */
-static u32 voffset __devinitdata;
+static u32 v_offset_default; /* For 32 MiB Aper size, 8 should be the default */
+static u32 voffset;
static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor);
-static int __devinit i810fb_init_pci (struct pci_dev *dev,
- const struct pci_device_id *entry);
+static int i810fb_init_pci(struct pci_dev *dev,
+ const struct pci_device_id *entry);
static void __exit i810fb_remove_pci(struct pci_dev *dev);
static int i810fb_resume(struct pci_dev *dev);
static int i810fb_suspend(struct pci_dev *dev, pm_message_t state);
@@ -97,7 +97,7 @@ static int i810fb_blank (int blank_mode, struct fb_info *info);
static void i810fb_release_resource (struct fb_info *info, struct i810fb_par *par);
/* PCI */
-static const char * const i810_pci_list[] __devinitconst = {
+static const char * const i810_pci_list[] = {
"Intel(R) 810 Framebuffer Device" ,
"Intel(R) 810-DC100 Framebuffer Device" ,
"Intel(R) 810E Framebuffer Device" ,
@@ -132,22 +132,22 @@ static struct pci_driver i810fb_driver = {
.resume = i810fb_resume,
};
-static char *mode_option __devinitdata = NULL;
-static int vram __devinitdata = 4;
-static int bpp __devinitdata = 8;
-static bool mtrr __devinitdata;
-static bool accel __devinitdata;
-static int hsync1 __devinitdata;
-static int hsync2 __devinitdata;
-static int vsync1 __devinitdata;
-static int vsync2 __devinitdata;
-static int xres __devinitdata;
+static char *mode_option = NULL;
+static int vram = 4;
+static int bpp = 8;
+static bool mtrr;
+static bool accel;
+static int hsync1;
+static int hsync2;
+static int vsync1;
+static int vsync2;
+static int xres;
static int yres;
-static int vyres __devinitdata;
-static bool sync __devinitdata;
-static bool extvga __devinitdata;
-static bool dcolor __devinitdata;
-static bool ddc3 __devinitdata;
+static int vyres;
+static bool sync;
+static bool extvga;
+static bool dcolor;
+static bool ddc3;
/*------------------------------------------------------------*/
@@ -1541,7 +1541,7 @@ static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
return 0;
}
-static struct fb_ops i810fb_ops __devinitdata = {
+static struct fb_ops i810fb_ops = {
.owner = THIS_MODULE,
.fb_open = i810fb_open,
.fb_release = i810fb_release,
@@ -1628,7 +1628,7 @@ fail:
* AGP resource allocation *
***********************************************************************/
-static void __devinit i810_fix_pointers(struct i810fb_par *par)
+static void i810_fix_pointers(struct i810fb_par *par)
{
par->fb.physical = par->aperture.physical+(par->fb.offset << 12);
par->fb.virtual = par->aperture.virtual+(par->fb.offset << 12);
@@ -1640,7 +1640,7 @@ static void __devinit i810_fix_pointers(struct i810fb_par *par)
(par->cursor_heap.offset << 12);
}
-static void __devinit i810_fix_offsets(struct i810fb_par *par)
+static void i810_fix_offsets(struct i810fb_par *par)
{
if (vram + 1 > par->aperture.size >> 20)
vram = (par->aperture.size >> 20) - 1;
@@ -1660,7 +1660,7 @@ static void __devinit i810_fix_offsets(struct i810fb_par *par)
par->cursor_heap.size = 4096;
}
-static int __devinit i810_alloc_agp_mem(struct fb_info *info)
+static int i810_alloc_agp_mem(struct fb_info *info)
{
struct i810fb_par *par = info->par;
int size;
@@ -1723,7 +1723,7 @@ static int __devinit i810_alloc_agp_mem(struct fb_info *info)
* Sets the user monitor's horizontal and vertical
* frequency limits
*/
-static void __devinit i810_init_monspecs(struct fb_info *info)
+static void i810_init_monspecs(struct fb_info *info)
{
if (!hsync1)
hsync1 = HFMIN;
@@ -1755,8 +1755,7 @@ static void __devinit i810_init_monspecs(struct fb_info *info)
* @par: pointer to i810fb_par structure
* @info: pointer to current fb_info structure
*/
-static void __devinit i810_init_defaults(struct i810fb_par *par,
- struct fb_info *info)
+static void i810_init_defaults(struct i810fb_par *par, struct fb_info *info)
{
mutex_init(&par->open_lock);
@@ -1812,7 +1811,7 @@ static void __devinit i810_init_defaults(struct i810fb_par *par,
* i810_init_device - initialize device
* @par: pointer to i810fb_par structure
*/
-static void __devinit i810_init_device(struct i810fb_par *par)
+static void i810_init_device(struct i810fb_par *par)
{
u8 reg;
u8 __iomem *mmio = par->mmio_start_virtual;
@@ -1833,9 +1832,8 @@ static void __devinit i810_init_device(struct i810fb_par *par)
}
-static int __devinit
-i810_allocate_pci_resource(struct i810fb_par *par,
- const struct pci_device_id *entry)
+static int i810_allocate_pci_resource(struct i810fb_par *par,
+ const struct pci_device_id *entry)
{
int err;
@@ -1892,7 +1890,7 @@ i810_allocate_pci_resource(struct i810fb_par *par,
return 0;
}
-static void __devinit i810fb_find_init_mode(struct fb_info *info)
+static void i810fb_find_init_mode(struct fb_info *info)
{
struct fb_videomode mode;
struct fb_var_screeninfo var;
@@ -1956,7 +1954,7 @@ static void __devinit i810fb_find_init_mode(struct fb_info *info)
}
#ifndef MODULE
-static int __devinit i810fb_setup(char *options)
+static int i810fb_setup(char *options)
{
char *this_opt, *suffix = NULL;
@@ -2007,8 +2005,8 @@ static int __devinit i810fb_setup(char *options)
}
#endif
-static int __devinit i810fb_init_pci (struct pci_dev *dev,
- const struct pci_device_id *entry)
+static int i810fb_init_pci(struct pci_dev *dev,
+ const struct pci_device_id *entry)
{
struct fb_info *info;
struct i810fb_par *par = NULL;
@@ -2136,7 +2134,7 @@ static void __exit i810fb_remove_pci(struct pci_dev *dev)
}
#ifndef MODULE
-static int __devinit i810fb_init(void)
+static int i810fb_init(void)
{
char *option = NULL;
@@ -2154,7 +2152,7 @@ static int __devinit i810fb_init(void)
#ifdef MODULE
-static int __devinit i810fb_init(void)
+static int i810fb_init(void)
{
hsync1 *= 1000;
hsync2 *= 1000;
diff --git a/drivers/video/i810/i810_main.h b/drivers/video/i810/i810_main.h
index 51d4f3d..a25afaa 100644
--- a/drivers/video/i810/i810_main.h
+++ b/drivers/video/i810/i810_main.h
@@ -64,7 +64,7 @@ static inline void flush_cache(void)
#include <asm/mtrr.h>
-static inline void __devinit set_mtrr(struct i810fb_par *par)
+static inline void set_mtrr(struct i810fb_par *par)
{
par->mtrr_reg = mtrr_add((u32) par->aperture.physical,
par->aperture.size, MTRR_TYPE_WRCOMB, 1);
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c
index 2d97752..79cbfa7 100644
--- a/drivers/video/igafb.c
+++ b/drivers/video/igafb.c
@@ -571,7 +571,7 @@ static int __init igafb_setup(char *options)
module_init(igafb_init);
MODULE_LICENSE("GPL");
-static struct pci_device_id igafb_pci_tbl[] __devinitdata = {
+static struct pci_device_id igafb_pci_tbl[] = {
{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ }
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index 8149356..d5220cc 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -225,7 +225,7 @@ struct initvalues {
__u8 addr, value;
};
-static struct initvalues ibm_initregs[] __devinitdata = {
+static struct initvalues ibm_initregs[] = {
{ CLKCTL, 0x21 },
{ SYNCCTL, 0x00 },
{ HSYNCPOS, 0x00 },
@@ -272,7 +272,7 @@ static struct initvalues ibm_initregs[] __devinitdata = {
{ KEYCTL, 0x00 }
};
-static struct initvalues tvp_initregs[] __devinitdata = {
+static struct initvalues tvp_initregs[] = {
{ TVPIRICC, 0x00 },
{ TVPIRBRC, 0xe4 },
{ TVPIRLAC, 0x06 },
@@ -336,7 +336,7 @@ enum {
static int inverse = 0;
static char fontname[40] __initdata = { 0 };
#if defined(CONFIG_PPC)
-static signed char init_vmode __devinitdata = -1, init_cmode __devinitdata = -1;
+static signed char init_vmode = -1, init_cmode = -1;
#endif
static struct imstt_regvals tvp_reg_init_2 = {
@@ -1333,7 +1333,7 @@ static struct pci_driver imsttfb_pci_driver = {
.name = "imsttfb",
.id_table = imsttfb_pci_tbl,
.probe = imsttfb_probe,
- .remove = __devexit_p(imsttfb_remove),
+ .remove = imsttfb_remove,
};
static struct fb_ops imsttfb_ops = {
@@ -1349,8 +1349,7 @@ static struct fb_ops imsttfb_ops = {
.fb_ioctl = imsttfb_ioctl,
};
-static void __devinit
-init_imstt(struct fb_info *info)
+static void init_imstt(struct fb_info *info)
{
struct imstt_par *par = info->par;
__u32 i, tmp, *ip, *end;
@@ -1466,8 +1465,7 @@ init_imstt(struct fb_info *info)
info->node, info->fix.id, info->fix.smem_len >> 20, tmp);
}
-static int __devinit
-imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
unsigned long addr, size;
struct imstt_par *par;
@@ -1534,8 +1532,7 @@ imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0;
}
-static void __devexit
-imsttfb_remove(struct pci_dev *pdev)
+static void imsttfb_remove(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct imstt_par *par = info->par;
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index cf2688d..0abf2bf 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -33,7 +33,6 @@
#include <linux/math64.h>
#include <linux/platform_data/video-imxfb.h>
-#include <mach/hardware.h>
/*
* Complain if VAR is out of range.
@@ -53,8 +52,8 @@
#define LCDC_SIZE 0x04
#define SIZE_XMAX(x) ((((x) >> 4) & 0x3f) << 20)
-#define YMAX_MASK (cpu_is_mx1() ? 0x1ff : 0x3ff)
-#define SIZE_YMAX(y) ((y) & YMAX_MASK)
+#define YMAX_MASK_IMX1 0x1ff
+#define YMAX_MASK_IMX21 0x3ff
#define LCDC_VPW 0x08
#define VPW_VPW(x) ((x) & 0x3ff)
@@ -128,12 +127,19 @@ struct imxfb_rgb {
struct fb_bitfield transp;
};
+enum imxfb_type {
+ IMX1_FB,
+ IMX21_FB,
+};
+
struct imxfb_info {
struct platform_device *pdev;
void __iomem *regs;
struct clk *clk_ipg;
struct clk *clk_ahb;
struct clk *clk_per;
+ enum imxfb_type devtype;
+ bool enabled;
/*
* These are the addresses we mapped
@@ -168,6 +174,24 @@ struct imxfb_info {
void (*backlight_power)(int);
};
+static struct platform_device_id imxfb_devtype[] = {
+ {
+ .name = "imx1-fb",
+ .driver_data = IMX1_FB,
+ }, {
+ .name = "imx21-fb",
+ .driver_data = IMX21_FB,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(platform, imxfb_devtype);
+
+static inline int is_imx1_fb(struct imxfb_info *fbi)
+{
+ return fbi->devtype == IMX1_FB;
+}
+
#define IMX_NAME "IMX"
/*
@@ -366,7 +390,7 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
break;
case 16:
default:
- if (cpu_is_mx1())
+ if (is_imx1_fb(fbi))
pcr |= PCR_BPIX_12;
else
pcr |= PCR_BPIX_16;
@@ -513,6 +537,10 @@ static void imxfb_exit_backlight(struct imxfb_info *fbi)
static void imxfb_enable_controller(struct imxfb_info *fbi)
{
+
+ if (fbi->enabled)
+ return;
+
pr_debug("Enabling LCD controller\n");
writel(fbi->screen_dma, fbi->regs + LCDC_SSA);
@@ -533,6 +561,7 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
clk_prepare_enable(fbi->clk_ipg);
clk_prepare_enable(fbi->clk_ahb);
clk_prepare_enable(fbi->clk_per);
+ fbi->enabled = true;
if (fbi->backlight_power)
fbi->backlight_power(1);
@@ -542,6 +571,9 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
static void imxfb_disable_controller(struct imxfb_info *fbi)
{
+ if (!fbi->enabled)
+ return;
+
pr_debug("Disabling LCD controller\n");
if (fbi->backlight_power)
@@ -552,6 +584,7 @@ static void imxfb_disable_controller(struct imxfb_info *fbi)
clk_disable_unprepare(fbi->clk_per);
clk_disable_unprepare(fbi->clk_ipg);
clk_disable_unprepare(fbi->clk_ahb);
+ fbi->enabled = false;
writel(0, fbi->regs + LCDC_RMCR);
}
@@ -596,6 +629,7 @@ static struct fb_ops imxfb_ops = {
static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
struct imxfb_info *fbi = info->par;
+ u32 ymax_mask = is_imx1_fb(fbi) ? YMAX_MASK_IMX1 : YMAX_MASK_IMX21;
pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n",
var->xres, var->hsync_len,
@@ -617,7 +651,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
if (var->right_margin > 255)
printk(KERN_ERR "%s: invalid right_margin %d\n",
info->fix.id, var->right_margin);
- if (var->yres < 1 || var->yres > YMAX_MASK)
+ if (var->yres < 1 || var->yres > ymax_mask)
printk(KERN_ERR "%s: invalid yres %d\n",
info->fix.id, var->yres);
if (var->vsync_len > 100)
@@ -645,7 +679,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
VCR_V_WAIT_2(var->upper_margin),
fbi->regs + LCDC_VCR);
- writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres),
+ writel(SIZE_XMAX(var->xres) | (var->yres & ymax_mask),
fbi->regs + LCDC_SIZE);
writel(fbi->pcr, fbi->regs + LCDC_PCR);
@@ -705,6 +739,8 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)
memset(fbi, 0, sizeof(struct imxfb_info));
+ fbi->devtype = pdev->id_entry->driver_data;
+
strlcpy(info->fix.id, IMX_NAME, sizeof(info->fix.id));
info->fix.type = FB_TYPE_PACKED_PIXELS;
@@ -892,7 +928,7 @@ failed_init:
return ret;
}
-static int __devexit imxfb_remove(struct platform_device *pdev)
+static int imxfb_remove(struct platform_device *pdev)
{
struct imx_fb_platform_data *pdata;
struct fb_info *info = platform_get_drvdata(pdev);
@@ -934,11 +970,12 @@ void imxfb_shutdown(struct platform_device * dev)
static struct platform_driver imxfb_driver = {
.suspend = imxfb_suspend,
.resume = imxfb_resume,
- .remove = __devexit_p(imxfb_remove),
+ .remove = imxfb_remove,
.shutdown = imxfb_shutdown,
.driver = {
.name = DRIVER_NAME,
},
+ .id_table = imxfb_devtype,
};
static int imxfb_setup(void)
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index bdcbfba..8209e46 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -132,7 +132,7 @@
#include "intelfbhw.h"
#include "../edid.h"
-static void __devinit get_initial_mode(struct intelfb_info *dinfo);
+static void get_initial_mode(struct intelfb_info *dinfo);
static void update_dinfo(struct intelfb_info *dinfo,
struct fb_var_screeninfo *var);
static int intelfb_open(struct fb_info *info, int user);
@@ -162,10 +162,10 @@ static int intelfb_sync(struct fb_info *info);
static int intelfb_ioctl(struct fb_info *info,
unsigned int cmd, unsigned long arg);
-static int __devinit intelfb_pci_register(struct pci_dev *pdev,
- const struct pci_device_id *ent);
-static void __devexit intelfb_pci_unregister(struct pci_dev *pdev);
-static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo);
+static int intelfb_pci_register(struct pci_dev *pdev,
+ const struct pci_device_id *ent);
+static void intelfb_pci_unregister(struct pci_dev *pdev);
+static int intelfb_set_fbinfo(struct intelfb_info *dinfo);
/*
* Limiting the class to PCI_CLASS_DISPLAY_VGA prevents function 1 of the
@@ -177,7 +177,7 @@ static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo);
#define INTELFB_CLASS_MASK 0
#endif
-static struct pci_device_id intelfb_pci_table[] __devinitdata = {
+static struct pci_device_id intelfb_pci_table[] = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_830M, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_830M },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_845G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_845G },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM },
@@ -219,7 +219,7 @@ static struct pci_driver intelfb_driver = {
.name = "intelfb",
.id_table = intelfb_pci_table,
.probe = intelfb_pci_register,
- .remove = __devexit_p(intelfb_pci_unregister)
+ .remove = intelfb_pci_unregister,
};
/* Module description/parameters */
@@ -415,7 +415,7 @@ module_exit(intelfb_exit);
***************************************************************/
#ifdef CONFIG_MTRR
-static inline void __devinit set_mtrr(struct intelfb_info *dinfo)
+static inline void set_mtrr(struct intelfb_info *dinfo)
{
dinfo->mtrr_reg = mtrr_add(dinfo->aperture.physical,
dinfo->aperture.size, MTRR_TYPE_WRCOMB, 1);
@@ -497,8 +497,8 @@ static void cleanup(struct intelfb_info *dinfo)
} while (0)
-static int __devinit intelfb_pci_register(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int intelfb_pci_register(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
struct fb_info *info;
struct intelfb_info *dinfo;
@@ -921,8 +921,7 @@ err_out_cmap:
return -ENODEV;
}
-static void __devexit
-intelfb_pci_unregister(struct pci_dev *pdev)
+static void intelfb_pci_unregister(struct pci_dev *pdev)
{
struct intelfb_info *dinfo = pci_get_drvdata(pdev);
@@ -970,7 +969,7 @@ static __inline__ int var_to_refresh(const struct fb_var_screeninfo *var)
* Various intialisation functions *
***************************************************************/
-static void __devinit get_initial_mode(struct intelfb_info *dinfo)
+static void get_initial_mode(struct intelfb_info *dinfo)
{
struct fb_var_screeninfo *var;
int xtot, ytot;
@@ -1037,7 +1036,7 @@ static void __devinit get_initial_mode(struct intelfb_info *dinfo)
}
}
-static int __devinit intelfb_init_var(struct intelfb_info *dinfo)
+static int intelfb_init_var(struct intelfb_info *dinfo)
{
struct fb_var_screeninfo *var;
int msrc = 0;
@@ -1118,7 +1117,7 @@ static int __devinit intelfb_init_var(struct intelfb_info *dinfo)
return 0;
}
-static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo)
+static int intelfb_set_fbinfo(struct intelfb_info *dinfo)
{
struct fb_info *info = dinfo->info;
diff --git a/drivers/video/jz4740_fb.c b/drivers/video/jz4740_fb.c
index 4d25711..36979b4 100644
--- a/drivers/video/jz4740_fb.c
+++ b/drivers/video/jz4740_fb.c
@@ -136,7 +136,7 @@ struct jzfb {
uint32_t pseudo_palette[16];
};
-static const struct fb_fix_screeninfo jzfb_fix __devinitconst = {
+static const struct fb_fix_screeninfo jzfb_fix = {
.id = "JZ4740 FB",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_TRUECOLOR,
@@ -619,7 +619,7 @@ static struct fb_ops jzfb_ops = {
.fb_setcolreg = jzfb_setcolreg,
};
-static int __devinit jzfb_probe(struct platform_device *pdev)
+static int jzfb_probe(struct platform_device *pdev)
{
int ret;
struct jzfb *jzfb;
@@ -660,9 +660,9 @@ static int __devinit jzfb_probe(struct platform_device *pdev)
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- jzfb->base = devm_request_and_ioremap(&pdev->dev, mem);
- if (!jzfb->base) {
- ret = -EBUSY;
+ jzfb->base = devm_ioremap_resource(&pdev->dev, mem);
+ if (IS_ERR(jzfb->base)) {
+ ret = PTR_ERR(jzfb->base);
goto err_framebuffer_release;
}
@@ -725,7 +725,7 @@ err_framebuffer_release:
return ret;
}
-static int __devexit jzfb_remove(struct platform_device *pdev)
+static int jzfb_remove(struct platform_device *pdev)
{
struct jzfb *jzfb = platform_get_drvdata(pdev);
@@ -794,7 +794,7 @@ static const struct dev_pm_ops jzfb_pm_ops = {
static struct platform_driver jzfb_driver = {
.probe = jzfb_probe,
- .remove = __devexit_p(jzfb_remove),
+ .remove = jzfb_remove,
.driver = {
.name = "jz4740-fb",
.pm = JZFB_PM_OPS,
diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c
index acb9370..6157f74 100644
--- a/drivers/video/kyro/fbdev.c
+++ b/drivers/video/kyro/fbdev.c
@@ -40,14 +40,14 @@
#define KHZ2PICOS(a) (1000000000UL/(a))
/****************************************************************************/
-static struct fb_fix_screeninfo kyro_fix __devinitdata = {
+static struct fb_fix_screeninfo kyro_fix = {
.id = "ST Kyro",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_TRUECOLOR,
.accel = FB_ACCEL_NONE,
};
-static struct fb_var_screeninfo kyro_var __devinitdata = {
+static struct fb_var_screeninfo kyro_var = {
/* 640x480, 16bpp @ 60 Hz */
.xres = 640,
.yres = 480,
@@ -81,18 +81,18 @@ typedef struct {
/* global graphics card info structure (one per card) */
static device_info_t deviceInfo;
-static char *mode_option __devinitdata = NULL;
-static int nopan __devinitdata = 0;
-static int nowrap __devinitdata = 1;
+static char *mode_option = NULL;
+static int nopan = 0;
+static int nowrap = 1;
#ifdef CONFIG_MTRR
-static int nomtrr __devinitdata = 0;
+static int nomtrr = 0;
#endif
/* PCI driver prototypes */
static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
static void kyrofb_remove(struct pci_dev *pdev);
-static struct fb_videomode kyro_modedb[] __devinitdata = {
+static struct fb_videomode kyro_modedb[] = {
{
/* 640x350 @ 85Hz */
NULL, 85, 640, 350, KHZ2PICOS(31500),
@@ -653,7 +653,7 @@ static struct pci_driver kyrofb_pci_driver = {
.name = "kyrofb",
.id_table = kyrofb_pci_tbl,
.probe = kyrofb_probe,
- .remove = __devexit_p(kyrofb_remove),
+ .remove = kyrofb_remove,
};
static struct fb_ops kyrofb_ops = {
@@ -667,8 +667,7 @@ static struct fb_ops kyrofb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static int __devinit kyrofb_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct fb_info *info;
struct kyrofb_info *currentpar;
@@ -754,7 +753,7 @@ out_unmap:
return -EINVAL;
}
-static void __devexit kyrofb_remove(struct pci_dev *pdev)
+static void kyrofb_remove(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct kyrofb_info *par = info->par;
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index 9e946e2..b17f500 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -547,7 +547,7 @@ static void leo_unmap_regs(struct platform_device *op, struct fb_info *info,
of_iounmap(&op->resource[0], info->screen_base, 0x800000);
}
-static int __devinit leo_probe(struct platform_device *op)
+static int leo_probe(struct platform_device *op)
{
struct device_node *dp = op->dev.of_node;
struct fb_info *info;
@@ -636,7 +636,7 @@ out_err:
return err;
}
-static int __devexit leo_remove(struct platform_device *op)
+static int leo_remove(struct platform_device *op)
{
struct fb_info *info = dev_get_drvdata(&op->dev);
struct leo_par *par = info->par;
@@ -668,7 +668,7 @@ static struct platform_driver leo_driver = {
.of_match_table = leo_match,
},
.probe = leo_probe,
- .remove = __devexit_p(leo_remove),
+ .remove = leo_remove,
};
static int __init leo_init(void)
diff --git a/drivers/video/mb862xx/mb862xxfbdrv.c b/drivers/video/mb862xx/mb862xxfbdrv.c
index d68e332..91c59c9 100644
--- a/drivers/video/mb862xx/mb862xxfbdrv.c
+++ b/drivers/video/mb862xx/mb862xxfbdrv.c
@@ -668,7 +668,7 @@ static int mb862xx_gdc_init(struct mb862xxfb_par *par)
return 0;
}
-static int __devinit of_platform_mb862xx_probe(struct platform_device *ofdev)
+static int of_platform_mb862xx_probe(struct platform_device *ofdev)
{
struct device_node *np = ofdev->dev.of_node;
struct device *dev = &ofdev->dev;
@@ -786,7 +786,7 @@ fbrel:
return ret;
}
-static int __devexit of_platform_mb862xx_remove(struct platform_device *ofdev)
+static int of_platform_mb862xx_remove(struct platform_device *ofdev)
{
struct fb_info *fbi = dev_get_drvdata(&ofdev->dev);
struct mb862xxfb_par *par = fbi->par;
@@ -823,7 +823,7 @@ static int __devexit of_platform_mb862xx_remove(struct platform_device *ofdev)
/*
* common types
*/
-static struct of_device_id __devinitdata of_platform_mb862xx_tbl[] = {
+static struct of_device_id of_platform_mb862xx_tbl[] = {
{ .compatible = "fujitsu,MB86276", },
{ .compatible = "fujitsu,lime", },
{ .compatible = "fujitsu,MB86277", },
@@ -841,7 +841,7 @@ static struct platform_driver of_platform_mb862xxfb_driver = {
.of_match_table = of_platform_mb862xx_tbl,
},
.probe = of_platform_mb862xx_probe,
- .remove = __devexit_p(of_platform_mb862xx_remove),
+ .remove = of_platform_mb862xx_remove,
};
#endif
@@ -984,7 +984,7 @@ static inline int mb862xx_pci_gdc_init(struct mb862xxfb_par *par)
#define CHIP_ID(id) \
{ PCI_DEVICE(PCI_VENDOR_ID_FUJITSU_LIMITED, id) }
-static struct pci_device_id mb862xx_pci_tbl[] __devinitdata = {
+static struct pci_device_id mb862xx_pci_tbl[] = {
/* MB86295/MB86296 */
CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALP),
CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALPA),
@@ -995,8 +995,8 @@ static struct pci_device_id mb862xx_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, mb862xx_pci_tbl);
-static int __devinit mb862xx_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int mb862xx_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
struct mb862xxfb_par *par;
struct fb_info *info;
@@ -1133,7 +1133,7 @@ out:
return ret;
}
-static void __devexit mb862xx_pci_remove(struct pci_dev *pdev)
+static void mb862xx_pci_remove(struct pci_dev *pdev)
{
struct fb_info *fbi = pci_get_drvdata(pdev);
struct mb862xxfb_par *par = fbi->par;
@@ -1174,11 +1174,11 @@ static struct pci_driver mb862xxfb_pci_driver = {
.name = DRV_NAME,
.id_table = mb862xx_pci_tbl,
.probe = mb862xx_pci_probe,
- .remove = __devexit_p(mb862xx_pci_remove),
+ .remove = mb862xx_pci_remove,
};
#endif
-static int __devinit mb862xxfb_init(void)
+static int mb862xxfb_init(void)
{
int ret = -ENODEV;
diff --git a/drivers/video/mbx/mbxdebugfs.c b/drivers/video/mbx/mbxdebugfs.c
index 12dec76..4449f24 100644
--- a/drivers/video/mbx/mbxdebugfs.c
+++ b/drivers/video/mbx/mbxdebugfs.c
@@ -213,7 +213,7 @@ static const struct file_operations misc_fops = {
.llseek = default_llseek,
};
-static void __devinit mbxfb_debugfs_init(struct fb_info *fbi)
+static void mbxfb_debugfs_init(struct fb_info *fbi)
{
struct mbxfb_info *mfbi = fbi->par;
struct mbxfb_debugfs_data *dbg;
@@ -236,7 +236,7 @@ static void __devinit mbxfb_debugfs_init(struct fb_info *fbi)
fbi, &misc_fops);
}
-static void __devexit mbxfb_debugfs_remove(struct fb_info *fbi)
+static void mbxfb_debugfs_remove(struct fb_info *fbi)
{
struct mbxfb_info *mfbi = fbi->par;
struct mbxfb_debugfs_data *dbg = mfbi->debugfs_data;
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
index 6563e50..0c1a874 100644
--- a/drivers/video/mbx/mbxfb.c
+++ b/drivers/video/mbx/mbxfb.c
@@ -79,7 +79,7 @@ struct mbxfb_info {
};
-static struct fb_var_screeninfo mbxfb_default __devinitdata = {
+static struct fb_var_screeninfo mbxfb_default = {
.xres = 640,
.yres = 480,
.xres_virtual = 640,
@@ -102,7 +102,7 @@ static struct fb_var_screeninfo mbxfb_default __devinitdata = {
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
};
-static struct fb_fix_screeninfo mbxfb_fix __devinitdata = {
+static struct fb_fix_screeninfo mbxfb_fix = {
.id = "MBX",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_TRUECOLOR,
@@ -687,7 +687,7 @@ static struct fb_ops mbxfb_ops = {
Enable external SDRAM controller. Assume that all clocks are active
by now.
*/
-static void __devinit setup_memc(struct fb_info *fbi)
+static void setup_memc(struct fb_info *fbi)
{
unsigned long tmp;
int i;
@@ -747,7 +747,7 @@ static void enable_clocks(struct fb_info *fbi)
write_reg_dly(0x00000001, PIXCLKDIV);
}
-static void __devinit setup_graphics(struct fb_info *fbi)
+static void setup_graphics(struct fb_info *fbi)
{
unsigned long gsctrl;
unsigned long vscadr;
@@ -781,7 +781,7 @@ static void __devinit setup_graphics(struct fb_info *fbi)
write_reg_dly(vscadr, VSCADR);
}
-static void __devinit setup_display(struct fb_info *fbi)
+static void setup_display(struct fb_info *fbi)
{
unsigned long dsctrl = 0;
@@ -795,7 +795,7 @@ static void __devinit setup_display(struct fb_info *fbi)
write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
}
-static void __devinit enable_controller(struct fb_info *fbi)
+static void enable_controller(struct fb_info *fbi)
{
u32 svctrl, shctrl;
@@ -881,7 +881,7 @@ static int mbxfb_resume(struct platform_device *dev)
#define res_size(_r) (((_r)->end - (_r)->start) + 1)
-static int __devinit mbxfb_probe(struct platform_device *dev)
+static int mbxfb_probe(struct platform_device *dev)
{
int ret;
struct fb_info *fbi;
@@ -1006,7 +1006,7 @@ err1:
return ret;
}
-static int __devexit mbxfb_remove(struct platform_device *dev)
+static int mbxfb_remove(struct platform_device *dev)
{
struct fb_info *fbi = platform_get_drvdata(dev);
@@ -1038,7 +1038,7 @@ static int __devexit mbxfb_remove(struct platform_device *dev)
static struct platform_driver mbxfb_driver = {
.probe = mbxfb_probe,
- .remove = __devexit_p(mbxfb_remove),
+ .remove = mbxfb_remove,
.suspend = mbxfb_suspend,
.resume = mbxfb_resume,
.driver = {
diff --git a/drivers/video/metronomefb.c b/drivers/video/metronomefb.c
index 97d45e5..f30150d 100644
--- a/drivers/video/metronomefb.c
+++ b/drivers/video/metronomefb.c
@@ -99,7 +99,7 @@ static struct epd_frame epd_frame_table[] = {
},
};
-static struct fb_fix_screeninfo metronomefb_fix __devinitdata = {
+static struct fb_fix_screeninfo metronomefb_fix = {
.id = "metronomefb",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_STATIC_PSEUDOCOLOR,
@@ -110,7 +110,7 @@ static struct fb_fix_screeninfo metronomefb_fix __devinitdata = {
.accel = FB_ACCEL_NONE,
};
-static struct fb_var_screeninfo metronomefb_var __devinitdata = {
+static struct fb_var_screeninfo metronomefb_var = {
.xres = DPY_W,
.yres = DPY_H,
.xres_virtual = DPY_W,
@@ -167,8 +167,8 @@ static u16 calc_img_cksum(u16 *start, int length)
}
/* here we decode the incoming waveform file and populate metromem */
-static int __devinit load_waveform(u8 *mem, size_t size, int m, int t,
- struct metronomefb_par *par)
+static int load_waveform(u8 *mem, size_t size, int m, int t,
+ struct metronomefb_par *par)
{
int tta;
int wmta;
@@ -338,7 +338,7 @@ static int metronome_display_cmd(struct metronomefb_par *par)
return par->board->met_wait_event_intr(par);
}
-static int __devinit metronome_powerup_cmd(struct metronomefb_par *par)
+static int metronome_powerup_cmd(struct metronomefb_par *par)
{
int i;
u16 cs;
@@ -367,7 +367,7 @@ static int __devinit metronome_powerup_cmd(struct metronomefb_par *par)
return par->board->met_wait_event(par);
}
-static int __devinit metronome_config_cmd(struct metronomefb_par *par)
+static int metronome_config_cmd(struct metronomefb_par *par)
{
/* setup config command
we can't immediately set the opcode since the controller
@@ -385,7 +385,7 @@ static int __devinit metronome_config_cmd(struct metronomefb_par *par)
return par->board->met_wait_event(par);
}
-static int __devinit metronome_init_cmd(struct metronomefb_par *par)
+static int metronome_init_cmd(struct metronomefb_par *par)
{
int i;
u16 cs;
@@ -411,7 +411,7 @@ static int __devinit metronome_init_cmd(struct metronomefb_par *par)
return par->board->met_wait_event(par);
}
-static int __devinit metronome_init_regs(struct metronomefb_par *par)
+static int metronome_init_regs(struct metronomefb_par *par)
{
int res;
@@ -569,7 +569,7 @@ static struct fb_deferred_io metronomefb_defio = {
.deferred_io = metronomefb_dpy_deferred_io,
};
-static int __devinit metronomefb_probe(struct platform_device *dev)
+static int metronomefb_probe(struct platform_device *dev)
{
struct fb_info *info;
struct metronome_board *board;
@@ -741,7 +741,7 @@ err:
return retval;
}
-static int __devexit metronomefb_remove(struct platform_device *dev)
+static int metronomefb_remove(struct platform_device *dev)
{
struct fb_info *info = platform_get_drvdata(dev);
@@ -763,7 +763,7 @@ static int __devexit metronomefb_remove(struct platform_device *dev)
static struct platform_driver metronomefb_driver = {
.probe = metronomefb_probe,
- .remove = __devexit_p(metronomefb_remove),
+ .remove = metronomefb_remove,
.driver = {
.owner = THIS_MODULE,
.name = "metronomefb",
diff --git a/drivers/video/mmp/Kconfig b/drivers/video/mmp/Kconfig
new file mode 100644
index 0000000..e9ea39e
--- /dev/null
+++ b/drivers/video/mmp/Kconfig
@@ -0,0 +1,11 @@
+menuconfig MMP_DISP
+ tristate "Marvell MMP Display Subsystem support"
+ depends on CPU_PXA910 || CPU_MMP2 || CPU_MMP3 || CPU_PXA988
+ help
+ Marvell Display Subsystem support.
+
+if MMP_DISP
+source "drivers/video/mmp/hw/Kconfig"
+source "drivers/video/mmp/panel/Kconfig"
+source "drivers/video/mmp/fb/Kconfig"
+endif
diff --git a/drivers/video/mmp/Makefile b/drivers/video/mmp/Makefile
new file mode 100644
index 0000000..a014cb3
--- /dev/null
+++ b/drivers/video/mmp/Makefile
@@ -0,0 +1 @@
+obj-y += core.o hw/ panel/ fb/
diff --git a/drivers/video/mmp/core.c b/drivers/video/mmp/core.c
new file mode 100644
index 0000000..9ed8341
--- /dev/null
+++ b/drivers/video/mmp/core.c
@@ -0,0 +1,258 @@
+/*
+ * linux/drivers/video/mmp/common.c
+ * This driver is a common framework for Marvell Display Controller
+ *
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Authors: Zhou Zhu <zzhu3@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/export.h>
+#include <video/mmp_disp.h>
+
+static struct mmp_overlay *path_get_overlay(struct mmp_path *path,
+ int overlay_id)
+{
+ if (path && overlay_id < path->overlay_num)
+ return &path->overlays[overlay_id];
+ return 0;
+}
+
+static int path_check_status(struct mmp_path *path)
+{
+ int i;
+ for (i = 0; i < path->overlay_num; i++)
+ if (path->overlays[i].status)
+ return 1;
+
+ return 0;
+}
+
+/*
+ * Get modelist write pointer of modelist.
+ * It also returns modelist number
+ * this function fetches modelist from phy/panel:
+ * for HDMI/parallel or dsi to hdmi cases, get from phy
+ * or get from panel
+ */
+static int path_get_modelist(struct mmp_path *path,
+ struct mmp_mode **modelist)
+{
+ BUG_ON(!path || !modelist);
+
+ if (path->panel && path->panel->get_modelist)
+ return path->panel->get_modelist(path->panel, modelist);
+
+ return 0;
+}
+
+/*
+ * panel list is used to pair panel/path when path/panel registered
+ * path list is used for both buffer driver and platdriver
+ * plat driver do path register/unregister
+ * panel driver do panel register/unregister
+ * buffer driver get registered path
+ */
+static LIST_HEAD(panel_list);
+static LIST_HEAD(path_list);
+static DEFINE_MUTEX(disp_lock);
+
+/*
+ * mmp_register_panel - register panel to panel_list and connect to path
+ * @p: panel to be registered
+ *
+ * this function provides interface for panel drivers to register panel
+ * to panel_list and connect to path which matchs panel->plat_path_name.
+ * no error returns when no matching path is found as path register after
+ * panel register is permitted.
+ */
+void mmp_register_panel(struct mmp_panel *panel)
+{
+ struct mmp_path *path;
+
+ mutex_lock(&disp_lock);
+
+ /* add */
+ list_add_tail(&panel->node, &panel_list);
+
+ /* try to register to path */
+ list_for_each_entry(path, &path_list, node) {
+ if (!strcmp(panel->plat_path_name, path->name)) {
+ dev_info(panel->dev, "connect to path %s\n",
+ path->name);
+ path->panel = panel;
+ break;
+ }
+ }
+
+ mutex_unlock(&disp_lock);
+}
+EXPORT_SYMBOL_GPL(mmp_register_panel);
+
+/*
+ * mmp_unregister_panel - unregister panel from panel_list and disconnect
+ * @p: panel to be unregistered
+ *
+ * this function provides interface for panel drivers to unregister panel
+ * from panel_list and disconnect from path.
+ */
+void mmp_unregister_panel(struct mmp_panel *panel)
+{
+ struct mmp_path *path;
+
+ mutex_lock(&disp_lock);
+ list_del(&panel->node);
+
+ list_for_each_entry(path, &path_list, node) {
+ if (path->panel && path->panel == panel) {
+ dev_info(panel->dev, "disconnect from path %s\n",
+ path->name);
+ path->panel = NULL;
+ break;
+ }
+ }
+ mutex_unlock(&disp_lock);
+}
+EXPORT_SYMBOL_GPL(mmp_unregister_panel);
+
+/*
+ * mmp_get_path - get path by name
+ * @p: path name
+ *
+ * this function checks path name in path_list and return matching path
+ * return NULL if no matching path
+ */
+struct mmp_path *mmp_get_path(const char *name)
+{
+ struct mmp_path *path;
+ int found = 0;
+
+ mutex_lock(&disp_lock);
+ list_for_each_entry(path, &path_list, node) {
+ if (!strcmp(name, path->name)) {
+ found = 1;
+ break;
+ }
+ }
+ mutex_unlock(&disp_lock);
+
+ return found ? path : NULL;
+}
+EXPORT_SYMBOL_GPL(mmp_get_path);
+
+/*
+ * mmp_register_path - init and register path by path_info
+ * @p: path info provided by display controller
+ *
+ * this function init by path info and register path to path_list
+ * this function also try to connect path with panel by name
+ */
+struct mmp_path *mmp_register_path(struct mmp_path_info *info)
+{
+ int i;
+ size_t size;
+ struct mmp_path *path = NULL;
+ struct mmp_panel *panel;
+
+ size = sizeof(struct mmp_path)
+ + sizeof(struct mmp_overlay) * info->overlay_num;
+ path = kzalloc(size, GFP_KERNEL);
+ if (!path)
+ goto failed;
+
+ /* path set */
+ mutex_init(&path->access_ok);
+ path->dev = info->dev;
+ path->id = info->id;
+ path->name = info->name;
+ path->output_type = info->output_type;
+ path->overlay_num = info->overlay_num;
+ path->plat_data = info->plat_data;
+ path->ops.set_mode = info->set_mode;
+
+ mutex_lock(&disp_lock);
+ /* get panel */
+ list_for_each_entry(panel, &panel_list, node) {
+ if (!strcmp(info->name, panel->plat_path_name)) {
+ dev_info(path->dev, "get panel %s\n", panel->name);
+ path->panel = panel;
+ break;
+ }
+ }
+
+ dev_info(path->dev, "register %s, overlay_num %d\n",
+ path->name, path->overlay_num);
+
+ /* default op set: if already set by driver, never cover it */
+ if (!path->ops.check_status)
+ path->ops.check_status = path_check_status;
+ if (!path->ops.get_overlay)
+ path->ops.get_overlay = path_get_overlay;
+ if (!path->ops.get_modelist)
+ path->ops.get_modelist = path_get_modelist;
+
+ /* step3: init overlays */
+ for (i = 0; i < path->overlay_num; i++) {
+ path->overlays[i].path = path;
+ path->overlays[i].id = i;
+ mutex_init(&path->overlays[i].access_ok);
+ path->overlays[i].ops = info->overlay_ops;
+ }
+
+ /* add to pathlist */
+ list_add_tail(&path->node, &path_list);
+
+ mutex_unlock(&disp_lock);
+ return path;
+
+failed:
+ kfree(path);
+ mutex_unlock(&disp_lock);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(mmp_register_path);
+
+/*
+ * mmp_unregister_path - unregister and destory path
+ * @p: path to be destoried.
+ *
+ * this function registers path and destorys it.
+ */
+void mmp_unregister_path(struct mmp_path *path)
+{
+ int i;
+
+ if (!path)
+ return;
+
+ mutex_lock(&disp_lock);
+ /* del from pathlist */
+ list_del(&path->node);
+
+ /* deinit overlays */
+ for (i = 0; i < path->overlay_num; i++)
+ mutex_destroy(&path->overlays[i].access_ok);
+
+ mutex_destroy(&path->access_ok);
+
+ kfree(path);
+ mutex_unlock(&disp_lock);
+
+ dev_info(path->dev, "de-register %s\n", path->name);
+}
+EXPORT_SYMBOL_GPL(mmp_unregister_path);
diff --git a/drivers/video/mmp/fb/Kconfig b/drivers/video/mmp/fb/Kconfig
new file mode 100644
index 0000000..9b0141f
--- /dev/null
+++ b/drivers/video/mmp/fb/Kconfig
@@ -0,0 +1,13 @@
+if MMP_DISP
+
+config MMP_FB
+ bool "fb driver for Marvell MMP Display Subsystem"
+ depends on FB
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ default y
+ help
+ fb driver for Marvell MMP Display Subsystem
+
+endif
diff --git a/drivers/video/mmp/fb/Makefile b/drivers/video/mmp/fb/Makefile
new file mode 100644
index 0000000..709fd1f
--- /dev/null
+++ b/drivers/video/mmp/fb/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MMP_FB) += mmpfb.o
diff --git a/drivers/video/mmp/fb/mmpfb.c b/drivers/video/mmp/fb/mmpfb.c
new file mode 100644
index 0000000..6d1fa96
--- /dev/null
+++ b/drivers/video/mmp/fb/mmpfb.c
@@ -0,0 +1,685 @@
+/*
+ * linux/drivers/video/mmp/fb/mmpfb.c
+ * Framebuffer driver for Marvell Display controller.
+ *
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Authors: Zhou Zhu <zzhu3@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include "mmpfb.h"
+
+static int var_to_pixfmt(struct fb_var_screeninfo *var)
+{
+ /*
+ * Pseudocolor mode?
+ */
+ if (var->bits_per_pixel == 8)
+ return PIXFMT_PSEUDOCOLOR;
+
+ /*
+ * Check for YUV422PLANAR.
+ */
+ if (var->bits_per_pixel == 16 && var->red.length == 8 &&
+ var->green.length == 4 && var->blue.length == 4) {
+ if (var->green.offset >= var->blue.offset)
+ return PIXFMT_YUV422P;
+ else
+ return PIXFMT_YVU422P;
+ }
+
+ /*
+ * Check for YUV420PLANAR.
+ */
+ if (var->bits_per_pixel == 12 && var->red.length == 8 &&
+ var->green.length == 2 && var->blue.length == 2) {
+ if (var->green.offset >= var->blue.offset)
+ return PIXFMT_YUV420P;
+ else
+ return PIXFMT_YVU420P;
+ }
+
+ /*
+ * Check for YUV422PACK.
+ */
+ if (var->bits_per_pixel == 16 && var->red.length == 16 &&
+ var->green.length == 16 && var->blue.length == 16) {
+ if (var->red.offset == 0)
+ return PIXFMT_YUYV;
+ else if (var->green.offset >= var->blue.offset)
+ return PIXFMT_UYVY;
+ else
+ return PIXFMT_VYUY;
+ }
+
+ /*
+ * Check for 565/1555.
+ */
+ if (var->bits_per_pixel == 16 && var->red.length <= 5 &&
+ var->green.length <= 6 && var->blue.length <= 5) {
+ if (var->transp.length == 0) {
+ if (var->red.offset >= var->blue.offset)
+ return PIXFMT_RGB565;
+ else
+ return PIXFMT_BGR565;
+ }
+ }
+
+ /*
+ * Check for 888/A888.
+ */
+ if (var->bits_per_pixel <= 32 && var->red.length <= 8 &&
+ var->green.length <= 8 && var->blue.length <= 8) {
+ if (var->bits_per_pixel == 24 && var->transp.length == 0) {
+ if (var->red.offset >= var->blue.offset)
+ return PIXFMT_RGB888PACK;
+ else
+ return PIXFMT_BGR888PACK;
+ }
+
+ if (var->bits_per_pixel == 32 && var->transp.offset == 24) {
+ if (var->red.offset >= var->blue.offset)
+ return PIXFMT_RGBA888;
+ else
+ return PIXFMT_BGRA888;
+ } else {
+ if (var->red.offset >= var->blue.offset)
+ return PIXFMT_RGB888UNPACK;
+ else
+ return PIXFMT_BGR888UNPACK;
+ }
+
+ /* fall through */
+ }
+
+ return -EINVAL;
+}
+
+static void pixfmt_to_var(struct fb_var_screeninfo *var, int pix_fmt)
+{
+ switch (pix_fmt) {
+ case PIXFMT_RGB565:
+ var->bits_per_pixel = 16;
+ var->red.offset = 11; var->red.length = 5;
+ var->green.offset = 5; var->green.length = 6;
+ var->blue.offset = 0; var->blue.length = 5;
+ var->transp.offset = 0; var->transp.length = 0;
+ break;
+ case PIXFMT_BGR565:
+ var->bits_per_pixel = 16;
+ var->red.offset = 0; var->red.length = 5;
+ var->green.offset = 5; var->green.length = 6;
+ var->blue.offset = 11; var->blue.length = 5;
+ var->transp.offset = 0; var->transp.length = 0;
+ break;
+ case PIXFMT_RGB888UNPACK:
+ var->bits_per_pixel = 32;
+ var->red.offset = 16; var->red.length = 8;
+ var->green.offset = 8; var->green.length = 8;
+ var->blue.offset = 0; var->blue.length = 8;
+ var->transp.offset = 0; var->transp.length = 0;
+ break;
+ case PIXFMT_BGR888UNPACK:
+ var->bits_per_pixel = 32;
+ var->red.offset = 0; var->red.length = 8;
+ var->green.offset = 8; var->green.length = 8;
+ var->blue.offset = 16; var->blue.length = 8;
+ var->transp.offset = 0; var->transp.length = 0;
+ break;
+ case PIXFMT_RGBA888:
+ var->bits_per_pixel = 32;
+ var->red.offset = 16; var->red.length = 8;
+ var->green.offset = 8; var->green.length = 8;
+ var->blue.offset = 0; var->blue.length = 8;
+ var->transp.offset = 24; var->transp.length = 8;
+ break;
+ case PIXFMT_BGRA888:
+ var->bits_per_pixel = 32;
+ var->red.offset = 0; var->red.length = 8;
+ var->green.offset = 8; var->green.length = 8;
+ var->blue.offset = 16; var->blue.length = 8;
+ var->transp.offset = 24; var->transp.length = 8;
+ break;
+ case PIXFMT_RGB888PACK:
+ var->bits_per_pixel = 24;
+ var->red.offset = 16; var->red.length = 8;
+ var->green.offset = 8; var->green.length = 8;
+ var->blue.offset = 0; var->blue.length = 8;
+ var->transp.offset = 0; var->transp.length = 0;
+ break;
+ case PIXFMT_BGR888PACK:
+ var->bits_per_pixel = 24;
+ var->red.offset = 0; var->red.length = 8;
+ var->green.offset = 8; var->green.length = 8;
+ var->blue.offset = 16; var->blue.length = 8;
+ var->transp.offset = 0; var->transp.length = 0;
+ break;
+ case PIXFMT_YUV420P:
+ var->bits_per_pixel = 12;
+ var->red.offset = 4; var->red.length = 8;
+ var->green.offset = 2; var->green.length = 2;
+ var->blue.offset = 0; var->blue.length = 2;
+ var->transp.offset = 0; var->transp.length = 0;
+ break;
+ case PIXFMT_YVU420P:
+ var->bits_per_pixel = 12;
+ var->red.offset = 4; var->red.length = 8;
+ var->green.offset = 0; var->green.length = 2;
+ var->blue.offset = 2; var->blue.length = 2;
+ var->transp.offset = 0; var->transp.length = 0;
+ break;
+ case PIXFMT_YUV422P:
+ var->bits_per_pixel = 16;
+ var->red.offset = 8; var->red.length = 8;
+ var->green.offset = 4; var->green.length = 4;
+ var->blue.offset = 0; var->blue.length = 4;
+ var->transp.offset = 0; var->transp.length = 0;
+ break;
+ case PIXFMT_YVU422P:
+ var->bits_per_pixel = 16;
+ var->red.offset = 8; var->red.length = 8;
+ var->green.offset = 0; var->green.length = 4;
+ var->blue.offset = 4; var->blue.length = 4;
+ var->transp.offset = 0; var->transp.length = 0;
+ break;
+ case PIXFMT_UYVY:
+ var->bits_per_pixel = 16;
+ var->red.offset = 8; var->red.length = 16;
+ var->green.offset = 4; var->green.length = 16;
+ var->blue.offset = 0; var->blue.length = 16;
+ var->transp.offset = 0; var->transp.length = 0;
+ break;
+ case PIXFMT_VYUY:
+ var->bits_per_pixel = 16;
+ var->red.offset = 8; var->red.length = 16;
+ var->green.offset = 0; var->green.length = 16;
+ var->blue.offset = 4; var->blue.length = 16;
+ var->transp.offset = 0; var->transp.length = 0;
+ break;
+ case PIXFMT_YUYV:
+ var->bits_per_pixel = 16;
+ var->red.offset = 0; var->red.length = 16;
+ var->green.offset = 4; var->green.length = 16;
+ var->blue.offset = 8; var->blue.length = 16;
+ var->transp.offset = 0; var->transp.length = 0;
+ break;
+ case PIXFMT_PSEUDOCOLOR:
+ var->bits_per_pixel = 8;
+ var->red.offset = 0; var->red.length = 8;
+ var->green.offset = 0; var->green.length = 8;
+ var->blue.offset = 0; var->blue.length = 8;
+ var->transp.offset = 0; var->transp.length = 0;
+ break;
+ }
+}
+
+/*
+ * fb framework has its limitation:
+ * 1. input color/output color is not seprated
+ * 2. fb_videomode not include output color
+ * so for fb usage, we keep a output format which is not changed
+ * then it's added for mmpmode
+ */
+static void fbmode_to_mmpmode(struct mmp_mode *mode,
+ struct fb_videomode *videomode, int output_fmt)
+{
+ u64 div_result = 1000000000000ll;
+ mode->name = videomode->name;
+ mode->refresh = videomode->refresh;
+ mode->xres = videomode->xres;
+ mode->yres = videomode->yres;
+
+ do_div(div_result, videomode->pixclock);
+ mode->pixclock_freq = (u32)div_result;
+
+ mode->left_margin = videomode->left_margin;
+ mode->right_margin = videomode->right_margin;
+ mode->upper_margin = videomode->upper_margin;
+ mode->lower_margin = videomode->lower_margin;
+ mode->hsync_len = videomode->hsync_len;
+ mode->vsync_len = videomode->vsync_len;
+ mode->hsync_invert = !!(videomode->sync & FB_SYNC_HOR_HIGH_ACT);
+ mode->vsync_invert = !!(videomode->sync & FB_SYNC_VERT_HIGH_ACT);
+ /* no defined flag in fb, use vmode>>3*/
+ mode->invert_pixclock = !!(videomode->vmode & 8);
+ mode->pix_fmt_out = output_fmt;
+}
+
+static void mmpmode_to_fbmode(struct fb_videomode *videomode,
+ struct mmp_mode *mode)
+{
+ u64 div_result = 1000000000000ll;
+
+ videomode->name = mode->name;
+ videomode->refresh = mode->refresh;
+ videomode->xres = mode->xres;
+ videomode->yres = mode->yres;
+
+ do_div(div_result, mode->pixclock_freq);
+ videomode->pixclock = (u32)div_result;
+
+ videomode->left_margin = mode->left_margin;
+ videomode->right_margin = mode->right_margin;
+ videomode->upper_margin = mode->upper_margin;
+ videomode->lower_margin = mode->lower_margin;
+ videomode->hsync_len = mode->hsync_len;
+ videomode->vsync_len = mode->vsync_len;
+ videomode->sync = (mode->hsync_invert ? FB_SYNC_HOR_HIGH_ACT : 0)
+ | (mode->vsync_invert ? FB_SYNC_VERT_HIGH_ACT : 0);
+ videomode->vmode = mode->invert_pixclock ? 8 : 0;
+}
+
+static int mmpfb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct mmpfb_info *fbi = info->par;
+
+ if (var->bits_per_pixel == 8)
+ return -EINVAL;
+ /*
+ * Basic geometry sanity checks.
+ */
+ if (var->xoffset + var->xres > var->xres_virtual)
+ return -EINVAL;
+ if (var->yoffset + var->yres > var->yres_virtual)
+ return -EINVAL;
+
+ /*
+ * Check size of framebuffer.
+ */
+ if (var->xres_virtual * var->yres_virtual *
+ (var->bits_per_pixel >> 3) > fbi->fb_size)
+ return -EINVAL;
+
+ return 0;
+}
+
+static unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
+{
+ return ((chan & 0xffff) >> (16 - bf->length)) << bf->offset;
+}
+
+static u32 to_rgb(u16 red, u16 green, u16 blue)
+{
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+
+ return (red << 16) | (green << 8) | blue;
+}
+
+static int mmpfb_setcolreg(unsigned int regno, unsigned int red,
+ unsigned int green, unsigned int blue,
+ unsigned int trans, struct fb_info *info)
+{
+ struct mmpfb_info *fbi = info->par;
+ u32 val;
+
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR && regno < 16) {
+ val = chan_to_field(red, &info->var.red);
+ val |= chan_to_field(green, &info->var.green);
+ val |= chan_to_field(blue , &info->var.blue);
+ fbi->pseudo_palette[regno] = val;
+ }
+
+ if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR && regno < 256) {
+ val = to_rgb(red, green, blue);
+ /* TODO */
+ }
+
+ return 0;
+}
+
+static int mmpfb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct mmpfb_info *fbi = info->par;
+ struct mmp_addr addr;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.phys[0] = (var->yoffset * var->xres_virtual + var->xoffset)
+ * var->bits_per_pixel / 8 + fbi->fb_start_dma;
+ mmp_overlay_set_addr(fbi->overlay, &addr);
+
+ return 0;
+}
+
+static int var_update(struct fb_info *info)
+{
+ struct mmpfb_info *fbi = info->par;
+ struct fb_var_screeninfo *var = &info->var;
+ struct fb_videomode *m;
+ int pix_fmt;
+
+ /* set pix_fmt */
+ pix_fmt = var_to_pixfmt(var);
+ if (pix_fmt < 0)
+ return -EINVAL;
+ pixfmt_to_var(var, pix_fmt);
+ fbi->pix_fmt = pix_fmt;
+
+ /* set var according to best video mode*/
+ m = (struct fb_videomode *)fb_match_mode(var, &info->modelist);
+ if (!m) {
+ dev_err(fbi->dev, "set par: no match mode, use best mode\n");
+ m = (struct fb_videomode *)fb_find_best_mode(var,
+ &info->modelist);
+ fb_videomode_to_var(var, m);
+ }
+ memcpy(&fbi->mode, m, sizeof(struct fb_videomode));
+
+ /* fix to 2* yres */
+ var->yres_virtual = var->yres * 2;
+ info->fix.visual = (pix_fmt == PIXFMT_PSEUDOCOLOR) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+ info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
+ info->fix.ypanstep = var->yres;
+ return 0;
+}
+
+static int mmpfb_set_par(struct fb_info *info)
+{
+ struct mmpfb_info *fbi = info->par;
+ struct fb_var_screeninfo *var = &info->var;
+ struct mmp_addr addr;
+ struct mmp_win win;
+ struct mmp_mode mode;
+ int ret;
+
+ ret = var_update(info);
+ if (ret != 0)
+ return ret;
+
+ /* set window/path according to new videomode */
+ fbmode_to_mmpmode(&mode, &fbi->mode, fbi->output_fmt);
+ mmp_path_set_mode(fbi->path, &mode);
+
+ memset(&win, 0, sizeof(win));
+ win.xsrc = win.xdst = fbi->mode.xres;
+ win.ysrc = win.ydst = fbi->mode.yres;
+ win.pix_fmt = fbi->pix_fmt;
+ mmp_overlay_set_win(fbi->overlay, &win);
+
+ /* set address always */
+ memset(&addr, 0, sizeof(addr));
+ addr.phys[0] = (var->yoffset * var->xres_virtual + var->xoffset)
+ * var->bits_per_pixel / 8 + fbi->fb_start_dma;
+ mmp_overlay_set_addr(fbi->overlay, &addr);
+
+ return 0;
+}
+
+static void mmpfb_power(struct mmpfb_info *fbi, int power)
+{
+ struct mmp_addr addr;
+ struct mmp_win win;
+ struct fb_var_screeninfo *var = &fbi->fb_info->var;
+
+ /* for power on, always set address/window again */
+ if (power) {
+ memset(&win, 0, sizeof(win));
+ win.xsrc = win.xdst = fbi->mode.xres;
+ win.ysrc = win.ydst = fbi->mode.yres;
+ win.pix_fmt = fbi->pix_fmt;
+ mmp_overlay_set_win(fbi->overlay, &win);
+
+ /* set address always */
+ memset(&addr, 0, sizeof(addr));
+ addr.phys[0] = fbi->fb_start_dma +
+ (var->yoffset * var->xres_virtual + var->xoffset)
+ * var->bits_per_pixel / 8;
+ mmp_overlay_set_addr(fbi->overlay, &addr);
+ }
+ mmp_overlay_set_onoff(fbi->overlay, power);
+}
+
+static int mmpfb_blank(int blank, struct fb_info *info)
+{
+ struct mmpfb_info *fbi = info->par;
+
+ mmpfb_power(fbi, (blank == FB_BLANK_UNBLANK));
+
+ return 0;
+}
+
+static struct fb_ops mmpfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_blank = mmpfb_blank,
+ .fb_check_var = mmpfb_check_var,
+ .fb_set_par = mmpfb_set_par,
+ .fb_setcolreg = mmpfb_setcolreg,
+ .fb_pan_display = mmpfb_pan_display,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+static int modes_setup(struct mmpfb_info *fbi)
+{
+ struct fb_videomode *videomodes;
+ struct mmp_mode *mmp_modes;
+ struct fb_info *info = fbi->fb_info;
+ int videomode_num, i;
+
+ /* get videomodes from path */
+ videomode_num = mmp_path_get_modelist(fbi->path, &mmp_modes);
+ if (!videomode_num) {
+ dev_warn(fbi->dev, "can't get videomode num\n");
+ return 0;
+ }
+ /* put videomode list to info structure */
+ videomodes = kzalloc(sizeof(struct fb_videomode) * videomode_num,
+ GFP_KERNEL);
+ if (!videomodes) {
+ dev_err(fbi->dev, "can't malloc video modes\n");
+ return -ENOMEM;
+ }
+ for (i = 0; i < videomode_num; i++)
+ mmpmode_to_fbmode(&videomodes[i], &mmp_modes[i]);
+ fb_videomode_to_modelist(videomodes, videomode_num, &info->modelist);
+
+ /* set videomode[0] as default mode */
+ memcpy(&fbi->mode, &videomodes[0], sizeof(struct fb_videomode));
+ fbi->output_fmt = mmp_modes[0].pix_fmt_out;
+ fb_videomode_to_var(&info->var, &fbi->mode);
+ mmp_path_set_mode(fbi->path, &mmp_modes[0]);
+
+ kfree(videomodes);
+ return videomode_num;
+}
+
+static int fb_info_setup(struct fb_info *info,
+ struct mmpfb_info *fbi)
+{
+ int ret = 0;
+ /* Initialise static fb parameters.*/
+ info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK |
+ FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
+ info->node = -1;
+ strcpy(info->fix.id, fbi->name);
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.type_aux = 0;
+ info->fix.xpanstep = 0;
+ info->fix.ypanstep = info->var.yres;
+ info->fix.ywrapstep = 0;
+ info->fix.accel = FB_ACCEL_NONE;
+ info->fix.smem_start = fbi->fb_start_dma;
+ info->fix.smem_len = fbi->fb_size;
+ info->fix.visual = (fbi->pix_fmt == PIXFMT_PSEUDOCOLOR) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+ info->fix.line_length = info->var.xres_virtual *
+ info->var.bits_per_pixel / 8;
+ info->fbops = &mmpfb_ops;
+ info->pseudo_palette = fbi->pseudo_palette;
+ info->screen_base = fbi->fb_start;
+ info->screen_size = fbi->fb_size;
+
+ /* For FB framework: Allocate color map and Register framebuffer*/
+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0)
+ ret = -ENOMEM;
+
+ return ret;
+}
+
+static void fb_info_clear(struct fb_info *info)
+{
+ fb_dealloc_cmap(&info->cmap);
+}
+
+static int mmpfb_probe(struct platform_device *pdev)
+{
+ struct mmp_buffer_driver_mach_info *mi;
+ struct fb_info *info = 0;
+ struct mmpfb_info *fbi = 0;
+ int ret, modes_num;
+
+ mi = pdev->dev.platform_data;
+ if (mi == NULL) {
+ dev_err(&pdev->dev, "no platform data defined\n");
+ return -EINVAL;
+ }
+
+ /* initialize fb */
+ info = framebuffer_alloc(sizeof(struct mmpfb_info), &pdev->dev);
+ if (info == NULL)
+ return -ENOMEM;
+ fbi = info->par;
+ if (!fbi) {
+ ret = -EINVAL;
+ goto failed;
+ }
+
+ /* init fb */
+ fbi->fb_info = info;
+ platform_set_drvdata(pdev, fbi);
+ fbi->dev = &pdev->dev;
+ fbi->name = mi->name;
+ fbi->pix_fmt = mi->default_pixfmt;
+ pixfmt_to_var(&info->var, fbi->pix_fmt);
+ mutex_init(&fbi->access_ok);
+
+ /* get display path by name */
+ fbi->path = mmp_get_path(mi->path_name);
+ if (!fbi->path) {
+ dev_err(&pdev->dev, "can't get the path %s\n", mi->path_name);
+ ret = -EINVAL;
+ goto failed_destroy_mutex;
+ }
+
+ dev_info(fbi->dev, "path %s get\n", fbi->path->name);
+
+ /* get overlay */
+ fbi->overlay = mmp_path_get_overlay(fbi->path, mi->overlay_id);
+ if (!fbi->overlay) {
+ ret = -EINVAL;
+ goto failed_destroy_mutex;
+ }
+ /* set fetch used */
+ mmp_overlay_set_fetch(fbi->overlay, mi->dmafetch_id);
+
+ modes_num = modes_setup(fbi);
+ if (modes_num < 0) {
+ ret = modes_num;
+ goto failed_destroy_mutex;
+ }
+
+ /*
+ * if get modes success, means not hotplug panels, use caculated buffer
+ * or use default size
+ */
+ if (modes_num > 0) {
+ /* fix to 2* yres */
+ info->var.yres_virtual = info->var.yres * 2;
+
+ /* Allocate framebuffer memory: size = modes xy *4 */
+ fbi->fb_size = info->var.xres_virtual * info->var.yres_virtual
+ * info->var.bits_per_pixel / 8;
+ } else {
+ fbi->fb_size = MMPFB_DEFAULT_SIZE;
+ }
+
+ fbi->fb_start = dma_alloc_coherent(&pdev->dev, PAGE_ALIGN(fbi->fb_size),
+ &fbi->fb_start_dma, GFP_KERNEL);
+ if (fbi->fb_start == NULL) {
+ dev_err(&pdev->dev, "can't alloc framebuffer\n");
+ ret = -ENOMEM;
+ goto failed_destroy_mutex;
+ }
+ memset(fbi->fb_start, 0, fbi->fb_size);
+ dev_info(fbi->dev, "fb %dk allocated\n", fbi->fb_size/1024);
+
+ /* fb power on */
+ if (modes_num > 0)
+ mmpfb_power(fbi, 1);
+
+ ret = fb_info_setup(info, fbi);
+ if (ret < 0)
+ goto failed_free_buff;
+
+ ret = register_framebuffer(info);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to register fb: %d\n", ret);
+ ret = -ENXIO;
+ goto failed_clear_info;
+ }
+
+ dev_info(fbi->dev, "loaded to /dev/fb%d <%s>.\n",
+ info->node, info->fix.id);
+
+#ifdef CONFIG_LOGO
+ if (fbi->fb_start) {
+ fb_prepare_logo(info, 0);
+ fb_show_logo(info, 0);
+ }
+#endif
+
+ return 0;
+
+failed_clear_info:
+ fb_info_clear(info);
+failed_free_buff:
+ dma_free_coherent(&pdev->dev, PAGE_ALIGN(fbi->fb_size), fbi->fb_start,
+ fbi->fb_start_dma);
+failed_destroy_mutex:
+ mutex_destroy(&fbi->access_ok);
+failed:
+ dev_err(fbi->dev, "mmp-fb: frame buffer device init failed\n");
+ platform_set_drvdata(pdev, NULL);
+
+ framebuffer_release(info);
+
+ return ret;
+}
+
+static struct platform_driver mmpfb_driver = {
+ .driver = {
+ .name = "mmp-fb",
+ .owner = THIS_MODULE,
+ },
+ .probe = mmpfb_probe,
+};
+
+static int mmpfb_init(void)
+{
+ return platform_driver_register(&mmpfb_driver);
+}
+module_init(mmpfb_init);
+
+MODULE_AUTHOR("Zhou Zhu <zhou.zhu@marvell.com>");
+MODULE_DESCRIPTION("Framebuffer driver for Marvell displays");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/mmp/fb/mmpfb.h b/drivers/video/mmp/fb/mmpfb.h
new file mode 100644
index 0000000..88c23c1
--- /dev/null
+++ b/drivers/video/mmp/fb/mmpfb.h
@@ -0,0 +1,54 @@
+/*
+ * linux/drivers/video/mmp/fb/mmpfb.h
+ * Framebuffer driver for Marvell Display controller.
+ *
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Authors: Zhou Zhu <zzhu3@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef _MMP_FB_H_
+#define _MMP_FB_H_
+
+#include <video/mmp_disp.h>
+#include <linux/fb.h>
+
+/* LCD controller private state. */
+struct mmpfb_info {
+ struct device *dev;
+ int id;
+ const char *name;
+
+ struct fb_info *fb_info;
+ /* basicaly videomode is for output */
+ struct fb_videomode mode;
+ int pix_fmt;
+
+ void *fb_start;
+ int fb_size;
+ dma_addr_t fb_start_dma;
+
+ struct mmp_overlay *overlay;
+ struct mmp_path *path;
+
+ struct mutex access_ok;
+
+ unsigned int pseudo_palette[16];
+ int output_fmt;
+};
+
+#define MMPFB_DEFAULT_SIZE (PAGE_ALIGN(1920 * 1080 * 4 * 2))
+#endif /* _MMP_FB_H_ */
diff --git a/drivers/video/mmp/hw/Kconfig b/drivers/video/mmp/hw/Kconfig
new file mode 100644
index 0000000..02f109a
--- /dev/null
+++ b/drivers/video/mmp/hw/Kconfig
@@ -0,0 +1,20 @@
+if MMP_DISP
+
+config MMP_DISP_CONTROLLER
+ bool "mmp display controller hw support"
+ depends on CPU_PXA910 || CPU_MMP2 || CPU_MMP3 || CPU_PXA988
+ default n
+ help
+ Marvell MMP display hw controller support
+ this controller is used on Marvell PXA910,
+ MMP2, MMP3, PXA988 chips
+
+config MMP_DISP_SPI
+ bool "mmp display controller spi port"
+ depends on MMP_DISP_CONTROLLER && SPI_MASTER
+ default y
+ help
+ Marvell MMP display hw controller spi port support
+ will register as a spi master for panel usage
+
+endif
diff --git a/drivers/video/mmp/hw/Makefile b/drivers/video/mmp/hw/Makefile
new file mode 100644
index 0000000..0000a71
--- /dev/null
+++ b/drivers/video/mmp/hw/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_MMP_DISP_CONTROLLER) += mmp_ctrl.o
+obj-$(CONFIG_MMP_DISP_SPI) += mmp_spi.o
diff --git a/drivers/video/mmp/hw/mmp_ctrl.c b/drivers/video/mmp/hw/mmp_ctrl.c
new file mode 100644
index 0000000..4bd31b2
--- /dev/null
+++ b/drivers/video/mmp/hw/mmp_ctrl.c
@@ -0,0 +1,591 @@
+/*
+ * linux/drivers/video/mmp/hw/mmp_ctrl.c
+ * Marvell MMP series Display Controller support
+ *
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Authors: Guoqing Li <ligq@marvell.com>
+ * Lisa Du <cldu@marvell.com>
+ * Zhou Zhu <zzhu3@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/vmalloc.h>
+#include <linux/uaccess.h>
+#include <linux/kthread.h>
+#include <linux/io.h>
+
+#include "mmp_ctrl.h"
+
+static irqreturn_t ctrl_handle_irq(int irq, void *dev_id)
+{
+ struct mmphw_ctrl *ctrl = (struct mmphw_ctrl *)dev_id;
+ u32 isr, imask, tmp;
+
+ isr = readl_relaxed(ctrl->reg_base + SPU_IRQ_ISR);
+ imask = readl_relaxed(ctrl->reg_base + SPU_IRQ_ENA);
+
+ do {
+ /* clear clock only */
+ tmp = readl_relaxed(ctrl->reg_base + SPU_IRQ_ISR);
+ if (tmp & isr)
+ writel_relaxed(~isr, ctrl->reg_base + SPU_IRQ_ISR);
+ } while ((isr = readl(ctrl->reg_base + SPU_IRQ_ISR)) & imask);
+
+ return IRQ_HANDLED;
+}
+
+static u32 fmt_to_reg(struct mmp_overlay *overlay, int pix_fmt)
+{
+ u32 link_config = path_to_path_plat(overlay->path)->link_config;
+ u32 rbswap, uvswap = 0, yuvswap = 0,
+ csc_en = 0, val = 0,
+ vid = overlay_is_vid(overlay);
+
+ switch (pix_fmt) {
+ case PIXFMT_RGB565:
+ case PIXFMT_RGB1555:
+ case PIXFMT_RGB888PACK:
+ case PIXFMT_RGB888UNPACK:
+ case PIXFMT_RGBA888:
+ rbswap = !(link_config & 0x1);
+ break;
+ case PIXFMT_VYUY:
+ case PIXFMT_YVU422P:
+ case PIXFMT_YVU420P:
+ rbswap = link_config & 0x1;
+ uvswap = 1;
+ break;
+ case PIXFMT_YUYV:
+ rbswap = link_config & 0x1;
+ yuvswap = 1;
+ break;
+ default:
+ rbswap = link_config & 0x1;
+ break;
+ }
+
+ switch (pix_fmt) {
+ case PIXFMT_RGB565:
+ case PIXFMT_BGR565:
+ val = 0;
+ break;
+ case PIXFMT_RGB1555:
+ case PIXFMT_BGR1555:
+ val = 0x1;
+ break;
+ case PIXFMT_RGB888PACK:
+ case PIXFMT_BGR888PACK:
+ val = 0x2;
+ break;
+ case PIXFMT_RGB888UNPACK:
+ case PIXFMT_BGR888UNPACK:
+ val = 0x3;
+ break;
+ case PIXFMT_RGBA888:
+ case PIXFMT_BGRA888:
+ val = 0x4;
+ break;
+ case PIXFMT_UYVY:
+ case PIXFMT_VYUY:
+ case PIXFMT_YUYV:
+ val = 0x5;
+ csc_en = 1;
+ break;
+ case PIXFMT_YUV422P:
+ case PIXFMT_YVU422P:
+ val = 0x6;
+ csc_en = 1;
+ break;
+ case PIXFMT_YUV420P:
+ case PIXFMT_YVU420P:
+ val = 0x7;
+ csc_en = 1;
+ break;
+ default:
+ break;
+ }
+
+ return (dma_palette(0) | dma_fmt(vid, val) |
+ dma_swaprb(vid, rbswap) | dma_swapuv(vid, uvswap) |
+ dma_swapyuv(vid, yuvswap) | dma_csc(vid, csc_en));
+}
+
+static void dmafetch_set_fmt(struct mmp_overlay *overlay)
+{
+ u32 tmp;
+ struct mmp_path *path = overlay->path;
+ tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id));
+ tmp &= ~dma_mask(overlay_is_vid(overlay));
+ tmp |= fmt_to_reg(overlay, overlay->win.pix_fmt);
+ writel_relaxed(tmp, ctrl_regs(path) + dma_ctrl(0, path->id));
+}
+
+static void overlay_set_win(struct mmp_overlay *overlay, struct mmp_win *win)
+{
+ struct lcd_regs *regs = path_regs(overlay->path);
+ u32 pitch;
+
+ /* assert win supported */
+ memcpy(&overlay->win, win, sizeof(struct mmp_win));
+
+ mutex_lock(&overlay->access_ok);
+ pitch = win->xsrc * pixfmt_to_stride(win->pix_fmt);
+ writel_relaxed(pitch, &regs->g_pitch);
+ writel_relaxed((win->ysrc << 16) | win->xsrc, &regs->g_size);
+ writel_relaxed((win->ydst << 16) | win->xdst, &regs->g_size_z);
+ writel_relaxed(0, &regs->g_start);
+
+ dmafetch_set_fmt(overlay);
+ mutex_unlock(&overlay->access_ok);
+}
+
+static void dmafetch_onoff(struct mmp_overlay *overlay, int on)
+{
+ u32 mask = overlay_is_vid(overlay) ? CFG_GRA_ENA_MASK :
+ CFG_DMA_ENA_MASK;
+ u32 enable = overlay_is_vid(overlay) ? CFG_GRA_ENA(1) : CFG_DMA_ENA(1);
+ u32 tmp;
+ struct mmp_path *path = overlay->path;
+
+ mutex_lock(&overlay->access_ok);
+ tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id));
+ tmp &= ~mask;
+ tmp |= (on ? enable : 0);
+ writel(tmp, ctrl_regs(path) + dma_ctrl(0, path->id));
+ mutex_unlock(&overlay->access_ok);
+}
+
+static void path_enabledisable(struct mmp_path *path, int on)
+{
+ u32 tmp;
+ mutex_lock(&path->access_ok);
+ tmp = readl_relaxed(ctrl_regs(path) + LCD_SCLK(path));
+ if (on)
+ tmp &= ~SCLK_DISABLE;
+ else
+ tmp |= SCLK_DISABLE;
+ writel_relaxed(tmp, ctrl_regs(path) + LCD_SCLK(path));
+ mutex_unlock(&path->access_ok);
+}
+
+static void path_onoff(struct mmp_path *path, int on)
+{
+ if (path->status == on) {
+ dev_info(path->dev, "path %s is already %s\n",
+ path->name, stat_name(path->status));
+ return;
+ }
+
+ if (on) {
+ path_enabledisable(path, 1);
+
+ if (path->panel && path->panel->set_onoff)
+ path->panel->set_onoff(path->panel, 1);
+ } else {
+ if (path->panel && path->panel->set_onoff)
+ path->panel->set_onoff(path->panel, 0);
+
+ path_enabledisable(path, 0);
+ }
+ path->status = on;
+}
+
+static void overlay_set_onoff(struct mmp_overlay *overlay, int on)
+{
+ if (overlay->status == on) {
+ dev_info(overlay_to_ctrl(overlay)->dev, "overlay %s is already %s\n",
+ overlay->path->name, stat_name(overlay->status));
+ return;
+ }
+ overlay->status = on;
+ dmafetch_onoff(overlay, on);
+ if (overlay->path->ops.check_status(overlay->path)
+ != overlay->path->status)
+ path_onoff(overlay->path, on);
+}
+
+static void overlay_set_fetch(struct mmp_overlay *overlay, int fetch_id)
+{
+ overlay->dmafetch_id = fetch_id;
+}
+
+static int overlay_set_addr(struct mmp_overlay *overlay, struct mmp_addr *addr)
+{
+ struct lcd_regs *regs = path_regs(overlay->path);
+
+ /* FIXME: assert addr supported */
+ memcpy(&overlay->addr, addr, sizeof(struct mmp_win));
+ writel(addr->phys[0], &regs->g_0);
+
+ return overlay->addr.phys[0];
+}
+
+static void path_set_mode(struct mmp_path *path, struct mmp_mode *mode)
+{
+ struct lcd_regs *regs = path_regs(path);
+ u32 total_x, total_y, vsync_ctrl, tmp, sclk_src, sclk_div,
+ link_config = path_to_path_plat(path)->link_config;
+
+ /* FIXME: assert videomode supported */
+ memcpy(&path->mode, mode, sizeof(struct mmp_mode));
+
+ mutex_lock(&path->access_ok);
+
+ /* polarity of timing signals */
+ tmp = readl_relaxed(ctrl_regs(path) + intf_ctrl(path->id)) & 0x1;
+ tmp |= mode->vsync_invert ? 0 : 0x8;
+ tmp |= mode->hsync_invert ? 0 : 0x4;
+ tmp |= link_config & CFG_DUMBMODE_MASK;
+ tmp |= CFG_DUMB_ENA(1);
+ writel_relaxed(tmp, ctrl_regs(path) + intf_ctrl(path->id));
+
+ writel_relaxed((mode->yres << 16) | mode->xres, &regs->screen_active);
+ writel_relaxed((mode->left_margin << 16) | mode->right_margin,
+ &regs->screen_h_porch);
+ writel_relaxed((mode->upper_margin << 16) | mode->lower_margin,
+ &regs->screen_v_porch);
+ total_x = mode->xres + mode->left_margin + mode->right_margin +
+ mode->hsync_len;
+ total_y = mode->yres + mode->upper_margin + mode->lower_margin +
+ mode->vsync_len;
+ writel_relaxed((total_y << 16) | total_x, &regs->screen_size);
+
+ /* vsync ctrl */
+ if (path->output_type == PATH_OUT_DSI)
+ vsync_ctrl = 0x01330133;
+ else
+ vsync_ctrl = ((mode->xres + mode->right_margin) << 16)
+ | (mode->xres + mode->right_margin);
+ writel_relaxed(vsync_ctrl, &regs->vsync_ctrl);
+
+ /* set pixclock div */
+ sclk_src = clk_get_rate(path_to_ctrl(path)->clk);
+ sclk_div = sclk_src / mode->pixclock_freq;
+ if (sclk_div * mode->pixclock_freq < sclk_src)
+ sclk_div++;
+
+ dev_info(path->dev, "%s sclk_src %d sclk_div 0x%x pclk %d\n",
+ __func__, sclk_src, sclk_div, mode->pixclock_freq);
+
+ tmp = readl_relaxed(ctrl_regs(path) + LCD_SCLK(path));
+ tmp &= ~CLK_INT_DIV_MASK;
+ tmp |= sclk_div;
+ writel_relaxed(tmp, ctrl_regs(path) + LCD_SCLK(path));
+
+ mutex_unlock(&path->access_ok);
+}
+
+static struct mmp_overlay_ops mmphw_overlay_ops = {
+ .set_fetch = overlay_set_fetch,
+ .set_onoff = overlay_set_onoff,
+ .set_win = overlay_set_win,
+ .set_addr = overlay_set_addr,
+};
+
+static void ctrl_set_default(struct mmphw_ctrl *ctrl)
+{
+ u32 tmp, irq_mask;
+
+ /*
+ * LCD Global control(LCD_TOP_CTRL) should be configed before
+ * any other LCD registers read/write, or there maybe issues.
+ */
+ tmp = readl_relaxed(ctrl->reg_base + LCD_TOP_CTRL);
+ tmp |= 0xfff0;
+ writel_relaxed(tmp, ctrl->reg_base + LCD_TOP_CTRL);
+
+
+ /* disable all interrupts */
+ irq_mask = path_imasks(0) | err_imask(0) |
+ path_imasks(1) | err_imask(1);
+ tmp = readl_relaxed(ctrl->reg_base + SPU_IRQ_ENA);
+ tmp &= ~irq_mask;
+ tmp |= irq_mask;
+ writel_relaxed(tmp, ctrl->reg_base + SPU_IRQ_ENA);
+}
+
+static void path_set_default(struct mmp_path *path)
+{
+ struct lcd_regs *regs = path_regs(path);
+ u32 dma_ctrl1, mask, tmp, path_config;
+
+ path_config = path_to_path_plat(path)->path_config;
+
+ /* Configure IOPAD: should be parallel only */
+ if (PATH_OUT_PARALLEL == path->output_type) {
+ mask = CFG_IOPADMODE_MASK | CFG_BURST_MASK | CFG_BOUNDARY_MASK;
+ tmp = readl_relaxed(ctrl_regs(path) + SPU_IOPAD_CONTROL);
+ tmp &= ~mask;
+ tmp |= path_config;
+ writel_relaxed(tmp, ctrl_regs(path) + SPU_IOPAD_CONTROL);
+ }
+
+ /* Select path clock source */
+ tmp = readl_relaxed(ctrl_regs(path) + LCD_SCLK(path));
+ tmp &= ~SCLK_SRC_SEL_MASK;
+ tmp |= path_config;
+ writel_relaxed(tmp, ctrl_regs(path) + LCD_SCLK(path));
+
+ /*
+ * Configure default bits: vsync triggers DMA,
+ * power save enable, configure alpha registers to
+ * display 100% graphics, and set pixel command.
+ */
+ dma_ctrl1 = 0x2032ff81;
+
+ dma_ctrl1 |= CFG_VSYNC_INV_MASK;
+ writel_relaxed(dma_ctrl1, ctrl_regs(path) + dma_ctrl(1, path->id));
+
+ /* Configure default register values */
+ writel_relaxed(0x00000000, &regs->blank_color);
+ writel_relaxed(0x00000000, &regs->g_1);
+ writel_relaxed(0x00000000, &regs->g_start);
+
+ /*
+ * 1.enable multiple burst request in DMA AXI
+ * bus arbiter for faster read if not tv path;
+ * 2.enable horizontal smooth filter;
+ */
+ if (PATH_PN == path->id) {
+ mask = CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK
+ | CFG_ARBFAST_ENA(1);
+ tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id));
+ tmp |= mask;
+ writel_relaxed(tmp, ctrl_regs(path) + dma_ctrl(0, path->id));
+ } else if (PATH_TV == path->id) {
+ mask = CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK
+ | CFG_ARBFAST_ENA(1);
+ tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id));
+ tmp &= ~mask;
+ tmp |= CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK;
+ writel_relaxed(tmp, ctrl_regs(path) + dma_ctrl(0, path->id));
+ }
+}
+
+static int path_init(struct mmphw_path_plat *path_plat,
+ struct mmp_mach_path_config *config)
+{
+ struct mmphw_ctrl *ctrl = path_plat->ctrl;
+ struct mmp_path_info *path_info;
+ struct mmp_path *path = NULL;
+
+ dev_info(ctrl->dev, "%s: %s\n", __func__, config->name);
+
+ /* init driver data */
+ path_info = kzalloc(sizeof(struct mmp_path_info), GFP_KERNEL);
+ if (!path_info) {
+ dev_err(ctrl->dev, "%s: unable to alloc path_info for %s\n",
+ __func__, config->name);
+ return 0;
+ }
+ path_info->name = config->name;
+ path_info->id = path_plat->id;
+ path_info->dev = ctrl->dev;
+ path_info->overlay_num = config->overlay_num;
+ path_info->overlay_ops = &mmphw_overlay_ops;
+ path_info->set_mode = path_set_mode;
+ path_info->plat_data = path_plat;
+
+ /* create/register platform device */
+ path = mmp_register_path(path_info);
+ if (!path) {
+ kfree(path_info);
+ return 0;
+ }
+ path_plat->path = path;
+ path_plat->path_config = config->path_config;
+ path_plat->link_config = config->link_config;
+ path_set_default(path);
+
+ kfree(path_info);
+ return 1;
+}
+
+static void path_deinit(struct mmphw_path_plat *path_plat)
+{
+ if (!path_plat)
+ return;
+
+ if (path_plat->path)
+ mmp_unregister_path(path_plat->path);
+}
+
+static int mmphw_probe(struct platform_device *pdev)
+{
+ struct mmp_mach_plat_info *mi;
+ struct resource *res;
+ int ret, i, size, irq;
+ struct mmphw_path_plat *path_plat;
+ struct mmphw_ctrl *ctrl = NULL;
+
+ /* get resources from platform data */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "%s: no IO memory defined\n", __func__);
+ ret = -ENOENT;
+ goto failed;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "%s: no IRQ defined\n", __func__);
+ ret = -ENOENT;
+ goto failed;
+ }
+
+ /* get configs from platform data */
+ mi = pdev->dev.platform_data;
+ if (mi == NULL || !mi->path_num || !mi->paths) {
+ dev_err(&pdev->dev, "%s: no platform data defined\n", __func__);
+ ret = -EINVAL;
+ goto failed;
+ }
+
+ /* allocate */
+ size = sizeof(struct mmphw_ctrl) + sizeof(struct mmphw_path_plat) *
+ mi->path_num;
+ ctrl = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
+ if (!ctrl) {
+ ret = -ENOMEM;
+ goto failed;
+ }
+
+ ctrl->name = mi->name;
+ ctrl->path_num = mi->path_num;
+ ctrl->dev = &pdev->dev;
+ ctrl->irq = irq;
+ platform_set_drvdata(pdev, ctrl);
+ mutex_init(&ctrl->access_ok);
+
+ /* map registers.*/
+ if (!devm_request_mem_region(ctrl->dev, res->start,
+ resource_size(res), ctrl->name)) {
+ dev_err(ctrl->dev,
+ "can't request region for resource %pR\n", res);
+ ret = -EINVAL;
+ goto failed;
+ }
+
+ ctrl->reg_base = devm_ioremap_nocache(ctrl->dev,
+ res->start, resource_size(res));
+ if (ctrl->reg_base == NULL) {
+ dev_err(ctrl->dev, "%s: res %x - %x map failed\n", __func__,
+ res->start, res->end);
+ ret = -ENOMEM;
+ goto failed;
+ }
+
+ /* request irq */
+ ret = devm_request_irq(ctrl->dev, ctrl->irq, ctrl_handle_irq,
+ IRQF_SHARED, "lcd_controller", ctrl);
+ if (ret < 0) {
+ dev_err(ctrl->dev, "%s unable to request IRQ %d\n",
+ __func__, ctrl->irq);
+ ret = -ENXIO;
+ goto failed;
+ }
+
+ /* get clock */
+ ctrl->clk = devm_clk_get(ctrl->dev, mi->clk_name);
+ if (IS_ERR(ctrl->clk)) {
+ dev_err(ctrl->dev, "unable to get clk %s\n", mi->clk_name);
+ ret = -ENOENT;
+ goto failed_get_clk;
+ }
+ clk_prepare_enable(ctrl->clk);
+
+ /* init global regs */
+ ctrl_set_default(ctrl);
+
+ /* init pathes from machine info and register them */
+ for (i = 0; i < ctrl->path_num; i++) {
+ /* get from config and machine info */
+ path_plat = &ctrl->path_plats[i];
+ path_plat->id = i;
+ path_plat->ctrl = ctrl;
+
+ /* path init */
+ if (!path_init(path_plat, &mi->paths[i])) {
+ ret = -EINVAL;
+ goto failed_path_init;
+ }
+ }
+
+#ifdef CONFIG_MMP_DISP_SPI
+ ret = lcd_spi_register(ctrl);
+ if (ret < 0)
+ goto failed_path_init;
+#endif
+
+ dev_info(ctrl->dev, "device init done\n");
+
+ return 0;
+
+failed_path_init:
+ for (i = 0; i < ctrl->path_num; i++) {
+ path_plat = &ctrl->path_plats[i];
+ path_deinit(path_plat);
+ }
+
+ if (ctrl->clk) {
+ devm_clk_put(ctrl->dev, ctrl->clk);
+ clk_disable_unprepare(ctrl->clk);
+ }
+failed_get_clk:
+ devm_free_irq(ctrl->dev, ctrl->irq, ctrl);
+failed:
+ if (ctrl) {
+ if (ctrl->reg_base)
+ devm_iounmap(ctrl->dev, ctrl->reg_base);
+ devm_release_mem_region(ctrl->dev, res->start,
+ resource_size(res));
+ devm_kfree(ctrl->dev, ctrl);
+ }
+
+ platform_set_drvdata(pdev, NULL);
+ dev_err(&pdev->dev, "device init failed\n");
+
+ return ret;
+}
+
+static struct platform_driver mmphw_driver = {
+ .driver = {
+ .name = "mmp-disp",
+ .owner = THIS_MODULE,
+ },
+ .probe = mmphw_probe,
+};
+
+static int mmphw_init(void)
+{
+ return platform_driver_register(&mmphw_driver);
+}
+module_init(mmphw_init);
+
+MODULE_AUTHOR("Li Guoqing<ligq@marvell.com>");
+MODULE_DESCRIPTION("Framebuffer driver for mmp");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/mmp/hw/mmp_ctrl.h b/drivers/video/mmp/hw/mmp_ctrl.h
new file mode 100644
index 0000000..6408d8e
--- /dev/null
+++ b/drivers/video/mmp/hw/mmp_ctrl.h
@@ -0,0 +1,1974 @@
+/*
+ * drivers/video/mmp/hw/mmp_ctrl.h
+ *
+ *
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Authors: Guoqing Li <ligq@marvell.com>
+ * Lisa Du <cldu@marvell.com>
+ * Zhou Zhu <zzhu3@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef _MMP_CTRL_H_
+#define _MMP_CTRL_H_
+
+#include <video/mmp_disp.h>
+
+/* ------------< LCD register >------------ */
+struct lcd_regs {
+/* TV patch register for MMP2 */
+/* 32 bit TV Video Frame0 Y Starting Address */
+#define LCD_TVD_START_ADDR_Y0 (0x0000)
+/* 32 bit TV Video Frame0 U Starting Address */
+#define LCD_TVD_START_ADDR_U0 (0x0004)
+/* 32 bit TV Video Frame0 V Starting Address */
+#define LCD_TVD_START_ADDR_V0 (0x0008)
+/* 32 bit TV Video Frame0 Command Starting Address */
+#define LCD_TVD_START_ADDR_C0 (0x000C)
+/* 32 bit TV Video Frame1 Y Starting Address Register*/
+#define LCD_TVD_START_ADDR_Y1 (0x0010)
+/* 32 bit TV Video Frame1 U Starting Address Register*/
+#define LCD_TVD_START_ADDR_U1 (0x0014)
+/* 32 bit TV Video Frame1 V Starting Address Register*/
+#define LCD_TVD_START_ADDR_V1 (0x0018)
+/* 32 bit TV Video Frame1 Command Starting Address Register*/
+#define LCD_TVD_START_ADDR_C1 (0x001C)
+/* 32 bit TV Video Y andC Line Length(Pitch)Register*/
+#define LCD_TVD_PITCH_YC (0x0020)
+/* 32 bit TV Video U andV Line Length(Pitch)Register*/
+#define LCD_TVD_PITCH_UV (0x0024)
+/* 32 bit TV Video Starting Point on Screen Register*/
+#define LCD_TVD_OVSA_HPXL_VLN (0x0028)
+/* 32 bit TV Video Source Size Register*/
+#define LCD_TVD_HPXL_VLN (0x002C)
+/* 32 bit TV Video Destination Size (After Zooming)Register*/
+#define LCD_TVDZM_HPXL_VLN (0x0030)
+ u32 v_y0;
+ u32 v_u0;
+ u32 v_v0;
+ u32 v_c0;
+ u32 v_y1;
+ u32 v_u1;
+ u32 v_v1;
+ u32 v_c1;
+ u32 v_pitch_yc; /* Video Y and C Line Length (Pitch) */
+ u32 v_pitch_uv; /* Video U and V Line Length (Pitch) */
+ u32 v_start; /* Video Starting Point on Screen */
+ u32 v_size; /* Video Source Size */
+ u32 v_size_z; /* Video Destination Size (After Zooming) */
+
+/* 32 bit TV Graphic Frame 0 Starting Address Register*/
+#define LCD_TVG_START_ADDR0 (0x0034)
+/* 32 bit TV Graphic Frame 1 Starting Address Register*/
+#define LCD_TVG_START_ADDR1 (0x0038)
+/* 32 bit TV Graphic Line Length(Pitch)Register*/
+#define LCD_TVG_PITCH (0x003C)
+/* 32 bit TV Graphic Starting Point on Screen Register*/
+#define LCD_TVG_OVSA_HPXL_VLN (0x0040)
+/* 32 bit TV Graphic Source Size Register*/
+#define LCD_TVG_HPXL_VLN (0x0044)
+/* 32 bit TV Graphic Destination size (after Zooming)Register*/
+#define LCD_TVGZM_HPXL_VLN (0x0048)
+ u32 g_0; /* Graphic Frame 0/1 Starting Address */
+ u32 g_1;
+ u32 g_pitch; /* Graphic Line Length (Pitch) */
+ u32 g_start; /* Graphic Starting Point on Screen */
+ u32 g_size; /* Graphic Source Size */
+ u32 g_size_z; /* Graphic Destination Size (After Zooming) */
+
+/* 32 bit TV Hardware Cursor Starting Point on screen Register*/
+#define LCD_TVC_OVSA_HPXL_VLN (0x004C)
+/* 32 bit TV Hardware Cursor Size Register */
+#define LCD_TVC_HPXL_VLN (0x0050)
+ u32 hc_start; /* Hardware Cursor */
+ u32 hc_size; /* Hardware Cursor */
+
+/* 32 bit TV Total Screen Size Register*/
+#define LCD_TV_V_H_TOTAL (0x0054)
+/* 32 bit TV Screen Active Size Register*/
+#define LCD_TV_V_H_ACTIVE (0x0058)
+/* 32 bit TV Screen Horizontal Porch Register*/
+#define LCD_TV_H_PORCH (0x005C)
+/* 32 bit TV Screen Vertical Porch Register*/
+#define LCD_TV_V_PORCH (0x0060)
+ u32 screen_size; /* Screen Total Size */
+ u32 screen_active; /* Screen Active Size */
+ u32 screen_h_porch; /* Screen Horizontal Porch */
+ u32 screen_v_porch; /* Screen Vertical Porch */
+
+/* 32 bit TV Screen Blank Color Register*/
+#define LCD_TV_BLANKCOLOR (0x0064)
+/* 32 bit TV Hardware Cursor Color1 Register*/
+#define LCD_TV_ALPHA_COLOR1 (0x0068)
+/* 32 bit TV Hardware Cursor Color2 Register*/
+#define LCD_TV_ALPHA_COLOR2 (0x006C)
+ u32 blank_color; /* Screen Blank Color */
+ u32 hc_Alpha_color1; /* Hardware Cursor Color1 */
+ u32 hc_Alpha_color2; /* Hardware Cursor Color2 */
+
+/* 32 bit TV Video Y Color Key Control*/
+#define LCD_TV_COLORKEY_Y (0x0070)
+/* 32 bit TV Video U Color Key Control*/
+#define LCD_TV_COLORKEY_U (0x0074)
+/* 32 bit TV Video V Color Key Control*/
+#define LCD_TV_COLORKEY_V (0x0078)
+ u32 v_colorkey_y; /* Video Y Color Key Control */
+ u32 v_colorkey_u; /* Video U Color Key Control */
+ u32 v_colorkey_v; /* Video V Color Key Control */
+
+/* 32 bit TV VSYNC PulsePixel Edge Control Register*/
+#define LCD_TV_SEPXLCNT (0x007C)
+ u32 vsync_ctrl; /* VSYNC PulsePixel Edge Control */
+};
+
+#define intf_ctrl(id) ((id) ? (((id) & 1) ? LCD_TVIF_CTRL : \
+ LCD_DUMB2_CTRL) : LCD_SPU_DUMB_CTRL)
+#define dma_ctrl0(id) ((id) ? (((id) & 1) ? LCD_TV_CTRL0 : \
+ LCD_PN2_CTRL0) : LCD_SPU_DMA_CTRL0)
+#define dma_ctrl1(id) ((id) ? (((id) & 1) ? LCD_TV_CTRL1 : \
+ LCD_PN2_CTRL1) : LCD_SPU_DMA_CTRL1)
+#define dma_ctrl(ctrl1, id) (ctrl1 ? dma_ctrl1(id) : dma_ctrl0(id))
+
+/* 32 bit TV Path DMA Control 0*/
+#define LCD_TV_CTRL0 (0x0080)
+/* 32 bit TV Path DMA Control 1*/
+#define LCD_TV_CTRL1 (0x0084)
+/* 32 bit TV Path Video Contrast*/
+#define LCD_TV_CONTRAST (0x0088)
+/* 32 bit TV Path Video Saturation*/
+#define LCD_TV_SATURATION (0x008C)
+/* 32 bit TV Path Video Hue Adjust*/
+#define LCD_TV_CBSH_HUE (0x0090)
+/* 32 bit TV Path TVIF Control Register */
+#define LCD_TVIF_CTRL (0x0094)
+#define TV_VBLNK_VALID_EN (1 << 12)
+
+/* 32 bit TV Path I/O Pad Control*/
+#define LCD_TVIOPAD_CTRL (0x0098)
+/* 32 bit TV Path Cloc Divider */
+#define LCD_TCLK_DIV (0x009C)
+
+#define LCD_SCLK(path) ((PATH_PN == path->id) ? LCD_CFG_SCLK_DIV :\
+ ((PATH_TV == path->id) ? LCD_TCLK_DIV : LCD_PN2_SCLK_DIV))
+
+/* dither configure */
+#ifdef CONFIG_CPU_PXA988
+#define LCD_DITHER_CTRL (0x01EC)
+#else
+#define LCD_DITHER_CTRL (0x00A0)
+#endif
+
+#define DITHER_TBL_INDEX_SEL(s) ((s) << 16)
+#define DITHER_MODE2(m) ((m) << 12)
+#define DITHER_MODE2_SHIFT (12)
+#define DITHER_4X8_EN2 (1 << 9)
+#define DITHER_4X8_EN2_SHIFT (9)
+#define DITHER_EN2 (1 << 8)
+#define DITHER_MODE1(m) ((m) << 4)
+#define DITHER_MODE1_SHIFT (4)
+#define DITHER_4X8_EN1 (1 << 1)
+#define DITHER_4X8_EN1_SHIFT (1)
+#define DITHER_EN1 (1)
+
+/* dither table data was fixed by video bpp of input and output*/
+#ifdef CONFIG_CPU_PXA988
+#define DITHER_TB_4X4_INDEX0 (0x6e4ca280)
+#define DITHER_TB_4X4_INDEX1 (0x5d7f91b3)
+#define DITHER_TB_4X8_INDEX0 (0xb391a280)
+#define DITHER_TB_4X8_INDEX1 (0x7f5d6e4c)
+#define DITHER_TB_4X8_INDEX2 (0x80a291b3)
+#define DITHER_TB_4X8_INDEX3 (0x4c6e5d7f)
+#define LCD_DITHER_TBL_DATA (0x01F0)
+#else
+#define DITHER_TB_4X4_INDEX0 (0x3b19f7d5)
+#define DITHER_TB_4X4_INDEX1 (0x082ac4e6)
+#define DITHER_TB_4X8_INDEX0 (0xf7d508e6)
+#define DITHER_TB_4X8_INDEX1 (0x3b194c2a)
+#define DITHER_TB_4X8_INDEX2 (0xc4e6d5f7)
+#define DITHER_TB_4X8_INDEX3 (0x082a193b)
+#define LCD_DITHER_TBL_DATA (0x00A4)
+#endif
+
+/* Video Frame 0&1 start address registers */
+#define LCD_SPU_DMA_START_ADDR_Y0 0x00C0
+#define LCD_SPU_DMA_START_ADDR_U0 0x00C4
+#define LCD_SPU_DMA_START_ADDR_V0 0x00C8
+#define LCD_CFG_DMA_START_ADDR_0 0x00CC /* Cmd address */
+#define LCD_SPU_DMA_START_ADDR_Y1 0x00D0
+#define LCD_SPU_DMA_START_ADDR_U1 0x00D4
+#define LCD_SPU_DMA_START_ADDR_V1 0x00D8
+#define LCD_CFG_DMA_START_ADDR_1 0x00DC /* Cmd address */
+
+/* YC & UV Pitch */
+#define LCD_SPU_DMA_PITCH_YC 0x00E0
+#define SPU_DMA_PITCH_C(c) ((c)<<16)
+#define SPU_DMA_PITCH_Y(y) (y)
+#define LCD_SPU_DMA_PITCH_UV 0x00E4
+#define SPU_DMA_PITCH_V(v) ((v)<<16)
+#define SPU_DMA_PITCH_U(u) (u)
+
+/* Video Starting Point on Screen Register */
+#define LCD_SPUT_DMA_OVSA_HPXL_VLN 0x00E8
+#define CFG_DMA_OVSA_VLN(y) ((y)<<16) /* 0~0xfff */
+#define CFG_DMA_OVSA_HPXL(x) (x) /* 0~0xfff */
+
+/* Video Size Register */
+#define LCD_SPU_DMA_HPXL_VLN 0x00EC
+#define CFG_DMA_VLN(y) ((y)<<16)
+#define CFG_DMA_HPXL(x) (x)
+
+/* Video Size After zooming Register */
+#define LCD_SPU_DZM_HPXL_VLN 0x00F0
+#define CFG_DZM_VLN(y) ((y)<<16)
+#define CFG_DZM_HPXL(x) (x)
+
+/* Graphic Frame 0&1 Starting Address Register */
+#define LCD_CFG_GRA_START_ADDR0 0x00F4
+#define LCD_CFG_GRA_START_ADDR1 0x00F8
+
+/* Graphic Frame Pitch */
+#define LCD_CFG_GRA_PITCH 0x00FC
+
+/* Graphic Starting Point on Screen Register */
+#define LCD_SPU_GRA_OVSA_HPXL_VLN 0x0100
+#define CFG_GRA_OVSA_VLN(y) ((y)<<16)
+#define CFG_GRA_OVSA_HPXL(x) (x)
+
+/* Graphic Size Register */
+#define LCD_SPU_GRA_HPXL_VLN 0x0104
+#define CFG_GRA_VLN(y) ((y)<<16)
+#define CFG_GRA_HPXL(x) (x)
+
+/* Graphic Size after Zooming Register */
+#define LCD_SPU_GZM_HPXL_VLN 0x0108
+#define CFG_GZM_VLN(y) ((y)<<16)
+#define CFG_GZM_HPXL(x) (x)
+
+/* HW Cursor Starting Point on Screen Register */
+#define LCD_SPU_HWC_OVSA_HPXL_VLN 0x010C
+#define CFG_HWC_OVSA_VLN(y) ((y)<<16)
+#define CFG_HWC_OVSA_HPXL(x) (x)
+
+/* HW Cursor Size */
+#define LCD_SPU_HWC_HPXL_VLN 0x0110
+#define CFG_HWC_VLN(y) ((y)<<16)
+#define CFG_HWC_HPXL(x) (x)
+
+/* Total Screen Size Register */
+#define LCD_SPUT_V_H_TOTAL 0x0114
+#define CFG_V_TOTAL(y) ((y)<<16)
+#define CFG_H_TOTAL(x) (x)
+
+/* Total Screen Active Size Register */
+#define LCD_SPU_V_H_ACTIVE 0x0118
+#define CFG_V_ACTIVE(y) ((y)<<16)
+#define CFG_H_ACTIVE(x) (x)
+
+/* Screen H&V Porch Register */
+#define LCD_SPU_H_PORCH 0x011C
+#define CFG_H_BACK_PORCH(b) ((b)<<16)
+#define CFG_H_FRONT_PORCH(f) (f)
+#define LCD_SPU_V_PORCH 0x0120
+#define CFG_V_BACK_PORCH(b) ((b)<<16)
+#define CFG_V_FRONT_PORCH(f) (f)
+
+/* Screen Blank Color Register */
+#define LCD_SPU_BLANKCOLOR 0x0124
+#define CFG_BLANKCOLOR_MASK 0x00FFFFFF
+#define CFG_BLANKCOLOR_R_MASK 0x000000FF
+#define CFG_BLANKCOLOR_G_MASK 0x0000FF00
+#define CFG_BLANKCOLOR_B_MASK 0x00FF0000
+
+/* HW Cursor Color 1&2 Register */
+#define LCD_SPU_ALPHA_COLOR1 0x0128
+#define CFG_HWC_COLOR1 0x00FFFFFF
+#define CFG_HWC_COLOR1_R(red) ((red)<<16)
+#define CFG_HWC_COLOR1_G(green) ((green)<<8)
+#define CFG_HWC_COLOR1_B(blue) (blue)
+#define CFG_HWC_COLOR1_R_MASK 0x000000FF
+#define CFG_HWC_COLOR1_G_MASK 0x0000FF00
+#define CFG_HWC_COLOR1_B_MASK 0x00FF0000
+#define LCD_SPU_ALPHA_COLOR2 0x012C
+#define CFG_HWC_COLOR2 0x00FFFFFF
+#define CFG_HWC_COLOR2_R_MASK 0x000000FF
+#define CFG_HWC_COLOR2_G_MASK 0x0000FF00
+#define CFG_HWC_COLOR2_B_MASK 0x00FF0000
+
+/* Video YUV Color Key Control */
+#define LCD_SPU_COLORKEY_Y 0x0130
+#define CFG_CKEY_Y2(y2) ((y2)<<24)
+#define CFG_CKEY_Y2_MASK 0xFF000000
+#define CFG_CKEY_Y1(y1) ((y1)<<16)
+#define CFG_CKEY_Y1_MASK 0x00FF0000
+#define CFG_CKEY_Y(y) ((y)<<8)
+#define CFG_CKEY_Y_MASK 0x0000FF00
+#define CFG_ALPHA_Y(y) (y)
+#define CFG_ALPHA_Y_MASK 0x000000FF
+#define LCD_SPU_COLORKEY_U 0x0134
+#define CFG_CKEY_U2(u2) ((u2)<<24)
+#define CFG_CKEY_U2_MASK 0xFF000000
+#define CFG_CKEY_U1(u1) ((u1)<<16)
+#define CFG_CKEY_U1_MASK 0x00FF0000
+#define CFG_CKEY_U(u) ((u)<<8)
+#define CFG_CKEY_U_MASK 0x0000FF00
+#define CFG_ALPHA_U(u) (u)
+#define CFG_ALPHA_U_MASK 0x000000FF
+#define LCD_SPU_COLORKEY_V 0x0138
+#define CFG_CKEY_V2(v2) ((v2)<<24)
+#define CFG_CKEY_V2_MASK 0xFF000000
+#define CFG_CKEY_V1(v1) ((v1)<<16)
+#define CFG_CKEY_V1_MASK 0x00FF0000
+#define CFG_CKEY_V(v) ((v)<<8)
+#define CFG_CKEY_V_MASK 0x0000FF00
+#define CFG_ALPHA_V(v) (v)
+#define CFG_ALPHA_V_MASK 0x000000FF
+
+/* Graphics/Video DMA color key enable bits in LCD_TV_CTRL1 */
+#define CFG_CKEY_GRA 0x2
+#define CFG_CKEY_DMA 0x1
+
+/* Interlace mode enable bits in LCD_TV_CTRL1 */
+#define CFG_TV_INTERLACE_EN (1 << 22)
+#define CFG_TV_NIB (1 << 0)
+
+#define LCD_PN_SEPXLCNT 0x013c /* MMP2 */
+
+/* SPI Read Data Register */
+#define LCD_SPU_SPI_RXDATA 0x0140
+
+/* Smart Panel Read Data Register */
+#define LCD_SPU_ISA_RSDATA 0x0144
+#define ISA_RXDATA_16BIT_1_DATA_MASK 0x000000FF
+#define ISA_RXDATA_16BIT_2_DATA_MASK 0x0000FF00
+#define ISA_RXDATA_16BIT_3_DATA_MASK 0x00FF0000
+#define ISA_RXDATA_16BIT_4_DATA_MASK 0xFF000000
+#define ISA_RXDATA_32BIT_1_DATA_MASK 0x00FFFFFF
+
+#define LCD_SPU_DBG_ISA (0x0148) /* TTC */
+#define LCD_SPU_DMAVLD_YC (0x014C)
+#define LCD_SPU_DMAVLD_UV (0x0150)
+#define LCD_SPU_DMAVLD_UVSPU_GRAVLD (0x0154)
+
+#define LCD_READ_IOPAD (0x0148) /* MMP2*/
+#define LCD_DMAVLD_YC (0x014C)
+#define LCD_DMAVLD_UV (0x0150)
+#define LCD_TVGGRAVLD_HLEN (0x0154)
+
+/* HWC SRAM Read Data Register */
+#define LCD_SPU_HWC_RDDAT 0x0158
+
+/* Gamma Table SRAM Read Data Register */
+#define LCD_SPU_GAMMA_RDDAT 0x015c
+#define CFG_GAMMA_RDDAT_MASK 0x000000FF
+
+/* Palette Table SRAM Read Data Register */
+#define LCD_SPU_PALETTE_RDDAT 0x0160
+#define CFG_PALETTE_RDDAT_MASK 0x00FFFFFF
+
+#define LCD_SPU_DBG_DMATOP (0x0164) /* TTC */
+#define LCD_SPU_DBG_GRATOP (0x0168)
+#define LCD_SPU_DBG_TXCTRL (0x016C)
+#define LCD_SPU_DBG_SLVTOP (0x0170)
+#define LCD_SPU_DBG_MUXTOP (0x0174)
+
+#define LCD_SLV_DBG (0x0164) /* MMP2 */
+#define LCD_TVDVLD_YC (0x0168)
+#define LCD_TVDVLD_UV (0x016C)
+#define LCD_TVC_RDDAT (0x0170)
+#define LCD_TV_GAMMA_RDDAT (0x0174)
+
+/* I/O Pads Input Read Only Register */
+#define LCD_SPU_IOPAD_IN 0x0178
+#define CFG_IOPAD_IN_MASK 0x0FFFFFFF
+
+#define LCD_TV_PALETTE_RDDAT (0x0178) /* MMP2 */
+
+/* Reserved Read Only Registers */
+#define LCD_CFG_RDREG5F 0x017C
+#define IRE_FRAME_CNT_MASK 0x000000C0
+#define IPE_FRAME_CNT_MASK 0x00000030
+#define GRA_FRAME_CNT_MASK 0x0000000C /* Graphic */
+#define DMA_FRAME_CNT_MASK 0x00000003 /* Video */
+
+#define LCD_FRAME_CNT (0x017C) /* MMP2 */
+
+/* SPI Control Register. */
+#define LCD_SPU_SPI_CTRL 0x0180
+#define CFG_SCLKCNT(div) ((div)<<24) /* 0xFF~0x2 */
+#define CFG_SCLKCNT_MASK 0xFF000000
+#define CFG_RXBITS(rx) (((rx) - 1)<<16) /* 0x1F~0x1 */
+#define CFG_RXBITS_MASK 0x00FF0000
+#define CFG_TXBITS(tx) (((tx) - 1)<<8) /* 0x1F~0x1 */
+#define CFG_TXBITS_MASK 0x0000FF00
+#define CFG_CLKINV(clk) ((clk)<<7)
+#define CFG_CLKINV_MASK 0x00000080
+#define CFG_KEEPXFER(transfer) ((transfer)<<6)
+#define CFG_KEEPXFER_MASK 0x00000040
+#define CFG_RXBITSTO0(rx) ((rx)<<5)
+#define CFG_RXBITSTO0_MASK 0x00000020
+#define CFG_TXBITSTO0(tx) ((tx)<<4)
+#define CFG_TXBITSTO0_MASK 0x00000010
+#define CFG_SPI_ENA(spi) ((spi)<<3)
+#define CFG_SPI_ENA_MASK 0x00000008
+#define CFG_SPI_SEL(spi) ((spi)<<2)
+#define CFG_SPI_SEL_MASK 0x00000004
+#define CFG_SPI_3W4WB(wire) ((wire)<<1)
+#define CFG_SPI_3W4WB_MASK 0x00000002
+#define CFG_SPI_START(start) (start)
+#define CFG_SPI_START_MASK 0x00000001
+
+/* SPI Tx Data Register */
+#define LCD_SPU_SPI_TXDATA 0x0184
+
+/*
+ 1. Smart Pannel 8-bit Bus Control Register.
+ 2. AHB Slave Path Data Port Register
+*/
+#define LCD_SPU_SMPN_CTRL 0x0188
+
+/* DMA Control 0 Register */
+#define LCD_SPU_DMA_CTRL0 0x0190
+#define CFG_NOBLENDING(nb) ((nb)<<31)
+#define CFG_NOBLENDING_MASK 0x80000000
+#define CFG_GAMMA_ENA(gn) ((gn)<<30)
+#define CFG_GAMMA_ENA_MASK 0x40000000
+#define CFG_CBSH_ENA(cn) ((cn)<<29)
+#define CFG_CBSH_ENA_MASK 0x20000000
+#define CFG_PALETTE_ENA(pn) ((pn)<<28)
+#define CFG_PALETTE_ENA_MASK 0x10000000
+#define CFG_ARBFAST_ENA(an) ((an)<<27)
+#define CFG_ARBFAST_ENA_MASK 0x08000000
+#define CFG_HWC_1BITMOD(mode) ((mode)<<26)
+#define CFG_HWC_1BITMOD_MASK 0x04000000
+#define CFG_HWC_1BITENA(mn) ((mn)<<25)
+#define CFG_HWC_1BITENA_MASK 0x02000000
+#define CFG_HWC_ENA(cn) ((cn)<<24)
+#define CFG_HWC_ENA_MASK 0x01000000
+#define CFG_DMAFORMAT(dmaformat) ((dmaformat)<<20)
+#define CFG_DMAFORMAT_MASK 0x00F00000
+#define CFG_GRAFORMAT(graformat) ((graformat)<<16)
+#define CFG_GRAFORMAT_MASK 0x000F0000
+/* for graphic part */
+#define CFG_GRA_FTOGGLE(toggle) ((toggle)<<15)
+#define CFG_GRA_FTOGGLE_MASK 0x00008000
+#define CFG_GRA_HSMOOTH(smooth) ((smooth)<<14)
+#define CFG_GRA_HSMOOTH_MASK 0x00004000
+#define CFG_GRA_TSTMODE(test) ((test)<<13)
+#define CFG_GRA_TSTMODE_MASK 0x00002000
+#define CFG_GRA_SWAPRB(swap) ((swap)<<12)
+#define CFG_GRA_SWAPRB_MASK 0x00001000
+#define CFG_GRA_SWAPUV(swap) ((swap)<<11)
+#define CFG_GRA_SWAPUV_MASK 0x00000800
+#define CFG_GRA_SWAPYU(swap) ((swap)<<10)
+#define CFG_GRA_SWAPYU_MASK 0x00000400
+#define CFG_GRA_SWAP_MASK 0x00001C00
+#define CFG_YUV2RGB_GRA(cvrt) ((cvrt)<<9)
+#define CFG_YUV2RGB_GRA_MASK 0x00000200
+#define CFG_GRA_ENA(gra) ((gra)<<8)
+#define CFG_GRA_ENA_MASK 0x00000100
+#define dma0_gfx_masks (CFG_GRAFORMAT_MASK | CFG_GRA_FTOGGLE_MASK | \
+ CFG_GRA_HSMOOTH_MASK | CFG_GRA_TSTMODE_MASK | CFG_GRA_SWAP_MASK | \
+ CFG_YUV2RGB_GRA_MASK | CFG_GRA_ENA_MASK)
+/* for video part */
+#define CFG_DMA_FTOGGLE(toggle) ((toggle)<<7)
+#define CFG_DMA_FTOGGLE_MASK 0x00000080
+#define CFG_DMA_HSMOOTH(smooth) ((smooth)<<6)
+#define CFG_DMA_HSMOOTH_MASK 0x00000040
+#define CFG_DMA_TSTMODE(test) ((test)<<5)
+#define CFG_DMA_TSTMODE_MASK 0x00000020
+#define CFG_DMA_SWAPRB(swap) ((swap)<<4)
+#define CFG_DMA_SWAPRB_MASK 0x00000010
+#define CFG_DMA_SWAPUV(swap) ((swap)<<3)
+#define CFG_DMA_SWAPUV_MASK 0x00000008
+#define CFG_DMA_SWAPYU(swap) ((swap)<<2)
+#define CFG_DMA_SWAPYU_MASK 0x00000004
+#define CFG_DMA_SWAP_MASK 0x0000001C
+#define CFG_YUV2RGB_DMA(cvrt) ((cvrt)<<1)
+#define CFG_YUV2RGB_DMA_MASK 0x00000002
+#define CFG_DMA_ENA(video) (video)
+#define CFG_DMA_ENA_MASK 0x00000001
+#define dma0_vid_masks (CFG_DMAFORMAT_MASK | CFG_DMA_FTOGGLE_MASK | \
+ CFG_DMA_HSMOOTH_MASK | CFG_DMA_TSTMODE_MASK | CFG_DMA_SWAP_MASK | \
+ CFG_YUV2RGB_DMA_MASK | CFG_DMA_ENA_MASK)
+#define dma_palette(val) ((val ? 1 : 0) << 28)
+#define dma_fmt(vid, val) ((val & 0xf) << ((vid) ? 20 : 16))
+#define dma_swaprb(vid, val) ((val ? 1 : 0) << ((vid) ? 4 : 12))
+#define dma_swapuv(vid, val) ((val ? 1 : 0) << ((vid) ? 3 : 11))
+#define dma_swapyuv(vid, val) ((val ? 1 : 0) << ((vid) ? 2 : 10))
+#define dma_csc(vid, val) ((val ? 1 : 0) << ((vid) ? 1 : 9))
+#define dma_hsmooth(vid, val) ((val ? 1 : 0) << ((vid) ? 6 : 14))
+#define dma_mask(vid) (dma_palette(1) | dma_fmt(vid, 0xf) | dma_csc(vid, 1) \
+ | dma_swaprb(vid, 1) | dma_swapuv(vid, 1) | dma_swapyuv(vid, 1))
+
+/* DMA Control 1 Register */
+#define LCD_SPU_DMA_CTRL1 0x0194
+#define CFG_FRAME_TRIG(trig) ((trig)<<31)
+#define CFG_FRAME_TRIG_MASK 0x80000000
+#define CFG_VSYNC_TRIG(trig) ((trig)<<28)
+#define CFG_VSYNC_TRIG_MASK 0x70000000
+#define CFG_VSYNC_INV(inv) ((inv)<<27)
+#define CFG_VSYNC_INV_MASK 0x08000000
+#define CFG_COLOR_KEY_MODE(cmode) ((cmode)<<24)
+#define CFG_COLOR_KEY_MASK 0x07000000
+#define CFG_CARRY(carry) ((carry)<<23)
+#define CFG_CARRY_MASK 0x00800000
+#define CFG_LNBUF_ENA(lnbuf) ((lnbuf)<<22)
+#define CFG_LNBUF_ENA_MASK 0x00400000
+#define CFG_GATED_ENA(gated) ((gated)<<21)
+#define CFG_GATED_ENA_MASK 0x00200000
+#define CFG_PWRDN_ENA(power) ((power)<<20)
+#define CFG_PWRDN_ENA_MASK 0x00100000
+#define CFG_DSCALE(dscale) ((dscale)<<18)
+#define CFG_DSCALE_MASK 0x000C0000
+#define CFG_ALPHA_MODE(amode) ((amode)<<16)
+#define CFG_ALPHA_MODE_MASK 0x00030000
+#define CFG_ALPHA(alpha) ((alpha)<<8)
+#define CFG_ALPHA_MASK 0x0000FF00
+#define CFG_PXLCMD(pxlcmd) (pxlcmd)
+#define CFG_PXLCMD_MASK 0x000000FF
+
+/* SRAM Control Register */
+#define LCD_SPU_SRAM_CTRL 0x0198
+#define CFG_SRAM_INIT_WR_RD(mode) ((mode)<<14)
+#define CFG_SRAM_INIT_WR_RD_MASK 0x0000C000
+#define CFG_SRAM_ADDR_LCDID(id) ((id)<<8)
+#define CFG_SRAM_ADDR_LCDID_MASK 0x00000F00
+#define CFG_SRAM_ADDR(addr) (addr)
+#define CFG_SRAM_ADDR_MASK 0x000000FF
+
+/* SRAM Write Data Register */
+#define LCD_SPU_SRAM_WRDAT 0x019C
+
+/* SRAM RTC/WTC Control Register */
+#define LCD_SPU_SRAM_PARA0 0x01A0
+
+/* SRAM Power Down Control Register */
+#define LCD_SPU_SRAM_PARA1 0x01A4
+#define CFG_CSB_256x32(hwc) ((hwc)<<15) /* HWC */
+#define CFG_CSB_256x32_MASK 0x00008000
+#define CFG_CSB_256x24(palette) ((palette)<<14) /* Palette */
+#define CFG_CSB_256x24_MASK 0x00004000
+#define CFG_CSB_256x8(gamma) ((gamma)<<13) /* Gamma */
+#define CFG_CSB_256x8_MASK 0x00002000
+#define CFG_PDWN256x32(pdwn) ((pdwn)<<7) /* HWC */
+#define CFG_PDWN256x32_MASK 0x00000080
+#define CFG_PDWN256x24(pdwn) ((pdwn)<<6) /* Palette */
+#define CFG_PDWN256x24_MASK 0x00000040
+#define CFG_PDWN256x8(pdwn) ((pdwn)<<5) /* Gamma */
+#define CFG_PDWN256x8_MASK 0x00000020
+#define CFG_PDWN32x32(pdwn) ((pdwn)<<3)
+#define CFG_PDWN32x32_MASK 0x00000008
+#define CFG_PDWN16x66(pdwn) ((pdwn)<<2)
+#define CFG_PDWN16x66_MASK 0x00000004
+#define CFG_PDWN32x66(pdwn) ((pdwn)<<1)
+#define CFG_PDWN32x66_MASK 0x00000002
+#define CFG_PDWN64x66(pdwn) (pdwn)
+#define CFG_PDWN64x66_MASK 0x00000001
+
+/* Smart or Dumb Panel Clock Divider */
+#define LCD_CFG_SCLK_DIV 0x01A8
+#define SCLK_SRC_SEL(src) ((src)<<31)
+#define SCLK_SRC_SEL_MASK 0x80000000
+#define SCLK_DISABLE (1<<28)
+#define CLK_FRACDIV(frac) ((frac)<<16)
+#define CLK_FRACDIV_MASK 0x0FFF0000
+#define DSI1_BITCLK_DIV(div) (div<<8)
+#define DSI1_BITCLK_DIV_MASK 0x00000F00
+#define CLK_INT_DIV(div) (div)
+#define CLK_INT_DIV_MASK 0x000000FF
+
+/* Video Contrast Register */
+#define LCD_SPU_CONTRAST 0x01AC
+#define CFG_BRIGHTNESS(bright) ((bright)<<16)
+#define CFG_BRIGHTNESS_MASK 0xFFFF0000
+#define CFG_CONTRAST(contrast) (contrast)
+#define CFG_CONTRAST_MASK 0x0000FFFF
+
+/* Video Saturation Register */
+#define LCD_SPU_SATURATION 0x01B0
+#define CFG_C_MULTS(mult) ((mult)<<16)
+#define CFG_C_MULTS_MASK 0xFFFF0000
+#define CFG_SATURATION(sat) (sat)
+#define CFG_SATURATION_MASK 0x0000FFFF
+
+/* Video Hue Adjust Register */
+#define LCD_SPU_CBSH_HUE 0x01B4
+#define CFG_SIN0(sin0) ((sin0)<<16)
+#define CFG_SIN0_MASK 0xFFFF0000
+#define CFG_COS0(con0) (con0)
+#define CFG_COS0_MASK 0x0000FFFF
+
+/* Dump LCD Panel Control Register */
+#define LCD_SPU_DUMB_CTRL 0x01B8
+#define CFG_DUMBMODE(mode) ((mode)<<28)
+#define CFG_DUMBMODE_MASK 0xF0000000
+#define CFG_LCDGPIO_O(data) ((data)<<20)
+#define CFG_LCDGPIO_O_MASK 0x0FF00000
+#define CFG_LCDGPIO_ENA(gpio) ((gpio)<<12)
+#define CFG_LCDGPIO_ENA_MASK 0x000FF000
+#define CFG_BIAS_OUT(bias) ((bias)<<8)
+#define CFG_BIAS_OUT_MASK 0x00000100
+#define CFG_REVERSE_RGB(RGB) ((RGB)<<7)
+#define CFG_REVERSE_RGB_MASK 0x00000080
+#define CFG_INV_COMPBLANK(blank) ((blank)<<6)
+#define CFG_INV_COMPBLANK_MASK 0x00000040
+#define CFG_INV_COMPSYNC(sync) ((sync)<<5)
+#define CFG_INV_COMPSYNC_MASK 0x00000020
+#define CFG_INV_HENA(hena) ((hena)<<4)
+#define CFG_INV_HENA_MASK 0x00000010
+#define CFG_INV_VSYNC(vsync) ((vsync)<<3)
+#define CFG_INV_VSYNC_MASK 0x00000008
+#define CFG_INV_HSYNC(hsync) ((hsync)<<2)
+#define CFG_INV_HSYNC_MASK 0x00000004
+#define CFG_INV_PCLK(pclk) ((pclk)<<1)
+#define CFG_INV_PCLK_MASK 0x00000002
+#define CFG_DUMB_ENA(dumb) (dumb)
+#define CFG_DUMB_ENA_MASK 0x00000001
+
+/* LCD I/O Pads Control Register */
+#define SPU_IOPAD_CONTROL 0x01BC
+#define CFG_GRA_VM_ENA(vm) ((vm)<<15)
+#define CFG_GRA_VM_ENA_MASK 0x00008000
+#define CFG_DMA_VM_ENA(vm) ((vm)<<13)
+#define CFG_DMA_VM_ENA_MASK 0x00002000
+#define CFG_CMD_VM_ENA(vm) ((vm)<<12)
+#define CFG_CMD_VM_ENA_MASK 0x00001000
+#define CFG_CSC(csc) ((csc)<<8)
+#define CFG_CSC_MASK 0x00000300
+#define CFG_BOUNDARY(size) ((size)<<5)
+#define CFG_BOUNDARY_MASK 0x00000020
+#define CFG_BURST(len) ((len)<<4)
+#define CFG_BURST_MASK 0x00000010
+#define CFG_IOPADMODE(iopad) (iopad)
+#define CFG_IOPADMODE_MASK 0x0000000F
+
+/* LCD Interrupt Control Register */
+#define SPU_IRQ_ENA 0x01C0
+#define DMA_FRAME_IRQ0_ENA(irq) ((irq)<<31)
+#define DMA_FRAME_IRQ0_ENA_MASK 0x80000000
+#define DMA_FRAME_IRQ1_ENA(irq) ((irq)<<30)
+#define DMA_FRAME_IRQ1_ENA_MASK 0x40000000
+#define DMA_FF_UNDERFLOW_ENA(ff) ((ff)<<29)
+#define DMA_FF_UNDERFLOW_ENA_MASK 0x20000000
+#define AXI_BUS_ERROR_IRQ_ENA(irq) ((irq)<<28)
+#define AXI_BUS_ERROR_IRQ_ENA_MASK 0x10000000
+#define GRA_FRAME_IRQ0_ENA(irq) ((irq)<<27)
+#define GRA_FRAME_IRQ0_ENA_MASK 0x08000000
+#define GRA_FRAME_IRQ1_ENA(irq) ((irq)<<26)
+#define GRA_FRAME_IRQ1_ENA_MASK 0x04000000
+#define GRA_FF_UNDERFLOW_ENA(ff) ((ff)<<25)
+#define GRA_FF_UNDERFLOW_ENA_MASK 0x02000000
+#define VSYNC_IRQ_ENA(vsync_irq) ((vsync_irq)<<23)
+#define VSYNC_IRQ_ENA_MASK 0x00800000
+#define DUMB_FRAMEDONE_ENA(fdone) ((fdone)<<22)
+#define DUMB_FRAMEDONE_ENA_MASK 0x00400000
+#define TWC_FRAMEDONE_ENA(fdone) ((fdone)<<21)
+#define TWC_FRAMEDONE_ENA_MASK 0x00200000
+#define HWC_FRAMEDONE_ENA(fdone) ((fdone)<<20)
+#define HWC_FRAMEDONE_ENA_MASK 0x00100000
+#define SLV_IRQ_ENA(irq) ((irq)<<19)
+#define SLV_IRQ_ENA_MASK 0x00080000
+#define SPI_IRQ_ENA(irq) ((irq)<<18)
+#define SPI_IRQ_ENA_MASK 0x00040000
+#define PWRDN_IRQ_ENA(irq) ((irq)<<17)
+#define PWRDN_IRQ_ENA_MASK 0x00020000
+#define AXI_LATENCY_TOO_LONG_IRQ_ENA(irq) ((irq)<<16)
+#define AXI_LATENCY_TOO_LONG_IRQ_ENA_MASK 0x00010000
+#define CLEAN_SPU_IRQ_ISR(irq) (irq)
+#define CLEAN_SPU_IRQ_ISR_MASK 0x0000FFFF
+#define TV_DMA_FRAME_IRQ0_ENA(irq) ((irq)<<15)
+#define TV_DMA_FRAME_IRQ0_ENA_MASK 0x00008000
+#define TV_DMA_FRAME_IRQ1_ENA(irq) ((irq)<<14)
+#define TV_DMA_FRAME_IRQ1_ENA_MASK 0x00004000
+#define TV_DMA_FF_UNDERFLOW_ENA(unerrun) ((unerrun)<<13)
+#define TV_DMA_FF_UNDERFLOW_ENA_MASK 0x00002000
+#define TVSYNC_IRQ_ENA(irq) ((irq)<<12)
+#define TVSYNC_IRQ_ENA_MASK 0x00001000
+#define TV_FRAME_IRQ0_ENA(irq) ((irq)<<11)
+#define TV_FRAME_IRQ0_ENA_MASK 0x00000800
+#define TV_FRAME_IRQ1_ENA(irq) ((irq)<<10)
+#define TV_FRAME_IRQ1_ENA_MASK 0x00000400
+#define TV_GRA_FF_UNDERFLOW_ENA(unerrun) ((unerrun)<<9)
+#define TV_GRA_FF_UNDERFLOW_ENA_MASK 0x00000200
+#define TV_FRAMEDONE_ENA(irq) ((irq)<<8)
+#define TV_FRAMEDONE_ENA_MASK 0x00000100
+
+/* FIXME - JUST GUESS */
+#define PN2_DMA_FRAME_IRQ0_ENA(irq) ((irq)<<7)
+#define PN2_DMA_FRAME_IRQ0_ENA_MASK 0x00000080
+#define PN2_DMA_FRAME_IRQ1_ENA(irq) ((irq)<<6)
+#define PN2_DMA_FRAME_IRQ1_ENA_MASK 0x00000040
+#define PN2_DMA_FF_UNDERFLOW_ENA(ff) ((ff)<<5)
+#define PN2_DMA_FF_UNDERFLOW_ENA_MASK 0x00000020
+#define PN2_GRA_FRAME_IRQ0_ENA(irq) ((irq)<<3)
+#define PN2_GRA_FRAME_IRQ0_ENA_MASK 0x00000008
+#define PN2_GRA_FRAME_IRQ1_ENA(irq) ((irq)<<2)
+#define PN2_GRA_FRAME_IRQ1_ENA_MASK 0x04000004
+#define PN2_GRA_FF_UNDERFLOW_ENA(ff) ((ff)<<1)
+#define PN2_GRA_FF_UNDERFLOW_ENA_MASK 0x00000002
+#define PN2_VSYNC_IRQ_ENA(irq) ((irq)<<0)
+#define PN2_SYNC_IRQ_ENA_MASK 0x00000001
+
+#define gf0_imask(id) ((id) ? (((id) & 1) ? TV_FRAME_IRQ0_ENA_MASK \
+ : PN2_GRA_FRAME_IRQ0_ENA_MASK) : GRA_FRAME_IRQ0_ENA_MASK)
+#define gf1_imask(id) ((id) ? (((id) & 1) ? TV_FRAME_IRQ1_ENA_MASK \
+ : PN2_GRA_FRAME_IRQ1_ENA_MASK) : GRA_FRAME_IRQ1_ENA_MASK)
+#define vsync_imask(id) ((id) ? (((id) & 1) ? TVSYNC_IRQ_ENA_MASK \
+ : PN2_SYNC_IRQ_ENA_MASK) : VSYNC_IRQ_ENA_MASK)
+#define vsync_imasks (vsync_imask(0) | vsync_imask(1))
+
+#define display_done_imask(id) ((id) ? (((id) & 1) ? TV_FRAMEDONE_ENA_MASK\
+ : (PN2_DMA_FRAME_IRQ0_ENA_MASK | PN2_DMA_FRAME_IRQ1_ENA_MASK))\
+ : DUMB_FRAMEDONE_ENA_MASK)
+
+#define display_done_imasks (display_done_imask(0) | display_done_imask(1))
+
+#define vf0_imask(id) ((id) ? (((id) & 1) ? TV_DMA_FRAME_IRQ0_ENA_MASK \
+ : PN2_DMA_FRAME_IRQ0_ENA_MASK) : DMA_FRAME_IRQ0_ENA_MASK)
+#define vf1_imask(id) ((id) ? (((id) & 1) ? TV_DMA_FRAME_IRQ1_ENA_MASK \
+ : PN2_DMA_FRAME_IRQ1_ENA_MASK) : DMA_FRAME_IRQ1_ENA_MASK)
+
+#define gfx_imasks (gf0_imask(0) | gf1_imask(0) | gf0_imask(1) | \
+ gf1_imask(1))
+#define vid_imasks (vf0_imask(0) | vf1_imask(0) | vf0_imask(1) | \
+ vf1_imask(1))
+#define vid_imask(id) (display_done_imask(id))
+
+#define pn1_imasks (gf0_imask(0) | gf1_imask(0) | vsync_imask(0) | \
+ display_done_imask(0) | vf0_imask(0) | vf1_imask(0))
+#define tv_imasks (gf0_imask(1) | gf1_imask(1) | vsync_imask(1) | \
+ display_done_imask(1) | vf0_imask(1) | vf1_imask(1))
+#define path_imasks(id) ((id) ? (tv_imasks) : (pn1_imasks))
+
+/* error indications */
+#define vid_udflow_imask(id) ((id) ? (((id) & 1) ? \
+ (TV_DMA_FF_UNDERFLOW_ENA_MASK) : (PN2_DMA_FF_UNDERFLOW_ENA_MASK)) : \
+ (DMA_FF_UNDERFLOW_ENA_MASK))
+#define gfx_udflow_imask(id) ((id) ? (((id) & 1) ? \
+ (TV_GRA_FF_UNDERFLOW_ENA_MASK) : (PN2_GRA_FF_UNDERFLOW_ENA_MASK)) : \
+ (GRA_FF_UNDERFLOW_ENA_MASK))
+
+#define err_imask(id) (vid_udflow_imask(id) | gfx_udflow_imask(id) | \
+ AXI_BUS_ERROR_IRQ_ENA_MASK | AXI_LATENCY_TOO_LONG_IRQ_ENA_MASK)
+#define err_imasks (err_imask(0) | err_imask(1) | err_imask(2))
+/* LCD Interrupt Status Register */
+#define SPU_IRQ_ISR 0x01C4
+#define DMA_FRAME_IRQ0(irq) ((irq)<<31)
+#define DMA_FRAME_IRQ0_MASK 0x80000000
+#define DMA_FRAME_IRQ1(irq) ((irq)<<30)
+#define DMA_FRAME_IRQ1_MASK 0x40000000
+#define DMA_FF_UNDERFLOW(ff) ((ff)<<29)
+#define DMA_FF_UNDERFLOW_MASK 0x20000000
+#define AXI_BUS_ERROR_IRQ(irq) ((irq)<<28)
+#define AXI_BUS_ERROR_IRQ_MASK 0x10000000
+#define GRA_FRAME_IRQ0(irq) ((irq)<<27)
+#define GRA_FRAME_IRQ0_MASK 0x08000000
+#define GRA_FRAME_IRQ1(irq) ((irq)<<26)
+#define GRA_FRAME_IRQ1_MASK 0x04000000
+#define GRA_FF_UNDERFLOW(ff) ((ff)<<25)
+#define GRA_FF_UNDERFLOW_MASK 0x02000000
+#define VSYNC_IRQ(vsync_irq) ((vsync_irq)<<23)
+#define VSYNC_IRQ_MASK 0x00800000
+#define DUMB_FRAMEDONE(fdone) ((fdone)<<22)
+#define DUMB_FRAMEDONE_MASK 0x00400000
+#define TWC_FRAMEDONE(fdone) ((fdone)<<21)
+#define TWC_FRAMEDONE_MASK 0x00200000
+#define HWC_FRAMEDONE(fdone) ((fdone)<<20)
+#define HWC_FRAMEDONE_MASK 0x00100000
+#define SLV_IRQ(irq) ((irq)<<19)
+#define SLV_IRQ_MASK 0x00080000
+#define SPI_IRQ(irq) ((irq)<<18)
+#define SPI_IRQ_MASK 0x00040000
+#define PWRDN_IRQ(irq) ((irq)<<17)
+#define PWRDN_IRQ_MASK 0x00020000
+#define AXI_LATENCY_TOO_LONGR_IRQ(irq) ((irq)<<16)
+#define AXI_LATENCY_TOO_LONGR_IRQ_MASK 0x00010000
+#define TV_DMA_FRAME_IRQ0(irq) ((irq)<<15)
+#define TV_DMA_FRAME_IRQ0_MASK 0x00008000
+#define TV_DMA_FRAME_IRQ1(irq) ((irq)<<14)
+#define TV_DMA_FRAME_IRQ1_MASK 0x00004000
+#define TV_DMA_FF_UNDERFLOW(unerrun) ((unerrun)<<13)
+#define TV_DMA_FF_UNDERFLOW_MASK 0x00002000
+#define TVSYNC_IRQ(irq) ((irq)<<12)
+#define TVSYNC_IRQ_MASK 0x00001000
+#define TV_FRAME_IRQ0(irq) ((irq)<<11)
+#define TV_FRAME_IRQ0_MASK 0x00000800
+#define TV_FRAME_IRQ1(irq) ((irq)<<10)
+#define TV_FRAME_IRQ1_MASK 0x00000400
+#define TV_GRA_FF_UNDERFLOW(unerrun) ((unerrun)<<9)
+#define TV_GRA_FF_UNDERFLOW_MASK 0x00000200
+#define PN2_DMA_FRAME_IRQ0(irq) ((irq)<<7)
+#define PN2_DMA_FRAME_IRQ0_MASK 0x00000080
+#define PN2_DMA_FRAME_IRQ1(irq) ((irq)<<6)
+#define PN2_DMA_FRAME_IRQ1_MASK 0x00000040
+#define PN2_DMA_FF_UNDERFLOW(ff) ((ff)<<5)
+#define PN2_DMA_FF_UNDERFLOW_MASK 0x00000020
+#define PN2_GRA_FRAME_IRQ0(irq) ((irq)<<3)
+#define PN2_GRA_FRAME_IRQ0_MASK 0x00000008
+#define PN2_GRA_FRAME_IRQ1(irq) ((irq)<<2)
+#define PN2_GRA_FRAME_IRQ1_MASK 0x04000004
+#define PN2_GRA_FF_UNDERFLOW(ff) ((ff)<<1)
+#define PN2_GRA_FF_UNDERFLOW_MASK 0x00000002
+#define PN2_VSYNC_IRQ(irq) ((irq)<<0)
+#define PN2_SYNC_IRQ_MASK 0x00000001
+
+/* LCD FIFO Depth register */
+#define LCD_FIFO_DEPTH 0x01c8
+#define VIDEO_FIFO(fi) ((fi) << 0)
+#define VIDEO_FIFO_MASK 0x00000003
+#define GRAPHIC_FIFO(fi) ((fi) << 2)
+#define GRAPHIC_FIFO_MASK 0x0000000c
+
+/* read-only */
+#define DMA_FRAME_IRQ0_LEVEL_MASK 0x00008000
+#define DMA_FRAME_IRQ1_LEVEL_MASK 0x00004000
+#define DMA_FRAME_CNT_ISR_MASK 0x00003000
+#define GRA_FRAME_IRQ0_LEVEL_MASK 0x00000800
+#define GRA_FRAME_IRQ1_LEVEL_MASK 0x00000400
+#define GRA_FRAME_CNT_ISR_MASK 0x00000300
+#define VSYNC_IRQ_LEVEL_MASK 0x00000080
+#define DUMB_FRAMEDONE_LEVEL_MASK 0x00000040
+#define TWC_FRAMEDONE_LEVEL_MASK 0x00000020
+#define HWC_FRAMEDONE_LEVEL_MASK 0x00000010
+#define SLV_FF_EMPTY_MASK 0x00000008
+#define DMA_FF_ALLEMPTY_MASK 0x00000004
+#define GRA_FF_ALLEMPTY_MASK 0x00000002
+#define PWRDN_IRQ_LEVEL_MASK 0x00000001
+
+/* 32 bit LCD Interrupt Reset Status*/
+#define SPU_IRQ_RSR (0x01C8)
+/* 32 bit Panel Path Graphic Partial Display Horizontal Control Register*/
+#define LCD_GRA_CUTHPXL (0x01CC)
+/* 32 bit Panel Path Graphic Partial Display Vertical Control Register*/
+#define LCD_GRA_CUTVLN (0x01D0)
+/* 32 bit TV Path Graphic Partial Display Horizontal Control Register*/
+#define LCD_TVG_CUTHPXL (0x01D4)
+/* 32 bit TV Path Graphic Partial Display Vertical Control Register*/
+#define LCD_TVG_CUTVLN (0x01D8)
+/* 32 bit LCD Global Control Register*/
+#define LCD_TOP_CTRL (0x01DC)
+/* 32 bit LCD SQU Line Buffer Control Register 1*/
+#define LCD_SQULN1_CTRL (0x01E0)
+/* 32 bit LCD SQU Line Buffer Control Register 2*/
+#define LCD_SQULN2_CTRL (0x01E4)
+#define squln_ctrl(id) ((id) ? (((id) & 1) ? LCD_SQULN2_CTRL : \
+ LCD_PN2_SQULN1_CTRL) : LCD_SQULN1_CTRL)
+
+/* 32 bit LCD Mixed Overlay Control Register */
+#define LCD_AFA_ALL2ONE (0x01E8)
+
+#define LCD_PN2_SCLK_DIV (0x01EC)
+#define LCD_PN2_TCLK_DIV (0x01F0)
+#define LCD_LVDS_SCLK_DIV_WR (0x01F4)
+#define LCD_LVDS_SCLK_DIV_RD (0x01FC)
+#define PN2_LCD_DMA_START_ADDR_Y0 (0x0200)
+#define PN2_LCD_DMA_START_ADDR_U0 (0x0204)
+#define PN2_LCD_DMA_START_ADDR_V0 (0x0208)
+#define PN2_LCD_DMA_START_ADDR_C0 (0x020C)
+#define PN2_LCD_DMA_START_ADDR_Y1 (0x0210)
+#define PN2_LCD_DMA_START_ADDR_U1 (0x0214)
+#define PN2_LCD_DMA_START_ADDR_V1 (0x0218)
+#define PN2_LCD_DMA_START_ADDR_C1 (0x021C)
+#define PN2_LCD_DMA_PITCH_YC (0x0220)
+#define PN2_LCD_DMA_PITCH_UV (0x0224)
+#define PN2_LCD_DMA_OVSA_HPXL_VLN (0x0228)
+#define PN2_LCD_DMA_HPXL_VLN (0x022C)
+#define PN2_LCD_DMAZM_HPXL_VLN (0x0230)
+#define PN2_LCD_GRA_START_ADDR0 (0x0234)
+#define PN2_LCD_GRA_START_ADDR1 (0x0238)
+#define PN2_LCD_GRA_PITCH (0x023C)
+#define PN2_LCD_GRA_OVSA_HPXL_VLN (0x0240)
+#define PN2_LCD_GRA_HPXL_VLN (0x0244)
+#define PN2_LCD_GRAZM_HPXL_VLN (0x0248)
+#define PN2_LCD_HWC_OVSA_HPXL_VLN (0x024C)
+#define PN2_LCD_HWC_HPXL_VLN (0x0250)
+#define LCD_PN2_V_H_TOTAL (0x0254)
+#define LCD_PN2_V_H_ACTIVE (0x0258)
+#define LCD_PN2_H_PORCH (0x025C)
+#define LCD_PN2_V_PORCH (0x0260)
+#define LCD_PN2_BLANKCOLOR (0x0264)
+#define LCD_PN2_ALPHA_COLOR1 (0x0268)
+#define LCD_PN2_ALPHA_COLOR2 (0x026C)
+#define LCD_PN2_COLORKEY_Y (0x0270)
+#define LCD_PN2_COLORKEY_U (0x0274)
+#define LCD_PN2_COLORKEY_V (0x0278)
+#define LCD_PN2_SEPXLCNT (0x027C)
+#define LCD_TV_V_H_TOTAL_FLD (0x0280)
+#define LCD_TV_V_PORCH_FLD (0x0284)
+#define LCD_TV_SEPXLCNT_FLD (0x0288)
+
+#define LCD_2ND_ALPHA (0x0294)
+#define LCD_PN2_CONTRAST (0x0298)
+#define LCD_PN2_SATURATION (0x029c)
+#define LCD_PN2_CBSH_HUE (0x02a0)
+#define LCD_TIMING_EXT (0x02C0)
+#define LCD_PN2_LAYER_ALPHA_SEL1 (0x02c4)
+#define LCD_PN2_CTRL0 (0x02C8)
+#define TV_LAYER_ALPHA_SEL1 (0x02cc)
+#define LCD_SMPN2_CTRL (0x02D0)
+#define LCD_IO_OVERL_MAP_CTRL (0x02D4)
+#define LCD_DUMB2_CTRL (0x02d8)
+#define LCD_PN2_CTRL1 (0x02DC)
+#define PN2_IOPAD_CONTROL (0x02E0)
+#define LCD_PN2_SQULN1_CTRL (0x02E4)
+#define PN2_LCD_GRA_CUTHPXL (0x02e8)
+#define PN2_LCD_GRA_CUTVLN (0x02ec)
+#define LCD_PN2_SQULN2_CTRL (0x02F0)
+#define ALL_LAYER_ALPHA_SEL (0x02F4)
+
+/* pxa988 has different MASTER_CTRL from MMP3/MMP2 */
+#ifdef CONFIG_CPU_PXA988
+#define TIMING_MASTER_CONTROL (0x01F4)
+#define MASTER_ENH(id) (1 << ((id) + 5))
+#define MASTER_ENV(id) (1 << ((id) + 6))
+#else
+#define TIMING_MASTER_CONTROL (0x02F8)
+#define MASTER_ENH(id) (1 << (id))
+#define MASTER_ENV(id) (1 << ((id) + 4))
+#endif
+
+#define DSI_START_SEL_SHIFT(id) (((id) << 1) + 8)
+#define timing_master_config(path, dsi_id, lcd_id) \
+ (MASTER_ENH(path) | MASTER_ENV(path) | \
+ (((lcd_id) + ((dsi_id) << 1)) << DSI_START_SEL_SHIFT(path)))
+
+#define LCD_2ND_BLD_CTL (0x02Fc)
+#define LVDS_SRC_MASK (3 << 30)
+#define LVDS_SRC_SHIFT (30)
+#define LVDS_FMT_MASK (1 << 28)
+#define LVDS_FMT_SHIFT (28)
+
+#define CLK_SCLK (1 << 0)
+#define CLK_LVDS_RD (1 << 1)
+#define CLK_LVDS_WR (1 << 2)
+
+#define gra_partdisp_ctrl_hor(id) ((id) ? (((id) & 1) ? \
+ LCD_TVG_CUTHPXL : PN2_LCD_GRA_CUTHPXL) : LCD_GRA_CUTHPXL)
+#define gra_partdisp_ctrl_ver(id) ((id) ? (((id) & 1) ? \
+ LCD_TVG_CUTVLN : PN2_LCD_GRA_CUTVLN) : LCD_GRA_CUTVLN)
+
+/*
+ * defined Video Memory Color format for DMA control 0 register
+ * DMA0 bit[23:20]
+ */
+#define VMODE_RGB565 0x0
+#define VMODE_RGB1555 0x1
+#define VMODE_RGB888PACKED 0x2
+#define VMODE_RGB888UNPACKED 0x3
+#define VMODE_RGBA888 0x4
+#define VMODE_YUV422PACKED 0x5
+#define VMODE_YUV422PLANAR 0x6
+#define VMODE_YUV420PLANAR 0x7
+#define VMODE_SMPNCMD 0x8
+#define VMODE_PALETTE4BIT 0x9
+#define VMODE_PALETTE8BIT 0xa
+#define VMODE_RESERVED 0xb
+
+/*
+ * defined Graphic Memory Color format for DMA control 0 register
+ * DMA0 bit[19:16]
+ */
+#define GMODE_RGB565 0x0
+#define GMODE_RGB1555 0x1
+#define GMODE_RGB888PACKED 0x2
+#define GMODE_RGB888UNPACKED 0x3
+#define GMODE_RGBA888 0x4
+#define GMODE_YUV422PACKED 0x5
+#define GMODE_YUV422PLANAR 0x6
+#define GMODE_YUV420PLANAR 0x7
+#define GMODE_SMPNCMD 0x8
+#define GMODE_PALETTE4BIT 0x9
+#define GMODE_PALETTE8BIT 0xa
+#define GMODE_RESERVED 0xb
+
+/*
+ * define for DMA control 1 register
+ */
+#define DMA1_FRAME_TRIG 31 /* bit location */
+#define DMA1_VSYNC_MODE 28
+#define DMA1_VSYNC_INV 27
+#define DMA1_CKEY 24
+#define DMA1_CARRY 23
+#define DMA1_LNBUF_ENA 22
+#define DMA1_GATED_ENA 21
+#define DMA1_PWRDN_ENA 20
+#define DMA1_DSCALE 18
+#define DMA1_ALPHA_MODE 16
+#define DMA1_ALPHA 08
+#define DMA1_PXLCMD 00
+
+/*
+ * defined for Configure Dumb Mode
+ * DUMB LCD Panel bit[31:28]
+ */
+#define DUMB16_RGB565_0 0x0
+#define DUMB16_RGB565_1 0x1
+#define DUMB18_RGB666_0 0x2
+#define DUMB18_RGB666_1 0x3
+#define DUMB12_RGB444_0 0x4
+#define DUMB12_RGB444_1 0x5
+#define DUMB24_RGB888_0 0x6
+#define DUMB_BLANK 0x7
+
+/*
+ * defined for Configure I/O Pin Allocation Mode
+ * LCD LCD I/O Pads control register bit[3:0]
+ */
+#define IOPAD_DUMB24 0x0
+#define IOPAD_DUMB18SPI 0x1
+#define IOPAD_DUMB18GPIO 0x2
+#define IOPAD_DUMB16SPI 0x3
+#define IOPAD_DUMB16GPIO 0x4
+#define IOPAD_DUMB12 0x5
+#define IOPAD_SMART18SPI 0x6
+#define IOPAD_SMART16SPI 0x7
+#define IOPAD_SMART8BOTH 0x8
+#define IOPAD_DUMB18_SMART8 0x9
+#define IOPAD_DUMB16_SMART8SPI 0xa
+#define IOPAD_DUMB16_SMART8GPIO 0xb
+#define IOPAD_DUMB16_DUMB16 0xc
+#define IOPAD_SMART8_SMART8 0xc
+
+/*
+ *defined for indicating boundary and cycle burst length
+ */
+#define CFG_BOUNDARY_1KB (1<<5)
+#define CFG_BOUNDARY_4KB (0<<5)
+#define CFG_CYC_BURST_LEN16 (1<<4)
+#define CFG_CYC_BURST_LEN8 (0<<4)
+
+/*
+ * defined Dumb Panel Clock Divider register
+ * SCLK_Source bit[31]
+ */
+ /* 0: PLL clock select*/
+#define AXI_BUS_SEL 0x80000000
+#define CCD_CLK_SEL 0x40000000
+#define DCON_CLK_SEL 0x20000000
+#define ENA_CLK_INT_DIV CONFIG_FB_DOVE_CLCD_SCLK_DIV
+#define IDLE_CLK_INT_DIV 0x1 /* idle Integer Divider */
+#define DIS_CLK_INT_DIV 0x0 /* Disable Integer Divider */
+
+/* SRAM ID */
+#define SRAMID_GAMMA_YR 0x0
+#define SRAMID_GAMMA_UG 0x1
+#define SRAMID_GAMMA_VB 0x2
+#define SRAMID_PALATTE 0x3
+#define SRAMID_HWC 0xf
+
+/* SRAM INIT Read/Write */
+#define SRAMID_INIT_READ 0x0
+#define SRAMID_INIT_WRITE 0x2
+#define SRAMID_INIT_DEFAULT 0x3
+
+/*
+ * defined VSYNC selection mode for DMA control 1 register
+ * DMA1 bit[30:28]
+ */
+#define VMODE_SMPN 0x0
+#define VMODE_SMPNIRQ 0x1
+#define VMODE_DUMB 0x2
+#define VMODE_IPE 0x3
+#define VMODE_IRE 0x4
+
+/*
+ * defined Configure Alpha and Alpha mode for DMA control 1 register
+ * DMA1 bit[15:08](alpha) / bit[17:16](alpha mode)
+ */
+/* ALPHA mode */
+#define MODE_ALPHA_DMA 0x0
+#define MODE_ALPHA_GRA 0x1
+#define MODE_ALPHA_CFG 0x2
+
+/* alpha value */
+#define ALPHA_NOGRAPHIC 0xFF /* all video, no graphic */
+#define ALPHA_NOVIDEO 0x00 /* all graphic, no video */
+#define ALPHA_GRAPHNVIDEO 0x0F /* Selects graphic & video */
+
+/*
+ * defined Pixel Command for DMA control 1 register
+ * DMA1 bit[07:00]
+ */
+#define PIXEL_CMD 0x81
+
+/* DSI */
+/* DSI1 - 4 Lane Controller base */
+#define DSI1_REGS_PHYSICAL_BASE 0xD420B800
+/* DSI2 - 3 Lane Controller base */
+#define DSI2_REGS_PHYSICAL_BASE 0xD420BA00
+
+/* DSI Controller Registers */
+struct dsi_lcd_regs {
+#define DSI_LCD1_CTRL_0 0x100 /* DSI Active Panel 1 Control register 0 */
+#define DSI_LCD1_CTRL_1 0x104 /* DSI Active Panel 1 Control register 1 */
+ u32 ctrl0;
+ u32 ctrl1;
+ u32 reserved1[2];
+
+#define DSI_LCD1_TIMING_0 0x110 /* Timing register 0 */
+#define DSI_LCD1_TIMING_1 0x114 /* Timing register 1 */
+#define DSI_LCD1_TIMING_2 0x118 /* Timing register 2 */
+#define DSI_LCD1_TIMING_3 0x11C /* Timing register 3 */
+#define DSI_LCD1_WC_0 0x120 /* Word Count register 0 */
+#define DSI_LCD1_WC_1 0x124 /* Word Count register 1 */
+#define DSI_LCD1_WC_2 0x128 /* Word Count register 2 */
+ u32 timing0;
+ u32 timing1;
+ u32 timing2;
+ u32 timing3;
+ u32 wc0;
+ u32 wc1;
+ u32 wc2;
+ u32 reserved2[1];
+ u32 slot_cnt0;
+ u32 slot_cnt1;
+ u32 reserved3[2];
+ u32 status_0;
+ u32 status_1;
+ u32 status_2;
+ u32 status_3;
+ u32 status_4;
+};
+
+struct dsi_regs {
+#define DSI_CTRL_0 0x000 /* DSI control register 0 */
+#define DSI_CTRL_1 0x004 /* DSI control register 1 */
+ u32 ctrl0;
+ u32 ctrl1;
+ u32 reserved1[2];
+ u32 irq_status;
+ u32 irq_mask;
+ u32 reserved2[2];
+
+#define DSI_CPU_CMD_0 0x020 /* DSI CPU packet command register 0 */
+#define DSI_CPU_CMD_1 0x024 /* DSU CPU Packet Command Register 1 */
+#define DSI_CPU_CMD_3 0x02C /* DSU CPU Packet Command Register 3 */
+#define DSI_CPU_WDAT_0 0x030 /* DSI CUP */
+ u32 cmd0;
+ u32 cmd1;
+ u32 cmd2;
+ u32 cmd3;
+ u32 dat0;
+ u32 status0;
+ u32 status1;
+ u32 status2;
+ u32 status3;
+ u32 status4;
+ u32 reserved3[2];
+
+ u32 smt_cmd;
+ u32 smt_ctrl0;
+ u32 smt_ctrl1;
+ u32 reserved4[1];
+
+ u32 rx0_status;
+
+/* Rx Packet Header - data from slave device */
+#define DSI_RX_PKT_HDR_0 0x064
+ u32 rx0_header;
+ u32 rx1_status;
+ u32 rx1_header;
+ u32 rx_ctrl;
+ u32 rx_ctrl1;
+ u32 rx2_status;
+ u32 rx2_header;
+ u32 reserved5[1];
+
+ u32 phy_ctrl1;
+#define DSI_PHY_CTRL_2 0x088 /* DSI DPHI Control Register 2 */
+#define DSI_PHY_CTRL_3 0x08C /* DPHY Control Register 3 */
+ u32 phy_ctrl2;
+ u32 phy_ctrl3;
+ u32 phy_status0;
+ u32 phy_status1;
+ u32 reserved6[5];
+ u32 phy_status2;
+
+#define DSI_PHY_RCOMP_0 0x0B0 /* DPHY Rcomp Control Register */
+ u32 phy_rcomp0;
+ u32 reserved7[3];
+#define DSI_PHY_TIME_0 0x0C0 /* DPHY Timing Control Register 0 */
+#define DSI_PHY_TIME_1 0x0C4 /* DPHY Timing Control Register 1 */
+#define DSI_PHY_TIME_2 0x0C8 /* DPHY Timing Control Register 2 */
+#define DSI_PHY_TIME_3 0x0CC /* DPHY Timing Control Register 3 */
+#define DSI_PHY_TIME_4 0x0D0 /* DPHY Timing Control Register 4 */
+#define DSI_PHY_TIME_5 0x0D4 /* DPHY Timing Control Register 5 */
+ u32 phy_timing0;
+ u32 phy_timing1;
+ u32 phy_timing2;
+ u32 phy_timing3;
+ u32 phy_code_0;
+ u32 phy_code_1;
+ u32 reserved8[2];
+ u32 mem_ctrl;
+ u32 tx_timer;
+ u32 rx_timer;
+ u32 turn_timer;
+ u32 reserved9[4];
+
+#define DSI_LCD1_CTRL_0 0x100 /* DSI Active Panel 1 Control register 0 */
+#define DSI_LCD1_CTRL_1 0x104 /* DSI Active Panel 1 Control register 1 */
+#define DSI_LCD1_TIMING_0 0x110 /* Timing register 0 */
+#define DSI_LCD1_TIMING_1 0x114 /* Timing register 1 */
+#define DSI_LCD1_TIMING_2 0x118 /* Timing register 2 */
+#define DSI_LCD1_TIMING_3 0x11C /* Timing register 3 */
+#define DSI_LCD1_WC_0 0x120 /* Word Count register 0 */
+#define DSI_LCD1_WC_1 0x124 /* Word Count register 1 */
+#define DSI_LCD1_WC_2 0x128 /* Word Count register 2 */
+ struct dsi_lcd_regs lcd1;
+ u32 reserved10[11];
+ struct dsi_lcd_regs lcd2;
+};
+
+#define DSI_LCD2_CTRL_0 0x180 /* DSI Active Panel 2 Control register 0 */
+#define DSI_LCD2_CTRL_1 0x184 /* DSI Active Panel 2 Control register 1 */
+#define DSI_LCD2_TIMING_0 0x190 /* Timing register 0 */
+#define DSI_LCD2_TIMING_1 0x194 /* Timing register 1 */
+#define DSI_LCD2_TIMING_2 0x198 /* Timing register 2 */
+#define DSI_LCD2_TIMING_3 0x19C /* Timing register 3 */
+#define DSI_LCD2_WC_0 0x1A0 /* Word Count register 0 */
+#define DSI_LCD2_WC_1 0x1A4 /* Word Count register 1 */
+#define DSI_LCD2_WC_2 0x1A8 /* Word Count register 2 */
+
+/* DSI_CTRL_0 0x0000 DSI Control Register 0 */
+#define DSI_CTRL_0_CFG_SOFT_RST (1<<31)
+#define DSI_CTRL_0_CFG_SOFT_RST_REG (1<<30)
+#define DSI_CTRL_0_CFG_LCD1_TX_EN (1<<8)
+#define DSI_CTRL_0_CFG_LCD1_SLV (1<<4)
+#define DSI_CTRL_0_CFG_LCD1_EN (1<<0)
+
+/* DSI_CTRL_1 0x0004 DSI Control Register 1 */
+#define DSI_CTRL_1_CFG_EOTP (1<<8)
+#define DSI_CTRL_1_CFG_RSVD (2<<4)
+#define DSI_CTRL_1_CFG_LCD2_VCH_NO_MASK (3<<2)
+#define DSI_CTRL_1_CFG_LCD2_VCH_NO_SHIFT 2
+#define DSI_CTRL_1_CFG_LCD1_VCH_NO_MASK (3<<0)
+#define DSI_CTRL_1_CFG_LCD1_VCH_NO_SHIFT 0
+
+/* DSI_LCD1_CTRL_1 0x0104 DSI Active Panel 1 Control Register 1 */
+/* LCD 1 Vsync Reset Enable */
+#define DSI_LCD1_CTRL_1_CFG_L1_VSYNC_RST_EN (1<<31)
+/* LCD 1 2K Pixel Buffer Mode Enable */
+#define DSI_LCD1_CTRL_1_CFG_L1_M2K_EN (1<<30)
+/* Bit(s) DSI_LCD1_CTRL_1_RSRV_29_23 reserved */
+/* Long Blanking Packet Enable */
+#define DSI_LCD1_CTRL_1_CFG_L1_HLP_PKT_EN (1<<22)
+/* Extra Long Blanking Packet Enable */
+#define DSI_LCD1_CTRL_1_CFG_L1_HEX_PKT_EN (1<<21)
+/* Front Porch Packet Enable */
+#define DSI_LCD1_CTRL_1_CFG_L1_HFP_PKT_EN (1<<20)
+/* hact Packet Enable */
+#define DSI_LCD1_CTRL_1_CFG_L1_HACT_PKT_EN (1<<19)
+/* Back Porch Packet Enable */
+#define DSI_LCD1_CTRL_1_CFG_L1_HBP_PKT_EN (1<<18)
+/* hse Packet Enable */
+#define DSI_LCD1_CTRL_1_CFG_L1_HSE_PKT_EN (1<<17)
+/* hsa Packet Enable */
+#define DSI_LCD1_CTRL_1_CFG_L1_HSA_PKT_EN (1<<16)
+/* All Item Enable after Pixel Data */
+#define DSI_LCD1_CTRL_1_CFG_L1_ALL_SLOT_EN (1<<15)
+/* Extra Long Packet Enable after Pixel Data */
+#define DSI_LCD1_CTRL_1_CFG_L1_HEX_SLOT_EN (1<<14)
+/* Bit(s) DSI_LCD1_CTRL_1_RSRV_13_11 reserved */
+/* Turn Around Bus at Last h Line */
+#define DSI_LCD1_CTRL_1_CFG_L1_LAST_LINE_TURN (1<<10)
+/* Go to Low Power Every Frame */
+#define DSI_LCD1_CTRL_1_CFG_L1_LPM_FRAME_EN (1<<9)
+/* Go to Low Power Every Line */
+#define DSI_LCD1_CTRL_1_CFG_L1_LPM_LINE_EN (1<<8)
+/* Bit(s) DSI_LCD1_CTRL_1_RSRV_7_4 reserved */
+/* DSI Transmission Mode for LCD 1 */
+#define DSI_LCD1_CTRL_1_CFG_L1_BURST_MODE_SHIFT 2
+#define DSI_LCD1_CTRL_1_CFG_L1_BURST_MODE_MASK (3<<2)
+/* LCD 1 Input Data RGB Mode for LCD 1 */
+#define DSI_LCD2_CTRL_1_CFG_L1_RGB_TYPE_SHIFT 0
+#define DSI_LCD2_CTRL_1_CFG_L1_RGB_TYPE_MASK (3<<2)
+
+/* DSI_PHY_CTRL_2 0x0088 DPHY Control Register 2 */
+/* Bit(s) DSI_PHY_CTRL_2_RSRV_31_12 reserved */
+/* DPHY LP Receiver Enable */
+#define DSI_PHY_CTRL_2_CFG_CSR_LANE_RESC_EN_MASK (0xf<<8)
+#define DSI_PHY_CTRL_2_CFG_CSR_LANE_RESC_EN_SHIFT 8
+/* DPHY Data Lane Enable */
+#define DSI_PHY_CTRL_2_CFG_CSR_LANE_EN_MASK (0xf<<4)
+#define DSI_PHY_CTRL_2_CFG_CSR_LANE_EN_SHIFT 4
+/* DPHY Bus Turn Around */
+#define DSI_PHY_CTRL_2_CFG_CSR_LANE_TURN_MASK (0xf)
+#define DSI_PHY_CTRL_2_CFG_CSR_LANE_TURN_SHIFT 0
+
+/* DSI_CPU_CMD_1 0x0024 DSI CPU Packet Command Register 1 */
+/* Bit(s) DSI_CPU_CMD_1_RSRV_31_24 reserved */
+/* LPDT TX Enable */
+#define DSI_CPU_CMD_1_CFG_TXLP_LPDT_MASK (0xf<<20)
+#define DSI_CPU_CMD_1_CFG_TXLP_LPDT_SHIFT 20
+/* ULPS TX Enable */
+#define DSI_CPU_CMD_1_CFG_TXLP_ULPS_MASK (0xf<<16)
+#define DSI_CPU_CMD_1_CFG_TXLP_ULPS_SHIFT 16
+/* Low Power TX Trigger Code */
+#define DSI_CPU_CMD_1_CFG_TXLP_TRIGGER_CODE_MASK (0xffff)
+#define DSI_CPU_CMD_1_CFG_TXLP_TRIGGER_CODE_SHIFT 0
+
+/* DSI_PHY_TIME_0 0x00c0 DPHY Timing Control Register 0 */
+/* Length of HS Exit Period in tx_clk_esc Cycles */
+#define DSI_PHY_TIME_0_CFG_CSR_TIME_HS_EXIT_MASK (0xff<<24)
+#define DSI_PHY_TIME_0_CFG_CSR_TIME_HS_EXIT_SHIFT 24
+/* DPHY HS Trail Period Length */
+#define DSI_PHY_TIME_0_CFG_CSR_TIME_HS_TRAIL_MASK (0xff<<16)
+#define DSI_PHY_TIME_0_CFG_CSR_TIME_HS_TRAIL_SHIFT 16
+/* DPHY HS Zero State Length */
+#define DSI_PHY_TIME_0_CDG_CSR_TIME_HS_ZERO_MASK (0xff<<8)
+#define DSI_PHY_TIME_0_CDG_CSR_TIME_HS_ZERO_SHIFT 8
+/* DPHY HS Prepare State Length */
+#define DSI_PHY_TIME_0_CFG_CSR_TIME_HS_PREP_MASK (0xff)
+#define DSI_PHY_TIME_0_CFG_CSR_TIME_HS_PREP_SHIFT 0
+
+/* DSI_PHY_TIME_1 0x00c4 DPHY Timing Control Register 1 */
+/* Time to Drive LP-00 by New Transmitter */
+#define DSI_PHY_TIME_1_CFG_CSR_TIME_TA_GET_MASK (0xff<<24)
+#define DSI_PHY_TIME_1_CFG_CSR_TIME_TA_GET_SHIFT 24
+/* Time to Drive LP-00 after Turn Request */
+#define DSI_PHY_TIME_1_CFG_CSR_TIME_TA_GO_MASK (0xff<<16)
+#define DSI_PHY_TIME_1_CFG_CSR_TIME_TA_GO_SHIFT 16
+/* DPHY HS Wakeup Period Length */
+#define DSI_PHY_TIME_1_CFG_CSR_TIME_WAKEUP_MASK (0xffff)
+#define DSI_PHY_TIME_1_CFG_CSR_TIME_WAKEUP_SHIFT 0
+
+/* DSI_PHY_TIME_2 0x00c8 DPHY Timing Control Register 2 */
+/* DPHY CLK Exit Period Length */
+#define DSI_PHY_TIME_2_CFG_CSR_TIME_CK_EXIT_MASK (0xff<<24)
+#define DSI_PHY_TIME_2_CFG_CSR_TIME_CK_EXIT_SHIFT 24
+/* DPHY CLK Trail Period Length */
+#define DSI_PHY_TIME_2_CFG_CSR_TIME_CK_TRAIL_MASK (0xff<<16)
+#define DSI_PHY_TIME_2_CFG_CSR_TIME_CK_TRAIL_SHIFT 16
+/* DPHY CLK Zero State Length */
+#define DSI_PHY_TIME_2_CFG_CSR_TIME_CK_ZERO_MASK (0xff<<8)
+#define DSI_PHY_TIME_2_CFG_CSR_TIME_CK_ZERO_SHIFT 8
+/* DPHY CLK LP Length */
+#define DSI_PHY_TIME_2_CFG_CSR_TIME_CK_LPX_MASK (0xff)
+#define DSI_PHY_TIME_2_CFG_CSR_TIME_CK_LPX_SHIFT 0
+
+/* DSI_PHY_TIME_3 0x00cc DPHY Timing Control Register 3 */
+/* Bit(s) DSI_PHY_TIME_3_RSRV_31_16 reserved */
+/* DPHY LP Length */
+#define DSI_PHY_TIME_3_CFG_CSR_TIME_LPX_MASK (0xff<<8)
+#define DSI_PHY_TIME_3_CFG_CSR_TIME_LPX_SHIFT 8
+/* DPHY HS req to rdy Length */
+#define DSI_PHY_TIME_3_CFG_CSR_TIME_REQRDY_MASK (0xff)
+#define DSI_PHY_TIME_3_CFG_CSR_TIME_REQRDY_SHIFT 0
+
+/*
+ * DSI timings
+ * PXA988 has diffrent ESC CLK with MMP2/MMP3
+ * it will be used in dsi_set_dphy() in pxa688_phy.c
+ * as low power mode clock.
+ */
+#ifdef CONFIG_CPU_PXA988
+#define DSI_ESC_CLK 52 /* Unit: Mhz */
+#define DSI_ESC_CLK_T 19 /* Unit: ns */
+#else
+#define DSI_ESC_CLK 66 /* Unit: Mhz */
+#define DSI_ESC_CLK_T 15 /* Unit: ns */
+#endif
+
+/* LVDS */
+/* LVDS_PHY_CTRL */
+#define LVDS_PHY_CTL 0x2A4
+#define LVDS_PLL_LOCK (1 << 31)
+#define LVDS_PHY_EXT_MASK (7 << 28)
+#define LVDS_PHY_EXT_SHIFT (28)
+#define LVDS_CLK_PHASE_MASK (0x7f << 16)
+#define LVDS_CLK_PHASE_SHIFT (16)
+#define LVDS_SSC_RESET_EXT (1 << 13)
+#define LVDS_SSC_MODE_DOWN_SPREAD (1 << 12)
+#define LVDS_SSC_EN (1 << 11)
+#define LVDS_PU_PLL (1 << 10)
+#define LVDS_PU_TX (1 << 9)
+#define LVDS_PU_IVREF (1 << 8)
+#define LVDS_CLK_SEL (1 << 7)
+#define LVDS_CLK_SEL_LVDS_PCLK (1 << 7)
+#define LVDS_PD_CH_MASK (0x3f << 1)
+#define LVDS_PD_CH(ch) ((ch) << 1)
+#define LVDS_RST (1 << 0)
+
+#define LVDS_PHY_CTL_EXT 0x2A8
+
+/* LVDS_PHY_CTRL_EXT1 */
+#define LVDS_SSC_RNGE_MASK (0x7ff << 16)
+#define LVDS_SSC_RNGE_SHIFT (16)
+#define LVDS_RESERVE_IN_MASK (0xf << 12)
+#define LVDS_RESERVE_IN_SHIFT (12)
+#define LVDS_TEST_MON_MASK (0x7 << 8)
+#define LVDS_TEST_MON_SHIFT (8)
+#define LVDS_POL_SWAP_MASK (0x3f << 0)
+#define LVDS_POL_SWAP_SHIFT (0)
+
+/* LVDS_PHY_CTRL_EXT2 */
+#define LVDS_TX_DIF_AMP_MASK (0xf << 24)
+#define LVDS_TX_DIF_AMP_SHIFT (24)
+#define LVDS_TX_DIF_CM_MASK (0x3 << 22)
+#define LVDS_TX_DIF_CM_SHIFT (22)
+#define LVDS_SELLV_TXCLK_MASK (0x1f << 16)
+#define LVDS_SELLV_TXCLK_SHIFT (16)
+#define LVDS_TX_CMFB_EN (0x1 << 15)
+#define LVDS_TX_TERM_EN (0x1 << 14)
+#define LVDS_SELLV_TXDATA_MASK (0x1f << 8)
+#define LVDS_SELLV_TXDATA_SHIFT (8)
+#define LVDS_SELLV_OP7_MASK (0x3 << 6)
+#define LVDS_SELLV_OP7_SHIFT (6)
+#define LVDS_SELLV_OP6_MASK (0x3 << 4)
+#define LVDS_SELLV_OP6_SHIFT (4)
+#define LVDS_SELLV_OP9_MASK (0x3 << 2)
+#define LVDS_SELLV_OP9_SHIFT (2)
+#define LVDS_STRESSTST_EN (0x1 << 0)
+
+/* LVDS_PHY_CTRL_EXT3 */
+#define LVDS_KVCO_MASK (0xf << 28)
+#define LVDS_KVCO_SHIFT (28)
+#define LVDS_CTUNE_MASK (0x3 << 26)
+#define LVDS_CTUNE_SHIFT (26)
+#define LVDS_VREG_IVREF_MASK (0x3 << 24)
+#define LVDS_VREG_IVREF_SHIFT (24)
+#define LVDS_VDDL_MASK (0xf << 20)
+#define LVDS_VDDL_SHIFT (20)
+#define LVDS_VDDM_MASK (0x3 << 18)
+#define LVDS_VDDM_SHIFT (18)
+#define LVDS_FBDIV_MASK (0xf << 8)
+#define LVDS_FBDIV_SHIFT (8)
+#define LVDS_REFDIV_MASK (0x7f << 0)
+#define LVDS_REFDIV_SHIFT (0)
+
+/* LVDS_PHY_CTRL_EXT4 */
+#define LVDS_SSC_FREQ_DIV_MASK (0xffff << 16)
+#define LVDS_SSC_FREQ_DIV_SHIFT (16)
+#define LVDS_INTPI_MASK (0xf << 12)
+#define LVDS_INTPI_SHIFT (12)
+#define LVDS_VCODIV_SEL_SE_MASK (0xf << 8)
+#define LVDS_VCODIV_SEL_SE_SHIFT (8)
+#define LVDS_RESET_INTP_EXT (0x1 << 7)
+#define LVDS_VCO_VRNG_MASK (0x7 << 4)
+#define LVDS_VCO_VRNG_SHIFT (4)
+#define LVDS_PI_EN (0x1 << 3)
+#define LVDS_ICP_MASK (0x7 << 0)
+#define LVDS_ICP_SHIFT (0)
+
+/* LVDS_PHY_CTRL_EXT5 */
+#define LVDS_FREQ_OFFSET_MASK (0x1ffff << 15)
+#define LVDS_FREQ_OFFSET_SHIFT (15)
+#define LVDS_FREQ_OFFSET_VALID (0x1 << 2)
+#define LVDS_FREQ_OFFSET_MODE_CK_DIV4_OUT (0x1 << 1)
+#define LVDS_FREQ_OFFSET_MODE_EN (0x1 << 0)
+
+/* VDMA */
+struct vdma_ch_regs {
+#define VDMA_DC_SADDR_1 0x320
+#define VDMA_DC_SADDR_2 0x3A0
+#define VDMA_DC_SZ_1 0x324
+#define VDMA_DC_SZ_2 0x3A4
+#define VDMA_CTRL_1 0x328
+#define VDMA_CTRL_2 0x3A8
+#define VDMA_SRC_SZ_1 0x32C
+#define VDMA_SRC_SZ_2 0x3AC
+#define VDMA_SA_1 0x330
+#define VDMA_SA_2 0x3B0
+#define VDMA_DA_1 0x334
+#define VDMA_DA_2 0x3B4
+#define VDMA_SZ_1 0x338
+#define VDMA_SZ_2 0x3B8
+ u32 dc_saddr;
+ u32 dc_size;
+ u32 ctrl;
+ u32 src_size;
+ u32 src_addr;
+ u32 dst_addr;
+ u32 dst_size;
+#define VDMA_PITCH_1 0x33C
+#define VDMA_PITCH_2 0x3BC
+#define VDMA_ROT_CTRL_1 0x340
+#define VDMA_ROT_CTRL_2 0x3C0
+#define VDMA_RAM_CTRL0_1 0x344
+#define VDMA_RAM_CTRL0_2 0x3C4
+#define VDMA_RAM_CTRL1_1 0x348
+#define VDMA_RAM_CTRL1_2 0x3C8
+ u32 pitch;
+ u32 rot_ctrl;
+ u32 ram_ctrl0;
+ u32 ram_ctrl1;
+
+};
+struct vdma_regs {
+#define VDMA_ARBR_CTRL 0x300
+#define VDMA_IRQR 0x304
+#define VDMA_IRQM 0x308
+#define VDMA_IRQS 0x30C
+#define VDMA_MDMA_ARBR_CTRL 0x310
+ u32 arbr_ctr;
+ u32 irq_raw;
+ u32 irq_mask;
+ u32 irq_status;
+ u32 mdma_arbr_ctrl;
+ u32 reserved[3];
+
+ struct vdma_ch_regs ch1;
+ u32 reserved2[21];
+ struct vdma_ch_regs ch2;
+};
+
+/* CMU */
+#define CMU_PIP_DE_H_CFG 0x0008
+#define CMU_PRI1_H_CFG 0x000C
+#define CMU_PRI2_H_CFG 0x0010
+#define CMU_ACE_MAIN_DE1_H_CFG 0x0014
+#define CMU_ACE_MAIN_DE2_H_CFG 0x0018
+#define CMU_ACE_PIP_DE1_H_CFG 0x001C
+#define CMU_ACE_PIP_DE2_H_CFG 0x0020
+#define CMU_PIP_DE_V_CFG 0x0024
+#define CMU_PRI_V_CFG 0x0028
+#define CMU_ACE_MAIN_DE_V_CFG 0x002C
+#define CMU_ACE_PIP_DE_V_CFG 0x0030
+#define CMU_BAR_0_CFG 0x0034
+#define CMU_BAR_1_CFG 0x0038
+#define CMU_BAR_2_CFG 0x003C
+#define CMU_BAR_3_CFG 0x0040
+#define CMU_BAR_4_CFG 0x0044
+#define CMU_BAR_5_CFG 0x0048
+#define CMU_BAR_6_CFG 0x004C
+#define CMU_BAR_7_CFG 0x0050
+#define CMU_BAR_8_CFG 0x0054
+#define CMU_BAR_9_CFG 0x0058
+#define CMU_BAR_10_CFG 0x005C
+#define CMU_BAR_11_CFG 0x0060
+#define CMU_BAR_12_CFG 0x0064
+#define CMU_BAR_13_CFG 0x0068
+#define CMU_BAR_14_CFG 0x006C
+#define CMU_BAR_15_CFG 0x0070
+#define CMU_BAR_CTRL 0x0074
+#define PATTERN_TOTAL 0x0078
+#define PATTERN_ACTIVE 0x007C
+#define PATTERN_FRONT_PORCH 0x0080
+#define PATTERN_BACK_PORCH 0x0084
+#define CMU_CLK_CTRL 0x0088
+
+#define CMU_ICSC_M_C0_L 0x0900
+#define CMU_ICSC_M_C0_H 0x0901
+#define CMU_ICSC_M_C1_L 0x0902
+#define CMU_ICSC_M_C1_H 0x0903
+#define CMU_ICSC_M_C2_L 0x0904
+#define CMU_ICSC_M_C2_H 0x0905
+#define CMU_ICSC_M_C3_L 0x0906
+#define CMU_ICSC_M_C3_H 0x0907
+#define CMU_ICSC_M_C4_L 0x0908
+#define CMU_ICSC_M_C4_H 0x0909
+#define CMU_ICSC_M_C5_L 0x090A
+#define CMU_ICSC_M_C5_H 0x090B
+#define CMU_ICSC_M_C6_L 0x090C
+#define CMU_ICSC_M_C6_H 0x090D
+#define CMU_ICSC_M_C7_L 0x090E
+#define CMU_ICSC_M_C7_H 0x090F
+#define CMU_ICSC_M_C8_L 0x0910
+#define CMU_ICSC_M_C8_H 0x0911
+#define CMU_ICSC_M_O1_0 0x0914
+#define CMU_ICSC_M_O1_1 0x0915
+#define CMU_ICSC_M_O1_2 0x0916
+#define CMU_ICSC_M_O2_0 0x0918
+#define CMU_ICSC_M_O2_1 0x0919
+#define CMU_ICSC_M_O2_2 0x091A
+#define CMU_ICSC_M_O3_0 0x091C
+#define CMU_ICSC_M_O3_1 0x091D
+#define CMU_ICSC_M_O3_2 0x091E
+#define CMU_ICSC_P_C0_L 0x0920
+#define CMU_ICSC_P_C0_H 0x0921
+#define CMU_ICSC_P_C1_L 0x0922
+#define CMU_ICSC_P_C1_H 0x0923
+#define CMU_ICSC_P_C2_L 0x0924
+#define CMU_ICSC_P_C2_H 0x0925
+#define CMU_ICSC_P_C3_L 0x0926
+#define CMU_ICSC_P_C3_H 0x0927
+#define CMU_ICSC_P_C4_L 0x0928
+#define CMU_ICSC_P_C4_H 0x0929
+#define CMU_ICSC_P_C5_L 0x092A
+#define CMU_ICSC_P_C5_H 0x092B
+#define CMU_ICSC_P_C6_L 0x092C
+#define CMU_ICSC_P_C6_H 0x092D
+#define CMU_ICSC_P_C7_L 0x092E
+#define CMU_ICSC_P_C7_H 0x092F
+#define CMU_ICSC_P_C8_L 0x0930
+#define CMU_ICSC_P_C8_H 0x0931
+#define CMU_ICSC_P_O1_0 0x0934
+#define CMU_ICSC_P_O1_1 0x0935
+#define CMU_ICSC_P_O1_2 0x0936
+#define CMU_ICSC_P_O2_0 0x0938
+#define CMU_ICSC_P_O2_1 0x0939
+#define CMU_ICSC_P_O2_2 0x093A
+#define CMU_ICSC_P_O3_0 0x093C
+#define CMU_ICSC_P_O3_1 0x093D
+#define CMU_ICSC_P_O3_2 0x093E
+#define CMU_BR_M_EN 0x0940
+#define CMU_BR_M_TH1_L 0x0942
+#define CMU_BR_M_TH1_H 0x0943
+#define CMU_BR_M_TH2_L 0x0944
+#define CMU_BR_M_TH2_H 0x0945
+#define CMU_ACE_M_EN 0x0950
+#define CMU_ACE_M_WFG1 0x0951
+#define CMU_ACE_M_WFG2 0x0952
+#define CMU_ACE_M_WFG3 0x0953
+#define CMU_ACE_M_TH0 0x0954
+#define CMU_ACE_M_TH1 0x0955
+#define CMU_ACE_M_TH2 0x0956
+#define CMU_ACE_M_TH3 0x0957
+#define CMU_ACE_M_TH4 0x0958
+#define CMU_ACE_M_TH5 0x0959
+#define CMU_ACE_M_OP0_L 0x095A
+#define CMU_ACE_M_OP0_H 0x095B
+#define CMU_ACE_M_OP5_L 0x095C
+#define CMU_ACE_M_OP5_H 0x095D
+#define CMU_ACE_M_GB2 0x095E
+#define CMU_ACE_M_GB3 0x095F
+#define CMU_ACE_M_MS1 0x0960
+#define CMU_ACE_M_MS2 0x0961
+#define CMU_ACE_M_MS3 0x0962
+#define CMU_BR_P_EN 0x0970
+#define CMU_BR_P_TH1_L 0x0972
+#define CMU_BR_P_TH1_H 0x0973
+#define CMU_BR_P_TH2_L 0x0974
+#define CMU_BR_P_TH2_H 0x0975
+#define CMU_ACE_P_EN 0x0980
+#define CMU_ACE_P_WFG1 0x0981
+#define CMU_ACE_P_WFG2 0x0982
+#define CMU_ACE_P_WFG3 0x0983
+#define CMU_ACE_P_TH0 0x0984
+#define CMU_ACE_P_TH1 0x0985
+#define CMU_ACE_P_TH2 0x0986
+#define CMU_ACE_P_TH3 0x0987
+#define CMU_ACE_P_TH4 0x0988
+#define CMU_ACE_P_TH5 0x0989
+#define CMU_ACE_P_OP0_L 0x098A
+#define CMU_ACE_P_OP0_H 0x098B
+#define CMU_ACE_P_OP5_L 0x098C
+#define CMU_ACE_P_OP5_H 0x098D
+#define CMU_ACE_P_GB2 0x098E
+#define CMU_ACE_P_GB3 0x098F
+#define CMU_ACE_P_MS1 0x0990
+#define CMU_ACE_P_MS2 0x0991
+#define CMU_ACE_P_MS3 0x0992
+#define CMU_FTDC_M_EN 0x09A0
+#define CMU_FTDC_P_EN 0x09A1
+#define CMU_FTDC_INLOW_L 0x09A2
+#define CMU_FTDC_INLOW_H 0x09A3
+#define CMU_FTDC_INHIGH_L 0x09A4
+#define CMU_FTDC_INHIGH_H 0x09A5
+#define CMU_FTDC_OUTLOW_L 0x09A6
+#define CMU_FTDC_OUTLOW_H 0x09A7
+#define CMU_FTDC_OUTHIGH_L 0x09A8
+#define CMU_FTDC_OUTHIGH_H 0x09A9
+#define CMU_FTDC_YLOW 0x09AA
+#define CMU_FTDC_YHIGH 0x09AB
+#define CMU_FTDC_CH1 0x09AC
+#define CMU_FTDC_CH2_L 0x09AE
+#define CMU_FTDC_CH2_H 0x09AF
+#define CMU_FTDC_CH3_L 0x09B0
+#define CMU_FTDC_CH3_H 0x09B1
+#define CMU_FTDC_1_C00_6 0x09B2
+#define CMU_FTDC_1_C01_6 0x09B8
+#define CMU_FTDC_1_C11_6 0x09BE
+#define CMU_FTDC_1_C10_6 0x09C4
+#define CMU_FTDC_1_OFF00_6 0x09CA
+#define CMU_FTDC_1_OFF10_6 0x09D0
+#define CMU_HS_M_EN 0x0A00
+#define CMU_HS_M_AX1_L 0x0A02
+#define CMU_HS_M_AX1_H 0x0A03
+#define CMU_HS_M_AX2_L 0x0A04
+#define CMU_HS_M_AX2_H 0x0A05
+#define CMU_HS_M_AX3_L 0x0A06
+#define CMU_HS_M_AX3_H 0x0A07
+#define CMU_HS_M_AX4_L 0x0A08
+#define CMU_HS_M_AX4_H 0x0A09
+#define CMU_HS_M_AX5_L 0x0A0A
+#define CMU_HS_M_AX5_H 0x0A0B
+#define CMU_HS_M_AX6_L 0x0A0C
+#define CMU_HS_M_AX6_H 0x0A0D
+#define CMU_HS_M_AX7_L 0x0A0E
+#define CMU_HS_M_AX7_H 0x0A0F
+#define CMU_HS_M_AX8_L 0x0A10
+#define CMU_HS_M_AX8_H 0x0A11
+#define CMU_HS_M_AX9_L 0x0A12
+#define CMU_HS_M_AX9_H 0x0A13
+#define CMU_HS_M_AX10_L 0x0A14
+#define CMU_HS_M_AX10_H 0x0A15
+#define CMU_HS_M_AX11_L 0x0A16
+#define CMU_HS_M_AX11_H 0x0A17
+#define CMU_HS_M_AX12_L 0x0A18
+#define CMU_HS_M_AX12_H 0x0A19
+#define CMU_HS_M_AX13_L 0x0A1A
+#define CMU_HS_M_AX13_H 0x0A1B
+#define CMU_HS_M_AX14_L 0x0A1C
+#define CMU_HS_M_AX14_H 0x0A1D
+#define CMU_HS_M_H1_H14 0x0A1E
+#define CMU_HS_M_S1_S14 0x0A2C
+#define CMU_HS_M_GL 0x0A3A
+#define CMU_HS_M_MAXSAT_RGB_Y_L 0x0A3C
+#define CMU_HS_M_MAXSAT_RGB_Y_H 0x0A3D
+#define CMU_HS_M_MAXSAT_RCR_L 0x0A3E
+#define CMU_HS_M_MAXSAT_RCR_H 0x0A3F
+#define CMU_HS_M_MAXSAT_RCB_L 0x0A40
+#define CMU_HS_M_MAXSAT_RCB_H 0x0A41
+#define CMU_HS_M_MAXSAT_GCR_L 0x0A42
+#define CMU_HS_M_MAXSAT_GCR_H 0x0A43
+#define CMU_HS_M_MAXSAT_GCB_L 0x0A44
+#define CMU_HS_M_MAXSAT_GCB_H 0x0A45
+#define CMU_HS_M_MAXSAT_BCR_L 0x0A46
+#define CMU_HS_M_MAXSAT_BCR_H 0x0A47
+#define CMU_HS_M_MAXSAT_BCB_L 0x0A48
+#define CMU_HS_M_MAXSAT_BCB_H 0x0A49
+#define CMU_HS_M_ROFF_L 0x0A4A
+#define CMU_HS_M_ROFF_H 0x0A4B
+#define CMU_HS_M_GOFF_L 0x0A4C
+#define CMU_HS_M_GOFF_H 0x0A4D
+#define CMU_HS_M_BOFF_L 0x0A4E
+#define CMU_HS_M_BOFF_H 0x0A4F
+#define CMU_HS_P_EN 0x0A50
+#define CMU_HS_P_AX1_L 0x0A52
+#define CMU_HS_P_AX1_H 0x0A53
+#define CMU_HS_P_AX2_L 0x0A54
+#define CMU_HS_P_AX2_H 0x0A55
+#define CMU_HS_P_AX3_L 0x0A56
+#define CMU_HS_P_AX3_H 0x0A57
+#define CMU_HS_P_AX4_L 0x0A58
+#define CMU_HS_P_AX4_H 0x0A59
+#define CMU_HS_P_AX5_L 0x0A5A
+#define CMU_HS_P_AX5_H 0x0A5B
+#define CMU_HS_P_AX6_L 0x0A5C
+#define CMU_HS_P_AX6_H 0x0A5D
+#define CMU_HS_P_AX7_L 0x0A5E
+#define CMU_HS_P_AX7_H 0x0A5F
+#define CMU_HS_P_AX8_L 0x0A60
+#define CMU_HS_P_AX8_H 0x0A61
+#define CMU_HS_P_AX9_L 0x0A62
+#define CMU_HS_P_AX9_H 0x0A63
+#define CMU_HS_P_AX10_L 0x0A64
+#define CMU_HS_P_AX10_H 0x0A65
+#define CMU_HS_P_AX11_L 0x0A66
+#define CMU_HS_P_AX11_H 0x0A67
+#define CMU_HS_P_AX12_L 0x0A68
+#define CMU_HS_P_AX12_H 0x0A69
+#define CMU_HS_P_AX13_L 0x0A6A
+#define CMU_HS_P_AX13_H 0x0A6B
+#define CMU_HS_P_AX14_L 0x0A6C
+#define CMU_HS_P_AX14_H 0x0A6D
+#define CMU_HS_P_H1_H14 0x0A6E
+#define CMU_HS_P_S1_S14 0x0A7C
+#define CMU_HS_P_GL 0x0A8A
+#define CMU_HS_P_MAXSAT_RGB_Y_L 0x0A8C
+#define CMU_HS_P_MAXSAT_RGB_Y_H 0x0A8D
+#define CMU_HS_P_MAXSAT_RCR_L 0x0A8E
+#define CMU_HS_P_MAXSAT_RCR_H 0x0A8F
+#define CMU_HS_P_MAXSAT_RCB_L 0x0A90
+#define CMU_HS_P_MAXSAT_RCB_H 0x0A91
+#define CMU_HS_P_MAXSAT_GCR_L 0x0A92
+#define CMU_HS_P_MAXSAT_GCR_H 0x0A93
+#define CMU_HS_P_MAXSAT_GCB_L 0x0A94
+#define CMU_HS_P_MAXSAT_GCB_H 0x0A95
+#define CMU_HS_P_MAXSAT_BCR_L 0x0A96
+#define CMU_HS_P_MAXSAT_BCR_H 0x0A97
+#define CMU_HS_P_MAXSAT_BCB_L 0x0A98
+#define CMU_HS_P_MAXSAT_BCB_H 0x0A99
+#define CMU_HS_P_ROFF_L 0x0A9A
+#define CMU_HS_P_ROFF_H 0x0A9B
+#define CMU_HS_P_GOFF_L 0x0A9C
+#define CMU_HS_P_GOFF_H 0x0A9D
+#define CMU_HS_P_BOFF_L 0x0A9E
+#define CMU_HS_P_BOFF_H 0x0A9F
+#define CMU_GLCSC_M_C0_L 0x0AA0
+#define CMU_GLCSC_M_C0_H 0x0AA1
+#define CMU_GLCSC_M_C1_L 0x0AA2
+#define CMU_GLCSC_M_C1_H 0x0AA3
+#define CMU_GLCSC_M_C2_L 0x0AA4
+#define CMU_GLCSC_M_C2_H 0x0AA5
+#define CMU_GLCSC_M_C3_L 0x0AA6
+#define CMU_GLCSC_M_C3_H 0x0AA7
+#define CMU_GLCSC_M_C4_L 0x0AA8
+#define CMU_GLCSC_M_C4_H 0x0AA9
+#define CMU_GLCSC_M_C5_L 0x0AAA
+#define CMU_GLCSC_M_C5_H 0x0AAB
+#define CMU_GLCSC_M_C6_L 0x0AAC
+#define CMU_GLCSC_M_C6_H 0x0AAD
+#define CMU_GLCSC_M_C7_L 0x0AAE
+#define CMU_GLCSC_M_C7_H 0x0AAF
+#define CMU_GLCSC_M_C8_L 0x0AB0
+#define CMU_GLCSC_M_C8_H 0x0AB1
+#define CMU_GLCSC_M_O1_1 0x0AB4
+#define CMU_GLCSC_M_O1_2 0x0AB5
+#define CMU_GLCSC_M_O1_3 0x0AB6
+#define CMU_GLCSC_M_O2_1 0x0AB8
+#define CMU_GLCSC_M_O2_2 0x0AB9
+#define CMU_GLCSC_M_O2_3 0x0ABA
+#define CMU_GLCSC_M_O3_1 0x0ABC
+#define CMU_GLCSC_M_O3_2 0x0ABD
+#define CMU_GLCSC_M_O3_3 0x0ABE
+#define CMU_GLCSC_P_C0_L 0x0AC0
+#define CMU_GLCSC_P_C0_H 0x0AC1
+#define CMU_GLCSC_P_C1_L 0x0AC2
+#define CMU_GLCSC_P_C1_H 0x0AC3
+#define CMU_GLCSC_P_C2_L 0x0AC4
+#define CMU_GLCSC_P_C2_H 0x0AC5
+#define CMU_GLCSC_P_C3_L 0x0AC6
+#define CMU_GLCSC_P_C3_H 0x0AC7
+#define CMU_GLCSC_P_C4_L 0x0AC8
+#define CMU_GLCSC_P_C4_H 0x0AC9
+#define CMU_GLCSC_P_C5_L 0x0ACA
+#define CMU_GLCSC_P_C5_H 0x0ACB
+#define CMU_GLCSC_P_C6_L 0x0ACC
+#define CMU_GLCSC_P_C6_H 0x0ACD
+#define CMU_GLCSC_P_C7_L 0x0ACE
+#define CMU_GLCSC_P_C7_H 0x0ACF
+#define CMU_GLCSC_P_C8_L 0x0AD0
+#define CMU_GLCSC_P_C8_H 0x0AD1
+#define CMU_GLCSC_P_O1_1 0x0AD4
+#define CMU_GLCSC_P_O1_2 0x0AD5
+#define CMU_GLCSC_P_O1_3 0x0AD6
+#define CMU_GLCSC_P_O2_1 0x0AD8
+#define CMU_GLCSC_P_O2_2 0x0AD9
+#define CMU_GLCSC_P_O2_3 0x0ADA
+#define CMU_GLCSC_P_O3_1 0x0ADC
+#define CMU_GLCSC_P_O3_2 0x0ADD
+#define CMU_GLCSC_P_O3_3 0x0ADE
+#define CMU_PIXVAL_M_EN 0x0AE0
+#define CMU_PIXVAL_P_EN 0x0AE1
+
+#define CMU_CLK_CTRL_TCLK 0x0
+#define CMU_CLK_CTRL_SCLK 0x2
+#define CMU_CLK_CTRL_MSK 0x2
+#define CMU_CLK_CTRL_ENABLE 0x1
+
+#define LCD_TOP_CTRL_TV 0x2
+#define LCD_TOP_CTRL_PN 0x0
+#define LCD_TOP_CTRL_SEL_MSK 0x2
+#define LCD_IO_CMU_IN_SEL_MSK (0x3 << 20)
+#define LCD_IO_CMU_IN_SEL_TV 0
+#define LCD_IO_CMU_IN_SEL_PN 1
+#define LCD_IO_CMU_IN_SEL_PN2 2
+#define LCD_IO_TV_OUT_SEL_MSK (0x3 << 26)
+#define LCD_IO_PN_OUT_SEL_MSK (0x3 << 24)
+#define LCD_IO_PN2_OUT_SEL_MSK (0x3 << 28)
+#define LCD_IO_TV_OUT_SEL_NON 3
+#define LCD_IO_PN_OUT_SEL_NON 3
+#define LCD_IO_PN2_OUT_SEL_NON 3
+#define LCD_TOP_CTRL_CMU_ENABLE 0x1
+#define LCD_IO_OVERL_MSK 0xC00000
+#define LCD_IO_OVERL_TV 0x0
+#define LCD_IO_OVERL_LCD1 0x400000
+#define LCD_IO_OVERL_LCD2 0xC00000
+#define HINVERT_MSK 0x4
+#define VINVERT_MSK 0x8
+#define HINVERT_LEN 0x2
+#define VINVERT_LEN 0x3
+
+#define CMU_CTRL 0x88
+#define CMU_CTRL_A0_MSK 0x6
+#define CMU_CTRL_A0_TV 0x0
+#define CMU_CTRL_A0_LCD1 0x1
+#define CMU_CTRL_A0_LCD2 0x2
+#define CMU_CTRL_A0_HDMI 0x3
+
+#define ICR_DRV_ROUTE_OFF 0x0
+#define ICR_DRV_ROUTE_TV 0x1
+#define ICR_DRV_ROUTE_LCD1 0x2
+#define ICR_DRV_ROUTE_LCD2 0x3
+
+enum {
+ PATH_PN = 0,
+ PATH_TV,
+ PATH_P2,
+};
+
+/*
+ * mmp path describes part of mmp path related info:
+ * which is hiden in display driver and not exported to buffer driver
+ */
+struct mmphw_ctrl;
+struct mmphw_path_plat {
+ int id;
+ struct mmphw_ctrl *ctrl;
+ struct mmp_path *path;
+ u32 path_config;
+ u32 link_config;
+};
+
+/* mmp ctrl describes mmp controller related info */
+struct mmphw_ctrl {
+ /* platform related, get from config */
+ const char *name;
+ int irq;
+ void *reg_base;
+ struct clk *clk;
+
+ /* sys info */
+ struct device *dev;
+
+ /* state */
+ int open_count;
+ int status;
+ struct mutex access_ok;
+
+ /*pathes*/
+ int path_num;
+ struct mmphw_path_plat path_plats[0];
+};
+
+static inline int overlay_is_vid(struct mmp_overlay *overlay)
+{
+ return overlay->dmafetch_id & 1;
+}
+
+static inline struct mmphw_path_plat *path_to_path_plat(struct mmp_path *path)
+{
+ return (struct mmphw_path_plat *)path->plat_data;
+}
+
+static inline struct mmphw_ctrl *path_to_ctrl(struct mmp_path *path)
+{
+ return path_to_path_plat(path)->ctrl;
+}
+
+static inline struct mmphw_ctrl *overlay_to_ctrl(struct mmp_overlay *overlay)
+{
+ return path_to_ctrl(overlay->path);
+}
+
+static inline void *ctrl_regs(struct mmp_path *path)
+{
+ return path_to_ctrl(path)->reg_base;
+}
+
+/* path regs, for regs symmetrical for both pathes */
+static inline struct lcd_regs *path_regs(struct mmp_path *path)
+{
+ if (path->id == PATH_PN)
+ return (struct lcd_regs *)(ctrl_regs(path) + 0xc0);
+ else if (path->id == PATH_TV)
+ return (struct lcd_regs *)ctrl_regs(path);
+ else if (path->id == PATH_P2)
+ return (struct lcd_regs *)(ctrl_regs(path) + 0x200);
+ else {
+ dev_err(path->dev, "path id %d invalid\n", path->id);
+ BUG_ON(1);
+ return NULL;
+ }
+}
+
+#ifdef CONFIG_MMP_DISP_SPI
+extern int lcd_spi_register(struct mmphw_ctrl *ctrl);
+#endif
+#endif /* _MMP_CTRL_H_ */
diff --git a/drivers/video/mmp/hw/mmp_spi.c b/drivers/video/mmp/hw/mmp_spi.c
new file mode 100644
index 0000000..e62ca7b
--- /dev/null
+++ b/drivers/video/mmp/hw/mmp_spi.c
@@ -0,0 +1,180 @@
+/*
+ * linux/drivers/video/mmp/hw/mmp_spi.c
+ * using the spi in LCD controler for commands send
+ *
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Authors: Guoqing Li <ligq@marvell.com>
+ * Lisa Du <cldu@marvell.com>
+ * Zhou Zhu <zzhu3@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/spi/spi.h>
+#include "mmp_ctrl.h"
+
+/**
+ * spi_write - write command to the SPI port
+ * @data: can be 8/16/32-bit, MSB justified data to write.
+ * @len: data length.
+ *
+ * Wait bus transfer complete IRQ.
+ * The caller is expected to perform the necessary locking.
+ *
+ * Returns:
+ * %-ETIMEDOUT timeout occurred
+ * 0 success
+ */
+static inline int lcd_spi_write(struct spi_device *spi, u32 data)
+{
+ int timeout = 100000, isr, ret = 0;
+ u32 tmp;
+ void *reg_base =
+ *(void **)spi_master_get_devdata(spi->master);
+
+ /* clear ISR */
+ writel_relaxed(~SPI_IRQ_MASK, reg_base + SPU_IRQ_ISR);
+
+ switch (spi->bits_per_word) {
+ case 8:
+ writel_relaxed((u8)data, reg_base + LCD_SPU_SPI_TXDATA);
+ break;
+ case 16:
+ writel_relaxed((u16)data, reg_base + LCD_SPU_SPI_TXDATA);
+ break;
+ case 32:
+ writel_relaxed((u32)data, reg_base + LCD_SPU_SPI_TXDATA);
+ break;
+ default:
+ dev_err(&spi->dev, "Wrong spi bit length\n");
+ }
+
+ /* SPI start to send command */
+ tmp = readl_relaxed(reg_base + LCD_SPU_SPI_CTRL);
+ tmp &= ~CFG_SPI_START_MASK;
+ tmp |= CFG_SPI_START(1);
+ writel(tmp, reg_base + LCD_SPU_SPI_CTRL);
+
+ isr = readl_relaxed(reg_base + SPU_IRQ_ISR);
+ while (!(isr & SPI_IRQ_ENA_MASK)) {
+ udelay(100);
+ isr = readl_relaxed(reg_base + SPU_IRQ_ISR);
+ if (!--timeout) {
+ ret = -ETIMEDOUT;
+ dev_err(&spi->dev, "spi cmd send time out\n");
+ break;
+ }
+ }
+
+ tmp = readl_relaxed(reg_base + LCD_SPU_SPI_CTRL);
+ tmp &= ~CFG_SPI_START_MASK;
+ tmp |= CFG_SPI_START(0);
+ writel_relaxed(tmp, reg_base + LCD_SPU_SPI_CTRL);
+
+ writel_relaxed(~SPI_IRQ_MASK, reg_base + SPU_IRQ_ISR);
+
+ return ret;
+}
+
+static int lcd_spi_setup(struct spi_device *spi)
+{
+ void *reg_base =
+ *(void **)spi_master_get_devdata(spi->master);
+ u32 tmp;
+
+ tmp = CFG_SCLKCNT(16) |
+ CFG_TXBITS(spi->bits_per_word) |
+ CFG_SPI_SEL(1) | CFG_SPI_ENA(1) |
+ CFG_SPI_3W4WB(1);
+ writel(tmp, reg_base + LCD_SPU_SPI_CTRL);
+
+ /*
+ * After set mode it need a time to pull up the spi singals,
+ * or it would cause the wrong waveform when send spi command,
+ * especially on pxa910h
+ */
+ tmp = readl_relaxed(reg_base + SPU_IOPAD_CONTROL);
+ if ((tmp & CFG_IOPADMODE_MASK) != IOPAD_DUMB18SPI)
+ writel_relaxed(IOPAD_DUMB18SPI |
+ (tmp & ~CFG_IOPADMODE_MASK),
+ reg_base + SPU_IOPAD_CONTROL);
+ udelay(20);
+ return 0;
+}
+
+static int lcd_spi_one_transfer(struct spi_device *spi, struct spi_message *m)
+{
+ struct spi_transfer *t;
+ int i;
+
+ list_for_each_entry(t, &m->transfers, transfer_list) {
+ switch (spi->bits_per_word) {
+ case 8:
+ for (i = 0; i < t->len; i++)
+ lcd_spi_write(spi, ((u8 *)t->tx_buf)[i]);
+ break;
+ case 16:
+ for (i = 0; i < t->len/2; i++)
+ lcd_spi_write(spi, ((u16 *)t->tx_buf)[i]);
+ break;
+ case 32:
+ for (i = 0; i < t->len/4; i++)
+ lcd_spi_write(spi, ((u32 *)t->tx_buf)[i]);
+ break;
+ default:
+ dev_err(&spi->dev, "Wrong spi bit length\n");
+ }
+ }
+
+ m->status = 0;
+ if (m->complete)
+ m->complete(m->context);
+ return 0;
+}
+
+int lcd_spi_register(struct mmphw_ctrl *ctrl)
+{
+ struct spi_master *master;
+ void **p_regbase;
+ int err;
+
+ master = spi_alloc_master(ctrl->dev, sizeof(void *));
+ if (!master) {
+ dev_err(ctrl->dev, "unable to allocate SPI master\n");
+ return -ENOMEM;
+ }
+ p_regbase = spi_master_get_devdata(master);
+ *p_regbase = ctrl->reg_base;
+
+ /* set bus num to 5 to avoid conflict with other spi hosts */
+ master->bus_num = 5;
+ master->num_chipselect = 1;
+ master->setup = lcd_spi_setup;
+ master->transfer = lcd_spi_one_transfer;
+
+ err = spi_register_master(master);
+ if (err < 0) {
+ dev_err(ctrl->dev, "unable to register SPI master\n");
+ spi_master_put(master);
+ return err;
+ }
+
+ dev_info(&master->dev, "registered\n");
+
+ return 0;
+}
diff --git a/drivers/video/mmp/panel/Kconfig b/drivers/video/mmp/panel/Kconfig
new file mode 100644
index 0000000..4b2c4f4
--- /dev/null
+++ b/drivers/video/mmp/panel/Kconfig
@@ -0,0 +1,6 @@
+config MMP_PANEL_TPOHVGA
+ bool "tpohvga panel TJ032MD01BW support"
+ depends on SPI_MASTER
+ default n
+ help
+ tpohvga panel support
diff --git a/drivers/video/mmp/panel/Makefile b/drivers/video/mmp/panel/Makefile
new file mode 100644
index 0000000..2f91611
--- /dev/null
+++ b/drivers/video/mmp/panel/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MMP_PANEL_TPOHVGA) += tpo_tj032md01bw.o
diff --git a/drivers/video/mmp/panel/tpo_tj032md01bw.c b/drivers/video/mmp/panel/tpo_tj032md01bw.c
new file mode 100644
index 0000000..998978b
--- /dev/null
+++ b/drivers/video/mmp/panel/tpo_tj032md01bw.c
@@ -0,0 +1,186 @@
+/*
+ * linux/drivers/video/mmp/panel/tpo_tj032md01bw.c
+ * active panel using spi interface to do init
+ *
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Authors: Guoqing Li <ligq@marvell.com>
+ * Lisa Du <cldu@marvell.com>
+ * Zhou Zhu <zzhu3@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/spi/spi.h>
+#include <video/mmp_disp.h>
+
+static u16 init[] = {
+ 0x0801,
+ 0x0800,
+ 0x0200,
+ 0x0304,
+ 0x040e,
+ 0x0903,
+ 0x0b18,
+ 0x0c53,
+ 0x0d01,
+ 0x0ee0,
+ 0x0f01,
+ 0x1058,
+ 0x201e,
+ 0x210a,
+ 0x220a,
+ 0x231e,
+ 0x2400,
+ 0x2532,
+ 0x2600,
+ 0x27ac,
+ 0x2904,
+ 0x2aa2,
+ 0x2b45,
+ 0x2c45,
+ 0x2d15,
+ 0x2e5a,
+ 0x2fff,
+ 0x306b,
+ 0x310d,
+ 0x3248,
+ 0x3382,
+ 0x34bd,
+ 0x35e7,
+ 0x3618,
+ 0x3794,
+ 0x3801,
+ 0x395d,
+ 0x3aae,
+ 0x3bff,
+ 0x07c9,
+};
+
+static u16 poweroff[] = {
+ 0x07d9,
+};
+
+struct tpohvga_plat_data {
+ void (*plat_onoff)(int status);
+ struct spi_device *spi;
+};
+
+static void tpohvga_onoff(struct mmp_panel *panel, int status)
+{
+ struct tpohvga_plat_data *plat = panel->plat_data;
+ int ret;
+
+ if (status) {
+ plat->plat_onoff(1);
+
+ ret = spi_write(plat->spi, init, sizeof(init));
+ if (ret < 0)
+ dev_warn(panel->dev, "init cmd failed(%d)\n", ret);
+ } else {
+ ret = spi_write(plat->spi, poweroff, sizeof(poweroff));
+ if (ret < 0)
+ dev_warn(panel->dev, "poweroff cmd failed(%d)\n", ret);
+
+ plat->plat_onoff(0);
+ }
+}
+
+static struct mmp_mode mmp_modes_tpohvga[] = {
+ [0] = {
+ .pixclock_freq = 10394400,
+ .refresh = 60,
+ .xres = 320,
+ .yres = 480,
+ .hsync_len = 10,
+ .left_margin = 15,
+ .right_margin = 10,
+ .vsync_len = 2,
+ .upper_margin = 4,
+ .lower_margin = 2,
+ .invert_pixclock = 1,
+ .pix_fmt_out = PIXFMT_RGB565,
+ },
+};
+
+static int tpohvga_get_modelist(struct mmp_panel *panel,
+ struct mmp_mode **modelist)
+{
+ *modelist = mmp_modes_tpohvga;
+ return 1;
+}
+
+static struct mmp_panel panel_tpohvga = {
+ .name = "tpohvga",
+ .panel_type = PANELTYPE_ACTIVE,
+ .get_modelist = tpohvga_get_modelist,
+ .set_onoff = tpohvga_onoff,
+};
+
+static int tpohvga_probe(struct spi_device *spi)
+{
+ struct mmp_mach_panel_info *mi;
+ int ret;
+ struct tpohvga_plat_data *plat_data;
+
+ /* get configs from platform data */
+ mi = spi->dev.platform_data;
+ if (mi == NULL) {
+ dev_err(&spi->dev, "%s: no platform data defined\n", __func__);
+ return -EINVAL;
+ }
+
+ /* setup spi related info */
+ spi->bits_per_word = 16;
+ ret = spi_setup(spi);
+ if (ret < 0) {
+ dev_err(&spi->dev, "spi setup failed %d", ret);
+ return ret;
+ }
+
+ plat_data = kzalloc(sizeof(*plat_data), GFP_KERNEL);
+ if (plat_data == NULL)
+ return -ENOMEM;
+
+ plat_data->spi = spi;
+ plat_data->plat_onoff = mi->plat_set_onoff;
+ panel_tpohvga.plat_data = plat_data;
+ panel_tpohvga.plat_path_name = mi->plat_path_name;
+ panel_tpohvga.dev = &spi->dev;
+
+ mmp_register_panel(&panel_tpohvga);
+
+ return 0;
+}
+
+static struct spi_driver panel_tpohvga_driver = {
+ .driver = {
+ .name = "tpo-hvga",
+ .owner = THIS_MODULE,
+ },
+ .probe = tpohvga_probe,
+};
+module_spi_driver(panel_tpohvga_driver);
+
+MODULE_AUTHOR("Lisa Du<cldu@marvell.com>");
+MODULE_DESCRIPTION("Panel driver for tpohvga");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index 35ac9e8..e0f8011 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -417,7 +417,7 @@ static void mddi_resume(struct msm_mddi_client_data *cdata)
mddi_set_auto_hibernate(&mddi->client_data, 1);
}
-static int __devinit mddi_get_client_caps(struct mddi_info *mddi)
+static int mddi_get_client_caps(struct mddi_info *mddi)
{
int i, j;
@@ -619,9 +619,8 @@ uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg)
static struct mddi_info mddi_info[2];
-static int __devinit mddi_clk_setup(struct platform_device *pdev,
- struct mddi_info *mddi,
- unsigned long clk_rate)
+static int mddi_clk_setup(struct platform_device *pdev, struct mddi_info *mddi,
+ unsigned long clk_rate)
{
int ret;
@@ -664,7 +663,7 @@ static int __init mddi_rev_data_setup(struct mddi_info *mddi)
return 0;
}
-static int __devinit mddi_probe(struct platform_device *pdev)
+static int mddi_probe(struct platform_device *pdev)
{
struct msm_mddi_platform_data *pdata = pdev->dev.platform_data;
struct mddi_info *mddi = &mddi_info[pdev->id];
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index f2566c1..113c787 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -261,7 +261,7 @@ int get_img(struct mdp_img *img, struct fb_info *info,
if (f.file == NULL)
return -1;
- if (MAJOR(f.file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
+ if (MAJOR(file_inode(f.file)->i_rdev) == FB_MAJOR) {
*start = info->fix.smem_start;
*len = info->fix.smem_len;
} else
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index ce1d452..cfdb380 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/mx3fb.c
@@ -26,10 +26,9 @@
#include <linux/console.h>
#include <linux/clk.h>
#include <linux/mutex.h>
+#include <linux/dma/ipu-dma.h>
#include <linux/platform_data/dma-imx.h>
-#include <mach/hardware.h>
-#include <mach/ipu.h>
#include <linux/platform_data/video-mx3fb.h>
#include <asm/io.h>
@@ -1307,7 +1306,7 @@ static int mx3fb_unmap_video_memory(struct fb_info *fbi)
dma_free_writecombine(fbi->device, fbi->fix.smem_len,
fbi->screen_base, fbi->fix.smem_start);
- fbi->screen_base = 0;
+ fbi->screen_base = NULL;
mutex_lock(&fbi->mm_lock);
fbi->fix.smem_start = 0;
fbi->fix.smem_len = 0;
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index 49619b4..755556c 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -369,7 +369,8 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
loop--;
}
- writel(VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4 + REG_CLR);
+ reg = readl(host->base + LCDC_VDCTRL4);
+ writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4);
clk_disable_unprepare(host->clk);
@@ -586,7 +587,7 @@ static struct fb_ops mxsfb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static int __devinit mxsfb_restore_mode(struct mxsfb_info *host)
+static int mxsfb_restore_mode(struct mxsfb_info *host)
{
struct fb_info *fb_info = &host->fb_info;
unsigned line_count;
@@ -677,7 +678,7 @@ static int __devinit mxsfb_restore_mode(struct mxsfb_info *host)
return 0;
}
-static int __devinit mxsfb_init_fbinfo(struct mxsfb_info *host)
+static int mxsfb_init_fbinfo(struct mxsfb_info *host)
{
struct fb_info *fb_info = &host->fb_info;
struct fb_var_screeninfo *var = &fb_info->var;
@@ -739,7 +740,7 @@ static int __devinit mxsfb_init_fbinfo(struct mxsfb_info *host)
return 0;
}
-static void __devexit mxsfb_free_videomem(struct mxsfb_info *host)
+static void mxsfb_free_videomem(struct mxsfb_info *host)
{
struct fb_info *fb_info = &host->fb_info;
@@ -772,7 +773,7 @@ static const struct of_device_id mxsfb_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, mxsfb_dt_ids);
-static int __devinit mxsfb_probe(struct platform_device *pdev)
+static int mxsfb_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
of_match_device(mxsfb_dt_ids, &pdev->dev);
@@ -912,7 +913,7 @@ error_alloc_info:
return ret;
}
-static int __devexit mxsfb_remove(struct platform_device *pdev)
+static int mxsfb_remove(struct platform_device *pdev)
{
struct fb_info *fb_info = platform_get_drvdata(pdev);
struct mxsfb_info *host = to_imxfb_host(fb_info);
@@ -949,7 +950,7 @@ static void mxsfb_shutdown(struct platform_device *pdev)
static struct platform_driver mxsfb_driver = {
.probe = mxsfb_probe,
- .remove = __devexit_p(mxsfb_remove),
+ .remove = mxsfb_remove,
.shutdown = mxsfb_shutdown,
.id_table = mxsfb_devtype,
.driver = {
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index afc9521..7ef079c 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -88,7 +88,7 @@ static bool external;
static bool libretto;
static bool nostretch;
static bool nopciburst;
-static char *mode_option __devinitdata = NULL;
+static char *mode_option = NULL;
#ifdef MODULE
@@ -1632,7 +1632,7 @@ static struct fb_ops neofb_ops = {
/* --------------------------------------------------------------------- */
-static struct fb_videomode __devinitdata mode800x480 = {
+static struct fb_videomode mode800x480 = {
.xres = 800,
.yres = 480,
.pixclock = 25000,
@@ -1646,8 +1646,7 @@ static struct fb_videomode __devinitdata mode800x480 = {
.vmode = FB_VMODE_NONINTERLACED
};
-static int __devinit neo_map_mmio(struct fb_info *info,
- struct pci_dev *dev)
+static int neo_map_mmio(struct fb_info *info, struct pci_dev *dev)
{
struct neofb_par *par = info->par;
@@ -1707,8 +1706,8 @@ static void neo_unmap_mmio(struct fb_info *info)
info->fix.mmio_len);
}
-static int __devinit neo_map_video(struct fb_info *info,
- struct pci_dev *dev, int video_len)
+static int neo_map_video(struct fb_info *info, struct pci_dev *dev,
+ int video_len)
{
//unsigned long addr;
@@ -1772,7 +1771,7 @@ static void neo_unmap_video(struct fb_info *info)
info->fix.smem_len);
}
-static int __devinit neo_scan_monitor(struct fb_info *info)
+static int neo_scan_monitor(struct fb_info *info)
{
struct neofb_par *par = info->par;
unsigned char type, display;
@@ -1851,7 +1850,7 @@ static int __devinit neo_scan_monitor(struct fb_info *info)
return 0;
}
-static int __devinit neo_init_hw(struct fb_info *info)
+static int neo_init_hw(struct fb_info *info)
{
struct neofb_par *par = info->par;
int videoRam = 896;
@@ -1939,8 +1938,8 @@ static int __devinit neo_init_hw(struct fb_info *info)
}
-static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const struct
- pci_device_id *id)
+static struct fb_info *neo_alloc_fb_info(struct pci_dev *dev,
+ const struct pci_device_id *id)
{
struct fb_info *info;
struct neofb_par *par;
@@ -2038,8 +2037,7 @@ static void neo_free_fb_info(struct fb_info *info)
/* --------------------------------------------------------------------- */
-static int __devinit neofb_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
+static int neofb_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct fb_info *info;
u_int h_sync, v_sync;
@@ -2128,7 +2126,7 @@ err_map_mmio:
return err;
}
-static void __devexit neofb_remove(struct pci_dev *dev)
+static void neofb_remove(struct pci_dev *dev)
{
struct fb_info *info = pci_get_drvdata(dev);
@@ -2194,7 +2192,7 @@ static struct pci_driver neofb_driver = {
.name = "neofb",
.id_table = neofb_devices,
.probe = neofb_probe,
- .remove = __devexit_p(neofb_remove)
+ .remove = neofb_remove,
};
/* ************************* init in-kernel code ************************** */
diff --git a/drivers/video/nuc900fb.c b/drivers/video/nuc900fb.c
index 475dfee..32581c7 100644
--- a/drivers/video/nuc900fb.c
+++ b/drivers/video/nuc900fb.c
@@ -387,7 +387,7 @@ static int nuc900fb_init_registers(struct fb_info *info)
* The buffer should be a non-cached, non-buffered, memory region
* to allow palette and pixel writes without flushing the cache.
*/
-static int __devinit nuc900fb_map_video_memory(struct fb_info *info)
+static int nuc900fb_map_video_memory(struct fb_info *info)
{
struct nuc900fb_info *fbi = info->par;
dma_addr_t map_dma;
@@ -499,7 +499,7 @@ static inline void nuc900fb_cpufreq_deregister(struct nuc900fb_info *info)
static char driver_name[] = "nuc900fb";
-static int __devinit nuc900fb_probe(struct platform_device *pdev)
+static int nuc900fb_probe(struct platform_device *pdev)
{
struct nuc900fb_info *fbi;
struct nuc900fb_display *display;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index fe13ac5..ff22871 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -70,34 +70,34 @@ static struct pci_device_id nvidiafb_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl);
/* command line data, set in nvidiafb_setup() */
-static int flatpanel __devinitdata = -1; /* Autodetect later */
-static int fpdither __devinitdata = -1;
-static int forceCRTC __devinitdata = -1;
-static int hwcur __devinitdata = 0;
-static int noaccel __devinitdata = 0;
-static int noscale __devinitdata = 0;
-static int paneltweak __devinitdata = 0;
-static int vram __devinitdata = 0;
-static int bpp __devinitdata = 8;
-static int reverse_i2c __devinitdata;
+static int flatpanel = -1; /* Autodetect later */
+static int fpdither = -1;
+static int forceCRTC = -1;
+static int hwcur = 0;
+static int noaccel = 0;
+static int noscale = 0;
+static int paneltweak = 0;
+static int vram = 0;
+static int bpp = 8;
+static int reverse_i2c;
#ifdef CONFIG_MTRR
-static bool nomtrr __devinitdata = false;
+static bool nomtrr = false;
#endif
#ifdef CONFIG_PMAC_BACKLIGHT
-static int backlight __devinitdata = 1;
+static int backlight = 1;
#else
-static int backlight __devinitdata = 0;
+static int backlight = 0;
#endif
-static char *mode_option __devinitdata = NULL;
+static char *mode_option = NULL;
-static struct fb_fix_screeninfo __devinitdata nvidiafb_fix = {
+static struct fb_fix_screeninfo nvidiafb_fix = {
.type = FB_TYPE_PACKED_PIXELS,
.xpanstep = 8,
.ypanstep = 1,
};
-static struct fb_var_screeninfo __devinitdata nvidiafb_default_var = {
+static struct fb_var_screeninfo nvidiafb_default_var = {
.xres = 640,
.yres = 480,
.xres_virtual = 640,
@@ -1105,7 +1105,7 @@ fail:
#define nvidiafb_resume NULL
#endif
-static int __devinit nvidia_set_fbinfo(struct fb_info *info)
+static int nvidia_set_fbinfo(struct fb_info *info)
{
struct fb_monspecs *specs = &info->monspecs;
struct fb_videomode modedb;
@@ -1201,7 +1201,7 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
return nvidiafb_check_var(&info->var, info);
}
-static u32 __devinit nvidia_get_chipset(struct fb_info *info)
+static u32 nvidia_get_chipset(struct fb_info *info)
{
struct nvidia_par *par = info->par;
u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device;
@@ -1224,7 +1224,7 @@ static u32 __devinit nvidia_get_chipset(struct fb_info *info)
return id;
}
-static u32 __devinit nvidia_get_arch(struct fb_info *info)
+static u32 nvidia_get_arch(struct fb_info *info)
{
struct nvidia_par *par = info->par;
u32 arch = 0;
@@ -1276,8 +1276,7 @@ static u32 __devinit nvidia_get_arch(struct fb_info *info)
return arch;
}
-static int __devinit nvidiafb_probe(struct pci_dev *pd,
- const struct pci_device_id *ent)
+static int nvidiafb_probe(struct pci_dev *pd, const struct pci_device_id *ent)
{
struct nvidia_par *par;
struct fb_info *info;
@@ -1438,7 +1437,7 @@ err_out:
return -ENODEV;
}
-static void __devexit nvidiafb_remove(struct pci_dev *pd)
+static void nvidiafb_remove(struct pci_dev *pd)
{
struct fb_info *info = pci_get_drvdata(pd);
struct nvidia_par *par = info->par;
@@ -1473,7 +1472,7 @@ static void __devexit nvidiafb_remove(struct pci_dev *pd)
* ------------------------------------------------------------------------- */
#ifndef MODULE
-static int __devinit nvidiafb_setup(char *options)
+static int nvidiafb_setup(char *options)
{
char *this_opt;
@@ -1529,7 +1528,7 @@ static struct pci_driver nvidiafb_driver = {
.probe = nvidiafb_probe,
.suspend = nvidiafb_suspend,
.resume = nvidiafb_resume,
- .remove = __devexit_p(nvidiafb_remove),
+ .remove = nvidiafb_remove,
};
/* ------------------------------------------------------------------------- *
@@ -1538,7 +1537,7 @@ static struct pci_driver nvidiafb_driver = {
*
* ------------------------------------------------------------------------- */
-static int __devinit nvidiafb_init(void)
+static int nvidiafb_init(void)
{
#ifndef MODULE
char *option = NULL;
diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c
new file mode 100644
index 0000000..13ecd98
--- /dev/null
+++ b/drivers/video/of_display_timing.c
@@ -0,0 +1,239 @@
+/*
+ * OF helpers for parsing display timings
+ *
+ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * based on of_videomode.c by Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ */
+#include <linux/export.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <video/display_timing.h>
+#include <video/of_display_timing.h>
+
+/**
+ * parse_timing_property - parse timing_entry from device_node
+ * @np: device_node with the property
+ * @name: name of the property
+ * @result: will be set to the return value
+ *
+ * DESCRIPTION:
+ * Every display_timing can be specified with either just the typical value or
+ * a range consisting of min/typ/max. This function helps handling this
+ **/
+static int parse_timing_property(struct device_node *np, const char *name,
+ struct timing_entry *result)
+{
+ struct property *prop;
+ int length, cells, ret;
+
+ prop = of_find_property(np, name, &length);
+ if (!prop) {
+ pr_err("%s: could not find property %s\n",
+ of_node_full_name(np), name);
+ return -EINVAL;
+ }
+
+ cells = length / sizeof(u32);
+ if (cells == 1) {
+ ret = of_property_read_u32(np, name, &result->typ);
+ result->min = result->typ;
+ result->max = result->typ;
+ } else if (cells == 3) {
+ ret = of_property_read_u32_array(np, name, &result->min, cells);
+ } else {
+ pr_err("%s: illegal timing specification in %s\n",
+ of_node_full_name(np), name);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+/**
+ * of_get_display_timing - parse display_timing entry from device_node
+ * @np: device_node with the properties
+ **/
+static struct display_timing *of_get_display_timing(struct device_node *np)
+{
+ struct display_timing *dt;
+ u32 val = 0;
+ int ret = 0;
+
+ dt = kzalloc(sizeof(*dt), GFP_KERNEL);
+ if (!dt) {
+ pr_err("%s: could not allocate display_timing struct\n",
+ of_node_full_name(np));
+ return NULL;
+ }
+
+ ret |= parse_timing_property(np, "hback-porch", &dt->hback_porch);
+ ret |= parse_timing_property(np, "hfront-porch", &dt->hfront_porch);
+ ret |= parse_timing_property(np, "hactive", &dt->hactive);
+ ret |= parse_timing_property(np, "hsync-len", &dt->hsync_len);
+ ret |= parse_timing_property(np, "vback-porch", &dt->vback_porch);
+ ret |= parse_timing_property(np, "vfront-porch", &dt->vfront_porch);
+ ret |= parse_timing_property(np, "vactive", &dt->vactive);
+ ret |= parse_timing_property(np, "vsync-len", &dt->vsync_len);
+ ret |= parse_timing_property(np, "clock-frequency", &dt->pixelclock);
+
+ dt->dmt_flags = 0;
+ dt->data_flags = 0;
+ if (!of_property_read_u32(np, "vsync-active", &val))
+ dt->dmt_flags |= val ? VESA_DMT_VSYNC_HIGH :
+ VESA_DMT_VSYNC_LOW;
+ if (!of_property_read_u32(np, "hsync-active", &val))
+ dt->dmt_flags |= val ? VESA_DMT_HSYNC_HIGH :
+ VESA_DMT_HSYNC_LOW;
+ if (!of_property_read_u32(np, "de-active", &val))
+ dt->data_flags |= val ? DISPLAY_FLAGS_DE_HIGH :
+ DISPLAY_FLAGS_DE_LOW;
+ if (!of_property_read_u32(np, "pixelclk-active", &val))
+ dt->data_flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE :
+ DISPLAY_FLAGS_PIXDATA_NEGEDGE;
+
+ if (of_property_read_bool(np, "interlaced"))
+ dt->data_flags |= DISPLAY_FLAGS_INTERLACED;
+ if (of_property_read_bool(np, "doublescan"))
+ dt->data_flags |= DISPLAY_FLAGS_DOUBLESCAN;
+
+ if (ret) {
+ pr_err("%s: error reading timing properties\n",
+ of_node_full_name(np));
+ kfree(dt);
+ return NULL;
+ }
+
+ return dt;
+}
+
+/**
+ * of_get_display_timings - parse all display_timing entries from a device_node
+ * @np: device_node with the subnodes
+ **/
+struct display_timings *of_get_display_timings(struct device_node *np)
+{
+ struct device_node *timings_np;
+ struct device_node *entry;
+ struct device_node *native_mode;
+ struct display_timings *disp;
+
+ if (!np) {
+ pr_err("%s: no devicenode given\n", of_node_full_name(np));
+ return NULL;
+ }
+
+ timings_np = of_find_node_by_name(np, "display-timings");
+ if (!timings_np) {
+ pr_err("%s: could not find display-timings node\n",
+ of_node_full_name(np));
+ return NULL;
+ }
+
+ disp = kzalloc(sizeof(*disp), GFP_KERNEL);
+ if (!disp) {
+ pr_err("%s: could not allocate struct disp'\n",
+ of_node_full_name(np));
+ goto dispfail;
+ }
+
+ entry = of_parse_phandle(timings_np, "native-mode", 0);
+ /* assume first child as native mode if none provided */
+ if (!entry)
+ entry = of_get_next_child(np, NULL);
+ /* if there is no child, it is useless to go on */
+ if (!entry) {
+ pr_err("%s: no timing specifications given\n",
+ of_node_full_name(np));
+ goto entryfail;
+ }
+
+ pr_debug("%s: using %s as default timing\n",
+ of_node_full_name(np), entry->name);
+
+ native_mode = entry;
+
+ disp->num_timings = of_get_child_count(timings_np);
+ if (disp->num_timings == 0) {
+ /* should never happen, as entry was already found above */
+ pr_err("%s: no timings specified\n", of_node_full_name(np));
+ goto entryfail;
+ }
+
+ disp->timings = kzalloc(sizeof(struct display_timing *) *
+ disp->num_timings, GFP_KERNEL);
+ if (!disp->timings) {
+ pr_err("%s: could not allocate timings array\n",
+ of_node_full_name(np));
+ goto entryfail;
+ }
+
+ disp->num_timings = 0;
+ disp->native_mode = 0;
+
+ for_each_child_of_node(timings_np, entry) {
+ struct display_timing *dt;
+
+ dt = of_get_display_timing(entry);
+ if (!dt) {
+ /*
+ * to not encourage wrong devicetrees, fail in case of
+ * an error
+ */
+ pr_err("%s: error in timing %d\n",
+ of_node_full_name(np), disp->num_timings + 1);
+ goto timingfail;
+ }
+
+ if (native_mode == entry)
+ disp->native_mode = disp->num_timings;
+
+ disp->timings[disp->num_timings] = dt;
+ disp->num_timings++;
+ }
+ of_node_put(timings_np);
+ /*
+ * native_mode points to the device_node returned by of_parse_phandle
+ * therefore call of_node_put on it
+ */
+ of_node_put(native_mode);
+
+ pr_debug("%s: got %d timings. Using timing #%d as default\n",
+ of_node_full_name(np), disp->num_timings,
+ disp->native_mode + 1);
+
+ return disp;
+
+timingfail:
+ if (native_mode)
+ of_node_put(native_mode);
+ display_timings_release(disp);
+entryfail:
+ kfree(disp);
+dispfail:
+ of_node_put(timings_np);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(of_get_display_timings);
+
+/**
+ * of_display_timings_exist - check if a display-timings node is provided
+ * @np: device_node with the timing
+ **/
+int of_display_timings_exist(struct device_node *np)
+{
+ struct device_node *timings_np;
+
+ if (!np)
+ return -EINVAL;
+
+ timings_np = of_parse_phandle(np, "display-timings", 0);
+ if (!timings_np)
+ return -EINVAL;
+
+ of_node_put(timings_np);
+ return 1;
+}
+EXPORT_SYMBOL_GPL(of_display_timings_exist);
diff --git a/drivers/video/of_videomode.c b/drivers/video/of_videomode.c
new file mode 100644
index 0000000..5b8066c
--- /dev/null
+++ b/drivers/video/of_videomode.c
@@ -0,0 +1,54 @@
+/*
+ * generic videomode helper
+ *
+ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * This file is released under the GPLv2
+ */
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/of.h>
+#include <video/display_timing.h>
+#include <video/of_display_timing.h>
+#include <video/of_videomode.h>
+#include <video/videomode.h>
+
+/**
+ * of_get_videomode - get the videomode #<index> from devicetree
+ * @np - devicenode with the display_timings
+ * @vm - set to return value
+ * @index - index into list of display_timings
+ * (Set this to OF_USE_NATIVE_MODE to use whatever mode is
+ * specified as native mode in the DT.)
+ *
+ * DESCRIPTION:
+ * Get a list of all display timings and put the one
+ * specified by index into *vm. This function should only be used, if
+ * only one videomode is to be retrieved. A driver that needs to work
+ * with multiple/all videomodes should work with
+ * of_get_display_timings instead.
+ **/
+int of_get_videomode(struct device_node *np, struct videomode *vm,
+ int index)
+{
+ struct display_timings *disp;
+ int ret;
+
+ disp = of_get_display_timings(np);
+ if (!disp) {
+ pr_err("%s: no timings specified\n", of_node_full_name(np));
+ return -EINVAL;
+ }
+
+ if (index == OF_USE_NATIVE_MODE)
+ index = disp->native_mode;
+
+ ret = videomode_from_timing(disp, vm, index);
+ if (ret)
+ return ret;
+
+ display_timings_release(disp);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_get_videomode);
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
index b48f95f..e512581 100644
--- a/drivers/video/omap/Kconfig
+++ b/drivers/video/omap/Kconfig
@@ -1,5 +1,5 @@
config FB_OMAP
- tristate "OMAP frame buffer support (EXPERIMENTAL)"
+ tristate "OMAP frame buffer support"
depends on FB
depends on ARCH_OMAP1
select FB_CFB_FILLRECT
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c
index ed4cad8..4a5f2cd 100644
--- a/drivers/video/omap/lcd_ams_delta.c
+++ b/drivers/video/omap/lcd_ams_delta.c
@@ -27,6 +27,7 @@
#include <linux/lcd.h>
#include <linux/gpio.h>
+#include <mach/hardware.h>
#include <mach/board-ams-delta.h>
#include "omapfb.h"
diff --git a/drivers/video/omap/lcd_inn1510.c b/drivers/video/omap/lcd_inn1510.c
index b38b1dd..2ee4232 100644
--- a/drivers/video/omap/lcd_inn1510.c
+++ b/drivers/video/omap/lcd_inn1510.c
@@ -23,7 +23,8 @@
#include <linux/platform_device.h>
#include <linux/io.h>
-#include <plat/fpga.h>
+#include <mach/hardware.h>
+
#include "omapfb.h"
static int innovator1510_panel_init(struct lcd_panel *panel,
@@ -38,13 +39,13 @@ static void innovator1510_panel_cleanup(struct lcd_panel *panel)
static int innovator1510_panel_enable(struct lcd_panel *panel)
{
- fpga_write(0x7, OMAP1510_FPGA_LCD_PANEL_CONTROL);
+ __raw_writeb(0x7, OMAP1510_FPGA_LCD_PANEL_CONTROL);
return 0;
}
static void innovator1510_panel_disable(struct lcd_panel *panel)
{
- fpga_write(0x0, OMAP1510_FPGA_LCD_PANEL_CONTROL);
+ __raw_writeb(0x0, OMAP1510_FPGA_LCD_PANEL_CONTROL);
}
static unsigned long innovator1510_panel_get_caps(struct lcd_panel *panel)
diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/omap/lcd_mipid.c
index b739600..803fee6 100644
--- a/drivers/video/omap/lcd_mipid.c
+++ b/drivers/video/omap/lcd_mipid.c
@@ -606,7 +606,7 @@ static struct spi_driver mipid_spi_driver = {
.owner = THIS_MODULE,
},
.probe = mipid_spi_probe,
- .remove = __devexit_p(mipid_spi_remove),
+ .remove = mipid_spi_remove,
};
module_spi_driver(mipid_spi_driver);
diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c
index 3aa62da..7fbe04b 100644
--- a/drivers/video/omap/lcd_osk.c
+++ b/drivers/video/omap/lcd_osk.c
@@ -24,7 +24,10 @@
#include <linux/platform_device.h>
#include <asm/gpio.h>
+
+#include <mach/hardware.h>
#include <mach/mux.h>
+
#include "omapfb.h"
static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c
index 7767338..b52f625 100644
--- a/drivers/video/omap/lcdc.c
+++ b/drivers/video/omap/lcdc.c
@@ -31,7 +31,7 @@
#include <linux/gfp.h>
#include <mach/lcdc.h>
-#include <plat/dma.h>
+#include <linux/omap-dma.h>
#include <asm/mach-types.h>
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 4351c43..e31f5b3 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -30,7 +30,7 @@
#include <linux/uaccess.h>
#include <linux/module.h>
-#include <plat/dma.h>
+#include <linux/omap-dma.h>
#include "omapfb.h"
#include "lcdc.h"
diff --git a/drivers/video/omap/sossi.c b/drivers/video/omap/sossi.c
index f79c137..d4e7684 100644
--- a/drivers/video/omap/sossi.c
+++ b/drivers/video/omap/sossi.c
@@ -25,7 +25,7 @@
#include <linux/io.h>
#include <linux/interrupt.h>
-#include <plat/dma.h>
+#include <linux/omap-dma.h>
#include "omapfb.h"
#include "lcdc.h"
diff --git a/drivers/video/omap2/Kconfig b/drivers/video/omap2/Kconfig
index d877c36..b07b2b0 100644
--- a/drivers/video/omap2/Kconfig
+++ b/drivers/video/omap2/Kconfig
@@ -1,9 +1,10 @@
-config OMAP2_VRAM
- bool
-
config OMAP2_VRFB
bool
+if ARCH_OMAP2PLUS
+
source "drivers/video/omap2/dss/Kconfig"
source "drivers/video/omap2/omapfb/Kconfig"
source "drivers/video/omap2/displays/Kconfig"
+
+endif
diff --git a/drivers/video/omap2/Makefile b/drivers/video/omap2/Makefile
index 5ddef12..5ea7cb9 100644
--- a/drivers/video/omap2/Makefile
+++ b/drivers/video/omap2/Makefile
@@ -1,4 +1,3 @@
-obj-$(CONFIG_OMAP2_VRAM) += vram.o
obj-$(CONFIG_OMAP2_VRFB) += vrfb.o
obj-$(CONFIG_OMAP2_DSS) += dss/
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index c835aa7..72699f8 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -710,27 +710,6 @@ static void acx_panel_disable(struct omap_dss_device *dssdev)
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}
-static int acx_panel_suspend(struct omap_dss_device *dssdev)
-{
- dev_dbg(&dssdev->dev, "%s\n", __func__);
- acx_panel_power_off(dssdev);
- dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
- return 0;
-}
-
-static int acx_panel_resume(struct omap_dss_device *dssdev)
-{
- int r;
-
- dev_dbg(&dssdev->dev, "%s\n", __func__);
- r = acx_panel_power_on(dssdev);
- if (r)
- return r;
-
- dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
- return 0;
-}
-
static void acx_panel_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
@@ -752,8 +731,6 @@ static struct omap_dss_driver acx_panel_driver = {
.enable = acx_panel_enable,
.disable = acx_panel_disable,
- .suspend = acx_panel_suspend,
- .resume = acx_panel_resume,
.set_timings = acx_panel_set_timings,
.check_timings = acx_panel_check_timings,
@@ -800,7 +777,7 @@ static struct spi_driver acx565akm_spi_driver = {
.owner = THIS_MODULE,
},
.probe = acx565akm_spi_probe,
- .remove = __devexit_p(acx565akm_spi_remove),
+ .remove = acx565akm_spi_remove,
};
module_spi_driver(acx565akm_spi_driver);
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 88295c5..c904f42 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -291,30 +291,6 @@ static struct panel_config generic_dpi_panels[] = {
.name = "h4",
},
- /* Unknown panel used in Samsung OMAP2 Apollon */
- {
- {
- .x_res = 480,
- .y_res = 272,
-
- .pixel_clock = 6250,
-
- .hsw = 41,
- .hfp = 2,
- .hbp = 2,
-
- .vsw = 10,
- .vfp = 2,
- .vbp = 2,
-
- .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
- .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
- .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
- .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
- .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
- },
- .name = "apollon",
- },
/* FocalTech ETM070003DH6 */
{
{
@@ -688,40 +664,6 @@ static void generic_dpi_panel_disable(struct omap_dss_device *dssdev)
mutex_unlock(&drv_data->lock);
}
-static int generic_dpi_panel_suspend(struct omap_dss_device *dssdev)
-{
- struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
-
- mutex_lock(&drv_data->lock);
-
- generic_dpi_panel_power_off(dssdev);
-
- dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-
- mutex_unlock(&drv_data->lock);
-
- return 0;
-}
-
-static int generic_dpi_panel_resume(struct omap_dss_device *dssdev)
-{
- struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
- int r;
-
- mutex_lock(&drv_data->lock);
-
- r = generic_dpi_panel_power_on(dssdev);
- if (r)
- goto err;
-
- dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-err:
- mutex_unlock(&drv_data->lock);
-
- return r;
-}
-
static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
@@ -769,8 +711,6 @@ static struct omap_dss_driver dpi_driver = {
.enable = generic_dpi_panel_enable,
.disable = generic_dpi_panel_disable,
- .suspend = generic_dpi_panel_suspend,
- .resume = generic_dpi_panel_resume,
.set_timings = generic_dpi_panel_set_timings,
.get_timings = generic_dpi_panel_get_timings,
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index 90c1cab..6e5abe8 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -143,46 +143,12 @@ static void lb035q02_panel_disable(struct omap_dss_device *dssdev)
mutex_unlock(&ld->lock);
}
-static int lb035q02_panel_suspend(struct omap_dss_device *dssdev)
-{
- struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
-
- mutex_lock(&ld->lock);
-
- lb035q02_panel_power_off(dssdev);
- dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-
- mutex_unlock(&ld->lock);
- return 0;
-}
-
-static int lb035q02_panel_resume(struct omap_dss_device *dssdev)
-{
- struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
- int r;
-
- mutex_lock(&ld->lock);
-
- r = lb035q02_panel_power_on(dssdev);
- if (r)
- goto err;
- dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
- mutex_unlock(&ld->lock);
- return 0;
-err:
- mutex_unlock(&ld->lock);
- return r;
-}
-
static struct omap_dss_driver lb035q02_driver = {
.probe = lb035q02_panel_probe,
.remove = lb035q02_panel_remove,
.enable = lb035q02_panel_enable,
.disable = lb035q02_panel_disable,
- .suspend = lb035q02_panel_suspend,
- .resume = lb035q02_panel_resume,
.driver = {
.name = "lgphilips_lb035q02_panel",
@@ -250,13 +216,13 @@ static void init_lb035q02_panel(struct spi_device *spi)
lb035q02_write_reg(spi, 0x3b, 0x0806);
}
-static int __devinit lb035q02_panel_spi_probe(struct spi_device *spi)
+static int lb035q02_panel_spi_probe(struct spi_device *spi)
{
init_lb035q02_panel(spi);
return omap_dss_register_driver(&lb035q02_driver);
}
-static int __devexit lb035q02_panel_spi_remove(struct spi_device *spi)
+static int lb035q02_panel_spi_remove(struct spi_device *spi)
{
omap_dss_unregister_driver(&lb035q02_driver);
return 0;
@@ -268,7 +234,7 @@ static struct spi_driver lb035q02_spi_driver = {
.owner = THIS_MODULE,
},
.probe = lb035q02_panel_spi_probe,
- .remove = __devexit_p(lb035q02_panel_spi_remove),
+ .remove = lb035q02_panel_spi_remove,
};
module_spi_driver(lb035q02_spi_driver);
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
index 3fc5ad0..dd12947 100644
--- a/drivers/video/omap2/displays/panel-n8x0.c
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -574,54 +574,6 @@ static void n8x0_panel_disable(struct omap_dss_device *dssdev)
mutex_unlock(&ddata->lock);
}
-static int n8x0_panel_suspend(struct omap_dss_device *dssdev)
-{
- struct panel_drv_data *ddata = get_drv_data(dssdev);
-
- dev_dbg(&dssdev->dev, "suspend\n");
-
- mutex_lock(&ddata->lock);
-
- rfbi_bus_lock();
-
- n8x0_panel_power_off(dssdev);
-
- rfbi_bus_unlock();
-
- dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-
- mutex_unlock(&ddata->lock);
-
- return 0;
-}
-
-static int n8x0_panel_resume(struct omap_dss_device *dssdev)
-{
- struct panel_drv_data *ddata = get_drv_data(dssdev);
- int r;
-
- dev_dbg(&dssdev->dev, "resume\n");
-
- mutex_lock(&ddata->lock);
-
- rfbi_bus_lock();
-
- r = n8x0_panel_power_on(dssdev);
-
- rfbi_bus_unlock();
-
- if (r) {
- mutex_unlock(&ddata->lock);
- return r;
- }
-
- dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
- mutex_unlock(&ddata->lock);
-
- return 0;
-}
-
static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev,
u16 *xres, u16 *yres)
{
@@ -683,8 +635,6 @@ static struct omap_dss_driver n8x0_panel_driver = {
.enable = n8x0_panel_enable,
.disable = n8x0_panel_disable,
- .suspend = n8x0_panel_suspend,
- .resume = n8x0_panel_resume,
.update = n8x0_panel_update,
.sync = n8x0_panel_sync,
@@ -702,18 +652,25 @@ static struct omap_dss_driver n8x0_panel_driver = {
static int mipid_spi_probe(struct spi_device *spi)
{
+ int r;
+
dev_dbg(&spi->dev, "mipid_spi_probe\n");
spi->mode = SPI_MODE_0;
s_drv_data.spidev = spi;
- return 0;
+ r = omap_dss_register_driver(&n8x0_panel_driver);
+ if (r)
+ pr_err("n8x0_panel: dss driver registration failed\n");
+
+ return r;
}
static int mipid_spi_remove(struct spi_device *spi)
{
dev_dbg(&spi->dev, "mipid_spi_remove\n");
+ omap_dss_unregister_driver(&n8x0_panel_driver);
return 0;
}
@@ -723,36 +680,8 @@ static struct spi_driver mipid_spi_driver = {
.owner = THIS_MODULE,
},
.probe = mipid_spi_probe,
- .remove = __devexit_p(mipid_spi_remove),
+ .remove = mipid_spi_remove,
};
+module_spi_driver(mipid_spi_driver);
-static int __init n8x0_panel_drv_init(void)
-{
- int r;
-
- r = spi_register_driver(&mipid_spi_driver);
- if (r) {
- pr_err("n8x0_panel: spi driver registration failed\n");
- return r;
- }
-
- r = omap_dss_register_driver(&n8x0_panel_driver);
- if (r) {
- pr_err("n8x0_panel: dss driver registration failed\n");
- spi_unregister_driver(&mipid_spi_driver);
- return r;
- }
-
- return 0;
-}
-
-static void __exit n8x0_panel_drv_exit(void)
-{
- spi_unregister_driver(&mipid_spi_driver);
-
- omap_dss_unregister_driver(&n8x0_panel_driver);
-}
-
-module_init(n8x0_panel_drv_init);
-module_exit(n8x0_panel_drv_exit);
MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index 908fd26..c4e9c2b 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -236,28 +236,6 @@ static void nec_8048_panel_disable(struct omap_dss_device *dssdev)
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}
-static int nec_8048_panel_suspend(struct omap_dss_device *dssdev)
-{
- nec_8048_panel_power_off(dssdev);
-
- dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-
- return 0;
-}
-
-static int nec_8048_panel_resume(struct omap_dss_device *dssdev)
-{
- int r;
-
- r = nec_8048_panel_power_on(dssdev);
- if (r)
- return r;
-
- dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
- return 0;
-}
-
static int nec_8048_recommended_bpp(struct omap_dss_device *dssdev)
{
return 16;
@@ -268,8 +246,6 @@ static struct omap_dss_driver nec_8048_driver = {
.remove = nec_8048_panel_remove,
.enable = nec_8048_panel_enable,
.disable = nec_8048_panel_disable,
- .suspend = nec_8048_panel_suspend,
- .resume = nec_8048_panel_resume,
.get_recommended_bpp = nec_8048_recommended_bpp,
.driver = {
@@ -347,7 +323,7 @@ static int nec_8048_spi_resume(struct spi_device *spi)
static struct spi_driver nec_8048_spi_driver = {
.probe = nec_8048_spi_probe,
- .remove = __devexit_p(nec_8048_spi_remove),
+ .remove = nec_8048_spi_remove,
.suspend = nec_8048_spi_suspend,
.resume = nec_8048_spi_resume,
.driver = {
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
index 9df8764..1b94018 100644
--- a/drivers/video/omap2/displays/panel-picodlp.c
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -50,6 +50,7 @@ struct picodlp_i2c_data {
static struct i2c_device_id picodlp_i2c_id[] = {
{ "picodlp_i2c_driver", 0 },
+ { }
};
struct picodlp_i2c_command {
@@ -503,47 +504,6 @@ static void picodlp_panel_disable(struct omap_dss_device *dssdev)
dev_dbg(&dssdev->dev, "disabling picodlp panel\n");
}
-static int picodlp_panel_suspend(struct omap_dss_device *dssdev)
-{
- struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
-
- mutex_lock(&picod->lock);
- /* Turn off DLP Power */
- if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
- mutex_unlock(&picod->lock);
- dev_err(&dssdev->dev, "unable to suspend picodlp panel,"
- " panel is not ACTIVE\n");
- return -EINVAL;
- }
-
- picodlp_panel_power_off(dssdev);
-
- dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
- mutex_unlock(&picod->lock);
-
- dev_dbg(&dssdev->dev, "suspending picodlp panel\n");
- return 0;
-}
-
-static int picodlp_panel_resume(struct omap_dss_device *dssdev)
-{
- struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
- int r;
-
- mutex_lock(&picod->lock);
- if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
- mutex_unlock(&picod->lock);
- dev_err(&dssdev->dev, "unable to resume picodlp panel,"
- " panel is not ACTIVE\n");
- return -EINVAL;
- }
-
- r = picodlp_panel_power_on(dssdev);
- mutex_unlock(&picod->lock);
- dev_dbg(&dssdev->dev, "resuming picodlp panel\n");
- return r;
-}
-
static void picodlp_get_resolution(struct omap_dss_device *dssdev,
u16 *xres, u16 *yres)
{
@@ -560,9 +520,6 @@ static struct omap_dss_driver picodlp_driver = {
.get_resolution = picodlp_get_resolution,
- .suspend = picodlp_panel_suspend,
- .resume = picodlp_panel_resume,
-
.driver = {
.name = "picodlp_panel",
.owner = THIS_MODULE,
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index 1ec3b27..cada8c6 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -194,29 +194,12 @@ static void sharp_ls_panel_disable(struct omap_dss_device *dssdev)
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}
-static int sharp_ls_panel_suspend(struct omap_dss_device *dssdev)
-{
- sharp_ls_power_off(dssdev);
- dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
- return 0;
-}
-
-static int sharp_ls_panel_resume(struct omap_dss_device *dssdev)
-{
- int r;
- r = sharp_ls_power_on(dssdev);
- dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
- return r;
-}
-
static struct omap_dss_driver sharp_ls_driver = {
.probe = sharp_ls_panel_probe,
.remove = __exit_p(sharp_ls_panel_remove),
.enable = sharp_ls_panel_enable,
.disable = sharp_ls_panel_disable,
- .suspend = sharp_ls_panel_suspend,
- .resume = sharp_ls_panel_resume,
.driver = {
.name = "sharp_ls_panel",
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index f2f6446..a32407a 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1245,76 +1245,6 @@ static void taal_disable(struct omap_dss_device *dssdev)
mutex_unlock(&td->lock);
}
-static int taal_suspend(struct omap_dss_device *dssdev)
-{
- struct taal_data *td = dev_get_drvdata(&dssdev->dev);
- int r;
-
- dev_dbg(&dssdev->dev, "suspend\n");
-
- mutex_lock(&td->lock);
-
- if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
- r = -EINVAL;
- goto err;
- }
-
- taal_cancel_ulps_work(dssdev);
- taal_cancel_esd_work(dssdev);
-
- dsi_bus_lock(dssdev);
-
- r = taal_wake_up(dssdev);
- if (!r)
- taal_power_off(dssdev);
-
- dsi_bus_unlock(dssdev);
-
- dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-
- mutex_unlock(&td->lock);
-
- return 0;
-err:
- mutex_unlock(&td->lock);
- return r;
-}
-
-static int taal_resume(struct omap_dss_device *dssdev)
-{
- struct taal_data *td = dev_get_drvdata(&dssdev->dev);
- int r;
-
- dev_dbg(&dssdev->dev, "resume\n");
-
- mutex_lock(&td->lock);
-
- if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
- r = -EINVAL;
- goto err;
- }
-
- dsi_bus_lock(dssdev);
-
- r = taal_power_on(dssdev);
-
- dsi_bus_unlock(dssdev);
-
- if (r) {
- dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
- } else {
- dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
- taal_queue_esd_work(dssdev);
- }
-
- mutex_unlock(&td->lock);
-
- return r;
-err:
- mutex_unlock(&td->lock);
- return r;
-}
-
static void taal_framedone_cb(int err, void *data)
{
struct omap_dss_device *dssdev = data;
@@ -1818,8 +1748,6 @@ static struct omap_dss_driver taal_driver = {
.enable = taal_enable,
.disable = taal_disable,
- .suspend = taal_suspend,
- .resume = taal_resume,
.update = taal_update,
.sync = taal_sync,
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index 383811c..8281baa 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -189,37 +189,6 @@ static void tfp410_disable(struct omap_dss_device *dssdev)
mutex_unlock(&ddata->lock);
}
-static int tfp410_suspend(struct omap_dss_device *dssdev)
-{
- struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
-
- mutex_lock(&ddata->lock);
-
- tfp410_power_off(dssdev);
-
- dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-
- mutex_unlock(&ddata->lock);
-
- return 0;
-}
-
-static int tfp410_resume(struct omap_dss_device *dssdev)
-{
- struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
- int r;
-
- mutex_lock(&ddata->lock);
-
- r = tfp410_power_on(dssdev);
- if (r == 0)
- dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
- mutex_unlock(&ddata->lock);
-
- return r;
-}
-
static void tfp410_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
@@ -355,8 +324,6 @@ static struct omap_dss_driver tfp410_driver = {
.enable = tfp410_enable,
.disable = tfp410_disable,
- .suspend = tfp410_suspend,
- .resume = tfp410_resume,
.set_timings = tfp410_set_timings,
.get_timings = tfp410_get_timings,
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index b5e6dbc..6b66439 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -401,24 +401,6 @@ static void tpo_td043_disable(struct omap_dss_device *dssdev)
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}
-static int tpo_td043_suspend(struct omap_dss_device *dssdev)
-{
- dev_dbg(&dssdev->dev, "suspend\n");
-
- tpo_td043_disable_dss(dssdev);
-
- dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-
- return 0;
-}
-
-static int tpo_td043_resume(struct omap_dss_device *dssdev)
-{
- dev_dbg(&dssdev->dev, "resume\n");
-
- return tpo_td043_enable_dss(dssdev);
-}
-
static int tpo_td043_probe(struct omap_dss_device *dssdev)
{
struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
@@ -500,8 +482,6 @@ static struct omap_dss_driver tpo_td043_driver = {
.enable = tpo_td043_enable,
.disable = tpo_td043_disable,
- .suspend = tpo_td043_suspend,
- .resume = tpo_td043_resume,
.set_mirror = tpo_td043_set_hmirror,
.get_mirror = tpo_td043_get_hmirror,
@@ -548,7 +528,7 @@ static int tpo_td043_spi_probe(struct spi_device *spi)
return 0;
}
-static int __devexit tpo_td043_spi_remove(struct spi_device *spi)
+static int tpo_td043_spi_remove(struct spi_device *spi)
{
struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&spi->dev);
@@ -600,7 +580,7 @@ static struct spi_driver tpo_td043_spi_driver = {
.pm = &tpo_td043_spi_pm,
},
.probe = tpo_td043_spi_probe,
- .remove = __devexit_p(tpo_td043_spi_remove),
+ .remove = tpo_td043_spi_remove,
};
module_spi_driver(tpo_td043_spi_driver);
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index 80f5390..cb0f145 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -1,33 +1,30 @@
menuconfig OMAP2_DSS
tristate "OMAP2+ Display Subsystem support"
- depends on ARCH_OMAP2PLUS
help
OMAP2+ Display Subsystem support.
if OMAP2_DSS
-config OMAP2_VRAM_SIZE
- int "VRAM size (MB)"
- range 0 32
- default 0
+config OMAP2_DSS_DEBUG
+ bool "Debug support"
+ default n
help
- The amount of SDRAM to reserve at boot time for video RAM use.
- This VRAM will be used by omapfb and other drivers that need
- large continuous RAM area for video use.
+ This enables printing of debug messages. Alternatively, debug messages
+ can also be enabled by setting CONFIG_DYNAMIC_DEBUG and then setting
+ appropriate flags in <debugfs>/dynamic_debug/control.
- You can also set this with "vram=<bytes>" kernel argument, or
- in the board file.
-
-config OMAP2_DSS_DEBUG_SUPPORT
- bool "Debug support"
- default y
+config OMAP2_DSS_DEBUGFS
+ bool "Debugfs filesystem support"
+ depends on DEBUG_FS
+ default n
help
- This enables debug messages. You need to enable printing
- with 'debug' module parameter.
+ This enables debugfs for OMAPDSS at <debugfs>/omapdss. This enables
+ querying about clock configuration and register configuration of dss,
+ dispc, dsi, hdmi and rfbi.
config OMAP2_DSS_COLLECT_IRQ_STATS
bool "Collect DSS IRQ statistics"
- depends on OMAP2_DSS_DEBUG_SUPPORT
+ depends on OMAP2_DSS_DEBUGFS
default n
help
Collect DSS IRQ statistics, printable via debugfs.
@@ -62,7 +59,6 @@ config OMAP2_DSS_VENC
config OMAP4_DSS_HDMI
bool "HDMI support"
- depends on ARCH_OMAP4
default y
help
HDMI Interface. This adds the High Definition Multimedia Interface.
@@ -70,11 +66,9 @@ config OMAP4_DSS_HDMI
config OMAP4_DSS_HDMI_AUDIO
bool
- depends on OMAP4_DSS_HDMI
config OMAP2_DSS_SDI
bool "SDI support"
- depends on ARCH_OMAP3
default n
help
SDI (Serial Display Interface) support.
@@ -84,7 +78,6 @@ config OMAP2_DSS_SDI
config OMAP2_DSS_DSI
bool "DSI support"
- depends on ARCH_OMAP3 || ARCH_OMAP4 || ARCH_OMAP5
default n
help
MIPI DSI (Display Serial Interface) support.
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 4549869..61949ff 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,6 +1,10 @@
obj-$(CONFIG_OMAP2_DSS) += omapdss.o
+# Core DSS files
omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
- manager.o manager-sysfs.o overlay.o overlay-sysfs.o output.o apply.o
+ output.o
+# DSS compat layer files
+omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \
+ dispc-compat.o display-sysfs.o
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
@@ -8,3 +12,4 @@ omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
hdmi_panel.o ti_hdmi_4xxx_ip.o
+ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 19d66f4..d446bdf 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -18,6 +18,7 @@
#define DSS_SUBSYS_NAME "APPLY"
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/jiffies.h>
@@ -26,6 +27,7 @@
#include "dss.h"
#include "dss_features.h"
+#include "dispc-compat.h"
/*
* We have 4 levels of cache for the dispc settings. First two are in SW and
@@ -70,7 +72,6 @@ struct ovl_priv_data {
bool shadow_extra_info_dirty;
bool enabled;
- enum omap_channel channel;
u32 fifo_low, fifo_high;
/*
@@ -105,6 +106,9 @@ struct mgr_priv_data {
struct omap_video_timings timings;
struct dss_lcd_mgr_config lcd_config;
+
+ void (*framedone_handler)(void *);
+ void *framedone_handler_data;
};
static struct {
@@ -132,7 +136,7 @@ static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr)
return &dss_data.mgr_priv_data_array[mgr->id];
}
-void dss_apply_init(void)
+static void apply_init_priv(void)
{
const int num_ovls = dss_feat_get_num_ovls();
struct mgr_priv_data *mp;
@@ -414,11 +418,46 @@ static void wait_pending_extra_info_updates(void)
r = wait_for_completion_timeout(&extra_updated_completion, t);
if (r == 0)
DSSWARN("timeout in wait_pending_extra_info_updates\n");
- else if (r < 0)
- DSSERR("wait_pending_extra_info_updates failed: %d\n", r);
}
-int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
+static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl)
+{
+ return ovl->manager ?
+ (ovl->manager->output ? ovl->manager->output->device : NULL) :
+ NULL;
+}
+
+static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
+{
+ return mgr->output ? mgr->output->device : NULL;
+}
+
+static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
+{
+ unsigned long timeout = msecs_to_jiffies(500);
+ struct omap_dss_device *dssdev = mgr->get_device(mgr);
+ u32 irq;
+ int r;
+
+ r = dispc_runtime_get();
+ if (r)
+ return r;
+
+ if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
+ irq = DISPC_IRQ_EVSYNC_ODD;
+ else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI)
+ irq = DISPC_IRQ_EVSYNC_EVEN;
+ else
+ irq = dispc_mgr_get_vsync_irq(mgr->id);
+
+ r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
+
+ dispc_runtime_put();
+
+ return r;
+}
+
+static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
{
unsigned long timeout = msecs_to_jiffies(500);
struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -488,7 +527,7 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
return r;
}
-int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
+static int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
{
unsigned long timeout = msecs_to_jiffies(500);
struct ovl_priv_data *op;
@@ -573,7 +612,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
struct mgr_priv_data *mp;
int r;
- DSSDBGF("%d", ovl->id);
+ DSSDBG("writing ovl %d regs", ovl->id);
if (!op->enabled || !op->info_dirty)
return;
@@ -608,7 +647,7 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
struct ovl_priv_data *op = get_ovl_priv(ovl);
struct mgr_priv_data *mp;
- DSSDBGF("%d", ovl->id);
+ DSSDBG("writing ovl %d regs extra", ovl->id);
if (!op->extra_info_dirty)
return;
@@ -617,7 +656,6 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
* disabled */
dispc_ovl_enable(ovl->id, op->enabled);
- dispc_ovl_set_channel_out(ovl->id, op->channel);
dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
mp = get_mgr_priv(ovl->manager);
@@ -632,7 +670,7 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
struct mgr_priv_data *mp = get_mgr_priv(mgr);
struct omap_overlay *ovl;
- DSSDBGF("%d", mgr->id);
+ DSSDBG("writing mgr %d regs", mgr->id);
if (!mp->enabled)
return;
@@ -658,7 +696,7 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
- DSSDBGF("%d", mgr->id);
+ DSSDBG("writing mgr %d regs extra", mgr->id);
if (!mp->extra_info_dirty)
return;
@@ -666,22 +704,8 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
dispc_mgr_set_timings(mgr->id, &mp->timings);
/* lcd_config parameters */
- if (dss_mgr_is_lcd(mgr->id)) {
- dispc_mgr_set_io_pad_mode(mp->lcd_config.io_pad_mode);
-
- dispc_mgr_enable_stallmode(mgr->id, mp->lcd_config.stallmode);
- dispc_mgr_enable_fifohandcheck(mgr->id,
- mp->lcd_config.fifohandcheck);
-
- dispc_mgr_set_clock_div(mgr->id, &mp->lcd_config.clock_info);
-
- dispc_mgr_set_tft_data_lines(mgr->id,
- mp->lcd_config.video_port_width);
-
- dispc_lcd_enable_signal_polarity(mp->lcd_config.lcden_sig_polarity);
-
- dispc_mgr_set_lcd_type_tft(mgr->id);
- }
+ if (dss_mgr_is_lcd(mgr->id))
+ dispc_mgr_set_lcd_config(mgr->id, &mp->lcd_config);
mp->extra_info_dirty = false;
if (mp->updating)
@@ -761,7 +785,7 @@ static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
}
}
-void dss_mgr_start_update(struct omap_overlay_manager *mgr)
+static void dss_mgr_start_update_compat(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
unsigned long flags;
@@ -786,9 +810,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
if (!dss_data.irq_enabled && need_isr())
dss_register_vsync_isr();
- dispc_mgr_enable(mgr->id, true);
-
- mgr_clear_shadow_dirty(mgr);
+ dispc_mgr_enable_sync(mgr->id);
spin_unlock_irqrestore(&data_lock, flags);
}
@@ -845,7 +867,6 @@ static void dss_apply_irq_handler(void *data, u32 mask)
for (i = 0; i < num_mgrs; i++) {
struct omap_overlay_manager *mgr;
struct mgr_priv_data *mp;
- bool was_updating;
mgr = omap_dss_get_overlay_manager(i);
mp = get_mgr_priv(mgr);
@@ -853,7 +874,6 @@ static void dss_apply_irq_handler(void *data, u32 mask)
if (!mp->enabled)
continue;
- was_updating = mp->updating;
mp->updating = dispc_mgr_is_enabled(i);
if (!mgr_manual_update(mgr)) {
@@ -872,6 +892,21 @@ static void dss_apply_irq_handler(void *data, u32 mask)
if (!extra_updating)
complete_all(&extra_updated_completion);
+ /* call framedone handlers for manual update displays */
+ for (i = 0; i < num_mgrs; i++) {
+ struct omap_overlay_manager *mgr;
+ struct mgr_priv_data *mp;
+
+ mgr = omap_dss_get_overlay_manager(i);
+ mp = get_mgr_priv(mgr);
+
+ if (!mgr_manual_update(mgr) || !mp->framedone_handler)
+ continue;
+
+ if (mask & dispc_mgr_get_framedone_irq(i))
+ mp->framedone_handler(mp->framedone_handler_data);
+ }
+
if (!need_isr())
dss_unregister_vsync_isr();
@@ -906,7 +941,7 @@ static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
mp->info = mp->user_info;
}
-int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
+static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
{
unsigned long flags;
struct omap_overlay *ovl;
@@ -1005,7 +1040,7 @@ static void dss_setup_fifos(void)
}
}
-int dss_mgr_enable(struct omap_overlay_manager *mgr)
+static int dss_mgr_enable_compat(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
unsigned long flags;
@@ -1035,10 +1070,13 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
if (!mgr_manual_update(mgr))
mp->updating = true;
+ if (!dss_data.irq_enabled && need_isr())
+ dss_register_vsync_isr();
+
spin_unlock_irqrestore(&data_lock, flags);
if (!mgr_manual_update(mgr))
- dispc_mgr_enable(mgr->id, true);
+ dispc_mgr_enable_sync(mgr->id);
out:
mutex_unlock(&apply_lock);
@@ -1052,7 +1090,7 @@ err:
return r;
}
-void dss_mgr_disable(struct omap_overlay_manager *mgr)
+static void dss_mgr_disable_compat(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
unsigned long flags;
@@ -1063,7 +1101,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
goto out;
if (!mgr_manual_update(mgr))
- dispc_mgr_enable(mgr->id, false);
+ dispc_mgr_disable_sync(mgr->id);
spin_lock_irqsave(&data_lock, flags);
@@ -1076,7 +1114,7 @@ out:
mutex_unlock(&apply_lock);
}
-int dss_mgr_set_info(struct omap_overlay_manager *mgr,
+static int dss_mgr_set_info(struct omap_overlay_manager *mgr,
struct omap_overlay_manager_info *info)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -1097,7 +1135,7 @@ int dss_mgr_set_info(struct omap_overlay_manager *mgr,
return 0;
}
-void dss_mgr_get_info(struct omap_overlay_manager *mgr,
+static void dss_mgr_get_info(struct omap_overlay_manager *mgr,
struct omap_overlay_manager_info *info)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -1110,7 +1148,7 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
spin_unlock_irqrestore(&data_lock, flags);
}
-int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+static int dss_mgr_set_output(struct omap_overlay_manager *mgr,
struct omap_dss_output *output)
{
int r;
@@ -1142,7 +1180,7 @@ err:
return r;
}
-int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
+static int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
{
int r;
struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -1189,7 +1227,7 @@ static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
mp->extra_info_dirty = true;
}
-void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
+static void dss_mgr_set_timings_compat(struct omap_overlay_manager *mgr,
const struct omap_video_timings *timings)
{
unsigned long flags;
@@ -1217,7 +1255,7 @@ static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr,
mp->extra_info_dirty = true;
}
-void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
+static void dss_mgr_set_lcd_config_compat(struct omap_overlay_manager *mgr,
const struct dss_lcd_mgr_config *config)
{
unsigned long flags;
@@ -1236,7 +1274,7 @@ out:
spin_unlock_irqrestore(&data_lock, flags);
}
-int dss_ovl_set_info(struct omap_overlay *ovl,
+static int dss_ovl_set_info(struct omap_overlay *ovl,
struct omap_overlay_info *info)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
@@ -1257,7 +1295,7 @@ int dss_ovl_set_info(struct omap_overlay *ovl,
return 0;
}
-void dss_ovl_get_info(struct omap_overlay *ovl,
+static void dss_ovl_get_info(struct omap_overlay *ovl,
struct omap_overlay_info *info)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
@@ -1270,7 +1308,7 @@ void dss_ovl_get_info(struct omap_overlay *ovl,
spin_unlock_irqrestore(&data_lock, flags);
}
-int dss_ovl_set_manager(struct omap_overlay *ovl,
+static int dss_ovl_set_manager(struct omap_overlay *ovl,
struct omap_overlay_manager *mgr)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
@@ -1289,45 +1327,40 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
goto err;
}
+ r = dispc_runtime_get();
+ if (r)
+ goto err;
+
spin_lock_irqsave(&data_lock, flags);
if (op->enabled) {
spin_unlock_irqrestore(&data_lock, flags);
DSSERR("overlay has to be disabled to change the manager\n");
r = -EINVAL;
- goto err;
+ goto err1;
}
- op->channel = mgr->id;
- op->extra_info_dirty = true;
+ dispc_ovl_set_channel_out(ovl->id, mgr->id);
ovl->manager = mgr;
list_add_tail(&ovl->list, &mgr->overlays);
spin_unlock_irqrestore(&data_lock, flags);
- /* XXX: When there is an overlay on a DSI manual update display, and
- * the overlay is first disabled, then moved to tv, and enabled, we
- * seem to get SYNC_LOST_DIGIT error.
- *
- * Waiting doesn't seem to help, but updating the manual update display
- * after disabling the overlay seems to fix this. This hints that the
- * overlay is perhaps somehow tied to the LCD output until the output
- * is updated.
- *
- * Userspace workaround for this is to update the LCD after disabling
- * the overlay, but before moving the overlay to TV.
- */
+ dispc_runtime_put();
mutex_unlock(&apply_lock);
return 0;
+
+err1:
+ dispc_runtime_put();
err:
mutex_unlock(&apply_lock);
return r;
}
-int dss_ovl_unset_manager(struct omap_overlay *ovl)
+static int dss_ovl_unset_manager(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
unsigned long flags;
@@ -1355,9 +1388,24 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl)
/* wait for pending extra_info updates to ensure the ovl is disabled */
wait_pending_extra_info_updates();
+ /*
+ * For a manual update display, there is no guarantee that the overlay
+ * is really disabled in HW, we may need an extra update from this
+ * manager before the configurations can go in. Return an error if the
+ * overlay needed an update from the manager.
+ *
+ * TODO: Instead of returning an error, try to do a dummy manager update
+ * here to disable the overlay in hardware. Use the *GATED fields in
+ * the DISPC_CONFIG registers to do a dummy update.
+ */
spin_lock_irqsave(&data_lock, flags);
- op->channel = -1;
+ if (ovl_manual_update(ovl) && op->extra_info_dirty) {
+ spin_unlock_irqrestore(&data_lock, flags);
+ DSSERR("need an update to change the manager\n");
+ r = -EINVAL;
+ goto err;
+ }
ovl->manager = NULL;
list_del(&ovl->list);
@@ -1372,7 +1420,7 @@ err:
return r;
}
-bool dss_ovl_is_enabled(struct omap_overlay *ovl)
+static bool dss_ovl_is_enabled(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
unsigned long flags;
@@ -1387,7 +1435,7 @@ bool dss_ovl_is_enabled(struct omap_overlay *ovl)
return e;
}
-int dss_ovl_enable(struct omap_overlay *ovl)
+static int dss_ovl_enable(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
unsigned long flags;
@@ -1437,7 +1485,7 @@ err1:
return r;
}
-int dss_ovl_disable(struct omap_overlay *ovl)
+static int dss_ovl_disable(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
unsigned long flags;
@@ -1472,3 +1520,152 @@ err:
return r;
}
+static int dss_mgr_register_framedone_handler_compat(struct omap_overlay_manager *mgr,
+ void (*handler)(void *), void *data)
+{
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+
+ if (mp->framedone_handler)
+ return -EBUSY;
+
+ mp->framedone_handler = handler;
+ mp->framedone_handler_data = data;
+
+ return 0;
+}
+
+static void dss_mgr_unregister_framedone_handler_compat(struct omap_overlay_manager *mgr,
+ void (*handler)(void *), void *data)
+{
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+
+ WARN_ON(mp->framedone_handler != handler ||
+ mp->framedone_handler_data != data);
+
+ mp->framedone_handler = NULL;
+ mp->framedone_handler_data = NULL;
+}
+
+static const struct dss_mgr_ops apply_mgr_ops = {
+ .start_update = dss_mgr_start_update_compat,
+ .enable = dss_mgr_enable_compat,
+ .disable = dss_mgr_disable_compat,
+ .set_timings = dss_mgr_set_timings_compat,
+ .set_lcd_config = dss_mgr_set_lcd_config_compat,
+ .register_framedone_handler = dss_mgr_register_framedone_handler_compat,
+ .unregister_framedone_handler = dss_mgr_unregister_framedone_handler_compat,
+};
+
+static int compat_refcnt;
+static DEFINE_MUTEX(compat_init_lock);
+
+int omapdss_compat_init(void)
+{
+ struct platform_device *pdev = dss_get_core_pdev();
+ struct omap_dss_device *dssdev = NULL;
+ int i, r;
+
+ mutex_lock(&compat_init_lock);
+
+ if (compat_refcnt++ > 0)
+ goto out;
+
+ apply_init_priv();
+
+ dss_init_overlay_managers(pdev);
+ dss_init_overlays(pdev);
+
+ for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) {
+ struct omap_overlay_manager *mgr;
+
+ mgr = omap_dss_get_overlay_manager(i);
+
+ mgr->set_output = &dss_mgr_set_output;
+ mgr->unset_output = &dss_mgr_unset_output;
+ mgr->apply = &omap_dss_mgr_apply;
+ mgr->set_manager_info = &dss_mgr_set_info;
+ mgr->get_manager_info = &dss_mgr_get_info;
+ mgr->wait_for_go = &dss_mgr_wait_for_go;
+ mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
+ mgr->get_device = &dss_mgr_get_device;
+ }
+
+ for (i = 0; i < omap_dss_get_num_overlays(); i++) {
+ struct omap_overlay *ovl = omap_dss_get_overlay(i);
+
+ ovl->is_enabled = &dss_ovl_is_enabled;
+ ovl->enable = &dss_ovl_enable;
+ ovl->disable = &dss_ovl_disable;
+ ovl->set_manager = &dss_ovl_set_manager;
+ ovl->unset_manager = &dss_ovl_unset_manager;
+ ovl->set_overlay_info = &dss_ovl_set_info;
+ ovl->get_overlay_info = &dss_ovl_get_info;
+ ovl->wait_for_go = &dss_mgr_wait_for_go_ovl;
+ ovl->get_device = &dss_ovl_get_device;
+ }
+
+ r = dss_install_mgr_ops(&apply_mgr_ops);
+ if (r)
+ goto err_mgr_ops;
+
+ for_each_dss_dev(dssdev) {
+ r = display_init_sysfs(pdev, dssdev);
+ /* XXX uninit sysfs files on error */
+ if (r)
+ goto err_disp_sysfs;
+ }
+
+ dispc_runtime_get();
+
+ r = dss_dispc_initialize_irq();
+ if (r)
+ goto err_init_irq;
+
+ dispc_runtime_put();
+
+out:
+ mutex_unlock(&compat_init_lock);
+
+ return 0;
+
+err_init_irq:
+ dispc_runtime_put();
+
+err_disp_sysfs:
+ dss_uninstall_mgr_ops();
+
+err_mgr_ops:
+ dss_uninit_overlay_managers(pdev);
+ dss_uninit_overlays(pdev);
+
+ compat_refcnt--;
+
+ mutex_unlock(&compat_init_lock);
+
+ return r;
+}
+EXPORT_SYMBOL(omapdss_compat_init);
+
+void omapdss_compat_uninit(void)
+{
+ struct platform_device *pdev = dss_get_core_pdev();
+ struct omap_dss_device *dssdev = NULL;
+
+ mutex_lock(&compat_init_lock);
+
+ if (--compat_refcnt > 0)
+ goto out;
+
+ dss_dispc_uninitialize_irq();
+
+ for_each_dss_dev(dssdev)
+ display_uninit_sysfs(pdev, dssdev);
+
+ dss_uninstall_mgr_ops();
+
+ dss_uninit_overlay_managers(pdev);
+ dss_uninit_overlays(pdev);
+out:
+ mutex_unlock(&compat_init_lock);
+}
+EXPORT_SYMBOL(omapdss_compat_uninit);
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index b2af72d..f8779d4 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -53,15 +53,23 @@ static char *def_disp_name;
module_param_named(def_disp, def_disp_name, charp, 0);
MODULE_PARM_DESC(def_disp, "default display name");
-#ifdef DEBUG
-bool dss_debug;
-module_param_named(debug, dss_debug, bool, 0644);
-#endif
-
-const char *dss_get_default_display_name(void)
+const char *omapdss_get_default_display_name(void)
{
return core.default_display_name;
}
+EXPORT_SYMBOL(omapdss_get_default_display_name);
+
+enum omapdss_version omapdss_get_version(void)
+{
+ struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
+ return pdata->version;
+}
+EXPORT_SYMBOL(omapdss_get_version);
+
+struct platform_device *dss_get_core_pdev(void)
+{
+ return core.pdev;
+}
/* REGULATORS */
@@ -93,21 +101,6 @@ struct regulator *dss_get_vdds_sdi(void)
return reg;
}
-int dss_get_ctx_loss_count(struct device *dev)
-{
- struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
- int cnt;
-
- if (!board_data->get_context_loss_count)
- return -ENOENT;
-
- cnt = board_data->get_context_loss_count(dev);
-
- WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt);
-
- return cnt;
-}
-
int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask)
{
struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
@@ -122,7 +115,7 @@ void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask)
{
struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
- if (!board_data->dsi_enable_pads)
+ if (!board_data->dsi_disable_pads)
return;
return board_data->dsi_disable_pads(dsi_id, lane_mask);
@@ -138,7 +131,7 @@ int dss_set_min_bus_tput(struct device *dev, unsigned long tput)
return 0;
}
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
+#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
static int dss_debug_show(struct seq_file *s, void *unused)
{
void (*func)(struct seq_file *) = s->private;
@@ -193,7 +186,7 @@ int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
return 0;
}
-#else /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */
+#else /* CONFIG_OMAP2_DSS_DEBUGFS */
static inline int dss_initialize_debugfs(void)
{
return 0;
@@ -205,7 +198,7 @@ int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
{
return 0;
}
-#endif /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */
+#endif /* CONFIG_OMAP2_DSS_DEBUGFS */
/* PLATFORM DEVICE */
static int omap_dss_pm_notif(struct notifier_block *b, unsigned long v, void *d)
@@ -237,12 +230,7 @@ static int __init omap_dss_probe(struct platform_device *pdev)
core.pdev = pdev;
- dss_features_init();
-
- dss_apply_init();
-
- dss_init_overlay_managers(pdev);
- dss_init_overlays(pdev);
+ dss_features_init(omapdss_get_version());
r = dss_initialize_debugfs();
if (r)
@@ -268,9 +256,6 @@ static int omap_dss_remove(struct platform_device *pdev)
dss_uninitialize_debugfs();
- dss_uninit_overlays(pdev);
- dss_uninit_overlay_managers(pdev);
-
return 0;
}
@@ -358,15 +343,10 @@ static int dss_driver_probe(struct device *dev)
dev_name(dev), dssdev->driver_name,
dssdrv->driver.name);
- r = dss_init_device(core.pdev, dssdev);
- if (r)
- return r;
-
r = dssdrv->probe(dssdev);
if (r) {
DSSERR("driver probe failed: %d\n", r);
- dss_uninit_device(core.pdev, dssdev);
return r;
}
@@ -387,8 +367,6 @@ static int dss_driver_remove(struct device *dev)
dssdrv->remove(dssdev);
- dss_uninit_device(core.pdev, dssdev);
-
dssdev->driver = NULL;
return 0;
@@ -507,6 +485,9 @@ static int __init omap_dss_bus_register(void)
/* INIT */
static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
+#ifdef CONFIG_OMAP2_DSS_DSI
+ dsi_init_platform_driver,
+#endif
#ifdef CONFIG_OMAP2_DSS_DPI
dpi_init_platform_driver,
#endif
@@ -519,15 +500,15 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
#ifdef CONFIG_OMAP2_DSS_VENC
venc_init_platform_driver,
#endif
-#ifdef CONFIG_OMAP2_DSS_DSI
- dsi_init_platform_driver,
-#endif
#ifdef CONFIG_OMAP4_DSS_HDMI
hdmi_init_platform_driver,
#endif
};
static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = {
+#ifdef CONFIG_OMAP2_DSS_DSI
+ dsi_uninit_platform_driver,
+#endif
#ifdef CONFIG_OMAP2_DSS_DPI
dpi_uninit_platform_driver,
#endif
@@ -540,9 +521,6 @@ static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = {
#ifdef CONFIG_OMAP2_DSS_VENC
venc_uninit_platform_driver,
#endif
-#ifdef CONFIG_OMAP2_DSS_DSI
- dsi_uninit_platform_driver,
-#endif
#ifdef CONFIG_OMAP4_DSS_HDMI
hdmi_uninit_platform_driver,
#endif
diff --git a/drivers/video/omap2/dss/dispc-compat.c b/drivers/video/omap2/dss/dispc-compat.c
new file mode 100644
index 0000000..928884c
--- /dev/null
+++ b/drivers/video/omap2/dss/dispc-compat.c
@@ -0,0 +1,667 @@
+/*
+ * Copyright (C) 2012 Texas Instruments
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "APPLY"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/seq_file.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+#include "dss_features.h"
+#include "dispc-compat.h"
+
+#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
+ DISPC_IRQ_OCP_ERR | \
+ DISPC_IRQ_VID1_FIFO_UNDERFLOW | \
+ DISPC_IRQ_VID2_FIFO_UNDERFLOW | \
+ DISPC_IRQ_SYNC_LOST | \
+ DISPC_IRQ_SYNC_LOST_DIGIT)
+
+#define DISPC_MAX_NR_ISRS 8
+
+struct omap_dispc_isr_data {
+ omap_dispc_isr_t isr;
+ void *arg;
+ u32 mask;
+};
+
+struct dispc_irq_stats {
+ unsigned long last_reset;
+ unsigned irq_count;
+ unsigned irqs[32];
+};
+
+static struct {
+ spinlock_t irq_lock;
+ u32 irq_error_mask;
+ struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
+ u32 error_irqs;
+ struct work_struct error_work;
+
+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
+ spinlock_t irq_stats_lock;
+ struct dispc_irq_stats irq_stats;
+#endif
+} dispc_compat;
+
+
+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
+static void dispc_dump_irqs(struct seq_file *s)
+{
+ unsigned long flags;
+ struct dispc_irq_stats stats;
+
+ spin_lock_irqsave(&dispc_compat.irq_stats_lock, flags);
+
+ stats = dispc_compat.irq_stats;
+ memset(&dispc_compat.irq_stats, 0, sizeof(dispc_compat.irq_stats));
+ dispc_compat.irq_stats.last_reset = jiffies;
+
+ spin_unlock_irqrestore(&dispc_compat.irq_stats_lock, flags);
+
+ seq_printf(s, "period %u ms\n",
+ jiffies_to_msecs(jiffies - stats.last_reset));
+
+ seq_printf(s, "irqs %d\n", stats.irq_count);
+#define PIS(x) \
+ seq_printf(s, "%-20s %10d\n", #x, stats.irqs[ffs(DISPC_IRQ_##x)-1]);
+
+ PIS(FRAMEDONE);
+ PIS(VSYNC);
+ PIS(EVSYNC_EVEN);
+ PIS(EVSYNC_ODD);
+ PIS(ACBIAS_COUNT_STAT);
+ PIS(PROG_LINE_NUM);
+ PIS(GFX_FIFO_UNDERFLOW);
+ PIS(GFX_END_WIN);
+ PIS(PAL_GAMMA_MASK);
+ PIS(OCP_ERR);
+ PIS(VID1_FIFO_UNDERFLOW);
+ PIS(VID1_END_WIN);
+ PIS(VID2_FIFO_UNDERFLOW);
+ PIS(VID2_END_WIN);
+ if (dss_feat_get_num_ovls() > 3) {
+ PIS(VID3_FIFO_UNDERFLOW);
+ PIS(VID3_END_WIN);
+ }
+ PIS(SYNC_LOST);
+ PIS(SYNC_LOST_DIGIT);
+ PIS(WAKEUP);
+ if (dss_has_feature(FEAT_MGR_LCD2)) {
+ PIS(FRAMEDONE2);
+ PIS(VSYNC2);
+ PIS(ACBIAS_COUNT_STAT2);
+ PIS(SYNC_LOST2);
+ }
+ if (dss_has_feature(FEAT_MGR_LCD3)) {
+ PIS(FRAMEDONE3);
+ PIS(VSYNC3);
+ PIS(ACBIAS_COUNT_STAT3);
+ PIS(SYNC_LOST3);
+ }
+#undef PIS
+}
+#endif
+
+/* dispc.irq_lock has to be locked by the caller */
+static void _omap_dispc_set_irqs(void)
+{
+ u32 mask;
+ int i;
+ struct omap_dispc_isr_data *isr_data;
+
+ mask = dispc_compat.irq_error_mask;
+
+ for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+ isr_data = &dispc_compat.registered_isr[i];
+
+ if (isr_data->isr == NULL)
+ continue;
+
+ mask |= isr_data->mask;
+ }
+
+ dispc_write_irqenable(mask);
+}
+
+int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
+{
+ int i;
+ int ret;
+ unsigned long flags;
+ struct omap_dispc_isr_data *isr_data;
+
+ if (isr == NULL)
+ return -EINVAL;
+
+ spin_lock_irqsave(&dispc_compat.irq_lock, flags);
+
+ /* check for duplicate entry */
+ for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+ isr_data = &dispc_compat.registered_isr[i];
+ if (isr_data->isr == isr && isr_data->arg == arg &&
+ isr_data->mask == mask) {
+ ret = -EINVAL;
+ goto err;
+ }
+ }
+
+ isr_data = NULL;
+ ret = -EBUSY;
+
+ for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+ isr_data = &dispc_compat.registered_isr[i];
+
+ if (isr_data->isr != NULL)
+ continue;
+
+ isr_data->isr = isr;
+ isr_data->arg = arg;
+ isr_data->mask = mask;
+ ret = 0;
+
+ break;
+ }
+
+ if (ret)
+ goto err;
+
+ _omap_dispc_set_irqs();
+
+ spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
+
+ return 0;
+err:
+ spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(omap_dispc_register_isr);
+
+int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
+{
+ int i;
+ unsigned long flags;
+ int ret = -EINVAL;
+ struct omap_dispc_isr_data *isr_data;
+
+ spin_lock_irqsave(&dispc_compat.irq_lock, flags);
+
+ for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+ isr_data = &dispc_compat.registered_isr[i];
+ if (isr_data->isr != isr || isr_data->arg != arg ||
+ isr_data->mask != mask)
+ continue;
+
+ /* found the correct isr */
+
+ isr_data->isr = NULL;
+ isr_data->arg = NULL;
+ isr_data->mask = 0;
+
+ ret = 0;
+ break;
+ }
+
+ if (ret == 0)
+ _omap_dispc_set_irqs();
+
+ spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(omap_dispc_unregister_isr);
+
+static void print_irq_status(u32 status)
+{
+ if ((status & dispc_compat.irq_error_mask) == 0)
+ return;
+
+#define PIS(x) (status & DISPC_IRQ_##x) ? (#x " ") : ""
+
+ pr_debug("DISPC IRQ: 0x%x: %s%s%s%s%s%s%s%s%s\n",
+ status,
+ PIS(OCP_ERR),
+ PIS(GFX_FIFO_UNDERFLOW),
+ PIS(VID1_FIFO_UNDERFLOW),
+ PIS(VID2_FIFO_UNDERFLOW),
+ dss_feat_get_num_ovls() > 3 ? PIS(VID3_FIFO_UNDERFLOW) : "",
+ PIS(SYNC_LOST),
+ PIS(SYNC_LOST_DIGIT),
+ dss_has_feature(FEAT_MGR_LCD2) ? PIS(SYNC_LOST2) : "",
+ dss_has_feature(FEAT_MGR_LCD3) ? PIS(SYNC_LOST3) : "");
+#undef PIS
+}
+
+/* Called from dss.c. Note that we don't touch clocks here,
+ * but we presume they are on because we got an IRQ. However,
+ * an irq handler may turn the clocks off, so we may not have
+ * clock later in the function. */
+static irqreturn_t omap_dispc_irq_handler(int irq, void *arg)
+{
+ int i;
+ u32 irqstatus, irqenable;
+ u32 handledirqs = 0;
+ u32 unhandled_errors;
+ struct omap_dispc_isr_data *isr_data;
+ struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
+
+ spin_lock(&dispc_compat.irq_lock);
+
+ irqstatus = dispc_read_irqstatus();
+ irqenable = dispc_read_irqenable();
+
+ /* IRQ is not for us */
+ if (!(irqstatus & irqenable)) {
+ spin_unlock(&dispc_compat.irq_lock);
+ return IRQ_NONE;
+ }
+
+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
+ spin_lock(&dispc_compat.irq_stats_lock);
+ dispc_compat.irq_stats.irq_count++;
+ dss_collect_irq_stats(irqstatus, dispc_compat.irq_stats.irqs);
+ spin_unlock(&dispc_compat.irq_stats_lock);
+#endif
+
+ print_irq_status(irqstatus);
+
+ /* Ack the interrupt. Do it here before clocks are possibly turned
+ * off */
+ dispc_clear_irqstatus(irqstatus);
+ /* flush posted write */
+ dispc_read_irqstatus();
+
+ /* make a copy and unlock, so that isrs can unregister
+ * themselves */
+ memcpy(registered_isr, dispc_compat.registered_isr,
+ sizeof(registered_isr));
+
+ spin_unlock(&dispc_compat.irq_lock);
+
+ for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+ isr_data = &registered_isr[i];
+
+ if (!isr_data->isr)
+ continue;
+
+ if (isr_data->mask & irqstatus) {
+ isr_data->isr(isr_data->arg, irqstatus);
+ handledirqs |= isr_data->mask;
+ }
+ }
+
+ spin_lock(&dispc_compat.irq_lock);
+
+ unhandled_errors = irqstatus & ~handledirqs & dispc_compat.irq_error_mask;
+
+ if (unhandled_errors) {
+ dispc_compat.error_irqs |= unhandled_errors;
+
+ dispc_compat.irq_error_mask &= ~unhandled_errors;
+ _omap_dispc_set_irqs();
+
+ schedule_work(&dispc_compat.error_work);
+ }
+
+ spin_unlock(&dispc_compat.irq_lock);
+
+ return IRQ_HANDLED;
+}
+
+static void dispc_error_worker(struct work_struct *work)
+{
+ int i;
+ u32 errors;
+ unsigned long flags;
+ static const unsigned fifo_underflow_bits[] = {
+ DISPC_IRQ_GFX_FIFO_UNDERFLOW,
+ DISPC_IRQ_VID1_FIFO_UNDERFLOW,
+ DISPC_IRQ_VID2_FIFO_UNDERFLOW,
+ DISPC_IRQ_VID3_FIFO_UNDERFLOW,
+ };
+
+ spin_lock_irqsave(&dispc_compat.irq_lock, flags);
+ errors = dispc_compat.error_irqs;
+ dispc_compat.error_irqs = 0;
+ spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
+
+ dispc_runtime_get();
+
+ for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+ struct omap_overlay *ovl;
+ unsigned bit;
+
+ ovl = omap_dss_get_overlay(i);
+ bit = fifo_underflow_bits[i];
+
+ if (bit & errors) {
+ DSSERR("FIFO UNDERFLOW on %s, disabling the overlay\n",
+ ovl->name);
+ dispc_ovl_enable(ovl->id, false);
+ dispc_mgr_go(ovl->manager->id);
+ msleep(50);
+ }
+ }
+
+ for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
+ struct omap_overlay_manager *mgr;
+ unsigned bit;
+
+ mgr = omap_dss_get_overlay_manager(i);
+ bit = dispc_mgr_get_sync_lost_irq(i);
+
+ if (bit & errors) {
+ int j;
+
+ DSSERR("SYNC_LOST on channel %s, restarting the output "
+ "with video overlays disabled\n",
+ mgr->name);
+
+ dss_mgr_disable(mgr);
+
+ for (j = 0; j < omap_dss_get_num_overlays(); ++j) {
+ struct omap_overlay *ovl;
+ ovl = omap_dss_get_overlay(j);
+
+ if (ovl->id != OMAP_DSS_GFX &&
+ ovl->manager == mgr)
+ ovl->disable(ovl);
+ }
+
+ dss_mgr_enable(mgr);
+ }
+ }
+
+ if (errors & DISPC_IRQ_OCP_ERR) {
+ DSSERR("OCP_ERR\n");
+ for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
+ struct omap_overlay_manager *mgr;
+
+ mgr = omap_dss_get_overlay_manager(i);
+ dss_mgr_disable(mgr);
+ }
+ }
+
+ spin_lock_irqsave(&dispc_compat.irq_lock, flags);
+ dispc_compat.irq_error_mask |= errors;
+ _omap_dispc_set_irqs();
+ spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
+
+ dispc_runtime_put();
+}
+
+int dss_dispc_initialize_irq(void)
+{
+ int r;
+
+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
+ spin_lock_init(&dispc_compat.irq_stats_lock);
+ dispc_compat.irq_stats.last_reset = jiffies;
+ dss_debugfs_create_file("dispc_irq", dispc_dump_irqs);
+#endif
+
+ spin_lock_init(&dispc_compat.irq_lock);
+
+ memset(dispc_compat.registered_isr, 0,
+ sizeof(dispc_compat.registered_isr));
+
+ dispc_compat.irq_error_mask = DISPC_IRQ_MASK_ERROR;
+ if (dss_has_feature(FEAT_MGR_LCD2))
+ dispc_compat.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
+ if (dss_has_feature(FEAT_MGR_LCD3))
+ dispc_compat.irq_error_mask |= DISPC_IRQ_SYNC_LOST3;
+ if (dss_feat_get_num_ovls() > 3)
+ dispc_compat.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW;
+
+ /*
+ * there's SYNC_LOST_DIGIT waiting after enabling the DSS,
+ * so clear it
+ */
+ dispc_clear_irqstatus(dispc_read_irqstatus());
+
+ INIT_WORK(&dispc_compat.error_work, dispc_error_worker);
+
+ _omap_dispc_set_irqs();
+
+ r = dispc_request_irq(omap_dispc_irq_handler, &dispc_compat);
+ if (r) {
+ DSSERR("dispc_request_irq failed\n");
+ return r;
+ }
+
+ return 0;
+}
+
+void dss_dispc_uninitialize_irq(void)
+{
+ dispc_free_irq(&dispc_compat);
+}
+
+static void dispc_mgr_disable_isr(void *data, u32 mask)
+{
+ struct completion *compl = data;
+ complete(compl);
+}
+
+static void dispc_mgr_enable_lcd_out(enum omap_channel channel)
+{
+ dispc_mgr_enable(channel, true);
+}
+
+static void dispc_mgr_disable_lcd_out(enum omap_channel channel)
+{
+ DECLARE_COMPLETION_ONSTACK(framedone_compl);
+ int r;
+ u32 irq;
+
+ if (dispc_mgr_is_enabled(channel) == false)
+ return;
+
+ /*
+ * When we disable LCD output, we need to wait for FRAMEDONE to know
+ * that DISPC has finished with the LCD output.
+ */
+
+ irq = dispc_mgr_get_framedone_irq(channel);
+
+ r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
+ irq);
+ if (r)
+ DSSERR("failed to register FRAMEDONE isr\n");
+
+ dispc_mgr_enable(channel, false);
+
+ /* if we couldn't register for framedone, just sleep and exit */
+ if (r) {
+ msleep(100);
+ return;
+ }
+
+ if (!wait_for_completion_timeout(&framedone_compl,
+ msecs_to_jiffies(100)))
+ DSSERR("timeout waiting for FRAME DONE\n");
+
+ r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
+ irq);
+ if (r)
+ DSSERR("failed to unregister FRAMEDONE isr\n");
+}
+
+static void dispc_digit_out_enable_isr(void *data, u32 mask)
+{
+ struct completion *compl = data;
+
+ /* ignore any sync lost interrupts */
+ if (mask & (DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD))
+ complete(compl);
+}
+
+static void dispc_mgr_enable_digit_out(void)
+{
+ DECLARE_COMPLETION_ONSTACK(vsync_compl);
+ int r;
+ u32 irq_mask;
+
+ if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) == true)
+ return;
+
+ /*
+ * Digit output produces some sync lost interrupts during the first
+ * frame when enabling. Those need to be ignored, so we register for the
+ * sync lost irq to prevent the error handler from triggering.
+ */
+
+ irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT) |
+ dispc_mgr_get_sync_lost_irq(OMAP_DSS_CHANNEL_DIGIT);
+
+ r = omap_dispc_register_isr(dispc_digit_out_enable_isr, &vsync_compl,
+ irq_mask);
+ if (r) {
+ DSSERR("failed to register %x isr\n", irq_mask);
+ return;
+ }
+
+ dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, true);
+
+ /* wait for the first evsync */
+ if (!wait_for_completion_timeout(&vsync_compl, msecs_to_jiffies(100)))
+ DSSERR("timeout waiting for digit out to start\n");
+
+ r = omap_dispc_unregister_isr(dispc_digit_out_enable_isr, &vsync_compl,
+ irq_mask);
+ if (r)
+ DSSERR("failed to unregister %x isr\n", irq_mask);
+}
+
+static void dispc_mgr_disable_digit_out(void)
+{
+ DECLARE_COMPLETION_ONSTACK(framedone_compl);
+ int r, i;
+ u32 irq_mask;
+ int num_irqs;
+
+ if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) == false)
+ return;
+
+ /*
+ * When we disable the digit output, we need to wait for FRAMEDONE to
+ * know that DISPC has finished with the output.
+ */
+
+ irq_mask = dispc_mgr_get_framedone_irq(OMAP_DSS_CHANNEL_DIGIT);
+ num_irqs = 1;
+
+ if (!irq_mask) {
+ /*
+ * omap 2/3 don't have framedone irq for TV, so we need to use
+ * vsyncs for this.
+ */
+
+ irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT);
+ /*
+ * We need to wait for both even and odd vsyncs. Note that this
+ * is not totally reliable, as we could get a vsync interrupt
+ * before we disable the output, which leads to timeout in the
+ * wait_for_completion.
+ */
+ num_irqs = 2;
+ }
+
+ r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
+ irq_mask);
+ if (r)
+ DSSERR("failed to register %x isr\n", irq_mask);
+
+ dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, false);
+
+ /* if we couldn't register the irq, just sleep and exit */
+ if (r) {
+ msleep(100);
+ return;
+ }
+
+ for (i = 0; i < num_irqs; ++i) {
+ if (!wait_for_completion_timeout(&framedone_compl,
+ msecs_to_jiffies(100)))
+ DSSERR("timeout waiting for digit out to stop\n");
+ }
+
+ r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
+ irq_mask);
+ if (r)
+ DSSERR("failed to unregister %x isr\n", irq_mask);
+}
+
+void dispc_mgr_enable_sync(enum omap_channel channel)
+{
+ if (dss_mgr_is_lcd(channel))
+ dispc_mgr_enable_lcd_out(channel);
+ else if (channel == OMAP_DSS_CHANNEL_DIGIT)
+ dispc_mgr_enable_digit_out();
+ else
+ WARN_ON(1);
+}
+
+void dispc_mgr_disable_sync(enum omap_channel channel)
+{
+ if (dss_mgr_is_lcd(channel))
+ dispc_mgr_disable_lcd_out(channel);
+ else if (channel == OMAP_DSS_CHANNEL_DIGIT)
+ dispc_mgr_disable_digit_out();
+ else
+ WARN_ON(1);
+}
+
+int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
+ unsigned long timeout)
+{
+ void dispc_irq_wait_handler(void *data, u32 mask)
+ {
+ complete((struct completion *)data);
+ }
+
+ int r;
+ DECLARE_COMPLETION_ONSTACK(completion);
+
+ r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion,
+ irqmask);
+
+ if (r)
+ return r;
+
+ timeout = wait_for_completion_interruptible_timeout(&completion,
+ timeout);
+
+ omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
+
+ if (timeout == 0)
+ return -ETIMEDOUT;
+
+ if (timeout == -ERESTARTSYS)
+ return -ERESTARTSYS;
+
+ return 0;
+}
diff --git a/drivers/video/omap2/dss/dispc-compat.h b/drivers/video/omap2/dss/dispc-compat.h
new file mode 100644
index 0000000..14a69b3
--- /dev/null
+++ b/drivers/video/omap2/dss/dispc-compat.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 Texas Instruments
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __OMAP2_DSS_DISPC_COMPAT_H
+#define __OMAP2_DSS_DISPC_COMPAT_H
+
+void dispc_mgr_enable_sync(enum omap_channel channel);
+void dispc_mgr_disable_sync(enum omap_channel channel);
+
+int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
+ unsigned long timeout);
+
+int dss_dispc_initialize_irq(void);
+void dss_dispc_uninitialize_irq(void);
+
+#endif
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index b43477a..05ff2b9 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -33,11 +33,9 @@
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/hardirq.h>
-#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
-
-#include <plat/cpu.h>
+#include <linux/sizes.h>
#include <video/omapdss.h>
@@ -48,21 +46,6 @@
/* DISPC */
#define DISPC_SZ_REGS SZ_4K
-#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
- DISPC_IRQ_OCP_ERR | \
- DISPC_IRQ_VID1_FIFO_UNDERFLOW | \
- DISPC_IRQ_VID2_FIFO_UNDERFLOW | \
- DISPC_IRQ_SYNC_LOST | \
- DISPC_IRQ_SYNC_LOST_DIGIT)
-
-#define DISPC_MAX_NR_ISRS 8
-
-struct omap_dispc_isr_data {
- omap_dispc_isr_t isr;
- void *arg;
- u32 mask;
-};
-
enum omap_burst_size {
BURST_SIZE_X2 = 0,
BURST_SIZE_X4 = 1,
@@ -75,12 +58,6 @@ enum omap_burst_size {
#define REG_FLD_MOD(idx, val, start, end) \
dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end))
-struct dispc_irq_stats {
- unsigned long last_reset;
- unsigned irq_count;
- unsigned irqs[32];
-};
-
struct dispc_features {
u8 sw_start;
u8 fp_start;
@@ -88,19 +65,26 @@ struct dispc_features {
u16 sw_max;
u16 vp_max;
u16 hp_max;
- int (*calc_scaling) (enum omap_plane plane,
+ u8 mgr_width_start;
+ u8 mgr_height_start;
+ u16 mgr_width_max;
+ u16 mgr_height_max;
+ int (*calc_scaling) (unsigned long pclk, unsigned long lclk,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
u16 pos_x, unsigned long *core_clk, bool mem_to_mem);
- unsigned long (*calc_core_clk) (enum omap_plane plane,
+ unsigned long (*calc_core_clk) (unsigned long pclk,
u16 width, u16 height, u16 out_width, u16 out_height,
bool mem_to_mem);
u8 num_fifos;
/* swap GFX & WB fifos */
bool gfx_fifo_workaround:1;
+
+ /* no DISPC_IRQ_FRAMEDONETV on this SoC */
+ bool no_framedone_tv:1;
};
#define DISPC_MAX_NR_FIFOS 5
@@ -112,27 +96,15 @@ static struct {
int ctx_loss_cnt;
int irq;
- struct clk *dss_clk;
u32 fifo_size[DISPC_MAX_NR_FIFOS];
/* maps which plane is using a fifo. fifo-id -> plane-id */
int fifo_assignment[DISPC_MAX_NR_FIFOS];
- spinlock_t irq_lock;
- u32 irq_error_mask;
- struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
- u32 error_irqs;
- struct work_struct error_work;
-
bool ctx_valid;
u32 ctx[DISPC_SZ_REGS / sizeof(u32)];
const struct dispc_features *feat;
-
-#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
- spinlock_t irq_stats_lock;
- struct dispc_irq_stats irq_stats;
-#endif
} dispc;
enum omap_color_component {
@@ -188,7 +160,7 @@ static const struct {
[OMAP_DSS_CHANNEL_DIGIT] = {
.name = "DIGIT",
.vsync_irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN,
- .framedone_irq = 0,
+ .framedone_irq = DISPC_IRQ_FRAMEDONETV,
.sync_lost_irq = DISPC_IRQ_SYNC_LOST_DIGIT,
.reg_desc = {
[DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL, 1, 1 },
@@ -243,7 +215,6 @@ struct color_conv_coef {
int full_range;
};
-static void _omap_dispc_set_irqs(void);
static unsigned long dispc_plane_pclk_rate(enum omap_plane plane);
static unsigned long dispc_plane_lclk_rate(enum omap_plane plane);
@@ -376,7 +347,7 @@ static void dispc_save_context(void)
if (dss_has_feature(FEAT_CORE_CLK_DIV))
SR(DIVISOR);
- dispc.ctx_loss_cnt = dss_get_ctx_loss_count(&dispc.pdev->dev);
+ dispc.ctx_loss_cnt = dss_get_ctx_loss_count();
dispc.ctx_valid = true;
DSSDBG("context saved, ctx_loss_count %d\n", dispc.ctx_loss_cnt);
@@ -391,7 +362,7 @@ static void dispc_restore_context(void)
if (!dispc.ctx_valid)
return;
- ctx = dss_get_ctx_loss_count(&dispc.pdev->dev);
+ ctx = dss_get_ctx_loss_count();
if (ctx >= 0 && ctx == dispc.ctx_loss_cnt)
return;
@@ -498,7 +469,7 @@ static void dispc_restore_context(void)
if (dss_has_feature(FEAT_MGR_LCD3))
RR(CONTROL3);
/* clear spurious SYNC_LOST_DIGIT interrupts */
- dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
+ dispc_clear_irqstatus(DISPC_IRQ_SYNC_LOST_DIGIT);
/*
* enable last so IRQs won't trigger before
@@ -522,6 +493,7 @@ int dispc_runtime_get(void)
WARN_ON(r < 0);
return r < 0 ? r : 0;
}
+EXPORT_SYMBOL(dispc_runtime_get);
void dispc_runtime_put(void)
{
@@ -532,16 +504,28 @@ void dispc_runtime_put(void)
r = pm_runtime_put_sync(&dispc.pdev->dev);
WARN_ON(r < 0 && r != -ENOSYS);
}
+EXPORT_SYMBOL(dispc_runtime_put);
u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
{
return mgr_desc[channel].vsync_irq;
}
+EXPORT_SYMBOL(dispc_mgr_get_vsync_irq);
u32 dispc_mgr_get_framedone_irq(enum omap_channel channel)
{
+ if (channel == OMAP_DSS_CHANNEL_DIGIT && dispc.feat->no_framedone_tv)
+ return 0;
+
return mgr_desc[channel].framedone_irq;
}
+EXPORT_SYMBOL(dispc_mgr_get_framedone_irq);
+
+u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel)
+{
+ return mgr_desc[channel].sync_lost_irq;
+}
+EXPORT_SYMBOL(dispc_mgr_get_sync_lost_irq);
u32 dispc_wb_get_framedone_irq(void)
{
@@ -552,28 +536,18 @@ bool dispc_mgr_go_busy(enum omap_channel channel)
{
return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
}
+EXPORT_SYMBOL(dispc_mgr_go_busy);
void dispc_mgr_go(enum omap_channel channel)
{
- bool enable_bit, go_bit;
-
- /* if the channel is not enabled, we don't need GO */
- enable_bit = mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE) == 1;
-
- if (!enable_bit)
- return;
-
- go_bit = mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
-
- if (go_bit) {
- DSSERR("GO bit not down for channel %d\n", channel);
- return;
- }
+ WARN_ON(dispc_mgr_is_enabled(channel) == false);
+ WARN_ON(dispc_mgr_go_busy(channel));
DSSDBG("GO %s\n", mgr_desc[channel].name);
mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1);
}
+EXPORT_SYMBOL(dispc_mgr_go);
bool dispc_wb_go_busy(void)
{
@@ -977,6 +951,7 @@ void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel)
}
dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
}
+EXPORT_SYMBOL(dispc_ovl_set_channel_out);
static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
{
@@ -1042,7 +1017,7 @@ static void dispc_configure_burst_sizes(void)
const int burst_size = BURST_SIZE_X8;
/* Configure burst size always to maximum size */
- for (i = 0; i < omap_dss_get_num_overlays(); ++i)
+ for (i = 0; i < dss_feat_get_num_ovls(); ++i)
dispc_ovl_set_burst_size(i, burst_size);
}
@@ -1076,7 +1051,7 @@ static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
}
static void dispc_mgr_set_cpr_coef(enum omap_channel channel,
- struct omap_dss_cpr_coefs *coefs)
+ const struct omap_dss_cpr_coefs *coefs)
{
u32 coef_r, coef_g, coef_b;
@@ -1124,7 +1099,9 @@ static void dispc_mgr_set_size(enum omap_channel channel, u16 width,
{
u32 val;
- val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
+ val = FLD_VAL(height - 1, dispc.feat->mgr_height_start, 16) |
+ FLD_VAL(width - 1, dispc.feat->mgr_width_start, 0);
+
dispc_write_reg(DISPC_SIZE_MGR(channel), val);
}
@@ -1246,7 +1223,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
if (use_fifomerge) {
total_fifo_size = 0;
- for (i = 0; i < omap_dss_get_num_overlays(); ++i)
+ for (i = 0; i < dss_feat_get_num_ovls(); ++i)
total_fifo_size += dispc_ovl_get_fifo_size(i);
} else {
total_fifo_size = ovl_fifo_size;
@@ -1991,16 +1968,14 @@ static void calc_tiler_rotation_offset(u16 screen_width, u16 width,
* This function is used to avoid synclosts in OMAP3, because of some
* undocumented horizontal position and timing related limitations.
*/
-static int check_horiz_timing_omap3(enum omap_plane plane,
+static int check_horiz_timing_omap3(unsigned long pclk, unsigned long lclk,
const struct omap_video_timings *t, u16 pos_x,
u16 width, u16 height, u16 out_width, u16 out_height)
{
- int DS = DIV_ROUND_UP(height, out_height);
+ const int ds = DIV_ROUND_UP(height, out_height);
unsigned long nonactive;
static const u8 limits[3] = { 8, 10, 20 };
u64 val, blank;
- unsigned long pclk = dispc_plane_pclk_rate(plane);
- unsigned long lclk = dispc_plane_lclk_rate(plane);
int i;
nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width;
@@ -2022,8 +1997,8 @@ static int check_horiz_timing_omap3(enum omap_plane plane,
*/
val = div_u64((u64)(nonactive - pos_x) * lclk, pclk);
DSSDBG("(nonactive - pos_x) * pcd = %llu max(0, DS - 2) * width = %d\n",
- val, max(0, DS - 2) * width);
- if (val < max(0, DS - 2) * width)
+ val, max(0, ds - 2) * width);
+ if (val < max(0, ds - 2) * width)
return -EINVAL;
/*
@@ -2033,21 +2008,20 @@ static int check_horiz_timing_omap3(enum omap_plane plane,
*/
val = div_u64((u64)nonactive * lclk, pclk);
DSSDBG("nonactive * pcd = %llu, max(0, DS - 1) * width = %d\n",
- val, max(0, DS - 1) * width);
- if (val < max(0, DS - 1) * width)
+ val, max(0, ds - 1) * width);
+ if (val < max(0, ds - 1) * width)
return -EINVAL;
return 0;
}
-static unsigned long calc_core_clk_five_taps(enum omap_plane plane,
+static unsigned long calc_core_clk_five_taps(unsigned long pclk,
const struct omap_video_timings *mgr_timings, u16 width,
u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode)
{
u32 core_clk = 0;
u64 tmp;
- unsigned long pclk = dispc_plane_pclk_rate(plane);
if (height <= out_height && width <= out_width)
return (unsigned long) pclk;
@@ -2081,22 +2055,19 @@ static unsigned long calc_core_clk_five_taps(enum omap_plane plane,
return core_clk;
}
-static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width,
+static unsigned long calc_core_clk_24xx(unsigned long pclk, u16 width,
u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
{
- unsigned long pclk = dispc_plane_pclk_rate(plane);
-
if (height > out_height && width > out_width)
return pclk * 4;
else
return pclk * 2;
}
-static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width,
+static unsigned long calc_core_clk_34xx(unsigned long pclk, u16 width,
u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
{
unsigned int hf, vf;
- unsigned long pclk = dispc_plane_pclk_rate(plane);
/*
* FIXME how to determine the 'A' factor
@@ -2119,11 +2090,9 @@ static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width,
return pclk * vf * hf;
}
-static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width,
+static unsigned long calc_core_clk_44xx(unsigned long pclk, u16 width,
u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
{
- unsigned long pclk;
-
/*
* If the overlay/writeback is in mem to mem mode, there are no
* downscaling limitations with respect to pixel clock, return 1 as
@@ -2133,15 +2102,13 @@ static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width,
if (mem_to_mem)
return 1;
- pclk = dispc_plane_pclk_rate(plane);
-
if (width > out_width)
return DIV_ROUND_UP(pclk, out_width) * width;
else
return pclk;
}
-static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane,
+static int dispc_ovl_calc_scaling_24xx(unsigned long pclk, unsigned long lclk,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
@@ -2159,7 +2126,7 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane,
do {
in_height = DIV_ROUND_UP(height, *decim_y);
in_width = DIV_ROUND_UP(width, *decim_x);
- *core_clk = dispc.feat->calc_core_clk(plane, in_width,
+ *core_clk = dispc.feat->calc_core_clk(pclk, in_width,
in_height, out_width, out_height, mem_to_mem);
error = (in_width > maxsinglelinewidth || !*core_clk ||
*core_clk > dispc_core_clk_rate());
@@ -2182,7 +2149,7 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane,
return 0;
}
-static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
+static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
@@ -2198,10 +2165,10 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
do {
in_height = DIV_ROUND_UP(height, *decim_y);
in_width = DIV_ROUND_UP(width, *decim_x);
- *core_clk = calc_core_clk_five_taps(plane, mgr_timings,
+ *core_clk = calc_core_clk_five_taps(pclk, mgr_timings,
in_width, in_height, out_width, out_height, color_mode);
- error = check_horiz_timing_omap3(plane, mgr_timings,
+ error = check_horiz_timing_omap3(pclk, lclk, mgr_timings,
pos_x, in_width, in_height, out_width,
out_height);
@@ -2210,7 +2177,7 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
in_height < out_height * 2)
*five_taps = false;
if (!*five_taps)
- *core_clk = dispc.feat->calc_core_clk(plane, in_width,
+ *core_clk = dispc.feat->calc_core_clk(pclk, in_width,
in_height, out_width, out_height,
mem_to_mem);
@@ -2229,8 +2196,8 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
}
} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
- if (check_horiz_timing_omap3(plane, mgr_timings, pos_x, width, height,
- out_width, out_height)){
+ if (check_horiz_timing_omap3(pclk, lclk, mgr_timings, pos_x, width,
+ height, out_width, out_height)){
DSSERR("horizontal timing too tight\n");
return -EINVAL;
}
@@ -2248,7 +2215,7 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
return 0;
}
-static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane,
+static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
@@ -2260,14 +2227,14 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane,
u16 in_height = DIV_ROUND_UP(height, *decim_y);
const int maxsinglelinewidth =
dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
- unsigned long pclk = dispc_plane_pclk_rate(plane);
const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
- if (mem_to_mem)
- in_width_max = DIV_ROUND_UP(out_width, maxdownscale);
- else
+ if (mem_to_mem) {
+ in_width_max = out_width * maxdownscale;
+ } else {
in_width_max = dispc_core_clk_rate() /
DIV_ROUND_UP(pclk, out_width);
+ }
*decim_x = DIV_ROUND_UP(width, in_width_max);
@@ -2285,12 +2252,12 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane,
return -EINVAL;
}
- *core_clk = dispc.feat->calc_core_clk(plane, in_width, in_height,
+ *core_clk = dispc.feat->calc_core_clk(pclk, in_width, in_height,
out_width, out_height, mem_to_mem);
return 0;
}
-static int dispc_ovl_calc_scaling(enum omap_plane plane,
+static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
enum omap_overlay_caps caps,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
@@ -2309,9 +2276,14 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
if ((caps & OMAP_DSS_OVL_CAP_SCALE) == 0)
return -EINVAL;
- *x_predecim = max_decim_limit;
- *y_predecim = (rotation_type == OMAP_DSS_ROT_TILER &&
- dss_has_feature(FEAT_BURST_2D)) ? 2 : max_decim_limit;
+ if (mem_to_mem) {
+ *x_predecim = *y_predecim = 1;
+ } else {
+ *x_predecim = max_decim_limit;
+ *y_predecim = (rotation_type == OMAP_DSS_ROT_TILER &&
+ dss_has_feature(FEAT_BURST_2D)) ?
+ 2 : max_decim_limit;
+ }
if (color_mode == OMAP_DSS_COLOR_CLUT1 ||
color_mode == OMAP_DSS_COLOR_CLUT2 ||
@@ -2332,7 +2304,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
if (decim_y > *y_predecim || out_height > height * 8)
return -EINVAL;
- ret = dispc.feat->calc_scaling(plane, mgr_timings, width, height,
+ ret = dispc.feat->calc_scaling(pclk, lclk, mgr_timings, width, height,
out_width, out_height, color_mode, five_taps,
x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk,
mem_to_mem);
@@ -2355,6 +2327,47 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
return 0;
}
+int dispc_ovl_check(enum omap_plane plane, enum omap_channel channel,
+ const struct omap_overlay_info *oi,
+ const struct omap_video_timings *timings,
+ int *x_predecim, int *y_predecim)
+{
+ enum omap_overlay_caps caps = dss_feat_get_overlay_caps(plane);
+ bool five_taps = true;
+ bool fieldmode = 0;
+ u16 in_height = oi->height;
+ u16 in_width = oi->width;
+ bool ilace = timings->interlace;
+ u16 out_width, out_height;
+ int pos_x = oi->pos_x;
+ unsigned long pclk = dispc_mgr_pclk_rate(channel);
+ unsigned long lclk = dispc_mgr_lclk_rate(channel);
+
+ out_width = oi->out_width == 0 ? oi->width : oi->out_width;
+ out_height = oi->out_height == 0 ? oi->height : oi->out_height;
+
+ if (ilace && oi->height == out_height)
+ fieldmode = 1;
+
+ if (ilace) {
+ if (fieldmode)
+ in_height /= 2;
+ out_height /= 2;
+
+ DSSDBG("adjusting for ilace: height %d, out_height %d\n",
+ in_height, out_height);
+ }
+
+ if (!dss_feat_color_mode_supported(plane, oi->color_mode))
+ return -EINVAL;
+
+ return dispc_ovl_calc_scaling(pclk, lclk, caps, timings, in_width,
+ in_height, out_width, out_height, oi->color_mode,
+ &five_taps, x_predecim, y_predecim, pos_x,
+ oi->rotation_type, false);
+}
+EXPORT_SYMBOL(dispc_ovl_check);
+
static int dispc_ovl_setup_common(enum omap_plane plane,
enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr,
u16 screen_width, int pos_x, int pos_y, u16 width, u16 height,
@@ -2370,12 +2383,14 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
unsigned offset0, offset1;
s32 row_inc;
s32 pix_inc;
- u16 frame_height = height;
+ u16 frame_width, frame_height;
unsigned int field_offset = 0;
u16 in_height = height;
u16 in_width = width;
int x_predecim = 1, y_predecim = 1;
bool ilace = mgr_timings->interlace;
+ unsigned long pclk = dispc_plane_pclk_rate(plane);
+ unsigned long lclk = dispc_plane_lclk_rate(plane);
if (paddr == 0)
return -EINVAL;
@@ -2400,7 +2415,7 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
if (!dss_feat_color_mode_supported(plane, color_mode))
return -EINVAL;
- r = dispc_ovl_calc_scaling(plane, caps, mgr_timings, in_width,
+ r = dispc_ovl_calc_scaling(pclk, lclk, caps, mgr_timings, in_width,
in_height, out_width, out_height, color_mode,
&five_taps, &x_predecim, &y_predecim, pos_x,
rotation_type, mem_to_mem);
@@ -2438,20 +2453,28 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
row_inc = 0;
pix_inc = 0;
+ if (plane == OMAP_DSS_WB) {
+ frame_width = out_width;
+ frame_height = out_height;
+ } else {
+ frame_width = in_width;
+ frame_height = height;
+ }
+
if (rotation_type == OMAP_DSS_ROT_TILER)
- calc_tiler_rotation_offset(screen_width, in_width,
+ calc_tiler_rotation_offset(screen_width, frame_width,
color_mode, fieldmode, field_offset,
&offset0, &offset1, &row_inc, &pix_inc,
x_predecim, y_predecim);
else if (rotation_type == OMAP_DSS_ROT_DMA)
- calc_dma_rotation_offset(rotation, mirror,
- screen_width, in_width, frame_height,
+ calc_dma_rotation_offset(rotation, mirror, screen_width,
+ frame_width, frame_height,
color_mode, fieldmode, field_offset,
&offset0, &offset1, &row_inc, &pix_inc,
x_predecim, y_predecim);
else
calc_vrfb_rotation_offset(rotation, mirror,
- screen_width, in_width, frame_height,
+ screen_width, frame_width, frame_height,
color_mode, fieldmode, field_offset,
&offset0, &offset1, &row_inc, &pix_inc,
x_predecim, y_predecim);
@@ -2505,7 +2528,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
bool mem_to_mem)
{
int r;
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+ enum omap_overlay_caps caps = dss_feat_get_overlay_caps(plane);
enum omap_channel channel;
channel = dispc_ovl_get_channel_out(plane);
@@ -2516,7 +2539,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height,
oi->color_mode, oi->rotation, oi->mirror, channel, replication);
- r = dispc_ovl_setup_common(plane, ovl->caps, oi->paddr, oi->p_uv_addr,
+ r = dispc_ovl_setup_common(plane, caps, oi->paddr, oi->p_uv_addr,
oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
oi->mirror, oi->zorder, oi->pre_mult_alpha, oi->global_alpha,
@@ -2524,6 +2547,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
return r;
}
+EXPORT_SYMBOL(dispc_ovl_setup);
int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
bool mem_to_mem, const struct omap_video_timings *mgr_timings)
@@ -2584,192 +2608,39 @@ int dispc_ovl_enable(enum omap_plane plane, bool enable)
return 0;
}
+EXPORT_SYMBOL(dispc_ovl_enable);
-static void dispc_disable_isr(void *data, u32 mask)
+bool dispc_ovl_enabled(enum omap_plane plane)
{
- struct completion *compl = data;
- complete(compl);
+ return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
}
+EXPORT_SYMBOL(dispc_ovl_enabled);
-static void _enable_lcd_out(enum omap_channel channel, bool enable)
+void dispc_mgr_enable(enum omap_channel channel, bool enable)
{
mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable);
/* flush posted write */
mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
}
-
-static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
-{
- struct completion frame_done_completion;
- bool is_on;
- int r;
- u32 irq;
-
- /* When we disable LCD output, we need to wait until frame is done.
- * Otherwise the DSS is still working, and turning off the clocks
- * prevents DSS from going to OFF mode */
- is_on = mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
-
- irq = mgr_desc[channel].framedone_irq;
-
- if (!enable && is_on) {
- init_completion(&frame_done_completion);
-
- r = omap_dispc_register_isr(dispc_disable_isr,
- &frame_done_completion, irq);
-
- if (r)
- DSSERR("failed to register FRAMEDONE isr\n");
- }
-
- _enable_lcd_out(channel, enable);
-
- if (!enable && is_on) {
- if (!wait_for_completion_timeout(&frame_done_completion,
- msecs_to_jiffies(100)))
- DSSERR("timeout waiting for FRAME DONE\n");
-
- r = omap_dispc_unregister_isr(dispc_disable_isr,
- &frame_done_completion, irq);
-
- if (r)
- DSSERR("failed to unregister FRAMEDONE isr\n");
- }
-}
-
-static void _enable_digit_out(bool enable)
-{
- REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1);
- /* flush posted write */
- dispc_read_reg(DISPC_CONTROL);
-}
-
-static void dispc_mgr_enable_digit_out(bool enable)
-{
- struct completion frame_done_completion;
- enum dss_hdmi_venc_clk_source_select src;
- int r, i;
- u32 irq_mask;
- int num_irqs;
-
- if (REG_GET(DISPC_CONTROL, 1, 1) == enable)
- return;
-
- src = dss_get_hdmi_venc_clk_source();
-
- if (enable) {
- unsigned long flags;
- /* When we enable digit output, we'll get an extra digit
- * sync lost interrupt, that we need to ignore */
- spin_lock_irqsave(&dispc.irq_lock, flags);
- dispc.irq_error_mask &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
- _omap_dispc_set_irqs();
- spin_unlock_irqrestore(&dispc.irq_lock, flags);
- }
-
- /* When we disable digit output, we need to wait until fields are done.
- * Otherwise the DSS is still working, and turning off the clocks
- * prevents DSS from going to OFF mode. And when enabling, we need to
- * wait for the extra sync losts */
- init_completion(&frame_done_completion);
-
- if (src == DSS_HDMI_M_PCLK && enable == false) {
- irq_mask = DISPC_IRQ_FRAMEDONETV;
- num_irqs = 1;
- } else {
- irq_mask = DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD;
- /* XXX I understand from TRM that we should only wait for the
- * current field to complete. But it seems we have to wait for
- * both fields */
- num_irqs = 2;
- }
-
- r = omap_dispc_register_isr(dispc_disable_isr, &frame_done_completion,
- irq_mask);
- if (r)
- DSSERR("failed to register %x isr\n", irq_mask);
-
- _enable_digit_out(enable);
-
- for (i = 0; i < num_irqs; ++i) {
- if (!wait_for_completion_timeout(&frame_done_completion,
- msecs_to_jiffies(100)))
- DSSERR("timeout waiting for digit out to %s\n",
- enable ? "start" : "stop");
- }
-
- r = omap_dispc_unregister_isr(dispc_disable_isr, &frame_done_completion,
- irq_mask);
- if (r)
- DSSERR("failed to unregister %x isr\n", irq_mask);
-
- if (enable) {
- unsigned long flags;
- spin_lock_irqsave(&dispc.irq_lock, flags);
- dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST_DIGIT;
- dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
- _omap_dispc_set_irqs();
- spin_unlock_irqrestore(&dispc.irq_lock, flags);
- }
-}
+EXPORT_SYMBOL(dispc_mgr_enable);
bool dispc_mgr_is_enabled(enum omap_channel channel)
{
return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
}
-
-void dispc_mgr_enable(enum omap_channel channel, bool enable)
-{
- if (dss_mgr_is_lcd(channel))
- dispc_mgr_enable_lcd_out(channel, enable);
- else if (channel == OMAP_DSS_CHANNEL_DIGIT)
- dispc_mgr_enable_digit_out(enable);
- else
- BUG();
-}
+EXPORT_SYMBOL(dispc_mgr_is_enabled);
void dispc_wb_enable(bool enable)
{
- enum omap_plane plane = OMAP_DSS_WB;
- struct completion frame_done_completion;
- bool is_on;
- int r;
- u32 irq;
-
- is_on = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
- irq = DISPC_IRQ_FRAMEDONEWB;
-
- if (!enable && is_on) {
- init_completion(&frame_done_completion);
-
- r = omap_dispc_register_isr(dispc_disable_isr,
- &frame_done_completion, irq);
- if (r)
- DSSERR("failed to register FRAMEDONEWB isr\n");
- }
-
- REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0);
-
- if (!enable && is_on) {
- if (!wait_for_completion_timeout(&frame_done_completion,
- msecs_to_jiffies(100)))
- DSSERR("timeout waiting for FRAMEDONEWB\n");
-
- r = omap_dispc_unregister_isr(dispc_disable_isr,
- &frame_done_completion, irq);
- if (r)
- DSSERR("failed to unregister FRAMEDONEWB isr\n");
- }
+ dispc_ovl_enable(OMAP_DSS_WB, enable);
}
bool dispc_wb_is_enabled(void)
{
- enum omap_plane plane = OMAP_DSS_WB;
-
- return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
+ return dispc_ovl_enabled(OMAP_DSS_WB);
}
-void dispc_lcd_enable_signal_polarity(bool act_high)
+static void dispc_lcd_enable_signal_polarity(bool act_high)
{
if (!dss_has_feature(FEAT_LCDENABLEPOL))
return;
@@ -2793,13 +2664,13 @@ void dispc_pck_free_enable(bool enable)
REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
}
-void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable)
+static void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable)
{
mgr_fld_write(channel, DISPC_MGR_FLD_FIFOHANDCHECK, enable);
}
-void dispc_mgr_set_lcd_type_tft(enum omap_channel channel)
+static void dispc_mgr_set_lcd_type_tft(enum omap_channel channel)
{
mgr_fld_write(channel, DISPC_MGR_FLD_STNTFT, 1);
}
@@ -2842,7 +2713,7 @@ static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch,
}
void dispc_mgr_setup(enum omap_channel channel,
- struct omap_overlay_manager_info *info)
+ const struct omap_overlay_manager_info *info)
{
dispc_mgr_set_default_color(channel, info->default_color);
dispc_mgr_set_trans_key(channel, info->trans_key_type, info->trans_key);
@@ -2854,8 +2725,9 @@ void dispc_mgr_setup(enum omap_channel channel,
dispc_mgr_set_cpr_coef(channel, &info->cpr_coefs);
}
}
+EXPORT_SYMBOL(dispc_mgr_setup);
-void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
+static void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
{
int code;
@@ -2880,7 +2752,7 @@ void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
mgr_fld_write(channel, DISPC_MGR_FLD_TFTDATALINES, code);
}
-void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
+static void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
{
u32 l;
int gpout0, gpout1;
@@ -2909,15 +2781,33 @@ void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
dispc_write_reg(DISPC_CONTROL, l);
}
-void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable)
+static void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable)
{
mgr_fld_write(channel, DISPC_MGR_FLD_STALLMODE, enable);
}
+void dispc_mgr_set_lcd_config(enum omap_channel channel,
+ const struct dss_lcd_mgr_config *config)
+{
+ dispc_mgr_set_io_pad_mode(config->io_pad_mode);
+
+ dispc_mgr_enable_stallmode(channel, config->stallmode);
+ dispc_mgr_enable_fifohandcheck(channel, config->fifohandcheck);
+
+ dispc_mgr_set_clock_div(channel, &config->clock_info);
+
+ dispc_mgr_set_tft_data_lines(channel, config->video_port_width);
+
+ dispc_lcd_enable_signal_polarity(config->lcden_sig_polarity);
+
+ dispc_mgr_set_lcd_type_tft(channel);
+}
+EXPORT_SYMBOL(dispc_mgr_set_lcd_config);
+
static bool _dispc_mgr_size_ok(u16 width, u16 height)
{
- return width <= dss_feat_get_param_max(FEAT_PARAM_MGR_WIDTH) &&
- height <= dss_feat_get_param_max(FEAT_PARAM_MGR_HEIGHT);
+ return width <= dispc.feat->mgr_width_max &&
+ height <= dispc.feat->mgr_height_max;
}
static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
@@ -3012,7 +2902,7 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
/* change name to mode? */
void dispc_mgr_set_timings(enum omap_channel channel,
- struct omap_video_timings *timings)
+ const struct omap_video_timings *timings)
{
unsigned xtot, ytot;
unsigned long ht, vt;
@@ -3051,6 +2941,7 @@ void dispc_mgr_set_timings(enum omap_channel channel,
dispc_mgr_set_size(channel, t.x_res, t.y_res);
}
+EXPORT_SYMBOL(dispc_mgr_set_timings);
static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
u16 pck_div)
@@ -3078,7 +2969,7 @@ unsigned long dispc_fclk_rate(void)
switch (dss_get_dispc_clk_source()) {
case OMAP_DSS_CLK_SRC_FCK:
- r = clk_get_rate(dispc.dss_clk);
+ r = dss_get_dispc_clk_rate();
break;
case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
dsidev = dsi_get_dsidev_from_id(0);
@@ -3103,28 +2994,32 @@ unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
unsigned long r;
u32 l;
- l = dispc_read_reg(DISPC_DIVISORo(channel));
+ if (dss_mgr_is_lcd(channel)) {
+ l = dispc_read_reg(DISPC_DIVISORo(channel));
- lcd = FLD_GET(l, 23, 16);
+ lcd = FLD_GET(l, 23, 16);
- switch (dss_get_lcd_clk_source(channel)) {
- case OMAP_DSS_CLK_SRC_FCK:
- r = clk_get_rate(dispc.dss_clk);
- break;
- case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
- dsidev = dsi_get_dsidev_from_id(0);
- r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
- break;
- case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
- dsidev = dsi_get_dsidev_from_id(1);
- r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
- break;
- default:
- BUG();
- return 0;
- }
+ switch (dss_get_lcd_clk_source(channel)) {
+ case OMAP_DSS_CLK_SRC_FCK:
+ r = dss_get_dispc_clk_rate();
+ break;
+ case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
+ dsidev = dsi_get_dsidev_from_id(0);
+ r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
+ break;
+ case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
+ dsidev = dsi_get_dsidev_from_id(1);
+ r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
+ break;
+ default:
+ BUG();
+ return 0;
+ }
- return r / lcd;
+ return r / lcd;
+ } else {
+ return dispc_fclk_rate();
+ }
}
unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
@@ -3174,21 +3069,28 @@ unsigned long dispc_core_clk_rate(void)
static unsigned long dispc_plane_pclk_rate(enum omap_plane plane)
{
- enum omap_channel channel = dispc_ovl_get_channel_out(plane);
+ enum omap_channel channel;
+
+ if (plane == OMAP_DSS_WB)
+ return 0;
+
+ channel = dispc_ovl_get_channel_out(plane);
return dispc_mgr_pclk_rate(channel);
}
static unsigned long dispc_plane_lclk_rate(enum omap_plane plane)
{
- enum omap_channel channel = dispc_ovl_get_channel_out(plane);
+ enum omap_channel channel;
- if (dss_mgr_is_lcd(channel))
- return dispc_mgr_lclk_rate(channel);
- else
- return dispc_fclk_rate();
+ if (plane == OMAP_DSS_WB)
+ return 0;
+
+ channel = dispc_ovl_get_channel_out(plane);
+ return dispc_mgr_lclk_rate(channel);
}
+
static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel)
{
int lcd, pcd;
@@ -3246,64 +3148,6 @@ void dispc_dump_clocks(struct seq_file *s)
dispc_runtime_put();
}
-#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
-void dispc_dump_irqs(struct seq_file *s)
-{
- unsigned long flags;
- struct dispc_irq_stats stats;
-
- spin_lock_irqsave(&dispc.irq_stats_lock, flags);
-
- stats = dispc.irq_stats;
- memset(&dispc.irq_stats, 0, sizeof(dispc.irq_stats));
- dispc.irq_stats.last_reset = jiffies;
-
- spin_unlock_irqrestore(&dispc.irq_stats_lock, flags);
-
- seq_printf(s, "period %u ms\n",
- jiffies_to_msecs(jiffies - stats.last_reset));
-
- seq_printf(s, "irqs %d\n", stats.irq_count);
-#define PIS(x) \
- seq_printf(s, "%-20s %10d\n", #x, stats.irqs[ffs(DISPC_IRQ_##x)-1]);
-
- PIS(FRAMEDONE);
- PIS(VSYNC);
- PIS(EVSYNC_EVEN);
- PIS(EVSYNC_ODD);
- PIS(ACBIAS_COUNT_STAT);
- PIS(PROG_LINE_NUM);
- PIS(GFX_FIFO_UNDERFLOW);
- PIS(GFX_END_WIN);
- PIS(PAL_GAMMA_MASK);
- PIS(OCP_ERR);
- PIS(VID1_FIFO_UNDERFLOW);
- PIS(VID1_END_WIN);
- PIS(VID2_FIFO_UNDERFLOW);
- PIS(VID2_END_WIN);
- if (dss_feat_get_num_ovls() > 3) {
- PIS(VID3_FIFO_UNDERFLOW);
- PIS(VID3_END_WIN);
- }
- PIS(SYNC_LOST);
- PIS(SYNC_LOST_DIGIT);
- PIS(WAKEUP);
- if (dss_has_feature(FEAT_MGR_LCD2)) {
- PIS(FRAMEDONE2);
- PIS(VSYNC2);
- PIS(ACBIAS_COUNT_STAT2);
- PIS(SYNC_LOST2);
- }
- if (dss_has_feature(FEAT_MGR_LCD3)) {
- PIS(FRAMEDONE3);
- PIS(VSYNC3);
- PIS(ACBIAS_COUNT_STAT3);
- PIS(SYNC_LOST3);
- }
-#undef PIS
-}
-#endif
-
static void dispc_dump_regs(struct seq_file *s)
{
int i, j;
@@ -3353,7 +3197,7 @@ static void dispc_dump_regs(struct seq_file *s)
#define DISPC_REG(i, name) name(i)
#define DUMPREG(i, r) seq_printf(s, "%s(%s)%*s %08x\n", #r, p_names[i], \
- 48 - strlen(#r) - strlen(p_names[i]), " ", \
+ (int)(48 - strlen(#r) - strlen(p_names[i])), " ", \
dispc_read_reg(DISPC_REG(i, r)))
p_names = mgr_names;
@@ -3430,7 +3274,7 @@ static void dispc_dump_regs(struct seq_file *s)
#define DISPC_REG(plane, name, i) name(plane, i)
#define DUMPREG(plane, name, i) \
seq_printf(s, "%s_%d(%s)%*s %08x\n", #name, i, p_names[plane], \
- 46 - strlen(#name) - strlen(p_names[plane]), " ", \
+ (int)(46 - strlen(#name) - strlen(p_names[plane])), " ", \
dispc_read_reg(DISPC_REG(plane, name, i)))
/* Video pipeline coefficient registers */
@@ -3533,7 +3377,7 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
}
void dispc_mgr_set_clock_div(enum omap_channel channel,
- struct dispc_clock_info *cinfo)
+ const struct dispc_clock_info *cinfo)
{
DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div);
DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div);
@@ -3557,403 +3401,34 @@ int dispc_mgr_get_clock_div(enum omap_channel channel,
return 0;
}
-/* dispc.irq_lock has to be locked by the caller */
-static void _omap_dispc_set_irqs(void)
+u32 dispc_read_irqstatus(void)
{
- u32 mask;
- u32 old_mask;
- int i;
- struct omap_dispc_isr_data *isr_data;
-
- mask = dispc.irq_error_mask;
-
- for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
- isr_data = &dispc.registered_isr[i];
-
- if (isr_data->isr == NULL)
- continue;
-
- mask |= isr_data->mask;
- }
-
- old_mask = dispc_read_reg(DISPC_IRQENABLE);
- /* clear the irqstatus for newly enabled irqs */
- dispc_write_reg(DISPC_IRQSTATUS, (mask ^ old_mask) & mask);
-
- dispc_write_reg(DISPC_IRQENABLE, mask);
-}
-
-int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
-{
- int i;
- int ret;
- unsigned long flags;
- struct omap_dispc_isr_data *isr_data;
-
- if (isr == NULL)
- return -EINVAL;
-
- spin_lock_irqsave(&dispc.irq_lock, flags);
-
- /* check for duplicate entry */
- for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
- isr_data = &dispc.registered_isr[i];
- if (isr_data->isr == isr && isr_data->arg == arg &&
- isr_data->mask == mask) {
- ret = -EINVAL;
- goto err;
- }
- }
-
- isr_data = NULL;
- ret = -EBUSY;
-
- for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
- isr_data = &dispc.registered_isr[i];
-
- if (isr_data->isr != NULL)
- continue;
-
- isr_data->isr = isr;
- isr_data->arg = arg;
- isr_data->mask = mask;
- ret = 0;
-
- break;
- }
-
- if (ret)
- goto err;
-
- _omap_dispc_set_irqs();
-
- spin_unlock_irqrestore(&dispc.irq_lock, flags);
-
- return 0;
-err:
- spin_unlock_irqrestore(&dispc.irq_lock, flags);
-
- return ret;
+ return dispc_read_reg(DISPC_IRQSTATUS);
}
-EXPORT_SYMBOL(omap_dispc_register_isr);
+EXPORT_SYMBOL(dispc_read_irqstatus);
-int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
+void dispc_clear_irqstatus(u32 mask)
{
- int i;
- unsigned long flags;
- int ret = -EINVAL;
- struct omap_dispc_isr_data *isr_data;
-
- spin_lock_irqsave(&dispc.irq_lock, flags);
-
- for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
- isr_data = &dispc.registered_isr[i];
- if (isr_data->isr != isr || isr_data->arg != arg ||
- isr_data->mask != mask)
- continue;
-
- /* found the correct isr */
-
- isr_data->isr = NULL;
- isr_data->arg = NULL;
- isr_data->mask = 0;
-
- ret = 0;
- break;
- }
-
- if (ret == 0)
- _omap_dispc_set_irqs();
-
- spin_unlock_irqrestore(&dispc.irq_lock, flags);
-
- return ret;
+ dispc_write_reg(DISPC_IRQSTATUS, mask);
}
-EXPORT_SYMBOL(omap_dispc_unregister_isr);
+EXPORT_SYMBOL(dispc_clear_irqstatus);
-#ifdef DEBUG
-static void print_irq_status(u32 status)
+u32 dispc_read_irqenable(void)
{
- if ((status & dispc.irq_error_mask) == 0)
- return;
-
- printk(KERN_DEBUG "DISPC IRQ: 0x%x: ", status);
-
-#define PIS(x) \
- if (status & DISPC_IRQ_##x) \
- printk(#x " ");
- PIS(GFX_FIFO_UNDERFLOW);
- PIS(OCP_ERR);
- PIS(VID1_FIFO_UNDERFLOW);
- PIS(VID2_FIFO_UNDERFLOW);
- if (dss_feat_get_num_ovls() > 3)
- PIS(VID3_FIFO_UNDERFLOW);
- PIS(SYNC_LOST);
- PIS(SYNC_LOST_DIGIT);
- if (dss_has_feature(FEAT_MGR_LCD2))
- PIS(SYNC_LOST2);
- if (dss_has_feature(FEAT_MGR_LCD3))
- PIS(SYNC_LOST3);
-#undef PIS
-
- printk("\n");
+ return dispc_read_reg(DISPC_IRQENABLE);
}
-#endif
+EXPORT_SYMBOL(dispc_read_irqenable);
-/* Called from dss.c. Note that we don't touch clocks here,
- * but we presume they are on because we got an IRQ. However,
- * an irq handler may turn the clocks off, so we may not have
- * clock later in the function. */
-static irqreturn_t omap_dispc_irq_handler(int irq, void *arg)
+void dispc_write_irqenable(u32 mask)
{
- int i;
- u32 irqstatus, irqenable;
- u32 handledirqs = 0;
- u32 unhandled_errors;
- struct omap_dispc_isr_data *isr_data;
- struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
-
- spin_lock(&dispc.irq_lock);
-
- irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
- irqenable = dispc_read_reg(DISPC_IRQENABLE);
-
- /* IRQ is not for us */
- if (!(irqstatus & irqenable)) {
- spin_unlock(&dispc.irq_lock);
- return IRQ_NONE;
- }
-
-#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
- spin_lock(&dispc.irq_stats_lock);
- dispc.irq_stats.irq_count++;
- dss_collect_irq_stats(irqstatus, dispc.irq_stats.irqs);
- spin_unlock(&dispc.irq_stats_lock);
-#endif
-
-#ifdef DEBUG
- if (dss_debug)
- print_irq_status(irqstatus);
-#endif
- /* Ack the interrupt. Do it here before clocks are possibly turned
- * off */
- dispc_write_reg(DISPC_IRQSTATUS, irqstatus);
- /* flush posted write */
- dispc_read_reg(DISPC_IRQSTATUS);
-
- /* make a copy and unlock, so that isrs can unregister
- * themselves */
- memcpy(registered_isr, dispc.registered_isr,
- sizeof(registered_isr));
-
- spin_unlock(&dispc.irq_lock);
-
- for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
- isr_data = &registered_isr[i];
-
- if (!isr_data->isr)
- continue;
-
- if (isr_data->mask & irqstatus) {
- isr_data->isr(isr_data->arg, irqstatus);
- handledirqs |= isr_data->mask;
- }
- }
-
- spin_lock(&dispc.irq_lock);
-
- unhandled_errors = irqstatus & ~handledirqs & dispc.irq_error_mask;
-
- if (unhandled_errors) {
- dispc.error_irqs |= unhandled_errors;
-
- dispc.irq_error_mask &= ~unhandled_errors;
- _omap_dispc_set_irqs();
-
- schedule_work(&dispc.error_work);
- }
-
- spin_unlock(&dispc.irq_lock);
-
- return IRQ_HANDLED;
-}
-
-static void dispc_error_worker(struct work_struct *work)
-{
- int i;
- u32 errors;
- unsigned long flags;
- static const unsigned fifo_underflow_bits[] = {
- DISPC_IRQ_GFX_FIFO_UNDERFLOW,
- DISPC_IRQ_VID1_FIFO_UNDERFLOW,
- DISPC_IRQ_VID2_FIFO_UNDERFLOW,
- DISPC_IRQ_VID3_FIFO_UNDERFLOW,
- };
-
- spin_lock_irqsave(&dispc.irq_lock, flags);
- errors = dispc.error_irqs;
- dispc.error_irqs = 0;
- spin_unlock_irqrestore(&dispc.irq_lock, flags);
-
- dispc_runtime_get();
-
- for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
- struct omap_overlay *ovl;
- unsigned bit;
-
- ovl = omap_dss_get_overlay(i);
- bit = fifo_underflow_bits[i];
-
- if (bit & errors) {
- DSSERR("FIFO UNDERFLOW on %s, disabling the overlay\n",
- ovl->name);
- dispc_ovl_enable(ovl->id, false);
- dispc_mgr_go(ovl->manager->id);
- msleep(50);
- }
- }
-
- for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
- struct omap_overlay_manager *mgr;
- unsigned bit;
-
- mgr = omap_dss_get_overlay_manager(i);
- bit = mgr_desc[i].sync_lost_irq;
-
- if (bit & errors) {
- struct omap_dss_device *dssdev = mgr->get_device(mgr);
- bool enable;
-
- DSSERR("SYNC_LOST on channel %s, restarting the output "
- "with video overlays disabled\n",
- mgr->name);
-
- enable = dssdev->state == OMAP_DSS_DISPLAY_ACTIVE;
- dssdev->driver->disable(dssdev);
-
- for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
- struct omap_overlay *ovl;
- ovl = omap_dss_get_overlay(i);
-
- if (ovl->id != OMAP_DSS_GFX &&
- ovl->manager == mgr)
- dispc_ovl_enable(ovl->id, false);
- }
-
- dispc_mgr_go(mgr->id);
- msleep(50);
-
- if (enable)
- dssdev->driver->enable(dssdev);
- }
- }
-
- if (errors & DISPC_IRQ_OCP_ERR) {
- DSSERR("OCP_ERR\n");
- for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
- struct omap_overlay_manager *mgr;
- struct omap_dss_device *dssdev;
+ u32 old_mask = dispc_read_reg(DISPC_IRQENABLE);
- mgr = omap_dss_get_overlay_manager(i);
- dssdev = mgr->get_device(mgr);
-
- if (dssdev && dssdev->driver)
- dssdev->driver->disable(dssdev);
- }
- }
-
- spin_lock_irqsave(&dispc.irq_lock, flags);
- dispc.irq_error_mask |= errors;
- _omap_dispc_set_irqs();
- spin_unlock_irqrestore(&dispc.irq_lock, flags);
-
- dispc_runtime_put();
-}
-
-int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout)
-{
- void dispc_irq_wait_handler(void *data, u32 mask)
- {
- complete((struct completion *)data);
- }
-
- int r;
- DECLARE_COMPLETION_ONSTACK(completion);
-
- r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion,
- irqmask);
-
- if (r)
- return r;
-
- timeout = wait_for_completion_timeout(&completion, timeout);
-
- omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
-
- if (timeout == 0)
- return -ETIMEDOUT;
-
- if (timeout == -ERESTARTSYS)
- return -ERESTARTSYS;
-
- return 0;
-}
-
-int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
- unsigned long timeout)
-{
- void dispc_irq_wait_handler(void *data, u32 mask)
- {
- complete((struct completion *)data);
- }
-
- int r;
- DECLARE_COMPLETION_ONSTACK(completion);
-
- r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion,
- irqmask);
-
- if (r)
- return r;
-
- timeout = wait_for_completion_interruptible_timeout(&completion,
- timeout);
-
- omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
-
- if (timeout == 0)
- return -ETIMEDOUT;
-
- if (timeout == -ERESTARTSYS)
- return -ERESTARTSYS;
-
- return 0;
-}
-
-static void _omap_dispc_initialize_irq(void)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&dispc.irq_lock, flags);
-
- memset(dispc.registered_isr, 0, sizeof(dispc.registered_isr));
-
- dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
- if (dss_has_feature(FEAT_MGR_LCD2))
- dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
- if (dss_has_feature(FEAT_MGR_LCD3))
- dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST3;
- if (dss_feat_get_num_ovls() > 3)
- dispc.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW;
-
- /* there's SYNC_LOST_DIGIT waiting after enabling the DSS,
- * so clear it */
- dispc_write_reg(DISPC_IRQSTATUS, dispc_read_reg(DISPC_IRQSTATUS));
-
- _omap_dispc_set_irqs();
+ /* clear the irqstatus for newly enabled irqs */
+ dispc_clear_irqstatus((mask ^ old_mask) & mask);
- spin_unlock_irqrestore(&dispc.irq_lock, flags);
+ dispc_write_reg(DISPC_IRQENABLE, mask);
}
+EXPORT_SYMBOL(dispc_write_irqenable);
void dispc_enable_sidle(void)
{
@@ -4000,9 +3475,14 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {
.sw_max = 64,
.vp_max = 255,
.hp_max = 256,
+ .mgr_width_start = 10,
+ .mgr_height_start = 26,
+ .mgr_width_max = 2048,
+ .mgr_height_max = 2048,
.calc_scaling = dispc_ovl_calc_scaling_24xx,
.calc_core_clk = calc_core_clk_24xx,
.num_fifos = 3,
+ .no_framedone_tv = true,
};
static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
@@ -4012,9 +3492,14 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
.sw_max = 64,
.vp_max = 255,
.hp_max = 256,
+ .mgr_width_start = 10,
+ .mgr_height_start = 26,
+ .mgr_width_max = 2048,
+ .mgr_height_max = 2048,
.calc_scaling = dispc_ovl_calc_scaling_34xx,
.calc_core_clk = calc_core_clk_34xx,
.num_fifos = 3,
+ .no_framedone_tv = true,
};
static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
@@ -4024,9 +3509,14 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
.sw_max = 256,
.vp_max = 4095,
.hp_max = 4096,
+ .mgr_width_start = 10,
+ .mgr_height_start = 26,
+ .mgr_width_max = 2048,
+ .mgr_height_max = 2048,
.calc_scaling = dispc_ovl_calc_scaling_34xx,
.calc_core_clk = calc_core_clk_34xx,
.num_fifos = 3,
+ .no_framedone_tv = true,
};
static const struct dispc_features omap44xx_dispc_feats __initconst = {
@@ -4036,35 +3526,70 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
.sw_max = 256,
.vp_max = 4095,
.hp_max = 4096,
+ .mgr_width_start = 10,
+ .mgr_height_start = 26,
+ .mgr_width_max = 2048,
+ .mgr_height_max = 2048,
+ .calc_scaling = dispc_ovl_calc_scaling_44xx,
+ .calc_core_clk = calc_core_clk_44xx,
+ .num_fifos = 5,
+ .gfx_fifo_workaround = true,
+};
+
+static const struct dispc_features omap54xx_dispc_feats __initconst = {
+ .sw_start = 7,
+ .fp_start = 19,
+ .bp_start = 31,
+ .sw_max = 256,
+ .vp_max = 4095,
+ .hp_max = 4096,
+ .mgr_width_start = 11,
+ .mgr_height_start = 27,
+ .mgr_width_max = 4096,
+ .mgr_height_max = 4096,
.calc_scaling = dispc_ovl_calc_scaling_44xx,
.calc_core_clk = calc_core_clk_44xx,
.num_fifos = 5,
.gfx_fifo_workaround = true,
};
-static int __init dispc_init_features(struct device *dev)
+static int __init dispc_init_features(struct platform_device *pdev)
{
const struct dispc_features *src;
struct dispc_features *dst;
- dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
+ dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
if (!dst) {
- dev_err(dev, "Failed to allocate DISPC Features\n");
+ dev_err(&pdev->dev, "Failed to allocate DISPC Features\n");
return -ENOMEM;
}
- if (cpu_is_omap24xx()) {
+ switch (omapdss_get_version()) {
+ case OMAPDSS_VER_OMAP24xx:
src = &omap24xx_dispc_feats;
- } else if (cpu_is_omap34xx()) {
- if (omap_rev() < OMAP3430_REV_ES3_0)
- src = &omap34xx_rev1_0_dispc_feats;
- else
- src = &omap34xx_rev3_0_dispc_feats;
- } else if (cpu_is_omap44xx()) {
- src = &omap44xx_dispc_feats;
- } else if (soc_is_omap54xx()) {
+ break;
+
+ case OMAPDSS_VER_OMAP34xx_ES1:
+ src = &omap34xx_rev1_0_dispc_feats;
+ break;
+
+ case OMAPDSS_VER_OMAP34xx_ES3:
+ case OMAPDSS_VER_OMAP3630:
+ case OMAPDSS_VER_AM35xx:
+ src = &omap34xx_rev3_0_dispc_feats;
+ break;
+
+ case OMAPDSS_VER_OMAP4430_ES1:
+ case OMAPDSS_VER_OMAP4430_ES2:
+ case OMAPDSS_VER_OMAP4:
src = &omap44xx_dispc_feats;
- } else {
+ break;
+
+ case OMAPDSS_VER_OMAP5:
+ src = &omap54xx_dispc_feats;
+ break;
+
+ default:
return -ENODEV;
}
@@ -4074,29 +3599,32 @@ static int __init dispc_init_features(struct device *dev)
return 0;
}
+int dispc_request_irq(irq_handler_t handler, void *dev_id)
+{
+ return devm_request_irq(&dispc.pdev->dev, dispc.irq, handler,
+ IRQF_SHARED, "OMAP DISPC", dev_id);
+}
+EXPORT_SYMBOL(dispc_request_irq);
+
+void dispc_free_irq(void *dev_id)
+{
+ devm_free_irq(&dispc.pdev->dev, dispc.irq, dev_id);
+}
+EXPORT_SYMBOL(dispc_free_irq);
+
/* DISPC HW IP initialisation */
static int __init omap_dispchw_probe(struct platform_device *pdev)
{
u32 rev;
int r = 0;
struct resource *dispc_mem;
- struct clk *clk;
dispc.pdev = pdev;
- r = dispc_init_features(&dispc.pdev->dev);
+ r = dispc_init_features(dispc.pdev);
if (r)
return r;
- spin_lock_init(&dispc.irq_lock);
-
-#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
- spin_lock_init(&dispc.irq_stats_lock);
- dispc.irq_stats.last_reset = jiffies;
-#endif
-
- INIT_WORK(&dispc.error_work, dispc_error_worker);
-
dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
if (!dispc_mem) {
DSSERR("can't get IORESOURCE_MEM DISPC\n");
@@ -4116,22 +3644,6 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
return -ENODEV;
}
- r = devm_request_irq(&pdev->dev, dispc.irq, omap_dispc_irq_handler,
- IRQF_SHARED, "OMAP DISPC", dispc.pdev);
- if (r < 0) {
- DSSERR("request_irq failed\n");
- return r;
- }
-
- clk = clk_get(&pdev->dev, "fck");
- if (IS_ERR(clk)) {
- DSSERR("can't get fck\n");
- r = PTR_ERR(clk);
- return r;
- }
-
- dispc.dss_clk = clk;
-
pm_runtime_enable(&pdev->dev);
r = dispc_runtime_get();
@@ -4140,8 +3652,6 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
_omap_dispc_initial_config();
- _omap_dispc_initialize_irq();
-
rev = dispc_read_reg(DISPC_REVISION);
dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n",
FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
@@ -4150,14 +3660,10 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
dss_debugfs_create_file("dispc", dispc_dump_regs);
-#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
- dss_debugfs_create_file("dispc_irq", dispc_dump_irqs);
-#endif
return 0;
err_runtime_get:
pm_runtime_disable(&pdev->dev);
- clk_put(dispc.dss_clk);
return r;
}
@@ -4165,8 +3671,6 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
- clk_put(dispc.dss_clk);
-
return 0;
}
diff --git a/drivers/video/omap2/dss/display-sysfs.c b/drivers/video/omap2/dss/display-sysfs.c
new file mode 100644
index 0000000..18211a9
--- /dev/null
+++ b/drivers/video/omap2/dss/display-sysfs.c
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "DISPLAY"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+
+#include <video/omapdss.h>
+#include "dss.h"
+#include "dss_features.h"
+
+static ssize_t display_enabled_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ bool enabled = dssdev->state != OMAP_DSS_DISPLAY_DISABLED;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", enabled);
+}
+
+static ssize_t display_enabled_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ int r;
+ bool enabled;
+
+ r = strtobool(buf, &enabled);
+ if (r)
+ return r;
+
+ if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
+ if (enabled) {
+ r = dssdev->driver->enable(dssdev);
+ if (r)
+ return r;
+ } else {
+ dssdev->driver->disable(dssdev);
+ }
+ }
+
+ return size;
+}
+
+static ssize_t display_tear_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ dssdev->driver->get_te ?
+ dssdev->driver->get_te(dssdev) : 0);
+}
+
+static ssize_t display_tear_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ int r;
+ bool te;
+
+ if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
+ return -ENOENT;
+
+ r = strtobool(buf, &te);
+ if (r)
+ return r;
+
+ r = dssdev->driver->enable_te(dssdev, te);
+ if (r)
+ return r;
+
+ return size;
+}
+
+static ssize_t display_timings_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_video_timings t;
+
+ if (!dssdev->driver->get_timings)
+ return -ENOENT;
+
+ dssdev->driver->get_timings(dssdev, &t);
+
+ return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
+ t.pixel_clock,
+ t.x_res, t.hfp, t.hbp, t.hsw,
+ t.y_res, t.vfp, t.vbp, t.vsw);
+}
+
+static ssize_t display_timings_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_video_timings t = dssdev->panel.timings;
+ int r, found;
+
+ if (!dssdev->driver->set_timings || !dssdev->driver->check_timings)
+ return -ENOENT;
+
+ found = 0;
+#ifdef CONFIG_OMAP2_DSS_VENC
+ if (strncmp("pal", buf, 3) == 0) {
+ t = omap_dss_pal_timings;
+ found = 1;
+ } else if (strncmp("ntsc", buf, 4) == 0) {
+ t = omap_dss_ntsc_timings;
+ found = 1;
+ }
+#endif
+ if (!found && sscanf(buf, "%u,%hu/%hu/%hu/%hu,%hu/%hu/%hu/%hu",
+ &t.pixel_clock,
+ &t.x_res, &t.hfp, &t.hbp, &t.hsw,
+ &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)
+ return -EINVAL;
+
+ r = dssdev->driver->check_timings(dssdev, &t);
+ if (r)
+ return r;
+
+ dssdev->driver->disable(dssdev);
+ dssdev->driver->set_timings(dssdev, &t);
+ r = dssdev->driver->enable(dssdev);
+ if (r)
+ return r;
+
+ return size;
+}
+
+static ssize_t display_rotate_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ int rotate;
+ if (!dssdev->driver->get_rotate)
+ return -ENOENT;
+ rotate = dssdev->driver->get_rotate(dssdev);
+ return snprintf(buf, PAGE_SIZE, "%u\n", rotate);
+}
+
+static ssize_t display_rotate_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ int rot, r;
+
+ if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
+ return -ENOENT;
+
+ r = kstrtoint(buf, 0, &rot);
+ if (r)
+ return r;
+
+ r = dssdev->driver->set_rotate(dssdev, rot);
+ if (r)
+ return r;
+
+ return size;
+}
+
+static ssize_t display_mirror_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ int mirror;
+ if (!dssdev->driver->get_mirror)
+ return -ENOENT;
+ mirror = dssdev->driver->get_mirror(dssdev);
+ return snprintf(buf, PAGE_SIZE, "%u\n", mirror);
+}
+
+static ssize_t display_mirror_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ int r;
+ bool mirror;
+
+ if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
+ return -ENOENT;
+
+ r = strtobool(buf, &mirror);
+ if (r)
+ return r;
+
+ r = dssdev->driver->set_mirror(dssdev, mirror);
+ if (r)
+ return r;
+
+ return size;
+}
+
+static ssize_t display_wss_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ unsigned int wss;
+
+ if (!dssdev->driver->get_wss)
+ return -ENOENT;
+
+ wss = dssdev->driver->get_wss(dssdev);
+
+ return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss);
+}
+
+static ssize_t display_wss_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ u32 wss;
+ int r;
+
+ if (!dssdev->driver->get_wss || !dssdev->driver->set_wss)
+ return -ENOENT;
+
+ r = kstrtou32(buf, 0, &wss);
+ if (r)
+ return r;
+
+ if (wss > 0xfffff)
+ return -EINVAL;
+
+ r = dssdev->driver->set_wss(dssdev, wss);
+ if (r)
+ return r;
+
+ return size;
+}
+
+static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
+ display_enabled_show, display_enabled_store);
+static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
+ display_tear_show, display_tear_store);
+static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR,
+ display_timings_show, display_timings_store);
+static DEVICE_ATTR(rotate, S_IRUGO|S_IWUSR,
+ display_rotate_show, display_rotate_store);
+static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR,
+ display_mirror_show, display_mirror_store);
+static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
+ display_wss_show, display_wss_store);
+
+static struct device_attribute *display_sysfs_attrs[] = {
+ &dev_attr_enabled,
+ &dev_attr_tear_elim,
+ &dev_attr_timings,
+ &dev_attr_rotate,
+ &dev_attr_mirror,
+ &dev_attr_wss,
+ NULL
+};
+
+int display_init_sysfs(struct platform_device *pdev,
+ struct omap_dss_device *dssdev)
+{
+ struct device_attribute *attr;
+ int i, r;
+
+ /* create device sysfs files */
+ i = 0;
+ while ((attr = display_sysfs_attrs[i++]) != NULL) {
+ r = device_create_file(&dssdev->dev, attr);
+ if (r) {
+ for (i = i - 2; i >= 0; i--) {
+ attr = display_sysfs_attrs[i];
+ device_remove_file(&dssdev->dev, attr);
+ }
+
+ DSSERR("failed to create sysfs file\n");
+ return r;
+ }
+ }
+
+ /* create display? sysfs links */
+ r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
+ dev_name(&dssdev->dev));
+ if (r) {
+ while ((attr = display_sysfs_attrs[i++]) != NULL)
+ device_remove_file(&dssdev->dev, attr);
+
+ DSSERR("failed to create sysfs display link\n");
+ return r;
+ }
+
+ return 0;
+}
+
+void display_uninit_sysfs(struct platform_device *pdev,
+ struct omap_dss_device *dssdev)
+{
+ struct device_attribute *attr;
+ int i = 0;
+
+ sysfs_remove_link(&pdev->dev.kobj, dev_name(&dssdev->dev));
+
+ while ((attr = display_sysfs_attrs[i++]) != NULL)
+ device_remove_file(&dssdev->dev, attr);
+}
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index ccf8550..0aa8ad8 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -31,250 +31,6 @@
#include "dss.h"
#include "dss_features.h"
-static ssize_t display_enabled_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct omap_dss_device *dssdev = to_dss_device(dev);
- bool enabled = dssdev->state != OMAP_DSS_DISPLAY_DISABLED;
-
- return snprintf(buf, PAGE_SIZE, "%d\n", enabled);
-}
-
-static ssize_t display_enabled_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t size)
-{
- struct omap_dss_device *dssdev = to_dss_device(dev);
- int r;
- bool enabled;
-
- r = strtobool(buf, &enabled);
- if (r)
- return r;
-
- if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
- if (enabled) {
- r = dssdev->driver->enable(dssdev);
- if (r)
- return r;
- } else {
- dssdev->driver->disable(dssdev);
- }
- }
-
- return size;
-}
-
-static ssize_t display_tear_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct omap_dss_device *dssdev = to_dss_device(dev);
- return snprintf(buf, PAGE_SIZE, "%d\n",
- dssdev->driver->get_te ?
- dssdev->driver->get_te(dssdev) : 0);
-}
-
-static ssize_t display_tear_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
-{
- struct omap_dss_device *dssdev = to_dss_device(dev);
- int r;
- bool te;
-
- if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
- return -ENOENT;
-
- r = strtobool(buf, &te);
- if (r)
- return r;
-
- r = dssdev->driver->enable_te(dssdev, te);
- if (r)
- return r;
-
- return size;
-}
-
-static ssize_t display_timings_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct omap_dss_device *dssdev = to_dss_device(dev);
- struct omap_video_timings t;
-
- if (!dssdev->driver->get_timings)
- return -ENOENT;
-
- dssdev->driver->get_timings(dssdev, &t);
-
- return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
- t.pixel_clock,
- t.x_res, t.hfp, t.hbp, t.hsw,
- t.y_res, t.vfp, t.vbp, t.vsw);
-}
-
-static ssize_t display_timings_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
-{
- struct omap_dss_device *dssdev = to_dss_device(dev);
- struct omap_video_timings t = dssdev->panel.timings;
- int r, found;
-
- if (!dssdev->driver->set_timings || !dssdev->driver->check_timings)
- return -ENOENT;
-
- found = 0;
-#ifdef CONFIG_OMAP2_DSS_VENC
- if (strncmp("pal", buf, 3) == 0) {
- t = omap_dss_pal_timings;
- found = 1;
- } else if (strncmp("ntsc", buf, 4) == 0) {
- t = omap_dss_ntsc_timings;
- found = 1;
- }
-#endif
- if (!found && sscanf(buf, "%u,%hu/%hu/%hu/%hu,%hu/%hu/%hu/%hu",
- &t.pixel_clock,
- &t.x_res, &t.hfp, &t.hbp, &t.hsw,
- &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)
- return -EINVAL;
-
- r = dssdev->driver->check_timings(dssdev, &t);
- if (r)
- return r;
-
- dssdev->driver->disable(dssdev);
- dssdev->driver->set_timings(dssdev, &t);
- r = dssdev->driver->enable(dssdev);
- if (r)
- return r;
-
- return size;
-}
-
-static ssize_t display_rotate_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct omap_dss_device *dssdev = to_dss_device(dev);
- int rotate;
- if (!dssdev->driver->get_rotate)
- return -ENOENT;
- rotate = dssdev->driver->get_rotate(dssdev);
- return snprintf(buf, PAGE_SIZE, "%u\n", rotate);
-}
-
-static ssize_t display_rotate_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
-{
- struct omap_dss_device *dssdev = to_dss_device(dev);
- int rot, r;
-
- if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
- return -ENOENT;
-
- r = kstrtoint(buf, 0, &rot);
- if (r)
- return r;
-
- r = dssdev->driver->set_rotate(dssdev, rot);
- if (r)
- return r;
-
- return size;
-}
-
-static ssize_t display_mirror_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct omap_dss_device *dssdev = to_dss_device(dev);
- int mirror;
- if (!dssdev->driver->get_mirror)
- return -ENOENT;
- mirror = dssdev->driver->get_mirror(dssdev);
- return snprintf(buf, PAGE_SIZE, "%u\n", mirror);
-}
-
-static ssize_t display_mirror_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
-{
- struct omap_dss_device *dssdev = to_dss_device(dev);
- int r;
- bool mirror;
-
- if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
- return -ENOENT;
-
- r = strtobool(buf, &mirror);
- if (r)
- return r;
-
- r = dssdev->driver->set_mirror(dssdev, mirror);
- if (r)
- return r;
-
- return size;
-}
-
-static ssize_t display_wss_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct omap_dss_device *dssdev = to_dss_device(dev);
- unsigned int wss;
-
- if (!dssdev->driver->get_wss)
- return -ENOENT;
-
- wss = dssdev->driver->get_wss(dssdev);
-
- return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss);
-}
-
-static ssize_t display_wss_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
-{
- struct omap_dss_device *dssdev = to_dss_device(dev);
- u32 wss;
- int r;
-
- if (!dssdev->driver->get_wss || !dssdev->driver->set_wss)
- return -ENOENT;
-
- r = kstrtou32(buf, 0, &wss);
- if (r)
- return r;
-
- if (wss > 0xfffff)
- return -EINVAL;
-
- r = dssdev->driver->set_wss(dssdev, wss);
- if (r)
- return r;
-
- return size;
-}
-
-static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
- display_enabled_show, display_enabled_store);
-static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
- display_tear_show, display_tear_store);
-static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR,
- display_timings_show, display_timings_store);
-static DEVICE_ATTR(rotate, S_IRUGO|S_IWUSR,
- display_rotate_show, display_rotate_store);
-static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR,
- display_mirror_show, display_mirror_store);
-static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
- display_wss_show, display_wss_store);
-
-static struct device_attribute *display_sysfs_attrs[] = {
- &dev_attr_enabled,
- &dev_attr_tear_elim,
- &dev_attr_timings,
- &dev_attr_rotate,
- &dev_attr_mirror,
- &dev_attr_wss,
- NULL
-};
-
void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
u16 *xres, u16 *yres)
{
@@ -320,136 +76,8 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev,
}
EXPORT_SYMBOL(omapdss_default_get_timings);
-/*
- * Connect dssdev to a manager if the manager is free or if force is specified.
- * Connect all overlays to that manager if they are free or if force is
- * specified.
- */
-static int dss_init_connections(struct omap_dss_device *dssdev, bool force)
-{
- struct omap_dss_output *out;
- struct omap_overlay_manager *mgr;
- int i, r;
-
- out = omapdss_get_output_from_dssdev(dssdev);
-
- WARN_ON(dssdev->output);
- WARN_ON(out->device);
-
- r = omapdss_output_set_device(out, dssdev);
- if (r) {
- DSSERR("failed to connect output to new device\n");
- return r;
- }
-
- mgr = omap_dss_get_overlay_manager(dssdev->channel);
-
- if (mgr->output && !force)
- return 0;
-
- if (mgr->output)
- mgr->unset_output(mgr);
-
- r = mgr->set_output(mgr, out);
- if (r) {
- DSSERR("failed to connect manager to output of new device\n");
-
- /* remove the output-device connection we just made */
- omapdss_output_unset_device(out);
- return r;
- }
-
- for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
- struct omap_overlay *ovl = omap_dss_get_overlay(i);
-
- if (!ovl->manager || force) {
- if (ovl->manager)
- ovl->unset_manager(ovl);
-
- r = ovl->set_manager(ovl, mgr);
- if (r) {
- DSSERR("failed to set initial overlay\n");
- return r;
- }
- }
- }
-
- return 0;
-}
-
-static void dss_uninit_connections(struct omap_dss_device *dssdev)
-{
- if (dssdev->output) {
- struct omap_overlay_manager *mgr = dssdev->output->manager;
-
- if (mgr)
- mgr->unset_output(mgr);
-
- omapdss_output_unset_device(dssdev->output);
- }
-}
-
-int dss_init_device(struct platform_device *pdev,
- struct omap_dss_device *dssdev)
-{
- struct device_attribute *attr;
- int i, r;
- const char *def_disp_name = dss_get_default_display_name();
- bool force;
-
- force = def_disp_name && strcmp(def_disp_name, dssdev->name) == 0;
- dss_init_connections(dssdev, force);
-
- /* create device sysfs files */
- i = 0;
- while ((attr = display_sysfs_attrs[i++]) != NULL) {
- r = device_create_file(&dssdev->dev, attr);
- if (r) {
- for (i = i - 2; i >= 0; i--) {
- attr = display_sysfs_attrs[i];
- device_remove_file(&dssdev->dev, attr);
- }
-
- dss_uninit_connections(dssdev);
-
- DSSERR("failed to create sysfs file\n");
- return r;
- }
- }
-
- /* create display? sysfs links */
- r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
- dev_name(&dssdev->dev));
- if (r) {
- while ((attr = display_sysfs_attrs[i++]) != NULL)
- device_remove_file(&dssdev->dev, attr);
-
- dss_uninit_connections(dssdev);
-
- DSSERR("failed to create sysfs display link\n");
- return r;
- }
-
- return 0;
-}
-
-void dss_uninit_device(struct platform_device *pdev,
- struct omap_dss_device *dssdev)
-{
- struct device_attribute *attr;
- int i = 0;
-
- sysfs_remove_link(&pdev->dev.kobj, dev_name(&dssdev->dev));
-
- while ((attr = display_sysfs_attrs[i++]) != NULL)
- device_remove_file(&dssdev->dev, attr);
-
- dss_uninit_connections(dssdev);
-}
-
static int dss_suspend_device(struct device *dev, void *data)
{
- int r;
struct omap_dss_device *dssdev = to_dss_device(dev);
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
@@ -457,15 +85,7 @@ static int dss_suspend_device(struct device *dev, void *data)
return 0;
}
- if (!dssdev->driver->suspend) {
- DSSERR("display '%s' doesn't implement suspend\n",
- dssdev->name);
- return -ENOSYS;
- }
-
- r = dssdev->driver->suspend(dssdev);
- if (r)
- return r;
+ dssdev->driver->disable(dssdev);
dssdev->activate_after_resume = true;
@@ -492,8 +112,8 @@ static int dss_resume_device(struct device *dev, void *data)
int r;
struct omap_dss_device *dssdev = to_dss_device(dev);
- if (dssdev->activate_after_resume && dssdev->driver->resume) {
- r = dssdev->driver->resume(dssdev);
+ if (dssdev->activate_after_resume) {
+ r = dssdev->driver->enable(dssdev);
if (r)
return r;
}
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 56748cf..4af136a 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -49,34 +49,53 @@ static struct {
struct omap_dss_output output;
} dpi;
-static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
+static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
{
- int dsi_module;
-
- dsi_module = clk == OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ? 0 : 1;
+ /*
+ * XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL
+ * would also be used for DISPC fclk. Meaning, when the DPI output is
+ * disabled, DISPC clock will be disabled, and TV out will stop.
+ */
+ switch (omapdss_get_version()) {
+ case OMAPDSS_VER_OMAP24xx:
+ case OMAPDSS_VER_OMAP34xx_ES1:
+ case OMAPDSS_VER_OMAP34xx_ES3:
+ case OMAPDSS_VER_OMAP3630:
+ case OMAPDSS_VER_AM35xx:
+ return NULL;
+ default:
+ break;
+ }
- return dsi_get_dsidev_from_id(dsi_module);
+ switch (channel) {
+ case OMAP_DSS_CHANNEL_LCD:
+ return dsi_get_dsidev_from_id(0);
+ case OMAP_DSS_CHANNEL_LCD2:
+ return dsi_get_dsidev_from_id(1);
+ default:
+ return NULL;
+ }
}
-static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
+static enum omap_dss_clk_source dpi_get_alt_clk_src(enum omap_channel channel)
{
- if (dssdev->clocks.dispc.dispc_fclk_src ==
- OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ||
- dssdev->clocks.dispc.dispc_fclk_src ==
- OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC ||
- dssdev->clocks.dispc.channel.lcd_clk_src ==
- OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ||
- dssdev->clocks.dispc.channel.lcd_clk_src ==
- OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC)
- return true;
- else
- return false;
+ switch (channel) {
+ case OMAP_DSS_CHANNEL_LCD:
+ return OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC;
+ case OMAP_DSS_CHANNEL_LCD2:
+ return OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
+ default:
+ /* this shouldn't happen */
+ WARN_ON(1);
+ return OMAP_DSS_CLK_SRC_FCK;
+ }
}
static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
unsigned long pck_req, unsigned long *fck, int *lck_div,
int *pck_div)
{
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
struct dsi_clock_info dsi_cinfo;
struct dispc_clock_info dispc_cinfo;
int r;
@@ -90,7 +109,8 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
if (r)
return r;
- dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
+ dss_select_lcd_clk_source(mgr->id,
+ dpi_get_alt_clk_src(mgr->id));
dpi.mgr_config.clock_info = dispc_cinfo;
@@ -135,7 +155,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
unsigned long pck;
int r = 0;
- if (dpi_use_dsi_pll(dssdev))
+ if (dpi.dsidev)
r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck,
&lck_div, &pck_div);
else
@@ -214,7 +234,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
if (r)
goto err_src_sel;
- if (dpi_use_dsi_pll(dssdev)) {
+ if (dpi.dsidev) {
r = dsi_runtime_get(dpi.dsidev);
if (r)
goto err_get_dsi;
@@ -242,10 +262,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
err_mgr_enable:
err_set_mode:
- if (dpi_use_dsi_pll(dssdev))
+ if (dpi.dsidev)
dsi_pll_uninit(dpi.dsidev, true);
err_dsi_pll_init:
- if (dpi_use_dsi_pll(dssdev))
+ if (dpi.dsidev)
dsi_runtime_put(dpi.dsidev);
err_get_dsi:
err_src_sel:
@@ -271,8 +291,8 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
dss_mgr_disable(mgr);
- if (dpi_use_dsi_pll(dssdev)) {
- dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
+ if (dpi.dsidev) {
+ dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
dsi_pll_uninit(dpi.dsidev, true);
dsi_runtime_put(dpi.dsidev);
}
@@ -311,13 +331,13 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
unsigned long pck;
struct dispc_clock_info dispc_cinfo;
- if (dss_mgr_check_timings(mgr, timings))
+ if (mgr && !dispc_mgr_timings_ok(mgr->id, timings))
return -EINVAL;
if (timings->pixel_clock == 0)
return -EINVAL;
- if (dpi_use_dsi_pll(dssdev)) {
+ if (dpi.dsidev) {
struct dsi_clock_info dsi_cinfo;
r = dsi_pll_calc_clock_div_pck(dpi.dsidev,
timings->pixel_clock * 1000,
@@ -359,8 +379,32 @@ void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
}
EXPORT_SYMBOL(omapdss_dpi_set_data_lines);
+static int __init dpi_verify_dsi_pll(struct platform_device *dsidev)
+{
+ int r;
+
+ /* do initial setup with the PLL to see if it is operational */
+
+ r = dsi_runtime_get(dsidev);
+ if (r)
+ return r;
+
+ r = dsi_pll_init(dsidev, 0, 1);
+ if (r) {
+ dsi_runtime_put(dsidev);
+ return r;
+ }
+
+ dsi_pll_uninit(dsidev, true);
+ dsi_runtime_put(dsidev);
+
+ return 0;
+}
+
static int __init dpi_init_display(struct omap_dss_device *dssdev)
{
+ struct platform_device *dsidev;
+
DSSDBG("init_display\n");
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) &&
@@ -377,19 +421,30 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
dpi.vdds_dsi_reg = vdds_dsi;
}
- if (dpi_use_dsi_pll(dssdev)) {
- enum omap_dss_clk_source dispc_fclk_src =
- dssdev->clocks.dispc.dispc_fclk_src;
- dpi.dsidev = dpi_get_dsidev(dispc_fclk_src);
+ /*
+ * XXX We shouldn't need dssdev->channel for this. The dsi pll clock
+ * source for DPI is SoC integration detail, not something that should
+ * be configured in the dssdev
+ */
+ dsidev = dpi_get_dsidev(dssdev->channel);
+
+ if (dsidev && dpi_verify_dsi_pll(dsidev)) {
+ dsidev = NULL;
+ DSSWARN("DSI PLL not operational\n");
}
+ if (dsidev)
+ DSSDBG("using DSI PLL for DPI clock\n");
+
+ dpi.dsidev = dsidev;
+
return 0;
}
static struct omap_dss_device * __init dpi_find_dssdev(struct platform_device *pdev)
{
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
- const char *def_disp_name = dss_get_default_display_name();
+ const char *def_disp_name = omapdss_get_default_display_name();
struct omap_dss_device *def_dssdev;
int i;
@@ -438,9 +493,18 @@ static void __init dpi_probe_pdata(struct platform_device *dpidev)
return;
}
+ r = omapdss_output_set_device(&dpi.output, dssdev);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dssdev->name);
+ dss_put_device(dssdev);
+ return;
+ }
+
r = dss_add_device(dssdev);
if (r) {
DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ omapdss_output_unset_device(&dpi.output);
dss_put_device(dssdev);
return;
}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index d64ac38..28d41d1 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -45,7 +45,6 @@
#include "dss.h"
#include "dss_features.h"
-/*#define VERBOSE_IRQ*/
#define DSI_CATCH_MISSING_TE
struct dsi_reg { u16 idx; };
@@ -365,11 +364,20 @@ struct platform_device *dsi_get_dsidev_from_id(int module)
struct omap_dss_output *out;
enum omap_dss_output_id id;
- id = module == 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+ switch (module) {
+ case 0:
+ id = OMAP_DSS_OUTPUT_DSI1;
+ break;
+ case 1:
+ id = OMAP_DSS_OUTPUT_DSI2;
+ break;
+ default:
+ return NULL;
+ }
out = omap_dss_get_output(id);
- return out->pdev;
+ return out ? out->pdev : NULL;
}
static inline void dsi_write_reg(struct platform_device *dsidev,
@@ -526,42 +534,38 @@ static inline void dsi_perf_show(struct platform_device *dsidev,
}
#endif
+static int verbose_irq;
+
static void print_irq_status(u32 status)
{
if (status == 0)
return;
-#ifndef VERBOSE_IRQ
- if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0)
+ if (!verbose_irq && (status & ~DSI_IRQ_CHANNEL_MASK) == 0)
return;
-#endif
- printk(KERN_DEBUG "DSI IRQ: 0x%x: ", status);
-#define PIS(x) \
- if (status & DSI_IRQ_##x) \
- printk(#x " ");
-#ifdef VERBOSE_IRQ
- PIS(VC0);
- PIS(VC1);
- PIS(VC2);
- PIS(VC3);
-#endif
- PIS(WAKEUP);
- PIS(RESYNC);
- PIS(PLL_LOCK);
- PIS(PLL_UNLOCK);
- PIS(PLL_RECALL);
- PIS(COMPLEXIO_ERR);
- PIS(HS_TX_TIMEOUT);
- PIS(LP_RX_TIMEOUT);
- PIS(TE_TRIGGER);
- PIS(ACK_TRIGGER);
- PIS(SYNC_LOST);
- PIS(LDO_POWER_GOOD);
- PIS(TA_TIMEOUT);
+#define PIS(x) (status & DSI_IRQ_##x) ? (#x " ") : ""
+
+ pr_debug("DSI IRQ: 0x%x: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+ status,
+ verbose_irq ? PIS(VC0) : "",
+ verbose_irq ? PIS(VC1) : "",
+ verbose_irq ? PIS(VC2) : "",
+ verbose_irq ? PIS(VC3) : "",
+ PIS(WAKEUP),
+ PIS(RESYNC),
+ PIS(PLL_LOCK),
+ PIS(PLL_UNLOCK),
+ PIS(PLL_RECALL),
+ PIS(COMPLEXIO_ERR),
+ PIS(HS_TX_TIMEOUT),
+ PIS(LP_RX_TIMEOUT),
+ PIS(TE_TRIGGER),
+ PIS(ACK_TRIGGER),
+ PIS(SYNC_LOST),
+ PIS(LDO_POWER_GOOD),
+ PIS(TA_TIMEOUT));
#undef PIS
-
- printk("\n");
}
static void print_irq_status_vc(int channel, u32 status)
@@ -569,28 +573,24 @@ static void print_irq_status_vc(int channel, u32 status)
if (status == 0)
return;
-#ifndef VERBOSE_IRQ
- if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0)
+ if (!verbose_irq && (status & ~DSI_VC_IRQ_PACKET_SENT) == 0)
return;
-#endif
- printk(KERN_DEBUG "DSI VC(%d) IRQ 0x%x: ", channel, status);
-#define PIS(x) \
- if (status & DSI_VC_IRQ_##x) \
- printk(#x " ");
- PIS(CS);
- PIS(ECC_CORR);
-#ifdef VERBOSE_IRQ
- PIS(PACKET_SENT);
-#endif
- PIS(FIFO_TX_OVF);
- PIS(FIFO_RX_OVF);
- PIS(BTA);
- PIS(ECC_NO_CORR);
- PIS(FIFO_TX_UDF);
- PIS(PP_BUSY_CHANGE);
+#define PIS(x) (status & DSI_VC_IRQ_##x) ? (#x " ") : ""
+
+ pr_debug("DSI VC(%d) IRQ 0x%x: %s%s%s%s%s%s%s%s%s\n",
+ channel,
+ status,
+ PIS(CS),
+ PIS(ECC_CORR),
+ PIS(ECC_NO_CORR),
+ verbose_irq ? PIS(PACKET_SENT) : "",
+ PIS(BTA),
+ PIS(FIFO_TX_OVF),
+ PIS(FIFO_RX_OVF),
+ PIS(FIFO_TX_UDF),
+ PIS(PP_BUSY_CHANGE));
#undef PIS
- printk("\n");
}
static void print_irq_status_cio(u32 status)
@@ -598,34 +598,31 @@ static void print_irq_status_cio(u32 status)
if (status == 0)
return;
- printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status);
-
-#define PIS(x) \
- if (status & DSI_CIO_IRQ_##x) \
- printk(#x " ");
- PIS(ERRSYNCESC1);
- PIS(ERRSYNCESC2);
- PIS(ERRSYNCESC3);
- PIS(ERRESC1);
- PIS(ERRESC2);
- PIS(ERRESC3);
- PIS(ERRCONTROL1);
- PIS(ERRCONTROL2);
- PIS(ERRCONTROL3);
- PIS(STATEULPS1);
- PIS(STATEULPS2);
- PIS(STATEULPS3);
- PIS(ERRCONTENTIONLP0_1);
- PIS(ERRCONTENTIONLP1_1);
- PIS(ERRCONTENTIONLP0_2);
- PIS(ERRCONTENTIONLP1_2);
- PIS(ERRCONTENTIONLP0_3);
- PIS(ERRCONTENTIONLP1_3);
- PIS(ULPSACTIVENOT_ALL0);
- PIS(ULPSACTIVENOT_ALL1);
+#define PIS(x) (status & DSI_CIO_IRQ_##x) ? (#x " ") : ""
+
+ pr_debug("DSI CIO IRQ 0x%x: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+ status,
+ PIS(ERRSYNCESC1),
+ PIS(ERRSYNCESC2),
+ PIS(ERRSYNCESC3),
+ PIS(ERRESC1),
+ PIS(ERRESC2),
+ PIS(ERRESC3),
+ PIS(ERRCONTROL1),
+ PIS(ERRCONTROL2),
+ PIS(ERRCONTROL3),
+ PIS(STATEULPS1),
+ PIS(STATEULPS2),
+ PIS(STATEULPS3),
+ PIS(ERRCONTENTIONLP0_1),
+ PIS(ERRCONTENTIONLP1_1),
+ PIS(ERRCONTENTIONLP0_2),
+ PIS(ERRCONTENTIONLP1_2),
+ PIS(ERRCONTENTIONLP0_3),
+ PIS(ERRCONTENTIONLP1_3),
+ PIS(ULPSACTIVENOT_ALL0),
+ PIS(ULPSACTIVENOT_ALL1));
#undef PIS
-
- printk("\n");
}
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
@@ -1107,28 +1104,16 @@ static inline void dsi_enable_pll_clock(struct platform_device *dsidev,
}
}
-#ifdef DEBUG
static void _dsi_print_reset_status(struct platform_device *dsidev)
{
u32 l;
int b0, b1, b2;
- if (!dss_debug)
- return;
-
/* A dummy read using the SCP interface to any DSIPHY register is
* required after DSIPHY reset to complete the reset of the DSI complex
* I/O. */
l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
- printk(KERN_DEBUG "DSI resets: ");
-
- l = dsi_read_reg(dsidev, DSI_PLL_STATUS);
- printk("PLL (%d) ", FLD_GET(l, 0, 0));
-
- l = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1);
- printk("CIO (%d) ", FLD_GET(l, 29, 29));
-
if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) {
b0 = 28;
b1 = 27;
@@ -1139,18 +1124,21 @@ static void _dsi_print_reset_status(struct platform_device *dsidev)
b2 = 26;
}
- l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
- printk("PHY (%x%x%x, %d, %d, %d)\n",
- FLD_GET(l, b0, b0),
- FLD_GET(l, b1, b1),
- FLD_GET(l, b2, b2),
- FLD_GET(l, 29, 29),
- FLD_GET(l, 30, 30),
- FLD_GET(l, 31, 31));
+#define DSI_FLD_GET(fld, start, end)\
+ FLD_GET(dsi_read_reg(dsidev, DSI_##fld), start, end)
+
+ pr_debug("DSI resets: PLL (%d) CIO (%d) PHY (%x%x%x, %d, %d, %d)\n",
+ DSI_FLD_GET(PLL_STATUS, 0, 0),
+ DSI_FLD_GET(COMPLEXIO_CFG1, 29, 29),
+ DSI_FLD_GET(DSIPHY_CFG5, b0, b0),
+ DSI_FLD_GET(DSIPHY_CFG5, b1, b1),
+ DSI_FLD_GET(DSIPHY_CFG5, b2, b2),
+ DSI_FLD_GET(DSIPHY_CFG5, 29, 29),
+ DSI_FLD_GET(DSIPHY_CFG5, 30, 30),
+ DSI_FLD_GET(DSIPHY_CFG5, 31, 31));
+
+#undef DSI_FLD_GET
}
-#else
-#define _dsi_print_reset_status(x)
-#endif
static inline int dsi_if_enable(struct platform_device *dsidev, bool enable)
{
@@ -1398,6 +1386,11 @@ retry:
cur.dsi_pll_hsdiv_dispc_clk =
cur.clkin4ddr / cur.regm_dispc;
+ if (cur.regm_dispc > 1 &&
+ cur.regm_dispc % 2 != 0 &&
+ req_pck >= 1000000)
+ continue;
+
/* this will narrow down the search a bit,
* but still give pixclocks below what was
* requested */
@@ -1612,7 +1605,7 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
u8 regn_start, regn_end, regm_start, regm_end;
u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end;
- DSSDBGF();
+ DSSDBG("DSI PLL clock config starts");
dsi->current_cinfo.clkin = cinfo->clkin;
dsi->current_cinfo.fint = cinfo->fint;
@@ -1748,11 +1741,21 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
DSSDBG("PLL init\n");
+ /*
+ * It seems that on many OMAPs we need to enable both to have a
+ * functional HSDivider.
+ */
+ enable_hsclk = enable_hsdiv = true;
+
if (dsi->vdds_dsi_reg == NULL) {
struct regulator *vdds_dsi;
vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi");
+ /* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */
+ if (IS_ERR(vdds_dsi))
+ vdds_dsi = regulator_get(&dsi->pdev->dev, "VCXIO");
+
if (IS_ERR(vdds_dsi)) {
DSSERR("can't get VDDS_DSI regulator\n");
return PTR_ERR(vdds_dsi);
@@ -2431,7 +2434,7 @@ static int dsi_cio_init(struct platform_device *dsidev)
int r;
u32 l;
- DSSDBGF();
+ DSSDBG("DSI CIO init starts");
r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
if (r)
@@ -2782,7 +2785,7 @@ static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
{
u32 r;
- DSSDBGF("%d", channel);
+ DSSDBG("Initial config of virtual channel %d", channel);
r = dsi_read_reg(dsidev, DSI_VC_CTRL(channel));
@@ -2814,7 +2817,7 @@ static int dsi_vc_config_source(struct platform_device *dsidev, int channel,
if (dsi->vc[channel].source == source)
return 0;
- DSSDBGF("%d", channel);
+ DSSDBG("Source config of virtual channel %d", channel);
dsi_sync_vc(dsidev, channel);
@@ -3572,7 +3575,7 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
int r, i;
unsigned mask;
- DSSDBGF();
+ DSSDBG("Entering ULPS");
WARN_ON(!dsi_bus_is_locked(dsidev));
@@ -4276,7 +4279,7 @@ int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
unsigned long pck;
int r;
- DSSDBGF("ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);
+ DSSDBG("Setting DSI clocks: ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);
mutex_lock(&dsi->lock);
@@ -4532,7 +4535,7 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work)
dsi_handle_framedone(dsi->pdev, -ETIMEDOUT);
}
-static void dsi_framedone_irq_callback(void *data, u32 mask)
+static void dsi_framedone_irq_callback(void *data)
{
struct platform_device *dsidev = (struct platform_device *) data;
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
@@ -4606,7 +4609,6 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct omap_overlay_manager *mgr = dssdev->output->manager;
int r;
- u32 irq = 0;
if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
dsi->timings.hsw = 1;
@@ -4616,12 +4618,10 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
dsi->timings.vfp = 0;
dsi->timings.vbp = 0;
- irq = dispc_mgr_get_framedone_irq(mgr->id);
-
- r = omap_dispc_register_isr(dsi_framedone_irq_callback,
- (void *) dsidev, irq);
+ r = dss_mgr_register_framedone_handler(mgr,
+ dsi_framedone_irq_callback, dsidev);
if (r) {
- DSSERR("can't get FRAMEDONE irq\n");
+ DSSERR("can't register FRAMEDONE handler\n");
goto err;
}
@@ -4659,8 +4659,8 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
return 0;
err1:
if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
- omap_dispc_unregister_isr(dsi_framedone_irq_callback,
- (void *) dsidev, irq);
+ dss_mgr_unregister_framedone_handler(mgr,
+ dsi_framedone_irq_callback, dsidev);
err:
return r;
}
@@ -4671,14 +4671,9 @@ static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct omap_overlay_manager *mgr = dssdev->output->manager;
- if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
- u32 irq;
-
- irq = dispc_mgr_get_framedone_irq(mgr->id);
-
- omap_dispc_unregister_isr(dsi_framedone_irq_callback,
- (void *) dsidev, irq);
- }
+ if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
+ dss_mgr_unregister_framedone_handler(mgr,
+ dsi_framedone_irq_callback, dsidev);
}
static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
@@ -4721,7 +4716,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
if (r)
goto err1;
- dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src);
dss_select_lcd_clk_source(mgr->id,
dssdev->clocks.dispc.channel.lcd_clk_src);
@@ -4756,7 +4750,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
err3:
dsi_cio_uninit(dsidev);
err2:
- dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
@@ -4783,7 +4776,6 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
dsi_vc_enable(dsidev, 2, 0);
dsi_vc_enable(dsidev, 3, 0);
- dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
dsi_cio_uninit(dsidev);
@@ -4972,6 +4964,10 @@ static int __init dsi_init_display(struct omap_dss_device *dssdev)
vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi");
+ /* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */
+ if (IS_ERR(vdds_dsi))
+ vdds_dsi = regulator_get(&dsi->pdev->dev, "VCXIO");
+
if (IS_ERR(vdds_dsi)) {
DSSERR("can't get VDDS_DSI regulator\n");
return PTR_ERR(vdds_dsi);
@@ -5112,7 +5108,7 @@ static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *p
{
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
- const char *def_disp_name = dss_get_default_display_name();
+ const char *def_disp_name = omapdss_get_default_display_name();
struct omap_dss_device *def_dssdev;
int i;
@@ -5142,6 +5138,7 @@ static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *p
static void __init dsi_probe_pdata(struct platform_device *dsidev)
{
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct omap_dss_device *plat_dssdev;
struct omap_dss_device *dssdev;
int r;
@@ -5164,9 +5161,18 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
return;
}
+ r = omapdss_output_set_device(&dsi->output, dssdev);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dssdev->name);
+ dss_put_device(dssdev);
+ return;
+ }
+
r = dss_add_device(dssdev);
if (r) {
DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ omapdss_output_unset_device(&dsi->output);
dss_put_device(dssdev);
return;
}
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 2ab1c3e..054c2a2 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -32,11 +32,10 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/gfp.h>
+#include <linux/sizes.h>
#include <video/omapdss.h>
-#include <plat/cpu.h>
-
#include "dss.h"
#include "dss_features.h"
@@ -78,6 +77,7 @@ static struct {
struct clk *dpll4_m4_ck;
struct clk *dss_clk;
+ unsigned long dss_clk_rate;
unsigned long cache_req_pck;
unsigned long cache_prate;
@@ -98,6 +98,8 @@ static const char * const dss_generic_clk_source_names[] = {
[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC",
[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI",
[OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK",
+ [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DSI_PLL2_HSDIV_DISPC",
+ [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DSI_PLL2_HSDIV_DSI",
};
static inline void dss_write_reg(const struct dss_reg idx, u32 val)
@@ -153,6 +155,21 @@ static void dss_restore_context(void)
#undef SR
#undef RR
+int dss_get_ctx_loss_count(void)
+{
+ struct omap_dss_board_info *board_data = dss.pdev->dev.platform_data;
+ int cnt;
+
+ if (!board_data->get_context_loss_count)
+ return -ENOENT;
+
+ cnt = board_data->get_context_loss_count(&dss.pdev->dev);
+
+ WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt);
+
+ return cnt;
+}
+
void dss_sdi_init(int datapairs)
{
u32 l;
@@ -303,7 +320,7 @@ static void dss_dump_regs(struct seq_file *s)
#undef DUMPREG
}
-void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
+static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
{
struct platform_device *dsidev;
int b;
@@ -374,8 +391,10 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
struct platform_device *dsidev;
int b, ix, pos;
- if (!dss_has_feature(FEAT_LCD_CLK_SRC))
+ if (!dss_has_feature(FEAT_LCD_CLK_SRC)) {
+ dss_select_dispc_clk_source(clk_src);
return;
+ }
switch (clk_src) {
case OMAP_DSS_CLK_SRC_FCK:
@@ -431,6 +450,29 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
}
}
+/* calculate clock rates using dividers in cinfo */
+int dss_calc_clock_rates(struct dss_clock_info *cinfo)
+{
+ if (dss.dpll4_m4_ck) {
+ unsigned long prate;
+
+ if (cinfo->fck_div > dss.feat->fck_div_max ||
+ cinfo->fck_div == 0)
+ return -EINVAL;
+
+ prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
+
+ cinfo->fck = prate / cinfo->fck_div *
+ dss.feat->dss_fck_multiplier;
+ } else {
+ if (cinfo->fck_div != 0)
+ return -EINVAL;
+ cinfo->fck = clk_get_rate(dss.dss_clk);
+ }
+
+ return 0;
+}
+
int dss_set_clock_div(struct dss_clock_info *cinfo)
{
if (dss.dpll4_m4_ck) {
@@ -448,6 +490,10 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
return -EINVAL;
}
+ dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
+
+ WARN_ONCE(dss.dss_clk_rate != cinfo->fck, "clk rate mismatch");
+
DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
return 0;
@@ -461,6 +507,41 @@ unsigned long dss_get_dpll4_rate(void)
return 0;
}
+unsigned long dss_get_dispc_clk_rate(void)
+{
+ return dss.dss_clk_rate;
+}
+
+static int dss_setup_default_clock(void)
+{
+ unsigned long max_dss_fck, prate;
+ unsigned fck_div;
+ struct dss_clock_info dss_cinfo = { 0 };
+ int r;
+
+ if (dss.dpll4_m4_ck == NULL)
+ return 0;
+
+ max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
+
+ prate = dss_get_dpll4_rate();
+
+ fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
+ max_dss_fck);
+
+ dss_cinfo.fck_div = fck_div;
+
+ r = dss_calc_clock_rates(&dss_cinfo);
+ if (r)
+ return r;
+
+ r = dss_set_clock_div(&dss_cinfo);
+ if (r)
+ return r;
+
+ return 0;
+}
+
int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
struct dispc_clock_info *dispc_cinfo)
{
@@ -697,11 +778,15 @@ static int dss_get_clocks(void)
dss.dss_clk = clk;
- clk = clk_get(NULL, dss.feat->clk_name);
- if (IS_ERR(clk)) {
- DSSERR("Failed to get %s\n", dss.feat->clk_name);
- r = PTR_ERR(clk);
- goto err;
+ if (dss.feat->clk_name) {
+ clk = clk_get(NULL, dss.feat->clk_name);
+ if (IS_ERR(clk)) {
+ DSSERR("Failed to get %s\n", dss.feat->clk_name);
+ r = PTR_ERR(clk);
+ goto err;
+ }
+ } else {
+ clk = NULL;
}
dss.dpll4_m4_ck = clk;
@@ -746,7 +831,7 @@ static void dss_runtime_put(void)
}
/* DEBUGFS */
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
+#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
void dss_debug_dump_clocks(struct seq_file *s)
{
dss_dump_clocks(s);
@@ -792,29 +877,45 @@ static const struct dss_features omap54xx_dss_feats __initconst = {
.dpi_select_source = &dss_dpi_select_source_omap5,
};
-static int __init dss_init_features(struct device *dev)
+static int __init dss_init_features(struct platform_device *pdev)
{
const struct dss_features *src;
struct dss_features *dst;
- dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
+ dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
if (!dst) {
- dev_err(dev, "Failed to allocate local DSS Features\n");
+ dev_err(&pdev->dev, "Failed to allocate local DSS Features\n");
return -ENOMEM;
}
- if (cpu_is_omap24xx())
+ switch (omapdss_get_version()) {
+ case OMAPDSS_VER_OMAP24xx:
src = &omap24xx_dss_feats;
- else if (cpu_is_omap34xx())
+ break;
+
+ case OMAPDSS_VER_OMAP34xx_ES1:
+ case OMAPDSS_VER_OMAP34xx_ES3:
+ case OMAPDSS_VER_AM35xx:
src = &omap34xx_dss_feats;
- else if (cpu_is_omap3630())
+ break;
+
+ case OMAPDSS_VER_OMAP3630:
src = &omap3630_dss_feats;
- else if (cpu_is_omap44xx())
+ break;
+
+ case OMAPDSS_VER_OMAP4430_ES1:
+ case OMAPDSS_VER_OMAP4430_ES2:
+ case OMAPDSS_VER_OMAP4:
src = &omap44xx_dss_feats;
- else if (soc_is_omap54xx())
+ break;
+
+ case OMAPDSS_VER_OMAP5:
src = &omap54xx_dss_feats;
- else
+ break;
+
+ default:
return -ENODEV;
+ }
memcpy(dst, src, sizeof(*dst));
dss.feat = dst;
@@ -831,7 +932,7 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
dss.pdev = pdev;
- r = dss_init_features(&dss.pdev->dev);
+ r = dss_init_features(dss.pdev);
if (r)
return r;
@@ -852,15 +953,23 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
if (r)
return r;
+ r = dss_setup_default_clock();
+ if (r)
+ goto err_setup_clocks;
+
pm_runtime_enable(&pdev->dev);
r = dss_runtime_get();
if (r)
goto err_runtime_get;
+ dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
+
/* Select DPLL */
REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
+ dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
+
#ifdef CONFIG_OMAP2_DSS_VENC
REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */
REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
@@ -884,6 +993,7 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
err_runtime_get:
pm_runtime_disable(&pdev->dev);
+err_setup_clocks:
dss_put_clocks();
return r;
}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 6728892..610c8e5 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -23,44 +23,20 @@
#ifndef __OMAP2_DSS_H
#define __OMAP2_DSS_H
-#ifdef CONFIG_OMAP2_DSS_DEBUG_SUPPORT
-#define DEBUG
-#endif
+#include <linux/interrupt.h>
-#ifdef DEBUG
-extern bool dss_debug;
-#ifdef DSS_SUBSYS_NAME
-#define DSSDBG(format, ...) \
- if (dss_debug) \
- printk(KERN_DEBUG "omapdss " DSS_SUBSYS_NAME ": " format, \
- ## __VA_ARGS__)
-#else
-#define DSSDBG(format, ...) \
- if (dss_debug) \
- printk(KERN_DEBUG "omapdss: " format, ## __VA_ARGS__)
+#ifdef pr_fmt
+#undef pr_fmt
#endif
#ifdef DSS_SUBSYS_NAME
-#define DSSDBGF(format, ...) \
- if (dss_debug) \
- printk(KERN_DEBUG "omapdss " DSS_SUBSYS_NAME \
- ": %s(" format ")\n", \
- __func__, \
- ## __VA_ARGS__)
+#define pr_fmt(fmt) DSS_SUBSYS_NAME ": " fmt
#else
-#define DSSDBGF(format, ...) \
- if (dss_debug) \
- printk(KERN_DEBUG "omapdss: " \
- ": %s(" format ")\n", \
- __func__, \
- ## __VA_ARGS__)
-#endif
-
-#else /* DEBUG */
-#define DSSDBG(format, ...)
-#define DSSDBGF(format, ...)
+#define pr_fmt(fmt) fmt
#endif
+#define DSSDBG(format, ...) \
+ pr_debug(format, ## __VA_ARGS__)
#ifdef DSS_SUBSYS_NAME
#define DSSERR(format, ...) \
@@ -186,11 +162,10 @@ struct seq_file;
struct platform_device;
/* core */
-const char *dss_get_default_display_name(void);
+struct platform_device *dss_get_core_pdev(void);
struct bus_type *dss_get_bus(void);
struct regulator *dss_get_vdds_dsi(void);
struct regulator *dss_get_vdds_sdi(void);
-int dss_get_ctx_loss_count(struct device *dev);
int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask);
void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask);
int dss_set_min_bus_tput(struct device *dev, unsigned long tput);
@@ -204,55 +179,18 @@ void dss_put_device(struct omap_dss_device *dssdev);
void dss_copy_device_pdata(struct omap_dss_device *dst,
const struct omap_dss_device *src);
-/* apply */
-void dss_apply_init(void);
-int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr);
-int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
-void dss_mgr_start_update(struct omap_overlay_manager *mgr);
-int omap_dss_mgr_apply(struct omap_overlay_manager *mgr);
-
-int dss_mgr_enable(struct omap_overlay_manager *mgr);
-void dss_mgr_disable(struct omap_overlay_manager *mgr);
-int dss_mgr_set_info(struct omap_overlay_manager *mgr,
- struct omap_overlay_manager_info *info);
-void dss_mgr_get_info(struct omap_overlay_manager *mgr,
- struct omap_overlay_manager_info *info);
-int dss_mgr_set_device(struct omap_overlay_manager *mgr,
- struct omap_dss_device *dssdev);
-int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
-int dss_mgr_set_output(struct omap_overlay_manager *mgr,
- struct omap_dss_output *output);
-int dss_mgr_unset_output(struct omap_overlay_manager *mgr);
-void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
- const struct omap_video_timings *timings);
-void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
- const struct dss_lcd_mgr_config *config);
-const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr);
-
-bool dss_ovl_is_enabled(struct omap_overlay *ovl);
-int dss_ovl_enable(struct omap_overlay *ovl);
-int dss_ovl_disable(struct omap_overlay *ovl);
-int dss_ovl_set_info(struct omap_overlay *ovl,
- struct omap_overlay_info *info);
-void dss_ovl_get_info(struct omap_overlay *ovl,
- struct omap_overlay_info *info);
-int dss_ovl_set_manager(struct omap_overlay *ovl,
- struct omap_overlay_manager *mgr);
-int dss_ovl_unset_manager(struct omap_overlay *ovl);
-
/* output */
void dss_register_output(struct omap_dss_output *out);
void dss_unregister_output(struct omap_dss_output *out);
-struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev);
/* display */
int dss_suspend_all_devices(void);
int dss_resume_all_devices(void);
void dss_disable_all_devices(void);
-int dss_init_device(struct platform_device *pdev,
+int display_init_sysfs(struct platform_device *pdev,
struct omap_dss_device *dssdev);
-void dss_uninit_device(struct platform_device *pdev,
+void display_uninit_sysfs(struct platform_device *pdev,
struct omap_dss_device *dssdev);
/* manager */
@@ -299,21 +237,23 @@ void dss_overlay_kobj_uninit(struct omap_overlay *ovl);
int dss_init_platform_driver(void) __init;
void dss_uninit_platform_driver(void);
+unsigned long dss_get_dispc_clk_rate(void);
int dss_dpi_select_source(enum omap_channel channel);
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
void dss_dump_clocks(struct seq_file *s);
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
+#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
void dss_debug_dump_clocks(struct seq_file *s);
#endif
+int dss_get_ctx_loss_count(void);
+
void dss_sdi_init(int datapairs);
int dss_sdi_enable(void);
void dss_sdi_disable(void);
-void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src);
void dss_select_dsi_clk_source(int dsi_module,
enum omap_dss_clk_source clk_src);
void dss_select_lcd_clk_source(enum omap_channel channel,
@@ -326,6 +266,7 @@ void dss_set_venc_output(enum omap_dss_venc_type type);
void dss_set_dac_pwrdn_bgz(bool enable);
unsigned long dss_get_dpll4_rate(void);
+int dss_calc_clock_rates(struct dss_clock_info *cinfo);
int dss_set_clock_div(struct dss_clock_info *cinfo);
int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
struct dispc_clock_info *dispc_cinfo);
@@ -413,8 +354,6 @@ static inline void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev)
}
static inline struct platform_device *dsi_get_dsidev_from_id(int module)
{
- WARN("%s: DSI not compiled in, returning platform device as NULL\n",
- __func__);
return NULL;
}
#endif
@@ -427,15 +366,10 @@ void dpi_uninit_platform_driver(void) __exit;
int dispc_init_platform_driver(void) __init;
void dispc_uninit_platform_driver(void) __exit;
void dispc_dump_clocks(struct seq_file *s);
-void dispc_irq_handler(void);
-
-int dispc_runtime_get(void);
-void dispc_runtime_put(void);
void dispc_enable_sidle(void);
void dispc_disable_sidle(void);
-void dispc_lcd_enable_signal_polarity(bool act_high);
void dispc_lcd_enable_signal(bool enable);
void dispc_pck_free_enable(bool enable);
void dispc_enable_fifomerge(bool enable);
@@ -455,36 +389,14 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
bool manual_update);
-int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
- bool replication, const struct omap_video_timings *mgr_timings,
- bool mem_to_mem);
-int dispc_ovl_enable(enum omap_plane plane, bool enable);
-void dispc_ovl_set_channel_out(enum omap_plane plane,
- enum omap_channel channel);
-
-void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable);
-u32 dispc_mgr_get_vsync_irq(enum omap_channel channel);
-u32 dispc_mgr_get_framedone_irq(enum omap_channel channel);
-bool dispc_mgr_go_busy(enum omap_channel channel);
-void dispc_mgr_go(enum omap_channel channel);
-bool dispc_mgr_is_enabled(enum omap_channel channel);
-void dispc_mgr_enable(enum omap_channel channel, bool enable);
-bool dispc_mgr_is_channel_enabled(enum omap_channel channel);
-void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode);
-void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable);
-void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
-void dispc_mgr_set_lcd_type_tft(enum omap_channel channel);
-void dispc_mgr_set_timings(enum omap_channel channel,
- struct omap_video_timings *timings);
+
unsigned long dispc_mgr_lclk_rate(enum omap_channel channel);
unsigned long dispc_mgr_pclk_rate(enum omap_channel channel);
unsigned long dispc_core_clk_rate(void);
void dispc_mgr_set_clock_div(enum omap_channel channel,
- struct dispc_clock_info *cinfo);
+ const struct dispc_clock_info *cinfo);
int dispc_mgr_get_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo);
-void dispc_mgr_setup(enum omap_channel channel,
- struct omap_overlay_manager_info *info);
u32 dispc_wb_get_framedone_irq(void);
bool dispc_wb_go_busy(void);
@@ -536,6 +448,8 @@ static inline unsigned long hdmi_get_pixel_clock(void)
#endif
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
+int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev);
+void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev);
void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index acbc1e1..d7d66ef 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -18,12 +18,12 @@
*/
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/types.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <video/omapdss.h>
-#include <plat/cpu.h>
#include "dss.h"
#include "dss_features.h"
@@ -430,8 +430,6 @@ static const struct dss_param_range omap2_dss_param_range[] = {
* scaler cannot scale a image with width more than 768.
*/
[FEAT_PARAM_LINEWIDTH] = { 1, 768 },
- [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
- [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 },
};
static const struct dss_param_range omap3_dss_param_range[] = {
@@ -446,8 +444,6 @@ static const struct dss_param_range omap3_dss_param_range[] = {
[FEAT_PARAM_DSI_FCK] = { 0, 173000000 },
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
[FEAT_PARAM_LINEWIDTH] = { 1, 1024 },
- [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
- [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 },
};
static const struct dss_param_range omap4_dss_param_range[] = {
@@ -462,8 +458,6 @@ static const struct dss_param_range omap4_dss_param_range[] = {
[FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
[FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
- [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
- [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 },
};
static const struct dss_param_range omap5_dss_param_range[] = {
@@ -478,8 +472,6 @@ static const struct dss_param_range omap5_dss_param_range[] = {
[FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
[FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
- [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
- [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 },
};
static const enum dss_feat_id omap2_dss_feat_list[] = {
@@ -546,6 +538,7 @@ static const enum dss_feat_id omap3630_dss_feat_list[] = {
FEAT_ALPHA_FIXED_ZORDER,
FEAT_FIFO_MERGE,
FEAT_OMAP3_DSI_FIFO_BUG,
+ FEAT_DPI_USES_VDDS_DSI,
};
static const enum dss_feat_id omap4430_es1_0_dss_feat_list[] = {
@@ -821,14 +814,25 @@ static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
.audio_start = ti_hdmi_4xxx_audio_start,
.audio_stop = ti_hdmi_4xxx_audio_stop,
.audio_config = ti_hdmi_4xxx_audio_config,
+ .audio_get_dma_port = ti_hdmi_4xxx_audio_get_dma_port,
#endif
};
-void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data)
+void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data,
+ enum omapdss_version version)
{
- if (cpu_is_omap44xx())
+ switch (version) {
+ case OMAPDSS_VER_OMAP4430_ES1:
+ case OMAPDSS_VER_OMAP4430_ES2:
+ case OMAPDSS_VER_OMAP4:
ip_data->ops = &omap4_hdmi_functions;
+ break;
+ default:
+ ip_data->ops = NULL;
+ }
+
+ WARN_ON(ip_data->ops == NULL);
}
#endif
@@ -837,11 +841,13 @@ int dss_feat_get_num_mgrs(void)
{
return omap_current_dss_features->num_mgrs;
}
+EXPORT_SYMBOL(dss_feat_get_num_mgrs);
int dss_feat_get_num_ovls(void)
{
return omap_current_dss_features->num_ovls;
}
+EXPORT_SYMBOL(dss_feat_get_num_ovls);
int dss_feat_get_num_wbs(void)
{
@@ -862,16 +868,19 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel
{
return omap_current_dss_features->supported_displays[channel];
}
+EXPORT_SYMBOL(dss_feat_get_supported_displays);
enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel)
{
return omap_current_dss_features->supported_outputs[channel];
}
+EXPORT_SYMBOL(dss_feat_get_supported_outputs);
enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
{
return omap_current_dss_features->supported_color_modes[plane];
}
+EXPORT_SYMBOL(dss_feat_get_supported_color_modes);
enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane)
{
@@ -929,29 +938,44 @@ bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type)
return omap_current_dss_features->supported_rotation_types & rot_type;
}
-void dss_features_init(void)
+void dss_features_init(enum omapdss_version version)
{
- if (cpu_is_omap24xx())
+ switch (version) {
+ case OMAPDSS_VER_OMAP24xx:
omap_current_dss_features = &omap2_dss_features;
- else if (cpu_is_omap3630())
+ break;
+
+ case OMAPDSS_VER_OMAP34xx_ES1:
+ case OMAPDSS_VER_OMAP34xx_ES3:
+ omap_current_dss_features = &omap3430_dss_features;
+ break;
+
+ case OMAPDSS_VER_OMAP3630:
omap_current_dss_features = &omap3630_dss_features;
- else if (cpu_is_omap34xx()) {
- if (soc_is_am35xx()) {
- omap_current_dss_features = &am35xx_dss_features;
- } else {
- omap_current_dss_features = &omap3430_dss_features;
- }
- }
- else if (omap_rev() == OMAP4430_REV_ES1_0)
+ break;
+
+ case OMAPDSS_VER_OMAP4430_ES1:
omap_current_dss_features = &omap4430_es1_0_dss_features;
- else if (omap_rev() == OMAP4430_REV_ES2_0 ||
- omap_rev() == OMAP4430_REV_ES2_1 ||
- omap_rev() == OMAP4430_REV_ES2_2)
+ break;
+
+ case OMAPDSS_VER_OMAP4430_ES2:
omap_current_dss_features = &omap4430_es2_0_1_2_dss_features;
- else if (cpu_is_omap44xx())
+ break;
+
+ case OMAPDSS_VER_OMAP4:
omap_current_dss_features = &omap4_dss_features;
- else if (soc_is_omap54xx())
+ break;
+
+ case OMAPDSS_VER_OMAP5:
omap_current_dss_features = &omap5_dss_features;
- else
+ break;
+
+ case OMAPDSS_VER_AM35xx:
+ omap_current_dss_features = &am35xx_dss_features;
+ break;
+
+ default:
DSSWARN("Unsupported OMAP version");
+ break;
+ }
}
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 9218113..489b9be 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -98,19 +98,12 @@ enum dss_range_param {
FEAT_PARAM_DSI_FCK,
FEAT_PARAM_DOWNSCALE,
FEAT_PARAM_LINEWIDTH,
- FEAT_PARAM_MGR_WIDTH,
- FEAT_PARAM_MGR_HEIGHT,
};
/* DSS Feature Functions */
-int dss_feat_get_num_mgrs(void);
-int dss_feat_get_num_ovls(void);
int dss_feat_get_num_wbs(void);
unsigned long dss_feat_get_param_min(enum dss_range_param param);
unsigned long dss_feat_get_param_max(enum dss_range_param param);
-enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
-enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
-enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
bool dss_feat_color_mode_supported(enum omap_plane plane,
enum omap_color_mode color_mode);
@@ -123,8 +116,9 @@ bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type);
bool dss_has_feature(enum dss_feat_id id);
void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
-void dss_features_init(void);
+void dss_features_init(enum omapdss_version version);
#if defined(CONFIG_OMAP4_DSS_HDMI)
-void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data);
+void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data,
+ enum omapdss_version version);
#endif
#endif
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index a48a7dd..72923645 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -60,6 +60,7 @@
static struct {
struct mutex lock;
struct platform_device *pdev;
+
struct hdmi_ip_data ip_data;
struct clk *sys_clk;
@@ -295,6 +296,12 @@ static const struct hdmi_config vesa_timings[] = {
false, },
{ 0x55, HDMI_DVI },
},
+ {
+ { 1920, 1200, 154000, 32, 48, 80, 6, 3, 26,
+ OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
+ false, },
+ { 0x44, HDMI_DVI },
+ },
};
static int hdmi_runtime_get(void)
@@ -333,13 +340,17 @@ static int __init hdmi_init_display(struct omap_dss_device *dssdev)
DSSDBG("init_display\n");
- dss_init_hdmi_ip_ops(&hdmi.ip_data);
+ dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version());
if (hdmi.vdda_hdmi_dac_reg == NULL) {
struct regulator *reg;
reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
+ /* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */
+ if (IS_ERR(reg))
+ reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC");
+
if (IS_ERR(reg)) {
DSSERR("can't get VDDA_HDMI_DAC regulator\n");
return PTR_ERR(reg);
@@ -355,7 +366,7 @@ static int __init hdmi_init_display(struct omap_dss_device *dssdev)
return 0;
}
-static void __exit hdmi_uninit_display(struct omap_dss_device *dssdev)
+static void hdmi_uninit_display(struct omap_dss_device *dssdev)
{
DSSDBG("uninit_display\n");
@@ -398,7 +409,8 @@ static bool hdmi_timings_compare(struct omap_video_timings *timing1,
{
int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
- if ((timing2->pixel_clock == timing1->pixel_clock) &&
+ if ((DIV_ROUND_CLOSEST(timing2->pixel_clock, 1000) ==
+ DIV_ROUND_CLOSEST(timing1->pixel_clock, 1000)) &&
(timing2->x_res == timing1->x_res) &&
(timing2->y_res == timing1->y_res)) {
@@ -500,12 +512,9 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
}
-static int hdmi_power_on(struct omap_dss_device *dssdev)
+static int hdmi_power_on_core(struct omap_dss_device *dssdev)
{
int r;
- struct omap_video_timings *p;
- struct omap_overlay_manager *mgr = dssdev->output->manager;
- unsigned long phy;
gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
gpio_set_value(hdmi.ls_oe_gpio, 1);
@@ -521,6 +530,38 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
if (r)
goto err_runtime_get;
+ /* Make selection of HDMI in DSS */
+ dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
+
+ return 0;
+
+err_runtime_get:
+ regulator_disable(hdmi.vdda_hdmi_dac_reg);
+err_vdac_enable:
+ gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
+ gpio_set_value(hdmi.ls_oe_gpio, 0);
+ return r;
+}
+
+static void hdmi_power_off_core(struct omap_dss_device *dssdev)
+{
+ hdmi_runtime_put();
+ regulator_disable(hdmi.vdda_hdmi_dac_reg);
+ gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
+ gpio_set_value(hdmi.ls_oe_gpio, 0);
+}
+
+static int hdmi_power_on_full(struct omap_dss_device *dssdev)
+{
+ int r;
+ struct omap_video_timings *p;
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
+ unsigned long phy;
+
+ r = hdmi_power_on_core(dssdev);
+ if (r)
+ return r;
+
dss_mgr_disable(mgr);
p = &hdmi.ip_data.cfg.timings;
@@ -548,17 +589,6 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
- /* Make selection of HDMI in DSS */
- dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
-
- /* Select the dispc clock source as PRCM clock, to ensure that it is not
- * DSI PLL source as the clock selected by DSI PLL might not be
- * sufficient for the resolution selected / that can be changed
- * dynamically by user. This can be moved to single location , say
- * Boardfile.
- */
- dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
-
/* bypass TV gamma table */
dispc_enable_gamma_table(0);
@@ -582,16 +612,11 @@ err_vid_enable:
err_phy_enable:
hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
err_pll_enable:
- hdmi_runtime_put();
-err_runtime_get:
- regulator_disable(hdmi.vdda_hdmi_dac_reg);
-err_vdac_enable:
- gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
- gpio_set_value(hdmi.ls_oe_gpio, 0);
+ hdmi_power_off_core(dssdev);
return -EIO;
}
-static void hdmi_power_off(struct omap_dss_device *dssdev)
+static void hdmi_power_off_full(struct omap_dss_device *dssdev)
{
struct omap_overlay_manager *mgr = dssdev->output->manager;
@@ -600,12 +625,8 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
- hdmi_runtime_put();
- regulator_disable(hdmi.vdda_hdmi_dac_reg);
-
- gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
- gpio_set_value(hdmi.ls_oe_gpio, 0);
+ hdmi_power_off_core(dssdev);
}
int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
@@ -644,8 +665,10 @@ static void hdmi_dump_regs(struct seq_file *s)
{
mutex_lock(&hdmi.lock);
- if (hdmi_runtime_get())
+ if (hdmi_runtime_get()) {
+ mutex_unlock(&hdmi.lock);
return;
+ }
hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s);
hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s);
@@ -713,7 +736,7 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
goto err0;
}
- r = hdmi_power_on(dssdev);
+ r = hdmi_power_on_full(dssdev);
if (r) {
DSSERR("failed to power on device\n");
goto err1;
@@ -735,13 +758,48 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
mutex_lock(&hdmi.lock);
- hdmi_power_off(dssdev);
+ hdmi_power_off_full(dssdev);
omap_dss_stop_device(dssdev);
mutex_unlock(&hdmi.lock);
}
+int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev)
+{
+ int r = 0;
+
+ DSSDBG("ENTER omapdss_hdmi_core_enable\n");
+
+ mutex_lock(&hdmi.lock);
+
+ hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
+
+ r = hdmi_power_on_core(dssdev);
+ if (r) {
+ DSSERR("failed to power on device\n");
+ goto err0;
+ }
+
+ mutex_unlock(&hdmi.lock);
+ return 0;
+
+err0:
+ mutex_unlock(&hdmi.lock);
+ return r;
+}
+
+void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev)
+{
+ DSSDBG("Enter omapdss_hdmi_core_disable\n");
+
+ mutex_lock(&hdmi.lock);
+
+ hdmi_power_off_core(dssdev);
+
+ mutex_unlock(&hdmi.lock);
+}
+
static int hdmi_get_clocks(struct platform_device *pdev)
{
struct clk *clk;
@@ -910,7 +968,7 @@ int hdmi_audio_config(struct omap_dss_audio *audio)
static struct omap_dss_device * __init hdmi_find_dssdev(struct platform_device *pdev)
{
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
- const char *def_disp_name = dss_get_default_display_name();
+ const char *def_disp_name = omapdss_get_default_display_name();
struct omap_dss_device *def_dssdev;
int i;
@@ -968,9 +1026,19 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
return;
}
+ r = omapdss_output_set_device(&hdmi.output, dssdev);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dssdev->name);
+ dss_put_device(dssdev);
+ return;
+ }
+
r = dss_add_device(dssdev);
if (r) {
DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ omapdss_output_unset_device(&hdmi.output);
+ hdmi_uninit_display(dssdev);
dss_put_device(dssdev);
return;
}
@@ -997,30 +1065,28 @@ static void __exit hdmi_uninit_output(struct platform_device *pdev)
/* HDMI HW IP initialisation */
static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
{
- struct resource *hdmi_mem;
+ struct resource *res;
int r;
hdmi.pdev = pdev;
mutex_init(&hdmi.lock);
+ mutex_init(&hdmi.ip_data.lock);
- hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
- if (!hdmi_mem) {
+ res = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
+ if (!res) {
DSSERR("can't get IORESOURCE_MEM HDMI\n");
return -EINVAL;
}
/* Base address taken from platform */
- hdmi.ip_data.base_wp = ioremap(hdmi_mem->start,
- resource_size(hdmi_mem));
- if (!hdmi.ip_data.base_wp) {
- DSSERR("can't ioremap WP\n");
- return -ENOMEM;
- }
+ hdmi.ip_data.base_wp = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(hdmi.ip_data.base_wp))
+ return PTR_ERR(hdmi.ip_data.base_wp);
r = hdmi_get_clocks(pdev);
if (r) {
- iounmap(hdmi.ip_data.base_wp);
+ DSSERR("can't get clocks\n");
return r;
}
@@ -1031,9 +1097,11 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
hdmi.ip_data.phy_offset = HDMI_PHY;
- mutex_init(&hdmi.ip_data.lock);
-
- hdmi_panel_init();
+ r = hdmi_panel_init();
+ if (r) {
+ DSSERR("can't init panel\n");
+ goto err_panel_init;
+ }
dss_debugfs_create_file("hdmi", hdmi_dump_regs);
@@ -1042,6 +1110,10 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
hdmi_probe_pdata(pdev);
return 0;
+
+err_panel_init:
+ hdmi_put_clocks();
+ return r;
}
static int __exit hdmi_remove_child(struct device *dev, void *data)
@@ -1065,8 +1137,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
hdmi_put_clocks();
- iounmap(hdmi.ip_data.base_wp);
-
return 0;
}
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index 69fb115..dfb8eda 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -280,58 +280,6 @@ static void hdmi_panel_disable(struct omap_dss_device *dssdev)
mutex_unlock(&hdmi.lock);
}
-static int hdmi_panel_suspend(struct omap_dss_device *dssdev)
-{
- int r = 0;
-
- mutex_lock(&hdmi.lock);
-
- if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
- r = -EINVAL;
- goto err;
- }
-
- /*
- * TODO: notify audio users that the display was suspended. For now,
- * disable audio locally to not break our audio state machine.
- */
- hdmi_panel_audio_disable(dssdev);
-
- dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
- omapdss_hdmi_display_disable(dssdev);
-
-err:
- mutex_unlock(&hdmi.lock);
-
- return r;
-}
-
-static int hdmi_panel_resume(struct omap_dss_device *dssdev)
-{
- int r = 0;
-
- mutex_lock(&hdmi.lock);
-
- if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
- r = -EINVAL;
- goto err;
- }
-
- r = omapdss_hdmi_display_enable(dssdev);
- if (r) {
- DSSERR("failed to power on\n");
- goto err;
- }
- /* TODO: notify audio users that the panel resumed. */
-
- dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-err:
- mutex_unlock(&hdmi.lock);
-
- return r;
-}
-
static void hdmi_get_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
@@ -379,20 +327,22 @@ static int hdmi_check_timings(struct omap_dss_device *dssdev,
static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len)
{
int r;
+ bool need_enable;
mutex_lock(&hdmi.lock);
- if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
- r = omapdss_hdmi_display_enable(dssdev);
+ need_enable = dssdev->state == OMAP_DSS_DISPLAY_DISABLED;
+
+ if (need_enable) {
+ r = omapdss_hdmi_core_enable(dssdev);
if (r)
goto err;
}
r = omapdss_hdmi_read_edid(buf, len);
- if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
- dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
- omapdss_hdmi_display_disable(dssdev);
+ if (need_enable)
+ omapdss_hdmi_core_disable(dssdev);
err:
mutex_unlock(&hdmi.lock);
@@ -402,20 +352,22 @@ err:
static bool hdmi_detect(struct omap_dss_device *dssdev)
{
int r;
+ bool need_enable;
mutex_lock(&hdmi.lock);
- if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
- r = omapdss_hdmi_display_enable(dssdev);
+ need_enable = dssdev->state == OMAP_DSS_DISPLAY_DISABLED;
+
+ if (need_enable) {
+ r = omapdss_hdmi_core_enable(dssdev);
if (r)
goto err;
}
r = omapdss_hdmi_detect();
- if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
- dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
- omapdss_hdmi_display_disable(dssdev);
+ if (need_enable)
+ omapdss_hdmi_core_disable(dssdev);
err:
mutex_unlock(&hdmi.lock);
@@ -427,8 +379,6 @@ static struct omap_dss_driver hdmi_driver = {
.remove = hdmi_panel_remove,
.enable = hdmi_panel_enable,
.disable = hdmi_panel_disable,
- .suspend = hdmi_panel_suspend,
- .resume = hdmi_panel_resume,
.get_timings = hdmi_get_timings,
.set_timings = hdmi_set_timings,
.check_timings = hdmi_check_timings,
@@ -454,9 +404,7 @@ int hdmi_panel_init(void)
spin_lock_init(&hdmi.audio_lock);
#endif
- omap_dss_register_driver(&hdmi_driver);
-
- return 0;
+ return omap_dss_register_driver(&hdmi_driver);
}
void hdmi_panel_exit(void)
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index c54d2f6..2551eaa 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -36,36 +36,6 @@
static int num_managers;
static struct omap_overlay_manager *managers;
-static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
-{
- return mgr->output ? mgr->output->device : NULL;
-}
-
-static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
-{
- unsigned long timeout = msecs_to_jiffies(500);
- struct omap_dss_device *dssdev = mgr->get_device(mgr);
- u32 irq;
- int r;
-
- r = dispc_runtime_get();
- if (r)
- return r;
-
- if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
- irq = DISPC_IRQ_EVSYNC_ODD;
- else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI)
- irq = DISPC_IRQ_EVSYNC_EVEN;
- else
- irq = dispc_mgr_get_vsync_irq(mgr->id);
-
- r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
-
- dispc_runtime_put();
-
- return r;
-}
-
int dss_init_overlay_managers(struct platform_device *pdev)
{
int i, r;
@@ -99,15 +69,6 @@ int dss_init_overlay_managers(struct platform_device *pdev)
break;
}
- mgr->set_output = &dss_mgr_set_output;
- mgr->unset_output = &dss_mgr_unset_output;
- mgr->apply = &omap_dss_mgr_apply;
- mgr->set_manager_info = &dss_mgr_set_info;
- mgr->get_manager_info = &dss_mgr_get_info;
- mgr->wait_for_go = &dss_mgr_wait_for_go;
- mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
- mgr->get_device = &dss_mgr_get_device;
-
mgr->caps = 0;
mgr->supported_displays =
dss_feat_get_supported_displays(mgr->id);
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index 813f266..79dea1a 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -114,35 +114,67 @@ struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
return NULL;
}
-struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev)
+static const struct dss_mgr_ops *dss_mgr_ops;
+
+int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops)
{
- struct omap_dss_output *out = NULL;
- enum omap_dss_output_id id;
-
- switch (dssdev->type) {
- case OMAP_DISPLAY_TYPE_DPI:
- out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI);
- break;
- case OMAP_DISPLAY_TYPE_DBI:
- out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI);
- break;
- case OMAP_DISPLAY_TYPE_SDI:
- out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI);
- break;
- case OMAP_DISPLAY_TYPE_VENC:
- out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC);
- break;
- case OMAP_DISPLAY_TYPE_HDMI:
- out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI);
- break;
- case OMAP_DISPLAY_TYPE_DSI:
- id = dssdev->phy.dsi.module == 0 ? OMAP_DSS_OUTPUT_DSI1 :
- OMAP_DSS_OUTPUT_DSI2;
- out = omap_dss_get_output(id);
- break;
- default:
- break;
- }
+ if (dss_mgr_ops)
+ return -EBUSY;
+
+ dss_mgr_ops = mgr_ops;
+
+ return 0;
+}
+EXPORT_SYMBOL(dss_install_mgr_ops);
+
+void dss_uninstall_mgr_ops(void)
+{
+ dss_mgr_ops = NULL;
+}
+EXPORT_SYMBOL(dss_uninstall_mgr_ops);
+
+void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
+ const struct omap_video_timings *timings)
+{
+ dss_mgr_ops->set_timings(mgr, timings);
+}
+EXPORT_SYMBOL(dss_mgr_set_timings);
+
+void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
+ const struct dss_lcd_mgr_config *config)
+{
+ dss_mgr_ops->set_lcd_config(mgr, config);
+}
+EXPORT_SYMBOL(dss_mgr_set_lcd_config);
+
+int dss_mgr_enable(struct omap_overlay_manager *mgr)
+{
+ return dss_mgr_ops->enable(mgr);
+}
+EXPORT_SYMBOL(dss_mgr_enable);
+
+void dss_mgr_disable(struct omap_overlay_manager *mgr)
+{
+ dss_mgr_ops->disable(mgr);
+}
+EXPORT_SYMBOL(dss_mgr_disable);
- return out;
+void dss_mgr_start_update(struct omap_overlay_manager *mgr)
+{
+ dss_mgr_ops->start_update(mgr);
+}
+EXPORT_SYMBOL(dss_mgr_start_update);
+
+int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr,
+ void (*handler)(void *), void *data)
+{
+ return dss_mgr_ops->register_framedone_handler(mgr, handler, data);
+}
+EXPORT_SYMBOL(dss_mgr_register_framedone_handler);
+
+void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr,
+ void (*handler)(void *), void *data)
+{
+ dss_mgr_ops->unregister_framedone_handler(mgr, handler, data);
}
+EXPORT_SYMBOL(dss_mgr_unregister_framedone_handler);
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 45f4994..eccde32 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -38,13 +38,6 @@
static int num_overlays;
static struct omap_overlay *overlays;
-static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl)
-{
- return ovl->manager ?
- (ovl->manager->output ? ovl->manager->output->device : NULL) :
- NULL;
-}
-
int omap_dss_get_num_overlays(void)
{
return num_overlays;
@@ -93,16 +86,6 @@ void dss_init_overlays(struct platform_device *pdev)
break;
}
- ovl->is_enabled = &dss_ovl_is_enabled;
- ovl->enable = &dss_ovl_enable;
- ovl->disable = &dss_ovl_disable;
- ovl->set_manager = &dss_ovl_set_manager;
- ovl->unset_manager = &dss_ovl_unset_manager;
- ovl->set_overlay_info = &dss_ovl_set_info;
- ovl->get_overlay_info = &dss_ovl_get_info;
- ovl->wait_for_go = &dss_mgr_wait_for_go_ovl;
- ovl->get_device = &dss_ovl_get_device;
-
ovl->caps = dss_feat_get_overlay_caps(ovl->id);
ovl->supported_modes =
dss_feat_get_supported_color_modes(ovl->id);
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 7282e5a..e903dd3 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -342,7 +342,7 @@ static int rfbi_transfer_area(struct omap_dss_device *dssdev,
return 0;
}
-static void framedone_callback(void *data, u32 mask)
+static void framedone_callback(void *data)
{
void (*callback)(void *data);
@@ -908,8 +908,8 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
goto err0;
}
- r = omap_dispc_register_isr(framedone_callback, NULL,
- DISPC_IRQ_FRAMEDONE);
+ r = dss_mgr_register_framedone_handler(out->manager,
+ framedone_callback, NULL);
if (r) {
DSSERR("can't get FRAMEDONE irq\n");
goto err1;
@@ -933,8 +933,10 @@ EXPORT_SYMBOL(omapdss_rfbi_display_enable);
void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
{
- omap_dispc_unregister_isr(framedone_callback, NULL,
- DISPC_IRQ_FRAMEDONE);
+ struct omap_dss_output *out = dssdev->output;
+
+ dss_mgr_unregister_framedone_handler(out->manager,
+ framedone_callback, NULL);
omap_dss_stop_device(dssdev);
rfbi_runtime_put();
@@ -950,7 +952,7 @@ static int __init rfbi_init_display(struct omap_dss_device *dssdev)
static struct omap_dss_device * __init rfbi_find_dssdev(struct platform_device *pdev)
{
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
- const char *def_disp_name = dss_get_default_display_name();
+ const char *def_disp_name = omapdss_get_default_display_name();
struct omap_dss_device *def_dssdev;
int i;
@@ -999,9 +1001,18 @@ static void __init rfbi_probe_pdata(struct platform_device *rfbidev)
return;
}
+ r = omapdss_output_set_device(&rfbi.output, dssdev);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dssdev->name);
+ dss_put_device(dssdev);
+ return;
+ }
+
r = dss_add_device(dssdev);
if (r) {
DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ omapdss_output_unset_device(&rfbi.output);
dss_put_device(dssdev);
return;
}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 7760851..62b5374 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -205,7 +205,7 @@ static int __init sdi_init_display(struct omap_dss_device *dssdev)
static struct omap_dss_device * __init sdi_find_dssdev(struct platform_device *pdev)
{
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
- const char *def_disp_name = dss_get_default_display_name();
+ const char *def_disp_name = omapdss_get_default_display_name();
struct omap_dss_device *def_dssdev;
int i;
@@ -254,9 +254,18 @@ static void __init sdi_probe_pdata(struct platform_device *sdidev)
return;
}
+ r = omapdss_output_set_device(&sdi.output, dssdev);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dssdev->name);
+ dss_put_device(dssdev);
+ return;
+ }
+
r = dss_add_device(dssdev);
if (r) {
DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ omapdss_output_unset_device(&sdi.output);
dss_put_device(dssdev);
return;
}
diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h
index b046c20..216aa70 100644
--- a/drivers/video/omap2/dss/ti_hdmi.h
+++ b/drivers/video/omap2/dss/ti_hdmi.h
@@ -102,6 +102,8 @@ struct ti_hdmi_ip_ops {
int (*audio_config)(struct hdmi_ip_data *ip_data,
struct omap_dss_audio *audio);
+
+ int (*audio_get_dma_port)(u32 *offset, u32 *size);
#endif
};
@@ -183,5 +185,6 @@ int ti_hdmi_4xxx_audio_start(struct hdmi_ip_data *ip_data);
void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data);
int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data,
struct omap_dss_audio *audio);
+int ti_hdmi_4xxx_audio_get_dma_port(u32 *offset, u32 *size);
#endif
#endif
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index c23b85a..e18b222 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -899,7 +899,7 @@ void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s)
#define DUMPCOREAV(r) seq_printf(s, "%-35s %08x\n", #r,\
hdmi_read_reg(hdmi_av_base(ip_data), r))
#define DUMPCOREAV2(i, r) seq_printf(s, "%s[%d]%*s %08x\n", #r, i, \
- (i < 10) ? 32 - strlen(#r) : 31 - strlen(#r), " ", \
+ (i < 10) ? 32 - (int)strlen(#r) : 31 - (int)strlen(#r), " ", \
hdmi_read_reg(hdmi_av_base(ip_data), CORE_REG(i, r)))
DUMPCORE(HDMI_CORE_SYS_VND_IDL);
@@ -1418,4 +1418,13 @@ void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data)
REG_FLD_MOD(hdmi_wp_base(ip_data),
HDMI_WP_AUDIO_CTRL, false, 30, 30);
}
+
+int ti_hdmi_4xxx_audio_get_dma_port(u32 *offset, u32 *size)
+{
+ if (!offset || !size)
+ return -EINVAL;
+ *offset = HDMI_WP_AUDIO_DATA;
+ *size = 4;
+ return 0;
+}
#endif
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 56efa3b..006caf3 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -744,7 +744,7 @@ static void venc_put_clocks(void)
static struct omap_dss_device * __init venc_find_dssdev(struct platform_device *pdev)
{
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
- const char *def_disp_name = dss_get_default_display_name();
+ const char *def_disp_name = omapdss_get_default_display_name();
struct omap_dss_device *def_dssdev;
int i;
@@ -795,9 +795,18 @@ static void __init venc_probe_pdata(struct platform_device *vencdev)
return;
}
+ r = omapdss_output_set_device(&venc.output, dssdev);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dssdev->name);
+ dss_put_device(dssdev);
+ return;
+ }
+
r = dss_add_device(dssdev);
if (r) {
DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ omapdss_output_unset_device(&venc.output);
dss_put_device(dssdev);
return;
}
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
index d55b878..0d2b1a0 100644
--- a/drivers/video/omap2/dss/venc_panel.c
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -157,12 +157,6 @@ static void venc_panel_disable(struct omap_dss_device *dssdev)
if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
goto end;
- if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
- /* suspended is the same as disabled with venc */
- dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
- goto end;
- }
-
omapdss_venc_display_disable(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
@@ -170,17 +164,6 @@ end:
mutex_unlock(&venc_panel.lock);
}
-static int venc_panel_suspend(struct omap_dss_device *dssdev)
-{
- venc_panel_disable(dssdev);
- return 0;
-}
-
-static int venc_panel_resume(struct omap_dss_device *dssdev)
-{
- return venc_panel_enable(dssdev);
-}
-
static void venc_panel_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
@@ -222,8 +205,6 @@ static struct omap_dss_driver venc_driver = {
.enable = venc_panel_enable,
.disable = venc_panel_disable,
- .suspend = venc_panel_suspend,
- .resume = venc_panel_resume,
.get_resolution = omapdss_default_get_resolution,
.get_recommended_bpp = omapdss_default_get_recommended_bpp,
diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig
index 4ea17dc..4cb12ce 100644
--- a/drivers/video/omap2/omapfb/Kconfig
+++ b/drivers/video/omap2/omapfb/Kconfig
@@ -2,7 +2,6 @@ menuconfig FB_OMAP2
tristate "OMAP2+ frame buffer support"
depends on FB && OMAP2_DSS && !DRM_OMAP
- select OMAP2_VRAM
select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 606b89f..d30b45d 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -28,10 +28,10 @@
#include <linux/omapfb.h>
#include <linux/vmalloc.h>
#include <linux/export.h>
+#include <linux/sizes.h>
#include <video/omapdss.h>
-#include <plat/vrfb.h>
-#include <plat/vram.h>
+#include <video/omapvrfb.h>
#include "omapfb.h"
@@ -211,6 +211,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
{
struct omapfb_info *ofbi = FB2OFB(fbi);
struct omapfb2_device *fbdev = ofbi->fbdev;
+ struct omap_dss_device *display = fb2display(fbi);
struct omapfb2_mem_region *rg;
int r = 0, i;
size_t size;
@@ -220,6 +221,9 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
size = PAGE_ALIGN(mi->size);
+ if (display && display->driver->sync)
+ display->driver->sync(display);
+
rg = ofbi->region;
down_write_nested(&rg->lock, rg->id);
@@ -279,7 +283,7 @@ static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
return 0;
}
-static int omapfb_update_window_nolock(struct fb_info *fbi,
+static int omapfb_update_window(struct fb_info *fbi,
u32 x, u32 y, u32 w, u32 h)
{
struct omap_dss_device *display = fb2display(fbi);
@@ -299,27 +303,6 @@ static int omapfb_update_window_nolock(struct fb_info *fbi,
return display->driver->update(display, x, y, w, h);
}
-/* This function is exported for SGX driver use */
-int omapfb_update_window(struct fb_info *fbi,
- u32 x, u32 y, u32 w, u32 h)
-{
- struct omapfb_info *ofbi = FB2OFB(fbi);
- struct omapfb2_device *fbdev = ofbi->fbdev;
- int r;
-
- if (!lock_fb_info(fbi))
- return -ENODEV;
- omapfb_lock(fbdev);
-
- r = omapfb_update_window_nolock(fbi, x, y, w, h);
-
- omapfb_unlock(fbdev);
- unlock_fb_info(fbi);
-
- return r;
-}
-EXPORT_SYMBOL(omapfb_update_window);
-
int omapfb_set_update_mode(struct fb_info *fbi,
enum omapfb_update_mode mode)
{
@@ -646,7 +629,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
break;
}
- r = omapfb_update_window_nolock(fbi, p.uwnd_o.x, p.uwnd_o.y,
+ r = omapfb_update_window(fbi, p.uwnd_o.x, p.uwnd_o.y,
p.uwnd_o.width, p.uwnd_o.height);
break;
@@ -663,7 +646,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
break;
}
- r = omapfb_update_window_nolock(fbi, p.uwnd.x, p.uwnd.y,
+ r = omapfb_update_window(fbi, p.uwnd.x, p.uwnd.y,
p.uwnd.width, p.uwnd.height);
break;
@@ -787,7 +770,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
case OMAPFB_WAITFORVSYNC:
DBG("ioctl WAITFORVSYNC\n");
- if (!display && !display->output && !display->output->manager) {
+ if (!display || !display->output || !display->output->manager) {
r = -EINVAL;
break;
}
@@ -853,14 +836,15 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
break;
case OMAPFB_GET_VRAM_INFO: {
- unsigned long vram, free, largest;
-
DBG("ioctl GET_VRAM_INFO\n");
- omap_vram_get_info(&vram, &free, &largest);
- p.vram_info.total = vram;
- p.vram_info.free = free;
- p.vram_info.largest_free_block = largest;
+ /*
+ * We don't have the ability to get this vram info anymore.
+ * Fill in something that should keep the applications working.
+ */
+ p.vram_info.total = SZ_1M * 64;
+ p.vram_info.free = SZ_1M * 64;
+ p.vram_info.largest_free_block = SZ_1M * 64;
if (copy_to_user((void __user *)arg, &p.vram_info,
sizeof(p.vram_info)))
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 16db158..ca585ef 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -31,9 +31,7 @@
#include <linux/omapfb.h>
#include <video/omapdss.h>
-#include <plat/cpu.h>
-#include <plat/vram.h>
-#include <plat/vrfb.h>
+#include <video/omapvrfb.h>
#include "omapfb.h"
@@ -1259,11 +1257,10 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
switch (blank) {
case FB_BLANK_UNBLANK:
- if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
+ if (display->state == OMAP_DSS_DISPLAY_ACTIVE)
goto exit;
- if (display->driver->resume)
- r = display->driver->resume(display);
+ r = display->driver->enable(display);
if ((display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) &&
d->update_mode == OMAPFB_AUTO_UPDATE &&
@@ -1284,8 +1281,7 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
if (d->auto_update_work_enabled)
omapfb_stop_auto_update(fbdev, display);
- if (display->driver->suspend)
- r = display->driver->suspend(display);
+ display->driver->disable(display);
break;
@@ -1336,24 +1332,25 @@ static void omapfb_free_fbmem(struct fb_info *fbi)
rg = ofbi->region;
- WARN_ON(atomic_read(&rg->map_count));
-
- if (rg->paddr)
- if (omap_vram_free(rg->paddr, rg->size))
- dev_err(fbdev->dev, "VRAM FREE failed\n");
+ if (rg->token == NULL)
+ return;
- if (rg->vaddr)
- iounmap(rg->vaddr);
+ WARN_ON(atomic_read(&rg->map_count));
if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
/* unmap the 0 angle rotation */
if (rg->vrfb.vaddr[0]) {
iounmap(rg->vrfb.vaddr[0]);
- omap_vrfb_release_ctx(&rg->vrfb);
rg->vrfb.vaddr[0] = NULL;
}
+
+ omap_vrfb_release_ctx(&rg->vrfb);
}
+ dma_free_attrs(fbdev->dev, rg->size, rg->token, rg->dma_handle,
+ &rg->attrs);
+
+ rg->token = NULL;
rg->vaddr = NULL;
rg->paddr = 0;
rg->alloc = 0;
@@ -1388,7 +1385,9 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
struct omapfb_info *ofbi = FB2OFB(fbi);
struct omapfb2_device *fbdev = ofbi->fbdev;
struct omapfb2_mem_region *rg;
- void __iomem *vaddr;
+ void *token;
+ DEFINE_DMA_ATTRS(attrs);
+ dma_addr_t dma_handle;
int r;
rg = ofbi->region;
@@ -1403,42 +1402,40 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
size = PAGE_ALIGN(size);
- if (!paddr) {
- DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
- r = omap_vram_alloc(size, &paddr);
- } else {
- DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr,
- ofbi->id);
- r = omap_vram_reserve(paddr, size);
- }
+ dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
- if (r) {
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
+ dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
+
+ DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
+
+ token = dma_alloc_attrs(fbdev->dev, size, &dma_handle,
+ GFP_KERNEL, &attrs);
+
+ if (token == NULL) {
dev_err(fbdev->dev, "failed to allocate framebuffer\n");
return -ENOMEM;
}
- if (ofbi->rotation_type != OMAP_DSS_ROT_VRFB) {
- vaddr = ioremap_wc(paddr, size);
-
- if (!vaddr) {
- dev_err(fbdev->dev, "failed to ioremap framebuffer\n");
- omap_vram_free(paddr, size);
- return -ENOMEM;
- }
+ DBG("allocated VRAM paddr %lx, vaddr %p\n",
+ (unsigned long)dma_handle, token);
- DBG("allocated VRAM paddr %lx, vaddr %p\n", paddr, vaddr);
- } else {
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
r = omap_vrfb_request_ctx(&rg->vrfb);
if (r) {
+ dma_free_attrs(fbdev->dev, size, token, dma_handle,
+ &attrs);
dev_err(fbdev->dev, "vrfb create ctx failed\n");
return r;
}
-
- vaddr = NULL;
}
- rg->paddr = paddr;
- rg->vaddr = vaddr;
+ rg->attrs = attrs;
+ rg->token = token;
+ rg->dma_handle = dma_handle;
+
+ rg->paddr = (unsigned long)dma_handle;
+ rg->vaddr = (void __iomem *)token;
rg->size = size;
rg->alloc = 1;
@@ -1532,6 +1529,9 @@ static int omapfb_parse_vram_param(const char *param, int max_entries,
}
+ WARN_ONCE(paddr,
+ "reserving memory at predefined address not supported\n");
+
paddrs[fbnum] = paddr;
sizes[fbnum] = size;
@@ -1611,7 +1611,6 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
{
struct omapfb_info *ofbi = FB2OFB(fbi);
struct omapfb2_device *fbdev = ofbi->fbdev;
- struct omap_dss_device *display = fb2display(fbi);
struct omapfb2_mem_region *rg = ofbi->region;
unsigned long old_size = rg->size;
unsigned long old_paddr = rg->paddr;
@@ -1626,9 +1625,6 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
if (old_size == size && old_type == type)
return 0;
- if (display && display->driver->sync)
- display->driver->sync(display);
-
omapfb_free_fbmem(fbi);
if (size == 0) {
@@ -1883,7 +1879,6 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
}
dev_set_drvdata(fbdev->dev, NULL);
- kfree(fbdev);
}
static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
@@ -2259,26 +2254,28 @@ static int omapfb_find_best_mode(struct omap_dss_device *display,
{
struct fb_monspecs *specs;
u8 *edid;
- int r, i, best_xres, best_idx, len;
+ int r, i, best_idx, len;
if (!display->driver->read_edid)
return -ENODEV;
len = 0x80 * 2;
edid = kmalloc(len, GFP_KERNEL);
+ if (edid == NULL)
+ return -ENOMEM;
r = display->driver->read_edid(display, edid, len);
if (r < 0)
goto err1;
specs = kzalloc(sizeof(*specs), GFP_KERNEL);
+ if (specs == NULL) {
+ r = -ENOMEM;
+ goto err1;
+ }
fb_edid_to_monspecs(edid, specs);
- if (edid[126] > 0)
- fb_edid_add_monspecs(edid + 0x80, specs);
-
- best_xres = 0;
best_idx = -1;
for (i = 0; i < specs->modedb_len; ++i) {
@@ -2294,16 +2291,20 @@ static int omapfb_find_best_mode(struct omap_dss_device *display,
if (m->xres == 2880 || m->xres == 1440)
continue;
+ if (m->vmode & FB_VMODE_INTERLACED ||
+ m->vmode & FB_VMODE_DOUBLE)
+ continue;
+
fb_videomode_to_omap_timings(m, display, &t);
r = display->driver->check_timings(display, &t);
- if (r == 0 && best_xres < m->xres) {
- best_xres = m->xres;
+ if (r == 0) {
best_idx = i;
+ break;
}
}
- if (best_xres == 0) {
+ if (best_idx == -1) {
r = -ENOENT;
goto err2;
}
@@ -2372,15 +2373,62 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
return 0;
}
+static int omapfb_init_connections(struct omapfb2_device *fbdev,
+ struct omap_dss_device *def_dssdev)
+{
+ int i, r;
+ struct omap_overlay_manager *mgr;
+
+ if (!def_dssdev->output) {
+ dev_err(fbdev->dev, "no output for the default display\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < fbdev->num_displays; ++i) {
+ struct omap_dss_device *dssdev = fbdev->displays[i].dssdev;
+ struct omap_dss_output *out = dssdev->output;
+
+ mgr = omap_dss_get_overlay_manager(dssdev->channel);
+
+ if (!mgr || !out)
+ continue;
+
+ if (mgr->output)
+ mgr->unset_output(mgr);
+
+ mgr->set_output(mgr, out);
+ }
+
+ mgr = def_dssdev->output->manager;
+
+ if (!mgr) {
+ dev_err(fbdev->dev, "no ovl manager for the default display\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < fbdev->num_overlays; i++) {
+ struct omap_overlay *ovl = fbdev->overlays[i];
+
+ if (ovl->manager)
+ ovl->unset_manager(ovl);
+
+ r = ovl->set_manager(ovl, mgr);
+ if (r)
+ dev_warn(fbdev->dev,
+ "failed to connect overlay %s to manager %s\n",
+ ovl->name, mgr->name);
+ }
+
+ return 0;
+}
+
static int __init omapfb_probe(struct platform_device *pdev)
{
struct omapfb2_device *fbdev = NULL;
int r = 0;
int i;
- struct omap_overlay *ovl;
struct omap_dss_device *def_display;
struct omap_dss_device *dssdev;
- struct omap_dss_device *ovl_device;
DBG("omapfb_probe\n");
@@ -2390,28 +2438,28 @@ static int __init omapfb_probe(struct platform_device *pdev)
goto err0;
}
- fbdev = kzalloc(sizeof(struct omapfb2_device), GFP_KERNEL);
+ fbdev = devm_kzalloc(&pdev->dev, sizeof(struct omapfb2_device),
+ GFP_KERNEL);
if (fbdev == NULL) {
r = -ENOMEM;
goto err0;
}
- /* TODO : Replace cpu check with omap_has_vrfb once HAS_FEATURE
- * available for OMAP2 and OMAP3
- */
- if (def_vrfb && !cpu_is_omap24xx() && !cpu_is_omap34xx()) {
+ if (def_vrfb && !omap_vrfb_supported()) {
def_vrfb = 0;
dev_warn(&pdev->dev, "VRFB is not supported on this hardware, "
"ignoring the module parameter vrfb=y\n");
}
+ r = omapdss_compat_init();
+ if (r)
+ goto err0;
mutex_init(&fbdev->mtx);
fbdev->dev = &pdev->dev;
platform_set_drvdata(pdev, fbdev);
- r = 0;
fbdev->num_displays = 0;
dssdev = NULL;
for_each_dss_dev(dssdev) {
@@ -2434,9 +2482,6 @@ static int __init omapfb_probe(struct platform_device *pdev)
d->update_mode = OMAPFB_AUTO_UPDATE;
}
- if (r)
- goto cleanup;
-
if (fbdev->num_displays == 0) {
dev_err(&pdev->dev, "no displays\n");
r = -EINVAL;
@@ -2451,15 +2496,33 @@ static int __init omapfb_probe(struct platform_device *pdev)
for (i = 0; i < fbdev->num_managers; i++)
fbdev->managers[i] = omap_dss_get_overlay_manager(i);
- /* gfx overlay should be the default one. find a display
- * connected to that, and use it as default display */
- ovl = omap_dss_get_overlay(0);
- ovl_device = ovl->get_device(ovl);
- if (ovl_device) {
- def_display = ovl_device;
- } else {
- dev_warn(&pdev->dev, "cannot find default display\n");
- def_display = NULL;
+ def_display = NULL;
+
+ for (i = 0; i < fbdev->num_displays; ++i) {
+ struct omap_dss_device *dssdev;
+ const char *def_name;
+
+ def_name = omapdss_get_default_display_name();
+
+ dssdev = fbdev->displays[i].dssdev;
+
+ if (def_name == NULL ||
+ (dssdev->name && strcmp(def_name, dssdev->name) == 0)) {
+ def_display = dssdev;
+ break;
+ }
+ }
+
+ if (def_display == NULL) {
+ dev_err(fbdev->dev, "failed to find default display\n");
+ r = -EINVAL;
+ goto cleanup;
+ }
+
+ r = omapfb_init_connections(fbdev, def_display);
+ if (r) {
+ dev_err(fbdev->dev, "failed to init overlay connections\n");
+ goto cleanup;
}
if (def_mode && strlen(def_mode) > 0) {
@@ -2510,6 +2573,7 @@ static int __init omapfb_probe(struct platform_device *pdev)
cleanup:
omapfb_free_resources(fbdev);
+ omapdss_compat_uninit();
err0:
dev_err(&pdev->dev, "failed to setup omapfb\n");
return r;
@@ -2525,6 +2589,8 @@ static int __exit omapfb_remove(struct platform_device *pdev)
omapfb_free_resources(fbdev);
+ omapdss_compat_uninit();
+
return 0;
}
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index e8d8cc7..18fa9e1 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -30,7 +30,7 @@
#include <linux/omapfb.h>
#include <video/omapdss.h>
-#include <plat/vrfb.h>
+#include <video/omapvrfb.h>
#include "omapfb.h"
@@ -441,6 +441,7 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
struct fb_info *fbi = dev_get_drvdata(dev);
struct omapfb_info *ofbi = FB2OFB(fbi);
struct omapfb2_device *fbdev = ofbi->fbdev;
+ struct omap_dss_device *display = fb2display(fbi);
struct omapfb2_mem_region *rg;
unsigned long size;
int r;
@@ -455,6 +456,9 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
if (!lock_fb_info(fbi))
return -ENODEV;
+ if (display && display->driver->sync)
+ display->driver->sync(display);
+
rg = ofbi->region;
down_write_nested(&rg->lock, rg->id);
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 5ced9b3..623cd87 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -28,6 +28,8 @@
#endif
#include <linux/rwsem.h>
+#include <linux/dma-attrs.h>
+#include <linux/dma-mapping.h>
#include <video/omapdss.h>
@@ -49,6 +51,9 @@ extern bool omapfb_debug;
struct omapfb2_mem_region {
int id;
+ struct dma_attrs attrs;
+ void *token;
+ dma_addr_t dma_handle;
u32 paddr;
void __iomem *vaddr;
struct vrfb vrfb;
@@ -124,9 +129,6 @@ void omapfb_remove_sysfs(struct omapfb2_device *fbdev);
int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg);
-int omapfb_update_window(struct fb_info *fbi,
- u32 x, u32 y, u32 w, u32 h);
-
int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
struct fb_var_screeninfo *var);
@@ -144,16 +146,16 @@ int omapfb_set_update_mode(struct fb_info *fbi, enum omapfb_update_mode mode);
static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
{
struct omapfb_info *ofbi = FB2OFB(fbi);
- int i;
+ struct omap_overlay *ovl;
/* XXX: returns the display connected to first attached overlay */
- for (i = 0; i < ofbi->num_overlays; i++) {
- struct omap_overlay *ovl = ofbi->overlays[i];
- return ovl->get_device(ovl);
- }
+ if (ofbi->num_overlays == 0)
+ return NULL;
- return NULL;
+ ovl = ofbi->overlays[0];
+
+ return ovl->get_device(ovl);
}
static inline struct omapfb_display_data *get_display_data(
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
deleted file mode 100644
index f2b15c4..0000000
--- a/drivers/video/omap2/vram.c
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * VRAM manager for OMAP
- *
- * Copyright (C) 2009 Nokia Corporation
- * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*#define DEBUG*/
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/seq_file.h>
-#include <linux/memblock.h>
-#include <linux/completion.h>
-#include <linux/debugfs.h>
-#include <linux/jiffies.h>
-#include <linux/module.h>
-
-#include <asm/setup.h>
-
-#include <plat/vram.h>
-
-#ifdef DEBUG
-#define DBG(format, ...) pr_debug("VRAM: " format, ## __VA_ARGS__)
-#else
-#define DBG(format, ...)
-#endif
-
-/* postponed regions are used to temporarily store region information at boot
- * time when we cannot yet allocate the region list */
-#define MAX_POSTPONED_REGIONS 10
-
-static bool vram_initialized;
-static int postponed_cnt;
-static struct {
- unsigned long paddr;
- size_t size;
-} postponed_regions[MAX_POSTPONED_REGIONS];
-
-struct vram_alloc {
- struct list_head list;
- unsigned long paddr;
- unsigned pages;
-};
-
-struct vram_region {
- struct list_head list;
- struct list_head alloc_list;
- unsigned long paddr;
- unsigned pages;
-};
-
-static DEFINE_MUTEX(region_mutex);
-static LIST_HEAD(region_list);
-
-static struct vram_region *omap_vram_create_region(unsigned long paddr,
- unsigned pages)
-{
- struct vram_region *rm;
-
- rm = kzalloc(sizeof(*rm), GFP_KERNEL);
-
- if (rm) {
- INIT_LIST_HEAD(&rm->alloc_list);
- rm->paddr = paddr;
- rm->pages = pages;
- }
-
- return rm;
-}
-
-#if 0
-static void omap_vram_free_region(struct vram_region *vr)
-{
- list_del(&vr->list);
- kfree(vr);
-}
-#endif
-
-static struct vram_alloc *omap_vram_create_allocation(struct vram_region *vr,
- unsigned long paddr, unsigned pages)
-{
- struct vram_alloc *va;
- struct vram_alloc *new;
-
- new = kzalloc(sizeof(*va), GFP_KERNEL);
-
- if (!new)
- return NULL;
-
- new->paddr = paddr;
- new->pages = pages;
-
- list_for_each_entry(va, &vr->alloc_list, list) {
- if (va->paddr > new->paddr)
- break;
- }
-
- list_add_tail(&new->list, &va->list);
-
- return new;
-}
-
-static void omap_vram_free_allocation(struct vram_alloc *va)
-{
- list_del(&va->list);
- kfree(va);
-}
-
-int omap_vram_add_region(unsigned long paddr, size_t size)
-{
- struct vram_region *rm;
- unsigned pages;
-
- if (vram_initialized) {
- DBG("adding region paddr %08lx size %d\n",
- paddr, size);
-
- size &= PAGE_MASK;
- pages = size >> PAGE_SHIFT;
-
- rm = omap_vram_create_region(paddr, pages);
- if (rm == NULL)
- return -ENOMEM;
-
- list_add(&rm->list, &region_list);
- } else {
- if (postponed_cnt == MAX_POSTPONED_REGIONS)
- return -ENOMEM;
-
- postponed_regions[postponed_cnt].paddr = paddr;
- postponed_regions[postponed_cnt].size = size;
-
- ++postponed_cnt;
- }
- return 0;
-}
-
-int omap_vram_free(unsigned long paddr, size_t size)
-{
- struct vram_region *rm;
- struct vram_alloc *alloc;
- unsigned start, end;
-
- DBG("free mem paddr %08lx size %d\n", paddr, size);
-
- size = PAGE_ALIGN(size);
-
- mutex_lock(&region_mutex);
-
- list_for_each_entry(rm, &region_list, list) {
- list_for_each_entry(alloc, &rm->alloc_list, list) {
- start = alloc->paddr;
- end = alloc->paddr + (alloc->pages >> PAGE_SHIFT);
-
- if (start >= paddr && end < paddr + size)
- goto found;
- }
- }
-
- mutex_unlock(&region_mutex);
- return -EINVAL;
-
-found:
- omap_vram_free_allocation(alloc);
-
- mutex_unlock(&region_mutex);
- return 0;
-}
-EXPORT_SYMBOL(omap_vram_free);
-
-static int _omap_vram_reserve(unsigned long paddr, unsigned pages)
-{
- struct vram_region *rm;
- struct vram_alloc *alloc;
- size_t size;
-
- size = pages << PAGE_SHIFT;
-
- list_for_each_entry(rm, &region_list, list) {
- unsigned long start, end;
-
- DBG("checking region %lx %d\n", rm->paddr, rm->pages);
-
- start = rm->paddr;
- end = start + (rm->pages << PAGE_SHIFT) - 1;
- if (start > paddr || end < paddr + size - 1)
- continue;
-
- DBG("block ok, checking allocs\n");
-
- list_for_each_entry(alloc, &rm->alloc_list, list) {
- end = alloc->paddr - 1;
-
- if (start <= paddr && end >= paddr + size - 1)
- goto found;
-
- start = alloc->paddr + (alloc->pages << PAGE_SHIFT);
- }
-
- end = rm->paddr + (rm->pages << PAGE_SHIFT) - 1;
-
- if (!(start <= paddr && end >= paddr + size - 1))
- continue;
-found:
- DBG("found area start %lx, end %lx\n", start, end);
-
- if (omap_vram_create_allocation(rm, paddr, pages) == NULL)
- return -ENOMEM;
-
- return 0;
- }
-
- return -ENOMEM;
-}
-
-int omap_vram_reserve(unsigned long paddr, size_t size)
-{
- unsigned pages;
- int r;
-
- DBG("reserve mem paddr %08lx size %d\n", paddr, size);
-
- size = PAGE_ALIGN(size);
- pages = size >> PAGE_SHIFT;
-
- mutex_lock(&region_mutex);
-
- r = _omap_vram_reserve(paddr, pages);
-
- mutex_unlock(&region_mutex);
-
- return r;
-}
-EXPORT_SYMBOL(omap_vram_reserve);
-
-static int _omap_vram_alloc(unsigned pages, unsigned long *paddr)
-{
- struct vram_region *rm;
- struct vram_alloc *alloc;
-
- list_for_each_entry(rm, &region_list, list) {
- unsigned long start, end;
-
- DBG("checking region %lx %d\n", rm->paddr, rm->pages);
-
- start = rm->paddr;
-
- list_for_each_entry(alloc, &rm->alloc_list, list) {
- end = alloc->paddr;
-
- if (end - start >= pages << PAGE_SHIFT)
- goto found;
-
- start = alloc->paddr + (alloc->pages << PAGE_SHIFT);
- }
-
- end = rm->paddr + (rm->pages << PAGE_SHIFT);
-found:
- if (end - start < pages << PAGE_SHIFT)
- continue;
-
- DBG("found %lx, end %lx\n", start, end);
-
- alloc = omap_vram_create_allocation(rm, start, pages);
- if (alloc == NULL)
- return -ENOMEM;
-
- *paddr = start;
-
- return 0;
- }
-
- return -ENOMEM;
-}
-
-int omap_vram_alloc(size_t size, unsigned long *paddr)
-{
- unsigned pages;
- int r;
-
- BUG_ON(!size);
-
- DBG("alloc mem size %d\n", size);
-
- size = PAGE_ALIGN(size);
- pages = size >> PAGE_SHIFT;
-
- mutex_lock(&region_mutex);
-
- r = _omap_vram_alloc(pages, paddr);
-
- mutex_unlock(&region_mutex);
-
- return r;
-}
-EXPORT_SYMBOL(omap_vram_alloc);
-
-void omap_vram_get_info(unsigned long *vram,
- unsigned long *free_vram,
- unsigned long *largest_free_block)
-{
- struct vram_region *vr;
- struct vram_alloc *va;
-
- *vram = 0;
- *free_vram = 0;
- *largest_free_block = 0;
-
- mutex_lock(&region_mutex);
-
- list_for_each_entry(vr, &region_list, list) {
- unsigned free;
- unsigned long pa;
-
- pa = vr->paddr;
- *vram += vr->pages << PAGE_SHIFT;
-
- list_for_each_entry(va, &vr->alloc_list, list) {
- free = va->paddr - pa;
- *free_vram += free;
- if (free > *largest_free_block)
- *largest_free_block = free;
- pa = va->paddr + (va->pages << PAGE_SHIFT);
- }
-
- free = vr->paddr + (vr->pages << PAGE_SHIFT) - pa;
- *free_vram += free;
- if (free > *largest_free_block)
- *largest_free_block = free;
- }
-
- mutex_unlock(&region_mutex);
-}
-EXPORT_SYMBOL(omap_vram_get_info);
-
-#if defined(CONFIG_DEBUG_FS)
-static int vram_debug_show(struct seq_file *s, void *unused)
-{
- struct vram_region *vr;
- struct vram_alloc *va;
- unsigned size;
-
- mutex_lock(&region_mutex);
-
- list_for_each_entry(vr, &region_list, list) {
- size = vr->pages << PAGE_SHIFT;
- seq_printf(s, "%08lx-%08lx (%d bytes)\n",
- vr->paddr, vr->paddr + size - 1,
- size);
-
- list_for_each_entry(va, &vr->alloc_list, list) {
- size = va->pages << PAGE_SHIFT;
- seq_printf(s, " %08lx-%08lx (%d bytes)\n",
- va->paddr, va->paddr + size - 1,
- size);
- }
- }
-
- mutex_unlock(&region_mutex);
-
- return 0;
-}
-
-static int vram_debug_open(struct inode *inode, struct file *file)
-{
- return single_open(file, vram_debug_show, inode->i_private);
-}
-
-static const struct file_operations vram_debug_fops = {
- .open = vram_debug_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int __init omap_vram_create_debugfs(void)
-{
- struct dentry *d;
-
- d = debugfs_create_file("vram", S_IRUGO, NULL,
- NULL, &vram_debug_fops);
- if (IS_ERR(d))
- return PTR_ERR(d);
-
- return 0;
-}
-#endif
-
-static __init int omap_vram_init(void)
-{
- int i;
-
- vram_initialized = 1;
-
- for (i = 0; i < postponed_cnt; i++)
- omap_vram_add_region(postponed_regions[i].paddr,
- postponed_regions[i].size);
-
-#ifdef CONFIG_DEBUG_FS
- if (omap_vram_create_debugfs())
- pr_err("VRAM: Failed to create debugfs file\n");
-#endif
-
- return 0;
-}
-
-arch_initcall(omap_vram_init);
-
-/* boottime vram alloc stuff */
-
-/* set from board file */
-static u32 omap_vram_sdram_start __initdata;
-static u32 omap_vram_sdram_size __initdata;
-
-/* set from kernel cmdline */
-static u32 omap_vram_def_sdram_size __initdata;
-static u32 omap_vram_def_sdram_start __initdata;
-
-static int __init omap_vram_early_vram(char *p)
-{
- omap_vram_def_sdram_size = memparse(p, &p);
- if (*p == ',')
- omap_vram_def_sdram_start = simple_strtoul(p + 1, &p, 16);
- return 0;
-}
-early_param("vram", omap_vram_early_vram);
-
-/*
- * Called from map_io. We need to call to this early enough so that we
- * can reserve the fixed SDRAM regions before VM could get hold of them.
- */
-void __init omap_vram_reserve_sdram_memblock(void)
-{
- u32 paddr;
- u32 size = 0;
-
- /* cmdline arg overrides the board file definition */
- if (omap_vram_def_sdram_size) {
- size = omap_vram_def_sdram_size;
- paddr = omap_vram_def_sdram_start;
- }
-
- if (!size) {
- size = omap_vram_sdram_size;
- paddr = omap_vram_sdram_start;
- }
-
-#ifdef CONFIG_OMAP2_VRAM_SIZE
- if (!size) {
- size = CONFIG_OMAP2_VRAM_SIZE * 1024 * 1024;
- paddr = 0;
- }
-#endif
-
- if (!size)
- return;
-
- size = ALIGN(size, SZ_2M);
-
- if (paddr) {
- if (paddr & ~PAGE_MASK) {
- pr_err("VRAM start address 0x%08x not page aligned\n",
- paddr);
- return;
- }
-
- if (!memblock_is_region_memory(paddr, size)) {
- pr_err("Illegal SDRAM region 0x%08x..0x%08x for VRAM\n",
- paddr, paddr + size - 1);
- return;
- }
-
- if (memblock_is_region_reserved(paddr, size)) {
- pr_err("FB: failed to reserve VRAM - busy\n");
- return;
- }
-
- if (memblock_reserve(paddr, size) < 0) {
- pr_err("FB: failed to reserve VRAM - no memory\n");
- return;
- }
- } else {
- paddr = memblock_alloc(size, SZ_2M);
- }
-
- memblock_free(paddr, size);
- memblock_remove(paddr, size);
-
- omap_vram_add_region(paddr, size);
-
- pr_info("Reserving %u bytes SDRAM for VRAM\n", size);
-}
-
-void __init omap_vram_set_sdram_vram(u32 size, u32 start)
-{
- omap_vram_sdram_start = start;
- omap_vram_sdram_size = size;
-}
diff --git a/drivers/video/omap2/vrfb.c b/drivers/video/omap2/vrfb.c
index 7e99022..10560ef 100644
--- a/drivers/video/omap2/vrfb.c
+++ b/drivers/video/omap2/vrfb.c
@@ -20,15 +20,16 @@
/*#define DEBUG*/
+#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/bitops.h>
#include <linux/mutex.h>
+#include <linux/platform_device.h>
-#include <plat/vrfb.h>
-#include <plat/sdrc.h>
+#include <video/omapvrfb.h>
#ifdef DEBUG
#define DBG(format, ...) pr_debug("VRFB: " format, ## __VA_ARGS__)
@@ -36,10 +37,10 @@
#define DBG(format, ...)
#endif
-#define SMS_ROT_VIRT_BASE(context, rot) \
- (((context >= 4) ? 0xD0000000 : 0x70000000) \
- + (0x4000000 * (context)) \
- + (0x1000000 * (rot)))
+#define SMS_ROT_CONTROL(context) (0x0 + 0x10 * context)
+#define SMS_ROT_SIZE(context) (0x4 + 0x10 * context)
+#define SMS_ROT_PHYSICAL_BA(context) (0x8 + 0x10 * context)
+#define SMS_ROT_VIRT_BASE(rot) (0x1000000 * (rot))
#define OMAP_VRFB_SIZE (2048 * 2048 * 4)
@@ -53,10 +54,16 @@
#define SMS_PW_OFFSET 4
#define SMS_PS_OFFSET 0
-#define VRFB_NUM_CTXS 12
/* bitmap of reserved contexts */
static unsigned long ctx_map;
+struct vrfb_ctx {
+ u32 base;
+ u32 physical_ba;
+ u32 control;
+ u32 size;
+};
+
static DEFINE_MUTEX(ctx_lock);
/*
@@ -65,17 +72,34 @@ static DEFINE_MUTEX(ctx_lock);
* we don't need locking, since no drivers will run until after the wake-up
* has finished.
*/
-static struct {
- u32 physical_ba;
- u32 control;
- u32 size;
-} vrfb_hw_context[VRFB_NUM_CTXS];
+
+static void __iomem *vrfb_base;
+
+static int num_ctxs;
+static struct vrfb_ctx *ctxs;
+
+static bool vrfb_loaded;
+
+static void omap2_sms_write_rot_control(u32 val, unsigned ctx)
+{
+ __raw_writel(val, vrfb_base + SMS_ROT_CONTROL(ctx));
+}
+
+static void omap2_sms_write_rot_size(u32 val, unsigned ctx)
+{
+ __raw_writel(val, vrfb_base + SMS_ROT_SIZE(ctx));
+}
+
+static void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx)
+{
+ __raw_writel(val, vrfb_base + SMS_ROT_PHYSICAL_BA(ctx));
+}
static inline void restore_hw_context(int ctx)
{
- omap2_sms_write_rot_control(vrfb_hw_context[ctx].control, ctx);
- omap2_sms_write_rot_size(vrfb_hw_context[ctx].size, ctx);
- omap2_sms_write_rot_physical_ba(vrfb_hw_context[ctx].physical_ba, ctx);
+ omap2_sms_write_rot_control(ctxs[ctx].control, ctx);
+ omap2_sms_write_rot_size(ctxs[ctx].size, ctx);
+ omap2_sms_write_rot_physical_ba(ctxs[ctx].physical_ba, ctx);
}
static u32 get_image_width_roundup(u16 width, u8 bytespp)
@@ -196,9 +220,9 @@ void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
control |= VRFB_PAGE_WIDTH_EXP << SMS_PW_OFFSET;
control |= VRFB_PAGE_HEIGHT_EXP << SMS_PH_OFFSET;
- vrfb_hw_context[ctx].physical_ba = paddr;
- vrfb_hw_context[ctx].size = size;
- vrfb_hw_context[ctx].control = control;
+ ctxs[ctx].physical_ba = paddr;
+ ctxs[ctx].size = size;
+ ctxs[ctx].control = control;
omap2_sms_write_rot_physical_ba(paddr, ctx);
omap2_sms_write_rot_size(size, ctx);
@@ -274,11 +298,11 @@ int omap_vrfb_request_ctx(struct vrfb *vrfb)
mutex_lock(&ctx_lock);
- for (ctx = 0; ctx < VRFB_NUM_CTXS; ++ctx)
+ for (ctx = 0; ctx < num_ctxs; ++ctx)
if ((ctx_map & (1 << ctx)) == 0)
break;
- if (ctx == VRFB_NUM_CTXS) {
+ if (ctx == num_ctxs) {
pr_err("vrfb: no free contexts\n");
r = -EBUSY;
goto out;
@@ -293,7 +317,7 @@ int omap_vrfb_request_ctx(struct vrfb *vrfb)
vrfb->context = ctx;
for (rot = 0; rot < 4; ++rot) {
- paddr = SMS_ROT_VIRT_BASE(ctx, rot);
+ paddr = ctxs[ctx].base + SMS_ROT_VIRT_BASE(rot);
if (!request_mem_region(paddr, OMAP_VRFB_SIZE, "vrfb")) {
pr_err("vrfb: failed to reserve VRFB "
"area for ctx %d, rotation %d\n",
@@ -314,3 +338,78 @@ out:
return r;
}
EXPORT_SYMBOL(omap_vrfb_request_ctx);
+
+bool omap_vrfb_supported(void)
+{
+ return vrfb_loaded;
+}
+EXPORT_SYMBOL(omap_vrfb_supported);
+
+static int __init vrfb_probe(struct platform_device *pdev)
+{
+ struct resource *mem;
+ int i;
+
+ /* first resource is the register res, the rest are vrfb contexts */
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&pdev->dev, "can't get vrfb base address\n");
+ return -EINVAL;
+ }
+
+ vrfb_base = devm_ioremap_resource(&pdev->dev, mem);
+ if (IS_ERR(vrfb_base))
+ return PTR_ERR(vrfb_base);
+
+ num_ctxs = pdev->num_resources - 1;
+
+ ctxs = devm_kzalloc(&pdev->dev,
+ sizeof(struct vrfb_ctx) * num_ctxs,
+ GFP_KERNEL);
+
+ if (!ctxs)
+ return -ENOMEM;
+
+ for (i = 0; i < num_ctxs; ++i) {
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i);
+ if (!mem) {
+ dev_err(&pdev->dev, "can't get vrfb ctx %d address\n",
+ i);
+ return -EINVAL;
+ }
+
+ ctxs[i].base = mem->start;
+ }
+
+ vrfb_loaded = true;
+
+ return 0;
+}
+
+static void __exit vrfb_remove(struct platform_device *pdev)
+{
+ vrfb_loaded = false;
+}
+
+static struct platform_driver vrfb_driver = {
+ .driver.name = "omapvrfb",
+ .remove = __exit_p(vrfb_remove),
+};
+
+static int __init vrfb_init(void)
+{
+ return platform_driver_probe(&vrfb_driver, &vrfb_probe);
+}
+
+static void __exit vrfb_exit(void)
+{
+ platform_driver_unregister(&vrfb_driver);
+}
+
+module_init(vrfb_init);
+module_exit(vrfb_exit);
+
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
+MODULE_DESCRIPTION("OMAP VRFB");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index d57cc58..4b23af6 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -249,7 +249,7 @@ static void p9100_init_fix(struct fb_info *info, int linebytes, struct device_no
info->fix.accel = FB_ACCEL_SUN_CGTHREE;
}
-static int __devinit p9100_probe(struct platform_device *op)
+static int p9100_probe(struct platform_device *op)
{
struct device_node *dp = op->dev.of_node;
struct fb_info *info;
@@ -326,7 +326,7 @@ out_err:
return err;
}
-static int __devexit p9100_remove(struct platform_device *op)
+static int p9100_remove(struct platform_device *op)
{
struct fb_info *info = dev_get_drvdata(&op->dev);
struct p9100_par *par = info->par;
@@ -359,7 +359,7 @@ static struct platform_driver p9100_driver = {
.of_match_table = p9100_match,
},
.probe = p9100_probe,
- .remove = __devexit_p(p9100_remove),
+ .remove = p9100_remove,
};
static int __init p9100_init(void)
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index ae3caa6..3d86bac 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -313,7 +313,8 @@ static void platinum_set_hardware(struct fb_info_platinum *pinfo)
/*
* Set misc info vars for this driver
*/
-static void __devinit platinum_init_info(struct fb_info *info, struct fb_info_platinum *pinfo)
+static void platinum_init_info(struct fb_info *info,
+ struct fb_info_platinum *pinfo)
{
/* Fill fb_info */
info->fbops = &platinumfb_ops;
@@ -338,7 +339,7 @@ static void __devinit platinum_init_info(struct fb_info *info, struct fb_info_pl
}
-static int __devinit platinum_init_fb(struct fb_info *info)
+static int platinum_init_fb(struct fb_info *info)
{
struct fb_info_platinum *pinfo = info->par;
struct fb_var_screeninfo var;
@@ -533,7 +534,7 @@ static int __init platinumfb_setup(char *options)
#define invalidate_cache(addr)
#endif
-static int __devinit platinumfb_probe(struct platform_device* odev)
+static int platinumfb_probe(struct platform_device* odev)
{
struct device_node *dp = odev->dev.of_node;
struct fb_info *info;
@@ -645,7 +646,7 @@ static int __devinit platinumfb_probe(struct platform_device* odev)
return rc;
}
-static int __devexit platinumfb_remove(struct platform_device* odev)
+static int platinumfb_remove(struct platform_device* odev)
{
struct fb_info *info = dev_get_drvdata(&odev->dev);
struct fb_info_platinum *pinfo = info->par;
@@ -683,7 +684,7 @@ static struct platform_driver platinum_driver =
.of_match_table = platinumfb_match,
},
.probe = platinumfb_probe,
- .remove = __devexit_p(platinumfb_remove),
+ .remove = platinumfb_remove,
};
static int __init platinumfb_init(void)
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index df31a24..81354ee 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -67,7 +67,7 @@
* Driver data
*/
static int hwcursor = 1;
-static char *mode_option __devinitdata;
+static char *mode_option;
/*
* The XFree GLINT driver will (I think to implement hardware cursor
@@ -80,10 +80,10 @@ static char *mode_option __devinitdata;
*/
static bool lowhsync;
static bool lowvsync;
-static bool noaccel __devinitdata;
+static bool noaccel;
/* mtrr option */
#ifdef CONFIG_MTRR
-static bool nomtrr __devinitdata;
+static bool nomtrr;
#endif
/*
@@ -107,7 +107,7 @@ struct pm2fb_par
* Here we define the default structs fb_fix_screeninfo and fb_var_screeninfo
* if we don't use modedb.
*/
-static struct fb_fix_screeninfo pm2fb_fix __devinitdata = {
+static struct fb_fix_screeninfo pm2fb_fix = {
.id = "",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
@@ -120,7 +120,7 @@ static struct fb_fix_screeninfo pm2fb_fix __devinitdata = {
/*
* Default video mode. In case the modedb doesn't work.
*/
-static struct fb_var_screeninfo pm2fb_var __devinitdata = {
+static struct fb_var_screeninfo pm2fb_var = {
/* "640x480, 8 bpp @ 60 Hz */
.xres = 640,
.yres = 480,
@@ -1515,8 +1515,7 @@ static struct fb_ops pm2fb_ops = {
* @param pdev PCI device.
* @param id PCI device ID.
*/
-static int __devinit pm2fb_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
+static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct pm2fb_par *default_par;
struct fb_info *info;
@@ -1727,7 +1726,7 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
*
* @param pdev PCI device to clean up.
*/
-static void __devexit pm2fb_remove(struct pci_dev *pdev)
+static void pm2fb_remove(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct fb_fix_screeninfo *fix = &info->fix;
@@ -1765,7 +1764,7 @@ static struct pci_driver pm2fb_driver = {
.name = "pm2fb",
.id_table = pm2fb_id_table,
.probe = pm2fb_probe,
- .remove = __devexit_p(pm2fb_remove),
+ .remove = pm2fb_remove,
};
MODULE_DEVICE_TABLE(pci, pm2fb_id_table);
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index 055e527..7718faa 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -56,12 +56,12 @@
* Driver data
*/
static int hwcursor = 1;
-static char *mode_option __devinitdata;
-static bool noaccel __devinitdata;
+static char *mode_option;
+static bool noaccel;
/* mtrr option */
#ifdef CONFIG_MTRR
-static bool nomtrr __devinitdata;
+static bool nomtrr;
#endif
/*
@@ -84,7 +84,7 @@ struct pm3_par {
* if we don't use modedb. If we do use modedb see pm3fb_init how to use it
* to get a fb_var_screeninfo. Otherwise define a default var as well.
*/
-static struct fb_fix_screeninfo pm3fb_fix __devinitdata = {
+static struct fb_fix_screeninfo pm3fb_fix = {
.id = "Permedia3",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
@@ -1229,7 +1229,7 @@ static struct fb_ops pm3fb_ops = {
/* mmio register are already mapped when this function is called */
/* the pm3fb_fix.smem_start is also set */
-static unsigned long __devinit pm3fb_size_memory(struct pm3_par *par)
+static unsigned long pm3fb_size_memory(struct pm3_par *par)
{
unsigned long memsize = 0;
unsigned long tempBypass, i, temp1, temp2;
@@ -1314,8 +1314,7 @@ static unsigned long __devinit pm3fb_size_memory(struct pm3_par *par)
return memsize;
}
-static int __devinit pm3fb_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+static int pm3fb_probe(struct pci_dev *dev, const struct pci_device_id *ent)
{
struct fb_info *info;
struct pm3_par *par;
@@ -1469,7 +1468,7 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
/*
* Cleanup
*/
-static void __devexit pm3fb_remove(struct pci_dev *dev)
+static void pm3fb_remove(struct pci_dev *dev)
{
struct fb_info *info = pci_get_drvdata(dev);
@@ -1507,7 +1506,7 @@ static struct pci_driver pm3fb_driver = {
.name = "pm3fb",
.id_table = pm3fb_id_table,
.probe = pm3fb_probe,
- .remove = __devexit_p(pm3fb_remove),
+ .remove = pm3fb_remove,
};
MODULE_DEVICE_TABLE(pci, pm3fb_id_table);
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c
index 9b4a60b..d1e46ce 100644
--- a/drivers/video/pmag-ba-fb.c
+++ b/drivers/video/pmag-ba-fb.c
@@ -43,7 +43,7 @@ struct pmagbafb_par {
};
-static struct fb_var_screeninfo pmagbafb_defined __devinitdata = {
+static struct fb_var_screeninfo pmagbafb_defined = {
.xres = 1024,
.yres = 864,
.xres_virtual = 1024,
@@ -67,7 +67,7 @@ static struct fb_var_screeninfo pmagbafb_defined __devinitdata = {
.vmode = FB_VMODE_NONINTERLACED,
};
-static struct fb_fix_screeninfo pmagbafb_fix __devinitdata = {
+static struct fb_fix_screeninfo pmagbafb_fix = {
.id = "PMAG-BA",
.smem_len = (1024 * 1024),
.type = FB_TYPE_PACKED_PIXELS,
@@ -141,7 +141,7 @@ static void __init pmagbafb_erase_cursor(struct fb_info *info)
}
-static int __devinit pmagbafb_probe(struct device *dev)
+static int pmagbafb_probe(struct device *dev)
{
struct tc_dev *tdev = to_tc_dev(dev);
resource_size_t start, len;
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
index 4e7a9c4..0e13174 100644
--- a/drivers/video/pmagb-b-fb.c
+++ b/drivers/video/pmagb-b-fb.c
@@ -44,7 +44,7 @@ struct pmagbbfb_par {
};
-static struct fb_var_screeninfo pmagbbfb_defined __devinitdata = {
+static struct fb_var_screeninfo pmagbbfb_defined = {
.bits_per_pixel = 8,
.red.length = 8,
.green.length = 8,
@@ -57,7 +57,7 @@ static struct fb_var_screeninfo pmagbbfb_defined __devinitdata = {
.vmode = FB_VMODE_NONINTERLACED,
};
-static struct fb_fix_screeninfo pmagbbfb_fix __devinitdata = {
+static struct fb_fix_screeninfo pmagbbfb_fix = {
.id = "PMAGB-BA",
.smem_len = (2048 * 1024),
.type = FB_TYPE_PACKED_PIXELS,
@@ -147,7 +147,7 @@ static void __init pmagbbfb_erase_cursor(struct fb_info *info)
/*
* Set up screen parameters.
*/
-static void __devinit pmagbbfb_screen_setup(struct fb_info *info)
+static void pmagbbfb_screen_setup(struct fb_info *info)
{
struct pmagbbfb_par *par = info->par;
@@ -179,9 +179,9 @@ static void __devinit pmagbbfb_screen_setup(struct fb_info *info)
/*
* Determine oscillator configuration.
*/
-static void __devinit pmagbbfb_osc_setup(struct fb_info *info)
+static void pmagbbfb_osc_setup(struct fb_info *info)
{
- static unsigned int pmagbbfb_freqs[] __devinitdata = {
+ static unsigned int pmagbbfb_freqs[] = {
130808, 119843, 104000, 92980, 74370, 72800,
69197, 66000, 65000, 50350, 36000, 32000, 25175
};
@@ -246,7 +246,7 @@ static void __devinit pmagbbfb_osc_setup(struct fb_info *info)
};
-static int __devinit pmagbbfb_probe(struct device *dev)
+static int pmagbbfb_probe(struct device *dev)
{
struct tc_dev *tdev = to_tc_dev(dev);
resource_size_t start, len;
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 0b340d6..920c27b 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -259,7 +259,7 @@ static const struct fb_videomode ps3fb_modedb[] = {
static int ps3fb_mode;
module_param(ps3fb_mode, int, 0);
-static char *mode_option __devinitdata;
+static char *mode_option;
static int ps3fb_cmp_mode(const struct fb_videomode *vmode,
const struct fb_var_screeninfo *var)
@@ -965,7 +965,7 @@ static struct fb_fix_screeninfo ps3fb_fix __initdata = {
.accel = FB_ACCEL_NONE,
};
-static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
+static int ps3fb_probe(struct ps3_system_bus_device *dev)
{
struct fb_info *info;
struct ps3fb_par *par;
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index bcd44c3..df07860 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -112,11 +112,11 @@ enum { VO_PAL, VO_NTSC, VO_VGA };
enum { PAL_ARGB1555, PAL_RGB565, PAL_ARGB4444, PAL_ARGB8888 };
struct pvr2_params { unsigned int val; char *name; };
-static struct pvr2_params cables[] __devinitdata = {
+static struct pvr2_params cables[] = {
{ CT_VGA, "VGA" }, { CT_RGB, "RGB" }, { CT_COMPOSITE, "COMPOSITE" },
};
-static struct pvr2_params outputs[] __devinitdata = {
+static struct pvr2_params outputs[] = {
{ VO_PAL, "PAL" }, { VO_NTSC, "NTSC" }, { VO_VGA, "VGA" },
};
@@ -145,7 +145,7 @@ static struct pvr2fb_par {
static struct fb_info *fb_info;
-static struct fb_fix_screeninfo pvr2_fix __devinitdata = {
+static struct fb_fix_screeninfo pvr2_fix = {
.id = "NEC PowerVR2",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_TRUECOLOR,
@@ -154,7 +154,7 @@ static struct fb_fix_screeninfo pvr2_fix __devinitdata = {
.accel = FB_ACCEL_NONE,
};
-static struct fb_var_screeninfo pvr2_var __devinitdata = {
+static struct fb_var_screeninfo pvr2_var = {
.xres = 640,
.yres = 480,
.xres_virtual = 640,
@@ -226,7 +226,7 @@ static struct fb_ops pvr2fb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static struct fb_videomode pvr2_modedb[] __devinitdata = {
+static struct fb_videomode pvr2_modedb[] = {
/*
* Broadcast video modes (PAL and NTSC). I'm unfamiliar with
* PAL-M and PAL-N, but from what I've read both modes parallel PAL and
@@ -256,7 +256,7 @@ static struct fb_videomode pvr2_modedb[] __devinitdata = {
#define DEFMODE_VGA 2
static int defmode = DEFMODE_NTSC;
-static char *mode_option __devinitdata = NULL;
+static char *mode_option = NULL;
static inline void pvr2fb_set_pal_type(unsigned int type)
{
@@ -763,7 +763,7 @@ out_unmap:
* in for flexibility anyways. Who knows, maybe someone has tv-out on a
* PCI-based version of these things ;-)
*/
-static int __devinit pvr2fb_common_init(void)
+static int pvr2fb_common_init(void)
{
struct pvr2fb_par *par = currentpar;
unsigned long modememused, rev;
@@ -922,8 +922,8 @@ static void __exit pvr2fb_dc_exit(void)
#endif /* CONFIG_SH_DREAMCAST */
#ifdef CONFIG_PCI
-static int __devinit pvr2fb_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int pvr2fb_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
int ret;
@@ -953,7 +953,7 @@ static int __devinit pvr2fb_pci_probe(struct pci_dev *pdev,
return pvr2fb_common_init();
}
-static void __devexit pvr2fb_pci_remove(struct pci_dev *pdev)
+static void pvr2fb_pci_remove(struct pci_dev *pdev)
{
if (fb_info->screen_base) {
iounmap(fb_info->screen_base);
@@ -967,7 +967,7 @@ static void __devexit pvr2fb_pci_remove(struct pci_dev *pdev)
pci_release_regions(pdev);
}
-static struct pci_device_id pvr2fb_pci_tbl[] __devinitdata = {
+static struct pci_device_id pvr2fb_pci_tbl[] = {
{ PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_NEON250,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0, },
@@ -979,7 +979,7 @@ static struct pci_driver pvr2fb_pci_driver = {
.name = "pvr2fb",
.id_table = pvr2fb_pci_tbl,
.probe = pvr2fb_pci_probe,
- .remove = __devexit_p(pvr2fb_pci_remove),
+ .remove = pvr2fb_pci_remove,
};
static int __init pvr2fb_pci_init(void)
@@ -993,8 +993,8 @@ static void __exit pvr2fb_pci_exit(void)
}
#endif /* CONFIG_PCI */
-static int __devinit pvr2_get_param(const struct pvr2_params *p, const char *s,
- int val, int size)
+static int pvr2_get_param(const struct pvr2_params *p, const char *s, int val,
+ int size)
{
int i;
diff --git a/drivers/video/pxa168fb.c b/drivers/video/pxa168fb.c
index f146089..aa9bd1f 100644
--- a/drivers/video/pxa168fb.c
+++ b/drivers/video/pxa168fb.c
@@ -560,7 +560,7 @@ static struct fb_ops pxa168fb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static int __devinit pxa168fb_init_mode(struct fb_info *info,
+static int pxa168fb_init_mode(struct fb_info *info,
struct pxa168fb_mach_info *mi)
{
struct pxa168fb_info *fbi = info->par;
@@ -600,7 +600,7 @@ static int __devinit pxa168fb_init_mode(struct fb_info *info,
return ret;
}
-static int __devinit pxa168fb_probe(struct platform_device *pdev)
+static int pxa168fb_probe(struct platform_device *pdev)
{
struct pxa168fb_mach_info *mi;
struct fb_info *info = 0;
@@ -783,7 +783,7 @@ failed_put_clk:
return ret;
}
-static int __devexit pxa168fb_remove(struct platform_device *pdev)
+static int pxa168fb_remove(struct platform_device *pdev)
{
struct pxa168fb_info *fbi = platform_get_drvdata(pdev);
struct fb_info *info;
@@ -826,7 +826,7 @@ static struct platform_driver pxa168fb_driver = {
.owner = THIS_MODULE,
},
.probe = pxa168fb_probe,
- .remove = __devexit_p(pxa168fb_remove),
+ .remove = pxa168fb_remove,
};
module_platform_driver(pxa168fb_driver);
diff --git a/drivers/video/pxa3xx-gcu.c b/drivers/video/pxa3xx-gcu.c
index 0b4ae0c..6c984ea 100644
--- a/drivers/video/pxa3xx-gcu.c
+++ b/drivers/video/pxa3xx-gcu.c
@@ -574,8 +574,7 @@ free_buffers(struct platform_device *dev,
priv->free = NULL;
}
-static int __devinit
-pxa3xx_gcu_probe(struct platform_device *dev)
+static int pxa3xx_gcu_probe(struct platform_device *dev)
{
int i, ret, irq;
struct resource *r;
@@ -714,8 +713,7 @@ err_free_priv:
return ret;
}
-static int __devexit
-pxa3xx_gcu_remove(struct platform_device *dev)
+static int pxa3xx_gcu_remove(struct platform_device *dev)
{
struct pxa3xx_gcu_priv *priv = platform_get_drvdata(dev);
struct resource *r = priv->resource_mem;
@@ -737,7 +735,7 @@ pxa3xx_gcu_remove(struct platform_device *dev)
static struct platform_driver pxa3xx_gcu_driver = {
.probe = pxa3xx_gcu_probe,
- .remove = __devexit_p(pxa3xx_gcu_remove),
+ .remove = pxa3xx_gcu_remove,
.driver = {
.owner = THIS_MODULE,
.name = DRV_NAME,
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 4fa2ad4..580f80c 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -869,8 +869,8 @@ static struct fb_ops overlay_fb_ops = {
.fb_set_par = overlayfb_set_par,
};
-static void __devinit init_pxafb_overlay(struct pxafb_info *fbi,
- struct pxafb_layer *ofb, int id)
+static void init_pxafb_overlay(struct pxafb_info *fbi, struct pxafb_layer *ofb,
+ int id)
{
sprintf(ofb->fb.fix.id, "overlay%d", id + 1);
@@ -903,8 +903,8 @@ static inline int pxafb_overlay_supported(void)
return 0;
}
-static int __devinit pxafb_overlay_map_video_memory(struct pxafb_info *pxafb,
- struct pxafb_layer *ofb)
+static int pxafb_overlay_map_video_memory(struct pxafb_info *pxafb,
+ struct pxafb_layer *ofb)
{
/* We assume that user will use at most video_mem_size for overlay fb,
* anyway, it's useless to use 16bpp main plane and 24bpp overlay
@@ -927,7 +927,7 @@ static int __devinit pxafb_overlay_map_video_memory(struct pxafb_info *pxafb,
return 0;
}
-static void __devinit pxafb_overlay_init(struct pxafb_info *fbi)
+static void pxafb_overlay_init(struct pxafb_info *fbi)
{
int i, ret;
@@ -959,7 +959,7 @@ static void __devinit pxafb_overlay_init(struct pxafb_info *fbi)
pr_info("PXA Overlay driver loaded successfully!\n");
}
-static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi)
+static void pxafb_overlay_exit(struct pxafb_info *fbi)
{
int i;
@@ -1706,7 +1706,7 @@ static const struct dev_pm_ops pxafb_pm_ops = {
};
#endif
-static int __devinit pxafb_init_video_memory(struct pxafb_info *fbi)
+static int pxafb_init_video_memory(struct pxafb_info *fbi)
{
int size = PAGE_ALIGN(fbi->video_mem_size);
@@ -1789,7 +1789,7 @@ decode_mode:
fbi->video_mem_size = video_mem_size;
}
-static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)
+static struct pxafb_info *pxafb_init_fbinfo(struct device *dev)
{
struct pxafb_info *fbi;
void *addr;
@@ -1853,7 +1853,7 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)
}
#ifdef CONFIG_FB_PXA_PARAMETERS
-static int __devinit parse_opt_mode(struct device *dev, const char *this_opt)
+static int parse_opt_mode(struct device *dev, const char *this_opt)
{
struct pxafb_mach_info *inf = dev->platform_data;
@@ -1912,7 +1912,7 @@ done:
return 0;
}
-static int __devinit parse_opt(struct device *dev, char *this_opt)
+static int parse_opt(struct device *dev, char *this_opt)
{
struct pxafb_mach_info *inf = dev->platform_data;
struct pxafb_mode_info *mode = &inf->modes[0];
@@ -2012,7 +2012,7 @@ static int __devinit parse_opt(struct device *dev, char *this_opt)
return 0;
}
-static int __devinit pxafb_parse_options(struct device *dev, char *options)
+static int pxafb_parse_options(struct device *dev, char *options)
{
char *this_opt;
int ret;
@@ -2031,7 +2031,7 @@ static int __devinit pxafb_parse_options(struct device *dev, char *options)
return 0;
}
-static char g_options[256] __devinitdata = "";
+static char g_options[256] = "";
#ifndef MODULE
static int __init pxafb_setup_options(void)
@@ -2061,8 +2061,7 @@ MODULE_PARM_DESC(options, "LCD parameters (see Documentation/fb/pxafb.txt)");
#ifdef DEBUG_VAR
/* Check for various illegal bit-combinations. Currently only
* a warning is given. */
-static void __devinit pxafb_check_options(struct device *dev,
- struct pxafb_mach_info *inf)
+static void pxafb_check_options(struct device *dev, struct pxafb_mach_info *inf)
{
if (inf->lcd_conn)
return;
@@ -2094,7 +2093,7 @@ static void __devinit pxafb_check_options(struct device *dev,
#define pxafb_check_options(...) do {} while (0)
#endif
-static int __devinit pxafb_probe(struct platform_device *dev)
+static int pxafb_probe(struct platform_device *dev)
{
struct pxafb_info *fbi;
struct pxafb_mach_info *inf;
@@ -2263,7 +2262,7 @@ failed:
return ret;
}
-static int __devexit pxafb_remove(struct platform_device *dev)
+static int pxafb_remove(struct platform_device *dev)
{
struct pxafb_info *fbi = platform_get_drvdata(dev);
struct resource *r;
@@ -2304,7 +2303,7 @@ static int __devexit pxafb_remove(struct platform_device *dev)
static struct platform_driver pxafb_driver = {
.probe = pxafb_probe,
- .remove = __devexit_p(pxafb_remove),
+ .remove = pxafb_remove,
.driver = {
.owner = THIS_MODULE,
.name = "pxa2xx-fb",
diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c
index a104e8c..d44c735 100644
--- a/drivers/video/q40fb.c
+++ b/drivers/video/q40fb.c
@@ -27,7 +27,7 @@
#define Q40_PHYS_SCREEN_ADDR 0xFE800000
-static struct fb_fix_screeninfo q40fb_fix __devinitdata = {
+static struct fb_fix_screeninfo q40fb_fix = {
.id = "Q40",
.smem_len = 1024*1024,
.type = FB_TYPE_PACKED_PIXELS,
@@ -36,7 +36,7 @@ static struct fb_fix_screeninfo q40fb_fix __devinitdata = {
.accel = FB_ACCEL_NONE,
};
-static struct fb_var_screeninfo q40fb_var __devinitdata = {
+static struct fb_var_screeninfo q40fb_var = {
.xres = 1024,
.yres = 512,
.xres_virtual = 1024,
@@ -83,7 +83,7 @@ static struct fb_ops q40fb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static int __devinit q40fb_probe(struct platform_device *dev)
+static int q40fb_probe(struct platform_device *dev)
{
struct fb_info *info;
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 90df1a6..9536715 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -205,28 +205,28 @@ MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
* ------------------------------------------------------------------------- */
/* command line data, set in rivafb_setup() */
-static int flatpanel __devinitdata = -1; /* Autodetect later */
-static int forceCRTC __devinitdata = -1;
-static bool noaccel __devinitdata = 0;
+static int flatpanel = -1; /* Autodetect later */
+static int forceCRTC = -1;
+static bool noaccel = 0;
#ifdef CONFIG_MTRR
-static bool nomtrr __devinitdata = 0;
+static bool nomtrr = 0;
#endif
#ifdef CONFIG_PMAC_BACKLIGHT
-static int backlight __devinitdata = 1;
+static int backlight = 1;
#else
-static int backlight __devinitdata = 0;
+static int backlight = 0;
#endif
-static char *mode_option __devinitdata = NULL;
+static char *mode_option = NULL;
static bool strictmode = 0;
-static struct fb_fix_screeninfo __devinitdata rivafb_fix = {
+static struct fb_fix_screeninfo rivafb_fix = {
.type = FB_TYPE_PACKED_PIXELS,
.xpanstep = 1,
.ypanstep = 1,
};
-static struct fb_var_screeninfo __devinitdata rivafb_default_var = {
+static struct fb_var_screeninfo rivafb_default_var = {
.xres = 640,
.yres = 480,
.xres_virtual = 640,
@@ -1709,7 +1709,7 @@ static struct fb_ops riva_fb_ops = {
.fb_sync = rivafb_sync,
};
-static int __devinit riva_set_fbinfo(struct fb_info *info)
+static int riva_set_fbinfo(struct fb_info *info)
{
unsigned int cmap_len;
struct riva_par *par = info->par;
@@ -1747,7 +1747,7 @@ static int __devinit riva_set_fbinfo(struct fb_info *info)
}
#ifdef CONFIG_PPC_OF
-static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
+static int riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
{
struct riva_par *par = info->par;
struct device_node *dp;
@@ -1780,7 +1780,7 @@ static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
#endif /* CONFIG_PPC_OF */
#if defined(CONFIG_FB_RIVA_I2C) && !defined(CONFIG_PPC_OF)
-static int __devinit riva_get_EDID_i2c(struct fb_info *info)
+static int riva_get_EDID_i2c(struct fb_info *info)
{
struct riva_par *par = info->par;
struct fb_var_screeninfo var;
@@ -1803,8 +1803,8 @@ static int __devinit riva_get_EDID_i2c(struct fb_info *info)
}
#endif /* CONFIG_FB_RIVA_I2C */
-static void __devinit riva_update_default_var(struct fb_var_screeninfo *var,
- struct fb_info *info)
+static void riva_update_default_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
{
struct fb_monspecs *specs = &info->monspecs;
struct fb_videomode modedb;
@@ -1836,7 +1836,7 @@ static void __devinit riva_update_default_var(struct fb_var_screeninfo *var,
}
-static void __devinit riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
+static void riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
{
NVTRACE_ENTER();
#ifdef CONFIG_PPC_OF
@@ -1850,7 +1850,7 @@ static void __devinit riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
}
-static void __devinit riva_get_edidinfo(struct fb_info *info)
+static void riva_get_edidinfo(struct fb_info *info)
{
struct fb_var_screeninfo *var = &rivafb_default_var;
struct riva_par *par = info->par;
@@ -1871,7 +1871,7 @@ static void __devinit riva_get_edidinfo(struct fb_info *info)
*
* ------------------------------------------------------------------------- */
-static u32 __devinit riva_get_arch(struct pci_dev *pd)
+static u32 riva_get_arch(struct pci_dev *pd)
{
u32 arch = 0;
@@ -1909,8 +1909,7 @@ static u32 __devinit riva_get_arch(struct pci_dev *pd)
return arch;
}
-static int __devinit rivafb_probe(struct pci_dev *pd,
- const struct pci_device_id *ent)
+static int rivafb_probe(struct pci_dev *pd, const struct pci_device_id *ent)
{
struct riva_par *default_par;
struct fb_info *info;
@@ -2105,7 +2104,7 @@ err_ret:
return ret;
}
-static void __devexit rivafb_remove(struct pci_dev *pd)
+static void rivafb_remove(struct pci_dev *pd)
{
struct fb_info *info = pci_get_drvdata(pd);
struct riva_par *par = info->par;
@@ -2145,7 +2144,7 @@ static void __devexit rivafb_remove(struct pci_dev *pd)
* ------------------------------------------------------------------------- */
#ifndef MODULE
-static int __devinit rivafb_setup(char *options)
+static int rivafb_setup(char *options)
{
char *this_opt;
@@ -2186,7 +2185,7 @@ static struct pci_driver rivafb_driver = {
.name = "rivafb",
.id_table = rivafb_pci_tbl,
.probe = rivafb_probe,
- .remove = __devexit_p(rivafb_remove),
+ .remove = rivafb_remove,
};
@@ -2197,7 +2196,7 @@ static struct pci_driver rivafb_driver = {
*
* ------------------------------------------------------------------------- */
-static int __devinit rivafb_init(void)
+static int rivafb_init(void)
{
#ifndef MODULE
char *option = NULL;
diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c
index 167400e..6a18337 100644
--- a/drivers/video/riva/rivafb-i2c.c
+++ b/drivers/video/riva/rivafb-i2c.c
@@ -86,9 +86,8 @@ static int riva_gpio_getsda(void* data)
return val;
}
-static int __devinit riva_setup_i2c_bus(struct riva_i2c_chan *chan,
- const char *name,
- unsigned int i2c_class)
+static int riva_setup_i2c_bus(struct riva_i2c_chan *chan, const char *name,
+ unsigned int i2c_class)
{
int rc;
@@ -124,7 +123,7 @@ static int __devinit riva_setup_i2c_bus(struct riva_i2c_chan *chan,
return rc;
}
-void __devinit riva_create_i2c_busses(struct riva_par *par)
+void riva_create_i2c_busses(struct riva_par *par)
{
par->chan[0].par = par;
par->chan[1].par = par;
@@ -150,7 +149,7 @@ void riva_delete_i2c_busses(struct riva_par *par)
}
}
-int __devinit riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid)
+int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid)
{
u8 *edid = NULL;
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index 28b1c6c..76d9053 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -84,7 +84,7 @@ static const char *s1d13xxxfb_prod_names[] = {
/*
* here we define the default struct fb_fix_screeninfo
*/
-static struct fb_fix_screeninfo __devinitdata s1d13xxxfb_fix = {
+static struct fb_fix_screeninfo s1d13xxxfb_fix = {
.id = S1D_FBID,
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
@@ -622,7 +622,7 @@ static struct fb_ops s1d13xxxfb_fbops = {
.fb_imageblit = cfb_imageblit,
};
-static int s1d13xxxfb_width_tab[2][4] __devinitdata = {
+static int s1d13xxxfb_width_tab[2][4] = {
{4, 8, 16, -1},
{9, 12, 18, -1},
};
@@ -642,8 +642,7 @@ static int s1d13xxxfb_width_tab[2][4] __devinitdata = {
* Note: some of the hardcoded values here might need some love to
* work on various chips, and might need to no longer be hardcoded.
*/
-static void __devinit
-s1d13xxxfb_fetch_hw_state(struct fb_info *info)
+static void s1d13xxxfb_fetch_hw_state(struct fb_info *info)
{
struct fb_var_screeninfo *var = &info->var;
struct fb_fix_screeninfo *fix = &info->fix;
@@ -764,8 +763,7 @@ s1d13xxxfb_remove(struct platform_device *pdev)
return 0;
}
-static int __devinit
-s1d13xxxfb_probe(struct platform_device *pdev)
+static int s1d13xxxfb_probe(struct platform_device *pdev)
{
struct s1d13xxxfb_par *default_par;
struct fb_info *info;
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 2ed7b63..968a625 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -189,7 +189,7 @@ struct s3c_fb_vsync {
/**
* struct s3c_fb - overall hardware state of the hardware
- * @slock: The spinlock protection for this data sturucture.
+ * @slock: The spinlock protection for this data structure.
* @dev: The device that we bound to, for printing, etc.
* @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
* @lcd_clk: The clk (sclk) feeding pixclk.
@@ -268,10 +268,10 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
case 8:
if (sfb->variant.palette[win->index] != 0) {
/* non palletised, A:1,R:2,G:3,B:2 mode */
- var->red.offset = 4;
+ var->red.offset = 5;
var->green.offset = 2;
var->blue.offset = 0;
- var->red.length = 5;
+ var->red.length = 2;
var->green.length = 3;
var->blue.length = 2;
var->transp.offset = 7;
@@ -288,6 +288,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
/* 666 with one bit alpha/transparency */
var->transp.offset = 18;
var->transp.length = 1;
+ /* drop through */
case 18:
var->bits_per_pixel = 32;
@@ -329,6 +330,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
default:
dev_err(sfb->dev, "invalid bpp\n");
+ return -EINVAL;
}
dev_dbg(sfb->dev, "%s: verified parameters\n", __func__);
@@ -1079,8 +1081,7 @@ static void s3c_fb_missing_pixclock(struct fb_videomode *mode)
*
* Allocate memory for the given framebuffer.
*/
-static int __devinit s3c_fb_alloc_memory(struct s3c_fb *sfb,
- struct s3c_fb_win *win)
+static int s3c_fb_alloc_memory(struct s3c_fb *sfb, struct s3c_fb_win *win)
{
struct s3c_fb_pd_win *windata = win->windata;
unsigned int real_size, virt_size, size;
@@ -1170,9 +1171,9 @@ static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win)
* Allocate and do the basic initialisation for one of the hardware's graphics
* windows.
*/
-static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
- struct s3c_fb_win_variant *variant,
- struct s3c_fb_win **res)
+static int s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
+ struct s3c_fb_win_variant *variant,
+ struct s3c_fb_win **res)
{
struct fb_var_screeninfo *var;
struct fb_videomode initmode;
@@ -1358,7 +1359,7 @@ static void s3c_fb_clear_win(struct s3c_fb *sfb, int win)
}
}
-static int __devinit s3c_fb_probe(struct platform_device *pdev)
+static int s3c_fb_probe(struct platform_device *pdev)
{
const struct platform_device_id *platid;
struct s3c_fb_driverdata *fbdrv;
@@ -1420,10 +1421,9 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
pm_runtime_enable(sfb->dev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- sfb->regs = devm_request_and_ioremap(dev, res);
- if (!sfb->regs) {
- dev_err(dev, "failed to map registers\n");
- ret = -ENXIO;
+ sfb->regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(sfb->regs)) {
+ ret = PTR_ERR(sfb->regs);
goto err_lcd_clk;
}
@@ -1519,7 +1519,7 @@ err_bus_clk:
* Shutdown and then release all the resources that the driver allocated
* on initialisation.
*/
-static int __devexit s3c_fb_remove(struct platform_device *pdev)
+static int s3c_fb_remove(struct platform_device *pdev)
{
struct s3c_fb *sfb = platform_get_drvdata(pdev);
int win;
@@ -1544,8 +1544,7 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int s3c_fb_suspend(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct s3c_fb *sfb = platform_get_drvdata(pdev);
+ struct s3c_fb *sfb = dev_get_drvdata(dev);
struct s3c_fb_win *win;
int win_no;
@@ -1572,8 +1571,7 @@ static int s3c_fb_suspend(struct device *dev)
static int s3c_fb_resume(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct s3c_fb *sfb = platform_get_drvdata(pdev);
+ struct s3c_fb *sfb = dev_get_drvdata(dev);
struct s3c_fb_platdata *pd = sfb->pdata;
struct s3c_fb_win *win;
int win_no;
@@ -1623,7 +1621,7 @@ static int s3c_fb_resume(struct device *dev)
if (!win)
continue;
- dev_dbg(&pdev->dev, "resuming window %d\n", win_no);
+ dev_dbg(dev, "resuming window %d\n", win_no);
s3c_fb_set_par(win->fbinfo);
}
@@ -1636,8 +1634,7 @@ static int s3c_fb_resume(struct device *dev)
#ifdef CONFIG_PM_RUNTIME
static int s3c_fb_runtime_suspend(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct s3c_fb *sfb = platform_get_drvdata(pdev);
+ struct s3c_fb *sfb = dev_get_drvdata(dev);
if (!sfb->variant.has_clksel)
clk_disable_unprepare(sfb->lcd_clk);
@@ -1649,8 +1646,7 @@ static int s3c_fb_runtime_suspend(struct device *dev)
static int s3c_fb_runtime_resume(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct s3c_fb *sfb = platform_get_drvdata(pdev);
+ struct s3c_fb *sfb = dev_get_drvdata(dev);
struct s3c_fb_platdata *pd = sfb->pdata;
clk_prepare_enable(sfb->bus_clk);
@@ -1910,7 +1906,7 @@ static struct s3c_fb_driverdata s3c_fb_data_exynos4 = {
static struct s3c_fb_driverdata s3c_fb_data_exynos5 = {
.variant = {
.nr_windows = 5,
- .vidtcon = VIDTCON0,
+ .vidtcon = FIMD_V8_VIDTCON0,
.wincon = WINCON(0),
.winmap = WINxMAP(0),
.keycon = WKEYCON,
@@ -2037,7 +2033,7 @@ static const struct dev_pm_ops s3cfb_pm_ops = {
static struct platform_driver s3c_fb_driver = {
.probe = s3c_fb_probe,
- .remove = __devexit_p(s3c_fb_remove),
+ .remove = s3c_fb_remove,
.id_table = s3c_fb_driver_ids,
.driver = {
.name = "s3c-fb",
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 1083bb9..76a0e7f 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -637,7 +637,7 @@ static struct fb_ops s3c2410fb_ops = {
* cache. Once this area is remapped, all virtual memory
* access to the video memory should occur at the new region.
*/
-static int __devinit s3c2410fb_map_video_memory(struct fb_info *info)
+static int s3c2410fb_map_video_memory(struct fb_info *info)
{
struct s3c2410fb_info *fbi = info->par;
dma_addr_t map_dma;
@@ -819,8 +819,8 @@ static inline void s3c2410fb_cpufreq_deregister(struct s3c2410fb_info *info)
static const char driver_name[] = "s3c2410fb";
-static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
- enum s3c_drv_type drv_type)
+static int s3c24xxfb_probe(struct platform_device *pdev,
+ enum s3c_drv_type drv_type)
{
struct s3c2410fb_info *info;
struct s3c2410fb_display *display;
@@ -1010,12 +1010,12 @@ dealloc_fb:
return ret;
}
-static int __devinit s3c2410fb_probe(struct platform_device *pdev)
+static int s3c2410fb_probe(struct platform_device *pdev)
{
return s3c24xxfb_probe(pdev, DRV_S3C2410);
}
-static int __devinit s3c2412fb_probe(struct platform_device *pdev)
+static int s3c2412fb_probe(struct platform_device *pdev)
{
return s3c24xxfb_probe(pdev, DRV_S3C2412);
}
@@ -1024,7 +1024,7 @@ static int __devinit s3c2412fb_probe(struct platform_device *pdev)
/*
* Cleanup
*/
-static int __devexit s3c2410fb_remove(struct platform_device *pdev)
+static int s3c2410fb_remove(struct platform_device *pdev)
{
struct fb_info *fbinfo = platform_get_drvdata(pdev);
struct s3c2410fb_info *info = fbinfo->par;
@@ -1101,7 +1101,7 @@ static int s3c2410fb_resume(struct platform_device *dev)
static struct platform_driver s3c2410fb_driver = {
.probe = s3c2410fb_probe,
- .remove = __devexit_p(s3c2410fb_remove),
+ .remove = s3c2410fb_remove,
.suspend = s3c2410fb_suspend,
.resume = s3c2410fb_resume,
.driver = {
@@ -1112,7 +1112,7 @@ static struct platform_driver s3c2410fb_driver = {
static struct platform_driver s3c2412fb_driver = {
.probe = s3c2412fb_probe,
- .remove = __devexit_p(s3c2410fb_remove),
+ .remove = s3c2410fb_remove,
.suspend = s3c2410fb_suspend,
.resume = s3c2410fb_resume,
.driver = {
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 1d00736..47ca86c 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -153,10 +153,10 @@ static const struct svga_timing_regs s3_timing_regs = {
/* Module parameters */
-static char *mode_option __devinitdata;
+static char *mode_option;
#ifdef CONFIG_MTRR
-static int mtrr __devinitdata = 1;
+static int mtrr = 1;
#endif
static int fasttext = 1;
@@ -255,7 +255,7 @@ static int s3fb_ddc_getsda(void *data)
return !!(s3fb_ddc_read(par) & DDC_SDA_IN);
}
-static int __devinit s3fb_setup_ddc_bus(struct fb_info *info)
+static int s3fb_setup_ddc_bus(struct fb_info *info)
{
struct s3fb_info *par = info->par;
@@ -1066,7 +1066,7 @@ static struct fb_ops s3fb_ops = {
/* ------------------------------------------------------------------------- */
-static int __devinit s3_identification(struct s3fb_info *par)
+static int s3_identification(struct s3fb_info *par)
{
int chip = par->chip;
@@ -1122,7 +1122,7 @@ static int __devinit s3_identification(struct s3fb_info *par)
/* PCI probe */
-static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+static int s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct pci_bus_region bus_reg;
struct resource vga_res;
@@ -1403,7 +1403,7 @@ err_enable_device:
/* PCI remove */
-static void __devexit s3_pci_remove(struct pci_dev *dev)
+static void s3_pci_remove(struct pci_dev *dev)
{
struct fb_info *info = pci_get_drvdata(dev);
struct s3fb_info __maybe_unused *par = info->par;
@@ -1509,7 +1509,7 @@ static int s3_pci_resume(struct pci_dev* dev)
/* List of boards that we are trying to support */
-static struct pci_device_id s3_devices[] __devinitdata = {
+static struct pci_device_id s3_devices[] = {
{PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8810), .driver_data = CHIP_XXX_TRIO},
{PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8811), .driver_data = CHIP_XXX_TRIO},
{PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8812), .driver_data = CHIP_M65_AURORA64VP},
@@ -1537,7 +1537,7 @@ static struct pci_driver s3fb_pci_driver = {
.name = "s3fb",
.id_table = s3_devices,
.probe = s3_pci_probe,
- .remove = __devexit_p(s3_pci_remove),
+ .remove = s3_pci_remove,
.suspend = s3_pci_suspend,
.resume = s3_pci_resume,
};
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index b632584..cfbde5e 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -1090,7 +1090,7 @@ static int sa1100fb_resume(struct platform_device *dev)
* cache. Once this area is remapped, all virtual memory
* access to the video memory should occur at the new region.
*/
-static int __devinit sa1100fb_map_video_memory(struct sa1100fb_info *fbi)
+static int sa1100fb_map_video_memory(struct sa1100fb_info *fbi)
{
/*
* We reserve one page for the palette, plus the size
@@ -1116,7 +1116,7 @@ static int __devinit sa1100fb_map_video_memory(struct sa1100fb_info *fbi)
}
/* Fake monspecs to fill in fbinfo structure */
-static struct fb_monspecs monspecs __devinitdata = {
+static struct fb_monspecs monspecs = {
.hfmin = 30000,
.hfmax = 70000,
.vfmin = 50,
@@ -1124,7 +1124,7 @@ static struct fb_monspecs monspecs __devinitdata = {
};
-static struct sa1100fb_info * __devinit sa1100fb_init_fbinfo(struct device *dev)
+static struct sa1100fb_info *sa1100fb_init_fbinfo(struct device *dev)
{
struct sa1100fb_mach_info *inf = dev->platform_data;
struct sa1100fb_info *fbi;
@@ -1205,7 +1205,7 @@ static struct sa1100fb_info * __devinit sa1100fb_init_fbinfo(struct device *dev)
return fbi;
}
-static int __devinit sa1100fb_probe(struct platform_device *pdev)
+static int sa1100fb_probe(struct platform_device *pdev)
{
struct sa1100fb_info *fbi;
struct resource *res;
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index f4f53b0..741b239 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -69,7 +69,7 @@
/* --------------------------------------------------------------------- */
-static char *mode_option __devinitdata = NULL;
+static char *mode_option = NULL;
#ifdef MODULE
@@ -1664,7 +1664,7 @@ static struct fb_ops savagefb_ops = {
/* --------------------------------------------------------------------- */
-static struct fb_var_screeninfo __devinitdata savagefb_var800x600x8 = {
+static struct fb_var_screeninfo savagefb_var800x600x8 = {
.accel_flags = FB_ACCELF_TEXT,
.xres = 800,
.yres = 600,
@@ -1715,7 +1715,7 @@ static void savage_disable_mmio(struct savagefb_par *par)
}
-static int __devinit savage_map_mmio(struct fb_info *info)
+static int savage_map_mmio(struct fb_info *info)
{
struct savagefb_par *par = info->par;
DBG("savage_map_mmio");
@@ -1761,8 +1761,7 @@ static void savage_unmap_mmio(struct fb_info *info)
}
}
-static int __devinit savage_map_video(struct fb_info *info,
- int video_len)
+static int savage_map_video(struct fb_info *info, int video_len)
{
struct savagefb_par *par = info->par;
int resource;
@@ -2052,9 +2051,8 @@ static int savage_init_hw(struct savagefb_par *par)
return videoRambytes;
}
-static int __devinit savage_init_fb_info(struct fb_info *info,
- struct pci_dev *dev,
- const struct pci_device_id *id)
+static int savage_init_fb_info(struct fb_info *info, struct pci_dev *dev,
+ const struct pci_device_id *id)
{
struct savagefb_par *par = info->par;
int err = 0;
@@ -2178,8 +2176,7 @@ static int __devinit savage_init_fb_info(struct fb_info *info,
/* --------------------------------------------------------------------- */
-static int __devinit savagefb_probe(struct pci_dev* dev,
- const struct pci_device_id* id)
+static int savagefb_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct fb_info *info;
struct savagefb_par *par;
@@ -2340,7 +2337,7 @@ static int __devinit savagefb_probe(struct pci_dev* dev,
return err;
}
-static void __devexit savagefb_remove(struct pci_dev *dev)
+static void savagefb_remove(struct pci_dev *dev)
{
struct fb_info *info = pci_get_drvdata(dev);
@@ -2449,7 +2446,7 @@ static int savagefb_resume(struct pci_dev* dev)
}
-static struct pci_device_id savagefb_devices[] __devinitdata = {
+static struct pci_device_id savagefb_devices[] = {
{PCI_VENDOR_ID_S3, PCI_CHIP_SUPSAV_MX128,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SUPERSAVAGE},
@@ -2530,7 +2527,7 @@ static struct pci_driver savagefb_driver = {
.probe = savagefb_probe,
.suspend = savagefb_suspend,
.resume = savagefb_resume,
- .remove = __devexit_p(savagefb_remove)
+ .remove = savagefb_remove,
};
/* **************************** exit-time only **************************** */
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index 53455f2..2331fad 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -47,7 +47,7 @@ static int ywrap = 0;
static int flatpanel_id = -1;
-static struct fb_fix_screeninfo sgivwfb_fix __devinitdata = {
+static struct fb_fix_screeninfo sgivwfb_fix = {
.id = "SGI Vis WS FB",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
@@ -57,7 +57,7 @@ static struct fb_fix_screeninfo sgivwfb_fix __devinitdata = {
.line_length = 640,
};
-static struct fb_var_screeninfo sgivwfb_var __devinitdata = {
+static struct fb_var_screeninfo sgivwfb_var = {
/* 640x480, 8 bpp */
.xres = 640,
.yres = 480,
@@ -79,7 +79,7 @@ static struct fb_var_screeninfo sgivwfb_var __devinitdata = {
.vmode = FB_VMODE_NONINTERLACED
};
-static struct fb_var_screeninfo sgivwfb_var1600sw __devinitdata = {
+static struct fb_var_screeninfo sgivwfb_var1600sw = {
/* 1600x1024, 8 bpp */
.xres = 1600,
.yres = 1024,
@@ -745,7 +745,7 @@ int __init sgivwfb_setup(char *options)
/*
* Initialisation
*/
-static int __devinit sgivwfb_probe(struct platform_device *dev)
+static int sgivwfb_probe(struct platform_device *dev)
{
struct sgivw_par *par;
struct fb_info *info;
@@ -825,7 +825,7 @@ fail_ioremap_regs:
return -ENXIO;
}
-static int __devexit sgivwfb_remove(struct platform_device *dev)
+static int sgivwfb_remove(struct platform_device *dev)
{
struct fb_info *info = platform_get_drvdata(dev);
@@ -845,7 +845,7 @@ static int __devexit sgivwfb_remove(struct platform_device *dev)
static struct platform_driver sgivwfb_driver = {
.probe = sgivwfb_probe,
- .remove = __devexit_p(sgivwfb_remove),
+ .remove = sgivwfb_remove,
.driver = {
.name = "sgivwfb",
},
diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c
index 83b16e2..5fbb0c7 100644
--- a/drivers/video/sh7760fb.c
+++ b/drivers/video/sh7760fb.c
@@ -431,7 +431,7 @@ static int sh7760fb_alloc_mem(struct fb_info *info)
return 0;
}
-static int __devinit sh7760fb_probe(struct platform_device *pdev)
+static int sh7760fb_probe(struct platform_device *pdev)
{
struct fb_info *info;
struct resource *res;
@@ -557,7 +557,7 @@ out_fb:
return ret;
}
-static int __devexit sh7760fb_remove(struct platform_device *dev)
+static int sh7760fb_remove(struct platform_device *dev)
{
struct fb_info *info = platform_get_drvdata(dev);
struct sh7760fb_par *par = info->par;
@@ -582,7 +582,7 @@ static struct platform_driver sh7760_lcdc_driver = {
.owner = THIS_MODULE,
},
.probe = sh7760fb_probe,
- .remove = __devexit_p(sh7760fb_remove),
+ .remove = sh7760fb_remove,
};
module_platform_driver(sh7760_lcdc_driver);
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index 3951fda..701b461 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -127,13 +127,12 @@ static void sh_mipi_shutdown(struct platform_device *pdev)
sh_mipi_dsi_enable(mipi, false);
}
-static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata)
+static int sh_mipi_setup(struct sh_mipi *mipi, const struct fb_videomode *mode)
{
void __iomem *base = mipi->base;
- struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan;
+ struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data;
u32 pctype, datatype, pixfmt, linelength, vmctr2;
u32 tmp, top, bottom, delay, div;
- bool yuv;
int bpp;
/*
@@ -146,95 +145,79 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata)
pctype = 0;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
- linelength = ch->lcd_modes[0].xres * 3;
- yuv = false;
+ linelength = mode->xres * 3;
break;
case MIPI_RGB565:
pctype = 1;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
- linelength = ch->lcd_modes[0].xres * 2;
- yuv = false;
+ linelength = mode->xres * 2;
break;
case MIPI_RGB666_LP:
pctype = 2;
datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
- linelength = ch->lcd_modes[0].xres * 3;
- yuv = false;
+ linelength = mode->xres * 3;
break;
case MIPI_RGB666:
pctype = 3;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
- linelength = (ch->lcd_modes[0].xres * 18 + 7) / 8;
- yuv = false;
+ linelength = (mode->xres * 18 + 7) / 8;
break;
case MIPI_BGR888:
pctype = 8;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
- linelength = ch->lcd_modes[0].xres * 3;
- yuv = false;
+ linelength = mode->xres * 3;
break;
case MIPI_BGR565:
pctype = 9;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
- linelength = ch->lcd_modes[0].xres * 2;
- yuv = false;
+ linelength = mode->xres * 2;
break;
case MIPI_BGR666_LP:
pctype = 0xa;
datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
- linelength = ch->lcd_modes[0].xres * 3;
- yuv = false;
+ linelength = mode->xres * 3;
break;
case MIPI_BGR666:
pctype = 0xb;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
- linelength = (ch->lcd_modes[0].xres * 18 + 7) / 8;
- yuv = false;
+ linelength = (mode->xres * 18 + 7) / 8;
break;
case MIPI_YUYV:
pctype = 4;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
- linelength = ch->lcd_modes[0].xres * 2;
- yuv = true;
+ linelength = mode->xres * 2;
break;
case MIPI_UYVY:
pctype = 5;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
- linelength = ch->lcd_modes[0].xres * 2;
- yuv = true;
+ linelength = mode->xres * 2;
break;
case MIPI_YUV420_L:
pctype = 6;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
- linelength = (ch->lcd_modes[0].xres * 12 + 7) / 8;
- yuv = true;
+ linelength = (mode->xres * 12 + 7) / 8;
break;
case MIPI_YUV420:
pctype = 7;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
/* Length of U/V line */
- linelength = (ch->lcd_modes[0].xres + 1) / 2;
- yuv = true;
+ linelength = (mode->xres + 1) / 2;
break;
default:
return -EINVAL;
}
- if ((yuv && ch->interface_type != YUV422) ||
- (!yuv && ch->interface_type != RGB24))
- return -EINVAL;
-
if (!pdata->lane)
return -EINVAL;
@@ -293,7 +276,7 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata)
*/
iowrite32(0x00000006, mipi->linkbase + DTCTR);
/* VSYNC width = 2 (<< 17) */
- iowrite32((ch->lcd_modes[0].vsync_len << pdata->vsynw_offset) |
+ iowrite32((mode->vsync_len << pdata->vsynw_offset) |
(pdata->clksrc << 16) | (pctype << 12) | datatype,
mipi->linkbase + VMCTR1);
@@ -327,7 +310,7 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata)
top = linelength << 16; /* RGBLEN */
bottom = 0x00000001;
if (pdata->flags & SH_MIPI_DSI_HSABM) /* HSALEN */
- bottom = (pdata->lane * ch->lcd_modes[0].hsync_len) - 10;
+ bottom = (pdata->lane * mode->hsync_len) - 10;
iowrite32(top | bottom , mipi->linkbase + VMLEN1);
/*
@@ -347,18 +330,18 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata)
div = 2;
if (pdata->flags & SH_MIPI_DSI_HFPBM) { /* HBPLEN */
- top = ch->lcd_modes[0].hsync_len + ch->lcd_modes[0].left_margin;
+ top = mode->hsync_len + mode->left_margin;
top = ((pdata->lane * top / div) - 10) << 16;
}
if (pdata->flags & SH_MIPI_DSI_HBPBM) { /* HFPLEN */
- bottom = ch->lcd_modes[0].right_margin;
+ bottom = mode->right_margin;
bottom = (pdata->lane * bottom / div) - 12;
}
- bpp = linelength / ch->lcd_modes[0].xres; /* byte / pixel */
+ bpp = linelength / mode->xres; /* byte / pixel */
if ((pdata->lane / div) > bpp) {
- tmp = ch->lcd_modes[0].xres / bpp; /* output cycle */
- tmp = ch->lcd_modes[0].xres - tmp; /* (input - output) cycle */
+ tmp = mode->xres / bpp; /* output cycle */
+ tmp = mode->xres - tmp; /* (input - output) cycle */
delay = (pdata->lane * tmp);
}
@@ -369,7 +352,7 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata)
/* setup LCD panel */
/* cf. drivers/video/omap/lcd_mipid.c */
- sh_mipi_dcs(ch->chan, MIPI_DCS_EXIT_SLEEP_MODE);
+ sh_mipi_dcs(pdata->channel, MIPI_DCS_EXIT_SLEEP_MODE);
msleep(120);
/*
* [7] - Page Address Mode
@@ -381,11 +364,11 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata)
* [1] - Flip Horizontal
* [0] - Flip Vertical
*/
- sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_ADDRESS_MODE, 0x00);
+ sh_mipi_dcs_param(pdata->channel, MIPI_DCS_SET_ADDRESS_MODE, 0x00);
/* cf. set_data_lines() */
- sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_PIXEL_FORMAT,
+ sh_mipi_dcs_param(pdata->channel, MIPI_DCS_SET_PIXEL_FORMAT,
pixfmt << 4);
- sh_mipi_dcs(ch->chan, MIPI_DCS_SET_DISPLAY_ON);
+ sh_mipi_dcs(pdata->channel, MIPI_DCS_SET_DISPLAY_ON);
/* Enable timeout counters */
iowrite32(0x00000f00, base + DSICTRL);
@@ -405,7 +388,7 @@ static int mipi_display_on(struct sh_mobile_lcdc_entity *entity)
if (ret < 0)
goto mipi_display_on_fail1;
- ret = sh_mipi_setup(mipi, pdata);
+ ret = sh_mipi_setup(mipi, &entity->def_mode);
if (ret < 0)
goto mipi_display_on_fail2;
@@ -550,7 +533,7 @@ efindslot:
return ret;
}
-static int __devexit sh_mipi_remove(struct platform_device *pdev)
+static int sh_mipi_remove(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -591,7 +574,7 @@ static int __devexit sh_mipi_remove(struct platform_device *pdev)
}
static struct platform_driver sh_mipi_driver = {
- .remove = __devexit_p(sh_mipi_remove),
+ .remove = sh_mipi_remove,
.shutdown = sh_mipi_shutdown,
.driver = {
.name = "sh-mipi-dsi",
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 699487c..63203ac 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -438,7 +438,7 @@ static unsigned long lcdc_sys_read_data(void *handle)
return lcdc_read(ch->lcdc, _LDDRDR) & LDDRDR_DRD_MASK;
}
-struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
+static struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
lcdc_sys_write_index,
lcdc_sys_write_data,
lcdc_sys_read_data,
@@ -586,8 +586,8 @@ static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch,
* Just turn on, if we run a resume here, the
* logo disappears.
*/
- info->var.width = monspec->max_x * 10;
- info->var.height = monspec->max_y * 10;
+ info->var.width = ch->display.width;
+ info->var.height = ch->display.height;
sh_mobile_lcdc_display_on(ch);
} else {
/* New monitor or have to wake up */
@@ -1614,6 +1614,15 @@ static int sh_mobile_lcdc_overlay_blank(int blank, struct fb_info *info)
return 1;
}
+static int
+sh_mobile_lcdc_overlay_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ struct sh_mobile_lcdc_overlay *ovl = info->par;
+
+ return dma_mmap_coherent(ovl->channel->lcdc->dev, vma, ovl->fb_mem,
+ ovl->dma_handle, ovl->fb_size);
+}
+
static struct fb_ops sh_mobile_lcdc_overlay_ops = {
.owner = THIS_MODULE,
.fb_read = fb_sys_read,
@@ -1626,6 +1635,7 @@ static struct fb_ops sh_mobile_lcdc_overlay_ops = {
.fb_ioctl = sh_mobile_lcdc_overlay_ioctl,
.fb_check_var = sh_mobile_lcdc_overlay_check_var,
.fb_set_par = sh_mobile_lcdc_overlay_set_par,
+ .fb_mmap = sh_mobile_lcdc_overlay_mmap,
};
static void
@@ -1639,7 +1649,7 @@ sh_mobile_lcdc_overlay_fb_unregister(struct sh_mobile_lcdc_overlay *ovl)
unregister_framebuffer(ovl->info);
}
-static int __devinit
+static int
sh_mobile_lcdc_overlay_fb_register(struct sh_mobile_lcdc_overlay *ovl)
{
struct sh_mobile_lcdc_priv *lcdc = ovl->channel->lcdc;
@@ -1678,7 +1688,7 @@ sh_mobile_lcdc_overlay_fb_cleanup(struct sh_mobile_lcdc_overlay *ovl)
framebuffer_release(info);
}
-static int __devinit
+static int
sh_mobile_lcdc_overlay_fb_init(struct sh_mobile_lcdc_overlay *ovl)
{
struct sh_mobile_lcdc_priv *priv = ovl->channel->lcdc;
@@ -2093,6 +2103,15 @@ static int sh_mobile_lcdc_blank(int blank, struct fb_info *info)
return 0;
}
+static int
+sh_mobile_lcdc_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ struct sh_mobile_lcdc_chan *ch = info->par;
+
+ return dma_mmap_coherent(ch->lcdc->dev, vma, ch->fb_mem,
+ ch->dma_handle, ch->fb_size);
+}
+
static struct fb_ops sh_mobile_lcdc_ops = {
.owner = THIS_MODULE,
.fb_setcolreg = sh_mobile_lcdc_setcolreg,
@@ -2108,6 +2127,7 @@ static struct fb_ops sh_mobile_lcdc_ops = {
.fb_release = sh_mobile_lcdc_release,
.fb_check_var = sh_mobile_lcdc_check_var,
.fb_set_par = sh_mobile_lcdc_set_par,
+ .fb_mmap = sh_mobile_lcdc_mmap,
};
static void
@@ -2117,7 +2137,7 @@ sh_mobile_lcdc_channel_fb_unregister(struct sh_mobile_lcdc_chan *ch)
unregister_framebuffer(ch->info);
}
-static int __devinit
+static int
sh_mobile_lcdc_channel_fb_register(struct sh_mobile_lcdc_chan *ch)
{
struct fb_info *info = ch->info;
@@ -2165,9 +2185,9 @@ sh_mobile_lcdc_channel_fb_cleanup(struct sh_mobile_lcdc_chan *ch)
framebuffer_release(info);
}
-static int __devinit
+static int
sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch,
- const struct fb_videomode *mode,
+ const struct fb_videomode *modes,
unsigned int num_modes)
{
struct sh_mobile_lcdc_priv *priv = ch->lcdc;
@@ -2193,7 +2213,7 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch,
info->pseudo_palette = &ch->pseudo_palette;
info->par = ch;
- fb_videomode_to_modelist(mode, num_modes, &info->modelist);
+ fb_videomode_to_modelist(modes, num_modes, &info->modelist);
ret = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0);
if (ret < 0) {
@@ -2227,9 +2247,9 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch,
* default.
*/
var = &info->var;
- fb_videomode_to_var(var, mode);
- var->width = ch->cfg->panel_cfg.width;
- var->height = ch->cfg->panel_cfg.height;
+ fb_videomode_to_var(var, modes);
+ var->width = ch->display.width;
+ var->height = ch->display.height;
var->xres_virtual = ch->xres_virtual;
var->yres_virtual = ch->yres_virtual;
var->activate = FB_ACTIVATE_NOW;
@@ -2262,6 +2282,7 @@ static int sh_mobile_lcdc_update_bl(struct backlight_device *bdev)
bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
brightness = 0;
+ ch->bl_brightness = brightness;
return ch->cfg->bl_info.set_brightness(brightness);
}
@@ -2269,7 +2290,7 @@ static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev)
{
struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev);
- return ch->cfg->bl_info.get_brightness();
+ return ch->bl_brightness;
}
static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev,
@@ -2396,7 +2417,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
* Probe/remove and driver init/exit
*/
-static const struct fb_videomode default_720p __devinitconst = {
+static const struct fb_videomode default_720p = {
.name = "HDMI 720p",
.xres = 1280,
.yres = 720,
@@ -2475,7 +2496,7 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
return 0;
}
-static int __devinit sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
+static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
{
int interface_type = ch->cfg->interface_type;
@@ -2515,11 +2536,11 @@ static int __devinit sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *
return 0;
}
-static int __devinit
-sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_priv *priv,
- struct sh_mobile_lcdc_overlay *ovl)
+static int
+sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_overlay *ovl)
{
const struct sh_mobile_lcdc_format_info *format;
+ struct device *dev = ovl->channel->lcdc->dev;
int ret;
if (ovl->cfg->fourcc == 0)
@@ -2528,7 +2549,7 @@ sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_priv *priv,
/* Validate the format. */
format = sh_mobile_format_info(ovl->cfg->fourcc);
if (format == NULL) {
- dev_err(priv->dev, "Invalid FOURCC %08x\n", ovl->cfg->fourcc);
+ dev_err(dev, "Invalid FOURCC %08x\n", ovl->cfg->fourcc);
return -EINVAL;
}
@@ -2556,10 +2577,10 @@ sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_priv *priv,
/* Allocate frame buffer memory. */
ovl->fb_size = ovl->cfg->max_xres * ovl->cfg->max_yres
* format->bpp / 8 * 2;
- ovl->fb_mem = dma_alloc_coherent(priv->dev, ovl->fb_size,
- &ovl->dma_handle, GFP_KERNEL);
+ ovl->fb_mem = dma_alloc_coherent(dev, ovl->fb_size, &ovl->dma_handle,
+ GFP_KERNEL);
if (!ovl->fb_mem) {
- dev_err(priv->dev, "unable to allocate buffer\n");
+ dev_err(dev, "unable to allocate buffer\n");
return -ENOMEM;
}
@@ -2570,12 +2591,12 @@ sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_priv *priv,
return 0;
}
-static int __devinit
-sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
- struct sh_mobile_lcdc_chan *ch)
+static int
+sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch)
{
const struct sh_mobile_lcdc_format_info *format;
const struct sh_mobile_lcdc_chan_cfg *cfg = ch->cfg;
+ struct device *dev = ch->lcdc->dev;
const struct fb_videomode *max_mode;
const struct fb_videomode *mode;
unsigned int num_modes;
@@ -2588,7 +2609,7 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
/* Validate the format. */
format = sh_mobile_format_info(cfg->fourcc);
if (format == NULL) {
- dev_err(priv->dev, "Invalid FOURCC %08x.\n", cfg->fourcc);
+ dev_err(dev, "Invalid FOURCC %08x.\n", cfg->fourcc);
return -EINVAL;
}
@@ -2604,7 +2625,7 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
/* NV12/NV21 buffers must have even number of lines */
if ((cfg->fourcc == V4L2_PIX_FMT_NV12 ||
cfg->fourcc == V4L2_PIX_FMT_NV21) && (mode->yres & 0x1)) {
- dev_err(priv->dev, "yres must be multiple of 2 for "
+ dev_err(dev, "yres must be multiple of 2 for "
"YCbCr420 mode.\n");
return -EINVAL;
}
@@ -2618,7 +2639,7 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
if (!max_size)
max_size = MAX_XRES * MAX_YRES;
else
- dev_dbg(priv->dev, "Found largest videomode %ux%u\n",
+ dev_dbg(dev, "Found largest videomode %ux%u\n",
max_mode->xres, max_mode->yres);
if (cfg->lcd_modes == NULL) {
@@ -2652,10 +2673,10 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
/* Allocate frame buffer memory. */
ch->fb_size = max_size * format->bpp / 8 * 2;
- ch->fb_mem = dma_alloc_coherent(priv->dev, ch->fb_size, &ch->dma_handle,
+ ch->fb_mem = dma_alloc_coherent(dev, ch->fb_size, &ch->dma_handle,
GFP_KERNEL);
if (ch->fb_mem == NULL) {
- dev_err(priv->dev, "unable to allocate buffer\n");
+ dev_err(dev, "unable to allocate buffer\n");
return -ENOMEM;
}
@@ -2663,8 +2684,7 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
if (cfg->tx_dev) {
if (!cfg->tx_dev->dev.driver ||
!try_module_get(cfg->tx_dev->dev.driver->owner)) {
- dev_warn(priv->dev,
- "unable to get transmitter device\n");
+ dev_warn(dev, "unable to get transmitter device\n");
return -EINVAL;
}
ch->tx_dev = platform_get_drvdata(cfg->tx_dev);
@@ -2675,7 +2695,7 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
return sh_mobile_lcdc_channel_fb_init(ch, mode, num_modes);
}
-static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
+static int sh_mobile_lcdc_probe(struct platform_device *pdev)
{
struct sh_mobile_lcdc_info *pdata = pdev->dev.platform_data;
struct sh_mobile_lcdc_priv *priv;
@@ -2772,9 +2792,9 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
for (i = 0; i < num_channels; i++) {
- struct sh_mobile_lcdc_chan *ch = priv->ch + i;
+ struct sh_mobile_lcdc_chan *ch = &priv->ch[i];
- error = sh_mobile_lcdc_channel_init(priv, ch);
+ error = sh_mobile_lcdc_channel_init(ch);
if (error)
goto err1;
}
@@ -2785,7 +2805,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
ovl->cfg = &pdata->overlays[i];
ovl->channel = &priv->ch[0];
- error = sh_mobile_lcdc_overlay_init(priv, ovl);
+ error = sh_mobile_lcdc_overlay_init(ovl);
if (error)
goto err1;
}
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index 0f92f65..f839ade 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -94,6 +94,7 @@ struct sh_mobile_lcdc_chan {
/* Backlight */
struct backlight_device *bl;
+ unsigned int bl_brightness;
/* FB */
struct fb_info *info;
diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
index 7a0ba8b..e0f0985 100644
--- a/drivers/video/sh_mobile_meram.c
+++ b/drivers/video/sh_mobile_meram.c
@@ -620,7 +620,7 @@ static UNIVERSAL_DEV_PM_OPS(sh_mobile_meram_dev_pm_ops,
* Probe/remove and driver init/exit
*/
-static int __devinit sh_mobile_meram_probe(struct platform_device *pdev)
+static int sh_mobile_meram_probe(struct platform_device *pdev)
{
struct sh_mobile_meram_priv *priv;
struct sh_mobile_meram_info *pdata = pdev->dev.platform_data;
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index a7a48db..977e279 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -106,8 +106,7 @@ sisfb_setdefaultparms(void)
/* ------------- Parameter parsing -------------- */
-static void __devinit
-sisfb_search_vesamode(unsigned int vesamode, bool quiet)
+static void sisfb_search_vesamode(unsigned int vesamode, bool quiet)
{
int i = 0, j = 0;
@@ -146,8 +145,7 @@ sisfb_search_vesamode(unsigned int vesamode, bool quiet)
printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
}
-static void __devinit
-sisfb_search_mode(char *name, bool quiet)
+static void sisfb_search_mode(char *name, bool quiet)
{
unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
int i = 0;
@@ -225,8 +223,7 @@ sisfb_search_mode(char *name, bool quiet)
}
#ifndef MODULE
-static void __devinit
-sisfb_get_vga_mode_from_kernel(void)
+static void sisfb_get_vga_mode_from_kernel(void)
{
#ifdef CONFIG_X86
char mymode[32];
@@ -345,8 +342,7 @@ sisfb_search_specialtiming(const char *name)
/* ----------- Various detection routines ----------- */
-static void __devinit
-sisfb_detect_custom_timing(struct sis_video_info *ivideo)
+static void sisfb_detect_custom_timing(struct sis_video_info *ivideo)
{
unsigned char *biosver = NULL;
unsigned char *biosdate = NULL;
@@ -403,8 +399,7 @@ sisfb_detect_custom_timing(struct sis_video_info *ivideo)
} while(mycustomttable[i].chipID);
}
-static bool __devinit
-sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
+static bool sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
{
int i, j, xres, yres, refresh, index;
u32 emodes;
@@ -505,8 +500,8 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
return monitor->datavalid;
}
-static void __devinit
-sisfb_handle_ddc(struct sis_video_info *ivideo, struct sisfb_monitor *monitor, int crtno)
+static void sisfb_handle_ddc(struct sis_video_info *ivideo,
+ struct sisfb_monitor *monitor, int crtno)
{
unsigned short temp, i, realcrtno = crtno;
unsigned char buffer[256];
@@ -1898,8 +1893,7 @@ static struct fb_ops sisfb_ops = {
/* ---------------- Chip generation dependent routines ---------------- */
-static struct pci_dev * __devinit
-sisfb_get_northbridge(int basechipid)
+static struct pci_dev *sisfb_get_northbridge(int basechipid)
{
struct pci_dev *pdev = NULL;
int nbridgenum, nbridgeidx, i;
@@ -1938,8 +1932,7 @@ sisfb_get_northbridge(int basechipid)
return pdev;
}
-static int __devinit
-sisfb_get_dram_size(struct sis_video_info *ivideo)
+static int sisfb_get_dram_size(struct sis_video_info *ivideo)
{
#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
u8 reg;
@@ -2038,8 +2031,7 @@ sisfb_get_dram_size(struct sis_video_info *ivideo)
/* -------------- video bridge device detection --------------- */
-static void __devinit
-sisfb_detect_VB_connect(struct sis_video_info *ivideo)
+static void sisfb_detect_VB_connect(struct sis_video_info *ivideo)
{
u8 cr32, temp;
@@ -2164,8 +2156,7 @@ sisfb_detect_VB_connect(struct sis_video_info *ivideo)
/* ------------------ Sensing routines ------------------ */
-static bool __devinit
-sisfb_test_DDC1(struct sis_video_info *ivideo)
+static bool sisfb_test_DDC1(struct sis_video_info *ivideo)
{
unsigned short old;
int count = 48;
@@ -2177,8 +2168,7 @@ sisfb_test_DDC1(struct sis_video_info *ivideo)
return (count != -1);
}
-static void __devinit
-sisfb_sense_crt1(struct sis_video_info *ivideo)
+static void sisfb_sense_crt1(struct sis_video_info *ivideo)
{
bool mustwait = false;
u8 sr1F, cr17;
@@ -2259,8 +2249,7 @@ sisfb_sense_crt1(struct sis_video_info *ivideo)
}
/* Determine and detect attached devices on SiS30x */
-static void __devinit
-SiS_SenseLCD(struct sis_video_info *ivideo)
+static void SiS_SenseLCD(struct sis_video_info *ivideo)
{
unsigned char buffer[256];
unsigned short temp, realcrtno, i;
@@ -2347,8 +2336,7 @@ SiS_SenseLCD(struct sis_video_info *ivideo)
ivideo->SiS_Pr.PanelSelfDetected = true;
}
-static int __devinit
-SISDoSense(struct sis_video_info *ivideo, u16 type, u16 test)
+static int SISDoSense(struct sis_video_info *ivideo, u16 type, u16 test)
{
int temp, mytest, result, i, j;
@@ -2377,8 +2365,7 @@ SISDoSense(struct sis_video_info *ivideo, u16 type, u16 test)
return result;
}
-static void __devinit
-SiS_Sense30x(struct sis_video_info *ivideo)
+static void SiS_Sense30x(struct sis_video_info *ivideo)
{
u8 backupP4_0d,backupP2_00,backupP2_4d,backupSR_1e,biosflag=0;
u16 svhs=0, svhs_c=0;
@@ -2518,8 +2505,7 @@ SiS_Sense30x(struct sis_video_info *ivideo)
}
/* Determine and detect attached TV's on Chrontel */
-static void __devinit
-SiS_SenseCh(struct sis_video_info *ivideo)
+static void SiS_SenseCh(struct sis_video_info *ivideo)
{
#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
u8 temp1, temp2;
@@ -2643,8 +2629,7 @@ SiS_SenseCh(struct sis_video_info *ivideo)
}
}
-static void __devinit
-sisfb_get_VB_type(struct sis_video_info *ivideo)
+static void sisfb_get_VB_type(struct sis_video_info *ivideo)
{
char stdstr[] = "sisfb: Detected";
char bridgestr[] = "video bridge";
@@ -2906,8 +2891,7 @@ sisfb_engine_init(struct sis_video_info *ivideo)
ivideo->engineok = 1;
}
-static void __devinit
-sisfb_detect_lcd_type(struct sis_video_info *ivideo)
+static void sisfb_detect_lcd_type(struct sis_video_info *ivideo)
{
u8 reg;
int i;
@@ -2962,8 +2946,7 @@ sisfb_detect_lcd_type(struct sis_video_info *ivideo)
ivideo->lcdxres, ivideo->lcdyres);
}
-static void __devinit
-sisfb_save_pdc_emi(struct sis_video_info *ivideo)
+static void sisfb_save_pdc_emi(struct sis_video_info *ivideo)
{
#ifdef CONFIG_FB_SIS_300
/* Save the current PanelDelayCompensation if the LCD is currently used */
@@ -3081,8 +3064,7 @@ sisfb_save_pdc_emi(struct sis_video_info *ivideo)
/* -------------------- Memory manager routines ---------------------- */
-static u32 __devinit
-sisfb_getheapstart(struct sis_video_info *ivideo)
+static u32 sisfb_getheapstart(struct sis_video_info *ivideo)
{
u32 ret = ivideo->sisfb_parm_mem * 1024;
u32 maxoffs = ivideo->video_size - ivideo->hwcursor_size - ivideo->cmdQueueSize;
@@ -3128,8 +3110,7 @@ sisfb_getheapstart(struct sis_video_info *ivideo)
return ret;
}
-static u32 __devinit
-sisfb_getheapsize(struct sis_video_info *ivideo)
+static u32 sisfb_getheapsize(struct sis_video_info *ivideo)
{
u32 max = ivideo->video_size - ivideo->hwcursor_size - ivideo->cmdQueueSize;
u32 ret = 0;
@@ -3154,8 +3135,7 @@ sisfb_getheapsize(struct sis_video_info *ivideo)
return ret;
}
-static int __devinit
-sisfb_heap_init(struct sis_video_info *ivideo)
+static int sisfb_heap_init(struct sis_video_info *ivideo)
{
struct SIS_OH *poh;
@@ -4061,8 +4041,8 @@ static int __init sisfb_setup(char *options)
}
#endif
-static int __devinit
-sisfb_check_rom(void __iomem *rom_base, struct sis_video_info *ivideo)
+static int sisfb_check_rom(void __iomem *rom_base,
+ struct sis_video_info *ivideo)
{
void __iomem *rom;
int romptr;
@@ -4089,8 +4069,7 @@ sisfb_check_rom(void __iomem *rom_base, struct sis_video_info *ivideo)
return 1;
}
-static unsigned char * __devinit
-sisfb_find_rom(struct pci_dev *pdev)
+static unsigned char *sisfb_find_rom(struct pci_dev *pdev)
{
struct sis_video_info *ivideo = pci_get_drvdata(pdev);
void __iomem *rom_base;
@@ -4149,9 +4128,8 @@ sisfb_find_rom(struct pci_dev *pdev)
return myrombase;
}
-static void __devinit
-sisfb_post_map_vram(struct sis_video_info *ivideo, unsigned int *mapsize,
- unsigned int min)
+static void sisfb_post_map_vram(struct sis_video_info *ivideo,
+ unsigned int *mapsize, unsigned int min)
{
if (*mapsize < (min << 20))
return;
@@ -4176,8 +4154,7 @@ sisfb_post_map_vram(struct sis_video_info *ivideo, unsigned int *mapsize,
}
#ifdef CONFIG_FB_SIS_300
-static int __devinit
-sisfb_post_300_buswidth(struct sis_video_info *ivideo)
+static int sisfb_post_300_buswidth(struct sis_video_info *ivideo)
{
void __iomem *FBAddress = ivideo->video_vbase;
unsigned short temp;
@@ -4222,7 +4199,7 @@ sisfb_post_300_buswidth(struct sis_video_info *ivideo)
return 1; /* 32bit */
}
-static const unsigned short __devinitconst SiS_DRAMType[17][5] = {
+static const unsigned short SiS_DRAMType[17][5] = {
{0x0C,0x0A,0x02,0x40,0x39},
{0x0D,0x0A,0x01,0x40,0x48},
{0x0C,0x09,0x02,0x20,0x35},
@@ -4242,10 +4219,9 @@ static const unsigned short __devinitconst SiS_DRAMType[17][5] = {
{0x09,0x08,0x01,0x01,0x00}
};
-static int __devinit
-sisfb_post_300_rwtest(struct sis_video_info *ivideo, int iteration, int buswidth,
- int PseudoRankCapacity, int PseudoAdrPinCount,
- unsigned int mapsize)
+static int sisfb_post_300_rwtest(struct sis_video_info *ivideo, int iteration,
+ int buswidth, int PseudoRankCapacity,
+ int PseudoAdrPinCount, unsigned int mapsize)
{
void __iomem *FBAddr = ivideo->video_vbase;
unsigned short sr14;
@@ -4309,8 +4285,7 @@ sisfb_post_300_rwtest(struct sis_video_info *ivideo, int iteration, int buswidth
return 0;
}
-static void __devinit
-sisfb_post_300_ramsize(struct pci_dev *pdev, unsigned int mapsize)
+static void sisfb_post_300_ramsize(struct pci_dev *pdev, unsigned int mapsize)
{
struct sis_video_info *ivideo = pci_get_drvdata(pdev);
int i, j, buswidth;
@@ -4335,8 +4310,7 @@ sisfb_post_300_ramsize(struct pci_dev *pdev, unsigned int mapsize)
}
}
-static void __devinit
-sisfb_post_sis300(struct pci_dev *pdev)
+static void sisfb_post_sis300(struct pci_dev *pdev)
{
struct sis_video_info *ivideo = pci_get_drvdata(pdev);
unsigned char *bios = ivideo->SiS_Pr.VirtualRomBase;
@@ -4547,8 +4521,7 @@ sisfb_post_sis300(struct pci_dev *pdev)
#ifdef CONFIG_FB_SIS_315
#if 0
-static void __devinit
-sisfb_post_sis315330(struct pci_dev *pdev)
+static void sisfb_post_sis315330(struct pci_dev *pdev)
{
/* TODO */
}
@@ -4559,8 +4532,7 @@ static inline int sisfb_xgi_is21(struct sis_video_info *ivideo)
return ivideo->chip_real_id == XGI_21;
}
-static void __devinit
-sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay)
+static void sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay)
{
unsigned int i;
u8 reg;
@@ -4571,9 +4543,9 @@ sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay)
}
}
-static int __devinit
-sisfb_find_host_bridge(struct sis_video_info *ivideo, struct pci_dev *mypdev,
- unsigned short pcivendor)
+static int sisfb_find_host_bridge(struct sis_video_info *ivideo,
+ struct pci_dev *mypdev,
+ unsigned short pcivendor)
{
struct pci_dev *pdev = NULL;
unsigned short temp;
@@ -4591,9 +4563,8 @@ sisfb_find_host_bridge(struct sis_video_info *ivideo, struct pci_dev *mypdev,
return ret;
}
-static int __devinit
-sisfb_post_xgi_rwtest(struct sis_video_info *ivideo, int starta,
- unsigned int enda, unsigned int mapsize)
+static int sisfb_post_xgi_rwtest(struct sis_video_info *ivideo, int starta,
+ unsigned int enda, unsigned int mapsize)
{
unsigned int pos;
int i;
@@ -4623,8 +4594,7 @@ sisfb_post_xgi_rwtest(struct sis_video_info *ivideo, int starta,
return 1;
}
-static int __devinit
-sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
+static int sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
{
unsigned int buswidth, ranksize, channelab, mapsize;
int i, j, k, l, status;
@@ -4876,8 +4846,7 @@ bail_out:
return status;
}
-static void __devinit
-sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb)
+static void sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb)
{
u8 v1, v2, v3;
int index;
@@ -4932,8 +4901,8 @@ sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb)
sisfb_post_xgi_delay(ivideo, 0x43);
}
-static void __devinit
-sisfb_post_xgi_ddr2_mrs_default(struct sis_video_info *ivideo, u8 regb)
+static void sisfb_post_xgi_ddr2_mrs_default(struct sis_video_info *ivideo,
+ u8 regb)
{
unsigned char *bios = ivideo->bios_abase;
u8 v1;
@@ -4973,8 +4942,7 @@ sisfb_post_xgi_ddr2_mrs_default(struct sis_video_info *ivideo, u8 regb)
sisfb_post_xgi_delay(ivideo, 1);
}
-static void __devinit
-sisfb_post_xgi_ddr2_mrs_xg21(struct sis_video_info *ivideo)
+static void sisfb_post_xgi_ddr2_mrs_xg21(struct sis_video_info *ivideo)
{
sisfb_post_xgi_setclocks(ivideo, 1);
@@ -5015,8 +4983,7 @@ sisfb_post_xgi_ddr2_mrs_xg21(struct sis_video_info *ivideo)
sisfb_post_xgi_delay(ivideo, 1);
}
-static void __devinit
-sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
+static void sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
{
unsigned char *bios = ivideo->bios_abase;
static const u8 cs158[8] = {
@@ -5061,8 +5028,7 @@ sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
sisfb_post_xgi_ddr2_mrs_default(ivideo, regb);
}
-static u8 __devinit
-sisfb_post_xgi_ramtype(struct sis_video_info *ivideo)
+static u8 sisfb_post_xgi_ramtype(struct sis_video_info *ivideo)
{
unsigned char *bios = ivideo->bios_abase;
u8 ramtype;
@@ -5101,8 +5067,7 @@ sisfb_post_xgi_ramtype(struct sis_video_info *ivideo)
return ramtype;
}
-static int __devinit
-sisfb_post_xgi(struct pci_dev *pdev)
+static int sisfb_post_xgi(struct pci_dev *pdev)
{
struct sis_video_info *ivideo = pci_get_drvdata(pdev);
unsigned char *bios = ivideo->bios_abase;
@@ -5839,8 +5804,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
}
#endif
-static int __devinit
-sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct sisfb_chip_info *chipinfo = &sisfb_chip_info[ent->driver_data];
struct sis_video_info *ivideo = NULL;
@@ -6530,7 +6494,7 @@ error_3: vfree(ivideo->bios_abase);
/* PCI DEVICE HANDLING */
/*****************************************************/
-static void __devexit sisfb_remove(struct pci_dev *pdev)
+static void sisfb_remove(struct pci_dev *pdev)
{
struct sis_video_info *ivideo = pci_get_drvdata(pdev);
struct fb_info *sis_fb_info = ivideo->memyselfandi;
@@ -6591,7 +6555,7 @@ static struct pci_driver sisfb_driver = {
.name = "sisfb",
.id_table = sisfb_pci_table,
.probe = sisfb_probe,
- .remove = __devexit_p(sisfb_remove)
+ .remove = sisfb_remove,
};
static int __init sisfb_init(void)
diff --git a/drivers/video/sis/sis_main.h b/drivers/video/sis/sis_main.h
index 9540e97..32e23c2 100644
--- a/drivers/video/sis/sis_main.h
+++ b/drivers/video/sis/sis_main.h
@@ -98,7 +98,7 @@ static struct sisfb_chip_info {
int hwcursor_size;
int CRT2_write_enable;
const char *chip_name;
-} sisfb_chip_info[] __devinitdata = {
+} sisfb_chip_info[] = {
{ SIS_300, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 300/305" },
{ SIS_540, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 540" },
{ SIS_630, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 630" },
@@ -113,7 +113,7 @@ static struct sisfb_chip_info {
{ XGI_40, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "XGI V3XT/V5/V8" },
};
-static struct pci_device_id __devinitdata sisfb_pci_table[] = {
+static struct pci_device_id sisfb_pci_table[] = {
#ifdef CONFIG_FB_SIS_300
{ PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
@@ -317,7 +317,7 @@ static struct _sis_lcd_data {
u16 xres;
u16 yres;
u8 default_mode_idx;
-} sis_lcd_data[] __devinitdata = {
+} sis_lcd_data[] = {
{ LCD_640x480, 640, 480, 23 },
{ LCD_800x600, 800, 600, 43 },
{ LCD_1024x600, 1024, 600, 67 },
@@ -339,21 +339,21 @@ static struct _sis_lcd_data {
};
/* CR36 evaluation */
-static unsigned short sis300paneltype[] __devinitdata = {
+static unsigned short sis300paneltype[] = {
LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
LCD_1280x960, LCD_640x480, LCD_1024x600, LCD_1152x768,
LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN,
LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN
};
-static unsigned short sis310paneltype[] __devinitdata = {
+static unsigned short sis310paneltype[] = {
LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
LCD_320x240_2, LCD_320x240_3, LCD_UNKNOWN, LCD_UNKNOWN
};
-static unsigned short sis661paneltype[] __devinitdata = {
+static unsigned short sis661paneltype[] = {
LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
LCD_1280x854, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
@@ -466,7 +466,7 @@ static struct _sisfbddcsmodes {
u16 h;
u16 v;
u32 d;
-} sisfb_ddcsmodes[] __devinitdata = {
+} sisfb_ddcsmodes[] = {
{ 0x10000, 67, 75, 108000},
{ 0x08000, 48, 72, 50000},
{ 0x04000, 46, 75, 49500},
@@ -488,7 +488,7 @@ static struct _sisfbddcfmodes {
u16 v;
u16 h;
u32 d;
-} sisfb_ddcfmodes[] __devinitdata = {
+} sisfb_ddcfmodes[] = {
{ 1280, 1024, 85, 92, 157500},
{ 1600, 1200, 60, 75, 162000},
{ 1600, 1200, 65, 82, 175500},
@@ -505,7 +505,7 @@ static struct _chswtable {
u16 subsysCard;
char *vendorName;
char *cardName;
-} mychswtable[] __devinitdata = {
+} mychswtable[] = {
{ 0x1631, 0x1002, "Mitachi", "0x1002" },
{ 0x1071, 0x7521, "Mitac" , "7521P" },
{ 0, 0, "" , "" }
@@ -525,7 +525,7 @@ static struct _customttable {
char *cardName;
u32 SpecialID;
char *optionName;
-} mycustomttable[] __devinitdata = {
+} mycustomttable[] = {
{ SIS_630, "2.00.07", "09/27/2002-13:38:25",
0x3240A8,
{ 0x220, 0x227, 0x228, 0x229, 0x0ee },
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index 5b6abc6..2d4694c 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -63,7 +63,7 @@
/*
* Driver data
*/
-static char *mode_option __devinitdata;
+static char *mode_option;
/*
* If your driver supports multiple boards, you should make the
@@ -84,7 +84,7 @@ struct xxx_par;
* if we don't use modedb. If we do use modedb see xxxfb_init how to use it
* to get a fb_var_screeninfo. Otherwise define a default var as well.
*/
-static struct fb_fix_screeninfo xxxfb_fix __devinitdata = {
+static struct fb_fix_screeninfo xxxfb_fix = {
.id = "FB's name",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
@@ -678,8 +678,7 @@ static struct fb_ops xxxfb_ops = {
*/
/* static int __init xxfb_probe (struct platform_device *pdev) -- for platform devs */
-static int __devinit xxxfb_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+static int xxxfb_probe(struct pci_dev *dev, const struct pci_device_id *ent)
{
struct fb_info *info;
struct xxx_par *par;
@@ -705,9 +704,7 @@ static int __devinit xxxfb_probe(struct pci_dev *dev,
*/
info->screen_base = framebuffer_virtual_memory;
info->fbops = &xxxfb_ops;
- info->fix = xxxfb_fix; /* this will be the only time xxxfb_fix will be
- * used, so mark it as __devinitdata
- */
+ info->fix = xxxfb_fix;
info->pseudo_palette = pseudo_palette; /* The pseudopalette is an
* 16-member array
*/
@@ -836,8 +833,8 @@ static int __devinit xxxfb_probe(struct pci_dev *dev,
/*
* Cleanup
*/
-/* static void __devexit xxxfb_remove(struct platform_device *pdev) */
-static void __devexit xxxfb_remove(struct pci_dev *dev)
+/* static void xxxfb_remove(struct platform_device *pdev) */
+static void xxxfb_remove(struct pci_dev *dev)
{
struct fb_info *info = pci_get_drvdata(dev);
/* or platform_get_drvdata(pdev); */
@@ -899,7 +896,7 @@ static struct pci_driver xxxfb_driver = {
.name = "xxxfb",
.id_table = xxxfb_id_table,
.probe = xxxfb_probe,
- .remove = __devexit_p(xxxfb_remove),
+ .remove = xxxfb_remove,
.suspend = xxxfb_suspend, /* optional but recommended */
.resume = xxxfb_resume, /* optional but recommended */
};
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index 3690eff..1501979 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -46,7 +46,7 @@
static char *fb_mode = "640x480-16@60";
static unsigned long default_bpp = 16;
-static struct fb_videomode __devinitdata sm501_default_mode = {
+static struct fb_videomode sm501_default_mode = {
.refresh = 60,
.xres = 640,
.yres = 480,
@@ -1664,8 +1664,7 @@ static void sm501fb_stop(struct sm501fb_info *info)
resource_size(info->regs_res));
}
-static int __devinit sm501fb_init_fb(struct fb_info *fb,
- enum sm501_controller head,
+static int sm501fb_init_fb(struct fb_info *fb, enum sm501_controller head,
const char *fbname)
{
struct sm501_platdata_fbsub *pd;
@@ -1850,8 +1849,8 @@ static struct sm501_platdata_fb sm501fb_def_pdata = {
static char driver_name_crt[] = "sm501fb-crt";
static char driver_name_pnl[] = "sm501fb-panel";
-static int __devinit sm501fb_probe_one(struct sm501fb_info *info,
- enum sm501_controller head)
+static int sm501fb_probe_one(struct sm501fb_info *info,
+ enum sm501_controller head)
{
unsigned char *name = (head == HEAD_CRT) ? "crt" : "panel";
struct sm501_platdata_fbsub *pd;
@@ -1892,9 +1891,8 @@ static void sm501_free_init_fb(struct sm501fb_info *info,
fb_dealloc_cmap(&fbi->cmap);
}
-static int __devinit sm501fb_start_one(struct sm501fb_info *info,
- enum sm501_controller head,
- const char *drvname)
+static int sm501fb_start_one(struct sm501fb_info *info,
+ enum sm501_controller head, const char *drvname)
{
struct fb_info *fbi = info->fb[head];
int ret;
@@ -1922,7 +1920,7 @@ static int __devinit sm501fb_start_one(struct sm501fb_info *info,
return 0;
}
-static int __devinit sm501fb_probe(struct platform_device *pdev)
+static int sm501fb_probe(struct platform_device *pdev)
{
struct sm501fb_info *info;
struct device *dev = &pdev->dev;
diff --git a/drivers/video/ssd1307fb.c b/drivers/video/ssd1307fb.c
new file mode 100644
index 0000000..395cb6a
--- /dev/null
+++ b/drivers/video/ssd1307fb.c
@@ -0,0 +1,397 @@
+/*
+ * Driver for the Solomon SSD1307 OLED controler
+ *
+ * Copyright 2012 Free Electrons
+ *
+ * Licensed under the GPLv2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/uaccess.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/pwm.h>
+#include <linux/delay.h>
+
+#define SSD1307FB_WIDTH 96
+#define SSD1307FB_HEIGHT 16
+
+#define SSD1307FB_DATA 0x40
+#define SSD1307FB_COMMAND 0x80
+
+#define SSD1307FB_CONTRAST 0x81
+#define SSD1307FB_SEG_REMAP_ON 0xa1
+#define SSD1307FB_DISPLAY_OFF 0xae
+#define SSD1307FB_DISPLAY_ON 0xaf
+#define SSD1307FB_START_PAGE_ADDRESS 0xb0
+
+struct ssd1307fb_par {
+ struct i2c_client *client;
+ struct fb_info *info;
+ struct pwm_device *pwm;
+ u32 pwm_period;
+ int reset;
+};
+
+static struct fb_fix_screeninfo ssd1307fb_fix = {
+ .id = "Solomon SSD1307",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_MONO10,
+ .xpanstep = 0,
+ .ypanstep = 0,
+ .ywrapstep = 0,
+ .line_length = SSD1307FB_WIDTH / 8,
+ .accel = FB_ACCEL_NONE,
+};
+
+static struct fb_var_screeninfo ssd1307fb_var = {
+ .xres = SSD1307FB_WIDTH,
+ .yres = SSD1307FB_HEIGHT,
+ .xres_virtual = SSD1307FB_WIDTH,
+ .yres_virtual = SSD1307FB_HEIGHT,
+ .bits_per_pixel = 1,
+};
+
+static int ssd1307fb_write_array(struct i2c_client *client, u8 type, u8 *cmd, u32 len)
+{
+ u8 *buf;
+ int ret = 0;
+
+ buf = kzalloc(len + 1, GFP_KERNEL);
+ if (!buf) {
+ dev_err(&client->dev, "Couldn't allocate sending buffer.\n");
+ return -ENOMEM;
+ }
+
+ buf[0] = type;
+ memcpy(buf + 1, cmd, len);
+
+ ret = i2c_master_send(client, buf, len + 1);
+ if (ret != len + 1) {
+ dev_err(&client->dev, "Couldn't send I2C command.\n");
+ goto error;
+ }
+
+error:
+ kfree(buf);
+ return ret;
+}
+
+static inline int ssd1307fb_write_cmd_array(struct i2c_client *client, u8 *cmd, u32 len)
+{
+ return ssd1307fb_write_array(client, SSD1307FB_COMMAND, cmd, len);
+}
+
+static inline int ssd1307fb_write_cmd(struct i2c_client *client, u8 cmd)
+{
+ return ssd1307fb_write_cmd_array(client, &cmd, 1);
+}
+
+static inline int ssd1307fb_write_data_array(struct i2c_client *client, u8 *cmd, u32 len)
+{
+ return ssd1307fb_write_array(client, SSD1307FB_DATA, cmd, len);
+}
+
+static inline int ssd1307fb_write_data(struct i2c_client *client, u8 data)
+{
+ return ssd1307fb_write_data_array(client, &data, 1);
+}
+
+static void ssd1307fb_update_display(struct ssd1307fb_par *par)
+{
+ u8 *vmem = par->info->screen_base;
+ int i, j, k;
+
+ /*
+ * The screen is divided in pages, each having a height of 8
+ * pixels, and the width of the screen. When sending a byte of
+ * data to the controller, it gives the 8 bits for the current
+ * column. I.e, the first byte are the 8 bits of the first
+ * column, then the 8 bits for the second column, etc.
+ *
+ *
+ * Representation of the screen, assuming it is 5 bits
+ * wide. Each letter-number combination is a bit that controls
+ * one pixel.
+ *
+ * A0 A1 A2 A3 A4
+ * B0 B1 B2 B3 B4
+ * C0 C1 C2 C3 C4
+ * D0 D1 D2 D3 D4
+ * E0 E1 E2 E3 E4
+ * F0 F1 F2 F3 F4
+ * G0 G1 G2 G3 G4
+ * H0 H1 H2 H3 H4
+ *
+ * If you want to update this screen, you need to send 5 bytes:
+ * (1) A0 B0 C0 D0 E0 F0 G0 H0
+ * (2) A1 B1 C1 D1 E1 F1 G1 H1
+ * (3) A2 B2 C2 D2 E2 F2 G2 H2
+ * (4) A3 B3 C3 D3 E3 F3 G3 H3
+ * (5) A4 B4 C4 D4 E4 F4 G4 H4
+ */
+
+ for (i = 0; i < (SSD1307FB_HEIGHT / 8); i++) {
+ ssd1307fb_write_cmd(par->client, SSD1307FB_START_PAGE_ADDRESS + (i + 1));
+ ssd1307fb_write_cmd(par->client, 0x00);
+ ssd1307fb_write_cmd(par->client, 0x10);
+
+ for (j = 0; j < SSD1307FB_WIDTH; j++) {
+ u8 buf = 0;
+ for (k = 0; k < 8; k++) {
+ u32 page_length = SSD1307FB_WIDTH * i;
+ u32 index = page_length + (SSD1307FB_WIDTH * k + j) / 8;
+ u8 byte = *(vmem + index);
+ u8 bit = byte & (1 << (j % 8));
+ bit = bit >> (j % 8);
+ buf |= bit << k;
+ }
+ ssd1307fb_write_data(par->client, buf);
+ }
+ }
+}
+
+
+static ssize_t ssd1307fb_write(struct fb_info *info, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct ssd1307fb_par *par = info->par;
+ unsigned long total_size;
+ unsigned long p = *ppos;
+ u8 __iomem *dst;
+
+ total_size = info->fix.smem_len;
+
+ if (p > total_size)
+ return -EINVAL;
+
+ if (count + p > total_size)
+ count = total_size - p;
+
+ if (!count)
+ return -EINVAL;
+
+ dst = (void __force *) (info->screen_base + p);
+
+ if (copy_from_user(dst, buf, count))
+ return -EFAULT;
+
+ ssd1307fb_update_display(par);
+
+ *ppos += count;
+
+ return count;
+}
+
+static void ssd1307fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+{
+ struct ssd1307fb_par *par = info->par;
+ sys_fillrect(info, rect);
+ ssd1307fb_update_display(par);
+}
+
+static void ssd1307fb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+{
+ struct ssd1307fb_par *par = info->par;
+ sys_copyarea(info, area);
+ ssd1307fb_update_display(par);
+}
+
+static void ssd1307fb_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+ struct ssd1307fb_par *par = info->par;
+ sys_imageblit(info, image);
+ ssd1307fb_update_display(par);
+}
+
+static struct fb_ops ssd1307fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_read = fb_sys_read,
+ .fb_write = ssd1307fb_write,
+ .fb_fillrect = ssd1307fb_fillrect,
+ .fb_copyarea = ssd1307fb_copyarea,
+ .fb_imageblit = ssd1307fb_imageblit,
+};
+
+static void ssd1307fb_deferred_io(struct fb_info *info,
+ struct list_head *pagelist)
+{
+ ssd1307fb_update_display(info->par);
+}
+
+static struct fb_deferred_io ssd1307fb_defio = {
+ .delay = HZ,
+ .deferred_io = ssd1307fb_deferred_io,
+};
+
+static int ssd1307fb_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct fb_info *info;
+ u32 vmem_size = SSD1307FB_WIDTH * SSD1307FB_HEIGHT / 8;
+ struct ssd1307fb_par *par;
+ u8 *vmem;
+ int ret;
+
+ if (!client->dev.of_node) {
+ dev_err(&client->dev, "No device tree data found!\n");
+ return -EINVAL;
+ }
+
+ info = framebuffer_alloc(sizeof(struct ssd1307fb_par), &client->dev);
+ if (!info) {
+ dev_err(&client->dev, "Couldn't allocate framebuffer.\n");
+ return -ENOMEM;
+ }
+
+ vmem = devm_kzalloc(&client->dev, vmem_size, GFP_KERNEL);
+ if (!vmem) {
+ dev_err(&client->dev, "Couldn't allocate graphical memory.\n");
+ ret = -ENOMEM;
+ goto fb_alloc_error;
+ }
+
+ info->fbops = &ssd1307fb_ops;
+ info->fix = ssd1307fb_fix;
+ info->fbdefio = &ssd1307fb_defio;
+
+ info->var = ssd1307fb_var;
+ info->var.red.length = 1;
+ info->var.red.offset = 0;
+ info->var.green.length = 1;
+ info->var.green.offset = 0;
+ info->var.blue.length = 1;
+ info->var.blue.offset = 0;
+
+ info->screen_base = (u8 __force __iomem *)vmem;
+ info->fix.smem_start = (unsigned long)vmem;
+ info->fix.smem_len = vmem_size;
+
+ fb_deferred_io_init(info);
+
+ par = info->par;
+ par->info = info;
+ par->client = client;
+
+ par->reset = of_get_named_gpio(client->dev.of_node,
+ "reset-gpios", 0);
+ if (!gpio_is_valid(par->reset)) {
+ ret = -EINVAL;
+ goto reset_oled_error;
+ }
+
+ ret = devm_gpio_request_one(&client->dev, par->reset,
+ GPIOF_OUT_INIT_HIGH,
+ "oled-reset");
+ if (ret) {
+ dev_err(&client->dev,
+ "failed to request gpio %d: %d\n",
+ par->reset, ret);
+ goto reset_oled_error;
+ }
+
+ par->pwm = pwm_get(&client->dev, NULL);
+ if (IS_ERR(par->pwm)) {
+ dev_err(&client->dev, "Could not get PWM from device tree!\n");
+ ret = PTR_ERR(par->pwm);
+ goto pwm_error;
+ }
+
+ par->pwm_period = pwm_get_period(par->pwm);
+
+ dev_dbg(&client->dev, "Using PWM%d with a %dns period.\n", par->pwm->pwm, par->pwm_period);
+
+ ret = register_framebuffer(info);
+ if (ret) {
+ dev_err(&client->dev, "Couldn't register the framebuffer\n");
+ goto fbreg_error;
+ }
+
+ i2c_set_clientdata(client, info);
+
+ /* Reset the screen */
+ gpio_set_value(par->reset, 0);
+ udelay(4);
+ gpio_set_value(par->reset, 1);
+ udelay(4);
+
+ /* Enable the PWM */
+ pwm_config(par->pwm, par->pwm_period / 2, par->pwm_period);
+ pwm_enable(par->pwm);
+
+ /* Map column 127 of the OLED to segment 0 */
+ ret = ssd1307fb_write_cmd(client, SSD1307FB_SEG_REMAP_ON);
+ if (ret < 0) {
+ dev_err(&client->dev, "Couldn't remap the screen.\n");
+ goto remap_error;
+ }
+
+ /* Turn on the display */
+ ret = ssd1307fb_write_cmd(client, SSD1307FB_DISPLAY_ON);
+ if (ret < 0) {
+ dev_err(&client->dev, "Couldn't turn the display on.\n");
+ goto remap_error;
+ }
+
+ dev_info(&client->dev, "fb%d: %s framebuffer device registered, using %d bytes of video memory\n", info->node, info->fix.id, vmem_size);
+
+ return 0;
+
+remap_error:
+ unregister_framebuffer(info);
+ pwm_disable(par->pwm);
+fbreg_error:
+ pwm_put(par->pwm);
+pwm_error:
+reset_oled_error:
+ fb_deferred_io_cleanup(info);
+fb_alloc_error:
+ framebuffer_release(info);
+ return ret;
+}
+
+static int ssd1307fb_remove(struct i2c_client *client)
+{
+ struct fb_info *info = i2c_get_clientdata(client);
+ struct ssd1307fb_par *par = info->par;
+
+ unregister_framebuffer(info);
+ pwm_disable(par->pwm);
+ pwm_put(par->pwm);
+ fb_deferred_io_cleanup(info);
+ framebuffer_release(info);
+
+ return 0;
+}
+
+static const struct i2c_device_id ssd1307fb_i2c_id[] = {
+ { "ssd1307fb", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ssd1307fb_i2c_id);
+
+static const struct of_device_id ssd1307fb_of_match[] = {
+ { .compatible = "solomon,ssd1307fb-i2c" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ssd1307fb_of_match);
+
+static struct i2c_driver ssd1307fb_driver = {
+ .probe = ssd1307fb_probe,
+ .remove = ssd1307fb_remove,
+ .id_table = ssd1307fb_i2c_id,
+ .driver = {
+ .name = "ssd1307fb",
+ .of_match_table = of_match_ptr(ssd1307fb_of_match),
+ .owner = THIS_MODULE,
+ },
+};
+
+module_i2c_driver(ssd1307fb_driver);
+
+MODULE_DESCRIPTION("FB driver for the Solomon SSD1307 OLED controler");
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 111fb32..9c00026 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -104,7 +104,7 @@ static bool slowpci; /* slow PCI settings */
*/
#define DEFAULT_VIDEO_MODE "640x480@60"
-static char *mode_option __devinitdata = DEFAULT_VIDEO_MODE;
+static char *mode_option = DEFAULT_VIDEO_MODE;
enum {
ID_VOODOO1 = 0,
@@ -113,7 +113,7 @@ enum {
#define IS_VOODOO2(par) ((par)->type == ID_VOODOO2)
-static struct sst_spec voodoo_spec[] __devinitdata = {
+static struct sst_spec voodoo_spec[] = {
{ .name = "Voodoo Graphics", .default_gfx_clock = 50000, .max_gfxclk = 60 },
{ .name = "Voodoo2", .default_gfx_clock = 75000, .max_gfxclk = 85 },
};
@@ -822,7 +822,7 @@ static void sstfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
/*
* get lfb size
*/
-static int __devinit sst_get_memsize(struct fb_info *info, __u32 *memsize)
+static int sst_get_memsize(struct fb_info *info, __u32 *memsize)
{
u8 __iomem *fbbase_virt = info->screen_base;
@@ -865,7 +865,7 @@ static int __devinit sst_get_memsize(struct fb_info *info, __u32 *memsize)
/* fbi should be idle, and fifo emty and mem disabled */
/* supposed to detect AT&T ATT20C409 and Ti TVP3409 ramdacs */
-static int __devinit sst_detect_att(struct fb_info *info)
+static int sst_detect_att(struct fb_info *info)
{
struct sstfb_par *par = info->par;
int i, mir, dir;
@@ -890,7 +890,7 @@ static int __devinit sst_detect_att(struct fb_info *info)
return 0;
}
-static int __devinit sst_detect_ti(struct fb_info *info)
+static int sst_detect_ti(struct fb_info *info)
{
struct sstfb_par *par = info->par;
int i, mir, dir;
@@ -926,7 +926,7 @@ static int __devinit sst_detect_ti(struct fb_info *info)
* touched...
* is it really safe ? how can i reset this ramdac ? geee...
*/
-static int __devinit sst_detect_ics(struct fb_info *info)
+static int sst_detect_ics(struct fb_info *info)
{
struct sstfb_par *par = info->par;
int m_clk0_1, m_clk0_7, m_clk1_b;
@@ -1105,7 +1105,7 @@ static void sst_set_vidmod_ics(struct fb_info *info, const int bpp)
*/
-static struct dac_switch dacs[] __devinitdata = {
+static struct dac_switch dacs[] = {
{ .name = "TI TVP3409",
.detect = sst_detect_ti,
.set_pll = sst_set_pll_att_ti,
@@ -1121,7 +1121,7 @@ static struct dac_switch dacs[] __devinitdata = {
.set_vidmod = sst_set_vidmod_ics },
};
-static int __devinit sst_detect_dactype(struct fb_info *info, struct sstfb_par *par)
+static int sst_detect_dactype(struct fb_info *info, struct sstfb_par *par)
{
int i, ret = 0;
@@ -1140,7 +1140,7 @@ static int __devinit sst_detect_dactype(struct fb_info *info, struct sstfb_par *
/*
* Internal Routines
*/
-static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
+static int sst_init(struct fb_info *info, struct sstfb_par *par)
{
u32 fbiinit0, fbiinit1, fbiinit4;
struct pci_dev *dev = par->dev;
@@ -1239,7 +1239,7 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
return 1;
}
-static void __devexit sst_shutdown(struct fb_info *info)
+static void sst_shutdown(struct fb_info *info)
{
struct sstfb_par *par = info->par;
struct pci_dev *dev = par->dev;
@@ -1271,7 +1271,7 @@ static void __devexit sst_shutdown(struct fb_info *info)
/*
* Interface to the world
*/
-static int __devinit sstfb_setup(char *options)
+static int sstfb_setup(char *options)
{
char *this_opt;
@@ -1317,8 +1317,7 @@ static struct fb_ops sstfb_ops = {
.fb_ioctl = sstfb_ioctl,
};
-static int __devinit sstfb_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
+static int sstfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct fb_info *info;
struct fb_fix_screeninfo *fix;
@@ -1458,7 +1457,7 @@ fail_mmio_mem:
return -ENXIO; /* no voodoo detected */
}
-static void __devexit sstfb_remove(struct pci_dev *pdev)
+static void sstfb_remove(struct pci_dev *pdev)
{
struct sstfb_par *par;
struct fb_info *info;
@@ -1490,11 +1489,11 @@ static struct pci_driver sstfb_driver = {
.name = "sstfb",
.id_table = sstfb_id_tbl,
.probe = sstfb_probe,
- .remove = __devexit_p(sstfb_remove),
+ .remove = sstfb_remove,
};
-static int __devinit sstfb_init(void)
+static int sstfb_init(void)
{
char *option = NULL;
@@ -1505,7 +1504,7 @@ static int __devinit sstfb_init(void)
return pci_register_driver(&sstfb_driver);
}
-static void __devexit sstfb_exit(void)
+static void sstfb_exit(void)
{
pci_unregister_driver(&sstfb_driver);
}
diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c
index 729a507..cc6f48b 100644
--- a/drivers/video/sunxvr1000.c
+++ b/drivers/video/sunxvr1000.c
@@ -25,7 +25,7 @@ struct gfb_info {
u32 pseudo_palette[16];
};
-static int __devinit gfb_get_props(struct gfb_info *gp)
+static int gfb_get_props(struct gfb_info *gp)
{
gp->width = of_getintprop_default(gp->of_node, "width", 0);
gp->height = of_getintprop_default(gp->of_node, "height", 0);
@@ -66,7 +66,7 @@ static struct fb_ops gfb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static int __devinit gfb_set_fbinfo(struct gfb_info *gp)
+static int gfb_set_fbinfo(struct gfb_info *gp)
{
struct fb_info *info = gp->info;
struct fb_var_screeninfo *var = &info->var;
@@ -111,7 +111,7 @@ static int __devinit gfb_set_fbinfo(struct gfb_info *gp)
return 0;
}
-static int __devinit gfb_probe(struct platform_device *op)
+static int gfb_probe(struct platform_device *op)
{
struct device_node *dp = op->dev.of_node;
struct fb_info *info;
@@ -173,7 +173,7 @@ err_out:
return err;
}
-static int __devexit gfb_remove(struct platform_device *op)
+static int gfb_remove(struct platform_device *op)
{
struct fb_info *info = dev_get_drvdata(&op->dev);
struct gfb_info *gp = info->par;
@@ -201,7 +201,7 @@ MODULE_DEVICE_TABLE(of, ffb_match);
static struct platform_driver gfb_driver = {
.probe = gfb_probe,
- .remove = __devexit_p(gfb_remove),
+ .remove = gfb_remove,
.driver = {
.name = "gfb",
.owner = THIS_MODULE,
diff --git a/drivers/video/sunxvr2500.c b/drivers/video/sunxvr2500.c
index 7fbcba8..843b6ba 100644
--- a/drivers/video/sunxvr2500.c
+++ b/drivers/video/sunxvr2500.c
@@ -29,7 +29,7 @@ struct s3d_info {
u32 pseudo_palette[16];
};
-static int __devinit s3d_get_props(struct s3d_info *sp)
+static int s3d_get_props(struct s3d_info *sp)
{
sp->width = of_getintprop_default(sp->of_node, "width", 0);
sp->height = of_getintprop_default(sp->of_node, "height", 0);
@@ -70,7 +70,7 @@ static struct fb_ops s3d_ops = {
.fb_imageblit = cfb_imageblit,
};
-static int __devinit s3d_set_fbinfo(struct s3d_info *sp)
+static int s3d_set_fbinfo(struct s3d_info *sp)
{
struct fb_info *info = sp->info;
struct fb_var_screeninfo *var = &info->var;
@@ -115,8 +115,8 @@ static int __devinit s3d_set_fbinfo(struct s3d_info *sp)
return 0;
}
-static int __devinit s3d_pci_register(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int s3d_pci_register(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
struct fb_info *info;
struct s3d_info *sp;
@@ -219,7 +219,7 @@ err_out:
return err;
}
-static void __devexit s3d_pci_unregister(struct pci_dev *pdev)
+static void s3d_pci_unregister(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct s3d_info *sp = info->par;
@@ -251,7 +251,7 @@ static struct pci_driver s3d_driver = {
.name = "s3d",
.id_table = s3d_pci_table,
.probe = s3d_pci_register,
- .remove = __devexit_p(s3d_pci_unregister),
+ .remove = s3d_pci_unregister,
};
static int __init s3d_init(void)
diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c
index 6c71b1b..387350d 100644
--- a/drivers/video/sunxvr500.c
+++ b/drivers/video/sunxvr500.c
@@ -51,7 +51,7 @@ struct e3d_info {
u32 pseudo_palette[16];
};
-static int __devinit e3d_get_props(struct e3d_info *ep)
+static int e3d_get_props(struct e3d_info *ep)
{
ep->width = of_getintprop_default(ep->of_node, "width", 0);
ep->height = of_getintprop_default(ep->of_node, "height", 0);
@@ -193,7 +193,7 @@ static struct fb_ops e3d_ops = {
.fb_imageblit = e3d_imageblit,
};
-static int __devinit e3d_set_fbinfo(struct e3d_info *ep)
+static int e3d_set_fbinfo(struct e3d_info *ep)
{
struct fb_info *info = ep->info;
struct fb_var_screeninfo *var = &info->var;
@@ -238,8 +238,8 @@ static int __devinit e3d_set_fbinfo(struct e3d_info *ep)
return 0;
}
-static int __devinit e3d_pci_register(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int e3d_pci_register(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
struct device_node *of_node;
const char *device_type;
@@ -392,7 +392,7 @@ err_out:
return err;
}
-static void __devexit e3d_pci_unregister(struct pci_dev *pdev)
+static void e3d_pci_unregister(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct e3d_info *ep = info->par;
@@ -437,7 +437,7 @@ static struct pci_driver e3d_driver = {
.name = "e3d",
.id_table = e3d_pci_table,
.probe = e3d_pci_register,
- .remove = __devexit_p(e3d_pci_unregister),
+ .remove = e3d_pci_unregister,
};
static int __init e3d_init(void)
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 07c66e9..c000852 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -362,7 +362,7 @@ static void tcx_unmap_regs(struct platform_device *op, struct fb_info *info,
info->screen_base, info->fix.smem_len);
}
-static int __devinit tcx_probe(struct platform_device *op)
+static int tcx_probe(struct platform_device *op)
{
struct device_node *dp = op->dev.of_node;
struct fb_info *info;
@@ -486,7 +486,7 @@ out_err:
return err;
}
-static int __devexit tcx_remove(struct platform_device *op)
+static int tcx_remove(struct platform_device *op)
{
struct fb_info *info = dev_get_drvdata(&op->dev);
struct tcx_par *par = info->par;
@@ -518,7 +518,7 @@ static struct platform_driver tcx_driver = {
.of_match_table = tcx_match,
},
.probe = tcx_probe,
- .remove = __devexit_p(tcx_remove),
+ .remove = tcx_remove,
};
static int __init tcx_init(void)
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index e026724..64bc28b 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -100,7 +100,7 @@ static inline int mtrr_del(int reg, unsigned long base,
#define VOODOO3_MAX_PIXCLOCK 300000
#define VOODOO5_MAX_PIXCLOCK 350000
-static struct fb_fix_screeninfo tdfx_fix __devinitdata = {
+static struct fb_fix_screeninfo tdfx_fix = {
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
.ypanstep = 1,
@@ -108,7 +108,7 @@ static struct fb_fix_screeninfo tdfx_fix __devinitdata = {
.accel = FB_ACCEL_3DFX_BANSHEE
};
-static struct fb_var_screeninfo tdfx_var __devinitdata = {
+static struct fb_var_screeninfo tdfx_var = {
/* "640x480, 8 bpp @ 60 Hz */
.xres = 640,
.yres = 480,
@@ -135,9 +135,8 @@ static struct fb_var_screeninfo tdfx_var __devinitdata = {
/*
* PCI driver prototypes
*/
-static int __devinit tdfxfb_probe(struct pci_dev *pdev,
- const struct pci_device_id *id);
-static void __devexit tdfxfb_remove(struct pci_dev *pdev);
+static int tdfxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id);
+static void tdfxfb_remove(struct pci_dev *pdev);
static struct pci_device_id tdfxfb_id_table[] = {
{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_BANSHEE,
@@ -156,7 +155,7 @@ static struct pci_driver tdfxfb_driver = {
.name = "tdfxfb",
.id_table = tdfxfb_id_table,
.probe = tdfxfb_probe,
- .remove = __devexit_p(tdfxfb_remove),
+ .remove = tdfxfb_remove,
};
MODULE_DEVICE_TABLE(pci, tdfxfb_id_table);
@@ -167,9 +166,9 @@ MODULE_DEVICE_TABLE(pci, tdfxfb_id_table);
static int nopan;
static int nowrap = 1; /* not implemented (yet) */
static int hwcursor = 1;
-static char *mode_option __devinitdata;
+static char *mode_option;
/* mtrr option */
-static bool nomtrr __devinitdata;
+static bool nomtrr;
/* -------------------------------------------------------------------------
* Hardware-specific funcions
@@ -1279,8 +1278,8 @@ static int tdfxfb_ddc_getsda(void *data)
return (0 != (tdfx_inl(par, VIDSERPARPORT) & DDC_SDA_IN));
}
-static int __devinit tdfxfb_setup_ddc_bus(struct tdfxfb_i2c_chan *chan,
- const char *name, struct device *dev)
+static int tdfxfb_setup_ddc_bus(struct tdfxfb_i2c_chan *chan, const char *name,
+ struct device *dev)
{
int rc;
@@ -1308,8 +1307,8 @@ static int __devinit tdfxfb_setup_ddc_bus(struct tdfxfb_i2c_chan *chan,
return rc;
}
-static int __devinit tdfxfb_setup_i2c_bus(struct tdfxfb_i2c_chan *chan,
- const char *name, struct device *dev)
+static int tdfxfb_setup_i2c_bus(struct tdfxfb_i2c_chan *chan, const char *name,
+ struct device *dev)
{
int rc;
@@ -1336,7 +1335,7 @@ static int __devinit tdfxfb_setup_i2c_bus(struct tdfxfb_i2c_chan *chan,
return rc;
}
-static void __devinit tdfxfb_create_i2c_busses(struct fb_info *info)
+static void tdfxfb_create_i2c_busses(struct fb_info *info)
{
struct tdfx_par *par = info->par;
@@ -1388,8 +1387,7 @@ static int tdfxfb_probe_i2c_connector(struct tdfx_par *par,
* Initializes and allocates resources for PCI device @pdev.
*
*/
-static int __devinit tdfxfb_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
+static int tdfxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct tdfx_par *default_par;
struct fb_info *info;
@@ -1626,7 +1624,7 @@ static void __init tdfxfb_setup(char *options)
* lifetime for the PCI device @pdev.
*
*/
-static void __devexit tdfxfb_remove(struct pci_dev *pdev)
+static void tdfxfb_remove(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct tdfx_par *par = info->par;
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index aba7686..c9c8e5a 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -61,8 +61,8 @@ static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *);
static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *);
static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
-static int __devinit tgafb_register(struct device *dev);
-static void __devexit tgafb_unregister(struct device *dev);
+static int tgafb_register(struct device *dev);
+static void tgafb_unregister(struct device *dev);
static const char *mode_option;
static const char *mode_option_pci = "640x480@60";
@@ -93,9 +93,8 @@ static struct fb_ops tgafb_ops = {
/*
* PCI registration operations
*/
-static int __devinit tgafb_pci_register(struct pci_dev *,
- const struct pci_device_id *);
-static void __devexit tgafb_pci_unregister(struct pci_dev *);
+static int tgafb_pci_register(struct pci_dev *, const struct pci_device_id *);
+static void tgafb_pci_unregister(struct pci_dev *);
static struct pci_device_id const tgafb_pci_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA) },
@@ -107,17 +106,16 @@ static struct pci_driver tgafb_pci_driver = {
.name = "tgafb",
.id_table = tgafb_pci_table,
.probe = tgafb_pci_register,
- .remove = __devexit_p(tgafb_pci_unregister),
+ .remove = tgafb_pci_unregister,
};
-static int __devinit
-tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int tgafb_pci_register(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
return tgafb_register(&pdev->dev);
}
-static void __devexit
-tgafb_pci_unregister(struct pci_dev *pdev)
+static void tgafb_pci_unregister(struct pci_dev *pdev)
{
tgafb_unregister(&pdev->dev);
}
@@ -127,8 +125,8 @@ tgafb_pci_unregister(struct pci_dev *pdev)
/*
* TC registration operations
*/
-static int __devinit tgafb_tc_register(struct device *);
-static int __devexit tgafb_tc_unregister(struct device *);
+static int tgafb_tc_register(struct device *);
+static int tgafb_tc_unregister(struct device *);
static struct tc_device_id const tgafb_tc_table[] = {
{ "DEC ", "PMAGD-AA" },
@@ -143,12 +141,11 @@ static struct tc_driver tgafb_tc_driver = {
.name = "tgafb",
.bus = &tc_bus_type,
.probe = tgafb_tc_register,
- .remove = __devexit_p(tgafb_tc_unregister),
+ .remove = tgafb_tc_unregister,
},
};
-static int __devinit
-tgafb_tc_register(struct device *dev)
+static int tgafb_tc_register(struct device *dev)
{
int status = tgafb_register(dev);
if (!status)
@@ -156,8 +153,7 @@ tgafb_tc_register(struct device *dev)
return status;
}
-static int __devexit
-tgafb_tc_unregister(struct device *dev)
+static int tgafb_tc_unregister(struct device *dev)
{
put_device(dev);
tgafb_unregister(dev);
@@ -1546,8 +1542,7 @@ static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info
return 0;
}
-static int __devinit
-tgafb_register(struct device *dev)
+static int tgafb_register(struct device *dev)
{
static const struct fb_videomode modedb_tc = {
/* 1280x1024 @ 72 Hz, 76.8 kHz hsync */
@@ -1692,8 +1687,7 @@ tgafb_register(struct device *dev)
return ret;
}
-static void __devexit
-tgafb_unregister(struct device *dev)
+static void tgafb_unregister(struct device *dev)
{
resource_size_t bar0_start = 0, bar0_len = 0;
int tga_bus_pci = TGA_BUS_PCI(dev);
@@ -1721,16 +1715,14 @@ tgafb_unregister(struct device *dev)
framebuffer_release(info);
}
-static void __devexit
-tgafb_exit(void)
+static void tgafb_exit(void)
{
tc_unregister_driver(&tgafb_tc_driver);
pci_unregister_driver(&tgafb_pci_driver);
}
#ifndef MODULE
-static int __devinit
-tgafb_setup(char *arg)
+static int tgafb_setup(char *arg)
{
char *this_opt;
@@ -1751,8 +1743,7 @@ tgafb_setup(char *arg)
}
#endif /* !MODULE */
-static int __devinit
-tgafb_init(void)
+static int tgafb_init(void)
{
int status;
#ifndef MODULE
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
index b244f06..dc4fb86 100644
--- a/drivers/video/tmiofb.c
+++ b/drivers/video/tmiofb.c
@@ -191,7 +191,7 @@
#define LCR_VCLKHW 0x1b4 /* VCLK High Width */
#define LCR_OC 0x1b6 /* Output Control */
-static char *mode_option __devinitdata;
+static char *mode_option;
struct tmiofb_par {
u32 pseudo_palette[16];
@@ -675,7 +675,7 @@ static struct fb_ops tmiofb_ops = {
/*--------------------------------------------------------------------------*/
-static int __devinit tmiofb_probe(struct platform_device *dev)
+static int tmiofb_probe(struct platform_device *dev)
{
const struct mfd_cell *cell = mfd_get_cell(dev);
struct tmio_fb_data *data = dev->dev.platform_data;
@@ -807,7 +807,7 @@ err_ioremap_ccr:
return retval;
}
-static int __devexit tmiofb_remove(struct platform_device *dev)
+static int tmiofb_remove(struct platform_device *dev)
{
const struct mfd_cell *cell = mfd_get_cell(dev);
struct fb_info *info = platform_get_drvdata(dev);
@@ -1002,7 +1002,7 @@ static struct platform_driver tmiofb_driver = {
.driver.name = "tmio-fb",
.driver.owner = THIS_MODULE,
.probe = tmiofb_probe,
- .remove = __devexit_p(tmiofb_remove),
+ .remove = tmiofb_remove,
.suspend = tmiofb_suspend,
.resume = tmiofb_resume,
};
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 34cf019..ab57d38 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -53,19 +53,19 @@ static struct fb_fix_screeninfo tridentfb_fix = {
/* defaults which are normally overriden by user values */
/* video mode */
-static char *mode_option __devinitdata = "640x480-8@60";
-static int bpp __devinitdata = 8;
+static char *mode_option = "640x480-8@60";
+static int bpp = 8;
-static int noaccel __devinitdata;
+static int noaccel;
static int center;
static int stretch;
-static int fp __devinitdata;
-static int crt __devinitdata;
+static int fp;
+static int crt;
-static int memsize __devinitdata;
-static int memdiff __devinitdata;
+static int memsize;
+static int memdiff;
static int nativex;
module_param(mode_option, charp, 0);
@@ -637,7 +637,7 @@ static inline void crtc_unlock(struct tridentfb_par *par)
}
/* Return flat panel's maximum x resolution */
-static int __devinit get_nativex(struct tridentfb_par *par)
+static int get_nativex(struct tridentfb_par *par)
{
int x, y, tmp;
@@ -771,7 +771,7 @@ static void set_number_of_lines(struct tridentfb_par *par, int lines)
* If we see that FP is active we assume we have one.
* Otherwise we have a CRT display. User can override.
*/
-static int __devinit is_flatpanel(struct tridentfb_par *par)
+static int is_flatpanel(struct tridentfb_par *par)
{
if (fp)
return 1;
@@ -781,7 +781,7 @@ static int __devinit is_flatpanel(struct tridentfb_par *par)
}
/* Try detecting the video memory size */
-static unsigned int __devinit get_memsize(struct tridentfb_par *par)
+static unsigned int get_memsize(struct tridentfb_par *par)
{
unsigned char tmp, tmp2;
unsigned int k;
@@ -1331,8 +1331,8 @@ static struct fb_ops tridentfb_ops = {
.fb_sync = tridentfb_sync,
};
-static int __devinit trident_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
+static int trident_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
{
int err;
unsigned char revision;
@@ -1543,7 +1543,7 @@ out_unmap1:
return err;
}
-static void __devexit trident_pci_remove(struct pci_dev *dev)
+static void trident_pci_remove(struct pci_dev *dev)
{
struct fb_info *info = pci_get_drvdata(dev);
struct tridentfb_par *par = info->par;
@@ -1591,7 +1591,7 @@ static struct pci_driver tridentfb_pci_driver = {
.name = "tridentfb",
.id_table = trident_devices,
.probe = trident_pci_probe,
- .remove = __devexit_p(trident_pci_remove)
+ .remove = trident_pci_remove,
};
/*
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 2f8f82d..b75db01 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -36,26 +36,26 @@ static struct cb_id uvesafb_cn_id = {
static char v86d_path[PATH_MAX] = "/sbin/v86d";
static char v86d_started; /* has v86d been started by uvesafb? */
-static struct fb_fix_screeninfo uvesafb_fix __devinitdata = {
+static struct fb_fix_screeninfo uvesafb_fix = {
.id = "VESA VGA",
.type = FB_TYPE_PACKED_PIXELS,
.accel = FB_ACCEL_NONE,
.visual = FB_VISUAL_TRUECOLOR,
};
-static int mtrr __devinitdata = 3; /* enable mtrr by default */
-static bool blank = 1; /* enable blanking by default */
-static int ypan = 1; /* 0: scroll, 1: ypan, 2: ywrap */
-static bool pmi_setpal __devinitdata = true; /* use PMI for palette changes */
-static bool nocrtc __devinitdata; /* ignore CRTC settings */
-static bool noedid __devinitdata; /* don't try DDC transfers */
-static int vram_remap __devinitdata; /* set amt. of memory to be used */
-static int vram_total __devinitdata; /* set total amount of memory */
-static u16 maxclk __devinitdata; /* maximum pixel clock */
-static u16 maxvf __devinitdata; /* maximum vertical frequency */
-static u16 maxhf __devinitdata; /* maximum horizontal frequency */
-static u16 vbemode __devinitdata; /* force use of a specific VBE mode */
-static char *mode_option __devinitdata;
+static int mtrr = 3; /* enable mtrr by default */
+static bool blank = 1; /* enable blanking by default */
+static int ypan = 1; /* 0: scroll, 1: ypan, 2: ywrap */
+static bool pmi_setpal = true; /* use PMI for palette changes */
+static bool nocrtc; /* ignore CRTC settings */
+static bool noedid; /* don't try DDC transfers */
+static int vram_remap; /* set amt. of memory to be used */
+static int vram_total; /* set total amount of memory */
+static u16 maxclk; /* maximum pixel clock */
+static u16 maxvf; /* maximum vertical frequency */
+static u16 maxhf; /* maximum horizontal frequency */
+static u16 vbemode; /* force use of a specific VBE mode */
+static char *mode_option;
static u8 dac_width = 6;
static struct uvesafb_ktask *uvfb_tasks[UVESAFB_TASKS_MAX];
@@ -418,8 +418,8 @@ static void uvesafb_vbe_state_restore(struct uvesafb_par *par, u8 *state_buf)
uvesafb_free(task);
}
-static int __devinit uvesafb_vbe_getinfo(struct uvesafb_ktask *task,
- struct uvesafb_par *par)
+static int uvesafb_vbe_getinfo(struct uvesafb_ktask *task,
+ struct uvesafb_par *par)
{
int err;
@@ -477,8 +477,8 @@ static int __devinit uvesafb_vbe_getinfo(struct uvesafb_ktask *task,
return 0;
}
-static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
- struct uvesafb_par *par)
+static int uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
+ struct uvesafb_par *par)
{
int off = 0, err;
u16 *mode;
@@ -556,8 +556,8 @@ static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
* x86 and not x86_64.
*/
#ifdef CONFIG_X86_32
-static int __devinit uvesafb_vbe_getpmi(struct uvesafb_ktask *task,
- struct uvesafb_par *par)
+static int uvesafb_vbe_getpmi(struct uvesafb_ktask *task,
+ struct uvesafb_par *par)
{
int i, err;
@@ -602,8 +602,8 @@ static int __devinit uvesafb_vbe_getpmi(struct uvesafb_ktask *task,
* Check whether a video mode is supported by the Video BIOS and is
* compatible with the monitor limits.
*/
-static int __devinit uvesafb_is_valid_mode(struct fb_videomode *mode,
- struct fb_info *info)
+static int uvesafb_is_valid_mode(struct fb_videomode *mode,
+ struct fb_info *info)
{
if (info->monspecs.gtf) {
fb_videomode_to_var(&info->var, mode);
@@ -618,8 +618,7 @@ static int __devinit uvesafb_is_valid_mode(struct fb_videomode *mode,
return 1;
}
-static int __devinit uvesafb_vbe_getedid(struct uvesafb_ktask *task,
- struct fb_info *info)
+static int uvesafb_vbe_getedid(struct uvesafb_ktask *task, struct fb_info *info)
{
struct uvesafb_par *par = info->par;
int err = 0;
@@ -684,8 +683,8 @@ static int __devinit uvesafb_vbe_getedid(struct uvesafb_ktask *task,
return err;
}
-static void __devinit uvesafb_vbe_getmonspecs(struct uvesafb_ktask *task,
- struct fb_info *info)
+static void uvesafb_vbe_getmonspecs(struct uvesafb_ktask *task,
+ struct fb_info *info)
{
struct uvesafb_par *par = info->par;
int i;
@@ -765,8 +764,8 @@ static void __devinit uvesafb_vbe_getmonspecs(struct uvesafb_ktask *task,
return;
}
-static void __devinit uvesafb_vbe_getstatesize(struct uvesafb_ktask *task,
- struct uvesafb_par *par)
+static void uvesafb_vbe_getstatesize(struct uvesafb_ktask *task,
+ struct uvesafb_par *par)
{
int err;
@@ -794,7 +793,7 @@ static void __devinit uvesafb_vbe_getstatesize(struct uvesafb_ktask *task,
par->vbe_state_size = 64 * (task->t.regs.ebx & 0xffff);
}
-static int __devinit uvesafb_vbe_init(struct fb_info *info)
+static int uvesafb_vbe_init(struct fb_info *info)
{
struct uvesafb_ktask *task = NULL;
struct uvesafb_par *par = info->par;
@@ -839,7 +838,7 @@ out: uvesafb_free(task);
return err;
}
-static int __devinit uvesafb_vbe_init_mode(struct fb_info *info)
+static int uvesafb_vbe_init_mode(struct fb_info *info)
{
struct list_head *pos;
struct fb_modelist *modelist;
@@ -1444,8 +1443,7 @@ static struct fb_ops uvesafb_ops = {
.fb_set_par = uvesafb_set_par,
};
-static void __devinit uvesafb_init_info(struct fb_info *info,
- struct vbe_mode_ib *mode)
+static void uvesafb_init_info(struct fb_info *info, struct vbe_mode_ib *mode)
{
unsigned int size_vmode;
unsigned int size_remap;
@@ -1540,7 +1538,7 @@ static void __devinit uvesafb_init_info(struct fb_info *info,
info->fbops->fb_pan_display = NULL;
}
-static void __devinit uvesafb_init_mtrr(struct fb_info *info)
+static void uvesafb_init_mtrr(struct fb_info *info)
{
#ifdef CONFIG_MTRR
if (mtrr && !(info->fix.smem_start & (PAGE_SIZE - 1))) {
@@ -1582,7 +1580,7 @@ static void __devinit uvesafb_init_mtrr(struct fb_info *info)
#endif /* CONFIG_MTRR */
}
-static void __devinit uvesafb_ioremap(struct fb_info *info)
+static void uvesafb_ioremap(struct fb_info *info)
{
#ifdef CONFIG_X86
switch (mtrr) {
@@ -1738,7 +1736,7 @@ static struct attribute_group uvesafb_dev_attgrp = {
.attrs = uvesafb_dev_attrs,
};
-static int __devinit uvesafb_probe(struct platform_device *dev)
+static int uvesafb_probe(struct platform_device *dev)
{
struct fb_info *info;
struct vbe_mode_ib *mode = NULL;
@@ -1882,7 +1880,7 @@ static struct platform_driver uvesafb_driver = {
static struct platform_device *uvesafb_device;
#ifndef MODULE
-static int __devinit uvesafb_setup(char *options)
+static int uvesafb_setup(char *options)
{
char *this_opt;
@@ -1950,7 +1948,7 @@ static ssize_t store_v86d(struct device_driver *dev, const char *buf,
static DRIVER_ATTR(v86d, S_IRUGO | S_IWUSR, show_v86d, store_v86d);
-static int __devinit uvesafb_init(void)
+static int uvesafb_init(void)
{
int err;
@@ -1994,7 +1992,7 @@ static int __devinit uvesafb_init(void)
module_init(uvesafb_init);
-static void __devexit uvesafb_exit(void)
+static void uvesafb_exit(void)
{
struct uvesafb_ktask *task;
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index 4709edc..0aa516f 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -393,7 +393,7 @@ static void vmlfb_release_devices(struct vml_par *par)
* Free up allocated resources for a device.
*/
-static void __devexit vml_pci_remove(struct pci_dev *dev)
+static void vml_pci_remove(struct pci_dev *dev)
{
struct fb_info *info;
struct vml_info *vinfo;
@@ -452,8 +452,7 @@ static void vmlfb_set_pref_pixel_format(struct fb_var_screeninfo *var)
* struct per pipe. Currently we have only one pipe.
*/
-static int __devinit vml_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
+static int vml_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct vml_info *vinfo;
struct fb_info *info;
@@ -1060,7 +1059,7 @@ static struct pci_driver vmlfb_pci_driver = {
.name = "vmlfb",
.id_table = vml_ids,
.probe = vml_pci_probe,
- .remove = __devexit_p(vml_pci_remove)
+ .remove = vml_pci_remove,
};
static void __exit vmlfb_cleanup(void)
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index c7f69252..8bc1f93 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -78,7 +78,7 @@ static void rvfree(void *mem, unsigned long size)
vfree(mem);
}
-static struct fb_var_screeninfo vfb_default __devinitdata = {
+static struct fb_var_screeninfo vfb_default = {
.xres = 640,
.yres = 480,
.xres_virtual = 640,
@@ -100,7 +100,7 @@ static struct fb_var_screeninfo vfb_default __devinitdata = {
.vmode = FB_VMODE_NONINTERLACED,
};
-static struct fb_fix_screeninfo vfb_fix __devinitdata = {
+static struct fb_fix_screeninfo vfb_fix = {
.id = "Virtual FB",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
@@ -477,7 +477,7 @@ static int __init vfb_setup(char *options)
* Initialisation
*/
-static int __devinit vfb_probe(struct platform_device *dev)
+static int vfb_probe(struct platform_device *dev)
{
struct fb_info *info;
int retval = -ENOMEM;
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 0267acd..545faec 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -65,7 +65,7 @@ struct vga16fb_par {
/* --------------------------------------------------------------------- */
-static struct fb_var_screeninfo vga16fb_defined __devinitdata = {
+static struct fb_var_screeninfo vga16fb_defined = {
.xres = 640,
.yres = 480,
.xres_virtual = 640,
@@ -85,7 +85,7 @@ static struct fb_var_screeninfo vga16fb_defined __devinitdata = {
};
/* name should not depend on EGA/VGA */
-static struct fb_fix_screeninfo vga16fb_fix __devinitdata = {
+static struct fb_fix_screeninfo vga16fb_fix = {
.id = "VGA16 VGA",
.smem_start = VGA_FB_PHYS,
.smem_len = VGA_FB_PHYS_LEN,
@@ -1303,7 +1303,7 @@ static int __init vga16fb_setup(char *options)
}
#endif
-static int __devinit vga16fb_probe(struct platform_device *dev)
+static int vga16fb_probe(struct platform_device *dev)
{
struct fb_info *info;
struct vga16fb_par *par;
@@ -1395,7 +1395,7 @@ static int __devinit vga16fb_probe(struct platform_device *dev)
return ret;
}
-static int __devexit vga16fb_remove(struct platform_device *dev)
+static int vga16fb_remove(struct platform_device *dev)
{
struct fb_info *info = platform_get_drvdata(dev);
@@ -1407,7 +1407,7 @@ static int __devexit vga16fb_remove(struct platform_device *dev)
static struct platform_driver vga16fb_driver = {
.probe = vga16fb_probe,
- .remove = __devexit_p(vga16fb_remove),
+ .remove = vga16fb_remove,
.driver = {
.name = "vga16fb",
},
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
index 6be72f0..7789553 100644
--- a/drivers/video/via/dvi.c
+++ b/drivers/video/via/dvi.c
@@ -25,7 +25,7 @@
static void tmds_register_write(int index, u8 data);
static int tmds_register_read(int index);
static int tmds_register_read_bytes(int index, u8 *buff, int buff_len);
-static void __devinit dvi_get_panel_size_from_DDCv1(
+static void dvi_get_panel_size_from_DDCv1(
struct tmds_chip_information *tmds_chip,
struct tmds_setting_information *tmds_setting);
static int viafb_dvi_query_EDID(void);
@@ -35,8 +35,8 @@ static inline bool check_tmds_chip(int device_id_subaddr, int device_id)
return tmds_register_read(device_id_subaddr) == device_id;
}
-void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
- struct tmds_setting_information *tmds_setting)
+void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
+ struct tmds_setting_information *tmds_setting)
{
DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
@@ -47,7 +47,7 @@ void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
return;
}
-bool __devinit viafb_tmds_trasmitter_identify(void)
+bool viafb_tmds_trasmitter_identify(void)
{
unsigned char sr2a = 0, sr1e = 0, sr3e = 0;
@@ -285,7 +285,7 @@ static int viafb_dvi_query_EDID(void)
}
/* Get Panel Size Using EDID1 Table */
-static void __devinit dvi_get_panel_size_from_DDCv1(
+static void dvi_get_panel_size_from_DDCv1(
struct tmds_chip_information *tmds_chip,
struct tmds_setting_information *tmds_setting)
{
diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h
index db75785..4c6bfba 100644
--- a/drivers/video/via/dvi.h
+++ b/drivers/video/via/dvi.h
@@ -56,8 +56,8 @@
int viafb_dvi_sense(void);
void viafb_dvi_disable(void);
void viafb_dvi_enable(void);
-bool __devinit viafb_tmds_trasmitter_identify(void);
-void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
+bool viafb_tmds_trasmitter_identify(void);
+void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
struct tmds_setting_information *tmds_setting);
void viafb_dvi_set_mode(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres, int iga);
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index 898590d..22450908 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -465,9 +465,9 @@ static struct via_device_mapping device_mapping[] = {
static struct via_clock clock;
static void load_fix_bit_crtc_reg(void);
-static void __devinit init_gfx_chip_info(int chip_type);
-static void __devinit init_tmds_chip_info(void);
-static void __devinit init_lvds_chip_info(void);
+static void init_gfx_chip_info(int chip_type);
+static void init_tmds_chip_info(void);
+static void init_lvds_chip_info(void);
static void device_screen_off(void);
static void device_screen_on(void);
static void set_display_channel(void);
@@ -1467,10 +1467,10 @@ void viafb_set_vclock(u32 clk, int set_iga)
via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */
}
-struct display_timing var_to_timing(const struct fb_var_screeninfo *var,
+struct via_display_timing var_to_timing(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres)
{
- struct display_timing timing;
+ struct via_display_timing timing;
u16 dx = (var->xres - cxres) / 2, dy = (var->yres - cyres) / 2;
timing.hor_addr = cxres;
@@ -1491,7 +1491,7 @@ struct display_timing var_to_timing(const struct fb_var_screeninfo *var,
void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres, int iga)
{
- struct display_timing crt_reg = var_to_timing(var,
+ struct via_display_timing crt_reg = var_to_timing(var,
cxres ? cxres : var->xres, cyres ? cyres : var->yres);
if (iga == IGA1)
@@ -1507,7 +1507,7 @@ void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var,
viafb_set_vclock(PICOS2KHZ(var->pixclock) * 1000, iga);
}
-void __devinit viafb_init_chip_info(int chip_type)
+void viafb_init_chip_info(int chip_type)
{
via_clock_init(&clock, chip_type);
init_gfx_chip_info(chip_type);
@@ -1540,7 +1540,7 @@ void viafb_update_device_setting(int hres, int vres, int bpp, int flag)
}
}
-static void __devinit init_gfx_chip_info(int chip_type)
+static void init_gfx_chip_info(int chip_type)
{
u8 tmp;
@@ -1593,7 +1593,7 @@ static void __devinit init_gfx_chip_info(int chip_type)
}
}
-static void __devinit init_tmds_chip_info(void)
+static void init_tmds_chip_info(void)
{
viafb_tmds_trasmitter_identify();
@@ -1638,7 +1638,7 @@ static void __devinit init_tmds_chip_info(void)
&viaparinfo->shared->tmds_setting_info);
}
-static void __devinit init_lvds_chip_info(void)
+static void init_lvds_chip_info(void)
{
viafb_lvds_trasmitter_identify();
viafb_init_lcd_size();
@@ -1672,7 +1672,7 @@ static void __devinit init_lvds_chip_info(void)
viaparinfo->chip_info->lvds_chip_info.output_interface);
}
-void __devinit viafb_init_dac(int set_iga)
+void viafb_init_dac(int set_iga)
{
int i;
u8 tmp;
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index 6be243c..3be073c 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -637,7 +637,7 @@ extern int viafb_LCD_ON;
extern int viafb_DVI_ON;
extern int viafb_hotplug;
-struct display_timing var_to_timing(const struct fb_var_screeninfo *var,
+struct via_display_timing var_to_timing(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres);
void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres, int iga);
@@ -663,8 +663,8 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
int viafb_setmode(void);
void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
const struct fb_videomode *mode);
-void __devinit viafb_init_chip_info(int chip_type);
-void __devinit viafb_init_dac(int set_iga);
+void viafb_init_chip_info(int chip_type);
+void viafb_init_dac(int set_iga);
int viafb_get_refresh(int hres, int vres, u32 float_refresh);
void viafb_update_device_setting(int hres, int vres, int bpp, int flag);
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index 1650379..5d21ff4 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -49,7 +49,7 @@ static struct _lcd_scaling_factor lcd_scaling_factor_CLE = {
};
static bool lvds_identify_integratedlvds(void);
-static void __devinit fp_id_to_vindex(int panel_id);
+static void fp_id_to_vindex(int panel_id);
static int lvds_register_read(int index);
static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
int panel_vres);
@@ -81,7 +81,7 @@ static inline bool check_lvds_chip(int device_id_subaddr, int device_id)
return lvds_register_read(device_id_subaddr) == device_id;
}
-void __devinit viafb_init_lcd_size(void)
+void viafb_init_lcd_size(void)
{
DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n");
@@ -139,7 +139,7 @@ static bool lvds_identify_integratedlvds(void)
return true;
}
-bool __devinit viafb_lvds_trasmitter_identify(void)
+bool viafb_lvds_trasmitter_identify(void)
{
if (viafb_lvds_identify_vt1636(VIA_PORT_31)) {
viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31;
@@ -180,7 +180,7 @@ bool __devinit viafb_lvds_trasmitter_identify(void)
return false;
}
-static void __devinit fp_id_to_vindex(int panel_id)
+static void fp_id_to_vindex(int panel_id)
{
DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n");
@@ -549,7 +549,7 @@ void viafb_lcd_set_mode(const struct fb_var_screeninfo *var, u16 cxres,
int panel_hres = plvds_setting_info->lcd_panel_hres;
int panel_vres = plvds_setting_info->lcd_panel_vres;
u32 clock;
- struct display_timing timing;
+ struct via_display_timing timing;
struct fb_var_screeninfo panel_var;
const struct fb_videomode *mode_crt_table, *panel_crt_table;
@@ -914,7 +914,7 @@ static void check_diport_of_integrated_lvds(
plvds_chip_info->output_interface);
}
-void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information
+void viafb_init_lvds_output_interface(struct lvds_chip_information
*plvds_chip_info,
struct lvds_setting_information
*plvds_setting_info)
diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h
index 8f3e4e0..5c988a0 100644
--- a/drivers/video/via/lcd.h
+++ b/drivers/video/via/lcd.h
@@ -71,15 +71,15 @@ void viafb_enable_lvds_vt1636(struct lvds_setting_information
struct lvds_chip_information *plvds_chip_info);
void viafb_lcd_disable(void);
void viafb_lcd_enable(void);
-void __devinit viafb_init_lcd_size(void);
-void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information
+void viafb_init_lcd_size(void);
+void viafb_init_lvds_output_interface(struct lvds_chip_information
*plvds_chip_info,
struct lvds_setting_information
*plvds_setting_info);
void viafb_lcd_set_mode(const struct fb_var_screeninfo *var, u16 cxres,
u16 cyres, struct lvds_setting_information *plvds_setting_info,
struct lvds_chip_information *plvds_chip_info);
-bool __devinit viafb_lvds_trasmitter_identify(void);
+bool viafb_lvds_trasmitter_identify(void);
void viafb_init_lvds_output_interface(struct lvds_chip_information
*plvds_chip_info,
struct lvds_setting_information
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h
index 3158dfc..65c65c6 100644
--- a/drivers/video/via/share.h
+++ b/drivers/video/via/share.h
@@ -319,7 +319,7 @@ struct crt_mode_table {
int refresh_rate;
int h_sync_polarity;
int v_sync_polarity;
- struct display_timing crtc;
+ struct via_display_timing crtc;
};
struct io_reg {
diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c
index dd58b53..6e27482 100644
--- a/drivers/video/via/via-core.c
+++ b/drivers/video/via/via-core.c
@@ -80,7 +80,7 @@ static inline int viafb_mmio_read(int reg)
*/
static u32 viafb_enabled_ints;
-static void __devinit viafb_int_init(void)
+static void viafb_int_init(void)
{
viafb_enabled_ints = 0;
@@ -475,7 +475,7 @@ static int viafb_get_fb_size_from_pci(int chip_type)
/*
* Figure out and map our MMIO regions.
*/
-static int __devinit via_pci_setup_mmio(struct viafb_dev *vdev)
+static int via_pci_setup_mmio(struct viafb_dev *vdev)
{
int ret;
/*
@@ -550,8 +550,8 @@ static struct viafb_subdev_info {
};
#define N_SUBDEVS ARRAY_SIZE(viafb_subdevs)
-static int __devinit via_create_subdev(struct viafb_dev *vdev,
- struct viafb_subdev_info *info)
+static int via_create_subdev(struct viafb_dev *vdev,
+ struct viafb_subdev_info *info)
{
int ret;
@@ -573,7 +573,7 @@ static int __devinit via_create_subdev(struct viafb_dev *vdev,
return ret;
}
-static int __devinit via_setup_subdevs(struct viafb_dev *vdev)
+static int via_setup_subdevs(struct viafb_dev *vdev)
{
int i;
@@ -671,8 +671,7 @@ static int via_resume(struct pci_dev *pdev)
}
#endif /* CONFIG_PM */
-static int __devinit via_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int via_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int ret;
@@ -716,7 +715,7 @@ out_disable:
return ret;
}
-static void __devexit via_pci_remove(struct pci_dev *pdev)
+static void via_pci_remove(struct pci_dev *pdev)
{
via_teardown_subdevs();
via_fb_pci_remove(pdev);
@@ -725,7 +724,7 @@ static void __devexit via_pci_remove(struct pci_dev *pdev)
}
-static struct pci_device_id via_pci_table[] __devinitdata = {
+static struct pci_device_id via_pci_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CLE266_DID),
.driver_data = UNICHROME_CLE266 },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K400_DID),
@@ -760,7 +759,7 @@ static struct pci_driver via_driver = {
.name = "viafb",
.id_table = via_pci_table,
.probe = via_pci_probe,
- .remove = __devexit_p(via_pci_remove),
+ .remove = via_pci_remove,
#ifdef CONFIG_PM
.suspend = via_suspend,
.resume = via_resume,
diff --git a/drivers/video/via/via-gpio.c b/drivers/video/via/via-gpio.c
index d69cfef..e408679 100644
--- a/drivers/video/via/via-gpio.c
+++ b/drivers/video/via/via-gpio.c
@@ -212,7 +212,7 @@ EXPORT_SYMBOL_GPL(viafb_gpio_lookup);
/*
* Platform device stuff.
*/
-static __devinit int viafb_gpio_probe(struct platform_device *platdev)
+static int viafb_gpio_probe(struct platform_device *platdev)
{
struct viafb_dev *vdev = platdev->dev.platform_data;
struct via_port_cfg *port_cfg = vdev->port_cfg;
diff --git a/drivers/video/via/via_modesetting.c b/drivers/video/via/via_modesetting.c
index 0e431ae..0b414b0 100644
--- a/drivers/video/via/via_modesetting.c
+++ b/drivers/video/via/via_modesetting.c
@@ -30,9 +30,9 @@
#include "debug.h"
-void via_set_primary_timing(const struct display_timing *timing)
+void via_set_primary_timing(const struct via_display_timing *timing)
{
- struct display_timing raw;
+ struct via_display_timing raw;
raw.hor_total = timing->hor_total / 8 - 5;
raw.hor_addr = timing->hor_addr / 8 - 1;
@@ -88,9 +88,9 @@ void via_set_primary_timing(const struct display_timing *timing)
via_write_reg_mask(VIACR, 0x17, 0x80, 0x80);
}
-void via_set_secondary_timing(const struct display_timing *timing)
+void via_set_secondary_timing(const struct via_display_timing *timing)
{
- struct display_timing raw;
+ struct via_display_timing raw;
raw.hor_total = timing->hor_total - 1;
raw.hor_addr = timing->hor_addr - 1;
diff --git a/drivers/video/via/via_modesetting.h b/drivers/video/via/via_modesetting.h
index 06e09fe..f6a6503 100644
--- a/drivers/video/via/via_modesetting.h
+++ b/drivers/video/via/via_modesetting.h
@@ -33,7 +33,7 @@
#define VIA_PITCH_MAX 0x3FF8
-struct display_timing {
+struct via_display_timing {
u16 hor_total;
u16 hor_addr;
u16 hor_blank_start;
@@ -49,8 +49,8 @@ struct display_timing {
};
-void via_set_primary_timing(const struct display_timing *timing);
-void via_set_secondary_timing(const struct display_timing *timing);
+void via_set_primary_timing(const struct via_display_timing *timing);
+void via_set_secondary_timing(const struct via_display_timing *timing);
void via_set_primary_address(u32 addr);
void via_set_secondary_address(u32 addr);
void via_set_primary_pitch(u32 pitch);
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index c80e770..325c43c 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -1072,7 +1072,7 @@ static int __init parse_active_dev(void)
return 0;
}
-static int __devinit parse_port(char *opt_str, int *output_interface)
+static int parse_port(char *opt_str, int *output_interface)
{
if (!strncmp(opt_str, "DVP0", 4))
*output_interface = INTERFACE_DVP0;
@@ -1089,7 +1089,7 @@ static int __devinit parse_port(char *opt_str, int *output_interface)
return 0;
}
-static void __devinit parse_lcd_port(void)
+static void parse_lcd_port(void)
{
parse_port(viafb_lcd_port, &viaparinfo->chip_info->lvds_chip_info.
output_interface);
@@ -1102,7 +1102,7 @@ static void __devinit parse_lcd_port(void)
output_interface);
}
-static void __devinit parse_dvi_port(void)
+static void parse_dvi_port(void)
{
parse_port(viafb_dvi_port, &viaparinfo->chip_info->tmds_chip_info.
output_interface);
@@ -1727,7 +1727,7 @@ static struct viafb_pm_hooks viafb_fb_pm_hooks = {
#endif
-static void __devinit i2c_bus_probe(struct viafb_shared *shared)
+static void i2c_bus_probe(struct viafb_shared *shared)
{
/* should be always CRT */
printk(KERN_INFO "viafb: Probing I2C bus 0x26\n");
@@ -1753,7 +1753,7 @@ static void i2c_bus_free(struct viafb_shared *shared)
via_aux_free(shared->i2c_2C);
}
-int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
+int via_fb_pci_probe(struct viafb_dev *vdev)
{
u32 default_xres, default_yres;
struct fb_var_screeninfo default_var;
@@ -1945,7 +1945,7 @@ out_fb_release:
return rc;
}
-void __devexit via_fb_pci_remove(struct pci_dev *pdev)
+void via_fb_pci_remove(struct pci_dev *pdev)
{
DEBUG_MSG(KERN_INFO "via_pci_remove!\n");
fb_dealloc_cmap(&viafbinfo->cmap);
diff --git a/drivers/video/videomode.c b/drivers/video/videomode.c
new file mode 100644
index 0000000..21c47a2
--- /dev/null
+++ b/drivers/video/videomode.c
@@ -0,0 +1,39 @@
+/*
+ * generic display timing functions
+ *
+ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * This file is released under the GPLv2
+ */
+
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <video/display_timing.h>
+#include <video/videomode.h>
+
+int videomode_from_timing(const struct display_timings *disp,
+ struct videomode *vm, unsigned int index)
+{
+ struct display_timing *dt;
+
+ dt = display_timings_get(disp, index);
+ if (!dt)
+ return -EINVAL;
+
+ vm->pixelclock = display_timing_get_value(&dt->pixelclock, TE_TYP);
+ vm->hactive = display_timing_get_value(&dt->hactive, TE_TYP);
+ vm->hfront_porch = display_timing_get_value(&dt->hfront_porch, TE_TYP);
+ vm->hback_porch = display_timing_get_value(&dt->hback_porch, TE_TYP);
+ vm->hsync_len = display_timing_get_value(&dt->hsync_len, TE_TYP);
+
+ vm->vactive = display_timing_get_value(&dt->vactive, TE_TYP);
+ vm->vfront_porch = display_timing_get_value(&dt->vfront_porch, TE_TYP);
+ vm->vback_porch = display_timing_get_value(&dt->vback_porch, TE_TYP);
+ vm->vsync_len = display_timing_get_value(&dt->vsync_len, TE_TYP);
+
+ vm->dmt_flags = dt->dmt_flags;
+ vm->data_flags = dt->data_flags;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(videomode_from_timing);
diff --git a/drivers/video/vt8500lcdfb.c b/drivers/video/vt8500lcdfb.c
index 9af8da7..aa2579c 100644
--- a/drivers/video/vt8500lcdfb.c
+++ b/drivers/video/vt8500lcdfb.c
@@ -273,7 +273,7 @@ static irqreturn_t vt8500lcd_handle_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int __devinit vt8500lcd_probe(struct platform_device *pdev)
+static int vt8500lcd_probe(struct platform_device *pdev)
{
struct vt8500lcd_info *fbi;
struct resource *res;
@@ -469,7 +469,7 @@ failed:
return ret;
}
-static int __devexit vt8500lcd_remove(struct platform_device *pdev)
+static int vt8500lcd_remove(struct platform_device *pdev)
{
struct vt8500lcd_info *fbi = platform_get_drvdata(pdev);
struct resource *res;
@@ -505,7 +505,7 @@ static const struct of_device_id via_dt_ids[] = {
static struct platform_driver vt8500lcd_driver = {
.probe = vt8500lcd_probe,
- .remove = __devexit_p(vt8500lcd_remove),
+ .remove = vt8500lcd_remove,
.driver = {
.owner = THIS_MODULE,
.name = "vt8500-lcd",
diff --git a/drivers/video/vt8623fb.c b/drivers/video/vt8623fb.c
index 4e74d26..e9557fa 100644
--- a/drivers/video/vt8623fb.c
+++ b/drivers/video/vt8623fb.c
@@ -660,7 +660,7 @@ static struct fb_ops vt8623fb_ops = {
/* PCI probe */
-static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+static int vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct pci_bus_region bus_reg;
struct resource vga_res;
@@ -807,7 +807,7 @@ err_enable_device:
/* PCI remove */
-static void __devexit vt8623_pci_remove(struct pci_dev *dev)
+static void vt8623_pci_remove(struct pci_dev *dev)
{
struct fb_info *info = pci_get_drvdata(dev);
@@ -906,7 +906,7 @@ fail:
/* List of boards that we are trying to support */
-static struct pci_device_id vt8623_devices[] __devinitdata = {
+static struct pci_device_id vt8623_devices[] = {
{PCI_DEVICE(PCI_VENDOR_ID_VIA, 0x3122)},
{0, 0, 0, 0, 0, 0, 0}
};
@@ -917,7 +917,7 @@ static struct pci_driver vt8623fb_pci_driver = {
.name = "vt8623fb",
.id_table = vt8623_devices,
.probe = vt8623_pci_probe,
- .remove = __devexit_p(vt8623_pci_remove),
+ .remove = vt8623_pci_remove,
.suspend = vt8623_pci_suspend,
.resume = vt8623_pci_resume,
};
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index 2f6b2b8..7a299e95 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -54,7 +54,7 @@ static void w100_update_enable(void);
static void w100_update_disable(void);
static void calc_hsync(struct w100fb_par *par);
static void w100_init_graphic_engine(struct w100fb_par *par);
-struct w100_pll_info *w100_get_xtal_table(unsigned int freq) __devinit;
+struct w100_pll_info *w100_get_xtal_table(unsigned int freq);
/* Pseudo palette size */
#define MAX_PALETTES 16
@@ -630,7 +630,7 @@ static int w100fb_resume(struct platform_device *dev)
#endif
-int __devinit w100fb_probe(struct platform_device *pdev)
+int w100fb_probe(struct platform_device *pdev)
{
int err = -EIO;
struct w100fb_mach_info *inf;
@@ -783,7 +783,7 @@ out:
}
-static int __devexit w100fb_remove(struct platform_device *pdev)
+static int w100fb_remove(struct platform_device *pdev)
{
struct fb_info *info = platform_get_drvdata(pdev);
struct w100fb_par *par=info->par;
@@ -1021,7 +1021,7 @@ static struct pll_entries {
{ 0 },
};
-struct w100_pll_info __devinit *w100_get_xtal_table(unsigned int freq)
+struct w100_pll_info *w100_get_xtal_table(unsigned int freq)
{
struct pll_entries *pll_entry = w100_pll_tables;
@@ -1624,7 +1624,7 @@ static void w100_vsync(void)
static struct platform_driver w100fb_driver = {
.probe = w100fb_probe,
- .remove = __devexit_p(w100fb_remove),
+ .remove = w100fb_remove,
.suspend = w100fb_suspend,
.resume = w100fb_resume,
.driver = {
diff --git a/drivers/video/wm8505fb.c b/drivers/video/wm8505fb.c
index 77539c1..4dd0580 100644
--- a/drivers/video/wm8505fb.c
+++ b/drivers/video/wm8505fb.c
@@ -260,7 +260,7 @@ static struct fb_ops wm8505fb_ops = {
.fb_blank = wm8505fb_blank,
};
-static int __devinit wm8505fb_probe(struct platform_device *pdev)
+static int wm8505fb_probe(struct platform_device *pdev)
{
struct wm8505fb_info *fbi;
struct resource *res;
@@ -431,7 +431,7 @@ failed:
return ret;
}
-static int __devexit wm8505fb_remove(struct platform_device *pdev)
+static int wm8505fb_remove(struct platform_device *pdev)
{
struct wm8505fb_info *fbi = platform_get_drvdata(pdev);
struct resource *res;
@@ -462,7 +462,7 @@ static const struct of_device_id wmt_dt_ids[] = {
static struct platform_driver wm8505fb_driver = {
.probe = wm8505fb_probe,
- .remove = __devexit_p(wm8505fb_remove),
+ .remove = wm8505fb_remove,
.driver = {
.owner = THIS_MODULE,
.name = DRIVER_NAME,
diff --git a/drivers/video/wmt_ge_rops.c b/drivers/video/wmt_ge_rops.c
index ba025b4..4aaeb18 100644
--- a/drivers/video/wmt_ge_rops.c
+++ b/drivers/video/wmt_ge_rops.c
@@ -124,7 +124,7 @@ int wmt_ge_sync(struct fb_info *p)
}
EXPORT_SYMBOL_GPL(wmt_ge_sync);
-static int __devinit wmt_ge_rops_probe(struct platform_device *pdev)
+static int wmt_ge_rops_probe(struct platform_device *pdev)
{
struct resource *res;
@@ -152,7 +152,7 @@ static int __devinit wmt_ge_rops_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit wmt_ge_rops_remove(struct platform_device *pdev)
+static int wmt_ge_rops_remove(struct platform_device *pdev)
{
iounmap(regbase);
return 0;
@@ -165,7 +165,7 @@ static const struct of_device_id wmt_dt_ids[] = {
static struct platform_driver wmt_ge_rops_driver = {
.probe = wmt_ge_rops_probe,
- .remove = __devexit_p(wmt_ge_rops_remove),
+ .remove = wmt_ge_rops_remove,
.driver = {
.owner = THIS_MODULE,
.name = "wmt_ge_rops",
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c
index 917bb56..cd005c2 100644
--- a/drivers/video/xen-fbfront.c
+++ b/drivers/video/xen-fbfront.c
@@ -358,8 +358,8 @@ static irqreturn_t xenfb_event_handler(int rq, void *dev_id)
return IRQ_HANDLED;
}
-static int __devinit xenfb_probe(struct xenbus_device *dev,
- const struct xenbus_device_id *id)
+static int xenfb_probe(struct xenbus_device *dev,
+ const struct xenbus_device_id *id)
{
struct xenfb_info *info;
struct fb_info *fb_info;
@@ -487,8 +487,7 @@ error:
return ret;
}
-static __devinit void
-xenfb_make_preferred_console(void)
+static void xenfb_make_preferred_console(void)
{
struct console *c;
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
index 1808452..af0b4fd 100644
--- a/drivers/video/xilinxfb.c
+++ b/drivers/video/xilinxfb.c
@@ -403,7 +403,7 @@ static int xilinxfb_release(struct device *dev)
* OF bus binding
*/
-static int __devinit xilinxfb_of_probe(struct platform_device *op)
+static int xilinxfb_of_probe(struct platform_device *op)
{
const u32 *prop;
u32 *p;
@@ -485,13 +485,13 @@ static int __devinit xilinxfb_of_probe(struct platform_device *op)
return -ENODEV;
}
-static int __devexit xilinxfb_of_remove(struct platform_device *op)
+static int xilinxfb_of_remove(struct platform_device *op)
{
return xilinxfb_release(&op->dev);
}
/* Match table for of_platform binding */
-static struct of_device_id xilinxfb_of_match[] __devinitdata = {
+static struct of_device_id xilinxfb_of_match[] = {
{ .compatible = "xlnx,xps-tft-1.00.a", },
{ .compatible = "xlnx,xps-tft-2.00.a", },
{ .compatible = "xlnx,xps-tft-2.01.a", },
@@ -503,7 +503,7 @@ MODULE_DEVICE_TABLE(of, xilinxfb_of_match);
static struct platform_driver xilinxfb_of_driver = {
.probe = xilinxfb_of_probe,
- .remove = __devexit_p(xilinxfb_of_remove),
+ .remove = xilinxfb_of_remove,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,