* [PATCHv2 13/15] backlight: atmel-pwm-bl: remove obsolete driver
From: Alexandre Belloni @ 2014-05-28 23:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1401319218-16772-1-git-send-email-alexandre.belloni@free-electrons.com>
The atmel-pwm-bl driver is now obsolete. It is not used by any mainlined boards
and is replaced by the generic pwm_bl with the pawm-atmel driver using the
generic PWM framework.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no>
Acked-by: Jingoo Han <jg1.han@samsung.com>
---
drivers/video/backlight/Kconfig | 11 --
drivers/video/backlight/Makefile | 1 -
drivers/video/backlight/atmel-pwm-bl.c | 223 ---------------------------------
include/linux/atmel-pwm-bl.h | 43 -------
4 files changed, 278 deletions(-)
delete mode 100644 drivers/video/backlight/atmel-pwm-bl.c
delete mode 100644 include/linux/atmel-pwm-bl.h
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 5a3eb2ecb525..9bd32b7a7561 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -178,17 +178,6 @@ config BACKLIGHT_ATMEL_LCDC
If in doubt, it's safe to enable this option; it doesn't kick
in unless the board's description says it's wired that way.
-config BACKLIGHT_ATMEL_PWM
- tristate "Atmel PWM backlight control"
- depends on ATMEL_PWM
- help
- Say Y here if you want to use the PWM peripheral in Atmel AT91 and
- AVR32 devices. This driver will need additional platform data to know
- which PWM instance to use and how to configure it.
-
- To compile this driver as a module, choose M here: the module will be
- called atmel-pwm-bl.
-
config BACKLIGHT_EP93XX
tristate "Cirrus EP93xx Backlight Driver"
depends on FB_EP93XX
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index bb820024f346..351451dbb607 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -25,7 +25,6 @@ obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o
obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o
obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o
obj-$(CONFIG_BACKLIGHT_AS3711) += as3711_bl.o
-obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o
obj-$(CONFIG_BACKLIGHT_BD6107) += bd6107.o
obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
deleted file mode 100644
index 261b1a4ec3d8..000000000000
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2008 Atmel Corporation
- *
- * Backlight driver using Atmel PWM peripheral.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/fb.h>
-#include <linux/gpio.h>
-#include <linux/backlight.h>
-#include <linux/atmel_pwm.h>
-#include <linux/atmel-pwm-bl.h>
-#include <linux/slab.h>
-
-struct atmel_pwm_bl {
- const struct atmel_pwm_bl_platform_data *pdata;
- struct backlight_device *bldev;
- struct platform_device *pdev;
- struct pwm_channel pwmc;
- int gpio_on;
-};
-
-static void atmel_pwm_bl_set_gpio_on(struct atmel_pwm_bl *pwmbl, int on)
-{
- if (!gpio_is_valid(pwmbl->gpio_on))
- return;
-
- gpio_set_value(pwmbl->gpio_on, on ^ pwmbl->pdata->on_active_low);
-}
-
-static int atmel_pwm_bl_set_intensity(struct backlight_device *bd)
-{
- struct atmel_pwm_bl *pwmbl = bl_get_data(bd);
- int intensity = bd->props.brightness;
- int pwm_duty;
-
- if (bd->props.power != FB_BLANK_UNBLANK)
- intensity = 0;
- if (bd->props.fb_blank != FB_BLANK_UNBLANK)
- intensity = 0;
-
- if (pwmbl->pdata->pwm_active_low)
- pwm_duty = pwmbl->pdata->pwm_duty_min + intensity;
- else
- pwm_duty = pwmbl->pdata->pwm_duty_max - intensity;
-
- if (pwm_duty > pwmbl->pdata->pwm_duty_max)
- pwm_duty = pwmbl->pdata->pwm_duty_max;
- if (pwm_duty < pwmbl->pdata->pwm_duty_min)
- pwm_duty = pwmbl->pdata->pwm_duty_min;
-
- if (!intensity) {
- atmel_pwm_bl_set_gpio_on(pwmbl, 0);
- pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty);
- pwm_channel_disable(&pwmbl->pwmc);
- } else {
- pwm_channel_enable(&pwmbl->pwmc);
- pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty);
- atmel_pwm_bl_set_gpio_on(pwmbl, 1);
- }
-
- return 0;
-}
-
-static int atmel_pwm_bl_get_intensity(struct backlight_device *bd)
-{
- struct atmel_pwm_bl *pwmbl = bl_get_data(bd);
- u32 cdty;
- u32 intensity;
-
- cdty = pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY);
- if (pwmbl->pdata->pwm_active_low)
- intensity = cdty - pwmbl->pdata->pwm_duty_min;
- else
- intensity = pwmbl->pdata->pwm_duty_max - cdty;
-
- return intensity & 0xffff;
-}
-
-static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl)
-{
- unsigned long pwm_rate = pwmbl->pwmc.mck;
- unsigned long prescale = DIV_ROUND_UP(pwm_rate,
- (pwmbl->pdata->pwm_frequency *
- pwmbl->pdata->pwm_compare_max)) - 1;
-
- /*
- * Prescale must be power of two and maximum 0xf in size because of
- * hardware limit. PWM speed will be:
- * PWM module clock speed / (2 ^ prescale).
- */
- prescale = fls(prescale);
- if (prescale > 0xf)
- prescale = 0xf;
-
- pwm_channel_writel(&pwmbl->pwmc, PWM_CMR, prescale);
- pwm_channel_writel(&pwmbl->pwmc, PWM_CDTY,
- pwmbl->pdata->pwm_duty_min +
- pwmbl->bldev->props.brightness);
- pwm_channel_writel(&pwmbl->pwmc, PWM_CPRD,
- pwmbl->pdata->pwm_compare_max);
-
- dev_info(&pwmbl->pdev->dev, "Atmel PWM backlight driver (%lu Hz)\n",
- pwmbl->pwmc.mck / pwmbl->pdata->pwm_compare_max /
- (1 << prescale));
-
- return pwm_channel_enable(&pwmbl->pwmc);
-}
-
-static const struct backlight_ops atmel_pwm_bl_ops = {
- .get_brightness = atmel_pwm_bl_get_intensity,
- .update_status = atmel_pwm_bl_set_intensity,
-};
-
-static int atmel_pwm_bl_probe(struct platform_device *pdev)
-{
- struct backlight_properties props;
- const struct atmel_pwm_bl_platform_data *pdata;
- struct backlight_device *bldev;
- struct atmel_pwm_bl *pwmbl;
- unsigned long flags;
- int retval;
-
- pdata = dev_get_platdata(&pdev->dev);
- if (!pdata)
- return -ENODEV;
-
- if (pdata->pwm_compare_max < pdata->pwm_duty_max ||
- pdata->pwm_duty_min > pdata->pwm_duty_max ||
- pdata->pwm_frequency = 0)
- return -EINVAL;
-
- pwmbl = devm_kzalloc(&pdev->dev, sizeof(struct atmel_pwm_bl),
- GFP_KERNEL);
- if (!pwmbl)
- return -ENOMEM;
-
- pwmbl->pdev = pdev;
- pwmbl->pdata = pdata;
- pwmbl->gpio_on = pdata->gpio_on;
-
- retval = pwm_channel_alloc(pdata->pwm_channel, &pwmbl->pwmc);
- if (retval)
- return retval;
-
- if (gpio_is_valid(pwmbl->gpio_on)) {
- /* Turn display off by default. */
- if (pdata->on_active_low)
- flags = GPIOF_OUT_INIT_HIGH;
- else
- flags = GPIOF_OUT_INIT_LOW;
-
- retval = devm_gpio_request_one(&pdev->dev, pwmbl->gpio_on,
- flags, "gpio_atmel_pwm_bl");
- if (retval)
- goto err_free_pwm;
- }
-
- memset(&props, 0, sizeof(struct backlight_properties));
- props.type = BACKLIGHT_RAW;
- props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min;
- bldev = devm_backlight_device_register(&pdev->dev, "atmel-pwm-bl",
- &pdev->dev, pwmbl, &atmel_pwm_bl_ops,
- &props);
- if (IS_ERR(bldev)) {
- retval = PTR_ERR(bldev);
- goto err_free_pwm;
- }
-
- pwmbl->bldev = bldev;
-
- platform_set_drvdata(pdev, pwmbl);
-
- /* Power up the backlight by default at middle intesity. */
- bldev->props.power = FB_BLANK_UNBLANK;
- bldev->props.brightness = bldev->props.max_brightness / 2;
-
- retval = atmel_pwm_bl_init_pwm(pwmbl);
- if (retval)
- goto err_free_pwm;
-
- atmel_pwm_bl_set_intensity(bldev);
-
- return 0;
-
-err_free_pwm:
- pwm_channel_free(&pwmbl->pwmc);
-
- return retval;
-}
-
-static int atmel_pwm_bl_remove(struct platform_device *pdev)
-{
- struct atmel_pwm_bl *pwmbl = platform_get_drvdata(pdev);
-
- atmel_pwm_bl_set_gpio_on(pwmbl, 0);
- pwm_channel_disable(&pwmbl->pwmc);
- pwm_channel_free(&pwmbl->pwmc);
-
- return 0;
-}
-
-static struct platform_driver atmel_pwm_bl_driver = {
- .driver = {
- .name = "atmel-pwm-bl",
- },
- /* REVISIT add suspend() and resume() */
- .probe = atmel_pwm_bl_probe,
- .remove = atmel_pwm_bl_remove,
-};
-
-module_platform_driver(atmel_pwm_bl_driver);
-
-MODULE_AUTHOR("Hans-Christian egtvedt <hans-christian.egtvedt@atmel.com>");
-MODULE_DESCRIPTION("Atmel PWM backlight driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:atmel-pwm-bl");
diff --git a/include/linux/atmel-pwm-bl.h b/include/linux/atmel-pwm-bl.h
deleted file mode 100644
index 0153a47806c2..000000000000
--- a/include/linux/atmel-pwm-bl.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2007 Atmel Corporation
- *
- * Driver for the AT32AP700X PS/2 controller (PSIF).
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#ifndef __INCLUDE_ATMEL_PWM_BL_H
-#define __INCLUDE_ATMEL_PWM_BL_H
-
-/**
- * struct atmel_pwm_bl_platform_data
- * @pwm_channel: which PWM channel in the PWM module to use.
- * @pwm_frequency: PWM frequency to generate, the driver will try to be as
- * close as the prescaler allows.
- * @pwm_compare_max: value to use in the PWM channel compare register.
- * @pwm_duty_max: maximum duty cycle value, must be less than or equal to
- * pwm_compare_max.
- * @pwm_duty_min: minimum duty cycle value, must be less than pwm_duty_max.
- * @pwm_active_low: set to one if the low part of the PWM signal increases the
- * brightness of the backlight.
- * @gpio_on: GPIO line to control the backlight on/off, set to -1 if not used.
- * @on_active_low: set to one if the on/off signal is on when GPIO is low.
- *
- * This struct must be added to the platform device in the board code. It is
- * used by the atmel-pwm-bl driver to setup the GPIO to control on/off and the
- * PWM device.
- */
-struct atmel_pwm_bl_platform_data {
- unsigned int pwm_channel;
- unsigned int pwm_frequency;
- unsigned int pwm_compare_max;
- unsigned int pwm_duty_max;
- unsigned int pwm_duty_min;
- unsigned int pwm_active_low;
- int gpio_on;
- unsigned int on_active_low;
-};
-
-#endif /* __INCLUDE_ATMEL_PWM_BL_H */
--
1.9.1
^ permalink raw reply related
* [PATCHv2 14/15] leds: atmel-pwm: remove obsolete driver
From: Alexandre Belloni @ 2014-05-28 23:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1401319218-16772-1-git-send-email-alexandre.belloni@free-electrons.com>
The leds-atmel-pwm driver is now obsolete. It is not used by any mainlined
boards and is replaced by the generic leds_pwm with the pwm-atmel driver using
the generic PWM framework.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Bryan Wu <cooloney@gmail.com>
---
drivers/leds/Kconfig | 8 ---
drivers/leds/Makefile | 1 -
drivers/leds/leds-atmel-pwm.c | 149 ------------------------------------------
3 files changed, 158 deletions(-)
delete mode 100644 drivers/leds/leds-atmel-pwm.c
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 6784c177eed1..27cf0cdcdaab 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -29,14 +29,6 @@ config LEDS_88PM860X
This option enables support for on-chip LED drivers found on Marvell
Semiconductor 88PM8606 PMIC.
-config LEDS_ATMEL_PWM
- tristate "LED Support using Atmel PWM outputs"
- depends on LEDS_CLASS
- depends on ATMEL_PWM
- help
- This option enables support for LEDs driven using outputs
- of the dedicated PWM controller found on newer Atmel SOCs.
-
config LEDS_LM3530
tristate "LCD Backlight driver for LM3530"
depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 79c5155199a7..3c036663f17b 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -6,7 +6,6 @@ obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o
# LED Platform Drivers
obj-$(CONFIG_LEDS_88PM860X) += leds-88pm860x.o
-obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o
obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o
obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o
diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c
deleted file mode 100644
index 56cec8d6a2ac..000000000000
--- a/drivers/leds/leds-atmel-pwm.c
+++ /dev/null
@@ -1,149 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/leds.h>
-#include <linux/io.h>
-#include <linux/atmel_pwm.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-
-struct pwmled {
- struct led_classdev cdev;
- struct pwm_channel pwmc;
- struct gpio_led *desc;
- u32 mult;
- u8 active_low;
-};
-
-
-/*
- * For simplicity, we use "brightness" as if it were a linear function
- * of PWM duty cycle. However, a logarithmic function of duty cycle is
- * probably a better match for perceived brightness: two is half as bright
- * as four, four is half as bright as eight, etc
- */
-static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b)
-{
- struct pwmled *led;
-
- /* update the duty cycle for the *next* period */
- led = container_of(cdev, struct pwmled, cdev);
- pwm_channel_writel(&led->pwmc, PWM_CUPD, led->mult * (unsigned) b);
-}
-
-/*
- * NOTE: we reuse the platform_data structure of GPIO leds,
- * but repurpose its "gpio" number as a PWM channel number.
- */
-static int pwmled_probe(struct platform_device *pdev)
-{
- const struct gpio_led_platform_data *pdata;
- struct pwmled *leds;
- int i;
- int status;
-
- pdata = dev_get_platdata(&pdev->dev);
- if (!pdata || pdata->num_leds < 1)
- return -ENODEV;
-
- leds = devm_kzalloc(&pdev->dev, pdata->num_leds * sizeof(*leds),
- GFP_KERNEL);
- if (!leds)
- return -ENOMEM;
-
- for (i = 0; i < pdata->num_leds; i++) {
- struct pwmled *led = leds + i;
- const struct gpio_led *dat = pdata->leds + i;
- u32 tmp;
-
- led->cdev.name = dat->name;
- led->cdev.brightness = LED_OFF;
- led->cdev.brightness_set = pwmled_brightness;
- led->cdev.default_trigger = dat->default_trigger;
-
- led->active_low = dat->active_low;
-
- status = pwm_channel_alloc(dat->gpio, &led->pwmc);
- if (status < 0)
- goto err;
-
- /*
- * Prescale clock by 2^x, so PWM counts in low MHz.
- * Start each cycle with the LED active, so increasing
- * the duty cycle gives us more time on (= brighter).
- */
- tmp = 5;
- if (!led->active_low)
- tmp |= PWM_CPR_CPOL;
- pwm_channel_writel(&led->pwmc, PWM_CMR, tmp);
-
- /*
- * Pick a period so PWM cycles at 100+ Hz; and a multiplier
- * for scaling duty cycle: brightness * mult.
- */
- tmp = (led->pwmc.mck / (1 << 5)) / 100;
- tmp /= 255;
- led->mult = tmp;
- pwm_channel_writel(&led->pwmc, PWM_CDTY,
- led->cdev.brightness * 255);
- pwm_channel_writel(&led->pwmc, PWM_CPRD,
- LED_FULL * tmp);
-
- pwm_channel_enable(&led->pwmc);
-
- /* Hand it over to the LED framework */
- status = led_classdev_register(&pdev->dev, &led->cdev);
- if (status < 0) {
- pwm_channel_free(&led->pwmc);
- goto err;
- }
- }
-
- platform_set_drvdata(pdev, leds);
- return 0;
-
-err:
- if (i > 0) {
- for (i = i - 1; i >= 0; i--) {
- led_classdev_unregister(&leds[i].cdev);
- pwm_channel_free(&leds[i].pwmc);
- }
- }
-
- return status;
-}
-
-static int pwmled_remove(struct platform_device *pdev)
-{
- const struct gpio_led_platform_data *pdata;
- struct pwmled *leds;
- unsigned i;
-
- pdata = dev_get_platdata(&pdev->dev);
- leds = platform_get_drvdata(pdev);
-
- for (i = 0; i < pdata->num_leds; i++) {
- struct pwmled *led = leds + i;
-
- led_classdev_unregister(&led->cdev);
- pwm_channel_free(&led->pwmc);
- }
-
- return 0;
-}
-
-static struct platform_driver pwmled_driver = {
- .driver = {
- .name = "leds-atmel-pwm",
- .owner = THIS_MODULE,
- },
- /* REVISIT add suspend() and resume() methods */
- .probe = pwmled_probe,
- .remove = pwmled_remove,
-};
-
-module_platform_driver(pwmled_driver);
-
-MODULE_DESCRIPTION("Driver for LEDs with PWM-controlled brightness");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:leds-atmel-pwm");
--
1.9.1
^ permalink raw reply related
* [PATCHv2 15/15] misc: atmel_pwm: remove obsolete driver
From: Alexandre Belloni @ 2014-05-28 23:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1401319218-16772-1-git-send-email-alexandre.belloni@free-electrons.com>
The misc/atmel_pwm is not used by any mainlined boards and has been replaced by
the pwm-driver using the generic PWM framework.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
drivers/misc/Kconfig | 10 --
drivers/misc/Makefile | 1 -
drivers/misc/atmel_pwm.c | 402 ----------------------------------------------
include/linux/atmel_pwm.h | 70 --------
4 files changed, 483 deletions(-)
delete mode 100644 drivers/misc/atmel_pwm.c
delete mode 100644 include/linux/atmel_pwm.h
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index a43d0c467274..b841180c7c74 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -51,16 +51,6 @@ config AD525X_DPOT_SPI
To compile this driver as a module, choose M here: the
module will be called ad525x_dpot-spi.
-config ATMEL_PWM
- tristate "Atmel AT32/AT91 PWM support"
- depends on HAVE_CLK
- depends on AVR32 || AT91SAM9263 || AT91SAM9RL || AT91SAM9G45
- help
- This option enables device driver support for the PWM channels
- on certain Atmel processors. Pulse Width Modulation is used for
- purposes including software controlled power-efficient backlights
- on LCD displays, motor control, and waveform generation.
-
config ATMEL_TCLIB
bool "Atmel AT32/AT91 Timer/Counter Library"
depends on (AVR32 || ARCH_AT91)
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index d59ce1261b38..5497d026e651 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -7,7 +7,6 @@ obj-$(CONFIG_AD525X_DPOT) += ad525x_dpot.o
obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o
obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o
obj-$(CONFIG_INTEL_MID_PTI) += pti.o
-obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o
obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
obj-$(CONFIG_BMP085) += bmp085.o
diff --git a/drivers/misc/atmel_pwm.c b/drivers/misc/atmel_pwm.c
deleted file mode 100644
index a6dc56e1bc58..000000000000
--- a/drivers/misc/atmel_pwm.c
+++ /dev/null
@@ -1,402 +0,0 @@
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/atmel_pwm.h>
-
-
-/*
- * This is a simple driver for the PWM controller found in various newer
- * Atmel SOCs, including the AVR32 series and the AT91sam9263.
- *
- * Chips with current Linux ports have only 4 PWM channels, out of max 32.
- * AT32UC3A and AT32UC3B chips have 7 channels (but currently no Linux).
- * Docs are inconsistent about the width of the channel counter registers;
- * it's at least 16 bits, but several places say 20 bits.
- */
-#define PWM_NCHAN 4 /* max 32 */
-
-struct pwm {
- spinlock_t lock;
- struct platform_device *pdev;
- u32 mask;
- int irq;
- void __iomem *base;
- struct clk *clk;
- struct pwm_channel *channel[PWM_NCHAN];
- void (*handler[PWM_NCHAN])(struct pwm_channel *);
-};
-
-
-/* global PWM controller registers */
-#define PWM_MR 0x00
-#define PWM_ENA 0x04
-#define PWM_DIS 0x08
-#define PWM_SR 0x0c
-#define PWM_IER 0x10
-#define PWM_IDR 0x14
-#define PWM_IMR 0x18
-#define PWM_ISR 0x1c
-
-static inline void pwm_writel(const struct pwm *p, unsigned offset, u32 val)
-{
- __raw_writel(val, p->base + offset);
-}
-
-static inline u32 pwm_readl(const struct pwm *p, unsigned offset)
-{
- return __raw_readl(p->base + offset);
-}
-
-static inline void __iomem *pwmc_regs(const struct pwm *p, int index)
-{
- return p->base + 0x200 + index * 0x20;
-}
-
-static struct pwm *pwm;
-
-static void pwm_dumpregs(struct pwm_channel *ch, char *tag)
-{
- struct device *dev = &pwm->pdev->dev;
-
- dev_dbg(dev, "%s: mr %08x, sr %08x, imr %08x\n",
- tag,
- pwm_readl(pwm, PWM_MR),
- pwm_readl(pwm, PWM_SR),
- pwm_readl(pwm, PWM_IMR));
- dev_dbg(dev,
- "pwm ch%d - mr %08x, dty %u, prd %u, cnt %u\n",
- ch->index,
- pwm_channel_readl(ch, PWM_CMR),
- pwm_channel_readl(ch, PWM_CDTY),
- pwm_channel_readl(ch, PWM_CPRD),
- pwm_channel_readl(ch, PWM_CCNT));
-}
-
-
-/**
- * pwm_channel_alloc - allocate an unused PWM channel
- * @index: identifies the channel
- * @ch: structure to be initialized
- *
- * Drivers allocate PWM channels according to the board's wiring, and
- * matching board-specific setup code. Returns zero or negative errno.
- */
-int pwm_channel_alloc(int index, struct pwm_channel *ch)
-{
- unsigned long flags;
- int status = 0;
-
- if (!pwm)
- return -EPROBE_DEFER;
-
- if (!(pwm->mask & 1 << index))
- return -ENODEV;
-
- if (index < 0 || index >= PWM_NCHAN || !ch)
- return -EINVAL;
- memset(ch, 0, sizeof *ch);
-
- spin_lock_irqsave(&pwm->lock, flags);
- if (pwm->channel[index])
- status = -EBUSY;
- else {
- clk_enable(pwm->clk);
-
- ch->regs = pwmc_regs(pwm, index);
- ch->index = index;
-
- /* REVISIT: ap7000 seems to go 2x as fast as we expect!! */
- ch->mck = clk_get_rate(pwm->clk);
-
- pwm->channel[index] = ch;
- pwm->handler[index] = NULL;
-
- /* channel and irq are always disabled when we return */
- pwm_writel(pwm, PWM_DIS, 1 << index);
- pwm_writel(pwm, PWM_IDR, 1 << index);
- }
- spin_unlock_irqrestore(&pwm->lock, flags);
- return status;
-}
-EXPORT_SYMBOL(pwm_channel_alloc);
-
-static int pwmcheck(struct pwm_channel *ch)
-{
- int index;
-
- if (!pwm)
- return -ENODEV;
- if (!ch)
- return -EINVAL;
- index = ch->index;
- if (index < 0 || index >= PWM_NCHAN || pwm->channel[index] != ch)
- return -EINVAL;
-
- return index;
-}
-
-/**
- * pwm_channel_free - release a previously allocated channel
- * @ch: the channel being released
- *
- * The channel is completely shut down (counter and IRQ disabled),
- * and made available for re-use. Returns zero, or negative errno.
- */
-int pwm_channel_free(struct pwm_channel *ch)
-{
- unsigned long flags;
- int t;
-
- spin_lock_irqsave(&pwm->lock, flags);
- t = pwmcheck(ch);
- if (t >= 0) {
- pwm->channel[t] = NULL;
- pwm->handler[t] = NULL;
-
- /* channel and irq are always disabled when we return */
- pwm_writel(pwm, PWM_DIS, 1 << t);
- pwm_writel(pwm, PWM_IDR, 1 << t);
-
- clk_disable(pwm->clk);
- t = 0;
- }
- spin_unlock_irqrestore(&pwm->lock, flags);
- return t;
-}
-EXPORT_SYMBOL(pwm_channel_free);
-
-int __pwm_channel_onoff(struct pwm_channel *ch, int enabled)
-{
- unsigned long flags;
- int t;
-
- /* OMITTED FUNCTIONALITY: starting several channels in synch */
-
- spin_lock_irqsave(&pwm->lock, flags);
- t = pwmcheck(ch);
- if (t >= 0) {
- pwm_writel(pwm, enabled ? PWM_ENA : PWM_DIS, 1 << t);
- t = 0;
- pwm_dumpregs(ch, enabled ? "enable" : "disable");
- }
- spin_unlock_irqrestore(&pwm->lock, flags);
-
- return t;
-}
-EXPORT_SYMBOL(__pwm_channel_onoff);
-
-/**
- * pwm_clk_alloc - allocate and configure CLKA or CLKB
- * @prescale: from 0..10, the power of two used to divide MCK
- * @div: from 1..255, the linear divisor to use
- *
- * Returns PWM_CPR_CLKA, PWM_CPR_CLKB, or negative errno. The allocated
- * clock will run with a period of (2^prescale * div) / MCK, or twice as
- * long if center aligned PWM output is used. The clock must later be
- * deconfigured using pwm_clk_free().
- */
-int pwm_clk_alloc(unsigned prescale, unsigned div)
-{
- unsigned long flags;
- u32 mr;
- u32 val = (prescale << 8) | div;
- int ret = -EBUSY;
-
- if (prescale >= 10 || div = 0 || div > 255)
- return -EINVAL;
-
- spin_lock_irqsave(&pwm->lock, flags);
- mr = pwm_readl(pwm, PWM_MR);
- if ((mr & 0xffff) = 0) {
- mr |= val;
- ret = PWM_CPR_CLKA;
- } else if ((mr & (0xffff << 16)) = 0) {
- mr |= val << 16;
- ret = PWM_CPR_CLKB;
- }
- if (ret > 0)
- pwm_writel(pwm, PWM_MR, mr);
- spin_unlock_irqrestore(&pwm->lock, flags);
- return ret;
-}
-EXPORT_SYMBOL(pwm_clk_alloc);
-
-/**
- * pwm_clk_free - deconfigure and release CLKA or CLKB
- *
- * Reverses the effect of pwm_clk_alloc().
- */
-void pwm_clk_free(unsigned clk)
-{
- unsigned long flags;
- u32 mr;
-
- spin_lock_irqsave(&pwm->lock, flags);
- mr = pwm_readl(pwm, PWM_MR);
- if (clk = PWM_CPR_CLKA)
- pwm_writel(pwm, PWM_MR, mr & ~(0xffff << 0));
- if (clk = PWM_CPR_CLKB)
- pwm_writel(pwm, PWM_MR, mr & ~(0xffff << 16));
- spin_unlock_irqrestore(&pwm->lock, flags);
-}
-EXPORT_SYMBOL(pwm_clk_free);
-
-/**
- * pwm_channel_handler - manage channel's IRQ handler
- * @ch: the channel
- * @handler: the handler to use, possibly NULL
- *
- * If the handler is non-null, the handler will be called after every
- * period of this PWM channel. If the handler is null, this channel
- * won't generate an IRQ.
- */
-int pwm_channel_handler(struct pwm_channel *ch,
- void (*handler)(struct pwm_channel *ch))
-{
- unsigned long flags;
- int t;
-
- spin_lock_irqsave(&pwm->lock, flags);
- t = pwmcheck(ch);
- if (t >= 0) {
- pwm->handler[t] = handler;
- pwm_writel(pwm, handler ? PWM_IER : PWM_IDR, 1 << t);
- t = 0;
- }
- spin_unlock_irqrestore(&pwm->lock, flags);
-
- return t;
-}
-EXPORT_SYMBOL(pwm_channel_handler);
-
-static irqreturn_t pwm_irq(int id, void *_pwm)
-{
- struct pwm *p = _pwm;
- irqreturn_t handled = IRQ_NONE;
- u32 irqstat;
- int index;
-
- spin_lock(&p->lock);
-
- /* ack irqs, then handle them */
- irqstat = pwm_readl(pwm, PWM_ISR);
-
- while (irqstat) {
- struct pwm_channel *ch;
- void (*handler)(struct pwm_channel *ch);
-
- index = ffs(irqstat) - 1;
- irqstat &= ~(1 << index);
- ch = pwm->channel[index];
- handler = pwm->handler[index];
- if (handler && ch) {
- spin_unlock(&p->lock);
- handler(ch);
- spin_lock(&p->lock);
- handled = IRQ_HANDLED;
- }
- }
-
- spin_unlock(&p->lock);
- return handled;
-}
-
-static int __init pwm_probe(struct platform_device *pdev)
-{
- struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- int irq = platform_get_irq(pdev, 0);
- u32 *mp = pdev->dev.platform_data;
- struct pwm *p;
- int status = -EIO;
-
- if (pwm)
- return -EBUSY;
- if (!r || irq < 0 || !mp || !*mp)
- return -ENODEV;
- if (*mp & ~((1<<PWM_NCHAN)-1)) {
- dev_warn(&pdev->dev, "mask 0x%x ... more than %d channels\n",
- *mp, PWM_NCHAN);
- return -EINVAL;
- }
-
- p = kzalloc(sizeof(*p), GFP_KERNEL);
- if (!p)
- return -ENOMEM;
-
- spin_lock_init(&p->lock);
- p->pdev = pdev;
- p->mask = *mp;
- p->irq = irq;
- p->base = ioremap(r->start, resource_size(r));
- if (!p->base)
- goto fail;
- p->clk = clk_get(&pdev->dev, "pwm_clk");
- if (IS_ERR(p->clk)) {
- status = PTR_ERR(p->clk);
- p->clk = NULL;
- goto fail;
- }
-
- status = request_irq(irq, pwm_irq, 0, pdev->name, p);
- if (status < 0)
- goto fail;
-
- pwm = p;
- platform_set_drvdata(pdev, p);
-
- return 0;
-
-fail:
- if (p->clk)
- clk_put(p->clk);
- if (p->base)
- iounmap(p->base);
-
- kfree(p);
- return status;
-}
-
-static int __exit pwm_remove(struct platform_device *pdev)
-{
- struct pwm *p = platform_get_drvdata(pdev);
-
- if (p != pwm)
- return -EINVAL;
-
- clk_enable(pwm->clk);
- pwm_writel(pwm, PWM_DIS, (1 << PWM_NCHAN) - 1);
- pwm_writel(pwm, PWM_IDR, (1 << PWM_NCHAN) - 1);
- clk_disable(pwm->clk);
-
- pwm = NULL;
-
- free_irq(p->irq, p);
- clk_put(p->clk);
- iounmap(p->base);
- kfree(p);
-
- return 0;
-}
-
-static struct platform_driver atmel_pwm_driver = {
- .driver = {
- .name = "atmel_pwm",
- .owner = THIS_MODULE,
- },
- .remove = __exit_p(pwm_remove),
-
- /* NOTE: PWM can keep running in AVR32 "idle" and "frozen" states;
- * and all AT91sam9263 states, albeit at reduced clock rate if
- * MCK becomes the slow clock (i.e. what Linux labels STR).
- */
-};
-
-module_platform_driver_probe(atmel_pwm_driver, pwm_probe);
-
-MODULE_DESCRIPTION("Driver for AT32/AT91 PWM module");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:atmel_pwm");
diff --git a/include/linux/atmel_pwm.h b/include/linux/atmel_pwm.h
deleted file mode 100644
index ea04abb3db8e..000000000000
--- a/include/linux/atmel_pwm.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef __LINUX_ATMEL_PWM_H
-#define __LINUX_ATMEL_PWM_H
-
-/**
- * struct pwm_channel - driver handle to a PWM channel
- * @regs: base of this channel's registers
- * @index: number of this channel (0..31)
- * @mck: base clock rate, which can be prescaled and maybe subdivided
- *
- * Drivers initialize a pwm_channel structure using pwm_channel_alloc().
- * Then they configure its clock rate (derived from MCK), alignment,
- * polarity, and duty cycle by writing directly to the channel registers,
- * before enabling the channel by calling pwm_channel_enable().
- *
- * After emitting a PWM signal for the desired length of time, drivers
- * may then pwm_channel_disable() or pwm_channel_free(). Both of these
- * disable the channel, but when it's freed the IRQ is deconfigured and
- * the channel must later be re-allocated and reconfigured.
- *
- * Note that if the period or duty cycle need to be changed while the
- * PWM channel is operating, drivers must use the PWM_CUPD double buffer
- * mechanism, either polling until they change or getting implicitly
- * notified through a once-per-period interrupt handler.
- */
-struct pwm_channel {
- void __iomem *regs;
- unsigned index;
- unsigned long mck;
-};
-
-extern int pwm_channel_alloc(int index, struct pwm_channel *ch);
-extern int pwm_channel_free(struct pwm_channel *ch);
-
-extern int pwm_clk_alloc(unsigned prescale, unsigned div);
-extern void pwm_clk_free(unsigned clk);
-
-extern int __pwm_channel_onoff(struct pwm_channel *ch, int enabled);
-
-#define pwm_channel_enable(ch) __pwm_channel_onoff((ch), 1)
-#define pwm_channel_disable(ch) __pwm_channel_onoff((ch), 0)
-
-/* periodic interrupts, mostly for CUPD changes to period or cycle */
-extern int pwm_channel_handler(struct pwm_channel *ch,
- void (*handler)(struct pwm_channel *ch));
-
-/* per-channel registers (banked at pwm_channel->regs) */
-#define PWM_CMR 0x00 /* mode register */
-#define PWM_CPR_CPD (1 << 10) /* set: CUPD modifies period */
-#define PWM_CPR_CPOL (1 << 9) /* set: idle high */
-#define PWM_CPR_CALG (1 << 8) /* set: center align */
-#define PWM_CPR_CPRE (0xf << 0) /* mask: rate is mck/(2^pre) */
-#define PWM_CPR_CLKA (0xb << 0) /* rate CLKA */
-#define PWM_CPR_CLKB (0xc << 0) /* rate CLKB */
-#define PWM_CDTY 0x04 /* duty cycle (max of CPRD) */
-#define PWM_CPRD 0x08 /* period (count up from zero) */
-#define PWM_CCNT 0x0c /* counter (20 bits?) */
-#define PWM_CUPD 0x10 /* update CPRD (or CDTY) next period */
-
-static inline void
-pwm_channel_writel(struct pwm_channel *pwmc, unsigned offset, u32 val)
-{
- __raw_writel(val, pwmc->regs + offset);
-}
-
-static inline u32 pwm_channel_readl(struct pwm_channel *pwmc, unsigned offset)
-{
- return __raw_readl(pwmc->regs + offset);
-}
-
-#endif /* __LINUX_ATMEL_PWM_H */
--
1.9.1
^ permalink raw reply related
* Re: [PATCHv2 15/15] misc: atmel_pwm: remove obsolete driver
From: Greg Kroah-Hartman @ 2014-05-28 23:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1401319218-16772-16-git-send-email-alexandre.belloni@free-electrons.com>
On Thu, May 29, 2014 at 01:20:18AM +0200, Alexandre Belloni wrote:
> The misc/atmel_pwm is not used by any mainlined boards and has been replaced by
> the pwm-driver using the generic PWM framework.
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
^ permalink raw reply
* [PATCH 1/1] video: omapdss: Fix potential null pointer dereference
From: Sachin Kamat @ 2014-05-30 10:38 UTC (permalink / raw)
To: linux-fbdev
kmalloc can return null. Add a check to avoid potential null
pointer dereference error when the pointer is accessed later.
Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
---
drivers/video/fbdev/omap2/dss/omapdss-boot-init.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c b/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c
index 99af9e88b2d8..2f0822ee3ff9 100644
--- a/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c
+++ b/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c
@@ -121,9 +121,11 @@ static void __init omapdss_add_to_list(struct device_node *node, bool root)
{
struct dss_conv_node *n = kmalloc(sizeof(struct dss_conv_node),
GFP_KERNEL);
- n->node = node;
- n->root = root;
- list_add(&n->list, &dss_conv_list);
+ if (n) {
+ n->node = node;
+ n->root = root;
+ list_add(&n->list, &dss_conv_list);
+ }
}
static bool __init omapdss_list_contains(const struct device_node *node)
--
1.7.9.5
^ permalink raw reply related
* [PATCH] console: Add persistent scrollback buffers for all VGA consoles
From: Manuel Schölling @ 2014-05-30 13:27 UTC (permalink / raw)
To: plagnioj
Cc: tomi.valkeinen, geert, broonie, rdunlap, dh.herrmann, airlied,
mtosatti, linux-fbdev, linux-kernel, Manuel Schölling
Add a scrollback buffers for each VGA console. The benefit is that
the scrollback history is not flushed when switching between consoles
but is persistent.
The buffers are allocated on demand when a new console is opened.
Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
---
drivers/video/console/Kconfig | 6 +-
drivers/video/console/vgacon.c | 124 ++++++++++++++++++++++++----------------
2 files changed, 79 insertions(+), 51 deletions(-)
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index fe1cd01..d7ec96c 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -38,14 +38,14 @@ config VGACON_SOFT_SCROLLBACK
RAM to allocate for this buffer. If unsure, say 'N'.
config VGACON_SOFT_SCROLLBACK_SIZE
- int "Scrollback Buffer Size (in KB)"
+ int "Scrollback Buffer Size per console (in KB)"
depends on VGACON_SOFT_SCROLLBACK
range 1 1024
default "64"
help
Enter the amount of System RAM to allocate for the scrollback
- buffer. Each 64KB will give you approximately 16 80x25
- screenfuls of scrollback buffer
+ buffer for each VGA console. Each 64KB will give you approximately
+ 16 80x25 screenfuls of scrollback buffer.
config MDA_CONSOLE
depends on !M68K && !PARISC && ISA
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 9d8feac..215eafb 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -181,75 +181,101 @@ static inline void vga_set_mem_top(struct vc_data *c)
#ifdef CONFIG_VGACON_SOFT_SCROLLBACK
/* software scrollback */
-static void *vgacon_scrollback;
-static int vgacon_scrollback_tail;
-static int vgacon_scrollback_size;
-static int vgacon_scrollback_rows;
-static int vgacon_scrollback_cnt;
-static int vgacon_scrollback_cur;
-static int vgacon_scrollback_save;
-static int vgacon_scrollback_restore;
-
-static void vgacon_scrollback_init(int pitch)
+struct vgacon_scrollback_info {
+ void *data;
+ int tail;
+ int size;
+ int rows;
+ int cnt;
+ int cur;
+ int save;
+ int restore;
+} vgacon_scrollbacks[MAX_NR_CONSOLES];
+
+static void vgacon_scrollback_init(int vc_num)
{
+ int pitch = vga_video_num_columns * 2;
int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
+ void *data;
- if (vgacon_scrollback) {
- vgacon_scrollback_cnt = 0;
- vgacon_scrollback_tail = 0;
- vgacon_scrollback_cur = 0;
- vgacon_scrollback_rows = rows - 1;
- vgacon_scrollback_size = rows * pitch;
+ data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
+ if (!data) {
+ pr_warn("VGAcon: failed to allocate memory for scrollback.\n");
+ vgacon_scrollbacks[vc_num].data = NULL;
+ return;
}
+
+ vgacon_scrollbacks[vc_num].data = data;
+ vgacon_scrollbacks[vc_num].cnt = 0;
+ vgacon_scrollbacks[vc_num].tail = 0;
+ vgacon_scrollbacks[vc_num].cur = 0;
+ vgacon_scrollbacks[vc_num].rows = rows - 1;
+ vgacon_scrollbacks[vc_num].size = rows * pitch;
+}
+
+static void vgacon_switch_scrollback(int vc_num)
+{
+ if (!vgacon_scrollbacks[vc_num].data)
+ vgacon_scrollback_init(vc_num);
}
static void vgacon_scrollback_startup(void)
{
- vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
- vgacon_scrollback_init(vga_video_num_columns * 2);
+ int i;
+
+ for (i = 0; i < MAX_NR_CONSOLES; ++i)
+ vgacon_scrollbacks[i].data = NULL;
+
+ vgacon_scrollback_init(0);
}
static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
{
+ struct vgacon_scrollback_info *scrollback;
void *p;
- if (!vgacon_scrollback_size || c->vc_num != fg_console)
+ scrollback = &vgacon_scrollbacks[c->vc_num];
+ if (!scrollback->data || !scrollback->size)
return;
p = (void *) (c->vc_origin + t * c->vc_size_row);
while (count--) {
- scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail,
+ scr_memcpyw(scrollback->data + scrollback->tail,
p, c->vc_size_row);
- vgacon_scrollback_cnt++;
+ scrollback->cnt++;
p += c->vc_size_row;
- vgacon_scrollback_tail += c->vc_size_row;
+ scrollback->tail += c->vc_size_row;
- if (vgacon_scrollback_tail >= vgacon_scrollback_size)
- vgacon_scrollback_tail = 0;
+ if (scrollback->tail >= scrollback->size)
+ scrollback->tail = 0;
- if (vgacon_scrollback_cnt > vgacon_scrollback_rows)
- vgacon_scrollback_cnt = vgacon_scrollback_rows;
+ if (scrollback->cnt > scrollback->rows)
+ scrollback->cnt = scrollback->rows;
- vgacon_scrollback_cur = vgacon_scrollback_cnt;
+ scrollback->cur = scrollback->cnt;
}
}
static void vgacon_restore_screen(struct vc_data *c)
{
- vgacon_scrollback_save = 0;
+ struct vgacon_scrollback_info *scrollback;
+
+ scrollback = &vgacon_scrollbacks[c->vc_num];
+ scrollback->save = 0;
- if (!vga_is_gfx && !vgacon_scrollback_restore) {
+ if (!vga_is_gfx && !scrollback->restore) {
scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
c->vc_screenbuf_size > vga_vram_size ?
vga_vram_size : c->vc_screenbuf_size);
- vgacon_scrollback_restore = 1;
- vgacon_scrollback_cur = vgacon_scrollback_cnt;
+ scrollback->restore = 1;
+ scrollback->cur = scrollback->cnt;
}
}
static int vgacon_scrolldelta(struct vc_data *c, int lines)
{
+ struct vgacon_scrollback_info *scrollback;
int start, end, count, soff;
if (!lines) {
@@ -258,41 +284,42 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
return 1;
}
- if (!vgacon_scrollback)
+ scrollback = &vgacon_scrollbacks[c->vc_num];
+ if (!scrollback->data)
return 1;
- if (!vgacon_scrollback_save) {
+ if (!scrollback->save) {
vgacon_cursor(c, CM_ERASE);
vgacon_save_screen(c);
- vgacon_scrollback_save = 1;
+ scrollback->save = 1;
}
- vgacon_scrollback_restore = 0;
- start = vgacon_scrollback_cur + lines;
+ scrollback->restore = 0;
+ start = scrollback->cur + lines;
end = start + abs(lines);
if (start < 0)
start = 0;
- if (start > vgacon_scrollback_cnt)
- start = vgacon_scrollback_cnt;
+ if (start > scrollback->cnt)
+ start = scrollback->cnt;
if (end < 0)
end = 0;
- if (end > vgacon_scrollback_cnt)
- end = vgacon_scrollback_cnt;
+ if (end > scrollback->cnt)
+ end = scrollback->cnt;
- vgacon_scrollback_cur = start;
+ scrollback->cur = start;
count = end - start;
- soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) *
+ soff = scrollback->tail - ((scrollback->cnt - end) *
c->vc_size_row);
soff -= count * c->vc_size_row;
if (soff < 0)
- soff += vgacon_scrollback_size;
+ soff += scrollback->size;
- count = vgacon_scrollback_cnt - start;
+ count = scrollback->cnt - start;
if (count > c->vc_rows)
count = c->vc_rows;
@@ -306,13 +333,13 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
count *= c->vc_size_row;
/* how much memory to end of buffer left? */
- copysize = min(count, vgacon_scrollback_size - soff);
- scr_memcpyw(d, vgacon_scrollback + soff, copysize);
+ copysize = min(count, scrollback->size - soff);
+ scr_memcpyw(d, scrollback->data + soff, copysize);
d += copysize;
count -= copysize;
if (count) {
- scr_memcpyw(d, vgacon_scrollback, count);
+ scr_memcpyw(d, scrollback->data, count);
d += count;
}
@@ -327,6 +354,7 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
#define vgacon_scrollback_startup(...) do { } while (0)
#define vgacon_scrollback_init(...) do { } while (0)
#define vgacon_scrollback_update(...) do { } while (0)
+#define vgacon_switch_scrollback(...) do { } while (0)
static void vgacon_restore_screen(struct vc_data *c)
{
@@ -842,7 +870,7 @@ static int vgacon_switch(struct vc_data *c)
vgacon_doresize(c, c->vc_cols, c->vc_rows);
}
- vgacon_scrollback_init(c->vc_size_row);
+ vgacon_switch_scrollback(c->vc_num);
return 0; /* Redrawing not needed */
}
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH] console: Add persistent scrollback buffers for all VGA consoles
From: Geert Uytterhoeven @ 2014-05-30 14:28 UTC (permalink / raw)
To: Manuel Schölling
Cc: Jean-Christophe PLAGNIOL-VILLARD, Tomi Valkeinen, Mark Brown,
Randy Dunlap, David Herrmann, Dave Airlie, Marcelo Tosatti,
Linux Fbdev development list, linux-kernel@vger.kernel.org
In-Reply-To: <1401456425-15931-1-git-send-email-manuel.schoelling@gmx.de>
Hi Manuel,
On Fri, May 30, 2014 at 3:27 PM, Manuel Schölling
<manuel.schoelling@gmx.de> wrote:
> Add a scrollback buffers for each VGA console. The benefit is that
> the scrollback history is not flushed when switching between consoles
> but is persistent.
> The buffers are allocated on demand when a new console is opened.
Thanks for your patch!
I see two issues with this feature:
1. Before, the single (default 64 KiB) buffer was allocated at startup.
Now you will allocate a buffer each time a new console is opened.
Depending on memory fragmentation, this may fail.
2. People with RAM-constrained systems may not like this.
Can it be a config option?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH] console: Add persistent scrollback buffers for all VGA consoles
From: Manuel Schoelling @ 2014-05-30 14:57 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Jean-Christophe PLAGNIOL-VILLARD, Tomi Valkeinen, Mark Brown,
Randy Dunlap, David Herrmann, Dave Airlie, Marcelo Tosatti,
Linux Fbdev development list, linux-kernel@vger.kernel.org
In-Reply-To: <CAMuHMdVrDB7Q+oZi_WJk07a7OF_VOJiOHxpYwRABymTKsPuMoA@mail.gmail.com>
Hi Geert,
On Fr, 2014-05-30 at 16:28 +0200, Geert Uytterhoeven wrote:
Hi Manuel,
>
> On Fri, May 30, 2014 at 3:27 PM, Manuel Schölling
> <manuel.schoelling@gmx.de> wrote:
> > Add a scrollback buffers for each VGA console. The benefit is that
> > the scrollback history is not flushed when switching between
consoles
> > but is persistent.
> > The buffers are allocated on demand when a new console is opened.
>
> Thanks for your patch!
>
> I see two issues with this feature:
> 1. Before, the single (default 64 KiB) buffer was allocated at
startup.
> Now you will allocate a buffer each time a new console is opened.
> Depending on memory fragmentation, this may fail.
Indeed, if allocation fails, scrollbuffer[vc_num]->data will stay NULL
and scrolling will be disabled for that console. Is that ok or would you
prefer another behavior of the kernel?
> 2. People with RAM-constrained systems may not like this.
> Can it be a config option?
Sure, I will add an option for that.
>
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 --
geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a
hacker. But
> when I'm talking to journalists I just say "programmer" or something
like that.
> -- Linus Torvalds
>
^ permalink raw reply
* Re: [PATCH] console: Add persistent scrollback buffers for all VGA consoles
From: Randy Dunlap @ 2014-05-30 17:06 UTC (permalink / raw)
To: Manuel Schölling, plagnioj
Cc: tomi.valkeinen, geert, broonie, dh.herrmann, airlied, mtosatti,
linux-fbdev, linux-kernel
In-Reply-To: <1401456425-15931-1-git-send-email-manuel.schoelling@gmx.de>
On 05/30/2014 06:27 AM, Manuel Schölling wrote:
> ---
> drivers/video/console/Kconfig | 6 +-
> drivers/video/console/vgacon.c | 124 ++++++++++++++++++++++++----------------
> 2 files changed, 79 insertions(+), 51 deletions(-)
>
> diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
> index fe1cd01..d7ec96c 100644
> --- a/drivers/video/console/Kconfig
> +++ b/drivers/video/console/Kconfig
> @@ -38,14 +38,14 @@ config VGACON_SOFT_SCROLLBACK
> RAM to allocate for this buffer. If unsure, say 'N'.
>
> config VGACON_SOFT_SCROLLBACK_SIZE
> - int "Scrollback Buffer Size (in KB)"
> + int "Scrollback Buffer Size per console (in KB)"
> depends on VGACON_SOFT_SCROLLBACK
> range 1 1024
> default "64"
> help
> Enter the amount of System RAM to allocate for the scrollback
> - buffer. Each 64KB will give you approximately 16 80x25
> - screenfuls of scrollback buffer
> + buffer for each VGA console. Each 64KB will give you approximately
> + 16 80x25 screenfuls of scrollback buffer.
Nitpick: CodingStyle says to indent help text 1 tab + 2 spaces.
>
> config MDA_CONSOLE
> depends on !M68K && !PARISC && ISA
--
~Randy
^ permalink raw reply
* Re: [PATCH] console: Add persistent scrollback buffers for all VGA consoles
From: Jakub Wilk @ 2014-05-30 22:26 UTC (permalink / raw)
To: Manuel Schölling
Cc: plagnioj, tomi.valkeinen, geert, broonie, rdunlap, dh.herrmann,
airlied, mtosatti, linux-fbdev, linux-kernel
In-Reply-To: <1401456425-15931-1-git-send-email-manuel.schoelling@gmx.de>
* Manuel Schölling <manuel.schoelling@gmx.de>, 2014-05-30, 15:27:
>Add a scrollback buffers for each VGA console. The benefit is that the
>scrollback history is not flushed when switching between consoles but
>is persistent.
Some people rely on this scrollback flushing as a security feature. Is
there even another way to clear the scrollback, than to switch to
another vt and then back again?
Debian ships this:
http://manpages.debian.org/cgi-bin/man.cgi?query=clear_console
https://sources.debian.net/src/bash/4.2%2Bdfsg-0.1/debian/clear_console.c
--
Jakub Wilk
^ permalink raw reply
* Re: [PATCH] console: Add persistent scrollback buffers for all VGA consoles
From: Manuel Schoelling @ 2014-05-31 9:49 UTC (permalink / raw)
To: Jakub Wilk
Cc: plagnioj, tomi.valkeinen, geert, broonie, rdunlap, dh.herrmann,
airlied, mtosatti, linux-fbdev, linux-kernel
In-Reply-To: <20140530222622.GA1385@jwilk.net>
On Sa, 2014-05-31 at 00:26 +0200, Jakub Wilk wrote:
> * Manuel Schölling <manuel.schoelling@gmx.de>, 2014-05-30, 15:27:
> >Add a scrollback buffers for each VGA console. The benefit is that the
> >scrollback history is not flushed when switching between consoles but
> >is persistent.
>
> Some people rely on this scrollback flushing as a security feature. Is
> there even another way to clear the scrollback, than to switch to
> another vt and then back again?
Thanks for raising this security issue! Maybe we should add something
like VT_FLUSH_SCROLLBACK to vt_ioctl()? [1]
I'm open for better ways to flush the scrollback history.
[1] http://lxr.free-electrons.com/source/drivers/tty/vt/vt_ioctl.c#L334
> Debian ships this:
> http://manpages.debian.org/cgi-bin/man.cgi?query=clear_console
> https://sources.debian.net/src/bash/4.2%2Bdfsg-0.1/debian/clear_console.c
>
^ permalink raw reply
* [PATCH v2] console: Add persistent scrollback buffers for all VGA consoles
From: Manuel Schölling @ 2014-05-31 10:57 UTC (permalink / raw)
To: plagnioj
Cc: tomi.valkeinen, geert, broonie, rdunlap, dh.herrmann, airlied,
mtosatti, linux-fbdev, linux-kernel, Manuel Schölling
In-Reply-To: <CAMuHMdXP47kf1sSfx1NLpGb1eGsepVvMPQjVg9XzfFYWpwBaTQ@mail.gmail.com>
Add a scrollback buffers for each VGA console. The benefit is that
the scrollback history is not flushed when switching between consoles
but is persistent.
The buffers are allocated on demand when a new console is opened.
Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
---
drivers/video/console/Kconfig | 19 ++++-
drivers/video/console/vgacon.c | 159 +++++++++++++++++++++++++++-------------
2 files changed, 124 insertions(+), 54 deletions(-)
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index fe1cd01..05fdc2c 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -43,9 +43,22 @@ config VGACON_SOFT_SCROLLBACK_SIZE
range 1 1024
default "64"
help
- Enter the amount of System RAM to allocate for the scrollback
- buffer. Each 64KB will give you approximately 16 80x25
- screenfuls of scrollback buffer
+ Enter the amount of System RAM to allocate for scrollback
+ buffers of VGA consoles. Each 64KB will give you approximately
+ 16 80x25 screenfuls of scrollback buffer.
+
+config VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE
+ bool "Persistent Scrollback History for each console"
+ depends on VGACON_SOFT_SCROLLBACK
+ default y
+ help
+ Say Y here if for each VGA console a scrollback buffer should
+ be allocated. The scrollback history will persist when switching
+ between consoles. If you say N here, scrollback is only supported
+ for the active VGA console and scrollback history will be flushed
+ when switching between consoles.
+
+ If you use a RAM-constrained system, say N here.
config MDA_CONSOLE
depends on !M68K && !PARISC && ISA
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 9d8feac..652131d 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -181,70 +181,126 @@ static inline void vga_set_mem_top(struct vc_data *c)
#ifdef CONFIG_VGACON_SOFT_SCROLLBACK
/* software scrollback */
-static void *vgacon_scrollback;
-static int vgacon_scrollback_tail;
-static int vgacon_scrollback_size;
-static int vgacon_scrollback_rows;
-static int vgacon_scrollback_cnt;
-static int vgacon_scrollback_cur;
-static int vgacon_scrollback_save;
-static int vgacon_scrollback_restore;
-
-static void vgacon_scrollback_init(int pitch)
+struct vgacon_scrollback_info {
+ void *data;
+ int tail;
+ int size;
+ int rows;
+ int cnt;
+ int cur;
+ int save;
+ int restore;
+};
+static struct vgacon_scrollback_info *vgacon_scrollback_cur;
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE
+static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES];
+#else
+static struct vgacon_scrollback_info vgacon_scrollbacks[1];
+#endif
+
+static void vgacon_scrollback_reset(size_t reset_size)
{
- int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
-
- if (vgacon_scrollback) {
- vgacon_scrollback_cnt = 0;
- vgacon_scrollback_tail = 0;
- vgacon_scrollback_cur = 0;
- vgacon_scrollback_rows = rows - 1;
- vgacon_scrollback_size = rows * pitch;
+ if (vgacon_scrollback_cur->data && reset_size > 0)
+ memset(vgacon_scrollback_cur->data, 0, reset_size);
+
+ vgacon_scrollback_cur->cnt = 0;
+ vgacon_scrollback_cur->tail = 0;
+ vgacon_scrollback_cur->cur = 0;
+}
+
+static void vgacon_scrollback_init(int vc_num)
+{
+ int pitch = vga_video_num_columns * 2;
+ size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+ int rows = size/pitch;
+ void *data;
+
+ data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
+ if (data) {
+ vgacon_scrollbacks[vc_num].data = data;
+ vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+
+ vgacon_scrollback_cur->rows = rows - 1;
+ vgacon_scrollback_cur->size = rows * pitch;
+
+ vgacon_scrollback_reset(0);
+ } else {
+ pr_warn("VGAcon: failed to allocate memory for scrollback. Trying to reuse previous buffer.\n");
+ /* leave vgacon_scrollback_cur untouched
+ but reset its content */
+ vgacon_scrollback_reset(size);
}
}
+static void vgacon_switch_scrollback(int vc_num)
+{
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE
+ if (!vgacon_scrollbacks[vc_num].data)
+ vgacon_scrollback_init(vc_num);
+ else
+ vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+#else
+ vc_num = 0;
+
+ if (!vgacon_scrollbacks[vc_num].data)
+ vgacon_scrollback_init(vc_num);
+ else {
+ size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+
+ vgacon_scrollback_reset(size);
+ }
+#endif
+}
+
static void vgacon_scrollback_startup(void)
{
- vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
- vgacon_scrollback_init(vga_video_num_columns * 2);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(vgacon_scrollbacks); ++i)
+ vgacon_scrollbacks[i].data = NULL;
+
+ vgacon_scrollback_cur = &vgacon_scrollbacks[0];
+ vgacon_scrollback_init(0);
}
static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
{
void *p;
- if (!vgacon_scrollback_size || c->vc_num != fg_console)
+ if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size)
return;
p = (void *) (c->vc_origin + t * c->vc_size_row);
while (count--) {
- scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail,
+ scr_memcpyw(vgacon_scrollback_cur->data +
+ vgacon_scrollback_cur->tail,
p, c->vc_size_row);
- vgacon_scrollback_cnt++;
+
+ vgacon_scrollback_cur->cnt++;
p += c->vc_size_row;
- vgacon_scrollback_tail += c->vc_size_row;
+ vgacon_scrollback_cur->tail += c->vc_size_row;
- if (vgacon_scrollback_tail >= vgacon_scrollback_size)
- vgacon_scrollback_tail = 0;
+ if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size)
+ vgacon_scrollback_cur->tail = 0;
- if (vgacon_scrollback_cnt > vgacon_scrollback_rows)
- vgacon_scrollback_cnt = vgacon_scrollback_rows;
+ if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows)
+ vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows;
- vgacon_scrollback_cur = vgacon_scrollback_cnt;
+ vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
}
}
static void vgacon_restore_screen(struct vc_data *c)
{
- vgacon_scrollback_save = 0;
+ vgacon_scrollback_cur->save = 0;
- if (!vga_is_gfx && !vgacon_scrollback_restore) {
+ if (!vga_is_gfx && !vgacon_scrollback_cur->restore) {
scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
c->vc_screenbuf_size > vga_vram_size ?
vga_vram_size : c->vc_screenbuf_size);
- vgacon_scrollback_restore = 1;
- vgacon_scrollback_cur = vgacon_scrollback_cnt;
+ vgacon_scrollback_cur->restore = 1;
+ vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
}
}
@@ -258,41 +314,41 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
return 1;
}
- if (!vgacon_scrollback)
+ if (!vgacon_scrollback_cur->data)
return 1;
- if (!vgacon_scrollback_save) {
+ if (!vgacon_scrollback_cur->save) {
vgacon_cursor(c, CM_ERASE);
vgacon_save_screen(c);
- vgacon_scrollback_save = 1;
+ vgacon_scrollback_cur->save = 1;
}
- vgacon_scrollback_restore = 0;
- start = vgacon_scrollback_cur + lines;
+ vgacon_scrollback_cur->restore = 0;
+ start = vgacon_scrollback_cur->cur + lines;
end = start + abs(lines);
if (start < 0)
start = 0;
- if (start > vgacon_scrollback_cnt)
- start = vgacon_scrollback_cnt;
+ if (start > vgacon_scrollback_cur->cnt)
+ start = vgacon_scrollback_cur->cnt;
if (end < 0)
end = 0;
- if (end > vgacon_scrollback_cnt)
- end = vgacon_scrollback_cnt;
+ if (end > vgacon_scrollback_cur->cnt)
+ end = vgacon_scrollback_cur->cnt;
- vgacon_scrollback_cur = start;
+ vgacon_scrollback_cur->cur = start;
count = end - start;
- soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) *
- c->vc_size_row);
+ soff = vgacon_scrollback_cur->tail -
+ ((vgacon_scrollback_cur->cnt - end) * c->vc_size_row);
soff -= count * c->vc_size_row;
if (soff < 0)
- soff += vgacon_scrollback_size;
+ soff += vgacon_scrollback_cur->size;
- count = vgacon_scrollback_cnt - start;
+ count = vgacon_scrollback_cur->cnt - start;
if (count > c->vc_rows)
count = c->vc_rows;
@@ -306,13 +362,13 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
count *= c->vc_size_row;
/* how much memory to end of buffer left? */
- copysize = min(count, vgacon_scrollback_size - soff);
- scr_memcpyw(d, vgacon_scrollback + soff, copysize);
+ copysize = min(count, vgacon_scrollback_cur->size - soff);
+ scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize);
d += copysize;
count -= copysize;
if (count) {
- scr_memcpyw(d, vgacon_scrollback, count);
+ scr_memcpyw(d, vgacon_scrollback_cur->data, count);
d += count;
}
@@ -327,6 +383,7 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
#define vgacon_scrollback_startup(...) do { } while (0)
#define vgacon_scrollback_init(...) do { } while (0)
#define vgacon_scrollback_update(...) do { } while (0)
+#define vgacon_switch_scrollback(...) do { } while (0)
static void vgacon_restore_screen(struct vc_data *c)
{
@@ -842,7 +899,7 @@ static int vgacon_switch(struct vc_data *c)
vgacon_doresize(c, c->vc_cols, c->vc_rows);
}
- vgacon_scrollback_init(c->vc_size_row);
+ vgacon_switch_scrollback(c->vc_num);
return 0; /* Redrawing not needed */
}
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH resend 2/4] backlight: Add backlight device (un)registration notification
From: Rafael J. Wysocki @ 2014-05-31 22:46 UTC (permalink / raw)
To: Lee Jones
Cc: Hans de Goede, Jingoo Han, 'Aaron Lu', 'Bryan Wu',
'Jean-Christophe Plagniol-Villard',
'Tomi Valkeinen', 'Ben Skeggs',
'David Airlie', 'Zhang Rui', 'Len Brown',
linux-acpi, linux-fbdev, dri-devel
In-Reply-To: <20140527092033.GF5875@lee--X1>
[-- Attachment #1: Type: text/plain, Size: 3044 bytes --]
On Tuesday, May 27, 2014 10:20:33 AM Lee Jones wrote:
> > On 05/26/2014 01:03 PM, Rafael J. Wysocki wrote:
> > > On Monday, May 26, 2014 12:03:43 PM Jingoo Han wrote:
> > >> On Thursday, May 22, 2014 6:02 PM, Lee Jones wrote:
> > >>> On Thursday, May 22, 2014 5:45 PM, Hans de Goede wrote:
> > >>>> On Thursday, May 22, 2014 8:31 AM, Rafael J. Wysocki wrote:
> > >>>>> On Wednesday, May 21, 2014 10:40 PM, Hans de Goede wrote:
> > >>>>>> Some firmware drivers, ie acpi-video want to get themselves out of the
> > >>>>>> way (in some cases) when their also is a raw backlight device available.
> > >>>>>>
> > >>>>>> Due to module loading ordering being unknown, acpi-video cannot be certain
> > >>>>>> that the backlight_device_registered(BACKLIGHT_RAW) it does for this is
> > >>>>>> the final verdict wrt there being a BACKLIGHT_RAW device.
> > >>>>>>
> > >>>>>> By adding notification acpi-video can listen for backlight devices showing
> > >>>>>> up after it has loaded, and unregister its backlight device if desired.
> > >>>>>>
> > >>>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> > >>>>>
> > >>>>> Backlight maintainer's ACK is requisite here.
> > >>>>
> > >>>> Agreed, which is why I send this set to all 3 the backlight maintainers
> > >>>> directly on both postings.
> > >>>>
> > >>>> What may be helpful for them is to hear from you if you're ok with the
> > >>>> acpi-video bits which are actually going to use this, since those will
> > >>>> be the only user of the new backlight api (for now).
> > >>>
> > >>> I'm happy to apply any Backlight patches which have either Bryan or
> > >>> Jingoo's Ack, as they are the reviewers for the BL subsystem.
> > >>
> > >> Acked-by: Jingoo Han <jg1.han@samsung.com>
> > >>
> > >> Lee Jones,
> > >> Would you merge this patch into your backlight git tree?
> > >
> > > Hans, does this series depend on things that I've applied already? If so,
> > > I'd very much prefer to take this series too as a whole.
> >
> > The 3th patch in this series:
> > " acpi-video: Unregister the backlight device if a raw one shows up later"
> > depends on my "acpi-video: Add an acpi_video_unregister_backlight function"
> > patch, which you've applied to your linux-next branch already.
> >
> > As well as on the 2nd patch in this series:
> > "backlight: Add backlight device (un)registration notification"
> >
> > So I agree that it is a good idea to take the whole series through your tree.
>
> I'm fine with that.
>
> Rafael, could you apply the set onto an immutable branch and send me a
> signed pull-request please?
You can find this patch on the branch at
git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git acpi-video
The top-most commit is 0dc6b96ac20c (ACPI / video: Add 4 new models to the
use_native_backlight DMI list).
Please feel free to pull from there if necessary, it is not going to be rebased.
Thanks!
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH resend 2/4] backlight: Add backlight device (un)registration notification
From: Lee Jones @ 2014-06-02 7:33 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Hans de Goede, Jingoo Han, 'Aaron Lu', 'Bryan Wu',
'Jean-Christophe Plagniol-Villard',
'Tomi Valkeinen', 'Ben Skeggs',
'David Airlie', 'Zhang Rui', 'Len Brown',
linux-acpi, linux-fbdev, dri-devel
In-Reply-To: <3320448.t5cXUpNSer@vostro.rjw.lan>
On Sun, 01 Jun 2014, Rafael J. Wysocki wrote:
> On Tuesday, May 27, 2014 10:20:33 AM Lee Jones wrote:
> > > On 05/26/2014 01:03 PM, Rafael J. Wysocki wrote:
> > > > On Monday, May 26, 2014 12:03:43 PM Jingoo Han wrote:
> > > >> On Thursday, May 22, 2014 6:02 PM, Lee Jones wrote:
> > > >>> On Thursday, May 22, 2014 5:45 PM, Hans de Goede wrote:
> > > >>>> On Thursday, May 22, 2014 8:31 AM, Rafael J. Wysocki wrote:
> > > >>>>> On Wednesday, May 21, 2014 10:40 PM, Hans de Goede wrote:
> > > >>>>>> Some firmware drivers, ie acpi-video want to get themselves out of the
> > > >>>>>> way (in some cases) when their also is a raw backlight device available.
> > > >>>>>>
> > > >>>>>> Due to module loading ordering being unknown, acpi-video cannot be certain
> > > >>>>>> that the backlight_device_registered(BACKLIGHT_RAW) it does for this is
> > > >>>>>> the final verdict wrt there being a BACKLIGHT_RAW device.
> > > >>>>>>
> > > >>>>>> By adding notification acpi-video can listen for backlight devices showing
> > > >>>>>> up after it has loaded, and unregister its backlight device if desired.
> > > >>>>>>
> > > >>>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> > > >>>>>
> > > >>>>> Backlight maintainer's ACK is requisite here.
> > > >>>>
> > > >>>> Agreed, which is why I send this set to all 3 the backlight maintainers
> > > >>>> directly on both postings.
> > > >>>>
> > > >>>> What may be helpful for them is to hear from you if you're ok with the
> > > >>>> acpi-video bits which are actually going to use this, since those will
> > > >>>> be the only user of the new backlight api (for now).
> > > >>>
> > > >>> I'm happy to apply any Backlight patches which have either Bryan or
> > > >>> Jingoo's Ack, as they are the reviewers for the BL subsystem.
> > > >>
> > > >> Acked-by: Jingoo Han <jg1.han@samsung.com>
> > > >>
> > > >> Lee Jones,
> > > >> Would you merge this patch into your backlight git tree?
> > > >
> > > > Hans, does this series depend on things that I've applied already? If so,
> > > > I'd very much prefer to take this series too as a whole.
> > >
> > > The 3th patch in this series:
> > > " acpi-video: Unregister the backlight device if a raw one shows up later"
> > > depends on my "acpi-video: Add an acpi_video_unregister_backlight function"
> > > patch, which you've applied to your linux-next branch already.
> > >
> > > As well as on the 2nd patch in this series:
> > > "backlight: Add backlight device (un)registration notification"
> > >
> > > So I agree that it is a good idea to take the whole series through your tree.
> >
> > I'm fine with that.
> >
> > Rafael, could you apply the set onto an immutable branch and send me a
> > signed pull-request please?
>
> You can find this patch on the branch at
>
> git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git acpi-video
>
> The top-most commit is 0dc6b96ac20c (ACPI / video: Add 4 new models to the
> use_native_backlight DMI list).
>
> Please feel free to pull from there if necessary, it is not going to be rebased.
acpi-video contains 14 patches! If we share patches in the future,
the branches really need to contain as few patches as possible. I'm
happy to set-up a special 'mfd-pm' immutable branch for future
releases to save either one of use pulling in more patches into our
respective trees than is necessary.
Rather than pull all those patches in to the MFD tree, I'll simply run
the risk of a merge conflict this time.
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* Re: [PATCH v2 1/5] gpu: ipu-v3: Move i.MX IPUv3 core driver out of staging
From: Philipp Zabel @ 2014-06-02 16:36 UTC (permalink / raw)
To: Greg Kroah-Hartman, Dave Airlie
Cc: devel, linux-fbdev, dri-devel, drm-devel, Tomi Valkeinen, kernel,
Russell King, Shawn Guo, Lucas Stach
In-Reply-To: <20140528211342.GA18203@kroah.com>
Am Mittwoch, den 28.05.2014, 14:13 -0700 schrieb Greg Kroah-Hartman:
> On Mon, May 26, 2014 at 04:19:39PM +0200, Philipp Zabel wrote:
> > The i.MX Image Processing Unit (IPU) contains a number of image processing
> > blocks that sit right in the middle between DRM and V4L2. Some of the modules,
> > such as Display Controller, Processor, and Interface (DC, DP, DI) or CMOS
> > Sensor Interface (CSI) and their FIFOs could be assigned to either framework,
> > but others, such as the dma controller (IDMAC) and image converter (IC) can
> > be used by both.
> > The IPUv3 core driver provides an internal API to access the modules, to be
> > used by both DRM and V4L2 IPUv3 drivers.
> >
> > Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> > Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> > ---
> > Changes since RFC:
> > - Rebased onto current staging-next
> > - Removed an unrelated change to ipu_pixelformat_to_colorspace
> > - Avoided moving around the IPU_PIX_FMT_GBR24 #define
>
> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Thank you. My favourite next step would be to send a pull request and
have this merged into drm-next. Dave, Greg would you be ok with this?
regards
Philipp
^ permalink raw reply
* Re: [PATCH v2 1/5] gpu: ipu-v3: Move i.MX IPUv3 core driver out of staging
From: Greg Kroah-Hartman @ 2014-06-02 17:06 UTC (permalink / raw)
To: Philipp Zabel
Cc: devel, linux-fbdev, dri-devel, drm-devel, Tomi Valkeinen, kernel,
Russell King, Dave Airlie
In-Reply-To: <1401726982.4173.58.camel@paszta.hi.pengutronix.de>
On Mon, Jun 02, 2014 at 06:36:22PM +0200, Philipp Zabel wrote:
> Am Mittwoch, den 28.05.2014, 14:13 -0700 schrieb Greg Kroah-Hartman:
> > On Mon, May 26, 2014 at 04:19:39PM +0200, Philipp Zabel wrote:
> > > The i.MX Image Processing Unit (IPU) contains a number of image processing
> > > blocks that sit right in the middle between DRM and V4L2. Some of the modules,
> > > such as Display Controller, Processor, and Interface (DC, DP, DI) or CMOS
> > > Sensor Interface (CSI) and their FIFOs could be assigned to either framework,
> > > but others, such as the dma controller (IDMAC) and image converter (IC) can
> > > be used by both.
> > > The IPUv3 core driver provides an internal API to access the modules, to be
> > > used by both DRM and V4L2 IPUv3 drivers.
> > >
> > > Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> > > Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> > > ---
> > > Changes since RFC:
> > > - Rebased onto current staging-next
> > > - Removed an unrelated change to ipu_pixelformat_to_colorspace
> > > - Avoided moving around the IPU_PIX_FMT_GBR24 #define
> >
> > Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>
> Thank you. My favourite next step would be to send a pull request and
> have this merged into drm-next. Dave, Greg would you be ok with this?
No objection from me, it's up to Dave what he wants for this.
greg k-h
^ permalink raw reply
* [PATCH] drm/i915: Kick out vga console
From: Daniel Vetter @ 2014-06-03 22:57 UTC (permalink / raw)
To: Intel Graphics Development
Cc: linux-fbdev, Daniel Vetter, DRI Development, Tomi Valkeinen,
Jean-Christophe Plagniol-Villard
From: Chris Wilson <chris@chris-wilson.co.uk>
Touching the VGA resources on an IVB EFI machine causes hard hangs when
we then kick out the efifb. Ouch.
Apparently this also prevents unclaimed register errors on hsw and
hard machine hangs on my i855gm when trying to unbind fbcon.
Also, we want this to make I915_FBDEV=n safe.
v2: Rebase and pimp commit message.
v3: We also need to unregister the vga console, otherwise the unbind
of the fb console before module unload might resurrect it again.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?idg813
Cc: David Herrmann <dh.herrmann@gmail.com>
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: linux-fbdev@vger.kernel.org
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> (v1)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/i915_dma.c | 34 +++++++++++++++++++++++++++++++++-
drivers/video/console/dummycon.c | 1 +
drivers/video/console/vgacon.c | 1 +
3 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index b9159ade5e85..a4df80740b37 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -36,6 +36,8 @@
#include "i915_drv.h"
#include "i915_trace.h"
#include <linux/pci.h>
+#include <linux/console.h>
+#include <linux/vt.h>
#include <linux/vgaarb.h>
#include <linux/acpi.h>
#include <linux/pnp.h>
@@ -1450,6 +1452,29 @@ static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
}
#endif
+static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
+{
+#if !defined(CONFIG_VGA_CONSOLE)
+ return 0;
+#else
+ int ret;
+
+#if !defined(CONFIG_DUMMY_CONSOLE)
+ return -ENODEV;
+#endif
+
+ DRM_INFO("Replacing VGA console driver\n");
+
+ console_lock();
+ ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1);
+ if (ret = 0)
+ ret = do_unregister_con_driver(&vga_con);
+ console_unlock();
+
+ return ret;
+#endif
+}
+
static void i915_dump_device_info(struct drm_i915_private *dev_priv)
{
const struct intel_device_info *info = &dev_priv->info;
@@ -1623,8 +1648,15 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (ret)
goto out_regs;
- if (drm_core_check_feature(dev, DRIVER_MODESET))
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ ret = i915_kick_out_vgacon(dev_priv);
+ if (ret) {
+ DRM_ERROR("failed to remove conflicting VGA console\n");
+ goto out_gtt;
+ }
+
i915_kick_out_firmware_fb(dev_priv);
+ }
pci_set_master(dev->pdev);
diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c
index b63860f7beab..40bec8d64b0a 100644
--- a/drivers/video/console/dummycon.c
+++ b/drivers/video/console/dummycon.c
@@ -77,3 +77,4 @@ const struct consw dummy_con = {
.con_set_palette = DUMMY,
.con_scrolldelta = DUMMY,
};
+EXPORT_SYMBOL_GPL(dummy_con);
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 9d8feac67637..84acd6223dc5 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -1440,5 +1440,6 @@ const struct consw vga_con = {
.con_build_attr = vgacon_build_attr,
.con_invert_region = vgacon_invert_region,
};
+EXPORT_SYMBOL(vga_con);
MODULE_LICENSE("GPL");
--
1.8.1.4
^ permalink raw reply related
* Re: [PATCH v2 1/5] gpu: ipu-v3: Move i.MX IPUv3 core driver out of staging
From: Dave Airlie @ 2014-06-04 3:07 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel@driverdev.osuosl.org, Linux Fbdev development list, kernel,
dri-devel, drm-devel, Tomi Valkeinen, Dave Airlie, Russell King
In-Reply-To: <20140602170650.GA31142@kroah.com>
On 3 June 2014 03:06, Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote:
> On Mon, Jun 02, 2014 at 06:36:22PM +0200, Philipp Zabel wrote:
>> Am Mittwoch, den 28.05.2014, 14:13 -0700 schrieb Greg Kroah-Hartman:
>> > On Mon, May 26, 2014 at 04:19:39PM +0200, Philipp Zabel wrote:
>> > > The i.MX Image Processing Unit (IPU) contains a number of image processing
>> > > blocks that sit right in the middle between DRM and V4L2. Some of the modules,
>> > > such as Display Controller, Processor, and Interface (DC, DP, DI) or CMOS
>> > > Sensor Interface (CSI) and their FIFOs could be assigned to either framework,
>> > > but others, such as the dma controller (IDMAC) and image converter (IC) can
>> > > be used by both.
>> > > The IPUv3 core driver provides an internal API to access the modules, to be
>> > > used by both DRM and V4L2 IPUv3 drivers.
>> > >
>> > > Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
>> > > Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
>> > > ---
>> > > Changes since RFC:
>> > > - Rebased onto current staging-next
>> > > - Removed an unrelated change to ipu_pixelformat_to_colorspace
>> > > - Avoided moving around the IPU_PIX_FMT_GBR24 #define
>> >
>> > Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>>
>> Thank you. My favourite next step would be to send a pull request and
>> have this merged into drm-next. Dave, Greg would you be ok with this?
>
> No objection from me, it's up to Dave what he wants for this.
Yes please send me a pull req for this.
Dave.
^ permalink raw reply
* [PATCH v3 0/7] OMAPDSS: Support multiple DPI instances
From: Archit Taneja @ 2014-06-04 6:52 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja
In-Reply-To: <1401096492-1405-1-git-send-email-archit@ti.com>
DSS on DRA7x has 3 DPI outputs. In order to get them to work. We need to make
the DPI driver support multiple DPI instances. We also need to tweak the
DT parsing done to match an encoder/connector/panel driver to find the
corresponding omapdss output. This series tries to achieve the above 2 tasks.
Changes in v3:
- Make indexes in port lists not depend on DPI and SDI CONFIGs.
- Cleaner code in dss_init_ports/uninit_ports.
- Split up the patch which creates multi DPI instances.
- Switch to a simpler way of extracting DPI driver data from dssdev.
- Change some of the dss-of fucntions, such that
omapdss_of_find_source_for_first_ep is simplified.
Archit Taneja (7):
OMAPDSS: DPI: Use DPI driver data
OMAPDSS: DPI: Allocate driver data
OMAPDSS: DPI: Store dpi_data pointer in the DT port's data
OMAPDSS: DSS: init dss ports cleanly
OMAPDSS: DT: Get source endpoint by matching reg-id
OMAPDSS: DPI: Add support for multiple instances
omapdss: DSS: add reg-id param to dpi_select_source
.../fbdev/omap2/displays-new/encoder-tfp410.c | 1 +
.../fbdev/omap2/displays-new/encoder-tpd12s015.c | 1 +
drivers/video/fbdev/omap2/dss/dpi.c | 259 ++++++++++++++-------
drivers/video/fbdev/omap2/dss/dss-of.c | 58 +++--
drivers/video/fbdev/omap2/dss/dss.c | 108 +++++++--
drivers/video/fbdev/omap2/dss/dss.h | 34 ++-
drivers/video/fbdev/omap2/dss/output.c | 19 +-
drivers/video/fbdev/omap2/dss/sdi.c | 2 +-
include/video/omapdss.h | 5 +-
9 files changed, 354 insertions(+), 133 deletions(-)
--
1.8.3.2
^ permalink raw reply
* [PATCH v3 1/7] OMAPDSS: DPI: Use DPI driver data
From: Archit Taneja @ 2014-06-04 6:52 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja
In-Reply-To: <1401864063-19196-1-git-send-email-archit@ti.com>
DPI related data is currently a static global struct parameter. It is accessed
directly by functions in the driver.
This method won't work if we want the driver to support multiple DPI instances.
Create struct dpi_data, and pass it's pointer to functions which need to use it.
We still have a static instance defined for dpi_data, which is accessed by top
level DPI ops. This will be removed when the driver dynamically allocates
dpi_data for each DPI instance.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/fbdev/omap2/dss/dpi.c | 187 +++++++++++++++++++++---------------
1 file changed, 107 insertions(+), 80 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
index 9368972..945d988 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -37,7 +37,7 @@
#include "dss.h"
#include "dss_features.h"
-static struct {
+struct dpi_data {
struct platform_device *pdev;
struct regulator *vdds_dsi_reg;
@@ -52,7 +52,9 @@ static struct {
struct omap_dss_device output;
bool port_initialized;
-} dpi;
+};
+
+static struct dpi_data dpi;
static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
{
@@ -200,15 +202,16 @@ static bool dpi_calc_dss_cb(unsigned long fck, void *data)
dpi_calc_dispc_cb, ctx);
}
-static bool dpi_dsi_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
+static bool dpi_dsi_clk_calc(struct dpi_data *dpi, unsigned long pck,
+ struct dpi_clk_calc_ctx *ctx)
{
unsigned long clkin;
unsigned long pll_min, pll_max;
- clkin = dsi_get_pll_clkin(dpi.dsidev);
+ clkin = dsi_get_pll_clkin(dpi->dsidev);
memset(ctx, 0, sizeof(*ctx));
- ctx->dsidev = dpi.dsidev;
+ ctx->dsidev = dpi->dsidev;
ctx->pck_min = pck - 1000;
ctx->pck_max = pck + 1000;
ctx->dsi_cinfo.clkin = clkin;
@@ -216,7 +219,7 @@ static bool dpi_dsi_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
pll_min = 0;
pll_max = 0;
- return dsi_pll_calc(dpi.dsidev, clkin,
+ return dsi_pll_calc(dpi->dsidev, clkin,
pll_min, pll_max,
dpi_calc_pll_cb, ctx);
}
@@ -252,7 +255,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
-static int dpi_set_dsi_clk(enum omap_channel channel,
+static int dpi_set_dsi_clk(struct dpi_data *dpi, enum omap_channel channel,
unsigned long pck_req, unsigned long *fck, int *lck_div,
int *pck_div)
{
@@ -260,18 +263,18 @@ static int dpi_set_dsi_clk(enum omap_channel channel,
int r;
bool ok;
- ok = dpi_dsi_clk_calc(pck_req, &ctx);
+ ok = dpi_dsi_clk_calc(dpi, pck_req, &ctx);
if (!ok)
return -EINVAL;
- r = dsi_pll_set_clock_div(dpi.dsidev, &ctx.dsi_cinfo);
+ r = dsi_pll_set_clock_div(dpi->dsidev, &ctx.dsi_cinfo);
if (r)
return r;
dss_select_lcd_clk_source(channel,
dpi_get_alt_clk_src(channel));
- dpi.mgr_config.clock_info = ctx.dispc_cinfo;
+ dpi->mgr_config.clock_info = ctx.dispc_cinfo;
*fck = ctx.dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
*lck_div = ctx.dispc_cinfo.lck_div;
@@ -280,8 +283,8 @@ static int dpi_set_dsi_clk(enum omap_channel channel,
return 0;
}
-static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
- int *lck_div, int *pck_div)
+static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req,
+ unsigned long *fck, int *lck_div, int *pck_div)
{
struct dpi_clk_calc_ctx ctx;
int r;
@@ -295,7 +298,7 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
if (r)
return r;
- dpi.mgr_config.clock_info = ctx.dispc_cinfo;
+ dpi->mgr_config.clock_info = ctx.dispc_cinfo;
*fck = ctx.fck;
*lck_div = ctx.dispc_cinfo.lck_div;
@@ -304,19 +307,21 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
return 0;
}
-static int dpi_set_mode(struct omap_overlay_manager *mgr)
+static int dpi_set_mode(struct dpi_data *dpi)
{
- struct omap_video_timings *t = &dpi.timings;
+ struct omap_dss_device *out = &dpi->output;
+ struct omap_overlay_manager *mgr = out->manager;
+ struct omap_video_timings *t = &dpi->timings;
int lck_div = 0, pck_div = 0;
unsigned long fck = 0;
unsigned long pck;
int r = 0;
- if (dpi.dsidev)
- r = dpi_set_dsi_clk(mgr->id, t->pixelclock, &fck,
+ if (dpi->dsidev)
+ r = dpi_set_dsi_clk(dpi, mgr->id, t->pixelclock, &fck,
&lck_div, &pck_div);
else
- r = dpi_set_dispc_clk(t->pixelclock, &fck,
+ r = dpi_set_dispc_clk(dpi, t->pixelclock, &fck,
&lck_div, &pck_div);
if (r)
return r;
@@ -335,28 +340,32 @@ static int dpi_set_mode(struct omap_overlay_manager *mgr)
return 0;
}
-static void dpi_config_lcd_manager(struct omap_overlay_manager *mgr)
+static void dpi_config_lcd_manager(struct dpi_data *dpi)
{
- dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
+ struct omap_dss_device *out = &dpi->output;
+ struct omap_overlay_manager *mgr = out->manager;
+
+ dpi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
- dpi.mgr_config.stallmode = false;
- dpi.mgr_config.fifohandcheck = false;
+ dpi->mgr_config.stallmode = false;
+ dpi->mgr_config.fifohandcheck = false;
- dpi.mgr_config.video_port_width = dpi.data_lines;
+ dpi->mgr_config.video_port_width = dpi->data_lines;
- dpi.mgr_config.lcden_sig_polarity = 0;
+ dpi->mgr_config.lcden_sig_polarity = 0;
- dss_mgr_set_lcd_config(mgr, &dpi.mgr_config);
+ dss_mgr_set_lcd_config(mgr, &dpi->mgr_config);
}
static int dpi_display_enable(struct omap_dss_device *dssdev)
{
- struct omap_dss_device *out = &dpi.output;
+ struct dpi_data *dpi = &dpi;
+ struct omap_dss_device *out = &dpi->output;
int r;
- mutex_lock(&dpi.lock);
+ mutex_lock(&dpi->lock);
- if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi.vdds_dsi_reg) {
+ if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi->vdds_dsi_reg) {
DSSERR("no VDSS_DSI regulator\n");
r = -ENODEV;
goto err_no_reg;
@@ -369,7 +378,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
}
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
- r = regulator_enable(dpi.vdds_dsi_reg);
+ r = regulator_enable(dpi->vdds_dsi_reg);
if (r)
goto err_reg_enable;
}
@@ -382,21 +391,21 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
if (r)
goto err_src_sel;
- if (dpi.dsidev) {
- r = dsi_runtime_get(dpi.dsidev);
+ if (dpi->dsidev) {
+ r = dsi_runtime_get(dpi->dsidev);
if (r)
goto err_get_dsi;
- r = dsi_pll_init(dpi.dsidev, 0, 1);
+ r = dsi_pll_init(dpi->dsidev, 0, 1);
if (r)
goto err_dsi_pll_init;
}
- r = dpi_set_mode(out->manager);
+ r = dpi_set_mode(dpi);
if (r)
goto err_set_mode;
- dpi_config_lcd_manager(out->manager);
+ dpi_config_lcd_manager(dpi);
mdelay(2);
@@ -404,78 +413,84 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
if (r)
goto err_mgr_enable;
- mutex_unlock(&dpi.lock);
+ mutex_unlock(&dpi->lock);
return 0;
err_mgr_enable:
err_set_mode:
- if (dpi.dsidev)
- dsi_pll_uninit(dpi.dsidev, true);
+ if (dpi->dsidev)
+ dsi_pll_uninit(dpi->dsidev, true);
err_dsi_pll_init:
- if (dpi.dsidev)
- dsi_runtime_put(dpi.dsidev);
+ if (dpi->dsidev)
+ dsi_runtime_put(dpi->dsidev);
err_get_dsi:
err_src_sel:
dispc_runtime_put();
err_get_dispc:
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
- regulator_disable(dpi.vdds_dsi_reg);
+ regulator_disable(dpi->vdds_dsi_reg);
err_reg_enable:
err_no_out_mgr:
err_no_reg:
- mutex_unlock(&dpi.lock);
+ mutex_unlock(&dpi->lock);
return r;
}
static void dpi_display_disable(struct omap_dss_device *dssdev)
{
- struct omap_overlay_manager *mgr = dpi.output.manager;
+ struct dpi_data *dpi = &dpi;
+ struct omap_overlay_manager *mgr = dpi->output.manager;
- mutex_lock(&dpi.lock);
+ mutex_lock(&dpi->lock);
dss_mgr_disable(mgr);
- if (dpi.dsidev) {
+ if (dpi->dsidev) {
dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
- dsi_pll_uninit(dpi.dsidev, true);
- dsi_runtime_put(dpi.dsidev);
+ dsi_pll_uninit(dpi->dsidev, true);
+ dsi_runtime_put(dpi->dsidev);
}
dispc_runtime_put();
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
- regulator_disable(dpi.vdds_dsi_reg);
+ regulator_disable(dpi->vdds_dsi_reg);
- mutex_unlock(&dpi.lock);
+ mutex_unlock(&dpi->lock);
}
static void dpi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
+ struct dpi_data *dpi = &dpi;
+
DSSDBG("dpi_set_timings\n");
- mutex_lock(&dpi.lock);
+ mutex_lock(&dpi->lock);
- dpi.timings = *timings;
+ dpi->timings = *timings;
- mutex_unlock(&dpi.lock);
+ mutex_unlock(&dpi->lock);
}
static void dpi_get_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
- mutex_lock(&dpi.lock);
+ struct dpi_data *dpi = &dpi;
+
+ mutex_lock(&dpi->lock);
- *timings = dpi.timings;
+ *timings = dpi->timings;
- mutex_unlock(&dpi.lock);
+ mutex_unlock(&dpi->lock);
}
static int dpi_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
- struct omap_overlay_manager *mgr = dpi.output.manager;
+ struct dpi_data *dpi = &dpi;
+ struct omap_overlay_manager *mgr = dpi->output.manager;
int lck_div, pck_div;
unsigned long fck;
unsigned long pck;
@@ -488,8 +503,8 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
if (timings->pixelclock = 0)
return -EINVAL;
- if (dpi.dsidev) {
- ok = dpi_dsi_clk_calc(timings->pixelclock, &ctx);
+ if (dpi->dsidev) {
+ ok = dpi_dsi_clk_calc(dpi, timings->pixelclock, &ctx);
if (!ok)
return -EINVAL;
@@ -514,11 +529,13 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
{
- mutex_lock(&dpi.lock);
+ struct dpi_data *dpi = &dpi;
- dpi.data_lines = data_lines;
+ mutex_lock(&dpi->lock);
- mutex_unlock(&dpi.lock);
+ dpi->data_lines = data_lines;
+
+ mutex_unlock(&dpi->lock);
}
static int dpi_verify_dsi_pll(struct platform_device *dsidev)
@@ -543,36 +560,36 @@ static int dpi_verify_dsi_pll(struct platform_device *dsidev)
return 0;
}
-static int dpi_init_regulator(void)
+static int dpi_init_regulator(struct dpi_data *dpi)
{
struct regulator *vdds_dsi;
if (!dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
return 0;
- if (dpi.vdds_dsi_reg)
+ if (dpi->vdds_dsi_reg)
return 0;
- vdds_dsi = devm_regulator_get(&dpi.pdev->dev, "vdds_dsi");
+ vdds_dsi = devm_regulator_get(&dpi->pdev->dev, "vdds_dsi");
if (IS_ERR(vdds_dsi)) {
if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
DSSERR("can't get VDDS_DSI regulator\n");
return PTR_ERR(vdds_dsi);
}
- dpi.vdds_dsi_reg = vdds_dsi;
+ dpi->vdds_dsi_reg = vdds_dsi;
return 0;
}
-static void dpi_init_pll(void)
+static void dpi_init_pll(struct dpi_data *dpi)
{
struct platform_device *dsidev;
- if (dpi.dsidev)
+ if (dpi->dsidev)
return;
- dsidev = dpi_get_dsidev(dpi.output.dispc_channel);
+ dsidev = dpi_get_dsidev(dpi->output.dispc_channel);
if (!dsidev)
return;
@@ -581,7 +598,7 @@ static void dpi_init_pll(void)
return;
}
- dpi.dsidev = dsidev;
+ dpi->dsidev = dsidev;
}
/*
@@ -618,14 +635,15 @@ static enum omap_channel dpi_get_channel(void)
static int dpi_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
+ struct dpi_data *dpi = &dpi;
struct omap_overlay_manager *mgr;
int r;
- r = dpi_init_regulator();
+ r = dpi_init_regulator(dpi);
if (r)
return r;
- dpi_init_pll();
+ dpi_init_pll(dpi);
mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
if (!mgr)
@@ -676,7 +694,8 @@ static const struct omapdss_dpi_ops dpi_ops = {
static void dpi_init_output(struct platform_device *pdev)
{
- struct omap_dss_device *out = &dpi.output;
+ struct dpi_data *dpi = &dpi;
+ struct omap_dss_device *out = &dpi->output;
out->dev = &pdev->dev;
out->id = OMAP_DSS_OUTPUT_DPI;
@@ -691,16 +710,21 @@ static void dpi_init_output(struct platform_device *pdev)
static void __exit dpi_uninit_output(struct platform_device *pdev)
{
- struct omap_dss_device *out = &dpi.output;
+ struct dpi_data *dpi = &dpi;
+ struct omap_dss_device *out = &dpi->output;
omapdss_unregister_output(out);
}
static int omap_dpi_probe(struct platform_device *pdev)
{
- dpi.pdev = pdev;
+ struct dpi_data *dpi = &dpi;
+
+ dpi->pdev = pdev;
- mutex_init(&dpi.lock);
+ dev_set_drvdata(&pdev->dev, dpi);
+
+ mutex_init(&dpi->lock);
dpi_init_output(pdev);
@@ -735,6 +759,7 @@ void __exit dpi_uninit_platform_driver(void)
int __init dpi_init_port(struct platform_device *pdev, struct device_node *port)
{
+ struct dpi_data *dpi = &dpi;
struct device_node *ep;
u32 datalines;
int r;
@@ -749,17 +774,17 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port)
goto err_datalines;
}
- dpi.data_lines = datalines;
+ dpi->data_lines = datalines;
of_node_put(ep);
- dpi.pdev = pdev;
+ dpi->pdev = pdev;
- mutex_init(&dpi.lock);
+ mutex_init(&dpi->lock);
dpi_init_output(pdev);
- dpi.port_initialized = true;
+ dpi->port_initialized = true;
return 0;
@@ -771,8 +796,10 @@ err_datalines:
void __exit dpi_uninit_port(void)
{
- if (!dpi.port_initialized)
+ struct dpi_data *dpi = &dpi;
+
+ if (!dpi->port_initialized)
return;
- dpi_uninit_output(dpi.pdev);
+ dpi_uninit_output(dpi->pdev);
}
--
1.8.3.2
^ permalink raw reply related
* [PATCH v3 2/7] OMAPDSS: DPI: Allocate driver data
From: Archit Taneja @ 2014-06-04 6:52 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja
In-Reply-To: <1401864063-19196-1-git-send-email-archit@ti.com>
Allocate driver data(dpi_data) for each DPI instance. It's allocated in
omap_dpi_probe() when DT isn't used, and in dpi_init_port() when DT is used.
The dpi_data struct instance is no longer global. In the case of DPI ops, it's
retrieved from dpi_get_data_from_dssdev(). 'dssdev' passed by the connected
encoder/panel driver is a pointer to the 'output' member in dpi_data, and thus
can be used to get the DPI instance's driver data. In the case of probe/ini_port
functions, it's set as DPI/DSS device's private data embedded in the
platform_device struct.
Having dpi_data as private data of the platform device will not work for
multiple DPI instances in the DT case. This is because there is no corresponding
platform_device for DPI or SDI, they exist only as ports under the parent DSS
platform_device in the DT case. The DPI port's private data('data' member in
device_node struct) will later be used to store dpi_data.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/fbdev/omap2/dss/dpi.c | 46 ++++++++++++++++++++++++++-----------
drivers/video/fbdev/omap2/dss/dss.c | 6 ++---
drivers/video/fbdev/omap2/dss/dss.h | 2 +-
3 files changed, 36 insertions(+), 18 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
index 945d988..9087619 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -54,7 +54,15 @@ struct dpi_data {
bool port_initialized;
};
-static struct dpi_data dpi;
+static struct dpi_data *dpi_get_data_from_dssdev(struct omap_dss_device *dssdev)
+{
+ return container_of(dssdev, struct dpi_data, output);
+}
+
+static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev)
+{
+ return dev_get_drvdata(&pdev->dev);
+}
static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
{
@@ -359,7 +367,7 @@ static void dpi_config_lcd_manager(struct dpi_data *dpi)
static int dpi_display_enable(struct omap_dss_device *dssdev)
{
- struct dpi_data *dpi = &dpi;
+ struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
struct omap_dss_device *out = &dpi->output;
int r;
@@ -439,7 +447,7 @@ err_no_reg:
static void dpi_display_disable(struct omap_dss_device *dssdev)
{
- struct dpi_data *dpi = &dpi;
+ struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
struct omap_overlay_manager *mgr = dpi->output.manager;
mutex_lock(&dpi->lock);
@@ -463,7 +471,7 @@ static void dpi_display_disable(struct omap_dss_device *dssdev)
static void dpi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
- struct dpi_data *dpi = &dpi;
+ struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
DSSDBG("dpi_set_timings\n");
@@ -477,7 +485,7 @@ static void dpi_set_timings(struct omap_dss_device *dssdev,
static void dpi_get_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
- struct dpi_data *dpi = &dpi;
+ struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
mutex_lock(&dpi->lock);
@@ -489,7 +497,7 @@ static void dpi_get_timings(struct omap_dss_device *dssdev,
static int dpi_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
- struct dpi_data *dpi = &dpi;
+ struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
struct omap_overlay_manager *mgr = dpi->output.manager;
int lck_div, pck_div;
unsigned long fck;
@@ -529,7 +537,7 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
{
- struct dpi_data *dpi = &dpi;
+ struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
mutex_lock(&dpi->lock);
@@ -635,7 +643,7 @@ static enum omap_channel dpi_get_channel(void)
static int dpi_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
- struct dpi_data *dpi = &dpi;
+ struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
struct omap_overlay_manager *mgr;
int r;
@@ -694,7 +702,7 @@ static const struct omapdss_dpi_ops dpi_ops = {
static void dpi_init_output(struct platform_device *pdev)
{
- struct dpi_data *dpi = &dpi;
+ struct dpi_data *dpi = dpi_get_data_from_pdev(pdev);
struct omap_dss_device *out = &dpi->output;
out->dev = &pdev->dev;
@@ -710,7 +718,7 @@ static void dpi_init_output(struct platform_device *pdev)
static void __exit dpi_uninit_output(struct platform_device *pdev)
{
- struct dpi_data *dpi = &dpi;
+ struct dpi_data *dpi = dpi_get_data_from_pdev(pdev);
struct omap_dss_device *out = &dpi->output;
omapdss_unregister_output(out);
@@ -718,7 +726,11 @@ static void __exit dpi_uninit_output(struct platform_device *pdev)
static int omap_dpi_probe(struct platform_device *pdev)
{
- struct dpi_data *dpi = &dpi;
+ struct dpi_data *dpi;
+
+ dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL);
+ if (!dpi)
+ return -ENOMEM;
dpi->pdev = pdev;
@@ -759,11 +771,15 @@ void __exit dpi_uninit_platform_driver(void)
int __init dpi_init_port(struct platform_device *pdev, struct device_node *port)
{
- struct dpi_data *dpi = &dpi;
+ struct dpi_data *dpi;
struct device_node *ep;
u32 datalines;
int r;
+ dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL);
+ if (!dpi)
+ return -ENOMEM;
+
ep = omapdss_of_get_next_endpoint(port, NULL);
if (!ep)
return 0;
@@ -786,6 +802,8 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port)
dpi->port_initialized = true;
+ dev_set_drvdata(&pdev->dev, dpi);
+
return 0;
err_datalines:
@@ -794,9 +812,9 @@ err_datalines:
return r;
}
-void __exit dpi_uninit_port(void)
+void __exit dpi_uninit_port(struct platform_device *pdev)
{
- struct dpi_data *dpi = &dpi;
+ struct dpi_data *dpi = dpi_get_data_from_pdev(pdev);
if (!dpi->port_initialized)
return;
diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c
index 6daeb7e..225b13f 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -820,10 +820,10 @@ static int __init dss_init_ports(struct platform_device *pdev)
return 0;
}
-static void __exit dss_uninit_ports(void)
+static void __exit dss_uninit_ports(struct platform_device *pdev)
{
#ifdef CONFIG_OMAP2_DSS_DPI
- dpi_uninit_port();
+ dpi_uninit_port(pdev);
#endif
#ifdef CONFIG_OMAP2_DSS_SDI
@@ -910,7 +910,7 @@ err_setup_clocks:
static int __exit omap_dsshw_remove(struct platform_device *pdev)
{
- dss_uninit_ports();
+ dss_uninit_ports(pdev);
pm_runtime_disable(&pdev->dev);
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index 8ff22c1..da7f5f9 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -359,7 +359,7 @@ int dpi_init_platform_driver(void) __init;
void dpi_uninit_platform_driver(void) __exit;
int dpi_init_port(struct platform_device *pdev, struct device_node *port) __init;
-void dpi_uninit_port(void) __exit;
+void dpi_uninit_port(struct platform_device *pdev) __exit;
/* DISPC */
int dispc_init_platform_driver(void) __init;
--
1.8.3.2
^ permalink raw reply related
* [PATCH v3 3/7] OMAPDSS: DPI: Store dpi_data pointer in the DT port's data
From: Archit Taneja @ 2014-06-04 6:52 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja
In-Reply-To: <1401864063-19196-1-git-send-email-archit@ti.com>
DPI and SDI ports are backed by only one parent DSS device. We don't have a
corresponding platform_device for ports under DSS. In order to support multiple
instances of DPI, we need to pass the driver data pointer through the DPI port's
private data ('data' member in device_node struct).
dpi_init_output/dpi_uninit_output are untouched and only used for non-DT case,
these are called when the DPI platform device probed/removed. These funcs will
be removed when non-DT mode is removed.
dpi_init_output_port/dpi_uninit_output_port are created and used for the DT
path, called when DSS inits/uninits it's ports. These new functions retrieve
the dpi_data pointer from 'port->data', and not from the platform device's
data(pdev->dev) like in the non-DT path.
We add some code in dss_uninit_ports() to pass a pointer to the DPI port in
dpi_uninit_port().
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/fbdev/omap2/dss/dpi.c | 36 ++++++++++++++++++++++++++++++------
drivers/video/fbdev/omap2/dss/dss.c | 13 ++++++++++++-
drivers/video/fbdev/omap2/dss/dss.h | 2 +-
3 files changed, 43 insertions(+), 8 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
index 9087619..b579022 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -59,6 +59,7 @@ static struct dpi_data *dpi_get_data_from_dssdev(struct omap_dss_device *dssdev)
return container_of(dssdev, struct dpi_data, output);
}
+/* only used in non-DT mode */
static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev)
{
return dev_get_drvdata(&pdev->dev);
@@ -724,6 +725,30 @@ static void __exit dpi_uninit_output(struct platform_device *pdev)
omapdss_unregister_output(out);
}
+static void dpi_init_output_port(struct platform_device *pdev,
+ struct device_node *port)
+{
+ struct dpi_data *dpi = port->data;
+ struct omap_dss_device *out = &dpi->output;
+
+ out->dev = &pdev->dev;
+ out->id = OMAP_DSS_OUTPUT_DPI;
+ out->output_type = OMAP_DISPLAY_TYPE_DPI;
+ out->dispc_channel = dpi_get_channel();
+ out->ops.dpi = &dpi_ops;
+ out->owner = THIS_MODULE;
+
+ omapdss_register_output(out);
+}
+
+static void __exit dpi_uninit_output_port(struct device_node *port)
+{
+ struct dpi_data *dpi = port->data;
+ struct omap_dss_device *out = &dpi->output;
+
+ omapdss_unregister_output(out);
+}
+
static int omap_dpi_probe(struct platform_device *pdev)
{
struct dpi_data *dpi;
@@ -795,15 +820,14 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port)
of_node_put(ep);
dpi->pdev = pdev;
+ port->data = dpi;
mutex_init(&dpi->lock);
- dpi_init_output(pdev);
+ dpi_init_output_port(pdev, port);
dpi->port_initialized = true;
- dev_set_drvdata(&pdev->dev, dpi);
-
return 0;
err_datalines:
@@ -812,12 +836,12 @@ err_datalines:
return r;
}
-void __exit dpi_uninit_port(struct platform_device *pdev)
+void __exit dpi_uninit_port(struct device_node *port)
{
- struct dpi_data *dpi = dpi_get_data_from_pdev(pdev);
+ struct dpi_data *dpi = port->data;
if (!dpi->port_initialized)
return;
- dpi_uninit_output(dpi->pdev);
+ dpi_uninit_output_port(port);
}
diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c
index 225b13f..bebb824 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -822,8 +822,19 @@ static int __init dss_init_ports(struct platform_device *pdev)
static void __exit dss_uninit_ports(struct platform_device *pdev)
{
+ struct device_node *parent = pdev->dev.of_node;
+ struct device_node *port;
+ int r;
+
+ if (parent = NULL)
+ return;
+
+ port = omapdss_of_get_next_port(parent, NULL);
+ if (!port)
+ return;
+
#ifdef CONFIG_OMAP2_DSS_DPI
- dpi_uninit_port(pdev);
+ dpi_uninit_port(port);
#endif
#ifdef CONFIG_OMAP2_DSS_SDI
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index da7f5f9..5b9db95 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -359,7 +359,7 @@ int dpi_init_platform_driver(void) __init;
void dpi_uninit_platform_driver(void) __exit;
int dpi_init_port(struct platform_device *pdev, struct device_node *port) __init;
-void dpi_uninit_port(struct platform_device *pdev) __exit;
+void dpi_uninit_port(struct device_node *port) __exit;
/* DISPC */
int dispc_init_platform_driver(void) __init;
--
1.8.3.2
^ permalink raw reply related
* [PATCH v3 4/7] OMAPDSS: DSS: init dss ports cleanly
From: Archit Taneja @ 2014-06-04 6:53 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja
In-Reply-To: <1401864063-19196-1-git-send-email-archit@ti.com>
The init/uninit port functions are used to set up the DPI and SDI outputs under
the dss platform device. A 'reg' property is used to determine whether the node
is DPI or SDI for OMAP34xx DSS revision. For other DSS revisions, only DPI
output exists.
For multiple DPI output instances(introduced in DRA7xx DSS), we would use the
'reg' property in dts to specify the DPI output instance.
The current functions work fine if there is only one DPI output instance in
DSS. For multiple DPI instances, it would get complicated to figure out whether
'reg' is used to specify whether the output is SDI, or another DPI instance.
We create a list of port types supported for each DSS rev, with the index of the
port in the list matching the reg id. This allows us to have a more generic way
to init/uninit ports within DSS, and support multiple DPI ports.
Also, make the uninit_port functions iterative since we will have multiple DPI
ports to uninit in the future.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/fbdev/omap2/dss/dss.c | 81 ++++++++++++++++++++++++++++++-------
drivers/video/fbdev/omap2/dss/dss.h | 26 +++++++++++-
drivers/video/fbdev/omap2/dss/sdi.c | 2 +-
3 files changed, 93 insertions(+), 16 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c
index bebb824..3b41953 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -70,6 +70,8 @@ struct dss_features {
u8 fck_div_max;
u8 dss_fck_multiplier;
const char *parent_clk_name;
+ enum omap_display_type *ports;
+ int num_ports;
int (*dpi_select_source)(enum omap_channel channel);
};
@@ -689,6 +691,16 @@ void dss_debug_dump_clocks(struct seq_file *s)
}
#endif
+
+static enum omap_display_type omap2plus_ports[] = {
+ OMAP_DISPLAY_TYPE_DPI,
+};
+
+static enum omap_display_type omap34xx_ports[] = {
+ OMAP_DISPLAY_TYPE_DPI,
+ OMAP_DISPLAY_TYPE_SDI,
+};
+
static const struct dss_features omap24xx_dss_feats __initconst = {
/*
* fck div max is really 16, but the divider range has gaps. The range
@@ -698,6 +710,8 @@ static const struct dss_features omap24xx_dss_feats __initconst = {
.dss_fck_multiplier = 2,
.parent_clk_name = "core_ck",
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
+ .ports = omap2plus_ports,
+ .num_ports = ARRAY_SIZE(omap2plus_ports),
};
static const struct dss_features omap34xx_dss_feats __initconst = {
@@ -705,6 +719,8 @@ static const struct dss_features omap34xx_dss_feats __initconst = {
.dss_fck_multiplier = 2,
.parent_clk_name = "dpll4_ck",
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
+ .ports = omap34xx_ports,
+ .num_ports = ARRAY_SIZE(omap34xx_ports),
};
static const struct dss_features omap3630_dss_feats __initconst = {
@@ -712,6 +728,8 @@ static const struct dss_features omap3630_dss_feats __initconst = {
.dss_fck_multiplier = 1,
.parent_clk_name = "dpll4_ck",
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
+ .ports = omap2plus_ports,
+ .num_ports = ARRAY_SIZE(omap2plus_ports),
};
static const struct dss_features omap44xx_dss_feats __initconst = {
@@ -719,6 +737,8 @@ static const struct dss_features omap44xx_dss_feats __initconst = {
.dss_fck_multiplier = 1,
.parent_clk_name = "dpll_per_x2_ck",
.dpi_select_source = &dss_dpi_select_source_omap4,
+ .ports = omap2plus_ports,
+ .num_ports = ARRAY_SIZE(omap2plus_ports),
};
static const struct dss_features omap54xx_dss_feats __initconst = {
@@ -726,6 +746,8 @@ static const struct dss_features omap54xx_dss_feats __initconst = {
.dss_fck_multiplier = 1,
.parent_clk_name = "dpll_per_x2_ck",
.dpi_select_source = &dss_dpi_select_source_omap5,
+ .ports = omap2plus_ports,
+ .num_ports = ARRAY_SIZE(omap2plus_ports),
};
static const struct dss_features am43xx_dss_feats __initconst = {
@@ -733,6 +755,8 @@ static const struct dss_features am43xx_dss_feats __initconst = {
.dss_fck_multiplier = 0,
.parent_clk_name = NULL,
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
+ .ports = omap2plus_ports,
+ .num_ports = ARRAY_SIZE(omap2plus_ports),
};
static int __init dss_init_features(struct platform_device *pdev)
@@ -798,23 +822,32 @@ static int __init dss_init_ports(struct platform_device *pdev)
if (!port)
return 0;
+ if (dss.feat->num_ports = 0)
+ return 0;
+
do {
+ enum omap_display_type port_type;
u32 reg;
r = of_property_read_u32(port, "reg", ®);
if (r)
reg = 0;
-#ifdef CONFIG_OMAP2_DSS_DPI
- if (reg = 0)
- dpi_init_port(pdev, port);
-#endif
+ if (reg >= dss.feat->num_ports)
+ continue;
-#ifdef CONFIG_OMAP2_DSS_SDI
- if (reg = 1)
- sdi_init_port(pdev, port);
-#endif
+ port_type = dss.feat->ports[reg];
+ switch (port_type) {
+ case OMAP_DISPLAY_TYPE_DPI:
+ dpi_init_port(pdev, port);
+ break;
+ case OMAP_DISPLAY_TYPE_SDI:
+ sdi_init_port(pdev, port);
+ break;
+ default:
+ break;
+ }
} while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
return 0;
@@ -833,13 +866,33 @@ static void __exit dss_uninit_ports(struct platform_device *pdev)
if (!port)
return;
-#ifdef CONFIG_OMAP2_DSS_DPI
- dpi_uninit_port(port);
-#endif
+ if (dss.feat->num_ports = 0)
+ return;
-#ifdef CONFIG_OMAP2_DSS_SDI
- sdi_uninit_port();
-#endif
+ do {
+ enum omap_display_type port_type;
+ u32 reg;
+
+ r = of_property_read_u32(port, "reg", ®);
+ if (r)
+ reg = 0;
+
+ if (reg >= dss.feat->num_ports)
+ continue;
+
+ port_type = dss.feat->ports[reg];
+
+ switch (port_type) {
+ case OMAP_DISPLAY_TYPE_DPI:
+ dpi_uninit_port(port);
+ break;
+ case OMAP_DISPLAY_TYPE_SDI:
+ sdi_uninit_port(port);
+ break;
+ default:
+ break;
+ }
+ } while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
}
/* DSS HW IP initialisation */
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index 5b9db95..f0d3e82 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -244,8 +244,20 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min,
int sdi_init_platform_driver(void) __init;
void sdi_uninit_platform_driver(void) __exit;
+#ifdef CONFIG_OMAP2_DSS_SDI
int sdi_init_port(struct platform_device *pdev, struct device_node *port) __init;
-void sdi_uninit_port(void) __exit;
+void sdi_uninit_port(struct device_node *port) __exit;
+#else
+static inline int __init sdi_init_port(struct platform_device *pdev,
+ struct device_node *port)
+{
+ WARN("%s: SDI not compiled in\n", __func__);
+ return 0;
+}
+static inline void __exit sdi_uninit_port(struct device_node *port)
+{
+}
+#endif
/* DSI */
@@ -358,8 +370,20 @@ static inline bool dsi_pll_calc(struct platform_device *dsidev,
int dpi_init_platform_driver(void) __init;
void dpi_uninit_platform_driver(void) __exit;
+#ifdef CONFIG_OMAP2_DSS_DPI
int dpi_init_port(struct platform_device *pdev, struct device_node *port) __init;
void dpi_uninit_port(struct device_node *port) __exit;
+#else
+static inline int __init dpi_init_port(struct platform_device *pdev,
+ struct device_node *port)
+{
+ WARN("%s: DPI not compiled in\n", __func__);
+ return 0;
+}
+static inline void __exit dpi_uninit_port(struct device_node *port)
+{
+}
+#endif
/* DISPC */
int dispc_init_platform_driver(void) __init;
diff --git a/drivers/video/fbdev/omap2/dss/sdi.c b/drivers/video/fbdev/omap2/dss/sdi.c
index 911dcc9..72f89db 100644
--- a/drivers/video/fbdev/omap2/dss/sdi.c
+++ b/drivers/video/fbdev/omap2/dss/sdi.c
@@ -424,7 +424,7 @@ err_datapairs:
return r;
}
-void __exit sdi_uninit_port(void)
+void __exit sdi_uninit_port(struct device_node *port)
{
if (!sdi.port_initialized)
return;
--
1.8.3.2
^ permalink raw reply related
* [PATCH v3 5/7] OMAPDSS: DT: Get source endpoint by matching reg-id
From: Archit Taneja @ 2014-06-04 6:53 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja
In-Reply-To: <1401864063-19196-1-git-send-email-archit@ti.com>
In omapdss_of_find_source_for_first_ep, we retrieve a source endpoint's DT node,
and then see what omapdss output has the matching device_node pointer in
omap_dss_find_output_by_node.
For all DPI and SDI outputs, the device_node pointer is set as the parent's DSS
device_node pointer. If the source is one of these outputs, the above method
won't work.
To get the correct output for ports within DSS(and in other cases in the future,
where multiple ports might be under one device), we require additional
information which is exclusive to the output port.
We create a new field in omap_dss_device called 'port_num', this provides port
number of the output port corresponding to this device. When searching for the
source endpoint in DT, we extract the 'reg' property from the port corresponding
to the endpoint source. From the list of registered outputs, we pick out that
output which has both dev->of_node and port_num matching with the device_node
pointer and 'reg' of the source endpoint node from DT.
For encoder blocks(the ones which have both an input and output port), we need
to set the port_num as the 'reg' property for the output port as defined in the
DT bindings. We set port_num to 1 in the tfp410 and tpd12s015 encoder drivers.
Signed-off-by: Archit Taneja <archit@ti.com>
---
.../fbdev/omap2/displays-new/encoder-tfp410.c | 1 +
.../fbdev/omap2/displays-new/encoder-tpd12s015.c | 1 +
drivers/video/fbdev/omap2/dss/dss-of.c | 58 +++++++++++++++-------
drivers/video/fbdev/omap2/dss/dss.h | 4 ++
drivers/video/fbdev/omap2/dss/output.c | 19 +++++--
include/video/omapdss.h | 5 +-
6 files changed, 66 insertions(+), 22 deletions(-)
diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
index b4e9a42..d927455 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
@@ -249,6 +249,7 @@ static int tfp410_probe(struct platform_device *pdev)
dssdev->output_type = OMAP_DISPLAY_TYPE_DVI;
dssdev->owner = THIS_MODULE;
dssdev->phy.dpi.data_lines = ddata->data_lines;
+ dssdev->port_num = 1;
r = omapdss_register_output(dssdev);
if (r) {
diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
index 7e33686..9e25fe7 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
@@ -389,6 +389,7 @@ static int tpd_probe(struct platform_device *pdev)
dssdev->type = OMAP_DISPLAY_TYPE_HDMI;
dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI;
dssdev->owner = THIS_MODULE;
+ dssdev->port_num = 1;
in = ddata->in;
diff --git a/drivers/video/fbdev/omap2/dss/dss-of.c b/drivers/video/fbdev/omap2/dss/dss-of.c
index a4b20aa..928ee63 100644
--- a/drivers/video/fbdev/omap2/dss/dss-of.c
+++ b/drivers/video/fbdev/omap2/dss/dss-of.c
@@ -20,6 +20,8 @@
#include <video/omapdss.h>
+#include "dss.h"
+
struct device_node *
omapdss_of_get_next_port(const struct device_node *parent,
struct device_node *prev)
@@ -84,20 +86,17 @@ omapdss_of_get_next_endpoint(const struct device_node *parent,
}
EXPORT_SYMBOL_GPL(omapdss_of_get_next_endpoint);
-static struct device_node *
-omapdss_of_get_remote_device_node(const struct device_node *node)
+struct device_node *dss_of_port_get_parent_device(struct device_node *port)
{
struct device_node *np;
int i;
- np = of_parse_phandle(node, "remote-endpoint", 0);
-
- if (!np)
+ if (!port)
return NULL;
- np = of_get_next_parent(np);
+ np = of_get_next_parent(port);
- for (i = 0; i < 3 && np; ++i) {
+ for (i = 0; i < 2 && np; ++i) {
struct property *prop;
prop = of_find_property(np, "compatible", NULL);
@@ -111,6 +110,31 @@ omapdss_of_get_remote_device_node(const struct device_node *node)
return NULL;
}
+u32 dss_of_port_get_port_number(struct device_node *port)
+{
+ int r;
+ u32 reg;
+
+ r = of_property_read_u32(port, "reg", ®);
+ if (r)
+ reg = 0;
+
+ return reg;
+}
+
+static struct device_node *omapdss_of_get_remote_port(const struct device_node *node)
+{
+ struct device_node *np;
+
+ np = of_parse_phandle(node, "remote-endpoint", 0);
+ if (!np)
+ return NULL;
+
+ np = of_get_next_parent(np);
+
+ return np;
+}
+
struct device_node *
omapdss_of_get_first_endpoint(const struct device_node *parent)
{
@@ -133,27 +157,25 @@ struct omap_dss_device *
omapdss_of_find_source_for_first_ep(struct device_node *node)
{
struct device_node *ep;
- struct device_node *src_node;
+ struct device_node *src_port;
struct omap_dss_device *src;
ep = omapdss_of_get_first_endpoint(node);
if (!ep)
return ERR_PTR(-EINVAL);
- src_node = omapdss_of_get_remote_device_node(ep);
-
- of_node_put(ep);
-
- if (!src_node)
+ src_port = omapdss_of_get_remote_port(ep);
+ if (!src_port) {
+ of_node_put(ep);
return ERR_PTR(-EINVAL);
+ }
- src = omap_dss_find_output_by_node(src_node);
+ of_node_put(ep);
- of_node_put(src_node);
+ src = omap_dss_find_output_by_port_node(src_port);
- if (!src)
- return ERR_PTR(-EPROBE_DEFER);
+ of_node_put(src_port);
- return src;
+ return src ? src : ERR_PTR(-EPROBE_DEFER);
}
EXPORT_SYMBOL_GPL(omapdss_of_find_source_for_first_ep);
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index f0d3e82..849ede1 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -215,6 +215,10 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
void dss_dump_clocks(struct seq_file *s);
+/* dss-of */
+struct device_node *dss_of_port_get_parent_device(struct device_node *port);
+u32 dss_of_port_get_port_number(struct device_node *port);
+
#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
void dss_debug_dump_clocks(struct seq_file *s);
#endif
diff --git a/drivers/video/fbdev/omap2/dss/output.c b/drivers/video/fbdev/omap2/dss/output.c
index 2ab3afa..1607215 100644
--- a/drivers/video/fbdev/omap2/dss/output.c
+++ b/drivers/video/fbdev/omap2/dss/output.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <linux/of.h>
#include <video/omapdss.h>
@@ -131,18 +132,30 @@ struct omap_dss_device *omap_dss_find_output(const char *name)
}
EXPORT_SYMBOL(omap_dss_find_output);
-struct omap_dss_device *omap_dss_find_output_by_node(struct device_node *node)
+struct omap_dss_device *omap_dss_find_output_by_port_node(struct device_node *port)
{
+ struct device_node *src_node;
struct omap_dss_device *out;
+ u32 reg;
+
+ src_node = dss_of_port_get_parent_device(port);
+ if (!src_node)
+ return NULL;
+
+ reg = dss_of_port_get_port_number(port);
list_for_each_entry(out, &output_list, list) {
- if (out->dev->of_node = node)
+ if (out->dev->of_node = src_node && out->port_num = reg) {
+ of_node_put(src_node);
return omap_dss_get_device(out);
+ }
}
+ of_node_put(src_node);
+
return NULL;
}
-EXPORT_SYMBOL(omap_dss_find_output_by_node);
+EXPORT_SYMBOL(omap_dss_find_output_by_port_node);
struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev)
{
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index fc06c5b..ec0dc29 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -790,6 +790,9 @@ struct omap_dss_device {
/* output instance */
enum omap_dss_output_id id;
+ /* the port number in the DT node */
+ int port_num;
+
/* dynamic fields */
struct omap_overlay_manager *manager;
@@ -909,7 +912,7 @@ int omapdss_register_output(struct omap_dss_device *output);
void omapdss_unregister_output(struct omap_dss_device *output);
struct omap_dss_device *omap_dss_get_output(enum omap_dss_output_id id);
struct omap_dss_device *omap_dss_find_output(const char *name);
-struct omap_dss_device *omap_dss_find_output_by_node(struct device_node *node);
+struct omap_dss_device *omap_dss_find_output_by_port_node(struct device_node *port);
int omapdss_output_set_device(struct omap_dss_device *out,
struct omap_dss_device *dssdev);
int omapdss_output_unset_device(struct omap_dss_device *out);
--
1.8.3.2
^ permalink raw reply related
* [PATCH v3 6/7] OMAPDSS: DPI: Add support for multiple instances
From: Archit Taneja @ 2014-06-04 6:53 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja
In-Reply-To: <1401864063-19196-1-git-send-email-archit@ti.com>
Register DPI outputs, and assign the port_num to them as specified by the
'reg' property in the DPI ports in DT.
To support multiple DPI instances, dpi_get_channel needs to take the DPI
instance's reg-id to get the corresponding channel. Make it take this
argument.We just pass 0 in the non-DT path, since we don't support multiple
instances in the non-DT case.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/fbdev/omap2/dss/dpi.c | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
index b579022..3e204a8 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -616,7 +616,7 @@ static void dpi_init_pll(struct dpi_data *dpi)
* the channel in some more dynamic manner, or get the channel as a user
* parameter.
*/
-static enum omap_channel dpi_get_channel(void)
+static enum omap_channel dpi_get_channel(int reg)
{
switch (omapdss_get_version()) {
case OMAPDSS_VER_OMAP24xx:
@@ -710,7 +710,7 @@ static void dpi_init_output(struct platform_device *pdev)
out->id = OMAP_DSS_OUTPUT_DPI;
out->output_type = OMAP_DISPLAY_TYPE_DPI;
out->name = "dpi.0";
- out->dispc_channel = dpi_get_channel();
+ out->dispc_channel = dpi_get_channel(0);
out->ops.dpi = &dpi_ops;
out->owner = THIS_MODULE;
@@ -730,11 +730,31 @@ static void dpi_init_output_port(struct platform_device *pdev,
{
struct dpi_data *dpi = port->data;
struct omap_dss_device *out = &dpi->output;
+ int r;
+ u32 reg;
+
+ r = of_property_read_u32(port, "reg", ®);
+ if (r)
+ reg = 0;
+
+ switch (reg) {
+ case 2:
+ out->name = "dpi.2";
+ break;
+ case 1:
+ out->name = "dpi.1";
+ break;
+ case 0:
+ default:
+ out->name = "dpi.0";
+ break;
+ }
out->dev = &pdev->dev;
out->id = OMAP_DSS_OUTPUT_DPI;
out->output_type = OMAP_DISPLAY_TYPE_DPI;
- out->dispc_channel = dpi_get_channel();
+ out->dispc_channel = dpi_get_channel(reg);
+ out->port_num = reg;
out->ops.dpi = &dpi_ops;
out->owner = THIS_MODULE;
--
1.8.3.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox