drivers/net/dsa/mt7530-mdio.c

Source file repositories/reference/linux-study-clean/drivers/net/dsa/mt7530-mdio.c

File Facts

System
Linux kernel
Corpus path
drivers/net/dsa/mt7530-mdio.c
Extension
.c
Size
6489 bytes
Lines
266
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

if (!mt7531_pcs_config[i]) {
			ret = -ENOMEM;
			break;
		}

		mt7531_pcs_config[i]->name = i ? "port6" : "port5";
		mt7531_pcs_config[i]->reg_bits = 16;
		mt7531_pcs_config[i]->val_bits = 32;
		mt7531_pcs_config[i]->reg_stride = 4;
		mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
		mt7531_pcs_config[i]->max_register = 0x17c;
		mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
		mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
		mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;

		regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv,
					  mt7531_pcs_config[i]);
		if (IS_ERR(regmap)) {
			ret = PTR_ERR(regmap);
			break;
		}
		pcs = mtk_pcs_lynxi_create(priv->dev, NULL, regmap,
					   MT7531_PHYA_CTRL_SIGNAL3);
		if (!pcs) {
			ret = -ENXIO;
			break;
		}
		priv->ports[5 + i].sgmii_pcs = pcs;
	}

	if (ret && i)
		mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);

	return ret;
}

static const struct of_device_id mt7530_of_match[] = {
	{ .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
	{ .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
	{ .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, mt7530_of_match);

static const struct regmap_config regmap_config = {
	.reg_bits = 16,
	.val_bits = 32,
	.reg_stride = 4,
	.max_register = MT7530_CREV,
	.disable_locking = true,
};

static int
mt7530_probe(struct mdio_device *mdiodev)
{
	struct mt7530_priv *priv;
	struct device_node *dn;
	int ret;

	dn = mdiodev->dev.of_node;

	priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->bus = mdiodev->bus;
	priv->dev = &mdiodev->dev;
	priv->mdiodev = mdiodev;

	ret = mt7530_probe_common(priv);
	if (ret)
		return ret;

	/* Use medatek,mcm property to distinguish hardware type that would
	 * cause a little bit differences on power-on sequence.
	 * Not MCM that indicates switch works as the remote standalone
	 * integrated circuit so the GPIO pin would be used to complete
	 * the reset, otherwise memory-mapped register accessing used
	 * through syscon provides in the case of MCM.
	 */
	priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
	if (priv->mcm) {
		dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");

		priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
		if (IS_ERR(priv->rstc)) {
			dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
			return PTR_ERR(priv->rstc);
		}
	} else {

Annotation

Implementation Notes