arch/powerpc/sysdev/cpm2_pic.c

Source file repositories/reference/linux-study-clean/arch/powerpc/sysdev/cpm2_pic.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/sysdev/cpm2_pic.c
Extension
.c
Size
6967 bytes
Lines
269
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/stddef.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>

#include <asm/immap_cpm2.h>
#include <asm/io.h>

#include "cpm2_pic.h"

/* External IRQS */
#define CPM2_IRQ_EXT1		19
#define CPM2_IRQ_EXT7		25

/* Port C IRQS */
#define CPM2_IRQ_PORTC15	48
#define CPM2_IRQ_PORTC0		63

static intctl_cpm2_t __iomem *cpm2_intctl;

static struct irq_domain *cpm2_pic_host;
static unsigned long ppc_cached_irq_mask[2]; /* 2 32-bit registers */

static const u_char irq_to_siureg[] = {
	1, 1, 1, 1, 1, 1, 1, 1,
	1, 1, 1, 1, 1, 1, 1, 1,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	1, 1, 1, 1, 1, 1, 1, 1,
	1, 1, 1, 1, 1, 1, 1, 1,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0
};

/* bit numbers do not match the docs, these are precomputed so the bit for
 * a given irq is (1 << irq_to_siubit[irq]) */
static const u_char irq_to_siubit[] = {
	 0, 15, 14, 13, 12, 11, 10,  9,
	 8,  7,  6,  5,  4,  3,  2,  1,
	 2,  1,  0, 14, 13, 12, 11, 10,
	 9,  8,  7,  6,  5,  4,  3,  0,
	31, 30, 29, 28, 27, 26, 25, 24,
	23, 22, 21, 20, 19, 18, 17, 16,
	16, 17, 18, 19, 20, 21, 22, 23,
	24, 25, 26, 27, 28, 29, 30, 31,
};

static void cpm2_mask_irq(struct irq_data *d)
{
	int	bit, word;
	unsigned int irq_nr = irqd_to_hwirq(d);

	bit = irq_to_siubit[irq_nr];
	word = irq_to_siureg[irq_nr];

	ppc_cached_irq_mask[word] &= ~(1 << bit);
	out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
}

static void cpm2_unmask_irq(struct irq_data *d)
{
	int	bit, word;
	unsigned int irq_nr = irqd_to_hwirq(d);

	bit = irq_to_siubit[irq_nr];
	word = irq_to_siureg[irq_nr];

	ppc_cached_irq_mask[word] |= 1 << bit;
	out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
}

static void cpm2_ack(struct irq_data *d)
{
	int	bit, word;
	unsigned int irq_nr = irqd_to_hwirq(d);

	bit = irq_to_siubit[irq_nr];
	word = irq_to_siureg[irq_nr];

	out_be32(&cpm2_intctl->ic_sipnrh + word, 1 << bit);
}

static void cpm2_end_irq(struct irq_data *d)
{
	int	bit, word;
	unsigned int irq_nr = irqd_to_hwirq(d);

	bit = irq_to_siubit[irq_nr];
	word = irq_to_siureg[irq_nr];

Annotation

Implementation Notes