LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* RE: How to trun off udbg0 during bootup?
From: SHAN Gavin @ 2010-01-21  3:56 UTC (permalink / raw)
  To: ???, linuxppc-dev
In-Reply-To: <b90a809a1001201702y7d42eb60v43f24cb1043a89fa@mail.gmail.com>

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


 
Hi,

 I `m working on a freescale-MPC8379eRDB like board.And I want to trun off
kernel message during bootup.

 I tried to  modify "console = XXX" argument in uboot but it did not work(It
works on ARM). Kernel always print:

"console [udbg0] enabled"    or   "console handover: boot [*udbg0*] -> real
[ttyS1]"

Does anybody know how can I turn off this udbg0?

You may check arch/powerpc/kernel/udbg.c and disable registering the early
debug console driver. Then you can not see the output before the message
line like "-> real [ttyS1]"

Good luck,
Gavin


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

^ permalink raw reply

* Re: [RFC:PATCH 01/03] powerpc: Extended ptrace interface
From: Michael Neuling @ 2010-01-21  2:47 UTC (permalink / raw)
  To: Dave Kleikamp
  Cc: linuxppc-dev list, Sergio Durigan Junior, Torez Smith,
	Thiago Jung Bauermann, David Gibson
In-Reply-To: <20100118215709.15684.28776.sendpatchset@norville.austin.ibm.com>

> powerpc: Extended ptrace interface
> 
> From: Torez Smith <lnxtorez@linux.vnet.ibm.com>
> 
> Add a new extended ptrace interface so that user-space has a single
> interface for powerpc, without having to know the specific layout
> of the debug registers.
> 
> Implement:
> PPC_PTRACE_GETHWDEBUGINFO
> PPC_PTRACE_SETHWDEBUG
> PPC_PTRACE_DELHWDEBUG
> 
> Signed-off-by: Torez Smith  <lnxtorez@linux.vnet.ibm.com>
> Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
> Acked-by: David Gibson <dwg@au1.ibm.com>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Josh Boyer <jwboyer@linux.vnet.ibm.com>
> Cc: Kumar Gala <galak@kernel.crashing.org>
> Cc: Sergio Durigan Junior <sergiodj@br.ibm.com>
> Cc: Thiago Jung Bauermann <bauerman@br.ibm.com>
> Cc: linuxppc-dev list <Linuxppc-dev@ozlabs.org>
> ---
> 
>  Documentation/powerpc/ptrace.txt  |  134 +++++++++++++++++++++++++++++++++++
++
>  arch/powerpc/include/asm/ptrace.h |   77 +++++++++++++++++++++
>  arch/powerpc/kernel/ptrace.c      |   90 +++++++++++++++++++++++++
>  3 files changed, 301 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/powerpc/ptrace.txt
> 
> 
> diff --git a/Documentation/powerpc/ptrace.txt b/Documentation/powerpc/ptrace.
txt
> new file mode 100644
> index 0000000..f4a5499
> --- /dev/null
> +++ b/Documentation/powerpc/ptrace.txt
> @@ -0,0 +1,134 @@
> +GDB intends to support the following hardware debug features of BookE
> +processors:
> +
> +4 hardware breakpoints (IAC)
> +2 hardware watchpoints (read, write and read-write) (DAC)
> +2 value conditions for the hardware watchpoints (DVC)
> +
> +For that, we need to extend ptrace so that GDB can query and set these
> +resources. Since we're extending, we're trying to create an interface
> +that's extendable and that covers both BookE and server processors, so
> +that GDB doesn't need to special-case each of them. We added the
> +following 3 new ptrace requests.
> +
> +1. PTRACE_PPC_GETHWDEBUGINFO
> +
> +Query for GDB to discover the hardware debug features. The main info to
> +be returned here is the minimum alignment for the hardware watchpoints.
> +BookE processors don't have restrictions here, but server processors have
> +an 8-byte alignment restriction for hardware watchpoints. We'd like to avoid
> +adding special cases to GDB based on what it sees in AUXV.
> +
> +Since we're at it, we added other useful info that the kernel can return to
> +GDB: this query will return the number of hardware breakpoints, hardware
> +watchpoints and whether it supports a range of addresses and a condition.
> +The query will fill the following structure provided by the requesting proce
ss:
> +
> +struct ppc_debug_info {
> +       unit32_t version;
> +       unit32_t num_instruction_bps;
> +       unit32_t num_data_bps;
> +       unit32_t num_condition_regs;
> +       unit32_t data_bp_alignment;
> +       unit32_t sizeof_condition; /* size of the DVC register */
> +       uint64_t features; /* bitmask of the individual flags */
> +};
> +
> +features will have bits indicating whether there is support for:
> +
> +#define PPC_DEBUG_FEATURE_INSN_BP_RANGE		0x1
> +#define PPC_DEBUG_FEATURE_INSN_BP_MASK		0x2
> +#define PPC_DEBUG_FEATURE_DATA_BP_RANGE		0x4
> +#define PPC_DEBUG_FEATURE_DATA_BP_MASK		0x8
> +
> +2. PTRACE_SETHWDEBUG
> +
> +Sets a hardware breakpoint or watchpoint, according to the provided structur
e:
> +
> +struct ppc_hw_breakpoint {
> +        uint32_t version;
> +#define PPC_BREAKPOINT_TRIGGER_EXECUTE  0x1
> +#define PPC_BREAKPOINT_TRIGGER_READ     0x2
> +#define PPC_BREAKPOINT_TRIGGER_WRITE    0x4
> +        uint32_t trigger_type;       /* only some combinations allowed */
> +#define PPC_BREAKPOINT_MODE_EXACT               0x0
> +#define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE     0x1
> +#define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE     0x2
> +#define PPC_BREAKPOINT_MODE_MASK                0x3
> +        uint32_t addr_mode;          /* address match mode */
> +
> +#define PPC_BREAKPOINT_CONDITION_MODE   0x3
> +#define PPC_BREAKPOINT_CONDITION_NONE   0x0
> +#define PPC_BREAKPOINT_CONDITION_AND    0x1
> +#define PPC_BREAKPOINT_CONDITION_EXACT  0x1	/* different name for the same 
thing as above */
> +#define PPC_BREAKPOINT_CONDITION_OR     0x2
> +#define PPC_BREAKPOINT_CONDITION_AND_OR 0x3
> +#define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000	/* byte enable bits */
> +#define PPC_BREAKPOINT_CONDITION_BE(n)  (1<<((n)+16))
> +        uint32_t condition_mode;     /* break/watchpoint condition flags */
> +
> +        uint64_t addr;
> +        uint64_t addr2;
> +        uint64_t condition_value;
> +};
> +
> +A request specifies one event, not necessarily just one register to be set.
> +For instance, if the request is for a watchpoint with a condition, both the
> +DAC and DVC registers will be set in the same request.
> +
> +With this GDB can ask for all kinds of hardware breakpoints and watchpoints
> +that the BookE supports. COMEFROM breakpoints available in server processors
> +are not contemplated, but that is out of the scope of this work.
> +
> +ptrace will return an integer (handle) uniquely identifying the breakpoint o
r
> +watchpoint just created. This integer will be used in the PTRACE_DELHWDEBUG
> +request to ask for its removal. Return -ENOSPC if the requested breakpoint
> +can't be allocated on the registers.
> +
> +Some examples of using the structure to:
> +
> +- set a breakpoint in the first breakpoint register
> +
> +  p.version         = PPC_DEBUG_CURRENT_VERSION;
> +  p.trigger_type    = PPC_BREAKPOINT_TRIGGER_EXECUTE;
> +  p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
> +  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
> +  p.addr            = (uint64_t) address;
> +  p.addr2           = 0;
> +  p.condition_value = 0;
> +
> +- set a watchpoint which triggers on reads in the second watchpoint register
> +
> +  p.version         = PPC_DEBUG_CURRENT_VERSION;
> +  p.trigger_type    = PPC_BREAKPOINT_TRIGGER_READ;
> +  p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
> +  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
> +  p.addr            = (uint64_t) address;
> +  p.addr2           = 0;
> +  p.condition_value = 0;
> +
> +- set a watchpoint which triggers only with a specific value
> +
> +  p.version         = PPC_DEBUG_CURRENT_VERSION;
> +  p.trigger_type    = PPC_BREAKPOINT_TRIGGER_READ;
> +  p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
> +  p.condition_mode  = PPC_BREAKPOINT_CONDITION_AND | PPC_BREAKPOINT_CONDITIO
N_BE_ALL;
> +  p.addr            = (uint64_t) address;
> +  p.addr2           = 0;
> +  p.condition_value = (uint64_t) condition;
> +
> +- set a ranged hardware breakpoint
> +
> +  p.version         = PPC_DEBUG_CURRENT_VERSION;
> +  p.trigger_type    = PPC_BREAKPOINT_TRIGGER_EXECUTE;
> +  p.addr_mode       = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
> +  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
> +  p.addr            = (uint64_t) begin_range;
> +  p.addr2           = (uint64_t) end_range;
> +  p.condition_value = 0;
> +
> +3. PTRACE_DELHWDEBUG
> +
> +Takes an integer which identifies an existing breakpoint or watchpoint
> +(i.e., the value returned from PTRACE_SETHWDEBUG), and deletes the
> +corresponding breakpoint or watchpoint..
> diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptr
ace.h
> index cbd759e..b451081 100644
> --- a/arch/powerpc/include/asm/ptrace.h
> +++ b/arch/powerpc/include/asm/ptrace.h
> @@ -24,6 +24,12 @@
>   * 2 of the License, or (at your option) any later version.
>   */
>  
> +#ifdef __KERNEL__
> +#include <linux/types.h>
> +#else
> +#include <stdint.h>
> +#endif
> +
>  #ifndef __ASSEMBLY__
>  
>  struct pt_regs {
> @@ -294,4 +300,75 @@ extern void user_disable_single_step(struct task_struct 
*);
>  
>  #define PTRACE_SINGLEBLOCK	0x100	/* resume execution until next branch *
/
>  
> +#define PPC_PTRACE_GETHWDBGINFO	0x89
> +#define PPC_PTRACE_SETHWDEBUG	0x88
> +#define PPC_PTRACE_DELHWDEBUG	0x87
> +
> +#ifndef __ASSEMBLY__
> +
> +struct ppc_debug_info {
> +	uint32_t version;		/* Only version 1 exists to date */
> +	uint32_t num_instruction_bps;
> +	uint32_t num_data_bps;
> +	uint32_t num_condition_regs;
> +	uint32_t data_bp_alignment;
> +	uint32_t sizeof_condition;	/* size of the DVC register */
> +	uint64_t features;
> +};
> +
> +#endif /* __ASSEMBLY__ */
> +
> +/*
> + * features will have bits indication whether there is support for:
> + */
> +#define PPC_DEBUG_FEATURE_INSN_BP_RANGE		0x0000000000000001
> +#define PPC_DEBUG_FEATURE_INSN_BP_MASK		0x0000000000000002
> +#define PPC_DEBUG_FEATURE_DATA_BP_RANGE		0x0000000000000004
> +#define PPC_DEBUG_FEATURE_DATA_BP_MASK		0x0000000000000008
> +
> +#ifndef __ASSEMBLY__
> +
> +struct ppc_hw_breakpoint {
> +	uint32_t version;		/* currently, version must be 1 */
> +	uint32_t trigger_type;		/* only some combinations allowed */
> +	uint32_t addr_mode;		/* address match mode */
> +	uint32_t condition_mode;	/* break/watchpoint condition flags */
> +	uint64_t addr;			/* break/watchpoint address */
> +	uint64_t addr2;			/* range end or mask */
> +	uint64_t condition_value;	/* contents of the DVC register */
> +};
> +
> +#endif /* __ASSEMBLY__ */
> +
> +/*
> + * Trigger Type
> + */
> +#define PPC_BREAKPOINT_TRIGGER_EXECUTE	0x00000001
> +#define PPC_BREAKPOINT_TRIGGER_READ	0x00000002
> +#define PPC_BREAKPOINT_TRIGGER_WRITE	0x00000004
> +#define PPC_BREAKPOINT_TRIGGER_RW	\
> +	(PPC_BREAKPOINT_TRIGGER_READ | PPC_BREAKPOINT_TRIGGER_WRITE)
> +
> +/*
> + * Address Mode
> + */
> +#define PPC_BREAKPOINT_MODE_EXACT		0x00000000
> +#define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE	0x00000001
> +#define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE	0x00000002
> +#define PPC_BREAKPOINT_MODE_MASK		0x00000003
> +
> +/*
> + * Condition Mode
> + */
> +#define PPC_BREAKPOINT_CONDITION_MODE	0x00000003
> +#define PPC_BREAKPOINT_CONDITION_NONE	0x00000000
> +#define PPC_BREAKPOINT_CONDITION_AND	0x00000001
> +#define PPC_BREAKPOINT_CONDITION_EXACT	PPC_BREAKPOINT_CONDITION_AND
> +#define PPC_BREAKPOINT_CONDITION_OR	0x00000002
> +#define PPC_BREAKPOINT_CONDITION_AND_OR	0x00000003
> +#define PPC_BREAKPOINT_CONDITION_BE_ALL	0x00ff0000
> +#define PPC_BREAKPOINT_CONDITION_BE_SHIFT	16
> +#define PPC_BREAKPOINT_CONDITION_BE(n)	\
> +	(1<<((n)+PPC_BREAKPOINT_CONDITION_BE_SHIFT))
> +
>  #endif /* _ASM_POWERPC_PTRACE_H */
> diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
> index ef14988..33ab496 100644
> --- a/arch/powerpc/kernel/ptrace.c
> +++ b/arch/powerpc/kernel/ptrace.c
> @@ -839,6 +839,52 @@ void ptrace_disable(struct task_struct *child)
>  	user_disable_single_step(child);
>  }
>  
> +static long ppc_set_hwdebug(struct task_struct *child,
> +		     struct ppc_hw_breakpoint *bp_info)
> +{
> +	/*
> +	 * We currently support one data breakpoint
> +	 */
> +	if (((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0) ||
> +	    ((bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0) ||
> +	    (bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_WRITE) ||
> +	    (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) ||
> +	    (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE))
> +		return -EINVAL;
> +
> +	if (child->thread.dabr)
> +		return -ENOSPC;
> +
> +	if ((unsigned long)bp_info->addr >= TASK_SIZE)
> +		return -EIO;
> +
> +	child->thread.dabr = (unsigned long)bp_info->addr;
> +#ifdef CONFIG_BOOKE

Do we want to add these CONFIG_BOOKE into a ppc_md call, so different
CPU typs can have different setups?  I could see other CPUs might need
to do different stuff here and we end up in #ifdef chaos

> +	child->thread.dbcr0 = DBCR0_IDM;
> +	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
> +		child->thread.dbcr0 |= DBSR_DAC1R;
> +	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
> +		child->thread.dbcr0 |= DBSR_DAC1W;
> +	child->thread.regs->msr |= MSR_DE;
> +#endif
> +	return 1;
> +}
> +
> +static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
> +{

addr is not used.

> +	if (data != 1)
> +		return -EINVAL;

.. other than this test, data is not being used.

Could probably just stick this function inline in the case statement
below like the other cases.

> +	if (child->thread.dabr == 0)
> +		return -ENOENT;
> +
> +	child->thread.dabr = 0;
> +#ifdef CONFIG_BOOKE
> +	child->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W | DBCR0_IDM);
> +	child->thread.regs->msr &= ~MSR_DE;
> +#endif
> +	return 0;
> +}
> +
>  /*
>   * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls,
>   * we mark them as obsolete now, they will be removed in a future version
> @@ -932,6 +978,50 @@ long arch_ptrace(struct task_struct *child, long request
, long addr, long data)
>  		break;
>  	}
>  
> +	case PPC_PTRACE_GETHWDBGINFO: {
> +		struct ppc_debug_info dbginfo;
> +
> +		dbginfo.version = 1;
> +		dbginfo.num_instruction_bps = 0;
> +		dbginfo.num_data_bps = 1;
> +		dbginfo.num_condition_regs = 0;
> +#ifdef CONFIG_PPC64
> +		dbginfo.data_bp_alignment = 8;
> +#else
> +		dbginfo.data_bp_alignment = 4;
> +#endif
> +		dbginfo.sizeof_condition = 0;
> +		dbginfo.features = 0;
> +
> +		if (!access_ok(VERIFY_WRITE, data,
> +			       sizeof(struct ppc_debug_info)))
> +			return -EFAULT;
> +		ret = __copy_to_user((struct ppc_debug_info __user *)data,
> +				     &dbginfo, sizeof(struct ppc_debug_info)) ?
> +		      -EFAULT : 0;
> +		break;
> +	}
> +
> +	case PPC_PTRACE_SETHWDEBUG: {
> +		struct ppc_hw_breakpoint bp_info;
> +
> +		if (!access_ok(VERIFY_READ, data,
> +			       sizeof(struct ppc_hw_breakpoint)))
> +			return -EFAULT;
> +		ret = __copy_from_user(&bp_info,
> +				       (struct ppc_hw_breakpoint __user *)data,
> +				       sizeof(struct ppc_hw_breakpoint)) ?
> +		      -EFAULT : 0;
> +		if (!ret)
> +			ret = ppc_set_hwdebug(child, &bp_info);
> +		break;
> +	}
> +
> +	case PPC_PTRACE_DELHWDEBUG: {
> +		ret = ppc_del_hwdebug(child, addr, data);
> +		break;
> +	}
> +
>  	case PTRACE_GET_DEBUGREG: {
>  		ret = -EINVAL;
>  		/* We only support one DABR and no IABRS at the moment */
> 
> -- 
> Dave Kleikamp
> IBM Linux Technology Center
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
> 

^ permalink raw reply

* [net-next-2.6 PATCH 2/3] fs_enet: Add support for MPC512x to fs_enet driver
From: Anatolij Gustschin @ 2010-01-21  2:13 UTC (permalink / raw)
  To: netdev; +Cc: wd, dzu, linuxppc-dev, Anatolij Gustschin, Piotr Ziecik
In-Reply-To: <1264039999-25731-1-git-send-email-agust@denx.de>

    drivers/net/fs_enet/*
        Enable fs_enet driver to work 5121 FEC
        Enable it with CONFIG_FS_ENET_MPC5121_FEC

Signed-off-by: John Rigby <jcrigby@gmail.com>
Signed-off-by: Piotr Ziecik <kosmo@semihalf.com>
Signed-off-by: Wolfgang Denk <wd@denx.de>
Signed-off-by: Anatolij Gustschin <agust@denx.de>
Cc: <linuxppc-dev@ozlabs.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
---
Changes since previous submited version:

- explicit type usage in register tables.
- don't use same variable name "fecp" for variables of
  different types.
- avoid re-checking the compatible by passing data pointer
  in the match struct.

 drivers/net/fs_enet/Kconfig        |   10 +-
 drivers/net/fs_enet/fs_enet-main.c |    4 +
 drivers/net/fs_enet/fs_enet.h      |   40 +++++++-
 drivers/net/fs_enet/mac-fec.c      |  212 +++++++++++++++++++++++++-----------
 drivers/net/fs_enet/mii-fec.c      |   76 ++++++++++---
 drivers/net/fs_enet/mpc5121_fec.h  |   64 +++++++++++
 drivers/net/fs_enet/mpc8xx_fec.h   |   37 ++++++
 7 files changed, 356 insertions(+), 87 deletions(-)
 create mode 100644 drivers/net/fs_enet/mpc5121_fec.h
 create mode 100644 drivers/net/fs_enet/mpc8xx_fec.h

diff --git a/drivers/net/fs_enet/Kconfig b/drivers/net/fs_enet/Kconfig
index 562ea68..fc073b5 100644
--- a/drivers/net/fs_enet/Kconfig
+++ b/drivers/net/fs_enet/Kconfig
@@ -1,9 +1,13 @@
 config FS_ENET
        tristate "Freescale Ethernet Driver"
-       depends on CPM1 || CPM2
+       depends on CPM1 || CPM2 || PPC_MPC512x
        select MII
        select PHYLIB
 
+config FS_ENET_MPC5121_FEC
+	def_bool y if (FS_ENET && PPC_MPC512x)
+	select FS_ENET_HAS_FEC
+
 config FS_ENET_HAS_SCC
 	bool "Chip has an SCC usable for ethernet"
 	depends on FS_ENET && (CPM1 || CPM2)
@@ -16,13 +20,13 @@ config FS_ENET_HAS_FCC
 
 config FS_ENET_HAS_FEC
 	bool "Chip has an FEC usable for ethernet"
-	depends on FS_ENET && CPM1
+	depends on FS_ENET && (CPM1 || FS_ENET_MPC5121_FEC)
 	select FS_ENET_MDIO_FEC
 	default y
 
 config FS_ENET_MDIO_FEC
 	tristate "MDIO driver for FEC"
-	depends on FS_ENET && CPM1
+	depends on FS_ENET && (CPM1 || FS_ENET_MPC5121_FEC)
 
 config FS_ENET_MDIO_FCC
 	tristate "MDIO driver for FCC"
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index c34a7e0..6bce5c8 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -1095,6 +1095,10 @@ static struct of_device_id fs_enet_match[] = {
 #endif
 #ifdef CONFIG_FS_ENET_HAS_FEC
 	{
+		.compatible = "fsl,mpc5121-fec",
+		.data = (void *)&fs_fec_ops,
+	},
+	{
 		.compatible = "fsl,pq1-fec-enet",
 		.data = (void *)&fs_fec_ops,
 	},
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index ef01e09..df935e8 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -13,11 +13,47 @@
 
 #ifdef CONFIG_CPM1
 #include <asm/cpm1.h>
+#endif
+
+#if defined(CONFIG_FS_ENET_HAS_FEC)
+#include <asm/cpm.h>
+#include "mpc8xx_fec.h"
+#include "mpc5121_fec.h"
 
 struct fec_info {
-	fec_t __iomem *fecp;
+	void __iomem *fecp;
+	u32 __iomem *fec_r_cntrl;
+	u32 __iomem *fec_ecntrl;
+	u32 __iomem *fec_ievent;
+	u32 __iomem *fec_mii_data;
+	u32 __iomem *fec_mii_speed;
 	u32 mii_speed;
 };
+
+struct reg_tbl {
+	u32 __iomem *fec_ievent;
+	u32 __iomem *fec_imask;
+	u32 __iomem *fec_r_des_active;
+	u32 __iomem *fec_x_des_active;
+	u32 __iomem *fec_r_des_start;
+	u32 __iomem *fec_x_des_start;
+	u32 __iomem *fec_r_cntrl;
+	u32 __iomem *fec_ecntrl;
+	u32 __iomem *fec_ivec;
+	u32 __iomem *fec_mii_speed;
+	u32 __iomem *fec_addr_low;
+	u32 __iomem *fec_addr_high;
+	u32 __iomem *fec_hash_table_high;
+	u32 __iomem *fec_hash_table_low;
+	u32 __iomem *fec_r_buff_size;
+	u32 __iomem *fec_r_bound;
+	u32 __iomem *fec_r_fstart;
+	u32 __iomem *fec_x_fstart;
+	u32 __iomem *fec_fun_code;
+	u32 __iomem *fec_r_hash;
+	u32 __iomem *fec_x_cntrl;
+	u32 __iomem *fec_dma_control;
+};
 #endif
 
 #ifdef CONFIG_CPM2
@@ -113,7 +149,9 @@ struct fs_enet_private {
 		struct {
 			int idx;		/* FEC1 = 0, FEC2 = 1  */
 			void __iomem *fecp;	/* hw registers        */
+			struct reg_tbl *rtbl;	/* used registers table */
 			u32 hthi, htlo;		/* state for multicast */
+			u32 fec_id;
 		} fec;
 
 		struct {
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
index a664aa1..fe9e368 100644
--- a/drivers/net/fs_enet/mac-fec.c
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -64,29 +64,40 @@
 #endif
 
 /* write */
-#define FW(_fecp, _reg, _v) __fs_out32(&(_fecp)->fec_ ## _reg, (_v))
+#define FW(_regp, _reg, _v) __fs_out32((_regp)->fec_ ## _reg, (_v))
 
 /* read */
-#define FR(_fecp, _reg)	__fs_in32(&(_fecp)->fec_ ## _reg)
+#define FR(_regp, _reg)	__fs_in32((_regp)->fec_ ## _reg)
 
 /* set bits */
-#define FS(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) | (_v))
+#define FS(_regp, _reg, _v) FW(_regp, _reg, FR(_regp, _reg) | (_v))
 
 /* clear bits */
-#define FC(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) & ~(_v))
+#define FC(_regp, _reg, _v) FW(_regp, _reg, FR(_regp, _reg) & ~(_v))
+
+/* register address macros */
+#define fec_reg_addr(_type, _reg) \
+	(fep->fec.rtbl->fec_##_reg = (u32 __iomem *)((u32)fep->fec.fecp + \
+				(u32)&((__typeof__(_type) *)NULL)->fec_##_reg))
+
+#define fec_reg_mpc8xx(_reg) \
+	fec_reg_addr(struct mpc8xx_fec, _reg)
+
+#define fec_reg_mpc5121(_reg) \
+	fec_reg_addr(struct mpc5121_fec, _reg)
 
 /*
  * Delay to wait for FEC reset command to complete (in us)
  */
 #define FEC_RESET_DELAY		50
 
-static int whack_reset(fec_t __iomem *fecp)
+static int whack_reset(struct reg_tbl *regp)
 {
 	int i;
 
-	FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET);
+	FW(regp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET);
 	for (i = 0; i < FEC_RESET_DELAY; i++) {
-		if ((FR(fecp, ecntrl) & FEC_ECNTRL_RESET) == 0)
+		if ((FR(regp, ecntrl) & FEC_ECNTRL_RESET) == 0)
 			return 0;	/* OK */
 		udelay(1);
 	}
@@ -106,6 +117,50 @@ static int do_pd_setup(struct fs_enet_private *fep)
 	if (!fep->fcc.fccp)
 		return -EINVAL;
 
+	fep->fec.rtbl = kzalloc(sizeof(*fep->fec.rtbl), GFP_KERNEL);
+	if (!fep->fec.rtbl) {
+		iounmap(fep->fec.fecp);
+		return -ENOMEM;
+	}
+
+	if (of_device_is_compatible(ofdev->node, "fsl,mpc5121-fec")) {
+		fep->fec.fec_id = FS_ENET_MPC5121_FEC;
+		fec_reg_mpc5121(ievent);
+		fec_reg_mpc5121(imask);
+		fec_reg_mpc5121(r_cntrl);
+		fec_reg_mpc5121(ecntrl);
+		fec_reg_mpc5121(r_des_active);
+		fec_reg_mpc5121(x_des_active);
+		fec_reg_mpc5121(r_des_start);
+		fec_reg_mpc5121(x_des_start);
+		fec_reg_mpc5121(addr_low);
+		fec_reg_mpc5121(addr_high);
+		fec_reg_mpc5121(hash_table_high);
+		fec_reg_mpc5121(hash_table_low);
+		fec_reg_mpc5121(r_buff_size);
+		fec_reg_mpc5121(mii_speed);
+		fec_reg_mpc5121(x_cntrl);
+		fec_reg_mpc5121(dma_control);
+	} else {
+		fec_reg_mpc8xx(ievent);
+		fec_reg_mpc8xx(imask);
+		fec_reg_mpc8xx(r_cntrl);
+		fec_reg_mpc8xx(ecntrl);
+		fec_reg_mpc8xx(mii_speed);
+		fec_reg_mpc8xx(r_des_active);
+		fec_reg_mpc8xx(x_des_active);
+		fec_reg_mpc8xx(r_des_start);
+		fec_reg_mpc8xx(x_des_start);
+		fec_reg_mpc8xx(ivec);
+		fec_reg_mpc8xx(addr_low);
+		fec_reg_mpc8xx(addr_high);
+		fec_reg_mpc8xx(hash_table_high);
+		fec_reg_mpc8xx(hash_table_low);
+		fec_reg_mpc8xx(r_buff_size);
+		fec_reg_mpc8xx(x_fstart);
+		fec_reg_mpc8xx(r_hash);
+		fec_reg_mpc8xx(x_cntrl);
+	}
 	return 0;
 }
 
@@ -162,15 +217,17 @@ static void free_bd(struct net_device *dev)
 
 static void cleanup_data(struct net_device *dev)
 {
-	/* nothing */
+	struct fs_enet_private *fep = netdev_priv(dev);
+
+	kfree(fep->fec.rtbl);
 }
 
 static void set_promiscuous_mode(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct reg_tbl *regp = fep->fec.rtbl;
 
-	FS(fecp, r_cntrl, FEC_RCNTRL_PROM);
+	FS(regp, r_cntrl, FEC_RCNTRL_PROM);
 }
 
 static void set_multicast_start(struct net_device *dev)
@@ -216,7 +273,7 @@ static void set_multicast_one(struct net_device *dev, const u8 *mac)
 static void set_multicast_finish(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct reg_tbl *regp = fep->fec.rtbl;
 
 	/* if all multi or too many multicasts; just enable all */
 	if ((dev->flags & IFF_ALLMULTI) != 0 ||
@@ -225,9 +282,9 @@ static void set_multicast_finish(struct net_device *dev)
 		fep->fec.htlo = 0xffffffffU;
 	}
 
-	FC(fecp, r_cntrl, FEC_RCNTRL_PROM);
-	FW(fecp, hash_table_high, fep->fec.hthi);
-	FW(fecp, hash_table_low, fep->fec.htlo);
+	FC(regp, r_cntrl, FEC_RCNTRL_PROM);
+	FW(regp, hash_table_high, fep->fec.hthi);
+	FW(regp, hash_table_low, fep->fec.htlo);
 }
 
 static void set_multicast_list(struct net_device *dev)
@@ -246,7 +303,7 @@ static void set_multicast_list(struct net_device *dev)
 static void restart(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct reg_tbl *regp = fep->fec.rtbl;
 	const struct fs_platform_info *fpi = fep->fpi;
 	dma_addr_t rx_bd_base_phys, tx_bd_base_phys;
 	int r;
@@ -255,7 +312,7 @@ static void restart(struct net_device *dev)
 	struct mii_bus* mii = fep->phydev->bus;
 	struct fec_info* fec_inf = mii->priv;
 
-	r = whack_reset(fep->fec.fecp);
+	r = whack_reset(regp);
 	if (r != 0)
 		dev_err(fep->dev, "FEC Reset FAILED!\n");
 	/*
@@ -267,20 +324,23 @@ static void restart(struct net_device *dev)
 		  (u32) dev->dev_addr[3];
 	addrlo = ((u32) dev->dev_addr[4] << 24) |
 		 ((u32) dev->dev_addr[5] << 16);
-	FW(fecp, addr_low, addrhi);
-	FW(fecp, addr_high, addrlo);
+	FW(regp, addr_low, addrhi);
+	FW(regp, addr_high, addrlo);
 
 	/*
 	 * Reset all multicast.
 	 */
-	FW(fecp, hash_table_high, fep->fec.hthi);
-	FW(fecp, hash_table_low, fep->fec.htlo);
+	FW(regp, hash_table_high, fep->fec.hthi);
+	FW(regp, hash_table_low, fep->fec.htlo);
 
 	/*
 	 * Set maximum receive buffer size.
 	 */
-	FW(fecp, r_buff_size, PKT_MAXBLR_SIZE);
-	FW(fecp, r_hash, PKT_MAXBUF_SIZE);
+	FW(regp, r_buff_size, PKT_MAXBLR_SIZE);
+	if (fep->fec.fec_id == FS_ENET_MPC5121_FEC)
+		FW(regp, r_cntrl, PKT_MAXBUF_SIZE << 16);
+	else
+		FW(regp, r_hash, PKT_MAXBUF_SIZE);
 
 	/* get physical address */
 	rx_bd_base_phys = fep->ring_mem_addr;
@@ -289,67 +349,82 @@ static void restart(struct net_device *dev)
 	/*
 	 * Set receive and transmit descriptor base.
 	 */
-	FW(fecp, r_des_start, rx_bd_base_phys);
-	FW(fecp, x_des_start, tx_bd_base_phys);
+	FW(regp, r_des_start, rx_bd_base_phys);
+	FW(regp, x_des_start, tx_bd_base_phys);
 
 	fs_init_bds(dev);
 
 	/*
-	 * Enable big endian and don't care about SDMA FC.
+	 * Enable big endian.
 	 */
-	FW(fecp, fun_code, 0x78000000);
+	if (fep->fec.fec_id == FS_ENET_MPC5121_FEC)
+		FS(regp, dma_control, 0xC0000000);
+	else
+		/* Don't care about SDMA Function Code. */
+		FW(regp, fun_code, 0x78000000);
 
 	/*
 	 * Set MII speed.
 	 */
-	FW(fecp, mii_speed, fec_inf->mii_speed);
+	FW(regp, mii_speed, fec_inf->mii_speed);
 
 	/*
 	 * Clear any outstanding interrupt.
 	 */
-	FW(fecp, ievent, 0xffc0);
-	FW(fecp, ivec, (virq_to_hw(fep->interrupt) / 2) << 29);
+	FW(regp, ievent, 0xffc0);
+	if (fep->fec.fec_id != FS_ENET_MPC5121_FEC)
+		FW(regp, ivec, (virq_to_hw(fep->interrupt) / 2) << 29);
+
+	/* MII enable */
+	if (fep->fec.fec_id == FS_ENET_MPC5121_FEC) {
+		/*
+		 * Only set requested bit - do not touch maximum packet
+		 * size configured earlier.
+		 */
+		FS(regp, r_cntrl, FEC_RCNTRL_MII_MODE);
+	} else {
+		FW(regp, r_cntrl, FEC_RCNTRL_MII_MODE);
+	}
 
-	FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE);	/* MII enable */
 	/*
 	 * adjust to duplex mode
 	 */
 	if (fep->phydev->duplex) {
-		FC(fecp, r_cntrl, FEC_RCNTRL_DRT);
-		FS(fecp, x_cntrl, FEC_TCNTRL_FDEN);	/* FD enable */
+		FC(regp, r_cntrl, FEC_RCNTRL_DRT);
+		FS(regp, x_cntrl, FEC_TCNTRL_FDEN);	/* FD enable */
 	} else {
-		FS(fecp, r_cntrl, FEC_RCNTRL_DRT);
-		FC(fecp, x_cntrl, FEC_TCNTRL_FDEN);	/* FD disable */
+		FS(regp, r_cntrl, FEC_RCNTRL_DRT);
+		FC(regp, x_cntrl, FEC_TCNTRL_FDEN);	/* FD disable */
 	}
 
 	/*
 	 * Enable interrupts we wish to service.
 	 */
-	FW(fecp, imask, FEC_ENET_TXF | FEC_ENET_TXB |
+	FW(regp, imask, FEC_ENET_TXF | FEC_ENET_TXB |
 	   FEC_ENET_RXF | FEC_ENET_RXB);
 
 	/*
 	 * And last, enable the transmit and receive processing.
 	 */
-	FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
-	FW(fecp, r_des_active, 0x01000000);
+	FW(regp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
+	FW(regp, r_des_active, 0x01000000);
 }
 
 static void stop(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
 	const struct fs_platform_info *fpi = fep->fpi;
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct reg_tbl *regp = fep->fec.rtbl;
 
 	struct fec_info* feci= fep->phydev->bus->priv;
 
 	int i;
 
-	if ((FR(fecp, ecntrl) & FEC_ECNTRL_ETHER_EN) == 0)
+	if ((FR(regp, ecntrl) & FEC_ECNTRL_ETHER_EN) == 0)
 		return;		/* already down */
 
-	FW(fecp, x_cntrl, 0x01);	/* Graceful transmit stop */
-	for (i = 0; ((FR(fecp, ievent) & 0x10000000) == 0) &&
+	FW(regp, x_cntrl, 0x01);	/* Graceful transmit stop */
+	for (i = 0; ((FR(regp, ievent) & 0x10000000) == 0) &&
 	     i < FEC_RESET_DELAY; i++)
 		udelay(1);
 
@@ -358,74 +433,74 @@ static void stop(struct net_device *dev)
 	/*
 	 * Disable FEC. Let only MII interrupts.
 	 */
-	FW(fecp, imask, 0);
-	FC(fecp, ecntrl, FEC_ECNTRL_ETHER_EN);
+	FW(regp, imask, 0);
+	FC(regp, ecntrl, FEC_ECNTRL_ETHER_EN);
 
 	fs_cleanup_bds(dev);
 
 	/* shut down FEC1? that's where the mii bus is */
 	if (fpi->has_phy) {
-		FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE);	/* MII enable */
-		FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
-		FW(fecp, ievent, FEC_ENET_MII);
-		FW(fecp, mii_speed, feci->mii_speed);
+		FS(regp, r_cntrl, FEC_RCNTRL_MII_MODE);	/* MII enable */
+		FS(regp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
+		FW(regp, ievent, FEC_ENET_MII);
+		FW(regp, mii_speed, feci->mii_speed);
 	}
 }
 
 static void napi_clear_rx_event(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct reg_tbl *regp = fep->fec.rtbl;
 
-	FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK);
+	FW(regp, ievent, FEC_NAPI_RX_EVENT_MSK);
 }
 
 static void napi_enable_rx(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct reg_tbl *regp = fep->fec.rtbl;
 
-	FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
+	FS(regp, imask, FEC_NAPI_RX_EVENT_MSK);
 }
 
 static void napi_disable_rx(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct reg_tbl *regp = fep->fec.rtbl;
 
-	FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
+	FC(regp, imask, FEC_NAPI_RX_EVENT_MSK);
 }
 
 static void rx_bd_done(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct reg_tbl *regp = fep->fec.rtbl;
 
-	FW(fecp, r_des_active, 0x01000000);
+	FW(regp, r_des_active, 0x01000000);
 }
 
 static void tx_kickstart(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct reg_tbl *regp = fep->fec.rtbl;
 
-	FW(fecp, x_des_active, 0x01000000);
+	FW(regp, x_des_active, 0x01000000);
 }
 
 static u32 get_int_events(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct reg_tbl *regp = fep->fec.rtbl;
 
-	return FR(fecp, ievent) & FR(fecp, imask);
+	return FR(regp, ievent) & FR(regp, imask);
 }
 
 static void clear_int_events(struct net_device *dev, u32 int_events)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct reg_tbl *regp = fep->fec.rtbl;
 
-	FW(fecp, ievent, int_events);
+	FW(regp, ievent, int_events);
 }
 
 static void ev_error(struct net_device *dev, u32 int_events)
@@ -438,18 +513,26 @@ static void ev_error(struct net_device *dev, u32 int_events)
 static int get_regs(struct net_device *dev, void *p, int *sizep)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
+	int size;
 
-	if (*sizep < sizeof(fec_t))
+	size = fep->fec.fec_id ? sizeof(struct mpc5121_fec) :
+				 sizeof(struct mpc8xx_fec);
+	if (*sizep < size)
 		return -EINVAL;
 
-	memcpy_fromio(p, fep->fec.fecp, sizeof(fec_t));
+	memcpy_fromio(p, fep->fec.fecp, size);
 
 	return 0;
 }
 
 static int get_regs_len(struct net_device *dev)
 {
-	return sizeof(fec_t);
+	struct fs_enet_private *fep = netdev_priv(dev);
+
+	if (fep->fec.fec_id == FS_ENET_MPC5121_FEC)
+		return sizeof(struct mpc5121_fec);
+	else
+		return sizeof(struct mpc8xx_fec);
 }
 
 static void tx_restart(struct net_device *dev)
@@ -479,4 +562,3 @@ const struct fs_ops fs_fec_ops = {
 	.allocate_bd		= allocate_bd,
 	.free_bd		= free_bd,
 };
-
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index 96eba42..eac18ab 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -49,24 +49,38 @@
 
 #define FEC_MII_LOOPS	10000
 
+#define fec_reg_addr(_type, _reg) \
+	(fec->fec_##_reg = (u32 __iomem *)((u32)fec->fecp + \
+				(u32)&((__typeof__(_type) *)NULL)->fec_##_reg))
+
+#define fec_reg_mpc8xx(_reg) \
+	fec_reg_addr(struct mpc8xx_fec, _reg)
+
+#define fec_reg_mpc5121(_reg) \
+	fec_reg_addr(struct mpc5121_fec, _reg)
+
+struct fs_enet_mdio_fec_match_data {
+	unsigned long (*get_bus_freq)(struct device_node *);
+	unsigned int fec_id;
+};
+
 static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
 {
 	struct fec_info* fec = bus->priv;
-	fec_t __iomem *fecp = fec->fecp;
 	int i, ret = -1;
 
-	BUG_ON((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0);
+	BUG_ON((in_be32(fec->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0);
 
 	/* Add PHY address to register command.  */
-	out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_read(location));
+	out_be32(fec->fec_mii_data, (phy_id << 23) | mk_mii_read(location));
 
 	for (i = 0; i < FEC_MII_LOOPS; i++)
-		if ((in_be32(&fecp->fec_ievent) & FEC_ENET_MII) != 0)
+		if ((in_be32(fec->fec_ievent) & FEC_ENET_MII) != 0)
 			break;
 
 	if (i < FEC_MII_LOOPS) {
-		out_be32(&fecp->fec_ievent, FEC_ENET_MII);
-		ret = in_be32(&fecp->fec_mii_data) & 0xffff;
+		out_be32(fec->fec_ievent, FEC_ENET_MII);
+		ret = in_be32(fec->fec_mii_data) & 0xffff;
 	}
 
 	return ret;
@@ -75,21 +89,21 @@ static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
 static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val)
 {
 	struct fec_info* fec = bus->priv;
-	fec_t __iomem *fecp = fec->fecp;
 	int i;
 
 	/* this must never happen */
-	BUG_ON((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0);
+	BUG_ON((in_be32(fec->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0);
 
 	/* Add PHY address to register command.  */
-	out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_write(location, val));
+	out_be32(fec->fec_mii_data, (phy_id << 23) |
+				    mk_mii_write(location, val));
 
 	for (i = 0; i < FEC_MII_LOOPS; i++)
-		if ((in_be32(&fecp->fec_ievent) & FEC_ENET_MII) != 0)
+		if ((in_be32(fec->fec_ievent) & FEC_ENET_MII) != 0)
 			break;
 
 	if (i < FEC_MII_LOOPS)
-		out_be32(&fecp->fec_ievent, FEC_ENET_MII);
+		out_be32(fec->fec_ievent, FEC_ENET_MII);
 
 	return 0;
 
@@ -107,7 +121,8 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
 	struct resource res;
 	struct mii_bus *new_bus;
 	struct fec_info *fec;
-	int (*get_bus_freq)(struct device_node *) = match->data;
+	unsigned long (*get_bus_freq)(struct device_node *) = NULL;
+	struct fs_enet_mdio_fec_match_data *md;
 	int ret = -ENOMEM, clock, speed;
 
 	new_bus = mdiobus_alloc();
@@ -134,6 +149,24 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
 	if (!fec->fecp)
 		goto out_fec;
 
+	md = match->data;
+	if (md)
+		get_bus_freq = md->get_bus_freq;
+
+	if (md && md->fec_id == FS_ENET_MPC5121_FEC) {
+		fec_reg_mpc5121(ecntrl);
+		fec_reg_mpc5121(ievent);
+		fec_reg_mpc5121(mii_data);
+		fec_reg_mpc5121(mii_speed);
+		fec_reg_mpc5121(r_cntrl);
+	} else {
+		fec_reg_mpc8xx(ecntrl);
+		fec_reg_mpc8xx(ievent);
+		fec_reg_mpc8xx(mii_data);
+		fec_reg_mpc8xx(mii_speed);
+		fec_reg_mpc8xx(r_cntrl);
+	}
+
 	if (get_bus_freq) {
 		clock = get_bus_freq(ofdev->node);
 		if (!clock) {
@@ -158,11 +191,11 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
 
 	fec->mii_speed = speed << 1;
 
-	setbits32(&fec->fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
-	setbits32(&fec->fecp->fec_ecntrl, FEC_ECNTRL_PINMUX |
-	                                  FEC_ECNTRL_ETHER_EN);
-	out_be32(&fec->fecp->fec_ievent, FEC_ENET_MII);
-	clrsetbits_be32(&fec->fecp->fec_mii_speed, 0x7E, fec->mii_speed);
+	setbits32(fec->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
+	setbits32(fec->fec_ecntrl, FEC_ECNTRL_PINMUX |
+				   FEC_ECNTRL_ETHER_EN);
+	out_be32(fec->fec_ievent, FEC_ENET_MII);
+	clrsetbits_be32(fec->fec_mii_speed, 0x7E, fec->mii_speed);
 
 	new_bus->phy_mask = ~0;
 	new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
@@ -207,6 +240,13 @@ static int fs_enet_mdio_remove(struct of_device *ofdev)
 	return 0;
 }
 
+#if defined(CONFIG_PPC_MPC512x)
+static struct fs_enet_mdio_fec_match_data mpc5121_match_data = {
+	.get_bus_freq = mpc5xxx_get_bus_frequency,
+	.fec_id = FS_ENET_MPC5121_FEC,
+};
+#endif
+
 static struct of_device_id fs_enet_mdio_fec_match[] = {
 	{
 		.compatible = "fsl,pq1-fec-mdio",
@@ -214,7 +254,7 @@ static struct of_device_id fs_enet_mdio_fec_match[] = {
 #if defined(CONFIG_PPC_MPC512x)
 	{
 		.compatible = "fsl,mpc5121-fec-mdio",
-		.data = mpc5xxx_get_bus_frequency,
+		.data = (void *)&mpc5121_match_data,
 	},
 #endif
 	{},
diff --git a/drivers/net/fs_enet/mpc5121_fec.h b/drivers/net/fs_enet/mpc5121_fec.h
new file mode 100644
index 0000000..18d4fb3
--- /dev/null
+++ b/drivers/net/fs_enet/mpc5121_fec.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: John Rigby, <jrigby@freescale.com>
+ *
+ * Modified version of drivers/net/fec.h:
+ *
+ *	fec.h  --  Fast Ethernet Controller for Motorola ColdFire SoC
+ *		   processors.
+ *
+ *	(C) Copyright 2000-2005, Greg Ungerer (gerg@snapgear.com)
+ *	(C) Copyright 2000-2001, Lineo (www.lineo.com)
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef MPC5121_FEC_H
+#define MPC5121_FEC_H
+
+struct mpc5121_fec {
+	u32 fec_reserved0;
+	u32 fec_ievent;			/* Interrupt event reg */
+	u32 fec_imask;			/* Interrupt mask reg */
+	u32 fec_reserved1;
+	u32 fec_r_des_active;		/* Receive descriptor reg */
+	u32 fec_x_des_active;		/* Transmit descriptor reg */
+	u32 fec_reserved2[3];
+	u32 fec_ecntrl;			/* Ethernet control reg */
+	u32 fec_reserved3[6];
+	u32 fec_mii_data;		/* MII manage frame reg */
+	u32 fec_mii_speed;		/* MII speed control reg */
+	u32 fec_reserved4[7];
+	u32 fec_mib_ctrlstat;		/* MIB control/status reg */
+	u32 fec_reserved5[7];
+	u32 fec_r_cntrl;		/* Receive control reg */
+	u32 fec_reserved6[15];
+	u32 fec_x_cntrl;		/* Transmit Control reg */
+	u32 fec_reserved7[7];
+	u32 fec_addr_low;		/* Low 32bits MAC address */
+	u32 fec_addr_high;		/* High 16bits MAC address */
+	u32 fec_opd;			/* Opcode + Pause duration */
+	u32 fec_reserved8[10];
+	u32 fec_hash_table_high;	/* High 32bits hash table */
+	u32 fec_hash_table_low;		/* Low 32bits hash table */
+	u32 fec_grp_hash_table_high;	/* High 32bits hash table */
+	u32 fec_grp_hash_table_low;	/* Low 32bits hash table */
+	u32 fec_reserved9[7];
+	u32 fec_x_wmrk;			/* FIFO transmit water mark */
+	u32 fec_reserved10;
+	u32 fec_r_bound;		/* FIFO receive bound reg */
+	u32 fec_r_fstart;		/* FIFO receive start reg */
+	u32 fec_reserved11[11];
+	u32 fec_r_des_start;		/* Receive descriptor ring */
+	u32 fec_x_des_start;		/* Transmit descriptor ring */
+	u32 fec_r_buff_size;		/* Maximum receive buff size */
+	u32 fec_reserved12[26];
+	u32 fec_dma_control;		/* DMA Endian and other ctrl */
+};
+
+#define FS_ENET_MPC5121_FEC	0x1
+
+#endif /* MPC5121_FEC_H */
diff --git a/drivers/net/fs_enet/mpc8xx_fec.h b/drivers/net/fs_enet/mpc8xx_fec.h
new file mode 100644
index 0000000..aa78445
--- /dev/null
+++ b/drivers/net/fs_enet/mpc8xx_fec.h
@@ -0,0 +1,37 @@
+/* MPC860T Fast Ethernet Controller.  It isn't part of the CPM, but
+ * it fits within the address space.
+ */
+
+struct mpc8xx_fec {
+	uint	fec_addr_low;		/* lower 32 bits of station address */
+	ushort	fec_addr_high;		/* upper 16 bits of station address */
+	ushort	res1;			/* reserved			    */
+	uint	fec_hash_table_high;	/* upper 32-bits of hash table	    */
+	uint	fec_hash_table_low;	/* lower 32-bits of hash table	    */
+	uint	fec_r_des_start;	/* beginning of Rx descriptor ring  */
+	uint	fec_x_des_start;	/* beginning of Tx descriptor ring  */
+	uint	fec_r_buff_size;	/* Rx buffer size		    */
+	uint	res2[9];		/* reserved			    */
+	uint	fec_ecntrl;		/* ethernet control register	    */
+	uint	fec_ievent;		/* interrupt event register	    */
+	uint	fec_imask;		/* interrupt mask register	    */
+	uint	fec_ivec;		/* interrupt level and vector status */
+	uint	fec_r_des_active;	/* Rx ring updated flag		    */
+	uint	fec_x_des_active;	/* Tx ring updated flag		    */
+	uint	res3[10];		/* reserved			    */
+	uint	fec_mii_data;		/* MII data register		    */
+	uint	fec_mii_speed;		/* MII speed control register	    */
+	uint	res4[17];		/* reserved			    */
+	uint	fec_r_bound;		/* end of RAM (read-only)	    */
+	uint	fec_r_fstart;		/* Rx FIFO start address	    */
+	uint	res5[6];		/* reserved			    */
+	uint	fec_x_fstart;		/* Tx FIFO start address	    */
+	uint	res6[17];		/* reserved			    */
+	uint	fec_fun_code;		/* fec SDMA function code	    */
+	uint	res7[3];		/* reserved			    */
+	uint	fec_r_cntrl;		/* Rx control register		    */
+	uint	fec_r_hash;		/* Rx hash register		    */
+	uint	res8[14];		/* reserved			    */
+	uint	fec_x_cntrl;		/* Tx control register		    */
+	uint	res9[0x1e];		/* reserved			    */
+};
-- 
1.5.6.3

^ permalink raw reply related

* [net-next-2.6 PATCH 3/3] fs_enet: Add FEC TX Alignment workaround for MPC5121
From: Anatolij Gustschin @ 2010-01-21  2:13 UTC (permalink / raw)
  To: netdev; +Cc: wd, dzu, linuxppc-dev, Anatolij Gustschin, Piotr Ziecik
In-Reply-To: <1264039999-25731-1-git-send-email-agust@denx.de>

The FEC on 5121 has problems with misaligned tx buffers.
The RM says any alignment is ok but empirical results
show that packet buffers ending in 0x1E will sometimes
hang the FEC.  Other bad alignment does not hang but will
cause silent TX failures resulting in about a 1% packet
loss as tested by ping -f from a remote host.

This patch is a work around that copies every tx packet
to an aligned skb before sending.

Signed-off-by: John Rigby <jcrigby@gmail.com>
Signed-off-by: Piotr Ziecik <kosmo@semihalf.com>
Signed-off-by: Wolfgang Denk <wd@denx.de>
Signed-off-by: Anatolij Gustschin <agust@denx.de>
Cc: <linuxppc-dev@ozlabs.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
---
Changes since previous submited version:

- don't use printk any more and use dev_warn().

 drivers/net/fs_enet/fs_enet-main.c |   38 ++++++++++++++++++++++++++++++++++++
 1 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 6bce5c8..7f0bd5d 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -580,6 +580,32 @@ void fs_cleanup_bds(struct net_device *dev)
 
 /**********************************************************************************/
 
+static struct sk_buff *tx_skb_align_workaround(struct net_device *dev,
+					       struct sk_buff *skb)
+{
+	struct sk_buff *new_skb;
+	struct fs_enet_private *fep = netdev_priv(dev);
+
+	/* Alloc new skb */
+	new_skb = dev_alloc_skb(ENET_RX_FRSIZE + 32);
+	if (!new_skb) {
+		dev_warn(fep->dev, "Memory squeeze, dropping tx packet.\n");
+		return NULL;
+	}
+
+	/* Make sure new skb is properly aligned */
+	skb_align(new_skb, 32);
+
+	/* Copy data to new skb ... */
+	skb_copy_from_linear_data(skb, new_skb->data, skb->len);
+	skb_put(new_skb, skb->len);
+
+	/* ... and free an old one */
+	dev_kfree_skb_any(skb);
+
+	return new_skb;
+}
+
 static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
@@ -588,6 +614,18 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	u16 sc;
 	unsigned long flags;
 
+	if (fep->fec.fec_id == FS_ENET_MPC5121_FEC) {
+		skb = tx_skb_align_workaround(dev, skb);
+		if (!skb) {
+			/*
+			 * We have lost packet due to memory allocation error
+			 * in tx_skb_align_workaround(). Hopefully original skb
+			 * is still valid, so try transmit it later.
+			 */
+			return NETDEV_TX_BUSY;
+		}
+	}
+
 	spin_lock_irqsave(&fep->tx_lock, flags);
 
 	/*
-- 
1.5.6.3

^ permalink raw reply related

* [net-next-2.6 PATCH 1/3] fs_enet: use dev_xxx instead of printk
From: Anatolij Gustschin @ 2010-01-21  2:13 UTC (permalink / raw)
  To: netdev; +Cc: wd, dzu, linuxppc-dev, Anatolij Gustschin, Piotr Ziecik
In-Reply-To: <1264039999-25731-1-git-send-email-agust@denx.de>

Signed-off-by: Anatolij Gustschin <agust@denx.de>
Cc: <linuxppc-dev@ozlabs.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: John Rigby <jcrigby@gmail.com>
Cc: Piotr Ziecik <kosmo@semihalf.com>
Cc: Wolfgang Denk <wd@denx.de>
---
 drivers/net/fs_enet/fs_enet-main.c |   39 +++++++++++++----------------------
 drivers/net/fs_enet/mac-fcc.c      |    5 ++-
 drivers/net/fs_enet/mac-fec.c      |   12 ++++------
 drivers/net/fs_enet/mac-scc.c      |    9 +++----
 4 files changed, 27 insertions(+), 38 deletions(-)

diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index ec2f503..c34a7e0 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -108,9 +108,7 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
 		 * the last indicator should be set.
 		 */
 		if ((sc & BD_ENET_RX_LAST) == 0)
-			printk(KERN_WARNING DRV_MODULE_NAME
-			       ": %s rcv is not +last\n",
-			       dev->name);
+			dev_warn(fep->dev, "rcv is not +last\n");
 
 		/*
 		 * Check for errors.
@@ -178,9 +176,8 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
 				received++;
 				netif_receive_skb(skb);
 			} else {
-				printk(KERN_WARNING DRV_MODULE_NAME
-				       ": %s Memory squeeze, dropping packet.\n",
-				       dev->name);
+				dev_warn(fep->dev,
+					 "Memory squeeze, dropping packet.\n");
 				fep->stats.rx_dropped++;
 				skbn = skb;
 			}
@@ -242,9 +239,7 @@ static int fs_enet_rx_non_napi(struct net_device *dev)
 		 * the last indicator should be set.
 		 */
 		if ((sc & BD_ENET_RX_LAST) == 0)
-			printk(KERN_WARNING DRV_MODULE_NAME
-			       ": %s rcv is not +last\n",
-			       dev->name);
+			dev_warn(fep->dev, "rcv is not +last\n");
 
 		/*
 		 * Check for errors.
@@ -313,9 +308,8 @@ static int fs_enet_rx_non_napi(struct net_device *dev)
 				received++;
 				netif_rx(skb);
 			} else {
-				printk(KERN_WARNING DRV_MODULE_NAME
-				       ": %s Memory squeeze, dropping packet.\n",
-				       dev->name);
+				dev_warn(fep->dev,
+					 "Memory squeeze, dropping packet.\n");
 				fep->stats.rx_dropped++;
 				skbn = skb;
 			}
@@ -388,10 +382,10 @@ static void fs_enet_tx(struct net_device *dev)
 		} else
 			fep->stats.tx_packets++;
 
-		if (sc & BD_ENET_TX_READY)
-			printk(KERN_WARNING DRV_MODULE_NAME
-			       ": %s HEY! Enet xmit interrupt and TX_READY.\n",
-			       dev->name);
+		if (sc & BD_ENET_TX_READY) {
+			dev_warn(fep->dev,
+				 "HEY! Enet xmit interrupt and TX_READY.\n");
+		}
 
 		/*
 		 * Deferred means some collisions occurred during transmit,
@@ -511,9 +505,8 @@ void fs_init_bds(struct net_device *dev)
 	for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) {
 		skb = dev_alloc_skb(ENET_RX_FRSIZE);
 		if (skb == NULL) {
-			printk(KERN_WARNING DRV_MODULE_NAME
-			       ": %s Memory squeeze, unable to allocate skb\n",
-			       dev->name);
+			dev_warn(fep->dev,
+				 "Memory squeeze, unable to allocate skb\n");
 			break;
 		}
 		skb_align(skb, ENET_RX_ALIGN);
@@ -610,8 +603,7 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		 * Ooops.  All transmit buffers are full.  Bail out.
 		 * This should not happen, since the tx queue should be stopped.
 		 */
-		printk(KERN_WARNING DRV_MODULE_NAME
-		       ": %s tx queue full!.\n", dev->name);
+		dev_warn(fep->dev, "tx queue full!.\n");
 		return NETDEV_TX_BUSY;
 	}
 
@@ -788,8 +780,7 @@ static int fs_enet_open(struct net_device *dev)
 	r = request_irq(fep->interrupt, fs_enet_interrupt, IRQF_SHARED,
 			"fs_enet-mac", dev);
 	if (r != 0) {
-		printk(KERN_ERR DRV_MODULE_NAME
-		       ": %s Could not allocate FS_ENET IRQ!", dev->name);
+		dev_err(fep->dev, "Could not allocate FS_ENET IRQ!");
 		if (fep->fpi->use_napi)
 			napi_disable(&fep->napi);
 		return -EINVAL;
@@ -1053,7 +1044,7 @@ static int __devinit fs_enet_probe(struct of_device *ofdev,
 	if (ret)
 		goto out_free_bd;
 
-	printk(KERN_INFO "%s: fs_enet: %pM\n", ndev->name, ndev->dev_addr);
+	pr_info("%s: fs_enet: %pM\n", ndev->name, ndev->dev_addr);
 
 	return 0;
 
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index 22e5a84..dd78640 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -476,8 +476,9 @@ static void clear_int_events(struct net_device *dev, u32 int_events)
 
 static void ev_error(struct net_device *dev, u32 int_events)
 {
-	printk(KERN_WARNING DRV_MODULE_NAME
-	       ": %s FS_ENET ERROR(s) 0x%x\n", dev->name, int_events);
+	struct fs_enet_private *fep = netdev_priv(dev);
+
+	dev_warn(fep->dev, "FS_ENET ERROR(s) 0x%x\n", int_events);
 }
 
 static int get_regs(struct net_device *dev, void *p, int *sizep)
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
index ca7bcb8..a664aa1 100644
--- a/drivers/net/fs_enet/mac-fec.c
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -257,8 +257,7 @@ static void restart(struct net_device *dev)
 
 	r = whack_reset(fep->fec.fecp);
 	if (r != 0)
-		printk(KERN_ERR DRV_MODULE_NAME
-				": %s FEC Reset FAILED!\n", dev->name);
+		dev_err(fep->dev, "FEC Reset FAILED!\n");
 	/*
 	 * Set station address.
 	 */
@@ -355,9 +354,7 @@ static void stop(struct net_device *dev)
 		udelay(1);
 
 	if (i == FEC_RESET_DELAY)
-		printk(KERN_WARNING DRV_MODULE_NAME
-		       ": %s FEC timeout on graceful transmit stop\n",
-		       dev->name);
+		dev_warn(fep->dev, "FEC timeout on graceful transmit stop\n");
 	/*
 	 * Disable FEC. Let only MII interrupts.
 	 */
@@ -433,8 +430,9 @@ static void clear_int_events(struct net_device *dev, u32 int_events)
 
 static void ev_error(struct net_device *dev, u32 int_events)
 {
-	printk(KERN_WARNING DRV_MODULE_NAME
-	       ": %s FEC ERROR(s) 0x%x\n", dev->name, int_events);
+	struct fs_enet_private *fep = netdev_priv(dev);
+
+	dev_warn(fep->dev, "FEC ERROR(s) 0x%x\n", int_events);
 }
 
 static int get_regs(struct net_device *dev, void *p, int *sizep)
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c
index 008cdd9..2d8917f 100644
--- a/drivers/net/fs_enet/mac-scc.c
+++ b/drivers/net/fs_enet/mac-scc.c
@@ -367,9 +367,7 @@ static void stop(struct net_device *dev)
 		udelay(1);
 
 	if (i == SCC_RESET_DELAY)
-		printk(KERN_WARNING DRV_MODULE_NAME
-		       ": %s SCC timeout on graceful transmit stop\n",
-		       dev->name);
+		dev_warn(fep->dev, "SCC timeout on graceful transmit stop\n");
 
 	W16(sccp, scc_sccm, 0);
 	C32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
@@ -429,8 +427,9 @@ static void clear_int_events(struct net_device *dev, u32 int_events)
 
 static void ev_error(struct net_device *dev, u32 int_events)
 {
-	printk(KERN_WARNING DRV_MODULE_NAME
-	       ": %s SCC ERROR(s) 0x%x\n", dev->name, int_events);
+	struct fs_enet_private *fep = netdev_priv(dev);
+
+	dev_warn(fep->dev, "SCC ERROR(s) 0x%x\n", int_events);
 }
 
 static int get_regs(struct net_device *dev, void *p, int *sizep)
-- 
1.5.6.3

^ permalink raw reply related

* [net-next-2.6 PATCH 0/3] Support for MPC512x FEC
From: Anatolij Gustschin @ 2010-01-21  2:13 UTC (permalink / raw)
  To: netdev; +Cc: wd, dzu, linuxppc-dev, Anatolij Gustschin

These patches attempt to provide support for the Freescale MPC512x
FEC in the fs_enet driver. The first cleanup patch replaces printk
by dev_xxx. The second and third attemt to support MPC5121 FEC
in the FEC driver. The first version of the last two patches
was previously submitted as part of the patch series for updated
MPC5121 support. Now these are separated and also address comments
to the first version. Additionally a cleanup patch is added
to this new series. The patches are based on net-next-2.6.

[1/3] fs_enet: use dev_xxx instead of printk
[2/3] fs_enet: Add support for MPC512x to fs_enet driver
[3/3] fs_enet: Add FEC TX Alignment workaround for MPC5121

The code has been tested on the Freescale/STX "MPC5121ADS" board
(board rev. 4) with a MPC5121e Rev. 2.

Cc: <linuxppc-dev@ozlabs.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: John Rigby <jcrigby@gmail.com>
---

^ permalink raw reply

* How to trun off udbg0 during bootup?
From: 景文林 @ 2010-01-21  1:02 UTC (permalink / raw)
  To: linuxppc-dev

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

Hi,

 I `m working on a freescale-MPC8379eRDB like board.And I want to trun off
kernel message during bootup.

 I tried to  modify "console = XXX" argument in uboot but it did not work(It
works on ARM). Kernel always print:

"console [udbg0] enabled"    or   "console handover: boot [*udbg0*] -> real
[ttyS1]"

Does anybody know how can I turn off this udbg0?


Regards,

jing wenlin

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

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: implement arch_scale_smt_power for Power7
From: Joel Schopp @ 2010-01-20 22:44 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: ego, Andreas Herrmann, linux-kernel, Ingo Molnar, linuxppc-dev
In-Reply-To: <1264020517.4283.1117.camel@laptop>

Peter Zijlstra wrote:
> On Wed, 2010-01-20 at 14:04 -0600, Joel Schopp wrote:
>   
>> On Power7 processors running in SMT4 mode with 2, 3, or 4 idle threads 
>> there is performance benefit to idling the higher numbered threads in
>> the core.  
>>     
>
> So this is an actual performance improvement, not only power savings?
>   
Yes.

>
>
> And you just wrecked x86 ;-)
>
> It has an smt_power implementation that tries to measure smt gains using
> aperf/mperf, trouble is that this represents the actual performance not
> the capacity. This has the problem that when idle it represents 0
> capacity and will not attract work.
>
> Coming up with something that actually works there is on the todo list,
> I was thinking perhaps temporal maximums from !idle.
>
> So if you want to go with this, you'll need to stub out
> arch/x86/kernel/cpu/sched.c
>   

