LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v6 08/17] spi: mpc512x: adjust to OF based clock lookup
From: Mark Rutland @ 2013-12-02  9:50 UTC (permalink / raw)
  To: Gerhard Sittig
  Cc: Mike Turquette, Detlev Zundel, linux-spi@vger.kernel.org,
	Mark Brown, Scott Wood, Anatolij Gustschin,
	linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <1385851897-23475-9-git-send-email-gsi@denx.de>

On Sat, Nov 30, 2013 at 10:51:28PM +0000, Gerhard Sittig wrote:
> after device tree based clock lookup became available, the peripheral
> driver need no longer construct clock names which include the PSC index,
> remove the "psc%d_mclk" template and unconditionally use 'mclk'
> 
> acquire and release the 'ipg' clock item for register access as well

For this and the other peripheral updates, it would be nice to have the
expected clock-names entries added to the respective binding documents.
Otherwise this looks fine to me.

Thanks,
Mark.

> 
> Cc: Mark Brown <broonie@kernel.org>
> Cc: linux-spi@vger.kernel.org
> Signed-off-by: Gerhard Sittig <gsi@denx.de>
> ---
>  drivers/spi/spi-mpc512x-psc.c |   26 ++++++++++++++++++--------
>  1 file changed, 18 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c
> index 9602bbd8d7ea..de66c676c248 100644
> --- a/drivers/spi/spi-mpc512x-psc.c
> +++ b/drivers/spi/spi-mpc512x-psc.c
> @@ -40,6 +40,7 @@ struct mpc512x_psc_spi {
>  	unsigned int irq;
>  	u8 bits_per_word;
>  	struct clk *clk_mclk;
> +	struct clk *clk_ipg;
>  	u32 mclk_rate;
>  
>  	struct completion txisrdone;
> @@ -475,8 +476,6 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
>  	struct spi_master *master;
>  	int ret;
>  	void *tempp;
> -	int psc_num;
> -	char clk_name[16];
>  	struct clk *clk;
>  
>  	master = spi_alloc_master(dev, sizeof *mps);
> @@ -520,9 +519,7 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
>  		goto free_master;
>  	init_completion(&mps->txisrdone);
>  
> -	psc_num = master->bus_num;
> -	snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num);
> -	clk = devm_clk_get(dev, clk_name);
> +	clk = devm_clk_get(dev, "mclk");
>  	if (IS_ERR(clk)) {
>  		ret = PTR_ERR(clk);
>  		goto free_irq;
> @@ -533,17 +530,29 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
>  	mps->clk_mclk = clk;
>  	mps->mclk_rate = clk_get_rate(clk);
>  
> +	clk = devm_clk_get(dev, "ipg");
> +	if (IS_ERR(clk)) {
> +		ret = PTR_ERR(clk);
> +		goto free_mclk_clock;
> +	}
> +	ret = clk_prepare_enable(clk);
> +	if (ret)
> +		goto free_mclk_clock;
> +	mps->clk_ipg = clk;
> +
>  	ret = mpc512x_psc_spi_port_config(master, mps);
>  	if (ret < 0)
> -		goto free_clock;
> +		goto free_ipg_clock;
>  
>  	ret = devm_spi_register_master(dev, master);
>  	if (ret < 0)
> -		goto free_clock;
> +		goto free_ipg_clock;
>  
>  	return ret;
>  
> -free_clock:
> +free_ipg_clock:
> +	clk_disable_unprepare(mps->clk_ipg);
> +free_mclk_clock:
>  	clk_disable_unprepare(mps->clk_mclk);
>  free_irq:
>  	free_irq(mps->irq, mps);
> @@ -561,6 +570,7 @@ static int mpc512x_psc_spi_do_remove(struct device *dev)
>  	struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
>  
>  	clk_disable_unprepare(mps->clk_mclk);
> +	clk_disable_unprepare(mps->clk_ipg);
>  	free_irq(mps->irq, mps);
>  	if (mps->psc)
>  		iounmap(mps->psc);
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

^ permalink raw reply

* Re: [PATCH v6 02/17] dts: mpc512x: introduce dt-bindings/clock/ header
From: Mark Rutland @ 2013-12-02  9:46 UTC (permalink / raw)
  To: Gerhard Sittig
  Cc: devicetree@vger.kernel.org, Mike Turquette, Pawel Moll,
	Detlev Zundel, Stephen Warren, rob.herring@calxeda.com,
	Scott Wood, Anatolij Gustschin, linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org, Ian Campbell
In-Reply-To: <1385851897-23475-3-git-send-email-gsi@denx.de>

On Sat, Nov 30, 2013 at 10:51:22PM +0000, Gerhard Sittig wrote:
> introduce a dt-bindings/ header file for MPC512x clocks,
> providing symbolic identifiers for those SoC clocks which
> clients will reference from their device tree nodes

There should be a binding document update to go with this, pointing out
that this include file defines the set of clock IDs for the MPC512x
clocks.

Otherwise, this looks fine to me.

Mark.

> 
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Stephen Warren <swarren@wwwdotorg.org>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: devicetree@vger.kernel.org
> Reviewed-by: Mike Turquette <mturquette@linaro.org>	# for v3: w/o bdlc, PSC ipg
> Signed-off-by: Gerhard Sittig <gsi@denx.de>
> ---
>  include/dt-bindings/clock/mpc512x-clock.h |   69 +++++++++++++++++++++++++++++
>  1 file changed, 69 insertions(+)
>  create mode 100644 include/dt-bindings/clock/mpc512x-clock.h
> 
> diff --git a/include/dt-bindings/clock/mpc512x-clock.h b/include/dt-bindings/clock/mpc512x-clock.h
> new file mode 100644
> index 000000000000..9e81b3b99a32
> --- /dev/null
> +++ b/include/dt-bindings/clock/mpc512x-clock.h
> @@ -0,0 +1,69 @@
> +/*
> + * This header provides constants for MPC512x clock specs in DT bindings.
> + */
> +
> +#ifndef _DT_BINDINGS_CLOCK_MPC512x_CLOCK_H
> +#define _DT_BINDINGS_CLOCK_MPC512x_CLOCK_H
> +
> +#define MPC512x_CLK_DUMMY		0
> +#define MPC512x_CLK_REF			1
> +#define MPC512x_CLK_SYS			2
> +#define MPC512x_CLK_DIU			3
> +#define MPC512x_CLK_VIU			4
> +#define MPC512x_CLK_CSB			5
> +#define MPC512x_CLK_E300		6
> +#define MPC512x_CLK_IPS			7
> +#define MPC512x_CLK_FEC			8
> +#define MPC512x_CLK_SATA		9
> +#define MPC512x_CLK_PATA		10
> +#define MPC512x_CLK_NFC			11
> +#define MPC512x_CLK_LPC			12
> +#define MPC512x_CLK_MBX_BUS		13
> +#define MPC512x_CLK_MBX			14
> +#define MPC512x_CLK_MBX_3D		15
> +#define MPC512x_CLK_AXE			16
> +#define MPC512x_CLK_USB1		17
> +#define MPC512x_CLK_USB2		18
> +#define MPC512x_CLK_I2C			19
> +#define MPC512x_CLK_MSCAN0_MCLK		20
> +#define MPC512x_CLK_MSCAN1_MCLK		21
> +#define MPC512x_CLK_MSCAN2_MCLK		22
> +#define MPC512x_CLK_MSCAN3_MCLK		23
> +#define MPC512x_CLK_BDLC		24
> +#define MPC512x_CLK_SDHC		25
> +#define MPC512x_CLK_PCI			26
> +#define MPC512x_CLK_PSC_MCLK_IN		27
> +#define MPC512x_CLK_SPDIF_TX		28
> +#define MPC512x_CLK_SPDIF_RX		29
> +#define MPC512x_CLK_SPDIF_MCLK		30
> +#define MPC512x_CLK_SPDIF		31
> +#define MPC512x_CLK_AC97		32
> +#define MPC512x_CLK_PSC0_MCLK		33
> +#define MPC512x_CLK_PSC1_MCLK		34
> +#define MPC512x_CLK_PSC2_MCLK		35
> +#define MPC512x_CLK_PSC3_MCLK		36
> +#define MPC512x_CLK_PSC4_MCLK		37
> +#define MPC512x_CLK_PSC5_MCLK		38
> +#define MPC512x_CLK_PSC6_MCLK		39
> +#define MPC512x_CLK_PSC7_MCLK		40
> +#define MPC512x_CLK_PSC8_MCLK		41
> +#define MPC512x_CLK_PSC9_MCLK		42
> +#define MPC512x_CLK_PSC10_MCLK		43
> +#define MPC512x_CLK_PSC11_MCLK		44
> +#define MPC512x_CLK_PSC_FIFO		45
> +#define MPC512x_CLK_PSC0		46
> +#define MPC512x_CLK_PSC1		47
> +#define MPC512x_CLK_PSC2		48
> +#define MPC512x_CLK_PSC3		49
> +#define MPC512x_CLK_PSC4		50
> +#define MPC512x_CLK_PSC5		51
> +#define MPC512x_CLK_PSC6		52
> +#define MPC512x_CLK_PSC7		53
> +#define MPC512x_CLK_PSC8		54
> +#define MPC512x_CLK_PSC9		55
> +#define MPC512x_CLK_PSC10		56
> +#define MPC512x_CLK_PSC11		57
> +
> +#define MPC512x_CLK_LAST_PUBLIC		57
> +
> +#endif
> -- 
> 1.7.10.4
> 
> 

^ permalink raw reply

* [PATCH] powerpc: fix xmon disassembler for little-endian
From: Philippe Bergheaud @ 2013-12-02  9:10 UTC (permalink / raw)
  To: Linuxppc-dev; +Cc: Philippe Bergheaud

This patch fixes the disassembler of the powerpc kernel debugger xmon,
for little-endian.

Signed-off-by: Philippe Bergheaud <felix@linux.vnet.ibm.com>
---
 arch/powerpc/xmon/xmon.c |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index af9d346..6c27804 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -171,7 +171,11 @@ extern void xmon_leave(void);
 #define REG		"%.8lx"
 #endif
 
+#ifdef __LITTLE_ENDIAN__
+#define GETWORD(v)	(((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
+#else
 #define GETWORD(v)	(((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
+#endif
 
 #define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
 			 || ('a' <= (c) && (c) <= 'f') \
-- 
1.7.10.4

^ permalink raw reply related

* [RFC PATCH powerpc 2/2] adjust the variable type and name in __pte_free_tlb()
From: Li Zhong @ 2013-12-03  8:33 UTC (permalink / raw)
  To: PowerPC email list; +Cc: Paul Mackerras
In-Reply-To: <1386059435.2578.13.camel@ThinkPad-T5421>

The patch adjusts the variable type and name for page in
__pte_free_tlb(), which now seems a little confusing. 

Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/pgalloc-64.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/pgalloc-64.h b/arch/powerpc/include/asm/pgalloc-64.h
index d7543c2..1580f9e 100644
--- a/arch/powerpc/include/asm/pgalloc-64.h
+++ b/arch/powerpc/include/asm/pgalloc-64.h
@@ -148,11 +148,11 @@ static inline void pgtable_free_tlb(struct mmu_gather *tlb,
 static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
 				  unsigned long address)
 {
-	struct page *page = page_address(table);
+	void *page_addr = page_address(table);
 
 	tlb_flush_pgtable(tlb, address);
 	pgtable_page_dtor(table);
-	pgtable_free_tlb(tlb, page, 0);
+	pgtable_free_tlb(tlb, page_addr, 0);
 }
 
 #else /* if CONFIG_PPC_64K_PAGES */

^ permalink raw reply related

* [RFC PATCH powerpc 1/2] fix using page adddress as the page stucture pointer in __pte_free_tlb()
From: Li Zhong @ 2013-12-03  8:30 UTC (permalink / raw)
  To: PowerPC email list; +Cc: Paul Mackerras

It seems that in __pte_free_tlb (non 64K page code path), we wrongly
pass the page address as the page structure pointer to
pgtable_page_dtor(), which needs the page structure pointer as the
argument.

The change also fixes following bug on next-1128:

[    0.563113] Unable to handle kernel paging request for data at address 0x00000000
[    0.563121] Faulting instruction address: 0xc0000000001d8e30
[    0.563128] Oops: Kernel access of bad area, sig: 11 [#1]
[    0.563132] PREEMPT SMP NR_CPUS=16 NUMA pSeries
[    0.563143] Modules linked in:
[    0.563150] CPU: 9 PID: 1 Comm: init Not tainted 3.13.0-rc1-next-20131128-dirty #1
[    0.563157] task: c0000001fed40000 ti: c0000001fed3c000 task.ti: c0000001fed3c000
[    0.563163] NIP: c0000000001d8e30 LR: c0000000001da4e8 CTR: c00000000018ed28
[    0.563171] REGS: c0000001fed3f060 TRAP: 0300   Not tainted  (3.13.0-rc1-next-20131128-dirty)
[    0.563177] MSR: 8000000000009032 <SF,EE,ME,IR,DR,RI>  CR: 24222982  XER: 20000001
[    0.563197] CFAR: c0000000001d8e0c DAR: 0000000000000000 DSISR: 42000000 SOFTE: 1 
GPR00: 0000000000000000 c0000001fed3f2e0 c000000000d4ce98 c0000001fe01f500 
GPR04: f000000000000000 0000000000000000 c0000000001a9980 0000000000000000 
GPR08: 0000000000b69000 0000000000040000 c0000001fc550108 0000000000000000 
GPR12: 0000000044779982 c00000000f33eb00 0000002000000000 1000000000000000 
GPR16: c000000000000000 0000000000000001 c0000001fcbd8000 c0000001fa4b83f8 
GPR20: 00000000ffffffff 00003fffffe00000 c0000001fa0a8ff8 0000000000000000 
GPR24: 0000000000000029 c0000001fed3c000 0000000000210d00 0000000000000001 
GPR28: 0000000000000000 0000000000000000 c0000001fe01f500 f000000000000000 
[    0.563299] NIP [c0000000001d8e30] .__slab_free+0xc8/0x42c
[    0.563306] LR [c0000000001da4e8] .kmem_cache_free+0x1d4/0x364
[    0.563311] Call Trace:
[    0.563316] [c0000001fed3f2e0] [6db6db6db6db6db7] 0x6db6db6db6db6db7 (unreliable)
[    0.563325] [c0000001fed3f410] [c0000000001da4e8] .kmem_cache_free+0x1d4/0x364
[    0.563334] [c0000001fed3f4d0] [c0000000001a9980] .ptlock_free+0x2c/0x44
[    0.563342] [c0000001fed3f550] [c0000000001aec98] .free_pgd_range+0x340/0x3d8
[    0.563350] [c0000001fed3f680] [c0000000001ee6b8] .shift_arg_pages+0x130/0x1a0
[    0.563358] [c0000001fed3f7c0] [c0000000001ee888] .setup_arg_pages+0x160/0x214
[    0.563366] [c0000001fed3f870] [c000000000257664] .load_elf_binary+0x540/0x168c
[    0.563374] [c0000001fed3f9d0] [c0000000001ecf28] .search_binary_handler+0xcc/0x238
[    0.563382] [c0000001fed3fa80] [c0000000002551e8] .load_script+0x26c/0x290
[    0.563390] [c0000001fed3fb90] [c0000000001ecf28] .search_binary_handler+0xcc/0x238
[    0.563397] [c0000001fed3fc40] [c0000000001ef1f4] .do_execve_common+0x6b4/0xa0c
[    0.563406] [c0000001fed3fd20] [c0000000001ef634] .do_execve+0x40/0x58
[    0.563414] [c0000001fed3fdb0] [c00000000000bdb4] .kernel_init+0x74/0x158
[    0.563422] [c0000001fed3fe30] [c00000000000a0ec] .ret_from_kernel_thread+0x5c/0x70
[    0.563429] Instruction dump:
[    0.563433] 635a0d00 3b600001 2fbc0000 41fe0014 e8810070 7f83e378 486543c1 60000000 
[    0.563450] e81e0022 829f0018 92810090 eaff0010 <7efd012a> a1210090 8aa10093 3809ffff 
[    0.563469] ---[ end trace 3be1fd3d950f1716 ]---

Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/pgalloc-64.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/include/asm/pgalloc-64.h b/arch/powerpc/include/asm/pgalloc-64.h
index 6940128..d7543c2 100644
--- a/arch/powerpc/include/asm/pgalloc-64.h
+++ b/arch/powerpc/include/asm/pgalloc-64.h
@@ -151,7 +151,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
 	struct page *page = page_address(table);
 
 	tlb_flush_pgtable(tlb, address);
-	pgtable_page_dtor(page);
+	pgtable_page_dtor(table);
 	pgtable_free_tlb(tlb, page, 0);
 }
 

^ permalink raw reply related

* re: ping: re:[PATCH 1/1] kernel code that do not handle NULL return of kmem_cache_zalloc
From: zhouzhouyi @ 2013-12-02  7:19 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev, kvm-ppc, kvm, dwmw2, joro, benh; +Cc: Zhouyi Zhou

From: Zhouyi Zhou <zhouzhouyi@gmail.com>

the text of previous ping message maybe garbled sorry for the trouble

> I do a grep for kmem_cache_zalloc and kmem_cache_alloc
> in kernel tree, and find some code do not handle NULL
> return of kmem_cache_zalloc correctly


> Signed-off-by: Zhouyi Zhou <yizhouzhou@ict.ac.cn>
---
 arch/powerpc/kvm/book3s_32_mmu_host.c |    5 +++++
 drivers/iommu/omap-iommu.c            |    3 ++-
 fs/jffs2/malloc.c                     |    4 ++++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c
index 3a0abd2..5fac89d 100644
--- a/arch/powerpc/kvm/book3s_32_mmu_host.c
+++ b/arch/powerpc/kvm/book3s_32_mmu_host.c
@@ -243,6 +243,11 @@ next_pteg:
 	/* Now tell our Shadow PTE code about the new page */
 
 	pte = kvmppc_mmu_hpte_cache_next(vcpu);
+	if (!pte) {
+		kvm_release_pfn_clean(hpaddr >> PAGE_SHIFT);
+		r = -EAGAIN;
+		goto out;
+	}
 
 	dprintk_mmu("KVM: %c%c Map 0x%llx: [%lx] 0x%llx (0x%llx) -> %lx\n",
 		    orig_pte->may_write ? 'w' : '-',
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index bcd78a7..5155714 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -551,7 +551,8 @@ static u32 *iopte_alloc(struct omap_iommu *obj, u32 *iopgd, u32 da)
 		dev_vdbg(obj->dev, "%s: a new pte:%p\n", __func__, iopte);
 	} else {
 		/* We raced, free the reduniovant table */
-		iopte_free(iopte);
+		if (iopte)
+			iopte_free(iopte);
 	}
 
 pte_ready:
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c
index 4f47aa2..58e2336 100644
--- a/fs/jffs2/malloc.c
+++ b/fs/jffs2/malloc.c
@@ -287,6 +287,8 @@ struct jffs2_xattr_datum *jffs2_alloc_xattr_datum(void)
 {
 	struct jffs2_xattr_datum *xd;
 	xd = kmem_cache_zalloc(xattr_datum_cache, GFP_KERNEL);
+	if (!xd)
+		return NULL;
 	dbg_memalloc("%p\n", xd);
 
 	xd->class = RAWNODE_CLASS_XATTR_DATUM;
@@ -305,6 +307,8 @@ struct jffs2_xattr_ref *jffs2_alloc_xattr_ref(void)
 {
 	struct jffs2_xattr_ref *ref;
 	ref = kmem_cache_zalloc(xattr_ref_cache, GFP_KERNEL);
+	if (!ref)
+		return NULL;
 	dbg_memalloc("%p\n", ref);
 
 	ref->class = RAWNODE_CLASS_XATTR_REF;
-- 
1.7.10.4

^ permalink raw reply related

* Re: [PATCH] watchdog: mpc8xxx_wdt: MPC8xx is HW enabled
From: Wolfgang Denk @ 2013-12-02  6:14 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: linux-watchdog, linux-kernel, Wim Van Sebroeck, scottwood,
	linuxppc-dev
In-Reply-To: <529B9152.9090106@roeck-us.net>

Dear Guenter,

In message <529B9152.9090106@roeck-us.net> you wrote:
> On 11/30/2013 07:45 AM, Christophe Leroy wrote:
> > MPC8xx watchdog is enabled at startup by HW.
> > If the bootloader disables it, it cannot be reenabled.
> 
> Is that true for all variants of 8xx, especially for 823 ? I am a bit concerned
> about breaking compatibility with some chips ... assuming there was a reason
> for not setting this flag originally.

This is correct, and applies for all variants of the MPC8xx, including
the MPC823 / MPC823E.  From the UM:

	"The software watchdog timer can be disabled or its timeout
	period can be changed in the SYPCR. Once the SYPCR is written,
	it cannot be written again until a system reset."

Actually this is the only correct behaviour.  Any watchdog that can be
disabled by software is not worth it's name, and unsuitable for any
kind of aplications where security / reliability are required.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Ninety-Ninety Rule of Project Schedules:
        The first ninety percent of the task takes ninety percent of
the time, and the last ten percent takes the other ninety percent.

^ permalink raw reply

* Re: 3.13 Oops on ppc64_cpu --smt=off
From: Preeti U Murthy @ 2013-12-02  4:01 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Paul Mackerras, linuxppc-dev
In-Reply-To: <9C236EE3-BB04-4BF9-ACE0-870A9E97EA0F@suse.de>

Hi,

On 11/30/2013 11:15 PM, Alexander Graf wrote:
> Hi Ben,
> 
> With current linus master (3.13-rc2+) I'm facing an interesting issue with

SMT disabling on p7. When I trigger the cpu offlining it works as expected,
but after a few seconds the machine goes into an oops as you can see below.
> 
> It looks like a null pointer dereference.

tip/sched/urgent has the below fix. Can you please apply the following it and
check if the issue gets resolved?  A similar issue was reported earlier as
well and it pointed to the commit id 37dc65. I believe the problem that you report
is also pointing to the regression caused by the same commit id.

Thanks

Regards
Preeti U Murthy

---
commit 42eb088ed246a5a817bb45a8b32fe234cf1c0f8b
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Tue Nov 19 16:41:49 2013 +0100

    sched: Avoid NULL dereference on sd_busy
    
    Commit 37dc6b50cee9 ("sched: Remove unnecessary iteration over sched
    domains to update nr_busy_cpus") forgot to clear 'sd_busy' under some
    conditions leading to a possible NULL deref in set_cpu_sd_state_idle().
    
    Reported-by: Anton Blanchard <anton@samba.org>
    Cc: Preeti U Murthy <preeti@linux.vnet.ibm.com>
    Signed-off-by: Peter Zijlstra <peterz@infradead.org>
    Link: http://lkml.kernel.org/r/20131118113701.GF3866@twins.programming.kicks-ass.net
    Signed-off-by: Ingo Molnar <mingo@kernel.org>

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index c1808606ee5f..a1591ca7eb5a 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4910,8 +4910,9 @@ static void update_top_cache_domain(int cpu)
 	if (sd) {
 		id = cpumask_first(sched_domain_span(sd));
 		size = cpumask_weight(sched_domain_span(sd));
-		rcu_assign_pointer(per_cpu(sd_busy, cpu), sd->parent);
+		sd = sd->parent; /* sd_busy */
 	}
+	rcu_assign_pointer(per_cpu(sd_busy, cpu), sd);

 	rcu_assign_pointer(per_cpu(sd_llc, cpu), sd);
 	per_cpu(sd_llc_size, cpu) = size;


> 
> 
> Alex
> 
> ($ ppc64_cpu --smt=off)
> kvm: disabling virtualization on CPU1
> kvm: disabling virtualization on CPU2
> kvm: disabling virtualization on CPU3
> kvm: disabling virtualization on CPU5
> kvm: disabling virtualization on CPU6
> kvm: disabling virtualization on CPU7
> kvm: disabling virtualization on CPU9
> kvm: disabling virtualization on CPU10
> kvm: disabling virtualization on CPU11
> kvm: disabling virtualization on CPU13
> kvm: disabling virtualization on CPU14
> kvm: disabling virtualization on CPU15
> kvm: disabling virtualization on CPU17
> kvm: disabling virtualization on CPU18
> kvm: disabling virtualization on CPU19
> kvm: disabling virtualization on CPU21
> kvm: disabling virtualization on CPU22
> kvm: disabling virtualization on CPU23
> kvm: disabling virtualization on CPU25
> kvm: disabling virtualization on CPU26
> kvm: disabling virtualization on CPU27
> kvm: disabling virtualization on CPU29
> kvm: disabling virtualization on CPU30
> kvm: disabling virtualization on CPU31
> kvm: disabling virtualization on CPU33
> kvm: disabling virtualization on CPU34
> kvm: disabling virtualization on CPU35
> kvm: disabling virtualization on CPU37
> kvm: disabling virtualization on CPU38
> kvm: disabling virtualization on CPU39
> kvm: disabling virtualization on CPU41
> kvm: disabling virtualization on CPU42
> kvm: disabling virtualization on CPU43
> kvm: disabling virtualization on CPU45
> kvm: disabling virtualization on CPU46
> kvm: disabling virtualization on CPU47
> kvm: disabling virtualization on CPU49
> kvm: disabling virtualization on CPU50
> kvm: disabling virtualization on CPU51
> kvm: disabling virtualization on CPU53
> kvm: disabling virtualization on CPU54
> kvm: disabling virtualization on CPU55
> kvm: disabling virtualization on CPU57
> kvm: disabling virtualization on CPU58
> kvm: disabling virtualization on CPU59
> kvm: disabling virtualization on CPU61
> kvm: disabling virtualization on CPU62
> kvm: disabling virtualization on CPU63
> Unable to handle kernel paging request for data at address 0x00000010
> Faulting instruction address: 0xc000000000124188
> Oops: Kernel access of bad area, sig: 11 [#1]
> SMP NR_CPUS=1024 NUMA PowerNV
> Modules linked in: iptable_filter ip_tables x_tables nfsv3 nfs_acl nfs fscache lockd sunrpc autofs4 binfmt_misc af_packet fuse loop dm_mod ohci_pci ohci_hcd ehci_pci ehci_hcd e1000e usbcore sr_mod cdrom ses enclosure rtc_generic usb_common ptp sg pps_core sd_mod crc_t10dif crct10dif_common scsi_dh_hp_sw scsi_dh_alua scsi_dh_emc scsi_dh_rdac scsi_dh virtio_pci virtio_console virtio_blk virtio virtio_ring ipr libata scsi_mod
> CPU: 56 PID: 0 Comm: swapper/56 Not tainted 3.13.0-rc2-0.g01695c8-default+ #1
> task: c0000007f28b5180 ti: c0000007f28c8000 task.ti: c0000007f28c8000
> NIP: c000000000124188 LR: c000000000124144 CTR: c00000000011e650
> REGS: c0000007f28cb1e0 TRAP: 0300   Not tainted  (3.13.0-rc2-0.g01695c8-default+)
> MSR: 9000000000009032 <SF,HV,EE,ME,IR,DR,RI>  CR: 24000028  XER: 00000000
> CFAR: c00000000000908c DAR: 0000000000000010 DSISR: 40000000 SOFTE: 0
> GPR00: 00000000ef4546c9 c0000007f28cb460 c0000000013c7690 0000000000000000
> GPR04: 0000000000000038 0000000000000010 c000000003314ea0 c000000000c72878
> GPR08: c000000000c83448 c0000007ef454600 0000000002690000 0000000000000000
> GPR12: 000000000000c345 c00000000ff0e000 c0000007f28cb8b0 0000000000000001
> GPR16: 7fffffffffffffff c0000007f28cb8c0 0000000002690000 000000219729878b
> GPR20: 0000000000000000 c000000000c72698 c0000000033027d0 c00000000142ca58
> GPR24: c000000000c84e80 c000000003314e80 c00000000142ca58 00000000ffffc32c
> GPR28: 0000000000000038 c0000007f28b5180 c0000000012f8cd0 c000000001422180
> NIP [c000000000124188] .trigger_load_balance+0xc8/0x2e0
> LR [c000000000124144] .trigger_load_balance+0x84/0x2e0
> Call Trace:
> [c0000007f28cb460] [c000000000124134] .trigger_load_balance+0x74/0x2e0 (unreliable)
> [c0000007f28cb510] [c00000000011ca50] .scheduler_tick+0x100/0x160
> [c0000007f28cb5d0] [c0000000000e9074] .update_process_times+0x64/0x90
> [c0000007f28cb660] [c0000000001628f4] .tick_sched_handle+0x34/0xc0
> [c0000007f28cb6f0] [c000000000162c60] .tick_sched_timer+0x70/0xc0
> [c0000007f28cb790] [c000000000109000] .__run_hrtimer+0x180/0x280
> [c0000007f28cb840] [c000000000109738] .hrtimer_interrupt+0x158/0x340
> [c0000007f28cb960] [c00000000001ec74] .timer_interrupt+0x174/0x2d0
> [c0000007f28cba10] [c000000000002824] decrementer_common+0x124/0x180
> --- Exception: 901 at .arch_local_irq_restore+0x84/0xa0
>     LR = .arch_local_irq_restore+0x84/0xa0
> [c0000007f28cbd00] [c000000000010c34] .arch_local_irq_restore+0x54/0xa0 (unreliable)
> [c0000007f28cbd70] [c0000000000174f8] .arch_cpu_idle+0xc8/0x170
> [c0000007f28cbe00] [c00000000014597c] .cpu_idle_loop+0x9c/0x2c0
> [c0000007f28cbed0] [c00000000003f800] .start_secondary+0x2a0/0x2d0
> [c0000007f28cbf90] [c0000000000097fc] .start_secondary_prolog+0x10/0x14
> Instruction dump:
> 78001f24 e8fe8040 7d7a002a 7ce93b78 7d29582a 2fa90000 419e0030 8009004c
> 2f800000 419e0024 9069004c e9690010 <e92b0010> 3929001c 7c004828 30000001
> ---[ end trace 5d5f06c369432fa1 ]---
> 
> Kernel panic - not syncing: Fatal exception in interrupt
> Rebooting in 100 seconds..
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
> 

^ permalink raw reply related

* ping: re: [PATCH 1/1] kernel code that do not handle NULL return of kmem_cache_zalloc
From: Zhouyi Zhou @ 2013-12-02  3:07 UTC (permalink / raw)
  To: Zhouyi Zhou
  Cc: kvm, linuxppc-dev, Joerg Roedel, linux-kernel, kvm-ppc,
	David Woodhouse
In-Reply-To: <1385549465-15945-1-git-send-email-yizhouzhou@ict.ac.cn>

ping
>=C2=A0I=C2=A0do=C2=A0a=C2=A0grep=C2=A0for=C2=A0kmem_cache_zalloc=C2=A0and=
=C2=A0kmem_cache_alloc
>=C2=A0in=C2=A0kernel=C2=A0tree,=C2=A0and=C2=A0find=C2=A0some=C2=A0code=C2=
=A0do=C2=A0not=C2=A0handle=C2=A0NULL
>=C2=A0return=C2=A0of=C2=A0kmem_cache_zalloc=C2=A0correctly
>=C2=A0
>=C2=A0
>=C2=A0Signed-off-by:=C2=A0Zhouyi=C2=A0Zhou=C2=A0<yizhouzhou@ict.ac.cn>
>=C2=A0---
>=C2=A0=C2=A0arch/powerpc/kvm/book3s_32_mmu_host.c=C2=A0|=C2=A0=C2=A0=C2=A0=
=C2=A05=C2=A0+++++
>=C2=A0=C2=A0drivers/iommu/omap-iommu.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0|=C2=A0=C2=A0=C2=A0=C2=A03=C2=A0++-
>=C2=A0=C2=A0fs/jffs2/malloc.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0|=C2=A0=C2=A0=C2=A0=C2=A04=C2=A0++++
>=C2=A0=C2=A03=C2=A0files=C2=A0changed,=C2=A011=C2=A0insertions(+),=C2=A01=
=C2=A0deletion(-)
>=C2=A0
>=C2=A0diff=C2=A0--git=C2=A0a/arch/powerpc/kvm/book3s_32_mmu_host.c=C2=A0b/=
arch/powerpc/kvm/book3s_32_mmu_host.c
>=C2=A0index=C2=A03a0abd2..5fac89d=C2=A0100644
>=C2=A0---=C2=A0a/arch/powerpc/kvm/book3s_32_mmu_host.c
>=C2=A0+++=C2=A0b/arch/powerpc/kvm/book3s_32_mmu_host.c
>=C2=A0@@=C2=A0-243,6=C2=A0+243,11=C2=A0@@=C2=A0next_pteg:
>=C2=A0=C2=A0=09/*=C2=A0Now=C2=A0tell=C2=A0our=C2=A0Shadow=C2=A0PTE=C2=A0co=
de=C2=A0about=C2=A0the=C2=A0new=C2=A0page=C2=A0*/
>=C2=A0=C2=A0
>=C2=A0=C2=A0=09pte=C2=A0=3D=C2=A0kvmppc_mmu_hpte_cache_next(vcpu);
>=C2=A0+=09if=C2=A0(!pte)=C2=A0{
>=C2=A0+=09=09kvm_release_pfn_clean(hpaddr=C2=A0>>=C2=A0PAGE_SHIFT);
>=C2=A0+=09=09r=C2=A0=3D=C2=A0-EAGAIN;
>=C2=A0+=09=09goto=C2=A0out;
>=C2=A0+=09}
>=C2=A0=C2=A0
>=C2=A0=C2=A0=09dprintk_mmu("KVM:=C2=A0%c%c=C2=A0Map=C2=A00x%llx:=C2=A0[%lx=
]=C2=A00x%llx=C2=A0(0x%llx)=C2=A0->=C2=A0%lx\n",
>=C2=A0=C2=A0=09=09=C2=A0=C2=A0=C2=A0=C2=A0orig_pte->may_write=C2=A0?=C2=A0=
'w'=C2=A0:=C2=A0'-',
>=C2=A0diff=C2=A0--git=C2=A0a/drivers/iommu/omap-iommu.c=C2=A0b/drivers/iom=
mu/omap-iommu.c
>=C2=A0index=C2=A0bcd78a7..5155714=C2=A0100644
>=C2=A0---=C2=A0a/drivers/iommu/omap-iommu.c
>=C2=A0+++=C2=A0b/drivers/iommu/omap-iommu.c
>=C2=A0@@=C2=A0-551,7=C2=A0+551,8=C2=A0@@=C2=A0static=C2=A0u32=C2=A0*iopte_=
alloc(struct=C2=A0omap_iommu=C2=A0*obj,=C2=A0u32=C2=A0*iopgd,=C2=A0u32=C2=
=A0da)
>=C2=A0=C2=A0=09=09dev_vdbg(obj->dev,=C2=A0"%s:=C2=A0a=C2=A0new=C2=A0pte:%p=
\n",=C2=A0__func__,=C2=A0iopte);
>=C2=A0=C2=A0=09}=C2=A0else=C2=A0{
>=C2=A0=C2=A0=09=09/*=C2=A0We=C2=A0raced,=C2=A0free=C2=A0the=C2=A0reduniova=
nt=C2=A0table=C2=A0*/
>=C2=A0-=09=09iopte_free(iopte);
>=C2=A0+=09=09if=C2=A0(iopte)
>=C2=A0+=09=09=09iopte_free(iopte);
>=C2=A0=C2=A0=09}
>=C2=A0=C2=A0
>=C2=A0=C2=A0pte_ready:
>=C2=A0diff=C2=A0--git=C2=A0a/fs/jffs2/malloc.c=C2=A0b/fs/jffs2/malloc.c
>=C2=A0index=C2=A04f47aa2..58e2336=C2=A0100644
>=C2=A0---=C2=A0a/fs/jffs2/malloc.c
>=C2=A0+++=C2=A0b/fs/jffs2/malloc.c
>=C2=A0@@=C2=A0-287,6=C2=A0+287,8=C2=A0@@=C2=A0struct=C2=A0jffs2_xattr_datu=
m=C2=A0*jffs2_alloc_xattr_datum(void)
>=C2=A0=C2=A0{
>=C2=A0=C2=A0=09struct=C2=A0jffs2_xattr_datum=C2=A0*xd;
>=C2=A0=C2=A0=09xd=C2=A0=3D=C2=A0kmem_cache_zalloc(xattr_datum_cache,=C2=A0=
GFP_KERNEL);
>=C2=A0+=09if=C2=A0(!xd)
>=C2=A0+=09=09return=C2=A0NULL;
>=C2=A0=C2=A0=09dbg_memalloc("%p\n",=C2=A0xd);
>=C2=A0=C2=A0
>=C2=A0=C2=A0=09xd->class=C2=A0=3D=C2=A0RAWNODE_CLASS_XATTR_DATUM;
>=C2=A0@@=C2=A0-305,6=C2=A0+307,8=C2=A0@@=C2=A0struct=C2=A0jffs2_xattr_ref=
=C2=A0*jffs2_alloc_xattr_ref(void)
>=C2=A0=C2=A0{
>=C2=A0=C2=A0=09struct=C2=A0jffs2_xattr_ref=C2=A0*ref;
>=C2=A0=C2=A0=09ref=C2=A0=3D=C2=A0kmem_cache_zalloc(xattr_ref_cache,=C2=A0G=
FP_KERNEL);
>=C2=A0+=09if=C2=A0(!ref)
>=C2=A0+=09=09return=C2=A0NULL;
>=C2=A0=C2=A0=09dbg_memalloc("%p\n",=C2=A0ref);
>=C2=A0=C2=A0
>=C2=A0=C2=A0=09ref->class=C2=A0=3D=C2=A0RAWNODE_CLASS_XATTR_REF;
>=C2=A0--=C2=A0
>=C2=A01.7.10.4
>=C2=A0

^ permalink raw reply

* Re: [PATCH] watchdog: mpc8xxx_wdt convert to watchdog core
From: Guenter Roeck @ 2013-12-01 19:38 UTC (permalink / raw)
  To: Christophe Leroy, Wim Van Sebroeck, scottwood
  Cc: linuxppc-dev, linux-kernel, linux-watchdog
In-Reply-To: <20131130153345.3070443E15@localhost.localdomain>

On 11/30/2013 07:33 AM, Christophe Leroy wrote:
> Convert mpc8xxx_wdt.c to the new watchdog API.
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>
> diff -ur a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
> --- a/drivers/watchdog/mpc8xxx_wdt.c	2013-05-11 22:57:46.000000000 +0200
> +++ b/drivers/watchdog/mpc8xxx_wdt.c	2013-11-30 16:14:53.803495472 +0100
> @@ -72,28 +72,31 @@
>    * to 0
>    */
>   static int prescale = 1;
> -static unsigned int timeout_sec;
>
> -static unsigned long wdt_is_open;
>   static DEFINE_SPINLOCK(wdt_spinlock);
>
> -static void mpc8xxx_wdt_keepalive(void)
> +static int mpc8xxx_wdt_ping(struct watchdog_device *w)
>   {
>   	/* Ping the WDT */
>   	spin_lock(&wdt_spinlock);
>   	out_be16(&wd_base->swsrr, 0x556c);
>   	out_be16(&wd_base->swsrr, 0xaa39);
>   	spin_unlock(&wdt_spinlock);
> +	return 0;

The return code is never checked, so you can make this function void.

>   }
>
> +static struct watchdog_device mpc8xxx_wdt_dev;
>   static void mpc8xxx_wdt_timer_ping(unsigned long arg);
> -static DEFINE_TIMER(wdt_timer, mpc8xxx_wdt_timer_ping, 0, 0);
> +static DEFINE_TIMER(wdt_timer, mpc8xxx_wdt_timer_ping, 0,
> +		(unsigned long)&mpc8xxx_wdt_dev);
>
>   static void mpc8xxx_wdt_timer_ping(unsigned long arg)
>   {
> -	mpc8xxx_wdt_keepalive();
> +	struct watchdog_device *w = (struct watchdog_device *)arg;
> +
> +	mpc8xxx_wdt_ping(w);
>   	/* We're pinging it twice faster than needed, just to be sure. */
> -	mod_timer(&wdt_timer, jiffies + HZ * timeout_sec / 2);
> +	mod_timer(&wdt_timer, jiffies + HZ * w->timeout / 2);
>   }
>
>   static void mpc8xxx_wdt_pr_warn(const char *msg)
> @@ -102,19 +105,9 @@
>   		reset ? "reset" : "machine check exception");
>   }
>
> -static ssize_t mpc8xxx_wdt_write(struct file *file, const char __user *buf,
> -				 size_t count, loff_t *ppos)
> -{
> -	if (count)
> -		mpc8xxx_wdt_keepalive();
> -	return count;
> -}
> -
> -static int mpc8xxx_wdt_open(struct inode *inode, struct file *file)
> +static int mpc8xxx_wdt_start(struct watchdog_device *w)
>   {
>   	u32 tmp = SWCRR_SWEN;
> -	if (test_and_set_bit(0, &wdt_is_open))
> -		return -EBUSY;
>
>   	/* Once we start the watchdog we can't stop it */
>   	if (nowayout)

This code and the subsequent module_get can be removed; it is handled by the infrastructure.


> @@ -132,59 +125,30 @@
>
>   	del_timer_sync(&wdt_timer);
>
> -	return nonseekable_open(inode, file);
> +	return 0;
>   }
>
> -static int mpc8xxx_wdt_release(struct inode *inode, struct file *file)
> +static int mpc8xxx_wdt_stop(struct watchdog_device *w)
>   {
> -	if (!nowayout)
> -		mpc8xxx_wdt_timer_ping(0);
> -	else
> -		mpc8xxx_wdt_pr_warn("watchdog closed");
> -	clear_bit(0, &wdt_is_open);
> +	mpc8xxx_wdt_timer_ping((unsigned long)w);

I really dislike this typecasting back and forth.

I think it would be better to move the mod_timer() call from mpc8xxx_wdt_timer_ping
into mpc8xxx_wdt_ping and call mpc8xxx_wdt_ping directly whenever possible.
 From mpc8xxx_wdt_timer_ping you can then just call mpc8xxx_wdt_ping with the
typecasted parameter.

>   	return 0;
>   }
>
> -static long mpc8xxx_wdt_ioctl(struct file *file, unsigned int cmd,
> -							unsigned long arg)
> -{
> -	void __user *argp = (void __user *)arg;
> -	int __user *p = argp;
> -	static const struct watchdog_info ident = {
> -		.options = WDIOF_KEEPALIVEPING,
> -		.firmware_version = 1,
> -		.identity = "MPC8xxx",
> -	};
> -
> -	switch (cmd) {
> -	case WDIOC_GETSUPPORT:
> -		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
> -	case WDIOC_GETSTATUS:
> -	case WDIOC_GETBOOTSTATUS:
> -		return put_user(0, p);
> -	case WDIOC_KEEPALIVE:
> -		mpc8xxx_wdt_keepalive();
> -		return 0;
> -	case WDIOC_GETTIMEOUT:
> -		return put_user(timeout_sec, p);
> -	default:
> -		return -ENOTTY;
> -	}
> -}
> +static struct watchdog_info mpc8xxx_wdt_info = {
> +	.options = WDIOF_KEEPALIVEPING,
> +	.firmware_version = 1,
> +	.identity = "MPC8xxx",
> +};
>
> -static const struct file_operations mpc8xxx_wdt_fops = {
> -	.owner		= THIS_MODULE,
> -	.llseek		= no_llseek,
> -	.write		= mpc8xxx_wdt_write,
> -	.unlocked_ioctl	= mpc8xxx_wdt_ioctl,
> -	.open		= mpc8xxx_wdt_open,
> -	.release	= mpc8xxx_wdt_release,
> +static struct watchdog_ops mpc8xxx_wdt_ops = {
> +	.owner = THIS_MODULE,
> +	.start = mpc8xxx_wdt_start,
> +	.stop = mpc8xxx_wdt_stop,
>   };
>
> -static struct miscdevice mpc8xxx_wdt_miscdev = {
> -	.minor	= WATCHDOG_MINOR,
> -	.name	= "watchdog",
> -	.fops	= &mpc8xxx_wdt_fops,
> +static struct watchdog_device mpc8xxx_wdt_dev = {
> +	.info = &mpc8xxx_wdt_info,
> +	.ops = &mpc8xxx_wdt_ops,
>   };
>
>   static const struct of_device_id mpc8xxx_wdt_match[];
> @@ -196,6 +160,7 @@
>   	const struct mpc8xxx_wdt_type *wdt_type;
>   	u32 freq = fsl_get_sys_freq();
>   	bool enabled;
> +	unsigned int timeout_sec;
>
>   	match = of_match_device(mpc8xxx_wdt_match, &ofdev->dev);
>   	if (!match)
> @@ -222,6 +187,7 @@
>   	else
>   		timeout_sec = timeout / freq;
>
> +	mpc8xxx_wdt_dev.timeout = timeout_sec;
>   #ifdef MODULE
>   	ret = mpc8xxx_wdt_init_late();
>   	if (ret)
> @@ -237,7 +203,7 @@
>   	 * userspace handles it.
>   	 */
>   	if (enabled)
> -		mpc8xxx_wdt_timer_ping(0);
> +		mpc8xxx_wdt_timer_ping((unsigned long)&mpc8xxx_wdt_dev);
>   	return 0;
>   err_unmap:
>   	iounmap(wd_base);
> @@ -249,7 +215,7 @@
>   {
>   	mpc8xxx_wdt_pr_warn("watchdog removed");

The mpc8xxx_wdt_pr_warn function is now rather unnecessary since
it is called only once. Might as well merge it into this function.

>   	del_timer_sync(&wdt_timer);
> -	misc_deregister(&mpc8xxx_wdt_miscdev);
> +	watchdog_unregister_device(&mpc8xxx_wdt_dev);
>   	iounmap(wd_base);
>
>   	return 0;
> @@ -301,10 +267,11 @@
>   	if (!wd_base)
>   		return -ENODEV;
>
> -	ret = misc_register(&mpc8xxx_wdt_miscdev);
> +	watchdog_set_nowayout(&mpc8xxx_wdt_dev, nowayout);
> +
> +	ret = watchdog_register_device(&mpc8xxx_wdt_dev);
>   	if (ret) {
> -		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
> -		       WATCHDOG_MINOR, ret);
> +		pr_err("cannot register watchdog device (err=%d)\n", ret);
>   		return ret;
>   	}
>   	return 0;
> diff -ur a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -1146,6 +1146,7 @@
>   config 8xxx_WDT
>   	tristate "MPC8xxx Platform Watchdog Timer"
>   	depends on PPC_8xx || PPC_83xx || PPC_86xx
> +	select WATCHDOG_CORE
>   	help
>   	  This driver is for a SoC level watchdog that exists on some
>   	  Freescale PowerPC processors. So far this driver supports:
>
> ---
> Ce courrier électronique ne contient aucun virus ou logiciel malveillant parce que la protection avast! Antivirus est active.
> http://www.avast.com
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>

^ permalink raw reply

* Re: [PATCH] watchdog: mpc8xxx_wdt: MPC8xx is HW enabled
From: Guenter Roeck @ 2013-12-01 19:43 UTC (permalink / raw)
  To: Christophe Leroy, Wim Van Sebroeck, scottwood
  Cc: linuxppc-dev, linux-kernel, linux-watchdog
In-Reply-To: <20131130154540.E83D743E15@localhost.localdomain>

On 11/30/2013 07:45 AM, Christophe Leroy wrote:
> MPC8xx watchdog is enabled at startup by HW.
> If the bootloader disables it, it cannot be reenabled.
>

Is that true for all variants of 8xx, especially for 823 ? I am a bit concerned
about breaking compatibility with some chips ... assuming there was a reason
for not setting this flag originally.

Thanks,
Guenter

> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>
> diff -ur a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
> --- a/drivers/watchdog/mpc8xxx_wdt.c	2013-05-11 22:57:46.000000000 +0200
> +++ b/drivers/watchdog/mpc8xxx_wdt.c	2013-08-08 02:12:15.000000000 +0200
> @@ -273,6 +310,7 @@
>   		.compatible = "fsl,mpc823-wdt",
>   		.data = &(struct mpc8xxx_wdt_type) {
>   			.prescaler = 0x800,
> +			.hw_enabled = true,
>   		},
>   	},
>   	{},
>
> ---
> Ce courrier électronique ne contient aucun virus ou logiciel malveillant parce que la protection avast! Antivirus est active.
> http://www.avast.com
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>

^ permalink raw reply

* Re: [PATCH 3/9] powerpc: Add TIF_ELF2ABI flag.
From: Rusty Russell @ 2013-12-01 10:30 UTC (permalink / raw)
  To: Michael Ellerman, Anton Blanchard
  Cc: alistair, paulus, linuxppc-dev, Ulrich.Weigand
In-Reply-To: <20131121115503.GD15913@concordia>

Michael Ellerman <mpe@ellerman.id.au> writes:
> On Wed, Nov 20, 2013 at 10:15:00PM +1100, Anton Blanchard wrote:
>> From: Rusty Russell <rusty@rustcorp.com.au>
>> 
>> Little endian ppc64 is getting an exciting new ABI.  This is reflected
>> by the bottom two bits of e_flags in the ELF header:
>> 
>> 	0 == legacy binaries (v1 ABI)
>> 	1 == binaries using the old ABI (compiled with a new toolchain)
>> 	2 == binaries using the new ABI.
>
> Just to be ridiculously clear for stupid people like me, you refer here
> to the "v1 ABI" and "the old ABI" - they are the same thing - right?

Sorry for delay, was off for a week.

Yes, same thing.

>> diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
>> index ba7b197..05a3030 100644
>> --- a/arch/powerpc/include/asm/thread_info.h
>> +++ b/arch/powerpc/include/asm/thread_info.h
>> @@ -107,6 +107,9 @@ static inline struct thread_info *current_thread_info(void)
>>  #define TIF_EMULATE_STACK_STORE	16	/* Is an instruction emulation
>>  						for stack store? */
>>  #define TIF_MEMDIE		17	/* is terminating due to OOM killer */
>> +#if defined(CONFIG_PPC64)
>> +#define TIF_ELF2ABI		18	/* function descriptors must die! */
>> +#endif
>
> This is the first TIF flag we #ifdef for 32 vs 64, is that just because
> we don't want to waste a flag on 32 bit?

No, it's because I wanted to make damn sure that there wasn't anyone
testing this in 32-bit code, since ELF2 is currently a 64-bit only
option.

Cheers,
Rusty.

^ permalink raw reply

* Re: Build regressions/improvements in v3.13-rc2
From: Geert Uytterhoeven @ 2013-12-01  9:50 UTC (permalink / raw)
  To: linux-kernel@vger.kernel.org
  Cc: sparclinux, linux-xtensa@linux-xtensa.org,
	linuxppc-dev@lists.ozlabs.org, Linux-sh list
In-Reply-To: <1385891092-13266-1-git-send-email-geert@linux-m68k.org>

On Sun, Dec 1, 2013 at 10:44 AM, Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
> JFYI, when comparing v3.13-rc2[1] to v3.13-rc1[3], the summaries are:
>   - build errors: +8/-8
>   - build warnings: +147/-97

  + /scratch/kisskb/src/drivers/crypto/caam/jr.c: error: implicit
declaration of function 'of_iomap'
[-Werror=implicit-function-declaration]:  => 468:2

powerpc/mpc85xx_defconfig

  + /scratch/kisskb/src/arch/powerpc/kernel/swsusp_booke.S: Error:
invalid sprg number:  => 161, 85, 165, 91, 167, 163, 87, 89

powerpc-randconfig

  + /scratch/kisskb/src/drivers/tty/ehv_bytechan.c: error: type
defaults to 'int' in declaration of 'console_initcall'
[-Werror=implicit-int]:  => 363:1

powerpc-allmodconfig

  + /scratch/kisskb/src/arch/sparc/kernel/kgdb_64.c: error: implicit
declaration of function 'exception_enter'
[-Werror=implicit-function-declaration]:  => 162:7
  + /scratch/kisskb/src/arch/sparc/kernel/kgdb_64.c: error: implicit
declaration of function 'exception_exit'
[-Werror=implicit-function-declaration]:  => 176:2

sparc64-allmodconfig

  + error: drivers/built-in.o: undefined reference to
`i2c_register_driver':  => .init.literal+0xd88)
  + error: sram.c: undefined reference to `devm_regmap_init_i2c':  =>
.text+0x590dc)

sparc-allmodconfig
xtensa-allmodconfig

  + /scratch/kisskb/src/drivers/gpu/drm/drm_gem_cma_helper.c: error:
implicit declaration of function 'dma_alloc_writecombine'
[-Werror=implicit-function-declaration]:  => 91:2
  + /scratch/kisskb/src/drivers/gpu/drm/drm_gem_cma_helper.c: error:
implicit declaration of function 'dma_free_writecombine'
[-Werror=implicit-function-declaration]:  => 176:3

sh-randconfig

> [1] http://kisskb.ellerman.id.au/kisskb/head/6939/ (119 out of 120 configs)
> [3] http://kisskb.ellerman.id.au/kisskb/head/6919/ (119 out of 120 configs)

Gr{oetje,eeting}s,

                        Geert

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

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

^ permalink raw reply

* [PATCH v6 17/17] clk: mpc512x: remove migration support workarounds
From: Gerhard Sittig @ 2013-11-30 22:51 UTC (permalink / raw)
  To: linuxppc-dev, linux-arm-kernel, Anatolij Gustschin,
	Mike Turquette
  Cc: Scott Wood, Gerhard Sittig, Detlev Zundel
In-Reply-To: <1385851897-23475-1-git-send-email-gsi@denx.de>

this change removes workarounds which have become obsolete after
migration to common clock support has completed
- remove clkdev registration calls (compatibility clock item aliases)
  after all peripheral drivers were adjusted for device tree based
  clock lookup
- remove pre-enable workarounds after all peripheral drivers were
  adjusted to acquire their respective clock items

workarounds for these clock items get removed:  FEC (ethernet), I2C,
PSC (UART, SPI), PSC FIFO, USB, NFC (NAND flash), VIU (video capture),
BDLC (CAN), CAN MCLK, DIU (video output)

these clkdev registered names won't be provided any longer by the
MPC512x platform's clock driver:  "psc%d_mclk", "mscan%d_mclk",
"usb%d_clk", "nfc_clk", "viu_clk", "sys_clk", "ref_clk"

the pre-enable workaround for PCI remains, but depends on the presence
of PCI related device tree nodes (disables the PCI clock in the absence
of PCI nodes, keeps the PCI clock enabled in the presence of nodes) --
moving clock acquisition into the peripheral driver isn't possible for
PCI because its initialization takes place before the platform clock
driver gets initialized, thus the clock provider isn't available then

Cc: Mike Turquette <mturquette@linaro.org>
Cc: Anatolij Gustschin <agust@denx.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
 arch/powerpc/platforms/512x/clock-commonclk.c |   50 ++++++++-----------------
 1 file changed, 16 insertions(+), 34 deletions(-)

diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c
index 945e4609e773..189be4a4cb42 100644
--- a/arch/powerpc/platforms/512x/clock-commonclk.c
+++ b/arch/powerpc/platforms/512x/clock-commonclk.c
@@ -696,46 +696,28 @@ static void mpc5121_clk_register_of_provider(struct device_node *np)
  */
 static void mpc5121_clk_provide_migration_support(void)
 {
-	int idx;
-	char name[32];
-
-	/*
-	 * provide "pre-CCF" alias clock names for peripheral drivers
-	 * which have not yet been adjusted to do OF based clock lookups
-	 */
-	clk_register_clkdev(clks[MPC512x_CLK_REF], "ref_clk", NULL);
-	clk_register_clkdev(clks[MPC512x_CLK_SYS], "sys_clk", NULL);
-	clk_register_clkdev(clks[MPC512x_CLK_VIU], "viu_clk", NULL);
-	clk_register_clkdev(clks[MPC512x_CLK_NFC], "nfc_clk", NULL);
-	clk_register_clkdev(clks[MPC512x_CLK_USB1], "usb1_clk", NULL);
-	clk_register_clkdev(clks[MPC512x_CLK_USB2], "usb2_clk", NULL);
-	for (idx = 0; idx < NR_PSCS; idx++) {
-		snprintf(name, sizeof(name), "psc%d_mclk", idx);
-		clk_register_clkdev(clks[MPC512x_CLK_PSC0_MCLK + idx],
-				    name, NULL);
-	}
-	for (idx = 0; idx < NR_MSCANS; idx++) {
-		snprintf(name, sizeof(name), "mscan%d_mclk", idx);
-		clk_register_clkdev(clks[MPC512x_CLK_MSCAN0_MCLK + idx],
-				    name, NULL);
-	}
-	clk_register_clkdev(clks[MPC512x_CLK_SPDIF_MCLK], "spdif_mclk", NULL);
 
 	/*
 	 * pre-enable those clock items which are not yet appropriately
 	 * acquired by their peripheral driver
+	 *
+	 * the PCI clock cannot get acquired by its peripheral driver,
+	 * because for this platform the driver won't probe(), instead
+	 * initialization is done from within the .setup_arch() routine
+	 * at a point in time where the clock provider has not been
+	 * setup yet and thus isn't available yet
+	 *
+	 * so we "pre-enable" the clock here, to not have the clock
+	 * subsystem automatically disable this item in a late init call
+	 *
+	 * this PCI clock pre-enable workaround only applies when there
+	 * are device tree nodes for PCI and thus the peripheral driver
+	 * has attached to bridges, otherwise the PCI clock remains
+	 * unused and so it gets disabled
 	 */
-	clk_prepare_enable(clks[MPC512x_CLK_PSC_FIFO]);
 	clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);/* serial console */
-	clk_prepare_enable(clks[MPC512x_CLK_FEC]);	/* network, NFS */
-	clk_prepare_enable(clks[MPC512x_CLK_DIU]);	/* display */
-	clk_prepare_enable(clks[MPC512x_CLK_I2C]);	/* I2C */
-	for (idx = 0; idx < NR_PSCS; idx++)		/* PSC ipg */
-		clk_prepare_enable(clks[MPC512x_CLK_PSC0 + idx]);
-	clk_prepare_enable(clks[MPC512x_CLK_BDLC]);	/* MSCAN ipg */
-	for (idx = 0; idx < NR_MSCANS; idx++)		/* MSCAN mclk */
-		clk_prepare_enable(clks[MPC512x_CLK_MSCAN0_MCLK + idx]);
-	clk_prepare_enable(clks[MPC512x_CLK_PCI]);	/* PCI */
+	if (of_find_compatible_node(NULL, "pci", "fsl,mpc5121-pci"))
+		clk_prepare_enable(clks[MPC512x_CLK_PCI]);
 }
 
 /*
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v6 16/17] powerpc/mpc512x: improve DIU related clock setup
From: Gerhard Sittig @ 2013-11-30 22:51 UTC (permalink / raw)
  To: linuxppc-dev, linux-arm-kernel, Anatolij Gustschin,
	Mike Turquette
  Cc: Scott Wood, Gerhard Sittig, Detlev Zundel
In-Reply-To: <1385851897-23475-1-git-send-email-gsi@denx.de>

adapt the DIU clock initialization to the COMMON_CLK approach:
device tree based clock lookup, prepare and unprepare for clocks,
work with frequencies not dividers, call the appropriate clk_*()
routines and don't access CCM registers

the "best clock" determination now completely relies on the
platform's clock driver to pick a frequency close to what the
caller requests, and merely checks whether the desired frequency
was met (fits the tolerance of the monitor)

this approach shall succeed upon first try in the usual case,
will test a few less desirable yet acceptable frequencies in
edge cases, and will fallback to "best effort" if none of the
previously tried frequencies pass the test

provide a fallback clock lookup approach in case the OF based clock
lookup for the DIU fails, this allows for successful operation in
the presence of an outdated device tree which lacks clock specs

Cc: Anatolij Gustschin <agust@denx.de>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
 arch/powerpc/platforms/512x/mpc512x_shared.c |  169 ++++++++++++++------------
 1 file changed, 92 insertions(+), 77 deletions(-)

diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c
index 36b5652aada2..adb95f03d4d4 100644
--- a/arch/powerpc/platforms/512x/mpc512x_shared.c
+++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
@@ -12,6 +12,7 @@
  * (at your option) any later version.
  */
 
+#include <linux/clk.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <linux/irq.h>
@@ -68,98 +69,112 @@ struct fsl_diu_shared_fb {
 	bool		in_use;
 };
 
-#define DIU_DIV_MASK	0x000000ff
+/* receives a pixel clock spec in pico seconds, adjusts the DIU clock rate */
 static void mpc512x_set_pixel_clock(unsigned int pixclock)
 {
-	unsigned long bestval, bestfreq, speed, busfreq;
-	unsigned long minpixclock, maxpixclock, pixval;
-	struct mpc512x_ccm __iomem *ccm;
 	struct device_node *np;
-	u32 temp;
-	long err;
-	int i;
+	struct clk *clk_diu;
+	unsigned long epsilon, minpixclock, maxpixclock;
+	unsigned long offset, want, got, delta;
 
-	np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock");
+	/* lookup and enable the DIU clock */
+	np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-diu");
 	if (!np) {
-		pr_err("Can't find clock control module.\n");
+		pr_err("Could not find DIU device tree node.\n");
 		return;
 	}
-
-	ccm = of_iomap(np, 0);
+	clk_diu = of_clk_get(np, 0);
+	if (IS_ERR(clk_diu)) {
+		/* backwards compat with device trees that lack clock specs */
+		clk_diu = clk_get_sys(np->name, "ipg");
+	}
 	of_node_put(np);
-	if (!ccm) {
-		pr_err("Can't map clock control module reg.\n");
+	if (IS_ERR(clk_diu)) {
+		pr_err("Could not lookup DIU clock.\n");
 		return;
 	}
-
-	np = of_find_node_by_type(NULL, "cpu");
-	if (np) {
-		const unsigned int *prop =
-			of_get_property(np, "bus-frequency", NULL);
-
-		of_node_put(np);
-		if (prop) {
-			busfreq = *prop;
-		} else {
-			pr_err("Can't get bus-frequency property\n");
-			return;
-		}
-	} else {
-		pr_err("Can't find 'cpu' node.\n");
+	if (clk_prepare_enable(clk_diu)) {
+		pr_err("Could not enable DIU clock.\n");
 		return;
 	}
 
-	/* Pixel Clock configuration */
-	pr_debug("DIU: Bus Frequency = %lu\n", busfreq);
-	speed = busfreq * 4; /* DIU_DIV ratio is 4 * CSB_CLK / DIU_CLK */
-
-	/* Calculate the pixel clock with the smallest error */
-	/* calculate the following in steps to avoid overflow */
-	pr_debug("DIU pixclock in ps - %d\n", pixclock);
-	temp = (1000000000 / pixclock) * 1000;
-	pixclock = temp;
-	pr_debug("DIU pixclock freq - %u\n", pixclock);
-
-	temp = temp / 20; /* pixclock * 0.05 */
-	pr_debug("deviation = %d\n", temp);
-	minpixclock = pixclock - temp;
-	maxpixclock = pixclock + temp;
-	pr_debug("DIU minpixclock - %lu\n", minpixclock);
-	pr_debug("DIU maxpixclock - %lu\n", maxpixclock);
-	pixval = speed/pixclock;
-	pr_debug("DIU pixval = %lu\n", pixval);
-
-	err = LONG_MAX;
-	bestval = pixval;
-	pr_debug("DIU bestval = %lu\n", bestval);
-
-	bestfreq = 0;
-	for (i = -1; i <= 1; i++) {
-		temp = speed / (pixval+i);
-		pr_debug("DIU test pixval i=%d, pixval=%lu, temp freq. = %u\n",
-			i, pixval, temp);
-		if ((temp < minpixclock) || (temp > maxpixclock))
-			pr_debug("DIU exceeds monitor range (%lu to %lu)\n",
-				minpixclock, maxpixclock);
-		else if (abs(temp - pixclock) < err) {
-			pr_debug("Entered the else if block %d\n", i);
-			err = abs(temp - pixclock);
-			bestval = pixval + i;
-			bestfreq = temp;
-		}
+	/*
+	 * convert the picoseconds spec into the desired clock rate,
+	 * determine the acceptable clock range for the monitor (+/- 5%),
+	 * do the calculation in steps to avoid integer overflow
+	 */
+	pr_debug("DIU pixclock in ps - %u\n", pixclock);
+	pixclock = (1000000000 / pixclock) * 1000;
+	pr_debug("DIU pixclock freq  - %u\n", pixclock);
+	epsilon = pixclock / 20; /* pixclock * 0.05 */
+	pr_debug("DIU deviation      - %lu\n", epsilon);
+	minpixclock = pixclock - epsilon;
+	maxpixclock = pixclock + epsilon;
+	pr_debug("DIU minpixclock    - %lu\n", minpixclock);
+	pr_debug("DIU maxpixclock    - %lu\n", maxpixclock);
+
+	/*
+	 * check whether the DIU supports the desired pixel clock
+	 *
+	 * - simply request the desired clock and see what the
+	 *   platform's clock driver will make of it, assuming that it
+	 *   will setup the best approximation of the requested value
+	 * - try other candidate frequencies in the order of decreasing
+	 *   preference (i.e. with increasing distance from the desired
+	 *   pixel clock, and checking the lower frequency before the
+	 *   higher frequency to not overload the hardware) until the
+	 *   first match is found -- any potential subsequent match
+	 *   would only be as good as the former match or typically
+	 *   would be less preferrable
+	 *
+	 * the offset increment of pixelclock divided by 64 is an
+	 * arbitrary choice -- it's simple to calculate, in the typical
+	 * case we expect the first check to succeed already, in the
+	 * worst case seven frequencies get tested (the exact center and
+	 * three more values each to the left and to the right) before
+	 * the 5% tolerance window is exceeded, resulting in fast enough
+	 * execution yet high enough probability of finding a suitable
+	 * value, while the error rate will be in the order of single
+	 * percents
+	 */
+	for (offset = 0; offset <= epsilon; offset += pixclock / 64) {
+		want = pixclock - offset;
+		pr_debug("DIU checking clock - %lu\n", want);
+		clk_set_rate(clk_diu, want);
+		got = clk_get_rate(clk_diu);
+		delta = abs(pixclock - got);
+		if (delta < epsilon)
+			break;
+		if (!offset)
+			continue;
+		want = pixclock + offset;
+		pr_debug("DIU checking clock - %lu\n", want);
+		clk_set_rate(clk_diu, want);
+		got = clk_get_rate(clk_diu);
+		delta = abs(pixclock - got);
+		if (delta < epsilon)
+			break;
 	}
+	if (offset <= epsilon) {
+		pr_debug("DIU clock accepted - %lu\n", want);
+		pr_debug("DIU pixclock want %u, got %lu, delta %lu, eps %lu\n",
+			 pixclock, got, delta, epsilon);
+		return;
+	}
+	pr_warn("DIU pixclock auto search unsuccessful\n");
 
-	pr_debug("DIU chose = %lx\n", bestval);
-	pr_debug("DIU error = %ld\n NomPixClk ", err);
-	pr_debug("DIU: Best Freq = %lx\n", bestfreq);
-	/* Modify DIU_DIV in CCM SCFR1 */
-	temp = in_be32(&ccm->scfr1);
-	pr_debug("DIU: Current value of SCFR1: 0x%08x\n", temp);
-	temp &= ~DIU_DIV_MASK;
-	temp |= (bestval & DIU_DIV_MASK);
-	out_be32(&ccm->scfr1, temp);
-	pr_debug("DIU: Modified value of SCFR1: 0x%08x\n", temp);
-	iounmap(ccm);
+	/*
+	 * what is the most appropriate action to take when the search
+	 * for an available pixel clock which is acceptable to the
+	 * monitor has failed?  disable the DIU (clock) or just provide
+	 * a "best effort"?  we go with the latter
+	 */
+	pr_warn("DIU pixclock best effort fallback (backend's choice)\n");
+	clk_set_rate(clk_diu, pixclock);
+	got = clk_get_rate(clk_diu);
+	delta = abs(pixclock - got);
+	pr_debug("DIU pixclock want %u, got %lu, delta %lu, eps %lu\n",
+		 pixclock, got, delta, epsilon);
 }
 
 static enum fsl_diu_monitor_port
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v6 15/17] net: can: mscan: remove non-CCF code for MPC512x
From: Gerhard Sittig @ 2013-11-30 22:51 UTC (permalink / raw)
  To: linuxppc-dev, linux-arm-kernel, Anatolij Gustschin,
	Mike Turquette
  Cc: Detlev Zundel, Gerhard Sittig, linux-can, Marc Kleine-Budde,
	Scott Wood, Wolfgang Grandegger
In-Reply-To: <1385851897-23475-1-git-send-email-gsi@denx.de>

transition to the common clock framework has completed and the PPC_CLOCK
is no longer available for the MPC512x platform, remove the now obsolete
code path of the mpc5xxx mscan driver which accessed clock control module
registers directly

Cc: Wolfgang Grandegger <wg@grandegger.com>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: linux-can@vger.kernel.org
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
 drivers/net/can/mscan/mpc5xxx_can.c |  141 -----------------------------------
 1 file changed, 141 deletions(-)

diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c
index f48f1297ff30..6b0c9958d824 100644
--- a/drivers/net/can/mscan/mpc5xxx_can.c
+++ b/drivers/net/can/mscan/mpc5xxx_can.c
@@ -109,9 +109,6 @@ static u32 mpc52xx_can_get_clock(struct platform_device *ofdev,
 #endif /* CONFIG_PPC_MPC52xx */
 
 #ifdef CONFIG_PPC_MPC512x
-
-#if IS_ENABLED(CONFIG_COMMON_CLK)
-
 static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
 				 const char *clock_source, int *mscan_clksrc)
 {
@@ -277,144 +274,6 @@ static void mpc512x_can_put_clock(struct platform_device *ofdev)
 	if (priv->clk_ipg)
 		clk_disable_unprepare(priv->clk_ipg);
 }
-
-#else	/* COMMON_CLK */
-
-struct mpc512x_clockctl {
-	u32 spmr;		/* System PLL Mode Reg */
-	u32 sccr[2];		/* System Clk Ctrl Reg 1 & 2 */
-	u32 scfr1;		/* System Clk Freq Reg 1 */
-	u32 scfr2;		/* System Clk Freq Reg 2 */
-	u32 reserved;
-	u32 bcr;		/* Bread Crumb Reg */
-	u32 pccr[12];		/* PSC Clk Ctrl Reg 0-11 */
-	u32 spccr;		/* SPDIF Clk Ctrl Reg */
-	u32 cccr;		/* CFM Clk Ctrl Reg */
-	u32 dccr;		/* DIU Clk Cnfg Reg */
-	u32 mccr[4];		/* MSCAN Clk Ctrl Reg 1-3 */
-};
-
-static struct of_device_id mpc512x_clock_ids[] = {
-	{ .compatible = "fsl,mpc5121-clock", },
-	{}
-};
-
-static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
-				 const char *clock_name, int *mscan_clksrc)
-{
-	struct mpc512x_clockctl __iomem *clockctl;
-	struct device_node *np_clock;
-	struct clk *sys_clk, *ref_clk;
-	int plen, clockidx, clocksrc = -1;
-	u32 sys_freq, val, clockdiv = 1, freq = 0;
-	const u32 *pval;
-
-	np_clock = of_find_matching_node(NULL, mpc512x_clock_ids);
-	if (!np_clock) {
-		dev_err(&ofdev->dev, "couldn't find clock node\n");
-		return 0;
-	}
-	clockctl = of_iomap(np_clock, 0);
-	if (!clockctl) {
-		dev_err(&ofdev->dev, "couldn't map clock registers\n");
-		goto exit_put;
-	}
-
-	/* Determine the MSCAN device index from the peripheral's
-	 * physical address. Register address offsets against the
-	 * IMMR base are:  0x1300, 0x1380, 0x2300, 0x2380
-	 */
-	pval = of_get_property(ofdev->dev.of_node, "reg", &plen);
-	BUG_ON(!pval || plen < sizeof(*pval));
-	clockidx = (*pval & 0x80) ? 1 : 0;
-	if (*pval & 0x2000)
-		clockidx += 2;
-
-	/*
-	 * Clock source and divider selection: 3 different clock sources
-	 * can be selected: "ip", "ref" or "sys". For the latter two, a
-	 * clock divider can be defined as well. If the clock source is
-	 * not specified by the device tree, we first try to find an
-	 * optimal CAN source clock based on the system clock. If that
-	 * is not posslible, the reference clock will be used.
-	 */
-	if (clock_name && !strcmp(clock_name, "ip")) {
-		*mscan_clksrc = MSCAN_CLKSRC_IPS;
-		freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node);
-	} else {
-		*mscan_clksrc = MSCAN_CLKSRC_BUS;
-
-		pval = of_get_property(ofdev->dev.of_node,
-				       "fsl,mscan-clock-divider", &plen);
-		if (pval && plen == sizeof(*pval))
-			clockdiv = *pval;
-		if (!clockdiv)
-			clockdiv = 1;
-
-		if (!clock_name || !strcmp(clock_name, "sys")) {
-			sys_clk = devm_clk_get(&ofdev->dev, "sys_clk");
-			if (IS_ERR(sys_clk)) {
-				dev_err(&ofdev->dev, "couldn't get sys_clk\n");
-				goto exit_unmap;
-			}
-			/* Get and round up/down sys clock rate */
-			sys_freq = 1000000 *
-				((clk_get_rate(sys_clk) + 499999) / 1000000);
-
-			if (!clock_name) {
-				/* A multiple of 16 MHz would be optimal */
-				if ((sys_freq % 16000000) == 0) {
-					clocksrc = 0;
-					clockdiv = sys_freq / 16000000;
-					freq = sys_freq / clockdiv;
-				}
-			} else {
-				clocksrc = 0;
-				freq = sys_freq / clockdiv;
-			}
-		}
-
-		if (clocksrc < 0) {
-			ref_clk = devm_clk_get(&ofdev->dev, "ref_clk");
-			if (IS_ERR(ref_clk)) {
-				dev_err(&ofdev->dev, "couldn't get ref_clk\n");
-				goto exit_unmap;
-			}
-			clocksrc = 1;
-			freq = clk_get_rate(ref_clk) / clockdiv;
-		}
-	}
-
-	/* Disable clock */
-	out_be32(&clockctl->mccr[clockidx], 0x0);
-	if (clocksrc >= 0) {
-		/* Set source and divider */
-		val = (clocksrc << 14) | ((clockdiv - 1) << 17);
-		out_be32(&clockctl->mccr[clockidx], val);
-		/* Enable clock */
-		out_be32(&clockctl->mccr[clockidx], val | 0x10000);
-	}
-
-	/* Enable MSCAN clock domain */
-	val = in_be32(&clockctl->sccr[1]);
-	if (!(val & (1 << 25)))
-		out_be32(&clockctl->sccr[1], val | (1 << 25));
-
-	dev_dbg(&ofdev->dev, "using '%s' with frequency divider %d\n",
-		*mscan_clksrc == MSCAN_CLKSRC_IPS ? "ips_clk" :
-		clocksrc == 1 ? "ref_clk" : "sys_clk", clockdiv);
-
-exit_unmap:
-	iounmap(clockctl);
-exit_put:
-	of_node_put(np_clock);
-	return freq;
-}
-
-#define mpc512x_can_put_clock NULL
-
-#endif	/* COMMON_CLK */
-
 #else /* !CONFIG_PPC_MPC512x */
 static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
 				 const char *clock_name, int *mscan_clksrc)
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v6 13/17] [media] fsl-viu: adjust for OF based clock lookup
From: Gerhard Sittig @ 2013-11-30 22:51 UTC (permalink / raw)
  To: linuxppc-dev, linux-arm-kernel, Anatolij Gustschin,
	Mike Turquette
  Cc: Scott Wood, Gerhard Sittig, linux-media, Detlev Zundel,
	Mauro Carvalho Chehab
In-Reply-To: <1385851897-23475-1-git-send-email-gsi@denx.de>

after device tree based clock lookup became available, the VIU driver
need no longer use the previous global "viu_clk" name, but should use
the "ipg" clock name specific to the OF node

Cc: Mauro Carvalho Chehab <m.chehab@samsung.com>
Cc: linux-media@vger.kernel.org
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
 drivers/media/platform/fsl-viu.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c
index 6a232239ee8c..dbf0ce38a8e7 100644
--- a/drivers/media/platform/fsl-viu.c
+++ b/drivers/media/platform/fsl-viu.c
@@ -1580,7 +1580,7 @@ static int viu_of_probe(struct platform_device *op)
 	}
 
 	/* enable VIU clock */
-	clk = devm_clk_get(&op->dev, "viu_clk");
+	clk = devm_clk_get(&op->dev, "ipg");
 	if (IS_ERR(clk)) {
 		dev_err(&op->dev, "failed to lookup the clock!\n");
 		ret = PTR_ERR(clk);
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v6 14/17] net: can: mscan: adjust to common clock support for mpc512x
From: Gerhard Sittig @ 2013-11-30 22:51 UTC (permalink / raw)
  To: linuxppc-dev, linux-arm-kernel, Anatolij Gustschin,
	Mike Turquette
  Cc: Detlev Zundel, Gerhard Sittig, linux-can, Marc Kleine-Budde,
	Scott Wood, Wolfgang Grandegger
In-Reply-To: <1385851897-23475-1-git-send-email-gsi@denx.de>

implement a .get_clock() callback for the MPC512x platform which uses
the common clock infrastructure (eliminating direct access to the clock
control registers from within the CAN network driver), and provide the
corresponding .put_clock() callback to release resources after use

acquire both the clock items for register access ("ipg") as well as for
wire communication ("can")

keep the previous implementation of MPC512x support in place during
migration, this results in a readable diff of the change

this change is neutral to the MPC5200 platform

Cc: Wolfgang Grandegger <wg@grandegger.com>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: linux-can@vger.kernel.org
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
 drivers/net/can/mscan/mpc5xxx_can.c |  179 +++++++++++++++++++++++++++++++++++
 1 file changed, 179 insertions(+)

diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c
index e59b3a392af6..f48f1297ff30 100644
--- a/drivers/net/can/mscan/mpc5xxx_can.c
+++ b/drivers/net/can/mscan/mpc5xxx_can.c
@@ -109,6 +109,177 @@ static u32 mpc52xx_can_get_clock(struct platform_device *ofdev,
 #endif /* CONFIG_PPC_MPC52xx */
 
 #ifdef CONFIG_PPC_MPC512x
+
+#if IS_ENABLED(CONFIG_COMMON_CLK)
+
+static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
+				 const char *clock_source, int *mscan_clksrc)
+{
+	struct device_node *np;
+	u32 clockdiv;
+	enum {
+		CLK_FROM_AUTO,
+		CLK_FROM_IPS,
+		CLK_FROM_SYS,
+		CLK_FROM_REF,
+	} clk_from;
+	struct clk *clk_in, *clk_can;
+	unsigned long freq_calc;
+	struct mscan_priv *priv;
+	struct clk *clk_ipg;
+
+	/* the caller passed in the clock source spec that was read from
+	 * the device tree, get the optional clock divider as well
+	 */
+	np = ofdev->dev.of_node;
+	clockdiv = 1;
+	of_property_read_u32(np, "fsl,mscan-clock-divider", &clockdiv);
+	dev_dbg(&ofdev->dev, "device tree specs: clk src[%s] div[%d]\n",
+		clock_source ? clock_source : "<NULL>", clockdiv);
+
+	/* when clock-source is 'ip', the CANCTL1[CLKSRC] bit needs to
+	 * get set, and the 'ips' clock is the input to the MSCAN
+	 * component
+	 *
+	 * for clock-source values of 'ref' or 'sys' the CANCTL1[CLKSRC]
+	 * bit needs to get cleared, an optional clock-divider may have
+	 * been specified (the default value is 1), the appropriate
+	 * MSCAN related MCLK is the input to the MSCAN component
+	 *
+	 * in the absence of a clock-source spec, first an optimal clock
+	 * gets determined based on the 'sys' clock, if that fails the
+	 * 'ref' clock is used
+	 */
+	clk_from = CLK_FROM_AUTO;
+	if (clock_source) {
+		/* interpret the device tree's spec for the clock source */
+		if (!strcmp(clock_source, "ip"))
+			clk_from = CLK_FROM_IPS;
+		else if (!strcmp(clock_source, "sys"))
+			clk_from = CLK_FROM_SYS;
+		else if (!strcmp(clock_source, "ref"))
+			clk_from = CLK_FROM_REF;
+		else
+			goto err_invalid;
+		dev_dbg(&ofdev->dev, "got a clk source spec[%d]\n", clk_from);
+	}
+	if (clk_from == CLK_FROM_AUTO) {
+		/* no spec so far, try the 'sys' clock; round to the
+		 * next MHz and see if we can get a multiple of 16MHz
+		 */
+		dev_dbg(&ofdev->dev, "no clk source spec, trying SYS\n");
+		clk_in = devm_clk_get(&ofdev->dev, "sys");
+		if (IS_ERR(clk_in))
+			goto err_notavail;
+		freq_calc = clk_get_rate(clk_in);
+		freq_calc +=  499999;
+		freq_calc /= 1000000;
+		freq_calc *= 1000000;
+		if ((freq_calc % 16000000) == 0) {
+			clk_from = CLK_FROM_SYS;
+			clockdiv = freq_calc / 16000000;
+			dev_dbg(&ofdev->dev,
+				"clk fit, sys[%lu] div[%d] freq[%lu]\n",
+				freq_calc, clockdiv, freq_calc / clockdiv);
+		}
+	}
+	if (clk_from == CLK_FROM_AUTO) {
+		/* no spec so far, use the 'ref' clock */
+		dev_dbg(&ofdev->dev, "no clk source spec, trying REF\n");
+		clk_in = devm_clk_get(&ofdev->dev, "ref");
+		if (IS_ERR(clk_in))
+			goto err_notavail;
+		clk_from = CLK_FROM_REF;
+		freq_calc = clk_get_rate(clk_in);
+		dev_dbg(&ofdev->dev,
+			"clk fit, ref[%lu] (no div) freq[%lu]\n",
+			freq_calc, freq_calc);
+	}
+
+	/* select IPS or MCLK as the MSCAN input (returned to the caller),
+	 * setup the MCLK mux source and rate if applicable, apply the
+	 * optionally specified or derived above divider, and determine
+	 * the actual resulting clock rate to return to the caller
+	 */
+	switch (clk_from) {
+	case CLK_FROM_IPS:
+		clk_can = devm_clk_get(&ofdev->dev, "ips");
+		if (IS_ERR(clk_can))
+			goto err_notavail;
+		priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
+		priv->clk_can = clk_can;
+		freq_calc = clk_get_rate(clk_can);
+		*mscan_clksrc = MSCAN_CLKSRC_IPS;
+		dev_dbg(&ofdev->dev, "clk from IPS, clksrc[%d] freq[%lu]\n",
+			*mscan_clksrc, freq_calc);
+		break;
+	case CLK_FROM_SYS:
+	case CLK_FROM_REF:
+		clk_can = devm_clk_get(&ofdev->dev, "mclk");
+		if (IS_ERR(clk_can))
+			goto err_notavail;
+		priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
+		priv->clk_can = clk_can;
+		if (clk_from == CLK_FROM_SYS)
+			clk_in = devm_clk_get(&ofdev->dev, "sys");
+		if (clk_from == CLK_FROM_REF)
+			clk_in = devm_clk_get(&ofdev->dev, "ref");
+		if (IS_ERR(clk_in))
+			goto err_notavail;
+		clk_set_parent(clk_can, clk_in);
+		freq_calc = clk_get_rate(clk_in);
+		freq_calc /= clockdiv;
+		clk_set_rate(clk_can, freq_calc);
+		freq_calc = clk_get_rate(clk_can);
+		*mscan_clksrc = MSCAN_CLKSRC_BUS;
+		dev_dbg(&ofdev->dev, "clk from MCLK, clksrc[%d] freq[%lu]\n",
+			*mscan_clksrc, freq_calc);
+		break;
+	default:
+		goto err_invalid;
+	}
+
+	/* the above clk_can item is used for the bitrate, access to
+	 * the peripheral's register set needs the clk_ipg item
+	 */
+	clk_ipg = devm_clk_get(&ofdev->dev, "ipg");
+	if (IS_ERR(clk_ipg))
+		goto err_notavail_ipg;
+	if (clk_prepare_enable(clk_ipg))
+		goto err_notavail_ipg;
+	priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
+	priv->clk_ipg = clk_ipg;
+
+	/* return the determined clock source rate */
+	return freq_calc;
+
+err_invalid:
+	dev_err(&ofdev->dev, "invalid clock source specification\n");
+	/* clock source rate could not get determined */
+	return 0;
+
+err_notavail:
+	dev_err(&ofdev->dev, "cannot acquire or setup bitrate clock source\n");
+	/* clock source rate could not get determined */
+	return 0;
+
+err_notavail_ipg:
+	dev_err(&ofdev->dev, "cannot acquire or setup register clock\n");
+	/* clock source rate could not get determined */
+	return 0;
+}
+
+static void mpc512x_can_put_clock(struct platform_device *ofdev)
+{
+	struct mscan_priv *priv;
+
+	priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
+	if (priv->clk_ipg)
+		clk_disable_unprepare(priv->clk_ipg);
+}
+
+#else	/* COMMON_CLK */
+
 struct mpc512x_clockctl {
 	u32 spmr;		/* System PLL Mode Reg */
 	u32 sccr[2];		/* System Clk Ctrl Reg 1 & 2 */
@@ -239,12 +410,18 @@ exit_put:
 	of_node_put(np_clock);
 	return freq;
 }
+
+#define mpc512x_can_put_clock NULL
+
+#endif	/* COMMON_CLK */
+
 #else /* !CONFIG_PPC_MPC512x */
 static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
 				 const char *clock_name, int *mscan_clksrc)
 {
 	return 0;
 }
