Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH v3 02/11] thermal: armada: Use msleep for long delays
From: Gregory CLEMENT @ 2017-12-14 10:51 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Zhang Rui, Eduardo Valentin, Rob Herring, Mark Rutland,
	Jason Cooper, Andrew Lunn, Sebastian Hesselbarth, Catalin Marinas,
	Will Deacon, Thomas Petazzoni, devicetree, Baruch Siach, linux-pm,
	Antoine Tenart, Nadav Haklai, David Sniatkiwicz, linux-arm-kernel
In-Reply-To: <20171214103011.24713-3-miquel.raynal@free-electrons.com>

Hi Miquel,
 
 On jeu., déc. 14 2017, Miquel Raynal <miquel.raynal@free-electrons.com> wrote:

> From: Baruch Siach <baruch@tkos.co.il>
>
> Use msleep for long (> 10ms) delays, instead of the busy waiting mdelay.
> All delays are called from the probe routine, where scheduling is
> allowed.
>
> Signed-off-by: Baruch Siach <baruch@tkos.co.il>
> Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>

Reviewed-by: Gregory CLEMENT <gregory.clement@free-electrons.com>

Thanks,

Gregory
> ---
>  drivers/thermal/armada_thermal.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
> index 706d74798cbe..6c4af2622d4f 100644
> --- a/drivers/thermal/armada_thermal.c
> +++ b/drivers/thermal/armada_thermal.c
> @@ -113,7 +113,7 @@ static void armada370_init_sensor(struct platform_device *pdev,
>  	reg &= ~PMU_TDC0_START_CAL_MASK;
>  	writel(reg, priv->control);
>  
> -	mdelay(10);
> +	msleep(10);
>  }
>  
>  static void armada375_init_sensor(struct platform_device *pdev,
> @@ -127,11 +127,11 @@ static void armada375_init_sensor(struct platform_device *pdev,
>  	reg &= ~A375_HW_RESETn;
>  
>  	writel(reg, priv->control + 4);
> -	mdelay(20);
> +	msleep(20);
>  
>  	reg |= A375_HW_RESETn;
>  	writel(reg, priv->control + 4);
> -	mdelay(50);
> +	msleep(50);
>  }
>  
>  static void armada380_init_sensor(struct platform_device *pdev,
> @@ -143,7 +143,7 @@ static void armada380_init_sensor(struct platform_device *pdev,
>  	if (!(reg & A380_HW_RESET)) {
>  		reg |= A380_HW_RESET;
>  		writel(reg, priv->control);
> -		mdelay(10);
> +		msleep(10);
>  	}
>  }
>  
> -- 
> 2.11.0
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* Re: [PATCH v4 2/4] ARM: PWM: add allwinner sun8i R40/V40/T3 pwm support.
From: Claudiu Beznea @ 2017-12-14 10:44 UTC (permalink / raw)
  To: hao_zhang, thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	linux-I+IVW8TIWO2tmTQ+vhA3Yw, wens-jdAy2FN1RRM,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-pwm-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20171213144446.GA18217@arx-s1>



On 13.12.2017 16:44, hao_zhang wrote:
> This patch add allwinner sun8i R40/V40/T3 pwm support.
> 
> Signed-off-by: hao_zhang <hao5781286-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>  drivers/pwm/Kconfig         |  10 +
>  drivers/pwm/Makefile        |   1 +
>  drivers/pwm/pwm-sun8i-r40.c | 449 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 460 insertions(+)
>  create mode 100644 drivers/pwm/pwm-sun8i-r40.c
> 
> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> index 763ee50..cde5a70 100644
> --- a/drivers/pwm/Kconfig
> +++ b/drivers/pwm/Kconfig
> @@ -444,6 +444,16 @@ config PWM_SUN4I
>  	  To compile this driver as a module, choose M here: the module
>  	  will be called pwm-sun4i.
>  
> +config PWM_SUN8I_R40
> +	tristate "Allwinner PWM SUN8I R40 support"
> +	depends on ARCH_SUNXI || COMPILE_TEST
> +	depends on HAS_IOMEM && COMMON_CLK
> +	help
> +	  Generic PWM framework driver for Allwinner SoCs R40, V40, T3.
> +
> +	  To compile this driver as a module, choose M here: the module
> +	  will be called pwm-sun8i-r40.
> +
>  config PWM_TEGRA
>  	tristate "NVIDIA Tegra PWM support"
>  	depends on ARCH_TEGRA
> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> index 0258a74..026a55b 100644
> --- a/drivers/pwm/Makefile
> +++ b/drivers/pwm/Makefile
> @@ -44,6 +44,7 @@ obj-$(CONFIG_PWM_STM32)		+= pwm-stm32.o
>  obj-$(CONFIG_PWM_STM32_LP)	+= pwm-stm32-lp.o
>  obj-$(CONFIG_PWM_STMPE)		+= pwm-stmpe.o
>  obj-$(CONFIG_PWM_SUN4I)		+= pwm-sun4i.o
> +obj-$(CONFIG_PWM_SUN8I_R40)	+= pwm-sun8i-r40.o
>  obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
>  obj-$(CONFIG_PWM_TIECAP)	+= pwm-tiecap.o
>  obj-$(CONFIG_PWM_TIEHRPWM)	+= pwm-tiehrpwm.o
> diff --git a/drivers/pwm/pwm-sun8i-r40.c b/drivers/pwm/pwm-sun8i-r40.c
> new file mode 100644
> index 0000000..8df538d
> --- /dev/null
> +++ b/drivers/pwm/pwm-sun8i-r40.c
> @@ -0,0 +1,449 @@
> +#include <linux/bitops.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/jiffies.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pwm.h>
> +#include <linux/slab.h>
> +#include <linux/spinlock.h>
> +#include <linux/time.h>
> +
> +#define PWM_IRQ_ENABLE_REG	0x0000
> +#define PCIE(ch)	BIT(ch)
> +
> +#define PWM_IRQ_STATUS_REG	0x0004
> +#define PIS(ch)	BIT(ch)
> +
> +#define CAPTURE_IRQ_ENABLE_REG	0x0010
> +#define CFIE(ch)	BIT(ch << 1 + 1)
> +#define CRIE(ch)	BIT(ch << 1)
> +
> +#define CAPTURE_IRQ_STATUS_REG	0x0014
> +#define CFIS(ch)	BIT(ch << 1 + 1)
> +#define CRIS(ch)	BIT(ch << 1)
> +
> +#define CLK_CFG_REG(ch)	(0x0020 + (ch >> 1) * 4)
> +#define CLK_SRC	BIT(7)
> +#define CLK_SRC_BYPASS_SEC	BIT(6)
> +#define CLK_SRC_BYPASS_FIR	BIT(5)
> +#define CLK_GATING	BIT(4)
> +#define CLK_DIV_M	GENMASK(3, 0)
> +
> +#define PWM_DZ_CTR_REG(ch)	(0x0030 + (ch >> 1) * 4)
> +#define PWM_DZ_INTV	GENMASK(15, 8)
> +#define PWM_DZ_EN	BIT(0)
> +
> +#define PWM_ENABLE_REG	0x0040
> +#define PWM_EN(ch)	BIT(ch)
> +
> +#define CAPTURE_ENABLE_REG	0x0044
> +#define CAP_EN(ch)	BIT(ch)
> +
> +#define PWM_CTR_REG(ch)	(0x0060 + ch * 0x20)
> +#define PWM_PERIOD_RDY	BIT(11)
> +#define PWM_PUL_START	BIT(10)
> +#define PWM_MODE	BIT(9)
> +#define PWM_ACT_STA	BIT(8)
> +#define PWM_PRESCAL_K	GENMASK(7, 0)
> +
> +#define PWM_PERIOD_REG(ch)	(0x0064 + ch * 0x20)
> +#define PWM_ENTIRE_CYCLE	GENMASK(31, 16)
> +#define PWM_ACT_CYCLE	GENMASK(15, 0)
> +
> +#define PWM_CNT_REG(ch)	(0x0068 + ch * 0x20)
> +#define PWM_CNT_VAL	GENMASK(15, 0)
> +
> +#define CAPTURE_CTR_REG(ch)	(0x006c + ch * 0x20)
> +#define CAPTURE_CRLF	BIT(2)
> +#define CAPTURE_CFLF	BIT(1)
> +#define CAPINV	BIT(0)
> +
> +#define CAPTURE_RISE_REG(ch)	(0x0070 + ch * 0x20)
> +#define CAPTURE_CRLR	GENMASK(15, 0)
> +
> +#define CAPTURE_FALL_REG(ch)	(0x0074 + ch * 0x20)
> +#define CAPTURE_CFLR	GENMASK(15, 0)
> +
> +struct sunxi_pwm_data {
> +	bool has_prescaler_bypass;
> +	bool has_rdy;
> +	unsigned int npwm;
> +};
> +
> +struct sunxi_pwm_chip {
> +	struct pwm_chip chip;
> +	struct clk *clk;
> +	void __iomem *base;
> +	spinlock_t ctrl_lock;
> +	const struct sunxi_pwm_data *data;
> +};
> +
> +static const u16 div_m_table[] = {
> +	1,
> +	2,
> +	4,
> +	8,
> +	16,
> +	32,
> +	64,
> +	128,
> +	256
> +};
> +
> +static inline struct sunxi_pwm_chip *to_sunxi_pwm_chip(struct pwm_chip *chip)
> +{
> +	return container_of(chip, struct sunxi_pwm_chip, chip);
> +}
> +
> +static inline u32 sunxi_pwm_readl(struct sunxi_pwm_chip *chip,
> +		unsigned long offset)
> +{
> +	return readl(chip->base + offset);
> +}
> +
> +static inline void sunxi_pwm_writel(struct sunxi_pwm_chip *chip,
> +		u32 val, unsigned long offset)
> +{
> +	writel(val, chip->base + offset);
> +}
> +
> +static void sunxi_pwm_set_bit(struct sunxi_pwm_chip *sunxi_pwm,
> +		unsigned long reg, u32 bit)
> +{
> +	u32 val;
> +
> +	val = sunxi_pwm_readl(sunxi_pwm, reg);
> +	val |= bit;
> +	sunxi_pwm_writel(sunxi_pwm, val, reg);
> +}
> +
> +static void sunxi_pwm_clear_bit(struct sunxi_pwm_chip *sunxi_pwm,
> +		unsigned long reg, u32 bit)
> +{
> +	u32 val;
> +
> +	val = sunxi_pwm_readl(sunxi_pwm, reg);
> +	val &= ~bit;
> +	sunxi_pwm_writel(sunxi_pwm, val, reg);
> +}
> +
> +static void sunxi_pwm_set_value(struct sunxi_pwm_chip *sunxi_pwm,
> +		unsigned long reg, u32 mask, u32 val)
> +{
> +	u32 tmp;
> +
> +	tmp = sunxi_pwm_readl(sunxi_pwm, reg);
> +	tmp &= ~mask;
> +	tmp |= mask & val;
> +	sunxi_pwm_writel(sunxi_pwm, tmp, reg);
> +}
> +
> +static void sunxi_pwm_set_polarity(struct sunxi_pwm_chip *chip, u32 ch,
> +		enum pwm_polarity polarity)
> +{
> +	if (polarity == PWM_POLARITY_NORMAL)
> +		sunxi_pwm_set_bit(chip, PWM_CTR_REG(ch), PWM_ACT_STA);
> +	else
> +		sunxi_pwm_clear_bit(chip, PWM_CTR_REG(ch), PWM_ACT_STA);
> +}
> +
> +static void sunxi_dump_reg(struct sunxi_pwm_chip *sunxi_pwm, u8 ch)
> +{
> +	dev_dbg(sunxi_pwm->chip.dev, "ch: %d\n"
> +			"\tPWM_IRQ_ENABLE_REG(%04x): \t0x%08x\n"
> +			"\tPWM_IRQ_STATUS_REG(%04x): \t0x%08x\n"
> +			"\tCAPTURE_IRQ_ENABLE_REG(%04x): \t0x%08x\n"
> +			"\tCAPTURE_IRQ_STATUS_REG(%04x): \t0x%08x\n"
> +			"\tCLK_CFG_REG(%04x)(%d): \t0x%08x\n"
> +			"\tPWM_DZ_CTR_REG(%04x)(%d): \t0x%08x\n"
> +			"\tPWM_ENABLE_REG(%04x): \t0x%08x\n"
> +			"\tCAPTURE_ENABLE_REG(%04x): \t0x%08x\n"
> +			"\tPWM_CTR_REG(%04x)(%d): \t0x%08x\n"
> +			"\tPWM_PERIOD_REG(%04x)(%d): \t0x%08x\n"
> +			"\tPWM_CNT_REG(%04x)(%d): \t0x%08x\n"
> +			"\tCAPTURE_CTR_REG(%04x)(%d): \t0x%08x\n"
> +			"\tCAPTURE_RISE_REG(%04x)(%d): \t0x%08x\n"
> +			"\tCAPTURE_FALL_REG(%04x)(%d): \t0x%08x\n",
> +			ch,
> +			PWM_IRQ_ENABLE_REG,
> +			readl(sunxi_pwm->base + PWM_IRQ_ENABLE_REG),
> +			PWM_IRQ_STATUS_REG,
> +			readl(sunxi_pwm->base + PWM_IRQ_STATUS_REG),
> +			CAPTURE_IRQ_ENABLE_REG,
> +			readl(sunxi_pwm->base + CAPTURE_IRQ_ENABLE_REG),
> +			CAPTURE_IRQ_STATUS_REG,
> +			readl(sunxi_pwm->base + CAPTURE_IRQ_STATUS_REG),
> +			CLK_CFG_REG(ch),
> +			ch, readl(sunxi_pwm->base + CLK_CFG_REG(ch)),
> +			PWM_DZ_CTR_REG(ch),
> +			ch, readl(sunxi_pwm->base + PWM_DZ_CTR_REG(ch)),
> +			PWM_ENABLE_REG,
> +			readl(sunxi_pwm->base + PWM_ENABLE_REG),
> +			CAPTURE_ENABLE_REG,
> +			readl(sunxi_pwm->base + CAPTURE_ENABLE_REG),
> +			PWM_CTR_REG(ch),
> +			ch, readl(sunxi_pwm->base + PWM_CTR_REG(ch)),
> +			PWM_PERIOD_REG(ch),
> +			ch, readl(sunxi_pwm->base + PWM_PERIOD_REG(ch)),
> +			PWM_CNT_REG(ch),
> +			ch, readl(sunxi_pwm->base + PWM_CNT_REG(ch)),
> +			CAPTURE_CTR_REG(ch),
> +			ch, readl(sunxi_pwm->base + CAPTURE_CTR_REG(ch)),
> +			CAPTURE_RISE_REG(ch),
> +			ch, readl(sunxi_pwm->base + CAPTURE_RISE_REG(ch)),
> +			CAPTURE_FALL_REG(ch),
> +			ch, readl(sunxi_pwm->base + CAPTURE_FALL_REG(ch)));
> +}
> +
> +static int sunxi_pwm_config(struct sunxi_pwm_chip *sunxi_pwm, u8 ch,
> +		struct pwm_state *state)
> +{
> +	u64 clk_rate, clk_div, val;
> +	u16 prescaler = 0;
> +	u8 id = 0;
> +
> +	clk_rate = clk_get_rate(sunxi_pwm->clk);
> +	dev_dbg(sunxi_pwm->chip.dev, "clock rate:%lld\n", clk_rate);
> +
> +	if (clk_rate == 24000000)
> +		sunxi_pwm_clear_bit(sunxi_pwm, CLK_CFG_REG(ch), CLK_SRC);
> +	else
> +		sunxi_pwm_set_bit(sunxi_pwm, CLK_CFG_REG(ch), CLK_SRC);
> +
> +	if (sunxi_pwm->data->has_prescaler_bypass) {
> +		/* pwm output bypass */
> +		if (ch % 2)
> +			sunxi_pwm_set_bit(sunxi_pwm, CLK_CFG_REG(ch),
> +					CLK_SRC_BYPASS_FIR);
> +		else
> +			sunxi_pwm_set_bit(sunxi_pwm, CLK_CFG_REG(ch),
> +					CLK_SRC_BYPASS_SEC);
> +		return 0;
> +	}
> +
> +	val = state->period * clk_rate;
> +	do_div(val, NSEC_PER_SEC);
> +	if (val < 1) {
> +		dev_err(sunxi_pwm->chip.dev,
> +				"period expects a larger value\n");
> +		return -EINVAL;
> +	}
> +
> +	/* calculate and set prescalar, div table, pwn entrie cycle */
> +	clk_div = val;
> +
> +	while (clk_div > 65535) {
> +		prescaler++;
> +		clk_div = val;
> +		do_div(clk_div, prescaler + 1);
> +		do_div(clk_div, div_m_table[id]);
> +
> +		if (prescaler == 255) {
> +			prescaler = 0;
> +			id++;
> +			if (id == 9)
> +				return -EINVAL;
> +		}
> +	}
> +
> +	sunxi_pwm_set_value(sunxi_pwm, PWM_PERIOD_REG(ch),
> +			PWM_ENTIRE_CYCLE, clk_div << 16);
> +	sunxi_pwm_set_value(sunxi_pwm, PWM_CTR_REG(ch),
> +			PWM_PRESCAL_K, prescaler << 0);
> +	sunxi_pwm_set_value(sunxi_pwm, CLK_CFG_REG(ch),
> +			CLK_DIV_M, id << 0);
> +
> +	/* set duty cycle */
> +	val = (prescaler + 1) * div_m_table[id] * clk_div;
> +	val = state->period;
> +	do_div(val, clk_div);
> +	clk_div = state->duty_cycle;
> +	do_div(clk_div, val);
> +
> +	sunxi_pwm_set_value(sunxi_pwm, PWM_PERIOD_REG(ch),
> +			PWM_ACT_CYCLE, clk_div << 0);
> +
> +	return 0;
> +}
> +
> +static int sunxi_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> +		struct pwm_state *state)
> +{
> +	int ret;
> +	struct sunxi_pwm_chip *sunxi_pwm = to_sunxi_pwm_chip(chip);
> +	struct pwm_state cstate;
> +
> +	sunxi_dump_reg(sunxi_pwm, pwm->hwpwm);
> +	pwm_get_state(pwm, &cstate);
> +	if (!cstate.enabled) {
> +		ret = clk_prepare_enable(sunxi_pwm->clk);
> +		if (ret) {
> +			dev_err(chip->dev, "failed to enable PWM clock\n");
> +			return ret;
> +		}
> +	}
> +
> +	spin_lock(&sunxi_pwm->ctrl_lock);
> +
> +	if (state->polarity != cstate.polarity)
> +		sunxi_pwm_set_polarity(sunxi_pwm, pwm->hwpwm, state->polarity);
> +
> +	if ((cstate.period != state->period) ||
> +			(cstate.duty_cycle != state->duty_cycle)) {
> +		ret = sunxi_pwm_config(sunxi_pwm, pwm->hwpwm, state);
> +		if (ret) {
> +			dev_err(chip->dev, "failed to enable PWM clock\n");
> +			return ret;
Here you might want to undo the previous polarity and do clk_disable_unprepare(),
if any, in order to not reach inconsistency b/w software state of PWM and hardware
state. Also, unlock the spinlock.
> +		}
> +	}
> +
> +	if (state->enabled) {
> +		sunxi_pwm_set_bit(sunxi_pwm,
> +				CLK_CFG_REG(pwm->hwpwm), CLK_GATING);
> +
> +		sunxi_pwm_set_bit(sunxi_pwm,
> +				PWM_ENABLE_REG, PWM_EN(pwm->hwpwm));
> +	} else {
> +		sunxi_pwm_clear_bit(sunxi_pwm,
> +				CLK_CFG_REG(pwm->hwpwm), CLK_GATING);
> +
> +		sunxi_pwm_clear_bit(sunxi_pwm,
> +				PWM_ENABLE_REG, PWM_EN(pwm->hwpwm));
> +	}
> +
> +	spin_unlock(&sunxi_pwm->ctrl_lock);
> +	sunxi_dump_reg(sunxi_pwm, pwm->hwpwm);
> +
> +	return 0;
> +}
> +
> +static void sunxi_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
> +		struct pwm_state *state)
> +{
> +	struct sunxi_pwm_chip *sunxi_pwm = to_sunxi_pwm_chip(chip);
> +	u64 clk_rate, tmp;
> +	u32 val;
> +	u16 clk_div, act_cycle;
> +	u8 prescal, id;
> +
> +	clk_rate = clk_get_rate(sunxi_pwm->clk);
> +
> +	val = sunxi_pwm_readl(sunxi_pwm, PWM_CTR_REG(pwm->hwpwm));
> +	if (PWM_ACT_STA & val)
> +		state->polarity = PWM_POLARITY_NORMAL;
> +	else
> +		state->polarity = PWM_POLARITY_INVERSED;
> +
> +	prescal = PWM_PRESCAL_K & val;
> +
> +	val = sunxi_pwm_readl(sunxi_pwm, PWM_ENABLE_REG);
> +	if (PWM_EN(pwm->hwpwm) & val)
> +		state->enabled = true;
> +	else
> +		state->enabled = false;
> +
> +	val = sunxi_pwm_readl(sunxi_pwm, PWM_PERIOD_REG(pwm->hwpwm));
> +	act_cycle = PWM_ACT_CYCLE & val;
> +	clk_div = val >> 16;
> +
> +	val = sunxi_pwm_readl(sunxi_pwm, CLK_CFG_REG(pwm->hwpwm));
> +	id = CLK_DIV_M & val;
> +
> +	tmp = act_cycle * prescal * div_m_table[id] * NSEC_PER_SEC;
> +	state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
> +	tmp = clk_div * prescal * div_m_table[id] * NSEC_PER_SEC;
> +	state->period = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
> +}
> +
> +static const struct pwm_ops sunxi_pwm_ops = {
> +	.apply = sunxi_pwm_apply,
> +	.get_state = sunxi_pwm_get_state,
> +	.owner = THIS_MODULE,
> +};
> +
> +static const struct sunxi_pwm_data sunxi_pwm_data_r40 = {
> +	.has_prescaler_bypass = false,
> +	.has_rdy = true,
> +	.npwm = 8,
> +};
> +
> +static const struct of_device_id sunxi_pwm_dt_ids[] = {
> +	{
> +		.compatible = "allwinner,sun8i-r40-pwm",
> +		.data = &sunxi_pwm_data_r40,
> +	},
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, sunxi_pwm_dt_ids);
> +
> +static int sunxi_pwm_probe(struct platform_device *pdev)
> +{
> +	struct sunxi_pwm_chip *pwm;
> +	struct resource *res;
> +	int ret;
> +	const struct of_device_id *match;
> +
> +	match = of_match_device(sunxi_pwm_dt_ids, &pdev->dev);
> +
> +	pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
> +	if (!pwm)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
check for res == NULL
> +	pwm->base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(pwm->base))
> +		return PTR_ERR(pwm->base);
> +
> +	pwm->clk = devm_clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(pwm->clk))
> +		return PTR_ERR(pwm->clk);
> +
> +	pwm->data = match->data;
> +	pwm->chip.dev = &pdev->dev;
> +	pwm->chip.ops = &sunxi_pwm_ops;
> +	pwm->chip.base = -1;
> +	pwm->chip.npwm = pwm->data->npwm;
> +	pwm->chip.of_xlate = of_pwm_xlate_with_flags;
> +	pwm->chip.of_pwm_n_cells = 3;
> +
> +	dev_dbg(pwm->chip.dev, "npwm: %d\n", pwm->chip.npwm);
> +
> +	spin_lock_init(&pwm->ctrl_lock);
> +
> +	ret = pwmchip_add(&pwm->chip);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
> +		return ret;
> +	}
> +
> +	platform_set_drvdata(pdev, pwm);
> +
> +	return 0;
> +}
> +
> +static int sunxi_pwm_remove(struct platform_device *pdev)
> +{
> +	struct sunxi_pwm_chip *pwm = platform_get_drvdata(pdev);
> +
> +	return pwmchip_remove(&pwm->chip);
> +}
> +
> +static struct platform_driver sunxi_pwm_driver = {
> +	.driver = {
> +		.name = "sun8i-r40-pwm",
> +		.of_match_table = sunxi_pwm_dt_ids,
> +	},
> +	.probe = sunxi_pwm_probe,
> +	.remove = sunxi_pwm_remove,
> +};
> +module_platform_driver(sunxi_pwm_driver);
> +
> +MODULE_ALIAS("platform:sun8i-r40-pwm");
> +MODULE_AUTHOR("Hao Zhang <hao5781286-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
> +MODULE_DESCRIPTION("Allwinner sun8i-r40 PWM driver");
> +MODULE_LICENSE("GPL v2");
> 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH V3 0/2] Tegra PCIe end point config space map code refactoring
From: Lorenzo Pieralisi @ 2017-12-14 10:37 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Bjorn Helgaas, Bjorn Helgaas, Vidya Sagar,
	treding-DDmLM1+adcrQT0dZR+AlfA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, kthota-DDmLM1+adcrQT0dZR+AlfA,
	mmaddireddy-DDmLM1+adcrQT0dZR+AlfA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20171212122252.GA29883@ulmo>

