drivers/phy/amlogic/phy-meson-axg-pcie.c

Source file repositories/reference/linux-study-clean/drivers/phy/amlogic/phy-meson-axg-pcie.c

File Facts

System
Linux kernel
Corpus path
drivers/phy/amlogic/phy-meson-axg-pcie.c
Extension
.c
Size
4415 bytes
Lines
188
Domain
Driver Families
Bucket
drivers/phy
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 phy_axg_pcie_priv {
	struct phy *phy;
	struct phy *analog;
	struct regmap *regmap;
	struct reset_control *reset;
};

static const struct regmap_config phy_axg_pcie_regmap_conf = {
	.reg_bits = 8,
	.val_bits = 32,
	.reg_stride = 4,
	.max_register = MESON_PCIE_REG0,
};

static int phy_axg_pcie_power_on(struct phy *phy)
{
	struct phy_axg_pcie_priv *priv = phy_get_drvdata(phy);
	int ret;

	ret = phy_power_on(priv->analog);
	if (ret != 0)
		return ret;

	regmap_update_bits(priv->regmap, MESON_PCIE_REG0,
			   MESON_PCIE_POWERDOWN, 0);
	return 0;
}

static int phy_axg_pcie_power_off(struct phy *phy)
{
	struct phy_axg_pcie_priv *priv = phy_get_drvdata(phy);
	int ret;

	ret = phy_power_off(priv->analog);
	if (ret != 0)
		return ret;

	regmap_update_bits(priv->regmap, MESON_PCIE_REG0,
			   MESON_PCIE_POWERDOWN, 1);
	return 0;
}

static int phy_axg_pcie_init(struct phy *phy)
{
	struct phy_axg_pcie_priv *priv = phy_get_drvdata(phy);
	int ret;

	ret = phy_init(priv->analog);
	if (ret != 0)
		return ret;

	regmap_write(priv->regmap, MESON_PCIE_REG0, MESON_PCIE_PHY_INIT);
	return reset_control_reset(priv->reset);
}

static int phy_axg_pcie_exit(struct phy *phy)
{
	struct phy_axg_pcie_priv *priv = phy_get_drvdata(phy);
	int ret;

	ret = phy_exit(priv->analog);
	if (ret != 0)
		return ret;

	return reset_control_reset(priv->reset);
}

static int phy_axg_pcie_reset(struct phy *phy)
{
	struct phy_axg_pcie_priv *priv = phy_get_drvdata(phy);
	int ret = 0;

	ret = phy_reset(priv->analog);
	if (ret != 0)
		goto out;

	ret = reset_control_assert(priv->reset);
	if (ret != 0)
		goto out;
	udelay(MESON_PCIE_RESET_DELAY);

	ret = reset_control_deassert(priv->reset);
	if (ret != 0)
		goto out;
	udelay(MESON_PCIE_RESET_DELAY);

out:
	return ret;
}

Annotation

Implementation Notes