+#define mpc512x_can_put_clock NULL
 #endif /* CONFIG_PPC_MPC512x */
 
 static const struct of_device_id mpc5xxx_can_table[];
@@ -386,11 +563,13 @@ static int mpc5xxx_can_resume(struct platform_device *ofdev)
 static const struct mpc5xxx_can_data mpc5200_can_data = {
 	.type = MSCAN_TYPE_MPC5200,
 	.get_clock = mpc52xx_can_get_clock,
+	/* .put_clock not applicable */
 };
 
 static const struct mpc5xxx_can_data mpc5121_can_data = {
 	.type = MSCAN_TYPE_MPC5121,
 	.get_clock = mpc512x_can_get_clock,
+	.put_clock = mpc512x_can_put_clock,
 };
 
 static const struct of_device_id mpc5xxx_can_table[] = {
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v6 12/17] mtd: mpc5121_nfc: adjust for OF based clock lookup
From: Gerhard Sittig @ 2013-11-30 22:51 UTC (permalink / raw)
  To: linuxppc-dev, linux-arm-kernel, Anatolij Gustschin,
	Mike Turquette
  Cc: Detlev Zundel, Artem Bityutskiy, Gerhard Sittig, linux-mtd,
	Scott Wood, David Woodhouse
In-Reply-To: <1385851897-23475-1-git-send-email-gsi@denx.de>

