drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
Extension
.c
Size
5721 bytes
Lines
237
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct s32_priv_data {
	void __iomem *ioaddr;
	void __iomem *ctrl_sts;
	struct regmap *sts_regmap;
	unsigned int sts_offset;
	struct device *dev;
	phy_interface_t *intf_mode;
	struct clk *tx_clk;
	struct clk *rx_clk;
};

static int s32_gmac_write_phy_intf_select(struct s32_priv_data *gmac)
{
	int ret = 0;

	if (gmac->ctrl_sts)
		writel(S32_PHY_INTF_SEL_RGMII, gmac->ctrl_sts);
	else
		ret = regmap_write(gmac->sts_regmap, gmac->sts_offset,
				   S32_PHY_INTF_SEL_RGMII);

	dev_dbg(gmac->dev, "PHY mode set to %s\n", phy_modes(*gmac->intf_mode));

	return ret;
}

static int s32_gmac_init(struct device *dev, void *priv)
{
	struct s32_priv_data *gmac = priv;
	int ret;

	/* Set initial TX interface clock */
	ret = clk_prepare_enable(gmac->tx_clk);
	if (ret) {
		dev_err(dev, "Can't enable tx clock\n");
		return ret;
	}
	ret = clk_set_rate(gmac->tx_clk, GMAC_INTF_RATE_125M);
	if (ret) {
		dev_err(dev, "Can't set tx clock\n");
		goto err_tx_disable;
	}

	/* Set initial RX interface clock */
	ret = clk_prepare_enable(gmac->rx_clk);
	if (ret) {
		dev_err(dev, "Can't enable rx clock\n");
		goto err_tx_disable;
	}
	ret = clk_set_rate(gmac->rx_clk, GMAC_INTF_RATE_125M);
	if (ret) {
		dev_err(dev, "Can't set rx clock\n");
		goto err_txrx_disable;
	}

	/* Set interface mode */
	ret = s32_gmac_write_phy_intf_select(gmac);
	if (ret) {
		dev_err(dev, "Can't set PHY interface mode\n");
		goto err_txrx_disable;
	}

	return 0;

err_txrx_disable:
	clk_disable_unprepare(gmac->rx_clk);
err_tx_disable:
	clk_disable_unprepare(gmac->tx_clk);
	return ret;
}

static void s32_gmac_exit(struct device *dev, void *priv)
{
	struct s32_priv_data *gmac = priv;

	clk_disable_unprepare(gmac->tx_clk);
	clk_disable_unprepare(gmac->rx_clk);
}

static void s32_gmac_setup_multi_irq(struct device *dev,
				     struct plat_stmmacenet_data *plat,
				     struct stmmac_resources *res)
{
	int i;

	/* RX IRQs */
	for (i = 0; i < plat->rx_queues_to_use; i++) {
		if (res->rx_irq[i] <= 0) {
			dev_dbg(dev, "Missing RX queue %d interrupt\n", i);
			goto mac_irq_mode;

Annotation

Implementation Notes