drivers/reset/reset-rzg2l-usbphy-ctrl.c

Source file repositories/reference/linux-study-clean/drivers/reset/reset-rzg2l-usbphy-ctrl.c

File Facts

System
Linux kernel
Corpus path
drivers/reset/reset-rzg2l-usbphy-ctrl.c
Extension
.c
Size
8697 bytes
Lines
354
Domain
Driver Families
Bucket
drivers/reset
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 rzg2l_usbphy_ctrl_priv {
	struct reset_controller_dev rcdev;
	struct reset_control *rstc;
	void __iomem *base;
	struct platform_device *vdev;
	struct regmap_field *pwrrdy;

	spinlock_t lock;
};

#define rcdev_to_priv(x)	container_of(x, struct rzg2l_usbphy_ctrl_priv, rcdev)

static int rzg2l_usbphy_ctrl_assert(struct reset_controller_dev *rcdev,
				    unsigned long id)
{
	struct rzg2l_usbphy_ctrl_priv *priv = rcdev_to_priv(rcdev);
	u32 port_mask = PHY_RESET_PORT1 | PHY_RESET_PORT2;
	void __iomem *base = priv->base;
	unsigned long flags;
	u32 val;

	spin_lock_irqsave(&priv->lock, flags);
	val = readl(base + RESET);
	val |= id ? PHY_RESET_PORT2 : PHY_RESET_PORT1;
	if (port_mask == (val & port_mask))
		val |= RESET_PLLRESET;
	writel(val, base + RESET);
	spin_unlock_irqrestore(&priv->lock, flags);

	return 0;
}

static int rzg2l_usbphy_ctrl_deassert(struct reset_controller_dev *rcdev,
				      unsigned long id)
{
	struct rzg2l_usbphy_ctrl_priv *priv = rcdev_to_priv(rcdev);
	void __iomem *base = priv->base;
	unsigned long flags;
	u32 val;

	spin_lock_irqsave(&priv->lock, flags);
	val = readl(base + RESET);

	val |= RESET_SEL_PLLRESET;
	val &= ~(RESET_PLLRESET | (id ? PHY_RESET_PORT2 : PHY_RESET_PORT1));
	writel(val, base + RESET);
	spin_unlock_irqrestore(&priv->lock, flags);

	return 0;
}

static int rzg2l_usbphy_ctrl_status(struct reset_controller_dev *rcdev,
				    unsigned long id)
{
	struct rzg2l_usbphy_ctrl_priv *priv = rcdev_to_priv(rcdev);
	u32 port_mask;

	port_mask = id ? PHY_RESET_PORT2 : PHY_RESET_PORT1;

	return !!(readl(priv->base + RESET) & port_mask);
}

/* put pll and phy into reset state */
static void rzg2l_usbphy_ctrl_init(struct rzg2l_usbphy_ctrl_priv *priv)
{
	unsigned long flags;
	u32 val;

	spin_lock_irqsave(&priv->lock, flags);
	val = readl(priv->base + RESET);
	val |= RESET_SEL_PLLRESET | RESET_PLLRESET | PHY_RESET_PORT2 | PHY_RESET_PORT1;
	writel(val, priv->base + RESET);
	spin_unlock_irqrestore(&priv->lock, flags);
}

#define RZG2L_USBPHY_CTRL_PWRRDY	1

static const struct of_device_id rzg2l_usbphy_ctrl_match_table[] = {
	{ .compatible = "renesas,rzg2l-usbphy-ctrl" },
	{
		.compatible = "renesas,r9a08g045-usbphy-ctrl",
		.data = (void *)RZG2L_USBPHY_CTRL_PWRRDY
	},
	{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, rzg2l_usbphy_ctrl_match_table);

static const struct reset_control_ops rzg2l_usbphy_ctrl_reset_ops = {
	.assert = rzg2l_usbphy_ctrl_assert,
	.deassert = rzg2l_usbphy_ctrl_deassert,

Annotation

Implementation Notes