after device tree based clock lookup became available, the NAND
flash driver need no longer use the previous global "nfc_clk" name,
but should use the "ipg" clock name specific to the OF node

Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Cc: linux-mtd@lists.infradead.org
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
 drivers/mtd/nand/mpc5121_nfc.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c
index 439bc3896418..779e60d12f89 100644
--- a/drivers/mtd/nand/mpc5121_nfc.c
+++ b/drivers/mtd/nand/mpc5121_nfc.c
@@ -731,7 +731,7 @@ static int mpc5121_nfc_probe(struct platform_device *op)
 	of_node_put(rootnode);
 
 	/* Enable NFC clock */
-	clk = devm_clk_get(dev, "nfc_clk");
+	clk = devm_clk_get(dev, "ipg");
 	if (IS_ERR(clk)) {
 		dev_err(dev, "Unable to acquire NFC clock!\n");
 		retval = PTR_ERR(clk);
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v6 11/17] USB: fsl-mph-dr-of: adjust for OF based clock lookup
From: Gerhard Sittig @ 2013-11-30 22:51 UTC (permalink / raw)
  To: linuxppc-dev, linux-arm-kernel, Anatolij Gustschin,
	Mike Turquette
  Cc: Scott Wood, Greg Kroah-Hartman, Gerhard Sittig, linux-usb,
	Detlev Zundel
