LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 1/6] Change RIO function mpc85xx_ to fsl_ .
From: Kumar Gala @ 2008-01-31  6:15 UTC (permalink / raw)
  To: Zhang Wei; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <ABF87B0B6A38C0458E319AC973ED68AEBD0683@zch01exm26.fsl.freescale.net>


On Jan 31, 2008, at 12:04 AM, Zhang Wei wrote:

> All right, I'll give you another patch for 86xx dts file. :)
>
> Btw: Why the PCI and other nodes were moved from SOC? Just for clear?
> If they are moved out, their register address must use full address  
> not
> offset address.

we did this because the feeling was the SOC node just represented the  
IMMR/CCSBAR registers, and not the address space used by the various  
busses.

(this is why pci, rio, and local bus all exist outside of the soc node).

- k

^ permalink raw reply

* Re: [PATCH 4/6] Add multi mport support.
From: Kumar Gala @ 2008-01-31  6:15 UTC (permalink / raw)
  To: Zhang Wei; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <ABF87B0B6A38C0458E319AC973ED68AEBD0677@zch01exm26.fsl.freescale.net>


On Jan 30, 2008, at 11:57 PM, Zhang Wei wrote:

>
>
>> -----Original Message-----
>> From: Kumar Gala [mailto:galak@kernel.crashing.org]
>>
>> On Jan 30, 2008, at 4:30 AM, Zhang Wei wrote:
>>
>>> Change lots of static variable to mport private. And add
>> mport to some
>>> function declaration.
>>
>> Can you explain this patch further.  Its not clear exactly from this
>> commit message why we are doing this.
>>
>> - k
>
> Sorry about I have a little hurry about it.
>
> The original RapidIO driver suppose there is only one mpc85xx RIO
> controller
> in system. So, some data structures are defined as mpc85xx_rio global,
> such as 'regs_win', 'dbell_ring', 'msg_tx_ring'. Now, I changed them  
> to
> mport's private members. And you can define multi RIO OF-nodes in dts
> file
> for multi RapidIO controller in one processor, such as PCI/PCI-Ex host
> controllers
> in Freescale's silicon. And the mport operation function declaration
> should be changed
> to know which RapidIO controller is target.

thanks, this makes a lot of sense and now reviewing the patch will  
make some sense to me :)

- k

^ permalink raw reply

* Re: [PATCH 4/6] Add multi mport support.
From: Kumar Gala @ 2008-01-31  6:20 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <EC566605-6890-4983-8700-3B15C9EFC1C5@kernel.crashing.org>


On Jan 31, 2008, at 12:15 AM, Kumar Gala wrote:

>
> On Jan 30, 2008, at 11:57 PM, Zhang Wei wrote:
>
>>
>>
>>> -----Original Message-----
>>> From: Kumar Gala [mailto:galak@kernel.crashing.org]
>>>
>>> On Jan 30, 2008, at 4:30 AM, Zhang Wei wrote:
>>>
>>>> Change lots of static variable to mport private. And add
>>> mport to some
>>>> function declaration.
>>>
>>> Can you explain this patch further.  Its not clear exactly from this
>>> commit message why we are doing this.
>>>
>>> - k
>>
>> Sorry about I have a little hurry about it.
>>
>> The original RapidIO driver suppose there is only one mpc85xx RIO
>> controller
>> in system. So, some data structures are defined as mpc85xx_rio  
>> global,
>> such as 'regs_win', 'dbell_ring', 'msg_tx_ring'. Now, I changed them
>> to
>> mport's private members. And you can define multi RIO OF-nodes in dts
>> file
>> for multi RapidIO controller in one processor, such as PCI/PCI-Ex  
>> host
>> controllers
>> in Freescale's silicon. And the mport operation function declaration
>> should be changed
>> to know which RapidIO controller is target.
>
> thanks, this makes a lot of sense and now reviewing the patch will
> make some sense to me :)

when we have multiple ports are the device IDs on the ports intended  
to be unique only to a port or unique across all ports?

- k

^ permalink raw reply

* RE: [PATCH 4/6] Add multi mport support.
From: Zhang Wei @ 2008-01-31  6:30 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <F2D2FCC7-D1ED-4DC6-BE7A-EE2755CCE125@kernel.crashing.org>

=20

> -----Original Message-----
> From: Kumar Gala [mailto:galak@kernel.crashing.org]=20
>=20
> On Jan 31, 2008, at 12:15 AM, Kumar Gala wrote:
>=20
> >
> > On Jan 30, 2008, at 11:57 PM, Zhang Wei wrote:
> >
> >>
> >>
> >>> -----Original Message-----
> >>> From: Kumar Gala [mailto:galak@kernel.crashing.org]
> >>>
> >>> On Jan 30, 2008, at 4:30 AM, Zhang Wei wrote:
> >>>
> >>>> Change lots of static variable to mport private. And add
> >>> mport to some
> >>>> function declaration.
> >>>
> >>> Can you explain this patch further.  Its not clear=20
> exactly from this
> >>> commit message why we are doing this.
> >>>
> >>> - k
> >>
> >> Sorry about I have a little hurry about it.
> >>
> >> The original RapidIO driver suppose there is only one mpc85xx RIO
> >> controller
> >> in system. So, some data structures are defined as mpc85xx_rio =20
> >> global,
> >> such as 'regs_win', 'dbell_ring', 'msg_tx_ring'. Now, I=20
> changed them
> >> to
> >> mport's private members. And you can define multi RIO=20
> OF-nodes in dts
> >> file
> >> for multi RapidIO controller in one processor, such as PCI/PCI-Ex =20
> >> host
> >> controllers
> >> in Freescale's silicon. And the mport operation function=20
> declaration
> >> should be changed
> >> to know which RapidIO controller is target.
> >
> > thanks, this makes a lot of sense and now reviewing the patch will
> > make some sense to me :)
>=20
> when we have multiple ports are the device IDs on the ports intended =20
> to be unique only to a port or unique across all ports?
>=20
I consider each RIO controller will has its own network, the device IDs
should be
unique only in its port network.

Cheers!
Wei

^ permalink raw reply

* RE: [PATCH 1/6] Change RIO function mpc85xx_ to fsl_ .
From: Zhang Wei @ 2008-01-31  6:04 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <A3EAB036-F69D-48DD-8CA9-4EAAE63AE1F5@kernel.crashing.org>

All right, I'll give you another patch for 86xx dts file. :)

 Btw: Why the PCI and other nodes were moved from SOC? Just for clear?
If they are moved out, their register address must use full address not
offset address.

Thanks!
Wei.

> -----Original Message-----
> From: Kumar Gala [mailto:galak@kernel.crashing.org]=20
> Sent: Wednesday, January 30, 2008 10:44 PM
> To: Zhang Wei
> Cc: mporter@kernel.crashing.org;=20
> linux-kernel@vger.kernel.org; linuxppc-dev@ozlabs.org
> Subject: Re: [PATCH 1/6] Change RIO function mpc85xx_ to fsl_ .
>=20
> Can you post a device tree update as well.
>=20
> The older patches on the list for the 86xx .dts should NOT=20
> put the rio =20
> node under the soc.  It should be at the same level as PCI.
>=20
> - k
>=20

^ permalink raw reply

* [PATCH] [POWERPC] Set dma_data correctly for direct_ops on pasemi
From: Olof Johansson @ 2008-01-31  6:41 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, torvalds
In-Reply-To: <18337.8955.539106.868486@cargo.ozlabs.ibm.com>

More late-caught fallout from the mainline merge. The patch:

[POWERPC] Use archdata.dma_data in dma_direct_ops and add the offset

"Now that all platforms using dma_direct_offset setup the
archdata.dma_data correctly, ..."

Nope -- the pasemi iommu setup code that disables translation on the
DMA pci device didn't set dma_data correctly.

The below patch is needed, please merge as soon as practical. Thanks!


Signed-off-by: Olof Johansson <olof@lixom.net>

diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c
index 9916a0f..c5cfd4b 100644
--- a/arch/powerpc/platforms/pasemi/iommu.c
+++ b/arch/powerpc/platforms/pasemi/iommu.c
@@ -182,8 +182,10 @@ static void pci_dma_dev_setup_pasemi(struct pci_dev *dev)
 	 * CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE at build time.
 	 */
 	if (dev->vendor == 0x1959 && dev->device == 0xa007 &&
-	    !firmware_has_feature(FW_FEATURE_LPAR))
+	    !firmware_has_feature(FW_FEATURE_LPAR)) {
 		dev->dev.archdata.dma_ops = &dma_direct_ops;
+		dev->dev.archdata.dma_data = 0;
+	}
 #endif
 
 	dev->dev.archdata.dma_data = &iommu_table_iobmap;

^ permalink raw reply related

* [PATCH 1/2] Add RapidIO node into MPC8641HPCN dts file
From: y @ 2008-01-31  7:45 UTC (permalink / raw)
  To: galak; +Cc: linuxppc-dev

From: Zhang Wei <wei.zhang@freescale.com>

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
---
 arch/powerpc/boot/dts/mpc8641_hpcn.dts |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index 556a9ca..1a0fce5 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -25,6 +25,7 @@
 		serial1 = &serial1;
 		pci0 = &pci0;
 		pci1 = &pci1;
+		rapidio0 = &rapidio0;
 	};
 
 	cpus {
@@ -499,4 +500,16 @@
 				  0 00100000>;
 		};
 	};
+
+	rapidio0: rapidio@f80c0000 {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		compatible = "fsl,rapidio-delta";
+		reg = <f80c0000 20000>;
+		ranges = <0 0 c0000000 0 20000000>;
+		interrupt-parent = <&mpic>;
+		/* err_irq bell_outb_irq bell_inb_irq
+			msg1_tx_irq msg1_rx_irq	msg2_tx_irq msg2_rx_irq */
+		interrupts = <30 2 31 2 32 2 35 2 36 2 37 2 38 2>;
+	};
 };
-- 
1.5.2

^ permalink raw reply related

* [PATCH 2/2] Add RapidIO node probing into MPC86xx_HPCN board id table.
From: y @ 2008-01-31  7:45 UTC (permalink / raw)
  To: galak; +Cc: linuxppc-dev
In-Reply-To: <12017655292517-git-send-email-y>

From: Zhang Wei <wei.zhang@freescale.com>

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
---
 arch/powerpc/platforms/86xx/mpc86xx_hpcn.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index cfbe8c5..4a3e421 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -215,6 +215,7 @@ mpc86xx_time_init(void)
 
 static __initdata struct of_device_id of_bus_ids[] = {
 	{ .compatible = "simple-bus", },
+	{ .compatible = "fsl,rapidio-delta", },
 	{},
 };
 
