All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/10] net/fec: add dual fec support for i.MX28
@ 2011-01-06  7:13 ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig

This patch series is to add dual fec support for mx28, which is
a mxs-based soc. Some code changes related to the following commits
are also made in this patch set for some reasons.

 e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
 netdev/fec.c: add phylib supporting to enable carrier detection (v2)

 e3fe8558c7fc182972c3d947d88744482111f304
 net/fec: fix pm to survive to suspend/resume

It's been tested on mx28 evk and mx51 babbage. For mx28, it has
to work against the tree

 git://git.pengutronix.de/git/imx/linux-2.6.git imx-for-2.6.38

plus patch

 [PATCH v4] ARM: mxs: Change duart device to use amba-pl011

The 3 patches below preceding with * have changes since v3, and
the detailed change log can be found in individual patch.

 [PATCH v4 01/10] net/fec: fix MMFR_OP type in fec_enet_mdio_write
 [PATCH v4 02/10] net/fec: remove the use of "index" which is legacy
 [PATCH v4 03/10] net/fec: add mac field into platform data and consolidate fec_get_mac
 [PATCH v4 04/10] net/fec: improve pm for better suspend/resume
*[PATCH v4 05/10] net/fec: add dual fec support for mx28
*[PATCH v4 06/10] ARM: mx28: update clock and device name for dual fec support
 [PATCH v4 07/10] ARM: mx28: add the second fec device registration
*[PATCH v4 08/10] ARM: mxs: add ocotp read function
 [PATCH v4 09/10] ARM: mx28: read fec mac address from ocotp
 [PATCH v4 10/10] ARM: mxs: add initial pm support

Thanks for the review.

Regards,
Shawn


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 00/10] net/fec: add dual fec support for i.MX28
@ 2011-01-06  7:13 ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series is to add dual fec support for mx28, which is
a mxs-based soc. Some code changes related to the following commits
are also made in this patch set for some reasons.

 e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
 netdev/fec.c: add phylib supporting to enable carrier detection (v2)

 e3fe8558c7fc182972c3d947d88744482111f304
 net/fec: fix pm to survive to suspend/resume

It's been tested on mx28 evk and mx51 babbage. For mx28, it has
to work against the tree

 git://git.pengutronix.de/git/imx/linux-2.6.git imx-for-2.6.38

plus patch

 [PATCH v4] ARM: mxs: Change duart device to use amba-pl011

The 3 patches below preceding with * have changes since v3, and
the detailed change log can be found in individual patch.

 [PATCH v4 01/10] net/fec: fix MMFR_OP type in fec_enet_mdio_write
 [PATCH v4 02/10] net/fec: remove the use of "index" which is legacy
 [PATCH v4 03/10] net/fec: add mac field into platform data and consolidate fec_get_mac
 [PATCH v4 04/10] net/fec: improve pm for better suspend/resume
*[PATCH v4 05/10] net/fec: add dual fec support for mx28
*[PATCH v4 06/10] ARM: mx28: update clock and device name for dual fec support
 [PATCH v4 07/10] ARM: mx28: add the second fec device registration
*[PATCH v4 08/10] ARM: mxs: add ocotp read function
 [PATCH v4 09/10] ARM: mx28: read fec mac address from ocotp
 [PATCH v4 10/10] ARM: mxs: add initial pm support

Thanks for the review.

Regards,
Shawn

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 01/10] net/fec: fix MMFR_OP type in fec_enet_mdio_write
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-06  7:13   ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig

FEC_MMFR_OP_WRITE should be used than FEC_MMFR_OP_READ in
a mdio write operation.

It's probably a typo introduced by commit:

e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
netdev/fec.c: add phylib supporting to enable carrier detection (v2)

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 drivers/net/fec.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index cce32d4..52e9ca8 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -651,8 +651,8 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
 	fep->mii_timeout = 0;
 	init_completion(&fep->mdio_done);
 
-	/* start a read op */
-	writel(FEC_MMFR_ST | FEC_MMFR_OP_READ |
+	/* start a write op */
+	writel(FEC_MMFR_ST | FEC_MMFR_OP_WRITE |
 		FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(regnum) |
 		FEC_MMFR_TA | FEC_MMFR_DATA(value),
 		fep->hwp + FEC_MII_DATA);
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 01/10] net/fec: fix MMFR_OP type in fec_enet_mdio_write
@ 2011-01-06  7:13   ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: linux-arm-kernel

FEC_MMFR_OP_WRITE should be used than FEC_MMFR_OP_READ in
a mdio write operation.

It's probably a typo introduced by commit:

e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
netdev/fec.c: add phylib supporting to enable carrier detection (v2)

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 drivers/net/fec.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index cce32d4..52e9ca8 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -651,8 +651,8 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
 	fep->mii_timeout = 0;
 	init_completion(&fep->mdio_done);
 
-	/* start a read op */
-	writel(FEC_MMFR_ST | FEC_MMFR_OP_READ |
+	/* start a write op */
+	writel(FEC_MMFR_ST | FEC_MMFR_OP_WRITE |
 		FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(regnum) |
 		FEC_MMFR_TA | FEC_MMFR_DATA(value),
 		fep->hwp + FEC_MII_DATA);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 02/10] net/fec: remove the use of "index" which is legacy
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-06  7:13   ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig

The "index" becomes legacy since fep->pdev->id starts working
to identify the instance.

Moreover, the call of fec_enet_init(ndev, 0) always passes 0
to fep->index. This makes the following code in fec_get_mac buggy.

	/* Adjust MAC if using default MAC address */
	if (iap == fec_mac_default)
		dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;

It may be the time to remove "index" and use fep->pdev->id instead.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 drivers/net/fec.c |    9 +++------
 1 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 52e9ca8..47f6b3b 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -186,7 +186,6 @@ struct fec_enet_private {
 	int     mii_timeout;
 	uint    phy_speed;
 	phy_interface_t	phy_interface;
-	int	index;
 	int	link;
 	int	full_duplex;
 	struct	completion mdio_done;
@@ -566,7 +565,7 @@ static void __inline__ fec_get_mac(struct net_device *dev)
 
 	/* Adjust MAC if using default MAC address */
 	if (iap == fec_mac_default)
-		 dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
+		 dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->pdev->id;
 }
 #endif
 
@@ -1067,9 +1066,8 @@ static const struct net_device_ops fec_netdev_ops = {
  /*
   * XXX:  We need to clean up on failure exits here.
   *
-  * index is only used in legacy code
   */
-static int fec_enet_init(struct net_device *dev, int index)
+static int fec_enet_init(struct net_device *dev)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
 	struct bufdesc *cbd_base;
@@ -1086,7 +1084,6 @@ static int fec_enet_init(struct net_device *dev, int index)
 
 	spin_lock_init(&fep->hw_lock);
 
-	fep->index = index;
 	fep->hwp = (void __iomem *)dev->base_addr;
 	fep->netdev = dev;
 
@@ -1316,7 +1313,7 @@ fec_probe(struct platform_device *pdev)
 	}
 	clk_enable(fep->clk);
 
-	ret = fec_enet_init(ndev, 0);
+	ret = fec_enet_init(ndev);
 	if (ret)
 		goto failed_init;
 
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 02/10] net/fec: remove the use of "index" which is legacy
@ 2011-01-06  7:13   ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: linux-arm-kernel

The "index" becomes legacy since fep->pdev->id starts working
to identify the instance.

Moreover, the call of fec_enet_init(ndev, 0) always passes 0
to fep->index. This makes the following code in fec_get_mac buggy.

	/* Adjust MAC if using default MAC address */
	if (iap == fec_mac_default)
		dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;

It may be the time to remove "index" and use fep->pdev->id instead.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 drivers/net/fec.c |    9 +++------
 1 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 52e9ca8..47f6b3b 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -186,7 +186,6 @@ struct fec_enet_private {
 	int     mii_timeout;
 	uint    phy_speed;
 	phy_interface_t	phy_interface;
-	int	index;
 	int	link;
 	int	full_duplex;
 	struct	completion mdio_done;
@@ -566,7 +565,7 @@ static void __inline__ fec_get_mac(struct net_device *dev)
 
 	/* Adjust MAC if using default MAC address */
 	if (iap == fec_mac_default)
-		 dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
+		 dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->pdev->id;
 }
 #endif
 
@@ -1067,9 +1066,8 @@ static const struct net_device_ops fec_netdev_ops = {
  /*
   * XXX:  We need to clean up on failure exits here.
   *
-  * index is only used in legacy code
   */
-static int fec_enet_init(struct net_device *dev, int index)
+static int fec_enet_init(struct net_device *dev)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
 	struct bufdesc *cbd_base;
@@ -1086,7 +1084,6 @@ static int fec_enet_init(struct net_device *dev, int index)
 
 	spin_lock_init(&fep->hw_lock);
 
-	fep->index = index;
 	fep->hwp = (void __iomem *)dev->base_addr;
 	fep->netdev = dev;
 
@@ -1316,7 +1313,7 @@ fec_probe(struct platform_device *pdev)
 	}
 	clk_enable(fep->clk);
 
-	ret = fec_enet_init(ndev, 0);
+	ret = fec_enet_init(ndev);
 	if (ret)
 		goto failed_init;
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 03/10] net/fec: add mac field into platform data and consolidate fec_get_mac
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-06  7:13   ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig

Add mac field into fec_platform_data and consolidate function
fec_get_mac to get mac address in following order.

 1) module parameter via kernel command line fec.macaddr=0x00,0x04,...
 2) from flash in case of CONFIG_M5272 or fec_platform_data mac
    field for others, which typically have mac stored in fuse
 3) fec mac address registers set by bootloader

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - Use module parameter than new kernel command line to pass
   mac address
 - Change variable name and comment to remove confusing word
   "default"
 - Fix copyright breakage in fec.h

 drivers/net/fec.c   |   81 ++++++++++++++++++++++++---------------------------
 include/linux/fec.h |    3 ++
 2 files changed, 41 insertions(+), 43 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 47f6b3b..47a3c7b 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -59,15 +59,11 @@
 #define FEC_ALIGNMENT	0x3
 #endif
 
-/*
- * Define the fixed address of the FEC hardware.
- */
-#if defined(CONFIG_M5272)
-
-static unsigned char	fec_mac_default[] = {
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
+static unsigned char macaddr[ETH_ALEN];
+module_param_array(macaddr, byte, NULL, 0);
+MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
 
+#if defined(CONFIG_M5272)
 /*
  * Some hardware gets it MAC address out of local flash memory.
  * if this is non-zero then assume it is the address to get MAC from.
@@ -537,37 +533,50 @@ rx_processing_done:
 }
 
 /* ------------------------------------------------------------------------- */
-#ifdef CONFIG_M5272
 static void __inline__ fec_get_mac(struct net_device *dev)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
+	struct fec_platform_data *pdata = fep->pdev->dev.platform_data;
 	unsigned char *iap, tmpaddr[ETH_ALEN];
 
-	if (FEC_FLASHMAC) {
-		/*
-		 * Get MAC address from FLASH.
-		 * If it is all 1's or 0's, use the default.
-		 */
-		iap = (unsigned char *)FEC_FLASHMAC;
-		if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
-		    (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
-			iap = fec_mac_default;
-		if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
-		    (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
-			iap = fec_mac_default;
-	} else {
-		*((unsigned long *) &tmpaddr[0]) = readl(fep->hwp + FEC_ADDR_LOW);
-		*((unsigned short *) &tmpaddr[4]) = (readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
+	/*
+	 * try to get mac address in following order:
+	 *
+	 * 1) module parameter via kernel command line in form
+	 *    fec.macaddr=0x00,0x04,0x9f,0x01,0x30,0xe0
+	 */
+	iap = macaddr;
+
+	/*
+	 * 2) from flash or fuse (via platform data)
+	 */
+	if (!is_valid_ether_addr(iap)) {
+#ifdef CONFIG_M5272
+		if (FEC_FLASHMAC)
+			iap = (unsigned char *)FEC_FLASHMAC;
+#else
+		if (pdata)
+			memcpy(iap, pdata->mac, ETH_ALEN);
+#endif
+	}
+
+	/*
+	 * 3) FEC mac registers set by bootloader
+	 */
+	if (!is_valid_ether_addr(iap)) {
+		*((unsigned long *) &tmpaddr[0]) =
+			be32_to_cpu(readl(fep->hwp + FEC_ADDR_LOW));
+		*((unsigned short *) &tmpaddr[4]) =
+			be16_to_cpu(readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
 		iap = &tmpaddr[0];
 	}
 
 	memcpy(dev->dev_addr, iap, ETH_ALEN);
 
-	/* Adjust MAC if using default MAC address */
-	if (iap == fec_mac_default)
-		 dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->pdev->id;
+	/* Adjust MAC if using macaddr */
+	if (iap == macaddr)
+		 dev->dev_addr[ETH_ALEN-1] = macaddr[ETH_ALEN-1] + fep->pdev->id;
 }
-#endif
 
 /* ------------------------------------------------------------------------- */
 
@@ -1087,22 +1096,8 @@ static int fec_enet_init(struct net_device *dev)
 	fep->hwp = (void __iomem *)dev->base_addr;
 	fep->netdev = dev;
 
-	/* Set the Ethernet address */
-#ifdef CONFIG_M5272
+	/* Get the Ethernet address */
 	fec_get_mac(dev);
-#else
-	{
-		unsigned long l;
-		l = readl(fep->hwp + FEC_ADDR_LOW);
-		dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24);
-		dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16);
-		dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8);
-		dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0);
-		l = readl(fep->hwp + FEC_ADDR_HIGH);
-		dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24);
-		dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16);
-	}
-#endif
 
 	/* Set receive and transmit descriptor base. */
 	fep->rx_bd_base = cbd_base;
diff --git a/include/linux/fec.h b/include/linux/fec.h
index 5d3523d..bcff455 100644
--- a/include/linux/fec.h
+++ b/include/linux/fec.h
@@ -3,6 +3,8 @@
  * Copyright (c) 2009 Orex Computed Radiography
  *   Baruch Siach <baruch@tkos.co.il>
  *
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
  * Header file for the FEC platform data
  *
  * This program is free software; you can redistribute it and/or modify
@@ -16,6 +18,7 @@
 
 struct fec_platform_data {
 	phy_interface_t phy;
+	unsigned char mac[ETH_ALEN];
 };
 
 #endif
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 03/10] net/fec: add mac field into platform data and consolidate fec_get_mac
@ 2011-01-06  7:13   ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: linux-arm-kernel

Add mac field into fec_platform_data and consolidate function
fec_get_mac to get mac address in following order.

 1) module parameter via kernel command line fec.macaddr=0x00,0x04,...
 2) from flash in case of CONFIG_M5272 or fec_platform_data mac
    field for others, which typically have mac stored in fuse
 3) fec mac address registers set by bootloader

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - Use module parameter than new kernel command line to pass
   mac address
 - Change variable name and comment to remove confusing word
   "default"
 - Fix copyright breakage in fec.h

 drivers/net/fec.c   |   81 ++++++++++++++++++++++++---------------------------
 include/linux/fec.h |    3 ++
 2 files changed, 41 insertions(+), 43 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 47f6b3b..47a3c7b 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -59,15 +59,11 @@
 #define FEC_ALIGNMENT	0x3
 #endif
 
-/*
- * Define the fixed address of the FEC hardware.
- */
-#if defined(CONFIG_M5272)
-
-static unsigned char	fec_mac_default[] = {
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
+static unsigned char macaddr[ETH_ALEN];
+module_param_array(macaddr, byte, NULL, 0);
+MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
 
+#if defined(CONFIG_M5272)
 /*
  * Some hardware gets it MAC address out of local flash memory.
  * if this is non-zero then assume it is the address to get MAC from.
@@ -537,37 +533,50 @@ rx_processing_done:
 }
 
 /* ------------------------------------------------------------------------- */
-#ifdef CONFIG_M5272
 static void __inline__ fec_get_mac(struct net_device *dev)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
+	struct fec_platform_data *pdata = fep->pdev->dev.platform_data;
 	unsigned char *iap, tmpaddr[ETH_ALEN];
 
-	if (FEC_FLASHMAC) {
-		/*
-		 * Get MAC address from FLASH.
-		 * If it is all 1's or 0's, use the default.
-		 */
-		iap = (unsigned char *)FEC_FLASHMAC;
-		if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
-		    (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
-			iap = fec_mac_default;
-		if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
-		    (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
-			iap = fec_mac_default;
-	} else {
-		*((unsigned long *) &tmpaddr[0]) = readl(fep->hwp + FEC_ADDR_LOW);
-		*((unsigned short *) &tmpaddr[4]) = (readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
+	/*
+	 * try to get mac address in following order:
+	 *
+	 * 1) module parameter via kernel command line in form
+	 *    fec.macaddr=0x00,0x04,0x9f,0x01,0x30,0xe0
+	 */
+	iap = macaddr;
+
+	/*
+	 * 2) from flash or fuse (via platform data)
+	 */
+	if (!is_valid_ether_addr(iap)) {
+#ifdef CONFIG_M5272
+		if (FEC_FLASHMAC)
+			iap = (unsigned char *)FEC_FLASHMAC;
+#else
+		if (pdata)
+			memcpy(iap, pdata->mac, ETH_ALEN);
+#endif
+	}
+
+	/*
+	 * 3) FEC mac registers set by bootloader
+	 */
+	if (!is_valid_ether_addr(iap)) {
+		*((unsigned long *) &tmpaddr[0]) =
+			be32_to_cpu(readl(fep->hwp + FEC_ADDR_LOW));
+		*((unsigned short *) &tmpaddr[4]) =
+			be16_to_cpu(readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
 		iap = &tmpaddr[0];
 	}
 
 	memcpy(dev->dev_addr, iap, ETH_ALEN);
 
-	/* Adjust MAC if using default MAC address */
-	if (iap == fec_mac_default)
-		 dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->pdev->id;
+	/* Adjust MAC if using macaddr */
+	if (iap == macaddr)
+		 dev->dev_addr[ETH_ALEN-1] = macaddr[ETH_ALEN-1] + fep->pdev->id;
 }
-#endif
 
 /* ------------------------------------------------------------------------- */
 
@@ -1087,22 +1096,8 @@ static int fec_enet_init(struct net_device *dev)
 	fep->hwp = (void __iomem *)dev->base_addr;
 	fep->netdev = dev;
 
-	/* Set the Ethernet address */
-#ifdef CONFIG_M5272
+	/* Get the Ethernet address */
 	fec_get_mac(dev);
-#else
-	{
-		unsigned long l;
-		l = readl(fep->hwp + FEC_ADDR_LOW);
-		dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24);
-		dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16);
-		dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8);
-		dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0);
-		l = readl(fep->hwp + FEC_ADDR_HIGH);
-		dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24);
-		dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16);
-	}
-#endif
 
 	/* Set receive and transmit descriptor base. */
 	fep->rx_bd_base = cbd_base;
diff --git a/include/linux/fec.h b/include/linux/fec.h
index 5d3523d..bcff455 100644
--- a/include/linux/fec.h
+++ b/include/linux/fec.h
@@ -3,6 +3,8 @@
  * Copyright (c) 2009 Orex Computed Radiography
  *   Baruch Siach <baruch@tkos.co.il>
  *
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
  * Header file for the FEC platform data
  *
  * This program is free software; you can redistribute it and/or modify
@@ -16,6 +18,7 @@
 
 struct fec_platform_data {
 	phy_interface_t phy;
+	unsigned char mac[ETH_ALEN];
 };
 
 #endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 04/10] net/fec: improve pm for better suspend/resume
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-06  7:13   ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig

The following commit made a fix to use fec_enet_open/fec_enet_close
over fec_enet_init/fec_stop for suspend/resume, because fec_enet_init
does not allow to have a working network interface at resume.

  e3fe8558c7fc182972c3d947d88744482111f304
  net/fec: fix pm to survive to suspend/resume

This fix works for i.mx/mxc fec controller, but fails on mx28 fec
which gets a different interrupt logic design. On i.mx fec, interrupt
can be triggered even bit ETHER_EN of ECR register is not set. But
on mx28 fec, ETHER_EN must be set to get interrupt work. Meanwhile,
MII interrupt is mandatory to resume the driver, because MDIO
read/write changed to interrupt mode by commit below.

  97b72e4320a9aaa4a7f1592ee7d2da7e2c9bd349
  fec: use interrupt for MDIO completion indication

fec_restart/fec_stop comes out as the solution working for both
cases.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 drivers/net/fec.c |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 47a3c7b..8a1c51f 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1372,8 +1372,10 @@ fec_suspend(struct device *dev)
 
 	if (ndev) {
 		fep = netdev_priv(ndev);
-		if (netif_running(ndev))
-			fec_enet_close(ndev);
+		if (netif_running(ndev)) {
+			fec_stop(ndev);
+			netif_device_detach(ndev);
+		}
 		clk_disable(fep->clk);
 	}
 	return 0;
@@ -1388,8 +1390,10 @@ fec_resume(struct device *dev)
 	if (ndev) {
 		fep = netdev_priv(ndev);
 		clk_enable(fep->clk);
-		if (netif_running(ndev))
-			fec_enet_open(ndev);
+		if (netif_running(ndev)) {
+			fec_restart(ndev, fep->full_duplex);
+			netif_device_attach(ndev);
+		}
 	}
 	return 0;
 }
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 04/10] net/fec: improve pm for better suspend/resume
@ 2011-01-06  7:13   ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: linux-arm-kernel

The following commit made a fix to use fec_enet_open/fec_enet_close
over fec_enet_init/fec_stop for suspend/resume, because fec_enet_init
does not allow to have a working network interface at resume.

  e3fe8558c7fc182972c3d947d88744482111f304
  net/fec: fix pm to survive to suspend/resume

This fix works for i.mx/mxc fec controller, but fails on mx28 fec
which gets a different interrupt logic design. On i.mx fec, interrupt
can be triggered even bit ETHER_EN of ECR register is not set. But
on mx28 fec, ETHER_EN must be set to get interrupt work. Meanwhile,
MII interrupt is mandatory to resume the driver, because MDIO
read/write changed to interrupt mode by commit below.

  97b72e4320a9aaa4a7f1592ee7d2da7e2c9bd349
  fec: use interrupt for MDIO completion indication

fec_restart/fec_stop comes out as the solution working for both
cases.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 drivers/net/fec.c |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 47a3c7b..8a1c51f 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1372,8 +1372,10 @@ fec_suspend(struct device *dev)
 
 	if (ndev) {
 		fep = netdev_priv(ndev);
-		if (netif_running(ndev))
-			fec_enet_close(ndev);
+		if (netif_running(ndev)) {
+			fec_stop(ndev);
+			netif_device_detach(ndev);
+		}
 		clk_disable(fep->clk);
 	}
 	return 0;
@@ -1388,8 +1390,10 @@ fec_resume(struct device *dev)
 	if (ndev) {
 		fep = netdev_priv(ndev);
 		clk_enable(fep->clk);
-		if (netif_running(ndev))
-			fec_enet_open(ndev);
+		if (netif_running(ndev)) {
+			fec_restart(ndev, fep->full_duplex);
+			netif_device_attach(ndev);
+		}
 	}
 	return 0;
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-06  7:13   ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig

This patch is to add mx28 dual fec support. Here are some key notes
for mx28 fec controller.

 - The mx28 fec controller naming ENET-MAC is a different IP from FEC
   used on other i.mx variants.  But they are basically compatible
   on software interface, so it's possible to share the same driver.
 - ENET-MAC design on mx28 made an improper assumption that it runs
   on a big-endian system. As the result, driver has to swap every
   frame going to and coming from the controller.
 - The external phys can only be configured by fec0, which means fec1
   can not work independently and both phys need to be configured by
   mii_bus attached on fec0.
 - ENET-MAC reset will get mac address registers reset too.
 - ENET-MAC MII/RMII mode and 10M/100M speed are configured
   differently FEC.
 - ETHER_EN bit must be set to get ENET-MAC interrupt work.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v4:
 - Use #ifndef CONFIG_ARM to include ColdFire header files
 - Define quirk bits in id_entry.driver_data to handle controller
   difference, which is more scalable than using device name
 - Define fec0_mii_bus as a static function in fec_enet_mii_init
   to fold the mii_bus instance attached on fec0
 - Use cpu_to_be32 over __swab32 in function swap_buffer

Changes for v3:
 - Move v2 changes into patch #3
 - Use device name to check if it's running on ENET-MAC

 drivers/net/Kconfig |    7 ++-
 drivers/net/fec.c   |  148 +++++++++++++++++++++++++++++++++++++++++++++------
 drivers/net/fec.h   |    5 +-
 3 files changed, 139 insertions(+), 21 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 4f1755b..f34629b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1944,18 +1944,19 @@ config 68360_ENET
 config FEC
 	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
 	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
-		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
+		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
 	select PHYLIB
 	help
 	  Say Y here if you want to use the built-in 10/100 Fast ethernet
 	  controller on some Motorola ColdFire and Freescale i.MX processors.
 
 config FEC2
-	bool "Second FEC ethernet controller (on some ColdFire CPUs)"
+	bool "Second FEC ethernet controller"
 	depends on FEC
 	help
 	  Say Y here if you want to use the second built-in 10/100 Fast
-	  ethernet controller on some Motorola ColdFire processors.
+	  ethernet controller on some Motorola ColdFire and Freescale
+	  i.MX processors.
 
 config FEC_MPC52xx
 	tristate "MPC52xx FEC driver"
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 8a1c51f..2a71373 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -17,6 +17,8 @@
  *
  * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
  * Copyright (c) 2004-2006 Macq Electronique SA.
+ *
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
  */
 
 #include <linux/module.h>
@@ -45,20 +47,36 @@
 
 #include <asm/cacheflush.h>
 
-#ifndef CONFIG_ARCH_MXC
+#ifndef CONFIG_ARM
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
 #endif
 
 #include "fec.h"
 
-#ifdef CONFIG_ARCH_MXC
-#include <mach/hardware.h>
+#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
 #define FEC_ALIGNMENT	0xf
 #else
 #define FEC_ALIGNMENT	0x3
 #endif
 
+#define DRIVER_NAME	"fec"
+
+/* Controller is ENET-MAC */
+#define FEC_QUIRK_ENET_MAC		(1 << 0)
+/* Controller needs driver to swap frame */
+#define FEC_QUIRK_SWAP_FRAME		(1 << 1)
+
+static struct platform_device_id fec_devtype[] = {
+	{
+		.name = DRIVER_NAME,
+		.driver_data = 0,
+	}, {
+		.name = "imx28-fec",
+		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME,
+	}
+};
+
 static unsigned char macaddr[ETH_ALEN];
 module_param_array(macaddr, byte, NULL, 0);
 MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
@@ -129,7 +147,8 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
  * account when setting it.
  */
 #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
-    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
+    defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
+    defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
 #define	OPT_FRAME_SIZE	(PKT_MAXBUF_SIZE << 16)
 #else
 #define	OPT_FRAME_SIZE	0
@@ -208,10 +227,23 @@ static void fec_stop(struct net_device *dev);
 /* Transmitter timeout */
 #define TX_TIMEOUT (2 * HZ)
 
+static void *swap_buffer(void *bufaddr, int len)
+{
+	int i;
+	unsigned int *buf = bufaddr;
+
+	for (i = 0; i < (len + 3) / 4; i++, buf++)
+		*buf = cpu_to_be32(*buf);
+
+	return bufaddr;
+}
+
 static netdev_tx_t
 fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
+	const struct platform_device_id *id_entry =
+				platform_get_device_id(fep->pdev);
 	struct bufdesc *bdp;
 	void *bufaddr;
 	unsigned short	status;
@@ -256,6 +288,14 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		bufaddr = fep->tx_bounce[index];
 	}
 
+	/*
+	 * Some design made an incorrect assumption on endian mode of
+	 * the system that it's running on. As the result, driver has to
+	 * swap every frame going to and coming from the controller.
+	 */
+	if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
+		swap_buffer(bufaddr, skb->len);
+
 	/* Save skb pointer */
 	fep->tx_skbuff[fep->skb_cur] = skb;
 
@@ -424,6 +464,8 @@ static void
 fec_enet_rx(struct net_device *dev)
 {
 	struct	fec_enet_private *fep = netdev_priv(dev);
+	const struct platform_device_id *id_entry =
+				platform_get_device_id(fep->pdev);
 	struct bufdesc *bdp;
 	unsigned short status;
 	struct	sk_buff	*skb;
@@ -487,6 +529,9 @@ fec_enet_rx(struct net_device *dev)
 	        dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
         			DMA_FROM_DEVICE);
 
+		if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
+			swap_buffer(data, pkt_len);
+
 		/* This does 16 byte alignment, exactly what we need.
 		 * The packet length includes FCS, but we don't want to
 		 * include that when passing upstream as it messes up
@@ -689,6 +734,7 @@ static int fec_enet_mii_probe(struct net_device *dev)
 	char mdio_bus_id[MII_BUS_ID_SIZE];
 	char phy_name[MII_BUS_ID_SIZE + 3];
 	int phy_id;
+	int dev_id = fep->pdev->id;
 
 	fep->phy_dev = NULL;
 
@@ -700,6 +746,8 @@ static int fec_enet_mii_probe(struct net_device *dev)
 			continue;
 		if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
 			continue;
+		if (dev_id--)
+			continue;
 		strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);
 		break;
 	}
@@ -737,10 +785,35 @@ static int fec_enet_mii_probe(struct net_device *dev)
 
 static int fec_enet_mii_init(struct platform_device *pdev)
 {
+	static struct mii_bus *fec0_mii_bus;
 	struct net_device *dev = platform_get_drvdata(pdev);
 	struct fec_enet_private *fep = netdev_priv(dev);
+	const struct platform_device_id *id_entry =
+				platform_get_device_id(fep->pdev);
 	int err = -ENXIO, i;
 
+	/*
+	 * The dual fec interfaces are not equivalent with enet-mac.
+	 * Here are the differences:
+	 *
+	 *  - fec0 supports MII & RMII modes while fec1 only supports RMII
+	 *  - fec0 acts as the 1588 time master while fec1 is slave
+	 *  - external phys can only be configured by fec0
+	 *
+	 * That is to say fec1 can not work independently. It only works
+	 * when fec0 is working. The reason behind this design is that the
+	 * second interface is added primarily for Switch mode.
+	 *
+	 * Because of the last point above, both phys are attached on fec0
+	 * mdio interface in board design, and need to be configured by
+	 * fec0 mii_bus.
+	 */
+	if ((id_entry->driver_data & FEC_QUIRK_ENET_MAC) && pdev->id) {
+		/* fec1 uses fec0 mii_bus */
+		fep->mii_bus = fec0_mii_bus;
+		return 0;
+	}
+
 	fep->mii_timeout = 0;
 
 	/*
@@ -777,6 +850,10 @@ static int fec_enet_mii_init(struct platform_device *pdev)
 	if (mdiobus_register(fep->mii_bus))
 		goto err_out_free_mdio_irq;
 
+	/* save fec0 mii_bus */
+	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
+		fec0_mii_bus = fep->mii_bus;
+
 	return 0;
 
 err_out_free_mdio_irq:
@@ -1148,12 +1225,25 @@ static void
 fec_restart(struct net_device *dev, int duplex)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
+	const struct platform_device_id *id_entry =
+				platform_get_device_id(fep->pdev);
 	int i;
+	u32 val, temp_mac[2];
 
 	/* Whack a reset.  We should wait for this. */
 	writel(1, fep->hwp + FEC_ECNTRL);
 	udelay(10);
 
+	/*
+	 * enet-mac reset will reset mac address registers too,
+	 * so need to reconfigure it.
+	 */
+	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
+		memcpy(&temp_mac, dev->dev_addr, ETH_ALEN);
+		writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW);
+		writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH);
+	}
+
 	/* Clear any outstanding interrupt. */
 	writel(0xffc00000, fep->hwp + FEC_IEVENT);
 
@@ -1200,20 +1290,45 @@ fec_restart(struct net_device *dev, int duplex)
 	/* Set MII speed */
 	writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
 
-#ifdef FEC_MIIGSK_ENR
-	if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
-		/* disable the gasket and wait */
-		writel(0, fep->hwp + FEC_MIIGSK_ENR);
-		while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
-			udelay(1);
+	/*
+	 * The phy interface and speed need to get configured
+	 * differently on enet-mac.
+	 */
+	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
+		val = readl(fep->hwp + FEC_R_CNTRL);
 
-		/* configure the gasket: RMII, 50 MHz, no loopback, no echo */
-		writel(1, fep->hwp + FEC_MIIGSK_CFGR);
+		/* MII or RMII */
+		if (fep->phy_interface == PHY_INTERFACE_MODE_RMII)
+			val |= (1 << 8);
+		else
+			val &= ~(1 << 8);
 
-		/* re-enable the gasket */
-		writel(2, fep->hwp + FEC_MIIGSK_ENR);
-	}
+		/* 10M or 100M */
+		if (fep->phy_dev && fep->phy_dev->speed == SPEED_100)
+			val &= ~(1 << 9);
+		else
+			val |= (1 << 9);
+
+		writel(val, fep->hwp + FEC_R_CNTRL);
+	} else {
+#ifdef FEC_MIIGSK_ENR
+		if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
+			/* disable the gasket and wait */
+			writel(0, fep->hwp + FEC_MIIGSK_ENR);
+			while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
+				udelay(1);
+
+			/*
+			 * configure the gasket:
+			 *   RMII, 50 MHz, no loopback, no echo
+			 */
+			writel(1, fep->hwp + FEC_MIIGSK_CFGR);
+
+			/* re-enable the gasket */
+			writel(2, fep->hwp + FEC_MIIGSK_ENR);
+		}
 #endif
+	}
 
 	/* And last, enable the transmit and receive processing */
 	writel(2, fep->hwp + FEC_ECNTRL);
@@ -1410,12 +1525,13 @@ static const struct dev_pm_ops fec_pm_ops = {
 
 static struct platform_driver fec_driver = {
 	.driver	= {
-		.name	= "fec",
+		.name	= DRIVER_NAME,
 		.owner	= THIS_MODULE,
 #ifdef CONFIG_PM
 		.pm	= &fec_pm_ops,
 #endif
 	},
+	.id_table = fec_devtype,
 	.probe	= fec_probe,
 	.remove	= __devexit_p(fec_drv_remove),
 };
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 2c48b25..ace318d 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -14,7 +14,8 @@
 /****************************************************************************/
 
 #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
-    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
+    defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
+    defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
 /*
  *	Just figures, Motorola would have to change the offsets for
  *	registers in the same peripheral device on different models
@@ -78,7 +79,7 @@
 /*
  *	Define the buffer descriptor structure.
  */
-#ifdef CONFIG_ARCH_MXC
+#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
 struct bufdesc {
 	unsigned short cbd_datlen;	/* Data length */
 	unsigned short cbd_sc;	/* Control and status info */
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
@ 2011-01-06  7:13   ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: linux-arm-kernel

This patch is to add mx28 dual fec support. Here are some key notes
for mx28 fec controller.

 - The mx28 fec controller naming ENET-MAC is a different IP from FEC
   used on other i.mx variants.  But they are basically compatible
   on software interface, so it's possible to share the same driver.
 - ENET-MAC design on mx28 made an improper assumption that it runs
   on a big-endian system. As the result, driver has to swap every
   frame going to and coming from the controller.
 - The external phys can only be configured by fec0, which means fec1
   can not work independently and both phys need to be configured by
   mii_bus attached on fec0.
 - ENET-MAC reset will get mac address registers reset too.
 - ENET-MAC MII/RMII mode and 10M/100M speed are configured
   differently FEC.
 - ETHER_EN bit must be set to get ENET-MAC interrupt work.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v4:
 - Use #ifndef CONFIG_ARM to include ColdFire header files
 - Define quirk bits in id_entry.driver_data to handle controller
   difference, which is more scalable than using device name
 - Define fec0_mii_bus as a static function in fec_enet_mii_init
   to fold the mii_bus instance attached on fec0
 - Use cpu_to_be32 over __swab32 in function swap_buffer

Changes for v3:
 - Move v2 changes into patch #3
 - Use device name to check if it's running on ENET-MAC

 drivers/net/Kconfig |    7 ++-
 drivers/net/fec.c   |  148 +++++++++++++++++++++++++++++++++++++++++++++------
 drivers/net/fec.h   |    5 +-
 3 files changed, 139 insertions(+), 21 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 4f1755b..f34629b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1944,18 +1944,19 @@ config 68360_ENET
 config FEC
 	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
 	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
-		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
+		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
 	select PHYLIB
 	help
 	  Say Y here if you want to use the built-in 10/100 Fast ethernet
 	  controller on some Motorola ColdFire and Freescale i.MX processors.
 
 config FEC2
-	bool "Second FEC ethernet controller (on some ColdFire CPUs)"
+	bool "Second FEC ethernet controller"
 	depends on FEC
 	help
 	  Say Y here if you want to use the second built-in 10/100 Fast
-	  ethernet controller on some Motorola ColdFire processors.
+	  ethernet controller on some Motorola ColdFire and Freescale
+	  i.MX processors.
 
 config FEC_MPC52xx
 	tristate "MPC52xx FEC driver"
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 8a1c51f..2a71373 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -17,6 +17,8 @@
  *
  * Bug fixes and cleanup by Philippe De Muyter (phdm at macqel.be)
  * Copyright (c) 2004-2006 Macq Electronique SA.
+ *
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
  */
 
 #include <linux/module.h>
@@ -45,20 +47,36 @@
 
 #include <asm/cacheflush.h>
 
-#ifndef CONFIG_ARCH_MXC
+#ifndef CONFIG_ARM
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
 #endif
 
 #include "fec.h"
 
-#ifdef CONFIG_ARCH_MXC
-#include <mach/hardware.h>
+#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
 #define FEC_ALIGNMENT	0xf
 #else
 #define FEC_ALIGNMENT	0x3
 #endif
 
+#define DRIVER_NAME	"fec"
+
+/* Controller is ENET-MAC */
+#define FEC_QUIRK_ENET_MAC		(1 << 0)
+/* Controller needs driver to swap frame */
+#define FEC_QUIRK_SWAP_FRAME		(1 << 1)
+
+static struct platform_device_id fec_devtype[] = {
+	{
+		.name = DRIVER_NAME,
+		.driver_data = 0,
+	}, {
+		.name = "imx28-fec",
+		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME,
+	}
+};
+
 static unsigned char macaddr[ETH_ALEN];
 module_param_array(macaddr, byte, NULL, 0);
 MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
@@ -129,7 +147,8 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
  * account when setting it.
  */
 #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
-    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
+    defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
+    defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
 #define	OPT_FRAME_SIZE	(PKT_MAXBUF_SIZE << 16)
 #else
 #define	OPT_FRAME_SIZE	0
@@ -208,10 +227,23 @@ static void fec_stop(struct net_device *dev);
 /* Transmitter timeout */
 #define TX_TIMEOUT (2 * HZ)
 
+static void *swap_buffer(void *bufaddr, int len)
+{
+	int i;
+	unsigned int *buf = bufaddr;
+
+	for (i = 0; i < (len + 3) / 4; i++, buf++)
+		*buf = cpu_to_be32(*buf);
+
+	return bufaddr;
+}
+
 static netdev_tx_t
 fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
+	const struct platform_device_id *id_entry =
+				platform_get_device_id(fep->pdev);
 	struct bufdesc *bdp;
 	void *bufaddr;
 	unsigned short	status;
@@ -256,6 +288,14 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		bufaddr = fep->tx_bounce[index];
 	}
 
+	/*
+	 * Some design made an incorrect assumption on endian mode of
+	 * the system that it's running on. As the result, driver has to
+	 * swap every frame going to and coming from the controller.
+	 */
+	if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
+		swap_buffer(bufaddr, skb->len);
+
 	/* Save skb pointer */
 	fep->tx_skbuff[fep->skb_cur] = skb;
 
@@ -424,6 +464,8 @@ static void
 fec_enet_rx(struct net_device *dev)
 {
 	struct	fec_enet_private *fep = netdev_priv(dev);
+	const struct platform_device_id *id_entry =
+				platform_get_device_id(fep->pdev);
 	struct bufdesc *bdp;
 	unsigned short status;
 	struct	sk_buff	*skb;
@@ -487,6 +529,9 @@ fec_enet_rx(struct net_device *dev)
 	        dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
         			DMA_FROM_DEVICE);
 
+		if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
+			swap_buffer(data, pkt_len);
+
 		/* This does 16 byte alignment, exactly what we need.
 		 * The packet length includes FCS, but we don't want to
 		 * include that when passing upstream as it messes up
@@ -689,6 +734,7 @@ static int fec_enet_mii_probe(struct net_device *dev)
 	char mdio_bus_id[MII_BUS_ID_SIZE];
 	char phy_name[MII_BUS_ID_SIZE + 3];
 	int phy_id;
+	int dev_id = fep->pdev->id;
 
 	fep->phy_dev = NULL;
 
@@ -700,6 +746,8 @@ static int fec_enet_mii_probe(struct net_device *dev)
 			continue;
 		if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
 			continue;
+		if (dev_id--)
+			continue;
 		strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);
 		break;
 	}
@@ -737,10 +785,35 @@ static int fec_enet_mii_probe(struct net_device *dev)
 
 static int fec_enet_mii_init(struct platform_device *pdev)
 {
+	static struct mii_bus *fec0_mii_bus;
 	struct net_device *dev = platform_get_drvdata(pdev);
 	struct fec_enet_private *fep = netdev_priv(dev);
+	const struct platform_device_id *id_entry =
+				platform_get_device_id(fep->pdev);
 	int err = -ENXIO, i;
 
+	/*
+	 * The dual fec interfaces are not equivalent with enet-mac.
+	 * Here are the differences:
+	 *
+	 *  - fec0 supports MII & RMII modes while fec1 only supports RMII
+	 *  - fec0 acts as the 1588 time master while fec1 is slave
+	 *  - external phys can only be configured by fec0
+	 *
+	 * That is to say fec1 can not work independently. It only works
+	 * when fec0 is working. The reason behind this design is that the
+	 * second interface is added primarily for Switch mode.
+	 *
+	 * Because of the last point above, both phys are attached on fec0
+	 * mdio interface in board design, and need to be configured by
+	 * fec0 mii_bus.
+	 */
+	if ((id_entry->driver_data & FEC_QUIRK_ENET_MAC) && pdev->id) {
+		/* fec1 uses fec0 mii_bus */
+		fep->mii_bus = fec0_mii_bus;
+		return 0;
+	}
+
 	fep->mii_timeout = 0;
 
 	/*
@@ -777,6 +850,10 @@ static int fec_enet_mii_init(struct platform_device *pdev)
 	if (mdiobus_register(fep->mii_bus))
 		goto err_out_free_mdio_irq;
 
+	/* save fec0 mii_bus */
+	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
+		fec0_mii_bus = fep->mii_bus;
+
 	return 0;
 
 err_out_free_mdio_irq:
@@ -1148,12 +1225,25 @@ static void
 fec_restart(struct net_device *dev, int duplex)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
+	const struct platform_device_id *id_entry =
+				platform_get_device_id(fep->pdev);
 	int i;
+	u32 val, temp_mac[2];
 
 	/* Whack a reset.  We should wait for this. */
 	writel(1, fep->hwp + FEC_ECNTRL);
 	udelay(10);
 
+	/*
+	 * enet-mac reset will reset mac address registers too,
+	 * so need to reconfigure it.
+	 */
+	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
+		memcpy(&temp_mac, dev->dev_addr, ETH_ALEN);
+		writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW);
+		writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH);
+	}
+
 	/* Clear any outstanding interrupt. */
 	writel(0xffc00000, fep->hwp + FEC_IEVENT);
 
@@ -1200,20 +1290,45 @@ fec_restart(struct net_device *dev, int duplex)
 	/* Set MII speed */
 	writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
 
-#ifdef FEC_MIIGSK_ENR
-	if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
-		/* disable the gasket and wait */
-		writel(0, fep->hwp + FEC_MIIGSK_ENR);
-		while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
-			udelay(1);
+	/*
+	 * The phy interface and speed need to get configured
+	 * differently on enet-mac.
+	 */
+	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
+		val = readl(fep->hwp + FEC_R_CNTRL);
 
-		/* configure the gasket: RMII, 50 MHz, no loopback, no echo */
-		writel(1, fep->hwp + FEC_MIIGSK_CFGR);
+		/* MII or RMII */
+		if (fep->phy_interface == PHY_INTERFACE_MODE_RMII)
+			val |= (1 << 8);
+		else
+			val &= ~(1 << 8);
 
-		/* re-enable the gasket */
-		writel(2, fep->hwp + FEC_MIIGSK_ENR);
-	}
+		/* 10M or 100M */
+		if (fep->phy_dev && fep->phy_dev->speed == SPEED_100)
+			val &= ~(1 << 9);
+		else
+			val |= (1 << 9);
+
+		writel(val, fep->hwp + FEC_R_CNTRL);
+	} else {
+#ifdef FEC_MIIGSK_ENR
+		if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
+			/* disable the gasket and wait */
+			writel(0, fep->hwp + FEC_MIIGSK_ENR);
+			while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
+				udelay(1);
+
+			/*
+			 * configure the gasket:
+			 *   RMII, 50 MHz, no loopback, no echo
+			 */
+			writel(1, fep->hwp + FEC_MIIGSK_CFGR);
+
+			/* re-enable the gasket */
+			writel(2, fep->hwp + FEC_MIIGSK_ENR);
+		}
 #endif
+	}
 
 	/* And last, enable the transmit and receive processing */
 	writel(2, fep->hwp + FEC_ECNTRL);
@@ -1410,12 +1525,13 @@ static const struct dev_pm_ops fec_pm_ops = {
 
 static struct platform_driver fec_driver = {
 	.driver	= {
-		.name	= "fec",
+		.name	= DRIVER_NAME,
 		.owner	= THIS_MODULE,
 #ifdef CONFIG_PM
 		.pm	= &fec_pm_ops,
 #endif
 	},
+	.id_table = fec_devtype,
 	.probe	= fec_probe,
 	.remove	= __devexit_p(fec_drv_remove),
 };
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 2c48b25..ace318d 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -14,7 +14,8 @@
 /****************************************************************************/
 
 #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
-    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
+    defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
+    defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
 /*
  *	Just figures, Motorola would have to change the offsets for
  *	registers in the same peripheral device on different models
@@ -78,7 +79,7 @@
 /*
  *	Define the buffer descriptor structure.
  */
-#ifdef CONFIG_ARCH_MXC
+#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
 struct bufdesc {
 	unsigned short cbd_datlen;	/* Data length */
 	unsigned short cbd_sc;	/* Control and status info */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 06/10] ARM: mx28: update clock and device name for dual fec support
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-06  7:13   ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig

Change device name from "fec" to "imx28-fec", so that fec driver
can distinguish mx28.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v4:
 - Use "imx28-fec" as fec device name

Changes for v3:
 - Change device name to "enet-mac"

 arch/arm/mach-mxs/clock-mx28.c           |    3 ++-
 arch/arm/mach-mxs/devices/platform-fec.c |    2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index f20b254..e2a8b0f 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -606,7 +606,8 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
 	/* for amba-pl011 driver */
 	_REGISTER_CLOCK("duart", NULL, uart_clk)
-	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+	_REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk)
+	_REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk)
 	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
 	_REGISTER_CLOCK("pll2", NULL, pll2_clk)
 	_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
index c08168c..c42dff7 100644
--- a/arch/arm/mach-mxs/devices/platform-fec.c
+++ b/arch/arm/mach-mxs/devices/platform-fec.c
@@ -45,6 +45,6 @@ struct platform_device *__init mxs_add_fec(
 		},
 	};
 
-	return mxs_add_platform_device("fec", data->id,
+	return mxs_add_platform_device("imx28-fec", data->id,
 			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
 }
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 06/10] ARM: mx28: update clock and device name for dual fec support
@ 2011-01-06  7:13   ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: linux-arm-kernel

Change device name from "fec" to "imx28-fec", so that fec driver
can distinguish mx28.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v4:
 - Use "imx28-fec" as fec device name

Changes for v3:
 - Change device name to "enet-mac"

 arch/arm/mach-mxs/clock-mx28.c           |    3 ++-
 arch/arm/mach-mxs/devices/platform-fec.c |    2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index f20b254..e2a8b0f 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -606,7 +606,8 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
 	/* for amba-pl011 driver */
 	_REGISTER_CLOCK("duart", NULL, uart_clk)
-	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+	_REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk)
+	_REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk)
 	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
 	_REGISTER_CLOCK("pll2", NULL, pll2_clk)
 	_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
index c08168c..c42dff7 100644
--- a/arch/arm/mach-mxs/devices/platform-fec.c
+++ b/arch/arm/mach-mxs/devices/platform-fec.c
@@ -45,6 +45,6 @@ struct platform_device *__init mxs_add_fec(
 		},
 	};
 
-	return mxs_add_platform_device("fec", data->id,
+	return mxs_add_platform_device("imx28-fec", data->id,
 			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 07/10] ARM: mx28: add the second fec device registration
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-06  7:13   ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/mach-mx28evk.c |   28 +++++++++++++++++++++++++---
 1 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index d162e95..def6519 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -57,6 +57,19 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
 		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
 	MX28_PAD_ENET_CLK__CLKCTRL_ENET |
 		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	/* fec1 */
+	MX28_PAD_ENET0_CRS__ENET1_RX_EN |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_RXD2__ENET1_RXD0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_RXD3__ENET1_RXD1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_COL__ENET1_TX_EN |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_TXD2__ENET1_TXD0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_TXD3__ENET1_TXD1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
 	/* phy power line */
 	MX28_PAD_SSP1_DATA3__GPIO_2_15 |
 		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
@@ -106,8 +119,14 @@ static void __init mx28evk_fec_reset(void)
 	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
 }
 
-static const struct fec_platform_data mx28_fec_pdata __initconst = {
-	.phy = PHY_INTERFACE_MODE_RMII,
+static struct fec_platform_data mx28_fec_pdata[] = {
+	{
+		/* fec0 */
+		.phy = PHY_INTERFACE_MODE_RMII,
+	}, {
+		/* fec1 */
+		.phy = PHY_INTERFACE_MODE_RMII,
+	},
 };
 
 static void __init mx28evk_init(void)
@@ -117,7 +136,10 @@ static void __init mx28evk_init(void)
 	mx28_add_duart();
 
 	mx28evk_fec_reset();
-	mx28_add_fec(0, &mx28_fec_pdata);
+	mx28_add_fec(0, &mx28_fec_pdata[0]);
+#ifdef CONFIG_FEC2
+	mx28_add_fec(1, &mx28_fec_pdata[1]);
+#endif
 }
 
 static void __init mx28evk_timer_init(void)
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 07/10] ARM: mx28: add the second fec device registration
@ 2011-01-06  7:13   ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/mach-mx28evk.c |   28 +++++++++++++++++++++++++---
 1 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index d162e95..def6519 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -57,6 +57,19 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
 		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
 	MX28_PAD_ENET_CLK__CLKCTRL_ENET |
 		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	/* fec1 */
+	MX28_PAD_ENET0_CRS__ENET1_RX_EN |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_RXD2__ENET1_RXD0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_RXD3__ENET1_RXD1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_COL__ENET1_TX_EN |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_TXD2__ENET1_TXD0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_TXD3__ENET1_TXD1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
 	/* phy power line */
 	MX28_PAD_SSP1_DATA3__GPIO_2_15 |
 		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
@@ -106,8 +119,14 @@ static void __init mx28evk_fec_reset(void)
 	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
 }
 
-static const struct fec_platform_data mx28_fec_pdata __initconst = {
-	.phy = PHY_INTERFACE_MODE_RMII,
+static struct fec_platform_data mx28_fec_pdata[] = {
+	{
+		/* fec0 */
+		.phy = PHY_INTERFACE_MODE_RMII,
+	}, {
+		/* fec1 */
+		.phy = PHY_INTERFACE_MODE_RMII,
+	},
 };
 
 static void __init mx28evk_init(void)
@@ -117,7 +136,10 @@ static void __init mx28evk_init(void)
 	mx28_add_duart();
 
 	mx28evk_fec_reset();
-	mx28_add_fec(0, &mx28_fec_pdata);
+	mx28_add_fec(0, &mx28_fec_pdata[0]);
+#ifdef CONFIG_FEC2
+	mx28_add_fec(1, &mx28_fec_pdata[1]);
+#endif
 }
 
 static void __init mx28evk_timer_init(void)
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 08/10] ARM: mxs: add ocotp read function
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-06  7:13   ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v4:
 - Call cpu_relax() during polling

Changes for v2:
 - Add mutex locking for mxs_read_ocotp()
 - Use type size_t for count and i
 - Add comment for clk_enable/disable skipping
 - Add ERROR bit clearing and polling step

 arch/arm/mach-mxs/Makefile              |    2 +-
 arch/arm/mach-mxs/include/mach/common.h |    1 +
 arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
 3 files changed, 81 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-mxs/ocotp.c

diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 39d3f9c..f23ebbd 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,5 +1,5 @@
 # Common support
-obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
+obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
 
 obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
 obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
index 59133eb..cf02552 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -13,6 +13,7 @@
 
 struct clk;
 
+extern int mxs_read_ocotp(int offset, int count, u32 *values);
 extern int mxs_reset_block(void __iomem *);
 extern void mxs_timer_init(struct clk *, int);
 
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
new file mode 100644
index 0000000..e2d39aa
--- /dev/null
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2010 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+#include <mach/mxs.h>
+
+#define BM_OCOTP_CTRL_BUSY		(1 << 8)
+#define BM_OCOTP_CTRL_ERROR		(1 << 9)
+#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
+
+static DEFINE_MUTEX(ocotp_mutex);
+
+int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
+{
+	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
+	int timeout = 0x400;
+	size_t i;
+
+	mutex_lock(&ocotp_mutex);
+
+	/*
+	 * clk_enable(hbus_clk) for ocotp can be skipped
+	 * as it must be on when system is running.
+	 */
+
+	/* try to clear ERROR bit */
+	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
+
+	/* check both BUSY and ERROR cleared */
+	while ((__raw_readl(ocotp_base) &
+		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
+		cpu_relax();
+
+	if (unlikely(!timeout))
+		goto error_unlock;
+
+	/* open OCOTP banks for read */
+	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+	/* approximately wait 32 hclk cycles */
+	udelay(1);
+
+	/* poll BUSY bit becoming cleared */
+	timeout = 0x400;
+	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
+		cpu_relax();
+
+	if (unlikely(!timeout))
+		goto error_unlock;
+
+	for (i = 0; i < count; i++, offset += 4)
+		*values++ = __raw_readl(ocotp_base + offset);
+
+	/* close banks for power saving */
+	__mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+	mutex_unlock(&ocotp_mutex);
+
+	return 0;
+
+error_unlock:
+	mutex_unlock(&ocotp_mutex);
+	pr_err("%s: timeout in reading OCOTP\n", __func__);
+	return -ETIMEDOUT;
+}
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 08/10] ARM: mxs: add ocotp read function
@ 2011-01-06  7:13   ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v4:
 - Call cpu_relax() during polling

Changes for v2:
 - Add mutex locking for mxs_read_ocotp()
 - Use type size_t for count and i
 - Add comment for clk_enable/disable skipping
 - Add ERROR bit clearing and polling step

 arch/arm/mach-mxs/Makefile              |    2 +-
 arch/arm/mach-mxs/include/mach/common.h |    1 +
 arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
 3 files changed, 81 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-mxs/ocotp.c

diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 39d3f9c..f23ebbd 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,5 +1,5 @@
 # Common support
-obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
+obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
 
 obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
 obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
index 59133eb..cf02552 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -13,6 +13,7 @@
 
 struct clk;
 
+extern int mxs_read_ocotp(int offset, int count, u32 *values);
 extern int mxs_reset_block(void __iomem *);
 extern void mxs_timer_init(struct clk *, int);
 
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
new file mode 100644
index 0000000..e2d39aa
--- /dev/null
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2010 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+#include <mach/mxs.h>
+
+#define BM_OCOTP_CTRL_BUSY		(1 << 8)
+#define BM_OCOTP_CTRL_ERROR		(1 << 9)
+#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
+
+static DEFINE_MUTEX(ocotp_mutex);
+
+int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
+{
+	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
+	int timeout = 0x400;
+	size_t i;
+
+	mutex_lock(&ocotp_mutex);
+
+	/*
+	 * clk_enable(hbus_clk) for ocotp can be skipped
+	 * as it must be on when system is running.
+	 */
+
+	/* try to clear ERROR bit */
+	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
+
+	/* check both BUSY and ERROR cleared */
+	while ((__raw_readl(ocotp_base) &
+		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
+		cpu_relax();
+
+	if (unlikely(!timeout))
+		goto error_unlock;
+
+	/* open OCOTP banks for read */
+	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+	/* approximately wait 32 hclk cycles */
+	udelay(1);
+
+	/* poll BUSY bit becoming cleared */
+	timeout = 0x400;
+	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
+		cpu_relax();
+
+	if (unlikely(!timeout))
+		goto error_unlock;
+
+	for (i = 0; i < count; i++, offset += 4)
+		*values++ = __raw_readl(ocotp_base + offset);
+
+	/* close banks for power saving */
+	__mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+	mutex_unlock(&ocotp_mutex);
+
+	return 0;
+
+error_unlock:
+	mutex_unlock(&ocotp_mutex);
+	pr_err("%s: timeout in reading OCOTP\n", __func__);
+	return -ETIMEDOUT;
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 09/10] ARM: mx28: read fec mac address from ocotp
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-06  7:13   ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig

Read fec mac address from ocotp and save it into fec_platform_data
mac field for fec driver to use.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - It's not necessary to remove "const" for fec_platform_data from
   platform-fec.c and devices-common.h, so add it back.
 - Hard-coding Freescale OUI (00:04:9f) instead of just the first
   two two octets.
 - Correct the return of mx28evk_fec_get_mac() and check it
   with caller

 arch/arm/mach-mxs/mach-mx28evk.c |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index def6519..54fa512 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -129,12 +129,44 @@ static struct fec_platform_data mx28_fec_pdata[] = {
 	},
 };
 
+static int __init mx28evk_fec_get_mac(void)
+{
+	int i, ret;
+	u32 val;
+
+	/*
+	 * OCOTP only stores the last 4 octets for each mac address,
+	 * so hard-code Freescale OUI (00:04:9f) here.
+	 */
+	for (i = 0; i < 2; i++) {
+		ret = mxs_read_ocotp(0x20 + i * 0x10, 1, &val);
+		if (ret)
+			goto error;
+
+		mx28_fec_pdata[i].mac[0] = 0x00;
+		mx28_fec_pdata[i].mac[1] = 0x04;
+		mx28_fec_pdata[i].mac[2] = 0x9f;
+		mx28_fec_pdata[i].mac[3] = (val >> 16) & 0xff;
+		mx28_fec_pdata[i].mac[4] = (val >> 8) & 0xff;
+		mx28_fec_pdata[i].mac[5] = (val >> 0) & 0xff;
+	}
+
+	return 0;
+
+error:
+	pr_err("%s: timeout when reading fec mac from OCOTP\n", __func__);
+	return ret;
+}
+
 static void __init mx28evk_init(void)
 {
 	mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
 
 	mx28_add_duart();
 
+	if (mx28evk_fec_get_mac())
+		pr_warn("%s: failed on fec mac setup\n", __func__);
+
 	mx28evk_fec_reset();
 	mx28_add_fec(0, &mx28_fec_pdata[0]);
 #ifdef CONFIG_FEC2
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 09/10] ARM: mx28: read fec mac address from ocotp
@ 2011-01-06  7:13   ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: linux-arm-kernel

Read fec mac address from ocotp and save it into fec_platform_data
mac field for fec driver to use.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - It's not necessary to remove "const" for fec_platform_data from
   platform-fec.c and devices-common.h, so add it back.
 - Hard-coding Freescale OUI (00:04:9f) instead of just the first
   two two octets.
 - Correct the return of mx28evk_fec_get_mac() and check it
   with caller

 arch/arm/mach-mxs/mach-mx28evk.c |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index def6519..54fa512 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -129,12 +129,44 @@ static struct fec_platform_data mx28_fec_pdata[] = {
 	},
 };
 
+static int __init mx28evk_fec_get_mac(void)
+{
+	int i, ret;
+	u32 val;
+
+	/*
+	 * OCOTP only stores the last 4 octets for each mac address,
+	 * so hard-code Freescale OUI (00:04:9f) here.
+	 */
+	for (i = 0; i < 2; i++) {
+		ret = mxs_read_ocotp(0x20 + i * 0x10, 1, &val);
+		if (ret)
+			goto error;
+
+		mx28_fec_pdata[i].mac[0] = 0x00;
+		mx28_fec_pdata[i].mac[1] = 0x04;
+		mx28_fec_pdata[i].mac[2] = 0x9f;
+		mx28_fec_pdata[i].mac[3] = (val >> 16) & 0xff;
+		mx28_fec_pdata[i].mac[4] = (val >> 8) & 0xff;
+		mx28_fec_pdata[i].mac[5] = (val >> 0) & 0xff;
+	}
+
+	return 0;
+
+error:
+	pr_err("%s: timeout when reading fec mac from OCOTP\n", __func__);
+	return ret;
+}
+
 static void __init mx28evk_init(void)
 {
 	mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
 
 	mx28_add_duart();
 
+	if (mx28evk_fec_get_mac())
+		pr_warn("%s: failed on fec mac setup\n", __func__);
+
 	mx28evk_fec_reset();
 	mx28_add_fec(0, &mx28_fec_pdata[0]);
 #ifdef CONFIG_FEC2
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 10/10] ARM: mxs: add initial pm support
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-06  7:13   ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig

This is a very initial pm support and basically does nothing.
With this pm support entry, drivers can start testing their own
pm functions.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Let build of pm.c depend on CONFIG_PM
 - Remove the blank line above device_initcall in pm.c

 arch/arm/mach-mxs/Makefile |    2 ++
 arch/arm/mach-mxs/pm.c     |   43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/pm.c

diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index f23ebbd..45a2925 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,6 +1,8 @@
 # Common support
 obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
 
+obj-$(CONFIG_PM) += pm.o
+
 obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
 obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
 
diff --git a/arch/arm/mach-mxs/pm.c b/arch/arm/mach-mxs/pm.c
new file mode 100644
index 0000000..fb042da
--- /dev/null
+++ b/arch/arm/mach-mxs/pm.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+#include <linux/io.h>
+#include <mach/system.h>
+
+static int mxs_suspend_enter(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_MEM:
+		arch_idle();
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static struct platform_suspend_ops mxs_suspend_ops = {
+	.enter = mxs_suspend_enter,
+	.valid = suspend_valid_only_mem,
+};
+
+static int __init mxs_pm_init(void)
+{
+	suspend_set_ops(&mxs_suspend_ops);
+	return 0;
+}
+device_initcall(mxs_pm_init);
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v4 10/10] ARM: mxs: add initial pm support
@ 2011-01-06  7:13   ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-06  7:13 UTC (permalink / raw)
  To: linux-arm-kernel

This is a very initial pm support and basically does nothing.
With this pm support entry, drivers can start testing their own
pm functions.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Let build of pm.c depend on CONFIG_PM
 - Remove the blank line above device_initcall in pm.c

 arch/arm/mach-mxs/Makefile |    2 ++
 arch/arm/mach-mxs/pm.c     |   43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/pm.c

diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index f23ebbd..45a2925 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,6 +1,8 @@
 # Common support
 obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
 
+obj-$(CONFIG_PM) += pm.o
+
 obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
 obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
 
diff --git a/arch/arm/mach-mxs/pm.c b/arch/arm/mach-mxs/pm.c
new file mode 100644
index 0000000..fb042da
--- /dev/null
+++ b/arch/arm/mach-mxs/pm.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+#include <linux/io.h>
+#include <mach/system.h>
+
+static int mxs_suspend_enter(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_MEM:
+		arch_idle();
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static struct platform_suspend_ops mxs_suspend_ops = {
+	.enter = mxs_suspend_enter,
+	.valid = suspend_valid_only_mem,
+};
+
+static int __init mxs_pm_init(void)
+{
+	suspend_set_ops(&mxs_suspend_ops);
+	return 0;
+}
+device_initcall(mxs_pm_init);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 00/10] net/fec: add dual fec support for i.MX28
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-09 23:44   ` David Miller
  -1 siblings, 0 replies; 118+ messages in thread
From: David Miller @ 2011-01-09 23:44 UTC (permalink / raw)
  To: shawn.guo
  Cc: gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig,
	lw, w.sang, s.hauer, jamie, jamie, netdev, linux-arm-kernel

From: Shawn Guo <shawn.guo@freescale.com>
Date: Thu, 6 Jan 2011 15:13:08 +0800

> This patch series is to add dual fec support for mx28, which is
> a mxs-based soc. Some code changes related to the following commits
> are also made in this patch set for some reasons.
> 
>  e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
>  netdev/fec.c: add phylib supporting to enable carrier detection (v2)
> 
>  e3fe8558c7fc182972c3d947d88744482111f304
>  net/fec: fix pm to survive to suspend/resume
> 
> It's been tested on mx28 evk and mx51 babbage. For mx28, it has
> to work against the tree
> 
>  git://git.pengutronix.de/git/imx/linux-2.6.git imx-for-2.6.38
> 
> plus patch
> 
>  [PATCH v4] ARM: mxs: Change duart device to use amba-pl011
> 
> The 3 patches below preceding with * have changes since v3, and
> the detailed change log can be found in individual patch.

I've applied all of the "net/fec:" patches (#1 to #5) to net-2.6,
please push the ARM changes via the appropriate ARM tree.

Thanks.

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 00/10] net/fec: add dual fec support for i.MX28
@ 2011-01-09 23:44   ` David Miller
  0 siblings, 0 replies; 118+ messages in thread
From: David Miller @ 2011-01-09 23:44 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@freescale.com>
Date: Thu, 6 Jan 2011 15:13:08 +0800

> This patch series is to add dual fec support for mx28, which is
> a mxs-based soc. Some code changes related to the following commits
> are also made in this patch set for some reasons.
> 
>  e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
>  netdev/fec.c: add phylib supporting to enable carrier detection (v2)
> 
>  e3fe8558c7fc182972c3d947d88744482111f304
>  net/fec: fix pm to survive to suspend/resume
> 
> It's been tested on mx28 evk and mx51 babbage. For mx28, it has
> to work against the tree
> 
>  git://git.pengutronix.de/git/imx/linux-2.6.git imx-for-2.6.38
> 
> plus patch
> 
>  [PATCH v4] ARM: mxs: Change duart device to use amba-pl011
> 
> The 3 patches below preceding with * have changes since v3, and
> the detailed change log can be found in individual patch.

I've applied all of the "net/fec:" patches (#1 to #5) to net-2.6,
please push the ARM changes via the appropriate ARM tree.

Thanks.

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 00/10] net/fec: add dual fec support for i.MX28
  2011-01-09 23:44   ` David Miller
@ 2011-01-10  3:08     ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-10  3:08 UTC (permalink / raw)
  To: David Miller
  Cc: gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig,
	lw, w.sang, s.hauer, jamie, jamie, netdev, linux-arm-kernel

On Sun, Jan 09, 2011 at 03:44:09PM -0800, David Miller wrote:
> From: Shawn Guo <shawn.guo@freescale.com>
> Date: Thu, 6 Jan 2011 15:13:08 +0800
> 
> > This patch series is to add dual fec support for mx28, which is
> > a mxs-based soc. Some code changes related to the following commits
> > are also made in this patch set for some reasons.
> > 
> >  e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
> >  netdev/fec.c: add phylib supporting to enable carrier detection (v2)
> > 
> >  e3fe8558c7fc182972c3d947d88744482111f304
> >  net/fec: fix pm to survive to suspend/resume
> > 
> > It's been tested on mx28 evk and mx51 babbage. For mx28, it has
> > to work against the tree
> > 
> >  git://git.pengutronix.de/git/imx/linux-2.6.git imx-for-2.6.38
> > 
> > plus patch
> > 
> >  [PATCH v4] ARM: mxs: Change duart device to use amba-pl011
> > 
> > The 3 patches below preceding with * have changes since v3, and
> > the detailed change log can be found in individual patch.
> 
> I've applied all of the "net/fec:" patches (#1 to #5) to net-2.6,
> please push the ARM changes via the appropriate ARM tree.
> 
> Thanks.
> 
Thanks, David.  I will ping Sascha for ARM changes.

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 00/10] net/fec: add dual fec support for i.MX28
@ 2011-01-10  3:08     ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-10  3:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jan 09, 2011 at 03:44:09PM -0800, David Miller wrote:
> From: Shawn Guo <shawn.guo@freescale.com>
> Date: Thu, 6 Jan 2011 15:13:08 +0800
> 
> > This patch series is to add dual fec support for mx28, which is
> > a mxs-based soc. Some code changes related to the following commits
> > are also made in this patch set for some reasons.
> > 
> >  e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
> >  netdev/fec.c: add phylib supporting to enable carrier detection (v2)
> > 
> >  e3fe8558c7fc182972c3d947d88744482111f304
> >  net/fec: fix pm to survive to suspend/resume
> > 
> > It's been tested on mx28 evk and mx51 babbage. For mx28, it has
> > to work against the tree
> > 
> >  git://git.pengutronix.de/git/imx/linux-2.6.git imx-for-2.6.38
> > 
> > plus patch
> > 
> >  [PATCH v4] ARM: mxs: Change duart device to use amba-pl011
> > 
> > The 3 patches below preceding with * have changes since v3, and
> > the detailed change log can be found in individual patch.
> 
> I've applied all of the "net/fec:" patches (#1 to #5) to net-2.6,
> please push the ARM changes via the appropriate ARM tree.
> 
> Thanks.
> 
Thanks, David.  I will ping Sascha for ARM changes.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 00/10] net/fec: add dual fec support for i.MX28
  2011-01-09 23:44   ` David Miller
@ 2011-01-11  8:15     ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-11  8:15 UTC (permalink / raw)
  To: s.hauer
  Cc: gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig,
	lw, w.sang, jamie, netdev, linux-arm-kernel

Hi Sascha,

On Sun, Jan 09, 2011 at 03:44:09PM -0800, David Miller wrote:
> From: Shawn Guo <shawn.guo@freescale.com>
> Date: Thu, 6 Jan 2011 15:13:08 +0800
> 
> > This patch series is to add dual fec support for mx28, which is
> > a mxs-based soc. Some code changes related to the following commits
> > are also made in this patch set for some reasons.
> > 
> >  e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
> >  netdev/fec.c: add phylib supporting to enable carrier detection (v2)
> > 
> >  e3fe8558c7fc182972c3d947d88744482111f304
> >  net/fec: fix pm to survive to suspend/resume
> > 
> > It's been tested on mx28 evk and mx51 babbage. For mx28, it has
> > to work against the tree
> > 
> >  git://git.pengutronix.de/git/imx/linux-2.6.git imx-for-2.6.38
> > 
> > plus patch
> > 
> >  [PATCH v4] ARM: mxs: Change duart device to use amba-pl011
> > 
> > The 3 patches below preceding with * have changes since v3, and
> > the detailed change log can be found in individual patch.
> 
> I've applied all of the "net/fec:" patches (#1 to #5) to net-2.6,
> please push the ARM changes via the appropriate ARM tree.
> 
Is there anything needs to be done to get the following patches
merged?

 [PATCH v4] ARM: mxs: Change duart device to use amba-pl011
 [PATCH v4 00/10] net/fec: add dual fec support for i.MX28, #6 to #10.

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 00/10] net/fec: add dual fec support for i.MX28
@ 2011-01-11  8:15     ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-11  8:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sascha,

On Sun, Jan 09, 2011 at 03:44:09PM -0800, David Miller wrote:
> From: Shawn Guo <shawn.guo@freescale.com>
> Date: Thu, 6 Jan 2011 15:13:08 +0800
> 
> > This patch series is to add dual fec support for mx28, which is
> > a mxs-based soc. Some code changes related to the following commits
> > are also made in this patch set for some reasons.
> > 
> >  e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
> >  netdev/fec.c: add phylib supporting to enable carrier detection (v2)
> > 
> >  e3fe8558c7fc182972c3d947d88744482111f304
> >  net/fec: fix pm to survive to suspend/resume
> > 
> > It's been tested on mx28 evk and mx51 babbage. For mx28, it has
> > to work against the tree
> > 
> >  git://git.pengutronix.de/git/imx/linux-2.6.git imx-for-2.6.38
> > 
> > plus patch
> > 
> >  [PATCH v4] ARM: mxs: Change duart device to use amba-pl011
> > 
> > The 3 patches below preceding with * have changes since v3, and
> > the detailed change log can be found in individual patch.
> 
> I've applied all of the "net/fec:" patches (#1 to #5) to net-2.6,
> please push the ARM changes via the appropriate ARM tree.
> 
Is there anything needs to be done to get the following patches
merged?

 [PATCH v4] ARM: mxs: Change duart device to use amba-pl011
 [PATCH v4 00/10] net/fec: add dual fec support for i.MX28, #6 to #10.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 05/10] net/fec: add dual fec support for mx28
  2011-01-06  7:13   ` Shawn Guo
@ 2011-01-11 10:27     ` Sascha Hauer
  -1 siblings, 0 replies; 118+ messages in thread
From: Sascha Hauer @ 2011-01-11 10:27 UTC (permalink / raw)
  To: Shawn Guo
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig, lw, w.sang, jamie, jamie, netdev,
	linux-arm-kernel

On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
> This patch is to add mx28 dual fec support. Here are some key notes
> for mx28 fec controller.
> 
>  - The mx28 fec controller naming ENET-MAC is a different IP from FEC
>    used on other i.mx variants.  But they are basically compatible
>    on software interface, so it's possible to share the same driver.
>  - ENET-MAC design on mx28 made an improper assumption that it runs
>    on a big-endian system. As the result, driver has to swap every
>    frame going to and coming from the controller.
>  - The external phys can only be configured by fec0, which means fec1
>    can not work independently and both phys need to be configured by
>    mii_bus attached on fec0.
>  - ENET-MAC reset will get mac address registers reset too.
>  - ENET-MAC MII/RMII mode and 10M/100M speed are configured
>    differently FEC.
>  - ETHER_EN bit must be set to get ENET-MAC interrupt work.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v4:
>  - Use #ifndef CONFIG_ARM to include ColdFire header files
>  - Define quirk bits in id_entry.driver_data to handle controller
>    difference, which is more scalable than using device name
>  - Define fec0_mii_bus as a static function in fec_enet_mii_init
>    to fold the mii_bus instance attached on fec0
>  - Use cpu_to_be32 over __swab32 in function swap_buffer
> 
> Changes for v3:
>  - Move v2 changes into patch #3
>  - Use device name to check if it's running on ENET-MAC
> 
>  drivers/net/Kconfig |    7 ++-
>  drivers/net/fec.c   |  148 +++++++++++++++++++++++++++++++++++++++++++++------
>  drivers/net/fec.h   |    5 +-
>  3 files changed, 139 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 4f1755b..f34629b 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -1944,18 +1944,19 @@ config 68360_ENET
>  config FEC
>  	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
>  	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
> -		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
> +		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
>  	select PHYLIB
>  	help
>  	  Say Y here if you want to use the built-in 10/100 Fast ethernet
>  	  controller on some Motorola ColdFire and Freescale i.MX processors.
>  
>  config FEC2
> -	bool "Second FEC ethernet controller (on some ColdFire CPUs)"
> +	bool "Second FEC ethernet controller"
>  	depends on FEC
>  	help
>  	  Say Y here if you want to use the second built-in 10/100 Fast
> -	  ethernet controller on some Motorola ColdFire processors.
> +	  ethernet controller on some Motorola ColdFire and Freescale
> +	  i.MX processors.

This option is used nowhere and should be removed. Certainly it does not
have the effect of enabling the second ethernet controller.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
@ 2011-01-11 10:27     ` Sascha Hauer
  0 siblings, 0 replies; 118+ messages in thread
From: Sascha Hauer @ 2011-01-11 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
> This patch is to add mx28 dual fec support. Here are some key notes
> for mx28 fec controller.
> 
>  - The mx28 fec controller naming ENET-MAC is a different IP from FEC
>    used on other i.mx variants.  But they are basically compatible
>    on software interface, so it's possible to share the same driver.
>  - ENET-MAC design on mx28 made an improper assumption that it runs
>    on a big-endian system. As the result, driver has to swap every
>    frame going to and coming from the controller.
>  - The external phys can only be configured by fec0, which means fec1
>    can not work independently and both phys need to be configured by
>    mii_bus attached on fec0.
>  - ENET-MAC reset will get mac address registers reset too.
>  - ENET-MAC MII/RMII mode and 10M/100M speed are configured
>    differently FEC.
>  - ETHER_EN bit must be set to get ENET-MAC interrupt work.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v4:
>  - Use #ifndef CONFIG_ARM to include ColdFire header files
>  - Define quirk bits in id_entry.driver_data to handle controller
>    difference, which is more scalable than using device name
>  - Define fec0_mii_bus as a static function in fec_enet_mii_init
>    to fold the mii_bus instance attached on fec0
>  - Use cpu_to_be32 over __swab32 in function swap_buffer
> 
> Changes for v3:
>  - Move v2 changes into patch #3
>  - Use device name to check if it's running on ENET-MAC
> 
>  drivers/net/Kconfig |    7 ++-
>  drivers/net/fec.c   |  148 +++++++++++++++++++++++++++++++++++++++++++++------
>  drivers/net/fec.h   |    5 +-
>  3 files changed, 139 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 4f1755b..f34629b 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -1944,18 +1944,19 @@ config 68360_ENET
>  config FEC
>  	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
>  	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
> -		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
> +		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
>  	select PHYLIB
>  	help
>  	  Say Y here if you want to use the built-in 10/100 Fast ethernet
>  	  controller on some Motorola ColdFire and Freescale i.MX processors.
>  
>  config FEC2
> -	bool "Second FEC ethernet controller (on some ColdFire CPUs)"
> +	bool "Second FEC ethernet controller"
>  	depends on FEC
>  	help
>  	  Say Y here if you want to use the second built-in 10/100 Fast
> -	  ethernet controller on some Motorola ColdFire processors.
> +	  ethernet controller on some Motorola ColdFire and Freescale
> +	  i.MX processors.

This option is used nowhere and should be removed. Certainly it does not
have the effect of enabling the second ethernet controller.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 07/10] ARM: mx28: add the second fec device registration
  2011-01-06  7:13   ` Shawn Guo
@ 2011-01-11 10:29     ` Sascha Hauer
  -1 siblings, 0 replies; 118+ messages in thread
From: Sascha Hauer @ 2011-01-11 10:29 UTC (permalink / raw)
  To: Shawn Guo
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig, lw, w.sang, jamie, jamie, netdev,
	linux-arm-kernel

On Thu, Jan 06, 2011 at 03:13:15PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/mach-mx28evk.c |   28 +++++++++++++++++++++++++---
>  1 files changed, 25 insertions(+), 3 deletions(-)
> 
>  
>  static void __init mx28evk_init(void)
> @@ -117,7 +136,10 @@ static void __init mx28evk_init(void)
>  	mx28_add_duart();
>  
>  	mx28evk_fec_reset();
> -	mx28_add_fec(0, &mx28_fec_pdata);
> +	mx28_add_fec(0, &mx28_fec_pdata[0]);
> +#ifdef CONFIG_FEC2
> +	mx28_add_fec(1, &mx28_fec_pdata[1]);
> +#endif

Please don't do this. If you really want to make this configurable with
kconfig use a board specific option, not a driver specific option. I
think this should be made unconditional though.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 07/10] ARM: mx28: add the second fec device registration
@ 2011-01-11 10:29     ` Sascha Hauer
  0 siblings, 0 replies; 118+ messages in thread
From: Sascha Hauer @ 2011-01-11 10:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jan 06, 2011 at 03:13:15PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/mach-mx28evk.c |   28 +++++++++++++++++++++++++---
>  1 files changed, 25 insertions(+), 3 deletions(-)
> 
>  
>  static void __init mx28evk_init(void)
> @@ -117,7 +136,10 @@ static void __init mx28evk_init(void)
>  	mx28_add_duart();
>  
>  	mx28evk_fec_reset();
> -	mx28_add_fec(0, &mx28_fec_pdata);
> +	mx28_add_fec(0, &mx28_fec_pdata[0]);
> +#ifdef CONFIG_FEC2
> +	mx28_add_fec(1, &mx28_fec_pdata[1]);
> +#endif

Please don't do this. If you really want to make this configurable with
kconfig use a board specific option, not a driver specific option. I
think this should be made unconditional though.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 05/10] net/fec: add dual fec support for mx28
  2011-01-11 10:27     ` Sascha Hauer
@ 2011-01-11 11:38       ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-11 11:38 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig, lw, w.sang, jamie, jamie, netdev,
	linux-arm-kernel

On Tue, Jan 11, 2011 at 11:27:17AM +0100, Sascha Hauer wrote:
> On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
> > This patch is to add mx28 dual fec support. Here are some key notes
> > for mx28 fec controller.
> > 
> >  - The mx28 fec controller naming ENET-MAC is a different IP from FEC
> >    used on other i.mx variants.  But they are basically compatible
> >    on software interface, so it's possible to share the same driver.
> >  - ENET-MAC design on mx28 made an improper assumption that it runs
> >    on a big-endian system. As the result, driver has to swap every
> >    frame going to and coming from the controller.
> >  - The external phys can only be configured by fec0, which means fec1
> >    can not work independently and both phys need to be configured by
> >    mii_bus attached on fec0.
> >  - ENET-MAC reset will get mac address registers reset too.
> >  - ENET-MAC MII/RMII mode and 10M/100M speed are configured
> >    differently FEC.
> >  - ETHER_EN bit must be set to get ENET-MAC interrupt work.
> > 
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > ---
> > Changes for v4:
> >  - Use #ifndef CONFIG_ARM to include ColdFire header files
> >  - Define quirk bits in id_entry.driver_data to handle controller
> >    difference, which is more scalable than using device name
> >  - Define fec0_mii_bus as a static function in fec_enet_mii_init
> >    to fold the mii_bus instance attached on fec0
> >  - Use cpu_to_be32 over __swab32 in function swap_buffer
> > 
> > Changes for v3:
> >  - Move v2 changes into patch #3
> >  - Use device name to check if it's running on ENET-MAC
> > 
> >  drivers/net/Kconfig |    7 ++-
> >  drivers/net/fec.c   |  148 +++++++++++++++++++++++++++++++++++++++++++++------
> >  drivers/net/fec.h   |    5 +-
> >  3 files changed, 139 insertions(+), 21 deletions(-)
> > 
> > diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> > index 4f1755b..f34629b 100644
> > --- a/drivers/net/Kconfig
> > +++ b/drivers/net/Kconfig
> > @@ -1944,18 +1944,19 @@ config 68360_ENET
> >  config FEC
> >  	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
> >  	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
> > -		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
> > +		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
> >  	select PHYLIB
> >  	help
> >  	  Say Y here if you want to use the built-in 10/100 Fast ethernet
> >  	  controller on some Motorola ColdFire and Freescale i.MX processors.
> >  
> >  config FEC2
> > -	bool "Second FEC ethernet controller (on some ColdFire CPUs)"
> > +	bool "Second FEC ethernet controller"
> >  	depends on FEC
> >  	help
> >  	  Say Y here if you want to use the second built-in 10/100 Fast
> > -	  ethernet controller on some Motorola ColdFire processors.
> > +	  ethernet controller on some Motorola ColdFire and Freescale
> > +	  i.MX processors.
> 
> This option is used nowhere and should be removed. Certainly it does not
> have the effect of enabling the second ethernet controller.
> 
As David has merged it, I would send a follow-up patch to remove it.

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
@ 2011-01-11 11:38       ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-11 11:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 11, 2011 at 11:27:17AM +0100, Sascha Hauer wrote:
> On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
> > This patch is to add mx28 dual fec support. Here are some key notes
> > for mx28 fec controller.
> > 
> >  - The mx28 fec controller naming ENET-MAC is a different IP from FEC
> >    used on other i.mx variants.  But they are basically compatible
> >    on software interface, so it's possible to share the same driver.
> >  - ENET-MAC design on mx28 made an improper assumption that it runs
> >    on a big-endian system. As the result, driver has to swap every
> >    frame going to and coming from the controller.
> >  - The external phys can only be configured by fec0, which means fec1
> >    can not work independently and both phys need to be configured by
> >    mii_bus attached on fec0.
> >  - ENET-MAC reset will get mac address registers reset too.
> >  - ENET-MAC MII/RMII mode and 10M/100M speed are configured
> >    differently FEC.
> >  - ETHER_EN bit must be set to get ENET-MAC interrupt work.
> > 
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > ---
> > Changes for v4:
> >  - Use #ifndef CONFIG_ARM to include ColdFire header files
> >  - Define quirk bits in id_entry.driver_data to handle controller
> >    difference, which is more scalable than using device name
> >  - Define fec0_mii_bus as a static function in fec_enet_mii_init
> >    to fold the mii_bus instance attached on fec0
> >  - Use cpu_to_be32 over __swab32 in function swap_buffer
> > 
> > Changes for v3:
> >  - Move v2 changes into patch #3
> >  - Use device name to check if it's running on ENET-MAC
> > 
> >  drivers/net/Kconfig |    7 ++-
> >  drivers/net/fec.c   |  148 +++++++++++++++++++++++++++++++++++++++++++++------
> >  drivers/net/fec.h   |    5 +-
> >  3 files changed, 139 insertions(+), 21 deletions(-)
> > 
> > diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> > index 4f1755b..f34629b 100644
> > --- a/drivers/net/Kconfig
> > +++ b/drivers/net/Kconfig
> > @@ -1944,18 +1944,19 @@ config 68360_ENET
> >  config FEC
> >  	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
> >  	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
> > -		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
> > +		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
> >  	select PHYLIB
> >  	help
> >  	  Say Y here if you want to use the built-in 10/100 Fast ethernet
> >  	  controller on some Motorola ColdFire and Freescale i.MX processors.
> >  
> >  config FEC2
> > -	bool "Second FEC ethernet controller (on some ColdFire CPUs)"
> > +	bool "Second FEC ethernet controller"
> >  	depends on FEC
> >  	help
> >  	  Say Y here if you want to use the second built-in 10/100 Fast
> > -	  ethernet controller on some Motorola ColdFire processors.
> > +	  ethernet controller on some Motorola ColdFire and Freescale
> > +	  i.MX processors.
> 
> This option is used nowhere and should be removed. Certainly it does not
> have the effect of enabling the second ethernet controller.
> 
As David has merged it, I would send a follow-up patch to remove it.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 07/10] ARM: mx28: add the second fec device registration
  2011-01-11 10:29     ` Sascha Hauer
@ 2011-01-11 11:39       ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-11 11:39 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig, lw, w.sang, jamie, jamie, netdev,
	linux-arm-kernel

Hi Sascha,

On Tue, Jan 11, 2011 at 11:29:09AM +0100, Sascha Hauer wrote:
> On Thu, Jan 06, 2011 at 03:13:15PM +0800, Shawn Guo wrote:
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > ---
> >  arch/arm/mach-mxs/mach-mx28evk.c |   28 +++++++++++++++++++++++++---
> >  1 files changed, 25 insertions(+), 3 deletions(-)
> > 
> >  
> >  static void __init mx28evk_init(void)
> > @@ -117,7 +136,10 @@ static void __init mx28evk_init(void)
> >  	mx28_add_duart();
> >  
> >  	mx28evk_fec_reset();
> > -	mx28_add_fec(0, &mx28_fec_pdata);
> > +	mx28_add_fec(0, &mx28_fec_pdata[0]);
> > +#ifdef CONFIG_FEC2
> > +	mx28_add_fec(1, &mx28_fec_pdata[1]);
> > +#endif
> 
> Please don't do this. If you really want to make this configurable with
> kconfig use a board specific option, not a driver specific option. I
> think this should be made unconditional though.
> 
I will resend this patch as v5 than the whole patch set, if you
do not mind.

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 07/10] ARM: mx28: add the second fec device registration
@ 2011-01-11 11:39       ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-11 11:39 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sascha,

On Tue, Jan 11, 2011 at 11:29:09AM +0100, Sascha Hauer wrote:
> On Thu, Jan 06, 2011 at 03:13:15PM +0800, Shawn Guo wrote:
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > ---
> >  arch/arm/mach-mxs/mach-mx28evk.c |   28 +++++++++++++++++++++++++---
> >  1 files changed, 25 insertions(+), 3 deletions(-)
> > 
> >  
> >  static void __init mx28evk_init(void)
> > @@ -117,7 +136,10 @@ static void __init mx28evk_init(void)
> >  	mx28_add_duart();
> >  
> >  	mx28evk_fec_reset();
> > -	mx28_add_fec(0, &mx28_fec_pdata);
> > +	mx28_add_fec(0, &mx28_fec_pdata[0]);
> > +#ifdef CONFIG_FEC2
> > +	mx28_add_fec(1, &mx28_fec_pdata[1]);
> > +#endif
> 
> Please don't do this. If you really want to make this configurable with
> kconfig use a board specific option, not a driver specific option. I
> think this should be made unconditional though.
> 
I will resend this patch as v5 than the whole patch set, if you
do not mind.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 07/10] ARM: mx28: add the second fec device registration
  2011-01-11 11:39       ` Shawn Guo
@ 2011-01-11 11:44         ` Sascha Hauer
  -1 siblings, 0 replies; 118+ messages in thread
From: Sascha Hauer @ 2011-01-11 11:44 UTC (permalink / raw)
  To: Shawn Guo
  Cc: gerg, B32542, netdev, u.kleine-koenig, jamie, baruch, w.sang,
	r64343, eric, bryan.wu, jamie, davem, linux-arm-kernel, lw

On Tue, Jan 11, 2011 at 07:39:52PM +0800, Shawn Guo wrote:
> Hi Sascha,
> 
> On Tue, Jan 11, 2011 at 11:29:09AM +0100, Sascha Hauer wrote:
> > On Thu, Jan 06, 2011 at 03:13:15PM +0800, Shawn Guo wrote:
> > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > > ---
> > >  arch/arm/mach-mxs/mach-mx28evk.c |   28 +++++++++++++++++++++++++---
> > >  1 files changed, 25 insertions(+), 3 deletions(-)
> > > 
> > >  
> > >  static void __init mx28evk_init(void)
> > > @@ -117,7 +136,10 @@ static void __init mx28evk_init(void)
> > >  	mx28_add_duart();
> > >  
> > >  	mx28evk_fec_reset();
> > > -	mx28_add_fec(0, &mx28_fec_pdata);
> > > +	mx28_add_fec(0, &mx28_fec_pdata[0]);
> > > +#ifdef CONFIG_FEC2
> > > +	mx28_add_fec(1, &mx28_fec_pdata[1]);
> > > +#endif
> > 
> > Please don't do this. If you really want to make this configurable with
> > kconfig use a board specific option, not a driver specific option. I
> > think this should be made unconditional though.
> > 
> I will resend this patch as v5 than the whole patch set, if you
> do not mind.

ok

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 07/10] ARM: mx28: add the second fec device registration
@ 2011-01-11 11:44         ` Sascha Hauer
  0 siblings, 0 replies; 118+ messages in thread
From: Sascha Hauer @ 2011-01-11 11:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 11, 2011 at 07:39:52PM +0800, Shawn Guo wrote:
> Hi Sascha,
> 
> On Tue, Jan 11, 2011 at 11:29:09AM +0100, Sascha Hauer wrote:
> > On Thu, Jan 06, 2011 at 03:13:15PM +0800, Shawn Guo wrote:
> > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > > ---
> > >  arch/arm/mach-mxs/mach-mx28evk.c |   28 +++++++++++++++++++++++++---
> > >  1 files changed, 25 insertions(+), 3 deletions(-)
> > > 
> > >  
> > >  static void __init mx28evk_init(void)
> > > @@ -117,7 +136,10 @@ static void __init mx28evk_init(void)
> > >  	mx28_add_duart();
> > >  
> > >  	mx28evk_fec_reset();
> > > -	mx28_add_fec(0, &mx28_fec_pdata);
> > > +	mx28_add_fec(0, &mx28_fec_pdata[0]);
> > > +#ifdef CONFIG_FEC2
> > > +	mx28_add_fec(1, &mx28_fec_pdata[1]);
> > > +#endif
> > 
> > Please don't do this. If you really want to make this configurable with
> > kconfig use a board specific option, not a driver specific option. I
> > think this should be made unconditional though.
> > 
> I will resend this patch as v5 than the whole patch set, if you
> do not mind.

ok

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH] net/fec: remove config FEC2 as it's used nowhere
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-11 12:07   ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-11 12:07 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig
  Cc: Shawn Guo

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 drivers/net/Kconfig |    8 --------
 1 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index f34629b..24b1b33 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1950,14 +1950,6 @@ config FEC
 	  Say Y here if you want to use the built-in 10/100 Fast ethernet
 	  controller on some Motorola ColdFire and Freescale i.MX processors.
 
-config FEC2
-	bool "Second FEC ethernet controller"
-	depends on FEC
-	help
-	  Say Y here if you want to use the second built-in 10/100 Fast
-	  ethernet controller on some Motorola ColdFire and Freescale
-	  i.MX processors.
-
 config FEC_MPC52xx
 	tristate "MPC52xx FEC driver"
 	depends on PPC_MPC52xx && PPC_BESTCOMM
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH] net/fec: remove config FEC2 as it's used nowhere
@ 2011-01-11 12:07   ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-11 12:07 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 drivers/net/Kconfig |    8 --------
 1 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index f34629b..24b1b33 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1950,14 +1950,6 @@ config FEC
 	  Say Y here if you want to use the built-in 10/100 Fast ethernet
 	  controller on some Motorola ColdFire and Freescale i.MX processors.
 
-config FEC2
-	bool "Second FEC ethernet controller"
-	depends on FEC
-	help
-	  Say Y here if you want to use the second built-in 10/100 Fast
-	  ethernet controller on some Motorola ColdFire and Freescale
-	  i.MX processors.
-
 config FEC_MPC52xx
 	tristate "MPC52xx FEC driver"
 	depends on PPC_MPC52xx && PPC_BESTCOMM
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v5] ARM: mx28: add the second fec device registration
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-11 12:09   ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-11 12:09 UTC (permalink / raw)
  To: s.hauer, davem, gerg, baruch, eric, bryan.wu, r64343, B32542; +Cc: Shawn Guo

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v5:
 - Do not use CONFIG_FEC2 which is a fec driver configration

 arch/arm/mach-mxs/mach-mx28evk.c |   26 +++++++++++++++++++++++---
 1 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index d162e95..8e2c597 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -57,6 +57,19 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
 		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
 	MX28_PAD_ENET_CLK__CLKCTRL_ENET |
 		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	/* fec1 */
+	MX28_PAD_ENET0_CRS__ENET1_RX_EN |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_RXD2__ENET1_RXD0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_RXD3__ENET1_RXD1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_COL__ENET1_TX_EN |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_TXD2__ENET1_TXD0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_TXD3__ENET1_TXD1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
 	/* phy power line */
 	MX28_PAD_SSP1_DATA3__GPIO_2_15 |
 		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
@@ -106,8 +119,14 @@ static void __init mx28evk_fec_reset(void)
 	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
 }
 
-static const struct fec_platform_data mx28_fec_pdata __initconst = {
-	.phy = PHY_INTERFACE_MODE_RMII,
+static struct fec_platform_data mx28_fec_pdata[] = {
+	{
+		/* fec0 */
+		.phy = PHY_INTERFACE_MODE_RMII,
+	}, {
+		/* fec1 */
+		.phy = PHY_INTERFACE_MODE_RMII,
+	},
 };
 
 static void __init mx28evk_init(void)
@@ -117,7 +136,8 @@ static void __init mx28evk_init(void)
 	mx28_add_duart();
 
 	mx28evk_fec_reset();
-	mx28_add_fec(0, &mx28_fec_pdata);
+	mx28_add_fec(0, &mx28_fec_pdata[0]);
+	mx28_add_fec(1, &mx28_fec_pdata[1]);
 }
 
 static void __init mx28evk_timer_init(void)
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v5] ARM: mx28: add the second fec device registration
@ 2011-01-11 12:09   ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-11 12:09 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v5:
 - Do not use CONFIG_FEC2 which is a fec driver configration

 arch/arm/mach-mxs/mach-mx28evk.c |   26 +++++++++++++++++++++++---
 1 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index d162e95..8e2c597 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -57,6 +57,19 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
 		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
 	MX28_PAD_ENET_CLK__CLKCTRL_ENET |
 		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	/* fec1 */
+	MX28_PAD_ENET0_CRS__ENET1_RX_EN |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_RXD2__ENET1_RXD0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_RXD3__ENET1_RXD1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_COL__ENET1_TX_EN |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_TXD2__ENET1_TXD0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_TXD3__ENET1_TXD1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
 	/* phy power line */
 	MX28_PAD_SSP1_DATA3__GPIO_2_15 |
 		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
@@ -106,8 +119,14 @@ static void __init mx28evk_fec_reset(void)
 	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
 }
 
-static const struct fec_platform_data mx28_fec_pdata __initconst = {
-	.phy = PHY_INTERFACE_MODE_RMII,
+static struct fec_platform_data mx28_fec_pdata[] = {
+	{
+		/* fec0 */
+		.phy = PHY_INTERFACE_MODE_RMII,
+	}, {
+		/* fec1 */
+		.phy = PHY_INTERFACE_MODE_RMII,
+	},
 };
 
 static void __init mx28evk_init(void)
@@ -117,7 +136,8 @@ static void __init mx28evk_init(void)
 	mx28_add_duart();
 
 	mx28evk_fec_reset();
-	mx28_add_fec(0, &mx28_fec_pdata);
+	mx28_add_fec(0, &mx28_fec_pdata[0]);
+	mx28_add_fec(1, &mx28_fec_pdata[1]);
 }
 
 static void __init mx28evk_timer_init(void)
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 05/10] net/fec: add dual fec support for mx28
  2011-01-11 10:27     ` Sascha Hauer
@ 2011-01-11 12:24       ` Greg Ungerer
  -1 siblings, 0 replies; 118+ messages in thread
From: Greg Ungerer @ 2011-01-11 12:24 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Shawn Guo, B32542, netdev, u.kleine-koenig, jamie, baruch,
	w.sang, r64343, eric, bryan.wu, jamie, davem, linux-arm-kernel,
	lw

On 11/01/11 20:27, Sascha Hauer wrote:
> On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
>> This patch is to add mx28 dual fec support. Here are some key notes
>> for mx28 fec controller.
>>
>>   - The mx28 fec controller naming ENET-MAC is a different IP from FEC
>>     used on other i.mx variants.  But they are basically compatible
>>     on software interface, so it's possible to share the same driver.
>>   - ENET-MAC design on mx28 made an improper assumption that it runs
>>     on a big-endian system. As the result, driver has to swap every
>>     frame going to and coming from the controller.
>>   - The external phys can only be configured by fec0, which means fec1
>>     can not work independently and both phys need to be configured by
>>     mii_bus attached on fec0.
>>   - ENET-MAC reset will get mac address registers reset too.
>>   - ENET-MAC MII/RMII mode and 10M/100M speed are configured
>>     differently FEC.
>>   - ETHER_EN bit must be set to get ENET-MAC interrupt work.
>>
>> Signed-off-by: Shawn Guo<shawn.guo@freescale.com>
>> ---
>> Changes for v4:
>>   - Use #ifndef CONFIG_ARM to include ColdFire header files
>>   - Define quirk bits in id_entry.driver_data to handle controller
>>     difference, which is more scalable than using device name
>>   - Define fec0_mii_bus as a static function in fec_enet_mii_init
>>     to fold the mii_bus instance attached on fec0
>>   - Use cpu_to_be32 over __swab32 in function swap_buffer
>>
>> Changes for v3:
>>   - Move v2 changes into patch #3
>>   - Use device name to check if it's running on ENET-MAC
>>
>>   drivers/net/Kconfig |    7 ++-
>>   drivers/net/fec.c   |  148 +++++++++++++++++++++++++++++++++++++++++++++------
>>   drivers/net/fec.h   |    5 +-
>>   3 files changed, 139 insertions(+), 21 deletions(-)
>>
>> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
>> index 4f1755b..f34629b 100644
>> --- a/drivers/net/Kconfig
>> +++ b/drivers/net/Kconfig
>> @@ -1944,18 +1944,19 @@ config 68360_ENET
>>   config FEC
>>   	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
>>   	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
>> -		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
>> +		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
>>   	select PHYLIB
>>   	help
>>   	  Say Y here if you want to use the built-in 10/100 Fast ethernet
>>   	  controller on some Motorola ColdFire and Freescale i.MX processors.
>>
>>   config FEC2
>> -	bool "Second FEC ethernet controller (on some ColdFire CPUs)"
>> +	bool "Second FEC ethernet controller"
>>   	depends on FEC
>>   	help
>>   	  Say Y here if you want to use the second built-in 10/100 Fast
>> -	  ethernet controller on some Motorola ColdFire processors.
>> +	  ethernet controller on some Motorola ColdFire and Freescale
>> +	  i.MX processors.
>
> This option is used nowhere and should be removed. Certainly it does not
> have the effect of enabling the second ethernet controller.

It does for a ColdFire platform...

grep -r CONFIG_FEC2 *

arch/m68knommu/configs/m5275evb_defconfig:CONFIG_FEC2=y
arch/m68knommu/platform/527x/config.c:#ifdef CONFIG_FEC2
arch/m68knommu/platform/527x/config.c:#ifdef CONFIG_FEC2

Regards
Greg


------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg@snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close,                            FAX:         +61 7 3891 3630
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
@ 2011-01-11 12:24       ` Greg Ungerer
  0 siblings, 0 replies; 118+ messages in thread
From: Greg Ungerer @ 2011-01-11 12:24 UTC (permalink / raw)
  To: linux-arm-kernel

On 11/01/11 20:27, Sascha Hauer wrote:
> On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
>> This patch is to add mx28 dual fec support. Here are some key notes
>> for mx28 fec controller.
>>
>>   - The mx28 fec controller naming ENET-MAC is a different IP from FEC
>>     used on other i.mx variants.  But they are basically compatible
>>     on software interface, so it's possible to share the same driver.
>>   - ENET-MAC design on mx28 made an improper assumption that it runs
>>     on a big-endian system. As the result, driver has to swap every
>>     frame going to and coming from the controller.
>>   - The external phys can only be configured by fec0, which means fec1
>>     can not work independently and both phys need to be configured by
>>     mii_bus attached on fec0.
>>   - ENET-MAC reset will get mac address registers reset too.
>>   - ENET-MAC MII/RMII mode and 10M/100M speed are configured
>>     differently FEC.
>>   - ETHER_EN bit must be set to get ENET-MAC interrupt work.
>>
>> Signed-off-by: Shawn Guo<shawn.guo@freescale.com>
>> ---
>> Changes for v4:
>>   - Use #ifndef CONFIG_ARM to include ColdFire header files
>>   - Define quirk bits in id_entry.driver_data to handle controller
>>     difference, which is more scalable than using device name
>>   - Define fec0_mii_bus as a static function in fec_enet_mii_init
>>     to fold the mii_bus instance attached on fec0
>>   - Use cpu_to_be32 over __swab32 in function swap_buffer
>>
>> Changes for v3:
>>   - Move v2 changes into patch #3
>>   - Use device name to check if it's running on ENET-MAC
>>
>>   drivers/net/Kconfig |    7 ++-
>>   drivers/net/fec.c   |  148 +++++++++++++++++++++++++++++++++++++++++++++------
>>   drivers/net/fec.h   |    5 +-
>>   3 files changed, 139 insertions(+), 21 deletions(-)
>>
>> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
>> index 4f1755b..f34629b 100644
>> --- a/drivers/net/Kconfig
>> +++ b/drivers/net/Kconfig
>> @@ -1944,18 +1944,19 @@ config 68360_ENET
>>   config FEC
>>   	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
>>   	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
>> -		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
>> +		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
>>   	select PHYLIB
>>   	help
>>   	  Say Y here if you want to use the built-in 10/100 Fast ethernet
>>   	  controller on some Motorola ColdFire and Freescale i.MX processors.
>>
>>   config FEC2
>> -	bool "Second FEC ethernet controller (on some ColdFire CPUs)"
>> +	bool "Second FEC ethernet controller"
>>   	depends on FEC
>>   	help
>>   	  Say Y here if you want to use the second built-in 10/100 Fast
>> -	  ethernet controller on some Motorola ColdFire processors.
>> +	  ethernet controller on some Motorola ColdFire and Freescale
>> +	  i.MX processors.
>
> This option is used nowhere and should be removed. Certainly it does not
> have the effect of enabling the second ethernet controller.

It does for a ColdFire platform...

grep -r CONFIG_FEC2 *

arch/m68knommu/configs/m5275evb_defconfig:CONFIG_FEC2=y
arch/m68knommu/platform/527x/config.c:#ifdef CONFIG_FEC2
arch/m68knommu/platform/527x/config.c:#ifdef CONFIG_FEC2

Regards
Greg


------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg at snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close,                            FAX:         +61 7 3891 3630
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 05/10] net/fec: add dual fec support for mx28
  2011-01-11 12:24       ` Greg Ungerer
@ 2011-01-11 13:07         ` Uwe Kleine-König
  -1 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-11 13:07 UTC (permalink / raw)
  To: Greg Ungerer
  Cc: Sascha Hauer, Shawn Guo, B32542, netdev, jamie, baruch, w.sang,
	r64343, eric, bryan.wu, jamie, davem, linux-arm-kernel, lw

Hi Greg,

On Tue, Jan 11, 2011 at 10:24:12PM +1000, Greg Ungerer wrote:
> On 11/01/11 20:27, Sascha Hauer wrote:
> >On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
> >This option is used nowhere and should be removed. Certainly it does not
> >have the effect of enabling the second ethernet controller.
> 
> It does for a ColdFire platform...
> 
> grep -r CONFIG_FEC2 *
> 
> arch/m68knommu/configs/m5275evb_defconfig:CONFIG_FEC2=y
> arch/m68knommu/platform/527x/config.c:#ifdef CONFIG_FEC2
> arch/m68knommu/platform/527x/config.c:#ifdef CONFIG_FEC2
IMHO Sascha's comment[1] applies here, too.

And someone might want to do what he suggested soon or the patch
removing CONFIG_FEC2[2] needs to be commented accordingly.

Best regards
Uwe

[1] http://thread.gmane.org/gmane.linux.network/182929/focus=183378
[2] http://mid.gmane.org/1294747672-4433-1-git-send-email-shawn.guo@freescale.com

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
@ 2011-01-11 13:07         ` Uwe Kleine-König
  0 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-11 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Greg,

On Tue, Jan 11, 2011 at 10:24:12PM +1000, Greg Ungerer wrote:
> On 11/01/11 20:27, Sascha Hauer wrote:
> >On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
> >This option is used nowhere and should be removed. Certainly it does not
> >have the effect of enabling the second ethernet controller.
> 
> It does for a ColdFire platform...
> 
> grep -r CONFIG_FEC2 *
> 
> arch/m68knommu/configs/m5275evb_defconfig:CONFIG_FEC2=y
> arch/m68knommu/platform/527x/config.c:#ifdef CONFIG_FEC2
> arch/m68knommu/platform/527x/config.c:#ifdef CONFIG_FEC2
IMHO Sascha's comment[1] applies here, too.

And someone might want to do what he suggested soon or the patch
removing CONFIG_FEC2[2] needs to be commented accordingly.

Best regards
Uwe

[1] http://thread.gmane.org/gmane.linux.network/182929/focus=183378
[2] http://mid.gmane.org/1294747672-4433-1-git-send-email-shawn.guo at freescale.com

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 05/10] net/fec: add dual fec support for mx28
  2011-01-11 13:07         ` Uwe Kleine-König
@ 2011-01-11 13:25           ` Greg Ungerer
  -1 siblings, 0 replies; 118+ messages in thread
From: Greg Ungerer @ 2011-01-11 13:25 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: baruch, B32542, netdev, Sascha Hauer, jamie, w.sang, r64343,
	linux-arm-kernel, eric, bryan.wu, jamie, davem, Shawn Guo, lw

Hi Uwe,

On 11/01/11 23:07, Uwe Kleine-König wrote:
> Hi Greg,
>
> On Tue, Jan 11, 2011 at 10:24:12PM +1000, Greg Ungerer wrote:
>> On 11/01/11 20:27, Sascha Hauer wrote:
>>> On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
>>> This option is used nowhere and should be removed. Certainly it does not
>>> have the effect of enabling the second ethernet controller.
>>
>> It does for a ColdFire platform...
>>
>> grep -r CONFIG_FEC2 *
>>
>> arch/m68knommu/configs/m5275evb_defconfig:CONFIG_FEC2=y
>> arch/m68knommu/platform/527x/config.c:#ifdef CONFIG_FEC2
>> arch/m68knommu/platform/527x/config.c:#ifdef CONFIG_FEC2
> IMHO Sascha's comment[1] applies here, too.

I am not arguing that it doesn't :-)

Simply that removing that config option and doing nothing
else would not be the right thing to do.

Regards
Greg


> And someone might want to do what he suggested soon or the patch
> removing CONFIG_FEC2[2] needs to be commented accordingly.
>
> Best regards
> Uwe
>
> [1] http://thread.gmane.org/gmane.linux.network/182929/focus=183378
> [2] http://mid.gmane.org/1294747672-4433-1-git-send-email-shawn.guo@freescale.com
>


-- 
------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg@snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close,                            FAX:         +61 7 3891 3630
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
@ 2011-01-11 13:25           ` Greg Ungerer
  0 siblings, 0 replies; 118+ messages in thread
From: Greg Ungerer @ 2011-01-11 13:25 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

On 11/01/11 23:07, Uwe Kleine-K?nig wrote:
> Hi Greg,
>
> On Tue, Jan 11, 2011 at 10:24:12PM +1000, Greg Ungerer wrote:
>> On 11/01/11 20:27, Sascha Hauer wrote:
>>> On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
>>> This option is used nowhere and should be removed. Certainly it does not
>>> have the effect of enabling the second ethernet controller.
>>
>> It does for a ColdFire platform...
>>
>> grep -r CONFIG_FEC2 *
>>
>> arch/m68knommu/configs/m5275evb_defconfig:CONFIG_FEC2=y
>> arch/m68knommu/platform/527x/config.c:#ifdef CONFIG_FEC2
>> arch/m68knommu/platform/527x/config.c:#ifdef CONFIG_FEC2
> IMHO Sascha's comment[1] applies here, too.

I am not arguing that it doesn't :-)

Simply that removing that config option and doing nothing
else would not be the right thing to do.

Regards
Greg


> And someone might want to do what he suggested soon or the patch
> removing CONFIG_FEC2[2] needs to be commented accordingly.
>
> Best regards
> Uwe
>
> [1] http://thread.gmane.org/gmane.linux.network/182929/focus=183378
> [2] http://mid.gmane.org/1294747672-4433-1-git-send-email-shawn.guo at freescale.com
>


-- 
------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg at snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close,                            FAX:         +61 7 3891 3630
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 08/10] ARM: mxs: add ocotp read function
  2011-01-06  7:13   ` Shawn Guo
@ 2011-01-11 13:31     ` Sascha Hauer
  -1 siblings, 0 replies; 118+ messages in thread
From: Sascha Hauer @ 2011-01-11 13:31 UTC (permalink / raw)
  To: Shawn Guo
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig, lw, w.sang, jamie, jamie, netdev,
	linux-arm-kernel

On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v4:
>  - Call cpu_relax() during polling
> 
> Changes for v2:
>  - Add mutex locking for mxs_read_ocotp()
>  - Use type size_t for count and i
>  - Add comment for clk_enable/disable skipping
>  - Add ERROR bit clearing and polling step
> 
>  arch/arm/mach-mxs/Makefile              |    2 +-
>  arch/arm/mach-mxs/include/mach/common.h |    1 +
>  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
>  3 files changed, 81 insertions(+), 1 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/ocotp.c
> 
> diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> index 39d3f9c..f23ebbd 100644
> --- a/arch/arm/mach-mxs/Makefile
> +++ b/arch/arm/mach-mxs/Makefile
> @@ -1,5 +1,5 @@
>  # Common support
> -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
>  
>  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
>  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
> diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> index 59133eb..cf02552 100644
> --- a/arch/arm/mach-mxs/include/mach/common.h
> +++ b/arch/arm/mach-mxs/include/mach/common.h
> @@ -13,6 +13,7 @@
>  
>  struct clk;
>  
> +extern int mxs_read_ocotp(int offset, int count, u32 *values);
>  extern int mxs_reset_block(void __iomem *);
>  extern void mxs_timer_init(struct clk *, int);
>  
> diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> new file mode 100644
> index 0000000..e2d39aa
> --- /dev/null
> +++ b/arch/arm/mach-mxs/ocotp.c
> @@ -0,0 +1,79 @@
> +/*
> + * Copyright 2010 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 as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/mutex.h>
> +
> +#include <mach/mxs.h>
> +
> +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> +
> +static DEFINE_MUTEX(ocotp_mutex);
> +
> +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> +{
> +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> +	int timeout = 0x400;
> +	size_t i;
> +
> +	mutex_lock(&ocotp_mutex);
> +
> +	/*
> +	 * clk_enable(hbus_clk) for ocotp can be skipped
> +	 * as it must be on when system is running.
> +	 */
> +
> +	/* try to clear ERROR bit */
> +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);

This operation does not try to clear the error bit but actually clears
it...

> +
> +	/* check both BUSY and ERROR cleared */
> +	while ((__raw_readl(ocotp_base) &
> +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> +		cpu_relax();

...which means you do not have to poll the error bit here...

> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	/* open OCOTP banks for read */
> +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> +
> +	/* approximately wait 32 hclk cycles */
> +	udelay(1);
> +
> +	/* poll BUSY bit becoming cleared */
> +	timeout = 0x400;
> +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> +		cpu_relax();

...which means you can factor out a ocotp_wait_busy function and let the
code speak instead of the comments.

> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	for (i = 0; i < count; i++, offset += 4)
> +		*values++ = __raw_readl(ocotp_base + offset);

The registers in the ocotp are 16 byte aligned. Does it really make
sense to provide a function allowing to read the gaps between the
registers?

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 08/10] ARM: mxs: add ocotp read function
@ 2011-01-11 13:31     ` Sascha Hauer
  0 siblings, 0 replies; 118+ messages in thread
From: Sascha Hauer @ 2011-01-11 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v4:
>  - Call cpu_relax() during polling
> 
> Changes for v2:
>  - Add mutex locking for mxs_read_ocotp()
>  - Use type size_t for count and i
>  - Add comment for clk_enable/disable skipping
>  - Add ERROR bit clearing and polling step
> 
>  arch/arm/mach-mxs/Makefile              |    2 +-
>  arch/arm/mach-mxs/include/mach/common.h |    1 +
>  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
>  3 files changed, 81 insertions(+), 1 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/ocotp.c
> 
> diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> index 39d3f9c..f23ebbd 100644
> --- a/arch/arm/mach-mxs/Makefile
> +++ b/arch/arm/mach-mxs/Makefile
> @@ -1,5 +1,5 @@
>  # Common support
> -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
>  
>  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
>  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
> diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> index 59133eb..cf02552 100644
> --- a/arch/arm/mach-mxs/include/mach/common.h
> +++ b/arch/arm/mach-mxs/include/mach/common.h
> @@ -13,6 +13,7 @@
>  
>  struct clk;
>  
> +extern int mxs_read_ocotp(int offset, int count, u32 *values);
>  extern int mxs_reset_block(void __iomem *);
>  extern void mxs_timer_init(struct clk *, int);
>  
> diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> new file mode 100644
> index 0000000..e2d39aa
> --- /dev/null
> +++ b/arch/arm/mach-mxs/ocotp.c
> @@ -0,0 +1,79 @@
> +/*
> + * Copyright 2010 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 as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/mutex.h>
> +
> +#include <mach/mxs.h>
> +
> +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> +
> +static DEFINE_MUTEX(ocotp_mutex);
> +
> +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> +{
> +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> +	int timeout = 0x400;
> +	size_t i;
> +
> +	mutex_lock(&ocotp_mutex);
> +
> +	/*
> +	 * clk_enable(hbus_clk) for ocotp can be skipped
> +	 * as it must be on when system is running.
> +	 */
> +
> +	/* try to clear ERROR bit */
> +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);

This operation does not try to clear the error bit but actually clears
it...

> +
> +	/* check both BUSY and ERROR cleared */
> +	while ((__raw_readl(ocotp_base) &
> +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> +		cpu_relax();

...which means you do not have to poll the error bit here...

> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	/* open OCOTP banks for read */
> +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> +
> +	/* approximately wait 32 hclk cycles */
> +	udelay(1);
> +
> +	/* poll BUSY bit becoming cleared */
> +	timeout = 0x400;
> +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> +		cpu_relax();

...which means you can factor out a ocotp_wait_busy function and let the
code speak instead of the comments.

> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	for (i = 0; i < count; i++, offset += 4)
> +		*values++ = __raw_readl(ocotp_base + offset);

The registers in the ocotp are 16 byte aligned. Does it really make
sense to provide a function allowing to read the gaps between the
registers?

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 08/10] ARM: mxs: add ocotp read function
  2011-01-11 13:31     ` Sascha Hauer
@ 2011-01-11 14:05       ` Uwe Kleine-König
  -1 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-11 14:05 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Shawn Guo, gerg, B32542, netdev, jamie, baruch, w.sang, r64343,
	eric, bryan.wu, jamie, davem, linux-arm-kernel, lw

Hello Sascha,

On Tue, Jan 11, 2011 at 02:31:37PM +0100, Sascha Hauer wrote:
> On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> > diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> > new file mode 100644
> > index 0000000..e2d39aa
> > --- /dev/null
> > +++ b/arch/arm/mach-mxs/ocotp.c
> > @@ -0,0 +1,79 @@
> > +/*
> > + * Copyright 2010 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 as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/err.h>
> > +#include <linux/mutex.h>
> > +
> > +#include <mach/mxs.h>
> > +
> > +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> > +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> > +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> > +
> > +static DEFINE_MUTEX(ocotp_mutex);
> > +
> > +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> > +{
> > +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> > +	int timeout = 0x400;
> > +	size_t i;
> > +
> > +	mutex_lock(&ocotp_mutex);
> > +
> > +	/*
> > +	 * clk_enable(hbus_clk) for ocotp can be skipped
> > +	 * as it must be on when system is running.
> > +	 */
> > +
> > +	/* try to clear ERROR bit */
> > +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> 
> This operation does not try to clear the error bit but actually clears
> it...
> 
> > +
> > +	/* check both BUSY and ERROR cleared */
> > +	while ((__raw_readl(ocotp_base) &
> > +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> > +		cpu_relax();
> 
> ...which means you do not have to poll the error bit here...
well, I don't know how the hardware works here, but in general the
argument is broken.  Registers are not memory, so just because you set a
bit in register space it doesn't mean it is really set when you read
from the same address.

If there is something wrong with the ocotp I'd even expect that clearing
the error bit doesn't work because it doesn't change the general
condition.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 08/10] ARM: mxs: add ocotp read function
@ 2011-01-11 14:05       ` Uwe Kleine-König
  0 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-11 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Sascha,

On Tue, Jan 11, 2011 at 02:31:37PM +0100, Sascha Hauer wrote:
> On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> > diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> > new file mode 100644
> > index 0000000..e2d39aa
> > --- /dev/null
> > +++ b/arch/arm/mach-mxs/ocotp.c
> > @@ -0,0 +1,79 @@
> > +/*
> > + * Copyright 2010 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 as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/err.h>
> > +#include <linux/mutex.h>
> > +
> > +#include <mach/mxs.h>
> > +
> > +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> > +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> > +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> > +
> > +static DEFINE_MUTEX(ocotp_mutex);
> > +
> > +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> > +{
> > +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> > +	int timeout = 0x400;
> > +	size_t i;
> > +
> > +	mutex_lock(&ocotp_mutex);
> > +
> > +	/*
> > +	 * clk_enable(hbus_clk) for ocotp can be skipped
> > +	 * as it must be on when system is running.
> > +	 */
> > +
> > +	/* try to clear ERROR bit */
> > +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> 
> This operation does not try to clear the error bit but actually clears
> it...
> 
> > +
> > +	/* check both BUSY and ERROR cleared */
> > +	while ((__raw_readl(ocotp_base) &
> > +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> > +		cpu_relax();
> 
> ...which means you do not have to poll the error bit here...
well, I don't know how the hardware works here, but in general the
argument is broken.  Registers are not memory, so just because you set a
bit in register space it doesn't mean it is really set when you read
from the same address.

If there is something wrong with the ocotp I'd even expect that clearing
the error bit doesn't work because it doesn't change the general
condition.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH] net/fec: remove config FEC2 as it's used nowhere
  2011-01-11 12:07   ` Shawn Guo
@ 2011-01-11 22:03     ` David Miller
  -1 siblings, 0 replies; 118+ messages in thread
From: David Miller @ 2011-01-11 22:03 UTC (permalink / raw)
  To: shawn.guo
  Cc: gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig,
	lw, w.sang, s.hauer, jamie, jamie, netdev, linux-arm-kernel

From: Shawn Guo <shawn.guo@freescale.com>
Date: Tue, 11 Jan 2011 20:07:52 +0800

> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>

Applied.

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH] net/fec: remove config FEC2 as it's used nowhere
@ 2011-01-11 22:03     ` David Miller
  0 siblings, 0 replies; 118+ messages in thread
From: David Miller @ 2011-01-11 22:03 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@freescale.com>
Date: Tue, 11 Jan 2011 20:07:52 +0800

> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>

Applied.

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 08/10] ARM: mxs: add ocotp read function
  2011-01-11 13:31     ` Sascha Hauer
@ 2011-01-12  6:47       ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-12  6:47 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig, lw, w.sang, jamie, jamie, netdev,
	linux-arm-kernel

Hi Sascha,

On Tue, Jan 11, 2011 at 02:31:37PM +0100, Sascha Hauer wrote:
> On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > ---
> > Changes for v4:
> >  - Call cpu_relax() during polling
> > 
> > Changes for v2:
> >  - Add mutex locking for mxs_read_ocotp()
> >  - Use type size_t for count and i
> >  - Add comment for clk_enable/disable skipping
> >  - Add ERROR bit clearing and polling step
> > 
> >  arch/arm/mach-mxs/Makefile              |    2 +-
> >  arch/arm/mach-mxs/include/mach/common.h |    1 +
> >  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
> >  3 files changed, 81 insertions(+), 1 deletions(-)
> >  create mode 100644 arch/arm/mach-mxs/ocotp.c
> > 
> > diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> > index 39d3f9c..f23ebbd 100644
> > --- a/arch/arm/mach-mxs/Makefile
> > +++ b/arch/arm/mach-mxs/Makefile
> > @@ -1,5 +1,5 @@
> >  # Common support
> > -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> > +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
> >  
> >  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
> >  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
> > diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> > index 59133eb..cf02552 100644
> > --- a/arch/arm/mach-mxs/include/mach/common.h
> > +++ b/arch/arm/mach-mxs/include/mach/common.h
> > @@ -13,6 +13,7 @@
> >  
> >  struct clk;
> >  
> > +extern int mxs_read_ocotp(int offset, int count, u32 *values);
> >  extern int mxs_reset_block(void __iomem *);
> >  extern void mxs_timer_init(struct clk *, int);
> >  
> > diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> > new file mode 100644
> > index 0000000..e2d39aa
> > --- /dev/null
> > +++ b/arch/arm/mach-mxs/ocotp.c
> > @@ -0,0 +1,79 @@
> > +/*
> > + * Copyright 2010 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 as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/err.h>
> > +#include <linux/mutex.h>
> > +
> > +#include <mach/mxs.h>
> > +
> > +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> > +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> > +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> > +
> > +static DEFINE_MUTEX(ocotp_mutex);
> > +
> > +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> > +{
> > +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> > +	int timeout = 0x400;
> > +	size_t i;
> > +
> > +	mutex_lock(&ocotp_mutex);
> > +
> > +	/*
> > +	 * clk_enable(hbus_clk) for ocotp can be skipped
> > +	 * as it must be on when system is running.
> > +	 */
> > +
> > +	/* try to clear ERROR bit */
> > +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> 
> This operation does not try to clear the error bit but actually clears
> it...
> 
> > +
> > +	/* check both BUSY and ERROR cleared */
> > +	while ((__raw_readl(ocotp_base) &
> > +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> > +		cpu_relax();
> 
> ...which means you do not have to poll the error bit here...
> 
> > +
> > +	if (unlikely(!timeout))
> > +		goto error_unlock;
> > +
> > +	/* open OCOTP banks for read */
> > +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> > +
> > +	/* approximately wait 32 hclk cycles */
> > +	udelay(1);
> > +
> > +	/* poll BUSY bit becoming cleared */
> > +	timeout = 0x400;
> > +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> > +		cpu_relax();
> 
> ...which means you can factor out a ocotp_wait_busy function and let the
> code speak instead of the comments.
> 
> > +
> > +	if (unlikely(!timeout))
> > +		goto error_unlock;
> > +
> > +	for (i = 0; i < count; i++, offset += 4)
> > +		*values++ = __raw_readl(ocotp_base + offset);
> 
> The registers in the ocotp are 16 byte aligned. Does it really make
> sense to provide a function allowing to read the gaps between the
> registers?
> 
Good catch.  The count was added to ease the consecutive otp word
reading, as there is bank open/close cost for otp read.  What about
the following changes?

int mxs_read_ocotp(unsigned offset, size_t otp_word_cnt, u32 *values)
{
	......

	for (i = 0; i < otp_word_cnt; i++, offset += 0x10)
		*values++ = __raw_readl(ocotp_base + offset);

	......
}


-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 08/10] ARM: mxs: add ocotp read function
@ 2011-01-12  6:47       ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-12  6:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sascha,

On Tue, Jan 11, 2011 at 02:31:37PM +0100, Sascha Hauer wrote:
> On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > ---
> > Changes for v4:
> >  - Call cpu_relax() during polling
> > 
> > Changes for v2:
> >  - Add mutex locking for mxs_read_ocotp()
> >  - Use type size_t for count and i
> >  - Add comment for clk_enable/disable skipping
> >  - Add ERROR bit clearing and polling step
> > 
> >  arch/arm/mach-mxs/Makefile              |    2 +-
> >  arch/arm/mach-mxs/include/mach/common.h |    1 +
> >  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
> >  3 files changed, 81 insertions(+), 1 deletions(-)
> >  create mode 100644 arch/arm/mach-mxs/ocotp.c
> > 
> > diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> > index 39d3f9c..f23ebbd 100644
> > --- a/arch/arm/mach-mxs/Makefile
> > +++ b/arch/arm/mach-mxs/Makefile
> > @@ -1,5 +1,5 @@
> >  # Common support
> > -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> > +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
> >  
> >  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
> >  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
> > diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> > index 59133eb..cf02552 100644
> > --- a/arch/arm/mach-mxs/include/mach/common.h
> > +++ b/arch/arm/mach-mxs/include/mach/common.h
> > @@ -13,6 +13,7 @@
> >  
> >  struct clk;
> >  
> > +extern int mxs_read_ocotp(int offset, int count, u32 *values);
> >  extern int mxs_reset_block(void __iomem *);
> >  extern void mxs_timer_init(struct clk *, int);
> >  
> > diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> > new file mode 100644
> > index 0000000..e2d39aa
> > --- /dev/null
> > +++ b/arch/arm/mach-mxs/ocotp.c
> > @@ -0,0 +1,79 @@
> > +/*
> > + * Copyright 2010 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 as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/err.h>
> > +#include <linux/mutex.h>
> > +
> > +#include <mach/mxs.h>
> > +
> > +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> > +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> > +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> > +
> > +static DEFINE_MUTEX(ocotp_mutex);
> > +
> > +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> > +{
> > +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> > +	int timeout = 0x400;
> > +	size_t i;
> > +
> > +	mutex_lock(&ocotp_mutex);
> > +
> > +	/*
> > +	 * clk_enable(hbus_clk) for ocotp can be skipped
> > +	 * as it must be on when system is running.
> > +	 */
> > +
> > +	/* try to clear ERROR bit */
> > +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> 
> This operation does not try to clear the error bit but actually clears
> it...
> 
> > +
> > +	/* check both BUSY and ERROR cleared */
> > +	while ((__raw_readl(ocotp_base) &
> > +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> > +		cpu_relax();
> 
> ...which means you do not have to poll the error bit here...
> 
> > +
> > +	if (unlikely(!timeout))
> > +		goto error_unlock;
> > +
> > +	/* open OCOTP banks for read */
> > +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> > +
> > +	/* approximately wait 32 hclk cycles */
> > +	udelay(1);
> > +
> > +	/* poll BUSY bit becoming cleared */
> > +	timeout = 0x400;
> > +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> > +		cpu_relax();
> 
> ...which means you can factor out a ocotp_wait_busy function and let the
> code speak instead of the comments.
> 
> > +
> > +	if (unlikely(!timeout))
> > +		goto error_unlock;
> > +
> > +	for (i = 0; i < count; i++, offset += 4)
> > +		*values++ = __raw_readl(ocotp_base + offset);
> 
> The registers in the ocotp are 16 byte aligned. Does it really make
> sense to provide a function allowing to read the gaps between the
> registers?
> 
Good catch.  The count was added to ease the consecutive otp word
reading, as there is bank open/close cost for otp read.  What about
the following changes?

int mxs_read_ocotp(unsigned offset, size_t otp_word_cnt, u32 *values)
{
	......

	for (i = 0; i < otp_word_cnt; i++, offset += 0x10)
		*values++ = __raw_readl(ocotp_base + offset);

	......
}


-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 05/10] net/fec: add dual fec support for mx28
  2011-01-11 13:25           ` Greg Ungerer
@ 2011-01-12  7:42             ` Uwe Kleine-König
  -1 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-12  7:42 UTC (permalink / raw)
  To: Greg Ungerer
  Cc: baruch, B32542, netdev, Sascha Hauer, jamie, w.sang, r64343,
	linux-arm-kernel, eric, bryan.wu, jamie, davem, Shawn Guo, lw

Hi Greg,

On Tue, Jan 11, 2011 at 11:25:41PM +1000, Greg Ungerer wrote:
> On 11/01/11 23:07, Uwe Kleine-König wrote:
> >On Tue, Jan 11, 2011 at 10:24:12PM +1000, Greg Ungerer wrote:
> >>On 11/01/11 20:27, Sascha Hauer wrote:
> >>>On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
> >>>This option is used nowhere and should be removed. Certainly it does not
> >>>have the effect of enabling the second ethernet controller.
> >>
> >>It does for a ColdFire platform...
> >>
> >>grep -r CONFIG_FEC2 *
> >>
> >>arch/m68knommu/configs/m5275evb_defconfig:CONFIG_FEC2=y
> >>arch/m68knommu/platform/527x/config.c:#ifdef CONFIG_FEC2
> >>arch/m68knommu/platform/527x/config.c:#ifdef CONFIG_FEC2
> >IMHO Sascha's comment[1] applies here, too.
> 
> I am not arguing that it doesn't :-)
> 
> Simply that removing that config option and doing nothing
> else would not be the right thing to do.
> 
> Regards
> Greg
> 
> 
> >And someone might want to do what he suggested soon or the patch
> >removing CONFIG_FEC2[2] needs to be commented accordingly.
note that davem took the patch removing CONFIG_FEC2 now.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
@ 2011-01-12  7:42             ` Uwe Kleine-König
  0 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-12  7:42 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Greg,

On Tue, Jan 11, 2011 at 11:25:41PM +1000, Greg Ungerer wrote:
> On 11/01/11 23:07, Uwe Kleine-K?nig wrote:
> >On Tue, Jan 11, 2011 at 10:24:12PM +1000, Greg Ungerer wrote:
> >>On 11/01/11 20:27, Sascha Hauer wrote:
> >>>On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
> >>>This option is used nowhere and should be removed. Certainly it does not
> >>>have the effect of enabling the second ethernet controller.
> >>
> >>It does for a ColdFire platform...
> >>
> >>grep -r CONFIG_FEC2 *
> >>
> >>arch/m68knommu/configs/m5275evb_defconfig:CONFIG_FEC2=y
> >>arch/m68knommu/platform/527x/config.c:#ifdef CONFIG_FEC2
> >>arch/m68knommu/platform/527x/config.c:#ifdef CONFIG_FEC2
> >IMHO Sascha's comment[1] applies here, too.
> 
> I am not arguing that it doesn't :-)
> 
> Simply that removing that config option and doing nothing
> else would not be the right thing to do.
> 
> Regards
> Greg
> 
> 
> >And someone might want to do what he suggested soon or the patch
> >removing CONFIG_FEC2[2] needs to be commented accordingly.
note that davem took the patch removing CONFIG_FEC2 now.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 08/10] ARM: mxs: add ocotp read function
  2011-01-12  6:47       ` Shawn Guo
@ 2011-01-12 14:50         ` Sascha Hauer
  -1 siblings, 0 replies; 118+ messages in thread
From: Sascha Hauer @ 2011-01-12 14:50 UTC (permalink / raw)
  To: Shawn Guo
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig, lw, w.sang, jamie, jamie, netdev,
	linux-arm-kernel

On Wed, Jan 12, 2011 at 02:47:12PM +0800, Shawn Guo wrote:
> Hi Sascha,
> 
> On Tue, Jan 11, 2011 at 02:31:37PM +0100, Sascha Hauer wrote:
> > On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > > ---
> > > Changes for v4:
> > >  - Call cpu_relax() during polling
> > > 
> > > Changes for v2:
> > >  - Add mutex locking for mxs_read_ocotp()
> > >  - Use type size_t for count and i
> > >  - Add comment for clk_enable/disable skipping
> > >  - Add ERROR bit clearing and polling step
> > > 
> > >  arch/arm/mach-mxs/Makefile              |    2 +-
> > >  arch/arm/mach-mxs/include/mach/common.h |    1 +
> > >  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
> > >  3 files changed, 81 insertions(+), 1 deletions(-)
> > >  create mode 100644 arch/arm/mach-mxs/ocotp.c
> > > 
> > > diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> > > index 39d3f9c..f23ebbd 100644
> > > --- a/arch/arm/mach-mxs/Makefile
> > > +++ b/arch/arm/mach-mxs/Makefile
> > > @@ -1,5 +1,5 @@
> > >  # Common support
> > > -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> > > +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
> > >  
> > >  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
> > >  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
> > > diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> > > index 59133eb..cf02552 100644
> > > --- a/arch/arm/mach-mxs/include/mach/common.h
> > > +++ b/arch/arm/mach-mxs/include/mach/common.h
> > > @@ -13,6 +13,7 @@
> > >  
> > >  struct clk;
> > >  
> > > +extern int mxs_read_ocotp(int offset, int count, u32 *values);
> > >  extern int mxs_reset_block(void __iomem *);
> > >  extern void mxs_timer_init(struct clk *, int);
> > >  
> > > diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> > > new file mode 100644
> > > index 0000000..e2d39aa
> > > --- /dev/null
> > > +++ b/arch/arm/mach-mxs/ocotp.c
> > > @@ -0,0 +1,79 @@
> > > +/*
> > > + * Copyright 2010 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 as published by
> > > + * the Free Software Foundation; either version 2 of the License, or
> > > + * (at your option) any later version.
> > > + *
> > > + * This program is distributed in the hope that it will be useful,
> > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > > + * GNU General Public License for more details.
> > > + */
> > > +
> > > +#include <linux/delay.h>
> > > +#include <linux/err.h>
> > > +#include <linux/mutex.h>
> > > +
> > > +#include <mach/mxs.h>
> > > +
> > > +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> > > +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> > > +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> > > +
> > > +static DEFINE_MUTEX(ocotp_mutex);
> > > +
> > > +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> > > +{
> > > +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> > > +	int timeout = 0x400;
> > > +	size_t i;
> > > +
> > > +	mutex_lock(&ocotp_mutex);
> > > +
> > > +	/*
> > > +	 * clk_enable(hbus_clk) for ocotp can be skipped
> > > +	 * as it must be on when system is running.
> > > +	 */
> > > +
> > > +	/* try to clear ERROR bit */
> > > +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> > 
> > This operation does not try to clear the error bit but actually clears
> > it...
> > 
> > > +
> > > +	/* check both BUSY and ERROR cleared */
> > > +	while ((__raw_readl(ocotp_base) &
> > > +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> > > +		cpu_relax();
> > 
> > ...which means you do not have to poll the error bit here...
> > 
> > > +
> > > +	if (unlikely(!timeout))
> > > +		goto error_unlock;
> > > +
> > > +	/* open OCOTP banks for read */
> > > +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> > > +
> > > +	/* approximately wait 32 hclk cycles */
> > > +	udelay(1);
> > > +
> > > +	/* poll BUSY bit becoming cleared */
> > > +	timeout = 0x400;
> > > +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> > > +		cpu_relax();
> > 
> > ...which means you can factor out a ocotp_wait_busy function and let the
> > code speak instead of the comments.
> > 
> > > +
> > > +	if (unlikely(!timeout))
> > > +		goto error_unlock;
> > > +
> > > +	for (i = 0; i < count; i++, offset += 4)
> > > +		*values++ = __raw_readl(ocotp_base + offset);
> > 
> > The registers in the ocotp are 16 byte aligned. Does it really make
> > sense to provide a function allowing to read the gaps between the
> > registers?
> > 
> Good catch.  The count was added to ease the consecutive otp word
> reading, as there is bank open/close cost for otp read.  What about
> the following changes?
> 
> int mxs_read_ocotp(unsigned offset, size_t otp_word_cnt, u32 *values)
> {
> 	......
> 
> 	for (i = 0; i < otp_word_cnt; i++, offset += 0x10)
> 		*values++ = __raw_readl(ocotp_base + offset);
> 
> 	......
> }

I would rather make a function like this:

static u32 ocotp[0x27];

const u32 *mxs_get_ocotp(void)
{
	static int once = 0;

	if (once)
		return ocotp

	/* bank open */

	for (i = 0; i < 0x27; i++)
		ocotp[i] = readl(ocotp_base + 0x20 + i * 0x10)

	/* bank_close */

	once = 1;

	return ocotp;
}


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 08/10] ARM: mxs: add ocotp read function
@ 2011-01-12 14:50         ` Sascha Hauer
  0 siblings, 0 replies; 118+ messages in thread
From: Sascha Hauer @ 2011-01-12 14:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jan 12, 2011 at 02:47:12PM +0800, Shawn Guo wrote:
> Hi Sascha,
> 
> On Tue, Jan 11, 2011 at 02:31:37PM +0100, Sascha Hauer wrote:
> > On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > > ---
> > > Changes for v4:
> > >  - Call cpu_relax() during polling
> > > 
> > > Changes for v2:
> > >  - Add mutex locking for mxs_read_ocotp()
> > >  - Use type size_t for count and i
> > >  - Add comment for clk_enable/disable skipping
> > >  - Add ERROR bit clearing and polling step
> > > 
> > >  arch/arm/mach-mxs/Makefile              |    2 +-
> > >  arch/arm/mach-mxs/include/mach/common.h |    1 +
> > >  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
> > >  3 files changed, 81 insertions(+), 1 deletions(-)
> > >  create mode 100644 arch/arm/mach-mxs/ocotp.c
> > > 
> > > diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> > > index 39d3f9c..f23ebbd 100644
> > > --- a/arch/arm/mach-mxs/Makefile
> > > +++ b/arch/arm/mach-mxs/Makefile
> > > @@ -1,5 +1,5 @@
> > >  # Common support
> > > -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> > > +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
> > >  
> > >  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
> > >  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
> > > diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> > > index 59133eb..cf02552 100644
> > > --- a/arch/arm/mach-mxs/include/mach/common.h
> > > +++ b/arch/arm/mach-mxs/include/mach/common.h
> > > @@ -13,6 +13,7 @@
> > >  
> > >  struct clk;
> > >  
> > > +extern int mxs_read_ocotp(int offset, int count, u32 *values);
> > >  extern int mxs_reset_block(void __iomem *);
> > >  extern void mxs_timer_init(struct clk *, int);
> > >  
> > > diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> > > new file mode 100644
> > > index 0000000..e2d39aa
> > > --- /dev/null
> > > +++ b/arch/arm/mach-mxs/ocotp.c
> > > @@ -0,0 +1,79 @@
> > > +/*
> > > + * Copyright 2010 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 as published by
> > > + * the Free Software Foundation; either version 2 of the License, or
> > > + * (at your option) any later version.
> > > + *
> > > + * This program is distributed in the hope that it will be useful,
> > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > > + * GNU General Public License for more details.
> > > + */
> > > +
> > > +#include <linux/delay.h>
> > > +#include <linux/err.h>
> > > +#include <linux/mutex.h>
> > > +
> > > +#include <mach/mxs.h>
> > > +
> > > +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> > > +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> > > +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> > > +
> > > +static DEFINE_MUTEX(ocotp_mutex);
> > > +
> > > +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> > > +{
> > > +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> > > +	int timeout = 0x400;
> > > +	size_t i;
> > > +
> > > +	mutex_lock(&ocotp_mutex);
> > > +
> > > +	/*
> > > +	 * clk_enable(hbus_clk) for ocotp can be skipped
> > > +	 * as it must be on when system is running.
> > > +	 */
> > > +
> > > +	/* try to clear ERROR bit */
> > > +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> > 
> > This operation does not try to clear the error bit but actually clears
> > it...
> > 
> > > +
> > > +	/* check both BUSY and ERROR cleared */
> > > +	while ((__raw_readl(ocotp_base) &
> > > +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> > > +		cpu_relax();
> > 
> > ...which means you do not have to poll the error bit here...
> > 
> > > +
> > > +	if (unlikely(!timeout))
> > > +		goto error_unlock;
> > > +
> > > +	/* open OCOTP banks for read */
> > > +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> > > +
> > > +	/* approximately wait 32 hclk cycles */
> > > +	udelay(1);
> > > +
> > > +	/* poll BUSY bit becoming cleared */
> > > +	timeout = 0x400;
> > > +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> > > +		cpu_relax();
> > 
> > ...which means you can factor out a ocotp_wait_busy function and let the
> > code speak instead of the comments.
> > 
> > > +
> > > +	if (unlikely(!timeout))
> > > +		goto error_unlock;
> > > +
> > > +	for (i = 0; i < count; i++, offset += 4)
> > > +		*values++ = __raw_readl(ocotp_base + offset);
> > 
> > The registers in the ocotp are 16 byte aligned. Does it really make
> > sense to provide a function allowing to read the gaps between the
> > registers?
> > 
> Good catch.  The count was added to ease the consecutive otp word
> reading, as there is bank open/close cost for otp read.  What about
> the following changes?
> 
> int mxs_read_ocotp(unsigned offset, size_t otp_word_cnt, u32 *values)
> {
> 	......
> 
> 	for (i = 0; i < otp_word_cnt; i++, offset += 0x10)
> 		*values++ = __raw_readl(ocotp_base + offset);
> 
> 	......
> }

I would rather make a function like this:

static u32 ocotp[0x27];

const u32 *mxs_get_ocotp(void)
{
	static int once = 0;

	if (once)
		return ocotp

	/* bank open */

	for (i = 0; i < 0x27; i++)
		ocotp[i] = readl(ocotp_base + 0x20 + i * 0x10)

	/* bank_close */

	once = 1;

	return ocotp;
}


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 08/10] ARM: mxs: add ocotp read function
  2011-01-12 14:50         ` Sascha Hauer
@ 2011-01-12 16:01           ` Uwe Kleine-König
  -1 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-12 16:01 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Shawn Guo, davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	lw, w.sang, jamie, jamie, netdev, linux-arm-kernel

Hello Sascha,

On Wed, Jan 12, 2011 at 03:50:36PM +0100, Sascha Hauer wrote:
> On Wed, Jan 12, 2011 at 02:47:12PM +0800, Shawn Guo wrote:
> > On Tue, Jan 11, 2011 at 02:31:37PM +0100, Sascha Hauer wrote:
> > > On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> > > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > > > ---
> > > > Changes for v4:
> > > >  - Call cpu_relax() during polling
> > > > 
> > > > Changes for v2:
> > > >  - Add mutex locking for mxs_read_ocotp()
> > > >  - Use type size_t for count and i
> > > >  - Add comment for clk_enable/disable skipping
> > > >  - Add ERROR bit clearing and polling step
> > > > 
> > > >  arch/arm/mach-mxs/Makefile              |    2 +-
> > > >  arch/arm/mach-mxs/include/mach/common.h |    1 +
> > > >  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
> > > >  3 files changed, 81 insertions(+), 1 deletions(-)
> > > >  create mode 100644 arch/arm/mach-mxs/ocotp.c
> > > > 
> > > > diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> > > > index 39d3f9c..f23ebbd 100644
> > > > --- a/arch/arm/mach-mxs/Makefile
> > > > +++ b/arch/arm/mach-mxs/Makefile
> > > > @@ -1,5 +1,5 @@
> > > >  # Common support
> > > > -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> > > > +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
> > > >  
> > > >  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
> > > >  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
> > > > diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> > > > index 59133eb..cf02552 100644
> > > > --- a/arch/arm/mach-mxs/include/mach/common.h
> > > > +++ b/arch/arm/mach-mxs/include/mach/common.h
> > > > @@ -13,6 +13,7 @@
> > > >  
> > > >  struct clk;
> > > >  
> > > > +extern int mxs_read_ocotp(int offset, int count, u32 *values);
> > > >  extern int mxs_reset_block(void __iomem *);
> > > >  extern void mxs_timer_init(struct clk *, int);
> > > >  
> > > > diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> > > > new file mode 100644
> > > > index 0000000..e2d39aa
> > > > --- /dev/null
> > > > +++ b/arch/arm/mach-mxs/ocotp.c
> > > > @@ -0,0 +1,79 @@
> > > > +/*
> > > > + * Copyright 2010 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 as published by
> > > > + * the Free Software Foundation; either version 2 of the License, or
> > > > + * (at your option) any later version.
> > > > + *
> > > > + * This program is distributed in the hope that it will be useful,
> > > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > > > + * GNU General Public License for more details.
> > > > + */
> > > > +
> > > > +#include <linux/delay.h>
> > > > +#include <linux/err.h>
> > > > +#include <linux/mutex.h>
> > > > +
> > > > +#include <mach/mxs.h>
> > > > +
> > > > +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> > > > +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> > > > +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> > > > +
> > > > +static DEFINE_MUTEX(ocotp_mutex);
> > > > +
> > > > +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> > > > +{
> > > > +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> > > > +	int timeout = 0x400;
> > > > +	size_t i;
> > > > +
> > > > +	mutex_lock(&ocotp_mutex);
> > > > +
> > > > +	/*
> > > > +	 * clk_enable(hbus_clk) for ocotp can be skipped
> > > > +	 * as it must be on when system is running.
> > > > +	 */
> > > > +
> > > > +	/* try to clear ERROR bit */
> > > > +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> > > 
> > > This operation does not try to clear the error bit but actually clears
> > > it...
> > > 
> > > > +
> > > > +	/* check both BUSY and ERROR cleared */
> > > > +	while ((__raw_readl(ocotp_base) &
> > > > +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> > > > +		cpu_relax();
> > > 
> > > ...which means you do not have to poll the error bit here...
> > > 
> > > > +
> > > > +	if (unlikely(!timeout))
> > > > +		goto error_unlock;
> > > > +
> > > > +	/* open OCOTP banks for read */
> > > > +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> > > > +
> > > > +	/* approximately wait 32 hclk cycles */
> > > > +	udelay(1);
> > > > +
> > > > +	/* poll BUSY bit becoming cleared */
> > > > +	timeout = 0x400;
> > > > +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> > > > +		cpu_relax();
> > > 
> > > ...which means you can factor out a ocotp_wait_busy function and let the
> > > code speak instead of the comments.
> > > 
> > > > +
> > > > +	if (unlikely(!timeout))
> > > > +		goto error_unlock;
> > > > +
> > > > +	for (i = 0; i < count; i++, offset += 4)
> > > > +		*values++ = __raw_readl(ocotp_base + offset);
> > > 
> > > The registers in the ocotp are 16 byte aligned. Does it really make
> > > sense to provide a function allowing to read the gaps between the
> > > registers?
> > > 
> > Good catch.  The count was added to ease the consecutive otp word
> > reading, as there is bank open/close cost for otp read.  What about
> > the following changes?
> > 
> > int mxs_read_ocotp(unsigned offset, size_t otp_word_cnt, u32 *values)
> > {
> > 	......
> > 
> > 	for (i = 0; i < otp_word_cnt; i++, offset += 0x10)
> > 		*values++ = __raw_readl(ocotp_base + offset);
> > 
> > 	......
> > }
> 
> I would rather make a function like this:
> 
> static u32 ocotp[0x27];
> 
> const u32 *mxs_get_ocotp(void)
> {
> 	static int once = 0;
> 
> 	if (once)
> 		return ocotp
> 
> 	/* bank open */
> 
> 	for (i = 0; i < 0x27; i++)
> 		ocotp[i] = readl(ocotp_base + 0x20 + i * 0x10)
> 
> 	/* bank_close */
> 
> 	once = 1;
> 
> 	return ocotp;
which is save on UP when it's not called from irq context.

Additionally I suggest a #define for 0x27 and 0x20.

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 08/10] ARM: mxs: add ocotp read function
@ 2011-01-12 16:01           ` Uwe Kleine-König
  0 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-12 16:01 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Sascha,

On Wed, Jan 12, 2011 at 03:50:36PM +0100, Sascha Hauer wrote:
> On Wed, Jan 12, 2011 at 02:47:12PM +0800, Shawn Guo wrote:
> > On Tue, Jan 11, 2011 at 02:31:37PM +0100, Sascha Hauer wrote:
> > > On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> > > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > > > ---
> > > > Changes for v4:
> > > >  - Call cpu_relax() during polling
> > > > 
> > > > Changes for v2:
> > > >  - Add mutex locking for mxs_read_ocotp()
> > > >  - Use type size_t for count and i
> > > >  - Add comment for clk_enable/disable skipping
> > > >  - Add ERROR bit clearing and polling step
> > > > 
> > > >  arch/arm/mach-mxs/Makefile              |    2 +-
> > > >  arch/arm/mach-mxs/include/mach/common.h |    1 +
> > > >  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
> > > >  3 files changed, 81 insertions(+), 1 deletions(-)
> > > >  create mode 100644 arch/arm/mach-mxs/ocotp.c
> > > > 
> > > > diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> > > > index 39d3f9c..f23ebbd 100644
> > > > --- a/arch/arm/mach-mxs/Makefile
> > > > +++ b/arch/arm/mach-mxs/Makefile
> > > > @@ -1,5 +1,5 @@
> > > >  # Common support
> > > > -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> > > > +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
> > > >  
> > > >  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
> > > >  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
> > > > diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> > > > index 59133eb..cf02552 100644
> > > > --- a/arch/arm/mach-mxs/include/mach/common.h
> > > > +++ b/arch/arm/mach-mxs/include/mach/common.h
> > > > @@ -13,6 +13,7 @@
> > > >  
> > > >  struct clk;
> > > >  
> > > > +extern int mxs_read_ocotp(int offset, int count, u32 *values);
> > > >  extern int mxs_reset_block(void __iomem *);
> > > >  extern void mxs_timer_init(struct clk *, int);
> > > >  
> > > > diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> > > > new file mode 100644
> > > > index 0000000..e2d39aa
> > > > --- /dev/null
> > > > +++ b/arch/arm/mach-mxs/ocotp.c
> > > > @@ -0,0 +1,79 @@
> > > > +/*
> > > > + * Copyright 2010 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 as published by
> > > > + * the Free Software Foundation; either version 2 of the License, or
> > > > + * (at your option) any later version.
> > > > + *
> > > > + * This program is distributed in the hope that it will be useful,
> > > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > > > + * GNU General Public License for more details.
> > > > + */
> > > > +
> > > > +#include <linux/delay.h>
> > > > +#include <linux/err.h>
> > > > +#include <linux/mutex.h>
> > > > +
> > > > +#include <mach/mxs.h>
> > > > +
> > > > +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> > > > +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> > > > +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> > > > +
> > > > +static DEFINE_MUTEX(ocotp_mutex);
> > > > +
> > > > +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> > > > +{
> > > > +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> > > > +	int timeout = 0x400;
> > > > +	size_t i;
> > > > +
> > > > +	mutex_lock(&ocotp_mutex);
> > > > +
> > > > +	/*
> > > > +	 * clk_enable(hbus_clk) for ocotp can be skipped
> > > > +	 * as it must be on when system is running.
> > > > +	 */
> > > > +
> > > > +	/* try to clear ERROR bit */
> > > > +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> > > 
> > > This operation does not try to clear the error bit but actually clears
> > > it...
> > > 
> > > > +
> > > > +	/* check both BUSY and ERROR cleared */
> > > > +	while ((__raw_readl(ocotp_base) &
> > > > +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> > > > +		cpu_relax();
> > > 
> > > ...which means you do not have to poll the error bit here...
> > > 
> > > > +
> > > > +	if (unlikely(!timeout))
> > > > +		goto error_unlock;
> > > > +
> > > > +	/* open OCOTP banks for read */
> > > > +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> > > > +
> > > > +	/* approximately wait 32 hclk cycles */
> > > > +	udelay(1);
> > > > +
> > > > +	/* poll BUSY bit becoming cleared */
> > > > +	timeout = 0x400;
> > > > +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> > > > +		cpu_relax();
> > > 
> > > ...which means you can factor out a ocotp_wait_busy function and let the
> > > code speak instead of the comments.
> > > 
> > > > +
> > > > +	if (unlikely(!timeout))
> > > > +		goto error_unlock;
> > > > +
> > > > +	for (i = 0; i < count; i++, offset += 4)
> > > > +		*values++ = __raw_readl(ocotp_base + offset);
> > > 
> > > The registers in the ocotp are 16 byte aligned. Does it really make
> > > sense to provide a function allowing to read the gaps between the
> > > registers?
> > > 
> > Good catch.  The count was added to ease the consecutive otp word
> > reading, as there is bank open/close cost for otp read.  What about
> > the following changes?
> > 
> > int mxs_read_ocotp(unsigned offset, size_t otp_word_cnt, u32 *values)
> > {
> > 	......
> > 
> > 	for (i = 0; i < otp_word_cnt; i++, offset += 0x10)
> > 		*values++ = __raw_readl(ocotp_base + offset);
> > 
> > 	......
> > }
> 
> I would rather make a function like this:
> 
> static u32 ocotp[0x27];
> 
> const u32 *mxs_get_ocotp(void)
> {
> 	static int once = 0;
> 
> 	if (once)
> 		return ocotp
> 
> 	/* bank open */
> 
> 	for (i = 0; i < 0x27; i++)
> 		ocotp[i] = readl(ocotp_base + 0x20 + i * 0x10)
> 
> 	/* bank_close */
> 
> 	once = 1;
> 
> 	return ocotp;
which is save on UP when it's not called from irq context.

Additionally I suggest a #define for 0x27 and 0x20.

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 08/10] ARM: mxs: add ocotp read function
  2011-01-12 16:01           ` Uwe Kleine-König
@ 2011-01-13  1:55             ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-13  1:55 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: Sascha Hauer, davem, gerg, baruch, eric, bryan.wu, r64343,
	B32542, lw, w.sang, jamie, jamie, netdev, linux-arm-kernel

On Wed, Jan 12, 2011 at 05:01:06PM +0100, Uwe Kleine-König wrote:
> Hello Sascha,
> 
> On Wed, Jan 12, 2011 at 03:50:36PM +0100, Sascha Hauer wrote:
> > On Wed, Jan 12, 2011 at 02:47:12PM +0800, Shawn Guo wrote:
> > > On Tue, Jan 11, 2011 at 02:31:37PM +0100, Sascha Hauer wrote:
> > > > On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> > > > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > > > > ---
> > > > > Changes for v4:
> > > > >  - Call cpu_relax() during polling
> > > > > 
> > > > > Changes for v2:
> > > > >  - Add mutex locking for mxs_read_ocotp()
> > > > >  - Use type size_t for count and i
> > > > >  - Add comment for clk_enable/disable skipping
> > > > >  - Add ERROR bit clearing and polling step
> > > > > 
> > > > >  arch/arm/mach-mxs/Makefile              |    2 +-
> > > > >  arch/arm/mach-mxs/include/mach/common.h |    1 +
> > > > >  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
> > > > >  3 files changed, 81 insertions(+), 1 deletions(-)
> > > > >  create mode 100644 arch/arm/mach-mxs/ocotp.c
> > > > > 
> > > > > diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> > > > > index 39d3f9c..f23ebbd 100644
> > > > > --- a/arch/arm/mach-mxs/Makefile
> > > > > +++ b/arch/arm/mach-mxs/Makefile
> > > > > @@ -1,5 +1,5 @@
> > > > >  # Common support
> > > > > -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> > > > > +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
> > > > >  
> > > > >  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
> > > > >  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
> > > > > diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> > > > > index 59133eb..cf02552 100644
> > > > > --- a/arch/arm/mach-mxs/include/mach/common.h
> > > > > +++ b/arch/arm/mach-mxs/include/mach/common.h
> > > > > @@ -13,6 +13,7 @@
> > > > >  
> > > > >  struct clk;
> > > > >  
> > > > > +extern int mxs_read_ocotp(int offset, int count, u32 *values);
> > > > >  extern int mxs_reset_block(void __iomem *);
> > > > >  extern void mxs_timer_init(struct clk *, int);
> > > > >  
> > > > > diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> > > > > new file mode 100644
> > > > > index 0000000..e2d39aa
> > > > > --- /dev/null
> > > > > +++ b/arch/arm/mach-mxs/ocotp.c
> > > > > @@ -0,0 +1,79 @@
> > > > > +/*
> > > > > + * Copyright 2010 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 as published by
> > > > > + * the Free Software Foundation; either version 2 of the License, or
> > > > > + * (at your option) any later version.
> > > > > + *
> > > > > + * This program is distributed in the hope that it will be useful,
> > > > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > > > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > > > > + * GNU General Public License for more details.
> > > > > + */
> > > > > +
> > > > > +#include <linux/delay.h>
> > > > > +#include <linux/err.h>
> > > > > +#include <linux/mutex.h>
> > > > > +
> > > > > +#include <mach/mxs.h>
> > > > > +
> > > > > +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> > > > > +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> > > > > +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> > > > > +
> > > > > +static DEFINE_MUTEX(ocotp_mutex);
> > > > > +
> > > > > +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> > > > > +{
> > > > > +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> > > > > +	int timeout = 0x400;
> > > > > +	size_t i;
> > > > > +
> > > > > +	mutex_lock(&ocotp_mutex);
> > > > > +
> > > > > +	/*
> > > > > +	 * clk_enable(hbus_clk) for ocotp can be skipped
> > > > > +	 * as it must be on when system is running.
> > > > > +	 */
> > > > > +
> > > > > +	/* try to clear ERROR bit */
> > > > > +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> > > > 
> > > > This operation does not try to clear the error bit but actually clears
> > > > it...
> > > > 
> > > > > +
> > > > > +	/* check both BUSY and ERROR cleared */
> > > > > +	while ((__raw_readl(ocotp_base) &
> > > > > +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> > > > > +		cpu_relax();
> > > > 
> > > > ...which means you do not have to poll the error bit here...
> > > > 
> > > > > +
> > > > > +	if (unlikely(!timeout))
> > > > > +		goto error_unlock;
> > > > > +
> > > > > +	/* open OCOTP banks for read */
> > > > > +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> > > > > +
> > > > > +	/* approximately wait 32 hclk cycles */
> > > > > +	udelay(1);
> > > > > +
> > > > > +	/* poll BUSY bit becoming cleared */
> > > > > +	timeout = 0x400;
> > > > > +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> > > > > +		cpu_relax();
> > > > 
> > > > ...which means you can factor out a ocotp_wait_busy function and let the
> > > > code speak instead of the comments.
> > > > 
> > > > > +
> > > > > +	if (unlikely(!timeout))
> > > > > +		goto error_unlock;
> > > > > +
> > > > > +	for (i = 0; i < count; i++, offset += 4)
> > > > > +		*values++ = __raw_readl(ocotp_base + offset);
> > > > 
> > > > The registers in the ocotp are 16 byte aligned. Does it really make
> > > > sense to provide a function allowing to read the gaps between the
> > > > registers?
> > > > 
> > > Good catch.  The count was added to ease the consecutive otp word
> > > reading, as there is bank open/close cost for otp read.  What about
> > > the following changes?
> > > 
> > > int mxs_read_ocotp(unsigned offset, size_t otp_word_cnt, u32 *values)
> > > {
> > > 	......
> > > 
> > > 	for (i = 0; i < otp_word_cnt; i++, offset += 0x10)
> > > 		*values++ = __raw_readl(ocotp_base + offset);
> > > 
> > > 	......
> > > }
> > 
> > I would rather make a function like this:
> > 
> > static u32 ocotp[0x27];
> > 
> > const u32 *mxs_get_ocotp(void)
> > {
> > 	static int once = 0;
> > 
> > 	if (once)
> > 		return ocotp
> > 
> > 	/* bank open */
> > 
> > 	for (i = 0; i < 0x27; i++)
> > 		ocotp[i] = readl(ocotp_base + 0x20 + i * 0x10)
> > 
> > 	/* bank_close */
> > 
> > 	once = 1;
> > 
> > 	return ocotp;
> which is save on UP when it's not called from irq context.
> 
> Additionally I suggest a #define for 0x27 and 0x20.
> 

So I will keep the mutex and not read SRK bits.

Thanks for the comments.

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 08/10] ARM: mxs: add ocotp read function
@ 2011-01-13  1:55             ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-13  1:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jan 12, 2011 at 05:01:06PM +0100, Uwe Kleine-K?nig wrote:
> Hello Sascha,
> 
> On Wed, Jan 12, 2011 at 03:50:36PM +0100, Sascha Hauer wrote:
> > On Wed, Jan 12, 2011 at 02:47:12PM +0800, Shawn Guo wrote:
> > > On Tue, Jan 11, 2011 at 02:31:37PM +0100, Sascha Hauer wrote:
> > > > On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> > > > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > > > > ---
> > > > > Changes for v4:
> > > > >  - Call cpu_relax() during polling
> > > > > 
> > > > > Changes for v2:
> > > > >  - Add mutex locking for mxs_read_ocotp()
> > > > >  - Use type size_t for count and i
> > > > >  - Add comment for clk_enable/disable skipping
> > > > >  - Add ERROR bit clearing and polling step
> > > > > 
> > > > >  arch/arm/mach-mxs/Makefile              |    2 +-
> > > > >  arch/arm/mach-mxs/include/mach/common.h |    1 +
> > > > >  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
> > > > >  3 files changed, 81 insertions(+), 1 deletions(-)
> > > > >  create mode 100644 arch/arm/mach-mxs/ocotp.c
> > > > > 
> > > > > diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> > > > > index 39d3f9c..f23ebbd 100644
> > > > > --- a/arch/arm/mach-mxs/Makefile
> > > > > +++ b/arch/arm/mach-mxs/Makefile
> > > > > @@ -1,5 +1,5 @@
> > > > >  # Common support
> > > > > -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> > > > > +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
> > > > >  
> > > > >  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
> > > > >  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
> > > > > diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> > > > > index 59133eb..cf02552 100644
> > > > > --- a/arch/arm/mach-mxs/include/mach/common.h
> > > > > +++ b/arch/arm/mach-mxs/include/mach/common.h
> > > > > @@ -13,6 +13,7 @@
> > > > >  
> > > > >  struct clk;
> > > > >  
> > > > > +extern int mxs_read_ocotp(int offset, int count, u32 *values);
> > > > >  extern int mxs_reset_block(void __iomem *);
> > > > >  extern void mxs_timer_init(struct clk *, int);
> > > > >  
> > > > > diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> > > > > new file mode 100644
> > > > > index 0000000..e2d39aa
> > > > > --- /dev/null
> > > > > +++ b/arch/arm/mach-mxs/ocotp.c
> > > > > @@ -0,0 +1,79 @@
> > > > > +/*
> > > > > + * Copyright 2010 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 as published by
> > > > > + * the Free Software Foundation; either version 2 of the License, or
> > > > > + * (at your option) any later version.
> > > > > + *
> > > > > + * This program is distributed in the hope that it will be useful,
> > > > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > > > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > > > > + * GNU General Public License for more details.
> > > > > + */
> > > > > +
> > > > > +#include <linux/delay.h>
> > > > > +#include <linux/err.h>
> > > > > +#include <linux/mutex.h>
> > > > > +
> > > > > +#include <mach/mxs.h>
> > > > > +
> > > > > +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> > > > > +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> > > > > +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> > > > > +
> > > > > +static DEFINE_MUTEX(ocotp_mutex);
> > > > > +
> > > > > +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> > > > > +{
> > > > > +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> > > > > +	int timeout = 0x400;
> > > > > +	size_t i;
> > > > > +
> > > > > +	mutex_lock(&ocotp_mutex);
> > > > > +
> > > > > +	/*
> > > > > +	 * clk_enable(hbus_clk) for ocotp can be skipped
> > > > > +	 * as it must be on when system is running.
> > > > > +	 */
> > > > > +
> > > > > +	/* try to clear ERROR bit */
> > > > > +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> > > > 
> > > > This operation does not try to clear the error bit but actually clears
> > > > it...
> > > > 
> > > > > +
> > > > > +	/* check both BUSY and ERROR cleared */
> > > > > +	while ((__raw_readl(ocotp_base) &
> > > > > +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> > > > > +		cpu_relax();
> > > > 
> > > > ...which means you do not have to poll the error bit here...
> > > > 
> > > > > +
> > > > > +	if (unlikely(!timeout))
> > > > > +		goto error_unlock;
> > > > > +
> > > > > +	/* open OCOTP banks for read */
> > > > > +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> > > > > +
> > > > > +	/* approximately wait 32 hclk cycles */
> > > > > +	udelay(1);
> > > > > +
> > > > > +	/* poll BUSY bit becoming cleared */
> > > > > +	timeout = 0x400;
> > > > > +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> > > > > +		cpu_relax();
> > > > 
> > > > ...which means you can factor out a ocotp_wait_busy function and let the
> > > > code speak instead of the comments.
> > > > 
> > > > > +
> > > > > +	if (unlikely(!timeout))
> > > > > +		goto error_unlock;
> > > > > +
> > > > > +	for (i = 0; i < count; i++, offset += 4)
> > > > > +		*values++ = __raw_readl(ocotp_base + offset);
> > > > 
> > > > The registers in the ocotp are 16 byte aligned. Does it really make
> > > > sense to provide a function allowing to read the gaps between the
> > > > registers?
> > > > 
> > > Good catch.  The count was added to ease the consecutive otp word
> > > reading, as there is bank open/close cost for otp read.  What about
> > > the following changes?
> > > 
> > > int mxs_read_ocotp(unsigned offset, size_t otp_word_cnt, u32 *values)
> > > {
> > > 	......
> > > 
> > > 	for (i = 0; i < otp_word_cnt; i++, offset += 0x10)
> > > 		*values++ = __raw_readl(ocotp_base + offset);
> > > 
> > > 	......
> > > }
> > 
> > I would rather make a function like this:
> > 
> > static u32 ocotp[0x27];
> > 
> > const u32 *mxs_get_ocotp(void)
> > {
> > 	static int once = 0;
> > 
> > 	if (once)
> > 		return ocotp
> > 
> > 	/* bank open */
> > 
> > 	for (i = 0; i < 0x27; i++)
> > 		ocotp[i] = readl(ocotp_base + 0x20 + i * 0x10)
> > 
> > 	/* bank_close */
> > 
> > 	once = 1;
> > 
> > 	return ocotp;
> which is save on UP when it's not called from irq context.
> 
> Additionally I suggest a #define for 0x27 and 0x20.
> 

So I will keep the mutex and not read SRK bits.

Thanks for the comments.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 05/10] net/fec: add dual fec support for mx28
  2011-01-06  7:13   ` Shawn Guo
@ 2011-01-13 14:48     ` Uwe Kleine-König
  -1 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-13 14:48 UTC (permalink / raw)
  To: Shawn Guo
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw, w.sang,
	s.hauer, jamie, jamie, netdev, linux-arm-kernel

Hello,

hmm, this review comes to late, probably I will post a follow-up patch
for the low-hanging fruits at least.

On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
> This patch is to add mx28 dual fec support. Here are some key notes
> for mx28 fec controller.
> 
>  - The mx28 fec controller naming ENET-MAC is a different IP from FEC
>    used on other i.mx variants.  But they are basically compatible
>    on software interface, so it's possible to share the same driver.
>  - ENET-MAC design on mx28 made an improper assumption that it runs
>    on a big-endian system. As the result, driver has to swap every
>    frame going to and coming from the controller.
>  - The external phys can only be configured by fec0, which means fec1
>    can not work independently and both phys need to be configured by
>    mii_bus attached on fec0.
>  - ENET-MAC reset will get mac address registers reset too.
>  - ENET-MAC MII/RMII mode and 10M/100M speed are configured
>    differently FEC.
>  - ETHER_EN bit must be set to get ENET-MAC interrupt work.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v4:
>  - Use #ifndef CONFIG_ARM to include ColdFire header files
I intended you to not use CONFIG_ARCH_MXS at all, at least up to now
CONFIG_ARM works quite well.

>  - Define quirk bits in id_entry.driver_data to handle controller
>    difference, which is more scalable than using device name
>  - Define fec0_mii_bus as a static function in fec_enet_mii_init
>    to fold the mii_bus instance attached on fec0
IMHO not very good.  At least the current code doesn't allow to have two
dual-fecs, because the 2nd dual-fec's slave would be attached to the 1st
dual-fec's mii_bus.  Don't know a nice solution though.  Probably you
either need a slave pointer in platform_data or have to treat a dual-fec
as only a single device.

>  - Use cpu_to_be32 over __swab32 in function swap_buffer
> 
> Changes for v3:
>  - Move v2 changes into patch #3
>  - Use device name to check if it's running on ENET-MAC
> 
>  drivers/net/Kconfig |    7 ++-
>  drivers/net/fec.c   |  148 +++++++++++++++++++++++++++++++++++++++++++++------
>  drivers/net/fec.h   |    5 +-
>  3 files changed, 139 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 4f1755b..f34629b 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -1944,18 +1944,19 @@ config 68360_ENET
>  config FEC
>  	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
>  	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
> -		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
> +		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC ?  Again this calls for a
more global approach for these registration facilities.

>  	select PHYLIB
>  	help
>  	  Say Y here if you want to use the built-in 10/100 Fast ethernet
>  	  controller on some Motorola ColdFire and Freescale i.MX processors.
>  
>  config FEC2
> -	bool "Second FEC ethernet controller (on some ColdFire CPUs)"
> +	bool "Second FEC ethernet controller"
>  	depends on FEC
>  	help
>  	  Say Y here if you want to use the second built-in 10/100 Fast
> -	  ethernet controller on some Motorola ColdFire processors.
> +	  ethernet controller on some Motorola ColdFire and Freescale
> +	  i.MX processors.
>  
>  config FEC_MPC52xx
>  	tristate "MPC52xx FEC driver"
> diff --git a/drivers/net/fec.c b/drivers/net/fec.c
> index 8a1c51f..2a71373 100644
> --- a/drivers/net/fec.c
> +++ b/drivers/net/fec.c
> @@ -17,6 +17,8 @@
>   *
>   * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
>   * Copyright (c) 2004-2006 Macq Electronique SA.
> + *
> + * Copyright (C) 2010 Freescale Semiconductor, Inc.
>   */
>  
>  #include <linux/module.h>
> @@ -45,20 +47,36 @@
>  
>  #include <asm/cacheflush.h>
>  
> -#ifndef CONFIG_ARCH_MXC
> +#ifndef CONFIG_ARM
>  #include <asm/coldfire.h>
>  #include <asm/mcfsim.h>
>  #endif
>  
>  #include "fec.h"
>  
> -#ifdef CONFIG_ARCH_MXC
> -#include <mach/hardware.h>
> +#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
>  #define FEC_ALIGNMENT	0xf
>  #else
>  #define FEC_ALIGNMENT	0x3
>  #endif
>  
> +#define DRIVER_NAME	"fec"
> +
> +/* Controller is ENET-MAC */
> +#define FEC_QUIRK_ENET_MAC		(1 << 0)
does this really qualify to be a quirk?

> +/* Controller needs driver to swap frame */
> +#define FEC_QUIRK_SWAP_FRAME		(1 << 1)
IMHO this is a bit misnamed.  FEC_QUIRK_NEEDS_BE_DATA or similar would
be more accurate.

> +static struct platform_device_id fec_devtype[] = {
> +	{
> +		.name = DRIVER_NAME,
> +		.driver_data = 0,
> +	}, {
> +		.name = "imx28-fec",
> +		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME,
> +	}
> +};
> +
>  static unsigned char macaddr[ETH_ALEN];
>  module_param_array(macaddr, byte, NULL, 0);
>  MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
> @@ -129,7 +147,8 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
>   * account when setting it.
>   */
>  #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
> -    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
> +    defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
> +    defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
I wonder what is excluded here.  FEC depends on

	M523x || M527x || M5272 || M528x || M520x || M532x || \
	MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28

so the only difference is that the latter lists M5272 which seems a bit
redundant in the presence of M527x.

>  #define	OPT_FRAME_SIZE	(PKT_MAXBUF_SIZE << 16)
>  #else
>  #define	OPT_FRAME_SIZE	0
> @@ -208,10 +227,23 @@ static void fec_stop(struct net_device *dev);
>  /* Transmitter timeout */
>  #define TX_TIMEOUT (2 * HZ)
>  
> +static void *swap_buffer(void *bufaddr, int len)
> +{
> +	int i;
> +	unsigned int *buf = bufaddr;
> +
> +	for (i = 0; i < (len + 3) / 4; i++, buf++)
> +		*buf = cpu_to_be32(*buf);
if len isn't a multiple of 4 this accesses bytes behind len.  Is this
generally OK here?  (E.g. because skbs always have a length that is a
multiple of 4?)
> +
> +	return bufaddr;
> +}
> +
>  static netdev_tx_t
>  fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  {
>  	struct fec_enet_private *fep = netdev_priv(dev);
> +	const struct platform_device_id *id_entry =
> +				platform_get_device_id(fep->pdev);
>  	struct bufdesc *bdp;
>  	void *bufaddr;
>  	unsigned short	status;
> @@ -256,6 +288,14 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  		bufaddr = fep->tx_bounce[index];
>  	}
>  
> +	/*
> +	 * Some design made an incorrect assumption on endian mode of
> +	 * the system that it's running on. As the result, driver has to
> +	 * swap every frame going to and coming from the controller.
> +	 */
> +	if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
> +		swap_buffer(bufaddr, skb->len);
> +
>  	/* Save skb pointer */
>  	fep->tx_skbuff[fep->skb_cur] = skb;
>  
> @@ -424,6 +464,8 @@ static void
>  fec_enet_rx(struct net_device *dev)
>  {
>  	struct	fec_enet_private *fep = netdev_priv(dev);
> +	const struct platform_device_id *id_entry =
> +				platform_get_device_id(fep->pdev);
>  	struct bufdesc *bdp;
>  	unsigned short status;
>  	struct	sk_buff	*skb;
> @@ -487,6 +529,9 @@ fec_enet_rx(struct net_device *dev)
>  	        dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
>          			DMA_FROM_DEVICE);
>  
> +		if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
> +			swap_buffer(data, pkt_len);
> +
>  		/* This does 16 byte alignment, exactly what we need.
>  		 * The packet length includes FCS, but we don't want to
>  		 * include that when passing upstream as it messes up
> @@ -689,6 +734,7 @@ static int fec_enet_mii_probe(struct net_device *dev)
>  	char mdio_bus_id[MII_BUS_ID_SIZE];
>  	char phy_name[MII_BUS_ID_SIZE + 3];
>  	int phy_id;
> +	int dev_id = fep->pdev->id;
>  
>  	fep->phy_dev = NULL;
>  
> @@ -700,6 +746,8 @@ static int fec_enet_mii_probe(struct net_device *dev)
>  			continue;
>  		if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
>  			continue;
> +		if (dev_id--)
> +			continue;
>  		strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);
>  		break;
>  	}
> @@ -737,10 +785,35 @@ static int fec_enet_mii_probe(struct net_device *dev)
>  
>  static int fec_enet_mii_init(struct platform_device *pdev)
>  {
> +	static struct mii_bus *fec0_mii_bus;
>  	struct net_device *dev = platform_get_drvdata(pdev);
>  	struct fec_enet_private *fep = netdev_priv(dev);
> +	const struct platform_device_id *id_entry =
> +				platform_get_device_id(fep->pdev);
>  	int err = -ENXIO, i;
>  
> +	/*
> +	 * The dual fec interfaces are not equivalent with enet-mac.
> +	 * Here are the differences:
> +	 *
> +	 *  - fec0 supports MII & RMII modes while fec1 only supports RMII
> +	 *  - fec0 acts as the 1588 time master while fec1 is slave
> +	 *  - external phys can only be configured by fec0
> +	 *
> +	 * That is to say fec1 can not work independently. It only works
> +	 * when fec0 is working. The reason behind this design is that the
> +	 * second interface is added primarily for Switch mode.
> +	 *
> +	 * Because of the last point above, both phys are attached on fec0
> +	 * mdio interface in board design, and need to be configured by
> +	 * fec0 mii_bus.
> +	 */
> +	if ((id_entry->driver_data & FEC_QUIRK_ENET_MAC) && pdev->id) {
> +		/* fec1 uses fec0 mii_bus */
> +		fep->mii_bus = fec0_mii_bus;
> +		return 0;
What happens if imx28-fec.1 is probed before imx28-fec.0?
> +	}
> +
>  	fep->mii_timeout = 0;
>  
>  	/*
> @@ -777,6 +850,10 @@ static int fec_enet_mii_init(struct platform_device *pdev)
>  	if (mdiobus_register(fep->mii_bus))
>  		goto err_out_free_mdio_irq;
>  
> +	/* save fec0 mii_bus */
> +	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
> +		fec0_mii_bus = fep->mii_bus;
> +
>  	return 0;
>  
>  err_out_free_mdio_irq:
> @@ -1148,12 +1225,25 @@ static void
>  fec_restart(struct net_device *dev, int duplex)
>  {
>  	struct fec_enet_private *fep = netdev_priv(dev);
> +	const struct platform_device_id *id_entry =
> +				platform_get_device_id(fep->pdev);
>  	int i;
> +	u32 val, temp_mac[2];
>  
>  	/* Whack a reset.  We should wait for this. */
>  	writel(1, fep->hwp + FEC_ECNTRL);
>  	udelay(10);
>  
> +	/*
> +	 * enet-mac reset will reset mac address registers too,
> +	 * so need to reconfigure it.
> +	 */
> +	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
> +		memcpy(&temp_mac, dev->dev_addr, ETH_ALEN);
> +		writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW);
> +		writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH);
> +	}
> +
>  	/* Clear any outstanding interrupt. */
>  	writel(0xffc00000, fep->hwp + FEC_IEVENT);
>  
> @@ -1200,20 +1290,45 @@ fec_restart(struct net_device *dev, int duplex)
>  	/* Set MII speed */
>  	writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
>  
> -#ifdef FEC_MIIGSK_ENR
> -	if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
> -		/* disable the gasket and wait */
> -		writel(0, fep->hwp + FEC_MIIGSK_ENR);
> -		while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
> -			udelay(1);
> +	/*
> +	 * The phy interface and speed need to get configured
> +	 * differently on enet-mac.
> +	 */
> +	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
> +		val = readl(fep->hwp + FEC_R_CNTRL);
>  
> -		/* configure the gasket: RMII, 50 MHz, no loopback, no echo */
> -		writel(1, fep->hwp + FEC_MIIGSK_CFGR);
> +		/* MII or RMII */
> +		if (fep->phy_interface == PHY_INTERFACE_MODE_RMII)
> +			val |= (1 << 8);
Can we have a #define for 1 << 8 please?

> +		else
> +			val &= ~(1 << 8);

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
@ 2011-01-13 14:48     ` Uwe Kleine-König
  0 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-13 14:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

hmm, this review comes to late, probably I will post a follow-up patch
for the low-hanging fruits at least.

On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
> This patch is to add mx28 dual fec support. Here are some key notes
> for mx28 fec controller.
> 
>  - The mx28 fec controller naming ENET-MAC is a different IP from FEC
>    used on other i.mx variants.  But they are basically compatible
>    on software interface, so it's possible to share the same driver.
>  - ENET-MAC design on mx28 made an improper assumption that it runs
>    on a big-endian system. As the result, driver has to swap every
>    frame going to and coming from the controller.
>  - The external phys can only be configured by fec0, which means fec1
>    can not work independently and both phys need to be configured by
>    mii_bus attached on fec0.
>  - ENET-MAC reset will get mac address registers reset too.
>  - ENET-MAC MII/RMII mode and 10M/100M speed are configured
>    differently FEC.
>  - ETHER_EN bit must be set to get ENET-MAC interrupt work.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v4:
>  - Use #ifndef CONFIG_ARM to include ColdFire header files
I intended you to not use CONFIG_ARCH_MXS at all, at least up to now
CONFIG_ARM works quite well.

>  - Define quirk bits in id_entry.driver_data to handle controller
>    difference, which is more scalable than using device name
>  - Define fec0_mii_bus as a static function in fec_enet_mii_init
>    to fold the mii_bus instance attached on fec0
IMHO not very good.  At least the current code doesn't allow to have two
dual-fecs, because the 2nd dual-fec's slave would be attached to the 1st
dual-fec's mii_bus.  Don't know a nice solution though.  Probably you
either need a slave pointer in platform_data or have to treat a dual-fec
as only a single device.

>  - Use cpu_to_be32 over __swab32 in function swap_buffer
> 
> Changes for v3:
>  - Move v2 changes into patch #3
>  - Use device name to check if it's running on ENET-MAC
> 
>  drivers/net/Kconfig |    7 ++-
>  drivers/net/fec.c   |  148 +++++++++++++++++++++++++++++++++++++++++++++------
>  drivers/net/fec.h   |    5 +-
>  3 files changed, 139 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 4f1755b..f34629b 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -1944,18 +1944,19 @@ config 68360_ENET
>  config FEC
>  	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
>  	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
> -		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
> +		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC ?  Again this calls for a
more global approach for these registration facilities.

>  	select PHYLIB
>  	help
>  	  Say Y here if you want to use the built-in 10/100 Fast ethernet
>  	  controller on some Motorola ColdFire and Freescale i.MX processors.
>  
>  config FEC2
> -	bool "Second FEC ethernet controller (on some ColdFire CPUs)"
> +	bool "Second FEC ethernet controller"
>  	depends on FEC
>  	help
>  	  Say Y here if you want to use the second built-in 10/100 Fast
> -	  ethernet controller on some Motorola ColdFire processors.
> +	  ethernet controller on some Motorola ColdFire and Freescale
> +	  i.MX processors.
>  
>  config FEC_MPC52xx
>  	tristate "MPC52xx FEC driver"
> diff --git a/drivers/net/fec.c b/drivers/net/fec.c
> index 8a1c51f..2a71373 100644
> --- a/drivers/net/fec.c
> +++ b/drivers/net/fec.c
> @@ -17,6 +17,8 @@
>   *
>   * Bug fixes and cleanup by Philippe De Muyter (phdm at macqel.be)
>   * Copyright (c) 2004-2006 Macq Electronique SA.
> + *
> + * Copyright (C) 2010 Freescale Semiconductor, Inc.
>   */
>  
>  #include <linux/module.h>
> @@ -45,20 +47,36 @@
>  
>  #include <asm/cacheflush.h>
>  
> -#ifndef CONFIG_ARCH_MXC
> +#ifndef CONFIG_ARM
>  #include <asm/coldfire.h>
>  #include <asm/mcfsim.h>
>  #endif
>  
>  #include "fec.h"
>  
> -#ifdef CONFIG_ARCH_MXC
> -#include <mach/hardware.h>
> +#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
>  #define FEC_ALIGNMENT	0xf
>  #else
>  #define FEC_ALIGNMENT	0x3
>  #endif
>  
> +#define DRIVER_NAME	"fec"
> +
> +/* Controller is ENET-MAC */
> +#define FEC_QUIRK_ENET_MAC		(1 << 0)
does this really qualify to be a quirk?

> +/* Controller needs driver to swap frame */
> +#define FEC_QUIRK_SWAP_FRAME		(1 << 1)
IMHO this is a bit misnamed.  FEC_QUIRK_NEEDS_BE_DATA or similar would
be more accurate.

> +static struct platform_device_id fec_devtype[] = {
> +	{
> +		.name = DRIVER_NAME,
> +		.driver_data = 0,
> +	}, {
> +		.name = "imx28-fec",
> +		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME,
> +	}
> +};
> +
>  static unsigned char macaddr[ETH_ALEN];
>  module_param_array(macaddr, byte, NULL, 0);
>  MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
> @@ -129,7 +147,8 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
>   * account when setting it.
>   */
>  #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
> -    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
> +    defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
> +    defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
I wonder what is excluded here.  FEC depends on

	M523x || M527x || M5272 || M528x || M520x || M532x || \
	MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28

so the only difference is that the latter lists M5272 which seems a bit
redundant in the presence of M527x.

>  #define	OPT_FRAME_SIZE	(PKT_MAXBUF_SIZE << 16)
>  #else
>  #define	OPT_FRAME_SIZE	0
> @@ -208,10 +227,23 @@ static void fec_stop(struct net_device *dev);
>  /* Transmitter timeout */
>  #define TX_TIMEOUT (2 * HZ)
>  
> +static void *swap_buffer(void *bufaddr, int len)
> +{
> +	int i;
> +	unsigned int *buf = bufaddr;
> +
> +	for (i = 0; i < (len + 3) / 4; i++, buf++)
> +		*buf = cpu_to_be32(*buf);
if len isn't a multiple of 4 this accesses bytes behind len.  Is this
generally OK here?  (E.g. because skbs always have a length that is a
multiple of 4?)
> +
> +	return bufaddr;
> +}
> +
>  static netdev_tx_t
>  fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  {
>  	struct fec_enet_private *fep = netdev_priv(dev);
> +	const struct platform_device_id *id_entry =
> +				platform_get_device_id(fep->pdev);
>  	struct bufdesc *bdp;
>  	void *bufaddr;
>  	unsigned short	status;
> @@ -256,6 +288,14 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  		bufaddr = fep->tx_bounce[index];
>  	}
>  
> +	/*
> +	 * Some design made an incorrect assumption on endian mode of
> +	 * the system that it's running on. As the result, driver has to
> +	 * swap every frame going to and coming from the controller.
> +	 */
> +	if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
> +		swap_buffer(bufaddr, skb->len);
> +
>  	/* Save skb pointer */
>  	fep->tx_skbuff[fep->skb_cur] = skb;
>  
> @@ -424,6 +464,8 @@ static void
>  fec_enet_rx(struct net_device *dev)
>  {
>  	struct	fec_enet_private *fep = netdev_priv(dev);
> +	const struct platform_device_id *id_entry =
> +				platform_get_device_id(fep->pdev);
>  	struct bufdesc *bdp;
>  	unsigned short status;
>  	struct	sk_buff	*skb;
> @@ -487,6 +529,9 @@ fec_enet_rx(struct net_device *dev)
>  	        dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
>          			DMA_FROM_DEVICE);
>  
> +		if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
> +			swap_buffer(data, pkt_len);
> +
>  		/* This does 16 byte alignment, exactly what we need.
>  		 * The packet length includes FCS, but we don't want to
>  		 * include that when passing upstream as it messes up
> @@ -689,6 +734,7 @@ static int fec_enet_mii_probe(struct net_device *dev)
>  	char mdio_bus_id[MII_BUS_ID_SIZE];
>  	char phy_name[MII_BUS_ID_SIZE + 3];
>  	int phy_id;
> +	int dev_id = fep->pdev->id;
>  
>  	fep->phy_dev = NULL;
>  
> @@ -700,6 +746,8 @@ static int fec_enet_mii_probe(struct net_device *dev)
>  			continue;
>  		if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
>  			continue;
> +		if (dev_id--)
> +			continue;
>  		strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);
>  		break;
>  	}
> @@ -737,10 +785,35 @@ static int fec_enet_mii_probe(struct net_device *dev)
>  
>  static int fec_enet_mii_init(struct platform_device *pdev)
>  {
> +	static struct mii_bus *fec0_mii_bus;
>  	struct net_device *dev = platform_get_drvdata(pdev);
>  	struct fec_enet_private *fep = netdev_priv(dev);
> +	const struct platform_device_id *id_entry =
> +				platform_get_device_id(fep->pdev);
>  	int err = -ENXIO, i;
>  
> +	/*
> +	 * The dual fec interfaces are not equivalent with enet-mac.
> +	 * Here are the differences:
> +	 *
> +	 *  - fec0 supports MII & RMII modes while fec1 only supports RMII
> +	 *  - fec0 acts as the 1588 time master while fec1 is slave
> +	 *  - external phys can only be configured by fec0
> +	 *
> +	 * That is to say fec1 can not work independently. It only works
> +	 * when fec0 is working. The reason behind this design is that the
> +	 * second interface is added primarily for Switch mode.
> +	 *
> +	 * Because of the last point above, both phys are attached on fec0
> +	 * mdio interface in board design, and need to be configured by
> +	 * fec0 mii_bus.
> +	 */
> +	if ((id_entry->driver_data & FEC_QUIRK_ENET_MAC) && pdev->id) {
> +		/* fec1 uses fec0 mii_bus */
> +		fep->mii_bus = fec0_mii_bus;
> +		return 0;
What happens if imx28-fec.1 is probed before imx28-fec.0?
> +	}
> +
>  	fep->mii_timeout = 0;
>  
>  	/*
> @@ -777,6 +850,10 @@ static int fec_enet_mii_init(struct platform_device *pdev)
>  	if (mdiobus_register(fep->mii_bus))
>  		goto err_out_free_mdio_irq;
>  
> +	/* save fec0 mii_bus */
> +	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
> +		fec0_mii_bus = fep->mii_bus;
> +
>  	return 0;
>  
>  err_out_free_mdio_irq:
> @@ -1148,12 +1225,25 @@ static void
>  fec_restart(struct net_device *dev, int duplex)
>  {
>  	struct fec_enet_private *fep = netdev_priv(dev);
> +	const struct platform_device_id *id_entry =
> +				platform_get_device_id(fep->pdev);
>  	int i;
> +	u32 val, temp_mac[2];
>  
>  	/* Whack a reset.  We should wait for this. */
>  	writel(1, fep->hwp + FEC_ECNTRL);
>  	udelay(10);
>  
> +	/*
> +	 * enet-mac reset will reset mac address registers too,
> +	 * so need to reconfigure it.
> +	 */
> +	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
> +		memcpy(&temp_mac, dev->dev_addr, ETH_ALEN);
> +		writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW);
> +		writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH);
> +	}
> +
>  	/* Clear any outstanding interrupt. */
>  	writel(0xffc00000, fep->hwp + FEC_IEVENT);
>  
> @@ -1200,20 +1290,45 @@ fec_restart(struct net_device *dev, int duplex)
>  	/* Set MII speed */
>  	writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
>  
> -#ifdef FEC_MIIGSK_ENR
> -	if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
> -		/* disable the gasket and wait */
> -		writel(0, fep->hwp + FEC_MIIGSK_ENR);
> -		while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
> -			udelay(1);
> +	/*
> +	 * The phy interface and speed need to get configured
> +	 * differently on enet-mac.
> +	 */
> +	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
> +		val = readl(fep->hwp + FEC_R_CNTRL);
>  
> -		/* configure the gasket: RMII, 50 MHz, no loopback, no echo */
> -		writel(1, fep->hwp + FEC_MIIGSK_CFGR);
> +		/* MII or RMII */
> +		if (fep->phy_interface == PHY_INTERFACE_MODE_RMII)
> +			val |= (1 << 8);
Can we have a #define for 1 << 8 please?

> +		else
> +			val &= ~(1 << 8);

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v5] ARM: mx28: add the second fec device registration
  2011-01-11 12:09   ` Shawn Guo
@ 2011-01-13 14:49     ` Uwe Kleine-König
  -1 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-13 14:49 UTC (permalink / raw)
  To: Shawn Guo
  Cc: s.hauer, davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw,
	w.sang, jamie, jamie, netdev, linux-arm-kernel

On Tue, Jan 11, 2011 at 08:09:24PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v5:
>  - Do not use CONFIG_FEC2 which is a fec driver configration
> 
>  arch/arm/mach-mxs/mach-mx28evk.c |   26 +++++++++++++++++++++++---
>  1 files changed, 23 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
> index d162e95..8e2c597 100644
> --- a/arch/arm/mach-mxs/mach-mx28evk.c
> +++ b/arch/arm/mach-mxs/mach-mx28evk.c
> @@ -57,6 +57,19 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
>  		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
>  	MX28_PAD_ENET_CLK__CLKCTRL_ENET |
>  		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	/* fec1 */
> +	MX28_PAD_ENET0_CRS__ENET1_RX_EN |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	MX28_PAD_ENET0_RXD2__ENET1_RXD0 |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	MX28_PAD_ENET0_RXD3__ENET1_RXD1 |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	MX28_PAD_ENET0_COL__ENET1_TX_EN |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	MX28_PAD_ENET0_TXD2__ENET1_TXD0 |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	MX28_PAD_ENET0_TXD3__ENET1_TXD1 |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
>  	/* phy power line */
>  	MX28_PAD_SSP1_DATA3__GPIO_2_15 |
>  		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
> @@ -106,8 +119,14 @@ static void __init mx28evk_fec_reset(void)
>  	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
>  }
>  
> -static const struct fec_platform_data mx28_fec_pdata __initconst = {
> -	.phy = PHY_INTERFACE_MODE_RMII,
> +static struct fec_platform_data mx28_fec_pdata[] = {
this can still be initdata, doesn't it?

> +	{
> +		/* fec0 */
> +		.phy = PHY_INTERFACE_MODE_RMII,
> +	}, {
> +		/* fec1 */
> +		.phy = PHY_INTERFACE_MODE_RMII,
> +	},
>  };
>  
>  static void __init mx28evk_init(void)
> @@ -117,7 +136,8 @@ static void __init mx28evk_init(void)
>  	mx28_add_duart();
>  
>  	mx28evk_fec_reset();
> -	mx28_add_fec(0, &mx28_fec_pdata);
> +	mx28_add_fec(0, &mx28_fec_pdata[0]);
> +	mx28_add_fec(1, &mx28_fec_pdata[1]);
>  }
>  
>  static void __init mx28evk_timer_init(void)
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v5] ARM: mx28: add the second fec device registration
@ 2011-01-13 14:49     ` Uwe Kleine-König
  0 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-13 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 11, 2011 at 08:09:24PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v5:
>  - Do not use CONFIG_FEC2 which is a fec driver configration
> 
>  arch/arm/mach-mxs/mach-mx28evk.c |   26 +++++++++++++++++++++++---
>  1 files changed, 23 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
> index d162e95..8e2c597 100644
> --- a/arch/arm/mach-mxs/mach-mx28evk.c
> +++ b/arch/arm/mach-mxs/mach-mx28evk.c
> @@ -57,6 +57,19 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
>  		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
>  	MX28_PAD_ENET_CLK__CLKCTRL_ENET |
>  		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	/* fec1 */
> +	MX28_PAD_ENET0_CRS__ENET1_RX_EN |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	MX28_PAD_ENET0_RXD2__ENET1_RXD0 |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	MX28_PAD_ENET0_RXD3__ENET1_RXD1 |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	MX28_PAD_ENET0_COL__ENET1_TX_EN |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	MX28_PAD_ENET0_TXD2__ENET1_TXD0 |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	MX28_PAD_ENET0_TXD3__ENET1_TXD1 |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
>  	/* phy power line */
>  	MX28_PAD_SSP1_DATA3__GPIO_2_15 |
>  		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
> @@ -106,8 +119,14 @@ static void __init mx28evk_fec_reset(void)
>  	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
>  }
>  
> -static const struct fec_platform_data mx28_fec_pdata __initconst = {
> -	.phy = PHY_INTERFACE_MODE_RMII,
> +static struct fec_platform_data mx28_fec_pdata[] = {
this can still be initdata, doesn't it?

> +	{
> +		/* fec0 */
> +		.phy = PHY_INTERFACE_MODE_RMII,
> +	}, {
> +		/* fec1 */
> +		.phy = PHY_INTERFACE_MODE_RMII,
> +	},
>  };
>  
>  static void __init mx28evk_init(void)
> @@ -117,7 +136,8 @@ static void __init mx28evk_init(void)
>  	mx28_add_duart();
>  
>  	mx28evk_fec_reset();
> -	mx28_add_fec(0, &mx28_fec_pdata);
> +	mx28_add_fec(0, &mx28_fec_pdata[0]);
> +	mx28_add_fec(1, &mx28_fec_pdata[1]);
>  }
>  
>  static void __init mx28evk_timer_init(void)
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 09/10] ARM: mx28: read fec mac address from ocotp
  2011-01-06  7:13   ` Shawn Guo
@ 2011-01-13 14:50     ` Uwe Kleine-König
  -1 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-13 14:50 UTC (permalink / raw)
  To: Shawn Guo
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw, w.sang,
	s.hauer, jamie, jamie, netdev, linux-arm-kernel

Hello Shawn,

$SUBJECT ~= s,mx28,mxs/mx28evk, please

On Thu, Jan 06, 2011 at 03:13:17PM +0800, Shawn Guo wrote:
> Read fec mac address from ocotp and save it into fec_platform_data
> mac field for fec driver to use.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
>  - It's not necessary to remove "const" for fec_platform_data from
>    platform-fec.c and devices-common.h, so add it back.
>  - Hard-coding Freescale OUI (00:04:9f) instead of just the first
>    two two octets.
>  - Correct the return of mx28evk_fec_get_mac() and check it
>    with caller
> 
>  arch/arm/mach-mxs/mach-mx28evk.c |   32 ++++++++++++++++++++++++++++++++
>  1 files changed, 32 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
> index def6519..54fa512 100644
> --- a/arch/arm/mach-mxs/mach-mx28evk.c
> +++ b/arch/arm/mach-mxs/mach-mx28evk.c
> @@ -129,12 +129,44 @@ static struct fec_platform_data mx28_fec_pdata[] = {
>  	},
>  };
>  
> +static int __init mx28evk_fec_get_mac(void)
> +{
> +	int i, ret;
> +	u32 val;
> +
> +	/*
> +	 * OCOTP only stores the last 4 octets for each mac address,
> +	 * so hard-code Freescale OUI (00:04:9f) here.
> +	 */
> +	for (i = 0; i < 2; i++) {
> +		ret = mxs_read_ocotp(0x20 + i * 0x10, 1, &val);
> +		if (ret)
> +			goto error;
> +
> +		mx28_fec_pdata[i].mac[0] = 0x00;
> +		mx28_fec_pdata[i].mac[1] = 0x04;
> +		mx28_fec_pdata[i].mac[2] = 0x9f;
> +		mx28_fec_pdata[i].mac[3] = (val >> 16) & 0xff;
> +		mx28_fec_pdata[i].mac[4] = (val >> 8) & 0xff;
> +		mx28_fec_pdata[i].mac[5] = (val >> 0) & 0xff;
> +	}
> +
> +	return 0;
> +
> +error:
> +	pr_err("%s: timeout when reading fec mac from OCOTP\n", __func__);
> +	return ret;
> +}
> +
>  static void __init mx28evk_init(void)
>  {
>  	mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
>  
>  	mx28_add_duart();
>  
> +	if (mx28evk_fec_get_mac())
> +		pr_warn("%s: failed on fec mac setup\n", __func__);
> +
>  	mx28evk_fec_reset();
>  	mx28_add_fec(0, &mx28_fec_pdata[0]);
>  #ifdef CONFIG_FEC2
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 09/10] ARM: mx28: read fec mac address from ocotp
@ 2011-01-13 14:50     ` Uwe Kleine-König
  0 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-13 14:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

$SUBJECT ~= s,mx28,mxs/mx28evk, please

On Thu, Jan 06, 2011 at 03:13:17PM +0800, Shawn Guo wrote:
> Read fec mac address from ocotp and save it into fec_platform_data
> mac field for fec driver to use.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
>  - It's not necessary to remove "const" for fec_platform_data from
>    platform-fec.c and devices-common.h, so add it back.
>  - Hard-coding Freescale OUI (00:04:9f) instead of just the first
>    two two octets.
>  - Correct the return of mx28evk_fec_get_mac() and check it
>    with caller
> 
>  arch/arm/mach-mxs/mach-mx28evk.c |   32 ++++++++++++++++++++++++++++++++
>  1 files changed, 32 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
> index def6519..54fa512 100644
> --- a/arch/arm/mach-mxs/mach-mx28evk.c
> +++ b/arch/arm/mach-mxs/mach-mx28evk.c
> @@ -129,12 +129,44 @@ static struct fec_platform_data mx28_fec_pdata[] = {
>  	},
>  };
>  
> +static int __init mx28evk_fec_get_mac(void)
> +{
> +	int i, ret;
> +	u32 val;
> +
> +	/*
> +	 * OCOTP only stores the last 4 octets for each mac address,
> +	 * so hard-code Freescale OUI (00:04:9f) here.
> +	 */
> +	for (i = 0; i < 2; i++) {
> +		ret = mxs_read_ocotp(0x20 + i * 0x10, 1, &val);
> +		if (ret)
> +			goto error;
> +
> +		mx28_fec_pdata[i].mac[0] = 0x00;
> +		mx28_fec_pdata[i].mac[1] = 0x04;
> +		mx28_fec_pdata[i].mac[2] = 0x9f;
> +		mx28_fec_pdata[i].mac[3] = (val >> 16) & 0xff;
> +		mx28_fec_pdata[i].mac[4] = (val >> 8) & 0xff;
> +		mx28_fec_pdata[i].mac[5] = (val >> 0) & 0xff;
> +	}
> +
> +	return 0;
> +
> +error:
> +	pr_err("%s: timeout when reading fec mac from OCOTP\n", __func__);
> +	return ret;
> +}
> +
>  static void __init mx28evk_init(void)
>  {
>  	mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
>  
>  	mx28_add_duart();
>  
> +	if (mx28evk_fec_get_mac())
> +		pr_warn("%s: failed on fec mac setup\n", __func__);
> +
>  	mx28evk_fec_reset();
>  	mx28_add_fec(0, &mx28_fec_pdata[0]);
>  #ifdef CONFIG_FEC2
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 06/10] ARM: mx28: update clock and device name for dual fec support
  2011-01-06  7:13   ` Shawn Guo
@ 2011-01-13 15:06     ` Uwe Kleine-König
  -1 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-13 15:06 UTC (permalink / raw)
  To: Shawn Guo
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw, w.sang,
	s.hauer, jamie, jamie, netdev, linux-arm-kernel

Hi Shawn,

On Thu, Jan 06, 2011 at 03:13:14PM +0800, Shawn Guo wrote:
> Change device name from "fec" to "imx28-fec", so that fec driver
> can distinguish mx28.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v4:
>  - Use "imx28-fec" as fec device name
> 
> Changes for v3:
>  - Change device name to "enet-mac"
> 
>  arch/arm/mach-mxs/clock-mx28.c           |    3 ++-
>  arch/arm/mach-mxs/devices/platform-fec.c |    2 +-
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
> index f20b254..e2a8b0f 100644
> --- a/arch/arm/mach-mxs/clock-mx28.c
> +++ b/arch/arm/mach-mxs/clock-mx28.c
> @@ -606,7 +606,8 @@ static struct clk_lookup lookups[] = {
>  	_REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
>  	/* for amba-pl011 driver */
>  	_REGISTER_CLOCK("duart", NULL, uart_clk)
> -	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
> +	_REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk)
> +	_REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk)
>  	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
>  	_REGISTER_CLOCK("pll2", NULL, pll2_clk)
>  	_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
> diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
> index c08168c..c42dff7 100644
> --- a/arch/arm/mach-mxs/devices/platform-fec.c
> +++ b/arch/arm/mach-mxs/devices/platform-fec.c
> @@ -45,6 +45,6 @@ struct platform_device *__init mxs_add_fec(
>  		},
>  	};
>  
> -	return mxs_add_platform_device("fec", data->id,
> +	return mxs_add_platform_device("imx28-fec", data->id,
IMHO "imx28-fec" shouldn't be hard coded here but come from data.  See
imx-spi device registration for an example.

Uwe
>  			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
>  }
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 06/10] ARM: mx28: update clock and device name for dual fec support
@ 2011-01-13 15:06     ` Uwe Kleine-König
  0 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-13 15:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Shawn,

On Thu, Jan 06, 2011 at 03:13:14PM +0800, Shawn Guo wrote:
> Change device name from "fec" to "imx28-fec", so that fec driver
> can distinguish mx28.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v4:
>  - Use "imx28-fec" as fec device name
> 
> Changes for v3:
>  - Change device name to "enet-mac"
> 
>  arch/arm/mach-mxs/clock-mx28.c           |    3 ++-
>  arch/arm/mach-mxs/devices/platform-fec.c |    2 +-
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
> index f20b254..e2a8b0f 100644
> --- a/arch/arm/mach-mxs/clock-mx28.c
> +++ b/arch/arm/mach-mxs/clock-mx28.c
> @@ -606,7 +606,8 @@ static struct clk_lookup lookups[] = {
>  	_REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
>  	/* for amba-pl011 driver */
>  	_REGISTER_CLOCK("duart", NULL, uart_clk)
> -	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
> +	_REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk)
> +	_REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk)
>  	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
>  	_REGISTER_CLOCK("pll2", NULL, pll2_clk)
>  	_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
> diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
> index c08168c..c42dff7 100644
> --- a/arch/arm/mach-mxs/devices/platform-fec.c
> +++ b/arch/arm/mach-mxs/devices/platform-fec.c
> @@ -45,6 +45,6 @@ struct platform_device *__init mxs_add_fec(
>  		},
>  	};
>  
> -	return mxs_add_platform_device("fec", data->id,
> +	return mxs_add_platform_device("imx28-fec", data->id,
IMHO "imx28-fec" shouldn't be hard coded here but come from data.  See
imx-spi device registration for an example.

Uwe
>  			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
>  }
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 08/10] ARM: mxs: add ocotp read function
  2011-01-06  7:13   ` Shawn Guo
@ 2011-01-13 15:19     ` Uwe Kleine-König
  -1 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-13 15:19 UTC (permalink / raw)
  To: Shawn Guo
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw, w.sang,
	s.hauer, jamie, jamie, netdev, linux-arm-kernel

On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v4:
>  - Call cpu_relax() during polling
> 
> Changes for v2:
>  - Add mutex locking for mxs_read_ocotp()
>  - Use type size_t for count and i
>  - Add comment for clk_enable/disable skipping
>  - Add ERROR bit clearing and polling step
> 
>  arch/arm/mach-mxs/Makefile              |    2 +-
>  arch/arm/mach-mxs/include/mach/common.h |    1 +
>  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
>  3 files changed, 81 insertions(+), 1 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/ocotp.c
> 
> diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> index 39d3f9c..f23ebbd 100644
> --- a/arch/arm/mach-mxs/Makefile
> +++ b/arch/arm/mach-mxs/Makefile
> @@ -1,5 +1,5 @@
>  # Common support
> -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
is it worth to make ocotp optional?  (and let evk select
CONFIG_MXS_OCOTP)

Best regards
Uwe
>  
>  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
>  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
> diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> index 59133eb..cf02552 100644
> --- a/arch/arm/mach-mxs/include/mach/common.h
> +++ b/arch/arm/mach-mxs/include/mach/common.h
> @@ -13,6 +13,7 @@
>  
>  struct clk;
>  
> +extern int mxs_read_ocotp(int offset, int count, u32 *values);
>  extern int mxs_reset_block(void __iomem *);
>  extern void mxs_timer_init(struct clk *, int);
>  
> diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> new file mode 100644
> index 0000000..e2d39aa
> --- /dev/null
> +++ b/arch/arm/mach-mxs/ocotp.c
> @@ -0,0 +1,79 @@
> +/*
> + * Copyright 2010 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 as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/mutex.h>
> +
> +#include <mach/mxs.h>
> +
> +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> +
> +static DEFINE_MUTEX(ocotp_mutex);
> +
> +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> +{
> +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> +	int timeout = 0x400;
> +	size_t i;
> +
> +	mutex_lock(&ocotp_mutex);
> +
> +	/*
> +	 * clk_enable(hbus_clk) for ocotp can be skipped
> +	 * as it must be on when system is running.
> +	 */
> +
> +	/* try to clear ERROR bit */
> +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> +
> +	/* check both BUSY and ERROR cleared */
> +	while ((__raw_readl(ocotp_base) &
> +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> +		cpu_relax();
> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	/* open OCOTP banks for read */
> +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> +
> +	/* approximately wait 32 hclk cycles */
> +	udelay(1);
> +
> +	/* poll BUSY bit becoming cleared */
> +	timeout = 0x400;
> +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> +		cpu_relax();
> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	for (i = 0; i < count; i++, offset += 4)
> +		*values++ = __raw_readl(ocotp_base + offset);
> +
> +	/* close banks for power saving */
> +	__mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> +
> +	mutex_unlock(&ocotp_mutex);
> +
> +	return 0;
> +
> +error_unlock:
> +	mutex_unlock(&ocotp_mutex);
> +	pr_err("%s: timeout in reading OCOTP\n", __func__);
> +	return -ETIMEDOUT;
> +}
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 08/10] ARM: mxs: add ocotp read function
@ 2011-01-13 15:19     ` Uwe Kleine-König
  0 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-13 15:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v4:
>  - Call cpu_relax() during polling
> 
> Changes for v2:
>  - Add mutex locking for mxs_read_ocotp()
>  - Use type size_t for count and i
>  - Add comment for clk_enable/disable skipping
>  - Add ERROR bit clearing and polling step
> 
>  arch/arm/mach-mxs/Makefile              |    2 +-
>  arch/arm/mach-mxs/include/mach/common.h |    1 +
>  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
>  3 files changed, 81 insertions(+), 1 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/ocotp.c
> 
> diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> index 39d3f9c..f23ebbd 100644
> --- a/arch/arm/mach-mxs/Makefile
> +++ b/arch/arm/mach-mxs/Makefile
> @@ -1,5 +1,5 @@
>  # Common support
> -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
is it worth to make ocotp optional?  (and let evk select
CONFIG_MXS_OCOTP)

Best regards
Uwe
>  
>  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
>  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
> diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> index 59133eb..cf02552 100644
> --- a/arch/arm/mach-mxs/include/mach/common.h
> +++ b/arch/arm/mach-mxs/include/mach/common.h
> @@ -13,6 +13,7 @@
>  
>  struct clk;
>  
> +extern int mxs_read_ocotp(int offset, int count, u32 *values);
>  extern int mxs_reset_block(void __iomem *);
>  extern void mxs_timer_init(struct clk *, int);
>  
> diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> new file mode 100644
> index 0000000..e2d39aa
> --- /dev/null
> +++ b/arch/arm/mach-mxs/ocotp.c
> @@ -0,0 +1,79 @@
> +/*
> + * Copyright 2010 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 as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/mutex.h>
> +
> +#include <mach/mxs.h>
> +
> +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> +
> +static DEFINE_MUTEX(ocotp_mutex);
> +
> +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> +{
> +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> +	int timeout = 0x400;
> +	size_t i;
> +
> +	mutex_lock(&ocotp_mutex);
> +
> +	/*
> +	 * clk_enable(hbus_clk) for ocotp can be skipped
> +	 * as it must be on when system is running.
> +	 */
> +
> +	/* try to clear ERROR bit */
> +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> +
> +	/* check both BUSY and ERROR cleared */
> +	while ((__raw_readl(ocotp_base) &
> +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> +		cpu_relax();
> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	/* open OCOTP banks for read */
> +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> +
> +	/* approximately wait 32 hclk cycles */
> +	udelay(1);
> +
> +	/* poll BUSY bit becoming cleared */
> +	timeout = 0x400;
> +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> +		cpu_relax();
> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	for (i = 0; i < count; i++, offset += 4)
> +		*values++ = __raw_readl(ocotp_base + offset);
> +
> +	/* close banks for power saving */
> +	__mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> +
> +	mutex_unlock(&ocotp_mutex);
> +
> +	return 0;
> +
> +error_unlock:
> +	mutex_unlock(&ocotp_mutex);
> +	pr_err("%s: timeout in reading OCOTP\n", __func__);
> +	return -ETIMEDOUT;
> +}
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 05/10] net/fec: add dual fec support for mx28
  2011-01-06  7:13   ` Shawn Guo
@ 2011-01-13 21:06     ` Uwe Kleine-König
  -1 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-13 21:06 UTC (permalink / raw)
  To: Shawn Guo
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw, w.sang,
	s.hauer, jamie, jamie, netdev, linux-arm-kernel

Hello again,

On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
>  static netdev_tx_t
>  fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  {
>  	struct fec_enet_private *fep = netdev_priv(dev);
> +	const struct platform_device_id *id_entry =
> +				platform_get_device_id(fep->pdev);
>  	struct bufdesc *bdp;
>  	void *bufaddr;
>  	unsigned short	status;
> @@ -256,6 +288,14 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  		bufaddr = fep->tx_bounce[index];
>  	}
>  
> +	/*
> +	 * Some design made an incorrect assumption on endian mode of
> +	 * the system that it's running on. As the result, driver has to
> +	 * swap every frame going to and coming from the controller.
> +	 */
> +	if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
> +		swap_buffer(bufaddr, skb->len);
> +
Is that save here?  bufaddr either points to a bounce buffer (which
should be OK definitely) or skb->data.  Or asked differently:  Is the
skb here owned by the driver such that it is allowed to write to it?
Does the driver eventually need to restore the original data?

Just before this if, there is some bounce buffer handling.  If it is not
OK to modify skb->data, the call to swap_buffer can easily be moved in
there.

>  	/* Save skb pointer */
>  	fep->tx_skbuff[fep->skb_cur] = skb;
>  
> @@ -424,6 +464,8 @@ static void
>  fec_enet_rx(struct net_device *dev)
>  {
>  	struct	fec_enet_private *fep = netdev_priv(dev);
> +	const struct platform_device_id *id_entry =
> +				platform_get_device_id(fep->pdev);
>  	struct bufdesc *bdp;
>  	unsigned short status;
>  	struct	sk_buff	*skb;
> @@ -487,6 +529,9 @@ fec_enet_rx(struct net_device *dev)
>  	        dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
>          			DMA_FROM_DEVICE);
>  
> +		if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
> +			swap_buffer(data, pkt_len);
> +
Here I guess it's OK, the hardware just wrote to the buffer, so the skb
cannot be shared to anything else and the write is all right.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
@ 2011-01-13 21:06     ` Uwe Kleine-König
  0 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-13 21:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hello again,

On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
>  static netdev_tx_t
>  fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  {
>  	struct fec_enet_private *fep = netdev_priv(dev);
> +	const struct platform_device_id *id_entry =
> +				platform_get_device_id(fep->pdev);
>  	struct bufdesc *bdp;
>  	void *bufaddr;
>  	unsigned short	status;
> @@ -256,6 +288,14 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  		bufaddr = fep->tx_bounce[index];
>  	}
>  
> +	/*
> +	 * Some design made an incorrect assumption on endian mode of
> +	 * the system that it's running on. As the result, driver has to
> +	 * swap every frame going to and coming from the controller.
> +	 */
> +	if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
> +		swap_buffer(bufaddr, skb->len);
> +
Is that save here?  bufaddr either points to a bounce buffer (which
should be OK definitely) or skb->data.  Or asked differently:  Is the
skb here owned by the driver such that it is allowed to write to it?
Does the driver eventually need to restore the original data?

Just before this if, there is some bounce buffer handling.  If it is not
OK to modify skb->data, the call to swap_buffer can easily be moved in
there.

>  	/* Save skb pointer */
>  	fep->tx_skbuff[fep->skb_cur] = skb;
>  
> @@ -424,6 +464,8 @@ static void
>  fec_enet_rx(struct net_device *dev)
>  {
>  	struct	fec_enet_private *fep = netdev_priv(dev);
> +	const struct platform_device_id *id_entry =
> +				platform_get_device_id(fep->pdev);
>  	struct bufdesc *bdp;
>  	unsigned short status;
>  	struct	sk_buff	*skb;
> @@ -487,6 +529,9 @@ fec_enet_rx(struct net_device *dev)
>  	        dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
>          			DMA_FROM_DEVICE);
>  
> +		if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
> +			swap_buffer(data, pkt_len);
> +
Here I guess it's OK, the hardware just wrote to the buffer, so the skb
cannot be shared to anything else and the write is all right.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 05/10] net/fec: add dual fec support for mx28
  2011-01-13 14:48     ` Uwe Kleine-König
@ 2011-01-14  5:48       ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14  5:48 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw, w.sang,
	s.hauer, jamie, jamie, netdev, linux-arm-kernel

Hi Uwe,

On Thu, Jan 13, 2011 at 03:48:05PM +0100, Uwe Kleine-König wrote:

[...]

> > +/* Controller is ENET-MAC */
> > +#define FEC_QUIRK_ENET_MAC           (1 << 0)
> does this really qualify to be a quirk?
> 
My understanding is that ENET-MAC is a type of "quirky" FEC
controller.

> > +/* Controller needs driver to swap frame */
> > +#define FEC_QUIRK_SWAP_FRAME         (1 << 1)
> IMHO this is a bit misnamed.  FEC_QUIRK_NEEDS_BE_DATA or similar would
> be more accurate.
> 
When your make this change, you may want to pick a better name for
function swap_buffer too.

[...]

> > +static void *swap_buffer(void *bufaddr, int len)
> > +{
> > +     int i;
> > +     unsigned int *buf = bufaddr;
> > +
> > +     for (i = 0; i < (len + 3) / 4; i++, buf++)
> > +             *buf = cpu_to_be32(*buf);
> if len isn't a multiple of 4 this accesses bytes behind len.  Is this
> generally OK here?  (E.g. because skbs always have a length that is a
> multiple of 4?)
The len may not be a multiple of 4.  But I believe bufaddr is always
a buffer allocated in a length that is a multiple of 4, and the 1~3
bytes exceeding the len very likely has no data that matters.  But
yes, it deserves a safer implementation.

[...]

> > +     /*
> > +      * The dual fec interfaces are not equivalent with enet-mac.
> > +      * Here are the differences:
> > +      *
> > +      *  - fec0 supports MII & RMII modes while fec1 only supports RMII
> > +      *  - fec0 acts as the 1588 time master while fec1 is slave
> > +      *  - external phys can only be configured by fec0
> > +      *
> > +      * That is to say fec1 can not work independently. It only works
> > +      * when fec0 is working. The reason behind this design is that the
> > +      * second interface is added primarily for Switch mode.
> > +      *
> > +      * Because of the last point above, both phys are attached on fec0
> > +      * mdio interface in board design, and need to be configured by
> > +      * fec0 mii_bus.
> > +      */
> > +     if ((id_entry->driver_data & FEC_QUIRK_ENET_MAC) && pdev->id) {
> > +             /* fec1 uses fec0 mii_bus */
> > +             fep->mii_bus = fec0_mii_bus;
> > +             return 0;
> What happens if imx28-fec.1 is probed before imx28-fec.0?
It's something that generally should not happen, as these two fec are
not equivalent, and fec.1 should always be added after fec.0 if you
intend to get dual interfaces.  But yes, we should add error checking
for this case in the driver.

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
@ 2011-01-14  5:48       ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14  5:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

On Thu, Jan 13, 2011 at 03:48:05PM +0100, Uwe Kleine-K?nig wrote:

[...]

> > +/* Controller is ENET-MAC */
> > +#define FEC_QUIRK_ENET_MAC           (1 << 0)
> does this really qualify to be a quirk?
> 
My understanding is that ENET-MAC is a type of "quirky" FEC
controller.

> > +/* Controller needs driver to swap frame */
> > +#define FEC_QUIRK_SWAP_FRAME         (1 << 1)
> IMHO this is a bit misnamed.  FEC_QUIRK_NEEDS_BE_DATA or similar would
> be more accurate.
> 
When your make this change, you may want to pick a better name for
function swap_buffer too.

[...]

> > +static void *swap_buffer(void *bufaddr, int len)
> > +{
> > +     int i;
> > +     unsigned int *buf = bufaddr;
> > +
> > +     for (i = 0; i < (len + 3) / 4; i++, buf++)
> > +             *buf = cpu_to_be32(*buf);
> if len isn't a multiple of 4 this accesses bytes behind len.  Is this
> generally OK here?  (E.g. because skbs always have a length that is a
> multiple of 4?)
The len may not be a multiple of 4.  But I believe bufaddr is always
a buffer allocated in a length that is a multiple of 4, and the 1~3
bytes exceeding the len very likely has no data that matters.  But
yes, it deserves a safer implementation.

[...]

> > +     /*
> > +      * The dual fec interfaces are not equivalent with enet-mac.
> > +      * Here are the differences:
> > +      *
> > +      *  - fec0 supports MII & RMII modes while fec1 only supports RMII
> > +      *  - fec0 acts as the 1588 time master while fec1 is slave
> > +      *  - external phys can only be configured by fec0
> > +      *
> > +      * That is to say fec1 can not work independently. It only works
> > +      * when fec0 is working. The reason behind this design is that the
> > +      * second interface is added primarily for Switch mode.
> > +      *
> > +      * Because of the last point above, both phys are attached on fec0
> > +      * mdio interface in board design, and need to be configured by
> > +      * fec0 mii_bus.
> > +      */
> > +     if ((id_entry->driver_data & FEC_QUIRK_ENET_MAC) && pdev->id) {
> > +             /* fec1 uses fec0 mii_bus */
> > +             fep->mii_bus = fec0_mii_bus;
> > +             return 0;
> What happens if imx28-fec.1 is probed before imx28-fec.0?
It's something that generally should not happen, as these two fec are
not equivalent, and fec.1 should always be added after fec.0 if you
intend to get dual interfaces.  But yes, we should add error checking
for this case in the driver.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 06/10] ARM: mx28: update clock and device name for dual fec support
  2011-01-13 15:06     ` Uwe Kleine-König
@ 2011-01-14  6:46       ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14  6:46 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw, w.sang,
	s.hauer, jamie, jamie, netdev, linux-arm-kernel

Hi Uwe,

On Thu, Jan 13, 2011 at 04:06:22PM +0100, Uwe Kleine-König wrote:
> Hi Shawn,
> 
> On Thu, Jan 06, 2011 at 03:13:14PM +0800, Shawn Guo wrote:
> > Change device name from "fec" to "imx28-fec", so that fec driver
> > can distinguish mx28.
> > 
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > ---
> > Changes for v4:
> >  - Use "imx28-fec" as fec device name
> > 
> > Changes for v3:
> >  - Change device name to "enet-mac"
> > 
> >  arch/arm/mach-mxs/clock-mx28.c           |    3 ++-
> >  arch/arm/mach-mxs/devices/platform-fec.c |    2 +-
> >  2 files changed, 3 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
> > index f20b254..e2a8b0f 100644
> > --- a/arch/arm/mach-mxs/clock-mx28.c
> > +++ b/arch/arm/mach-mxs/clock-mx28.c
> > @@ -606,7 +606,8 @@ static struct clk_lookup lookups[] = {
> >  	_REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
> >  	/* for amba-pl011 driver */
> >  	_REGISTER_CLOCK("duart", NULL, uart_clk)
> > -	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
> > +	_REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk)
> > +	_REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk)
> >  	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
> >  	_REGISTER_CLOCK("pll2", NULL, pll2_clk)
> >  	_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
> > diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
> > index c08168c..c42dff7 100644
> > --- a/arch/arm/mach-mxs/devices/platform-fec.c
> > +++ b/arch/arm/mach-mxs/devices/platform-fec.c
> > @@ -45,6 +45,6 @@ struct platform_device *__init mxs_add_fec(
> >  		},
> >  	};
> >  
> > -	return mxs_add_platform_device("fec", data->id,
> > +	return mxs_add_platform_device("imx28-fec", data->id,
> IMHO "imx28-fec" shouldn't be hard coded here but come from data.  See
> imx-spi device registration for an example.
> 
Sascha has merged the patch, so I will send a follow-up patch.

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 06/10] ARM: mx28: update clock and device name for dual fec support
@ 2011-01-14  6:46       ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14  6:46 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

On Thu, Jan 13, 2011 at 04:06:22PM +0100, Uwe Kleine-K?nig wrote:
> Hi Shawn,
> 
> On Thu, Jan 06, 2011 at 03:13:14PM +0800, Shawn Guo wrote:
> > Change device name from "fec" to "imx28-fec", so that fec driver
> > can distinguish mx28.
> > 
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > ---
> > Changes for v4:
> >  - Use "imx28-fec" as fec device name
> > 
> > Changes for v3:
> >  - Change device name to "enet-mac"
> > 
> >  arch/arm/mach-mxs/clock-mx28.c           |    3 ++-
> >  arch/arm/mach-mxs/devices/platform-fec.c |    2 +-
> >  2 files changed, 3 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
> > index f20b254..e2a8b0f 100644
> > --- a/arch/arm/mach-mxs/clock-mx28.c
> > +++ b/arch/arm/mach-mxs/clock-mx28.c
> > @@ -606,7 +606,8 @@ static struct clk_lookup lookups[] = {
> >  	_REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
> >  	/* for amba-pl011 driver */
> >  	_REGISTER_CLOCK("duart", NULL, uart_clk)
> > -	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
> > +	_REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk)
> > +	_REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk)
> >  	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
> >  	_REGISTER_CLOCK("pll2", NULL, pll2_clk)
> >  	_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
> > diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
> > index c08168c..c42dff7 100644
> > --- a/arch/arm/mach-mxs/devices/platform-fec.c
> > +++ b/arch/arm/mach-mxs/devices/platform-fec.c
> > @@ -45,6 +45,6 @@ struct platform_device *__init mxs_add_fec(
> >  		},
> >  	};
> >  
> > -	return mxs_add_platform_device("fec", data->id,
> > +	return mxs_add_platform_device("imx28-fec", data->id,
> IMHO "imx28-fec" shouldn't be hard coded here but come from data.  See
> imx-spi device registration for an example.
> 
Sascha has merged the patch, so I will send a follow-up patch.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH] ARM: mxs: pass fec device name via platform data
  2011-01-13 15:06     ` Uwe Kleine-König
@ 2011-01-14  6:53       ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14  6:53 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw; +Cc: Shawn Guo

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/devices/platform-fec.c        |   11 ++++++-----
 arch/arm/mach-mxs/include/mach/devices-common.h |    1 +
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
index c42dff7..75eb26b 100644
--- a/arch/arm/mach-mxs/devices/platform-fec.c
+++ b/arch/arm/mach-mxs/devices/platform-fec.c
@@ -10,20 +10,21 @@
 #include <mach/mx28.h>
 #include <mach/devices-common.h>
 
-#define mxs_fec_data_entry_single(soc, _id)				\
+#define mxs_fec_data_entry_single(soc, _devid, _id)			\
 	{								\
+		.devid = _devid,					\
 		.id = _id,						\
 		.iobase = soc ## _ENET_MAC ## _id ## _BASE_ADDR,	\
 		.irq = soc ## _INT_ENET_MAC ## _id,			\
 	}
 
-#define mxs_fec_data_entry(soc, _id)					\
-	[_id] = mxs_fec_data_entry_single(soc, _id)
+#define mxs_fec_data_entry(soc, _devid, _id)				\
+	[_id] = mxs_fec_data_entry_single(soc, _devid, _id)
 
 #ifdef CONFIG_SOC_IMX28
 const struct mxs_fec_data mx28_fec_data[] __initconst = {
 #define mx28_fec_data_entry(_id)					\
-	mxs_fec_data_entry(MX28, _id)
+	mxs_fec_data_entry(MX28, "imx28-fec", _id)
 	mx28_fec_data_entry(0),
 	mx28_fec_data_entry(1),
 };
@@ -45,6 +46,6 @@ struct platform_device *__init mxs_add_fec(
 		},
 	};
 
-	return mxs_add_platform_device("imx28-fec", data->id,
+	return mxs_add_platform_device(data->devid, data->id,
 			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
 }
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index 6c3d1a1..10fbcfd 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -33,6 +33,7 @@ int __init mxs_add_duart(const struct amba_device *dev);
 /* fec */
 #include <linux/fec.h>
 struct mxs_fec_data {
+	const char *devid;
 	int id;
 	resource_size_t iobase;
 	resource_size_t iosize;
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH] ARM: mxs: pass fec device name via platform data
@ 2011-01-14  6:53       ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14  6:53 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/devices/platform-fec.c        |   11 ++++++-----
 arch/arm/mach-mxs/include/mach/devices-common.h |    1 +
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
index c42dff7..75eb26b 100644
--- a/arch/arm/mach-mxs/devices/platform-fec.c
+++ b/arch/arm/mach-mxs/devices/platform-fec.c
@@ -10,20 +10,21 @@
 #include <mach/mx28.h>
 #include <mach/devices-common.h>
 
-#define mxs_fec_data_entry_single(soc, _id)				\
+#define mxs_fec_data_entry_single(soc, _devid, _id)			\
 	{								\
+		.devid = _devid,					\
 		.id = _id,						\
 		.iobase = soc ## _ENET_MAC ## _id ## _BASE_ADDR,	\
 		.irq = soc ## _INT_ENET_MAC ## _id,			\
 	}
 
-#define mxs_fec_data_entry(soc, _id)					\
-	[_id] = mxs_fec_data_entry_single(soc, _id)
+#define mxs_fec_data_entry(soc, _devid, _id)				\
+	[_id] = mxs_fec_data_entry_single(soc, _devid, _id)
 
 #ifdef CONFIG_SOC_IMX28
 const struct mxs_fec_data mx28_fec_data[] __initconst = {
 #define mx28_fec_data_entry(_id)					\
-	mxs_fec_data_entry(MX28, _id)
+	mxs_fec_data_entry(MX28, "imx28-fec", _id)
 	mx28_fec_data_entry(0),
 	mx28_fec_data_entry(1),
 };
@@ -45,6 +46,6 @@ struct platform_device *__init mxs_add_fec(
 		},
 	};
 
-	return mxs_add_platform_device("imx28-fec", data->id,
+	return mxs_add_platform_device(data->devid, data->id,
 			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
 }
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index 6c3d1a1..10fbcfd 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -33,6 +33,7 @@ int __init mxs_add_duart(const struct amba_device *dev);
 /* fec */
 #include <linux/fec.h>
 struct mxs_fec_data {
+	const char *devid;
 	int id;
 	resource_size_t iobase;
 	resource_size_t iosize;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

* Re: [PATCH v5] ARM: mx28: add the second fec device registration
  2011-01-13 14:49     ` Uwe Kleine-König
@ 2011-01-14  7:04       ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14  7:04 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: s.hauer, davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw,
	w.sang, jamie, jamie, netdev, linux-arm-kernel

Hi Uwe,

On Thu, Jan 13, 2011 at 03:49:00PM +0100, Uwe Kleine-König wrote:
> On Tue, Jan 11, 2011 at 08:09:24PM +0800, Shawn Guo wrote:
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > ---
> > Changes for v5:
> >  - Do not use CONFIG_FEC2 which is a fec driver configration
> > 
> >  arch/arm/mach-mxs/mach-mx28evk.c |   26 +++++++++++++++++++++++---
> >  1 files changed, 23 insertions(+), 3 deletions(-)
> > 
> > diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
> > index d162e95..8e2c597 100644
> > --- a/arch/arm/mach-mxs/mach-mx28evk.c
> > +++ b/arch/arm/mach-mxs/mach-mx28evk.c
> > @@ -57,6 +57,19 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
> >  		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> >  	MX28_PAD_ENET_CLK__CLKCTRL_ENET |
> >  		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> > +	/* fec1 */
> > +	MX28_PAD_ENET0_CRS__ENET1_RX_EN |
> > +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> > +	MX28_PAD_ENET0_RXD2__ENET1_RXD0 |
> > +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> > +	MX28_PAD_ENET0_RXD3__ENET1_RXD1 |
> > +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> > +	MX28_PAD_ENET0_COL__ENET1_TX_EN |
> > +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> > +	MX28_PAD_ENET0_TXD2__ENET1_TXD0 |
> > +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> > +	MX28_PAD_ENET0_TXD3__ENET1_TXD1 |
> > +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> >  	/* phy power line */
> >  	MX28_PAD_SSP1_DATA3__GPIO_2_15 |
> >  		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
> > @@ -106,8 +119,14 @@ static void __init mx28evk_fec_reset(void)
> >  	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
> >  }
> >  
> > -static const struct fec_platform_data mx28_fec_pdata __initconst = {
> > -	.phy = PHY_INTERFACE_MODE_RMII,
> > +static struct fec_platform_data mx28_fec_pdata[] = {
> this can still be initdata, doesn't it?
> 
Sascha has merged the patch.  This one line change may not deserve
a separate patch, so I will take care of it when updating the file
with new version of ocotp patch.

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v5] ARM: mx28: add the second fec device registration
@ 2011-01-14  7:04       ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14  7:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

On Thu, Jan 13, 2011 at 03:49:00PM +0100, Uwe Kleine-K?nig wrote:
> On Tue, Jan 11, 2011 at 08:09:24PM +0800, Shawn Guo wrote:
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > ---
> > Changes for v5:
> >  - Do not use CONFIG_FEC2 which is a fec driver configration
> > 
> >  arch/arm/mach-mxs/mach-mx28evk.c |   26 +++++++++++++++++++++++---
> >  1 files changed, 23 insertions(+), 3 deletions(-)
> > 
> > diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
> > index d162e95..8e2c597 100644
> > --- a/arch/arm/mach-mxs/mach-mx28evk.c
> > +++ b/arch/arm/mach-mxs/mach-mx28evk.c
> > @@ -57,6 +57,19 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
> >  		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> >  	MX28_PAD_ENET_CLK__CLKCTRL_ENET |
> >  		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> > +	/* fec1 */
> > +	MX28_PAD_ENET0_CRS__ENET1_RX_EN |
> > +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> > +	MX28_PAD_ENET0_RXD2__ENET1_RXD0 |
> > +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> > +	MX28_PAD_ENET0_RXD3__ENET1_RXD1 |
> > +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> > +	MX28_PAD_ENET0_COL__ENET1_TX_EN |
> > +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> > +	MX28_PAD_ENET0_TXD2__ENET1_TXD0 |
> > +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> > +	MX28_PAD_ENET0_TXD3__ENET1_TXD1 |
> > +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> >  	/* phy power line */
> >  	MX28_PAD_SSP1_DATA3__GPIO_2_15 |
> >  		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
> > @@ -106,8 +119,14 @@ static void __init mx28evk_fec_reset(void)
> >  	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
> >  }
> >  
> > -static const struct fec_platform_data mx28_fec_pdata __initconst = {
> > -	.phy = PHY_INTERFACE_MODE_RMII,
> > +static struct fec_platform_data mx28_fec_pdata[] = {
> this can still be initdata, doesn't it?
> 
Sascha has merged the patch.  This one line change may not deserve
a separate patch, so I will take care of it when updating the file
with new version of ocotp patch.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v5 08/10] ARM: mxs: add ocotp read function
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-14  7:24   ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14  7:24 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw; +Cc: Shawn Guo

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/Kconfig               |    4 ++
 arch/arm/mach-mxs/Makefile              |    3 +
 arch/arm/mach-mxs/include/mach/common.h |    1 +
 arch/arm/mach-mxs/ocotp.c               |   90 +++++++++++++++++++++++++++++++
 4 files changed, 98 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/ocotp.c

diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index 8bfc8df..cd2fbdf 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -2,6 +2,9 @@ if ARCH_MXS
 
 source "arch/arm/mach-mxs/devices/Kconfig"
 
+config MXS_OCOTP
+	bool
+
 config SOC_IMX23
 	bool
 	select CPU_ARM926T
@@ -26,6 +29,7 @@ config MACH_MX28EVK
 	select SOC_IMX28
 	select MXS_HAVE_AMBA_DUART
 	select MXS_HAVE_PLATFORM_FEC
+	select MXS_OCOTP
 	default y
 	help
 	  Include support for MX28EVK platform. This includes specific
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 39d3f9c..623899b 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,6 +1,9 @@
 # Common support
 obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
 
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_MXS_OCOTP) += ocotp.o
+
 obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
 obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
 
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
index 59133eb..635bb5d 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -13,6 +13,7 @@
 
 struct clk;
 
+extern const u32 *mxs_get_ocotp(void);
 extern int mxs_reset_block(void __iomem *);
 extern void mxs_timer_init(struct clk *, int);
 
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
new file mode 100644
index 0000000..eb2eab7
--- /dev/null
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2010 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+#include <mach/mxs.h>
+
+#define OCOTP_WORD_OFFSET		0x20
+#define OCOTP_WORD_COUNT		0x20
+
+#define BM_OCOTP_CTRL_BUSY		(1 << 8)
+#define BM_OCOTP_CTRL_ERROR		(1 << 9)
+#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
+
+static DEFINE_MUTEX(ocotp_mutex);
+static u32 ocotp_words[OCOTP_WORD_COUNT];
+
+const u32 *mxs_get_ocotp(void)
+{
+	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
+	int timeout = 0x400;
+	size_t i;
+	static int once = 0;
+
+	if (once)
+		return ocotp_words;
+
+	mutex_lock(&ocotp_mutex);
+
+	/*
+	 * clk_enable(hbus_clk) for ocotp can be skipped
+	 * as it must be on when system is running.
+	 */
+
+	/* try to clear ERROR bit */
+	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
+
+	/* check both BUSY and ERROR cleared */
+	while ((__raw_readl(ocotp_base) &
+		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
+		cpu_relax();
+
+	if (unlikely(!timeout))
+		goto error_unlock;
+
+	/* open OCOTP banks for read */
+	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+	/* approximately wait 32 hclk cycles */
+	udelay(1);
+
+	/* poll BUSY bit becoming cleared */
+	timeout = 0x400;
+	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
+		cpu_relax();
+
+	if (unlikely(!timeout))
+		goto error_unlock;
+
+	for (i = 0; i < OCOTP_WORD_COUNT; i++)
+		ocotp_words[i] = __raw_readl(ocotp_base + OCOTP_WORD_OFFSET +
+						i * 0x10);
+
+	/* close banks for power saving */
+	__mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+	mutex_unlock(&ocotp_mutex);
+
+	once = 1;
+
+	return ocotp_words;
+
+error_unlock:
+	mutex_unlock(&ocotp_mutex);
+	pr_err("%s: timeout in reading OCOTP\n", __func__);
+	return NULL;
+}
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v5 08/10] ARM: mxs: add ocotp read function
@ 2011-01-14  7:24   ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14  7:24 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/Kconfig               |    4 ++
 arch/arm/mach-mxs/Makefile              |    3 +
 arch/arm/mach-mxs/include/mach/common.h |    1 +
 arch/arm/mach-mxs/ocotp.c               |   90 +++++++++++++++++++++++++++++++
 4 files changed, 98 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/ocotp.c

diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index 8bfc8df..cd2fbdf 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -2,6 +2,9 @@ if ARCH_MXS
 
 source "arch/arm/mach-mxs/devices/Kconfig"
 
+config MXS_OCOTP
+	bool
+
 config SOC_IMX23
 	bool
 	select CPU_ARM926T
@@ -26,6 +29,7 @@ config MACH_MX28EVK
 	select SOC_IMX28
 	select MXS_HAVE_AMBA_DUART
 	select MXS_HAVE_PLATFORM_FEC
+	select MXS_OCOTP
 	default y
 	help
 	  Include support for MX28EVK platform. This includes specific
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 39d3f9c..623899b 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,6 +1,9 @@
 # Common support
 obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
 
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_MXS_OCOTP) += ocotp.o
+
 obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
 obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
 
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
index 59133eb..635bb5d 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -13,6 +13,7 @@
 
 struct clk;
 
+extern const u32 *mxs_get_ocotp(void);
 extern int mxs_reset_block(void __iomem *);
 extern void mxs_timer_init(struct clk *, int);
 
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
new file mode 100644
index 0000000..eb2eab7
--- /dev/null
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2010 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+#include <mach/mxs.h>
+
+#define OCOTP_WORD_OFFSET		0x20
+#define OCOTP_WORD_COUNT		0x20
+
+#define BM_OCOTP_CTRL_BUSY		(1 << 8)
+#define BM_OCOTP_CTRL_ERROR		(1 << 9)
+#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
+
+static DEFINE_MUTEX(ocotp_mutex);
+static u32 ocotp_words[OCOTP_WORD_COUNT];
+
+const u32 *mxs_get_ocotp(void)
+{
+	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
+	int timeout = 0x400;
+	size_t i;
+	static int once = 0;
+
+	if (once)
+		return ocotp_words;
+
+	mutex_lock(&ocotp_mutex);
+
+	/*
+	 * clk_enable(hbus_clk) for ocotp can be skipped
+	 * as it must be on when system is running.
+	 */
+
+	/* try to clear ERROR bit */
+	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
+
+	/* check both BUSY and ERROR cleared */
+	while ((__raw_readl(ocotp_base) &
+		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
+		cpu_relax();
+
+	if (unlikely(!timeout))
+		goto error_unlock;
+
+	/* open OCOTP banks for read */
+	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+	/* approximately wait 32 hclk cycles */
+	udelay(1);
+
+	/* poll BUSY bit becoming cleared */
+	timeout = 0x400;
+	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
+		cpu_relax();
+
+	if (unlikely(!timeout))
+		goto error_unlock;
+
+	for (i = 0; i < OCOTP_WORD_COUNT; i++)
+		ocotp_words[i] = __raw_readl(ocotp_base + OCOTP_WORD_OFFSET +
+						i * 0x10);
+
+	/* close banks for power saving */
+	__mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+	mutex_unlock(&ocotp_mutex);
+
+	once = 1;
+
+	return ocotp_words;
+
+error_unlock:
+	mutex_unlock(&ocotp_mutex);
+	pr_err("%s: timeout in reading OCOTP\n", __func__);
+	return NULL;
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v5 09/10] ARM: mxs/mx28evk: read fec mac address from ocotp
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-14  7:25   ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14  7:25 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw; +Cc: Shawn Guo

Read fec mac address from ocotp and save it into fec_platform_data
mac field for fec driver to use.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/mach-mx28evk.c |   35 ++++++++++++++++++++++++++++++++++-
 1 files changed, 34 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index 8e2c597..e8db99f 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -119,7 +119,7 @@ static void __init mx28evk_fec_reset(void)
 	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
 }
 
-static struct fec_platform_data mx28_fec_pdata[] = {
+static struct fec_platform_data mx28_fec_pdata[] __initdata = {
 	{
 		/* fec0 */
 		.phy = PHY_INTERFACE_MODE_RMII,
@@ -129,12 +129,45 @@ static struct fec_platform_data mx28_fec_pdata[] = {
 	},
 };
 
+static int __init mx28evk_fec_get_mac(void)
+{
+	int i;
+	u32 val;
+	const u32 *ocotp = mxs_get_ocotp();
+
+	if (!ocotp)
+		goto error;
+
+	/*
+	 * OCOTP only stores the last 4 octets for each mac address,
+	 * so hard-code Freescale OUI (00:04:9f) here.
+	 */
+	for (i = 0; i < 2; i++) {
+		val = ocotp[i * 4];
+		mx28_fec_pdata[i].mac[0] = 0x00;
+		mx28_fec_pdata[i].mac[1] = 0x04;
+		mx28_fec_pdata[i].mac[2] = 0x9f;
+		mx28_fec_pdata[i].mac[3] = (val >> 16) & 0xff;
+		mx28_fec_pdata[i].mac[4] = (val >> 8) & 0xff;
+		mx28_fec_pdata[i].mac[5] = (val >> 0) & 0xff;
+	}
+
+	return 0;
+
+error:
+	pr_err("%s: timeout when reading fec mac from OCOTP\n", __func__);
+	return -ETIMEDOUT;
+}
+
 static void __init mx28evk_init(void)
 {
 	mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
 
 	mx28_add_duart();
 
+	if (mx28evk_fec_get_mac())
+		pr_warn("%s: failed on fec mac setup\n", __func__);
+
 	mx28evk_fec_reset();
 	mx28_add_fec(0, &mx28_fec_pdata[0]);
 	mx28_add_fec(1, &mx28_fec_pdata[1]);
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v5 09/10] ARM: mxs/mx28evk: read fec mac address from ocotp
@ 2011-01-14  7:25   ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14  7:25 UTC (permalink / raw)
  To: linux-arm-kernel

Read fec mac address from ocotp and save it into fec_platform_data
mac field for fec driver to use.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/mach-mx28evk.c |   35 ++++++++++++++++++++++++++++++++++-
 1 files changed, 34 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index 8e2c597..e8db99f 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -119,7 +119,7 @@ static void __init mx28evk_fec_reset(void)
 	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
 }
 
-static struct fec_platform_data mx28_fec_pdata[] = {
+static struct fec_platform_data mx28_fec_pdata[] __initdata = {
 	{
 		/* fec0 */
 		.phy = PHY_INTERFACE_MODE_RMII,
@@ -129,12 +129,45 @@ static struct fec_platform_data mx28_fec_pdata[] = {
 	},
 };
 
+static int __init mx28evk_fec_get_mac(void)
+{
+	int i;
+	u32 val;
+	const u32 *ocotp = mxs_get_ocotp();
+
+	if (!ocotp)
+		goto error;
+
+	/*
+	 * OCOTP only stores the last 4 octets for each mac address,
+	 * so hard-code Freescale OUI (00:04:9f) here.
+	 */
+	for (i = 0; i < 2; i++) {
+		val = ocotp[i * 4];
+		mx28_fec_pdata[i].mac[0] = 0x00;
+		mx28_fec_pdata[i].mac[1] = 0x04;
+		mx28_fec_pdata[i].mac[2] = 0x9f;
+		mx28_fec_pdata[i].mac[3] = (val >> 16) & 0xff;
+		mx28_fec_pdata[i].mac[4] = (val >> 8) & 0xff;
+		mx28_fec_pdata[i].mac[5] = (val >> 0) & 0xff;
+	}
+
+	return 0;
+
+error:
+	pr_err("%s: timeout when reading fec mac from OCOTP\n", __func__);
+	return -ETIMEDOUT;
+}
+
 static void __init mx28evk_init(void)
 {
 	mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
 
 	mx28_add_duart();
 
+	if (mx28evk_fec_get_mac())
+		pr_warn("%s: failed on fec mac setup\n", __func__);
+
 	mx28evk_fec_reset();
 	mx28_add_fec(0, &mx28_fec_pdata[0]);
 	mx28_add_fec(1, &mx28_fec_pdata[1]);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 05/10] net/fec: add dual fec support for mx28
  2011-01-14  5:48       ` Shawn Guo
@ 2011-01-14  7:52         ` Uwe Kleine-König
  -1 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-14  7:52 UTC (permalink / raw)
  To: Shawn Guo
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw, w.sang,
	s.hauer, jamie, jamie, netdev, linux-arm-kernel

On Fri, Jan 14, 2011 at 01:48:40PM +0800, Shawn Guo wrote:
> Hi Uwe,
> 
> On Thu, Jan 13, 2011 at 03:48:05PM +0100, Uwe Kleine-König wrote:
> 
> [...]
> 
> > > +/* Controller is ENET-MAC */
> > > +#define FEC_QUIRK_ENET_MAC           (1 << 0)
> > does this really qualify to be a quirk?
> > 
> My understanding is that ENET-MAC is a type of "quirky" FEC
> controller.
> 
> > > +/* Controller needs driver to swap frame */
> > > +#define FEC_QUIRK_SWAP_FRAME         (1 << 1)
> > IMHO this is a bit misnamed.  FEC_QUIRK_NEEDS_BE_DATA or similar would
> > be more accurate.
> > 
> When your make this change, you may want to pick a better name for
> function swap_buffer too.
> 
> [...]
> 
> > > +static void *swap_buffer(void *bufaddr, int len)
> > > +{
> > > +     int i;
> > > +     unsigned int *buf = bufaddr;
> > > +
> > > +     for (i = 0; i < (len + 3) / 4; i++, buf++)
> > > +             *buf = cpu_to_be32(*buf);
> > if len isn't a multiple of 4 this accesses bytes behind len.  Is this
> > generally OK here?  (E.g. because skbs always have a length that is a
> > multiple of 4?)
> The len may not be a multiple of 4.  But I believe bufaddr is always
> a buffer allocated in a length that is a multiple of 4, and the 1~3
> bytes exceeding the len very likely has no data that matters.  But
> yes, it deserves a safer implementation.
Did you test what happens if bufaddr isn't aligned?  Does it work at all
then?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
@ 2011-01-14  7:52         ` Uwe Kleine-König
  0 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-14  7:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jan 14, 2011 at 01:48:40PM +0800, Shawn Guo wrote:
> Hi Uwe,
> 
> On Thu, Jan 13, 2011 at 03:48:05PM +0100, Uwe Kleine-K?nig wrote:
> 
> [...]
> 
> > > +/* Controller is ENET-MAC */
> > > +#define FEC_QUIRK_ENET_MAC           (1 << 0)
> > does this really qualify to be a quirk?
> > 
> My understanding is that ENET-MAC is a type of "quirky" FEC
> controller.
> 
> > > +/* Controller needs driver to swap frame */
> > > +#define FEC_QUIRK_SWAP_FRAME         (1 << 1)
> > IMHO this is a bit misnamed.  FEC_QUIRK_NEEDS_BE_DATA or similar would
> > be more accurate.
> > 
> When your make this change, you may want to pick a better name for
> function swap_buffer too.
> 
> [...]
> 
> > > +static void *swap_buffer(void *bufaddr, int len)
> > > +{
> > > +     int i;
> > > +     unsigned int *buf = bufaddr;
> > > +
> > > +     for (i = 0; i < (len + 3) / 4; i++, buf++)
> > > +             *buf = cpu_to_be32(*buf);
> > if len isn't a multiple of 4 this accesses bytes behind len.  Is this
> > generally OK here?  (E.g. because skbs always have a length that is a
> > multiple of 4?)
> The len may not be a multiple of 4.  But I believe bufaddr is always
> a buffer allocated in a length that is a multiple of 4, and the 1~3
> bytes exceeding the len very likely has no data that matters.  But
> yes, it deserves a safer implementation.
Did you test what happens if bufaddr isn't aligned?  Does it work at all
then?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 08/10] ARM: mxs: add ocotp read function
  2011-01-13 15:19     ` Uwe Kleine-König
@ 2011-01-14  8:33       ` Sascha Hauer
  -1 siblings, 0 replies; 118+ messages in thread
From: Sascha Hauer @ 2011-01-14  8:33 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: Shawn Guo, gerg, B32542, netdev, jamie, baruch, w.sang, r64343,
	eric, bryan.wu, jamie, davem, linux-arm-kernel, lw

On Thu, Jan 13, 2011 at 04:19:39PM +0100, Uwe Kleine-König wrote:
> On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > ---
> > Changes for v4:
> >  - Call cpu_relax() during polling
> > 
> > Changes for v2:
> >  - Add mutex locking for mxs_read_ocotp()
> >  - Use type size_t for count and i
> >  - Add comment for clk_enable/disable skipping
> >  - Add ERROR bit clearing and polling step
> > 
> >  arch/arm/mach-mxs/Makefile              |    2 +-
> >  arch/arm/mach-mxs/include/mach/common.h |    1 +
> >  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
> >  3 files changed, 81 insertions(+), 1 deletions(-)
> >  create mode 100644 arch/arm/mach-mxs/ocotp.c
> > 
> > diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> > index 39d3f9c..f23ebbd 100644
> > --- a/arch/arm/mach-mxs/Makefile
> > +++ b/arch/arm/mach-mxs/Makefile
> > @@ -1,5 +1,5 @@
> >  # Common support
> > -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> > +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
> is it worth to make ocotp optional?  (and let evk select
> CONFIG_MXS_OCOTP)

I think not.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 08/10] ARM: mxs: add ocotp read function
@ 2011-01-14  8:33       ` Sascha Hauer
  0 siblings, 0 replies; 118+ messages in thread
From: Sascha Hauer @ 2011-01-14  8:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jan 13, 2011 at 04:19:39PM +0100, Uwe Kleine-K?nig wrote:
> On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > ---
> > Changes for v4:
> >  - Call cpu_relax() during polling
> > 
> > Changes for v2:
> >  - Add mutex locking for mxs_read_ocotp()
> >  - Use type size_t for count and i
> >  - Add comment for clk_enable/disable skipping
> >  - Add ERROR bit clearing and polling step
> > 
> >  arch/arm/mach-mxs/Makefile              |    2 +-
> >  arch/arm/mach-mxs/include/mach/common.h |    1 +
> >  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
> >  3 files changed, 81 insertions(+), 1 deletions(-)
> >  create mode 100644 arch/arm/mach-mxs/ocotp.c
> > 
> > diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> > index 39d3f9c..f23ebbd 100644
> > --- a/arch/arm/mach-mxs/Makefile
> > +++ b/arch/arm/mach-mxs/Makefile
> > @@ -1,5 +1,5 @@
> >  # Common support
> > -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> > +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
> is it worth to make ocotp optional?  (and let evk select
> CONFIG_MXS_OCOTP)

I think not.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH] ARM: mxs: pass fec device name via platform data
  2011-01-14  6:53       ` Shawn Guo
@ 2011-01-14  8:38         ` Uwe Kleine-König
  -1 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-14  8:38 UTC (permalink / raw)
  To: Shawn Guo
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw, w.sang,
	s.hauer, jamie, jamie, netdev, linux-arm-kernel

On Fri, Jan 14, 2011 at 02:53:20PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

> ---
>  arch/arm/mach-mxs/devices/platform-fec.c        |   11 ++++++-----
>  arch/arm/mach-mxs/include/mach/devices-common.h |    1 +
>  2 files changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
> index c42dff7..75eb26b 100644
> --- a/arch/arm/mach-mxs/devices/platform-fec.c
> +++ b/arch/arm/mach-mxs/devices/platform-fec.c
> @@ -10,20 +10,21 @@
>  #include <mach/mx28.h>
>  #include <mach/devices-common.h>
>  
> -#define mxs_fec_data_entry_single(soc, _id)				\
> +#define mxs_fec_data_entry_single(soc, _devid, _id)			\
>  	{								\
> +		.devid = _devid,					\
>  		.id = _id,						\
>  		.iobase = soc ## _ENET_MAC ## _id ## _BASE_ADDR,	\
>  		.irq = soc ## _INT_ENET_MAC ## _id,			\
>  	}
>  
> -#define mxs_fec_data_entry(soc, _id)					\
> -	[_id] = mxs_fec_data_entry_single(soc, _id)
> +#define mxs_fec_data_entry(soc, _devid, _id)				\
> +	[_id] = mxs_fec_data_entry_single(soc, _devid, _id)
>  
>  #ifdef CONFIG_SOC_IMX28
>  const struct mxs_fec_data mx28_fec_data[] __initconst = {
>  #define mx28_fec_data_entry(_id)					\
> -	mxs_fec_data_entry(MX28, _id)
> +	mxs_fec_data_entry(MX28, "imx28-fec", _id)
>  	mx28_fec_data_entry(0),
>  	mx28_fec_data_entry(1),
>  };
> @@ -45,6 +46,6 @@ struct platform_device *__init mxs_add_fec(
>  		},
>  	};
>  
> -	return mxs_add_platform_device("imx28-fec", data->id,
> +	return mxs_add_platform_device(data->devid, data->id,
>  			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
>  }
> diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
> index 6c3d1a1..10fbcfd 100644
> --- a/arch/arm/mach-mxs/include/mach/devices-common.h
> +++ b/arch/arm/mach-mxs/include/mach/devices-common.h
> @@ -33,6 +33,7 @@ int __init mxs_add_duart(const struct amba_device *dev);
>  /* fec */
>  #include <linux/fec.h>
>  struct mxs_fec_data {
> +	const char *devid;
>  	int id;
>  	resource_size_t iobase;
>  	resource_size_t iosize;
> -- 
> 1.7.1
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH] ARM: mxs: pass fec device name via platform data
@ 2011-01-14  8:38         ` Uwe Kleine-König
  0 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-14  8:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jan 14, 2011 at 02:53:20PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
Acked-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>

> ---
>  arch/arm/mach-mxs/devices/platform-fec.c        |   11 ++++++-----
>  arch/arm/mach-mxs/include/mach/devices-common.h |    1 +
>  2 files changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
> index c42dff7..75eb26b 100644
> --- a/arch/arm/mach-mxs/devices/platform-fec.c
> +++ b/arch/arm/mach-mxs/devices/platform-fec.c
> @@ -10,20 +10,21 @@
>  #include <mach/mx28.h>
>  #include <mach/devices-common.h>
>  
> -#define mxs_fec_data_entry_single(soc, _id)				\
> +#define mxs_fec_data_entry_single(soc, _devid, _id)			\
>  	{								\
> +		.devid = _devid,					\
>  		.id = _id,						\
>  		.iobase = soc ## _ENET_MAC ## _id ## _BASE_ADDR,	\
>  		.irq = soc ## _INT_ENET_MAC ## _id,			\
>  	}
>  
> -#define mxs_fec_data_entry(soc, _id)					\
> -	[_id] = mxs_fec_data_entry_single(soc, _id)
> +#define mxs_fec_data_entry(soc, _devid, _id)				\
> +	[_id] = mxs_fec_data_entry_single(soc, _devid, _id)
>  
>  #ifdef CONFIG_SOC_IMX28
>  const struct mxs_fec_data mx28_fec_data[] __initconst = {
>  #define mx28_fec_data_entry(_id)					\
> -	mxs_fec_data_entry(MX28, _id)
> +	mxs_fec_data_entry(MX28, "imx28-fec", _id)
>  	mx28_fec_data_entry(0),
>  	mx28_fec_data_entry(1),
>  };
> @@ -45,6 +46,6 @@ struct platform_device *__init mxs_add_fec(
>  		},
>  	};
>  
> -	return mxs_add_platform_device("imx28-fec", data->id,
> +	return mxs_add_platform_device(data->devid, data->id,
>  			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
>  }
> diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
> index 6c3d1a1..10fbcfd 100644
> --- a/arch/arm/mach-mxs/include/mach/devices-common.h
> +++ b/arch/arm/mach-mxs/include/mach/devices-common.h
> @@ -33,6 +33,7 @@ int __init mxs_add_duart(const struct amba_device *dev);
>  /* fec */
>  #include <linux/fec.h>
>  struct mxs_fec_data {
> +	const char *devid;
>  	int id;
>  	resource_size_t iobase;
>  	resource_size_t iosize;
> -- 
> 1.7.1
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v5 08/10] ARM: mxs: add ocotp read function
  2011-01-14  7:24   ` Shawn Guo
@ 2011-01-14  8:40     ` Sascha Hauer
  -1 siblings, 0 replies; 118+ messages in thread
From: Sascha Hauer @ 2011-01-14  8:40 UTC (permalink / raw)
  To: Shawn Guo
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw, w.sang,
	jamie, jamie, netdev, linux-arm-kernel

On Fri, Jan 14, 2011 at 03:24:54PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/Kconfig               |    4 ++
>  arch/arm/mach-mxs/Makefile              |    3 +
>  arch/arm/mach-mxs/include/mach/common.h |    1 +
>  arch/arm/mach-mxs/ocotp.c               |   90 +++++++++++++++++++++++++++++++
>  4 files changed, 98 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/ocotp.c
> 
> diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
> index 8bfc8df..cd2fbdf 100644
> --- a/arch/arm/mach-mxs/Kconfig
> +++ b/arch/arm/mach-mxs/Kconfig
> @@ -2,6 +2,9 @@ if ARCH_MXS
>  
>  source "arch/arm/mach-mxs/devices/Kconfig"
>  
> +config MXS_OCOTP
> +	bool
> +
>  config SOC_IMX23
>  	bool
>  	select CPU_ARM926T
> @@ -26,6 +29,7 @@ config MACH_MX28EVK
>  	select SOC_IMX28
>  	select MXS_HAVE_AMBA_DUART
>  	select MXS_HAVE_PLATFORM_FEC
> +	select MXS_OCOTP
>  	default y
>  	help
>  	  Include support for MX28EVK platform. This includes specific
> diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> index 39d3f9c..623899b 100644
> --- a/arch/arm/mach-mxs/Makefile
> +++ b/arch/arm/mach-mxs/Makefile
> @@ -1,6 +1,9 @@
>  # Common support
>  obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
>  
> +obj-$(CONFIG_PM) += pm.o
> +obj-$(CONFIG_MXS_OCOTP) += ocotp.o
> +
>  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
>  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
>  
> diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> index 59133eb..635bb5d 100644
> --- a/arch/arm/mach-mxs/include/mach/common.h
> +++ b/arch/arm/mach-mxs/include/mach/common.h
> @@ -13,6 +13,7 @@
>  
>  struct clk;
>  
> +extern const u32 *mxs_get_ocotp(void);
>  extern int mxs_reset_block(void __iomem *);
>  extern void mxs_timer_init(struct clk *, int);
>  
> diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> new file mode 100644
> index 0000000..eb2eab7
> --- /dev/null
> +++ b/arch/arm/mach-mxs/ocotp.c
> @@ -0,0 +1,90 @@
> +/*
> + * Copyright 2010 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 as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/mutex.h>
> +
> +#include <mach/mxs.h>
> +
> +#define OCOTP_WORD_OFFSET		0x20
> +#define OCOTP_WORD_COUNT		0x20
> +
> +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> +
> +static DEFINE_MUTEX(ocotp_mutex);
> +static u32 ocotp_words[OCOTP_WORD_COUNT];
> +
> +const u32 *mxs_get_ocotp(void)
> +{
> +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> +	int timeout = 0x400;
> +	size_t i;
> +	static int once = 0;
> +
> +	if (once)
> +		return ocotp_words;
> +
> +	mutex_lock(&ocotp_mutex);
> +
> +	/*
> +	 * clk_enable(hbus_clk) for ocotp can be skipped
> +	 * as it must be on when system is running.
> +	 */
> +
> +	/* try to clear ERROR bit */
> +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> +
> +	/* check both BUSY and ERROR cleared */
> +	while ((__raw_readl(ocotp_base) &
> +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> +		cpu_relax();
> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	/* open OCOTP banks for read */
> +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> +
> +	/* approximately wait 32 hclk cycles */
> +	udelay(1);
> +
> +	/* poll BUSY bit becoming cleared */
> +	timeout = 0x400;
> +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> +		cpu_relax();
> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	for (i = 0; i < OCOTP_WORD_COUNT; i++)
> +		ocotp_words[i] = __raw_readl(ocotp_base + OCOTP_WORD_OFFSET +
> +						i * 0x10);
> +
> +	/* close banks for power saving */
> +	__mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> +
> +	mutex_unlock(&ocotp_mutex);
> +
> +	once = 1;
> +
> +	return ocotp_words;
> +
> +error_unlock:
> +	mutex_unlock(&ocotp_mutex);
> +	pr_err("%s: timeout in reading OCOTP\n", __func__);
> +	return NULL;
> +}

EXPORT_SYMBOL?

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v5 08/10] ARM: mxs: add ocotp read function
@ 2011-01-14  8:40     ` Sascha Hauer
  0 siblings, 0 replies; 118+ messages in thread
From: Sascha Hauer @ 2011-01-14  8:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jan 14, 2011 at 03:24:54PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/Kconfig               |    4 ++
>  arch/arm/mach-mxs/Makefile              |    3 +
>  arch/arm/mach-mxs/include/mach/common.h |    1 +
>  arch/arm/mach-mxs/ocotp.c               |   90 +++++++++++++++++++++++++++++++
>  4 files changed, 98 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/ocotp.c
> 
> diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
> index 8bfc8df..cd2fbdf 100644
> --- a/arch/arm/mach-mxs/Kconfig
> +++ b/arch/arm/mach-mxs/Kconfig
> @@ -2,6 +2,9 @@ if ARCH_MXS
>  
>  source "arch/arm/mach-mxs/devices/Kconfig"
>  
> +config MXS_OCOTP
> +	bool
> +
>  config SOC_IMX23
>  	bool
>  	select CPU_ARM926T
> @@ -26,6 +29,7 @@ config MACH_MX28EVK
>  	select SOC_IMX28
>  	select MXS_HAVE_AMBA_DUART
>  	select MXS_HAVE_PLATFORM_FEC
> +	select MXS_OCOTP
>  	default y
>  	help
>  	  Include support for MX28EVK platform. This includes specific
> diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> index 39d3f9c..623899b 100644
> --- a/arch/arm/mach-mxs/Makefile
> +++ b/arch/arm/mach-mxs/Makefile
> @@ -1,6 +1,9 @@
>  # Common support
>  obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
>  
> +obj-$(CONFIG_PM) += pm.o
> +obj-$(CONFIG_MXS_OCOTP) += ocotp.o
> +
>  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
>  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
>  
> diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> index 59133eb..635bb5d 100644
> --- a/arch/arm/mach-mxs/include/mach/common.h
> +++ b/arch/arm/mach-mxs/include/mach/common.h
> @@ -13,6 +13,7 @@
>  
>  struct clk;
>  
> +extern const u32 *mxs_get_ocotp(void);
>  extern int mxs_reset_block(void __iomem *);
>  extern void mxs_timer_init(struct clk *, int);
>  
> diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> new file mode 100644
> index 0000000..eb2eab7
> --- /dev/null
> +++ b/arch/arm/mach-mxs/ocotp.c
> @@ -0,0 +1,90 @@
> +/*
> + * Copyright 2010 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 as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/mutex.h>
> +
> +#include <mach/mxs.h>
> +
> +#define OCOTP_WORD_OFFSET		0x20
> +#define OCOTP_WORD_COUNT		0x20
> +
> +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> +
> +static DEFINE_MUTEX(ocotp_mutex);
> +static u32 ocotp_words[OCOTP_WORD_COUNT];
> +
> +const u32 *mxs_get_ocotp(void)
> +{
> +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> +	int timeout = 0x400;
> +	size_t i;
> +	static int once = 0;
> +
> +	if (once)
> +		return ocotp_words;
> +
> +	mutex_lock(&ocotp_mutex);
> +
> +	/*
> +	 * clk_enable(hbus_clk) for ocotp can be skipped
> +	 * as it must be on when system is running.
> +	 */
> +
> +	/* try to clear ERROR bit */
> +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> +
> +	/* check both BUSY and ERROR cleared */
> +	while ((__raw_readl(ocotp_base) &
> +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> +		cpu_relax();
> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	/* open OCOTP banks for read */
> +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> +
> +	/* approximately wait 32 hclk cycles */
> +	udelay(1);
> +
> +	/* poll BUSY bit becoming cleared */
> +	timeout = 0x400;
> +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> +		cpu_relax();
> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	for (i = 0; i < OCOTP_WORD_COUNT; i++)
> +		ocotp_words[i] = __raw_readl(ocotp_base + OCOTP_WORD_OFFSET +
> +						i * 0x10);
> +
> +	/* close banks for power saving */
> +	__mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> +
> +	mutex_unlock(&ocotp_mutex);
> +
> +	once = 1;
> +
> +	return ocotp_words;
> +
> +error_unlock:
> +	mutex_unlock(&ocotp_mutex);
> +	pr_err("%s: timeout in reading OCOTP\n", __func__);
> +	return NULL;
> +}

EXPORT_SYMBOL?

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v5 08/10] ARM: mxs: add ocotp read function
  2011-01-14  7:24   ` Shawn Guo
@ 2011-01-14  8:42     ` Uwe Kleine-König
  -1 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-14  8:42 UTC (permalink / raw)
  To: Shawn Guo
  Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw, w.sang,
	s.hauer, jamie, jamie, netdev, linux-arm-kernel

On Fri, Jan 14, 2011 at 03:24:54PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/Kconfig               |    4 ++
>  arch/arm/mach-mxs/Makefile              |    3 +
>  arch/arm/mach-mxs/include/mach/common.h |    1 +
>  arch/arm/mach-mxs/ocotp.c               |   90 +++++++++++++++++++++++++++++++
>  4 files changed, 98 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/ocotp.c
> 
> diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
> index 8bfc8df..cd2fbdf 100644
> --- a/arch/arm/mach-mxs/Kconfig
> +++ b/arch/arm/mach-mxs/Kconfig
> @@ -2,6 +2,9 @@ if ARCH_MXS
>  
>  source "arch/arm/mach-mxs/devices/Kconfig"
>  
> +config MXS_OCOTP
> +	bool
> +
>  config SOC_IMX23
>  	bool
>  	select CPU_ARM926T
> @@ -26,6 +29,7 @@ config MACH_MX28EVK
>  	select SOC_IMX28
>  	select MXS_HAVE_AMBA_DUART
>  	select MXS_HAVE_PLATFORM_FEC
> +	select MXS_OCOTP
>  	default y
>  	help
>  	  Include support for MX28EVK platform. This includes specific
> diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> index 39d3f9c..623899b 100644
> --- a/arch/arm/mach-mxs/Makefile
> +++ b/arch/arm/mach-mxs/Makefile
> @@ -1,6 +1,9 @@
>  # Common support
>  obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
>  
> +obj-$(CONFIG_PM) += pm.o
this line doesn't belong here.

> +obj-$(CONFIG_MXS_OCOTP) += ocotp.o
> +
>  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
>  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
>  
> diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> index 59133eb..635bb5d 100644
> --- a/arch/arm/mach-mxs/include/mach/common.h
> +++ b/arch/arm/mach-mxs/include/mach/common.h
> @@ -13,6 +13,7 @@
>  
>  struct clk;
>  
> +extern const u32 *mxs_get_ocotp(void);
>  extern int mxs_reset_block(void __iomem *);
>  extern void mxs_timer_init(struct clk *, int);
>  
> diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> new file mode 100644
> index 0000000..eb2eab7
> --- /dev/null
> +++ b/arch/arm/mach-mxs/ocotp.c
> @@ -0,0 +1,90 @@
> +/*
> + * Copyright 2010 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 as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/mutex.h>
> +
> +#include <mach/mxs.h>
> +
> +#define OCOTP_WORD_OFFSET		0x20
> +#define OCOTP_WORD_COUNT		0x20
> +
> +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> +
> +static DEFINE_MUTEX(ocotp_mutex);
> +static u32 ocotp_words[OCOTP_WORD_COUNT];
> +
> +const u32 *mxs_get_ocotp(void)
> +{
> +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> +	int timeout = 0x400;
> +	size_t i;
> +	static int once = 0;
> +
> +	if (once)
> +		return ocotp_words;
> +
> +	mutex_lock(&ocotp_mutex);
> +
> +	/*
> +	 * clk_enable(hbus_clk) for ocotp can be skipped
> +	 * as it must be on when system is running.
> +	 */
> +
> +	/* try to clear ERROR bit */
> +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> +
> +	/* check both BUSY and ERROR cleared */
> +	while ((__raw_readl(ocotp_base) &
> +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> +		cpu_relax();
> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	/* open OCOTP banks for read */
> +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> +
> +	/* approximately wait 32 hclk cycles */
> +	udelay(1);
> +
> +	/* poll BUSY bit becoming cleared */
> +	timeout = 0x400;
> +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> +		cpu_relax();
> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	for (i = 0; i < OCOTP_WORD_COUNT; i++)
> +		ocotp_words[i] = __raw_readl(ocotp_base + OCOTP_WORD_OFFSET +
> +						i * 0x10);
> +
> +	/* close banks for power saving */
> +	__mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> +
> +	mutex_unlock(&ocotp_mutex);
> +
> +	once = 1;
once needs to be protected by the mutex, too.

Best regards
Uwe

> +
> +	return ocotp_words;
> +
> +error_unlock:
> +	mutex_unlock(&ocotp_mutex);
> +	pr_err("%s: timeout in reading OCOTP\n", __func__);
> +	return NULL;
> +}
> -- 
> 1.7.1
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v5 08/10] ARM: mxs: add ocotp read function
@ 2011-01-14  8:42     ` Uwe Kleine-König
  0 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-14  8:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jan 14, 2011 at 03:24:54PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/Kconfig               |    4 ++
>  arch/arm/mach-mxs/Makefile              |    3 +
>  arch/arm/mach-mxs/include/mach/common.h |    1 +
>  arch/arm/mach-mxs/ocotp.c               |   90 +++++++++++++++++++++++++++++++
>  4 files changed, 98 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/ocotp.c
> 
> diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
> index 8bfc8df..cd2fbdf 100644
> --- a/arch/arm/mach-mxs/Kconfig
> +++ b/arch/arm/mach-mxs/Kconfig
> @@ -2,6 +2,9 @@ if ARCH_MXS
>  
>  source "arch/arm/mach-mxs/devices/Kconfig"
>  
> +config MXS_OCOTP
> +	bool
> +
>  config SOC_IMX23
>  	bool
>  	select CPU_ARM926T
> @@ -26,6 +29,7 @@ config MACH_MX28EVK
>  	select SOC_IMX28
>  	select MXS_HAVE_AMBA_DUART
>  	select MXS_HAVE_PLATFORM_FEC
> +	select MXS_OCOTP
>  	default y
>  	help
>  	  Include support for MX28EVK platform. This includes specific
> diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> index 39d3f9c..623899b 100644
> --- a/arch/arm/mach-mxs/Makefile
> +++ b/arch/arm/mach-mxs/Makefile
> @@ -1,6 +1,9 @@
>  # Common support
>  obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
>  
> +obj-$(CONFIG_PM) += pm.o
this line doesn't belong here.

> +obj-$(CONFIG_MXS_OCOTP) += ocotp.o
> +
>  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
>  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
>  
> diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> index 59133eb..635bb5d 100644
> --- a/arch/arm/mach-mxs/include/mach/common.h
> +++ b/arch/arm/mach-mxs/include/mach/common.h
> @@ -13,6 +13,7 @@
>  
>  struct clk;
>  
> +extern const u32 *mxs_get_ocotp(void);
>  extern int mxs_reset_block(void __iomem *);
>  extern void mxs_timer_init(struct clk *, int);
>  
> diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> new file mode 100644
> index 0000000..eb2eab7
> --- /dev/null
> +++ b/arch/arm/mach-mxs/ocotp.c
> @@ -0,0 +1,90 @@
> +/*
> + * Copyright 2010 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 as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/mutex.h>
> +
> +#include <mach/mxs.h>
> +
> +#define OCOTP_WORD_OFFSET		0x20
> +#define OCOTP_WORD_COUNT		0x20
> +
> +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> +
> +static DEFINE_MUTEX(ocotp_mutex);
> +static u32 ocotp_words[OCOTP_WORD_COUNT];
> +
> +const u32 *mxs_get_ocotp(void)
> +{
> +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> +	int timeout = 0x400;
> +	size_t i;
> +	static int once = 0;
> +
> +	if (once)
> +		return ocotp_words;
> +
> +	mutex_lock(&ocotp_mutex);
> +
> +	/*
> +	 * clk_enable(hbus_clk) for ocotp can be skipped
> +	 * as it must be on when system is running.
> +	 */
> +
> +	/* try to clear ERROR bit */
> +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> +
> +	/* check both BUSY and ERROR cleared */
> +	while ((__raw_readl(ocotp_base) &
> +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> +		cpu_relax();
> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	/* open OCOTP banks for read */
> +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> +
> +	/* approximately wait 32 hclk cycles */
> +	udelay(1);
> +
> +	/* poll BUSY bit becoming cleared */
> +	timeout = 0x400;
> +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> +		cpu_relax();
> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	for (i = 0; i < OCOTP_WORD_COUNT; i++)
> +		ocotp_words[i] = __raw_readl(ocotp_base + OCOTP_WORD_OFFSET +
> +						i * 0x10);
> +
> +	/* close banks for power saving */
> +	__mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> +
> +	mutex_unlock(&ocotp_mutex);
> +
> +	once = 1;
once needs to be protected by the mutex, too.

Best regards
Uwe

> +
> +	return ocotp_words;
> +
> +error_unlock:
> +	mutex_unlock(&ocotp_mutex);
> +	pr_err("%s: timeout in reading OCOTP\n", __func__);
> +	return NULL;
> +}
> -- 
> 1.7.1
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v5 08/10] ARM: mxs: add ocotp read function
  2011-01-14  8:40     ` Sascha Hauer
@ 2011-01-14  9:48       ` Uwe Kleine-König
  -1 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-14  9:48 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Shawn Guo, gerg, B32542, netdev, jamie, baruch, w.sang, r64343,
	eric, bryan.wu, jamie, davem, linux-arm-kernel, lw

Hello Sascha,

On Fri, Jan 14, 2011 at 09:40:09AM +0100, Sascha Hauer wrote:
> On Fri, Jan 14, 2011 at 03:24:54PM +0800, Shawn Guo wrote:
> > +const u32 *mxs_get_ocotp(void)
> > +{
> > + [...]
> > +}
> 
> EXPORT_SYMBOL?
I don't think this should be necessary.  mxs_get_ocotp should only be
called from platform code that cannot (ot at least should not) be
modular.  I suggest to skip it for now and if we really need it later
only add it then.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v5 08/10] ARM: mxs: add ocotp read function
@ 2011-01-14  9:48       ` Uwe Kleine-König
  0 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-14  9:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Sascha,

On Fri, Jan 14, 2011 at 09:40:09AM +0100, Sascha Hauer wrote:
> On Fri, Jan 14, 2011 at 03:24:54PM +0800, Shawn Guo wrote:
> > +const u32 *mxs_get_ocotp(void)
> > +{
> > + [...]
> > +}
> 
> EXPORT_SYMBOL?
I don't think this should be necessary.  mxs_get_ocotp should only be
called from platform code that cannot (ot at least should not) be
modular.  I suggest to skip it for now and if we really need it later
only add it then.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 05/10] net/fec: add dual fec support for mx28
  2011-01-14  7:52         ` Uwe Kleine-König
@ 2011-01-14 13:08           ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14 13:08 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: gerg, B32542, netdev, s.hauer, jamie, baruch, w.sang, r64343,
	eric, bryan.wu, jamie, davem, linux-arm-kernel, lw

On Fri, Jan 14, 2011 at 08:52:23AM +0100, Uwe Kleine-König wrote:
> On Fri, Jan 14, 2011 at 01:48:40PM +0800, Shawn Guo wrote:
> > Hi Uwe,
> > 
> > On Thu, Jan 13, 2011 at 03:48:05PM +0100, Uwe Kleine-König wrote:
> > 
> > [...]
> > 
> > > > +/* Controller is ENET-MAC */
> > > > +#define FEC_QUIRK_ENET_MAC           (1 << 0)
> > > does this really qualify to be a quirk?
> > > 
> > My understanding is that ENET-MAC is a type of "quirky" FEC
> > controller.
> > 
> > > > +/* Controller needs driver to swap frame */
> > > > +#define FEC_QUIRK_SWAP_FRAME         (1 << 1)
> > > IMHO this is a bit misnamed.  FEC_QUIRK_NEEDS_BE_DATA or similar would
> > > be more accurate.
> > > 
> > When your make this change, you may want to pick a better name for
> > function swap_buffer too.
> > 
> > [...]
> > 
> > > > +static void *swap_buffer(void *bufaddr, int len)
> > > > +{
> > > > +     int i;
> > > > +     unsigned int *buf = bufaddr;
> > > > +
> > > > +     for (i = 0; i < (len + 3) / 4; i++, buf++)
> > > > +             *buf = cpu_to_be32(*buf);
> > > if len isn't a multiple of 4 this accesses bytes behind len.  Is this
> > > generally OK here?  (E.g. because skbs always have a length that is a
> > > multiple of 4?)
> > The len may not be a multiple of 4.  But I believe bufaddr is always
> > a buffer allocated in a length that is a multiple of 4, and the 1~3
> > bytes exceeding the len very likely has no data that matters.  But
> > yes, it deserves a safer implementation.
> Did you test what happens if bufaddr isn't aligned?  Does it work at all
> then?
> 
I see many calls passing a len that is not a multiple of 4, but it
works good.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
@ 2011-01-14 13:08           ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14 13:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jan 14, 2011 at 08:52:23AM +0100, Uwe Kleine-K?nig wrote:
> On Fri, Jan 14, 2011 at 01:48:40PM +0800, Shawn Guo wrote:
> > Hi Uwe,
> > 
> > On Thu, Jan 13, 2011 at 03:48:05PM +0100, Uwe Kleine-K?nig wrote:
> > 
> > [...]
> > 
> > > > +/* Controller is ENET-MAC */
> > > > +#define FEC_QUIRK_ENET_MAC           (1 << 0)
> > > does this really qualify to be a quirk?
> > > 
> > My understanding is that ENET-MAC is a type of "quirky" FEC
> > controller.
> > 
> > > > +/* Controller needs driver to swap frame */
> > > > +#define FEC_QUIRK_SWAP_FRAME         (1 << 1)
> > > IMHO this is a bit misnamed.  FEC_QUIRK_NEEDS_BE_DATA or similar would
> > > be more accurate.
> > > 
> > When your make this change, you may want to pick a better name for
> > function swap_buffer too.
> > 
> > [...]
> > 
> > > > +static void *swap_buffer(void *bufaddr, int len)
> > > > +{
> > > > +     int i;
> > > > +     unsigned int *buf = bufaddr;
> > > > +
> > > > +     for (i = 0; i < (len + 3) / 4; i++, buf++)
> > > > +             *buf = cpu_to_be32(*buf);
> > > if len isn't a multiple of 4 this accesses bytes behind len.  Is this
> > > generally OK here?  (E.g. because skbs always have a length that is a
> > > multiple of 4?)
> > The len may not be a multiple of 4.  But I believe bufaddr is always
> > a buffer allocated in a length that is a multiple of 4, and the 1~3
> > bytes exceeding the len very likely has no data that matters.  But
> > yes, it deserves a safer implementation.
> Did you test what happens if bufaddr isn't aligned?  Does it work at all
> then?
> 
I see many calls passing a len that is not a multiple of 4, but it
works good.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 08/10] ARM: mxs: add ocotp read function
  2011-01-14  8:33       ` Sascha Hauer
@ 2011-01-14 13:16         ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14 13:16 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: gerg, B32542, netdev, bryan.wu, jamie, baruch, w.sang, r64343,
	eric, Uwe Kleine-König, jamie, davem, linux-arm-kernel, lw

On Fri, Jan 14, 2011 at 09:33:20AM +0100, Sascha Hauer wrote:
> On Thu, Jan 13, 2011 at 04:19:39PM +0100, Uwe Kleine-König wrote:
> > On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > > ---
> > > Changes for v4:
> > >  - Call cpu_relax() during polling
> > > 
> > > Changes for v2:
> > >  - Add mutex locking for mxs_read_ocotp()
> > >  - Use type size_t for count and i
> > >  - Add comment for clk_enable/disable skipping
> > >  - Add ERROR bit clearing and polling step
> > > 
> > >  arch/arm/mach-mxs/Makefile              |    2 +-
> > >  arch/arm/mach-mxs/include/mach/common.h |    1 +
> > >  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
> > >  3 files changed, 81 insertions(+), 1 deletions(-)
> > >  create mode 100644 arch/arm/mach-mxs/ocotp.c
> > > 
> > > diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> > > index 39d3f9c..f23ebbd 100644
> > > --- a/arch/arm/mach-mxs/Makefile
> > > +++ b/arch/arm/mach-mxs/Makefile
> > > @@ -1,5 +1,5 @@
> > >  # Common support
> > > -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> > > +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
> > is it worth to make ocotp optional?  (and let evk select
> > CONFIG_MXS_OCOTP)
> 
> I think not.
> 
I thought it depends on how we think about it.  If we think that
ocotp is a block of soc and should be on every system based on
the soc, we should build it unconditional.  However, if we think
ocotp is a function that could either be used on a machine or not,
it should be built conditional, so that the machine does not use
ocotp function could save the ocotp build and the memory of
u32 ocotp_words[0x20].

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 08/10] ARM: mxs: add ocotp read function
@ 2011-01-14 13:16         ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14 13:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jan 14, 2011 at 09:33:20AM +0100, Sascha Hauer wrote:
> On Thu, Jan 13, 2011 at 04:19:39PM +0100, Uwe Kleine-K?nig wrote:
> > On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > > ---
> > > Changes for v4:
> > >  - Call cpu_relax() during polling
> > > 
> > > Changes for v2:
> > >  - Add mutex locking for mxs_read_ocotp()
> > >  - Use type size_t for count and i
> > >  - Add comment for clk_enable/disable skipping
> > >  - Add ERROR bit clearing and polling step
> > > 
> > >  arch/arm/mach-mxs/Makefile              |    2 +-
> > >  arch/arm/mach-mxs/include/mach/common.h |    1 +
> > >  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
> > >  3 files changed, 81 insertions(+), 1 deletions(-)
> > >  create mode 100644 arch/arm/mach-mxs/ocotp.c
> > > 
> > > diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> > > index 39d3f9c..f23ebbd 100644
> > > --- a/arch/arm/mach-mxs/Makefile
> > > +++ b/arch/arm/mach-mxs/Makefile
> > > @@ -1,5 +1,5 @@
> > >  # Common support
> > > -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> > > +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
> > is it worth to make ocotp optional?  (and let evk select
> > CONFIG_MXS_OCOTP)
> 
> I think not.
> 
I thought it depends on how we think about it.  If we think that
ocotp is a block of soc and should be on every system based on
the soc, we should build it unconditional.  However, if we think
ocotp is a function that could either be used on a machine or not,
it should be built conditional, so that the machine does not use
ocotp function could save the ocotp build and the memory of
u32 ocotp_words[0x20].

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v6 08/10] ARM: mxs: add ocotp read function
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-14 15:11   ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14 15:11 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig
  Cc: Shawn Guo

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/Kconfig               |    4 ++
 arch/arm/mach-mxs/Makefile              |    2 +
 arch/arm/mach-mxs/include/mach/common.h |    1 +
 arch/arm/mach-mxs/ocotp.c               |   90 +++++++++++++++++++++++++++++++
 4 files changed, 97 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/ocotp.c

diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index 8bfc8df..cd2fbdf 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -2,6 +2,9 @@ if ARCH_MXS
 
 source "arch/arm/mach-mxs/devices/Kconfig"
 
+config MXS_OCOTP
+	bool
+
 config SOC_IMX23
 	bool
 	select CPU_ARM926T
@@ -26,6 +29,7 @@ config MACH_MX28EVK
 	select SOC_IMX28
 	select MXS_HAVE_AMBA_DUART
 	select MXS_HAVE_PLATFORM_FEC
+	select MXS_OCOTP
 	default y
 	help
 	  Include support for MX28EVK platform. This includes specific
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 39d3f9c..df501a8 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,6 +1,8 @@
 # Common support
 obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
 
+obj-$(CONFIG_MXS_OCOTP) += ocotp.o
+
 obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
 obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
 
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
index 59133eb..635bb5d 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -13,6 +13,7 @@
 
 struct clk;
 
+extern const u32 *mxs_get_ocotp(void);
 extern int mxs_reset_block(void __iomem *);
 extern void mxs_timer_init(struct clk *, int);
 
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
new file mode 100644
index 0000000..65157a3
--- /dev/null
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2010 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+#include <mach/mxs.h>
+
+#define OCOTP_WORD_OFFSET		0x20
+#define OCOTP_WORD_COUNT		0x20
+
+#define BM_OCOTP_CTRL_BUSY		(1 << 8)
+#define BM_OCOTP_CTRL_ERROR		(1 << 9)
+#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
+
+static DEFINE_MUTEX(ocotp_mutex);
+static u32 ocotp_words[OCOTP_WORD_COUNT];
+
+const u32 *mxs_get_ocotp(void)
+{
+	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
+	int timeout = 0x400;
+	size_t i;
+	static int once = 0;
+
+	if (once)
+		return ocotp_words;
+
+	mutex_lock(&ocotp_mutex);
+
+	/*
+	 * clk_enable(hbus_clk) for ocotp can be skipped
+	 * as it must be on when system is running.
+	 */
+
+	/* try to clear ERROR bit */
+	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
+
+	/* check both BUSY and ERROR cleared */
+	while ((__raw_readl(ocotp_base) &
+		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
+		cpu_relax();
+
+	if (unlikely(!timeout))
+		goto error_unlock;
+
+	/* open OCOTP banks for read */
+	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+	/* approximately wait 32 hclk cycles */
+	udelay(1);
+
+	/* poll BUSY bit becoming cleared */
+	timeout = 0x400;
+	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
+		cpu_relax();
+
+	if (unlikely(!timeout))
+		goto error_unlock;
+
+	for (i = 0; i < OCOTP_WORD_COUNT; i++)
+		ocotp_words[i] = __raw_readl(ocotp_base + OCOTP_WORD_OFFSET +
+						i * 0x10);
+
+	/* close banks for power saving */
+	__mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+	once = 1;
+
+	mutex_unlock(&ocotp_mutex);
+
+	return ocotp_words;
+
+error_unlock:
+	mutex_unlock(&ocotp_mutex);
+	pr_err("%s: timeout in reading OCOTP\n", __func__);
+	return NULL;
+}
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v6 08/10] ARM: mxs: add ocotp read function
@ 2011-01-14 15:11   ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-14 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/Kconfig               |    4 ++
 arch/arm/mach-mxs/Makefile              |    2 +
 arch/arm/mach-mxs/include/mach/common.h |    1 +
 arch/arm/mach-mxs/ocotp.c               |   90 +++++++++++++++++++++++++++++++
 4 files changed, 97 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/ocotp.c

diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index 8bfc8df..cd2fbdf 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -2,6 +2,9 @@ if ARCH_MXS
 
 source "arch/arm/mach-mxs/devices/Kconfig"
 
+config MXS_OCOTP
+	bool
+
 config SOC_IMX23
 	bool
 	select CPU_ARM926T
@@ -26,6 +29,7 @@ config MACH_MX28EVK
 	select SOC_IMX28
 	select MXS_HAVE_AMBA_DUART
 	select MXS_HAVE_PLATFORM_FEC
+	select MXS_OCOTP
 	default y
 	help
 	  Include support for MX28EVK platform. This includes specific
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 39d3f9c..df501a8 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,6 +1,8 @@
 # Common support
 obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
 
+obj-$(CONFIG_MXS_OCOTP) += ocotp.o
+
 obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
 obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
 
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
index 59133eb..635bb5d 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -13,6 +13,7 @@
 
 struct clk;
 
+extern const u32 *mxs_get_ocotp(void);
 extern int mxs_reset_block(void __iomem *);
 extern void mxs_timer_init(struct clk *, int);
 
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
new file mode 100644
index 0000000..65157a3
--- /dev/null
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2010 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+#include <mach/mxs.h>
+
+#define OCOTP_WORD_OFFSET		0x20
+#define OCOTP_WORD_COUNT		0x20
+
+#define BM_OCOTP_CTRL_BUSY		(1 << 8)
+#define BM_OCOTP_CTRL_ERROR		(1 << 9)
+#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
+
+static DEFINE_MUTEX(ocotp_mutex);
+static u32 ocotp_words[OCOTP_WORD_COUNT];
+
+const u32 *mxs_get_ocotp(void)
+{
+	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
+	int timeout = 0x400;
+	size_t i;
+	static int once = 0;
+
+	if (once)
+		return ocotp_words;
+
+	mutex_lock(&ocotp_mutex);
+
+	/*
+	 * clk_enable(hbus_clk) for ocotp can be skipped
+	 * as it must be on when system is running.
+	 */
+
+	/* try to clear ERROR bit */
+	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
+
+	/* check both BUSY and ERROR cleared */
+	while ((__raw_readl(ocotp_base) &
+		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
+		cpu_relax();
+
+	if (unlikely(!timeout))
+		goto error_unlock;
+
+	/* open OCOTP banks for read */
+	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+	/* approximately wait 32 hclk cycles */
+	udelay(1);
+
+	/* poll BUSY bit becoming cleared */
+	timeout = 0x400;
+	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
+		cpu_relax();
+
+	if (unlikely(!timeout))
+		goto error_unlock;
+
+	for (i = 0; i < OCOTP_WORD_COUNT; i++)
+		ocotp_words[i] = __raw_readl(ocotp_base + OCOTP_WORD_OFFSET +
+						i * 0x10);
+
+	/* close banks for power saving */
+	__mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+	once = 1;
+
+	mutex_unlock(&ocotp_mutex);
+
+	return ocotp_words;
+
+error_unlock:
+	mutex_unlock(&ocotp_mutex);
+	pr_err("%s: timeout in reading OCOTP\n", __func__);
+	return NULL;
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 05/10] net/fec: add dual fec support for mx28
  2011-01-14 13:08           ` Shawn Guo
@ 2011-01-17  8:16             ` Lothar Waßmann
  -1 siblings, 0 replies; 118+ messages in thread
From: Lothar Waßmann @ 2011-01-17  8:16 UTC (permalink / raw)
  To: Shawn Guo
  Cc: gerg, B32542, netdev, s.hauer, bryan.wu, jamie, baruch, w.sang,
	r64343, eric, Uwe Kleine-König, jamie, davem,
	linux-arm-kernel

Hi,

Shawn Guo writes:
> On Fri, Jan 14, 2011 at 08:52:23AM +0100, Uwe Kleine-König wrote:
> > On Fri, Jan 14, 2011 at 01:48:40PM +0800, Shawn Guo wrote:
> > > Hi Uwe,
> > > 
> > > On Thu, Jan 13, 2011 at 03:48:05PM +0100, Uwe Kleine-König wrote:
> > > 
> > > [...]
> > > 
> > > > > +/* Controller is ENET-MAC */
> > > > > +#define FEC_QUIRK_ENET_MAC           (1 << 0)
> > > > does this really qualify to be a quirk?
> > > > 
> > > My understanding is that ENET-MAC is a type of "quirky" FEC
> > > controller.
> > > 
> > > > > +/* Controller needs driver to swap frame */
> > > > > +#define FEC_QUIRK_SWAP_FRAME         (1 << 1)
> > > > IMHO this is a bit misnamed.  FEC_QUIRK_NEEDS_BE_DATA or similar would
> > > > be more accurate.
> > > > 
> > > When your make this change, you may want to pick a better name for
> > > function swap_buffer too.
> > > 
> > > [...]
> > > 
> > > > > +static void *swap_buffer(void *bufaddr, int len)
> > > > > +{
> > > > > +     int i;
> > > > > +     unsigned int *buf = bufaddr;
> > > > > +
> > > > > +     for (i = 0; i < (len + 3) / 4; i++, buf++)
> > > > > +             *buf = cpu_to_be32(*buf);
> > > > if len isn't a multiple of 4 this accesses bytes behind len.  Is this
> > > > generally OK here?  (E.g. because skbs always have a length that is a
> > > > multiple of 4?)
> > > The len may not be a multiple of 4.  But I believe bufaddr is always
> > > a buffer allocated in a length that is a multiple of 4, and the 1~3
> > > bytes exceeding the len very likely has no data that matters.  But
> > > yes, it deserves a safer implementation.
> > Did you test what happens if bufaddr isn't aligned?  Does it work at all
> > then?
> > 
> I see many calls passing a len that is not a multiple of 4, but it
> works good.
> 
That does not prove anything, actually.

Anyway "bufaddr isn't aligned" != "len is not a multiple of 4".
Is there any guarantee that the function cannot be called with a
non-aligned buffer address?


Lothar Waßmann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstraße 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Geschäftsführer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info@karo-electronics.de
___________________________________________________________

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
@ 2011-01-17  8:16             ` Lothar Waßmann
  0 siblings, 0 replies; 118+ messages in thread
From: Lothar Waßmann @ 2011-01-17  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Shawn Guo writes:
> On Fri, Jan 14, 2011 at 08:52:23AM +0100, Uwe Kleine-K?nig wrote:
> > On Fri, Jan 14, 2011 at 01:48:40PM +0800, Shawn Guo wrote:
> > > Hi Uwe,
> > > 
> > > On Thu, Jan 13, 2011 at 03:48:05PM +0100, Uwe Kleine-K?nig wrote:
> > > 
> > > [...]
> > > 
> > > > > +/* Controller is ENET-MAC */
> > > > > +#define FEC_QUIRK_ENET_MAC           (1 << 0)
> > > > does this really qualify to be a quirk?
> > > > 
> > > My understanding is that ENET-MAC is a type of "quirky" FEC
> > > controller.
> > > 
> > > > > +/* Controller needs driver to swap frame */
> > > > > +#define FEC_QUIRK_SWAP_FRAME         (1 << 1)
> > > > IMHO this is a bit misnamed.  FEC_QUIRK_NEEDS_BE_DATA or similar would
> > > > be more accurate.
> > > > 
> > > When your make this change, you may want to pick a better name for
> > > function swap_buffer too.
> > > 
> > > [...]
> > > 
> > > > > +static void *swap_buffer(void *bufaddr, int len)
> > > > > +{
> > > > > +     int i;
> > > > > +     unsigned int *buf = bufaddr;
> > > > > +
> > > > > +     for (i = 0; i < (len + 3) / 4; i++, buf++)
> > > > > +             *buf = cpu_to_be32(*buf);
> > > > if len isn't a multiple of 4 this accesses bytes behind len.  Is this
> > > > generally OK here?  (E.g. because skbs always have a length that is a
> > > > multiple of 4?)
> > > The len may not be a multiple of 4.  But I believe bufaddr is always
> > > a buffer allocated in a length that is a multiple of 4, and the 1~3
> > > bytes exceeding the len very likely has no data that matters.  But
> > > yes, it deserves a safer implementation.
> > Did you test what happens if bufaddr isn't aligned?  Does it work at all
> > then?
> > 
> I see many calls passing a len that is not a multiple of 4, but it
> works good.
> 
That does not prove anything, actually.

Anyway "bufaddr isn't aligned" != "len is not a multiple of 4".
Is there any guarantee that the function cannot be called with a
non-aligned buffer address?


Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 05/10] net/fec: add dual fec support for mx28
  2011-01-17  8:16             ` Lothar Waßmann
@ 2011-01-17  8:42               ` Uwe Kleine-König
  -1 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-17  8:42 UTC (permalink / raw)
  To: Lothar Waßmann
  Cc: Shawn Guo, gerg, B32542, netdev, s.hauer, jamie, baruch, w.sang,
	r64343, eric, bryan.wu, jamie, davem, linux-arm-kernel

Hi,

On Mon, Jan 17, 2011 at 09:16:22AM +0100, Lothar Waßmann wrote:
> Shawn Guo writes:
> > On Fri, Jan 14, 2011 at 08:52:23AM +0100, Uwe Kleine-König wrote:
> > > On Fri, Jan 14, 2011 at 01:48:40PM +0800, Shawn Guo wrote:
> > > > Hi Uwe,
> > > > 
> > > > On Thu, Jan 13, 2011 at 03:48:05PM +0100, Uwe Kleine-König wrote:
> > > > 
> > > > [...]
> > > > 
> > > > > > +/* Controller is ENET-MAC */
> > > > > > +#define FEC_QUIRK_ENET_MAC           (1 << 0)
> > > > > does this really qualify to be a quirk?
> > > > > 
> > > > My understanding is that ENET-MAC is a type of "quirky" FEC
> > > > controller.
> > > > 
> > > > > > +/* Controller needs driver to swap frame */
> > > > > > +#define FEC_QUIRK_SWAP_FRAME         (1 << 1)
> > > > > IMHO this is a bit misnamed.  FEC_QUIRK_NEEDS_BE_DATA or similar would
> > > > > be more accurate.
> > > > > 
> > > > When your make this change, you may want to pick a better name for
> > > > function swap_buffer too.
> > > > 
> > > > [...]
> > > > 
> > > > > > +static void *swap_buffer(void *bufaddr, int len)
> > > > > > +{
> > > > > > +     int i;
> > > > > > +     unsigned int *buf = bufaddr;
> > > > > > +
> > > > > > +     for (i = 0; i < (len + 3) / 4; i++, buf++)
> > > > > > +             *buf = cpu_to_be32(*buf);
> > > > > if len isn't a multiple of 4 this accesses bytes behind len.  Is this
> > > > > generally OK here?  (E.g. because skbs always have a length that is a
> > > > > multiple of 4?)
> > > > The len may not be a multiple of 4.  But I believe bufaddr is always
> > > > a buffer allocated in a length that is a multiple of 4, and the 1~3
> > > > bytes exceeding the len very likely has no data that matters.  But
> > > > yes, it deserves a safer implementation.
> > > Did you test what happens if bufaddr isn't aligned?  Does it work at all
> > > then?
> > > 
> > I see many calls passing a len that is not a multiple of 4, but it
> > works good.
> > 
> That does not prove anything, actually.
> 
> Anyway "bufaddr isn't aligned" != "len is not a multiple of 4".
> Is there any guarantee that the function cannot be called with a
> non-aligned buffer address?
Over the weekend I wondered if we could reach alignment via a dma-mask
setting.  Didn't check yet how this is configured.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
@ 2011-01-17  8:42               ` Uwe Kleine-König
  0 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-17  8:42 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Mon, Jan 17, 2011 at 09:16:22AM +0100, Lothar Wa?mann wrote:
> Shawn Guo writes:
> > On Fri, Jan 14, 2011 at 08:52:23AM +0100, Uwe Kleine-K?nig wrote:
> > > On Fri, Jan 14, 2011 at 01:48:40PM +0800, Shawn Guo wrote:
> > > > Hi Uwe,
> > > > 
> > > > On Thu, Jan 13, 2011 at 03:48:05PM +0100, Uwe Kleine-K?nig wrote:
> > > > 
> > > > [...]
> > > > 
> > > > > > +/* Controller is ENET-MAC */
> > > > > > +#define FEC_QUIRK_ENET_MAC           (1 << 0)
> > > > > does this really qualify to be a quirk?
> > > > > 
> > > > My understanding is that ENET-MAC is a type of "quirky" FEC
> > > > controller.
> > > > 
> > > > > > +/* Controller needs driver to swap frame */
> > > > > > +#define FEC_QUIRK_SWAP_FRAME         (1 << 1)
> > > > > IMHO this is a bit misnamed.  FEC_QUIRK_NEEDS_BE_DATA or similar would
> > > > > be more accurate.
> > > > > 
> > > > When your make this change, you may want to pick a better name for
> > > > function swap_buffer too.
> > > > 
> > > > [...]
> > > > 
> > > > > > +static void *swap_buffer(void *bufaddr, int len)
> > > > > > +{
> > > > > > +     int i;
> > > > > > +     unsigned int *buf = bufaddr;
> > > > > > +
> > > > > > +     for (i = 0; i < (len + 3) / 4; i++, buf++)
> > > > > > +             *buf = cpu_to_be32(*buf);
> > > > > if len isn't a multiple of 4 this accesses bytes behind len.  Is this
> > > > > generally OK here?  (E.g. because skbs always have a length that is a
> > > > > multiple of 4?)
> > > > The len may not be a multiple of 4.  But I believe bufaddr is always
> > > > a buffer allocated in a length that is a multiple of 4, and the 1~3
> > > > bytes exceeding the len very likely has no data that matters.  But
> > > > yes, it deserves a safer implementation.
> > > Did you test what happens if bufaddr isn't aligned?  Does it work at all
> > > then?
> > > 
> > I see many calls passing a len that is not a multiple of 4, but it
> > works good.
> > 
> That does not prove anything, actually.
> 
> Anyway "bufaddr isn't aligned" != "len is not a multiple of 4".
> Is there any guarantee that the function cannot be called with a
> non-aligned buffer address?
Over the weekend I wondered if we could reach alignment via a dma-mask
setting.  Didn't check yet how this is configured.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 05/10] net/fec: add dual fec support for mx28
  2011-01-13 14:48     ` Uwe Kleine-König
@ 2011-01-17  9:06       ` Uwe Kleine-König
  -1 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-17  9:06 UTC (permalink / raw)
  To: Shawn Guo
  Cc: gerg, Greg Ungerer, B32542, netdev, s.hauer, jamie, baruch,
	w.sang, r64343, eric, bryan.wu, jamie, davem, linux-arm-kernel,
	lw

Hello,

On Thu, Jan 13, 2011 at 03:48:05PM +0100, Uwe Kleine-König wrote:
> >  #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
> > -    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
> > +    defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
> > +    defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
> I wonder what is excluded here.  FEC depends on
> 
> 	M523x || M527x || M5272 || M528x || M520x || M532x || \
> 	MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
> 
> so the only difference is that the latter lists M5272 which seems a bit
> redundant in the presence of M527x.
M527x = {M5271, M5275}, so it seems to me that only M5272 is excluded
here.  I don't know if it's possible to have a kernel supporting M5272
and (e.g.) M527x.  If yes, does the driver work correct on M5272 then?

Greg, it seems to me that M5272 is the exception here, not all the
others.  Would it make sense to make the above read:

	#if !defined(CONFIG_M5272)

?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
@ 2011-01-17  9:06       ` Uwe Kleine-König
  0 siblings, 0 replies; 118+ messages in thread
From: Uwe Kleine-König @ 2011-01-17  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Thu, Jan 13, 2011 at 03:48:05PM +0100, Uwe Kleine-K?nig wrote:
> >  #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
> > -    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
> > +    defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
> > +    defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
> I wonder what is excluded here.  FEC depends on
> 
> 	M523x || M527x || M5272 || M528x || M520x || M532x || \
> 	MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
> 
> so the only difference is that the latter lists M5272 which seems a bit
> redundant in the presence of M527x.
M527x = {M5271, M5275}, so it seems to me that only M5272 is excluded
here.  I don't know if it's possible to have a kernel supporting M5272
and (e.g.) M527x.  If yes, does the driver work correct on M5272 then?

Greg, it seems to me that M5272 is the exception here, not all the
others.  Would it make sense to make the above read:

	#if !defined(CONFIG_M5272)

?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 05/10] net/fec: add dual fec support for mx28
  2011-01-17  8:16             ` Lothar Waßmann
@ 2011-01-17 11:52               ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-17 11:52 UTC (permalink / raw)
  To: Lothar Waßmann
  Cc: Uwe Kleine-König, gerg, B32542, netdev, s.hauer, jamie,
	baruch, w.sang, r64343, eric, bryan.wu, jamie, davem,
	linux-arm-kernel

Hi Lothar,

On Mon, Jan 17, 2011 at 09:16:22AM +0100, Lothar Waßmann wrote:
> Hi,
> 
> Shawn Guo writes:
> > On Fri, Jan 14, 2011 at 08:52:23AM +0100, Uwe Kleine-König wrote:
> > > On Fri, Jan 14, 2011 at 01:48:40PM +0800, Shawn Guo wrote:
> > > > Hi Uwe,
> > > > 
> > > > On Thu, Jan 13, 2011 at 03:48:05PM +0100, Uwe Kleine-König wrote:
> > > > 
> > > > [...]
> > > > 
> > > > > > +/* Controller is ENET-MAC */
> > > > > > +#define FEC_QUIRK_ENET_MAC           (1 << 0)
> > > > > does this really qualify to be a quirk?
> > > > > 
> > > > My understanding is that ENET-MAC is a type of "quirky" FEC
> > > > controller.
> > > > 
> > > > > > +/* Controller needs driver to swap frame */
> > > > > > +#define FEC_QUIRK_SWAP_FRAME         (1 << 1)
> > > > > IMHO this is a bit misnamed.  FEC_QUIRK_NEEDS_BE_DATA or similar would
> > > > > be more accurate.
> > > > > 
> > > > When your make this change, you may want to pick a better name for
> > > > function swap_buffer too.
> > > > 
> > > > [...]
> > > > 
> > > > > > +static void *swap_buffer(void *bufaddr, int len)
> > > > > > +{
> > > > > > +     int i;
> > > > > > +     unsigned int *buf = bufaddr;
> > > > > > +
> > > > > > +     for (i = 0; i < (len + 3) / 4; i++, buf++)
> > > > > > +             *buf = cpu_to_be32(*buf);
> > > > > if len isn't a multiple of 4 this accesses bytes behind len.  Is this
> > > > > generally OK here?  (E.g. because skbs always have a length that is a
> > > > > multiple of 4?)
> > > > The len may not be a multiple of 4.  But I believe bufaddr is always
> > > > a buffer allocated in a length that is a multiple of 4, and the 1~3
> > > > bytes exceeding the len very likely has no data that matters.  But
> > > > yes, it deserves a safer implementation.
> > > Did you test what happens if bufaddr isn't aligned?  Does it work at all
> > > then?
> > > 
> > I see many calls passing a len that is not a multiple of 4, but it
> > works good.
> > 
> That does not prove anything, actually.
> 
> Anyway "bufaddr isn't aligned" != "len is not a multiple of 4".
> Is there any guarantee that the function cannot be called with a
> non-aligned buffer address?
> 
Oops, I misunderstood the comment.  With bounce buffer alignment
handling removed, the driver stops working.  But at least, mx28
fec driver can work with FEC_ALIGNMENT 0x3 and not necessarily with
0xf. 

I hope this is what you intended to know.

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
@ 2011-01-17 11:52               ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-17 11:52 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lothar,

On Mon, Jan 17, 2011 at 09:16:22AM +0100, Lothar Wa?mann wrote:
> Hi,
> 
> Shawn Guo writes:
> > On Fri, Jan 14, 2011 at 08:52:23AM +0100, Uwe Kleine-K?nig wrote:
> > > On Fri, Jan 14, 2011 at 01:48:40PM +0800, Shawn Guo wrote:
> > > > Hi Uwe,
> > > > 
> > > > On Thu, Jan 13, 2011 at 03:48:05PM +0100, Uwe Kleine-K?nig wrote:
> > > > 
> > > > [...]
> > > > 
> > > > > > +/* Controller is ENET-MAC */
> > > > > > +#define FEC_QUIRK_ENET_MAC           (1 << 0)
> > > > > does this really qualify to be a quirk?
> > > > > 
> > > > My understanding is that ENET-MAC is a type of "quirky" FEC
> > > > controller.
> > > > 
> > > > > > +/* Controller needs driver to swap frame */
> > > > > > +#define FEC_QUIRK_SWAP_FRAME         (1 << 1)
> > > > > IMHO this is a bit misnamed.  FEC_QUIRK_NEEDS_BE_DATA or similar would
> > > > > be more accurate.
> > > > > 
> > > > When your make this change, you may want to pick a better name for
> > > > function swap_buffer too.
> > > > 
> > > > [...]
> > > > 
> > > > > > +static void *swap_buffer(void *bufaddr, int len)
> > > > > > +{
> > > > > > +     int i;
> > > > > > +     unsigned int *buf = bufaddr;
> > > > > > +
> > > > > > +     for (i = 0; i < (len + 3) / 4; i++, buf++)
> > > > > > +             *buf = cpu_to_be32(*buf);
> > > > > if len isn't a multiple of 4 this accesses bytes behind len.  Is this
> > > > > generally OK here?  (E.g. because skbs always have a length that is a
> > > > > multiple of 4?)
> > > > The len may not be a multiple of 4.  But I believe bufaddr is always
> > > > a buffer allocated in a length that is a multiple of 4, and the 1~3
> > > > bytes exceeding the len very likely has no data that matters.  But
> > > > yes, it deserves a safer implementation.
> > > Did you test what happens if bufaddr isn't aligned?  Does it work at all
> > > then?
> > > 
> > I see many calls passing a len that is not a multiple of 4, but it
> > works good.
> > 
> That does not prove anything, actually.
> 
> Anyway "bufaddr isn't aligned" != "len is not a multiple of 4".
> Is there any guarantee that the function cannot be called with a
> non-aligned buffer address?
> 
Oops, I misunderstood the comment.  With bounce buffer alignment
handling removed, the driver stops working.  But at least, mx28
fec driver can work with FEC_ALIGNMENT 0x3 and not necessarily with
0xf. 

I hope this is what you intended to know.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v4 08/10] ARM: mxs: add ocotp read function
  2011-01-14 13:16         ` Shawn Guo
@ 2011-01-19 10:48           ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-19 10:48 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: gerg, B32542, netdev, bryan.wu, jamie, baruch, w.sang, r64343,
	eric, Uwe Kleine-König, jamie, davem, linux-arm-kernel, lw

Hi Sascha,

On Fri, Jan 14, 2011 at 09:16:56PM +0800, Shawn Guo wrote:
> On Fri, Jan 14, 2011 at 09:33:20AM +0100, Sascha Hauer wrote:
> > On Thu, Jan 13, 2011 at 04:19:39PM +0100, Uwe Kleine-König wrote:
> > > On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> > > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > > > ---
> > > > Changes for v4:
> > > >  - Call cpu_relax() during polling
> > > > 
> > > > Changes for v2:
> > > >  - Add mutex locking for mxs_read_ocotp()
> > > >  - Use type size_t for count and i
> > > >  - Add comment for clk_enable/disable skipping
> > > >  - Add ERROR bit clearing and polling step
> > > > 
> > > >  arch/arm/mach-mxs/Makefile              |    2 +-
> > > >  arch/arm/mach-mxs/include/mach/common.h |    1 +
> > > >  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
> > > >  3 files changed, 81 insertions(+), 1 deletions(-)
> > > >  create mode 100644 arch/arm/mach-mxs/ocotp.c
> > > > 
> > > > diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> > > > index 39d3f9c..f23ebbd 100644
> > > > --- a/arch/arm/mach-mxs/Makefile
> > > > +++ b/arch/arm/mach-mxs/Makefile
> > > > @@ -1,5 +1,5 @@
> > > >  # Common support
> > > > -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> > > > +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
> > > is it worth to make ocotp optional?  (and let evk select
> > > CONFIG_MXS_OCOTP)
> > 
> > I think not.
> > 
> I thought it depends on how we think about it.  If we think that
> ocotp is a block of soc and should be on every system based on
> the soc, we should build it unconditional.  However, if we think
> ocotp is a function that could either be used on a machine or not,
> it should be built conditional, so that the machine does not use
> ocotp function could save the ocotp build and the memory of
> u32 ocotp_words[0x20].
> 
You've not merged patch #8, #9, #10, so you still think
CONFIG_MXS_OCOTP should not be added?

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v4 08/10] ARM: mxs: add ocotp read function
@ 2011-01-19 10:48           ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-19 10:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sascha,

On Fri, Jan 14, 2011 at 09:16:56PM +0800, Shawn Guo wrote:
> On Fri, Jan 14, 2011 at 09:33:20AM +0100, Sascha Hauer wrote:
> > On Thu, Jan 13, 2011 at 04:19:39PM +0100, Uwe Kleine-K?nig wrote:
> > > On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> > > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > > > ---
> > > > Changes for v4:
> > > >  - Call cpu_relax() during polling
> > > > 
> > > > Changes for v2:
> > > >  - Add mutex locking for mxs_read_ocotp()
> > > >  - Use type size_t for count and i
> > > >  - Add comment for clk_enable/disable skipping
> > > >  - Add ERROR bit clearing and polling step
> > > > 
> > > >  arch/arm/mach-mxs/Makefile              |    2 +-
> > > >  arch/arm/mach-mxs/include/mach/common.h |    1 +
> > > >  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
> > > >  3 files changed, 81 insertions(+), 1 deletions(-)
> > > >  create mode 100644 arch/arm/mach-mxs/ocotp.c
> > > > 
> > > > diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> > > > index 39d3f9c..f23ebbd 100644
> > > > --- a/arch/arm/mach-mxs/Makefile
> > > > +++ b/arch/arm/mach-mxs/Makefile
> > > > @@ -1,5 +1,5 @@
> > > >  # Common support
> > > > -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> > > > +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
> > > is it worth to make ocotp optional?  (and let evk select
> > > CONFIG_MXS_OCOTP)
> > 
> > I think not.
> > 
> I thought it depends on how we think about it.  If we think that
> ocotp is a block of soc and should be on every system based on
> the soc, we should build it unconditional.  However, if we think
> ocotp is a function that could either be used on a machine or not,
> it should be built conditional, so that the machine does not use
> ocotp function could save the ocotp build and the memory of
> u32 ocotp_words[0x20].
> 
You've not merged patch #8, #9, #10, so you still think
CONFIG_MXS_OCOTP should not be added?

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v5] ARM: mxs: add initial pm support
  2011-01-06  7:13 ` Shawn Guo
@ 2011-01-24  9:05   ` Shawn Guo
  -1 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-24  9:05 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, u.kleine-koenig
  Cc: Shawn Guo

This is a very initial pm support and basically does nothing.
With this pm support entry, drivers can start testing their own
pm functions.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Hi Sascha,

The merging conflict was fixed in this version, and you can pick it
up on imx-for-2.6.39 branch now.

 arch/arm/mach-mxs/Makefile |    1 +
 arch/arm/mach-mxs/pm.c     |   43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/pm.c

diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index df501a8..6b26f02 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -2,6 +2,7 @@
 obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
 
 obj-$(CONFIG_MXS_OCOTP) += ocotp.o
+obj-$(CONFIG_PM) += pm.o
 
 obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
 obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
diff --git a/arch/arm/mach-mxs/pm.c b/arch/arm/mach-mxs/pm.c
new file mode 100644
index 0000000..fb042da
--- /dev/null
+++ b/arch/arm/mach-mxs/pm.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+#include <linux/io.h>
+#include <mach/system.h>
+
+static int mxs_suspend_enter(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_MEM:
+		arch_idle();
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static struct platform_suspend_ops mxs_suspend_ops = {
+	.enter = mxs_suspend_enter,
+	.valid = suspend_valid_only_mem,
+};
+
+static int __init mxs_pm_init(void)
+{
+	suspend_set_ops(&mxs_suspend_ops);
+	return 0;
+}
+device_initcall(mxs_pm_init);
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 118+ messages in thread

* [PATCH v5] ARM: mxs: add initial pm support
@ 2011-01-24  9:05   ` Shawn Guo
  0 siblings, 0 replies; 118+ messages in thread
From: Shawn Guo @ 2011-01-24  9:05 UTC (permalink / raw)
  To: linux-arm-kernel

This is a very initial pm support and basically does nothing.
With this pm support entry, drivers can start testing their own
pm functions.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Hi Sascha,

The merging conflict was fixed in this version, and you can pick it
up on imx-for-2.6.39 branch now.

 arch/arm/mach-mxs/Makefile |    1 +
 arch/arm/mach-mxs/pm.c     |   43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/pm.c

diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index df501a8..6b26f02 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -2,6 +2,7 @@
 obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
 
 obj-$(CONFIG_MXS_OCOTP) += ocotp.o
+obj-$(CONFIG_PM) += pm.o
 
 obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
 obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
diff --git a/arch/arm/mach-mxs/pm.c b/arch/arm/mach-mxs/pm.c
new file mode 100644
index 0000000..fb042da
--- /dev/null
+++ b/arch/arm/mach-mxs/pm.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+#include <linux/io.h>
+#include <mach/system.h>
+
+static int mxs_suspend_enter(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_MEM:
+		arch_idle();
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static struct platform_suspend_ops mxs_suspend_ops = {
+	.enter = mxs_suspend_enter,
+	.valid = suspend_valid_only_mem,
+};
+
+static int __init mxs_pm_init(void)
+{
+	suspend_set_ops(&mxs_suspend_ops);
+	return 0;
+}
+device_initcall(mxs_pm_init);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 118+ messages in thread

end of thread, other threads:[~2011-01-24  9:05 UTC | newest]

Thread overview: 118+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-06  7:13 [PATCH v4 00/10] net/fec: add dual fec support for i.MX28 Shawn Guo
2011-01-06  7:13 ` Shawn Guo
2011-01-06  7:13 ` [PATCH v4 01/10] net/fec: fix MMFR_OP type in fec_enet_mdio_write Shawn Guo
2011-01-06  7:13   ` Shawn Guo
2011-01-06  7:13 ` [PATCH v4 02/10] net/fec: remove the use of "index" which is legacy Shawn Guo
2011-01-06  7:13   ` Shawn Guo
2011-01-06  7:13 ` [PATCH v4 03/10] net/fec: add mac field into platform data and consolidate fec_get_mac Shawn Guo
2011-01-06  7:13   ` Shawn Guo
2011-01-06  7:13 ` [PATCH v4 04/10] net/fec: improve pm for better suspend/resume Shawn Guo
2011-01-06  7:13   ` Shawn Guo
2011-01-06  7:13 ` [PATCH v4 05/10] net/fec: add dual fec support for mx28 Shawn Guo
2011-01-06  7:13   ` Shawn Guo
2011-01-11 10:27   ` Sascha Hauer
2011-01-11 10:27     ` Sascha Hauer
2011-01-11 11:38     ` Shawn Guo
2011-01-11 11:38       ` Shawn Guo
2011-01-11 12:24     ` Greg Ungerer
2011-01-11 12:24       ` Greg Ungerer
2011-01-11 13:07       ` Uwe Kleine-König
2011-01-11 13:07         ` Uwe Kleine-König
2011-01-11 13:25         ` Greg Ungerer
2011-01-11 13:25           ` Greg Ungerer
2011-01-12  7:42           ` Uwe Kleine-König
2011-01-12  7:42             ` Uwe Kleine-König
2011-01-13 14:48   ` Uwe Kleine-König
2011-01-13 14:48     ` Uwe Kleine-König
2011-01-14  5:48     ` Shawn Guo
2011-01-14  5:48       ` Shawn Guo
2011-01-14  7:52       ` Uwe Kleine-König
2011-01-14  7:52         ` Uwe Kleine-König
2011-01-14 13:08         ` Shawn Guo
2011-01-14 13:08           ` Shawn Guo
2011-01-17  8:16           ` Lothar Waßmann
2011-01-17  8:16             ` Lothar Waßmann
2011-01-17  8:42             ` Uwe Kleine-König
2011-01-17  8:42               ` Uwe Kleine-König
2011-01-17 11:52             ` Shawn Guo
2011-01-17 11:52               ` Shawn Guo
2011-01-17  9:06     ` Uwe Kleine-König
2011-01-17  9:06       ` Uwe Kleine-König
2011-01-13 21:06   ` Uwe Kleine-König
2011-01-13 21:06     ` Uwe Kleine-König
2011-01-06  7:13 ` [PATCH v4 06/10] ARM: mx28: update clock and device name for dual fec support Shawn Guo
2011-01-06  7:13   ` Shawn Guo
2011-01-13 15:06   ` Uwe Kleine-König
2011-01-13 15:06     ` Uwe Kleine-König
2011-01-14  6:46     ` Shawn Guo
2011-01-14  6:46       ` Shawn Guo
2011-01-14  6:53     ` [PATCH] ARM: mxs: pass fec device name via platform data Shawn Guo
2011-01-14  6:53       ` Shawn Guo
2011-01-14  8:38       ` Uwe Kleine-König
2011-01-14  8:38         ` Uwe Kleine-König
2011-01-06  7:13 ` [PATCH v4 07/10] ARM: mx28: add the second fec device registration Shawn Guo
2011-01-06  7:13   ` Shawn Guo
2011-01-11 10:29   ` Sascha Hauer
2011-01-11 10:29     ` Sascha Hauer
2011-01-11 11:39     ` Shawn Guo
2011-01-11 11:39       ` Shawn Guo
2011-01-11 11:44       ` Sascha Hauer
2011-01-11 11:44         ` Sascha Hauer
2011-01-06  7:13 ` [PATCH v4 08/10] ARM: mxs: add ocotp read function Shawn Guo
2011-01-06  7:13   ` Shawn Guo
2011-01-11 13:31   ` Sascha Hauer
2011-01-11 13:31     ` Sascha Hauer
2011-01-11 14:05     ` Uwe Kleine-König
2011-01-11 14:05       ` Uwe Kleine-König
2011-01-12  6:47     ` Shawn Guo
2011-01-12  6:47       ` Shawn Guo
2011-01-12 14:50       ` Sascha Hauer
2011-01-12 14:50         ` Sascha Hauer
2011-01-12 16:01         ` Uwe Kleine-König
2011-01-12 16:01           ` Uwe Kleine-König
2011-01-13  1:55           ` Shawn Guo
2011-01-13  1:55             ` Shawn Guo
2011-01-13 15:19   ` Uwe Kleine-König
2011-01-13 15:19     ` Uwe Kleine-König
2011-01-14  8:33     ` Sascha Hauer
2011-01-14  8:33       ` Sascha Hauer
2011-01-14 13:16       ` Shawn Guo
2011-01-14 13:16         ` Shawn Guo
2011-01-19 10:48         ` Shawn Guo
2011-01-19 10:48           ` Shawn Guo
2011-01-06  7:13 ` [PATCH v4 09/10] ARM: mx28: read fec mac address from ocotp Shawn Guo
2011-01-06  7:13   ` Shawn Guo
2011-01-13 14:50   ` Uwe Kleine-König
2011-01-13 14:50     ` Uwe Kleine-König
2011-01-06  7:13 ` [PATCH v4 10/10] ARM: mxs: add initial pm support Shawn Guo
2011-01-06  7:13   ` Shawn Guo
2011-01-09 23:44 ` [PATCH v4 00/10] net/fec: add dual fec support for i.MX28 David Miller
2011-01-09 23:44   ` David Miller
2011-01-10  3:08   ` Shawn Guo
2011-01-10  3:08     ` Shawn Guo
2011-01-11  8:15   ` Shawn Guo
2011-01-11  8:15     ` Shawn Guo
2011-01-11 12:07 ` [PATCH] net/fec: remove config FEC2 as it's used nowhere Shawn Guo
2011-01-11 12:07   ` Shawn Guo
2011-01-11 22:03   ` David Miller
2011-01-11 22:03     ` David Miller
2011-01-11 12:09 ` [PATCH v5] ARM: mx28: add the second fec device registration Shawn Guo
2011-01-11 12:09   ` Shawn Guo
2011-01-13 14:49   ` Uwe Kleine-König
2011-01-13 14:49     ` Uwe Kleine-König
2011-01-14  7:04     ` Shawn Guo
2011-01-14  7:04       ` Shawn Guo
2011-01-14  7:24 ` [PATCH v5 08/10] ARM: mxs: add ocotp read function Shawn Guo
2011-01-14  7:24   ` Shawn Guo
2011-01-14  8:40   ` Sascha Hauer
2011-01-14  8:40     ` Sascha Hauer
2011-01-14  9:48     ` Uwe Kleine-König
2011-01-14  9:48       ` Uwe Kleine-König
2011-01-14  8:42   ` Uwe Kleine-König
2011-01-14  8:42     ` Uwe Kleine-König
2011-01-14  7:25 ` [PATCH v5 09/10] ARM: mxs/mx28evk: read fec mac address from ocotp Shawn Guo
2011-01-14  7:25   ` Shawn Guo
2011-01-14 15:11 ` [PATCH v6 08/10] ARM: mxs: add ocotp read function Shawn Guo
2011-01-14 15:11   ` Shawn Guo
2011-01-24  9:05 ` [PATCH v5] ARM: mxs: add initial pm support Shawn Guo
2011-01-24  9:05   ` Shawn Guo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.