diff options
author | Jiri Kosina <jkosina@suse.cz> | 2014-11-20 14:42:02 +0100 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2014-11-20 14:42:02 +0100 |
commit | a02001086bbfb4da35d1228bebc2f1b442db455f (patch) | |
tree | 62ab47936cef06fd08657ca5b6cd1df98c19be57 /drivers/video | |
parent | eff264efeeb0898408e8c9df72d8a32621035bed (diff) | |
parent | fc14f9c1272f62c3e8d01300f52467c0d9af50f9 (diff) | |
download | op-kernel-dev-a02001086bbfb4da35d1228bebc2f1b442db455f.zip op-kernel-dev-a02001086bbfb4da35d1228bebc2f1b442db455f.tar.gz |
Merge Linus' tree to be be to apply submitted patches to newer code than
current trivial.git base
Diffstat (limited to 'drivers/video')
134 files changed, 1913 insertions, 1630 deletions
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c index a6f7cc0..9a23698 100644 --- a/drivers/video/backlight/88pm860x_bl.c +++ b/drivers/video/backlight/88pm860x_bl.c @@ -265,7 +265,6 @@ static int pm860x_backlight_probe(struct platform_device *pdev) static struct platform_driver pm860x_backlight_driver = { .driver = { .name = "88pm860x-backlight", - .owner = THIS_MODULE, }, .probe = pm860x_backlight_probe, }; diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 5d44905..8d03924 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -178,17 +178,6 @@ config BACKLIGHT_ATMEL_LCDC If in doubt, it's safe to enable this option; it doesn't kick in unless the board's description says it's wired that way. -config BACKLIGHT_ATMEL_PWM - tristate "Atmel PWM backlight control" - depends on ATMEL_PWM - help - Say Y here if you want to use the PWM peripheral in Atmel AT91 and - AVR32 devices. This driver will need additional platform data to know - which PWM instance to use and how to configure it. - - To compile this driver as a module, choose M here: the module will be - called atmel-pwm-bl. - config BACKLIGHT_EP93XX tristate "Cirrus EP93xx Backlight Driver" depends on FB_EP93XX @@ -207,6 +196,15 @@ config BACKLIGHT_GENERIC known as the Corgi backlight driver. If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y. +config BACKLIGHT_IPAQ_MICRO + tristate "iPAQ microcontroller backlight driver" + depends on MFD_IPAQ_MICRO + default y + help + Say y to enable the backlight driver for Compaq iPAQ handheld + computers. Say yes if you have one of the h3100/h3600/h3700 + machines. + config BACKLIGHT_LM3533 tristate "Backlight Driver for LM3533" depends on BACKLIGHT_CLASS_DEVICE diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index bb82002..fcd50b73 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o obj-$(CONFIG_BACKLIGHT_AS3711) += as3711_bl.o -obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o obj-$(CONFIG_BACKLIGHT_BD6107) += bd6107.o obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o @@ -36,6 +35,7 @@ obj-$(CONFIG_BACKLIGHT_GENERIC) += generic_bl.o obj-$(CONFIG_BACKLIGHT_GPIO) += gpio_backlight.o obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o +obj-$(CONFIG_BACKLIGHT_IPAQ_MICRO) += ipaq_micro_bl.o obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o obj-$(CONFIG_BACKLIGHT_LM3630A) += lm3630a_bl.o obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o diff --git a/drivers/video/backlight/aat2870_bl.c b/drivers/video/backlight/aat2870_bl.c index ec5350f..50774e6 100644 --- a/drivers/video/backlight/aat2870_bl.c +++ b/drivers/video/backlight/aat2870_bl.c @@ -67,11 +67,6 @@ static inline int aat2870_bl_disable(struct aat2870_bl_driver_data *aat2870_bl) return aat2870->write(aat2870, AAT2870_BL_CH_EN, 0x0); } -static int aat2870_bl_get_brightness(struct backlight_device *bd) -{ - return bd->props.brightness; -} - static int aat2870_bl_update_status(struct backlight_device *bd) { struct aat2870_bl_driver_data *aat2870_bl = bl_get_data(bd); @@ -120,7 +115,6 @@ static int aat2870_bl_check_fb(struct backlight_device *bd, struct fb_info *fi) static const struct backlight_ops aat2870_bl_ops = { .options = BL_CORE_SUSPENDRESUME, - .get_brightness = aat2870_bl_get_brightness, .update_status = aat2870_bl_update_status, .check_fb = aat2870_bl_check_fb, }; @@ -217,7 +211,6 @@ static int aat2870_bl_remove(struct platform_device *pdev) static struct platform_driver aat2870_bl_driver = { .driver = { .name = "aat2870-backlight", - .owner = THIS_MODULE, }, .probe = aat2870_bl_probe, .remove = aat2870_bl_remove, diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c index f37097a..dd88ba1 100644 --- a/drivers/video/backlight/adp5520_bl.c +++ b/drivers/video/backlight/adp5520_bl.c @@ -67,6 +67,7 @@ static int adp5520_bl_set(struct backlight_device *bl, int brightness) static int adp5520_bl_update_status(struct backlight_device *bl) { int brightness = bl->props.brightness; + if (bl->props.power != FB_BLANK_UNBLANK) brightness = 0; @@ -374,7 +375,6 @@ static SIMPLE_DEV_PM_OPS(adp5520_bl_pm_ops, adp5520_bl_suspend, static struct platform_driver adp5520_bl_driver = { .driver = { .name = "adp5520-backlight", - .owner = THIS_MODULE, .pm = &adp5520_bl_pm_ops, }, .probe = adp5520_bl_probe, diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c index be8d83d..71147f4 100644 --- a/drivers/video/backlight/adp8860_bl.c +++ b/drivers/video/backlight/adp8860_bl.c @@ -181,6 +181,7 @@ static int adp8860_clr_bits(struct i2c_client *client, int reg, uint8_t bit_mask static void adp8860_led_work(struct work_struct *work) { struct adp8860_led *led = container_of(work, struct adp8860_led, work); + adp8860_write(led->client, ADP8860_ISC1 - led->id + 1, led->new_brightness >> 1); } @@ -362,6 +363,7 @@ static int adp8860_bl_set(struct backlight_device *bl, int brightness) static int adp8860_bl_update_status(struct backlight_device *bl) { int brightness = bl->props.brightness; + if (bl->props.power != FB_BLANK_UNBLANK) brightness = 0; @@ -499,6 +501,7 @@ static ssize_t adp8860_bl_l1_daylight_max_store(struct device *dev, { struct adp8860_bl *data = dev_get_drvdata(dev); int ret = kstrtoul(buf, 10, &data->cached_daylight_max); + if (ret) return ret; diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c index 251af4d..037e430 100644 --- a/drivers/video/backlight/adp8870_bl.c +++ b/drivers/video/backlight/adp8870_bl.c @@ -144,6 +144,7 @@ static int adp8870_read(struct i2c_client *client, int reg, uint8_t *val) static int adp8870_write(struct i2c_client *client, u8 reg, u8 val) { int ret = i2c_smbus_write_byte_data(client, reg, val); + if (ret) dev_err(&client->dev, "failed to write\n"); @@ -195,6 +196,7 @@ static int adp8870_clr_bits(struct i2c_client *client, int reg, uint8_t bit_mask static void adp8870_led_work(struct work_struct *work) { struct adp8870_led *led = container_of(work, struct adp8870_led, work); + adp8870_write(led->client, ADP8870_ISC1 + led->id - 1, led->new_brightness >> 1); } @@ -399,6 +401,7 @@ static int adp8870_bl_set(struct backlight_device *bl, int brightness) static int adp8870_bl_update_status(struct backlight_device *bl) { int brightness = bl->props.brightness; + if (bl->props.power != FB_BLANK_UNBLANK) brightness = 0; @@ -649,6 +652,7 @@ static ssize_t adp8870_bl_l1_daylight_max_store(struct device *dev, { struct adp8870_bl *data = dev_get_drvdata(dev); int ret = kstrtoul(buf, 10, &data->cached_daylight_max); + if (ret) return ret; diff --git a/drivers/video/backlight/ams369fg06.c b/drivers/video/backlight/ams369fg06.c index d8952c4..5f897f9 100644 --- a/drivers/video/backlight/ams369fg06.c +++ b/drivers/video/backlight/ams369fg06.c @@ -325,11 +325,11 @@ static int ams369fg06_power_on(struct ams369fg06 *lcd) if (!pd->reset) { dev_err(lcd->dev, "reset is NULL.\n"); return -EINVAL; - } else { - pd->reset(lcd->ld); - msleep(pd->reset_delay); } + pd->reset(lcd->ld); + msleep(pd->reset_delay); + ret = ams369fg06_ldi_init(lcd); if (ret) { dev_err(lcd->dev, "failed to initialize ldi.\n"); @@ -410,11 +410,6 @@ static int ams369fg06_set_power(struct lcd_device *ld, int power) return ams369fg06_power(lcd, power); } -static int ams369fg06_get_brightness(struct backlight_device *bd) -{ - return bd->props.brightness; -} - static int ams369fg06_set_brightness(struct backlight_device *bd) { int ret = 0; @@ -443,7 +438,6 @@ static struct lcd_ops ams369fg06_lcd_ops = { }; static const struct backlight_ops ams369fg06_backlight_ops = { - .get_brightness = ams369fg06_get_brightness, .update_status = ams369fg06_set_brightness, }; diff --git a/drivers/video/backlight/as3711_bl.c b/drivers/video/backlight/as3711_bl.c index bb1fc45..734a915 100644 --- a/drivers/video/backlight/as3711_bl.c +++ b/drivers/video/backlight/as3711_bl.c @@ -467,7 +467,6 @@ static int as3711_backlight_probe(struct platform_device *pdev) static struct platform_driver as3711_backlight_driver = { .driver = { .name = "as3711-backlight", - .owner = THIS_MODULE, }, .probe = as3711_backlight_probe, }; diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c deleted file mode 100644 index 261b1a4..0000000 --- a/drivers/video/backlight/atmel-pwm-bl.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (C) 2008 Atmel Corporation - * - * Backlight driver using Atmel PWM peripheral. - * - * 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/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/fb.h> -#include <linux/gpio.h> -#include <linux/backlight.h> -#include <linux/atmel_pwm.h> -#include <linux/atmel-pwm-bl.h> -#include <linux/slab.h> - -struct atmel_pwm_bl { - const struct atmel_pwm_bl_platform_data *pdata; - struct backlight_device *bldev; - struct platform_device *pdev; - struct pwm_channel pwmc; - int gpio_on; -}; - -static void atmel_pwm_bl_set_gpio_on(struct atmel_pwm_bl *pwmbl, int on) -{ - if (!gpio_is_valid(pwmbl->gpio_on)) - return; - - gpio_set_value(pwmbl->gpio_on, on ^ pwmbl->pdata->on_active_low); -} - -static int atmel_pwm_bl_set_intensity(struct backlight_device *bd) -{ - struct atmel_pwm_bl *pwmbl = bl_get_data(bd); - int intensity = bd->props.brightness; - int pwm_duty; - - if (bd->props.power != FB_BLANK_UNBLANK) - intensity = 0; - if (bd->props.fb_blank != FB_BLANK_UNBLANK) - intensity = 0; - - if (pwmbl->pdata->pwm_active_low) - pwm_duty = pwmbl->pdata->pwm_duty_min + intensity; - else - pwm_duty = pwmbl->pdata->pwm_duty_max - intensity; - - if (pwm_duty > pwmbl->pdata->pwm_duty_max) - pwm_duty = pwmbl->pdata->pwm_duty_max; - if (pwm_duty < pwmbl->pdata->pwm_duty_min) - pwm_duty = pwmbl->pdata->pwm_duty_min; - - if (!intensity) { - atmel_pwm_bl_set_gpio_on(pwmbl, 0); - pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty); - pwm_channel_disable(&pwmbl->pwmc); - } else { - pwm_channel_enable(&pwmbl->pwmc); - pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty); - atmel_pwm_bl_set_gpio_on(pwmbl, 1); - } - - return 0; -} - -static int atmel_pwm_bl_get_intensity(struct backlight_device *bd) -{ - struct atmel_pwm_bl *pwmbl = bl_get_data(bd); - u32 cdty; - u32 intensity; - - cdty = pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY); - if (pwmbl->pdata->pwm_active_low) - intensity = cdty - pwmbl->pdata->pwm_duty_min; - else - intensity = pwmbl->pdata->pwm_duty_max - cdty; - - return intensity & 0xffff; -} - -static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl) -{ - unsigned long pwm_rate = pwmbl->pwmc.mck; - unsigned long prescale = DIV_ROUND_UP(pwm_rate, - (pwmbl->pdata->pwm_frequency * - pwmbl->pdata->pwm_compare_max)) - 1; - - /* - * Prescale must be power of two and maximum 0xf in size because of - * hardware limit. PWM speed will be: - * PWM module clock speed / (2 ^ prescale). - */ - prescale = fls(prescale); - if (prescale > 0xf) - prescale = 0xf; - - pwm_channel_writel(&pwmbl->pwmc, PWM_CMR, prescale); - pwm_channel_writel(&pwmbl->pwmc, PWM_CDTY, - pwmbl->pdata->pwm_duty_min + - pwmbl->bldev->props.brightness); - pwm_channel_writel(&pwmbl->pwmc, PWM_CPRD, - pwmbl->pdata->pwm_compare_max); - - dev_info(&pwmbl->pdev->dev, "Atmel PWM backlight driver (%lu Hz)\n", - pwmbl->pwmc.mck / pwmbl->pdata->pwm_compare_max / - (1 << prescale)); - - return pwm_channel_enable(&pwmbl->pwmc); -} - -static const struct backlight_ops atmel_pwm_bl_ops = { - .get_brightness = atmel_pwm_bl_get_intensity, - .update_status = atmel_pwm_bl_set_intensity, -}; - -static int atmel_pwm_bl_probe(struct platform_device *pdev) -{ - struct backlight_properties props; - const struct atmel_pwm_bl_platform_data *pdata; - struct backlight_device *bldev; - struct atmel_pwm_bl *pwmbl; - unsigned long flags; - int retval; - - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) - return -ENODEV; - - if (pdata->pwm_compare_max < pdata->pwm_duty_max || - pdata->pwm_duty_min > pdata->pwm_duty_max || - pdata->pwm_frequency == 0) - return -EINVAL; - - pwmbl = devm_kzalloc(&pdev->dev, sizeof(struct atmel_pwm_bl), - GFP_KERNEL); - if (!pwmbl) - return -ENOMEM; - - pwmbl->pdev = pdev; - pwmbl->pdata = pdata; - pwmbl->gpio_on = pdata->gpio_on; - - retval = pwm_channel_alloc(pdata->pwm_channel, &pwmbl->pwmc); - if (retval) - return retval; - - if (gpio_is_valid(pwmbl->gpio_on)) { - /* Turn display off by default. */ - if (pdata->on_active_low) - flags = GPIOF_OUT_INIT_HIGH; - else - flags = GPIOF_OUT_INIT_LOW; - - retval = devm_gpio_request_one(&pdev->dev, pwmbl->gpio_on, - flags, "gpio_atmel_pwm_bl"); - if (retval) - goto err_free_pwm; - } - - memset(&props, 0, sizeof(struct backlight_properties)); - props.type = BACKLIGHT_RAW; - props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min; - bldev = devm_backlight_device_register(&pdev->dev, "atmel-pwm-bl", - &pdev->dev, pwmbl, &atmel_pwm_bl_ops, - &props); - if (IS_ERR(bldev)) { - retval = PTR_ERR(bldev); - goto err_free_pwm; - } - - pwmbl->bldev = bldev; - - platform_set_drvdata(pdev, pwmbl); - - /* Power up the backlight by default at middle intesity. */ - bldev->props.power = FB_BLANK_UNBLANK; - bldev->props.brightness = bldev->props.max_brightness / 2; - - retval = atmel_pwm_bl_init_pwm(pwmbl); - if (retval) - goto err_free_pwm; - - atmel_pwm_bl_set_intensity(bldev); - - return 0; - -err_free_pwm: - pwm_channel_free(&pwmbl->pwmc); - - return retval; -} - -static int atmel_pwm_bl_remove(struct platform_device *pdev) -{ - struct atmel_pwm_bl *pwmbl = platform_get_drvdata(pdev); - - atmel_pwm_bl_set_gpio_on(pwmbl, 0); - pwm_channel_disable(&pwmbl->pwmc); - pwm_channel_free(&pwmbl->pwmc); - - return 0; -} - -static struct platform_driver atmel_pwm_bl_driver = { - .driver = { - .name = "atmel-pwm-bl", - }, - /* REVISIT add suspend() and resume() */ - .probe = atmel_pwm_bl_probe, - .remove = atmel_pwm_bl_remove, -}; - -module_platform_driver(atmel_pwm_bl_driver); - -MODULE_AUTHOR("Hans-Christian egtvedt <hans-christian.egtvedt@atmel.com>"); -MODULE_DESCRIPTION("Atmel PWM backlight driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:atmel-pwm-bl"); diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 4280890..bddc8b1 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -223,6 +223,8 @@ static ssize_t actual_brightness_show(struct device *dev, mutex_lock(&bd->ops_lock); if (bd->ops && bd->ops->get_brightness) rc = sprintf(buf, "%d\n", bd->ops->get_brightness(bd)); + else + rc = sprintf(buf, "%d\n", bd->props.brightness); mutex_unlock(&bd->ops_lock); return rc; diff --git a/drivers/video/backlight/bd6107.c b/drivers/video/backlight/bd6107.c index 16dd9bc..fdb2f7e 100644 --- a/drivers/video/backlight/bd6107.c +++ b/drivers/video/backlight/bd6107.c @@ -105,11 +105,6 @@ static int bd6107_backlight_update_status(struct backlight_device *backlight) return 0; } -static int bd6107_backlight_get_brightness(struct backlight_device *backlight) -{ - return backlight->props.brightness; -} - static int bd6107_backlight_check_fb(struct backlight_device *backlight, struct fb_info *info) { @@ -121,7 +116,6 @@ static int bd6107_backlight_check_fb(struct backlight_device *backlight, static const struct backlight_ops bd6107_backlight_ops = { .options = BL_CORE_SUSPENDRESUME, .update_status = bd6107_backlight_update_status, - .get_brightness = bd6107_backlight_get_brightness, .check_fb = bd6107_backlight_check_fb, }; diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c index 51d18d6..d7c37a8 100644 --- a/drivers/video/backlight/corgi_lcd.c +++ b/drivers/video/backlight/corgi_lcd.c @@ -143,6 +143,7 @@ static void lcdtg_i2c_send_byte(struct corgi_lcd *lcd, uint8_t base, uint8_t data) { int i; + for (i = 0; i < 8; i++) { if (data & 0x80) lcdtg_i2c_send_bit(lcd, base | POWER0_COM_DOUT); diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c index f3fed9e..3e3880f 100644 --- a/drivers/video/backlight/cr_bllcd.c +++ b/drivers/video/backlight/cr_bllcd.c @@ -235,6 +235,7 @@ static int cr_backlight_probe(struct platform_device *pdev) static int cr_backlight_remove(struct platform_device *pdev) { struct cr_panel *crp = platform_get_drvdata(pdev); + crp->cr_backlight_device->props.power = FB_BLANK_POWERDOWN; crp->cr_backlight_device->props.brightness = 0; crp->cr_backlight_device->props.max_brightness = 0; diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c index 12c5d84..f793738 100644 --- a/drivers/video/backlight/da903x_bl.c +++ b/drivers/video/backlight/da903x_bl.c @@ -162,7 +162,6 @@ static int da903x_backlight_probe(struct platform_device *pdev) static struct platform_driver da903x_backlight_driver = { .driver = { .name = "da903x-backlight", - .owner = THIS_MODULE, }, .probe = da903x_backlight_probe, }; diff --git a/drivers/video/backlight/da9052_bl.c b/drivers/video/backlight/da9052_bl.c index 20d55be..d4bd74bd 100644 --- a/drivers/video/backlight/da9052_bl.c +++ b/drivers/video/backlight/da9052_bl.c @@ -173,7 +173,6 @@ static struct platform_driver da9052_wled_driver = { .id_table = da9052_wled_ids, .driver = { .name = "da9052-wled", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/backlight/ep93xx_bl.c b/drivers/video/backlight/ep93xx_bl.c index 0d1f633..0067931 100644 --- a/drivers/video/backlight/ep93xx_bl.c +++ b/drivers/video/backlight/ep93xx_bl.c @@ -128,7 +128,6 @@ static SIMPLE_DEV_PM_OPS(ep93xxbl_pm_ops, ep93xxbl_suspend, ep93xxbl_resume); static struct platform_driver ep93xxbl_driver = { .driver = { .name = "ep93xx-bl", - .owner = THIS_MODULE, .pm = &ep93xxbl_pm_ops, }, .probe = ep93xxbl_probe, diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c index 5d8d652..67dfb93 100644 --- a/drivers/video/backlight/generic_bl.c +++ b/drivers/video/backlight/generic_bl.c @@ -52,24 +52,6 @@ static int genericbl_get_intensity(struct backlight_device *bd) return genericbl_intensity; } -/* - * Called when the battery is low to limit the backlight intensity. - * If limit==0 clear any limit, otherwise limit the intensity - */ -void genericbl_limit_intensity(int limit) -{ - struct backlight_device *bd = generic_backlight_device; - - mutex_lock(&bd->ops_lock); - if (limit) - bd->props.state |= GENERICBL_BATTLOW; - else - bd->props.state &= ~GENERICBL_BATTLOW; - backlight_update_status(generic_backlight_device); - mutex_unlock(&bd->ops_lock); -} -EXPORT_SYMBOL(genericbl_limit_intensity); - static const struct backlight_ops genericbl_ops = { .options = BL_CORE_SUSPENDRESUME, .get_brightness = genericbl_get_intensity, diff --git a/drivers/video/backlight/gpio_backlight.c b/drivers/video/backlight/gpio_backlight.c index 1cea688..439feb2 100644 --- a/drivers/video/backlight/gpio_backlight.c +++ b/drivers/video/backlight/gpio_backlight.c @@ -44,11 +44,6 @@ static int gpio_backlight_update_status(struct backlight_device *bl) return 0; } -static int gpio_backlight_get_brightness(struct backlight_device *bl) -{ - return bl->props.brightness; -} - static int gpio_backlight_check_fb(struct backlight_device *bl, struct fb_info *info) { @@ -60,7 +55,6 @@ static int gpio_backlight_check_fb(struct backlight_device *bl, static const struct backlight_ops gpio_backlight_ops = { .options = BL_CORE_SUSPENDRESUME, .update_status = gpio_backlight_update_status, - .get_brightness = gpio_backlight_get_brightness, .check_fb = gpio_backlight_check_fb, }; @@ -157,7 +151,6 @@ static struct of_device_id gpio_backlight_of_match[] = { static struct platform_driver gpio_backlight_driver = { .driver = { .name = "gpio-backlight", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(gpio_backlight_of_match), }, .probe = gpio_backlight_probe, diff --git a/drivers/video/backlight/ili922x.c b/drivers/video/backlight/ili922x.c index ea67fe1..e7f0890 100644 --- a/drivers/video/backlight/ili922x.c +++ b/drivers/video/backlight/ili922x.c @@ -495,17 +495,18 @@ static int ili922x_probe(struct spi_device *spi) "no LCD found: Chip ID 0x%x, ret %d\n", reg, ret); return -ENODEV; - } else { - dev_info(&spi->dev, "ILI%x found, SPI freq %d, mode %d\n", - reg, spi->max_speed_hz, spi->mode); } + dev_info(&spi->dev, "ILI%x found, SPI freq %d, mode %d\n", + reg, spi->max_speed_hz, spi->mode); + ret = ili922x_read_status(spi, ®); if (ret) { dev_err(&spi->dev, "reading RS failed...\n"); return ret; - } else - dev_dbg(&spi->dev, "status: 0x%x\n", reg); + } + + dev_dbg(&spi->dev, "status: 0x%x\n", reg); ili922x_display_init(spi); diff --git a/drivers/video/backlight/ipaq_micro_bl.c b/drivers/video/backlight/ipaq_micro_bl.c new file mode 100644 index 0000000..347dc11 --- /dev/null +++ b/drivers/video/backlight/ipaq_micro_bl.c @@ -0,0 +1,83 @@ +/* + * 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. + * + * iPAQ microcontroller backlight support + * Author : Linus Walleij <linus.walleij@linaro.org> + */ + +#include <linux/backlight.h> +#include <linux/err.h> +#include <linux/fb.h> +#include <linux/init.h> +#include <linux/mfd/ipaq-micro.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +static int micro_bl_update_status(struct backlight_device *bd) +{ + struct ipaq_micro *micro = dev_get_drvdata(&bd->dev); + int intensity = bd->props.brightness; + struct ipaq_micro_msg msg = { + .id = MSG_BACKLIGHT, + .tx_len = 3, + }; + + if (bd->props.power != FB_BLANK_UNBLANK) + intensity = 0; + if (bd->props.state & (BL_CORE_FBBLANK | BL_CORE_SUSPENDED)) + intensity = 0; + + /* + * Message format: + * Byte 0: backlight instance (usually 1) + * Byte 1: on/off + * Byte 2: intensity, 0-255 + */ + msg.tx_data[0] = 0x01; + msg.tx_data[1] = intensity > 0 ? 1 : 0; + msg.tx_data[2] = intensity; + return ipaq_micro_tx_msg_sync(micro, &msg); +} + +static const struct backlight_ops micro_bl_ops = { + .options = BL_CORE_SUSPENDRESUME, + .update_status = micro_bl_update_status, +}; + +static struct backlight_properties micro_bl_props = { + .type = BACKLIGHT_RAW, + .max_brightness = 255, + .power = FB_BLANK_UNBLANK, + .brightness = 64, +}; + +static int micro_backlight_probe(struct platform_device *pdev) +{ + struct backlight_device *bd; + struct ipaq_micro *micro = dev_get_drvdata(pdev->dev.parent); + + bd = devm_backlight_device_register(&pdev->dev, "ipaq-micro-backlight", + &pdev->dev, micro, µ_bl_ops, + µ_bl_props); + if (IS_ERR(bd)) + return PTR_ERR(bd); + + platform_set_drvdata(pdev, bd); + backlight_update_status(bd); + + return 0; +} + +static struct platform_driver micro_backlight_device_driver = { + .driver = { + .name = "ipaq-micro-backlight", + }, + .probe = micro_backlight_probe, +}; +module_platform_driver(micro_backlight_device_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("driver for iPAQ Atmel micro backlight"); +MODULE_ALIAS("platform:ipaq-micro-backlight"); diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c index 6ce96b4..7e6ff53 100644 --- a/drivers/video/backlight/jornada720_bl.c +++ b/drivers/video/backlight/jornada720_bl.c @@ -41,11 +41,11 @@ static int jornada_bl_get_brightness(struct backlight_device *bd) dev_err(&bd->dev, "get brightness timeout\n"); jornada_ssp_end(); return -ETIMEDOUT; - } else { - /* exchange txdummy for value */ - ret = jornada_ssp_byte(TXDUMMY); } + /* exchange txdummy for value */ + ret = jornada_ssp_byte(TXDUMMY); + jornada_ssp_end(); return BL_MAX_BRIGHT - ret; diff --git a/drivers/video/backlight/jornada720_lcd.c b/drivers/video/backlight/jornada720_lcd.c index da3876c..dfa0fa0 100644 --- a/drivers/video/backlight/jornada720_lcd.c +++ b/drivers/video/backlight/jornada720_lcd.c @@ -27,11 +27,7 @@ static int jornada_lcd_get_power(struct lcd_device *ld) { - /* LDD2 in PPC = LCD POWER */ - if (PPSR & PPC_LDD2) - return FB_BLANK_UNBLANK; /* PW ON */ - else - return FB_BLANK_POWERDOWN; /* PW OFF */ + return PPSR & PPC_LDD2 ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; } static int jornada_lcd_get_contrast(struct lcd_device *ld) @@ -43,37 +39,38 @@ static int jornada_lcd_get_contrast(struct lcd_device *ld) jornada_ssp_start(); - if (jornada_ssp_byte(GETCONTRAST) != TXDUMMY) { - dev_err(&ld->dev, "get contrast failed\n"); - jornada_ssp_end(); - return -ETIMEDOUT; - } else { + if (jornada_ssp_byte(GETCONTRAST) == TXDUMMY) { ret = jornada_ssp_byte(TXDUMMY); - jornada_ssp_end(); - return ret; + goto success; } + + dev_err(&ld->dev, "failed to set contrast\n"); + ret = -ETIMEDOUT; + +success: + jornada_ssp_end(); + return ret; } static int jornada_lcd_set_contrast(struct lcd_device *ld, int value) { - int ret; + int ret = 0; jornada_ssp_start(); /* start by sending our set contrast cmd to mcu */ - ret = jornada_ssp_byte(SETCONTRAST); - - /* push the new value */ - if (jornada_ssp_byte(value) != TXDUMMY) { - dev_err(&ld->dev, "set contrast failed\n"); - jornada_ssp_end(); - return -ETIMEDOUT; + if (jornada_ssp_byte(SETCONTRAST) == TXDUMMY) { + /* if successful push the new value */ + if (jornada_ssp_byte(value) == TXDUMMY) + goto success; } - /* if we get here we can assume everything went well */ - jornada_ssp_end(); + dev_err(&ld->dev, "failed to set contrast\n"); + ret = -ETIMEDOUT; - return 0; +success: + jornada_ssp_end(); + return ret; } static int jornada_lcd_set_power(struct lcd_device *ld, int power) diff --git a/drivers/video/backlight/ld9040.c b/drivers/video/backlight/ld9040.c index 506a6c2..f71eaf1 100644 --- a/drivers/video/backlight/ld9040.c +++ b/drivers/video/backlight/ld9040.c @@ -566,11 +566,11 @@ static int ld9040_power_on(struct ld9040 *lcd) if (!pd->reset) { dev_err(lcd->dev, "reset is NULL.\n"); return -EINVAL; - } else { - pd->reset(lcd->ld); - msleep(pd->reset_delay); } + pd->reset(lcd->ld); + msleep(pd->reset_delay); + ret = ld9040_ldi_init(lcd); if (ret) { dev_err(lcd->dev, "failed to initialize ldi.\n"); @@ -642,11 +642,6 @@ static int ld9040_get_power(struct lcd_device *ld) return lcd->power; } -static int ld9040_get_brightness(struct backlight_device *bd) -{ - return bd->props.brightness; -} - static int ld9040_set_brightness(struct backlight_device *bd) { int ret = 0, brightness = bd->props.brightness; @@ -674,7 +669,6 @@ static struct lcd_ops ld9040_lcd_ops = { }; static const struct backlight_ops ld9040_backlight_ops = { - .get_brightness = ld9040_get_brightness, .update_status = ld9040_set_brightness, }; diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c index cff1fbe..0e2337f 100644 --- a/drivers/video/backlight/lm3533_bl.c +++ b/drivers/video/backlight/lm3533_bl.c @@ -397,7 +397,6 @@ static void lm3533_bl_shutdown(struct platform_device *pdev) static struct platform_driver lm3533_bl_driver = { .driver = { .name = "lm3533-backlight", - .owner = THIS_MODULE, .pm = &lm3533_bl_pm_ops, }, .probe = lm3533_bl_probe, diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c index 5f36808..cd50df5 100644 --- a/drivers/video/backlight/lm3639_bl.c +++ b/drivers/video/backlight/lm3639_bl.c @@ -254,7 +254,6 @@ static void lm3639_torch_brightness_set(struct led_classdev *cdev, return; out: dev_err(pchip->dev, "i2c failed to access register\n"); - return; } /* flash */ @@ -293,7 +292,6 @@ static void lm3639_flash_brightness_set(struct led_classdev *cdev, return; out: dev_err(pchip->dev, "i2c failed to access register\n"); - return; } static const struct regmap_config lm3639_regmap = { diff --git a/drivers/video/backlight/lms501kf03.c b/drivers/video/backlight/lms501kf03.c index 77258b7..7e38103 100644 --- a/drivers/video/backlight/lms501kf03.c +++ b/drivers/video/backlight/lms501kf03.c @@ -232,19 +232,19 @@ static int lms501kf03_power_on(struct lms501kf03 *lcd) if (!pd->power_on) { dev_err(lcd->dev, "power_on is NULL.\n"); return -EINVAL; - } else { - pd->power_on(lcd->ld, 1); - msleep(pd->power_on_delay); } + pd->power_on(lcd->ld, 1); + msleep(pd->power_on_delay); + if (!pd->reset) { dev_err(lcd->dev, "reset is NULL.\n"); return -EINVAL; - } else { - pd->reset(lcd->ld); - msleep(pd->reset_delay); } + pd->reset(lcd->ld); + msleep(pd->reset_delay); + ret = lms501kf03_ldi_init(lcd); if (ret) { dev_err(lcd->dev, "failed to initialize ldi.\n"); diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c index 2ca3a04..25fb8e3 100644 --- a/drivers/video/backlight/lp855x_bl.c +++ b/drivers/video/backlight/lp855x_bl.c @@ -268,21 +268,16 @@ static int lp855x_bl_update_status(struct backlight_device *bl) } else if (lp->mode == REGISTER_BASED) { u8 val = bl->props.brightness; + lp855x_write_byte(lp, lp->cfg->reg_brightness, val); } return 0; } -static int lp855x_bl_get_brightness(struct backlight_device *bl) -{ - return bl->props.brightness; -} - static const struct backlight_ops lp855x_bl_ops = { .options = BL_CORE_SUSPENDRESUME, .update_status = lp855x_bl_update_status, - .get_brightness = lp855x_bl_get_brightness, }; static int lp855x_backlight_register(struct lp855x *lp) @@ -314,6 +309,7 @@ static ssize_t lp855x_get_chip_id(struct device *dev, struct device_attribute *attr, char *buf) { struct lp855x *lp = dev_get_drvdata(dev); + return scnprintf(buf, PAGE_SIZE, "%s\n", lp->chipname); } diff --git a/drivers/video/backlight/lp8788_bl.c b/drivers/video/backlight/lp8788_bl.c index daba34d..e418d5b 100644 --- a/drivers/video/backlight/lp8788_bl.c +++ b/drivers/video/backlight/lp8788_bl.c @@ -176,15 +176,9 @@ static int lp8788_bl_update_status(struct backlight_device *bl_dev) return 0; } -static int lp8788_bl_get_brightness(struct backlight_device *bl_dev) -{ - return bl_dev->props.brightness; -} - static const struct backlight_ops lp8788_bl_ops = { .options = BL_CORE_SUSPENDRESUME, .update_status = lp8788_bl_update_status, - .get_brightness = lp8788_bl_get_brightness, }; static int lp8788_backlight_register(struct lp8788_bl *bl) @@ -321,7 +315,6 @@ static struct platform_driver lp8788_bl_driver = { .remove = lp8788_backlight_remove, .driver = { .name = LP8788_DEV_BACKLIGHT, - .owner = THIS_MODULE, }, }; module_platform_driver(lp8788_bl_driver); diff --git a/drivers/video/backlight/lv5207lp.c b/drivers/video/backlight/lv5207lp.c index 1802b2d..8ab7297 100644 --- a/drivers/video/backlight/lv5207lp.c +++ b/drivers/video/backlight/lv5207lp.c @@ -70,11 +70,6 @@ static int lv5207lp_backlight_update_status(struct backlight_device *backlight) return 0; } -static int lv5207lp_backlight_get_brightness(struct backlight_device *backlight) -{ - return backlight->props.brightness; -} - static int lv5207lp_backlight_check_fb(struct backlight_device *backlight, struct fb_info *info) { @@ -86,7 +81,6 @@ static int lv5207lp_backlight_check_fb(struct backlight_device *backlight, static const struct backlight_ops lv5207lp_backlight_ops = { .options = BL_CORE_SUSPENDRESUME, .update_status = lv5207lp_backlight_update_status, - .get_brightness = lv5207lp_backlight_get_brightness, .check_fb = lv5207lp_backlight_check_fb, }; diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c index 66fa08c..7b738d6 100644 --- a/drivers/video/backlight/max8925_bl.c +++ b/drivers/video/backlight/max8925_bl.c @@ -197,7 +197,6 @@ static int max8925_backlight_probe(struct platform_device *pdev) static struct platform_driver max8925_backlight_driver = { .driver = { .name = "max8925-backlight", - .owner = THIS_MODULE, }, .probe = max8925_backlight_probe, }; diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c index a0dcd88..546d94d 100644 --- a/drivers/video/backlight/omap1_bl.c +++ b/drivers/video/backlight/omap1_bl.c @@ -120,6 +120,7 @@ static int omapbl_update_status(struct backlight_device *dev) static int omapbl_get_intensity(struct backlight_device *dev) { struct omap_backlight *bl = bl_get_data(dev); + return bl->current_intensity; } diff --git a/drivers/video/backlight/ot200_bl.c b/drivers/video/backlight/ot200_bl.c index f5a5202..3acdb9f 100644 --- a/drivers/video/backlight/ot200_bl.c +++ b/drivers/video/backlight/ot200_bl.c @@ -152,7 +152,6 @@ static int ot200_backlight_remove(struct platform_device *pdev) static struct platform_driver ot200_backlight_driver = { .driver = { .name = "ot200-backlight", - .owner = THIS_MODULE, }, .probe = ot200_backlight_probe, .remove = ot200_backlight_remove, diff --git a/drivers/video/backlight/pandora_bl.c b/drivers/video/backlight/pandora_bl.c index 2098c5d..5d8bb8b 100644 --- a/drivers/video/backlight/pandora_bl.c +++ b/drivers/video/backlight/pandora_bl.c @@ -100,15 +100,9 @@ done: return 0; } -static int pandora_backlight_get_brightness(struct backlight_device *bl) -{ - return bl->props.brightness; -} - static const struct backlight_ops pandora_backlight_ops = { .options = BL_CORE_SUSPENDRESUME, .update_status = pandora_backlight_update_status, - .get_brightness = pandora_backlight_get_brightness, }; static int pandora_backlight_probe(struct platform_device *pdev) @@ -148,7 +142,6 @@ static int pandora_backlight_probe(struct platform_device *pdev) static struct platform_driver pandora_backlight_driver = { .driver = { .name = "pandora-backlight", - .owner = THIS_MODULE, }, .probe = pandora_backlight_probe, }; diff --git a/drivers/video/backlight/pcf50633-backlight.c b/drivers/video/backlight/pcf50633-backlight.c index b95d3b0..85bd573 100644 --- a/drivers/video/backlight/pcf50633-backlight.c +++ b/drivers/video/backlight/pcf50633-backlight.c @@ -90,6 +90,7 @@ static int pcf50633_bl_update_status(struct backlight_device *bl) static int pcf50633_bl_get_brightness(struct backlight_device *bl) { struct pcf50633_bl *pcf_bl = bl_get_data(bl); + return pcf_bl->brightness; } diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c index c3d2e20..872a3bf 100644 --- a/drivers/video/backlight/platform_lcd.c +++ b/drivers/video/backlight/platform_lcd.c @@ -148,7 +148,6 @@ MODULE_DEVICE_TABLE(of, platform_lcd_of_match); static struct platform_driver platform_lcd_driver = { .driver = { .name = "platform-lcd", - .owner = THIS_MODULE, .pm = &platform_lcd_pm_ops, .of_match_table = of_match_ptr(platform_lcd_of_match), }, diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 38ca88b..cb5ae4c 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -115,11 +115,6 @@ static int pwm_backlight_update_status(struct backlight_device *bl) return 0; } -static int pwm_backlight_get_brightness(struct backlight_device *bl) -{ - return bl->props.brightness; -} - static int pwm_backlight_check_fb(struct backlight_device *bl, struct fb_info *info) { @@ -130,7 +125,6 @@ static int pwm_backlight_check_fb(struct backlight_device *bl, static const struct backlight_ops pwm_backlight_ops = { .update_status = pwm_backlight_update_status, - .get_brightness = pwm_backlight_get_brightness, .check_fb = pwm_backlight_check_fb, }; @@ -179,6 +173,7 @@ static int pwm_backlight_parse_dt(struct device *dev, data->max_brightness--; } + data->enable_gpio = -EINVAL; return 0; } @@ -245,13 +240,10 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->dev = &pdev->dev; pb->enabled = false; - pb->enable_gpio = devm_gpiod_get(&pdev->dev, "enable"); + pb->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable"); if (IS_ERR(pb->enable_gpio)) { ret = PTR_ERR(pb->enable_gpio); - if (ret == -ENOENT) - pb->enable_gpio = NULL; - else - goto err_alloc; + goto err_alloc; } /* @@ -398,7 +390,6 @@ static const struct dev_pm_ops pwm_backlight_pm_ops = { static struct platform_driver pwm_backlight_driver = { .driver = { .name = "pwm-backlight", - .owner = THIS_MODULE, .pm = &pwm_backlight_pm_ops, .of_match_table = of_match_ptr(pwm_backlight_of_match), }, diff --git a/drivers/video/backlight/s6e63m0.c b/drivers/video/backlight/s6e63m0.c index 2d6d481..28bfa12 100644 --- a/drivers/video/backlight/s6e63m0.c +++ b/drivers/video/backlight/s6e63m0.c @@ -507,19 +507,19 @@ static int s6e63m0_power_on(struct s6e63m0 *lcd) if (!pd->power_on) { dev_err(lcd->dev, "power_on is NULL.\n"); return -EINVAL; - } else { - pd->power_on(lcd->ld, 1); - msleep(pd->power_on_delay); } + pd->power_on(lcd->ld, 1); + msleep(pd->power_on_delay); + if (!pd->reset) { dev_err(lcd->dev, "reset is NULL.\n"); return -EINVAL; - } else { - pd->reset(lcd->ld); - msleep(pd->reset_delay); } + pd->reset(lcd->ld); + msleep(pd->reset_delay); + ret = s6e63m0_ldi_init(lcd); if (ret) { dev_err(lcd->dev, "failed to initialize ldi.\n"); @@ -597,11 +597,6 @@ static int s6e63m0_get_power(struct lcd_device *ld) return lcd->power; } -static int s6e63m0_get_brightness(struct backlight_device *bd) -{ - return bd->props.brightness; -} - static int s6e63m0_set_brightness(struct backlight_device *bd) { int ret = 0, brightness = bd->props.brightness; @@ -629,7 +624,6 @@ static struct lcd_ops s6e63m0_lcd_ops = { }; static const struct backlight_ops s6e63m0_backlight_ops = { - .get_brightness = s6e63m0_get_brightness, .update_status = s6e63m0_set_brightness, }; diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c index 908016f..30afce3 100644 --- a/drivers/video/backlight/tdo24m.c +++ b/drivers/video/backlight/tdo24m.c @@ -300,12 +300,14 @@ static int tdo24m_power(struct tdo24m *lcd, int power) static int tdo24m_set_power(struct lcd_device *ld, int power) { struct tdo24m *lcd = lcd_get_data(ld); + return tdo24m_power(lcd, power); } static int tdo24m_get_power(struct lcd_device *ld) { struct tdo24m *lcd = lcd_get_data(ld); + return lcd->power; } diff --git a/drivers/video/backlight/tps65217_bl.c b/drivers/video/backlight/tps65217_bl.c index 595dcf5..61d72bf 100644 --- a/drivers/video/backlight/tps65217_bl.c +++ b/drivers/video/backlight/tps65217_bl.c @@ -109,15 +109,9 @@ static int tps65217_bl_update_status(struct backlight_device *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, @@ -329,7 +323,6 @@ static int tps65217_bl_probe(struct platform_device *pdev) static struct platform_driver tps65217_bl_driver = { .probe = tps65217_bl_probe, .driver = { - .owner = THIS_MODULE, .name = "tps65217-bl", }, }; diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c index 8b9455e..6eab0d6 100644 --- a/drivers/video/backlight/wm831x_bl.c +++ b/drivers/video/backlight/wm831x_bl.c @@ -111,6 +111,7 @@ static int wm831x_backlight_update_status(struct backlight_device *bl) static int wm831x_backlight_get_brightness(struct backlight_device *bl) { struct wm831x_backlight_data *data = bl_get_data(bl); + return data->current_brightness; } @@ -217,7 +218,6 @@ static int wm831x_backlight_probe(struct platform_device *pdev) static struct platform_driver wm831x_backlight_driver = { .driver = { .name = "wm831x-backlight", - .owner = THIS_MODULE, }, .probe = wm831x_backlight_probe, }; diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c index 61b182b..dbfe4ee 100644 --- a/drivers/video/console/bitblit.c +++ b/drivers/video/console/bitblit.c @@ -205,7 +205,6 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, static void bit_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) { - int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; unsigned int cw = vc->vc_font.width; unsigned int ch = vc->vc_font.height; unsigned int rw = info->var.xres - (vc->vc_cols*cw); @@ -214,7 +213,7 @@ static void bit_clear_margins(struct vc_data *vc, struct fb_info *info, unsigned int bs = info->var.yres - bh; struct fb_fillrect region; - region.color = attr_bgcol_ec(bgshift, vc, info); + region.color = 0; region.rop = ROP_COPY; if (rw && !bottom_only) { diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 57b1d44..eb976ee 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -448,8 +448,10 @@ static int __init fb_console_setup(char *this_opt) return 1; while ((options = strsep(&this_opt, ",")) != NULL) { - if (!strncmp(options, "font:", 5)) + if (!strncmp(options, "font:", 5)) { strlcpy(fontname, options + 5, sizeof(fontname)); + continue; + } if (!strncmp(options, "scrollback:", 11)) { options += 11; @@ -457,13 +459,9 @@ static int __init fb_console_setup(char *this_opt) fbcon_softback_size = simple_strtoul(options, &options, 0); if (*options == 'k' || *options == 'K') { fbcon_softback_size *= 1024; - options++; } - if (*options != ',') - return 1; - options++; - } else - return 1; + } + continue; } if (!strncmp(options, "map:", 4)) { @@ -478,8 +476,7 @@ static int __init fb_console_setup(char *this_opt) fbcon_map_override(); } - - return 1; + continue; } if (!strncmp(options, "vc:", 3)) { @@ -491,7 +488,8 @@ static int __init fb_console_setup(char *this_opt) if (*options++ == '-') last_fb_vc = simple_strtoul(options, &options, 10) - 1; fbcon_is_default = 0; - } + continue; + } if (!strncmp(options, "rotate:", 7)) { options += 7; @@ -499,6 +497,7 @@ static int __init fb_console_setup(char *this_opt) initial_rotation = simple_strtoul(options, &options, 0); if (initial_rotation > 3) initial_rotation = 0; + continue; } } return 1; diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c index 41b32ae..5a3cbf6 100644 --- a/drivers/video/console/fbcon_ccw.c +++ b/drivers/video/console/fbcon_ccw.c @@ -197,9 +197,8 @@ static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info, unsigned int bh = info->var.xres - (vc->vc_rows*ch); unsigned int bs = vc->vc_rows*ch; struct fb_fillrect region; - int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; - region.color = attr_bgcol_ec(bgshift,vc,info); + region.color = 0; region.rop = ROP_COPY; if (rw && !bottom_only) { diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c index a93670e..e7ee44d 100644 --- a/drivers/video/console/fbcon_cw.c +++ b/drivers/video/console/fbcon_cw.c @@ -180,9 +180,8 @@ static void cw_clear_margins(struct vc_data *vc, struct fb_info *info, unsigned int bh = info->var.xres - (vc->vc_rows*ch); unsigned int rs = info->var.yres - rw; struct fb_fillrect region; - int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; - region.color = attr_bgcol_ec(bgshift,vc,info); + region.color = 0; region.rop = ROP_COPY; if (rw && !bottom_only) { diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c index ff0872c..19e3714 100644 --- a/drivers/video/console/fbcon_ud.c +++ b/drivers/video/console/fbcon_ud.c @@ -227,9 +227,8 @@ static void ud_clear_margins(struct vc_data *vc, struct fb_info *info, unsigned int rw = info->var.xres - (vc->vc_cols*cw); unsigned int bh = info->var.yres - (vc->vc_rows*ch); struct fb_fillrect region; - int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; - region.color = attr_bgcol_ec(bgshift,vc,info); + region.color = 0; region.rop = ROP_COPY; if (rw && !bottom_only) { diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 6e6aa70..517f565 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -56,7 +56,7 @@ static int cursor_size_lastfrom; static int cursor_size_lastto; static u32 vgacon_xres; static u32 vgacon_yres; -static struct vgastate state; +static struct vgastate vgastate; #define BLANK 0x0020 @@ -400,7 +400,7 @@ static const char *vgacon_startup(void) vga_video_num_lines = screen_info.orig_video_lines; vga_video_num_columns = screen_info.orig_video_cols; - state.vgabase = NULL; + vgastate.vgabase = NULL; if (screen_info.orig_video_mode == 7) { /* Monochrome display */ @@ -851,12 +851,12 @@ static void vga_set_palette(struct vc_data *vc, unsigned char *table) { int i, j; - vga_w(state.vgabase, VGA_PEL_MSK, 0xff); + vga_w(vgastate.vgabase, VGA_PEL_MSK, 0xff); for (i = j = 0; i < 16; i++) { - vga_w(state.vgabase, VGA_PEL_IW, table[i]); - vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); - vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); - vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); + vga_w(vgastate.vgabase, VGA_PEL_IW, table[i]); + vga_w(vgastate.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); + vga_w(vgastate.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); + vga_w(vgastate.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); } } @@ -1008,7 +1008,7 @@ static int vgacon_blank(struct vc_data *c, int blank, int mode_switch) switch (blank) { case 0: /* Unblank */ if (vga_vesa_blanked) { - vga_vesa_unblank(&state); + vga_vesa_unblank(&vgastate); vga_vesa_blanked = 0; } if (vga_palette_blanked) { @@ -1022,7 +1022,7 @@ static int vgacon_blank(struct vc_data *c, int blank, int mode_switch) case 1: /* Normal blanking */ case -1: /* Obsolete */ if (!mode_switch && vga_video_type == VIDEO_TYPE_VGAC) { - vga_pal_blank(&state); + vga_pal_blank(&vgastate); vga_palette_blanked = 1; return 0; } @@ -1034,7 +1034,7 @@ static int vgacon_blank(struct vc_data *c, int blank, int mode_switch) return 1; default: /* VESA blanking */ if (vga_video_type == VIDEO_TYPE_VGAC) { - vga_vesa_blank(&state, blank - 1); + vga_vesa_blank(&vgastate, blank - 1); vga_vesa_blanked = blank; } return 0; @@ -1280,7 +1280,7 @@ static int vgacon_font_set(struct vc_data *c, struct console_font *font, unsigne (charcount != 256 && charcount != 512)) return -EINVAL; - rc = vgacon_do_font_op(&state, font->data, 1, charcount == 512); + rc = vgacon_do_font_op(&vgastate, font->data, 1, charcount == 512); if (rc) return rc; @@ -1299,7 +1299,7 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font) font->charcount = vga_512_chars ? 512 : 256; if (!font->data) return 0; - return vgacon_do_font_op(&state, font->data, 0, vga_512_chars); + return vgacon_do_font_op(&vgastate, font->data, 0, vga_512_chars); } #else diff --git a/drivers/video/fbdev/68328fb.c b/drivers/video/fbdev/68328fb.c index 552258c..17f21ce 100644 --- a/drivers/video/fbdev/68328fb.c +++ b/drivers/video/fbdev/68328fb.c @@ -49,12 +49,6 @@ #error wrong architecture for the MC68x328 frame buffer device #endif -#if defined(CONFIG_FB_68328_INVERT) -#define MC68X328FB_MONO_VISUAL FB_VISUAL_MONO01 -#else -#define MC68X328FB_MONO_VISUAL FB_VISUAL_MONO10 -#endif - static u_long videomemory; static u_long videomemorysize; @@ -462,7 +456,7 @@ int __init mc68x328fb_init(void) fb_info.fix.line_length = get_line_length(mc68x328fb_default.xres_virtual, mc68x328fb_default.bits_per_pixel); fb_info.fix.visual = (mc68x328fb_default.bits_per_pixel) == 1 ? - MC68X328FB_MONO_VISUAL : FB_VISUAL_PSEUDOCOLOR; + FB_VISUAL_MONO10 : FB_VISUAL_PSEUDOCOLOR; if (fb_info.var.bits_per_pixel == 1) { fb_info.var.red.length = fb_info.var.green.length = fb_info.var.blue.length = 1; fb_info.var.red.offset = fb_info.var.green.offset = fb_info.var.blue.offset = 0; diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 59c98bfd..c7bf606 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -4,6 +4,7 @@ menuconfig FB tristate "Support for frame buffer devices" + select FB_CMDLINE ---help--- The frame buffer device provides an abstraction for the graphics hardware. It represents the frame buffer of some video hardware and @@ -52,6 +53,9 @@ config FIRMWARE_EDID combination with certain motherboards and monitors are known to suffer from this problem. +config FB_CMDLINE + bool + config FB_DDC tristate depends on FB @@ -280,6 +284,8 @@ config FB_ARMCLCD select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_MODE_HELPERS if OF + select VIDEOMODE_HELPERS if OF help This framebuffer device driver is for the ARM PrimeCell PL110 Colour LCD controller. ARM PrimeCells provide the building @@ -290,6 +296,12 @@ config FB_ARMCLCD here and read <file:Documentation/kbuild/modules.txt>. The module will be called amba-clcd. +# Helper logic selected only by the ARM Versatile platform family. +config PLAT_VERSATILE_CLCD + def_bool ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS + depends on ARM + depends on FB_ARMCLCD && FB=y + config FB_ACORN bool "Acorn VIDC support" depends on (FB = y) && ARM && ARCH_ACORN @@ -301,15 +313,26 @@ config FB_ACORN hardware found in Acorn RISC PCs and other ARM-based machines. If unsure, say N. -config FB_CLPS711X - bool "CLPS711X LCD support" - depends on (FB = y) && ARM && ARCH_CLPS711X +config FB_CLPS711X_OLD + tristate select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + +config FB_CLPS711X + tristate "CLPS711X LCD support" + depends on FB && (ARCH_CLPS711X || COMPILE_TEST) + select FB_CLPS711X_OLD if ARCH_CLPS711X && !ARCH_MULTIPLATFORM + select BACKLIGHT_LCD_SUPPORT + select FB_MODE_HELPERS + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select LCD_CLASS_DEVICE + select VIDEOMODE_HELPERS help - Say Y to enable the Framebuffer driver for the CLPS7111 and - EP7212 processors. + Say Y to enable the Framebuffer driver for the Cirrus Logic + CLPS711X CPUs. config FB_SA1100 bool "SA-1100 LCD support" @@ -2018,8 +2041,8 @@ config FB_TMIO_ACCELL config FB_S3C tristate "Samsung S3C framebuffer support" - depends on FB && (CPU_S3C2416 || ARCH_S3C64XX || ARCH_S5P64X0 || \ - ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) + depends on FB && (CPU_S3C2416 || ARCH_S3C64XX || \ + ARCH_S5PV210 || ARCH_EXYNOS) select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -2333,10 +2356,11 @@ config FB_MSM config FB_MX3 tristate "MX3 Framebuffer support" depends on FB && MX3_IPU + select BACKLIGHT_CLASS_DEVICE + select BACKLIGHT_LCD_SUPPORT select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select BACKLIGHT_CLASS_DEVICE default y help This is a framebuffer device for the i.MX31 LCD Controller. So diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile index 0284f2a..1979aff 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -14,7 +14,8 @@ obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o # Hardware specific drivers go first obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o obj-$(CONFIG_FB_ARC) += arcfb.o -obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o +obj-$(CONFIG_FB_CLPS711X) += clps711x-fb.o +obj-$(CONFIG_FB_CLPS711X_OLD) += clps711xfb.o obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o obj-$(CONFIG_FB_GRVGA) += grvga.o obj-$(CONFIG_FB_PM2) += pm2fb.o @@ -78,6 +79,7 @@ obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o obj-$(CONFIG_FB_PVR2) += pvr2fb.o obj-$(CONFIG_FB_VOODOO1) += sstfb.o obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o +obj-$(CONFIG_PLAT_VERSATILE_CLCD) += amba-clcd-versatile.o obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o obj-$(CONFIG_FB_68328) += 68328fb.o obj-$(CONFIG_FB_GBE) += gbefb.o diff --git a/drivers/video/fbdev/amba-clcd-versatile.c b/drivers/video/fbdev/amba-clcd-versatile.c new file mode 100644 index 0000000..7a8afcd --- /dev/null +++ b/drivers/video/fbdev/amba-clcd-versatile.c @@ -0,0 +1,182 @@ +#include <linux/device.h> +#include <linux/dma-mapping.h> +#include <linux/amba/bus.h> +#include <linux/amba/clcd.h> +#include <linux/platform_data/video-clcd-versatile.h> + +static struct clcd_panel vga = { + .mode = { + .name = "VGA", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 39721, + .left_margin = 40, + .right_margin = 24, + .upper_margin = 32, + .lower_margin = 11, + .hsync_len = 96, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_BCD | TIM2_IPC, + .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1), + .caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888, + .bpp = 16, +}; + +static struct clcd_panel xvga = { + .mode = { + .name = "XVGA", + .refresh = 60, + .xres = 1024, + .yres = 768, + .pixclock = 15748, + .left_margin = 152, + .right_margin = 48, + .upper_margin = 23, + .lower_margin = 3, + .hsync_len = 104, + .vsync_len = 4, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_BCD | TIM2_IPC, + .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1), + .caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888, + .bpp = 16, +}; + +/* Sanyo TM38QV67A02A - 3.8 inch QVGA (320x240) Color TFT */ +static struct clcd_panel sanyo_tm38qv67a02a = { + .mode = { + .name = "Sanyo TM38QV67A02A", + .refresh = 116, + .xres = 320, + .yres = 240, + .pixclock = 100000, + .left_margin = 6, + .right_margin = 6, + .upper_margin = 5, + .lower_margin = 5, + .hsync_len = 6, + .vsync_len = 6, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_BCD, + .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1), + .caps = CLCD_CAP_5551, + .bpp = 16, +}; + +static struct clcd_panel sanyo_2_5_in = { + .mode = { + .name = "Sanyo QVGA Portrait", + .refresh = 116, + .xres = 240, + .yres = 320, + .pixclock = 100000, + .left_margin = 20, + .right_margin = 10, + .upper_margin = 2, + .lower_margin = 2, + .hsync_len = 10, + .vsync_len = 2, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC, + .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1), + .caps = CLCD_CAP_5551, + .bpp = 16, +}; + +/* Epson L2F50113T00 - 2.2 inch 176x220 Color TFT */ +static struct clcd_panel epson_l2f50113t00 = { + .mode = { + .name = "Epson L2F50113T00", + .refresh = 390, + .xres = 176, + .yres = 220, + .pixclock = 62500, + .left_margin = 3, + .right_margin = 2, + .upper_margin = 1, + .lower_margin = 0, + .hsync_len = 3, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_BCD | TIM2_IPC, + .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1), + .caps = CLCD_CAP_5551, + .bpp = 16, +}; + +static struct clcd_panel *panels[] = { + &vga, + &xvga, + &sanyo_tm38qv67a02a, + &sanyo_2_5_in, + &epson_l2f50113t00, +}; + +struct clcd_panel *versatile_clcd_get_panel(const char *name) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(panels); i++) + if (strcmp(panels[i]->mode.name, name) == 0) + break; + + if (i < ARRAY_SIZE(panels)) + return panels[i]; + + pr_err("CLCD: couldn't get parameters for panel %s\n", name); + + return NULL; +} + +int versatile_clcd_setup_dma(struct clcd_fb *fb, unsigned long framesize) +{ + dma_addr_t dma; + + fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize, + &dma, GFP_KERNEL); + if (!fb->fb.screen_base) { + pr_err("CLCD: unable to map framebuffer\n"); + return -ENOMEM; + } + + fb->fb.fix.smem_start = dma; + fb->fb.fix.smem_len = framesize; + + return 0; +} + +int versatile_clcd_mmap_dma(struct clcd_fb *fb, struct vm_area_struct *vma) +{ + return dma_mmap_writecombine(&fb->dev->dev, vma, + fb->fb.screen_base, + fb->fb.fix.smem_start, + fb->fb.fix.smem_len); +} + +void versatile_clcd_remove_dma(struct clcd_fb *fb) +{ + dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len, + fb->fb.screen_base, fb->fb.fix.smem_start); +} diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c index 14d6b37..6ad23bd 100644 --- a/drivers/video/fbdev/amba-clcd.c +++ b/drivers/video/fbdev/amba-clcd.c @@ -24,8 +24,16 @@ #include <linux/list.h> #include <linux/amba/bus.h> #include <linux/amba/clcd.h> +#include <linux/bitops.h> #include <linux/clk.h> #include <linux/hardirq.h> +#include <linux/dma-mapping.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_graph.h> +#include <video/display_timing.h> +#include <video/of_display_timing.h> +#include <video/videomode.h> #include <asm/sizes.h> @@ -543,6 +551,269 @@ static int clcdfb_register(struct clcd_fb *fb) return ret; } +#ifdef CONFIG_OF +static int clcdfb_of_get_dpi_panel_mode(struct device_node *node, + struct fb_videomode *mode) +{ + int err; + struct display_timing timing; + struct videomode video; + + err = of_get_display_timing(node, "panel-timing", &timing); + if (err) + return err; + + videomode_from_timing(&timing, &video); + + err = fb_videomode_from_videomode(&video, mode); + if (err) + return err; + + return 0; +} + +static int clcdfb_snprintf_mode(char *buf, int size, struct fb_videomode *mode) +{ + return snprintf(buf, size, "%ux%u@%u", mode->xres, mode->yres, + mode->refresh); +} + +static int clcdfb_of_get_mode(struct device *dev, struct device_node *endpoint, + struct fb_videomode *mode) +{ + int err; + struct device_node *panel; + char *name; + int len; + + panel = of_graph_get_remote_port_parent(endpoint); + if (!panel) + return -ENODEV; + + /* Only directly connected DPI panels supported for now */ + if (of_device_is_compatible(panel, "panel-dpi")) + err = clcdfb_of_get_dpi_panel_mode(panel, mode); + else + err = -ENOENT; + if (err) + return err; + + len = clcdfb_snprintf_mode(NULL, 0, mode); + name = devm_kzalloc(dev, len + 1, GFP_KERNEL); + clcdfb_snprintf_mode(name, len + 1, mode); + mode->name = name; + + return 0; +} + +static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0) +{ + static struct { + unsigned int part; + u32 r0, g0, b0; + u32 caps; + } panels[] = { + { 0x110, 1, 7, 13, CLCD_CAP_5551 }, + { 0x110, 0, 8, 16, CLCD_CAP_888 }, + { 0x111, 4, 14, 20, CLCD_CAP_444 }, + { 0x111, 3, 11, 19, CLCD_CAP_444 | CLCD_CAP_5551 }, + { 0x111, 3, 10, 19, CLCD_CAP_444 | CLCD_CAP_5551 | + CLCD_CAP_565 }, + { 0x111, 0, 8, 16, CLCD_CAP_444 | CLCD_CAP_5551 | + CLCD_CAP_565 | CLCD_CAP_888 }, + }; + int i; + + /* Bypass pixel clock divider, data output on the falling edge */ + fb->panel->tim2 = TIM2_BCD | TIM2_IPC; + + /* TFT display, vert. comp. interrupt at the start of the back porch */ + fb->panel->cntl |= CNTL_LCDTFT | CNTL_LCDVCOMP(1); + + fb->panel->caps = 0; + + /* Match the setup with known variants */ + for (i = 0; i < ARRAY_SIZE(panels) && !fb->panel->caps; i++) { + if (amba_part(fb->dev) != panels[i].part) + continue; + if (g0 != panels[i].g0) + continue; + if (r0 == panels[i].r0 && b0 == panels[i].b0) + fb->panel->caps = panels[i].caps; + } + + return fb->panel->caps ? 0 : -EINVAL; +} + +static int clcdfb_of_init_display(struct clcd_fb *fb) +{ + struct device_node *endpoint; + int err; + unsigned int bpp; + u32 max_bandwidth; + u32 tft_r0b0g0[3]; + + fb->panel = devm_kzalloc(&fb->dev->dev, sizeof(*fb->panel), GFP_KERNEL); + if (!fb->panel) + return -ENOMEM; + + endpoint = of_graph_get_next_endpoint(fb->dev->dev.of_node, NULL); + if (!endpoint) + return -ENODEV; + + err = clcdfb_of_get_mode(&fb->dev->dev, endpoint, &fb->panel->mode); + if (err) + return err; + + err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth", + &max_bandwidth); + if (!err) { + /* + * max_bandwidth is in bytes per second and pixclock in + * pico-seconds, so the maximum allowed bits per pixel is + * 8 * max_bandwidth / (PICOS2KHZ(pixclock) * 1000) + * Rearrange this calculation to avoid overflow and then ensure + * result is a valid format. + */ + bpp = max_bandwidth / (1000 / 8) + / PICOS2KHZ(fb->panel->mode.pixclock); + bpp = rounddown_pow_of_two(bpp); + if (bpp > 32) + bpp = 32; + } else + bpp = 32; + fb->panel->bpp = bpp; + +#ifdef CONFIG_CPU_BIG_ENDIAN + fb->panel->cntl |= CNTL_BEBO; +#endif + fb->panel->width = -1; + fb->panel->height = -1; + + if (of_property_read_u32_array(endpoint, + "arm,pl11x,tft-r0g0b0-pads", + tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) == 0) + return clcdfb_of_init_tft_panel(fb, tft_r0b0g0[0], + tft_r0b0g0[1], tft_r0b0g0[2]); + + return -ENOENT; +} + +static int clcdfb_of_vram_setup(struct clcd_fb *fb) +{ + int err; + struct device_node *memory; + u64 size; + + err = clcdfb_of_init_display(fb); + if (err) + return err; + + memory = of_parse_phandle(fb->dev->dev.of_node, "memory-region", 0); + if (!memory) + return -ENODEV; + + fb->fb.screen_base = of_iomap(memory, 0); + if (!fb->fb.screen_base) + return -ENOMEM; + + fb->fb.fix.smem_start = of_translate_address(memory, + of_get_address(memory, 0, &size, NULL)); + fb->fb.fix.smem_len = size; + + return 0; +} + +static int clcdfb_of_vram_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) +{ + unsigned long off, user_size, kernel_size; + + + off = vma->vm_pgoff << PAGE_SHIFT; + user_size = vma->vm_end - vma->vm_start; + kernel_size = fb->fb.fix.smem_len; + + if (off >= kernel_size || user_size > (kernel_size - off)) + return -ENXIO; + + return remap_pfn_range(vma, vma->vm_start, + __phys_to_pfn(fb->fb.fix.smem_start) + vma->vm_pgoff, + user_size, + pgprot_writecombine(vma->vm_page_prot)); +} + +static void clcdfb_of_vram_remove(struct clcd_fb *fb) +{ + iounmap(fb->fb.screen_base); +} + +static int clcdfb_of_dma_setup(struct clcd_fb *fb) +{ + unsigned long framesize; + dma_addr_t dma; + int err; + + err = clcdfb_of_init_display(fb); + if (err) + return err; + + framesize = fb->panel->mode.xres * fb->panel->mode.yres * + fb->panel->bpp / 8; + fb->fb.screen_base = dma_alloc_coherent(&fb->dev->dev, framesize, + &dma, GFP_KERNEL); + if (!fb->fb.screen_base) + return -ENOMEM; + + fb->fb.fix.smem_start = dma; + fb->fb.fix.smem_len = framesize; + + return 0; +} + +static int clcdfb_of_dma_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) +{ + return dma_mmap_writecombine(&fb->dev->dev, vma, fb->fb.screen_base, + fb->fb.fix.smem_start, fb->fb.fix.smem_len); +} + +static void clcdfb_of_dma_remove(struct clcd_fb *fb) +{ + dma_free_coherent(&fb->dev->dev, fb->fb.fix.smem_len, + fb->fb.screen_base, fb->fb.fix.smem_start); +} + +static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev) +{ + struct clcd_board *board = devm_kzalloc(&dev->dev, sizeof(*board), + GFP_KERNEL); + struct device_node *node = dev->dev.of_node; + + if (!board) + return NULL; + + board->name = of_node_full_name(node); + board->caps = CLCD_CAP_ALL; + board->check = clcdfb_check; + board->decode = clcdfb_decode; + if (of_find_property(node, "memory-region", NULL)) { + board->setup = clcdfb_of_vram_setup; + board->mmap = clcdfb_of_vram_mmap; + board->remove = clcdfb_of_vram_remove; + } else { + board->setup = clcdfb_of_dma_setup; + board->mmap = clcdfb_of_dma_mmap; + board->remove = clcdfb_of_dma_remove; + } + + return board; +} +#else +static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev) +{ + return NULL; +} +#endif + static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id) { struct clcd_board *board = dev_get_platdata(&dev->dev); @@ -550,6 +821,9 @@ static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id) int ret; if (!board) + board = clcdfb_of_get_board(dev); + + if (!board) return -EINVAL; ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c index d36e830..9ec81d4 100644 --- a/drivers/video/fbdev/atmel_lcdfb.c +++ b/drivers/video/fbdev/atmel_lcdfb.c @@ -24,9 +24,9 @@ #include <linux/of_device.h> #include <linux/of_gpio.h> #include <video/of_display_timing.h> +#include <linux/regulator/consumer.h> #include <video/videomode.h> -#include <mach/cpu.h> #include <asm/gpio.h> #include <video/atmel_lcdc.h> @@ -60,6 +60,7 @@ struct atmel_lcdfb_info { struct atmel_lcdfb_pdata pdata; struct atmel_lcdfb_config *config; + struct regulator *reg_lcd; }; struct atmel_lcdfb_power_ctrl_gpio { @@ -290,7 +291,7 @@ static void init_contrast(struct atmel_lcdfb_info *sinfo) /* contrast pwm can be 'inverted' */ if (pdata->lcdcon_pol_negative) - contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE); + contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE); /* have some default contrast/backlight settings */ lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr); @@ -302,10 +303,24 @@ static void init_contrast(struct atmel_lcdfb_info *sinfo) static inline void atmel_lcdfb_power_control(struct atmel_lcdfb_info *sinfo, int on) { + int ret; struct atmel_lcdfb_pdata *pdata = &sinfo->pdata; if (pdata->atmel_lcdfb_power_control) pdata->atmel_lcdfb_power_control(pdata, on); + else if (sinfo->reg_lcd) { + if (on) { + ret = regulator_enable(sinfo->reg_lcd); + if (ret) + dev_err(&sinfo->pdev->dev, + "lcd regulator enable failed: %d\n", ret); + } else { + ret = regulator_disable(sinfo->reg_lcd); + if (ret) + dev_err(&sinfo->pdev->dev, + "lcd regulator disable failed: %d\n", ret); + } + } } static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = { @@ -1097,16 +1112,19 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo) pdata->lcd_wiring_mode = ret; pdata->lcdcon_is_backlight = of_property_read_bool(display_np, "atmel,lcdcon-backlight"); + pdata->lcdcon_pol_negative = of_property_read_bool(display_np, "atmel,lcdcon-backlight-inverted"); timings = of_get_display_timings(display_np); if (!timings) { dev_err(dev, "failed to get display timings\n"); + ret = -EINVAL; goto put_display_node; } timings_np = of_find_node_by_name(display_np, "display-timings"); if (!timings_np) { dev_err(dev, "failed to find display-timings node\n"); + ret = -ENODEV; goto put_display_node; } @@ -1192,6 +1210,10 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) if (!sinfo->config) goto free_info; + sinfo->reg_lcd = devm_regulator_get(&pdev->dev, "lcd"); + if (IS_ERR(sinfo->reg_lcd)) + sinfo->reg_lcd = NULL; + info->flags = ATMEL_LCDFB_FBINFO_DEFAULT; info->pseudo_palette = sinfo->pseudo_palette; info->fbops = &atmel_lcdfb_ops; diff --git a/drivers/video/fbdev/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c index 52108be..aedf2fb 100644 --- a/drivers/video/fbdev/aty/aty128fb.c +++ b/drivers/video/fbdev/aty/aty128fb.c @@ -324,14 +324,61 @@ struct aty128_meminfo { }; /* various memory configurations */ -static const struct aty128_meminfo sdr_128 = - { 4, 4, 3, 3, 1, 3, 1, 16, 30, 16, "128-bit SDR SGRAM (1:1)" }; -static const struct aty128_meminfo sdr_64 = - { 4, 8, 3, 3, 1, 3, 1, 17, 46, 17, "64-bit SDR SGRAM (1:1)" }; -static const struct aty128_meminfo sdr_sgram = - { 4, 4, 1, 2, 1, 2, 1, 16, 24, 16, "64-bit SDR SGRAM (2:1)" }; -static const struct aty128_meminfo ddr_sgram = - { 4, 4, 3, 3, 2, 3, 1, 16, 31, 16, "64-bit DDR SGRAM" }; +static const struct aty128_meminfo sdr_128 = { + .ML = 4, + .MB = 4, + .Trcd = 3, + .Trp = 3, + .Twr = 1, + .CL = 3, + .Tr2w = 1, + .LoopLatency = 16, + .DspOn = 30, + .Rloop = 16, + .name = "128-bit SDR SGRAM (1:1)", +}; + +static const struct aty128_meminfo sdr_64 = { + .ML = 4, + .MB = 8, + .Trcd = 3, + .Trp = 3, + .Twr = 1, + .CL = 3, + .Tr2w = 1, + .LoopLatency = 17, + .DspOn = 46, + .Rloop = 17, + .name = "64-bit SDR SGRAM (1:1)", +}; + +static const struct aty128_meminfo sdr_sgram = { + .ML = 4, + .MB = 4, + .Trcd = 1, + .Trp = 2, + .Twr = 1, + .CL = 2, + .Tr2w = 1, + .LoopLatency = 16, + .DspOn = 24, + .Rloop = 16, + .name = "64-bit SDR SGRAM (2:1)", +}; + +static const struct aty128_meminfo ddr_sgram = { + .ML = 4, + .MB = 4, + .Trcd = 3, + .Trp = 3, + .Twr = 2, + .CL = 3, + .Tr2w = 1, + .LoopLatency = 16, + .DspOn = 31, + .Rloop = 16, + .name = "64-bit DDR SGRAM", +}; static struct fb_fix_screeninfo aty128fb_fix = { .id = "ATY Rage128", @@ -1802,13 +1849,7 @@ static int aty128_bl_update_status(struct backlight_device *bd) return 0; } -static int aty128_bl_get_brightness(struct backlight_device *bd) -{ - return bd->props.brightness; -} - static const struct backlight_ops aty128_bl_data = { - .get_brightness = aty128_bl_get_brightness, .update_status = aty128_bl_update_status, }; diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c index c3d0074..37ec09b 100644 --- a/drivers/video/fbdev/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -2211,13 +2211,7 @@ static int aty_bl_update_status(struct backlight_device *bd) return 0; } -static int aty_bl_get_brightness(struct backlight_device *bd) -{ - return bd->props.brightness; -} - static const struct backlight_ops aty_bl_data = { - .get_brightness = aty_bl_get_brightness, .update_status = aty_bl_update_status, }; diff --git a/drivers/video/fbdev/aty/radeon_backlight.c b/drivers/video/fbdev/aty/radeon_backlight.c index db572df..301d6d6 100644 --- a/drivers/video/fbdev/aty/radeon_backlight.c +++ b/drivers/video/fbdev/aty/radeon_backlight.c @@ -123,13 +123,7 @@ static int radeon_bl_update_status(struct backlight_device *bd) return 0; } -static int radeon_bl_get_brightness(struct backlight_device *bd) -{ - return bd->props.brightness; -} - static const struct backlight_ops radeon_bl_data = { - .get_brightness = radeon_bl_get_brightness, .update_status = radeon_bl_update_status, }; diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c index 372d4ae..0676746e 100644 --- a/drivers/video/fbdev/au1100fb.c +++ b/drivers/video/fbdev/au1100fb.c @@ -41,6 +41,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <linux/clk.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -113,7 +114,7 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) case VESA_NO_BLANKING: /* Turn on panel */ fbdev->regs->lcd_control |= LCD_CONTROL_GO; - au_sync(); + wmb(); /* drain writebuffer */ break; case VESA_VSYNC_SUSPEND: @@ -121,7 +122,7 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) case VESA_POWERDOWN: /* Turn off panel */ fbdev->regs->lcd_control &= ~LCD_CONTROL_GO; - au_sync(); + wmb(); /* drain writebuffer */ break; default: break; @@ -434,7 +435,7 @@ static int au1100fb_drv_probe(struct platform_device *dev) struct au1100fb_device *fbdev = NULL; struct resource *regs_res; unsigned long page; - u32 sys_clksrc; + struct clk *c; /* Allocate new device private */ fbdev = devm_kzalloc(&dev->dev, sizeof(struct au1100fb_device), @@ -473,6 +474,13 @@ static int au1100fb_drv_probe(struct platform_device *dev) print_dbg("Register memory map at %p", fbdev->regs); print_dbg("phys=0x%08x, size=%d", fbdev->regs_phys, fbdev->regs_len); + c = clk_get(NULL, "lcd_intclk"); + if (!IS_ERR(c)) { + fbdev->lcdclk = c; + clk_set_rate(c, 48000000); + clk_prepare_enable(c); + } + /* Allocate the framebuffer to the maximum screen size * nbr of video buffers */ fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres * (fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS; @@ -506,10 +514,6 @@ static int au1100fb_drv_probe(struct platform_device *dev) print_dbg("Framebuffer memory map at %p", fbdev->fb_mem); print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024); - /* Setup LCD clock to AUX (48 MHz) */ - sys_clksrc = au_readl(SYS_CLKSRC) & ~(SYS_CS_ML_MASK | SYS_CS_DL | SYS_CS_CL); - au_writel((sys_clksrc | (1 << SYS_CS_ML_BIT)), SYS_CLKSRC); - /* load the panel info into the var struct */ au1100fb_var.bits_per_pixel = fbdev->panel->bpp; au1100fb_var.xres = fbdev->panel->xres; @@ -546,6 +550,10 @@ static int au1100fb_drv_probe(struct platform_device *dev) return 0; failed: + if (fbdev->lcdclk) { + clk_disable_unprepare(fbdev->lcdclk); + clk_put(fbdev->lcdclk); + } if (fbdev->fb_mem) { dma_free_noncoherent(&dev->dev, fbdev->fb_len, fbdev->fb_mem, fbdev->fb_phys); @@ -576,11 +584,15 @@ int au1100fb_drv_remove(struct platform_device *dev) fb_dealloc_cmap(&fbdev->info.cmap); + if (fbdev->lcdclk) { + clk_disable_unprepare(fbdev->lcdclk); + clk_put(fbdev->lcdclk); + } + return 0; } #ifdef CONFIG_PM -static u32 sys_clksrc; static struct au1100fb_regs fbregs; int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state) @@ -590,14 +602,11 @@ int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state) if (!fbdev) return 0; - /* Save the clock source state */ - sys_clksrc = au_readl(SYS_CLKSRC); - /* Blank the LCD */ au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); - /* Stop LCD clocking */ - au_writel(sys_clksrc & ~SYS_CS_ML_MASK, SYS_CLKSRC); + if (fbdev->lcdclk) + clk_disable(fbdev->lcdclk); memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs)); @@ -613,8 +622,8 @@ int au1100fb_drv_resume(struct platform_device *dev) memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs)); - /* Restart LCD clocking */ - au_writel(sys_clksrc, SYS_CLKSRC); + if (fbdev->lcdclk) + clk_enable(fbdev->lcdclk); /* Unblank the LCD */ au1100fb_fb_blank(VESA_NO_BLANKING, &fbdev->info); diff --git a/drivers/video/fbdev/au1100fb.h b/drivers/video/fbdev/au1100fb.h index 12d9642d..9af1993 100644 --- a/drivers/video/fbdev/au1100fb.h +++ b/drivers/video/fbdev/au1100fb.h @@ -109,6 +109,7 @@ struct au1100fb_device { size_t fb_len; dma_addr_t fb_phys; int panel_idx; + struct clk *lcdclk; }; /********************************************************************/ diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index 4cfba78..18600d4 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c @@ -30,6 +30,7 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <linux/clk.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/kernel.h> @@ -330,9 +331,8 @@ struct panel_settings uint32 mode_pwmhi; uint32 mode_outmask; uint32 mode_fifoctrl; - uint32 mode_toyclksrc; uint32 mode_backlight; - uint32 mode_auxpll; + uint32 lcdclk; #define Xres min_xres #define Yres min_yres u32 min_xres; /* Minimum horizontal resolution */ @@ -379,9 +379,8 @@ static struct panel_settings known_lcd_panels[] = .mode_pwmhi = 0x00000000, .mode_outmask = 0x00FFFFFF, .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, - .mode_auxpll = 8, /* 96MHz AUXPLL */ + .lcdclk = 96, 320, 320, 240, 240, }, @@ -407,9 +406,8 @@ static struct panel_settings known_lcd_panels[] = .mode_pwmhi = 0x00000000, .mode_outmask = 0x00FFFFFF, .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, - .mode_auxpll = 8, /* 96MHz AUXPLL */ + .lcdclk = 96, 640, 480, 640, 480, }, @@ -435,9 +433,8 @@ static struct panel_settings known_lcd_panels[] = .mode_pwmhi = 0x00000000, .mode_outmask = 0x00FFFFFF, .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, - .mode_auxpll = 8, /* 96MHz AUXPLL */ + .lcdclk = 96, 800, 800, 600, 600, }, @@ -463,9 +460,8 @@ static struct panel_settings known_lcd_panels[] = .mode_pwmhi = 0x00000000, .mode_outmask = 0x00FFFFFF, .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, - .mode_auxpll = 6, /* 72MHz AUXPLL */ + .lcdclk = 72, 1024, 1024, 768, 768, }, @@ -491,9 +487,8 @@ static struct panel_settings known_lcd_panels[] = .mode_pwmhi = 0x00000000, .mode_outmask = 0x00FFFFFF, .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, - .mode_auxpll = 10, /* 120MHz AUXPLL */ + .lcdclk = 120, 1280, 1280, 1024, 1024, }, @@ -519,9 +514,8 @@ static struct panel_settings known_lcd_panels[] = .mode_pwmhi = 0x03400000, /* SCB 0x0 */ .mode_outmask = 0x00FFFFFF, .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, - .mode_auxpll = 8, /* 96MHz AUXPLL */ + .lcdclk = 96, 1024, 1024, 768, 768, }, @@ -550,9 +544,8 @@ static struct panel_settings known_lcd_panels[] = .mode_pwmhi = 0x03400000, .mode_outmask = 0x00fcfcfc, .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, - .mode_auxpll = 8, /* 96MHz AUXPLL */ + .lcdclk = 96, 640, 480, 640, 480, }, @@ -581,9 +574,8 @@ static struct panel_settings known_lcd_panels[] = .mode_pwmhi = 0x03400000, .mode_outmask = 0x00fcfcfc, .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, - .mode_auxpll = 8, /* 96MHz AUXPLL */ + .lcdclk = 96, /* 96MHz AUXPLL */ 320, 320, 240, 240, }, @@ -612,9 +604,8 @@ static struct panel_settings known_lcd_panels[] = .mode_pwmhi = 0x03400000, .mode_outmask = 0x00fcfcfc, .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, - .mode_auxpll = 8, /* 96MHz AUXPLL */ + .lcdclk = 96, 856, 856, 480, 480, }, @@ -646,9 +637,8 @@ static struct panel_settings known_lcd_panels[] = .mode_pwmhi = 0x00000000, .mode_outmask = 0x00FFFFFF, .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, - .mode_auxpll = (48/12) * 2, + .lcdclk = 96, 800, 800, 480, 480, }, @@ -764,7 +754,7 @@ static int au1200_setlocation (struct au1200fb_device *fbdev, int plane, /* Disable the window while making changes, then restore WINEN */ winenable = lcd->winenable & (1 << plane); - au_sync(); + wmb(); /* drain writebuffer */ lcd->winenable &= ~(1 << plane); lcd->window[plane].winctrl0 = winctrl0; lcd->window[plane].winctrl1 = winctrl1; @@ -772,7 +762,7 @@ static int au1200_setlocation (struct au1200fb_device *fbdev, int plane, lcd->window[plane].winbuf1 = fbdev->fb_phys; lcd->window[plane].winbufctrl = 0; /* select winbuf0 */ lcd->winenable |= winenable; - au_sync(); + wmb(); /* drain writebuffer */ return 0; } @@ -788,22 +778,21 @@ static void au1200_setpanel(struct panel_settings *newpanel, /* Make sure all windows disabled */ winenable = lcd->winenable; lcd->winenable = 0; - au_sync(); + wmb(); /* drain writebuffer */ /* * Ensure everything is disabled before reconfiguring */ if (lcd->screen & LCD_SCREEN_SEN) { /* Wait for vertical sync period */ lcd->intstatus = LCD_INT_SS; - while ((lcd->intstatus & LCD_INT_SS) == 0) { - au_sync(); - } + while ((lcd->intstatus & LCD_INT_SS) == 0) + ; lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/ do { lcd->intstatus = lcd->intstatus; /*clear interrupts*/ - au_sync(); + wmb(); /* drain writebuffer */ /*wait for controller to shut down*/ } while ((lcd->intstatus & LCD_INT_SD) == 0); @@ -829,11 +818,17 @@ static void au1200_setpanel(struct panel_settings *newpanel, */ if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT)) { - uint32 sys_clksrc; - au_writel(panel->mode_auxpll, SYS_AUXPLL); - sys_clksrc = au_readl(SYS_CLKSRC) & ~0x0000001f; - sys_clksrc |= panel->mode_toyclksrc; - au_writel(sys_clksrc, SYS_CLKSRC); + struct clk *c = clk_get(NULL, "lcd_intclk"); + long r, pc = panel->lcdclk * 1000000; + + if (!IS_ERR(c)) { + r = clk_round_rate(c, pc); + if ((pc - r) < (pc / 10)) { /* 10% slack */ + clk_set_rate(c, r); + clk_prepare_enable(c); + } + clk_put(c); + } } /* @@ -847,7 +842,7 @@ static void au1200_setpanel(struct panel_settings *newpanel, lcd->pwmhi = panel->mode_pwmhi; lcd->outmask = panel->mode_outmask; lcd->fifoctrl = panel->mode_fifoctrl; - au_sync(); + wmb(); /* drain writebuffer */ /* fixme: Check window settings to make sure still valid * for new geometry */ @@ -863,7 +858,7 @@ static void au1200_setpanel(struct panel_settings *newpanel, * Re-enable screen now that it is configured */ lcd->screen |= LCD_SCREEN_SEN; - au_sync(); + wmb(); /* drain writebuffer */ /* Call init of panel */ if (pd->panel_init) @@ -956,7 +951,7 @@ static void au1200_setmode(struct au1200fb_device *fbdev) | LCD_WINCTRL2_SCY_1 ) ; lcd->winenable |= win->w[plane].mode_winenable; - au_sync(); + wmb(); /* drain writebuffer */ } @@ -1259,7 +1254,6 @@ static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) pdata->brightness = 30; } divider = (lcd->pwmdiv & 0x3FFFF) + 1; - hi1 = (lcd->pwmhi >> 16) + 1; hi1 = (((pdata->brightness & 0xFF)+1) * divider >> 8); lcd->pwmhi &= 0xFFFF; lcd->pwmhi |= (hi1 << 16); @@ -1270,7 +1264,7 @@ static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) if (pdata->flags & SCREEN_MASK) lcd->colorkeymsk = pdata->mask; - au_sync(); + wmb(); /* drain writebuffer */ } static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) @@ -1288,7 +1282,7 @@ static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) hi1 = (lcd->pwmhi >> 16) + 1; divider = (lcd->pwmdiv & 0x3FFFF) + 1; pdata->brightness = ((hi1 << 8) / divider) - 1; - au_sync(); + wmb(); /* drain writebuffer */ } static void set_window(unsigned int plane, @@ -1387,7 +1381,7 @@ static void set_window(unsigned int plane, val |= (pdata->enable & 1) << plane; lcd->winenable = val; } - au_sync(); + wmb(); /* drain writebuffer */ } static void get_window(unsigned int plane, @@ -1414,7 +1408,7 @@ static void get_window(unsigned int plane, pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21; pdata->enable = (lcd->winenable >> plane) & 1; - au_sync(); + wmb(); /* drain writebuffer */ } static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd, @@ -1511,7 +1505,7 @@ static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id) { /* Nothing to do for now, just clear any pending interrupt */ lcd->intstatus = lcd->intstatus; - au_sync(); + wmb(); /* drain writebuffer */ return IRQ_HANDLED; } @@ -1809,7 +1803,7 @@ static int au1200fb_drv_suspend(struct device *dev) au1200_setpanel(NULL, pd); lcd->outmask = 0; - au_sync(); + wmb(); /* drain writebuffer */ return 0; } diff --git a/drivers/video/fbdev/chipsfb.c b/drivers/video/fbdev/chipsfb.c index 206a66b..59abdc6 100644 --- a/drivers/video/fbdev/chipsfb.c +++ b/drivers/video/fbdev/chipsfb.c @@ -273,7 +273,7 @@ static struct chips_init_reg chips_init_xr[] = { { 0xa8, 0x00 } }; -static void __init chips_hw_init(void) +static void chips_hw_init(void) { int i; diff --git a/drivers/video/fbdev/clps711x-fb.c b/drivers/video/fbdev/clps711x-fb.c new file mode 100644 index 0000000..49a7bb4 --- /dev/null +++ b/drivers/video/fbdev/clps711x-fb.c @@ -0,0 +1,397 @@ +/* + * Cirrus Logic CLPS711X FB driver + * + * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru> + * Based on driver by Russell King <rmk@arm.linux.org.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/clk.h> +#include <linux/fb.h> +#include <linux/io.h> +#include <linux/lcd.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/mfd/syscon.h> +#include <linux/mfd/syscon/clps711x.h> +#include <linux/regulator/consumer.h> +#include <video/of_display_timing.h> + +#define CLPS711X_FB_NAME "clps711x-fb" +#define CLPS711X_FB_BPP_MAX (4) + +/* Registers relative to LCDCON */ +#define CLPS711X_LCDCON (0x0000) +# define LCDCON_GSEN BIT(30) +# define LCDCON_GSMD BIT(31) +#define CLPS711X_PALLSW (0x0280) +#define CLPS711X_PALMSW (0x02c0) +#define CLPS711X_FBADDR (0x0d40) + +struct clps711x_fb_info { + struct clk *clk; + void __iomem *base; + struct regmap *syscon; + resource_size_t buffsize; + struct fb_videomode mode; + struct regulator *lcd_pwr; + u32 ac_prescale; + bool cmap_invert; +}; + +static int clps711x_fb_setcolreg(u_int regno, u_int red, u_int green, + u_int blue, u_int transp, struct fb_info *info) +{ + struct clps711x_fb_info *cfb = info->par; + u32 level, mask, shift; + + if (regno >= BIT(info->var.bits_per_pixel)) + return -EINVAL; + + shift = 4 * (regno & 7); + mask = 0xf << shift; + /* gray = 0.30*R + 0.58*G + 0.11*B */ + level = (((red * 77 + green * 151 + blue * 28) >> 20) << shift) & mask; + if (cfb->cmap_invert) + level = 0xf - level; + + regno = (regno < 8) ? CLPS711X_PALLSW : CLPS711X_PALMSW; + + writel((readl(cfb->base + regno) & ~mask) | level, cfb->base + regno); + + return 0; +} + +static int clps711x_fb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + u32 val; + + if (var->bits_per_pixel < 1 || + var->bits_per_pixel > CLPS711X_FB_BPP_MAX) + return -EINVAL; + + if (!var->pixclock) + return -EINVAL; + + val = DIV_ROUND_UP(var->xres, 16) - 1; + if (val < 0x01 || val > 0x3f) + return -EINVAL; + + val = DIV_ROUND_UP(var->yres * var->xres * var->bits_per_pixel, 128); + val--; + if (val < 0x001 || val > 0x1fff) + return -EINVAL; + + var->transp.msb_right = 0; + var->transp.offset = 0; + var->transp.length = 0; + var->red.msb_right = 0; + var->red.offset = 0; + var->red.length = var->bits_per_pixel; + var->green = var->red; + var->blue = var->red; + var->grayscale = var->bits_per_pixel > 1; + + return 0; +} + +static int clps711x_fb_set_par(struct fb_info *info) +{ + struct clps711x_fb_info *cfb = info->par; + resource_size_t size; + u32 lcdcon, pps; + + size = (info->var.xres * info->var.yres * info->var.bits_per_pixel) / 8; + if (size > cfb->buffsize) + return -EINVAL; + + switch (info->var.bits_per_pixel) { + case 1: + info->fix.visual = FB_VISUAL_MONO01; + break; + case 2: + case 4: + info->fix.visual = FB_VISUAL_PSEUDOCOLOR; + break; + default: + return -EINVAL; + } + + info->fix.line_length = info->var.xres * info->var.bits_per_pixel / 8; + info->fix.smem_len = size; + + lcdcon = (info->var.xres * info->var.yres * + info->var.bits_per_pixel) / 128 - 1; + lcdcon |= ((info->var.xres / 16) - 1) << 13; + lcdcon |= (cfb->ac_prescale & 0x1f) << 25; + + pps = clk_get_rate(cfb->clk) / (PICOS2KHZ(info->var.pixclock) * 1000); + if (pps) + pps--; + lcdcon |= (pps & 0x3f) << 19; + + if (info->var.bits_per_pixel == 4) + lcdcon |= LCDCON_GSMD; + if (info->var.bits_per_pixel >= 2) + lcdcon |= LCDCON_GSEN; + + /* LCDCON must only be changed while the LCD is disabled */ + regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0); + writel(lcdcon, cfb->base + CLPS711X_LCDCON); + regmap_update_bits(cfb->syscon, SYSCON_OFFSET, + SYSCON1_LCDEN, SYSCON1_LCDEN); + + return 0; +} + +static int clps711x_fb_blank(int blank, struct fb_info *info) +{ + /* Return happy */ + return 0; +} + +static struct fb_ops clps711x_fb_ops = { + .owner = THIS_MODULE, + .fb_setcolreg = clps711x_fb_setcolreg, + .fb_check_var = clps711x_fb_check_var, + .fb_set_par = clps711x_fb_set_par, + .fb_blank = clps711x_fb_blank, + .fb_fillrect = sys_fillrect, + .fb_copyarea = sys_copyarea, + .fb_imageblit = sys_imageblit, +}; + +static int clps711x_lcd_check_fb(struct lcd_device *lcddev, struct fb_info *fi) +{ + struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev); + + return (!fi || fi->par == cfb) ? 1 : 0; +} + +static int clps711x_lcd_get_power(struct lcd_device *lcddev) +{ + struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev); + + if (!IS_ERR_OR_NULL(cfb->lcd_pwr)) + if (!regulator_is_enabled(cfb->lcd_pwr)) + return FB_BLANK_NORMAL; + + return FB_BLANK_UNBLANK; +} + +static int clps711x_lcd_set_power(struct lcd_device *lcddev, int blank) +{ + struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev); + + if (!IS_ERR_OR_NULL(cfb->lcd_pwr)) { + if (blank == FB_BLANK_UNBLANK) { + if (!regulator_is_enabled(cfb->lcd_pwr)) + return regulator_enable(cfb->lcd_pwr); + } else { + if (regulator_is_enabled(cfb->lcd_pwr)) + return regulator_disable(cfb->lcd_pwr); + } + } + + return 0; +} + +static struct lcd_ops clps711x_lcd_ops = { + .check_fb = clps711x_lcd_check_fb, + .get_power = clps711x_lcd_get_power, + .set_power = clps711x_lcd_set_power, +}; + +static int clps711x_fb_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *disp, *np = dev->of_node; + struct clps711x_fb_info *cfb; + struct lcd_device *lcd; + struct fb_info *info; + struct resource *res; + int ret = -ENOENT; + u32 val; + + if (fb_get_options(CLPS711X_FB_NAME, NULL)) + return -ENODEV; + + info = framebuffer_alloc(sizeof(*cfb), dev); + if (!info) + return -ENOMEM; + + cfb = info->par; + platform_set_drvdata(pdev, info); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + goto out_fb_release; + cfb->base = devm_ioremap(dev, res->start, resource_size(res)); + if (!cfb->base) { + ret = -ENOMEM; + goto out_fb_release; + } + + info->fix.mmio_start = res->start; + info->fix.mmio_len = resource_size(res); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + info->screen_base = devm_ioremap_resource(dev, res); + if (IS_ERR(info->screen_base)) { + ret = PTR_ERR(info->screen_base); + goto out_fb_release; + } + + /* Physical address should be aligned to 256 MiB */ + if (res->start & 0x0fffffff) { + ret = -EINVAL; + goto out_fb_release; + } + + info->apertures = alloc_apertures(1); + if (!info->apertures) { + ret = -ENOMEM; + goto out_fb_release; + } + + cfb->buffsize = resource_size(res); + info->fix.smem_start = res->start; + info->apertures->ranges[0].base = info->fix.smem_start; + info->apertures->ranges[0].size = cfb->buffsize; + + cfb->clk = devm_clk_get(dev, NULL); + if (IS_ERR(cfb->clk)) { + ret = PTR_ERR(cfb->clk); + goto out_fb_release; + } + + cfb->syscon = + syscon_regmap_lookup_by_compatible("cirrus,clps711x-syscon1"); + if (IS_ERR(cfb->syscon)) { + ret = PTR_ERR(cfb->syscon); + goto out_fb_release; + } + + disp = of_parse_phandle(np, "display", 0); + if (!disp) { + dev_err(&pdev->dev, "No display defined\n"); + ret = -ENODATA; + goto out_fb_release; + } + + ret = of_get_fb_videomode(disp, &cfb->mode, OF_USE_NATIVE_MODE); + if (ret) + goto out_fb_release; + + of_property_read_u32(disp, "ac-prescale", &cfb->ac_prescale); + cfb->cmap_invert = of_property_read_bool(disp, "cmap-invert"); + + ret = of_property_read_u32(disp, "bits-per-pixel", + &info->var.bits_per_pixel); + if (ret) + goto out_fb_release; + + /* Force disable LCD on any mismatch */ + if (info->fix.smem_start != (readb(cfb->base + CLPS711X_FBADDR) << 28)) + regmap_update_bits(cfb->syscon, SYSCON_OFFSET, + SYSCON1_LCDEN, 0); + + ret = regmap_read(cfb->syscon, SYSCON_OFFSET, &val); + if (ret) + goto out_fb_release; + + if (!(val & SYSCON1_LCDEN)) { + /* Setup start FB address */ + writeb(info->fix.smem_start >> 28, cfb->base + CLPS711X_FBADDR); + /* Clean FB memory */ + memset_io(info->screen_base, 0, cfb->buffsize); + } + + cfb->lcd_pwr = devm_regulator_get(dev, "lcd"); + if (PTR_ERR(cfb->lcd_pwr) == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto out_fb_release; + } + + info->fbops = &clps711x_fb_ops; + info->flags = FBINFO_DEFAULT; + info->var.activate = FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW; + info->var.height = -1; + info->var.width = -1; + info->var.vmode = FB_VMODE_NONINTERLACED; + info->fix.type = FB_TYPE_PACKED_PIXELS; + info->fix.accel = FB_ACCEL_NONE; + strlcpy(info->fix.id, CLPS711X_FB_NAME, sizeof(info->fix.id)); + fb_videomode_to_var(&info->var, &cfb->mode); + + ret = fb_alloc_cmap(&info->cmap, BIT(CLPS711X_FB_BPP_MAX), 0); + if (ret) + goto out_fb_release; + + ret = fb_set_var(info, &info->var); + if (ret) + goto out_fb_dealloc_cmap; + + ret = register_framebuffer(info); + if (ret) + goto out_fb_dealloc_cmap; + + lcd = devm_lcd_device_register(dev, "clps711x-lcd", dev, cfb, + &clps711x_lcd_ops); + if (!IS_ERR(lcd)) + return 0; + + ret = PTR_ERR(lcd); + unregister_framebuffer(info); + +out_fb_dealloc_cmap: + regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0); + fb_dealloc_cmap(&info->cmap); + +out_fb_release: + framebuffer_release(info); + + return ret; +} + +static int clps711x_fb_remove(struct platform_device *pdev) +{ + struct fb_info *info = platform_get_drvdata(pdev); + struct clps711x_fb_info *cfb = info->par; + + regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0); + + unregister_framebuffer(info); + fb_dealloc_cmap(&info->cmap); + framebuffer_release(info); + + return 0; +} + +static const struct of_device_id clps711x_fb_dt_ids[] = { + { .compatible = "cirrus,clps711x-fb", }, + { } +}; +MODULE_DEVICE_TABLE(of, clps711x_fb_dt_ids); + +static struct platform_driver clps711x_fb_driver = { + .driver = { + .name = CLPS711X_FB_NAME, + .owner = THIS_MODULE, + .of_match_table = clps711x_fb_dt_ids, + }, + .probe = clps711x_fb_probe, + .remove = clps711x_fb_remove, +}; +module_platform_driver(clps711x_fb_driver); + +MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); +MODULE_DESCRIPTION("Cirrus Logic CLPS711X FB driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/controlfb.c b/drivers/video/fbdev/controlfb.c index fdadef9..080fdd2 100644 --- a/drivers/video/fbdev/controlfb.c +++ b/drivers/video/fbdev/controlfb.c @@ -218,7 +218,8 @@ static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *i */ static int controlfb_set_par (struct fb_info *info) { - struct fb_info_control *p = (struct fb_info_control *) info; + struct fb_info_control *p = + container_of(info, struct fb_info_control, info); struct fb_par_control par; int err; @@ -258,7 +259,8 @@ static int controlfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { unsigned int xoffset, hstep; - struct fb_info_control *p = (struct fb_info_control *)info; + struct fb_info_control *p = + container_of(info, struct fb_info_control, info); struct fb_par_control *par = &p->par; /* @@ -309,7 +311,8 @@ static int controlfb_mmap(struct fb_info *info, static int controlfb_blank(int blank_mode, struct fb_info *info) { - struct fb_info_control *p = (struct fb_info_control *) info; + struct fb_info_control *p = + container_of(info, struct fb_info_control, info); unsigned ctrl; ctrl = ld_le32(CNTRL_REG(p,ctrl)); @@ -342,7 +345,8 @@ static int controlfb_blank(int blank_mode, struct fb_info *info) static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { - struct fb_info_control *p = (struct fb_info_control *) info; + struct fb_info_control *p = + container_of(info, struct fb_info_control, info); __u8 r, g, b; if (regno > 255) @@ -833,7 +837,8 @@ static int control_var_to_par(struct fb_var_screeninfo *var, unsigned hperiod, hssync, hsblank, hesync, heblank, piped, heq, hlfln, hserr, vperiod, vssync, vesync, veblank, vsblank, vswin, vewin; unsigned long pixclock; - struct fb_info_control *p = (struct fb_info_control *) fb_info; + struct fb_info_control *p = + container_of(fb_info, struct fb_info_control, info); struct control_regvals *r = &par->regvals; switch (var->bits_per_pixel) { diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile index fa30653..67f28e2 100644 --- a/drivers/video/fbdev/core/Makefile +++ b/drivers/video/fbdev/core/Makefile @@ -1,4 +1,5 @@ obj-y += fb_notify.o +obj-$(CONFIG_FB_CMDLINE) += fb_cmdline.o obj-$(CONFIG_FB) += fb.o fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ modedb.o fbcvt.o diff --git a/drivers/video/fbdev/core/cfbcopyarea.c b/drivers/video/fbdev/core/cfbcopyarea.c index bcb5723..6d4bfee 100644 --- a/drivers/video/fbdev/core/cfbcopyarea.c +++ b/drivers/video/fbdev/core/cfbcopyarea.c @@ -55,8 +55,8 @@ bitcpy(struct fb_info *p, unsigned long __iomem *dst, unsigned dst_idx, * If you suspect bug in this function, compare it with this simple * memmove implementation. */ - fb_memmove((char *)dst + ((dst_idx & (bits - 1))) / 8, - (char *)src + ((src_idx & (bits - 1))) / 8, n / 8); + memmove((char *)dst + ((dst_idx & (bits - 1))) / 8, + (char *)src + ((src_idx & (bits - 1))) / 8, n / 8); return; #endif @@ -221,8 +221,8 @@ bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, unsigned dst_idx, * If you suspect bug in this function, compare it with this simple * memmove implementation. */ - fb_memmove((char *)dst + ((dst_idx & (bits - 1))) / 8, - (char *)src + ((src_idx & (bits - 1))) / 8, n / 8); + memmove((char *)dst + ((dst_idx & (bits - 1))) / 8, + (char *)src + ((src_idx & (bits - 1))) / 8, n / 8); return; #endif @@ -324,7 +324,10 @@ bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, unsigned dst_idx, d0 = d0 << left | d1 >> right; } d0 = fb_rev_pixels_in_long(d0, bswapmask); - FB_WRITEL(comp(d0, FB_READL(dst), first), dst); + if (!first) + FB_WRITEL(d0, dst); + else + FB_WRITEL(comp(d0, FB_READL(dst), first), dst); d0 = d1; dst--; n -= dst_idx+1; diff --git a/drivers/video/fbdev/core/fb_cmdline.c b/drivers/video/fbdev/core/fb_cmdline.c new file mode 100644 index 0000000..39509cc --- /dev/null +++ b/drivers/video/fbdev/core/fb_cmdline.c @@ -0,0 +1,110 @@ +/* + * linux/drivers/video/fb_cmdline.c + * + * Copyright (C) 2014 Intel Corp + * Copyright (C) 1994 Martin Schaller + * + * 2001 - Documented with DocBook + * - Brad Douglas <brad@neruo.com> + * + * 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. + * + * Authors: + * Vetter <danie.vetter@ffwll.ch> + */ +#include <linux/init.h> +#include <linux/fb.h> + +static char *video_options[FB_MAX] __read_mostly; +static int ofonly __read_mostly; + +const char *fb_mode_option; +EXPORT_SYMBOL_GPL(fb_mode_option); + +/** + * fb_get_options - get kernel boot parameters + * @name: framebuffer name as it would appear in + * the boot parameter line + * (video=<name>:<options>) + * @option: the option will be stored here + * + * NOTE: Needed to maintain backwards compatibility + */ +int fb_get_options(const char *name, char **option) +{ + char *opt, *options = NULL; + int retval = 0; + int name_len = strlen(name), i; + + if (name_len && ofonly && strncmp(name, "offb", 4)) + retval = 1; + + if (name_len && !retval) { + for (i = 0; i < FB_MAX; i++) { + if (video_options[i] == NULL) + continue; + if (!video_options[i][0]) + continue; + opt = video_options[i]; + if (!strncmp(name, opt, name_len) && + opt[name_len] == ':') + options = opt + name_len + 1; + } + } + /* No match, pass global option */ + if (!options && option && fb_mode_option) + options = kstrdup(fb_mode_option, GFP_KERNEL); + if (options && !strncmp(options, "off", 3)) + retval = 1; + + if (option) + *option = options; + + return retval; +} +EXPORT_SYMBOL(fb_get_options); + +/** + * video_setup - process command line options + * @options: string of options + * + * Process command line options for frame buffer subsystem. + * + * NOTE: This function is a __setup and __init function. + * It only stores the options. Drivers have to call + * fb_get_options() as necessary. + * + * Returns zero. + * + */ +static int __init video_setup(char *options) +{ + int i, global = 0; + + if (!options || !*options) + global = 1; + + if (!global && !strncmp(options, "ofonly", 6)) { + ofonly = 1; + global = 1; + } + + if (!global && !strchr(options, ':')) { + fb_mode_option = options; + global = 1; + } + + if (!global) { + for (i = 0; i < FB_MAX; i++) { + if (video_options[i] == NULL) { + video_options[i] = options; + break; + } + } + } + + return 1; +} +__setup("video=", video_setup); diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index b5e85f6..0705d88 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1908,96 +1908,4 @@ int fb_new_modelist(struct fb_info *info) return err; } -static char *video_options[FB_MAX] __read_mostly; -static int ofonly __read_mostly; - -/** - * fb_get_options - get kernel boot parameters - * @name: framebuffer name as it would appear in - * the boot parameter line - * (video=<name>:<options>) - * @option: the option will be stored here - * - * NOTE: Needed to maintain backwards compatibility - */ -int fb_get_options(const char *name, char **option) -{ - char *opt, *options = NULL; - int retval = 0; - int name_len = strlen(name), i; - - if (name_len && ofonly && strncmp(name, "offb", 4)) - retval = 1; - - if (name_len && !retval) { - for (i = 0; i < FB_MAX; i++) { - if (video_options[i] == NULL) - continue; - if (!video_options[i][0]) - continue; - opt = video_options[i]; - if (!strncmp(name, opt, name_len) && - opt[name_len] == ':') - options = opt + name_len + 1; - } - } - /* No match, pass global option */ - if (!options && option && fb_mode_option) - options = kstrdup(fb_mode_option, GFP_KERNEL); - if (options && !strncmp(options, "off", 3)) - retval = 1; - - if (option) - *option = options; - - return retval; -} -EXPORT_SYMBOL(fb_get_options); - -#ifndef MODULE -/** - * video_setup - process command line options - * @options: string of options - * - * Process command line options for frame buffer subsystem. - * - * NOTE: This function is a __setup and __init function. - * It only stores the options. Drivers have to call - * fb_get_options() as necessary. - * - * Returns zero. - * - */ -static int __init video_setup(char *options) -{ - int i, global = 0; - - if (!options || !*options) - global = 1; - - if (!global && !strncmp(options, "ofonly", 6)) { - ofonly = 1; - global = 1; - } - - if (!global && !strchr(options, ':')) { - fb_mode_option = options; - global = 1; - } - - if (!global) { - for (i = 0; i < FB_MAX; i++) { - if (video_options[i] == NULL) { - video_options[i] = options; - break; - } - - } - } - - return 1; -} -__setup("video=", video_setup); -#endif - MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/core/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c index 53444ac..60c3f0a 100644 --- a/drivers/video/fbdev/core/fbsysfs.c +++ b/drivers/video/fbdev/core/fbsysfs.c @@ -485,16 +485,8 @@ static ssize_t show_bl_curve(struct device *device, mutex_lock(&fb_info->bl_curve_mutex); for (i = 0; i < FB_BACKLIGHT_LEVELS; i += 8) - len += snprintf(&buf[len], PAGE_SIZE, - "%02x %02x %02x %02x %02x %02x %02x %02x\n", - fb_info->bl_curve[i + 0], - fb_info->bl_curve[i + 1], - fb_info->bl_curve[i + 2], - fb_info->bl_curve[i + 3], - fb_info->bl_curve[i + 4], - fb_info->bl_curve[i + 5], - fb_info->bl_curve[i + 6], - fb_info->bl_curve[i + 7]); + len += snprintf(&buf[len], PAGE_SIZE, "%8ph\n", + fb_info->bl_curve + i); mutex_unlock(&fb_info->bl_curve_mutex); return len; diff --git a/drivers/video/fbdev/core/modedb.c b/drivers/video/fbdev/core/modedb.c index a9a907c..388f797 100644 --- a/drivers/video/fbdev/core/modedb.c +++ b/drivers/video/fbdev/core/modedb.c @@ -29,9 +29,6 @@ #define DPRINTK(fmt, args...) #endif -const char *fb_mode_option; -EXPORT_SYMBOL_GPL(fb_mode_option); - /* * Standard video mode definitions (taken from XFree86) */ diff --git a/drivers/video/fbdev/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c index b0a950f..99acf53 100644 --- a/drivers/video/fbdev/cyber2000fb.c +++ b/drivers/video/fbdev/cyber2000fb.c @@ -159,7 +159,7 @@ cyber2000_seqw(unsigned int reg, unsigned int val, struct cfb_info *cfb) static void cyber2000fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { - struct cfb_info *cfb = (struct cfb_info *)info; + struct cfb_info *cfb = container_of(info, struct cfb_info, fb); unsigned long dst, col; if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) { @@ -191,7 +191,7 @@ cyber2000fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) static void cyber2000fb_copyarea(struct fb_info *info, const struct fb_copyarea *region) { - struct cfb_info *cfb = (struct cfb_info *)info; + struct cfb_info *cfb = container_of(info, struct cfb_info, fb); unsigned int cmd = CO_CMD_L_PATTERN_FGCOL; unsigned long src, dst; @@ -241,7 +241,7 @@ cyber2000fb_imageblit(struct fb_info *info, const struct fb_image *image) static int cyber2000fb_sync(struct fb_info *info) { - struct cfb_info *cfb = (struct cfb_info *)info; + struct cfb_info *cfb = container_of(info, struct cfb_info, fb); int count = 100000; if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) @@ -276,7 +276,7 @@ static int cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { - struct cfb_info *cfb = (struct cfb_info *)info; + struct cfb_info *cfb = container_of(info, struct cfb_info, fb); struct fb_var_screeninfo *var = &cfb->fb.var; u32 pseudo_val; int ret = 1; @@ -758,7 +758,7 @@ cyber2000fb_decode_clock(struct par_info *hw, struct cfb_info *cfb, static int cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - struct cfb_info *cfb = (struct cfb_info *)info; + struct cfb_info *cfb = container_of(info, struct cfb_info, fb); struct par_info hw; unsigned int mem; int err; @@ -861,7 +861,7 @@ cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) static int cyber2000fb_set_par(struct fb_info *info) { - struct cfb_info *cfb = (struct cfb_info *)info; + struct cfb_info *cfb = container_of(info, struct cfb_info, fb); struct fb_var_screeninfo *var = &cfb->fb.var; struct par_info hw; unsigned int mem; @@ -971,7 +971,7 @@ static int cyber2000fb_set_par(struct fb_info *info) static int cyber2000fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - struct cfb_info *cfb = (struct cfb_info *)info; + struct cfb_info *cfb = container_of(info, struct cfb_info, fb); if (cyber2000fb_update_start(cfb, var)) return -EINVAL; @@ -1007,7 +1007,7 @@ cyber2000fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) */ static int cyber2000fb_blank(int blank, struct fb_info *info) { - struct cfb_info *cfb = (struct cfb_info *)info; + struct cfb_info *cfb = container_of(info, struct cfb_info, fb); unsigned int sync = 0; int i; diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c index a8484f7..10c876c 100644 --- a/drivers/video/fbdev/da8xx-fb.c +++ b/drivers/video/fbdev/da8xx-fb.c @@ -419,7 +419,7 @@ static void lcd_cfg_horizontal_sync(int back_porch, int pulse_width, { u32 reg; - reg = lcdc_read(LCD_RASTER_TIMING_0_REG) & 0xf; + reg = lcdc_read(LCD_RASTER_TIMING_0_REG) & 0x3ff; reg |= (((back_porch-1) & 0xff) << 24) | (((front_porch-1) & 0xff) << 16) | (((pulse_width-1) & 0x3f) << 10); @@ -1447,18 +1447,15 @@ static int fb_probe(struct platform_device *device) da8xx_fb_fix.line_length - 1; /* allocate palette buffer */ - par->v_palette_base = dma_alloc_coherent(NULL, - PALETTE_SIZE, - (resource_size_t *) - &par->p_palette_base, - GFP_KERNEL | GFP_DMA); + par->v_palette_base = dma_zalloc_coherent(NULL, PALETTE_SIZE, + (resource_size_t *)&par->p_palette_base, + GFP_KERNEL | GFP_DMA); if (!par->v_palette_base) { dev_err(&device->dev, "GLCD: kmalloc for palette buffer failed\n"); ret = -EINVAL; goto err_release_fb_mem; } - memset(par->v_palette_base, 0, PALETTE_SIZE); par->irq = platform_get_irq(device, 0); if (par->irq < 0) { diff --git a/drivers/video/fbdev/exynos/s6e8ax0.c b/drivers/video/fbdev/exynos/s6e8ax0.c index 29e70ed..95873f2 100644 --- a/drivers/video/fbdev/exynos/s6e8ax0.c +++ b/drivers/video/fbdev/exynos/s6e8ax0.c @@ -704,11 +704,6 @@ static int s6e8ax0_get_power(struct lcd_device *ld) return lcd->power; } -static int s6e8ax0_get_brightness(struct backlight_device *bd) -{ - return bd->props.brightness; -} - static int s6e8ax0_set_brightness(struct backlight_device *bd) { int ret = 0, brightness = bd->props.brightness; @@ -736,7 +731,6 @@ static struct lcd_ops s6e8ax0_lcd_ops = { }; static const struct backlight_ops s6e8ax0_backlight_ops = { - .get_brightness = s6e8ax0_get_brightness, .update_status = s6e8ax0_set_brightness, }; diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c index e23392e..4254336 100644 --- a/drivers/video/fbdev/hyperv_fb.c +++ b/drivers/video/fbdev/hyperv_fb.c @@ -224,6 +224,11 @@ struct hvfb_par { u32 pseudo_palette[16]; u8 init_buf[MAX_VMBUS_PKT_SIZE]; u8 recv_buf[MAX_VMBUS_PKT_SIZE]; + + /* If true, the VSC notifies the VSP on every framebuffer change */ + bool synchronous_fb; + + struct notifier_block hvfb_panic_nb; }; static uint screen_width = HVFB_WIDTH; @@ -532,6 +537,19 @@ static void hvfb_update_work(struct work_struct *w) schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY); } +static int hvfb_on_panic(struct notifier_block *nb, + unsigned long e, void *p) +{ + struct hvfb_par *par; + struct fb_info *info; + + par = container_of(nb, struct hvfb_par, hvfb_panic_nb); + par->synchronous_fb = true; + info = par->info; + synthvid_update(info); + + return NOTIFY_DONE; +} /* Framebuffer operation handlers */ @@ -582,14 +600,44 @@ static int hvfb_blank(int blank, struct fb_info *info) return 1; /* get fb_blank to set the colormap to all black */ } +static void hvfb_cfb_fillrect(struct fb_info *p, + const struct fb_fillrect *rect) +{ + struct hvfb_par *par = p->par; + + cfb_fillrect(p, rect); + if (par->synchronous_fb) + synthvid_update(p); +} + +static void hvfb_cfb_copyarea(struct fb_info *p, + const struct fb_copyarea *area) +{ + struct hvfb_par *par = p->par; + + cfb_copyarea(p, area); + if (par->synchronous_fb) + synthvid_update(p); +} + +static void hvfb_cfb_imageblit(struct fb_info *p, + const struct fb_image *image) +{ + struct hvfb_par *par = p->par; + + cfb_imageblit(p, image); + if (par->synchronous_fb) + synthvid_update(p); +} + static struct fb_ops hvfb_ops = { .owner = THIS_MODULE, .fb_check_var = hvfb_check_var, .fb_set_par = hvfb_set_par, .fb_setcolreg = hvfb_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = hvfb_cfb_fillrect, + .fb_copyarea = hvfb_cfb_copyarea, + .fb_imageblit = hvfb_cfb_imageblit, .fb_blank = hvfb_blank, }; @@ -801,6 +849,11 @@ static int hvfb_probe(struct hv_device *hdev, par->fb_ready = true; + par->synchronous_fb = false; + par->hvfb_panic_nb.notifier_call = hvfb_on_panic; + atomic_notifier_chain_register(&panic_notifier_list, + &par->hvfb_panic_nb); + return 0; error: @@ -820,6 +873,9 @@ static int hvfb_remove(struct hv_device *hdev) struct fb_info *info = hv_get_drvdata(hdev); struct hvfb_par *par = info->par; + atomic_notifier_chain_unregister(&panic_notifier_list, + &par->hvfb_panic_nb); + par->update = false; par->fb_ready = false; @@ -836,7 +892,7 @@ static int hvfb_remove(struct hv_device *hdev) } -static DEFINE_PCI_DEVICE_TABLE(pci_stub_id_table) = { +static const struct pci_device_id pci_stub_id_table[] = { { .vendor = PCI_VENDOR_ID_MICROSOFT, .device = PCI_DEVICE_ID_HYPERV_VIDEO, diff --git a/drivers/video/fbdev/i740fb.c b/drivers/video/fbdev/i740fb.c index ca7c9df..a2b4204 100644 --- a/drivers/video/fbdev/i740fb.c +++ b/drivers/video/fbdev/i740fb.c @@ -1260,7 +1260,7 @@ fail: #define I740_ID_PCI 0x00d1 #define I740_ID_AGP 0x7800 -static DEFINE_PCI_DEVICE_TABLE(i740fb_id_table) = { +static const struct pci_device_id i740fb_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, I740_ID_PCI) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, I740_ID_AGP) }, { 0 } diff --git a/drivers/video/fbdev/intelfb/intelfbhw.c b/drivers/video/fbdev/intelfb/intelfbhw.c index fbad61d..d31ed4e 100644 --- a/drivers/video/fbdev/intelfb/intelfbhw.c +++ b/drivers/video/fbdev/intelfb/intelfbhw.c @@ -1191,7 +1191,6 @@ int intelfbhw_mode_to_hw(struct intelfb_info *dinfo, vsync_end = vsync_start + var->vsync_len; vtotal = vsync_end + var->upper_margin; vblank_start = vactive; - vblank_end = vtotal; vblank_end = vsync_end + 1; DBG_MSG("V: act %d, ss %d, se %d, tot %d bs %d, be %d\n", @@ -1859,7 +1858,7 @@ void intelfbhw_cursor_init(struct intelfb_info *dinfo) tmp = INREG(CURSOR_CONTROL); tmp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE | CURSOR_ENABLE | CURSOR_STRIDE_MASK); - tmp = CURSOR_FORMAT_3C; + tmp |= CURSOR_FORMAT_3C; OUTREG(CURSOR_CONTROL, tmp); OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.offset << 12); tmp = (64 << CURSOR_SIZE_H_SHIFT) | diff --git a/drivers/video/fbdev/matrox/matroxfb_base.c b/drivers/video/fbdev/matrox/matroxfb_base.c index 7116c53..62539ca 100644 --- a/drivers/video/fbdev/matrox/matroxfb_base.c +++ b/drivers/video/fbdev/matrox/matroxfb_base.c @@ -1341,19 +1341,57 @@ struct video_board { struct matrox_switch* lowlevel; }; #ifdef CONFIG_FB_MATROX_MILLENIUM -static struct video_board vbMillennium = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGA2064W, &matrox_millennium}; -static struct video_board vbMillennium2 = {0x1000000, 0x0800000, FB_ACCEL_MATROX_MGA2164W, &matrox_millennium}; -static struct video_board vbMillennium2A = {0x1000000, 0x0800000, FB_ACCEL_MATROX_MGA2164W_AGP, &matrox_millennium}; +static struct video_board vbMillennium = { + .maxvram = 0x0800000, + .maxdisplayable = 0x0800000, + .accelID = FB_ACCEL_MATROX_MGA2064W, + .lowlevel = &matrox_millennium +}; + +static struct video_board vbMillennium2 = { + .maxvram = 0x1000000, + .maxdisplayable = 0x0800000, + .accelID = FB_ACCEL_MATROX_MGA2164W, + .lowlevel = &matrox_millennium +}; + +static struct video_board vbMillennium2A = { + .maxvram = 0x1000000, + .maxdisplayable = 0x0800000, + .accelID = FB_ACCEL_MATROX_MGA2164W_AGP, + .lowlevel = &matrox_millennium +}; #endif /* CONFIG_FB_MATROX_MILLENIUM */ #ifdef CONFIG_FB_MATROX_MYSTIQUE -static struct video_board vbMystique = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGA1064SG, &matrox_mystique}; +static struct video_board vbMystique = { + .maxvram = 0x0800000, + .maxdisplayable = 0x0800000, + .accelID = FB_ACCEL_MATROX_MGA1064SG, + .lowlevel = &matrox_mystique +}; #endif /* CONFIG_FB_MATROX_MYSTIQUE */ #ifdef CONFIG_FB_MATROX_G -static struct video_board vbG100 = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGAG100, &matrox_G100}; -static struct video_board vbG200 = {0x1000000, 0x1000000, FB_ACCEL_MATROX_MGAG200, &matrox_G100}; +static struct video_board vbG100 = { + .maxvram = 0x0800000, + .maxdisplayable = 0x0800000, + .accelID = FB_ACCEL_MATROX_MGAG100, + .lowlevel = &matrox_G100 +}; + +static struct video_board vbG200 = { + .maxvram = 0x1000000, + .maxdisplayable = 0x1000000, + .accelID = FB_ACCEL_MATROX_MGAG200, + .lowlevel = &matrox_G100 +}; /* from doc it looks like that accelerator can draw only to low 16MB :-( Direct accesses & displaying are OK for whole 32MB */ -static struct video_board vbG400 = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400, &matrox_G100}; +static struct video_board vbG400 = { + .maxvram = 0x2000000, + .maxdisplayable = 0x1000000, + .accelID = FB_ACCEL_MATROX_MGAG400, + .lowlevel = &matrox_G100 +}; #endif #define DEVF_VIDEO64BIT 0x0001 diff --git a/drivers/video/fbdev/matrox/matroxfb_maven.c b/drivers/video/fbdev/matrox/matroxfb_maven.c index ee41a0f..bf5ce04 100644 --- a/drivers/video/fbdev/matrox/matroxfb_maven.c +++ b/drivers/video/fbdev/matrox/matroxfb_maven.c @@ -201,21 +201,23 @@ struct matrox_pll_ctl { }; static const struct matrox_pll_features2 maven1000_pll = { - 50000000, - 300000000, - 5, 128, - 3, 32, - 3 + .vco_freq_min = 50000000, + .vco_freq_max = 300000000, + .feed_div_min = 5, + .feed_div_max = 128, + .in_div_min = 3, + .in_div_max = 32, + .post_shift_max = 3 }; static const struct matrox_pll_ctl maven_PAL = { - 540000, - 50 + .ref_freq = 540000, + .den = 50 }; static const struct matrox_pll_ctl maven_NTSC = { - 450450, /* 27027000/60 == 27000000/59.94005994 */ - 60 + .ref_freq = 450450, /* 27027000/60 == 27000000/59.94005994 */ + .den = 60 }; static int matroxfb_PLL_mavenclock(const struct matrox_pll_features2* pll, diff --git a/drivers/video/fbdev/mbx/mbxfb.c b/drivers/video/fbdev/mbx/mbxfb.c index 2bd52ed..698df954 100644 --- a/drivers/video/fbdev/mbx/mbxfb.c +++ b/drivers/video/fbdev/mbx/mbxfb.c @@ -628,14 +628,14 @@ static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd, case MBXFB_IOCS_PLANEORDER: if (copy_from_user(&porder, (void __user*)arg, sizeof(struct mbxfb_planeorder))) - return -EFAULT; + return -EFAULT; return mbxfb_ioctl_planeorder(&porder); case MBXFB_IOCS_ALPHA: if (copy_from_user(&alpha, (void __user*)arg, sizeof(struct mbxfb_alphaCtl))) - return -EFAULT; + return -EFAULT; return mbxfb_ioctl_alphactl(&alpha); diff --git a/drivers/video/fbdev/msm/mddi_client_dummy.c b/drivers/video/fbdev/msm/mddi_client_dummy.c index f1b0dfc..cdb8f69 100644 --- a/drivers/video/fbdev/msm/mddi_client_dummy.c +++ b/drivers/video/fbdev/msm/mddi_client_dummy.c @@ -15,6 +15,7 @@ * GNU General Public License for more details. */ +#include <linux/device.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/kernel.h> @@ -51,8 +52,7 @@ static int mddi_dummy_probe(struct platform_device *pdev) { struct msm_mddi_client_data *client_data = pdev->dev.platform_data; struct panel_info *panel = - kzalloc(sizeof(struct panel_info), GFP_KERNEL); - int ret; + devm_kzalloc(&pdev->dev, sizeof(struct panel_info), GFP_KERNEL); if (!panel) return -ENOMEM; platform_set_drvdata(pdev, panel); @@ -67,24 +67,11 @@ static int mddi_dummy_probe(struct platform_device *pdev) client_data->fb_resource, 1); panel->panel_data.fb_data = client_data->private_client_data; panel->pdev.dev.platform_data = &panel->panel_data; - ret = platform_device_register(&panel->pdev); - if (ret) { - kfree(panel); - return ret; - } - return 0; -} - -static int mddi_dummy_remove(struct platform_device *pdev) -{ - struct panel_info *panel = platform_get_drvdata(pdev); - kfree(panel); - return 0; + return platform_device_register(&panel->pdev); } static struct platform_driver mddi_client_dummy = { .probe = mddi_dummy_probe, - .remove = mddi_dummy_remove, .driver = { .name = "mddi_c_dummy" }, }; diff --git a/drivers/video/fbdev/msm/msm_fb.c b/drivers/video/fbdev/msm/msm_fb.c index 1374803..2979d7e7 100644 --- a/drivers/video/fbdev/msm/msm_fb.c +++ b/drivers/video/fbdev/msm/msm_fb.c @@ -569,8 +569,13 @@ static int msmfb_probe(struct platform_device *pdev) mutex_init(&msmfb->panel_init_lock); init_waitqueue_head(&msmfb->frame_wq); INIT_WORK(&msmfb->resume_work, power_on_panel); - msmfb->black = kzalloc(msmfb->fb->var.bits_per_pixel*msmfb->xres, - GFP_KERNEL); + msmfb->black = devm_kzalloc(&pdev->dev, + msmfb->fb->var.bits_per_pixel*msmfb->xres, + GFP_KERNEL); + if (!msmfb->black) { + ret = -ENOMEM; + goto error_register_framebuffer; + } printk(KERN_INFO "msmfb_probe() installing %d x %d panel\n", msmfb->xres, msmfb->yres); @@ -589,6 +594,8 @@ static int msmfb_probe(struct platform_device *pdev) msmfb->sleeping = WAKING; + platform_set_drvdata(pdev, msmfb); + return 0; error_register_framebuffer: @@ -598,9 +605,23 @@ error_setup_fbmem: return ret; } +static int msmfb_remove(struct platform_device *pdev) +{ + struct msmfb_info *msmfb; + + msmfb = platform_get_drvdata(pdev); + + unregister_framebuffer(msmfb->fb); + iounmap(msmfb->fb->screen_base); + framebuffer_release(msmfb->fb); + + return 0; +} + static struct platform_driver msm_panel_driver = { /* need to write remove */ .probe = msmfb_probe, + .remove = msmfb_remove, .driver = {.name = "msm_panel"}, }; diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c index c645a0a..23ec781e 100644 --- a/drivers/video/fbdev/mx3fb.c +++ b/drivers/video/fbdev/mx3fb.c @@ -461,8 +461,7 @@ static void sdc_disable_channel(struct mx3fb_info *mx3_fbi) spin_unlock_irqrestore(&mx3fb->lock, flags); - mx3_fbi->txd->chan->device->device_control(mx3_fbi->txd->chan, - DMA_TERMINATE_ALL, 0); + dmaengine_terminate_all(mx3_fbi->txd->chan); mx3_fbi->txd = NULL; mx3_fbi->cookie = -EINVAL; } @@ -1179,7 +1178,7 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var, /* * We enable the End of Frame interrupt, which will free a tx-descriptor, - * which we will need for the next device_prep_slave_sg(). The + * which we will need for the next dmaengine_prep_slave_sg(). The * IRQ-handler will disable the IRQ again. */ init_completion(&mx3_fbi->flip_cmpl); diff --git a/drivers/video/fbdev/nvidia/nv_backlight.c b/drivers/video/fbdev/nvidia/nv_backlight.c index 8471008..5c151b2 100644 --- a/drivers/video/fbdev/nvidia/nv_backlight.c +++ b/drivers/video/fbdev/nvidia/nv_backlight.c @@ -82,13 +82,7 @@ static int nvidia_bl_update_status(struct backlight_device *bd) return 0; } -static int nvidia_bl_get_brightness(struct backlight_device *bd) -{ - return bd->props.brightness; -} - static const struct backlight_ops nvidia_bl_ops = { - .get_brightness = nvidia_bl_get_brightness, .update_status = nvidia_bl_update_status, }; diff --git a/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c index 5ee3b55..9192166 100644 --- a/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c +++ b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c @@ -301,6 +301,8 @@ static const struct of_device_id tvc_of_match[] = { {}, }; +MODULE_DEVICE_TABLE(of, tvc_of_match); + static struct platform_driver tvc_connector_driver = { .probe = tvc_probe, .remove = __exit_p(tvc_remove), @@ -308,6 +310,7 @@ static struct platform_driver tvc_connector_driver = { .name = "connector-analog-tv", .owner = THIS_MODULE, .of_match_table = tvc_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c index 74de2bc..2dfb6e5 100644 --- a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c +++ b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c @@ -391,6 +391,7 @@ static struct platform_driver dvi_connector_driver = { .name = "connector-dvi", .owner = THIS_MODULE, .of_match_table = dvic_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c index 4420ccb..7b25967 100644 --- a/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c +++ b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c @@ -262,6 +262,23 @@ static int hdmic_audio_config(struct omap_dss_device *dssdev, return 0; } +static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode) +{ + struct panel_drv_data *ddata = to_panel_data(dssdev); + struct omap_dss_device *in = ddata->in; + + return in->ops.hdmi->set_hdmi_mode(in, hdmi_mode); +} + +static int hdmic_set_infoframe(struct omap_dss_device *dssdev, + const struct hdmi_avi_infoframe *avi) +{ + struct panel_drv_data *ddata = to_panel_data(dssdev); + struct omap_dss_device *in = ddata->in; + + return in->ops.hdmi->set_infoframe(in, avi); +} + static struct omap_dss_driver hdmic_driver = { .connect = hdmic_connect, .disconnect = hdmic_disconnect, @@ -277,6 +294,8 @@ static struct omap_dss_driver hdmic_driver = { .read_edid = hdmic_read_edid, .detect = hdmic_detect, + .set_hdmi_mode = hdmic_set_hdmi_mode, + .set_hdmi_infoframe = hdmic_set_infoframe, .audio_enable = hdmic_audio_enable, .audio_disable = hdmic_audio_disable, @@ -418,6 +437,7 @@ static struct platform_driver hdmi_connector_driver = { .name = "connector-hdmi", .owner = THIS_MODULE, .of_match_table = hdmic_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c index b4e9a42..47ee7cd 100644 --- a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c +++ b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c @@ -298,6 +298,7 @@ static struct platform_driver tfp410_driver = { .name = "tfp410", .owner = THIS_MODULE, .of_match_table = tfp410_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c index 7e33686..c4abd56 100644 --- a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c +++ b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c @@ -242,6 +242,24 @@ static int tpd_audio_config(struct omap_dss_device *dssdev, return in->ops.hdmi->audio_config(in, audio); } +static int tpd_set_infoframe(struct omap_dss_device *dssdev, + const struct hdmi_avi_infoframe *avi) +{ + struct panel_drv_data *ddata = to_panel_data(dssdev); + struct omap_dss_device *in = ddata->in; + + return in->ops.hdmi->set_infoframe(in, avi); +} + +static int tpd_set_hdmi_mode(struct omap_dss_device *dssdev, + bool hdmi_mode) +{ + struct panel_drv_data *ddata = to_panel_data(dssdev); + struct omap_dss_device *in = ddata->in; + + return in->ops.hdmi->set_hdmi_mode(in, hdmi_mode); +} + static const struct omapdss_hdmi_ops tpd_hdmi_ops = { .connect = tpd_connect, .disconnect = tpd_disconnect, @@ -255,6 +273,8 @@ static const struct omapdss_hdmi_ops tpd_hdmi_ops = { .read_edid = tpd_read_edid, .detect = tpd_detect, + .set_infoframe = tpd_set_infoframe, + .set_hdmi_mode = tpd_set_hdmi_mode, .audio_enable = tpd_audio_enable, .audio_disable = tpd_audio_disable, @@ -441,6 +461,7 @@ static struct platform_driver tpd_driver = { .name = "tpd12s015", .owner = THIS_MODULE, .of_match_table = tpd_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/panel-dpi.c b/drivers/video/fbdev/omap2/displays-new/panel-dpi.c index 3636b61..a9c3dcf 100644 --- a/drivers/video/fbdev/omap2/displays-new/panel-dpi.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-dpi.c @@ -327,6 +327,7 @@ static struct platform_driver panel_dpi_driver = { .name = "panel-dpi", .owner = THIS_MODULE, .of_match_table = panel_dpi_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c b/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c index d6f14e8..899cb1a 100644 --- a/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c @@ -1378,6 +1378,7 @@ static struct platform_driver dsicm_driver = { .name = "panel-dsi-cm", .owner = THIS_MODULE, .of_match_table = dsicm_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c index cc5b512..27d4fcf 100644 --- a/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c @@ -394,6 +394,7 @@ static struct spi_driver lb035q02_spi_driver = { .name = "panel_lgphilips_lb035q02", .owner = THIS_MODULE, .of_match_table = lb035q02_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c b/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c index 3595f11..ccf3f4f 100644 --- a/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c @@ -424,6 +424,7 @@ static struct spi_driver nec_8048_driver = { .owner = THIS_MODULE, .pm = NEC_8048_PM_OPS, .of_match_table = nec_8048_of_match, + .suppress_bind_attrs = true, }, .probe = nec_8048_probe, .remove = nec_8048_remove, diff --git a/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c index f1f72ce..234142c 100644 --- a/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c @@ -410,6 +410,7 @@ static struct platform_driver sharp_ls_driver = { .name = "panel-sharp-ls037v7dw01", .owner = THIS_MODULE, .of_match_table = sharp_ls_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c index c7ba4d8..337ccc5 100644 --- a/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c @@ -817,6 +817,10 @@ static int acx565akm_probe(struct spi_device *spi) bldev = backlight_device_register("acx565akm", &ddata->spi->dev, ddata, &acx565akm_bl_ops, &props); + if (IS_ERR(bldev)) { + r = PTR_ERR(bldev); + goto err_reg_bl; + } ddata->bl_dev = bldev; if (ddata->has_cabc) { r = sysfs_create_group(&bldev->dev.kobj, &bldev_attr_group); @@ -862,6 +866,7 @@ err_reg: sysfs_remove_group(&bldev->dev.kobj, &bldev_attr_group); err_sysfs: backlight_device_unregister(bldev); +err_reg_bl: err_detect: err_gpio: omap_dss_put_device(ddata->in); @@ -899,6 +904,7 @@ static struct spi_driver acx565akm_driver = { .name = "acx565akm", .owner = THIS_MODULE, .of_match_table = acx565akm_of_match, + .suppress_bind_attrs = true, }, .probe = acx565akm_probe, .remove = acx565akm_remove, diff --git a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c index 728808b..fbba0b8 100644 --- a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c @@ -500,6 +500,7 @@ static struct spi_driver td028ttec1_spi_driver = { .name = "panel-tpo-td028ttec1", .owner = THIS_MODULE, .of_match_table = td028ttec1_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c index de78ab0..5aba76b 100644 --- a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c @@ -673,6 +673,7 @@ static struct spi_driver tpo_td043_spi_driver = { .owner = THIS_MODULE, .pm = &tpo_td043_spi_pm, .of_match_table = tpo_td043_of_match, + .suppress_bind_attrs = true, }, .probe = tpo_td043_probe, .remove = tpo_td043_remove, diff --git a/drivers/video/fbdev/omap2/dss/Kconfig b/drivers/video/fbdev/omap2/dss/Kconfig index 285bcd1..3d5eb6c 100644 --- a/drivers/video/fbdev/omap2/dss/Kconfig +++ b/drivers/video/fbdev/omap2/dss/Kconfig @@ -5,6 +5,7 @@ menuconfig OMAP2_DSS tristate "OMAP2+ Display Subsystem support" select VIDEOMODE_HELPERS select OMAP2_DSS_INIT + select HDMI help OMAP2+ Display Subsystem support. diff --git a/drivers/video/fbdev/omap2/dss/apply.c b/drivers/video/fbdev/omap2/dss/apply.c index 0a0b084..663ccc3 100644 --- a/drivers/video/fbdev/omap2/dss/apply.c +++ b/drivers/video/fbdev/omap2/dss/apply.c @@ -1132,6 +1132,8 @@ static void dss_mgr_disable_compat(struct omap_overlay_manager *mgr) if (!mp->enabled) goto out; + wait_pending_extra_info_updates(); + if (!mgr_manual_update(mgr)) dispc_mgr_disable_sync(mgr->id); diff --git a/drivers/video/fbdev/omap2/dss/dispc-compat.c b/drivers/video/fbdev/omap2/dss/dispc-compat.c index 83779c2..633c461 100644 --- a/drivers/video/fbdev/omap2/dss/dispc-compat.c +++ b/drivers/video/fbdev/omap2/dss/dispc-compat.c @@ -634,13 +634,14 @@ void dispc_mgr_disable_sync(enum omap_channel channel) WARN_ON(1); } +static inline void dispc_irq_wait_handler(void *data, u32 mask) +{ + complete((struct completion *)data); +} + int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask, unsigned long timeout) { - void dispc_irq_wait_handler(void *data, u32 mask) - { - complete((struct completion *)data); - } int r; DECLARE_COMPLETION_ONSTACK(completion); diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c index 7aa33b0..0e9a74b 100644 --- a/drivers/video/fbdev/omap2/dss/dispc.c +++ b/drivers/video/fbdev/omap2/dss/dispc.c @@ -2879,19 +2879,24 @@ static bool _dispc_mgr_pclk_ok(enum omap_channel channel, bool dispc_mgr_timings_ok(enum omap_channel channel, const struct omap_video_timings *timings) { - bool timings_ok; - - timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res); + if (!_dispc_mgr_size_ok(timings->x_res, timings->y_res)) + return false; - timings_ok &= _dispc_mgr_pclk_ok(channel, timings->pixelclock); + if (!_dispc_mgr_pclk_ok(channel, timings->pixelclock)) + return false; if (dss_mgr_is_lcd(channel)) { - timings_ok &= _dispc_lcd_timings_ok(timings->hsw, timings->hfp, + /* TODO: OMAP4+ supports interlace for LCD outputs */ + if (timings->interlace) + return false; + + if (!_dispc_lcd_timings_ok(timings->hsw, timings->hfp, timings->hbp, timings->vsw, timings->vfp, - timings->vbp); + timings->vbp)) + return false; } - return timings_ok; + return true; } static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw, @@ -3257,13 +3262,10 @@ static void dispc_dump_regs(struct seq_file *s) if (i == OMAP_DSS_CHANNEL_DIGIT) continue; - DUMPREG(i, DISPC_DEFAULT_COLOR); - DUMPREG(i, DISPC_TRANS_COLOR); DUMPREG(i, DISPC_TIMING_H); DUMPREG(i, DISPC_TIMING_V); DUMPREG(i, DISPC_POL_FREQ); DUMPREG(i, DISPC_DIVISORo); - DUMPREG(i, DISPC_SIZE_MGR); DUMPREG(i, DISPC_DATA_CYCLE1); DUMPREG(i, DISPC_DATA_CYCLE2); @@ -3288,8 +3290,11 @@ static void dispc_dump_regs(struct seq_file *s) DUMPREG(i, DISPC_OVL_FIFO_SIZE_STATUS); DUMPREG(i, DISPC_OVL_ROW_INC); DUMPREG(i, DISPC_OVL_PIXEL_INC); + if (dss_has_feature(FEAT_PRELOAD)) DUMPREG(i, DISPC_OVL_PRELOAD); + if (dss_has_feature(FEAT_MFLAG)) + DUMPREG(i, DISPC_OVL_MFLAG_THRESHOLD); if (i == OMAP_DSS_GFX) { DUMPREG(i, DISPC_OVL_WINDOW_SKIP); @@ -3310,10 +3315,6 @@ static void dispc_dump_regs(struct seq_file *s) } if (dss_has_feature(FEAT_ATTR2)) DUMPREG(i, DISPC_OVL_ATTRIBUTES2); - if (dss_has_feature(FEAT_PRELOAD)) - DUMPREG(i, DISPC_OVL_PRELOAD); - if (dss_has_feature(FEAT_MFLAG)) - DUMPREG(i, DISPC_OVL_MFLAG_THRESHOLD); } #undef DISPC_REG @@ -3841,6 +3842,7 @@ static struct platform_driver omap_dispchw_driver = { .owner = THIS_MODULE, .pm = &dispc_pm_ops, .of_match_table = dispc_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/dss/dispc.h b/drivers/video/fbdev/omap2/dss/dispc.h index 78edb44..3043d6e 100644 --- a/drivers/video/fbdev/omap2/dss/dispc.h +++ b/drivers/video/fbdev/omap2/dss/dispc.h @@ -101,8 +101,7 @@ DISPC_FIR_COEF_V2_OFFSET(n, i)) #define DISPC_OVL_PRELOAD(n) (DISPC_OVL_BASE(n) + \ DISPC_PRELOAD_OFFSET(n)) -#define DISPC_OVL_MFLAG_THRESHOLD(n) (DISPC_OVL_BASE(n) + \ - DISPC_MFLAG_THRESHOLD_OFFSET(n)) +#define DISPC_OVL_MFLAG_THRESHOLD(n) DISPC_MFLAG_THRESHOLD_OFFSET(n) /* DISPC up/downsampling FIR filter coefficient structure */ struct dispc_coef { diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c index 9368972..4a3363d 100644 --- a/drivers/video/fbdev/omap2/dss/dpi.c +++ b/drivers/video/fbdev/omap2/dss/dpi.c @@ -720,6 +720,7 @@ static struct platform_driver omap_dpi_driver = { .driver = { .name = "omapdss_dpi", .owner = THIS_MODULE, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c index 4755a34..0793bc6 100644 --- a/drivers/video/fbdev/omap2/dss/dsi.c +++ b/drivers/video/fbdev/omap2/dss/dsi.c @@ -1603,7 +1603,7 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev, } else if (dss_has_feature(FEAT_DSI_PLL_SELFREQDCO)) { f = cinfo->clkin4ddr < 1000000000 ? 0x2 : 0x4; - l = FLD_MOD(l, f, 4, 1); /* PLL_SELFREQDCO */ + l = FLD_MOD(l, f, 3, 1); /* PLL_SELFREQDCO */ } l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ @@ -2571,7 +2571,10 @@ static int dsi_sync_vc_vp(struct platform_device *dsidev, int channel) { struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); DECLARE_COMPLETION_ONSTACK(completion); - struct dsi_packet_sent_handler_data vp_data = { dsidev, &completion }; + struct dsi_packet_sent_handler_data vp_data = { + .dsidev = dsidev, + .completion = &completion + }; int r = 0; u8 bit; @@ -2617,7 +2620,10 @@ static void dsi_packet_sent_handler_l4(void *data, u32 mask) static int dsi_sync_vc_l4(struct platform_device *dsidev, int channel) { DECLARE_COMPLETION_ONSTACK(completion); - struct dsi_packet_sent_handler_data l4_data = { dsidev, &completion }; + struct dsi_packet_sent_handler_data l4_data = { + .dsidev = dsidev, + .completion = &completion + }; int r = 0; r = dsi_register_isr_vc(dsidev, channel, dsi_packet_sent_handler_l4, @@ -5658,18 +5664,11 @@ err_runtime_get: return r; } -static int dsi_unregister_child(struct device *dev, void *data) -{ - struct platform_device *pdev = to_platform_device(dev); - platform_device_unregister(pdev); - return 0; -} - static int __exit omap_dsihw_remove(struct platform_device *dsidev) { struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); - device_for_each_child(&dsidev->dev, NULL, dsi_unregister_child); + of_platform_depopulate(&dsidev->dev); WARN_ON(dsi->scp_clk_refcount > 0); @@ -5755,6 +5754,7 @@ static struct platform_driver omap_dsihw_driver = { .owner = THIS_MODULE, .pm = &dsi_pm_ops, .of_match_table = dsi_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c index 6daeb7e..14bcd6c 100644 --- a/drivers/video/fbdev/omap2/dss/dss.c +++ b/drivers/video/fbdev/omap2/dss/dss.c @@ -966,6 +966,7 @@ static struct platform_driver omap_dsshw_driver = { .owner = THIS_MODULE, .pm = &dss_pm_ops, .of_match_table = dss_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h index fbee078..262771b 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi.h +++ b/drivers/video/fbdev/omap2/dss/hdmi.h @@ -22,6 +22,7 @@ #include <linux/delay.h> #include <linux/io.h> #include <linux/platform_device.h> +#include <linux/hdmi.h> #include <video/omapdss.h> #include "dss.h" @@ -142,7 +143,7 @@ enum hdmi_audio_samples_perword { HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1 }; -enum hdmi_audio_sample_size { +enum hdmi_audio_sample_size_omap { HDMI_AUDIO_SAMPLE_16BITS = 0, HDMI_AUDIO_SAMPLE_24BITS = 1 }; @@ -178,59 +179,6 @@ enum hdmi_audio_mclk_mode { HDMI_AUDIO_MCLK_192FS = 7 }; -/* INFOFRAME_AVI_ and INFOFRAME_AUDIO_ definitions */ -enum hdmi_core_infoframe { - HDMI_INFOFRAME_AVI_DB1Y_RGB = 0, - HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1, - HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2, - HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0, - HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON = 1, - HDMI_INFOFRAME_AVI_DB1B_NO = 0, - HDMI_INFOFRAME_AVI_DB1B_VERT = 1, - HDMI_INFOFRAME_AVI_DB1B_HORI = 2, - HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3, - HDMI_INFOFRAME_AVI_DB1S_0 = 0, - HDMI_INFOFRAME_AVI_DB1S_1 = 1, - HDMI_INFOFRAME_AVI_DB1S_2 = 2, - HDMI_INFOFRAME_AVI_DB2C_NO = 0, - HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1, - HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2, - HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3, - HDMI_INFOFRAME_AVI_DB2M_NO = 0, - HDMI_INFOFRAME_AVI_DB2M_43 = 1, - HDMI_INFOFRAME_AVI_DB2M_169 = 2, - HDMI_INFOFRAME_AVI_DB2R_SAME = 8, - HDMI_INFOFRAME_AVI_DB2R_43 = 9, - HDMI_INFOFRAME_AVI_DB2R_169 = 10, - HDMI_INFOFRAME_AVI_DB2R_149 = 11, - HDMI_INFOFRAME_AVI_DB3ITC_NO = 0, - HDMI_INFOFRAME_AVI_DB3ITC_YES = 1, - HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0, - HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1, - HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0, - HDMI_INFOFRAME_AVI_DB3Q_LR = 1, - HDMI_INFOFRAME_AVI_DB3Q_FR = 2, - HDMI_INFOFRAME_AVI_DB3SC_NO = 0, - HDMI_INFOFRAME_AVI_DB3SC_HORI = 1, - HDMI_INFOFRAME_AVI_DB3SC_VERT = 2, - HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3, - HDMI_INFOFRAME_AVI_DB5PR_NO = 0, - HDMI_INFOFRAME_AVI_DB5PR_2 = 1, - HDMI_INFOFRAME_AVI_DB5PR_3 = 2, - HDMI_INFOFRAME_AVI_DB5PR_4 = 3, - HDMI_INFOFRAME_AVI_DB5PR_5 = 4, - HDMI_INFOFRAME_AVI_DB5PR_6 = 5, - HDMI_INFOFRAME_AVI_DB5PR_7 = 6, - HDMI_INFOFRAME_AVI_DB5PR_8 = 7, - HDMI_INFOFRAME_AVI_DB5PR_9 = 8, - HDMI_INFOFRAME_AVI_DB5PR_10 = 9, -}; - -struct hdmi_cm { - int code; - int mode; -}; - struct hdmi_video_format { enum hdmi_packing_mode packing_mode; u32 y_res; /* Line per panel */ @@ -239,7 +187,8 @@ struct hdmi_video_format { struct hdmi_config { struct omap_video_timings timings; - struct hdmi_cm cm; + struct hdmi_avi_infoframe infoframe; + enum hdmi_core_hdmi_dvi hdmi_dvi_mode; }; /* HDMI PLL structure */ @@ -260,7 +209,7 @@ struct hdmi_audio_format { enum hdmi_audio_justify justification; enum hdmi_audio_sample_order sample_order; enum hdmi_audio_samples_perword samples_per_word; - enum hdmi_audio_sample_size sample_size; + enum hdmi_audio_sample_size_omap sample_size; enum hdmi_audio_blk_strt_end_sig en_sig_blk_strt_end; }; @@ -298,47 +247,6 @@ struct hdmi_core_audio_config { bool en_spdif; }; -/* - * Refer to section 8.2 in HDMI 1.3 specification for - * details about infoframe databytes - */ -struct hdmi_core_infoframe_avi { - /* Y0, Y1 rgb,yCbCr */ - u8 db1_format; - /* A0 Active information Present */ - u8 db1_active_info; - /* B0, B1 Bar info data valid */ - u8 db1_bar_info_dv; - /* S0, S1 scan information */ - u8 db1_scan_info; - /* C0, C1 colorimetry */ - u8 db2_colorimetry; - /* M0, M1 Aspect ratio (4:3, 16:9) */ - u8 db2_aspect_ratio; - /* R0...R3 Active format aspect ratio */ - u8 db2_active_fmt_ar; - /* ITC IT content. */ - u8 db3_itc; - /* EC0, EC1, EC2 Extended colorimetry */ - u8 db3_ec; - /* Q1, Q0 Quantization range */ - u8 db3_q_range; - /* SC1, SC0 Non-uniform picture scaling */ - u8 db3_nup_scaling; - /* VIC0..6 Video format identification */ - u8 db4_videocode; - /* PR0..PR3 Pixel repetition factor */ - u8 db5_pixel_repeat; - /* Line number end of top bar */ - u16 db6_7_line_eoftop; - /* Line number start of bottom bar */ - u16 db8_9_line_sofbottom; - /* Pixel number end of left bar */ - u16 db10_11_pixel_eofleft; - /* Pixel number start of right bar */ - u16 db12_13_pixel_sofright; -}; - struct hdmi_wp_data { void __iomem *base; }; @@ -358,8 +266,6 @@ struct hdmi_phy_data { struct hdmi_core_data { void __iomem *base; - - struct hdmi_core_infoframe_avi avi_cfg; }; static inline void hdmi_write_reg(void __iomem *base_addr, const u32 idx, @@ -425,9 +331,6 @@ int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy); int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes); /* HDMI common funcs */ -const struct hdmi_config *hdmi_default_timing(void); -const struct hdmi_config *hdmi_get_timings(int mode, int code); -struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing); int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep, struct hdmi_phy_data *phy); diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c index 626aad2..9a8713c 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi4.c +++ b/drivers/video/fbdev/omap2/dss/hdmi4.c @@ -281,29 +281,11 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev, static void hdmi_display_set_timing(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { - struct hdmi_cm cm; - const struct hdmi_config *t; - mutex_lock(&hdmi.lock); - cm = hdmi_get_code(timings); - hdmi.cfg.cm = cm; - - t = hdmi_get_timings(cm.mode, cm.code); - if (t != NULL) { - hdmi.cfg = *t; - - dispc_set_tv_pclk(t->timings.pixelclock); - } else { - hdmi.cfg.timings = *timings; - hdmi.cfg.cm.code = 0; - hdmi.cfg.cm.mode = HDMI_DVI; - - dispc_set_tv_pclk(timings->pixelclock); - } + hdmi.cfg.timings = *timings; - DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ? - "DVI" : "HDMI", hdmi.cfg.cm.code); + dispc_set_tv_pclk(timings->pixelclock); mutex_unlock(&hdmi.lock); } @@ -311,14 +293,7 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev, static void hdmi_display_get_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { - const struct hdmi_config *cfg; - struct hdmi_cm cm = hdmi.cfg.cm; - - cfg = hdmi_get_timings(cm.mode, cm.code); - if (cfg == NULL) - cfg = hdmi_default_timing(); - - memcpy(timings, &cfg->timings, sizeof(cfg->timings)); + *timings = hdmi.cfg.timings; } static void hdmi_dump_regs(struct seq_file *s) @@ -516,7 +491,7 @@ static int hdmi_audio_enable(struct omap_dss_device *dssdev) mutex_lock(&hdmi.lock); - if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { + if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) { r = -EPERM; goto err; } @@ -554,7 +529,7 @@ static bool hdmi_audio_supported(struct omap_dss_device *dssdev) mutex_lock(&hdmi.lock); - r = hdmi_mode_has_audio(hdmi.cfg.cm.mode); + r = hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode); mutex_unlock(&hdmi.lock); return r; @@ -568,7 +543,7 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev, mutex_lock(&hdmi.lock); - if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { + if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) { r = -EPERM; goto err; } @@ -615,6 +590,20 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev, } #endif +static int hdmi_set_infoframe(struct omap_dss_device *dssdev, + const struct hdmi_avi_infoframe *avi) +{ + hdmi.cfg.infoframe = *avi; + return 0; +} + +static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev, + bool hdmi_mode) +{ + hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI; + return 0; +} + static const struct omapdss_hdmi_ops hdmi_ops = { .connect = hdmi_connect, .disconnect = hdmi_disconnect, @@ -627,6 +616,8 @@ static const struct omapdss_hdmi_ops hdmi_ops = { .get_timings = hdmi_display_get_timings, .read_edid = hdmi_read_edid, + .set_infoframe = hdmi_set_infoframe, + .set_hdmi_mode = hdmi_set_hdmi_mode, .audio_enable = hdmi_audio_enable, .audio_disable = hdmi_audio_disable, @@ -790,6 +781,7 @@ static struct platform_driver omapdss_hdmihw_driver = { .owner = THIS_MODULE, .pm = &hdmi_pm_ops, .of_match_table = hdmi_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.c b/drivers/video/fbdev/omap2/dss/hdmi4_core.c index 8bde7b7..4ad39cf 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi4_core.c +++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.c @@ -197,9 +197,7 @@ int hdmi4_read_edid(struct hdmi_core_data *core, u8 *edid, int len) return l; } -static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, - struct hdmi_core_infoframe_avi *avi_cfg, - struct hdmi_core_packet_enable_repeat *repeat_cfg) +static void hdmi_core_init(struct hdmi_core_video_config *video_cfg) { DSSDBG("Enter hdmi_core_init\n"); @@ -210,35 +208,6 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE; video_cfg->hdmi_dvi = HDMI_DVI; video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK; - - /* info frame */ - avi_cfg->db1_format = 0; - avi_cfg->db1_active_info = 0; - avi_cfg->db1_bar_info_dv = 0; - avi_cfg->db1_scan_info = 0; - avi_cfg->db2_colorimetry = 0; - avi_cfg->db2_aspect_ratio = 0; - avi_cfg->db2_active_fmt_ar = 0; - avi_cfg->db3_itc = 0; - avi_cfg->db3_ec = 0; - avi_cfg->db3_q_range = 0; - avi_cfg->db3_nup_scaling = 0; - avi_cfg->db4_videocode = 0; - avi_cfg->db5_pixel_repeat = 0; - avi_cfg->db6_7_line_eoftop = 0; - avi_cfg->db8_9_line_sofbottom = 0; - avi_cfg->db10_11_pixel_eofleft = 0; - avi_cfg->db12_13_pixel_sofright = 0; - - /* packet enable and repeat */ - repeat_cfg->audio_pkt = 0; - repeat_cfg->audio_pkt_repeat = 0; - repeat_cfg->avi_infoframe = 0; - repeat_cfg->avi_infoframe_repeat = 0; - repeat_cfg->gen_cntrl_pkt = 0; - repeat_cfg->gen_cntrl_pkt_repeat = 0; - repeat_cfg->generic_pkt = 0; - repeat_cfg->generic_pkt_repeat = 0; } static void hdmi_core_powerdown_disable(struct hdmi_core_data *core) @@ -303,80 +272,22 @@ static void hdmi_core_video_config(struct hdmi_core_data *core, HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5); } -static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core) +static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core, + struct hdmi_avi_infoframe *frame) { - u32 val; - char sum = 0, checksum = 0; void __iomem *av_base = hdmi_av_base(core); - struct hdmi_core_infoframe_avi info_avi = core->avi_cfg; - - sum += 0x82 + 0x002 + 0x00D; - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_TYPE, 0x082); - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_VERS, 0x002); - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_LEN, 0x00D); - - val = (info_avi.db1_format << 5) | - (info_avi.db1_active_info << 4) | - (info_avi.db1_bar_info_dv << 2) | - (info_avi.db1_scan_info); - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(0), val); - sum += val; - - val = (info_avi.db2_colorimetry << 6) | - (info_avi.db2_aspect_ratio << 4) | - (info_avi.db2_active_fmt_ar); - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(1), val); - sum += val; - - val = (info_avi.db3_itc << 7) | - (info_avi.db3_ec << 4) | - (info_avi.db3_q_range << 2) | - (info_avi.db3_nup_scaling); - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(2), val); - sum += val; - - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(3), - info_avi.db4_videocode); - sum += info_avi.db4_videocode; - - val = info_avi.db5_pixel_repeat; - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(4), val); - sum += val; - - val = info_avi.db6_7_line_eoftop & 0x00FF; - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(5), val); - sum += val; - - val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF); - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(6), val); - sum += val; - - val = info_avi.db8_9_line_sofbottom & 0x00FF; - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(7), val); - sum += val; - - val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF); - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(8), val); - sum += val; - - val = info_avi.db10_11_pixel_eofleft & 0x00FF; - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(9), val); - sum += val; - - val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF); - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(10), val); - sum += val; - - val = info_avi.db12_13_pixel_sofright & 0x00FF; - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(11), val); - sum += val; - - val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF); - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(12), val); - sum += val; + u8 data[HDMI_INFOFRAME_SIZE(AVI)]; + int i; - checksum = 0x100 - sum; - hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_CHSUM, checksum); + hdmi_avi_infoframe_pack(frame, data, sizeof(data)); + + print_hex_dump_debug("AVI: ", DUMP_PREFIX_NONE, 16, 1, data, + HDMI_INFOFRAME_SIZE(AVI), false); + + for (i = 0; i < sizeof(data); ++i) { + hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_BASE + i * 4, + data[i]); + } } static void hdmi_core_av_packet_config(struct hdmi_core_data *core, @@ -404,11 +315,10 @@ void hdmi4_configure(struct hdmi_core_data *core, struct omap_video_timings video_timing; struct hdmi_video_format video_format; /* HDMI core */ - struct hdmi_core_infoframe_avi *avi_cfg = &core->avi_cfg; struct hdmi_core_video_config v_core_cfg; - struct hdmi_core_packet_enable_repeat repeat_cfg; + struct hdmi_core_packet_enable_repeat repeat_cfg = { 0 }; - hdmi_core_init(&v_core_cfg, avi_cfg, &repeat_cfg); + hdmi_core_init(&v_core_cfg); hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg); @@ -431,44 +341,24 @@ void hdmi4_configure(struct hdmi_core_data *core, hdmi_core_powerdown_disable(core); v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL; - v_core_cfg.hdmi_dvi = cfg->cm.mode; + v_core_cfg.hdmi_dvi = cfg->hdmi_dvi_mode; hdmi_core_video_config(core, &v_core_cfg); /* release software reset in the core */ hdmi_core_swreset_release(core); - /* - * configure packet - * info frame video see doc CEA861-D page 65 - */ - avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB; - avi_cfg->db1_active_info = - HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF; - avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO; - avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0; - avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO; - avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO; - avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME; - avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO; - avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601; - avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT; - avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO; - avi_cfg->db4_videocode = cfg->cm.code; - avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO; - avi_cfg->db6_7_line_eoftop = 0; - avi_cfg->db8_9_line_sofbottom = 0; - avi_cfg->db10_11_pixel_eofleft = 0; - avi_cfg->db12_13_pixel_sofright = 0; - - hdmi_core_aux_infoframe_avi_config(core); + if (cfg->hdmi_dvi_mode == HDMI_HDMI) { + hdmi_core_write_avi_infoframe(core, &cfg->infoframe); + + /* enable/repeat the infoframe */ + repeat_cfg.avi_infoframe = HDMI_PACKETENABLE; + repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON; + /* wakeup */ + repeat_cfg.audio_pkt = HDMI_PACKETENABLE; + repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON; + } - /* enable/repeat the infoframe */ - repeat_cfg.avi_infoframe = HDMI_PACKETENABLE; - repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON; - /* wakeup */ - repeat_cfg.audio_pkt = HDMI_PACKETENABLE; - repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON; hdmi_core_av_packet_config(core, repeat_cfg); } diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.h b/drivers/video/fbdev/omap2/dss/hdmi4_core.h index bb64689..827909e 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi4_core.h +++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.h @@ -145,6 +145,7 @@ #define HDMI_CORE_AV_DPD 0xF4 #define HDMI_CORE_AV_PB_CTRL1 0xF8 #define HDMI_CORE_AV_PB_CTRL2 0xFC +#define HDMI_CORE_AV_AVI_BASE 0x100 #define HDMI_CORE_AV_AVI_TYPE 0x100 #define HDMI_CORE_AV_AVI_VERS 0x104 #define HDMI_CORE_AV_AVI_LEN 0x108 diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c index c468b9e..169b764 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi5.c +++ b/drivers/video/fbdev/omap2/dss/hdmi5.c @@ -299,29 +299,11 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev, static void hdmi_display_set_timing(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { - struct hdmi_cm cm; - const struct hdmi_config *t; - mutex_lock(&hdmi.lock); - cm = hdmi_get_code(timings); - hdmi.cfg.cm = cm; - - t = hdmi_get_timings(cm.mode, cm.code); - if (t != NULL) { - hdmi.cfg = *t; - - dispc_set_tv_pclk(t->timings.pixelclock); - } else { - hdmi.cfg.timings = *timings; - hdmi.cfg.cm.code = 0; - hdmi.cfg.cm.mode = HDMI_DVI; - - dispc_set_tv_pclk(timings->pixelclock); - } + hdmi.cfg.timings = *timings; - DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ? - "DVI" : "HDMI", hdmi.cfg.cm.code); + dispc_set_tv_pclk(timings->pixelclock); mutex_unlock(&hdmi.lock); } @@ -329,14 +311,7 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev, static void hdmi_display_get_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { - const struct hdmi_config *cfg; - struct hdmi_cm cm = hdmi.cfg.cm; - - cfg = hdmi_get_timings(cm.mode, cm.code); - if (cfg == NULL) - cfg = hdmi_default_timing(); - - memcpy(timings, &cfg->timings, sizeof(cfg->timings)); + *timings = hdmi.cfg.timings; } static void hdmi_dump_regs(struct seq_file *s) @@ -541,7 +516,7 @@ static int hdmi_audio_enable(struct omap_dss_device *dssdev) mutex_lock(&hdmi.lock); - if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { + if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) { r = -EPERM; goto err; } @@ -579,7 +554,7 @@ static bool hdmi_audio_supported(struct omap_dss_device *dssdev) mutex_lock(&hdmi.lock); - r = hdmi_mode_has_audio(hdmi.cfg.cm.mode); + r = hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode); mutex_unlock(&hdmi.lock); return r; @@ -593,7 +568,7 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev, mutex_lock(&hdmi.lock); - if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { + if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) { r = -EPERM; goto err; } @@ -640,6 +615,20 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev, } #endif +static int hdmi_set_infoframe(struct omap_dss_device *dssdev, + const struct hdmi_avi_infoframe *avi) +{ + hdmi.cfg.infoframe = *avi; + return 0; +} + +static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev, + bool hdmi_mode) +{ + hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI; + return 0; +} + static const struct omapdss_hdmi_ops hdmi_ops = { .connect = hdmi_connect, .disconnect = hdmi_disconnect, @@ -652,6 +641,8 @@ static const struct omapdss_hdmi_ops hdmi_ops = { .get_timings = hdmi_display_get_timings, .read_edid = hdmi_read_edid, + .set_infoframe = hdmi_set_infoframe, + .set_hdmi_mode = hdmi_set_hdmi_mode, .audio_enable = hdmi_audio_enable, .audio_disable = hdmi_audio_disable, @@ -815,6 +806,7 @@ static struct platform_driver omapdss_hdmihw_driver = { .owner = THIS_MODULE, .pm = &hdmi_pm_ops, .of_match_table = hdmi_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.c b/drivers/video/fbdev/omap2/dss/hdmi5_core.c index 7528c7a..83acbf7 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi5_core.c +++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.c @@ -290,7 +290,6 @@ void hdmi5_core_dump(struct hdmi_core_data *core, struct seq_file *s) } static void hdmi_core_init(struct hdmi_core_vid_config *video_cfg, - struct hdmi_core_infoframe_avi *avi_cfg, struct hdmi_config *cfg) { DSSDBG("hdmi_core_init\n"); @@ -312,27 +311,8 @@ static void hdmi_core_init(struct hdmi_core_vid_config *video_cfg, video_cfg->vblank_osc = 0; /* Always 0 - need to confirm */ video_cfg->vblank = cfg->timings.vsw + cfg->timings.vfp + cfg->timings.vbp; - video_cfg->v_fc_config.cm.mode = cfg->cm.mode; + video_cfg->v_fc_config.hdmi_dvi_mode = cfg->hdmi_dvi_mode; video_cfg->v_fc_config.timings.interlace = cfg->timings.interlace; - - /* info frame */ - avi_cfg->db1_format = 0; - avi_cfg->db1_active_info = 0; - avi_cfg->db1_bar_info_dv = 0; - avi_cfg->db1_scan_info = 0; - avi_cfg->db2_colorimetry = 0; - avi_cfg->db2_aspect_ratio = 0; - avi_cfg->db2_active_fmt_ar = 0; - avi_cfg->db3_itc = 0; - avi_cfg->db3_ec = 0; - avi_cfg->db3_q_range = 0; - avi_cfg->db3_nup_scaling = 0; - avi_cfg->db4_videocode = 0; - avi_cfg->db5_pixel_repeat = 0; - avi_cfg->db6_7_line_eoftop = 0; - avi_cfg->db8_9_line_sofbottom = 0; - avi_cfg->db10_11_pixel_eofleft = 0; - avi_cfg->db12_13_pixel_sofright = 0; } /* DSS_HDMI_CORE_VIDEO_CONFIG */ @@ -398,7 +378,7 @@ static void hdmi_core_video_config(struct hdmi_core_data *core, /* select DVI mode */ REG_FLD_MOD(base, HDMI_CORE_FC_INVIDCONF, - cfg->v_fc_config.cm.mode, 3, 3); + cfg->v_fc_config.hdmi_dvi_mode, 3, 3); } static void hdmi_core_config_video_packetizer(struct hdmi_core_data *core) @@ -438,24 +418,60 @@ static void hdmi_core_config_video_sampler(struct hdmi_core_data *core) REG_FLD_MOD(core->base, HDMI_CORE_TX_INVID0, video_mapping, 4, 0); } -static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core) +static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core, + struct hdmi_avi_infoframe *frame) { void __iomem *base = core->base; - struct hdmi_core_infoframe_avi avi = core->avi_cfg; - - REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_format, 1, 0); - REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_active_info, 6, 6); - REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_bar_info_dv, 3, 2); - REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_scan_info, 5, 4); - REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_colorimetry, 7, 6); - REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_aspect_ratio, 5, 4); - REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_active_fmt_ar, 3, 0); - REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_itc, 7, 7); - REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_ec, 6, 4); - REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_q_range, 3, 2); - REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_nup_scaling, 1, 0); - REG_FLD_MOD(base, HDMI_CORE_FC_AVIVID, avi.db4_videocode, 6, 0); - REG_FLD_MOD(base, HDMI_CORE_FC_PRCONF, avi.db5_pixel_repeat, 3, 0); + u8 data[HDMI_INFOFRAME_SIZE(AVI)]; + u8 *ptr; + unsigned y, a, b, s; + unsigned c, m, r; + unsigned itc, ec, q, sc; + unsigned vic; + unsigned yq, cn, pr; + + hdmi_avi_infoframe_pack(frame, data, sizeof(data)); + + print_hex_dump_debug("AVI: ", DUMP_PREFIX_NONE, 16, 1, data, + HDMI_INFOFRAME_SIZE(AVI), false); + + ptr = data + HDMI_INFOFRAME_HEADER_SIZE; + + y = (ptr[0] >> 5) & 0x3; + a = (ptr[0] >> 4) & 0x1; + b = (ptr[0] >> 2) & 0x3; + s = (ptr[0] >> 0) & 0x3; + + c = (ptr[1] >> 6) & 0x3; + m = (ptr[1] >> 4) & 0x3; + r = (ptr[1] >> 0) & 0x3; + + itc = (ptr[2] >> 7) & 0x1; + ec = (ptr[2] >> 4) & 0x7; + q = (ptr[2] >> 2) & 0x3; + sc = (ptr[2] >> 0) & 0x3; + + vic = ptr[3]; + + yq = (ptr[4] >> 6) & 0x3; + cn = (ptr[4] >> 4) & 0x3; + pr = (ptr[4] >> 0) & 0xf; + + hdmi_write_reg(base, HDMI_CORE_FC_AVICONF0, + (a << 6) | (s << 4) | (b << 2) | (y << 0)); + + hdmi_write_reg(base, HDMI_CORE_FC_AVICONF1, + (c << 6) | (m << 4) | (r << 0)); + + hdmi_write_reg(base, HDMI_CORE_FC_AVICONF2, + (itc << 7) | (ec << 4) | (q << 2) | (sc << 0)); + + hdmi_write_reg(base, HDMI_CORE_FC_AVIVID, vic); + + hdmi_write_reg(base, HDMI_CORE_FC_AVICONF3, + (yq << 2) | (cn << 0)); + + REG_FLD_MOD(base, HDMI_CORE_FC_PRCONF, pr, 3, 0); } static void hdmi_core_csc_config(struct hdmi_core_data *core, @@ -497,10 +513,8 @@ static void hdmi_core_configure_range(struct hdmi_core_data *core) /* support limited range with 24 bit color depth for now */ csc_coeff = csc_table_deepcolor[0]; - core->avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_LR; hdmi_core_csc_config(core, csc_coeff); - hdmi_core_aux_infoframe_avi_config(core); } static void hdmi_core_enable_video_path(struct hdmi_core_data *core) @@ -591,11 +605,10 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp, struct omap_video_timings video_timing; struct hdmi_video_format video_format; struct hdmi_core_vid_config v_core_cfg; - struct hdmi_core_infoframe_avi *avi_cfg = &core->avi_cfg; hdmi_core_mask_interrupts(core); - hdmi_core_init(&v_core_cfg, avi_cfg, cfg); + hdmi_core_init(&v_core_cfg, cfg); hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg); @@ -608,7 +621,9 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp, hdmi_wp_video_config_interface(wp, &video_timing); + /* support limited range with 24 bit color depth for now */ hdmi_core_configure_range(core); + cfg->infoframe.quantization_range = HDMI_QUANTIZATION_RANGE_LIMITED; /* * configure core video part, set software reset in the core @@ -621,29 +636,8 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp, hdmi_core_config_csc(core); hdmi_core_config_video_sampler(core); - /* - * configure packet info frame video see doc CEA861-D page 65 - */ - avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB; - avi_cfg->db1_active_info = - HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF; - avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO; - avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0; - avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO; - avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO; - avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME; - avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO; - avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601; - avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT; - avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO; - avi_cfg->db4_videocode = cfg->cm.code; - avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO; - avi_cfg->db6_7_line_eoftop = 0; - avi_cfg->db8_9_line_sofbottom = 0; - avi_cfg->db10_11_pixel_eofleft = 0; - avi_cfg->db12_13_pixel_sofright = 0; - - hdmi_core_aux_infoframe_avi_config(core); + if (cfg->hdmi_dvi_mode == HDMI_HDMI) + hdmi_core_write_avi_infoframe(core, &cfg->infoframe); hdmi_core_enable_video_path(core); diff --git a/drivers/video/fbdev/omap2/dss/hdmi_common.c b/drivers/video/fbdev/omap2/dss/hdmi_common.c index 9a2c39c..7d5f103 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi_common.c +++ b/drivers/video/fbdev/omap2/dss/hdmi_common.c @@ -1,18 +1,4 @@ -/* - * Logic for the below structure : - * user enters the CEA or VESA timings by specifying the HDMI/DVI code. - * There is a correspondence between CEA/VESA timing and code, please - * refer to section 6.3 in HDMI 1.3 specification for timing code. - * - * In the below structure, cea_vesa_timings corresponds to all OMAP4 - * supported CEA and VESA timing values.code_cea corresponds to the CEA - * code, It is used to get the timing from cea_vesa_timing array.Similarly - * with code_vesa. Code_index is used for back mapping, that is once EDID - * is read from the TV, EDID is parsed to find the timing values and then - * map it to corresponding CEA or VESA index. - */ - #define DSS_SUBSYS_NAME "HDMI" #include <linux/kernel.h> @@ -22,308 +8,6 @@ #include "hdmi.h" -static const struct hdmi_config cea_timings[] = { - { - { 640, 480, 25200000, 96, 16, 48, 2, 10, 33, - OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, - false, }, - { 1, HDMI_HDMI }, - }, - { - { 720, 480, 27027000, 62, 16, 60, 6, 9, 30, - OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, - false, }, - { 2, HDMI_HDMI }, - }, - { - { 1280, 720, 74250000, 40, 110, 220, 5, 5, 20, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 4, HDMI_HDMI }, - }, - { - { 1920, 540, 74250000, 44, 88, 148, 5, 2, 15, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, - true, }, - { 5, HDMI_HDMI }, - }, - { - { 1440, 240, 27027000, 124, 38, 114, 3, 4, 15, - OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, - true, }, - { 6, HDMI_HDMI }, - }, - { - { 1920, 1080, 148500000, 44, 88, 148, 5, 4, 36, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 16, HDMI_HDMI }, - }, - { - { 720, 576, 27000000, 64, 12, 68, 5, 5, 39, - OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, - false, }, - { 17, HDMI_HDMI }, - }, - { - { 1280, 720, 74250000, 40, 440, 220, 5, 5, 20, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 19, HDMI_HDMI }, - }, - { - { 1920, 540, 74250000, 44, 528, 148, 5, 2, 15, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, - true, }, - { 20, HDMI_HDMI }, - }, - { - { 1440, 288, 27000000, 126, 24, 138, 3, 2, 19, - OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, - true, }, - { 21, HDMI_HDMI }, - }, - { - { 1440, 576, 54000000, 128, 24, 136, 5, 5, 39, - OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, - false, }, - { 29, HDMI_HDMI }, - }, - { - { 1920, 1080, 148500000, 44, 528, 148, 5, 4, 36, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 31, HDMI_HDMI }, - }, - { - { 1920, 1080, 74250000, 44, 638, 148, 5, 4, 36, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 32, HDMI_HDMI }, - }, - { - { 2880, 480, 108108000, 248, 64, 240, 6, 9, 30, - OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, - false, }, - { 35, HDMI_HDMI }, - }, - { - { 2880, 576, 108000000, 256, 48, 272, 5, 5, 39, - OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, - false, }, - { 37, HDMI_HDMI }, - }, -}; - -static const struct hdmi_config vesa_timings[] = { -/* VESA From Here */ - { - { 640, 480, 25175000, 96, 16, 48, 2, 11, 31, - OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, - false, }, - { 4, HDMI_DVI }, - }, - { - { 800, 600, 40000000, 128, 40, 88, 4, 1, 23, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 9, HDMI_DVI }, - }, - { - { 848, 480, 33750000, 112, 16, 112, 8, 6, 23, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 0xE, HDMI_DVI }, - }, - { - { 1280, 768, 79500000, 128, 64, 192, 7, 3, 20, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, - false, }, - { 0x17, HDMI_DVI }, - }, - { - { 1280, 800, 83500000, 128, 72, 200, 6, 3, 22, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, - false, }, - { 0x1C, HDMI_DVI }, - }, - { - { 1360, 768, 85500000, 112, 64, 256, 6, 3, 18, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 0x27, HDMI_DVI }, - }, - { - { 1280, 960, 108000000, 112, 96, 312, 3, 1, 36, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 0x20, HDMI_DVI }, - }, - { - { 1280, 1024, 108000000, 112, 48, 248, 3, 1, 38, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 0x23, HDMI_DVI }, - }, - { - { 1024, 768, 65000000, 136, 24, 160, 6, 3, 29, - OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, - false, }, - { 0x10, HDMI_DVI }, - }, - { - { 1400, 1050, 121750000, 144, 88, 232, 4, 3, 32, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, - false, }, - { 0x2A, HDMI_DVI }, - }, - { - { 1440, 900, 106500000, 152, 80, 232, 6, 3, 25, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, - false, }, - { 0x2F, HDMI_DVI }, - }, - { - { 1680, 1050, 146250000, 176 , 104, 280, 6, 3, 30, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, - false, }, - { 0x3A, HDMI_DVI }, - }, - { - { 1366, 768, 85500000, 143, 70, 213, 3, 3, 24, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 0x51, HDMI_DVI }, - }, - { - { 1920, 1080, 148500000, 44, 148, 80, 5, 4, 36, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 0x52, HDMI_DVI }, - }, - { - { 1280, 768, 68250000, 32, 48, 80, 7, 3, 12, - OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 0x16, HDMI_DVI }, - }, - { - { 1400, 1050, 101000000, 32, 48, 80, 4, 3, 23, - OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 0x29, HDMI_DVI }, - }, - { - { 1680, 1050, 119000000, 32, 48, 80, 6, 3, 21, - OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 0x39, HDMI_DVI }, - }, - { - { 1280, 800, 79500000, 32, 48, 80, 6, 3, 14, - OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 0x1B, HDMI_DVI }, - }, - { - { 1280, 720, 74250000, 40, 110, 220, 5, 5, 20, - OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 0x55, HDMI_DVI }, - }, - { - { 1920, 1200, 154000000, 32, 48, 80, 6, 3, 26, - OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, - false, }, - { 0x44, HDMI_DVI }, - }, -}; - -const struct hdmi_config *hdmi_default_timing(void) -{ - return &vesa_timings[0]; -} - -static const struct hdmi_config *hdmi_find_timing(int code, - const struct hdmi_config *timings_arr, int len) -{ - int i; - - for (i = 0; i < len; i++) { - if (timings_arr[i].cm.code == code) - return &timings_arr[i]; - } - - return NULL; -} - -const struct hdmi_config *hdmi_get_timings(int mode, int code) -{ - const struct hdmi_config *arr; - int len; - - if (mode == HDMI_DVI) { - arr = vesa_timings; - len = ARRAY_SIZE(vesa_timings); - } else { - arr = cea_timings; - len = ARRAY_SIZE(cea_timings); - } - - return hdmi_find_timing(code, arr, len); -} - -static bool hdmi_timings_compare(struct omap_video_timings *timing1, - const struct omap_video_timings *timing2) -{ - int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; - - if ((DIV_ROUND_CLOSEST(timing2->pixelclock, 1000000) == - DIV_ROUND_CLOSEST(timing1->pixelclock, 1000000)) && - (timing2->x_res == timing1->x_res) && - (timing2->y_res == timing1->y_res)) { - - timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp; - timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp; - timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp; - timing1_vsync = timing1->vfp + timing1->vsw + timing1->vbp; - - DSSDBG("timing1_hsync = %d timing1_vsync = %d"\ - "timing2_hsync = %d timing2_vsync = %d\n", - timing1_hsync, timing1_vsync, - timing2_hsync, timing2_vsync); - - if ((timing1_hsync == timing2_hsync) && - (timing1_vsync == timing2_vsync)) { - return true; - } - } - return false; -} - -struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) -{ - int i; - struct hdmi_cm cm = {-1}; - DSSDBG("hdmi_get_code\n"); - - for (i = 0; i < ARRAY_SIZE(cea_timings); i++) { - if (hdmi_timings_compare(timing, &cea_timings[i].timings)) { - cm = cea_timings[i].cm; - goto end; - } - } - for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) { - if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) { - cm = vesa_timings[i].cm; - goto end; - } - } - -end: - return cm; -} - int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep, struct hdmi_phy_data *phy) { diff --git a/drivers/video/fbdev/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c index 54df12a..6d92bb3 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi_pll.c +++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c @@ -124,16 +124,15 @@ static int hdmi_pll_config(struct hdmi_pll_data *pll) r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */ r = FLD_MOD(r, fmt->refsel, 22, 21); /* REFSEL */ - if (fmt->dcofreq) { - /* divider programming for frequency beyond 1000Mhz */ - REG_FLD_MOD(pll->base, PLLCTRL_CFG3, fmt->regsd, 17, 10); + if (fmt->dcofreq) r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */ - } else { + else r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */ - } hdmi_write_reg(pll->base, PLLCTRL_CFG2, r); + REG_FLD_MOD(pll->base, PLLCTRL_CFG3, fmt->regsd, 17, 10); + r = hdmi_read_reg(pll->base, PLLCTRL_CFG4); r = FLD_MOD(r, fmt->regm2, 24, 18); r = FLD_MOD(r, fmt->regmf, 17, 0); @@ -144,8 +143,8 @@ static int hdmi_pll_config(struct hdmi_pll_data *pll) /* wait for bit change */ if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_GO, - 0, 0, 1) != 1) { - DSSERR("PLL GO bit not set\n"); + 0, 0, 0) != 0) { + DSSERR("PLL GO bit not clearing\n"); return -ETIMEDOUT; } diff --git a/drivers/video/fbdev/omap2/dss/manager-sysfs.c b/drivers/video/fbdev/omap2/dss/manager-sysfs.c index 37b59fe..a7414fb 100644 --- a/drivers/video/fbdev/omap2/dss/manager-sysfs.c +++ b/drivers/video/fbdev/omap2/dss/manager-sysfs.c @@ -44,6 +44,13 @@ static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf) dssdev->name : "<none>"); } +static int manager_display_match(struct omap_dss_device *dssdev, void *data) +{ + const char *str = data; + + return sysfs_streq(dssdev->name, str); +} + static ssize_t manager_display_store(struct omap_overlay_manager *mgr, const char *buf, size_t size) { @@ -52,17 +59,12 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr, struct omap_dss_device *dssdev = NULL; struct omap_dss_device *old_dssdev; - int match(struct omap_dss_device *dssdev, void *data) - { - const char *str = data; - return sysfs_streq(dssdev->name, str); - } - if (buf[size-1] == '\n') --len; if (len > 0) - dssdev = omap_dss_find_device((void *)buf, match); + dssdev = omap_dss_find_device((void *)buf, + manager_display_match); if (len > 0 && dssdev == NULL) return -EINVAL; diff --git a/drivers/video/fbdev/omap2/dss/rfbi.c b/drivers/video/fbdev/omap2/dss/rfbi.c index c8a81a2..878273f 100644 --- a/drivers/video/fbdev/omap2/dss/rfbi.c +++ b/drivers/video/fbdev/omap2/dss/rfbi.c @@ -1044,6 +1044,7 @@ static struct platform_driver omap_rfbihw_driver = { .name = "omapdss_rfbi", .owner = THIS_MODULE, .pm = &rfbi_pm_ops, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/dss/sdi.c b/drivers/video/fbdev/omap2/dss/sdi.c index 911dcc9..4c9c46d 100644 --- a/drivers/video/fbdev/omap2/dss/sdi.c +++ b/drivers/video/fbdev/omap2/dss/sdi.c @@ -377,6 +377,7 @@ static struct platform_driver omap_sdi_driver = { .driver = { .name = "omapdss_sdi", .owner = THIS_MODULE, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/dss/venc.c b/drivers/video/fbdev/omap2/dss/venc.c index 21d8111..d077d8a 100644 --- a/drivers/video/fbdev/omap2/dss/venc.c +++ b/drivers/video/fbdev/omap2/dss/venc.c @@ -966,6 +966,7 @@ static struct platform_driver omap_venchw_driver = { .owner = THIS_MODULE, .pm = &venc_pm_ops, .of_match_table = venc_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c index ec2d132..ce8a705 100644 --- a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c +++ b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c @@ -273,16 +273,16 @@ static struct omapfb_colormode omapfb_colormodes[] = { }, }; +static bool cmp_component(struct fb_bitfield *f1, struct fb_bitfield *f2) +{ + return f1->length == f2->length && + f1->offset == f2->offset && + f1->msb_right == f2->msb_right; +} + static bool cmp_var_to_colormode(struct fb_var_screeninfo *var, struct omapfb_colormode *color) { - bool cmp_component(struct fb_bitfield *f1, struct fb_bitfield *f2) - { - return f1->length == f2->length && - f1->offset == f2->offset && - f1->msb_right == f2->msb_right; - } - if (var->bits_per_pixel == 0 || var->red.length == 0 || var->blue.length == 0 || @@ -1833,14 +1833,13 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev) if (fbdev == NULL) return; - for (i = 0; i < fbdev->num_fbs; i++) { - struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); - int j; + for (i = 0; i < fbdev->num_overlays; i++) { + struct omap_overlay *ovl = fbdev->overlays[i]; - for (j = 0; j < ofbi->num_overlays; j++) { - struct omap_overlay *ovl = ofbi->overlays[j]; - ovl->disable(ovl); - } + ovl->disable(ovl); + + if (ovl->manager) + ovl->unset_manager(ovl); } for (i = 0; i < fbdev->num_fbs; i++) @@ -2619,7 +2618,7 @@ err0: return r; } -static int __exit omapfb_remove(struct platform_device *pdev) +static int omapfb_remove(struct platform_device *pdev) { struct omapfb2_device *fbdev = platform_get_drvdata(pdev); @@ -2636,7 +2635,7 @@ static int __exit omapfb_remove(struct platform_device *pdev) static struct platform_driver omapfb_driver = { .probe = omapfb_probe, - .remove = __exit_p(omapfb_remove), + .remove = omapfb_remove, .driver = { .name = "omapfb", .owner = THIS_MODULE, @@ -2651,6 +2650,7 @@ module_param_named(mirror, def_mirror, bool, 0); module_platform_driver(omapfb_driver); +MODULE_ALIAS("platform:omapfb"); MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>"); MODULE_DESCRIPTION("OMAP2/3 Framebuffer"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c index 167cfff..7c74f58 100644 --- a/drivers/video/fbdev/pvr2fb.c +++ b/drivers/video/fbdev/pvr2fb.c @@ -1001,7 +1001,7 @@ static int pvr2_get_param(const struct pvr2_params *p, const char *s, int val, for (i = 0 ; i < size ; i++ ) { if (s != NULL) { - if (!strnicmp(p[i].name, s, strlen(s))) + if (!strncasecmp(p[i].name, s, strlen(s))) return p[i].val; } else { if (p[i].val == val) diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c index 1ecd9ce..a5acca8 100644 --- a/drivers/video/fbdev/pxafb.c +++ b/drivers/video/fbdev/pxafb.c @@ -138,7 +138,7 @@ static int pxafb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, u_int trans, struct fb_info *info) { - struct pxafb_info *fbi = (struct pxafb_info *)info; + struct pxafb_info *fbi = container_of(info, struct pxafb_info, fb); u_int val; if (regno >= fbi->palette_size) @@ -183,7 +183,7 @@ static int pxafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int trans, struct fb_info *info) { - struct pxafb_info *fbi = (struct pxafb_info *)info; + struct pxafb_info *fbi = container_of(info, struct pxafb_info, fb); unsigned int val; int ret = 1; @@ -456,7 +456,7 @@ static int pxafb_adjust_timing(struct pxafb_info *fbi, */ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - struct pxafb_info *fbi = (struct pxafb_info *)info; + struct pxafb_info *fbi = container_of(info, struct pxafb_info, fb); struct pxafb_mach_info *inf = dev_get_platdata(fbi->dev); int err; @@ -494,7 +494,7 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) */ static int pxafb_set_par(struct fb_info *info) { - struct pxafb_info *fbi = (struct pxafb_info *)info; + struct pxafb_info *fbi = container_of(info, struct pxafb_info, fb); struct fb_var_screeninfo *var = &info->var; if (var->bits_per_pixel >= 16) @@ -533,7 +533,7 @@ static int pxafb_set_par(struct fb_info *info) static int pxafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - struct pxafb_info *fbi = (struct pxafb_info *)info; + struct pxafb_info *fbi = container_of(info, struct pxafb_info, fb); struct fb_var_screeninfo newvar; int dma = DMA_MAX + DMA_BASE; @@ -566,7 +566,7 @@ static int pxafb_pan_display(struct fb_var_screeninfo *var, */ static int pxafb_blank(int blank, struct fb_info *info) { - struct pxafb_info *fbi = (struct pxafb_info *)info; + struct pxafb_info *fbi = container_of(info, struct pxafb_info, fb); int i; switch (blank) { @@ -725,7 +725,7 @@ static struct pxafb_layer_ops ofb_ops[] = { static int overlayfb_open(struct fb_info *info, int user) { - struct pxafb_layer *ofb = (struct pxafb_layer *)info; + struct pxafb_layer *ofb = container_of(info, struct pxafb_layer, fb); /* no support for framebuffer console on overlay */ if (user == 0) @@ -743,7 +743,7 @@ static int overlayfb_open(struct fb_info *info, int user) static int overlayfb_release(struct fb_info *info, int user) { - struct pxafb_layer *ofb = (struct pxafb_layer*) info; + struct pxafb_layer *ofb = container_of(info, struct pxafb_layer, fb); if (ofb->usage == 1) { ofb->ops->disable(ofb); @@ -760,7 +760,7 @@ static int overlayfb_release(struct fb_info *info, int user) static int overlayfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - struct pxafb_layer *ofb = (struct pxafb_layer *)info; + struct pxafb_layer *ofb = container_of(info, struct pxafb_layer, fb); struct fb_var_screeninfo *base_var = &ofb->fbi->fb.var; int xpos, ypos, pfor, bpp; @@ -836,7 +836,7 @@ static int overlayfb_check_video_memory(struct pxafb_layer *ofb) static int overlayfb_set_par(struct fb_info *info) { - struct pxafb_layer *ofb = (struct pxafb_layer *)info; + struct pxafb_layer *ofb = container_of(info, struct pxafb_layer, fb); struct fb_var_screeninfo *var = &info->var; int xpos, ypos, pfor, bpp, ret; diff --git a/drivers/video/fbdev/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c index 8a8d7f0..be73727 100644 --- a/drivers/video/fbdev/riva/fbdev.c +++ b/drivers/video/fbdev/riva/fbdev.c @@ -326,13 +326,7 @@ static int riva_bl_update_status(struct backlight_device *bd) return 0; } -static int riva_bl_get_brightness(struct backlight_device *bd) -{ - return bd->props.brightness; -} - static const struct backlight_ops riva_bl_ops = { - .get_brightness = riva_bl_get_brightness, .update_status = riva_bl_update_status, }; diff --git a/drivers/video/fbdev/riva/riva_hw.c b/drivers/video/fbdev/riva/riva_hw.c index 78fdbf5..8bdf37f 100644 --- a/drivers/video/fbdev/riva/riva_hw.c +++ b/drivers/video/fbdev/riva/riva_hw.c @@ -430,7 +430,6 @@ static char nv3_arb(nv3_fifo_info * res_info, nv3_sim_state * state, nv3_arb_in int mmisses, gmisses, vmisses, eburst_size, mburst_size; int refresh_cycle; - refresh_cycle = 0; refresh_cycle = 2*(state->mclk_khz/state->pclk_khz) + 5; mmisses = 2; if (state->mem_aligned) gmisses = 2; diff --git a/drivers/video/fbdev/s3c-fb.c b/drivers/video/fbdev/s3c-fb.c index 62acae2..b33abb0 100644 --- a/drivers/video/fbdev/s3c-fb.c +++ b/drivers/video/fbdev/s3c-fb.c @@ -1805,38 +1805,6 @@ static struct s3c_fb_driverdata s3c_fb_data_64xx = { .win[4] = &s3c_fb_data_64xx_wins[4], }; -static struct s3c_fb_driverdata s3c_fb_data_s5pc100 = { - .variant = { - .nr_windows = 5, - .vidtcon = VIDTCON0, - .wincon = WINCON(0), - .winmap = WINxMAP(0), - .keycon = WKEYCON, - .osd = VIDOSD_BASE, - .osd_stride = 16, - .buf_start = VIDW_BUF_START(0), - .buf_size = VIDW_BUF_SIZE(0), - .buf_end = VIDW_BUF_END(0), - - .palette = { - [0] = 0x2400, - [1] = 0x2800, - [2] = 0x2c00, - [3] = 0x3000, - [4] = 0x3400, - }, - - .has_prtcon = 1, - .has_blendcon = 1, - .has_clksel = 1, - }, - .win[0] = &s3c_fb_data_s5p_wins[0], - .win[1] = &s3c_fb_data_s5p_wins[1], - .win[2] = &s3c_fb_data_s5p_wins[2], - .win[3] = &s3c_fb_data_s5p_wins[3], - .win[4] = &s3c_fb_data_s5p_wins[4], -}; - static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = { .variant = { .nr_windows = 5, @@ -1970,41 +1938,11 @@ static struct s3c_fb_driverdata s3c_fb_data_s3c2443 = { }, }; -static struct s3c_fb_driverdata s3c_fb_data_s5p64x0 = { - .variant = { - .nr_windows = 3, - .vidtcon = VIDTCON0, - .wincon = WINCON(0), - .winmap = WINxMAP(0), - .keycon = WKEYCON, - .osd = VIDOSD_BASE, - .osd_stride = 16, - .buf_start = VIDW_BUF_START(0), - .buf_size = VIDW_BUF_SIZE(0), - .buf_end = VIDW_BUF_END(0), - - .palette = { - [0] = 0x2400, - [1] = 0x2800, - [2] = 0x2c00, - }, - - .has_blendcon = 1, - .has_fixvclk = 1, - }, - .win[0] = &s3c_fb_data_s5p_wins[0], - .win[1] = &s3c_fb_data_s5p_wins[1], - .win[2] = &s3c_fb_data_s5p_wins[2], -}; - static struct platform_device_id s3c_fb_driver_ids[] = { { .name = "s3c-fb", .driver_data = (unsigned long)&s3c_fb_data_64xx, }, { - .name = "s5pc100-fb", - .driver_data = (unsigned long)&s3c_fb_data_s5pc100, - }, { .name = "s5pv210-fb", .driver_data = (unsigned long)&s3c_fb_data_s5pv210, }, { @@ -2016,9 +1954,6 @@ static struct platform_device_id s3c_fb_driver_ids[] = { }, { .name = "s3c2443-fb", .driver_data = (unsigned long)&s3c_fb_data_s3c2443, - }, { - .name = "s5p64x0-fb", - .driver_data = (unsigned long)&s3c_fb_data_s5p64x0, }, {}, }; diff --git a/drivers/video/fbdev/s3c2410fb.c b/drivers/video/fbdev/s3c2410fb.c index 81af5a6..e350eb5 100644 --- a/drivers/video/fbdev/s3c2410fb.c +++ b/drivers/video/fbdev/s3c2410fb.c @@ -601,12 +601,12 @@ static int s3c2410fb_debug_store(struct device *dev, if (len < 1) return -EINVAL; - if (strnicmp(buf, "on", 2) == 0 || - strnicmp(buf, "1", 1) == 0) { + if (strncasecmp(buf, "on", 2) == 0 || + strncasecmp(buf, "1", 1) == 0) { debug = 1; dev_dbg(dev, "s3c2410fb: Debug On"); - } else if (strnicmp(buf, "off", 3) == 0 || - strnicmp(buf, "0", 1) == 0) { + } else if (strncasecmp(buf, "off", 3) == 0 || + strncasecmp(buf, "0", 1) == 0) { debug = 0; dev_dbg(dev, "s3c2410fb: Debug Off"); } else { @@ -616,7 +616,7 @@ static int s3c2410fb_debug_store(struct device *dev, return len; } -static DEVICE_ATTR(debug, 0666, s3c2410fb_debug_show, s3c2410fb_debug_store); +static DEVICE_ATTR(debug, 0664, s3c2410fb_debug_show, s3c2410fb_debug_store); static struct fb_ops s3c2410fb_ops = { .owner = THIS_MODULE, @@ -932,7 +932,7 @@ static int s3c24xxfb_probe(struct platform_device *pdev, goto release_irq; } - clk_enable(info->clk); + clk_prepare_enable(info->clk); dprintk("got and enabled clock\n"); usleep_range(1000, 1100); @@ -996,7 +996,7 @@ static int s3c24xxfb_probe(struct platform_device *pdev, free_video_memory: s3c2410fb_unmap_video_memory(fbinfo); release_clock: - clk_disable(info->clk); + clk_disable_unprepare(info->clk); clk_put(info->clk); release_irq: free_irq(irq, info); @@ -1038,7 +1038,7 @@ static int s3c2410fb_remove(struct platform_device *pdev) s3c2410fb_unmap_video_memory(fbinfo); if (info->clk) { - clk_disable(info->clk); + clk_disable_unprepare(info->clk); clk_put(info->clk); info->clk = NULL; } @@ -1070,7 +1070,7 @@ static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state) * before the clock goes off again (bjd) */ usleep_range(1000, 1100); - clk_disable(info->clk); + clk_disable_unprepare(info->clk); return 0; } @@ -1080,7 +1080,7 @@ static int s3c2410fb_resume(struct platform_device *dev) struct fb_info *fbinfo = platform_get_drvdata(dev); struct s3c2410fb_info *info = fbinfo->par; - clk_enable(info->clk); + clk_prepare_enable(info->clk); usleep_range(1000, 1100); s3c2410fb_init_registers(fbinfo); diff --git a/drivers/video/fbdev/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c index 580c444e..9690216 100644 --- a/drivers/video/fbdev/sa1100fb.c +++ b/drivers/video/fbdev/sa1100fb.c @@ -268,7 +268,8 @@ static int sa1100fb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, u_int trans, struct fb_info *info) { - struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; + struct sa1100fb_info *fbi = + container_of(info, struct sa1100fb_info, fb); u_int val, ret = 1; if (regno < fbi->palette_size) { @@ -289,7 +290,8 @@ static int sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int trans, struct fb_info *info) { - struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; + struct sa1100fb_info *fbi = + container_of(info, struct sa1100fb_info, fb); unsigned int val; int ret = 1; @@ -366,7 +368,8 @@ static inline unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo static int sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; + struct sa1100fb_info *fbi = + container_of(info, struct sa1100fb_info, fb); int rgbidx; if (var->xres < MIN_XRES) @@ -433,7 +436,8 @@ static void sa1100fb_set_visual(struct sa1100fb_info *fbi, u32 visual) */ static int sa1100fb_set_par(struct fb_info *info) { - struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; + struct sa1100fb_info *fbi = + container_of(info, struct sa1100fb_info, fb); struct fb_var_screeninfo *var = &info->var; unsigned long palette_mem_size; @@ -526,7 +530,8 @@ sa1100fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, */ static int sa1100fb_blank(int blank, struct fb_info *info) { - struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; + struct sa1100fb_info *fbi = + container_of(info, struct sa1100fb_info, fb); int i; dev_dbg(fbi->dev, "sa1100fb_blank: blank=%d\n", blank); @@ -555,7 +560,8 @@ static int sa1100fb_blank(int blank, struct fb_info *info) static int sa1100fb_mmap(struct fb_info *info, struct vm_area_struct *vma) { - struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; + struct sa1100fb_info *fbi = + container_of(info, struct sa1100fb_info, fb); unsigned long off = vma->vm_pgoff << PAGE_SHIFT; if (off < info->fix.smem_len) { diff --git a/drivers/video/fbdev/sh_mobile_hdmi.c b/drivers/video/fbdev/sh_mobile_hdmi.c index 9a33ee0..7c72a3f 100644 --- a/drivers/video/fbdev/sh_mobile_hdmi.c +++ b/drivers/video/fbdev/sh_mobile_hdmi.c @@ -281,6 +281,7 @@ struct sh_hdmi { u8 edid_block_addr; u8 edid_segment_nr; u8 edid_blocks; + int irq; struct clk *hdmi_clk; struct device *dev; struct delayed_work edid_work; @@ -1299,6 +1300,7 @@ static int __init sh_hdmi_probe(struct platform_device *pdev) hdmi->dev = &pdev->dev; hdmi->entity.owner = THIS_MODULE; hdmi->entity.ops = &sh_hdmi_ops; + hdmi->irq = irq; hdmi->hdmi_clk = clk_get(&pdev->dev, "ick"); if (IS_ERR(hdmi->hdmi_clk)) { @@ -1415,12 +1417,11 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev) { struct sh_hdmi *hdmi = entity_to_sh_hdmi(platform_get_drvdata(pdev)); struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - int irq = platform_get_irq(pdev, 0); snd_soc_unregister_codec(&pdev->dev); /* No new work will be scheduled, wait for running ISR */ - free_irq(irq, hdmi); + free_irq(hdmi->irq, hdmi); /* Wait for already scheduled work */ cancel_delayed_work_sync(&hdmi->edid_work); pm_runtime_put(&pdev->dev); @@ -1435,10 +1436,49 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev) return 0; } +static int sh_hdmi_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct sh_hdmi *hdmi = entity_to_sh_hdmi(platform_get_drvdata(pdev)); + + disable_irq(hdmi->irq); + /* Wait for already scheduled work */ + cancel_delayed_work_sync(&hdmi->edid_work); + return 0; +} + +static int sh_hdmi_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct sh_mobile_hdmi_info *pdata = dev_get_platdata(dev); + struct sh_hdmi *hdmi = entity_to_sh_hdmi(platform_get_drvdata(pdev)); + + /* Re-init interrupt polarity */ + if (pdata->flags & HDMI_OUTPUT_PUSH_PULL) + hdmi_bit_set(hdmi, 0x02, 0x02, HDMI_SYSTEM_CTRL); + + if (pdata->flags & HDMI_OUTPUT_POLARITY_HI) + hdmi_bit_set(hdmi, 0x01, 0x01, HDMI_SYSTEM_CTRL); + + /* Re-init htop1 */ + if (hdmi->htop1) + sh_hdmi_htop1_init(hdmi); + + /* Now it's safe to enable interrupts again */ + enable_irq(hdmi->irq); + return 0; +} + +static const struct dev_pm_ops sh_hdmi_pm_ops = { + .suspend = sh_hdmi_suspend, + .resume = sh_hdmi_resume, +}; + static struct platform_driver sh_hdmi_driver = { .remove = __exit_p(sh_hdmi_remove), .driver = { .name = "sh-mobile-hdmi", + .pm = &sh_hdmi_pm_ops, }, }; diff --git a/drivers/video/fbdev/sis/init.c b/drivers/video/fbdev/sis/init.c index bd40f5e..dfe3eb7 100644 --- a/drivers/video/fbdev/sis/init.c +++ b/drivers/video/fbdev/sis/init.c @@ -1511,7 +1511,7 @@ SiS_Get310DRAMType(struct SiS_Private *SiS_Pr) } else if(SiS_Pr->ChipType >= SIS_340) { /* TODO */ data = 0; - } if(SiS_Pr->ChipType >= SIS_661) { + } else if(SiS_Pr->ChipType >= SIS_661) { if(SiS_Pr->SiS_ROMNew) { data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6); } else { diff --git a/drivers/video/fbdev/sis/init301.c b/drivers/video/fbdev/sis/init301.c index a89e3ca..295e0de 100644 --- a/drivers/video/fbdev/sis/init301.c +++ b/drivers/video/fbdev/sis/init301.c @@ -1714,7 +1714,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */ } else { SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802; - SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112; + SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; SiS_Pr->PanelVCLKIdx300 = VCLK81_300; SiS_Pr->PanelVCLKIdx315 = VCLK81_315; diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c index 22ad028..e5d11b1 100644 --- a/drivers/video/fbdev/sis/sis_main.c +++ b/drivers/video/fbdev/sis/sis_main.c @@ -162,7 +162,7 @@ static void sisfb_search_mode(char *name, bool quiet) return; } - if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) { + if(!strncasecmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) { if(!quiet) printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n"); @@ -201,7 +201,7 @@ static void sisfb_search_mode(char *name, bool quiet) i = 0; j = 0; while(sisbios_mode[i].mode_no[0] != 0) { - if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) { + if(!strncasecmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) { if(sisfb_fstn) { if(sisbios_mode[i-1].mode_no[1] == 0x50 || sisbios_mode[i-1].mode_no[1] == 0x56 || @@ -262,7 +262,7 @@ sisfb_search_crt2type(const char *name) if(name == NULL) return; while(sis_crt2type[i].type_no != -1) { - if(!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) { + if(!strncasecmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) { sisfb_crt2type = sis_crt2type[i].type_no; sisfb_tvplug = sis_crt2type[i].tvplug_no; sisfb_crt2flags = sis_crt2type[i].flags; @@ -289,7 +289,7 @@ sisfb_search_tvstd(const char *name) return; while(sis_tvtype[i].type_no != -1) { - if(!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) { + if(!strncasecmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) { sisfb_tvstd = sis_tvtype[i].type_no; break; } @@ -308,12 +308,12 @@ sisfb_search_specialtiming(const char *name) if(name == NULL) return; - if(!strnicmp(name, "none", 4)) { + if(!strncasecmp(name, "none", 4)) { sisfb_specialtiming = CUT_FORCENONE; printk(KERN_DEBUG "sisfb: Special timing disabled\n"); } else { while(mycustomttable[i].chipID != 0) { - if(!strnicmp(name,mycustomttable[i].optionName, + if(!strncasecmp(name,mycustomttable[i].optionName, strlen(mycustomttable[i].optionName))) { sisfb_specialtiming = mycustomttable[i].SpecialID; found = true; @@ -1572,10 +1572,6 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) /* Adapt RGB settings */ sisfb_bpp_to_var(ivideo, var); - /* Sanity check for offsets */ - if(var->xoffset < 0) var->xoffset = 0; - if(var->yoffset < 0) var->yoffset = 0; - if(var->xres > var->xres_virtual) var->xres_virtual = var->xres; @@ -3956,68 +3952,68 @@ static int __init sisfb_setup(char *options) if(!(*this_opt)) continue; - if(!strnicmp(this_opt, "off", 3)) { + if(!strncasecmp(this_opt, "off", 3)) { sisfb_off = 1; - } else if(!strnicmp(this_opt, "forcecrt2type:", 14)) { + } else if(!strncasecmp(this_opt, "forcecrt2type:", 14)) { /* Need to check crt2 type first for fstn/dstn */ sisfb_search_crt2type(this_opt + 14); - } else if(!strnicmp(this_opt, "tvmode:",7)) { + } else if(!strncasecmp(this_opt, "tvmode:",7)) { sisfb_search_tvstd(this_opt + 7); - } else if(!strnicmp(this_opt, "tvstandard:",11)) { + } else if(!strncasecmp(this_opt, "tvstandard:",11)) { sisfb_search_tvstd(this_opt + 11); - } else if(!strnicmp(this_opt, "mode:", 5)) { + } else if(!strncasecmp(this_opt, "mode:", 5)) { sisfb_search_mode(this_opt + 5, false); - } else if(!strnicmp(this_opt, "vesa:", 5)) { + } else if(!strncasecmp(this_opt, "vesa:", 5)) { sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), false); - } else if(!strnicmp(this_opt, "rate:", 5)) { + } else if(!strncasecmp(this_opt, "rate:", 5)) { sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0); - } else if(!strnicmp(this_opt, "forcecrt1:", 10)) { + } else if(!strncasecmp(this_opt, "forcecrt1:", 10)) { sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0); - } else if(!strnicmp(this_opt, "mem:",4)) { + } else if(!strncasecmp(this_opt, "mem:",4)) { sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0); - } else if(!strnicmp(this_opt, "pdc:", 4)) { + } else if(!strncasecmp(this_opt, "pdc:", 4)) { sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0); - } else if(!strnicmp(this_opt, "pdc1:", 5)) { + } else if(!strncasecmp(this_opt, "pdc1:", 5)) { sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0); - } else if(!strnicmp(this_opt, "noaccel", 7)) { + } else if(!strncasecmp(this_opt, "noaccel", 7)) { sisfb_accel = 0; - } else if(!strnicmp(this_opt, "accel", 5)) { + } else if(!strncasecmp(this_opt, "accel", 5)) { sisfb_accel = -1; - } else if(!strnicmp(this_opt, "noypan", 6)) { + } else if(!strncasecmp(this_opt, "noypan", 6)) { sisfb_ypan = 0; - } else if(!strnicmp(this_opt, "ypan", 4)) { + } else if(!strncasecmp(this_opt, "ypan", 4)) { sisfb_ypan = -1; - } else if(!strnicmp(this_opt, "nomax", 5)) { + } else if(!strncasecmp(this_opt, "nomax", 5)) { sisfb_max = 0; - } else if(!strnicmp(this_opt, "max", 3)) { + } else if(!strncasecmp(this_opt, "max", 3)) { sisfb_max = -1; - } else if(!strnicmp(this_opt, "userom:", 7)) { + } else if(!strncasecmp(this_opt, "userom:", 7)) { sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0); - } else if(!strnicmp(this_opt, "useoem:", 7)) { + } else if(!strncasecmp(this_opt, "useoem:", 7)) { sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); - } else if(!strnicmp(this_opt, "nocrt2rate", 10)) { + } else if(!strncasecmp(this_opt, "nocrt2rate", 10)) { sisfb_nocrt2rate = 1; - } else if(!strnicmp(this_opt, "scalelcd:", 9)) { + } else if(!strncasecmp(this_opt, "scalelcd:", 9)) { unsigned long temp = 2; temp = simple_strtoul(this_opt + 9, NULL, 0); if((temp == 0) || (temp == 1)) { sisfb_scalelcd = temp ^ 1; } - } else if(!strnicmp(this_opt, "tvxposoffset:", 13)) { + } else if(!strncasecmp(this_opt, "tvxposoffset:", 13)) { int temp = 0; temp = (int)simple_strtol(this_opt + 13, NULL, 0); if((temp >= -32) && (temp <= 32)) { sisfb_tvxposoffset = temp; } - } else if(!strnicmp(this_opt, "tvyposoffset:", 13)) { + } else if(!strncasecmp(this_opt, "tvyposoffset:", 13)) { int temp = 0; temp = (int)simple_strtol(this_opt + 13, NULL, 0); if((temp >= -32) && (temp <= 32)) { sisfb_tvyposoffset = temp; } - } else if(!strnicmp(this_opt, "specialtiming:", 14)) { + } else if(!strncasecmp(this_opt, "specialtiming:", 14)) { sisfb_search_specialtiming(this_opt + 14); - } else if(!strnicmp(this_opt, "lvdshl:", 7)) { + } else if(!strncasecmp(this_opt, "lvdshl:", 7)) { int temp = 4; temp = simple_strtoul(this_opt + 7, NULL, 0); if((temp >= 0) && (temp <= 3)) { @@ -4026,9 +4022,9 @@ static int __init sisfb_setup(char *options) } else if(this_opt[0] >= '0' && this_opt[0] <= '9') { sisfb_search_mode(this_opt, true); #if !defined(__i386__) && !defined(__x86_64__) - } else if(!strnicmp(this_opt, "resetcard", 9)) { + } else if(!strncasecmp(this_opt, "resetcard", 9)) { sisfb_resetcard = 1; - } else if(!strnicmp(this_opt, "videoram:", 9)) { + } else if(!strncasecmp(this_opt, "videoram:", 9)) { sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0); #endif } else { @@ -5834,7 +5830,7 @@ static int sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ivideo->cardnumber++; } - strncpy(ivideo->myid, chipinfo->chip_name, 30); + strlcpy(ivideo->myid, chipinfo->chip_name, sizeof(ivideo->myid)); ivideo->warncount = 0; ivideo->chip_id = pdev->device; diff --git a/drivers/video/fbdev/sm501fb.c b/drivers/video/fbdev/sm501fb.c index c2c8eb6..9e74e8f 100644 --- a/drivers/video/fbdev/sm501fb.c +++ b/drivers/video/fbdev/sm501fb.c @@ -1187,9 +1187,9 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev, if (len < 1) return -EINVAL; - if (strnicmp(buf, "crt", 3) == 0) + if (strncasecmp(buf, "crt", 3) == 0) head = HEAD_CRT; - else if (strnicmp(buf, "panel", 5) == 0) + else if (strncasecmp(buf, "panel", 5) == 0) head = HEAD_PANEL; else return -EINVAL; diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c index cfe8a2f..86621fa 100644 --- a/drivers/video/fbdev/stifb.c +++ b/drivers/video/fbdev/stifb.c @@ -918,7 +918,7 @@ static int stifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { - struct stifb_info *fb = (struct stifb_info *) info; + struct stifb_info *fb = container_of(info, struct stifb_info, info); u32 color; if (regno >= NR_PALETTE) @@ -978,7 +978,7 @@ stifb_setcolreg(u_int regno, u_int red, u_int green, static int stifb_blank(int blank_mode, struct fb_info *info) { - struct stifb_info *fb = (struct stifb_info *) info; + struct stifb_info *fb = container_of(info, struct stifb_info, info); int enable = (blank_mode == 0) ? ENABLE : DISABLE; switch (fb->id) { diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c index 77b890e..046d51d 100644 --- a/drivers/video/fbdev/udlfb.c +++ b/drivers/video/fbdev/udlfb.c @@ -1528,11 +1528,8 @@ static int dlfb_parse_vendor_descriptor(struct dlfb_data *dev, } if (total_len > 5) { - pr_info("vendor descriptor length:%x data:%02x %02x %02x %02x" \ - "%02x %02x %02x %02x %02x %02x %02x\n", - total_len, desc[0], - desc[1], desc[2], desc[3], desc[4], desc[5], desc[6], - desc[7], desc[8], desc[9], desc[10]); + pr_info("vendor descriptor length:%x data:%11ph\n", total_len, + desc); if ((desc[0] != total_len) || /* descriptor length */ (desc[1] != 0x5f) || /* vendor descriptor type */ diff --git a/drivers/video/fbdev/valkyriefb.c b/drivers/video/fbdev/valkyriefb.c index 97cb9bd..275fb98 100644 --- a/drivers/video/fbdev/valkyriefb.c +++ b/drivers/video/fbdev/valkyriefb.c @@ -136,7 +136,8 @@ static struct fb_ops valkyriefb_ops = { /* Sets the video mode according to info->var */ static int valkyriefb_set_par(struct fb_info *info) { - struct fb_info_valkyrie *p = (struct fb_info_valkyrie *) info; + struct fb_info_valkyrie *p = + container_of(info, struct fb_info_valkyrie, info); volatile struct valkyrie_regs __iomem *valkyrie_regs = p->valkyrie_regs; struct fb_par_valkyrie *par = info->par; struct valkyrie_regvals *init; @@ -194,7 +195,8 @@ valkyriefb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) */ static int valkyriefb_blank(int blank_mode, struct fb_info *info) { - struct fb_info_valkyrie *p = (struct fb_info_valkyrie *) info; + struct fb_info_valkyrie *p = + container_of(info, struct fb_info_valkyrie, info); struct fb_par_valkyrie *par = info->par; struct valkyrie_regvals *init = par->init; @@ -226,7 +228,8 @@ static int valkyriefb_blank(int blank_mode, struct fb_info *info) static int valkyriefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { - struct fb_info_valkyrie *p = (struct fb_info_valkyrie *) info; + struct fb_info_valkyrie *p = + container_of(info, struct fb_info_valkyrie, info); volatile struct cmap_regs __iomem *cmap_regs = p->cmap_regs; struct fb_par_valkyrie *par = info->par; @@ -263,10 +266,10 @@ static inline int valkyrie_vram_reqd(int video_mode, int color_mode) static void set_valkyrie_clock(unsigned char *params) { +#ifdef CONFIG_ADB_CUDA struct adb_request req; int i; -#ifdef CONFIG_ADB_CUDA for (i = 0; i < 3; ++i) { cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, 0x50, i + 1, params[i]); @@ -465,7 +468,8 @@ static int valkyrie_var_to_par(struct fb_var_screeninfo *var, { int vmode, cmode; struct valkyrie_regvals *init; - struct fb_info_valkyrie *p = (struct fb_info_valkyrie *) fb_info; + struct fb_info_valkyrie *p = + container_of(fb_info, struct fb_info_valkyrie, info); if (mac_var_to_vmode(var, &vmode, &cmode) != 0) { printk(KERN_ERR "valkyriefb: can't do %dx%dx%d.\n", diff --git a/drivers/video/fbdev/vermilion/vermilion.c b/drivers/video/fbdev/vermilion/vermilion.c index 048a666..5f930ae 100644 --- a/drivers/video/fbdev/vermilion/vermilion.c +++ b/drivers/video/fbdev/vermilion/vermilion.c @@ -481,7 +481,6 @@ static int vml_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) default: err = -ENODEV; goto out_err_1; - break; } info = &vinfo->info; diff --git a/drivers/video/fbdev/via/via-gpio.c b/drivers/video/fbdev/via/via-gpio.c index e408679..6f433b8 100644 --- a/drivers/video/fbdev/via/via-gpio.c +++ b/drivers/video/fbdev/via/via-gpio.c @@ -270,7 +270,7 @@ static int viafb_gpio_probe(struct platform_device *platdev) static int viafb_gpio_remove(struct platform_device *platdev) { unsigned long flags; - int ret = 0, i; + int i; #ifdef CONFIG_PM viafb_pm_unregister(&viafb_gpio_pm_hooks); @@ -280,11 +280,7 @@ static int viafb_gpio_remove(struct platform_device *platdev) * Get unregistered. */ if (viafb_gpio_config.gpio_chip.ngpio > 0) { - ret = gpiochip_remove(&viafb_gpio_config.gpio_chip); - if (ret) { /* Somebody still using it? */ - printk(KERN_ERR "Viafb: GPIO remove failed\n"); - return ret; - } + gpiochip_remove(&viafb_gpio_config.gpio_chip); } /* * Disable the ports. @@ -294,7 +290,7 @@ static int viafb_gpio_remove(struct platform_device *platdev) viafb_gpio_disable(viafb_gpio_config.active_gpios[i]); viafb_gpio_config.gpio_chip.ngpio = 0; spin_unlock_irqrestore(&viafb_gpio_config.vdev->reg_lock, flags); - return ret; + return 0; } static struct platform_driver via_gpio_driver = { diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c index 901014b..09dc447 100644 --- a/drivers/video/fbdev/xen-fbfront.c +++ b/drivers/video/fbdev/xen-fbfront.c @@ -684,12 +684,13 @@ static const struct xenbus_device_id xenfb_ids[] = { { "" } }; -static DEFINE_XENBUS_DRIVER(xenfb, , +static struct xenbus_driver xenfb_driver = { + .ids = xenfb_ids, .probe = xenfb_probe, .remove = xenfb_remove, .resume = xenfb_resume, .otherend_changed = xenfb_backend_changed, -); +}; static int __init xenfb_init(void) { diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c index 987edf1..32d8275 100644 --- a/drivers/video/of_display_timing.c +++ b/drivers/video/of_display_timing.c @@ -233,9 +233,9 @@ struct display_timings *of_get_display_timings(struct device_node *np) return disp; timingfail: - if (native_mode) - of_node_put(native_mode); + of_node_put(native_mode); display_timings_release(disp); + disp = NULL; entryfail: kfree(disp); dispfail: |