-- 
1.5.2

^ permalink raw reply related

* [PATCH 1/2] Add RapidIO node into MPC8641HPCN dts file
From: Zhang Wei @ 2008-01-31  7:46 UTC (permalink / raw)
  To: galak; +Cc: linuxppc-dev

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
---
 arch/powerpc/boot/dts/mpc8641_hpcn.dts |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index 556a9ca..1a0fce5 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -25,6 +25,7 @@
 		serial1 = &serial1;
 		pci0 = &pci0;
 		pci1 = &pci1;
+		rapidio0 = &rapidio0;
 	};
 
 	cpus {
@@ -499,4 +500,16 @@
 				  0 00100000>;
 		};
 	};
+
+	rapidio0: rapidio@f80c0000 {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		compatible = "fsl,rapidio-delta";
+		reg = <f80c0000 20000>;
+		ranges = <0 0 c0000000 0 20000000>;
+		interrupt-parent = <&mpic>;
+		/* err_irq bell_outb_irq bell_inb_irq
+			msg1_tx_irq msg1_rx_irq	msg2_tx_irq msg2_rx_irq */
+		interrupts = <30 2 31 2 32 2 35 2 36 2 37 2 38 2>;
+	};
 };
-- 
1.5.2

^ permalink raw reply related

* [PATCH 2/2] Add RapidIO node probing into MPC86xx_HPCN board id table.
From: Zhang Wei @ 2008-01-31  7:46 UTC (permalink / raw)
  To: galak; +Cc: linuxppc-dev
In-Reply-To: <12017656032841-git-send-email-wei.zhang@freescale.com>

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
---
 arch/powerpc/platforms/86xx/mpc86xx_hpcn.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index cfbe8c5..4a3e421 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -215,6 +215,7 @@ mpc86xx_time_init(void)
 
 static __initdata struct of_device_id of_bus_ids[] = {
 	{ .compatible = "simple-bus", },
+	{ .compatible = "fsl,rapidio-delta", },
 	{},
 };
 
-- 
1.5.2

^ permalink raw reply related

* RE: [PATCH 1/2] Add RapidIO node into MPC8641HPCN dts file
From: Zhang Wei @ 2008-01-31  7:36 UTC (permalink / raw)
  To: galak; +Cc: linuxppc-dev
In-Reply-To: <12017655292517-git-send-email-y>

Sorry for wrong sending name of this and next email.

Best Regards,
Wei.=20

> -----Original Message-----
> From: y [mailto:y]=20
> Sent: Thursday, January 31, 2008 3:45 PM
> To: galak@kernel.crashing.org
> Cc: linuxppc-dev@ozlabs.org; Zhang Wei
> Subject: [PATCH 1/2] Add RapidIO node into MPC8641HPCN dts file
>=20
> From: Zhang Wei <wei.zhang@freescale.com>
>=20
> Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
> ---
>  arch/powerpc/boot/dts/mpc8641_hpcn.dts |   13 +++++++++++++
>  1 files changed, 13 insertions(+), 0 deletions(-)
>=20
> diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts=20
> b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
> index 556a9ca..1a0fce5 100644
> --- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
> +++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
> @@ -25,6 +25,7 @@
>  		serial1 =3D &serial1;
>  		pci0 =3D &pci0;
>  		pci1 =3D &pci1;
> +		rapidio0 =3D &rapidio0;
>  	};
> =20
>  	cpus {
> @@ -499,4 +500,16 @@
>  				  0 00100000>;
>  		};
>  	};
> +
> +	rapidio0: rapidio@f80c0000 {
> +		#address-cells =3D <2>;
> +		#size-cells =3D <2>;
> +		compatible =3D "fsl,rapidio-delta";
> +		reg =3D <f80c0000 20000>;
> +		ranges =3D <0 0 c0000000 0 20000000>;
> +		interrupt-parent =3D <&mpic>;
> +		/* err_irq bell_outb_irq bell_inb_irq
> +			msg1_tx_irq msg1_rx_irq	msg2_tx_irq=20
> msg2_rx_irq */
> +		interrupts =3D <30 2 31 2 32 2 35 2 36 2 37 2 38 2>;
> +	};
>  };
> --=20
> 1.5.2
>=20
>=20

^ permalink raw reply

* Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup
From: Ingo Molnar @ 2008-01-31  9:06 UTC (permalink / raw)
  To: Luck, Tony
  Cc: sparclinux, linux-ia64, Linux Kernel Development, Mike Travis,
	Linux/PPC Development, Geert Uytterhoeven, Thomas Gleixner,
	Linus Torvalds
In-Reply-To: <1FE6DD409037234FAB833C420AA843EC78C219@orsmsx424.amr.corp.intel.com>


* Luck, Tony <tony.luck@intel.com> wrote:

> > I'll start digging on why this doesn't boot ... but you might as well
> > send the fixes so far upstream to Linus so that the SMP fix is available
> 
> Well a pure 2.6.24 version compiled with CONFIG_SMP=n booted just 
> fine, so the breakage is recent ... and more than likely related to 
> this change.
> 
> I've only had a casual dig at the failing case ... kernel dies in 
> memset() as called from kmem_cache_alloc() with the address being 
> written as 0x4000000000117b48 (which is off in the virtual address 
> space range used by users ... not a kernel address).

hm, as far as i could check, on ia64 UP the .percpu section link 
difference was the only ia64 difference i could find out of those 
changes. Could you try to copy a 2.6.24 include/asm-generic/percpu.h, 
include/asm-ia64.h and include/linux/percpu.h into your current tree, 
and see whether that boots? If yes, then it's the percpu changes. The 
patch below does this ontop of very latest -git - and it builds fine 
with your UP config with a crosscompiler.

> I'll dig some more tomorrow.

thanks.

	Ingo

---
 include/asm-generic/percpu.h |   99 ++++++++++++++++---------------------------
 include/asm-ia64/percpu.h    |   57 +++++++++++++++++++-----
 include/linux/percpu.h       |   20 --------
 3 files changed, 82 insertions(+), 94 deletions(-)

Index: linux-x86.q/include/asm-generic/percpu.h
===================================================================
--- linux-x86.q.orig/include/asm-generic/percpu.h
+++ linux-x86.q/include/asm-generic/percpu.h
@@ -3,79 +3,54 @@
 #include <linux/compiler.h>
 #include <linux/threads.h>
 
-/*
- * Determine the real variable name from the name visible in the
- * kernel sources.
- */
-#define per_cpu_var(var) per_cpu__##var
-
+#define __GENERIC_PER_CPU
 #ifdef CONFIG_SMP
 
-/*
- * per_cpu_offset() is the offset that has to be added to a
- * percpu variable to get to the instance for a certain processor.
- *
- * Most arches use the __per_cpu_offset array for those offsets but
- * some arches have their own ways of determining the offset (x86_64, s390).
- */
-#ifndef __per_cpu_offset
 extern unsigned long __per_cpu_offset[NR_CPUS];
 
 #define per_cpu_offset(x) (__per_cpu_offset[x])
-#endif
-
-/*
- * Determine the offset for the currently active processor.
- * An arch may define __my_cpu_offset to provide a more effective
- * means of obtaining the offset to the per cpu variables of the
- * current processor.
- */
-#ifndef __my_cpu_offset
-#define __my_cpu_offset per_cpu_offset(raw_smp_processor_id())
-#define my_cpu_offset per_cpu_offset(smp_processor_id())
-#else
-#define my_cpu_offset __my_cpu_offset
-#endif
-
-/*
- * Add a offset to a pointer but keep the pointer as is.
- *
- * Only S390 provides its own means of moving the pointer.
- */
-#ifndef SHIFT_PERCPU_PTR
-#define SHIFT_PERCPU_PTR(__p, __offset)	RELOC_HIDE((__p), (__offset))
-#endif
-
-/*
- * A percpu variable may point to a discarded regions. The following are
- * established ways to produce a usable pointer from the percpu variable
- * offset.
- */
-#define per_cpu(var, cpu) \
-	(*SHIFT_PERCPU_PTR(&per_cpu_var(var), per_cpu_offset(cpu)))
-#define __get_cpu_var(var) \
-	(*SHIFT_PERCPU_PTR(&per_cpu_var(var), my_cpu_offset))
-#define __raw_get_cpu_var(var) \
-	(*SHIFT_PERCPU_PTR(&per_cpu_var(var), __my_cpu_offset))
-
-
-#ifdef CONFIG_HAVE_SETUP_PER_CPU_AREA
-extern void setup_per_cpu_areas(void);
-#endif
 
+/* Separate out the type, so (int[3], foo) works. */
+#define DEFINE_PER_CPU(type, name) \
+    __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
+
+#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name)		\
+    __attribute__((__section__(".data.percpu.shared_aligned"))) \
+    __typeof__(type) per_cpu__##name				\
+    ____cacheline_aligned_in_smp
+
+/* var is in discarded region: offset to particular copy we want */
+#define per_cpu(var, cpu) (*({				\
+	extern int simple_identifier_##var(void);	\
+	RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); }))
+#define __get_cpu_var(var) per_cpu(var, smp_processor_id())
+#define __raw_get_cpu_var(var) per_cpu(var, raw_smp_processor_id())
+
+/* A macro to avoid #include hell... */
+#define percpu_modcopy(pcpudst, src, size)			\
+do {								\
+	unsigned int __i;					\
+	for_each_possible_cpu(__i)				\
+		memcpy((pcpudst)+__per_cpu_offset[__i],		\
+		       (src), (size));				\
+} while (0)
 #else /* ! SMP */
 
-#define per_cpu(var, cpu)			(*((void)(cpu), &per_cpu_var(var)))
-#define __get_cpu_var(var)			per_cpu_var(var)
-#define __raw_get_cpu_var(var)			per_cpu_var(var)
+#define DEFINE_PER_CPU(type, name) \
+    __typeof__(type) per_cpu__##name
+
+#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name)	\
+    DEFINE_PER_CPU(type, name)
+
+#define per_cpu(var, cpu)			(*((void)(cpu), &per_cpu__##var))
+#define __get_cpu_var(var)			per_cpu__##var
+#define __raw_get_cpu_var(var)			per_cpu__##var
 
 #endif	/* SMP */
 
-#ifndef PER_CPU_ATTRIBUTES
-#define PER_CPU_ATTRIBUTES
-#endif
+#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
 
-#define DECLARE_PER_CPU(type, name) extern PER_CPU_ATTRIBUTES \
-					__typeof__(type) per_cpu_var(name)
+#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var)
+#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var)
 
 #endif /* _ASM_GENERIC_PERCPU_H_ */
