Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v3 1/2] spi:fsl-dspi:convert to use regmap and big-endian supports
From: Alexander Shiyan @ 2014-02-11  6:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392097697-14919-1-git-send-email-b44548@freescale.com>

???????, 11 ??????? 2014, 13:48 +08:00 ?? Chao Fu <b44548@freescale.com>:
> From: Chao Fu <B44548@freescale.com>
> 
> Freescale DSPI module will have two endianess in different platform,
> but ARM is little endian. So when DSPI in big endian, core in little endian,
> readl and writel can not adjust R/W register in this condition.
> This patch will remove general readl/writel, and import regmap mechanism.
> Data endian will be transfered in regmap APIs.

In this case You should additionally select REGMAP_MMIO option
for SPI_FSL_DSPI in the drivers/spi/Kconfig.

---

^ permalink raw reply

* [PATCH] ARM: imx: avoid calling clk APIs in idle thread which may cause schedule
From: Anson Huang @ 2014-02-11  8:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140211061833.GD31484@S2101-09.ap.freescale.net>

On Tue, Feb 11, 2014 at 02:18:35PM +0800, Shawn Guo wrote:
> On Mon, Feb 10, 2014 at 02:34:50PM +0800, Anson Huang wrote:
> > @@ -81,19 +99,67 @@ static const u32 clks_init_on[] __initconst = {
> >   * entering WAIT mode.
> >   *
> >   * This function will set the ARM clk to max value within the 12:5 limit.
> > + * As IPG clock is fixed at 66MHz(so ARM freq must not exceed 158.4MHz),
> > + * ARM freq are one of below setpoints: 396MHz, 792MHz and 996MHz, since
> > + * the clk APIs can NOT be called in idle thread(may cause kernel schedule
> > + * as there is sleep function in PLL wait function), so here we just slow
> > + * down ARM to below freq according to previous freq:
> > + *
> > + * run mode      wait mode
> > + * 396MHz   ->   132MHz;
> > + * 792MHz   ->   158.4MHz;
> > + * 996MHz   ->   142.3MHz;
> >   */
> > +static int imx6sl_get_arm_divider_for_wait(void)
> > +{
> > +	if (readl_relaxed(ccm_base + CCSR) & BM_CCSR_PLL1_SW_CLK_SEL) {
> > +		return ARM_WAIT_DIV_396M;
> > +	} else {
> > +		if ((readl_relaxed(anatop_base + PLL_ARM) &
> > +			BM_PLL_ARM_DIV_SELECT) == PLL_ARM_DIV_792M)
> > +			return ARM_WAIT_DIV_792M;
> > +		else
> > +			return ARM_WAIT_DIV_996M;
> > +	}
> > +}
> > +
> > +static void imx6sl_enable_pll_arm(bool enable)
> > +{
> > +	static u32 saved_pll_arm;
> > +	u32 val;
> > +
> > +	if (enable) {
> > +		saved_pll_arm = val = readl_relaxed(anatop_base + PLL_ARM);
> > +		val |= BM_PLL_ARM_ENABLE;
> > +		val &= ~BM_PLL_ARM_POWERDOWN;
> > +		writel_relaxed(val, anatop_base + PLL_ARM);
> > +		while (!(__raw_readl(anatop_base + PLL_ARM) & BM_PLL_ARM_LOCK))
> > +			;
> > +	} else {
> > +		 writel_relaxed(saved_pll_arm, anatop_base + PLL_ARM);
> > +	}
> > +}
> > +
> >  void imx6sl_set_wait_clk(bool enter)
> >  {
> > -	static unsigned long saved_arm_rate;
> > +	static unsigned long saved_arm_div;
> >  
> > +	/*
> > +	 * According to hardware design, arm podf change need
> > +	 * PLL1 clock enabled.
> > +	 */
> > +	imx6sl_enable_pll_arm(true);
> 
> This only applies to the ARM_WAIT_DIV_396M case, since for the other two
> PLL1 must already be enabled, right?

Yes, I will add condition check to make sure it is only called when ARM is
@396MHz.

> 
> >  	if (enter) {
> > -		unsigned long ipg_rate = clk_get_rate(clks[IMX6SL_CLK_IPG]);
> > -		unsigned long max_arm_wait_rate = (12 * ipg_rate) / 5;
> > -		saved_arm_rate = clk_get_rate(clks[IMX6SL_CLK_ARM]);
> > -		clk_set_rate(clks[IMX6SL_CLK_ARM], max_arm_wait_rate);
> > +		saved_arm_div = readl_relaxed(ccm_base + CACRR);
> > +		writel_relaxed(imx6sl_get_arm_divider_for_wait(),
> > +			ccm_base + CACRR);
> >  	} else {
> > -		clk_set_rate(clks[IMX6SL_CLK_ARM], saved_arm_rate);
> > +		writel_relaxed(saved_arm_div, ccm_base + CACRR);
> >  	}
> > +
> > +	while (__raw_readl(ccm_base + CDHIPR) & BM_CDHIPR_ARM_PODF_BUSY)
> > +		;
> > +	imx6sl_enable_pll_arm(false);
> >  }
> >  
> >  static void __init imx6sl_clocks_init(struct device_node *ccm_node)
> > @@ -110,6 +176,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
> >  
> >  	np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop");
> >  	base = of_iomap(np, 0);
> > +	anatop_base = base;
> 
> More logical to put it after the WARN_ON() below?
> 
> >  	WARN_ON(!base);
> >  
> >  	/*                                             type               name            parent  base         div_mask */
> > @@ -157,6 +224,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
> >  
> >  	np = ccm_node;
> >  	base = of_iomap(np, 0);
> > +	ccm_base = base;
> 
> Ditto.

Will improve it in V2, thanks.

Anson.

> 
> Shawn
> 
> >  	WARN_ON(!base);
> >  
> >  	/* Reuse imx6q pm code */
> > -- 
> > 1.7.9.5
> > 
> > 
> 

^ permalink raw reply

* [PATCH 1/4] arm64: topology: Implement basic CPU topology support
From: Vincent Guittot @ 2014-02-11  8:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140210164647.GB13533@sirena.org.uk>

On 10 February 2014 17:46, Mark Brown <broonie@kernel.org> wrote:
> On Mon, Feb 10, 2014 at 04:22:31PM +0000, Catalin Marinas wrote:
>> On Mon, Feb 10, 2014 at 01:02:01PM +0000, Mark Brown wrote:
>
>> > +           if (cpu != cpuid)
>> > +                   cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
>> > +   }
>> > +   smp_wmb();
>
>> I now noticed there are a couple of smp_wmb() calls in this patch. What
>> are they for?
>
> To be honest I mostly cargo culted them from the ARM implementation; I
> did look a bit but didn't fully dig into it - it seemed they were
> required to ensure that the updates for the new CPU are visible over all
> CPUs.  Vincent?

Yes that's it. we must ensure that updates are made visible to other CPUs

^ permalink raw reply

* [RFC PATCH] arm64: add support for AES in CCM mode using Crypto Extensions
From: Ard Biesheuvel @ 2014-02-11  8:21 UTC (permalink / raw)
  To: linux-arm-kernel

This adds support for a synchronous implementation of AES in CCM mode
using ARMv8 Crypto Extensions, using NEON registers q0 - q5.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
Hi all,

I am posting this for review/RFC. The main topic for feedback is the way
I have used an inner blkcipher instance to process the encrypted + authenticated
data.

The point of having a dedicated module for synchronous ccm(aes) is the fact that
mac80211 uses it for WPA2 CCMP en-/decryption, where it runs entirely in soft
IRQ context. In this case, the performance improvement offered by dedicated AES
instructions is likely wasted on stacking and unstacking the NEON register file,
as the generic CCM operates on a single AES block at a time.

Instead, this implementation interleaves the CTR and CBC modes at the round
level, eliminating 50% of both the input and round key loads and (hopefully)
eliminating pipeline stalls by operating on two AES blocks at a time.

Tested with tcrypt, no performance numbers yet.

-- 
Ard.


 arch/arm64/Makefile                |   1 +
 arch/arm64/crypto/Makefile         |  12 ++
 arch/arm64/crypto/aesce-ccm-core.S | 222 +++++++++++++++++++++
 arch/arm64/crypto/aesce-ccm-glue.c | 387 +++++++++++++++++++++++++++++++++++++
 4 files changed, 622 insertions(+)
 create mode 100644 arch/arm64/crypto/Makefile
 create mode 100644 arch/arm64/crypto/aesce-ccm-core.S
 create mode 100644 arch/arm64/crypto/aesce-ccm-glue.c

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index e0b75464b7f1..a4b3e253557d 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -46,6 +46,7 @@ core-y		+= arch/arm64/emu/
 core-y		+= arch/arm64/kernel/ arch/arm64/mm/
 core-$(CONFIG_KVM) += arch/arm64/kvm/
 core-$(CONFIG_XEN) += arch/arm64/xen/
+core-$(CONFIG_CRYPTO) += arch/arm64/crypto/
 libs-y		:= arch/arm64/lib/ $(libs-y)
 libs-y		+= $(LIBGCC)
 
diff --git a/arch/arm64/crypto/Makefile b/arch/arm64/crypto/Makefile
new file mode 100644
index 000000000000..ba10ebb53e9e
--- /dev/null
+++ b/arch/arm64/crypto/Makefile
@@ -0,0 +1,12 @@
+#
+# linux/arch/arm64/crypto/Makefile
+#
+# Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+
+aesce-ccm-y	:= aesce-ccm-glue.o aesce-ccm-core.o
+obj-m		+= aesce-ccm.o
diff --git a/arch/arm64/crypto/aesce-ccm-core.S b/arch/arm64/crypto/aesce-ccm-core.S
new file mode 100644
index 000000000000..f808c17eac45
--- /dev/null
+++ b/arch/arm64/crypto/aesce-ccm-core.S
@@ -0,0 +1,222 @@
+/*
+ * linux/arch/arm64/crypto/aesce-ccm-core.S - AES-CCM transform for
+ *                                            ARMv8 with Crypto Extensions
+ *
+ * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+
+	.text
+	.arch	armv8-a+crypto
+
+	/*
+	 * void ce_aes_ccm_auth_data(u8 mac[], u8 const in[], u32 abytes,
+	 *			     u32 *macp, u8 const rk[], u32 rounds);
+	 */
+ENTRY(ce_aes_ccm_auth_data)
+	ldr	w8, [x3]			/* leftover from prev round? */
+	ld1	{v0.2d}, [x0]			/* load mac */
+	cbz	w8, 1f
+	sub	w8, w8, #16
+	eor	v1.16b, v1.16b, v1.16b
+0:	ldrb	w7, [x1], #1			/* get 1 byte of input */
+	subs	w2, w2, #1
+	add	w8, w8, #1
+	ins	v1.b[0], w7
+	ext	v1.16b, v1.16b, v1.16b, #1	/* rotate in the input bytes */
+	beq	8f				/* out of input? */
+	cbnz	w8, 0b
+	eor	v0.16b, v0.16b, v1.16b
+1:	ld1	{v3.2d}, [x4]			/* load first round key */
+	prfm	pldl1strm, [x1]
+	cmp	w5, #12				/* which key size? */
+	add	x6, x4, #16
+	sub	w7, w5, #2			/* modified # of rounds */
+	bmi	2f
+	bne	5f
+	mov	v5.16b, v3.16b
+	b	4f
+2:	mov	v4.16b, v3.16b
+	ld1	{v5.2d}, [x6], #16		/* load 2nd round key */
+3:	aese	v0.16b, v4.16b
+	aesmc	v0.16b, v0.16b
+4:	ld1	{v3.2d}, [x6], #16		/* load next round key */
+	aese	v0.16b, v5.16b
+	aesmc	v0.16b, v0.16b
+5:	ld1	{v4.2d}, [x6], #16		/* load next round key */
+	subs	w7, w7, #3
+	aese	v0.16b, v3.16b
+	aesmc	v0.16b, v0.16b
+	ld1	{v5.2d}, [x6], #16		/* load next round key */
+	bpl	3b
+	aese	v0.16b, v4.16b
+	subs	w2, w2, #16			/* last data? */
+	eor	v0.16b, v0.16b, v5.16b		/* final round */
+	bmi	6f
+	ld1	{v1.16b}, [x1], #16		/* load next input block */
+	eor	v0.16b, v0.16b, v1.16b		/* xor with mac */
+	bne	1b
+6:	st1	{v0.2d}, [x0]			/* store mac */
+	beq	10f
+	adds	w2, w2, #16
+	beq	10f
+	mov	w8, w2
+7:	ldrb	w7, [x1], #1
+	umov	w6, v0.b[0]
+	eor	w6, w6, w7
+	strb	w6, [x0], #1
+	subs	w2, w2, #1
+	beq	10f
+	ext	v0.16b, v0.16b, v0.16b, #1	/* rotate out the mac bytes */
+	b	7b
+8:	mov	w7, w8
+	add	w8, w8, #16
+9:	ext	v1.16b, v1.16b, v1.16b, #1
+	adds	w7, w7, #1
+	bne	9b
+	eor	v0.16b, v0.16b, v1.16b
+	st1	{v0.2d}, [x0]
+10:	str	w8, [x3]
+	ret
+ENDPROC(ce_aes_ccm_auth_data)
+
+	/*
+	 * void ce_aes_ccm_final(u8 mac[], u8 const ctr[], u8 const rk[],
+	 * 			 u32 rounds);
+	 */
+ENTRY(ce_aes_ccm_final)
+	ld1	{v3.2d}, [x2], #16		/* load first round key */
+	ld1	{v0.2d}, [x0]			/* load mac */
+	cmp	w3, #12				/* which key size? */
+	sub	w3, w3, #2			/* modified # of rounds */
+	ld1	{v1.2d}, [x1]			/* load 1st ctriv */
+	bmi	0f
+	bne	3f
+	mov	v5.16b, v3.16b
+	b	2f
+0:	mov	v4.16b, v3.16b
+1:	ld1	{v5.2d}, [x2], #16		/* load next round key */
+	aese	v0.16b, v4.16b
+	aesmc	v0.16b, v0.16b
+	aese	v1.16b, v4.16b
+	aesmc	v1.16b, v1.16b
+2:	ld1	{v3.2d}, [x2], #16		/* load next round key */
+	aese	v0.16b, v5.16b
+	aesmc	v0.16b, v0.16b
+	aese	v1.16b, v5.16b
+	aesmc	v1.16b, v1.16b
+3:	ld1	{v4.2d}, [x2], #16		/* load next round key */
+	subs	w3, w3, #3
+	aese	v0.16b, v3.16b
+	aesmc	v0.16b, v0.16b
+	aese	v1.16b, v3.16b
+	aesmc	v1.16b, v1.16b
+	bpl	1b
+	aese	v0.16b, v4.16b
+	aese	v1.16b, v4.16b
+	/* final round key cancels out */
+	eor	v0.16b, v0.16b, v1.16b		/* en-/decrypt the mac */
+	st1	{v0.2d}, [x0]			/* store result */
+	ret
+ENDPROC(ce_aes_ccm_final)
+
+	.macro	aes_ccm_do_crypt,enc
+	ldr	x8, [x6, #8]			/* load lower ctr */
+	ld1	{v0.2d}, [x5]			/* load mac */
+	rev	x8, x8				/* keep swabbed ctr in reg */
+0:	/* outer loop */
+	ld1	{v1.1d}, [x6]			/* load upper ctr */
+	prfm	pldl1strm, [x1]
+	add	x8, x8, #1
+	rev	x9, x8
+	cmp	w4, #12				/* which key size? */
+	sub	w7, w4, #2			/* get modified # of rounds */
+	ins	v1.d[1], x9			/* no carry in lower ctr */
+	ld1	{v3.2d}, [x3]			/* load first round key */
+	add	x10, x3, #16
+	bmi	1f
+	bne	4f
+	mov	v5.16b, v3.16b
+	b	3f
+1:	mov	v4.16b, v3.16b
+	ld1	{v5.2d}, [x10], #16		/* load 2nd round key */
+2:	/* inner loop: 3 rounds, 2x interleaved */
+	aese	v0.16b, v4.16b
+	aesmc	v0.16b, v0.16b
+	aese	v1.16b, v4.16b
+	aesmc	v1.16b, v1.16b
+3:	ld1	{v3.2d}, [x10], #16		/* load next round key */
+	aese	v0.16b, v5.16b
+	aesmc	v0.16b, v0.16b
+	aese	v1.16b, v5.16b
+	aesmc	v1.16b, v1.16b
+4:	ld1	{v4.2d}, [x10], #16		/* load next round key */
+	subs	w7, w7, #3
+	aese	v0.16b, v3.16b
+	aesmc	v0.16b, v0.16b
+	aese	v1.16b, v3.16b
+	aesmc	v1.16b, v1.16b
+	ld1	{v5.2d}, [x10], #16		/* load next round key */
+	bpl	2b
+	aese	v0.16b, v4.16b
+	aese	v1.16b, v4.16b
+	subs	w2, w2, #16
+	bmi	5f
+	ld1	{v2.16b}, [x1], #16		/* load next input block */
+	.if	\enc == 1
+	eor	v2.16b, v2.16b, v5.16b		/* final round enc+mac */
+	eor	v1.16b, v1.16b, v2.16b		/* xor with crypted ctr */
+	.else
+	eor	v2.16b, v2.16b, v1.16b		/* xor with crypted ctr */
+	eor	v1.16b, v2.16b, v5.16b		/* final round enc */
+	.endif
+	eor	v0.16b, v0.16b, v2.16b		/* xor mac with pt ^ rk[last] */
+	st1	{v1.16b}, [x0], #16		/* write output block */
+	bne	0b
+5:	eor	v0.16b, v0.16b, v5.16b		/* final round mac */
+	eor	v1.16b, v1.16b, v5.16b		/* final round enc */
+	st1	{v0.2d}, [x5]			/* store mac */
+	beq	7f
+	add	w2, w2, #16			/* process partial tail block */
+6:	ldrb	w9, [x1], #1			/* get 1 byte of input */
+	umov	w6, v1.b[0]			/* get top crypted ctr byte */
+	umov	w7, v0.b[0]			/* get top mac byte */
+	.if	\enc == 1
+	eor	w7, w7, w9
+	eor	w9, w9, w6
+	.else
+	eor	w9, w9, w6
+	eor	w7, w7, w9
+	.endif
+	strb	w9, [x0], #1			/* store out byte */
+	strb	w7, [x5], #1			/* store mac byte */
+	subs	w2, w2, #1
+	beq	8f
+	ext	v0.16b, v0.16b, v0.16b, #1	/* shift out mac byte */
+	ext	v1.16b, v1.16b, v1.16b, #1	/* shift out ctr byte */
+	b	6b
+7:	rev	x8, x8
+	str	x8, [x6, #8]			/* store lsb end of ctr (BE) */
+8:	ret
+	.endm
+
+	/*
+	 * void ce_aes_ccm_encrypt(u8 out[], u8 const in[], u32 cbytes,
+	 * 			   u8 const rk[], u32 rounds, u8 mac[],
+	 * 			   u8 ctr[]);
+	 * void ce_aes_ccm_decrypt(u8 out[], u8 const in[], u32 cbytes,
+	 * 			   u8 const rk[], u32 rounds, u8 mac[],
+	 * 			   u8 ctr[]);
+	 */
+ENTRY(ce_aes_ccm_encrypt)
+	aes_ccm_do_crypt	1
+ENDPROC(ce_aes_ccm_encrypt)
+
+ENTRY(ce_aes_ccm_decrypt)
+	aes_ccm_do_crypt	0
+ENDPROC(ce_aes_ccm_decrypt)
diff --git a/arch/arm64/crypto/aesce-ccm-glue.c b/arch/arm64/crypto/aesce-ccm-glue.c
new file mode 100644
index 000000000000..153a40f43a6e
--- /dev/null
+++ b/arch/arm64/crypto/aesce-ccm-glue.c
@@ -0,0 +1,387 @@
+/*
+ * linux/arch/arm64/crypto/aes-ccm-glue.c
+ *
+ * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <asm/neon.h>
+#include <asm/unaligned.h>
+#include <crypto/aes.h>
+#include <crypto/algapi.h>
+#include <crypto/scatterwalk.h>
+#include <linux/crypto.h>
+#include <linux/module.h>
+
+struct crypto_ccm_aes_ctx {
+	struct crypto_aes_ctx	*key;
+	struct crypto_blkcipher	*blk_tfm;
+};
+
+static int num_rounds(struct crypto_aes_ctx *ctx)
+{
+	/*
+	 * # of rounds specified by AES:
+	 * 128 bit key		10 rounds
+	 * 192 bit key		12 rounds
+	 * 256 bit key		14 rounds
+	 * => n byte key	=> 6 + (n/4) rounds
+	 */
+	return 6 + ctx->key_length / 4;
+}
+
+asmlinkage void ce_aes_ccm_auth_data(u8 mac[], u8 const in[], u32 abytes,
+				     u32 *macp, u32 const rk[], u32 rounds);
+
+asmlinkage void ce_aes_ccm_encrypt(u8 out[], u8 const in[], u32 cbytes,
+				   u32 const rk[], u32 rounds, u8 mac[],
+				   u8 ctr[]);
+
+asmlinkage void ce_aes_ccm_decrypt(u8 out[], u8 const in[], u32 cbytes,
+				   u32 const rk[], u32 rounds, u8 mac[],
+				   u8 ctr[]);
+
+asmlinkage void ce_aes_ccm_final(u8 mac[], u8 const ctr[], u32 const rk[],
+				 u32 rounds);
+
+static int ccm_setkey(struct crypto_aead *tfm, const u8 *in_key,
+		      unsigned int key_len)
+{
+	struct crypto_ccm_aes_ctx *ctx = crypto_aead_ctx(tfm);
+	int ret;
+
+	ret = crypto_aes_expand_key(ctx->key, in_key, key_len);
+	if (!ret)
+		return 0;
+
+	tfm->base.crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+	return -EINVAL;
+}
+
+static int ccm_setauthsize(struct crypto_aead *tfm, unsigned int authsize)
+{
+	if ((authsize & 1) || authsize < 4)
+		return -EINVAL;
+	return 0;
+}
+
+static int ccm_init_mac(struct aead_request *req, u8 maciv[], u32 msglen)
+{
+	struct crypto_aead *aead = crypto_aead_reqtfm(req);
+	__be32 *n = (__be32 *)&maciv[AES_BLOCK_SIZE - 8];
+	u32 l = req->iv[0] + 1;
+
+	/* verify that CCM dimension 'L' is set correctly in the IV */
+	if (l < 2 || l > 8)
+		return -EINVAL;
+
+	/* verify that msglen can in fact be represented in L bytes */
+	if (msglen >> (8 * l))
+		return -EOVERFLOW;
+
+	/*
+	 * Even if the CCM spec allows L values of up to 8, the Linux cryptoapi
+	 * uses a u32 type to represent msglen so the top 4 bytes are always 0.
+	 */
+	n[0] = 0;
+	n[1] = cpu_to_be32(msglen);
+
+	memcpy(maciv, req->iv, AES_BLOCK_SIZE - l);
+
+	/*
+	 * Meaning of byte 0 according to CCM spec (RFC 3610/NIST 800-38C)
+	 * - bits 0..2	: max # of bytes required to represent msglen, minus 1
+	 *                (already set by caller)
+	 * - bits 3..5	: size of auth tag (1 => 4 bytes, 2 => 6 bytes, etc)
+	 * - bit 6	: indicates presence of authenticate-only data
+	 */
+	maciv[0] |= (crypto_aead_authsize(aead) - 2) << 2;
+	if (req->assoclen)
+		maciv[0] |= 0x40;
+
+	memset(&req->iv[AES_BLOCK_SIZE - l], 0, l);
+	return 0;
+}
+
+static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
+{
+	struct crypto_aead *aead = crypto_aead_reqtfm(req);
+	struct crypto_ccm_aes_ctx *ctx = crypto_aead_ctx(aead);
+	struct __packed { __be16 l; __be32 h; u16 len; } ltag;
+	struct scatter_walk walk;
+	u32 len = req->assoclen;
+	u32 macp = 0;
+
+	/* prepend the AAD with a length tag */
+	if (len < 0xff00) {
+		ltag.l = cpu_to_be16(len);
+		ltag.len = 2;
+	} else  {
+		ltag.l = cpu_to_be16(0xfffe);
+		put_unaligned_be32(len, &ltag.h);
+		ltag.len = 6;
+	}
+
+	ce_aes_ccm_auth_data(mac, (u8 *)&ltag, ltag.len, &macp,
+			     ctx->key->key_enc, num_rounds(ctx->key));
+	scatterwalk_start(&walk, req->assoc);
+
+	do {
+		u32 n = scatterwalk_clamp(&walk, len);
+		u8 *p;
+
+		if (!n) {
+			scatterwalk_start(&walk, sg_next(walk.sg));
+			n = scatterwalk_clamp(&walk, len);
+		}
+		p = scatterwalk_map(&walk);
+		ce_aes_ccm_auth_data(mac, p, n, &macp,
+				     ctx->key->key_enc, num_rounds(ctx->key));
+		len -= n;
+
+		scatterwalk_unmap(p);
+		scatterwalk_advance(&walk, n);
+		scatterwalk_done(&walk, 0, len);
+	} while (len);
+}
+
+struct ccm_inner_desc_info {
+	u8	ctriv[AES_BLOCK_SIZE];
+	u8	mac[AES_BLOCK_SIZE];
+} __aligned(8);
+
+static int ccm_inner_encrypt(struct blkcipher_desc *desc,
+			     struct scatterlist *dst, struct scatterlist *src,
+			     unsigned int nbytes)
+{
+	struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+	struct ccm_inner_desc_info *descinfo = desc->info;
+	struct blkcipher_walk walk;
+	int err;
+
+	blkcipher_walk_init(&walk, dst, src, nbytes);
+	err = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE);
+
+	while (walk.nbytes) {
+		u32 tail = walk.nbytes % AES_BLOCK_SIZE;
+
+		if (walk.nbytes == nbytes)
+			tail = 0;
+
+		ce_aes_ccm_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
+				   walk.nbytes - tail, ctx->key_enc,
+				   num_rounds(ctx), descinfo->mac,
+				   descinfo->ctriv);
+
+		nbytes -= walk.nbytes - tail;
+		err = blkcipher_walk_done(desc, &walk, tail);
+	}
+	return err;
+}
+
+static int ccm_inner_decrypt(struct blkcipher_desc *desc,
+			     struct scatterlist *dst, struct scatterlist *src,
+			     unsigned int nbytes)
+{
+	struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+	struct ccm_inner_desc_info *descinfo = desc->info;
+	struct blkcipher_walk walk;
+	int err;
+
+	blkcipher_walk_init(&walk, dst, src, nbytes);
+	err = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE);
+
+	while (walk.nbytes) {
+		u32 tail = walk.nbytes % AES_BLOCK_SIZE;
+
+		if (walk.nbytes == nbytes)
+			tail = 0;
+
+		ce_aes_ccm_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
+				   walk.nbytes - tail, ctx->key_enc,
+				   num_rounds(ctx), descinfo->mac,
+				   descinfo->ctriv);
+
+		nbytes -= walk.nbytes - tail;
+		err = blkcipher_walk_done(desc, &walk, tail);
+	}
+	return err;
+}
+
+static int ccm_encrypt(struct aead_request *req)
+{
+	struct crypto_aead *aead = crypto_aead_reqtfm(req);
+	struct crypto_ccm_aes_ctx *ctx = crypto_aead_ctx(aead);
+	struct crypto_blkcipher *blk_tfm = ctx->blk_tfm;
+	struct ccm_inner_desc_info descinfo;
+	int err;
+
+	struct blkcipher_desc desc = {
+		.tfm	= blk_tfm,
+		.info	= &descinfo,
+		.flags = 0,
+	};
+
+	err = ccm_init_mac(req, descinfo.mac, req->cryptlen);
+	if (err)
+		return err;
+
+	kernel_neon_begin_partial(6);
+
+	if (req->assoclen)
+		ccm_calculate_auth_mac(req, descinfo.mac);
+
+	memcpy(descinfo.ctriv, req->iv, AES_BLOCK_SIZE);
+
+	/* call inner blkcipher to process the payload */
+	err = crypto_blkcipher_crt(blk_tfm)->encrypt(&desc, req->dst, req->src,
+						     req->cryptlen);
+	if (!err)
+		ce_aes_ccm_final(descinfo.mac, req->iv, ctx->key->key_enc,
+				 num_rounds(ctx->key));
+
+	kernel_neon_end();
+
+	if (err)
+		return err;
+
+	/* copy authtag to end of dst */
+	scatterwalk_map_and_copy(descinfo.mac, req->dst, req->cryptlen,
+				 crypto_aead_authsize(aead), 1);
+
+	return 0;
+}
+
+static int ccm_decrypt(struct aead_request *req)
+{
+	struct crypto_aead *aead = crypto_aead_reqtfm(req);
+	struct crypto_ccm_aes_ctx *ctx = crypto_aead_ctx(aead);
+	struct crypto_blkcipher *blk_tfm = ctx->blk_tfm;
+	struct ccm_inner_desc_info descinfo;
+	u8 atag[AES_BLOCK_SIZE];
+	u32 len;
+	int err;
+
+	struct blkcipher_desc desc = {
+		.tfm	= blk_tfm,
+		.info	= &descinfo,
+		.flags = 0,
+	};
+
+	len = req->cryptlen - crypto_aead_authsize(aead);
+	err = ccm_init_mac(req, descinfo.mac, len);
+	if (err)
+		return err;
+
+	if (req->assoclen)
+		ccm_calculate_auth_mac(req, descinfo.mac);
+
+	memcpy(descinfo.ctriv, req->iv, AES_BLOCK_SIZE);
+
+	kernel_neon_begin_partial(6);
+
+	/* call inner blkcipher to process the payload */
+	err = crypto_blkcipher_crt(blk_tfm)->decrypt(&desc, req->dst, req->src,
+						     len);
+	if (!err)
+		ce_aes_ccm_final(descinfo.mac, req->iv, ctx->key->key_enc,
+				 num_rounds(ctx->key));
+
+	kernel_neon_end();
+
+	if (err)
+		return err;
+
+	/* compare calculated auth tag with the stored one */
+	scatterwalk_map_and_copy(atag, req->src, len,
+				 crypto_aead_authsize(aead), 0);
+
+	if (memcmp(descinfo.mac, atag, crypto_aead_authsize(aead)))
+		return -EBADMSG;
+	return 0;
+}
+
+static int ccm_init(struct crypto_tfm *tfm)
+{
+	struct crypto_ccm_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+	struct crypto_blkcipher *blk_tfm;
+
+	blk_tfm = crypto_alloc_blkcipher("__driver-ccm-aesce-inner", 0, 0);
+	if (IS_ERR(blk_tfm))
+		return PTR_ERR(blk_tfm);
+
+	ctx->blk_tfm = blk_tfm;
+	ctx->key = crypto_blkcipher_ctx(blk_tfm);
+
+	return 0;
+}
+
+static void ccm_exit(struct crypto_tfm *tfm)
+{
+	struct crypto_ccm_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	crypto_free_blkcipher(ctx->blk_tfm);
+}
+
+static struct crypto_alg aes_algs[] = { {
+	.cra_name		= "__ccm-aesce-inner",
+	.cra_driver_name	= "__driver-ccm-aesce-inner",
+	.cra_priority		= 0,
+	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
+	.cra_blocksize		= 1,
+	.cra_ctxsize		= sizeof(struct crypto_aes_ctx),
+	.cra_alignmask		= 7,
+	.cra_type		= &crypto_blkcipher_type,
+	.cra_module		= THIS_MODULE,
+	.cra_blkcipher = {
+		.min_keysize	= AES_MIN_KEY_SIZE,
+		.max_keysize	= AES_MAX_KEY_SIZE,
+		.ivsize		= sizeof(struct ccm_inner_desc_info),
+		.setkey		= crypto_aes_set_key,
+		.encrypt	= ccm_inner_encrypt,
+		.decrypt	= ccm_inner_decrypt,
+	},
+}, {
+	.cra_name		= "ccm(aes)",
+	.cra_driver_name	= "ccm-aes-ce",
+	.cra_priority		= 300,
+	.cra_flags		= CRYPTO_ALG_TYPE_AEAD,
+	.cra_blocksize		= 1,
+	.cra_ctxsize		= sizeof(struct crypto_ccm_aes_ctx),
+	.cra_alignmask		= 7,
+	.cra_type		= &crypto_aead_type,
+	.cra_module		= THIS_MODULE,
+	.cra_init		= ccm_init,
+	.cra_exit		= ccm_exit,
+	.cra_aead = {
+		.ivsize		= AES_BLOCK_SIZE,
+		.maxauthsize	= AES_BLOCK_SIZE,
+		.setkey		= ccm_setkey,
+		.setauthsize	= ccm_setauthsize,
+		.encrypt	= ccm_encrypt,
+		.decrypt	= ccm_decrypt,
+	}
+} };
+
+static int __init aes_mod_init(void)
+{
+	if (!(elf_hwcap & HWCAP_AES))
+		return -ENODEV;
+	return crypto_register_algs(aes_algs, ARRAY_SIZE(aes_algs));
+}
+
+static void __exit aes_mod_exit(void)
+{
+	crypto_unregister_algs(aes_algs, ARRAY_SIZE(aes_algs));
+}
+
+module_init(aes_mod_init);
+module_exit(aes_mod_exit);
+
+MODULE_DESCRIPTION("Synchronous AES in CCM mode using ARMv8 Crypto Extensions");
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ccm(aes)");
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH V2] ARM: imx: avoid calling clk APIs in idle thread which may cause schedule
From: Anson Huang @ 2014-02-11  8:25 UTC (permalink / raw)
  To: linux-arm-kernel