On Tue, Dec 12, 2017 at 01:22:52PM +0100, Thierry Reding wrote:

[...]

> > > > Hi Bjorn,
> > > > 
> > > > there's a bunch of PCI related patches for Tegra floating around on the
> > > > lists. I'm wondering if you'd be okay if I pick those up into the Tegra
> > > > tree after they've been reviewed and send you a pull request later on
> > > > (say around v4.15-rc6). That would allow me to get things cooking in
> > > > linux-next for a bit and get broader testing in addition to the
> > > > flexibility to patch things up if they break.
> > > 
> > > Lorenzo will be merging the Tegra stuff, so this is more a question
> > > for him.
> > > 
> > > Just to clarify, I think your questions is about putting those patches
> > > in
> > > git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git#for-next.
> > > If you put them there they will show up in linux-next, and then when
> > > Lorenzo merges them, you'll have to coordinate so they don't get
> > > merged into linux-next twice (once via the usual PCI tree route and
> > > again via the Tegra tree).
> > > 
> > > If you wait until after they've been reviewed to put them into the
> > > Tegra tree, I'm not sure what the gain is, because I assume Lorenzo
> > > would merge them at about that same point.
> > 
> > I think that after the review, the Tegra patches that are considered for
> > upstream they should go to -next via the PCI tree as any other platform PCI
> > patches; the relevant patches need ACKs from the respective platform
> > maintainer - I am getting to them as fast as I can.
> 
> Just to clarify: I wasn't suggesting that these patches are merged for
> v4.16 via the Tegra tree, only that I carry them in the Tegra tree for a
> little while so that we can get broader testing and fix things up in
> case they break. My proposal was to then send a pull request for
> inclusion in the PCI tree. linux-next can deal with this type of
> scenario just fine because it will simply see the same branch twice and
> ignore the second one.
> 
> If you prefer to merge directly via the PCI tree that works for me too.

