All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Ungerer <gerg@snapgear.com>
To: Sascha Hauer <s.hauer@pengutronix.de>
Cc: netdev@vger.kernel.org, frederic rodo <fred.rodo@gmail.com>
Subject: Re: [PATCH] FEC: Turn FEC driver into platform device driver
Date: Wed, 28 Jan 2009 17:36:17 +1000	[thread overview]
Message-ID: <49800AF1.7020909@snapgear.com> (raw)
In-Reply-To: <1233052804-31228-10-git-send-email-s.hauer@pengutronix.de>

Hi Sascha,

Sascha Hauer wrote:
> This turns the fec driver into a platform device driver for new
> platforms. Old platforms are still supported through a FEC_LEGACY define
> till they are also ported.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/net/fec.c |  249 ++++++++++++++++++++++++++++++++++++++++++++++------
>  1 files changed, 220 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/net/fec.c b/drivers/net/fec.c
> index 2c8783a..ed4825b 100644
> --- a/drivers/net/fec.c
> +++ b/drivers/net/fec.c
> @@ -39,6 +39,7 @@
>  #include <linux/io.h>
>  #include <linux/irq.h>
>  #include <linux/clk.h>
> +#include <linux/platform_device.h>
>  
>  #include <asm/cacheflush.h>
>  
> @@ -49,12 +50,6 @@
>  
>  #include "fec.h"
>  
> -#if defined(CONFIG_FEC2)
> -#define	FEC_MAX_PORTS	2
> -#else
> -#define	FEC_MAX_PORTS	1
> -#endif
> -
>  #ifdef CONFIG_ARCH_MXC
>  #include <mach/hardware.h>
>  #define FEC_ALIGNMENT	0xf
> @@ -62,13 +57,22 @@
>  #define FEC_ALIGNMENT	0x3
>  #endif
>  
> +#if defined CONFIG_M5272 || defined CONFIG_M527x || defined CONFIG_M523x \
> +	|| defined CONFIG_M528x || defined CONFIG_M532

This list needs to include a "defined CONFIG_M520x" as well.

Aside from this it builds and runs fine on the ColdFire parts
I tried it on.

Regards
Greg




