diff options
Diffstat (limited to 'drivers/video')
41 files changed, 493 insertions, 116 deletions
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 4e1d2ad50ba1..2919e2334052 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -150,6 +150,13 @@ config LCD_HX8357 If you have a HX-8357 LCD panel, say Y to enable its LCD control driver. + config LCD_OTM3225A + tristate "ORISE Technology OTM3225A support" + depends on SPI + help + If you have a panel based on the OTM3225A controller + chip then say y to include a driver for it. + endif # LCD_CLASS_DEVICE # @@ -467,6 +474,12 @@ config BACKLIGHT_ARCXCNN If you have an ARCxCnnnn family backlight say Y to enable the backlight driver. +config BACKLIGHT_RAVE_SP + tristate "RAVE SP Backlight driver" + depends on RAVE_SP_CORE + help + Support for backlight control on RAVE SP device. + endif # BACKLIGHT_CLASS_DEVICE endif # BACKLIGHT_LCD_SUPPORT diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 5e28f01c8391..0dcc2c745c03 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_LCD_LD9040) += ld9040.o obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o obj-$(CONFIG_LCD_LMS501KF03) += lms501kf03.o obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o +obj-$(CONFIG_LCD_OTM3225A) += otm3225a.o obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o obj-$(CONFIG_LCD_S6E63M0) += s6e63m0.o obj-$(CONFIG_LCD_TDO24M) += tdo24m.o @@ -57,3 +58,4 @@ obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o obj-$(CONFIG_BACKLIGHT_ARCXCNN) += arcxcnn_bl.o +obj-$(CONFIG_BACKLIGHT_RAVE_SP) += rave-sp-backlight.o diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c index e7315bf14d60..16119bde9750 100644 --- a/drivers/video/backlight/adp8860_bl.c +++ b/drivers/video/backlight/adp8860_bl.c @@ -223,7 +223,7 @@ static int adp8860_led_probe(struct i2c_client *client) struct led_info *cur_led; int ret, i; - led = devm_kzalloc(&client->dev, sizeof(*led) * pdata->num_leds, + led = devm_kcalloc(&client->dev, pdata->num_leds, sizeof(*led), GFP_KERNEL); if (led == NULL) return -ENOMEM; diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c index 058d1def2d1f..4fec9aa92d9b 100644 --- a/drivers/video/backlight/adp8870_bl.c +++ b/drivers/video/backlight/adp8870_bl.c @@ -246,7 +246,7 @@ static int adp8870_led_probe(struct i2c_client *client) struct led_info *cur_led; int ret, i; - led = devm_kzalloc(&client->dev, pdata->num_leds * sizeof(*led), + led = devm_kcalloc(&client->dev, pdata->num_leds, sizeof(*led), GFP_KERNEL); if (led == NULL) return -ENOMEM; diff --git a/drivers/video/backlight/as3711_bl.c b/drivers/video/backlight/as3711_bl.c index 734a9158946b..ca544aa764b8 100644 --- a/drivers/video/backlight/as3711_bl.c +++ b/drivers/video/backlight/as3711_bl.c @@ -28,8 +28,6 @@ enum as3711_bl_type { struct as3711_bl_data { bool powered; - const char *fb_name; - struct device *fb_dev; enum as3711_bl_type type; int brightness; struct backlight_device *bl; @@ -262,10 +260,10 @@ static int as3711_bl_register(struct platform_device *pdev, static int as3711_backlight_parse_dt(struct device *dev) { struct as3711_bl_pdata *pdata = dev_get_platdata(dev); - struct device_node *bl = - of_find_node_by_name(dev->parent->of_node, "backlight"), *fb; + struct device_node *bl, *fb; int ret; + bl = of_get_child_by_name(dev->parent->of_node, "backlight"); if (!bl) { dev_dbg(dev, "backlight node not found\n"); return -ENODEV; @@ -273,26 +271,30 @@ static int as3711_backlight_parse_dt(struct device *dev) fb = of_parse_phandle(bl, "su1-dev", 0); if (fb) { - pdata->su1_fb = fb->full_name; + of_node_put(fb); + + pdata->su1_fb = true; ret = of_property_read_u32(bl, "su1-max-uA", &pdata->su1_max_uA); if (pdata->su1_max_uA <= 0) ret = -EINVAL; if (ret < 0) - return ret; + goto err_put_bl; } fb = of_parse_phandle(bl, "su2-dev", 0); if (fb) { int count = 0; - pdata->su2_fb = fb->full_name; + of_node_put(fb); + + pdata->su2_fb = true; ret = of_property_read_u32(bl, "su2-max-uA", &pdata->su2_max_uA); if (pdata->su2_max_uA <= 0) ret = -EINVAL; if (ret < 0) - return ret; + goto err_put_bl; if (of_find_property(bl, "su2-feedback-voltage", NULL)) { pdata->su2_feedback = AS3711_SU2_VOLTAGE; @@ -314,8 +316,10 @@ static int as3711_backlight_parse_dt(struct device *dev) pdata->su2_feedback = AS3711_SU2_CURR_AUTO; count++; } - if (count != 1) - return -EINVAL; + if (count != 1) { + ret = -EINVAL; + goto err_put_bl; + } count = 0; if (of_find_property(bl, "su2-fbprot-lx-sd4", NULL)) { @@ -334,8 +338,10 @@ static int as3711_backlight_parse_dt(struct device *dev) pdata->su2_fbprot = AS3711_SU2_GPIO4; count++; } - if (count != 1) - return -EINVAL; + if (count != 1) { + ret = -EINVAL; + goto err_put_bl; + } count = 0; if (of_find_property(bl, "su2-auto-curr1", NULL)) { @@ -355,11 +361,20 @@ static int as3711_backlight_parse_dt(struct device *dev) * At least one su2-auto-curr* must be specified iff * AS3711_SU2_CURR_AUTO is used */ - if (!count ^ (pdata->su2_feedback != AS3711_SU2_CURR_AUTO)) - return -EINVAL; + if (!count ^ (pdata->su2_feedback != AS3711_SU2_CURR_AUTO)) { + ret = -EINVAL; + goto err_put_bl; + } } + of_node_put(bl); + return 0; + +err_put_bl: + of_node_put(bl); + + return ret; } static int as3711_backlight_probe(struct platform_device *pdev) @@ -412,7 +427,6 @@ static int as3711_backlight_probe(struct platform_device *pdev) if (pdata->su1_fb) { su = &supply->su1; - su->fb_name = pdata->su1_fb; su->type = AS3711_BL_SU1; max_brightness = min(pdata->su1_max_uA, 31); @@ -423,7 +437,6 @@ static int as3711_backlight_probe(struct platform_device *pdev) if (pdata->su2_fb) { su = &supply->su2; - su->fb_name = pdata->su2_fb; su->type = AS3711_BL_SU2; switch (pdata->su2_fbprot) { diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c index 67dfb939a514..4dea91acea13 100644 --- a/drivers/video/backlight/generic_bl.c +++ b/drivers/video/backlight/generic_bl.c @@ -21,9 +21,6 @@ static int genericbl_intensity; static struct backlight_device *generic_backlight_device; static struct generic_bl_info *bl_machinfo; -/* Flag to signal when the battery is low */ -#define GENERICBL_BATTLOW BL_CORE_DRIVER1 - static int genericbl_send_intensity(struct backlight_device *bd) { int intensity = bd->props.brightness; @@ -34,8 +31,6 @@ static int genericbl_send_intensity(struct backlight_device *bd) intensity = 0; if (bd->props.state & BL_CORE_SUSPENDED) intensity = 0; - if (bd->props.state & GENERICBL_BATTLOW) - intensity &= bl_machinfo->limit_mask; bl_machinfo->set_bl_intensity(intensity); diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c index 939f057836e1..73612485ed07 100644 --- a/drivers/video/backlight/lp855x_bl.c +++ b/drivers/video/backlight/lp855x_bl.c @@ -374,7 +374,7 @@ static int lp855x_parse_dt(struct lp855x *lp) struct device_node *child; int i = 0; - rom = devm_kzalloc(dev, sizeof(*rom) * rom_length, GFP_KERNEL); + rom = devm_kcalloc(dev, rom_length, sizeof(*rom), GFP_KERNEL); if (!rom) return -ENOMEM; diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c index 7b738d60ecc2..f3aa6088f1d9 100644 --- a/drivers/video/backlight/max8925_bl.c +++ b/drivers/video/backlight/max8925_bl.c @@ -116,7 +116,7 @@ static void max8925_backlight_dt_init(struct platform_device *pdev) if (!pdata) return; - np = of_find_node_by_name(nproot, "backlight"); + np = of_get_child_by_name(nproot, "backlight"); if (!np) { dev_err(&pdev->dev, "failed to find backlight node\n"); return; @@ -125,6 +125,8 @@ static void max8925_backlight_dt_init(struct platform_device *pdev) if (!of_property_read_u32(np, "maxim,max8925-dual-string", &val)) pdata->dual_string = val; + of_node_put(np); + pdev->dev.platform_data = pdata; } diff --git a/drivers/video/backlight/otm3225a.c b/drivers/video/backlight/otm3225a.c new file mode 100644 index 000000000000..2472e2167aae --- /dev/null +++ b/drivers/video/backlight/otm3225a.c @@ -0,0 +1,252 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Driver for ORISE Technology OTM3225A SOC for TFT LCD + * Copyright (C) 2017, EETS GmbH, Felix Brack <fb@ltec.ch> + * + * This driver implements a lcd device for the ORISE OTM3225A display + * controller. The control interface to the display is SPI and the display's + * memory is updated over the 16-bit RGB interface. + * The main source of information for writing this driver was provided by the + * OTM3225A datasheet from ORISE Technology. Some information arise from the + * ILI9328 datasheet from ILITEK as well as from the datasheets and sample code + * provided by Crystalfontz America Inc. who sells the CFAF240320A-032T, a 3.2" + * TFT LC display using the OTM3225A controller. + */ + +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/lcd.h> +#include <linux/module.h> +#include <linux/spi/spi.h> + +#define OTM3225A_INDEX_REG 0x70 +#define OTM3225A_DATA_REG 0x72 + +/* instruction register list */ +#define DRIVER_OUTPUT_CTRL_1 0x01 +#define DRIVER_WAVEFORM_CTRL 0x02 +#define ENTRY_MODE 0x03 +#define SCALING_CTRL 0x04 +#define DISPLAY_CTRL_1 0x07 +#define DISPLAY_CTRL_2 0x08 +#define DISPLAY_CTRL_3 0x09 +#define FRAME_CYCLE_CTRL 0x0A +#define EXT_DISP_IFACE_CTRL_1 0x0C +#define FRAME_MAKER_POS 0x0D +#define EXT_DISP_IFACE_CTRL_2 0x0F +#define POWER_CTRL_1 0x10 +#define POWER_CTRL_2 0x11 +#define POWER_CTRL_3 0x12 +#define POWER_CTRL_4 0x13 +#define GRAM_ADDR_HORIZ_SET 0x20 +#define GRAM_ADDR_VERT_SET 0x21 +#define GRAM_READ_WRITE 0x22 +#define POWER_CTRL_7 0x29 +#define FRAME_RATE_CTRL 0x2B +#define GAMMA_CTRL_1 0x30 +#define GAMMA_CTRL_2 0x31 +#define GAMMA_CTRL_3 0x32 +#define GAMMA_CTRL_4 0x35 +#define GAMMA_CTRL_5 0x36 +#define GAMMA_CTRL_6 0x37 +#define GAMMA_CTRL_7 0x38 +#define GAMMA_CTRL_8 0x39 +#define GAMMA_CTRL_9 0x3C +#define GAMMA_CTRL_10 0x3D +#define WINDOW_HORIZ_RAM_START 0x50 +#define WINDOW_HORIZ_RAM_END 0x51 +#define WINDOW_VERT_RAM_START 0x52 +#define WINDOW_VERT_RAM_END 0x53 +#define DRIVER_OUTPUT_CTRL_2 0x60 +#define BASE_IMG_DISPLAY_CTRL 0x61 +#define VERT_SCROLL_CTRL 0x6A +#define PD1_DISPLAY_POS 0x80 +#define PD1_RAM_START 0x81 +#define PD1_RAM_END 0x82 +#define PD2_DISPLAY_POS 0x83 +#define PD2_RAM_START 0x84 +#define PD2_RAM_END 0x85 +#define PANEL_IFACE_CTRL_1 0x90 +#define PANEL_IFACE_CTRL_2 0x92 +#define PANEL_IFACE_CTRL_4 0x95 +#define PANEL_IFACE_CTRL_5 0x97 + +struct otm3225a_data { + struct spi_device *spi; + struct lcd_device *ld; + int power; +}; + +struct otm3225a_spi_instruction { + unsigned char reg; /* register to write */ + unsigned short value; /* data to write to 'reg' */ + unsigned short delay; /* delay in ms after write */ +}; + +static struct otm3225a_spi_instruction display_init[] = { + { DRIVER_OUTPUT_CTRL_1, 0x0000, 0 }, + { DRIVER_WAVEFORM_CTRL, 0x0700, 0 }, + { ENTRY_MODE, 0x50A0, 0 }, + { SCALING_CTRL, 0x0000, 0 }, + { DISPLAY_CTRL_2, 0x0606, 0 }, + { DISPLAY_CTRL_3, 0x0000, 0 }, + { FRAME_CYCLE_CTRL, 0x0000, 0 }, + { EXT_DISP_IFACE_CTRL_1, 0x0000, 0 }, + { FRAME_MAKER_POS, 0x0000, 0 }, + { EXT_DISP_IFACE_CTRL_2, 0x0002, 0 }, + { POWER_CTRL_2, 0x0007, 0 }, + { POWER_CTRL_3, 0x0000, 0 }, + { POWER_CTRL_4, 0x0000, 200 }, + { DISPLAY_CTRL_1, 0x0101, 0 }, + { POWER_CTRL_1, 0x12B0, 0 }, + { POWER_CTRL_2, 0x0007, 0 }, + { POWER_CTRL_3, 0x01BB, 50 }, + { POWER_CTRL_4, 0x0013, 0 }, + { POWER_CTRL_7, 0x0010, 50 }, + { GAMMA_CTRL_1, 0x000A, 0 }, + { GAMMA_CTRL_2, 0x1326, 0 }, + { GAMMA_CTRL_3, 0x0A29, 0 }, + { GAMMA_CTRL_4, 0x0A0A, 0 }, + { GAMMA_CTRL_5, 0x1E03, 0 }, + { GAMMA_CTRL_6, 0x031E, 0 }, + { GAMMA_CTRL_7, 0x0706, 0 }, + { GAMMA_CTRL_8, 0x0303, 0 }, + { GAMMA_CTRL_9, 0x010E, 0 }, + { GAMMA_CTRL_10, 0x040E, 0 }, + { WINDOW_HORIZ_RAM_START, 0x0000, 0 }, + { WINDOW_HORIZ_RAM_END, 0x00EF, 0 }, + { WINDOW_VERT_RAM_START, 0x0000, 0 }, + { WINDOW_VERT_RAM_END, 0x013F, 0 }, + { DRIVER_OUTPUT_CTRL_2, 0x2700, 0 }, + { BASE_IMG_DISPLAY_CTRL, 0x0001, 0 }, + { VERT_SCROLL_CTRL, 0x0000, 0 }, + { PD1_DISPLAY_POS, 0x0000, 0 }, + { PD1_RAM_START, 0x0000, 0 }, + { PD1_RAM_END, 0x0000, 0 }, + { PD2_DISPLAY_POS, 0x0000, 0 }, + { PD2_RAM_START, 0x0000, 0 }, + { PD2_RAM_END, 0x0000, 0 }, + { PANEL_IFACE_CTRL_1, 0x0010, 0 }, + { PANEL_IFACE_CTRL_2, 0x0000, 0 }, + { PANEL_IFACE_CTRL_4, 0x0210, 0 }, + { PANEL_IFACE_CTRL_5, 0x0000, 0 }, + { DISPLAY_CTRL_1, 0x0133, 0 }, +}; + +static struct otm3225a_spi_instruction display_enable_rgb_interface[] = { + { ENTRY_MODE, 0x1080, 0 }, + { GRAM_ADDR_HORIZ_SET, 0x0000, 0 }, + { GRAM_ADDR_VERT_SET, 0x0000, 0 }, + { EXT_DISP_IFACE_CTRL_1, 0x0111, 500 }, +}; + +static struct otm3225a_spi_instruction display_off[] = { + { DISPLAY_CTRL_1, 0x0131, 100 }, + { DISPLAY_CTRL_1, 0x0130, 100 }, + { DISPLAY_CTRL_1, 0x0100, 0 }, + { POWER_CTRL_1, 0x0280, 0 }, + { POWER_CTRL_3, 0x018B, 0 }, +}; + +static struct otm3225a_spi_instruction display_on[] = { + { POWER_CTRL_1, 0x1280, 0 }, + { DISPLAY_CTRL_1, 0x0101, 100 }, + { DISPLAY_CTRL_1, 0x0121, 0 }, + { DISPLAY_CTRL_1, 0x0123, 100 }, + { DISPLAY_CTRL_1, 0x0133, 10 }, +}; + +static void otm3225a_write(struct spi_device *spi, + struct otm3225a_spi_instruction *instruction, + unsigned int count) +{ + unsigned char buf[3]; + + while (count--) { + /* address register using index register */ + buf[0] = OTM3225A_INDEX_REG; + buf[1] = 0x00; + buf[2] = instruction->reg; + spi_write(spi, buf, 3); + + /* write data to addressed register */ + buf[0] = OTM3225A_DATA_REG; + buf[1] = (instruction->value >> 8) & 0xff; + buf[2] = instruction->value & 0xff; + spi_write(spi, buf, 3); + + /* execute delay if any */ + if (instruction->delay) + msleep(instruction->delay); + instruction++; + } +} + +static int otm3225a_set_power(struct lcd_device *ld, int power) +{ + struct otm3225a_data *dd = lcd_get_data(ld); + + if (power == dd->power) + return 0; + + if (power > FB_BLANK_UNBLANK) + otm3225a_write(dd->spi, display_off, ARRAY_SIZE(display_off)); + else + otm3225a_write(dd->spi, display_on, ARRAY_SIZE(display_on)); + dd->power = power; + + return 0; +} + +static int otm3225a_get_power(struct lcd_device *ld) +{ + struct otm3225a_data *dd = lcd_get_data(ld); + + return dd->power; +} + +static struct lcd_ops otm3225a_ops = { + .set_power = otm3225a_set_power, + .get_power = otm3225a_get_power, +}; + +static int otm3225a_probe(struct spi_device *spi) +{ + struct otm3225a_data *dd; + struct lcd_device *ld; + struct device *dev = &spi->dev; + + dd = devm_kzalloc(dev, sizeof(struct otm3225a_data), GFP_KERNEL); + if (dd == NULL) + return -ENOMEM; + + ld = devm_lcd_device_register(dev, dev_name(dev), dev, dd, + &otm3225a_ops); + if (IS_ERR(ld)) + return PTR_ERR(ld); + + dd->spi = spi; + dd->ld = ld; + dev_set_drvdata(dev, dd); + + dev_info(dev, "Initializing and switching to RGB interface"); + otm3225a_write(spi, display_init, ARRAY_SIZE(display_init)); + otm3225a_write(spi, display_enable_rgb_interface, + ARRAY_SIZE(display_enable_rgb_interface)); + return 0; +} + +static struct spi_driver otm3225a_driver = { + .driver = { + .name = "otm3225a", + .owner = THIS_MODULE, + }, + .probe = otm3225a_probe, +}; + +module_spi_driver(otm3225a_driver); + +MODULE_AUTHOR("Felix Brack <fb@ltec.ch>"); +MODULE_DESCRIPTION("OTM3225A TFT LCD driver"); +MODULE_VERSION("1.0.0"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/video/backlight/pandora_bl.c b/drivers/video/backlight/pandora_bl.c index a186bc677c7d..9618766e3866 100644 --- a/drivers/video/backlight/pandora_bl.c +++ b/drivers/video/backlight/pandora_bl.c @@ -35,11 +35,15 @@ #define MAX_VALUE 63 #define MAX_USER_VALUE (MAX_VALUE - MIN_VALUE) -#define PANDORABL_WAS_OFF BL_CORE_DRIVER1 +struct pandora_private { + unsigned old_state; +#define PANDORABL_WAS_OFF 1 +}; static int pandora_backlight_update_status(struct backlight_device *bl) { int brightness = bl->props.brightness; + struct pandora_private *priv = bl_get_data(bl); u8 r; if (bl->props.power != FB_BLANK_UNBLANK) @@ -53,7 +57,7 @@ static int pandora_backlight_update_status(struct backlight_device *bl) brightness = MAX_USER_VALUE; if (brightness == 0) { - if (bl->props.state & PANDORABL_WAS_OFF) + if (priv->old_state == PANDORABL_WAS_OFF) goto done; /* first disable PWM0 output, then clock */ @@ -66,7 +70,7 @@ static int pandora_backlight_update_status(struct backlight_device *bl) goto done; } - if (bl->props.state & PANDORABL_WAS_OFF) { + if (priv->old_state == PANDORABL_WAS_OFF) { /* * set PWM duty cycle to max. TPS61161 seems to use this * to calibrate it's PWM sensitivity when it starts. @@ -93,9 +97,9 @@ static int pandora_backlight_update_status(struct backlight_device *bl) done: if (brightness != 0) - bl->props.state &= ~PANDORABL_WAS_OFF; + priv->old_state = 0; else - bl->props.state |= PANDORABL_WAS_OFF; + priv->old_state = PANDORABL_WAS_OFF; return 0; } @@ -109,13 +113,20 @@ static int pandora_backlight_probe(struct platform_device *pdev) { struct backlight_properties props; struct backlight_device *bl; + struct pandora_private *priv; u8 r; + priv = devm_kmalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) { + dev_err(&pdev->dev, "failed to allocate driver private data\n"); + return -ENOMEM; + } + memset(&props, 0, sizeof(props)); props.max_brightness = MAX_USER_VALUE; props.type = BACKLIGHT_RAW; bl = devm_backlight_device_register(&pdev->dev, pdev->name, &pdev->dev, - NULL, &pandora_backlight_ops, &props); + priv, &pandora_backlight_ops, &props); if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); return PTR_ERR(bl); @@ -126,7 +137,7 @@ static int pandora_backlight_probe(struct platform_device *pdev) /* 64 cycle period, ON position 0 */ twl_i2c_write_u8(TWL_MODULE_PWM, 0x80, TWL_PWM0_ON); - bl->props.state |= PANDORABL_WAS_OFF; + priv->old_state = PANDORABL_WAS_OFF; bl->props.brightness = MAX_USER_VALUE; backlight_update_status(bl); diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 1c2289ddd555..44ac5bde4e9d 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -10,6 +10,7 @@ * published by the Free Software Foundation. */ +#include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/gpio.h> #include <linux/module.h> @@ -35,6 +36,8 @@ struct pwm_bl_data { struct gpio_desc *enable_gpio; unsigned int scale; bool legacy; + unsigned int post_pwm_on_delay; + unsigned int pwm_off_delay; int (*notify)(struct device *, int brightness); void (*notify_after)(struct device *, @@ -54,10 +57,14 @@ static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness) if (err < 0) dev_err(pb->dev, "failed to enable power supply\n"); + pwm_enable(pb->pwm); + + if (pb->post_pwm_on_delay) + msleep(pb->post_pwm_on_delay); + if (pb->enable_gpio) gpiod_set_value_cansleep(pb->enable_gpio, 1); - pwm_enable(pb->pwm); pb->enabled = true; } @@ -66,12 +73,15 @@ static void pwm_backlight_power_off(struct pwm_bl_data *pb) if (!pb->enabled) return; - pwm_config(pb->pwm, 0, pb->period); - pwm_disable(pb->pwm); - if (pb->enable_gpio) gpiod_set_value_cansleep(pb->enable_gpio, 0); + if (pb->pwm_off_delay) + msleep(pb->pwm_off_delay); + + pwm_config(pb->pwm, 0, pb->period); + pwm_disable(pb->pwm); + regulator_disable(pb->power_supply); pb->enabled = false; } @@ -177,6 +187,14 @@ static int pwm_backlight_parse_dt(struct device *dev, data->max_brightness--; } + /* + * These values are optional and set as 0 by default, the out values + * are modified only if a valid u32 value can be decoded. + */ + of_property_read_u32(node, "post-pwm-on-delay-ms", + &data->post_pwm_on_delay); + of_property_read_u32(node, "pwm-off-delay-ms", &data->pwm_off_delay); + data->enable_gpio = -EINVAL; return 0; } @@ -275,6 +293,8 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->exit = data->exit; pb->dev = &pdev->dev; pb->enabled = false; + pb->post_pwm_on_delay = data->post_pwm_on_delay; + pb->pwm_off_delay = data->pwm_off_delay; pb->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable", GPIOD_ASIS); @@ -301,14 +321,14 @@ static int pwm_backlight_probe(struct platform_device *pdev) /* * If the GPIO is not known to be already configured as output, that - * is, if gpiod_get_direction returns either GPIOF_DIR_IN or -EINVAL, - * change the direction to output and set the GPIO as active. + * is, if gpiod_get_direction returns either 1 or -EINVAL, change the + * direction to output and set the GPIO as active. * Do not force the GPIO to active when it was already output as it * could cause backlight flickering or we would enable the backlight too * early. Leave the decision of the initial backlight state for later. */ if (pb->enable_gpio && - gpiod_get_direction(pb->enable_gpio) != GPIOF_DIR_OUT) + gpiod_get_direction(pb->enable_gpio) != 0) gpiod_direction_output(pb->enable_gpio, 1); pb->power_supply = devm_regulator_get(&pdev->dev, "power"); diff --git a/drivers/video/backlight/rave-sp-backlight.c b/drivers/video/backlight/rave-sp-backlight.c new file mode 100644 index 000000000000..462f14a1b19d --- /dev/null +++ b/drivers/video/backlight/rave-sp-backlight.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * LCD Backlight driver for RAVE SP + * + * Copyright (C) 2018 Zodiac Inflight Innovations + * + */ + +#include <linux/backlight.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/mfd/rave-sp.h> +#include <linux/platform_device.h> + +#define RAVE_SP_BACKLIGHT_LCD_EN BIT(7) + +static int rave_sp_backlight_update_status(struct backlight_device *bd) +{ + const struct backlight_properties *p = &bd->props; + const u8 intensity = + (p->power == FB_BLANK_UNBLANK) ? p->brightness : 0; + struct rave_sp *sp = dev_get_drvdata(&bd->dev); + u8 cmd[] = { + [0] = RAVE_SP_CMD_SET_BACKLIGHT, + [1] = 0, + [2] = intensity ? RAVE_SP_BACKLIGHT_LCD_EN | intensity : 0, + [3] = 0, + [4] = 0, + }; + + return rave_sp_exec(sp, cmd, sizeof(cmd), NULL, 0); +} + +static const struct backlight_ops rave_sp_backlight_ops = { + .options = BL_CORE_SUSPENDRESUME, + .update_status = rave_sp_backlight_update_status, +}; + +static struct backlight_properties rave_sp_backlight_props = { + .type = BACKLIGHT_PLATFORM, + .max_brightness = 100, + .brightness = 50, +}; + +static int rave_sp_backlight_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct backlight_device *bd; + + bd = devm_backlight_device_register(dev, pdev->name, dev->parent, + dev_get_drvdata(dev->parent), + &rave_sp_backlight_ops, + &rave_sp_backlight_props); + if (IS_ERR(bd)) + return PTR_ERR(bd); + + backlight_update_status(bd); + + return 0; +} + +static const struct of_device_id rave_sp_backlight_of_match[] = { + { .compatible = "zii,rave-sp-backlight" }, + {} +}; + +static struct platform_driver rave_sp_backlight_driver = { + .probe = rave_sp_backlight_probe, + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = rave_sp_backlight_of_match, + }, +}; +module_platform_driver(rave_sp_backlight_driver); + +MODULE_DEVICE_TABLE(of, rave_sp_backlight_of_match); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>"); +MODULE_AUTHOR("Nikita Yushchenko <nikita.yoush@cogentembedded.com>"); +MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>"); +MODULE_DESCRIPTION("RAVE SP Backlight driver"); diff --git a/drivers/video/backlight/tps65217_bl.c b/drivers/video/backlight/tps65217_bl.c index 380917c86276..762e3feed097 100644 --- a/drivers/video/backlight/tps65217_bl.c +++ b/drivers/video/backlight/tps65217_bl.c @@ -184,11 +184,11 @@ static struct tps65217_bl_pdata * tps65217_bl_parse_dt(struct platform_device *pdev) { struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); - struct device_node *node = of_node_get(tps->dev->of_node); + struct device_node *node; struct tps65217_bl_pdata *pdata, *err; u32 val; - node = of_find_node_by_name(node, "backlight"); + node = of_get_child_by_name(tps->dev->of_node, "backlight"); if (!node) return ERR_PTR(-ENODEV); diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 08b822656846..ff45dca3ee46 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -649,7 +649,7 @@ static void *sti_bmode_font_raw(struct sti_cooked_font *f) unsigned char *n, *p, *q; int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font); - n = kzalloc(4*size, STI_LOWMEM); + n = kcalloc(4, size, STI_LOWMEM); if (!n) return NULL; p = n + 3; diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c index 5e0491861439..0adf0683cf08 100644 --- a/drivers/video/fbdev/au1100fb.c +++ b/drivers/video/fbdev/au1100fb.c @@ -501,7 +501,7 @@ static int au1100fb_drv_probe(struct platform_device *dev) fbdev->info.fix = au1100fb_fix; fbdev->info.pseudo_palette = - devm_kzalloc(&dev->dev, sizeof(u32) * 16, GFP_KERNEL); + devm_kcalloc(&dev->dev, 16, sizeof(u32), GFP_KERNEL); if (!fbdev->info.pseudo_palette) return -ENOMEM; diff --git a/drivers/video/fbdev/broadsheetfb.c b/drivers/video/fbdev/broadsheetfb.c index 9f9a7bef1ff6..d6ba348deb9f 100644 --- a/drivers/video/fbdev/broadsheetfb.c +++ b/drivers/video/fbdev/broadsheetfb.c @@ -617,7 +617,7 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par, int tail_start_addr; int start_sector_addr; - sector_buffer = kzalloc(sizeof(char)*sector_size, GFP_KERNEL); + sector_buffer = kzalloc(sector_size, GFP_KERNEL); if (!sector_buffer) return -ENOMEM; diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c index 790900d646c0..ca935c09a261 100644 --- a/drivers/video/fbdev/core/bitblit.c +++ b/drivers/video/fbdev/core/bitblit.c @@ -269,7 +269,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, if (attribute) { u8 *dst; - dst = kmalloc(w * vc->vc_font.height, GFP_ATOMIC); + dst = kmalloc_array(w, vc->vc_font.height, GFP_ATOMIC); if (!dst) return; kfree(ops->cursor_data); @@ -312,7 +312,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, vc->vc_cursor_type != ops->p->cursor_shape || ops->cursor_state.mask == NULL || ops->cursor_reset) { - char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC); + char *mask = kmalloc_array(w, vc->vc_font.height, GFP_ATOMIC); int cur_height, size, i = 0; u8 msk = 0xff; diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 3e330e0f56ed..c910e74d46ff 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -591,7 +591,8 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, if (scr_readw(r) != vc->vc_video_erase_char) break; if (r != q && new_rows >= rows + logo_lines) { - save = kmalloc(logo_lines * new_cols * 2, GFP_KERNEL); + save = kmalloc(array3_size(logo_lines, new_cols, 2), + GFP_KERNEL); if (save) { int i = cols < new_cols ? cols : new_cols; scr_memsetw(save, erase, logo_lines * new_cols * 2); diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c index 37a8b0b22566..dfa9a8aa4509 100644 --- a/drivers/video/fbdev/core/fbcon_ccw.c +++ b/drivers/video/fbdev/core/fbcon_ccw.c @@ -258,7 +258,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode, if (attribute) { u8 *dst; - dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC); + dst = kmalloc_array(w, vc->vc_font.width, GFP_ATOMIC); if (!dst) return; kfree(ops->cursor_data); @@ -304,14 +304,15 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode, vc->vc_cursor_type != ops->p->cursor_shape || ops->cursor_state.mask == NULL || ops->cursor_reset) { - char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC); + char *tmp, *mask = kmalloc_array(w, vc->vc_font.width, + GFP_ATOMIC); int cur_height, size, i = 0; int width = (vc->vc_font.width + 7)/8; if (!mask) return; - tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC); + tmp = kmalloc_array(width, vc->vc_font.height, GFP_ATOMIC); if (!tmp) { kfree(mask); diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c index 1888f8c866e8..ce08251bfd38 100644 --- a/drivers/video/fbdev/core/fbcon_cw.c +++ b/drivers/video/fbdev/core/fbcon_cw.c @@ -241,7 +241,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode, if (attribute) { u8 *dst; - dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC); + dst = kmalloc_array(w, vc->vc_font.width, GFP_ATOMIC); if (!dst) return; kfree(ops->cursor_data); @@ -287,14 +287,15 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode, vc->vc_cursor_type != ops->p->cursor_shape || ops->cursor_state.mask == NULL || ops->cursor_reset) { - char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC); + char *tmp, *mask = kmalloc_array(w, vc->vc_font.width, + GFP_ATOMIC); int cur_height, size, i = 0; int width = (vc->vc_font.width + 7)/8; if (!mask) return; - tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC); + tmp = kmalloc_array(width, vc->vc_font.height, GFP_ATOMIC); if (!tmp) { kfree(mask); diff --git a/drivers/video/fbdev/core/fbcon_rotate.c b/drivers/video/fbdev/core/fbcon_rotate.c index 8a51e4d95cc5..c0d445294aa7 100644 --- a/drivers/video/fbdev/core/fbcon_rotate.c +++ b/drivers/video/fbdev/core/fbcon_rotate.c @@ -46,7 +46,7 @@ static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc) info->fbops->fb_sync(info); if (ops->fd_size < d_cellsize * len) { - dst = kmalloc(d_cellsize * len, GFP_KERNEL); + dst = kmalloc_array(len, d_cellsize, GFP_KERNEL); if (dst == NULL) { err = -ENOMEM; diff --git a/drivers/video/fbdev/core/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c index f98eee263597..1936afc78fec 100644 --- a/drivers/video/fbdev/core/fbcon_ud.c +++ b/drivers/video/fbdev/core/fbcon_ud.c @@ -289,7 +289,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode, if (attribute) { u8 *dst; - dst = kmalloc(w * vc->vc_font.height, GFP_ATOMIC); + dst = kmalloc_array(w, vc->vc_font.height, GFP_ATOMIC); if (!dst) return; kfree(ops->cursor_data); @@ -335,7 +335,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode, vc->vc_cursor_type != ops->p->cursor_shape || ops->cursor_state.mask == NULL || ops->cursor_reset) { - char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC); + char *mask = kmalloc_array(w, vc->vc_font.height, GFP_ATOMIC); int cur_height, size, i = 0; u8 msk = 0xff; diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index f741ba8df01b..609438d2465b 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -489,7 +489,8 @@ static int fb_show_logo_line(struct fb_info *info, int rotate, } if (fb_logo.depth <= 4) { - logo_new = kmalloc(logo->width * logo->height, GFP_KERNEL); + logo_new = kmalloc_array(logo->width, logo->height, + GFP_KERNEL); if (logo_new == NULL) { kfree(palette); if (saved_pseudo_palette) @@ -506,8 +507,8 @@ static int fb_show_logo_line(struct fb_info *info, int rotate, image.height = logo->height; if (rotate) { - logo_rotate = kmalloc(logo->width * - logo->height, GFP_KERNEL); + logo_rotate = kmalloc_array(logo->width, logo->height, + GFP_KERNEL); if (logo_rotate) fb_rotate_logo(info, logo_rotate, &image, rotate); } @@ -713,19 +714,6 @@ static const struct seq_operations proc_fb_seq_ops = { .show = fb_seq_show, }; -static int proc_fb_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &proc_fb_seq_ops); -} - -static const struct file_operations fb_proc_fops = { - .owner = THIS_MODULE, - .open = proc_fb_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - /* * We hold a reference to the fb_info in file->private_data, * but if the current registered fb has changed, we don't @@ -1877,7 +1865,7 @@ fbmem_init(void) { int ret; - if (!proc_create("fb", 0, NULL, &fb_proc_fops)) + if (!proc_create_seq("fb", 0, NULL, &proc_fb_seq_ops)) return -ENOMEM; ret = register_chrdev(FB_MAJOR, "fb", &fb_fops); diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c index 2b2d67328514..852d86c1c527 100644 --- a/drivers/video/fbdev/core/fbmon.c +++ b/drivers/video/fbdev/core/fbmon.c @@ -620,7 +620,7 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize, int num = 0, i, first = 1; int ver, rev; - mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL); + mode = kcalloc(50, sizeof(struct fb_videomode), GFP_KERNEL); if (mode == NULL) return NULL; @@ -671,7 +671,7 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize, } *dbsize = num; - m = kmalloc(num * sizeof(struct fb_videomode), GFP_KERNEL); + m = kmalloc_array(num, sizeof(struct fb_videomode), GFP_KERNEL); if (!m) return mode; memmove(m, mode, num * sizeof(struct fb_videomode)); @@ -1055,8 +1055,9 @@ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs) if (!(num + svd_n)) return; - m = kzalloc((specs->modedb_len + num + svd_n) * - sizeof(struct fb_videomode), GFP_KERNEL); + m = kcalloc(specs->modedb_len + num + svd_n, + sizeof(struct fb_videomode), + GFP_KERNEL); if (!m) return; diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c index ba82f97fb42b..c4eb8661f751 100644 --- a/drivers/video/fbdev/imxfb.c +++ b/drivers/video/fbdev/imxfb.c @@ -662,7 +662,7 @@ static int imxfb_init_fbinfo(struct platform_device *pdev) pr_debug("%s\n",__func__); - info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); + info->pseudo_palette = kmalloc_array(16, sizeof(u32), GFP_KERNEL); if (!info->pseudo_palette) return -ENOMEM; diff --git a/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c index fe92eed6da70..8dd296d257dd 100644 --- a/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c +++ b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c @@ -245,7 +245,7 @@ static void mb86290fb_imageblit(struct fb_info *info, return; } - cmd = kmalloc(cmdlen * 4, GFP_DMA); + cmd = kmalloc_array(cmdlen, 4, GFP_DMA); if (!cmd) return cfb_imageblit(info, image); cmdfn(cmd, step, dx, dy, width, height, fgcolor, bgcolor, image, info); diff --git a/drivers/video/fbdev/mmp/fb/mmpfb.c b/drivers/video/fbdev/mmp/fb/mmpfb.c index 292b3e403044..ee212be67dc6 100644 --- a/drivers/video/fbdev/mmp/fb/mmpfb.c +++ b/drivers/video/fbdev/mmp/fb/mmpfb.c @@ -493,8 +493,8 @@ static int modes_setup(struct mmpfb_info *fbi) return 0; } /* put videomode list to info structure */ - videomodes = kzalloc(sizeof(struct fb_videomode) * videomode_num, - GFP_KERNEL); + videomodes = kcalloc(videomode_num, sizeof(struct fb_videomode), + GFP_KERNEL); if (!videomodes) return -ENOMEM; diff --git a/drivers/video/fbdev/mxsfb.c b/drivers/video/fbdev/mxsfb.c index 246bea3a7d9b..12c8bd1d24d5 100644 --- a/drivers/video/fbdev/mxsfb.c +++ b/drivers/video/fbdev/mxsfb.c @@ -931,7 +931,7 @@ static int mxsfb_probe(struct platform_device *pdev) if (IS_ERR(host->reg_lcd)) host->reg_lcd = NULL; - fb_info->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16, + fb_info->pseudo_palette = devm_kcalloc(&pdev->dev, 16, sizeof(u32), GFP_KERNEL); if (!fb_info->pseudo_palette) { ret = -ENOMEM; diff --git a/drivers/video/fbdev/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c index 34521f52aa3b..fbeeed5afe35 100644 --- a/drivers/video/fbdev/nvidia/nvidia.c +++ b/drivers/video/fbdev/nvidia/nvidia.c @@ -566,7 +566,7 @@ static int nvidiafb_cursor(struct fb_info *info, struct fb_cursor *cursor) u8 *msk = (u8 *) cursor->mask; u8 *src; - src = kmalloc(s_pitch * cursor->image.height, GFP_ATOMIC); + src = kmalloc_array(s_pitch, cursor->image.height, GFP_ATOMIC); if (src) { switch (cursor->rop) { diff --git a/drivers/video/fbdev/omap2/Kconfig b/drivers/video/fbdev/omap2/Kconfig index 0921c4de8407..4de381f2452e 100644 --- a/drivers/video/fbdev/omap2/Kconfig +++ b/drivers/video/fbdev/omap2/Kconfig @@ -1,4 +1,4 @@ -if ARCH_OMAP2PLUS +if OF && (ARCH_OMAP2PLUS || COMPILE_TEST) source "drivers/video/fbdev/omap2/omapfb/Kconfig" diff --git a/drivers/video/fbdev/omap2/omapfb/dss/manager.c b/drivers/video/fbdev/omap2/omapfb/dss/manager.c index 69f86d2cc274..d21c641e1f3c 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/manager.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/manager.c @@ -42,8 +42,8 @@ int dss_init_overlay_managers(void) num_managers = dss_feat_get_num_mgrs(); - managers = kzalloc(sizeof(struct omap_overlay_manager) * num_managers, - GFP_KERNEL); + managers = kcalloc(num_managers, sizeof(struct omap_overlay_manager), + GFP_KERNEL); BUG_ON(managers == NULL); diff --git a/drivers/video/fbdev/omap2/omapfb/dss/overlay.c b/drivers/video/fbdev/omap2/omapfb/dss/overlay.c index d6c5d75d2ef8..be17a4785a5e 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/overlay.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/overlay.c @@ -59,8 +59,8 @@ void dss_init_overlays(struct platform_device *pdev) num_overlays = dss_feat_get_num_ovls(); - overlays = kzalloc(sizeof(struct omap_overlay) * num_overlays, - GFP_KERNEL); + overlays = kcalloc(num_overlays, sizeof(struct omap_overlay), + GFP_KERNEL); BUG_ON(overlays == NULL); diff --git a/drivers/video/fbdev/omap2/omapfb/vrfb.c b/drivers/video/fbdev/omap2/omapfb/vrfb.c index f346b02eee1d..f355ecfac3b1 100644 --- a/drivers/video/fbdev/omap2/omapfb/vrfb.c +++ b/drivers/video/fbdev/omap2/omapfb/vrfb.c @@ -359,8 +359,8 @@ static int __init vrfb_probe(struct platform_device *pdev) num_ctxs = pdev->num_resources - 1; - ctxs = devm_kzalloc(&pdev->dev, - sizeof(struct vrfb_ctx) * num_ctxs, + ctxs = devm_kcalloc(&pdev->dev, + num_ctxs, sizeof(struct vrfb_ctx), GFP_KERNEL); if (!ctxs) diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c index a582d3ae7ac1..8a53d1de611d 100644 --- a/drivers/video/fbdev/pvr2fb.c +++ b/drivers/video/fbdev/pvr2fb.c @@ -682,7 +682,7 @@ static ssize_t pvr2fb_write(struct fb_info *info, const char *buf, nr_pages = (count + PAGE_SIZE - 1) >> PAGE_SHIFT; - pages = kmalloc(nr_pages * sizeof(struct page *), GFP_KERNEL); + pages = kmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL); if (!pages) return -ENOMEM; diff --git a/drivers/video/fbdev/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c index ff8282374f37..cc242ba057d3 100644 --- a/drivers/video/fbdev/riva/fbdev.c +++ b/drivers/video/fbdev/riva/fbdev.c @@ -1615,7 +1615,7 @@ static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor) u8 *msk = (u8 *) cursor->mask; u8 *src; - src = kmalloc(s_pitch * cursor->image.height, GFP_ATOMIC); + src = kmalloc_array(s_pitch, cursor->image.height, GFP_ATOMIC); if (src) { switch (cursor->rop) { diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c index 73676eb0244a..440a6636d8f0 100644 --- a/drivers/video/fbdev/uvesafb.c +++ b/drivers/video/fbdev/uvesafb.c @@ -486,8 +486,9 @@ static int uvesafb_vbe_getmodes(struct uvesafb_ktask *task, mode++; } - par->vbe_modes = kzalloc(sizeof(struct vbe_mode_ib) * - par->vbe_modes_cnt, GFP_KERNEL); + par->vbe_modes = kcalloc(par->vbe_modes_cnt, + sizeof(struct vbe_mode_ib), + GFP_KERNEL); if (!par->vbe_modes) return -ENOMEM; @@ -858,7 +859,7 @@ static int uvesafb_vbe_init_mode(struct fb_info *info) * Convert the modelist into a modedb so that we can use it with * fb_find_mode(). */ - mode = kzalloc(i * sizeof(*mode), GFP_KERNEL); + mode = kcalloc(i, sizeof(*mode), GFP_KERNEL); if (mode) { i = 0; list_for_each(pos, &info->modelist) { @@ -1044,7 +1045,8 @@ static int uvesafb_setcmap(struct fb_cmap *cmap, struct fb_info *info) info->cmap.len || cmap->start < info->cmap.start) return -EINVAL; - entries = kmalloc(sizeof(*entries) * cmap->len, GFP_KERNEL); + entries = kmalloc_array(cmap->len, sizeof(*entries), + GFP_KERNEL); if (!entries) return -ENOMEM; diff --git a/drivers/video/fbdev/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c index 35e46800cc0a..d2f785068ef4 100644 --- a/drivers/video/fbdev/via/viafbdev.c +++ b/drivers/video/fbdev/via/viafbdev.c @@ -595,7 +595,8 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) break; case VIAFB_GET_GAMMA_LUT: - viafb_gamma_table = kmalloc(256 * sizeof(u32), GFP_KERNEL); + viafb_gamma_table = kmalloc_array(256, sizeof(u32), + GFP_KERNEL); if (!viafb_gamma_table) return -ENOMEM; viafb_get_gamma_table(viafb_gamma_table); @@ -1474,19 +1475,6 @@ static int viafb_sup_odev_proc_show(struct seq_file *m, void *v) return 0; } -static int viafb_sup_odev_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, viafb_sup_odev_proc_show, NULL); -} - -static const struct file_operations viafb_sup_odev_proc_fops = { - .owner = THIS_MODULE, - .open = viafb_sup_odev_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - static ssize_t odev_update(const char __user *buffer, size_t count, u32 *odev) { char buf[64], *ptr = buf; @@ -1615,8 +1603,8 @@ static void viafb_init_proc(struct viafb_shared *shared) &viafb_vt1636_proc_fops); #endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ - proc_create("supported_output_devices", 0, viafb_entry, - &viafb_sup_odev_proc_fops); + proc_create_single("supported_output_devices", 0, viafb_entry, + viafb_sup_odev_proc_show); iga1_entry = proc_mkdir("iga1", viafb_entry); shared->iga1_proc_entry = iga1_entry; proc_create("output_devices", 0, iga1_entry, diff --git a/drivers/video/fbdev/w100fb.c b/drivers/video/fbdev/w100fb.c index 035ff6e02894..696106ecdff0 100644 --- a/drivers/video/fbdev/w100fb.c +++ b/drivers/video/fbdev/w100fb.c @@ -693,7 +693,8 @@ int w100fb_probe(struct platform_device *pdev) goto out; } - info->pseudo_palette = kmalloc(sizeof (u32) * MAX_PALETTES, GFP_KERNEL); + info->pseudo_palette = kmalloc_array(MAX_PALETTES, sizeof(u32), + GFP_KERNEL); if (!info->pseudo_palette) { err = -ENOMEM; goto out; diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c index 46f63960fa9e..6a4bbc9e1fb0 100644 --- a/drivers/video/fbdev/xen-fbfront.c +++ b/drivers/video/fbdev/xen-fbfront.c @@ -412,7 +412,7 @@ static int xenfb_probe(struct xenbus_device *dev, info->nr_pages = (fb_size + PAGE_SIZE - 1) >> PAGE_SHIFT; - info->gfns = vmalloc(sizeof(unsigned long) * info->nr_pages); + info->gfns = vmalloc(array_size(sizeof(unsigned long), info->nr_pages)); if (!info->gfns) goto error_nomem; diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c index 111a0ab6280a..38716eb50408 100644 --- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c @@ -93,6 +93,9 @@ ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer, if (size < length) return -ENOSPC; + if (frame->picture_aspect > HDMI_PICTURE_ASPECT_16_9) + return -EINVAL; + memset(buffer, 0, size); ptr[0] = frame->type; diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c index 83b8963c9657..5244e93ceafc 100644 --- a/drivers/video/of_display_timing.c +++ b/drivers/video/of_display_timing.c @@ -181,8 +181,9 @@ struct display_timings *of_get_display_timings(const struct device_node *np) goto entryfail; } - disp->timings = kzalloc(sizeof(struct display_timing *) * - disp->num_timings, GFP_KERNEL); + disp->timings = kcalloc(disp->num_timings, + sizeof(struct display_timing *), + GFP_KERNEL); if (!disp->timings) { pr_err("%pOF: could not allocate timings array\n", np); goto entryfail; |