Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b631e52 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mediatek-fixes'



Sean Wang says:

====================
net: ethernet: mediatek: a couple of fixes

a couple of fixes come out from integrating with linux-4.8 rc1
they all are verified and workable on linux-4.8 rc1

Changes since v1:
- usage of loops to work out if all required clock are ready instead
of tedious coding
- remove redundant pinctrl setup that is already done by core driver
thanks for careful and patient reviewing by Andrew Lunn
- splitting distinct changes into the separate patches
- change variable naming from err to ret for readable coding

Changes since v2:
- restore to original clock disabling sequence that is changed
accidentally in the last version
- refine the commit log that would cause misunderstanding what has
been done in the changes
- refine the commit log that would cause footnote losing due to
improper delimiter use

Changes since v3:
- fix git rejects caused by mixing a change from net-next, so
remake the patch set based on the current net branch again.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9264251e aa6e8a54
Loading
Loading
Loading
Loading
+42 −40
Original line number Diff line number Diff line
@@ -50,6 +50,10 @@ static const struct mtk_ethtool_stats {
	MTK_ETHTOOL_STAT(rx_flow_control_packets),
};

static const char * const mtk_clks_source_name[] = {
	"ethif", "esw", "gp1", "gp2"
};

void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg)
{
	__raw_writel(val, eth->base + reg);
@@ -291,7 +295,7 @@ static int mtk_phy_connect(struct mtk_mac *mac)
static int mtk_mdio_init(struct mtk_eth *eth)
{
	struct device_node *mii_np;
	int err;
	int ret;

	mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus");
	if (!mii_np) {
@@ -300,13 +304,13 @@ static int mtk_mdio_init(struct mtk_eth *eth)
	}

	if (!of_device_is_available(mii_np)) {
		err = 0;
		ret = -ENODEV;
		goto err_put_node;
	}

	eth->mii_bus = mdiobus_alloc();
	eth->mii_bus = devm_mdiobus_alloc(eth->dev);
	if (!eth->mii_bus) {
		err = -ENOMEM;
		ret = -ENOMEM;
		goto err_put_node;
	}

@@ -317,19 +321,11 @@ static int mtk_mdio_init(struct mtk_eth *eth)
	eth->mii_bus->parent = eth->dev;

	snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%s", mii_np->name);
	err = of_mdiobus_register(eth->mii_bus, mii_np);
	if (err)
		goto err_free_bus;

	return 0;

err_free_bus:
	mdiobus_free(eth->mii_bus);
	ret = of_mdiobus_register(eth->mii_bus, mii_np);

err_put_node:
	of_node_put(mii_np);
	eth->mii_bus = NULL;
	return err;
	return ret;
}

static void mtk_mdio_cleanup(struct mtk_eth *eth)
@@ -338,8 +334,6 @@ static void mtk_mdio_cleanup(struct mtk_eth *eth)
		return;

	mdiobus_unregister(eth->mii_bus);
	of_node_put(eth->mii_bus->dev.of_node);
	mdiobus_free(eth->mii_bus);
}

static inline void mtk_irq_disable(struct mtk_eth *eth, u32 mask)
@@ -588,14 +582,15 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
	dma_addr_t mapped_addr;
	unsigned int nr_frags;
	int i, n_desc = 1;
	u32 txd4 = 0;
	u32 txd4 = 0, fport;

	itxd = ring->next_free;
	if (itxd == ring->last_free)
		return -ENOMEM;

	/* set the forward port */
	txd4 |= (mac->id + 1) << TX_DMA_FPORT_SHIFT;
	fport = (mac->id + 1) << TX_DMA_FPORT_SHIFT;
	txd4 |= fport;

	tx_buf = mtk_desc_to_tx_buf(ring, itxd);
	memset(tx_buf, 0, sizeof(*tx_buf));
@@ -653,7 +648,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
			WRITE_ONCE(txd->txd3, (TX_DMA_SWC |
					       TX_DMA_PLEN0(frag_map_size) |
					       last_frag * TX_DMA_LS0));
			WRITE_ONCE(txd->txd4, 0);
			WRITE_ONCE(txd->txd4, fport);

			tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC;
			tx_buf = mtk_desc_to_tx_buf(ring, txd);
@@ -865,7 +860,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
		/* receive data */
		skb = build_skb(data, ring->frag_size);
		if (unlikely(!skb)) {
			put_page(virt_to_head_page(new_data));
			skb_free_frag(new_data);
			netdev->stats.rx_dropped++;
			goto release_desc;
		}
@@ -1506,10 +1501,7 @@ static void mtk_uninit(struct net_device *dev)
	struct mtk_eth *eth = mac->hw;

	phy_disconnect(mac->phy_dev);
	mtk_mdio_cleanup(eth);
	mtk_irq_disable(eth, ~0);
	free_irq(eth->irq[1], dev);
	free_irq(eth->irq[2], dev);
}