As clk_pllv3_wait_lock will call usleep_range, and the clk APIs
mutex lock may be held when CPU entering idle, so calling clk
APIs must be avoided in cpu idle thread, this is to avoid reschedule
warning in cpu idle, just access register directly to achieve that.

bad: scheduling from the idle thread!
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.14.0-rc1+ #657
Backtrace:
[<80012188>] (dump_backtrace) from [<8001246c>] (show_stack+0x18/0x1c)
 r6:808c0038 r5:00000000 r4:808e5a1c r3:00000000
[<80012454>] (show_stack) from [<8064b2ec>] (dump_stack+0x84/0x9c)
[<8064b268>] (dump_stack) from [<80055ee0>] (dequeue_task_idle+0x20/0x30)
 r5:808bef40 r4:bf7dff40
[<80055ec0>] (dequeue_task_idle) from [<8004f028>] (dequeue_task+0x30/0x50)
 r4:bf7dff40 r3:80055ec0
[<8004eff8>] (dequeue_task) from [<800503c0>] (deactivate_task+0x30/0x34)
 r4:bf7dff40
[<80050390>] (deactivate_task) from [<8064d8e4>] (__schedule+0x2c8/0x5c0)
[<8064d61c>] (__schedule) from [<8064dc14>] (schedule+0x38/0x88)
 r10:80912964 r9:808c1e50 r8:808c0038 r7:808cbf30 r6:80e128ec r5:60000093
 r4:80912968
[<8064dbdc>] (schedule) from [<8064dfec>] (schedule_preempt_disabled+0x10/0x14)
[<8064dfdc>] (schedule_preempt_disabled) from [<8064ebc0>] (mutex_lock_nested+0x1c0/0x3c0)
[<8064ea00>] (mutex_lock_nested) from [<804ae71c>] (clk_prepare_lock+0x44/0xe4)
 r10:806554cc r9:bf7df1bc r8:808cf4f8 r7:808cf544 r6:bf7df1b8 r5:808c0010
 r4:80e69750
[<804ae6d8>] (clk_prepare_lock) from [<804af214>] (clk_get_rate+0x14/0x64)
 r6:bf7df1b8 r5:00000002 r4:bf017000 r3:80922ad0
[<804af200>] (clk_get_rate) from [<80025d30>] (imx6sl_set_wait_clk+0x18/0x20)
 r5:00000002 r4:00000001
[<80025d18>] (imx6sl_set_wait_clk) from [<80023454>] (imx6sl_enter_wait+0x20/0x48)
[<80023434>] (imx6sl_enter_wait) from [<80477c24>] (cpuidle_enter_state+0x44/0xfc)
 r4:3c386e48 r3:80023434
[<80477be0>] (cpuidle_enter_state) from [<80477dd8>] (cpuidle_idle_call+0xfc/0x160)
 r8:808cf4f8 r7:00000001 r6:80e69534 r5:00000000 r4:bf7df1b8
[<80477cdc>] (cpuidle_idle_call) from [<8000f61c>] (arch_cpu_idle+0x10/0x50)
 r9:808c0000 r8:00000000 r7:80921a89 r6:808c8938 r5:808c899c r4:808c0000
[<8000f60c>] (arch_cpu_idle) from [<8006fa94>] (cpu_startup_entry+0x108/0x160)
[<8006f98c>] (cpu_startup_entry) from [<806452ac>] (rest_init+0xb4/0xdc)
 r7:808afae0
[<806451f8>] (rest_init) from [<8086fb58>] (start_kernel+0x328/0x38c)
 r6:ffffffff r5:808c8880 r4:808c8a30
[<8086f830>] (start_kernel) from [<80008074>] (0x80008074)

Signed-off-by: Anson Huang <b20788@freescale.com>
---
Changes since V1:
	1. Move ccm_base and anatop_base initialization after WARN check;
	2. Only enable PLL1 when ARM is sourcing clock from 396M PFD.

 arch/arm/mach-imx/clk-imx6sl.c |   83 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 77 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c
index b71570d..f7073c0 100644
--- a/arch/arm/mach-imx/clk-imx6sl.c
+++ b/arch/arm/mach-imx/clk-imx6sl.c
@@ -18,6 +18,22 @@
 #include "clk.h"
 #include "common.h"
 
+#define CCSR			0xc
+#define BM_CCSR_PLL1_SW_CLK_SEL	(1 << 2)
+#define CACRR			0x10
+#define CDHIPR			0x48
+#define BM_CDHIPR_ARM_PODF_BUSY	(1 << 16)
+#define ARM_WAIT_DIV_396M	2
+#define ARM_WAIT_DIV_792M	4
+#define ARM_WAIT_DIV_996M	6
+
+#define PLL_ARM			0x0
+#define BM_PLL_ARM_DIV_SELECT	(0x7f << 0)
+#define BM_PLL_ARM_POWERDOWN	(1 << 12)
+#define BM_PLL_ARM_ENABLE	(1 << 13)
+#define BM_PLL_ARM_LOCK		(1 << 31)
+#define PLL_ARM_DIV_792M	66
+
 static const char *step_sels[]		= { "osc", "pll2_pfd2", };
 static const char *pll1_sw_sels[]	= { "pll1_sys", "step", };
 static const char *ocram_alt_sels[]	= { "pll2_pfd2", "pll3_pfd1", };
