diff options
Diffstat (limited to 'drivers/video')
33 files changed, 693 insertions, 404 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index b694d7669d32..44c9ef1435a2 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -11,6 +11,10 @@ config APERTURE_HELPERS Support tracking and hand-over of aperture ownership. Required by graphics drivers for firmware-provided framebuffers. +config SCREEN_INFO + bool + default n + config STI_CORE bool depends on PARISC @@ -18,10 +22,7 @@ config STI_CORE STI refers to the HP "Standard Text Interface" which is a set of BIOS routines contained in a ROM chip in HP PA-RISC based machines. -config VIDEO_CMDLINE - bool - -config VIDEO_NOMODESET +config VIDEO bool default n diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 6bbc03950899..ffbac4387c67 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -1,12 +1,15 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_APERTURE_HELPERS) += aperture.o +obj-$(CONFIG_SCREEN_INFO) += screen_info.o obj-$(CONFIG_STI_CORE) += sticore.o obj-$(CONFIG_VGASTATE) += vgastate.o -obj-$(CONFIG_VIDEO_CMDLINE) += cmdline.o -obj-$(CONFIG_VIDEO_NOMODESET) += nomodeset.o +obj-$(CONFIG_VIDEO) += cmdline.o nomodeset.o obj-$(CONFIG_HDMI) += hdmi.o +screen_info-y := screen_info_generic.o +screen_info-$(CONFIG_PCI) += screen_info_pci.o + obj-$(CONFIG_VT) += console/ obj-$(CONFIG_FB_STI) += console/ obj-$(CONFIG_LOGO) += logo/ diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index ea2d0d69bd8c..230bca07b09d 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -183,6 +183,13 @@ config BACKLIGHT_KTD253 which is a 1-wire GPIO-controlled backlight found in some mobile phones. +config BACKLIGHT_KTD2801 + tristate "Backlight Driver for Kinetic KTD2801" + select LEDS_EXPRESSWIRE + help + Say Y to enable the backlight driver for the Kinetic KTD2801 1-wire + GPIO-controlled backlight found in Samsung Galaxy Core Prime VE LTE. + config BACKLIGHT_KTZ8866 tristate "Backlight Driver for Kinetic KTZ8866" depends on I2C diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 06966cb20459..8d2cb252042d 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -34,6 +34,7 @@ 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_KTD253) += ktd253-backlight.o +obj-$(CONFIG_BACKLIGHT_KTD2801) += ktd2801-backlight.o obj-$(CONFIG_BACKLIGHT_KTZ8866) += ktz8866.o obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o obj-$(CONFIG_BACKLIGHT_LM3630A) += lm3630a_bl.o diff --git a/drivers/video/backlight/as3711_bl.c b/drivers/video/backlight/as3711_bl.c index 28437c2da0f5..e6f66bb35ef5 100644 --- a/drivers/video/backlight/as3711_bl.c +++ b/drivers/video/backlight/as3711_bl.c @@ -383,10 +383,8 @@ static int as3711_backlight_probe(struct platform_device *pdev) if (pdev->dev.parent->of_node) { ret = as3711_backlight_parse_dt(&pdev->dev); - if (ret < 0) { - dev_err(&pdev->dev, "DT parsing failed: %d\n", ret); - return ret; - } + if (ret < 0) + return dev_err_probe(&pdev->dev, ret, "DT parsing failed\n"); } if (!pdata->su1_fb && !pdata->su2_fb) { diff --git a/drivers/video/backlight/bd6107.c b/drivers/video/backlight/bd6107.c index c95a12bf0ce2..b1e7126380ef 100644 --- a/drivers/video/backlight/bd6107.c +++ b/drivers/video/backlight/bd6107.c @@ -119,7 +119,6 @@ static int bd6107_probe(struct i2c_client *client) struct backlight_device *backlight; struct backlight_properties props; struct bd6107 *bd; - int ret; if (pdata == NULL) { dev_err(&client->dev, "No platform data\n"); @@ -147,11 +146,9 @@ static int bd6107_probe(struct i2c_client *client) * the reset. */ bd->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH); - if (IS_ERR(bd->reset)) { - dev_err(&client->dev, "unable to request reset GPIO\n"); - ret = PTR_ERR(bd->reset); - return ret; - } + if (IS_ERR(bd->reset)) + return dev_err_probe(&client->dev, PTR_ERR(bd->reset), + "unable to request reset GPIO\n"); memset(&props, 0, sizeof(props)); props.type = BACKLIGHT_RAW; diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c index 0a57033ae31d..dd765098ad98 100644 --- a/drivers/video/backlight/corgi_lcd.c +++ b/drivers/video/backlight/corgi_lcd.c @@ -11,6 +11,7 @@ * by Eric Miao <eric.miao@marvell.com> */ +#include <linux/backlight.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/video/backlight/da9052_bl.c b/drivers/video/backlight/da9052_bl.c index 1cdc8543310b..b8ff7046510e 100644 --- a/drivers/video/backlight/da9052_bl.c +++ b/drivers/video/backlight/da9052_bl.c @@ -117,6 +117,7 @@ static int da9052_backlight_probe(struct platform_device *pdev) wleds->led_reg = platform_get_device_id(pdev)->driver_data; wleds->state = DA9052_WLEDS_OFF; + memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_RAW; props.max_brightness = DA9052_MAX_BRIGHTNESS; diff --git a/drivers/video/backlight/gpio_backlight.c b/drivers/video/backlight/gpio_backlight.c index d28c30b2a35d..e0c8c2a3f5dc 100644 --- a/drivers/video/backlight/gpio_backlight.c +++ b/drivers/video/backlight/gpio_backlight.c @@ -64,13 +64,9 @@ static int gpio_backlight_probe(struct platform_device *pdev) def_value = device_property_read_bool(dev, "default-on"); gbl->gpiod = devm_gpiod_get(dev, NULL, GPIOD_ASIS); - if (IS_ERR(gbl->gpiod)) { - ret = PTR_ERR(gbl->gpiod); - if (ret != -EPROBE_DEFER) - dev_err(dev, - "Error: The gpios parameter is missing or invalid.\n"); - return ret; - } + if (IS_ERR(gbl->gpiod)) + return dev_err_probe(dev, PTR_ERR(gbl->gpiod), + "The gpios parameter is missing or invalid\n"); memset(&props, 0, sizeof(props)); props.type = BACKLIGHT_RAW; diff --git a/drivers/video/backlight/hx8357.c b/drivers/video/backlight/hx8357.c index d7298376cf74..339d9128fbde 100644 --- a/drivers/video/backlight/hx8357.c +++ b/drivers/video/backlight/hx8357.c @@ -8,9 +8,9 @@ #include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/lcd.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/property.h> #include <linux/spi/spi.h> #define HX8357_NUM_IM_PINS 3 @@ -564,41 +564,28 @@ static struct lcd_ops hx8357_ops = { .get_power = hx8357_get_power, }; -static const struct of_device_id hx8357_dt_ids[] = { - { - .compatible = "himax,hx8357", - .data = hx8357_lcd_init, - }, - { - .compatible = "himax,hx8369", - .data = hx8369_lcd_init, - }, - {}, -}; -MODULE_DEVICE_TABLE(of, hx8357_dt_ids); +typedef int (*hx8357_init_fn)(struct lcd_device *); static int hx8357_probe(struct spi_device *spi) { struct device *dev = &spi->dev; struct lcd_device *lcdev; struct hx8357_data *lcd; - const struct of_device_id *match; + hx8357_init_fn init_fn; int i, ret; - lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL); + lcd = devm_kzalloc(dev, sizeof(*lcd), GFP_KERNEL); if (!lcd) return -ENOMEM; ret = spi_setup(spi); - if (ret < 0) { - dev_err(&spi->dev, "SPI setup failed.\n"); - return ret; - } + if (ret < 0) + return dev_err_probe(dev, ret, "SPI setup failed.\n"); lcd->spi = spi; - match = of_match_device(hx8357_dt_ids, &spi->dev); - if (!match || !match->data) + init_fn = device_get_match_data(dev); + if (!init_fn) return -EINVAL; lcd->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); @@ -609,14 +596,15 @@ static int hx8357_probe(struct spi_device *spi) lcd->im_pins = devm_gpiod_get_array_optional(dev, "im", GPIOD_OUT_LOW); if (IS_ERR(lcd->im_pins)) return dev_err_probe(dev, PTR_ERR(lcd->im_pins), "failed to request im GPIOs\n"); - if (lcd->im_pins->ndescs < HX8357_NUM_IM_PINS) - return dev_err_probe(dev, -EINVAL, "not enough im GPIOs\n"); + if (lcd->im_pins) { + if (lcd->im_pins->ndescs < HX8357_NUM_IM_PINS) + return dev_err_probe(dev, -EINVAL, "not enough im GPIOs\n"); - for (i = 0; i < HX8357_NUM_IM_PINS; i++) - gpiod_set_consumer_name(lcd->im_pins->desc[i], "im_pins"); + for (i = 0; i < HX8357_NUM_IM_PINS; i++) + gpiod_set_consumer_name(lcd->im_pins->desc[i], "im_pins"); + } - lcdev = devm_lcd_device_register(&spi->dev, "mxsfb", &spi->dev, lcd, - &hx8357_ops); + lcdev = devm_lcd_device_register(dev, "mxsfb", dev, lcd, &hx8357_ops); if (IS_ERR(lcdev)) { ret = PTR_ERR(lcdev); return ret; @@ -625,17 +613,28 @@ static int hx8357_probe(struct spi_device *spi) hx8357_lcd_reset(lcdev); - ret = ((int (*)(struct lcd_device *))match->data)(lcdev); - if (ret) { - dev_err(&spi->dev, "Couldn't initialize panel\n"); - return ret; - } + ret = init_fn(lcdev); + if (ret) + return dev_err_probe(dev, ret, "Couldn't initialize panel\n"); - dev_info(&spi->dev, "Panel probed\n"); + dev_info(dev, "Panel probed\n"); return 0; } +static const struct of_device_id hx8357_dt_ids[] = { + { + .compatible = "himax,hx8357", + .data = hx8357_lcd_init, + }, + { + .compatible = "himax,hx8369", + .data = hx8369_lcd_init, + }, + {} +}; +MODULE_DEVICE_TABLE(of, hx8357_dt_ids); + static struct spi_driver hx8357_driver = { .probe = hx8357_probe, .driver = { diff --git a/drivers/video/backlight/ktd2801-backlight.c b/drivers/video/backlight/ktd2801-backlight.c new file mode 100644 index 000000000000..d295c2766025 --- /dev/null +++ b/drivers/video/backlight/ktd2801-backlight.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Datasheet: + * https://www.kinet-ic.com/uploads/web/KTD2801/KTD2801-04b.pdf + */ +#include <linux/backlight.h> +#include <linux/gpio/consumer.h> +#include <linux/leds-expresswire.h> +#include <linux/platform_device.h> +#include <linux/property.h> + +#define KTD2801_DEFAULT_BRIGHTNESS 100 +#define KTD2801_MAX_BRIGHTNESS 255 + +/* These values have been extracted from Samsung's driver. */ +static const struct expresswire_timing ktd2801_timing = { + .poweroff_us = 2600, + .detect_delay_us = 150, + .detect_us = 270, + .data_start_us = 5, + .short_bitset_us = 5, + .long_bitset_us = 15, + .end_of_data_low_us = 10, + .end_of_data_high_us = 350 +}; + +struct ktd2801_backlight { + struct expresswire_common_props props; + struct backlight_device *bd; + bool was_on; +}; + +static int ktd2801_update_status(struct backlight_device *bd) +{ + struct ktd2801_backlight *ktd2801 = bl_get_data(bd); + u8 brightness = (u8) backlight_get_brightness(bd); + + if (backlight_is_blank(bd)) { + expresswire_power_off(&ktd2801->props); + ktd2801->was_on = false; + return 0; + } + + if (!ktd2801->was_on) { + expresswire_enable(&ktd2801->props); + ktd2801->was_on = true; + } + + expresswire_write_u8(&ktd2801->props, brightness); + + return 0; +} + +static const struct backlight_ops ktd2801_backlight_ops = { + .update_status = ktd2801_update_status, +}; + +static int ktd2801_backlight_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct backlight_device *bd; + struct ktd2801_backlight *ktd2801; + u32 brightness, max_brightness; + int ret; + + ktd2801 = devm_kzalloc(dev, sizeof(*ktd2801), GFP_KERNEL); + if (!ktd2801) + return -ENOMEM; + ktd2801->was_on = true; + ktd2801->props.timing = ktd2801_timing; + + ret = device_property_read_u32(dev, "max-brightness", &max_brightness); + if (ret) + max_brightness = KTD2801_MAX_BRIGHTNESS; + if (max_brightness > KTD2801_MAX_BRIGHTNESS) { + dev_err(dev, "illegal max brightness specified\n"); + max_brightness = KTD2801_MAX_BRIGHTNESS; + } + + ret = device_property_read_u32(dev, "default-brightness", &brightness); + if (ret) + brightness = KTD2801_DEFAULT_BRIGHTNESS; + if (brightness > max_brightness) { + dev_err(dev, "default brightness exceeds max\n"); + brightness = max_brightness; + } + + ktd2801->props.ctrl_gpio = devm_gpiod_get(dev, "ctrl", GPIOD_OUT_HIGH); + if (IS_ERR(ktd2801->props.ctrl_gpio)) + return dev_err_probe(dev, PTR_ERR(ktd2801->props.ctrl_gpio), + "failed to get backlight GPIO"); + gpiod_set_consumer_name(ktd2801->props.ctrl_gpio, dev_name(dev)); + + bd = devm_backlight_device_register(dev, dev_name(dev), dev, ktd2801, + &ktd2801_backlight_ops, NULL); + if (IS_ERR(bd)) + return dev_err_probe(dev, PTR_ERR(bd), + "failed to register backlight"); + + bd->props.max_brightness = max_brightness; + bd->props.brightness = brightness; + + ktd2801->bd = bd; + platform_set_drvdata(pdev, bd); + backlight_update_status(bd); + + return 0; +} + +static const struct of_device_id ktd2801_of_match[] = { + { .compatible = "kinetic,ktd2801" }, + { } +}; +MODULE_DEVICE_TABLE(of, ktd2801_of_match); + +static struct platform_driver ktd2801_backlight_driver = { + .driver = { + .name = "ktd2801-backlight", + .of_match_table = ktd2801_of_match, + }, + .probe = ktd2801_backlight_probe, +}; +module_platform_driver(ktd2801_backlight_driver); + +MODULE_IMPORT_NS(EXPRESSWIRE); +MODULE_AUTHOR("Duje Mihanović <duje.mihanovic@skole.hr>"); +MODULE_DESCRIPTION("Kinetic KTD2801 Backlight Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/backlight/ktz8866.c b/drivers/video/backlight/ktz8866.c index 9c980f2571ee..014877b5a984 100644 --- a/drivers/video/backlight/ktz8866.c +++ b/drivers/video/backlight/ktz8866.c @@ -97,20 +97,20 @@ static void ktz8866_init(struct ktz8866 *ktz) { unsigned int val = 0; - if (of_property_read_u32(ktz->client->dev.of_node, "current-num-sinks", &val)) + if (!of_property_read_u32(ktz->client->dev.of_node, "current-num-sinks", &val)) ktz8866_write(ktz, BL_EN, BIT(val) - 1); else /* Enable all 6 current sinks if the number of current sinks isn't specified. */ ktz8866_write(ktz, BL_EN, BIT(6) - 1); - if (of_property_read_u32(ktz->client->dev.of_node, "kinetic,current-ramp-delay-ms", &val)) { + if (!of_property_read_u32(ktz->client->dev.of_node, "kinetic,current-ramp-delay-ms", &val)) { if (val <= 128) ktz8866_write(ktz, BL_CFG2, BIT(7) | (ilog2(val) << 3) | PWM_HYST); else ktz8866_write(ktz, BL_CFG2, BIT(7) | ((5 + val / 64) << 3) | PWM_HYST); } - if (of_property_read_u32(ktz->client->dev.of_node, "kinetic,led-enable-ramp-delay-ms", &val)) { + if (!of_property_read_u32(ktz->client->dev.of_node, "kinetic,led-enable-ramp-delay-ms", &val)) { if (val == 0) ktz8866_write(ktz, BL_DIMMING, 0); else { diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c index cc763cf15f53..bd5137ee203b 100644 --- a/drivers/video/backlight/l4f00242t03.c +++ b/drivers/video/backlight/l4f00242t03.c @@ -179,34 +179,28 @@ static int l4f00242t03_probe(struct spi_device *spi) priv->spi = spi; priv->reset = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_HIGH); - if (IS_ERR(priv->reset)) { - dev_err(&spi->dev, - "Unable to get the lcd l4f00242t03 reset gpio.\n"); - return PTR_ERR(priv->reset); - } + if (IS_ERR(priv->reset)) + return dev_err_probe(&spi->dev, PTR_ERR(priv->reset), + "Unable to get the lcd l4f00242t03 reset gpio.\n"); gpiod_set_consumer_name(priv->reset, "lcd l4f00242t03 reset"); priv->enable = devm_gpiod_get(&spi->dev, "enable", GPIOD_OUT_LOW); - if (IS_ERR(priv->enable)) { - dev_err(&spi->dev, - "Unable to get the lcd l4f00242t03 data en gpio.\n"); - return PTR_ERR(priv->enable); - } + if (IS_ERR(priv->enable)) + return dev_err_probe(&spi->dev, PTR_ERR(priv->enable), + "Unable to get the lcd l4f00242t03 data en gpio.\n"); gpiod_set_consumer_name(priv->enable, "lcd l4f00242t03 data enable"); priv->io_reg = devm_regulator_get(&spi->dev, "vdd"); - if (IS_ERR(priv->io_reg)) { - dev_err(&spi->dev, "%s: Unable to get the IO regulator\n", - __func__); - return PTR_ERR(priv->io_reg); - } + if (IS_ERR(priv->io_reg)) + return dev_err_probe(&spi->dev, PTR_ERR(priv->io_reg), + "%s: Unable to get the IO regulator\n", + __func__); priv->core_reg = devm_regulator_get(&spi->dev, "vcore"); - if (IS_ERR(priv->core_reg)) { - dev_err(&spi->dev, "%s: Unable to get the core regulator\n", - __func__); - return PTR_ERR(priv->core_reg); - } + if (IS_ERR(priv->core_reg)) + return dev_err_probe(&spi->dev, PTR_ERR(priv->core_reg), + "%s: Unable to get the core regulator\n", + __func__); priv->ld = devm_lcd_device_register(&spi->dev, "l4f00242t03", &spi->dev, priv, &l4f_ops); diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c index a3412c936ca2..76d47e2e8242 100644 --- a/drivers/video/backlight/lm3630a_bl.c +++ b/drivers/video/backlight/lm3630a_bl.c @@ -189,10 +189,11 @@ static int lm3630a_bank_a_update_status(struct backlight_device *bl) int ret; struct lm3630a_chip *pchip = bl_get_data(bl); enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; + int brightness = backlight_get_brightness(bl); /* pwm control */ if ((pwm_ctrl & LM3630A_PWM_BANK_A) != 0) - return lm3630a_pwm_ctrl(pchip, bl->props.brightness, + return lm3630a_pwm_ctrl(pchip, brightness, bl->props.max_brightness); /* disable sleep */ @@ -201,9 +202,9 @@ static int lm3630a_bank_a_update_status(struct backlight_device *bl) goto out_i2c_err; usleep_range(1000, 2000); /* minimum brightness is 0x04 */ - ret = lm3630a_write(pchip, REG_BRT_A, bl->props.brightness); + ret = lm3630a_write(pchip, REG_BRT_A, brightness); - if (backlight_is_blank(bl) || (backlight_get_brightness(bl) < 0x4)) + if (brightness < 0x4) /* turn the string off */ ret |= lm3630a_update(pchip, REG_CTRL, LM3630A_LEDA_ENABLE, 0); else @@ -233,7 +234,7 @@ static int lm3630a_bank_a_get_brightness(struct backlight_device *bl) if (rval < 0) goto out_i2c_err; brightness |= rval; - goto out; + return brightness; } /* disable sleep */ @@ -244,11 +245,8 @@ static int lm3630a_bank_a_get_brightness(struct backlight_device *bl) rval = lm3630a_read(pchip, REG_BRT_A); if (rval < 0) goto out_i2c_err; - brightness = rval; + return rval; -out: - bl->props.brightness = brightness; - return bl->props.brightness; out_i2c_err: dev_err(pchip->dev, "i2c failed to access register\n"); return 0; @@ -266,10 +264,11 @@ static int lm3630a_bank_b_update_status(struct backlight_device *bl) int ret; struct lm3630a_chip *pchip = bl_get_data(bl); enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; + int brightness = backlight_get_brightness(bl); /* pwm control */ if ((pwm_ctrl & LM3630A_PWM_BANK_B) != 0) - return lm3630a_pwm_ctrl(pchip, bl->props.brightness, + return lm3630a_pwm_ctrl(pchip, brightness, bl->props.max_brightness); /* disable sleep */ @@ -278,9 +277,9 @@ static int lm3630a_bank_b_update_status(struct backlight_device *bl) goto out_i2c_err; usleep_range(1000, 2000); /* minimum brightness is 0x04 */ - ret = lm3630a_write(pchip, REG_BRT_B, bl->props.brightness); + ret = lm3630a_write(pchip, REG_BRT_B, brightness); - if (backlight_is_blank(bl) || (backlight_get_brightness(bl) < 0x4)) + if (brightness < 0x4) /* turn the string off */ ret |= lm3630a_update(pchip, REG_CTRL, LM3630A_LEDB_ENABLE, 0); else @@ -310,7 +309,7 @@ static int lm3630a_bank_b_get_brightness(struct backlight_device *bl) if (rval < 0) goto out_i2c_err; brightness |= rval; - goto out; + return brightness; } /* disable sleep */ @@ -321,11 +320,8 @@ static int lm3630a_bank_b_get_brightness(struct backlight_device *bl) rval = lm3630a_read(pchip, REG_BRT_B); if (rval < 0) goto out_i2c_err; - brightness = rval; + return rval; -out: - bl->props.brightness = brightness; - return bl->props.brightness; out_i2c_err: dev_err(pchip->dev, "i2c failed to access register\n"); return 0; @@ -343,6 +339,7 @@ static int lm3630a_backlight_register(struct lm3630a_chip *pchip) struct backlight_properties props; const char *label; + memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_RAW; if (pdata->leda_ctrl != LM3630A_LEDA_DISABLE) { props.brightness = pdata->leda_init_brt; @@ -543,10 +540,8 @@ static int lm3630a_probe(struct i2c_client *client) pchip->enable_gpio = devm_gpiod_get_optional(&client->dev, "enable", GPIOD_OUT_HIGH); - if (IS_ERR(pchip->enable_gpio)) { - rval = PTR_ERR(pchip->enable_gpio); - return rval; - } + if (IS_ERR(pchip->enable_gpio)) + return PTR_ERR(pchip->enable_gpio); /* chip initialize */ rval = lm3630a_chip_init(pchip); @@ -563,10 +558,9 @@ static int lm3630a_probe(struct i2c_client *client) /* pwm */ if (pdata->pwm_ctrl != LM3630A_PWM_DISABLE) { pchip->pwmd = devm_pwm_get(pchip->dev, "lm3630a-pwm"); - if (IS_ERR(pchip->pwmd)) { - dev_err(&client->dev, "fail : get pwm device\n"); - return PTR_ERR(pchip->pwmd); - } + if (IS_ERR(pchip->pwmd)) + return dev_err_probe(&client->dev, PTR_ERR(pchip->pwmd), + "fail : get pwm device\n"); pwm_init_state(pchip->pwmd, &pchip->pwmd_state); } diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c index 5246c171497d..564f62acd721 100644 --- a/drivers/video/backlight/lm3639_bl.c +++ b/drivers/video/backlight/lm3639_bl.c @@ -338,6 +338,7 @@ static int lm3639_probe(struct i2c_client *client) } /* backlight */ + memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_RAW; props.brightness = pdata->init_brt_led; props.max_brightness = pdata->max_brt_led; diff --git a/drivers/video/backlight/lp8788_bl.c b/drivers/video/backlight/lp8788_bl.c index d1a14b0db265..31f97230ee50 100644 --- a/drivers/video/backlight/lp8788_bl.c +++ b/drivers/video/backlight/lp8788_bl.c @@ -191,6 +191,7 @@ static int lp8788_backlight_register(struct lp8788_bl *bl) int init_brt; char *name; + memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_PLATFORM; props.max_brightness = MAX_BRIGHTNESS; diff --git a/drivers/video/backlight/mp3309c.c b/drivers/video/backlight/mp3309c.c index 34d71259fac1..c80a1481e742 100644 --- a/drivers/video/backlight/mp3309c.c +++ b/drivers/video/backlight/mp3309c.c @@ -15,6 +15,8 @@ #include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/i2c.h> +#include <linux/mod_devicetable.h> +#include <linux/property.h> #include <linux/pwm.h> #include <linux/regmap.h> @@ -131,7 +133,7 @@ static int mp3309c_bl_update_status(struct backlight_device *bl) chip->pdata->levels[brightness], chip->pdata->levels[chip->pdata->max_brightness]); pwmstate.enabled = true; - ret = pwm_apply_state(chip->pwmd, &pwmstate); + ret = pwm_apply_might_sleep(chip->pwmd, &pwmstate); if (ret) return ret; @@ -199,20 +201,15 @@ static const struct backlight_ops mp3309c_bl_ops = { .update_status = mp3309c_bl_update_status, }; -static int pm3309c_parse_dt_node(struct mp3309c_chip *chip, - struct mp3309c_platform_data *pdata) +static int mp3309c_parse_fwnode(struct mp3309c_chip *chip, + struct mp3309c_platform_data *pdata) { - struct device_node *node = chip->dev->of_node; - struct property *prop_pwms; - struct property *prop_levels = NULL; - int length = 0; int ret, i; unsigned int num_levels, tmp_value; + struct device *dev = chip->dev; - if (!node) { - dev_err(chip->dev, "failed to get DT node\n"); - return -ENODEV; - } + if (!dev_fwnode(dev)) + return dev_err_probe(dev, -ENODEV, "failed to get firmware node\n"); /* * Dimming mode: the MP3309C provides two dimming control mode: @@ -224,12 +221,10 @@ static int pm3309c_parse_dt_node(struct mp3309c_chip *chip, * found in the backlight node, the mode switches to PWM mode. */ pdata->dimming_mode = DIMMING_ANALOG_I2C; - prop_pwms = of_find_property(node, "pwms", &length); - if (prop_pwms) { - chip->pwmd = devm_pwm_get(chip->dev, NULL); + if (device_property_present(dev, "pwms")) { + chip->pwmd = devm_pwm_get(dev, NULL); if (IS_ERR(chip->pwmd)) - return dev_err_probe(chip->dev, PTR_ERR(chip->pwmd), - "error getting pwm data\n"); + return dev_err_probe(dev, PTR_ERR(chip->pwmd), "error getting pwm data\n"); pdata->dimming_mode = DIMMING_PWM; pwm_apply_args(chip->pwmd); } @@ -247,21 +242,17 @@ static int pm3309c_parse_dt_node(struct mp3309c_chip *chip, num_levels = ANALOG_I2C_NUM_LEVELS; /* Enable GPIO used in I2C dimming mode only */ - chip->enable_gpio = devm_gpiod_get(chip->dev, "enable", - GPIOD_OUT_HIGH); + chip->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH); if (IS_ERR(chip->enable_gpio)) - return dev_err_probe(chip->dev, - PTR_ERR(chip->enable_gpio), + return dev_err_probe(dev, PTR_ERR(chip->enable_gpio), "error getting enable gpio\n"); } else { /* * PWM control mode: check for brightness level in DT */ - prop_levels = of_find_property(node, "brightness-levels", - &length); - if (prop_levels) { + if (device_property_present(dev, "brightness-levels")) { /* Read brightness levels from DT */ - num_levels = length / sizeof(u32); + num_levels = device_property_count_u32(dev, "brightness-levels"); if (num_levels < 2) return -EINVAL; } else { @@ -271,14 +262,12 @@ static int pm3309c_parse_dt_node(struct mp3309c_chip *chip, } /* Fill brightness levels array */ - pdata->levels = devm_kcalloc(chip->dev, num_levels, - sizeof(*pdata->levels), GFP_KERNEL); + pdata->levels = devm_kcalloc(dev, num_levels, sizeof(*pdata->levels), GFP_KERNEL); if (!pdata->levels) return -ENOMEM; - if (prop_levels) { - ret = of_property_read_u32_array(node, "brightness-levels", - pdata->levels, - num_levels); + if (device_property_present(dev, "brightness-levels")) { + ret = device_property_read_u32_array(dev, "brightness-levels", + pdata->levels, num_levels); if (ret < 0) return ret; } else { @@ -288,13 +277,11 @@ static int pm3309c_parse_dt_node(struct mp3309c_chip *chip, pdata->max_brightness = num_levels - 1; - ret = of_property_read_u32(node, "default-brightness", - &pdata->default_brightness); + ret = device_property_read_u32(dev, "default-brightness", &pdata->default_brightness); if (ret) pdata->default_brightness = pdata->max_brightness; if (pdata->default_brightness > pdata->max_brightness) { - dev_err(chip->dev, - "default brightness exceeds max brightness\n"); + dev_err_probe(dev, -ERANGE, "default brightness exceeds max brightness\n"); pdata->default_brightness = pdata->max_brightness; } @@ -310,8 +297,8 @@ static int pm3309c_parse_dt_node(struct mp3309c_chip *chip, * If missing, the default value for OVP is 35.5V */ pdata->over_voltage_protection = REG_I2C_1_OVP1; - if (!of_property_read_u32(node, "mps,overvoltage-protection-microvolt", - &tmp_value)) { + ret = device_property_read_u32(dev, "mps,overvoltage-protection-microvolt", &tmp_value); + if (!ret) { switch (tmp_value) { case 13500000: pdata->over_voltage_protection = 0x00; @@ -328,62 +315,59 @@ static int pm3309c_parse_dt_node(struct mp3309c_chip *chip, } /* Synchronous (default) and non-synchronous mode */ - pdata->sync_mode = true; - if (of_property_read_bool(node, "mps,no-sync-mode")) - pdata->sync_mode = false; + pdata->sync_mode = !device_property_read_bool(dev, "mps,no-sync-mode"); return 0; } static int mp3309c_probe(struct i2c_client *client) { - struct mp3309c_platform_data *pdata = dev_get_platdata(&client->dev); + struct device *dev = &client->dev; + struct mp3309c_platform_data *pdata = dev_get_platdata(dev); struct mp3309c_chip *chip; struct backlight_properties props; struct pwm_state pwmstate; int ret; - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - dev_err(&client->dev, "failed to check i2c functionality\n"); - return -EOPNOTSUPP; - } + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return dev_err_probe(dev, -EOPNOTSUPP, "failed to check i2c functionality\n"); - chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); + chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; - chip->dev = &client->dev; + chip->dev = dev; chip->regmap = devm_regmap_init_i2c(client, &mp3309c_regmap); if (IS_ERR(chip->regmap)) - return dev_err_probe(&client->dev, PTR_ERR(chip->regmap), + return dev_err_probe(dev, PTR_ERR(chip->regmap), "failed to allocate register map\n"); i2c_set_clientdata(client, chip); if (!pdata) { - pdata = devm_kzalloc(chip->dev, sizeof(*pdata), GFP_KERNEL); + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; - ret = pm3309c_parse_dt_node(chip, pdata); + ret = mp3309c_parse_fwnode(chip, pdata); if (ret) return ret; } chip->pdata = pdata; /* Backlight properties */ + memset(&props, 0, sizeof(struct backlight_properties)); props.brightness = pdata->default_brightness; props.max_brightness = pdata->max_brightness; props.scale = BACKLIGHT_SCALE_LINEAR; props.type = BACKLIGHT_RAW; props.power = FB_BLANK_UNBLANK; props.fb_blank = FB_BLANK_UNBLANK; - chip->bl = devm_backlight_device_register(chip->dev, "mp3309c", - chip->dev, chip, + chip->bl = devm_backlight_device_register(dev, "mp3309c", dev, chip, &mp3309c_bl_ops, &props); if (IS_ERR(chip->bl)) - return dev_err_probe(chip->dev, PTR_ERR(chip->bl), + return dev_err_probe(dev, PTR_ERR(chip->bl), "error registering backlight device\n"); /* In PWM dimming mode, enable pwm device */ @@ -393,10 +377,9 @@ static int mp3309c_probe(struct i2c_client *client) chip->pdata->default_brightness, chip->pdata->max_brightness); pwmstate.enabled = true; - ret = pwm_apply_state(chip->pwmd, &pwmstate); + ret = pwm_apply_might_sleep(chip->pwmd, &pwmstate); if (ret) - return dev_err_probe(chip->dev, ret, - "error setting pwm device\n"); + return dev_err_probe(dev, ret, "error setting pwm device\n"); } chip->pdata->status = FIRST_POWER_ON; diff --git a/drivers/video/backlight/pandora_bl.c b/drivers/video/backlight/pandora_bl.c index f946470ce9f6..51faa889e01f 100644 --- a/drivers/video/backlight/pandora_bl.c +++ b/drivers/video/backlight/pandora_bl.c @@ -114,10 +114,8 @@ static int pandora_backlight_probe(struct platform_device *pdev) u8 r; priv = devm_kmalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(&pdev->dev, "failed to allocate driver private data\n"); + if (!priv) return -ENOMEM; - } memset(&props, 0, sizeof(props)); props.max_brightness = MAX_USER_VALUE; diff --git a/drivers/video/cmdline.c b/drivers/video/cmdline.c index d3d257489c3d..49ee3fb4951a 100644 --- a/drivers/video/cmdline.c +++ b/drivers/video/cmdline.c @@ -80,6 +80,7 @@ const char *video_get_options(const char *name) } EXPORT_SYMBOL(video_get_options); +#if IS_ENABLED(CONFIG_FB_CORE) bool __video_get_options(const char *name, const char **options, bool is_of) { bool enabled = true; @@ -96,6 +97,7 @@ bool __video_get_options(const char *name, const char **options, bool is_of) return enabled; } EXPORT_SYMBOL(__video_get_options); +#endif /* * Process command line options for video adapters. This function is diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 2d0bcc1d786e..a61b8260b8f3 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -75,7 +75,6 @@ config FB_CIRRUS select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS - select VIDEO_NOMODESET help This enables support for Cirrus Logic GD542x/543x based boards on Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum. @@ -95,7 +94,6 @@ config FB_PM2 select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS - select VIDEO_NOMODESET help This is the frame buffer device driver for cards based on the 3D Labs Permedia, Permedia 2 and Permedia 2V chips. @@ -161,7 +159,6 @@ config FB_CYBER2000 tristate "CyberPro 2000/2010/5000 support" depends on FB && PCI && (BROKEN || !SPARC64) select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help This enables support for the Integraphics CyberPro 20x0 and 5000 VGA chips used in the Rebel.com Netwinder and other machines. @@ -312,7 +309,6 @@ config FB_CT65550 bool "Chips 65550 display support" depends on (FB = y) && PPC32 && PCI select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help This is the frame buffer device driver for the Chips & Technologies 65550 graphics chip in PowerBooks. @@ -321,7 +317,6 @@ config FB_ASILIANT bool "Asiliant (Chips) 69000 display support" depends on (FB = y) && PCI select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help This is the frame buffer device driver for the Asiliant 69030 chipset @@ -331,7 +326,6 @@ config FB_IMSTT select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS select FB_MACMODES if PPC_PMAC - select VIDEO_NOMODESET help The IMS Twin Turbo is a PCI-based frame buffer card bundled with many Macintosh and compatible computers. @@ -396,7 +390,6 @@ config FB_TGA select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS - select VIDEO_NOMODESET help This is the frame buffer device driver for generic TGA and SFB+ graphic cards. These include DEC ZLXp-E1, -E2 and -E3 PCI cards, @@ -573,7 +566,6 @@ config FB_XVR500 select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS - select VIDEO_NOMODESET help This is the framebuffer device for the Sun XVR-500 and similar graphics cards based upon the 3DLABS Wildcat chipset. The driver @@ -585,7 +577,6 @@ config FB_XVR2500 bool "Sun XVR-2500 3DLABS Wildcat support" depends on (FB = y) && PCI && SPARC64 select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help This is the framebuffer device for the Sun XVR-2500 and similar graphics cards based upon the 3DLABS Wildcat chipset. The driver @@ -611,7 +602,6 @@ config FB_PVR2 select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS - select VIDEO_NOMODESET help Say Y here if you have a PowerVR 2 card in your box. If you plan to run linux on your Dreamcast, you will have to say Y here. @@ -674,7 +664,6 @@ config FB_NVIDIA select FB_IOMEM_FOPS select BITREVERSE select VGASTATE - select VIDEO_NOMODESET help This driver supports graphics boards with the nVidia chips, TNT and newer. For very old chipsets, such as the RIVA128, then use @@ -723,7 +712,6 @@ config FB_RIVA select FB_MODE_HELPERS select BITREVERSE select VGASTATE - select VIDEO_NOMODESET help This driver supports graphics boards with the nVidia Riva/Geforce chips. @@ -766,7 +754,6 @@ config FB_I740 select FB_IOMEM_HELPERS select FB_MODE_HELPERS select VGASTATE - select VIDEO_NOMODESET select FB_DDC help This driver supports graphics cards based on Intel740 chip. @@ -777,7 +764,6 @@ config FB_I810 select FB_IOMEM_FOPS select FB_MODE_HELPERS select VGASTATE - select VIDEO_NOMODESET help This driver supports the on-board graphics built in to the Intel 810 and 815 chipsets. Say Y if you have and plan to use such a board. @@ -830,7 +816,6 @@ config FB_MATROX select FB_IOMEM_FOPS select FB_TILEBLITTING select FB_MACMODES if PPC_PMAC - select VIDEO_NOMODESET help Say Y here if you have a Matrox Millennium, Matrox Millennium II, Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox @@ -953,7 +938,6 @@ config FB_RADEON select FB_IOMEM_FOPS select FB_MACMODES if PPC select FB_MODE_HELPERS - select VIDEO_NOMODESET help Choose this option if you want to use an ATI Radeon graphics card as a framebuffer device. There are both PCI and AGP versions. You @@ -991,7 +975,6 @@ config FB_ATY128 select FB_BACKLIGHT if FB_ATY128_BACKLIGHT select FB_IOMEM_HELPERS select FB_MACMODES if PPC_PMAC - select VIDEO_NOMODESET help This driver supports graphics boards with the ATI Rage128 chips. Say Y if you have such a graphics board and read @@ -1017,7 +1000,6 @@ config FB_ATY select FB_IOMEM_FOPS select FB_MACMODES if PPC select FB_ATY_CT if SPARC64 && PCI - select VIDEO_NOMODESET help This driver supports graphics boards with the ATI Mach64 chips. Say Y if you have such a graphics board. @@ -1069,7 +1051,6 @@ config FB_S3 select FB_TILEBLITTING select FB_SVGALIB select VGASTATE - select VIDEO_NOMODESET select FONT_8x16 if FRAMEBUFFER_CONSOLE help Driver for graphics boards with S3 Trio / S3 Virge chip. @@ -1091,7 +1072,6 @@ config FB_SAVAGE select FB_IOMEM_FOPS select FB_MODE_HELPERS select VGASTATE - select VIDEO_NOMODESET help This driver supports notebooks and computers with S3 Savage PCI/AGP chips. @@ -1131,7 +1111,6 @@ config FB_SIS select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS select FB_SIS_300 if !FB_SIS_315 - select VIDEO_NOMODESET help This is the frame buffer device driver for the SiS 300, 315, 330 and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets. @@ -1162,7 +1141,6 @@ config FB_VIA select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS select I2C_ALGOBIT - select VIDEO_NOMODESET help This is the frame buffer device driver for Graphics chips of VIA UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/ @@ -1203,7 +1181,6 @@ config FB_NEOMAGIC select FB_IOMEM_FOPS select FB_MODE_HELPERS select VGASTATE - select VIDEO_NOMODESET help This driver supports notebooks with NeoMagic PCI chips. Say Y if you have such a graphics card. @@ -1215,7 +1192,6 @@ config FB_KYRO tristate "IMG Kyro support" depends on FB && PCI select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help Say Y here if you have a STG4000 / Kyro / PowerVR 3 based graphics board. @@ -1231,7 +1207,6 @@ config FB_3DFX select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS select FB_MODE_HELPERS - select VIDEO_NOMODESET help This driver supports graphics boards with the 3Dfx Banshee, Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have @@ -1260,7 +1235,6 @@ config FB_VOODOO1 depends on FB && PCI depends on FB_DEVICE select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or Voodoo2 (cvg) based graphics card. @@ -1283,7 +1257,6 @@ config FB_VT8623 select FB_TILEBLITTING select FB_SVGALIB select VGASTATE - select VIDEO_NOMODESET select FONT_8x16 if FRAMEBUFFER_CONSOLE help Driver for CastleRock integrated graphics core in the @@ -1298,7 +1271,6 @@ config FB_TRIDENT select FB_DDC select FB_IOMEM_FOPS select FB_MODE_HELPERS - select VIDEO_NOMODESET help This is the frame buffer device driver for Trident PCI/AGP chipsets. Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D @@ -1323,7 +1295,6 @@ config FB_ARK select FB_TILEBLITTING select FB_SVGALIB select VGASTATE - select VIDEO_NOMODESET select FONT_8x16 if FRAMEBUFFER_CONSOLE help Driver for PCI graphics boards with ARK 2000PV chip @@ -1336,7 +1307,6 @@ config FB_PM3 select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS - select VIDEO_NOMODESET help This is the frame buffer device driver for the 3DLabs Permedia3 chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 & @@ -1347,7 +1317,6 @@ config FB_CARMINE tristate "Fujitsu carmine frame buffer support" depends on FB && PCI select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help This is the frame buffer device driver for the Fujitsu Carmine chip. The driver provides two independent frame buffer devices. @@ -1629,7 +1598,6 @@ config FB_IBM_GXT4500 tristate "Framebuffer support for IBM GXT4000P/4500P/6000P/6500P adaptors" depends on FB select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help Say Y here to enable support for the IBM GXT4000P/6000P and GXT4500P/6500P display adaptor based on Raster Engine RC1000, @@ -1747,7 +1715,6 @@ config FB_MB862XX depends on FB depends on PCI || (OF && PPC) select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers. @@ -1813,7 +1780,6 @@ config FB_HYPERV depends on FB && HYPERV select DMA_CMA if HAVE_DMA_CONTIGUOUS && CMA select FB_IOMEM_HELPERS_DEFERRED - select VIDEO_NOMODESET help This framebuffer driver supports Microsoft Hyper-V Synthetic Video. @@ -1847,7 +1813,6 @@ config FB_SM712 tristate "Silicon Motion SM712 framebuffer support" depends on FB && PCI select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help Frame buffer driver for the Silicon Motion SM710, SM712, SM721 and SM722 chips. diff --git a/drivers/video/fbdev/chipsfb.c b/drivers/video/fbdev/chipsfb.c index b80711f13df8..b16a905588fe 100644 --- a/drivers/video/fbdev/chipsfb.c +++ b/drivers/video/fbdev/chipsfb.c @@ -15,6 +15,7 @@ */ #include <linux/aperture.h> +#include <linux/backlight.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/video/fbdev/core/Kconfig b/drivers/video/fbdev/core/Kconfig index 21053bf00dc5..db09fe87fcd4 100644 --- a/drivers/video/fbdev/core/Kconfig +++ b/drivers/video/fbdev/core/Kconfig @@ -4,7 +4,7 @@ # config FB_CORE - select VIDEO_CMDLINE + select VIDEO tristate config FB_NOTIFY diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 17a9fc80b4e4..98d0e2dbcd2f 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2395,11 +2395,9 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount, struct fbcon_ops *ops = info->fbcon_par; struct fbcon_display *p = &fb_display[vc->vc_num]; int resize, ret, old_userfont, old_width, old_height, old_charcount; - char *old_data = NULL; + u8 *old_data = vc->vc_font.data; resize = (w != vc->vc_font.width) || (h != vc->vc_font.height); - if (p->userfont) - old_data = vc->vc_font.data; vc->vc_font.data = (void *)(p->fontdata = data); old_userfont = p->userfont; if ((p->userfont = userfont)) @@ -2433,13 +2431,13 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount, update_screen(vc); } - if (old_data && (--REFCOUNT(old_data) == 0)) + if (old_userfont && (--REFCOUNT(old_data) == 0)) kfree(old_data - FONT_EXTRA_WORDS * sizeof(int)); return 0; err_out: p->fontdata = old_data; - vc->vc_font.data = (void *)old_data; + vc->vc_font.data = old_data; if (userfont) { p->userfont = old_userfont; diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index fc206755f5f6..48287366e0d4 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -645,7 +645,6 @@ int fb_new_modelist(struct fb_info *info) return 0; } -#if defined(CONFIG_VIDEO_NOMODESET) bool fb_modesetting_disabled(const char *drvname) { bool fwonly = video_firmware_drivers_only(); @@ -657,6 +656,5 @@ bool fb_modesetting_disabled(const char *drvname) return fwonly; } EXPORT_SYMBOL(fb_modesetting_disabled); -#endif MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index f9b4ddd592ce..8dd82afb3452 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -13,11 +13,9 @@ #include <linux/efi-bgrt.h> #include <linux/errno.h> #include <linux/fb.h> -#include <linux/pci.h> #include <linux/platform_device.h> #include <linux/printk.h> #include <linux/screen_info.h> -#include <linux/pm_runtime.h> #include <video/vga.h> #include <asm/efi.h> #include <drm/drm_utils.h> /* For drm_get_panel_orientation_quirk */ @@ -48,8 +46,6 @@ static bool use_bgrt = true; static bool request_mem_succeeded = false; static u64 mem_flags = EFI_MEMORY_WC | EFI_MEMORY_UC; -static struct pci_dev *efifb_pci_dev; /* dev with BAR covering the efifb */ - struct efifb_par { u32 pseudo_palette[16]; resource_size_t base; @@ -108,7 +104,7 @@ static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, */ #if defined CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER && \ defined CONFIG_ACPI_BGRT -static void efifb_copy_bmp(u8 *src, u32 *dst, int width, struct screen_info *si) +static void efifb_copy_bmp(u8 *src, u32 *dst, int width, const struct screen_info *si) { u8 r, g, b; @@ -130,7 +126,7 @@ static void efifb_copy_bmp(u8 *src, u32 *dst, int width, struct screen_info *si) * resolution still fits, it will be displayed very close to the right edge of * the display looking quite bad. This function checks for this. */ -static bool efifb_bgrt_sanity_check(struct screen_info *si, u32 bmp_width) +static bool efifb_bgrt_sanity_check(const struct screen_info *si, u32 bmp_width) { /* * All x86 firmwares horizontally center the image (the yoffset @@ -141,16 +137,15 @@ static bool efifb_bgrt_sanity_check(struct screen_info *si, u32 bmp_width) return bgrt_tab.image_offset_x == expected_xoffset; } #else -static bool efifb_bgrt_sanity_check(struct screen_info *si, u32 bmp_width) +static bool efifb_bgrt_sanity_check(const struct screen_info *si, u32 bmp_width) { return true; } #endif -static void efifb_show_boot_graphics(struct fb_info *info) +static void efifb_show_boot_graphics(struct fb_info *info, const struct screen_info *si) { u32 bmp_width, bmp_height, bmp_pitch, dst_x, y, src_y; - struct screen_info *si = &screen_info; struct bmp_file_header *file_header; struct bmp_dib_header *dib_header; void *bgrt_image = NULL; @@ -247,7 +242,8 @@ error: pr_warn("efifb: Ignoring BGRT: unexpected or invalid BMP data\n"); } #else -static inline void efifb_show_boot_graphics(struct fb_info *info) {} +static inline void efifb_show_boot_graphics(struct fb_info *info, const struct screen_info *si) +{ } #endif /* @@ -258,9 +254,6 @@ static void efifb_destroy(struct fb_info *info) { struct efifb_par *par = info->par; - if (efifb_pci_dev) - pm_runtime_put(&efifb_pci_dev->dev); - if (info->screen_base) { if (mem_flags & (EFI_MEMORY_UC | EFI_MEMORY_WC)) iounmap(info->screen_base); @@ -282,7 +275,7 @@ static const struct fb_ops efifb_ops = { .fb_setcolreg = efifb_setcolreg, }; -static int efifb_setup(char *options) +static int efifb_setup(struct screen_info *si, char *options) { char *this_opt; @@ -290,16 +283,16 @@ static int efifb_setup(char *options) while ((this_opt = strsep(&options, ",")) != NULL) { if (!*this_opt) continue; - efifb_setup_from_dmi(&screen_info, this_opt); + efifb_setup_from_dmi(si, this_opt); if (!strncmp(this_opt, "base:", 5)) - screen_info.lfb_base = simple_strtoul(this_opt+5, NULL, 0); + si->lfb_base = simple_strtoul(this_opt+5, NULL, 0); else if (!strncmp(this_opt, "stride:", 7)) - screen_info.lfb_linelength = simple_strtoul(this_opt+7, NULL, 0) * 4; + si->lfb_linelength = simple_strtoul(this_opt+7, NULL, 0) * 4; else if (!strncmp(this_opt, "height:", 7)) - screen_info.lfb_height = simple_strtoul(this_opt+7, NULL, 0); + si->lfb_height = simple_strtoul(this_opt+7, NULL, 0); else if (!strncmp(this_opt, "width:", 6)) - screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0); + si->lfb_width = simple_strtoul(this_opt+6, NULL, 0); else if (!strcmp(this_opt, "nowc")) mem_flags &= ~EFI_MEMORY_WC; else if (!strcmp(this_opt, "nobgrt")) @@ -310,15 +303,15 @@ static int efifb_setup(char *options) return 0; } -static inline bool fb_base_is_valid(void) +static inline bool fb_base_is_valid(struct screen_info *si) { - if (screen_info.lfb_base) + if (si->lfb_base) return true; - if (!(screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)) + if (!(si->capabilities & VIDEO_CAPABILITY_64BIT_BASE)) return false; - if (screen_info.ext_lfb_base) + if (si->ext_lfb_base) return true; return false; @@ -329,7 +322,10 @@ static ssize_t name##_show(struct device *dev, \ struct device_attribute *attr, \ char *buf) \ { \ - return sprintf(buf, fmt "\n", (screen_info.lfb_##name)); \ + struct screen_info *si = dev_get_platdata(dev); \ + if (!si) \ + return -ENODEV; \ + return sprintf(buf, fmt "\n", (si->lfb_##name)); \ } \ static DEVICE_ATTR_RO(name) @@ -349,13 +345,9 @@ static struct attribute *efifb_attrs[] = { }; ATTRIBUTE_GROUPS(efifb); -static bool pci_dev_disabled; /* FB base matches BAR of a disabled device */ - -static struct resource *bar_resource; -static u64 bar_offset; - static int efifb_probe(struct platform_device *dev) { + struct screen_info *si; struct fb_info *info; struct efifb_par *par; int err, orientation; @@ -365,62 +357,60 @@ static int efifb_probe(struct platform_device *dev) char *option = NULL; efi_memory_desc_t md; - if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled) + /* + * If we fail probing the device, the kernel might try a different + * driver. We get a copy of the attached screen_info, so that we can + * modify its values without affecting later drivers. + */ + si = dev_get_platdata(&dev->dev); + if (!si) + return -ENODEV; + si = devm_kmemdup(&dev->dev, si, sizeof(*si), GFP_KERNEL); + if (!si) + return -ENOMEM; + + if (si->orig_video_isVGA != VIDEO_TYPE_EFI) return -ENODEV; if (fb_get_options("efifb", &option)) return -ENODEV; - efifb_setup(option); + efifb_setup(si, option); /* We don't get linelength from UGA Draw Protocol, only from * EFI Graphics Protocol. So if it's not in DMI, and it's not * passed in from the user, we really can't use the framebuffer. */ - if (!screen_info.lfb_linelength) + if (!si->lfb_linelength) return -ENODEV; - if (!screen_info.lfb_depth) - screen_info.lfb_depth = 32; - if (!screen_info.pages) - screen_info.pages = 1; - if (!fb_base_is_valid()) { + if (!si->lfb_depth) + si->lfb_depth = 32; + if (!si->pages) + si->pages = 1; + if (!fb_base_is_valid(si)) { printk(KERN_DEBUG "efifb: invalid framebuffer address\n"); return -ENODEV; } printk(KERN_INFO "efifb: probing for efifb\n"); /* just assume they're all unset if any are */ - if (!screen_info.blue_size) { - screen_info.blue_size = 8; - screen_info.blue_pos = 0; - screen_info.green_size = 8; - screen_info.green_pos = 8; - screen_info.red_size = 8; - screen_info.red_pos = 16; - screen_info.rsvd_size = 8; - screen_info.rsvd_pos = 24; + if (!si->blue_size) { + si->blue_size = 8; + si->blue_pos = 0; + si->green_size = 8; + si->green_pos = 8; + si->red_size = 8; + si->red_pos = 16; + si->rsvd_size = 8; + si->rsvd_pos = 24; } - efifb_fix.smem_start = screen_info.lfb_base; + efifb_fix.smem_start = __screen_info_lfb_base(si); - if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) { - u64 ext_lfb_base; - - ext_lfb_base = (u64)(unsigned long)screen_info.ext_lfb_base << 32; - efifb_fix.smem_start |= ext_lfb_base; - } - - if (bar_resource && - bar_resource->start + bar_offset != efifb_fix.smem_start) { - dev_info(&efifb_pci_dev->dev, - "BAR has moved, updating efifb address\n"); - efifb_fix.smem_start = bar_resource->start + bar_offset; - } - - efifb_defined.bits_per_pixel = screen_info.lfb_depth; - efifb_defined.xres = screen_info.lfb_width; - efifb_defined.yres = screen_info.lfb_height; - efifb_fix.line_length = screen_info.lfb_linelength; + efifb_defined.bits_per_pixel = si->lfb_depth; + efifb_defined.xres = si->lfb_width; + efifb_defined.yres = si->lfb_height; + efifb_fix.line_length = si->lfb_linelength; /* size_vmode -- that is the amount of memory needed for the * used video mode, i.e. the minimum amount of @@ -430,7 +420,7 @@ static int efifb_probe(struct platform_device *dev) /* size_total -- all video memory we have. Used for * entries, ressource allocation and bounds * checking. */ - size_total = screen_info.lfb_size; + size_total = si->lfb_size; if (size_total < size_vmode) size_total = size_vmode; @@ -505,14 +495,14 @@ static int efifb_probe(struct platform_device *dev) goto err_release_fb; } - efifb_show_boot_graphics(info); + efifb_show_boot_graphics(info, si); pr_info("efifb: framebuffer at 0x%lx, using %dk, total %dk\n", efifb_fix.smem_start, size_remap/1024, size_total/1024); pr_info("efifb: mode is %dx%dx%d, linelength=%d, pages=%d\n", efifb_defined.xres, efifb_defined.yres, efifb_defined.bits_per_pixel, efifb_fix.line_length, - screen_info.pages); + si->pages); efifb_defined.xres_virtual = efifb_defined.xres; efifb_defined.yres_virtual = efifb_fix.smem_len / @@ -526,26 +516,26 @@ static int efifb_probe(struct platform_device *dev) efifb_defined.left_margin = (efifb_defined.xres / 8) & 0xf8; efifb_defined.hsync_len = (efifb_defined.xres / 8) & 0xf8; - efifb_defined.red.offset = screen_info.red_pos; - efifb_defined.red.length = screen_info.red_size; - efifb_defined.green.offset = screen_info.green_pos; - efifb_defined.green.length = screen_info.green_size; - efifb_defined.blue.offset = screen_info.blue_pos; - efifb_defined.blue.length = screen_info.blue_size; - efifb_defined.transp.offset = screen_info.rsvd_pos; - efifb_defined.transp.length = screen_info.rsvd_size; + efifb_defined.red.offset = si->red_pos; + efifb_defined.red.length = si->red_size; + efifb_defined.green.offset = si->green_pos; + efifb_defined.green.length = si->green_size; + efifb_defined.blue.offset = si->blue_pos; + efifb_defined.blue.length = si->blue_size; + efifb_defined.transp.offset = si->rsvd_pos; + efifb_defined.transp.length = si->rsvd_size; pr_info("efifb: %s: " "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n", "Truecolor", - screen_info.rsvd_size, - screen_info.red_size, - screen_info.green_size, - screen_info.blue_size, - screen_info.rsvd_pos, - screen_info.red_pos, - screen_info.green_pos, - screen_info.blue_pos); + si->rsvd_size, + si->red_size, + si->green_size, + si->blue_size, + si->rsvd_pos, + si->red_pos, + si->green_pos, + si->blue_pos); efifb_fix.ypanstep = 0; efifb_fix.ywrapstep = 0; @@ -582,26 +572,20 @@ static int efifb_probe(struct platform_device *dev) goto err_groups; } - if (efifb_pci_dev) - WARN_ON(pm_runtime_get_sync(&efifb_pci_dev->dev) < 0); - err = devm_aperture_acquire_for_platform_device(dev, par->base, par->size); if (err) { pr_err("efifb: cannot acquire aperture\n"); - goto err_put_rpm_ref; + goto err_fb_dealloc_cmap; } err = register_framebuffer(info); if (err < 0) { pr_err("efifb: cannot register framebuffer\n"); - goto err_put_rpm_ref; + goto err_fb_dealloc_cmap; } fb_info(info, "%s frame buffer device\n", info->fix.id); return 0; -err_put_rpm_ref: - if (efifb_pci_dev) - pm_runtime_put(&efifb_pci_dev->dev); - +err_fb_dealloc_cmap: fb_dealloc_cmap(&info->cmap); err_groups: sysfs_remove_groups(&dev->dev.kobj, efifb_groups); @@ -636,58 +620,3 @@ static struct platform_driver efifb_driver = { }; builtin_platform_driver(efifb_driver); - -#if defined(CONFIG_PCI) - -static void record_efifb_bar_resource(struct pci_dev *dev, int idx, u64 offset) -{ - u16 word; - - efifb_pci_dev = dev; - - pci_read_config_word(dev, PCI_COMMAND, &word); - if (!(word & PCI_COMMAND_MEMORY)) { - pci_dev_disabled = true; - dev_err(&dev->dev, - "BAR %d: assigned to efifb but device is disabled!\n", - idx); - return; - } - - bar_resource = &dev->resource[idx]; - bar_offset = offset; - - dev_info(&dev->dev, "BAR %d: assigned to efifb\n", idx); -} - -static void efifb_fixup_resources(struct pci_dev *dev) -{ - u64 base = screen_info.lfb_base; - u64 size = screen_info.lfb_size; - int i; - - if (efifb_pci_dev || screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) - return; - - if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) - base |= (u64)screen_info.ext_lfb_base << 32; - - if (!base) - return; - - for (i = 0; i < PCI_STD_NUM_BARS; i++) { - struct resource *res = &dev->resource[i]; - - if (!(res->flags & IORESOURCE_MEM)) - continue; - - if (res->start <= base && res->end >= base + size - 1) { - record_efifb_bar_resource(dev, i, base - res->start); - break; - } - } -} -DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY, - 16, efifb_fixup_resources); - -#endif diff --git a/drivers/video/fbdev/geode/Kconfig b/drivers/video/fbdev/geode/Kconfig index 9a49916e0492..3b20420cc94d 100644 --- a/drivers/video/fbdev/geode/Kconfig +++ b/drivers/video/fbdev/geode/Kconfig @@ -14,7 +14,6 @@ config FB_GEODE_LX tristate "AMD Geode LX framebuffer support" depends on FB && FB_GEODE select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help Framebuffer driver for the display controller integrated into the AMD Geode LX processors. @@ -28,7 +27,6 @@ config FB_GEODE_GX tristate "AMD Geode GX framebuffer support" depends on FB && FB_GEODE select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help Framebuffer driver for the display controller integrated into the AMD Geode GX processors. @@ -42,7 +40,6 @@ config FB_GEODE_GX1 tristate "AMD Geode GX1 framebuffer support" depends on FB && FB_GEODE select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help Framebuffer driver for the display controller integrated into the AMD Geode GX1 processor. diff --git a/drivers/video/fbdev/hgafb.c b/drivers/video/fbdev/hgafb.c index 264c8cedba15..c3bc5b78b749 100644 --- a/drivers/video/fbdev/hgafb.c +++ b/drivers/video/fbdev/hgafb.c @@ -670,7 +670,7 @@ static void __exit hgafb_exit(void) * * ------------------------------------------------------------------------- */ -MODULE_AUTHOR("Ferenc Bakonyi (fero@drama.obuda.kando.hu)"); +MODULE_AUTHOR("Ferenc Bakonyi <fero@drama.obuda.kando.hu>"); MODULE_DESCRIPTION("FBDev driver for Hercules Graphics Adaptor"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c index c26ee6fd73c9..8fdccf033b2d 100644 --- a/drivers/video/fbdev/hyperv_fb.c +++ b/drivers/video/fbdev/hyperv_fb.c @@ -1010,8 +1010,6 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) goto getmem_done; } pr_info("Unable to allocate enough contiguous physical memory on Gen 1 VM. Using MMIO instead.\n"); - } else { - goto err1; } /* diff --git a/drivers/video/fbdev/mmp/hw/mmp_spi.c b/drivers/video/fbdev/mmp/hw/mmp_spi.c index 0f8f0312a7c4..cf23650d7f0b 100644 --- a/drivers/video/fbdev/mmp/hw/mmp_spi.c +++ b/drivers/video/fbdev/mmp/hw/mmp_spi.c @@ -32,7 +32,7 @@ static inline int lcd_spi_write(struct spi_device *spi, u32 data) int timeout = 100000, isr, ret = 0; u32 tmp; void __iomem *reg_base = (void __iomem *) - *(void **)spi_master_get_devdata(spi->master); + *(void **) spi_controller_get_devdata(spi->controller); /* clear ISR */ writel_relaxed(~SPI_IRQ_MASK, reg_base + SPU_IRQ_ISR); @@ -81,7 +81,7 @@ static inline int lcd_spi_write(struct spi_device *spi, u32 data) static int lcd_spi_setup(struct spi_device *spi) { void __iomem *reg_base = (void __iomem *) - *(void **)spi_master_get_devdata(spi->master); + *(void **) spi_controller_get_devdata(spi->controller); u32 tmp; tmp = CFG_SCLKCNT(16) | @@ -136,32 +136,32 @@ static int lcd_spi_one_transfer(struct spi_device *spi, struct spi_message *m) int lcd_spi_register(struct mmphw_ctrl *ctrl) { - struct spi_master *master; + struct spi_controller *ctlr; void **p_regbase; int err; - master = spi_alloc_master(ctrl->dev, sizeof(void *)); - if (!master) { + ctlr = spi_alloc_master(ctrl->dev, sizeof(void *)); + if (!ctlr) { dev_err(ctrl->dev, "unable to allocate SPI master\n"); return -ENOMEM; } - p_regbase = spi_master_get_devdata(master); + p_regbase = spi_controller_get_devdata(ctlr); *p_regbase = (void __force *)ctrl->reg_base; /* set bus num to 5 to avoid conflict with other spi hosts */ - master->bus_num = 5; - master->num_chipselect = 1; - master->setup = lcd_spi_setup; - master->transfer = lcd_spi_one_transfer; + ctlr->bus_num = 5; + ctlr->num_chipselect = 1; + ctlr->setup = lcd_spi_setup; + ctlr->transfer = lcd_spi_one_transfer; - err = spi_register_master(master); + err = spi_register_controller(ctlr); if (err < 0) { dev_err(ctrl->dev, "unable to register SPI master\n"); - spi_master_put(master); + spi_controller_put(ctlr); return err; } - dev_info(&master->dev, "registered\n"); + dev_info(&ctlr->dev, "registered\n"); return 0; } diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index 6f58ee276ad1..028a56525047 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -470,7 +470,7 @@ static int simplefb_attach_genpds(struct simplefb_par *par, if (err == -ENOENT) return 0; - dev_info(dev, "failed to parse power-domains: %d\n", err); + dev_err(dev, "failed to parse power-domains: %d\n", err); return err; } diff --git a/drivers/video/fbdev/vesafb.c b/drivers/video/fbdev/vesafb.c index c0edceea0a79..8ab64ae4cad3 100644 --- a/drivers/video/fbdev/vesafb.c +++ b/drivers/video/fbdev/vesafb.c @@ -243,6 +243,7 @@ static int vesafb_setup(char *options) static int vesafb_probe(struct platform_device *dev) { + struct screen_info *si; struct fb_info *info; struct vesafb_par *par; int i, err; @@ -251,21 +252,33 @@ static int vesafb_probe(struct platform_device *dev) unsigned int size_total; char *option = NULL; + /* + * If we fail probing the device, the kernel might try a different + * driver. We get a copy of the attached screen_info, so that we can + * modify its values without affecting later drivers. + */ + si = dev_get_platdata(&dev->dev); + if (!si) + return -ENODEV; + si = devm_kmemdup(&dev->dev, si, sizeof(*si), GFP_KERNEL); + if (!si) + return -ENOMEM; + /* ignore error return of fb_get_options */ fb_get_options("vesafb", &option); vesafb_setup(option); - if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) + if (si->orig_video_isVGA != VIDEO_TYPE_VLFB) return -ENODEV; - vga_compat = (screen_info.capabilities & 2) ? 0 : 1; - vesafb_fix.smem_start = screen_info.lfb_base; - vesafb_defined.bits_per_pixel = screen_info.lfb_depth; + vga_compat = (si->capabilities & 2) ? 0 : 1; + vesafb_fix.smem_start = si->lfb_base; + vesafb_defined.bits_per_pixel = si->lfb_depth; if (15 == vesafb_defined.bits_per_pixel) vesafb_defined.bits_per_pixel = 16; - vesafb_defined.xres = screen_info.lfb_width; - vesafb_defined.yres = screen_info.lfb_height; - vesafb_fix.line_length = screen_info.lfb_linelength; + vesafb_defined.xres = si->lfb_width; + vesafb_defined.yres = si->lfb_height; + vesafb_fix.line_length = si->lfb_linelength; vesafb_fix.visual = (vesafb_defined.bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; @@ -277,7 +290,7 @@ static int vesafb_probe(struct platform_device *dev) /* size_total -- all video memory we have. Used for mtrr * entries, resource allocation and bounds * checking. */ - size_total = screen_info.lfb_size * 65536; + size_total = si->lfb_size * 65536; if (vram_total) size_total = vram_total * 1024 * 1024; if (size_total < size_vmode) @@ -297,7 +310,7 @@ static int vesafb_probe(struct platform_device *dev) vesafb_fix.smem_len = size_remap; #ifndef __i386__ - screen_info.vesapm_seg = 0; + si->vesapm_seg = 0; #endif if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) { @@ -317,23 +330,26 @@ static int vesafb_probe(struct platform_device *dev) par = info->par; info->pseudo_palette = par->pseudo_palette; - par->base = screen_info.lfb_base; + par->base = si->lfb_base; par->size = size_total; printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n", - vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages); + vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, + vesafb_fix.line_length, si->pages); - if (screen_info.vesapm_seg) { + if (si->vesapm_seg) { printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n", - screen_info.vesapm_seg,screen_info.vesapm_off); + si->vesapm_seg, si->vesapm_off); } - if (screen_info.vesapm_seg < 0xc000) + if (si->vesapm_seg < 0xc000) ypan = pmi_setpal = 0; /* not available or some DOS TSR ... */ if (ypan || pmi_setpal) { + unsigned long pmi_phys; unsigned short *pmi_base; - pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off); + pmi_phys = ((unsigned long)si->vesapm_seg << 4) + si->vesapm_off; + pmi_base = (unsigned short *)phys_to_virt(pmi_phys); pmi_start = (void*)((char*)pmi_base + pmi_base[1]); pmi_pal = (void*)((char*)pmi_base + pmi_base[2]); printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal); @@ -377,14 +393,14 @@ static int vesafb_probe(struct platform_device *dev) vesafb_defined.left_margin = (vesafb_defined.xres / 8) & 0xf8; vesafb_defined.hsync_len = (vesafb_defined.xres / 8) & 0xf8; - vesafb_defined.red.offset = screen_info.red_pos; - vesafb_defined.red.length = screen_info.red_size; - vesafb_defined.green.offset = screen_info.green_pos; - vesafb_defined.green.length = screen_info.green_size; - vesafb_defined.blue.offset = screen_info.blue_pos; - vesafb_defined.blue.length = screen_info.blue_size; - vesafb_defined.transp.offset = screen_info.rsvd_pos; - vesafb_defined.transp.length = screen_info.rsvd_size; + vesafb_defined.red.offset = si->red_pos; + vesafb_defined.red.length = si->red_size; + vesafb_defined.green.offset = si->green_pos; + vesafb_defined.green.length = si->green_size; + vesafb_defined.blue.offset = si->blue_pos; + vesafb_defined.blue.length = si->blue_size; + vesafb_defined.transp.offset = si->rsvd_pos; + vesafb_defined.transp.length = si->rsvd_size; if (vesafb_defined.bits_per_pixel <= 8) { depth = vesafb_defined.green.length; @@ -399,14 +415,14 @@ static int vesafb_probe(struct platform_device *dev) (vesafb_defined.bits_per_pixel > 8) ? "Truecolor" : (vga_compat || pmi_setpal) ? "Pseudocolor" : "Static Pseudocolor", - screen_info.rsvd_size, - screen_info.red_size, - screen_info.green_size, - screen_info.blue_size, - screen_info.rsvd_pos, - screen_info.red_pos, - screen_info.green_pos, - screen_info.blue_pos); + si->rsvd_size, + si->red_size, + si->green_size, + si->blue_size, + si->rsvd_pos, + si->red_pos, + si->green_pos, + si->blue_pos); vesafb_fix.ypanstep = ypan ? 1 : 0; vesafb_fix.ywrapstep = (ypan>1) ? 1 : 0; diff --git a/drivers/video/screen_info_generic.c b/drivers/video/screen_info_generic.c new file mode 100644 index 000000000000..64117c6367ab --- /dev/null +++ b/drivers/video/screen_info_generic.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/export.h> +#include <linux/ioport.h> +#include <linux/screen_info.h> +#include <linux/string.h> + +static void resource_init_named(struct resource *r, + resource_size_t start, resource_size_t size, + const char *name, unsigned int flags) +{ + memset(r, 0, sizeof(*r)); + + r->start = start; + r->end = start + size - 1; + r->name = name; + r->flags = flags; +} + +static void resource_init_io_named(struct resource *r, + resource_size_t start, resource_size_t size, + const char *name) +{ + resource_init_named(r, start, size, name, IORESOURCE_IO); +} + +static void resource_init_mem_named(struct resource *r, + resource_size_t start, resource_size_t size, + const char *name) +{ + resource_init_named(r, start, size, name, IORESOURCE_MEM); +} + +static inline bool __screen_info_has_ega_gfx(unsigned int mode) +{ + switch (mode) { + case 0x0d: /* 320x200-4 */ + case 0x0e: /* 640x200-4 */ + case 0x0f: /* 640x350-1 */ + case 0x10: /* 640x350-4 */ + return true; + default: + return false; + } +} + +static inline bool __screen_info_has_vga_gfx(unsigned int mode) +{ + switch (mode) { + case 0x10: /* 640x480-1 */ + case 0x12: /* 640x480-4 */ + case 0x13: /* 320-200-8 */ + case 0x6a: /* 800x600-4 (VESA) */ + return true; + default: + return __screen_info_has_ega_gfx(mode); + } +} + +/** + * screen_info_resources() - Get resources from screen_info structure + * @si: the screen_info + * @r: pointer to an array of resource structures + * @num: number of elements in @r: + * + * Returns: + * The number of resources stored in @r on success, or a negative errno code otherwise. + * + * A call to screen_info_resources() returns the resources consumed by the + * screen_info's device or framebuffer. The result is stored in the caller-supplied + * array @r with up to @num elements. The function returns the number of + * initialized elements. + */ +ssize_t screen_info_resources(const struct screen_info *si, struct resource *r, size_t num) +{ + struct resource *pos = r; + unsigned int type = screen_info_video_type(si); + u64 base, size; + + switch (type) { + case VIDEO_TYPE_MDA: + if (num > 0) + resource_init_io_named(pos++, 0x3b0, 12, "mda"); + if (num > 1) + resource_init_io_named(pos++, 0x3bf, 0x01, "mda"); + if (num > 2) + resource_init_mem_named(pos++, 0xb0000, 0x2000, "mda"); + break; + case VIDEO_TYPE_CGA: + if (num > 0) + resource_init_io_named(pos++, 0x3d4, 0x02, "cga"); + if (num > 1) + resource_init_mem_named(pos++, 0xb8000, 0x2000, "cga"); + break; + case VIDEO_TYPE_EGAM: + if (num > 0) + resource_init_io_named(pos++, 0x3bf, 0x10, "ega"); + if (num > 1) + resource_init_mem_named(pos++, 0xb0000, 0x8000, "ega"); + break; + case VIDEO_TYPE_EGAC: + if (num > 0) + resource_init_io_named(pos++, 0x3c0, 0x20, "ega"); + if (num > 1) { + if (__screen_info_has_ega_gfx(si->orig_video_mode)) + resource_init_mem_named(pos++, 0xa0000, 0x10000, "ega"); + else + resource_init_mem_named(pos++, 0xb8000, 0x8000, "ega"); + } + break; + case VIDEO_TYPE_VGAC: + if (num > 0) + resource_init_io_named(pos++, 0x3c0, 0x20, "vga+"); + if (num > 1) { + if (__screen_info_has_vga_gfx(si->orig_video_mode)) + resource_init_mem_named(pos++, 0xa0000, 0x10000, "vga+"); + else + resource_init_mem_named(pos++, 0xb8000, 0x8000, "vga+"); + } + break; + case VIDEO_TYPE_VLFB: + case VIDEO_TYPE_EFI: + base = __screen_info_lfb_base(si); + if (!base) + break; + size = __screen_info_lfb_size(si, type); + if (!size) + break; + if (num > 0) + resource_init_mem_named(pos++, base, size, "lfb"); + break; + case VIDEO_TYPE_PICA_S3: + case VIDEO_TYPE_MIPS_G364: + case VIDEO_TYPE_SGI: + case VIDEO_TYPE_TGAC: + case VIDEO_TYPE_SUN: + case VIDEO_TYPE_SUNPCI: + case VIDEO_TYPE_PMAC: + default: + /* not supported */ + return -EINVAL; + } + + return pos - r; +} +EXPORT_SYMBOL(screen_info_resources); diff --git a/drivers/video/screen_info_pci.c b/drivers/video/screen_info_pci.c new file mode 100644 index 000000000000..6c5833517141 --- /dev/null +++ b/drivers/video/screen_info_pci.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/pci.h> +#include <linux/printk.h> +#include <linux/screen_info.h> +#include <linux/string.h> + +static struct pci_dev *screen_info_lfb_pdev; +static size_t screen_info_lfb_bar; +static resource_size_t screen_info_lfb_offset; +static struct resource screen_info_lfb_res = DEFINE_RES_MEM(0, 0); + +static bool __screen_info_relocation_is_valid(const struct screen_info *si, struct resource *pr) +{ + u64 size = __screen_info_lfb_size(si, screen_info_video_type(si)); + + if (screen_info_lfb_offset > resource_size(pr)) + return false; + if (size > resource_size(pr)) + return false; + if (resource_size(pr) - size < screen_info_lfb_offset) + return false; + + return true; +} + +void screen_info_apply_fixups(void) +{ + struct screen_info *si = &screen_info; + + if (screen_info_lfb_pdev) { + struct resource *pr = &screen_info_lfb_pdev->resource[screen_info_lfb_bar]; + + if (pr->start != screen_info_lfb_res.start) { + if (__screen_info_relocation_is_valid(si, pr)) { + /* + * Only update base if we have an actual + * relocation to a valid I/O range. + */ + __screen_info_set_lfb_base(si, pr->start + screen_info_lfb_offset); + pr_info("Relocating firmware framebuffer to offset %pa[d] within %pr\n", + &screen_info_lfb_offset, pr); + } else { + pr_warn("Invalid relocating, disabling firmware framebuffer\n"); + } + } + } +} + +static void screen_info_fixup_lfb(struct pci_dev *pdev) +{ + unsigned int type; + struct resource res[SCREEN_INFO_MAX_RESOURCES]; + size_t i, numres; + int ret; + const struct screen_info *si = &screen_info; + + if (screen_info_lfb_pdev) + return; // already found + + type = screen_info_video_type(si); + if (type != VIDEO_TYPE_EFI) + return; // only applies to EFI + + ret = screen_info_resources(si, res, ARRAY_SIZE(res)); + if (ret < 0) + return; + numres = ret; + + for (i = 0; i < numres; ++i) { + struct resource *r = &res[i]; + const struct resource *pr; + + if (!(r->flags & IORESOURCE_MEM)) + continue; + pr = pci_find_resource(pdev, r); + if (!pr) + continue; + + /* + * We've found a PCI device with the framebuffer + * resource. Store away the parameters to track + * relocation of the framebuffer aperture. + */ + screen_info_lfb_pdev = pdev; + screen_info_lfb_bar = pr - pdev->resource; + screen_info_lfb_offset = r->start - pr->start; + memcpy(&screen_info_lfb_res, r, sizeof(screen_info_lfb_res)); + } +} +DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY, 16, + screen_info_fixup_lfb); + +static struct pci_dev *__screen_info_pci_dev(struct resource *res) +{ + struct pci_dev *pdev = NULL; + const struct resource *r = NULL; + + if (!(res->flags & IORESOURCE_MEM)) + return NULL; + + while (!r && (pdev = pci_get_base_class(PCI_BASE_CLASS_DISPLAY, pdev))) { + r = pci_find_resource(pdev, res); + } + + return pdev; +} + +/** + * screen_info_pci_dev() - Return PCI parent device that contains screen_info's framebuffer + * @si: the screen_info + * + * Returns: + * The screen_info's parent device or NULL on success, or a pointer-encoded + * errno value otherwise. The value NULL is not an error. It signals that no + * PCI device has been found. + */ +struct pci_dev *screen_info_pci_dev(const struct screen_info *si) +{ + struct resource res[SCREEN_INFO_MAX_RESOURCES]; + ssize_t i, numres; + + numres = screen_info_resources(si, res, ARRAY_SIZE(res)); + if (numres < 0) + return ERR_PTR(numres); + + for (i = 0; i < numres; ++i) { + struct pci_dev *pdev = __screen_info_pci_dev(&res[i]); + + if (pdev) + return pdev; + } + + return NULL; +} +EXPORT_SYMBOL(screen_info_pci_dev); |