LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 04/13] powerpc: Update hugetlb huge_pte_alloc and tablewalk code for FSL BOOKE
From: Benjamin Herrenschmidt @ 2011-11-29  5:25 UTC (permalink / raw)
  To: Becky Bruce; +Cc: linuxppc-dev, david
In-Reply-To: <1318279870278-git-send-email-beckyb@kernel.crashing.org>

On Mon, 2011-10-10 at 15:50 -0500, Becky Bruce wrote:
> From: Becky Bruce <beckyb@kernel.crashing.org>
> 
> This updates the hugetlb page table code to handle 64-bit FSL_BOOKE.
> The previous 32-bit work counted on the inner levels of the page table
> collapsing.

Seriously, my brain hurts !!!

So I've tried to understand that code and so far, what I came up with is
this, please reply and let me know if I'm full of crack or what ...

 - David's code has entire levels "branching off" into hugepd's which
are hugetlb specific page dirs. That requires address space constrainst.

 - The hack you do with HUGEPD_PGD_SHIFT defined to PGDIR_SHIFT and
HUGEPD_PUD_SHIFT to PUD_SHIFT consists of collasping that back into the
normal levels.

 - I really don't understand what you are doing in __hugepte_alloc(). It
seems to me that you are trying to make things still point to some kind
of separate hugepd dir with the hugeptes in it and have the page tables
point to that but I don't quite get it.

 - Couldn't we just instead ditch the whole hugepd concept alltogether
and simply have the huge ptes in the page table at the right level,
using possibly multiple consecutive of them for a single page when
needed ?

Example: 4K base page size. PMD maps 2M. a 16M page could be
representing by having 8 consecutive hugeptes pointing to the same huge
page in the PMD directory.

I believe we always "know" when accessing a PTE whether it's going to be
huge or not and if it's huge, the page size. IE. All the functions we
care about either get the vma (which gets you everything you need) or
the size (huge_pte_alloc).

This should be much simpler than what we have today.

That way, we have a completely generic accross-the-board way to store
huge pte's in our page tables, which is totally disconnected from the
slices. The later remains a purely server-only thing which only affects
the SLB code and get_unmapped_area().

That means that we'll have to find another option for PowerEN giant
indirects but that's a non issue at the moment. I think we can keep the
complexity local to the PowerEN code by doing shadows there if we need
to.

What do you think ?

Ben.

^ permalink raw reply

* Re: [PATCH] powerpc/40x: Add APM8018X SOC support
From: Tanmay Inamdar @ 2011-11-29  6:11 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, linux-kernel, Arnd Bergmann
In-Reply-To: <1322435957.23348.23.camel@pasglop>

On Mon, Nov 28, 2011 at 4:49 AM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Fri, 2011-11-25 at 17:49 +0530, Tanmay Inamdar wrote:
>
>>
>> =A0 =A0 =A0 =A0 >
>> =A0 =A0 =A0 =A0 > +#if defined(CONFIG_APM8018X)
>> =A0 =A0 =A0 =A0 > +/* CPR */
>> =A0 =A0 =A0 =A0 > +#define DCRN_CPR0_CONFIG_ADDR =A0 =A0 =A0 =A00xa
>> =A0 =A0 =A0 =A0 > +#define DCRN_CPR1_CONFIG_DATA =A0 =A0 =A0 =A00xb
>> =A0 =A0 =A0 =A0 > +/* AHB */
>> =A0 =A0 =A0 =A0 > +#define DCRN_SDR1_CONFIG_ADDR =A0 =A0 =A0 =A00xc
>> =A0 =A0 =A0 =A0 > +#define DCRN_SDR1_CONFIG_DATA =A0 =A0 =A0 =A00xd
>> =A0 =A0 =A0 =A0 > +#else
>> =A0 =A0 =A0 =A0 > =A0/* CPRs (440GX and 440SP/440SPe) */
>> =A0 =A0 =A0 =A0 > =A0#define DCRN_CPR0_CONFIG_ADDR =A0 =A0 =A0 =A00xc
>> =A0 =A0 =A0 =A0 > =A0#define DCRN_CPR0_CONFIG_DATA =A0 =A0 =A0 =A00xd
>> =A0 =A0 =A0 =A0 > +#endif /* CONFIG_APM8018X */
>>
>>
>> =A0 =A0 =A0 =A0 same comment as above.
>>
>> Some existing drivers use these macros. If I change the names, I will
>> have to update the
>> driver code.
>
> Right, the best approach is to create a small wrapper that provides cpr
> and sdr accesses using helpers. That way you can:
>
> =A0- Properly lock since it's all indirect
>
> =A0- Obtain the right DCRs at boot time, stick them in variables
> =A0 and use them at runtime, avoiding the hard coded constants completely
>
> =A0- Make the code generally look much better
>
> Ie. Provide something like read_sdr1() and write_sdr1() accessors and
> change the drivers to use them.

Ok.
There are 'mfdcri' and 'mtdcri' macros in
"arch/powerpc/include/asm/dcr-native.h" file.
They internally use '__mfdcri' and '__mtdcri' functions which can be
used for the same
purpose as mentioned above.
Instead of putting this change in current patch, I will make separate
patch for this purpose.

>
>> =A0 =A0 =A0 =A0 > diff --git a/arch/powerpc/kernel/cputable.c
>> =A0 =A0 =A0 =A0 b/arch/powerpc/kernel/cputable.c
>> =A0 =A0 =A0 =A0 > index edae5bb..e5c51a6 100644
>> =A0 =A0 =A0 =A0 > --- a/arch/powerpc/kernel/cputable.c
>> =A0 =A0 =A0 =A0 > +++ b/arch/powerpc/kernel/cputable.c
>> =A0 =A0 =A0 =A0 > @@ -1505,6 +1505,58 @@ static struct cpu_spec __initda=
ta
>> =A0 =A0 =A0 =A0 cpu_specs[] =3D {
>> =A0 =A0 =A0 =A0 > =A0 =A0 =A0 =A0 =A0 =A0 =A0 .machine_check =A0 =A0 =A0=
 =A0 =A0=3D machine_check_4xx,
>> =A0 =A0 =A0 =A0 > =A0 =A0 =A0 =A0 =A0 =A0 =A0 .platform =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 =3D "ppc405",
>> =A0 =A0 =A0 =A0 > =A0 =A0 =A0 },
>> =A0 =A0 =A0 =A0 > + =A0 =A0 { =A0 =A0 =A0 /* APM80186-SK */
>> =A0 =A0 =A0 =A0 > + =A0 =A0 =A0 =A0 =A0 =A0 .pvr_mask =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 =3D 0xffffffff,
>> =A0 =A0 =A0 =A0 > + =A0 =A0 =A0 =A0 =A0 =A0 .pvr_value =A0 =A0 =A0 =A0 =
=A0 =A0 =A0=3D 0x7ff11432,
>>
>>
>> =A0 =A0 =A0 =A0 If you mask out the lower bits, you only need a single e=
ntry
>> =A0 =A0 =A0 =A0 instead of
>> =A0 =A0 =A0 =A0 four identical ones.
>>
>> You are right. But each PVR represent different version of SOC. If I
>> create single entry, then I will have to give generic cpu_name which I
>> don't want.
>
> Note that you should really tell you designers to move away from using
> the PVR to identify the SoC's. This is BAD and isn't sustainable long
> run. Stick to representing the core itself in the PVR and provide a
> different mechanism to identify the SoC (different SPR would do, or even
> a DCR).
>
>> =A0 =A0 =A0 =A0 > --- a/arch/powerpc/kernel/udbg_16550.c
>> =A0 =A0 =A0 =A0 > +++ b/arch/powerpc/kernel/udbg_16550.c
>> =A0 =A0 =A0 =A0 > @@ -18,6 +18,19 @@ extern void real_writeb(u8 data, vo=
latile
>> =A0 =A0 =A0 =A0 u8 __iomem *addr);
>> =A0 =A0 =A0 =A0 > =A0extern u8 real_205_readb(volatile u8 __iomem =A0*ad=
dr);
>> =A0 =A0 =A0 =A0 > =A0extern void real_205_writeb(u8 data, volatile u8 __=
iomem
>> =A0 =A0 =A0 =A0 *addr);
>> =A0 =A0 =A0 =A0 >
>> =A0 =A0 =A0 =A0 > +#ifdef CONFIG_UART_16550_WORD_ADDRESSABLE
>> =A0 =A0 =A0 =A0 > +struct NS16550 {
>> =A0 =A0 =A0 =A0 > + =A0 =A0 /* this struct must be packed */
>> =A0 =A0 =A0 =A0 > + =A0 =A0 unsigned char rbr; =A0/* 0 */ u8 s0[3];
>> =A0 =A0 =A0 =A0 > + =A0 =A0 unsigned char ier; =A0/* 1 */ u8 s1[3];
>> =A0 =A0 =A0 =A0 > + =A0 =A0 unsigned char fcr; =A0/* 2 */ u8 s2[3];
>> =A0 =A0 =A0 =A0 > + =A0 =A0 unsigned char lcr; =A0/* 3 */ u8 s3[3];
>> =A0 =A0 =A0 =A0 > + =A0 =A0 unsigned char mcr; =A0/* 4 */ u8 s4[3];
>> =A0 =A0 =A0 =A0 > + =A0 =A0 unsigned char lsr; =A0/* 5 */ u8 s5[3];
>> =A0 =A0 =A0 =A0 > + =A0 =A0 unsigned char msr; =A0/* 6 */ u8 s6[3];
>> =A0 =A0 =A0 =A0 > + =A0 =A0 unsigned char scr; =A0/* 7 */ u8 s7[3];
>> =A0 =A0 =A0 =A0 > +};
>> =A0 =A0 =A0 =A0 > +#else
>> =A0 =A0 =A0 =A0 > =A0struct NS16550 {
>> =A0 =A0 =A0 =A0 > =A0 =A0 =A0 /* this struct must be packed */
>> =A0 =A0 =A0 =A0 > =A0 =A0 =A0 unsigned char rbr; =A0/* 0 */
>> =A0 =A0 =A0 =A0 > @@ -29,6 +42,7 @@ struct NS16550 {
>> =A0 =A0 =A0 =A0 > =A0 =A0 =A0 unsigned char msr; =A0/* 6 */
>> =A0 =A0 =A0 =A0 > =A0 =A0 =A0 unsigned char scr; =A0/* 7 */
>> =A0 =A0 =A0 =A0 > =A0};
>> =A0 =A0 =A0 =A0 > +#endif /* CONFIG_UART_16550_WORD_ADDRESSABLE */
>> =A0 =A0 =A0 =A0 >
>>
>>
>> =A0 =A0 =A0 =A0 Same things as with the register definitions. Please mak=
e this
>> =A0 =A0 =A0 =A0 run-time selectable to allow build-time configurations t=
hat
>> =A0 =A0 =A0 =A0 support both layouts.
>>
>> Yes. I will try to find better solution.
>
> Cheers,
> Ben.
>
>
>
Regards,
Tanmay
CONFIDENTIALITY NOTICE: This e-mail message, including any attachments, =

is for the sole use of the intended recipient(s) and contains information=
=A0
that is confidential and proprietary to AppliedMicro Corporation or its s=
ubsidiaries. =

It is to be used solely for the purpose of furthering the parties' busine=
ss relationship. =

All unauthorized review, use, disclosure or distribution is prohibited. =

If you are not the intended recipient, please contact the sender by reply=
 e-mail =

and destroy all copies of the original message.
=0D

^ permalink raw reply

* Re: [RFC PATCH v2 1/4] cpuidle: (powerpc) Add cpu_idle_wait() to allow switching of idle routines
From: Deepthi Dharwar @ 2011-11-29  6:42 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, linux-pm, linux-kernel, linux-pm
In-Reply-To: <1322512522.23348.43.camel@pasglop>

On 11/29/2011 02:05 AM, Benjamin Herrenschmidt wrote:

> On Mon, 2011-11-28 at 16:32 +0530, Deepthi Dharwar wrote:
> 
>>> Additionally, I'm a bit worried (but maybe we already discussed that a
>>> while back, I don't know) but cpu_idle_wait() has "wait" in the name,
>>> which makes me think it might need to actually -wait- for all cpus to
>>> have come out of the function.
>>
>> cpu_idle_wait is used to ensure that all the CPUs discard old idle
>> handler and update to new one.  Required while changing idle
>> handler on SMP systems.
>>
>>> Now your implementation doesn't provide that guarantee. It might be
>>> fine, I don't know, but if it is, you'd better document it well in the
>>> comments surrounding the code, because as it is, all you do is shoot an
>>> interrupt which will cause the target CPU to eventually come out of idle
>>> some time in the future.
>>
>>
>> I was hoping that sending an explicit reschedule to the cpus would
>> do the trick but sure we can add some documentation around the code.
> 
> Well, the question is what guarantee do you expect. Sending a reschedule
> IPI will take the other CPUs out of the actual sleep mode, but it will
> be some time from there back to getting out of the handler function
> (first back out of hypervisor etc...).
> 
> The code as you implemented it doesn't wait for that to happen. It might
> be fine ... or not. I don't know what semantics you are after precisely.
> 
> Cheers,
> Ben.
> 
> 


Yes, this could be problematic as there is small window for the
race condition to occur . Otherwise we need to manually schedule
it by running a kernel thread but this would definitely have a
overhead and would be an overkill.

Regards,
Deepthi

^ permalink raw reply

* Re: [RFC PATCH v2 4/4] cpuidle: (POWER) Handle power_save=off
From: Deepthi Dharwar @ 2011-11-29  6:44 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, linux-pm, linux-kernel, linux-pm
In-Reply-To: <1322512771.23348.45.camel@pasglop>

On 11/29/2011 02:09 AM, Benjamin Herrenschmidt wrote:

> On Mon, 2011-11-28 at 16:33 +0530, Deepthi Dharwar wrote:
> 
>> On an LPAR if cpuidle is disabled, ppc_md.power_save is still set to
>> cpuidle_idle_call by default here. This would result in calling of
>> cpuidle_idle_call repeatedly, only for the call to return -ENODEV. The
>> default idle is never executed.
>> This would be a major design flaw. No fallback idle routine.
>>
>> We propose to fix this by checking the return value of
>> ppc_md.power_save() call from void to int.
>> Right now return value is void, but if we change this to int, this
>> would solve two problems. One being removing the cast to a function
>> pointer in the prev patch and this design flaw stated above.
>>
>> So by checking the return value of ppc_md.power_save(), we can invoke
>> the default idle on failure. But my only concern is about the effects of
>> changing the ppc_md.power_save() to return int on other powerpc
>> architectures. Would it be a good idea to change the return type to int
>> which would help us flag an error and fallback to default idle?
> 
> I would have preferred an approach where the cpuidle module sets
> ppc_md.power_save when loaded and restores it when unloaded ... but that
> would have to go into the cpuidle core as a powerpc specific tweak and
> might not be generally well received.
> 
> So go for it, add the return value, but you'll have to update all the
> idle functions (grep for power_save in arch/powerpc to find them).
> 


Thanks Ben. Yes, I will update all the idle functions under powerpc.
I will re-work these patches with the discussed changes.

Regards,
Deepthi

^ permalink raw reply

* [PATCH v2] powerpc/40x: Add APM8018X SOC support
From: Tanmay Inamdar @ 2011-11-29  7:01 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev, linux-kernel, Tanmay Inamdar

The AppliedMicro APM8018X embedded processor targets embedded applications that
require low power and a small footprint. It features a PowerPC 405 processor
core built in a 65nm low-power CMOS process with a five-stage pipeline executing
up to one instruction per cycle. The family has 128-kbytes of on-chip memory,
a 128-bit local bus and on-chip DDR2 SDRAM controller with 16-bit interface.

Features:
*CPU speed (frequency): up to 600 MHz
*Five-stage pipeline, executes up to one instruction per cycle
*16 KB-I/16 KB-D L1 caches, two-way set-associative
*128 KB on-chip memory
*128-bit processor local bus (PLB)
*Separate 128-bit read and 128-bit write data bus
*Up to 6.4 GBps of peak on-chip bandwidth at 200 MHz
*On-chip DDR2 SDRAM controller with 16-bit interface
*Support for one rank of DDR2 SDRAM up to 512 MB
*One Gen 1 single-lane PCI Express interface
*One Gen 1 single lane miniPCIe interface
*Configurable as root or endpoint
*One SATA controller operating at up to 3.0 Gbps with integrated SerDes
*Two Ethernet 10/100/1000 Mbps, full-duplex MACs (RGMII/TMII/MII)
*TCP/IP acceleration hardware, QoS, and jumbo frame support
*IEEE 1588 V1 and V2 support
*On-chip IPsec acceleration with header/trailer processing
*Supports DES, 3DES, and AES encryption
*Operates at 1.5/12/480 Mbps bus speeds

version 2:
	1. compressed defconfig.
	2. cleaned dts.
	3. cputable with single cpu entry instead of 4 similar entries.
	4. removed uart specific changes.

Signed-off-by: Tanmay Inamdar <tinamdar@apm.com>
---
 arch/powerpc/boot/dts/klondike.dts          |  227 +++++++++++++++++++++++++++
 arch/powerpc/configs/40x/klondike_defconfig |   55 +++++++
 arch/powerpc/kernel/cputable.c              |   13 ++
 arch/powerpc/platforms/40x/Kconfig          |   11 ++
 arch/powerpc/platforms/40x/ppc40x_simple.c  |    1 +
 5 files changed, 307 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/boot/dts/klondike.dts
 create mode 100644 arch/powerpc/configs/40x/klondike_defconfig

diff --git a/arch/powerpc/boot/dts/klondike.dts b/arch/powerpc/boot/dts/klondike.dts
new file mode 100644
index 0000000..8c94290
--- /dev/null
+++ b/arch/powerpc/boot/dts/klondike.dts
@@ -0,0 +1,227 @@
+/*
+ * Device Tree for Klondike (APM8018X) board.
+ *
+ * Copyright (c) 2010, Applied Micro Circuits Corporation
+ * Author: Tanmay Inamdar <tinamdar@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	model = "apm,klondike";
+	compatible = "apm,klondike";
+	dcr-parent = <&{/cpus/cpu@0}>;
+
+	aliases {
+		ethernet0 = &EMAC0;
+		ethernet1 = &EMAC1;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			model = "PowerPC,apm8018x";
+			reg = <0x00000000>;
+			clock-frequency = <300000000>; /* Filled in by U-Boot */
+			timebase-frequency = <300000000>; /* Filled in by U-Boot */
+			i-cache-line-size = <32>;
+			d-cache-line-size = <32>;
+			i-cache-size = <16384>; /* 16 kB */
+			d-cache-size = <16384>; /* 16 kB */
+			dcr-controller;
+			dcr-access-method = "native";
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x20000000>; /* Filled in by U-Boot */
+	};
+
+	UIC0: interrupt-controller {
+		compatible = "ibm,uic";
+		interrupt-controller;
+		cell-index = <0>;
+		dcr-reg = <0x0c0 0x010>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+	};
+
+	UIC1: interrupt-controller1 {
+		compatible = "ibm,uic";
+		interrupt-controller;
+		cell-index = <1>;
+		dcr-reg = <0x0d0 0x010>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+		interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
+		interrupt-parent = <&UIC0>;
+	};
+
+	UIC2: interrupt-controller2 {
+		compatible = "ibm,uic";
+		interrupt-controller;
+		cell-index = <2>;
+		dcr-reg = <0x0e0 0x010>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+		interrupts = <0x0a 0x4 0x0b 0x4>; /* cascade */
+		interrupt-parent = <&UIC0>;
+	};
+
+	UIC3: interrupt-controller3 {
+		compatible = "ibm,uic";
+		interrupt-controller;
+		cell-index = <3>;
+		dcr-reg = <0x0f0 0x010>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+		interrupts = <0x10 0x4 0x11 0x4>; /* cascade */
+		interrupt-parent = <&UIC0>;
+	};
+
+	plb {
+		compatible = "ibm,plb4";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		clock-frequency = <0>; /* Filled in by U-Boot */
+
+		SDRAM0: memory-controller {
+			compatible = "ibm,sdram-apm8018x";
+			dcr-reg = <0x010 0x002>;
+		};
+
+		MAL0: mcmal {
+			compatible = "ibm,mcmal2";
+			dcr-reg = <0x180 0x062>;
+			num-tx-chans = <2>;
+			num-rx-chans = <16>;
+			#address-cells = <0>;
+			#size-cells = <0>;
+			interrupt-parent = <&UIC1>;
+			interrupts = </*TXEOB*/   0x6 0x4
+					/*RXEOB*/ 0x7 0x4
+					/*SERR*/  0x1 0x4
+					/*TXDE*/  0x2 0x4
+					/*RXDE*/  0x3 0x4>;
+		};
+
+		POB0: opb {
+			compatible = "ibm,opb";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x20000000 0x20000000 0x30000000
+				  0x50000000 0x50000000 0x10000000
+				  0x60000000 0x60000000 0x10000000
+				  0xFE000000 0xFE000000 0x00010000>;
+			dcr-reg = <0x100 0x020>;
+			clock-frequency = <300000000>; /* Filled in by U-Boot */
+
+			RGMII0: emac-rgmii@400a2000 {
+				compatible = "ibm,rgmii";
+				reg = <0x400a2000 0x00000010>;
+				has-mdio;
+			};
+
+			TAH0: emac-tah@400a3000 {
+				compatible = "ibm,tah";
+				reg = <0x400a3000 0x100>;
+			};
+
+			TAH1: emac-tah@400a4000 {
+				compatible = "ibm,tah";
+				reg = <0x400a4000 0x100>;
+			};
+
+			EMAC0: ethernet@400a0000 {
+				compatible = "ibm,emac4", "ibm-emac4sync";
+				interrupt-parent = <&EMAC0>;
+				interrupts = <0x0>;
+				#interrupt-cells = <1>;
+				#address-cells = <0>;
+				#size-cells = <0>;
+				interrupt-map = </*Status*/ 0x0 &UIC0 0x13 0x4>;
+				reg = <0x400a0000 0x00000100>;
+				local-mac-address = [000000000000]; /* Filled in by U-Boot */
+				mal-device = <&MAL0>;
+				mal-tx-channel = <0x0>;
+				mal-rx-channel = <0x0>;
+				cell-index = <0>;
+				max-frame-size = <9000>;
+				rx-fifo-size = <4096>;
+				tx-fifo-size = <2048>;
+				phy-mode = "rgmii";
+				phy-address = <0x2>;
+				turbo = "no";
+				phy-map = <0x00000000>;
+				rgmii-device = <&RGMII0>;
+				rgmii-channel = <0>;
+				tah-device = <&TAH0>;
+				tah-channel = <0>;
+				has-inverted-stacr-oc;
+				has-new-stacr-staopc;
+			};
+
+			EMAC1: ethernet@400a1000 {
+				compatible = "ibm,emac4", "ibm-emac4sync";
+				status = "disabled";
+				interrupt-parent = <&EMAC1>;
+				interrupts = <0x0>;
+				#interrupt-cells = <1>;
+				#address-cells = <0>;
+				#size-cells = <0>;
+				interrupt-map = </*Status*/ 0x0 &UIC0 0x14 0x4>;
+				reg = <0x400a1000 0x00000100>;
+				local-mac-address = [000000000000]; /* Filled in by U-Boot */
+				mal-device = <&MAL0>;
+				mal-tx-channel = <1>;
+				mal-rx-channel = <8>;
+				cell-index = <1>;
+				max-frame-size = <9000>;
+				rx-fifo-size = <4096>;
+				tx-fifo-size = <2048>;
+				phy-mode = "rgmii";
+				phy-address = <0x3>;
+				turbo = "no";
+				phy-map = <0x00000000>;
+				rgmii-device = <&RGMII0>;
+				rgmii-channel = <1>;
+				tah-device = <&TAH1>;
+				tah-channel = <0>;
+				has-inverted-stacr-oc;
+				has-new-stacr-staopc;
+				mdio-device = <&EMAC0>;
+			};
+		};
+	};
+
+	chosen {
+		linux,stdout-path = "/plb/opb/serial@50001000";
+	};
+};
diff --git a/arch/powerpc/configs/40x/klondike_defconfig b/arch/powerpc/configs/40x/klondike_defconfig
new file mode 100644
index 0000000..c0d228d
--- /dev/null
+++ b/arch/powerpc/configs/40x/klondike_defconfig
@@ -0,0 +1,55 @@
+CONFIG_40x=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_WALNUT is not set
+CONFIG_APM8018X=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_MATH_EMULATION=y
+# CONFIG_MIGRATION is not set
+# CONFIG_SUSPEND is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_PROC_DEVICETREE=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=35000
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_SAS_ATTRS=y
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT4_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_CRAMFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_AVERAGE=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_FTRACE is not set
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index edae5bb..ce59693 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -1505,6 +1505,19 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.machine_check		= machine_check_4xx,
 		.platform		= "ppc405",
 	},