We would end up merging the patches into -next at the same time, so there
is not much point in queuing them via Tegra if they go via the PCI tree
eventually; we should not add to -next patches that are not ready to
be merged anyway.

I need your help (ACKs) though to queue them up - I review the patches
but I can neither test them nor get access to HW TRMs so for some of them
there is not much I can do.

Thanks,
Lorenzo

^ permalink raw reply

* [PATCH v3 11/11] ARM64: dts: marvell: Add thermal support for A7K/A8K
From: Miquel Raynal @ 2017-12-14 10:30 UTC (permalink / raw)
  To: Zhang Rui, Eduardo Valentin, Rob Herring, Mark Rutland,
	Jason Cooper, Andrew Lunn, Gregory Clement, Sebastian Hesselbarth,
	Catalin Marinas, Will Deacon
  Cc: linux-pm, devicetree, linux-arm-kernel, Thomas Petazzoni,
	Antoine Tenart, Nadav Haklai, Miquel Raynal, Baruch Siach,
	David Sniatkiwicz
In-Reply-To: <20171214103011.24713-1-miquel.raynal@free-electrons.com>

Add thermal DT nodes in AP806 and CP110 master/slave DTSI files.

Suggested-by: David Sniatkiwicz <davidsn@marvell.com>
Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
---
 arch/arm64/boot/dts/marvell/armada-ap806.dtsi        | 7 +++++++
 arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi | 7 +++++++
 arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi  | 7 +++++++
 3 files changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
index 1c4dd8ab9ad5..ceda98a4f8cc 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
@@ -285,6 +285,13 @@
 					gpio-ranges = <&ap_pinctrl 0 0 20>;
 				};
 			};
+
+			ap_thermal: thermal@6f808C {
+				compatible = "marvell,armada-ap806-thermal";
+				reg = <0x6f808C 0x4>,
+				      <0x6f8084 0x8>;
+				marvell,thermal-zone-name = "ap_thermal_zone";
+			};
 		};
 	};
 };
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
index e3b64d03fbd8..0dc92897fd7c 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
@@ -182,6 +182,13 @@
 				interrupts = <ICU_GRP_NSR 77 IRQ_TYPE_LEVEL_HIGH>;
 			};
 
+			cpm_thermal: thermal@400078 {
+				compatible = "marvell,armada-cp110-thermal";
+				reg = <0x400078 0x4>,
+				      <0x400070 0x8>;
+				marvell,thermal-zone-name = "cp0_thermal_zone";
+			};
+
 			cpm_syscon0: system-controller@440000 {
 				compatible = "syscon", "simple-mfd";
 				reg = <0x440000 0x2000>;
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
index 0d51096c69f8..5a7589a90db1 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
@@ -182,6 +182,13 @@
 				interrupts = <ICU_GRP_NSR 77 IRQ_TYPE_LEVEL_HIGH>;
 			};
 