@@ -65,6 +81,8 @@ static struct clk_div_table video_div_table[] = {
 
 static struct clk *clks[IMX6SL_CLK_END];
 static struct clk_onecell_data clk_data;
+static void __iomem *ccm_base;
+static void __iomem *anatop_base;
 
 static const u32 clks_init_on[] __initconst = {
 	IMX6SL_CLK_IPG, IMX6SL_CLK_ARM, IMX6SL_CLK_MMDC_ROOT,
@@ -81,19 +99,70 @@ static const u32 clks_init_on[] __initconst = {
  * entering WAIT mode.
  *
  * This function will set the ARM clk to max value within the 12:5 limit.
+ * As IPG clock is fixed@66MHz(so ARM freq must not exceed 158.4MHz),
+ * ARM freq are one of below setpoints: 396MHz, 792MHz and 996MHz, since
+ * the clk APIs can NOT be called in idle thread(may cause kernel schedule
+ * as there is sleep function in PLL wait function), so here we just slow
+ * down ARM to below freq according to previous freq:
+ *
+ * run mode      wait mode
+ * 396MHz   ->   132MHz;
+ * 792MHz   ->   158.4MHz;
+ * 996MHz   ->   142.3MHz;
  */
+static int imx6sl_get_arm_divider_for_wait(void)
+{
+	if (readl_relaxed(ccm_base + CCSR) & BM_CCSR_PLL1_SW_CLK_SEL) {
+		return ARM_WAIT_DIV_396M;
+	} else {
+		if ((readl_relaxed(anatop_base + PLL_ARM) &
+			BM_PLL_ARM_DIV_SELECT) == PLL_ARM_DIV_792M)
+			return ARM_WAIT_DIV_792M;
+		else
+			return ARM_WAIT_DIV_996M;
+	}
+}
+
+static void imx6sl_enable_pll_arm(bool enable)
+{
+	static u32 saved_pll_arm;
+	u32 val;
+
+	if (enable) {
+		saved_pll_arm = val = readl_relaxed(anatop_base + PLL_ARM);
+		val |= BM_PLL_ARM_ENABLE;
+		val &= ~BM_PLL_ARM_POWERDOWN;
+		writel_relaxed(val, anatop_base + PLL_ARM);
+		while (!(__raw_readl(anatop_base + PLL_ARM) & BM_PLL_ARM_LOCK))
+			;
+	} else {
+		 writel_relaxed(saved_pll_arm, anatop_base + PLL_ARM);
+	}
+}
+
 void imx6sl_set_wait_clk(bool enter)
 {
-	static unsigned long saved_arm_rate;
+	static unsigned long saved_arm_div;
+	int arm_div_for_wait = imx6sl_get_arm_divider_for_wait();
+
+	/*
+	 * According to hardware design, arm podf change need
+	 * PLL1 clock enabled.
+	 */
+	if (arm_div_for_wait == ARM_WAIT_DIV_396M)
+		imx6sl_enable_pll_arm(true);
 
 	if (enter) {
-		unsigned long ipg_rate = clk_get_rate(clks[IMX6SL_CLK_IPG]);
-		unsigned long max_arm_wait_rate = (12 * ipg_rate) / 5;
-		saved_arm_rate = clk_get_rate(clks[IMX6SL_CLK_ARM]);
-		clk_set_rate(clks[IMX6SL_CLK_ARM], max_arm_wait_rate);
+		saved_arm_div = readl_relaxed(ccm_base + CACRR);
+		writel_relaxed(arm_div_for_wait, ccm_base + CACRR);
 	} else {
-		clk_set_rate(clks[IMX6SL_CLK_ARM], saved_arm_rate);
+		writel_relaxed(saved_arm_div, ccm_base + CACRR);
 	}
+	while (__raw_readl(ccm_base + CDHIPR) & BM_CDHIPR_ARM_PODF_BUSY)
+		;
+
+	if (arm_div_for_wait == ARM_WAIT_DIV_396M)
+		imx6sl_enable_pll_arm(false);
 }
 
 static void __init imx6sl_clocks_init(struct device_node *ccm_node)
@@ -111,6 +180,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
 	np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop");
 	base = of_iomap(np, 0);
 	WARN_ON(!base);
+	anatop_base = base;
 
 	/*                                             type               name            parent  base         div_mask */
 	clks[IMX6SL_CLK_PLL1_SYS]      = imx_clk_pllv3(IMX_PLLV3_SYS,	  "pll1_sys",	   "osc", base,        0x7f);
@@ -158,6 +228,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
 	np = ccm_node;
 	base = of_iomap(np, 0);
 	WARN_ON(!base);
+	ccm_base = base;
 
 	/* Reuse imx6q pm code */
 	imx6q_pm_set_ccm_base(base);
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v6 01/19] clocksource: orion: Use atomic access for shared registers
From: Ezequiel Garcia @ 2014-02-11  8:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F96993.9090007@linaro.org>

On Tue, Feb 11, 2014 at 01:06:43AM +0100, Daniel Lezcano wrote:
> On 02/06/2014 06:20 PM, Ezequiel Garcia wrote:
> > Replace the driver-specific thread-safe shared register API
> > by the recently introduced atomic_io_clear_set().
> >
> > Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
> > Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
> > Tested-by: Willy Tarreau <w@1wt.eu>
> > Acked-by: Jason Cooper <jason@lakedaemon.net>
> > Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
> 
> The patch looks good for me.
> 
> Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> 

Daniel,

Jason acked this patch for you to take it. Or do you prefer that we
merge it with the rest of the watchdog series?

-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com

^ permalink raw reply

* [PATCH v7 00/18] Armada 370/XP watchdog
From: Ezequiel Garcia @ 2014-02-11  8:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392073237-2554-1-git-send-email-ezequiel.garcia@free-electrons.com>

On Mon, Feb 10, 2014 at 08:00:19PM -0300, Ezequiel Garcia wrote:
> Yet another round. This time, addressing Guenter's comment about the nowayout
> parameter. So, to allow for proper nowayout behavior, we now restrict the
> initial watchdog stop; which is only done if the watchdog is not properly
> enabled.
> 
> I've dropped the clocksource patch which was previously part of the series.
> The patch is independent and will be merged through the subsystem maintainer,
> Daniel Lezcano.
> 
> Also, I've updated the multi_v7_defconfig, as per Jason Cooper request.
> 
> This series depends on Sebastian's irqchip fixes to clear the bridge irqs
> cause, which Jason picked here:
> 
>   http://git.infradead.org/linux-mvebu.git mvebu-next/irqchip-fixes
> 
> Wim: Can we take all the watchdog changes through mvebu, with your Ack?
> This way, we can sort out the irqchip dependency.
> 

Wim: Do you have any comments about these patches?

-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com

^ permalink raw reply

* [RFC PATCH 2/3] staging: imx-drm-core: Use graph to find connection between crtc and encoder
From: Dan Carpenter @ 2014-02-11  8:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140210162631.GC26684@n2100.arm.linux.org.uk>

> Why is this loop soo complicated?  Why do you need to mess around with
> this "last_ep" stuff - you don't actually end up using it.
> 
> The loop reduces down to this without comments:
> 
>  	for (i = 0; !ret; i++) {
                    ^^^^
Philipp, "ret" isn't set anymore in the new loop.

>  		uint32_t mask;
> 
> 		ep = v4l2_of_get_next_endpoint(np, last_ep);
> 		if (!ep)
> 			break;
> 
> 		/* CSI */
> 		mask = imx_drm_find_crtc_mask(imxdrm, ep);
> 		of_node_put(ep);
> 
> 		if (mask == 0)
> 			return -EPROBE_DEFER;
> 
> 		crtc_mask |= mask;
> 	}

regards,
dan carpenter

^ permalink raw reply

* [RFC/PATCH v2] ARM: vDSO gettimeofday using generic timer architecture
From: Steve Capper @ 2014-02-11  8:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140210171200.GE26684@n2100.arm.linux.org.uk>

On Mon, Feb 10, 2014 at 05:12:00PM +0000, Russell King - ARM Linux wrote:
> On Mon, Feb 10, 2014 at 04:51:16PM +0000, Steve Capper wrote:
> > Hi Russell,
> > 
> > On Sun, Feb 09, 2014 at 10:20:23AM +0000, Russell King - ARM Linux wrote:
> > > On Fri, Feb 07, 2014 at 05:05:49PM -0600, Nathan Lynch wrote:
> > > > +	/* Grab the vDSO code pages. */
> > > > +	for (i = 0; i < vdso_pages; i++) {
> > > > +		pg = virt_to_page(&vdso_start + i*PAGE_SIZE);
> > > > +		ClearPageReserved(pg);
> > > > +		get_page(pg);
> > > > +		vdso_pagelist[i] = pg;
> > > > +	}
> > > 
> > > Why do we want to clear the reserved status?  This looks over complicated
> > > to me.
> > > 
> > 
> > This looks like it was inherited from the PowerPC code where the
> > behaviour of set_pte_at would change dependent on whether or not the
> > page was reserved (set_pte_at->set_pte_filter->maybe_pte_to_page). I
> > think we can safely remove this from ARM and ARM64.
> 
> Great, so we can get rid of that and the get_page() on the vdso data
> page below.
> 
> > > > +
> > > > +	/* Sanity check the shared object header. */
> > > > +	vbase = vmap(vdso_pagelist, 1, 0, PAGE_KERNEL);
> > > > +	if (vbase == NULL) {
> > > > +		pr_err("Failed to map vDSO pagelist!\n");
> > > > +		return -ENOMEM;
> > > > +	} else if (memcmp(vbase, "\177ELF", 4)) {
> > > > +		pr_err("vDSO is not a valid ELF object!\n");
> > > > +		ret = -EINVAL;
> > > > +		goto unmap;
> > > > +	}
> > > 
> > > Why do we need to vmap() pages which are already accessible - vdso_start
> > > must be part of the kernel image, and therefore will be accessible via
> > > standard mappings.
> > > 
> > 
> > This is a dress rehersal for install_special_mapping more than anything.
> > If we map the page, and look at the first 4 bytes, are they what we
> > expect?
> 
> My point is that we can already view this page directly by dereferencing
> vdso_start - do we really need to perform this apparant test of the MMU?
> If the MMU isn't working in this way, we have much bigger and more
> fundamental problems...
> 

I see, yes I think people would notice the MMU not working :-).
This code also tests the alignment of vdso_start in a roundabout way.
I'm not sure whether or not an explicit alignment check to PAGE_SIZE
would be beneficial instead of the test mapping.

Cheers,
-- 
Steve

^ permalink raw reply

* [PATCH v2 2/5] irqchip: gic: use writel instead of dsb + writel_relaxed
From: Marc Zyngier @ 2014-02-11  8:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392042159-11603-2-git-send-email-will.deacon@arm.com>

On 10/02/14 14:22, Will Deacon wrote:
> When sending an SGI to another CPU, we require a DSB to ensure that
> any pending stores to normal memory are made visible to the recipient
> before the interrupt arrives.
> 
> Rather than use a vanilla dsb() (which will soon cause an assembly error
> on arm64) before the writel_relaxed, we can instead use dsb(ishst),
> since we just need to ensure that any pending normal writes are visible
> within the inner-shareable domain before we poke the GIC.
> 
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
> ---
> 
> v1 => v2: Use dsb ishst instead of writel (which requires an L2 sync)
>           since the sync should already have been executed by the caller
> 	  if required. We *might* be able to relax this further to a dmb
> 	  but Catalin and I haven't got to the bottom of that yet.
> 
> Marc: I dropped your Ack, so could you take another look please?

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* [PATCH] arm: add DSB after icache flush in __flush_icache_all()
From: Vinayak Kale @ 2014-02-11  8:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F90734.1090607@gmail.com>

On Mon, Feb 10, 2014 at 10:37 PM, Dirk Behme <dirk.behme@gmail.com> wrote:
> Am 10.02.2014 11:43, schrieb Catalin Marinas:
>
>> On Sun, Feb 09, 2014 at 06:09:49AM +0000, Dirk Behme wrote:
>>>
>>> Am 05.02.2014 10:33, schrieb Vinayak Kale:
>>>>
>>>> Add DSB after icache flush to complete the cache maintenance operation.
>>>>
>>>> Signed-off-by: Vinayak Kale <vkale@apm.com>
>>>
>>>
>>> Should this go to -stable, too?
>>>
>>> I haven't looked into the details, but at least it seems to apply
>>> cleanly on a 3.8 kernel.
>>
>>
>> It should. For the similar arm64 fix I added 'cc: stable' myself (commit
>> 5044bad43ee57).
>
>
> While the arm64 patch already hit mainline, I can't find this one in
> mainline, -next or even the patch system, yet (?)
>
> Vinayak: Could you put this patch into the patch system and CC stable,
> please?
Sure.
>
> Thanks
>
> Dirk

^ permalink raw reply

* [RFC PATCH 2/3] staging: imx-drm-core: Use graph to find connection between crtc and encoder
From: Philipp Zabel @ 2014-02-11  9:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140211083831.GV26722@mwanda>

Hi Dan,

Am Dienstag, den 11.02.2014, 11:38 +0300 schrieb Dan Carpenter:
> > Why is this loop soo complicated?  Why do you need to mess around with
> > this "last_ep" stuff - you don't actually end up using it.
> > 
> > The loop reduces down to this without comments:
> > 
> >  	for (i = 0; !ret; i++) {
>                     ^^^^
> Philipp, "ret" isn't set anymore in the new loop.

thanks, I'll drop ret in the next version.

regards
Philipp

^ permalink raw reply

* [PATCH v2 1/3] net: stmmac:sti: Add STi SOC glue driver.
From: srinivas kandagatla @ 2014-02-11  9:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140210.144054.2066120014050984537.davem@davemloft.net>

Thankyou Dave,
I will fix these in next version.


On 10/02/14 22:40, David Miller wrote:
> From: <srinivas.kandagatla@st.com>
> Date: Fri, 7 Feb 2014 10:55:25 +0000
> 
>> +		if (dwmac->interface == PHY_INTERFACE_MODE_MII ||
>> +			dwmac->interface == PHY_INTERFACE_MODE_GMII) {
> 
> This is not indented correctly, the first character on the second line should
> line up exactly at the column after the openning parenthesis on the first
> line.
> 
> The objective is not to indent using only TAB characters, which you
> are doing here.
> 
> Rather, the objective is to use the appropriate number of TAB _and_
> space characters necessary to reach the proper column.
> 
>> +		const char *rs;
>> +		err = of_property_read_string(np, "st,tx-retime-src", &rs);
> 
> Please add an empty line after the local variable declaration.
> 
>> +		if (!strcasecmp(rs, "clk_125"))
>> +			dwmac->is_tx_retime_src_clk_125 = true;
>> +
>> +	}
> 
> That empty line is superfluous, please delete it.
> 
> 


Thanks,
srini

^ permalink raw reply

* [PATCH v3 05/11] ARM: LPAE: provide an IPA capable pmd_addr_end
From: Marc Zyngier @ 2014-02-11  9:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140207171057.GR9157@cbox>

On 07/02/14 17:10, Christoffer Dall wrote:
> On Fri, Feb 07, 2014 at 03:44:01PM +0000, Catalin Marinas wrote:
>> On Fri, Feb 07, 2014 at 04:04:56AM +0000, Christoffer Dall wrote:
>>> On Thu, Feb 06, 2014 at 10:43:28AM +0000, Catalin Marinas wrote:
>>>> On Wed, Feb 05, 2014 at 07:55:45PM +0000, Marc Zyngier wrote:
>>>>> The default pmd_addr_end macro uses an unsigned long to represent
>>>>> the VA. When used with KVM and stage-2 translation, the VA is
>>>>> actually an IPA, which is up to 40 bits. This also affect the
>>>>> SMMU driver, which also deals with stage-2 translation.
>>>>>
>>>>> Instead, provide an implementation that can cope with larger VAs
>>>>> by using a u64 instead. This version will overload the default
>>>>> one provided in include/asm-generic/pgtable.h.
>>>>>
>>>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>>>>> ---
>>>>>  arch/arm/include/asm/pgtable-3level.h | 5 +++++
>>>>>  1 file changed, 5 insertions(+)
>>>>>
>>>>> diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
>>>>> index 03243f7..594867b 100644
>>>>> --- a/arch/arm/include/asm/pgtable-3level.h
>>>>> +++ b/arch/arm/include/asm/pgtable-3level.h
>>>>> @@ -262,6 +262,11 @@ static inline int has_transparent_hugepage(void)
>>>>>  	return 1;
>>>>>  }
>>>>>  
>>>>> +#define pmd_addr_end(addr, end)						\
>>>>> +({	u64 __boundary = ((addr) + PMD_SIZE) & PMD_MASK;		\
>>>>> +	(__boundary - 1 < (end) - 1)? __boundary: (end);		\
>>>>> +})
>>>>
>>>> I see why you need this but it affects all the other uses of
>>>> pmd_addr_end() with 32-bit VA. It would be slight performance, I don't
>>>> think it's noticeable.
>>>>
>>>> A different approach could be something like (untested):
>>>>
>>>> #define pmd_addr_end(addr, end)					\
>>>> ({	__typeof__(addr) __boundary = ...
>>>> 	...
>>>> })
>>>>
>>>> What about the pgd_addr_end(), do we need this or it's not used by KVM?
>>>>
>>>
>>> What about pud_addr_end(), is that defined as a noop on LPAE, or?
>>>
>>> I would be in favor of introducing them all using your approach to avoid
>>> somebody being inspired by the KVM code when dealing with IPAs and
>>> breaking things unknowingly.
>>
>> I had a brief chat with Marc yesterday around this and it may be safer
>> to simply introduce kvm_p*d_addr_end() macros. You already do this for
>> pgd_addr_end() since it cannot be overridden in the generic headers.
>>
> Sounds good to me.  We should introduce all of them then.

I'll repost a series with that change in.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* [PATCH RESEND] arm: add DSB after icache flush in __flush_icache_all()
From: Vinayak Kale @ 2014-02-11  9:10 UTC (permalink / raw)
  To: linux-arm-kernel

Add DSB after icache flush to complete the cache maintenance operation.

Signed-off-by: Vinayak Kale <vkale@apm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---

PS:
- This patch is tested for ARM-v7.

 arch/arm/include/asm/cacheflush.h |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index ee753f1..ab91ebb 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -212,6 +212,7 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *,
 static inline void __flush_icache_all(void)
 {
 	__flush_icache_preferred();
+	dsb();
 }
 
 /*
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v6 01/19] clocksource: orion: Use atomic access for shared registers
From: Daniel Lezcano @ 2014-02-11  9:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140211083024.GA3687@localhost>

On 02/11/2014 09:30 AM, Ezequiel Garcia wrote:
> On Tue, Feb 11, 2014 at 01:06:43AM +0100, Daniel Lezcano wrote:
>> On 02/06/2014 06:20 PM, Ezequiel Garcia wrote:
>>> Replace the driver-specific thread-safe shared register API
>>> by the recently introduced atomic_io_clear_set().
>>>
>>> Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
>>> Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
>>> Tested-by: Willy Tarreau <w@1wt.eu>
>>> Acked-by: Jason Cooper <jason@lakedaemon.net>
>>> Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
>>
>> The patch looks good for me.
>>
>> Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
>>
>
> Daniel,
>
> Jason acked this patch for you to take it. Or do you prefer that we
> merge it with the rest of the watchdog series?

I can pick it, but doesn't the watchdog series depend on it ?

-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply

* [PATCH v9 2/4] ehci-platform: Add support for clks and phy passed through devicetree
From: Roger Quadros @ 2014-02-11  9:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391787403-20961-3-git-send-email-hdegoede@redhat.com>

Hi Hans,

On 02/07/2014 05:36 PM, Hans de Goede wrote:
> Currently ehci-platform is only used in combination with devicetree when used
> with some Via socs. By extending it to (optionally) get clks and a phy from
> devicetree, and enabling / disabling those on power_on / off, it can be used
> more generically. Specifically after this commit it can be used for the
> ehci controller on Allwinner sunxi SoCs.
> 
> Since ehci-platform is intended to handle any generic enough non pci ehci
> device, add a "usb-ehci" compatibility string.
> 
> There already is a usb-ehci device-tree bindings document, update this
> with clks and phy bindings info.
> 
> Although actually quite generic so far the via,vt8500 compatibilty string
> had its own bindings document. Somehow we even ended up with 2 of them. Since
> these provide no extra information over the generic usb-ehci documentation,
> this patch removes them.
> 
> The ehci-ppc-of.c driver also claims the usb-ehci compatibility string,
> even though it mostly is ibm,usb-ehci-440epx specific. ehci-platform.c is
> not needed on ppc platforms, so add a !PPC_OF dependency to it to avoid
> 2 drivers claiming the same compatibility string getting build on ppc.
> 

This breaks all OMAP platforms on linux-next for the exact same reason. see [1].

./arch/arm/boot/dts/omap4.dtsi:				compatible = "ti,ehci-omap", "usb-ehci";
./arch/arm/boot/dts/omap3.dtsi:				compatible = "ti,ehci-omap", "usb-ehci";
./arch/arm/boot/dts/omap5.dtsi:				compatible = "ti,ehci-omap", "usb-ehci";


The other platforms that claim compatibility with "usb-ehci" are

ARM
./arch/arm/boot/dts/tegra30.dtsi:		compatible = "nvidia,tegra30-ehci", "usb-ehci";
./arch/arm/boot/dts/tegra20.dtsi:		compatible = "nvidia,tegra20-ehci", "usb-ehci";
./arch/arm/boot/dts/spear600.dtsi:			compatible = "st,spear600-ehci", "usb-ehci";

./arch/arm/boot/dts/spear3xx.dtsi:			compatible = "st,spear600-ehci", "usb-ehci";
./arch/arm/boot/dts/sama5d3.dtsi:			compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
./arch/arm/boot/dts/at91sam9g45.dtsi:			compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
./arch/arm/boot/dts/spear13xx.dtsi:			compatible = "st,spear600-ehci", "usb-ehci";
./arch/arm/boot/dts/at91sam9x5.dtsi:			compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
./arch/arm/boot/dts/tegra114.dtsi:		compatible = "nvidia,tegra30-ehci", "usb-ehci";


MIPS
./arch/mips/cavium-octeon/octeon_68xx.dts:				compatible = "cavium,octeon-6335-ehci","usb-ehci";
./arch/mips/cavium-octeon/octeon_3xxx.dts:				compatible = "cavium,octeon-6335-ehci","usb-ehci";

Do we know that we don't break these platforms as well?

cheers,
-roger

[1] - http://marc.info/?l=linux-usb&m=139204800102167&w=2

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> Acked-by: Alan Stern <stern@rowland.harvard.edu>
> ---
>  Documentation/devicetree/bindings/usb/usb-ehci.txt |  25 +++-
>  .../devicetree/bindings/usb/via,vt8500-ehci.txt    |  15 ---
>  .../devicetree/bindings/usb/vt8500-ehci.txt        |  12 --
>  drivers/usb/host/Kconfig                           |   1 +
>  drivers/usb/host/ehci-platform.c                   | 147 +++++++++++++++++----
>  5 files changed, 142 insertions(+), 58 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
>  delete mode 100644 Documentation/devicetree/bindings/usb/vt8500-ehci.txt
> 
> diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt b/Documentation/devicetree/bindings/usb/usb-ehci.txt
> index fa18612..2c1aeeb 100644
> --- a/Documentation/devicetree/bindings/usb/usb-ehci.txt
> +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt
> @@ -7,13 +7,14 @@ Required properties:
>      (debug-port or other) can be also specified here, but only after
>      definition of standard EHCI registers.
>    - interrupts : one EHCI interrupt should be described here.
> -If device registers are implemented in big endian mode, the device
> -node should have "big-endian-regs" property.
> -If controller implementation operates with big endian descriptors,
> -"big-endian-desc" property should be specified.
> -If both big endian registers and descriptors are used by the controller
> -implementation, "big-endian" property can be specified instead of having
> -both "big-endian-regs" and "big-endian-desc".
> +
> +Optional properties:
> + - big-endian-regs : boolean, set this for hcds with big-endian registers
> + - big-endian-desc : boolean, set this for hcds with big-endian descriptors
> + - big-endian : boolean, for hcds with big-endian-regs + big-endian-desc
> + - clocks : a list of phandle + clock specifier pairs
> + - phys : phandle + phy specifier pair
> + - phy-names : "usb"
>  
>  Example (Sequoia 440EPx):
>      ehci at e0000300 {
> @@ -23,3 +24,13 @@ Example (Sequoia 440EPx):
>  	   reg = <0 e0000300 90 0 e0000390 70>;
>  	   big-endian;
>     };
> +
> +Example (Allwinner sun4i A10 SoC):
> +   ehci0: usb at 01c14000 {
> +	   compatible = "allwinner,sun4i-a10-ehci", "usb-ehci";
> +	   reg = <0x01c14000 0x100>;
> +	   interrupts = <39>;
> +	   clocks = <&ahb_gates 1>;
> +	   phys = <&usbphy 1>;
> +	   phy-names = "usb";
> +   };
> diff --git a/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt b/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
> deleted file mode 100644
> index 17b3ad1..0000000
> --- a/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
> +++ /dev/null
> @@ -1,15 +0,0 @@
> -VIA/Wondermedia VT8500 EHCI Controller
> ------------------------------------------------------
> -
> -Required properties:
> -- compatible : "via,vt8500-ehci"
> -- reg : Should contain 1 register ranges(address and length)
> -- interrupts : ehci controller interrupt
> -
> -Example:
> -
> -	ehci at d8007900 {
> -		compatible = "via,vt8500-ehci";
> -		reg = <0xd8007900 0x200>;
> -		interrupts = <43>;
> -	};
> diff --git a/Documentation/devicetree/bindings/usb/vt8500-ehci.txt b/Documentation/devicetree/bindings/usb/vt8500-ehci.txt
> deleted file mode 100644
> index 5fb8fd6..0000000
> --- a/Documentation/devicetree/bindings/usb/vt8500-ehci.txt
> +++ /dev/null
> @@ -1,12 +0,0 @@
> -VIA VT8500 and Wondermedia WM8xxx SoC USB controllers.
> -
> -Required properties:
> - - compatible: Should be "via,vt8500-ehci" or "wm,prizm-ehci".
> - - reg: Address range of the ehci registers. size should be 0x200
> - - interrupts: Should contain the ehci interrupt.
> -
> -usb: ehci at D8007100 {
> -	compatible = "wm,prizm-ehci", "usb-ehci";
> -	reg = <0xD8007100 0x200>;
> -	interrupts = <1>;
> -};
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index a9707da..e28cbe0 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -255,6 +255,7 @@ config USB_EHCI_ATH79
>  
>  config USB_EHCI_HCD_PLATFORM
>  	tristate "Generic EHCI driver for a platform device"
> +	depends on !PPC_OF
>  	default n
>  	---help---
>  	  Adds an EHCI host driver for a generic platform device, which
> diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
> index 01536cf..5ebd0b7 100644
> --- a/drivers/usb/host/ehci-platform.c
> +++ b/drivers/usb/host/ehci-platform.c
> @@ -3,6 +3,7 @@
>   *
>   * Copyright 2007 Steven Brown <sbrown@cortland.com>
>   * Copyright 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
> + * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
>   *
>   * Derived from the ohci-ssb driver
>   * Copyright 2007 Michael Buesch <m@bues.ch>
> @@ -18,6 +19,7 @@
>   *
>   * Licensed under the GNU/GPL. See COPYING for details.
>   */
> +#include <linux/clk.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/err.h>
>  #include <linux/kernel.h>
> @@ -25,6 +27,7 @@
>  #include <linux/io.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> +#include <linux/phy/phy.h>
>  #include <linux/platform_device.h>
>  #include <linux/usb.h>
>  #include <linux/usb/hcd.h>
> @@ -33,6 +36,13 @@
>  #include "ehci.h"
>  
>  #define DRIVER_DESC "EHCI generic platform driver"
> +#define EHCI_MAX_CLKS 3
> +#define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv)
> +
> +struct ehci_platform_priv {
> +	struct clk *clks[EHCI_MAX_CLKS];
> +	struct phy *phy;
> +};
>  
>  static const char hcd_name[] = "ehci-platform";
>  
> @@ -64,38 +74,90 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
>  	return 0;
>  }
>  
> +static int ehci_platform_power_on(struct platform_device *dev)
> +{
> +	struct usb_hcd *hcd = platform_get_drvdata(dev);
> +	struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
> +	int clk, ret;
> +
> +	for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) {
> +		ret = clk_prepare_enable(priv->clks[clk]);
> +		if (ret)
> +			goto err_disable_clks;
> +	}
> +
> +	if (priv->phy) {
> +		ret = phy_init(priv->phy);
> +		if (ret)
> +			goto err_disable_clks;
> +
> +		ret = phy_power_on(priv->phy);
> +		if (ret)
> +			goto err_exit_phy;
> +	}
> +
> +	return 0;
> +
> +err_exit_phy:
> +	phy_exit(priv->phy);
> +err_disable_clks:
> +	while (--clk >= 0)
> +		clk_disable_unprepare(priv->clks[clk]);
> +
> +	return ret;
> +}
> +
> +static void ehci_platform_power_off(struct platform_device *dev)
> +{
> +	struct usb_hcd *hcd = platform_get_drvdata(dev);
> +	struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
> +	int clk;
> +
> +	if (priv->phy) {
> +		phy_power_off(priv->phy);
> +		phy_exit(priv->phy);
> +	}
> +
> +	for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--)
> +		if (priv->clks[clk])
> +			clk_disable_unprepare(priv->clks[clk]);
> +}
> +
>  static struct hc_driver __read_mostly ehci_platform_hc_driver;
>  
>  static const struct ehci_driver_overrides platform_overrides __initconst = {
> -	.reset =	ehci_platform_reset,
> +	.reset =		ehci_platform_reset,
> +	.extra_priv_size =	sizeof(struct ehci_platform_priv),
>  };
>  
> -static struct usb_ehci_pdata ehci_platform_defaults;
> +static struct usb_ehci_pdata ehci_platform_defaults = {
> +	.power_on =		ehci_platform_power_on,
> +	.power_suspend =	ehci_platform_power_off,
> +	.power_off =		ehci_platform_power_off,
> +};
>  
>  static int ehci_platform_probe(struct platform_device *dev)
>  {
>  	struct usb_hcd *hcd;
>  	struct resource *res_mem;
> -	struct usb_ehci_pdata *pdata;
> -	int irq;
> -	int err;
> +	struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
> +	struct ehci_platform_priv *priv;
> +	int err, irq, clk = 0;
>  
>  	if (usb_disabled())
>  		return -ENODEV;
>  
>  	/*
> -	 * use reasonable defaults so platforms don't have to provide these.
> -	 * with DT probing on ARM, none of these are set.
> +	 * Use reasonable defaults so platforms don't have to provide these
> +	 * with DT probing on ARM.
>  	 */
> -	if (!dev_get_platdata(&dev->dev))
> -		dev->dev.platform_data = &ehci_platform_defaults;
> +	if (!pdata)
> +		pdata = &ehci_platform_defaults;
>  
>  	err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
>  	if (err)
>  		return err;
>  
> -	pdata = dev_get_platdata(&dev->dev);
> -
>  	irq = platform_get_irq(dev, 0);
>  	if (irq < 0) {
>  		dev_err(&dev->dev, "no irq provided");
> @@ -107,17 +169,40 @@ static int ehci_platform_probe(struct platform_device *dev)
>  		return -ENXIO;
>  	}
>  
> +	hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev,
> +			     dev_name(&dev->dev));
> +	if (!hcd)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(dev, hcd);
> +	dev->dev.platform_data = pdata;
> +	priv = hcd_to_ehci_priv(hcd);
> +
> +	if (pdata == &ehci_platform_defaults && dev->dev.of_node) {
> +		priv->phy = devm_phy_get(&dev->dev, "usb");
> +		if (IS_ERR(priv->phy)) {
> +			err = PTR_ERR(priv->phy);
> +			if (err == -EPROBE_DEFER)
> +				goto err_put_hcd;
> +			priv->phy = NULL;
> +		}
> +
> +		for (clk = 0; clk < EHCI_MAX_CLKS; clk++) {
> +			priv->clks[clk] = of_clk_get(dev->dev.of_node, clk);
> +			if (IS_ERR(priv->clks[clk])) {
> +				err = PTR_ERR(priv->clks[clk]);
> +				if (err == -EPROBE_DEFER)
> +					goto err_put_clks;
> +				priv->clks[clk] = NULL;
> +				break;
> +			}
> +		}
> +	}
> +
>  	if (pdata->power_on) {
>  		err = pdata->power_on(dev);
>  		if (err < 0)
> -			return err;
> -	}
> -
> -	hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev,
> -			     dev_name(&dev->dev));
> -	if (!hcd) {
> -		err = -ENOMEM;
> -		goto err_power;
> +			goto err_put_clks;
>  	}
>  
>  	hcd->rsrc_start = res_mem->start;
> @@ -126,22 +211,28 @@ static int ehci_platform_probe(struct platform_device *dev)
>  	hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);
>  	if (IS_ERR(hcd->regs)) {
>  		err = PTR_ERR(hcd->regs);
> -		goto err_put_hcd;
> +		goto err_power;
>  	}
>  	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
>  	if (err)
> -		goto err_put_hcd;
> +		goto err_power;
>  
>  	device_wakeup_enable(hcd->self.controller);
>  	platform_set_drvdata(dev, hcd);
>  
>  	return err;
>  
> -err_put_hcd:
> -	usb_put_hcd(hcd);
>  err_power:
>  	if (pdata->power_off)
>  		pdata->power_off(dev);
> +err_put_clks:
> +	while (--clk >= 0)
> +		clk_put(priv->clks[clk]);
> +err_put_hcd:
> +	if (pdata == &ehci_platform_defaults)
> +		dev->dev.platform_data = NULL;
> +
> +	usb_put_hcd(hcd);
>  
>  	return err;
>  }
> @@ -150,13 +241,19 @@ static int ehci_platform_remove(struct platform_device *dev)
>  {
>  	struct usb_hcd *hcd = platform_get_drvdata(dev);
>  	struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
> +	struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
> +	int clk;
>  
>  	usb_remove_hcd(hcd);
> -	usb_put_hcd(hcd);
>  
>  	if (pdata->power_off)
>  		pdata->power_off(dev);
>  
> +	for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++)
> +		clk_put(priv->clks[clk]);
> +
> +	usb_put_hcd(hcd);
> +
>  	if (pdata == &ehci_platform_defaults)
>  		dev->dev.platform_data = NULL;
>  
> @@ -207,8 +304,10 @@ static int ehci_platform_resume(struct device *dev)
>  static const struct of_device_id vt8500_ehci_ids[] = {
>  	{ .compatible = "via,vt8500-ehci", },
>  	{ .compatible = "wm,prizm-ehci", },
> +	{ .compatible = "usb-ehci", },
>  	{}
>  };
> +MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
>  
>  static const struct platform_device_id ehci_platform_table[] = {
>  	{ "ehci-platform", 0 },
> 

^ permalink raw reply

* [linux-sunxi] Re: [PATCH 1/3] mfd: axp20x: Add mfd driver for axp20x PMIC
From: Lee Jones @ 2014-02-11  9:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAOQ7t2axObbBpVcF0z826Q2b0DaCx+wr0fvJ1X9Ek33174pOwA@mail.gmail.com>

> >> +static const struct regmap_irq axp20x_regmap_irqs[] = {
> >> +     AXP20X_IRQ(ACIN_OVER_V,         0, 7),
> >> +     AXP20X_IRQ(ACIN_PLUGIN,         0, 6),

[...]

> >> +     AXP20X_IRQ(GPIO1_INPUT,         4, 1),
> >> +     AXP20X_IRQ(GPIO0_INPUT,         4, 0),
> >> +};
> >
> > Where are these handled i.e. where is the irq_handler located?
> 
> Each one is used by a different driver for each subsystem of the MFD,
> so each driver will have a specific irq_handler. I need the full list
> here to register with regmap_add_irq_chip() the generic

> regmap_irq_thread.

Okay, this is all I needed.  I must confess that I haven't _used_
regmap_add_irq_chip() before and was a little confused as to how it
worked exactly.  We used to handle hierarchical IRQs ourselves, but
this is better I think.

<snip>

> >> +const struct of_device_id axp20x_of_match[] = {
> >> +     { .compatible = "x-powers,axp20x", .data = (void *)AXP20X },
> >
> > There's no need to add device IDs if you only support one device.
> 
> Ok. But what if in the future we want to add a new device?

Then we add support for device identification. Until then, it's just
meaningless cruft.

> >> +     { },
> >> +};
> >> +
> >> +static struct axp20x_dev *axp20x_pm_power_off;
> >
> > This looks pretty unconventional. What's the point of it?
> 
> On a single board we can have multiple AXPs so I track which one is in
> charge of powering off the board (and to get the correct device in the
> axp20x_power_off())

Is it this device's responsibility to shut down the _entire_ board? Or
does the call below only turn off _this_ device?

> >> +static void axp20x_power_off(void)
> >> +{
> >> +     regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL, 0x80);

<snip>

> >> +     of_id = of_match_device(axp20x_of_match, &i2c->dev);
> >> +     if (!of_id) {
> >> +             dev_err(&i2c->dev, "Unable to setup AXP20X data\n");
> >> +             return -ENODEV;
> >> +     }
> >> +     axp20x->variant = (int) of_id->data;
> >
> > Lots of code here surrounding added device support, but only one
> > device is supported. Why so?
> 
> Because at the moment I support only axp202 and axp209 but I wanted
> something future-proof

Nothing is future-proof. :)

