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

bast-irq.c (2765B)


      1// SPDX-License-Identifier: GPL-2.0+
      2//
      3// Copyright 2003-2005 Simtec Electronics
      4//   Ben Dooks <ben@simtec.co.uk>
      5//
      6// http://www.simtec.co.uk/products/EB2410ITX/
      7
      8#include <linux/init.h>
      9#include <linux/module.h>
     10#include <linux/ioport.h>
     11#include <linux/device.h>
     12#include <linux/io.h>
     13
     14#include <asm/irq.h>
     15#include <asm/mach-types.h>
     16#include <asm/mach/irq.h>
     17
     18#include "regs-irq.h"
     19#include "irqs.h"
     20
     21#include "bast.h"
     22
     23#define irqdbf(x...)
     24#define irqdbf2(x...)
     25
     26/* handle PC104 ISA interrupts from the system CPLD */
     27
     28/* table of ISA irq nos to the relevant mask... zero means
     29 * the irq is not implemented
     30*/
     31static const unsigned char bast_pc104_irqmasks[] = {
     32	0,   /* 0 */
     33	0,   /* 1 */
     34	0,   /* 2 */
     35	1,   /* 3 */
     36	0,   /* 4 */
     37	2,   /* 5 */
     38	0,   /* 6 */
     39	4,   /* 7 */
     40	0,   /* 8 */
     41	0,   /* 9 */
     42	8,   /* 10 */
     43	0,   /* 11 */
     44	0,   /* 12 */
     45	0,   /* 13 */
     46	0,   /* 14 */
     47	0,   /* 15 */
     48};
     49
     50static const unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 };
     51
     52static void
     53bast_pc104_mask(struct irq_data *data)
     54{
     55	unsigned long temp;
     56
     57	temp = __raw_readb(BAST_VA_PC104_IRQMASK);
     58	temp &= ~bast_pc104_irqmasks[data->irq];
     59	__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
     60}
     61
     62static void
     63bast_pc104_maskack(struct irq_data *data)
     64{
     65	struct irq_desc *desc = irq_to_desc(BAST_IRQ_ISA);
     66
     67	bast_pc104_mask(data);
     68	desc->irq_data.chip->irq_ack(&desc->irq_data);
     69}
     70
     71static void
     72bast_pc104_unmask(struct irq_data *data)
     73{
     74	unsigned long temp;
     75
     76	temp = __raw_readb(BAST_VA_PC104_IRQMASK);
     77	temp |= bast_pc104_irqmasks[data->irq];
     78	__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
     79}
     80
     81static struct irq_chip  bast_pc104_chip = {
     82	.irq_mask	= bast_pc104_mask,
     83	.irq_unmask	= bast_pc104_unmask,
     84	.irq_ack	= bast_pc104_maskack
     85};
     86
     87static void bast_irq_pc104_demux(struct irq_desc *desc)
     88{
     89	unsigned int stat;
     90	unsigned int irqno;
     91	int i;
     92
     93	stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf;
     94
     95	if (unlikely(stat == 0)) {
     96		/* ack if we get an irq with nothing (ie, startup) */
     97		desc->irq_data.chip->irq_ack(&desc->irq_data);
     98	} else {
     99		/* handle the IRQ */
    100
    101		for (i = 0; stat != 0; i++, stat >>= 1) {
    102			if (stat & 1) {
    103				irqno = bast_pc104_irqs[i];
    104				generic_handle_irq(irqno);
    105			}
    106		}
    107	}
    108}
    109
    110static __init int bast_irq_init(void)
    111{
    112	unsigned int i;
    113
    114	if (machine_is_bast()) {
    115		printk(KERN_INFO "BAST PC104 IRQ routing, Copyright 2005 Simtec Electronics\n");
    116
    117		/* zap all the IRQs */
    118
    119		__raw_writeb(0x0, BAST_VA_PC104_IRQMASK);
    120
    121		irq_set_chained_handler(BAST_IRQ_ISA, bast_irq_pc104_demux);
    122
    123		/* register our IRQs */
    124
    125		for (i = 0; i < 4; i++) {
    126			unsigned int irqno = bast_pc104_irqs[i];
    127
    128			irq_set_chip_and_handler(irqno, &bast_pc104_chip,
    129						 handle_level_irq);
    130			irq_clear_status_flags(irqno, IRQ_NOREQUEST);
    131		}
    132	}
    133
    134	return 0;
    135}
    136
    137arch_initcall(bast_irq_init);