* 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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox