LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* qe: change qe_setbrg() to take an enum qe_clock instead of an integer
From: Timur Tabi @ 2007-11-29 21:56 UTC (permalink / raw)
  To: linuxppc-dev, galak; +Cc: Timur Tabi

qe_setbrg() currently takes an integer to indicate the BRG number.  Change that
to take an enum qe_clock instead, since this enum is intended to represent
clock sources.

Signed-off-by: Timur Tabi <timur@freescale.com>
---

This patch applies to Kumar's for-2.6.25 branch.  You might need to apply my
other patch, "qe: fix device tree lookup code in qe_muram_init()", first.

It's safe to change the parameters to qe_setbrg() because no one is using that
function yet.

 arch/powerpc/sysdev/qe_lib/qe.c |   12 +++--
 include/asm-powerpc/qe.h        |   94 +++++++++++++++++++-------------------
 2 files changed, 54 insertions(+), 52 deletions(-)

diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 298e073..8ef4690 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -167,19 +167,20 @@ unsigned int get_brg_clk(void)
 
 /* Program the BRG to the given sampling rate and multiplier
  *
- * @brg: the BRG, 1-16
+ * @brg: the BRG, QE_BRG1 - QE_BRG16
  * @rate: the desired sampling rate
  * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or
  * GUMR_L[TDCR].  E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01,
  * then 'multiplier' should be 8.
- *
- * Also note that the value programmed into the BRGC register must be even.
  */
-void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier)
+void qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
 {
 	u32 divisor, tempval;
 	u32 div16 = 0;
 
+	if ((brg < QE_BRG1) || (brg > QE_BRG16))
+		return;
+
 	divisor = get_brg_clk() / (rate * multiplier);
 
 	if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
@@ -196,8 +197,9 @@ void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier)
 	tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
 		QE_BRGC_ENABLE | div16;
 
-	out_be32(&qe_immr->brg.brgc[brg - 1], tempval);
+	out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval);
 }
+EXPORT_SYMBOL(qe_setbrg);
 
 /* Initialize SNUMs (thread serial numbers) according to
  * QE Module Control chapter, SNUM table
diff --git a/include/asm-powerpc/qe.h b/include/asm-powerpc/qe.h
index 0dabe46..c779033 100644
--- a/include/asm-powerpc/qe.h
+++ b/include/asm-powerpc/qe.h
@@ -28,6 +28,52 @@
 #define MEM_PART_SECONDARY	1
 #define MEM_PART_MURAM		2
 
+/* Clocks and BRGs */
+enum qe_clock {
+	QE_CLK_NONE = 0,
+	QE_BRG1,		/* Baud Rate Generator 1 */
+	QE_BRG2,		/* Baud Rate Generator 2 */
+	QE_BRG3,		/* Baud Rate Generator 3 */
+	QE_BRG4,		/* Baud Rate Generator 4 */
+	QE_BRG5,		/* Baud Rate Generator 5 */
+	QE_BRG6,		/* Baud Rate Generator 6 */
+	QE_BRG7,		/* Baud Rate Generator 7 */
+	QE_BRG8,		/* Baud Rate Generator 8 */
+	QE_BRG9,		/* Baud Rate Generator 9 */
+	QE_BRG10,		/* Baud Rate Generator 10 */
+	QE_BRG11,		/* Baud Rate Generator 11 */
+	QE_BRG12,		/* Baud Rate Generator 12 */
+	QE_BRG13,		/* Baud Rate Generator 13 */
+	QE_BRG14,		/* Baud Rate Generator 14 */
+	QE_BRG15,		/* Baud Rate Generator 15 */
+	QE_BRG16,		/* Baud Rate Generator 16 */
+	QE_CLK1,		/* Clock 1 */
+	QE_CLK2,		/* Clock 2 */
+	QE_CLK3,		/* Clock 3 */
+	QE_CLK4,		/* Clock 4 */
+	QE_CLK5,		/* Clock 5 */
+	QE_CLK6,		/* Clock 6 */
+	QE_CLK7,		/* Clock 7 */
+	QE_CLK8,		/* Clock 8 */
+	QE_CLK9,		/* Clock 9 */
+	QE_CLK10,		/* Clock 10 */
+	QE_CLK11,		/* Clock 11 */
+	QE_CLK12,		/* Clock 12 */
+	QE_CLK13,		/* Clock 13 */
+	QE_CLK14,		/* Clock 14 */
+	QE_CLK15,		/* Clock 15 */
+	QE_CLK16,		/* Clock 16 */
+	QE_CLK17,		/* Clock 17 */
+	QE_CLK18,		/* Clock 18 */
+	QE_CLK19,		/* Clock 19 */
+	QE_CLK20,		/* Clock 20 */
+	QE_CLK21,		/* Clock 21 */
+	QE_CLK22,		/* Clock 22 */
+	QE_CLK23,		/* Clock 23 */
+	QE_CLK24,		/* Clock 24 */
+	QE_CLK_DUMMY
+};
+
 /* Export QE common operations */
 extern void qe_reset(void);
 extern int par_io_init(struct device_node *np);
@@ -38,7 +84,7 @@ extern int par_io_data_set(u8 port, u8 pin, u8 val);
 
 /* QE internal API */
 int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input);
-void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier);
+void qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier);
 int qe_get_snum(void);
 void qe_put_snum(u8 snum);
 unsigned long qe_muram_alloc(int size, int align);
@@ -129,52 +175,6 @@ enum comm_dir {
 	COMM_DIR_RX_AND_TX = 3
 };
 
-/* Clocks and BRGs */
-enum qe_clock {
-	QE_CLK_NONE = 0,
-	QE_BRG1,		/* Baud Rate Generator 1 */
-	QE_BRG2,		/* Baud Rate Generator 2 */
-	QE_BRG3,		/* Baud Rate Generator 3 */
-	QE_BRG4,		/* Baud Rate Generator 4 */
-	QE_BRG5,		/* Baud Rate Generator 5 */
-	QE_BRG6,		/* Baud Rate Generator 6 */
-	QE_BRG7,		/* Baud Rate Generator 7 */
-	QE_BRG8,		/* Baud Rate Generator 8 */
-	QE_BRG9,		/* Baud Rate Generator 9 */
-	QE_BRG10,		/* Baud Rate Generator 10 */
-	QE_BRG11,		/* Baud Rate Generator 11 */
-	QE_BRG12,		/* Baud Rate Generator 12 */
-	QE_BRG13,		/* Baud Rate Generator 13 */
-	QE_BRG14,		/* Baud Rate Generator 14 */
-	QE_BRG15,		/* Baud Rate Generator 15 */
-	QE_BRG16,		/* Baud Rate Generator 16 */
-	QE_CLK1,		/* Clock 1 */
-	QE_CLK2,		/* Clock 2 */
-	QE_CLK3,		/* Clock 3 */
-	QE_CLK4,		/* Clock 4 */
-	QE_CLK5,		/* Clock 5 */
-	QE_CLK6,		/* Clock 6 */
-	QE_CLK7,		/* Clock 7 */
-	QE_CLK8,		/* Clock 8 */
-	QE_CLK9,		/* Clock 9 */
-	QE_CLK10,		/* Clock 10 */
-	QE_CLK11,		/* Clock 11 */
-	QE_CLK12,		/* Clock 12 */
-	QE_CLK13,		/* Clock 13 */
-	QE_CLK14,		/* Clock 14 */
-	QE_CLK15,		/* Clock 15 */
-	QE_CLK16,		/* Clock 16 */
-	QE_CLK17,		/* Clock 17 */
-	QE_CLK18,		/* Clock 18 */
-	QE_CLK19,		/* Clock 19 */
-	QE_CLK20,		/* Clock 20 */
-	QE_CLK21,		/* Clock 21 */
-	QE_CLK22,		/* Clock 22 */
-	QE_CLK23,		/* Clock 23 */
-	QE_CLK24,		/* Clock 24 */
-	QE_CLK_DUMMY,
-};
-
 /* QE CMXUCR Registers.
  * There are two UCCs represented in each of the four CMXUCR registers.
  * These values are for the UCC in the LSBs
-- 
1.5.2.4

^ permalink raw reply related

* Re: qe: change qe_setbrg() to take an enum qe_clock instead of an integer
From: Kumar Gala @ 2007-11-29 22:45 UTC (permalink / raw)
  To: Timur Tabi; +Cc: linuxppc-dev
In-Reply-To: <1196373406380-git-send-email-timur@freescale.com>


On Nov 29, 2007, at 3:56 PM, Timur Tabi wrote:

> qe_setbrg() currently takes an integer to indicate the BRG number.   
> Change that
> to take an enum qe_clock instead, since this enum is intended to  
> represent
> clock sources.
>
> Signed-off-by: Timur Tabi <timur@freescale.com>
> ---
>
> This patch applies to Kumar's for-2.6.25 branch.  You might need to  
> apply my
> other patch, "qe: fix device tree lookup code in qe_muram_init()",  
> first.
>
> It's safe to change the parameters to qe_setbrg() because no one is  
> using that
> function yet.
>
> arch/powerpc/sysdev/qe_lib/qe.c |   12 +++--
> include/asm-powerpc/qe.h        |   94 ++++++++++++++++++ 
> +-------------------
> 2 files changed, 54 insertions(+), 52 deletions(-)
>
> diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/ 
> qe_lib/qe.c
> index 298e073..8ef4690 100644
> --- a/arch/powerpc/sysdev/qe_lib/qe.c
> +++ b/arch/powerpc/sysdev/qe_lib/qe.c
> @@ -167,19 +167,20 @@ unsigned int get_brg_clk(void)
>
> /* Program the BRG to the given sampling rate and multiplier
>  *
> - * @brg: the BRG, 1-16
> + * @brg: the BRG, QE_BRG1 - QE_BRG16
>  * @rate: the desired sampling rate
>  * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or
>  * GUMR_L[TDCR].  E.g., if this BRG is the RX clock, and  
> GUMR_L[RDCR]=01,
>  * then 'multiplier' should be 8.
> - *
> - * Also note that the value programmed into the BRGC register must  
> be even.
>  */
> -void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int  
> multiplier)
> +void qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int  
> multiplier)
> {
> 	u32 divisor, tempval;
> 	u32 div16 = 0;
>
> +	if ((brg < QE_BRG1) || (brg > QE_BRG16))
> +		return;

seems like we should report some form of error like -EINVAL instead.

>
> +
> 	divisor = get_brg_clk() / (rate * multiplier);
>
> 	if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
> @@ -196,8 +197,9 @@ void qe_setbrg(unsigned int brg, unsigned int  
> rate, unsigned int multiplier)
> 	tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
> 		QE_BRGC_ENABLE | div16;
>
> -	out_be32(&qe_immr->brg.brgc[brg - 1], tempval);
> +	out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval);
> }
> +EXPORT_SYMBOL(qe_setbrg);
>
> /* Initialize SNUMs (thread serial numbers) according to
>  * QE Module Control chapter, SNUM table

- k

^ permalink raw reply

* Re: qe: fix device tree lookup code in qe_muram_init()
From: Kumar Gala @ 2007-11-29 22:54 UTC (permalink / raw)
  To: Timur Tabi; +Cc: linuxppc-dev
In-Reply-To: <11963681602431-git-send-email-timur@freescale.com>


On Nov 29, 2007, at 2:29 PM, Timur Tabi wrote:

> Function qe_muram_init() was only looking for a node called "data- 
> only",
> instead of making sure it is the correct node.  This patch modifies
> qe_muram_init() to find the QE node first, then the MURAM node  
> inside it,
> and then the data-only node.  It also reports errors.
>
> Signed-off-by: Timur Tabi <timur@freescale.com>
> ---
> arch/powerpc/sysdev/qe_lib/qe.c |   39 ++++++++++++++++++++++++++++++ 
> +--------
> 1 files changed, 31 insertions(+), 8 deletions(-)

Add a compatible property in the muram data-only node called "fsl,qe- 
muram-data" and match on that compatible to find the node instead of  
walking the tree like you are. And report an error if there isn't a  
'fsl,qe-muram-data' node

- k

^ permalink raw reply

* [PATCH v2] qe: change qe_setbrg() to take an enum qe_clock instead of an integer
From: Timur Tabi @ 2007-11-29 23:26 UTC (permalink / raw)
  To: linuxppc-dev, galak; +Cc: Timur Tabi

qe_setbrg() currently takes an integer to indicate the BRG number.  Change that
to take an enum qe_clock instead, since this enum is intended to represent
clock sources.

Signed-off-by: Timur Tabi <timur@freescale.com>
---

This patch applies to Kumar's for-2.6.25 branch.  You might need to apply my
other patch, "qe: fix device tree lookup code in qe_muram_init()", first.

It's safe to change the parameters to qe_setbrg() because no one is using that
function yet.

 arch/powerpc/sysdev/qe_lib/qe.c |   14 ++++--
 include/asm-powerpc/qe.h        |   94 +++++++++++++++++++-------------------
 2 files changed, 56 insertions(+), 52 deletions(-)

diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 298e073..f26bc0c 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -167,19 +167,20 @@ unsigned int get_brg_clk(void)
 
 /* Program the BRG to the given sampling rate and multiplier
  *
- * @brg: the BRG, 1-16
+ * @brg: the BRG, QE_BRG1 - QE_BRG16
  * @rate: the desired sampling rate
  * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or
  * GUMR_L[TDCR].  E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01,
  * then 'multiplier' should be 8.
- *
- * Also note that the value programmed into the BRGC register must be even.
  */
