[U-Boot] [PATCH 7/7] net: sh_eth: Add DM and DT support

Joe Hershberger joe.hershberger at ni.com
Fri Feb 16 22:23:47 UTC 2018


On Wed, Jan 24, 2018 at 4:21 PM, Marek Vasut <marek.vasut at gmail.com> wrote:
> Add DM capable code into the SH ethernet driver and support probing
> both from DT and pdata. The legacy non-DM, non-DT support is retained
> as there are still systems in the tree which are not DM or DT capable.
>
> Signed-off-by: Marek Vasut <marek.vasut+renesas at gmail.com>
> Cc: Nobuhiro Iwamatsu <iwamatsu at nigauri.org>
> Cc: Joe Hershberger <joe.hershberger at ni.com>
> ---
>  drivers/net/sh_eth.c | 268 +++++++++++++++++++++++++++++++++++++++++++++++++++

Shouldn't you also be including the bindings text file?

>  1 file changed, 268 insertions(+)
>
> diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
> index 8442fc9a2f..5a5c6bc39e 100644
> --- a/drivers/net/sh_eth.c
> +++ b/drivers/net/sh_eth.c
> @@ -18,6 +18,13 @@
>  #include <linux/errno.h>
>  #include <asm/io.h>
>
> +#ifdef CONFIG_DM_ETH
> +#include <clk.h>
> +#include <dm.h>
> +#include <linux/mii.h>
> +#include <asm/gpio.h>
> +#endif
> +
>  #include "sh_eth.h"
>
>  #ifndef CONFIG_SH_ETHER_USE_PORT
> @@ -512,6 +519,7 @@ static int sh_eth_start_common(struct sh_eth_dev *eth)
>         return 0;
>  }
>
> +#ifndef CONFIG_DM_ETH
>  static int sh_eth_phy_config_legacy(struct sh_eth_dev *eth)
>  {
>         int port = eth->port, ret = 0;
> @@ -666,6 +674,266 @@ err:
>         return ret;
>  }
>
> +#else /* CONFIG_DM_ETH */
> +
> +struct sh_ether_priv {
> +       struct sh_eth_dev       shdev;
> +
> +       struct mii_dev          *bus;
> +       void __iomem            *iobase;
> +       struct clk              clk;
> +       struct gpio_desc        reset_gpio;
> +};
> +
> +static int sh_ether_send(struct udevice *dev, void *packet, int len)
> +{
> +       struct sh_ether_priv *priv = dev_get_priv(dev);
> +       struct sh_eth_dev *eth = &priv->shdev;
> +
> +       return sh_eth_send_common(eth, packet, len);
> +}
> +
> +static int sh_ether_recv(struct udevice *dev, int flags, uchar **packetp)
> +{
> +       struct sh_ether_priv *priv = dev_get_priv(dev);
> +       struct sh_eth_dev *eth = &priv->shdev;
> +       struct sh_eth_info *port_info = &eth->port_info[eth->port];
> +       uchar *packet = (uchar *)ADDR_TO_P2(port_info->rx_desc_cur->rd2);
> +       int len;
> +
> +       len = sh_eth_recv_start(eth);
> +       if (len > 0) {
> +               invalidate_cache(packet, len);
> +               *packetp = packet;
> +
> +               return len;
> +       } else {
> +               len = 0;
> +
> +               /* Restart the receiver if disabled */
> +               if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R))
> +                       sh_eth_write(port_info, EDRRR_R, EDRRR);
> +
> +               return -EAGAIN;
> +       }
> +}
> +
> +static int sh_ether_free_pkt(struct udevice *dev, uchar *packet, int length)
> +{
> +       struct sh_ether_priv *priv = dev_get_priv(dev);
> +       struct sh_eth_dev *eth = &priv->shdev;
> +       struct sh_eth_info *port_info = &eth->port_info[eth->port];
> +
> +       sh_eth_recv_finish(eth);
> +
> +       /* Restart the receiver if disabled */
> +       if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R))
> +               sh_eth_write(port_info, EDRRR_R, EDRRR);
> +
> +       return 0;
> +}
> +
> +static int sh_ether_write_hwaddr(struct udevice *dev)
> +{
> +       struct sh_ether_priv *priv = dev_get_priv(dev);
> +       struct sh_eth_dev *eth = &priv->shdev;
> +       struct sh_eth_info *port_info = &eth->port_info[eth->port];
> +       struct eth_pdata *pdata = dev_get_platdata(dev);
> +
> +       sh_eth_write_hwaddr(port_info, pdata->enetaddr);
> +
> +       return 0;
> +}
> +
> +static int sh_eth_phy_config(struct udevice *dev)
> +{
> +       struct sh_ether_priv *priv = dev_get_priv(dev);
> +       struct eth_pdata *pdata = dev_get_platdata(dev);
> +       struct sh_eth_dev *eth = &priv->shdev;
> +       int port = eth->port, ret = 0;
> +       struct sh_eth_info *port_info = &eth->port_info[port];
> +       struct phy_device *phydev;
> +       int mask = 0xffffffff;
> +
> +       phydev = phy_find_by_mask(priv->bus, mask, pdata->phy_interface);
> +       if (!phydev)
> +               return -ENODEV;
> +
> +       phy_connect_dev(phydev, dev);
> +
> +       port_info->phydev = phydev;
> +       phy_config(phydev);
> +
> +       return ret;
> +}
> +
> +static int sh_ether_start(struct udevice *dev)
> +{
> +       struct sh_ether_priv *priv = dev_get_priv(dev);
> +       struct eth_pdata *pdata = dev_get_platdata(dev);
> +       struct sh_eth_dev *eth = &priv->shdev;
> +       int ret;
> +
> +       ret = clk_enable(&priv->clk);
> +       if (ret)
> +               return ret;
> +
> +       ret = sh_eth_init_common(eth, pdata->enetaddr);
> +       if (ret)
> +               goto err_clk;
> +
> +       ret = sh_eth_phy_config(dev);
> +       if (ret) {
> +               printf(SHETHER_NAME ": phy config timeout\n");
> +               goto err_start;
> +       }
> +
> +       ret = sh_eth_start_common(eth);
> +       if (ret)
> +               goto err_start;
> +
> +       return 0;
> +
> +err_start:
> +       sh_eth_tx_desc_free(eth);
> +       sh_eth_rx_desc_free(eth);
> +err_clk:
> +       clk_disable(&priv->clk);
> +       return ret;
> +}
> +
> +static void sh_ether_stop(struct udevice *dev)
> +{
> +       struct sh_ether_priv *priv = dev_get_priv(dev);
> +
> +       sh_eth_stop(&priv->shdev);
> +       clk_disable(&priv->clk);
> +}
> +
> +static int sh_ether_probe(struct udevice *udev)
> +{
> +       struct eth_pdata *pdata = dev_get_platdata(udev);
> +       struct sh_ether_priv *priv = dev_get_priv(udev);
> +       struct sh_eth_dev *eth = &priv->shdev;
> +       struct mii_dev *mdiodev;
> +       void __iomem *iobase;
> +       int ret;
> +
> +       iobase = map_physmem(pdata->iobase, 0x1000, MAP_NOCACHE);

What's the magic number here? Shouldn't it be a #define?

> +       priv->iobase = iobase;
> +
> +       ret = clk_get_by_index(udev, 0, &priv->clk);
> +       if (ret < 0)
> +               goto err_mdio_alloc;
> +
> +       gpio_request_by_name(udev, "reset-gpios", 0, &priv->reset_gpio,
> +                            GPIOD_IS_OUT);
> +
> +       mdiodev = mdio_alloc();
> +       if (!mdiodev) {
> +               ret = -ENOMEM;
> +               goto err_mdio_alloc;
> +       }
> +
> +       mdiodev->read = bb_miiphy_read;
> +       mdiodev->write = bb_miiphy_write;
> +       bb_miiphy_buses[0].priv = eth;
> +       snprintf(mdiodev->name, sizeof(mdiodev->name), udev->name);
> +
> +       ret = mdio_register(mdiodev);
> +       if (ret < 0)
> +               goto err_mdio_register;
> +
> +       priv->bus = miiphy_get_dev_by_name(udev->name);
> +
> +       eth->port = CONFIG_SH_ETHER_USE_PORT;
> +       eth->port_info[eth->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR;
> +       eth->port_info[eth->port].iobase =
> +               (void __iomem *)(BASE_IO_ADDR + 0x800 * eth->port);
> +
> +       return 0;
> +
> +err_mdio_register:
> +       mdio_free(mdiodev);
> +err_mdio_alloc:
> +       unmap_physmem(priv->iobase, MAP_NOCACHE);
> +       return ret;
> +}

[ ... ]


More information about the U-Boot mailing list