+	{	/* APM8018X */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x7ff11432,
+		.cpu_name		= "APM8018X",
+		.cpu_features		= CPU_FTRS_40X,
+		.cpu_user_features	= PPC_FEATURE_32 |
+			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+		.mmu_features		= MMU_FTR_TYPE_40x,
+		.icache_bsize		= 32,
+		.dcache_bsize		= 32,
+		.machine_check		= machine_check_4xx,
+		.platform		= "ppc405",
+	},
 	{	/* default match */
 		.pvr_mask		= 0x00000000,
 		.pvr_value		= 0x00000000,
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig
index 1530229..8883f2c 100644
--- a/arch/powerpc/platforms/40x/Kconfig
+++ b/arch/powerpc/platforms/40x/Kconfig
@@ -186,3 +186,14 @@ config IBM405_ERR51
 #	bool
 #	depends on !STB03xxx && PPC4xx_DMA
 #	default y
+#
+
+config APM8018X
+	bool "APM8018X"
+	depends on 40x
+	default n
+	select PPC40x_SIMPLE
+	help
+	  This option enables support for the AppliedMicro APM8018X evaluation
+	  board.
+
diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c
index e8dd5c5..2f8fde6 100644
--- a/arch/powerpc/platforms/40x/ppc40x_simple.c
+++ b/arch/powerpc/platforms/40x/ppc40x_simple.c
@@ -55,6 +55,7 @@ static const char *board[] __initdata = {
 	"amcc,haleakala",
 	"amcc,kilauea",
 	"amcc,makalu",
+	"apm,klondike",
 	"est,hotfoot"
 };
 
-- 
1.6.1.rc3

^ permalink raw reply related

* Re: [RFC PATCH v2 1/4] cpuidle: (powerpc) Add cpu_idle_wait() to allow switching of idle routines
From: Benjamin Herrenschmidt @ 2011-11-29  7:01 UTC (permalink / raw)
  To: Deepthi Dharwar; +Cc: linuxppc-dev, linux-pm, linux-kernel, linux-pm
In-Reply-To: <4ED47EC2.2090802@linux.vnet.ibm.com>

On Tue, 2011-11-29 at 12:12 +0530, Deepthi Dharwar wrote:
> 
> Yes, this could be problematic as there is small window for the
> race condition to occur . Otherwise we need to manually schedule
> it by running a kernel thread but this would definitely have a
> overhead and would be an overkill. 

Depends what this "window" is. IE. What are you trying to protect
yourself against ? What's the risk ?

If it's just module unload, then stop_machine is probably your
friend :-)

Cheers,
Ben.

^ permalink raw reply

* Re: [RFC PATCH v2 1/4] cpuidle: (powerpc) Add cpu_idle_wait() to allow switching of idle routines
From: Deepthi Dharwar @ 2011-11-29  7:15 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, linux-pm, linux-kernel, linux-pm
In-Reply-To: <1322550115.23348.72.camel@pasglop>

On 11/29/2011 12:31 PM, Benjamin Herrenschmidt wrote:

> On Tue, 2011-11-29 at 12:12 +0530, Deepthi Dharwar wrote:
>>
>> Yes, this could be problematic as there is small window for the
>> race condition to occur . Otherwise we need to manually schedule
>> it by running a kernel thread but this would definitely have a
>> overhead and would be an overkill. 
> 
> Depends what this "window" is. IE. What are you trying to protect
> yourself against ? What's the risk ?
> 
> If it's just module unload, then stop_machine is probably your
> friend :-)
> 
> Cheers,
> Ben.
> 
> 


Yup, it is the module unload that I am worried about. Otherwise
manually doing it using kernel thread would be an overkill -:(

Regards,
Deepthi

^ permalink raw reply

* [PATCH net-next v4 4/4] powerpc: tqm8548/tqm8xx: add and update CAN device nodes
From: Wolfgang Grandegger @ 2011-11-29  9:11 UTC (permalink / raw)
  To: netdev
  Cc: Stanislav Yelenskiy, devicetree-discuss, linux-can, linuxppc-dev,
	IreneV, socketcan-users, Wolfgang Zarre
In-Reply-To: <1322557890-6363-1-git-send-email-wg@grandegger.com>

This patch enables or updates support for the CC770 and AN82527
CAN controller on the TQM8548 and TQM8xx boards.

CC: devicetree-discuss@lists.ozlabs.org
CC: linuxppc-dev@ozlabs.org
CC: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
---
 arch/powerpc/boot/dts/tqm8548-bigflash.dts |   19 ++++++++++++++-----
 arch/powerpc/boot/dts/tqm8548.dts          |   19 ++++++++++++++-----
 arch/powerpc/boot/dts/tqm8xx.dts           |   25 +++++++++++++++++++++++++
 3 files changed, 53 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/boot/dts/tqm8548-bigflash.dts b/arch/powerpc/boot/dts/tqm8548-bigflash.dts
index 9452c3c..d918752 100644
--- a/arch/powerpc/boot/dts/tqm8548-bigflash.dts
+++ b/arch/powerpc/boot/dts/tqm8548-bigflash.dts
@@ -352,7 +352,7 @@
 		ranges = <
 			0 0x0 0xfc000000 0x04000000	// NOR FLASH bank 1
 			1 0x0 0xf8000000 0x08000000	// NOR FLASH bank 0
-			2 0x0 0xa3000000 0x00008000	// CAN (2 x i82527)
+			2 0x0 0xa3000000 0x00008000	// CAN (2 x CC770)
 			3 0x0 0xa3010000 0x00008000	// NAND FLASH
 
 		>;
@@ -393,18 +393,27 @@
 		};
 
 		/* Note: CAN support needs be enabled in U-Boot */
