cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

intc-525x.c (2258B)


      1/*
      2 * intc2.c  -- support for the 2nd INTC controller of the 525x
      3 *
      4 * (C) Copyright 2012, Steven King <sfking@fdwdc.com>
      5 * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
      6 *
      7 * This file is subject to the terms and conditions of the GNU General Public
      8 * License.  See the file COPYING in the main directory of this archive
      9 * for more details.
     10 */
     11
     12#include <linux/types.h>
     13#include <linux/init.h>
     14#include <linux/kernel.h>
     15#include <linux/interrupt.h>
     16#include <linux/irq.h>
     17#include <linux/io.h>
     18#include <asm/coldfire.h>
     19#include <asm/mcfsim.h>
     20
     21static void intc2_irq_gpio_mask(struct irq_data *d)
     22{
     23	u32 imr = readl(MCFSIM2_GPIOINTENABLE);
     24	u32 type = irqd_get_trigger_type(d);
     25	int irq = d->irq - MCF_IRQ_GPIO0;
     26
     27	if (type & IRQ_TYPE_EDGE_RISING)
     28		imr &= ~(0x001 << irq);
     29	if (type & IRQ_TYPE_EDGE_FALLING)
     30		imr &= ~(0x100 << irq);
     31	writel(imr, MCFSIM2_GPIOINTENABLE);
     32}
     33
     34static void intc2_irq_gpio_unmask(struct irq_data *d)
     35{
     36	u32 imr = readl(MCFSIM2_GPIOINTENABLE);
     37	u32 type = irqd_get_trigger_type(d);
     38	int irq = d->irq - MCF_IRQ_GPIO0;
     39
     40	if (type & IRQ_TYPE_EDGE_RISING)
     41		imr |= (0x001 << irq);
     42	if (type & IRQ_TYPE_EDGE_FALLING)
     43		imr |= (0x100 << irq);
     44	writel(imr, MCFSIM2_GPIOINTENABLE);
     45}
     46
     47static void intc2_irq_gpio_ack(struct irq_data *d)
     48{
     49	u32 imr = 0;
     50	u32 type = irqd_get_trigger_type(d);
     51	int irq = d->irq - MCF_IRQ_GPIO0;
     52
     53	if (type & IRQ_TYPE_EDGE_RISING)
     54		imr |= (0x001 << irq);
     55	if (type & IRQ_TYPE_EDGE_FALLING)
     56		imr |= (0x100 << irq);
     57	writel(imr, MCFSIM2_GPIOINTCLEAR);
     58}
     59
     60static int intc2_irq_gpio_set_type(struct irq_data *d, unsigned int f)
     61{
     62	if (f & ~IRQ_TYPE_EDGE_BOTH)
     63		return -EINVAL;
     64	return 0;
     65}
     66
     67static struct irq_chip intc2_irq_gpio_chip = {
     68	.name		= "CF-INTC2",
     69	.irq_mask	= intc2_irq_gpio_mask,
     70	.irq_unmask	= intc2_irq_gpio_unmask,
     71	.irq_ack	= intc2_irq_gpio_ack,
     72	.irq_set_type	= intc2_irq_gpio_set_type,
     73};
     74
     75static int __init mcf_intc2_init(void)
     76{
     77	int irq;
     78
     79	/* set the interrupt base for the second interrupt controller */
     80	writel(MCFINTC2_VECBASE, MCFINTC2_INTBASE);
     81
     82	/* GPIO interrupt sources */
     83	for (irq = MCF_IRQ_GPIO0; (irq <= MCF_IRQ_GPIO6); irq++) {
     84		irq_set_chip(irq, &intc2_irq_gpio_chip);
     85		irq_set_handler(irq, handle_edge_irq);
     86	}
     87
     88	return 0;
     89}
     90
     91arch_initcall(mcf_intc2_init);