drivers/irqchip/irq-davinci-cp-intc.c

Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-davinci-cp-intc.c

File Facts

System
Linux kernel
Corpus path
drivers/irqchip/irq-davinci-cp-intc.c
Extension
.c
Size
7168 bytes
Lines
247
Domain
Driver Families
Bucket
drivers/irqchip
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

// SPDX-License-Identifier: GPL-2.0-only
//
// Author: Steve Chen <schen@mvista.com>
// Copyright (C) 2008-2009, MontaVista Software, Inc. <source@mvista.com>
// Author: Bartosz Golaszewski <bgolaszewski@baylibre.com>
// Copyright (C) 2019, Texas Instruments
//
// TI Common Platform Interrupt Controller (cp_intc) driver

#include <linux/export.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqdomain.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>

#include <asm/exception.h>

#define DAVINCI_CP_INTC_CTRL			0x04
#define DAVINCI_CP_INTC_HOST_CTRL		0x0c
#define DAVINCI_CP_INTC_GLOBAL_ENABLE		0x10
#define DAVINCI_CP_INTC_SYS_STAT_IDX_CLR	0x24
#define DAVINCI_CP_INTC_SYS_ENABLE_IDX_SET	0x28
#define DAVINCI_CP_INTC_SYS_ENABLE_IDX_CLR	0x2c
#define DAVINCI_CP_INTC_HOST_ENABLE_IDX_SET	0x34
#define DAVINCI_CP_INTC_HOST_ENABLE_IDX_CLR	0x38
#define DAVINCI_CP_INTC_PRIO_IDX		0x80
#define DAVINCI_CP_INTC_SYS_STAT_CLR(n)		(0x0280 + (n << 2))
#define DAVINCI_CP_INTC_SYS_ENABLE_CLR(n)	(0x0380 + (n << 2))
#define DAVINCI_CP_INTC_CHAN_MAP(n)		(0x0400 + (n << 2))
#define DAVINCI_CP_INTC_SYS_POLARITY(n)		(0x0d00 + (n << 2))
#define DAVINCI_CP_INTC_SYS_TYPE(n)		(0x0d80 + (n << 2))
#define DAVINCI_CP_INTC_HOST_ENABLE(n)		(0x1500 + (n << 2))
#define DAVINCI_CP_INTC_PRI_INDX_MASK		GENMASK(9, 0)
#define DAVINCI_CP_INTC_GPIR_NONE		BIT(31)

static void __iomem *davinci_cp_intc_base;
static struct irq_domain *davinci_cp_intc_irq_domain;

static inline unsigned int davinci_cp_intc_read(unsigned int offset)
{
	return readl_relaxed(davinci_cp_intc_base + offset);
}

static inline void davinci_cp_intc_write(unsigned long value,
					 unsigned int offset)
{
	writel_relaxed(value, davinci_cp_intc_base + offset);
}

static void davinci_cp_intc_ack_irq(struct irq_data *d)
{
	davinci_cp_intc_write(d->hwirq, DAVINCI_CP_INTC_SYS_STAT_IDX_CLR);
}

static void davinci_cp_intc_mask_irq(struct irq_data *d)
{
	/* XXX don't know why we need to disable nIRQ here... */
	davinci_cp_intc_write(1, DAVINCI_CP_INTC_HOST_ENABLE_IDX_CLR);
	davinci_cp_intc_write(d->hwirq, DAVINCI_CP_INTC_SYS_ENABLE_IDX_CLR);
	davinci_cp_intc_write(1, DAVINCI_CP_INTC_HOST_ENABLE_IDX_SET);
}

static void davinci_cp_intc_unmask_irq(struct irq_data *d)
{
	davinci_cp_intc_write(d->hwirq, DAVINCI_CP_INTC_SYS_ENABLE_IDX_SET);
}

static int davinci_cp_intc_set_irq_type(struct irq_data *d,
					unsigned int flow_type)
{
	unsigned int reg, mask, polarity, type;

	reg = BIT_WORD(d->hwirq);
	mask = BIT_MASK(d->hwirq);
	polarity = davinci_cp_intc_read(DAVINCI_CP_INTC_SYS_POLARITY(reg));
	type = davinci_cp_intc_read(DAVINCI_CP_INTC_SYS_TYPE(reg));

	switch (flow_type) {
	case IRQ_TYPE_EDGE_RISING:
		polarity |= mask;
		type |= mask;
		break;
	case IRQ_TYPE_EDGE_FALLING:
		polarity &= ~mask;
		type |= mask;
		break;

Annotation

Implementation Notes