-		can0@2,0 {
-			compatible = "intel,82527"; // Bosch CC770
+		can@2,0 {
+			compatible = "bosch,cc770"; // Bosch CC770
 			reg = <2 0x0 0x100>;
 			interrupts = <4 1>;
 			interrupt-parent = <&mpic>;
+			bosch,external-clock-frequency = <16000000>;
+			bosch,disconnect-rx1-input;
+			bosch,disconnect-tx1-output;
+			bosch,iso-low-speed-mux;
+			bosch,clock-out-frequency = <16000000>;
 		};
 
-		can1@2,100 {
-			compatible = "intel,82527"; // Bosch CC770
+		can@2,100 {
+			compatible = "bosch,cc770"; // Bosch CC770
 			reg = <2 0x100 0x100>;
 			interrupts = <4 1>;
 			interrupt-parent = <&mpic>;
+			bosch,external-clock-frequency = <16000000>;
+			bosch,disconnect-rx1-input;
+			bosch,disconnect-tx1-output;
+			bosch,iso-low-speed-mux;
 		};
 
 		/* Note: NAND support needs to be enabled in U-Boot */
diff --git a/arch/powerpc/boot/dts/tqm8548.dts b/arch/powerpc/boot/dts/tqm8548.dts
index 619776f..988d887 100644
--- a/arch/powerpc/boot/dts/tqm8548.dts
+++ b/arch/powerpc/boot/dts/tqm8548.dts
@@ -352,7 +352,7 @@
 		ranges = <
 			0 0x0 0xfc000000 0x04000000	// NOR FLASH bank 1
 			1 0x0 0xf8000000 0x08000000	// NOR FLASH bank 0
-			2 0x0 0xe3000000 0x00008000	// CAN (2 x i82527)
+			2 0x0 0xe3000000 0x00008000	// CAN (2 x CC770)
 			3 0x0 0xe3010000 0x00008000	// NAND FLASH
 
 		>;
@@ -393,18 +393,27 @@
 		};
 
 		/* Note: CAN support needs be enabled in U-Boot */
-		can0@2,0 {
-			compatible = "intel,82527"; // Bosch CC770
+		can@2,0 {
+			compatible = "bosch,cc770"; // Bosch CC770
 			reg = <2 0x0 0x100>;
 			interrupts = <4 1>;
 			interrupt-parent = <&mpic>;
+			bosch,external-clock-frequency = <16000000>;
+			bosch,disconnect-rx1-input;
+			bosch,disconnect-tx1-output;
+			bosch,iso-low-speed-mux;
+			bosch,clock-out-frequency = <16000000>;
 		};
 
-		can1@2,100 {
-			compatible = "intel,82527"; // Bosch CC770
+		can@2,100 {
+			compatible = "bosch,cc770"; // Bosch CC770
 			reg = <2 0x100 0x100>;
 			interrupts = <4 1>;
 			interrupt-parent = <&mpic>;
+			bosch,external-clock-frequency = <16000000>;
+			bosch,disconnect-rx1-input;
+			bosch,disconnect-tx1-output;
+			bosch,iso-low-speed-mux;
 		};
 
 		/* Note: NAND support needs to be enabled in U-Boot */
diff --git a/arch/powerpc/boot/dts/tqm8xx.dts b/arch/powerpc/boot/dts/tqm8xx.dts
index f6da7ec..c3dba25 100644
--- a/arch/powerpc/boot/dts/tqm8xx.dts
+++ b/arch/powerpc/boot/dts/tqm8xx.dts
@@ -57,6 +57,7 @@
 
 		ranges = <
 			0x0 0x0 0x40000000 0x800000
+			0x3 0x0 0xc0000000 0x200
 		>;
 
 		flash@0,0 {
@@ -67,6 +68,30 @@
 			bank-width = <4>;
 			device-width = <2>;
 		};
+
+		/* Note: CAN support needs be enabled in U-Boot */
+		can@3,0 {
+			compatible = "intc,82527";
+			reg = <3 0x0 0x80>;
+			interrupts = <8 1>;
+			interrupt-parent = <&PIC>;
+			bosch,external-clock-frequency = <16000000>;
+			bosch,disconnect-rx1-input;
+			bosch,disconnect-tx1-output;
+			bosch,iso-low-speed-mux;
+			bosch,clock-out-frequency = <16000000>;
+		};
+
+		can@3,100 {
+			compatible = "intc,82527";
+			reg = <3 0x100 0x80>;
+			interrupts = <8 1>;
+			interrupt-parent = <&PIC>;
+			bosch,external-clock-frequency = <16000000>;
+			bosch,disconnect-rx1-input;
+			bosch,disconnect-tx1-output;
+			bosch,iso-low-speed-mux;
+		};
 	};
 
 	soc@fff00000 {
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH net-next v4 3/4] can: cc770: add platform bus driver for the CC770 and AN82527
From: Wolfgang Grandegger @ 2011-11-29  9:11 UTC (permalink / raw)
  To: netdev
  Cc: Stanislav Yelenskiy, Devicetree-discuss, linux-can, linuxppc-dev,
	IreneV, socketcan-users, Wolfgang Zarre
In-Reply-To: <1322557890-6363-1-git-send-email-wg@grandegger.com>

This driver works with both, static platform data and device tree
bindings. It has been tested on a TQM855L board with two AN82527
CAN controllers on the local bus.

CC: Devicetree-discuss@lists.ozlabs.org
CC: linuxppc-dev@ozlabs.org
CC: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 .../devicetree/bindings/net/can/cc770.txt          |   56 ++++
 drivers/net/can/cc770/Kconfig                      |    7 +
 drivers/net/can/cc770/Makefile                     |    1 +
 drivers/net/can/cc770/cc770_platform.c             |  273 ++++++++++++++++++++
 4 files changed, 337 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/can/cc770.txt
 create mode 100644 drivers/net/can/cc770/cc770_platform.c

diff --git a/Documentation/devicetree/bindings/net/can/cc770.txt b/Documentation/devicetree/bindings/net/can/cc770.txt
new file mode 100644
index 0000000..01e282d
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/can/cc770.txt
@@ -0,0 +1,56 @@
+Memory mapped Bosch CC770 and Intel AN82527 CAN controller
+
+Note: The CC770 is a CAN controller from Bosch, which is 100%
+compatible with the old AN82527 from Intel, but with "bugs" being fixed.
+
+Required properties:
+
+- compatible : should be "bosch,cc770" for the CC770 and "intc,82527"
+	for the AN82527.
+
+- reg : should specify the chip select, address offset and size required
+	to map the registers of the controller. The size is usually 0x80.
+
+- interrupts : property with a value describing the interrupt source
+	(number and sensitivity) required for the controller.
+
+Optional properties:
+
+- bosch,external-clock-frequency : frequency of the external oscillator
+	clock in Hz. Note that the internal clock frequency used by the
+	controller is half of that value. If not specified, a default
+	value of 16000000 (16 MHz) is used.
+
+- bosch,clock-out-frequency : slock frequency in Hz on the CLKOUT pin.
+	If not specified or if the specified value is 0, the CLKOUT pin
+	will be disabled.
+
+- bosch,slew-rate : slew rate of the CLKOUT signal. If not specified,
+	a resonable value will be calculated.
+
+- bosch,disconnect-rx0-input : see data sheet.
+
+- bosch,disconnect-rx1-input : see data sheet.
+
+- bosch,disconnect-tx1-output : see data sheet.
+
+- bosch,polarity-dominant : see data sheet.
+
+- bosch,divide-memory-clock : see data sheet.
+
+- bosch,iso-low-speed-mux : see data sheet.
+
+For further information, please have a look to the CC770 or AN82527.
+
+Examples:
+
+can@3,100 {
+	compatible = "bosch,cc770";
+	reg = <3 0x100 0x80>;
+	interrupts = <2 0>;
+	interrupt-parent = <&mpic>;
+	bosch,external-clock-frequency = <16000000>;
+};
+
+
+
diff --git a/drivers/net/can/cc770/Kconfig b/drivers/net/can/cc770/Kconfig
index 28e4d48..22c07a8 100644
--- a/drivers/net/can/cc770/Kconfig
+++ b/drivers/net/can/cc770/Kconfig
@@ -11,4 +11,11 @@ config CAN_CC770_ISA
 	  connected to the ISA bus using I/O port, memory mapped or
 	  indirect access.
 
+config CAN_CC770_PLATFORM
+	tristate "Generic Platform Bus based CC770 driver"
+	---help---
+	  This driver adds support for the CC770 and AN82527 chips
+	  connected to the "platform bus" (Linux abstraction for directly
+	  to the processor attached devices).
+
 endif
diff --git a/drivers/net/can/cc770/Makefile b/drivers/net/can/cc770/Makefile
index 872ecff..9fb8321 100644
--- a/drivers/net/can/cc770/Makefile
+++ b/drivers/net/can/cc770/Makefile
@@ -4,5 +4,6 @@
 
 obj-$(CONFIG_CAN_CC770) += cc770.o
 obj-$(CONFIG_CAN_CC770_ISA) += cc770_isa.o
+obj-$(CONFIG_CAN_CC770_PLATFORM) += cc770_platform.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/cc770/cc770_platform.c b/drivers/net/can/cc770/cc770_platform.c
new file mode 100644
index 0000000..fb87b22
--- /dev/null
+++ b/drivers/net/can/cc770/cc770_platform.c
@@ -0,0 +1,273 @@
+/*
+ * Driver for CC770 and AN82527 CAN controllers on the platform bus
+ *
+ * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * If platform data are used you should have similar definitions
+ * in your board-specific code:
+ *
+ *   static struct cc770_platform_data myboard_cc770_pdata = {
+ *           .osc_freq = 16000000,
+ *           .cir = 0x41,
+ *           .cor = 0x20,
+ *           .bcr = 0x40,
+ *   };
+ *
+ * Please see include/linux/can/platform/cc770.h for description of
+ * above fields.
+ *
+ * If the device tree is used, you need a CAN node definition in your
+ * DTS file similar to:
+ *
+ *   can@3,100 {
+ *           compatible = "bosch,cc770";
+ *           reg = <3 0x100 0x80>;
+ *           interrupts = <2 0>;
+ *           interrupt-parent = <&mpic>;
+ *           bosch,external-clock-frequency = <16000000>;
+ *   };
+ *
+ * See "Documentation/devicetree/bindings/net/can/cc770.txt" for further
+ * information.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/platform/cc770.h>
+
+#include <linux/of_platform.h>
+
+#include "cc770.h"
+
+#define DRV_NAME "cc770_platform"
+
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for CC770 on the platform bus");
+MODULE_LICENSE("GPL v2");
+
+#define CC770_PLATFORM_CAN_CLOCK  16000000
+
+static u8 cc770_platform_read_reg(const struct cc770_priv *priv, int reg)
+{
+	return in_8(priv->reg_base + reg);
+}
+
+static void cc770_platform_write_reg(const struct cc770_priv *priv, int reg,
+				     u8 val)
+{
+	out_8(priv->reg_base + reg, val);
+}
+
+static int __devinit cc770_get_of_node_data(struct platform_device *pdev,
+					    struct cc770_priv *priv)
+{
+	struct device_node *np = pdev->dev.of_node;
+	const u32 *prop;
+	int prop_size;
+	u32 clkext;
+
+	prop = of_get_property(np, "bosch,external-clock-frequency",
+			       &prop_size);
+	if (prop && (prop_size ==  sizeof(u32)))
+		clkext = *prop;
+	else
+		clkext = CC770_PLATFORM_CAN_CLOCK; /* default */
+	priv->can.clock.freq = clkext;
+
+	/* The system clock may not exceed 10 MHz */
+	if (priv->can.clock.freq > 10000000) {
+		priv->cpu_interface |= CPUIF_DSC;
+		priv->can.clock.freq /= 2;
+	}
+
+	/* The memory clock may not exceed 8 MHz */
+	if (priv->can.clock.freq > 8000000)
+		priv->cpu_interface |= CPUIF_DMC;
+
+	if (of_get_property(np, "bosch,divide-memory-clock", NULL))
+		priv->cpu_interface |= CPUIF_DMC;
+	if (of_get_property(np, "bosch,iso-low-speed-mux", NULL))
+		priv->cpu_interface |= CPUIF_MUX;
+
+	if (!of_get_property(np, "bosch,no-comperator-bypass", NULL))
+		priv->bus_config |= BUSCFG_CBY;
+	if (of_get_property(np, "bosch,disconnect-rx0-input", NULL))
+		priv->bus_config |= BUSCFG_DR0;
+	if (of_get_property(np, "bosch,disconnect-rx1-input", NULL))
+		priv->bus_config |= BUSCFG_DR1;
+	if (of_get_property(np, "bosch,disconnect-tx1-output", NULL))
+		priv->bus_config |= BUSCFG_DT1;
+	if (of_get_property(np, "bosch,polarity-dominant", NULL))
+		priv->bus_config |= BUSCFG_POL;
+
+	prop = of_get_property(np, "bosch,clock-out-frequency", &prop_size);
+	if (prop && (prop_size == sizeof(u32)) && *prop > 0) {
+		u32 cdv = clkext / *prop;
+		int slew;
+
+		if (cdv > 0 && cdv < 16) {
+			priv->cpu_interface |= CPUIF_CEN;
+			priv->clkout |= (cdv - 1) & CLKOUT_CD_MASK;
+
+			prop = of_get_property(np, "bosch,slew-rate",
+					       &prop_size);
+			if (prop && (prop_size == sizeof(u32))) {
+				slew = *prop;
+			} else {
+				/* Determine default slew rate */
+				slew = (CLKOUT_SL_MASK >>
+					CLKOUT_SL_SHIFT) -
+					((cdv * clkext - 1) / 8000000);
+				if (slew < 0)
+					slew = 0;
+			}
+			priv->clkout |= (slew << CLKOUT_SL_SHIFT) &
+				CLKOUT_SL_MASK;
+		} else {
+			dev_dbg(&pdev->dev, "invalid clock-out-frequency\n");
+		}
+	}
+
+	return 0;
+}
+
+static int __devinit cc770_get_platform_data(struct platform_device *pdev,
+					     struct cc770_priv *priv)
+{
+
+	struct cc770_platform_data *pdata = pdev->dev.platform_data;
+
+	priv->can.clock.freq = pdata->osc_freq;
+	if (priv->cpu_interface | CPUIF_DSC)
+		priv->can.clock.freq /= 2;
+	priv->clkout = pdata->cor;
+	priv->bus_config = pdata->bcr;
+	priv->cpu_interface = pdata->cir;
+
+	return 0;
+}
+
+static int __devinit cc770_platform_probe(struct platform_device *pdev)
+{
+	struct net_device *dev;
+	struct cc770_priv *priv;
+	struct resource *mem;
+	resource_size_t mem_size;
+	void __iomem *base;
+	int err, irq;
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(pdev, 0);
+	if (!mem || irq <= 0)
+		return -ENODEV;
+
+	mem_size = resource_size(mem);
+	if (!request_mem_region(mem->start, mem_size, pdev->name))
+		return -EBUSY;
+
+	base = ioremap(mem->start, mem_size);
+	if (!base) {
+		err = -ENOMEM;
+		goto exit_release_mem;
+	}
+
+	dev = alloc_cc770dev(0);
+	if (!dev) {
+		err = -ENOMEM;
+		goto exit_unmap_mem;
+	}
+
+	dev->irq = irq;
+	priv = netdev_priv(dev);
+	priv->read_reg = cc770_platform_read_reg;
+	priv->write_reg = cc770_platform_write_reg;
+	priv->irq_flags = IRQF_SHARED;
+	priv->reg_base = base;
+
+	if (pdev->dev.of_node)
+		err = cc770_get_of_node_data(pdev, priv);
+	else if (pdev->dev.platform_data)
+		err = cc770_get_platform_data(pdev, priv);
+	else
+		err = -ENODEV;
+	if (err)
+		goto exit_free_cc770;
+
+	dev_dbg(&pdev->dev,
+		 "reg_base=0x%p irq=%d clock=%d cpu_interface=0x%02x "
+		 "bus_config=0x%02x clkout=0x%02x\n",
+		 priv->reg_base, dev->irq, priv->can.clock.freq,
+		 priv->cpu_interface, priv->bus_config, priv->clkout);
+
+	dev_set_drvdata(&pdev->dev, dev);
+	SET_NETDEV_DEV(dev, &pdev->dev);
+
+	err = register_cc770dev(dev);
+	if (err) {
+		dev_err(&pdev->dev,
+			"couldn't register CC700 device (err=%d)\n", err);
+		goto exit_free_cc770;
+	}
+
+	return 0;
+
+exit_free_cc770:
+	free_cc770dev(dev);
+exit_unmap_mem:
+	iounmap(base);
+exit_release_mem:
+	release_mem_region(mem->start, mem_size);
+
+	return err;
+}
+
+static int __devexit cc770_platform_remove(struct platform_device *pdev)
+{
+	struct net_device *dev = dev_get_drvdata(&pdev->dev);
+	struct cc770_priv *priv = netdev_priv(dev);
+	struct resource *mem;
+
+	unregister_cc770dev(dev);
+	iounmap(priv->reg_base);
+	free_cc770dev(dev);
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(mem->start, resource_size(mem));
+
+	return 0;
+}
+
+static struct of_device_id __devinitdata cc770_platform_table[] = {
+	{.compatible = "bosch,cc770"}, /* CC770 from Bosch */
+	{.compatible = "intc,82527"},  /* AN82527 from Intel CP */
+	{},
+};
+
+static struct platform_driver cc770_platform_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = cc770_platform_table,
+	},
+	.probe = cc770_platform_probe,
+	.remove = __devexit_p(cc770_platform_remove),
+};
+
+module_platform_driver(cc770_platform_driver);
+
-- 
1.7.4.1

^ permalink raw reply related

* Booting Linux on one core of P1022
From: Arshad, Farrukh @ 2011-11-29  8:36 UTC (permalink / raw)
  To: linuxppc-dev@lists.ozlabs.org

[-- Attachment #1: Type: text/plain, Size: 3528 bytes --]

Greetings All,

I am working on P1022RDK (P1022 Processor). I am trying to bring up LTIB Linux only on Core1 of the processor. I have configured the "cpus" node in the device tree file as following way

Cpus {
     #address-cells = <1>;
     #size-cells = <0>;
     PowerPC,P1022@1 {
           Device_type = "cpu";
          Ret = <0x1>;
           Next-level-cache = <&L2>;
     };
};

Mpic: pic@40000 {
     Interrupt-controller;
     #address-cells = <0>;
     #interrupt-cells = <2>;
     Reg = <0x40000 0x40000>;
     Compatible = "chrp,open-pic";
     Device_type = "open-pic";
     Pic-no-reset;
     Protected-sources = <
           16         // l2-cache-controller@20000
     >;
};

I am loading the kernel from Uboot as following way

Setenv bootm_low 0x10000000
Setenv bootm_size 0x10000000
Setenv bootm boot=/dev/mmcblk0p3 ro debug rootdelay=5
Interrupts off
Bootm start $load1addr - $fdt1addr
Bootm loados
Bootm fdt
Fdt boardsetup
Fdt chosen
Bootm prep
Bootm go

Using above configuration when the kernel boots it fails giving following message

[    2.057448] WM8960 I2C Codec 1-001a: No platform data supplied
[    3.062314] WM8960 I2C Codec 1-001a: Failed to issue reset
[    3.067816] WM8960 I2C Codec: probe of 1-001a failed with error -110
[    3.074528] No device for DAI WM8990 ADC/DAC Primary
[    3.079834] ALSA device list:
[    3.082821]   No soundcards found.
[    3.087561] IPv4 over IPv4 tunneling driver
[    3.092757] GRE over IPv4 tunneling driver
[    3.097871] TCP cubic registered
[    3.101124] Initializing XFRM netlink socket
[    3.105405] NET: Registered protocol family 17
[    3.109869] NET: Registered protocol family 15
[    3.114734] SCTP: Hash tables configured (established 8192 bind 8192)
[    3.122984] drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
[    3.129329] Waiting 5sec before mounting root device...
[    8.138471] Root-NFS: No NFS server available, giving up.
[    8.143896] VFS: Unable to mount root fs via NFS, trying floppy.
[    8.150150] VFS: Cannot open root device "mmcblk0p3" or unknown-block(2,0)
[    8.157038] Please append a correct "root=" boot option; here are the available partitions:
[    8.165410] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0)
[    8.173681] Rebooting in 180 seconds..
[   11.994301] mmc0: Timeout waiting for hardware interrupt.
[   11.999870] sdhci: ============== REGISTER DUMP ==============
[   12.005697] sdhci: Sys addr: 0x00000000 | Version:  0x00001201
[   12.011523] sdhci: Blk size: 0x00000000 | Blk cnt:  0x00000001
[   12.017349] sdhci: Argument: 0x00000000 | Trn mode: 0x00000000
[   12.023175] sdhci: Present:  0xff8d0008 | Host ctl: 0x00000020
[   12.029001] sdhci: Power:    0x00000003 | Blk gap:  0x00000000
[   12.034828] sdhci: Wake-up:  0x00000000 | Clock:    0x000010ff
[   12.040654] sdhci: Timeout:  0x00000000 | Int stat: 0x00000001
[   12.046479] sdhci: Int enab: 0x007f0003 | Sig enab: 0x007f0003
[   12.052305] sdhci: AC12 err: 0x00000000 | Slot int: 0x00001201
[   12.058130] sdhci: Caps:     0x05f30000 | Max curr: 0x00000000
[   12.063955] sdhci: ===========================================

When I boot the same kernel using 2 CPUs in the device tree file, it boots successfully. Any thoughts on what I am missing.


Best Regards

Farrukh Arshad
Sr. Software Development Engineer
Mentor Graphics Pakistan
Ph:   +92 - 423 - 609 - 92 - 09
Cell: +92 - 303 - 444 - 77 - 05


[-- Attachment #2: Type: text/html, Size: 13920 bytes --]

^ permalink raw reply

* lmb_alloc() and page memory overlap
From: Prashant Bhole @ 2011-11-29 13:21 UTC (permalink / raw)
  To: linuxppc-dev

Hi,
I am using custom 460ex board with kernel version 2.6.30.
I noticed that page_alloc() is returning a page whose memory
is already allocated by lmb_alloc() while unflattening the device
tree. As per my knowledge the memory allocated by lmb_alloc()
should be reserved till the end, right?

Some more explanation of what I observed:

unflatten_device_tree() allocates memory, which will be used
for "struct node" objects in the device tree. I obtained base
address of allocated memory in "unsigned long base_mem"

Now I executed the following code after the kernel booted properly.

---------------------------------------------------------------
extern unsigned long mem; // lmb_alloc() memory
struct page *test_page = virt_to_page(mem);
struct page *new_page = NULL;

while(1)
{
    new_page = NULL;
    new_page = alloc_page(GFP_KERNEL);
    if(!new_page)
    {
        printk("Allocation failed\n");
        while(1);
    }
    if(test_page == new_page)
    {
         printk("Memory already allocated by lmb_alloc\n");
         while(1);
    }
}
---------------------------------------------------------------

After many page allocations, I always hit the condition (test_page == new_page).
Am I doing anything wrong here?
Has anybody faced this kind of problem before?


I also noticed that lmb_dump_all() shows 2 regions overlapping (last two):

LMB configuration:
 rmo_size    = 0x30000000
 memory.size = 0x30000000
 memory.cnt  = 0x1
 memory[0x0]    0x0000000000000000 - 0x000000002fffffff, 0x30000000 bytes
 reserved.cnt  = 0x6
 reserved[0x0]  0x0000000000000000 - 0x00000000006bffff, 0x6c0000 bytes
 reserved[0x1]  0x0000000000ffa000 - 0x0000000000ffcfff, 0x3000 bytes
 reserved[0x2]  0x000000002fdd0000 - 0x000000002fddffff, 0x10000 bytes
 reserved[0x3]  0x000000002fde4000 - 0x000000002fde9fff, 0x6000 bytes
 reserved[0x4]  0x000000002fdeb060 - 0x000000002ffff768, 0x214709 bytes
 reserved[0x5]  0x000000002fdee000 - 0x000000002ffff769, 0x21176a bytes


Thanks,
Prashant

^ permalink raw reply

* Re: [PATCH v3 2/3] hvc_init(): Enforce one-time initialization.
From: Amit Shah @ 2011-11-29 14:21 UTC (permalink / raw)
  To: Miche Baker-Harvey
  Cc: Stephen Rothwell, xen-devel, Konrad Rzeszutek Wilk, Rusty Russell,
	linux-kernel, virtualization, Anton Blanchard, Mike Waychison,
	ppc-dev, Greg Kroah-Hartman, Eric Northrup
In-Reply-To: <CAB8RdaoDxMCgTjuGP70bGrsrtgh=USYtU3Spo5OPtVMYAM5EzQ@mail.gmail.com>

Hi,

On (Mon) 28 Nov 2011 [15:40:41], Miche Baker-Harvey wrote:
> Amit,
> 
> You said that the work would be serialized "due to port additions
> being on work items on the same workqueue".  I'm not seeing that.

You leave a lot of questions unanswered.  What's your environment?
Are you hot-plugging ports?  Are you using qemu?  What's your command
line?

> I've double checked this by using a mutex_trylock in
> hvc_console::hvc_alloc(), and here's the relevant output from dmesg:
> 
> root@myubuntu:~# dmesg | grep MBH
> [3307216.210274] MBH: got hvc_ports_mutex
> [3307216.210690] MBH: trylock of hvc_ports_mutex failed
> [3307216.211143] MBH: got hvc_ports_mutex
> 
> This is in a system with two virtio console ports, each of which is a
> console.  I think if the VIRTIO_CONSOLE_CONSOLE_PORT message handling
> were actually being serialized, the trylock should never fail.

Agreed.

> What's the source of the serialization for the workqueue items?  At
> first reading it looks like the control_work_handler gets called for
> each virtio interrupt?

It all depends on how you add ports.  If you're using qemu, they
happen via the control work handler.

		Amit

^ permalink raw reply

* Re: [PATCH 2/6] powerpc/85xx: consolidate of_platform_bus_probe calls
From: Kumar Gala @ 2011-11-29 15:48 UTC (permalink / raw)
  To: Tabi Timur-B04825
  Cc: Dmitry Eremin-Solenikov, Gala Kumar-B11780,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <CAOZdJXXZG38v-tgA2Ty7-uxJ3AxoFCmNxMO3dKJnJYQtJFb9DA@mail.gmail.com>


On Nov 28, 2011, at 5:42 PM, Tabi Timur-B04825 wrote:

> On Thu, Nov 17, 2011 at 11:56 AM, Dmitry Eremin-Solenikov
> <dbaryshkov@gmail.com> wrote:
>=20
>> diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c =
b/arch/powerpc/platforms/85xx/p1022_ds.c
>> index 00d93a4..cacb4d4 100644
>> --- a/arch/powerpc/platforms/85xx/p1022_ds.c
>> +++ b/arch/powerpc/platforms/85xx/p1022_ds.c
>> @@ -330,10 +330,6 @@ static void __init p1022_ds_setup_arch(void)
>>  }
>>=20
>>  static struct of_device_id __initdata p1022_ds_ids[] =3D {
>> -       { .type =3D "soc", },
>> -       { .compatible =3D "soc", },
>> -       { .compatible =3D "simple-bus", },
>> -       { .compatible =3D "gianfar", },
>>        /* So that the DMA channel nodes can be probed individually: =
*/
>>        { .compatible =3D "fsl,eloplus-dma", },
>>        {},
>> @@ -343,6 +339,7 @@ static int __init p1022_ds_publish_devices(void)
>>  {
>>        return of_platform_bus_probe(NULL, p1022_ds_ids, NULL);
>>  }
>> +machine_device_initcall(p1022_ds, mpc85xx_common_publish_devices);
>>  machine_device_initcall(p1022_ds, p1022_ds_publish_devices);
>=20
> I don't think this is working.  I need to investigate some more to be
> sure, but it looks like this is not picking up "fsl,eloplus-dma".
> None of the DMA channels are being probed in the audio driver
> (sound/soc/fsl_dma.c).

Hmm, that's odd.  Should see if the issues exists before the change.

- k=

^ permalink raw reply

* Re: [PATCH 2/6] powerpc/85xx: consolidate of_platform_bus_probe calls
From: Timur Tabi @ 2011-11-29 16:17 UTC (permalink / raw)
  To: Kumar Gala
  Cc: Dmitry Eremin-Solenikov, Gala Kumar-B11780,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <38BAFE03-DB17-4442-8CC2-E386E46FEB19@kernel.crashing.org>

Kumar Gala wrote:

>> I don't think this is working.  I need to investigate some more to be
>> sure, but it looks like this is not picking up "fsl,eloplus-dma".
>> None of the DMA channels are being probed in the audio driver
>> (sound/soc/fsl_dma.c).
> 
> Hmm, that's odd.  Should see if the issues exists before the change.

If I move the "fsl,eloplus-dma" into mpc85xx_common_ids[], then everything works.

I suspect there's some kind of state machine in of_platform_bus_probe() that allows it to find the DMA channel nodes if it's scanned everything else first.  I'm trying to debug it now.

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply

* Re: [PATCH 2/6] powerpc/85xx: consolidate of_platform_bus_probe calls
From: Timur Tabi @ 2011-11-29 16:20 UTC (permalink / raw)
  To: Kumar Gala
  Cc: Dmitry Eremin-Solenikov, Gala Kumar-B11780,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <4ED5058F.90004@freescale.com>

Timur Tabi wrote:

> If I move the "fsl,eloplus-dma" into mpc85xx_common_ids[], then everything works.
> 
> I suspect there's some kind of state machine in of_platform_bus_probe() that allows it to find the DMA channel nodes if it's scanned everything else first.  I'm trying to debug it now.

So why do we need mpc85xx_common_ids[] at all?  Why can't of_platform_bus_probe() just scan the entire tree?

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply

* Re: [PATCH 04/13] powerpc: Update hugetlb huge_pte_alloc and tablewalk code for FSL BOOKE
From: Becky Bruce @ 2011-11-29 16:36 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, David Gibson
In-Reply-To: <1322544333.23348.69.camel@pasglop>


On Nov 28, 2011, at 11:25 PM, Benjamin Herrenschmidt wrote:

> On Mon, 2011-10-10 at 15:50 -0500, Becky Bruce wrote:
>> From: Becky Bruce <beckyb@kernel.crashing.org>
>>=20
>> This updates the hugetlb page table code to handle 64-bit FSL_BOOKE.
>> The previous 32-bit work counted on the inner levels of the page =
table
>> collapsing.
>=20
> Seriously, my brain hurts !!!

Now you know how I felt when I got the original code from David :)

