LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] powerpc/40x: Add APM8018X SOC support
From: Tanmay @ 2011-11-24  5:47 UTC (permalink / raw)
  To: Paul Bolle; +Cc: linuxppc-dev, Tanmay Inamdar, linux-kernel
In-Reply-To: <1322043831.1753.49.camel@x61.thuisdomein>

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

Hello,

Thanks for the comments. Please see inline.

Regards,
Tanmay

On Wed, Nov 23, 2011 at 3:53 PM, Paul Bolle <pebolle@tiscali.nl> wrote:

> Tanmay,
>
> (Some minor Kconfig related comments follow.)
>
> On Wed, 2011-11-23 at 15:14 +0530, Tanmay Inamdar wrote:
> > The AppliedMicro APM8018X embedded processor targets embedded
> applications that
> > require low power and a small footprint. It features a PowerPC 405
> processor
> > core built in a 65nm low-power CMOS process with a five-stage pipeline
> executing
> > up to one instruction per cycle. The family has 128-kbytes of on-chip
> memory,
> > a 128-bit local bus and on-chip DDR2 SDRAM controller with 16-bit
> interface.
> >
> >[...]
> >
> > Signed-off-by: Tanmay Inamdar <tinamdar@apm.com>
> > ---
> >  arch/powerpc/Kconfig                        |    6 +
> >  arch/powerpc/boot/dcr.h                     |    6 +
> >  arch/powerpc/boot/dts/klondike.dts          |  668 +++++++++++++
> >  arch/powerpc/configs/40x/klondike_defconfig | 1353
> +++++++++++++++++++++++++++
> >  arch/powerpc/include/asm/dcr-regs.h         |   20 +
> >  arch/powerpc/kernel/cputable.c              |   52 +
> >  arch/powerpc/kernel/udbg_16550.c            |   22 +
> >  arch/powerpc/platforms/40x/Kconfig          |   11 +
> >  arch/powerpc/platforms/40x/ppc40x_simple.c  |    4 +-
> >  9 files changed, 2141 insertions(+), 1 deletions(-)
> >  create mode 100644 arch/powerpc/boot/dts/klondike.dts
> >  create mode 100644 arch/powerpc/configs/40x/klondike_defconfig
> >
> > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> > index b177caa..3f2cc36 100644
> > --- a/arch/powerpc/Kconfig
> > +++ b/arch/powerpc/Kconfig
> > @@ -978,3 +978,9 @@ config PPC_LIB_RHEAP
> >       bool
> >
> >  source "arch/powerpc/kvm/Kconfig"
> > +
> > +config UART_16550_WORD_ADDRESSABLE
> > +     bool
> > +     default n
> > +     help
> > +        Enable this if your UART 16550 is word addressable.
>
> This is only relevant for this SOC isn't it? If so, it might be better
> to add it to arch/powerpc/platforms/40x/Kconfig.
>
> The help line can be dropped (there's no prompt, so the help won't be
> user visible).
>
> Some people would suggest to use
>        def_bool n
>
> here. (I don't really care.)
>
Agreed. As Kumar Gala suggested in his comment, I will move this and make a
separate patch for UART changes.

>
> > [...]
>
> > diff --git a/arch/powerpc/kernel/udbg_16550.c
> b/arch/powerpc/kernel/udbg_16550.c
> > index 6837f83..dd3bce9 100644
> > --- a/arch/powerpc/kernel/udbg_16550.c
> > +++ b/arch/powerpc/kernel/udbg_16550.c
> > @@ -18,6 +18,19 @@ extern void real_writeb(u8 data, volatile u8 __iomem
> *addr);
> >  extern u8 real_205_readb(volatile u8 __iomem  *addr);
> >  extern void real_205_writeb(u8 data, volatile u8 __iomem *addr);
> >
> > +#ifdef CONFIG_UART_16550_WORD_ADDRESSABLE
> > +struct NS16550 {
> > +     /* this struct must be packed */
> > +     unsigned char rbr;  /* 0 */ u8 s0[3];
> > +     unsigned char ier;  /* 1 */ u8 s1[3];
> > +     unsigned char fcr;  /* 2 */ u8 s2[3];
> > +     unsigned char lcr;  /* 3 */ u8 s3[3];
> > +     unsigned char mcr;  /* 4 */ u8 s4[3];
> > +     unsigned char lsr;  /* 5 */ u8 s5[3];
> > +     unsigned char msr;  /* 6 */ u8 s6[3];
> > +     unsigned char scr;  /* 7 */ u8 s7[3];
> > +};
> > +#else
> >  struct NS16550 {
> >       /* this struct must be packed */
> >       unsigned char rbr;  /* 0 */
> > @@ -29,6 +42,7 @@ struct NS16550 {
> >       unsigned char msr;  /* 6 */
> >       unsigned char scr;  /* 7 */
> >  };
> > +#endif /* CONFIG_UART_16550_WORD_ADDRESSABLE */
> >
> >  #define thr rbr
> >  #define iir fcr
> > [...]
> > diff --git a/arch/powerpc/platforms/40x/Kconfig
> b/arch/powerpc/platforms/40x/Kconfig
> > index 1530229..3d0d1d9 100644
> > --- a/arch/powerpc/platforms/40x/Kconfig
> > +++ b/arch/powerpc/platforms/40x/Kconfig
> > @@ -186,3 +186,14 @@ config IBM405_ERR51
> >  #    bool
> >  #    depends on !STB03xxx && PPC4xx_DMA
> >  #    default y
> > +#
> > +
> > +config APM8018X
> > +     bool "APM8018X"
> > +     depends on 40x
> > +     default y
>
> Why is this "default y"? All other "selectors" of PPC40x_SIMPLE default
> to n.
>
> Yes. This is a mistake. This should be 'n'.


> > +     select PPC40x_SIMPLE
>
> There was recently some powerpc related discussion on using "select" on
> symbols that are themselves user selectable (see
> https://lkml.org/lkml/2011/11/9/426 ). But other symbols already select
> this symbol so this is not specific to this patch.
>
> > +     select UART_16550_WORD_ADDRESSABLE
> > +     help
> > +       This option enables support for the AppliedMicro Klondike board.
> > +
>
> Since you're selecting it here it's good that you made
> UART_16550_WORD_ADDRESSABLE hidden (as it has no prompt). But perhaps
> you could even drop it and in the code just test for CONFIG_APM8018X. Or
> are you expecting more users of UART_16550_WORD_ADDRESSABLE?
>
At this moment, it is only APM8018X SOC expects this. I am not sure about
more users of  UART_16550_WORD_ADDRESSABLE.  I will try to eliminate it or
make it as a run time selection.

>
> > [...]
>
>
> Paul Bolle
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>

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

^ permalink raw reply

* Re: [PATCH 2/3] powerpc/85xx: add pixis indirect mode device tree node
From: Kumar Gala @ 2011-11-24  5:16 UTC (permalink / raw)
  To: Timur Tabi; +Cc: scottwood, linuxppc-dev
In-Reply-To: <1321638601-6861-2-git-send-email-timur@freescale.com>


On Nov 18, 2011, at 11:50 AM, Timur Tabi wrote:

> The Freescale P1022 has a unique pin muxing "feature" where the DIU =
video
> controller's video signals are muxed with 24 of the local bus address =
signals.
> When the DIU is enabled, the bulk of the local bus is disabled, =
preventing
> access to memory-mapped devices like NOR flash and the pixis FPGA.
>=20
> In this situation, the pixis supports "indirect mode", which allows =
access
> to the pixis itself by reading/writing addresses on specific local bus
> chip selects.  CS0 is used to select which pixis register to access, =
and
> CS1 is used to read/write the value.
>=20
> To support this, we introduce another board-control child node of the
> localbus node that contains a 'reg' property for CS0 and CS1.  This =
will
> produce the correct physical addresses for CS0 and CS1.
>=20
> Signed-off-by: Timur Tabi <timur@freescale.com>
> ---
> arch/powerpc/boot/dts/p1022ds.dts |   14 ++++++++++++++
> 1 files changed, 14 insertions(+), 0 deletions(-)

applied to next

- k=

^ permalink raw reply

* Re: [PATCH 1/3] powerpc/85xx: p1022ds: disable the NOR flash node if video is enabled
From: Kumar Gala @ 2011-11-24  5:12 UTC (permalink / raw)
  To: Timur Tabi; +Cc: scottwood, linuxppc-dev
In-Reply-To: <1321638601-6861-1-git-send-email-timur@freescale.com>


On Nov 18, 2011, at 11:49 AM, Timur Tabi wrote:

> The Freescale P1022 has a unique pin muxing "feature" where the DIU =
video
> controller's video signals are muxed with 24 of the local bus address =
signals.
> When the DIU is enabled, the bulk of the local bus is disabled, =
preventing
> access to memory-mapped devices like NOR flash and the pixis FPGA.
>=20
> Therefore, if the DIU is going to be enabled, then memory-mapped =
devices on
> the localbus, like NOR flash, need to be disabled.
>=20
> Signed-off-by: Timur Tabi <timur@freescale.com>
> ---
> arch/powerpc/platforms/85xx/p1022_ds.c |   70 =
++++++++++++++++++++++++++++++++
> 1 files changed, 70 insertions(+), 0 deletions(-)
>=20
> diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c =
b/arch/powerpc/platforms/85xx/p1022_ds.c
> index fda1571..e0280e2 100644
> --- a/arch/powerpc/platforms/85xx/p1022_ds.c
> +++ b/arch/powerpc/platforms/85xx/p1022_ds.c
> @@ -270,6 +270,54 @@ void __init p1022_ds_pic_init(void)
> void __init mpc85xx_smp_init(void);
> #endif
>=20
> +#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
> +
> +/*
> + * Disables a node in the device tree.
> + *
> + * This function is called before kmalloc() is available, and it's =
only called
> + * once, so we instead of allocating the new property object via the =
bootmem
> + * allocator, we just create a static local variable.
> + */
> +static void __init disable_one_node(struct device_node *np)
> +{
> +	struct property *old;
> +	static struct property new =3D {
> +		.name =3D "status",
> +		.value =3D "disabled",
> +		.length =3D sizeof("disabled"),
> +	};
> +
> +	old =3D of_find_property(np, new.name, NULL);
> +	if (old)
> +		prom_update_property(np, &new, old);
> +	else
> +		prom_add_property(np, &new);
> +}
> +
> +/* TRUE if there is a "video=3Dfslfb" command-line parameter. */
> +static bool fslfb;
> +
> +/*
> + * Search for a "video=3Dfslfb" command-line parameter, and set =
'fslfb' to
> + * true if we find it.
> + *
> + * We need to use early_param() instead of __setup() because the =
normal
> + * __setup() gets called to late.  However, early_param() gets called =
very
> + * early, before the device tree is unflattened, so all we can do now =
is set a
> + * global variable.  Later on, p1022_ds_setup_arch() will use that =
variable
> + * to determine if we need to update the device tree.
> + */
> +static int __init early_video_setup(char *options)
> +{
> +	fslfb =3D (strncmp(options, "fslfb:", 6) =3D=3D 0);
> +
> +	return 0;
> +}
> +early_param("video", early_video_setup);
> +
> +#endif
> +
> /*
>  * Setup the architecture
>  */
> @@ -307,6 +355,28 @@ static void __init p1022_ds_setup_arch(void)
> 	diu_ops.set_monitor_port	=3D p1022ds_set_monitor_port;
> 	diu_ops.set_pixel_clock		=3D p1022ds_set_pixel_clock;
> 	diu_ops.valid_monitor_port	=3D p1022ds_valid_monitor_port;
> +
> +	/*
> +	 * Delete the NOR flash node if there is video=3Dfslfb... =
command-line
> +	 * parameter.  When the DIU is active, NOR flash is unavailable, =
so we
> +	 * have to delete the node before the MTD driver loads.
> +	 */

Fix comment, you aren't deleting the node, your marked it disabled.

> +	if (fslfb) {
> +		struct device_node *np =3D
> +			of_find_compatible_node(NULL, NULL, =
"fsl,p1022-elbc");
> +
> +		if (np) {
> +			np =3D of_find_compatible_node(np, NULL, =
"cfi-flash");
> +			if (np) {
> +				pr_info("p1022ds: disabling %s node",
> +					np->full_name);
> +				disable_one_node(np);
> +				of_node_put(np);
> +			}
> +		}
> +
> +	}
> +
> #endif
>=20
> #ifdef CONFIG_SMP
> --=20
> 1.7.3.4
>=20
>=20
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [PATCH] powerpc/85xx: Add lbc suspend support for PM
From: Kumar Gala @ 2011-11-24  5:04 UTC (permalink / raw)
  To: Jia Hongtao; +Cc: B11780, linuxppc-dev
In-Reply-To: <1321856951-10789-1-git-send-email-B38951@freescale.com>


On Nov 21, 2011, at 12:29 AM, Jia Hongtao wrote:

> Power supply for LBC registers is off when system go to deep-sleep =
state.
> We save the values of registers before suspend and restore to =
registers
> after resume.
>=20
> We removed the last two reservation arrays from struct fsl_lbc_regs =
for
> allocating less memory and minimizing the memcpy size.
>=20
> Signed-off-by: Jiang Yutang <b14898@freescale.com>
> Signed-off-by: Jia Hongtao <B38951@freescale.com>
> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
> arch/powerpc/include/asm/fsl_lbc.h |    7 +++++--
> arch/powerpc/sysdev/fsl_lbc.c      |   36 =
++++++++++++++++++++++++++++++++++++
> 2 files changed, 41 insertions(+), 2 deletions(-)

applied to next

- k=

^ permalink raw reply

* Re: [PATCH] Do not hide resource for pci/pcie when configured as Agent/EP
From: Kumar Gala @ 2011-11-24  5:04 UTC (permalink / raw)
  To: Jia Hongtao; +Cc: B11780, linuxppc-dev
In-Reply-To: <1319789280-12091-1-git-send-email-B38951@freescale.com>


On Oct 28, 2011, at 3:08 AM, Jia Hongtao wrote:

> From: Jason Jin <Jason.jin@freescale.com>
> 
> Current pci/pcie init code will hide the pci/pcie host resource.
> But did not judge it is host/RC or agent/EP. If configured as
> agent/EP, we should avoid hiding its resource in the host side.
> 
> In PCI system, the Programing Interface can be used to judge the
> host/agent status:
> Programing Interface = 0: host
> Programing Interface = 1: Agent
> 
> In PCIE system, both the Programing Interface and Header type can
> be used to judge the RC/EP status.
> Header Type = 0: EP
> Header Type = 1: RC
> 
> Signed-off-by: Jason Jin <Jason.jin@freescale.com>
> Signed-off-by: Mingkai Hu <Mingkai.hu@freescale.com>
> Signed-off-by: Jia Hongtao <B38951@freescale.com>
> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
> arch/powerpc/kernel/pci-common.c |    3 +++
> 1 files changed, 3 insertions(+), 0 deletions(-)

applied to next

- k

^ permalink raw reply

* [git pull] Please pull powerpc.git merge branch
From: Kumar Gala @ 2011-11-24  5:03 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev

Ben,

A few minor fixes for FSL PPC SoCs to send up to Linus.

- k

The following changes since commit caca6a03d365883564885f2c1da3e88dcf65d139:

  Linux 3.2-rc3 (2011-11-23 20:20:28 -0800)

are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git merge

Kumar Gala (1):
      powerpc/85xx: Fix compile error on p3060_qds.c

Paul Bolle (1):
      powerpc/p3060qds: Fix select of 'MPC8xxx_GPIO'

Roy Zang (1):
      powerpc/p1023: set IRQ[4:6,11] to active-high level sensitive for PCIe

 arch/powerpc/boot/dts/p1023rds.dts      |   17 +++++++++++++----
 arch/powerpc/platforms/85xx/Kconfig     |    2 +-
 arch/powerpc/platforms/85xx/p3060_qds.c |    2 +-
 3 files changed, 15 insertions(+), 6 deletions(-)

^ permalink raw reply

* Re: [4/4] powerpc/booke: Re-organize debug code
From: Kumar Gala @ 2011-11-24  4:54 UTC (permalink / raw)
  To: Ben Herrenschmidt; +Cc: linuxppc-dev@ozlabs.org list
In-Reply-To: <567C3D8A-BBB9-4487-8069-0EA57701D7B6@pobox.com>

>>>> * set_dabr/do_dabr are no longer used when CNFIG_PPC_ADV_DEBUG_REGS =
is set
>>>> refactor code a bit such that we only build the dabr code for
>>>> !CONFIG_PPC_ADV_DEBUG_REGS and removed some =
CONFIG_PPC_ADV_DEBUG_REGS
>>>> code in set_dabr that would never get built.
>>>>=20
>>>> * Move do_send_trap into traps.c as its only used there
>>>>=20
>>>> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
>>>>=20
>>>> ---
>>>> arch/powerpc/include/asm/system.h |    5 +--
>>>> arch/powerpc/kernel/process.c     |   97 =
+++++++++++++-----------------------
>>>> arch/powerpc/kernel/traps.c       |   17 +++++++
>>>> 3 files changed, 53 insertions(+), 66 deletions(-)
>>>>=20
>>>> diff --git a/arch/powerpc/include/asm/system.h =
b/arch/powerpc/include/asm/system.h
>>>> index e30a13d..1dc5d9c 100644
>>>> --- a/arch/powerpc/include/asm/system.h
>>>> +++ b/arch/powerpc/include/asm/system.h
>>>> @@ -111,11 +111,8 @@ static inline int debugger_dabr_match(struct =
pt_regs *regs) { return 0; }
>>>> static inline int debugger_fault_handler(struct pt_regs *regs) { =
return 0; }
>>>> #endif
>>>>=20
>>>> +#ifndef CONFIG_PPC_ADV_DEBUG_REGS
>>>> extern int set_dabr(unsigned long dabr);
>>>> -#ifdef CONFIG_PPC_ADV_DEBUG_REGS
>>>> -extern void do_send_trap(struct pt_regs *regs, unsigned long =
address,
>>>> -			 unsigned long error_code, int signal_code, int =
brkpt);
>>>> -#else
>>>=20
>>>=20
>>> This part of the patch breaks xmon.c
>>> Naively I simply wrapped the xmon call:
>>>=20
>>> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
>>> index f08836a..b5911b2 100644
>>> --- a/arch/powerpc/xmon/xmon.c
>>> +++ b/arch/powerpc/xmon/xmon.c
>>> @@ -738,8 +738,10 @@ static void insert_bpts(void)
>>>=20
>>> static void insert_cpu_bpts(void)
>>> {
>>> +#ifndef CONFIG_PPC_ADV_DEBUG_REGS
>>> 	if (dabr.enabled)
>>> 		set_dabr(dabr.address | (dabr.enabled & 7));
>>> +#endif
>>> 	if (iabr && cpu_has_feature(CPU_FTR_IABR))
>>> 		mtspr(SPRN_IABR, iabr->address
>>> 			 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
>>> @@ -767,7 +769,9 @@ static void remove_bpts(void)
>>>=20
>>> static void remove_cpu_bpts(void)
>>> {
>>> +#ifndef CONFIG_PPC_ADV_DEBUG_REGS
>>> 	set_dabr(0);
>>> +#endif
>>> 	if (cpu_has_feature(CPU_FTR_IABR))
>>> 		mtspr(SPRN_IABR, 0);
>>> }
>>=20
>> Shouldn't all of these functions be #ifndef'd out as we don't support =
cpu_bpts on book-e parts in xmon code today?
>=20
> Well I guess this is one for benh, because I would have expected xmon =
to test and call ppc_md.dabr.
> Actually, should everyone be doing that?
> -jx

Ben,

Any comment on direction here ?

- k

>>>> extern void do_dabr(struct pt_regs *regs, unsigned long address,
>>>> 		    unsigned long error_code);
>>>> #endif
>>>> diff --git a/arch/powerpc/kernel/process.c =
b/arch/powerpc/kernel/process.c
>>>> index 269a309..989e574 100644
>>>> --- a/arch/powerpc/kernel/process.c
>>>> +++ b/arch/powerpc/kernel/process.c
>>>> @@ -251,50 +251,6 @@ void discard_lazy_cpu_state(void)
>>>> #endif /* CONFIG_SMP */
>>>>=20
>>>> #ifdef CONFIG_PPC_ADV_DEBUG_REGS
>>>> -void do_send_trap(struct pt_regs *regs, unsigned long address,
>>>> -		  unsigned long error_code, int signal_code, int =
breakpt)
>>>> -{
>>>> -	siginfo_t info;
>>>> -
>>>> -	if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
>>>> -			11, SIGSEGV) =3D=3D NOTIFY_STOP)
>>>> -		return;
>>>> -
>>>> -	/* Deliver the signal to userspace */
>>>> -	info.si_signo =3D SIGTRAP;
>>>> -	info.si_errno =3D breakpt;	/* breakpoint or watchpoint id =
*/
>>>> -	info.si_code =3D signal_code;
>>>> -	info.si_addr =3D (void __user *)address;
>>>> -	force_sig_info(SIGTRAP, &info, current);
>>>> -}
>>>> -#else	/* !CONFIG_PPC_ADV_DEBUG_REGS */
>>>> -void do_dabr(struct pt_regs *regs, unsigned long address,
>>>> -		    unsigned long error_code)
>>>> -{
>>>> -	siginfo_t info;
>>>> -
>>>> -	if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
>>>> -			11, SIGSEGV) =3D=3D NOTIFY_STOP)
>>>> -		return;
>>>> -
>>>> -	if (debugger_dabr_match(regs))
>>>> -		return;
>>>> -
>>>> -	/* Clear the DABR */
>>>> -	set_dabr(0);
>>>> -
>>>> -	/* Deliver the signal to userspace */
>>>> -	info.si_signo =3D SIGTRAP;
>>>> -	info.si_errno =3D 0;
>>>> -	info.si_code =3D TRAP_HWBKPT;
>>>> -	info.si_addr =3D (void __user *)address;
>>>> -	force_sig_info(SIGTRAP, &info, current);
>>>> -}
>>>> -#endif	/* CONFIG_PPC_ADV_DEBUG_REGS */
>>>> -
>>>> -static DEFINE_PER_CPU(unsigned long, current_dabr);
>>>> -
>>>> -#ifdef CONFIG_PPC_ADV_DEBUG_REGS
>>>> /*
>>>> * Set the debug registers back to their default "safe" values.
>>>> */
>>>> @@ -357,16 +313,7 @@ static void switch_booke_debug_regs(struct =
thread_struct *new_thread)
>>>> 			prime_debug_regs(new_thread);
>>>> }
>>>> #else	/* !CONFIG_PPC_ADV_DEBUG_REGS */
>>>> -#ifndef CONFIG_HAVE_HW_BREAKPOINT
>>>> -static void set_debug_reg_defaults(struct thread_struct *thread)
>>>> -{
>>>> -	if (thread->dabr) {
>>>> -		thread->dabr =3D 0;
>>>> -		set_dabr(0);
>>>> -	}
>>>> -}
>>>> -#endif /* !CONFIG_HAVE_HW_BREAKPOINT */
>>>> -#endif	/* CONFIG_PPC_ADV_DEBUG_REGS */
>>>> +static DEFINE_PER_CPU(unsigned long, current_dabr);
>>>>=20
>>>> int set_dabr(unsigned long dabr)
>>>> {
>>>> @@ -376,19 +323,45 @@ int set_dabr(unsigned long dabr)
>>>> 		return ppc_md.set_dabr(dabr);
>>>>=20
>>>> 	/* XXX should we have a CPU_FTR_HAS_DABR ? */
>>>> -#ifdef CONFIG_PPC_ADV_DEBUG_REGS
>>>> -	mtspr(SPRN_DAC1, dabr);
>>>> -#ifdef CONFIG_PPC_47x
>>>> -	isync();
>>>> -#endif
>>>> -#elif defined(CONFIG_PPC_BOOK3S)
>>>> 	mtspr(SPRN_DABR, dabr);
>>>> -#endif
>>>> -
>>>>=20
>>>> 	return 0;
>>>> }
>>>>=20
>>>> +void do_dabr(struct pt_regs *regs, unsigned long address,
>>>> +		    unsigned long error_code)
>>>> +{
>>>> +	siginfo_t info;
>>>> +
>>>> +	if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
>>>> +			11, SIGSEGV) =3D=3D NOTIFY_STOP)
>>>> +		return;
>>>> +
>>>> +	if (debugger_dabr_match(regs))
>>>> +		return;
>>>> +
>>>> +	/* Clear the DABR */
>>>> +	set_dabr(0);
>>>> +
>>>> +	/* Deliver the signal to userspace */
>>>> +	info.si_signo =3D SIGTRAP;
>>>> +	info.si_errno =3D 0;
>>>> +	info.si_code =3D TRAP_HWBKPT;
>>>> +	info.si_addr =3D (void __user *)address;
>>>> +	force_sig_info(SIGTRAP, &info, current);
>>>> +}
>>>> +
>>>> +#ifndef CONFIG_HAVE_HW_BREAKPOINT
>>>> +static void set_debug_reg_defaults(struct thread_struct *thread)
>>>> +{
>>>> +	if (thread->dabr) {
>>>> +		thread->dabr =3D 0;
>>>> +		set_dabr(0);
>>>> +	}
>>>> +}
>>>> +#endif /* !CONFIG_HAVE_HW_BREAKPOINT */
>>>> +#endif	/* CONFIG_PPC_ADV_DEBUG_REGS */
>>>> +
>>>> #ifdef CONFIG_PPC64
>>>> DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
>>>> #endif
>>>> diff --git a/arch/powerpc/kernel/traps.c =
b/arch/powerpc/kernel/traps.c
>>>> index db733d3..edc1108 100644
>>>> --- a/arch/powerpc/kernel/traps.c
>>>> +++ b/arch/powerpc/kernel/traps.c
>>>> @@ -1184,6 +1184,23 @@ void SoftwareEmulation(struct pt_regs *regs)
>>>> #endif /* CONFIG_8xx */
>>>>=20
>>>> #ifdef CONFIG_PPC_ADV_DEBUG_REGS
>>>> +static void do_send_trap(struct pt_regs *regs, unsigned long =
address,
>>>> +		  unsigned long error_code, int signal_code, int =
breakpt)
>>>> +{
>>>> +	siginfo_t info;
>>>> +
>>>> +	if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
>>>> +			11, SIGSEGV) =3D=3D NOTIFY_STOP)
>>>> +		return;
>>>> +
>>>> +	/* Deliver the signal to userspace */
>>>> +	info.si_signo =3D SIGTRAP;
>>>> +	info.si_errno =3D breakpt;	/* breakpoint or watchpoint id =
*/
>>>> +	info.si_code =3D signal_code;
>>>> +	info.si_addr =3D (void __user *)address;
>>>> +	force_sig_info(SIGTRAP, &info, current);
>>>> +}
>>>> +
>>>> static void handle_debug(struct pt_regs *regs, unsigned long =
debug_status)
>>>> {
>>>> 	int changed =3D 0;
>>=20

^ permalink raw reply

* Re: [PATCH 1/2] Unify pci/pcie initialization code
From: Kumar Gala @ 2011-11-24  4:50 UTC (permalink / raw)
  To: Jia Hongtao-B38951
  Cc: Gala Kumar-B11780, linuxppc-dev@lists.ozlabs.org, Li Yang-R58472
In-Reply-To: <412C8208B4A0464FA894C5F0C278CD5DFD4DB8@039-SN1MPN1-005.039d.mgd.msft.net>


On Nov 22, 2011, at 12:20 AM, Jia Hongtao-B38951 wrote:

> Hi Kumar,
> We want more comments on this series of patches ([1/2] & [2/2]) to =
speed up the pushing-to-kernel progress.
> Thanks.

I think the code is fine, but you need to update it for all the boards =
include the 86xx ones.

- k

>=20
> -----Original Message-----
> From: Jia Hongtao-B38951=20
> Sent: Monday, October 31, 2011 1:55 PM
> To: linuxppc-dev@lists.ozlabs.org
> Cc: Li Yang-R58472; Gala Kumar-B11780; Jia Hongtao-B38951
> Subject: [PATCH 1/2] Unify pci/pcie initialization code
>=20
> In previous version pci/pcie initialization is in platform code which =
Initialize PCI bridge base on EP/RC or host/agent settings.
> We unified pci/pcie initialization as common APIs named fsl_pci_setup =
which can be called by platform code.
>=20
> Signed-off-by: Jia Hongtao <B38951@freescale.com>
> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
> arch/powerpc/platforms/85xx/mpc85xx_ds.c |   30 ++-----------------
> arch/powerpc/sysdev/fsl_pci.c            |   48 =
++++++++++++++++++++++++++++++
> arch/powerpc/sysdev/fsl_pci.h            |    5 +++
> 3 files changed, 56 insertions(+), 27 deletions(-)
>=20
> diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c =
b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
> index 10e7db0..7188c0b 100644
> --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
> +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
> @@ -157,33 +157,12 @@ extern void __init mpc85xx_smp_init(void);  =
#endif  static void __init mpc85xx_ds_setup_arch(void)  { -#ifdef =
CONFIG_PCI
> -	struct device_node *np;
> -	struct pci_controller *hose;
> -#endif
> -	dma_addr_t max =3D 0xffffffff;
> -
> 	if (ppc_md.progress)
> 		ppc_md.progress("mpc85xx_ds_setup_arch()", 0);
>=20
> -#ifdef CONFIG_PCI
> -	for_each_node_by_type(np, "pci") {
> -		if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
> -		    of_device_is_compatible(np, "fsl,mpc8548-pcie") ||
> -		    of_device_is_compatible(np, "fsl,p2020-pcie")) {
> -			struct resource rsrc;
> -			of_address_to_resource(np, 0, &rsrc);
> -			if ((rsrc.start & 0xfffff) =3D=3D =
primary_phb_addr)
> -				fsl_add_bridge(np, 1);
> -			else
> -				fsl_add_bridge(np, 0);
> -
> -			hose =3D pci_find_hose_for_OF_device(np);
> -			max =3D min(max, hose->dma_window_base_cur +
> -					hose->dma_window_size);
> -		}
> -	}
> +	fsl_pci_setup(primary_phb_addr);
>=20
> +#ifdef CONFIG_PCI
> 	ppc_md.pci_exclude_device =3D mpc85xx_exclude_device;  #endif
>=20
> @@ -192,11 +171,8 @@ static void __init mpc85xx_ds_setup_arch(void)  =
#endif
>=20
> #ifdef CONFIG_SWIOTLB
> -	if (memblock_end_of_DRAM() > max) {
> +	if (memblock_end_of_DRAM() > 0xffffffff)
> 		ppc_swiotlb_enable =3D 1;
> -		set_pci_dma_ops(&swiotlb_dma_ops);
> -		ppc_md.pci_dma_dev_setup =3D pci_dma_dev_setup_swiotlb;
> -	}
> #endif
>=20
> 	printk("MPC85xx DS board from Freescale Semiconductor\n"); diff =
--git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c =
index 80b8b7a..4d4536f 100644
> --- a/arch/powerpc/sysdev/fsl_pci.c
> +++ b/arch/powerpc/sysdev/fsl_pci.c
> @@ -402,6 +402,54 @@ int __init fsl_add_bridge(struct device_node =
*dev, int is_primary)  }  #endif /* CONFIG_FSL_SOC_BOOKE || =
CONFIG_PPC_86xx */
>=20
> +static struct of_device_id pci_ids[] =3D {
> +	{ .compatible =3D "fsl,mpc8540-pci", },
> +	{ .compatible =3D "fsl,mpc8548-pcie", },
> +	{},
> +};
> +
> +/**
> + * fsl_pci_setup - Initialization for PCI
> + * @primary_phb_addr: primary bus address
> + *
> + * Add bridge if pci controller is a host  */ void fsl_pci_setup(int=20=

> +primary_phb_addr) {
> +	struct device_node *np;
> +	struct pci_controller *hose;
> +	dma_addr_t min_dma_addr =3D 0xffffffff;
> +
> +	for_each_node_by_type(np, "pci") {
> +		if (of_match_node(pci_ids, np)) {
> +			struct resource rsrc;
> +			of_address_to_resource(np, 0, &rsrc);
> +			if ((rsrc.start & 0xfffff) =3D=3D =
primary_phb_addr)
> +				fsl_add_bridge(np, 1);
> +			else
> +				fsl_add_bridge(np, 0);
> +
> +			hose =3D pci_find_hose_for_OF_device(np);
> +			min_dma_addr =3D min(min_dma_addr,
> +					hose->dma_window_base_cur
> +					+ hose->dma_window_size);
> +
> +		}
> +	}
> +
> +#ifdef CONFIG_SWIOTLB
> +	/*
> +	 * if we couldn't map all of DRAM via the dma windows we need =
SWIOTLB
> +	 * to handle buffers located outside of dma capable memory =
region
> +	 */
> +	if (memblock_end_of_DRAM() > min_dma_addr) {
> +		ppc_swiotlb_enable =3D 1;
> +		set_pci_dma_ops(&swiotlb_dma_ops);
> +		ppc_md.pci_dma_dev_setup =3D pci_dma_dev_setup_swiotlb;
> +	}
> +#endif
> +}
> +
> DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, =
quirk_fsl_pcie_header);
>=20
> #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x) diff --git =
a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h index =
a39ed5c..775ea21 100644
> --- a/arch/powerpc/sysdev/fsl_pci.h
> +++ b/arch/powerpc/sysdev/fsl_pci.h
> @@ -89,6 +89,11 @@ struct ccsr_pci {
> };
>=20
> extern int fsl_add_bridge(struct device_node *dev, int is_primary);
> +#ifndef CONFIG_PCI
> +#define fsl_pci_setup(p)
> +#else
> +extern void fsl_pci_setup(int primary_phb_addr); #endif
> extern void fsl_pcibios_fixup_bus(struct pci_bus *bus);  extern int =
mpc83xx_add_bridge(struct device_node *dev);
> u64 fsl_pci_immrbar_base(struct pci_controller *hose);
> --
> 1.7.5.1
>=20
>=20
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* [PATCH 2/3] mtd/nand : set correct length to FBCR for a non-full-page write
From: b35362 @ 2011-11-24  0:41 UTC (permalink / raw)
  To: dwmw2, Artem.Bityutskiy, scottwood
  Cc: linuxppc-dev, akpm, linux-mtd, linux-kernel
