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


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  GT641xx IRQ routines.
      4 *
      5 *  Copyright (C) 2007	Yoichi Yuasa <yuasa@linux-mips.org>
      6 */
      7#include <linux/hardirq.h>
      8#include <linux/init.h>
      9#include <linux/irq.h>
     10#include <linux/spinlock.h>
     11#include <linux/types.h>
     12
     13#include <asm/gt64120.h>
     14
     15#define GT641XX_IRQ_TO_BIT(irq) (1U << (irq - GT641XX_IRQ_BASE))
     16
     17static DEFINE_RAW_SPINLOCK(gt641xx_irq_lock);
     18
     19static void ack_gt641xx_irq(struct irq_data *d)
     20{
     21	unsigned long flags;
     22	u32 cause;
     23
     24	raw_spin_lock_irqsave(&gt641xx_irq_lock, flags);
     25	cause = GT_READ(GT_INTRCAUSE_OFS);
     26	cause &= ~GT641XX_IRQ_TO_BIT(d->irq);
     27	GT_WRITE(GT_INTRCAUSE_OFS, cause);
     28	raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
     29}
     30
     31static void mask_gt641xx_irq(struct irq_data *d)
     32{
     33	unsigned long flags;
     34	u32 mask;
     35
     36	raw_spin_lock_irqsave(&gt641xx_irq_lock, flags);
     37	mask = GT_READ(GT_INTRMASK_OFS);
     38	mask &= ~GT641XX_IRQ_TO_BIT(d->irq);
     39	GT_WRITE(GT_INTRMASK_OFS, mask);
     40	raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
     41}
     42
     43static void mask_ack_gt641xx_irq(struct irq_data *d)
     44{
     45	unsigned long flags;
     46	u32 cause, mask;
     47
     48	raw_spin_lock_irqsave(&gt641xx_irq_lock, flags);
     49	mask = GT_READ(GT_INTRMASK_OFS);
     50	mask &= ~GT641XX_IRQ_TO_BIT(d->irq);
     51	GT_WRITE(GT_INTRMASK_OFS, mask);
     52
     53	cause = GT_READ(GT_INTRCAUSE_OFS);
     54	cause &= ~GT641XX_IRQ_TO_BIT(d->irq);
     55	GT_WRITE(GT_INTRCAUSE_OFS, cause);
     56	raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
     57}
     58
     59static void unmask_gt641xx_irq(struct irq_data *d)
     60{
     61	unsigned long flags;
     62	u32 mask;
     63
     64	raw_spin_lock_irqsave(&gt641xx_irq_lock, flags);
     65	mask = GT_READ(GT_INTRMASK_OFS);
     66	mask |= GT641XX_IRQ_TO_BIT(d->irq);
     67	GT_WRITE(GT_INTRMASK_OFS, mask);
     68	raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
     69}
     70
     71static struct irq_chip gt641xx_irq_chip = {
     72	.name		= "GT641xx",
     73	.irq_ack	= ack_gt641xx_irq,
     74	.irq_mask	= mask_gt641xx_irq,
     75	.irq_mask_ack	= mask_ack_gt641xx_irq,
     76	.irq_unmask	= unmask_gt641xx_irq,
     77};
     78
     79void gt641xx_irq_dispatch(void)
     80{
     81	u32 cause, mask;
     82	int i;
     83
     84	cause = GT_READ(GT_INTRCAUSE_OFS);
     85	mask = GT_READ(GT_INTRMASK_OFS);
     86	cause &= mask;
     87
     88	/*
     89	 * bit0 : logical or of all the interrupt bits.
     90	 * bit30: logical or of bits[29:26,20:1].
     91	 * bit31: logical or of bits[25:1].
     92	 */
     93	for (i = 1; i < 30; i++) {
     94		if (cause & (1U << i)) {
     95			do_IRQ(GT641XX_IRQ_BASE + i);
     96			return;
     97		}
     98	}
     99
    100	atomic_inc(&irq_err_count);
    101}
    102
    103void __init gt641xx_irq_init(void)
    104{
    105	int i;
    106
    107	GT_WRITE(GT_INTRMASK_OFS, 0);
    108	GT_WRITE(GT_INTRCAUSE_OFS, 0);
    109
    110	/*
    111	 * bit0 : logical or of all the interrupt bits.
    112	 * bit30: logical or of bits[29:26,20:1].
    113	 * bit31: logical or of bits[25:1].
    114	 */
    115	for (i = 1; i < 30; i++)
    116		irq_set_chip_and_handler(GT641XX_IRQ_BASE + i,
    117					 &gt641xx_irq_chip, handle_level_irq);
    118}