>=20
> So I've tried to understand that code and so far, what I came up with =
is
> this, please reply and let me know if I'm full of crack or what ...
>=20
> - David's code has entire levels "branching off" into hugepd's which
> are hugetlb specific page dirs. That requires address space =
constrainst.

Yes.

>=20
> - The hack you do with HUGEPD_PGD_SHIFT defined to PGDIR_SHIFT and
> HUGEPD_PUD_SHIFT to PUD_SHIFT consists of collasping that back into =
the
> normal levels.

That exists so Jimi's code for A2 and mine can coexist peacefully =
without ifdeffing huge blocks because we peel off the page table at =
different points for a hugepd.  In my case, if I have a 4M page, that is =
handled by having 2 entries at the 2M layer, each of which is a pointer =
to the same pte stored in a kmem_cache created for that purpose.  In the =
server/A2 case, they peel off at the layer above 4M and have a sub-table =
kmem_cache that has a bunch of same-size huge page ptes (this is all =
because of the slice constraint).

>=20
> - I really don't understand what you are doing in __hugepte_alloc(). =
It
> seems to me that you are trying to make things still point to some =
kind
> of separate hugepd dir with the hugeptes in it and have the page =
tables
> point to that but I don't quite get it.

In your example below, the alloc code is:
1) allocating a small kmem_cache for the pte

2) filling in 8 entries at the 2M level with the pointers to that pte, =
with the upper bit munged to indicate huge and bits in the lower region =
that store the huge page size because it can't be encoded in the book3e =
pte format

>=20
> - Couldn't we just instead ditch the whole hugepd concept alltogether
> and simply have the huge ptes in the page table at the right level,
> using possibly multiple consecutive of them for a single page when
> needed ?
>=20
> Example: 4K base page size. PMD maps 2M. a 16M page could be
> representing by having 8 consecutive hugeptes pointing to the same =
huge
> page in the PMD directory.

We currently have 8 consecutive PMD entries that are pointers to the =
same kmem_cache that holds the actual PTE.  I did this for a few =
reasons:

1) I was trying to stay as close to what David had done as possible

2) symmetry - in every other case entries at higher levels of the normal =
page table are pointers to something, and it's easy to identify that =
something is a pointer to hugepte using David's upper-bit-flipping =
trick.  If we have an actual entry mixed in with the pointers it might =
be hard to tell that's it's an actual PTE and not a pointer without =
getting information from somewhere else (i.e. the vma)

3) I was trying to avoid having multiple copies of the actual pte - this =
way it's easy to do stuff like change the perms on the PTE, since I only =
have to modify one copy

4) I needed the information laid out for quick TLB miss fault-handling =
of hugepte tlb misses (see below).

>=20
> I believe we always "know" when accessing a PTE whether it's going to =
be
> huge or not and if it's huge, the page size. IE. All the functions we
> care about either get the vma (which gets you everything you need) or
> the size (huge_pte_alloc).

An exception is the 32-bit fault hander asm code.  It does a walk of the =
page table to reload the tlb.  We need to be able to easily identify =
that we're walking into a hugepage area so we know to load the tlbcam.  =
Having the pointer there with the munged upper bit that David devised is =
very convenient for that.  Also, the Book3e page table format does not =
allow us to represent page sizes > 32m.  So that's encoded in the hugepd =
instead (and not in the pte).

I'm not sure how to get around this without slowing things down.  I =
originally had a slower handler and it turned out to impact performance =
of several important workloads and my perf guys griped at me. I was =
actually eventually planning to rewrite the 64b fsl book3e handler to =
deal with this in asm as well.   Large workloads on our systems do a lot =
of tlbcam entry replacement due to 1) the small size of the tlbcam and =
2) the lack of any hardware replacement policy on that array.

There are other places where we'd have to modify the code to have the =
vma available (not that it's hard to do, but it's not floating around =
everywhere).  And there may be other places where this is an issue - I'd =
have to go dig around a bit to answer that.

For the record, I hate the idea of not being able to walk the page table =
without going elsewhere for information.  IMHO I should be able to tell =
everything I need to load a TLB entry from there without digging up a =
vma.

>=20
> This should be much simpler than what we have today.
>=20
> That way, we have a completely generic accross-the-board way to store
> huge pte's in our page tables, which is totally disconnected from the
> slices. The later remains a purely server-only thing which only =
affects
> the SLB code and get_unmapped_area().

David and Jimi will have to comment about whether they can flatten out =
their stuff to just store PTEs.  A lot of my code exists because I was =
attempting to be as close to the IBM implementation as possible.

>=20
> That means that we'll have to find another option for PowerEN giant
> indirects but that's a non issue at the moment. I think we can keep =
the
> complexity local to the PowerEN code by doing shadows there if we need
> to.
>=20
> What do you think ?

I'm happy if we can come up with another solution that still allows me =
to do my miss fault handling efficiently in asm.... What we do on FSL =
Booke with storing multiple pointers to a single pte is actually a =
fairly clean solution given the constraints.  It's only in the context =
of having a different implementation coexisting with it that makes =
things start getting complicated.  If you have some suggestions on =
another way to deal with this, I'm all ears.

Cheers,
B

^ permalink raw reply

* Re: [PATCH 2/6] powerpc/85xx: consolidate of_platform_bus_probe calls
From: Kumar Gala @ 2011-11-29 16:38 UTC (permalink / raw)
  To: Timur Tabi, Benjamin Herrenschmidt
  Cc: Dmitry Eremin-Solenikov, Gala Kumar-B11780,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <4ED50633.4020506@freescale.com>


On Nov 29, 2011, at 10:20 AM, Timur Tabi wrote:

> Timur Tabi wrote:
>=20
>> If I move the "fsl,eloplus-dma" into mpc85xx_common_ids[], then =
everything works.
>>=20
>> I suspect there's some kind of state machine in =
of_platform_bus_probe() that allows it to find the DMA channel nodes if =
it's scanned everything else first.  I'm trying to debug it now.
>=20
> So why do we need mpc85xx_common_ids[] at all?  Why can't =
of_platform_bus_probe() just scan the entire tree?

Ben would probably have to answer that.  I can't remember why he wanted =
it.  I'm sure he has a good reason.

- k=

^ permalink raw reply

* Re: [PATCH 02/13] powerpc: hugetlb: fix huge_ptep_set_access_flags return value
From: Becky Bruce @ 2011-11-29 16:52 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, david
In-Reply-To: <1322539102.23348.57.camel@pasglop>


On Nov 28, 2011, at 9:58 PM, Benjamin Herrenschmidt wrote:

> On Mon, 2011-10-10 at 15:50 -0500, Becky Bruce wrote:
>=20
>> diff --git a/arch/powerpc/include/asm/hugetlb.h =
b/arch/powerpc/include/asm/hugetlb.h
>> index 8600493..70f9885 100644
>> --- a/arch/powerpc/include/asm/hugetlb.h
>> +++ b/arch/powerpc/include/asm/hugetlb.h
>> @@ -124,7 +124,18 @@ static inline int =
huge_ptep_set_access_flags(struct vm_area_struct *vma,
>> 					     unsigned long addr, pte_t =
*ptep,
>> 					     pte_t pte, int dirty)
>> {
>> +#if defined(CONFIG_PPC_MMU_NOHASH) && \
>> +	!(defined(CONFIG_PPC_FSL_BOOK3E) && defined(CONFIG_PPC32))
>=20
> The above conditional makes my brain hurt. Can you change that to
> instead
>=20
> #ifdef HUGETLB_NEED_PRELOAD
>=20
> ... or something like that, which you then #define in the right
> mmu-xxxx.h header ?

Sure.

Can I publish this as a followup instead of rebasing?  We're trying to =
stay sync'ed with what's in our BSP and it would be easier for me/Kumar =
to deal with.

Cheers,
B

>=20
> Cheers,
> Ben.
>=20
>=20
>> +	/*
>> +	 * The "return 1" forces a call of update_mmu_cache, which will =
write a
>> +	 * TLB entry.  Without this, platforms that don't do a write of =
the TLB
>> +	 * entry in the TLB miss handler asm will fault ad infinitum.
>> +	 */
>> +	ptep_set_access_flags(vma, addr, ptep, pte, dirty);
>> +	return 1;
>> +#else
>> 	return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
>> +#endif
>> }
>>=20
>> static inline pte_t huge_ptep_get(pte_t *ptep)
>=20

^ permalink raw reply

* Re: [PATCH v3 2/3] hvc_init(): Enforce one-time initialization.
From: Miche Baker-Harvey @ 2011-11-29 17:04 UTC (permalink / raw)
  To: Amit Shah
  Cc: Stephen Rothwell, xen-devel, Konrad Rzeszutek Wilk, Rusty Russell,
	linux-kernel, virtualization, Anton Blanchard, Mike Waychison,
	ppc-dev, Greg Kroah-Hartman, Eric Northrup
In-Reply-To: <20111129142149.GE2822@amit-x200.redhat.com>

Amit,
We aren't using either QEMU or kvmtool, but we are using KVM. =A0All
theissues we are seeing happen when we try to establish multiple
virtioconsoles at boot time. =A0The command line isn't relevant, but I
cantell you the protocol that's passing between the host (kvm) and
theguest (see the end of this message).
We do go through the control_work_handler(), but it's not
providingsynchronization. =A0Here's a trace of the
control_work_handler() andhandle_control_message() calls; note that
there are two concurrentcalls to control_work_handler().
I decorated control_work_handler() with a "lifetime" marker,=A0and
passedthis value to handle_control_message(), so we can see which
control
messages are being handled from which instance of
thecontrol_work_handler() thread.
Notice that we enter control_work_handler() a second time before
thehandling of the second PORT_ADD message is complete. The
firstCONSOLE_PORT message is handled by the second
control_work_handler()call, but the second is handled by the first
control_work_handler() call.

root@myubuntu:~# dmesg | grep MBH[3371055.808738]
control_work_handler #1[3371055.809372] + #1 handle_control_message
PORT_ADD[3371055.810169] - handle_control_message
PORT_ADD[3371055.810170] + #1 handle_control_message PORT_ADD
[3371055.810244] =A0control_work_handler #2[3371055.810245] + #2
handle_control_message CONSOLE_PORT[3371055.810246] =A0got
hvc_ports_mutex[3371055.810578] - handle_control_message
PORT_ADD[3371055.810579] + #1 handle_control_message
CONSOLE_PORT[3371055.810580] =A0trylock of hvc_ports_mutex
failed[3371055.811352] =A0got hvc_ports_mutex[3371055.811370] -
handle_control_message CONSOLE_PORT[3371055.816609] -
handle_control_message CONSOLE_PORT=A0=A0So, I'm guessing the bug is that
there shouldn't be two instances ofcontrol_work_handler() running
simultaneously?
Thanks,
Miche

Protocol:We set up the virtio console device registers during
initialization,specifying the multiport feature, and some number of
ports, n, where nis greater than 1.
In the guest, virtcons_probe() finds our device, and successfully
sendsthe VIRTIO_CONSOLE_DEVICE_READY=3D1 control message.
On the host, we receive the VIRTIO_CONSOLE_DEVICE_READY message,
andsend one VIRTIO_CONSOLE_PORT_ADD message via the Receive Control
queuefor each port in the number of ports. =A0These messages are
notserialized: they are all sent at once.
The VIRTIO_CONSOLE_PORT_ADD messages are received
inhandle_control_message() in virtio_console.c, and add_port() is
calledfor each. =A0After each port is added, the guest
sendsVIRTIO_CONSOLE_PORT_READY to the host, and in these messages, the
idof the port is included in the message.
On the host, in response to each VIRTIO_CONSOLE_PORT_READY=3D1
message,we may send a VIRTIO_CONSOLE_CONSOLE_PORT message.
On the guest, in response to each VIRTIO_CONSOLE_CONSOLE_PORT
message,init_port_console() is called on the individual port. =A0The
same id isused for these messages as was used for the PORT_READY
messages.
After each successful init_port_console(), the guest
sendsVIRTIO_CONSOLE_PORT_OPEN back to the host.

On Tue, Nov 29, 2011 at 6:21 AM, Amit Shah <amit.shah@redhat.com> wrote:
> Hi,
>
> On (Mon) 28 Nov 2011 [15:40:41], Miche Baker-Harvey wrote:
>> Amit,
>>
>> You said that the work would be serialized "due to port additions
>> being on work items on the same workqueue". =A0I'm not seeing that.
>
> You leave a lot of questions unanswered. =A0What's your environment?
> Are you hot-plugging ports? =A0Are you using qemu? =A0What's your command
> line?
>
>> I've double checked this by using a mutex_trylock in
>> hvc_console::hvc_alloc(), and here's the relevant output from dmesg:
>>
>> root@myubuntu:~# dmesg | grep MBH
>> [3307216.210274] MBH: got hvc_ports_mutex
>> [3307216.210690] MBH: trylock of hvc_ports_mutex failed
>> [3307216.211143] MBH: got hvc_ports_mutex
>>
>> This is in a system with two virtio console ports, each of which is a
>> console. =A0I think if the VIRTIO_CONSOLE_CONSOLE_PORT message handling
>> were actually being serialized, the trylock should never fail.
>
> Agreed.
>
>> What's the source of the serialization for the workqueue items? =A0At
>> first reading it looks like the control_work_handler gets called for
>> each virtio interrupt?
>
> It all depends on how you add ports. =A0If you're using qemu, they
> happen via the control work handler.
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Amit
>

^ permalink raw reply

* Re: [PATCH][RFC] fsldma: fix performance degradation by optimizing spinlock use.
From: Ira W. Snyder @ 2011-11-29 17:25 UTC (permalink / raw)
  To: Li Yang-R58472
  Cc: vinod.koul@intel.com, Shi Xuelin-B29237,
	linuxppc-dev@lists.ozlabs.org, dan.j.williams@intel.com,
	linux-kernel@vger.kernel.org
In-Reply-To: <3F607A5180246847A760FD34122A1E052E07B7@039-SN1MPN1-003.039d.mgd.msft.net>