In-Reply-To: <1322095306-13156-1-git-send-email-b35362@freescale.com>

From: Liu Shuo <b35362@freescale.com>

When we do a non-full-page write, the length be set to FBCR should
not be 'elbc_fcm_ctrl->index', it should be 'elbc_fcm_ctrl->index -
elbc_fcm_ctrl->column'.

Signed-off-by: Liu Shuo <b35362@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
 drivers/mtd/nand/fsl_elbc_nand.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 6fce7da..d634c5f 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -474,7 +474,8 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 		 */
 		if (elbc_fcm_ctrl->oob || elbc_fcm_ctrl->column != 0 ||
 		    elbc_fcm_ctrl->index != mtd->writesize + mtd->oobsize)
-			out_be32(&lbc->fbcr, elbc_fcm_ctrl->index);
+			out_be32(&lbc->fbcr,
+				elbc_fcm_ctrl->index - elbc_fcm_ctrl->column);
 		else
 			out_be32(&lbc->fbcr, 0);
 
-- 
1.7.1

^ permalink raw reply related

* [PATCH 3/3] mtd/nand : workaround for Freescale FCM to support large-page Nand chip
From: b35362 @ 2011-11-24  0:41 UTC (permalink / raw)
  To: dwmw2, Artem.Bityutskiy, scottwood
  Cc: linuxppc-dev, akpm, linux-mtd, linux-kernel
