summaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--drivers/video/atafb.c6
-rw-r--r--drivers/video/atmel_lcdfb.c11
-rw-r--r--drivers/video/backlight/Kconfig33
-rw-r--r--drivers/video/backlight/Makefile4
-rw-r--r--drivers/video/backlight/adp5520_bl.c377
-rw-r--r--drivers/video/backlight/adx_bl.c178
-rw-r--r--drivers/video/backlight/backlight.c42
-rw-r--r--drivers/video/backlight/corgi_lcd.c5
-rw-r--r--drivers/video/backlight/da903x_bl.c20
-rw-r--r--drivers/video/backlight/hp680_bl.c2
-rw-r--r--drivers/video/backlight/lcd.c2
-rw-r--r--drivers/video/backlight/lms283gf05.c242
-rw-r--r--drivers/video/backlight/mbp_nvidia_bl.c36
-rw-r--r--drivers/video/backlight/wm831x_bl.c250
-rw-r--r--drivers/video/console/fbcon.c5
-rw-r--r--drivers/video/da8xx-fb.c3
-rw-r--r--drivers/video/fb_defio.c2
-rw-r--r--drivers/video/fbmem.c2
-rw-r--r--drivers/video/msm/mddi.c3
-rw-r--r--drivers/video/msm/mddi_client_nt35399.c1
-rw-r--r--drivers/video/msm/mddi_client_toshiba.c1
-rw-r--r--drivers/video/msm/mdp.c18
-rw-r--r--drivers/video/msm/mdp_ppp.c20
-rw-r--r--drivers/video/omap/blizzard.c10
-rw-r--r--drivers/video/omap/dispc.c2
-rw-r--r--drivers/video/omap/omapfb_main.c22
-rw-r--r--drivers/video/pxafb.c32
-rw-r--r--drivers/video/savage/savagefb_driver.c20
-rw-r--r--drivers/video/uvesafb.c28
30 files changed, 1235 insertions, 144 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 9bbb2855ea9..188e1ba3b69 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2121,7 +2121,7 @@ config FB_EP93XX
config FB_PRE_INIT_FB
bool "Don't reinitialize, use bootloader's GDC/Display configuration"
- depends on FB_MB862XX_LIME
+ depends on FB && FB_MB862XX_LIME
---help---
Select this option if display contents should be inherited as set by
the bootloader.
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 8cd279be74e..37624f74e88 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -329,12 +329,6 @@ extern unsigned char fontdata_8x16[];
*
* * perform fb specific mmap *
* int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
- *
- * * save current hardware state *
- * void (*fb_save_state)(struct fb_info *info);
- *
- * * restore saved state *
- * void (*fb_restore_state)(struct fb_info *info);
* } ;
*/
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 2830ffd7297..d5e801076d3 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -484,6 +484,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
unsigned long value;
unsigned long clk_value_khz;
unsigned long bits_per_line;
+ unsigned long pix_factor = 2;
might_sleep();
@@ -516,20 +517,24 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
/* Now, the LCDC core... */
/* Set pixel clock */
+ if (cpu_is_at91sam9g45() && !cpu_is_at91sam9g45es())
+ pix_factor = 1;
+
clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000;
value = DIV_ROUND_UP(clk_value_khz, PICOS2KHZ(info->var.pixclock));
- if (value < 2) {
+ if (value < pix_factor) {
dev_notice(info->device, "Bypassing pixel clock divider\n");
lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, ATMEL_LCDC_BYPASS);
} else {
- value = (value / 2) - 1;
+ value = (value / pix_factor) - 1;
dev_dbg(info->device, " * programming CLKVAL = 0x%08lx\n",
value);
lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1,
value << ATMEL_LCDC_CLKVAL_OFFSET);
- info->var.pixclock = KHZ2PICOS(clk_value_khz / (2 * (value + 1)));
+ info->var.pixclock =
+ KHZ2PICOS(clk_value_khz / (pix_factor * (value + 1)));
dev_dbg(info->device, " updated pixclk: %lu KHz\n",
PICOS2KHZ(info->var.pixclock));
}
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 90861cd9316..09bfa9662e4 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -31,6 +31,13 @@ config LCD_CORGI
Say y here to support the LCD panels usually found on SHARP
corgi (C7x0) and spitz (Cxx00) models.
+config LCD_LMS283GF05
+ tristate "Samsung LMS283GF05 LCD"
+ depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO
+ help
+ SPI driver for Samsung LMS283GF05. This provides basic support
+ for powering the LCD up/down through a sysfs interface.
+
config LCD_LTV350QV
tristate "Samsung LTV350QV LCD Panel"
depends on LCD_CLASS_DEVICE && SPI_MASTER
@@ -229,3 +236,29 @@ config BACKLIGHT_SAHARA
help
If you have a Tabletkiosk Sahara Touch-iT, say y to enable the
backlight driver.
+
+config BACKLIGHT_WM831X
+ tristate "WM831x PMIC Backlight Driver"
+ depends on BACKLIGHT_CLASS_DEVICE && MFD_WM831X
+ help
+ If you have a backlight driven by the ISINK and DCDC of a
+ WM831x PMIC say y to enable the backlight driver for it.
+
+config BACKLIGHT_ADX
+ tristate "Avionic Design Xanthos Backlight Driver"
+ depends on BACKLIGHT_CLASS_DEVICE && ARCH_PXA_ADX
+ default y
+ help
+ Say Y to enable the backlight driver on Avionic Design Xanthos-based
+ boards.
+
+config BACKLIGHT_ADP5520
+ tristate "Backlight Driver for ADP5520/ADP5501 using WLED"
+ depends on BACKLIGHT_CLASS_DEVICE && PMIC_ADP5520
+ help
+ If you have a LCD backlight connected to the BST/BL_SNK output of
+ ADP5520 or ADP5501, say Y here to enable this driver.
+
+ To compile this driver as a module, choose M here: the module will
+ be called adp5520_bl.
+
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 4eb178c1d68..9a405548874 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -3,6 +3,7 @@
obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o
obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o
+obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o
obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
obj-$(CONFIG_LCD_ILI9320) += ili9320.o
obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o
@@ -24,4 +25,7 @@ obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o
obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
+obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
+obj-$(CONFIG_BACKLIGHT_ADX) += adx_bl.o
+obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o
diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c
new file mode 100644
index 00000000000..ad05da5ba3c
--- /dev/null
+++ b/drivers/video/backlight/adp5520_bl.c
@@ -0,0 +1,377 @@
+/*
+ * Backlight driver for Analog Devices ADP5520/ADP5501 MFD PMICs
+ *
+ * Copyright 2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/mfd/adp5520.h>
+
+struct adp5520_bl {
+ struct device *master;
+ struct adp5520_backlight_platfrom_data *pdata;
+ struct mutex lock;
+ unsigned long cached_daylight_max;
+ int id;
+ int current_brightness;
+};
+
+static int adp5520_bl_set(struct backlight_device *bl, int brightness)
+{
+ struct adp5520_bl *data = bl_get_data(bl);
+ struct device *master = data->master;
+ int ret = 0;
+
+ if (data->pdata->en_ambl_sens) {
+ if ((brightness > 0) && (brightness < ADP5020_MAX_BRIGHTNESS)) {
+ /* Disable Ambient Light auto adjust */
+ ret |= adp5520_clr_bits(master, BL_CONTROL,
+ BL_AUTO_ADJ);
+ ret |= adp5520_write(master, DAYLIGHT_MAX, brightness);
+ } else {
+ /*
+ * MAX_BRIGHTNESS -> Enable Ambient Light auto adjust
+ * restore daylight l3 sysfs brightness
+ */
+ ret |= adp5520_write(master, DAYLIGHT_MAX,
+ data->cached_daylight_max);
+ ret |= adp5520_set_bits(master, BL_CONTROL,
+ BL_AUTO_ADJ);
+ }
+ } else {
+ ret |= adp5520_write(master, DAYLIGHT_MAX, brightness);
+ }
+
+ if (data->current_brightness && brightness == 0)
+ ret |= adp5520_set_bits(master,
+ MODE_STATUS, DIM_EN);
+ else if (data->current_brightness == 0 && brightness)
+ ret |= adp5520_clr_bits(master,
+ MODE_STATUS, DIM_EN);
+
+ if (!ret)
+ data->current_brightness = brightness;
+
+ return ret;
+}
+
+static int adp5520_bl_update_status(struct backlight_device *bl)
+{
+ int brightness = bl->props.brightness;
+ if (bl->props.power != FB_BLANK_UNBLANK)
+ brightness = 0;
+
+ if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+ brightness = 0;
+
+ return adp5520_bl_set(bl, brightness);
+}
+
+static int adp5520_bl_get_brightness(struct backlight_device *bl)
+{
+ struct adp5520_bl *data = bl_get_data(bl);
+ int error;
+ uint8_t reg_val;
+
+ error = adp5520_read(data->master, BL_VALUE, &reg_val);
+
+ return error ? data->current_brightness : reg_val;
+}
+
+static struct backlight_ops adp5520_bl_ops = {
+ .update_status = adp5520_bl_update_status,
+ .get_brightness = adp5520_bl_get_brightness,
+};
+
+static int adp5520_bl_setup(struct backlight_device *bl)
+{
+ struct adp5520_bl *data = bl_get_data(bl);
+ struct device *master = data->master;
+ struct adp5520_backlight_platfrom_data *pdata = data->pdata;
+ int ret = 0;
+
+ ret |= adp5520_write(master, DAYLIGHT_MAX, pdata->l1_daylight_max);
+ ret |= adp5520_write(master, DAYLIGHT_DIM, pdata->l1_daylight_dim);
+
+ if (pdata->en_ambl_sens) {
+ data->cached_daylight_max = pdata->l1_daylight_max;
+ ret |= adp5520_write(master, OFFICE_MAX, pdata->l2_office_max);
+ ret |= adp5520_write(master, OFFICE_DIM, pdata->l2_office_dim);
+ ret |= adp5520_write(master, DARK_MAX, pdata->l3_dark_max);
+ ret |= adp5520_write(master, DARK_DIM, pdata->l3_dark_dim);
+ ret |= adp5520_write(master, L2_TRIP, pdata->l2_trip);
+ ret |= adp5520_write(master, L2_HYS, pdata->l2_hyst);
+ ret |= adp5520_write(master, L3_TRIP, pdata->l3_trip);
+ ret |= adp5520_write(master, L3_HYS, pdata->l3_hyst);
+ ret |= adp5520_write(master, ALS_CMPR_CFG,
+ ALS_CMPR_CFG_VAL(pdata->abml_filt, L3_EN));
+ }
+
+ ret |= adp5520_write(master, BL_CONTROL,
+ BL_CTRL_VAL(pdata->fade_led_law, pdata->en_ambl_sens));
+
+ ret |= adp5520_write(master, BL_FADE, FADE_VAL(pdata->fade_in,
+ pdata->fade_out));
+
+ ret |= adp5520_set_bits(master, MODE_STATUS, BL_EN | DIM_EN);
+
+ return ret;
+}
+
+static ssize_t adp5520_show(struct device *dev, char *buf, int reg)
+{
+ struct adp5520_bl *data = dev_get_drvdata(dev);
+ int error;
+ uint8_t reg_val;
+
+ mutex_lock(&data->lock);
+ error = adp5520_read(data->master, reg, &reg_val);
+ mutex_unlock(&data->lock);
+
+ return sprintf(buf, "%u\n", reg_val);
+}
+
+static ssize_t adp5520_store(struct device *dev, const char *buf,
+ size_t count, int reg)
+{
+ struct adp5520_bl *data = dev_get_drvdata(dev);
+ unsigned long val;
+ int ret;
+
+ ret = strict_strtoul(buf, 10, &val);
+ if (ret)
+ return ret;
+
+ mutex_lock(&data->lock);
+ adp5520_write(data->master, reg, val);
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t adp5520_bl_dark_max_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return adp5520_show(dev, buf, DARK_MAX);
+}
+
+static ssize_t adp5520_bl_dark_max_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return adp5520_store(dev, buf, count, DARK_MAX);
+}
+static DEVICE_ATTR(dark_max, 0664, adp5520_bl_dark_max_show,
+ adp5520_bl_dark_max_store);
+
+static ssize_t adp5520_bl_office_max_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return adp5520_show(dev, buf, OFFICE_MAX);
+}
+
+static ssize_t adp5520_bl_office_max_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return adp5520_store(dev, buf, count, OFFICE_MAX);
+}
+static DEVICE_ATTR(office_max, 0664, adp5520_bl_office_max_show,
+ adp5520_bl_office_max_store);
+
+static ssize_t adp5520_bl_daylight_max_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return adp5520_show(dev, buf, DAYLIGHT_MAX);
+}
+
+static ssize_t adp5520_bl_daylight_max_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct adp5520_bl *data = dev_get_drvdata(dev);
+
+ strict_strtoul(buf, 10, &data->cached_daylight_max);
+ return adp5520_store(dev, buf, count, DAYLIGHT_MAX);
+}
+static DEVICE_ATTR(daylight_max, 0664, adp5520_bl_daylight_max_show,
+ adp5520_bl_daylight_max_store);
+
+static ssize_t adp5520_bl_dark_dim_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return adp5520_show(dev, buf, DARK_DIM);
+}
+
+static ssize_t adp5520_bl_dark_dim_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return adp5520_store(dev, buf, count, DARK_DIM);
+}
+static DEVICE_ATTR(dark_dim, 0664, adp5520_bl_dark_dim_show,
+ adp5520_bl_dark_dim_store);
+
+static ssize_t adp5520_bl_office_dim_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return adp5520_show(dev, buf, OFFICE_DIM);
+}
+
+static ssize_t adp5520_bl_office_dim_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return adp5520_store(dev, buf, count, OFFICE_DIM);
+}
+static DEVICE_ATTR(office_dim, 0664, adp5520_bl_office_dim_show,
+ adp5520_bl_office_dim_store);
+
+static ssize_t adp5520_bl_daylight_dim_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return adp5520_show(dev, buf, DAYLIGHT_DIM);
+}
+
+static ssize_t adp5520_bl_daylight_dim_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return adp5520_store(dev, buf, count, DAYLIGHT_DIM);
+}
+static DEVICE_ATTR(daylight_dim, 0664, adp5520_bl_daylight_dim_show,
+ adp5520_bl_daylight_dim_store);
+
+static struct attribute *adp5520_bl_attributes[] = {
+ &dev_attr_dark_max.attr,
+ &dev_attr_dark_dim.attr,
+ &dev_attr_office_max.attr,
+ &dev_attr_office_dim.attr,
+ &dev_attr_daylight_max.attr,
+ &dev_attr_daylight_dim.attr,
+ NULL
+};
+
+static const struct attribute_group adp5520_bl_attr_group = {
+ .attrs = adp5520_bl_attributes,
+};
+
+static int __devinit adp5520_bl_probe(struct platform_device *pdev)
+{
+ struct backlight_device *bl;
+ struct adp5520_bl *data;
+ int ret = 0;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (data == NULL)
+ return -ENOMEM;
+
+ data->master = pdev->dev.parent;
+ data->pdata = pdev->dev.platform_data;
+
+ if (data->pdata == NULL) {
+ dev_err(&pdev->dev, "missing platform data\n");
+ kfree(data);
+ return -ENODEV;
+ }
+
+ data->id = pdev->id;
+ data->current_brightness = 0;
+
+ mutex_init(&data->lock);
+
+ bl = backlight_device_register(pdev->name, data->master,
+ data, &adp5520_bl_ops);
+ if (IS_ERR(bl)) {
+ dev_err(&pdev->dev, "failed to register backlight\n");
+ kfree(data);
+ return PTR_ERR(bl);
+ }
+
+ bl->props.max_brightness =
+ bl->props.brightness = ADP5020_MAX_BRIGHTNESS;
+
+ if (data->pdata->en_ambl_sens)
+ ret = sysfs_create_group(&bl->dev.kobj,
+ &adp5520_bl_attr_group);
+
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register sysfs\n");
+ backlight_device_unregister(bl);
+ kfree(data);
+ }
+
+ platform_set_drvdata(pdev, bl);
+ ret |= adp5520_bl_setup(bl);
+ backlight_update_status(bl);
+
+ return ret;
+}
+
+static int __devexit adp5520_bl_remove(struct platform_device *pdev)
+{
+ struct backlight_device *bl = platform_get_drvdata(pdev);
+ struct adp5520_bl *data = bl_get_data(bl);
+
+ adp5520_clr_bits(data->master, MODE_STATUS, BL_EN);
+
+ if (data->pdata->en_ambl_sens)
+ sysfs_remove_group(&bl->dev.kobj,
+ &adp5520_bl_attr_group);
+
+ backlight_device_unregister(bl);
+ kfree(data);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int adp5520_bl_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ struct backlight_device *bl = platform_get_drvdata(pdev);
+ return adp5520_bl_set(bl, 0);
+}
+
+static int adp5520_bl_resume(struct platform_device *pdev)
+{
+ struct backlight_device *bl = platform_get_drvdata(pdev);
+
+ backlight_update_status(bl);
+ return 0;
+}
+#else
+#define adp5520_bl_suspend NULL
+#define adp5520_bl_resume NULL
+#endif
+
+static struct platform_driver adp5520_bl_driver = {
+ .driver = {
+ .name = "adp5520-backlight",
+ .owner = THIS_MODULE,
+ },
+ .probe = adp5520_bl_probe,
+ .remove = __devexit_p(adp5520_bl_remove),
+ .suspend = adp5520_bl_suspend,
+ .resume = adp5520_bl_resume,
+};
+
+static int __init adp5520_bl_init(void)
+{
+ return platform_driver_register(&adp5520_bl_driver);
+}
+module_init(adp5520_bl_init);
+
+static void __exit adp5520_bl_exit(void)
+{
+ platform_driver_unregister(&adp5520_bl_driver);
+}
+module_exit(adp5520_bl_exit);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("ADP5520(01) Backlight Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:adp5520-backlight");
diff --git a/drivers/video/backlight/adx_bl.c b/drivers/video/backlight/adx_bl.c
new file mode 100644
index 00000000000..2c3bdfc620b
--- /dev/null
+++ b/drivers/video/backlight/adx_bl.c
@@ -0,0 +1,178 @@
+/*
+ * linux/drivers/video/backlight/adx.c
+ *
+ * Copyright (C) 2009 Avionic Design GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Written by Thierry Reding <thierry.reding@avionic-design.de>
+ */
+
+#include <linux/backlight.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+/* register definitions */
+#define ADX_BACKLIGHT_CONTROL 0x00
+#define ADX_BACKLIGHT_CONTROL_ENABLE (1 << 0)
+#define ADX_BACKLIGHT_BRIGHTNESS 0x08
+#define ADX_BACKLIGHT_STATUS 0x10
+#define ADX_BACKLIGHT_ERROR 0x18
+
+struct adxbl {
+ void __iomem *base;
+};
+
+static int adx_backlight_update_status(struct backlight_device *bldev)
+{
+ struct adxbl *bl = bl_get_data(bldev);
+ u32 value;
+
+ value = bldev->props.brightness;
+ writel(value, bl->base + ADX_BACKLIGHT_BRIGHTNESS);
+
+ value = readl(bl->base + ADX_BACKLIGHT_CONTROL);
+
+ if (bldev->props.state & BL_CORE_FBBLANK)
+ value &= ~ADX_BACKLIGHT_CONTROL_ENABLE;
+ else
+ value |= ADX_BACKLIGHT_CONTROL_ENABLE;
+
+ writel(value, bl->base + ADX_BACKLIGHT_CONTROL);
+
+ return 0;
+}
+
+static int adx_backlight_get_brightness(struct backlight_device *bldev)
+{
+ struct adxbl *bl = bl_get_data(bldev);
+ u32 brightness;
+
+ brightness = readl(bl->base + ADX_BACKLIGHT_BRIGHTNESS);
+ return brightness & 0xff;
+}
+
+static int adx_backlight_check_fb(struct fb_info *fb)
+{
+ return 1;
+}
+
+static struct backlight_ops adx_backlight_ops = {
+ .options = 0,
+ .update_status = adx_backlight_update_status,
+ .get_brightness = adx_backlight_get_brightness,
+ .check_fb = adx_backlight_check_fb,
+};
+
+static int __devinit adx_backlight_probe(struct platform_device *pdev)
+{
+ struct backlight_device *bldev;
+ struct resource *res;
+ struct adxbl *bl;
+ int ret = 0;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ ret = -ENXIO;
+ goto out;
+ }
+
+ res = devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), res->name);
+ if (!res) {
+ ret = -ENXIO;
+ goto out;
+ }
+
+ bl = devm_kzalloc(&pdev->dev, sizeof(*bl), GFP_KERNEL);
+ if (!bl) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ bl->base = devm_ioremap_nocache(&pdev->dev, res->start,
+ resource_size(res));
+ if (!bl->base) {
+ ret = -ENXIO;
+ goto out;
+ }
+
+ bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, bl,
+ &adx_backlight_ops);
+ if (!bldev) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ bldev->props.max_brightness = 0xff;
+ bldev->props.brightness = 0xff;
+ bldev->props.power = FB_BLANK_UNBLANK;
+
+ platform_set_drvdata(pdev, bldev);
+
+out:
+ return ret;
+}
+
+static int __devexit adx_backlight_remove(struct platform_device *pdev)
+{
+ struct backlight_device *bldev;
+ int ret = 0;
+
+ bldev = platform_get_drvdata(pdev);
+ bldev->props.power = FB_BLANK_UNBLANK;
+ bldev->props.brightness = 0xff;
+ backlight_update_status(bldev);
+ backlight_device_unregister(bldev);
+ platform_set_drvdata(pdev, NULL);
+
+ return ret;
+}
+
+#ifdef CONFIG_PM
+static int adx_backlight_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ return 0;
+}
+
+static int adx_backlight_resume(struct platform_device *pdev)
+{
+ return 0;
+}
+#else
+#define adx_backlight_suspend NULL
+#define adx_backlight_resume NULL
+#endif
+
+static struct platform_driver adx_backlight_driver = {
+ .probe = adx_backlight_probe,
+ .remove = __devexit_p(adx_backlight_remove),
+ .suspend = adx_backlight_suspend,
+ .resume = adx_backlight_resume,
+ .driver = {
+ .name = "adx-backlight",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init adx_backlight_init(void)
+{
+ return platform_driver_register(&adx_backlight_driver);
+}
+
+static void __exit adx_backlight_exit(void)
+{
+ platform_driver_unregister(&adx_backlight_driver);
+}
+
+module_init(adx_backlight_init);
+module_exit(adx_backlight_exit);
+
+MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
+MODULE_DESCRIPTION("Avionic Design Xanthos Backlight Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 157057c79ca..6615ac7fa60 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -73,6 +73,27 @@ static inline void backlight_unregister_fb(struct backlight_device *bd)
}
#endif /* CONFIG_FB */
+static void backlight_generate_event(struct backlight_device *bd,
+ enum backlight_update_reason reason)
+{
+ char *envp[2];
+
+ switch (reason) {
+ case BACKLIGHT_UPDATE_SYSFS:
+ envp[0] = "SOURCE=sysfs";
+ break;
+ case BACKLIGHT_UPDATE_HOTKEY:
+ envp[0] = "SOURCE=hotkey";
+ break;
+ default:
+ envp[0] = "SOURCE=unknown";
+ break;
+ }
+ envp[1] = NULL;
+ kobject_uevent_env(&bd->dev.kobj, KOBJ_CHANGE, envp);
+ sysfs_notify(&bd->dev.kobj, NULL, "actual_brightness");
+}
+
static ssize_t backlight_show_power(struct device *dev,
struct device_attribute *attr,char *buf)
{
@@ -142,6 +163,8 @@ static ssize_t backlight_store_brightness(struct device *dev,
}
mutex_unlock(&bd->ops_lock);
+ backlight_generate_event(bd, BACKLIGHT_UPDATE_SYSFS);
+
return rc;
}
@@ -214,6 +237,25 @@ static struct device_attribute bl_device_attributes[] = {
};
/**
+ * backlight_force_update - tell the backlight subsystem that hardware state
+ * has changed
+ * @bd: the backlight device to update
+ *
+ * Updates the internal state of the backlight in response to a hardware event,
+ * and generate a uevent to notify userspace
+ */
+void backlight_force_update(struct backlight_device *bd,
+ enum backlight_update_reason reason)
+{
+ mutex_lock(&bd->ops_lock);
+ if (bd->ops && bd->ops->get_brightness)
+ bd->props.brightness = bd->ops->get_brightness(bd);
+ mutex_unlock(&bd->ops_lock);
+ backlight_generate_event(bd, reason);
+}
+EXPORT_SYMBOL(backlight_force_update);
+
+/**
* backlight_device_register - create and register a new object of
* backlight_device class.
* @name: the name of the new object(must be the same as the name of the
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c
index 2211a852af9..96774949cd3 100644
--- a/drivers/video/backlight/corgi_lcd.c
+++ b/drivers/video/backlight/corgi_lcd.c
@@ -433,8 +433,9 @@ static int corgi_bl_update_status(struct backlight_device *bd)
if (corgibl_flags & CORGIBL_SUSPENDED)
intensity = 0;
- if (corgibl_flags & CORGIBL_BATTLOW)
- intensity &= lcd->limit_mask;
+
+ if ((corgibl_flags & CORGIBL_BATTLOW) && intensity > lcd->limit_mask)
+ intensity = lcd->limit_mask;
return corgi_bl_set_intensity(lcd, intensity);
}
diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c
index 93bb4340cc6..701a1081e19 100644
--- a/drivers/video/backlight/da903x_bl.c
+++ b/drivers/video/backlight/da903x_bl.c
@@ -154,34 +154,38 @@ static int da903x_backlight_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
-static int da903x_backlight_suspend(struct platform_device *pdev,
- pm_message_t state)
+static int da903x_backlight_suspend(struct device *dev)
{
+ struct platform_device *pdev = to_platform_device(dev);
struct backlight_device *bl = platform_get_drvdata(pdev);
return da903x_backlight_set(bl, 0);
}
-static int da903x_backlight_resume(struct platform_device *pdev)
+static int da903x_backlight_resume(struct device *dev)
{
+ struct platform_device *pdev = to_platform_device(dev);
struct backlight_device *bl = platform_get_drvdata(pdev);
backlight_update_status(bl);
return 0;
}
-#else
-#define da903x_backlight_suspend NULL
-#define da903x_backlight_resume NULL
+
+static struct dev_pm_ops da903x_backlight_pm_ops = {
+ .suspend = da903x_backlight_suspend,
+ .resume = da903x_backlight_resume,
+};
#endif
static struct platform_driver da903x_backlight_driver = {
.driver = {
.name = "da903x-backlight",
.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &da903x_backlight_pm_ops,
+#endif
},
.probe = da903x_backlight_probe,
.remove = da903x_backlight_remove,
- .suspend = da903x_backlight_suspend,
- .resume = da903x_backlight_resume,
};
static int __init da903x_backlight_init(void)
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index 5be55a20d8c..7fb4eefff80 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -103,7 +103,7 @@ static struct backlight_ops hp680bl_ops = {
.update_status = hp680bl_set_intensity,
};
-static int __init hp680bl_probe(struct platform_device *pdev)
+static int __devinit hp680bl_probe(struct platform_device *pdev)
{
struct backlight_device *bd;
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index b6449470106..a482dd7b031 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -56,7 +56,7 @@ static int fb_notifier_callback(struct notifier_block *self,
static int lcd_register_fb(struct lcd_device *ld)
{
- memset(&ld->fb_notif, 0, sizeof(&ld->fb_notif));
+ memset(&ld->fb_notif, 0, sizeof(ld->fb_notif));
ld->fb_notif.notifier_call = fb_notifier_callback;
return fb_register_client(&ld->fb_notif);
}
diff --git a/drivers/video/backlight/lms283gf05.c b/drivers/video/backlight/lms283gf05.c
new file mode 100644
index 00000000000..447b542a20c
--- /dev/null
+++ b/drivers/video/backlight/lms283gf05.c
@@ -0,0 +1,242 @@
+/*
+ * lms283gf05.c -- support for Samsung LMS283GF05 LCD
+ *
+ * Copyright (c) 2009 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/lcd.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/lms283gf05.h>
+
+struct lms283gf05_state {
+ struct spi_device *spi;
+ struct lcd_device *ld;
+};
+
+struct lms283gf05_seq {
+ unsigned char reg;
+ unsigned short value;
+ unsigned char delay;
+};
+
+/* Magic sequences supplied by manufacturer, for details refer to datasheet */
+static struct lms283gf05_seq disp_initseq[] = {
+ /* REG, VALUE, DELAY */
+ { 0x07, 0x0000, 0 },
+ { 0x13, 0x0000, 10 },
+
+ { 0x11, 0x3004, 0 },
+ { 0x14, 0x200F, 0 },
+ { 0x10, 0x1a20, 0 },
+ { 0x13, 0x0040, 50 },
+
+ { 0x13, 0x0060, 0 },
+ { 0x13, 0x0070, 200 },
+
+ { 0x01, 0x0127, 0 },
+ { 0x02, 0x0700, 0 },
+ { 0x03, 0x1030, 0 },
+ { 0x08, 0x0208, 0 },
+ { 0x0B, 0x0620, 0 },
+ { 0x0C, 0x0110, 0 },
+ { 0x30, 0x0120, 0 },
+ { 0x31, 0x0127, 0 },
+ { 0x32, 0x0000, 0 },
+ { 0x33, 0x0503, 0 },
+ { 0x34, 0x0727, 0 },
+ { 0x35, 0x0124, 0 },
+ { 0x36, 0x0706, 0 },
+ { 0x37, 0x0701, 0 },
+ { 0x38, 0x0F00, 0 },
+ { 0x39, 0x0F00, 0 },
+ { 0x40, 0x0000, 0 },
+ { 0x41, 0x0000, 0 },
+ { 0x42, 0x013f, 0 },
+ { 0x43, 0x0000, 0 },
+ { 0x44, 0x013f, 0 },
+ { 0x45, 0x0000, 0 },
+ { 0x46, 0xef00, 0 },
+ { 0x47, 0x013f, 0 },
+ { 0x48, 0x0000, 0 },
+ { 0x07, 0x0015, 30 },
+
+ { 0x07, 0x0017, 0 },
+
+ { 0x20, 0x0000, 0 },
+ { 0x21, 0x0000, 0 },
+ { 0x22, 0x0000, 0 }
+};
+
+static struct lms283gf05_seq disp_pdwnseq[] = {
+ { 0x07, 0x0016, 30 },
+
+ { 0x07, 0x0004, 0 },
+ { 0x10, 0x0220, 20 },
+
+ { 0x13, 0x0060, 50 },
+
+ { 0x13, 0x0040, 50 },
+
+ { 0x13, 0x0000, 0 },
+ { 0x10, 0x0000, 0 }
+};
+
+
+static void lms283gf05_reset(unsigned long gpio, bool inverted)
+{
+ gpio_set_value(gpio, !inverted);
+ mdelay(100);
+ gpio_set_value(gpio, inverted);
+ mdelay(20);
+ gpio_set_value(gpio, !inverted);
+ mdelay(20);
+}
+
+static void lms283gf05_toggle(struct spi_device *spi,
+ struct lms283gf05_seq *seq, int sz)
+{
+ char buf[3];
+ int i;
+
+ for (i = 0; i < sz; i++) {
+ buf[0] = 0x74;
+ buf[1] = 0x00;
+ buf[2] = seq[i].reg;
+ spi_write(spi, buf, 3);
+
+ buf[0] = 0x76;
+ buf[1] = seq[i].value >> 8;
+ buf[2] = seq[i].value & 0xff;
+ spi_write(spi, buf, 3);
+
+ mdelay(seq[i].delay);
+ }
+}
+
+static int lms283gf05_power_set(struct lcd_device *ld, int power)
+{
+ struct lms283gf05_state *st = lcd_get_data(ld);
+ struct spi_device *spi = st->spi;
+ struct lms283gf05_pdata *pdata = spi->dev.platform_data;
+
+ if (power) {
+ if (pdata)
+ lms283gf05_reset(pdata->reset_gpio,
+ pdata->reset_inverted);
+ lms283gf05_toggle(spi, disp_initseq, ARRAY_SIZE(disp_initseq));
+ } else {
+ lms283gf05_toggle(spi, disp_pdwnseq, ARRAY_SIZE(disp_pdwnseq));
+ if (pdata)
+ gpio_set_value(pdata->reset_gpio,
+ pdata->reset_inverted);
+ }
+
+ return 0;
+}
+
+static struct lcd_ops lms_ops = {
+ .set_power = lms283gf05_power_set,
+ .get_power = NULL,
+};
+
+static int __devinit lms283gf05_probe(struct spi_device *spi)
+{
+ struct lms283gf05_state *st;
+ struct lms283gf05_pdata *pdata = spi->dev.platform_data;
+ struct lcd_device *ld;
+ int ret = 0;
+
+ if (pdata != NULL) {
+ ret = gpio_request(pdata->reset_gpio, "LMS285GF05 RESET");
+ if (ret)
+ return ret;
+
+ ret = gpio_direction_output(pdata->reset_gpio,
+ !pdata->reset_inverted);
+ if (ret)
+ goto err;
+ }
+
+ st = kzalloc(sizeof(struct lms283gf05_state), GFP_KERNEL);
+ if (st == NULL) {
+ dev_err(&spi->dev, "No memory for device state\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ ld = lcd_device_register("lms283gf05", &spi->dev, st, &lms_ops);
+ if (IS_ERR(ld)) {
+ ret = PTR_ERR(ld);
+ goto err2;
+ }
+
+ st->spi = spi;
+ st->ld = ld;
+
+ dev_set_drvdata(&spi->dev, st);
+
+ /* kick in the LCD */
+ if (pdata)
+ lms283gf05_reset(pdata->reset_gpio, pdata->reset_inverted);
+ lms283gf05_toggle(spi, disp_initseq, ARRAY_SIZE(disp_initseq));
+
+ return 0;
+
+err2:
+ kfree(st);
+err:
+ if (pdata != NULL)
+ gpio_free(pdata->reset_gpio);
+
+ return ret;
+}
+
+static int __devexit lms283gf05_remove(struct spi_device *spi)
+{
+ struct lms283gf05_state *st = dev_get_drvdata(&spi->dev);
+ struct lms283gf05_pdata *pdata = st->spi->dev.platform_data;
+
+ lcd_device_unregister(st->ld);
+
+ if (pdata != NULL)
+ gpio_free(pdata->reset_gpio);
+
+ kfree(st);
+
+ return 0;
+}
+
+static struct spi_driver lms283gf05_driver = {
+ .driver = {
+ .name = "lms283gf05",
+ .owner = THIS_MODULE,
+ },
+ .probe = lms283gf05_probe,
+ .remove = __devexit_p(lms283gf05_remove),
+};
+
+static __init int lms283gf05_init(void)
+{
+ return spi_register_driver(&lms283gf05_driver);
+}
+
+static __exit void lms283gf05_exit(void)
+{
+ spi_unregister_driver(&lms283gf05_driver);
+}
+
+module_init(lms283gf05_init);
+module_exit(lms283gf05_exit);
+
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION("LCD283GF05 LCD");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c
index 3bb4c0a50c6..9edb8d7c295 100644
--- a/drivers/video/backlight/mbp_nvidia_bl.c
+++ b/drivers/video/backlight/mbp_nvidia_bl.c
@@ -166,6 +166,15 @@ static const struct dmi_system_id __initdata mbp_device_table[] = {
},
{
.callback = mbp_dmi_match,
+ .ident = "MacBookAir 1,1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir1,1"),
+ },
+ .driver_data = (void *)&intel_chipset_data,
+ },
+ {
+ .callback = mbp_dmi_match,
.ident = "MacBook 5,1",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
@@ -175,6 +184,15 @@ static const struct dmi_system_id __initdata mbp_device_table[] = {
},
{
.callback = mbp_dmi_match,
+ .ident = "MacBook 5,2",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,2"),
+ },
+ .driver_data = (void *)&nvidia_chipset_data,
+ },
+ {
+ .callback = mbp_dmi_match,
.ident = "MacBookAir 2,1",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
@@ -191,6 +209,24 @@ static const struct dmi_system_id __initdata mbp_device_table[] = {
},
.driver_data = (void *)&nvidia_chipset_data,
},
+ {
+ .callback = mbp_dmi_match,
+ .ident = "MacBookPro 5,2",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,2"),
+ },
+ .driver_data = (void *)&nvidia_chipset_data,
+ },
+ {
+ .callback = mbp_dmi_match,
+ .ident = "MacBookPro 5,5",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,5"),
+ },
+ .driver_data = (void *)&nvidia_chipset_data,
+ },
{ }
};
diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c
new file mode 100644
index 00000000000..467bdb7efb2
--- /dev/null
+++ b/drivers/video/backlight/wm831x_bl.c
@@ -0,0 +1,250 @@
+/*
+ * Backlight driver for Wolfson Microelectronics WM831x PMICs
+ *
+ * Copyright 2009 Wolfson Microelectonics plc
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/pdata.h>
+#include <linux/mfd/wm831x/regulator.h>
+
+struct wm831x_backlight_data {
+ struct wm831x *wm831x;
+ int isink_reg;
+ int current_brightness;
+};
+
+static int wm831x_backlight_set(struct backlight_device *bl, int brightness)
+{
+ struct wm831x_backlight_data *data = bl_get_data(bl);
+ struct wm831x *wm831x = data->wm831x;
+ int power_up = !data->current_brightness && brightness;
+ int power_down = data->current_brightness && !brightness;
+ int ret;
+
+ if (power_up) {
+ /* Enable the ISINK */
+ ret = wm831x_set_bits(wm831x, data->isink_reg,
+ WM831X_CS1_ENA, WM831X_CS1_ENA);
+ if (ret < 0)
+ goto err;
+
+ /* Enable the DC-DC */
+ ret = wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE,
+ WM831X_DC4_ENA, WM831X_DC4_ENA);
+ if (ret < 0)
+ goto err;
+ }
+
+ if (power_down) {
+ /* DCDC first */
+ ret = wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE,
+ WM831X_DC4_ENA, 0);
+ if (ret < 0)
+ goto err;
+
+ /* ISINK */
+ ret = wm831x_set_bits(wm831x, data->isink_reg,
+ WM831X_CS1_DRIVE | WM831X_CS1_ENA, 0);
+ if (ret < 0)
+ goto err;
+ }
+
+ /* Set the new brightness */
+ ret = wm831x_set_bits(wm831x, data->isink_reg,
+ WM831X_CS1_ISEL_MASK, brightness);
+ if (ret < 0)
+ goto err;
+
+ if (power_up) {
+ /* Drive current through the ISINK */
+ ret = wm831x_set_bits(wm831x, data->isink_reg,
+ WM831X_CS1_DRIVE, WM831X_CS1_DRIVE);
+ if (ret < 0)
+ return ret;
+ }
+
+ data->current_brightness = brightness;
+
+ return 0;
+
+err:
+ /* If we were in the middle of a power transition always shut down
+ * for safety.
+ */
+ if (power_up || power_down) {
+ wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, WM831X_DC4_ENA, 0);
+ wm831x_set_bits(wm831x, data->isink_reg, WM831X_CS1_ENA, 0);
+ }
+
+ return ret;
+}
+
+static int wm831x_backlight_update_status(struct backlight_device *bl)
+{
+ int brightness = bl->props.brightness;
+
+ if (bl->props.power != FB_BLANK_UNBLANK)
+ brightness = 0;
+
+ if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+ brightness = 0;
+
+ if (bl->props.state & BL_CORE_SUSPENDED)
+ brightness = 0;
+
+ return wm831x_backlight_set(bl, brightness);
+}
+
+static int wm831x_backlight_get_brightness(struct backlight_device *bl)
+{
+ struct wm831x_backlight_data *data = bl_get_data(bl);
+ return data->current_brightness;
+}
+
+static struct backlight_ops wm831x_backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = wm831x_backlight_update_status,
+ .get_brightness = wm831x_backlight_get_brightness,
+};
+
+static int wm831x_backlight_probe(struct platform_device *pdev)
+{
+ struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+ struct wm831x_pdata *wm831x_pdata;
+ struct wm831x_backlight_pdata *pdata;
+ struct wm831x_backlight_data *data;
+ struct backlight_device *bl;
+ int ret, i, max_isel, isink_reg, dcdc_cfg;
+
+ /* We need platform data */
+ if (pdev->dev.parent->platform_data) {
+ wm831x_pdata = pdev->dev.parent->platform_data;
+ pdata = wm831x_pdata->backlight;
+ } else {
+ pdata = NULL;
+ }
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "No platform data supplied\n");
+ return -EINVAL;
+ }
+
+ /* Figure out the maximum current we can use */
+ for (i = 0; i < WM831X_ISINK_MAX_ISEL; i++) {
+ if (wm831x_isinkv_values[i] > pdata->max_uA)
+ break;
+ }
+
+ if (i == 0) {
+ dev_err(&pdev->dev, "Invalid max_uA: %duA\n", pdata->max_uA);
+ return -EINVAL;
+ }
+ max_isel = i - 1;
+
+ if (pdata->max_uA != wm831x_isinkv_values[max_isel])
+ dev_warn(&pdev->dev,
+ "Maximum current is %duA not %duA as requested\n",
+ wm831x_isinkv_values[max_isel], pdata->max_uA);
+
+ switch (pdata->isink) {
+ case 1:
+ isink_reg = WM831X_CURRENT_SINK_1;
+ dcdc_cfg = 0;
+ break;
+ case 2:
+ isink_reg = WM831X_CURRENT_SINK_2;
+ dcdc_cfg = WM831X_DC4_FBSRC;
+ break;
+ default:
+ dev_err(&pdev->dev, "Invalid ISINK %d\n", pdata->isink);
+ return -EINVAL;
+ }
+
+ /* Configure the ISINK to use for feedback */
+ ret = wm831x_reg_unlock(wm831x);
+ if (ret < 0)
+ return ret;
+
+ ret = wm831x_set_bits(wm831x, WM831X_DC4_CONTROL, WM831X_DC4_FBSRC,
+ dcdc_cfg);
+
+ wm831x_reg_lock(wm831x);
+ if (ret < 0)
+ return ret;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (data == NULL)
+ return -ENOMEM;
+
+ data->wm831x = wm831x;
+ data->current_brightness = 0;
+ data->isink_reg = isink_reg;
+
+ bl = backlight_device_register("wm831x", &pdev->dev,
+ data, &wm831x_backlight_ops);
+ if (IS_ERR(bl)) {
+ dev_err(&pdev->dev, "failed to register backlight\n");
+ kfree(data);
+ return PTR_ERR(bl);
+ }
+
+ bl->props.max_brightness = max_isel;
+ bl->props.brightness = max_isel;
+
+ platform_set_drvdata(pdev, bl);
+
+ /* Disable the DCDC if it was started so we can bootstrap */
+ wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, WM831X_DC4_ENA, 0);
+
+
+ backlight_update_status(bl);
+
+ return 0;
+}
+
+static int wm831x_backlight_remove(struct platform_device *pdev)
+{
+ struct backlight_device *bl = platform_get_drvdata(pdev);
+ struct wm831x_backlight_data *data = bl_get_data(bl);
+
+ backlight_device_unregister(bl);
+ kfree(data);
+ return 0;
+}
+
+static struct platform_driver wm831x_backlight_driver = {
+ .driver = {
+ .name = "wm831x-backlight",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm831x_backlight_probe,
+ .remove = wm831x_backlight_remove,
+};
+
+static int __init wm831x_backlight_init(void)
+{
+ return platform_driver_register(&wm831x_backlight_driver);
+}
+module_init(wm831x_backlight_init);
+
+static void __exit wm831x_backlight_exit(void)
+{
+ platform_driver_unregister(&wm831x_backlight_driver);
+}
+module_exit(wm831x_backlight_exit);
+
+MODULE_DESCRIPTION("Backlight Driver for WM831x PMICs");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm831x-backlight");
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 5a686cea23f..3681c6a8821 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -2311,14 +2311,11 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
ops->graphics = 1;
if (!blank) {
- if (info->fbops->fb_save_state)
- info->fbops->fb_save_state(info);
var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
fb_set_var(info, &var);
ops->graphics = 0;
ops->var = info->var;
- } else if (info->fbops->fb_restore_state)
- info->fbops->fb_restore_state(info);
+ }
}
if (!fbcon_is_inactive(vc, info)) {
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 42e1005e291..035d56835b7 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -26,7 +26,6 @@
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>
-#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <video/da8xx-fb.h>
@@ -705,7 +704,7 @@ static int __init fb_probe(struct platform_device *device)
if (i == ARRAY_SIZE(known_lcd_panels)) {
dev_err(&device->dev, "GLCD: No valid panel found\n");
- ret = ENODEV;
+ ret = -ENODEV;
goto err_clk_disable;
} else
dev_info(&device->dev, "GLCD: Found %s panel\n",
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 0a7a6679ee6..c27ab1ed960 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -125,7 +125,7 @@ page_already_added:
return 0;
}
-static struct vm_operations_struct fb_deferred_io_vm_ops = {
+static const struct vm_operations_struct fb_deferred_io_vm_ops = {
.fault = fb_deferred_io_fault,
.page_mkwrite = fb_deferred_io_mkwrite,
};
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index a1f2e7ce730..99bbd282ce6 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1800,7 +1800,7 @@ static int __init video_setup(char *options)
global = 1;
}
- if (!global && !strstr(options, "fb:")) {
+ if (!global && !strchr(options, ':')) {
fb_mode_option = options;
global = 1;
}
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index f2de5a1acd6..474421fe79a 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -24,11 +24,10 @@
#include <linux/spinlock.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/sched.h>
#include <mach/msm_iomap.h>
#include <mach/irqs.h>
#include <mach/board.h>
-#include <linux/delay.h>
-
#include <mach/msm_fb.h>
#include "mddi_hw.h"
diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c
index 9c78050ac79..c9e9349451c 100644
--- a/drivers/video/msm/mddi_client_nt35399.c
+++ b/drivers/video/msm/mddi_client_nt35399.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
+#include <linux/sched.h>
#include <linux/gpio.h>
#include <mach/msm_fb.h>
diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/msm/mddi_client_toshiba.c
index 80d0f5fdf0b..71048e78f7f 100644
--- a/drivers/video/msm/mddi_client_toshiba.c
+++ b/drivers/video/msm/mddi_client_toshiba.c
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
+#include <linux/sched.h>
#include <mach/msm_fb.h>
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 99636a2b20f..6c519e2fa2b 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -22,9 +22,6 @@
#include <linux/wait.h>
#include <linux/clk.h>
#include <linux/file.h>
-#ifdef CONFIG_ANDROID_PMEM
-#include <linux/android_pmem.h>
-#endif
#include <linux/major.h>
#include <mach/msm_iomap.h>
@@ -262,11 +259,6 @@ int get_img(struct mdp_img *img, struct fb_info *info,
struct file *file;
unsigned long vstart;
-#ifdef CONFIG_ANDROID_PMEM
- if (!get_pmem_file(img->memory_id, start, &vstart, len, filep))
- return 0;
-#endif
-
file = fget_light(img->memory_id, &put_needed);
if (file == NULL)
return -1;
@@ -283,12 +275,6 @@ int get_img(struct mdp_img *img, struct fb_info *info,
void put_img(struct file *src_file, struct file *dst_file)
{
-#ifdef CONFIG_ANDROID_PMEM
- if (src_file)
- put_pmem_file(src_file);
- if (dst_file)
- put_pmem_file(dst_file);
-#endif
}
int mdp_blit(struct mdp_device *mdp_dev, struct fb_info *fb,
@@ -320,9 +306,6 @@ int mdp_blit(struct mdp_device *mdp_dev, struct fb_info *fb,
if (unlikely(get_img(&req->dst, fb, &dst_start, &dst_len, &dst_file))) {
printk(KERN_ERR "mpd_ppp: could not retrieve dst image from "
"memory\n");
-#ifdef CONFIG_ANDROID_PMEM
- put_pmem_file(src_file);
-#endif
return -EINVAL;
}
mutex_lock(&mdp_mutex);
@@ -499,7 +482,6 @@ int mdp_probe(struct platform_device *pdev)
/* register mdp device */
mdp->mdp_dev.dev.parent = &pdev->dev;
mdp->mdp_dev.dev.class = mdp_class;
- snprintf(mdp->mdp_dev.dev.bus_id, BUS_ID_SIZE, "mdp%d", pdev->id);
/* if you can remove the platform device you'd have to implement
* this:
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c
index ba2c4673b64..4ff001f4cbb 100644
--- a/drivers/video/msm/mdp_ppp.c
+++ b/drivers/video/msm/mdp_ppp.c
@@ -16,7 +16,6 @@
#include <linux/file.h>
#include <linux/delay.h>
#include <linux/msm_mdp.h>
-#include <linux/android_pmem.h>
#include <mach/msm_fb.h>
#include "mdp_hw.h"
@@ -579,25 +578,6 @@ static int valid_src_dst(unsigned long src_start, unsigned long src_len,
static void flush_imgs(struct mdp_blit_req *req, struct mdp_regs *regs,
struct file *src_file, struct file *dst_file)
{
-#ifdef CONFIG_ANDROID_PMEM
- uint32_t src0_len, src1_len, dst0_len, dst1_len;
-
- /* flush src images to memory before dma to mdp */
- get_len(&req->src, &req->src_rect, regs->src_bpp, &src0_len,
- &src1_len);
- flush_pmem_file(src_file, req->src.offset, src0_len);
- if (IS_PSEUDOPLNR(req->src.format))
- flush_pmem_file(src_file, req->src.offset + src0_len,
- src1_len);
-
- /* flush dst images */
- get_len(&req->dst, &req->dst_rect, regs->dst_bpp, &dst0_len,
- &dst1_len);
- flush_pmem_file(dst_file, req->dst.offset, dst0_len);
- if (IS_PSEUDOPLNR(req->dst.format))
- flush_pmem_file(dst_file, req->dst.offset + dst0_len,
- dst1_len);
-#endif
}
static void get_chroma_addr(struct mdp_img *img, struct mdp_rect *rect,
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c
index d5e59556f9e..70dadf9d233 100644
--- a/drivers/video/omap/blizzard.c
+++ b/drivers/video/omap/blizzard.c
@@ -93,7 +93,7 @@ struct blizzard_reg_list {
};
/* These need to be saved / restored separately from the rest. */
-static struct blizzard_reg_list blizzard_pll_regs[] = {
+static const struct blizzard_reg_list blizzard_pll_regs[] = {
{
.start = 0x04, /* Don't save PLL ctrl (0x0C) */
.end = 0x0a,
@@ -104,7 +104,7 @@ static struct blizzard_reg_list blizzard_pll_regs[] = {
},
};
-static struct blizzard_reg_list blizzard_gen_regs[] = {
+static const struct blizzard_reg_list blizzard_gen_regs[] = {
{
.start = 0x18, /* SDRAM control */
.end = 0x20,
@@ -191,7 +191,7 @@ struct blizzard_struct {
struct omapfb_device *fbdev;
struct lcd_ctrl_extif *extif;
- struct lcd_ctrl *int_ctrl;
+ const struct lcd_ctrl *int_ctrl;
void (*power_up)(struct device *dev);
void (*power_down)(struct device *dev);
@@ -1372,7 +1372,7 @@ static void blizzard_get_caps(int plane, struct omapfb_caps *caps)
(1 << OMAPFB_COLOR_YUV420);
}
-static void _save_regs(struct blizzard_reg_list *list, int cnt)
+static void _save_regs(const struct blizzard_reg_list *list, int cnt)
{
int i;
@@ -1383,7 +1383,7 @@ static void _save_regs(struct blizzard_reg_list *list, int cnt)
}
}
-static void _restore_regs(struct blizzard_reg_list *list, int cnt)
+static void _restore_regs(const struct blizzard_reg_list *list, int cnt)
{
int i;
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index 80a11d078df..f16e4215422 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -1035,7 +1035,7 @@ static void mmap_user_close(struct vm_area_struct *vma)
atomic_dec(&dispc.map_count[plane]);
}
-static struct vm_operations_struct mmap_user_ops = {
+static const struct vm_operations_struct mmap_user_ops = {
.open = mmap_user_open,
.close = mmap_user_close,
};
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 125e605b8c6..0d0c8c8b9b5 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -393,7 +393,7 @@ static void omapfb_sync(struct fb_info *fbi)
* Set fb_info.fix fields and also updates fbdev.
* When calling this fb_info.var must be set up already.
*/
-static void set_fb_fix(struct fb_info *fbi)
+static void set_fb_fix(struct fb_info *fbi, int from_init)
{
struct fb_fix_screeninfo *fix = &fbi->fix;
struct fb_var_screeninfo *var = &fbi->var;
@@ -403,10 +403,16 @@ static void set_fb_fix(struct fb_info *fbi)
rg = &plane->fbdev->mem_desc.region[plane->idx];
fbi->screen_base = rg->vaddr;
- mutex_lock(&fbi->mm_lock);
- fix->smem_start = rg->paddr;
- fix->smem_len = rg->size;
- mutex_unlock(&fbi->mm_lock);
+
+ if (!from_init) {
+ mutex_lock(&fbi->mm_lock);
+ fix->smem_start = rg->paddr;
+ fix->smem_len = rg->size;
+ mutex_unlock(&fbi->mm_lock);
+ } else {
+ fix->smem_start = rg->paddr;
+ fix->smem_len = rg->size;
+ }
fix->type = FB_TYPE_PACKED_PIXELS;
bpp = var->bits_per_pixel;
@@ -704,7 +710,7 @@ static int omapfb_set_par(struct fb_info *fbi)
int r = 0;
omapfb_rqueue_lock(fbdev);
- set_fb_fix(fbi);
+ set_fb_fix(fbi, 0);
r = ctrl_change_mode(fbi);
omapfb_rqueue_unlock(fbdev);
@@ -904,7 +910,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
if (old_size != size) {
if (size) {
memcpy(&fbi->var, new_var, sizeof(fbi->var));
- set_fb_fix(fbi);
+ set_fb_fix(fbi, 0);
} else {
/*
* Set these explicitly to indicate that the
@@ -1504,7 +1510,7 @@ static int fbinfo_init(struct omapfb_device *fbdev, struct fb_info *info)
var->bits_per_pixel = fbdev->panel->bpp;
set_fb_var(info, var);
- set_fb_fix(info);
+ set_fb_fix(info, 1);
r = fb_alloc_cmap(&info->cmap, 16, 0);
if (r != 0)
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 6506117c134..1820c4a2443 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -1638,24 +1638,26 @@ pxafb_freq_policy(struct notifier_block *nb, unsigned long val, void *data)
* Power management hooks. Note that we won't be called from IRQ context,
* unlike the blank functions above, so we may sleep.
*/
-static int pxafb_suspend(struct platform_device *dev, pm_message_t state)
+static int pxafb_suspend(struct device *dev)
{
- struct pxafb_info *fbi = platform_get_drvdata(dev);
+ struct pxafb_info *fbi = dev_get_drvdata(dev);
set_ctrlr_state(fbi, C_DISABLE_PM);
return 0;
}
-static int pxafb_resume(struct platform_device *dev)
+static int pxafb_resume(struct device *dev)
{
- struct pxafb_info *fbi = platform_get_drvdata(dev);
+ struct pxafb_info *fbi = dev_get_drvdata(dev);
set_ctrlr_state(fbi, C_ENABLE_PM);
return 0;
}
-#else
-#define pxafb_suspend NULL
-#define pxafb_resume NULL
+
+static struct dev_pm_ops pxafb_pm_ops = {
+ .suspend = pxafb_suspend,
+ .resume = pxafb_resume,
+};
#endif
static int __devinit pxafb_init_video_memory(struct pxafb_info *fbi)
@@ -2081,6 +2083,9 @@ static int __devinit pxafb_probe(struct platform_device *dev)
goto failed;
}
+ if (cpu_is_pxa3xx() && inf->acceleration_enabled)
+ fbi->fb.fix.accel = FB_ACCEL_PXA3XX;
+
fbi->backlight_power = inf->pxafb_backlight_power;
fbi->lcd_power = inf->pxafb_lcd_power;
@@ -2091,14 +2096,14 @@ static int __devinit pxafb_probe(struct platform_device *dev)
goto failed_fbi;
}
- r = request_mem_region(r->start, r->end - r->start + 1, dev->name);
+ r = request_mem_region(r->start, resource_size(r), dev->name);
if (r == NULL) {
dev_err(&dev->dev, "failed to request I/O memory\n");
ret = -EBUSY;
goto failed_fbi;
}
- fbi->mmio_base = ioremap(r->start, r->end - r->start + 1);
+ fbi->mmio_base = ioremap(r->start, resource_size(r));
if (fbi->mmio_base == NULL) {
dev_err(&dev->dev, "failed to map I/O memory\n");
ret = -EBUSY;
@@ -2197,7 +2202,7 @@ failed_free_dma:
failed_free_io:
iounmap(fbi->mmio_base);
failed_free_res:
- release_mem_region(r->start, r->end - r->start + 1);
+ release_mem_region(r->start, resource_size(r));
failed_fbi:
clk_put(fbi->clk);
platform_set_drvdata(dev, NULL);
@@ -2237,7 +2242,7 @@ static int __devexit pxafb_remove(struct platform_device *dev)
iounmap(fbi->mmio_base);
r = platform_get_resource(dev, IORESOURCE_MEM, 0);
- release_mem_region(r->start, r->end - r->start + 1);
+ release_mem_region(r->start, resource_size(r));
clk_put(fbi->clk);
kfree(fbi);
@@ -2248,11 +2253,12 @@ static int __devexit pxafb_remove(struct platform_device *dev)
static struct platform_driver pxafb_driver = {
.probe = pxafb_probe,
.remove = __devexit_p(pxafb_remove),
- .suspend = pxafb_suspend,
- .resume = pxafb_resume,
.driver = {
.owner = THIS_MODULE,
.name = "pxa2xx-fb",
+#ifdef CONFIG_PM
+ .pm = &pxafb_pm_ops,
+#endif
},
};
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 37b135d5d12..842d157e102 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -1565,7 +1565,7 @@ static int savagefb_blank(int blank, struct fb_info *info)
vga_out8(0x3c5, sr8, par);
vga_out8(0x3c4, 0x0d, par);
srd = vga_in8(0x3c5, par);
- srd &= 0x03;
+ srd &= 0x50;
switch (blank) {
case FB_BLANK_UNBLANK:
@@ -1606,22 +1606,6 @@ static int savagefb_blank(int blank, struct fb_info *info)
return (blank == FB_BLANK_NORMAL) ? 1 : 0;
}
-static void savagefb_save_state(struct fb_info *info)
-{
- struct savagefb_par *par = info->par;
-
- savage_get_default_par(par, &par->save);
-}
-
-static void savagefb_restore_state(struct fb_info *info)
-{
- struct savagefb_par *par = info->par;
-
- savagefb_blank(FB_BLANK_POWERDOWN, info);
- savage_set_default_par(par, &par->save);
- savagefb_blank(FB_BLANK_UNBLANK, info);
-}
-
static int savagefb_open(struct fb_info *info, int user)
{
struct savagefb_par *par = info->par;
@@ -1667,8 +1651,6 @@ static struct fb_ops savagefb_ops = {
.fb_setcolreg = savagefb_setcolreg,
.fb_pan_display = savagefb_pan_display,
.fb_blank = savagefb_blank,
- .fb_save_state = savagefb_save_state,
- .fb_restore_state = savagefb_restore_state,
#if defined(CONFIG_FB_SAVAGE_ACCEL)
.fb_fillrect = savagefb_fillrect,
.fb_copyarea = savagefb_copyarea,
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index e35232a1857..54fbb2995a5 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -1411,23 +1411,6 @@ static int uvesafb_check_var(struct fb_var_screeninfo *var,
return 0;
}
-static void uvesafb_save_state(struct fb_info *info)
-{
- struct uvesafb_par *par = info->par;
-
- if (par->vbe_state_saved)
- kfree(par->vbe_state_saved);
-
- par->vbe_state_saved = uvesafb_vbe_state_save(par);
-}
-
-static void uvesafb_restore_state(struct fb_info *info)
-{
- struct uvesafb_par *par = info->par;
-
- uvesafb_vbe_state_restore(par, par->vbe_state_saved);
-}
-
static struct fb_ops uvesafb_ops = {
.owner = THIS_MODULE,
.fb_open = uvesafb_open,
@@ -1441,8 +1424,6 @@ static struct fb_ops uvesafb_ops = {
.fb_imageblit = cfb_imageblit,
.fb_check_var = uvesafb_check_var,
.fb_set_par = uvesafb_set_par,
- .fb_save_state = uvesafb_save_state,
- .fb_restore_state = uvesafb_restore_state,
};
static void __devinit uvesafb_init_info(struct fb_info *info,
@@ -1459,15 +1440,6 @@ static void __devinit uvesafb_init_info(struct fb_info *info,
info->fix.ypanstep = par->ypan ? 1 : 0;
info->fix.ywrapstep = (par->ypan > 1) ? 1 : 0;
- /*
- * If we were unable to get the state buffer size, disable
- * functions for saving and restoring the hardware state.
- */
- if (par->vbe_state_size == 0) {
- info->fbops->fb_save_state = NULL;
- info->fbops->fb_restore_state = NULL;
- }
-
/* Disable blanking if the user requested so. */
if (!blank)
info->fbops->fb_blank = NULL;