Index: linux-x86.q/include/asm-ia64/percpu.h
===================================================================
--- linux-x86.q.orig/include/asm-ia64/percpu.h
+++ linux-x86.q/include/asm-ia64/percpu.h
@@ -15,36 +15,69 @@
 
 #include <linux/threads.h>
 
-#ifdef CONFIG_SMP
-
 #ifdef HAVE_MODEL_SMALL_ATTRIBUTE
-# define PER_CPU_ATTRIBUTES	__attribute__((__model__ (__small__)))
+# define __SMALL_ADDR_AREA	__attribute__((__model__ (__small__)))
+#else
+# define __SMALL_ADDR_AREA
 #endif
 
-#define __my_cpu_offset	__ia64_per_cpu_var(local_per_cpu_offset)
+#define DECLARE_PER_CPU(type, name)				\
+	extern __SMALL_ADDR_AREA __typeof__(type) per_cpu__##name
+
+/* Separate out the type, so (int[3], foo) works. */
+#define DEFINE_PER_CPU(type, name)				\
+	__attribute__((__section__(".data.percpu")))		\
+	__SMALL_ADDR_AREA __typeof__(type) per_cpu__##name
+
+#ifdef CONFIG_SMP
+#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name)			\
+	__attribute__((__section__(".data.percpu.shared_aligned")))	\
+	__SMALL_ADDR_AREA __typeof__(type) per_cpu__##name		\
+	____cacheline_aligned_in_smp
+#else
+#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name)	\
+	DEFINE_PER_CPU(type, name)
+#endif
+
+/*
+ * Pretty much a literal copy of asm-generic/percpu.h, except that percpu_modcopy() is an
+ * external routine, to avoid include-hell.
+ */
+#ifdef CONFIG_SMP
+
+extern unsigned long __per_cpu_offset[NR_CPUS];
+#define per_cpu_offset(x) (__per_cpu_offset[x])
 
+/* Equal to __per_cpu_offset[smp_processor_id()], but faster to access: */
+DECLARE_PER_CPU(unsigned long, local_per_cpu_offset);
+
+#define per_cpu(var, cpu)  (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]))
+#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __ia64_per_cpu_var(local_per_cpu_offset)))
+#define __raw_get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __ia64_per_cpu_var(local_per_cpu_offset)))
+
+extern void percpu_modcopy(void *pcpudst, const void *src, unsigned long size);
+extern void setup_per_cpu_areas (void);
 extern void *per_cpu_init(void);
 
 #else /* ! SMP */
 
-#define PER_CPU_ATTRIBUTES	__attribute__((__section__(".data.percpu")))
-
+#define per_cpu(var, cpu)			(*((void)(cpu), &per_cpu__##var))
+#define __get_cpu_var(var)			per_cpu__##var
+#define __raw_get_cpu_var(var)			per_cpu__##var
 #define per_cpu_init()				(__phys_per_cpu_start)
 
 #endif	/* SMP */
 
+#define EXPORT_PER_CPU_SYMBOL(var)		EXPORT_SYMBOL(per_cpu__##var)
+#define EXPORT_PER_CPU_SYMBOL_GPL(var)		EXPORT_SYMBOL_GPL(per_cpu__##var)
+
 /*
  * Be extremely careful when taking the address of this variable!  Due to virtual
  * remapping, it is different from the canonical address returned by __get_cpu_var(var)!
  * On the positive side, using __ia64_per_cpu_var() instead of __get_cpu_var() is slightly
  * more efficient.
  */
-#define __ia64_per_cpu_var(var)	per_cpu__##var
-
-#include <asm-generic/percpu.h>
-
-/* Equal to __per_cpu_offset[smp_processor_id()], but faster to access: */
-DECLARE_PER_CPU(unsigned long, local_per_cpu_offset);
+#define __ia64_per_cpu_var(var)	(per_cpu__##var)
 
 #endif /* !__ASSEMBLY__ */
 
Index: linux-x86.q/include/linux/percpu.h
===================================================================
--- linux-x86.q.orig/include/linux/percpu.h
+++ linux-x86.q/include/linux/percpu.h
@@ -9,26 +9,6 @@
 
 #include <asm/percpu.h>
 
-#ifdef CONFIG_SMP
-#define DEFINE_PER_CPU(type, name)					\
-	__attribute__((__section__(".data.percpu")))			\
-	PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
-
-#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name)			\
-	__attribute__((__section__(".data.percpu.shared_aligned")))	\
-	PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name		\
-	____cacheline_aligned_in_smp
-#else
-#define DEFINE_PER_CPU(type, name)					\
-	PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
-
-#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name)		      \
-	DEFINE_PER_CPU(type, name)
-#endif
-
-#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var)
-#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var)
-
 /* Enough to cover all DEFINE_PER_CPUs in kernel, including modules. */
 #ifndef PERCPU_ENOUGH_ROOM
 #ifdef CONFIG_MODULES

^ permalink raw reply

* Re: [RFC] [POWERPC] bootwrapper: build multiple cuImages
From: Jochen Friedrich @ 2008-01-31 10:21 UTC (permalink / raw)
  To: Grant Likely; +Cc: scottwood, linuxppc-dev, Arnd Bergmann
In-Reply-To: <20080131003347.5779.96112.stgit@trillian.secretlab.ca>

Hi Grant,

> Currently, the kernel uses CONFIG_DEVICE_TREE to wrap a kernel image
> with a fdt blob which means for any given configuration only one dts
> file can be selected and so support for only one board can be built
> 
> This patch moves the selection of the default .dts file out of the kernel
> config and into the bootwrapper makefile.  The makefile chooses which
> images to build based on the kernel config and the dts source file
> name is taken directly from the image name.  For example "cuImage.ebony"
> will use "ebony.dts" as the device tree source file.

Cool stuff. This should be the last step to enable multiplatform builds on
8xx etc. as Arndt asked a few days ago ;)

Thanks,
Jochen

^ permalink raw reply

* Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup
From: Adrian Bunk @ 2008-01-31 10:47 UTC (permalink / raw)
  To: Luck, Tony
  Cc: sparclinux, linux-ia64, Linux Kernel Development, Mike Travis,
	Linux/PPC Development, Ivan Kokshaysky, Geert Uytterhoeven,
	Ingo Molnar, Linus Torvalds, Thomas Gleixner
In-Reply-To: <1FE6DD409037234FAB833C420AA843EC757F12@orsmsx424.amr.corp.intel.com>

On Wed, Jan 30, 2008 at 11:33:29AM -0800, Luck, Tony wrote:
> > I'm having trouble replicating this error.  With the latest linux-2.6.git
> > plus the patch I just sent, I get the following errors:
> >
> > drivers/input/mouse/psmouse-base.c:45: error: __param_proto causes a section type conflict
> > drivers/md/md.c:5881: error: __param_start_ro causes a section type conflict
> 
> Weird.  psmouse-base.c builds ok for me.  Perhaps there is a compiler
> version difference?  I'm running a rather old 3.4.6 that came with
> my RHEL 4.5 release.
>...

It depends on the compiler version.

And you were in the Cc of Ivan's patch that fixes it... [1]

> -Tony

cu
Adrian

[1] http://lkml.org/lkml/2007/12/27/29

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed

^ permalink raw reply

* Re: [PATCH] [POWERPC] Set dma_data correctly for direct_ops on pasemi
From: Michael Ellerman @ 2008-01-31 12:38 UTC (permalink / raw)
  To: Olof Johansson; +Cc: torvalds, Paul Mackerras, linuxppc-dev
In-Reply-To: <20080131064130.GA32344@lixom.net>

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

On Thu, 2008-01-31 at 00:41 -0600, Olof Johansson wrote:
> More late-caught fallout from the mainline merge. The patch:
> 
> [POWERPC] Use archdata.dma_data in dma_direct_ops and add the offset
> 
> "Now that all platforms using dma_direct_offset setup the
> archdata.dma_data correctly, ..."
> 
> Nope -- the pasemi iommu setup code that disables translation on the
> DMA pci device didn't set dma_data correctly.
> 
> The below patch is needed, please merge as soon as practical. Thanks!

Sorry about that.

I'm confused though, didn't your device come from alloc_pci_dev() which
kzalloc()s the pci_dev which contains the archdata which contains the
dma_data, ie. dma_data will already be 0?

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* [PATCHv4 2.6.25] i2c: adds support for i2c bus on Freescale CPM1/CPM2 controllers
From: Jochen Friedrich @ 2008-01-31 12:54 UTC (permalink / raw)
  To: Scott Wood; +Cc: linux-kernel, linuxppc-dev list, i2c, Jean Delvare

Using the port of 2.4 code from Vitaly Bordug <vitb@kernel.crashing.org>
and the actual algorithm used by the i2c driver of the DBox code on
cvs.tuxboc.org from Tmbinc, Gillem (htoa@gmx.net). Renamed i2c-rpx.c and
i2c-algo-8xx.c to i2c-cpm.c and converted the driver to an
of_platform_driver.

Signed-off-by: Jochen Friedrich <jochen@scram.de>
---
 drivers/i2c/busses/Kconfig   |   10 +
 drivers/i2c/busses/Makefile  |    1 +
 drivers/i2c/busses/i2c-cpm.c |  759 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 770 insertions(+), 0 deletions(-)
 create mode 100644 drivers/i2c/busses/i2c-cpm.c

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index b61f56b..1d18db7 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -114,6 +114,16 @@ config I2C_BLACKFIN_TWI_CLK_KHZ
 	help
 	  The unit of the TWI clock is kHz.
 
+config I2C_CPM
+	tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)"
+	depends on (CPM1 || CPM2) && I2C && PPC_OF
+	help
+	  This supports the use of the I2C interface on Freescale
+	  processors with CPM1 or CPM2.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-cpm.
+
 config I2C_DAVINCI
 	tristate "DaVinci I2C driver"
 	depends on ARCH_DAVINCI
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index ea7068f..1291e2b 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
 obj-$(CONFIG_I2C_AT91)		+= i2c-at91.o
 obj-$(CONFIG_I2C_AU1550)	+= i2c-au1550.o
 obj-$(CONFIG_I2C_BLACKFIN_TWI)	+= i2c-bfin-twi.o