In-Reply-To: <1322095306-13156-1-git-send-email-b35362@freescale.com>

From: Liu Shuo <b35362@freescale.com>

Freescale FCM controller has a 2K size limitation of buffer RAM. In order
to support the Nand flash chip whose page size is larger than 2K bytes,
we read/write 2k data repeatedly by issuing FIR_OP_RB/FIR_OP_WB and save
them to a large buffer.

Signed-off-by: Liu Shuo <b35362@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
 drivers/mtd/nand/fsl_elbc_nand.c |  211 +++++++++++++++++++++++++++++++++++---
 1 files changed, 194 insertions(+), 17 deletions(-)

diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index d634c5f..c96e714 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -55,7 +55,9 @@ struct fsl_elbc_mtd {
 	struct device *dev;
 	int bank;               /* Chip select bank number           */
 	u8 __iomem *vbase;      /* Chip select base virtual address  */
-	int page_size;          /* NAND page size (0=512, 1=2048)    */
+	int page_size;          /* NAND page size, the mutiple of 2048.
+				 * (0=512, 1=2048, 2=4096, 4=8192....)
+				 */
 	unsigned int fmr;       /* FCM Flash Mode Register value     */
 };
 
@@ -75,6 +77,8 @@ struct fsl_elbc_fcm_ctrl {
 	unsigned int use_mdr;    /* Non zero if the MDR is to be set      */
 	unsigned int oob;        /* Non zero if operating on OOB data     */
 	unsigned int counter;	 /* counter for the initializations	  */
+
+	char *buffer;            /* just be used when pagesize > 2048     */
 };
 
 /* These map to the positions used by the FCM hardware ECC generator */
@@ -150,6 +154,42 @@ static struct nand_bbt_descr bbt_mirror_descr = {
 };
 
 /*=================================*/
+static void io_to_buffer(struct mtd_info *mtd, int subpage, int oob)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct fsl_elbc_mtd *priv = chip->priv;
+	struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
+	void *src, *dst;
+	int len = (oob ? 64 : 2048);
+
+	if (oob)
+		dst = elbc_fcm_ctrl->buffer + mtd->writesize + subpage * 64;
+	else
+		dst = elbc_fcm_ctrl->buffer + subpage * 2048;
+
+	src = elbc_fcm_ctrl->addr + (oob ? 2048 : 0);
+	memcpy_fromio(dst, src, len);
+}
+
+static void buffer_to_io(struct mtd_info *mtd, int subpage, int oob)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct fsl_elbc_mtd *priv = chip->priv;
+	struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
+	void *src, *dst;
+	int len = (oob ? 64 : 2048);
+
+	if (oob)
+		src = elbc_fcm_ctrl->buffer + mtd->writesize + subpage * 64;
+	else
+		src = elbc_fcm_ctrl->buffer + subpage * 2048;
+
+	dst = elbc_fcm_ctrl->addr + (oob ? 2048 : 0);
+	memcpy_toio(dst, src, len);
+
+	/* See the in_8() in fsl_elbc_write_buf() */
+	in_8(elbc_fcm_ctrl->addr);
+}
 
 /*
  * Set up the FCM hardware block and page address fields, and the fcm
@@ -193,7 +233,7 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
 
 	/* for OOB data point to the second half of the buffer */
 	if (oob)
-		elbc_fcm_ctrl->index += priv->page_size ? 2048 : 512;
+		elbc_fcm_ctrl->index += mtd->writesize;
 
 	dev_vdbg(priv->dev, "set_addr: bank=%d, "
 			    "elbc_fcm_ctrl->addr=0x%p (0x%p), "
@@ -311,6 +351,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 	struct fsl_lbc_ctrl *ctrl = priv->ctrl;
 	struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand;
 	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
+	int i;
 
 	elbc_fcm_ctrl->use_mdr = 0;
 
@@ -339,6 +380,26 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 
 		fsl_elbc_do_read(chip, 0);
 		fsl_elbc_run_command(mtd);
+
+		if (priv->page_size <= 1)
+			return;
+
+		/* Continue to read the rest bytes if writesize > 2048 */
+		io_to_buffer(mtd, 0, 0);
+		io_to_buffer(mtd, 0, 1);
+
+		out_be32(&lbc->fir, FIR_OP_RB << FIR_OP1_SHIFT);
+
+		for (i = 1; i < priv->page_size; i++) {
+			/*
+			 * Maybe there are some reasons of FCM hardware timing,
+			 * we must insert a FIR_OP_NOP(0x00) before FIR_OP_RB.
+			 */
+			fsl_elbc_run_command(mtd);
+			io_to_buffer(mtd, i, 0);
+			io_to_buffer(mtd, i, 1);
+		}
+
 		return;
 
 	/* READOOB reads only the OOB because no ECC is performed. */
@@ -347,13 +408,36 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 		         "fsl_elbc_cmdfunc: NAND_CMD_READOOB, page_addr:"
 			 " 0x%x, column: 0x%x.\n", page_addr, column);
 
-		out_be32(&lbc->fbcr, mtd->oobsize - column);
-		set_addr(mtd, column, page_addr, 1);
+		if (priv->page_size <= 1) {
+			out_be32(&lbc->fbcr, mtd->oobsize - column);
+			set_addr(mtd, column, page_addr, 1);
+		} else {
+			out_be32(&lbc->fbcr, 64);
+			set_addr(mtd, 0, page_addr, 1);
+			elbc_fcm_ctrl->index += column;
+		}
 
 		elbc_fcm_ctrl->read_bytes = mtd->writesize + mtd->oobsize;
 
 		fsl_elbc_do_read(chip, 1);
 		fsl_elbc_run_command(mtd);
+
+		if (priv->page_size <= 1)
+			return;
+
+		if (column < 64)
+			io_to_buffer(mtd, 0, 1);
+
+		out_be32(&lbc->fbcr, 2112);
+		out_be32(&lbc->fir, FIR_OP_RB << FIR_OP1_SHIFT);
+		out_be32(&lbc->fpar, in_be32(&lbc->fpar) & ~FPAR_LP_MS);
+
+		for (i = 1; i < priv->page_size; i++) {
+			fsl_elbc_run_command(mtd);
+			if (column < (64 * (i + 1)))
+				io_to_buffer(mtd, i, 1);
+		}
+
 		return;
 
 	/* READID must read all 5 possible bytes while CEB is active */
@@ -429,7 +513,14 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 		      (NAND_CMD_SEQIN    << FCR_CMD2_SHIFT) |
 		      (NAND_CMD_PAGEPROG << FCR_CMD3_SHIFT);
 