OK.  Guess I now will have a 3 patch series, with a patch to stub out 
the x86 broken version.

Care to take Gautham's bugfix patch (patch 1/2) now, since it just fixes 
a bug?  You'll need it if you ever try to make the x86 broken version work.

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: implement arch_scale_smt_power for Power7
From: Joel Schopp @ 2010-01-20 22:36 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linux-kernel, Ingo Molnar, linuxppc-dev, Peter Zijlstra, ego
In-Reply-To: <1264023213.724.561.camel@pasglop>


>> +
>> +static inline int thread_in_smt4core(int x)
>> +{
>> +  return x % 4;
>> +}
>>     
>
> Needs a whitespace here though I don't really like the above. Any reason
> why you can't use the existing cpu_thread_in_core() ?
>   
I will change it to cpu_thread_in_core()
>   
>> +unsigned long arch_scale_smt_power(struct sched_domain *sd, int cpu)
>> +{
>> +  int cpu2;
>> +  int idle_count = 0;
>> +
>> +  struct cpumask *cpu_map = sched_domain_span(sd);
>> +
>> +	unsigned long weight = cpumask_weight(cpu_map);
>> +	unsigned long smt_gain = sd->smt_gain;
>>     
>
> More whitespace damage above.
>   
You are better than checkpatch.pl, will fix.
>   
>> +	if (cpu_has_feature(CPU_FTRS_POWER7) && weight == 4) {
>> +		for_each_cpu(cpu2, cpu_map) {
>> +			if (idle_cpu(cpu2))
>> +				idle_count++;
>> +		}
>>     
>
> I'm not 100% sure about the use of the CPU feature above. First I wonder
> if the right approach is to instead do something like
>
> 	if (!cpu_has_feature(...) !! weigth < 4)
> 		return default_scale_smt_power(sd, cpu);
>
> Though we may be better off using a ppc_md. hook here to avoid
> calculating the weight etc... on processors that don't need any
> of that.
>
> I also dislike your naming. I would suggest you change cpu_map to
> sibling_map() and cpu2 to sibling (or just c). One thing I wonder is how
> sure we are that sched_domain_span() is always going to give us the
> threads btw ? If we introduce another sched domain level for NUMA
> purposes can't we get confused ?
>   
Right now it's 100% always giving us threads.  My development version of 
the patch had a BUG_ON() to check this.  I expect this to stay the case 
in the future as the name of the function is arch_scale_smt_power(), 
which clearly denotes threads are expected.

I am not stuck on the names, I'll change it to sibling instead of cpu2 
and sibling_map instead of cpu_map.  It seems clear to me either way.

As for testing the ! case it seems funcationally equivalent, and mine 
seems less confusing.

Having a ppc.md hook with exactly 1 user is pointless, especially since 
you'll still have to calculate the weight with the ability to 
dynamically disable smt.

> Also, how hot is this code path ?
>   
It's every load balance, which is to say not hot, but fairly frequent.  
I haven't been able to measure an impact from doing very hairy 
calculations (without actually changing the weights) here vs not having 
it at all in actual end workloads.
>   
>> +		/* the following section attempts to tweak cpu power based
>> +		 * on current idleness of the threads dynamically at runtime
>> +		 */
>> +		if (idle_count == 2 || idle_count == 3 || idle_count == 4) {
>>     
>
> 		if (idle_count > 1) ? :-)
>   
Yes :)  Originally I had done different weightings for each of the 3 
cases, which gained in some workloads but regressed some others.   But 
since I'm not doing that anymore I'll fold it down to > 1

^ permalink raw reply

* Re: [rtc-linux] [PATCH 05/11] rtc: Add MPC5121 Real time clock driver
From: Alessandro Zummo @ 2010-01-20 22:19 UTC (permalink / raw)
  To: rtc-linux; +Cc: wd, dzu, linuxppc-dev, John Rigby, agust, Piotr Ziecik
In-Reply-To: <1263932653-3634-6-git-send-email-agust@denx.de>

On Tue, 19 Jan 2010 21:24:07 +0100
Anatolij Gustschin <agust@denx.de> wrote:

 Hi,

  thank for you submission. A few comments below. You might
 want to read http://groups.google.com/group/rtc-linux/web/checklist?pli=1

> From: John Rigby <jrigby@freescale.com>
> 
> Based on Domen Puncer's rtc driver for 5200 posted to
> the ppclinux mailing list:
>         http://patchwork.ozlabs.org/linuxppc-embedded/patch?id=11675
> but never commited anywhere.
> 
> Changes to Domen's original:
> 
>     Changed filenames/routine names from mpc5200* to mpc5121*
>     Changed match to only care about compatible and use "fsl,"
>     convention for compatible.
> 
>     Make alarms more sane by dealing with lack of second alarm resolution.
> 
>     Deal with the fact that most of the 5121 rtc registers are not persistent
>     across a reset even with a battery attached:
> 
>         Use actual_time register for time keeping
>         and target_time register as an offset to linux time
> 
>         The target_time register would normally be used for hibernation
>         but hibernation does not work on current silicon 
> Signed-off-by: John Rigby <jcrigby@gmail.com>
> Signed-off-by: Piotr Ziecik <kosmo@semihalf.com>
> Signed-off-by: Wolfgang Denk <wd@denx.de>
> Signed-off-by: Anatolij Gustschin <agust@denx.de>
> Cc: <rtc-linux@googlegroups.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: John Rigby <jcrigby@gmail.com>
> ---
>  drivers/rtc/Kconfig       |   10 +
>  drivers/rtc/Makefile      |    1 +
>  drivers/rtc/rtc-mpc5121.c |  408 +++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 419 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/rtc/rtc-mpc5121.c
> 
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 8167e9e..e51b094 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -868,4 +868,14 @@ config RTC_DRV_MC13783
>  	help
>  	  This enables support for the Freescale MC13783 PMIC RTC
>  
> +config RTC_DRV_MPC5121
> +	tristate "Freescale MPC5121 built-in RTC"
> +	depends on RTC_CLASS
> +	help
> +	  If you say yes here you will get support for the
> +	  built-in RTC MPC5121.
> +
> +	  This driver can also be built as a module. If so, the module
> +	  will be called rtc-mpc5121.
> +
>  endif # RTC_CLASS
> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> index e5160fd..db1dcd4 100644
> --- a/drivers/rtc/Makefile
> +++ b/drivers/rtc/Makefile
> @@ -56,6 +56,7 @@ obj-$(CONFIG_RTC_DRV_MAX6902)	+= rtc-max6902.o
>  obj-$(CONFIG_RTC_DRV_MC13783)	+= rtc-mc13783.o
>  obj-$(CONFIG_RTC_DRV_MSM6242)	+= rtc-msm6242.o
>  obj-$(CONFIG_RTC_DRV_MV)	+= rtc-mv.o
> +obj-$(CONFIG_RTC_DRV_MPC5121)	+= rtc-mpc5121.o
>  obj-$(CONFIG_RTC_DRV_NUC900)	+= rtc-nuc900.o
>  obj-$(CONFIG_RTC_DRV_OMAP)	+= rtc-omap.o
>  obj-$(CONFIG_RTC_DRV_PCAP)	+= rtc-pcap.o
> diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c
> new file mode 100644
> index 0000000..63460cb
> --- /dev/null
> +++ b/drivers/rtc/rtc-mpc5121.c
> @@ -0,0 +1,408 @@
> +/*
> + * Real-time clock driver for MPC5121
> + *
> + * Copyright 2007, Domen Puncer <domen.puncer@telargo.com>
> + * Copyright 2008, Freescale Semiconductor, Inc. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +/*
> + * History:
> + *
> + * Based on mpc5200_rtc.c written by Domen Puncer <domen.puncer@telargo.com>
> + *   posted to linuxppc-embedded mailing list:
> + *     http://patchwork.ozlabs.org/linuxppc-embedded/patch?id=11675
> + *   but never committed to any public tree.
> + *
> + * Author: John Rigby <jrigby@freescale.com>
> + *   Converted to 5121 rtc driver.
> + *
> + *   Make alarms more sane by dealing with lack of second alarm resolution.
> + *
> + *   Use actual_time time register for time keeping since it is persistent
> + *   and the normal rtc registers are not.  Use target_time register as an
> + *   offset to linux time.
> + *
> + */

 The history goes in the changelog. Author(s) name on the top.

> +#include <linux/module.h>
> +#include <linux/rtc.h>
> +#include <linux/of_device.h>
> +#include <linux/of_platform.h>
> +#include <linux/io.h>
> +
> +struct mpc5121_rtc_regs {
> +	u8 set_time;		/* RTC + 0x00 */
> +	u8 hour_set;		/* RTC + 0x01 */
> +	u8 minute_set;		/* RTC + 0x02 */
> +	u8 second_set;		/* RTC + 0x03 */
> +
> +	u8 set_date;		/* RTC + 0x04 */
> +	u8 month_set;		/* RTC + 0x05 */
> +	u8 weekday_set;		/* RTC + 0x06 */
> +	u8 date_set;		/* RTC + 0x07 */
> +
> +	u8 write_sw;		/* RTC + 0x08 */
> +	u8 sw_set;		/* RTC + 0x09 */
> +	u16 year_set;		/* RTC + 0x0a */
> +
> +	u8 alm_enable;		/* RTC + 0x0c */
> +	u8 alm_hour_set;	/* RTC + 0x0d */
> +	u8 alm_min_set;		/* RTC + 0x0e */
> +	u8 int_enable;		/* RTC + 0x0f */
> +
> +	u8 reserved1;
> +	u8 hour;		/* RTC + 0x11 */
> +	u8 minute;		/* RTC + 0x12 */
> +	u8 second;		/* RTC + 0x13 */
> +
> +	u8 month;		/* RTC + 0x14 */
> +	u8 wday_mday;		/* RTC + 0x15 */
> +	u16 year;		/* RTC + 0x16 */
> +
> +	u8 int_alm;		/* RTC + 0x18 */
> +	u8 int_sw;		/* RTC + 0x19 */
> +	u8 alm_status;		/* RTC + 0x1a */
> +	u8 sw_minute;		/* RTC + 0x1b */
> +
> +	u8 bus_error_1;		/* RTC + 0x1c */
> +	u8 int_day;		/* RTC + 0x1d */
> +	u8 int_min;		/* RTC + 0x1e */
> +	u8 int_sec;		/* RTC + 0x1f */
> +
> +	/*
> +	 * target_time:
> +	 *	intended to be used for hibernation but hibernation
> +	 *	does not work on silicon rev 1.5 so use it for non-volatile
> +	 *	storage of offset between the actual_time register and linux
> +	 *	time
> +	 */
> +	u32 target_time;	/* RTC + 0x20 */
> +	/*
> +	 * actual_time:
> +	 * 	readonly time since VBAT_RTC was last connected
> +	 */
> +	u32 actual_time;	/* RTC + 0x24 */
> +	u32 keep_alive;		/* RTC + 0x28 */
> +};
> +
> +struct mpc5121_rtc_data {
> +	unsigned irq;
> +	unsigned irq_periodic;
> +	struct mpc5121_rtc_regs __iomem *regs;
> +	struct rtc_device *rtc;
> +	struct rtc_wkalrm wkalarm;
> +};
> +
> +/*
> + * Update second/minute/hour registers.
> + *
> + * This is just so alarm will work.
> + */
> +static void mpc5121_rtc_update_smh(struct mpc5121_rtc_regs __iomem *regs,
> +	struct rtc_time *tm)
> +{
> +	out_8(&regs->second_set, tm->tm_sec);
> +	out_8(&regs->minute_set, tm->tm_min);
> +	out_8(&regs->hour_set, tm->tm_hour);
> +
> +	/* set time sequence */
> +	out_8(&regs->set_time, 0x1);
> +	out_8(&regs->set_time, 0x3);
> +	out_8(&regs->set_time, 0x1);
> +	out_8(&regs->set_time, 0x0);
> +}
> +
> +static int mpc5121_rtc_read_time(struct device *dev, struct rtc_time *tm)
> +{
> +	struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
> +	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
> +	unsigned long now;
> +
> +	/*
> +	 * linux time is actual_time plus the offset saved in target_time
> +	 */
> +	now = in_be32(&regs->actual_time) + in_be32(&regs->target_time);
> +
> +	rtc_time_to_tm(now, tm);
> +
> +	/*
> +	 * update second minute hour registers
> +	 * so alarms will work
> +	 */
> +	mpc5121_rtc_update_smh(regs, tm);
> +
> +	return 0;
> +}
> +
> +static int mpc5121_rtc_set_time(struct device *dev, struct rtc_time *tm)
> +{
> +	struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
> +	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
> +	int ret;
> +	unsigned long now;
> +
> +
> +	/*
> +	 * The actual_time register is read only so we write the offset
> +	 * between it and linux time to the target_time register.
> +	 */
> +	ret = rtc_tm_to_time(tm, &now);
> +	if (ret == 0)
> +		out_be32(&regs->target_time, now - in_be32(&regs->actual_time));
> +
> +	/*
> +	 * update second minute hour registers
> +	 * so alarms will work
> +	 */
> +	mpc5121_rtc_update_smh(regs, tm);
> +
> +	return 0;
> +}
> +
> +static int mpc5121_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
> +{
> +	struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
> +	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
> +
> +	*alarm = rtc->wkalarm;
> +
> +	alarm->pending = in_8(&regs->alm_status);
> +
> +	return 0;
> +}
> +
> +static int mpc5121_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
> +{
> +	struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
> +	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
> +
> +	/*
> +	 * the alarm has no seconds so deal with it
> +	 */
> +	if (alarm->time.tm_sec) {
> +		alarm->time.tm_sec = 0;
> +		alarm->time.tm_min++;
> +		if (alarm->time.tm_min >= 60) {
> +			alarm->time.tm_min = 0;
> +			alarm->time.tm_hour++;
> +			if (alarm->time.tm_hour >= 24)
> +				alarm->time.tm_hour = 0;
> +		}
> +	}
> +
> +	alarm->time.tm_mday = -1;
> +	alarm->time.tm_mon = -1;
> +	alarm->time.tm_year = -1;
> +
> +	out_8(&regs->alm_min_set, alarm->time.tm_min);
> +	out_8(&regs->alm_hour_set, alarm->time.tm_hour);
> +
> +	out_8(&regs->alm_enable, alarm->enabled);
> +
> +	rtc->wkalarm = *alarm;
> +	return 0;
> +}
> +
> +static irqreturn_t mpc5121_rtc_handler(int irq, void *dev)
> +{
> +	struct mpc5121_rtc_data *rtc = dev_get_drvdata((struct device *)dev);
> +	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
> +
> +	if (in_8(&regs->int_alm)) {
> +		/* acknowledge and clear status */
> +		out_8(&regs->int_alm, 1);
> +		out_8(&regs->alm_status, 1);
> +
> +		rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
> +		return IRQ_HANDLED;
> +	}
> +
> +	return IRQ_NONE;
> +}
> +
> +static irqreturn_t mpc5121_rtc_handler_upd(int irq, void *dev)
> +{
> +	struct mpc5121_rtc_data *rtc = dev_get_drvdata((struct device *)dev);
> +	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
> +
> +	if (in_8(&regs->int_sec) && (in_8(&regs->int_enable) & 0x1)) {
> +		/* acknowledge */
> +		out_8(&regs->int_sec, 1);
> +
> +		rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_UF);
> +		return IRQ_HANDLED;
> +	}
> +
> +	return IRQ_NONE;
> +}
> +
> +static int mpc5121_rtc_ioctl(struct device *dev, unsigned int cmd,
> +							unsigned long arg)
> +{
> +	struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
> +	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
> +
> +	switch (cmd) {
> +		/* alarm interrupt */
> +	case RTC_AIE_ON:
> +		out_8(&regs->alm_enable, 1);
> +		rtc->wkalarm.enabled = 1;
> +		break;
> +	case RTC_AIE_OFF:
> +		out_8(&regs->alm_enable, 0);
> +		rtc->wkalarm.enabled = 0;
> +		break;
> +
> +		/* update interrupt */
> +	case RTC_UIE_ON:
> +		out_8(&regs->int_enable,
> +				(in_8(&regs->int_enable) & ~0x8) | 0x1);
> +		break;
> +	case RTC_UIE_OFF:
> +		out_8(&regs->int_enable, in_8(&regs->int_enable) & ~0x1);
> +		break;
> +
> +		/* no periodic interrupts */
> +	case RTC_IRQP_READ:
> +	case RTC_IRQP_SET:
> +		return -ENOTTY;
> +
> +	default:
> +		return -ENOIOCTLCMD;
> +	}
> +	return 0;
> +}

 please implement the alarm/irq interface vie the ->ops
 structure.