+obj-$(CONFIG_I2C_CPM)		+= i2c-cpm.o
 obj-$(CONFIG_I2C_DAVINCI)	+= i2c-davinci.o
 obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
 obj-$(CONFIG_I2C_GPIO)		+= i2c-gpio.o
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
new file mode 100644
index 0000000..7191427
--- /dev/null
+++ b/drivers/i2c/busses/i2c-cpm.c
@@ -0,0 +1,759 @@
+/*
+ * Freescale CPM1/CPM2 I2C interface.
+ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
+ *
+ * moved into proper i2c interface;
+ * Brad Parker (brad@heeltoe.com)
+ *
+ * (C) 2007 Montavista Software, Inc.
+ * Vitaly Bordug <vitb@kernel.crashing.org>
+ *
+ * RPX lite specific parts of the i2c interface
+ * Update:  There actually isn't anything RPXLite-specific about this module.
+ * This should work for most any CPM board.  The console messages have been
+ * changed to eliminate RPXLite references.
+ *
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * moved into proper i2c interface; separated out platform specific
+ * parts into i2c-8xx.c
+ * Brad Parker (brad@heeltoe.com)
+ *
+ * Parts from dbox2_i2c.c (cvs.tuxbox.org)
+ * (C) 2000-2001 Tmbinc, Gillem (htoa@gmx.net)
+ *
+ * (C) 2007 Montavista Software, Inc.
+ * Vitaly Bordug <vitb@kernel.crashing.org>
+ *
+ * Converted to of_platform_device. Renamed to i2c-cpm.c.
+ * (C) 2007 Jochen Friedrich <jochen@scram.de>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/stddef.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/time.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <sysdev/fsl_soc.h>
+#include <asm/cpm.h>
+
+/*
+ * Wait for patch from Jon Smirl
+ * #include "powerpc-common.h"
+ */
+
+/* Try to define this if you have an older CPU (earlier than rev D4) */
+/* However, better use a GPIO based bitbang driver in this case :/   */
+#undef	I2C_CHIP_ERRATA
+
+#define CPM_MAX_READ    513
+#define CPM_MAXBD       4
+
+#define CPM_CR_INIT_TRX		(0x00)
+#define CPM_CR_CLOSE_RXBD	(0x07)
+
+#define I2C_EB			(0x10) /* Big endian mode */
+
+/* I2C parameter RAM. */
+struct i2c_ram {
+	ushort  rbase;		/* Rx Buffer descriptor base address */
+	ushort  tbase;		/* Tx Buffer descriptor base address */
+	u_char  rfcr;		/* Rx function code */
+	u_char  tfcr;		/* Tx function code */
+	ushort  mrblr;		/* Max receive buffer length */
+	uint    rstate;		/* Internal */
+	uint    rdp;		/* Internal */
+	ushort  rbptr;		/* Rx Buffer descriptor pointer */
+	ushort  rbc;		/* Internal */
+	uint    rxtmp;		/* Internal */
+	uint    tstate;		/* Internal */
+	uint    tdp;		/* Internal */
+	ushort  tbptr;		/* Tx Buffer descriptor pointer */
+	ushort  tbc;		/* Internal */
+	uint    txtmp;		/* Internal */
+	char    res1[4];	/* Reserved */
+	ushort  rpbase;		/* Relocation pointer */
+	char    res2[2];	/* Reserved */
+};
+
+/* I2C Registers */
+struct i2c_reg {
+	u8	i2mod;
+	u8	res1[3];
+	u8	i2add;
+	u8	res2[3];
+	u8	i2brg;
+	u8	res3[3];
+	u8	i2com;
+	u8	res4[3];
+	u8	i2cer;
+	u8	res5[3];
+	u8	i2cmr;
+};
+
+struct cpm_i2c {
+	char *base;
+	struct of_device *ofdev;
+	struct i2c_adapter adap;
+	uint dp_addr;
+	int version; /* CPM1=1, CPM2=2 */
+	int irq;
+	int cp_command;
+	struct i2c_reg __iomem *i2c_reg;
+	struct i2c_ram __iomem *i2c_ram;
+	u16 i2c_addr;
+	wait_queue_head_t i2c_wait;
+	struct mutex i2c_mutex; /* Protects I2C CPM */
+	u_char *txbuf[CPM_MAXBD];
+	u_char *rxbuf[CPM_MAXBD];
+	u32 txdma[CPM_MAXBD];
+	u32 rxdma[CPM_MAXBD];
+};
+
+static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id)
+{
+	struct cpm_i2c *cpm;
+	struct i2c_reg __iomem *i2c_reg;
+	struct i2c_adapter *adap = dev_id;
+	int i;
+
+	cpm = i2c_get_adapdata(dev_id);
+	i2c_reg = cpm->i2c_reg;
+
+	/* Clear interrupt. */
+	i = in_8(&i2c_reg->i2cer);
+	out_8(&i2c_reg->i2cer, i);
+
+	dev_dbg(&adap->dev, "Interrupt: %x\n", i);
+
+	/* Get 'me going again. */
+	wake_up_interruptible(&cpm->i2c_wait);
+
+	return i ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static void cpm_reset_i2c_params(struct cpm_i2c *cpm)
+{
+	struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+
+	/* Set up the IIC parameters in the parameter ram. */
+	out_be16(&i2c_ram->tbase, cpm->dp_addr);
+	out_be16(&i2c_ram->rbase, cpm->dp_addr + sizeof(cbd_t) * CPM_MAXBD);
+
+	out_8(&i2c_ram->tfcr, I2C_EB);
+	out_8(&i2c_ram->rfcr, I2C_EB);
+
+	out_be16(&i2c_ram->mrblr, CPM_MAX_READ);
+
+	out_be32(&i2c_ram->rstate, 0);
+	out_be32(&i2c_ram->rdp, 0);
+	out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase));
+	out_be16(&i2c_ram->rbc, 0);
+	out_be32(&i2c_ram->rxtmp, 0);
+	out_be32(&i2c_ram->tstate, 0);
+	out_be32(&i2c_ram->tdp, 0);
+	out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase));
+	out_be16(&i2c_ram->tbc, 0);
+	out_be32(&i2c_ram->txtmp, 0);
+}
+
+static void cpm_i2c_force_close(struct i2c_adapter *adap)
+{
+	struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+	struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg;
+
+	dev_dbg(&adap->dev, "cpm_i2c_force_close()\n");
+
+	cpm_command(cpm->cp_command, CPM_CR_CLOSE_RXBD);
+
+	out_8(&i2c_reg->i2cmr, 0x00);	/* Disable all interrupts */
+	out_8(&i2c_reg->i2cer, 0xff);
+}
+
+static void cpm_i2c_parse_message(struct i2c_adapter *adap,
+	struct i2c_msg *pmsg, int num, int tx, int rx)
+{
+	cbd_t *tbdf, *rbdf;
+	u_char addr;
+	u_char *tb;
+	u_char *rb;
+	struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+	struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+	int i, dscan;
+
+	tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+	rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+	/*
+	 * This chip can't do zero length writes. However, the i2c core uses
+	 * them to scan for devices. The best we can do is to convert them
+	 * into 1 byte reads
+	 */
+
+	dscan = ((pmsg->len == 0) && (num == 1));
+
+	addr = pmsg->addr << 1;
+	if ((pmsg->flags & I2C_M_RD) || dscan)
+		addr |= 1;
+
+	tb = cpm->txbuf[tx];
+	rb = cpm->rxbuf[rx];
+
+	/* Align read buffer */
+	rb = (u_char *) (((ulong) rb + 1) & ~1);
+
+	if ((pmsg->flags & I2C_M_RD) || dscan) {
+		/*
+		 * To read, we need an empty buffer of the proper length.
+		 * All that is used is the first byte for address, the remainder
+		 * is just used for timing (and doesn't really have to exist).
+		 */
+		tb[0] = addr;		/* Device address byte w/rw flag */
+
+		dev_dbg(&adap->dev, "cpm_i2c_read(abyte=0x%x)\n", addr);
+
+		if (dscan)
+			tbdf[tx].cbd_datlen = 2;
+		else
+			tbdf[tx].cbd_datlen = pmsg->len + 1;
+
+		tbdf[tx].cbd_sc = 0;
+
+		if (!(pmsg->flags & I2C_M_NOSTART))
+			tbdf[tx].cbd_sc |= BD_I2C_START;
+		if (tx + 1 == num)
+			tbdf[tx].cbd_sc |= BD_SC_LAST | BD_SC_WRAP;
+
+		rbdf[rx].cbd_datlen = 0;
+		rbdf[rx].cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
+
+		if (rx + 1 == CPM_MAXBD)
+			tbdf[rx].cbd_sc |= BD_SC_WRAP;
+
+		eieio();
+		tbdf[tx].cbd_sc |= BD_SC_READY;
+	} else {
+		tb[0] = addr;		/* Device address byte w/rw flag */
+		for (i = 0; i < pmsg->len; i++)
+			tb[i+1] = pmsg->buf[i];
+
+		dev_dbg(&adap->dev, "cpm_iic_write(abyte=0x%x)\n", addr);
+
+		tbdf[tx].cbd_datlen = pmsg->len + 1;
+		tbdf[tx].cbd_sc = 0;
+
+		if (!(pmsg->flags & I2C_M_NOSTART))
+			tbdf[tx].cbd_sc |= BD_I2C_START;
+
+		if (tx + 1 == num)
+			tbdf[tx].cbd_sc |= BD_SC_LAST | BD_SC_WRAP;
+
+		eieio();
+		tbdf[tx].cbd_sc |= BD_SC_READY | BD_SC_INTRPT;
+
+		dev_dbg(&adap->dev, "tx sc %d %04x\n",
+			tx, tbdf[tx].cbd_sc);
+	}
+}
+
+static int cpm_i2c_check_message(struct i2c_adapter *adap,
+	struct i2c_msg *pmsg, int tx, int rx)
+{
+	cbd_t *tbdf, *rbdf;
+	u_char *tb;
+	u_char *rb;
+	struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+	struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+	int i;
+
+	tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+	rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+	tb = cpm->txbuf[tx];
+	rb = cpm->rxbuf[rx];
+
+	/* Align read buffer */
+	rb = (u_char *) (((uint) rb + 1) & ~1);
+
+	if (pmsg->flags & I2C_M_RD) {
+		dev_dbg(&adap->dev, "rx sc %04x, rx sc %04x\n",
+			tbdf[tx].cbd_sc, rbdf[rx].cbd_sc);
+
+		if (tbdf[tx].cbd_sc & BD_SC_NAK) {
+			dev_dbg(&adap->dev, "IIC read; No ack\n");
+
+			if (pmsg->flags & I2C_M_IGNORE_NAK)
+				return 0;
+			else
+				return -EIO;
+		}
+		if (rbdf[rx].cbd_sc & BD_SC_EMPTY) {
+			dev_dbg(&adap->dev,
+				"IIC read; complete but rbuf empty\n");
+			return -EREMOTEIO;
+		}
+		if (rbdf[rx].cbd_sc & BD_SC_OV) {
+			dev_dbg(&adap->dev, "IIC read; Overrun\n");
+			return -EREMOTEIO;
+		}
+		for (i = 0; i < pmsg->len; i++)
+			pmsg->buf[i] = rb[i];
+	} else {
+		dev_dbg(&adap->dev, "tx sc %d %04x\n", tx, tbdf[tx].cbd_sc);
+
+		if (tbdf[tx].cbd_sc & BD_SC_NAK) {
+			dev_dbg(&adap->dev, "IIC write; No ack\n");
+
+			if (pmsg->flags & I2C_M_IGNORE_NAK)
+				return 0;
+			else
+				return -EIO;
+		}
+		if (tbdf[tx].cbd_sc & BD_SC_UN) {
+			dev_dbg(&adap->dev, "IIC write; Underrun\n");
+			return -EIO;
+		}
+		if (tbdf[tx].cbd_sc & BD_SC_CL) {
+			dev_dbg(&adap->dev, "IIC write; Collision\n");
+			return -EIO;
+		}
+	}
+	return 0;
+}
+
+static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+	struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+	struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg;
+	struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+	struct i2c_msg *pmsg, *rmsg;
+	int ret, i;
+	int tptr;
+	int rptr;
+	cbd_t *tbdf, *rbdf;
+
+	if (num > CPM_MAXBD)
+		return -EINVAL;
+
+	/* Check if we have any oversized READ requests */
+	for (i = 0; i < num; i++) {
+		pmsg = &msgs[i];
+		if (pmsg->len >= CPM_MAX_READ)
+			return -EINVAL;
+	}
+
+	mutex_lock(&cpm->i2c_mutex);
+
+	/* Reset to use first buffer */
+	out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase));
+	out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase));
+
+	tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+	rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+	tptr = 0;
+	rptr = 0;
+
+	while (tptr < num) {
+		pmsg = &msgs[tptr];
+		dev_dbg(&adap->dev, "i2c-algo-cpm.o: " "R: %d T: %d\n",
+			rptr, tptr);
+
+		cpm_i2c_parse_message(adap, pmsg, num, tptr, rptr);
+		if (pmsg->flags & I2C_M_RD)
+			rptr++;
+		tptr++;
+	}
+	/* Start transfer now */
+	/* Chip bug, set enable here */
+	out_8(&i2c_reg->i2cmr, 0x13);	/* Enable RX/TX/Error interupts */
+	out_8(&i2c_reg->i2cer, 0xff);	/* Clear interrupt status */
+	out_8(&i2c_reg->i2mod, in_8(&i2c_reg->i2mod) | 1);	/* Enable */
+	/* Begin transmission */
+	out_8(&i2c_reg->i2com, in_8(&i2c_reg->i2com) | 0x80);
+
+	tptr = 0;
+	rptr = 0;
+
+	while (tptr < num) {
+		/* Check for outstanding messages */
+		dev_dbg(&adap->dev, "test ready.\n");
+		if (!(tbdf[tptr].cbd_sc & BD_SC_READY)) {
+			dev_dbg(&adap->dev, "ready.\n");
+			rmsg = &msgs[tptr];
+			ret = cpm_i2c_check_message(adap, rmsg, tptr, rptr);
+			tptr++;
+			if (rmsg->flags & I2C_M_RD)
+				rptr++;
+			if (ret)
+				goto out_err;
+		} else {
+			dev_dbg(&adap->dev, "not ready.\n");
+			ret = wait_event_interruptible_timeout(cpm->i2c_wait,
+				!(tbdf[tptr].cbd_sc & BD_SC_READY), 1 * HZ);
+			if (ret == 0) {
+				ret = -EREMOTEIO;
+				dev_dbg(&adap->dev, "I2C read: timeout!\n");
+				goto out_err;
+			}
+		}
+	}
+#ifdef I2C_CHIP_ERRATA
+	/*
+	 * Chip errata, clear enable. This is not needed on rev D4 CPUs.
+	 * Disabling I2C too early may cause too short stop condition
+	 */
+	udelay(4);
+	out_8(&i2c_reg->i2mod, in_8(&i2c_reg->i2mod) | ~1);
+#endif
+	mutex_unlock(&cpm->i2c_mutex);
+	return (num);
+
+out_err:
+	cpm_i2c_force_close(adap);
+#ifdef I2C_CHIP_ERRATA
+	/*
+	 * Chip errata, clear enable. This is not needed on rev D4 CPUs.
+	 */
+	out_8(&i2c_reg->i2mod, in_8(&i2c_reg->i2mod) | ~1);
+#endif
+	mutex_unlock(&cpm->i2c_mutex);
+	return ret;
+}
+
+static u32 cpm_i2c_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+/* -----exported algorithm data: -------------------------------------	*/
+
+static const struct i2c_algorithm cpm_i2c_algo = {
+	.master_xfer = cpm_i2c_xfer,
+	.functionality = cpm_i2c_func,
+};
+
+static const struct i2c_adapter cpm_ops = {
+	.owner		= THIS_MODULE,
+	.name		= "i2c-cpm",
+	.id		= I2C_HW_MPC8XX_EPON,
+	.algo		= &cpm_i2c_algo,
+	.class		= I2C_CLASS_HWMON,
+};
+
+static int cpm_i2c_setup(struct cpm_i2c *cpm)
+{
+	struct of_device *ofdev = cpm->ofdev;
+	const u32 *data;
+	int len, ret, i;
+	void __iomem *i2c_base;
+	cbd_t *tbdf, *rbdf;
+	unsigned char brg;
+
+	pr_debug("i2c-cpm: cpm_i2c_setup()\n");
+
+	init_waitqueue_head(&cpm->i2c_wait);
+	mutex_init(&cpm->i2c_mutex);
+
+	cpm->irq = of_irq_to_resource(ofdev->node, 0, NULL);
+	if (cpm->irq == NO_IRQ)
+		return -EINVAL;
+
+	/* Install interrupt handler. */
+	ret = request_irq(cpm->irq, cpm_i2c_interrupt, 0, "cpm_i2c",
+			  &cpm->adap);
+	if (ret)
+		goto out_irq;
+
+	/* IIC parameter RAM */
+	i2c_base = of_iomap(ofdev->node, 1);
+	if (i2c_base == NULL) {
+		ret = -EINVAL;
+		goto out_irq;
+	}
+
+	if (of_device_is_compatible(ofdev->node, "fsl,cpm1-i2c")) {
+
+		/* Check for and use a microcode relocation patch. */
+		cpm->i2c_ram = i2c_base;
+		cpm->i2c_addr = in_be16(&cpm->i2c_ram->rpbase);
+
+		/*
+		 * Maybe should use cpm_muram_alloc instead of hardcoding
+		 * this in micropatch.c
+		 */
+		if (cpm->i2c_addr) {
+			cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr);
+			iounmap(i2c_base);
+		}
+
+		cpm->version = 1;
+
+	} else if (of_device_is_compatible(ofdev->node, "fsl,cpm2-i2c")) {
+		cpm->i2c_addr = cpm_muram_alloc(sizeof(struct i2c_ram), 64);
+		cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr);
+		out_be16(i2c_base, cpm->i2c_addr);
+		iounmap(i2c_base);
+
+		cpm->version = 2;
+
+	} else {
+		iounmap(i2c_base);
+		ret = -EINVAL;
+		goto out_irq;
+	}
+
+	/* I2C control/status registers */
+	cpm->i2c_reg = of_iomap(ofdev->node, 0);
+	if (cpm->i2c_reg == NULL) {
+		ret = -EINVAL;
+		goto out_ram;
+	}
+
+	data = of_get_property(ofdev->node, "fsl,cpm-command", &len);
+	if (!data || len != 4) {
+		ret = -EINVAL;
+		goto out_reg;
+	}
+	cpm->cp_command = *data;
+
+	data = of_get_property(ofdev->node, "linux,i2c-class", &len);
+	if (data && len == 4)
+		cpm->adap.class = *data;
+
+	/*
+	 * Allocate space for CPM_MAXBD transmit and receive buffer
+	 * descriptors in the DP ram.
+	 */
+	cpm->dp_addr = cpm_muram_alloc(sizeof(cbd_t) * 2 * CPM_MAXBD, 8);
+	if (!cpm->dp_addr) {
+		ret = -ENOMEM;
+		goto out_reg;
+	}
+
+	/* Initialize Tx/Rx parameters. */
+
+	cpm_reset_i2c_params(cpm);
+
+	pr_debug("i2c-cpm: i2c_ram %x, dp_addr 0x%x\n", (uint) cpm->i2c_ram,
+		cpm->dp_addr);
+	pr_debug("i2c-cpm: tbase %d, rbase %d\n",
+		in_be16(&cpm->i2c_ram->tbase), in_be16(&cpm->i2c_ram->rbase));
+
+	tbdf = (cbd_t *) cpm_muram_addr(in_be16(&cpm->i2c_ram->tbase));
+	rbdf = (cbd_t *) cpm_muram_addr(in_be16(&cpm->i2c_ram->rbase));
+
+	/* Allocate TX and RX buffers */
+
+	for (i = 0; i < CPM_MAXBD; i++) {
+		cpm->rxbuf[i] = dma_alloc_coherent(
+			NULL, CPM_MAX_READ + 1, &cpm->rxdma[i], GFP_KERNEL);
+		if (!cpm->rxbuf[i]) {
+			ret = -ENOMEM;
+			goto out_muram;
+		}
+		rbdf[i].cbd_bufaddr = ((cpm->rxdma[i] + 1) & ~1);
+		cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent(
+			NULL, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL);
+		if (!cpm->txbuf[i]) {
+			ret = -ENOMEM;
+			goto out_muram;
+		}
+		tbdf[i].cbd_bufaddr = cpm->txdma[i];
+	}
+
+	cpm_command(cpm->cp_command, CPM_CR_INIT_TRX);
+
+	/*
+	 * Select an invalid address. Just make sure we don't use loopback mode
+	 */
+	out_8(&cpm->i2c_reg->i2add, 0xfe);
+
+	/* Make clock run at 60 kHz. */
+
+	brg = get_brgfreq() / (32 * 2 * 60000) - 3;
+	out_8(&cpm->i2c_reg->i2brg, brg);
+
+	out_8(&cpm->i2c_reg->i2mod, 0x00);
+	out_8(&cpm->i2c_reg->i2com, 0x01);	/* Master mode */
+
+	/* Disable interrupts. */
+	out_8(&cpm->i2c_reg->i2cmr, 0);
+	out_8(&cpm->i2c_reg->i2cer, 0xff);
+
+	return 0;
+
+out_muram:
+	for (i = 0; i < CPM_MAXBD; i++) {
+		if (cpm->rxbuf[i])
+			dma_free_coherent(NULL, CPM_MAX_READ + 1,
+				cpm->rxbuf[i], cpm->rxdma[i]);
+		if (cpm->txbuf[i])
+			dma_free_coherent(NULL, CPM_MAX_READ + 1,
+				cpm->txbuf[i], cpm->txdma[i]);
+	}
+	cpm_muram_free(cpm->dp_addr);
+out_reg:
+	iounmap(cpm->i2c_reg);
+out_ram:
+	if ((cpm->version == 1) && (!cpm->i2c_addr))
+		iounmap(cpm->i2c_ram);
+	if (cpm->version == 2)
+		cpm_muram_free(cpm->i2c_addr);
+out_irq:
+	free_irq(cpm->irq, &cpm->adap);
+	return ret;
+}
+
+static void cpm_i2c_shutdown(struct cpm_i2c *cpm)
+{
+	int i;
+
+	/* Shut down I2C. */
+	out_8(&cpm->i2c_reg->i2mod, in_8(&cpm->i2c_reg->i2mod) | ~1);
+
+	/* Disable interrupts */
+	out_8(&cpm->i2c_reg->i2cmr, 0);
+	out_8(&cpm->i2c_reg->i2cer, 0xff);
+
+	free_irq(cpm->irq, &cpm->adap);
+
+	/* Free all memory */
+	for (i = 0; i < CPM_MAXBD; i++) {
+		dma_free_coherent(NULL, CPM_MAX_READ + 1,
+			cpm->rxbuf[i], cpm->rxdma[i]);
+		dma_free_coherent(NULL, CPM_MAX_READ + 1,
+			cpm->txbuf[i], cpm->txdma[i]);
+	}
+
+	cpm_muram_free(cpm->dp_addr);
+	iounmap(cpm->i2c_reg);
+
+	if ((cpm->version == 1) && (!cpm->i2c_addr))
+		iounmap(cpm->i2c_ram);
+	if (cpm->version == 2)
+		cpm_muram_free(cpm->i2c_addr);
+
+	return;
+}
+
+static int __devinit cpm_i2c_probe(struct of_device *ofdev,
+			 const struct of_device_id *match)
+{
+	int result;
+	struct cpm_i2c *cpm;
+
+	cpm = kzalloc(sizeof(struct cpm_i2c), GFP_KERNEL);
+	if (!cpm)
+		return -ENOMEM;
+
+	cpm->ofdev = ofdev;
+
+	dev_set_drvdata(&ofdev->dev, cpm);
+
+	cpm->adap = cpm_ops;
+	i2c_set_adapdata(&cpm->adap, cpm);
+	cpm->adap.dev.parent = &ofdev->dev;
+
+	result = cpm_i2c_setup(cpm);
+	if (result) {
+		printk(KERN_ERR "i2c-cpm: Unable to init hardware\n");
+		goto out;
+	}
+
+	/* register new adapter to i2c module... */
+
+	result = i2c_add_adapter(&cpm->adap);
+	if (result < 0) {
+		printk(KERN_ERR "i2c-cpm: Unable to register with I2C\n");
+		goto out2;
+	}
+
+	pr_debug("i2c-cpm: hw routines for %s registered.\n", cpm->adap.name);
+
+	/*
+	 * Wait for patch from Jon Smirl
+	 * of_register_i2c_devices(&cpm->adap, ofdev->node);
+	 */
+
+	return 0;
+out2:
+	cpm_i2c_shutdown(cpm);
+out:
+	dev_set_drvdata(&ofdev->dev, NULL);
+	kfree(cpm);
+
+	return result;
+}
+
+static int __devexit cpm_i2c_remove(struct of_device *ofdev)
+{
+	struct cpm_i2c *cpm = dev_get_drvdata(&ofdev->dev);
+
+	i2c_del_adapter(&cpm->adap);
+
+	cpm_i2c_shutdown(cpm);
+
+	dev_set_drvdata(&ofdev->dev, NULL);
+	kfree(cpm);
+
+	return 0;
+}
+
+static const struct of_device_id cpm_i2c_match[] = {
+	{
+		.compatible = "fsl,cpm-i2c",
+	},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, cpm_i2c_match);
+
+static struct of_platform_driver cpm_i2c_driver = {
+	.match_table	= cpm_i2c_match,
+	.probe		= cpm_i2c_probe,
+	.remove		= __devexit_p(cpm_i2c_remove),
+	.driver		= {
+		.name	= "fsl-i2c-cpm",
+		.owner	= THIS_MODULE,
+	}
+};
+
+static int __init cpm_i2c_init(void)
+{
+	return of_register_platform_driver(&cpm_i2c_driver);
+}
+
+static void __exit cpm_i2c_exit(void)
+{
+	of_unregister_platform_driver(&cpm_i2c_driver);
+}
+
+module_init(cpm_i2c_init);
+module_exit(cpm_i2c_exit);
+
+MODULE_AUTHOR("Dan Malek <dmalek@jlc.net>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for CPM boards");
+MODULE_LICENSE("GPL");
-- 
1.5.3.8

