drivers/bus/omap_l3_noc.c

Source file repositories/reference/linux-study-clean/drivers/bus/omap_l3_noc.c

File Facts

System
Linux kernel
Corpus path
drivers/bus/omap_l3_noc.c
Extension
.c
Size
10493 bytes
Lines
375
Domain
Driver Families
Bucket
drivers/bus
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

if (masterid == master->id) {
			master_name = master->name;
			break;
		}
	}

	op_code = readl_relaxed(l3_targ_hdr) & 0x7;

	m_req_info = readl_relaxed(l3_targ_info) & 0xF;
	snprintf(info_string, sizeof(info_string),
		 ": %s in %s mode during %s access",
		 (m_req_info & BIT(0)) ? "Opcode Fetch" : "Data Access",
		 (m_req_info & BIT(1)) ? "Supervisor" : "User",
		 (m_req_info & BIT(3)) ? "Debug" : "Functional");

	WARN(true,
	     "%s:L3 %s Error: MASTER %s TARGET %s (%s)%s%s\n",
	     dev_name(l3->dev),
	     err_description,
	     master_name, target_name,
	     l3_transaction_type[op_code],
	     err_string, info_string);

	/* clear the std error log*/
	clear = std_err_main | CLEAR_STDERR_LOG;
	writel_relaxed(clear, l3_targ_stderr);

	return 0;
}

/**
 * l3_interrupt_handler() - interrupt handler for l3 events
 * @irq:	irq number
 * @_l3:	pointer to l3 structure
 *
 * Interrupt Handler for L3 error detection.
 *	1) Identify the L3 clockdomain partition to which the error belongs to.
 *	2) Identify the slave where the error information is logged
 *	... handle the slave event..
 *	7) if the slave is unknown, mask out the slave.
 */
static irqreturn_t l3_interrupt_handler(int irq, void *_l3)
{
	struct omap_l3 *l3 = _l3;
	int inttype, i, ret;
	int err_src = 0;
	u32 err_reg, mask_val;
	void __iomem *base, *mask_reg;
	struct l3_flagmux_data *flag_mux;

	/* Get the Type of interrupt */
	inttype = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR;

	for (i = 0; i < l3->num_modules; i++) {
		/*
		 * Read the regerr register of the clock domain
		 * to determine the source
		 */
		base = l3->l3_base[i];
		flag_mux = l3->l3_flagmux[i];
		err_reg = readl_relaxed(base + flag_mux->offset +
					L3_FLAGMUX_REGERR0 + (inttype << 3));

		err_reg &= ~(inttype ? flag_mux->mask_app_bits :
				flag_mux->mask_dbg_bits);

		/* Get the corresponding error and analyse */
		if (err_reg) {
			/* Identify the source from control status register */
			err_src = __ffs(err_reg);

			ret = l3_handle_target(l3, base, flag_mux, err_src);

			/*
			 * Certain plaforms may have "undocumented" status
			 * pending on boot. So dont generate a severe warning
			 * here. Just mask it off to prevent the error from
			 * reoccuring and locking up the system.
			 */
			if (ret) {
				dev_err(l3->dev,
					"L3 %s error: target %d mod:%d %s\n",
					inttype ? "debug" : "application",
					err_src, i, "(unclearable)");

				mask_reg = base + flag_mux->offset +
					   L3_FLAGMUX_MASK0 + (inttype << 3);
				mask_val = readl_relaxed(mask_reg);
				mask_val &= ~(1 << err_src);
				writel_relaxed(mask_val, mask_reg);

Annotation

Implementation Notes