> +
> +static const struct rtc_class_ops mpc5121_rtc_ops = {
> +	.read_time = mpc5121_rtc_read_time,
> +	.set_time = mpc5121_rtc_set_time,
> +	.read_alarm = mpc5121_rtc_read_alarm,
> +	.set_alarm = mpc5121_rtc_set_alarm,
> +	.ioctl = mpc5121_rtc_ioctl,
> +};
> +
> +static int __devinit mpc5121_rtc_probe(struct of_device *op,
> +					const struct of_device_id *match)
> +{
> +	struct mpc5121_rtc_data *rtc;
> +	int err = 0;
> +	u32 ka;
> +
> +	rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
> +	if (!rtc) {
> +		err = -ENOMEM;
> +		goto out;
> +	}

 return -ENOMEM;

> +
> +	rtc->regs = of_iomap(op->node, 0);
> +
 
 extra empty line

> +	if (!rtc->regs) {
> +		printk(KERN_ERR "%s: couldn't map io space\n", __func__);
> +		err = -ENOSYS;
> +		goto out_free;
> +	}
> +
> +	device_init_wakeup(&op->dev, 1);
> +
> +	rtc->rtc = rtc_device_register("mpc5121-rtc", &op->dev,
> +						&mpc5121_rtc_ops, THIS_MODULE);
> +	if (IS_ERR(rtc->rtc)) {
> +		err = PTR_ERR(rtc->rtc);
> +		goto out_unmap;
> +	}
> +
> +	dev_set_drvdata(&op->dev, rtc);
> +
> +	rtc->irq = irq_of_parse_and_map(op->node, 1);
> +	err = request_irq(rtc->irq, mpc5121_rtc_handler, IRQF_DISABLED,
> +						"mpc5121-rtc", &op->dev);
> +	if (err) {
> +		printk(KERN_ERR "%s: could not request irq: %i\n",
> +							__func__, rtc->irq);
> +		goto out_dispose;
> +	}
> +
> +	rtc->irq_periodic = irq_of_parse_and_map(op->node, 0);
> +	err = request_irq(rtc->irq_periodic, mpc5121_rtc_handler_upd,
> +				 IRQF_DISABLED, "mpc5121-rtc_upd", &op->dev);
> +	if (err) {
> +		printk(KERN_ERR "%s: could not request irq: %i\n",
> +						__func__, rtc->irq_periodic);
> +		goto out_dispose2;
> +	}
> +
> +	ka = in_be32(&rtc->regs->keep_alive);
> +	if (ka & 0x02) {
> +		printk(KERN_WARNING
> +			"mpc5121-rtc: Battery or oscillator failure!\n");
> +		out_be32(&rtc->regs->keep_alive, ka);
> +	}
> +
> +	goto out;
> +
> +out_dispose2:
> +	irq_dispose_mapping(rtc->irq_periodic);
> +	free_irq(rtc->irq, &op->dev);
> +out_dispose:
> +	irq_dispose_mapping(rtc->irq);
> +out_unmap:
> +	iounmap(rtc->regs);
> +out_free:
> +	kfree(rtc);
> +out:
> +	return err;
> +}
> +
> +static int __devexit mpc5121_rtc_remove(struct of_device *op)
> +{
> +	struct mpc5121_rtc_data *rtc = dev_get_drvdata(&op->dev);
> +	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
> +
> +	/* disable interrupt, so there are no nasty surprises */
> +	out_8(&regs->alm_enable, 0);
> +	out_8(&regs->int_enable, in_8(&regs->int_enable) & ~0x1);
> +
> +	rtc_device_unregister(rtc->rtc);
> +	iounmap(rtc->regs);
> +	free_irq(rtc->irq, &op->dev);
> +	free_irq(rtc->irq_periodic, &op->dev);
> +	irq_dispose_mapping(rtc->irq);
> +	irq_dispose_mapping(rtc->irq_periodic);
> +	dev_set_drvdata(&op->dev, NULL);
> +	kfree(rtc);
> +
> +	return 0;
> +}
> +
> +static struct of_device_id mpc5121_rtc_match[] = {
> +	{ .compatible = "fsl,mpc5121-rtc", },
> +	{},
> +};
> +
> +static struct of_platform_driver mpc5121_rtc_driver = {
> +	.owner = THIS_MODULE,
> +	.name = "mpc5121-rtc",
> +	.match_table = mpc5121_rtc_match,
> +	.probe = mpc5121_rtc_probe,
> +	.remove = mpc5121_rtc_remove,
> +};
> +
> +static int __init mpc5121_rtc_init(void)
> +{
> +	return of_register_platform_driver(&mpc5121_rtc_driver);
> +}
> +
> +static void __exit mpc5121_rtc_exit(void)
> +{
> +	of_unregister_platform_driver(&mpc5121_rtc_driver);
> +}
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("John Rigby <jrigby@freescale.com>");
> +
> +module_init(mpc5121_rtc_init);
> +module_exit(mpc5121_rtc_exit);
> -- 
> 1.5.6.3
> 