^ permalink raw reply related

* [PATCH/RFC] [POWERPC] Add i2c pins to dts and board setup
From: Jochen Friedrich @ 2008-01-31 12:54 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev list

Add CPM i2c support for mpc8272, mpc866 and mpc885 boards.

Signed-off-by: Jochen Friedrich <jochen@scram.de>
---
 arch/powerpc/boot/dts/mpc8272ads.dts         |   10 ++++++++++
 arch/powerpc/boot/dts/mpc866ads.dts          |   10 ++++++++++
 arch/powerpc/boot/dts/mpc885ads.dts          |   10 ++++++++++
 arch/powerpc/platforms/82xx/mpc8272_ads.c    |    5 +++++
 arch/powerpc/platforms/8xx/mpc86xads_setup.c |    4 ++++
 arch/powerpc/platforms/8xx/mpc885ads_setup.c |    3 +++
 6 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts
index 7285ca1..7273996 100644
--- a/arch/powerpc/boot/dts/mpc8272ads.dts
+++ b/arch/powerpc/boot/dts/mpc8272ads.dts
@@ -215,6 +215,16 @@
 				linux,network-index = <1>;
 				fsl,cpm-command = <16200300>;
 			};
+
+			i2c@11860 {
+				compatible = "fsl,mpc8248-i2c",
+					     "fsl,cpm2-i2c",
+					     "fsl,cpm-i2c";
+				reg = <11860 20 8afc 2>;
+				interrupts = <1 8>;
+				interrupt-parent = <&PIC>;
+				fsl,cpm-command = <29600000>;
+			};
 		};
 
 		PIC: interrupt-controller@10c00 {
diff --git a/arch/powerpc/boot/dts/mpc866ads.dts b/arch/powerpc/boot/dts/mpc866ads.dts
index daf9433..d669049 100644
--- a/arch/powerpc/boot/dts/mpc866ads.dts
+++ b/arch/powerpc/boot/dts/mpc866ads.dts
@@ -169,6 +169,16 @@
 				fsl,cpm-command = <0000>;
 				linux,network-index = <1>;
 			};