-void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier)
+int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
 {
 	u32 divisor, tempval;
 	u32 div16 = 0;
 
+	if ((brg < QE_BRG1) || (brg > QE_BRG16))
+		return -EINVAL;
+
 	divisor = get_brg_clk() / (rate * multiplier);
 
 	if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
@@ -196,8 +197,11 @@ void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier)
 	tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
 		QE_BRGC_ENABLE | div16;
 
-	out_be32(&qe_immr->brg.brgc[brg - 1], tempval);
+	out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval);
+
+	return 0;
 }
+EXPORT_SYMBOL(qe_setbrg);
 
 /* Initialize SNUMs (thread serial numbers) according to
  * QE Module Control chapter, SNUM table
diff --git a/include/asm-powerpc/qe.h b/include/asm-powerpc/qe.h
index 0dabe46..bcf60be 100644
--- a/include/asm-powerpc/qe.h
+++ b/include/asm-powerpc/qe.h
@@ -28,6 +28,52 @@
 #define MEM_PART_SECONDARY	1
 #define MEM_PART_MURAM		2
 
+/* Clocks and BRGs */
+enum qe_clock {
+	QE_CLK_NONE = 0,
+	QE_BRG1,		/* Baud Rate Generator 1 */
+	QE_BRG2,		/* Baud Rate Generator 2 */
+	QE_BRG3,		/* Baud Rate Generator 3 */
+	QE_BRG4,		/* Baud Rate Generator 4 */
+	QE_BRG5,		/* Baud Rate Generator 5 */
+	QE_BRG6,		/* Baud Rate Generator 6 */
+	QE_BRG7,		/* Baud Rate Generator 7 */
+	QE_BRG8,		/* Baud Rate Generator 8 */
+	QE_BRG9,		/* Baud Rate Generator 9 */
+	QE_BRG10,		/* Baud Rate Generator 10 */
+	QE_BRG11,		/* Baud Rate Generator 11 */
+	QE_BRG12,		/* Baud Rate Generator 12 */
+	QE_BRG13,		/* Baud Rate Generator 13 */
+	QE_BRG14,		/* Baud Rate Generator 14 */
+	QE_BRG15,		/* Baud Rate Generator 15 */
+	QE_BRG16,		/* Baud Rate Generator 16 */
+	QE_CLK1,		/* Clock 1 */
+	QE_CLK2,		/* Clock 2 */
+	QE_CLK3,		/* Clock 3 */
+	QE_CLK4,		/* Clock 4 */
+	QE_CLK5,		/* Clock 5 */
+	QE_CLK6,		/* Clock 6 */
+	QE_CLK7,		/* Clock 7 */
+	QE_CLK8,		/* Clock 8 */
+	QE_CLK9,		/* Clock 9 */
+	QE_CLK10,		/* Clock 10 */
+	QE_CLK11,		/* Clock 11 */
+	QE_CLK12,		/* Clock 12 */
+	QE_CLK13,		/* Clock 13 */
+	QE_CLK14,		/* Clock 14 */
+	QE_CLK15,		/* Clock 15 */
+	QE_CLK16,		/* Clock 16 */
+	QE_CLK17,		/* Clock 17 */
+	QE_CLK18,		/* Clock 18 */
+	QE_CLK19,		/* Clock 19 */
+	QE_CLK20,		/* Clock 20 */
+	QE_CLK21,		/* Clock 21 */
+	QE_CLK22,		/* Clock 22 */
+	QE_CLK23,		/* Clock 23 */
+	QE_CLK24,		/* Clock 24 */
+	QE_CLK_DUMMY
+};
+
 /* Export QE common operations */
 extern void qe_reset(void);
 extern int par_io_init(struct device_node *np);
@@ -38,7 +84,7 @@ extern int par_io_data_set(u8 port, u8 pin, u8 val);
 
 /* QE internal API */
 int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input);
-void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier);
+int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier);
 int qe_get_snum(void);
 void qe_put_snum(u8 snum);
 unsigned long qe_muram_alloc(int size, int align);
@@ -129,52 +175,6 @@ enum comm_dir {
 	COMM_DIR_RX_AND_TX = 3
 };
 
