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

irq-zevio.c (3225B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  linux/drivers/irqchip/irq-zevio.c
      4 *
      5 *  Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
      6 */
      7
      8#include <linux/io.h>
      9#include <linux/irq.h>
     10#include <linux/irqchip.h>
     11#include <linux/of.h>
     12#include <linux/of_address.h>
     13#include <linux/of_irq.h>
     14
     15#include <asm/mach/irq.h>
     16#include <asm/exception.h>
     17
     18#define IO_STATUS	0x000
     19#define IO_RAW_STATUS	0x004
     20#define IO_ENABLE	0x008
     21#define IO_DISABLE	0x00C
     22#define IO_CURRENT	0x020
     23#define IO_RESET	0x028
     24#define IO_MAX_PRIOTY	0x02C
     25
     26#define IO_IRQ_BASE	0x000
     27#define IO_FIQ_BASE	0x100
     28
     29#define IO_INVERT_SEL	0x200
     30#define IO_STICKY_SEL	0x204
     31#define IO_PRIORITY_SEL	0x300
     32
     33#define MAX_INTRS	32
     34#define FIQ_START	MAX_INTRS
     35
     36static struct irq_domain *zevio_irq_domain;
     37static void __iomem *zevio_irq_io;
     38
     39static void zevio_irq_ack(struct irq_data *irqd)
     40{
     41	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(irqd);
     42	struct irq_chip_regs *regs = &irq_data_get_chip_type(irqd)->regs;
     43
     44	readl(gc->reg_base + regs->ack);
     45}
     46
     47static void __exception_irq_entry zevio_handle_irq(struct pt_regs *regs)
     48{
     49	int irqnr;
     50
     51	while (readl(zevio_irq_io + IO_STATUS)) {
     52		irqnr = readl(zevio_irq_io + IO_CURRENT);
     53		generic_handle_domain_irq(zevio_irq_domain, irqnr);
     54	}
     55}
     56
     57static void __init zevio_init_irq_base(void __iomem *base)
     58{
     59	/* Disable all interrupts */
     60	writel(~0, base + IO_DISABLE);
     61
     62	/* Accept interrupts of all priorities */
     63	writel(0xF, base + IO_MAX_PRIOTY);
     64
     65	/* Reset existing interrupts */
     66	readl(base + IO_RESET);
     67}
     68
     69static int __init zevio_of_init(struct device_node *node,
     70				struct device_node *parent)
     71{
     72	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
     73	struct irq_chip_generic *gc;
     74	int ret;
     75
     76	if (WARN_ON(zevio_irq_io || zevio_irq_domain))
     77		return -EBUSY;
     78
     79	zevio_irq_io = of_iomap(node, 0);
     80	BUG_ON(!zevio_irq_io);
     81
     82	/* Do not invert interrupt status bits */
     83	writel(~0, zevio_irq_io + IO_INVERT_SEL);
     84
     85	/* Disable sticky interrupts */
     86	writel(0, zevio_irq_io + IO_STICKY_SEL);
     87
     88	/* We don't use IRQ priorities. Set each IRQ to highest priority. */
     89	memset_io(zevio_irq_io + IO_PRIORITY_SEL, 0, MAX_INTRS * sizeof(u32));
     90
     91	/* Init IRQ and FIQ */
     92	zevio_init_irq_base(zevio_irq_io + IO_IRQ_BASE);
     93	zevio_init_irq_base(zevio_irq_io + IO_FIQ_BASE);
     94
     95	zevio_irq_domain = irq_domain_add_linear(node, MAX_INTRS,
     96						 &irq_generic_chip_ops, NULL);
     97	BUG_ON(!zevio_irq_domain);
     98
     99	ret = irq_alloc_domain_generic_chips(zevio_irq_domain, MAX_INTRS, 1,
    100					     "zevio_intc", handle_level_irq,
    101					     clr, 0, IRQ_GC_INIT_MASK_CACHE);
    102	BUG_ON(ret);
    103
    104	gc = irq_get_domain_generic_chip(zevio_irq_domain, 0);
    105	gc->reg_base				= zevio_irq_io;
    106	gc->chip_types[0].chip.irq_ack		= zevio_irq_ack;
    107	gc->chip_types[0].chip.irq_mask		= irq_gc_mask_disable_reg;
    108	gc->chip_types[0].chip.irq_unmask	= irq_gc_unmask_enable_reg;
    109	gc->chip_types[0].regs.mask		= IO_IRQ_BASE + IO_ENABLE;
    110	gc->chip_types[0].regs.enable		= IO_IRQ_BASE + IO_ENABLE;
    111	gc->chip_types[0].regs.disable		= IO_IRQ_BASE + IO_DISABLE;
    112	gc->chip_types[0].regs.ack		= IO_IRQ_BASE + IO_RESET;
    113
    114	set_handle_irq(zevio_handle_irq);
    115
    116	pr_info("TI-NSPIRE classic IRQ controller\n");
    117	return 0;
    118}
    119
    120IRQCHIP_DECLARE(zevio_irq, "lsi,zevio-intc", zevio_of_init);