^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * arch/powerpc/kernel/mpic.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Driver for interrupt controllers following the OpenPIC standard, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * common implementation being IBM's MPIC. This driver also can deal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * with various broken implementations of this HW.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright 2010-2012 Freescale Semiconductor, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * License. See the file COPYING in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #undef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #undef DEBUG_IPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #undef DEBUG_IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #undef DEBUG_LOW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/syscore_ops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/ratelimit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <asm/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <asm/machdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <asm/mpic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <asm/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include "mpic.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define DBG(fmt...) printk(fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define DBG(fmt...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct bus_type mpic_subsys = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .name = "mpic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .dev_name = "mpic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) EXPORT_SYMBOL_GPL(mpic_subsys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static struct mpic *mpics;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static struct mpic *mpic_primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static DEFINE_RAW_SPINLOCK(mpic_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #ifdef CONFIG_PPC32 /* XXX for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #ifdef CONFIG_IRQ_ALL_CPUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define distribute_irqs (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define distribute_irqs (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #ifdef CONFIG_MPIC_WEIRD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static u32 mpic_infos[][MPIC_IDX_END] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) [0] = { /* Original OpenPIC compatible MPIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) MPIC_GREG_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) MPIC_GREG_FEATURE_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) MPIC_GREG_GLOBAL_CONF_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) MPIC_GREG_VENDOR_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) MPIC_GREG_IPI_VECTOR_PRI_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) MPIC_GREG_IPI_STRIDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) MPIC_GREG_SPURIOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) MPIC_GREG_TIMER_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) MPIC_TIMER_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) MPIC_TIMER_STRIDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) MPIC_TIMER_CURRENT_CNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) MPIC_TIMER_BASE_CNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) MPIC_TIMER_VECTOR_PRI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) MPIC_TIMER_DESTINATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) MPIC_CPU_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) MPIC_CPU_STRIDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) MPIC_CPU_IPI_DISPATCH_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) MPIC_CPU_IPI_DISPATCH_STRIDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) MPIC_CPU_CURRENT_TASK_PRI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) MPIC_CPU_WHOAMI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) MPIC_CPU_INTACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) MPIC_CPU_EOI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) MPIC_CPU_MCACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) MPIC_IRQ_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) MPIC_IRQ_STRIDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) MPIC_IRQ_VECTOR_PRI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) MPIC_VECPRI_VECTOR_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) MPIC_VECPRI_POLARITY_POSITIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) MPIC_VECPRI_POLARITY_NEGATIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) MPIC_VECPRI_SENSE_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) MPIC_VECPRI_SENSE_EDGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) MPIC_VECPRI_POLARITY_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) MPIC_VECPRI_SENSE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) MPIC_IRQ_DESTINATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) [1] = { /* Tsi108/109 PIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) TSI108_GREG_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) TSI108_GREG_FEATURE_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) TSI108_GREG_GLOBAL_CONF_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) TSI108_GREG_VENDOR_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) TSI108_GREG_IPI_VECTOR_PRI_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) TSI108_GREG_IPI_STRIDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) TSI108_GREG_SPURIOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) TSI108_GREG_TIMER_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) TSI108_TIMER_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) TSI108_TIMER_STRIDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) TSI108_TIMER_CURRENT_CNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) TSI108_TIMER_BASE_CNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) TSI108_TIMER_VECTOR_PRI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) TSI108_TIMER_DESTINATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) TSI108_CPU_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) TSI108_CPU_STRIDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) TSI108_CPU_IPI_DISPATCH_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) TSI108_CPU_IPI_DISPATCH_STRIDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) TSI108_CPU_CURRENT_TASK_PRI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) TSI108_CPU_WHOAMI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) TSI108_CPU_INTACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) TSI108_CPU_EOI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) TSI108_CPU_MCACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) TSI108_IRQ_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) TSI108_IRQ_STRIDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) TSI108_IRQ_VECTOR_PRI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) TSI108_VECPRI_VECTOR_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) TSI108_VECPRI_POLARITY_POSITIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) TSI108_VECPRI_POLARITY_NEGATIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) TSI108_VECPRI_SENSE_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) TSI108_VECPRI_SENSE_EDGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) TSI108_VECPRI_POLARITY_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) TSI108_VECPRI_SENSE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) TSI108_IRQ_DESTINATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define MPIC_INFO(name) mpic->hw_set[MPIC_IDX_##name]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #else /* CONFIG_MPIC_WEIRD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define MPIC_INFO(name) MPIC_##name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #endif /* CONFIG_MPIC_WEIRD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static inline unsigned int mpic_processor_id(struct mpic *mpic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) unsigned int cpu = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (!(mpic->flags & MPIC_SECONDARY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) cpu = hard_smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * Register accessor functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static inline u32 _mpic_read(enum mpic_reg_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct mpic_reg_bank *rb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) switch(type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #ifdef CONFIG_PPC_DCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) case mpic_access_dcr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return dcr_read(rb->dhost, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) case mpic_access_mmio_be:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return in_be32(rb->base + (reg >> 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) case mpic_access_mmio_le:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return in_le32(rb->base + (reg >> 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static inline void _mpic_write(enum mpic_reg_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct mpic_reg_bank *rb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) unsigned int reg, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) switch(type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #ifdef CONFIG_PPC_DCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) case mpic_access_dcr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) dcr_write(rb->dhost, reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) case mpic_access_mmio_be:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) out_be32(rb->base + (reg >> 2), value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) case mpic_access_mmio_le:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) out_le32(rb->base + (reg >> 2), value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) enum mpic_reg_type type = mpic->reg_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) (ipi * MPIC_INFO(GREG_IPI_STRIDE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if ((mpic->flags & MPIC_BROKEN_IPI) && type == mpic_access_mmio_le)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) type = mpic_access_mmio_be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return _mpic_read(type, &mpic->gregs, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) (ipi * MPIC_INFO(GREG_IPI_STRIDE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) _mpic_write(mpic->reg_type, &mpic->gregs, offset, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static inline unsigned int mpic_tm_offset(struct mpic *mpic, unsigned int tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return (tm >> 2) * MPIC_TIMER_GROUP_STRIDE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) (tm & 3) * MPIC_INFO(TIMER_STRIDE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static inline u32 _mpic_tm_read(struct mpic *mpic, unsigned int tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) unsigned int offset = mpic_tm_offset(mpic, tm) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) MPIC_INFO(TIMER_VECTOR_PRI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return _mpic_read(mpic->reg_type, &mpic->tmregs, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static inline void _mpic_tm_write(struct mpic *mpic, unsigned int tm, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) unsigned int offset = mpic_tm_offset(mpic, tm) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) MPIC_INFO(TIMER_VECTOR_PRI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) _mpic_write(mpic->reg_type, &mpic->tmregs, offset, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) unsigned int cpu = mpic_processor_id(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return _mpic_read(mpic->reg_type, &mpic->cpuregs[cpu], reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) unsigned int cpu = mpic_processor_id(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) _mpic_write(mpic->reg_type, &mpic->cpuregs[cpu], reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) unsigned int isu = src_no >> mpic->isu_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) unsigned int idx = src_no & mpic->isu_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) val = _mpic_read(mpic->reg_type, &mpic->isus[isu],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) reg + (idx * MPIC_INFO(IRQ_STRIDE)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) #ifdef CONFIG_MPIC_BROKEN_REGREAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (reg == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) val = (val & (MPIC_VECPRI_MASK | MPIC_VECPRI_ACTIVITY)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) mpic->isu_reg0_shadow[src_no];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) unsigned int reg, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) unsigned int isu = src_no >> mpic->isu_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) unsigned int idx = src_no & mpic->isu_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) _mpic_write(mpic->reg_type, &mpic->isus[isu],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) reg + (idx * MPIC_INFO(IRQ_STRIDE)), value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #ifdef CONFIG_MPIC_BROKEN_REGREAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (reg == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) mpic->isu_reg0_shadow[src_no] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) value & ~(MPIC_VECPRI_MASK | MPIC_VECPRI_ACTIVITY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) #define mpic_read(b,r) _mpic_read(mpic->reg_type,&(b),(r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) #define mpic_write(b,r,v) _mpic_write(mpic->reg_type,&(b),(r),(v))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) #define mpic_ipi_read(i) _mpic_ipi_read(mpic,(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) #define mpic_ipi_write(i,v) _mpic_ipi_write(mpic,(i),(v))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) #define mpic_tm_read(i) _mpic_tm_read(mpic,(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) #define mpic_tm_write(i,v) _mpic_tm_write(mpic,(i),(v))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) #define mpic_cpu_read(i) _mpic_cpu_read(mpic,(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) #define mpic_cpu_write(i,v) _mpic_cpu_write(mpic,(i),(v))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) #define mpic_irq_read(s,r) _mpic_irq_read(mpic,(s),(r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) #define mpic_irq_write(s,r,v) _mpic_irq_write(mpic,(s),(r),(v))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * Low level utility functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static void _mpic_map_mmio(struct mpic *mpic, phys_addr_t phys_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct mpic_reg_bank *rb, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) unsigned int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) rb->base = ioremap(phys_addr + offset, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) BUG_ON(rb->base == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) #ifdef CONFIG_PPC_DCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) unsigned int offset, unsigned int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) phys_addr_t phys_addr = dcr_resource_start(mpic->node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) rb->dhost = dcr_map(mpic->node, phys_addr + offset, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) BUG_ON(!DCR_MAP_OK(rb->dhost));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static inline void mpic_map(struct mpic *mpic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) phys_addr_t phys_addr, struct mpic_reg_bank *rb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) unsigned int offset, unsigned int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (mpic->flags & MPIC_USES_DCR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) _mpic_map_dcr(mpic, rb, offset, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) _mpic_map_mmio(mpic, phys_addr, rb, offset, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) #else /* CONFIG_PPC_DCR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) #define mpic_map(m,p,b,o,s) _mpic_map_mmio(m,p,b,o,s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) #endif /* !CONFIG_PPC_DCR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* Check if we have one of those nice broken MPICs with a flipped endian on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * reads from IPI registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static void __init mpic_test_broken_ipi(struct mpic *mpic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) u32 r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) mpic_write(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0), MPIC_VECPRI_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) r = mpic_read(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (r == le32_to_cpu(MPIC_VECPRI_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) printk(KERN_INFO "mpic: Detected reversed IPI registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) mpic->flags |= MPIC_BROKEN_IPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) #ifdef CONFIG_MPIC_U3_HT_IRQS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /* Test if an interrupt is sourced from HyperTransport (used on broken U3s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * to force the edge setting on the MPIC and do the ack workaround.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (source >= 128 || !mpic->fixups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return mpic->fixups[source].base != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static inline void mpic_ht_end_irq(struct mpic *mpic, unsigned int source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) struct mpic_irq_fixup *fixup = &mpic->fixups[source];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (fixup->applebase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) unsigned int soff = (fixup->index >> 3) & ~3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) unsigned int mask = 1U << (fixup->index & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) writel(mask, fixup->applebase + soff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) raw_spin_lock(&mpic->fixup_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) writeb(0x11 + 2 * fixup->index, fixup->base + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) writel(fixup->data, fixup->base + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) raw_spin_unlock(&mpic->fixup_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) bool level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) struct mpic_irq_fixup *fixup = &mpic->fixups[source];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (fixup->base == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) DBG("startup_ht_interrupt(0x%x) index: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) source, fixup->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) raw_spin_lock_irqsave(&mpic->fixup_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /* Enable and configure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) writeb(0x10 + 2 * fixup->index, fixup->base + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) tmp = readl(fixup->base + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) tmp &= ~(0x23U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) tmp |= 0x22;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) writel(tmp, fixup->base + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) raw_spin_unlock_irqrestore(&mpic->fixup_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /* use the lowest bit inverted to the actual HW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * set if this fixup was enabled, clear otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) mpic->save_data[source].fixup_data = tmp | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) struct mpic_irq_fixup *fixup = &mpic->fixups[source];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (fixup->base == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) DBG("shutdown_ht_interrupt(0x%x)\n", source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* Disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) raw_spin_lock_irqsave(&mpic->fixup_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) writeb(0x10 + 2 * fixup->index, fixup->base + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) tmp = readl(fixup->base + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) tmp |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) writel(tmp, fixup->base + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) raw_spin_unlock_irqrestore(&mpic->fixup_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /* use the lowest bit inverted to the actual HW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * set if this fixup was enabled, clear otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) mpic->save_data[source].fixup_data = tmp & ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) #ifdef CONFIG_PCI_MSI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static void __init mpic_scan_ht_msi(struct mpic *mpic, u8 __iomem *devbase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) unsigned int devfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) u8 __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) u8 pos, flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) u64 addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) u8 id = readb(devbase + pos + PCI_CAP_LIST_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (id == PCI_CAP_ID_HT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) id = readb(devbase + pos + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if ((id & HT_5BIT_CAP_MASK) == HT_CAPTYPE_MSI_MAPPING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (pos == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) base = devbase + pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) flags = readb(base + HT_MSI_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (!(flags & HT_MSI_FLAGS_FIXED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) addr = readl(base + HT_MSI_ADDR_LO) & HT_MSI_ADDR_LO_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) addr = addr | ((u64)readl(base + HT_MSI_ADDR_HI) << 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) printk(KERN_DEBUG "mpic: - HT:%02x.%x %s MSI mapping found @ 0x%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) PCI_SLOT(devfn), PCI_FUNC(devfn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) flags & HT_MSI_FLAGS_ENABLE ? "enabled" : "disabled", addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (!(flags & HT_MSI_FLAGS_ENABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) writeb(flags | HT_MSI_FLAGS_ENABLE, base + HT_MSI_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static void __init mpic_scan_ht_msi(struct mpic *mpic, u8 __iomem *devbase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) unsigned int devfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) unsigned int devfn, u32 vdid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) int i, irq, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) u8 __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) u8 pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) u8 id = readb(devbase + pos + PCI_CAP_LIST_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (id == PCI_CAP_ID_HT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) id = readb(devbase + pos + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if ((id & HT_5BIT_CAP_MASK) == HT_CAPTYPE_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (pos == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) base = devbase + pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) writeb(0x01, base + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) n = (readl(base + 4) >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) printk(KERN_INFO "mpic: - HT:%02x.%x [0x%02x] vendor %04x device %04x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) " has %d irqs\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) devfn >> 3, devfn & 0x7, pos, vdid & 0xffff, vdid >> 16, n + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) for (i = 0; i <= n; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) writeb(0x10 + 2 * i, base + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) tmp = readl(base + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) irq = (tmp >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) DBG("HT PIC index 0x%x, irq 0x%x, tmp: %08x\n", i, irq, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /* mask it , will be unmasked later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) tmp |= 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) writel(tmp, base + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) mpic->fixups[irq].index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) mpic->fixups[irq].base = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /* Apple HT PIC has a non-standard way of doing EOIs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if ((vdid & 0xffff) == 0x106b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) mpic->fixups[irq].applebase = devbase + 0x60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) mpic->fixups[irq].applebase = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) writeb(0x11 + 2 * i, base + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) mpic->fixups[irq].data = readl(base + 4) | 0x80000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static void __init mpic_scan_ht_pics(struct mpic *mpic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) unsigned int devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) u8 __iomem *cfgspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) printk(KERN_INFO "mpic: Setting up HT PICs workarounds for U3/U4\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) /* Allocate fixups array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) mpic->fixups = kcalloc(128, sizeof(*mpic->fixups), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) BUG_ON(mpic->fixups == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* Init spinlock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) raw_spin_lock_init(&mpic->fixup_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) /* Map U3 config space. We assume all IO-APICs are on the primary bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * so we only need to map 64kB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) cfgspace = ioremap(0xf2000000, 0x10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) BUG_ON(cfgspace == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /* Now we scan all slots. We do a very quick scan, we read the header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * type, vendor ID and device ID only, that's plenty enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) for (devfn = 0; devfn < 0x100; devfn++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) u8 __iomem *devbase = cfgspace + (devfn << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) u8 hdr_type = readb(devbase + PCI_HEADER_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) u32 l = readl(devbase + PCI_VENDOR_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) u16 s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) DBG("devfn %x, l: %x\n", devfn, l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /* If no device, skip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (l == 0xffffffff || l == 0x00000000 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) l == 0x0000ffff || l == 0xffff0000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /* Check if is supports capability lists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) s = readw(devbase + PCI_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (!(s & PCI_STATUS_CAP_LIST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) mpic_scan_ht_pic(mpic, devbase, devfn, l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) mpic_scan_ht_msi(mpic, devbase, devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /* next device, if function 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (PCI_FUNC(devfn) == 0 && (hdr_type & 0x80) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) devfn += 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) #else /* CONFIG_MPIC_U3_HT_IRQS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static void __init mpic_scan_ht_pics(struct mpic *mpic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) #endif /* CONFIG_MPIC_U3_HT_IRQS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) /* Find an mpic associated with a given linux interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) static struct mpic *mpic_find(unsigned int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (irq < NUM_ISA_INTERRUPTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return irq_get_chip_data(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* Determine if the linux irq is an IPI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /* Determine if the linux irq is a timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return (src >= mpic->timer_vecs[0] && src <= mpic->timer_vecs[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /* Convert a cpu mask from logical to physical cpu numbers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static inline u32 mpic_physmask(u32 cpumask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) u32 mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) for (i = 0; i < min(32, NR_CPUS) && cpu_possible(i); ++i, cpumask >>= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) mask |= (cpumask & 1) << get_hard_smp_processor_id(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) /* Get the mpic structure from the IPI number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) static inline struct mpic * mpic_from_ipi(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /* Get the mpic structure from the irq number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) static inline struct mpic * mpic_from_irq(unsigned int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return irq_get_chip_data(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) /* Get the mpic structure from the irq data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static inline struct mpic * mpic_from_irq_data(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) /* Send an EOI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static inline void mpic_eoi(struct mpic *mpic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) mpic_cpu_write(MPIC_INFO(CPU_EOI), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * Linux descriptor level callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) void mpic_unmask_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) unsigned int loops = 100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct mpic *mpic = mpic_from_irq_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) unsigned int src = irqd_to_hwirq(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, d->irq, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) ~MPIC_VECPRI_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /* make sure mask gets to controller before we return to user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (!loops--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) printk(KERN_ERR "%s: timeout on hwirq %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) __func__, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) } while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) void mpic_mask_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) unsigned int loops = 100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct mpic *mpic = mpic_from_irq_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) unsigned int src = irqd_to_hwirq(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) DBG("%s: disable_irq: %d (src %d)\n", mpic->name, d->irq, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) MPIC_VECPRI_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) /* make sure mask gets to controller before we return to user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (!loops--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) printk(KERN_ERR "%s: timeout on hwirq %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) __func__, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) } while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) void mpic_end_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) struct mpic *mpic = mpic_from_irq_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) #ifdef DEBUG_IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) DBG("%s: end_irq: %d\n", mpic->name, d->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) /* We always EOI on end_irq() even for edge interrupts since that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) * should only lower the priority, the MPIC should have properly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) * latched another edge interrupt coming in anyway
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) mpic_eoi(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) #ifdef CONFIG_MPIC_U3_HT_IRQS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) static void mpic_unmask_ht_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) struct mpic *mpic = mpic_from_irq_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) unsigned int src = irqd_to_hwirq(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) mpic_unmask_irq(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (irqd_is_level_type(d))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) mpic_ht_end_irq(mpic, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static unsigned int mpic_startup_ht_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct mpic *mpic = mpic_from_irq_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) unsigned int src = irqd_to_hwirq(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) mpic_unmask_irq(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) mpic_startup_ht_interrupt(mpic, src, irqd_is_level_type(d));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) static void mpic_shutdown_ht_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct mpic *mpic = mpic_from_irq_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) unsigned int src = irqd_to_hwirq(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) mpic_shutdown_ht_interrupt(mpic, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) mpic_mask_irq(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) static void mpic_end_ht_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct mpic *mpic = mpic_from_irq_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) unsigned int src = irqd_to_hwirq(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) #ifdef DEBUG_IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) DBG("%s: end_irq: %d\n", mpic->name, d->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) /* We always EOI on end_irq() even for edge interrupts since that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) * should only lower the priority, the MPIC should have properly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) * latched another edge interrupt coming in anyway
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (irqd_is_level_type(d))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) mpic_ht_end_irq(mpic, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) mpic_eoi(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) #endif /* !CONFIG_MPIC_U3_HT_IRQS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) static void mpic_unmask_ipi(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) struct mpic *mpic = mpic_from_ipi(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) unsigned int src = virq_to_hw(d->irq) - mpic->ipi_vecs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, d->irq, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) static void mpic_mask_ipi(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* NEVER disable an IPI... that's just plain wrong! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) static void mpic_end_ipi(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) struct mpic *mpic = mpic_from_ipi(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) * IPIs are marked IRQ_PER_CPU. This has the side effect of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * applying to them. We EOI them late to avoid re-entering.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) mpic_eoi(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) #endif /* CONFIG_SMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) static void mpic_unmask_tm(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) struct mpic *mpic = mpic_from_irq_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) unsigned int src = virq_to_hw(d->irq) - mpic->timer_vecs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) DBG("%s: enable_tm: %d (tm %d)\n", mpic->name, d->irq, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) mpic_tm_write(src, mpic_tm_read(src) & ~MPIC_VECPRI_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) mpic_tm_read(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) static void mpic_mask_tm(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) struct mpic *mpic = mpic_from_irq_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) unsigned int src = virq_to_hw(d->irq) - mpic->timer_vecs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) mpic_tm_write(src, mpic_tm_read(src) | MPIC_VECPRI_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) mpic_tm_read(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) int mpic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) bool force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) struct mpic *mpic = mpic_from_irq_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) unsigned int src = irqd_to_hwirq(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) int cpuid = irq_choose_cpu(cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) u32 mask = cpumask_bits(cpumask)[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) mask &= cpumask_bits(cpu_online_mask)[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) mpic_physmask(mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return IRQ_SET_MASK_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) /* Now convert sense value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) switch(type & IRQ_TYPE_SENSE_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) case IRQ_TYPE_EDGE_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) return MPIC_INFO(VECPRI_SENSE_EDGE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) MPIC_INFO(VECPRI_POLARITY_POSITIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) case IRQ_TYPE_EDGE_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) case IRQ_TYPE_EDGE_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) return MPIC_INFO(VECPRI_SENSE_EDGE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) case IRQ_TYPE_LEVEL_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return MPIC_INFO(VECPRI_SENSE_LEVEL) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) MPIC_INFO(VECPRI_POLARITY_POSITIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) case IRQ_TYPE_LEVEL_LOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return MPIC_INFO(VECPRI_SENSE_LEVEL) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) struct mpic *mpic = mpic_from_irq_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) unsigned int src = irqd_to_hwirq(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) unsigned int vecpri, vold, vnew;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) mpic, d->irq, src, flow_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (src >= mpic->num_sources)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) /* We don't support "none" type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (flow_type == IRQ_TYPE_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) flow_type = IRQ_TYPE_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) /* Default: read HW settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (flow_type == IRQ_TYPE_DEFAULT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) int vold_ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) vold_ps = vold & (MPIC_INFO(VECPRI_POLARITY_MASK) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) MPIC_INFO(VECPRI_SENSE_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (vold_ps == (MPIC_INFO(VECPRI_SENSE_EDGE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) MPIC_INFO(VECPRI_POLARITY_POSITIVE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) flow_type = IRQ_TYPE_EDGE_RISING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) else if (vold_ps == (MPIC_INFO(VECPRI_SENSE_EDGE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) MPIC_INFO(VECPRI_POLARITY_NEGATIVE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) flow_type = IRQ_TYPE_EDGE_FALLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) else if (vold_ps == (MPIC_INFO(VECPRI_SENSE_LEVEL) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) MPIC_INFO(VECPRI_POLARITY_POSITIVE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) flow_type = IRQ_TYPE_LEVEL_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) else if (vold_ps == (MPIC_INFO(VECPRI_SENSE_LEVEL) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) MPIC_INFO(VECPRI_POLARITY_NEGATIVE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) flow_type = IRQ_TYPE_LEVEL_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) WARN_ONCE(1, "mpic: unknown IRQ type %d\n", vold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) /* Apply to irq desc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) irqd_set_trigger_type(d, flow_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /* Apply to HW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (mpic_is_ht_interrupt(mpic, src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) vecpri = MPIC_VECPRI_POLARITY_POSITIVE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) MPIC_VECPRI_SENSE_EDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) vecpri = mpic_type_to_vecpri(mpic, flow_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) MPIC_INFO(VECPRI_SENSE_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) vnew |= vecpri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (vold != vnew)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) return IRQ_SET_MASK_OK_NOCOPY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) void mpic_set_vector(unsigned int virq, unsigned int vector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct mpic *mpic = mpic_from_irq(virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) unsigned int src = virq_to_hw(virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) unsigned int vecpri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) DBG("mpic: set_vector(mpic:@%p,virq:%d,src:%d,vector:0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) mpic, virq, src, vector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (src >= mpic->num_sources)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) vecpri = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) vecpri = vecpri & ~MPIC_INFO(VECPRI_VECTOR_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) vecpri |= vector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) static void mpic_set_destination(unsigned int virq, unsigned int cpuid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) struct mpic *mpic = mpic_from_irq(virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) unsigned int src = virq_to_hw(virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) DBG("mpic: set_destination(mpic:@%p,virq:%d,src:%d,cpuid:0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) mpic, virq, src, cpuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (src >= mpic->num_sources)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) static struct irq_chip mpic_irq_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .irq_mask = mpic_mask_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) .irq_unmask = mpic_unmask_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) .irq_eoi = mpic_end_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) .irq_set_type = mpic_set_irq_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) static const struct irq_chip mpic_ipi_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) .irq_mask = mpic_mask_ipi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) .irq_unmask = mpic_unmask_ipi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) .irq_eoi = mpic_end_ipi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) #endif /* CONFIG_SMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) static struct irq_chip mpic_tm_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) .irq_mask = mpic_mask_tm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) .irq_unmask = mpic_unmask_tm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) .irq_eoi = mpic_end_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) #ifdef CONFIG_MPIC_U3_HT_IRQS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) static const struct irq_chip mpic_irq_ht_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .irq_startup = mpic_startup_ht_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) .irq_shutdown = mpic_shutdown_ht_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) .irq_mask = mpic_mask_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) .irq_unmask = mpic_unmask_ht_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) .irq_eoi = mpic_end_ht_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) .irq_set_type = mpic_set_irq_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) #endif /* CONFIG_MPIC_U3_HT_IRQS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) static int mpic_host_match(struct irq_domain *h, struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) enum irq_domain_bus_token bus_token)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) /* Exact match, unless mpic node is NULL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) struct device_node *of_node = irq_domain_get_of_node(h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return of_node == NULL || of_node == node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static int mpic_host_map(struct irq_domain *h, unsigned int virq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) irq_hw_number_t hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) struct mpic *mpic = h->host_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) struct irq_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) DBG("mpic: map virq %d, hwirq 0x%lx\n", virq, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (hw == mpic->spurious_vec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (mpic->protected && test_bit(hw, mpic->protected)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) pr_warn("mpic: Mapping of source 0x%x failed, source protected by firmware !\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) (unsigned int)hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) else if (hw >= mpic->ipi_vecs[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) WARN_ON(mpic->flags & MPIC_SECONDARY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) DBG("mpic: mapping as IPI\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) irq_set_chip_data(virq, mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) irq_set_chip_and_handler(virq, &mpic->hc_ipi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) handle_percpu_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) #endif /* CONFIG_SMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (hw >= mpic->timer_vecs[0] && hw <= mpic->timer_vecs[7]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) WARN_ON(mpic->flags & MPIC_SECONDARY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) DBG("mpic: mapping as timer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) irq_set_chip_data(virq, mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) irq_set_chip_and_handler(virq, &mpic->hc_tm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) handle_fasteoi_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (mpic_map_error_int(mpic, virq, hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (hw >= mpic->num_sources) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) pr_warn("mpic: Mapping of source 0x%x failed, source out of range !\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) (unsigned int)hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) mpic_msi_reserve_hwirq(mpic, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) /* Default chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) chip = &mpic->hc_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) #ifdef CONFIG_MPIC_U3_HT_IRQS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) /* Check for HT interrupts, override vecpri */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (mpic_is_ht_interrupt(mpic, hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) chip = &mpic->hc_ht_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) #endif /* CONFIG_MPIC_U3_HT_IRQS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) DBG("mpic: mapping to irq chip @%p\n", chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) irq_set_chip_data(virq, mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) irq_set_chip_and_handler(virq, chip, handle_fasteoi_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) /* Set default irq type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) irq_set_irq_type(virq, IRQ_TYPE_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) /* If the MPIC was reset, then all vectors have already been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) * initialized. Otherwise, a per source lazy initialization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) * is done here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (!mpic_is_ipi(mpic, hw) && (mpic->flags & MPIC_NO_RESET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) cpu = mpic_processor_id(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) mpic_set_vector(virq, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) mpic_set_destination(virq, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) mpic_irq_set_priority(virq, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) static int mpic_host_xlate(struct irq_domain *h, struct device_node *ct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) const u32 *intspec, unsigned int intsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) irq_hw_number_t *out_hwirq, unsigned int *out_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) struct mpic *mpic = h->host_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) static unsigned char map_mpic_senses[4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) IRQ_TYPE_EDGE_RISING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) IRQ_TYPE_LEVEL_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) IRQ_TYPE_LEVEL_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) IRQ_TYPE_EDGE_FALLING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) *out_hwirq = intspec[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) if (intsize >= 4 && (mpic->flags & MPIC_FSL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) * Freescale MPIC with extended intspec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) * First two cells are as usual. Third specifies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * an "interrupt type". Fourth is type-specific data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) * See Documentation/devicetree/bindings/powerpc/fsl/mpic.txt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) switch (intspec[2]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) if (!(mpic->flags & MPIC_FSL_HAS_EIMR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (intspec[3] >= ARRAY_SIZE(mpic->err_int_vecs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) *out_hwirq = mpic->err_int_vecs[intspec[3]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (intspec[0] >= ARRAY_SIZE(mpic->ipi_vecs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) *out_hwirq = mpic->ipi_vecs[intspec[0]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if (intspec[0] >= ARRAY_SIZE(mpic->timer_vecs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) *out_hwirq = mpic->timer_vecs[intspec[0]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) pr_debug("%s: unknown irq type %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) __func__, intspec[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) *out_flags = map_mpic_senses[intspec[1] & 3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) } else if (intsize > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) u32 mask = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) /* Apple invented a new race of encoding on machines with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) * an HT APIC. They encode, among others, the index within
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) * the HT APIC. We don't care about it here since thankfully,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) * it appears that they have the APIC already properly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) * configured, and thus our current fixup code that reads the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) * APIC config works fine. However, we still need to mask out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) * bits in the specifier to make sure we only get bit 0 which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) * is the level/edge bit (the only sense bit exposed by Apple),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) * as their bit 1 means something else.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) if (machine_is(powermac))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) mask = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) *out_flags = map_mpic_senses[intspec[1] & mask];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) *out_flags = IRQ_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) DBG("mpic: xlate (%d cells: 0x%08x 0x%08x) to line 0x%lx sense 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) intsize, intspec[0], intspec[1], *out_hwirq, *out_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) /* IRQ handler for a secondary MPIC cascaded from another IRQ controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) static void mpic_cascade(struct irq_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) struct irq_chip *chip = irq_desc_get_chip(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) struct mpic *mpic = irq_desc_get_handler_data(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) unsigned int virq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) BUG_ON(!(mpic->flags & MPIC_SECONDARY));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) virq = mpic_get_one_irq(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) if (virq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) generic_handle_irq(virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) chip->irq_eoi(&desc->irq_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) static const struct irq_domain_ops mpic_host_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) .match = mpic_host_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) .map = mpic_host_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) .xlate = mpic_host_xlate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) static u32 fsl_mpic_get_version(struct mpic *mpic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) u32 brr1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (!(mpic->flags & MPIC_FSL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) MPIC_FSL_BRR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) return brr1 & MPIC_FSL_BRR1_VER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) * Exported functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) u32 fsl_mpic_primary_get_version(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) struct mpic *mpic = mpic_primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) if (mpic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) return fsl_mpic_get_version(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) struct mpic * __init mpic_alloc(struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) phys_addr_t phys_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) unsigned int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) unsigned int isu_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) unsigned int irq_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) int i, psize, intvec_top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) struct mpic *mpic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) u32 greg_feature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) const char *vers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) const u32 *psrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) u32 last_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) u32 fsl_version = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) /* Default MPIC search parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) static const struct of_device_id __initconst mpic_device_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) { .type = "open-pic", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) { .compatible = "open-pic", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) * If we were not passed a device-tree node, then perform the default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) * search for standardized a standardized OpenPIC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) node = of_node_get(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) node = of_find_matching_node(NULL, mpic_device_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) if (!node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) /* Pick the physical address from the device tree if unspecified */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) if (!phys_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) /* Check if it is DCR-based */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (of_property_read_bool(node, "dcr-reg")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) flags |= MPIC_USES_DCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) struct resource r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) if (of_address_to_resource(node, 0, &r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) goto err_of_node_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) phys_addr = r.start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) /* Read extra device-tree properties into the flags variable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (of_get_property(node, "big-endian", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) flags |= MPIC_BIG_ENDIAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) if (of_get_property(node, "pic-no-reset", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) flags |= MPIC_NO_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (of_get_property(node, "single-cpu-affinity", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) flags |= MPIC_SINGLE_DEST_CPU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) if (of_device_is_compatible(node, "fsl,mpic")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) flags |= MPIC_FSL | MPIC_LARGE_VECTORS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) mpic_irq_chip.flags |= IRQCHIP_SKIP_SET_WAKE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) mpic_tm_chip.flags |= IRQCHIP_SKIP_SET_WAKE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (mpic == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) goto err_of_node_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) mpic->name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) mpic->node = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) mpic->paddr = phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) mpic->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) mpic->hc_irq = mpic_irq_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) mpic->hc_irq.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) if (!(mpic->flags & MPIC_SECONDARY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) mpic->hc_irq.irq_set_affinity = mpic_set_affinity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) #ifdef CONFIG_MPIC_U3_HT_IRQS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) mpic->hc_ht_irq = mpic_irq_ht_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) mpic->hc_ht_irq.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) if (!(mpic->flags & MPIC_SECONDARY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) mpic->hc_ht_irq.irq_set_affinity = mpic_set_affinity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) #endif /* CONFIG_MPIC_U3_HT_IRQS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) mpic->hc_ipi = mpic_ipi_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) mpic->hc_ipi.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) #endif /* CONFIG_SMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) mpic->hc_tm = mpic_tm_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) mpic->hc_tm.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) mpic->num_sources = 0; /* so far */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) if (mpic->flags & MPIC_LARGE_VECTORS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) intvec_top = 2047;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) intvec_top = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) mpic->timer_vecs[0] = intvec_top - 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) mpic->timer_vecs[1] = intvec_top - 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) mpic->timer_vecs[2] = intvec_top - 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) mpic->timer_vecs[3] = intvec_top - 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) mpic->timer_vecs[4] = intvec_top - 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) mpic->timer_vecs[5] = intvec_top - 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) mpic->timer_vecs[6] = intvec_top - 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) mpic->timer_vecs[7] = intvec_top - 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) mpic->ipi_vecs[0] = intvec_top - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) mpic->ipi_vecs[1] = intvec_top - 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) mpic->ipi_vecs[2] = intvec_top - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) mpic->ipi_vecs[3] = intvec_top - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) mpic->spurious_vec = intvec_top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) /* Look for protected sources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) psrc = of_get_property(mpic->node, "protected-sources", &psize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) if (psrc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) /* Allocate a bitmap with one bit per interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) unsigned int mapsize = BITS_TO_LONGS(intvec_top + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) mpic->protected = kcalloc(mapsize, sizeof(long), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) BUG_ON(mpic->protected == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) for (i = 0; i < psize/sizeof(u32); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) if (psrc[i] > intvec_top)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) __set_bit(psrc[i], mpic->protected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) #ifdef CONFIG_MPIC_WEIRD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) mpic->hw_set = mpic_infos[MPIC_GET_REGSET(mpic->flags)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) /* default register type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) if (mpic->flags & MPIC_BIG_ENDIAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) mpic->reg_type = mpic_access_mmio_be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) mpic->reg_type = mpic_access_mmio_le;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) * An MPIC with a "dcr-reg" property must be accessed that way, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) * only if the kernel includes DCR support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) #ifdef CONFIG_PPC_DCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) if (mpic->flags & MPIC_USES_DCR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) mpic->reg_type = mpic_access_dcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) BUG_ON(mpic->flags & MPIC_USES_DCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) /* Map the global registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) mpic_map(mpic, mpic->paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if (mpic->flags & MPIC_FSL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) * Yes, Freescale really did put global registers in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) * magic per-cpu area -- and they don't even show up in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) * non-magic per-cpu copies that this driver normally uses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) mpic_map(mpic, mpic->paddr, &mpic->thiscpuregs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) MPIC_CPU_THISBASE, 0x1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) fsl_version = fsl_mpic_get_version(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) /* Error interrupt mask register (EIMR) is required for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) * handling individual device error interrupts. EIMR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) * was added in MPIC version 4.1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) * Over here we reserve vector number space for error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) * interrupt vectors. This space is stolen from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) * global vector number space, as in case of ipis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) * and timer interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) * Available vector space = intvec_top - 13, where 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) * is the number of vectors which have been consumed by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) * ipis, timer interrupts and spurious.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) if (fsl_version >= 0x401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) ret = mpic_setup_error_int(mpic, intvec_top - 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) * EPR is only available starting with v4.0. To support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) * platforms that don't know the MPIC version at compile-time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) * such as qemu-e500, turn off coreint if this MPIC doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) * support it. Note that we never enable it if it wasn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) * requested in the first place.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) * This is done outside the MPIC_FSL check, so that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) * also disable coreint if the MPIC node doesn't have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) * an "fsl,mpic" compatible at all. This will be the case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) * with device trees generated by older versions of QEMU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) * fsl_version will be zero if MPIC_FSL is not set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) if (fsl_version < 0x400 && (flags & MPIC_ENABLE_COREINT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) WARN_ON(ppc_md.get_irq != mpic_get_coreint_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) ppc_md.get_irq = mpic_get_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) /* Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) /* When using a device-node, reset requests are only honored if the MPIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) * is allowed to reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) if (!(mpic->flags & MPIC_NO_RESET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) printk(KERN_DEBUG "mpic: Resetting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) | MPIC_GREG_GCONF_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) while( mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) & MPIC_GREG_GCONF_RESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) /* CoreInt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) if (mpic->flags & MPIC_ENABLE_COREINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) | MPIC_GREG_GCONF_COREINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if (mpic->flags & MPIC_ENABLE_MCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) | MPIC_GREG_GCONF_MCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) * The MPIC driver will crash if there are more cores than we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) * can initialize, so we may as well catch that problem here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) BUG_ON(num_possible_cpus() > MPIC_MAX_CPUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) /* Map the per-CPU registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) for_each_possible_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) unsigned int cpu = get_hard_smp_processor_id(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) mpic_map(mpic, mpic->paddr, &mpic->cpuregs[cpu],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) MPIC_INFO(CPU_BASE) + cpu * MPIC_INFO(CPU_STRIDE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 0x1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) * Read feature register. For non-ISU MPICs, num sources as well. On
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) * ISU MPICs, sources are counted as ISUs are added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) * By default, the last source number comes from the MPIC, but the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) * device-tree and board support code can override it on buggy hw.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) * If we get passed an isu_size (multi-isu MPIC) then we use that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) * as a default instead of the value read from the HW.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) last_irq = (greg_feature & MPIC_GREG_FEATURE_LAST_SRC_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) if (isu_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) last_irq = isu_size * MPIC_MAX_ISU - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) of_property_read_u32(mpic->node, "last-interrupt-source", &last_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) if (irq_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) last_irq = irq_count - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) /* Initialize main ISU if none provided */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) if (!isu_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) isu_size = last_irq + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) mpic->num_sources = isu_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) mpic_map(mpic, mpic->paddr, &mpic->isus[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) MPIC_INFO(IRQ_BASE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) MPIC_INFO(IRQ_STRIDE) * isu_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) mpic->isu_size = isu_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) mpic->isu_mask = (1 << mpic->isu_shift) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) mpic->irqhost = irq_domain_add_linear(mpic->node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) intvec_top,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) &mpic_host_ops, mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) * FIXME: The code leaks the MPIC object and mappings here; this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) * is very unlikely to fail but it ought to be fixed anyways.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) if (mpic->irqhost == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) /* Display version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) switch (greg_feature & MPIC_GREG_FEATURE_VERSION_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) vers = "1.0";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) vers = "1.2";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) vers = "1.3";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) vers = "<unknown>";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) " max %d CPUs\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) name, vers, (unsigned long long)mpic->paddr, num_possible_cpus());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) mpic->isu_size, mpic->isu_shift, mpic->isu_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) mpic->next = mpics;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) mpics = mpic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) if (!(mpic->flags & MPIC_SECONDARY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) mpic_primary = mpic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) irq_set_default_host(mpic->irqhost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) return mpic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) err_of_node_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) phys_addr_t paddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) unsigned int isu_first = isu_num * mpic->isu_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) BUG_ON(isu_num >= MPIC_MAX_ISU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) mpic_map(mpic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) paddr, &mpic->isus[isu_num], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) if ((isu_first + mpic->isu_size) > mpic->num_sources)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) mpic->num_sources = isu_first + mpic->isu_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) void __init mpic_init(struct mpic *mpic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) int i, cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) int num_timers = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) BUG_ON(mpic->num_sources == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) /* Set current processor priority to max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) if (mpic->flags & MPIC_FSL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) u32 version = fsl_mpic_get_version(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) * Timer group B is present at the latest in MPIC 3.1 (e.g.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) * mpc8536). It is not present in MPIC 2.0 (e.g. mpc8544).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) * I don't know about the status of intermediate versions (or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) * whether they even exist).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) if (version >= 0x0301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) num_timers = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) /* Initialize timers to our reserved vectors and mask them for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) for (i = 0; i < num_timers; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) unsigned int offset = mpic_tm_offset(mpic, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) mpic_write(mpic->tmregs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) offset + MPIC_INFO(TIMER_DESTINATION),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 1 << hard_smp_processor_id());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) mpic_write(mpic->tmregs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) offset + MPIC_INFO(TIMER_VECTOR_PRI),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) MPIC_VECPRI_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) (9 << MPIC_VECPRI_PRIORITY_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) (mpic->timer_vecs[0] + i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) /* Initialize IPIs to our reserved vectors and mark them disabled for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) mpic_test_broken_ipi(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) mpic_ipi_write(i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) MPIC_VECPRI_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) (10 << MPIC_VECPRI_PRIORITY_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) (mpic->ipi_vecs[0] + i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) /* Do the HT PIC fixups on U3 broken mpic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) DBG("MPIC flags: %x\n", mpic->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) if ((mpic->flags & MPIC_U3_HT_IRQS) && !(mpic->flags & MPIC_SECONDARY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) mpic_scan_ht_pics(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) mpic_u3msi_init(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) mpic_pasemi_msi_init(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) cpu = mpic_processor_id(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) if (!(mpic->flags & MPIC_NO_RESET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) for (i = 0; i < mpic->num_sources; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) /* start with vector = source number, and masked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) u32 vecpri = MPIC_VECPRI_MASK | i |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) (8 << MPIC_VECPRI_PRIORITY_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) /* check if protected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) if (mpic->protected && test_bit(i, mpic->protected))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) /* init hw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), 1 << cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) /* Init spurious vector */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), mpic->spurious_vec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) /* Disable 8259 passthrough, if supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) if (!(mpic->flags & MPIC_NO_PTHROU_DIS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) | MPIC_GREG_GCONF_8259_PTHROU_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) if (mpic->flags & MPIC_NO_BIAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) | MPIC_GREG_GCONF_NO_BIAS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) /* Set current processor priority to 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) /* allocate memory to save mpic state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) mpic->save_data = kmalloc_array(mpic->num_sources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) sizeof(*mpic->save_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) BUG_ON(mpic->save_data == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) /* Check if this MPIC is chained from a parent interrupt controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) if (mpic->flags & MPIC_SECONDARY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) int virq = irq_of_parse_and_map(mpic->node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) if (virq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) printk(KERN_INFO "%pOF: hooking up to IRQ %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) mpic->node, virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) irq_set_handler_data(virq, mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) irq_set_chained_handler(virq, &mpic_cascade);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) /* FSL mpic error interrupt initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) if (mpic->flags & MPIC_FSL_HAS_EIMR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) mpic_err_int_init(mpic, MPIC_FSL_ERR_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) struct mpic *mpic = mpic_find(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) unsigned int src = virq_to_hw(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) if (!mpic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) raw_spin_lock_irqsave(&mpic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) if (mpic_is_ipi(mpic, src)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) ~MPIC_VECPRI_PRIORITY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) mpic_ipi_write(src - mpic->ipi_vecs[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) } else if (mpic_is_tm(mpic, src)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) reg = mpic_tm_read(src - mpic->timer_vecs[0]) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) ~MPIC_VECPRI_PRIORITY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) mpic_tm_write(src - mpic->timer_vecs[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) & ~MPIC_VECPRI_PRIORITY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) raw_spin_unlock_irqrestore(&mpic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) void mpic_setup_this_cpu(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) struct mpic *mpic = mpic_primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) u32 msk = 1 << hard_smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) BUG_ON(mpic == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) DBG("%s: setup_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) raw_spin_lock_irqsave(&mpic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) /* let the mpic know we want intrs. default affinity is 0xffffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) * until changed via /proc. That's how it's done on x86. If we want
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) * it differently, then we should make sure we also change the default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) * values of irq_desc[].affinity in irq.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) if (distribute_irqs && !(mpic->flags & MPIC_SINGLE_DEST_CPU)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) for (i = 0; i < mpic->num_sources ; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) /* Set current processor priority to 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) raw_spin_unlock_irqrestore(&mpic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) #endif /* CONFIG_SMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) int mpic_cpu_get_priority(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) struct mpic *mpic = mpic_primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) return mpic_cpu_read(MPIC_INFO(CPU_CURRENT_TASK_PRI));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) void mpic_cpu_set_priority(int prio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) struct mpic *mpic = mpic_primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) prio &= MPIC_CPU_TASKPRI_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), prio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) void mpic_teardown_this_cpu(int secondary)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) struct mpic *mpic = mpic_primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) u32 msk = 1 << hard_smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) BUG_ON(mpic == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) DBG("%s: teardown_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) raw_spin_lock_irqsave(&mpic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) /* let the mpic know we don't want intrs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) for (i = 0; i < mpic->num_sources ; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) & ~msk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) /* Set current processor priority to max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) /* We need to EOI the IPI since not all platforms reset the MPIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) * on boot and new interrupts wouldn't get delivered otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) mpic_eoi(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) raw_spin_unlock_irqrestore(&mpic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) static unsigned int _mpic_get_one_irq(struct mpic *mpic, int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) u32 src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) src = mpic_cpu_read(reg) & MPIC_INFO(VECPRI_VECTOR_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) #ifdef DEBUG_LOW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) DBG("%s: get_one_irq(reg 0x%x): %d\n", mpic->name, reg, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) if (unlikely(src == mpic->spurious_vec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) if (mpic->flags & MPIC_SPV_EOI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) mpic_eoi(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) if (unlikely(mpic->protected && test_bit(src, mpic->protected))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) printk_ratelimited(KERN_WARNING "%s: Got protected source %d !\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) mpic->name, (int)src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) mpic_eoi(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) return irq_linear_revmap(mpic->irqhost, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) unsigned int mpic_get_one_irq(struct mpic *mpic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) return _mpic_get_one_irq(mpic, MPIC_INFO(CPU_INTACK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) unsigned int mpic_get_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) struct mpic *mpic = mpic_primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) BUG_ON(mpic == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) return mpic_get_one_irq(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) unsigned int mpic_get_coreint_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) #ifdef CONFIG_BOOKE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) struct mpic *mpic = mpic_primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) u32 src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) BUG_ON(mpic == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) src = mfspr(SPRN_EPR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) if (unlikely(src == mpic->spurious_vec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) if (mpic->flags & MPIC_SPV_EOI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) mpic_eoi(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) if (unlikely(mpic->protected && test_bit(src, mpic->protected))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) printk_ratelimited(KERN_WARNING "%s: Got protected source %d !\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) mpic->name, (int)src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) return irq_linear_revmap(mpic->irqhost, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) unsigned int mpic_get_mcirq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) struct mpic *mpic = mpic_primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) BUG_ON(mpic == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) return _mpic_get_one_irq(mpic, MPIC_INFO(CPU_MCACK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) void mpic_request_ipis(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) struct mpic *mpic = mpic_primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) BUG_ON(mpic == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) printk(KERN_INFO "mpic: requesting IPIs...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) unsigned int vipi = irq_create_mapping(mpic->irqhost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) mpic->ipi_vecs[0] + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) if (!vipi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) printk(KERN_ERR "Failed to map %s\n", smp_ipi_name[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) smp_request_message_ipi(vipi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) void smp_mpic_message_pass(int cpu, int msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) struct mpic *mpic = mpic_primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) u32 physmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) BUG_ON(mpic == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) /* make sure we're sending something that translates to an IPI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) if ((unsigned int)msg > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) printk("SMP %d: smp_message_pass: unknown msg %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) smp_processor_id(), msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) #ifdef DEBUG_IPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) physmask = 1 << get_hard_smp_processor_id(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) msg * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE), physmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) void __init smp_mpic_probe(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) int nr_cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) DBG("smp_mpic_probe()...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) nr_cpus = num_possible_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) DBG("nr_cpus: %d\n", nr_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) if (nr_cpus > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) mpic_request_ipis();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) void smp_mpic_setup_cpu(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) mpic_setup_this_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) void mpic_reset_core(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) struct mpic *mpic = mpic_primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) u32 pir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) int cpuid = get_hard_smp_processor_id(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) /* Set target bit for core reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) pir = mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) pir |= (1 << cpuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) /* Restore target bit after reset complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) pir &= ~(1 << cpuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) /* Perform 15 EOI on each reset core to clear pending interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) * This is required for FSL CoreNet based devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) if (mpic->flags & MPIC_FSL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) for (i = 0; i < 15; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) _mpic_write(mpic->reg_type, &mpic->cpuregs[cpuid],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) MPIC_CPU_EOI, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) #endif /* CONFIG_SMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) static void mpic_suspend_one(struct mpic *mpic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) for (i = 0; i < mpic->num_sources; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) mpic->save_data[i].vecprio =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) mpic_irq_read(i, MPIC_INFO(IRQ_VECTOR_PRI));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) mpic->save_data[i].dest =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) static int mpic_suspend(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) struct mpic *mpic = mpics;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) while (mpic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) mpic_suspend_one(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) mpic = mpic->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) static void mpic_resume_one(struct mpic *mpic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) for (i = 0; i < mpic->num_sources; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) mpic->save_data[i].vecprio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) mpic->save_data[i].dest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) #ifdef CONFIG_MPIC_U3_HT_IRQS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) if (mpic->fixups) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) struct mpic_irq_fixup *fixup = &mpic->fixups[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) if (fixup->base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) /* we use the lowest bit in an inverted meaning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) if ((mpic->save_data[i].fixup_data & 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) /* Enable and configure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) writeb(0x10 + 2 * fixup->index, fixup->base + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) writel(mpic->save_data[i].fixup_data & ~1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) fixup->base + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) } /* end for loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) static void mpic_resume(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) struct mpic *mpic = mpics;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) while (mpic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) mpic_resume_one(mpic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) mpic = mpic->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) static struct syscore_ops mpic_syscore_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) .resume = mpic_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) .suspend = mpic_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) static int mpic_init_sys(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) register_syscore_ops(&mpic_syscore_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) rc = subsys_system_register(&mpic_subsys, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) unregister_syscore_ops(&mpic_syscore_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) pr_err("mpic: Failed to register subsystem!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) device_initcall(mpic_init_sys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) #endif