-		if (priv->page_size) {
+		if (priv->page_size > 1) {
+			/* writesize > 2048 */
+			out_be32(&lbc->fir,
+				 (FIR_OP_CM2 << FIR_OP0_SHIFT) |
+				 (FIR_OP_CA  << FIR_OP1_SHIFT) |
+				 (FIR_OP_PA  << FIR_OP2_SHIFT) |
+				 (FIR_OP_WB  << FIR_OP3_SHIFT));
+		} else if (priv->page_size) {
 			out_be32(&lbc->fir,
 			         (FIR_OP_CM2 << FIR_OP0_SHIFT) |
 			         (FIR_OP_CA  << FIR_OP1_SHIFT) |
@@ -458,7 +549,13 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 		}
 
 		out_be32(&lbc->fcr, fcr);
-		set_addr(mtd, column, page_addr, elbc_fcm_ctrl->oob);
+		if (elbc_fcm_ctrl->oob && priv->page_size > 1) {
+			set_addr(mtd, 0, page_addr, 0);
+			elbc_fcm_ctrl->index = elbc_fcm_ctrl->column;
+		} else {
+			set_addr(mtd, column, page_addr, elbc_fcm_ctrl->oob);
+		}
+
 		return;
 	}
 
@@ -472,14 +569,59 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 		 * then set the exact length, otherwise use a full page
 		 * write so the HW generates the ECC.
 		 */
-		if (elbc_fcm_ctrl->oob || elbc_fcm_ctrl->column != 0 ||
-		    elbc_fcm_ctrl->index != mtd->writesize + mtd->oobsize)
+		if (elbc_fcm_ctrl->oob) {
+			int len;
+			/* write oob */
+			if (priv->page_size > 1) {
+				/* when pagesize of chip is greater than 2048,
+				 * we have to write full page to write spare
+				 * region, so we fill '0xff' to main region
+				 * and some bytes of spare region which we
+				 * don't want to rewrite.
+				 * (write '1' won't change the original value)
+				 */
+				memset(elbc_fcm_ctrl->buffer, 0xff,
+						elbc_fcm_ctrl->column);
+				len = 2112;
+			} else {
+				len = elbc_fcm_ctrl->index -
+						elbc_fcm_ctrl->column;
+			}
+			out_be32(&lbc->fbcr, len);
+		} else if (elbc_fcm_ctrl->column != 0 ||
+		    elbc_fcm_ctrl->index != mtd->writesize + mtd->oobsize) {
 			out_be32(&lbc->fbcr,
 				elbc_fcm_ctrl->index - elbc_fcm_ctrl->column);
-		else
+		} else {
 			out_be32(&lbc->fbcr, 0);
+		}
+
+		if (priv->page_size > 1) {
+			buffer_to_io(mtd, 0, 0);
+			buffer_to_io(mtd, 0, 1);
+		}
 
 		fsl_elbc_run_command(mtd);
+
+		if (priv->page_size <= 1)
+			return;
+
+		out_be32(&lbc->fir, FIR_OP_WB << FIR_OP1_SHIFT);
+		for (i = 1; i < priv->page_size; i++) {
+			elbc_fcm_ctrl->use_mdr = 1;
+			/* For the last subpage */
+			if (i == priv->page_size - 1)
+				out_be32(&lbc->fir,
+					(FIR_OP_WB  << FIR_OP1_SHIFT) |
+					(FIR_OP_CM3 << FIR_OP2_SHIFT) |
+					(FIR_OP_CW1 << FIR_OP3_SHIFT) |
+					(FIR_OP_RS  << FIR_OP4_SHIFT));
+
+			buffer_to_io(mtd, i, 0);
+			buffer_to_io(mtd, i, 1);
+			fsl_elbc_run_command(mtd);
+		}
+
 		return;
 	}
 
@@ -548,7 +690,14 @@ static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
 		len = bufsize - elbc_fcm_ctrl->index;
 	}
 
-	memcpy_toio(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index], buf, len);
+	if (mtd->writesize > 2048) {
+		memcpy(&elbc_fcm_ctrl->buffer[elbc_fcm_ctrl->index],
+				buf, len);
+	} else {
+		memcpy_toio(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index],
+				buf, len);
+	}
+
 	/*
 	 * This is workaround for the weird elbc hangs during nand write,
 	 * Scott Wood says: "...perhaps difference in how long it takes a
@@ -594,7 +743,13 @@ static void fsl_elbc_read_buf(struct mtd_info *mtd, u8 *buf, int len)
 
 	avail = min((unsigned int)len,
 			elbc_fcm_ctrl->read_bytes - elbc_fcm_ctrl->index);
-	memcpy_fromio(buf, &elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index], avail);
+	if (mtd->writesize > 2048) {
+		memcpy(buf, &elbc_fcm_ctrl->buffer[elbc_fcm_ctrl->index],
+				avail);
+	} else {
+		memcpy_fromio(buf, &elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index],
+				avail);
+	}
 	elbc_fcm_ctrl->index += avail;
 
 	if (len > avail)
@@ -630,10 +785,17 @@ static int fsl_elbc_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
 		return -EINVAL;
 	}
 
-	for (i = 0; i < len; i++)
-		if (in_8(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index + i])
-				!= buf[i])
-			break;
+	if (mtd->writesize > 2048) {
+		for (i = 0; i < len; i++)
+			if (elbc_fcm_ctrl->buffer[elbc_fcm_ctrl->index + i]
+					!= buf[i])
+				break;
+	} else {
+		for (i = 0; i < len; i++)
+			if (in_8(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index + i])
+					!= buf[i])
+				break;
+	}
 
 	elbc_fcm_ctrl->index += len;
 	return i == len && elbc_fcm_ctrl->status == LTESR_CC ? 0 : -EIO;
@@ -716,8 +878,9 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
 	if (mtd->writesize == 512) {
 		priv->page_size = 0;
 		clrbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS);
-	} else if (mtd->writesize == 2048) {
-		priv->page_size = 1;
+	} else if (mtd->writesize >= 2048 && mtd->writesize <= 16 * 1024) {
+		priv->page_size = mtd->writesize / 2048;
+
 		setbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS);
 		/* adjust ecc setup if needed */
 		if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) ==
@@ -891,6 +1054,19 @@ static int __devinit fsl_elbc_nand_probe(struct platform_device *pdev)
 			goto err;
 		}
 		elbc_fcm_ctrl->counter++;
+		/*
+		 * Freescale FCM controller has a 2K size limitation of buffer
+		 * RAM, so elbc_fcm_ctrl->buffer have to be used if writesize
+		 * of chip is greater than 2048.
+		 * We malloc a large enough buffer (maximum page size is 16K).
+		 */
+		elbc_fcm_ctrl->buffer = kmalloc(1024 * 16 + 1024, GFP_KERNEL);
+		if (!elbc_fcm_ctrl->buffer) {
+			dev_err(dev, "failed to allocate memory\n");
+			mutex_unlock(&fsl_elbc_nand_mutex);
+			ret = -ENOMEM;
+			goto err;
+		}
 
 		spin_lock_init(&elbc_fcm_ctrl->controller.lock);
 		init_waitqueue_head(&elbc_fcm_ctrl->controller.wq);
@@ -960,6 +1136,7 @@ static int fsl_elbc_nand_remove(struct platform_device *pdev)
 	elbc_fcm_ctrl->counter--;
 	if (!elbc_fcm_ctrl->counter) {
 		fsl_lbc_ctrl_dev->nand = NULL;
+		kfree(elbc_fcm_ctrl->buffer);
 		kfree(elbc_fcm_ctrl);
 	}
 	mutex_unlock(&fsl_elbc_nand_mutex);
-- 
1.7.1

^ permalink raw reply related

* [PATCH 1/3] mtd/nand : use elbc_fcm_ctrl->oob to set FPAR_MS bit of FPAR
From: b35362 @ 2011-11-24  0:41 UTC (permalink / raw)
  To: dwmw2, Artem.Bityutskiy, scottwood
  Cc: linuxppc-dev, akpm, linux-mtd, linux-kernel

From: Liu Shuo <b35362@freescale.com>

On both of large-page chip and small-page chip, we always should use
'elbc_fcm_ctrl->oob' to set the FPAR_LP_MS/FPAR_SP_MS bit of FPAR, don't
use a overflowed 'column' to set it.

Signed-off-by: Liu Shuo <b35362@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
 drivers/mtd/nand/fsl_elbc_nand.c |   18 +++++++++++-------
 1 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index cc08a11..6fce7da 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -414,9 +414,17 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 		         page_addr, column);
 
 		elbc_fcm_ctrl->column = column;
-		elbc_fcm_ctrl->oob = 0;
 		elbc_fcm_ctrl->use_mdr = 1;
 
+		if (column >= mtd->writesize) {
+			/* OOB area */
+			column -= mtd->writesize;
+			elbc_fcm_ctrl->oob = 1;
+		} else {
+			WARN_ON(column != 0);
+			elbc_fcm_ctrl->oob = 0;
+		}
+
 		fcr = (NAND_CMD_STATUS   << FCR_CMD1_SHIFT) |
 		      (NAND_CMD_SEQIN    << FCR_CMD2_SHIFT) |
 		      (NAND_CMD_PAGEPROG << FCR_CMD3_SHIFT);
@@ -441,16 +449,12 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 			         (FIR_OP_CW1 << FIR_OP6_SHIFT) |
 			         (FIR_OP_RS  << FIR_OP7_SHIFT));
 
-			if (column >= mtd->writesize) {
+			if (elbc_fcm_ctrl->oob)
 				/* OOB area --> READOOB */
-				column -= mtd->writesize;
 				fcr |= NAND_CMD_READOOB << FCR_CMD0_SHIFT;
-				elbc_fcm_ctrl->oob = 1;
-			} else {
-				WARN_ON(column != 0);
+			else
 				/* First 256 bytes --> READ0 */
 				fcr |= NAND_CMD_READ0 << FCR_CMD0_SHIFT;
-			}
 		}
 
 		out_be32(&lbc->fcr, fcr);
-- 
1.7.1

^ permalink raw reply related

* Re: [PATCH v2] usb/fsl_udc: fix dequeuing a request in progress
From: Peter Chen @ 2011-11-24  1:56 UTC (permalink / raw)
  To: Li Yang; +Cc: gregkh, linuxppc-dev, linux-usb, balbi
In-Reply-To: <1322050376-13553-1-git-send-email-leoli@freescale.com>

On Wed, Nov 23, 2011 at 08:12:56PM +0800, Li Yang wrote:
> The original implementation of dequeuing a request in progress
> is not correct.  Change to use a correct process and also clean
> up the related functions a little bit.
> 
> Signed-off-by: Li Yang <leoli@freescale.com>
> Cc: Peter Chen <peter.chen@freescale.com>
> ---
>  drivers/usb/gadget/fsl_udc_core.c |   68 +++++++++++++++++-------------------
>  drivers/usb/gadget/fsl_usb2_udc.h |   10 +++++
>  2 files changed, 42 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
> index b2c44e1..cc704dc 100644
> --- a/drivers/usb/gadget/fsl_udc_core.c
> +++ b/drivers/usb/gadget/fsl_udc_core.c
> @@ -696,12 +696,31 @@ static void fsl_free_request(struct usb_ep *_ep, struct usb_request *_req)
>  		kfree(req);
>  }
>  
> -/*-------------------------------------------------------------------------*/
> +/* Actually add a dTD chain to an empty dQH and let go */
> +static void fsl_prime_ep(struct fsl_ep *ep, struct ep_td_struct *td)
> +{
> +	struct ep_queue_head *qh = get_qh_by_ep(ep);
> +
> +	/* Write dQH next pointer and terminate bit to 0 */
> +	qh->next_dtd_ptr = cpu_to_hc32(td->td_dma
> +			& EP_QUEUE_HEAD_NEXT_POINTER_MASK);
> +
> +	/* Clear active and halt bit */
> +	qh->size_ioc_int_sts &= cpu_to_hc32(~(EP_QUEUE_HEAD_STATUS_ACTIVE
> +					| EP_QUEUE_HEAD_STATUS_HALT));
> +
> +	/* Ensure that updates to the QH will occur before priming. */
> +	wmb();
> +
> +	/* Prime endpoint by writing correct bit to ENDPTPRIME */
> +	fsl_writel(ep_is_in(ep) ? (1 << (ep_index(ep) + 16))
> +			: (1 << (ep_index(ep))), &dr_regs->endpointprime);
> +}
> +
> +/* Add dTD chain to the dQH of an EP */
>  static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
>  {
> -	int i = ep_index(ep) * 2 + ep_is_in(ep);
>  	u32 temp, bitmask, tmp_stat;
> -	struct ep_queue_head *dQH = &ep->udc->ep_qh[i];
>  
>  	/* VDBG("QH addr Register 0x%8x", dr_regs->endpointlistaddr);
>  	VDBG("ep_qh[%d] addr is 0x%8x", i, (u32)&(ep->udc->ep_qh[i])); */
> @@ -719,7 +738,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
>  			cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK);
>  		/* Read prime bit, if 1 goto done */
>  		if (fsl_readl(&dr_regs->endpointprime) & bitmask)
> -			goto out;
> +			return;
>  
>  		do {
>  			/* Set ATDTW bit in USBCMD */
> @@ -736,28 +755,10 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
>  		fsl_writel(temp & ~USB_CMD_ATDTW, &dr_regs->usbcmd);
>  
>  		if (tmp_stat)
> -			goto out;
> +			return;
>  	}
>  
> -	/* Write dQH next pointer and terminate bit to 0 */
> -	temp = req->head->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK;
> -	dQH->next_dtd_ptr = cpu_to_hc32(temp);
> -
> -	/* Clear active and halt bit */
> -	temp = cpu_to_hc32(~(EP_QUEUE_HEAD_STATUS_ACTIVE
> -			| EP_QUEUE_HEAD_STATUS_HALT));
> -	dQH->size_ioc_int_sts &= temp;
> -
> -	/* Ensure that updates to the QH will occur before priming. */
> -	wmb();
> -
> -	/* Prime endpoint by writing 1 to ENDPTPRIME */
> -	temp = ep_is_in(ep)
> -		? (1 << (ep_index(ep) + 16))
> -		: (1 << (ep_index(ep)));
> -	fsl_writel(temp, &dr_regs->endpointprime);
> -out:
> -	return;
> +	fsl_prime_ep(ep, req->head);
>  }
>  
>  /* Fill in the dTD structure
> @@ -973,25 +974,20 @@ static int fsl_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
>  
>  		/* The request isn't the last request in this ep queue */
>  		if (req->queue.next != &ep->queue) {
> -			struct ep_queue_head *qh;
>  			struct fsl_req *next_req;
>  
> -			qh = ep->qh;
>  			next_req = list_entry(req->queue.next, struct fsl_req,
>  					queue);
>  
> -			/* Point the QH to the first TD of next request */
> -			fsl_writel((u32) next_req->head, &qh->curr_dtd_ptr);
> +			/* prime with dTD of next request */
> +			fsl_prime_ep(ep, next_req->head);
>  		}
> -
> -		/* The request hasn't been processed, patch up the TD chain */
> +	/* The request hasn't been processed, patch up the TD chain */
>  	} else {
>  		struct fsl_req *prev_req;
>  
>  		prev_req = list_entry(req->queue.prev, struct fsl_req, queue);
> -		fsl_writel(fsl_readl(&req->tail->next_td_ptr),
> -				&prev_req->tail->next_td_ptr);
> -
> +		prev_req->tail->next_td_ptr = req->tail->next_td_ptr;
>  	}
>  
>  	done(ep, req, -ECONNRESET);
> @@ -1068,7 +1064,7 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep)
>  	struct fsl_udc *udc;
>  	int size = 0;
>  	u32 bitmask;
> -	struct ep_queue_head *d_qh;
> +	struct ep_queue_head *qh;
>  
>  	ep = container_of(_ep, struct fsl_ep, ep);
>  	if (!_ep || (!ep->desc && ep_index(ep) != 0))
> @@ -1079,13 +1075,13 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep)
>  	if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)
>  		return -ESHUTDOWN;
>  
> -	d_qh = &ep->udc->ep_qh[ep_index(ep) * 2 + ep_is_in(ep)];
> +	qh = get_qh_by_ep(ep);
>  
>  	bitmask = (ep_is_in(ep)) ? (1 << (ep_index(ep) + 16)) :
>  	    (1 << (ep_index(ep)));
>  
>  	if (fsl_readl(&dr_regs->endptstatus) & bitmask)
> -		size = (d_qh->size_ioc_int_sts & DTD_PACKET_SIZE)
> +		size = (qh->size_ioc_int_sts & DTD_PACKET_SIZE)
>  		    >> DTD_LENGTH_BIT_POS;
>  
>  	pr_debug("%s %u\n", __func__, size);
> diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h
> index 1d51be8..f781f5d 100644
> --- a/drivers/usb/gadget/fsl_usb2_udc.h
> +++ b/drivers/usb/gadget/fsl_usb2_udc.h
> @@ -569,6 +569,16 @@ static void dump_msg(const char *label, const u8 * buf, unsigned int length)
>  					* 2 + ((windex & USB_DIR_IN) ? 1 : 0))
>  #define get_pipe_by_ep(EP)	(ep_index(EP) * 2 + ep_is_in(EP))
>  
> +static inline struct ep_queue_head *get_qh_by_ep(struct fsl_ep *ep)
> +{
> +	/* we only have one ep0 structure but two queue heads */
> +	if (ep_index(ep) != 0)
> +		return ep->qh;
> +	else
> +		return &ep->udc->ep_qh[(ep->udc->ep0_dir ==
> +				USB_DIR_IN) ? 1 : 0];
> +}
> +
>  struct platform_device;
>  #ifdef CONFIG_ARCH_MXC
>  int fsl_udc_clk_init(struct platform_device *pdev);
> -- 
> 1.5.4.3
> 
Testing this patch at i.MX51 BBG, and it is OK.