In-Reply-To: <1385851897-23475-1-git-send-email-gsi@denx.de>

after device tree based clock lookup became available, the peripheral
driver need no longer construct clock names which include the component
index -- remove the "usb%d_clk" template, always use "ipg" instead

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-usb@vger.kernel.org
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
 drivers/usb/host/fsl-mph-dr-of.c |   13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c
index abd5050a4899..9162d1b6c0a3 100644
--- a/drivers/usb/host/fsl-mph-dr-of.c
+++ b/drivers/usb/host/fsl-mph-dr-of.c
@@ -261,19 +261,8 @@ int fsl_usb2_mpc5121_init(struct platform_device *pdev)
 	struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev);
 	struct clk *clk;
 	int err;
-	char clk_name[10];
-	int base, clk_num;
-
-	base = pdev->resource->start & 0xf000;
-	if (base == 0x3000)
-		clk_num = 1;
-	else if (base == 0x4000)
-		clk_num = 2;
-	else
-		return -ENODEV;
 
-	snprintf(clk_name, sizeof(clk_name), "usb%d_clk", clk_num);
-	clk = devm_clk_get(pdev->dev.parent, clk_name);
+	clk = devm_clk_get(pdev->dev.parent, "ipg");
 	if (IS_ERR(clk)) {
 		dev_err(&pdev->dev, "failed to get clk\n");
 		return PTR_ERR(clk);
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v6 08/17] spi: mpc512x: adjust to OF based clock lookup
From: Gerhard Sittig @ 2013-11-30 22:51 UTC (permalink / raw)
  To: linuxppc-dev, linux-arm-kernel, Anatolij Gustschin,
	Mike Turquette
  Cc: Scott Wood, Gerhard Sittig, Mark Brown, Detlev Zundel, linux-spi
