Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] arm64: Neaten show_regs, remove KERN_CONT
From: Mark Rutland @ 2016-10-24 11:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4cbf196b83cd9d175634e7056744dc649ae87f63.1477253239.git.joe@perches.com>

On Sun, Oct 23, 2016 at 01:40:49PM -0700, Joe Perches wrote:
> commit db4b0710fae9 ("arm64: fix show_regs fallout from KERN_CONT changes")
> corrected the KERN_CONT fallout from commit 4bcc595ccd80
> ("printk: reinstate KERN_CONT for printing continuation lines"), but
> the code still has unnecessary KERN_CONT uses.  Remove them.

Why are these unnecessary KERN_CONTs a larger problem than duplicating
the format string for a third time? Having to duplicate it at all was
annoying enough.

Overall, to avoid messing with the KERN_CONT mess it'd be nicer to
format this all into a buffer (with the format string only existing the
once) and subsequently print it with one printk call.

> Miscellanea:
> 
> o Remove unnecessary trailing blank from the output too.
> 
> Signed-off-by: Joe Perches <joe@perches.com>
> ---
>  arch/arm64/kernel/process.c | 18 ++++++++----------
>  1 file changed, 8 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 01753cd7d3f0..2278e7197a8e 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -190,18 +190,16 @@ void __show_regs(struct pt_regs *regs)
>  
>  	i = top_reg;
>  
> -	while (i >= 0) {
> -		printk("x%-2d: %016llx ", i, regs->regs[i]);
> +	if (i >= 0 && !(i % 2)) {

This is difficult to read. Given we know that in either case i >= 0, and
to retain the style of existing code, this would be better as:

	if (i % 2 == 0) {

> +		printk("x%-2d: %016llx\n", i, regs->regs[i]);
>  		i--;
> -
> -		if (i % 2 == 0) {
> -			pr_cont("x%-2d: %016llx ", i, regs->regs[i]);
> -			i--;
> -		}
> -
> -		pr_cont("\n");
>  	}
> -	printk("\n");

This should be retained. It's meant to be there *in addition* to the
newline on the final reg line.

> +	while (i > 0) {
> +		printk("x%-2d: %016llx x%-2d: %016llx\n",
> +		       i, regs->regs[i],
> +		       i - 1, regs->regs[i - 1]);
> +		i -= 2;
> +	}
>  }

Thanks,
Mark.

^ permalink raw reply

* [PATCH] kernel: irq: fix build failure
From: Stephen Rothwell @ 2016-10-24 11:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161024102215.GN14477@dell>

Hi Lee,

On Mon, 24 Oct 2016 11:22:15 +0100 Lee Jones <lee.jones@linaro.org> wrote:
>
> On Fri, 21 Oct 2016, Thomas Gleixner wrote:
> 
> > On Fri, 21 Oct 2016, Stephen Rothwell wrote:  
> > > On Thu, 20 Oct 2016 14:55:45 +0200 (CEST) Thomas Gleixner <tglx@linutronix.de> wrote:  
> > > > I know. This is under discussion with the driver folks as we are not going
> > > > to blindly export stuff just because someone slapped a irq_set_parent()
> > > > into the code w/o knowing why.  
> > > 
> > > Do we have any idea if a resolution is close.  This was first reported
> > > in linux-next in September 14/15.  :-(  
> > 
> > Grr. Yes. As much as I hate it, I'll go and export it for now. Should be
> > able to get it into rc2.  
> 
> Did this get in?  I still have people complaining about it.

It is in -rc2.  Commit 3118dac501bc.

-- 
Cheers,
Stephen Rothwell

^ permalink raw reply

* [PATCH v2] ARM: dts: imx6sx: Add UDOO Neo support
From: Shawn Guo @ 2016-10-24 11:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476629064-10634-1-git-send-email-afaerber@suse.de>

On Sun, Oct 16, 2016 at 04:44:23PM +0200, Andreas F?rber wrote:
> Add initial device trees for UDOO Neo Basic, Extended and Full boards:
> * Serial console is enabled, other serial ports are prepared.
> * I2C based PMIC is enabled.
> * Ethernet is enabled for Basic and Full.
> * SDHC is enabled, with the SDIO_PWR GPIO modeled as a regulator.
> * Both user LEDs are enabled, with the orange one reserved for the M4
>   and with the SD card as default trigger for the red LED.
> 
> The decision on a board compatible string is deferred to later.
> 
> Cc: Ettore Chimenti <ettore.chimenti@udoo.org>
> Signed-off-by: Andreas F?rber <afaerber@suse.de>

<snip>

> +/ {
> +	compatible = "fsl,imx6sx";
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +
> +		red {
> +			label = "udoo-neo:red:mmc";
> +			gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>;
> +			default-state = "off";
> +			linux,default-trigger = "mmc0";
> +		};
> +
> +		orange {
> +			label = "udoo-neo:orange:user";
> +			gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>;
> +			default-state = "keep";
> +		};
> +	};
> +
> +	sdio_pwr_reg: sd-gpio-regulator {

We do have a recommended naming schema for fixed regulator.  I updated
it a bit as below, and applied the patch.

Shawn

> +		compatible = "regulator-fixed";
> +		gpio = <&gpio6 1 GPIO_ACTIVE_HIGH>;
> +		enable-active-high;
> +		regulator-name = "SDIO_PWR";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		regulator-boot-on;
> +	};
> +};

diff --git a/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi b/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
index 314d25b15641..2b65d26f4396 100644
--- a/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
+++ b/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
@@ -66,7 +66,7 @@
                };
        };
 
-       sdio_pwr_reg: sd-gpio-regulator {
+       reg_sdio_pwr: regulator-sdio-pwr {
                compatible = "regulator-fixed";
                gpio = <&gpio6 1 GPIO_ACTIVE_HIGH>;
                enable-active-high;
@@ -283,7 +283,7 @@
 &usdhc2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc2>;
-       vmmc-supply = <&sdio_pwr_reg>;
+       vmmc-supply = <&reg_sdio_pwr>;
        bus-width = <4>;
        cd-gpios = <&gpio6 2 GPIO_ACTIVE_LOW>;
        no-1-8-v;

^ permalink raw reply related

* [PATCH 2/3] arm64: arch_timer: Work around QorIQ Erratum Hisilicon-161x01
From: Ding Tianhong @ 2016-10-24 11:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <ae996e5d-a27d-52eb-8969-3113ec553a1b@arm.com>

See below comments.

On 2016/10/24 18:13, Marc Zyngier wrote:
> On 23/10/16 04:21, Ding Tianhong wrote:
>> Erratum Hisilicon-161x01 says that the ARM generic timer counter "has the
>> potential to contain an erroneous value when the timer value changes".
>> Accesses to TVAL (both read and write) are also affected due to the implicit counter
>> read.  Accesses to CVAL are not affected.
>>
>> The workaround is to reread TVAL and count registers until successive
>> reads return the limited range value (32) by back-to-back reads.  Writes to TVAL are
>> replaced with an equivalent write to CVAL.
>>
>> The workaround is enabled if the hisilicon,erratum-161x01 property is found in
>> the timer node in the device tree.  This can be overridden with the
>> clocksource.arm_arch_timer.hisilicon-161x01 boot parameter, which allows KVM
>> users to enable the workaround until a mechanism is implemented to
>> automatically communicate this information.
>>
>> Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
>> ---
>>  Documentation/arm64/silicon-errata.txt |   1 +
>>  Documentation/kernel-parameters.txt    |   9 ++
>>  arch/arm64/include/asm/arch_timer.h    |  41 +++++++--
>>  drivers/clocksource/Kconfig            |  14 ++-
>>  drivers/clocksource/arm_arch_timer.c   | 153 +++++++++++++++++++++++++++------
>>  5 files changed, 182 insertions(+), 36 deletions(-)
>>
>> diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
>> index 405da11..3a79803 100644
>> --- a/Documentation/arm64/silicon-errata.txt
>> +++ b/Documentation/arm64/silicon-errata.txt
>> @@ -63,3 +63,4 @@ stable kernels.
>>  | Cavium         | ThunderX SMMUv2 | #27704          | N/A		       |
>>  |                |                 |                 |                         |
>>  | Freescale/NXP  | LS2080A/LS1043A | A-008585        | FSL_ERRATUM_A008585     |
>> +| Hisilicon	 | Hip05/Hip06/Hip07 | #161x01	     | HISILICON_ERRATUM_161x01|
> 
> Please keep the columns aligned. If the affected component doesn't fit
> in the allocated space, use multiple lines, or write it in a condensed
> way (Hip0{5,6,7} for example). Also, please use spaces instead of tabs
> to match the rest of the file.
> 

Miss this, Sorry.

>> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
>> index 6fa1d8a..175f349 100644
>> --- a/Documentation/kernel-parameters.txt
>> +++ b/Documentation/kernel-parameters.txt
>> @@ -707,6 +707,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
>>  			erratum.  If unspecified, the workaround is
>>  			enabled based on the device tree.
>>
>> +	clocksource.arm_arch_timer.hisilicon-161x01=
>> +			[ARM64]
>> +			Format: <bool>
>> +			Enable/disable the workaround of Hisilicon
>> +			erratum 161x01.  This can be useful for KVM
>> +			guests, if the guest device tree doesn't show the
>> +			erratum.  If unspecified, the workaround is
>> +			enabled based on the device tree.
>> +
>>  	clearcpuid=BITNUM [X86]
>>  			Disable CPUID feature X for the kernel. See
>>  			arch/x86/include/asm/cpufeatures.h for the valid bit
>> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
>> index eaa5bbe..6b510db 100644
>> --- a/arch/arm64/include/asm/arch_timer.h
>> +++ b/arch/arm64/include/asm/arch_timer.h
>> @@ -29,17 +29,24 @@
>>
>>  #include <clocksource/arm_arch_timer.h>
>>
>> -#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585)
>> +#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161X01)
>>  extern struct static_key_false arch_timer_read_ool_enabled;
>> -#define needs_fsl_a008585_workaround() \
>> +extern struct arch_timer_erratum_workaround *erratum_workaround;
>> +#define needs_timer_erratum_workaround() \
>>  	static_branch_unlikely(&arch_timer_read_ool_enabled)
>>  #else
>> -#define needs_fsl_a008585_workaround()  false
>> +#define needs_timer_erratum_workaround()  false
>>  #endif
>>
>> -u32 __fsl_a008585_read_cntp_tval_el0(void);
>> -u32 __fsl_a008585_read_cntv_tval_el0(void);
>> -u64 __fsl_a008585_read_cntvct_el0(void);
>> +struct clock_event_device;
>> +
>> +struct arch_timer_erratum_workaround {
>> +	int erratum;
>> +	u32 (*read_cntp_tval_el0)(void);
>> +	u32 (*read_cntv_tval_el0)(void);
>> +	u64 (*read_cntvct_el0)(void);
>> +};
>> +extern struct arch_timer_erratum_workaround *erratum_workaround;
> 
> You seem to be doing two things in this patch:
> - Introducing a more generic erratum handling mechanism
> - Adding a workaround for your particular erratum
> 
> Please make this two patches.
> 

OK.

>>
>>  /*
>>   * The number of retries is an arbitrary value well beyond the highest number
>> @@ -59,16 +66,34 @@ u64 __fsl_a008585_read_cntvct_el0(void);
>>  	_new;						\
>>  })
>>
>> +#define __hisi_161x01_read_reg(reg) ({			\
>> +	u64 _old, _new;					\
>> +	int _retries = 200;				\
> 
> How has this number of retries been determined?
> 

Just a empirical data to avoid dead loop, mostly it should not loop so many times, advice from chip developer.

>> +							\
>> +	do {						\
>> +		_old = read_sysreg(reg);		\
>> +		_new = read_sysreg(reg);		\
>> +		_retries--;				\
>> +	} while (unlikely((_new - _old) >> 5) && _retries);	\
> 
> Please document why ignoring the bottom 5 bits is a reasonable thing to do.
> 
OK.

>> +							\
>> +	WARN_ON_ONCE(!_retries);			\
>> +	_new;						\
>> +})
>> +
>> +
>> +
>>  #define arch_timer_reg_read_stable(reg) 		\
>>  ({							\
>>  	u64 _val;					\
>> -	if (needs_fsl_a008585_workaround())		\
>> -		_val = __fsl_a008585_read_##reg();	\
>> +	if (needs_timer_erratum_workaround())		\
>> +		_val = erratum_workaround->read_##reg();	\
>>  	else						\
>>  		_val = read_sysreg(reg);		\
>>  	_val;						\
>>  })
>>
>> +
>> +
>>  /*
>>   * These register accessors are marked inline so the compiler can
>>   * nicely work out which register we want, and chuck away the rest of
>> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
>> index 8a753fd..fcfcdc7 100644
>> --- a/drivers/clocksource/Kconfig
>> +++ b/drivers/clocksource/Kconfig
>> @@ -312,8 +312,20 @@ config FSL_ERRATUM_A008585
>>  	help
>>  	  This option enables a workaround for Freescale/NXP Erratum
>>  	  A-008585 ("ARM generic timer may contain an erroneous
>> -	  value").  The workaround will only be active if the
>> +	  value").  The workaround will be active if the
>>  	  fsl,erratum-a008585 property is found in the timer node.
>> +	  This can be overridden with the clocksource.arm_arch_timer.fsl-a008585
>> +	  boot parameter.
>> +
>> +config HISILICON_ERRATUM_161X01
>> +	bool "Workaround for Hisilicon Erratum 161201"
>> +	default y
>> +	depends on ARM_ARCH_TIMER && ARM64
>> +	help
>> +	  This option enables a workaround for Hisilicon Erratum
>> +	  161201. The workaround will be active if the hisi,erratum-161201
>> +	  property is found in the timer node. This can be overridden with
>> +	  the clocksource.arm_arch_timer.hisi-161201 boot parameter.
> 
> Please pick a side. This is either called 161X01 or 161201.
>
Sorry.


>>
>>  config ARM_GLOBAL_TIMER
>>  	bool "Support for the ARM global timer" if COMPILE_TEST
>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>> index 73c487d..e1cf0ad 100644
>> --- a/drivers/clocksource/arm_arch_timer.c
>> +++ b/drivers/clocksource/arm_arch_timer.c
>> @@ -90,16 +90,23 @@ static int __init early_evtstrm_cfg(char *buf)
>>  }
>>  early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg);
>>
>> -/*
>> - * Architected system timer support.
>> - */
>> +#define 	FSL_A008585		1
>> +#define 	HISILICON_161X01	2
>> +
>> +struct arch_timer_erratum_workaround *erratum_workaround;
>> +
>> +#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161X01)
>> +static int arch_timer_uses_erratum = 0;
>>
>> -#ifdef CONFIG_FSL_ERRATUM_A008585
>>  DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled);
>>  EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
>> +#endif
>>
>> -static int fsl_a008585_enable = -1;
>> +/*
>> + * Architected system timer support.
>> + */
>>
>> +#ifdef CONFIG_FSL_ERRATUM_A008585
>>  static int __init early_fsl_a008585_cfg(char *buf)
>>  {
>>  	int ret;
>> @@ -109,28 +116,96 @@ static int __init early_fsl_a008585_cfg(char *buf)
>>  	if (ret)
>>  		return ret;
>>
>> -	fsl_a008585_enable = val;
>> +	if (val)
>> +		arch_timer_uses_erratum = FSL_A008585;
>> +
> 
> I don't think you need this indirection. You should be able to set the
> erratum_workaround pointer, and test that only to enable the OOL access.
> 
>>  	return 0;
>>  }
>>  early_param("clocksource.arm_arch_timer.fsl-a008585", early_fsl_a008585_cfg);
>>
>> -u32 __fsl_a008585_read_cntp_tval_el0(void)
>> +u32 fsl_a008585_read_cntp_tval_el0(void)
>>  {
>>  	return __fsl_a008585_read_reg(cntp_tval_el0);
>>  }
>>
>> -u32 __fsl_a008585_read_cntv_tval_el0(void)
>> +u32 fsl_a008585_read_cntv_tval_el0(void)
>>  {
>>  	return __fsl_a008585_read_reg(cntv_tval_el0);
>>  }
>>
>> -u64 __fsl_a008585_read_cntvct_el0(void)
>> +u64 fsl_a008585_read_cntvct_el0(void)
>>  {
>>  	return __fsl_a008585_read_reg(cntvct_el0);
>>  }
>> -EXPORT_SYMBOL(__fsl_a008585_read_cntvct_el0);
>> +EXPORT_SYMBOL(fsl_a008585_read_cntvct_el0);
> 
> Since you're now going to through a pointer indirection
> (erratum_workaround), why do you need this export? Why aren't all these
> function static? How does it work with modules that need to access
> cntvct_el0 (hint: it probably doesn't...)?
> 
>> +#else
>> +u32 fsl_a008585_read_cntp_tval_el0(void)
>> +{
>> +	return 0;
>> +}
>> +
>> +u32 fsl_a008585_read_cntv_tval_el0(void)
>> +{
>> +	return 0;
>> +}
>> +
>> +u64 fsl_a008585_read_cntvct_el0(void)
>> +{
>> +	return 0;
>> +}
>> +EXPORT_SYMBOL(fsl_a008585_read_cntvct_el0);
> 
> I don't think we need any of this.

Agree.

> 
>>  #endif /* CONFIG_FSL_ERRATUM_A008585 */
>>
>> +#ifdef CONFIG_HISILICON_ERRATUM_161X01
>> +static int __init early_hisi_161x01_cfg(char *buf)
>> +{
>> +	int ret;
>> +	bool val;
>> +
>> +	ret = strtobool(buf, &val);
>> +	if (ret)
>> +		return ret;
>> +
>> +	if (val)
>> +		arch_timer_uses_erratum = HISILICON_161X01;
>> +
>> +	return 0;
>> +}
>> +early_param("clocksource.arm_arch_timer.hisilicon-161x01", early_hisi_161x01_cfg);
>> +
>> +u32 hisi_161x01_read_cntp_tval_el0(void)
>> +{
>> +	return __hisi_161x01_read_reg(cntp_tval_el0);
>> +}
>> +
>> +u32 hisi_161x01_read_cntv_tval_el0(void)
>> +{
>> +	return __hisi_161x01_read_reg(cntv_tval_el0);
>> +}
>> +
>> +u64 hisi_161x01_read_cntvct_el0(void)
>> +{
>> +	return __hisi_161x01_read_reg(cntvct_el0);
>> +}
>> +EXPORT_SYMBOL(hisi_161x01_read_cntvct_el0);
> 
> Same issue.
> 
>> +#else
>> +u32 hisi_161x01_read_cntp_tval_el0(void)
>> +{
>> +	return 0;
>> +}
>> +
>> +u32 hisi_161x01_read_cntv_tval_el0(void)
>> +{
>> +	return 0;
>> +}
>> +
>> +u64 hisi_161x01_read_cntvct_el0(void)
>> +{
>> +	return 0;
>> +}
>> +EXPORT_SYMBOL(hisi_161x01_read_cntvct_el0);
>> +#endif
>> +
>>  static __always_inline
>>  void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val,
>>  			  struct clock_event_device *clk)
>> @@ -280,8 +355,8 @@ static __always_inline void set_next_event(const int access, unsigned long evt,
>>  	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
>>  }
>>
>> -#ifdef CONFIG_FSL_ERRATUM_A008585
>> -static __always_inline void fsl_a008585_set_next_event(const int access,
>> +#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161X01)
>> +static __always_inline void erratum_set_next_event(const int access,
>>  		unsigned long evt, struct clock_event_device *clk)
>>  {
>>  	unsigned long ctrl;
>> @@ -299,20 +374,35 @@ static __always_inline void fsl_a008585_set_next_event(const int access,
>>  	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
>>  }
>>
>> -static int fsl_a008585_set_next_event_virt(unsigned long evt,
>> +static int erratum_set_next_event_virt(unsigned long evt,
>>  					   struct clock_event_device *clk)
>>  {
>> -	fsl_a008585_set_next_event(ARCH_TIMER_VIRT_ACCESS, evt, clk);
>> +	erratum_set_next_event(ARCH_TIMER_VIRT_ACCESS, evt, clk);
>>  	return 0;
>>  }
>>
>> -static int fsl_a008585_set_next_event_phys(unsigned long evt,
>> +static int erratum_set_next_event_phys(unsigned long evt,
>>  					   struct clock_event_device *clk)
>>  {
>> -	fsl_a008585_set_next_event(ARCH_TIMER_PHYS_ACCESS, evt, clk);
>> +	erratum_set_next_event(ARCH_TIMER_PHYS_ACCESS, evt, clk);
>>  	return 0;
>>  }
>> -#endif /* CONFIG_FSL_ERRATUM_A008585 */
>> +#endif /* CONFIG_FSL_ERRATUM_A008585 || CONFIG_HISILICON_ERRATUM_161X01 */
>> +
>> +#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161X01)
>> +static struct arch_timer_erratum_workaround arch_timer_erratum[] = {
>> +{
>> +	.erratum = FSL_A008585,
>> +	.read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
>> +	.read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
>> +	.read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
>> +},{
>> +	.erratum = HISILICON_161X01,
>> +	.read_cntp_tval_el0 = hisi_161x01_read_cntp_tval_el0,
>> +	.read_cntv_tval_el0 = hisi_161x01_read_cntv_tval_el0,
>> +	.read_cntvct_el0 = hisi_161x01_read_cntvct_el0,
>> +} };
> 
> Since the two erratum are allowed to be selected independently, you
> shouldn't lump them together here.
> 

OK.

>> +#endif
>>
>>  static int arch_timer_set_next_event_virt(unsigned long evt,
>>  					  struct clock_event_device *clk)
>> @@ -342,16 +432,16 @@ static int arch_timer_set_next_event_phys_mem(unsigned long evt,
>>  	return 0;
>>  }
>>
>> -static void fsl_a008585_set_sne(struct clock_event_device *clk)
>> +static void erratum_set_sne(struct clock_event_device *clk)
>>  {
>> -#ifdef CONFIG_FSL_ERRATUM_A008585
>> +#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161X01)
>>  	if (!static_branch_unlikely(&arch_timer_read_ool_enabled))
>>  		return;
>>
>>  	if (arch_timer_uses_ppi == VIRT_PPI)
>> -		clk->set_next_event = fsl_a008585_set_next_event_virt;
>> +		clk->set_next_event = erratum_set_next_event_virt;
>>  	else
>> -		clk->set_next_event = fsl_a008585_set_next_event_phys;
>> +		clk->set_next_event = erratum_set_next_event_phys;
>>  #endif
>>  }
>>
>> @@ -384,7 +474,7 @@ static void __arch_timer_setup(unsigned type,
>>  			BUG();
>>  		}
>>
>> -		fsl_a008585_set_sne(clk);
>> +		erratum_set_sne(clk);
>>  	} else {
>>  		clk->features |= CLOCK_EVT_FEAT_DYNIRQ;
>>  		clk->name = "arch_mem_timer";
>> @@ -890,12 +980,21 @@ static int __init arch_timer_of_init(struct device_node *np)
>>
>>  	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
>>
>> -#ifdef CONFIG_FSL_ERRATUM_A008585
>> -	if (fsl_a008585_enable < 0)
>> -		fsl_a008585_enable = of_property_read_bool(np, "fsl,erratum-a008585");
>> -	if (fsl_a008585_enable) {
>> +#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161X01)
>> +	if (!arch_timer_uses_erratum) {
>> +		if (IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) &&
>> +		    of_property_read_bool(np, "fsl,erratum-a008585"))
>> +			arch_timer_uses_erratum = FSL_A008585;
>> +		else if (IS_ENABLED(CONFIG_HISI_ERRATUM_161X01) &&
>> +			 of_property_read_bool(np, "hisilicon,erratum-161x01"))
>> +			arch_timer_uses_erratum = HISILICON_161X01;
>> +	}
>> +
>> +	if (arch_timer_uses_erratum) {
>> +		erratum_workaround = &arch_timer_erratum[arch_timer_uses_erratum - 1];
>> +		pr_info("Enabling workaround for %s\n", arch_timer_uses_erratum == FSL_A008585 ?
>> +			"FSL erratum A-008585" : "HISILICON ERRATUM 161x01");
>>  		static_branch_enable(&arch_timer_read_ool_enabled);
>> -		pr_info("Enabling workaround for FSL erratum A-008585\n");
> 
> Get rid of arch_timer_uses_erratum, of the erratum identifier in the
> structure, and put a static string in there. That should do everything
> you need.
> 

OK.

Thanks.
Ding

>>  	}
>>  #endif
>>
> 
> Thanks,
> 
> 	M.
> 

^ permalink raw reply

* [PATCH 2/5] ARM: davinci: Don't append git rev to local version
From: Sekhar Nori @ 2016-10-24 11:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477075018-20176-3-git-send-email-david@lechnology.com>

On Saturday 22 October 2016 12:06 AM, David Lechner wrote:
> In the davinci default configuration, don't append the git revision to
> the local kernel version by. This seems like the more desirable default
> value.

Why? To the contrary I actually quite like the fact that the git commit
is appended to version string. Makes it easy for me to cross-check that
I am booting the right image.

> 
> Signed-off-by: David Lechner <david@lechnology.com>

Thanks,
Sekhar

^ permalink raw reply

* [PATCH] Documentation: DMA-API: Clarify semantics of dma_set_mask_and_coherent
From: Punit Agrawal @ 2016-10-24 11:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161024110819.GO3541@8bytes.org>

Joerg Roedel <joro@8bytes.org> writes:

> On Fri, Oct 21, 2016 at 03:09:16PM -0600, Jonathan Corbet wrote:
>> On Mon, 17 Oct 2016 16:26:23 +0100
>> Punit Agrawal <punit.agrawal@arm.com> wrote:
>> 
>> > The dma mapping api howto gives the impression that using the
>> > dma_set_mask_and_coherent (and related DMA APIs) will cause the kernel
>> > to check all the components in the path from the device to memory for
>> > addressing restrictions. In systems with address translations between
>> > the device and memory (e.g., when using IOMMU), this implies that a
>> > successful call to set set dma mask has checked the addressing
>> > constraints of the intermediaries as well.
>
> This is basically true when you have DMA controllers in the path from
> device to memory. But it is not true for IOMMUs, because IOMMU drivers
> are consumers of the dma-masks, they don't really restrict them. An
> IOMMU driver knows the limitations of IOMMU hardware and counts that in
> when allocating an address for a dma-buffer.

Yes, that's what I'd found looking at the IOMMU drivers in the tree.

>
> So long story short: Any IOMMU restrictions in address space size don't
> need to be represented in the dma-mask for a device.

That was another rabbit hole I'd spend some time in - whether IOMMU
restrictions need to be factored into the dma_mask for devices.

As size(dma_mask) > size(iommu supported address size) still works, I
came to the conclusion that the documentation can maybe help clarify
this.

This patch is an attempt to update the documentation to inform the user
that even if the dma_set_mask call succeeds, the system may still not
use the entire device address space.

Thanks for clarifying a few of my doubts.

Punit

>
>
>
> 	Joerg

^ permalink raw reply

* [PATCH] of: Add vendor prefix for Aries Embedded GmbH
From: Marek Vasut @ 2016-10-24 11:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919213800.9498-1-marex@denx.de>

On 09/19/2016 11:38 PM, Marek Vasut wrote:
> Add vendor prefix for Aries Embedded GmbH
> http://www.aries-embedded.de/
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Rob Herring <robh@kernel.org>

Hi, bump ?

> ---
>  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 69caf14..522dd65 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.txt
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
> @@ -27,6 +27,7 @@ analogix	Analogix Semiconductor, Inc.
>  apm	Applied Micro Circuits Corporation (APM)
>  aptina	Aptina Imaging
>  arasan	Arasan Chip Systems
> +aries	Aries Embedded GmbH
>  arm	ARM Ltd.
>  armadeus	ARMadeus Systems SARL
>  arrow	Arrow Electronics
> 


-- 
Best regards,
Marek Vasut

^ permalink raw reply

* [SPAM][PATCH 3/4] mtk_mdp_m2m: remove an unused struct
From: Minghsiu Tsai @ 2016-10-24 11:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <624b0ea4550b90318ec2293d80b1caa5bafd2a35.1477058332.git.mchehab@s-opensource.com>

On Fri, 2016-10-21 at 11:59 -0200, Mauro Carvalho Chehab wrote:
> drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c:48:33: warning: ?mtk_mdp_size_align? defined but not used [-Wunused-variable]
>  static struct mtk_mdp_pix_align mtk_mdp_size_align = {
>                                  ^~~~~~~~~~~~~~~~~~
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
> ---
>  drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c | 7 -------
>  1 file changed, 7 deletions(-)
> 
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> index 065502757133..33124a6c9951 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> @@ -45,13 +45,6 @@ struct mtk_mdp_pix_limit {
>  	u16 target_rot_en_h;
>  };
>  
> -static struct mtk_mdp_pix_align mtk_mdp_size_align = {
> -	.org_w			= 16,
> -	.org_h			= 16,
> -	.target_w		= 2,
> -	.target_h		= 2,
> -};
> -

Hi Mauro,

The structure is used for the format V4L2_PIX_FMT_MT21C which is added
in the later patch.
"[media] media: mtk-mdp: support pixelformat V4L2_PIX_FMT_MT21C"

I just know checkpatch should be run patch by patch, so this warning
message will be generated without the MT21C patch.

I found all mtk-mdp patches have been merged in media tree, so is this
patch still needed?

If yes, remove 'mtk_mdp_size_align' in this patch, and re-added it in
the MT21C patch. 


minghsiu

>  static const struct mtk_mdp_fmt mtk_mdp_formats[] = {
>  	{
>  		.pixelformat	= V4L2_PIX_FMT_NV12M,

^ permalink raw reply

* [PATCH 3/4] mtk_mdp_m2m: remove an unused struct
From: Minghsiu Tsai @ 2016-10-24 11:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <624b0ea4550b90318ec2293d80b1caa5bafd2a35.1477058332.git.mchehab@s-opensource.com>

On Fri, 2016-10-21 at 11:59 -0200, Mauro Carvalho Chehab wrote:
> drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c:48:33: warning: ?mtk_mdp_size_align? defined but not used [-Wunused-variable]
>  static struct mtk_mdp_pix_align mtk_mdp_size_align = {
>                                  ^~~~~~~~~~~~~~~~~~
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
> ---
>  drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c | 7 -------
>  1 file changed, 7 deletions(-)
> 
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> index 065502757133..33124a6c9951 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> @@ -45,13 +45,6 @@ struct mtk_mdp_pix_limit {
>  	u16 target_rot_en_h;
>  };
>  
> -static struct mtk_mdp_pix_align mtk_mdp_size_align = {
> -	.org_w			= 16,
> -	.org_h			= 16,
> -	.target_w		= 2,
> -	.target_h		= 2,
> -};
> -

Hi Mauro,

The structure is used for the format V4L2_PIX_FMT_MT21C which is added
in the later patch.
"[media] media: mtk-mdp: support pixelformat V4L2_PIX_FMT_MT21C"

I just know checkpatch should be run patch by patch, so this warning
message will be generated without the MT21C patch.

I found all mtk-mdp patches have been merged in media tree, so is this
patch still needed?

If yes, remove 'mtk_mdp_size_align' in this patch, and re-added it in
the MT21C patch. 


minghsiu

>  static const struct mtk_mdp_fmt mtk_mdp_formats[] = {
>  	{
>  		.pixelformat	= V4L2_PIX_FMT_NV12M,

^ permalink raw reply

* [PATCH] Documentation: DMA-API: Clarify semantics of dma_set_mask_and_coherent
From: Punit Agrawal @ 2016-10-24 11:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161021150916.0d274e9f@lwn.net>

Jonathan Corbet <corbet@lwn.net> writes:

> On Mon, 17 Oct 2016 16:26:23 +0100
> Punit Agrawal <punit.agrawal@arm.com> wrote:
>
>> The dma mapping api howto gives the impression that using the
>> dma_set_mask_and_coherent (and related DMA APIs) will cause the kernel
>> to check all the components in the path from the device to memory for
>> addressing restrictions. In systems with address translations between
>> the device and memory (e.g., when using IOMMU), this implies that a
>> successful call to set set dma mask has checked the addressing
>> constraints of the intermediaries as well.
>> 
>> For the IOMMU drivers in the tree, the check is actually performed while
>> allocating the DMA buffer rather than when the DMA mask is
>> configured. For MMUs that do not support the full device addressing
>> capability, the allocations are made from a reduced address space.
>> 
>> Update the documentation to clarify that even though the call to
>> dma_set_mask_and_coherent succeeds, it may not be possible to use the
>> full addressing capability of the device.
>
> OK, so I guess I can buy this.  But...
>
>> Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
>> Cc: Jonathan Corbet <corbet@lwn.net>
>> ---
>>  Documentation/DMA-API-HOWTO.txt | 39 +++++++++++++++++++++++----------------
>>  1 file changed, 23 insertions(+), 16 deletions(-)
>> 
>> diff --git a/Documentation/DMA-API-HOWTO.txt b/Documentation/DMA-API-HOWTO.txt
>> index 979228b..240d1ee 100644
>> --- a/Documentation/DMA-API-HOWTO.txt
>> +++ b/Documentation/DMA-API-HOWTO.txt
>> @@ -159,39 +159,46 @@ support 64-bit addressing (DAC) for all transactions.  And at least
>>  one platform (SGI SN2) requires 64-bit consistent allocations to
>>  operate correctly when the IO bus is in PCI-X mode.
>>  
>> -For correct operation, you must interrogate the kernel in your device
>> -probe routine to see if the DMA controller on the machine can properly
>> -support the DMA addressing limitation your device has.  It is good
>> +For correct operation, you must inform the kernel in your device probe
>> +routine to see if the DMA controller on the machine can properly
>> +support the DMA addressing capabilities your device has.  It is good
>
> Here it's still saying "to see if the DMA controller on the machine can
> properly support the DMA addressing capabilities your device has".  So
> you've not really changed the sense of this sentence here.

You're right - the changes don't go far enough.

How about dropping the bit so that it now reads -

"For correct operation, in your device probe routine, you must inform
the DMA addressing capabilities of your device to the kernel."

>
> If I understand things correctly, the calls in question are storing the
> device's limitations; they will only fail if the kernel is entirely
> unable to work within the indicated range, right?  I don't think there's
> ever been any guarantee that the system as a whole could use the entire
> range that is addressable by the device.

That matches my understanding as well. I was just trying to make it more
explicit with this patch.

> I have no objection to making
> that more clear, but let's actually make it more clear by saying what the
> functions are actually doing.
>
> Make sense, or am I missing something here?

Let me know if the change I suggest is an improvement and I'll send out
a v2.

Thanks,
Punit

>
> Thanks,
>
> jon

^ permalink raw reply

* [PATCH] ARM: imx_v6_v7_defconfig: Increase CMA size
From: Shawn Guo @ 2016-10-24 11:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161017163411.11888-1-marex@denx.de>

On Mon, Oct 17, 2016 at 06:34:11PM +0200, Marek Vasut wrote:
> Increase the CMA size to 64 MiB, otherwise it isn't possible to use
> etnaviv driver on systems with 1920x1080 panel due to insufficient
> memory .
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Fabio Estevam <fabio.estevam@nxp.com>
> Cc: Shawn Guo <shawnguo@kernel.org>

Applied, thanks.

^ permalink raw reply

* [PATCH] i2c: rk3x: Give the tuning value 0 during rk3x_i2c_v0_calc_timings
From: Andy Yan @ 2016-10-24 11:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477125822-30644-1-git-send-email-david.wu@rock-chips.com>

Hi:


On 2016?10?22? 16:43, David Wu wrote:
> We found a bug that i2c transfer sometimes failed on 3066a board with
> stabel-4.8, the con register would be updated by uninitialized tuning
> value, it made the i2c transfer failed.
>
> So give the tuning value to be zero during rk3x_i2c_v0_calc_timings.
>
> Signed-off-by: David Wu <david.wu@rock-chips.com>
> ---
>   drivers/i2c/busses/i2c-rk3x.c | 2 ++
>   1 file changed, 2 insertions(+)
>
> diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
> index 50702c7..df22066 100644
> --- a/drivers/i2c/busses/i2c-rk3x.c
> +++ b/drivers/i2c/busses/i2c-rk3x.c
> @@ -694,6 +694,8 @@ static int rk3x_i2c_v0_calc_timings(unsigned long clk_rate,
>   	t_calc->div_low--;
>   	t_calc->div_high--;
>   
> +	/* Give the tuning value 0, that would not update con register */
> +	t_calc->tuning = 0;
>   	/* Maximum divider supported by hw is 0xffff */
>   	if (t_calc->div_low > 0xffff) {
>   		t_calc->div_low = 0xffff;

rk3066a based board can't boot up(with endless i2c irq messages print 
out) from linux-4.8 without this fix.

Tested-by: Andy Yan <andy.yan@rock-chips.com>

^ permalink raw reply

* [PATCH] ARM: imx_v6_v7_defconfig: Select the es8328 codec driver
From: Shawn Guo @ 2016-10-24 11:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161017163433.11938-1-marex@denx.de>

On Mon, Oct 17, 2016 at 06:34:33PM +0200, Marek Vasut wrote:
> Select CONFIG_SND_SOC_ES8328 so that we can have audio functional
> by default on Kosagi Novena boards.
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Fabio Estevam <fabio.estevam@nxp.com>
> Cc: Shawn Guo <shawnguo@kernel.org>

Applied, thanks.

^ permalink raw reply

* [PATCH] ARM: dts: novena: Enable PWM1
From: Shawn Guo @ 2016-10-24 11:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161017163449.11990-1-marex@denx.de>

On Mon, Oct 17, 2016 at 06:34:49PM +0200, Marek Vasut wrote:
> Enable PWM1, otherwise the backlight cannot work.
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Fabio Estevam <fabio.estevam@nxp.com>
> Cc: Shawn Guo <shawnguo@kernel.org>

Applied, thanks.

^ permalink raw reply

* [PATCH 5/5] ARM: dts: Add LEGO MINDSTORTMS EV3 dts
From: Sekhar Nori @ 2016-10-24 11:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477075018-20176-6-git-send-email-david@lechnology.com>

On Saturday 22 October 2016 12:06 AM, David Lechner wrote:
> This adds a device tree definition file for LEGO MINDSTORMS EV3.

Thanks for the patch!

> 
> What is working:
> 
> * Pin muxing
> * MicroSD card reader
> * UART on input port 1
> 
> What is partially working:
> 
> * Buttons - working after GPIO fix
> * LEDs - working after GPIO fix
> * Poweroff/reset - working after GPIO fix

Is the GPIO fix something that will go in v4.9-rc cycle ?

> * Flash memory - driver loads but can't read the block devices - this is
>   probably due to the fact that we are not able to configure the SPI to
>   use DMA via device tree

Hmm, I would not have expected PIO mode to be so inefficient that you
are unable to even read the block device.

> * EEPROM - there seems to be a hardware bug that causes the first byte
>   read to be corrupted - this can be worked around by adding an I2C stop
>   between writing the register and reading the data, but the at24 driver
>   does not have an option to do this
> 
> What is not working/to be added later:
> 
> * Display - waiting for "tiny DRM" to be mainlined
> * Speaker - needs new PWM sound driver
> * USB - waiting for OHCI and MUSB device tree support to be mainlined
> * ADC - needs new iio driver
> * GPIOs - broken because of recent changes to core gpio driver
> * Bluetooth - needs new driver for sequencing power/enable/clock
> * Input and output ports - need some sort of new phy or extcon driver
> * Battery - needs new power supply driver (depends on ADC iio driver)
> 
> Signed-off-by: David Lechner <david@lechnology.com>
> ---
>  arch/arm/boot/dts/Makefile     |   3 +-
>  arch/arm/boot/dts/lego-ev3.dts | 454 +++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 456 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/boot/dts/lego-ev3.dts
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index f80f5b7..5f91c1a 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -116,7 +116,8 @@ dtb-$(CONFIG_ARCH_CLPS711X) += \
>  dtb-$(CONFIG_ARCH_DAVINCI) += \
>  	da850-lcdk.dtb \
>  	da850-enbw-cmc.dtb \
> -	da850-evm.dtb
> +	da850-evm.dtb \
> +	lego-ev3.dtb
>  dtb-$(CONFIG_ARCH_DIGICOLOR) += \
>  	cx92755_equinox.dtb
>  dtb-$(CONFIG_ARCH_EFM32) += \
> diff --git a/arch/arm/boot/dts/lego-ev3.dts b/arch/arm/boot/dts/lego-ev3.dts
> new file mode 100644
> index 0000000..a6b4c7d
> --- /dev/null
> +++ b/arch/arm/boot/dts/lego-ev3.dts
> @@ -0,0 +1,454 @@
> +/*
> + * Device tree for LEGO MINDSTORMS EV3
> + *
> + * Copyright (C) 2016 David Lechner <david@lechnology.com>
> + *
> + * This program is free software; you can redistribute  it and/or modify it
> + * under  the terms of  the GNU General  Public License as published by the
> + * Free Software Foundation, version 2.
> + */
> +
> +/dts-v1/;
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/linux-event-codes.h>
> +#include <dt-bindings/pwm/pwm.h>
> +
> +#include "da850.dtsi"
> +
> +/ {
> +	compatible = "lego,ev3", "ti,da850";
> +	model = "LEGO MINDSTORMS EV3";
> +
> +	soc at 1c00000 {
> +		/*
> +		 * (ab)using pinctrl-single to disable all internal pullups/
> +		 * pulldowns on I/O.
> +		 */
> +		pinmux at 22c00c {
> +			compatible = "pinctrl-single";
> +			reg = <0x22c00c 0x4>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			pinctrl-single,bit-per-mux;
> +			pinctrl-single,register-width = <32>;
> +			pinctrl-single,function-mask = <0xf>;
> +			/*
> +			 * There is a bug in pinctrl-single that prevents us
> +			 * from setting function-mask to 1, so doing things
> +			 * in groups of 4. Doesn't really matter since we are
> +			 * disabling all at once anyway.
> +			 */
> +
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pupu_disable>;
> +
> +			pupu_disable: pinmux_all_pins {
> +				pinctrl-single,bits = <
> +					0x0 0x00000000 0xffffffff
> +				>;
> +			};

Sigh. This is quite an abuse :)

I know we don't have a good way to configure this in kernel today. And I
am surprised we never had to care about disabling pullups so far. Can
you clarify why you need it? I assume there is some contention you want
to avoid, but on which interface?

I dont think this can be done this way using pinctrl-single. A small
driver to handle pullup/down control for da850 may have to be added to
drivers/pinctrl. It will be better to check with Linus Walleij on his
thoughts using a new thread ccing the pinctrl subsystem list as well.

[...]

> +	in1_pins: pinmux_in1_pins {
> +		pinctrl-single,bits = <
> +			/* GP0[15] */
> +			0x0 0x00000008 0x0000000f
> +			/* GP0[2] */
> +			0x4 0x00800000 0x00f00000
> +			/* GP2[2] */
> +			0x18 0x00800000 0x00f00000
> +			/* GP8[10], GP8[11] */
> +			0x48 0x88000000 0xff000000
> +		>;
> +	};

I see that this is not really used. Can you add these when you actually
use them. Looks like that applies to some other definitions like this below.

> +&ehrpwm1 {
> +	status = "disabled";

Hmm, disabled? Can you add this node when you actually use it?

> +	pinctrl-names = "default";
> +	/* MBPWM, MAPWM */
> +	pinctrl-0 = <&ehrpwm1a_pins>, <&ehrpwm1b_pins>;
> +};
> +
> +&ecap1 {
> +	status = "disabled";

same here and other places below.

> +	pinctrl-names = "default";
> +	/* MDPWM */
> +	pinctrl-0 = <&ecap1_pins>;
> +};
> +
> +&spi0 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&spi0_pins>, <&spi0_cs0_pin>, <&spi0_cs3_pin>;
> +	dmas = <&edma0 14 0>, <&edma0 15 0>;
> +	dma-names = "rx", "tx";
> +
> +	spi-flash at 0 {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "n25q128a13", "jedec,spi-nor";
> +		reg = <0>;
> +		spi-max-frequency = <50000000>;
> +		ti,spi-wdelay = <8>;
> +
> +		partition at 0 {
> +			label = "U-Boot";
> +			reg = <0 0x40000>;

Thats 256KB for U-Boot and MLO (I assume in concatenated AIS image). Is
that sufficient for future too? Moving partitions later is tough ask
because that means users will lose data when they upgrade the kernel
because of partitions moving around. Just a suggestion to keep future
U-Boot bloat in mind and not use a "just fits" number.

> +		};
> +
> +		partition at 40000 {
> +			label = "U-Boot Env";
> +			reg = <0x40000 0x10000>;
> +		};
> +
> +		partition at 50000 {
> +			label = "Kernel";
> +			reg = <0x50000 0x200000>;
> +		};
> +
> +		partition at 250000 {
> +			label = "Filesystem";
> +			reg = <0x250000 0xa50000>;
> +		};
> +
> +		partition at cb0000 {
> +			label = "Storage";
> +			reg = <0xcb0000 0x2f0000>;
> +		};
> +	};
> +
> +	/* TODO: ADC goes here */

I would drop this comment.

> +};
> +
> +&spi1 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&spi1_pins>, <&spi1_cs0_pin>;
> +
> +	/* TODO: LCD Display goes here */

Add this node when you actually have display working.

Thanks,
Sekhar

^ permalink raw reply

* [PATCH 2/4] mtk_mdp_vpu: remove a double unlock at the error path
From: Minghsiu Tsai @ 2016-10-24 11:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <768767961c64dea3fdd86132c9eba87ae652d588.1477058332.git.mchehab@s-opensource.com>

On Fri, 2016-10-21 at 11:59 -0200, Mauro Carvalho Chehab wrote:
> As warned by smatch:
> 	drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c:98 mtk_mdp_vpu_send_msg() error: double unlock 'mutex:&ctx->mdp_dev->vpulock'
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
> ---
>  drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c b/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c
> index b38d29e99f7a..5c8caa864e32 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c
> @@ -91,7 +91,6 @@ static int mtk_mdp_vpu_send_msg(void *msg, int len, struct mtk_mdp_vpu *vpu,
>  	mutex_lock(&ctx->mdp_dev->vpulock);
>  	err = vpu_ipi_send(vpu->pdev, (enum ipi_id)id, msg, len);
>  	if (err) {
> -		mutex_unlock(&ctx->mdp_dev->vpulock);

Hi Mauro,

It has been fixed by Hans in the later patch.

Author: Hans Verkuil <hverkuil@xs4all.nl>
Date:   Mon Sep 19 05:00:34 2016 -0300

    [media] mtk-mdp: fix double mutex_unlock

    Fix smatch error:

    media-git/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c:100
mtk_mdp_vpu_send_msg() error: double unlock 'mutex:&ctx->

    Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>



minghsiu

>  		dev_err(&ctx->mdp_dev->pdev->dev,
>  			"vpu_ipi_send fail status %d\n", err);
>  	}

^ permalink raw reply

* [PATCH] usb: gadget: udc: atmel: fix endpoint name
From: Nicolas Ferre @ 2016-10-24 11:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <874m535dti.fsf@linux.intel.com>

Le 26/09/2016 ? 09:18, Felipe Balbi a ?crit :
> 
> Hi,
> 
> Greg Kroah-Hartman <gregkh@linuxfoundation.org> writes:
>> On Fri, Sep 23, 2016 at 04:20:45PM +0200, Nicolas Ferre wrote:
>>> Le 16/09/2016 ? 10:36, Nicolas Ferre a ?crit :
>>>> Le 15/09/2016 ? 17:07, Alexandre Belloni a ?crit :
>>>>> Since commit c32b5bcfa3c4 ("ARM: dts: at91: Fix USB endpoint nodes"),
>>>>> atmel_usba_udc fails with:
>>>>>
>>>>> ------------[ cut here ]------------
>>>>> WARNING: CPU: 0 PID: 0 at include/linux/usb/gadget.h:405
>>>>> ecm_do_notify+0x188/0x1a0
>>>>> Modules linked in:
>>>>> CPU: 0 PID: 0 Comm: swapper Not tainted 4.7.0+ #15
>>>>> Hardware name: Atmel SAMA5
>>>>> [<c010ccfc>] (unwind_backtrace) from [<c010a7ec>] (show_stack+0x10/0x14)
>>>>> [<c010a7ec>] (show_stack) from [<c0115c10>] (__warn+0xe4/0xfc)
>>>>> [<c0115c10>] (__warn) from [<c0115cd8>] (warn_slowpath_null+0x20/0x28)
>>>>> [<c0115cd8>] (warn_slowpath_null) from [<c04377ac>] (ecm_do_notify+0x188/0x1a0)
>>>>> [<c04377ac>] (ecm_do_notify) from [<c04379a4>] (ecm_set_alt+0x74/0x1ac)
>>>>> [<c04379a4>] (ecm_set_alt) from [<c042f74c>] (composite_setup+0xfc0/0x19f8)
>>>>> [<c042f74c>] (composite_setup) from [<c04356e8>] (usba_udc_irq+0x8f4/0xd9c)
>>>>> [<c04356e8>] (usba_udc_irq) from [<c013ec9c>] (handle_irq_event_percpu+0x9c/0x158)
>>>>> [<c013ec9c>] (handle_irq_event_percpu) from [<c013ed80>] (handle_irq_event+0x28/0x3c)
>>>>> [<c013ed80>] (handle_irq_event) from [<c01416d4>] (handle_fasteoi_irq+0xa0/0x168)
>>>>> [<c01416d4>] (handle_fasteoi_irq) from [<c013e3f8>] (generic_handle_irq+0x24/0x34)
>>>>> [<c013e3f8>] (generic_handle_irq) from [<c013e640>] (__handle_domain_irq+0x54/0xa8)
>>>>> [<c013e640>] (__handle_domain_irq) from [<c010b214>] (__irq_svc+0x54/0x70)
>>>>> [<c010b214>] (__irq_svc) from [<c0107eb0>] (arch_cpu_idle+0x38/0x3c)
>>>>> [<c0107eb0>] (arch_cpu_idle) from [<c0137300>] (cpu_startup_entry+0x9c/0xdc)
>>>>> [<c0137300>] (cpu_startup_entry) from [<c0900c40>] (start_kernel+0x354/0x360)
>>>>> [<c0900c40>] (start_kernel) from [<20008078>] (0x20008078)
>>>>> ---[ end trace e7cf9dcebf4815a6 ]---
>>>>>
>>>>> Fixes: c32b5bcfa3c4 ("ARM: dts: at91: Fix USB endpoint nodes")
>>>>> Reported-by: Richard Genoud <richard.genoud@gmail.com>
>>>>> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
>>>>
>>>> Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
>>>>
>>>> Felipe, Greg,
>>>> It is clearly a regression and material for 4.8-fixes. But I do know
>>>> that we are very late in the process :-(
>>>> Please do what you can to make it progress before 4.8-final but I'm
>>>> truly aware of the challenge.
>>>
>>> Any chance that we can have it (aka ping)?
>>
>> It's Felipe's area, not mine :)
> 
> Sorry, I had missed this one. Greg, seems like this would be the only
> pending fix. Do you want it in a pull request or would you prefer to
> just pick it up as a patch? Works either way for me. In case you decide
> to pick it up as a patch:
> 
> Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com>
> 
> If you prefer to pick it up as a pull request, I already have the patch
> in my 'fixes' branch, just need to tag it and send it to you.

Felipe,

We agreed to delay this patch after the merge window is closed. But I
feel that it's beginning to be urgent to make this patch go forward:
actual users of our kernel are facing the issue:

https://lkml.org/lkml/2016/10/17/493

We're already at -rc2 and I don't see USB-fixes included...

Best regards,
-- 
Nicolas Ferre

^ permalink raw reply

* [PATCH] ARM: dts: vf610: fix IRQ flag of global timer
From: Shawn Guo @ 2016-10-24 12:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161018015127.16981-1-stefan@agner.ch>

On Mon, Oct 17, 2016 at 06:51:27PM -0700, Stefan Agner wrote:
> The global timer IRQ (PPI[0], PPI 11 in device tree terms) is a
> rising edge interrupt. The ARM Cortex-A5 MPCore TRM in Chapter
> 10.1.2. Interrupt types and sources says:
> "Interrupt is rising-edge sensitive."
> 
> The bits seem to be read-only, hence this missconfiguration had
> no negative effect. However, with commit 992345a58e0c
> ("irqchip/gic: WARN if setting the interrupt type for a PPI fails")
> warnings such as this get printed:
> GIC: PPI11 is secure or misconfigured
> 
> With this change the new configuration matches the default
> configuration and no warning is printed anymore.
> 
> Signed-off-by: Stefan Agner <stefan@agner.ch>

Applied, thanks.

^ permalink raw reply

* [PATCH v1] char: hw_random: atmel-rng: disable TRNG during suspend
From: Nicolas Ferre @ 2016-10-24 12:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477296208-28335-1-git-send-email-wenyou.yang@atmel.com>

Le 24/10/2016 ? 10:03, Wenyou Yang a ?crit :
> To fix the over consumption on the VDDCore due to the TRNG enabled,
> disable the TRNG during suspend, not only disable the user interface
> clock (which is controlled by PMC). Because the user interface clock
> is independent from any clock that may be used in the entropy source
> logic circuitry.
> 
> Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
> ---
> 
>  drivers/char/hw_random/atmel-rng.c | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c
> index 0fcc9e6..2e2d09a 100644
> --- a/drivers/char/hw_random/atmel-rng.c
> +++ b/drivers/char/hw_random/atmel-rng.c
> @@ -48,6 +48,16 @@ static int atmel_trng_read(struct hwrng *rng, void *buf, size_t max,
>  		return 0;
>  }
>  
> +static void atmel_trng_enable(struct atmel_trng *trng)
> +{
> +	writel(TRNG_KEY | 1, trng->base + TRNG_CR);
> +}
> +
> +static void atmel_trng_disable(struct atmel_trng *trng)
> +{
> +	writel(TRNG_KEY, trng->base + TRNG_CR);
> +}
> +
>  static int atmel_trng_probe(struct platform_device *pdev)
>  {
>  	struct atmel_trng *trng;
> @@ -71,7 +81,7 @@ static int atmel_trng_probe(struct platform_device *pdev)
>  	if (ret)
>  		return ret;
>  
> -	writel(TRNG_KEY | 1, trng->base + TRNG_CR);
> +	atmel_trng_enable(trng);
>  	trng->rng.name = pdev->name;
>  	trng->rng.read = atmel_trng_read;
>  
> @@ -94,7 +104,7 @@ static int atmel_trng_remove(struct platform_device *pdev)
>  
>  	hwrng_unregister(&trng->rng);
>  
> -	writel(TRNG_KEY, trng->base + TRNG_CR);
> +	atmel_trng_disable(trng);
>  	clk_disable_unprepare(trng->clk);
>  
>  	return 0;
> @@ -105,6 +115,7 @@ static int atmel_trng_suspend(struct device *dev)
>  {
>  	struct atmel_trng *trng = dev_get_drvdata(dev);
>  
> +	atmel_trng_disable(trng);
>  	clk_disable_unprepare(trng->clk);
>  
>  	return 0;
> @@ -114,6 +125,7 @@ static int atmel_trng_resume(struct device *dev)
>  {
>  	struct atmel_trng *trng = dev_get_drvdata(dev);
>  
> +	atmel_trng_enable(trng);
>  	return clk_prepare_enable(trng->clk);

Isn't it the other way around:
enable the user interface first, then enable the internal clock? like:

clk_prepare_enable(trng->clk);
atmel_trng_enable(trng);

Regards,
-- 
Nicolas Ferre

^ permalink raw reply

* [PATCH] kernel: irq: fix build failure
From: Lee Jones @ 2016-10-24 12:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161024223231.5cdbb2ac@canb.auug.org.au>

On Mon, 24 Oct 2016, Stephen Rothwell wrote:
> On Mon, 24 Oct 2016 11:22:15 +0100 Lee Jones <lee.jones@linaro.org> wrote:
> > On Fri, 21 Oct 2016, Thomas Gleixner wrote:
> > 
> > > On Fri, 21 Oct 2016, Stephen Rothwell wrote:  
> > > > On Thu, 20 Oct 2016 14:55:45 +0200 (CEST) Thomas Gleixner <tglx@linutronix.de> wrote:  
> > > > > I know. This is under discussion with the driver folks as we are not going
> > > > > to blindly export stuff just because someone slapped a irq_set_parent()
> > > > > into the code w/o knowing why.  
> > > > 
> > > > Do we have any idea if a resolution is close.  This was first reported
> > > > in linux-next in September 14/15.  :-(  
> > > 
> > > Grr. Yes. As much as I hate it, I'll go and export it for now. Should be
> > > able to get it into rc2.  
> > 
> > Did this get in?  I still have people complaining about it.
> 
> It is in -rc2.  Commit 3118dac501bc.

Ah, I was searching for patches authored my Thomas.

I see it now, thanks.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH v3 0/5] Add runtime PM support for clocks (on Exynos SoC example)
From: Marek Szyprowski @ 2016-10-24 12:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CGME20161024121224eucas1p1070b72308dc9c8d8d2b10fa5bfeaf5ed@eucas1p1.samsung.com>

Dear All,

This patchset adds runtime PM support to common clock framework. This is an
attempt to implement support for clock controllers, which belongs to a power
domain. This approach works surprisingly well on Exynos 4412 and 5433 SoCs,
what allowed us to solve various freeze/crash issues related to power
management.

The main idea behind this patchset is to keep clock's controller power domain
enabled every time when at least one of its clock is enabled or access to its
registers is being made. Clock controller driver (clock provider) can
supply a struct device pointer, which is the used by clock core for tracking and
managing clock's controller runtime pm state. Each clk_prepare() operation will
first call pm_runtime_get_sync() on the supplied device, while clk_unprepare()
will do pm_runtime_put() at the end.

This runtime PM feature has been tested with Exynos4412 and Exynos5433 clocks
drivers. Both have some clocks, which belongs to respective power domains and
need special handling during power on/off procedures. Till now it wasn't handled
at all, what caused various problems.

Patches for exynos 4412 and 5433 clocks drivers change the way the clock
provider is initialized. Instead of CLK_OF_DECLARE based initialization, a
complete platform device driver infrastructure is being used. This is needed to
let driver to use runtime pm feature and integrate with generic power domains.
The side-effect of this change is a delay in clock provider registeration
during system boot, so early initialized drivers might get EPROBEDEFER error
when requesting their clocks. This is an issue for IOMMU drivers, so
this patchset will be fully functional once the deferred probe for IOMMU
will be merged.

The side-effect of this patchset is the one can finally read
/sys/kernel/debug/clk/clk_summary on all Exynos4412 boards without any freeze.

If one wants to test this patchset (on Exynos4412 Trats2 device with FIMC-IS
driver), I've provided a branch with all needed patches (fixes for Exynos,
FIMC-IS driver and IOMMU deferred probe):
https://git.linaro.org/people/marek.szyprowski/linux-srpol.git v4.9-clocks-pm-v3

Patches are based on vanilla v4.9-rc1 kernel.

Best regards
Marek Szyprowski
Samsung R&D Institute Poland

Changelog:

v3:
- Removed CLK_RUNTIME_PM flag, core now simply checks if runtime pm is enabled
  for the provided device during clock registration as suggested by Ulf
- Simplified code for exynos4412 isp clock driver registration
- Resolved some other minor issues pointed by Ulf clk core code
- Rebased onto v4.9-rc1 and new version of IOMMU deferred probe patchset

v2: https://www.spinics.net/lists/arm-kernel/msg532798.html
- Simplified clk_pm_runtime_get/put functions, removed workaround for devices
  with disabled runtime pm. Such workaround is no longer needed since commit
  4d23a5e84806b202d9231929c9507ef7cf7a0185 ("PM / Domains: Allow runtime PM
  during system PM phases").
- Added CLK_RUNTIME_PM flag to indicate clocks, for which clock core should
  call runtime pm functions. This solves problem with clocks, for which struct
  device is already registered, but no runtime pm is enabled.
- Extended commit messages according to Ulf suggestions.
- Fixed some style issues pointed by Barlomiej.

v1: http://www.spinics.net/lists/arm-kernel/msg528128.html
- initial version

Marek Szyprowski (5):
  clk: add support for runtime pm
  clock: samsung: add support for runtime pm
  clocks: exynos4x12: add runtime pm support for ISP clocks
  ARM: dts: exynos: add support for ISP power domain to exynos4x12
    clocks device
  clocks: exynos5433: add runtime pm support

 .../devicetree/bindings/clock/exynos4-clock.txt    |  22 ++
 arch/arm/boot/dts/exynos4x12.dtsi                  |   5 +
 drivers/clk/clk.c                                  | 111 +++++-
 drivers/clk/samsung/clk-exynos4.c                  | 211 +++++++----
 drivers/clk/samsung/clk-exynos5433.c               | 390 +++++++++++++++++----
 drivers/clk/samsung/clk-pll.c                      |   2 +-
 drivers/clk/samsung/clk.c                          |  12 +-
 drivers/clk/samsung/clk.h                          |   7 +
 8 files changed, 605 insertions(+), 155 deletions(-)

-- 
1.9.1

^ permalink raw reply

* [PATCH v3 1/5] clk: add support for runtime pm
From: Marek Szyprowski @ 2016-10-24 12:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477311130-6534-1-git-send-email-m.szyprowski@samsung.com>

Registers for some clocks might be located in the SOC area, which are under the
power domain. To enable access to those registers respective domain has to be
turned on. Additionally, registers for such clocks will usually loose its
contents when power domain is turned off, so additional saving and restoring of
them might be needed in the clock controller driver.

This patch adds basic infrastructure in the clocks core to allow implementing
driver for such clocks under power domains. Clock provider can supply a
struct device pointer, which is the used by clock core for tracking and managing
clock's controller runtime pm state. Each clk_prepare() operation
will first call pm_runtime_get_sync() on the supplied device, while
clk_unprepare() will do pm_runtime_put() at the end.

Additional calls to pm_runtime_get/put functions are required to ensure that any
register access (like calculating/changing clock rates and unpreparing/disabling
unused clocks on boot) will be done with clock controller in runtime resumend
state.

When one wants to register clock controller, which make use of this feature, he
has to:
1. Provide a struct device to the core when registering the provider.
2. Ensure to enable runtime PM for that device before registering clocks.
3. Make sure that the runtime PM status of the controller device reflects
   the HW state.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/clk/clk.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 101 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 0fb39fe217d1..3cf202ccf5a9 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -21,6 +21,7 @@
 #include <linux/of.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/pm_runtime.h>
 #include <linux/sched.h>
 #include <linux/clkdev.h>
 
@@ -46,6 +47,7 @@ struct clk_core {
 	const struct clk_ops	*ops;
 	struct clk_hw		*hw;
 	struct module		*owner;
+	struct device		*dev;
 	struct clk_core		*parent;
 	const char		**parent_names;
 	struct clk_core		**parents;
@@ -87,6 +89,26 @@ struct clk {
 	struct hlist_node clks_node;
 };
 
+/***           runtime pm          ***/
+static int clk_pm_runtime_get(struct clk_core *core)
+{
+	int ret = 0;
+
+	if (!core->dev)
+		return 0;
+
+	ret = pm_runtime_get_sync(core->dev);
+	return ret < 0 ? ret : 0;
+}
+
+static void clk_pm_runtime_put(struct clk_core *core)
+{
+	if (!core->dev)
+		return;
+
+	pm_runtime_put(core->dev);
+}
+
 /***           locking             ***/
 static void clk_prepare_lock(void)
 {
@@ -150,6 +172,8 @@ static void clk_enable_unlock(unsigned long flags)
 
 static bool clk_core_is_prepared(struct clk_core *core)
 {
+	bool status;
+
 	/*
 	 * .is_prepared is optional for clocks that can prepare
 	 * fall back to software usage counter if it is missing
@@ -157,11 +181,20 @@ static bool clk_core_is_prepared(struct clk_core *core)
 	if (!core->ops->is_prepared)
 		return core->prepare_count;
 
-	return core->ops->is_prepared(core->hw);
+	if (clk_pm_runtime_get(core) == 0) {
+		status = core->ops->is_prepared(core->hw);
+		clk_pm_runtime_put(core);
+	} else {
+		status = false;
+	}
+
+	return status;
 }
 
 static bool clk_core_is_enabled(struct clk_core *core)
 {
+	bool status;
+
 	/*
 	 * .is_enabled is only mandatory for clocks that gate
 	 * fall back to software usage counter if .is_enabled is missing
@@ -169,7 +202,30 @@ static bool clk_core_is_enabled(struct clk_core *core)
 	if (!core->ops->is_enabled)
 		return core->enable_count;
 
-	return core->ops->is_enabled(core->hw);
+	/*
+	 * Check if clock controller's device is runtime active before
+	 * calling .is_enabled callback. If not, assume that clock is
+	 * disabled, because we might be called from atomic context, from
+	 * which pm_runtime_get() is not allowed.
+	 * This function is called mainly from clk_disable_unused_subtree,
+	 * which ensures proper runtime pm activation of controller before
+	 * taking enable spinlock, but the below check is needed if one tries
+	 * to call it from other places.
+	 */
+	if (core->dev) {
+		pm_runtime_get_noresume(core->dev);
+		if (!pm_runtime_active(core->dev)) {
+			status = false;
+			goto done;
+		}
+	}
+
+	status = core->ops->is_enabled(core->hw);
+done:
+	if (core->dev)
+		pm_runtime_put(core->dev);
+
+	return status;
 }
 
 /***    helper functions   ***/
@@ -489,6 +545,8 @@ static void clk_core_unprepare(struct clk_core *core)
 	if (core->ops->unprepare)
 		core->ops->unprepare(core->hw);
 
+	clk_pm_runtime_put(core);
+
 	trace_clk_unprepare_complete(core);
 	clk_core_unprepare(core->parent);
 }
@@ -530,10 +588,14 @@ static int clk_core_prepare(struct clk_core *core)
 		return 0;
 
 	if (core->prepare_count == 0) {
-		ret = clk_core_prepare(core->parent);
+		ret = clk_pm_runtime_get(core);
 		if (ret)
 			return ret;
 
+		ret = clk_core_prepare(core->parent);
+		if (ret)
+			goto runtime_put;
+
 		trace_clk_prepare(core);
 
 		if (core->ops->prepare)
@@ -541,15 +603,18 @@ static int clk_core_prepare(struct clk_core *core)
 
 		trace_clk_prepare_complete(core);
 
-		if (ret) {
-			clk_core_unprepare(core->parent);
-			return ret;
-		}
+		if (ret)
+			goto unprepare;
 	}
 
 	core->prepare_count++;
 
 	return 0;
+unprepare:
+	clk_core_unprepare(core->parent);
+runtime_put:
+	clk_pm_runtime_put(core);
+	return ret;
 }
 
 static int clk_core_prepare_lock(struct clk_core *core)
@@ -745,6 +810,9 @@ static void clk_unprepare_unused_subtree(struct clk_core *core)
 	if (core->flags & CLK_IGNORE_UNUSED)
 		return;
 
+	if (clk_pm_runtime_get(core))
+		return;
+
 	if (clk_core_is_prepared(core)) {
 		trace_clk_unprepare(core);
 		if (core->ops->unprepare_unused)
@@ -753,6 +821,8 @@ static void clk_unprepare_unused_subtree(struct clk_core *core)
 			core->ops->unprepare(core->hw);
 		trace_clk_unprepare_complete(core);
 	}
+
+	clk_pm_runtime_put(core);
 }
 
 static void clk_disable_unused_subtree(struct clk_core *core)
@@ -768,6 +838,9 @@ static void clk_disable_unused_subtree(struct clk_core *core)
 	if (core->flags & CLK_OPS_PARENT_ENABLE)
 		clk_core_prepare_enable(core->parent);
 
+	if (clk_pm_runtime_get(core))
+		goto unprepare_out;
+
 	flags = clk_enable_lock();
 
 	if (core->enable_count)
@@ -792,6 +865,8 @@ static void clk_disable_unused_subtree(struct clk_core *core)
 
 unlock_out:
 	clk_enable_unlock(flags);
+	clk_pm_runtime_put(core);
+unprepare_out:
 	if (core->flags & CLK_OPS_PARENT_ENABLE)
 		clk_core_disable_unprepare(core->parent);
 }
@@ -1563,6 +1638,7 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
 {
 	struct clk_core *top, *fail_clk;
 	unsigned long rate = req_rate;
+	int ret = 0;
 
 	if (!core)
 		return 0;
@@ -1579,21 +1655,28 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
 	if (!top)
 		return -EINVAL;
 
+	ret = clk_pm_runtime_get(core);
+	if (ret)
+		return ret;
+
 	/* notify that we are about to change rates */
 	fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE);
 	if (fail_clk) {
 		pr_debug("%s: failed to set %s rate\n", __func__,
 				fail_clk->name);
 		clk_propagate_rate_change(top, ABORT_RATE_CHANGE);
-		return -EBUSY;
+		ret = -EBUSY;
+		goto err;
 	}
 
 	/* change the rates */
 	clk_change_rate(top);
 
 	core->req_rate = req_rate;
+err:
+	clk_pm_runtime_put(core);
 
-	return 0;
+	return ret;
 }
 
 /**
@@ -1824,12 +1907,16 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
 		p_rate = parent->rate;
 	}
 
+	ret = clk_pm_runtime_get(core);
+	if (ret)
+		goto out;
+
 	/* propagate PRE_RATE_CHANGE notifications */
 	ret = __clk_speculate_rates(core, p_rate);
 
 	/* abort if a driver objects */
 	if (ret & NOTIFY_STOP_MASK)
-		goto out;
+		goto runtime_put;
 
 	/* do the re-parent */
 	ret = __clk_set_parent(core, parent, p_index);
@@ -1842,6 +1929,8 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
 		__clk_recalc_accuracies(core);
 	}
 
+runtime_put:
+	clk_pm_runtime_put(core);
 out:
 	clk_prepare_unlock();
 
@@ -2549,6 +2638,8 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
 		goto fail_name;
 	}
 	core->ops = hw->init->ops;
+	if (dev && pm_runtime_enabled(dev))
+		core->dev = dev;
 	if (dev && dev->driver)
 		core->owner = dev->driver->owner;
 	core->hw = hw;
-- 
1.9.1

^ permalink raw reply related

* [PATCH v3 2/5] clock: samsung: add support for runtime pm
From: Marek Szyprowski @ 2016-10-24 12:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477311130-6534-1-git-send-email-m.szyprowski@samsung.com>

This patch adds struct device pointer to samsung_clk_provider and forwarding it
to clk_register_* functions, so drivers can register clocks, which use runtime
pm feature.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/clk/samsung/clk-pll.c |  2 +-
 drivers/clk/samsung/clk.c     | 12 ++++++------
 drivers/clk/samsung/clk.h     |  1 +
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 9617825daabb..f5249a7e545d 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -1345,7 +1345,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	pll->lock_reg = base + pll_clk->lock_offset;
 	pll->con_reg = base + pll_clk->con_offset;
 
-	clk = clk_register(NULL, &pll->hw);
+	clk = clk_register(ctx->dev, &pll->hw);
 	if (IS_ERR(clk)) {
 		pr_err("%s: failed to register pll clock %s : %ld\n",
 			__func__, pll_clk->name, PTR_ERR(clk));
diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
index b7d87d6db9dc..e6923714f024 100644
--- a/drivers/clk/samsung/clk.c
+++ b/drivers/clk/samsung/clk.c
@@ -143,7 +143,7 @@ void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx,
 	unsigned int idx, ret;
 
 	for (idx = 0; idx < nr_clk; idx++, list++) {
-		clk = clk_register_fixed_rate(NULL, list->name,
+		clk = clk_register_fixed_rate(ctx->dev, list->name,
 			list->parent_name, list->flags, list->fixed_rate);
 		if (IS_ERR(clk)) {
 			pr_err("%s: failed to register clock %s\n", __func__,
@@ -172,7 +172,7 @@ void __init samsung_clk_register_fixed_factor(struct samsung_clk_provider *ctx,
 	unsigned int idx;
 
 	for (idx = 0; idx < nr_clk; idx++, list++) {
-		clk = clk_register_fixed_factor(NULL, list->name,
+		clk = clk_register_fixed_factor(ctx->dev, list->name,
 			list->parent_name, list->flags, list->mult, list->div);
 		if (IS_ERR(clk)) {
 			pr_err("%s: failed to register clock %s\n", __func__,
@@ -193,7 +193,7 @@ void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
 	unsigned int idx, ret;
 
 	for (idx = 0; idx < nr_clk; idx++, list++) {
-		clk = clk_register_mux(NULL, list->name, list->parent_names,
+		clk = clk_register_mux(ctx->dev, list->name, list->parent_names,
 			list->num_parents, list->flags,
 			ctx->reg_base + list->offset,
 			list->shift, list->width, list->mux_flags, &ctx->lock);
@@ -226,13 +226,13 @@ void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
 
 	for (idx = 0; idx < nr_clk; idx++, list++) {
 		if (list->table)
-			clk = clk_register_divider_table(NULL, list->name,
+			clk = clk_register_divider_table(ctx->dev, list->name,
 				list->parent_name, list->flags,
 				ctx->reg_base + list->offset,
 				list->shift, list->width, list->div_flags,
 				list->table, &ctx->lock);
 		else
-			clk = clk_register_divider(NULL, list->name,
+			clk = clk_register_divider(ctx->dev, list->name,
 				list->parent_name, list->flags,
 				ctx->reg_base + list->offset, list->shift,
 				list->width, list->div_flags, &ctx->lock);
@@ -264,7 +264,7 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
 	unsigned int idx, ret;
 
 	for (idx = 0; idx < nr_clk; idx++, list++) {
-		clk = clk_register_gate(NULL, list->name, list->parent_name,
+		clk = clk_register_gate(ctx->dev, list->name, list->parent_name,
 				list->flags, ctx->reg_base + list->offset,
 				list->bit_idx, list->gate_flags, &ctx->lock);
 		if (IS_ERR(clk)) {
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index da3bdebabf1e..9263d8a27c6b 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -26,6 +26,7 @@
  */
 struct samsung_clk_provider {
 	void __iomem *reg_base;
+	struct device *dev;
 	struct clk_onecell_data clk_data;
 	spinlock_t lock;
 };
-- 
1.9.1

^ permalink raw reply related

* [PATCH v3 3/5] clocks: exynos4x12: add runtime pm support for ISP clocks
From: Marek Szyprowski @ 2016-10-24 12:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477311130-6534-1-git-send-email-m.szyprowski@samsung.com>

Exynos4412 clock controller contains some additional clocks for FIMC-ISP
(Camera ISP) subsystem. Registers for those clocks are partially located
in the SOC area, which belongs to ISP power domain.

This patch implements integration of ISP clocks with ISP power domain
by using runtime pm feature of clocks core. This finally solves all the
mysterious freezes in accessing ISP clocks when ISP power domain is disabled.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 .../devicetree/bindings/clock/exynos4-clock.txt    |  22 +++
 drivers/clk/samsung/clk-exynos4.c                  | 211 +++++++++++++++------
 2 files changed, 172 insertions(+), 61 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
index f5a5b19ed3b2..429dd7e420e4 100644
--- a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
+++ b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
@@ -41,3 +41,25 @@ Example 2: UART controller node that consumes the clock generated by the clock
 		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
 		clock-names = "uart", "clk_uart_baud0";
 	};
+
+Exynos4412 clock controller contains some additional clocks for FIMC-ISP
+(Camera ISP) subsystem. Registers for those clocks are partially located
+in the SOC area, which belongs to ISP power domain. To properly handle
+additional ISP clocks and their integration with power domains, an
+additional subnode "isp-clock-controller" with "samsung,exynos4412-isp-clock"
+compatible has to be defined under the main Exynos4 clock node. This subnode
+can be then used for linking with respective ISP power domain (for more
+information, see Samsung Exynos power domains bindings).
+
+Example 3: An example of a clock controller for Exynos4412 with ISP clocks.
+
+	clock: clock-controller at 10030000 {
+		compatible = "samsung,exynos4412-clock";
+		reg = <0x10030000 0x20000>;
+		#clock-cells = <1>;
+
+		isp-clock-controller {
+			compatible = "samsung,exynos4412-isp-clock";
+			power-domains = <&pd_isp>;
+		};
+	};
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index faab9b31baf5..e5165be348ef 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -16,7 +16,10 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_platform.h>
 #include <linux/syscore_ops.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 
 #include "clk.h"
 #include "clk-cpu.h"
@@ -123,6 +126,8 @@
 #define CLKOUT_CMU_CPU		0x14a00
 #define PWR_CTRL1		0x15020
 #define E4X12_PWR_CTRL2		0x15024
+
+/* Exynos4x12 specific registers, which belong to ISP power domain */
 #define E4X12_DIV_ISP0		0x18300
 #define E4X12_DIV_ISP1		0x18304
 #define E4X12_GATE_ISP0		0x18800
@@ -156,6 +161,8 @@ enum exynos4_plls {
 
 static void __iomem *reg_base;
 static enum exynos4_soc exynos4_soc;
+static struct samsung_clk_provider *exynos4412_ctx;
+static struct device_node *exynos4412_clk_node;
 
 /*
  * Support for CMU save/restore across system suspends
@@ -164,6 +171,7 @@ enum exynos4_plls {
 static struct samsung_clk_reg_dump *exynos4_save_common;
 static struct samsung_clk_reg_dump *exynos4_save_soc;
 static struct samsung_clk_reg_dump *exynos4_save_pll;
+static struct samsung_clk_reg_dump *exynos4x12_save_isp;
 
 /*
  * list of controller registers to be saved and restored during a
@@ -192,6 +200,13 @@ enum exynos4_plls {
 	E4X12_PWR_CTRL2,
 };
 
+static const unsigned long exynos4x12_clk_isp_save[] __initconst = {
+	E4X12_DIV_ISP0,
+	E4X12_DIV_ISP1,
+	E4X12_GATE_ISP0,
+	E4X12_GATE_ISP1,
+};
+
 static const unsigned long exynos4_clk_pll_regs[] __initconst = {
 	EPLL_LOCK,
 	VPLL_LOCK,
@@ -822,20 +837,21 @@ static void __init exynos4_clk_sleep_init(void) {}
 	DIV(0, "div_spi1_isp", "mout_spi1_isp", E4X12_DIV_ISP, 16, 4),
 	DIV(0, "div_spi1_isp_pre", "div_spi1_isp", E4X12_DIV_ISP, 20, 8),
 	DIV(0, "div_uart_isp", "mout_uart_isp", E4X12_DIV_ISP, 28, 4),
-	DIV_F(CLK_DIV_ISP0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3,
-						CLK_GET_RATE_NOCACHE, 0),
-	DIV_F(CLK_DIV_ISP1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3,
-						CLK_GET_RATE_NOCACHE, 0),
-	DIV(0, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3),
-	DIV_F(CLK_DIV_MCUISP0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1,
-						4, 3, CLK_GET_RATE_NOCACHE, 0),
-	DIV_F(CLK_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1,
-						8, 3, CLK_GET_RATE_NOCACHE, 0),
 	DIV(CLK_SCLK_FIMG2D, "sclk_fimg2d", "mout_g2d", DIV_DMC1, 0, 4),
 	DIV(CLK_DIV_C2C, "div_c2c", "mout_c2c", DIV_DMC1, 4, 3),
 	DIV(0, "div_c2c_aclk", "div_c2c", DIV_DMC1, 12, 3),
 };
 
+static struct samsung_div_clock exynos4x12_isp_div_clks[] = {
+	DIV_F(CLK_DIV_ISP0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3, 0, 0),
+	DIV_F(CLK_DIV_ISP1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3, 0, 0),
+	DIV_F(CLK_DIV_MCUISP0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1,
+						4, 3, 0, 0),
+	DIV_F(CLK_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1,
+						8, 3, 0, 0),
+	DIV_F(0, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3, 0, 0),
+};
+
 /* list of gate clocks supported in all exynos4 soc's */
 static const struct samsung_gate_clock exynos4_gate_clks[] __initconst = {
 	/*
@@ -1132,64 +1148,41 @@ static void __init exynos4_clk_sleep_init(void) {}
 			0, 0),
 	GATE(CLK_I2S0, "i2s0", "aclk100", E4X12_GATE_IP_MAUDIO, 3,
 			0, 0),
-	GATE(CLK_FIMC_ISP, "isp", "aclk200", E4X12_GATE_ISP0, 0,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_FIMC_DRC, "drc", "aclk200", E4X12_GATE_ISP0, 1,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_FIMC_FD, "fd", "aclk200", E4X12_GATE_ISP0, 2,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_FIMC_LITE0, "lite0", "aclk200", E4X12_GATE_ISP0, 3,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_FIMC_LITE1, "lite1", "aclk200", E4X12_GATE_ISP0, 4,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_MCUISP, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_GICISP, "gicisp", "aclk200", E4X12_GATE_ISP0, 7,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_SMMU_ISP, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_SMMU_DRC, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_SMMU_FD, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_SMMU_LITE0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_SMMU_LITE1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_PPMUISPMX, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_PPMUISPX, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_MCUCTL_ISP, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_MPWM_ISP, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_I2C0_ISP, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_I2C1_ISP, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_MTCADC_ISP, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_PWM_ISP, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_WDT_ISP, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_UART_ISP, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_ASYNCAXIM, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_SMMU_ISPCX, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_SPI0_ISP, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-	GATE(CLK_SPI1_ISP, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13,
-			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(CLK_G2D, "g2d", "aclk200", GATE_IP_DMC, 23, 0, 0),
 	GATE(CLK_SMMU_G2D, "smmu_g2d", "aclk200", GATE_IP_DMC, 24, 0, 0),
 	GATE(CLK_TMU_APBIF, "tmu_apbif", "aclk100", E4X12_GATE_IP_PERIR, 17, 0,
 		0),
 };
 
+static struct samsung_gate_clock exynos4x12_isp_gate_clks[] = {
+	GATE(CLK_FIMC_ISP, "isp", "aclk200", E4X12_GATE_ISP0, 0, 0, 0),
+	GATE(CLK_FIMC_DRC, "drc", "aclk200", E4X12_GATE_ISP0, 1, 0, 0),
+	GATE(CLK_FIMC_FD, "fd", "aclk200", E4X12_GATE_ISP0, 2, 0, 0),
+	GATE(CLK_FIMC_LITE0, "lite0", "aclk200", E4X12_GATE_ISP0, 3, 0, 0),
+	GATE(CLK_FIMC_LITE1, "lite1", "aclk200", E4X12_GATE_ISP0, 4, 0, 0),
+	GATE(CLK_MCUISP, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5, 0, 0),
+	GATE(CLK_GICISP, "gicisp", "aclk200", E4X12_GATE_ISP0, 7, 0, 0),
+	GATE(CLK_SMMU_ISP, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8, 0, 0),
+	GATE(CLK_SMMU_DRC, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9, 0, 0),
+	GATE(CLK_SMMU_FD, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10, 0, 0),
+	GATE(CLK_SMMU_LITE0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11, 0, 0),
+	GATE(CLK_SMMU_LITE1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12, 0, 0),
+	GATE(CLK_PPMUISPMX, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20, 0, 0),
+	GATE(CLK_PPMUISPX, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21, 0, 0),
+	GATE(CLK_MCUCTL_ISP, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23, 0, 0),
+	GATE(CLK_MPWM_ISP, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24, 0, 0),
+	GATE(CLK_I2C0_ISP, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25, 0, 0),
+	GATE(CLK_I2C1_ISP, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26, 0, 0),
+	GATE(CLK_MTCADC_ISP, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27, 0, 0),
+	GATE(CLK_PWM_ISP, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28, 0, 0),
+	GATE(CLK_WDT_ISP, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30, 0, 0),
+	GATE(CLK_UART_ISP, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31, 0, 0),
+	GATE(CLK_ASYNCAXIM, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0, 0, 0),
+	GATE(CLK_SMMU_ISPCX, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4, 0, 0),
+	GATE(CLK_SPI0_ISP, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12, 0, 0),
+	GATE(CLK_SPI1_ISP, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13, 0, 0),
+};
+
 static const struct samsung_clock_alias exynos4_aliases[] __initconst = {
 	ALIAS(CLK_MOUT_CORE, NULL, "moutcore"),
 	ALIAS(CLK_ARM_CLK, NULL, "armclk"),
@@ -1438,6 +1431,100 @@ static void __init exynos4x12_core_down_clock(void)
 	{  0 },
 };
 
+static int exynos4x12_isp_clk_suspend(struct device *dev)
+{
+	samsung_clk_save(reg_base, exynos4x12_save_isp,
+				ARRAY_SIZE(exynos4x12_clk_isp_save));
+	return 0;
+}
+
+static int exynos4x12_isp_clk_resume(struct device *dev)
+{
+	samsung_clk_restore(reg_base, exynos4x12_save_isp,
+				ARRAY_SIZE(exynos4x12_clk_isp_save));
+	return 0;
+}
+
+static int __init exynos4x12_isp_clk_probe(struct platform_device *pdev)
+{
+	struct samsung_clk_provider *ctx = exynos4412_ctx;
+
+	if (!ctx)
+		return -ENODEV;
+
+	exynos4x12_save_isp = samsung_clk_alloc_reg_dump(exynos4x12_clk_isp_save,
+					ARRAY_SIZE(exynos4x12_clk_isp_save));
+	if (!exynos4x12_save_isp)
+		return -ENOMEM;
+
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	ctx->dev = &pdev->dev;
+
+	samsung_clk_register_div(ctx, exynos4x12_isp_div_clks,
+		ARRAY_SIZE(exynos4x12_isp_div_clks));
+	samsung_clk_register_gate(ctx, exynos4x12_isp_gate_clks,
+		ARRAY_SIZE(exynos4x12_isp_gate_clks));
+
+	return 0;
+}
+
+static const struct of_device_id exynos4x12_isp_clk_of_match[] = {
+	{ .compatible = "samsung,exynos4412-isp-clock", },
+	{ },
+};
+
+static const struct dev_pm_ops exynos4x12_isp_pm_ops = {
+	SET_RUNTIME_PM_OPS(exynos4x12_isp_clk_suspend,
+			   exynos4x12_isp_clk_resume, NULL)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				     pm_runtime_force_resume)
+};
+
+static struct platform_driver exynos4x12_isp_clk_driver __refdata = {
+	.driver	= {
+		.name = "exynos-isp-clk",
+		.of_match_table = exynos4x12_isp_clk_of_match,
+		.suppress_bind_attrs = true,
+		.pm = &exynos4x12_isp_pm_ops,
+	},
+	.probe = exynos4x12_isp_clk_probe,
+};
+
+static int __init exynos4x12_isp_clk_init(void)
+{
+	if (!exynos4412_clk_node)
+		return 0;
+
+	of_platform_populate(exynos4412_clk_node, NULL, NULL, NULL);
+	return platform_driver_register(&exynos4x12_isp_clk_driver);
+}
+arch_initcall(exynos4x12_isp_clk_init);
+
+static void __init exynos4x12_isp_defer_clocks(struct samsung_clk_provider *ctx,
+					       struct device_node *parent)
+{
+	struct device_node *np = of_get_next_available_child(parent, NULL);
+	if (!np)
+		return;
+
+	if (of_device_is_compatible(np,
+		    exynos4x12_isp_clk_of_match[0].compatible)) {
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(exynos4x12_isp_div_clks); i++)
+			samsung_clk_add_lookup(ctx, ERR_PTR(-EPROBE_DEFER),
+					       exynos4x12_isp_div_clks[i].id);
+		for (i = 0; i < ARRAY_SIZE(exynos4x12_isp_gate_clks); i++)
+			samsung_clk_add_lookup(ctx, ERR_PTR(-EPROBE_DEFER),
+					       exynos4x12_isp_gate_clks[i].id);
+		exynos4412_ctx = ctx;
+		exynos4412_clk_node = parent;
+	}
+	of_node_put(np);
+}
+
 /* register exynos4 clocks */
 static void __init exynos4_clk_init(struct device_node *np,
 				    enum exynos4_soc soc)
@@ -1529,6 +1616,8 @@ static void __init exynos4_clk_init(struct device_node *np,
 		samsung_clk_register_fixed_factor(ctx,
 			exynos4x12_fixed_factor_clks,
 			ARRAY_SIZE(exynos4x12_fixed_factor_clks));
+		exynos4x12_isp_defer_clocks(ctx, np);
+
 		if (of_machine_is_compatible("samsung,exynos4412")) {
 			exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
 				mout_core_p4x12[0], mout_core_p4x12[1], 0x14200,
-- 
1.9.1

^ permalink raw reply related

* [PATCH v3 4/5] ARM: dts: exynos: add support for ISP power domain to exynos4x12 clocks device
From: Marek Szyprowski @ 2016-10-24 12:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477311130-6534-1-git-send-email-m.szyprowski@samsung.com>

Exynos4412 clock controller contains some additional clocks for FIMC-ISP
(Camera ISP) subsystem. Registers for those clocks are partially located
in the SOC area, which belongs to ISP power domain.

This patch implements integration of ISP clocks with ISP power domain.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos4x12.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index 0074f566cd3b..5667fd33dc98 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -74,6 +74,11 @@
 		compatible = "samsung,exynos4412-clock";
 		reg = <0x10030000 0x20000>;
 		#clock-cells = <1>;
+
+		isp-clock-controller {
+			compatible = "samsung,exynos4412-isp-clock";
+			power-domains = <&pd_isp>;
+		};
 	};
 
 	mct at 10050000 {
-- 
1.9.1

^ permalink raw reply related


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