Acked-by: Peter Chen <peter.chen@freescale.com>
-- 

Best Regards,
Peter Chen

^ permalink raw reply

* Re: [RFC PATCH 0/11] KVM: PPC: Update Book3S HV memory handling
From: Marcelo Tosatti @ 2011-11-23 23:59 UTC (permalink / raw)
  To: Paul Mackerras
  Cc: linuxppc-dev, kvm list, Alexander Graf, kvm-ppc, Avi Kivity
In-Reply-To: <20111118215424.GA24455@bloggs.ozlabs.ibm.com>

On Sat, Nov 19, 2011 at 08:54:24AM +1100, Paul Mackerras wrote:
> On Fri, Nov 18, 2011 at 02:57:11PM +0100, Alexander Graf wrote:
> > 
> > This touches areas that I'm sure non-PPC people would want to see as
> > well. Could you please CC kvm@vger too next time?
> > 
> > Avi, Marcelo, mind to review some of the bits in this patch set? :)
> 
> I did cc the last patch (the one that adds barriers in the MMU
> notifier sequence/count logic) to kvm@vger.  Do you mean I should cc
> the whole series?  The only other thing touching generic code is the
> addition of the KVM_MEMSLOT_IO flag in the first patch.

I don't see such flag anywhere in the patches in this thread?

> I'm hoping the extra barriers will be OK since they are no-ops on
> x86.  In fact I now think that the smp_wmbs I added to
> kvm_mmu_notifier_invalidate_page and kvm_mmu_notifier_change_pte
> aren't in fact necessary, since it's only necessary to ensure that the
> sequence number increase is visible before the point where
> kvm_unmap_hva or kvm_set_spte_hva unlock the bitlock on the first rmap
> chain they look at, which will be ensured anyway by the barrier before
> the unlock.
> 
> Paul.
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [RFC PATCH 11/11] KVM: PPC: Eliminate global spinlock in kvmppc_h_enter
From: Marcelo Tosatti @ 2011-11-23 23:54 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, Alexander Graf, kvm-ppc, kvm
In-Reply-To: <20111116235549.GL26985@bloggs.ozlabs.ibm.com>

On Thu, Nov 17, 2011 at 10:55:49AM +1100, Paul Mackerras wrote:
> >From dfd5bcfac841f8a36593edf60d9fb15e0d633287 Mon Sep 17 00:00:00 2001
> From: Paul Mackerras <paulus@samba.org>
> Date: Mon, 14 Nov 2011 13:30:38 +1100
> Subject: 
> 
> Currently, kvmppc_h_enter takes a spinlock that is global to the guest,
> kvm->mmu_lock, in order to check for pending PTE invalidations safely.
> On some workloads, kvmppc_h_enter is called heavily and the use of a
> global spinlock could compromise scalability.  We already use a per-
> guest page spinlock in the form of the bit spinlock on the rmap chain,
> and this gives us synchronization with the PTE invalidation side, which
> also takes the bit spinlock on the rmap chain for each page being
> invalidated.  Thus it is sufficient to check for pending invalidations
> while the rmap chain bit spinlock is held.  However, now we require
> barriers in mmu_notifier_retry() and in the places where
> mmu_notifier_count and mmu_notifier_seq are updated, since we can now
> call mmu_notifier_retry() concurrently with updates to those fields.
> 
> Signed-off-by: Paul Mackerras <paulus@samba.org>
> ---
> Cc'd to kvm@vger.kernel.org for review of the generic kvm changes.

Looks good to me.

^ permalink raw reply

* Re: [PATCH v3 2/8] [booke] Rename mapping based RELOCATABLE to DYNAMIC_MEMSTART for BookE
From: Josh Boyer @ 2011-11-23 16:47 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: Josh Poimboeuf, David Laight, Alan Modra, Scott Wood,
	linuxppc-dev
In-Reply-To: <20111114054144.23410.65704.stgit@suzukikp.in.ibm.com>

On Mon, Nov 14, 2011 at 12:41 AM, Suzuki K. Poulose <suzuki@in.ibm.com> wro=
te:
> The current implementation of CONFIG_RELOCATABLE in BookE is based
> on mapping the page aligned kernel load address to KERNELBASE. This
> approach however is not enough for platforms, where the TLB page size
> is large (e.g, 256M on 44x). So we are renaming the RELOCATABLE used
> currently in BookE to DYNAMIC_MEMSTART to reflect the actual method.
>
> The CONFIG_RELOCATABLE for PPC32(BookE) based on processing of the
> dynamic relocations will be introduced in the later in the patch series.
>
> This change would allow the use of the old method of RELOCATABLE for
> platforms which can afford to enforce the page alignment (platforms with
> smaller TLB size).

I'm OK with the general direction, but this touches a lot of non-4xx
code.  I'd prefer it if Ben took this directly on whatever final
solution is done.

> I haven tested this change only on 440x. I don't have an FSL BookE to ver=
ify
> the changes there.
>
> Scott,
> Could you please test this patch on FSL and let me know the results ?

Scott, did you ever get around to testing this?  In my opinion, this
shouldn't go in without a Tested-by: from someone that tried it on an
FSL platform.

> Suggested-by: Scott Wood <scottwood@freescale.com>
>
> Signed-off-by: Suzuki K. Poulose <suzuki@in.ibm.com>
> Cc: =A0 =A0 Scott Wood <scottwood@freescale.com>
> Cc: =A0 =A0 Kumar Gala <galak@kernel.crashing.org>
> Cc: =A0 =A0 Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: =A0 =A0 linux ppc dev <linuxppc-dev@lists.ozlabs.org>
> ---
>
> =A0arch/powerpc/Kconfig =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0| =A0 50 ++++++++++++++++---------
> =A0arch/powerpc/configs/44x/iss476-smp_defconfig | =A0 =A02 +
> =A0arch/powerpc/include/asm/kdump.h =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A05=
 ++-
> =A0arch/powerpc/include/asm/page.h =A0 =A0 =A0 =A0 =A0 =A0 =A0 | =A0 =A04=
 +-
> =A0arch/powerpc/kernel/crash_dump.c =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A04=
 +-
> =A0arch/powerpc/kernel/head_44x.S =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =
=A04 ++
> =A0arch/powerpc/kernel/head_fsl_booke.S =A0 =A0 =A0 =A0 =A0| =A0 =A02 +
> =A0arch/powerpc/kernel/machine_kexec.c =A0 =A0 =A0 =A0 =A0 | =A0 =A02 +
> =A0arch/powerpc/kernel/prom_init.c =A0 =A0 =A0 =A0 =A0 =A0 =A0 | =A0 =A02=
 +
> =A0arch/powerpc/mm/44x_mmu.c =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 | =
=A0 =A02 +
> =A010 files changed, 47 insertions(+), 30 deletions(-)
>
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index d7c2d1a..8d4f789 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -363,7 +363,8 @@ config KEXEC
> =A0config CRASH_DUMP
> =A0 =A0 =A0 =A0bool "Build a kdump crash kernel"
> =A0 =A0 =A0 =A0depends on PPC64 || 6xx || FSL_BOOKE
> - =A0 =A0 =A0 select RELOCATABLE if PPC64 || FSL_BOOKE
> + =A0 =A0 =A0 select RELOCATABLE if PPC64
> + =A0 =A0 =A0 select DYNAMIC_MEMSTART if FSL_BOOKE
> =A0 =A0 =A0 =A0help
> =A0 =A0 =A0 =A0 =A0Build a kernel suitable for use as a kdump capture ker=
nel.
> =A0 =A0 =A0 =A0 =A0The same kernel binary can be used as production kerne=
l and dump
> @@ -841,23 +842,36 @@ config LOWMEM_CAM_NUM
> =A0 =A0 =A0 =A0int "Number of CAMs to use to map low memory" if LOWMEM_CA=
M_NUM_BOOL
> =A0 =A0 =A0 =A0default 3
>
> -config RELOCATABLE
> - =A0 =A0 =A0 bool "Build a relocatable kernel (EXPERIMENTAL)"
> +config DYNAMIC_MEMSTART

OK, so my one bikeshed comment here.

We add DYNAMIC_MEMSTART for 32-bit, and we have RELOCATABLE for
64-bit.  Then throughout almost the rest of the patch, all we're doing
is duplicating what RELOCATABLE already did (e.g. if ! either thing).
It works, but it is kind of ugly.

Instead, could we define a helper config variable that can be used in
place of that construct?  Something like:

config NONSTATIC_KERNEL (or whatever)
    bool
    default n

...

config DYNAMIC_MEMSTART
    <blah>
    select NONSTATIC_KERNEL

...

config RELOCATABLE
    <blah>
    select NONSTATIC_KERNEL


Then you can do this kind of thing:

       default "0x02000000" if PPC_STD_MMU && CRASH_DUMP && !(NONSTATIC_KER=
NEL)

#if defined(CONFIG_CRASH_DUMP) && !(defined(CONFIG_NONSTATIC_KERNEL))

instead of this:

       default "0x02000000" if PPC_STD_MMU && CRASH_DUMP &&
!(RELOCATABLE || DYNAMIC_MEMSTART)
#if defined(CONFIG_CRASH_DUMP) && !(defined(CONFIG_RELOCATABLE) || \
                                   defined(CONFIG_DYNAMIC_MEMSTART))

while still allowing for differences between RELOCATABLE and DYNAMIC_MEMSTA=
RT.

Thoughts?

josh

^ permalink raw reply

* Re: [PATCH v3 1/8] [44x] Fix typo in KEXEC Kconfig dependency
From: Josh Boyer @ 2011-11-23 16:26 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: Josh Poimboeuf, David Laight, Alan Modra, Scott Wood,
	linuxppc-dev
In-Reply-To: <20111114054129.23410.57513.stgit@suzukikp.in.ibm.com>

On Mon, Nov 14, 2011 at 12:41 AM, Suzuki K. Poulose <suzuki@in.ibm.com> wro=
te:
> Kexec is not supported on 47x. 47x is a variant of 44x with slightly
> different MMU and SMP support. There was a typo in the Kconfig
> dependency for KEXEC. This patch fixes the same.
>
> Signed-off-by: Suzuki K. Poulose <suzuki@in.ibm.com>
> Cc: =A0 =A0 Kumar Gala <galak@kernel.crashing.org>
> Cc: =A0 =A0 Josh Boyer <jwboyer@gmail.com>
> Cc: =A0 =A0 linux ppc dev <linuxppc-dev@lists.ozlabs.org>

Ben already took this one for 3.2.  I should have added my Acked-by a while=
 ago.

josh

^ permalink raw reply

* Re: [PATCH] powerpc/40x: Add APM8018X SOC support
From: Kumar Gala @ 2011-11-23 16:16 UTC (permalink / raw)
  To: Tanmay Inamdar; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1322041464-20605-1-git-send-email-tinamdar@apm.com>


On Nov 23, 2011, at 3:44 AM, Tanmay Inamdar wrote:

> arch/powerpc/kernel/udbg_16550.c            |   22 +

Would be probably good to split this change into its own patch.

- k

^ permalink raw reply

* Re: [PATCH] powerpc/40x: Add APM8018X SOC support
From: Arnd Bergmann @ 2011-11-23 14:15 UTC (permalink / raw)
  To: Tanmay Inamdar; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1322041464-20605-1-git-send-email-tinamdar@apm.com>

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

Hi Tanmay,

> +#if defined(CONFIG_APM8018X)
> +#define DCRN_CPR0_ADDR	0xa
> +#define DCRN_CPR0_DATA	0xb
> +#else
>  /* 440EP Clock/Power-on Reset regs */
>  #define DCRN_CPR0_ADDR	0xc
>  #define DCRN_CPR0_DATA	0xd
> +#endif /* CONFIG_APM8018X */

This prevents you from building one kernel that runs on both APM8018X and
others. Better define a new constant name for the new registers and select
the right one at run-time.