In-Reply-To: <1385851897-23475-1-git-send-email-gsi@denx.de>

after device tree based clock lookup became available, the peripheral
driver need no longer construct clock names which include the PSC index,
remove the "psc%d_mclk" template and unconditionally use 'mclk'

acquire and release the 'ipg' clock item for register access as well

Cc: Mark Brown <broonie@kernel.org>
Cc: linux-spi@vger.kernel.org
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
 drivers/spi/spi-mpc512x-psc.c |   26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c
index 9602bbd8d7ea..de66c676c248 100644
--- a/drivers/spi/spi-mpc512x-psc.c
+++ b/drivers/spi/spi-mpc512x-psc.c
@@ -40,6 +40,7 @@ struct mpc512x_psc_spi {
 	unsigned int irq;
 	u8 bits_per_word;
 	struct clk *clk_mclk;
+	struct clk *clk_ipg;
 	u32 mclk_rate;
 
 	struct completion txisrdone;
@@ -475,8 +476,6 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
 	struct spi_master *master;
 	int ret;
 	void *tempp;
-	int psc_num;
-	char clk_name[16];
 	struct clk *clk;
 
 	master = spi_alloc_master(dev, sizeof *mps);
@@ -520,9 +519,7 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
 		goto free_master;
 	init_completion(&mps->txisrdone);
 
-	psc_num = master->bus_num;
-	snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num);
-	clk = devm_clk_get(dev, clk_name);
+	clk = devm_clk_get(dev, "mclk");
 	if (IS_ERR(clk)) {
 		ret = PTR_ERR(clk);
 		goto free_irq;
@@ -533,17 +530,29 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
 	mps->clk_mclk = clk;
 	mps->mclk_rate = clk_get_rate(clk);
 
+	clk = devm_clk_get(dev, "ipg");
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		goto free_mclk_clock;
+	}
+	ret = clk_prepare_enable(clk);
+	if (ret)
+		goto free_mclk_clock;
+	mps->clk_ipg = clk;
+
 	ret = mpc512x_psc_spi_port_config(master, mps);
 	if (ret < 0)
