[PATCH v7 1/5] staging/android: add num_fences field to struct sync_file_info

2016-03-30 Thread Gustavo Padovan
Hi Greg,

2016-03-30 Greg Kroah-Hartman :

> On Thu, Mar 03, 2016 at 04:40:42PM -0300, Gustavo Padovan wrote:
> > From: Gustavo Padovan 
> 
> 
> 
> Gustavo, can you resend both series of your android patches so I know I
> have the latest ones to work with?  Please also collect the acks that
> people have provided so far.

I have resent it already. The lastest patches on this series is v10,
it contain the acks

https://lkml.org/lkml/2016/3/18/298

Gustavo


[Bug 94445] Tonga llvm assert since RegisterCoalescer: Need to check DstReg+SrcReg for missing undef flags

2016-03-30 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=94445

--- Comment #7 from Andy Furniss  ---
Working for me with current llvm/mesa.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160330/077ec17b/attachment.html>


[PATCH v5 00/46] pwm: add support for atomic update

2016-03-30 Thread Boris Brezillon
+Doug (sorry, I forgot to add you in to the recipient list)

On Wed, 30 Mar 2016 22:03:23 +0200
Boris Brezillon  wrote:

> Hello,
> 
> This series adds support for atomic PWM update, or IOW, the capability
> to update all the parameters of a PWM device (enabled/disabled, period,
> duty and polarity) in one go.
> 
> It also adds support for initial PWM state retrieval (or hardware readout),
> which should allow smooth handover between the bootloader and Linux. For
> example, critical PWM users (like critical regulators controlled by a PWM)
> can query the current PWM state, and adapt the PWM config without having
> to disable/enable the PWM, or abruptly change the period/dutycyle/polarity
> config.
> 
> Thierry, I hope this version meets your expectations, if that's not the
> case, could you let me know quickly so I can adjust the implementation
> accordingly (I'd really like to get most of those changes in 4.7).

Oh, I forgot to mention that I'm not necessarily expecting all those
patches to be taken in one go. We only need patches 1 to 31 for the
problem exposed by Doug. Patch 32 is deprecating the non-atomic APIs and
patches 33 to 46 are switching all PWM users to the atomic APIs to avoid
compilation warnings.
It's up to you to decide which you'd like to take.

> 
> Best Regards,
> 
> Boris
> 
> Changes since v4:
> - introduce pwm_args to expose per-board/platform config
> - deprecate non-atomic APIs
> - implement non-atomic functions as wrappers around atomic ones
> - patch all PWM users to use the atomic API
> - rename the ->reset_state() hook into ->get_state()
> - drop most acks
> - rework PWM config in the pwm-regulator driver
> - patch sun4i and sti PWM drivers to support HW readout
> 
> Changes since v3:
> - rebased on pwm/for-next after pulling 4.4-rc1
> - replace direct access to pwm fields by pwm_get/set_xxx() helpers, thus
>   fixing some build errors
> - split changes to allow each maintainer to review/ack or take the
>   modification through its subsystem
> 
> Changes since v2:
> - rebased on top of 4.3-rc2
> - reintroduced pwm-regulator patches
> 
> Changes since v1:
> - dropped applied patches
> - squashed Heiko's fixes into the rockchip driver changes
> - made a few cosmetic changes
> - added kerneldoc comments
> - added Heiko's patch to display more information in debugfs
> - dropped pwm-regulator patches (should be submitted separately)
> 
> *** BLURB HERE ***
> 
> Boris Brezillon (45):
>   pwm: rcar: make use of pwm_is_enabled()
>   backlight: pwm_bl: remove useless call to pwm_set_period()
>   backlight: lm3630a_bl: stop messing with the pwm->period field
>   pwm: get rid of pwm->lock
>   pwm: introduce the pwm_args concept
>   pwm: use pwm_get/set_xxx() helpers where appropriate
>   clk: pwm: use pwm_get_args() where appropriate
>   hwmon: pwm-fan: use pwm_get_args() where appropriate
>   misc: max77693-haptic: use pwm_get_args() where appropriate
>   leds: pwm: use pwm_get_args() where appropriate
>   regulator: pwm: use pwm_get_args() where appropriate
>   fbdev: ssd1307fb: use pwm_get_args() where appropriate
>   backlight: pwm_bl: use pwm_get_args() where appropriate
>   pwm: keep PWM state in sync with hardware state
>   pwm: introduce the pwm_state concept
>   pwm: move the enabled/disabled info into pwm_state
>   pwm: add the PWM initial state retrieval infra
>   pwm: add the core infrastructure to allow atomic update
>   pwm: switch to the atomic API
>   pwm: rockchip: add initial state retrieval
>   pwm: rockchip: avoid glitches on already running PWMs
>   pwm: rockchip: add support for atomic update
>   pwm: sti: add support for initial state retrieval
>   pwm: sti: avoid glitches on already running PWMs
>   pwm: sun4i: implement hardware readout
>   regulator: pwm: adjust PWM config at probe time
>   regulator: pwm: swith to the atomic PWM API
>   regulator: pwm: properly initialize the ->state field
>   regulator: pwm: retrieve correct voltage
>   pwm: update documentation
>   pwm: deprecate pwm_config(), pwm_enable() and pwm_disable()
>   pwm: replace pwm_disable() by pwm_apply_state()
>   clk: pwm: switch to the atomic API
>   hwmon: pwm-fan: switch to the atomic API
>   input: misc: max77693: switch to the atomic API
>   input: misc: max8997: switch to the atomic PWM API
>   input: misc: pwm-beeper: switch to the atomic PWM API
>   leds: pwm: switch to the atomic PWM API
>   backlight: lm3630a: switch to the atomic PWM API
>   backlight: lp855x: switch to the atomic PWM API
>   backlight: lp8788: switch to the atomic PWM API
>   backlight: pwm_bl: switch to the atomic PWM API
>   video: ssd1307fb: switch to the atomic PWM API
>   drm: i915: switch to the atomic PWM API
>   ARM: s3c24xx: rx1950: switch to the atomic PWM API
> 
> Heiko Stübner (1):
>   pwm: add information about polarity, duty cycle and period to debugfs
> 
>  Documentation/pwm.txt|  27 +++-
>  arch/arm/mach-s3c24xx/mach-rx1950.c  |  17 +-
>  drivers/clk/clk-pwm.c|  36 ++

[PATCH v5 46/46] ARM: s3c24xx: rx1950: switch to the atomic PWM API

2016-03-30 Thread Boris Brezillon
Replace pwm_disable/enable/config() by pwm_apply_state().

Signed-off-by: Boris Brezillon 
---
 arch/arm/mach-s3c24xx/mach-rx1950.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c 
b/arch/arm/mach-s3c24xx/mach-rx1950.c
index 774c982..2dc9487 100644
--- a/arch/arm/mach-s3c24xx/mach-rx1950.c
+++ b/arch/arm/mach-s3c24xx/mach-rx1950.c
@@ -384,10 +384,15 @@ static struct pwm_device *lcd_pwm;

 static void rx1950_lcd_power(int enable)
 {
+   struct pwm_state pstate;
int i;
static int enabled;
+
if (enabled == enable)
return;
+
+   pwm_get_state(lcd_pwm, &pstate);
+
if (!enable) {

/* GPC11-GPC15->OUTPUT */
@@ -433,15 +438,21 @@ static void rx1950_lcd_power(int enable)

/* GPB1->OUTPUT, GPB1->0 */
gpio_direction_output(S3C2410_GPB(1), 0);
-   pwm_config(lcd_pwm, 0, LCD_PWM_PERIOD);
+
+   pstate.enabled = false;
+   pstate.period = LCD_PWM_PERIOD;
+   pstate.duty_cycle = 0;
+   pwm_apply_state(lcd_pwm, &pstate);
pwm_disable(lcd_pwm);

/* GPC0->0, GPC10->0 */
gpio_direction_output(S3C2410_GPC(0), 0);
gpio_direction_output(S3C2410_GPC(10), 0);
} else {
-   pwm_config(lcd_pwm, LCD_PWM_DUTY, LCD_PWM_PERIOD);
-   pwm_enable(lcd_pwm);
+   pstate.enabled = true;
+   pstate.period = LCD_PWM_PERIOD;
+   pstate.duty_cycle = LCD_PWM_DUTY;
+   pwm_apply_state(lcd_pwm, &pstate);

gpio_direction_output(S3C2410_GPC(0), 1);
gpio_direction_output(S3C2410_GPC(5), 1);
-- 
2.5.0



[PATCH v5 45/46] drm: i915: switch to the atomic PWM API

2016-03-30 Thread Boris Brezillon
pwm_config/enable/disable() have been deprecated and should be replaced
by pwm_apply_state().

Signed-off-by: Boris Brezillon 
---
 drivers/gpu/drm/i915/intel_panel.c | 39 +-
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_panel.c 
b/drivers/gpu/drm/i915/intel_panel.c
index 21ee647..b86bd20 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -538,10 +538,10 @@ static u32 bxt_get_backlight(struct intel_connector 
*connector)
 static u32 pwm_get_backlight(struct intel_connector *connector)
 {
struct intel_panel *panel = &connector->panel;
-   int duty_ns;
+   struct pwm_state pstate;

-   duty_ns = pwm_get_duty_cycle(panel->backlight.pwm);
-   return DIV_ROUND_UP(duty_ns * 100, CRC_PMIC_PWM_PERIOD_NS);
+   pwm_get_state(panel->backlight.pwm, &pstate);
+   return DIV_ROUND_UP(pstate.duty_cycle * 100, CRC_PMIC_PWM_PERIOD_NS);
 }

 static u32 intel_panel_get_backlight(struct intel_connector *connector)
@@ -630,9 +630,12 @@ static void bxt_set_backlight(struct intel_connector 
*connector, u32 level)
 static void pwm_set_backlight(struct intel_connector *connector, u32 level)
 {
struct intel_panel *panel = &connector->panel;
-   int duty_ns = DIV_ROUND_UP(level * CRC_PMIC_PWM_PERIOD_NS, 100);
+   struct pwm_state pstate;

-   pwm_config(panel->backlight.pwm, duty_ns, CRC_PMIC_PWM_PERIOD_NS);
+   pwm_get_state(panel->backlight.pwm, &pstate);
+   pstate.duty_cycle = DIV_ROUND_UP(level * CRC_PMIC_PWM_PERIOD_NS, 100);
+   pstate.period = CRC_PMIC_PWM_PERIOD_NS;
+   pwm_apply_state(panel->backlight.pwm, &pstate);
 }

 static void
@@ -801,11 +804,15 @@ static void bxt_disable_backlight(struct intel_connector 
*connector)
 static void pwm_disable_backlight(struct intel_connector *connector)
 {
struct intel_panel *panel = &connector->panel;
+   struct pwm_state pstate;

/* Disable the backlight */
-   pwm_config(panel->backlight.pwm, 0, CRC_PMIC_PWM_PERIOD_NS);
+   pwm_get_state(panel->backlight.pwm, &pstate);
+   pstate.duty_cycle = 0;
+   pwm_apply_state(panel->backlight.pwm, &pstate);
usleep_range(2000, 3000);
-   pwm_disable(panel->backlight.pwm);
+   pstate.enabled = false;
+   pwm_apply_state(panel->backlight.pwm, &pstate);
 }

 void intel_panel_disable_backlight(struct intel_connector *connector)
@@ -1068,8 +1075,11 @@ static void bxt_enable_backlight(struct intel_connector 
*connector)
 static void pwm_enable_backlight(struct intel_connector *connector)
 {
struct intel_panel *panel = &connector->panel;
+   struct pwm_state pstate;

-   pwm_enable(panel->backlight.pwm);
+   pwm_get_state(panel->backlight.pwm, &pstate);
+   pstate.enabled = true;
+   pwm_apply_state(panel->backlight.pwm, &pstate);
intel_panel_actually_set_backlight(connector, panel->backlight.level);
 }

@@ -1630,6 +1640,7 @@ static int pwm_setup_backlight(struct intel_connector 
*connector,
 {
struct drm_device *dev = connector->base.dev;
struct intel_panel *panel = &connector->panel;
+   struct pwm_state pstate;
int retval;

/* Get the PWM chip for backlight control */
@@ -1640,8 +1651,10 @@ static int pwm_setup_backlight(struct intel_connector 
*connector,
return -ENODEV;
}

-   retval = pwm_config(panel->backlight.pwm, CRC_PMIC_PWM_PERIOD_NS,
-   CRC_PMIC_PWM_PERIOD_NS);
+   pwm_get_state(panel->backlight.pwm, &pstate);
+   pstate.period = CRC_PMIC_PWM_PERIOD_NS;
+   pstate.duty_cycle = CRC_PMIC_PWM_PERIOD_NS;
+   retval = pwm_apply_state(panel->backlight.pwm, &pstate);
if (retval < 0) {
DRM_ERROR("Failed to configure the pwm chip\n");
pwm_put(panel->backlight.pwm);
@@ -1651,9 +1664,9 @@ static int pwm_setup_backlight(struct intel_connector 
*connector,

panel->backlight.min = 0; /* 0% */
panel->backlight.max = 100; /* 100% */
-   panel->backlight.level = DIV_ROUND_UP(
-pwm_get_duty_cycle(panel->backlight.pwm) * 100,
-CRC_PMIC_PWM_PERIOD_NS);
+   pwm_get_state(panel->backlight.pwm, &pstate);
+   panel->backlight.level = DIV_ROUND_UP(pstate.duty_cycle * 100,
+ pstate.period);
panel->backlight.enabled = panel->backlight.level != 0;

return 0;
-- 
2.5.0



[PATCH v5 44/46] video: ssd1307fb: switch to the atomic PWM API

2016-03-30 Thread Boris Brezillon
pwm_config/enable/disable() have been deprecated and should be replaced
by pwm_apply_state().

Signed-off-by: Boris Brezillon 
---
 drivers/video/fbdev/ssd1307fb.c | 24 +++-
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c
index df9c63a..ed9a115 100644
--- a/drivers/video/fbdev/ssd1307fb.c
+++ b/drivers/video/fbdev/ssd1307fb.c
@@ -289,6 +289,8 @@ static int ssd1307fb_init(struct ssd1307fb_par *par)
struct pwm_args pargs = { };

if (par->device_info->need_pwm) {
+   struct pwm_state pstate;
+
par->pwm = pwm_get(&par->client->dev, NULL);
if (IS_ERR(par->pwm)) {
dev_err(&par->client->dev, "Could not get PWM from 
device tree!\n");
@@ -296,10 +298,14 @@ static int ssd1307fb_init(struct ssd1307fb_par *par)
}

pwm_get_args(par->pwm, &pargs);
+   pwm_get_state(par->pwm, &pstate);
par->pwm_period = pargs.period;
+
/* Enable the PWM */
-   pwm_config(par->pwm, par->pwm_period / 2, par->pwm_period);
-   pwm_enable(par->pwm);
+   pstate.period = pargs.period;
+   pstate.duty_cycle = pstate.period / 2;
+   pstate.enabled = true;
+   pwm_apply_state(par->pwm, &pstate);

dev_dbg(&par->client->dev, "Using PWM%d with a %dns period.\n",
par->pwm->pwm, par->pwm_period);
@@ -685,8 +691,12 @@ static int ssd1307fb_probe(struct i2c_client *client,
 bl_init_error:
unregister_framebuffer(info);
 panel_init_error:
-   if (par->device_info->need_pwm) {
-   pwm_disable(par->pwm);
+   if (par->device_info->need_pwm && par->pwm) {
+   struct pwm_state pstate;
+
+   pwm_get_state(par->pwm, &pstate);
+   pstate.enabled = false;
+   pwm_apply_state(par->pwm, &pstate);
pwm_put(par->pwm);
};
 reset_oled_error:
@@ -707,7 +717,11 @@ static int ssd1307fb_remove(struct i2c_client *client)

unregister_framebuffer(info);
if (par->device_info->need_pwm) {
-   pwm_disable(par->pwm);
+   struct pwm_state pstate;
+
+   pwm_get_state(par->pwm, &pstate);
+   pstate.enabled = false;
+   pwm_apply_state(par->pwm, &pstate);
pwm_put(par->pwm);
};
fb_deferred_io_cleanup(info);
-- 
2.5.0



[PATCH v5 43/46] backlight: pwm_bl: switch to the atomic PWM API

2016-03-30 Thread Boris Brezillon
pwm_config/enable/disable() have been deprecated and should be replaced
by pwm_apply_state().

Signed-off-by: Boris Brezillon 
---
 drivers/video/backlight/pwm_bl.c | 43 ++--
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 2479c11..b069fb2 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -43,8 +43,22 @@ struct pwm_bl_data {
void(*exit)(struct device *);
 };

+static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness)
+{
+   unsigned int lth = pb->lth_brightness;
+   int duty_cycle;
+
+   if (pb->levels)
+   duty_cycle = pb->levels[brightness];
+   else
+   duty_cycle = brightness;
+
+   return (duty_cycle * (pb->period - lth) / pb->scale) + lth;
+}
+
 static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness)
 {
+   struct pwm_state pstate;
int err;

if (pb->enabled)
@@ -57,17 +71,24 @@ static void pwm_backlight_power_on(struct pwm_bl_data *pb, 
int brightness)
if (pb->enable_gpio)
gpiod_set_value(pb->enable_gpio, 1);

-   pwm_enable(pb->pwm);
+   pwm_get_state(pb->pwm, &pstate);
+   pstate.duty_cycle = compute_duty_cycle(pb, brightness);
+   pstate.enabled = true;
+   pwm_apply_state(pb->pwm, &pstate);
pb->enabled = true;
 }

 static void pwm_backlight_power_off(struct pwm_bl_data *pb)
 {
+   struct pwm_state pstate;
+
if (!pb->enabled)
return;

-   pwm_config(pb->pwm, 0, pb->period);
-   pwm_disable(pb->pwm);
+   pwm_get_state(pb->pwm, &pstate);
+   pstate.duty_cycle = 0;
+   pstate.enabled = false;
+   pwm_apply_state(pb->pwm, &pstate);

if (pb->enable_gpio)
gpiod_set_value(pb->enable_gpio, 0);
@@ -76,24 +97,10 @@ static void pwm_backlight_power_off(struct pwm_bl_data *pb)
pb->enabled = false;
 }

-static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness)
-{
-   unsigned int lth = pb->lth_brightness;
-   int duty_cycle;
-
-   if (pb->levels)
-   duty_cycle = pb->levels[brightness];
-   else
-   duty_cycle = brightness;
-
-   return (duty_cycle * (pb->period - lth) / pb->scale) + lth;
-}
-
 static int pwm_backlight_update_status(struct backlight_device *bl)
 {
struct pwm_bl_data *pb = bl_get_data(bl);
int brightness = bl->props.brightness;
-   int duty_cycle;

if (bl->props.power != FB_BLANK_UNBLANK ||
bl->props.fb_blank != FB_BLANK_UNBLANK ||
@@ -104,8 +111,6 @@ static int pwm_backlight_update_status(struct 
backlight_device *bl)
brightness = pb->notify(pb->dev, brightness);

if (brightness > 0) {
-   duty_cycle = compute_duty_cycle(pb, brightness);
-   pwm_config(pb->pwm, duty_cycle, pb->period);
pwm_backlight_power_on(pb, brightness);
} else
pwm_backlight_power_off(pb);
-- 
2.5.0



[PATCH v5 42/46] backlight: lp8788: switch to the atomic PWM API

2016-03-30 Thread Boris Brezillon
pwm_config/enable/disable() have been deprecated and should be replaced
by pwm_apply_state().

Signed-off-by: Boris Brezillon 
---
 drivers/video/backlight/lp8788_bl.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/video/backlight/lp8788_bl.c 
b/drivers/video/backlight/lp8788_bl.c
index 5d583d7..521c730 100644
--- a/drivers/video/backlight/lp8788_bl.c
+++ b/drivers/video/backlight/lp8788_bl.c
@@ -124,16 +124,13 @@ static int lp8788_backlight_configure(struct lp8788_bl 
*bl)

 static void lp8788_pwm_ctrl(struct lp8788_bl *bl, int br, int max_br)
 {
-   unsigned int period;
-   unsigned int duty;
struct device *dev;
+   struct pwm_state pstate;
struct pwm_device *pwm;

if (!bl->pdata)
return;

-   period = bl->pdata->period_ns;
-   duty = br * period / max_br;
dev = bl->lp->dev;

/* request PWM device with the consumer name */
@@ -147,11 +144,15 @@ static void lp8788_pwm_ctrl(struct lp8788_bl *bl, int br, 
int max_br)
bl->pwm = pwm;
}

-   pwm_config(bl->pwm, duty, period);
-   if (duty)
-   pwm_enable(bl->pwm);
+   pwm_get_state(bl->pwm, &pstate);
+   pstate.period = bl->pdata->period_ns;
+   pstate.duty_cycle = br * pstate.period / max_br;
+   if (pstate.duty_cycle)
+   pstate.enabled = true;
else
-   pwm_disable(bl->pwm);
+   pstate.enabled = false;
+
+   pwm_apply_state(bl->pwm, &pstate);
 }

 static int lp8788_bl_update_status(struct backlight_device *bl_dev)
-- 
2.5.0



[PATCH v5 41/46] backlight: lp855x: switch to the atomic PWM API

2016-03-30 Thread Boris Brezillon
pwm_config/enable/disable() have been deprecated and should be replaced
by pwm_apply_state().

Signed-off-by: Boris Brezillon 
---
 drivers/video/backlight/lp855x_bl.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/lp855x_bl.c 
b/drivers/video/backlight/lp855x_bl.c
index daca9e6..5468e7a 100644
--- a/drivers/video/backlight/lp855x_bl.c
+++ b/drivers/video/backlight/lp855x_bl.c
@@ -235,8 +235,7 @@ err:

 static void lp855x_pwm_ctrl(struct lp855x *lp, int br, int max_br)
 {
-   unsigned int period = lp->pdata->period_ns;
-   unsigned int duty = br * period / max_br;
+   struct pwm_state pstate;
struct pwm_device *pwm;

/* request pwm device with the consumer name */
@@ -248,11 +247,15 @@ static void lp855x_pwm_ctrl(struct lp855x *lp, int br, 
int max_br)
lp->pwm = pwm;
}

-   pwm_config(lp->pwm, duty, period);
-   if (duty)
-   pwm_enable(lp->pwm);
+   pwm_get_state(lp->pwm, &pstate);
+   pstate.period = lp->pdata->period_ns;
+   pstate.duty_cycle = br * pstate.period / max_br;
+   if (pstate.duty_cycle)
+   pstate.enabled = true;
else
-   pwm_disable(lp->pwm);
+   pstate.enabled = false;
+
+   pwm_apply_state(lp->pwm, &pstate);
 }

 static int lp855x_bl_update_status(struct backlight_device *bl)
-- 
2.5.0



[PATCH v5 40/46] backlight: lm3630a: switch to the atomic PWM API

2016-03-30 Thread Boris Brezillon
pwm_config/enable/disable() have been deprecated and should be replaced
by pwm_apply_state().

Signed-off-by: Boris Brezillon 
---
 drivers/video/backlight/lm3630a_bl.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/video/backlight/lm3630a_bl.c 
b/drivers/video/backlight/lm3630a_bl.c
index 3d16bd6..fdad23c 100644
--- a/drivers/video/backlight/lm3630a_bl.c
+++ b/drivers/video/backlight/lm3630a_bl.c
@@ -162,14 +162,16 @@ static int lm3630a_intr_config(struct lm3630a_chip *pchip)

 static void lm3630a_pwm_ctrl(struct lm3630a_chip *pchip, int br, int br_max)
 {
-   unsigned int period = pchip->pdata->pwm_period;
-   unsigned int duty = br * period / br_max;
+   struct pwm_state pstate;

-   pwm_config(pchip->pwmd, duty, period);
-   if (duty)
-   pwm_enable(pchip->pwmd);
+   pwm_get_state(pchip->pwmd, &pstate);
+   pstate.period = pchip->pdata->pwm_period;
+   pstate.duty_cycle = br * pstate.period / br_max;
+   if (pstate.duty_cycle)
+   pstate.enabled = true;
else
-   pwm_disable(pchip->pwmd);
+   pstate.enabled = false;
+   pwm_apply_state(pchip->pwmd, &pstate);
 }

 /* update and get brightness */
-- 
2.5.0



[PATCH v5 39/46] leds: pwm: switch to the atomic PWM API

2016-03-30 Thread Boris Brezillon
pwm_config/enable/disable() have been deprecated and should be replaced
by pwm_apply_state().

Signed-off-by: Boris Brezillon 
---
 drivers/leds/leds-pwm.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index b48231c..f69b222 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -40,13 +40,18 @@ struct led_pwm_priv {
 static void __led_pwm_set(struct led_pwm_data *led_dat)
 {
int new_duty = led_dat->duty;
+   struct pwm_state pstate;

-   pwm_config(led_dat->pwm, new_duty, led_dat->period);
+   pwm_get_state(led_dat->pwm, &pstate);
+   pstate.duty_cycle = new_duty;
+   pstate.period = led_dat->period;

if (new_duty == 0)
-   pwm_disable(led_dat->pwm);
+   pstate.enabled = false;
else
-   pwm_enable(led_dat->pwm);
+   pstate.enabled = true;
+
+   pwm_apply_state(led_dat->pwm, &pstate);
 }

 static void led_pwm_set(struct led_classdev *led_cdev,
-- 
2.5.0



[PATCH v5 38/46] input: misc: pwm-beeper: switch to the atomic PWM API

2016-03-30 Thread Boris Brezillon
pwm_config/enable/disable() have been deprecated and should be replaced
by pwm_apply_state().

Signed-off-by: Boris Brezillon 
---
 drivers/input/misc/pwm-beeper.c | 46 +++--
 1 file changed, 31 insertions(+), 15 deletions(-)

diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c
index f2261ab..36c9897 100644
--- a/drivers/input/misc/pwm-beeper.c
+++ b/drivers/input/misc/pwm-beeper.c
@@ -34,7 +34,7 @@ static int pwm_beeper_event(struct input_dev *input,
 {
int ret = 0;
struct pwm_beeper *beeper = input_get_drvdata(input);
-   unsigned long period;
+   struct pwm_state pstate;

if (type != EV_SND || value < 0)
return -EINVAL;
@@ -49,19 +49,22 @@ static int pwm_beeper_event(struct input_dev *input,
return -EINVAL;
}

+   pwm_get_state(beeper->pwm, &pstate);
+
if (value == 0) {
-   pwm_disable(beeper->pwm);
+   pstate.enabled = false;
} else {
-   period = HZ_TO_NANOSECONDS(value);
-   ret = pwm_config(beeper->pwm, period / 2, period);
-   if (ret)
-   return ret;
-   ret = pwm_enable(beeper->pwm);
-   if (ret)
-   return ret;
-   beeper->period = period;
+   pstate.enabled = false;
+   pstate.period = HZ_TO_NANOSECONDS(value);
+   pstate.duty_cycle = pstate.period / 2;
}

+   ret = pwm_apply_state(beeper->pwm, &pstate);
+   if (ret)
+   return ret;
+
+   beeper->period = value ? pstate.period : 0;
+
return 0;
 }

@@ -132,10 +135,13 @@ err_free:
 static int pwm_beeper_remove(struct platform_device *pdev)
 {
struct pwm_beeper *beeper = platform_get_drvdata(pdev);
+   struct pwm_state pstate;

input_unregister_device(beeper->input);

-   pwm_disable(beeper->pwm);
+   pwm_get_state(beeper->pwm, &pstate);
+   pstate.enabled = false;
+   pwm_apply_state(beeper->pwm, &pstate);
pwm_free(beeper->pwm);

kfree(beeper);
@@ -147,8 +153,13 @@ static int __maybe_unused pwm_beeper_suspend(struct device 
*dev)
 {
struct pwm_beeper *beeper = dev_get_drvdata(dev);

-   if (beeper->period)
-   pwm_disable(beeper->pwm);
+   if (beeper->period) {
+   struct pwm_state pstate;
+
+   pwm_get_state(beeper->pwm, &pstate);
+   pstate.enabled = false;
+   pwm_apply_state(beeper->pwm, &pstate);
+   }

return 0;
 }
@@ -158,8 +169,13 @@ static int __maybe_unused pwm_beeper_resume(struct device 
*dev)
struct pwm_beeper *beeper = dev_get_drvdata(dev);

if (beeper->period) {
-   pwm_config(beeper->pwm, beeper->period / 2, beeper->period);
-   pwm_enable(beeper->pwm);
+   struct pwm_state pstate;
+
+   pwm_get_state(beeper->pwm, &pstate);
+   pstate.period = beeper->period;
+   pstate.duty_cycle = beeper->period / 2;
+   pstate.enabled = true;
+   pwm_apply_state(beeper->pwm, &pstate);
}

return 0;
-- 
2.5.0



[PATCH v5 37/46] input: misc: max8997: switch to the atomic PWM API

2016-03-30 Thread Boris Brezillon
pwm_config/enable/disable() have been deprecated and should be replaced
by pwm_apply_state().

Signed-off-by: Boris Brezillon 
---
 drivers/input/misc/max8997_haptic.c | 23 ++-
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/input/misc/max8997_haptic.c 
b/drivers/input/misc/max8997_haptic.c
index a806ba3..fcc0eb7 100644
--- a/drivers/input/misc/max8997_haptic.c
+++ b/drivers/input/misc/max8997_haptic.c
@@ -72,8 +72,12 @@ static int max8997_haptic_set_duty_cycle(struct 
max8997_haptic *chip)
int ret = 0;

if (chip->mode == MAX8997_EXTERNAL_MODE) {
-   unsigned int duty = chip->pwm_period * chip->level / 100;
-   ret = pwm_config(chip->pwm, duty, chip->pwm_period);
+   struct pwm_state pstate;
+
+   pwm_get_state(chip->pwm, &pstate);
+   pstate.period = chip->pwm_period;
+   pstate.duty_cycle = chip->pwm_period * chip->level / 100;
+   ret = pwm_apply_state(chip->pwm, &pstate);
} else {
int i;
u8 duty_index = 0;
@@ -188,7 +192,11 @@ static void max8997_haptic_enable(struct max8997_haptic 
*chip)
}
max8997_haptic_configure(chip);
if (chip->mode == MAX8997_EXTERNAL_MODE) {
-   error = pwm_enable(chip->pwm);
+   struct pwm_state pstate;
+
+   pwm_get_state(chip->pwm, &pstate);
+   pstate.enabled = true;
+   error = pwm_apply_state(chip->pwm, &pstate);
if (error) {
dev_err(chip->dev, "Failed to enable PWM\n");
regulator_disable(chip->regulator);
@@ -209,8 +217,13 @@ static void max8997_haptic_disable(struct max8997_haptic 
*chip)
if (chip->enabled) {
chip->enabled = false;
max8997_haptic_configure(chip);
-   if (chip->mode == MAX8997_EXTERNAL_MODE)
-   pwm_disable(chip->pwm);
+   if (chip->mode == MAX8997_EXTERNAL_MODE) {
+   struct pwm_state pstate;
+
+   pwm_get_state(chip->pwm, &pstate);
+   pstate.enabled = false;
+   pwm_apply_state(chip->pwm, &pstate);
+   }
regulator_disable(chip->regulator);
}

-- 
2.5.0



[PATCH v5 36/46] input: misc: max77693: switch to the atomic API

2016-03-30 Thread Boris Brezillon
pwm_config/enable/disable() have been deprecated and should be replaced
by pwm_apply_state().

Signed-off-by: Boris Brezillon 
---
 drivers/input/misc/max77693-haptic.c | 23 +--
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/input/misc/max77693-haptic.c 
b/drivers/input/misc/max77693-haptic.c
index cf6aac0..aef7dc4 100644
--- a/drivers/input/misc/max77693-haptic.c
+++ b/drivers/input/misc/max77693-haptic.c
@@ -70,13 +70,16 @@ struct max77693_haptic {

 static int max77693_haptic_set_duty_cycle(struct max77693_haptic *haptic)
 {
+   struct pwm_state pstate;
struct pwm_args pargs = { };
-   int delta;
int error;

pwm_get_args(haptic->pwm_dev, &pargs);
-   delta = (pargs.period + haptic->pwm_duty) / 2;
-   error = pwm_config(haptic->pwm_dev, delta, pargs.period);
+   pwm_get_state(haptic->pwm_dev, &pstate);
+
+   pstate.period = pargs.period;
+   pstate.duty_cycle = (pargs.period + haptic->pwm_duty) / 2;
+   error = pwm_apply_state(haptic->pwm_dev, &pstate);
if (error) {
dev_err(haptic->dev, "failed to configure pwm: %d\n", error);
return error;
@@ -161,12 +164,16 @@ static int max77693_haptic_lowsys(struct max77693_haptic 
*haptic, bool enable)

 static void max77693_haptic_enable(struct max77693_haptic *haptic)
 {
+   struct pwm_state pstate;
int error;

if (haptic->enabled)
return;

-   error = pwm_enable(haptic->pwm_dev);
+   pwm_get_state(haptic->pwm_dev, &pstate);
+   pstate.enabled = true;
+
+   error = pwm_apply_state(haptic->pwm_dev, &pstate);
if (error) {
dev_err(haptic->dev,
"failed to enable haptic pwm device: %d\n", error);
@@ -188,11 +195,13 @@ static void max77693_haptic_enable(struct max77693_haptic 
*haptic)
 err_enable_config:
max77693_haptic_lowsys(haptic, false);
 err_enable_lowsys:
-   pwm_disable(haptic->pwm_dev);
+   pstate.enabled = false;
+   pwm_apply_state(haptic->pwm_dev, &pstate);
 }

 static void max77693_haptic_disable(struct max77693_haptic *haptic)
 {
+   struct pwm_state pstate;
int error;

if (!haptic->enabled)
@@ -206,7 +215,9 @@ static void max77693_haptic_disable(struct max77693_haptic 
*haptic)
if (error)
goto err_disable_lowsys;

-   pwm_disable(haptic->pwm_dev);
+   pwm_get_state(haptic->pwm_dev, &pstate);
+   pstate.enabled = false;
+   pwm_apply_state(haptic->pwm_dev, &pstate);
haptic->enabled = false;

return;
-- 
2.5.0



[PATCH v5 35/46] hwmon: pwm-fan: switch to the atomic API

2016-03-30 Thread Boris Brezillon
pwm_config/enable/disable() have been deprecated and should be replaced
by pwm_apply_state().

Signed-off-by: Boris Brezillon 
---
 drivers/hwmon/pwm-fan.c | 81 -
 1 file changed, 46 insertions(+), 35 deletions(-)

diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c
index 82c5656..da4e4ab 100644
--- a/drivers/hwmon/pwm-fan.c
+++ b/drivers/hwmon/pwm-fan.c
@@ -40,8 +40,8 @@ struct pwm_fan_ctx {

 static int  __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm)
 {
+   struct pwm_state pstate;
struct pwm_args pargs = { };
-   unsigned long duty;
int ret = 0;

pwm_get_args(ctx->pwm, &pargs);
@@ -50,19 +50,17 @@ static int  __set_pwm(struct pwm_fan_ctx *ctx, unsigned 
long pwm)
if (ctx->pwm_value == pwm)
goto exit_set_pwm_err;

-   duty = DIV_ROUND_UP(pwm * (pargs.period - 1), MAX_PWM);
-   ret = pwm_config(ctx->pwm, duty, pargs.period);
-   if (ret)
-   goto exit_set_pwm_err;
-
+   pwm_get_state(ctx->pwm, &pstate);
+   pstate.period = pargs.period;
+   pstate.duty_cycle = DIV_ROUND_UP(pwm * (pargs.period - 1), MAX_PWM);
if (pwm == 0)
-   pwm_disable(ctx->pwm);
+   pstate.enabled = false;
+   else
+   pstate.enabled = true;

-   if (ctx->pwm_value == 0) {
-   ret = pwm_enable(ctx->pwm);
-   if (ret)
-   goto exit_set_pwm_err;
-   }
+   ret = pwm_apply_state(ctx->pwm, &pstate);
+   if (ret)
+   goto exit_set_pwm_err;

ctx->pwm_value = pwm;
 exit_set_pwm_err:
@@ -217,10 +215,10 @@ static int pwm_fan_of_get_cooling_data(struct device *dev,
 static int pwm_fan_probe(struct platform_device *pdev)
 {
struct thermal_cooling_device *cdev;
+   struct pwm_state pstate;
struct pwm_args pargs = { };
struct pwm_fan_ctx *ctx;
struct device *hwmon;
-   int duty_cycle;
int ret;

ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
@@ -239,27 +237,25 @@ static int pwm_fan_probe(struct platform_device *pdev)

/* Set duty cycle to maximum allowed */
pwm_get_args(ctx->pwm, &pargs);
-   duty_cycle = pargs.period - 1;
+   pwm_get_state(ctx->pwm, &pstate);
+
+   pstate.period = pargs.period;
+   pstate.duty_cycle = pargs.period - 1;
+   pstate.enabled = true;
ctx->pwm_value = MAX_PWM;

-   ret = pwm_config(ctx->pwm, duty_cycle, pargs.period);
+   ret = pwm_apply_state(ctx->pwm, &pstate);
if (ret) {
dev_err(&pdev->dev, "Failed to configure PWM\n");
return ret;
}

-   /* Enbale PWM output */
-   ret = pwm_enable(ctx->pwm);
-   if (ret) {
-   dev_err(&pdev->dev, "Failed to enable PWM\n");
-   return ret;
-   }
-
hwmon = devm_hwmon_device_register_with_groups(&pdev->dev, "pwmfan",
   ctx, pwm_fan_groups);
if (IS_ERR(hwmon)) {
dev_err(&pdev->dev, "Failed to register hwmon device\n");
-   pwm_disable(ctx->pwm);
+   pstate.enabled = false;
+   pwm_apply_state(ctx->pwm, &pstate);
return PTR_ERR(hwmon);
}

@@ -275,7 +271,8 @@ static int pwm_fan_probe(struct platform_device *pdev)
if (IS_ERR(cdev)) {
dev_err(&pdev->dev,
"Failed to register pwm-fan as cooling device");
-   pwm_disable(ctx->pwm);
+   pstate.enabled = false;
+   pwm_apply_state(ctx->pwm, &pstate);
return PTR_ERR(cdev);
}
ctx->cdev = cdev;
@@ -290,8 +287,14 @@ static int pwm_fan_remove(struct platform_device *pdev)
struct pwm_fan_ctx *ctx = platform_get_drvdata(pdev);

thermal_cooling_device_unregister(ctx->cdev);
-   if (ctx->pwm_value)
-   pwm_disable(ctx->pwm);
+   if (ctx->pwm_value) {
+   struct pwm_state pstate;
+
+   pwm_get_state(ctx->pwm, &pstate);
+   pstate.enabled = false;
+   pwm_apply_state(ctx->pwm, &pstate);
+   }
+
return 0;
 }

@@ -300,27 +303,35 @@ static int pwm_fan_suspend(struct device *dev)
 {
struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);

-   if (ctx->pwm_value)
-   pwm_disable(ctx->pwm);
+   if (ctx->pwm_value) {
+   struct pwm_state pstate;
+
+   pwm_get_state(ctx->pwm, &pstate);
+   pstate.enabled = false;
+   pwm_apply_state(ctx->pwm, &pstate);
+   }
+
return 0;
 }

 static int pwm_fan_resume(struct device *dev)
 {
struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
+   struct pwm_state pstate;
struct pwm_args pargs = { };
-   unsigned long duty;
-   

[PATCH v5 34/46] clk: pwm: switch to the atomic API

2016-03-30 Thread Boris Brezillon
pwm_config/enable/disable() have been deprecated and should be replaced
by pwm_apply_state().

Signed-off-by: Boris Brezillon 
---
 drivers/clk/clk-pwm.c | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/clk-pwm.c b/drivers/clk/clk-pwm.c
index ebcd738..49ec5b1 100644
--- a/drivers/clk/clk-pwm.c
+++ b/drivers/clk/clk-pwm.c
@@ -28,15 +28,29 @@ static inline struct clk_pwm *to_clk_pwm(struct clk_hw *hw)
 static int clk_pwm_prepare(struct clk_hw *hw)
 {
struct clk_pwm *clk_pwm = to_clk_pwm(hw);
+   struct pwm_state pstate;

-   return pwm_enable(clk_pwm->pwm);
+   pwm_get_state(clk_pwm->pwm, &pstate);
+   if (pstate.enabled)
+   return 0;
+
+   pstate.enabled = true;
+
+   return pwm_apply_state(clk_pwm->pwm, &pstate);
 }

 static void clk_pwm_unprepare(struct clk_hw *hw)
 {
struct clk_pwm *clk_pwm = to_clk_pwm(hw);
+   struct pwm_state pstate;
+
+   pwm_get_state(clk_pwm->pwm, &pstate);
+   if (!pstate.enabled)
+   return;

-   pwm_disable(clk_pwm->pwm);
+   pstate.enabled = false;
+
+   pwm_apply_state(clk_pwm->pwm, &pstate);
 }

 static unsigned long clk_pwm_recalc_rate(struct clk_hw *hw,
@@ -56,6 +70,7 @@ static const struct clk_ops clk_pwm_ops = {
 static int clk_pwm_probe(struct platform_device *pdev)
 {
struct device_node *node = pdev->dev.of_node;
+   struct pwm_state pstate;
struct pwm_args pargs = { };
struct clk_init_data init;
struct clk_pwm *clk_pwm;
@@ -88,7 +103,12 @@ static int clk_pwm_probe(struct platform_device *pdev)
return -EINVAL;
}

-   ret = pwm_config(pwm, (pargs.period + 1) >> 1, pargs.period);
+   pwm_get_state(pwm, &pstate);
+   pstate.period = pargs.period;
+   pstate.polarity = pargs.polarity;
+   pstate.duty_cycle = (pargs.period + 1) >> 1;
+
+   ret = pwm_apply_state(pwm, &pstate);
if (ret < 0)
return ret;

-- 
2.5.0



[PATCH v5 33/46] pwm: replace pwm_disable() by pwm_apply_state()

2016-03-30 Thread Boris Brezillon
Some PWM drivers are calling the deprecated pwm_disable() function in
their pwm->free() or pdev->remove() function. Replace those calls by
the pwm_apply_state().

Signed-off-by: Boris Brezillon 
---
 drivers/pwm/pwm-lpc18xx-sct.c | 7 +--
 drivers/pwm/pwm-lpc32xx.c | 9 +++--
 drivers/pwm/pwm-spear.c   | 9 +++--
 drivers/pwm/pwm-sti.c | 9 +++--
 4 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c
index 19dc64c..c4d7cb1 100644
--- a/drivers/pwm/pwm-lpc18xx-sct.c
+++ b/drivers/pwm/pwm-lpc18xx-sct.c
@@ -305,9 +305,12 @@ static void lpc18xx_pwm_free(struct pwm_chip *chip, struct 
pwm_device *pwm)
 {
struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
+   struct pwm_state pstate;

-   pwm_disable(pwm);
-   pwm_set_duty_cycle(pwm, 0);
+   pwm_get_state(pwm, &pstate);
+   pstate.duty_cycle = 0;
+   pstate.enabled = false;
+   pwm_apply_state(pwm, &pstate);
clear_bit(lpc18xx_data->duty_event, &lpc18xx_pwm->event_map);
 }

diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c
index 4d470c1..95870e0 100644
--- a/drivers/pwm/pwm-lpc32xx.c
+++ b/drivers/pwm/pwm-lpc32xx.c
@@ -138,8 +138,13 @@ static int lpc32xx_pwm_remove(struct platform_device *pdev)
struct lpc32xx_pwm_chip *lpc32xx = platform_get_drvdata(pdev);
unsigned int i;

-   for (i = 0; i < lpc32xx->chip.npwm; i++)
-   pwm_disable(&lpc32xx->chip.pwms[i]);
+   for (i = 0; i < lpc32xx->chip.npwm; i++) {
+   struct pwm_state pstate;
+
+   pwm_get_state(&lpc32xx->chip.pwms[i], &pstate);
+   pstate.enabled = false;
+   pwm_apply_state(&lpc32xx->chip.pwms[i], &pstate);
+   }

return pwmchip_remove(&lpc32xx->chip);
 }
diff --git a/drivers/pwm/pwm-spear.c b/drivers/pwm/pwm-spear.c
index 6c6b44f..2ee4cd5 100644
--- a/drivers/pwm/pwm-spear.c
+++ b/drivers/pwm/pwm-spear.c
@@ -233,8 +233,13 @@ static int spear_pwm_remove(struct platform_device *pdev)
struct spear_pwm_chip *pc = platform_get_drvdata(pdev);
int i;

-   for (i = 0; i < NUM_PWM; i++)
-   pwm_disable(&pc->chip.pwms[i]);
+   for (i = 0; i < NUM_PWM; i++) {
+   struct pwm_state pstate;
+
+   pwm_get_state(&pc->chip.pwms[i], &pstate);
+   pstate.enabled = false;
+   pwm_apply_state(&pc->chip.pwms[i], &pstate);
+   }

/* clk was prepared in probe, hence unprepare it here */
clk_unprepare(pc->clk);
diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c
index bea1d17..0ec44a8 100644
--- a/drivers/pwm/pwm-sti.c
+++ b/drivers/pwm/pwm-sti.c
@@ -435,8 +435,13 @@ static int sti_pwm_remove(struct platform_device *pdev)
struct sti_pwm_chip *pc = platform_get_drvdata(pdev);
unsigned int i;

-   for (i = 0; i < pc->cdata->num_chan; i++)
-   pwm_disable(&pc->chip.pwms[i]);
+   for (i = 0; i < pc->cdata->num_chan; i++) {
+   struct pwm_state pstate;
+
+   pwm_get_state(&pc->chip.pwms[i], &pstate);
+   pstate.enabled = false;
+   pwm_apply_state(&pc->chip.pwms[i], &pstate);
+   }

clk_unprepare(pc->clk);

-- 
2.5.0



[PATCH v5 32/46] pwm: deprecate pwm_config(), pwm_enable() and pwm_disable()

2016-03-30 Thread Boris Brezillon
Prefix those function as deprecated to encourage all existing users to
switch to pwm_apply_state().

Signed-off-by: Boris Brezillon 
---
 include/linux/pwm.h | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 4aad4eb..9bac10f 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -225,8 +225,8 @@ int pwm_apply_state(struct pwm_device *pwm, struct 
pwm_state *state);
  *
  * Returns: 0 on success or a negative error code on failure.
  */
-static inline int pwm_config(struct pwm_device *pwm, int duty_ns,
-int period_ns)
+static inline int __deprecated pwm_config(struct pwm_device *pwm, int duty_ns,
+ int period_ns)
 {
struct pwm_state pstate;

@@ -252,8 +252,8 @@ static inline int pwm_config(struct pwm_device *pwm, int 
duty_ns,
  *
  * Returns: 0 on success or a negative error code on failure.
  */
-static inline int pwm_set_polarity(struct pwm_device *pwm,
-  enum pwm_polarity polarity)
+static inline int __deprecated pwm_set_polarity(struct pwm_device *pwm,
+   enum pwm_polarity polarity)
 {
struct pwm_state pstate;

@@ -284,7 +284,7 @@ static inline int pwm_set_polarity(struct pwm_device *pwm,
  *
  * Returns: 0 on success or a negative error code on failure.
  */
-static inline int pwm_enable(struct pwm_device *pwm)
+static inline int __deprecated pwm_enable(struct pwm_device *pwm)
 {
struct pwm_state pstate;

@@ -303,7 +303,7 @@ static inline int pwm_enable(struct pwm_device *pwm)
  * pwm_disable() - stop a PWM output toggling
  * @pwm: PWM device
  */
-static inline void pwm_disable(struct pwm_device *pwm)
+static inline void __deprecated pwm_disable(struct pwm_device *pwm)
 {
struct pwm_state pstate;

@@ -360,24 +360,24 @@ static inline int pwm_apply_state(struct pwm_device *pwm,
return -ENOTSUPP;
 }

-static inline int pwm_config(struct pwm_device *pwm, int duty_ns,
-int period_ns)
+static inline int __deprecated pwm_config(struct pwm_device *pwm, int duty_ns,
+ int period_ns)
 {
return -EINVAL;
 }

-static inline int pwm_set_polarity(struct pwm_device *pwm,
-  enum pwm_polarity polarity)
+static inline int __deprecated pwm_set_polarity(struct pwm_device *pwm,
+   enum pwm_polarity polarity)
 {
return -ENOTSUPP;
 }

-static inline int pwm_enable(struct pwm_device *pwm)
+static inline int __deprecated pwm_enable(struct pwm_device *pwm)
 {
return -EINVAL;
 }

-static inline void pwm_disable(struct pwm_device *pwm)
+static inline void __deprecated pwm_disable(struct pwm_device *pwm)
 {
 }

-- 
2.5.0



[PATCH v5 31/46] pwm: update documentation

2016-03-30 Thread Boris Brezillon
Update the PWM subsystem documentation to reflect the atomic PWM changes.

Signed-off-by: Boris Brezillon 
---
 Documentation/pwm.txt | 27 +--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/Documentation/pwm.txt b/Documentation/pwm.txt
index ca895fd..cb25fca 100644
--- a/Documentation/pwm.txt
+++ b/Documentation/pwm.txt
@@ -42,9 +42,23 @@ variants of these functions, devm_pwm_get() and 
devm_pwm_put(), also exist.

 After being requested, a PWM has to be configured using:

-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);
+int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *pstate);

-To start/stop toggling the PWM output use pwm_enable()/pwm_disable().
+This API controls both the PWM period/duty_cycle config and the
+enable/disable state.
+
+The legacy pwm_config(), pwm_enable() and pwm_disable() are now deprecated,
+and should be replaced by pwm_apply_state() calls.
+
+The PWM user API also allows one to query the PWM state with pwm_get_state().
+
+In addition to the PWM state, the PWM API also exposes PWM arguments, which
+are the reference PWM config one should use on this PWM.
+PWM arguments are usually platform-specific and allows the PWM user to only
+care about dutycycle relatively to the full period (like, duty = 50% of the
+period). struct pwm_args contains 2 fields (period and polarity) and should
+be used to set the initial PWM config (usually done in the probe function
+of the PWM user). PWM arguments are retrieved with pwm_get_args().

 Using PWMs with the sysfs interface
 ---
@@ -105,6 +119,15 @@ goes low for the remainder of the period. Conversely, a 
signal with inversed
 polarity starts low for the duration of the duty cycle and goes high for the
 remainder of the period.

+Drivers are encouraged to implement ->apply() instead of the legacy
+->enable(), ->disable() and ->config() methods. Doing that should provide
+atomicity in the PWM config workflow, which is required when the PWM controls
+a critical device (like a regulator).
+
+The implementation of ->get_state() (a method used to retrieve initial PWM
+state) is also encouraged for the same reason: letting the PWM user know
+about the current PWM state would allow him to avoid glitches.
+
 Locking
 ---

-- 
2.5.0



[PATCH v5 30/46] regulator: pwm: retrieve correct voltage

2016-03-30 Thread Boris Brezillon
The continuous PWM voltage regulator is caching the voltage value in
the ->volt_uV field. While most of the time this value should reflect the
real voltage, sometime it can be sightly different if the PWM device
rounded the set_duty_cycle request.
Moreover, this value is not valid until someone has modified the regulator
output.

Remove the ->volt_uV field and always rely on the PWM state to calculate
the regulator output.

Signed-off-by: Boris Brezillon 
---
 drivers/regulator/pwm-regulator.c | 23 +--
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/regulator/pwm-regulator.c 
b/drivers/regulator/pwm-regulator.c
index 9374796..77f42d8 100644
--- a/drivers/regulator/pwm-regulator.c
+++ b/drivers/regulator/pwm-regulator.c
@@ -35,9 +35,6 @@ struct pwm_regulator_data {
struct regulator_ops ops;

int state;
-
-   /* Continuous voltage */
-   int volt_uV;
 };

 struct pwm_voltages {
@@ -167,11 +164,27 @@ static int pwm_voltage_to_duty_cycle_percentage(struct 
regulator_dev *rdev, int
return ((req_uV * 100) - (min_uV * 100)) / diff;
 }

+static int pwm_duty_cycle_percentage_to_voltage(struct regulator_dev *rdev,
+   int dutycycle)
+{
+   int min_uV = rdev->constraints->min_uV;
+   int max_uV = rdev->constraints->max_uV;
+   int diff = max_uV - min_uV;
+
+   return min_uV + ((diff * dutycycle) / 100);
+}
+
 static int pwm_regulator_get_voltage(struct regulator_dev *rdev)
 {
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
+   struct pwm_state pstate;
+   u64 dutycycle;

-   return drvdata->volt_uV;
+   pwm_get_state(drvdata->pwm, &pstate);
+   dutycycle = pstate.duty_cycle * 100;
+   do_div(dutycycle, pstate.period);
+
+   return pwm_duty_cycle_percentage_to_voltage(rdev, dutycycle);
 }

 static int pwm_regulator_set_voltage(struct regulator_dev *rdev,
@@ -196,8 +209,6 @@ static int pwm_regulator_set_voltage(struct regulator_dev 
*rdev,
return ret;
}

-   drvdata->volt_uV = min_uV;
-
/* Delay required by PWM regulator to settle to the new voltage */
usleep_range(ramp_delay, ramp_delay + 1000);

-- 
2.5.0



[PATCH v5 29/46] regulator: pwm: properly initialize the ->state field

2016-03-30 Thread Boris Brezillon
The ->state field is currently initialized to 0, thus referencing the
voltage selector at index 0, which might not reflect the current voltage
value.
If possible, retrieve the current voltage selector from the PWM state, else
return -EINVAL.

Signed-off-by: Boris Brezillon 
Tested-by: Heiko Stuebner 
Acked-by: Mark Brown 
---
 drivers/regulator/pwm-regulator.c | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/drivers/regulator/pwm-regulator.c 
b/drivers/regulator/pwm-regulator.c
index 42cc312..9374796 100644
--- a/drivers/regulator/pwm-regulator.c
+++ b/drivers/regulator/pwm-regulator.c
@@ -48,10 +48,35 @@ struct pwm_voltages {
 /**
  * Voltage table call-backs
  */
+static void pwm_regulator_init_state(struct regulator_dev *rdev)
+{
+   struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
+   struct pwm_state pwm_state;
+   unsigned int dutycycle;
+   int i;
+
+   pwm_get_state(drvdata->pwm, &pwm_state);
+
+   if (!pwm_state.period)
+   return;
+
+   dutycycle = (pwm_state.duty_cycle * 100) / pwm_state.period;
+
+   for (i = 0; i < rdev->desc->n_voltages; i++) {
+   if (dutycycle == drvdata->duty_cycle_table[i].dutycycle) {
+   drvdata->state = i;
+   return;
+   }
+   }
+}
+
 static int pwm_regulator_get_voltage_sel(struct regulator_dev *rdev)
 {
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);

+   if (drvdata->state < 0)
+   pwm_regulator_init_state(rdev);
+
return drvdata->state;
 }

@@ -234,6 +259,7 @@ static int pwm_regulator_init_table(struct platform_device 
*pdev,
return ret;
}

+   drvdata->state  = -EINVAL;
drvdata->duty_cycle_table   = duty_cycle_table;
memcpy(&drvdata->ops, &pwm_regulator_voltage_table_ops,
   sizeof(drvdata->ops));
-- 
2.5.0



[PATCH v5 28/46] regulator: pwm: swith to the atomic PWM API

2016-03-30 Thread Boris Brezillon
pwm_config/enable/disable() have been deprecated in favor of
pwm_apply_state().
Replace all those calls with the equivalent pwm_get/apply_state().

Signed-off-by: Boris Brezillon 
---
 drivers/regulator/pwm-regulator.c | 54 ---
 1 file changed, 34 insertions(+), 20 deletions(-)

diff --git a/drivers/regulator/pwm-regulator.c 
b/drivers/regulator/pwm-regulator.c
index 9590fb0..42cc312 100644
--- a/drivers/regulator/pwm-regulator.c
+++ b/drivers/regulator/pwm-regulator.c
@@ -59,16 +59,18 @@ static int pwm_regulator_set_voltage_sel(struct 
regulator_dev *rdev,
 unsigned selector)
 {
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
-   struct pwm_args pargs = { };
-   int dutycycle;
+   struct pwm_state pstate = { };
+   u64 dutycycle;
int ret;

-   pwm_get_args(drvdata->pwm, &pargs);
+   pwm_get_state(drvdata->pwm, &pstate);

-   dutycycle = (pargs.period *
-   drvdata->duty_cycle_table[selector].dutycycle) / 100;
+   dutycycle = drvdata->duty_cycle_table[selector].dutycycle;
+   dutycycle *= pstate.period;
+   do_div(dutycycle, 100);
+   pstate.duty_cycle = dutycycle;

-   ret = pwm_config(drvdata->pwm, dutycycle, pargs.period);
+   ret = pwm_apply_state(drvdata->pwm, &pstate);
if (ret) {
dev_err(&rdev->dev, "Failed to configure PWM\n");
return ret;
@@ -93,24 +95,39 @@ static int pwm_regulator_list_voltage(struct regulator_dev 
*rdev,
 static int pwm_regulator_enable(struct regulator_dev *dev)
 {
struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
+   struct pwm_state pstate = { };
+
+   pwm_get_state(drvdata->pwm, &pstate);
+   if (pstate.enabled)
+   return 0;
+
+   pstate.enabled = true;

-   return pwm_enable(drvdata->pwm);
+   return pwm_apply_state(drvdata->pwm, &pstate);
 }

 static int pwm_regulator_disable(struct regulator_dev *dev)
 {
struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
+   struct pwm_state pstate = { };

-   pwm_disable(drvdata->pwm);
+   pwm_get_state(drvdata->pwm, &pstate);
+   if (!pstate.enabled)
+   return 0;

-   return 0;
+   pstate.enabled = false;
+
+   return pwm_apply_state(drvdata->pwm, &pstate);
 }

 static int pwm_regulator_is_enabled(struct regulator_dev *dev)
 {
struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
+   struct pwm_state pstate = { };

-   return pwm_is_enabled(drvdata->pwm);
+   pwm_get_state(drvdata->pwm, &pstate);
+
+   return pstate.enabled;
 }

 /**
@@ -138,25 +155,22 @@ static int pwm_regulator_set_voltage(struct regulator_dev 
*rdev,
 {
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
unsigned int ramp_delay = rdev->constraints->ramp_delay;
-   struct pwm_args pargs = { };
-   int duty_cycle;
+   struct pwm_state pstate = { };
+   u64 duty_cycle;
int ret;

-   pwm_get_args(drvdata->pwm, &pargs);
+   pwm_get_state(drvdata->pwm, &pstate);
duty_cycle = pwm_voltage_to_duty_cycle_percentage(rdev, min_uV);
+   duty_cycle *= pstate.period;
+   do_div(duty_cycle, 100);
+   pstate.duty_cycle = duty_cycle;

-   ret = pwm_config(drvdata->pwm, (pargs.period / 100) * duty_cycle,
-pargs.period);
+   ret = pwm_apply_state(drvdata->pwm, &pstate);
if (ret) {
dev_err(&rdev->dev, "Failed to configure PWM\n");
return ret;
}

-   ret = pwm_enable(drvdata->pwm);
-   if (ret) {
-   dev_err(&rdev->dev, "Failed to enable PWM\n");
-   return ret;
-   }
drvdata->volt_uV = min_uV;

/* Delay required by PWM regulator to settle to the new voltage */
-- 
2.5.0



[PATCH v5 27/46] regulator: pwm: adjust PWM config at probe time

2016-03-30 Thread Boris Brezillon
The PWM attached to a PWM regulator device might have been previously
configured by the bootloader.
Make sure the bootloader and linux config are in sync, and adjust the PWM
config if that's not the case.

Signed-off-by: Boris Brezillon 
---
 drivers/regulator/pwm-regulator.c | 50 +++
 1 file changed, 50 insertions(+)

diff --git a/drivers/regulator/pwm-regulator.c 
b/drivers/regulator/pwm-regulator.c
index 9154c47..9590fb0 100644
--- a/drivers/regulator/pwm-regulator.c
+++ b/drivers/regulator/pwm-regulator.c
@@ -240,6 +240,52 @@ static int pwm_regulator_init_continuous(struct 
platform_device *pdev,
return 0;
 }

+static int pwm_regulator_adjust_pwm_config(struct pwm_regulator_data *drvdata)
+{
+   struct pwm_state pstate = { };
+   struct pwm_args pargs = { };
+
+   pwm_get_args(drvdata->pwm, &pargs);
+   pwm_get_state(drvdata->pwm, &pstate);
+
+   /*
+* if the current period is zero this either means the PWM driver
+* does not support initial state retrieval or the PWM was not
+* configured.
+* In any case, we setup the new period and poloarity, and assign a
+* duty_cycle of 0.
+*/
+   if (!pstate.period) {
+   pstate.duty_cycle = 0;
+   pstate.period = pargs.period;
+   pstate.polarity = pargs.polarity;
+
+   return pwm_apply_state(drvdata->pwm, &pstate);
+   }
+
+   /*
+* Adjust the PWM dutycycle/period based on the period value provided
+* in PWM args.
+*/
+   if (pargs.period != pstate.period) {
+   u64 dutycycle = (u64)pstate.duty_cycle * pargs.period;
+
+   do_div(dutycycle, pstate.period);
+   pstate.duty_cycle = dutycycle;
+   pstate.period = pargs.period;
+   }
+
+   /*
+* If the polarity changed, we should also change the dutycycle value.
+*/
+   if (pargs.polarity != pstate.polarity) {
+   pstate.polarity = pargs.polarity;
+   pstate.duty_cycle = pstate.period - pstate.duty_cycle;
+   }
+
+   return pwm_apply_state(drvdata->pwm, &pstate);
+}
+
 static int pwm_regulator_probe(struct platform_device *pdev)
 {
const struct regulator_init_data *init_data;
@@ -283,6 +329,10 @@ static int pwm_regulator_probe(struct platform_device 
*pdev)
return PTR_ERR(drvdata->pwm);
}

+   ret = pwm_regulator_adjust_pwm_config(drvdata);
+   if (ret)
+   return ret;
+
regulator = devm_regulator_register(&pdev->dev,
&drvdata->desc, &config);
if (IS_ERR(regulator)) {
-- 
2.5.0



[PATCH v5 26/46] pwm: sun4i: implement hardware readout

2016-03-30 Thread Boris Brezillon
Implement ->get_state() instead of only initializing the polarity in
the probe function.

This implementation also takes care of keeping the PWM clk enabled if at
least one of the PWM exported by the PWM chip is already enabled, which
should prevent glitches.

Signed-off-by: Boris Brezillon 
---
 drivers/pwm/pwm-sun4i.c | 74 -
 1 file changed, 55 insertions(+), 19 deletions(-)

diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index 03a99a5..34cb296 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -252,11 +252,65 @@ static void sun4i_pwm_disable(struct pwm_chip *chip, 
struct pwm_device *pwm)
clk_disable_unprepare(sun4i_pwm->clk);
 }

+static void sun4i_pwm_get_state(struct pwm_chip *chip,
+   struct pwm_device *pwm,
+   struct pwm_state *pstate)
+{
+   struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+   unsigned int clk_rate = clk_get_rate(sun4i_pwm->clk);
+   int prescaler, prescalerid;
+   int ret;
+   u32 val;
+
+   ret = clk_prepare_enable(sun4i_pwm->clk);
+   if (ret) {
+   dev_err(chip->dev, "Failed to enable PWM clock");
+   return;
+   }
+
+   val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
+   if (val & BIT_CH(PWM_ACT_STATE, pwm->hwpwm))
+   pstate->polarity = PWM_POLARITY_INVERSED;
+   else
+   pstate->polarity = PWM_POLARITY_NORMAL;
+
+   if ((val & BIT_CH(PWM_EN, pwm->hwpwm)) &&
+   (val & BIT_CH(PWM_CLK_GATING, pwm->hwpwm)))
+   pstate->enabled = true;
+   else
+   pstate->enabled = false;
+
+   pstate->period = 0;
+   pstate->duty_cycle = 0;
+   prescalerid = (val >> (PWMCH_OFFSET * pwm->hwpwm)) & PWM_PRESCAL_MASK;
+   prescaler = prescaler_table[prescalerid];
+   if (prescaler) {
+   u64 timens;
+
+   clk_rate /= prescaler;
+
+   val = sun4i_pwm_readl(sun4i_pwm, PWM_CH_PRD(pwm->hwpwm));
+
+   timens = ((val >> 16) & PWM_PRD_MASK) + 1;
+   timens *= NSEC_PER_SEC;
+   do_div(timens, clk_rate);
+   pstate->period = timens;
+
+   timens = val & PWM_DTY_MASK;
+   timens *= NSEC_PER_SEC;
+   do_div(timens, clk_rate);
+   pstate->duty_cycle = timens;
+   }
+
+   clk_disable_unprepare(sun4i_pwm->clk);
+}
+
 static const struct pwm_ops sun4i_pwm_ops = {
.config = sun4i_pwm_config,
.set_polarity = sun4i_pwm_set_polarity,
.enable = sun4i_pwm_enable,
.disable = sun4i_pwm_disable,
+   .get_state = sun4i_pwm_get_state,
.owner = THIS_MODULE,
 };

@@ -307,8 +361,7 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
 {
struct sun4i_pwm_chip *pwm;
struct resource *res;
-   u32 val;
-   int i, ret;
+   int ret;
const struct of_device_id *match;

match = of_match_device(sun4i_pwm_dt_ids, &pdev->dev);
@@ -345,24 +398,7 @@ static int sun4i_pwm_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, pwm);

-   ret = clk_prepare_enable(pwm->clk);
-   if (ret) {
-   dev_err(&pdev->dev, "failed to enable PWM clock\n");
-   goto clk_error;
-   }
-
-   val = sun4i_pwm_readl(pwm, PWM_CTRL_REG);
-   for (i = 0; i < pwm->chip.npwm; i++)
-   if (!(val & BIT_CH(PWM_ACT_STATE, i)))
-   pwm_set_polarity(&pwm->chip.pwms[i],
-PWM_POLARITY_INVERSED);
-   clk_disable_unprepare(pwm->clk);
-
return 0;
-
-clk_error:
-   pwmchip_remove(&pwm->chip);
-   return ret;
 }

 static int sun4i_pwm_remove(struct platform_device *pdev)
-- 
2.5.0



[PATCH v5 25/46] pwm: sti: avoid glitches on already running PWMs

2016-03-30 Thread Boris Brezillon
The current logic will disable the PWM clk even if a PWM was left
enabled by the bootloader (because it's controlling a critical device
like a regulator for example).
Keep the PWM clk enabled if at least one PWM is enabled to avoid any
glitches.

Signed-off-by: Boris Brezillon 
---
 drivers/pwm/pwm-sti.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c
index 0fbca94..bea1d17 100644
--- a/drivers/pwm/pwm-sti.c
+++ b/drivers/pwm/pwm-sti.c
@@ -343,7 +343,7 @@ static int sti_pwm_probe(struct platform_device *pdev)
struct sti_pwm_compat_data *cdata;
struct sti_pwm_chip *pc;
struct resource *res;
-   int ret;
+   int i, ret;

pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
if (!pc)
@@ -394,7 +394,7 @@ static int sti_pwm_probe(struct platform_device *pdev)
return -EINVAL;
}

-   ret = clk_prepare(pc->clk);
+   ret = clk_prepare_enable(pc->clk);
if (ret) {
dev_err(dev, "failed to prepare clock\n");
return ret;
@@ -412,6 +412,19 @@ static int sti_pwm_probe(struct platform_device *pdev)
return ret;
}

+   /*
+* Keep the PWM clk enabled if some PWMs appear to be up and
+* running.
+*/
+   for (i = 0; i < pc->chip.npwm; i++) {
+   struct pwm_state pstate;
+
+   pwm_get_state(&pc->chip.pwms[i], &pstate);
+   if (pstate.enabled)
+   clk_enable(pc->clk);
+   }
+   clk_disable(pc->clk);
+
platform_set_drvdata(pdev, pc);

return 0;
-- 
2.5.0



[PATCH v5 24/46] pwm: sti: add support for initial state retrieval

2016-03-30 Thread Boris Brezillon
Implement ->get_state() to provide support for initial state retrieval.

Signed-off-by: Boris Brezillon 
---
 drivers/pwm/pwm-sti.c | 41 +
 1 file changed, 41 insertions(+)

diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c
index 92abbd5..0fbca94 100644
--- a/drivers/pwm/pwm-sti.c
+++ b/drivers/pwm/pwm-sti.c
@@ -238,6 +238,46 @@ static void sti_pwm_disable(struct pwm_chip *chip, struct 
pwm_device *pwm)
mutex_unlock(&pc->sti_pwm_lock);
 }

+static void sti_pwm_get_state(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ struct pwm_state *pstate)
+{
+   struct sti_pwm_chip *pc = to_sti_pwmchip(chip);
+   unsigned int regval, prescaler;
+   u64 timens;
+   int ret;
+
+   /* The clock has to be enabled to access PWM registers */
+   ret = clk_enable(pc->clk);
+   if (ret) {
+   dev_err(chip->dev, "Failed to enable PWM clk");
+   return;
+   }
+
+   regmap_field_read(pc->prescale_high, ®val);
+   prescaler = regval << 4;
+   regmap_field_read(pc->prescale_low, ®val);
+   prescaler |= regval;
+
+   timens = (u64)(prescaler + 1) * NSEC_PER_SEC *
+(pc->cdata->max_pwm_cnt + 1);
+   do_div(timens, pc->clk_rate);
+
+   pstate->period = timens;
+
+   regmap_read(pc->regmap, STI_DS_REG(pwm->hwpwm), ®val);
+   timens = (u64)(regval + 1) * pstate->period;
+   do_div(timens, pc->cdata->max_pwm_cnt + 1);
+   pstate->duty_cycle = timens;
+
+   regmap_field_read(pc->pwm_en, ®val);
+   pstate->enabled = regval;
+
+   pstate->polarity = PWM_POLARITY_NORMAL;
+
+   clk_disable(pc->clk);
+}
+
 static void sti_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
 {
struct sti_pwm_chip *pc = to_sti_pwmchip(chip);
@@ -249,6 +289,7 @@ static const struct pwm_ops sti_pwm_ops = {
.config = sti_pwm_config,
.enable = sti_pwm_enable,
.disable = sti_pwm_disable,
+   .get_state = sti_pwm_get_state,
.free = sti_pwm_free,
.owner = THIS_MODULE,
 };
-- 
2.5.0



[PATCH v5 23/46] pwm: rockchip: add support for atomic update

2016-03-30 Thread Boris Brezillon
Implement the ->apply() function to add support for atomic update.

Signed-off-by: Boris Brezillon 
Tested-by: Heiko Stuebner 
---
 drivers/pwm/pwm-rockchip.c | 63 --
 1 file changed, 39 insertions(+), 24 deletions(-)

diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index 5c7e79c..ed27740 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -50,7 +50,8 @@ struct rockchip_pwm_data {
const struct pwm_ops *ops;

void (*set_enable)(struct pwm_chip *chip,
-  struct pwm_device *pwm, bool enable);
+  struct pwm_device *pwm, bool enable,
+  enum pwm_polarity polarity);
void (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm,
  struct pwm_state *pstate);
 };
@@ -61,7 +62,8 @@ static inline struct rockchip_pwm_chip 
*to_rockchip_pwm_chip(struct pwm_chip *c)
 }

 static void rockchip_pwm_set_enable_v1(struct pwm_chip *chip,
-  struct pwm_device *pwm, bool enable)
+  struct pwm_device *pwm, bool enable,
+  enum pwm_polarity polarity)
 {
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
u32 enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN;
@@ -91,14 +93,15 @@ static void rockchip_pwm_get_state_v1(struct pwm_chip *chip,
 }

 static void rockchip_pwm_set_enable_v2(struct pwm_chip *chip,
-  struct pwm_device *pwm, bool enable)
+  struct pwm_device *pwm, bool enable,
+  enum pwm_polarity polarity)
 {
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
u32 enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
  PWM_CONTINUOUS;
u32 val;

-   if (pwm_get_polarity(pwm) == PWM_POLARITY_INVERSED)
+   if (polarity == PWM_POLARITY_INVERSED)
enable_conf |= PWM_DUTY_NEGATIVE | PWM_INACTIVE_POSITIVE;
else
enable_conf |= PWM_DUTY_POSITIVE | PWM_INACTIVE_NEGATIVE;
@@ -168,7 +171,6 @@ static int rockchip_pwm_config(struct pwm_chip *chip, 
struct pwm_device *pwm,
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
unsigned long period, duty;
u64 clk_rate, div;
-   int ret;

clk_rate = clk_get_rate(pc->clk);

@@ -185,15 +187,8 @@ static int rockchip_pwm_config(struct pwm_chip *chip, 
struct pwm_device *pwm,
do_div(div, pc->data->prescaler * NSEC_PER_SEC);
duty = div;

-   ret = clk_enable(pc->clk);
-   if (ret)
-   return ret;
-
writel(period, pc->base + pc->data->regs.period);
writel(duty, pc->base + pc->data->regs.duty);
-   writel(0, pc->base + pc->data->regs.cntr);
-
-   clk_disable(pc->clk);

return 0;
 }
@@ -211,43 +206,63 @@ static int rockchip_pwm_set_polarity(struct pwm_chip 
*chip,
return 0;
 }

-static int rockchip_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
 {
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+   struct pwm_state curstate;
+   bool enabled;
int ret;

+   pwm_get_state(pwm, &curstate);
+   enabled = curstate.enabled;
+
ret = clk_enable(pc->clk);
if (ret)
return ret;

-   pc->data->set_enable(chip, pwm, true);
+   if (state->polarity != curstate.polarity && enabled) {
+   pc->data->set_enable(chip, pwm, false, state->polarity);
+   enabled = false;
+   }

-   return 0;
-}
+   ret = rockchip_pwm_config(chip, pwm, state->duty_cycle, state->period);
+   if (ret) {
+   if (enabled != curstate.enabled)
+   pc->data->set_enable(chip, pwm, !enabled,
+state->polarity);

-static void rockchip_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
-   struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+   goto out;
+   }

-   pc->data->set_enable(chip, pwm, false);
+   if (state->enabled != enabled)
+   pc->data->set_enable(chip, pwm, state->enabled,
+state->polarity);

+   /*
+* Update the state with the real hardware, which can differ a bit
+* because of period/duty_cycle approximation.
+*/
+   rockchip_pwm_get_state(chip, pwm, state);
+
+out:
clk_disable(pc->clk);
+
+   return ret;
 }

 static const struct pwm_ops rockchip_pwm_ops_v1 = {
.get_state = rockchip_pwm_get_state,
.config = rockchip_pwm_config,
-   .enable = rockchip_pwm_enable,
-   .disa

[PATCH v5 22/46] pwm: rockchip: avoid glitches on already running PWMs

2016-03-30 Thread Boris Brezillon
The current logic will disable the PWM clk even if the PWM was left
enabled by the bootloader (because it's controlling a critical device
like a regulator for example).
Keep the PWM clk enabled if the PWM is enabled to avoid any glitches.

Signed-off-by: Boris Brezillon 
---
 drivers/pwm/pwm-rockchip.c | 24 +++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index 6a1087c..5c7e79c 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -302,6 +302,7 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
 {
const struct of_device_id *id;
struct rockchip_pwm_chip *pc;
+   struct pwm_state pstate;
struct resource *r;
int ret;

@@ -322,7 +323,7 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
if (IS_ERR(pc->clk))
return PTR_ERR(pc->clk);

-   ret = clk_prepare(pc->clk);
+   ret = clk_prepare_enable(pc->clk);
if (ret)
return ret;

@@ -345,12 +346,33 @@ static int rockchip_pwm_probe(struct platform_device 
*pdev)
dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
}

+   /* Keep the PWM clk enabled if the PWM appears to be up and running. */
+   pwm_get_state(pc->chip.pwms, &pstate);
+   if (!pstate.enabled)
+   clk_disable(pc->clk);
+
return ret;
 }

 static int rockchip_pwm_remove(struct platform_device *pdev)
 {
struct rockchip_pwm_chip *pc = platform_get_drvdata(pdev);
+   struct pwm_state pstate;
+
+   /*
+* Disable the PWM clk before unpreparing it if the PWM device is still
+* running. This should only happen when the last PWM user left it
+* enabled, or when nobody requested a PWM that was previously enabled
+* by the bootloader.
+*
+* FIXME: Maybe the core should disable all PWM devices in
+* pwmchip_remove(). In this case we'd only have to call
+* clk_unprepare() after pwmchip_remove().
+*
+*/
+   pwm_get_state(pc->chip.pwms, &pstate);
+   if (pstate.enabled)
+   clk_disable(pc->clk);

clk_unprepare(pc->clk);

-- 
2.5.0



[PATCH v5 21/46] pwm: rockchip: add initial state retrieval

2016-03-30 Thread Boris Brezillon
Implement the ->get_state() function to expose initial state.

Signed-off-by: Boris Brezillon 
---
 drivers/pwm/pwm-rockchip.c | 69 ++
 1 file changed, 69 insertions(+)

diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index 7d9cc90..6a1087c 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -51,6 +51,8 @@ struct rockchip_pwm_data {

void (*set_enable)(struct pwm_chip *chip,
   struct pwm_device *pwm, bool enable);
+   void (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *pstate);
 };

 static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip 
*c)
@@ -75,6 +77,19 @@ static void rockchip_pwm_set_enable_v1(struct pwm_chip *chip,
writel_relaxed(val, pc->base + pc->data->regs.ctrl);
 }

+static void rockchip_pwm_get_state_v1(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ struct pwm_state *pstate)
+{
+   struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+   u32 enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN;
+   u32 val;
+
+   val = readl(pc->base + pc->data->regs.ctrl);
+   if ((val & enable_conf) == enable_conf)
+   pstate->enabled = true;
+}
+
 static void rockchip_pwm_set_enable_v2(struct pwm_chip *chip,
   struct pwm_device *pwm, bool enable)
 {
@@ -98,6 +113,55 @@ static void rockchip_pwm_set_enable_v2(struct pwm_chip 
*chip,
writel_relaxed(val, pc->base + pc->data->regs.ctrl);
 }

+static void rockchip_pwm_get_state_v2(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ struct pwm_state *pstate)
+{
+   struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+   u32 enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
+ PWM_CONTINUOUS;
+   u32 val;
+
+   val = readl(pc->base + pc->data->regs.ctrl);
+   if ((val & enable_conf) != enable_conf)
+   return;
+
+   pstate->enabled = true;
+
+   if (!(val & PWM_DUTY_POSITIVE))
+   pstate->polarity = PWM_POLARITY_INVERSED;
+}
+
+static void rockchip_pwm_get_state(struct pwm_chip *chip,
+  struct pwm_device *pwm,
+  struct pwm_state *pstate)
+{
+   struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+   unsigned long clk_rate;
+   u64 tmp;
+   int ret;
+
+   ret = clk_enable(pc->clk);
+   if (ret)
+   return;
+
+   clk_rate = clk_get_rate(pc->clk);
+
+   tmp = readl(pc->base + pc->data->regs.period);
+   tmp *= pc->data->prescaler * NSEC_PER_SEC;
+   do_div(tmp, clk_rate);
+   pstate->period = tmp;
+
+   tmp = readl(pc->base + pc->data->regs.duty);
+   tmp *= pc->data->prescaler * NSEC_PER_SEC;
+   do_div(tmp, clk_rate);
+   pstate->duty_cycle = tmp;
+
+   pc->data->get_state(chip, pwm, pstate);
+
+   clk_disable(pc->clk);
+}
+
 static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
   int duty_ns, int period_ns)
 {
@@ -171,6 +235,7 @@ static void rockchip_pwm_disable(struct pwm_chip *chip, 
struct pwm_device *pwm)
 }

 static const struct pwm_ops rockchip_pwm_ops_v1 = {
+   .get_state = rockchip_pwm_get_state,
.config = rockchip_pwm_config,
.enable = rockchip_pwm_enable,
.disable = rockchip_pwm_disable,
@@ -178,6 +243,7 @@ static const struct pwm_ops rockchip_pwm_ops_v1 = {
 };

 static const struct pwm_ops rockchip_pwm_ops_v2 = {
+   .get_state = rockchip_pwm_get_state,
.config = rockchip_pwm_config,
.set_polarity = rockchip_pwm_set_polarity,
.enable = rockchip_pwm_enable,
@@ -195,6 +261,7 @@ static const struct rockchip_pwm_data pwm_data_v1 = {
.prescaler = 2,
.ops = &rockchip_pwm_ops_v1,
.set_enable = rockchip_pwm_set_enable_v1,
+   .get_state = rockchip_pwm_get_state_v1,
 };

 static const struct rockchip_pwm_data pwm_data_v2 = {
@@ -207,6 +274,7 @@ static const struct rockchip_pwm_data pwm_data_v2 = {
.prescaler = 1,
.ops = &rockchip_pwm_ops_v2,
.set_enable = rockchip_pwm_set_enable_v2,
+   .get_state = rockchip_pwm_get_state_v2,
 };

 static const struct rockchip_pwm_data pwm_data_vop = {
@@ -219,6 +287,7 @@ static const struct rockchip_pwm_data pwm_data_vop = {
.prescaler = 1,
.ops = &rockchip_pwm_ops_v2,
.set_enable = rockchip_pwm_set_enable_v2,
+   .get_state = rockchip_pwm_get_state_v2,
 };

 static const struct of_device_id rockchip_pwm_dt_ids[] = {
-- 
2.5.0



[PATCH v5 20/46] pwm: add information about polarity, duty cycle and period to debugfs

2016-03-30 Thread Boris Brezillon
From: Heiko Stübner 

The pwm-states make it possible to also output the polarity, duty cycle
and period information in the debugfs pwm summary-outout.
This makes it easier to gather overview information about pwms without
needing to walk through the sysfs attributes of every pwm.

Signed-off-by: Heiko Stuebner 
Signed-off-by: Boris Brezillon 
---
 drivers/pwm/core.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index c2b1569..9a83840 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -894,6 +894,11 @@ static void pwm_dbg_show(struct pwm_chip *chip, struct 
seq_file *s)
if (pstate.enabled)
seq_puts(s, " enabled");

+   seq_printf(s, " period:%uns", pstate.period);
+   seq_printf(s, " duty:%uns", pstate.duty_cycle);
+   seq_printf(s, " polarity:%s",
+  pstate.polarity ? "inverse" : "normal");
+
seq_puts(s, "\n");
}
 }
-- 
2.5.0



[PATCH v5 19/46] pwm: switch to the atomic API

2016-03-30 Thread Boris Brezillon
Replace legacy pwm_get/set_xxx() and pwm_config/enable/disable() calls
by pwm_get/apply_state().

Signed-off-by: Boris Brezillon 
---
 drivers/pwm/core.c  |  5 -
 drivers/pwm/sysfs.c | 61 +++--
 2 files changed, 40 insertions(+), 26 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 62e6b3c..c2b1569 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -882,13 +882,16 @@ static void pwm_dbg_show(struct pwm_chip *chip, struct 
seq_file *s)

for (i = 0; i < chip->npwm; i++) {
struct pwm_device *pwm = &chip->pwms[i];
+   struct pwm_state pstate;
+
+   pwm_get_state(pwm, &pstate);

seq_printf(s, " pwm-%-3d (%-20.20s):", i, pwm->label);

if (test_bit(PWMF_REQUESTED, &pwm->flags))
seq_puts(s, " requested");

-   if (pwm_is_enabled(pwm))
+   if (pstate.enabled)
seq_puts(s, " enabled");

seq_puts(s, "\n");
diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
index ab28c89..7ec1747 100644
--- a/drivers/pwm/sysfs.c
+++ b/drivers/pwm/sysfs.c
@@ -47,13 +47,13 @@ static ssize_t period_show(struct device *child,
 {
struct pwm_export *export = child_to_pwm_export(child);
const struct pwm_device *pwm = export->pwm;
-   unsigned int period;
+   struct pwm_state pstate;

mutex_lock(&export->lock);
-   period = pwm_get_period(pwm);
+   pwm_get_state(pwm, &pstate);
mutex_unlock(&export->lock);

-   return sprintf(buf, "%u\n", period);
+   return sprintf(buf, "%u\n", pstate.period);
 }

 static ssize_t period_store(struct device *child,
@@ -62,6 +62,7 @@ static ssize_t period_store(struct device *child,
 {
struct pwm_export *export = child_to_pwm_export(child);
struct pwm_device *pwm = export->pwm;
+   struct pwm_state pstate;
unsigned int val;
int ret;

@@ -70,7 +71,9 @@ static ssize_t period_store(struct device *child,
return ret;

mutex_lock(&export->lock);
-   ret = pwm_config(pwm, pwm_get_duty_cycle(pwm), val);
+   pwm_get_state(pwm, &pstate);
+   pstate.period = val;
+   ret = pwm_apply_state(pwm, &pstate);
mutex_unlock(&export->lock);

return ret ? : size;
@@ -82,13 +85,13 @@ static ssize_t duty_cycle_show(struct device *child,
 {
struct pwm_export *export = child_to_pwm_export(child);
const struct pwm_device *pwm = export->pwm;
-   unsigned int duty;
+   struct pwm_state pstate;

mutex_lock(&export->lock);
-   duty = pwm_get_duty_cycle(pwm);
+   pwm_get_state(pwm, &pstate);
mutex_unlock(&export->lock);

-   return sprintf(buf, "%u\n", duty);
+   return sprintf(buf, "%u\n", pstate.duty_cycle);
 }

 static ssize_t duty_cycle_store(struct device *child,
@@ -97,6 +100,7 @@ static ssize_t duty_cycle_store(struct device *child,
 {
struct pwm_export *export = child_to_pwm_export(child);
struct pwm_device *pwm = export->pwm;
+   struct pwm_state pstate;
unsigned int val;
int ret;

@@ -105,7 +109,9 @@ static ssize_t duty_cycle_store(struct device *child,
return ret;

mutex_lock(&export->lock);
-   ret = pwm_config(pwm, val, pwm_get_period(pwm));
+   pwm_get_state(pwm, &pstate);
+   pstate.duty_cycle = val;
+   ret = pwm_apply_state(pwm, &pstate);
mutex_unlock(&export->lock);

return ret ? : size;
@@ -117,13 +123,13 @@ static ssize_t enable_show(struct device *child,
 {
struct pwm_export *export = child_to_pwm_export(child);
const struct pwm_device *pwm = export->pwm;
-   bool enabled;
+   struct pwm_state pstate;

mutex_lock(&export->lock);
-   enabled = pwm_is_enabled(pwm);
+   pwm_get_state(pwm, &pstate);
mutex_unlock(&export->lock);

-   return sprintf(buf, "%d\n", enabled);
+   return sprintf(buf, "%d\n", pstate.enabled);
 }

 static ssize_t enable_store(struct device *child,
@@ -132,24 +138,20 @@ static ssize_t enable_store(struct device *child,
 {
struct pwm_export *export = child_to_pwm_export(child);
struct pwm_device *pwm = export->pwm;
+   struct pwm_state pstate;
int val, ret;

ret = kstrtoint(buf, 0, &val);
if (ret)
return ret;

+   if (val != 0 && val != 1)
+   return -EINVAL;
+
mutex_lock(&export->lock);
-   switch (val) {
-   case 0:
-   pwm_disable(pwm);
-   break;
-   case 1:
-   ret = pwm_enable(pwm);
-   break;
-   default:
-   ret = -EINVAL;
-   break;
-   }
+   pwm_get_state(pwm, &pstate);
+   pstate.enabled = val;
+   ret = pwm_apply_state(pwm, &pstate);
mutex_unlock(&export->lock);

return ret ? : size;
@@ -162,9 +

[PATCH v5 18/46] pwm: add the core infrastructure to allow atomic update

2016-03-30 Thread Boris Brezillon
Add an ->apply() method to the pwm_ops struct to allow PWM drivers to
implement atomic update.
This method will be preferred over the ->enable(), ->disable() and
->config() methods if available.

Add the pwm_apply_state() function to the PWM user API.

Note that the pwm_apply_state() does not guarantee the atomicity of the
update operation, it all depends on the availability and implementation
of the ->apply() method.

pwm_enable/disable/set_polarity/config() are now implemented as wrappers
around the pwm_apply_state() function.

Signed-off-by: Boris Brezillon 
---
 drivers/pwm/core.c  | 155 ++-
 include/linux/pwm.h | 207 +---
 2 files changed, 220 insertions(+), 142 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index a909c64..62e6b3c 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -226,6 +226,19 @@ void *pwm_get_chip_data(struct pwm_device *pwm)
 }
 EXPORT_SYMBOL_GPL(pwm_get_chip_data);

+static bool pwm_ops_check(const struct pwm_ops *ops)
+{
+   /* driver supports legacy, non-atomic operation */
+   if (ops->config && ops->enable && ops->disable)
+   return true;
+
+   /* driver supports atomic operation */
+   if (ops->apply)
+   return true;
+
+   return false;
+}
+
 /**
  * pwmchip_add_with_polarity() - register a new PWM chip
  * @chip: the PWM chip to add
@@ -244,8 +257,10 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
unsigned int i;
int ret;

-   if (!chip || !chip->dev || !chip->ops || !chip->ops->config ||
-   !chip->ops->enable || !chip->ops->disable || !chip->npwm)
+   if (!chip || !chip->dev || !chip->ops || !chip->npwm)
+   return -EINVAL;
+
+   if (!pwm_ops_check(chip->ops))
return -EINVAL;

mutex_lock(&pwm_lock);
@@ -431,102 +446,72 @@ void pwm_free(struct pwm_device *pwm)
 EXPORT_SYMBOL_GPL(pwm_free);

 /**
- * pwm_config() - change a PWM device configuration
+ * pwm_apply_state() - atomically apply a new state to a PWM device
  * @pwm: PWM device
- * @duty_ns: "on" time (in nanoseconds)
- * @period_ns: duration (in nanoseconds) of one cycle
- *
- * Returns: 0 on success or a negative error code on failure.
+ * @state: new state to apply. This can be adjusted by the PWM driver
+ *if the requested config is not achievable, for example,
+ *->duty_cycle and ->period might be approximated.
  */
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state)
 {
int err;

-   if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns)
-   return -EINVAL;
-
-   err = pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
-   if (err)
-   return err;
-
-   pwm->state.duty_cycle = duty_ns;
-   pwm->state.period = period_ns;
-
-   return 0;
-}
-EXPORT_SYMBOL_GPL(pwm_config);
-
-/**
- * pwm_set_polarity() - configure the polarity of a PWM signal
- * @pwm: PWM device
- * @polarity: new polarity of the PWM signal
- *
- * Note that the polarity cannot be configured while the PWM device is
- * enabled.
- *
- * Returns: 0 on success or a negative error code on failure.
- */
-int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
-{
-   int err;
-
-   if (!pwm || !pwm->chip->ops)
-   return -EINVAL;
-
-   if (!pwm->chip->ops->set_polarity)
-   return -ENOSYS;
-
-   if (pwm_is_enabled(pwm))
-   return -EBUSY;
-
-   err = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
-   if (err)
-   return err;
-
-   pwm->state.polarity = polarity;
-
-   return 0;
-}
-EXPORT_SYMBOL_GPL(pwm_set_polarity);
-
-/**
- * pwm_enable() - start a PWM output toggling
- * @pwm: PWM device
- *
- * Returns: 0 on success or a negative error code on failure.
- */
-int pwm_enable(struct pwm_device *pwm)
-{
-   int err = 0;
-
if (!pwm)
return -EINVAL;

-   if (!pwm_is_enabled(pwm)) {
-   err = pwm->chip->ops->enable(pwm->chip, pwm);
-   if (!err)
-   pwm->state.enabled = true;
-   }
+   if (!memcmp(state, &pwm->state, sizeof(*state)))
+   return 0;

-   return err;
-}
-EXPORT_SYMBOL_GPL(pwm_enable);
+   if (pwm->chip->ops->apply) {
+   err = pwm->chip->ops->apply(pwm->chip, pwm, state);
+   if (err)
+   return err;
+   } else {
+   /*
+* FIXME: restore the initial state in case of error.
+*/
+   if (state->polarity != pwm->state.polarity) {
+   if (!pwm->chip->ops->set_polarity)
+   return -ENOTSUPP;
+
+   /*
+* Changing the polarity of a running 

[PATCH v5 17/46] pwm: add the PWM initial state retrieval infra

2016-03-30 Thread Boris Brezillon
Add a ->get_state() function to the pwm_ops struct to let PWM drivers
initialize the PWM state attached to a PWM device.

Signed-off-by: Boris Brezillon 
---
 drivers/pwm/core.c  | 3 +++
 include/linux/pwm.h | 5 +
 2 files changed, 8 insertions(+)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index c240b54..a909c64 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -270,6 +270,9 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
pwm->hwpwm = i;
pwm->state.polarity = polarity;

+   if (chip->ops->get_state)
+   chip->ops->get_state(chip, pwm, &pwm->state);
+
radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
}

diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 55bf463..ceedcf8 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -211,6 +211,9 @@ static inline void pwm_get_args(const struct pwm_device 
*pwm,
  * @set_polarity: configure the polarity of this PWM
  * @enable: enable PWM output toggling
  * @disable: disable PWM output toggling
+ * @get_state: get the current PWM state. This function is only
+ *called once per PWM device when the PWM chip is
+ *registered.
  * @dbg_show: optional routine to show contents in debugfs
  * @owner: helps prevent removal of modules exporting active PWMs
  */
@@ -223,6 +226,8 @@ struct pwm_ops {
enum pwm_polarity polarity);
int (*enable)(struct pwm_chip *chip, struct pwm_device *pwm);
void (*disable)(struct pwm_chip *chip, struct pwm_device *pwm);
+   void (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *pstate);
 #ifdef CONFIG_DEBUG_FS
void (*dbg_show)(struct pwm_chip *chip, struct seq_file *s);
 #endif
-- 
2.5.0



[PATCH v5 16/46] pwm: move the enabled/disabled info into pwm_state

2016-03-30 Thread Boris Brezillon
Prepare the transition to PWM atomic update by moving the enabled/disabled
state into the pwm_state struct. This way we can easily update the whole
PWM state by copying the new state in the ->state field.

Signed-off-by: Boris Brezillon 
---
 drivers/pwm/core.c  | 13 +
 include/linux/pwm.h | 11 ---
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index f3f91e7..c240b54 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -499,10 +499,10 @@ int pwm_enable(struct pwm_device *pwm)
if (!pwm)
return -EINVAL;

-   if (!test_and_set_bit(PWMF_ENABLED, &pwm->flags)) {
+   if (!pwm_is_enabled(pwm)) {
err = pwm->chip->ops->enable(pwm->chip, pwm);
-   if (err)
-   clear_bit(PWMF_ENABLED, &pwm->flags);
+   if (!err)
+   pwm->state.enabled = true;
}

return err;
@@ -515,8 +515,13 @@ EXPORT_SYMBOL_GPL(pwm_enable);
  */
 void pwm_disable(struct pwm_device *pwm)
 {
-   if (pwm && test_and_clear_bit(PWMF_ENABLED, &pwm->flags))
+   if (!pwm)
+   return;
+
+   if (pwm_is_enabled(pwm)) {
pwm->chip->ops->disable(pwm->chip, pwm);
+   pwm->state.enabled = false;
+   }
 }
 EXPORT_SYMBOL_GPL(pwm_disable);

diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index f0f0f37..55bf463 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -93,8 +93,7 @@ struct pwm_args {

 enum {
PWMF_REQUESTED = 1 << 0,
-   PWMF_ENABLED = 1 << 1,
-   PWMF_EXPORTED = 1 << 2,
+   PWMF_EXPORTED = 1 << 1,
 };

 /*
@@ -102,11 +101,13 @@ enum {
  * @period: PWM period (in nanoseconds)
  * @duty_cycle: PWM duty cycle (in nanoseconds)
  * @polarity: PWM polarity
+ * @enabled: PWM enabled status
  */
 struct pwm_state {
unsigned int period;
unsigned int duty_cycle;
enum pwm_polarity polarity;
+   bool enabled;
 };

 /**
@@ -145,7 +146,11 @@ static inline void pwm_get_state(const struct pwm_device 
*pwm,

 static inline bool pwm_is_enabled(const struct pwm_device *pwm)
 {
-   return test_bit(PWMF_ENABLED, &pwm->flags);
+   struct pwm_state pstate;
+
+   pwm_get_state(pwm, &pstate);
+
+   return pstate.enabled;
 }

 static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
-- 
2.5.0



[PATCH v5 15/46] pwm: introduce the pwm_state concept

2016-03-30 Thread Boris Brezillon
The PWM state, represented by its period, duty_cycle and polarity,
is currently directly stored in the PWM device.
Declare a pwm_state structure embedding those field so that we can later
use this struct to atomically update all the PWM parameters at once.

All pwm_get_xxx() helpers are now implemented as wrappers around
pwm_get_state().

Signed-off-by: Boris Brezillon 
---
 drivers/pwm/core.c  |  8 
 include/linux/pwm.h | 54 +
 2 files changed, 46 insertions(+), 16 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 6433059..f3f91e7 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -268,7 +268,7 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
pwm->chip = chip;
pwm->pwm = chip->base + i;
pwm->hwpwm = i;
-   pwm->polarity = polarity;
+   pwm->state.polarity = polarity;

radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
}
@@ -446,8 +446,8 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int 
period_ns)
if (err)
return err;

-   pwm->duty_cycle = duty_ns;
-   pwm->period = period_ns;
+   pwm->state.duty_cycle = duty_ns;
+   pwm->state.period = period_ns;

return 0;
 }
@@ -480,7 +480,7 @@ int pwm_set_polarity(struct pwm_device *pwm, enum 
pwm_polarity polarity)
if (err)
return err;

-   pwm->polarity = polarity;
+   pwm->state.polarity = polarity;

return 0;
 }
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index ed65354..f0f0f37 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -97,6 +97,18 @@ enum {
PWMF_EXPORTED = 1 << 2,
 };

+/*
+ * struct pwm_state - state of a PWM channel
+ * @period: PWM period (in nanoseconds)
+ * @duty_cycle: PWM duty cycle (in nanoseconds)
+ * @polarity: PWM polarity
+ */
+struct pwm_state {
+   unsigned int period;
+   unsigned int duty_cycle;
+   enum pwm_polarity polarity;
+};
+
 /**
  * struct pwm_device - PWM channel object
  * @label: name of the PWM device
@@ -105,10 +117,8 @@ enum {
  * @pwm: global index of the PWM device
  * @chip: PWM chip providing this PWM device
  * @chip_data: chip-private data associated with the PWM device
- * @period: period of the PWM signal (in nanoseconds)
- * @duty_cycle: duty cycle of the PWM signal (in nanoseconds)
- * @polarity: polarity of the PWM signal
  * @args: PWM arguments
+ * @state: curent PWM channel state
  */
 struct pwm_device {
const char *label;
@@ -118,13 +128,21 @@ struct pwm_device {
struct pwm_chip *chip;
void *chip_data;

-   unsigned int period;
-   unsigned int duty_cycle;
-   enum pwm_polarity polarity;
-
struct pwm_args args;
+   struct pwm_state state;
 };

+/**
+ * pwm_get_state() - retrieve the current PWM state
+ * @pwm: PWM device
+ * @state: state to fill with the current PWM state
+ */
+static inline void pwm_get_state(const struct pwm_device *pwm,
+struct pwm_state *state)
+{
+   *state = pwm->state;
+}
+
 static inline bool pwm_is_enabled(const struct pwm_device *pwm)
 {
return test_bit(PWMF_ENABLED, &pwm->flags);
@@ -133,23 +151,31 @@ static inline bool pwm_is_enabled(const struct pwm_device 
*pwm)
 static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
 {
if (pwm)
-   pwm->period = period;
+   pwm->state.period = period;
 }

 static inline unsigned int pwm_get_period(const struct pwm_device *pwm)
 {
-   return pwm ? pwm->period : 0;
+   struct pwm_state pstate;
+
+   pwm_get_state(pwm, &pstate);
+
+   return pstate.period;
 }

 static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int 
duty)
 {
if (pwm)
-   pwm->duty_cycle = duty;
+   pwm->state.duty_cycle = duty;
 }

 static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm)
 {
-   return pwm ? pwm->duty_cycle : 0;
+   struct pwm_state pstate;
+
+   pwm_get_state(pwm, &pstate);
+
+   return pstate.duty_cycle;
 }

 /*
@@ -159,7 +185,11 @@ int pwm_set_polarity(struct pwm_device *pwm, enum 
pwm_polarity polarity);

 static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
 {
-   return pwm ? pwm->polarity : PWM_POLARITY_NORMAL;
+   struct pwm_state pstate;
+
+   pwm_get_state(pwm, &pstate);
+
+   return pstate.polarity;
 }

 static inline void pwm_get_args(const struct pwm_device *pwm,
-- 
2.5.0



[PATCH v5 14/46] pwm: keep PWM state in sync with hardware state

2016-03-30 Thread Boris Brezillon
Before the introduction of pwm_args, the core and some drivers were
resetting the PWM period and polarity states to the reference values
(those provided through the DT, a PWM lookup table or hardcoded in the
driver).

Now that all PWM users are correctly using pwm_args to configure their
PWM device, we can safely remove some pwm_set_period/polarity() calls.

Signed-off-by: Boris Brezillon 
---
 drivers/pwm/core.c | 5 -
 drivers/pwm/pwm-clps711x.c | 1 -
 drivers/pwm/pwm-pxa.c  | 1 -
 3 files changed, 7 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index cd55d61..6433059 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -147,13 +147,11 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct 
of_phandle_args *args)
return pwm;

pwm->args.period = args->args[1];
-   pwm_set_period(pwm, pwm->args.period);

if (args->args[2] & PWM_POLARITY_INVERTED)
pwm->args.polarity = PWM_POLARITY_INVERSED;
else
pwm->args.polarity = PWM_POLARITY_NORMAL;
-   pwm_set_polarity(pwm, pwm->args.polarity);

return pwm;
 }
@@ -175,7 +173,6 @@ of_pwm_simple_xlate(struct pwm_chip *pc, const struct 
of_phandle_args *args)
return pwm;

pwm->args.period = args->args[1];
-   pwm_set_period(pwm, pwm->args.period);

return pwm;
 }
@@ -745,8 +742,6 @@ struct pwm_device *pwm_get(struct device *dev, const char 
*con_id)

pwm->args.period = chosen->period;
pwm->args.polarity = chosen->polarity;
-   pwm_set_period(pwm, chosen->period);
-   pwm_set_polarity(pwm, chosen->polarity);

 out:
mutex_unlock(&pwm_lookup_lock);
diff --git a/drivers/pwm/pwm-clps711x.c b/drivers/pwm/pwm-clps711x.c
index 807a48d..7d33542 100644
--- a/drivers/pwm/pwm-clps711x.c
+++ b/drivers/pwm/pwm-clps711x.c
@@ -61,7 +61,6 @@ static int clps711x_pwm_request(struct pwm_chip *chip, struct 
pwm_device *pwm)

/* Store constant period value */
pwm->args.period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, freq);
-   pwm_set_period(pwm, pwm->args.period);

return 0;
 }
diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c
index 3fcc886..58b709f 100644
--- a/drivers/pwm/pwm-pxa.c
+++ b/drivers/pwm/pwm-pxa.c
@@ -161,7 +161,6 @@ pxa_pwm_of_xlate(struct pwm_chip *pc, const struct 
of_phandle_args *args)
return pwm;

pwm->args.period = args->args[0];
-   pwm_set_period(pwm, args->args[0]);

return pwm;
 }
-- 
2.5.0



[PATCH v5 13/46] backlight: pwm_bl: use pwm_get_args() where appropriate

2016-03-30 Thread Boris Brezillon
The PWM framework has clarified the concept of reference PWM config
(the platform dependent config retrieved from the DT or the PWM
lookup table) and real PWM state.

Use pwm_get_args() when the PWM user wants to retrieve this reference
config and not the current state.

This is part of the rework allowing the PWM framework to support
hardware readout and expose real PWM state even when the PWM has
just been requested (before the user calls pwm_config/enable/disable()).

Signed-off-by: Boris Brezillon 
---
 drivers/video/backlight/pwm_bl.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index a33a290..2479c11 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -201,6 +201,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
struct device_node *node = pdev->dev.of_node;
struct pwm_bl_data *pb;
int initial_blank = FB_BLANK_UNBLANK;
+   struct pwm_args pargs = { };
int ret;

if (!data) {
@@ -312,7 +313,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
 * set the period from platform data if it has not already been set
 * via the PWM lookup table.
 */
-   pb->period = pwm_get_period(pb->pwm);
+   pwm_get_args(pb->pwm, &pargs);
+   pb->period = pargs.period;
if (!pb->period && (data->pwm_period_ns > 0))
pb->period = data->pwm_period_ns;

-- 
2.5.0



[PATCH v5 12/46] fbdev: ssd1307fb: use pwm_get_args() where appropriate

2016-03-30 Thread Boris Brezillon
The PWM framework has clarified the concept of reference PWM config
(the platform dependent config retrieved from the DT or the PWM
lookup table) and real PWM state.

Use pwm_get_args() when the PWM user wants to retrieve this reference
config and not the current state.

This is part of the rework allowing the PWM framework to support
hardware readout and expose real PWM state even when the PWM has
just been requested (before the user calls pwm_config/enable/disable()).

Signed-off-by: Boris Brezillon 
---
 drivers/video/fbdev/ssd1307fb.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c
index fa34808..df9c63a 100644
--- a/drivers/video/fbdev/ssd1307fb.c
+++ b/drivers/video/fbdev/ssd1307fb.c
@@ -286,6 +286,7 @@ static int ssd1307fb_init(struct ssd1307fb_par *par)
 {
int ret;
u32 precharge, dclk, com_invdir, compins;
+   struct pwm_args pargs = { };

if (par->device_info->need_pwm) {
par->pwm = pwm_get(&par->client->dev, NULL);
@@ -294,7 +295,8 @@ static int ssd1307fb_init(struct ssd1307fb_par *par)
return PTR_ERR(par->pwm);
}

-   par->pwm_period = pwm_get_period(par->pwm);
+   pwm_get_args(par->pwm, &pargs);
+   par->pwm_period = pargs.period;
/* Enable the PWM */
pwm_config(par->pwm, par->pwm_period / 2, par->pwm_period);
pwm_enable(par->pwm);
-- 
2.5.0



[PATCH v5 11/46] regulator: pwm: use pwm_get_args() where appropriate

2016-03-30 Thread Boris Brezillon
The PWM framework has clarified the concept of reference PWM config
(the platform dependent config retrieved from the DT or the PWM
lookup table) and real PWM state.

Use pwm_get_args() when the PWM user wants to retrieve this reference
config and not the current state.

This is part of the rework allowing the PWM framework to support
hardware readout and expose real PWM state even when the PWM has
just been requested (before the user calls pwm_config/enable/disable()).

Signed-off-by: Boris Brezillon 
---
 drivers/regulator/pwm-regulator.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/regulator/pwm-regulator.c 
b/drivers/regulator/pwm-regulator.c
index 4689d62..9154c47 100644
--- a/drivers/regulator/pwm-regulator.c
+++ b/drivers/regulator/pwm-regulator.c
@@ -59,16 +59,16 @@ static int pwm_regulator_set_voltage_sel(struct 
regulator_dev *rdev,
 unsigned selector)
 {
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
-   unsigned int pwm_reg_period;
+   struct pwm_args pargs = { };
int dutycycle;
int ret;

-   pwm_reg_period = pwm_get_period(drvdata->pwm);
+   pwm_get_args(drvdata->pwm, &pargs);

-   dutycycle = (pwm_reg_period *
+   dutycycle = (pargs.period *
drvdata->duty_cycle_table[selector].dutycycle) / 100;

-   ret = pwm_config(drvdata->pwm, dutycycle, pwm_reg_period);
+   ret = pwm_config(drvdata->pwm, dutycycle, pargs.period);
if (ret) {
dev_err(&rdev->dev, "Failed to configure PWM\n");
return ret;
@@ -138,13 +138,15 @@ static int pwm_regulator_set_voltage(struct regulator_dev 
*rdev,
 {
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
unsigned int ramp_delay = rdev->constraints->ramp_delay;
-   unsigned int period = pwm_get_period(drvdata->pwm);
+   struct pwm_args pargs = { };
int duty_cycle;
int ret;

+   pwm_get_args(drvdata->pwm, &pargs);
duty_cycle = pwm_voltage_to_duty_cycle_percentage(rdev, min_uV);

-   ret = pwm_config(drvdata->pwm, (period / 100) * duty_cycle, period);
+   ret = pwm_config(drvdata->pwm, (pargs.period / 100) * duty_cycle,
+pargs.period);
if (ret) {
dev_err(&rdev->dev, "Failed to configure PWM\n");
return ret;
-- 
2.5.0



[PATCH v5 10/46] leds: pwm: use pwm_get_args() where appropriate

2016-03-30 Thread Boris Brezillon
The PWM framework has clarified the concept of reference PWM config
(the platform dependent config retrieved from the DT or the PWM
lookup table) and real PWM state.

Use pwm_get_args() when the PWM user wants to retrieve this reference
config and not the current state.

This is part of the rework allowing the PWM framework to support
hardware readout and expose real PWM state even when the PWM has
just been requested (before the user calls pwm_config/enable/disable()).

Signed-off-by: Boris Brezillon 
---
 drivers/leds/leds-pwm.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index 4783bac..b48231c 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -91,6 +91,7 @@ static int led_pwm_add(struct device *dev, struct 
led_pwm_priv *priv,
   struct led_pwm *led, struct device_node *child)
 {
struct led_pwm_data *led_data = &priv->leds[priv->num_leds];
+   struct pwm_args pargs = { };
int ret;

led_data->active_low = led->active_low;
@@ -117,7 +118,8 @@ static int led_pwm_add(struct device *dev, struct 
led_pwm_priv *priv,
else
led_data->cdev.brightness_set_blocking = led_pwm_set_blocking;

-   led_data->period = pwm_get_period(led_data->pwm);
+   pwm_get_args(led_data->pwm, &pargs);
+   led_data->period = pargs.period;
if (!led_data->period && (led->pwm_period_ns > 0))
led_data->period = led->pwm_period_ns;

-- 
2.5.0



[PATCH v5 09/46] misc: max77693-haptic: use pwm_get_args() where appropriate

2016-03-30 Thread Boris Brezillon
The PWM framework has clarified the concept of reference PWM config
(the platform dependent config retrieved from the DT or the PWM
lookup table) and real PWM state.

Use pwm_get_args() when the PWM user wants to retrieve this reference
config and not the current state.

This is part of the rework allowing the PWM framework to support
hardware readout and expose real PWM state even when the PWM has
just been requested (before the user calls pwm_config/enable/disable()).

Signed-off-by: Boris Brezillon 
---
 drivers/input/misc/max77693-haptic.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/input/misc/max77693-haptic.c 
b/drivers/input/misc/max77693-haptic.c
index 6d96bff..cf6aac0 100644
--- a/drivers/input/misc/max77693-haptic.c
+++ b/drivers/input/misc/max77693-haptic.c
@@ -70,10 +70,13 @@ struct max77693_haptic {

 static int max77693_haptic_set_duty_cycle(struct max77693_haptic *haptic)
 {
-   int delta = (haptic->pwm_dev->period + haptic->pwm_duty) / 2;
+   struct pwm_args pargs = { };
+   int delta;
int error;

-   error = pwm_config(haptic->pwm_dev, delta, haptic->pwm_dev->period);
+   pwm_get_args(haptic->pwm_dev, &pargs);
+   delta = (pargs.period + haptic->pwm_duty) / 2;
+   error = pwm_config(haptic->pwm_dev, delta, pargs.period);
if (error) {
dev_err(haptic->dev, "failed to configure pwm: %d\n", error);
return error;
@@ -234,6 +237,7 @@ static int max77693_haptic_play_effect(struct input_dev 
*dev, void *data,
   struct ff_effect *effect)
 {
struct max77693_haptic *haptic = input_get_drvdata(dev);
+   struct pwm_args pargs = { };
u64 period_mag_multi;

haptic->magnitude = effect->u.rumble.strong_magnitude;
@@ -245,7 +249,8 @@ static int max77693_haptic_play_effect(struct input_dev 
*dev, void *data,
 * The formula to convert magnitude to pwm_duty as follows:
 * - pwm_duty = (magnitude * pwm_period) / MAX_MAGNITUDE(0x)
 */
-   period_mag_multi = (u64)haptic->pwm_dev->period * haptic->magnitude;
+   pwm_get_args(haptic->pwm_dev, &pargs);
+   period_mag_multi = (u64)pargs.period * haptic->magnitude;
haptic->pwm_duty = (unsigned int)(period_mag_multi >>
MAX_MAGNITUDE_SHIFT);

-- 
2.5.0



[PATCH v5 08/46] hwmon: pwm-fan: use pwm_get_args() where appropriate

2016-03-30 Thread Boris Brezillon
The PWM framework has clarified the concept of reference PWM config
(the platform dependent config retrieved from the DT or the PWM
lookup table) and real PWM state.

Use pwm_get_args() when the PWM user wants to retrieve this reference
config and not the current state.

This is part of the rework allowing the PWM framework to support
hardware readout and expose real PWM state even when the PWM has
just been requested (before the user calls pwm_config/enable/disable()).

Signed-off-by: Boris Brezillon 
---
 drivers/hwmon/pwm-fan.c | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c
index 3e23003..82c5656 100644
--- a/drivers/hwmon/pwm-fan.c
+++ b/drivers/hwmon/pwm-fan.c
@@ -40,15 +40,18 @@ struct pwm_fan_ctx {

 static int  __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm)
 {
+   struct pwm_args pargs = { };
unsigned long duty;
int ret = 0;

+   pwm_get_args(ctx->pwm, &pargs);
+
mutex_lock(&ctx->lock);
if (ctx->pwm_value == pwm)
goto exit_set_pwm_err;

-   duty = DIV_ROUND_UP(pwm * (ctx->pwm->period - 1), MAX_PWM);
-   ret = pwm_config(ctx->pwm, duty, ctx->pwm->period);
+   duty = DIV_ROUND_UP(pwm * (pargs.period - 1), MAX_PWM);
+   ret = pwm_config(ctx->pwm, duty, pargs.period);
if (ret)
goto exit_set_pwm_err;

@@ -214,6 +217,7 @@ static int pwm_fan_of_get_cooling_data(struct device *dev,
 static int pwm_fan_probe(struct platform_device *pdev)
 {
struct thermal_cooling_device *cdev;
+   struct pwm_args pargs = { };
struct pwm_fan_ctx *ctx;
struct device *hwmon;
int duty_cycle;
@@ -234,10 +238,11 @@ static int pwm_fan_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ctx);

/* Set duty cycle to maximum allowed */
-   duty_cycle = ctx->pwm->period - 1;
+   pwm_get_args(ctx->pwm, &pargs);
+   duty_cycle = pargs.period - 1;
ctx->pwm_value = MAX_PWM;

-   ret = pwm_config(ctx->pwm, duty_cycle, ctx->pwm->period);
+   ret = pwm_config(ctx->pwm, duty_cycle, pargs.period);
if (ret) {
dev_err(&pdev->dev, "Failed to configure PWM\n");
return ret;
@@ -303,14 +308,16 @@ static int pwm_fan_suspend(struct device *dev)
 static int pwm_fan_resume(struct device *dev)
 {
struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
+   struct pwm_args pargs = { };
unsigned long duty;
int ret;

if (ctx->pwm_value == 0)
return 0;

-   duty = DIV_ROUND_UP(ctx->pwm_value * (ctx->pwm->period - 1), MAX_PWM);
-   ret = pwm_config(ctx->pwm, duty, ctx->pwm->period);
+   pwm_get_args(ctx->pwm, &pargs);
+   duty = DIV_ROUND_UP(ctx->pwm_value * (pargs.period - 1), MAX_PWM);
+   ret = pwm_config(ctx->pwm, duty, pargs.period);
if (ret)
return ret;
return pwm_enable(ctx->pwm);
-- 
2.5.0



[PATCH v5 07/46] clk: pwm: use pwm_get_args() where appropriate

2016-03-30 Thread Boris Brezillon
The PWM framework has clarified the concept of reference PWM config
(the platform dependent config retrieved from the DT or the PWM
lookup table) and real PWM state.

Use pwm_get_args() when the PWM user wants to retrieve this reference
config and not the current state.

This is part of the rework allowing the PWM framework to support
hardware readout and expose real PWM state even when the PWM has
just been requested (before the user calls pwm_config/enable/disable()).

Signed-off-by: Boris Brezillon 
---
 drivers/clk/clk-pwm.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/clk-pwm.c b/drivers/clk/clk-pwm.c
index 8830458..ebcd738 100644
--- a/drivers/clk/clk-pwm.c
+++ b/drivers/clk/clk-pwm.c
@@ -56,6 +56,7 @@ static const struct clk_ops clk_pwm_ops = {
 static int clk_pwm_probe(struct platform_device *pdev)
 {
struct device_node *node = pdev->dev.of_node;
+   struct pwm_args pargs = { };
struct clk_init_data init;
struct clk_pwm *clk_pwm;
struct pwm_device *pwm;
@@ -71,22 +72,23 @@ static int clk_pwm_probe(struct platform_device *pdev)
if (IS_ERR(pwm))
return PTR_ERR(pwm);

-   if (!pwm->period) {
+   pwm_get_args(pwm, &pargs);
+   if (!pargs.period) {
dev_err(&pdev->dev, "invalid PWM period\n");
return -EINVAL;
}

if (of_property_read_u32(node, "clock-frequency", &clk_pwm->fixed_rate))
-   clk_pwm->fixed_rate = NSEC_PER_SEC / pwm->period;
+   clk_pwm->fixed_rate = NSEC_PER_SEC / pargs.period;

-   if (pwm->period != NSEC_PER_SEC / clk_pwm->fixed_rate &&
-   pwm->period != DIV_ROUND_UP(NSEC_PER_SEC, clk_pwm->fixed_rate)) {
+   if (pargs.period != NSEC_PER_SEC / clk_pwm->fixed_rate &&
+   pargs.period != DIV_ROUND_UP(NSEC_PER_SEC, clk_pwm->fixed_rate)) {
dev_err(&pdev->dev,
"clock-frequency does not match PWM period\n");
return -EINVAL;
}

-   ret = pwm_config(pwm, (pwm->period + 1) >> 1, pwm->period);
+   ret = pwm_config(pwm, (pargs.period + 1) >> 1, pargs.period);
if (ret < 0)
return ret;

-- 
2.5.0



[PATCH v5 06/46] pwm: use pwm_get/set_xxx() helpers where appropriate

2016-03-30 Thread Boris Brezillon
Use pwm_get/set_xxx() helpers instead of directly accessing the pwm->xxx
field. Doing that will ease adaptation of the PWM framework to support
atomic update.

Signed-off-by: Boris Brezillon 
---
Patch generated with the following coccinelle script:

--->8---
virtual patch

@@
struct pwm_device *p;
expression e;
@@
(
-(p)->polarity = e;
+pwm_set_polarity(p, e);
|
-(p)->polarity
+pwm_get_polarity(p)
|
-(p)->period = e;
+pwm_set_period(p, e);
|
-(p)->period
+pwm_get_period(p)
|
-(p)->duty_cycle = e;
+pwm_set_duty_cycle(p, e);
|
-(p)->duty_cycle
+pwm_get_duty_cycle(p)
)
--->8---
---
 drivers/pwm/pwm-crc.c  | 2 +-
 drivers/pwm/pwm-lpc18xx-sct.c  | 2 +-
 drivers/pwm/pwm-omap-dmtimer.c | 2 +-
 drivers/pwm/pwm-sun4i.c| 3 ++-
 4 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/pwm/pwm-crc.c b/drivers/pwm/pwm-crc.c
index 7101c70..bd0ebd0 100644
--- a/drivers/pwm/pwm-crc.c
+++ b/drivers/pwm/pwm-crc.c
@@ -75,7 +75,7 @@ static int crc_pwm_config(struct pwm_chip *c, struct 
pwm_device *pwm,
return -EINVAL;
}

-   if (pwm->period != period_ns) {
+   if (pwm_get_period(pwm) != period_ns) {
int clk_div;

/* changing the clk divisor, need to disable fisrt */
diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c
index 9861fed..19dc64c 100644
--- a/drivers/pwm/pwm-lpc18xx-sct.c
+++ b/drivers/pwm/pwm-lpc18xx-sct.c
@@ -249,7 +249,7 @@ static int lpc18xx_pwm_enable(struct pwm_chip *chip, struct 
pwm_device *pwm)
   LPC18XX_PWM_EVSTATEMSK(lpc18xx_data->duty_event),
   LPC18XX_PWM_EVSTATEMSK_ALL);

-   if (pwm->polarity == PWM_POLARITY_NORMAL) {
+   if (pwm_get_polarity(pwm) == PWM_POLARITY_NORMAL) {
set_event = lpc18xx_pwm->period_event;
clear_event = lpc18xx_data->duty_event;
res_action = LPC18XX_PWM_RES_SET;
diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index b7e6ecb..3e95090 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -192,7 +192,7 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
load_value, load_value, match_value, match_value);

omap->pdata->set_pwm(omap->dm_timer,
- pwm->polarity == PWM_POLARITY_INVERSED,
+ pwm_get_polarity(pwm) == PWM_POLARITY_INVERSED,
  true,
  PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE);

diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index 67af9f6..03a99a5 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -354,7 +354,8 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
val = sun4i_pwm_readl(pwm, PWM_CTRL_REG);
for (i = 0; i < pwm->chip.npwm; i++)
if (!(val & BIT_CH(PWM_ACT_STATE, i)))
-   pwm->chip.pwms[i].polarity = PWM_POLARITY_INVERSED;
+   pwm_set_polarity(&pwm->chip.pwms[i],
+PWM_POLARITY_INVERSED);
clk_disable_unprepare(pwm->clk);

return 0;
-- 
2.5.0



[PATCH v5 05/46] pwm: introduce the pwm_args concept

2016-03-30 Thread Boris Brezillon
Currently the PWM core mixes the current PWM state with the per-platform
reference config (specified through the PWM lookup table, DT definition or
directly hardcoded in PWM drivers).

Create a pwm_args struct to store this reference config, so that PWM users
can differentiate the current config from the reference one.

Patch all places where pwm->args should be initialized. We keep the
pwm_set_polarity/period() calls until all PWM users are patched to
use pwm_args instead of pwm_get_period/polarity().

Signed-off-by: Boris Brezillon 
---
 drivers/pwm/core.c | 13 +
 drivers/pwm/pwm-clps711x.c |  3 ++-
 drivers/pwm/pwm-pxa.c  |  1 +
 include/linux/pwm.h| 26 ++
 4 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 7c330ff..cd55d61 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -146,12 +146,14 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct 
of_phandle_args *args)
if (IS_ERR(pwm))
return pwm;

-   pwm_set_period(pwm, args->args[1]);
+   pwm->args.period = args->args[1];
+   pwm_set_period(pwm, pwm->args.period);

if (args->args[2] & PWM_POLARITY_INVERTED)
-   pwm_set_polarity(pwm, PWM_POLARITY_INVERSED);
+   pwm->args.polarity = PWM_POLARITY_INVERSED;
else
-   pwm_set_polarity(pwm, PWM_POLARITY_NORMAL);
+   pwm->args.polarity = PWM_POLARITY_NORMAL;
+   pwm_set_polarity(pwm, pwm->args.polarity);

return pwm;
 }
@@ -172,7 +174,8 @@ of_pwm_simple_xlate(struct pwm_chip *pc, const struct 
of_phandle_args *args)
if (IS_ERR(pwm))
return pwm;

-   pwm_set_period(pwm, args->args[1]);
+   pwm->args.period = args->args[1];
+   pwm_set_period(pwm, pwm->args.period);

return pwm;
 }
@@ -740,6 +743,8 @@ struct pwm_device *pwm_get(struct device *dev, const char 
*con_id)
if (IS_ERR(pwm))
goto out;

+   pwm->args.period = chosen->period;
+   pwm->args.polarity = chosen->polarity;
pwm_set_period(pwm, chosen->period);
pwm_set_polarity(pwm, chosen->polarity);

diff --git a/drivers/pwm/pwm-clps711x.c b/drivers/pwm/pwm-clps711x.c
index a80c108..807a48d 100644
--- a/drivers/pwm/pwm-clps711x.c
+++ b/drivers/pwm/pwm-clps711x.c
@@ -60,7 +60,8 @@ static int clps711x_pwm_request(struct pwm_chip *chip, struct 
pwm_device *pwm)
return -EINVAL;

/* Store constant period value */
-   pwm_set_period(pwm, DIV_ROUND_CLOSEST(NSEC_PER_SEC, freq));
+   pwm->args.period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, freq);
+   pwm_set_period(pwm, pwm->args.period);

return 0;
 }
diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c
index cb2f702..3fcc886 100644
--- a/drivers/pwm/pwm-pxa.c
+++ b/drivers/pwm/pwm-pxa.c
@@ -160,6 +160,7 @@ pxa_pwm_of_xlate(struct pwm_chip *pc, const struct 
of_phandle_args *args)
if (IS_ERR(pwm))
return pwm;

+   pwm->args.period = args->args[0];
pwm_set_period(pwm, args->args[0]);

return pwm;
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 6555f01..ed65354 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -74,6 +74,23 @@ enum pwm_polarity {
PWM_POLARITY_INVERSED,
 };

+/**
+ * struct pwm_args - PWM arguments
+ * @period: reference period
+ * @polarity: reference polarity
+ *
+ * This structure describe board-dependent arguments attached to a PWM
+ * device. Those arguments are usually retrieved from the PWM lookup table or
+ * DT definition.
+ * This should not be confused with the PWM state: PWM args not representing
+ * the current PWM state, but the configuration the PWM user plan to use
+ * on this PWM device.
+ */
+struct pwm_args {
+   unsigned int period;
+   enum pwm_polarity polarity;
+};
+
 enum {
PWMF_REQUESTED = 1 << 0,
PWMF_ENABLED = 1 << 1,
@@ -91,6 +108,7 @@ enum {
  * @period: period of the PWM signal (in nanoseconds)
  * @duty_cycle: duty cycle of the PWM signal (in nanoseconds)
  * @polarity: polarity of the PWM signal
+ * @args: PWM arguments
  */
 struct pwm_device {
const char *label;
@@ -103,6 +121,8 @@ struct pwm_device {
unsigned int period;
unsigned int duty_cycle;
enum pwm_polarity polarity;
+
+   struct pwm_args args;
 };

 static inline bool pwm_is_enabled(const struct pwm_device *pwm)
@@ -142,6 +162,12 @@ static inline enum pwm_polarity pwm_get_polarity(const 
struct pwm_device *pwm)
return pwm ? pwm->polarity : PWM_POLARITY_NORMAL;
 }

+static inline void pwm_get_args(const struct pwm_device *pwm,
+   struct pwm_args *args)
+{
+   *args = pwm->args;
+}
+
 /**
  * struct pwm_ops - PWM controller operations
  * @request: optional hook for requesting a PWM
-- 
2.5.0



[PATCH v5 04/46] pwm: get rid of pwm->lock

2016-03-30 Thread Boris Brezillon
PWM devices are not protected against concurrent accesses. The lock in
pwm_device might let PWM users think it is, but it's actually only
protecting the enabled state.

Removing this lock should be fine as long as all PWM users are aware that
accesses to the PWM device have to be serialized, which seems to be the
case for all of them except the sysfs interface.
Patch the sysfs code by adding a lock to the pwm_export struct and making
sure it's taken for all accesses to the exported PWM device.

Signed-off-by: Boris Brezillon 
---
 drivers/pwm/core.c  | 19 --
 drivers/pwm/sysfs.c | 57 ++---
 include/linux/pwm.h |  2 --
 3 files changed, 50 insertions(+), 28 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 7831bc6..7c330ff 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -269,7 +269,6 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
pwm->pwm = chip->base + i;
pwm->hwpwm = i;
pwm->polarity = polarity;
-   mutex_init(&pwm->lock);

radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
}
@@ -474,22 +473,16 @@ int pwm_set_polarity(struct pwm_device *pwm, enum 
pwm_polarity polarity)
if (!pwm->chip->ops->set_polarity)
return -ENOSYS;

-   mutex_lock(&pwm->lock);
-
-   if (pwm_is_enabled(pwm)) {
-   err = -EBUSY;
-   goto unlock;
-   }
+   if (pwm_is_enabled(pwm))
+   return -EBUSY;

err = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
if (err)
-   goto unlock;
+   return err;

pwm->polarity = polarity;

-unlock:
-   mutex_unlock(&pwm->lock);
-   return err;
+   return 0;
 }
 EXPORT_SYMBOL_GPL(pwm_set_polarity);

@@ -506,16 +499,12 @@ int pwm_enable(struct pwm_device *pwm)
if (!pwm)
return -EINVAL;

-   mutex_lock(&pwm->lock);
-
if (!test_and_set_bit(PWMF_ENABLED, &pwm->flags)) {
err = pwm->chip->ops->enable(pwm->chip, pwm);
if (err)
clear_bit(PWMF_ENABLED, &pwm->flags);
}

-   mutex_unlock(&pwm->lock);
-
return err;
 }
 EXPORT_SYMBOL_GPL(pwm_enable);
diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
index 9c90886..ab28c89 100644
--- a/drivers/pwm/sysfs.c
+++ b/drivers/pwm/sysfs.c
@@ -26,6 +26,7 @@
 struct pwm_export {
struct device child;
struct pwm_device *pwm;
+   struct mutex lock;
 };

 static struct pwm_export *child_to_pwm_export(struct device *child)
@@ -44,16 +45,23 @@ static ssize_t period_show(struct device *child,
   struct device_attribute *attr,
   char *buf)
 {
-   const struct pwm_device *pwm = child_to_pwm_device(child);
+   struct pwm_export *export = child_to_pwm_export(child);
+   const struct pwm_device *pwm = export->pwm;
+   unsigned int period;
+
+   mutex_lock(&export->lock);
+   period = pwm_get_period(pwm);
+   mutex_unlock(&export->lock);

-   return sprintf(buf, "%u\n", pwm_get_period(pwm));
+   return sprintf(buf, "%u\n", period);
 }

 static ssize_t period_store(struct device *child,
struct device_attribute *attr,
const char *buf, size_t size)
 {
-   struct pwm_device *pwm = child_to_pwm_device(child);
+   struct pwm_export *export = child_to_pwm_export(child);
+   struct pwm_device *pwm = export->pwm;
unsigned int val;
int ret;

@@ -61,7 +69,9 @@ static ssize_t period_store(struct device *child,
if (ret)
return ret;

+   mutex_lock(&export->lock);
ret = pwm_config(pwm, pwm_get_duty_cycle(pwm), val);
+   mutex_unlock(&export->lock);

return ret ? : size;
 }
@@ -70,16 +80,23 @@ static ssize_t duty_cycle_show(struct device *child,
   struct device_attribute *attr,
   char *buf)
 {
-   const struct pwm_device *pwm = child_to_pwm_device(child);
+   struct pwm_export *export = child_to_pwm_export(child);
+   const struct pwm_device *pwm = export->pwm;
+   unsigned int duty;
+
+   mutex_lock(&export->lock);
+   duty = pwm_get_duty_cycle(pwm);
+   mutex_unlock(&export->lock);

-   return sprintf(buf, "%u\n", pwm_get_duty_cycle(pwm));
+   return sprintf(buf, "%u\n", duty);
 }

 static ssize_t duty_cycle_store(struct device *child,
struct device_attribute *attr,
const char *buf, size_t size)
 {
-   struct pwm_device *pwm = child_to_pwm_device(child);
+   struct pwm_export *export = child_to_pwm_export(child);
+   struct pwm_device *pwm = export->pwm;
unsigned int val;
int ret;

@@ -87,7 +104,9 @@ static ssize_t duty_cycle_store(struct device *chil

[PATCH v5 03/46] backlight: lm3630a_bl: stop messing with the pwm->period field

2016-03-30 Thread Boris Brezillon
pwm->period field is not supposed to be changed by PWM users. The only
ones authorized to change it are the PWM core and PWM drivers.

Signed-off-by: Boris Brezillon 
---
 drivers/video/backlight/lm3630a_bl.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/video/backlight/lm3630a_bl.c 
b/drivers/video/backlight/lm3630a_bl.c
index 35fe482..3d16bd6 100644
--- a/drivers/video/backlight/lm3630a_bl.c
+++ b/drivers/video/backlight/lm3630a_bl.c
@@ -162,7 +162,7 @@ static int lm3630a_intr_config(struct lm3630a_chip *pchip)

 static void lm3630a_pwm_ctrl(struct lm3630a_chip *pchip, int br, int br_max)
 {
-   unsigned int period = pwm_get_period(pchip->pwmd);
+   unsigned int period = pchip->pdata->pwm_period;
unsigned int duty = br * period / br_max;

pwm_config(pchip->pwmd, duty, period);
@@ -425,7 +425,6 @@ static int lm3630a_probe(struct i2c_client *client,
return PTR_ERR(pchip->pwmd);
}
}
-   pchip->pwmd->period = pdata->pwm_period;

/* interrupt enable  : irq 0 is not allowed */
pchip->irq = client->irq;
-- 
2.5.0



[PATCH v5 02/46] backlight: pwm_bl: remove useless call to pwm_set_period()

2016-03-30 Thread Boris Brezillon
The PWM period will be set when calling pwm_config. Remove this useless
call to pwm_set_period(), which might mess up with the internal PWM state.

Signed-off-by: Boris Brezillon 
Acked-by: Lee Jones 
---
 drivers/video/backlight/pwm_bl.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 64f9e1b..a33a290 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -313,10 +313,8 @@ static int pwm_backlight_probe(struct platform_device 
*pdev)
 * via the PWM lookup table.
 */
pb->period = pwm_get_period(pb->pwm);
-   if (!pb->period && (data->pwm_period_ns > 0)) {
+   if (!pb->period && (data->pwm_period_ns > 0))
pb->period = data->pwm_period_ns;
-   pwm_set_period(pb->pwm, data->pwm_period_ns);
-   }

pb->lth_brightness = data->lth_brightness * (pb->period / pb->scale);

-- 
2.5.0



[PATCH v5 01/46] pwm: rcar: make use of pwm_is_enabled()

2016-03-30 Thread Boris Brezillon
Commit 5c31252c4a86 ("pwm: Add the pwm_is_enabled() helper") introduced a
new function to test whether a PWM device is enabled or not without
manipulating PWM internal fields.
Hiding this is necessary if we want to smoothly move to the atomic PWM
config approach without impacting PWM drivers.
Fix this driver to use pwm_is_enabled() instead of directly accessing the
->flags field.

Signed-off-by: Boris Brezillon 
---
 drivers/pwm/pwm-rcar.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pwm/pwm-rcar.c b/drivers/pwm/pwm-rcar.c
index 7b8ac06..1c85ecc 100644
--- a/drivers/pwm/pwm-rcar.c
+++ b/drivers/pwm/pwm-rcar.c
@@ -157,7 +157,7 @@ static int rcar_pwm_config(struct pwm_chip *chip, struct 
pwm_device *pwm,
return div;

/* Let the core driver set pwm->period if disabled and duty_ns == 0 */
-   if (!test_bit(PWMF_ENABLED, &pwm->flags) && !duty_ns)
+   if (!pwm_is_enabled(pwm) && !duty_ns)
return 0;

rcar_pwm_update(rp, RCAR_PWMCR_SYNC, RCAR_PWMCR_SYNC, RCAR_PWMCR);
-- 
2.5.0



[PATCH v5 00/46] pwm: add support for atomic update

2016-03-30 Thread Boris Brezillon
Hello,

This series adds support for atomic PWM update, or IOW, the capability
to update all the parameters of a PWM device (enabled/disabled, period,
duty and polarity) in one go.

It also adds support for initial PWM state retrieval (or hardware readout),
which should allow smooth handover between the bootloader and Linux. For
example, critical PWM users (like critical regulators controlled by a PWM)
can query the current PWM state, and adapt the PWM config without having
to disable/enable the PWM, or abruptly change the period/dutycyle/polarity
config.

Thierry, I hope this version meets your expectations, if that's not the
case, could you let me know quickly so I can adjust the implementation
accordingly (I'd really like to get most of those changes in 4.7).

Best Regards,

Boris

Changes since v4:
- introduce pwm_args to expose per-board/platform config
- deprecate non-atomic APIs
- implement non-atomic functions as wrappers around atomic ones
- patch all PWM users to use the atomic API
- rename the ->reset_state() hook into ->get_state()
- drop most acks
- rework PWM config in the pwm-regulator driver
- patch sun4i and sti PWM drivers to support HW readout

Changes since v3:
- rebased on pwm/for-next after pulling 4.4-rc1
- replace direct access to pwm fields by pwm_get/set_xxx() helpers, thus
  fixing some build errors
- split changes to allow each maintainer to review/ack or take the
  modification through its subsystem

Changes since v2:
- rebased on top of 4.3-rc2
- reintroduced pwm-regulator patches

Changes since v1:
- dropped applied patches
- squashed Heiko's fixes into the rockchip driver changes
- made a few cosmetic changes
- added kerneldoc comments
- added Heiko's patch to display more information in debugfs
- dropped pwm-regulator patches (should be submitted separately)

*** BLURB HERE ***

Boris Brezillon (45):
  pwm: rcar: make use of pwm_is_enabled()
  backlight: pwm_bl: remove useless call to pwm_set_period()
  backlight: lm3630a_bl: stop messing with the pwm->period field
  pwm: get rid of pwm->lock
  pwm: introduce the pwm_args concept
  pwm: use pwm_get/set_xxx() helpers where appropriate
  clk: pwm: use pwm_get_args() where appropriate
  hwmon: pwm-fan: use pwm_get_args() where appropriate
  misc: max77693-haptic: use pwm_get_args() where appropriate
  leds: pwm: use pwm_get_args() where appropriate
  regulator: pwm: use pwm_get_args() where appropriate
  fbdev: ssd1307fb: use pwm_get_args() where appropriate
  backlight: pwm_bl: use pwm_get_args() where appropriate
  pwm: keep PWM state in sync with hardware state
  pwm: introduce the pwm_state concept
  pwm: move the enabled/disabled info into pwm_state
  pwm: add the PWM initial state retrieval infra
  pwm: add the core infrastructure to allow atomic update
  pwm: switch to the atomic API
  pwm: rockchip: add initial state retrieval
  pwm: rockchip: avoid glitches on already running PWMs
  pwm: rockchip: add support for atomic update
  pwm: sti: add support for initial state retrieval
  pwm: sti: avoid glitches on already running PWMs
  pwm: sun4i: implement hardware readout
  regulator: pwm: adjust PWM config at probe time
  regulator: pwm: swith to the atomic PWM API
  regulator: pwm: properly initialize the ->state field
  regulator: pwm: retrieve correct voltage
  pwm: update documentation
  pwm: deprecate pwm_config(), pwm_enable() and pwm_disable()
  pwm: replace pwm_disable() by pwm_apply_state()
  clk: pwm: switch to the atomic API
  hwmon: pwm-fan: switch to the atomic API
  input: misc: max77693: switch to the atomic API
  input: misc: max8997: switch to the atomic PWM API
  input: misc: pwm-beeper: switch to the atomic PWM API
  leds: pwm: switch to the atomic PWM API
  backlight: lm3630a: switch to the atomic PWM API
  backlight: lp855x: switch to the atomic PWM API
  backlight: lp8788: switch to the atomic PWM API
  backlight: pwm_bl: switch to the atomic PWM API
  video: ssd1307fb: switch to the atomic PWM API
  drm: i915: switch to the atomic PWM API
  ARM: s3c24xx: rx1950: switch to the atomic PWM API

Heiko Stübner (1):
  pwm: add information about polarity, duty cycle and period to debugfs

 Documentation/pwm.txt|  27 +++-
 arch/arm/mach-s3c24xx/mach-rx1950.c  |  17 +-
 drivers/clk/clk-pwm.c|  36 -
 drivers/gpu/drm/i915/intel_panel.c   |  39 +++--
 drivers/hwmon/pwm-fan.c  |  88 ++
 drivers/input/misc/max77693-haptic.c |  28 +++-
 drivers/input/misc/max8997_haptic.c  |  23 ++-
 drivers/input/misc/pwm-beeper.c  |  46 --
 drivers/leds/leds-pwm.c  |  15 +-
 drivers/pwm/core.c   | 186 ++---
 drivers/pwm/pwm-clps711x.c   |   2 +-
 drivers/pwm/pwm-crc.c|   2 +-
 drivers/pwm/pwm-lpc18xx-sct.c|   9 +-
 drivers/pwm/pwm-lpc32xx.c|   9 +-
 drivers/pwm/pwm-omap-dmtimer.c   |   2 +-
 drivers/pwm/pwm-pxa.c|   2 +-
 drivers/pwm/pwm-rcar.c  

[PATCH 1/2] drm: Untangle __KERNEL__ guards

2016-03-30 Thread Daniel Vetter
On Wed, Mar 30, 2016 at 04:56:17PM +0100, Emil Velikov wrote:
> On 30 March 2016 at 15:42, Daniel Vetter  wrote:
> > make headers_install can't handle fancy conditions, so let's simplify
> > things for it a bit.
> >
> > Cc: Emil Velikov 
> > Signed-off-by: Daniel Vetter 
> > ---
> >  include/uapi/drm/drm.h | 8 +++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
> > index c7ecc3abff03..3b56285a7e2a 100644
> > --- a/include/uapi/drm/drm.h
> > +++ b/include/uapi/drm/drm.h
> > @@ -36,7 +36,13 @@
> >  #ifndef _DRM_H_
> >  #define _DRM_H_
> >
> > -#if defined(__KERNEL__) || defined(__linux__)
> > +#if defined(__KERNEL__)
> > +
> > +#include 
> > +#include 
> > +typedef unsigned int drm_handle_t;
> > +
> > +#elif defined(__linux__)
> >
> Bit dubious how that used to work, and that the program fails with the
> original, yet handled "elif defined..." correctly.

I didn't dare looking into the horror show the script is - still charred
from looking too closely at kerneldoc ;-)

> Regardless,
> Reviewed-by: Emil Velikov 

Thanks for the review, all expect the last one (to make them pendantic
compliant, still missing r-b on that) applied to drm-misc.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH 3/3] drm: Move DRM_MODE_OBJECT_* to uapi headers

2016-03-30 Thread Daniel Vetter
On Wed, Mar 30, 2016 at 02:55:17PM -0300, Paulo Zanoni wrote:
> 2016-03-30 13:07 GMT-03:00 Emil Velikov :
> > On 30 March 2016 at 15:19, Daniel Vetter  wrote:
> >> These type defines are officially part of the uapi, but ended up in
> >> the wrong headers somehow when we split them all.
> >>
> >> Cc: Emil Velikov 
> >> Signed-off-by: Daniel Vetter 
> > The way it was done originally (by Paulo) with commit
> > c543188afb7a83e66161c026dc6fd5eb38dc0b63 it seemed deliberate. At the
> > same time the libdrm got a different treatment
> > 8c75703df0fdf65b3851f8eb5822705638decff3. Would be swell Paulo can
> > confirm (re: unintentional or deliberate difference), if he recalls
> > any of this :-)
> >
> > Barring any objections from Paulo
> 
> No objections from Paulo. The include/uapi directory didn't even exist
> at that time, and I guess I was just trying to make things work,
> without any specific coding philosophy in mind.

Yeah, I suspect that this was actually fumbled in the uapi split-up
somehow ...
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH 2/2] drm: Make uapi headers C89 pendantic compliant

2016-03-30 Thread Emil Velikov
On 30 March 2016 at 15:42, Daniel Vetter  wrote:
> This ports the below libdrm commit to the kernel
>
> commit 0f4452bb51306024fbf4cbf77d8baab20cefba67
> Author: Daniel Kurtz 
> Date:   Mon Aug 26 23:39:16 2013 +0800
>
> libdrm: Make some drm headers compatible with gcc -std=c89 -pedantic
>
> The following minor changes were needed to these headers:
>  * Convert // comments to /* */
>  * No , after final member of enum
>
> With these changes, these header files can be included by a program that
> is built with gcc options:
>   -std=c89 -Werror -pedantic
>
> Signed-off-by: Daniel Kurtz 
> Signed-off-by: Eric Anholt 
> Reviewed-by: Eric Anholt 
>
> Signed-off-by: Daniel Vetter 
Yes, please :-)

Reviewed-by: Emil Velikov 

-Emil


[RFC PATCH v1 0/4] Add Rockchip RGA support

2016-03-30 Thread Emil Velikov
On 29 March 2016 at 14:13, Emil Velikov  wrote:
> On 28 March 2016 at 23:13, Heiko Stübner  wrote:
>
>> I have the feeling we're going quite a bit off-topic right now :-) .
>> The binary-driver-crazyness, hasn't really anything to do with Yakir's 
>> support
>> for the RGA (which is about raster-graphics-acceleration, so 2d stuff).
>>
>> And me mentioning the armsoc-ddx was merely a means to allow some sort of
>> different userspace user, as requested in your original mail ;-) .
>>
> Seems like I forgot to state the obvious - for all the reasons
> mentioned, the armsoc ddx seems like a bad example.
>
>> Maybe you know a better use-case on where to demonstrate the viability of the
>> userspace API for it as originally requested.
> I'm afraid that my RockChip-foo is extremely limited. Perhaps the
> actual user of these should be mentioned ? xf86-video-rockhip (is
> there one ?) or any other effort/project that lacks some (all?) of the
> criticism listed.
>
> (Sort of) the bottom line - either reuse the existing interfaces or
> provide an approved, full blown userspace (libdrm demos/programs do
> not count) that uses the new interfaces.
>
> I haven't made these rules, just a fool^Wguy that repeats them so that
> people don't abuse them much. If in doubt check with Dave and Daniel V
> - they had enough repeating these.
>
I can see how my earlier response may have been come
across/interpreted as aggressive and/or demanding. Apologies anyone
got upset/annoyed.

Let me try in another light - if you guys are willing to have
xf86-video-rockchip or keep track of/co-maintain armsoc, pretty much
everyone will be over the moon. Personally I'd opt for the former,
taking the modesetting (the one in the xserver tree) as a base - it
has all the cool new bits ;-)

Regards,
Emil


[PATCH v7 1/5] staging/android: add num_fences field to struct sync_file_info

2016-03-30 Thread Greg Kroah-Hartman
On Wed, Mar 30, 2016 at 11:53:38PM -0300, Gustavo Padovan wrote:
> Hi Greg,
> 
> 2016-03-30 Greg Kroah-Hartman :
> 
> > On Thu, Mar 03, 2016 at 04:40:42PM -0300, Gustavo Padovan wrote:
> > > From: Gustavo Padovan 
> > 
> > 
> > 
> > Gustavo, can you resend both series of your android patches so I know I
> > have the latest ones to work with?  Please also collect the acks that
> > people have provided so far.
> 
> I have resent it already. The lastest patches on this series is v10,
> it contain the acks
> 
> https://lkml.org/lkml/2016/3/18/298

Ok, I'll review those, thanks.

greg k-h


next-20160330 build: 1 failures 7 warnings (next-20160330)

2016-03-30 Thread Boris Brezillon
Hi Mark,

On Wed, 30 Mar 2016 09:35:45 -0700
Mark Brown  wrote:

> On Wed, Mar 30, 2016 at 07:57:19AM +0100, Build bot for Mark Brown wrote:
> 
> Today's -next fails to build an arm allmodconfig due to:
> 
> > arm-allmodconfig
> > ../drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c:618:2: error: implicit 
> > declaration of function 'drm_connector_unplug_all' 
> > [-Werror=implicit-function-declaration]
> 
> which appears to be triggered by a missed update in 6c87e5c3ec6db0 (drm:
> Rename drm_connector_unplug_all() to drm_connector_unregister_all())
> due to this driver being newly added in a different tree.

Daniel already fixed it here [1].

[1]http://www.spinics.net/lists/dri-devel/msg103521.html


-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


[Intel-gfx] [PATCH] drm/ttm: Remove TTM_HAS_AGP

2016-03-30 Thread kbuild test robot
Hi Daniel,

[auto build test WARNING on drm/drm-next]
[also build test WARNING on v4.6-rc1 next-20160330]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improving the system]

url:
https://github.com/0day-ci/linux/commits/Daniel-Vetter/drm-ttm-Remove-TTM_HAS_AGP/20160330-191030
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: sparc64-allyesconfig (attached as .config)
reproduce:
wget 
https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
 -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=sparc64 

All warnings (new ones prefixed by >>):

   In file included from include/drm/ttm/ttm_page_alloc.h:29:0,
from drivers/gpu/drm/ttm/ttm_memory.c:32:
>> include/drm/ttm/ttm_bo_driver.h:1033:18: warning: extra tokens at end of 
>> #ifdef directive
#ifdef IS_ENABLED(CONFIG_AGP)
 ^
   In file included from include/drm/ttm/ttm_page_alloc.h:29:0,
from drivers/gpu/drm/ttm/ttm_memory.c:32:
>> include/drm/ttm/ttm_bo_driver.h:1033:18: warning: extra tokens at end of 
>> #ifdef directive
#ifdef IS_ENABLED(CONFIG_AGP)
 ^

vim +1033 include/drm/ttm/ttm_bo_driver.h

  1017   struct fence *fence,
  1018   bool evict, bool no_wait_gpu,
  1019   struct ttm_mem_reg *new_mem);
  1020  /**
  1021   * ttm_io_prot
  1022   *
  1023   * @c_state: Caching state.
  1024   * @tmp: Page protection flag for a normal, cached mapping.
  1025   *
  1026   * Utility function that returns the pgprot_t that should be used for
  1027   * setting up a PTE with the caching model indicated by @c_state.
  1028   */
  1029  extern pgprot_t ttm_io_prot(uint32_t caching_flags, pgprot_t tmp);
  1030  
  1031  extern const struct ttm_mem_type_manager_func ttm_bo_manager_func;
  1032  
> 1033  #ifdef IS_ENABLED(CONFIG_AGP)
  1034  #include 
  1035  
  1036  /**
  1037   * ttm_agp_tt_create
  1038   *
  1039   * @bdev: Pointer to a struct ttm_bo_device.
  1040   * @bridge: The agp bridge this device is sitting on.
  1041   * @size: Size of the data needed backing.

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation
-- next part --
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/octet-stream
Size: 45149 bytes
Desc: not available
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160330/a51a2e89/attachment-0001.obj>


[Bug 92258] [regression] Opening menu in Steam running via DRI_PRIME with enabled DRI3 could lead to radeon kernel module crash

2016-03-30 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=92258

--- Comment #25 from Vladislav Kamenev  ---
p.s forgot to mention - after patch freezes in WoW dissappeared. Now i use
NFS:Underground to cause freezes.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160330/46b5b2da/attachment.html>


[PATCH] drm: bridge/dw-hdmi: Remove pre_enable/post_disable dummy funcs

2016-03-30 Thread Laurent Pinchart
Hi Archit,

Thank you for the patch.

On Wednesday 30 Mar 2016 14:53:24 Archit Taneja wrote:
> We don't need to keep empty callbacks for the (pre/post) enable/disable
> drm_bridge ops anymore. Remove the nop callback used here for
> pre_enable and post_disable ops.
> 
> Signed-off-by: Archit Taneja 

Acked-by: Laurent Pinchart 

> ---
>  drivers/gpu/drm/bridge/dw-hdmi.c | 7 ---
>  1 file changed, 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c
> b/drivers/gpu/drm/bridge/dw-hdmi.c index 9795b724..c9d9412 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -1413,11 +1413,6 @@ static void dw_hdmi_bridge_enable(struct drm_bridge
> *bridge) mutex_unlock(&hdmi->mutex);
>  }
> 
> -static void dw_hdmi_bridge_nop(struct drm_bridge *bridge)
> -{
> - /* do nothing */
> -}
> -
>  static enum drm_connector_status
>  dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  {
> @@ -1536,8 +1531,6 @@ static const struct drm_connector_helper_funcs
> dw_hdmi_connector_helper_funcs = static const struct drm_bridge_funcs
> dw_hdmi_bridge_funcs = {
>   .enable = dw_hdmi_bridge_enable,
>   .disable = dw_hdmi_bridge_disable,
> - .pre_enable = dw_hdmi_bridge_nop,
> - .post_disable = dw_hdmi_bridge_nop,
>   .mode_set = dw_hdmi_bridge_mode_set,
>  };

-- 
Regards,

Laurent Pinchart



[Intel-gfx] [PATCH 01/10] drm/ttm: Remove TTM_HAS_AGP

2016-03-30 Thread kbuild test robot
Hi Daniel,

[auto build test ERROR on drm/drm-next]
[also build test ERROR on v4.6-rc1 next-20160330]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improving the system]

url:
https://github.com/0day-ci/linux/commits/Daniel-Vetter/Another-shot-at-cruft-removal/20160330-174803
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: i386-allmodconfig (attached as .config)
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

All error/warnings (new ones prefixed by >>):

   drivers/gpu/drm/nouveau/nouveau_bo.c: In function 'nouveau_ttm_tt_create':
>> drivers/gpu/drm/nouveau/nouveau_bo.c:581:10: error: implicit declaration of 
>> function 'ttm_agp_tt_create' [-Werror=implicit-function-declaration]
  return ttm_agp_tt_create(bdev, drm->agp.bridge, size,
 ^
>> drivers/gpu/drm/nouveau/nouveau_bo.c:581:10: warning: return makes pointer 
>> from integer without a cast [-Wint-conversion]
   drivers/gpu/drm/nouveau/nouveau_bo.c: In function 'nouveau_ttm_tt_populate':
>> drivers/gpu/drm/nouveau/nouveau_bo.c:1501:10: error: implicit declaration of 
>> function 'ttm_agp_tt_populate' [-Werror=implicit-function-declaration]
  return ttm_agp_tt_populate(ttm);
 ^
   drivers/gpu/drm/nouveau/nouveau_bo.c: In function 
'nouveau_ttm_tt_unpopulate':
>> drivers/gpu/drm/nouveau/nouveau_bo.c:1568:3: error: implicit declaration of 
>> function 'ttm_agp_tt_unpopulate' [-Werror=implicit-function-declaration]
  ttm_agp_tt_unpopulate(ttm);
  ^
   cc1: some warnings being treated as errors
--
   drivers/gpu/drm/radeon/radeon_ttm.c: In function 'radeon_ttm_tt_create':
>> drivers/gpu/drm/radeon/radeon_ttm.c:685:10: error: implicit declaration of 
>> function 'ttm_agp_tt_create' [-Werror=implicit-function-declaration]
  return ttm_agp_tt_create(bdev, rdev->ddev->agp->bridge,
 ^
>> drivers/gpu/drm/radeon/radeon_ttm.c:685:10: warning: return makes pointer 
>> from integer without a cast [-Wint-conversion]
   drivers/gpu/drm/radeon/radeon_ttm.c: In function 'radeon_ttm_tt_populate':
>> drivers/gpu/drm/radeon/radeon_ttm.c:741:10: error: implicit declaration of 
>> function 'ttm_agp_tt_populate' [-Werror=implicit-function-declaration]
  return ttm_agp_tt_populate(ttm);
 ^
   drivers/gpu/drm/radeon/radeon_ttm.c: In function 'radeon_ttm_tt_unpopulate':
>> drivers/gpu/drm/radeon/radeon_ttm.c:792:3: error: implicit declaration of 
>> function 'ttm_agp_tt_unpopulate' [-Werror=implicit-function-declaration]
  ttm_agp_tt_unpopulate(ttm);
  ^
   cc1: some warnings being treated as errors

vim +/ttm_agp_tt_unpopulate +1568 drivers/gpu/drm/nouveau/nouveau_bo.c

26c9e8eff Ben Skeggs2015-08-20  1495if 
(!nvxx_device(&drm->device)->func->cpu_coherent &&
c3a0c771e Alexandre Courbot 2014-10-27  1496ttm->caching_state 
== tt_uncached)
c3a0c771e Alexandre Courbot 2014-10-27  1497return 
ttm_dma_populate(ttm_dma, dev->dev);
c3a0c771e Alexandre Courbot 2014-10-27  1498  
a7fb8a23c Daniel Vetter 2015-09-09  1499  #if IS_ENABLED(CONFIG_AGP)
340b0e7c5 Ben Skeggs2015-08-20  1500if (drm->agp.bridge) {
dea7e0ac4 Jerome Glisse 2012-01-03 @1501return 
ttm_agp_tt_populate(ttm);
dea7e0ac4 Jerome Glisse 2012-01-03  1502}
dea7e0ac4 Jerome Glisse 2012-01-03  1503  #endif
dea7e0ac4 Jerome Glisse 2012-01-03  1504  
9bcd38de5 Alexandre Courbot 2016-03-02  1505  #if 
IS_ENABLED(CONFIG_SWIOTLB) && IS_ENABLED(CONFIG_X86)
3230cfc34 Konrad Rzeszutek Wilk 2011-10-17  1506if (swiotlb_nr_tbl()) {
8e7e70522 Jerome Glisse 2011-11-09  1507return 
ttm_dma_populate((void *)ttm, dev->dev);
3230cfc34 Konrad Rzeszutek Wilk 2011-10-17  1508}
3230cfc34 Konrad Rzeszutek Wilk 2011-10-17  1509  #endif
3230cfc34 Konrad Rzeszutek Wilk 2011-10-17  1510  
3230cfc34 Konrad Rzeszutek Wilk 2011-10-17  1511r = 
ttm_pool_populate(ttm);
3230cfc34 Konrad Rzeszutek Wilk 2011-10-17  1512if (r) {
3230cfc34 Konrad Rzeszutek Wilk 2011-10-17  1513return r;
3230cfc34 Konrad Rzeszutek Wilk 2011-10-17  1514}
3230cfc34 Konrad Rzeszutek Wilk 2011-10-17  1515  
3230cfc34 Konrad Rzeszutek Wilk 2011-10-17  1516for (i = 0; i < 
ttm->num_pages; i++) {
fd1496a0f Alexandre Courbot 2014-07-31  1517dma_addr_t addr;
fd1496a0f Alexandre Courbot 2014-07-31  1518  
fd1496a0f Alexandre Courbot 2014-07-31  1519addr = 
dma_map_page(pdev, ttm->pages[i], 0, PAGE_SIZE,
fd1496a0f Alexandre Co

[Bug 92258] [regression] Opening menu in Steam running via DRI_PRIME with enabled DRI3 could lead to radeon kernel module crash

2016-03-30 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=92258

--- Comment #24 from Vladislav Kamenev  ---
(In reply to Michel D�nzer from comment #19)
> (In reply to Vladislav Kamenev from comment #18)
> > Checked a 4.5.0 kernel with this patch.
> > No changes. Suffering kernel freezes.
> 
> Please attach the corresponding dmesg output.


Posted my netconsole log.
Its just nothing.
Runned patched kernel with debug and loglevel=7 kernel parametres.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160330/b86017f7/attachment.html>


[Bug 92258] [regression] Opening menu in Steam running via DRI_PRIME with enabled DRI3 could lead to radeon kernel module crash

2016-03-30 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=92258

--- Comment #23 from Vladislav Kamenev  ---
Created attachment 122639
  --> https://bugs.freedesktop.org/attachment.cgi?id=122639&action=edit
netconsole log

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160330/19f3a29d/attachment.html>


[Bug 94667] Artifacts on applications on discrete and kernel freezes

2016-03-30 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=94667

--- Comment #13 from Vladislav Kamenev  ---
Found one interesting thing.
When the opengl window is not main (playing in windowed mode and opened console
for example) there is not flickering\artifacts and all runs smooth and well.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160330/79fed227/attachment.html>


[PATCH v7 1/5] staging/android: add num_fences field to struct sync_file_info

2016-03-30 Thread Greg Kroah-Hartman
On Thu, Mar 03, 2016 at 04:40:42PM -0300, Gustavo Padovan wrote:
> From: Gustavo Padovan 



Gustavo, can you resend both series of your android patches so I know I
have the latest ones to work with?  Please also collect the acks that
people have provided so far.

thanks,

greg k-h


[PATCH v2 3/3] drm: bridge: anx78xx: Add anx78xx driver support.

2016-03-30 Thread Enric Balletbo i Serra
Although there are other chips from the same family that can reuse this
driver, at the moment we only tested ANX7814 chip.

The ANX7814 is an ultra-low power Full-HD (1080p60) SlimPort transmitter
designed for portable devices. This driver adds initial support for HDMI
to DP pass-through mode.

Cc: Emil Velikov 
Cc: Rob Herring 
Cc: Dan Carpenter 
Cc: Daniel Kurtz 
Signed-off-by: Enric Balletbo i Serra 
---

Changes since v1:
 - Dan Carpenter: 
   - Fix missing error code
   - Use meaningful names for goto exit paths
 - Rob Herring: 
   - Use hpd instead cable_det as is the more standard name.
 - Daniel Kurtz: 
   - Use regmap_bulk in aux_transfer
   - Fix gpio reset polarity.
   - Turn off v10 last so we mirror poweron sequence
   - Fix some error paths.
   - Remove mutex in anx78xx_detect
 - kbuild:
   - WARNING: PTR_ERR_OR_ZERO can be used

 free any cached EDID on any plug event.
 drivers/gpu/drm/bridge/Kconfig   |8 +
 drivers/gpu/drm/bridge/Makefile  |1 +
 drivers/gpu/drm/bridge/anx78xx.c | 1411 ++
 drivers/gpu/drm/bridge/anx78xx.h |  719 +++
 4 files changed, 2139 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/anx78xx.c
 create mode 100644 drivers/gpu/drm/bridge/anx78xx.h

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 27e2022..0f595ae 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -40,4 +40,12 @@ config DRM_PARADE_PS8622
---help---
  Parade eDP-LVDS bridge chip driver.

+config DRM_ANX78XX
+   tristate "Analogix ANX78XX bridge"
+   select DRM_KMS_HELPER
+   select REGMAP_I2C
+   ---help---
+ ANX78XX is a HD video transmitter chip over micro-USB connector
+ for smartphone device.
+
 endmenu
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index f13c33d..8f0d69e 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
 obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
 obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
 obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
+obj-$(CONFIG_DRM_ANX78XX) += anx78xx.o
diff --git a/drivers/gpu/drm/bridge/anx78xx.c b/drivers/gpu/drm/bridge/anx78xx.c
new file mode 100644
index 000..995a2a7
--- /dev/null
+++ b/drivers/gpu/drm/bridge/anx78xx.c
@@ -0,0 +1,1411 @@
+/*
+ * Copyright(c) 2016, Analogix Semiconductor.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Based on anx7808 driver obtained from chromeos with copyright:
+ * Copyright(c) 2013, Google Inc.
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "anx78xx.h"
+
+#define I2C_NUM_ADDRESSES  5
+#define I2C_IDX_TX_P0  0
+#define I2C_IDX_TX_P1  1
+#define I2C_IDX_TX_P2  2
+#define I2C_IDX_RX_P0  3
+#define I2C_IDX_RX_P1  4
+
+#define XTAL_CLK   270 /* 27M */
+#define AUX_CH_BUFFER_SIZE 16
+#define AUX_WAIT_TIMEOUT_MS15
+#define AUX_WAIT_INTERVAL_MS   1
+
+/*
+ * _wait_for - magic (register) wait macro
+ *
+ * Does the right thing for modeset paths when run under kdgb or similar atomic
+ * contexts. Note that it's important that we check the condition again after
+ * having timed out, since the timeout could be due to preemption or similar 
and
+ * we've never had a chance to check the condition before the timeout.
+ */
+#define _wait_for(COND, TO_MS, INTVL_MS) ({ \
+   unsigned long timeout__ = jiffies + msecs_to_jiffies(TO_MS) + 1;\
+   int ret__ = 0;  \
+   while (!(COND)) {   \
+   if (time_after(jiffies, timeout__)) {   \
+   if (!(COND))\
+   ret__ = -ETIMEDOUT; \
+   break;  \
+   }   \
+   if (drm_can_sleep())  { \
+   usleep_range(INTVL_MS * 1000,   \
+   (INTVL_MS + 1) * 1000); \
+   } else {\
+ 

[PATCH v2 2/3] devicetree: Add ANX7814 SlimPort transmitter binding.

2016-03-30 Thread Enric Balletbo i Serra
The ANX7814 is an ultra-low power Full-HD (1080p60) SlimPort transmitter
designed for portable devices.

Cc: Rob Herring 
Signed-off-by: Enric Balletbo i Serra 
---

Changes since v1:
 - Rob Herring:
   - Rename cable-det-gpios for hpd-gpios as is more standard
   - Fix HDMI output for HDMI input

 .../devicetree/bindings/video/bridge/anx7814.txt   | 41 ++
 1 file changed, 41 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/bridge/anx7814.txt

diff --git a/Documentation/devicetree/bindings/video/bridge/anx7814.txt 
b/Documentation/devicetree/bindings/video/bridge/anx7814.txt
new file mode 100644
index 000..0ce4978
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/bridge/anx7814.txt
@@ -0,0 +1,41 @@
+Analogix ANX7814 SlimPort (Full-HD Transmitter)
+---
+
+The ANX7814 is an ultra-low power Full-HD (1080p60) SlimPort transmitter
+designed for portable devices.
+
+Required properties:
+
+ - compatible  : "analogix,anx7814"
+ - reg : I2C address of the device
+ - interrupt-parent: Should be the phandle of the interrupt controller
+ that services interrupts for this device
+ - interrupts  : Should contain the INTP interrupt
+ - hpd-gpios   : Which GPIO to use for hpd
+ - pd-gpios: Which GPIO to use for power down
+ - reset-gpios : Which GPIO to use for reset
+
+Optional properties:
+
+ - v10-gpios   : Which GPIO to use for V10 control.
+ - Video port for HDMI input, using the DT bindings defined in [1].
+
+[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+
+Example:
+
+   anx7814: anx7814 at 38 {
+   compatible = "analogix,anx7814";
+   reg = <0x38>;
+   interrupt-parent = <&gpio0>;
+   interrupts = <99 IRQ_TYPE_LEVEL_LOW>;   /* INTP */
+   hpd-gpios = <&pio 36 GPIO_ACTIVE_HIGH>;
+   pd-gpios = <&pio 33 GPIO_ACTIVE_HIGH>;
+   reset-gpios = <&pio 98 GPIO_ACTIVE_HIGH>;
+   v10-gpios = <&pio 35 GPIO_ACTIVE_HIGH>;
+   port {
+   anx7814_in: endpoint {
+   remote-endpoint = <&hdmi0_out>;
+   };
+   };
+   };
-- 
2.1.0



[PATCH v2 1/3] of: Add vendor prefix for Analogix Semiconductor

2016-03-30 Thread Enric Balletbo i Serra
Analogix Semiconductor Inc. develops analog and mixed-signal devices for
digital media and communications interconnect applications.

Cc: Rob Herring 
Signed-off-by: Enric Balletbo i Serra 
Acked-by: Rob Herring 
---

Changes since v1:
 - Add Acked-by: Rob Herring 

 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt 
b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 86740d4..683320a 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -22,6 +22,7 @@ amlogic   Amlogic, Inc.
 ampire Ampire Co., Ltd.
 amsAMS AG
 amstaosAMS-Taos Inc.
+analogix   Analogix Semiconductor, Inc.
 apmApplied Micro Circuits Corporation (APM)
 aptina Aptina Imaging
 arasan Arasan Chip Systems
-- 
2.1.0



[PATCH v2 0/3] Add ANX7814 I2C bridge driver

2016-03-30 Thread Enric Balletbo i Serra
Hi all,

Following the Emil suggestions to increase the chances of this getting reviewed
I added a per-patch changelog and I explicitly Cc (in the commit message) the
people who commented. I will also cut down the people from the to/cc list. If
someone is really interested to be there just ping me.

This patch set to introduces the anx7814 slimport transmitter driver. These
new series will replace the old series that can be found here [1]. The reason
why I introduce these new series is because the driver changed significantly.
The old approach used a polled state machine ans was not really well using the
kernel mode setting API. With this new driver I tried to use better the drm API
and use an interrupt driven model.

Wating for your new comments...

Changes since previous version:
 - Add Acked-by: Rob Herring  for patch 0001
 - Dan Carpenter: 
   - Fix missing error code
   - Use meaningful names for goto exit paths
 - Rob Herring:
   - Rename cable-det-gpios for hpd-gpios as is more standard
   - Fix HDMI output for HDMI input
   - Use hpd instead cable_det as is the more standard name.
 - Daniel Kurtz: 
   - Use regmap_bulk in aux_transfer
   - Fix gpio reset polarity.
   - Turn off v10 last so we mirror poweron sequence
   - Fix some error paths.
   - Remove mutex in anx78xx_detect
 - kbuild:
   - WARNING: PTR_ERR_OR_ZERO can be used

[1] https://lwn.net/Articles/666885/

Enric Balletbo i Serra (3):
  of: Add vendor prefix for Analogix Semiconductor
  devicetree: Add ANX7814 SlimPort transmitter binding.
  drm: bridge: anx78xx: Add anx78xx driver support.

 .../devicetree/bindings/vendor-prefixes.txt|1 +
 .../devicetree/bindings/video/bridge/anx7814.txt   |   41 +
 drivers/gpu/drm/bridge/Kconfig |8 +
 drivers/gpu/drm/bridge/Makefile|1 +
 drivers/gpu/drm/bridge/anx78xx.c   | 1411 
 drivers/gpu/drm/bridge/anx78xx.h   |  719 ++
 6 files changed, 2181 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/bridge/anx7814.txt
 create mode 100644 drivers/gpu/drm/bridge/anx78xx.c
 create mode 100644 drivers/gpu/drm/bridge/anx78xx.h

-- 
2.1.0



[Intel-gfx] [PATCH 05/10] drm: Give drm_agp_clear drm_legacy_ prefix

2016-03-30 Thread kbuild test robot
Hi Daniel,

[auto build test ERROR on drm/drm-next]
[also build test ERROR on v4.6-rc1 next-20160330]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improving the system]

url:
https://github.com/0day-ci/linux/commits/Daniel-Vetter/Another-shot-at-cruft-removal/20160330-174803
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: sparc64-allmodconfig (attached as .config)
reproduce:
wget 
https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
 -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=sparc64 

Note: the 
linux-review/Daniel-Vetter/Another-shot-at-cruft-removal/20160330-174803 HEAD 
0ef75daff5d81f77ebd5796d853c534749223b2e builds fine.
  It only hurts bisectibility.

All errors (new ones prefixed by >>):

   drivers/gpu/drm/drm_fops.c: In function 'drm_lastclose':
>> drivers/gpu/drm/drm_fops.c:416:2: error: implicit declaration of function 
>> 'drm_legacy_agp_clear' [-Werror=implicit-function-declaration]
 drm_legacy_agp_clear(dev);
 ^
   cc1: some warnings being treated as errors
--
   drivers/gpu/drm/drm_pci.c: In function 'drm_pci_agp_destroy':
>> drivers/gpu/drm/drm_pci.c:253:3: error: implicit declaration of function 
>> 'drm_legacy_agp_clear' [-Werror=implicit-function-declaration]
  drm_legacy_agp_clear(dev);
  ^
   cc1: some warnings being treated as errors

vim +/drm_legacy_agp_clear +416 drivers/gpu/drm/drm_fops.c

   410  
   411  if (dev->irq_enabled && !drm_core_check_feature(dev, 
DRIVER_MODESET))
   412  drm_irq_uninstall(dev);
   413  
   414  mutex_lock(&dev->struct_mutex);
   415  
 > 416  drm_legacy_agp_clear(dev);
   417  
   418  drm_legacy_sg_cleanup(dev);
   419  drm_legacy_vma_flush(dev);

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation
-- next part --
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/octet-stream
Size: 44851 bytes
Desc: not available
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160330/f2a33d54/attachment-0001.obj>


[PATCH] drm: align #include directives with libdrm in uapi headers

2016-03-30 Thread Daniel Vetter
We can't use  because that upsets the serach paths in libdrm.
Also, drop the circular inclusion in drm_mode.h.

v2: Actually change the right headers.

v3: Drop the #include removal per Emil's request.

Cc: Emil Velikov 
Signed-off-by: Daniel Vetter 
---
 include/uapi/drm/drm.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 7d42d105f32a..85ada499574b 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -685,7 +685,7 @@ struct drm_prime_handle {
__s32 fd;
 };

-#include 
+#include "drm_mode.h"

 #define DRM_IOCTL_BASE 'd'
 #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
-- 
2.8.0.rc3



[PATCH 02/11] drm/atomic: export drm_atomic_helper_wait_for_fences()

2016-03-30 Thread Gustavo Padovan
2016-03-18 Rob Clark :

Hi Rob,

> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/drm_atomic_helper.c | 15 +--
>  include/drm/drm_atomic_helper.h |  2 ++
>  2 files changed, 15 insertions(+), 2 deletions(-)

Reviewed-by: Gustavo Padovan 

Gustavo


[Bug 92258] [regression] Opening menu in Steam running via DRI_PRIME with enabled DRI3 could lead to radeon kernel module crash

2016-03-30 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=92258

--- Comment #22 from russianneuromancer at ya.ru ---
I also want to clarify that I not 100% sure because with for example with 4.1.6
this issue takes two days of uptime and some usage to get reproduced (comment
#6).

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160330/b1daa4cd/attachment.html>


[Bug 113341] GPU Lockup on AMD Kaveri

2016-03-30 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=113341

--- Comment #10 from Bernd Steinhauser  ---
During the last 2 weeks I switched between amdgpu and radeon a couple of times.
What I noticed is that with radeon I do get lockups here and there, I think
almost always (not 100% sure though) when a video is running.
Both with xv and vdpau as video output.
llvm is now 3.8.

On amdgpu I haven't seen a lockup yet, except for a view when bisecting 4.4-rc2
or -rc3, but I guess that was a different problem which got fixed until the
release.

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


[Bug 94667] Artifacts on applications on discrete and kernel freezes

2016-03-30 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=94667

--- Comment #12 from Vladislav Kamenev  ---
Now it appears that bug https://bugs.freedesktop.org/show_bug.cgi?id=92258
is not related to my kernel freezes.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160330/c22169d6/attachment.html>


[Bug 92258] [regression] Opening menu in Steam running via DRI_PRIME with enabled DRI3 could lead to radeon kernel module crash

2016-03-30 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=92258

--- Comment #21 from Vladislav Kamenev  ---
(In reply to Michel D�nzer from comment #19)
> (In reply to Vladislav Kamenev from comment #18)
> > Checked a 4.5.0 kernel with this patch.
> > No changes. Suffering kernel freezes.
> 
> Please attach the corresponding dmesg output.

Cannot make any logs cuz of freeze.
Will try netconsole again today.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160330/5a4975c5/attachment.html>


[PATCH] vgacon: dummy implementation for vgacon_text_force

2016-03-30 Thread Daniel Vetter
On Wed, Mar 30, 2016 at 09:52:28AM -0400, Alex Deucher wrote:
> On Wed, Mar 30, 2016 at 5:26 AM, Daniel Vetter  
> wrote:
> > This allows us to ditch a ton of ugly #ifdefs from a bunch of drm modeset
> > drivers.
> >
> > v2: Make the dummy function actually return a sane value, spotted by
> > Ville.
> >
> > v3: Because the patch is still in limbo there's no more drivers to
> > convert, noticed by Emil.
> >
> > v4: Rebase once more, because hooray. I'll just go ahead an apply this
> > one later on to drm-misc.
> >
> > Cc: Emil Velikov 
> > Cc: Ville Syrjälä 
> > Cc: Andrew Morton 
> > Cc: Greg Kroah-Hartman 
> > Signed-off-by: Daniel Vetter 
> 
> Reviewed-by: Alex Deucher 

Applied to drm-misc, thanks for the review.
-Daniel

> 
> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 --
> >  drivers/gpu/drm/ast/ast_drv.c   | 2 --
> >  drivers/gpu/drm/cirrus/cirrus_drv.c | 2 --
> >  drivers/gpu/drm/i915/i915_drv.c | 2 --
> >  drivers/gpu/drm/mgag200/mgag200_drv.c   | 2 --
> >  drivers/gpu/drm/nouveau/nouveau_drm.c   | 2 --
> >  drivers/gpu/drm/qxl/qxl_drv.c   | 2 --
> >  drivers/gpu/drm/radeon/radeon_drv.c | 2 --
> >  drivers/gpu/drm/virtio/virtgpu_drv.c| 2 --
> >  drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 --
> >  include/linux/console.h | 2 ++
> >  11 files changed, 2 insertions(+), 20 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > index f1e17d60055a..93462aea9faa 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > @@ -556,12 +556,10 @@ static struct pci_driver amdgpu_kms_pci_driver = {
> >  static int __init amdgpu_init(void)
> >  {
> > amdgpu_sync_init();
> > -#ifdef CONFIG_VGA_CONSOLE
> > if (vgacon_text_force()) {
> > DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n");
> > return -EINVAL;
> > }
> > -#endif
> > DRM_INFO("amdgpu kernel modesetting enabled.\n");
> > driver = &kms_driver;
> > pdriver = &amdgpu_kms_pci_driver;
> > diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
> > index 9a32d9dfdd26..fcd9c0714836 100644
> > --- a/drivers/gpu/drm/ast/ast_drv.c
> > +++ b/drivers/gpu/drm/ast/ast_drv.c
> > @@ -218,10 +218,8 @@ static struct drm_driver driver = {
> >
> >  static int __init ast_init(void)
> >  {
> > -#ifdef CONFIG_VGA_CONSOLE
> > if (vgacon_text_force() && ast_modeset == -1)
> > return -EINVAL;
> > -#endif
> >
> > if (ast_modeset == 0)
> > return -EINVAL;
> > diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c 
> > b/drivers/gpu/drm/cirrus/cirrus_drv.c
> > index 7bc394ec9fb3..dc83f69da6f1 100644
> > --- a/drivers/gpu/drm/cirrus/cirrus_drv.c
> > +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
> > @@ -163,10 +163,8 @@ static struct pci_driver cirrus_pci_driver = {
> >
> >  static int __init cirrus_init(void)
> >  {
> > -#ifdef CONFIG_VGA_CONSOLE
> > if (vgacon_text_force() && cirrus_modeset == -1)
> > return -EINVAL;
> > -#endif
> >
> > if (cirrus_modeset == 0)
> > return -EINVAL;
> > diff --git a/drivers/gpu/drm/i915/i915_drv.c 
> > b/drivers/gpu/drm/i915/i915_drv.c
> > index f73b4f7b2d39..349e17cc8540 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.c
> > +++ b/drivers/gpu/drm/i915/i915_drv.c
> > @@ -1754,10 +1754,8 @@ static int __init i915_init(void)
> > if (i915.modeset == 0)
> > driver.driver_features &= ~DRIVER_MODESET;
> >
> > -#ifdef CONFIG_VGA_CONSOLE
> > if (vgacon_text_force() && i915.modeset == -1)
> > driver.driver_features &= ~DRIVER_MODESET;
> > -#endif
> >
> > if (!(driver.driver_features & DRIVER_MODESET)) {
> > /* Silently fail loading to not upset userspace. */
> > diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c 
> > b/drivers/gpu/drm/mgag200/mgag200_drv.c
> > index b0af77454d52..ebb470ff7200 100644
> > --- a/drivers/gpu/drm/mgag200/mgag200_drv.c
> > +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
> > @@ -116,10 +116,8 @@ static struct pci_driver mgag200_pci_driver = {
> >
> >  static int __init mgag200_init(void)
> >  {
> > -#ifdef CONFIG_VGA_CONSOLE
> > if (vgacon_text_force() && mgag200_modeset == -1)
> > return -EINVAL;
> > -#endif
> >
> > if (mgag200_modeset == 0)
> > return -EINVAL;
> > diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c 
> > b/drivers/gpu/drm/nouveau/nouveau_drm.c
> > index d06877d9c1ed..db5c7d0cc25c 100644
> > --- a/drivers/gpu/drm/nouveau/nouveau_drm.c
> > +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
> > @@ -1083,10 +1083,8 @@ nouveau_drm_init(void)
> > nouveau_display_options();
> >
> > if (nouveau_modeset == -1) {
> > -#ifdef CONFIG_VGA_CONSOLE
> > if (vgacon_text_force())
> > nouveau_modeset = 0

[PATCH 10/10] drm/tegra: Don't set a gamma table size

2016-03-30 Thread Daniel Vetter
On Wed, Mar 30, 2016 at 02:39:22PM +0200, Thierry Reding wrote:
> On Wed, Mar 30, 2016 at 11:51:25AM +0200, Daniel Vetter wrote:
> > tegra doesn't have any functions to set gamma tables, so this is
> > completely defunct.
> > 
> > Not nice to lie to userspace, so let's stop!
> > 
> > Cc: Thierry Reding 
> > Signed-off-by: Daniel Vetter 
> > ---
> >  drivers/gpu/drm/tegra/dc.c | 1 -
> >  1 file changed, 1 deletion(-)
> 
> Do you want this to go through the Tegra tree or do you have follow-up
> work that depends on this?

Driver trees is fine, pls just confirm when you do so (to make sure I
don't accidentally merge it too).
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH 04/10] drm/sysfs: Nuke TV/DVI property files

2016-03-30 Thread Daniel Vetter
On Wed, Mar 30, 2016 at 09:49:26AM -0400, Alex Deucher wrote:
> On Wed, Mar 30, 2016 at 5:45 AM, Daniel Vetter  
> wrote:
> > This goes all the way back to the original KMS commit aeons ago
> >
> > commit f453ba0460742ad027ae0c4c7d61e62817b3e7ef
> > Author: Dave Airlie 
> > Date:   Fri Nov 7 14:05:41 2008 -0800
> >
> > DRM: add mode setting support
> >
> > But it seems to be completely unused. Only i915 and nouveau even
> > register these properties, and the corresponding DDX don't even look
> > at them. Also the sysfs files are read-only, so not useful to
> > configure anything.
> >
> > I suspect that this was added with the goal to have read-only access
> > to all properties in sysfs, but we never followed through on that.
> > Also, that should be done in a more generic fashion.
> >
> > Since it would be real work to fix up the locking (with atomic we're
> > now chasing pointers when reading properties) and it seems unused lets
> > just nuke this all. It's easier. Of course we'll keep the properties
> > themselves, those are still exposed through the KMS ioctls.
> >
> > Signed-off-by: Daniel Vetter 
> 
> Reviewed-by: Alex Deucher 

Applied, thanks for the review.
-Daniel

> 
> > ---
> >  drivers/gpu/drm/drm_sysfs.c | 156 
> > 
> >  1 file changed, 156 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > index 43875cb35691..fa7fadce8063 100644
> > --- a/drivers/gpu/drm/drm_sysfs.c
> > +++ b/drivers/gpu/drm/drm_sysfs.c
> > @@ -292,102 +292,6 @@ static ssize_t modes_show(struct device *device,
> > return written;
> >  }
> >
> > -static ssize_t tv_subconnector_show(struct device *device,
> > -   struct device_attribute *attr,
> > -   char *buf)
> > -{
> > -   struct drm_connector *connector = to_drm_connector(device);
> > -   struct drm_device *dev = connector->dev;
> > -   struct drm_property *prop;
> > -   uint64_t subconnector;
> > -   int ret;
> > -
> > -   prop = dev->mode_config.tv_subconnector_property;
> > -   if (!prop) {
> > -   DRM_ERROR("Unable to find subconnector property\n");
> > -   return 0;
> > -   }
> > -
> > -   ret = drm_object_property_get_value(&connector->base, prop, 
> > &subconnector);
> > -   if (ret)
> > -   return 0;
> > -
> > -   return snprintf(buf, PAGE_SIZE, "%s",
> > -   drm_get_tv_subconnector_name((int)subconnector));
> > -}
> > -
> > -static ssize_t tv_select_subconnector_show(struct device *device,
> > -  struct device_attribute *attr,
> > -  char *buf)
> > -{
> > -   struct drm_connector *connector = to_drm_connector(device);
> > -   struct drm_device *dev = connector->dev;
> > -   struct drm_property *prop;
> > -   uint64_t subconnector;
> > -   int ret;
> > -
> > -   prop = dev->mode_config.tv_select_subconnector_property;
> > -   if (!prop) {
> > -   DRM_ERROR("Unable to find select subconnector property\n");
> > -   return 0;
> > -   }
> > -
> > -   ret = drm_object_property_get_value(&connector->base, prop, 
> > &subconnector);
> > -   if (ret)
> > -   return 0;
> > -
> > -   return snprintf(buf, PAGE_SIZE, "%s",
> > -   drm_get_tv_select_name((int)subconnector));
> > -}
> > -
> > -static ssize_t dvii_subconnector_show(struct device *device,
> > - struct device_attribute *attr,
> > - char *buf)
> > -{
> > -   struct drm_connector *connector = to_drm_connector(device);
> > -   struct drm_device *dev = connector->dev;
> > -   struct drm_property *prop;
> > -   uint64_t subconnector;
> > -   int ret;
> > -
> > -   prop = dev->mode_config.dvi_i_subconnector_property;
> > -   if (!prop) {
> > -   DRM_ERROR("Unable to find subconnector property\n");
> > -   return 0;
> > -   }
> > -
> > -   ret = drm_object_property_get_value(&connector->base, prop, 
> > &subconnector);
> > -   if (ret)
> > -   return 0;
> > -
> > -   return snprintf(buf, PAGE_SIZE, "%s",
> > -   drm_get_dvi_i_subconnector_name((int)subconnector));
> > -}
> > -
> > -static ssize_t dvii_select_subconnector_show(struct device *device,
> > -struct device_attribute *attr,
> > -char *buf)
> > -{
> > -   struct drm_connector *connector = to_drm_connector(device);
> > -   struct drm_device *dev = connector->dev;
> > -   struct drm_property *prop;
> > -   uint64_t subconnector;
> > -   int ret;
> > -
> > -   prop = dev->mode_config.dvi_i_select_subconnector_property;
> > -   if (!prop) {
> > -  

[PATCH 03/10] drm/armada: Drop fb gamma_set/get functions

2016-03-30 Thread Daniel Vetter
On Wed, Mar 30, 2016 at 01:56:06PM +0100, Russell King - ARM Linux wrote:
> On Wed, Mar 30, 2016 at 01:19:21PM +0200, Daniel Vetter wrote:
> > On Wed, Mar 30, 2016 at 1:09 PM, Russell King - ARM Linux
> >  wrote:
> > > On Wed, Mar 30, 2016 at 11:51:18AM +0200, Daniel Vetter wrote:
> > >> The fb helper private gamma_set/get functions are only required when
> > >> the driver supports paletted 8bit mode with fbdev. Armada uses 32bpp
> > >> unconditionally, so this is just dead code. It also doesn't do
> > >> anything really. Let's just remove it.
> > >
> > > This comment is misleading: Armada supports 16bpp formats as well as
> > > 32bpp, and the hardware does have 8bpp modes to, but I've chosen not
> > > to support the 8bpp modes.
> > 
> > This is purely about the fbdev emulation (and yeah need to clarify
> > that), not about kms support in general. And these two gamma_set/get
> > hooks are _only_ used by the fbdev emulation, and only needed if you
> > do 8bit paletted mode. Ok if I change the commit message to "Armada
> > used 32bpp unconditionally for fbdev emulation, ..."?
> 
> I still don't know where you get that from - the armada fbdev code
> supports more than just 32bpp.  Please explain.

Ok, I lost myself in the code and missed the cmdline parsing of fbdev
depth. So seems indeed possible to create a 8bit fbdev on armada (since
armada_framebuffer_create won't reject it, and I didn't see anything
else). I'll drop this patch. Thanks for the feedback.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH v4 RESEND 5/5] drm/i915: Get rid of intel_dp_dpcd_read_wake()

2016-03-30 Thread Jani Nikula
On Mon, 28 Mar 2016, Lyude  wrote:
> Since we've fixed up drm_dp_dpcd_read() to allow for retries when things
> timeout, there's no use for having this function anymore. Good riddens.
>
> Signed-off-by: Lyude 
> ---
>  drivers/gpu/drm/i915/intel_dp.c | 79 
> -
>  1 file changed, 22 insertions(+), 57 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index f069a82..43c2933 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3184,47 +3184,14 @@ static void chv_dp_post_pll_disable(struct 
> intel_encoder *encoder)
>  }
>  
>  /*
> - * Native read with retry for link status and receiver capability reads for
> - * cases where the sink may still be asleep.
> - *
> - * Sinks are *supposed* to come up within 1ms from an off state, but we're 
> also
> - * supposed to retry 3 times per the spec.
> - */
> -static ssize_t
> -intel_dp_dpcd_read_wake(struct drm_dp_aux *aux, unsigned int offset,
> - void *buffer, size_t size)
> -{
> - ssize_t ret;
> - int i;
> -
> - /*
> -  * Sometime we just get the same incorrect byte repeated
> -  * over the entire buffer. Doing just one throw away read
> -  * initially seems to "solve" it.
> -  */
> - drm_dp_dpcd_read(aux, DP_DPCD_REV, buffer, 1);

Ville, care to check this series (except patch 1) with your display to
see if it still works?

BR,
Jani.


> -
> - for (i = 0; i < 3; i++) {
> - ret = drm_dp_dpcd_read(aux, offset, buffer, size);
> - if (ret == size)
> - return ret;
> - msleep(1);
> - }
> -
> - return ret;
> -}
> -
> -/*
>   * Fetch AUX CH registers 0x202 - 0x207 which contain
>   * link status information
>   */
>  bool
>  intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t 
> link_status[DP_LINK_STATUS_SIZE])
>  {
> - return intel_dp_dpcd_read_wake(&intel_dp->aux,
> -DP_LANE0_1_STATUS,
> -link_status,
> -DP_LINK_STATUS_SIZE) == 
> DP_LINK_STATUS_SIZE;
> + return drm_dp_dpcd_read(&intel_dp->aux, DP_LANE0_1_STATUS, link_status,
> + DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE;
>  }
>  
>  /* These are source-specific values. */
> @@ -3859,8 +3826,8 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
>   struct drm_i915_private *dev_priv = dev->dev_private;
>   uint8_t rev;
>  
> - if (intel_dp_dpcd_read_wake(&intel_dp->aux, 0x000, intel_dp->dpcd,
> - sizeof(intel_dp->dpcd)) < 0)
> + if (drm_dp_dpcd_read(&intel_dp->aux, 0x000, intel_dp->dpcd,
> +  sizeof(intel_dp->dpcd)) < 0)
>   return false; /* aux transfer failed */
>  
>   DRM_DEBUG_KMS("DPCD: %*ph\n", (int) sizeof(intel_dp->dpcd), 
> intel_dp->dpcd);
> @@ -3871,9 +3838,9 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
>   /* Check if the panel supports PSR */
>   memset(intel_dp->psr_dpcd, 0, sizeof(intel_dp->psr_dpcd));
>   if (is_edp(intel_dp)) {
> - intel_dp_dpcd_read_wake(&intel_dp->aux, DP_PSR_SUPPORT,
> - intel_dp->psr_dpcd,
> - sizeof(intel_dp->psr_dpcd));
> + drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT,
> +  intel_dp->psr_dpcd,
> +  sizeof(intel_dp->psr_dpcd));
>   if (intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED) {
>   dev_priv->psr.sink_support = true;
>   DRM_DEBUG_KMS("Detected EDP PSR Panel.\n");
> @@ -3884,9 +3851,9 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
>   uint8_t frame_sync_cap;
>  
>   dev_priv->psr.sink_support = true;
> - intel_dp_dpcd_read_wake(&intel_dp->aux,
> - DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP,
> - &frame_sync_cap, 1);
> + drm_dp_dpcd_read(&intel_dp->aux,
> +  DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP,
> +  &frame_sync_cap, 1);
>   dev_priv->psr.aux_frame_sync = frame_sync_cap ? true : 
> false;
>   /* PSR2 needs frame sync as well */
>   dev_priv->psr.psr2_support = 
> dev_priv->psr.aux_frame_sync;
> @@ -3902,15 +3869,13 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
>   /* Intermediate frequency support */
>   if (is_edp(intel_dp) &&
>   (intel_dp->dpcd[DP_EDP_CONFIGURATION_CAP] & 
> DP_DPCD_DISPLAY_CONTROL_CAPABLE) &&
> - (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_EDP_DPCD_REV, &rev, 1) 
> == 1) &&
> + (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_DPCD_REV, &rev, 1) == 1) &&
>   (rev >= 

[PATCH] drm/ttm: Remove TTM_HAS_AGP

2016-03-30 Thread Daniel Vetter
On Wed, Mar 30, 2016 at 01:53:38PM +0100, Emil Velikov wrote:
> On 30 March 2016 at 12:24, Daniel Vetter  wrote:
> > It tries to do fancy things with excluding agp support if ttm is
> > built-in, but agp isn't. Instead just express this depency like drm
> > does and use CONFIG_AGP everywhere.
> >
> > Also use the neat Makefile magic to make the entire ttm_agp_backend
> > file optional.
> >
> > v2: Use IS_ENABLED(CONFIG_AGP) as suggested by Ville
> >
> > v3: Review from Emil.
> >
> > v4: Actually get it right as spotted by 0-day.
> >
> Nice one. I didn't even spot the typo/thinko in v3 ;-)
> 
> > Cc: Emil Velikov 
> > Cc: Ville Syrjälä 
> > Signed-off-by: Daniel Vetter 
> Reviewed-by: Emil Velikov 

Applied to drm-misc, thanks for the review.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH] drm: Make drm.h uapi header safe for C++

2016-03-30 Thread Daniel Vetter
virtual is a protected keyword in C++ and can't be used at all. Ugh.

This aligns the kernel versions of the drm headers with the ones in
libdrm.

v2: Also annote with __user, as request by Emil&Ilia.

Cc: Ilia Mirkin 
Cc: Emil Velikov 
Signed-off-by: Daniel Vetter 
---
 include/uapi/drm/drm.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index a0ebfe7c9a28..7d42d105f32a 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -373,7 +373,11 @@ struct drm_buf_pub {
  */
 struct drm_buf_map {
int count;  /**< Length of the buffer list */
+#ifdef __cplusplus
+   void __user *virt;
+#else
void __user *virtual;   /**< Mmap'd area in user-virtual */
+#endif
struct drm_buf_pub __user *list;/**< Buffer information */
 };

-- 
2.8.0.rc3



[PATCH 2/3] drm: align #include directives with libdrm in uapi headers

2016-03-30 Thread Daniel Vetter
On Wed, Mar 30, 2016 at 04:05:20PM +0100, Emil Velikov wrote:
> On 30 March 2016 at 15:19, Daniel Vetter  wrote:
> > We can't use  because that upsets the serach paths in libdrm.
> > Also, drop the circular inclusion in drm_mode.h.
> >
> > v2: Actually change the right headers.
> >
> > Cc: Emil Velikov 
> > Signed-off-by: Daniel Vetter 
> > ---
> >  include/uapi/drm/drm.h  | 2 +-
> >  include/uapi/drm/drm_mode.h | 2 --
> >  2 files changed, 1 insertion(+), 3 deletions(-)
> >
> > diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
> > index d299c7749091..c7ecc3abff03 100644
> > --- a/include/uapi/drm/drm.h
> > +++ b/include/uapi/drm/drm.h
> > @@ -685,7 +685,7 @@ struct drm_prime_handle {
> > __s32 fd;
> >  };
> >
> > -#include 
> > +#include "drm_mode.h"
> >
> >  #define DRM_IOCTL_BASE 'd'
> >  #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > index c0217434d28d..db106ab01039 100644
> > --- a/include/uapi/drm/drm_mode.h
> > +++ b/include/uapi/drm/drm_mode.h
> > @@ -27,8 +27,6 @@
> >  #ifndef _DRM_MODE_H
> >  #define _DRM_MODE_H
> >
> > -#include "drm.h"
> > -
> I'm thinking about the complete inverse actually.
> 
> Any program that depends on drm_mode.h but does not include it
> explicitly is severely broken. On the other hand, we rely on the drm.h
> to resolve the linux specific types (for non-linux platforms).
> 
> Unfortunately I've not looked how much busted userspace there is in
> either case (this patch vs my suggestion).

Well I was just blindly aligning the #includes to match what we have right
now in libdrm. That's the safest option really. It would be nice to
untangle this, but I think it's too late for that now :(
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH] drm: align #include directives with libdrm in uapi headers

2016-03-30 Thread Emil Velikov
On 30 March 2016 at 16:54, Daniel Vetter  wrote:
> We can't use  because that upsets the serach paths in libdrm.
> Also, drop the circular inclusion in drm_mode.h.
>
> v2: Actually change the right headers.
>
> v3: Drop the #include removal per Emil's request.
>
Thanks.

> Cc: Emil Velikov 
> Signed-off-by: Daniel Vetter 

Reviewed-by: Emil Velikov 

-Emil


[PATCH 3/3] drm: Move DRM_MODE_OBJECT_* to uapi headers

2016-03-30 Thread Emil Velikov
On 30 March 2016 at 15:19, Daniel Vetter  wrote:
> These type defines are officially part of the uapi, but ended up in
> the wrong headers somehow when we split them all.
>
> Cc: Emil Velikov 
> Signed-off-by: Daniel Vetter 
The way it was done originally (by Paulo) with commit
c543188afb7a83e66161c026dc6fd5eb38dc0b63 it seemed deliberate. At the
same time the libdrm got a different treatment
8c75703df0fdf65b3851f8eb5822705638decff3. Would be swell Paulo can
confirm (re: unintentional or deliberate difference), if he recalls
any of this :-)

Barring any objections from Paulo
Reviewed-by: Emil Velikov 

-Emil


[Bug 92258] [regression] Opening menu in Steam running via DRI_PRIME with enabled DRI3 could lead to radeon kernel module crash

2016-03-30 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=92258

--- Comment #20 from russianneuromancer at ya.ru ---
I wasn't able to reproduce issue with patch from Comment #10 (called menu like
two hundred times).

I not sure if it's 100% fixed with this patch, because that was fresh boot, no
other usual programs running, but without this patch issues was reproducible
even under this simple conditions.

So, for now patch seems like help, if crash happen again under different
condition (with longer uptime and more background processes) I will provide new
dmesg.

Michel, please let me know do you intend to submit this patch to upstream?

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160330/af25237d/attachment-0001.html>


[PATCH 7/7] headers: Update drm.h

2016-03-30 Thread Daniel Vetter
This needs the kernel patch to make sure the C++ protection is in place.

Otherwise just new defines, using the right fixed-width types and
some shuffling in where stuff is defined (the DRM_CAP list moved, but
the #defines are the same).

Generated using make headers_install.

Signed-off-by: Daniel Vetter 
---
 include/drm/drm.h | 67 ++-
 1 file changed, 41 insertions(+), 26 deletions(-)

diff --git a/include/drm/drm.h b/include/drm/drm.h
index e213ec68a9c3..b4ebaa965a94 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -36,7 +36,7 @@
 #ifndef _DRM_H_
 #define _DRM_H_

-#if defined(__linux__)
+#if   defined(__linux__)

 #include 
 #include 
@@ -54,6 +54,7 @@ typedef int32_t  __s32;
 typedef uint32_t __u32;
 typedef int64_t  __s64;
 typedef uint64_t __u64;
+typedef size_t   __kernel_size_t;
 typedef unsigned long drm_handle_t;

 #endif
@@ -129,11 +130,11 @@ struct drm_version {
int version_major;/**< Major version */
int version_minor;/**< Minor version */
int version_patchlevel;   /**< Patch level */
-   size_t name_len;  /**< Length of name buffer */
+   __kernel_size_t name_len; /**< Length of name buffer */
char *name;   /**< Name of driver */
-   size_t date_len;  /**< Length of date buffer */
+   __kernel_size_t date_len; /**< Length of date buffer */
char *date;   /**< User-space buffer to hold date */
-   size_t desc_len;  /**< Length of desc buffer */
+   __kernel_size_t desc_len; /**< Length of desc buffer */
char *desc;   /**< User-space buffer to hold desc */
 };

@@ -143,7 +144,7 @@ struct drm_version {
  * \sa drmGetBusid() and drmSetBusId().
  */
 struct drm_unique {
-   size_t unique_len;/**< Length of unique */
+   __kernel_size_t unique_len;   /**< Length of unique */
char *unique; /**< Unique name for driver instantiation */
 };

@@ -180,7 +181,7 @@ enum drm_map_type {
_DRM_SHM = 2, /**< shared, cached */
_DRM_AGP = 3, /**< AGP/GART */
_DRM_SCATTER_GATHER = 4,  /**< Scatter/gather memory for PCI DMA */
-   _DRM_CONSISTENT = 5,  /**< Consistent memory for PCI DMA */
+   _DRM_CONSISTENT = 5   /**< Consistent memory for PCI DMA */
 };

 /**
@@ -466,12 +467,15 @@ struct drm_irq_busid {
 enum drm_vblank_seq_type {
_DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence 
number */
_DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
+   /* bits 1-6 are reserved for high crtcs */
+   _DRM_VBLANK_HIGH_CRTC_MASK = 0x003e,
_DRM_VBLANK_EVENT = 0x400,   /**< Send event instead of blocking */
_DRM_VBLANK_FLIP = 0x800,   /**< Scheduled buffer swap should flip 
*/
_DRM_VBLANK_NEXTONMISS = 0x1000,/**< If missed, wait for next 
vblank */
_DRM_VBLANK_SECONDARY = 0x2000, /**< Secondary display 
controller */
_DRM_VBLANK_SIGNAL = 0x4000 /**< Send signal instead of blocking, 
unsupported */
 };
+#define _DRM_VBLANK_HIGH_CRTC_SHIFT 1

 #define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE)
 #define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_EVENT | _DRM_VBLANK_SIGNAL | \
@@ -611,6 +615,28 @@ struct drm_gem_open {
__u64 size;
 };

+#define DRM_CAP_DUMB_BUFFER0x1
+#define DRM_CAP_VBLANK_HIGH_CRTC   0x2
+#define DRM_CAP_DUMB_PREFERRED_DEPTH   0x3
+#define DRM_CAP_DUMB_PREFER_SHADOW 0x4
+#define DRM_CAP_PRIME  0x5
+#define  DRM_PRIME_CAP_IMPORT  0x1
+#define  DRM_PRIME_CAP_EXPORT  0x2
+#define DRM_CAP_TIMESTAMP_MONOTONIC0x6
+#define DRM_CAP_ASYNC_PAGE_FLIP0x7
+/*
+ * The CURSOR_WIDTH and CURSOR_HEIGHT capabilities return a valid widthxheight
+ * combination for the hardware cursor. The intention is that a hardware
+ * agnostic userspace can query a cursor plane size to use.
+ *
+ * Note that the cross-driver contract is to merely return a valid size;
+ * drivers are free to attach another meaning on top, eg. i915 returns the
+ * maximum plane size.
+ */
+#define DRM_CAP_CURSOR_WIDTH   0x8
+#define DRM_CAP_CURSOR_HEIGHT  0x9
+#define DRM_CAP_ADDFB2_MODIFIERS   0x10
+
 /** DRM_IOCTL_GET_CAP ioctl argument type */
 struct drm_get_cap {
__u64 capability;
@@ -629,17 +655,17 @@ struct drm_get_cap {
 /**
  * DRM_CLIENT_CAP_UNIVERSAL_PLANES
  *
- * if set to 1, the DRM core will expose the full universal plane list
- * (including primary and cursor planes).
+ * If set to 1, the DRM core will expose all planes (overlay, primary, and
+ * cursor) to userspace.
  */
-#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
+#define DRM_CLIENT_CAP_UNIVERSAL_PLANES  2

 /**
  * DRM_CLIENT_CAP_ATOMIC
  *
- * If set to 1, the DRM core will allow atomic modesetting requests.
+ * If set to 1, the DR

[PATCH 6/7] headers: Update drm_mode.h

2016-03-30 Thread Daniel Vetter
Generated using make headers_install.

Only cosmetics&new definitions here now.

Signed-off-by: Daniel Vetter 
---
 include/drm/drm_mode.h | 168 ++---
 1 file changed, 117 insertions(+), 51 deletions(-)

diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index 115f36e452d9..8c48c0a558c0 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -56,6 +56,10 @@
 #define DRM_MODE_FLAG_PIXMUX   (1<<11)
 #define DRM_MODE_FLAG_DBLCLK   (1<<12)
 #define DRM_MODE_FLAG_CLKDIV2  (1<<13)
+ /*
+  * When adding a new stereo mode don't forget to adjust DRM_MODE_FLAGS_3D_MAX
+  * (define not exposed to user space).
+  */
 #define DRM_MODE_FLAG_3D_MASK  (0x1f<<14)
 #define  DRM_MODE_FLAG_3D_NONE (0<<14)
 #define  DRM_MODE_FLAG_3D_FRAME_PACKING(1<<14)
@@ -82,6 +86,11 @@
 #define DRM_MODE_SCALE_CENTER  2 /* Centered, no scaling */
 #define DRM_MODE_SCALE_ASPECT  3 /* Full screen, preserve aspect */

+/* Picture aspect ratio options */
+#define DRM_MODE_PICTURE_ASPECT_NONE   0
+#define DRM_MODE_PICTURE_ASPECT_4_31
+#define DRM_MODE_PICTURE_ASPECT_16_9   2
+
 /* Dithering mode options */
 #define DRM_MODE_DITHERING_OFF 0
 #define DRM_MODE_DITHERING_ON  1
@@ -94,8 +103,16 @@

 struct drm_mode_modeinfo {
__u32 clock;
-   __u16 hdisplay, hsync_start, hsync_end, htotal, hskew;
-   __u16 vdisplay, vsync_start, vsync_end, vtotal, vscan;
+   __u16 hdisplay;
+   __u16 hsync_start;
+   __u16 hsync_end;
+   __u16 htotal;
+   __u16 hskew;
+   __u16 vdisplay;
+   __u16 vsync_start;
+   __u16 vsync_end;
+   __u16 vtotal;
+   __u16 vscan;

__u32 vrefresh;

@@ -113,8 +130,10 @@ struct drm_mode_card_res {
__u32 count_crtcs;
__u32 count_connectors;
__u32 count_encoders;
-   __u32 min_width, max_width;
-   __u32 min_height, max_height;
+   __u32 min_width;
+   __u32 max_width;
+   __u32 min_height;
+   __u32 max_height;
 };

 struct drm_mode_crtc {
@@ -124,30 +143,35 @@ struct drm_mode_crtc {
__u32 crtc_id; /**< Id */
__u32 fb_id; /**< Id of framebuffer */

-   __u32 x, y; /**< Position on the frameuffer */
+   __u32 x; /**< x Position on the framebuffer */
+   __u32 y; /**< y Position on the framebuffer */

__u32 gamma_size;
__u32 mode_valid;
struct drm_mode_modeinfo mode;
 };

-#define DRM_MODE_PRESENT_TOP_FIELD (1<<0)
-#define DRM_MODE_PRESENT_BOTTOM_FIELD  (1<<1)
+#define DRM_MODE_PRESENT_TOP_FIELD (1<<0)
+#define DRM_MODE_PRESENT_BOTTOM_FIELD  (1<<1)

 /* Planes blend with or override other bits on the CRTC */
 struct drm_mode_set_plane {
__u32 plane_id;
__u32 crtc_id;
__u32 fb_id; /* fb object contains surface format type */
-   __u32 flags;
+   __u32 flags; /* see above flags */

/* Signed dest location allows it to be partially off screen */
-   __s32 crtc_x, crtc_y;
-   __u32 crtc_w, crtc_h;
+   __s32 crtc_x;
+   __s32 crtc_y;
+   __u32 crtc_w;
+   __u32 crtc_h;

/* Source values are 16.16 fixed point */
-   __u32 src_x, src_y;
-   __u32 src_h, src_w;
+   __u32 src_x;
+   __u32 src_y;
+   __u32 src_h;
+   __u32 src_w;
 };

 struct drm_mode_get_plane {
@@ -233,8 +257,11 @@ struct drm_mode_get_connector {
__u32 connector_type_id;

__u32 connection;
-   __u32 mm_width, mm_height; /**< HxW in millimeters */
+   __u32 mm_width;  /**< width in millimeters */
+   __u32 mm_height; /**< height in millimeters */
__u32 subpixel;
+
+   __u32 pad;
 };

 #define DRM_MODE_PROP_PENDING  (1<<0)
@@ -259,6 +286,13 @@ struct drm_mode_get_connector {
 #define DRM_MODE_PROP_OBJECT   DRM_MODE_PROP_TYPE(1)
 #define DRM_MODE_PROP_SIGNED_RANGE DRM_MODE_PROP_TYPE(2)

+/* the PROP_ATOMIC flag is used to hide properties from userspace that
+ * is not aware of atomic properties.  This is mostly to work around
+ * older userspace (DDX drivers) that read/write each prop they find,
+ * witout being aware that this could be triggering a lengthy modeset.
+ */
+#define DRM_MODE_PROP_ATOMIC0x8000
+
 struct drm_mode_property_enum {
__u64 value;
char name[DRM_PROP_NAME_LEN];
@@ -273,6 +307,8 @@ struct drm_mode_get_property {
char name[DRM_PROP_NAME_LEN];

__u32 count_values;
+   /* This is only used to count enum values, not blobs. The _blobs is
+* simply because of a historical reason, i.e. backwards compat. */
__u32 count_enum_blobs;
 };

@@ -290,6 +326,7 @@ struct drm_mode_connector_set_property {
 #define DRM_MODE_OBJECT_FB 0xfbfbfbfb
 #define DRM_MODE_OBJECT_BLOB 0x
 #define DRM_MODE_OBJECT_PLANE 0x
+#define DRM_MODE_OBJECT_ANY 0

 struct drm_mode_obj_get_properties {
__u64 props_ptr;
@@ -31

[PATCH 5/7] headers: Update drm_fourcc.h

2016-03-30 Thread Daniel Vetter
Only real difference is switching to kernel types for fixed-width
integers, like we should.

Signed-off-by: Daniel Vetter 
---
 include/drm/drm_fourcc.h | 17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index e741b09a00fd..4d8da699a623 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -24,16 +24,23 @@
 #ifndef DRM_FOURCC_H
 #define DRM_FOURCC_H

-#include 
+#include "drm.h"

-#define fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
- ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+#define fourcc_code(a, b, c, d) ((__u32)(a) | ((__u32)(b) << 8) | \
+((__u32)(c) << 16) | ((__u32)(d) << 24))

 #define DRM_FORMAT_BIG_ENDIAN (1<<31) /* format is big endian instead of 
little endian */

 /* color index */
 #define DRM_FORMAT_C8  fourcc_code('C', '8', ' ', ' ') /* [7:0] C */

+/* 8 bpp Red */
+#define DRM_FORMAT_R8  fourcc_code('R', '8', ' ', ' ') /* [7:0] R */
+
+/* 16 bpp RG */
+#define DRM_FORMAT_RG88fourcc_code('R', 'G', '8', '8') /* 
[15:0] R:G 8:8 little endian */
+#define DRM_FORMAT_GR88fourcc_code('G', 'R', '8', '8') /* 
[15:0] G:R 8:8 little endian */
+
 /* 8 bpp RGB */
 #define DRM_FORMAT_RGB332  fourcc_code('R', 'G', 'B', '8') /* [7:0] R:G:B 
3:3:2 */
 #define DRM_FORMAT_BGR233  fourcc_code('B', 'G', 'R', '8') /* [7:0] B:G:R 
2:3:3 */
@@ -106,6 +113,8 @@
 #define DRM_FORMAT_NV21fourcc_code('N', 'V', '2', '1') /* 2x2 
subsampled Cb:Cr plane */
 #define DRM_FORMAT_NV16fourcc_code('N', 'V', '1', '6') /* 2x1 
subsampled Cr:Cb plane */
 #define DRM_FORMAT_NV61fourcc_code('N', 'V', '6', '1') /* 2x1 
subsampled Cb:Cr plane */
+#define DRM_FORMAT_NV24fourcc_code('N', 'V', '2', '4') /* 
non-subsampled Cr:Cb plane */
+#define DRM_FORMAT_NV42fourcc_code('N', 'V', '4', '2') /* 
non-subsampled Cb:Cr plane */

 /*
  * 3 plane YCbCr
@@ -216,7 +225,7 @@
  * - multiple of 128 pixels for the width
  * - multiple of  32 pixels for the height
  *
- * For more information: see 
http://linuxtv.org/downloads/v4l-dvb-apis/re32.html
+ * For more information: see 
https://linuxtv.org/downloads/v4l-dvb-apis/re32.html
  */
 #define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE  fourcc_mod_code(SAMSUNG, 1)

-- 
2.8.0.rc3



[PATCH 4/7] headers: Update drm_sarea.h

2016-03-30 Thread Daniel Vetter
Generated using make headers_install. Only difference is a new value
of SAREA_MAX for mips. Not that we ever shipped a dri1 driver on that
platform probably ...

Signed-off-by: Daniel Vetter 
---
 include/drm/drm_sarea.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/drm/drm_sarea.h b/include/drm/drm_sarea.h
index 7325558d9cbd..502934edc21a 100644
--- a/include/drm/drm_sarea.h
+++ b/include/drm/drm_sarea.h
@@ -37,6 +37,8 @@
 /* SAREA area needs to be at least a page */
 #if defined(__alpha__)
 #define SAREA_MAX   0x2000U
+#elif defined(__mips__)
+#define SAREA_MAX   0x4000U
 #elif defined(__ia64__)
 #define SAREA_MAX   0x1U   /* 64kB */
 #else
-- 
2.8.0.rc3



[PATCH 3/7] headers: Update drm_i915.h

2016-03-30 Thread Daniel Vetter
Generated using make header_install.

Signed-off-by: Daniel Vetter 
---
 include/drm/i915_drm.h | 43 +++
 1 file changed, 35 insertions(+), 8 deletions(-)

diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 0e51d4214e1a..c4ce6b2c6f89 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -772,10 +772,12 @@ struct drm_i915_gem_execbuffer2 {
 #define I915_EXEC_HANDLE_LUT   (1<<12)

 /** Used for switching BSD rings on the platforms with two BSD rings */
-#define I915_EXEC_BSD_MASK (3<<13)
-#define I915_EXEC_BSD_DEFAULT  (0<<13) /* default ping-pong mode */
-#define I915_EXEC_BSD_RING1(1<<13)
-#define I915_EXEC_BSD_RING2(2<<13)
+#define I915_EXEC_BSD_SHIFT (13)
+#define I915_EXEC_BSD_MASK  (3 << I915_EXEC_BSD_SHIFT)
+/* default ping-pong mode */
+#define I915_EXEC_BSD_DEFAULT   (0 << I915_EXEC_BSD_SHIFT)
+#define I915_EXEC_BSD_RING1 (1 << I915_EXEC_BSD_SHIFT)
+#define I915_EXEC_BSD_RING2 (2 << I915_EXEC_BSD_SHIFT)

 /** Tell the kernel that the batchbuffer is processed by
  *  the resource streamer.
@@ -812,10 +814,35 @@ struct drm_i915_gem_busy {
/** Handle of the buffer to check for busy */
__u32 handle;

-   /** Return busy status (1 if busy, 0 if idle).
-* The high word is used to indicate on which rings the object
-* currently resides:
-*  16:31 - busy (r or r/w) rings (16 render, 17 bsd, 18 blt, etc)
+   /** Return busy status
+*
+* A return of 0 implies that the object is idle (after
+* having flushed any pending activity), and a non-zero return that
+* the object is still in-flight on the GPU. (The GPU has not yet
+* signaled completion for all pending requests that reference the
+* object.)
+*
+* The returned dword is split into two fields to indicate both
+* the engines on which the object is being read, and the
+* engine on which it is currently being written (if any).
+*
+* The low word (bits 0:15) indicate if the object is being written
+* to by any engine (there can only be one, as the GEM implicit
+* synchronisation rules force writes to be serialised). Only the
+* engine for the last write is reported.
+*
+* The high word (bits 16:31) are a bitmask of which engines are
+* currently reading from the object. Multiple engines may be
+* reading from the object simultaneously.
+*
+* The value of each engine is the same as specified in the
+* EXECBUFFER2 ioctl, i.e. I915_EXEC_RENDER, I915_EXEC_BSD etc.
+* Note I915_EXEC_DEFAULT is a symbolic value and is mapped to
+* the I915_EXEC_RENDER engine for execution, and so it is never
+* reported as active itself. Some hardware may have parallel
+* execution engines, e.g. multiple media engines, which are
+* mapped to the same identifier in the EXECBUFFER2 ioctl and
+* so are not separately reported for busyness.
 */
__u32 busy;
 };
-- 
2.8.0.rc3



[PATCH 2/7] tests/kms-steal-crtc: Use correct includes

2016-03-30 Thread Daniel Vetter
It was relying on drm_fourcc.h providing , which is silly.
Fix it.

Signed-off-by: Daniel Vetter 
---
 tests/kms/kms-steal-crtc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/kms/kms-steal-crtc.c b/tests/kms/kms-steal-crtc.c
index 497772e237f1..4b830d27a1bf 100644
--- a/tests/kms/kms-steal-crtc.c
+++ b/tests/kms/kms-steal-crtc.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #ifdef HAVE_SYS_SELECT_H
-- 
2.8.0.rc3



[PATCH 1/7] headers: Remove _DRM_GEM

2016-03-30 Thread Daniel Vetter
This was purely a kernel-internal type used in a early patch version
to add GEM bo mmap support. It was never used in-kernel in merged code
nor in userspace. Nuke it to align with kernel headers.

For reference the kernel patch:

commit 05f51722a154e73019434bd020e50ddb941046c5
Author: Daniel Vetter 
Date:   Wed Dec 11 11:34:32 2013 +0100

drm/bufs: remove handling of _DRM_GEM mappings

Gone with the new gem vma offset manager from David.

We can also ditch the uapi header definition from the enum since
userspace never used this. It ended up in there purely for historical
reasons (for reusing the old drm mmap code essentially), not because
userspace ever needed it.

Cc: David Herrmann 
Reviewed-by: David Herrmann 
Signed-off-by: Daniel Vetter 
Signed-off-by: Dave Airlie 

Signed-off-by: Daniel Vetter 
---
 include/drm/drm.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/drm/drm.h b/include/drm/drm.h
index a950b580cd11..e213ec68a9c3 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -181,7 +181,6 @@ enum drm_map_type {
_DRM_AGP = 3, /**< AGP/GART */
_DRM_SCATTER_GATHER = 4,  /**< Scatter/gather memory for PCI DMA */
_DRM_CONSISTENT = 5,  /**< Consistent memory for PCI DMA */
-   _DRM_GEM = 6  /**< GEM object */
 };

 /**
-- 
2.8.0.rc3



[PATCH 1/5] drm: Add new DCS commands in the enum list

2016-03-30 Thread Jani Nikula
From: Deepak M 

Adding new DCS commands which are specified in the
DCS 1.3 spec related to CABC.

v2: Sorted the Macro`s by value (Andrzej)

v3 by Jani: sort all of enum, refer to MIPI DCS 1.3

Cc: Andrzej Hajda 
Cc: Thierry Reding 
Cc: David Airlie 
Cc: Ville Syrjälä 
Cc: Daniel Vetter 
Cc: 
Suggested-by: Jani Nikula 
Signed-off-by: Deepak M 
Signed-off-by: Jani Nikula 
---
 include/video/mipi_display.h | 8 
 1 file changed, 8 insertions(+)

diff --git a/include/video/mipi_display.h b/include/video/mipi_display.h
index ddcc8ca7316b..19aa65a35546 100644
--- a/include/video/mipi_display.h
+++ b/include/video/mipi_display.h
@@ -115,6 +115,14 @@ enum {
MIPI_DCS_READ_MEMORY_CONTINUE   = 0x3E,
MIPI_DCS_SET_TEAR_SCANLINE  = 0x44,
MIPI_DCS_GET_SCANLINE   = 0x45,
+   MIPI_DCS_SET_DISPLAY_BRIGHTNESS = 0x51, /* MIPI DCS 1.3 */
+   MIPI_DCS_GET_DISPLAY_BRIGHTNESS = 0x52, /* MIPI DCS 1.3 */
+   MIPI_DCS_WRITE_CONTROL_DISPLAY  = 0x53, /* MIPI DCS 1.3 */
+   MIPI_DCS_GET_CONTROL_DISPLAY= 0x54, /* MIPI DCS 1.3 */
+   MIPI_DCS_WRITE_POWER_SAVE   = 0x55, /* MIPI DCS 1.3 */
+   MIPI_DCS_GET_POWER_SAVE = 0x56, /* MIPI DCS 1.3 */
+   MIPI_DCS_SET_CABC_MIN_BRIGHTNESS = 0x5E,/* MIPI DCS 1.3 */
+   MIPI_DCS_GET_CABC_MIN_BRIGHTNESS = 0x5F,/* MIPI DCS 1.3 */
MIPI_DCS_READ_DDB_START = 0xA1,
MIPI_DCS_READ_DDB_CONTINUE  = 0xA8,
 };
-- 
2.1.4



[PATCH] drm: Make drm.h uapi header safe for C++

2016-03-30 Thread Emil Velikov
On 30 March 2016 at 16:12, Daniel Vetter  wrote:
> virtual is a protected keyword in C++ and can't be used at all. Ugh.
>
> This aligns the kernel versions of the drm headers with the ones in
> libdrm.
>
> v2: Also annote with __user, as request by Emil&Ilia.

Reviewed-by: Emil Velikov 

-Emil


[PATCH 1/2] drm: Untangle __KERNEL__ guards

2016-03-30 Thread Emil Velikov
On 30 March 2016 at 15:42, Daniel Vetter  wrote:
> make headers_install can't handle fancy conditions, so let's simplify
> things for it a bit.
>
> Cc: Emil Velikov 
> Signed-off-by: Daniel Vetter 
> ---
>  include/uapi/drm/drm.h | 8 +++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
> index c7ecc3abff03..3b56285a7e2a 100644
> --- a/include/uapi/drm/drm.h
> +++ b/include/uapi/drm/drm.h
> @@ -36,7 +36,13 @@
>  #ifndef _DRM_H_
>  #define _DRM_H_
>
> -#if defined(__KERNEL__) || defined(__linux__)
> +#if defined(__KERNEL__)
> +
> +#include 
> +#include 
> +typedef unsigned int drm_handle_t;
> +
> +#elif defined(__linux__)
>
Bit dubious how that used to work, and that the program fails with the
original, yet handled "elif defined..." correctly.

Regardless,
Reviewed-by: Emil Velikov 

-Emil


[PATCH] drm/core: Add drm_accurate_vblank_count_and_time.

2016-03-30 Thread Ville Syrjälä
On Wed, Mar 30, 2016 at 03:41:26PM +0200, Maarten Lankhorst wrote:
> Op 30-03-16 om 15:13 schreef Ville Syrjälä:
> > On Tue, Mar 29, 2016 at 03:38:55PM +0200, Maarten Lankhorst wrote:
> >> This function is useful for gen2 intel devices which have no frame
> >> counter, but need a way to determine the current vblank count without
> >> racing with the vblank interrupt handler.
> >>
> >> intel_pipe_update_start checks if no vblank interrupt will occur
> >> during vblank evasion, but cannot check whether the vblank handler has
> >> run to completion. This function uses the timestamps to determine
> >> when the last vblank has happened, and interpolates from there.
> > Didn't really read it in detail, but on a glance it seems too
> > complicated to me. All we should really need is something like this:
> >
> > drm_vblank_get();
> > drm_update_vblank_count();
> > accurate = drm_vblank_count();
> >
> Updating from non vblank irq context might cause the vblank clock to drift, 
> or at least contend the vblank lock.

I don't see a problem. The scanout position is anyway used to fix up the
timestamp.

> 
> This is why I call drm_vblank_count_and_time, and then interpolate as if 
> update_vblank_count was called on the result.
> 
> ~Maarten

-- 
Ville Syrjälä
Intel OTC


[PATCH 2/2] drm: Make uapi headers C89 pendantic compliant

2016-03-30 Thread Daniel Vetter
This ports the below libdrm commit to the kernel

commit 0f4452bb51306024fbf4cbf77d8baab20cefba67
Author: Daniel Kurtz 
Date:   Mon Aug 26 23:39:16 2013 +0800

libdrm: Make some drm headers compatible with gcc -std=c89 -pedantic

The following minor changes were needed to these headers:
 * Convert // comments to /* */
 * No , after final member of enum

With these changes, these header files can be included by a program that
is built with gcc options:
  -std=c89 -Werror -pedantic

Signed-off-by: Daniel Kurtz 
Signed-off-by: Eric Anholt 
Reviewed-by: Eric Anholt 

Signed-off-by: Daniel Vetter 
---
 include/uapi/drm/drm.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 3b56285a7e2a..8b41297038aa 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -187,7 +187,7 @@ enum drm_map_type {
_DRM_SHM = 2, /**< shared, cached */
_DRM_AGP = 3, /**< AGP/GART */
_DRM_SCATTER_GATHER = 4,  /**< Scatter/gather memory for PCI DMA */
-   _DRM_CONSISTENT = 5,  /**< Consistent memory for PCI DMA */
+   _DRM_CONSISTENT = 5   /**< Consistent memory for PCI DMA */
 };

 /**
@@ -441,7 +441,7 @@ struct drm_draw {
  * DRM_IOCTL_UPDATE_DRAW ioctl argument type.
  */
 typedef enum {
-   DRM_DRAWABLE_CLIPRECTS,
+   DRM_DRAWABLE_CLIPRECTS
 } drm_drawable_info_type_t;

 struct drm_update_draw {
-- 
2.8.0.rc3



[PATCH 1/2] drm: Untangle __KERNEL__ guards

2016-03-30 Thread Daniel Vetter
make headers_install can't handle fancy conditions, so let's simplify
things for it a bit.

Cc: Emil Velikov 
Signed-off-by: Daniel Vetter 
---
 include/uapi/drm/drm.h | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index c7ecc3abff03..3b56285a7e2a 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -36,7 +36,13 @@
 #ifndef _DRM_H_
 #define _DRM_H_

-#if defined(__KERNEL__) || defined(__linux__)
+#if defined(__KERNEL__)
+
+#include 
+#include 
+typedef unsigned int drm_handle_t;
+
+#elif defined(__linux__)

 #include 
 #include 
-- 
2.8.0.rc3



[pull] radeon and amdgpu drm-next-4.6

2016-03-30 Thread Alex Deucher
Hi Dave,

Just a few fixes for 4.6 this week:
- Add some SI DPM quirks
- Improve the ACP Kconfig text
- Additional BO pinning checks

The following changes since commit 4604202ca8d2a5e33b4bca0812b5d92975ed1bd8:

  Merge branch 'drm-next-4.6' of git://people.freedesktop.org/~agd5f/linux into 
drm-next (2016-03-25 16:02:06 +1000)

are available in the git repository at:

  git://people.freedesktop.org/~agd5f/linux drm-next-4.6

for you to fetch changes up to 104ece975746d94b8276cd7f38d6b5c056d700b5:

  drm/amdgpu: Don't move pinned BOs (2016-03-28 11:55:38 -0400)


Alex Deucher (3):
  drm/radeon: add a dpm quirk for sapphire Dual-X R7 370 2G D5
  drm/radeon: add another R7 370 quirk
  drm/radeon: add a dpm quirk for all R7 370 parts

Borislav Petkov (1):
  drm/amd: Beef up ACP Kconfig menu text

Michel Dänzer (2):
  drm/radeon: Don't move pinned BOs
  drm/amdgpu: Don't move pinned BOs

 drivers/gpu/drm/amd/acp/Kconfig| 8 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 4 
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c| 6 ++
 drivers/gpu/drm/radeon/radeon_object.c | 4 
 drivers/gpu/drm/radeon/radeon_ttm.c| 6 ++
 drivers/gpu/drm/radeon/si_dpm.c| 6 ++
 6 files changed, 32 insertions(+), 2 deletions(-)


  1   2   3   >