drivers/char/ipmi/kcs_bmc_aspeed.c

Source file repositories/reference/linux-study-clean/drivers/char/ipmi/kcs_bmc_aspeed.c

File Facts

System
Linux kernel
Corpus path
drivers/char/ipmi/kcs_bmc_aspeed.c
Extension
.c
Size
18550 bytes
Lines
683
Domain
Driver Families
Bucket
drivers/char
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 aspeed_kcs_bmc {
	struct kcs_bmc_device kcs_bmc;

	struct regmap *map;

	struct {
		enum aspeed_kcs_irq_mode mode;
		int id;
	} upstream_irq;

	struct {
		spinlock_t lock;
		bool remove;
		struct timer_list timer;
	} obe;
};

static inline struct aspeed_kcs_bmc *to_aspeed_kcs_bmc(struct kcs_bmc_device *kcs_bmc)
{
	return container_of(kcs_bmc, struct aspeed_kcs_bmc, kcs_bmc);
}

static u8 aspeed_kcs_inb(struct kcs_bmc_device *kcs_bmc, u32 reg)
{
	struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc);
	u32 val = 0;
	int rc;

	rc = regmap_read(priv->map, reg, &val);
	WARN(rc != 0, "regmap_read() failed: %d\n", rc);

	return rc == 0 ? (u8) val : 0;
}

static void aspeed_kcs_outb(struct kcs_bmc_device *kcs_bmc, u32 reg, u8 data)
{
	struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc);
	int rc;

	rc = regmap_write(priv->map, reg, data);
	WARN(rc != 0, "regmap_write() failed: %d\n", rc);

	/* Trigger the upstream IRQ on ODR writes, if enabled */

	switch (reg) {
	case LPC_ODR1:
	case LPC_ODR2:
	case LPC_ODR3:
	case LPC_ODR4:
		break;
	default:
		return;
	}

	if (priv->upstream_irq.mode != aspeed_kcs_irq_serirq)
		return;

	switch (kcs_bmc->channel) {
	case 1:
		switch (priv->upstream_irq.id) {
		case 12:
			regmap_update_bits(priv->map, LPC_SIRQCR0, LPC_SIRQCR0_IRQ12E1,
					   LPC_SIRQCR0_IRQ12E1);
			break;
		case 1:
			regmap_update_bits(priv->map, LPC_SIRQCR0, LPC_SIRQCR0_IRQ1E1,
					   LPC_SIRQCR0_IRQ1E1);
			break;
		default:
			break;
		}
		break;
	case 2:
		regmap_update_bits(priv->map, LPC_HICR5, LPC_HICR5_IRQXE2, LPC_HICR5_IRQXE2);
		break;
	case 3:
		regmap_update_bits(priv->map, LPC_HICR5, LPC_HICR5_IRQXE3, LPC_HICR5_IRQXE3);
		break;
	case 4:
		regmap_update_bits(priv->map, LPC_HICRC, LPC_HICRC_IRQXE4, LPC_HICRC_IRQXE4);
		break;
	default:
		break;
	}
}

static void aspeed_kcs_updateb(struct kcs_bmc_device *kcs_bmc, u32 reg, u8 mask, u8 val)
{
	struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc);
	int rc;

Annotation

Implementation Notes