On Tue, Nov 29, 2011 at 03:19:05AM +0000, Li Yang-R58472 wrote:
> > Subject: Re: [PATCH][RFC] fsldma: fix performance degradation by optimizing
> > spinlock use.
> > 
> > On Thu, Nov 24, 2011 at 08:12:25AM +0000, Shi Xuelin-B29237 wrote:
> > > Hi Ira,
> > >
> > > Thanks for your review.
> > >
> > > After second thought, I think your scenario may not occur.
> > > Because the cookie 20 we query must be returned by fsl_dma_tx_submit(...) in
> > practice.
> > > We never query a cookie not returned by fsl_dma_tx_submit(...).
> > >
> > 
> > I agree about this part.
> > 
> > > When we call fsl_tx_status(20), the chan->common.cookie is definitely wrote as
> > 20 and cpu2 could not read as 19.
> > >
> > 
> > This is what I don't agree about. However, I'm not an expert on CPU cache vs.
> > memory accesses in an multi-processor system. The section titled "CACHE
> > COHERENCY" in Documentation/memory-barriers.txt leads me to believe that the
> > scenario I described is possible.
> 
> For Freescale PowerPC, the chip automatically takes care of cache coherency.  Even if this is a concern, spinlock can't address it.
> 
> > 
> > What happens if CPU1's write of chan->common.cookie only goes into CPU1's
> > cache. It never makes it to main memory before CPU2 fetches the old value of 19.
> > 
> > I don't think you should see any performance impact from the smp_mb()
> > operation.
> 
> Smp_mb() do have impact on performance if it's in the hot path.  While it might be safer having it, I doubt it is really necessary.  If the CPU1 doesn't have the updated last_used, it's shouldn't have known there is a cookie 20 existed either.
> 

I believe that you are correct, for powerpc. However, anything outside
of arch/powerpc shouldn't assume it only runs on powerpc. I wouldn't be
surprised to see fsldma running on an iMX someday (ARM processor).

My interpretation says that the change introduces the possibility that
fsl_tx_status() returns the wrong answer for an extremely small time
window, on SMP only, based on Documentation/memory-barriers.txt. But I
can't seem convince you.

My real question is what code path is hitting this spinlock? Is it in
mainline Linux? Why is it polling rather than using callbacks to
determine DMA completion?

Thanks,
Ira

> > > -----Original Message-----
> > > From: Ira W. Snyder [mailto:iws@ovro.caltech.edu]
> > > Sent: 2011年11月23日 2:59
> > > To: Shi Xuelin-B29237
> > > Cc: dan.j.williams@intel.com; Li Yang-R58472; zw@zh-kernel.org;
> > > vinod.koul@intel.com; linuxppc-dev@lists.ozlabs.org;
> > > linux-kernel@vger.kernel.org
> > > Subject: Re: [PATCH][RFC] fsldma: fix performance degradation by optimizing
> > spinlock use.
> > >
> > > On Tue, Nov 22, 2011 at 12:55:05PM +0800, b29237@freescale.com wrote:
> > > > From: Forrest Shi <b29237@freescale.com>
> > > >
> > > >     dma status check function fsl_tx_status is heavily called in
> > > >     a tight loop and the desc lock in fsl_tx_status contended by
> > > >     the dma status update function. this caused the dma performance
> > > >     degrades much.
> > > >
> > > >     this patch releases the lock in the fsl_tx_status function.
> > > >     I believe it has no neglect impact on the following call of
> > > >     dma_async_is_complete(...).
> > > >
> > > >     we can see below three conditions will be identified as success
> > > >     a)  x < complete < use
> > > >     b)  x < complete+N < use+N
> > > >     c)  x < complete < use+N
> > > >     here complete is the completed_cookie, use is the last_used
> > > >     cookie, x is the querying cookie, N is MAX cookie
> > > >
> > > >     when chan->completed_cookie is being read, the last_used may
> > > >     be incresed. Anyway it has no neglect impact on the dma status
> > > >     decision.
> > > >
> > > >     Signed-off-by: Forrest Shi <xuelin.shi@freescale.com>
> > > > ---
> > > >  drivers/dma/fsldma.c |    5 -----
> > > >  1 files changed, 0 insertions(+), 5 deletions(-)
> > > >
> > > > diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index
> > > > 8a78154..1dca56f 100644
> > > > --- a/drivers/dma/fsldma.c
> > > > +++ b/drivers/dma/fsldma.c
> > > > @@ -986,15 +986,10 @@ static enum dma_status fsl_tx_status(struct
> > dma_chan *dchan,
> > > >  	struct fsldma_chan *chan = to_fsl_chan(dchan);
> > > >  	dma_cookie_t last_complete;
> > > >  	dma_cookie_t last_used;
> > > > -	unsigned long flags;
> > > > -
> > > > -	spin_lock_irqsave(&chan->desc_lock, flags);
> > > >
> > >
> > > This will cause a bug. See below for a detailed explanation. You need this instead:
> > >
> > > 	/*
> > > 	 * On an SMP system, we must ensure that this CPU has seen the
> > > 	 * memory accesses performed by another CPU under the
> > > 	 * chan->desc_lock spinlock.
> > > 	 */
> > > 	smp_mb();
> > > >  	last_complete = chan->completed_cookie;
> > > >  	last_used = dchan->cookie;
> > > >
> > > > -	spin_unlock_irqrestore(&chan->desc_lock, flags);
> > > > -
> > > >  	dma_set_tx_state(txstate, last_complete, last_used, 0);
> > > >  	return dma_async_is_complete(cookie, last_complete, last_used);  }
> > >
> > > Facts:
> > > - dchan->cookie is the same member as chan->common.cookie (same memory
> > > location)
> > > - chan->common.cookie is the "last allocated cookie for a pending transaction"
> > > - chan->completed_cookie is the "last completed transaction"
> > >
> > > I have replaced "dchan->cookie" with "chan->common.cookie" in the below
> > explanation, to keep everything referenced from the same structure.
> > >
> > > Variable usage before your change. Everything is used locked.
> > > - RW chan->common.cookie		(fsl_dma_tx_submit)
> > > - R  chan->common.cookie		(fsl_tx_status)
> > > - R  chan->completed_cookie		(fsl_tx_status)
> > > - W  chan->completed_cookie		(dma_do_tasklet)
> > >
> > > Variable usage after your change:
> > > - RW chan->common.cookie		LOCKED
> > > - R  chan->common.cookie		NO LOCK
> > > - R  chan->completed_cookie		NO LOCK
> > > - W  chan->completed_cookie             LOCKED
> > >
> > > What if we assume that you have a 2 CPU system (such as a P2020). After your
> > changes, one possible sequence is:
> > >
> > > === CPU1 - allocate + submit descriptor: fsl_dma_tx_submit() ===
> > > spin_lock_irqsave
> > > descriptor->cookie = 20		(x in your example)
> > > chan->common.cookie = 20	(used in your example)
> > > spin_unlock_irqrestore
> > >
> > > === CPU2 - immediately calls fsl_tx_status() ===
> > > chan->common.cookie == 19
> > > chan->completed_cookie == 19
> > > descriptor->cookie == 20
> > >
> > > Since we don't have locks anymore, CPU2 may not have seen the write to
> > > chan->common.cookie yet.
> > >
> > > Also assume that the DMA hardware has not started processing the
> > > transaction yet. Therefore dma_do_tasklet() has not been called, and
> > > chan->completed_cookie has not been updated.
> > >
> > > In this case, dma_async_is_complete() (on CPU2) returns DMA_SUCCESS, even
> > though the DMA operation has not succeeded. The DMA operation has not even
> > started yet!
> > >
> > > The smp_mb() fixes this, since it forces CPU2 to have seen all memory operations
> > that happened before CPU1 released the spinlock. Spinlocks are implicit SMP
> > memory barriers.
> > >
> > > Therefore, the above example becomes:
> > > smp_mb();
> > > chan->common.cookie == 20
> > > chan->completed_cookie == 19
> > > descriptor->cookie == 20
> > >
> > > Then dma_async_is_complete() returns DMA_IN_PROGRESS, which is correct.
> > >
> > > Thanks,
> > > Ira
> > >
> > >
> > > _______________________________________________
> > > Linuxppc-dev mailing list
> > > Linuxppc-dev@lists.ozlabs.org
> > > https://lists.ozlabs.org/listinfo/linuxppc-dev
> 

^ permalink raw reply

* Re: [PATCH v3 2/3] hvc_init(): Enforce one-time initialization.
From: Miche Baker-Harvey @ 2011-11-29 17:50 UTC (permalink / raw)
  To: Amit Shah
  Cc: Stephen Rothwell, xen-devel, Konrad Rzeszutek Wilk, Rusty Russell,
	linux-kernel, virtualization, Anton Blanchard, Mike Waychison,
	ppc-dev, Greg Kroah-Hartman, Eric Northrup
In-Reply-To: <CAB8RdapuPRym2dH_9mgmGdzpCxnP1KpS+hS8JJ-geVkga5fMcw@mail.gmail.com>

Good grief!  Sorry for the spacing mess-up!  Here's a resend with reformatting.

Amit,
We aren't using either QEMU or kvmtool, but we are using KVM.  All
the issues we are seeing happen when we try to establish multiple
virtioconsoles at boot time.  The command line isn't relevant, but I
can tell you the protocol that's passing between the host (kvm) and
the guest (see the end of this message).

We do go through the control_work_handler(), but it's not
providing synchronization.  Here's a trace of the
control_work_handler() and handle_control_message() calls; note that
there are two concurrent calls to control_work_handler().

I decorated control_work_handler() with a "lifetime" marker, and
passed this value to handle_control_message(), so we can see which
control messages are being handled from which instance of
the control_work_handler() thread.

Notice that we enter control_work_handler() a second time before
the handling of the second PORT_ADD message is complete. The
first CONSOLE_PORT message is handled by the second
control_work_handler() call, but the second is handled by the first
control_work_handler() call.

root@myubuntu:~# dmesg | grep MBH
[3371055.808738] control_work_handler #1
[3371055.809372] + #1 handle_control_message PORT_ADD
[3371055.810169] - handle_control_message PORT_ADD
[3371055.810170] + #1 handle_control_message PORT_ADD
[3371055.810244]  control_work_handler #2
[3371055.810245] + #2 handle_control_message CONSOLE_PORT
[3371055.810246]  got hvc_ports_mutex
[3371055.810578] - handle_control_message PORT_ADD
[3371055.810579] + #1 handle_control_message CONSOLE_PORT
[3371055.810580]  trylock of hvc_ports_mutex failed
[3371055.811352]  got hvc_ports_mutex
[3371055.811370] - handle_control_message CONSOLE_PORT
[3371055.816609] - handle_control_message CONSOLE_PORT

So, I'm guessing the bug is that there shouldn't be two instances of
control_work_handler() running simultaneously?

Thanks,

Miche

Protocol:
We set up the virtio console device registers during initialization,
specifying the multiport feature, and some number of
ports, n, where nis greater than 1.

In the guest, virtcons_probe() finds our device, and successfully
sends the VIRTIO_CONSOLE_DEVICE_READY=1 control message.
On the host, we receive the VIRTIO_CONSOLE_DEVICE_READY message,
and send one VIRTIO_CONSOLE_PORT_ADD message via the Receive Control
queuefor each port in the number of ports.  These messages are
not serialized: they are all sent at once.

The VIRTIO_CONSOLE_PORT_ADD messages are received
in handle_control_message() in virtio_console.c, and add_port() is
called for each.  After each port is added, the guest
sendsVIRTIO_CONSOLE_PORT_READY to the host, and in these messages, the
id of the port is included in the message.

On the host, in response to each VIRTIO_CONSOLE_PORT_READY=1
message, we may send a VIRTIO_CONSOLE_CONSOLE_PORT message.
On the guest, in response to each VIRTIO_CONSOLE_CONSOLE_PORT
message, init_port_console() is called on the individual port.  The
same id is used for these messages as was used for the PORT_READY
messages.

After each successful init_port_console(), the guest
sends VIRTIO_CONSOLE_PORT_OPEN back to the host.

^ permalink raw reply

* Re: [PATCH 2/6] powerpc/85xx: consolidate of_platform_bus_probe calls
From: Timur Tabi @ 2011-11-29 18:52 UTC (permalink / raw)
  To: Kumar Gala
  Cc: Dmitry Eremin-Solenikov, Gala Kumar-B11780,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <2C30517A-CF00-455A-ABE4-CA92A8856C70@kernel.crashing.org>

Kumar Gala wrote:
> Ben would probably have to answer that.  I can't remember why he wanted it.  I'm sure he has a good reason.

Well, I'm not sure what's going on with the code.  I *think* what's happening is that the first call of_platform_bus_probe() is scanning most, but not all, of the tree, and it's somehow reserving all of those nodes.  Then we call of_platform_bus_probe() again, but it never finds the DMA nodes.  of_platform_bus_probe() never actually calls of_platform_bus_create() this time around.  Perhaps the recursive nature of of_platform_bus_create() is part of the problem.

The only fix I can think of is to move "fsl,eloplus-dma" into mpc85xx_common_ids[].  I'll post a patch that does that, and we can discuss it.

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply

* [PATCH 00/10] powerpc/mpic: General cleanup patch series
From: Kyle Moffett @ 2011-11-29 18:58 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev

Hello,

As BenH requested, this is the version-2 repost of the PowerPC MPIC
cleanup patch series.

All of the review comments have been addressed, and I have performed
build and boot testing on our HWW-1U-1A hardware with these patches
applied (plus a few independent board-support patches).

Unfortunately, this has a potentially very broad impact across a wide
variety of hardware that I don't have the ability to test with, so
any additional testing will be highly appreciated.  Ben has indicated
that he plans to put it into his testing tree soon, so hopefully any
such issues will get ironed out quickly.

Cheers,
Kyle Moffett

^ permalink raw reply

* [PATCH 01/10] powerpc/85xx: Move mpc85xx_smp_init() decl to a new "smp.h"
From: Kyle Moffett @ 2011-11-29 18:58 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Paul Mackerras, linuxppc-dev, Kyle Moffett
In-Reply-To: <1322593117-29938-1-git-send-email-Kyle.D.Moffett@boeing.com>

This removes a bunch of "extern" declarations and CONFIG_SMP ifdefs.

Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Kumar Gala <galak@kernel.crashing.org>
---
 arch/powerpc/platforms/85xx/corenet_ds.c  |    7 +------
 arch/powerpc/platforms/85xx/mpc85xx_ds.c  |    6 +-----
 arch/powerpc/platforms/85xx/mpc85xx_mds.c |    7 +------
 arch/powerpc/platforms/85xx/mpc85xx_rdb.c |    7 +------
 arch/powerpc/platforms/85xx/p1022_ds.c    |    7 +------
 arch/powerpc/platforms/85xx/p1023_rds.c   |    7 +------
 arch/powerpc/platforms/85xx/smp.c         |    1 +
 arch/powerpc/platforms/85xx/smp.h         |   15 +++++++++++++++
 arch/powerpc/platforms/85xx/xes_mpc85xx.c |    6 +-----
 9 files changed, 23 insertions(+), 40 deletions(-)
 create mode 100644 arch/powerpc/platforms/85xx/smp.h

