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.c (3452B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * linux/arch/sh/boards/se/7724/irq.c
      4 *
      5 * Copyright (C) 2009 Renesas Solutions Corp.
      6 *
      7 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
      8 *
      9 * Based on  linux/arch/sh/boards/se/7722/irq.c
     10 * Copyright (C) 2007  Nobuhiro Iwamatsu
     11 *
     12 * Hitachi UL SolutionEngine 7724 Support.
     13 */
     14#include <linux/init.h>
     15#include <linux/irq.h>
     16#include <linux/interrupt.h>
     17#include <linux/export.h>
     18#include <linux/topology.h>
     19#include <linux/io.h>
     20#include <linux/err.h>
     21#include <mach-se/mach/se7724.h>
     22
     23struct fpga_irq {
     24	unsigned long  sraddr;
     25	unsigned long  mraddr;
     26	unsigned short mask;
     27	unsigned int   base;
     28};
     29
     30static unsigned int fpga2irq(unsigned int irq)
     31{
     32	if (irq >= IRQ0_BASE &&
     33	    irq <= IRQ0_END)
     34		return IRQ0_IRQ;
     35	else if (irq >= IRQ1_BASE &&
     36		 irq <= IRQ1_END)
     37		return IRQ1_IRQ;
     38	else
     39		return IRQ2_IRQ;
     40}
     41
     42static struct fpga_irq get_fpga_irq(unsigned int irq)
     43{
     44	struct fpga_irq set;
     45
     46	switch (irq) {
     47	case IRQ0_IRQ:
     48		set.sraddr = IRQ0_SR;
     49		set.mraddr = IRQ0_MR;
     50		set.mask   = IRQ0_MASK;
     51		set.base   = IRQ0_BASE;
     52		break;
     53	case IRQ1_IRQ:
     54		set.sraddr = IRQ1_SR;
     55		set.mraddr = IRQ1_MR;
     56		set.mask   = IRQ1_MASK;
     57		set.base   = IRQ1_BASE;
     58		break;
     59	default:
     60		set.sraddr = IRQ2_SR;
     61		set.mraddr = IRQ2_MR;
     62		set.mask   = IRQ2_MASK;
     63		set.base   = IRQ2_BASE;
     64		break;
     65	}
     66
     67	return set;
     68}
     69
     70static void disable_se7724_irq(struct irq_data *data)
     71{
     72	unsigned int irq = data->irq;
     73	struct fpga_irq set = get_fpga_irq(fpga2irq(irq));
     74	unsigned int bit = irq - set.base;
     75	__raw_writew(__raw_readw(set.mraddr) | 0x0001 << bit, set.mraddr);
     76}
     77
     78static void enable_se7724_irq(struct irq_data *data)
     79{
     80	unsigned int irq = data->irq;
     81	struct fpga_irq set = get_fpga_irq(fpga2irq(irq));
     82	unsigned int bit = irq - set.base;
     83	__raw_writew(__raw_readw(set.mraddr) & ~(0x0001 << bit), set.mraddr);
     84}
     85
     86static struct irq_chip se7724_irq_chip __read_mostly = {
     87	.name		= "SE7724-FPGA",
     88	.irq_mask	= disable_se7724_irq,
     89	.irq_unmask	= enable_se7724_irq,
     90};
     91
     92static void se7724_irq_demux(struct irq_desc *desc)
     93{
     94	unsigned int irq = irq_desc_get_irq(desc);
     95	struct fpga_irq set = get_fpga_irq(irq);
     96	unsigned short intv = __raw_readw(set.sraddr);
     97	unsigned int ext_irq = set.base;
     98
     99	intv &= set.mask;
    100
    101	for (; intv; intv >>= 1, ext_irq++) {
    102		if (!(intv & 1))
    103			continue;
    104
    105		generic_handle_irq(ext_irq);
    106	}
    107}
    108
    109/*
    110 * Initialize IRQ setting
    111 */
    112void __init init_se7724_IRQ(void)
    113{
    114	int irq_base, i;
    115
    116	__raw_writew(0xffff, IRQ0_MR);  /* mask all */
    117	__raw_writew(0xffff, IRQ1_MR);  /* mask all */
    118	__raw_writew(0xffff, IRQ2_MR);  /* mask all */
    119	__raw_writew(0x0000, IRQ0_SR);  /* clear irq */
    120	__raw_writew(0x0000, IRQ1_SR);  /* clear irq */
    121	__raw_writew(0x0000, IRQ2_SR);  /* clear irq */
    122	__raw_writew(0x002a, IRQ_MODE); /* set irq type */
    123
    124	irq_base = irq_alloc_descs(SE7724_FPGA_IRQ_BASE, SE7724_FPGA_IRQ_BASE,
    125				   SE7724_FPGA_IRQ_NR, numa_node_id());
    126	if (IS_ERR_VALUE(irq_base)) {
    127		pr_err("%s: failed hooking irqs for FPGA\n", __func__);
    128		return;
    129	}
    130
    131	for (i = 0; i < SE7724_FPGA_IRQ_NR; i++)
    132		irq_set_chip_and_handler_name(irq_base + i, &se7724_irq_chip,
    133					      handle_level_irq, "level");
    134
    135	irq_set_chained_handler(IRQ0_IRQ, se7724_irq_demux);
    136	irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
    137
    138	irq_set_chained_handler(IRQ1_IRQ, se7724_irq_demux);
    139	irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW);
    140
    141	irq_set_chained_handler(IRQ2_IRQ, se7724_irq_demux);
    142	irq_set_irq_type(IRQ2_IRQ, IRQ_TYPE_LEVEL_LOW);
    143}