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

Marek Vasut marek.vasut at gmail.com
Sat Feb 17 00:05:49 UTC 2018


On 02/16/2018 11:23 PM, Joe Hershberger wrote:
> 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?

Since this stuff is already in, I sent a patchset addressing the feedback.

-- 
Best regards,
Marek Vasut


More information about the U-Boot mailing list