drivers/pmdomain/bcm/bcm63xx-power.c

Source file repositories/reference/linux-study-clean/drivers/pmdomain/bcm/bcm63xx-power.c

File Facts

System
Linux kernel
Corpus path
drivers/pmdomain/bcm/bcm63xx-power.c
Extension
.c
Size
8203 bytes
Lines
376
Domain
Driver Families
Bucket
drivers/pmdomain
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 bcm63xx_power_dev {
	struct generic_pm_domain genpd;
	struct bcm63xx_power *power;
	uint32_t mask;
};

struct bcm63xx_power {
	void __iomem *base;
	spinlock_t lock;
	struct bcm63xx_power_dev *dev;
	struct genpd_onecell_data genpd_data;
	struct generic_pm_domain **genpd;
};

struct bcm63xx_power_data {
	const char * const name;
	uint8_t bit;
	unsigned int flags;
};

static int bcm63xx_power_get_state(struct bcm63xx_power_dev *pmd, bool *is_on)
{
	struct bcm63xx_power *power = pmd->power;

	if (!pmd->mask) {
		*is_on = false;
		return -EINVAL;
	}

	*is_on = !(__raw_readl(power->base) & pmd->mask);

	return 0;
}

static int bcm63xx_power_set_state(struct bcm63xx_power_dev *pmd, bool on)
{
	struct bcm63xx_power *power = pmd->power;
	unsigned long flags;
	uint32_t val;

	if (!pmd->mask)
		return -EINVAL;

	spin_lock_irqsave(&power->lock, flags);
	val = __raw_readl(power->base);
	if (on)
		val &= ~pmd->mask;
	else
		val |= pmd->mask;
	__raw_writel(val, power->base);
	spin_unlock_irqrestore(&power->lock, flags);

	return 0;
}

static int bcm63xx_power_on(struct generic_pm_domain *genpd)
{
	struct bcm63xx_power_dev *pmd = container_of(genpd,
		struct bcm63xx_power_dev, genpd);

	return bcm63xx_power_set_state(pmd, true);
}

static int bcm63xx_power_off(struct generic_pm_domain *genpd)
{
	struct bcm63xx_power_dev *pmd = container_of(genpd,
		struct bcm63xx_power_dev, genpd);

	return bcm63xx_power_set_state(pmd, false);
}

static int bcm63xx_power_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	const struct bcm63xx_power_data *entry, *table;
	struct bcm63xx_power *power;
	unsigned int ndom;
	uint8_t max_bit = 0;
	int ret;

	power = devm_kzalloc(dev, sizeof(*power), GFP_KERNEL);
	if (!power)
		return -ENOMEM;

	power->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(power->base))
		return PTR_ERR(power->base);

	table = of_device_get_match_data(dev);

Annotation

Implementation Notes