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