> +#define FEC_LEGACY
> +/*
> + * Define the fixed address of the FEC hardware.
> + */
>  #if defined(CONFIG_M5272)
>  #define HAVE_mii_link_interrupt
>  #endif
>  
> -/*
> - * Define the fixed address of the FEC hardware.
> - */
> +#if defined(CONFIG_FEC2)
> +#define	FEC_MAX_PORTS	2
> +#else
> +#define	FEC_MAX_PORTS	1
> +#endif
> +
>  static unsigned int fec_hw[] = {
>  #if defined(CONFIG_M5272)
>  	(MCF_MBAR + 0x840),
> @@ -106,6 +110,8 @@ static unsigned char	fec_mac_default[] = {
>  #define	FEC_FLASHMAC	0
>  #endif
>  
> +#endif /* FEC_LEGACY */
> +
>  /* Forward declarations of some structures to support different PHYs
>  */
>  
> @@ -189,6 +195,8 @@ struct fec_enet_private {
>  
>  	struct net_device *netdev;
>  
> +	struct clk *clk;
> +
>  	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
>  	unsigned char *tx_bounce[TX_RING_SIZE];
>  	struct	sk_buff* tx_skbuff[TX_RING_SIZE];
> @@ -1919,7 +1927,9 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
>  		printk("FEC: No PHY device found.\n");
>  		/* Disable external MII interface */
>  		fecp->fec_mii_speed = fep->phy_speed = 0;
> +#ifdef FREC_LEGACY
>  		fec_disable_phy_intr();
> +#endif
>  	}
>  }
>  
> @@ -2101,12 +2111,12 @@ fec_set_mac_address(struct net_device *dev)
>  
>  }
>  
> -/* Initialize the FEC Ethernet on 860T (or ColdFire 5272).
> - */
>   /*
>    * XXX:  We need to clean up on failure exits here.
> +  *
> +  * index is only used in legacy code
>    */
> -int __init fec_enet_init(struct net_device *dev)
> +int __init fec_enet_init(struct net_device *dev, int index)
>  {
>  	struct fec_enet_private *fep = netdev_priv(dev);
>  	unsigned long	mem_addr;
> @@ -2114,11 +2124,6 @@ int __init fec_enet_init(struct net_device *dev)
>  	cbd_t		*cbd_base;
>  	volatile fec_t	*fecp;
>  	int 		i, j;
> -	static int	index = 0;
> -
> -	/* Only allow us to be probed once. */
> -	if (index >= FEC_MAX_PORTS)
> -		return -ENXIO;
>  
>  	/* Allocate memory for buffer descriptors.
>  	*/
> @@ -2133,7 +2138,7 @@ int __init fec_enet_init(struct net_device *dev)
>  
>  	/* Create an Ethernet device instance.
>  	*/
> -	fecp = (volatile fec_t *) fec_hw[index];
> +	fecp = (volatile fec_t *)dev->base_addr;
>  
>  	fep->index = index;
>  	fep->hwp = fecp;
> @@ -2144,16 +2149,24 @@ int __init fec_enet_init(struct net_device *dev)
>  	fecp->fec_ecntrl = 1;
>  	udelay(10);
>  
> -	/* Set the Ethernet address.  If using multiple Enets on the 8xx,
> -	 * this needs some work to get unique addresses.
> -	 *
> -	 * This is our default MAC address unless the user changes
> -	 * it via eth_mac_addr (our dev->set_mac_addr handler).
> -	 */
> +	/* Set the Ethernet address */
> +#ifdef FEC_LEGACY
>  	fec_get_mac(dev);
> +#else
> +	{
> +		unsigned long l;
> +		l = fecp->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 = fecp->fec_addr_high;
> +		dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24);
> +		dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16);
> +	}
> +#endif
>  
>  	cbd_base = (cbd_t *)mem_addr;
> -	/* XXX: missing check for allocation failure */
>  
>  	/* Set receive and transmit descriptor base.
>  	*/
> @@ -2220,10 +2233,12 @@ int __init fec_enet_init(struct net_device *dev)
>  	fecp->fec_r_des_start = fep->bd_dma;
>  	fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t) * RX_RING_SIZE;
>  
> +#ifdef FEC_LEGACY
>  	/* Install our interrupt handlers. This varies depending on
>  	 * the architecture.
>  	*/
>  	fec_request_intrs(dev);
> +#endif
>  
>  	fecp->fec_grp_hash_table_high = 0;
>  	fecp->fec_grp_hash_table_low = 0;
> @@ -2235,8 +2250,6 @@ int __init fec_enet_init(struct net_device *dev)
>  	fecp->fec_hash_table_low = 0;
>  #endif
>  
> -	dev->base_addr = (unsigned long)fecp;
> -
>  	/* The FEC Ethernet specific entries in the device structure. */
>  	dev->open = fec_enet_open;
>  	dev->hard_start_xmit = fec_enet_start_xmit;
> @@ -2250,7 +2263,20 @@ int __init fec_enet_init(struct net_device *dev)
>  	mii_free = mii_cmds;
>  
>  	/* setup MII interface */
> +#ifdef FEC_LEGACY
>  	fec_set_mii(dev, fep);
> +#else
> +	fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
> +	fecp->fec_x_cntrl = 0x00;
> +
> +	/*
> +	 * Set MII speed to 2.5 MHz
> +	 */
> +	fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999)
> +					/ 2500000) / 2) & 0x3F) << 1;
> +	fecp->fec_mii_speed = fep->phy_speed;
> +	fec_restart(dev, 0);
> +#endif
>  
>  	/* Clear and enable interrupts */
>  	fecp->fec_ievent = 0xffc00000;
> @@ -2263,7 +2289,6 @@ int __init fec_enet_init(struct net_device *dev)
>  	fep->phy_addr = 0;
>  	mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy);
>  
> -	index++;
>  	return 0;
>  }
>  
> @@ -2414,6 +2439,7 @@ fec_stop(struct net_device *dev)
>  	fecp->fec_mii_speed = fep->phy_speed;
>  }
>  
> +#ifdef FEC_LEGACY
>  static int __init fec_enet_module_init(void)
>  {
>  	struct net_device *dev;
> @@ -2425,7 +2451,8 @@ static int __init fec_enet_module_init(void)
>  		dev = alloc_etherdev(sizeof(struct fec_enet_private));
>  		if (!dev)
>  			return -ENOMEM;
> -		err = fec_enet_init(dev);
> +		dev->base_addr = (unsigned long)fec_hw[i];
> +		err = fec_enet_init(dev, i);
>  		if (err) {
>  			free_netdev(dev);
>  			continue;
> @@ -2440,6 +2467,170 @@ static int __init fec_enet_module_init(void)
>  	}
>  	return 0;
>  }
> +#else
> +
> +static int __devinit
> +fec_probe(struct platform_device *pdev)
> +{
> +	struct fec_enet_private *fep;
> +	struct net_device *ndev;
> +	int i, irq, ret = 0;
> +	struct resource *r;
> +
> +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!r)
> +		return -ENXIO;
> +
> +	r = request_mem_region(r->start, resource_size(r), pdev->name);
> +	if (!r)
> +		return -EBUSY;
> +
> +	/* Init network device */
> +	ndev = alloc_etherdev(sizeof(struct fec_enet_private));
> +	if (!ndev)
> +		return -ENOMEM;
> +
> +	SET_NETDEV_DEV(ndev, &pdev->dev);
> +
> +	/* setup board info structure */
> +	fep = netdev_priv(ndev);
> +	memset(fep, 0, sizeof(*fep));
> +
> +	ndev->base_addr = (unsigned long)ioremap(r->start, resource_size(r));
> +
> +	if (!ndev->base_addr) {
> +		ret = -ENOMEM;
> +		goto failed_ioremap;
> +	}
> +
> +	platform_set_drvdata(pdev, ndev);
> +
> +	/* This device has up to three irqs on some platforms */
> +	for (i = 0; i < 3; i++) {
> +		irq = platform_get_irq(pdev, i);
> +		if (i && irq < 0)
> +			break;
> +		ret = request_irq(irq, fec_enet_interrupt, IRQF_DISABLED, pdev->name, ndev);
> +		if (ret) {
> +			while (i >= 0) {
> +				irq = platform_get_irq(pdev, i);
> +				free_irq(irq, ndev);
> +				i--;
> +			}
> +			goto failed_irq;
> +		}
> +	}
> +
> +	fep->clk = clk_get(&pdev->dev, "fec_clk");
> +	if (IS_ERR(fep->clk)) {
> +		ret = PTR_ERR(fep->clk);
> +		goto failed_clk;
> +	}
> +	clk_enable(fep->clk);
> +
> +	ret = fec_enet_init(ndev, 0);
> +	if (ret)
> +		goto failed_init;
> +
> +	ret = register_netdev(ndev);
> +	if (ret)
> +		goto failed_register;
> +
> +	return 0;
> +
> +failed_register:
> +failed_init:
> +	clk_disable(fep->clk);
> +	clk_put(fep->clk);
> +failed_clk:
> +	for (i = 0; i < 3; i++) {
> +		irq = platform_get_irq(pdev, i);
> +		if (irq > 0)
> +			free_irq(irq, ndev);
> +	}
> +failed_irq:
> +	iounmap((void __iomem *)ndev->base_addr);
> +failed_ioremap:
> +	free_netdev(ndev);
> +
> +	return ret;
> +}
> +
> +static int __devexit
> +fec_drv_remove(struct platform_device *pdev)
> +{
> +	struct net_device *ndev = platform_get_drvdata(pdev);
> +	struct fec_enet_private *fep = netdev_priv(ndev);
> +
> +	platform_set_drvdata(pdev, NULL);
> +
> +	fec_stop(ndev);
> +	clk_disable(fep->clk);
> +	clk_put(fep->clk);
> +	iounmap((void __iomem *)ndev->base_addr);
> +	unregister_netdev(ndev);
> +	free_netdev(ndev);
> +	return 0;
> +}
> +
> +static int
> +fec_suspend(struct platform_device *dev, pm_message_t state)
> +{
> +	struct net_device *ndev = platform_get_drvdata(dev);
> +	struct fec_enet_private *fep;
> +
> +	if (ndev) {
> +		fep = netdev_priv(ndev);
> +		if (netif_running(ndev)) {
> +			netif_device_detach(ndev);
> +			fec_stop(ndev);
> +		}
> +	}
> +	return 0;
> +}
> +
> +static int
> +fec_resume(struct platform_device *dev)
> +{
> +	struct net_device *ndev = platform_get_drvdata(dev);
> +
> +	if (ndev) {
> +		if (netif_running(ndev)) {
> +			fec_enet_init(ndev, 0);
> +			netif_device_attach(ndev);
> +		}
> +	}
> +	return 0;
> +}
> +
> +static struct platform_driver fec_driver = {
> +	.driver	= {
> +		.name    = "fec",
> +		.owner	 = THIS_MODULE,
> +	},
> +	.probe   = fec_probe,
> +	.remove  = __devexit_p(fec_drv_remove),
> +	.suspend = fec_suspend,
> +	.resume  = fec_resume,
> +};
> +
> +static int __init
> +fec_enet_module_init(void)
> +{
> +	printk(KERN_INFO "FEC Ethernet Driver\n");
> +
> +	return platform_driver_register(&fec_driver);
> +}
> +
> +static void __exit
> +fec_enet_cleanup(void)
> +{
> +	platform_driver_unregister(&fec_driver);
> +}
> +
> +module_exit(fec_enet_cleanup);
> +
> +#endif /* FEC_LEGACY */
>  
>  module_init(fec_enet_module_init);
>  

