drivers/pmdomain/bcm/bcm-pmb.c

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

File Facts

System
Linux kernel
Corpus path
drivers/pmdomain/bcm/bcm-pmb.c
Extension
.c
Size
9839 bytes
Lines
364
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 bcm_pmb {
	struct device *dev;
	void __iomem *base;
	spinlock_t lock;
	bool little_endian;
	struct genpd_onecell_data genpd_onecell_data;
};

struct bcm_pmb_pd_data {
	const char * const name;
	int id;
	u8 bus;
	u8 device;
};

struct bcm_pmb_pm_domain {
	struct bcm_pmb *pmb;
	const struct bcm_pmb_pd_data *data;
	struct generic_pm_domain genpd;
};

static int bcm_pmb_bpcm_read(struct bcm_pmb *pmb, int bus, u8 device,
			     int offset, u32 *val)
{
	void __iomem *base = pmb->base + bus * 0x20;
	unsigned long flags;
	int err;

	spin_lock_irqsave(&pmb->lock, flags);
	err = bpcm_rd(base, device, offset, val);
	spin_unlock_irqrestore(&pmb->lock, flags);

	if (!err)
		*val = pmb->little_endian ? le32_to_cpu(*val) : be32_to_cpu(*val);

	return err;
}

static int bcm_pmb_bpcm_write(struct bcm_pmb *pmb, int bus, u8 device,
			      int offset, u32 val)
{
	void __iomem *base = pmb->base + bus * 0x20;
	unsigned long flags;
	int err;

	val = pmb->little_endian ? cpu_to_le32(val) : cpu_to_be32(val);

	spin_lock_irqsave(&pmb->lock, flags);
	err = bpcm_wr(base, device, offset, val);
	spin_unlock_irqrestore(&pmb->lock, flags);

	return err;
}

static int bcm_pmb_power_off_zone(struct bcm_pmb *pmb, int bus, u8 device,
				  int zone)
{
	int offset;
	u32 val;
	int err;

	offset = BPCM_ZONE0 + zone * BPCM_ZONE_SIZE + BPCM_ZONE_CONTROL;

	err = bcm_pmb_bpcm_read(pmb, bus, device, offset, &val);
	if (err)
		return err;

	val |= BPCM_ZONE_CONTROL_PWR_DN_REQ;
	val &= ~BPCM_ZONE_CONTROL_PWR_UP_REQ;

	err = bcm_pmb_bpcm_write(pmb, bus, device, offset, val);

	return err;
}

static int bcm_pmb_power_on_zone(struct bcm_pmb *pmb, int bus, u8 device,
				 int zone)
{
	int offset;
	u32 val;
	int err;

	offset = BPCM_ZONE0 + zone * BPCM_ZONE_SIZE + BPCM_ZONE_CONTROL;

	err = bcm_pmb_bpcm_read(pmb, bus, device, offset, &val);
	if (err)
		return err;

	if (!(val & BPCM_ZONE_CONTROL_PWR_ON_STATE)) {
		val &= ~BPCM_ZONE_CONTROL_PWR_DN_REQ;

Annotation

Implementation Notes