-/* Clocks and BRGs */
-enum qe_clock {
-	QE_CLK_NONE = 0,
-	QE_BRG1,		/* Baud Rate Generator 1 */
-	QE_BRG2,		/* Baud Rate Generator 2 */
-	QE_BRG3,		/* Baud Rate Generator 3 */
-	QE_BRG4,		/* Baud Rate Generator 4 */
-	QE_BRG5,		/* Baud Rate Generator 5 */
-	QE_BRG6,		/* Baud Rate Generator 6 */
-	QE_BRG7,		/* Baud Rate Generator 7 */
-	QE_BRG8,		/* Baud Rate Generator 8 */
-	QE_BRG9,		/* Baud Rate Generator 9 */
-	QE_BRG10,		/* Baud Rate Generator 10 */
-	QE_BRG11,		/* Baud Rate Generator 11 */
-	QE_BRG12,		/* Baud Rate Generator 12 */
-	QE_BRG13,		/* Baud Rate Generator 13 */
-	QE_BRG14,		/* Baud Rate Generator 14 */
-	QE_BRG15,		/* Baud Rate Generator 15 */
-	QE_BRG16,		/* Baud Rate Generator 16 */
-	QE_CLK1,		/* Clock 1 */
-	QE_CLK2,		/* Clock 2 */
-	QE_CLK3,		/* Clock 3 */
-	QE_CLK4,		/* Clock 4 */
-	QE_CLK5,		/* Clock 5 */
-	QE_CLK6,		/* Clock 6 */
-	QE_CLK7,		/* Clock 7 */
-	QE_CLK8,		/* Clock 8 */
-	QE_CLK9,		/* Clock 9 */
-	QE_CLK10,		/* Clock 10 */
-	QE_CLK11,		/* Clock 11 */
-	QE_CLK12,		/* Clock 12 */
-	QE_CLK13,		/* Clock 13 */
-	QE_CLK14,		/* Clock 14 */
-	QE_CLK15,		/* Clock 15 */
-	QE_CLK16,		/* Clock 16 */
-	QE_CLK17,		/* Clock 17 */
-	QE_CLK18,		/* Clock 18 */
-	QE_CLK19,		/* Clock 19 */
-	QE_CLK20,		/* Clock 20 */
-	QE_CLK21,		/* Clock 21 */
-	QE_CLK22,		/* Clock 22 */
-	QE_CLK23,		/* Clock 23 */
-	QE_CLK24,		/* Clock 24 */
-	QE_CLK_DUMMY,
-};
-
 /* QE CMXUCR Registers.
  * There are two UCCs represented in each of the four CMXUCR registers.
  * These values are for the UCC in the LSBs
-- 
1.5.2.4

^ permalink raw reply related

* Re: [PATCH Rev 2] 8xxx: Convert #include of asm/of_{platform, device}.h into linux/of_{platform, device}.h.
From: Kumar Gala @ 2007-11-30  0:33 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: linuxppc-dev
In-Reply-To: <E1IpStN-0003li-2G@jdl.com>


On Nov 6, 2007, at 12:11 PM, Jon Loeliger wrote:

> From: Jon Loeliger <jdl@freescale.com>
>
> Signed-off-by: Jon Loeliger <jdl@freescale.com>
> Acked-by: Stephen Rothwell <sfr@canb.auug.org.au>
> ---
>
> Chip away at some janitor work.
> Catch both asm/of_platform.h and asm/of_device.h this time.
> Add sfr's ACK.
>
> arch/powerpc/platforms/82xx/pq2fads.c     |    2 +-
> arch/powerpc/platforms/83xx/mpc832x_mds.c |    4 ++--
> arch/powerpc/platforms/83xx/mpc832x_rdb.c |    2 +-
> arch/powerpc/platforms/83xx/mpc836x_mds.c |    4 ++--
> arch/powerpc/platforms/85xx/mpc85xx_mds.c |    4 ++--
> 5 files changed, 8 insertions(+), 8 deletions(-)
>

applied.

- k

^ permalink raw reply

* Re: [PATCH v7 1/9] add e300c4 entry to cputable
From: Kumar Gala @ 2007-11-30  0:33 UTC (permalink / raw)
  To: Li Yang; +Cc: linuxppc-dev
In-Reply-To: <1192793930-26039-2-git-send-email-leoli@freescale.com>


On Oct 19, 2007, at 6:38 AM, Li Yang wrote:

> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
> arch/powerpc/kernel/cputable.c |   13 ++++++++++++-
> 1 files changed, 12 insertions(+), 1 deletions(-)

applied.

- k

^ permalink raw reply

* Re: [PATCH v7 2/9] ipic: add new interrupts introduced by new chip
From: Kumar Gala @ 2007-11-30  0:34 UTC (permalink / raw)
  To: Li Yang; +Cc: linuxppc-dev, paulus
In-Reply-To: <1192793930-26039-3-git-send-email-leoli@freescale.com>


On Oct 19, 2007, at 6:38 AM, Li Yang wrote:

> These interrupts are introduced by the latest Freescale SoC such as
> MPC837x.
>
> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
> arch/powerpc/sysdev/ipic.c |  138 +++++++++++++++++++++++++++++++++++ 
> +++++++--
> arch/powerpc/sysdev/ipic.h |    7 +-
> include/asm-powerpc/ipic.h |   12 ++--
> 3 files changed, 143 insertions(+), 14 deletions(-)


applied.

- k

^ permalink raw reply

* Re: [PATCH v7 4/9] add platform support for MPC837x MDS board
From: Kumar Gala @ 2007-11-30  0:34 UTC (permalink / raw)
  To: Li Yang; +Cc: linuxppc-dev
In-Reply-To: <1192793930-26039-5-git-send-email-leoli@freescale.com>


On Oct 19, 2007, at 6:38 AM, Li Yang wrote:

> The MPC837x MDS is a new member of Freescale MDS reference system.
>
> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
> arch/powerpc/platforms/83xx/Kconfig       |   12 +++
> arch/powerpc/platforms/83xx/Makefile      |    1 +
> arch/powerpc/platforms/83xx/mpc837x_mds.c |  104 ++++++++++++++++++++ 
> +++++++++
> 3 files changed, 117 insertions(+), 0 deletions(-)
> create mode 100644 arch/powerpc/platforms/83xx/mpc837x_mds.c


applied.

- k

^ permalink raw reply

* Re: [PATCH v7 7/9] ipic: clean up unsupported ack operations
From: Kumar Gala @ 2007-11-30  0:35 UTC (permalink / raw)
  To: Li Yang; +Cc: linuxppc-dev
In-Reply-To: <1192793930-26039-8-git-send-email-leoli@freescale.com>


On Oct 19, 2007, at 6:38 AM, Li Yang wrote:

> IPIC controller doesn't support ack operations.  The pending registers
> are read-only.  The patch removes ack operations which are not needed.
>
> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
> arch/powerpc/sysdev/ipic.c |   40 + 
> +--------------------------------------
> 1 files changed, 2 insertions(+), 38 deletions(-)

applied.

- 

^ permalink raw reply

* Re: [PATCH v7 8/9] add MPC837x MDS default kernel configuration
From: Kumar Gala @ 2007-11-30  0:37 UTC (permalink / raw)
  To: Li Yang; +Cc: linuxppc-dev
In-Reply-To: <1192793930-26039-9-git-send-email-leoli@freescale.com>


On Oct 19, 2007, at 6:38 AM, Li Yang wrote:

> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
> arch/powerpc/configs/mpc837x_mds_defconfig |  878 +++++++++++++++++++ 
> +++++++++
> 1 files changed, 878 insertions(+), 0 deletions(-)
> create mode 100644 arch/powerpc/configs/mpc837x_mds_defconfig

applied.

- k

^ permalink raw reply

* Re: powerpc: fix guts_set_dmacr() and add guts_set_pmuxcr_dma() to immap_86xx.h
From: Kumar Gala @ 2007-11-30  0:37 UTC (permalink / raw)
  To: Timur Tabi; +Cc: linuxppc-dev
In-Reply-To: <11963675973785-git-send-email-timur@freescale.com>


On Nov 29, 2007, at 2:19 PM, Timur Tabi wrote:

> Updated guts_set_dmacr() to enumerate the DMA controllers at 0,  
> instead of 1,
> so that it now matches other related functions.  Added function
> guts_set_pmuxcr_dma() to set the external DMA control bits in the  
> PMUXCR
> register of the global utilities structure.
>
> Signed-off-by: Timur Tabi <timur@freescale.com>
> ---
>
> Changing the behavior of guts_set_dmacr() is okay because no one  
> uses that
> function yet.
>
> This patch is for Kumar's for-2.6.25 branch.

applied.

- k

^ permalink raw reply

* Re: [PATCH v2] qe: change qe_setbrg() to take an enum qe_clock instead of an integer
From: Kumar Gala @ 2007-11-30  0:37 UTC (permalink / raw)
  To: Timur Tabi; +Cc: linuxppc-dev
In-Reply-To: <11963787903105-git-send-email-timur@freescale.com>


On Nov 29, 2007, at 5:26 PM, Timur Tabi wrote:

> qe_setbrg() currently takes an integer to indicate the BRG number.   
> Change that
> to take an enum qe_clock instead, since this enum is intended to  
> represent
> clock sources.
>
> Signed-off-by: Timur Tabi <timur@freescale.com>
> ---
>
> This patch applies to Kumar's for-2.6.25 branch.  You might need to  
> apply my
> other patch, "qe: fix device tree lookup code in qe_muram_init()",  
> first.
>
> It's safe to change the parameters to qe_setbrg() because no one is  
> using that
> function yet.
>
> arch/powerpc/sysdev/qe_lib/qe.c |   14 ++++--
> include/asm-powerpc/qe.h        |   94 ++++++++++++++++++ 
> +-------------------
> 2 files changed, 56 insertions(+), 52 deletions(-)

applied.

- k

^ permalink raw reply

* Re: [PATCH v7 9/9] add MPC837x MDS board default device tree
From: Kumar Gala @ 2007-11-30  0:44 UTC (permalink / raw)
  To: Li Yang; +Cc: linuxppc-dev
In-Reply-To: <1192793930-26039-10-git-send-email-leoli@freescale.com>


On Oct 19, 2007, at 6:38 AM, Li Yang wrote:

> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
> Updated pci node.
> arch/powerpc/boot/dts/mpc8377_mds.dts |  282 ++++++++++++++++++++++++ 
> +++++++
> arch/powerpc/boot/dts/mpc8378_mds.dts |  264 ++++++++++++++++++++++++ 
> +++++
> arch/powerpc/boot/dts/mpc8379_mds.dts |  300 ++++++++++++++++++++++++ 
> +++++++++
> 3 files changed, 846 insertions(+), 0 deletions(-)
> create mode 100644 arch/powerpc/boot/dts/mpc8377_mds.dts
> create mode 100644 arch/powerpc/boot/dts/mpc8378_mds.dts
> create mode 100644 arch/powerpc/boot/dts/mpc8379_mds.dts

Can you make the following updates:

* Drop serdes and phy-handles
* Update sata nodes:

+	sata@19000 {
+		compatible = "fsl,mpc8315-sata", "fsl,sata-pq2pro;
+		reg = <19000 1000>;
+		interrupts = <2d 8>;
+		interrupt-parent = < &ipic >;
+        };

* Added labels for ethernet (enet), serial, pci

(some examples below):

- k

>
>
> diff --git a/arch/powerpc/boot/dts/mpc8377_mds.dts b/arch/powerpc/ 
> boot/dts/mpc8377_mds.dts
> new file mode 100644
> index 0000000..4402e39
> --- /dev/null
> +++ b/arch/powerpc/boot/dts/mpc8377_mds.dts
> @@ -0,0 +1,282 @@
> +/*
> + * MPC8377E MDS Device Tree Source
> + *
> + * Copyright 2007 Freescale Semiconductor Inc.
> + *
> + * This program is free software; you can redistribute  it and/or  
> modify it
> + * under  the terms of  the GNU General  Public License as  
> published by the
> + * Free Software Foundation;  either version 2 of the  License, or  
> (at your
> + * option) any later version.
> + */
> +
> +/ {
> +	model = "fsl,mpc8377emds";
> +	compatible = "fsl,mpc8377emds","fsl,mpc837xmds";
> +	#address-cells = <1>;
> +	#size-cells = <1>;

[VERIFY THIS -- is copy/pasted from somewhere else]

+       aliases {
+               ethernet0 = "/soc8540@e0000000/ethernet@24000";
+               ethernet1 = "/soc@e0000000/ethernet@25000";
+               ethernet2 = "/soc@e0000000/ethernet@26000";
+               serial0 = "/soc@e0000000/serial@4500";
+               serial1 = "/soc@e0000000/serial@4600";
+               pci0 = "/pci@e0008000";
+       };


> +
> +		enet0: ethernet@24000 {

>
> +			device_type = "network";
> +			model = "eTSEC";
> +			compatible = "gianfar";
> +			reg = <24000 1000>;
> +			local-mac-address = [ 00 00 00 00 00 00 ];
> +			interrupts = <20 8 21 8 22 8>;
> +			phy-connection-type = "mii";
> +			interrupt-parent = < &ipic >;
> +			phy-handle = < &phy2 >;
> +		};
> +
> +		enet1: ethernet@25000 {

>
> +			device_type = "network";
> +			model = "eTSEC";
> +			compatible = "gianfar";
> +			reg = <25000 1000>;
> +			local-mac-address = [ 00 00 00 00 00 00 ];
> +			interrupts = <23 8 24 8 25 8>;
> +			phy-connection-type = "mii";
> +			interrupt-parent = < &ipic >;
> +			phy-handle = < &phy3 >;
> +		};
> +
> +		serial0: serial@4500 {

>
> +			device_type = "serial";
> +			compatible = "ns16550";
> +			reg = <4500 100>;
> +			clock-frequency = <0>;
> +			interrupts = <9 8>;
> +			interrupt-parent = < &ipic >;
> +		};
> +
> +		serial1: serial@4600 {

>
> +			device_type = "serial";
> +			compatible = "ns16550";
> +			reg = <4600 100>;
> +			clock-frequency = <0>;
> +			interrupts = <a 8>;
> +			interrupt-parent = < &ipic >;
> +		};
> +


> +	pci0: pci@e0008500 {
> +		interrupt-map-mask = <f800 0 0 7>;
> +		


> device_type = "pci";
> +	};
> +};

^ permalink raw reply

* [PATCH 1/2] [POWERPC] Consolidate compatible-to-i2c_boardinfo mapping code
From: Olof Johansson @ 2007-11-30  3:26 UTC (permalink / raw)
  To: linuxppc-dev

[POWERPC] Consolidate compatible-to-i2c_boardinfo mapping code

Move the mapping from device tree compatible field to i2c_boardinfo
structures for powerpc, since several platforms now use this.

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

---

 arch/powerpc/sysdev/Makefile         |    1 
 arch/powerpc/sysdev/fsl_soc.c        |   38 ---------------------
 arch/powerpc/sysdev/i2c_of_mapping.c |   61 +++++++++++++++++++++++++++++++++++
 include/asm-powerpc/i2c_of.h         |   14 ++++++++
 4 files changed, 77 insertions(+), 37 deletions(-)


Index: 2.6.24/arch/powerpc/sysdev/Makefile
===================================================================
--- 2.6.24.orig/arch/powerpc/sysdev/Makefile
+++ 2.6.24/arch/powerpc/sysdev/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_MV64X60)		+= $(mv64x60-y) m
 				   mv64x60_udbg.o
 obj-$(CONFIG_RTC_DRV_CMOS)	+= rtc_cmos_setup.o
 obj-$(CONFIG_AXON_RAM)		+= axonram.o
+obj-$(CONFIG_I2C_BOARDINFO)	+= i2c_of_mapping.o
 
 ifeq ($(CONFIG_PPC_MERGE),y)
 obj-$(CONFIG_PPC_INDIRECT_PCI)	+= indirect_pci.o
Index: 2.6.24/arch/powerpc/sysdev/i2c_of_mapping.c
===================================================================
--- /dev/null
+++ 2.6.24/arch/powerpc/sysdev/i2c_of_mapping.c
@@ -0,0 +1,61 @@
+/*
+ * Parts based on arch/powerpc/sysdev/fsl_soc.c:
+ *
+ * 2006 (c) MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/i2c.h>
+#include <asm/i2c_of.h>
+
+struct i2c_driver_device {
+	char    *of_device;
+	char    *i2c_driver;
+	char    *i2c_type;
+};
+
+
+/* This table is used to map from device tree compat fields to
+ * the driver and model used by the i2c board info structures.
+ *
+ * Add new mappings as needed.
+ */
+
+static struct i2c_driver_device i2c_devices[] __initdata = {
+	{"ricoh,rs5c372a", "rtc-rs5c372", "rs5c372a",},
+	{"ricoh,rs5c372b", "rtc-rs5c372", "rs5c372b",},
+	{"ricoh,rv5c386",  "rtc-rs5c372", "rv5c386",},
+	{"ricoh,rv5c387a", "rtc-rs5c372", "rv5c387a",},
+	{"dallas,ds1307",  "rtc-ds1307",  "ds1307",},
+	{"dallas,ds1337",  "rtc-ds1307",  "ds1337",},
+	{"dallas,ds1338",  "rtc-ds1307",  "ds1338",},
+	{"dallas,ds1339",  "rtc-ds1307",  "ds1339",},
+	{"dallas,ds1340",  "rtc-ds1307",  "ds1340",},
+	{"stm,m41t00",     "rtc-ds1307",  "m41t00"},
+	{"dallas,ds1374",  "rtc-ds1374",  "rtc-ds1374",},
+};
+
+int __init of_fill_i2c_info(struct device_node *node,
+			    struct i2c_board_info *info)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
+		if (!of_device_is_compatible(node, i2c_devices[i].of_device))
+			continue;
+		if (strlcpy(info->driver_name, i2c_devices[i].i2c_driver,
+			    KOBJ_NAME_LEN) >= KOBJ_NAME_LEN ||
+		    strlcpy(info->type, i2c_devices[i].i2c_type,
+			    I2C_NAME_SIZE) >= I2C_NAME_SIZE)
+			return -ENOMEM;
+		return 0;
+	}
+	return -ENODEV;
+}
Index: 2.6.24/include/asm-powerpc/i2c_of.h
===================================================================
--- /dev/null
+++ 2.6.24/include/asm-powerpc/i2c_of.h
@@ -0,0 +1,14 @@
+/*
+ * Functions to map device tree compatible fields to values used by i2c
+ * board info structures
+ */
+
+#ifndef POWERPC_I2C_OF_H
+#define POWERPC_I2C_OF_H
+
+#ifdef CONFIG_I2C_BOARDINFO
+extern int __init of_fill_i2c_info(struct device_node *node,
+				   struct i2c_board_info *info);
+#endif
+
+#endif
Index: 2.6.24/arch/powerpc/sysdev/fsl_soc.c
===================================================================
--- 2.6.24.orig/arch/powerpc/sysdev/fsl_soc.c
+++ 2.6.24/arch/powerpc/sysdev/fsl_soc.c
@@ -320,43 +320,7 @@ arch_initcall(gfar_of_init);
 
 #ifdef CONFIG_I2C_BOARDINFO
 #include <linux/i2c.h>