-- 

 Best regards,

 Alessandro Zummo,
  Tower Technologies - Torino, Italy

  http://www.towertech.it

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: implement arch_scale_smt_power for Power7
From: Joel Schopp @ 2010-01-20 22:09 UTC (permalink / raw)
  To: Michael Neuling
  Cc: Ingo Molnar, ego, linuxppc-dev, Peter Zijlstra, linux-kernel
In-Reply-To: <26556.1264021443@neuling.org>


>> +	if (cpu_has_feature(CPU_FTRS_POWER7) && weight == 4) {
>>     
>
> I think we should avoid using cpu_has_feature like this.  It's better to
> create a new feature and add it to POWER7 in the cputable, then check
> for that here.
>
> The way that it is now, I think any CPU that has superset of the POWER7
> features, will be true here.  This is not what we want.
>   
Any ideas for what to call this feature?  ASYM_SMT4 ?
>
>> +	smt_gain /= weight;
>>     
>
> This results in a PPC div, when most of the time it's going to be a
> power of two divide.  You've optimised the divides a few lines above
> this, but not this one.  Some consistency would be good.
>
>   
I can turn that into a conditional branch (case statement) with a shift 
for the common 1,2,4 cases which should cover all procs available today 
falling back to a divide for any theoretical future processors that do 
other numbers of threads.

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: implement arch_scale_smt_power for Power7
From: Michael Neuling @ 2010-01-20 21:58 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: ego, Andreas Herrmann, linux-kernel, Ingo Molnar, linuxppc-dev
In-Reply-To: <1264020517.4283.1117.camel@laptop>

> > On Power7 processors running in SMT4 mode with 2, 3, or 4 idle threads 
> > there is performance benefit to idling the higher numbered threads in
> > the core.  
> 
> So this is an actual performance improvement, not only power savings?

It's primarily a performance improvement.  Any power/energy savings
would be a bonus.  

Mikey

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: implement arch_scale_smt_power for Power7
From: Benjamin Herrenschmidt @ 2010-01-20 21:33 UTC (permalink / raw)
  To: Joel Schopp; +Cc: linux-kernel, Ingo Molnar, linuxppc-dev, Peter Zijlstra, ego
In-Reply-To: <1264017847.5717.132.camel@jschopp-laptop>

On Wed, 2010-01-20 at 14:04 -0600, Joel Schopp wrote:
> On Power7 processors running in SMT4 mode with 2, 3, or 4 idle threads 
> there is performance benefit to idling the higher numbered threads in
> the core.  
> 
> This patch implements arch_scale_smt_power to dynamically update smt
> thread power in these idle cases in order to prefer threads 0,1 over
> threads 2,3 within a core.
> 
> Signed-off-by: Joel Schopp <jschopp@austin.ibm.com>

So I'll leave Peter deal with the scheduler aspects and will focus on
details :-)