static int mtk_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -1813,6 +1805,7 @@ static int mtk_probe(struct platform_device *pdev)
	if (!eth)
		return -ENOMEM;

	eth->dev = &pdev->dev;
	eth->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(eth->base))
		return PTR_ERR(eth->base);
@@ -1847,21 +1840,21 @@ static int mtk_probe(struct platform_device *pdev)
			return -ENXIO;
		}
	}

	eth->clk_ethif = devm_clk_get(&pdev->dev, "ethif");
	eth->clk_esw = devm_clk_get(&pdev->dev, "esw");
	eth->clk_gp1 = devm_clk_get(&pdev->dev, "gp1");
	eth->clk_gp2 = devm_clk_get(&pdev->dev, "gp2");
	if (IS_ERR(eth->clk_esw) || IS_ERR(eth->clk_gp1) ||
	    IS_ERR(eth->clk_gp2) || IS_ERR(eth->clk_ethif))
	for (i = 0; i < ARRAY_SIZE(eth->clks); i++) {
		eth->clks[i] = devm_clk_get(eth->dev,
					    mtk_clks_source_name[i]);
		if (IS_ERR(eth->clks[i])) {
			if (PTR_ERR(eth->clks[i]) == -EPROBE_DEFER)
				return -EPROBE_DEFER;
			return -ENODEV;
		}
	}

	clk_prepare_enable(eth->clk_ethif);
	clk_prepare_enable(eth->clk_esw);
	clk_prepare_enable(eth->clk_gp1);
	clk_prepare_enable(eth->clk_gp2);
	clk_prepare_enable(eth->clks[MTK_CLK_ETHIF]);
	clk_prepare_enable(eth->clks[MTK_CLK_ESW]);
	clk_prepare_enable(eth->clks[MTK_CLK_GP1]);
	clk_prepare_enable(eth->clks[MTK_CLK_GP2]);

	eth->dev = &pdev->dev;
	eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE);
	INIT_WORK(&eth->pending_work, mtk_pending_work);

@@ -1903,15 +1896,24 @@ static int mtk_probe(struct platform_device *pdev)
static int mtk_remove(struct platform_device *pdev)
{
	struct mtk_eth *eth = platform_get_drvdata(pdev);
	int i;

	clk_disable_unprepare(eth->clk_ethif);
	clk_disable_unprepare(eth->clk_esw);
	clk_disable_unprepare(eth->clk_gp1);
	clk_disable_unprepare(eth->clk_gp2);
	/* stop all devices to make sure that dma is properly shut down */
	for (i = 0; i < MTK_MAC_COUNT; i++) {
		if (!eth->netdev[i])
			continue;
		mtk_stop(eth->netdev[i]);
	}

	clk_disable_unprepare(eth->clks[MTK_CLK_ETHIF]);
	clk_disable_unprepare(eth->clks[MTK_CLK_ESW]);
	clk_disable_unprepare(eth->clks[MTK_CLK_GP1]);
	clk_disable_unprepare(eth->clks[MTK_CLK_GP2]);

	netif_napi_del(&eth->tx_napi);
	netif_napi_del(&eth->rx_napi);
	mtk_cleanup(eth);
	mtk_mdio_cleanup(eth);
	platform_set_drvdata(pdev, NULL);

	return 0;
+14 −8
Original line number Diff line number Diff line
@@ -290,6 +290,17 @@ enum mtk_tx_flags {
	MTK_TX_FLAGS_PAGE0	= 0x02,
};

/* This enum allows us to identify how the clock is defined on the array of the
 * clock in the order
 */
enum mtk_clks_map {
	MTK_CLK_ETHIF,
	MTK_CLK_ESW,
	MTK_CLK_GP1,
	MTK_CLK_GP2,
	MTK_CLK_MAX
};

/* struct mtk_tx_buf -	This struct holds the pointers to the memory pointed at
 *			by the TX descriptor	s
 * @skb:		The SKB pointer of the packet being sent
@@ -370,10 +381,7 @@ struct mtk_rx_ring {
 * @scratch_ring:	Newer SoCs need memory for a second HW managed TX ring
 * @phy_scratch_ring:	physical address of scratch_ring
 * @scratch_head:	The scratch memory that scratch_ring points to.
 * @clk_ethif:		The ethif clock
 * @clk_esw:		The switch clock
 * @clk_gp1:		The gmac1 clock
 * @clk_gp2:		The gmac2 clock
 * @clks:		clock array for all clocks required
 * @mii_bus:		If there is a bus we need to create an instance for it
 * @pending_work:	The workqueue used to reset the dma ring
 */
@@ -400,10 +408,8 @@ struct mtk_eth {
	struct mtk_tx_dma		*scratch_ring;
	dma_addr_t			phy_scratch_ring;
	void				*scratch_head;
	struct clk			*clk_ethif;
	struct clk			*clk_esw;
	struct clk			*clk_gp1;
	struct clk			*clk_gp2;
	struct clk			*clks[MTK_CLK_MAX];

	struct mii_bus			*mii_bus;
	struct work_struct		pending_work;
};