-struct i2c_driver_device {
-	char	*of_device;
-	char	*i2c_driver;
-	char	*i2c_type;
-};
-
-static struct i2c_driver_device i2c_devices[] __initdata = {
-	{"ricoh,rs5c372a", "rtc-rs5c372", "rs5c372a",},
-	{"ricoh,rs5c372b", "rtc-rs5c372", "rs5c372b",},
-	{"ricoh,rv5c386",  "rtc-rs5c372", "rv5c386",},
-	{"ricoh,rv5c387a", "rtc-rs5c372", "rv5c387a",},
-	{"dallas,ds1307",  "rtc-ds1307",  "ds1307",},
-	{"dallas,ds1337",  "rtc-ds1307",  "ds1337",},
-	{"dallas,ds1338",  "rtc-ds1307",  "ds1338",},
-	{"dallas,ds1339",  "rtc-ds1307",  "ds1339",},
-	{"dallas,ds1340",  "rtc-ds1307",  "ds1340",},
-	{"stm,m41t00",     "rtc-ds1307",  "m41t00"},
-	{"dallas,ds1374",  "rtc-ds1374",  "rtc-ds1374",},
-};
-
-static int __init of_find_i2c_driver(struct device_node *node,
-				     struct i2c_board_info *info)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
-		if (!of_device_is_compatible(node, i2c_devices[i].of_device))
-			continue;
-		if (strlcpy(info->driver_name, i2c_devices[i].i2c_driver,
-			    KOBJ_NAME_LEN) >= KOBJ_NAME_LEN ||
-		    strlcpy(info->type, i2c_devices[i].i2c_type,
-			    I2C_NAME_SIZE) >= I2C_NAME_SIZE)
-			return -ENOMEM;
-		return 0;
-	}
-	return -ENODEV;
-}
+#include <asm/i2c_of.h>
 
 static void __init of_register_i2c_devices(struct device_node *adap_node,
 					   int bus_num)

^ permalink raw reply

* [PATCH 2/2] [POWERPC] pasemi: Register i2c_board_info
From: Olof Johansson @ 2007-11-30  3:29 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <20071130032645.GA25580@lixom.net>

[POWERPC] pasemi: Register i2c_board_info

Setup i2c_board_info based on device tree contents. This has to be
a device_initcall since we need PCI to be probed by the time we
run it, but before the actual driver is initialized.


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

Index: 2.6.24/arch/powerpc/platforms/pasemi/Makefile
===================================================================
--- 2.6.24.orig/arch/powerpc/platforms/pasemi/Makefile
+++ 2.6.24/arch/powerpc/platforms/pasemi/Makefile
@@ -1,4 +1,4 @@
-obj-y	+= setup.o pci.o time.o idle.o powersave.o iommu.o
+obj-y	+= setup.o pci.o time.o idle.o powersave.o iommu.o misc.o
 obj-$(CONFIG_PPC_PASEMI_MDIO)	+= gpio_mdio.o
 obj-$(CONFIG_ELECTRA_IDE) += electra_ide.o
 obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o
Index: 2.6.24/arch/powerpc/platforms/pasemi/misc.c
===================================================================
--- /dev/null
+++ 2.6.24/arch/powerpc/platforms/pasemi/misc.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2007 PA Semi, Inc
+ *
+ * Parts based on arch/powerpc/sysdev/fsl_soc.c:
+ *
+ * 2006 (c) MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/of.h>
+#include <linux/i2c.h>
+#include <asm/i2c_of.h>
+
+#ifdef CONFIG_I2C_BOARDINFO
+static int __init pasemi_register_i2c_devices(void)
+{
+	struct pci_dev *pdev;
+	struct device_node *adap_node;
+	struct device_node *node;
+
+	pdev = NULL;
+	while ((pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa003, pdev))) {
+		adap_node = pci_device_to_OF_node(pdev);
+
+		if (!adap_node)
+			continue;
+
+		node = NULL;
+		while ((node = of_get_next_child(adap_node, node))) {
+			struct i2c_board_info info = {};
+			const u32 *addr;
+			int len;
+
+			addr = of_get_property(node, "reg", &len);
+			if (!addr || len < sizeof(int) ||
+			    *addr > (1 << 10) - 1) {
+				printk(KERN_WARNING
+					"pasemi_register_i2c_devices: "
+					"invalid i2c device entry\n");
+				continue;
+			}
+
+			info.irq = irq_of_parse_and_map(node, 0);
+			if (info.irq == NO_IRQ)
+				info.irq = -1;
+
+			if (of_fill_i2c_info(node, &info) < 0)
+				continue;
+
+			info.addr = *addr;
+
+			i2c_register_board_info(PCI_FUNC(pdev->devfn), &info,
+						1);
+		}
+	}
+	return 0;
+}
+device_initcall(pasemi_register_i2c_devices);
+#endif

^ permalink raw reply

* [PATCH] Add MPC837xEMDS PCIE RC mode support
From: Li Li @ 2007-11-30  3:45 UTC (permalink / raw)
  To: Kumar Gala, linuxppc-dev

The PCIE controller is initiated in u-boot.