> diff --git a/arch/powerpc/boot/dts/klondike.dts b/arch/powerpc/boot/dts/klondike.dts
> new file mode 100644
> index 0000000..9372a52
> --- /dev/null
> +++ b/arch/powerpc/boot/dts/klondike.dts
> @@ -0,0 +1,668 @@
> +/*
> + * Device Tree Source for AMCC Klondike (405)
> + *

The device tree file for the most part describes the chip, but partly also
the board. Have you considered splitting the soc parts into a .dtsi file
and moving all the configuration into a separate file?


> diff --git a/arch/powerpc/configs/40x/klondike_defconfig b/arch/powerpc/configs/40x/klondike_defconfig
> new file mode 100644
> index 0000000..840f438
> --- /dev/null
> +++ b/arch/powerpc/configs/40x/klondike_defconfig
> @@ -0,0 +1,1353 @@
> +#
> +# Automatically generated file; DO NOT EDIT.
> +# Linux/powerpc 3.2.0-rc2 Kernel Configuration
> +#
> +# CONFIG_PPC64 is not set
> +

Please use 'make savedefconfig' to create a minimal defconfig file instead of listing
the full configuration here.

> diff --git a/arch/powerpc/include/asm/dcr-regs.h b/arch/powerpc/include/asm/dcr-regs.h
> index 380274d..c900cfd 100644
> --- a/arch/powerpc/include/asm/dcr-regs.h
> +++ b/arch/powerpc/include/asm/dcr-regs.h
> @@ -24,9 +24,18 @@
>   * of the driver main register set
>   */
>  
> +#if defined(CONFIG_APM8018X)
> +/* CPR */
> +#define DCRN_CPR0_CONFIG_ADDR	0xa
> +#define DCRN_CPR1_CONFIG_DATA	0xb
> +/* AHB */
> +#define DCRN_SDR1_CONFIG_ADDR	0xc
> +#define DCRN_SDR1_CONFIG_DATA	0xd
> +#else
>  /* CPRs (440GX and 440SP/440SPe) */
>  #define DCRN_CPR0_CONFIG_ADDR	0xc
>  #define DCRN_CPR0_CONFIG_DATA	0xd
> +#endif /* CONFIG_APM8018X */

same comment as above.

> diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
> index edae5bb..e5c51a6 100644
> --- a/arch/powerpc/kernel/cputable.c
> +++ b/arch/powerpc/kernel/cputable.c
> @@ -1505,6 +1505,58 @@ static struct cpu_spec __initdata cpu_specs[] = {
>  		.machine_check		= machine_check_4xx,
>  		.platform		= "ppc405",
>  	},
> +	{	/* APM80186-SK */
> +		.pvr_mask		= 0xffffffff,
> +		.pvr_value		= 0x7ff11432,

If you mask out the lower bits, you only need a single entry instead of
four identical ones.

> --- a/arch/powerpc/kernel/udbg_16550.c
> +++ b/arch/powerpc/kernel/udbg_16550.c
> @@ -18,6 +18,19 @@ extern void real_writeb(u8 data, volatile u8 __iomem *addr);
>  extern u8 real_205_readb(volatile u8 __iomem  *addr);
>  extern void real_205_writeb(u8 data, volatile u8 __iomem *addr);
>  
> +#ifdef CONFIG_UART_16550_WORD_ADDRESSABLE
> +struct NS16550 {
> +	/* this struct must be packed */
> +	unsigned char rbr;  /* 0 */ u8 s0[3];
> +	unsigned char ier;  /* 1 */ u8 s1[3];
> +	unsigned char fcr;  /* 2 */ u8 s2[3];
> +	unsigned char lcr;  /* 3 */ u8 s3[3];
> +	unsigned char mcr;  /* 4 */ u8 s4[3];
> +	unsigned char lsr;  /* 5 */ u8 s5[3];
> +	unsigned char msr;  /* 6 */ u8 s6[3];
> +	unsigned char scr;  /* 7 */ u8 s7[3];
> +};
> +#else
>  struct NS16550 {
>  	/* this struct must be packed */
>  	unsigned char rbr;  /* 0 */
> @@ -29,6 +42,7 @@ struct NS16550 {
>  	unsigned char msr;  /* 6 */
>  	unsigned char scr;  /* 7 */
>  };
> +#endif /* CONFIG_UART_16550_WORD_ADDRESSABLE */
>

Same things as with the register definitions. Please make this
run-time selectable to allow build-time configurations that
support both layouts.

	Arnd

^ permalink raw reply

* Re: [PATCH] powerpc/40x: Add APM8018X SOC support
From: Josh Boyer @ 2011-11-23 14:10 UTC (permalink / raw)
  To: Tanmay Inamdar; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1322041464-20605-1-git-send-email-tinamdar@apm.com>

On Wed, Nov 23, 2011 at 4:44 AM, Tanmay Inamdar <tinamdar@apm.com> wrote:
>
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index b177caa..3f2cc36 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -978,3 +978,9 @@ config PPC_LIB_RHEAP
> =A0 =A0 =A0 =A0bool
>
> =A0source "arch/powerpc/kvm/Kconfig"
> +
> +config UART_16550_WORD_ADDRESSABLE
> + =A0 =A0 =A0 bool
> + =A0 =A0 =A0 default n
> + =A0 =A0 =A0 help
> + =A0 =A0 =A0 =A0 =A0Enable this if your UART 16550 is word addressable.

Ugh.  What is this for?  More specifically, if the UART requires word
reads and writes, shouldn't it be using reg-shift/reg-offset in the
device tree?  I'm confused why UDBG would need this sort of code, but
the runtime serial driver doesn't?

> diff --git a/arch/powerpc/boot/dts/klondike.dts b/arch/powerpc/boot/dts/k=
londike.dts


> + =A0 =A0 =A0 OCM: ocm@20000000 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =3D "ibm,ocm";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 status =3D "enabled";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 cell-index =3D <1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 reg =3D < 0x20000000 0x1f000 =A0 /* 128K - =
4K NAND */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 0xfffe0000 0x1f000>; /* 128=
K - 4K I2C =A0*/
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 bootmode =3D "nand";
> + =A0 =A0 =A0 };

What is this?  There's nothing in the kernel or in this patch that
binds with "ibm,ocm".  Also, that 'bootmode' property doesn't seem
like a hardware value, but a human descriptor of something that
switches it to boot from NAND.


> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 crypto: crypto@40000000 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 device_type =3D "crypto";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =3D "405ex-crypt=
o", "amcc,ppc405ex-crypto", "amcc,ppc4xx-crypto";

Why is the "405ex-crypto" string there?

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 EDMA: edma@40080000 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #address-cells =3D <1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #size-cells =3D <1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =3D "amcc,edma";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 device_type =3D "dma";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /*complQ-fifo-memory =3D "o=
cm";*/
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 cell-index =3D <0>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 reg =3D <0x40080000 0x00010=
000>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dcr-reg =3D <0x060 0x09f>;
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupt-parent =3D <&UIC0=
>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupts =3D </*complQ A =
*/ =A00x4 4
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 /*EDMA Err */ =A00x6 4 >;
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dma-channel@0 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =
=3D "amcc,edma-channel";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /*descripto=
r-memory =3D "ocm";*/
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 cell-index =
=3D <0>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dcr-reg =3D=
 <0x0000006a 0x0000006b>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 };
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 };

What's this?  Again, nothing binds to "amcc,edma" in the kernel or
patch.  At the very least this (and OCM above) need some binding
descriptions added to Documentation/devicetree/bindings/powerpc/4xx/

> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 MSI: dwc_pcie-msi@40090000 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =3D "amcc,dwc_pc=
ie-msi", "dwc_pcie-msi";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 status =3D "ok";

Is the status property something that is set by U-Boot, or will it
always be "ok"?  If the latter, I don't think you need to specify it
at all.

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 reg =3D <0x40090000 0x100>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupts =3D<0x0 0x1 0x2 =
0x3>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupt-parent =3D <&MSI>=
;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #interrupt-cells =3D <1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #address-cells =3D <0>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #size-cells =3D <0>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupt-map =3D <0x0 &UIC=
0 0x0C 0x1
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A00x1 &UIC0 0x0D 0x1
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A00x2 &UIC0 0x0E 0x1
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A00x3 &UIC0 0x0F 0x1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 };

Same binding comment here.

> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 AHB: ahb {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 device_type =3D "ahb";

I doubt the device_type is needed.

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =3D "amcc,405ex-=
ahb", "ibm,ahb";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #address-cells =3D <1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #size-cells =3D <1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ranges;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 clock-frequency =3D <0>; /*=
 Filled in by U-Boot */

Same binding comment for ahb.

> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 lcd: lcd@58060000 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 device_type=
 =3D "lcd";

Drop device_type.

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =
=3D "apm,apm-lcd","apm,db9000";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 version =3D=
 "apm-1.1";

Why is 'version' there?  Version of what?  The hardware itself, the
driver?  I doubt this is needed.

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 reg =3D <0x=
58060000 0x00001000>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupt-p=
arent =3D <&UIC0>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* interr=
upt index 0 for chip 1.0
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* interr=
upt index 1 for chip 1.1
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*/
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupts =
=3D <0x1c 2 0x1c 4>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 };

Same binding comment for apm,apm-lcd.  I'm just going to assert again
that anything that doesn't have a defined binding and/or driver needs
to be documented when it's introduced.  Repeat that for the rest of
the patch :).

> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 sdhc0: sdhc@58050000 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 device_type=
 =3D "sdhc";

Drop device_type.

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =
=3D "amcc,ahb-sdhc";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #interrupt-=
cells =3D <1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 reg =3D <0x=
58050000 0x100>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupt-p=
arent =3D <&UIC0>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupts =
=3D <0x18 0x4>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 bootmode =
=3D "i2c";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 };
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 tdm0: tdm@58010000 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 device_type=
 =3D "tdm";

Drop device_type.

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 status =3D =
"disabled";

Is that set by U-Boot?

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =
=3D "apm,ahb-tdm";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #interrupt-=
cells =3D <1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 reg =3D <0x=
58010000 0x100>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupt-p=
arent =3D <&UIC1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupts =
=3D <0x15 0x1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 };
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 usbotg0: usbotg@58080000 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 device_type=
 =3D "usb";

Drop device_type.

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =
=3D "apm,usb-otg";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 reg =3D <0x=
58080000 0x10000>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupt-p=
arent =3D <&UIC0>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupts =
=3D <0x1B 4>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mode =3D "h=
ost";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 };
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 spi0: spi@50000000 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #address-ce=
lls =3D <1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #size-cells=
 =3D <0>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 device_type=
 =3D "spi";

Drop device_type.  I think you're starting to get the trend, so repeat
for the rest of the devices.

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =
=3D "apm,apm-spi";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 reg =3D <0x=
50000000 0x100>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupt-p=
arent =3D <&UIC0>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupts =
=3D <0x7 1>; =A0/* interrupt number->0x7 Polarity->HIGH Sensitivity->LEVEL =
*/
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 half_duplex=
 =3D <0x1>; =A0 /*0 =3D rx/tx mode, 1 =3D eprom read mode */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 sysclk =3D =
<100000000>; =A0 /* input clock */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 bus_num =3D=
 <0x0>; =A0 =A0 =A0 /* SPI =3D 0 */

> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 PCIE0: pciex@58020000 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 device_type=
 =3D "pci";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =
=3D "ibm,plb-pciex", "dwc-pciex", "amcc,dwc-pciex";

Why the unprefixed dwc-pciex compatible property?

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #interrupt-=
cells =3D <1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #size-cells=
 =3D <2>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #address-ce=
lls =3D <3>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 primary;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 port =3D <0=
>; /* port number */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 status =3D =
"ok";


> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 PCIE1: pciex@58030000 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 device_type=
 =3D "pci";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =
=3D "ibm,plb-pciex", "dwc-pciex", "amcc,dwc-pciex";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #interrupt-=
cells =3D <1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #size-cells=
 =3D <2>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #address-ce=
lls =3D <3>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 primary;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 port =3D <1=
>; /* port number */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 status =3D =
"disabled";

Is this set by U-Boot?


> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 sata@58040000 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =
=3D "sata-ahci";

Uh.. what?

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 reg =3D =A0=
<0x58040000 0x2000>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupt-p=
arent =3D <&UIC0>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupts =
=3D <0x1a 1>;


> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ufc@0xFE000=
000 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 compatible =3D "ibm,ufc";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 reg =3D <0xFE000000 0x00010000>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 #address-cells =3D <1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 #size-cells =3D <1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 bootmode =3D "nand";

Is UFC some kind of new flash controller that isn't NDFC?  Also,
bootmode seems to be a human and/or driver variable, not a description
of the hardware.

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 UART0: serial@50001000 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 device_type=
 =3D "serial";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =
=3D "ns16550";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 reg =3D <0x=
50001000 0x00000100>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 virtual-reg=
 =3D <0x50001000>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 clock-frequ=
ency =3D <300000000>; /* Filled in by U-Boot */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 current-spe=
ed =3D <115200>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupt-p=
arent =3D <&UIC0>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupts =
=3D <0x0 0x4>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /*reg-shift=
 =3D <2>;*/

This is commented out, but seems to be needed when you take the
word-addressed UDBG thing into account?


> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 IEEE1588_0: ieee1588ts0@400=
a5000 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 status =3D =
"ok";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =
=3D "ieee1588-ts";

What is that?

> diff --git a/arch/powerpc/configs/40x/klondike_defconfig b/arch/powerpc/c=
onfigs/40x/klondike_defconfig
> new file mode 100644
> index 0000000..840f438
> --- /dev/null
> +++ b/arch/powerpc/configs/40x/klondike_defconfig
> @@ -0,0 +1,1353 @@
> +#
> +# Automatically generated file; DO NOT EDIT.
> +# Linux/powerpc 3.2.0-rc2 Kernel Configuration
> +#
> +# CONFIG_PPC64 is not set

This is a full defconfig.  We don't need a full config file.  You can
generate one with 'make savedefconfig' that contains only the options
you need to set.




> diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_=
16550.c
> index 6837f83..dd3bce9 100644
> --- a/arch/powerpc/kernel/udbg_16550.c
> +++ b/arch/powerpc/kernel/udbg_16550.c
> @@ -18,6 +18,19 @@ extern void real_writeb(u8 data, volatile u8 __iomem *=
addr);
> =A0extern u8 real_205_readb(volatile u8 __iomem =A0*addr);
> =A0extern void real_205_writeb(u8 data, volatile u8 __iomem *addr);
>
> +#ifdef CONFIG_UART_16550_WORD_ADDRESSABLE
> +struct NS16550 {
> + =A0 =A0 =A0 /* this struct must be packed */
> + =A0 =A0 =A0 unsigned char rbr; =A0/* 0 */ u8 s0[3];

An array of length 3 for something "word-addressable"?  When did words
change to 3 bytes?  Now, I still haven't finished my coffee yet, but
that is really confusing.

> + =A0 =A0 =A0 unsigned char ier; =A0/* 1 */ u8 s1[3];
> + =A0 =A0 =A0 unsigned char fcr; =A0/* 2 */ u8 s2[3];
> + =A0 =A0 =A0 unsigned char lcr; =A0/* 3 */ u8 s3[3];
> + =A0 =A0 =A0 unsigned char mcr; =A0/* 4 */ u8 s4[3];
> + =A0 =A0 =A0 unsigned char lsr; =A0/* 5 */ u8 s5[3];
> + =A0 =A0 =A0 unsigned char msr; =A0/* 6 */ u8 s6[3];
> + =A0 =A0 =A0 unsigned char scr; =A0/* 7 */ u8 s7[3];
> +};
> +#else
> =A0struct NS16550 {
> =A0 =A0 =A0 =A0/* this struct must be packed */
> =A0 =A0 =A0 =A0unsigned char rbr; =A0/* 0 */
> @@ -29,6 +42,7 @@ struct NS16550 {
> =A0 =A0 =A0 =A0unsigned char msr; =A0/* 6 */
> =A0 =A0 =A0 =A0unsigned char scr; =A0/* 7 */
> =A0};
> +#endif /* CONFIG_UART_16550_WORD_ADDRESSABLE */
>
> =A0#define thr rbr
> =A0#define iir fcr
> @@ -52,8 +66,16 @@ static struct NS16550 __iomem *udbg_comport;
> =A0static void udbg_550_flush(void)
> =A0{
> =A0 =A0 =A0 =A0if (udbg_comport) {
> +#if defined(CONFIG_APM8018X)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 int index;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 for (index =3D 0; index < 3500; index++) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((in_8(&udbg_comport->ls=
r) & LSR_THRE) =3D=3D LSR_THRE)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> +#else