-		goto free_clock;
+		goto free_ipg_clock;
 
 	ret = devm_spi_register_master(dev, master);
 	if (ret < 0)
-		goto free_clock;
+		goto free_ipg_clock;
 
 	return ret;
 
-free_clock:
+free_ipg_clock:
+	clk_disable_unprepare(mps->clk_ipg);
+free_mclk_clock:
 	clk_disable_unprepare(mps->clk_mclk);
 free_irq:
 	free_irq(mps->irq, mps);
@@ -561,6 +570,7 @@ static int mpc512x_psc_spi_do_remove(struct device *dev)
 	struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
 
 	clk_disable_unprepare(mps->clk_mclk);
+	clk_disable_unprepare(mps->clk_ipg);
 	free_irq(mps->irq, mps);
 	if (mps->psc)
 		iounmap(mps->psc);
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v6 10/17] serial: mpc512x: setup the PSC FIFO clock as well
From: Gerhard Sittig @ 2013-11-30 22:51 UTC (permalink / raw)
  To: linuxppc-dev, linux-arm-kernel, Anatolij Gustschin,
	Mike Turquette
  Cc: Detlev Zundel, Greg Kroah-Hartman, Gerhard Sittig, linux-serial,
	Scott Wood, Jiri Slaby
In-Reply-To: <1385851897-23475-1-git-send-email-gsi@denx.de>

prepare and enable the FIFO clock upon PSC FIFO initialization,
check for and propagage errors when enabling the PSC FIFO clock,
disable and unprepare the FIFO clock upon PSC FIFO uninitialization

devm_{get,put}_clk() doesn't apply here, as the SoC provides a
single FIFO component which is shared among several PSC components,
thus the FIFO isn't associated with a device (while the PSCs are)

provide a fallback clock lookup approach in case the OF based clock
lookup for the PSC FIFO fails, this allows for successful operation in
the presence of an outdated device tree which lacks clock specs

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: linux-serial@vger.kernel.org
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> # for v4
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
Greg, the addition since v4 is the clk_get_sys() call for the 'ipg'
clock item (backwards compat for device trees w/o clock specs)

---
 drivers/tty/serial/mpc52xx_uart.c |   50 ++++++++++++++++++++++++++++++++-----
 1 file changed, 44 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c
