drivers/soc/qcom/smsm.c

Source file repositories/reference/linux-study-clean/drivers/soc/qcom/smsm.c

File Facts

System
Linux kernel
Corpus path
drivers/soc/qcom/smsm.c
Extension
.c
Size
18581 bytes
Lines
695
Domain
Driver Families
Bucket
drivers/soc
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 qcom_smsm {
	struct device *dev;

	u32 local_host;

	u32 num_hosts;
	u32 num_entries;

	u32 *local_state;
	u32 *subscription;
	struct qcom_smem_state *state;

	spinlock_t lock;

	struct smsm_entry *entries;
	struct smsm_host *hosts;

	struct mbox_client mbox_client;
};

/**
 * struct smsm_entry - per remote processor entry context
 * @smsm:	back-reference to driver context
 * @domain:	IRQ domain for this entry, if representing a remote system
 * @irq_enabled: bitmap of which state bits IRQs are enabled
 * @irq_rising:	bitmap tracking if rising bits should be propagated
 * @irq_falling: bitmap tracking if falling bits should be propagated
 * @last_value:	snapshot of state bits last time the interrupts where propagated
 * @remote_state: pointer to this entry's state bits
 * @subscription: pointer to a row in the subscription matrix representing this
 *		entry
 */
struct smsm_entry {
	struct qcom_smsm *smsm;

	struct irq_domain *domain;
	DECLARE_BITMAP(irq_enabled, 32);
	DECLARE_BITMAP(irq_rising, 32);
	DECLARE_BITMAP(irq_falling, 32);
	unsigned long last_value;

	u32 *remote_state;
	u32 *subscription;
};

/**
 * struct smsm_host - representation of a remote host
 * @ipc_regmap:	regmap for outgoing interrupt
 * @ipc_offset:	offset in @ipc_regmap for outgoing interrupt
 * @ipc_bit:	bit in @ipc_regmap + @ipc_offset for outgoing interrupt
 * @mbox_chan:	apcs ipc mailbox channel handle
 */
struct smsm_host {
	struct regmap *ipc_regmap;
	int ipc_offset;
	int ipc_bit;

	struct mbox_chan *mbox_chan;
};

/**
 * smsm_update_bits() - change bit in outgoing entry and inform subscribers
 * @data:	smsm context pointer
 * @mask:	value mask
 * @value:	new value
 *
 * Used to set and clear the bits in the outgoing/local entry and inform
 * subscribers about the change.
 */
static int smsm_update_bits(void *data, u32 mask, u32 value)
{
	struct qcom_smsm *smsm = data;
	struct smsm_host *hostp;
	unsigned long flags;
	u32 changes;
	u32 host;
	u32 orig;
	u32 val;

	spin_lock_irqsave(&smsm->lock, flags);

	/* Update the entry */
	val = orig = readl(smsm->local_state);
	val &= ~mask;
	val |= value;

	/* Don't signal if we didn't change the value */
	changes = val ^ orig;
	if (!changes) {
		spin_unlock_irqrestore(&smsm->lock, flags);

Annotation

Implementation Notes