You only need to add this functionality when it's going to be
utilised.

> >> +     axp20x->i2c_client = i2c;
> >> +     i2c_set_clientdata(i2c, axp20x);
> >> +
> >> +     axp20x->dev = &i2c->dev;
> >> +     dev_set_drvdata(axp20x->dev, axp20x);
> >
> > Do you make use of all this saving of the device container?
> >
> > If so, where?
> 
> In the drivers for subsystems (input, regulators, gpio, etc..)

Can you link me to the patches please?  Any reason why they're not in
this set?  By submitting them together you give the Maintainers a good
over-view on how the system works together.

> > Also:
> >   i2c_set_clientdata(i2c)
> >
> > and:
> >   dev_set_drvdata(i2c->dev);
> >
> > ... do exactly the same thing i.e. set i2c->dev->p->device_data.
> 
> Right.

Right.  So why are you doing them both?

<snip>

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

^ permalink raw reply

* [PATCH] ARM: mm: support big-endian page tables
From: Jianguo Wu @ 2014-02-11  9:20 UTC (permalink / raw)
  To: linux-arm-kernel

When enable LPAE and big-endian in a hisilicon board, while specify
mem=384M mem=512M at 7680M, will get bad page state:

Freeing unused kernel memory: 180K (c0466000 - c0493000)
BUG: Bad page state in process init  pfn:fa442
page:c7749840 count:0 mapcount:-1 mapping:  (null) index:0x0
page flags: 0x40000400(reserved)
Modules linked in:
CPU: 0 PID: 1 Comm: init Not tainted 3.10.27+ #66
[<c000f5f0>] (unwind_backtrace+0x0/0x11c) from [<c000cbc4>] (show_stack+0x10/0x14)
[<c000cbc4>] (show_stack+0x10/0x14) from [<c009e448>] (bad_page+0xd4/0x104)
[<c009e448>] (bad_page+0xd4/0x104) from [<c009e520>] (free_pages_prepare+0xa8/0x14c)
[<c009e520>] (free_pages_prepare+0xa8/0x14c) from [<c009f8ec>] (free_hot_cold_page+0x18/0xf0)
[<c009f8ec>] (free_hot_cold_page+0x18/0xf0) from [<c00b5444>] (handle_pte_fault+0xcf4/0xdc8)
[<c00b5444>] (handle_pte_fault+0xcf4/0xdc8) from [<c00b6458>] (handle_mm_fault+0xf4/0x120)
[<c00b6458>] (handle_mm_fault+0xf4/0x120) from [<c0013754>] (do_page_fault+0xfc/0x354)
[<c0013754>] (do_page_fault+0xfc/0x354) from [<c0008400>] (do_DataAbort+0x2c/0x90)
[<c0008400>] (do_DataAbort+0x2c/0x90) from [<c0008fb4>] (__dabt_usr+0x34/0x40)

