[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 = ð->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 = ð->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 = ð->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 = ð->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