> ---
> Index: linux-2.6.git/arch/powerpc/kernel/smp.c
> ===================================================================
> --- linux-2.6.git.orig/arch/powerpc/kernel/smp.c
> +++ linux-2.6.git/arch/powerpc/kernel/smp.c
> @@ -617,3 +617,44 @@ void __cpu_die(unsigned int cpu)
>  		smp_ops->cpu_die(cpu);
>  }
>  #endif
> +
> +static inline int thread_in_smt4core(int x)
> +{
> +  return x % 4;
> +}

Needs a whitespace here though I don't really like the above. Any reason
why you can't use the existing cpu_thread_in_core() ?

> +unsigned long arch_scale_smt_power(struct sched_domain *sd, int cpu)
> +{
> +  int cpu2;
> +  int idle_count = 0;
> +
> +  struct cpumask *cpu_map = sched_domain_span(sd);
> +
> +	unsigned long weight = cpumask_weight(cpu_map);
> +	unsigned long smt_gain = sd->smt_gain;

More whitespace damage above.

> +	if (cpu_has_feature(CPU_FTRS_POWER7) && weight == 4) {
> +		for_each_cpu(cpu2, cpu_map) {
> +			if (idle_cpu(cpu2))
> +				idle_count++;
> +		}

I'm not 100% sure about the use of the CPU feature above. First I wonder
if the right approach is to instead do something like

	if (!cpu_has_feature(...) !! weigth < 4)
		return default_scale_smt_power(sd, cpu);

Though we may be better off using a ppc_md. hook here to avoid
calculating the weight etc... on processors that don't need any
of that.

I also dislike your naming. I would suggest you change cpu_map to
sibling_map() and cpu2 to sibling (or just c). One thing I wonder is how
sure we are that sched_domain_span() is always going to give us the
threads btw ? If we introduce another sched domain level for NUMA
purposes can't we get confused ?

Also, how hot is this code path ?

> +		/* the following section attempts to tweak cpu power based
> +		 * on current idleness of the threads dynamically at runtime
> +		 */
> +		if (idle_count == 2 || idle_count == 3 || idle_count == 4) {

		if (idle_count > 1) ? :-)

> +			if (thread_in_smt4core(cpu) == 0 ||
> +			    thread_in_smt4core(cpu) == 1) {

			int thread = cpu_thread_in_core(cpu);
			if (thread < 2)
				...

> +				/* add 75 % to thread power */
> +				smt_gain += (smt_gain >> 1) + (smt_gain >> 2);
> +			} else {
> +				 /* subtract 75 % to thread power */
> +				smt_gain = smt_gain >> 2;
> +			}
> +		}
> +	}
> +	/* default smt gain is 1178, weight is # of SMT threads */
> +	smt_gain /= weight;
> +
> +	return smt_gain;

