drivers/i3c/master.c

Source file repositories/reference/linux-study-clean/drivers/i3c/master.c

File Facts

System
Linux kernel
Corpus path
drivers/i3c/master.c
Extension
.c
Size
94913 bytes
Lines
3612
Domain
Driver Families
Bucket
drivers/i3c
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static int i3c_device_match(struct device *dev, const struct device_driver *drv)
{
	struct i3c_device *i3cdev;
	const struct i3c_driver *i3cdrv;

	if (dev->type != &i3c_device_type)
		return 0;

	i3cdev = dev_to_i3cdev(dev);
	i3cdrv = drv_to_i3cdrv(drv);
	if (i3c_device_match_id(i3cdev, i3cdrv->id_table))
		return 1;

	return 0;
}

static int i3c_device_probe(struct device *dev)
{
	struct i3c_device *i3cdev = dev_to_i3cdev(dev);
	struct i3c_driver *driver = drv_to_i3cdrv(dev->driver);

	return driver->probe(i3cdev);
}

static void i3c_device_remove(struct device *dev)
{
	struct i3c_device *i3cdev = dev_to_i3cdev(dev);
	struct i3c_driver *driver = drv_to_i3cdrv(dev->driver);

	if (driver->remove)
		driver->remove(i3cdev);
}

static enum i3c_addr_slot_status
i3c_bus_get_addr_slot_status_mask(struct i3c_bus *bus, u16 addr, u32 mask)
{
	unsigned long status;
	int bitpos = addr * I3C_ADDR_SLOT_STATUS_BITS;

	if (addr > I2C_MAX_ADDR)
		return I3C_ADDR_SLOT_RSVD;

	status = bus->addrslots[bitpos / BITS_PER_LONG];
	status >>= bitpos % BITS_PER_LONG;

	return status & mask;
}

static enum i3c_addr_slot_status
i3c_bus_get_addr_slot_status(struct i3c_bus *bus, u16 addr)
{
	return i3c_bus_get_addr_slot_status_mask(bus, addr, I3C_ADDR_SLOT_STATUS_MASK);
}

static void i3c_bus_set_addr_slot_status_mask(struct i3c_bus *bus, u16 addr,
					      enum i3c_addr_slot_status status, u32 mask)
{
	int bitpos = addr * I3C_ADDR_SLOT_STATUS_BITS;
	unsigned long *ptr;

	if (addr > I2C_MAX_ADDR)
		return;

	ptr = bus->addrslots + (bitpos / BITS_PER_LONG);
	*ptr &= ~((unsigned long)mask << (bitpos % BITS_PER_LONG));
	*ptr |= ((unsigned long)status & mask) << (bitpos % BITS_PER_LONG);
}

static void i3c_bus_set_addr_slot_status(struct i3c_bus *bus, u16 addr,
					 enum i3c_addr_slot_status status)
{
	i3c_bus_set_addr_slot_status_mask(bus, addr, status, I3C_ADDR_SLOT_STATUS_MASK);
}

static bool i3c_bus_dev_addr_is_avail(struct i3c_bus *bus, u8 addr)
{
	enum i3c_addr_slot_status status;

	status = i3c_bus_get_addr_slot_status(bus, addr);

	return status == I3C_ADDR_SLOT_FREE;
}

/*
 * ┌────┬─────────────┬───┬─────────┬───┐
 * │S/Sr│ 7'h7E RnW=0 │ACK│ ENTDAA  │ T ├────┐
 * └────┴─────────────┴───┴─────────┴───┘    │
 * ┌─────────────────────────────────────────┘
 * │  ┌──┬─────────────┬───┬─────────────────┬────────────────┬───┬─────────┐
 * └─►│Sr│7'h7E RnW=1  │ACK│48bit UID BCR DCR│Assign 7bit Addr│PAR│ ACK/NACK│

Annotation

Implementation Notes