+
+			i2c@860 {
+				compatible = "fsl,mpc866-i2c",
+					     "fsl,cpm1-i2c",
+					     "fsl,cpm-i2c";
+				reg = <860 20 3c80 30>;
+				interrupts = <10>;
+				interrupt-parent = <&CPM_PIC>;
+				fsl,cpm-command = <0010>;
+			};
 		};
 	};
 
diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts
index 8848e63..fd9c9d7 100644
--- a/arch/powerpc/boot/dts/mpc885ads.dts
+++ b/arch/powerpc/boot/dts/mpc885ads.dts
@@ -213,6 +213,16 @@
 				fsl,cpm-command = <0080>;
 				linux,network-index = <2>;
 			};
+
+			i2c@860 {
+				compatible = "fsl,mpc885-i2c",
+					     "fsl,cpm1-i2c",
+					     "fsl,cpm-i2c";
+				reg = <860 20 3c80 30>;
+				interrupts = <10>;
+				interrupt-parent = <&CPM_PIC>;
+				fsl,cpm-command = <0010>;
+			};
 		};
 	};
 
diff --git a/arch/powerpc/platforms/82xx/mpc8272_ads.c b/arch/powerpc/platforms/82xx/mpc8272_ads.c
index 3fce6b3..8f1862a 100644
--- a/arch/powerpc/platforms/82xx/mpc8272_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc8272_ads.c
@@ -96,6 +96,11 @@ static struct cpm_pin mpc8272_ads_pins[] = {
 	{1, 31, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
 	{2, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
 	{2, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+
+	/* I2C */
+	{3, 26, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN},
+	{3, 27, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN},
+
 };
 
 static void __init init_ioports(void)
diff --git a/arch/powerpc/platforms/8xx/mpc86xads_setup.c b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
index c028a5b..caaec29 100644
--- a/arch/powerpc/platforms/8xx/mpc86xads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
@@ -65,6 +65,10 @@ static struct cpm_pin mpc866ads_pins[] = {
 	{CPM_PORTD, 13, CPM_PIN_OUTPUT},
 	{CPM_PORTD, 14, CPM_PIN_OUTPUT},
 	{CPM_PORTD, 15, CPM_PIN_OUTPUT},
+
+	/* I2C */
+	{CPM_PORTB, 26, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
+	{CPM_PORTB, 27, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
 };
 
 static void __init init_ioports(void)
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index 6e7ded0..45ed6cd 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -158,6 +158,9 @@ static struct cpm_pin mpc885ads_pins[] = {
 	{CPM_PORTE, 28, CPM_PIN_OUTPUT},
 	{CPM_PORTE, 29, CPM_PIN_OUTPUT},
 #endif
+	/* I2C */
+	{CPM_PORTB, 26, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
+	{CPM_PORTB, 27, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
 };
 
 static void __init init_ioports(void)
-- 
1.5.3.8

^ permalink raw reply related

* Re: Configuring Freecale ucc_geth without a PHY
From: Steven Hein @ 2008-01-31 13:38 UTC (permalink / raw)
  To: Kim Phillips; +Cc: linuxppc-embedded
In-Reply-To: <20080129114310.3109caaa.kim.phillips@freescale.com>

Kim Phillips wrote:
> On Tue, 29 Jan 2008 11:08:43 -0600
> Steven Hein <ssh@sgi.com> wrote:
>
>   
>> Hi all,
>>
>> I have a custom board with an MPC8358 (our board is based
>> off of the MPC8360E-MDS development board) that has its eth's
>> directly connected (GMII) to a Broadcom network switch
>> part on the same board, with no PHYs between them.
>> We've have been using a 2.6.16.18 kernel (from TimeSys) up
>> until now, and I hacked in some crude support for no-phy
>> configs forced to 100Mbit and 1Gbit speeds.   Now I'm
>> moving to 2.6.22 (with 8360 the patches from bitshrine.org),
>> and I'm trying to understand how I should do this with
>> device trees, the new PHY infrastructure, etc.   Has anyone
>> else needed this support?   Does anyone have any suggestions
>> as to how to tackle it?
>>     
>
> check out the "fixed-link" property and associated code.  This
> implementation came about after 2.6.22 though (it's commit-ish
> v2.6.23-10096-ga21e282).
>
> Kim
>   
Thanks for the pointer Kim!     Using the "fixed-link" property
code already in the tree, and adding the glue in ucc_geth.c to
use it (modeled after the code in gianfar fix-link support
in fsl_soc.c), I was able to get this working with me 8360 board.

Is there a document anywhere that describes how to submit
patches for the powerpc kernel?    Or do I just create the patch
(I'm learning about git right now...) again the paulus/powerpc.git
tree, and send it to this list?

Thanks,
Steve

-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Steve Hein (ssh@sgi.com)              Engineering Diagnostics/Software
Silicon Graphics, Inc.                          
1168 Industrial Blvd.                 Phone: (715) 726-8410
Chippewa Falls, WI 54729              Fax:   (715) 726-6715
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

^ permalink raw reply

* Kernel oops while duming user core.
From: Rune Torgersen @ 2008-01-31 13:45 UTC (permalink / raw)
  To: linuxppc-dev

Hi

I get the following kernel core while a user program I have is dumping
core.
Any DIeas at what to look for? (this is runnign 2.6.24, arch/powerpc on
a 8280)
When runnign the program on 2.6.18 arch/ppc, the program gets a sig 11
and dumps core.
On 2.6.24, I ghet the kernel oops, and then the program hangs sround
forever and is unkillable.

Unable to handle kernel paging request for data at address 0x48024000
Faulting instruction address: 0xc000ef88
Oops: Kernel access of bad area, sig: 11 [#1]
PREEMPT Innovative Systems ApMax
Modules linked in: drv_wd(P) drv_scc devcom drv_pcir tipc drv_ss7
drv_auxcpu drv_leds(P) drv_ethsw proc_sysinfo(P) i2c_8266(P)
NIP: c000ef88 LR: c0012180 CTR: 00000080
REGS: eebc9b70 TRAP: 0300   Tainted: P         (2.6.24)
MSR: 00009032 <EE,ME,IR,DR>  CR: 24004442  XER: 00000000
DAR: 48024000, DSISR: 20000000
TASK =3D eebac3c0[3131] 'armd' THREAD: eebc8000
GPR00: ee9b7d00 eebc9c20 eebac3c0 48024000 00000080 399a4181 48024000
00000000
GPR08: 399a4181 ee9b7d00 00000000 c2000000 44004422 10100f38 ee82fc00
bfffffff
GPR16: ef377060 00000030 ee9b7d00 00000000 eebc9cdc 00000011 eebc9cd8
eeb96480
GPR24: ee9b7d00 399a4181 48024000 eeb9a370 eeb9a370 399a4181 48024000
c2733480
NIP [c000ef88] __flush_dcache_icache+0x14/0x40
LR [c0012180] update_mmu_cache+0x74/0x114
Call Trace:
[eebc9c20] [eebc8000] 0xeebc8000 (unreliable)
[eebc9c40] [c005d060] handle_mm_fault+0x630/0xbc0
[eebc9c80] [c005d9e4] get_user_pages+0x3f4/0x4fc
[eebc9cd0] [c00aa7c4] elf_core_dump+0x9a4/0xc5c
[eebc9d60] [c00779e4] do_coredump+0x6e0/0x748
[eebc9e50] [c002a5b0] get_signal_to_deliver+0x40c/0x45c
[eebc9e80] [c0008ce8] do_signal+0x50/0x294
[eebc9f40] [c000fb98] do_user_signal+0x74/0xc4
--- Exception: 300 at 0x10044efc
    LR =3D 0x10044ec0
Instruction dump:
4d820020 7c8903a6 7c001bac 38630020 4200fff8 7c0004ac 4e800020 60000000
54630026 38800080 7c8903a6 7c661b78 <7c00186c> 38630020 4200fff8
7c0004ac
---[ end trace 97db37eaf213da3c ]---
note: armd[3131] exited with preempt_count 2
=20

^ permalink raw reply

* [PATCH v7] [POWERPC] Add LED driver for Promess Motion-PRO board.
From: Marian Balakowicz @ 2008-01-31 13:49 UTC (permalink / raw)
  To: linuxppc-dev

Add support for two Motion-PRO board custom LEDs:
- motionpro-statusled
- motionpro-readyled

Signed-off-by: Jan Wrobel <wrr@semihalf.com>
Signed-off-by: Marian Balakowicz <m8@semihalf.com>
---

Update since v6:
- fix error handling for null label proper

 drivers/leds/Kconfig          |    7 +
 drivers/leds/Makefile         |    3 
 drivers/leds/leds-motionpro.c |  250 +++++++++++++++++++++++++++++++++++++++++
 include/asm-powerpc/mpc52xx.h |    5 +
 4 files changed, 264 insertions(+), 1 deletions(-)
 create mode 100644 drivers/leds/leds-motionpro.c


diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index ec568fa..1567ed6 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -55,6 +55,13 @@ config LEDS_TOSA
 	  This option enables support for the LEDs on Sharp Zaurus
 	  SL-6000 series.
 
+config LEDS_MOTIONPRO
+	tristate "Motion-PRO LEDs Support"
+	depends on LEDS_CLASS && PPC_MPC5200
+	help
+	  This option enables support for status and ready LEDs connected
+	  to GPIO lines on Motion-PRO board.
+
 config LEDS_S3C24XX
 	tristate "LED Support for Samsung S3C24XX GPIO LEDs"
 	depends on LEDS_CLASS && ARCH_S3C2410
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index a60de1b..a56d399 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -18,7 +18,8 @@ obj-$(CONFIG_LEDS_H1940)		+= leds-h1940.o
 obj-$(CONFIG_LEDS_COBALT_QUBE)		+= leds-cobalt-qube.o
 obj-$(CONFIG_LEDS_COBALT_RAQ)		+= leds-cobalt-raq.o
 obj-$(CONFIG_LEDS_GPIO)			+= leds-gpio.o
-obj-$(CONFIG_LEDS_CM_X270)              += leds-cm-x270.o
+obj-$(CONFIG_LEDS_CM_X270)		+= leds-cm-x270.o
+obj-$(CONFIG_LEDS_MOTIONPRO)		+= leds-motionpro.o
 
 # LED Triggers
 obj-$(CONFIG_LEDS_TRIGGER_TIMER)	+= ledtrig-timer.o
diff --git a/drivers/leds/leds-motionpro.c b/drivers/leds/leds-motionpro.c
new file mode 100644
index 0000000..b8dfa8a
--- /dev/null
+++ b/drivers/leds/leds-motionpro.c
@@ -0,0 +1,250 @@
+/*
+ * LEDs driver for the Motion-PRO board.
+ *
+ * Copyright (C) 2007 Semihalf
+ * Jan Wrobel <wrr@semihalf.com>
+ * Marian Balakowicz <m8@semihalf.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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., 51
+ * Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *
+ * Decription:
+ * This driver enables control over Motion-PRO status and ready LEDs through
+ * sysfs. LEDs can be controlled by writing to sysfs files:
+ * class/leds/<led-name>/(brightness|delay_off|delay_on).
+ * See Documentation/leds-class.txt for more details.
+ * <led-name> is the set to the value of 'label' property of the
+ * corresponding GPT node.
+ *
+ * Before user issues first control command via sysfs, LED blinking is
+ * controlled by the kernel ('blink-delay' property of the GPT node
+ * in the device tree blob).
+ *
+ */
+
+#define DEBUG
+
+#include <linux/module.h>
+#include <linux/leds.h>
+#include <linux/of_platform.h>
+#include <asm/mpc52xx.h>
+
+/* LED control bits */
+#define LED_ON	MPC52xx_GPT_OUTPUT_1
+
+/* LED mode */
+#define LED_MODE_KERNEL		1
+#define LED_MODE_USER		2
+
+struct motionpro_led {
+	spinlock_t led_lock;		/* Protects the LED data */
+	struct mpc52xx_gpt __iomem *gpt;/* LED registers */
+	struct timer_list blink_timer;	/* Used if blink_delay is nonzero */
+	unsigned int blink_delay;	/* [ms], if set to 0 blinking is off */
+	unsigned int mode;		/* kernel/user */
+	struct led_classdev mpled_cdev;	/* LED class */
+};
+
+/*
+ * Timer event - blinks LED before user takes control over it
+ * with the first access via sysfs.
+ */
+static void mpled_timer_toggle(unsigned long data)
+{
+	struct motionpro_led *mpled = (struct motionpro_led *)data;
+
+	spin_lock_bh(&mpled->led_lock);
+	if (mpled->mode == LED_MODE_KERNEL) {
+		u32 val = in_be32(&mpled->gpt->mode);
+		val ^= LED_ON;
+		out_be32(&mpled->gpt->mode, val);
+
+		mod_timer(&mpled->blink_timer,
+			jiffies + msecs_to_jiffies(mpled->blink_delay));
+	}
+	spin_unlock_bh(&mpled->led_lock);
+}
+
+/*
+ * Turn on/off led according to user settings in sysfs.
+ * First call to this function disables kernel blinking.
+ */
+static void mpled_set(struct led_classdev *led_cdev,
+		      enum led_brightness brightness)
+{
+	struct motionpro_led *mpled;
+	int old_mode;
+	u32 val;
+
+	mpled = container_of(led_cdev, struct motionpro_led, mpled_cdev);
+
+	spin_lock_bh(&mpled->led_lock);
+	/* disable kernel controll */
+	old_mode = mpled->mode;
+	if (old_mode == LED_MODE_KERNEL)
+		mpled->mode = LED_MODE_USER;
+
+	val = in_be32(&mpled->gpt->mode);
+	if (brightness)
+		val |= LED_ON;
+	else
+		val &= ~LED_ON;
+	out_be32(&mpled->gpt->mode, val);
+	spin_unlock_bh(&mpled->led_lock);
+
+	/* delete kernel mode blink timer, not needed anymore */
+	if ((old_mode == LED_MODE_KERNEL) && mpled->blink_delay)
+		del_timer(&mpled->blink_timer);
+}
+
+static void mpled_init_led(void __iomem *gpt_mode)
+{
+	u32 val = in_be32(gpt_mode);
+	val |= MPC52xx_GPT_ENABLE_OUTPUT;
+	val &= ~LED_ON;
+	out_be32(gpt_mode, val);
+}
+
+static int __devinit mpled_probe(struct of_device *op,
+				 const struct of_device_id *match)
+{
+	struct motionpro_led *mpled;
+	const unsigned int *of_blink_delay;
+	const char *label;
+	int err;
+
+	dev_dbg(&op->dev, "mpled_probe: node=%s (op=%p, match=%p)\n",
+		op->node->name, op, match);
+
+	mpled = kzalloc(sizeof(*mpled), GFP_KERNEL);
+	if (!mpled)
+		return -ENOMEM;
+
+	mpled->gpt = of_iomap(op->node, 0);
+	if (!mpled->gpt) {
+		printk(KERN_ERR __FILE__ ": "
+			"Error mapping GPT registers for LED %s\n",
+			op->node->full_name);
+		err = -EIO;
+		goto err_free;
+	}
+
+	/* initialize GPT for LED use */
+	mpled_init_led(&mpled->gpt->mode);
+
+	spin_lock_init(&mpled->led_lock);
+	mpled->mode = LED_MODE_KERNEL;
+
+	/* get LED label, used to register led classdev */
+	label = of_get_property(op->node, "label", NULL);
+	if (label == NULL) {
+		printk(KERN_ERR __FILE__ ": "
+			"No label property provided for LED %s\n",
+			op->node->full_name);
+		err = -EINVAL;
+		goto err;
+	}
+	dev_dbg(&op->dev, "mpled_probe: label = '%s'\n", label);
+
+	/* get 'blink-delay' property if present */
+	of_blink_delay = of_get_property(op->node, "blink-delay", NULL);
+	mpled->blink_delay =  of_blink_delay ? *of_blink_delay : 0;
+	dev_dbg(&op->dev, "mpled_probe: blink_delay = %d msec\n",
+		mpled->blink_delay);
+
+	/* initialize kernel blink_timer if blink_delay was provided */
+	if (mpled->blink_delay) {
+		init_timer(&mpled->blink_timer);
+		mpled->blink_timer.function = mpled_timer_toggle;
+		mpled->blink_timer.data = (unsigned long)mpled;
+
+		mod_timer(&mpled->blink_timer,
+			jiffies + msecs_to_jiffies(mpled->blink_delay));
+	}
+
+	/* register LED classdev */
+	mpled->mpled_cdev.name = label;
+	mpled->mpled_cdev.brightness_set = mpled_set;
+	mpled->mpled_cdev.default_trigger = "timer";
+
+	err = led_classdev_register(NULL, &mpled->mpled_cdev);
+	if (err) {
+		printk(KERN_ERR __FILE__ ": "
+			"Error registering class device for LED %s\n",
+			op->node->full_name);
+		goto err;
+	}
+
+	dev_set_drvdata(&op->dev, mpled);
+	return 0;
+
+err:
+	if (mpled->blink_delay)
+		del_timer(&mpled->blink_timer);
+	iounmap(mpled->gpt);
+err_free:
+	kfree(mpled);
+
+	return err;
+}
+
+static int mpled_remove(struct of_device *op)
+{
+	struct motionpro_led *mpled = dev_get_drvdata(&op->dev);
+
+	dev_dbg(&op->dev, "mpled_remove: (%p)\n", op);
+
+	if (mpled->blink_delay && (mpled->mode == LED_MODE_KERNEL))
+		del_timer(&mpled->blink_timer);
+
+	led_classdev_unregister(&mpled->mpled_cdev);
+
+	iounmap(mpled->gpt);
+	kfree(mpled);
+
+	return 0;
+}
+
+static const struct of_device_id mpled_match[] = {
+	{ .compatible = "promess,motionpro-led", },
+	{},
+};
+
+static struct of_platform_driver mpled_driver = {
+	.match_table	= mpled_match,
+	.probe		= mpled_probe,
+	.remove		= mpled_remove,
+	.driver		= {
+		.owner		= THIS_MODULE,
+		.name		= "leds-motionpro",
+	},
+};
+
+static int __init mpled_init(void)
+{
+	return of_register_platform_driver(&mpled_driver);
+}
+
+static void __exit mpled_exit(void)
+{
+	of_unregister_platform_driver(&mpled_driver);
+}
+
+module_init(mpled_init);
+module_exit(mpled_exit);
+
+MODULE_LICENSE("GPL")
+MODULE_DESCRIPTION("Motion-PRO LED driver");
+MODULE_AUTHOR("Jan Wrobel <wrr@semihalf.com>");
+MODULE_AUTHOR("Marian Balakowicz <m8@semihalf.com>");
diff --git a/include/asm-powerpc/mpc52xx.h b/include/asm-powerpc/mpc52xx.h
index 1c48c6d..de869ee 100644
--- a/include/asm-powerpc/mpc52xx.h
+++ b/include/asm-powerpc/mpc52xx.h
@@ -147,6 +147,11 @@ struct mpc52xx_gpio {
 #define MPC52xx_GPIO_PSC_CONFIG_UART_WITH_CD	5
 #define MPC52xx_GPIO_PCI_DIS			(1<<15)
 
+/* Enables GPT register to operate as simple GPIO output register */
+#define MPC52xx_GPT_ENABLE_OUTPUT	0x00000024
+/* Puts 1 on GPT output pin */
+#define MPC52xx_GPT_OUTPUT_1		0x00000010
+
 /* GPIO with WakeUp*/
 struct mpc52xx_gpio_wkup {
 	u8 wkup_gpioe;		/* GPIO_WKUP + 0x00 */

^ permalink raw reply related

* build fails for adder875 for new pulls of powerpc.git
From: Rognlien Dag Kristian @ 2008-01-31 14:18 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <mailman.1812.1201784040.6908.linuxppc-dev@ozlabs.org>

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


The latest commits to powerpc.git removes commproc.h files used by arch/powerpc/platforms/8xx/adder875.c

The kernel fails to build for the adder configs.

Regards,
Dag Rognlien

[-- Attachment #2: winmail.dat --]
[-- Type: application/ms-tnef, Size: 2642 bytes --]

^ permalink raw reply

* Re: [RFC] [POWERPC] bootwrapper: build multiple cuImages
From: Scott Wood @ 2008-01-31 16:00 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <fa686aa40801301840k3d9a9ba2n251d2cdb9e659748@mail.gmail.com>

On Wed, Jan 30, 2008 at 07:40:28PM -0700, Grant Likely wrote:
> mpc866ads, mpc885ads and ep88xc are oddities in that they build
> zImages with embedded device tree blobs.  

What about ep8248e?  And the mpc8xxads boards use cuImage, not zImage.

> One option would be to add two new targets: zImage.dtb.% and
> zImage.initrd.dtb.%, but I'm not sure if it is a good idea.

I'd much prefer that over having several lines per board in the makefile.

-Scott

^ permalink raw reply

* RE: Kernel oops while duming user core.
From: Rune Torgersen @ 2008-01-31 16:26 UTC (permalink / raw)
  To: Nathan Lynch; +Cc: linuxppc-dev
In-Reply-To: <20080131161527.GT14201@localdomain>

Nathan Lynch wrote:
> Hmm, this is the second report of 2.6.24 crashing in
> __flush_dcache_icache during a core dump; see:
> http://ozlabs.org/pipermail/linuxppc-dev/2007-December/048662.html
>=20
> Is this easily recreatable?

Yes. I have a binary that will do this every time it is started (on this
particular system),=20
only takes about 10 seconds before it dumps.

I was going to test HEAD of powerpc.git to see if it is still there.
I cannot test any earlier versions as our board port was done on 2.6.24.

Our older kernel port is 2.6.18 on arch/ppc, and it works just fine.


One potential clue:
> Unable to handle kernel paging request for data at address 0x48024000

this adddress is beyond our physical memory. We have 1GB of mem=20
(CONFIG_HIGH_MEM enabled) so 0x3fff_ffff is the last valid address.
0x4000_0000 to 0x7fff_ffff are unused, 0x8000_0000 to 0x9fff_ffff is
used by PCI.

^ permalink raw reply

* [PATCH v2] [POWERPC] Set dma_data correctly for direct_ops on pasemi
From: Olof Johansson @ 2008-01-31 16:25 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, torvalds
In-Reply-To: <20080131064130.GA32344@lixom.net>


More fallout from the merge:

[POWERPC] Use archdata.dma_data in dma_direct_ops and add the offset

"Now that all platforms using dma_direct_offset setup the
archdata.dma_data correctly, ..."

Nope -- the pasemi iommu setup code that disables translation on the DMA
pci device still set dma_data to point at the table. The below patch is
needed, please merge asap.


Signed-off-by: Olof Johansson <olof@lixom.net>

diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c
index 9916a0f..5803f11 100644
--- a/arch/powerpc/platforms/pasemi/iommu.c
+++ b/arch/powerpc/platforms/pasemi/iommu.c
@@ -182,8 +182,10 @@ static void pci_dma_dev_setup_pasemi(struct pci_dev *dev)
 	 * CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE at build time.
 	 */
 	if (dev->vendor == 0x1959 && dev->device == 0xa007 &&
-	    !firmware_has_feature(FW_FEATURE_LPAR))
+	    !firmware_has_feature(FW_FEATURE_LPAR)) {
 		dev->dev.archdata.dma_ops = &dma_direct_ops;
+		return;
+	}
 #endif
 
 	dev->dev.archdata.dma_data = &iommu_table_iobmap;

^ permalink raw reply related

* Re: [PATCH] [POWERPC] Set dma_data correctly for direct_ops on pasemi
From: Olof Johansson @ 2008-01-31 16:18 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: torvalds, Paul Mackerras, linuxppc-dev
In-Reply-To: <1201783096.4147.3.camel@concordia>

On Thu, Jan 31, 2008 at 11:38:16PM +1100, Michael Ellerman wrote:
> On Thu, 2008-01-31 at 00:41 -0600, Olof Johansson wrote:
> > More late-caught fallout from the mainline merge. The patch:
> > 
> > [POWERPC] Use archdata.dma_data in dma_direct_ops and add the offset
> > 
> > "Now that all platforms using dma_direct_offset setup the
> > archdata.dma_data correctly, ..."
> > 
> > Nope -- the pasemi iommu setup code that disables translation on the
> > DMA pci device didn't set dma_data correctly.
> > 
> > The below patch is needed, please merge as soon as practical. Thanks!
> 
> Sorry about that.
> 
> I'm confused though, didn't your device come from alloc_pci_dev() which
> kzalloc()s the pci_dev which contains the archdata which contains the
> dma_data, ie. dma_data will already be 0?

Yeah, I don't see how my patch could work (but it did), since the code
falls through and overwrites dma_data with the pointer to the table,
just as before. Weird, I did test it last night. See new patch.


-Olof

^ permalink raw reply


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