Cheers,
Ben.

> +}
> Index: linux-2.6.git/kernel/sched_features.h
> ===================================================================
> --- linux-2.6.git.orig/kernel/sched_features.h
> +++ linux-2.6.git/kernel/sched_features.h
> @@ -107,7 +107,7 @@ SCHED_FEAT(CACHE_HOT_BUDDY, 1)
>  /*
>   * Use arch dependent cpu power functions
>   */
> -SCHED_FEAT(ARCH_POWER, 0)
> +SCHED_FEAT(ARCH_POWER, 1)
>  
>  SCHED_FEAT(HRTICK, 0)
>  SCHED_FEAT(DOUBLE_TICK, 0)
> 

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: implement arch_scale_smt_power for Power7
From: Michael Neuling @ 2010-01-20 21:04 UTC (permalink / raw)
  To: Joel Schopp; +Cc: Ingo Molnar, ego, linuxppc-dev, Peter Zijlstra, linux-kernel
In-Reply-To: <1264017847.5717.132.camel@jschopp-laptop>

> On Power7 processors running in SMT4 mode with 2, 3, or 4 idle threads 
> there is performance benefit to idling the higher numbered threads in
> the core.  
> 
> This patch implements arch_scale_smt_power to dynamically update smt
> thread power in these idle cases in order to prefer threads 0,1 over
> threads 2,3 within a core.
> 
> Signed-off-by: Joel Schopp <jschopp@austin.ibm.com>
> ---
> Index: linux-2.6.git/arch/powerpc/kernel/smp.c
> ===================================================================
> --- linux-2.6.git.orig/arch/powerpc/kernel/smp.c
> +++ linux-2.6.git/arch/powerpc/kernel/smp.c
> @@ -617,3 +617,44 @@ void __cpu_die(unsigned int cpu)
>  		smp_ops->cpu_die(cpu);
>  }
>  #endif
> +
> +static inline int thread_in_smt4core(int x)
> +{
> +  return x % 4;
> +}
> +unsigned long arch_scale_smt_power(struct sched_domain *sd, int cpu)
> +{
> +  int cpu2;
> +  int idle_count = 0;
> +
> +  struct cpumask *cpu_map = sched_domain_span(sd);
> +
> +	unsigned long weight = cpumask_weight(cpu_map);
> +	unsigned long smt_gain = sd->smt_gain;
> +
> +	if (cpu_has_feature(CPU_FTRS_POWER7) && weight == 4) {

I think we should avoid using cpu_has_feature like this.  It's better to
create a new feature and add it to POWER7 in the cputable, then check
for that here.

The way that it is now, I think any CPU that has superset of the POWER7
features, will be true here.  This is not what we want.

> +		for_each_cpu(cpu2, cpu_map) {
> +			if (idle_cpu(cpu2))
> +				idle_count++;
> +		}
> +
> +		/* the following section attempts to tweak cpu power based
> +		 * on current idleness of the threads dynamically at runtime
> +		 */
> +		if (idle_count == 2 || idle_count == 3 || idle_count == 4) {
> +			if (thread_in_smt4core(cpu) == 0 ||
> +			    thread_in_smt4core(cpu) == 1) {
> +				/* add 75 % to thread power */
> +				smt_gain += (smt_gain >> 1) + (smt_gain >> 2);
> +			} else {
> +				 /* subtract 75 % to thread power */
> +				smt_gain = smt_gain >> 2;
> +			}
> +		}
> +	}
> +	/* default smt gain is 1178, weight is # of SMT threads */
> +	smt_gain /= weight;

This results in a PPC div, when most of the time it's going to be a
power of two divide.  You've optimised the divides a few lines above
this, but not this one.  Some consistency would be good.

Mikey

> +
> +	return smt_gain;
> +
> +}
> Index: linux-2.6.git/kernel/sched_features.h
> ===================================================================
> --- linux-2.6.git.orig/kernel/sched_features.h
> +++ linux-2.6.git/kernel/sched_features.h
> @@ -107,7 +107,7 @@ SCHED_FEAT(CACHE_HOT_BUDDY, 1)
>  /*
>   * Use arch dependent cpu power functions
>   */
> -SCHED_FEAT(ARCH_POWER, 0)
> +SCHED_FEAT(ARCH_POWER, 1)
>  
>  SCHED_FEAT(HRTICK, 0)
>  SCHED_FEAT(DOUBLE_TICK, 0)
> 
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
> 

^ permalink raw reply

* Re: [PATCH] powerpc/4xx: Add pcix type 1 transactions
From: Benjamin Herrenschmidt @ 2010-01-20 20:51 UTC (permalink / raw)
  To: Stef van Os; +Cc: linuxppc-dev, felix, sr, fkan, Stef van Os
In-Reply-To: <1263995979-10954-1-git-send-email-stef.van.os@prodrive.nl>

On Wed, 2010-01-20 at 14:59 +0100, Stef van Os wrote:
> Some of the newer 4xx pci cores don't send PCI type 1 transactions.
> This patch enables type 1 transations for pcix nodes, thus enabling
> devices behind PCI bridges.
> 
> Signed-off-by: Stef van Os <stef.van.os@gmail.com>
> ---

Thanks, I'll send that to Linus after LCA.

Cheers,
Ben.

>  arch/powerpc/sysdev/ppc4xx_pci.c |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
> index 6ff9d71..8aa3302 100644
> --- a/arch/powerpc/sysdev/ppc4xx_pci.c
> +++ b/arch/powerpc/sysdev/ppc4xx_pci.c
> @@ -569,7 +569,8 @@ static void __init ppc4xx_probe_pcix_bridge(struct device_node *np)
>  	hose->last_busno = bus_range ? bus_range[1] : 0xff;
>  
>  	/* Setup config space */
> -	setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4, 0);
> +	setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4,
> +					PPC_INDIRECT_TYPE_SET_CFG_TYPE);
>  
>  	/* Disable all windows */
>  	writel(0, reg + PCIX0_POM0SA);
> -- 
> 1.6.6.267.g5b159
> 
> 
> Disclaimer: The information contained in this email, including any attachments is 
> confidential and is for the sole use of the intended recipient(s). Any unauthorized 
> review, use, disclosure or distribution is prohibited. If you are not the intended 
> recipient, please notify the sender immediately by replying to this message and 
> destroy all copies of this message and any attachments.

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: implement arch_scale_smt_power for Power7
From: Peter Zijlstra @ 2010-01-20 20:48 UTC (permalink / raw)
  To: Joel Schopp
  Cc: ego, Andreas Herrmann, linux-kernel, Ingo Molnar, linuxppc-dev
In-Reply-To: <1264017847.5717.132.camel@jschopp-laptop>

On Wed, 2010-01-20 at 14:04 -0600, Joel Schopp wrote:
> On Power7 processors running in SMT4 mode with 2, 3, or 4 idle threads 
> there is performance benefit to idling the higher numbered threads in
> the core.  

So this is an actual performance improvement, not only power savings?

> This patch implements arch_scale_smt_power to dynamically update smt
> thread power in these idle cases in order to prefer threads 0,1 over
> threads 2,3 within a core.
> 
> Signed-off-by: Joel Schopp <jschopp@austin.ibm.com>
> ---
> Index: linux-2.6.git/arch/powerpc/kernel/smp.c
> ===================================================================
> --- linux-2.6.git.orig/arch/powerpc/kernel/smp.c
> +++ linux-2.6.git/arch/powerpc/kernel/smp.c
> @@ -617,3 +617,44 @@ void __cpu_die(unsigned int cpu)
>  		smp_ops->cpu_die(cpu);
>  }
>  #endif
> +
> +static inline int thread_in_smt4core(int x)
> +{
> +  return x % 4;
> +}
> +unsigned long arch_scale_smt_power(struct sched_domain *sd, int cpu)
> +{
> +  int cpu2;
> +  int idle_count = 0;
> +
> +  struct cpumask *cpu_map = sched_domain_span(sd);
> +
> +	unsigned long weight = cpumask_weight(cpu_map);
> +	unsigned long smt_gain = sd->smt_gain;
> +
> +	if (cpu_has_feature(CPU_FTRS_POWER7) && weight == 4) {
> +		for_each_cpu(cpu2, cpu_map) {
> +			if (idle_cpu(cpu2))
> +				idle_count++;
> +		}
> +
> +		/* the following section attempts to tweak cpu power based
> +		 * on current idleness of the threads dynamically at runtime
> +		 */
> +		if (idle_count == 2 || idle_count == 3 || idle_count == 4) {
> +			if (thread_in_smt4core(cpu) == 0 ||
> +			    thread_in_smt4core(cpu) == 1) {
> +				/* add 75 % to thread power */
> +				smt_gain += (smt_gain >> 1) + (smt_gain >> 2);
> +			} else {
> +				 /* subtract 75 % to thread power */
> +				smt_gain = smt_gain >> 2;
> +			}
> +		}
> +	}
> +	/* default smt gain is 1178, weight is # of SMT threads */
> +	smt_gain /= weight;
> +
> +	return smt_gain;
> +
> +}

This looks to suffer significant whitespace damage.

The design goal for smt_power was to be able to actually measure the
processing gains from smt and feed that into the scheduler, not really
placement tricks like this.

Now I also heard AMD might want to have something similar to this,
something to do with powerlines and die layout.

I'm not sure playing games with cpu_power is the best or if simply
moving tasks to lower numbered cpus using an SD_flag is the best
solution for these kinds of things.

> Index: linux-2.6.git/kernel/sched_features.h
> ===================================================================
> --- linux-2.6.git.orig/kernel/sched_features.h
> +++ linux-2.6.git/kernel/sched_features.h
> @@ -107,7 +107,7 @@ SCHED_FEAT(CACHE_HOT_BUDDY, 1)
>  /*
>   * Use arch dependent cpu power functions
>   */
> -SCHED_FEAT(ARCH_POWER, 0)
> +SCHED_FEAT(ARCH_POWER, 1)
>  
>  SCHED_FEAT(HRTICK, 0)
>  SCHED_FEAT(DOUBLE_TICK, 0)

And you just wrecked x86 ;-)

It has an smt_power implementation that tries to measure smt gains using
aperf/mperf, trouble is that this represents the actual performance not
the capacity. This has the problem that when idle it represents 0
capacity and will not attract work.

Coming up with something that actually works there is on the todo list,
I was thinking perhaps temporal maximums from !idle.

So if you want to go with this, you'll need to stub out
arch/x86/kernel/cpu/sched.c

^ permalink raw reply

* [PATCH 2/2] powerpc: implement arch_scale_smt_power for Power7
From: Joel Schopp @ 2010-01-20 20:04 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Ingo Molnar, linuxppc-dev, linux-kernel, ego
In-Reply-To: <1264017638.5717.121.camel@jschopp-laptop>

On Power7 processors running in SMT4 mode with 2, 3, or 4 idle threads 
there is performance benefit to idling the higher numbered threads in
the core.  

This patch implements arch_scale_smt_power to dynamically update smt
thread power in these idle cases in order to prefer threads 0,1 over
threads 2,3 within a core.

Signed-off-by: Joel Schopp <jschopp@austin.ibm.com>
---
Index: linux-2.6.git/arch/powerpc/kernel/smp.c
===================================================================
--- linux-2.6.git.orig/arch/powerpc/kernel/smp.c
+++ linux-2.6.git/arch/powerpc/kernel/smp.c
@@ -617,3 +617,44 @@ void __cpu_die(unsigned int cpu)
 		smp_ops->cpu_die(cpu);
 }
 #endif
+
+static inline int thread_in_smt4core(int x)
+{
+  return x % 4;
+}
+unsigned long arch_scale_smt_power(struct sched_domain *sd, int cpu)
+{
+  int cpu2;
+  int idle_count = 0;
+
+  struct cpumask *cpu_map = sched_domain_span(sd);
+
+	unsigned long weight = cpumask_weight(cpu_map);
+	unsigned long smt_gain = sd->smt_gain;
+
+	if (cpu_has_feature(CPU_FTRS_POWER7) && weight == 4) {
+		for_each_cpu(cpu2, cpu_map) {
+			if (idle_cpu(cpu2))
+				idle_count++;
+		}
+
+		/* the following section attempts to tweak cpu power based
+		 * on current idleness of the threads dynamically at runtime
+		 */
+		if (idle_count == 2 || idle_count == 3 || idle_count == 4) {
+			if (thread_in_smt4core(cpu) == 0 ||
+			    thread_in_smt4core(cpu) == 1) {
+				/* add 75 % to thread power */
+				smt_gain += (smt_gain >> 1) + (smt_gain >> 2);
+			} else {
+				 /* subtract 75 % to thread power */
+				smt_gain = smt_gain >> 2;
+			}
+		}
+	}
+	/* default smt gain is 1178, weight is # of SMT threads */
+	smt_gain /= weight;
+
+	return smt_gain;
+
+}
Index: linux-2.6.git/kernel/sched_features.h
===================================================================
--- linux-2.6.git.orig/kernel/sched_features.h
+++ linux-2.6.git/kernel/sched_features.h
@@ -107,7 +107,7 @@ SCHED_FEAT(CACHE_HOT_BUDDY, 1)
 /*
  * Use arch dependent cpu power functions
  */
-SCHED_FEAT(ARCH_POWER, 0)
+SCHED_FEAT(ARCH_POWER, 1)
 
 SCHED_FEAT(HRTICK, 0)
 SCHED_FEAT(DOUBLE_TICK, 0)

^ permalink raw reply

* [PATCH 1/2] sched: Fix the place where group powers are updated.
From: Joel Schopp @ 2010-01-20 20:02 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Ingo Molnar, linuxppc-dev, linux-kernel, ego
In-Reply-To: <1264017638.5717.121.camel@jschopp-laptop>

From: Gautham R Shenoy <ego@in.ibm.com>

We want to update the sched_group_powers when balance_cpu == this_cpu.

Currently the group powers are updated only if the balance_cpu is the first
CPU in the local group. But balance_cpu = this_cpu could also be the first
idle cpu in the group. Hence fix the place where the group powers are updated.

Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
Signed-off-by: Joel Schopp <jschopp@austin.ibm.com>
---
 kernel/sched.c |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/kernel/sched.c b/kernel/sched.c
