* [PATCH v2 3/4] powerpc: add e500 HID1 bit definition
From: Li Yang @ 2010-06-18 6:24 UTC (permalink / raw)
To: galak, linuxppc-dev
In-Reply-To: <1276842263-4186-2-git-send-email-leoli@freescale.com>
Also make 74xx HID1 definition conditional.
Signed-off-by: Li Yang <leoli@freescale.com>
---
arch/powerpc/include/asm/reg.h | 2 ++
arch/powerpc/include/asm/reg_booke.h | 16 ++++++++++++++++
2 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index d62fdf4..235d356 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -283,6 +283,7 @@
#define HID0_NOPTI (1<<0) /* No-op dcbt and dcbst instr. */
#define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */
+#ifdef CONFIG_6xx
#define HID1_EMCP (1<<31) /* 7450 Machine Check Pin Enable */
#define HID1_DFS (1<<22) /* 7447A Dynamic Frequency Scaling */
#define HID1_PC0 (1<<16) /* 7450 PLL_CFG[0] */
@@ -292,6 +293,7 @@
#define HID1_SYNCBE (1<<11) /* 7450 ABE for sync, eieio */
#define HID1_ABE (1<<10) /* 7450 Address Broadcast Enable */
#define HID1_PS (1<<16) /* 750FX PLL selection */
+#endif
#define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */
#define SPRN_HID2_GEKKO 0x398 /* Gekko HID2 Register */
#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 2360317..6d393f7 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -245,6 +245,22 @@
store or cache line push */
#endif
+/* Bit definitions for the HID1 */
+#ifdef CONFIG_E500
+#ifndef CONFIG_PPC_E500MC
+/* e500v1/v2 */
+#define HID1_PLL_CFG_MASK 0xfc000000UL /* PLL_CFG input pins */
+#define HID1_RFXE 0x00020000UL /* Read fault exception enable */
+#define HID1_R1DPE 0x00008000UL /* R1 data bus parity enable */
+#define HID1_R2DPE 0x00004000UL /* R2 data bus parity enable */
+#define HID1_ASTME 0x00002000UL /* Address bus streaming mode enable */
+#define HID1_ABE 0x00001000UL /* Address broadcast enable */
+#define HID1_MPXTT 0x00000400UL /* MPX re-map transfer type */
+#define HID1_ATS 0x00000080UL /* Atomic status */
+#define HID1_MID_MASK 0x0000000fUL /* MID input pins */
+#endif
+#endif
+
/* Bit definitions for the DBSR. */
/*
* DBSR bits which have conflicting definitions on true Book E versus IBM 40x.
--
1.6.4
^ permalink raw reply related
* [PATCH v2 4/4] fsl_rio: fix non-standard HID1 register access
From: Li Yang @ 2010-06-18 6:24 UTC (permalink / raw)
To: galak, linuxppc-dev
In-Reply-To: <1276842263-4186-3-git-send-email-leoli@freescale.com>
The access to HID1 register is only legitimate for e500 v1/v2 cores.
Also fixes magic number.
Signed-off-by: Li Yang <leoli@freescale.com>
---
arch/powerpc/sysdev/fsl_rio.c | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 954a754..aa9a21d 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1523,9 +1523,12 @@ int fsl_rio_setup(struct of_device *dev)
#ifdef CONFIG_E500
saved_mcheck_exception = ppc_md.machine_check_exception;
ppc_md.machine_check_exception = fsl_rio_mcheck_exception;
-#endif
- /* Ensure that RFXE is set */
- mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000));
+
+#ifndef CONFIG_PPC_E500MC
+ /* Ensure that RFXE is set on e500 v1/v2 */
+ mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | HID1_RFXE));
+#endif /* !PPC_E500MC */
+#endif /* E500 */
return 0;
err:
--
1.6.4
^ permalink raw reply related
* [PATCH v2 2/4] fsl_rio: fix machine check exception for e500mc
From: Li Yang @ 2010-06-18 6:24 UTC (permalink / raw)
To: galak, linuxppc-dev
In-Reply-To: <1276842263-4186-1-git-send-email-leoli@freescale.com>
The original code only covers e500 v1/v2.
Signed-off-by: Li Yang <leoli@freescale.com>
---
arch/powerpc/sysdev/fsl_rio.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index f908ba6..954a754 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -248,7 +248,8 @@ static int fsl_rio_mcheck_exception(struct pt_regs *regs)
const struct exception_table_entry *entry = NULL;
unsigned long reason = mfspr(SPRN_MCSR);
- if (reason & MCSR_BUS_RBERR) {
+ /* covers both e500v1/v2 and e500mc */
+ if (reason & (MCSR_BUS_RBERR | MCSR_LD)) {
reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR));
if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) {
/* Check if we are prepared to handle this fault */
--
1.6.4
^ permalink raw reply related
* [PATCH v2 1/4] fsl_rio: fix compile errors
From: Li Yang @ 2010-06-18 6:24 UTC (permalink / raw)
To: galak, linuxppc-dev
Fixes the following compile problem on E500 platforms:
arch/powerpc/sysdev/fsl_rio.c: In function 'fsl_rio_mcheck_exception':
arch/powerpc/sysdev/fsl_rio.c:248: error: 'MCSR_MASK' undeclared (first use in this function)
Also fixes the compile problem on non-E500 platforms.
Signed-off-by: Li Yang <leoli@freescale.com>
---
arch/powerpc/sysdev/fsl_rio.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 30e1626..f908ba6 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -240,12 +240,13 @@ struct rio_priv {
static void __iomem *rio_regs_win;
+#ifdef CONFIG_E500
static int (*saved_mcheck_exception)(struct pt_regs *regs);
static int fsl_rio_mcheck_exception(struct pt_regs *regs)
{
const struct exception_table_entry *entry = NULL;
- unsigned long reason = (mfspr(SPRN_MCSR) & MCSR_MASK);
+ unsigned long reason = mfspr(SPRN_MCSR);
if (reason & MCSR_BUS_RBERR) {
reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR));
@@ -269,6 +270,7 @@ static int fsl_rio_mcheck_exception(struct pt_regs *regs)
else
return cur_cpu_spec->machine_check(regs);
}
+#endif
/**
* fsl_rio_doorbell_send - Send a MPC85xx doorbell message
@@ -1517,8 +1519,10 @@ int fsl_rio_setup(struct of_device *dev)
fsl_rio_doorbell_init(port);
fsl_rio_port_write_init(port);
+#ifdef CONFIG_E500
saved_mcheck_exception = ppc_md.machine_check_exception;
ppc_md.machine_check_exception = fsl_rio_mcheck_exception;
+#endif
/* Ensure that RFXE is set */
mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000));
--
1.6.4
^ permalink raw reply related
* Re: [PATCH 3/3] fsl_rio: fix non-standard HID1 register access
From: Kumar Gala @ 2010-06-18 5:51 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linuxppc-dev
In-Reply-To: <AANLkTind1zMrnldhZmeacglmVyfX8VN2qO_JJlkPAe0v@mail.gmail.com>
On Jun 18, 2010, at 12:46 AM, Geert Uytterhoeven wrote:
> On Fri, Jun 18, 2010 at 07:29, Li Yang <leoli@freescale.com> wrote:
>> The access to HID1 register is only legitimate for e500 v1/v2 cores.
>>
>> Signed-off-by: Li Yang <leoli@freescale.com>
>> ---
>> arch/powerpc/sysdev/fsl_rio.c | 7 +++++--
>> 1 files changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
>> index 954a754..785a882 100644
>> --- a/arch/powerpc/sysdev/fsl_rio.c
>> +++ b/arch/powerpc/sysdev/fsl_rio.c
>> @@ -1523,9 +1523,12 @@ int fsl_rio_setup(struct of_device *dev)
>> #ifdef CONFIG_E500
>> saved_mcheck_exception = ppc_md.machine_check_exception;
>> ppc_md.machine_check_exception = fsl_rio_mcheck_exception;
>> -#endif
>> - /* Ensure that RFXE is set */
>> +
>> +#ifndef CONFIG_E500MC
>> + /* Ensure that RFXE is set on e500 v1/v2 */
>> mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000));
>> +#endif /* !E500MC */
>> +#endif /* E500 */
>>
>> return 0;
>> err:
>
> This prevents you from building a kernel for both normal E500 and E500MC.
>
> Gr{oetje,eeting}s,
Also, not a fan of the magic number 0x20000.
- k
^ permalink raw reply
* Re: [PATCH 3/3] fsl_rio: fix non-standard HID1 register access
From: Geert Uytterhoeven @ 2010-06-18 5:46 UTC (permalink / raw)
To: Li Yang; +Cc: linuxppc-dev
In-Reply-To: <1276838958-28947-3-git-send-email-leoli@freescale.com>
On Fri, Jun 18, 2010 at 07:29, Li Yang <leoli@freescale.com> wrote:
> The access to HID1 register is only legitimate for e500 v1/v2 cores.
>
> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
> =C2=A0arch/powerpc/sysdev/fsl_rio.c | =C2=A0 =C2=A07 +++++--
> =C2=A01 files changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.=
c
> index 954a754..785a882 100644
> --- a/arch/powerpc/sysdev/fsl_rio.c
> +++ b/arch/powerpc/sysdev/fsl_rio.c
> @@ -1523,9 +1523,12 @@ int fsl_rio_setup(struct of_device *dev)
> =C2=A0#ifdef CONFIG_E500
> =C2=A0 =C2=A0 =C2=A0 =C2=A0saved_mcheck_exception =3D ppc_md.machine_chec=
k_exception;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0ppc_md.machine_check_exception =3D fsl_rio_mch=
eck_exception;
> -#endif
> - =C2=A0 =C2=A0 =C2=A0 /* Ensure that RFXE is set */
> +
> +#ifndef CONFIG_E500MC
> + =C2=A0 =C2=A0 =C2=A0 /* Ensure that RFXE is set on e500 v1/v2 */
> =C2=A0 =C2=A0 =C2=A0 =C2=A0mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000))=
;
> +#endif /* !E500MC */
> +#endif /* E500 */
>
> =C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;
> =C2=A0err:
This prevents you from building a kernel for both normal E500 and E500MC.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k=
.org
In personal conversations with technical people, I call myself a hacker. Bu=
t
when I'm talking to journalists I just say "programmer" or something like t=
hat.
-- Linus Torvalds
^ permalink raw reply
* [PATCH 3/3] fsl_rio: fix non-standard HID1 register access
From: Li Yang @ 2010-06-18 5:29 UTC (permalink / raw)
To: galak, linuxppc-dev
In-Reply-To: <1276838958-28947-2-git-send-email-leoli@freescale.com>
The access to HID1 register is only legitimate for e500 v1/v2 cores.
Signed-off-by: Li Yang <leoli@freescale.com>
---
arch/powerpc/sysdev/fsl_rio.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 954a754..785a882 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1523,9 +1523,12 @@ int fsl_rio_setup(struct of_device *dev)
#ifdef CONFIG_E500
saved_mcheck_exception = ppc_md.machine_check_exception;
ppc_md.machine_check_exception = fsl_rio_mcheck_exception;
-#endif
- /* Ensure that RFXE is set */
+
+#ifndef CONFIG_E500MC
+ /* Ensure that RFXE is set on e500 v1/v2 */
mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000));
+#endif /* !E500MC */
+#endif /* E500 */
return 0;
err:
--
1.6.4
^ permalink raw reply related
* [PATCH 2/3] fsl_rio: fix machine check exception for e500mc
From: Li Yang @ 2010-06-18 5:29 UTC (permalink / raw)
To: galak, linuxppc-dev
In-Reply-To: <1276838958-28947-1-git-send-email-leoli@freescale.com>
The original code only covers e500 v1/v2.
Signed-off-by: Li Yang <leoli@freescale.com>
---
arch/powerpc/sysdev/fsl_rio.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index f908ba6..954a754 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -248,7 +248,8 @@ static int fsl_rio_mcheck_exception(struct pt_regs *regs)
const struct exception_table_entry *entry = NULL;
unsigned long reason = mfspr(SPRN_MCSR);
- if (reason & MCSR_BUS_RBERR) {
+ /* covers both e500v1/v2 and e500mc */
+ if (reason & (MCSR_BUS_RBERR | MCSR_LD)) {
reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR));
if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) {
/* Check if we are prepared to handle this fault */
--
1.6.4
^ permalink raw reply related
* [PATCH 1/3] fsl_rio: fix compile errors
From: Li Yang @ 2010-06-18 5:29 UTC (permalink / raw)
To: galak, linuxppc-dev
Fixes the following compile problem on E500 platforms:
arch/powerpc/sysdev/fsl_rio.c: In function 'fsl_rio_mcheck_exception':
arch/powerpc/sysdev/fsl_rio.c:248: error: 'MCSR_MASK' undeclared (first use in this function)
Also fixes the compile problem on non-E500 platforms.
Signed-off-by: Li Yang <leoli@freescale.com>
---
arch/powerpc/sysdev/fsl_rio.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 30e1626..f908ba6 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -240,12 +240,13 @@ struct rio_priv {
static void __iomem *rio_regs_win;
+#ifdef CONFIG_E500
static int (*saved_mcheck_exception)(struct pt_regs *regs);
static int fsl_rio_mcheck_exception(struct pt_regs *regs)
{
const struct exception_table_entry *entry = NULL;
- unsigned long reason = (mfspr(SPRN_MCSR) & MCSR_MASK);
+ unsigned long reason = mfspr(SPRN_MCSR);
if (reason & MCSR_BUS_RBERR) {
reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR));
@@ -269,6 +270,7 @@ static int fsl_rio_mcheck_exception(struct pt_regs *regs)
else
return cur_cpu_spec->machine_check(regs);
}
+#endif
/**
* fsl_rio_doorbell_send - Send a MPC85xx doorbell message
@@ -1517,8 +1519,10 @@ int fsl_rio_setup(struct of_device *dev)
fsl_rio_doorbell_init(port);
fsl_rio_port_write_init(port);
+#ifdef CONFIG_E500
saved_mcheck_exception = ppc_md.machine_check_exception;
ppc_md.machine_check_exception = fsl_rio_mcheck_exception;
+#endif
/* Ensure that RFXE is set */
mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000));
--
1.6.4
^ permalink raw reply related
* Re: [PATCH]460EX on-chip SATA driver<kernel 2.6.33><resubmission>
From: Jassi Brar @ 2010-06-18 4:34 UTC (permalink / raw)
To: Rupjyoti Sarmah; +Cc: linux-ide, sr, jgarzik, linux-kernel, linuxppc-dev
In-Reply-To: <201006041226.o54CQH2V017366@amcc.com>
On Fri, Jun 4, 2010 at 9:26 PM, Rupjyoti Sarmah <rsarmah@amcc.com> wrote:
> This patch enables the on-chip DWC SATA controller of the AppliedMicro processor 460EX.
Doesn't this DWC sata IP provide AHCI ? Just curious.
^ permalink raw reply
* Re: [PATCH 5/5] of/irq: merge of_irq_map_one()
From: Grant Likely @ 2010-06-18 0:39 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux,
devicetree-discuss, linuxppc-dev
In-Reply-To: <1276819045.8826.45.camel@pasglop>
On Thu, Jun 17, 2010 at 5:57 PM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Thu, 2010-06-17 at 17:11 -0600, Grant Likely wrote:
>> On Thu, Jun 10, 2010 at 7:17 PM, Benjamin Herrenschmidt
>> <benh@kernel.crashing.org> wrote:
>> > On Thu, 2010-06-10 at 17:36 -0600, Grant Likely wrote:
>> >>
>> >> Okay. =A0I had been trying to avoid #ifdefs in the common code, but
>> >> you're probably right. =A0I'll rework.
>> >
>> > Not even ifdef's ... just move the quirk map there. You can always
>> > #define the quirk variable to 0 on archs that have no quirks, to
>> > make it compile away if you believe it represents bloat, but they
>> > are simple well localized things so I doubt it matters.
>>
>> They're pretty small, but powermac32 is the only code that actually
>> uses the quirk facility. =A0Everything else parses sanely it would
>> appear. =A0I'd rather have them localized to the powermac code and
>> eliminate the quirks from the common code.
>
> Maybe, but the way you end up gutting out some internal functions of the
> parser so they can be overriden by the arch is just plain gross :-)
Heh, I won't dispute that. Give me a day or so. If I can't come up
with anything better, then I'll just move it all over.
g.
^ permalink raw reply
* [PATCH] powerpc: Linux cannot run with 0 cores
From: Anton Blanchard @ 2010-06-18 0:33 UTC (permalink / raw)
To: benh, paulmck; +Cc: linuxppc-dev
If we configure with CONFIG_SMP=n or set NR_CPUS less than the number of
SMT threads we will set the max cores property to 0 in the
ibm,client-architecture-support structure. On new versions of firmware that
understand this property it obliges and terminates our partition.
Use DIV_ROUND_UP so we handle not only the CONFIG_SMP=n case but also the
case where NR_CPUS isn't a multiple of the number of SMT threads.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-2.6/arch/powerpc/kernel/prom_init.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/prom_init.c 2010-06-17 09:08:20.000000000 +1000
+++ linux-2.6/arch/powerpc/kernel/prom_init.c 2010-06-17 09:10:02.000000000 +1000
@@ -872,7 +872,7 @@ static void __init prom_send_capabilitie
"ibm_architecture_vec structure inconsistent: 0x%x !\n",
*cores);
} else {
- *cores = NR_CPUS / prom_count_smt_threads();
+ *cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads());
prom_printf("Max number of cores passed to firmware: 0x%x\n",
(unsigned long)*cores);
}
^ permalink raw reply
* Re: [PATCH 5/5] of/irq: merge of_irq_map_one()
From: Benjamin Herrenschmidt @ 2010-06-17 23:57 UTC (permalink / raw)
To: Grant Likely
Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux,
devicetree-discuss, linuxppc-dev
In-Reply-To: <AANLkTin5K0IL5iKj9i9qBucSpQz2-p5wIvUtC4iU0jUP@mail.gmail.com>
On Thu, 2010-06-17 at 17:11 -0600, Grant Likely wrote:
> On Thu, Jun 10, 2010 at 7:17 PM, Benjamin Herrenschmidt
> <benh@kernel.crashing.org> wrote:
> > On Thu, 2010-06-10 at 17:36 -0600, Grant Likely wrote:
> >>
> >> Okay. I had been trying to avoid #ifdefs in the common code, but
> >> you're probably right. I'll rework.
> >
> > Not even ifdef's ... just move the quirk map there. You can always
> > #define the quirk variable to 0 on archs that have no quirks, to
> > make it compile away if you believe it represents bloat, but they
> > are simple well localized things so I doubt it matters.
>
> They're pretty small, but powermac32 is the only code that actually
> uses the quirk facility. Everything else parses sanely it would
> appear. I'd rather have them localized to the powermac code and
> eliminate the quirks from the common code.
Maybe, but the way you end up gutting out some internal functions of the
parser so they can be overriden by the arch is just plain gross :-) And
more bloat than just having a localized quirk test which can easily
compile to nothing when powermac isn't built.
IE. I'd rather you then add some kind of of_irq_map_fixup() or something
like that in the generic code that can be an empty inline when powermac
isn't there, and be defined by powerpc to do the right thing then,
rather than move the core of the function to a separate weak version.
Because the day you fix a bug in the weak variant, or change a calling
convention, you'll forget to also update the "overrides" in the arch.
> If other platforms show up with bad irq mappings, then I want to take
> the approach of fixing the data rather than adding more quirks cases.
>
> Anyway, let me try my hand at reworking to be a lot clearer and see
> what it looks like.
Ben.
^ permalink raw reply
* Re: [PATCH 5/5] of/irq: merge of_irq_map_one()
From: Grant Likely @ 2010-06-17 23:11 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux,
devicetree-discuss, linuxppc-dev
In-Reply-To: <1276219072.1962.82.camel@pasglop>
On Thu, Jun 10, 2010 at 7:17 PM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Thu, 2010-06-10 at 17:36 -0600, Grant Likely wrote:
>>
>> Okay. =A0I had been trying to avoid #ifdefs in the common code, but
>> you're probably right. =A0I'll rework.
>
> Not even ifdef's ... just move the quirk map there. You can always
> #define the quirk variable to 0 on archs that have no quirks, to
> make it compile away if you believe it represents bloat, but they
> are simple well localized things so I doubt it matters.
They're pretty small, but powermac32 is the only code that actually
uses the quirk facility. Everything else parses sanely it would
appear. I'd rather have them localized to the powermac code and
eliminate the quirks from the common code.
If other platforms show up with bad irq mappings, then I want to take
the approach of fixing the data rather than adding more quirks cases.
Anyway, let me try my hand at reworking to be a lot clearer and see
what it looks like.
g.
^ permalink raw reply
* Re: Porting a driver to powerpc using FDT
From: Chris Alfred @ 2010-06-17 22:15 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <AANLkTilWdUcjK29QAJki75miWQt7Hzv8KWOXrtCvtPi8@mail.gmail.com>
>> (1) The .dts file - this is the Flattened Device Tree (FDT)
>> descriptor:
>>
>> / {
>> ...
>>
>> virtual-device {
>> compatible = "simple-bus";
>> mydevice0 {
>> compatible = "myvendor,mydevice";
>> };
>> };
>>
>> ...
>> };
>>
>> For my board "simple-bus" is an already defined bus in the .dts.
>> In my case the .dts had:
>
> This comment raised warning flags for me. Can you post your new
> current device tree? It sounds like you put your DSA device into
> the
> localbus node. You shouldn't need to do that. Many nodes in a
> single
> tree can claim compatibility with "simple-bus".
I guess my example structure was not clear. virtual-device is not
inside localbus. My current .dts is below.
/dts-v1/;
/ {
model = "jkc,jkc5200n8";
compatible = "jkc,jkc5200n8";
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&mpc5200_pic>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
PowerPC,5200@0 {
device_type = "cpu";
reg = <0>;
d-cache-line-size = <32>;
i-cache-line-size = <32>;
d-cache-size = <0x4000>; // L1, 16K
i-cache-size = <0x4000>; // L1, 16K
timebase-frequency = <0>; // from bootloader
bus-frequency = <0>; // from bootloader
clock-frequency = <0>; // from bootloader
};
};
memory {
device_type = "memory";
reg = <0x00000000 0x10000000>; // 256MB
};
soc5200@f0000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "fsl,mpc5200b-immr";
ranges = <0 0xf0000000 0x0000c000>;
reg = <0xf0000000 0x00000100>;
bus-frequency = <0>; // from bootloader
system-frequency = <0>; // from bootloader
cdm@200 {
compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm";
reg = <0x200 0x38>;
};
mpc5200_pic: interrupt-controller@500 {
// 5200 interrupts are encoded into two levels;
interrupt-controller;
#interrupt-cells = <3>;
compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
reg = <0x500 0x80>;
};
timer@600 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x600 0x10>;
interrupts = <1 9 0>;
fsl,has-wdt;
};
timer@610 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x610 0x10>;
interrupts = <1 10 0>;
};
timer@620 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x620 0x10>;
interrupts = <1 11 0>;
};
timer@630 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x630 0x10>;
interrupts = <1 12 0>;
};
timer@640 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x640 0x10>;
interrupts = <1 13 0>;
};
timer@650 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x650 0x10>;
interrupts = <1 14 0>;
};
timer@660 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x660 0x10>;
interrupts = <1 15 0>;
};
timer@670 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x670 0x10>;
interrupts = <1 16 0>;
};
rtc@800 { // Real time clock
compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
reg = <0x800 0x100>;
interrupts = <1 5 0 1 6 0>;
};
can@900 {
compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
interrupts = <2 17 0>;
reg = <0x900 0x80>;
};
can@980 {
compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
interrupts = <2 18 0>;
reg = <0x980 0x80>;
};
gpio_simple: gpio@b00 {
compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
reg = <0xb00 0x40>;
interrupts = <1 7 0>;
gpio-controller;
#gpio-cells = <2>;
};
gpio_wkup: gpio@c00 {
compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
reg = <0xc00 0x40>;
interrupts = <1 8 0 0 3 0>;
gpio-controller;
#gpio-cells = <2>;
};
spi@f00 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
reg = <0xf00 0x20>;
interrupts = <2 13 0 2 14 0>;
interrupt-parent = <&mpc5200_pic>;
switch0: ethernet-switch@0 {
compatible = "micrel,spi-ks8995-dsa";
spi-max-frequency = <1000000>;
reg = <0>;
};
};
usb@1000 {
compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be";
reg = <0x1000 0xff>;
interrupts = <2 6 0>;
};
dma-controller@1200 {
compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm";
reg = <0x1200 0x80>;
interrupts = <3 0 0 3 1 0 3 2 0 3 3 0
3 4 0 3 5 0 3 6 0 3 7 0
3 8 0 3 9 0 3 10 0 3 11 0
3 12 0 3 13 0 3 14 0 3 15 0>;
};
xlb@1f00 {
compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb";
reg = <0x1f00 0x100>;
};
serial@2000 { // PSC1
compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
cell-index = <0>;
reg = <0x2000 0x100>;
interrupts = <2 1 0>;
};
// PSC2 in ac97 mode example
ac97@2200 { // PSC2
compatible = "fsl,mpc5200b-psc-ac97","fsl,mpc5200-psc-ac97";
cell-index = <1>;
reg = <0x2200 0x100>;
interrupts = <2 2 0>;
};
// PSC3 in CODEC mode example
i2s@2400 { // PSC3
compatible = "fsl,mpc5200b-psc-i2s"; //not 5200 compatible
cell-index = <2>;
reg = <0x2400 0x100>;
interrupts = <2 3 0>;
};
ethernet0: ethernet@3000 {
compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
reg = <0x3000 0x400>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <2 5 0>;
phy-handle = <&phy0>;
};
mdio0: mdio@3000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
reg = <0x3000 0x400>; // fec range, since we need to setup fec
interrupts
interrupts = <2 5 0>; // these are for "mii command finished", not
link changes & co.
phy0: ethernet-phy@1 {
reg = <1>;
};
};
ata@3a00 {
compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
reg = <0x3a00 0x100>;
interrupts = <2 7 0>;
};
i2c@3d00 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d00 0x40>;
interrupts = <2 15 0>;
};
i2c@3d40 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d40 0x40>;
interrupts = <2 16 0>;
};
sram@8000 {
compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram";
reg = <0x8000 0x4000>;
};
};
pci@f0000d00 {
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
device_type = "pci";
compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci";
reg = <0xf0000d00 0x100>;
interrupt-map-mask = <0xf800 0 0 7>;
interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3 // 1st slot
0xc000 0 0 2 &mpc5200_pic 1 1 3
0xc000 0 0 3 &mpc5200_pic 1 2 3
0xc000 0 0 4 &mpc5200_pic 1 3 3
0xc800 0 0 1 &mpc5200_pic 1 1 3 // 2nd slot
0xc800 0 0 2 &mpc5200_pic 1 2 3
0xc800 0 0 3 &mpc5200_pic 1 3 3
0xc800 0 0 4 &mpc5200_pic 0 0 3>;
clock-frequency = <0>; // From boot loader
interrupts = <2 8 0 2 9 0 2 10 0>;
bus-range = <0 0>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
};
virtual-device {
compatible = "simple-bus";
dsa {
compatible = "jkc,jkc5200n8-dsa-of";
ethernet-handle = <ðernet0>;
mdio-handle = <&mdio0>;
// TODO: incomplete, in design
};
};
localbus {
compatible = "fsl,mpc5200b-lpb","fsl,mpc5200-lpb","simple-bus";
#address-cells = <2>;
#size-cells = <1>;
ranges = <0 0 0xff000000 0x01000000 /* CS0: Flash */
1 0 0x10000000 0x10000000>; /* CS1: USB ISP1761 */
flash@0,0 {
compatible = "cfi-flash";
reg = <0 0 0x01000000>;
bank-width = <2>;
#size-cells = <1>;
#address-cells = <1>;
// fe000000 aliased at ff000000
partition@0 {
label = "spare";
reg = <0x00000000 0x00f00000>;
};
partition@f00000 {
label = "u-boot";
reg = <0x00f00000 0x00040000>;
};
partition@f40000 {
label = "u-boot-env";
reg = <0x00f40000 0x00020000>;
};
partition@f60000 {
label = "spare2";
reg = <0x00f60000 0x000a0000>;
};
};
isp1761@1,0 {
compatible = "nxp,usb-isp1761";
reg = <1 0 0x10000000>;
bus-width = <16>;
big-endian;
interrupts = <1 1 3>; /* HC INT */
};
};
};
^ permalink raw reply
* [PATCHv2 2/2] powerpc: Partition hibernation support
From: Brian King @ 2010-06-17 21:54 UTC (permalink / raw)
To: benh; +Cc: brking, linuxppc-dev
Enables support for HMC initiated partition hibernation. This is
a firmware assisted hibernation, since the firmware handles writing
the memory out to disk, along with other partition information,
so we just mimic suspend to ram.
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
---
arch/powerpc/Kconfig | 2
arch/powerpc/include/asm/machdep.h | 1
arch/powerpc/platforms/pseries/Makefile | 4
arch/powerpc/platforms/pseries/hotplug-cpu.c | 3
arch/powerpc/platforms/pseries/suspend.c | 214 +++++++++++++++++++++++++++
5 files changed, 223 insertions(+), 1 deletion(-)
diff -puN /dev/null arch/powerpc/platforms/pseries/suspend.c
--- /dev/null 2009-12-15 17:58:07.000000000 -0600
+++ linux-2.6-bjking1/arch/powerpc/platforms/pseries/suspend.c 2010-06-16 13:49:30.000000000 -0500
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2010 Brian King IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/delay.h>
+#include <linux/suspend.h>
+#include <asm/firmware.h>
+#include <asm/hvcall.h>
+#include <asm/machdep.h>
+#include <asm/mmu.h>
+#include <asm/rtas.h>
+
+static u64 stream_id;
+static struct sys_device suspend_sysdev;
+static DECLARE_COMPLETION(suspend_work);
+static struct rtas_suspend_me_data suspend_data;
+static atomic_t suspending;
+
+/**
+ * pseries_suspend_begin - First phase of hibernation
+ *
+ * Check to ensure we are in a valid state to hibernate
+ *
+ * Return value:
+ * 0 on success / other on failure
+ **/
+static int pseries_suspend_begin(suspend_state_t state)
+{
+ long vasi_state, rc;
+ unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+
+ /* Make sure the state is valid */
+ rc = plpar_hcall(H_VASI_STATE, retbuf, stream_id);
+
+ vasi_state = retbuf[0];
+
+ if (rc) {
+ pr_err("pseries_suspend_begin: vasi_state returned %ld\n",rc);
+ return rc;
+ } else if (vasi_state == H_VASI_ENABLED) {
+ return -EAGAIN;
+ } else if (vasi_state != H_VASI_SUSPENDING) {
+ pr_err("pseries_suspend_begin: vasi_state returned state %ld\n",
+ vasi_state);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/**
+ * pseries_suspend_cpu - Suspend a single CPU
+ *
+ * Makes the H_JOIN call to suspend the CPU
+ *
+ **/
+static int pseries_suspend_cpu(void)
+{
+ if (atomic_read(&suspending))
+ return rtas_suspend_cpu(&suspend_data);
+ return 0;
+}
+
+/**
+ * pseries_suspend_enter - Final phase of hibernation
+ *
+ * Return value:
+ * 0 on success / other on failure
+ **/
+static int pseries_suspend_enter(suspend_state_t state)
+{
+ int rc = rtas_suspend_last_cpu(&suspend_data);
+
+ atomic_set(&suspending, 0);
+ atomic_set(&suspend_data.done, 1);
+ return rc;
+}
+
+/**
+ * pseries_prepare_late - Prepare to suspend all other CPUs
+ *
+ * Return value:
+ * 0 on success / other on failure
+ **/
+static int pseries_prepare_late(void)
+{
+ atomic_set(&suspending, 1);
+ atomic_set(&suspend_data.working, 0);
+ atomic_set(&suspend_data.done, 0);
+ atomic_set(&suspend_data.error, 0);
+ suspend_data.complete = &suspend_work;
+ INIT_COMPLETION(suspend_work);
+ return 0;
+}
+
+/**
+ * store_hibernate - Initiate partition hibernation
+ * @classdev: sysdev class struct
+ * @attr: class device attribute struct
+ * @buf: buffer
+ * @count: buffer size
+ *
+ * Write the stream ID received from the HMC to this file
+ * to trigger hibernating the partition
+ *
+ * Return value:
+ * number of bytes printed to buffer / other on failure
+ **/
+static ssize_t store_hibernate(struct sysdev_class *classdev,
+ struct sysdev_class_attribute *attr,
+ const char *buf, size_t count)
+{
+ int rc;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ stream_id = simple_strtoul(buf, NULL, 16);
+
+ do {
+ rc = pseries_suspend_begin(PM_SUSPEND_MEM);
+ if (rc == -EAGAIN)
+ ssleep(1);
+ } while (rc == -EAGAIN);
+
+ if (!rc)
+ rc = pm_suspend(PM_SUSPEND_MEM);
+
+ stream_id = 0;
+
+ if (!rc)
+ rc = count;
+ return rc;
+}
+
+static SYSDEV_CLASS_ATTR(hibernate, S_IWUSR, NULL, store_hibernate);
+
+static struct sysdev_class suspend_sysdev_class = {
+ .name = "power",
+};
+
+static struct platform_suspend_ops pseries_suspend_ops = {
+ .valid = suspend_valid_only_mem,
+ .begin = pseries_suspend_begin,
+ .prepare_late = pseries_prepare_late,
+ .enter = pseries_suspend_enter,
+};
+
+/**
+ * pseries_suspend_sysfs_register - Register with sysfs
+ *
+ * Return value:
+ * 0 on success / other on failure
+ **/
+static int pseries_suspend_sysfs_register(struct sys_device *sysdev)
+{
+ int rc;
+
+ if ((rc = sysdev_class_register(&suspend_sysdev_class)))
+ return rc;
+
+ sysdev->id = 0;
+ sysdev->cls = &suspend_sysdev_class;
+
+ if ((rc = sysdev_class_create_file(&suspend_sysdev_class, &attr_hibernate)))
+ goto class_unregister;
+
+ return 0;
+
+class_unregister:
+ sysdev_class_unregister(&suspend_sysdev_class);
+ return rc;
+}
+
+/**
+ * pseries_suspend_init - initcall for pSeries suspend
+ *
+ * Return value:
+ * 0 on success / other on failure
+ **/
+static int __init pseries_suspend_init(void)
+{
+ int rc;
+
+ if (!machine_is(pseries) || !firmware_has_feature(FW_FEATURE_LPAR))
+ return 0;
+
+ suspend_data.token = rtas_token("ibm,suspend-me");
+ if (suspend_data.token == RTAS_UNKNOWN_SERVICE)
+ return 0;
+
+ if ((rc = pseries_suspend_sysfs_register(&suspend_sysdev)))
+ return rc;
+
+ ppc_md.suspend_disable_cpu = pseries_suspend_cpu;
+ suspend_set_ops(&pseries_suspend_ops);
+ return 0;
+}
+
+__initcall(pseries_suspend_init);
diff -puN arch/powerpc/Kconfig~powerpc_allarch_pseries_hibernation arch/powerpc/Kconfig
--- linux-2.6/arch/powerpc/Kconfig~powerpc_allarch_pseries_hibernation 2010-06-16 13:49:30.000000000 -0500
+++ linux-2.6-bjking1/arch/powerpc/Kconfig 2010-06-16 13:49:30.000000000 -0500
@@ -218,7 +218,7 @@ config ARCH_HIBERNATION_POSSIBLE
config ARCH_SUSPEND_POSSIBLE
def_bool y
depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \
- PPC_85xx || PPC_86xx
+ PPC_85xx || PPC_86xx || PPC_PSERIES
config PPC_DCR_NATIVE
bool
diff -puN arch/powerpc/platforms/pseries/Makefile~powerpc_allarch_pseries_hibernation arch/powerpc/platforms/pseries/Makefile
--- linux-2.6/arch/powerpc/platforms/pseries/Makefile~powerpc_allarch_pseries_hibernation 2010-06-16 13:49:30.000000000 -0500
+++ linux-2.6-bjking1/arch/powerpc/platforms/pseries/Makefile 2010-06-16 13:49:30.000000000 -0500
@@ -26,3 +26,7 @@ obj-$(CONFIG_HCALL_STATS) += hvCall_inst
obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o
obj-$(CONFIG_CMM) += cmm.o
obj-$(CONFIG_DTL) += dtl.o
+
+ifeq ($(CONFIG_PPC_PSERIES),y)
+obj-$(CONFIG_SUSPEND) += suspend.o
+endif
diff -puN arch/powerpc/include/asm/machdep.h~powerpc_allarch_pseries_hibernation arch/powerpc/include/asm/machdep.h
--- linux-2.6/arch/powerpc/include/asm/machdep.h~powerpc_allarch_pseries_hibernation 2010-06-16 13:49:30.000000000 -0500
+++ linux-2.6-bjking1/arch/powerpc/include/asm/machdep.h 2010-06-16 13:49:30.000000000 -0500
@@ -266,6 +266,7 @@ struct machdep_calls {
void (*suspend_disable_irqs)(void);
void (*suspend_enable_irqs)(void);
#endif
+ int (*suspend_disable_cpu)(void);
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
ssize_t (*cpu_probe)(const char *, size_t);
diff -puN arch/powerpc/platforms/pseries/hotplug-cpu.c~powerpc_allarch_pseries_hibernation arch/powerpc/platforms/pseries/hotplug-cpu.c
--- linux-2.6/arch/powerpc/platforms/pseries/hotplug-cpu.c~powerpc_allarch_pseries_hibernation 2010-06-16 13:49:30.000000000 -0500
+++ linux-2.6-bjking1/arch/powerpc/platforms/pseries/hotplug-cpu.c 2010-06-16 13:49:30.000000000 -0500
@@ -116,6 +116,9 @@ static void pseries_mach_cpu_die(void)
if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
set_cpu_current_state(cpu, CPU_STATE_INACTIVE);
+ if (ppc_md.suspend_disable_cpu)
+ ppc_md.suspend_disable_cpu();
+
cede_latency_hint = 2;
get_lppaca()->idle = 1;
_
^ permalink raw reply
* [PATCHv2 1/2] powerpc: Migration code reorganization / hibernation prep
From: Brian King @ 2010-06-17 21:54 UTC (permalink / raw)
To: benh; +Cc: brking, linuxppc-dev
Partition hibernation will use some of the same code as is
currently used for Live Partition Migration. This function
further abstracts this code such that code outside of rtas.c
can utilize it. It also changes the error field in the suspend
me data structure to be an atomic type, since it is set and
checked on different cpus without any barriers or locking.
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/hvcall.h | 1
arch/powerpc/include/asm/rtas.h | 10 +++
arch/powerpc/kernel/rtas.c | 105 +++++++++++++++++++++++++-------------
3 files changed, 81 insertions(+), 35 deletions(-)
diff -puN arch/powerpc/include/asm/rtas.h~powerpc_rtas_hibernate_prep arch/powerpc/include/asm/rtas.h
--- linux-2.6/arch/powerpc/include/asm/rtas.h~powerpc_rtas_hibernate_prep 2010-06-16 13:49:29.000000000 -0500
+++ linux-2.6-bjking1/arch/powerpc/include/asm/rtas.h 2010-06-16 13:49:29.000000000 -0500
@@ -63,6 +63,14 @@ struct rtas_t {
struct device_node *dev; /* virtual address pointer */
};
+struct rtas_suspend_me_data {
+ atomic_t working; /* number of cpus accessing this struct */
+ atomic_t done;
+ int token; /* ibm,suspend-me */
+ atomic_t error;
+ struct completion *complete; /* wait on this until working == 0 */
+};
+
/* RTAS event classes */
#define RTAS_INTERNAL_ERROR 0x80000000 /* set bit 0 */
#define RTAS_EPOW_WARNING 0x40000000 /* set bit 1 */
@@ -174,6 +182,8 @@ extern int rtas_set_indicator(int indica
extern int rtas_set_indicator_fast(int indicator, int index, int new_value);
extern void rtas_progress(char *s, unsigned short hex);
extern void rtas_initialize(void);
+extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data);
+extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data);
struct rtc_time;
extern unsigned long rtas_get_boot_time(void);
diff -puN arch/powerpc/kernel/rtas.c~powerpc_rtas_hibernate_prep arch/powerpc/kernel/rtas.c
--- linux-2.6/arch/powerpc/kernel/rtas.c~powerpc_rtas_hibernate_prep 2010-06-16 13:49:29.000000000 -0500
+++ linux-2.6-bjking1/arch/powerpc/kernel/rtas.c 2010-06-16 15:29:44.000000000 -0500
@@ -47,14 +47,6 @@ struct rtas_t rtas = {
};
EXPORT_SYMBOL(rtas);
-struct rtas_suspend_me_data {
- atomic_t working; /* number of cpus accessing this struct */
- atomic_t done;
- int token; /* ibm,suspend-me */
- int error;
- struct completion *complete; /* wait on this until working == 0 */
-};
-
DEFINE_SPINLOCK(rtas_data_buf_lock);
EXPORT_SYMBOL(rtas_data_buf_lock);
@@ -714,14 +706,53 @@ void rtas_os_term(char *str)
static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
#ifdef CONFIG_PPC_PSERIES
-static void rtas_percpu_suspend_me(void *info)
+static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_when_done)
+{
+ u16 slb_size = mmu_slb_size;
+ int rc = H_MULTI_THREADS_ACTIVE;
+ int cpu;
+
+ slb_set_size(SLB_MIN_SIZE);
+ printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", smp_processor_id());
+
+ while (rc == H_MULTI_THREADS_ACTIVE && !atomic_read(&data->done) &&
+ !atomic_read(&data->error))
+ rc = rtas_call(data->token, 0, 1, NULL);
+
+ if (rc || atomic_read(&data->error)) {
+ printk(KERN_DEBUG "ibm,suspend-me returned %d\n", rc);
+ slb_set_size(slb_size);
+ }
+
+ if (atomic_read(&data->error))
+ rc = atomic_read(&data->error);
+
+ atomic_set(&data->error, rc);
+
+ if (wake_when_done) {
+ atomic_set(&data->done, 1);
+
+ for_each_online_cpu(cpu)
+ plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu));
+ }
+
+ if (atomic_dec_return(&data->working) == 0)
+ complete(data->complete);
+
+ return rc;
+}
+
+int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data)
+{
+ atomic_inc(&data->working);
+ return __rtas_suspend_last_cpu(data, 0);
+}
+
+static int __rtas_suspend_cpu(struct rtas_suspend_me_data *data, int wake_when_done)
{
long rc = H_SUCCESS;
unsigned long msr_save;
- u16 slb_size = mmu_slb_size;
int cpu;
- struct rtas_suspend_me_data *data =
- (struct rtas_suspend_me_data *)info;
atomic_inc(&data->working);
@@ -729,7 +760,7 @@ static void rtas_percpu_suspend_me(void
msr_save = mfmsr();
mtmsr(msr_save & ~(MSR_EE));
- while (rc == H_SUCCESS && !atomic_read(&data->done))
+ while (rc == H_SUCCESS && !atomic_read(&data->done) && !atomic_read(&data->error))
rc = plpar_hcall_norets(H_JOIN);
mtmsr(msr_save);
@@ -741,33 +772,37 @@ static void rtas_percpu_suspend_me(void
/* All other cpus are in H_JOIN, this cpu does
* the suspend.
*/
- slb_set_size(SLB_MIN_SIZE);
- printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n",
- smp_processor_id());
- data->error = rtas_call(data->token, 0, 1, NULL);
-
- if (data->error) {
- printk(KERN_DEBUG "ibm,suspend-me returned %d\n",
- data->error);
- slb_set_size(slb_size);
- }
+ return __rtas_suspend_last_cpu(data, wake_when_done);
} else {
printk(KERN_ERR "H_JOIN on cpu %i failed with rc = %ld\n",
smp_processor_id(), rc);
- data->error = rc;
+ atomic_set(&data->error, rc);
}
- atomic_set(&data->done, 1);
+ if (wake_when_done) {
+ atomic_set(&data->done, 1);
- /* This cpu did the suspend or got an error; in either case,
- * we need to prod all other other cpus out of join state.
- * Extra prods are harmless.
- */
- for_each_online_cpu(cpu)
- plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu));
+ /* This cpu did the suspend or got an error; in either case,
+ * we need to prod all other other cpus out of join state.
+ * Extra prods are harmless.
+ */
+ for_each_online_cpu(cpu)
+ plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu));
+ }
out:
if (atomic_dec_return(&data->working) == 0)
complete(data->complete);
+ return rc;
+}
+
+int rtas_suspend_cpu(struct rtas_suspend_me_data *data)
+{
+ return __rtas_suspend_cpu(data, 0);
+}
+
+static void rtas_percpu_suspend_me(void *info)
+{
+ __rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1);
}
static int rtas_ibm_suspend_me(struct rtas_args *args)
@@ -802,22 +837,22 @@ static int rtas_ibm_suspend_me(struct rt
atomic_set(&data.working, 0);
atomic_set(&data.done, 0);
+ atomic_set(&data.error, 0);
data.token = rtas_token("ibm,suspend-me");
- data.error = 0;
data.complete = &done;
/* Call function on all CPUs. One of us will make the
* rtas call
*/
if (on_each_cpu(rtas_percpu_suspend_me, &data, 0))
- data.error = -EINVAL;
+ atomic_set(&data.error, -EINVAL);
wait_for_completion(&done);
- if (data.error != 0)
+ if (atomic_read(&data.error) != 0)
printk(KERN_ERR "Error doing global join\n");
- return data.error;
+ return atomic_read(&data.error);
}
#else /* CONFIG_PPC_PSERIES */
static int rtas_ibm_suspend_me(struct rtas_args *args)
diff -puN arch/powerpc/include/asm/hvcall.h~powerpc_rtas_hibernate_prep arch/powerpc/include/asm/hvcall.h
--- linux-2.6/arch/powerpc/include/asm/hvcall.h~powerpc_rtas_hibernate_prep 2010-06-16 13:49:29.000000000 -0500
+++ linux-2.6-bjking1/arch/powerpc/include/asm/hvcall.h 2010-06-16 13:49:29.000000000 -0500
@@ -74,6 +74,7 @@
#define H_NOT_ENOUGH_RESOURCES -44
#define H_R_STATE -45
#define H_RESCINDEND -46
+#define H_MULTI_THREADS_ACTIVE -9005
/* Long Busy is a condition that can be returned by the firmware
_
^ permalink raw reply
* [PATCHv2 0/2] powerpc: pSeries Partition Hibernation
From: Brian King @ 2010-06-17 21:53 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev
Here is a refresh of partition hibernation support for pSeries.
It includes a fix for a regression in the partition migration
support. Barring any objections, I think these patches should
be ready to merge.
Overview
---------
Partition Hibernation on pSeries is a new platform feature that
allows for long term suspension of a logical partition much like
suspending a laptop to disk. The primary difference is that writing
the memory image out to disk is driven by system firmware and the
Virtual I/O Server rather than from the LPAR itself. Partition
hibernation on Power is initiated from the Hardware Management Console.
The user selects the partition, then selects the suspend function.
This results in a command (drmgr) getting sent to the Linux partition,
indicating it should prepare for suspension. A "stream id" is sent
to the Linux LPAR which is used by the OS to correlate with firmware.
In the Linux LPAR, the drmgr command then writes this stream id to
a new sysfs file: /sys/devices/system/power/hibernate. The kernel
then takes over, calling H_VASI_ENABLE with the stream id as
long as firmware indicates it is suspending but not ready for
the client LPAR to enter the final phase of the suspension.
Once H_VASI_ENABLE returns a state of H_VASI_SUSPENDING, the client
OS is expected to enter the final phase of hibernation. To do this,
we then simply invoke the pm_suspend code and mimic suspend to ram.
We mimic suspend to ram rather than suspend to disk, since firmware
and the VIOS takes care of writing everything out to disk. We are
then able to leverage all the existing suspend code in the kernel.
Once we enter the prepare_late phase of suspend, we set a flag which
we check when disable_nonboot_cpus gets called. When the nonboot
CPU gets offlined and placed into the inactive state, we hook
into pseries_mach_cpu_die in order to call H_JOIN, since the
nonboot CPUs need to be in H_JOIN state when we finally suspend.
Once all the nonboot CPUs have been offlined and are in H_JOIN,
and we get to the "enter" state, we make the ibm,suspend-me RTAS
call on the remaining CPU which then completes the hibernation.
When we resume, there is very little platform code required to
execute. enable_nonboot_cpus already sends an H_PROD as part
of bringing up the nonboot cpus, so this will kick the CPU out
of H_JOIN. I've already added resume handlers to the virtual
I/O drivers to check for any dropped interrupts. drmgr then
handles updating the device tree just like it does today
for live partition migration.
These patches have been tested with repeated suspend/resume
cycles. Partition migration has also been regression tested
since the first patch touches that path.
--
Brian King
Linux on Power Virtualization
IBM Linux Technology Center
^ permalink raw reply
* Re: Fixed-link PHY question
From: Gary Thomas @ 2010-06-17 18:50 UTC (permalink / raw)
To: Linux PPC Development
In-Reply-To: <4C1A61D9.4020306@mlbassoc.com>
On 06/17/2010 11:56 AM, Gary Thomas wrote:
> I'm working with 2.6.33.3 on a MPC8358. I'm trying to get it
> to talk to a Marvell (DSA) switch which uses special drivers
> and addressing to act like a PHY. I have this working fine
> on some older (2.6.28) systems by using a fixed-link PHY
> descriptor in my device tree (using the TSEC on 8347).
>
> The GETH driver calls 'of_phy_connect_fixed_link' which
> always gives me this error:
> PHY 0:01 not found
> net eth1: Could not attach to PHY
>
> How can I get the GETH driver to just accept the pseudo
> PHY connection specified by
> fixed-link = <1 1 1000 0 0>;
Figured it out - my ethernet node in the device tree has
to be called 'ethernet' for the fixed PHY emulation to see
the fixed-link properties.
Seems rather limited, but I don't have time to change it.
--
------------------------------------------------------------
Gary Thomas | Consulting for the
MLB Associates | Embedded world
------------------------------------------------------------
^ permalink raw reply
* Fixed-link PHY question
From: Gary Thomas @ 2010-06-17 17:56 UTC (permalink / raw)
To: Linux PPC Development
I'm working with 2.6.33.3 on a MPC8358. I'm trying to get it
to talk to a Marvell (DSA) switch which uses special drivers
and addressing to act like a PHY. I have this working fine
on some older (2.6.28) systems by using a fixed-link PHY
descriptor in my device tree (using the TSEC on 8347).
The GETH driver calls 'of_phy_connect_fixed_link' which
always gives me this error:
PHY 0:01 not found
net eth1: Could not attach to PHY
How can I get the GETH driver to just accept the pseudo
PHY connection specified by
fixed-link = <1 1 1000 0 0>;
Thanks
--
------------------------------------------------------------
Gary Thomas | Consulting for the
MLB Associates | Embedded world
------------------------------------------------------------
^ permalink raw reply
* Re: Porting a driver to powerpc using FDT
From: Grant Likely @ 2010-06-17 16:37 UTC (permalink / raw)
To: Chris Alfred; +Cc: linuxppc-dev
In-Reply-To: <6EAB45775B71486B8E72844E797E1D0F@kos>
Hi Chris, thanks for the write up. Some comments below, and I'm also
in the process of writing better documentation for all of this. You
can find it here:
http://devicetree.org/Device_Tree_Usage
That page describes how the device tree is structured. I'm about to
start another page on how Linux uses the device tree. That page
should cover the same topics that you describe below.
On Thu, Jun 17, 2010 at 5:11 AM, Chris Alfred <c.alfred@internode.on.net> w=
rote:
>> virtual-devices {
>> =A0 =A0 =A0 =A0 compatible =3D "simple-bus";
>> =A0 =A0 =A0 =A0 dsa {
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =3D "<vendor>,jkc5200n8-dsa";
>> =A0 =A0 =A0 =A0 };
>> };
>
> Ok, after correcting the names, the basic OF driver is probed.
>
> Now to try and use probe to register the DSA platform driver with the
> OF driver as its parent.
>
>
> =3D=3D=3D=3D=3D=3D=3D
>
> For those interested in how to get a very basic OF (uses FDT) driver
> going, the steps I did are below.
>
> 'myvendor' is your company name, and 'mydevice' is the name of the
> device - use better names in real code.
>
> (1) The .dts file - this is the Flattened Device Tree (FDT)
> descriptor:
>
> =A0 =A0/ {
> =A0 =A0 =A0 =A0...
>
> =A0 =A0 =A0 =A0 virtual-device {
> =A0 =A0 =A0 =A0 =A0compatible =3D "simple-bus";
> =A0 =A0 =A0 =A0 =A0mydevice0 {
> =A0 =A0 =A0 =A0 =A0 compatible =3D "myvendor,mydevice";
> =A0 =A0 =A0 =A0 =A0};
> =A0 =A0 =A0 =A0 };
>
> =A0 =A0 =A0 =A0...
> =A0 =A0};
>
> =A0 =A0For my board "simple-bus" is an already defined bus in the .dts.
> In my case the .dts had:
This comment raised warning flags for me. Can you post your new
current device tree? It sounds like you put your DSA device into the
localbus node. You shouldn't need to do that. Many nodes in a single
tree can claim compatibility with "simple-bus".
>
> =A0 =A0/ {
> =A0 =A0 =A0 =A0...
>
> =A0 =A0 =A0 =A0localbus {
> =A0 =A0 =A0 =A0 =A0compatible =3D
> "fsl,mpc5200b-lpb","fsl,mpc5200-lpb","simple-bus";
>
> =A0 =A0 =A0 =A0 =A0...
> =A0 =A0 =A0 =A0 };
>
> =A0 =A0 =A0 =A0...
> =A0 =A0};
>
> (2) Create the OF driver:
>
> =A0 =A0#include <linux/of.h>
> =A0 =A0#include <linux/kernel.h>
> =A0 =A0#include <linux/of_platform.h>
>
> =A0 =A0static int __devinit mydevice_probe(struct of_device *ofdev, const
> struct of_device_id *match)
> =A0 =A0{
> =A0 =A0 printk("mydevice_probe\n");
> =A0 =A0 return 0;
> =A0 =A0}
>
> =A0 =A0static int mydevice_remove(struct of_device *ofdev)
__devexit
> =A0 =A0{
> =A0 =A0 printk("mydevice_remove\n");
> =A0 =A0 return 0;
> =A0 =A0}
>
>
> =A0 =A0static const struct of_device_id mydevice_match[] =3D {
> =A0 =A0 {
> =A0 =A0 =A0.compatible =3D "myvendor,mydevice",
> =A0 =A0 },
> =A0 =A0 {}
> =A0 =A0};
>
> =A0 =A0static struct of_platform_driver mydevice_driver =3D {
> =A0 =A0 .name =3D "mydevice-driver",
> =A0 =A0 .match_table =3D mydevice_match,
> =A0 =A0 .probe =3D mydevice_probe,
> =A0 =A0 .remove =3D mydevice_remove,
> =A0 =A0};
.remove =3D __devexit_P(mydevice_remove),
>
> =A0 =A0static int __init mydevice_driver_init(void)
> =A0 =A0{
> =A0 =A0 printk("mydevice_drver_init\n");
>
> =A0 =A0 if (of_register_platform_driver(&mydevice_driver))
> =A0 =A0 =A0printk(KERN_ERR "Unable to register platform driver\n");
>
> =A0 =A0 return 0;
> =A0 =A0}
> =A0 =A0module_init(mydevice_driver_init);
Should actually be:
static int __init mydevice_driver_init(void)
{
printk("mydevice_drver_init\n");
return of_register_platform_driver(&mydevice_driver);
}
module_init(mydevice_driver_init);
The driver core will report an error if registration fails.
>
> =A0 =A0static void __exit mydevice_driver_cleanup(void)
> =A0 =A0{
> =A0 =A0 printk("mydevice_driver_cleanup\n");
>
> =A0 =A0 of_unregister_platform_driver(&mydevice_driver);
> =A0 =A0}
> =A0 =A0module_exit(mydevice_driver_cleanup);
>
> =A0 =A0MODULE_DESCRIPTION("mydevice driver");
> =A0 =A0MODULE_AUTHOR("name <email>");
> =A0 =A0MODULE_LICENSE("GPL v2");
> =A0 =A0MODULE_ALIAS("platform:mydevice-driver");
>
> (3) Change the appropriate Makefile and Kconfig to compile the OF
> driver.
>
> During kernel boot you should see the lines:
>
> =A0 =A0mydevice_driver_init
> =A0 =A0mydevice_probe
>
> If not, you probably have one of the strings (text in " ") incorrect.
>
> In /sys/bus/of_platform/drivers, you should have a directory named
> 'mydevice-driver'.
>
> In /sys/bus/of_platform/drivers/mydevice-driver you should have a
> directory named 'mydevice0.1'. The name 'mydevice0' comes from the
> .dts above.
which will be a symlink to the actual device location in the internal
Linux device hierarchy.
>
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>
> Brief explaination of how I think this is all tied together:
>
> (1) The Flattened Device Tree is included with the compiled kernel
> image.
Generally not. Usually the device tree is passed in via u-boot.
There is a form (cuImage) that links the dtb into the kernel, but that
is not recommended, and is only used for supporting old version of
u-boot that cannot pass the dtb at boot.
> (2) The module_init(...) macro is like declaring a 'main' for drivers.
> The kernel calls all of the functions declared in the module_init(...)
> macros during startup.
yes.
> (3) When a device driver is registered via
> of_register_platform_driver(), this invokes a scan of the FDT to find
> matches with strings in the .match_table. If a match is found, the
> .probe is called for the created device instance.
Not quite. Registering drivers does not cause a scan of the DT.
Instead, it looks in the list of registered devices to see if there is
anything to bind against. The devices are actually registered at boot
time in the function of_platform_bus_probe() which on the mpc5200 is
called by the function mpc52xx_declare_of_platform_devices().
Drivers won't bind against anything that isn't already registered as a
device in the Linux device model.
Cheers,
g.
^ permalink raw reply
* Re: Porting a driver to powerpc using FDT
From: Grant Likely @ 2010-06-17 14:55 UTC (permalink / raw)
To: Chris Alfred; +Cc: linuxppc-dev
In-Reply-To: <DC0A9AAD98D847FC97F74D4B04C4E898@kos>
On Wed, Jun 16, 2010 at 10:25 PM, Chris Alfred
<c.alfred@internode.on.net> wrote:
>>>>> dsa_of_init is successfully called; but dsa_of_probe is not
>>>>> called.
>>>>
>>>> That means the node is not being used to register an of_device. I
>>>> need some more information to suggest how best to fix this.
>>>
>>>> What SoC are you using?
>>>> What file in arch/powerpc/platforms/* is used to setup your
>>>> machine?
>>>
>>> We are using the MPC5200. Very similar to the Lite5200.
>>
>> So you're board is driver by
>> arch/powerpc/platforms/52xx/mpc5200_simple.c then?
>
> The Lite5200 is based on arch/powerpc/platforms/52xx/lite5200.c
>
> We have only done a text search/replace lite5200 to jkc5200.
> Based on your email, we have now also changed fsl,jkc5200n8 to
> jkc,jkc5200n8
Unless you need to add a bunch of board specific setup, you shouldn't
need to do this. It should be sufficient to add jkc,jkc5200n8 to the
list of boards in mpc5200_simple.c. The Lite5200 has a separate board
file because the original u-boot firmware for it didn't setup clocks
or port_config correctly. Almost every other board uses
mpc5200_simple.c
media5200 is the other exception because it needs to add a whole other
irq controller.
>> As mentioned, drop the reg property and be more specific in the
>> compatible value.
>
> Done, changed fsl,jkc5200n8 to jkc,jkc5200n8
>
>> If you do the
>> following, then it should start working:
>>
>> virtual-devices {
>> =A0 =A0 =A0 =A0 compatible =3D "simple-bus";
>> =A0 =A0 =A0 =A0 dsa {
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =3D "<vendor>,jkc5200n8-dsa";
>> =A0 =A0 =A0 =A0 };
>> };
>
> Where did "simple-bus" come from?
>
> Did you mean "mpc5200-simple-platform" from:
>
> =A0 =A0define_machine(mpc5200_simple_platform) {
> =A0 =A0 .name =A0=3D "mpc5200-simple-platform",
No, mpc5200-simple-platform is just a name shown to users. It doesn't
actually match against anything in the device tree.
"simple-bus" means that a node represents a simple transparent bridge
device. Linux uses that value to decide that the bus node contains
device nodes that it should register. Take a look at the ePAPR spec.
g.
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: Porting a driver to powerpc using FDT
From: Chris Alfred @ 2010-06-17 11:11 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <AANLkTim8kD9PH7BqOIV0GvElIfOgUDMw1VfWcOJhj-8r@mail.gmail.com>
> virtual-devices {
> compatible = "simple-bus";
> dsa {
> compatible = "<vendor>,jkc5200n8-dsa";
> };
> };
Ok, after correcting the names, the basic OF driver is probed.
Now to try and use probe to register the DSA platform driver with the
OF driver as its parent.
=======
For those interested in how to get a very basic OF (uses FDT) driver
going, the steps I did are below.
'myvendor' is your company name, and 'mydevice' is the name of the
device - use better names in real code.
(1) The .dts file - this is the Flattened Device Tree (FDT)
descriptor:
/ {
...
virtual-device {
compatible = "simple-bus";
mydevice0 {
compatible = "myvendor,mydevice";
};
};
...
};
For my board "simple-bus" is an already defined bus in the .dts.
In my case the .dts had:
/ {
...
localbus {
compatible =
"fsl,mpc5200b-lpb","fsl,mpc5200-lpb","simple-bus";
...
};
...
};
(2) Create the OF driver:
#include <linux/of.h>
#include <linux/kernel.h>
#include <linux/of_platform.h>
static int __devinit mydevice_probe(struct of_device *ofdev, const
struct of_device_id *match)
{
printk("mydevice_probe\n");
return 0;
}
static int mydevice_remove(struct of_device *ofdev)
{
printk("mydevice_remove\n");
return 0;
}
static const struct of_device_id mydevice_match[] = {
{
.compatible = "myvendor,mydevice",
},
{}
};
static struct of_platform_driver mydevice_driver = {
.name = "mydevice-driver",
.match_table = mydevice_match,
.probe = mydevice_probe,
.remove = mydevice_remove,
};
static int __init mydevice_driver_init(void)
{
printk("mydevice_drver_init\n");
if (of_register_platform_driver(&mydevice_driver))
printk(KERN_ERR "Unable to register platform driver\n");
return 0;
}
module_init(mydevice_driver_init);
static void __exit mydevice_driver_cleanup(void)
{
printk("mydevice_driver_cleanup\n");
of_unregister_platform_driver(&mydevice_driver);
}
module_exit(mydevice_driver_cleanup);
MODULE_DESCRIPTION("mydevice driver");
MODULE_AUTHOR("name <email>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:mydevice-driver");
(3) Change the appropriate Makefile and Kconfig to compile the OF
driver.
During kernel boot you should see the lines:
mydevice_driver_init
mydevice_probe
If not, you probably have one of the strings (text in " ") incorrect.
In /sys/bus/of_platform/drivers, you should have a directory named
'mydevice-driver'.
In /sys/bus/of_platform/drivers/mydevice-driver you should have a
directory named 'mydevice0.1'. The name 'mydevice0' comes from the
.dts above.
==========
Brief explaination of how I think this is all tied together:
(1) The Flattened Device Tree is included with the compiled kernel
image.
(2) The module_init(...) macro is like declaring a 'main' for drivers.
The kernel calls all of the functions declared in the module_init(...)
macros during startup.
(3) When a device driver is registered via
of_register_platform_driver(), this invokes a scan of the FDT to find
matches with strings in the .match_table. If a match is found, the
.probe is called for the created device instance.
Chris
^ permalink raw reply
* Re: [U-Boot] random exception on ppc based board
From: Thirumalai @ 2010-06-17 10:04 UTC (permalink / raw)
To: u-boot, linuxppc-dev
In-Reply-To: <19C9E63006DB43CBA8CD5BA6EDA1E832@itd210>
----- Original Message -----
From: "Thirumalai" <thirumalai.p@datapatterns.co.in>
To: <u-boot@lists.denx.de>; <linuxppc-dev@ozlabs.org>
Sent: Saturday, June 12, 2010 10:40 AM
Subject: [U-Boot] random exception on ppc based board
> Hi,
> I am having a ppc based target on which linux-2.4.20 kernel is running
> with u-boot 1.3.4 as boot loader. The target is having MPC7410 as
> processor
> and MPC107 as system controller. Regarding memory it is having 128 MB of
> ram
> and 16 MB of Flash memory. Also the kernel is patched with RTLinux-3.2 for
> realtime performance. I am getting a random Program and DSI exception on
> the
> target. Normally the exeption occurs during loading of rtl_time.o. The
> panic
> message is given below.
>
> ==================
> Using /usr/rtlinux/modules/rtl_time.okernel BUG at page_alloc.c:221!
> Oops: Exception in kernel mode, sig: 4
> NIP: C0032980 XER: 00000000 LR: C0032980 SP: C7CEDBA0 REGS: c7cedaf0 TRAP:
> 0700 Not tainted
> MSR: 00089032 EE: 1 PR: 0 FP: 0 ME: 1 IR/DR: 11
> TASK = c7cec000[366] 'exe' Last syscall: 3
> last math c7cec000 last altivec 00000000
> GPR00: C0032980 C7CEDBA0 C7CEC000 00000020 00000001 00000001 00001137
> 00000000
> GPR08: 00000002 00000000 CD879EC0 C7CEDAB0 CD876108 C0011934 00000000
> 00000000
> GPR16: 00000004 00000001 C002A0E8 C789E840 00009032 07CEDD90 C01A2C70
> C01A2C70
> GPR24: 00000001 00000000 C016E080 00000000 C79966E0 00000000 C016E0B8
> C016E0C4
> Call backtrace:
> C0032980 C0033020 C0032C4C C0025A18 C0025B58 C0025D8C C000EF88
> C0005D48 C03A8B28 C0029B28 C002A258 C003A99C C0005AFC 00000000
> 0FF15DBC 0FF175DC 0FF09894 10012190 100127D0 100356AC 100352A4
> 0FEBCF6C 00000000
>
> Oops: kernel access of bad area, sig: 11
> NIP: C00326DC XER: 00000000 LR: C0032588 SP: C7CED880 REGS: c7ced7d0 TRAP:
> 0300 Not tainted
> MSR: 00009032 EE: 1 PR: 0 FP: 0 ME: 1 IR/DR: 11
> DAR: 00000000, DSISR: 42000000
> TASK = c7cec000[366] 'exe' Last syscall: 3
> last math c7cec000 last altivec 00000000
> GPR00: 00000000 C7CED880 C7CEC000 C7CED888 FFFFFFFF 30026000 C0388250
> 00000000
> GPR08: 00008000 00000000 00155210 00000000 CD876CD4 C0032588 00000000
> 00000000
> GPR16: 00000004 00000001 C002A0E8 C789E840 00009032 C01A2C70 C01A2C70
> C016E130
> GPR24: C0233024 C0388234 00003E06 00007C0C C016E080 FFFFFFFE C016E0B8
> C0388260
> Call backtrace:
> C003249C C0033398 C0033B18 C00243D8 C0026234 C00246D0 C0027A70
> C001326C C00187D4 C0005ED4 C0005F44 C00062B0 C0005D48 C0032980
> C0033020 C0032C4C C0025A18 C0025B58 C0025D8C C000EF88 C0005D48
> C03A8B28 C0029B28 C002A258 C003A99C C0005AFC 00000000 0FF15DBC
> 0FF175DC 0FF09894 10012190 100127D0 100356AC
> Illegal instruction
> ========
> Sometimes i am getting the following panic message.
> ===========
> Oops: kernel access of bad area, sig: 11
> NIP: C0033360 XER: 20000000 LR: C00DE9A8 SP: C016C0D0 REGS: c016c020 TRAP:
> 0300 Tainted: P
> MSR: 00009032 EE: 1 PR: 0 FP: 0 ME: 1 IR/DR: 11
> DAR: 03910018, DSISR: 40000000
> TASK = c016a480[0] 'swapper' Last syscall: 120
> last math c505c000 last altivec 00000000
> GPR00: C00DE9A8 C016C0D0 C016A480 03910000 00000000 00000000 C5A469DC
> FFFFFFFF
> GPR08: 00000001 03910014 00000043 C5A2FE20 2490C022 C0030A04 07FF0D00
> 00000000
> GPR16: 00044008 00000000 00000000 00000000 00001032 00000003 FFFFFFFF
> 0A050393
> GPR24: C5A46980 C5A2F842 00000040 00000000 C5A2F842 C01C0000 C5A46980
> 00000001
> Call backtrace:
> 00000040 C00DE9A8 C00DE9DC C00DEB28 C01163D4 C01166EC C00F4898
> C00F44E4 C00F4AC8 C00F468C C00E3664 C00E3810 C00E397C C001A200
> C0007620 CD876CAC C0005D40 C000744C C0007460 C0003918 C01815E0
> 000035F0
> Kernel panic: Aiee, killing interrupt handler!
> In interrupt handler - not syncing
> <0>Rebooting in 180 seconds..
> ================
>
>
> How to debug this???
>
> -Thirumalai
>
> _______________________________________________
> U-Boot mailing list
> U-Boot@lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
Hi all,
We fixed this problem. When we ran e2fsck -f ramdisk.img it shown me
0.9% non-contiguos block. So we tried to defragment the ramdisk image using
e2defrag utility. After this the problem disappeared. But i don't know how
an ext2 file system is getting fragmented ? Also how this particular file
(rtl_time.o) is getting fragmented?
Any clue?
-Thirumalai
^ permalink raw reply
* Re: [PATCH v2] lite5200: fix ethernet phy address
From: Dmitry Eremin-Solenikov @ 2010-06-17 8:41 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <AANLkTilDO4Q_pXHux71Cr34EQsso-8kAd1ce7q2ATrCd@mail.gmail.com>
On 16.06.2010 22:25, Grant Likely wrote:
> On Tue, Jun 15, 2010 at 4:19 PM, Dmitry Eremin-Solenikov
> <dbaryshkov@gmail.com> wrote:
>> Dmitry Eremin-Solenikov wrote:
>>
>>> According to my schematics, on Lite5200 board ethernet phy uses address
>>> 0 (all ADDR lines are pulled down). With this change I can talk to
>>> onboard phy (LXT971) and correctly use autonegotiation.
>>
>> What about this patch?
>
> It was included in my merge req to Linus yesterday.
Yes. This mail was sent a minute before you've sent poll request to Linus :)
Sorry for the noise.
--
With best wishes
Dmitry
^ 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