index 6345f377a246..97888f4900ec 100644
--- a/drivers/tty/serial/mpc52xx_uart.c
+++ b/drivers/tty/serial/mpc52xx_uart.c
@@ -421,6 +421,7 @@ struct psc_fifoc {
 
 static struct psc_fifoc __iomem *psc_fifoc;
 static unsigned int psc_fifoc_irq;
+static struct clk *psc_fifoc_clk;
 
 static void mpc512x_psc_fifo_init(struct uart_port *port)
 {
@@ -568,36 +569,73 @@ static unsigned int mpc512x_psc_set_baudrate(struct uart_port *port,
 /* Init PSC FIFO Controller */
 static int __init mpc512x_psc_fifoc_init(void)
 {
+	int err;
 	struct device_node *np;
+	struct clk *clk;
+
+	/* default error code, potentially overwritten by clock calls */
+	err = -ENODEV;
 
 	np = of_find_compatible_node(NULL, NULL,
 				     "fsl,mpc5121-psc-fifo");
 	if (!np) {
 		pr_err("%s: Can't find FIFOC node\n", __func__);
-		return -ENODEV;
+		goto out_err;
+	}
+
+	clk = of_clk_get(np, 0);
+	if (IS_ERR(clk)) {
+		/* backwards compat with device trees that lack clock specs */
+		clk = clk_get_sys(np->name, "ipg");
+	}
+	if (IS_ERR(clk)) {
+		pr_err("%s: Can't lookup FIFO clock\n", __func__);
+		err = PTR_ERR(clk);
+		goto out_ofnode_put;
+	}
+	if (clk_prepare_enable(clk)) {
+		pr_err("%s: Can't enable FIFO clock\n", __func__);
+		clk_put(clk);
+		goto out_ofnode_put;
 	}
+	psc_fifoc_clk = clk;
 
 	psc_fifoc = of_iomap(np, 0);
 	if (!psc_fifoc) {
 		pr_err("%s: Can't map FIFOC\n", __func__);
-		of_node_put(np);
-		return -ENODEV;
+		goto out_clk_disable;
 	}
 
 	psc_fifoc_irq = irq_of_parse_and_map(np, 0);
-	of_node_put(np);
 	if (psc_fifoc_irq == 0) {
 		pr_err("%s: Can't get FIFOC irq\n", __func__);
-		iounmap(psc_fifoc);
-		return -ENODEV;
+		goto out_unmap;
 	}
 
+	of_node_put(np);
 	return 0;
+
+out_unmap:
+	iounmap(psc_fifoc);
+out_clk_disable:
+	clk_disable_unprepare(psc_fifoc_clk);
+	clk_put(psc_fifoc_clk);
+out_ofnode_put:
+	of_node_put(np);
+out_err:
+	return err;
 }
 
 static void __exit mpc512x_psc_fifoc_uninit(void)
 {
 	iounmap(psc_fifoc);
+
+	/* disable the clock, errors are not fatal */
+	if (psc_fifoc_clk) {
+		clk_disable_unprepare(psc_fifoc_clk);
+		clk_put(psc_fifoc_clk);
+		psc_fifoc_clk = NULL;
+	}
 }
 
 /* 512x specific interrupt handler. The caller holds the port lock */
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v6 07/17] clk: mpc5xxx: switch to COMMON_CLK, retire PPC_CLOCK
From: Gerhard Sittig @ 2013-11-30 22:51 UTC (permalink / raw)
  To: linuxppc-dev, linux-arm-kernel, Anatolij Gustschin,
	Mike Turquette
  Cc: Scott Wood, Gerhard Sittig, Detlev Zundel
In-Reply-To: <1385851897-23475-1-git-send-email-gsi@denx.de>

the setup before the change was
- arch/powerpc/Kconfig had the PPC_CLOCK option, off by default
- depending on the PPC_CLOCK option the arch/powerpc/kernel/clock.c file
  was built, which implements the clk.h API but always returns -ENOSYS
  unless a platform registers specific callbacks
- the MPC52xx platform selected PPC_CLOCK but did not register any
  callbacks, thus all clk.h API calls keep resulting in -ENOSYS errors
  (which is OK, all peripheral drivers deal with the situation)
- the MPC512x platform selected PPC_CLOCK and registered specific
  callbacks implemented in arch/powerpc/platforms/512x/clock.c, thus
  provided real support for the clock API
- no other powerpc platform did select PPC_CLOCK

the situation after the change is
- the MPC512x platform implements the COMMON_CLK interface, and thus the
  PPC_CLOCK approach in arch/powerpc/platforms/512x/clock.c has become
  obsolete
- the MPC52xx platform still lacks genuine support for the clk.h API
  while this is not a change against the previous situation (the error
  code returned from COMMON_CLK stubs differs but every call still
  results in an error)
- with all references gone, the arch/powerpc/kernel/clock.c wrapper and
  the PPC_CLOCK option have become obsolete, as did the clk_interface.h
  header file

the switch from PPC_CLOCK to COMMON_CLK is done for all platforms within
the same commit such that multiplatform kernels (the combination of 512x
and 52xx within one executable) keep working

Cc: Mike Turquette <mturquette@linaro.org>
Cc: Anatolij Gustschin <agust@denx.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
 arch/powerpc/Kconfig                     |    5 -
 arch/powerpc/include/asm/clk_interface.h |   20 -
 arch/powerpc/kernel/Makefile             |    1 -
 arch/powerpc/kernel/clock.c              |   82 ----
 arch/powerpc/platforms/512x/Kconfig      |    2 +-
 arch/powerpc/platforms/512x/Makefile     |    1 -
 arch/powerpc/platforms/512x/clock.c      |  754 ------------------------------
 arch/powerpc/platforms/52xx/Kconfig      |    2 +-
 8 files changed, 2 insertions(+), 865 deletions(-)
 delete mode 100644 arch/powerpc/include/asm/clk_interface.h
 delete mode 100644 arch/powerpc/kernel/clock.c
 delete mode 100644 arch/powerpc/platforms/512x/clock.c

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index b44b52c0a8f0..26f8d940c6b8 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -1037,11 +1037,6 @@ config KEYS_COMPAT
 
 source "crypto/Kconfig"
 
-config PPC_CLOCK
-	bool
-	default n
-	select HAVE_CLK
-
 config PPC_LIB_RHEAP
 	bool
 
diff --git a/arch/powerpc/include/asm/clk_interface.h b/arch/powerpc/include/asm/clk_interface.h
deleted file mode 100644
index ab1882c1e176..000000000000
--- a/arch/powerpc/include/asm/clk_interface.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __ASM_POWERPC_CLK_INTERFACE_H
-#define __ASM_POWERPC_CLK_INTERFACE_H
-
-#include <linux/clk.h>
-
-struct clk_interface {
-	struct clk*	(*clk_get)	(struct device *dev, const char *id);
-	int		(*clk_enable)	(struct clk *clk);
-	void		(*clk_disable)	(struct clk *clk);
-	unsigned long	(*clk_get_rate)	(struct clk *clk);
-	void		(*clk_put)	(struct clk *clk);
-	long		(*clk_round_rate) (struct clk *clk, unsigned long rate);
-	int 		(*clk_set_rate)	(struct clk *clk, unsigned long rate);
-	int		(*clk_set_parent) (struct clk *clk, struct clk *parent);
-	struct clk*	(*clk_get_parent) (struct clk *clk);
-};
-
-extern struct clk_interface clk_functions;
-
-#endif /* __ASM_POWERPC_CLK_INTERFACE_H */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 445cb6e39d5b..f460a3b769dc 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -47,7 +47,6 @@ obj-$(CONFIG_ALTIVEC)		+= vecemu.o
 obj-$(CONFIG_PPC_970_NAP)	+= idle_power4.o
 obj-$(CONFIG_PPC_P7_NAP)	+= idle_power7.o
 obj-$(CONFIG_PPC_OF)		+= of_platform.o prom_parse.o
-obj-$(CONFIG_PPC_CLOCK)		+= clock.o
 procfs-y			:= proc_powerpc.o
 obj-$(CONFIG_PROC_FS)		+= $(procfs-y)
 rtaspci-$(CONFIG_PPC64)-$(CONFIG_PCI)	:= rtas_pci.o
diff --git a/arch/powerpc/kernel/clock.c b/arch/powerpc/kernel/clock.c
deleted file mode 100644
index a764b47791e8..000000000000
--- a/arch/powerpc/kernel/clock.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Dummy clk implementations for powerpc.
- * These need to be overridden in platform code.
- */
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/errno.h>
-#include <linux/export.h>
-#include <asm/clk_interface.h>
-
-struct clk_interface clk_functions;
-
-struct clk *clk_get(struct device *dev, const char *id)
-{
-	if (clk_functions.clk_get)
-		return clk_functions.clk_get(dev, id);
-	return ERR_PTR(-ENOSYS);
-}
-EXPORT_SYMBOL(clk_get);
-
-void clk_put(struct clk *clk)
-{
-	if (clk_functions.clk_put)
-		clk_functions.clk_put(clk);
-}
-EXPORT_SYMBOL(clk_put);
-
-int clk_enable(struct clk *clk)
-{
-	if (clk_functions.clk_enable)
-		return clk_functions.clk_enable(clk);
-	return -ENOSYS;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-	if (clk_functions.clk_disable)
-		clk_functions.clk_disable(clk);
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-	if (clk_functions.clk_get_rate)
-		return clk_functions.clk_get_rate(clk);
-	return 0;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	if (clk_functions.clk_round_rate)
-		return clk_functions.clk_round_rate(clk, rate);
-	return -ENOSYS;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	if (clk_functions.clk_set_rate)
-		return clk_functions.clk_set_rate(clk, rate);
-	return -ENOSYS;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-struct clk *clk_get_parent(struct clk *clk)
-{
-	if (clk_functions.clk_get_parent)
-		return clk_functions.clk_get_parent(clk);
-	return ERR_PTR(-ENOSYS);
-}
-EXPORT_SYMBOL(clk_get_parent);
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-	if (clk_functions.clk_set_parent)
-		return clk_functions.clk_set_parent(clk, parent);
-	return -ENOSYS;
-}
-EXPORT_SYMBOL(clk_set_parent);
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
index fc9c1cbfcb1d..5aa3f4b5332c 100644
--- a/arch/powerpc/platforms/512x/Kconfig
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -1,9 +1,9 @@
 config PPC_MPC512x
 	bool "512x-based boards"
 	depends on 6xx
+	select COMMON_CLK
 	select FSL_SOC
 	select IPIC
-	select PPC_CLOCK
 	select PPC_PCI_CHOICE
 	select FSL_PCI if PCI
 	select ARCH_WANT_OPTIONAL_GPIOLIB
diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile
index 1e05f9def8a4..01693121a2b1 100644
--- a/arch/powerpc/platforms/512x/Makefile
+++ b/arch/powerpc/platforms/512x/Makefile
@@ -1,7 +1,6 @@
 #
 # Makefile for the Freescale PowerPC 512x linux kernel.
 #
-obj-$(CONFIG_PPC_CLOCK)		+= clock.o
 obj-$(CONFIG_COMMON_CLK)	+= clock-commonclk.o
 obj-y				+= mpc512x_shared.o
 obj-$(CONFIG_MPC5121_ADS)	+= mpc5121_ads.o mpc5121_ads_cpld.o
diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c
deleted file mode 100644
index fd8a37653417..000000000000
--- a/arch/powerpc/platforms/512x/clock.c
+++ /dev/null
@@ -1,754 +0,0 @@
-/*
- * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Author: John Rigby <jrigby@freescale.com>
- *
- * Implements the clk api defined in include/linux/clk.h
- *
- *    Original based on linux/arch/arm/mach-integrator/clock.c
- *
- *    Copyright (C) 2004 ARM Limited.
- *    Written by Deep Blue Solutions Limited.
- *
- * 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/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-#include <linux/io.h>
-
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <asm/mpc5xxx.h>
-#include <asm/mpc5121.h>
-#include <asm/clk_interface.h>
-
-#include "mpc512x.h"
-
-#undef CLK_DEBUG
-
-static int clocks_initialized;
-
-#define CLK_HAS_RATE	0x1	/* has rate in MHz */
-#define CLK_HAS_CTRL	0x2	/* has control reg and bit */
-
-struct clk {
-	struct list_head node;
-	char name[32];
-	int flags;
-	struct device *dev;
-	unsigned long rate;
-	struct module *owner;
-	void (*calc) (struct clk *);
-	struct clk *parent;
-	int reg, bit;		/* CLK_HAS_CTRL */
-	int div_shift;		/* only used by generic_div_clk_calc */
-};
-
-static LIST_HEAD(clocks);
-static DEFINE_MUTEX(clocks_mutex);
-
-static struct clk *mpc5121_clk_get(struct device *dev, const char *id)
-{
-	struct clk *p, *clk = ERR_PTR(-ENOENT);
-	int dev_match;
-	int id_match;
-
-	if (dev == NULL || id == NULL)
-		return clk;
-
-	mutex_lock(&clocks_mutex);
-	list_for_each_entry(p, &clocks, node) {
-		dev_match = id_match = 0;
-
-		if (dev == p->dev)
-			dev_match++;
-		if (strcmp(id, p->name) == 0)
-			id_match++;
-		if ((dev_match || id_match) && try_module_get(p->owner)) {
-			clk = p;
-			break;
-		}
-	}
-	mutex_unlock(&clocks_mutex);
-
-	return clk;
-}
-
-#ifdef CLK_DEBUG
-static void dump_clocks(void)
-{
-	struct clk *p;
-
-	mutex_lock(&clocks_mutex);
-	printk(KERN_INFO "CLOCKS:\n");
-	list_for_each_entry(p, &clocks, node) {
-		pr_info("  %s=%ld", p->name, p->rate);
-		if (p->parent)
-			pr_cont(" %s=%ld", p->parent->name,
-			       p->parent->rate);
-		if (p->flags & CLK_HAS_CTRL)
-			pr_cont(" reg/bit=%d/%d", p->reg, p->bit);
-		pr_cont("\n");
-	}
-	mutex_unlock(&clocks_mutex);
-}
-#define	DEBUG_CLK_DUMP() dump_clocks()
-#else
-#define	DEBUG_CLK_DUMP()
-#endif
-
-
-static void mpc5121_clk_put(struct clk *clk)
-{
-	module_put(clk->owner);
-}
-
-#define NRPSC 12
-
-struct mpc512x_clockctl {
-	u32 spmr;		/* System PLL Mode Reg */
-	u32 sccr[2];		/* System Clk Ctrl Reg 1 & 2 */
-	u32 scfr1;		/* System Clk Freq Reg 1 */
-	u32 scfr2;		/* System Clk Freq Reg 2 */
-	u32 reserved;
-	u32 bcr;		/* Bread Crumb Reg */
-	u32 pccr[NRPSC];	/* PSC Clk Ctrl Reg 0-11 */
-	u32 spccr;		/* SPDIF Clk Ctrl Reg */
-	u32 cccr;		/* CFM Clk Ctrl Reg */
-	u32 dccr;		/* DIU Clk Cnfg Reg */
-};
-
-static struct mpc512x_clockctl __iomem *clockctl;
-
-static int mpc5121_clk_enable(struct clk *clk)
-{
-	unsigned int mask;
-
-	if (clk->flags & CLK_HAS_CTRL) {
-		mask = in_be32(&clockctl->sccr[clk->reg]);
-		mask |= 1 << clk->bit;
-		out_be32(&clockctl->sccr[clk->reg], mask);
-	}
-	return 0;
-}
-
-static void mpc5121_clk_disable(struct clk *clk)
-{
-	unsigned int mask;
-
-	if (clk->flags & CLK_HAS_CTRL) {
-		mask = in_be32(&clockctl->sccr[clk->reg]);
-		mask &= ~(1 << clk->bit);
-		out_be32(&clockctl->sccr[clk->reg], mask);
-	}
-}
-
-static unsigned long mpc5121_clk_get_rate(struct clk *clk)
-{
-	if (clk->flags & CLK_HAS_RATE)
-		return clk->rate;
-	else
-		return 0;
-}
-
-static long mpc5121_clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	return rate;
-}
-
-static int mpc5121_clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	return 0;
-}
-
-static int clk_register(struct clk *clk)
-{
-	mutex_lock(&clocks_mutex);
-	list_add(&clk->node, &clocks);
-	mutex_unlock(&clocks_mutex);
-	return 0;
-}
-
-static unsigned long spmf_mult(void)
-{
-	/*
-	 * Convert spmf to multiplier
-	 */
-	static int spmf_to_mult[] = {
-		68, 1, 12, 16,
-		20, 24, 28, 32,
-		36, 40, 44, 48,
-		52, 56, 60, 64
-	};
-	int spmf = (in_be32(&clockctl->spmr) >> 24) & 0xf;
-	return spmf_to_mult[spmf];
-}
-
-static unsigned long sysdiv_div_x_2(void)
-{
-	/*
-	 * Convert sysdiv to divisor x 2
-	 * Some divisors have fractional parts so
-	 * multiply by 2 then divide by this value
-	 */
-	static int sysdiv_to_div_x_2[] = {
-		4, 5, 6, 7,
-		8, 9, 10, 14,
-		12, 16, 18, 22,
-		20, 24, 26, 30,
-		28, 32, 34, 38,
-		36, 40, 42, 46,
-		44, 48, 50, 54,
-		52, 56, 58, 62,
-		60, 64, 66,
-	};
-	int sysdiv = (in_be32(&clockctl->scfr2) >> 26) & 0x3f;
-	return sysdiv_to_div_x_2[sysdiv];
-}
-
-static unsigned long ref_to_sys(unsigned long rate)
-{
-	rate *= spmf_mult();
-	rate *= 2;
-	rate /= sysdiv_div_x_2();
-
-	return rate;
-}
-
-static unsigned long sys_to_ref(unsigned long rate)
-{
-	rate *= sysdiv_div_x_2();
-	rate /= 2;
-	rate /= spmf_mult();
-
-	return rate;
-}
-
-static long ips_to_ref(unsigned long rate)
-{
-	int ips_div = (in_be32(&clockctl->scfr1) >> 23) & 0x7;
-
-	rate *= ips_div;	/* csb_clk = ips_clk * ips_div */
-	rate *= 2;		/* sys_clk = csb_clk * 2 */
-	return sys_to_ref(rate);
-}
-
-static unsigned long devtree_getfreq(char *clockname)
-{
-	struct device_node *np;
-	const unsigned int *prop;
-	unsigned int val = 0;
-
-	np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-immr");
-	if (np) {
-		prop = of_get_property(np, clockname, NULL);
-		if (prop)
-			val = *prop;
-	    of_node_put(np);
-	}
-	return val;
-}
-
-static void ref_clk_calc(struct clk *clk)
-{
-	unsigned long rate;
-
-	rate = devtree_getfreq("bus-frequency");
-	if (rate == 0) {
-		printk(KERN_ERR "No bus-frequency in dev tree\n");
-		clk->rate = 0;
-		return;
-	}
-	clk->rate = ips_to_ref(rate);
-}
-
-static struct clk ref_clk = {
-	.name = "ref_clk",
-	.calc = ref_clk_calc,
-};
-
-
-static void sys_clk_calc(struct clk *clk)
-{
-	clk->rate = ref_to_sys(ref_clk.rate);
-}
-
-static struct clk sys_clk = {
-	.name = "sys_clk",
-	.calc = sys_clk_calc,
-};
-
-static void diu_clk_calc(struct clk *clk)
-{
-	int diudiv_x_2 = in_be32(&clockctl->scfr1) & 0xff;
-	unsigned long rate;
-
-	rate = sys_clk.rate;
-
-	rate *= 2;
-	rate /= diudiv_x_2;
-
-	clk->rate = rate;
-}
-
-static void viu_clk_calc(struct clk *clk)
-{
-	unsigned long rate;
-
-	rate = sys_clk.rate;
-	rate /= 2;
-	clk->rate = rate;
-}
-
-static void half_clk_calc(struct clk *clk)
-{
-	clk->rate = clk->parent->rate / 2;
-}
-
-static void generic_div_clk_calc(struct clk *clk)
-{
-	int div = (in_be32(&clockctl->scfr1) >> clk->div_shift) & 0x7;
-
-	clk->rate = clk->parent->rate / div;
-}
-
-static void unity_clk_calc(struct clk *clk)
-{
-	clk->rate = clk->parent->rate;
-}
-
-static struct clk csb_clk = {
-	.name = "csb_clk",
-	.calc = half_clk_calc,
-	.parent = &sys_clk,
-};
-
-static void e300_clk_calc(struct clk *clk)
-{
-	int spmf = (in_be32(&clockctl->spmr) >> 16) & 0xf;
-	int ratex2 = clk->parent->rate * spmf;
-
-	clk->rate = ratex2 / 2;
-}
-
-static struct clk e300_clk = {
-	.name = "e300_clk",
-	.calc = e300_clk_calc,
-	.parent = &csb_clk,
-};
-
-static struct clk ips_clk = {
-	.name = "ips_clk",
-	.calc = generic_div_clk_calc,
-	.parent = &csb_clk,
-	.div_shift = 23,
-};
-
-/*
- * Clocks controlled by SCCR1 (.reg = 0)
- */
-static struct clk lpc_clk = {
-	.name = "lpc_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 0,
-	.bit = 30,
-	.calc = generic_div_clk_calc,
-	.parent = &ips_clk,
-	.div_shift = 11,
-};
-
-static struct clk nfc_clk = {
-	.name = "nfc_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 0,
-	.bit = 29,
-	.calc = generic_div_clk_calc,
-	.parent = &ips_clk,
-	.div_shift = 8,
-};
-
-static struct clk pata_clk = {
-	.name = "pata_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 0,
-	.bit = 28,
-	.calc = unity_clk_calc,
-	.parent = &ips_clk,
-};
-
-/*
- * PSC clocks (bits 27 - 16)
- * are setup elsewhere
- */
-
-static struct clk sata_clk = {
-	.name = "sata_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 0,
-	.bit = 14,
-	.calc = unity_clk_calc,
-	.parent = &ips_clk,
-};
-
-static struct clk fec_clk = {
-	.name = "fec_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 0,
-	.bit = 13,
-	.calc = unity_clk_calc,
-	.parent = &ips_clk,
-};
-
-static struct clk pci_clk = {
-	.name = "pci_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 0,
-	.bit = 11,
-	.calc = generic_div_clk_calc,
-	.parent = &csb_clk,
-	.div_shift = 20,
-};
-
-/*
- * Clocks controlled by SCCR2 (.reg = 1)
- */
-static struct clk diu_clk = {
-	.name = "diu_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 1,
-	.bit = 31,
-	.calc = diu_clk_calc,
-};
-
-static struct clk viu_clk = {
-	.name = "viu_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 1,
-	.bit = 18,
-	.calc = viu_clk_calc,
-};
-
-static struct clk axe_clk = {
-	.name = "axe_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 1,
-	.bit = 30,
-	.calc = unity_clk_calc,
-	.parent = &csb_clk,
-};
-
-static struct clk usb1_clk = {
-	.name = "usb1_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 1,
-	.bit = 28,
-	.calc = unity_clk_calc,
-	.parent = &csb_clk,
-};
-
-static struct clk usb2_clk = {
-	.name = "usb2_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 1,
-	.bit = 27,
-	.calc = unity_clk_calc,
-	.parent = &csb_clk,
-};
-
-static struct clk i2c_clk = {
-	.name = "i2c_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 1,
-	.bit = 26,
-	.calc = unity_clk_calc,
-	.parent = &ips_clk,
-};
-
-static struct clk mscan_clk = {
-	.name = "mscan_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 1,
-	.bit = 25,
-	.calc = unity_clk_calc,
-	.parent = &ips_clk,
-};
-
-static struct clk sdhc_clk = {
-	.name = "sdhc_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 1,
-	.bit = 24,
-	.calc = unity_clk_calc,
-	.parent = &ips_clk,
-};
-
-static struct clk mbx_bus_clk = {
-	.name = "mbx_bus_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 1,
-	.bit = 22,
-	.calc = half_clk_calc,
-	.parent = &csb_clk,
-};
-
-static struct clk mbx_clk = {
-	.name = "mbx_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 1,
-	.bit = 21,
-	.calc = unity_clk_calc,
-	.parent = &csb_clk,
-};
-
-static struct clk mbx_3d_clk = {
-	.name = "mbx_3d_clk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 1,
-	.bit = 20,
-	.calc = generic_div_clk_calc,
-	.parent = &mbx_bus_clk,
-	.div_shift = 14,
-};
-
-static void psc_mclk_in_calc(struct clk *clk)
-{
-	clk->rate = devtree_getfreq("psc_mclk_in");
-	if (!clk->rate)
-		clk->rate = 25000000;
-}
-
-static struct clk psc_mclk_in = {
-	.name = "psc_mclk_in",
-	.calc = psc_mclk_in_calc,
-};
-
-static struct clk spdif_txclk = {
-	.name = "spdif_txclk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 1,
-	.bit = 23,
-};
-
-static struct clk spdif_rxclk = {
-	.name = "spdif_rxclk",
-	.flags = CLK_HAS_CTRL,
-	.reg = 1,
-	.bit = 23,
-};
-
-static void ac97_clk_calc(struct clk *clk)
-{
-	/* ac97 bit clock is always 24.567 MHz */
-	clk->rate = 24567000;
-}
-
-static struct clk ac97_clk = {
-	.name = "ac97_clk_in",
-	.calc = ac97_clk_calc,
-};
-
-static struct clk *rate_clks[] = {
-	&ref_clk,
-	&sys_clk,
-	&diu_clk,
-	&viu_clk,
-	&csb_clk,
-	&e300_clk,
-	&ips_clk,
-	&fec_clk,
-	&sata_clk,
-	&pata_clk,
-	&nfc_clk,
-	&lpc_clk,
-	&mbx_bus_clk,
-	&mbx_clk,
-	&mbx_3d_clk,
-	&axe_clk,
-	&usb1_clk,
-	&usb2_clk,
-	&i2c_clk,
-	&mscan_clk,
-	&sdhc_clk,
-	&pci_clk,
-	&psc_mclk_in,
-	&spdif_txclk,
-	&spdif_rxclk,
-	&ac97_clk,
-	NULL
-};
-
-static void rate_clk_init(struct clk *clk)
-{
-	if (clk->calc) {
-		clk->calc(clk);
-		clk->flags |= CLK_HAS_RATE;
-		clk_register(clk);
-	} else {
-		printk(KERN_WARNING
-		       "Could not initialize clk %s without a calc routine\n",
-		       clk->name);
-	}
-}
-
-static void rate_clks_init(void)
-{
-	struct clk **cpp, *clk;
-
-	cpp = rate_clks;
-	while ((clk = *cpp++))
-		rate_clk_init(clk);
-}
-
-/*
- * There are two clk enable registers with 32 enable bits each
- * psc clocks and device clocks are all stored in dev_clks
- */
-static struct clk dev_clks[2][32];
-
-/*
- * Given a psc number return the dev_clk
- * associated with it
- */
-static struct clk *psc_dev_clk(int pscnum)
-{
-	int reg, bit;
-	struct clk *clk;
-
-	reg = 0;
-	bit = 27 - pscnum;
-
-	clk = &dev_clks[reg][bit];
-	clk->reg = 0;
-	clk->bit = bit;
-	return clk;
-}
-
-/*
- * PSC clock rate calculation
- */
-static void psc_calc_rate(struct clk *clk, int pscnum, struct device_node *np)
-{
-	unsigned long mclk_src = sys_clk.rate;
-	unsigned long mclk_div;
-
-	/*
-	 * Can only change value of mclk divider
-	 * when the divider is disabled.
-	 *
-	 * Zero is not a valid divider so minimum
-	 * divider is 1
-	 *
-	 * disable/set divider/enable
-	 */
-	out_be32(&clockctl->pccr[pscnum], 0);
-	out_be32(&clockctl->pccr[pscnum], 0x00020000);
-	out_be32(&clockctl->pccr[pscnum], 0x00030000);
-
-	if (in_be32(&clockctl->pccr[pscnum]) & 0x80) {
-		clk->rate = spdif_rxclk.rate;
-		return;
-	}
-
-	switch ((in_be32(&clockctl->pccr[pscnum]) >> 14) & 0x3) {
-	case 0:
-		mclk_src = sys_clk.rate;
-		break;
-	case 1:
-		mclk_src = ref_clk.rate;
-		break;
-	case 2:
-		mclk_src = psc_mclk_in.rate;
-		break;
-	case 3:
-		mclk_src = spdif_txclk.rate;
-		break;
-	}
-
-	mclk_div = ((in_be32(&clockctl->pccr[pscnum]) >> 17) & 0x7fff) + 1;
-	clk->rate = mclk_src / mclk_div;
-}
-
-/*
- * Find all psc nodes in device tree and assign a clock
- * with name "psc%d_mclk" and dev pointing at the device
- * returned from of_find_device_by_node
- */
-static void psc_clks_init(void)
-{
-	struct device_node *np;
-	struct platform_device *ofdev;
-	u32 reg;
-	const char *psc_compat;
-
-	psc_compat = mpc512x_select_psc_compat();
-	if (!psc_compat)
-		return;
-
-	for_each_compatible_node(np, NULL, psc_compat) {
-		if (!of_property_read_u32(np, "reg", &reg)) {
-			int pscnum = (reg & 0xf00) >> 8;
-			struct clk *clk = psc_dev_clk(pscnum);
-
-			clk->flags = CLK_HAS_RATE | CLK_HAS_CTRL;
-			ofdev = of_find_device_by_node(np);
-			clk->dev = &ofdev->dev;
-			/*
-			 * AC97 is special rate clock does
-			 * not go through normal path
-			 */
-			if (of_device_is_compatible(np, "fsl,mpc5121-psc-ac97"))
-				clk->rate = ac97_clk.rate;
-			else
-				psc_calc_rate(clk, pscnum, np);
-			sprintf(clk->name, "psc%d_mclk", pscnum);
-			clk_register(clk);
-			clk_enable(clk);
-		}
-	}
-}
-
-static struct clk_interface mpc5121_clk_functions = {
-	.clk_get		= mpc5121_clk_get,
-	.clk_enable		= mpc5121_clk_enable,
-	.clk_disable		= mpc5121_clk_disable,
-	.clk_get_rate		= mpc5121_clk_get_rate,
-	.clk_put		= mpc5121_clk_put,
-	.clk_round_rate		= mpc5121_clk_round_rate,
-	.clk_set_rate		= mpc5121_clk_set_rate,
-	.clk_set_parent		= NULL,
-	.clk_get_parent		= NULL,
-};
-
-int __init mpc5121_clk_init(void)
-{
-	struct device_node *np;
-
-	np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock");
-	if (np) {
-		clockctl = of_iomap(np, 0);
-		of_node_put(np);
-	}
-
-	if (!clockctl) {
-		printk(KERN_ERR "Could not map clock control registers\n");
-		return 0;
-	}
-
-	rate_clks_init();
-	psc_clks_init();
-
-	/* leave clockctl mapped forever */
-	/*iounmap(clockctl); */
-	DEBUG_CLK_DUMP();
-	clocks_initialized++;
-	clk_functions = mpc5121_clk_functions;
-	return 0;
-}
diff --git a/arch/powerpc/platforms/52xx/Kconfig b/arch/powerpc/platforms/52xx/Kconfig
index af54174801f7..b625a2c6f4f2 100644
--- a/arch/powerpc/platforms/52xx/Kconfig
+++ b/arch/powerpc/platforms/52xx/Kconfig
@@ -1,7 +1,7 @@
 config PPC_MPC52xx
 	bool "52xx-based boards"
 	depends on 6xx
-	select PPC_CLOCK
+	select COMMON_CLK
 	select PPC_PCI_CHOICE
 
 config PPC_MPC5200_SIMPLE
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v6 09/17] serial: mpc512x: adjust for OF based clock lookup
From: Gerhard Sittig @ 2013-11-30 22:51 UTC (permalink / raw)
  To: linuxppc-dev, linux-arm-kernel, Anatolij Gustschin,
	Mike Turquette
  Cc: Detlev Zundel, Greg Kroah-Hartman, Gerhard Sittig, linux-serial,
	Scott Wood, Jiri Slaby
In-Reply-To: <1385851897-23475-1-git-send-email-gsi@denx.de>

after device tree based clock lookup became available, the peripheral
driver need no longer construct clock names which include the PSC index,
remove the "psc%d_mclk" template and unconditionally use 'mclk'

acquire and release the "ipg" clock item for register access as well

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: linux-serial@vger.kernel.org
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> # for v4
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
Greg, the difference since v4 of this patch is that v4 took the 'mclk'
and 'ipg' clock items in reverse order, and thus potentially obfuscated
the adjusted name for 'mclk' -- the updated version of the patch is
identical in content but cleaner diff-wise

---
 drivers/tty/serial/mpc52xx_uart.c |   40 ++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c
index ec06505e3ae6..6345f377a246 100644
--- a/drivers/tty/serial/mpc52xx_uart.c
+++ b/drivers/tty/serial/mpc52xx_uart.c
@@ -619,29 +619,55 @@ static irqreturn_t mpc512x_psc_handle_irq(struct uart_port *port)
 }
 
 static struct clk *psc_mclk_clk[MPC52xx_PSC_MAXNUM];
+static struct clk *psc_ipg_clk[MPC52xx_PSC_MAXNUM];
 
 /* called from within the .request_port() callback (allocation) */
 static int mpc512x_psc_alloc_clock(struct uart_port *port)
 {
 	int psc_num;
-	char clk_name[16];
 	struct clk *clk;
 	int err;
 
 	psc_num = (port->mapbase & 0xf00) >> 8;
-	snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num);
-	clk = devm_clk_get(port->dev, clk_name);
+
+	clk = devm_clk_get(port->dev, "mclk");
 	if (IS_ERR(clk)) {
 		dev_err(port->dev, "Failed to get MCLK!\n");
-		return PTR_ERR(clk);
+		err = PTR_ERR(clk);
+		goto out_err;
 	}
 	err = clk_prepare_enable(clk);
 	if (err) {
 		dev_err(port->dev, "Failed to enable MCLK!\n");
-		return err;
+		goto out_err;
 	}
 	psc_mclk_clk[psc_num] = clk;
+
+	clk = devm_clk_get(port->dev, "ipg");
+	if (IS_ERR(clk)) {
+		dev_err(port->dev, "Failed to get IPG clock!\n");
+		err = PTR_ERR(clk);
+		goto out_err;
+	}
+	err = clk_prepare_enable(clk);
+	if (err) {
+		dev_err(port->dev, "Failed to enable IPG clock!\n");
+		goto out_err;
+	}
+	psc_ipg_clk[psc_num] = clk;
+
 	return 0;
+
+out_err:
+	if (psc_mclk_clk[psc_num]) {
+		clk_disable_unprepare(psc_mclk_clk[psc_num]);
+		psc_mclk_clk[psc_num] = NULL;
+	}
+	if (psc_ipg_clk[psc_num]) {
+		clk_disable_unprepare(psc_ipg_clk[psc_num]);
+		psc_ipg_clk[psc_num] = NULL;
+	}
+	return err;
 }
 
 /* called from within the .release_port() callback (release) */
@@ -656,6 +682,10 @@ static void mpc512x_psc_relse_clock(struct uart_port *port)
 		clk_disable_unprepare(clk);
 		psc_mclk_clk[psc_num] = NULL;
 	}
+	if (psc_ipg_clk[psc_num]) {
+		clk_disable_unprepare(psc_ipg_clk[psc_num]);
+		psc_ipg_clk[psc_num] = NULL;
+	}
 }
 
 /* implementation of the .clock() callback (enable/disable) */
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v6 06/17] dts: mpc512x: add clock specs for client lookups
From: Gerhard Sittig @ 2013-11-30 22:51 UTC (permalink / raw)
  To: linuxppc-dev, linux-arm-kernel, Anatolij Gustschin,
	Mike Turquette
  Cc: Mark Rutland, devicetree, Detlev Zundel, Pawel Moll,
	Stephen Warren, Gerhard Sittig, Rob Herring, Scott Wood,
	Ian Campbell
In-Reply-To: <1385851897-23475-1-git-send-email-gsi@denx.de>

this addresses the client side of device tree based clock lookups

add clock specifiers to the mbx, nfc, mscan, sdhc, i2c, axe, diu, viu,
mdio, fec, usb, pata, psc, psc fifo, and pci nodes in the shared
mpc5121.dtsi include

Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: devicetree@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Reviewed-by: Mike Turquette <mturquette@linaro.org>	# for v3: w/o bdlc, PSC ipg
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
 arch/powerpc/boot/dts/mpc5121.dtsi |   95 ++++++++++++++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi b/arch/powerpc/boot/dts/mpc5121.dtsi
index 9bfcb7558197..d8c6f967785f 100644
--- a/arch/powerpc/boot/dts/mpc5121.dtsi
+++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -51,6 +51,10 @@
 		compatible = "fsl,mpc5121-mbx";
 		reg = <0x20000000 0x4000>;
 		interrupts = <66 0x8>;
+		clocks = <&clks MPC512x_CLK_MBX_BUS>,
+			 <&clks MPC512x_CLK_MBX_3D>,
+			 <&clks MPC512x_CLK_MBX>;
+		clock-names = "mbx-bus", "mbx-3d", "mbx";
 	};
 
 	sram@30000000 {
@@ -64,6 +68,8 @@
 		interrupts = <6 8>;
 		#address-cells = <1>;
 		#size-cells = <1>;
+		clocks = <&clks MPC512x_CLK_NFC>;
+		clock-names = "ipg";
 	};
 
 	localbus@80000020 {
@@ -156,12 +162,24 @@
 			compatible = "fsl,mpc5121-mscan";
 			reg = <0x1300 0x80>;
 			interrupts = <12 0x8>;
+			clocks = <&clks MPC512x_CLK_BDLC>,
+				 <&clks MPC512x_CLK_IPS>,
+				 <&clks MPC512x_CLK_SYS>,
+				 <&clks MPC512x_CLK_REF>,
+				 <&clks MPC512x_CLK_MSCAN0_MCLK>;
+			clock-names = "ipg", "ips", "sys", "ref", "mclk";
 		};
 
 		can@1380 {
 			compatible = "fsl,mpc5121-mscan";
 			reg = <0x1380 0x80>;
 			interrupts = <13 0x8>;
+			clocks = <&clks MPC512x_CLK_BDLC>,
+				 <&clks MPC512x_CLK_IPS>,
+				 <&clks MPC512x_CLK_SYS>,
+				 <&clks MPC512x_CLK_REF>,
+				 <&clks MPC512x_CLK_MSCAN1_MCLK>;
+			clock-names = "ipg", "ips", "sys", "ref", "mclk";
 		};
 
 		sdhc@1500 {
@@ -170,6 +188,9 @@
 			interrupts = <8 0x8>;
 			dmas = <&dma0 30>;
 			dma-names = "rx-tx";
+			clocks = <&clks MPC512x_CLK_IPS>,
+				 <&clks MPC512x_CLK_SDHC>;
+			clock-names = "ipg", "per";
 		};
 
 		i2c@1700 {
@@ -178,6 +199,8 @@
 			compatible = "fsl,mpc5121-i2c", "fsl-i2c";
 			reg = <0x1700 0x20>;
 			interrupts = <9 0x8>;
+			clocks = <&clks MPC512x_CLK_I2C>;
+			clock-names = "ipg";
 		};
 
 		i2c@1720 {
@@ -186,6 +209,8 @@
 			compatible = "fsl,mpc5121-i2c", "fsl-i2c";
 			reg = <0x1720 0x20>;
 			interrupts = <10 0x8>;
+			clocks = <&clks MPC512x_CLK_I2C>;
+			clock-names = "ipg";
 		};
 
 		i2c@1740 {
@@ -194,6 +219,8 @@
 			compatible = "fsl,mpc5121-i2c", "fsl-i2c";
 			reg = <0x1740 0x20>;
 			interrupts = <11 0x8>;
+			clocks = <&clks MPC512x_CLK_I2C>;
+			clock-names = "ipg";
 		};
 
 		i2ccontrol@1760 {
@@ -205,30 +232,48 @@
 			compatible = "fsl,mpc5121-axe";
 			reg = <0x2000 0x100>;
 			interrupts = <42 0x8>;
+			clocks = <&clks MPC512x_CLK_AXE>;
+			clock-names = "ipg";
 		};
 
 		display@2100 {
 			compatible = "fsl,mpc5121-diu";
 			reg = <0x2100 0x100>;
 			interrupts = <64 0x8>;
+			clocks = <&clks MPC512x_CLK_DIU>;
+			clock-names = "ipg";
 		};
 
 		can@2300 {
 			compatible = "fsl,mpc5121-mscan";
 			reg = <0x2300 0x80>;
 			interrupts = <90 0x8>;
+			clocks = <&clks MPC512x_CLK_BDLC>,
+				 <&clks MPC512x_CLK_IPS>,
+				 <&clks MPC512x_CLK_SYS>,
+				 <&clks MPC512x_CLK_REF>,
+				 <&clks MPC512x_CLK_MSCAN2_MCLK>;
+			clock-names = "ipg", "ips", "sys", "ref", "mclk";
 		};
 
 		can@2380 {
 			compatible = "fsl,mpc5121-mscan";
 			reg = <0x2380 0x80>;
 			interrupts = <91 0x8>;
+			clocks = <&clks MPC512x_CLK_BDLC>,
+				 <&clks MPC512x_CLK_IPS>,
+				 <&clks MPC512x_CLK_SYS>,
+				 <&clks MPC512x_CLK_REF>,
+				 <&clks MPC512x_CLK_MSCAN3_MCLK>;
+			clock-names = "ipg", "ips", "sys", "ref", "mclk";
 		};
 
 		viu@2400 {
 			compatible = "fsl,mpc5121-viu";
 			reg = <0x2400 0x400>;
 			interrupts = <67 0x8>;
+			clocks = <&clks MPC512x_CLK_VIU>;
+			clock-names = "ipg";
 		};
 
 		mdio@2800 {
@@ -236,6 +281,8 @@
 			reg = <0x2800 0x800>;
 			#address-cells = <1>;
 			#size-cells = <0>;
+			clocks = <&clks MPC512x_CLK_FEC>;
+			clock-names = "per";
 		};
 
 		eth0: ethernet@2800 {
@@ -244,6 +291,8 @@
 			reg = <0x2800 0x800>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <4 0x8>;
+			clocks = <&clks MPC512x_CLK_FEC>;
+			clock-names = "per";
 		};
 
 		/* USB1 using external ULPI PHY */
@@ -255,6 +304,8 @@
 			interrupts = <43 0x8>;
 			dr_mode = "otg";
 			phy_type = "ulpi";
+			clocks = <&clks MPC512x_CLK_USB1>;
+			clock-names = "ipg";
 		};
 
 		/* USB0 using internal UTMI PHY */
@@ -266,6 +317,8 @@
 			interrupts = <44 0x8>;
 			dr_mode = "otg";
 			phy_type = "utmi_wide";
+			clocks = <&clks MPC512x_CLK_USB2>;
+			clock-names = "ipg";
 		};
 
 		/* IO control */
@@ -284,6 +337,8 @@
 			compatible = "fsl,mpc5121-pata";
 			reg = <0x10200 0x100>;
 			interrupts = <5 0x8>;
+			clocks = <&clks MPC512x_CLK_PATA>;
+			clock-names = "ipg";
 		};
 
 		/* 512x PSCs are not 52xx PSC compatible */
@@ -295,6 +350,9 @@
 			interrupts = <40 0x8>;
 			fsl,rx-fifo-size = <16>;
 			fsl,tx-fifo-size = <16>;
+			clocks = <&clks MPC512x_CLK_PSC0>,
+				 <&clks MPC512x_CLK_PSC0_MCLK>;
+			clock-names = "ipg", "mclk";
 		};
 
 		/* PSC1 */
@@ -304,6 +362,9 @@
 			interrupts = <40 0x8>;
 			fsl,rx-fifo-size = <16>;
 			fsl,tx-fifo-size = <16>;
+			clocks = <&clks MPC512x_CLK_PSC1>,
+				 <&clks MPC512x_CLK_PSC1_MCLK>;
+			clock-names = "ipg", "mclk";
 		};
 
 		/* PSC2 */
@@ -313,6 +374,9 @@
 			interrupts = <40 0x8>;
 			fsl,rx-fifo-size = <16>;
 			fsl,tx-fifo-size = <16>;
+			clocks = <&clks MPC512x_CLK_PSC2>,
+				 <&clks MPC512x_CLK_PSC2_MCLK>;
+			clock-names = "ipg", "mclk";
 		};
 
 		/* PSC3 */
@@ -322,6 +386,9 @@
 			interrupts = <40 0x8>;
 			fsl,rx-fifo-size = <16>;
 			fsl,tx-fifo-size = <16>;
+			clocks = <&clks MPC512x_CLK_PSC3>,
+				 <&clks MPC512x_CLK_PSC3_MCLK>;
+			clock-names = "ipg", "mclk";
 		};
 
 		/* PSC4 */
@@ -331,6 +398,9 @@
 			interrupts = <40 0x8>;
 			fsl,rx-fifo-size = <16>;
 			fsl,tx-fifo-size = <16>;
+			clocks = <&clks MPC512x_CLK_PSC4>,
+				 <&clks MPC512x_CLK_PSC4_MCLK>;
+			clock-names = "ipg", "mclk";
 		};
 
 		/* PSC5 */
@@ -340,6 +410,9 @@
 			interrupts = <40 0x8>;
 			fsl,rx-fifo-size = <16>;
 			fsl,tx-fifo-size = <16>;
+			clocks = <&clks MPC512x_CLK_PSC5>,
+				 <&clks MPC512x_CLK_PSC5_MCLK>;
+			clock-names = "ipg", "mclk";
 		};
 
 		/* PSC6 */
@@ -349,6 +422,9 @@
 			interrupts = <40 0x8>;
 			fsl,rx-fifo-size = <16>;
 			fsl,tx-fifo-size = <16>;
+			clocks = <&clks MPC512x_CLK_PSC6>,
+				 <&clks MPC512x_CLK_PSC6_MCLK>;
+			clock-names = "ipg", "mclk";
 		};
 
 		/* PSC7 */
@@ -358,6 +434,9 @@
 			interrupts = <40 0x8>;
 			fsl,rx-fifo-size = <16>;
 			fsl,tx-fifo-size = <16>;
+			clocks = <&clks MPC512x_CLK_PSC7>,
+				 <&clks MPC512x_CLK_PSC7_MCLK>;
+			clock-names = "ipg", "mclk";
 		};
 
 		/* PSC8 */
@@ -367,6 +446,9 @@
 			interrupts = <40 0x8>;
 			fsl,rx-fifo-size = <16>;
 			fsl,tx-fifo-size = <16>;
+			clocks = <&clks MPC512x_CLK_PSC8>,
+				 <&clks MPC512x_CLK_PSC8_MCLK>;
+			clock-names = "ipg", "mclk";
 		};
 
 		/* PSC9 */
@@ -376,6 +458,9 @@
 			interrupts = <40 0x8>;
 			fsl,rx-fifo-size = <16>;
 			fsl,tx-fifo-size = <16>;
+			clocks = <&clks MPC512x_CLK_PSC9>,
+				 <&clks MPC512x_CLK_PSC9_MCLK>;
+			clock-names = "ipg", "mclk";
 		};
 
 		/* PSC10 */
@@ -385,6 +470,9 @@
 			interrupts = <40 0x8>;
 			fsl,rx-fifo-size = <16>;
 			fsl,tx-fifo-size = <16>;
+			clocks = <&clks MPC512x_CLK_PSC10>,
+				 <&clks MPC512x_CLK_PSC10_MCLK>;
+			clock-names = "ipg", "mclk";
 		};
 
 		/* PSC11 */
@@ -394,12 +482,17 @@
 			interrupts = <40 0x8>;
 			fsl,rx-fifo-size = <16>;
 			fsl,tx-fifo-size = <16>;
+			clocks = <&clks MPC512x_CLK_PSC11>,
+				 <&clks MPC512x_CLK_PSC11_MCLK>;
+			clock-names = "ipg", "mclk";
 		};
 
 		pscfifo@11f00 {
 			compatible = "fsl,mpc5121-psc-fifo";
 			reg = <0x11f00 0x100>;
 			interrupts = <40 0x8>;
+			clocks = <&clks MPC512x_CLK_PSC_FIFO>;
+			clock-names = "ipg";
 		};
 
 		dma0: dma@14000 {
@@ -417,6 +510,8 @@
 		#address-cells = <3>;
 		#size-cells = <2>;
 		#interrupt-cells = <1>;
+		clocks = <&clks MPC512x_CLK_PCI>;
+		clock-names = "ipg";
 
 		reg = <0x80008500 0x100	/* internal registers */
 		       0x80008300 0x8>;	/* config space access registers */
-- 
1.7.10.4

^ 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