The bad pfn:fa442 is not system memory(mem=384M mem=512M at 7680M), after debugging,
I find in page fault handler, will get wrong pfn from pte just after set pte,
as follow:
do_anonymous_page()
{
	...
	set_pte_at(mm, address, page_table, entry);
	
	//debug code
	pfn = pte_pfn(entry);
	pr_info("pfn:0x%lx, pte:0x%llx\n", pfn, pte_val(entry));

	//read out the pte just set
	new_pte = pte_offset_map(pmd, address);
	new_pfn = pte_pfn(*new_pte);
	pr_info("new pfn:0x%lx, new pte:0x%llx\n", pfn, pte_val(entry));
	...
}

pfn:   0x1fa4f5,     pte:0xc00001fa4f575f
new_pfn:0xfa4f5, new_pte:0xc00000fa4f5f5f	//new pfn/pte is wrong.

The bug is happened in cpu_v7_set_pte_ext(ptep, pte):
when pte is 64-bit, for little-endian, will store low 32-bit in r2,
high 32-bit in r3; for big-endian, will store low 32-bit in r3,
high 32-bit in r2, this will cause wrong pfn stored in pte,
so we should exchange r2 and r3 for big-endian.

Signed-off-by: Jianguo Wu <wujianguo@huawei.com>
---
 arch/arm/mm/proc-v7-3level.S |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index 6ba4bd9..71b3892 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -65,6 +65,15 @@ ENDPROC(cpu_v7_switch_mm)
  */
 ENTRY(cpu_v7_set_pte_ext)
 #ifdef CONFIG_MMU
+#ifdef CONFIG_CPU_ENDIAN_BE8
+	tst	r3, #L_PTE_VALID
+	beq	1f
+	tst	r2, #1 << (57 - 32)		@ L_PTE_NONE
+	bicne	r3, #L_PTE_VALID
+	bne	1f
+	tst	r2, #1 << (55 - 32)		@ L_PTE_DIRTY
+	orreq	r3, #L_PTE_RDONLY
+#else
 	tst	r2, #L_PTE_VALID
 	beq	1f
 	tst	r3, #1 << (57 - 32)		@ L_PTE_NONE
@@ -72,6 +81,7 @@ ENTRY(cpu_v7_set_pte_ext)
 	bne	1f
 	tst	r3, #1 << (55 - 32)		@ L_PTE_DIRTY
 	orreq	r2, #L_PTE_RDONLY
+#endif
 1:	strd	r2, r3, [r0]
 	ALT_SMP(W(nop))
 	ALT_UP (mcr	p15, 0, r0, c7, c10, 1)		@ flush_pte
-- 1.7.1 

^ permalink raw reply related

* [PATCH 00/12] ARM: S3C24XX: convert s3c2410, s3c2440 s3c2442 to common clock framework
From: Heiko Stübner @ 2014-02-11  9:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAL5jtJm=Ehwk2ZyCJaW0NfMn8XM893r1hdCVWs2skMv4+M7yXQ@mail.gmail.com>

Hi Kukjin,

Am Dienstag, 11. Februar 2014, 11:46:13 schrieb Kukjin Kim:
> 2014-02-10 1:26 GMT+05:30 Tomasz Figa <tomasz.figa@gmail.com>:
> > 
> > For patches 4, 5, 9, 10, 11, 12:
> > 
> > Reviewed-by: Tomasz Figa <t.figa@samsung.com>
> > 
> > For patches 6, 7:
> > 
> > Acked-by: Tomasz Figa <t.figa@samsung.com>
> 
> Really nice series.
> Heiko, thanks for your effort and Tomasz, thanks for your review and ack.
> 
> OK, I'll apply this whole series and this will be sent to arm-soc in this
> week.

not this fast :-)

Tomasz hat some comments about the two clk-drivers included, which I'll need 
to address first.

Also, this series, as well as the other two at the moment conflict with Tomasz' 
clock-pm changes. Our (Tomasz and me) current plan was for me to respin the 3 
ccf conversion series against his clock-pm series, which I hope to do in the 
next two days or so.


Heiko

^ permalink raw reply

* [GIT PULL] Ux500 AB8500 DT conversion
From: Linus Walleij @ 2014-02-11  9:24 UTC (permalink / raw)
  To: linux-arm-kernel

Hi ARM SoC folks,

the following converts the AB8500 pin configuration from board
file to device tree and removes the final pin settings board file
config.

Please pull it into an apropriate Ux500 device tree branch, I'll
possibly send more Ux500 DT stuff on top of this.

Yours,
Linus Walleij