What is index, and why do you read the same register 3500 times?  That
doesn't sound like an index, it sounds like some kind of poor-mans
timeout.

> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0while ((in_8(&udbg_comport->lsr) & LSR_THR=
E) =3D=3D 0)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* wait for idle */;
> +#endif /* CONFIG_APM8018X */
> =A0 =A0 =A0 =A0}
> =A0}
>
> diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/=
40x/Kconfig
> index 1530229..3d0d1d9 100644
> --- a/arch/powerpc/platforms/40x/Kconfig
> +++ b/arch/powerpc/platforms/40x/Kconfig
> @@ -186,3 +186,14 @@ config IBM405_ERR51
> =A0# =A0 =A0 =A0bool
> =A0# =A0 =A0 =A0depends on !STB03xxx && PPC4xx_DMA
> =A0# =A0 =A0 =A0default y
> +#
> +
> +config APM8018X
> + =A0 =A0 =A0 bool "APM8018X"
> + =A0 =A0 =A0 depends on 40x
> + =A0 =A0 =A0 default y

default n please.

> + =A0 =A0 =A0 select PPC40x_SIMPLE
> + =A0 =A0 =A0 select UART_16550_WORD_ADDRESSABLE
> + =A0 =A0 =A0 help
> + =A0 =A0 =A0 =A0 This option enables support for the AppliedMicro Klondi=
ke board.
> +
> diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/pl=
atforms/40x/ppc40x_simple.c
> index e8dd5c5..c8576af 100644
> --- a/arch/powerpc/platforms/40x/ppc40x_simple.c
> +++ b/arch/powerpc/platforms/40x/ppc40x_simple.c
> @@ -17,7 +17,7 @@
> =A0#include <asm/pci-bridge.h>
> =A0#include <asm/ppc4xx.h>
> =A0#include <asm/prom.h>
> -#include <asm/time.h>
> +#include <linux/time.h>

Is this needed for a reason?  If so, it should be submitted as a separate p=
atch.

> =A0#include <asm/udbg.h>
> =A0#include <asm/uic.h>
>
> @@ -29,6 +29,7 @@ static __initdata struct of_device_id ppc40x_of_bus[] =
=3D {
> =A0 =A0 =A0 =A0{ .compatible =3D "ibm,plb4", },
> =A0 =A0 =A0 =A0{ .compatible =3D "ibm,opb", },
> =A0 =A0 =A0 =A0{ .compatible =3D "ibm,ebc", },
> + =A0 =A0 =A0 { .compatible =3D "ibm,ahb", },
> =A0 =A0 =A0 =A0{ .compatible =3D "simple-bus", },
> =A0 =A0 =A0 =A0{},
> =A0};
> @@ -55,6 +56,7 @@ static const char *board[] __initdata =3D {
> =A0 =A0 =A0 =A0"amcc,haleakala",
> =A0 =A0 =A0 =A0"amcc,kilauea",
> =A0 =A0 =A0 =A0"amcc,makalu",
> + =A0 =A0 =A0 "amcc,klondike",
> =A0 =A0 =A0 =A0"est,hotfoot"
> =A0};
>
> --
> 1.6.1.rc3
>
>

^ permalink raw reply

* Re: [PATCH v3 2/3] hvc_init(): Enforce one-time initialization.
From: Amit Shah @ 2011-11-23 13:15 UTC (permalink / raw)
  To: Sasha Levin
  Cc: Stephen Rothwell, xen-devel, Konrad Rzeszutek Wilk, Rusty Russell,
	Miche Baker-Harvey, linux-kernel, virtualization, Anton Blanchard,
	Mike Waychison, ppc-dev, Greg Kroah-Hartman, Eric Northrup
In-Reply-To: <1322053564.3581.19.camel@lappy>

On (Wed) 23 Nov 2011 [15:06:04], Sasha Levin wrote:
> On Wed, 2011-11-23 at 18:26 +0530, Amit Shah wrote:
> > On (Wed) 23 Nov 2011 [16:08:52], Amit Shah wrote:
> > > With this setup, with and without patches, I can spawn two consoles
> > > via:
> > > 
> > > /sbin/agetty /dev/hvc0 9600 vt100
> > > /sbin/agetty /dev/hvc1 9600 vt100
> > > 
> > > (Strange thing is, the second one gives a 'password incorrect' error
> > > on login attempts, while the first one logs in fine.  I do remember
> > > testing multiple consoles just fine a year and a half back, so no idea
> > > why this isn't behaving as expected -- but it mostly looks like a
> > > userspace issue rather than kernel one.)
> > 
> > Right -- when I test this on the Fedora 11 VM I used back then, the
> > two consoles work just fine without these patches.  When I use
> > something newer (F14), I get the weird password rejection, with and
> > without your patches.
> 
> It's not a weird password rejection, it's probably not set as a secure
> terminal :)
> 
> Try adding hvc1 to /etc/securetty on the guest.

Ah, of course :-)

		Amit

^ permalink raw reply

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

On Wed, 2011-11-23 at 18:26 +0530, Amit Shah wrote:
> On (Wed) 23 Nov 2011 [16:08:52], Amit Shah wrote:
> > With this setup, with and without patches, I can spawn two consoles
> > via:
> > 
> > /sbin/agetty /dev/hvc0 9600 vt100
> > /sbin/agetty /dev/hvc1 9600 vt100
> > 
> > (Strange thing is, the second one gives a 'password incorrect' error
> > on login attempts, while the first one logs in fine.  I do remember
> > testing multiple consoles just fine a year and a half back, so no idea
> > why this isn't behaving as expected -- but it mostly looks like a
> > userspace issue rather than kernel one.)
> 
> Right -- when I test this on the Fedora 11 VM I used back then, the
> two consoles work just fine without these patches.  When I use
> something newer (F14), I get the weird password rejection, with and
> without your patches.

It's not a weird password rejection, it's probably not set as a secure
terminal :)

Try adding hvc1 to /etc/securetty on the guest.

-- 

Sasha.

^ permalink raw reply

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

On (Wed) 23 Nov 2011 [16:08:52], Amit Shah wrote:
> With this setup, with and without patches, I can spawn two consoles
> via:
> 
> /sbin/agetty /dev/hvc0 9600 vt100
> /sbin/agetty /dev/hvc1 9600 vt100
> 
> (Strange thing is, the second one gives a 'password incorrect' error
> on login attempts, while the first one logs in fine.  I do remember
> testing multiple consoles just fine a year and a half back, so no idea
> why this isn't behaving as expected -- but it mostly looks like a
> userspace issue rather than kernel one.)

Right -- when I test this on the Fedora 11 VM I used back then, the
two consoles work just fine without these patches.  When I use
something newer (F14), I get the weird password rejection, with and
without your patches.

		Amit

^ permalink raw reply

* Re: [PATCH v3 3/3] mtd/nand : workaround for Freescale FCM to support large-page Nand chip
From: LiuShuo @ 2011-11-23 12:14 UTC (permalink / raw)
  To: Scott Wood
  Cc: Artem.Bityutskiy, linuxppc-dev, linux-kernel, Liu Shuo,
	Shengzhou Liu, linux-mtd, akpm, dwmw2
In-Reply-To: <4ECC368C.3010801@freescale.com>

=E4=BA=8E 2011=E5=B9=B411=E6=9C=8823=E6=97=A5 07:55, Scott Wood =E5=86=99=
=E9=81=93:
> On 11/15/2011 03:29 AM, b35362@freescale.com wrote:
>> From: Liu Shuo<b35362@freescale.com>
>>
>> Freescale FCM controller has a 2K size limitation of buffer RAM. In or=
der
>> to support the Nand flash chip whose page size is larger than 2K bytes=
,
>> we read/write 2k data repeatedly by issuing FIR_OP_RB/FIR_OP_WB and sa=
ve
>> them to a large buffer.
>>
>> Signed-off-by: Liu Shuo<Shuo.Liu@freescale.com>
>> Signed-off-by: Shengzhou Liu<Shengzhou.Liu@freescale.com>
>> Signed-off-by: Li Yang<leoli@freescale.com>
>> ---
>>   drivers/mtd/nand/fsl_elbc_nand.c |  216 ++++++++++++++++++++++++++++=
+++++++---
>>   1 files changed, 199 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_e=
lbc_nand.c
>> index c2c231b..415f87e 100644
>> --- a/drivers/mtd/nand/fsl_elbc_nand.c
>> +++ b/drivers/mtd/nand/fsl_elbc_nand.c
>> @@ -55,7 +55,9 @@ struct fsl_elbc_mtd {
>>   	struct device *dev;
>>   	int bank;               /* Chip select bank number           */
>>   	u8 __iomem *vbase;      /* Chip select base virtual address  */
>> -	int page_size;          /* NAND page size (0=3D512, 1=3D2048)    */
>> +	int page_size;          /* NAND page size (0=3D512, 1=3D2048, 2=3D40=
96...),
>> +				 * the mutiple of 2048.
>> +				 */
> That "..." isn't very descriptive.  What happens with 8192-byte pages?
> Is it 3 or 4?
>
> Please just get rid of this and use mtd->writesize.
>
>> +		for (i =3D 1; i<  priv->page_size; i++) {
>> +			/*
>> +			 * Maybe there are some reasons of FCM hardware timming,
>> +			 * we must insert a FIR_OP_NOP(0x00) before FIR_OP_RB.
>> +			 */
> s/timming/timing/
>
>>   	/* PAGEPROG reuses all of the setup from SEQIN and adds the length =
*/
>>   	case NAND_CMD_PAGEPROG: {
>> +		int len;
>>   		dev_vdbg(priv->dev,
>>   			 "fsl_elbc_cmdfunc: NAND_CMD_PAGEPROG "
>>   			 "writing %d bytes.\n", elbc_fcm_ctrl->index);
>> -
>>   		/* if the write did not start at 0 or is not a full page
>>   		 * then set the exact length, otherwise use a full page
>>   		 * write so the HW generates the ECC.
>>   		 */
>> -		if (elbc_fcm_ctrl->oob || elbc_fcm_ctrl->column !=3D 0 ||
>> +		if (elbc_fcm_ctrl->column>=3D mtd->writesize) {
>> +			/* write oob */
>> +			if (priv->page_size>  1) {
>> +				/* when pagesize of chip is greater than 2048,
>> +				 * we have to write full page to write spare
>> +				 * region, so we fill '0xff' to main region
>> +				 * and some bytes of spare region which we
>> +				 * don't want to rewrite.
>> +				 * (write '1' won't change the original value)
>> +				 */
>> +				memset(elbc_fcm_ctrl->buffer, 0xff,
>> +						elbc_fcm_ctrl->column);
> I don't like relying on this -- can we use RNDIN instead to do a
> discontiguous write?
>
I have no better way to implement it now.
Some chips have 'NOP' limitation, so I don't use the FIR_OP_UA to do a=20
oob write.
>> +				len =3D 2112;
> len =3D min(elbc_fcm_ctrl->index, 2112);
when do a oob write (writesize > 2048), elbc_fcm_ctrl->index is greater=20
writesize
(is 4096 at least).
>> +			} else
>> +				len =3D mtd->writesize + mtd->oobsize -
>> +					elbc_fcm_ctrl->column;
>> +			out_be32(&lbc->fbcr, len);
> len =3D elbc_fcm_ctrl->index - elbc_fcm_ctrl->column;
>
> Use braces on both sides of the if/else if it's needed on one side.
>> +		} else if (elbc_fcm_ctrl->column !=3D 0 ||
>>   		    elbc_fcm_ctrl->index !=3D mtd->writesize + mtd->oobsize)
>>   			out_be32(&lbc->fbcr, elbc_fcm_ctrl->index);
> This should have set fbcr to index - column as well (after adjusting --
> though really it's not a supported use case.  We should only be seeing
> column !=3D 0 for oob.
>
I have make a independent to fix this issue.
(In fact,documentation says FCM will stop automatically after
reading the last byte of spare region)
>> @@ -625,10 +776,16 @@ static int fsl_elbc_verify_buf(struct mtd_info *=
mtd, const u_char *buf, int len)
>>   		return -EINVAL;
>>   	}
>>
>> -	for (i =3D 0; i<  len; i++)
>> -		if (in_8(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index + i])
>> -				!=3D buf[i])
>> -			break;
>> +	if (mtd->writesize>  2048)
>> +		for (i =3D 0; i<  len; i++)
>> +			if (elbc_fcm_ctrl->buffer[elbc_fcm_ctrl->index + i]
>> +					!=3D buf[i])
>> +				break;
>> +	else
>> +		for (i =3D 0; i<  len; i++)
>> +			if (in_8(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index + i])
>> +					!=3D buf[i])
>> +				break;
> Please use braces around multiline if/for bodies, even if they're
> technically a single statement -- especially when you've got a dangling
> else.
>
>>   	elbc_fcm_ctrl->index +=3D len;
>>   	return i =3D=3D len&&  elbc_fcm_ctrl->status =3D=3D LTESR_CC ? 0 : =
-EIO;
>> @@ -657,6 +814,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info=
 *mtd)
>>   	struct fsl_elbc_mtd *priv =3D chip->priv;
>>   	struct fsl_lbc_ctrl *ctrl =3D priv->ctrl;
>>   	struct fsl_lbc_regs __iomem *lbc =3D ctrl->regs;
>> +	struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl =3D ctrl->nand;
>>   	unsigned int al;
>>
>>   	/* calculate FMR Address Length field */
>> @@ -707,12 +865,17 @@ static int fsl_elbc_chip_init_tail(struct mtd_in=
fo *mtd)
>>   	dev_dbg(priv->dev, "fsl_elbc_init: mtd->oobsize =3D %d\n",
>>   		mtd->oobsize);
>>
>> +	kfree(elbc_fcm_ctrl->buffer);
>> +	elbc_fcm_ctrl->buffer =3D NULL;
>> +
>>   	/* adjust Option Register and ECC to match Flash page size */
>>   	if (mtd->writesize =3D=3D 512) {
>>   		priv->page_size =3D 0;
>>   		clrbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS);
>> -	} else if (mtd->writesize =3D=3D 2048) {
>> -		priv->page_size =3D 1;
>> +	} else if (mtd->writesize>=3D 2048) {
>> +		/* page_size =3D writesize / 2048 */
>> +		priv->page_size =3D mtd->writesize>>  11;
> Why not just write priv->page_size =3D mtd->writesize / 2048 in the cod=
e
> rather than the comment (it compiles to the same code)?  Other than
> because you were requested to remove priv->page_size, that is. :-)
>
>>   		setbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS);
>>   		/* adjust ecc setup if needed */
>>   		if ((in_be32(&lbc->bank[priv->bank].br)&  BR_DECC) =3D=3D
>> @@ -723,6 +886,14 @@ static int fsl_elbc_chip_init_tail(struct mtd_inf=
o *mtd)
>>   					&fsl_elbc_oob_lp_eccm0;
>>   			chip->badblock_pattern =3D&largepage_memorybased;
>>   		}
>> +
>> +		/* re-malloc if pagesize>  2048*/
>> +		if (mtd->writesize>  2048) {
>> +			elbc_fcm_ctrl->buffer =3D kmalloc(mtd->writesize +
>> +						    mtd->oobsize, GFP_KERNEL);
>> +			if (!elbc_fcm_ctrl->buffer)
>> +				return -ENOMEM;
>> +		}
>>   	} else {
>>   		dev_err(priv->dev,
>>   			"fsl_elbc_init: page size %d is not supported\n",
> buffer is a controller-wide resource, but you're setting it based on th=
e
> most-recently-probed NAND chip.  It should be large enough to
> accommodate the largest page size in use on any connected chip.  Even i=
f
> all chips in the system have the same page size, you're introducing a
> race if a previously-probed chip is already in use (the controller lock
> is not held here).
>
> Just allocate a buffer large enough for a 16K page size in the main ini=
t
> function, and print an error in the tail if you encounter a larger page
> size.
>
>> @@ -886,6 +1057,17 @@ static int __devinit fsl_elbc_nand_probe(struct =
platform_device *pdev)
>>   			goto err;
>>   		}
>>   		elbc_fcm_ctrl->counter++;
>> +		/*
>> +		 * Freescale FCM controller has a 2K size limitation of buffer
>> +		 * RAM, so elbc_fcm_ctrl->buffer have to be used if writesize
>> +		 * of chip is greater than 2048.
>> +		 * We malloc a large enough buffer at this point, because we
>> +		 * don't know writesize before calling nand_scan(). We will
>> +		 * re-malloc later if needed.
>> +		 */
>> +		elbc_fcm_ctrl->buffer =3D kmalloc(4096 * 6, GFP_KERNEL);
>> +		if (!elbc_fcm_ctrl->buffer)
>> +			return -ENOMEM;
> Clean up properly if you fail to allocate the buffer.  This includes
> freeing elbc_fcm_ctrl, setting fsl_lbc_ctrl_dev->nand to NULL, and
> releasing fsl_elbc_nand_mutex.
> -Scott
- LiuShuo

^ permalink raw reply

* [PATCH v2] usb/fsl_udc: fix dequeuing a request in progress
From: Li Yang @ 2011-11-23 12:12 UTC (permalink / raw)
  To: balbi, gregkh; +Cc: linux-usb, linuxppc-dev, Peter Chen

The original implementation of dequeuing a request in progress
is not correct.  Change to use a correct process and also clean
up the related functions a little bit.

Signed-off-by: Li Yang <leoli@freescale.com>
Cc: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/gadget/fsl_udc_core.c |   68 +++++++++++++++++-------------------
 drivers/usb/gadget/fsl_usb2_udc.h |   10 +++++
 2 files changed, 42 insertions(+), 36 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index b2c44e1..cc704dc 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -696,12 +696,31 @@ static void fsl_free_request(struct usb_ep *_ep, struct usb_request *_req)
 		kfree(req);
 }
 