-- 
------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg@snapgear.com
SnapGear, a McAfee Company                  PHONE:       +61 7 3435 2888
825 Stanley St,                             FAX:         +61 7 3891 3630
Woolloongabba, QLD, 4102, Australia         WEB: http://www.SnapGear.com

  reply	other threads:[~2009-01-28  7:36 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-27 10:39 FEC Patches Sascha Hauer
2009-01-27 10:39 ` [PATCH] fec: remove unused #else branches Sascha Hauer
2009-01-27 10:39   ` [PATCH] fec: remove empty functions Sascha Hauer
2009-01-27 10:39     ` [PATCH] fec: use linux/*.h instead of asm/*.h Sascha Hauer
2009-01-27 10:39       ` [PATCH] fec: do not use memcpy on physical addresses Sascha Hauer
2009-01-27 10:40         ` [PATCH] fec: use dma_alloc_coherent for descriptor ring Sascha Hauer
2009-01-27 10:40           ` [PATCH] fec: Fix KS8721BL_ICSR phy register offset Sascha Hauer
2009-01-27 10:40             ` [PATCH] fec: replace flush_dcache_range with dma_sync_single Sascha Hauer
2009-01-27 10:40               ` [PATCH] fec: Add support for Freescale MX27 Sascha Hauer
2009-01-27 10:40                 ` [PATCH] FEC: Turn FEC driver into platform device driver Sascha Hauer
2009-01-28  7:36                   ` Greg Ungerer [this message]
2009-01-28  7:37 ` FEC Patches Greg Ungerer
2009-01-28 18:53   ` Sascha Hauer
2009-01-28 20:31     ` David Miller
2009-01-29  9:03       ` Sascha Hauer
2009-01-28 23:46     ` Greg Ungerer
  -- strict thread matches above, loose matches on Subject: below --
2009-01-29  9:03 FEC patches Sascha Hauer
2009-01-29  9:03 ` [PATCH] fec: remove unused #else branches Sascha Hauer
2009-01-29  9:03   ` [PATCH] fec: remove empty functions Sascha Hauer
2009-01-29  9:03     ` [PATCH] fec: use linux/*.h instead of asm/*.h Sascha Hauer
2009-01-29  9:03       ` [PATCH] fec: do not use memcpy on physical addresses Sascha Hauer
2009-01-29  9:03         ` [PATCH] fec: use dma_alloc_coherent for descriptor ring Sascha Hauer
2009-01-29  9:03           ` [PATCH] fec: Fix KS8721BL_ICSR phy register offset Sascha Hauer
2009-01-29  9:03             ` [PATCH] fec: replace flush_dcache_range with dma_sync_single Sascha Hauer
2009-01-29  9:03               ` [PATCH] fec: Add support for Freescale MX27 Sascha Hauer
2009-01-29  9:03                 ` [PATCH] FEC: Turn FEC driver into platform device driver Sascha Hauer
     [not found] <1233051848-5994-1-git-send-email-y>
     [not found] ` <1233051848-5994-2-git-send-email-y>
     [not found]   ` <1233051848-5994-3-git-send-email-y>
     [not found]     ` <1233051848-5994-4-git-send-email-y>
     [not found]       ` <1233051848-5994-5-git-send-email-y>
     [not found]         ` <1233051848-5994-6-git-send-email-y>
     [not found]           ` <1233051848-5994-7-git-send-email-y>
     [not found]             ` <1233051848-5994-8-git-send-email-y>
     [not found]               ` <1233051848-5994-9-git-send-email-y>
2009-01-27 10:24                 ` y

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=49800AF1.7020909@snapgear.com \
    --to=gerg@snapgear.com \
    --cc=fred.rodo@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=s.hauer@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.