index 281da29..5d2a451 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -3721,11 +3721,8 @@ static inline void update_sg_lb_stats(struct sched_domain *sd,
 	unsigned long sum_avg_load_per_task;
 	unsigned long avg_load_per_task;
 
-	if (local_group) {
+	if (local_group)
 		balance_cpu = group_first_cpu(group);
-		if (balance_cpu == this_cpu)
-			update_group_power(sd, this_cpu);
-	}
 
 	/* Tally up the load of all CPUs in the group */
 	sum_avg_load_per_task = avg_load_per_task = 0;
@@ -3773,6 +3770,8 @@ static inline void update_sg_lb_stats(struct sched_domain *sd,
 		return;
 	}
 
+	update_group_power(sd, this_cpu);
+
 	/* Adjust by relative CPU power of the group */
 	sgs->avg_load = (sgs->group_load * SCHED_LOAD_SCALE) / group->cpu_power;
 

^ permalink raw reply related

* [PATCH 0/2] sched: arch_scale_smt_powers
From: Joel Schopp @ 2010-01-20 20:00 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: ego, linux-kernel, Ingo Molnar, linuxppc-dev

The new Power7 processor has 4 way SMT.  This 4 way SMT benefits from
dynamic power updates that arch_scale_smt_power was designed to provide.
The first patch fixes a generic scheduler bug necessary for arch_scale_smt
to properly function.  The second patch implements arch_scale_smt_power 
for powerpc, and in particular for Power7 processors.

---
Gautham R Shenoy (1):
sched: Fix the place where group powers are updated.

Joel Schopp (1):
powerpc: implement arch_scale_smt_power for Power7

 arch/powerpc/kernel/smp.c |   41 +++++++++++++++++++++++++++++++++++++++++
 kernel/sched.c            |    7 +++----
 kernel/sched_features.h   |    2 +-
 3 files changed, 45 insertions(+), 5 deletions(-)

^ permalink raw reply

* Re: fsl upm NAND Flash issue without GPIO chip handler
From: Scott Wood @ 2010-01-20 18:39 UTC (permalink / raw)
  To: nanda; +Cc: linuxppc-dev, avorontsov
In-Reply-To: <1263921085.S.3173.3591.f5mail-147-110.rediffmail.com.old.1264011068.46402@webmail.rediffmail.com>

nanda wrote:
> my response inlined..
> 
> On Tue, 19 Jan 2010 22:41:25 +0530 wrote
>  >nanda wrote:
>  >
>  > We had merged the 2.6.24
> 
> That's pretty old...
>  >> We were using 2.6.24 as this kernel version this is the references 
> used by us for MPC8321E.
>  > with the FSL based NAND driver,
> 
> Which one? Which chip are you using, and how is NAND attached to it?
>  >> MPC8321E processor connected to STM NAND Flash. Port C PIN 15 of the 
> processor connected to the R/B# ( Ready/Busy PIN) of the STM NAND Flash.

And the other pins are connected to the local bus controller via UPM?

This is supported in the upstream kernel by drivers/mtd/nand/fsl_upm.c, 
if there's nothing else keeping you on the BSP kernel.

>  > we observed that gpio library is mandatory to be included. We have 
> not included the
>  > gpios configured in the dts file as the we don’t have the separate GPIO
>  > chip(arch/powepc/boot/dts/board.dts).
> 
> What separate GPIO chip? Which "board.dts" are you looking at?
>  >> dts file I was refering is mpc832x_rdb.dts file, which we assumed 
> that GPIO controller is not required. ( Correct me if my assumption is 
> correct)

The only gpio controller in that dts file is the SoC's GPIO block (not a 
separate "GPIO chip").  Specifically, it's port D; you'll want to add a 
node for port C.

>  > After executing the image in the board, we observed the below
>  > 1) The device ID and manufacture Id was printed as "c0" and "c0" and the
>  > error message "No NAND device found!!!". Does it mean it is not
>  > accessing the NAND flash and the values read are junk one?
>  > 2) Processor of the board doesn’t connect the Ready/Busy of the NAND
>  > flash through the separate GPIO chip. I mean it is directly connected
>  > from GPIO Port C of PIN 15 to the Ready/Busy PIN of the NAND flash.
>  > Hence is it necessary to port the gpio specific functions like
>  > gpio_request/gpio_free(specified in fsl_upm.c file), instead should we
>  > need to configure the PIN par_io_config_pin() for configuration of the
>  > PORT C with 15th PIN and set the data value using par_io_data_set()
>  > (specified arch/powerpc/sysdev/qe_lib/qe_io.c)
> 
> Have you tried pointing the "gpios" property at pin 15 of port C? The
> whole point of this abstraction is that these connections are described
> in the data, not in the code.
>  >> Iam not sure how to specify the in the mpc832x_rdb.dts for the pin 
> 15 port C of the MPc8321E processor.

It should look like port B/E in the 836x_rdk dts, except you want reg to 
point at the port C registers.

For details, see the following binding documents: 
Documentation/powerpc/dts-bindings/gpio/gpio.txt
Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/par_io.txt
Documentation/powerpc/dts-bindings/fsl/upm-nand.txt

-Scott

^ permalink raw reply

* Re: Re: fsl upm NAND Flash issue without GPIO chip handler
From: nanda @ 2010-01-20 18:11 UTC (permalink / raw)
  To: scottwood; +Cc: linuxppc-dev, avorontsov

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

my response inlined..

On Tue, 19 Jan 2010 22:41:25 +0530  wrote
>nanda wrote:
> 
> We had merged the 2.6.24 

That's pretty old...
>> We were using 2.6.24 as this kernel version this is the references used by us for MPC8321E.
> with the FSL based NAND driver,

Which one? Which chip are you using, and how is NAND attached to it?
>> MPC8321E processor connected to STM NAND Flash. Port C PIN 15 of the processor connected to the R/B# ( Ready/Busy PIN) of the STM NAND Flash. 

> we observed that gpio library is mandatory to be included. We have not included the 
> gpios configured in the dts file as the we don’t have the separate GPIO 
> chip(arch/powepc/boot/dts/board.dts).

What separate GPIO chip? Which "board.dts" are you looking at?
>> dts file I was refering is mpc832x_rdb.dts file, which we assumed that GPIO controller is not required. ( Correct me if my assumption is correct)  

> After executing the image in the board, we observed the below
> 1) The device ID and manufacture Id was printed as "c0" and "c0" and the 
> error message "No NAND device found!!!". Does it mean it is not 
> accessing the NAND flash and the values read are junk one?
> 2) Processor of the board doesn’t connect the Ready/Busy of the NAND 
> flash through the separate GPIO chip. I mean it is directly connected 
> from GPIO Port C of PIN 15 to the Ready/Busy PIN of the NAND flash. 
> Hence is it necessary to port the gpio specific functions like 
> gpio_request/gpio_free(specified in fsl_upm.c file), instead should we 
> need to configure the PIN par_io_config_pin() for configuration of the 
> PORT C with 15th PIN and set the data value using par_io_data_set() 
> (specified arch/powerpc/sysdev/qe_lib/qe_io.c)

Have you tried pointing the "gpios" property at pin 15 of port C? The 
whole point of this abstraction is that these connections are described 
in the data, not in the code.
>> Iam not sure how to specify the  in the mpc832x_rdb.dts for the pin 15 port C of the MPc8321E processor. Please help us on the same.
Some reference which I made was mpc836x_rdk.dts file which mandates the GPIO controller, hence I felt not required(Correct me if Iam wrong)

-Nanda

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

^ permalink raw reply

* Re: [PATCH 01/11] fs_enet: Add support for MPC512x to fs_enet driver
From: Scott Wood @ 2010-01-20 17:02 UTC (permalink / raw)
  To: Anatolij Gustschin
  Cc: Piotr Ziecik, dzu, netdev, linuxppc-dev, John Rigby, wd
In-Reply-To: <20100120122058.1539412b@wker>

Anatolij Gustschin wrote:
> Scott Wood <scottwood@freescale.com> wrote:
>> You can put a data pointer in the of_platform match struct, instead of 
>> re-checking the compatible.
> 
> .data pointer in 'fs_enet_mdio_fec_match' is already used for
> mpc5xxx_get_bus_frequency(). Setting .data to some sort of FEC ID in
> match struct for "fsl,pq1-fec-mdio" would be confusing to.

You could point .data to a struct if there are multiple things.

-Scott

^ permalink raw reply

* Freescale RapidIO controller shortcomings, memory access and DMA support
From: Alex Dubov @ 2010-01-20 14:46 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: zw

Greetings.=0A=0AI'm currently involved in a project which aims to use a Rap=
idIO fabric as,=0Aessentially, a cluster interconnect. That is, our system =
contains a=0Amultitude of processing elements, rather than a host + some du=
mb=0Aperipherals.=0A=0AUnfortunately, it appears that Freescale's rapidio c=
ontroller is not well=0Asuited for this kind of use and the situation doesn=
't seem to get any=0Abetter in new chips. Just for the sake of general rant=
, I shall mention=0Athe missing functionality:=0A=0A1. Support for sending/=
receiving raw RIO packets - could be used to emulate=0Aall the necessary fe=
atures in software, if it was available.=0A=0A2. Support for indirect descr=
iptors in inbound message queue, akin to the=0Aone in outbound. It will all=
ow not to waste tons of space in the incoming=0Amessage buffer, and, even m=
ore important, will allow for Source ID based=0Amessage dispatch. Frankly, =
I don't understand what RIO core designers were=0Athinking - piling of prot=
ocol layers on top of RIO messages is not a good=0Aidea (and piling the who=
le Ethernet + friends protocol stack over there is=0Aeven worse).=0A=0A3. P=
roper IO TLB would be nice, but even without it there are accepted ways=0At=
o manage DMA from peripherals without reverting to overly complex hw=0Asche=
mes. After all, it won't be a big deal for a controller to support=0Aout-of=
-memory interrupt event, which would allow managing of DMA transfers=0Ain c=
oncurrent fashion, leading to a true zero-copy IO.=0A=0A4. Related to the p=
revious point, there's no control, nor indication about=0Awhich message siz=
es are actually used for outbound window originated=0Atransactions. Sending=
 16 bytes of actual phy data for each 4 processor=0Abytes can be a little b=
it wasteful (I hope, that there's some buffering=0Agoing on, but absence of=
 control is depressing).=0A=0A--- end of the rant ---=0A=0AI understand, th=
at Zhang Wei and Li Yang did some work in the direction=0Aof memory mapped =
RIO access. Therefore, I wonder: what is the final fate=0Aof their submissi=
on? Is there some sort of summary, what functionality=0Ahad been added and =
how was it envisaged to be used from user space?=0A=0AI'm currently working=
 on a fork of rapidio subsystem, which I intend to=0Abring to a feature com=
pleteness as far as possible (given the shortcoming=0Aabove) and use it as =
a cluster interconnect. I don't want to step on other=0Apeople's rakes and =
I would like a good cluster functionality support=0Amerged eventually into =
the mainline kernel, so any feedback is very=0Amuch appreciated.=0A=0A=0A=
=0A      __________________________________________________________________=
________________=0ASee what's on at the movies in your area. Find out now: =
http://au.movies.yahoo.com/session-times/

^ permalink raw reply

* [PATCH] powerpc/4xx: Add pcix type 1 transactions
From: Stef van Os @ 2010-01-20 13:59 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Stef van Os, felix, fkan, Stef van Os, sr

U29tZSBvZiB0aGUgbmV3ZXIgNHh4IHBjaSBjb3JlcyBkb24ndCBzZW5kIFBDSSB0eXBlIDEgdHJh
bnNhY3Rpb25zLg0KVGhpcyBwYXRjaCBlbmFibGVzIHR5cGUgMSB0cmFuc2F0aW9ucyBmb3IgcGNp
eCBub2RlcywgdGh1cyBlbmFibGluZw0KZGV2aWNlcyBiZWhpbmQgUENJIGJyaWRnZXMuDQoNClNp
Z25lZC1vZmYtYnk6IFN0ZWYgdmFuIE9zIDxzdGVmLnZhbi5vc0BnbWFpbC5jb20+DQotLS0NCiBh
cmNoL3Bvd2VycGMvc3lzZGV2L3BwYzR4eF9wY2kuYyB8ICAgIDMgKystDQogMSBmaWxlcyBjaGFu
Z2VkLCAyIGluc2VydGlvbnMoKyksIDEgZGVsZXRpb25zKC0pDQoNCmRpZmYgLS1naXQgYS9hcmNo
L3Bvd2VycGMvc3lzZGV2L3BwYzR4eF9wY2kuYyBiL2FyY2gvcG93ZXJwYy9zeXNkZXYvcHBjNHh4
X3BjaS5jDQppbmRleCA2ZmY5ZDcxLi44YWEzMzAyIDEwMDY0NA0KLS0tIGEvYXJjaC9wb3dlcnBj
L3N5c2Rldi9wcGM0eHhfcGNpLmMNCisrKyBiL2FyY2gvcG93ZXJwYy9zeXNkZXYvcHBjNHh4X3Bj
aS5jDQpAQCAtNTY5LDcgKzU2OSw4IEBAIHN0YXRpYyB2b2lkIF9faW5pdCBwcGM0eHhfcHJvYmVf
cGNpeF9icmlkZ2Uoc3RydWN0IGRldmljZV9ub2RlICpucCkNCiAJaG9zZS0+bGFzdF9idXNubyA9
IGJ1c19yYW5nZSA/IGJ1c19yYW5nZVsxXSA6IDB4ZmY7DQogDQogCS8qIFNldHVwIGNvbmZpZyBz
cGFjZSAqLw0KLQlzZXR1cF9pbmRpcmVjdF9wY2koaG9zZSwgcnNyY19jZmcuc3RhcnQsIHJzcmNf
Y2ZnLnN0YXJ0ICsgMHg0LCAwKTsNCisJc2V0dXBfaW5kaXJlY3RfcGNpKGhvc2UsIHJzcmNfY2Zn
LnN0YXJ0LCByc3JjX2NmZy5zdGFydCArIDB4NCwNCisJCQkJCVBQQ19JTkRJUkVDVF9UWVBFX1NF
VF9DRkdfVFlQRSk7DQogDQogCS8qIERpc2FibGUgYWxsIHdpbmRvd3MgKi8NCiAJd3JpdGVsKDAs
IHJlZyArIFBDSVgwX1BPTTBTQSk7DQotLSANCjEuNi42LjI2Ny5nNWIxNTkNCg0KDQpEaXNjbGFp
bWVyOiBUaGUgaW5mb3JtYXRpb24gY29udGFpbmVkIGluIHRoaXMgZW1haWwsIGluY2x1ZGluZyBh
bnkgYXR0YWNobWVudHMgaXMgDQpjb25maWRlbnRpYWwgYW5kIGlzIGZvciB0aGUgc29sZSB1c2Ug
b2YgdGhlIGludGVuZGVkIHJlY2lwaWVudChzKS4gQW55IHVuYXV0aG9yaXplZCANCnJldmlldywg
dXNlLCBkaXNjbG9zdXJlIG9yIGRpc3RyaWJ1dGlvbiBpcyBwcm9oaWJpdGVkLiBJZiB5b3UgYXJl
IG5vdCB0aGUgaW50ZW5kZWQgDQpyZWNpcGllbnQsIHBsZWFzZSBub3RpZnkgdGhlIHNlbmRlciBp
bW1lZGlhdGVseSBieSByZXBseWluZyB0byB0aGlzIG1lc3NhZ2UgYW5kIA0KZGVzdHJveSBhbGwg
Y29waWVzIG9mIHRoaXMgbWVzc2FnZSBhbmQgYW55IGF0dGFjaG1lbnRzLg==

^ permalink raw reply

* Re: linux-next: kvm tree build warning
From: Stephen Rothwell @ 2010-01-20 13:01 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Marcelo Tosatti, ppc-dev, linux-next, Avi Kivity, linux-kernel
In-Reply-To: <3727B46C-0197-47A4-AF41-023517C15752@suse.de>

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

Hi Alex,

On Wed, 20 Jan 2010 11:42:28 +0100 Alexander Graf <agraf@suse.de> wrote:
>
> This is odd. The same function saves and restores ext_bkp.vrsave under a common condition:
> 
> So there can't be a case where ext_bkp.vrsave is read, but not written to before, which is what this warning implies, right?

Right.

> Also, why doesn't gcc complain about vscr too then? They're both used in the very same if statement.

I have no idea how gcc makes these decisions. :-(

> Additionally, while compiling locally I looked for warnings and didn't spot any. So apparently our compiler versions / options don't match. Which version of gcc are you using? I assume a gcc bug.
> 
> $ gcc --version
> gcc (SUSE Linux) 4.3.2 [gcc-4_3-branch revision 141291]

I use a 4.4.0 cross compiler (I should update it).
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ 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