diff --git a/arch/powerpc/platforms/85xx/corenet_ds.c b/arch/powerpc/platforms/85xx/corenet_ds.c
index 802ad11..435074d 100644
--- a/arch/powerpc/platforms/85xx/corenet_ds.c
+++ b/arch/powerpc/platforms/85xx/corenet_ds.c
@@ -31,6 +31,7 @@
 #include <linux/of_platform.h>
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
+#include "smp.h"
 
 void __init corenet_ds_pic_init(void)
 {
@@ -65,10 +66,6 @@ void __init corenet_ds_pic_init(void)
 /*
  * Setup the architecture
  */
-#ifdef CONFIG_SMP
-void __init mpc85xx_smp_init(void);
-#endif
-
 void __init corenet_ds_setup_arch(void)
 {
 #ifdef CONFIG_PCI
@@ -77,9 +74,7 @@ void __init corenet_ds_setup_arch(void)
 #endif
 	dma_addr_t max = 0xffffffff;
 
-#ifdef CONFIG_SMP
 	mpc85xx_smp_init();
-#endif
 
 #ifdef CONFIG_PCI
 	for_each_node_by_type(np, "pci") {
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index 1b9a8cf..52d2a3e 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -35,6 +35,7 @@
 
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
+#include "smp.h"
 
 #undef DEBUG
 
@@ -152,9 +153,6 @@ static int mpc85xx_exclude_device(struct pci_controller *hose,
 /*
  * Setup the architecture
  */
-#ifdef CONFIG_SMP
-extern void __init mpc85xx_smp_init(void);
-#endif
 static void __init mpc85xx_ds_setup_arch(void)
 {
 #ifdef CONFIG_PCI
@@ -187,9 +185,7 @@ static void __init mpc85xx_ds_setup_arch(void)
 	ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 #endif
 
-#ifdef CONFIG_SMP
 	mpc85xx_smp_init();
-#endif
 
 #ifdef CONFIG_SWIOTLB
 	if (memblock_end_of_DRAM() > max) {
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index a23a3ff..e4d470e 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -51,6 +51,7 @@
 #include <asm/qe_ic.h>
 #include <asm/mpic.h>
 #include <asm/swiotlb.h>
+#include "smp.h"
 
 #undef DEBUG
 #ifdef DEBUG
@@ -153,10 +154,6 @@ static int mpc8568_mds_phy_fixups(struct phy_device *phydev)
  * Setup the architecture
  *
  */
-#ifdef CONFIG_SMP
-extern void __init mpc85xx_smp_init(void);
-#endif
-
 #ifdef CONFIG_QUICC_ENGINE
 static struct of_device_id mpc85xx_qe_ids[] __initdata = {
 	{ .type = "qe", },
@@ -381,9 +378,7 @@ static void __init mpc85xx_mds_setup_arch(void)
 	}
 #endif
 
-#ifdef CONFIG_SMP
 	mpc85xx_smp_init();
-#endif
 
 	mpc85xx_mds_qe_init();
 
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
index f5ff911..cd49898 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
@@ -29,6 +29,7 @@
 
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
+#include "smp.h"
 
 #undef DEBUG
 
@@ -82,9 +83,6 @@ void __init mpc85xx_rdb_pic_init(void)
 /*
  * Setup the architecture
  */
-#ifdef CONFIG_SMP
-extern void __init mpc85xx_smp_init(void);
-#endif
 static void __init mpc85xx_rdb_setup_arch(void)
 {
 #ifdef CONFIG_PCI
@@ -102,10 +100,7 @@ static void __init mpc85xx_rdb_setup_arch(void)
 
 #endif
 
-#ifdef CONFIG_SMP
 	mpc85xx_smp_init();
-#endif
-
 	printk(KERN_INFO "MPC85xx RDB board from Freescale Semiconductor\n");
 }
 
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index fda1571..089b959 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -26,6 +26,7 @@
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
 #include <asm/fsl_guts.h>
+#include "smp.h"
 
 #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
 
@@ -266,10 +267,6 @@ void __init p1022_ds_pic_init(void)
 	mpic_init(mpic);
 }
 
-#ifdef CONFIG_SMP
-void __init mpc85xx_smp_init(void);
-#endif
-
 /*
  * Setup the architecture
  */
@@ -309,9 +306,7 @@ static void __init p1022_ds_setup_arch(void)
 	diu_ops.valid_monitor_port	= p1022ds_valid_monitor_port;
 #endif
 
-#ifdef CONFIG_SMP
 	mpc85xx_smp_init();
-#endif
 
 #ifdef CONFIG_SWIOTLB
 	if (memblock_end_of_DRAM() > max) {
diff --git a/arch/powerpc/platforms/85xx/p1023_rds.c b/arch/powerpc/platforms/85xx/p1023_rds.c
index 835e0b3..da546ea 100644
--- a/arch/powerpc/platforms/85xx/p1023_rds.c
+++ b/arch/powerpc/platforms/85xx/p1023_rds.c
@@ -30,6 +30,7 @@
 #include <asm/prom.h>
 #include <asm/udbg.h>
 #include <asm/mpic.h>
+#include "smp.h"
 
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
@@ -39,10 +40,6 @@
  * Setup the architecture
  *
  */
-#ifdef CONFIG_SMP
-void __init mpc85xx_smp_init(void);
-#endif
-
 static void __init mpc85xx_rds_setup_arch(void)
 {
 	struct device_node *np;
@@ -87,9 +84,7 @@ static void __init mpc85xx_rds_setup_arch(void)
 		fsl_add_bridge(np, 0);
 #endif
 
-#ifdef CONFIG_SMP
 	mpc85xx_smp_init();
-#endif
 }
 
 static struct of_device_id p1023_ids[] = {
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index 2df4785..ff42490 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -27,6 +27,7 @@
 
 #include <sysdev/fsl_soc.h>
 #include <sysdev/mpic.h>
+#include "smp.h"
 
 extern void __early_start(void);
 
diff --git a/arch/powerpc/platforms/85xx/smp.h b/arch/powerpc/platforms/85xx/smp.h
new file mode 100644
index 0000000..e2b4493
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/smp.h
@@ -0,0 +1,15 @@
+#ifndef POWERPC_85XX_SMP_H_
+#define POWERPC_85XX_SMP_H_ 1
+
+#include <linux/init.h>
+
+#ifdef CONFIG_SMP
+void __init mpc85xx_smp_init(void);
+#else
+static inline void mpc85xx_smp_init(void)
+{
+	/* Nothing to do */
+}
+#endif
+
+#endif /* not POWERPC_85XX_SMP_H_ */
diff --git a/arch/powerpc/platforms/85xx/xes_mpc85xx.c b/arch/powerpc/platforms/85xx/xes_mpc85xx.c
index a9dc5e7..ce3f660 100644
--- a/arch/powerpc/platforms/85xx/xes_mpc85xx.c
+++ b/arch/powerpc/platforms/85xx/xes_mpc85xx.c
@@ -32,6 +32,7 @@
 
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
+#include "smp.h"
 
 /* A few bit definitions needed for fixups on some boards */
 #define MPC85xx_L2CTL_L2E		0x80000000 /* L2 enable */
@@ -136,9 +137,6 @@ static int primary_phb_addr;
 /*
  * Setup the architecture
  */
-#ifdef CONFIG_SMP
-extern void __init mpc85xx_smp_init(void);
-#endif
 static void __init xes_mpc85xx_setup_arch(void)
 {
 #ifdef CONFIG_PCI
@@ -172,9 +170,7 @@ static void __init xes_mpc85xx_setup_arch(void)
 	}
 #endif
 
-#ifdef CONFIG_SMP
 	mpc85xx_smp_init();
-#endif
 }
 
 static struct of_device_id __initdata xes_mpc85xx_ids[] = {
-- 
1.7.2.5

^ permalink raw reply related

* [PATCH 02/10] powerpc: Consolidate mpic_alloc() OF address translation
From: Kyle Moffett @ 2011-11-29 18:58 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Paul Mackerras, Kyle Moffett, linuxppc-dev
In-Reply-To: <1322593117-29938-1-git-send-email-Kyle.D.Moffett@boeing.com>

Instead of using the open-coded "reg" property lookup and address
translation in mpic_alloc(), directly call of_address_to_resource().
This includes various workarounds for special cases which the naive
of_address_translate() does not.

Afterwards it is possible to remove the copiously copy-pasted calls to
of_address_translate() from the 85xx/86xx/powermac platforms.

Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Kumar Gala <galak@kernel.crashing.org>
---
 arch/powerpc/platforms/85xx/corenet_ds.c  |    9 +----
 arch/powerpc/platforms/85xx/ksi8560.c     |    9 +----
 arch/powerpc/platforms/85xx/mpc8536_ds.c  |    9 +----
 arch/powerpc/platforms/85xx/mpc85xx_ads.c |    9 +----
 arch/powerpc/platforms/85xx/mpc85xx_cds.c |    9 +----
 arch/powerpc/platforms/85xx/mpc85xx_ds.c  |   11 +----
 arch/powerpc/platforms/85xx/mpc85xx_mds.c |    9 +----
 arch/powerpc/platforms/85xx/mpc85xx_rdb.c |   11 +----
 arch/powerpc/platforms/85xx/p1010rdb.c    |    9 +----
 arch/powerpc/platforms/85xx/p1022_ds.c    |    9 +----
 arch/powerpc/platforms/85xx/p1023_rds.c   |    9 +----
 arch/powerpc/platforms/85xx/sbc8548.c     |    9 +----
 arch/powerpc/platforms/85xx/sbc8560.c     |    9 +----
 arch/powerpc/platforms/85xx/socrates.c    |    9 +----
 arch/powerpc/platforms/85xx/stx_gp3.c     |    9 +----
 arch/powerpc/platforms/85xx/tqm85xx.c     |    9 +----
 arch/powerpc/platforms/85xx/xes_mpc85xx.c |    9 +----
 arch/powerpc/platforms/86xx/pic.c         |    4 +-
 arch/powerpc/platforms/powermac/pic.c     |    7 +---
 arch/powerpc/sysdev/mpic.c                |   61 ++++++++++++++++-------------
 20 files changed, 55 insertions(+), 174 deletions(-)

diff --git a/arch/powerpc/platforms/85xx/corenet_ds.c b/arch/powerpc/platforms/85xx/corenet_ds.c
index 435074d..7893ad3 100644
--- a/arch/powerpc/platforms/85xx/corenet_ds.c
+++ b/arch/powerpc/platforms/85xx/corenet_ds.c
@@ -36,7 +36,6 @@
 void __init corenet_ds_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np = NULL;
 	unsigned int flags = MPIC_PRIMARY | MPIC_BIG_ENDIAN |
 				MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU;
@@ -48,16 +47,10 @@ void __init corenet_ds_pic_init(void)
 		return;
 	}
 
-	if (of_address_to_resource(np, 0, &r)) {
-		printk(KERN_ERR "Failed to map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
 	if (ppc_md.get_irq == mpic_get_coreint_irq)
 		flags |= MPIC_ENABLE_COREINT;
 
-	mpic = mpic_alloc(np, r.start, flags, 0, 256, " OpenPIC  ");
+	mpic = mpic_alloc(np, 0, flags, 0, 256, " OpenPIC  ");
 	BUG_ON(mpic == NULL);
 
 	mpic_init(mpic);
diff --git a/arch/powerpc/platforms/85xx/ksi8560.c b/arch/powerpc/platforms/85xx/ksi8560.c
index c46f935..b20c07d 100644
--- a/arch/powerpc/platforms/85xx/ksi8560.c
+++ b/arch/powerpc/platforms/85xx/ksi8560.c
@@ -68,7 +68,6 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
 static void __init ksi8560_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np;
 #ifdef CONFIG_CPM2
 	int irq;
@@ -81,13 +80,7 @@ static void __init ksi8560_pic_init(void)
 		return;
 	}
 
-	if (of_address_to_resource(np, 0, &r)) {
-		printk(KERN_ERR "Could not map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
-	mpic = mpic_alloc(np, r.start,
+	mpic = mpic_alloc(np, 0,
 			MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
 			0, 256, " OpenPIC  ");
 	BUG_ON(mpic == NULL);
diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c
index f79f2f1..03173ba 100644
--- a/arch/powerpc/platforms/85xx/mpc8536_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c
@@ -35,7 +35,6 @@
 void __init mpc8536_ds_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np;
 
 	np = of_find_node_by_type(NULL, "open-pic");
@@ -44,13 +43,7 @@ void __init mpc8536_ds_pic_init(void)
 		return;
 	}
 
-	if (of_address_to_resource(np, 0, &r)) {
-		printk(KERN_ERR "Failed to map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
-	mpic = mpic_alloc(np, r.start,
+	mpic = mpic_alloc(np, 0,
 			  MPIC_PRIMARY | MPIC_WANTS_RESET |
 			  MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
 			0, 256, " OpenPIC  ");
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index 3b2c9bb..5cb797b 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -64,7 +64,6 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
 static void __init mpc85xx_ads_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np = NULL;
 #ifdef CONFIG_CPM2
 	int irq;
@@ -76,13 +75,7 @@ static void __init mpc85xx_ads_pic_init(void)
 		return;
 	}
 
-	if (of_address_to_resource(np, 0, &r)) {
-		printk(KERN_ERR "Could not map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
-	mpic = mpic_alloc(np, r.start,
+	mpic = mpic_alloc(np, 0,
 			MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
 			0, 256, " OpenPIC  ");
 	BUG_ON(mpic == NULL);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 66cb8d6..3e65336 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -186,7 +186,6 @@ static struct irqaction mpc85xxcds_8259_irqaction = {
 static void __init mpc85xx_cds_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np = NULL;
 
 	np = of_find_node_by_type(np, "open-pic");
@@ -196,13 +195,7 @@ static void __init mpc85xx_cds_pic_init(void)
 		return;
 	}
 
-	if (of_address_to_resource(np, 0, &r)) {
-		printk(KERN_ERR "Failed to map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
-	mpic = mpic_alloc(np, r.start,
+	mpic = mpic_alloc(np, 0,
 			MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
 			0, 256, " OpenPIC  ");
 	BUG_ON(mpic == NULL);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index 52d2a3e..b608da7 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -61,7 +61,6 @@ static void mpc85xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
 void __init mpc85xx_ds_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np;
 #ifdef CONFIG_PPC_I8259
 	struct device_node *cascade_node = NULL;
@@ -75,20 +74,14 @@ void __init mpc85xx_ds_pic_init(void)
 		return;
 	}
 
-	if (of_address_to_resource(np, 0, &r)) {
-		printk(KERN_ERR "Failed to map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
 	if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS-CAMP")) {
-		mpic = mpic_alloc(np, r.start,
+		mpic = mpic_alloc(np, 0,
 			MPIC_PRIMARY |
 			MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
 			MPIC_SINGLE_DEST_CPU,
 			0, 256, " OpenPIC  ");
 	} else {
-		mpic = mpic_alloc(np, r.start,
+		mpic = mpic_alloc(np, 0,
 			  MPIC_PRIMARY | MPIC_WANTS_RESET |
 			  MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
 			  MPIC_SINGLE_DEST_CPU,
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index e4d470e..f2f7527 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -474,20 +474,13 @@ machine_arch_initcall(p1021_mds, swiotlb_setup_bus_notifier);
 static void __init mpc85xx_mds_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np = NULL;
 
 	np = of_find_node_by_type(NULL, "open-pic");
 	if (!np)
 		return;
 
-	if (of_address_to_resource(np, 0, &r)) {
-		printk(KERN_ERR "Failed to map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
-	mpic = mpic_alloc(np, r.start,
+	mpic = mpic_alloc(np, 0,
 			MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN |
 			MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU,
 			0, 256, " OpenPIC  ");
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
index cd49898..67bd1d4 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
@@ -43,7 +43,6 @@
 void __init mpc85xx_rdb_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np;
 	unsigned long root = of_get_flat_dt_root();
 
@@ -53,20 +52,14 @@ void __init mpc85xx_rdb_pic_init(void)
 		return;
 	}
 
-	if (of_address_to_resource(np, 0, &r)) {
-		printk(KERN_ERR "Failed to map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
 	if (of_flat_dt_is_compatible(root, "fsl,MPC85XXRDB-CAMP")) {
-		mpic = mpic_alloc(np, r.start,
+		mpic = mpic_alloc(np, 0,
 			MPIC_PRIMARY |
 			MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
 			MPIC_SINGLE_DEST_CPU,
 			0, 256, " OpenPIC  ");
 	} else {
-		mpic = mpic_alloc(np, r.start,
+		mpic = mpic_alloc(np, 0,
 		  MPIC_PRIMARY | MPIC_WANTS_RESET |
 		  MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
 		  MPIC_SINGLE_DEST_CPU,
diff --git a/arch/powerpc/platforms/85xx/p1010rdb.c b/arch/powerpc/platforms/85xx/p1010rdb.c
index d7387fa..2efcdcd 100644
--- a/arch/powerpc/platforms/85xx/p1010rdb.c
+++ b/arch/powerpc/platforms/85xx/p1010rdb.c
@@ -31,7 +31,6 @@
 void __init p1010_rdb_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np;
 
 	np = of_find_node_by_type(NULL, "open-pic");
@@ -40,13 +39,7 @@ void __init p1010_rdb_pic_init(void)
 		return;
 	}
 
-	if (of_address_to_resource(np, 0, &r)) {
-		printk(KERN_ERR "Failed to map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
-	mpic = mpic_alloc(np, r.start, MPIC_PRIMARY | MPIC_WANTS_RESET |
+	mpic = mpic_alloc(np, 0, MPIC_PRIMARY | MPIC_WANTS_RESET |
 	  MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU,
 	  0, 256, " OpenPIC  ");
 
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index 089b959..e840cc9 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -240,7 +240,6 @@ p1022ds_valid_monitor_port(enum fsl_diu_monitor_port port)
 void __init p1022_ds_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np;
 
 	np = of_find_node_by_type(NULL, "open-pic");
@@ -249,13 +248,7 @@ void __init p1022_ds_pic_init(void)
 		return;
 	}
 
-	if (of_address_to_resource(np, 0, &r)) {
-		pr_err("Failed to map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
-	mpic = mpic_alloc(np, r.start,
+	mpic = mpic_alloc(np, 0,
 		MPIC_PRIMARY | MPIC_WANTS_RESET |
 		MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
 		MPIC_SINGLE_DEST_CPU,
diff --git a/arch/powerpc/platforms/85xx/p1023_rds.c b/arch/powerpc/platforms/85xx/p1023_rds.c
index da546ea..6988fab 100644
--- a/arch/powerpc/platforms/85xx/p1023_rds.c
+++ b/arch/powerpc/platforms/85xx/p1023_rds.c
@@ -107,7 +107,6 @@ machine_device_initcall(p1023_rds, p1023_publish_devices);
 static void __init mpc85xx_rds_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np = NULL;
 
 	np = of_find_node_by_type(NULL, "open-pic");
@@ -116,13 +115,7 @@ static void __init mpc85xx_rds_pic_init(void)
 		return;
 	}
 
-	if (of_address_to_resource(np, 0, &r)) {
-		printk(KERN_ERR "Failed to map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
-	mpic = mpic_alloc(np, r.start,
+	mpic = mpic_alloc(np, 0,
 		MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN |
 		MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU,
 		0, 256, " OpenPIC  ");
diff --git a/arch/powerpc/platforms/85xx/sbc8548.c b/arch/powerpc/platforms/85xx/sbc8548.c
index 14632a9..218761a 100644
--- a/arch/powerpc/platforms/85xx/sbc8548.c
+++ b/arch/powerpc/platforms/85xx/sbc8548.c
@@ -53,7 +53,6 @@ static int sbc_rev;
 static void __init sbc8548_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np = NULL;
 
 	np = of_find_node_by_type(np, "open-pic");
@@ -63,13 +62,7 @@ static void __init sbc8548_pic_init(void)
 		return;
 	}
 
-	if (of_address_to_resource(np, 0, &r)) {
-		printk(KERN_ERR "Failed to map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
-	mpic = mpic_alloc(np, r.start,
+	mpic = mpic_alloc(np, 0,
 			MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
 			0, 256, " OpenPIC  ");
 	BUG_ON(mpic == NULL);
diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c
index cebd786..6e3066a 100644
--- a/arch/powerpc/platforms/85xx/sbc8560.c
+++ b/arch/powerpc/platforms/85xx/sbc8560.c
@@ -55,7 +55,6 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
 static void __init sbc8560_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np = NULL;
 #ifdef CONFIG_CPM2
 	int irq;
@@ -67,13 +66,7 @@ static void __init sbc8560_pic_init(void)
 		return;
 	}
 
-	if (of_address_to_resource(np, 0, &r)) {
-		printk(KERN_ERR "Could not map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
-	mpic = mpic_alloc(np, r.start,
+	mpic = mpic_alloc(np, 0,
 			MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
 			0, 256, " OpenPIC  ");
 	BUG_ON(mpic == NULL);
diff --git a/arch/powerpc/platforms/85xx/socrates.c b/arch/powerpc/platforms/85xx/socrates.c
index 747d8fb..fb4bfd6 100644
--- a/arch/powerpc/platforms/85xx/socrates.c
+++ b/arch/powerpc/platforms/85xx/socrates.c
@@ -46,7 +46,6 @@
 static void __init socrates_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np;
 
 	np = of_find_node_by_type(NULL, "open-pic");
@@ -55,13 +54,7 @@ static void __init socrates_pic_init(void)
 		return;
 	}
 
-	if (of_address_to_resource(np, 0, &r)) {
-		printk(KERN_ERR "Could not map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
-	mpic = mpic_alloc(np, r.start,
+	mpic = mpic_alloc(np, 0,
 			MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
 			0, 256, " OpenPIC  ");
 	BUG_ON(mpic == NULL);
diff --git a/arch/powerpc/platforms/85xx/stx_gp3.c b/arch/powerpc/platforms/85xx/stx_gp3.c
index 5387e9f..78aef45 100644
--- a/arch/powerpc/platforms/85xx/stx_gp3.c
+++ b/arch/powerpc/platforms/85xx/stx_gp3.c
@@ -59,7 +59,6 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
 static void __init stx_gp3_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np;
 #ifdef CONFIG_CPM2
 	int irq;
@@ -71,13 +70,7 @@ static void __init stx_gp3_pic_init(void)
 		return;
 	}
 
-	if (of_address_to_resource(np, 0, &r)) {
-		printk(KERN_ERR "Could not map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
-	mpic = mpic_alloc(np, r.start,
+	mpic = mpic_alloc(np, 0,
 			MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
 			0, 256, " OpenPIC  ");
 	BUG_ON(mpic == NULL);
diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c
index 325de77..5775f4c 100644
--- a/arch/powerpc/platforms/85xx/tqm85xx.c
+++ b/arch/powerpc/platforms/85xx/tqm85xx.c
@@ -57,7 +57,6 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
 static void __init tqm85xx_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np;
 #ifdef CONFIG_CPM2
 	int irq;
@@ -69,13 +68,7 @@ static void __init tqm85xx_pic_init(void)
 		return;
 	}
 
-	if (of_address_to_resource(np, 0, &r)) {
-		printk(KERN_ERR "Could not map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
-	mpic = mpic_alloc(np, r.start,
+	mpic = mpic_alloc(np, 0,
 			MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
 			0, 256, " OpenPIC  ");
 	BUG_ON(mpic == NULL);
diff --git a/arch/powerpc/platforms/85xx/xes_mpc85xx.c b/arch/powerpc/platforms/85xx/xes_mpc85xx.c
index ce3f660..fccf9aa 100644
--- a/arch/powerpc/platforms/85xx/xes_mpc85xx.c
+++ b/arch/powerpc/platforms/85xx/xes_mpc85xx.c
@@ -42,7 +42,6 @@
 void __init xes_mpc85xx_pic_init(void)
 {
 	struct mpic *mpic;
-	struct resource r;
 	struct device_node *np;
 
 	np = of_find_node_by_type(NULL, "open-pic");
@@ -51,13 +50,7 @@ void __init xes_mpc85xx_pic_init(void)
 		return;
 	}
 
-	if (of_address_to_resource(np, 0, &r)) {
-		printk(KERN_ERR "Failed to map mpic register space\n");
-		of_node_put(np);
-		return;
-	}
-
-	mpic = mpic_alloc(np, r.start,
+	mpic = mpic_alloc(np, 0,
 			  MPIC_PRIMARY | MPIC_WANTS_RESET |
 			  MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
 			0, 256, " OpenPIC  ");
diff --git a/arch/powerpc/platforms/86xx/pic.c b/arch/powerpc/platforms/86xx/pic.c
index 8ef8960..f85c8f0 100644
--- a/arch/powerpc/platforms/86xx/pic.c
+++ b/arch/powerpc/platforms/86xx/pic.c
@@ -33,7 +33,6 @@ void __init mpc86xx_init_irq(void)
 {
 	struct mpic *mpic;
 	struct device_node *np;
-	struct resource res;
 #ifdef CONFIG_PPC_I8259
 	struct device_node *cascade_node = NULL;
 	int cascade_irq;
@@ -43,9 +42,8 @@ void __init mpc86xx_init_irq(void)
 	np = of_find_node_by_type(NULL, "open-pic");
 	if (np == NULL)
 		return;
-	of_address_to_resource(np, 0, &res);
 
-	mpic = mpic_alloc(np, res.start,
+	mpic = mpic_alloc(np, 0,
 			MPIC_PRIMARY | MPIC_WANTS_RESET |
 			MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
 			MPIC_SINGLE_DEST_CPU,
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 901bfbd..44f9774 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -498,15 +498,10 @@ static struct mpic * __init pmac_setup_one_mpic(struct device_node *np,
 						int master)
 {
 	const char *name = master ? " MPIC 1   " : " MPIC 2   ";
-	struct resource r;
 	struct mpic *mpic;
 	unsigned int flags = master ? MPIC_PRIMARY : 0;
 	int rc;
 
-	rc = of_address_to_resource(np, 0, &r);
-	if (rc)
-		return NULL;
-
 	pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0);
 
 	flags |= MPIC_WANTS_RESET;
@@ -519,7 +514,7 @@ static struct mpic * __init pmac_setup_one_mpic(struct device_node *np,
 	if (master && (flags & MPIC_BIG_ENDIAN))
 		flags |= MPIC_U3_HT_IRQS;
 
-	mpic = mpic_alloc(np, r.start, flags, 0, 0, name);
+	mpic = mpic_alloc(np, 0, flags, 0, 0, name);
 	if (mpic == NULL)
 		return NULL;
 
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 8c7e852..d68c9ca 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1142,7 +1142,24 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 	const char	*vers;
 	int		i;
 	int		intvec_top;
-	u64		paddr = phys_addr;
+
+	/*
+	 * If no phyiscal address was specified then all of the phyiscal
+	 * addressing parameters must come from the device-tree.
+	 */
+	if (!phys_addr) {
+		BUG_ON(!node);
+
+		/* Check if it is DCR-based */
+		if (of_get_property(node, "dcr-reg", NULL)) {
+			flags |= MPIC_USES_DCR;
+		} else {
+			struct resource r;
+			if (of_address_to_resource(node, 0, &r))
+				return NULL;
+			phys_addr = r.start;
+		}
+	}
 
 	mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL);
 	if (mpic == NULL)
@@ -1224,35 +1241,25 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 #endif
 
 	/* default register type */
-	mpic->reg_type = (flags & MPIC_BIG_ENDIAN) ?
-		mpic_access_mmio_be : mpic_access_mmio_le;
-
-	/* If no physical address is passed in, a device-node is mandatory */
-	BUG_ON(paddr == 0 && node == NULL);
+	if (flags & MPIC_BIG_ENDIAN)
+		mpic->reg_type = mpic_access_mmio_be;
+	else
+		mpic->reg_type = mpic_access_mmio_le;
 
-	/* If no physical address passed in, check if it's dcr based */
-	if (paddr == 0 && of_get_property(node, "dcr-reg", NULL) != NULL) {
+	/*
+	 * An MPIC with a "dcr-reg" property must be accessed that way, but
+	 * only if the kernel includes DCR support.
+	 */
 #ifdef CONFIG_PPC_DCR
-		mpic->flags |= MPIC_USES_DCR;
+	if (flags & MPIC_USES_DCR)
 		mpic->reg_type = mpic_access_dcr;
 #else
-		BUG();
-#endif /* CONFIG_PPC_DCR */
-	}
-
-	/* If the MPIC is not DCR based, and no physical address was passed
-	 * in, try to obtain one
-	 */
-	if (paddr == 0 && !(mpic->flags & MPIC_USES_DCR)) {
-		const u32 *reg = of_get_property(node, "reg", NULL);
-		BUG_ON(reg == NULL);
-		paddr = of_translate_address(node, reg);
-		BUG_ON(paddr == OF_BAD_ADDR);
-	}
+	BUG_ON(flags & MPIC_USES_DCR);
+#endif
 
 	/* Map the global registers */
-	mpic_map(mpic, node, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
-	mpic_map(mpic, node, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
+	mpic_map(mpic, node, phys_addr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
+	mpic_map(mpic, node, phys_addr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
 
 	/* Reset */
 
@@ -1307,7 +1314,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 	for_each_possible_cpu(i) {
 		unsigned int cpu = get_hard_smp_processor_id(i);
 
-		mpic_map(mpic, node, paddr, &mpic->cpuregs[cpu],
+		mpic_map(mpic, node, phys_addr, &mpic->cpuregs[cpu],
 			 MPIC_INFO(CPU_BASE) + cpu * MPIC_INFO(CPU_STRIDE),
 			 0x1000);
 	}
@@ -1315,7 +1322,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 	/* Initialize main ISU if none provided */
 	if (mpic->isu_size == 0) {
 		mpic->isu_size = mpic->num_sources;
-		mpic_map(mpic, node, paddr, &mpic->isus[0],
+		mpic_map(mpic, node, phys_addr, &mpic->isus[0],
 			 MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
 	}
 	mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
@@ -1347,7 +1354,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 	}
 	printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx,"
 	       " max %d CPUs\n",
-	       name, vers, (unsigned long long)paddr, num_possible_cpus());
+	       name, vers, (unsigned long long)phys_addr, num_possible_cpus());
 	printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n",
 	       mpic->isu_size, mpic->isu_shift, mpic->isu_mask);
 
-- 
1.7.2.5

^ 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