-/*-------------------------------------------------------------------------*/
+/* Actually add a dTD chain to an empty dQH and let go */
+static void fsl_prime_ep(struct fsl_ep *ep, struct ep_td_struct *td)
+{
+	struct ep_queue_head *qh = get_qh_by_ep(ep);
+
+	/* Write dQH next pointer and terminate bit to 0 */
+	qh->next_dtd_ptr = cpu_to_hc32(td->td_dma
+			& EP_QUEUE_HEAD_NEXT_POINTER_MASK);
+
+	/* Clear active and halt bit */
+	qh->size_ioc_int_sts &= cpu_to_hc32(~(EP_QUEUE_HEAD_STATUS_ACTIVE
+					| EP_QUEUE_HEAD_STATUS_HALT));
+
+	/* Ensure that updates to the QH will occur before priming. */
+	wmb();
+
+	/* Prime endpoint by writing correct bit to ENDPTPRIME */
+	fsl_writel(ep_is_in(ep) ? (1 << (ep_index(ep) + 16))
+			: (1 << (ep_index(ep))), &dr_regs->endpointprime);
+}
+
+/* Add dTD chain to the dQH of an EP */
 static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
 {
-	int i = ep_index(ep) * 2 + ep_is_in(ep);
 	u32 temp, bitmask, tmp_stat;
-	struct ep_queue_head *dQH = &ep->udc->ep_qh[i];
 
 	/* VDBG("QH addr Register 0x%8x", dr_regs->endpointlistaddr);
 	VDBG("ep_qh[%d] addr is 0x%8x", i, (u32)&(ep->udc->ep_qh[i])); */
@@ -719,7 +738,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
 			cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK);
 		/* Read prime bit, if 1 goto done */
 		if (fsl_readl(&dr_regs->endpointprime) & bitmask)
-			goto out;
+			return;
 
 		do {
 			/* Set ATDTW bit in USBCMD */
@@ -736,28 +755,10 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
 		fsl_writel(temp & ~USB_CMD_ATDTW, &dr_regs->usbcmd);
 
 		if (tmp_stat)
-			goto out;
+			return;
 	}
 
-	/* Write dQH next pointer and terminate bit to 0 */
-	temp = req->head->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK;
-	dQH->next_dtd_ptr = cpu_to_hc32(temp);
-
-	/* Clear active and halt bit */
-	temp = cpu_to_hc32(~(EP_QUEUE_HEAD_STATUS_ACTIVE
-			| EP_QUEUE_HEAD_STATUS_HALT));
-	dQH->size_ioc_int_sts &= temp;
-
-	/* Ensure that updates to the QH will occur before priming. */
-	wmb();
-
-	/* Prime endpoint by writing 1 to ENDPTPRIME */
-	temp = ep_is_in(ep)
-		? (1 << (ep_index(ep) + 16))
-		: (1 << (ep_index(ep)));
-	fsl_writel(temp, &dr_regs->endpointprime);
-out:
-	return;
+	fsl_prime_ep(ep, req->head);
 }
 
 /* Fill in the dTD structure
@@ -973,25 +974,20 @@ static int fsl_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
 
 		/* The request isn't the last request in this ep queue */
 		if (req->queue.next != &ep->queue) {
-			struct ep_queue_head *qh;
 			struct fsl_req *next_req;
 
-			qh = ep->qh;
 			next_req = list_entry(req->queue.next, struct fsl_req,
 					queue);
 
-			/* Point the QH to the first TD of next request */
-			fsl_writel((u32) next_req->head, &qh->curr_dtd_ptr);
+			/* prime with dTD of next request */
+			fsl_prime_ep(ep, next_req->head);
 		}
-
-		/* The request hasn't been processed, patch up the TD chain */
+	/* The request hasn't been processed, patch up the TD chain */
 	} else {
 		struct fsl_req *prev_req;
 
 		prev_req = list_entry(req->queue.prev, struct fsl_req, queue);
-		fsl_writel(fsl_readl(&req->tail->next_td_ptr),
-				&prev_req->tail->next_td_ptr);
-
+		prev_req->tail->next_td_ptr = req->tail->next_td_ptr;
 	}
 
 	done(ep, req, -ECONNRESET);
@@ -1068,7 +1064,7 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep)
 	struct fsl_udc *udc;
 	int size = 0;
 	u32 bitmask;
-	struct ep_queue_head *d_qh;
+	struct ep_queue_head *qh;
 
 	ep = container_of(_ep, struct fsl_ep, ep);
 	if (!_ep || (!ep->desc && ep_index(ep) != 0))
@@ -1079,13 +1075,13 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep)
 	if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)
 		return -ESHUTDOWN;
 
-	d_qh = &ep->udc->ep_qh[ep_index(ep) * 2 + ep_is_in(ep)];
+	qh = get_qh_by_ep(ep);
 
 	bitmask = (ep_is_in(ep)) ? (1 << (ep_index(ep) + 16)) :
 	    (1 << (ep_index(ep)));
 
 	if (fsl_readl(&dr_regs->endptstatus) & bitmask)
-		size = (d_qh->size_ioc_int_sts & DTD_PACKET_SIZE)
+		size = (qh->size_ioc_int_sts & DTD_PACKET_SIZE)
 		    >> DTD_LENGTH_BIT_POS;
 
 	pr_debug("%s %u\n", __func__, size);
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h
index 1d51be8..f781f5d 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.h
+++ b/drivers/usb/gadget/fsl_usb2_udc.h
@@ -569,6 +569,16 @@ static void dump_msg(const char *label, const u8 * buf, unsigned int length)
 					* 2 + ((windex & USB_DIR_IN) ? 1 : 0))
 #define get_pipe_by_ep(EP)	(ep_index(EP) * 2 + ep_is_in(EP))
 
+static inline struct ep_queue_head *get_qh_by_ep(struct fsl_ep *ep)
+{
+	/* we only have one ep0 structure but two queue heads */
+	if (ep_index(ep) != 0)
+		return ep->qh;
+	else
+		return &ep->udc->ep_qh[(ep->udc->ep0_dir ==
+				USB_DIR_IN) ? 1 : 0];
+}
+
 struct platform_device;
 #ifdef CONFIG_ARCH_MXC
 int fsl_udc_clk_init(struct platform_device *pdev);
-- 
1.5.4.3

^ permalink raw reply related

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

On (Thu) 17 Nov 2011 [10:57:37], Miche Baker-Harvey wrote:
> Rusty, Michael, Stephen, et al,
> 
> Thanks for your comments on these patches.
> 
> For what I'm trying to do, all three patches are necessary, but maybe
> I'm going about it the wrong way. Your input would be appreciated.
> I'm in no way claiming that these patches are "right", just that it's
> working for me, and that what's in the current pool is not.
> 
> What I'm trying to do is:
> On X86,
> under KVM,
> start a virtio console device,
> with multiple ports on the device,
> at least one of which is also a console (as well as ttyS0).
> 
> (Eventually, we want to be able to add virtio console ports on the
> fly, and to have multiple virtio console ports be consoles.)

Are you using kvm-tool to do this?  QEMU can already hot-plug ports
and virtio-console (virtio-serial) devices.

> When all three of the patches are in place, this works great. (By
> great, I mean that getty's start up on all of ttyS0, hvc0 and hvc1,
> and console output goes to ttyS0 and to hvc0.
> "who" shows three users:  ttyS0, hvc0, and hvc1.
> "cat /proc/consoles" shows both ttyS0 and hvc0.
> I can use all three getty's, and console output really does appear on
> both the consoles.
> 
> Based on Rusty's comments, I tried removing each of the patches
> individually. Here's what happens today. I've seen other failure modes
> depending on what precisely I'm passing the guest.
> There's three patches:
> 1/3 "fix locking of vtermno"
> 2/3 "enforce one-time initialization with hvc_init
> "3/3 "use separate struct console * for each console"
> 
> If I remove the "fix locking of vtermno", I only get one virtio
> console terminal.  "who" shows the ttyS0 and the hvc0, and I can log
> into the gettys on both. I don't get the second virtio console getty.
> Interestingly, hvc0 shows up in /proc/consoles twice, and in fact the
> console output is dumped twice to hvc0 (as you'd expect from looking
> at printk.c, each line appears twice, followed by the next line.)

I don't really understand why.  "fix locking of vtermno" adds locks in
init_port_console(), which is called from add_port(), which should be
serialised due to port additions being on work items on the same
workqueue.  I don't see a race here.

> If I remove the "enforce one-time initialization with hvc_init" patch,
> which makes sure only a single thread is doing the hvc_init, and gates
> anyone from continuing until it has completed, I get different
> failures, including hangs, and dereferences of NULL pointers.
> 
> If I remove the "use separate struct console * for each console"patch,
> what I'm seeing now is that while all of ttyS0, hvc0, and hvc1 are
> present with gettys running on them, of the three, only ttyS0 is a
> console.

I don't see any difference in my testing with and without these
patches.

This is how I tested with qemu:

./x86_64-softmmu/qemu-system-x86_64 -m 512 -smp 2 -chardev
socket,path=/tmp/foo,server,nowait,id=foo -chardev
socket,path=/tmp/bar,server,nowait,id=bar -device virtio-serial
-device virtconsole,chardev=foo,nr=4 -device
virtconsole,chardev=bar,nr=3 -net none  -kernel
/home/amit/src/linux/arch/x86/boot/bzImage -append 'root=/dev/sda1
console=tty0 console=ttyS0' -initrd /tmp/initramfs.img
/guests/f14-nolvm.qcow2 -enable-kvm -snapshot

With this setup, with and without patches, I can spawn two consoles
via:

/sbin/agetty /dev/hvc0 9600 vt100
/sbin/agetty /dev/hvc1 9600 vt100

(Strange thing is, the second one gives a 'password incorrect' error
on login attempts, while the first one logs in fine.  I do remember
testing multiple consoles just fine a year and a half back, so no idea
why this isn't behaving as expected -- but it mostly looks like a
userspace issue rather than kernel one.)

As mentioned earlier, I've not looked at the hvc code, but given my
testing results, I'd like to first understand what you're seeing and
what your environment is.

		Amit

^ permalink raw reply


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