arch/arm/mach-imx/avic.c

Source file repositories/reference/linux-study-clean/arch/arm/mach-imx/avic.c

File Facts

System
Linux kernel
Corpus path
arch/arm/mach-imx/avic.c
Extension
.c
Size
6567 bytes
Lines
237
Domain
Architecture Layer
Bucket
arch/arm
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

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
 */

#include <linux/module.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/irqchip.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <asm/mach/irq.h>
#include <asm/exception.h>

#include "common.h"
#include "hardware.h"
#include "irq-common.h"

#define AVIC_INTCNTL		0x00	/* int control reg */
#define AVIC_NIMASK		0x04	/* int mask reg */
#define AVIC_INTENNUM		0x08	/* int enable number reg */
#define AVIC_INTDISNUM		0x0C	/* int disable number reg */
#define AVIC_INTENABLEH		0x10	/* int enable reg high */
#define AVIC_INTENABLEL		0x14	/* int enable reg low */
#define AVIC_INTTYPEH		0x18	/* int type reg high */
#define AVIC_INTTYPEL		0x1C	/* int type reg low */
#define AVIC_NIPRIORITY(x)	(0x20 + 4 * (7 - (x))) /* int priority */
#define AVIC_NIVECSR		0x40	/* norm int vector/status */
#define AVIC_FIVECSR		0x44	/* fast int vector/status */
#define AVIC_INTSRCH		0x48	/* int source reg high */
#define AVIC_INTSRCL		0x4C	/* int source reg low */
#define AVIC_INTFRCH		0x50	/* int force reg high */
#define AVIC_INTFRCL		0x54	/* int force reg low */
#define AVIC_NIPNDH		0x58	/* norm int pending high */
#define AVIC_NIPNDL		0x5C	/* norm int pending low */
#define AVIC_FIPNDH		0x60	/* fast int pending high */
#define AVIC_FIPNDL		0x64	/* fast int pending low */

#define AVIC_NUM_IRQS 64

/* low power interrupt mask registers */
#define MX25_CCM_LPIMR0	0x68
#define MX25_CCM_LPIMR1	0x6C

static void __iomem *avic_base;
static void __iomem *mx25_ccm_base;
static struct irq_domain *domain;

#ifdef CONFIG_FIQ
static int avic_set_irq_fiq(unsigned int hwirq, unsigned int type)
{
	unsigned int irqt;

	if (hwirq >= AVIC_NUM_IRQS)
		return -EINVAL;

	if (hwirq < AVIC_NUM_IRQS / 2) {
		irqt = imx_readl(avic_base + AVIC_INTTYPEL) & ~(1 << hwirq);
		imx_writel(irqt | (!!type << hwirq), avic_base + AVIC_INTTYPEL);
	} else {
		hwirq -= AVIC_NUM_IRQS / 2;
		irqt = imx_readl(avic_base + AVIC_INTTYPEH) & ~(1 << hwirq);
		imx_writel(irqt | (!!type << hwirq), avic_base + AVIC_INTTYPEH);
	}

	return 0;
}
#endif /* CONFIG_FIQ */


static struct mxc_extra_irq avic_extra_irq = {
#ifdef CONFIG_FIQ
	.set_irq_fiq = avic_set_irq_fiq,
#endif
};

#ifdef CONFIG_PM
static u32 avic_saved_mask_reg[2];

static void avic_irq_suspend(struct irq_data *d)
{
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
	struct irq_chip_type *ct = gc->chip_types;
	int idx = d->hwirq >> 5;

	avic_saved_mask_reg[idx] = imx_readl(avic_base + ct->regs.mask);
	imx_writel(gc->wake_active, avic_base + ct->regs.mask);

Annotation

Implementation Notes