The following changes since commit 38dbfb59d1175ef458d006556061adeaa8751b72:

  Linus 3.14-rc1 (2014-02-02 16:42:13 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
tags/ab8500-dt-for-arm-soc

for you to fetch changes up to 77ad9dfc2c7e3b5ce49efc5c0c215f7c36c91cf2:

  ARM: ux500: move last AB8505 set-up to DT (2014-02-04 20:50:55 +0100)

----------------------------------------------------------------
AB8500 device tree conversion and the deletion of all
pin-related configuration from the Ux500 board files.

----------------------------------------------------------------
Linus Walleij (10):
      ARM: ux500: move AB8500 GPIOs to device tree
      ARM: ux500: move AB8500 YCBCR settings to device tree
      ARM: ux500: move AB8500 PWM out settings to device tree
      ARM: ux500: move AB8500 audio interface 1 settings to DT
      ARM: ux500: move AB8500 USB UICC settings to DT
      ARM: ux500: move AB8500 DMIC settings to DT
      ARM: ux500: move AB8500 EXTCPENA from board file to DT
      ARM: ux500: move AB8500 modem I2C settings to DT
      ARM: ux500: move AB8500 clock out pins to DT
      ARM: ux500: move last AB8505 set-up to DT

 arch/arm/boot/dts/ste-href-ab8500.dtsi  | 428 ++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/ste-href-ab8505.dtsi  | 240 ++++++++++++++++++
 arch/arm/boot/dts/ste-hrefprev60.dtsi   |   1 +
 arch/arm/boot/dts/ste-hrefv60plus.dtsi  |   1 +
 arch/arm/boot/dts/ste-snowball.dts      |   1 +
 arch/arm/mach-ux500/Makefile            |   1 -
 arch/arm/mach-ux500/board-mop500-pins.c | 291 ----------------------
 arch/arm/mach-ux500/board-mop500.h      |   4 -
 arch/arm/mach-ux500/cpu-db8500.c        |  10 -
 9 files changed, 671 insertions(+), 306 deletions(-)
 create mode 100644 arch/arm/boot/dts/ste-href-ab8500.dtsi
 create mode 100644 arch/arm/boot/dts/ste-href-ab8505.dtsi
 delete mode 100644 arch/arm/mach-ux500/board-mop500-pins.c

^ permalink raw reply

* [PATCH 2/5] clocksource: qcom: Move clocksource code out of mach-msm
From: Daniel Lezcano @ 2014-02-11  9:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391553421-26914-3-git-send-email-galak@codeaurora.org>

On 02/04/2014 11:36 PM, Kumar Gala wrote:
> We intent to share the clocksource code for MSM platforms between legacy
> and multiplatform supported qcom SoCs.
>
> Acked-by: Olof Johansson <olof@lixom.net>
> Signed-off-by: Kumar Gala <galak@codeaurora.org>

Hi Kumar,

through which tree do you expect this patch to be upstream ?



-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply

* [PATCH v3 7/7] devicetree: bindings: Document PM8921/8058 PMICs
From: Lee Jones @ 2014-02-11  9:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389206270-3728-8-git-send-email-sboyd@codeaurora.org>

> PM8921 and PM8058 are PMICs found paired with MSM8960 and MSM8660
> devices respectively. They contain subdevices such as keypads,
> RTCs, regulators, clocks, etc.
> 
> Cc: <devicetree@vger.kernel.org>
> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> ---
>  .../devicetree/bindings/mfd/qcom,pm8xxx.txt        | 63 ++++++++++++++++++++++
>  1 file changed, 63 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/qcom,pm8xxx.txt
> 
> diff --git a/Documentation/devicetree/bindings/mfd/qcom,pm8xxx.txt b/Documentation/devicetree/bindings/mfd/qcom,pm8xxx.txt
> new file mode 100644
> index 000000000000..e3fe625ffd58
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/qcom,pm8xxx.txt
> @@ -0,0 +1,63 @@

<snip>

> +- interrupts:
> +	Usage: required
> +	Value type: <prop-encoded-array>

Either provide an example or a comment to see the description of
#interrupt-cells 

> +	Definition: specifies the interrupt that indicates a subdevice
> +		    has generated an interrupt (summary interrupt). The
> +		    format of the specifier is defined by the binding document
> +		    describing the node's interrupt parent.
> +
> +- #interrupt-cells:
> +	Usage: required
> +	Value type : <u32>
> +	Definition: must be 2. Specifies the number of cells needed to encode
> +		    an interrupt source. The 1st cell contains the interrupt
> +		    number. The 2nd cell is the trigger type and level flags
> +		    encoded as follows:
> +
> +			1 = low-to-high edge triggered
> +			2 = high-to-low edge triggered
> +			4 = active high level-sensitive
> +			8 = active low level-sensitive

Actually I'd prefer if you used the definitions in:
  dt-bindings/interrupt-controller/irq.h

> +- interrupt-controller:
> +	Usage: required
> +	Value type: <empty>
> +	Definition: identifies this node as an interrupt controller
> +
> +EXAMPLE
> +
> +	pmicintc: pmic at 0 {
> +		compatible = "qcom,pm8921";
> +		interrupts = <104 8>;

As above.

> +		#interrupt-cells = <2>;
> +		interrupt-controller;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		pwrkey {
> +			compatible = "qcom,pm8921-pwrkey";
> +			interrupt-parent = <&pmicintc>;
> +			interrupts = <50 1>, <51 1>;

As above.

> +		};
> +	};
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> hosted by The Linux Foundation

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

^ permalink raw reply

* [PATCH V6 00/12]PCI:Add SPEAr13xx PCie support
From: Mohit Kumar @ 2014-02-11  9:29 UTC (permalink / raw)
  To: linux-arm-kernel

Patch# 1 and 2: Improvement and fixes for SPEAr13xx support.
Patch# 3,5 and 8: Add DT bindings for miphy40lp, misc and pcie node
Patch# 4,6 and 7: Add miphy40lp skelten driver and support for spear1310/40 
miphy wrapper.
Patch# 9-11: Add SPEAr13xx PCIe driver and dt support.

These pathes are tested with linux-3.14-rc1 with following patch on the top of
it:
Author: Balaji T K <balajitk@ti.com>
Date:   Mon Jan 20 16:41:27 2014 +0200

    ata: ahci_platform: Manage SATA PHY

Tested with SPEAr1310 evaluation board:
	- INTEL PRO 100/100 EP card
	- USB xhci gen2 card
 	- Above cards connected through LeCROY PTC switch

Modifications for SATA are tested with SPEAr1340-evb board

Changes since v5:
- Split DT bindings for misc, miphy-40lp and pcie node into sepearte patches
- Merge config options PCIE_SPEAR13XX and PCI_MSI into defconfig patch 
- Incorporated other minor comments
Changes since v4:
- Uses per device function pointers passed from .data field to
  the of_device_id instead of of_device_is_compatible.
- Incorporated other minor comments from v4

Changes since v3:
- Phy driver renamed to phy-miphy40lp
- ahci phy hook patch used as suggested by Arnd
- Incorporated other minor comments from v3

Changes since v2:
- Incorporated comments to move SPEAr13xx PCIe and SATA phy specific routines to
  the phy framework
- Modify ahci driver to include phy hooks
- phy-core driver modifications for subsys_initcall() 
 
Changes since v1:
- Few patches of the series are already accepted and applied to mainline e.g.
 pcie designware driver improvements,fixes for IO translation bug, PCIe dw
 driver maintainer. So dropped these from v2.
- Incorporated comment to move the common/reset PCIe code to the seperate driver
- PCIe and SATA share common PHY configuration registers, so move SATA
 platform code to the system config driver
Fourth patch is improves pcie designware driver and fixes the IO
translation bug. IO translation bug fix leads to the working of PCIe EP devices
connected to RC through switch.

PCIe driver support for SPEAr1310/40 platform board is added.

These patches are tested with SPEAr1310 evaluation board:
	- INTEL PRO 100/100 EP card
	- USB xhci gen2 card
 	- Above cards connected through LeCROY PTC switch

Cc: linux-arm-kernel at lists.infradead.org
Cc: devicetree at vger.kernel.org
Cc: linux-ide at vger.kernel.org
Cc: linux-pci at vger.kernel.org
Cc: spear-devel at list.st.com
Cc: linux-kernel at vger.kernel.org
Cc: linux-pm at vger.kernel.org

Mohit Kumar (2):
  SPEAr13xx: defconfig: Update
  MAINTAINERS: Add ST SPEAr13xx PCIe driver maintainer

Pratyush Anand (10):
  clk: SPEAr13XX: Fix pcie clock name
  SPEAr13XX: Fix static mapping table
  phy: st-miphy40lp: Add binding information
  phy: st-miphy40lp: Add skeleton driver
  SPEAr: misc: Add binding information
  SPEAr13xx: Fixup: Move SPEAr1340 SATA platform code to phy driver
  phy: st-miphy-40lp: Add SPEAr1310 and SPEAr1340 PCIe phy support
  SPEAr13xx: Add binding information for PCIe controller
  SPEAr13XX: dts: Add PCIe node information
  pcie: SPEAr13xx: Add designware wrapper support

 .../devicetree/bindings/arm/spear-misc.txt         |    9 +
 .../devicetree/bindings/pci/spear13xx-pcie.txt     |   14 +
 .../devicetree/bindings/phy/st-miphy40lp.txt       |   18 +
 MAINTAINERS                                        |    6 +
 arch/arm/boot/dts/spear1310-evb.dts                |    4 +
 arch/arm/boot/dts/spear1310.dtsi                   |   93 ++++-
 arch/arm/boot/dts/spear1340-evb.dts                |    4 +
 arch/arm/boot/dts/spear1340.dtsi                   |   31 ++-
 arch/arm/boot/dts/spear13xx.dtsi                   |    9 +-
 arch/arm/configs/spear13xx_defconfig               |   16 +
 arch/arm/mach-spear/Kconfig                        |    3 +
 arch/arm/mach-spear/include/mach/spear.h           |    4 +-
 arch/arm/mach-spear/spear1340.c                    |  127 +-----
 arch/arm/mach-spear/spear13xx.c                    |    2 +-
 drivers/clk/spear/spear1310_clock.c                |    6 +-
 drivers/clk/spear/spear1340_clock.c                |    2 +-
 drivers/pci/host/Kconfig                           |    8 +
 drivers/pci/host/Makefile                          |    1 +
 drivers/pci/host/pcie-spear13xx.c                  |  414 +++++++++++++++
 drivers/phy/Kconfig                                |    7 +
 drivers/phy/Makefile                               |    1 +
 drivers/phy/phy-miphy40lp.c                        |  543 ++++++++++++++++++++
 22 files changed, 1183 insertions(+), 139 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/spear-misc.txt
 create mode 100644 Documentation/devicetree/bindings/pci/spear13xx-pcie.txt
 create mode 100644 Documentation/devicetree/bindings/phy/st-miphy40lp.txt
 create mode 100644 drivers/pci/host/pcie-spear13xx.c
 create mode 100644 drivers/phy/phy-miphy40lp.c

^ permalink raw reply

* [PATCH V6 01/12] clk: SPEAr13XX: Fix pcie clock name
From: Mohit Kumar @ 2014-02-11  9:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1392109054.git.mohit.kumar@st.com>

From: Pratyush Anand <pratyush.anand@st.com>

Follow dt clock naming convention for PCIe clocks.

Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Mohit Kumar <mohit.kumar@st.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: spear-devel at list.st.com
Cc: linux-arm-kernel at lists.infradead.org
---
 drivers/clk/spear/spear1310_clock.c |    6 +++---
 drivers/clk/spear/spear1340_clock.c |    2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c
index 65894f7..4daa597 100644
--- a/drivers/clk/spear/spear1310_clock.c
+++ b/drivers/clk/spear/spear1310_clock.c
@@ -742,19 +742,19 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
 	clk = clk_register_gate(NULL, "pcie_sata_0_clk", "ahb_clk", 0,
 			SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_0_CLK_ENB,
 			0, &_lock);
-	clk_register_clkdev(clk, NULL, "dw_pcie.0");
+	clk_register_clkdev(clk, NULL, "b1000000.pcie");
 	clk_register_clkdev(clk, NULL, "b1000000.ahci");
 
 	clk = clk_register_gate(NULL, "pcie_sata_1_clk", "ahb_clk", 0,
 			SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_1_CLK_ENB,
 			0, &_lock);
-	clk_register_clkdev(clk, NULL, "dw_pcie.1");
+	clk_register_clkdev(clk, NULL, "b1800000.pcie");
 	clk_register_clkdev(clk, NULL, "b1800000.ahci");
 
 	clk = clk_register_gate(NULL, "pcie_sata_2_clk", "ahb_clk", 0,
 			SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_2_CLK_ENB,
 			0, &_lock);
-	clk_register_clkdev(clk, NULL, "dw_pcie.2");
+	clk_register_clkdev(clk, NULL, "b4000000.pcie");
 	clk_register_clkdev(clk, NULL, "b4000000.ahci");
 
 	clk = clk_register_gate(NULL, "sysram0_clk", "ahb_clk", 0,
diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c
index fe835c1..5a5c664 100644
--- a/drivers/clk/spear/spear1340_clock.c
+++ b/drivers/clk/spear/spear1340_clock.c
@@ -839,7 +839,7 @@ void __init spear1340_clk_init(void __iomem *misc_base)
 	clk = clk_register_gate(NULL, "pcie_sata_clk", "ahb_clk", 0,
 			SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_PCIE_SATA_CLK_ENB,
 			0, &_lock);
-	clk_register_clkdev(clk, NULL, "dw_pcie");
+	clk_register_clkdev(clk, NULL, "b1000000.pcie");
 	clk_register_clkdev(clk, NULL, "b1000000.ahci");
 
 	clk = clk_register_gate(NULL, "sysram0_clk", "ahb_clk", 0,
-- 
1.7.0.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