+			cps_thermal: thermal@400078 {
+				compatible = "marvell,armada-cp110-thermal";
+				reg = <0x400078 0x4>,
+				      <0x400070 0x8>;
+				marvell,thermal-zone-name = "cp1_thermal_zone";
+			};
+
 			cps_syscon0: system-controller@440000 {
 				compatible = "syscon", "simple-mfd";
 				reg = <0x440000 0x2000>;
-- 
2.11.0

^ permalink raw reply related

* [PATCH v3 10/11] thermal: armada: Give useful names to the thermal zone
From: Miquel Raynal @ 2017-12-14 10:30 UTC (permalink / raw)
  To: Zhang Rui, Eduardo Valentin, Rob Herring, Mark Rutland,
	Jason Cooper, Andrew Lunn, Gregory Clement, Sebastian Hesselbarth,
	Catalin Marinas, Will Deacon
  Cc: linux-pm, devicetree, linux-arm-kernel, Thomas Petazzoni,
	Antoine Tenart, Nadav Haklai, Miquel Raynal, Baruch Siach,
	David Sniatkiwicz
In-Reply-To: <20171214103011.24713-1-miquel.raynal@free-electrons.com>

After registration to the thermal core, sysfs will make one entry
per instance of the driver in /sys/class/thermal_zoneX and
/sys/class/hwmon/hwmonX, X being the index of the instance, all of them
having the type/name "armada_thermal".

Until now there was only one thermal zone per SoC but SoCs like Armada
A7K and Armada A8K have respectively two and three thermal zones (one
per AP and one per CP) and this number is subject to grow in the future.

Because there is no easy way to name them effectively, use the new DT
property "marvell,thermal-zone-name" if it is available.

Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
---
 drivers/thermal/armada_thermal.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 1c4122f7377c..b31d03dde44b 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -357,6 +357,8 @@ MODULE_DEVICE_TABLE(of, armada_thermal_id_table);
 
 static int armada_thermal_probe(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
+	const char *zone_name = "armada_thermal";
 	void __iomem *control = NULL;
 	struct thermal_zone_device *thermal;
 	const struct of_device_id *match;
@@ -398,8 +400,14 @@ static int armada_thermal_probe(struct platform_device *pdev)
 	priv->data = (struct armada_thermal_data *)match->data;
 	priv->data->init_sensor(pdev, priv);
 
-	thermal = thermal_zone_device_register("armada_thermal", 0, 0,
-					       priv, &ops, NULL, 0, 0);
+	/*
+	 * Some platforms use several instances of this driver without any way
+	 * to identify them. Use a new property to gave the thermal zone name a
+	 * valid meaning (used by hwmon too).
+	 */
+	of_property_read_string(np, "marvell,thermal-zone-name", &zone_name);
+	thermal = thermal_zone_device_register(zone_name, 0, 0, priv, &ops,
+					       NULL, 0, 0);
 	if (IS_ERR(thermal)) {
 		dev_err(&pdev->dev,
 			"Failed to register thermal zone device\n");
-- 
2.11.0

^ permalink raw reply related

* [PATCH v3 09/11] thermal: armada: Wait sensors validity before exiting the init callback
From: Miquel Raynal @ 2017-12-14 10:30 UTC (permalink / raw)
  To: Zhang Rui, Eduardo Valentin, Rob Herring, Mark Rutland,
	Jason Cooper, Andrew Lunn, Gregory Clement, Sebastian Hesselbarth,
	Catalin Marinas, Will Deacon
  Cc: linux-pm, devicetree, linux-arm-kernel, Thomas Petazzoni,
	Antoine Tenart, Nadav Haklai, Miquel Raynal, Baruch Siach,
	David Sniatkiwicz
In-Reply-To: <20171214103011.24713-1-miquel.raynal@free-electrons.com>

The thermal core will check for sensors validity right after the
initialization callback has returned. As the initialization routine make
a reset, the sensors are not ready immediately and the core spawns an
error in the dmesg. Avoid this annoying situation by polling on the
validity bit before exiting from these routines. This also avoid the use
of blind sleeps.

Suggested-by: David Sniatkiwicz <davidsn@marvell.com>
Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
---
 drivers/thermal/armada_thermal.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index be141ca53e83..1c4122f7377c 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/of_device.h>
 #include <linux/thermal.h>
+#include <linux/iopoll.h>
 
 /* Thermal Manager Control and Status Register */
 #define PMU_TDC0_SW_RST_MASK		(0x1 << 1)
@@ -59,6 +60,9 @@
 #define CONTROL1_EXT_TSEN_SW_RESET	BIT(7)
 #define CONTROL1_EXT_TSEN_HW_RESETn	BIT(8)
 
+#define STATUS_POLL_PERIOD_US		1000
+#define STATUS_POLL_TIMEOUT_US		100000
+
 struct armada_thermal_data;
 
 /* Marvell EBU Thermal Sensor Dev Structure */
@@ -154,6 +158,16 @@ static void armada375_init_sensor(struct platform_device *pdev,
 	msleep(50);
 }
 
+static void armada_wait_sensor_validity(struct armada_thermal_priv *priv)
+{
+	u32 reg;
+
+	readl_relaxed_poll_timeout(priv->status, reg,
+				   reg & priv->data->is_valid_bit,
+				   STATUS_POLL_PERIOD_US,
+				   STATUS_POLL_TIMEOUT_US);
+}
+
 static void armada380_init_sensor(struct platform_device *pdev,
 				  struct armada_thermal_priv *priv)
 {
@@ -163,7 +177,6 @@ static void armada380_init_sensor(struct platform_device *pdev,
 	reg |= CONTROL1_EXT_TSEN_HW_RESETn;
 	reg &= ~CONTROL1_EXT_TSEN_SW_RESET;
 	writel(reg, priv->control1);
-	msleep(10);
 
 	/* Set Tsen Tc Trim to correct default value (errata #132698) */
 	if (priv->control0) {
@@ -171,8 +184,10 @@ static void armada380_init_sensor(struct platform_device *pdev,
 		reg &= ~CONTROL0_TSEN_TC_TRIM_MASK;
 		reg |= CONTROL0_TSEN_TC_TRIM_VAL;
 		writel(reg, priv->control0);
-		msleep(10);
 	}
+
+	/* Wait the sensors to be valid or the core will warn the user */
+	armada_wait_sensor_validity(priv);
 }
 
 static void armada_ap806_init_sensor(struct platform_device *pdev,
@@ -190,7 +205,9 @@ static void armada_ap806_init_sensor(struct platform_device *pdev,
 	reg &= ~CONTROL0_TSEN_RESET;
 	reg |= CONTROL0_TSEN_START | CONTROL0_TSEN_ENABLE;
 	writel(reg, priv->control0);
-	msleep(10);
+
+	/* Wait the sensors to be valid or the core will warn the user */
+	armada_wait_sensor_validity(priv);
 }
 
 static bool armada_is_valid(struct armada_thermal_priv *priv)
-- 
2.11.0

^ permalink raw reply related

* [PATCH v3 08/11] thermal: armada: Change sensors trim default value
From: Miquel Raynal @ 2017-12-14 10:30 UTC (permalink / raw)
  To: Zhang Rui, Eduardo Valentin, Rob Herring, Mark Rutland,
	Jason Cooper, Andrew Lunn, Gregory Clement, Sebastian Hesselbarth,
	Catalin Marinas, Will Deacon
  Cc: linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Thomas Petazzoni, Antoine Tenart, Nadav Haklai, Miquel Raynal,
	Baruch Siach, David Sniatkiwicz
In-Reply-To: <20171214103011.24713-1-miquel.raynal-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

Errata #132698 highlights an error in the default value of Tc trim.
Set this parameter to b'011.

Suggested-by: David Sniatkiwicz <davidsn-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Miquel Raynal <miquel.raynal-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 drivers/thermal/armada_thermal.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index da58a8961a37..be141ca53e83 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -46,6 +46,10 @@
 #define CONTROL0_OFFSET			0x0
 #define CONTROL1_OFFSET			0x4
 
+/* Errata fields */
+#define CONTROL0_TSEN_TC_TRIM_MASK	0x7
+#define CONTROL0_TSEN_TC_TRIM_VAL	0x3
+
 /* TSEN refers to the temperature sensors within the AP */
 #define CONTROL0_TSEN_START		BIT(0)
 #define CONTROL0_TSEN_RESET		BIT(1)
@@ -160,6 +164,15 @@ static void armada380_init_sensor(struct platform_device *pdev,
 	reg &= ~CONTROL1_EXT_TSEN_SW_RESET;
 	writel(reg, priv->control1);
 	msleep(10);
+
+	/* Set Tsen Tc Trim to correct default value (errata #132698) */
+	if (priv->control0) {
+		reg = readl_relaxed(priv->control0);
+		reg &= ~CONTROL0_TSEN_TC_TRIM_MASK;
+		reg |= CONTROL0_TSEN_TC_TRIM_VAL;
+		writel(reg, priv->control0);
+		msleep(10);
+	}
 }
 
 static void armada_ap806_init_sensor(struct platform_device *pdev,
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v3 07/11] thermal: armada: Update Kconfig and module description
From: Miquel Raynal @ 2017-12-14 10:30 UTC (permalink / raw)
  To: Zhang Rui, Eduardo Valentin, Rob Herring, Mark Rutland,
	Jason Cooper, Andrew Lunn, Gregory Clement, Sebastian Hesselbarth,
	Catalin Marinas, Will Deacon
  Cc: linux-pm, devicetree, linux-arm-kernel, Thomas Petazzoni,
	Antoine Tenart, Nadav Haklai, Miquel Raynal, Baruch Siach,
	David Sniatkiwicz
In-Reply-To: <20171214103011.24713-1-miquel.raynal@free-electrons.com>

Update Armada thermal driver Kconfig entry as well as the driver's
MODULE_DESCRIPTION content, now that 64-bit SoCs are also supported,
eg. Armada 7K and Armada 8K.

Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
---
 drivers/thermal/Kconfig          | 4 ++--
 drivers/thermal/armada_thermal.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 315ae2926e20..44cad046f272 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -301,13 +301,13 @@ config DB8500_THERMAL
 	  thermal zone if trip points reached.
 
 config ARMADA_THERMAL
-	tristate "Armada 370/XP thermal management"
+	tristate "Armada 370/XP/7K/8K thermal management"
 	depends on ARCH_MVEBU || COMPILE_TEST
 	depends on HAS_IOMEM
 	depends on OF
 	help
 	  Enable this option if you want to have support for thermal management
-	  controller present in Armada 370 and Armada XP SoC.
+	  controller present in Armada 370, Armada XP, Armada 7K/8K SoCs.
 
 config DA9062_THERMAL
 	tristate "DA9062/DA9061 Dialog Semiconductor thermal driver"
diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index f5c911524656..da58a8961a37 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -403,5 +403,5 @@ static struct platform_driver armada_thermal_driver = {
 module_platform_driver(armada_thermal_driver);
 
 MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>");
-MODULE_DESCRIPTION("Armada 370/XP thermal driver");
+MODULE_DESCRIPTION("Armada SoCs thermal driver");
 MODULE_LICENSE("GPL v2");
-- 
2.11.0

^ permalink raw reply related

* [PATCH v3 06/11] thermal: armada: Add support for Armada CP110
From: Miquel Raynal @ 2017-12-14 10:30 UTC (permalink / raw)
  To: Zhang Rui, Eduardo Valentin, Rob Herring, Mark Rutland,
	Jason Cooper, Andrew Lunn, Gregory Clement, Sebastian Hesselbarth,
	Catalin Marinas, Will Deacon
  Cc: linux-pm, devicetree, linux-arm-kernel, Thomas Petazzoni,
	Antoine Tenart, Nadav Haklai, Miquel Raynal, Baruch Siach,
	David Sniatkiwicz
In-Reply-To: <20171214103011.24713-1-miquel.raynal@free-electrons.com>

From: Baruch Siach <baruch@tkos.co.il>

The CP110 component is integrated in the Armada 8k and 7k lines of
processors.

Signed-off-by: Baruch Siach <baruch@tkos.co.il>
[<miquel.raynal@free-electrons.com>: renamed the register pointers]
Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
---
 drivers/thermal/armada_thermal.c | 30 ++++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 279d01937bb8..f5c911524656 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -37,7 +37,6 @@
 #define A375_UNIT_CONTROL_MASK		0x7
 #define A375_READOUT_INVERT		BIT(15)
 #define A375_HW_RESETn			BIT(8)
-#define A380_HW_RESET			BIT(8)
 
 /* Legacy bindings */
 #define LEGACY_CONTROL_MEM_LEN		0x4
@@ -52,6 +51,10 @@
 #define CONTROL0_TSEN_RESET		BIT(1)
 #define CONTROL0_TSEN_ENABLE		BIT(2)
 
+/* EXT_TSEN refers to the external temperature sensors, out of the AP */
+#define CONTROL1_EXT_TSEN_SW_RESET	BIT(7)
+#define CONTROL1_EXT_TSEN_HW_RESETn	BIT(8)
+
 struct armada_thermal_data;
 
 /* Marvell EBU Thermal Sensor Dev Structure */
@@ -153,11 +156,10 @@ static void armada380_init_sensor(struct platform_device *pdev,
 	u32 reg = readl_relaxed(priv->control1);
 
 	/* Reset hardware once */
-	if (!(reg & A380_HW_RESET)) {
-		reg |= A380_HW_RESET;
-		writel(reg, priv->control1);
-		msleep(10);
-	}
+	reg |= CONTROL1_EXT_TSEN_HW_RESETn;
+	reg &= ~CONTROL1_EXT_TSEN_SW_RESET;
+	writel(reg, priv->control1);
+	msleep(10);
 }
 
 static void armada_ap806_init_sensor(struct platform_device *pdev,
@@ -280,6 +282,18 @@ static const struct armada_thermal_data armada_ap806_data = {
 	.signed_sample = true,
 };
 
+static const struct armada_thermal_data armada_cp110_data = {
+	.is_valid = armada_is_valid,
+	.init_sensor = armada380_init_sensor,
+	.is_valid_bit = BIT(10),
+	.temp_shift = 0,
+	.temp_mask = 0x3ff,
+	.coef_b = 1172499100UL,
+	.coef_m = 2000096UL,
+	.coef_div = 4201,
+	.inverted = true,
+};
+
 static const struct of_device_id armada_thermal_id_table[] = {
 	{
 		.compatible = "marvell,armadaxp-thermal",
@@ -302,6 +316,10 @@ static const struct of_device_id armada_thermal_id_table[] = {
 		.data       = &armada_ap806_data,
 	},
 	{
+		.compatible = "marvell,armada-cp110-thermal",
+		.data       = &armada_cp110_data,
+	},
+	{
 		/* sentinel */
 	},
 };
-- 
2.11.0

^ permalink raw reply related

* [PATCH v3 05/11] thermal: armada: Add support for Armada AP806
From: Miquel Raynal @ 2017-12-14 10:30 UTC (permalink / raw)
  To: Zhang Rui, Eduardo Valentin, Rob Herring, Mark Rutland,
	Jason Cooper, Andrew Lunn, Gregory Clement, Sebastian Hesselbarth,
	Catalin Marinas, Will Deacon
  Cc: linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Thomas Petazzoni, Antoine Tenart, Nadav Haklai, Miquel Raynal,
	Baruch Siach, David Sniatkiwicz
In-Reply-To: <20171214103011.24713-1-miquel.raynal-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

From: Baruch Siach <baruch-NswTu9S1W3P6gbPvEgmw2w@public.gmane.org>

The AP806 component is integrated in the Armada 8k and 7k lines of
processors.

The thermal sensor sample field on the status register is a signed
value. Extend armada_get_temp() to handle signed values.

Signed-off-by: Baruch Siach <baruch-NswTu9S1W3P6gbPvEgmw2w@public.gmane.org>
Signed-off-by: Miquel Raynal <miquel.raynal-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 drivers/thermal/armada_thermal.c | 51 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index e5b184cee79b..279d01937bb8 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -47,6 +47,11 @@
 #define CONTROL0_OFFSET			0x0
 #define CONTROL1_OFFSET			0x4
 
+/* TSEN refers to the temperature sensors within the AP */
+#define CONTROL0_TSEN_START		BIT(0)
+#define CONTROL0_TSEN_RESET		BIT(1)
+#define CONTROL0_TSEN_ENABLE		BIT(2)
+
 struct armada_thermal_data;
 
 /* Marvell EBU Thermal Sensor Dev Structure */
@@ -70,6 +75,7 @@ struct armada_thermal_data {
 	unsigned long coef_m;
 	unsigned long coef_div;
 	bool inverted;
+	bool signed_sample;
 
 	/* Register shift and mask to access the sensor temperature */
 	unsigned int temp_shift;
@@ -154,6 +160,24 @@ static void armada380_init_sensor(struct platform_device *pdev,
 	}
 }
 
+static void armada_ap806_init_sensor(struct platform_device *pdev,
+				     struct armada_thermal_priv *priv)
+{
+	u32 reg;
+
+	if (!priv->control0) {
+		dev_err(&pdev->dev,
+			"Cannot access to control0 (control LSB) register\n");
+		return;
+	}
+
+	reg = readl_relaxed(priv->control0);
+	reg &= ~CONTROL0_TSEN_RESET;
+	reg |= CONTROL0_TSEN_START | CONTROL0_TSEN_ENABLE;
+	writel(reg, priv->control0);
+	msleep(10);
+}
+
 static bool armada_is_valid(struct armada_thermal_priv *priv)
 {
 	u32 reg = readl_relaxed(priv->status);
@@ -167,6 +191,7 @@ static int armada_get_temp(struct thermal_zone_device *thermal,
 	struct armada_thermal_priv *priv = thermal->devdata;
 	u32 reg;
 	unsigned long m, b, div;
+	int sample;
 
 	/* Valid check */
 	if (priv->data->is_valid && !priv->data->is_valid(priv)) {
@@ -177,6 +202,11 @@ static int armada_get_temp(struct thermal_zone_device *thermal,
 
 	reg = readl_relaxed(priv->status);
 	reg = (reg >> priv->data->temp_shift) & priv->data->temp_mask;
+	if (priv->data->signed_sample)
+		/* The most significant bit is the sign bit */
+		sample = sign_extend32(reg, fls(priv->data->temp_mask) - 1);
+	else
+		sample = reg;
 
 	/* Get formula coeficients */
 	b = priv->data->coef_b;
@@ -184,9 +214,9 @@ static int armada_get_temp(struct thermal_zone_device *thermal,
 	div = priv->data->coef_div;
 
 	if (priv->data->inverted)
-		*temp = ((m * reg) - b) / div;
+		*temp = ((m * sample) - b) / div;
 	else
-		*temp = (b - (m * reg)) / div;
+		*temp = (b - (m * sample)) / div;
 	return 0;
 }
 
@@ -237,6 +267,19 @@ static const struct armada_thermal_data armada380_data = {
 	.inverted = true,
 };
 
+static const struct armada_thermal_data armada_ap806_data = {
+	.is_valid = armada_is_valid,
+	.init_sensor = armada_ap806_init_sensor,
+	.is_valid_bit = BIT(16),
+	.temp_shift = 0,
+	.temp_mask = 0x3ff,
+	.coef_b = -150000,
+	.coef_m = 423UL,
+	.coef_div = 1,
+	.inverted = true,
+	.signed_sample = true,
+};
+
 static const struct of_device_id armada_thermal_id_table[] = {
 	{
 		.compatible = "marvell,armadaxp-thermal",
@@ -255,6 +298,10 @@ static const struct of_device_id armada_thermal_id_table[] = {
 		.data       = &armada380_data,
 	},
 	{
+		.compatible = "marvell,armada-ap806-thermal",
+		.data       = &armada_ap806_data,
+	},
+	{
 		/* sentinel */
 	},
 };
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v3 04/11] thermal: armada: Rationalize register accesses
From: Miquel Raynal @ 2017-12-14 10:30 UTC (permalink / raw)
  To: Zhang Rui, Eduardo Valentin, Rob Herring, Mark Rutland,
	Jason Cooper, Andrew Lunn, Gregory Clement, Sebastian Hesselbarth,
	Catalin Marinas, Will Deacon
  Cc: linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Thomas Petazzoni, Antoine Tenart, Nadav Haklai, Miquel Raynal,
	Baruch Siach, David Sniatkiwicz
In-Reply-To: <20171214103011.24713-1-miquel.raynal-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

Bindings were incomplete for a long time by only exposing one of the two
available control registers. To ease the migration to the full bindings
(already in use for the Armada 375 SoC), rename the pointers for
clarification. This way, it will only be needed to add another pointer
to access the other control register when the time comes.

This avoids dangerous situations where the offset 0 of the control
area can be either one register or the other depending on the bindings
used. After this change, device trees of other SoCs could be migrated to
the "full" bindings if they may benefit from features from the
unaccessible register, without any change in the driver.

Signed-off-by: Miquel Raynal <miquel.raynal-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 drivers/thermal/armada_thermal.c | 86 +++++++++++++++++++++++++---------------
 1 file changed, 55 insertions(+), 31 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 26698f2d3ca7..e5b184cee79b 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -39,12 +39,21 @@
 #define A375_HW_RESETn			BIT(8)
 #define A380_HW_RESET			BIT(8)
 
+/* Legacy bindings */
+#define LEGACY_CONTROL_MEM_LEN		0x4
+
+/* Current bindings with the 2 control registers under the same memory area */
+#define LEGACY_CONTROL1_OFFSET		0x0
+#define CONTROL0_OFFSET			0x0
+#define CONTROL1_OFFSET			0x4
+
 struct armada_thermal_data;
 
 /* Marvell EBU Thermal Sensor Dev Structure */
 struct armada_thermal_priv {
-	void __iomem *sensor;
-	void __iomem *control;
+	void __iomem *status;
+	void __iomem *control0;
+	void __iomem *control1;
 	struct armada_thermal_data *data;
 };
 
@@ -71,45 +80,45 @@ struct armada_thermal_data {
 static void armadaxp_init_sensor(struct platform_device *pdev,
 				 struct armada_thermal_priv *priv)
 {
-	unsigned long reg;
+	u32 reg;
 
-	reg = readl_relaxed(priv->control);
+	reg = readl_relaxed(priv->control1);
 	reg |= PMU_TDC0_OTF_CAL_MASK;
-	writel(reg, priv->control);
+	writel(reg, priv->control1);
 
 	/* Reference calibration value */
 	reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
 	reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
-	writel(reg, priv->control);
+	writel(reg, priv->control1);
 
 	/* Reset the sensor */
-	reg = readl_relaxed(priv->control);
-	writel((reg | PMU_TDC0_SW_RST_MASK), priv->control);
+	reg = readl_relaxed(priv->control1);
+	writel((reg | PMU_TDC0_SW_RST_MASK), priv->control1);
 
-	writel(reg, priv->control);
+	writel(reg, priv->control1);
 
 	/* Enable the sensor */
-	reg = readl_relaxed(priv->sensor);
+	reg = readl_relaxed(priv->status);
 	reg &= ~PMU_TM_DISABLE_MASK;
-	writel(reg, priv->sensor);
+	writel(reg, priv->status);
 }
 
 static void armada370_init_sensor(struct platform_device *pdev,
 				  struct armada_thermal_priv *priv)
 {
-	unsigned long reg;
+	u32 reg;
 
-	reg = readl_relaxed(priv->control);
+	reg = readl_relaxed(priv->control1);
 	reg |= PMU_TDC0_OTF_CAL_MASK;
-	writel(reg, priv->control);
+	writel(reg, priv->control1);
 
 	/* Reference calibration value */
 	reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
 	reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
-	writel(reg, priv->control);
+	writel(reg, priv->control1);
 
 	reg &= ~PMU_TDC0_START_CAL_MASK;
-	writel(reg, priv->control);
+	writel(reg, priv->control1);
 
 	msleep(10);
 }
@@ -117,37 +126,37 @@ static void armada370_init_sensor(struct platform_device *pdev,
 static void armada375_init_sensor(struct platform_device *pdev,
 				  struct armada_thermal_priv *priv)
 {
-	unsigned long reg;
+	u32 reg;
 
-	reg = readl(priv->control + 4);
+	reg = readl(priv->control1);
 	reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT);
 	reg &= ~A375_READOUT_INVERT;
 	reg &= ~A375_HW_RESETn;
 
-	writel(reg, priv->control + 4);
+	writel(reg, priv->control1);
 	msleep(20);
 
 	reg |= A375_HW_RESETn;
-	writel(reg, priv->control + 4);
+	writel(reg, priv->control1);
 	msleep(50);
 }
 
 static void armada380_init_sensor(struct platform_device *pdev,
 				  struct armada_thermal_priv *priv)
 {
-	unsigned long reg = readl_relaxed(priv->control);
+	u32 reg = readl_relaxed(priv->control1);
 
 	/* Reset hardware once */
 	if (!(reg & A380_HW_RESET)) {
 		reg |= A380_HW_RESET;
-		writel(reg, priv->control);
+		writel(reg, priv->control1);
 		msleep(10);
 	}
 }
 
 static bool armada_is_valid(struct armada_thermal_priv *priv)
 {
-	unsigned long reg = readl_relaxed(priv->sensor);
+	u32 reg = readl_relaxed(priv->status);
 
 	return reg & priv->data->is_valid_bit;
 }
@@ -156,7 +165,7 @@ static int armada_get_temp(struct thermal_zone_device *thermal,
 			  int *temp)
 {
 	struct armada_thermal_priv *priv = thermal->devdata;
-	unsigned long reg;
+	u32 reg;
 	unsigned long m, b, div;
 
 	/* Valid check */
@@ -166,7 +175,7 @@ static int armada_get_temp(struct thermal_zone_device *thermal,
 		return -EIO;
 	}
 
-	reg = readl_relaxed(priv->sensor);
+	reg = readl_relaxed(priv->status);
 	reg = (reg >> priv->data->temp_shift) & priv->data->temp_mask;
 
 	/* Get formula coeficients */
@@ -253,6 +262,7 @@ MODULE_DEVICE_TABLE(of, armada_thermal_id_table);
 
 static int armada_thermal_probe(struct platform_device *pdev)
 {
+	void __iomem *control = NULL;
 	struct thermal_zone_device *thermal;
 	const struct of_device_id *match;
 	struct armada_thermal_priv *priv;
@@ -267,14 +277,28 @@ static int armada_thermal_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->sensor = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(priv->sensor))
-		return PTR_ERR(priv->sensor);
+	priv->status = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(priv->status))
+		return PTR_ERR(priv->status);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	priv->control = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(priv->control))
-		return PTR_ERR(priv->control);
+	control = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(control))
+		return PTR_ERR(control);
+
+	/*
+	 * Legacy DT bindings only described "control1" register (also referred
+	 * as "control MSB" on old documentation). New bindings cover
+	 * "control0/control LSB" and "control1/control MSB" registers within
+	 * the same resource, which is then of size 8 instead of 4.
+	 */
+	if ((res->end - res->start) == LEGACY_CONTROL_MEM_LEN) {
+		/* ->control0 unavailable in this configuration */
+		priv->control1 = control + LEGACY_CONTROL1_OFFSET;
+	} else {
+		priv->control0 = control + CONTROL0_OFFSET;
+		priv->control1 = control + CONTROL1_OFFSET;
+	}
 
 	priv->data = (struct armada_thermal_data *)match->data;
 	priv->data->init_sensor(pdev, priv);
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v3 03/11] thermal: armada: Simplify the check of the validity bit
From: Miquel Raynal @ 2017-12-14 10:30 UTC (permalink / raw)
  To: Zhang Rui, Eduardo Valentin, Rob Herring, Mark Rutland,
	Jason Cooper, Andrew Lunn, Gregory Clement, Sebastian Hesselbarth,
	Catalin Marinas, Will Deacon
  Cc: linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Thomas Petazzoni, Antoine Tenart, Nadav Haklai, Miquel Raynal,
	Baruch Siach, David Sniatkiwicz
In-Reply-To: <20171214103011.24713-1-miquel.raynal-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

All Armada SoCs use one bit to declare if the sensor values are valid.
This bit moves across the versions of the IP.

The method until then was to do both a shift and compare with an useless
flag of "0x1". It is clearer and quicker to directly save the value that
must be ANDed instead of the bit position and do a single bitwise AND
operation.

Signed-off-by: Miquel Raynal <miquel.raynal-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 drivers/thermal/armada_thermal.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 6c4af2622d4f..26698f2d3ca7 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -24,8 +24,6 @@
 #include <linux/of_device.h>
 #include <linux/thermal.h>
 
-#define THERMAL_VALID_MASK		0x1
-
 /* Thermal Manager Control and Status Register */
 #define PMU_TDC0_SW_RST_MASK		(0x1 << 1)
 #define PMU_TM_DISABLE_OFFS		0
@@ -67,7 +65,7 @@ struct armada_thermal_data {
 	/* Register shift and mask to access the sensor temperature */
 	unsigned int temp_shift;
 	unsigned int temp_mask;
-	unsigned int is_valid_shift;
+	unsigned int is_valid_bit;
 };
 
 static void armadaxp_init_sensor(struct platform_device *pdev,
@@ -151,7 +149,7 @@ static bool armada_is_valid(struct armada_thermal_priv *priv)
 {
 	unsigned long reg = readl_relaxed(priv->sensor);
 
-	return (reg >> priv->data->is_valid_shift) & THERMAL_VALID_MASK;
+	return reg & priv->data->is_valid_bit;
 }
 
 static int armada_get_temp(struct thermal_zone_device *thermal,
@@ -199,7 +197,7 @@ static const struct armada_thermal_data armadaxp_data = {
 static const struct armada_thermal_data armada370_data = {
 	.is_valid = armada_is_valid,
 	.init_sensor = armada370_init_sensor,
-	.is_valid_shift = 9,
+	.is_valid_bit = BIT(9),
 	.temp_shift = 10,
 	.temp_mask = 0x1ff,
 	.coef_b = 3153000000UL,
@@ -210,7 +208,7 @@ static const struct armada_thermal_data armada370_data = {
 static const struct armada_thermal_data armada375_data = {
 	.is_valid = armada_is_valid,
 	.init_sensor = armada375_init_sensor,
-	.is_valid_shift = 10,
+	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
 	.temp_mask = 0x1ff,
 	.coef_b = 3171900000UL,
@@ -221,7 +219,7 @@ static const struct armada_thermal_data armada375_data = {
 static const struct armada_thermal_data armada380_data = {
 	.is_valid = armada_is_valid,
 	.init_sensor = armada380_init_sensor,
-	.is_valid_shift = 10,
+	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
 	.temp_mask = 0x3ff,
 	.coef_b = 1172499100UL,
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v3 02/11] thermal: armada: Use msleep for long delays
From: Miquel Raynal @ 2017-12-14 10:30 UTC (permalink / raw)
  To: Zhang Rui, Eduardo Valentin, Rob Herring, Mark Rutland,
	Jason Cooper, Andrew Lunn, Gregory Clement, Sebastian Hesselbarth,
	Catalin Marinas, Will Deacon
  Cc: linux-pm, devicetree, linux-arm-kernel, Thomas Petazzoni,
	Antoine Tenart, Nadav Haklai, Miquel Raynal, Baruch Siach,
	David Sniatkiwicz
In-Reply-To: <20171214103011.24713-1-miquel.raynal@free-electrons.com>

From: Baruch Siach <baruch@tkos.co.il>

Use msleep for long (> 10ms) delays, instead of the busy waiting mdelay.
All delays are called from the probe routine, where scheduling is
allowed.

Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
---
 drivers/thermal/armada_thermal.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 706d74798cbe..6c4af2622d4f 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -113,7 +113,7 @@ static void armada370_init_sensor(struct platform_device *pdev,
 	reg &= ~PMU_TDC0_START_CAL_MASK;
 	writel(reg, priv->control);
 
-	mdelay(10);
+	msleep(10);
 }
 
 static void armada375_init_sensor(struct platform_device *pdev,
@@ -127,11 +127,11 @@ static void armada375_init_sensor(struct platform_device *pdev,
 	reg &= ~A375_HW_RESETn;
 
 	writel(reg, priv->control + 4);
-	mdelay(20);
+	msleep(20);
 
 	reg |= A375_HW_RESETn;
 	writel(reg, priv->control + 4);
-	mdelay(50);
+	msleep(50);
 }
 
 static void armada380_init_sensor(struct platform_device *pdev,
@@ -143,7 +143,7 @@ static void armada380_init_sensor(struct platform_device *pdev,
 	if (!(reg & A380_HW_RESET)) {
 		reg |= A380_HW_RESET;
 		writel(reg, priv->control);
-		mdelay(10);
+		msleep(10);
 	}
 }
 
-- 
2.11.0

^ permalink raw reply related

* [PATCH v3 01/11] dt-bindings: thermal: Describe Armada AP806 and CP110
From: Miquel Raynal @ 2017-12-14 10:30 UTC (permalink / raw)
  To: Zhang Rui, Eduardo Valentin, Rob Herring, Mark Rutland,
	Jason Cooper, Andrew Lunn, Gregory Clement, Sebastian Hesselbarth,
	Catalin Marinas, Will Deacon
  Cc: linux-pm, devicetree, linux-arm-kernel, Thomas Petazzoni,
	Antoine Tenart, Nadav Haklai, Miquel Raynal, Baruch Siach,
	David Sniatkiwicz
In-Reply-To: <20171214103011.24713-1-miquel.raynal@free-electrons.com>

From: Baruch Siach <baruch@tkos.co.il>

Add compatible strings for AP806 and CP110 that are part of the Armada
8k/7k line of SoCs.

Add a note on the differences in the size of the control area in
different bindings. This is an existing difference between the Armada
375 binding and the other boards already supported. The new AP806 and
CP110 bindings are similar to the existing Armada 375 in this regard.

Also add a note about the new property "marvell,thermal-zone-name" to
help identify the zones from the sysfs.

Signed-off-by: Baruch Siach <baruch@tkos.co.il>
[<miquel.raynal@free-electrons.com>: reword, additional details, new
property]
Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
---
 .../devicetree/bindings/thermal/armada-thermal.txt | 29 ++++++++++++++++++----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/thermal/armada-thermal.txt b/Documentation/devicetree/bindings/thermal/armada-thermal.txt
index 24aacf8948c5..1602dc2ee220 100644
--- a/Documentation/devicetree/bindings/thermal/armada-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/armada-thermal.txt
@@ -7,17 +7,36 @@ Required properties:
 		marvell,armada375-thermal
 		marvell,armada380-thermal
 		marvell,armadaxp-thermal
+		marvell,armada-ap806-thermal
+		marvell,armada-cp110-thermal
 
 - reg:		Device's register space.
 		Two entries are expected, see the examples below.
-		The first one is required for the sensor register;
-		the second one is required for the control register
-		to be used for sensor initialization (a.k.a. calibration).
+		The first one points to the status register (4B).
+		The second one points to the control registers (8B).
+		Note: with legacy bindings, the second entry pointed
+		only on the so called "control MSB" ("control 1"), was
+		4B wide and did not let the possibility to reach the
+		"control LSB" ("control 0") register.
 
-Example:
+Optional properties:
 
+- marvell,thermal-zone-name: The name to identify the thermal zone
+                             within the sysfs, useful when multiple
+                             thermal zones are registered (AP, CPx...).
+
+Examples:
+
+	/* Legacy bindings */
 	thermal@d0018300 {
 		compatible = "marvell,armada370-thermal";
-                reg = <0xd0018300 0x4
+		reg = <0xd0018300 0x4
 		       0xd0018304 0x4>;
 	};
+
+	ap_thermal: thermal@6f8084 {
+		compatible = "marvell,armada-ap806-thermal";
+		reg = <0x6f808C 0x4>,
+		      <0x6f8084 0x8>;
+		marvell,thermal-zone-name = "ap_thermal_zone";
+	};
-- 
2.11.0

^ permalink raw reply related

* [PATCH v3 00/11] Armada thermal: improvements and A7K/A8K SoCs support
From: Miquel Raynal @ 2017-12-14 10:30 UTC (permalink / raw)
  To: Zhang Rui, Eduardo Valentin, Rob Herring, Mark Rutland,
	Jason Cooper, Andrew Lunn, Gregory Clement, Sebastian Hesselbarth,
	Catalin Marinas, Will Deacon
  Cc: linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Thomas Petazzoni, Antoine Tenart, Nadav Haklai, Miquel Raynal,
	Baruch Siach, David Sniatkiwicz

Hi,

This series takes over Baruch's series by integrating his patches about
supporting thermal on Armada 7K and 8K SoCs within a larger series with
several improvements on the armada_thermal.c driver.

For now, Armada 380 and CP110 compatibles share the same initialization
routine but this will probably change in the near future when adding
support for overheat interrupts.

DT bindings documentation is updated to match existing code. A new
property is introduced to identify thermal zones, see the commit using
it for more details.

Armada AP806 and CP110 DT are also updated with thermal nodes.

Thank you,
Miquèl


Baruch Siach (4):
  dt-bindings: thermal: Describe Armada AP806 and CP110
  thermal: armada: Use msleep for long delays
  thermal: armada: Add support for Armada AP806
  thermal: armada: Add support for Armada CP110

Miquel Raynal (7):
  thermal: armada: Simplify the check of the validity bit
  thermal: armada: Rationalize register accesses
  thermal: armada: Update Kconfig and module description
  thermal: armada: Change sensors trim default value
  thermal: armada: Wait sensors validity before exiting the init
    callback
  thermal: armada: Give useful names to the thermal zone
  ARM64: dts: marvell: Add thermal support for A7K/A8K

 .../devicetree/bindings/thermal/armada-thermal.txt |  29 ++-
 arch/arm64/boot/dts/marvell/armada-ap806.dtsi      |   7 +
 .../boot/dts/marvell/armada-cp110-master.dtsi      |   7 +
 .../arm64/boot/dts/marvell/armada-cp110-slave.dtsi |   7 +
 drivers/thermal/Kconfig                            |   4 +-
 drivers/thermal/armada_thermal.c                   | 225 ++++++++++++++++-----
 6 files changed, 222 insertions(+), 57 deletions(-)

-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH V6 3/7] device property: Introduce a common API to fetch device match data
From: Sakari Ailus @ 2017-12-14 10:28 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Sakari Ailus, Sinan Kaya, dmaengine, Timur Tabi,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	ACPI Devel Maling List, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	Greg Kroah-Hartman, Rafael J. Wysocki, Len Brown, Mika Westerberg,
	Dmitry Torokhov, Rob Herring, Kieran Bingham, open list
In-Reply-To: <CAJZ5v0inHMCLGyPaAeuJNo2VH7f3Th0KdpT2UkPBCsvrSDi0gQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Thu, Dec 07, 2017 at 11:19:51PM +0100, Rafael J. Wysocki wrote:
> On Thu, Dec 7, 2017 at 11:06 PM, Sakari Ailus <sakari.ailus-X3B1VOXEql0@public.gmane.org> wrote:
> > On Thu, Dec 07, 2017 at 03:17:52PM -0500, Sinan Kaya wrote:
> >> On 12/7/2017 7:40 AM, Sakari Ailus wrote:
> >> > On Tue, Dec 05, 2017 at 12:04:48PM -0500, Sinan Kaya wrote:
> >> >> @@ -101,6 +103,8 @@ struct fwnode_operations {
> >> >>    (*graph_get_port_parent)(struct fwnode_handle *fwnode);
> >> >>    int (*graph_parse_endpoint)(const struct fwnode_handle *fwnode,
> >> >>                                struct fwnode_endpoint *endpoint);
> >> >> +  void *(*get_match_data)(const struct fwnode_handle *fwnode,
> >> >> +                          struct device *dev);
> >> >
> >> > You can make dev const, too.
> >> >
> >>
> >> done, I couldn't change device_get_match_data() parameter const due to
> >> dev_fwnode() function.
> >>
> >>                  from /local/mnt/workspace/projects/caf/kernel/drivers/base/property.c:13:
> >>
> >> /local/mnt/workspace/projects/caf/kernel/drivers/base/property.c:1341:39: warning: passing argument 1 of 'dev_fwnode' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
> >>   return fwnode_call_ptr_op(dev_fwnode(dev), device_get_match_data,
> >
> > Right. Makes sense.
> >
> > I guess it's not perhaps worth it introducing dev_fwnode_const just for
> > this. devices are seldom if ever const anyway.
> 
> They cannot be const.  Had they been const, it wouldn't have been
> possible to register them even. :-)

In general no, but this function does not change the device in any way,
therefore it could be const in principle.

-- 
Sakari Ailus
sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH 2/2] sfp: add sff module support
From: Russell King @ 2017-12-14 10:27 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, Rob Herring
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Mark Rutland,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20171214102712.GP10595-l+eeeJia6m9URfEZ8mYm6t73F7V6hmMc@public.gmane.org>

Add support for SFF modules, which are soldered down SFP modules.
These have a different phys_id value, and also have the present and
rate select signals omitted compared with their socketed counter-parts.

Signed-off-by: Russell King <rmk+kernel-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org>
---
 drivers/net/phy/sfp.c | 78 ++++++++++++++++++++++++++++++++++++++++++---------
 include/linux/sfp.h   |  1 +
 2 files changed, 65 insertions(+), 14 deletions(-)

diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index 9dfc1c4c954f..96511557eb2c 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -98,12 +98,18 @@ static const enum gpiod_flags gpio_flags[] = {
 
 static DEFINE_MUTEX(sfp_mutex);
 
+struct sff_data {
+	unsigned int gpios;
+	bool (*module_supported)(const struct sfp_eeprom_id *id);
+};
+
 struct sfp {
 	struct device *dev;
 	struct i2c_adapter *i2c;
 	struct mii_bus *i2c_mii;
 	struct sfp_bus *sfp_bus;
 	struct phy_device *mod_phy;
+	const struct sff_data *type;
 
 	unsigned int (*get_state)(struct sfp *);
 	void (*set_state)(struct sfp *, unsigned int);
@@ -123,6 +129,36 @@ struct sfp {
 	struct sfp_eeprom_id id;
 };
 
+static bool sff_module_supported(const struct sfp_eeprom_id *id)
+{
+	return id->base.phys_id == SFP_PHYS_ID_SFF &&
+	       id->base.phys_ext_id == SFP_PHYS_EXT_ID_SFP;
+}
+
+static const struct sff_data sff_data = {
+	.gpios = SFP_F_LOS | SFP_F_TX_FAULT | SFP_F_TX_DISABLE,
+	.module_supported = sff_module_supported,
+};
+
+static bool sfp_module_supported(const struct sfp_eeprom_id *id)
+{
+	return id->base.phys_id == SFP_PHYS_ID_SFP &&
+	       id->base.phys_ext_id == SFP_PHYS_EXT_ID_SFP;
+}
+
+static const struct sff_data sfp_data = {
+	.gpios = SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT |
+		 SFP_F_TX_DISABLE | SFP_F_RATE_SELECT,
+	.module_supported = sfp_module_supported,
+};
+
+static const struct of_device_id sfp_of_match[] = {
+	{ .compatible = "sff,sff", .data = &sff_data, },
+	{ .compatible = "sff,sfp", .data = &sfp_data, },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, sfp_of_match);
+
 static unsigned long poll_jiffies;
 
 static unsigned int sfp_gpio_get_state(struct sfp *sfp)
@@ -141,6 +177,11 @@ static unsigned int sfp_gpio_get_state(struct sfp *sfp)
 	return state;
 }
 
+static unsigned int sff_gpio_get_state(struct sfp *sfp)
+{
+	return sfp_gpio_get_state(sfp) | SFP_F_PRESENT;
+}
+
 static void sfp_gpio_set_state(struct sfp *sfp, unsigned int state)
 {
 	if (state & SFP_F_PRESENT) {
@@ -479,10 +520,10 @@ static int sfp_sm_mod_probe(struct sfp *sfp)
 	dev_info(sfp->dev, "module %s %s rev %s sn %s dc %s\n",
 		 vendor, part, rev, sn, date);
 
-	/* We only support SFP modules, not the legacy GBIC modules. */
-	if (sfp->id.base.phys_id != SFP_PHYS_ID_SFP ||
-	    sfp->id.base.phys_ext_id != SFP_PHYS_EXT_ID_SFP) {
-		dev_err(sfp->dev, "module is not SFP - phys id 0x%02x 0x%02x\n",
+	/* Check whether we support this module */
+	if (!sfp->type->module_supported(&sfp->id)) {
+		dev_err(sfp->dev,
+			"module is not supported - phys id 0x%02x 0x%02x\n",
 			sfp->id.base.phys_id, sfp->id.base.phys_ext_id);
 		return -EINVAL;
 	}
@@ -801,6 +842,7 @@ static void sfp_cleanup(void *data)
 
 static int sfp_probe(struct platform_device *pdev)
 {
+	const struct sff_data *sff;
 	struct sfp *sfp;
 	bool poll = false;
 	int irq, err, i;
@@ -815,10 +857,19 @@ static int sfp_probe(struct platform_device *pdev)
 	if (err < 0)
 		return err;
 
+	sff = sfp->type = &sfp_data;
+
 	if (pdev->dev.of_node) {
 		struct device_node *node = pdev->dev.of_node;
+		const struct of_device_id *id;
 		struct device_node *np;
 
+		id = of_match_node(sfp_of_match, node);
+		if (WARN_ON(!id))
+			return -EINVAL;
+
+		sff = sfp->type = id->data;
+
 		np = of_parse_phandle(node, "i2c-bus", 0);
 		if (np) {
 			struct i2c_adapter *i2c;
@@ -834,17 +885,22 @@ static int sfp_probe(struct platform_device *pdev)
 				return err;
 			}
 		}
+	}
 
-		for (i = 0; i < GPIO_MAX; i++) {
+	for (i = 0; i < GPIO_MAX; i++)
+		if (sff->gpios & BIT(i)) {
 			sfp->gpio[i] = devm_gpiod_get_optional(sfp->dev,
 					   gpio_of_names[i], gpio_flags[i]);
 			if (IS_ERR(sfp->gpio[i]))
 				return PTR_ERR(sfp->gpio[i]);
 		}
 
-		sfp->get_state = sfp_gpio_get_state;
-		sfp->set_state = sfp_gpio_set_state;
-	}
+	sfp->get_state = sfp_gpio_get_state;
+	sfp->set_state = sfp_gpio_set_state;
+
+	/* Modules that have no detect signal are always present */
+	if (!(sfp->gpio[GPIO_MODDEF0]))
+		sfp->get_state = sff_gpio_get_state;
 
 	sfp->sfp_bus = sfp_register_socket(sfp->dev, sfp, &sfp_module_ops);
 	if (!sfp->sfp_bus)
@@ -899,12 +955,6 @@ static int sfp_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static const struct of_device_id sfp_of_match[] = {
-	{ .compatible = "sff,sfp", },
-	{ },
-};
-MODULE_DEVICE_TABLE(of, sfp_of_match);
-
 static struct platform_driver sfp_driver = {
 	.probe = sfp_probe,
 	.remove = sfp_remove,
diff --git a/include/linux/sfp.h b/include/linux/sfp.h
index 47ea32d3e816..0c5c5f6ae1ec 100644
--- a/include/linux/sfp.h
+++ b/include/linux/sfp.h
@@ -231,6 +231,7 @@ enum {
 	SFP_SFF8472_COMPLIANCE		= 0x5e,
 	SFP_CC_EXT			= 0x5f,
 
+	SFP_PHYS_ID_SFF			= 0x02,
 	SFP_PHYS_ID_SFP			= 0x03,
 	SFP_PHYS_EXT_ID_SFP		= 0x04,
 	SFP_CONNECTOR_UNSPEC		= 0x00,
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH 1/2] dt-bindings: add sff,sff binding for SFP support
From: Russell King @ 2017-12-14 10:27 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, Rob Herring
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Mark Rutland,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20171214102712.GP10595-l+eeeJia6m9URfEZ8mYm6t73F7V6hmMc@public.gmane.org>

Add "sff,sff" for SFF module support with SFP.  These have a different
phys_id value, and also have the present and rate select signals omitted
compared with their socketed counter-parts.

Signed-off-by: Russell King <rmk+kernel-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org>
---
 Documentation/devicetree/bindings/net/sff,sfp.txt | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/sff,sfp.txt b/Documentation/devicetree/bindings/net/sff,sfp.txt
index 60e970ce10ee..f1c441bedf68 100644
--- a/Documentation/devicetree/bindings/net/sff,sfp.txt
+++ b/Documentation/devicetree/bindings/net/sff,sfp.txt
@@ -3,7 +3,9 @@ Transceiver
 
 Required properties:
 
-- compatible : must be "sff,sfp"
+- compatible : must be one of
+  "sff,sfp" for SFP modules
+  "sff,sff" for soldered down SFF modules
 
 Optional Properties:
 
@@ -11,7 +13,8 @@ Transceiver
   interface
 
 - mod-def0-gpios : GPIO phandle and a specifier of the MOD-DEF0 (AKA Mod_ABS)
-  module presence input gpio signal, active (module absent) high
+  module presence input gpio signal, active (module absent) high. Must
+  not be present for SFF modules
 
 - los-gpios : GPIO phandle and a specifier of the Receiver Loss of Signal
   Indication input gpio signal, active (signal lost) high
@@ -24,10 +27,11 @@ Transceiver
 
 - rate-select0-gpios : GPIO phandle and a specifier of the Rx Signaling Rate
   Select (AKA RS0) output gpio signal, low: low Rx rate, high: high Rx rate
+  Must not be present for SFF modules
 
 - rate-select1-gpios : GPIO phandle and a specifier of the Tx Signaling Rate
   Select (AKA RS1) output gpio signal (SFP+ only), low: low Tx rate, high:
-  high Tx rate
+  high Tx rate. Must not be present for SFF modules
 
 Example #1: Direct serdes to SFP connection
 
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH 0/2] Add SFF module support
From: Russell King - ARM Linux @ 2017-12-14 10:27 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, Rob Herring
  Cc: devicetree, Mark Rutland, netdev

Add support for SFF modules.  SFF modules are similar to SFP modules,
but they have fewer control signals, and are soldered down rather than
pluggable.

They also have different IDs in the EEPROM to identify as soldered down
SFF modules.

 Documentation/devicetree/bindings/net/sff,sfp.txt | 10 ++-
 drivers/net/phy/sfp.c                             | 78 +++++++++++++++++++----
 include/linux/sfp.h                               |  1 +
 3 files changed, 72 insertions(+), 17 deletions(-)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up

^ permalink raw reply

* Re: [PATCH 3/3] ARM: dts: r8a7793: Correct critical CPU temperature
From: Geert Uytterhoeven @ 2017-12-14 10:25 UTC (permalink / raw)
  To: Chris Paterson
  Cc: Kuninori Morimoto, Rob Herring, Mark Rutland, Simon Horman,
	Magnus Damm, Russell King, devicetree, Linux-Renesas,
	linux-arm-kernel
In-Reply-To: <1513242521-11236-4-git-send-email-chris.paterson2@renesas.com>

On Thu, Dec 14, 2017 at 10:08 AM, Chris Paterson
<chris.paterson2@renesas.com> wrote:
> The R-Car M2N hardware manual states that Tc = –40°C to +105°C. The

M2-N

> thermal sensor has an accuracy of ±5°C and there can be a temperature
> difference of 1 or 2 degrees between Tjmax and the thermal sensor due
> to the location of the latter.
>
> This means that 95°C is a safer value to use.
>
> Fixes: 57f9156bc620ac56 ("ARM: dts: r8a7793: enable to use thermal-zone")
> Signed-off-by: Chris Paterson <chris.paterson2@renesas.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH 2/3] ARM: dts: r8a7791: Correct critical CPU temperature
From: Geert Uytterhoeven @ 2017-12-14 10:24 UTC (permalink / raw)
  To: Chris Paterson
  Cc: Kuninori Morimoto, Rob Herring, Mark Rutland, Simon Horman,
	Magnus Damm, Russell King, devicetree, Linux-Renesas,
	linux-arm-kernel
In-Reply-To: <1513242521-11236-3-git-send-email-chris.paterson2@renesas.com>

On Thu, Dec 14, 2017 at 10:08 AM, Chris Paterson
<chris.paterson2@renesas.com> wrote:
> The R-Car M2W hardware manual states that Tc = –40°C to +105°C. The

M2-W

> thermal sensor has an accuracy of ±5°C and there can be a temperature
> difference of 1 or 2 degrees between Tjmax and the thermal sensor due
> to the location of the latter.
>
> This means that 95°C is a safer value to use.
>
> Fixes: cac68a56e34b9810 ("ARM: dts: r8a7791: enable to use thermal-zone")
> Signed-off-by: Chris Paterson <chris.paterson2@renesas.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH 1/3] ARM: dts: r8a7790: Correct critical CPU temperature
From: Geert Uytterhoeven @ 2017-12-14 10:23 UTC (permalink / raw)
  To: Chris Paterson
  Cc: Kuninori Morimoto, Rob Herring, Mark Rutland, Simon Horman,
	Magnus Damm, Russell King, devicetree, Linux-Renesas,
	linux-arm-kernel
In-Reply-To: <1513242521-11236-2-git-send-email-chris.paterson2@renesas.com>

On Thu, Dec 14, 2017 at 10:08 AM, Chris Paterson
<chris.paterson2@renesas.com> wrote:
> The R-Car H2 hardware manual states that Tc = –40°C to +105°C. The
> thermal sensor has an accuracy of ±5°C and there can be a temperature
> difference of 1 or 2 degrees between Tjmax and the thermal sensor due
> to the location of the latter.
>
> This means that 95°C is a safer value to use.
>
> Fixes: a8b805f3606f7af7 ("ARM: dts: r8a7790: enable to use thermal-zone")
> Signed-off-by: Chris Paterson <chris.paterson2@renesas.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH 3/5] media: i2c: Add TDA1997x HDMI receiver driver
From: Hans Verkuil @ 2017-12-14 10:11 UTC (permalink / raw)
  To: Tim Harvey
  Cc: Rob Herring, linux-media, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Shawn Guo,
	Steve Longerbeam, Philipp Zabel, Hans Verkuil,
	Mauro Carvalho Chehab
In-Reply-To: <CAJ+vNU1MBqK2ZkDhu7HM-EfNmgceXtah9srygzKuW-ajq9nhtA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On 14/12/17 00:33, Tim Harvey wrote:
> On Tue, Dec 12, 2017 at 4:18 AM, Hans Verkuil <hverkuil-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org> wrote:
>> Hi Tim,
>>
>> Sorry for the delay, I needed to find some time to think about this.
>>
>> On 11/16/17 05:30, Rob Herring wrote:
>>> On Wed, Nov 15, 2017 at 10:31:14AM -0800, Tim Harvey wrote:
>>>> On Wed, Nov 15, 2017 at 7:52 AM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>>>>> On Thu, Nov 09, 2017 at 10:45:34AM -0800, Tim Harvey wrote:
>>>>>> Add support for the TDA1997x HDMI receivers.
>>>>>>
>>>>>> Cc: Hans Verkuil <hverkuil-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org>
>>>>>> Signed-off-by: Tim Harvey <tharvey-UMMOYl/HMS+akBO8gow8eQ@public.gmane.org>
>>>>>> ---
>>>>>> v3:
>>>>>>  - use V4L2_DV_BT_FRAME_WIDTH/HEIGHT macros
>>>>>>  - fixed missing break
>>>>>>  - use only hdmi_infoframe_log for infoframe logging
>>>>>>  - simplify tda1997x_s_stream error handling
>>>>>>  - add delayed work proc to handle hotplug enable/disable
>>>>>>  - fix set_edid (disable HPD before writing, enable after)
>>>>>>  - remove enabling edid by default
>>>>>>  - initialize timings
>>>>>>  - take quant range into account in colorspace conversion
>>>>>>  - remove vendor/product tracking (we provide this in log_status via infoframes)
>>>>>>  - add v4l_controls
>>>>>>  - add more detail to log_status
>>>>>>  - calculate vhref generator timings
>>>>>>  - timing detection fixes (rounding errors, hswidth errors)
>>>>>>  - rename configure_input/configure_conv functions
>>>>>>
>>>>>> v2:
>>>>>>  - implement dv timings enum/cap
>>>>>>  - remove deprecated g_mbus_config op
>>>>>>  - fix dv_query_timings
>>>>>>  - add EDID get/set handling
>>>>>>  - remove max-pixel-rate support
>>>>>>  - add audio codec DAI support
>>>>>>  - change audio bindings
>>>>>> ---
>>>>>>  drivers/media/i2c/Kconfig            |    9 +
>>>>>>  drivers/media/i2c/Makefile           |    1 +
>>>>>>  drivers/media/i2c/tda1997x.c         | 3485 ++++++++++++++++++++++++++++++++++
>>>>>>  include/dt-bindings/media/tda1997x.h |   78 +
>>>>>
>>>>> This belongs with the binding documentation patch.
>>>>>
>>>>
>>>> Rob,
>>>>
>>>> Thanks - missed that. I will move it for v4.
>>>>
>>>> Regarding your previous comment to the v2 series:
>>>>> The rest of the binding looks fine, but I have some reservations about
>>>>> this. I think this should be common probably. There's been a few
>>>>> bindings for display recently that deal with the interface format. Maybe
>>>>> some vendor property is needed here to map a standard interface format
>>>>> back to pin configuration.
>>>>
>>>> I take it this is not an 'Ack' for the bindings?
>>>>
>>>> Which did you feel should be made common? I admit I was surprised
>>>> there wasn't a common binding for audio bus format (i2s|spdif) but if
>>>> you were referring to the video data that would probably be much more
>>>> complicated.
>>>
>>> The video data. Either you have to try to come up with some way to map
>>> color components to signals/pins (and even cycles) or you just enumerate
>>> the formats and keep adding to them when new ones appear. There's h/w
>>> that allows the former, but in the end you have to interoperate, so
>>> enumerating the formats is probably enough.
>>>
>>>> I was hoping one of the media/driver maintainers would respond to your
>>>> comment with thoughts as I'm not familiar with a very wide variety of
>>>> receivers.
>>>
>>> I am hoping, too.
>>
>> I don't think it is right to store this in the DT. How you map the output pins
>> is a driver thing. So when you are requested to enumerate the mediabus formats
>> (include/uapi/linux/media-bus-format.h) you support, you do so based on the
>> capabilities of the hardware, and when a format is requested you program the
>> hardware accordingly.
>>
>> The device tree should describe the physical characteristics like the number
>> of pins that are hooked up (i.e. are there 24, 30 or 36 pins connected).
>>
>> These vidout-portcfg mappings do not appear to describe physical properties
>> but really register settings.
> 
> Hans,
> 
> They are register settings that define which bits on the internal data
> bus are mapped to which pins on the package. Internally these parts
> have a 36bit video data bus but externally the tda19971 only has 24
> pins and even then perhaps only 8 are hooked up if using BT656 and the
> registers also define 'which 8' as it could have been connected to the
> upper or lower part of the bus. So while the bindings from
> video-interfaces.txt provide bus-width and details of the sync
> signals, additional hardware-specific interconnect details such as how
> the video bits are shifted/mixed on the output bus are needed here.
> This is why I feel vidout-portcfg should be a dt property vs something
> like a module param.

The video-interfaces.txt bindings text defines bus-width and data-shift.
The last one would define 'which 8'.

Only if the hardware can do weird stuff like using pins 4-7 and 16-19 would
this be insufficient. But in that case we would need something more detailed
in video-interfaces.txt.

Frankly, unless you've seen anyone do something weird like that I would stick
to bus-width and data-shift.

Regards,

	Hans
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v7 0/6] add clk controller driver for Meson-AXG SoC
From: Yixun Lan @ 2017-12-14 10:11 UTC (permalink / raw)
  To: Jerome Brunet, Neil Armstrong, Kevin Hilman
  Cc: yixun.lan, Rob Herring, Mark Rutland, Michael Turquette,
	Stephen Boyd, Carlo Caione, Qiufang Dai, Jian Hu, linux-amlogic,
	devicetree, linux-clk, linux-arm-kernel, linux-kernel
In-Reply-To: <1513245826.32163.7.camel@baylibre.com>

Hi Jerome & Kevin

On 12/14/17 18:03, Jerome Brunet wrote:
> On Mon, 2017-12-11 at 22:13 +0800, Yixun Lan wrote:
>> Qiufang Dai (3):
>>   clk: meson-axg: add clocks dt-bindings required header
>>   clk: meson-axg: add clock controller drivers
>>   arm64: dts: meson-axg: add clock DT info for Meson AXG SoC
>>
>> Yixun Lan (3):
>>   clk: meson: make the spinlock naming more specific
>>   dt-bindings: clock: add compatible variant for the Meson-AXG
>>   arm64: dts: meson-axg: switch uart_ao clock to CLK81
>>
>>  .../bindings/clock/amlogic,gxbb-clkc.txt           |   7 +-
>>  arch/arm64/Kconfig.platforms                       |   1 +
>>  arch/arm64/boot/dts/amlogic/meson-axg-s400.dts     |   2 +
>>  arch/arm64/boot/dts/amlogic/meson-axg.dtsi         |  19 +-
>>  drivers/clk/meson/Kconfig                          |   8 +
>>  drivers/clk/meson/Makefile                         |   1 +
>>  drivers/clk/meson/axg.c                            | 936 +++++++++++++++++++++
>>  drivers/clk/meson/axg.h                            | 126 +++
>>  drivers/clk/meson/clkc.h                           |   2 +-
>>  drivers/clk/meson/gxbb.c                           | 112 +--
>>  drivers/clk/meson/meson8b.c                        |  24 +-
>>  include/dt-bindings/clock/axg-clkc.h               |  71 ++
>>  12 files changed, 1234 insertions(+), 75 deletions(-)
>>  create mode 100644 drivers/clk/meson/axg.c
>>  create mode 100644 drivers/clk/meson/axg.h
>>  create mode 100644 include/dt-bindings/clock/axg-clkc.h
> 
> Kevin, 
> 
> I took the first 4 patches through clk-meson. I left the last 2 for you.
> 
> I have applied the DT bindings update separately.
> Let me know if you have dependency on these new bindings and need a tag.
> 

thanks for taking care of this..

I think it's a good idea to make a tag, if peripheral driver request
clock, then the DT part patch will need
include/dt-bindings/clock/axg-clkc.h to build successfully.

Yixun


^ permalink raw reply

* Re: [PATCH] PCI: qcom: add missing supplies required for msm8996
From: Stanimir Varbanov @ 2017-12-14 10:06 UTC (permalink / raw)
  To: srinivas.kandagatla, stanimir.varbanov, linux-pci, bhelgaas
  Cc: linux-arm-msm, linux-kernel, robh+dt, devicetree, Bjorn Helgaas
In-Reply-To: <20171208092053.4417-1-srinivas.kandagatla@linaro.org>

Hi Srini,

On 12/08/2017 11:20 AM, srinivas.kandagatla@linaro.org wrote:
> From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> 
> This patch adds supplies that are required for msm8996. Two of them vdda
> and vdda-1p8 are analog supplies that go in to controller, and the rest

According to the msm8996 device specification there are two pins related
to the PCIe power: VDD_PCIE_CORE (power for PCIe core circuitry) and
VDD_PCIE_1P8 (power for PCIe I/O circuitry). Thus I think it is clear
that VDD_PCIE_CORE is vdda and VDD_PCIE_1P8 should be part of PCIe phy
driver DT binding (and this is the case currently [1]). So I don't think
we need vdda-1p8 regulator DT binding for that in pcie-qcom.

> of the two vddpe's are supplies to PCIe endpoints.

For this part I'm still not sure. On first sight it looks that these
vdd's should be part of endpoint drivers, on the other hand we have
mPCIe connector (on db820c) which has two power rails 3p3v and 1p5v
which should be controlled/enabled as well.

So I'd like to hear more opinions on that, i.e. how this is solved by
the other PCIe bridge drivers.

> 
> Without these supplies PCIe endpoints which require power supplies are
> not enumerated at all, as there is no one to power it up.
> 
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> ---
>  .../devicetree/bindings/pci/qcom,pcie.txt          | 16 +++++++++++++
>  drivers/pci/dwc/pcie-qcom.c                        | 28 ++++++++++++++++++++--
>  2 files changed, 42 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.txt b/Documentation/devicetree/bindings/pci/qcom,pcie.txt
> index 3c9d321b3d3b..045102cb3e12 100644
> --- a/Documentation/devicetree/bindings/pci/qcom,pcie.txt
> +++ b/Documentation/devicetree/bindings/pci/qcom,pcie.txt
> @@ -179,6 +179,11 @@
>  	Value type: <phandle>
>  	Definition: A phandle to the core analog power supply
>  
> +- vdda-1p8-supply:
> +	Usage: required for msm8996
> +	Value type: <phandle>
> +	Definition: A phandle to the 1.8v analog power supply
> +
>  - vdda_phy-supply:
>  	Usage: required for ipq/apq8064
>  	Value type: <phandle>
> @@ -189,6 +194,15 @@
>  	Value type: <phandle>
>  	Definition: A phandle to the analog power supply for IC which generates
>  		    reference clock
> +- vddpe-supply:
> +	Usage: optional
> +	Value type: <phandle>
> +	Definition: A phandle to the PCIe endpoint power supply
> +
> +- vddpe1-supply:
> +	Usage: optional
> +	Value type: <phandle>
> +	Definition: A phandle to the PCIe endpoint power supply 1
>  
>  - phys:
>  	Usage: required for apq8084
> @@ -205,6 +219,8 @@
>  	Value type: <prop-encoded-array>
>  	Definition: List of phandle and GPIO specifier pairs. Should contain
>  			- "perst-gpios"	PCIe endpoint reset signal line
> +			- "pe_en-gpios"	PCIe endpoint enable signal line
> +			- "pe_en1-gpios" PCIe endpoint enable1 signal line

those two shouldn't be here, instead they should be part of regulator DT
node, so please drop them.

>  			- "wake-gpios"	PCIe endpoint wake signal line
>  
>  * Example for ipq/apq8064
> diff --git a/drivers/pci/dwc/pcie-qcom.c b/drivers/pci/dwc/pcie-qcom.c
> index 952a4fc4bf3c..01488f90da31 100644
> --- a/drivers/pci/dwc/pcie-qcom.c
> +++ b/drivers/pci/dwc/pcie-qcom.c
> @@ -109,13 +109,15 @@ struct qcom_pcie_resources_1_0_0 {
>  	struct reset_control *core;
>  	struct regulator *vdda;
>  };
> -
> +#define QCOM_PCIE_MAX_SUPPLY	4
>  struct qcom_pcie_resources_2_3_2 {
>  	struct clk *aux_clk;
>  	struct clk *master_clk;
>  	struct clk *slave_clk;
>  	struct clk *cfg_clk;
>  	struct clk *pipe_clk;
> +	int num_supplies;
> +	struct regulator_bulk_data supplies[QCOM_PCIE_MAX_SUPPLY];
>  };
>  
>  struct qcom_pcie_resources_2_4_0 {
> @@ -529,6 +531,17 @@ static int qcom_pcie_get_resources_2_3_2(struct qcom_pcie *pcie)
>  	struct qcom_pcie_resources_2_3_2 *res = &pcie->res.v2_3_2;
>  	struct dw_pcie *pci = pcie->pci;
>  	struct device *dev = pci->dev;
> +	int ret;
> +
> +	res->supplies[0].supply = "vdda";
> +	res->supplies[1].supply = "vdda-1p8";
> +	res->supplies[2].supply = "vddpe";
> +	res->supplies[3].supply = "vddpe1";
> +	res->num_supplies = QCOM_PCIE_MAX_SUPPLY;
> +	ret = devm_regulator_bulk_get(dev, QCOM_PCIE_MAX_SUPPLY,
> +				      res->supplies);

If we decide to go on this direction we need to replace this with
devm_regulator_bulk_get_optional (yes I know there is no such regulator
API yet) because they are optional in the DT binding.

<snip>

-- 
regards,
Stan

[1]
https://elixir.free-electrons.com/linux/latest/source/arch/arm64/boot/dts/qcom/msm8996.dtsi#L638

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox