summaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/68328fb.c2
-rw-r--r--drivers/video/Kconfig18
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/aty/aty128fb.c2
-rw-r--r--drivers/video/aty/atyfb_base.c3
-rw-r--r--drivers/video/auo_k190x.c2
-rw-r--r--drivers/video/backlight/88pm860x_bl.c147
-rw-r--r--drivers/video/backlight/Kconfig30
-rw-r--r--drivers/video/backlight/Makefile4
-rw-r--r--drivers/video/backlight/da9052_bl.c4
-rw-r--r--drivers/video/backlight/kb3886_bl.c4
-rw-r--r--drivers/video/backlight/lm3630_bl.c475
-rw-r--r--drivers/video/backlight/lm3639_bl.c437
-rw-r--r--drivers/video/backlight/ltv350qv.c6
-rw-r--r--drivers/video/backlight/max8925_bl.c79
-rw-r--r--drivers/video/backlight/omap1_bl.c4
-rw-r--r--drivers/video/backlight/platform_lcd.c10
-rw-r--r--drivers/video/backlight/progear_bl.c162
-rw-r--r--drivers/video/backlight/tps65217_bl.c342
-rw-r--r--drivers/video/console/bitblit.c2
-rw-r--r--drivers/video/console/fbcon.c11
-rw-r--r--drivers/video/da8xx-fb.c8
-rw-r--r--drivers/video/efifb.c4
-rw-r--r--drivers/video/ep93xx-fb.c2
-rw-r--r--drivers/video/epson1355fb.c749
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi.c2
-rw-r--r--drivers/video/fb-puv3.c3
-rw-r--r--drivers/video/fb_defio.c2
-rw-r--r--drivers/video/fbmem.c3
-rw-r--r--drivers/video/gbefb.c2
-rw-r--r--drivers/video/geode/gx1fb_core.c2
-rw-r--r--drivers/video/gxt4500.c4
-rw-r--r--drivers/video/i810/i810_main.c2
-rw-r--r--drivers/video/imxfb.c2
-rw-r--r--drivers/video/jz4740_fb.c2
-rw-r--r--drivers/video/mb862xx/mb862xxfbdrv.c2
-rw-r--r--drivers/video/msm/mddi.c2
-rw-r--r--drivers/video/msm/mddi_client_dummy.c2
-rw-r--r--drivers/video/msm/mddi_client_nt35399.c2
-rw-r--r--drivers/video/msm/mddi_client_toshiba.c2
-rw-r--r--drivers/video/msm/mdp.c14
-rw-r--r--drivers/video/msm/mdp_hw.h2
-rw-r--r--drivers/video/msm/mdp_ppp.c2
-rw-r--r--drivers/video/msm/msm_fb.c2
-rw-r--r--drivers/video/mx3fb.c4
-rw-r--r--drivers/video/nuc900fb.c2
-rw-r--r--drivers/video/nuc900fb.h2
-rw-r--r--drivers/video/omap/lcd_ams_delta.c3
-rw-r--r--drivers/video/omap/lcd_mipid.c2
-rw-r--r--drivers/video/omap/lcd_osk.c2
-rw-r--r--drivers/video/omap2/displays/panel-taal.c6
-rw-r--r--drivers/video/omap2/dss/dispc.c1
-rw-r--r--drivers/video/omap2/dss/dsi.c6
-rw-r--r--drivers/video/omap2/dss/sdi.c14
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c5
-rw-r--r--drivers/video/ps3fb.c3
-rw-r--r--drivers/video/pxafb.c2
-rw-r--r--drivers/video/sbuslib.c5
-rw-r--r--drivers/video/smscufx.c1
-rw-r--r--drivers/video/tmiofb.c4
-rw-r--r--drivers/video/udlfb.c1
-rw-r--r--drivers/video/vermilion/vermilion.c1
-rw-r--r--drivers/video/vfb.c1
-rw-r--r--drivers/video/vt8500lcdfb.c81
-rw-r--r--drivers/video/wm8505fb.c99
-rw-r--r--drivers/video/wmt_ge_rops.c9
66 files changed, 1667 insertions, 1149 deletions
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c
index a425d65d5ba..fa44fbed397 100644
--- a/drivers/video/68328fb.c
+++ b/drivers/video/68328fb.c
@@ -400,7 +400,7 @@ static int mc68x328fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
#ifndef MMU
/* this is uClinux (no MMU) specific code */
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_start = videomemory;
return 0;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 0217f7415ef..20c33c42600 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -979,18 +979,6 @@ config FB_PVR2
(<file:drivers/video/pvr2fb.c>). Please see the file
<file:Documentation/fb/pvr2fb.txt>.
-config FB_EPSON1355
- bool "Epson 1355 framebuffer support"
- depends on (FB = y) && ARCH_CEIVA
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Build in support for the SED1355 Epson Research Embedded RAMDAC
- LCD/CRT Controller (since redesignated as the S1D13505) as a
- framebuffer. Product specs at
- <http://vdc.epson.com/>.
-
config FB_S1D13XXX
tristate "Epson S1D13XXX framebuffer support"
depends on FB
@@ -1788,7 +1776,7 @@ config FB_AU1200
config FB_VT8500
bool "VT8500 LCD Driver"
- depends on (FB = y) && ARM && ARCH_VT8500 && VTWM_VERSION_VT8500
+ depends on (FB = y) && ARM && ARCH_VT8500
select FB_WMT_GE_ROPS
select FB_SYS_IMAGEBLIT
help
@@ -1797,11 +1785,11 @@ config FB_VT8500
config FB_WM8505
bool "WM8505 frame buffer support"
- depends on (FB = y) && ARM && ARCH_VT8500 && VTWM_VERSION_WM8505
+ depends on (FB = y) && ARM && ARCH_VT8500
select FB_WMT_GE_ROPS
select FB_SYS_IMAGEBLIT
help
- This is the framebuffer driver for WonderMedia WM8505
+ This is the framebuffer driver for WonderMedia WM8505/WM8650
integrated LCD controller.
source "drivers/video/geode/Kconfig"
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index ee8dafb69e3..194035986af 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -94,7 +94,6 @@ obj-$(CONFIG_FB_G364) += g364fb.o
obj-$(CONFIG_FB_EP93XX) += ep93xx-fb.o
obj-$(CONFIG_FB_SA1100) += sa1100fb.o
obj-$(CONFIG_FB_HIT) += hitfb.o
-obj-$(CONFIG_FB_EPSON1355) += epson1355fb.o
obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o
obj-$(CONFIG_FB_PVR2) += pvr2fb.o
obj-$(CONFIG_FB_VOODOO1) += sstfb.o
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 747442d2c0f..0fefa84ed9a 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -149,7 +149,7 @@ enum {
};
/* Must match above enum */
-static const char *r128_family[] __devinitdata = {
+static char * const r128_family[] __devinitconst = {
"AGP",
"PCI",
"PRO AGP",
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 3f2e8c13f1c..868932f904e 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -1942,8 +1942,7 @@ static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
off = vma->vm_pgoff << PAGE_SHIFT;
size = vma->vm_end - vma->vm_start;
- /* To stop the swapper from even considering these pages. */
- vma->vm_flags |= (VM_IO | VM_RESERVED);
+ /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
if (((vma->vm_pgoff == 0) && (size == info->fix.smem_len)) ||
((off == info->fix.smem_len) && (size == PAGE_SIZE)))
diff --git a/drivers/video/auo_k190x.c b/drivers/video/auo_k190x.c
index 77da6a2f43d..c03ecdd31e4 100644
--- a/drivers/video/auo_k190x.c
+++ b/drivers/video/auo_k190x.c
@@ -987,7 +987,6 @@ err_regfb:
fb_dealloc_cmap(&info->cmap);
err_cmap:
fb_deferred_io_cleanup(info);
- kfree(info->fbdefio);
err_defio:
vfree((void *)info->screen_base);
err_irq:
@@ -1022,7 +1021,6 @@ int __devexit auok190x_common_remove(struct platform_device *pdev)
fb_dealloc_cmap(&info->cmap);
fb_deferred_io_cleanup(info);
- kfree(info->fbdefio);
vfree((void *)info->screen_base);
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index f75da8758ad..b7ec34c57f4 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/fb.h>
@@ -31,57 +32,26 @@ struct pm860x_backlight_data {
int port;
int pwm;
int iset;
+ int reg_duty_cycle;
+ int reg_always_on;
+ int reg_current;
};
-static inline int wled_a(int port)
-{
- int ret;
-
- ret = ((port - PM8606_BACKLIGHT1) << 1) + 2;
- return ret;
-}
-
-static inline int wled_b(int port)
-{
- int ret;
-
- ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
- return ret;
-}
-
-/* WLED2 & WLED3 share the same IDC */
-static inline int wled_idc(int port)
-{
- int ret;
-
- switch (port) {
- case PM8606_BACKLIGHT1:
- case PM8606_BACKLIGHT2:
- ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
- break;
- case PM8606_BACKLIGHT3:
- default:
- ret = ((port - PM8606_BACKLIGHT2) << 1) + 3;
- break;
- }
- return ret;
-}
-
static int backlight_power_set(struct pm860x_chip *chip, int port,
int on)
{
int ret = -EINVAL;
switch (port) {
- case PM8606_BACKLIGHT1:
+ case 0:
ret = on ? pm8606_osc_enable(chip, WLED1_DUTY) :
pm8606_osc_disable(chip, WLED1_DUTY);
break;
- case PM8606_BACKLIGHT2:
+ case 1:
ret = on ? pm8606_osc_enable(chip, WLED2_DUTY) :
pm8606_osc_disable(chip, WLED2_DUTY);
break;
- case PM8606_BACKLIGHT3:
+ case 2:
ret = on ? pm8606_osc_enable(chip, WLED3_DUTY) :
pm8606_osc_disable(chip, WLED3_DUTY);
break;
@@ -104,13 +74,13 @@ static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
if (brightness)
backlight_power_set(chip, data->port, 1);
- ret = pm860x_reg_write(data->i2c, wled_a(data->port), value);
+ ret = pm860x_reg_write(data->i2c, data->reg_duty_cycle, value);
if (ret < 0)
goto out;
if ((data->current_brightness == 0) && brightness) {
if (data->iset) {
- ret = pm860x_set_bits(data->i2c, wled_idc(data->port),
+ ret = pm860x_set_bits(data->i2c, data->reg_current,
CURRENT_BITMASK, data->iset);
if (ret < 0)
goto out;
@@ -123,17 +93,17 @@ static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
}
if (brightness == MAX_BRIGHTNESS) {
/* set WLED_ON bit as 100% */
- ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+ ret = pm860x_set_bits(data->i2c, data->reg_always_on,
PM8606_WLED_ON, PM8606_WLED_ON);
}
} else {
if (brightness == MAX_BRIGHTNESS) {
/* set WLED_ON bit as 100% */
- ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+ ret = pm860x_set_bits(data->i2c, data->reg_always_on,
PM8606_WLED_ON, PM8606_WLED_ON);
} else {
/* clear WLED_ON bit since it's not 100% */
- ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+ ret = pm860x_set_bits(data->i2c, data->reg_always_on,
PM8606_WLED_ON, 0);
}
}
@@ -174,7 +144,7 @@ static int pm860x_backlight_get_brightness(struct backlight_device *bl)
struct pm860x_chip *chip = data->chip;
int ret;
- ret = pm860x_reg_read(data->i2c, wled_a(data->port));
+ ret = pm860x_reg_read(data->i2c, data->reg_duty_cycle);
if (ret < 0)
goto out;
data->current_brightness = ret;
@@ -190,46 +160,85 @@ static const struct backlight_ops pm860x_backlight_ops = {
.get_brightness = pm860x_backlight_get_brightness,
};
+#ifdef CONFIG_OF
+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;
+ int iset = 0;
+ if (!nproot)
+ return -ENODEV;
+ nproot = of_find_node_by_name(nproot, "backlights");
+ if (!nproot) {
+ dev_err(&pdev->dev, "failed to find backlights node\n");
+ return -ENODEV;
+ }
+ for_each_child_of_node(nproot, np) {
+ if (!of_node_cmp(np->name, name)) {
+ of_property_read_u32(np, "marvell,88pm860x-iset",
+ &iset);
+ data->iset = PM8606_WLED_CURRENT(iset);
+ of_property_read_u32(np, "marvell,88pm860x-pwm",
+ &data->pwm);
+ break;
+ }
+ }
+ return 0;
+}
+#else
+#define pm860x_backlight_dt_init(x, y, z) (-1)
+#endif
+
static int pm860x_backlight_probe(struct platform_device *pdev)
{
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct pm860x_backlight_pdata *pdata = NULL;
+ struct pm860x_backlight_pdata *pdata = pdev->dev.platform_data;
struct pm860x_backlight_data *data;
struct backlight_device *bl;
struct resource *res;
struct backlight_properties props;
char name[MFD_NAME_SIZE];
- int ret;
-
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "No I/O resource!\n");
- return -EINVAL;
- }
-
- pdata = pdev->dev.platform_data;
- if (pdata == NULL) {
- dev_err(&pdev->dev, "platform data isn't assigned to "
- "backlight\n");
- return -EINVAL;
- }
+ int ret = 0;
data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_backlight_data),
GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
- strncpy(name, res->name, MFD_NAME_SIZE);
+ 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;
+ }
+ 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;
+ }
+ 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;
+ }
+ data->reg_current = res->start;
+
+ memset(name, 0, MFD_NAME_SIZE);
+ sprintf(name, "backlight-%d", pdev->id);
+ data->port = pdev->id;
data->chip = chip;
data->i2c = (chip->id == CHIP_PM8606) ? chip->client \
: chip->companion;
data->current_brightness = MAX_BRIGHTNESS;
- data->pwm = pdata->pwm;
- data->iset = pdata->iset;
- data->port = pdata->flags;
- if (data->port < 0) {
- dev_err(&pdev->dev, "wrong platform data is assigned");
- kfree(data);
- return -EINVAL;
+ if (pm860x_backlight_dt_init(pdev, data, name)) {
+ if (pdata) {
+ data->pwm = pdata->pwm;
+ data->iset = pdata->iset;
+ }
}
memset(&props, 0, sizeof(struct backlight_properties));
@@ -248,12 +257,14 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
/* read current backlight */
ret = pm860x_backlight_get_brightness(bl);
if (ret < 0)
- goto out;
+ goto out_brt;
backlight_update_status(bl);
return 0;
-out:
+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 cf282763a8d..c101697a4ba 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -229,13 +229,6 @@ config BACKLIGHT_HP700
If you have an HP Jornada 700 series,
say Y to include backlight control driver.
-config BACKLIGHT_PROGEAR
- tristate "Frontpath ProGear Backlight Driver"
- depends on PCI && X86
- help
- If you have a Frontpath ProGear say Y to enable the
- backlight driver.
-
config BACKLIGHT_CARILLO_RANCH
tristate "Intel Carillo Ranch Backlight Driver"
depends on LCD_CLASS_DEVICE && PCI && X86 && FB_LE80578
@@ -352,6 +345,22 @@ config BACKLIGHT_AAT2870
If you have a AnalogicTech AAT2870 say Y to enable the
backlight driver.
+config BACKLIGHT_LM3630
+ tristate "Backlight Driver for LM3630"
+ depends on BACKLIGHT_CLASS_DEVICE && I2C
+ select REGMAP_I2C
+ help
+ This supports TI LM3630 Backlight Driver
+
+config BACKLIGHT_LM3639
+ tristate "Backlight Driver for LM3639"
+ depends on BACKLIGHT_CLASS_DEVICE && I2C
+ select REGMAP_I2C
+ select NEW_LEDS
+ select LEDS_CLASS
+ help
+ This supports TI LM3639 Backlight + 1.5A Flash LED Driver
+
config BACKLIGHT_LP855X
tristate "Backlight driver for TI LP855X"
depends on BACKLIGHT_CLASS_DEVICE && I2C
@@ -373,6 +382,13 @@ config BACKLIGHT_PANDORA
If you have a Pandora console, say Y to enable the
backlight driver.
+config BACKLIGHT_TPS65217
+ tristate "TPS65217 Backlight"
+ depends on BACKLIGHT_CLASS_DEVICE && MFD_TPS65217
+ help
+ If you have a Texas Instruments TPS65217 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 a2ac9cfbaf6..e7ce7291635 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -23,10 +23,11 @@ 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_PROGEAR) += progear_bl.o
obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
@@ -43,3 +44,4 @@ obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_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
diff --git a/drivers/video/backlight/da9052_bl.c b/drivers/video/backlight/da9052_bl.c
index b628d68f516..ac196181fe4 100644
--- a/drivers/video/backlight/da9052_bl.c
+++ b/drivers/video/backlight/da9052_bl.c
@@ -72,7 +72,7 @@ static int da9052_adjust_wled_brightness(struct da9052_bl *wleds)
if (ret < 0)
return ret;
- msleep(10);
+ usleep_range(10000, 11000);
if (wleds->brightness) {
ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg],
@@ -129,7 +129,6 @@ static int da9052_backlight_probe(struct platform_device *pdev)
&da9052_backlight_ops, &props);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "Failed to register backlight\n");
- devm_kfree(&pdev->dev, wleds);
return PTR_ERR(bl);
}
@@ -149,7 +148,6 @@ static int da9052_backlight_remove(struct platform_device *pdev)
wleds->state = DA9052_WLEDS_OFF;
da9052_adjust_wled_brightness(wleds);
backlight_device_unregister(bl);
- devm_kfree(&pdev->dev, wleds);
return 0;
}
diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c
index 72dd5556a35..6c5ed6b242c 100644
--- a/drivers/video/backlight/kb3886_bl.c
+++ b/drivers/video/backlight/kb3886_bl.c
@@ -34,9 +34,9 @@ static void kb3886_bl_set_intensity(int intensity)
mutex_lock(&bl_mutex);
intensity = intensity&0xff;
outb(KB3886_ADC_DAC_PWM, KB3886_PARENT);
- msleep(10);
+ usleep_range(10000, 11000);
outb(KB3886_PWM0_WRITE, KB3886_IO);
- msleep(10);
+ usleep_range(10000, 11000);
outb(intensity, KB3886_IO);
mutex_unlock(&bl_mutex);
}
diff --git a/drivers/video/backlight/lm3630_bl.c b/drivers/video/backlight/lm3630_bl.c
new file mode 100644
index 00000000000..dc191441796
--- /dev/null
+++ b/drivers/video/backlight/lm3630_bl.c
@@ -0,0 +1,475 @@
+/*
+* Simple driver for Texas Instruments LM3630 Backlight driver chip
+* Copyright (C) 2012 Texas Instruments
+*
+* 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/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <linux/regmap.h>
+#include <linux/platform_data/lm3630_bl.h>
+
+#define REG_CTRL 0x00
+#define REG_CONFIG 0x01
+#define REG_BRT_A 0x03
+#define REG_BRT_B 0x04
+#define REG_INT_STATUS 0x09
+#define REG_INT_EN 0x0A
+#define REG_FAULT 0x0B
+#define REG_PWM_OUTLOW 0x12
+#define REG_PWM_OUTHIGH 0x13
+#define REG_MAX 0x1F
+
+#define INT_DEBOUNCE_MSEC 10
+
+enum lm3630_leds {
+ BLED_ALL = 0,
+ BLED_1,
+ BLED_2
+};
+
+static const char *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 */
+};
+
+struct lm3630_chip_data {
+ struct device *dev;
+ struct delayed_work work;
+ int irq;
+ struct workqueue_struct *irqthread;
+ struct lm3630_platform_data *pdata;
+ struct backlight_device *bled1;
+ struct backlight_device *bled2;
+ struct regmap *regmap;
+};
+
+/* initialize chip */
+static int __devinit lm3630_chip_init(struct lm3630_chip_data *pchip)
+{
+ int ret;
+ unsigned int reg_val;
+ struct lm3630_platform_data *pdata = pchip->pdata;
+
+ /*pwm control */
+ reg_val = ((pdata->pwm_active & 0x01) << 2) | (pdata->pwm_ctrl & 0x03);
+ ret = regmap_update_bits(pchip->regmap, REG_CONFIG, 0x07, reg_val);
+ if (ret < 0)
+ goto out;
+
+ /* bank control */
+ reg_val = ((pdata->bank_b_ctrl & 0x01) << 1) |
+ (pdata->bank_a_ctrl & 0x07);
+ ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x07, reg_val);
+ if (ret < 0)
+ goto out;
+
+ ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00);
+ if (ret < 0)
+ goto out;
+
+ /* set initial brightness */
+ if (pdata->bank_a_ctrl != BANK_A_CTRL_DISABLE) {
+ ret = regmap_write(pchip->regmap,
+ REG_BRT_A, pdata->init_brt_led1);
+ if (ret < 0)
+ goto out;
+ }
+
+ if (pdata->bank_b_ctrl != BANK_B_CTRL_DISABLE) {
+ ret = regmap_write(pchip->regmap,
+ REG_BRT_B, pdata->init_brt_led2);
+ if (ret < 0)
+ goto out;
+ }
+ return ret;
+
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return ret;
+}
+
+/* interrupt handling */
+static void lm3630_delayed_func(struct work_struct *work)
+{
+ int ret;
+ unsigned int reg_val;
+ struct lm3630_chip_data *pchip;
+
+ pchip = container_of(work, struct lm3630_chip_data, work.work);
+
+ ret = regmap_read(pchip->regmap, REG_INT_STATUS, &reg_val);
+ if (ret < 0) {
+ dev_err(pchip->dev,
+ "i2c failed to access REG_INT_STATUS Register\n");
+ return;
+ }
+
+ dev_info(pchip->dev, "REG_INT_STATUS Register is 0x%x\n", reg_val);
+}
+
+static irqreturn_t lm3630_isr_func(int irq, void *chip)
+{
+ int ret;
+ struct lm3630_chip_data *pchip = chip;
+ unsigned long delay = msecs_to_jiffies(INT_DEBOUNCE_MSEC);
+
+ queue_delayed_work(pchip->irqthread, &pchip->work, delay);
+
+ ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00);
+ if (ret < 0)
+ goto out;
+
+ return IRQ_HANDLED;
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return IRQ_HANDLED;
+}
+
+static int lm3630_intr_config(struct lm3630_chip_data *pchip)
+{
+ INIT_DELAYED_WORK(&pchip->work, lm3630_delayed_func);
+ pchip->irqthread = create_singlethread_workqueue("lm3630-irqthd");
+ if (!pchip->irqthread) {
+ dev_err(pchip->dev, "create irq thread fail...\n");
+ return -1;
+ }
+ if (request_threaded_irq
+ (pchip->irq, NULL, lm3630_isr_func,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "lm3630_irq", pchip)) {
+ dev_err(pchip->dev, "request threaded irq fail..\n");
+ return -1;
+ }
+ return 0;
+}
+
+static bool
+set_intensity(struct backlight_device *bl, struct lm3630_chip_data *pchip)
+{
+ if (!pchip->pdata->pwm_set_intensity)
+ return false;
+ pchip->pdata->pwm_set_intensity(bl->props.brightness - 1,
+ pchip->pdata->pwm_period);
+ return true;
+}
+
+/* update and get brightness */
+static int lm3630_bank_a_update_status(struct backlight_device *bl)
+{
+ int ret;
+ struct lm3630_chip_data *pchip = bl_get_data(bl);
+ enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl;
+
+ /* brightness 0 means disable */
+ if (!bl->props.brightness) {
+ ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x04, 0x00);
+ if (ret < 0)
+ goto out;
+ return bl->props.brightness;
+ }
+
+ /* pwm control */
+ if (pwm_ctrl == PWM_CTRL_BANK_A || pwm_ctrl == PWM_CTRL_BANK_ALL) {
+ if (!set_intensity(bl, pchip))
+ dev_err(pchip->dev, "No pwm control func. in plat-data\n");
+ } else {
+
+ /* i2c control */
+ ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00);
+ if (ret < 0)
+ goto out;
+ mdelay(1);
+ ret = regmap_write(pchip->regmap,
+ REG_BRT_A, bl->props.brightness - 1);
+ if (ret < 0)
+ goto out;
+ }
+ return bl->props.brightness;
+out:
+ dev_err(pchip->dev, "i2c failed to access REG_CTRL\n");
+ return bl->props.brightness;
+}
+
+static int lm3630_bank_a_get_brightness(struct backlight_device *bl)
+{
+ unsigned int reg_val;
+ int brightness, ret;
+ struct lm3630_chip_data *pchip = bl_get_data(bl);
+ enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl;
+
+ if (pwm_ctrl == PWM_CTRL_BANK_A || pwm_ctrl == PWM_CTRL_BANK_ALL) {
+ ret = regmap_read(pchip->regmap, REG_PWM_OUTHIGH, &reg_val);
+ if (ret < 0)
+ goto out;
+ brightness = reg_val & 0x01;
+ ret = regmap_read(pchip->regmap, REG_PWM_OUTLOW, &reg_val);
+ if (ret < 0)
+ goto out;
+ brightness = ((brightness << 8) | reg_val) + 1;
+ } else {
+ ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00);
+ if (ret < 0)
+ goto out;
+ mdelay(1);
+ ret = regmap_read(pchip->regmap, REG_BRT_A, &reg_val);
+ if (ret < 0)
+ goto out;
+ brightness = reg_val + 1;
+ }
+ bl->props.brightness = brightness;
+ return bl->props.brightness;
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return 0;
+}
+
+static const struct backlight_ops lm3630_bank_a_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = lm3630_bank_a_update_status,
+ .get_brightness = lm3630_bank_a_get_brightness,
+};
+
+static int lm3630_bank_b_update_status(struct backlight_device *bl)
+{
+ int ret;
+ struct lm3630_chip_data *pchip = bl_get_data(bl);
+ enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl;
+
+ if (pwm_ctrl == PWM_CTRL_BANK_B || pwm_ctrl == PWM_CTRL_BANK_ALL) {
+ if (!set_intensity(bl, pchip))
+ dev_err(pchip->dev,
+ "no pwm control func. in plat-data\n");
+ } else {
+ ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00);
+ if (ret < 0)
+ goto out;
+ mdelay(1);
+ ret = regmap_write(pchip->regmap,
+ REG_BRT_B, bl->props.brightness - 1);
+ }
+ return bl->props.brightness;
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return bl->props.brightness;
+}
+
+static int lm3630_bank_b_get_brightness(struct backlight_device *bl)
+{
+ unsigned int reg_val;
+ int brightness, ret;
+ struct lm3630_chip_data *pchip = bl_get_data(bl);
+ enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl;
+
+ if (pwm_ctrl == PWM_CTRL_BANK_B || pwm_ctrl == PWM_CTRL_BANK_ALL) {
+ ret = regmap_read(pchip->regmap, REG_PWM_OUTHIGH, &reg_val);
+ if (ret < 0)
+ goto out;
+ brightness = reg_val & 0x01;
+ ret = regmap_read(pchip->regmap, REG_PWM_OUTLOW, &reg_val);
+ if (ret < 0)
+ goto out;
+ brightness = ((brightness << 8) | reg_val) + 1;
+ } else {
+ ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00);
+ if (ret < 0)
+ goto out;
+ mdelay(1);
+ ret = regmap_read(pchip->regmap, REG_BRT_B, &reg_val);
+ if (ret < 0)
+ goto out;
+ brightness = reg_val + 1;
+ }
+ bl->props.brightness = brightness;
+
+ return bl->props.brightness;
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return bl->props.brightness;
+}
+
+static const struct backlight_ops lm3630_bank_b_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = lm3630_bank_b_update_status,
+ .get_brightness = lm3630_bank_b_get_brightness,
+};
+
+static int lm3630_backlight_register(struct lm3630_chip_data *pchip,
+ enum lm3630_leds ledno)
+{
+ const char *name = bled_name[ledno];
+ struct backlight_properties props;
+ struct lm3630_platform_data *pdata = pchip->pdata;
+
+ props.type = BACKLIGHT_RAW;
+ switch (ledno) {
+ case BLED_1:
+ case BLED_ALL:
+ props.brightness = pdata->init_brt_led1;
+ props.max_brightness = pdata->max_brt_led1;
+ pchip->bled1 =
+ backlight_device_register(name, pchip->dev, pchip,
+ &lm3630_bank_a_ops, &props);
+ if (IS_ERR(pchip->bled1))
+ return -EIO;
+ break;
+ case BLED_2:
+ props.brightness = pdata->init_brt_led2;
+ props.max_brightness = pdata->max_brt_led2;
+ pchip->bled2 =
+ backlight_device_register(name, pchip->dev, pchip,
+ &lm3630_bank_b_ops, &props);
+ if (IS_ERR(pchip->bled2))
+ return -EIO;
+ break;
+ }
+ return 0;
+}
+
+static void lm3630_backlight_unregister(struct lm3630_chip_data *pchip)
+{
+ if (pchip->bled1)
+ backlight_device_unregister(pchip->bled1);
+ if (pchip->bled2)
+ backlight_device_unregister(pchip->bled2);
+}
+
+static const struct regmap_config lm3630_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = REG_MAX,
+};
+
+static int __devinit lm3630_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct lm3630_platform_data *pdata = client->dev.platform_data;
+ struct lm3630_chip_data *pchip;
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(&client->dev, "fail : i2c functionality check...\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (pdata == NULL) {
+ dev_err(&client->dev, "fail : no platform data.\n");
+ return -ENODATA;
+ }
+
+ pchip = devm_kzalloc(&client->dev, sizeof(struct lm3630_chip_data),
+ GFP_KERNEL);
+ if (!pchip)
+ return -ENOMEM;
+ pchip->pdata = pdata;
+ pchip->dev = &client->dev;
+
+ pchip->regmap = devm_regmap_init_i2c(client, &lm3630_regmap);
+ if (IS_ERR(pchip->regmap)) {
+ ret = PTR_ERR(pchip->regmap);
+ dev_err(&client->dev, "fail : allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+ i2c_set_clientdata(client, pchip);
+
+ /* chip initialize */
+ ret = lm3630_chip_init(pchip);
+ if (ret < 0) {
+ dev_err(&client->dev, "fail : init chip\n");
+ goto err_chip_init;
+ }
+
+ switch (pdata->bank_a_ctrl) {
+ case BANK_A_CTRL_ALL:
+ ret = lm3630_backlight_register(pchip, BLED_ALL);
+ pdata->bank_b_ctrl = BANK_B_CTRL_DISABLE;
+ break;
+ case BANK_A_CTRL_LED1:
+ ret = lm3630_backlight_register(pchip, BLED_1);
+ break;
+ case BANK_A_CTRL_LED2:
+ ret = lm3630_backlight_register(pchip, BLED_2);
+ pdata->bank_b_ctrl = BANK_B_CTRL_DISABLE;
+ break;
+ default:
+ break;
+ }
+
+ if (ret < 0)
+ goto err_bl_reg;
+
+ if (pdata->bank_b_ctrl && pchip->bled2 == NULL) {
+ ret = lm3630_backlight_register(pchip, BLED_2);
+ if (ret < 0)
+ goto err_bl_reg;
+ }
+
+ /* interrupt enable : irq 0 is not allowed for lm3630 */
+ pchip->irq = client->irq;
+ if (pchip->irq)
+ lm3630_intr_config(pchip);
+
+ dev_info(&client->dev, "LM3630 backlight register OK.\n");
+ return 0;
+
+err_bl_reg:
+ dev_err(&client->dev, "fail : backlight register.\n");
+ lm3630_backlight_unregister(pchip);
+err_chip_init:
+ return ret;
+}
+
+static int __devexit lm3630_remove(struct i2c_client *client)
+{
+ int ret;
+ struct lm3630_chip_data *pchip = i2c_get_clientdata(client);
+
+ ret = regmap_write(pchip->regmap, REG_BRT_A, 0);
+ if (ret < 0)
+ dev_err(pchip->dev, "i2c failed to access register\n");
+
+ ret = regmap_write(pchip->regmap, REG_BRT_B, 0);
+ if (ret < 0)
+ dev_err(pchip->dev, "i2c failed to access register\n");
+
+ lm3630_backlight_unregister(pchip);
+ if (pchip->irq) {
+ free_irq(pchip->irq, pchip);
+ flush_workqueue(pchip->irqthread);
+ destroy_workqueue(pchip->irqthread);
+ }
+ return 0;
+}
+
+static const struct i2c_device_id lm3630_id[] = {
+ {LM3630_NAME, 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, lm3630_id);
+
+static struct i2c_driver lm3630_i2c_driver = {
+ .driver = {
+ .name = LM3630_NAME,
+ },
+ .probe = lm3630_probe,
+ .remove = __devexit_p(lm3630_remove),
+ .id_table = lm3630_id,
+};
+
+module_i2c_driver(lm3630_i2c_driver);
+
+MODULE_DESCRIPTION("Texas Instruments Backlight driver for LM3630");
+MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
+MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c
new file mode 100644
index 00000000000..c6915c6c3cd
--- /dev/null
+++ b/drivers/video/backlight/lm3639_bl.c
@@ -0,0 +1,437 @@
+/*
+* Simple driver for Texas Instruments LM3639 Backlight + Flash LED driver chip
+* Copyright (C) 2012 Texas Instruments
+*
+* 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/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <linux/regmap.h>
+#include <linux/platform_data/lm3639_bl.h>
+
+#define REG_DEV_ID 0x00
+#define REG_CHECKSUM 0x01
+#define REG_BL_CONF_1 0x02
+#define REG_BL_CONF_2 0x03
+#define REG_BL_CONF_3 0x04
+#define REG_BL_CONF_4 0x05
+#define REG_FL_CONF_1 0x06
+#define REG_FL_CONF_2 0x07
+#define REG_FL_CONF_3 0x08
+#define REG_IO_CTRL 0x09
+#define REG_ENABLE 0x0A
+#define REG_FLAG 0x0B
+#define REG_MAX REG_FLAG
+
+struct lm3639_chip_data {
+ struct device *dev;
+ struct lm3639_platform_data *pdata;
+
+ struct backlight_device *bled;
+ struct led_classdev cdev_flash;
+ struct led_classdev cdev_torch;
+ struct regmap *regmap;
+
+ unsigned int bled_mode;
+ unsigned int bled_map;
+ unsigned int last_flag;
+};
+
+/* initialize chip */
+static int __devinit lm3639_chip_init(struct lm3639_chip_data *pchip)
+{
+ int ret;
+ unsigned int reg_val;
+ struct lm3639_platform_data *pdata = pchip->pdata;
+
+ /* input pins config. */
+ ret =
+ regmap_update_bits(pchip->regmap, REG_BL_CONF_1, 0x08,
+ pdata->pin_pwm);
+ if (ret < 0)
+ goto out;
+
+ reg_val = (pdata->pin_pwm & 0x40) | pdata->pin_strobe | pdata->pin_tx;
+ ret = regmap_update_bits(pchip->regmap, REG_IO_CTRL, 0x7C, reg_val);
+ if (ret < 0)
+ goto out;
+
+ /* init brightness */
+ ret = regmap_write(pchip->regmap, REG_BL_CONF_4, pdata->init_brt_led);
+ if (ret < 0)
+ goto out;
+
+ ret = regmap_write(pchip->regmap, REG_BL_CONF_3, pdata->init_brt_led);
+ if (ret < 0)
+ goto out;
+
+ /* output pins config. */
+ if (!pdata->init_brt_led)
+ reg_val = pdata->fled_pins | pdata->bled_pins;
+ else
+ reg_val = pdata->fled_pins | pdata->bled_pins | 0x01;
+
+ ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x79, reg_val);
+ if (ret < 0)
+ goto out;
+
+ return ret;
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return ret;
+}
+
+/* update and get brightness */
+static int lm3639_bled_update_status(struct backlight_device *bl)
+{
+ int ret;
+ unsigned int reg_val;
+ struct lm3639_chip_data *pchip = bl_get_data(bl);
+ struct lm3639_platform_data *pdata = pchip->pdata;
+
+ ret = regmap_read(pchip->regmap, REG_FLAG, &reg_val);
+ if (ret < 0)
+ goto out;
+
+ if (reg_val != 0)
+ dev_info(pchip->dev, "last flag is 0x%x\n", reg_val);
+
+ /* pwm control */
+ if (pdata->pin_pwm) {
+ if (pdata->pwm_set_intensity)
+ pdata->pwm_set_intensity(bl->props.brightness,
+ pdata->max_brt_led);
+ else
+ dev_err(pchip->dev,
+ "No pwm control func. in plat-data\n");
+ return bl->props.brightness;
+ }
+
+ /* i2c control and set brigtness */
+ ret = regmap_write(pchip->regmap, REG_BL_CONF_4, bl->props.brightness);
+ if (ret < 0)
+ goto out;
+ ret = regmap_write(pchip->regmap, REG_BL_CONF_3, bl->props.brightness);
+ if (ret < 0)
+ goto out;
+
+ if (!bl->props.brightness)
+ ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x01, 0x00);
+ else
+ ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x01, 0x01);
+ if (ret < 0)
+ goto out;
+
+ return bl->props.brightness;
+out:
+ dev_err(pchip->dev, "i2c failed to access registers\n");
+ return bl->props.brightness;
+}
+
+static int lm3639_bled_get_brightness(struct backlight_device *bl)
+{
+ int ret;
+ unsigned int reg_val;
+ struct lm3639_chip_data *pchip = bl_get_data(bl);
+ struct lm3639_platform_data *pdata = pchip->pdata;
+
+ if (pdata->pin_pwm) {
+ if (pdata->pwm_get_intensity)
+ bl->props.brightness = pdata->pwm_get_intensity();
+ else
+ dev_err(pchip->dev,
+ "No pwm control func. in plat-data\n");
+ return bl->props.brightness;
+ }
+
+ ret = regmap_read(pchip->regmap, REG_BL_CONF_1, &reg_val);
+ if (ret < 0)
+ goto out;
+ if (reg_val & 0x10)
+ ret = regmap_read(pchip->regmap, REG_BL_CONF_4, &reg_val);
+ else
+ ret = regmap_read(pchip->regmap, REG_BL_CONF_3, &reg_val);
+ if (ret < 0)
+ goto out;
+ bl->props.brightness = reg_val;
+
+ return bl->props.brightness;
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return bl->props.brightness;
+}
+
+static const struct backlight_ops lm3639_bled_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = lm3639_bled_update_status,
+ .get_brightness = lm3639_bled_get_brightness,
+};
+
+/* backlight mapping mode */
+static ssize_t lm3639_bled_mode_store(struct device *dev,
+ struct device_attribute *devAttr,
+ const char *buf, size_t size)
+{
+ ssize_t ret;
+ struct lm3639_chip_data *pchip = dev_get_drvdata(dev);
+ unsigned int state;
+
+ ret = kstrtouint(buf, 10, &state);
+ if (ret)
+ goto out_input;
+
+ if (!state)
+ ret =
+ regmap_update_bits(pchip->regmap, REG_BL_CONF_1, 0x10,
+ 0x00);
+ else
+ ret =
+ regmap_update_bits(pchip->regmap, REG_BL_CONF_1, 0x10,
+ 0x10);
+
+ if (ret < 0)
+ goto out;
+
+ return size;
+
+out:
+ dev_err(pchip->dev, "%s:i2c access fail to register\n", __func__);
+ return size;
+
+out_input:
+ dev_err(pchip->dev, "%s:input conversion fail\n", __func__);
+ return size;
+
+}
+
+static DEVICE_ATTR(bled_mode, 0666, NULL, lm3639_bled_mode_store);
+
+/* torch */
+static void lm3639_torch_brightness_set(struct led_classdev *cdev,
+ enum led_brightness brightness)
+{
+ int ret;
+ unsigned int reg_val;
+ struct lm3639_chip_data *pchip;
+
+ pchip = container_of(cdev, struct lm3639_chip_data, cdev_torch);
+
+ ret = regmap_read(pchip->regmap, REG_FLAG, &reg_val);
+ if (ret < 0)
+ goto out;
+ if (reg_val != 0)
+ dev_info(pchip->dev, "last flag is 0x%x\n", reg_val);
+
+ /* brightness 0 means off state */
+ if (!brightness) {
+ ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x06, 0x00);
+ if (ret < 0)
+ goto out;
+ return;
+ }
+
+ ret = regmap_update_bits(pchip->regmap,
+ REG_FL_CONF_1, 0x70, (brightness - 1) << 4);
+ if (ret < 0)
+ goto out;
+ ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x06, 0x02);
+ if (ret < 0)
+ goto out;
+
+ return;
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return;
+}
+
+/* flash */
+static void lm3639_flash_brightness_set(struct led_classdev *cdev,
+ enum led_brightness brightness)
+{
+ int ret;
+ unsigned int reg_val;
+ struct lm3639_chip_data *pchip;
+
+ pchip = container_of(cdev, struct lm3639_chip_data, cdev_flash);
+
+ ret = regmap_read(pchip->regmap, REG_FLAG, &reg_val);
+ if (ret < 0)
+ goto out;
+ if (reg_val != 0)
+ dev_info(pchip->dev, "last flag is 0x%x\n", reg_val);
+
+ /* torch off before flash control */
+ ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x06, 0x00);
+ if (ret < 0)
+ goto out;
+
+ /* brightness 0 means off state */
+ if (!brightness)
+ return;
+
+ ret = regmap_update_bits(pchip->regmap,
+ REG_FL_CONF_1, 0x0F, brightness - 1);
+ if (ret < 0)
+ goto out;
+ ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x06, 0x06);
+ if (ret < 0)
+ goto out;
+
+ return;
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return;
+}
+
+static const struct regmap_config lm3639_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = REG_MAX,
+};
+
+static int __devinit lm3639_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret;
+ struct lm3639_chip_data *pchip;
+ struct lm3639_platform_data *pdata = client->dev.platform_data;
+ struct backlight_properties props;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(&client->dev, "i2c functionality check fail.\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (pdata == NULL) {
+ dev_err(&client->dev, "Needs Platform Data.\n");
+ return -ENODATA;
+ }
+
+ pchip = devm_kzalloc(&client->dev,
+ sizeof(struct lm3639_chip_data), GFP_KERNEL);
+ if (!pchip)
+ return -ENOMEM;
+
+ pchip->pdata = pdata;
+ pchip->dev = &client->dev;
+
+ pchip->regmap = devm_regmap_init_i2c(client, &lm3639_regmap);
+ if (IS_ERR(pchip->regmap)) {
+ ret = PTR_ERR(pchip->regmap);
+ dev_err(&client->dev, "fail : allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+ i2c_set_clientdata(client, pchip);
+
+ /* chip initialize */
+ ret = lm3639_chip_init(pchip);
+ if (ret < 0) {
+ dev_err(&client->dev, "fail : chip init\n");
+ goto err_out;
+ }
+
+ /* backlight */
+ props.type = BACKLIGHT_RAW;
+ props.brightness = pdata->init_brt_led;
+ props.max_brightness = pdata->max_brt_led;
+ pchip->bled =
+ backlight_device_register("lm3639_bled", pchip->dev, pchip,
+ &lm3639_bled_ops, &props);
+ if (IS_ERR(pchip->bled)) {
+ dev_err(&client->dev, "fail : backlight register\n");
+ ret = -EIO;
+ 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;
+ }
+
+ /* flash */
+ pchip->cdev_flash.name = "lm3639_flash";
+ pchip->cdev_flash.max_brightness = 16;
+ pchip->cdev_flash.brightness_set = lm3639_flash_brightness_set;
+ ret = led_classdev_register((struct device *)
+ &client->dev, &pchip->cdev_flash);
+ if (ret < 0) {
+ dev_err(&client->dev, "fail : flash register\n");
+ ret = -EIO;
+ goto err_flash;
+ }
+
+ /* torch */
+ pchip->cdev_torch.name = "lm3639_torch";
+ pchip->cdev_torch.max_brightness = 8;
+ pchip->cdev_torch.brightness_set = lm3639_torch_brightness_set;
+ ret = led_classdev_register((struct device *)
+ &client->dev, &pchip->cdev_torch);
+ if (ret < 0) {
+ dev_err(&client->dev, "fail : torch register\n");
+ ret = -EIO;
+ goto err_torch;
+ }
+
+ return 0;
+
+err_torch:
+ led_classdev_unregister(&pchip->cdev_flash);
+err_flash:
+ device_remove_file(&(pchip->bled->dev), &dev_attr_bled_mode);
+err_bled_mode:
+ backlight_device_unregister(pchip->bled);
+err_out:
+ return ret;
+}
+
+static int __devexit lm3639_remove(struct i2c_client *client)
+{
+ struct lm3639_chip_data *pchip = i2c_get_clientdata(client);
+
+ regmap_write(pchip->regmap, REG_ENABLE, 0x00);
+
+ if (&pchip->cdev_torch)
+ led_classdev_unregister(&pchip->cdev_torch);
+ if (&pchip->cdev_flash)
+ led_classdev_unregister(&pchip->cdev_flash);
+ if (pchip->bled) {
+ device_remove_file(&(pchip->bled->dev), &dev_attr_bled_mode);
+ backlight_device_unregister(pchip->bled);
+ }
+ return 0;
+}
+
+static const struct i2c_device_id lm3639_id[] = {
+ {LM3639_NAME, 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, lm3639_id);
+static struct i2c_driver lm3639_i2c_driver = {
+ .driver = {
+ .name = LM3639_NAME,
+ },
+ .probe = lm3639_probe,
+ .remove = __devexit_p(lm3639_remove),
+ .id_table = lm3639_id,
+};
+
+module_i2c_driver(lm3639_i2c_driver);
+
+MODULE_DESCRIPTION("Texas Instruments Backlight+Flash LED driver for LM3639");
+MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
+MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c
index 6c0f1ac0d32..4066a5bbd82 100644
--- a/drivers/video/backlight/ltv350qv.c
+++ b/drivers/video/backlight/ltv350qv.c
@@ -75,7 +75,7 @@ static int ltv350qv_power_on(struct ltv350qv *lcd)
/* Power On Reset Display off State */
if (ltv350qv_write_reg(lcd, LTV_PWRCTL1, 0x0000))
goto err;
- msleep(15);
+ usleep_range(15000, 16000);
/* Power Setting Function 1 */
if (ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE))
@@ -153,7 +153,7 @@ err_settings:
err_power2:
err_power1:
ltv350qv_write_reg(lcd, LTV_PWRCTL2, 0x0000);
- msleep(1);
+ usleep_range(1000, 1100);
err:
ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE);
return -EIO;
@@ -175,7 +175,7 @@ static int ltv350qv_power_off(struct ltv350qv *lcd)
ret |= ltv350qv_write_reg(lcd, LTV_PWRCTL2, 0x0000);
/* Wait at least 1 ms */
- msleep(1);
+ usleep_range(1000, 1100);
/* Power down setting 2 */
ret |= ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE);
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c
index e833ac72e06..f72ba54f364 100644
--- a/drivers/video/backlight/max8925_bl.c
+++ b/drivers/video/backlight/max8925_bl.c
@@ -27,7 +27,9 @@
struct max8925_backlight_data {
struct max8925_chip *chip;
- int current_brightness;
+ int current_brightness;
+ int reg_mode_cntl;
+ int reg_cntl;
};
static int max8925_backlight_set(struct backlight_device *bl, int brightness)
@@ -42,16 +44,16 @@ static int max8925_backlight_set(struct backlight_device *bl, int brightness)
else
value = brightness;
- ret = max8925_reg_write(chip->i2c, MAX8925_WLED_CNTL, value);
+ ret = max8925_reg_write(chip->i2c, data->reg_cntl, value);
if (ret < 0)
goto out;
if (!data->current_brightness && brightness)
/* enable WLED output */
- ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 1);
+ ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 1, 1);
else if (!brightness)
/* disable WLED output */
- ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 0);
+ ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 1, 0);
if (ret < 0)
goto out;
dev_dbg(chip->dev, "set brightness %d\n", value);
@@ -85,7 +87,7 @@ static int max8925_backlight_get_brightness(struct backlight_device *bl)
struct max8925_chip *chip = data->chip;
int ret;
- ret = max8925_reg_read(chip->i2c, MAX8925_WLED_CNTL);
+ ret = max8925_reg_read(chip->i2c, data->reg_cntl);
if (ret < 0)
return -EINVAL;
data->current_brightness = ret;
@@ -102,69 +104,70 @@ static const struct backlight_ops max8925_backlight_ops = {
static int __devinit max8925_backlight_probe(struct platform_device *pdev)
{
struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct max8925_platform_data *max8925_pdata;
- struct max8925_backlight_pdata *pdata = NULL;
+ struct max8925_backlight_pdata *pdata = pdev->dev.platform_data;
struct max8925_backlight_data *data;
struct backlight_device *bl;
struct backlight_properties props;
struct resource *res;
- char name[MAX8925_NAME_SIZE];
unsigned char value;
- int ret;
-
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "No I/O resource!\n");
- return -EINVAL;
- }
-
- if (pdev->dev.parent->platform_data) {
- max8925_pdata = pdev->dev.parent->platform_data;
- pdata = max8925_pdata->backlight;
- }
-
- if (!pdata) {
- dev_err(&pdev->dev, "platform data isn't assigned to "
- "backlight\n");
- return -EINVAL;
- }
+ int ret = 0;
data = devm_kzalloc(&pdev->dev, sizeof(struct max8925_backlight_data),
GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
- strncpy(name, res->name, MAX8925_NAME_SIZE);
+
+ 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;
+ }
+ 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;
+ }
+ data->reg_cntl = res->start;
+
data->chip = chip;
data->current_brightness = 0;
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_RAW;
props.max_brightness = MAX_BRIGHTNESS;
- bl = backlight_device_register(name, &pdev->dev, data,
+ bl = backlight_device_register("max8925-backlight", &pdev->dev, data,
&max8925_backlight_ops, &props);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
- return PTR_ERR(bl);
+ ret = PTR_ERR(bl);
+ goto out;
}
bl->props.brightness = MAX_BRIGHTNESS;
platform_set_drvdata(pdev, bl);
value = 0;
- if (pdata->lxw_scl)
- value |= (1 << 7);
- if (pdata->lxw_freq)
- value |= (LWX_FREQ(pdata->lxw_freq) << 4);
- if (pdata->dual_string)
- value |= (1 << 1);
- ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 0xfe, value);
+ if (pdata) {
+ if (pdata->lxw_scl)
+ value |= (1 << 7);
+ if (pdata->lxw_freq)
+ value |= (LWX_FREQ(pdata->lxw_freq) << 4);
+ if (pdata->dual_string)
+ value |= (1 << 1);
+ }
+ ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 0xfe, value);
if (ret < 0)
- goto out;
+ goto out_brt;
backlight_update_status(bl);
return 0;
-out:
+out_brt:
backlight_device_unregister(bl);
+out:
+ devm_kfree(&pdev->dev, data);
return ret;
}
diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c
index bfdc5fbeaa1..9a046a4c98f 100644
--- a/drivers/video/backlight/omap1_bl.c
+++ b/drivers/video/backlight/omap1_bl.c
@@ -27,10 +27,10 @@
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/slab.h>
+#include <linux/platform_data/omap1_bl.h>
#include <mach/hardware.h>
-#include <plat/board.h>
-#include <plat/mux.h>
+#include <mach/mux.h>
#define OMAPBL_MAX_INTENSITY 0xff
diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c
index b6672340d6c..ca4f5d70fe1 100644
--- a/drivers/video/backlight/platform_lcd.c
+++ b/drivers/video/backlight/platform_lcd.c
@@ -16,6 +16,7 @@
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/lcd.h>
+#include <linux/of.h>
#include <linux/slab.h>
#include <video/platform_lcd.h>
@@ -145,6 +146,14 @@ static SIMPLE_DEV_PM_OPS(platform_lcd_pm_ops, platform_lcd_suspend,
platform_lcd_resume);
#endif
+#ifdef CONFIG_OF
+static const struct of_device_id platform_lcd_of_match[] = {
+ { .compatible = "platform-lcd" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, platform_lcd_of_match);
+#endif
+
static struct platform_driver platform_lcd_driver = {
.driver = {
.name = "platform-lcd",
@@ -152,6 +161,7 @@ static struct platform_driver platform_lcd_driver = {
#ifdef CONFIG_PM
.pm = &platform_lcd_pm_ops,
#endif
+ .of_match_table = of_match_ptr(platform_lcd_of_match),
},
.probe = platform_lcd_probe,
.remove = __devexit_p(platform_lcd_remove),
diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c
deleted file mode 100644
index 69b35f02929..00000000000
--- a/drivers/video/backlight/progear_bl.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Backlight Driver for Frontpath ProGear HX1050+
- *
- * Copyright (c) 2006 Marcin Juszkiewicz
- *
- * Based on Progear LCD driver by M Schacht
- * <mschacht at alumni dot washington dot edu>
- *
- * Based on Sharp's Corgi Backlight Driver
- * Based on Backlight Driver for HP Jornada 680
- *
- * 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.
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/mutex.h>
-#include <linux/fb.h>
-#include <linux/backlight.h>
-#include <linux/pci.h>
-
-#define PMU_LPCR 0xB0
-#define SB_MPS1 0x61
-#define HW_LEVEL_MAX 0x77
-#define HW_LEVEL_MIN 0x4f
-
-static struct pci_dev *pmu_dev = NULL;
-static struct pci_dev *sb_dev = NULL;
-
-static int progearbl_set_intensity(struct backlight_device *bd)
-{
- int intensity = bd->props.brightness;
-
- if (bd->props.power != FB_BLANK_UNBLANK)
- intensity = 0;
- if (bd->props.fb_blank != FB_BLANK_UNBLANK)
- intensity = 0;
-
- pci_write_config_byte(pmu_dev, PMU_LPCR, intensity + HW_LEVEL_MIN);
-
- return 0;
-}
-
-static int progearbl_get_intensity(struct backlight_device *bd)
-{
- u8 intensity;
- pci_read_config_byte(pmu_dev, PMU_LPCR, &intensity);
-
- return intensity - HW_LEVEL_MIN;
-}
-
-static const struct backlight_ops progearbl_ops = {
- .get_brightness = progearbl_get_intensity,
- .update_status = progearbl_set_intensity,
-};
-
-static int progearbl_probe(struct platform_device *pdev)
-{
- struct backlight_properties props;
- u8 temp;
- struct backlight_device *progear_backlight_device;
- int ret;
-
- pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL);
- if (!pmu_dev) {
- pr_err("ALI M7101 PMU not found.\n");
- return -ENODEV;
- }
-
- sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
- if (!sb_dev) {
- pr_err("ALI 1533 SB not found.\n");
- ret = -ENODEV;
- goto put_pmu;
- }
-
- /* Set SB_MPS1 to enable brightness control. */
- pci_read_config_byte(sb_dev, SB_MPS1, &temp);
- pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20);
-
- memset(&props, 0, sizeof(struct backlight_properties));
- props.type = BACKLIGHT_RAW;
- props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
- progear_backlight_device = backlight_device_register("progear-bl",
- &pdev->dev, NULL,
- &progearbl_ops,
- &props);
- if (IS_ERR(progear_backlight_device)) {
- ret = PTR_ERR(progear_backlight_device);
- goto put_sb;
- }
-
- platform_set_drvdata(pdev, progear_backlight_device);
-
- progear_backlight_device->props.power = FB_BLANK_UNBLANK;
- progear_backlight_device->props.brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
- progearbl_set_intensity(progear_backlight_device);
-
- return 0;
-put_sb:
- pci_dev_put(sb_dev);
-put_pmu:
- pci_dev_put(pmu_dev);
- return ret;
-}
-
-static int progearbl_remove(struct platform_device *pdev)
-{
- struct backlight_device *bd = platform_get_drvdata(pdev);
- backlight_device_unregister(bd);
-
- return 0;
-}
-
-static struct platform_driver progearbl_driver = {
- .probe = progearbl_probe,
- .remove = progearbl_remove,
- .driver = {
- .name = "progear-bl",
- },
-};
-
-static struct platform_device *progearbl_device;
-
-static int __init progearbl_init(void)
-{
- int ret = platform_driver_register(&progearbl_driver);
-
- if (ret)
- return ret;
- progearbl_device = platform_device_register_simple("progear-bl", -1,
- NULL, 0);
- if (IS_ERR(progearbl_device)) {
- platform_driver_unregister(&progearbl_driver);
- return PTR_ERR(progearbl_device);
- }
-
- return 0;
-}
-
-static void __exit progearbl_exit(void)
-{
- pci_dev_put(pmu_dev);
- pci_dev_put(sb_dev);
-
- platform_device_unregister(progearbl_device);
- platform_driver_unregister(&progearbl_driver);
-}
-
-module_init(progearbl_init);
-module_exit(progearbl_exit);
-
-MODULE_AUTHOR("Marcin Juszkiewicz <linux@hrw.one.pl>");
-MODULE_DESCRIPTION("ProGear Backlight Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/tps65217_bl.c b/drivers/video/backlight/tps65217_bl.c
new file mode 100644
index 00000000000..70881633b45
--- /dev/null
+++ b/drivers/video/backlight/tps65217_bl.c
@@ -0,0 +1,342 @@
+/*
+ * tps65217_bl.c
+ *
+ * TPS65217 backlight driver
+ *
+ * Copyright (C) 2012 Matthias Kaehlcke
+ * Author: Matthias Kaehlcke <matthias@kaehlcke.net>
+ *
+ * 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/mfd/tps65217.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+struct tps65217_bl {
+ struct tps65217 *tps;
+ struct device *dev;
+ struct backlight_device *bl;
+ bool is_enabled;
+};
+
+static int tps65217_bl_enable(struct tps65217_bl *tps65217_bl)
+{
+ int rc;
+
+ rc = tps65217_set_bits(tps65217_bl->tps, TPS65217_REG_WLEDCTRL1,
+ TPS65217_WLEDCTRL1_ISINK_ENABLE,
+ TPS65217_WLEDCTRL1_ISINK_ENABLE, TPS65217_PROTECT_NONE);
+ if (rc) {
+ dev_err(tps65217_bl->dev,
+ "failed to enable backlight: %d\n", rc);
+ return rc;
+ }
+
+ tps65217_bl->is_enabled = true;
+
+ dev_dbg(tps65217_bl->dev, "backlight enabled\n");
+
+ return 0;
+}
+
+static int tps65217_bl_disable(struct tps65217_bl *tps65217_bl)
+{
+ int rc;
+
+ rc = tps65217_clear_bits(tps65217_bl->tps,
+ TPS65217_REG_WLEDCTRL1,
+ TPS65217_WLEDCTRL1_ISINK_ENABLE,
+ TPS65217_PROTECT_NONE);
+ if (rc) {
+ dev_err(tps65217_bl->dev,
+ "failed to disable backlight: %d\n", rc);
+ return rc;
+ }
+
+ tps65217_bl->is_enabled = false;
+
+ dev_dbg(tps65217_bl->dev, "backlight disabled\n");
+
+ return 0;
+}
+
+static int tps65217_bl_update_status(struct backlight_device *bl)
+{
+ struct tps65217_bl *tps65217_bl = bl_get_data(bl);
+ int rc;
+ int brightness = bl->props.brightness;
+
+ if (bl->props.state & BL_CORE_SUSPENDED)
+ brightness = 0;
+
+ if ((bl->props.power != FB_BLANK_UNBLANK) ||
+ (bl->props.fb_blank != FB_BLANK_UNBLANK))
+ /* framebuffer in low power mode or blanking active */
+ brightness = 0;
+
+ if (brightness > 0) {
+ rc = tps65217_reg_write(tps65217_bl->tps,
+ TPS65217_REG_WLEDCTRL2,
+ brightness - 1,
+ TPS65217_PROTECT_NONE);
+ if (rc) {
+ dev_err(tps65217_bl->dev,
+ "failed to set brightness level: %d\n", rc);
+ return rc;
+ }
+
+ dev_dbg(tps65217_bl->dev, "brightness set to %d\n", brightness);
+
+ if (!tps65217_bl->is_enabled)
+ rc = tps65217_bl_enable(tps65217_bl);
+ } else {
+ rc = tps65217_bl_disable(tps65217_bl);
+ }
+
+ return rc;
+}
+
+static int tps65217_bl_get_brightness(struct backlight_device *bl)
+{
+ return bl->props.brightness;
+}
+
+static const struct backlight_ops tps65217_bl_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = tps65217_bl_update_status,
+ .get_brightness = tps65217_bl_get_brightness
+};
+
+static int tps65217_bl_hw_init(struct tps65217_bl *tps65217_bl,
+ struct tps65217_bl_pdata *pdata)
+{
+ int rc;
+
+ rc = tps65217_bl_disable(tps65217_bl);
+ if (rc)
+ return rc;
+
+ switch (pdata->isel) {
+ case TPS65217_BL_ISET1:
+ /* select ISET_1 current level */
+ rc = tps65217_clear_bits(tps65217_bl->tps,
+ TPS65217_REG_WLEDCTRL1,
+ TPS65217_WLEDCTRL1_ISEL,
+ TPS65217_PROTECT_NONE);
+ if (rc) {
+ dev_err(tps65217_bl->dev,
+ "failed to select ISET1 current level: %d)\n",
+ rc);
+ return rc;
+ }
+
+ dev_dbg(tps65217_bl->dev, "selected ISET1 current level\n");
+
+ break;
+
+ case TPS65217_BL_ISET2:
+ /* select ISET2 current level */
+ rc = tps65217_set_bits(tps65217_bl->tps, TPS65217_REG_WLEDCTRL1,
+ TPS65217_WLEDCTRL1_ISEL,
+ TPS65217_WLEDCTRL1_ISEL, TPS65217_PROTECT_NONE);
+ if (rc) {
+ dev_err(tps65217_bl->dev,
+ "failed to select ISET2 current level: %d\n",
+ rc);
+ return rc;
+ }
+
+ dev_dbg(tps65217_bl->dev, "selected ISET2 current level\n");
+
+ break;
+
+ default:
+ dev_err(tps65217_bl->dev,
+ "invalid value for current level: %d\n", pdata->isel);
+ return -EINVAL;
+ }
+
+ /* set PWM frequency */
+ rc = tps65217_set_bits(tps65217_bl->tps,
+ TPS65217_REG_WLEDCTRL1,
+ TPS65217_WLEDCTRL1_FDIM_MASK,
+ pdata->fdim,
+ TPS65217_PROTECT_NONE);
+ if (rc) {
+ dev_err(tps65217_bl->dev,
+ "failed to select PWM dimming frequency: %d\n",
+ rc);
+ return rc;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static struct tps65217_bl_pdata *
+tps65217_bl_parse_dt(struct platform_device *pdev)
+{
+ struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
+ struct device_node *node = of_node_get(tps->dev->of_node);
+ struct tps65217_bl_pdata *pdata, *err;
+ u32 val;
+
+ node = of_find_node_by_name(node, "backlight");
+ if (!node)
+ return ERR_PTR(-ENODEV);
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(&pdev->dev, "failed to allocate platform data\n");
+ err = ERR_PTR(-ENOMEM);
+ goto err;
+ }
+
+ pdata->isel = TPS65217_BL_ISET1;
+ if (!of_property_read_u32(node, "isel", &val)) {
+ if (val < TPS65217_BL_ISET1 ||
+ val > TPS65217_BL_ISET2) {
+ dev_err(&pdev->dev,
+ "invalid 'isel' value in the device tree\n");
+ err = ERR_PTR(-EINVAL);
+ goto err;
+ }
+
+ pdata->isel = val;
+ }
+
+ pdata->fdim = TPS65217_BL_FDIM_200HZ;
+ if (!of_property_read_u32(node, "fdim", &val)) {
+ switch (val) {
+ case 100:
+ pdata->fdim = TPS65217_BL_FDIM_100HZ;
+ break;
+
+ case 200:
+ pdata->fdim = TPS65217_BL_FDIM_200HZ;
+ break;
+
+ case 500:
+ pdata->fdim = TPS65217_BL_FDIM_500HZ;
+ break;
+
+ case 1000:
+ pdata->fdim = TPS65217_BL_FDIM_1000HZ;
+ break;
+
+ default:
+ dev_err(&pdev->dev,
+ "invalid 'fdim' value in the device tree\n");
+ err = ERR_PTR(-EINVAL);
+ goto err;
+ }
+ }
+
+ of_node_put(node);
+
+ return pdata;
+
+err:
+ of_node_put(node);
+
+ return err;
+}
+#else
+static struct tps65217_bl_pdata *
+tps65217_bl_parse_dt(struct platform_device *pdev)
+{
+ return NULL;
+}
+#endif
+
+static int tps65217_bl_probe(struct platform_device *pdev)
+{
+ int rc;
+ struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
+ struct tps65217_bl *tps65217_bl;
+ struct tps65217_bl_pdata *pdata;
+ struct backlight_properties bl_props;
+
+ if (tps->dev->of_node) {
+ pdata = tps65217_bl_parse_dt(pdev);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+ } else {
+ if (!pdev->dev.platform_data) {
+ dev_err(&pdev->dev, "no platform data provided\n");
+ return -EINVAL;
+ }
+
+ pdata = pdev->dev.platform_data;
+ }
+
+ tps65217_bl = devm_kzalloc(&pdev->dev, sizeof(*tps65217_bl),
+ GFP_KERNEL);
+ if (tps65217_bl == NULL) {
+ dev_err(&pdev->dev, "allocation of struct tps65217_bl failed\n");
+ return -ENOMEM;
+ }
+
+ tps65217_bl->tps = tps;
+ tps65217_bl->dev = &pdev->dev;
+ tps65217_bl->is_enabled = false;
+
+ rc = tps65217_bl_hw_init(tps65217_bl, pdata);
+ if (rc)
+ return rc;
+
+ memset(&bl_props, 0, sizeof(struct backlight_properties));
+ bl_props.type = BACKLIGHT_RAW;
+ bl_props.max_brightness = 100;
+
+ tps65217_bl->bl = backlight_device_register(pdev->name,
+ tps65217_bl->dev, tps65217_bl,
+ &tps65217_bl_ops, &bl_props);
+ if (IS_ERR(tps65217_bl->bl)) {
+ dev_err(tps65217_bl->dev,
+ "registration of backlight device failed: %d\n", rc);
+ return PTR_ERR(tps65217_bl->bl);
+ }
+
+ tps65217_bl->bl->props.brightness = 0;
+ platform_set_drvdata(pdev, tps65217_bl);
+
+ return 0;
+}
+
+static int tps65217_bl_remove(struct platform_device *pdev)
+{
+ struct tps65217_bl *tps65217_bl = platform_get_drvdata(pdev);
+
+ backlight_device_unregister(tps65217_bl->bl);
+
+ return 0;
+}
+
+static struct platform_driver tps65217_bl_driver = {
+ .probe = tps65217_bl_probe,
+ .remove = tps65217_bl_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "tps65217-bl",
+ },
+};
+
+module_platform_driver(tps65217_bl_driver);
+
+MODULE_DESCRIPTION("TPS65217 Backlight driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Matthias Kaehlcke <matthias@kaehlcke.net>");
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 28b1a834906..61b182bf32a 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -162,7 +162,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,
image.depth = 1;
if (attribute) {
- buf = kmalloc(cellsize, GFP_KERNEL);
+ buf = kmalloc(cellsize, GFP_ATOMIC);
if (!buf)
return;
}
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 2e471c22abf..fdefa8fd72c 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -372,8 +372,15 @@ static void fb_flashcursor(struct work_struct *work)
struct vc_data *vc = NULL;
int c;
int mode;
+ int ret;
+
+ /* FIXME: we should sort out the unbind locking instead */
+ /* instead we just fail to flash the cursor if we can't get
+ * the lock instead of blocking fbcon deinit */
+ ret = console_trylock();
+ if (ret == 0)
+ return;
- console_lock();
if (ops && ops->currcon != -1)
vc = vc_cons[ops->currcon].d;
@@ -442,7 +449,7 @@ static int __init fb_console_setup(char *this_opt)
while ((options = strsep(&this_opt, ",")) != NULL) {
if (!strncmp(options, "font:", 5))
- strcpy(fontname, options + 5);
+ strlcpy(fontname, options + 5, sizeof(fontname));
if (!strncmp(options, "scrollback:", 11)) {
options += 11;
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 7ae9d53f2bf..113d43a16f5 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -131,7 +131,7 @@
#define UPPER_MARGIN 32
#define LOWER_MARGIN 32
-static resource_size_t da8xx_fb_reg_base;
+static void __iomem *da8xx_fb_reg_base;
static struct resource *lcdc_regs;
static unsigned int lcd_revision;
static irq_handler_t lcdc_irq_handler;
@@ -951,7 +951,7 @@ static int __devexit fb_remove(struct platform_device *dev)
clk_disable(par->lcdc_clk);
clk_put(par->lcdc_clk);
framebuffer_release(info);
- iounmap((void __iomem *)da8xx_fb_reg_base);
+ iounmap(da8xx_fb_reg_base);
release_mem_region(lcdc_regs->start, resource_size(lcdc_regs));
}
@@ -1171,7 +1171,7 @@ static int __devinit fb_probe(struct platform_device *device)
if (!lcdc_regs)
return -EBUSY;
- da8xx_fb_reg_base = (resource_size_t)ioremap(lcdc_regs->start, len);
+ da8xx_fb_reg_base = ioremap(lcdc_regs->start, len);
if (!da8xx_fb_reg_base) {
ret = -EBUSY;
goto err_request_mem;
@@ -1392,7 +1392,7 @@ err_clk_put:
clk_put(fb_clk);
err_ioremap:
- iounmap((void __iomem *)da8xx_fb_reg_base);
+ iounmap(da8xx_fb_reg_base);
err_request_mem:
release_mem_region(lcdc_regs->start, len);
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index b4a632ada40..932abaa58a8 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -553,7 +553,9 @@ static int __init efifb_init(void)
int ret;
char *option = NULL;
- dmi_check_system(dmi_system_table);
+ if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI ||
+ !(screen_info.capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS))
+ dmi_check_system(dmi_system_table);
if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
return -ENODEV;
diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c
index 345d9623097..f2c092da84b 100644
--- a/drivers/video/ep93xx-fb.c
+++ b/drivers/video/ep93xx-fb.c
@@ -24,7 +24,7 @@
#include <linux/clk.h>
#include <linux/fb.h>
-#include <mach/fb.h>
+#include <linux/platform_data/video-ep93xx.h>
/* Vertical Frame Timing Registers */
#define EP93XXFB_VLINES_TOTAL 0x0000 /* SW locked */
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
deleted file mode 100644
index 68b9b511ce8..00000000000
--- a/drivers/video/epson1355fb.c
+++ /dev/null
@@ -1,749 +0,0 @@
-/*
- * linux/drivers/video/epson1355fb.c -- Epson S1D13505 frame buffer for 2.5.
- *
- * Epson Research S1D13505 Embedded RAMDAC LCD/CRT Controller
- * (previously known as SED1355)
- *
- * Cf. http://vdc.epson.com/
- *
- *
- * Copyright (C) Hewlett-Packard Company. All rights reserved.
- *
- * Written by Christopher Hoover <ch@hpl.hp.com>
- *
- * Adapted from:
- *
- * linux/drivers/video/skeletonfb.c
- * Modified to new api Jan 2001 by James Simmons (jsimmons@infradead.org)
- * Created 28 Dec 1997 by Geert Uytterhoeven
- *
- * linux/drivers/video/epson1355fb.c (2.4 driver)
- * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- *
- *
- * Noteworthy Issues
- * -----------------
- *
- * This driver is complicated by the fact that this is a 16-bit chip
- * and, on at least one platform (ceiva), we can only do 16-bit reads
- * and writes to the framebuffer. We hide this from user space
- * except in the case of mmap().
- *
- *
- * To Do
- * -----
- *
- * - Test 8-bit pseudocolor mode
- * - Allow setting bpp, virtual resolution
- * - Implement horizontal panning
- * - (maybe) Implement hardware cursor
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-
-#include <asm/types.h>
-#include <asm/io.h>
-#include <linux/uaccess.h>
-
-#include <video/epson1355.h>
-
-struct epson1355_par {
- unsigned long reg_addr;
- u32 pseudo_palette[16];
-};
-
-/* ------------------------------------------------------------------------- */
-
-#if defined(CONFIG_ARM)
-
-# ifdef CONFIG_ARCH_CEIVA
-# include <mach/hardware.h>
-# define EPSON1355FB_BASE_PHYS (CEIVA_PHYS_SED1355)
-# endif
-
-static inline u8 epson1355_read_reg(struct epson1355_par *par, int index)
-{
- return __raw_readb(par->reg_addr + index);
-}
-
-static inline void epson1355_write_reg(struct epson1355_par *par, u8 data, int index)
-{
- __raw_writeb(data, par->reg_addr + index);
-}
-
-#else
-# error "no architecture-specific epson1355_{read,write}_reg"
-#endif
-
-#ifndef EPSON1355FB_BASE_PHYS
-# error "EPSON1355FB_BASE_PHYS is not defined"
-#endif
-
-#define EPSON1355FB_REGS_OFS (0)
-#define EPSON1355FB_REGS_PHYS (EPSON1355FB_BASE_PHYS + EPSON1355FB_REGS_OFS)
-#define EPSON1355FB_REGS_LEN (64)
-
-#define EPSON1355FB_FB_OFS (0x00200000)
-#define EPSON1355FB_FB_PHYS (EPSON1355FB_BASE_PHYS + EPSON1355FB_FB_OFS)
-#define EPSON1355FB_FB_LEN (2 * 1024 * 1024)
-
-/* ------------------------------------------------------------------------- */
-
-static inline u16 epson1355_read_reg16(struct epson1355_par *par, int index)
-{
- u8 lo = epson1355_read_reg(par, index);
- u8 hi = epson1355_read_reg(par, index + 1);
-
- return (hi << 8) | lo;
-}
-
-static inline void epson1355_write_reg16(struct epson1355_par *par, u16 data, int index)
-{
- u8 lo = data & 0xff;
- u8 hi = (data >> 8) & 0xff;
-
- epson1355_write_reg(par, lo, index);
- epson1355_write_reg(par, hi, index + 1);
-}
-
-static inline u32 epson1355_read_reg20(struct epson1355_par *par, int index)
-{
- u8 b0 = epson1355_read_reg(par, index);
- u8 b1 = epson1355_read_reg(par, index + 1);
- u8 b2 = epson1355_read_reg(par, index + 2);
-
- return (b2 & 0x0f) << 16 | (b1 << 8) | b0;
-}
-
-static inline void epson1355_write_reg20(struct epson1355_par *par, u32 data, int index)
-{
- u8 b0 = data & 0xff;
- u8 b1 = (data >> 8) & 0xff;
- u8 b2 = (data >> 16) & 0x0f;
-
- epson1355_write_reg(par, b0, index);
- epson1355_write_reg(par, b1, index + 1);
- epson1355_write_reg(par, b2, index + 2);
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void set_lut(struct epson1355_par *par, u8 index, u8 r, u8 g, u8 b)
-{
- epson1355_write_reg(par, index, REG_LUT_ADDR);
- epson1355_write_reg(par, r, REG_LUT_DATA);
- epson1355_write_reg(par, g, REG_LUT_DATA);
- epson1355_write_reg(par, b, REG_LUT_DATA);
-}
-
-
-/**
- * epson1355fb_setcolreg - sets a color register.
- * @regno: Which register in the CLUT we are programming
- * @red: The red value which can be up to 16 bits wide
- * @green: The green value which can be up to 16 bits wide
- * @blue: The blue value which can be up to 16 bits wide.
- * @transp: If supported the alpha value which can be up to 16 bits wide.
- * @info: frame buffer info structure
- *
- * Returns negative errno on error, or zero on success.
- */
-static int epson1355fb_setcolreg(unsigned regno, unsigned r, unsigned g,
- unsigned b, unsigned transp,
- struct fb_info *info)
-{
- struct epson1355_par *par = info->par;
-
- if (info->var.grayscale)
- r = g = b = (19595 * r + 38470 * g + 7471 * b) >> 16;
-
- switch (info->fix.visual) {
- case FB_VISUAL_TRUECOLOR:
- if (regno >= 16)
- return -EINVAL;
-
- ((u32 *) info->pseudo_palette)[regno] =
- (r & 0xf800) | (g & 0xfc00) >> 5 | (b & 0xf800) >> 11;
-
- break;
- case FB_VISUAL_PSEUDOCOLOR:
- if (regno >= 256)
- return -EINVAL;
-
- set_lut(par, regno, r >> 8, g >> 8, b >> 8);
-
- break;
- default:
- return -ENOSYS;
- }
- return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/**
- * epson1355fb_pan_display - Pans the display.
- * @var: frame buffer variable screen structure
- * @info: frame buffer structure that represents a single frame buffer
- *
- * Pan (or wrap, depending on the `vmode' field) the display using the
- * `xoffset' and `yoffset' fields of the `var' structure.
- * If the values don't fit, return -EINVAL.
- *
- * Returns negative errno on error, or zero on success.
- */
-static int epson1355fb_pan_display(struct fb_var_screeninfo *var,
- struct fb_info *info)
-{
- struct epson1355_par *par = info->par;
- u32 start;
-
- if (var->xoffset != 0) /* not yet ... */
- return -EINVAL;
-
- if (var->yoffset + info->var.yres > info->var.yres_virtual)
- return -EINVAL;
-
- start = (info->fix.line_length >> 1) * var->yoffset;
-
- epson1355_write_reg20(par, start, REG_SCRN1_DISP_START_ADDR0);
-
- return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void lcd_enable(struct epson1355_par *par, int enable)
-{
- u8 mode = epson1355_read_reg(par, REG_DISPLAY_MODE);
-
- if (enable)
- mode |= 1;
- else
- mode &= ~1;
-
- epson1355_write_reg(par, mode, REG_DISPLAY_MODE);
-}
-
-#if defined(CONFIG_ARCH_CEIVA)
-static void backlight_enable(int enable)
-{
- /* ### this should be protected by a spinlock ... */
- u8 pddr = clps_readb(PDDR);
- if (enable)
- pddr |= (1 << 5);
- else
- pddr &= ~(1 << 5);
- clps_writeb(pddr, PDDR);
-}
-#else
-static void backlight_enable(int enable)
-{
-}
-#endif
-
-
-/**
- * epson1355fb_blank - blanks the display.
- * @blank_mode: the blank mode we want.
- * @info: frame buffer structure that represents a single frame buffer
- *
- * Blank the screen if blank_mode != 0, else unblank. Return 0 if
- * blanking succeeded, != 0 if un-/blanking failed due to e.g. a
- * video mode which doesn't support it. Implements VESA suspend
- * and powerdown modes on hardware that supports disabling hsync/vsync:
- * blank_mode == 2: suspend vsync
- * blank_mode == 3: suspend hsync
- * blank_mode == 4: powerdown
- *
- * Returns negative errno on error, or zero on success.
- *
- */
-static int epson1355fb_blank(int blank_mode, struct fb_info *info)
-{
- struct epson1355_par *par = info->par;
-
- switch (blank_mode) {
- case FB_BLANK_UNBLANK:
- case FB_BLANK_NORMAL:
- lcd_enable(par, 1);
- backlight_enable(1);
- break;
- case FB_BLANK_VSYNC_SUSPEND:
- case FB_BLANK_HSYNC_SUSPEND:
- backlight_enable(0);
- break;
- case FB_BLANK_POWERDOWN:
- backlight_enable(0);
- lcd_enable(par, 0);
- break;
- default:
- return -EINVAL;
- }
-
- /* let fbcon do a soft blank for us */
- return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/*
- * We can't use the cfb generic routines, as we have to limit
- * ourselves to 16-bit or 8-bit loads and stores to this 16-bit
- * chip.
- */
-
-static inline void epson1355fb_fb_writel(unsigned long v, unsigned long *a)
-{
- u16 *p = (u16 *) a;
- u16 l = v & 0xffff;
- u16 h = v >> 16;
-
- fb_writew(l, p);
- fb_writew(h, p + 1);
-}
-
-static inline unsigned long epson1355fb_fb_readl(const unsigned long *a)
-{
- const u16 *p = (u16 *) a;
- u16 l = fb_readw(p);
- u16 h = fb_readw(p + 1);
-
- return (h << 16) | l;
-}
-
-#define FB_READL epson1355fb_fb_readl
-#define FB_WRITEL epson1355fb_fb_writel
-
-/* ------------------------------------------------------------------------- */
-
-static inline unsigned long copy_from_user16(void *to, const void *from,
- unsigned long n)
-{
- u16 *dst = (u16 *) to;
- u16 *src = (u16 *) from;
-
- if (!access_ok(VERIFY_READ, from, n))
- return n;
-
- while (n > 1) {
- u16 v;
- if (__get_user(v, src))
- return n;
-
- fb_writew(v, dst);
-
- src++, dst++;
- n -= 2;
- }
-
- if (n) {
- u8 v;
-
- if (__get_user(v, ((u8 *) src)))
- return n;
-
- fb_writeb(v, dst);
- }
- return 0;
-}
-
-static inline unsigned long copy_to_user16(void *to, const void *from,
- unsigned long n)
-{
- u16 *dst = (u16 *) to;
- u16 *src = (u16 *) from;
-
- if (!access_ok(VERIFY_WRITE, to, n))
- return n;
-
- while (n > 1) {
- u16 v = fb_readw(src);
-
- if (__put_user(v, dst))
- return n;
-
- src++, dst++;
- n -= 2;
- }
-
- if (n) {
- u8 v = fb_readb(src);
-
- if (__put_user(v, ((u8 *) dst)))
- return n;
- }
- return 0;
-}
-
-
-static ssize_t
-epson1355fb_read(struct fb_info *info, char *buf, size_t count, loff_t * ppos)
-{
- unsigned long p = *ppos;
-
- if (p >= info->fix.smem_len)
- return 0;
- if (count >= info->fix.smem_len)
- count = info->fix.smem_len;
- if (count + p > info->fix.smem_len)
- count = info->fix.smem_len - p;
-
- if (count) {
- char *base_addr;
-
- base_addr = info->screen_base;
- count -= copy_to_user16(buf, base_addr + p, count);
- if (!count)
- return -EFAULT;
- *ppos += count;
- }
- return count;
-}
-
-static ssize_t
-epson1355fb_write(struct fb_info *info, const char *buf,
- size_t count, loff_t * ppos)
-{
- unsigned long p = *ppos;
- int err;
-
- /* from fbmem.c except for our own copy_*_user */
- if (p > info->fix.smem_len)
- return -ENOSPC;
- if (count >= info->fix.smem_len)
- count = info->fix.smem_len;
- err = 0;
- if (count + p > info->fix.smem_len) {
- count = info->fix.smem_len - p;
- err = -ENOSPC;
- }
-
- if (count) {
- char *base_addr;
-
- base_addr = info->screen_base;
- count -= copy_from_user16(base_addr + p, buf, count);
- *ppos += count;
- err = -EFAULT;
- }
- if (count)
- return count;
- return err;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static struct fb_ops epson1355fb_fbops = {
- .owner = THIS_MODULE,
- .fb_setcolreg = epson1355fb_setcolreg,
- .fb_pan_display = epson1355fb_pan_display,
- .fb_blank = epson1355fb_blank,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_read = epson1355fb_read,
- .fb_write = epson1355fb_write,
-};
-
-/* ------------------------------------------------------------------------- */
-
-static __init unsigned int get_fb_size(struct fb_info *info)
-{
- unsigned int size = 2 * 1024 * 1024;
- char *p = info->screen_base;
-
- /* the 512k framebuffer is aliased at start + 0x80000 * n */
- fb_writeb(1, p);
- fb_writeb(0, p + 0x80000);
- if (!fb_readb(p))
- size = 512 * 1024;
-
- fb_writeb(0, p);
-
- return size;
-}
-
-static int epson1355_width_tab[2][4] __devinitdata =
- { {4, 8, 16, -1}, {9, 12, 16, -1} };
-static int epson1355_bpp_tab[8] __devinitdata = { 1, 2, 4, 8, 15, 16 };
-
-static void __devinit fetch_hw_state(struct fb_info *info, struct epson1355_par *par)
-{
- struct fb_var_screeninfo *var = &info->var;
- struct fb_fix_screeninfo *fix = &info->fix;
- u8 panel, display;
- u16 offset;
- u32 xres, yres;
- u32 xres_virtual, yres_virtual;
- int bpp, lcd_bpp;
- int is_color, is_dual, is_tft;
- int lcd_enabled, crt_enabled;
-
- fix->type = FB_TYPE_PACKED_PIXELS;
-
- display = epson1355_read_reg(par, REG_DISPLAY_MODE);
- bpp = epson1355_bpp_tab[(display >> 2) & 7];
-
- switch (bpp) {
- case 8:
- fix->visual = FB_VISUAL_PSEUDOCOLOR;
- var->bits_per_pixel = 8;
- var->red.offset = var->green.offset = var->blue.offset = 0;
- var->red.length = var->green.length = var->blue.length = 8;
- break;
- case 16:
- /* 5-6-5 RGB */
- fix->visual = FB_VISUAL_TRUECOLOR;
- 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;
- break;
- default:
- BUG();
- }
- fb_alloc_cmap(&(info->cmap), 256, 0);
-
- panel = epson1355_read_reg(par, REG_PANEL_TYPE);
- is_color = (panel & 0x04) != 0;
- is_dual = (panel & 0x02) != 0;
- is_tft = (panel & 0x01) != 0;
- crt_enabled = (display & 0x02) != 0;
- lcd_enabled = (display & 0x01) != 0;
- lcd_bpp = epson1355_width_tab[is_tft][(panel >> 4) & 3];
-
- xres = (epson1355_read_reg(par, REG_HORZ_DISP_WIDTH) + 1) * 8;
- yres = (epson1355_read_reg16(par, REG_VERT_DISP_HEIGHT0) + 1) *
- ((is_dual && !crt_enabled) ? 2 : 1);
- offset = epson1355_read_reg16(par, REG_MEM_ADDR_OFFSET0) & 0x7ff;
- xres_virtual = offset * 16 / bpp;
- yres_virtual = fix->smem_len / (offset * 2);
-
- var->xres = xres;
- var->yres = yres;
- var->xres_virtual = xres_virtual;
- var->yres_virtual = yres_virtual;
- var->xoffset = var->yoffset = 0;
-
- fix->line_length = offset * 2;
-
- fix->xpanstep = 0; /* no pan yet */
- fix->ypanstep = 1;
- fix->ywrapstep = 0;
- fix->accel = FB_ACCEL_NONE;
-
- var->grayscale = !is_color;
-
-#ifdef DEBUG
- printk(KERN_INFO
- "epson1355fb: xres=%d, yres=%d, "
- "is_color=%d, is_dual=%d, is_tft=%d\n",
- xres, yres, is_color, is_dual, is_tft);
- printk(KERN_INFO
- "epson1355fb: bpp=%d, lcd_bpp=%d, "
- "crt_enabled=%d, lcd_enabled=%d\n",
- bpp, lcd_bpp, crt_enabled, lcd_enabled);
-#endif
-}
-
-
-static void clearfb16(struct fb_info *info)
-{
- u16 *dst = (u16 *) info->screen_base;
- unsigned long n = info->fix.smem_len;
-
- while (n > 1) {
- fb_writew(0, dst);
- dst++, n -= 2;
- }
-
- if (n)
- fb_writeb(0, dst);
-}
-
-static int epson1355fb_remove(struct platform_device *dev)
-{
- struct fb_info *info = platform_get_drvdata(dev);
- struct epson1355_par *par = info->par;
-
- backlight_enable(0);
- if (par) {
- lcd_enable(par, 0);
- if (par && par->reg_addr)
- iounmap((void *) par->reg_addr);
- }
-
- if (info) {
- fb_dealloc_cmap(&info->cmap);
- if (info->screen_base)
- iounmap(info->screen_base);
- framebuffer_release(info);
- }
- release_mem_region(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN);
- release_mem_region(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN);
- return 0;
-}
-
-static int __devinit epson1355fb_probe(struct platform_device *dev)
-{
- struct epson1355_par *default_par;
- struct fb_info *info;
- u8 revision;
- int rc = 0;
-
- if (!request_mem_region(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN, "S1D13505 registers")) {
- printk(KERN_ERR "epson1355fb: unable to reserve "
- "registers at 0x%0x\n", EPSON1355FB_REGS_PHYS);
- rc = -EBUSY;
- goto bail;
- }
-
- if (!request_mem_region(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN,
- "S1D13505 framebuffer")) {
- printk(KERN_ERR "epson1355fb: unable to reserve "
- "framebuffer at 0x%0x\n", EPSON1355FB_FB_PHYS);
- rc = -EBUSY;
- goto bail;
- }
-
- info = framebuffer_alloc(sizeof(struct epson1355_par), &dev->dev);
- if (!info) {
- rc = -ENOMEM;
- goto bail;
- }
-
- default_par = info->par;
- default_par->reg_addr = (unsigned long) ioremap(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN);
- if (!default_par->reg_addr) {
- printk(KERN_ERR "epson1355fb: unable to map registers\n");
- rc = -ENOMEM;
- goto bail;
- }
- info->pseudo_palette = default_par->pseudo_palette;
-
- info->screen_base = ioremap(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN);
- if (!info->screen_base) {
- printk(KERN_ERR "epson1355fb: unable to map framebuffer\n");
- rc = -ENOMEM;
- goto bail;
- }
-
- revision = epson1355_read_reg(default_par, REG_REVISION_CODE);
- if ((revision >> 2) != 3) {
- printk(KERN_INFO "epson1355fb: epson1355 not found\n");
- rc = -ENODEV;
- goto bail;
- }
-
- info->fix.mmio_start = EPSON1355FB_REGS_PHYS;
- info->fix.mmio_len = EPSON1355FB_REGS_LEN;
- info->fix.smem_start = EPSON1355FB_FB_PHYS;
- info->fix.smem_len = get_fb_size(info);
-
- printk(KERN_INFO "epson1355fb: regs mapped at 0x%lx, fb %d KiB mapped at 0x%p\n",
- default_par->reg_addr, info->fix.smem_len / 1024, info->screen_base);
-
- strcpy(info->fix.id, "S1D13505");
- info->par = default_par;
- info->fbops = &epson1355fb_fbops;
- info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
-
- /* we expect the boot loader to have initialized the chip
- with appropriate parameters from which we can determinte
- the flavor of lcd panel attached */
- fetch_hw_state(info, default_par);
-
- /* turn this puppy on ... */
- clearfb16(info);
- backlight_enable(1);
- lcd_enable(default_par, 1);
-
- if (register_framebuffer(info) < 0) {
- rc = -EINVAL;
- goto bail;
- }
- /*
- * Our driver data.
- */
- platform_set_drvdata(dev, info);
-
- printk(KERN_INFO "fb%d: %s frame buffer device\n",
- info->node, info->fix.id);
-
- return 0;
-
- bail:
- epson1355fb_remove(dev);
- return rc;
-}
-
-static struct platform_driver epson1355fb_driver = {
- .probe = epson1355fb_probe,
- .remove = epson1355fb_remove,
- .driver = {
- .name = "epson1355fb",
- },
-};
-
-static struct platform_device *epson1355fb_device;
-
-int __init epson1355fb_init(void)
-{
- int ret = 0;
-
- if (fb_get_options("epson1355fb", NULL))
- return -ENODEV;
-
- ret = platform_driver_register(&epson1355fb_driver);
-
- if (!ret) {
- epson1355fb_device = platform_device_alloc("epson1355fb", 0);
-
- if (epson1355fb_device)
- ret = platform_device_add(epson1355fb_device);
- else
- ret = -ENOMEM;
-
- if (ret) {
- platform_device_put(epson1355fb_device);
- platform_driver_unregister(&epson1355fb_driver);
- }
- }
-
- return ret;
-}
-
-module_init(epson1355fb_init);
-
-#ifdef MODULE
-static void __exit epson1355fb_exit(void)
-{
- platform_device_unregister(epson1355fb_device);
- platform_driver_unregister(&epson1355fb_driver);
-}
-
-/* ------------------------------------------------------------------------- */
-
-module_exit(epson1355fb_exit);
-#endif
-
-MODULE_AUTHOR("Christopher Hoover <ch@hpl.hp.com>");
-MODULE_DESCRIPTION("Framebuffer driver for Epson S1D13505");
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
index 4bc2b8a5dd8..663c308d0e7 100644
--- a/drivers/video/exynos/exynos_mipi_dsi.c
+++ b/drivers/video/exynos/exynos_mipi_dsi.c
@@ -461,7 +461,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
done:
platform_set_drvdata(pdev, dsim);
- dev_dbg(&pdev->dev, "%s() completed sucessfuly (%s mode)\n", __func__,
+ dev_dbg(&pdev->dev, "%s() completed successfully (%s mode)\n", __func__,
dsim_config->e_interface == DSIM_COMMAND ? "CPU" : "RGB");
return 0;
diff --git a/drivers/video/fb-puv3.c b/drivers/video/fb-puv3.c
index 60a787fa32c..7d106f1f490 100644
--- a/drivers/video/fb-puv3.c
+++ b/drivers/video/fb-puv3.c
@@ -653,9 +653,8 @@ int unifb_mmap(struct fb_info *info,
vma->vm_page_prot))
return -EAGAIN;
- vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
+ /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
return 0;
-
}
static struct fb_ops unifb_ops = {
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 64cda560c48..88cad6b8b47 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -166,7 +166,7 @@ static const struct address_space_operations fb_deferred_io_aops = {
static int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
vma->vm_ops = &fb_deferred_io_vm_ops;
- vma->vm_flags |= ( VM_RESERVED | VM_DONTEXPAND );
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
if (!(info->flags & FBINFO_VIRTFB))
vma->vm_flags |= VM_IO;
vma->vm_private_data = info;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 0dff12a1dae..3ff0105a496 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1410,8 +1410,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
return -EINVAL;
off += start;
vma->vm_pgoff = off >> PAGE_SHIFT;
- /* This is an IO map - tell maydump to skip this VMA */
- vma->vm_flags |= VM_IO | VM_RESERVED;
+ /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by io_remap_pfn_range()*/
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
fb_pgprotect(file, vma, off);
if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index 7e7b7a9ba27..05e2a8a99d8 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -1024,7 +1024,7 @@ static int gbefb_mmap(struct fb_info *info,
pgprot_val(vma->vm_page_prot) =
pgprot_fb(pgprot_val(vma->vm_page_prot));
- vma->vm_flags |= VM_IO | VM_RESERVED;
+ /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
/* look for the starting tile */
tile = &gbe_tiles.cpu[offset >> TILE_SHIFT];
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c
index 5a5d0928df3..265c5ed59ad 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 __devinitdata gx1_modedb[] = {
+static const struct fb_videomode __devinitconst gx1_modedb[] = {
/* 640x480-60 VESA */
{ NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2,
0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
diff --git a/drivers/video/gxt4500.c b/drivers/video/gxt4500.c
index 0fad23f810a..0e9afa41d16 100644
--- a/drivers/video/gxt4500.c
+++ b/drivers/video/gxt4500.c
@@ -156,7 +156,7 @@ struct gxt4500_par {
static char *mode_option;
/* default mode: 1280x1024 @ 60 Hz, 8 bpp */
-static const struct fb_videomode defaultmode __devinitdata = {
+static const struct fb_videomode defaultmode __devinitconst = {
.refresh = 60,
.xres = 1280,
.yres = 1024,
@@ -581,7 +581,7 @@ static int gxt4500_blank(int blank, struct fb_info *info)
return 0;
}
-static const struct fb_fix_screeninfo gxt4500_fix __devinitdata = {
+static const struct fb_fix_screeninfo gxt4500_fix __devinitconst = {
.id = "IBM GXT4500P",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index b83f36190ca..5c067816a81 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -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 *i810_pci_list[] __devinitdata = {
+static const char * const i810_pci_list[] __devinitconst = {
"Intel(R) 810 Framebuffer Device" ,
"Intel(R) 810-DC100 Framebuffer Device" ,
"Intel(R) 810E Framebuffer Device" ,
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index caad3689b4e..53ffdfc82a7 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -32,7 +32,7 @@
#include <linux/io.h>
#include <linux/math64.h>
-#include <mach/imxfb.h>
+#include <linux/platform_data/video-imxfb.h>
#include <mach/hardware.h>
/*
diff --git a/drivers/video/jz4740_fb.c b/drivers/video/jz4740_fb.c
index de366937c93..3c63fc24bb1 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 __devinitdata = {
+static const struct fb_fix_screeninfo jzfb_fix __devinitconst = {
.id = "JZ4740 FB",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_TRUECOLOR,
diff --git a/drivers/video/mb862xx/mb862xxfbdrv.c b/drivers/video/mb862xx/mb862xxfbdrv.c
index 00ce1f34b49..57d940be5f3 100644
--- a/drivers/video/mb862xx/mb862xxfbdrv.c
+++ b/drivers/video/mb862xx/mb862xxfbdrv.c
@@ -328,6 +328,8 @@ static int mb862xxfb_ioctl(struct fb_info *fbi, unsigned int cmd,
case MB862XX_L1_SET_CFG:
if (copy_from_user(l1_cfg, argp, sizeof(*l1_cfg)))
return -EFAULT;
+ if (l1_cfg->dh == 0 || l1_cfg->dw == 0)
+ return -EINVAL;
if ((l1_cfg->sw >= l1_cfg->dw) && (l1_cfg->sh >= l1_cfg->dh)) {
/* downscaling */
outreg(cap, GC_CAP_CSC,
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index b061d709bc4..bf73f048006 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -29,7 +29,7 @@
#include <mach/msm_iomap.h>
#include <mach/irqs.h>
#include <mach/board.h>
-#include <mach/msm_fb.h>
+#include <linux/platform_data/video-msm_fb.h>
#include "mddi_hw.h"
#define FLAG_DISABLE_HIBERNATION 0x0001
diff --git a/drivers/video/msm/mddi_client_dummy.c b/drivers/video/msm/mddi_client_dummy.c
index d2a091cebe2..f1b0dfcc971 100644
--- a/drivers/video/msm/mddi_client_dummy.c
+++ b/drivers/video/msm/mddi_client_dummy.c
@@ -20,7 +20,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
-#include <mach/msm_fb.h>
+#include <linux/platform_data/video-msm_fb.h>
struct panel_info {
struct platform_device pdev;
diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c
index 7fcd67e132b..d7a5bf84fb2 100644
--- a/drivers/video/msm/mddi_client_nt35399.c
+++ b/drivers/video/msm/mddi_client_nt35399.c
@@ -22,7 +22,7 @@
#include <linux/sched.h>
#include <linux/gpio.h>
#include <linux/slab.h>
-#include <mach/msm_fb.h>
+#include <linux/platform_data/video-msm_fb.h>
static DECLARE_WAIT_QUEUE_HEAD(nt35399_vsync_wait);
diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/msm/mddi_client_toshiba.c
index 053eb687733..061d7dfebbf 100644
--- a/drivers/video/msm/mddi_client_toshiba.c
+++ b/drivers/video/msm/mddi_client_toshiba.c
@@ -22,7 +22,7 @@
#include <linux/gpio.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <mach/msm_fb.h>
+#include <linux/platform_data/video-msm_fb.h>
#define LCD_CONTROL_BLOCK_BASE 0x110000
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index cb2ddf164c9..2e0f3bab611 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -26,7 +26,7 @@
#include <linux/slab.h>
#include <mach/msm_iomap.h>
-#include <mach/msm_fb.h>
+#include <linux/platform_data/video-msm_fb.h>
#include <linux/platform_device.h>
#include <linux/export.h>
@@ -257,19 +257,17 @@ int get_img(struct mdp_img *img, struct fb_info *info,
unsigned long *start, unsigned long *len,
struct file **filep)
{
- int put_needed, ret = 0;
- struct file *file;
-
- file = fget_light(img->memory_id, &put_needed);
- if (file == NULL)
+ int ret = 0;
+ struct fd f = fdget(img->memory_id);
+ if (f.file == NULL)
return -1;
- if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
+ if (MAJOR(f.file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
*start = info->fix.smem_start;
*len = info->fix.smem_len;
} else
ret = -1;
- fput_light(file, put_needed);
+ fdput(f);
return ret;
}
diff --git a/drivers/video/msm/mdp_hw.h b/drivers/video/msm/mdp_hw.h
index d80477415ca..a0bacf581b3 100644
--- a/drivers/video/msm/mdp_hw.h
+++ b/drivers/video/msm/mdp_hw.h
@@ -16,7 +16,7 @@
#define _MDP_HW_H_
#include <mach/msm_iomap.h>
-#include <mach/msm_fb.h>
+#include <linux/platform_data/video-msm_fb.h>
struct mdp_info {
struct mdp_device mdp_dev;
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c
index 2b6564e8bfe..be6079cdfbb 100644
--- a/drivers/video/msm/mdp_ppp.c
+++ b/drivers/video/msm/mdp_ppp.c
@@ -16,7 +16,7 @@
#include <linux/file.h>
#include <linux/delay.h>
#include <linux/msm_mdp.h>
-#include <mach/msm_fb.h>
+#include <linux/platform_data/video-msm_fb.h>
#include "mdp_hw.h"
#include "mdp_scale_tables.h"
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index c6e3b4fcdd6..ec08a9ec377 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -25,7 +25,7 @@
#include <linux/msm_mdp.h>
#include <linux/io.h>
#include <linux/uaccess.h>
-#include <mach/msm_fb.h>
+#include <linux/platform_data/video-msm_fb.h>
#include <mach/board.h>
#include <linux/workqueue.h>
#include <linux/clk.h>
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index c89f8a8d36d..d7381088a18 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/mx3fb.c
@@ -27,10 +27,10 @@
#include <linux/clk.h>
#include <linux/mutex.h>
-#include <mach/dma.h>
+#include <linux/platform_data/dma-imx.h>
#include <mach/hardware.h>
#include <mach/ipu.h>
-#include <mach/mx3fb.h>
+#include <linux/platform_data/video-mx3fb.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/video/nuc900fb.c b/drivers/video/nuc900fb.c
index e10f551ade2..93387555337 100644
--- a/drivers/video/nuc900fb.c
+++ b/drivers/video/nuc900fb.c
@@ -38,7 +38,7 @@
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-ldm.h>
-#include <mach/fb.h>
+#include <linux/platform_data/video-nuc900fb.h>
#include "nuc900fb.h"
diff --git a/drivers/video/nuc900fb.h b/drivers/video/nuc900fb.h
index bc7c9300f27..9a1ca6dbb6b 100644
--- a/drivers/video/nuc900fb.h
+++ b/drivers/video/nuc900fb.h
@@ -16,7 +16,7 @@
#define __NUC900FB_H
#include <mach/map.h>
-#include <mach/fb.h>
+#include <linux/platform_data/video-nuc900fb.h>
enum nuc900_lcddrv_type {
LCDDRV_NUC910,
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c
index d3a31132722..ed4cad87fbc 100644
--- a/drivers/video/omap/lcd_ams_delta.c
+++ b/drivers/video/omap/lcd_ams_delta.c
@@ -27,8 +27,7 @@
#include <linux/lcd.h>
#include <linux/gpio.h>
-#include <plat/board-ams-delta.h>
-#include <mach/hardware.h>
+#include <mach/board-ams-delta.h>
#include "omapfb.h"
diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/omap/lcd_mipid.c
index e3880c4a0bb..b739600c51a 100644
--- a/drivers/video/omap/lcd_mipid.c
+++ b/drivers/video/omap/lcd_mipid.c
@@ -25,7 +25,7 @@
#include <linux/spi/spi.h>
#include <linux/module.h>
-#include <plat/lcd_mipid.h>
+#include <linux/platform_data/lcd-mipid.h>
#include "omapfb.h"
diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c
index 5914220dfa9..3aa62da8919 100644
--- a/drivers/video/omap/lcd_osk.c
+++ b/drivers/video/omap/lcd_osk.c
@@ -24,7 +24,7 @@
#include <linux/platform_device.h>
#include <asm/gpio.h>
-#include <plat/mux.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/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 3f5acc7771d..6b5e6e0e202 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -906,7 +906,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
r = -ENOMEM;
goto err_wq;
}
- INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
+ INIT_DEFERRABLE_WORK(&td->esd_work, taal_esd_work);
INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
dev_set_drvdata(&dssdev->dev, td);
@@ -962,8 +962,8 @@ static int taal_probe(struct omap_dss_device *dssdev)
goto err_irq;
}
- INIT_DELAYED_WORK_DEFERRABLE(&td->te_timeout_work,
- taal_te_timeout_work_callback);
+ INIT_DEFERRABLE_WORK(&td->te_timeout_work,
+ taal_te_timeout_work_callback);
dev_dbg(&dssdev->dev, "Using GPIO TE\n");
}
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 5b289c5f695..ee9e29639dc 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -37,6 +37,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <plat/cpu.h>
#include <plat/clock.h>
#include <video/omapdss.h>
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index b07e8864f82..05ee04667af 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4306,7 +4306,7 @@ static void dsi_framedone_irq_callback(void *data, u32 mask)
* and is sending the data.
*/
- __cancel_delayed_work(&dsi->framedone_timeout_work);
+ cancel_delayed_work(&dsi->framedone_timeout_work);
dsi_handle_framedone(dsidev, 0);
}
@@ -4863,8 +4863,8 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
mutex_init(&dsi->lock);
sema_init(&dsi->bus_lock, 1);
- INIT_DELAYED_WORK_DEFERRABLE(&dsi->framedone_timeout_work,
- dsi_framedone_timeout_work_callback);
+ INIT_DEFERRABLE_WORK(&dsi->framedone_timeout_work,
+ dsi_framedone_timeout_work_callback);
#ifdef DSI_CATCH_MISSING_TE
init_timer(&dsi->te_timer);
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 5d31699fbd3..f43bfe17b3b 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -105,6 +105,20 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
sdi_config_lcd_manager(dssdev);
+ /*
+ * LCLK and PCLK divisors are located in shadow registers, and we
+ * normally write them to DISPC registers when enabling the output.
+ * However, SDI uses pck-free as source clock for its PLL, and pck-free
+ * is affected by the divisors. And as we need the PLL before enabling
+ * the output, we need to write the divisors early.
+ *
+ * It seems just writing to the DISPC register is enough, and we don't
+ * need to care about the shadow register mechanism for pck-free. The
+ * exact reason for this is unknown.
+ */
+ dispc_mgr_set_clock_div(dssdev->manager->id,
+ &sdi.mgr_config.clock_info);
+
dss_sdi_init(dssdev->phy.sdi.datapairs);
r = dss_sdi_enable();
if (r)
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 08ec1a7103f..15373f4aee1 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -31,6 +31,7 @@
#include <linux/omapfb.h>
#include <video/omapdss.h>
+#include <plat/cpu.h>
#include <plat/vram.h>
#include <plat/vrfb.h>
@@ -1127,7 +1128,7 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
DBG("user mmap region start %lx, len %d, off %lx\n", start, len, off);
vma->vm_pgoff = off >> PAGE_SHIFT;
- vma->vm_flags |= VM_IO | VM_RESERVED;
+ /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
vma->vm_ops = &mmap_user_ops;
vma->vm_private_data = rg;
@@ -1192,7 +1193,7 @@ static int _setcolreg(struct fb_info *fbi, u_int regno, u_int red, u_int green,
break;
if (regno < 16) {
- u16 pal;
+ u32 pal;
pal = ((red >> (16 - var->red.length)) <<
var->red.offset) |
((green >> (16 - var->green.length)) <<
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 213fbbcf613..4e292f29bf5 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -31,7 +31,6 @@
#include <linux/fb.h>
#include <linux/init.h>
-#include <asm/abs_addr.h>
#include <asm/cell-regs.h>
#include <asm/lv1call.h>
#include <asm/ps3av.h>
@@ -1141,7 +1140,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
*/
fb_start = ps3fb_videomemory.address + GPU_FB_START;
info->screen_base = (char __force __iomem *)fb_start;
- info->fix.smem_start = virt_to_abs(fb_start);
+ info->fix.smem_start = __pa(fb_start);
info->fix.smem_len = ps3fb_videomemory.size - GPU_FB_START;
info->pseudo_palette = par->pseudo_palette;
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 3f902557690..4fa2ad43fd9 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -61,7 +61,7 @@
#include <asm/irq.h>
#include <asm/div64.h>
#include <mach/bitfield.h>
-#include <mach/pxafb.h>
+#include <linux/platform_data/video-pxafb.h>
/*
* Complain if VAR is out of range.
diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c
index 3c1de981a18..296afae442f 100644
--- a/drivers/video/sbuslib.c
+++ b/drivers/video/sbuslib.c
@@ -57,9 +57,8 @@ int sbusfb_mmap_helper(struct sbus_mmap_map *map,
off = vma->vm_pgoff << PAGE_SHIFT;
- /* To stop the swapper from even considering these pages */
- vma->vm_flags |= (VM_IO | VM_RESERVED);
-
+ /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
+
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
/* Each page, see which map applies */
diff --git a/drivers/video/smscufx.c b/drivers/video/smscufx.c
index 5533a32c6ca..97bd6620c36 100644
--- a/drivers/video/smscufx.c
+++ b/drivers/video/smscufx.c
@@ -803,7 +803,6 @@ static int ufx_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
size = 0;
}
- vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
return 0;
}
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
index 8e4a446b5ed..b244f060f15 100644
--- a/drivers/video/tmiofb.c
+++ b/drivers/video/tmiofb.c
@@ -694,6 +694,10 @@ static int __devinit tmiofb_probe(struct platform_device *dev)
dev_err(&dev->dev, "NULL platform data!\n");
return -EINVAL;
}
+ if (ccr == NULL || lcr == NULL || vram == NULL || irq < 0) {
+ dev_err(&dev->dev, "missing resources\n");
+ return -EINVAL;
+ }
info = framebuffer_alloc(sizeof(struct tmiofb_par), &dev->dev);
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index 8af64148294..f45eba3d615 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -345,7 +345,6 @@ static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
size = 0;
}
- vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
return 0;
}
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index 970e43d13f5..89aef343e29 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -1018,7 +1018,6 @@ static int vmlfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
offset += vinfo->vram_start;
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
- vma->vm_flags |= VM_RESERVED | VM_IO;
if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
size, vma->vm_page_prot))
return -EAGAIN;
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 501a922aa9d..c7f692525b8 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -439,7 +439,6 @@ static int vfb_mmap(struct fb_info *info,
size = 0;
}
- vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
return 0;
}
diff --git a/drivers/video/vt8500lcdfb.c b/drivers/video/vt8500lcdfb.c
index 2a5fe6ede84..9af8da70e78 100644
--- a/drivers/video/vt8500lcdfb.c
+++ b/drivers/video/vt8500lcdfb.c
@@ -30,11 +30,18 @@
#include <linux/platform_device.h>
#include <linux/wait.h>
-#include <mach/vt8500fb.h>
+#include <linux/platform_data/video-vt8500lcdfb.h>
#include "vt8500lcdfb.h"
#include "wmt_ge_rops.h"
+#ifdef CONFIG_OF
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/memblock.h>
+#endif
+
+
#define to_vt8500lcd_info(__info) container_of(__info, \
struct vt8500lcd_info, fb)
@@ -270,15 +277,21 @@ static int __devinit vt8500lcd_probe(struct platform_device *pdev)
{
struct vt8500lcd_info *fbi;
struct resource *res;
- struct vt8500fb_platform_data *pdata = pdev->dev.platform_data;
void *addr;
int irq, ret;
+ struct fb_videomode of_mode;
+ struct device_node *np;
+ u32 bpp;
+ dma_addr_t fb_mem_phys;
+ unsigned long fb_mem_len;
+ void *fb_mem_virt;
+
ret = -ENOMEM;
fbi = NULL;
- fbi = kzalloc(sizeof(struct vt8500lcd_info) + sizeof(u32) * 16,
- GFP_KERNEL);
+ fbi = devm_kzalloc(&pdev->dev, sizeof(struct vt8500lcd_info)
+ + sizeof(u32) * 16, GFP_KERNEL);
if (!fbi) {
dev_err(&pdev->dev, "Failed to initialize framebuffer device\n");
ret = -ENOMEM;
@@ -333,9 +346,45 @@ static int __devinit vt8500lcd_probe(struct platform_device *pdev)
goto failed_free_res;
}
- fbi->fb.fix.smem_start = pdata->video_mem_phys;
- fbi->fb.fix.smem_len = pdata->video_mem_len;
- fbi->fb.screen_base = pdata->video_mem_virt;
+ np = of_parse_phandle(pdev->dev.of_node, "default-mode", 0);
+ if (!np) {
+ pr_err("%s: No display description in Device Tree\n", __func__);
+ ret = -EINVAL;
+ goto failed_free_res;
+ }
+
+ /*
+ * This code is copied from Sascha Hauer's of_videomode helper
+ * and can be replaced with a call to the helper once mainlined
+ */
+ ret = 0;
+ ret |= of_property_read_u32(np, "hactive", &of_mode.xres);
+ ret |= of_property_read_u32(np, "vactive", &of_mode.yres);
+ ret |= of_property_read_u32(np, "hback-porch", &of_mode.left_margin);
+ ret |= of_property_read_u32(np, "hfront-porch", &of_mode.right_margin);
+ ret |= of_property_read_u32(np, "hsync-len", &of_mode.hsync_len);
+ ret |= of_property_read_u32(np, "vback-porch", &of_mode.upper_margin);
+ ret |= of_property_read_u32(np, "vfront-porch", &of_mode.lower_margin);
+ ret |= of_property_read_u32(np, "vsync-len", &of_mode.vsync_len);
+ ret |= of_property_read_u32(np, "bpp", &bpp);
+ if (ret) {
+ pr_err("%s: Unable to read display properties\n", __func__);
+ goto failed_free_res;
+ }
+ of_mode.vmode = FB_VMODE_NONINTERLACED;
+
+ /* try allocating the framebuffer */
+ fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8);
+ fb_mem_virt = dma_alloc_coherent(&pdev->dev, fb_mem_len, &fb_mem_phys,
+ GFP_KERNEL);
+ if (!fb_mem_virt) {
+ pr_err("%s: Failed to allocate framebuffer\n", __func__);
+ return -ENOMEM;
+ };
+
+ fbi->fb.fix.smem_start = fb_mem_phys;
+ fbi->fb.fix.smem_len = fb_mem_len;
+ fbi->fb.screen_base = fb_mem_virt;
fbi->palette_size = PAGE_ALIGN(512);
fbi->palette_cpu = dma_alloc_coherent(&pdev->dev,
@@ -370,10 +419,11 @@ static int __devinit vt8500lcd_probe(struct platform_device *pdev)
goto failed_free_irq;
}
- fb_videomode_to_var(&fbi->fb.var, &pdata->mode);
- fbi->fb.var.bits_per_pixel = pdata->bpp;
- fbi->fb.var.xres_virtual = pdata->xres_virtual;
- fbi->fb.var.yres_virtual = pdata->yres_virtual;
+ fb_videomode_to_var(&fbi->fb.var, &of_mode);
+
+ fbi->fb.var.xres_virtual = of_mode.xres;
+ fbi->fb.var.yres_virtual = of_mode.yres * 2;
+ fbi->fb.var.bits_per_pixel = bpp;
ret = vt8500lcd_set_par(&fbi->fb);
if (ret) {
@@ -448,12 +498,18 @@ static int __devexit vt8500lcd_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id via_dt_ids[] = {
+ { .compatible = "via,vt8500-fb", },
+ {}
+};
+
static struct platform_driver vt8500lcd_driver = {
.probe = vt8500lcd_probe,
.remove = __devexit_p(vt8500lcd_remove),
.driver = {
.owner = THIS_MODULE,
.name = "vt8500-lcd",
+ .of_match_table = of_match_ptr(via_dt_ids),
},
};
@@ -461,4 +517,5 @@ module_platform_driver(vt8500lcd_driver);
MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>");
MODULE_DESCRIPTION("LCD controller driver for VIA VT8500");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, via_dt_ids);
diff --git a/drivers/video/wm8505fb.c b/drivers/video/wm8505fb.c
index c8703bd61b7..77539c1b56a 100644
--- a/drivers/video/wm8505fb.c
+++ b/drivers/video/wm8505fb.c
@@ -28,8 +28,11 @@
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/wait.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/memblock.h>
-#include <mach/vt8500fb.h>
+#include <linux/platform_data/video-vt8500lcdfb.h>
#include "wm8505fb_regs.h"
#include "wmt_ge_rops.h"
@@ -59,8 +62,12 @@ static int wm8505fb_init_hw(struct fb_info *info)
writel(fbi->fb.fix.smem_start, fbi->regbase + WMT_GOVR_FBADDR);
writel(fbi->fb.fix.smem_start, fbi->regbase + WMT_GOVR_FBADDR1);
- /* Set in-memory picture format to RGB 32bpp */
- writel(0x1c, fbi->regbase + WMT_GOVR_COLORSPACE);
+ /*
+ * Set in-memory picture format to RGB
+ * 0x31C sets the correct color mode (RGB565) for WM8650
+ * Bit 8+9 (0x300) are ignored on WM8505 as reserved
+ */
+ writel(0x31c, fbi->regbase + WMT_GOVR_COLORSPACE);
writel(1, fbi->regbase + WMT_GOVR_COLORSPACE1);
/* Virtual buffer size */
@@ -127,6 +134,18 @@ static int wm8505fb_set_par(struct fb_info *info)
info->var.blue.msb_right = 0;
info->fix.visual = FB_VISUAL_TRUECOLOR;
info->fix.line_length = info->var.xres_virtual << 2;
+ } else if (info->var.bits_per_pixel == 16) {
+ info->var.red.offset = 11;
+ info->var.red.length = 5;
+ info->var.red.msb_right = 0;
+ info->var.green.offset = 5;
+ info->var.green.length = 6;
+ info->var.green.msb_right = 0;
+ info->var.blue.offset = 0;
+ info->var.blue.length = 5;
+ info->var.blue.msb_right = 0;
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ info->fix.line_length = info->var.xres_virtual << 1;
}
wm8505fb_set_timing(info);
@@ -246,16 +265,20 @@ static int __devinit wm8505fb_probe(struct platform_device *pdev)
struct wm8505fb_info *fbi;
struct resource *res;
void *addr;
- struct vt8500fb_platform_data *pdata;
int ret;
- pdata = pdev->dev.platform_data;
+ struct fb_videomode of_mode;
+ struct device_node *np;
+ u32 bpp;
+ dma_addr_t fb_mem_phys;
+ unsigned long fb_mem_len;
+ void *fb_mem_virt;
ret = -ENOMEM;
fbi = NULL;
- fbi = kzalloc(sizeof(struct wm8505fb_info) + sizeof(u32) * 16,
- GFP_KERNEL);
+ fbi = devm_kzalloc(&pdev->dev, sizeof(struct wm8505fb_info) +
+ sizeof(u32) * 16, GFP_KERNEL);
if (!fbi) {
dev_err(&pdev->dev, "Failed to initialize framebuffer device\n");
ret = -ENOMEM;
@@ -305,21 +328,58 @@ static int __devinit wm8505fb_probe(struct platform_device *pdev)
goto failed_free_res;
}
- fb_videomode_to_var(&fbi->fb.var, &pdata->mode);
+ np = of_parse_phandle(pdev->dev.of_node, "default-mode", 0);
+ if (!np) {
+ pr_err("%s: No display description in Device Tree\n", __func__);
+ ret = -EINVAL;
+ goto failed_free_res;
+ }
+
+ /*
+ * This code is copied from Sascha Hauer's of_videomode helper
+ * and can be replaced with a call to the helper once mainlined
+ */
+ ret = 0;
+ ret |= of_property_read_u32(np, "hactive", &of_mode.xres);
+ ret |= of_property_read_u32(np, "vactive", &of_mode.yres);
+ ret |= of_property_read_u32(np, "hback-porch", &of_mode.left_margin);
+ ret |= of_property_read_u32(np, "hfront-porch", &of_mode.right_margin);
+ ret |= of_property_read_u32(np, "hsync-len", &of_mode.hsync_len);
+ ret |= of_property_read_u32(np, "vback-porch", &of_mode.upper_margin);
+ ret |= of_property_read_u32(np, "vfront-porch", &of_mode.lower_margin);
+ ret |= of_property_read_u32(np, "vsync-len", &of_mode.vsync_len);
+ ret |= of_property_read_u32(np, "bpp", &bpp);
+ if (ret) {
+ pr_err("%s: Unable to read display properties\n", __func__);
+ goto failed_free_res;
+ }
+
+ of_mode.vmode = FB_VMODE_NONINTERLACED;
+ fb_videomode_to_var(&fbi->fb.var, &of_mode);
fbi->fb.var.nonstd = 0;
fbi->fb.var.activate = FB_ACTIVATE_NOW;
fbi->fb.var.height = -1;
fbi->fb.var.width = -1;
- fbi->fb.var.xres_virtual = pdata->xres_virtual;
- fbi->fb.var.yres_virtual = pdata->yres_virtual;
- fbi->fb.var.bits_per_pixel = pdata->bpp;
- fbi->fb.fix.smem_start = pdata->video_mem_phys;
- fbi->fb.fix.smem_len = pdata->video_mem_len;
- fbi->fb.screen_base = pdata->video_mem_virt;
- fbi->fb.screen_size = pdata->video_mem_len;
+ /* try allocating the framebuffer */
+ fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8);
+ fb_mem_virt = dma_alloc_coherent(&pdev->dev, fb_mem_len, &fb_mem_phys,
+ GFP_KERNEL);
+ if (!fb_mem_virt) {
+ pr_err("%s: Failed to allocate framebuffer\n", __func__);
+ return -ENOMEM;
+ };
+
+ fbi->fb.var.xres_virtual = of_mode.xres;
+ fbi->fb.var.yres_virtual = of_mode.yres * 2;
+ fbi->fb.var.bits_per_pixel = bpp;
+
+ fbi->fb.fix.smem_start = fb_mem_phys;
+ fbi->fb.fix.smem_len = fb_mem_len;
+ fbi->fb.screen_base = fb_mem_virt;
+ fbi->fb.screen_size = fb_mem_len;
if (fb_alloc_cmap(&fbi->fb.cmap, 256, 0) < 0) {
dev_err(&pdev->dev, "Failed to allocate color map\n");
@@ -395,12 +455,18 @@ static int __devexit wm8505fb_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id wmt_dt_ids[] = {
+ { .compatible = "wm,wm8505-fb", },
+ {}
+};
+
static struct platform_driver wm8505fb_driver = {
.probe = wm8505fb_probe,
.remove = __devexit_p(wm8505fb_remove),
.driver = {
.owner = THIS_MODULE,
.name = DRIVER_NAME,
+ .of_match_table = of_match_ptr(wmt_dt_ids),
},
};
@@ -408,4 +474,5 @@ module_platform_driver(wm8505fb_driver);
MODULE_AUTHOR("Ed Spiridonov <edo.rus@gmail.com>");
MODULE_DESCRIPTION("Framebuffer driver for WMT WM8505");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, wmt_dt_ids);
diff --git a/drivers/video/wmt_ge_rops.c b/drivers/video/wmt_ge_rops.c
index 55be3865015..ba025b4c7d0 100644
--- a/drivers/video/wmt_ge_rops.c
+++ b/drivers/video/wmt_ge_rops.c
@@ -158,12 +158,18 @@ static int __devexit wmt_ge_rops_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id wmt_dt_ids[] = {
+ { .compatible = "wm,prizm-ge-rops", },
+ { /* sentinel */ }
+};
+
static struct platform_driver wmt_ge_rops_driver = {
.probe = wmt_ge_rops_probe,
.remove = __devexit_p(wmt_ge_rops_remove),
.driver = {
.owner = THIS_MODULE,
.name = "wmt_ge_rops",
+ .of_match_table = of_match_ptr(wmt_dt_ids),
},
};
@@ -172,4 +178,5 @@ module_platform_driver(wmt_ge_rops_driver);
MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com");
MODULE_DESCRIPTION("Accelerators for raster operations using "
"WonderMedia Graphics Engine");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, wmt_dt_ids);