This patch is based on Leo`s mpc837xe patches.


Signed-off-by: Tony Li <tony.li@freescale.com>
---
 arch/powerpc/boot/dts/mpc8377_mds.dts     |   56 ++++++++--
 arch/powerpc/boot/dts/mpc8378_mds.dts     |   56 ++++++++--
 arch/powerpc/platforms/83xx/Kconfig       |    7 ++
 arch/powerpc/platforms/83xx/mpc8313_rdb.c |    2 +-
 arch/powerpc/platforms/83xx/mpc832x_mds.c |    2 +-
 arch/powerpc/platforms/83xx/mpc832x_rdb.c |    2 +-
 arch/powerpc/platforms/83xx/mpc834x_itx.c |    2 +-
 arch/powerpc/platforms/83xx/mpc834x_mds.c |    2 +-
 arch/powerpc/platforms/83xx/mpc836x_mds.c |    2 +-
 arch/powerpc/platforms/83xx/mpc837x_mds.c |    7 +-
 arch/powerpc/platforms/83xx/mpc83xx.h     |   10 ++-
 arch/powerpc/platforms/83xx/pci.c         |  166 +++++++++++++++++++++++++++-
 12 files changed, 283 insertions(+), 31 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc8377_mds.dts b/arch/powerpc/boot/dts/mpc8377_mds.dts
index 4402e39..1f7819e 100644
--- a/arch/powerpc/boot/dts/mpc8377_mds.dts
+++ b/arch/powerpc/boot/dts/mpc8377_mds.dts
@@ -197,14 +197,6 @@
 			clock = <d#100>;
 		};
 
-		serdes2:serdes@e3100 {
-			compatible = "fsl,serdes";
-			reg = <e3100 100>;
-			vdd-1v;
-			protocol = "pcie";
-			clock = <d#100>;
-		};
-
 		/* IPIC
 		 * interrupts cell = <intr #, sense>
 		 * sense values match linux IORESOURCE_IRQ_* defines:
@@ -279,4 +271,52 @@
 		compatible = "fsl,mpc8349-pci";
 		device_type = "pci";
 	};
+
+	pci2@e0009000 {
+		interrupt-map-mask = <f800 0 0 7>;
+		msi-available-ranges = <43 4 51 52 56 57 58 59>;
+		interrupt-map = <
+			0000 0 0 1 &ipic 1 8
+			0000 0 0 2 &ipic 1 8
+			0000 0 0 3 &ipic 1 8
+			0000 0 0 4 &ipic 1 8
+		>;
+		interrupt-parent = < &ipic >;
+		interrupts = <1 8>;
+		bus-range = <0 0>;
+		ranges = <02000000 0 A8000000 A8000000 0 10000000
+		          01000000 0 00000000 B8000000 0 00800000>;
+		clock-frequency = <0>;
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <e0009000 00001000
+		       a0000000 08000000>;
+		compatible = "fsl,mpc8377-pcie";
+		device_type = "pci";
+	};
+
+	pci3@e000a000 {
+		interrupt-map-mask = <f800 0 0 7>;
+		msi-available-ranges = <43 4 51 52 56 57 58 59>;
+		interrupt-map = <
+			0000 0 0 1 &ipic 2 8
+			0000 0 0 2 &ipic 2 8
+			0000 0 0 3 &ipic 2 8
+			0000 0 0 4 &ipic 2 8
+		>;
+		interrupt-parent = < &ipic >;
+		interrupts = <2 8>;
+		bus-range = <0 0>;
+		ranges = <02000000 0 C8000000 C8000000 0 10000000
+			  01000000 0 00000000 D8000000 0 00800000>;
+		clock-frequency = <0>;
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <e000a000 00001000
+		       c0000000 08000000>;
+		compatible = "fsl,mpc8377-pcie";
+		device_type = "pci";
+	};
 };
diff --git a/arch/powerpc/boot/dts/mpc8378_mds.dts b/arch/powerpc/boot/dts/mpc8378_mds.dts
index 54171f4..1503ae3 100644
--- a/arch/powerpc/boot/dts/mpc8378_mds.dts
+++ b/arch/powerpc/boot/dts/mpc8378_mds.dts
@@ -179,14 +179,6 @@
 			clock = <d#100>;
 		};
 
-		serdes2:serdes@e3100 {
-			compatible = "fsl,serdes";
-			reg = <e3100 100>;
-			vdd-1v;
-			protocol = "pcie";
-			clock = <d#100>;
-		};
-
 		/* IPIC
 		 * interrupts cell = <intr #, sense>
 		 * sense values match linux IORESOURCE_IRQ_* defines:
@@ -261,4 +253,52 @@
 		compatible = "fsl,mpc8349-pci";
 		device_type = "pci";
 	};
+
+	pci2@e0009000 {
+		interrupt-map-mask = <f800 0 0 7>;
+		msi-available-ranges = <43 4 51 52 56 57 58 59>;
+		interrupt-map = <
+			0000 0 0 1 &ipic 1 8
+			0000 0 0 2 &ipic 1 8
+			0000 0 0 3 &ipic 1 8
+			0000 0 0 4 &ipic 1 8
+		>;
+		interrupt-parent = < &ipic >;
+		interrupts = <1 8>;
+		bus-range = <0 0>;
+		ranges = <02000000 0 A8000000 A8000000 0 10000000
+		          01000000 0 00000000 B8000000 0 00800000>;
+		clock-frequency = <0>;
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <e0009000 00001000
+		       a0000000 08000000>;
+		compatible = "fsl,mpc8377-pcie";
+		device_type = "pci";
+	};
+
+	pci3@e000a000 {
+		interrupt-map-mask = <f800 0 0 7>;
+		msi-available-ranges = <43 4 51 52 56 57 58 59>;
+		interrupt-map = <
+			0000 0 0 1 &ipic 2 8
+			0000 0 0 2 &ipic 2 8
+			0000 0 0 3 &ipic 2 8
+			0000 0 0 4 &ipic 2 8
+		>;
+		interrupt-parent = < &ipic >;
+		interrupts = <2 8>;
+		bus-range = <0 0>;
+		ranges = <02000000 0 C8000000 C8000000 0 10000000
+			  01000000 0 00000000 D8000000 0 00800000>;
+		clock-frequency = <0>;
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <e000a000 00001000
+		       c0000000 08000000>;
+		compatible = "fsl,mpc8377-pcie";
+		device_type = "pci";
+	};
 };
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 0c61e7a..00154c5 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -87,3 +87,10 @@ config PPC_MPC837x
 	select PPC_INDIRECT_PCI
 	select FSL_SERDES
 	default y if MPC837x_MDS
+
+config PPC_MPC83XX_PCIE
+	bool "MPC837X PCI Express support"
+	depends on PCIEPORTBUS && PPC_MPC837x
+	default n
+	help
+	  Enables MPC837x PCI express RC mode
diff --git a/arch/powerpc/platforms/83xx/mpc8313_rdb.c b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
index 33766b8..1a86a66 100644
--- a/arch/powerpc/platforms/83xx/mpc8313_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
@@ -44,7 +44,7 @@ static void __init mpc8313_rdb_setup_arch(void)
 
 #ifdef CONFIG_PCI
 	for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
-		mpc83xx_add_bridge(np);
+		mpc83xx_add_bridge(np, PPC_83XX_PCI);
 #endif
 	mpc831x_usb_cfg();
 }
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index 972fa85..8c5afaf 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -74,7 +74,7 @@ static void __init mpc832x_sys_setup_arch(void)
 
 #ifdef CONFIG_PCI
 	for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
-		mpc83xx_add_bridge(np);
+		mpc83xx_add_bridge(np, PPC_83XX_PCI);
 #endif
 
 #ifdef CONFIG_QUICC_ENGINE
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index fbca336..91a01bd 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -94,7 +94,7 @@ static void __init mpc832x_rdb_setup_arch(void)
 
 #ifdef CONFIG_PCI
 	for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
-		mpc83xx_add_bridge(np);
+		mpc83xx_add_bridge(np, PPC_83XX_PCI);
 #endif
 
 #ifdef CONFIG_QUICC_ENGINE
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c
index aa76819..377f946 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_itx.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c
@@ -53,7 +53,7 @@ static void __init mpc834x_itx_setup_arch(void)
 
 #ifdef CONFIG_PCI
 	for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
-		mpc83xx_add_bridge(np);
+		mpc83xx_add_bridge(np, PPC_83XX_PCI);
 #endif
 
 	mpc834x_usb_cfg();
diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c
index 00aed7c..4dc17a5 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c
@@ -84,7 +84,7 @@ static void __init mpc834x_mds_setup_arch(void)
 
 #ifdef CONFIG_PCI
 	for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
-		mpc83xx_add_bridge(np);
+		mpc83xx_add_bridge(np, PPC_83XX_PCI);
 #endif
 
 	mpc834xemds_usb_cfg();
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index 0f3855c..5b13b34 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -80,7 +80,7 @@ static void __init mpc836x_mds_setup_arch(void)
 
 #ifdef CONFIG_PCI
 	for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
-		mpc83xx_add_bridge(np);
+		mpc83xx_add_bridge(np, PPC_83XX_PCI);
 #endif
 
 #ifdef CONFIG_QUICC_ENGINE
diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c
index 166c111..6048f1b 100644
--- a/arch/powerpc/platforms/83xx/mpc837x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c
@@ -43,7 +43,12 @@ static void __init mpc837x_mds_setup_arch(void)
 
 #ifdef CONFIG_PCI
 	for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
-		mpc83xx_add_bridge(np);
+		mpc83xx_add_bridge(np, PPC_83XX_PCI);
+#endif
+#ifdef CONFIG_PPC_MPC83XX_PCIE
+	for_each_compatible_node(np, "pci", "fsl,mpc8377-pcie") {
+		mpc83xx_add_bridge(np, PPC_83XX_PCIE);
+	}
 #endif
 }
 
diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h
index b778cb4..2078da7 100644
--- a/arch/powerpc/platforms/83xx/mpc83xx.h
+++ b/arch/powerpc/platforms/83xx/mpc83xx.h
@@ -43,12 +43,18 @@
 #define PORTSCX_PTS_UTMI           0x00000000
 #define PORTSCX_PTS_ULPI           0x80000000
 
+/* PCIE Registers */
+#define PEX_LTSSM_STAT		0x404
+#define PEX_LTSSM_STAT_L0	0x16
+#define PEX_GCLK_RATIO		0x440
+
 /*
  * Declaration for the various functions exported by the
  * mpc83xx_* files. Mostly for use by mpc83xx_setup
  */
-
-extern int mpc83xx_add_bridge(struct device_node *dev);
+#define PPC_83XX_PCI	0x1
+#define PPC_83XX_PCIE	0x2
+extern int mpc83xx_add_bridge(struct device_node *dev, int flags);
 extern void mpc83xx_restart(char *cmd);
 extern long mpc83xx_time_init(void);
 extern int mpc834x_usb_cfg(void);
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c
index 80425d7..0b52b2e 100644
--- a/arch/powerpc/platforms/83xx/pci.c
+++ b/arch/powerpc/platforms/83xx/pci.c
@@ -25,6 +25,8 @@
 #include <asm/prom.h>
 #include <sysdev/fsl_soc.h>
 
+#include "mpc83xx.h"
+
 #undef DEBUG
 
 #ifdef DEBUG
@@ -33,13 +35,157 @@
 #define DBG(x...)
 #endif
 
-int __init mpc83xx_add_bridge(struct device_node *dev)
+#if defined(CONFIG_PPC_MPC83XX_PCIE)
+
+/* PCIE config space Read/Write routines */
+static int direct_read_config_pcie(struct pci_bus *bus,
+			uint devfn, int offset, int len, u32 *val)
+{
+	struct pci_controller *hose = bus->sysdata;
+	void __iomem *cfg_addr;
+	u32 bus_no;
+
+	if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	if (ppc_md.pci_exclude_device)
+		if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
+			return PCIBIOS_DEVICE_NOT_FOUND;
+
+	switch (len) {
+	case 2:
+		if (offset & 1)
+			return -EINVAL;
+		break;
+	case 4:
+	if (offset & 3)
+		return -EINVAL;
+		break;
+	}
+
+	pr_debug("_read_cfg_pcie: bus=%d devfn=%x off=%x len=%x\n",
+		bus->number, devfn, offset, len);
+
+	if (bus->number == hose->first_busno) {
+		if (devfn & 0xf8)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+		bus_no = hose->self_busno;
+	} else
+		bus_no = bus->number;
+
+	cfg_addr = (void __iomem *)((ulong) hose->cfg_addr +
+		((bus_no << 20) | (devfn << 12) | (offset & 0xfff)));
+
+	switch (len) {
+	case 1:
+		*val = in_8(cfg_addr);
+		break;
+	case 2:
+		*val = in_le16(cfg_addr);
+		break;
+	default:
+		*val = in_le32(cfg_addr);
+		break;
+	}
+	pr_debug("_read_cfg_pcie: val=%x cfg_addr=%p\n", *val, cfg_addr);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int direct_write_config_pcie(struct pci_bus *bus,
+			uint devfn, int offset, int len, u32 val)
+{
+	struct pci_controller *hose = bus->sysdata;
+	void __iomem *cfg_addr;
+	u32 bus_no;
+
+	if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	if (ppc_md.pci_exclude_device)
+		if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
+			return PCIBIOS_DEVICE_NOT_FOUND;
+
+	switch (len) {
+	case 2:
+		if (offset & 1)
+			return -EINVAL;
+		break;
+	case 4:
+		if (offset & 3)
+			return -EINVAL;
+		break;
+	}
+
+	if (bus->number == hose->first_busno) {
+		if (devfn & 0xf8)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+		bus_no = hose->self_busno;
+	} else
+		bus_no = bus->number;
+
+	cfg_addr = (void __iomem *)((ulong) hose->cfg_addr +
+		((bus_no << 20) | (devfn << 12) | (offset & 0xfff)));
+
+	switch (len) {
+	case 1:
+		out_8(cfg_addr, val);
+		break;
+	case 2:
+		out_le16(cfg_addr, val);
+		break;
+	default:
+		out_le32(cfg_addr, val);
+		break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops direct_pcie_ops = {
+	direct_read_config_pcie,
+	direct_write_config_pcie
+};
+
+void __init setup_direct_pcie(struct pci_controller *hose, u32 cfg_addr, u32 cfg_size)
+{
+	ulong base = cfg_addr & PAGE_MASK;
+	void __iomem *mbase, *addr;
+
+	mbase = ioremap(base, cfg_size);
+	addr = mbase + (cfg_addr & ~PAGE_MASK);
+	hose->cfg_addr = addr;
+	hose->ops = &direct_pcie_ops;
+}
+
+static void __init mpc83xx_setup_pcie(struct pci_controller *hose,
+			struct resource *reg, struct resource *cfg_space)
+{
+	void __iomem *hose_cfg_base;
+	u32 val;
+
+	hose_cfg_base = ioremap(reg->start, reg->end - reg->start + 1);
+
+	val = in_le32(hose_cfg_base + PEX_LTSSM_STAT);
+	if (val < PEX_LTSSM_STAT_L0)
+		hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+
+	setup_direct_pcie(hose, cfg_space->start,
+			cfg_space->end - cfg_space->start + 1);
+}
+#endif /* CONFIG_PPC_MPC83XX_PCIE */
+
+int __init mpc83xx_add_bridge(struct device_node *dev, int flags)
 {
 	int len;
 	struct pci_controller *hose;
 	struct resource rsrc;
+#if defined(CONFIG_PPC_MPC83XX_PCIE)
+	struct resource cfg_space;
+#endif
 	const int *bus_range;
-	int primary = 1, has_address = 0;
+	static int primary = 1;
+	int has_address = 0;
 	phys_addr_t immr = get_immrbase();
 
 	DBG("Adding PCI host bridge %s\n", dev->full_name);
@@ -66,14 +212,21 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
 	 * the other at 0x8600, we consider the 0x8500 the primary controller
 	 */
 	/* PCI 1 */
-	if ((rsrc.start & 0xfffff) == 0x8500) {
+	if ((rsrc.start & 0xfffff) == 0x8500)
 		setup_indirect_pci(hose, immr + 0x8300, immr + 0x8304, 0);
-	}
 	/* PCI 2 */
-	if ((rsrc.start & 0xfffff) == 0x8600) {
+	if ((rsrc.start & 0xfffff) == 0x8600)
 		setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384, 0);
-		primary = 0;
+
+#if defined(CONFIG_PPC_MPC83XX_PCIE)
+	if (flags & PPC_83XX_PCIE) {
+		if (of_address_to_resource(dev, 1, &cfg_space)) {
+			printk("PCIE RC losts configure space. Skip it\n");
+			return 1;
+		}
+		mpc83xx_setup_pcie(hose, &rsrc, &cfg_space);
 	}
+#endif
 
 	printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. "
 	       "Firmware bus number: %d->%d\n",
@@ -86,6 +239,7 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
 	/* Interpret the "ranges" property */
 	/* This also maps the I/O region and sets isa_io/mem_base */
 	pci_process_bridge_OF_ranges(hose, dev, primary);
+	primary = 0;
 
 	return 0;
 }
-- 
1.5.2

^ permalink raw reply related

* [PATCH] Add IPIC MSI interrupt support
From: Li Li @ 2007-11-30  3:48 UTC (permalink / raw)
  To: Kumar Gala, linuxppc-dev

The IPIC MSI is introduced on MPC837x chip.
Implements the IPIC MSI as two level interrupt controller.

Signed-off-by: Tony Li <tony.li@freescale.com>
---
 arch/powerpc/boot/dts/mpc8377_mds.dts     |   14 ++
 arch/powerpc/boot/dts/mpc8378_mds.dts     |   14 ++
 arch/powerpc/boot/dts/mpc8379_mds.dts     |   14 ++
 arch/powerpc/platforms/83xx/Kconfig       |    6 +
 arch/powerpc/platforms/83xx/mpc837x_mds.c |   11 +
 arch/powerpc/sysdev/Makefile              |    1 +
 arch/powerpc/sysdev/ipic_msi.c            |  359 +++++++++++++++++++++++++++++
 include/asm-powerpc/ipic_msi.h            |   54 +++++
 8 files changed, 473 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/sysdev/ipic_msi.c
 create mode 100644 include/asm-powerpc/ipic_msi.h

diff --git a/arch/powerpc/boot/dts/mpc8377_mds.dts b/arch/powerpc/boot/dts/mpc8377_mds.dts
index 1f7819e..1068fe2 100644
--- a/arch/powerpc/boot/dts/mpc8377_mds.dts
+++ b/arch/powerpc/boot/dts/mpc8377_mds.dts
@@ -210,6 +210,20 @@
 			#interrupt-cells = <2>;
 			reg = <700 100>;
 		};
+
+		ipic-msi@7c0 {
+			compatible = "fsl,ipic-msi";
+			reg = <7c0 40>;
+			interrupts = < 43 8
+				       4  8
+				       51 8
+				       52 8
+				       56 8
+				       57 8
+				       58 8
+				       59 8 >;
+			interrupt-parent = < &ipic >;
+		};
 	};
 
 	pci@e0008500 {
diff --git a/arch/powerpc/boot/dts/mpc8378_mds.dts b/arch/powerpc/boot/dts/mpc8378_mds.dts
index 1503ae3..f12658f 100644
--- a/arch/powerpc/boot/dts/mpc8378_mds.dts
+++ b/arch/powerpc/boot/dts/mpc8378_mds.dts
@@ -192,6 +192,20 @@
 			#interrupt-cells = <2>;
 			reg = <700 100>;
 		};
+
+		ipic-msi@7c0 {
+			compatible = "fsl,ipic-msi";
+			reg = <7c0 40>;
+			interrupts = < 43 8
+				       4  8
+				       51 8
+				       52 8
+				       56 8
+				       57 8
+				       58 8
+				       59 8 >;
+			interrupt-parent = < &ipic >;
+		};
 	};
 
 	pci@e0008500 {
diff --git a/arch/powerpc/boot/dts/mpc8379_mds.dts b/arch/powerpc/boot/dts/mpc8379_mds.dts
index cdb4426..9fe4bd2 100644
--- a/arch/powerpc/boot/dts/mpc8379_mds.dts
+++ b/arch/powerpc/boot/dts/mpc8379_mds.dts
@@ -236,6 +236,20 @@
 			#interrupt-cells = <2>;
 			reg = <700 100>;
 		};
+
+		ipic-msi@7c0 {
+			compatible = "fsl,ipic-msi";
+			reg = <7c0 40>;
+			interrupts = < 43 8
+				       4  8
+				       51 8
+				       52 8
+				       56 8
+				       57 8
+				       58 8
+				       59 8 >;
+			interrupt-parent = < &ipic >;
+		};
 	};
 
 	pci@e0008500 {
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 00154c5..4c51f78 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -88,6 +88,12 @@ config PPC_MPC837x
 	select FSL_SERDES
 	default y if MPC837x_MDS
 
+config IPIC_MSI
+	bool
+	depends on PCI_MSI
+	default y if PPC_MPC837x
+	default n
+
 config PPC_MPC83XX_PCIE
 	bool "MPC837X PCI Express support"
 	depends on PCIEPORTBUS && PPC_MPC837x
diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c
index 6048f1b..dbea34b 100644
--- a/arch/powerpc/platforms/83xx/mpc837x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c
@@ -17,6 +17,9 @@
 
 #include <asm/time.h>
 #include <asm/ipic.h>
+#if CONFIG_IPIC_MSI
+#include <asm/ipic_msi.h>
+#endif
 #include <asm/udbg.h>
 #include <asm/prom.h>
 
@@ -84,6 +87,14 @@ static void __init mpc837x_mds_init_IRQ(void)
 	 * in case the boot rom changed something on us.
 	 */
 	ipic_set_default_priority();
+
+#if CONFIG_IPIC_MSI
+	np = of_find_compatible_node(NULL, NULL, "fsl,ipic-msi");
+	if (!np)
+		return;
+
+	ipic_msi_init(np, ipic_msi_cascade);
+#endif
 }
 
 /*
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 99a77d7..5946b6a 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -25,6 +25,7 @@ ifeq ($(CONFIG_PPC_MERGE),y)
 obj-$(CONFIG_PPC_INDIRECT_PCI)	+= indirect_pci.o
 obj-$(CONFIG_PPC_I8259)		+= i8259.o
 obj-$(CONFIG_PPC_83xx)		+= ipic.o
+obj-$(CONFIG_IPIC_MSI)		+= ipic_msi.o
 obj-$(CONFIG_4xx)		+= uic.o
 obj-$(CONFIG_XILINX_VIRTEX)	+= xilinx_intc.o
 endif
diff --git a/arch/powerpc/sysdev/ipic_msi.c b/arch/powerpc/sysdev/ipic_msi.c
new file mode 100644
index 0000000..57758f7
--- /dev/null
+++ b/arch/powerpc/sysdev/ipic_msi.c
@@ -0,0 +1,359 @@
+/*
+ * arch/powerpc/sysdev/ipic_msi.c
+ *
+ * IPIC MSI routines implementations.
+ *
+ * Auther: Tony Li <tony.li@freescale.com>
+ *
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+
+#include <linux/pci.h>
+#include <linux/msi.h>
+#include <linux/irq.h>
+
+#include <asm/ipic_msi.h>
+
+#define MSIR0	0x43
+#define MSIR1	0x4
+#define MSIR2	0x51
+#define MSIR3	0x52
+#define MSIR4	0x56
+#define MSIR5	0x57
+#define MSIR6	0x58
+#define MSIR7	0x59
+
+
+static struct ipic_msi *ipic_msi;
+static DEFINE_SPINLOCK(ipic_msi_lock);
+static DEFINE_SPINLOCK(ipic_msi_bitmap_lock);
+
+static inline u32 ipic_msi_read(volatile u32 __iomem *base, unsigned int reg)
+{
+	return in_be32(base + (reg >> 2));
+}
+
+static inline void ipic_msi_write(volatile u32 __iomem *base,
+					unsigned int reg, u32 value)
+{
+	out_be32(base + (reg >> 2), value);
+}
+
+static struct ipic_msi * ipic_msi_from_irq(unsigned int virq)
+{
+	return ipic_msi;
+}
+
+#define	ipic_msi_irq_to_hw(virq)	((unsigned int)irq_map[virq].hwirq)
+static void ipic_msi_unmask(unsigned int virq)
+{
+	struct ipic_msi *msi = ipic_msi_from_irq(virq);
+	unsigned int src = ipic_msi_irq_to_hw(virq);
+	unsigned long flags;
+	u32 temp;
+
+	spin_lock_irqsave(&ipic_msi_lock, flags);
+	temp = ipic_msi_read(msi->regs, IPIC_MSIMR);
+	ipic_msi_write(msi->regs, IPIC_MSIMR,
+		temp & ~(1 << (src / msi->int_per_msir)));
+
+	spin_unlock_irqrestore(&ipic_msi_lock, flags);
+}
+
+static void ipic_msi_mask(unsigned int virq)
+{
+	struct ipic_msi *msi = ipic_msi_from_irq(virq);
+	unsigned int src = ipic_msi_irq_to_hw(virq);
+	unsigned long flags;
+	u32 temp;
+
+	spin_lock_irqsave(&ipic_msi_lock, flags);
+
+	temp = ipic_msi_read(msi->regs, IPIC_MSIMR);
+	ipic_msi_write(msi->regs, IPIC_MSIMR,
+		temp | (1 << (src / msi->int_per_msir)));
+
+	spin_unlock_irqrestore(&ipic_msi_lock, flags);
+}
+/*
+ * We do not need this actually. The MSIR register has been read once
+ * in ipic_msi_get_irq. So, this MSI interrupt has been acked
+ */
+static void ipic_msi_ack(unsigned int virq)
+{
+	struct ipic_msi *msi = ipic_msi_from_irq(virq);
+	unsigned int src = ipic_msi_irq_to_hw(virq);
+	unsigned long flags;
+
+	spin_lock_irqsave(&ipic_msi_lock, flags);
+
+	ipic_msi_read(msi->regs, IPIC_MSIR0 + (4 * (src / msi->int_per_msir)));
+
+	spin_unlock_irqrestore(&ipic_msi_lock,flags);
+}
+
+static struct irq_chip ipic_msi_chip = {
+	.typename = " IPIC MSI ",
+	.unmask = ipic_msi_unmask,
+	.mask = ipic_msi_mask,
+	.ack = ipic_msi_ack,
+};
+
+static int ipic_msi_host_map(struct irq_host *h, unsigned int virq,
+				irq_hw_number_t hw)
+{
+	struct ipic_msi *msi = h->host_data;
+	struct irq_chip *chip = msi->hc_irq;
+
+	set_irq_chip_data(virq, msi);
+	get_irq_desc(virq)->status |= IRQ_TYPE_EDGE_FALLING;
+
+	set_irq_chip_and_handler(virq, chip, handle_edge_irq);
+	return 0;
+}
+
+static struct irq_host_ops ipic_msi_host_ops = {
+	.map = ipic_msi_host_map,
+};
+
+irq_hw_number_t ipic_msi_alloc_hwirqs(struct ipic_msi *msi, int num)
+{
+	unsigned long flags;
+	int offset, order = get_count_order(num);
+
+	spin_lock_irqsave(&ipic_msi_bitmap_lock, flags);
+
+	offset = bitmap_find_free_region(msi->ipic_msi_bitmap,
+			msi->nr_msir * msi->int_per_msir, order);
+
+	spin_unlock_irqrestore(&ipic_msi_bitmap_lock, flags);
+
+	pr_debug("%s: allocated 0x%x (2^%d) at offset 0x%x\n",
+		__FUNCTION__, num, order, offset);
+
+	return offset;
+}
+
+void ipic_msi_free_hwirqs(struct ipic_msi *msi, int offset, int num)
+{
+	unsigned long flags;
+	int order = get_count_order(num);
+
+	pr_debug("%s: freeing 0x%x (2^%d) at offset 0x%x\n",
+		__FUNCTION__, num, order, offset);
+
+	spin_lock_irqsave(&ipic_msi_bitmap_lock, flags);
+	bitmap_release_region(msi->ipic_msi_bitmap, offset, order);
+	spin_unlock_irqrestore(&ipic_msi_bitmap_lock, flags);
+}
+
+static int ipic_msi_init_allocator(struct ipic_msi *msi)
+{
+	int size;
+
+	size = BITS_TO_LONGS(msi->nr_msir * msi->int_per_msir) * sizeof(long);
+	msi->ipic_msi_bitmap = alloc_maybe_bootmem(size, GFP_KERNEL);
+
+	if (msi->ipic_msi_bitmap == NULL) {
+		pr_debug("%s: ENOMEM allocating allocator bitmap!\n",
+				__FUNCTION__);
+		return -ENOMEM;
+	}
+	memset(msi->ipic_msi_bitmap, 0, size);
+
+	return 0;
+}
+
+static void ipic_msi_compose_msg(struct ipic_msi *msi, int hwirq,
+						struct msi_msg *msg)
+{
+	unsigned int srs;
+	unsigned int ibs;
+
+	srs = hwirq / msi->int_per_msir;
+	ibs = hwirq - srs * msi->int_per_msir;
+
+	msg->address_lo = msi->msi_addr_lo;
+	msg->address_hi = msi->msi_addr_hi;
+	msg->data = (srs << 5) | (ibs & 0x1F);
+
+	pr_debug("%s: allocated srs: %d, ibs: %d\n",
+		__FUNCTION__, srs, ibs);
+
+}
+
+static int ipic_msi_setup_irqs(struct pci_dev *pdev, int nvec, int type)
+{
+	struct ipic_msi *msi = ipic_msi;
+	irq_hw_number_t hwirq;
+	unsigned int virq;
+	struct msi_desc *entry;
+	struct msi_msg msg;
+
+	list_for_each_entry(entry, &pdev->msi_list, list) {
+		hwirq = ipic_msi_alloc_hwirqs(msi, 1);
+		if (hwirq < 0) {
+			pr_debug("%s: fail allocating msi interrupt\n",
+					__FUNCTION__);
+			return hwirq;
+		}
+
+		/* This hwirq belongs to the irq_host other than irq_host of IPIC
+ 		 * So, it is independent to hwirq of IPIC */
+		virq = irq_create_mapping(msi->irqhost, hwirq);
+		if (virq == NO_IRQ) {
+			pr_debug("%s: fail mapping hwirq 0x%lx\n",
+					__FUNCTION__, hwirq);
+			ipic_msi_free_hwirqs(msi, hwirq, 1);
+			return -ENOSPC;
+		}
+		set_irq_msi(virq, entry);
+		ipic_msi_compose_msg(msi, hwirq, &msg);
+		write_msi_msg(virq, &msg);
+
+		hwirq++;
+	}
+
+	return 0;
+}
+
+static void ipic_msi_teardown_irqs(struct pci_dev *pdev)
+{
+	struct msi_desc *entry;
+	struct ipic_msi *msi = ipic_msi;
+
+	list_for_each_entry(entry, &pdev->msi_list, list) {
+		if (entry->irq == NO_IRQ)
+			continue;
+		set_irq_msi(entry->irq, NULL);
+		ipic_msi_free_hwirqs(msi, virq_to_hw(entry->irq), 1);
+		irq_dispose_mapping(entry->irq);
+	}
+
+	return;
+}
+
+void __init ipic_msi_init(struct device_node *node,
+			void (*handler)(unsigned int irq, struct irq_desc *desc))
+{
+	struct ipic_msi *msi;
+	struct resource res;
+	int i;
+	int rc = 0;
+
+	msi = alloc_maybe_bootmem(sizeof(*msi), GFP_KERNEL);
+	if (msi == NULL)
+		return;
+
+	memset(msi, 0, sizeof(*msi));
+
+
+	msi->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR,
+					NR_MSIR, &ipic_msi_host_ops, 0);
+	if (msi->irqhost == NULL) {
+		of_node_put(node);
+		goto out;
+	}
+
+	rc = of_address_to_resource(node, 0, &res);
+	if (rc) {
+		of_node_put(node);
+		goto out;
+	}
+
+	msi->regs = ioremap(res.start, res.end - res.start + 1);
+	msi->irqhost->host_data = msi;
+	msi->hc_irq = &ipic_msi_chip;
+
+	msi->msi_addr_lo = 0xE00007F8;
+	msi->msi_addr_hi = 0;
+	msi->nr_msir = ARRAY_SIZE(msi->msir);
+	msi->int_per_msir = 32;
+	for (i = 0; i < msi->nr_msir; i++) {
+		unsigned int virt_msir = irq_of_parse_and_map(node, i);
+		if (virt_msir != NO_IRQ) {
+			set_irq_data(virt_msir, msi);
+			set_irq_chained_handler(virt_msir, handler);
+			msi->msir[i] = virt_msir;
+		} else
+			msi->msir[i] = NO_IRQ;
+	}
+
+	rc = ipic_msi_init_allocator(msi);
+	if (rc)
+		goto out;
+
+	ipic_msi = msi;
+
+	WARN_ON(ppc_md.setup_msi_irqs);
+	ppc_md.setup_msi_irqs = ipic_msi_setup_irqs;
+	ppc_md.teardown_msi_irqs = ipic_msi_teardown_irqs;
+
+out:
+	if (mem_init_done)
+		kfree(msi);
+
+	return;
+}
+
+static int ipic_msi_get_irq(struct ipic_msi *msi, int virt_msir)
+{
+	int msir = -1;
+	unsigned int temp;
+	unsigned int offset;
+	int i;
+
+	for (i = 0; i < msi->nr_msir; i++)
+		if (virt_msir == msi->msir[i]) {
+			msir = i;
+			break;
+		}
+
+	if (i >= msi->nr_msir)
+		return NO_IRQ;
+
+	temp = ipic_msi_read(msi->regs, IPIC_MSIR0 + (i * 4));
+	offset = ffs(temp) - 1;
+
+	return irq_linear_revmap(msi->irqhost, (msir * msi->int_per_msir + offset));
+}
+
+void ipic_msi_cascade(unsigned int irq, struct irq_desc *desc)
+{
+	struct ipic_msi *msi;
+	unsigned int cascade_irq;
+
+	spin_lock(&desc->lock);
+	if (desc->chip->mask_ack)
+		desc->chip->mask_ack(irq);
+	else {
+		desc->chip->mask(irq);
+		desc->chip->ack(irq);
+	}
+
+	if (unlikely(desc->status & IRQ_INPROGRESS))
+		goto unlock;
+
+	desc->status |= IRQ_INPROGRESS;
+	msi = desc->handler_data;
+	cascade_irq = ipic_msi_get_irq(msi, irq);
+
+	spin_unlock(&desc->lock);
+
+	if (cascade_irq != NO_IRQ)
+		generic_handle_irq(cascade_irq);
+
+	spin_lock(&desc->lock);
+	desc->status &= ~IRQ_INPROGRESS;
+	if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
+		desc->chip->unmask(irq);
+
+unlock:
+	spin_unlock(&desc->lock);
+}
diff --git a/include/asm-powerpc/ipic_msi.h b/include/asm-powerpc/ipic_msi.h
new file mode 100644
index 0000000..ba952df
--- /dev/null
+++ b/include/asm-powerpc/ipic_msi.h
@@ -0,0 +1,54 @@
+/*
+ * include/asm-powerpc/ipic_msi.h
+ *
+ * IPIC MSI structure.
+ *
+ * Author: Tony Li <tony.li@freescale.com>
+ *
+ * Copyright (c) 2007 Freescale Semiconductor, Inc
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef _ASM_POWERPC_IPIC_MSI_H
+#define _ASM_POWERPC_IPIC_MSI_H
+
+#define NR_MSIR	8
+/* MSI interrupt register offset compared to MSI base address (0xc0) */
+#define IPIC_MSIR0	0x0	/* MSI Interrupt Reg 0 */
+#define IPIC_MSIR1	0x4	/* MSI Interrupt Reg 1 */
+#define IPIC_MSIR2	0x8	/* MSI Interrupt Reg 2 */
+#define IPIC_MSIR3	0xC	/* MSI Interrupt Reg 3 */
+#define IPIC_MSIR4	0x10	/* MSI Interrupt Reg 4 */
+#define IPIC_MSIR5	0x14	/* MSI Interrupt Reg 5 */
+#define IPIC_MSIR6	0x18	/* MSI Interrupt Reg 6 */
+#define IPIC_MSIR7	0x1C	/* MSI Interrupt Reg 7 */
+#define IPIC_MSIMR	0x30	/* MSI Interrupt Mask Reg */
+#define IPIC_MSISR	0x34	/* MSI Interrupt Status Reg */
+#define IPIC_MSIIR	0x38	/* MSI Interrupt Index Reg */
+
+struct ipic_msi {
+	volatile u32 __iomem *regs;
+
+	struct irq_host *irqhost;
+	struct irq_chip *hc_irq;
+
+	unsigned long cascade_irq;
+	unsigned int msir[8];
+
+	u32 msi_addr_lo;
+	u32 msi_addr_hi;
+
+	int nr_msir;
+	int int_per_msir;
+
+	void *ipic_msi_bitmap;
+};
+
+extern void ipic_msi_cascade(unsigned int irq, struct irq_desc *desc);
+extern void __init ipic_msi_init(struct device_node *node,
+		void (*handler)(unsigned int irq, struct irq_desc *desc));
+
+#endif /* _ASM_POWERPC_IPIC_MSI_H */
-- 
1.5.2

^ permalink raw reply related

* Re: [PATCH] Add MPC837xEMDS PCIE RC mode support
From: Olof Johansson @ 2007-11-30  4:14 UTC (permalink / raw)
  To: Li Li; +Cc: linuxppc-dev, Kumar Gala
In-Reply-To: <1196394334.29683.5.camel@Guyver>

Hi,

On Fri, Nov 30, 2007 at 11:45:34AM +0800, Li Li wrote:

> +	pci2@e0009000 {

Why call it pci2@ (and pci3@ below)? They are clearly identifiable with 
their unit addresses anyway.

> +config PPC_MPC83XX_PCIE
> +	bool "MPC837X PCI Express support"
> +	depends on PCIEPORTBUS && PPC_MPC837x
> +	default n
> +	help
> +	  Enables MPC837x PCI express RC mode

Why have a separate config option for this?

For systems where you don't want PCI-e configured, it should be left
out of the device tree instead.



-Olof

^ permalink raw reply

* Re: [BUG] 2.6.24-rc3-mm2 soft lockup while running tbench
From: Kamalesh Babulal @ 2007-11-30  5:09 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linuxppc-dev, balbir, linux-kernel
In-Reply-To: <20071129130905.c31431f3.akpm@linux-foundation.org>

Andrew Morton wrote:
> On Wed, 28 Nov 2007 20:03:22 +0530
> Kamalesh Babulal <kamalesh@linux.vnet.ibm.com> wrote:
> 
>> Hi Andrew,
>>
>> while running tbench on the powerpc with 2.6.24-rc3-mm2 softlock up occurs
>>
>> BUG: soft lockup - CPU#0 stuck for 11s! [tbench:12183]
>> NIP: c0000000000ac978 LR: c0000000000acff0 CTR: c00000000005c648
>> REGS: C00000076F0F3200 TRAP: 0901   Not tainted  (2.6.24-rc3-mm2-autotest)
>> MSR: 8000000000009032 <EE,ME,IR,DR>  CR: 44000482  XER: 00000000
>> TASK = C00000076F4BC000[12183] 'tbench' THREAD: C00000076F0F0000 CPU: 0
>> NIP [c0000000000ac978] .get_page_from_freelist+0x1cc/0x754
>> LR [c0000000000acff0] .__alloc_pages+0xb0/0x3a8
>> Call Trace:
>> [c00000076f0f3480] [c00000076f0f3560] 0xc00000076f0f3560 (unreliable)
>> [c00000076f0f3590] [c0000000000acff0] .__alloc_pages+0xb0/0x3a8
>> [c00000076f0f3680] [c0000000000ce2e4] .alloc_pages_current+0xa8/0xc8
>> [c00000076f0f3710] [c0000000000ac6ec] .__get_free_pages+0x20/0x70
>> [c00000076f0f3790] [c0000000000d75c8] .__kmalloc_node_track_caller+0x60/0x148
>> [c00000076f0f3840] [c0000000002c22b0] .__alloc_skb+0x98/0x184
>> [c00000076f0f38f0] [c000000000306cd8] .tcp_sendmsg+0x1fc/0xe24
>> [c00000076f0f3a10] [c0000000002b963c] .sock_sendmsg+0xe4/0x128
>> [c00000076f0f3c10] [c0000000002ba4ec] .sys_sendto+0xd4/0x120
>> [c00000076f0f3d90] [c0000000002df2f8] .compat_sys_socketcall+0x148/0x214
>> [c00000076f0f3e30] [c00000000000872c] syscall_exit+0x0/0x40
>> Instruction dump:
>> 720b0001 eb970000 40820070 72000002 4182000c e8bc0000 48000018 72080004 
>> 4182000c e8bc0008 48000008 e8bc0010 <e8c10078> 7f83e378 7de407b4 7e078378 
>>
> 
> hm.  Beats me.  Does the machine recover OK?
> -
Hi Andrew,

In the set of test cases ran serially, the softlockup in seen in tbench,
then the remaining test cases get to run successfully after the softlockup.

-- 
Thanks & Regards,
Kamalesh Babulal,
Linux Technology Center,
IBM, ISTL.

^ permalink raw reply

* [PATCH 0/11] ibm_newemac: Candidate patches for 2.6.25
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev

Here are the patches I have pending for EMAC. With those, along with
some other powerpc patches scheduled for 2.6.25 for adding support
for those various boards, I have EMAC now working properly on a
variety of platforms, such as Taishan (440GX), Katmai (440SP),
EP405 (405GP), Bamboo (440EP), etc...

This serie apply on top of the patch:

"ibm_newemac: Fix possible lockup on close"

Which should be on its way to 2.6.24 already.

^ permalink raw reply

* [PATCH 1/11] ibm_newemac: Add BCM5248 and Marvell 88E1111 PHY support
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <1196401223.5661.297518056501.qpush@grosgo>

From: Stefan Roese <sr@denx.de>

This patch adds BCM5248 and Marvell 88E1111 PHY support to NEW EMAC driver.
These PHY chips are used on PowerPC 440EPx boards.
The PHY code is based on the previous work by Stefan Roese <sr@denx.de>

Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Valentine Barshak <vbarshak@ru.mvista.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

--- linux.orig/drivers/net/ibm_newemac/phy.c	2007-06-15 21:45:18.000000000 +0400
+++ linux/drivers/net/ibm_newemac/phy.c	2007-06-15 20:45:15.000000000 +0400
@@ -306,8 +306,47 @@
 	.ops		= &cis8201_phy_ops
 };
 
+static struct mii_phy_def bcm5248_phy_def = {
+
+	.phy_id		= 0x0143bc00,
+	.phy_id_mask	= 0x0ffffff0,
+	.name		= "BCM5248 10/100 SMII Ethernet",
+	.ops		= &generic_phy_ops
+};
+
+static int m88e1111_init(struct mii_phy *phy)
+{
+	printk("%s: Marvell 88E1111 Ethernet\n", __FUNCTION__);
+	phy_write(phy, 0x14, 0x0ce3);
+	phy_write(phy, 0x18, 0x4101);
+	phy_write(phy, 0x09, 0x0e00);
+	phy_write(phy, 0x04, 0x01e1);
+	phy_write(phy, 0x00, 0x9140);
+	phy_write(phy, 0x00, 0x1140);
+
+	return  0;
+}
+
+static struct mii_phy_ops m88e1111_phy_ops = {
+	.init		= m88e1111_init,
+	.setup_aneg	= genmii_setup_aneg,
+	.setup_forced	= genmii_setup_forced,
+	.poll_link	= genmii_poll_link,
+	.read_link	= genmii_read_link
+};
+
+static struct mii_phy_def m88e1111_phy_def = {
+
+	.phy_id		= 0x01410CC0,
+	.phy_id_mask	= 0x0ffffff0,
+	.name		= "Marvell 88E1111 Ethernet",
+	.ops		= &m88e1111_phy_ops,
+};
+
 static struct mii_phy_def *mii_phy_table[] = {
 	&cis8201_phy_def,
+	&bcm5248_phy_def,
+	&m88e1111_phy_def,
 	&genmii_phy_def,
 	NULL
 };
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* [PATCH 2/11] ibm_newemac: Add ET1011c PHY support
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <1196401223.5661.297518056501.qpush@grosgo>

From: Stefan Roese <sr@denx.de>

This adds support for the Agere ET1011c PHY as found on the AMCC Taishan
board.

Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

 drivers/net/ibm_newemac/phy.c |   37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

Index: linux-work/drivers/net/ibm_newemac/phy.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/phy.c	2007-11-08 18:54:12.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/phy.c	2007-11-08 18:54:13.000000000 +1100
@@ -327,6 +327,42 @@ static int m88e1111_init(struct mii_phy 
 	return  0;
 }
 
+static int et1011c_init(struct mii_phy *phy)
+{
+        u16 reg_short;
+
+        reg_short = (u16)(phy_read(phy,0x16));
+        reg_short &= ~(0x7);
+        reg_short |= 0x6;       /* RGMII Trace Delay*/
+        phy_write(phy, 0x16, reg_short);
+
+        reg_short = (u16)(phy_read(phy, 0x17));
+        reg_short &= ~(0x40);
+        phy_write(phy, 0x17, reg_short);
+
+        phy_write(phy,0x1c,0x74f0);
+        return 0;
+}
+
+static struct mii_phy_ops et1011c_phy_ops = {
+        .init           = et1011c_init,
+        .setup_aneg     = genmii_setup_aneg,
+        .setup_forced   = genmii_setup_forced,
+        .poll_link      = genmii_poll_link,
+        .read_link      = genmii_read_link
+};
+
+static struct mii_phy_def et1011c_phy_def = {
+        .phy_id         = 0x0282f000,
+        .phy_id_mask    = 0x0fffff00,
+        .name           = "ET1011C Gigabit Ethernet",
+        .ops            = &et1011c_phy_ops
+};
+
+
+
+
+
 static struct mii_phy_ops m88e1111_phy_ops = {
 	.init		= m88e1111_init,
 	.setup_aneg	= genmii_setup_aneg,
@@ -344,6 +380,7 @@ static struct mii_phy_def m88e1111_phy_d
 };
 
 static struct mii_phy_def *mii_phy_table[] = {
+	&et1011c_phy_def,
 	&cis8201_phy_def,
 	&bcm5248_phy_def,
 	&m88e1111_phy_def,

^ permalink raw reply

* [PATCH 3/11] ibm_newemac: Fix ZMII refcounting bug
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <1196401223.5661.297518056501.qpush@grosgo>

When using ZMII for MDIO only (such as 440GX with RGMII for data and ZMII for
MDIO), the ZMII code would fail to properly refcount, thus triggering a
BUG_ON().

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Stefan Roese <sr@denx.de>
---

 drivers/net/ibm_newemac/zmii.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Index: linux-work/drivers/net/ibm_newemac/zmii.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/zmii.c	2007-11-08 15:45:32.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/zmii.c	2007-11-08 15:46:21.000000000 +1100
@@ -83,12 +83,14 @@ int __devinit zmii_attach(struct of_devi
 
 	ZMII_DBG(dev, "init(%d, %d)" NL, input, *mode);
 
-	if (!zmii_valid_mode(*mode))
+	if (!zmii_valid_mode(*mode)) {
 		/* Probably an EMAC connected to RGMII,
 		 * but it still may need ZMII for MDIO so
 		 * we don't fail here.
 		 */
+		dev->users++;
 		return 0;
+	}
 
 	mutex_lock(&dev->lock);
 

^ permalink raw reply

* [PATCH 4/11] ibm_newemac: Workaround reset timeout when no link
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <1196401223.5661.297518056501.qpush@grosgo>

With some PHYs, when the link goes away, the EMAC reset fails due
to the loss of the RX clock I believe.

The old EMAC driver worked around that using some internal chip-specific
clock force bits that are different on various 44x implementations.

This is an attempt at doing it differently, by avoiding the reset when
there is no link, but forcing loopback mode instead. It seems to work
on my Taishan 440GX based board so far.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Stefan Roese <sr@denx.de>
---

 drivers/net/ibm_newemac/core.c |   20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

Index: linux-work/drivers/net/ibm_newemac/core.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/core.c	2007-11-20 14:46:51.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/core.c	2007-11-20 14:46:58.000000000 +1100
@@ -464,26 +464,34 @@ static int emac_configure(struct emac_in
 {
 	struct emac_regs __iomem *p = dev->emacp;
 	struct net_device *ndev = dev->ndev;
-	int tx_size, rx_size;
+	int tx_size, rx_size, link = netif_carrier_ok(dev->ndev);
 	u32 r, mr1 = 0;
 
 	DBG(dev, "configure" NL);
 
-	if (emac_reset(dev) < 0)
+	if (!link) {
+		out_be32(&p->mr1, in_be32(&p->mr1)
+			 | EMAC_MR1_FDE | EMAC_MR1_ILE);
+		udelay(100);
+	} else if (emac_reset(dev) < 0)
 		return -ETIMEDOUT;
 
 	if (emac_has_feature(dev, EMAC_FTR_HAS_TAH))
 		tah_reset(dev->tah_dev);
 
-	DBG(dev, " duplex = %d, pause = %d, asym_pause = %d\n",
-	    dev->phy.duplex, dev->phy.pause, dev->phy.asym_pause);
+	DBG(dev, " link = %d duplex = %d, pause = %d, asym_pause = %d\n",
+	    link, dev->phy.duplex, dev->phy.pause, dev->phy.asym_pause);
 
 	/* Default fifo sizes */
 	tx_size = dev->tx_fifo_size;
 	rx_size = dev->rx_fifo_size;
 
+	/* No link, force loopback */
+	if (!link)
+		mr1 = EMAC_MR1_FDE | EMAC_MR1_ILE;
+
 	/* Check for full duplex */
-	if (dev->phy.duplex == DUPLEX_FULL)
+	else if (dev->phy.duplex == DUPLEX_FULL)
 		mr1 |= EMAC_MR1_FDE | EMAC_MR1_MWSW_001;
 
 	/* Adjust fifo sizes, mr1 and timeouts based on link speed */
@@ -1165,9 +1173,9 @@ static void emac_link_timer(struct work_
 		link_poll_interval = PHY_POLL_LINK_ON;
 	} else {
 		if (netif_carrier_ok(dev->ndev)) {
-			emac_reinitialize(dev);
 			netif_carrier_off(dev->ndev);
 			netif_tx_disable(dev->ndev);
+			emac_reinitialize(dev);
 			emac_print_link_status(dev);
 		}
 		link_poll_interval = PHY_POLL_LINK_OFF;

^ permalink raw reply

* [PATCH 5/11] ibm_newemac: Cleanup/Fix RGMII MDIO support detection
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <1196401223.5661.297518056501.qpush@grosgo>

More than just "AXON" version of EMAC RGMII supports MDIO, so replace
the current test with a generic property in the device-tree that
indicates such support.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Stefan Roese <sr@denx.de>
---

 arch/powerpc/boot/dts/sequoia.dts |    1 +
 drivers/net/ibm_newemac/rgmii.c   |   20 +++++++++++---------
 drivers/net/ibm_newemac/rgmii.h   |    5 +++--
 3 files changed, 15 insertions(+), 11 deletions(-)

Index: linux-work/drivers/net/ibm_newemac/rgmii.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/rgmii.c	2007-11-12 10:55:54.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/rgmii.c	2007-11-12 10:56:56.000000000 +1100
@@ -140,7 +140,7 @@ void rgmii_get_mdio(struct of_device *of
 
 	RGMII_DBG2(dev, "get_mdio(%d)" NL, input);
 
-	if (dev->type != RGMII_AXON)
+	if (!(dev->flags & EMAC_RGMII_FLAG_HAS_MDIO))
 		return;
 
 	mutex_lock(&dev->lock);
@@ -161,7 +161,7 @@ void rgmii_put_mdio(struct of_device *of
 
 	RGMII_DBG2(dev, "put_mdio(%d)" NL, input);
 
-	if (dev->type != RGMII_AXON)
+	if (!(dev->flags & EMAC_RGMII_FLAG_HAS_MDIO))
 		return;
 
 	fer = in_be32(&p->fer);
@@ -250,11 +250,13 @@ static int __devinit rgmii_probe(struct 
 		goto err_free;
 	}
 
-	/* Check for RGMII type */
+	/* Check for RGMII flags */
+	if (of_get_property(ofdev->node, "has-mdio", NULL))
+		dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO;
+
+	/* CAB lacks the right properties, fix this up */
 	if (of_device_is_compatible(ofdev->node, "ibm,rgmii-axon"))
-		dev->type = RGMII_AXON;
-	else
-		dev->type = RGMII_STANDARD;
+		dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO;
 
 	DBG2(dev, " Boot FER = 0x%08x, SSR = 0x%08x\n",
 	     in_be32(&dev->base->fer), in_be32(&dev->base->ssr));
@@ -263,9 +265,9 @@ static int __devinit rgmii_probe(struct 
 	out_be32(&dev->base->fer, 0);
 
 	printk(KERN_INFO
-	       "RGMII %s %s initialized\n",
-	       dev->type == RGMII_STANDARD ? "standard" : "axon",
-	       ofdev->node->full_name);
+	       "RGMII %s initialized with%s MDIO support\n",
+	       ofdev->node->full_name,
+	       (dev->flags & EMAC_RGMII_FLAG_HAS_MDIO) ? "" : "out");
 
 	wmb();
 	dev_set_drvdata(&ofdev->dev, dev);
Index: linux-work/drivers/net/ibm_newemac/rgmii.h
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/rgmii.h	2007-11-12 10:55:54.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/rgmii.h	2007-11-12 10:56:56.000000000 +1100
@@ -35,8 +35,9 @@ struct rgmii_regs {
 struct rgmii_instance {
 	struct rgmii_regs __iomem	*base;
 
-	/* Type of RGMII bridge */
-	int				type;
+	/* RGMII bridge flags */
+	int				flags;
+#define EMAC_RGMII_FLAG_HAS_MDIO	0x00000001
 
 	/* Only one EMAC whacks us at a time */
 	struct mutex			lock;
Index: linux-work/arch/powerpc/boot/dts/sequoia.dts
===================================================================
--- linux-work.orig/arch/powerpc/boot/dts/sequoia.dts	2007-11-12 10:58:38.000000000 +1100
+++ linux-work/arch/powerpc/boot/dts/sequoia.dts	2007-11-12 10:58:47.000000000 +1100
@@ -245,6 +245,7 @@
 				device_type = "rgmii-interface";
 				compatible = "ibm,rgmii-440epx", "ibm,rgmii";
 				reg = <ef601000 8>;
+				has-mdio;
 			};
 
 			EMAC0: ethernet@ef600e00 {

^ 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