0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include <linux/init.h>
0026 #include <linux/interrupt.h>
0027 #include <linux/kernel.h>
0028 #include <linux/irq.h>
0029 #include <linux/irqchip.h>
0030 #include <linux/irqdomain.h>
0031
0032 #include <asm/irq_cpu.h>
0033 #include <asm/mipsregs.h>
0034 #include <asm/mipsmtregs.h>
0035 #include <asm/setup.h>
0036
0037 static struct irq_domain *irq_domain;
0038 static struct irq_domain *ipi_domain;
0039
0040 static inline void unmask_mips_irq(struct irq_data *d)
0041 {
0042 set_c0_status(IE_SW0 << d->hwirq);
0043 irq_enable_hazard();
0044 }
0045
0046 static inline void mask_mips_irq(struct irq_data *d)
0047 {
0048 clear_c0_status(IE_SW0 << d->hwirq);
0049 irq_disable_hazard();
0050 }
0051
0052 static struct irq_chip mips_cpu_irq_controller = {
0053 .name = "MIPS",
0054 .irq_ack = mask_mips_irq,
0055 .irq_mask = mask_mips_irq,
0056 .irq_mask_ack = mask_mips_irq,
0057 .irq_unmask = unmask_mips_irq,
0058 .irq_eoi = unmask_mips_irq,
0059 .irq_disable = mask_mips_irq,
0060 .irq_enable = unmask_mips_irq,
0061 };
0062
0063
0064
0065
0066
0067 static unsigned int mips_mt_cpu_irq_startup(struct irq_data *d)
0068 {
0069 unsigned int vpflags = dvpe();
0070
0071 clear_c0_cause(C_SW0 << d->hwirq);
0072 evpe(vpflags);
0073 unmask_mips_irq(d);
0074 return 0;
0075 }
0076
0077
0078
0079
0080
0081 static void mips_mt_cpu_irq_ack(struct irq_data *d)
0082 {
0083 unsigned int vpflags = dvpe();
0084 clear_c0_cause(C_SW0 << d->hwirq);
0085 evpe(vpflags);
0086 mask_mips_irq(d);
0087 }
0088
0089 #ifdef CONFIG_GENERIC_IRQ_IPI
0090
0091 static void mips_mt_send_ipi(struct irq_data *d, unsigned int cpu)
0092 {
0093 irq_hw_number_t hwirq = irqd_to_hwirq(d);
0094 unsigned long flags;
0095 int vpflags;
0096
0097 local_irq_save(flags);
0098
0099
0100 WARN_ON(!cpus_are_siblings(smp_processor_id(), cpu));
0101
0102 vpflags = dvpe();
0103 settc(cpu_vpe_id(&cpu_data[cpu]));
0104 write_vpe_c0_cause(read_vpe_c0_cause() | (C_SW0 << hwirq));
0105 evpe(vpflags);
0106
0107 local_irq_restore(flags);
0108 }
0109
0110 #endif
0111
0112 static struct irq_chip mips_mt_cpu_irq_controller = {
0113 .name = "MIPS",
0114 .irq_startup = mips_mt_cpu_irq_startup,
0115 .irq_ack = mips_mt_cpu_irq_ack,
0116 .irq_mask = mask_mips_irq,
0117 .irq_mask_ack = mips_mt_cpu_irq_ack,
0118 .irq_unmask = unmask_mips_irq,
0119 .irq_eoi = unmask_mips_irq,
0120 .irq_disable = mask_mips_irq,
0121 .irq_enable = unmask_mips_irq,
0122 #ifdef CONFIG_GENERIC_IRQ_IPI
0123 .ipi_send_single = mips_mt_send_ipi,
0124 #endif
0125 };
0126
0127 asmlinkage void __weak plat_irq_dispatch(void)
0128 {
0129 unsigned long pending = read_c0_cause() & read_c0_status() & ST0_IM;
0130 int irq;
0131
0132 if (!pending) {
0133 spurious_interrupt();
0134 return;
0135 }
0136
0137 pending >>= CAUSEB_IP;
0138 while (pending) {
0139 struct irq_domain *d;
0140
0141 irq = fls(pending) - 1;
0142 if (IS_ENABLED(CONFIG_GENERIC_IRQ_IPI) && irq < 2)
0143 d = ipi_domain;
0144 else
0145 d = irq_domain;
0146
0147 do_domain_IRQ(d, irq);
0148 pending &= ~BIT(irq);
0149 }
0150 }
0151
0152 static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq,
0153 irq_hw_number_t hw)
0154 {
0155 struct irq_chip *chip;
0156
0157 if (hw < 2 && cpu_has_mipsmt) {
0158
0159 chip = &mips_mt_cpu_irq_controller;
0160 } else {
0161 chip = &mips_cpu_irq_controller;
0162 }
0163
0164 if (cpu_has_vint)
0165 set_vi_handler(hw, plat_irq_dispatch);
0166
0167 irq_set_chip_and_handler(irq, chip, handle_percpu_irq);
0168
0169 return 0;
0170 }
0171
0172 static const struct irq_domain_ops mips_cpu_intc_irq_domain_ops = {
0173 .map = mips_cpu_intc_map,
0174 .xlate = irq_domain_xlate_onecell,
0175 };
0176
0177 #ifdef CONFIG_GENERIC_IRQ_IPI
0178
0179 struct cpu_ipi_domain_state {
0180 DECLARE_BITMAP(allocated, 2);
0181 };
0182
0183 static int mips_cpu_ipi_alloc(struct irq_domain *domain, unsigned int virq,
0184 unsigned int nr_irqs, void *arg)
0185 {
0186 struct cpu_ipi_domain_state *state = domain->host_data;
0187 unsigned int i, hwirq;
0188 int ret;
0189
0190 for (i = 0; i < nr_irqs; i++) {
0191 hwirq = find_first_zero_bit(state->allocated, 2);
0192 if (hwirq == 2)
0193 return -EBUSY;
0194 bitmap_set(state->allocated, hwirq, 1);
0195
0196 ret = irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq,
0197 &mips_mt_cpu_irq_controller,
0198 NULL);
0199 if (ret)
0200 return ret;
0201
0202 ret = irq_domain_set_hwirq_and_chip(domain->parent, virq + i, hwirq,
0203 &mips_mt_cpu_irq_controller,
0204 NULL);
0205
0206 if (ret)
0207 return ret;
0208
0209 ret = irq_set_irq_type(virq + i, IRQ_TYPE_LEVEL_HIGH);
0210 if (ret)
0211 return ret;
0212 }
0213
0214 return 0;
0215 }
0216
0217 static int mips_cpu_ipi_match(struct irq_domain *d, struct device_node *node,
0218 enum irq_domain_bus_token bus_token)
0219 {
0220 bool is_ipi;
0221
0222 switch (bus_token) {
0223 case DOMAIN_BUS_IPI:
0224 is_ipi = d->bus_token == bus_token;
0225 return (!node || (to_of_node(d->fwnode) == node)) && is_ipi;
0226 default:
0227 return 0;
0228 }
0229 }
0230
0231 static const struct irq_domain_ops mips_cpu_ipi_chip_ops = {
0232 .alloc = mips_cpu_ipi_alloc,
0233 .match = mips_cpu_ipi_match,
0234 };
0235
0236 static void mips_cpu_register_ipi_domain(struct device_node *of_node)
0237 {
0238 struct cpu_ipi_domain_state *ipi_domain_state;
0239
0240 ipi_domain_state = kzalloc(sizeof(*ipi_domain_state), GFP_KERNEL);
0241 ipi_domain = irq_domain_add_hierarchy(irq_domain,
0242 IRQ_DOMAIN_FLAG_IPI_SINGLE,
0243 2, of_node,
0244 &mips_cpu_ipi_chip_ops,
0245 ipi_domain_state);
0246 if (!ipi_domain)
0247 panic("Failed to add MIPS CPU IPI domain");
0248 irq_domain_update_bus_token(ipi_domain, DOMAIN_BUS_IPI);
0249 }
0250
0251 #else
0252
0253 static inline void mips_cpu_register_ipi_domain(struct device_node *of_node) {}
0254
0255 #endif
0256
0257 static void __init __mips_cpu_irq_init(struct device_node *of_node)
0258 {
0259
0260 clear_c0_status(ST0_IM);
0261 clear_c0_cause(CAUSEF_IP);
0262
0263 irq_domain = irq_domain_add_legacy(of_node, 8, MIPS_CPU_IRQ_BASE, 0,
0264 &mips_cpu_intc_irq_domain_ops,
0265 NULL);
0266 if (!irq_domain)
0267 panic("Failed to add irqdomain for MIPS CPU");
0268
0269
0270
0271
0272
0273 if (cpu_has_mipsmt)
0274 mips_cpu_register_ipi_domain(of_node);
0275 }
0276
0277 void __init mips_cpu_irq_init(void)
0278 {
0279 __mips_cpu_irq_init(NULL);
0280 }
0281
0282 int __init mips_cpu_irq_of_init(struct device_node *of_node,
0283 struct device_node *parent)
0284 {
0285 __mips_cpu_irq_init(of_node);
0286 return 0;
0287 }
0288 IRQCHIP_DECLARE(cpu_intc, "mti,cpu-interrupt-controller", mips_cpu_irq_of_init);