mpic.c 50.1 KB
Newer Older
1 2 3 4 5 6 7 8
/*
 *  arch/powerpc/kernel/mpic.c
 *
 *  Driver for interrupt controllers following the OpenPIC standard, the
 *  common implementation beeing IBM's MPIC. This driver also can deal
 *  with various broken implementations of this HW.
 *
 *  Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
9
 *  Copyright 2010-2012 Freescale Semiconductor, Inc.
10 11 12 13 14 15 16
 *
 *  This file is subject to the terms and conditions of the GNU General Public
 *  License.  See the file COPYING in the main directory of this archive
 *  for more details.
 */

#undef DEBUG
17 18 19
#undef DEBUG_IPI
#undef DEBUG_IRQ
#undef DEBUG_LOW
20 21 22 23 24 25 26 27 28 29

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <linux/bootmem.h>
#include <linux/spinlock.h>
#include <linux/pci.h>
30
#include <linux/slab.h>
31
#include <linux/syscore_ops.h>
32
#include <linux/ratelimit.h>
33 34 35 36 37 38 39 40 41 42

#include <asm/ptrace.h>
#include <asm/signal.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/machdep.h>
#include <asm/mpic.h>
#include <asm/smp.h>

M
Michael Ellerman 已提交
43 44
#include "mpic.h"

45 46 47 48 49 50 51 52
#ifdef DEBUG
#define DBG(fmt...) printk(fmt)
#else
#define DBG(fmt...)
#endif

static struct mpic *mpics;
static struct mpic *mpic_primary;
53
static DEFINE_RAW_SPINLOCK(mpic_lock);
54

55
#ifdef CONFIG_PPC32	/* XXX for now */
56 57 58 59 60
#ifdef CONFIG_IRQ_ALL_CPUS
#define distribute_irqs	(1)
#else
#define distribute_irqs	(0)
#endif
61
#endif
62

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
#ifdef CONFIG_MPIC_WEIRD
static u32 mpic_infos[][MPIC_IDX_END] = {
	[0] = {	/* Original OpenPIC compatible MPIC */
		MPIC_GREG_BASE,
		MPIC_GREG_FEATURE_0,
		MPIC_GREG_GLOBAL_CONF_0,
		MPIC_GREG_VENDOR_ID,
		MPIC_GREG_IPI_VECTOR_PRI_0,
		MPIC_GREG_IPI_STRIDE,
		MPIC_GREG_SPURIOUS,
		MPIC_GREG_TIMER_FREQ,

		MPIC_TIMER_BASE,
		MPIC_TIMER_STRIDE,
		MPIC_TIMER_CURRENT_CNT,
		MPIC_TIMER_BASE_CNT,
		MPIC_TIMER_VECTOR_PRI,
		MPIC_TIMER_DESTINATION,

		MPIC_CPU_BASE,
		MPIC_CPU_STRIDE,
		MPIC_CPU_IPI_DISPATCH_0,
		MPIC_CPU_IPI_DISPATCH_STRIDE,
		MPIC_CPU_CURRENT_TASK_PRI,
		MPIC_CPU_WHOAMI,
		MPIC_CPU_INTACK,
		MPIC_CPU_EOI,
90
		MPIC_CPU_MCACK,
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128

		MPIC_IRQ_BASE,
		MPIC_IRQ_STRIDE,
		MPIC_IRQ_VECTOR_PRI,
		MPIC_VECPRI_VECTOR_MASK,
		MPIC_VECPRI_POLARITY_POSITIVE,
		MPIC_VECPRI_POLARITY_NEGATIVE,
		MPIC_VECPRI_SENSE_LEVEL,
		MPIC_VECPRI_SENSE_EDGE,
		MPIC_VECPRI_POLARITY_MASK,
		MPIC_VECPRI_SENSE_MASK,
		MPIC_IRQ_DESTINATION
	},
	[1] = {	/* Tsi108/109 PIC */
		TSI108_GREG_BASE,
		TSI108_GREG_FEATURE_0,
		TSI108_GREG_GLOBAL_CONF_0,
		TSI108_GREG_VENDOR_ID,
		TSI108_GREG_IPI_VECTOR_PRI_0,
		TSI108_GREG_IPI_STRIDE,
		TSI108_GREG_SPURIOUS,
		TSI108_GREG_TIMER_FREQ,

		TSI108_TIMER_BASE,
		TSI108_TIMER_STRIDE,
		TSI108_TIMER_CURRENT_CNT,
		TSI108_TIMER_BASE_CNT,
		TSI108_TIMER_VECTOR_PRI,
		TSI108_TIMER_DESTINATION,

		TSI108_CPU_BASE,
		TSI108_CPU_STRIDE,
		TSI108_CPU_IPI_DISPATCH_0,
		TSI108_CPU_IPI_DISPATCH_STRIDE,
		TSI108_CPU_CURRENT_TASK_PRI,
		TSI108_CPU_WHOAMI,
		TSI108_CPU_INTACK,
		TSI108_CPU_EOI,
129
		TSI108_CPU_MCACK,
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152

		TSI108_IRQ_BASE,
		TSI108_IRQ_STRIDE,
		TSI108_IRQ_VECTOR_PRI,
		TSI108_VECPRI_VECTOR_MASK,
		TSI108_VECPRI_POLARITY_POSITIVE,
		TSI108_VECPRI_POLARITY_NEGATIVE,
		TSI108_VECPRI_SENSE_LEVEL,
		TSI108_VECPRI_SENSE_EDGE,
		TSI108_VECPRI_POLARITY_MASK,
		TSI108_VECPRI_SENSE_MASK,
		TSI108_IRQ_DESTINATION
	},
};

#define MPIC_INFO(name) mpic->hw_set[MPIC_IDX_##name]

#else /* CONFIG_MPIC_WEIRD */

#define MPIC_INFO(name) MPIC_##name

#endif /* CONFIG_MPIC_WEIRD */

153 154 155 156
static inline unsigned int mpic_processor_id(struct mpic *mpic)
{
	unsigned int cpu = 0;

157
	if (!(mpic->flags & MPIC_SECONDARY))
158 159 160 161 162
		cpu = hard_smp_processor_id();

	return cpu;
}

163 164 165 166 167
/*
 * Register accessor functions
 */


168 169 170
static inline u32 _mpic_read(enum mpic_reg_type type,
			     struct mpic_reg_bank *rb,
			     unsigned int reg)
171
{
172 173 174
	switch(type) {
#ifdef CONFIG_PPC_DCR
	case mpic_access_dcr:
175
		return dcr_read(rb->dhost, reg);
176 177 178 179 180 181 182
#endif
	case mpic_access_mmio_be:
		return in_be32(rb->base + (reg >> 2));
	case mpic_access_mmio_le:
	default:
		return in_le32(rb->base + (reg >> 2));
	}
183 184
}

185 186 187
static inline void _mpic_write(enum mpic_reg_type type,
			       struct mpic_reg_bank *rb,
 			       unsigned int reg, u32 value)
188
{
189 190 191
	switch(type) {
#ifdef CONFIG_PPC_DCR
	case mpic_access_dcr:
192 193
		dcr_write(rb->dhost, reg, value);
		break;
194 195
#endif
	case mpic_access_mmio_be:
196 197
		out_be32(rb->base + (reg >> 2), value);
		break;
198 199
	case mpic_access_mmio_le:
	default:
200 201
		out_le32(rb->base + (reg >> 2), value);
		break;
202
	}
203 204 205 206
}

static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi)
{
207
	enum mpic_reg_type type = mpic->reg_type;
208 209
	unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
			      (ipi * MPIC_INFO(GREG_IPI_STRIDE));
210

211 212 213
	if ((mpic->flags & MPIC_BROKEN_IPI) && type == mpic_access_mmio_le)
		type = mpic_access_mmio_be;
	return _mpic_read(type, &mpic->gregs, offset);
214 215 216 217
}

static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value)
{
218 219
	unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
			      (ipi * MPIC_INFO(GREG_IPI_STRIDE));
220

221
	_mpic_write(mpic->reg_type, &mpic->gregs, offset, value);
222 223
}

224
static inline unsigned int mpic_tm_offset(struct mpic *mpic, unsigned int tm)
225
{
226 227 228
	return (tm >> 2) * MPIC_TIMER_GROUP_STRIDE +
	       (tm & 3) * MPIC_INFO(TIMER_STRIDE);
}
229

230 231 232 233
static inline u32 _mpic_tm_read(struct mpic *mpic, unsigned int tm)
{
	unsigned int offset = mpic_tm_offset(mpic, tm) +
			      MPIC_INFO(TIMER_VECTOR_PRI);
234 235 236 237 238 239

	return _mpic_read(mpic->reg_type, &mpic->tmregs, offset);
}

static inline void _mpic_tm_write(struct mpic *mpic, unsigned int tm, u32 value)
{
240 241
	unsigned int offset = mpic_tm_offset(mpic, tm) +
			      MPIC_INFO(TIMER_VECTOR_PRI);
242 243 244 245

	_mpic_write(mpic->reg_type, &mpic->tmregs, offset, value);
}

246 247
static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg)
{
248
	unsigned int cpu = mpic_processor_id(mpic);
249

250
	return _mpic_read(mpic->reg_type, &mpic->cpuregs[cpu], reg);
251 252 253 254
}

static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 value)
{
255
	unsigned int cpu = mpic_processor_id(mpic);
256

257
	_mpic_write(mpic->reg_type, &mpic->cpuregs[cpu], reg, value);
258 259 260 261 262 263
}

static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigned int reg)
{
	unsigned int	isu = src_no >> mpic->isu_shift;
	unsigned int	idx = src_no & mpic->isu_mask;
264
	unsigned int	val;
265

266 267
	val = _mpic_read(mpic->reg_type, &mpic->isus[isu],
			 reg + (idx * MPIC_INFO(IRQ_STRIDE)));
268 269
#ifdef CONFIG_MPIC_BROKEN_REGREAD
	if (reg == 0)
270 271
		val = (val & (MPIC_VECPRI_MASK | MPIC_VECPRI_ACTIVITY)) |
			mpic->isu_reg0_shadow[src_no];
272
#endif
273
	return val;
274 275 276 277 278 279 280 281
}

static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
				   unsigned int reg, u32 value)
{
	unsigned int	isu = src_no >> mpic->isu_shift;
	unsigned int	idx = src_no & mpic->isu_mask;

282
	_mpic_write(mpic->reg_type, &mpic->isus[isu],
283
		    reg + (idx * MPIC_INFO(IRQ_STRIDE)), value);
284 285 286

#ifdef CONFIG_MPIC_BROKEN_REGREAD
	if (reg == 0)
287 288
		mpic->isu_reg0_shadow[src_no] =
			value & ~(MPIC_VECPRI_MASK | MPIC_VECPRI_ACTIVITY);
289
#endif
290 291
}

292 293
#define mpic_read(b,r)		_mpic_read(mpic->reg_type,&(b),(r))
#define mpic_write(b,r,v)	_mpic_write(mpic->reg_type,&(b),(r),(v))
294 295
#define mpic_ipi_read(i)	_mpic_ipi_read(mpic,(i))
#define mpic_ipi_write(i,v)	_mpic_ipi_write(mpic,(i),(v))
296 297
#define mpic_tm_read(i)		_mpic_tm_read(mpic,(i))
#define mpic_tm_write(i,v)	_mpic_tm_write(mpic,(i),(v))
298 299 300 301 302 303 304 305 306 307 308
#define mpic_cpu_read(i)	_mpic_cpu_read(mpic,(i))
#define mpic_cpu_write(i,v)	_mpic_cpu_write(mpic,(i),(v))
#define mpic_irq_read(s,r)	_mpic_irq_read(mpic,(s),(r))
#define mpic_irq_write(s,r,v)	_mpic_irq_write(mpic,(s),(r),(v))


/*
 * Low level utility functions
 */


309
static void _mpic_map_mmio(struct mpic *mpic, phys_addr_t phys_addr,
310 311 312 313 314 315 316 317
			   struct mpic_reg_bank *rb, unsigned int offset,
			   unsigned int size)
{
	rb->base = ioremap(phys_addr + offset, size);
	BUG_ON(rb->base == NULL);
}

#ifdef CONFIG_PPC_DCR
318
static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb,
319 320
			  unsigned int offset, unsigned int size)
{
321
	phys_addr_t phys_addr = dcr_resource_start(mpic->node, 0);
322
	rb->dhost = dcr_map(mpic->node, phys_addr + offset, size);
323 324 325
	BUG_ON(!DCR_MAP_OK(rb->dhost));
}

326
static inline void mpic_map(struct mpic *mpic,
327 328
			    phys_addr_t phys_addr, struct mpic_reg_bank *rb,
			    unsigned int offset, unsigned int size)
329 330
{
	if (mpic->flags & MPIC_USES_DCR)
331
		_mpic_map_dcr(mpic, rb, offset, size);
332 333 334 335
	else
		_mpic_map_mmio(mpic, phys_addr, rb, offset, size);
}
#else /* CONFIG_PPC_DCR */
336
#define mpic_map(m,p,b,o,s)	_mpic_map_mmio(m,p,b,o,s)
337 338 339
#endif /* !CONFIG_PPC_DCR */


340 341 342 343 344 345 346 347

/* Check if we have one of those nice broken MPICs with a flipped endian on
 * reads from IPI registers
 */
static void __init mpic_test_broken_ipi(struct mpic *mpic)
{
	u32 r;

348 349
	mpic_write(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0), MPIC_VECPRI_MASK);
	r = mpic_read(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0));
350 351 352 353 354 355 356

	if (r == le32_to_cpu(MPIC_VECPRI_MASK)) {
		printk(KERN_INFO "mpic: Detected reversed IPI registers\n");
		mpic->flags |= MPIC_BROKEN_IPI;
	}
}

357
#ifdef CONFIG_MPIC_U3_HT_IRQS
358 359 360 361

/* Test if an interrupt is sourced from HyperTransport (used on broken U3s)
 * to force the edge setting on the MPIC and do the ack workaround.
 */
362
static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source)
363
{
364
	if (source >= 128 || !mpic->fixups)
365
		return 0;
366
	return mpic->fixups[source].base != NULL;
367 368
}

369

370
static inline void mpic_ht_end_irq(struct mpic *mpic, unsigned int source)
371
{
372
	struct mpic_irq_fixup *fixup = &mpic->fixups[source];
373

374 375 376 377 378
	if (fixup->applebase) {
		unsigned int soff = (fixup->index >> 3) & ~3;
		unsigned int mask = 1U << (fixup->index & 0x1f);
		writel(mask, fixup->applebase + soff);
	} else {
379
		raw_spin_lock(&mpic->fixup_lock);
380 381
		writeb(0x11 + 2 * fixup->index, fixup->base + 2);
		writel(fixup->data, fixup->base + 4);
382
		raw_spin_unlock(&mpic->fixup_lock);
383
	}
384 385
}

386
static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
387
				      bool level)
388 389 390 391 392 393 394 395
{
	struct mpic_irq_fixup *fixup = &mpic->fixups[source];
	unsigned long flags;
	u32 tmp;

	if (fixup->base == NULL)
		return;

396 397
	DBG("startup_ht_interrupt(0x%x) index: %d\n",
	    source, fixup->index);
398
	raw_spin_lock_irqsave(&mpic->fixup_lock, flags);
399 400 401 402
	/* Enable and configure */
	writeb(0x10 + 2 * fixup->index, fixup->base + 2);
	tmp = readl(fixup->base + 4);
	tmp &= ~(0x23U);
403
	if (level)
404 405
		tmp |= 0x22;
	writel(tmp, fixup->base + 4);
406
	raw_spin_unlock_irqrestore(&mpic->fixup_lock, flags);
407 408 409 410 411 412

#ifdef CONFIG_PM
	/* use the lowest bit inverted to the actual HW,
	 * set if this fixup was enabled, clear otherwise */
	mpic->save_data[source].fixup_data = tmp | 1;
#endif
413 414
}

415
static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source)
416 417 418 419 420 421 422 423
{
	struct mpic_irq_fixup *fixup = &mpic->fixups[source];
	unsigned long flags;
	u32 tmp;

	if (fixup->base == NULL)
		return;

424
	DBG("shutdown_ht_interrupt(0x%x)\n", source);
425 426

	/* Disable */
427
	raw_spin_lock_irqsave(&mpic->fixup_lock, flags);
428 429
	writeb(0x10 + 2 * fixup->index, fixup->base + 2);
	tmp = readl(fixup->base + 4);
430
	tmp |= 1;
431
	writel(tmp, fixup->base + 4);
432
	raw_spin_unlock_irqrestore(&mpic->fixup_lock, flags);
433 434 435 436 437 438

#ifdef CONFIG_PM
	/* use the lowest bit inverted to the actual HW,
	 * set if this fixup was enabled, clear otherwise */
	mpic->save_data[source].fixup_data = tmp & ~1;
#endif
439
}
440

441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469
#ifdef CONFIG_PCI_MSI
static void __init mpic_scan_ht_msi(struct mpic *mpic, u8 __iomem *devbase,
				    unsigned int devfn)
{
	u8 __iomem *base;
	u8 pos, flags;
	u64 addr = 0;

	for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0;
	     pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) {
		u8 id = readb(devbase + pos + PCI_CAP_LIST_ID);
		if (id == PCI_CAP_ID_HT) {
			id = readb(devbase + pos + 3);
			if ((id & HT_5BIT_CAP_MASK) == HT_CAPTYPE_MSI_MAPPING)
				break;
		}
	}

	if (pos == 0)
		return;

	base = devbase + pos;

	flags = readb(base + HT_MSI_FLAGS);
	if (!(flags & HT_MSI_FLAGS_FIXED)) {
		addr = readl(base + HT_MSI_ADDR_LO) & HT_MSI_ADDR_LO_MASK;
		addr = addr | ((u64)readl(base + HT_MSI_ADDR_HI) << 32);
	}

470
	printk(KERN_DEBUG "mpic:   - HT:%02x.%x %s MSI mapping found @ 0x%llx\n",
471 472 473 474 475 476 477 478 479 480 481 482 483 484
		PCI_SLOT(devfn), PCI_FUNC(devfn),
		flags & HT_MSI_FLAGS_ENABLE ? "enabled" : "disabled", addr);

	if (!(flags & HT_MSI_FLAGS_ENABLE))
		writeb(flags | HT_MSI_FLAGS_ENABLE, base + HT_MSI_FLAGS);
}
#else
static void __init mpic_scan_ht_msi(struct mpic *mpic, u8 __iomem *devbase,
				    unsigned int devfn)
{
	return;
}
#endif

485 486
static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase,
				    unsigned int devfn, u32 vdid)
487
{
488
	int i, irq, n;
489
	u8 __iomem *base;
490
	u32 tmp;
491
	u8 pos;
492

493 494 495
	for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0;
	     pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) {
		u8 id = readb(devbase + pos + PCI_CAP_LIST_ID);
496
		if (id == PCI_CAP_ID_HT) {
497
			id = readb(devbase + pos + 3);
498
			if ((id & HT_5BIT_CAP_MASK) == HT_CAPTYPE_IRQ)
499 500
				break;
		}
501
	}
502 503 504
	if (pos == 0)
		return;

505 506 507
	base = devbase + pos;
	writeb(0x01, base + 2);
	n = (readl(base + 4) >> 16) & 0xff;
508

509 510 511
	printk(KERN_INFO "mpic:   - HT:%02x.%x [0x%02x] vendor %04x device %04x"
	       " has %d irqs\n",
	       devfn >> 3, devfn & 0x7, pos, vdid & 0xffff, vdid >> 16, n + 1);
512 513

	for (i = 0; i <= n; i++) {
514 515
		writeb(0x10 + 2 * i, base + 2);
		tmp = readl(base + 4);
516
		irq = (tmp >> 16) & 0xff;
517 518 519 520 521 522 523 524 525 526 527 528 529
		DBG("HT PIC index 0x%x, irq 0x%x, tmp: %08x\n", i, irq, tmp);
		/* mask it , will be unmasked later */
		tmp |= 0x1;
		writel(tmp, base + 4);
		mpic->fixups[irq].index = i;
		mpic->fixups[irq].base = base;
		/* Apple HT PIC has a non-standard way of doing EOIs */
		if ((vdid & 0xffff) == 0x106b)
			mpic->fixups[irq].applebase = devbase + 0x60;
		else
			mpic->fixups[irq].applebase = NULL;
		writeb(0x11 + 2 * i, base + 2);
		mpic->fixups[irq].data = readl(base + 4) | 0x80000000;
530 531 532
	}
}
 
533

534
static void __init mpic_scan_ht_pics(struct mpic *mpic)
535 536 537 538
{
	unsigned int devfn;
	u8 __iomem *cfgspace;

539
	printk(KERN_INFO "mpic: Setting up HT PICs workarounds for U3/U4\n");
540 541

	/* Allocate fixups array */
542
	mpic->fixups = kzalloc(128 * sizeof(*mpic->fixups), GFP_KERNEL);
543 544 545
	BUG_ON(mpic->fixups == NULL);

	/* Init spinlock */
546
	raw_spin_lock_init(&mpic->fixup_lock);
547

548 549
	/* Map U3 config space. We assume all IO-APICs are on the primary bus
	 * so we only need to map 64kB.
550
	 */
551
	cfgspace = ioremap(0xf2000000, 0x10000);
552 553
	BUG_ON(cfgspace == NULL);

554 555
	/* Now we scan all slots. We do a very quick scan, we read the header
	 * type, vendor ID and device ID only, that's plenty enough
556
	 */
557
	for (devfn = 0; devfn < 0x100; devfn++) {
558 559 560
		u8 __iomem *devbase = cfgspace + (devfn << 8);
		u8 hdr_type = readb(devbase + PCI_HEADER_TYPE);
		u32 l = readl(devbase + PCI_VENDOR_ID);
561
		u16 s;
562 563 564 565 566 567 568

		DBG("devfn %x, l: %x\n", devfn, l);

		/* If no device, skip */
		if (l == 0xffffffff || l == 0x00000000 ||
		    l == 0x0000ffff || l == 0xffff0000)
			goto next;
569 570 571 572
		/* Check if is supports capability lists */
		s = readw(devbase + PCI_STATUS);
		if (!(s & PCI_STATUS_CAP_LIST))
			goto next;
573

574
		mpic_scan_ht_pic(mpic, devbase, devfn, l);
575
		mpic_scan_ht_msi(mpic, devbase, devfn);
576

577 578
	next:
		/* next device, if function 0 */
579
		if (PCI_FUNC(devfn) == 0 && (hdr_type & 0x80) == 0)
580 581 582 583
			devfn += 7;
	}
}

584
#else /* CONFIG_MPIC_U3_HT_IRQS */
585 586 587 588 589 590 591 592 593 594

static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source)
{
	return 0;
}

static void __init mpic_scan_ht_pics(struct mpic *mpic)
{
}

595
#endif /* CONFIG_MPIC_U3_HT_IRQS */
596 597

/* Find an mpic associated with a given linux interrupt */
598
static struct mpic *mpic_find(unsigned int irq)
599
{
600 601
	if (irq < NUM_ISA_INTERRUPTS)
		return NULL;
602

603
	return irq_get_chip_data(irq);
604
}
605

606
/* Determine if the linux irq is an IPI */
607
static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int src)
608 609
{
	return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]);
610 611
}

612
/* Determine if the linux irq is a timer */
613
static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int src)
614 615 616
{
	return (src >= mpic->timer_vecs[0] && src <= mpic->timer_vecs[7]);
}
617

618 619 620 621 622 623
/* Convert a cpu mask from logical to physical cpu numbers. */
static inline u32 mpic_physmask(u32 cpumask)
{
	int i;
	u32 mask = 0;

624
	for (i = 0; i < min(32, NR_CPUS); ++i, cpumask >>= 1)
625 626 627 628 629 630
		mask |= (cpumask & 1) << get_hard_smp_processor_id(i);
	return mask;
}

#ifdef CONFIG_SMP
/* Get the mpic structure from the IPI number */
631
static inline struct mpic * mpic_from_ipi(struct irq_data *d)
632
{
633
	return irq_data_get_irq_chip_data(d);
634 635 636 637 638 639
}
#endif

/* Get the mpic structure from the irq number */
static inline struct mpic * mpic_from_irq(unsigned int irq)
{
640
	return irq_get_chip_data(irq);
641 642 643 644 645 646
}

/* Get the mpic structure from the irq data */
static inline struct mpic * mpic_from_irq_data(struct irq_data *d)
{
	return irq_data_get_irq_chip_data(d);
647 648 649 650 651
}

/* Send an EOI */
static inline void mpic_eoi(struct mpic *mpic)
{
652 653
	mpic_cpu_write(MPIC_INFO(CPU_EOI), 0);
	(void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI));
654 655 656 657 658 659 660
}

/*
 * Linux descriptor level callbacks
 */


661
void mpic_unmask_irq(struct irq_data *d)
662 663
{
	unsigned int loops = 100000;
664
	struct mpic *mpic = mpic_from_irq_data(d);
665
	unsigned int src = irqd_to_hwirq(d);
666

667
	DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, d->irq, src);
668

669 670
	mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
		       mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) &
671
		       ~MPIC_VECPRI_MASK);
672 673 674
	/* make sure mask gets to controller before we return to user */
	do {
		if (!loops--) {
675 676
			printk(KERN_ERR "%s: timeout on hwirq %u\n",
			       __func__, src);
677 678
			break;
		}
679
	} while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK);
680 681
}

682
void mpic_mask_irq(struct irq_data *d)
683 684
{
	unsigned int loops = 100000;
685
	struct mpic *mpic = mpic_from_irq_data(d);
686
	unsigned int src = irqd_to_hwirq(d);
687

688
	DBG("%s: disable_irq: %d (src %d)\n", mpic->name, d->irq, src);
689

690 691
	mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
		       mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) |
692
		       MPIC_VECPRI_MASK);
693 694 695 696

	/* make sure mask gets to controller before we return to user */
	do {
		if (!loops--) {
697 698
			printk(KERN_ERR "%s: timeout on hwirq %u\n",
			       __func__, src);
699 700
			break;
		}
701
	} while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK));
702 703
}

704
void mpic_end_irq(struct irq_data *d)
705
{
706
	struct mpic *mpic = mpic_from_irq_data(d);
707 708

#ifdef DEBUG_IRQ
709
	DBG("%s: end_irq: %d\n", mpic->name, d->irq);
710 711 712 713 714 715 716 717 718
#endif
	/* We always EOI on end_irq() even for edge interrupts since that
	 * should only lower the priority, the MPIC should have properly
	 * latched another edge interrupt coming in anyway
	 */

	mpic_eoi(mpic);
}

719
#ifdef CONFIG_MPIC_U3_HT_IRQS
720

721
static void mpic_unmask_ht_irq(struct irq_data *d)
722
{
723
	struct mpic *mpic = mpic_from_irq_data(d);
724
	unsigned int src = irqd_to_hwirq(d);
725

726
	mpic_unmask_irq(d);
727

728
	if (irqd_is_level_type(d))
729 730 731
		mpic_ht_end_irq(mpic, src);
}

732
static unsigned int mpic_startup_ht_irq(struct irq_data *d)
733
{
734
	struct mpic *mpic = mpic_from_irq_data(d);
735
	unsigned int src = irqd_to_hwirq(d);
736

737
	mpic_unmask_irq(d);
738
	mpic_startup_ht_interrupt(mpic, src, irqd_is_level_type(d));
739 740

	return 0;
741 742
}

743
static void mpic_shutdown_ht_irq(struct irq_data *d)
744
{
745
	struct mpic *mpic = mpic_from_irq_data(d);
746
	unsigned int src = irqd_to_hwirq(d);
747

748
	mpic_shutdown_ht_interrupt(mpic, src);
749
	mpic_mask_irq(d);
750 751
}

752
static void mpic_end_ht_irq(struct irq_data *d)
753
{
754
	struct mpic *mpic = mpic_from_irq_data(d);
755
	unsigned int src = irqd_to_hwirq(d);
756

757
#ifdef DEBUG_IRQ
758
	DBG("%s: end_irq: %d\n", mpic->name, d->irq);
759
#endif
760 761 762 763 764
	/* We always EOI on end_irq() even for edge interrupts since that
	 * should only lower the priority, the MPIC should have properly
	 * latched another edge interrupt coming in anyway
	 */

765
	if (irqd_is_level_type(d))
766
		mpic_ht_end_irq(mpic, src);
767 768
	mpic_eoi(mpic);
}
769
#endif /* !CONFIG_MPIC_U3_HT_IRQS */
770

771 772
#ifdef CONFIG_SMP

773
static void mpic_unmask_ipi(struct irq_data *d)
774
{
775
	struct mpic *mpic = mpic_from_ipi(d);
776
	unsigned int src = virq_to_hw(d->irq) - mpic->ipi_vecs[0];
777

778
	DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, d->irq, src);
779 780 781
	mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK);
}

782
static void mpic_mask_ipi(struct irq_data *d)
783 784 785 786
{
	/* NEVER disable an IPI... that's just plain wrong! */
}

787
static void mpic_end_ipi(struct irq_data *d)
788
{
789
	struct mpic *mpic = mpic_from_ipi(d);
790 791 792 793 794 795 796 797 798 799 800

	/*
	 * IPIs are marked IRQ_PER_CPU. This has the side effect of
	 * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from
	 * applying to them. We EOI them late to avoid re-entering.
	 */
	mpic_eoi(mpic);
}

#endif /* CONFIG_SMP */

801 802 803 804 805
static void mpic_unmask_tm(struct irq_data *d)
{
	struct mpic *mpic = mpic_from_irq_data(d);
	unsigned int src = virq_to_hw(d->irq) - mpic->timer_vecs[0];

806
	DBG("%s: enable_tm: %d (tm %d)\n", mpic->name, d->irq, src);
807 808 809 810 811 812 813 814 815 816 817 818 819
	mpic_tm_write(src, mpic_tm_read(src) & ~MPIC_VECPRI_MASK);
	mpic_tm_read(src);
}

static void mpic_mask_tm(struct irq_data *d)
{
	struct mpic *mpic = mpic_from_irq_data(d);
	unsigned int src = virq_to_hw(d->irq) - mpic->timer_vecs[0];

	mpic_tm_write(src, mpic_tm_read(src) | MPIC_VECPRI_MASK);
	mpic_tm_read(src);
}

820 821
int mpic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
		      bool force)
822
{
823
	struct mpic *mpic = mpic_from_irq_data(d);
824
	unsigned int src = irqd_to_hwirq(d);
825

826
	if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
827
		int cpuid = irq_choose_cpu(cpumask);
828

829 830
		mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid);
	} else {
831
		u32 mask = cpumask_bits(cpumask)[0];
832

833
		mask &= cpumask_bits(cpu_online_mask)[0];
834 835

		mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
836
			       mpic_physmask(mask));
837
	}
838 839

	return 0;
840 841
}

842
static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
843 844
{
	/* Now convert sense value */
845
	switch(type & IRQ_TYPE_SENSE_MASK) {
846
	case IRQ_TYPE_EDGE_RISING:
847 848
		return MPIC_INFO(VECPRI_SENSE_EDGE) |
		       MPIC_INFO(VECPRI_POLARITY_POSITIVE);
849
	case IRQ_TYPE_EDGE_FALLING:
850
	case IRQ_TYPE_EDGE_BOTH:
851 852
		return MPIC_INFO(VECPRI_SENSE_EDGE) |
		       MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
853
	case IRQ_TYPE_LEVEL_HIGH:
854 855
		return MPIC_INFO(VECPRI_SENSE_LEVEL) |
		       MPIC_INFO(VECPRI_POLARITY_POSITIVE);
856 857
	case IRQ_TYPE_LEVEL_LOW:
	default:
858 859
		return MPIC_INFO(VECPRI_SENSE_LEVEL) |
		       MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
860
	}
861 862
}

863
int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
864
{
865
	struct mpic *mpic = mpic_from_irq_data(d);
866
	unsigned int src = irqd_to_hwirq(d);
867 868
	unsigned int vecpri, vold, vnew;

869
	DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
870
	    mpic, d->irq, src, flow_type);
871

872
	if (src >= mpic->num_sources)
873 874
		return -EINVAL;

875 876 877
	vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));

	/* We don't support "none" type */
878
	if (flow_type == IRQ_TYPE_NONE)
879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902
		flow_type = IRQ_TYPE_DEFAULT;

	/* Default: read HW settings */
	if (flow_type == IRQ_TYPE_DEFAULT) {
		switch(vold & (MPIC_INFO(VECPRI_POLARITY_MASK) |
			       MPIC_INFO(VECPRI_SENSE_MASK))) {
			case MPIC_INFO(VECPRI_SENSE_EDGE) |
			     MPIC_INFO(VECPRI_POLARITY_POSITIVE):
				flow_type = IRQ_TYPE_EDGE_RISING;
				break;
			case MPIC_INFO(VECPRI_SENSE_EDGE) |
			     MPIC_INFO(VECPRI_POLARITY_NEGATIVE):
				flow_type = IRQ_TYPE_EDGE_FALLING;
				break;
			case MPIC_INFO(VECPRI_SENSE_LEVEL) |
			     MPIC_INFO(VECPRI_POLARITY_POSITIVE):
				flow_type = IRQ_TYPE_LEVEL_HIGH;
				break;
			case MPIC_INFO(VECPRI_SENSE_LEVEL) |
			     MPIC_INFO(VECPRI_POLARITY_NEGATIVE):
				flow_type = IRQ_TYPE_LEVEL_LOW;
				break;
		}
	}
903

904
	/* Apply to irq desc */
905
	irqd_set_trigger_type(d, flow_type);
906

907
	/* Apply to HW */
908 909 910 911
	if (mpic_is_ht_interrupt(mpic, src))
		vecpri = MPIC_VECPRI_POLARITY_POSITIVE |
			MPIC_VECPRI_SENSE_EDGE;
	else
912
		vecpri = mpic_type_to_vecpri(mpic, flow_type);
913

914 915
	vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) |
			MPIC_INFO(VECPRI_SENSE_MASK));
916 917
	vnew |= vecpri;
	if (vold != vnew)
918
		mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew);
919

920
	return IRQ_SET_MASK_OK_NOCOPY;
921 922
}

923 924 925
void mpic_set_vector(unsigned int virq, unsigned int vector)
{
	struct mpic *mpic = mpic_from_irq(virq);
926
	unsigned int src = virq_to_hw(virq);
927 928 929 930 931
	unsigned int vecpri;

	DBG("mpic: set_vector(mpic:@%p,virq:%d,src:%d,vector:0x%x)\n",
	    mpic, virq, src, vector);

932
	if (src >= mpic->num_sources)
933 934 935 936 937 938 939 940
		return;

	vecpri = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
	vecpri = vecpri & ~MPIC_INFO(VECPRI_VECTOR_MASK);
	vecpri |= vector;
	mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
}

941 942 943
void mpic_set_destination(unsigned int virq, unsigned int cpuid)
{
	struct mpic *mpic = mpic_from_irq(virq);
944
	unsigned int src = virq_to_hw(virq);
945 946 947 948

	DBG("mpic: set_destination(mpic:@%p,virq:%d,src:%d,cpuid:0x%x)\n",
	    mpic, virq, src, cpuid);

949
	if (src >= mpic->num_sources)
950 951 952 953 954
		return;

	mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid);
}

955
static struct irq_chip mpic_irq_chip = {
956 957 958 959
	.irq_mask	= mpic_mask_irq,
	.irq_unmask	= mpic_unmask_irq,
	.irq_eoi	= mpic_end_irq,
	.irq_set_type	= mpic_set_irq_type,
960 961 962 963
};

#ifdef CONFIG_SMP
static struct irq_chip mpic_ipi_chip = {
964 965 966
	.irq_mask	= mpic_mask_ipi,
	.irq_unmask	= mpic_unmask_ipi,
	.irq_eoi	= mpic_end_ipi,
967 968 969
};
#endif /* CONFIG_SMP */

970 971 972 973 974 975
static struct irq_chip mpic_tm_chip = {
	.irq_mask	= mpic_mask_tm,
	.irq_unmask	= mpic_unmask_tm,
	.irq_eoi	= mpic_end_irq,
};

976
#ifdef CONFIG_MPIC_U3_HT_IRQS
977
static struct irq_chip mpic_irq_ht_chip = {
978 979 980 981 982 983
	.irq_startup	= mpic_startup_ht_irq,
	.irq_shutdown	= mpic_shutdown_ht_irq,
	.irq_mask	= mpic_mask_irq,
	.irq_unmask	= mpic_unmask_ht_irq,
	.irq_eoi	= mpic_end_ht_irq,
	.irq_set_type	= mpic_set_irq_type,
984
};
985
#endif /* CONFIG_MPIC_U3_HT_IRQS */
986

987

988
static int mpic_host_match(struct irq_domain *h, struct device_node *node)
989 990
{
	/* Exact match, unless mpic node is NULL */
991
	return h->of_node == NULL || h->of_node == node;
992 993
}

994
static int mpic_host_map(struct irq_domain *h, unsigned int virq,
995
			 irq_hw_number_t hw)
996 997
{
	struct mpic *mpic = h->host_data;
998
	struct irq_chip *chip;
999

1000
	DBG("mpic: map virq %d, hwirq 0x%lx\n", virq, hw);
1001

1002
	if (hw == mpic->spurious_vec)
1003
		return -EINVAL;
1004 1005
	if (mpic->protected && test_bit(hw, mpic->protected))
		return -EINVAL;
1006

1007
#ifdef CONFIG_SMP
1008
	else if (hw >= mpic->ipi_vecs[0]) {
1009
		WARN_ON(mpic->flags & MPIC_SECONDARY);
1010

1011
		DBG("mpic: mapping as IPI\n");
1012 1013
		irq_set_chip_data(virq, mpic);
		irq_set_chip_and_handler(virq, &mpic->hc_ipi,
1014 1015 1016 1017 1018
					 handle_percpu_irq);
		return 0;
	}
#endif /* CONFIG_SMP */

1019
	if (hw >= mpic->timer_vecs[0] && hw <= mpic->timer_vecs[7]) {
1020
		WARN_ON(mpic->flags & MPIC_SECONDARY);
1021 1022 1023 1024 1025 1026 1027 1028

		DBG("mpic: mapping as timer\n");
		irq_set_chip_data(virq, mpic);
		irq_set_chip_and_handler(virq, &mpic->hc_tm,
					 handle_fasteoi_irq);
		return 0;
	}

1029 1030 1031
	if (mpic_map_error_int(mpic, virq, hw))
		return 0;

1032
	if (hw >= mpic->num_sources)
1033 1034
		return -EINVAL;

M
Michael Ellerman 已提交
1035 1036
	mpic_msi_reserve_hwirq(mpic, hw);

1037
	/* Default chip */
1038 1039
	chip = &mpic->hc_irq;

1040
#ifdef CONFIG_MPIC_U3_HT_IRQS
1041
	/* Check for HT interrupts, override vecpri */
1042
	if (mpic_is_ht_interrupt(mpic, hw))
1043
		chip = &mpic->hc_ht_irq;
1044
#endif /* CONFIG_MPIC_U3_HT_IRQS */
1045

1046
	DBG("mpic: mapping to irq chip @%p\n", chip);
1047

1048 1049
	irq_set_chip_data(virq, mpic);
	irq_set_chip_and_handler(virq, chip, handle_fasteoi_irq);
1050 1051

	/* Set default irq type */
1052
	irq_set_irq_type(virq, IRQ_TYPE_DEFAULT);
1053

1054 1055 1056 1057 1058 1059
	/* If the MPIC was reset, then all vectors have already been
	 * initialized.  Otherwise, a per source lazy initialization
	 * is done here.
	 */
	if (!mpic_is_ipi(mpic, hw) && (mpic->flags & MPIC_NO_RESET)) {
		mpic_set_vector(virq, hw);
1060
		mpic_set_destination(virq, mpic_processor_id(mpic));
1061 1062 1063
		mpic_irq_set_priority(virq, 8);
	}

1064 1065 1066
	return 0;
}

1067
static int mpic_host_xlate(struct irq_domain *h, struct device_node *ct,
1068
			   const u32 *intspec, unsigned int intsize,
1069 1070 1071
			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)

{
1072
	struct mpic *mpic = h->host_data;
1073 1074 1075 1076 1077 1078 1079 1080
	static unsigned char map_mpic_senses[4] = {
		IRQ_TYPE_EDGE_RISING,
		IRQ_TYPE_LEVEL_LOW,
		IRQ_TYPE_LEVEL_HIGH,
		IRQ_TYPE_EDGE_FALLING,
	};

	*out_hwirq = intspec[0];
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
	if (intsize >= 4 && (mpic->flags & MPIC_FSL)) {
		/*
		 * Freescale MPIC with extended intspec:
		 * First two cells are as usual.  Third specifies
		 * an "interrupt type".  Fourth is type-specific data.
		 *
		 * See Documentation/devicetree/bindings/powerpc/fsl/mpic.txt
		 */
		switch (intspec[2]) {
		case 0:
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100
			break;
		case 1:
			if (!(mpic->flags & MPIC_FSL_HAS_EIMR))
				break;

			if (intspec[3] >= ARRAY_SIZE(mpic->err_int_vecs))
				return -EINVAL;

			*out_hwirq = mpic->err_int_vecs[intspec[3]];

1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
			break;
		case 2:
			if (intspec[0] >= ARRAY_SIZE(mpic->ipi_vecs))
				return -EINVAL;

			*out_hwirq = mpic->ipi_vecs[intspec[0]];
			break;
		case 3:
			if (intspec[0] >= ARRAY_SIZE(mpic->timer_vecs))
				return -EINVAL;

			*out_hwirq = mpic->timer_vecs[intspec[0]];
			break;
		default:
			pr_debug("%s: unknown irq type %u\n",
				 __func__, intspec[2]);
			return -EINVAL;
		}

		*out_flags = map_mpic_senses[intspec[1] & 3];
	} else if (intsize > 1) {
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137
		u32 mask = 0x3;

		/* Apple invented a new race of encoding on machines with
		 * an HT APIC. They encode, among others, the index within
		 * the HT APIC. We don't care about it here since thankfully,
		 * it appears that they have the APIC already properly
		 * configured, and thus our current fixup code that reads the
		 * APIC config works fine. However, we still need to mask out
		 * bits in the specifier to make sure we only get bit 0 which
		 * is the level/edge bit (the only sense bit exposed by Apple),
		 * as their bit 1 means something else.
		 */
		if (machine_is(powermac))
			mask = 0x1;
		*out_flags = map_mpic_senses[intspec[1] & mask];
	} else
1138 1139
		*out_flags = IRQ_TYPE_NONE;

1140 1141 1142
	DBG("mpic: xlate (%d cells: 0x%08x 0x%08x) to line 0x%lx sense 0x%x\n",
	    intsize, intspec[0], intspec[1], *out_hwirq, *out_flags);

1143 1144 1145
	return 0;
}

1146 1147 1148 1149 1150 1151 1152 1153 1154 1155
/* IRQ handler for a secondary MPIC cascaded from another IRQ controller */
static void mpic_cascade(unsigned int irq, struct irq_desc *desc)
{
	struct irq_chip *chip = irq_desc_get_chip(desc);
	struct mpic *mpic = irq_desc_get_handler_data(desc);
	unsigned int virq;

	BUG_ON(!(mpic->flags & MPIC_SECONDARY));

	virq = mpic_get_one_irq(mpic);
1156
	if (virq)
1157 1158 1159 1160 1161
		generic_handle_irq(virq);

	chip->irq_eoi(&desc->irq_data);
}

1162
static struct irq_domain_ops mpic_host_ops = {
1163 1164 1165 1166 1167
	.match = mpic_host_match,
	.map = mpic_host_map,
	.xlate = mpic_host_xlate,
};

1168 1169 1170 1171
/*
 * Exported functions
 */

1172
struct mpic * __init mpic_alloc(struct device_node *node,
1173
				phys_addr_t phys_addr,
1174 1175 1176 1177 1178
				unsigned int flags,
				unsigned int isu_size,
				unsigned int irq_count,
				const char *name)
{
1179 1180 1181 1182 1183
	int i, psize, intvec_top;
	struct mpic *mpic;
	u32 greg_feature;
	const char *vers;
	const u32 *psrc;
1184
	u32 last_irq;
1185

1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203
	/* Default MPIC search parameters */
	static const struct of_device_id __initconst mpic_device_id[] = {
		{ .type	      = "open-pic", },
		{ .compatible = "open-pic", },
		{},
	};

	/*
	 * If we were not passed a device-tree node, then perform the default
	 * search for standardized a standardized OpenPIC.
	 */
	if (node) {
		node = of_node_get(node);
	} else {
		node = of_find_matching_node(NULL, mpic_device_id);
		if (!node)
			return NULL;
	}
1204

1205 1206
	/* Pick the physical address from the device tree if unspecified */
	if (!phys_addr) {
1207 1208 1209 1210 1211 1212
		/* Check if it is DCR-based */
		if (of_get_property(node, "dcr-reg", NULL)) {
			flags |= MPIC_USES_DCR;
		} else {
			struct resource r;
			if (of_address_to_resource(node, 0, &r))
1213
				goto err_of_node_put;
1214 1215 1216
			phys_addr = r.start;
		}
	}
1217

1218 1219 1220 1221 1222
	/* Read extra device-tree properties into the flags variable */
	if (of_get_property(node, "big-endian", NULL))
		flags |= MPIC_BIG_ENDIAN;
	if (of_get_property(node, "pic-no-reset", NULL))
		flags |= MPIC_NO_RESET;
1223 1224
	if (of_get_property(node, "single-cpu-affinity", NULL))
		flags |= MPIC_SINGLE_DEST_CPU;
1225
	if (of_device_is_compatible(node, "fsl,mpic"))
1226
		flags |= MPIC_FSL | MPIC_LARGE_VECTORS;
1227

K
Kumar Gala 已提交
1228
	mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL);
1229
	if (mpic == NULL)
1230
		goto err_of_node_put;
K
Kumar Gala 已提交
1231

1232
	mpic->name = name;
1233
	mpic->node = node;
1234
	mpic->paddr = phys_addr;
1235
	mpic->flags = flags;
1236

1237
	mpic->hc_irq = mpic_irq_chip;
1238
	mpic->hc_irq.name = name;
1239
	if (!(mpic->flags & MPIC_SECONDARY))
1240
		mpic->hc_irq.irq_set_affinity = mpic_set_affinity;
1241
#ifdef CONFIG_MPIC_U3_HT_IRQS
1242
	mpic->hc_ht_irq = mpic_irq_ht_chip;
1243
	mpic->hc_ht_irq.name = name;
1244
	if (!(mpic->flags & MPIC_SECONDARY))
1245
		mpic->hc_ht_irq.irq_set_affinity = mpic_set_affinity;
1246
#endif /* CONFIG_MPIC_U3_HT_IRQS */
1247

1248
#ifdef CONFIG_SMP
1249
	mpic->hc_ipi = mpic_ipi_chip;
1250
	mpic->hc_ipi.name = name;
1251 1252
#endif /* CONFIG_SMP */

1253 1254 1255
	mpic->hc_tm = mpic_tm_chip;
	mpic->hc_tm.name = name;

1256 1257
	mpic->num_sources = 0; /* so far */

1258
	if (mpic->flags & MPIC_LARGE_VECTORS)
1259 1260 1261 1262
		intvec_top = 2047;
	else
		intvec_top = 255;

1263 1264 1265 1266 1267 1268 1269 1270
	mpic->timer_vecs[0] = intvec_top - 12;
	mpic->timer_vecs[1] = intvec_top - 11;
	mpic->timer_vecs[2] = intvec_top - 10;
	mpic->timer_vecs[3] = intvec_top - 9;
	mpic->timer_vecs[4] = intvec_top - 8;
	mpic->timer_vecs[5] = intvec_top - 7;
	mpic->timer_vecs[6] = intvec_top - 6;
	mpic->timer_vecs[7] = intvec_top - 5;
1271 1272 1273 1274 1275 1276
	mpic->ipi_vecs[0]   = intvec_top - 4;
	mpic->ipi_vecs[1]   = intvec_top - 3;
	mpic->ipi_vecs[2]   = intvec_top - 2;
	mpic->ipi_vecs[3]   = intvec_top - 1;
	mpic->spurious_vec  = intvec_top;

1277
	/* Look for protected sources */
1278
	psrc = of_get_property(mpic->node, "protected-sources", &psize);
1279 1280 1281 1282 1283 1284 1285 1286 1287
	if (psrc) {
		/* Allocate a bitmap with one bit per interrupt */
		unsigned int mapsize = BITS_TO_LONGS(intvec_top + 1);
		mpic->protected = kzalloc(mapsize*sizeof(long), GFP_KERNEL);
		BUG_ON(mpic->protected == NULL);
		for (i = 0; i < psize/sizeof(u32); i++) {
			if (psrc[i] > intvec_top)
				continue;
			__set_bit(psrc[i], mpic->protected);
1288 1289
		}
	}
1290

1291
#ifdef CONFIG_MPIC_WEIRD
1292
	mpic->hw_set = mpic_infos[MPIC_GET_REGSET(mpic->flags)];
1293 1294
#endif

1295
	/* default register type */
1296
	if (mpic->flags & MPIC_BIG_ENDIAN)
1297 1298 1299
		mpic->reg_type = mpic_access_mmio_be;
	else
		mpic->reg_type = mpic_access_mmio_le;
1300

1301 1302 1303 1304
	/*
	 * An MPIC with a "dcr-reg" property must be accessed that way, but
	 * only if the kernel includes DCR support.
	 */
1305
#ifdef CONFIG_PPC_DCR
1306
	if (mpic->flags & MPIC_USES_DCR)
1307 1308
		mpic->reg_type = mpic_access_dcr;
#else
1309
	BUG_ON(mpic->flags & MPIC_USES_DCR);
1310
#endif
1311

1312
	/* Map the global registers */
1313 1314
	mpic_map(mpic, mpic->paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
	mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
1315

1316
	if (mpic->flags & MPIC_FSL) {
1317 1318 1319
		u32 brr1, version;
		int ret;

1320 1321 1322 1323 1324 1325 1326
		/*
		 * Yes, Freescale really did put global registers in the
		 * magic per-cpu area -- and they don't even show up in the
		 * non-magic per-cpu copies that this driver normally uses.
		 */
		mpic_map(mpic, mpic->paddr, &mpic->thiscpuregs,
			 MPIC_CPU_THISBASE, 0x1000);
1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349

		brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
				MPIC_FSL_BRR1);
		version = brr1 & MPIC_FSL_BRR1_VER;

		/* Error interrupt mask register (EIMR) is required for
		 * handling individual device error interrupts. EIMR
		 * was added in MPIC version 4.1.
		 *
		 * Over here we reserve vector number space for error
		 * interrupt vectors. This space is stolen from the
		 * global vector number space, as in case of ipis
		 * and timer interrupts.
		 *
		 * Available vector space = intvec_top - 12, where 12
		 * is the number of vectors which have been consumed by
		 * ipis and timer interrupts.
		 */
		if (version >= 0x401) {
			ret = mpic_setup_error_int(mpic, intvec_top - 12);
			if (ret)
				return NULL;
		}
1350 1351
	}

1352
	/* Reset */
1353 1354 1355 1356

	/* When using a device-node, reset requests are only honored if the MPIC
	 * is allowed to reset.
	 */
1357
	if (!(mpic->flags & MPIC_NO_RESET)) {
1358
		printk(KERN_DEBUG "mpic: Resetting\n");
1359 1360
		mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
			   mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
1361
			   | MPIC_GREG_GCONF_RESET);
1362
		while( mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
1363 1364 1365 1366
		       & MPIC_GREG_GCONF_RESET)
			mb();
	}

1367
	/* CoreInt */
1368
	if (mpic->flags & MPIC_ENABLE_COREINT)
1369 1370 1371 1372
		mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
			   mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
			   | MPIC_GREG_GCONF_COREINT);

1373
	if (mpic->flags & MPIC_ENABLE_MCK)
1374 1375 1376 1377
		mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
			   mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
			   | MPIC_GREG_GCONF_MCK);

1378 1379 1380 1381 1382 1383
	/*
	 * The MPIC driver will crash if there are more cores than we
	 * can initialize, so we may as well catch that problem here.
	 */
	BUG_ON(num_possible_cpus() > MPIC_MAX_CPUS);

1384
	/* Map the per-CPU registers */
1385 1386 1387
	for_each_possible_cpu(i) {
		unsigned int cpu = get_hard_smp_processor_id(i);

1388
		mpic_map(mpic, mpic->paddr, &mpic->cpuregs[cpu],
1389
			 MPIC_INFO(CPU_BASE) + cpu * MPIC_INFO(CPU_STRIDE),
1390
			 0x1000);
1391 1392
	}

1393 1394 1395 1396 1397 1398 1399 1400 1401
	/*
	 * Read feature register.  For non-ISU MPICs, num sources as well. On
	 * ISU MPICs, sources are counted as ISUs are added
	 */
	greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0));

	/*
	 * By default, the last source number comes from the MPIC, but the
	 * device-tree and board support code can override it on buggy hw.
1402 1403
	 * If we get passed an isu_size (multi-isu MPIC) then we use that
	 * as a default instead of the value read from the HW.
1404 1405
	 */
	last_irq = (greg_feature & MPIC_GREG_FEATURE_LAST_SRC_MASK)
1406 1407 1408
				>> MPIC_GREG_FEATURE_LAST_SRC_SHIFT;	
	if (isu_size)
		last_irq = isu_size  * MPIC_MAX_ISU - 1;
1409 1410 1411 1412
	of_property_read_u32(mpic->node, "last-interrupt-source", &last_irq);
	if (irq_count)
		last_irq = irq_count - 1;

1413
	/* Initialize main ISU if none provided */
1414 1415 1416
	if (!isu_size) {
		isu_size = last_irq + 1;
		mpic->num_sources = isu_size;
1417
		mpic_map(mpic, mpic->paddr, &mpic->isus[0],
1418 1419
				MPIC_INFO(IRQ_BASE),
				MPIC_INFO(IRQ_STRIDE) * isu_size);
1420
	}
1421 1422

	mpic->isu_size = isu_size;
1423 1424 1425
	mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
	mpic->isu_mask = (1 << mpic->isu_shift) - 1;

1426
	mpic->irqhost = irq_domain_add_linear(mpic->node,
1427
				       intvec_top,
1428
				       &mpic_host_ops, mpic);
1429 1430 1431 1432 1433

	/*
	 * FIXME: The code leaks the MPIC object and mappings here; this
	 * is very unlikely to fail but it ought to be fixed anyways.
	 */
1434 1435 1436
	if (mpic->irqhost == NULL)
		return NULL;

1437
	/* Display version */
1438
	switch (greg_feature & MPIC_GREG_FEATURE_VERSION_MASK) {
1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451
	case 1:
		vers = "1.0";
		break;
	case 2:
		vers = "1.2";
		break;
	case 3:
		vers = "1.3";
		break;
	default:
		vers = "<unknown>";
		break;
	}
1452 1453
	printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx,"
	       " max %d CPUs\n",
1454
	       name, vers, (unsigned long long)mpic->paddr, num_possible_cpus());
1455 1456
	printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n",
	       mpic->isu_size, mpic->isu_shift, mpic->isu_mask);
1457 1458 1459 1460

	mpic->next = mpics;
	mpics = mpic;

1461
	if (!(mpic->flags & MPIC_SECONDARY)) {
1462
		mpic_primary = mpic;
1463 1464
		irq_set_default_host(mpic->irqhost);
	}
1465 1466

	return mpic;
1467 1468 1469 1470

err_of_node_put:
	of_node_put(node);
	return NULL;
1471 1472 1473
}

void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
1474
			    phys_addr_t paddr)
1475 1476 1477 1478 1479
{
	unsigned int isu_first = isu_num * mpic->isu_size;

	BUG_ON(isu_num >= MPIC_MAX_ISU);

1480
	mpic_map(mpic,
1481
		 paddr, &mpic->isus[isu_num], 0,
1482
		 MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
1483

1484 1485 1486 1487 1488 1489
	if ((isu_first + mpic->isu_size) > mpic->num_sources)
		mpic->num_sources = isu_first + mpic->isu_size;
}

void __init mpic_init(struct mpic *mpic)
{
1490
	int i, cpu;
1491
	int num_timers = 4;
1492 1493 1494 1495 1496 1497

	BUG_ON(mpic->num_sources == 0);

	printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources);

	/* Set current processor priority to max */
1498
	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
1499

1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514
	if (mpic->flags & MPIC_FSL) {
		u32 brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
				      MPIC_FSL_BRR1);
		u32 version = brr1 & MPIC_FSL_BRR1_VER;

		/*
		 * Timer group B is present at the latest in MPIC 3.1 (e.g.
		 * mpc8536).  It is not present in MPIC 2.0 (e.g. mpc8544).
		 * I don't know about the status of intermediate versions (or
		 * whether they even exist).
		 */
		if (version >= 0x0301)
			num_timers = 8;
	}

1515 1516 1517 1518
	/* FSL mpic error interrupt intialization */
	if (mpic->flags & MPIC_FSL_HAS_EIMR)
		mpic_err_int_init(mpic, MPIC_FSL_ERR_INT);

1519
	/* Initialize timers to our reserved vectors and mask them for now */
1520 1521 1522
	for (i = 0; i < num_timers; i++) {
		unsigned int offset = mpic_tm_offset(mpic, i);

1523
		mpic_write(mpic->tmregs,
1524
			   offset + MPIC_INFO(TIMER_DESTINATION),
1525
			   1 << hard_smp_processor_id());
1526
		mpic_write(mpic->tmregs,
1527
			   offset + MPIC_INFO(TIMER_VECTOR_PRI),
1528
			   MPIC_VECPRI_MASK |
1529
			   (9 << MPIC_VECPRI_PRIORITY_SHIFT) |
1530
			   (mpic->timer_vecs[0] + i));
1531 1532 1533 1534 1535 1536 1537 1538
	}

	/* Initialize IPIs to our reserved vectors and mark them disabled for now */
	mpic_test_broken_ipi(mpic);
	for (i = 0; i < 4; i++) {
		mpic_ipi_write(i,
			       MPIC_VECPRI_MASK |
			       (10 << MPIC_VECPRI_PRIORITY_SHIFT) |
1539
			       (mpic->ipi_vecs[0] + i));
1540 1541
	}

1542
	/* Do the HT PIC fixups on U3 broken mpic */
1543
	DBG("MPIC flags: %x\n", mpic->flags);
1544
	if ((mpic->flags & MPIC_U3_HT_IRQS) && !(mpic->flags & MPIC_SECONDARY)) {
1545
		mpic_scan_ht_pics(mpic);
1546 1547
		mpic_u3msi_init(mpic);
	}
1548

1549 1550
	mpic_pasemi_msi_init(mpic);

1551
	cpu = mpic_processor_id(mpic);
1552

1553 1554 1555 1556 1557
	if (!(mpic->flags & MPIC_NO_RESET)) {
		for (i = 0; i < mpic->num_sources; i++) {
			/* start with vector = source number, and masked */
			u32 vecpri = MPIC_VECPRI_MASK | i |
				(8 << MPIC_VECPRI_PRIORITY_SHIFT);
1558
		
1559 1560 1561 1562 1563 1564 1565
			/* check if protected */
			if (mpic->protected && test_bit(i, mpic->protected))
				continue;
			/* init hw */
			mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
			mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), 1 << cpu);
		}
1566 1567
	}
	
1568 1569
	/* Init spurious vector */
	mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), mpic->spurious_vec);
1570

1571 1572 1573 1574 1575
	/* Disable 8259 passthrough, if supported */
	if (!(mpic->flags & MPIC_NO_PTHROU_DIS))
		mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
			   mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
			   | MPIC_GREG_GCONF_8259_PTHROU_DIS);
1576

1577 1578 1579 1580 1581
	if (mpic->flags & MPIC_NO_BIAS)
		mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
			mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
			| MPIC_GREG_GCONF_NO_BIAS);

1582
	/* Set current processor priority to 0 */
1583
	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
1584 1585 1586

#ifdef CONFIG_PM
	/* allocate memory to save mpic state */
1587 1588
	mpic->save_data = kmalloc(mpic->num_sources * sizeof(*mpic->save_data),
				  GFP_KERNEL);
1589 1590
	BUG_ON(mpic->save_data == NULL);
#endif
1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601

	/* Check if this MPIC is chained from a parent interrupt controller */
	if (mpic->flags & MPIC_SECONDARY) {
		int virq = irq_of_parse_and_map(mpic->node, 0);
		if (virq != NO_IRQ) {
			printk(KERN_INFO "%s: hooking up to IRQ %d\n",
					mpic->node->full_name, virq);
			irq_set_handler_data(virq, mpic);
			irq_set_chained_handler(virq, &mpic_cascade);
		}
	}
1602 1603
}

1604 1605 1606 1607 1608 1609 1610 1611 1612
void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio)
{
	u32 v;

	v = mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1);
	v &= ~MPIC_GREG_GLOBAL_CONF_1_CLK_RATIO_MASK;
	v |= MPIC_GREG_GLOBAL_CONF_1_CLK_RATIO(clock_ratio);
	mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1, v);
}
1613

1614 1615
void __init mpic_set_serial_int(struct mpic *mpic, int enable)
{
1616
	unsigned long flags;
1617 1618
	u32 v;

1619
	raw_spin_lock_irqsave(&mpic_lock, flags);
1620 1621 1622 1623 1624 1625
	v = mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1);
	if (enable)
		v |= MPIC_GREG_GLOBAL_CONF_1_SIE;
	else
		v &= ~MPIC_GREG_GLOBAL_CONF_1_SIE;
	mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1, v);
1626
	raw_spin_unlock_irqrestore(&mpic_lock, flags);
1627
}
1628 1629 1630

void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
{
1631
	struct mpic *mpic = mpic_find(irq);
1632
	unsigned int src = virq_to_hw(irq);
1633 1634 1635
	unsigned long flags;
	u32 reg;

1636 1637 1638
	if (!mpic)
		return;

1639
	raw_spin_lock_irqsave(&mpic_lock, flags);
1640
	if (mpic_is_ipi(mpic, src)) {
1641
		reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) &
1642
			~MPIC_VECPRI_PRIORITY_MASK;
1643
		mpic_ipi_write(src - mpic->ipi_vecs[0],
1644
			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
1645
	} else if (mpic_is_tm(mpic, src)) {
1646 1647 1648 1649
		reg = mpic_tm_read(src - mpic->timer_vecs[0]) &
			~MPIC_VECPRI_PRIORITY_MASK;
		mpic_tm_write(src - mpic->timer_vecs[0],
			      reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
1650
	} else {
1651
		reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI))
1652
			& ~MPIC_VECPRI_PRIORITY_MASK;
1653
		mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
1654 1655
			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
	}
1656
	raw_spin_unlock_irqrestore(&mpic_lock, flags);
1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670
}

void mpic_setup_this_cpu(void)
{
#ifdef CONFIG_SMP
	struct mpic *mpic = mpic_primary;
	unsigned long flags;
	u32 msk = 1 << hard_smp_processor_id();
	unsigned int i;

	BUG_ON(mpic == NULL);

	DBG("%s: setup_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());

1671
	raw_spin_lock_irqsave(&mpic_lock, flags);
1672 1673 1674 1675

 	/* let the mpic know we want intrs. default affinity is 0xffffffff
	 * until changed via /proc. That's how it's done on x86. If we want
	 * it differently, then we should make sure we also change the default
1676
	 * values of irq_desc[].affinity in irq.c.
1677 1678 1679
 	 */
	if (distribute_irqs) {
	 	for (i = 0; i < mpic->num_sources ; i++)
1680 1681
			mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
				mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk);
1682 1683 1684
	}

	/* Set current processor priority to 0 */
1685
	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
1686

1687
	raw_spin_unlock_irqrestore(&mpic_lock, flags);
1688 1689 1690 1691 1692 1693 1694
#endif /* CONFIG_SMP */
}

int mpic_cpu_get_priority(void)
{
	struct mpic *mpic = mpic_primary;

1695
	return mpic_cpu_read(MPIC_INFO(CPU_CURRENT_TASK_PRI));
1696 1697 1698 1699 1700 1701 1702
}

void mpic_cpu_set_priority(int prio)
{
	struct mpic *mpic = mpic_primary;

	prio &= MPIC_CPU_TASKPRI_MASK;
1703
	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), prio);
1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715
}

void mpic_teardown_this_cpu(int secondary)
{
	struct mpic *mpic = mpic_primary;
	unsigned long flags;
	u32 msk = 1 << hard_smp_processor_id();
	unsigned int i;

	BUG_ON(mpic == NULL);

	DBG("%s: teardown_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());
1716
	raw_spin_lock_irqsave(&mpic_lock, flags);
1717 1718 1719

	/* let the mpic know we don't want intrs.  */
	for (i = 0; i < mpic->num_sources ; i++)
1720 1721
		mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
			mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) & ~msk);
1722 1723

	/* Set current processor priority to max */
1724
	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
1725 1726 1727 1728
	/* We need to EOI the IPI since not all platforms reset the MPIC
	 * on boot and new interrupts wouldn't get delivered otherwise.
	 */
	mpic_eoi(mpic);
1729

1730
	raw_spin_unlock_irqrestore(&mpic_lock, flags);
1731 1732 1733
}


1734
static unsigned int _mpic_get_one_irq(struct mpic *mpic, int reg)
1735
{
1736
	u32 src;
1737

1738
	src = mpic_cpu_read(reg) & MPIC_INFO(VECPRI_VECTOR_MASK);
1739
#ifdef DEBUG_LOW
1740
	DBG("%s: get_one_irq(reg 0x%x): %d\n", mpic->name, reg, src);
1741
#endif
1742 1743 1744
	if (unlikely(src == mpic->spurious_vec)) {
		if (mpic->flags & MPIC_SPV_EOI)
			mpic_eoi(mpic);
1745
		return NO_IRQ;
1746
	}
1747
	if (unlikely(mpic->protected && test_bit(src, mpic->protected))) {
1748 1749
		printk_ratelimited(KERN_WARNING "%s: Got protected source %d !\n",
				   mpic->name, (int)src);
1750 1751 1752 1753
		mpic_eoi(mpic);
		return NO_IRQ;
	}

1754
	return irq_linear_revmap(mpic->irqhost, src);
1755 1756
}

1757 1758 1759 1760 1761
unsigned int mpic_get_one_irq(struct mpic *mpic)
{
	return _mpic_get_one_irq(mpic, MPIC_INFO(CPU_INTACK));
}

O
Olaf Hering 已提交
1762
unsigned int mpic_get_irq(void)
1763 1764 1765 1766 1767
{
	struct mpic *mpic = mpic_primary;

	BUG_ON(mpic == NULL);

O
Olaf Hering 已提交
1768
	return mpic_get_one_irq(mpic);
1769 1770
}

1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786
unsigned int mpic_get_coreint_irq(void)
{
#ifdef CONFIG_BOOKE
	struct mpic *mpic = mpic_primary;
	u32 src;

	BUG_ON(mpic == NULL);

	src = mfspr(SPRN_EPR);

	if (unlikely(src == mpic->spurious_vec)) {
		if (mpic->flags & MPIC_SPV_EOI)
			mpic_eoi(mpic);
		return NO_IRQ;
	}
	if (unlikely(mpic->protected && test_bit(src, mpic->protected))) {
1787 1788
		printk_ratelimited(KERN_WARNING "%s: Got protected source %d !\n",
				   mpic->name, (int)src);
1789 1790 1791 1792 1793 1794 1795 1796 1797
		return NO_IRQ;
	}

	return irq_linear_revmap(mpic->irqhost, src);
#else
	return NO_IRQ;
#endif
}

1798 1799 1800 1801 1802 1803 1804 1805
unsigned int mpic_get_mcirq(void)
{
	struct mpic *mpic = mpic_primary;

	BUG_ON(mpic == NULL);

	return _mpic_get_one_irq(mpic, MPIC_INFO(CPU_MCACK));
}
1806 1807 1808 1809 1810

#ifdef CONFIG_SMP
void mpic_request_ipis(void)
{
	struct mpic *mpic = mpic_primary;
1811
	int i;
1812 1813
	BUG_ON(mpic == NULL);

1814
	printk(KERN_INFO "mpic: requesting IPIs...\n");
1815 1816 1817

	for (i = 0; i < 4; i++) {
		unsigned int vipi = irq_create_mapping(mpic->irqhost,
1818
						       mpic->ipi_vecs[0] + i);
1819
		if (vipi == NO_IRQ) {
1820 1821
			printk(KERN_ERR "Failed to map %s\n", smp_ipi_name[i]);
			continue;
1822
		}
1823
		smp_request_message_ipi(vipi, i);
1824
	}
1825
}
1826

1827
void smp_mpic_message_pass(int cpu, int msg)
1828 1829
{
	struct mpic *mpic = mpic_primary;
1830
	u32 physmask;
1831 1832 1833

	BUG_ON(mpic == NULL);

1834 1835 1836 1837 1838 1839
	/* make sure we're sending something that translates to an IPI */
	if ((unsigned int)msg > 3) {
		printk("SMP %d: smp_message_pass: unknown msg %d\n",
		       smp_processor_id(), msg);
		return;
	}
1840 1841 1842 1843 1844 1845 1846 1847 1848

#ifdef DEBUG_IPI
	DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, msg);
#endif

	physmask = 1 << get_hard_smp_processor_id(cpu);

	mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) +
		       msg * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE), physmask);
1849
}
1850 1851 1852 1853 1854 1855 1856

int __init smp_mpic_probe(void)
{
	int nr_cpus;

	DBG("smp_mpic_probe()...\n");

1857
	nr_cpus = cpumask_weight(cpu_possible_mask);
1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870

	DBG("nr_cpus: %d\n", nr_cpus);

	if (nr_cpus > 1)
		mpic_request_ipis();

	return nr_cpus;
}

void __devinit smp_mpic_setup_cpu(int cpu)
{
	mpic_setup_this_cpu();
}
1871 1872 1873 1874 1875 1876

void mpic_reset_core(int cpu)
{
	struct mpic *mpic = mpic_primary;
	u32 pir;
	int cpuid = get_hard_smp_processor_id(cpu);
1877
	int i;
1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888

	/* Set target bit for core reset */
	pir = mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));
	pir |= (1 << cpuid);
	mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir);
	mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));

	/* Restore target bit after reset complete */
	pir &= ~(1 << cpuid);
	mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir);
	mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));
1889 1890 1891 1892 1893 1894 1895 1896 1897

	/* Perform 15 EOI on each reset core to clear pending interrupts.
	 * This is required for FSL CoreNet based devices */
	if (mpic->flags & MPIC_FSL) {
		for (i = 0; i < 15; i++) {
			_mpic_write(mpic->reg_type, &mpic->cpuregs[cpuid],
				      MPIC_CPU_EOI, 0);
		}
	}
1898
}
1899
#endif /* CONFIG_SMP */
1900 1901

#ifdef CONFIG_PM
1902
static void mpic_suspend_one(struct mpic *mpic)
1903 1904 1905 1906 1907 1908 1909 1910 1911
{
	int i;

	for (i = 0; i < mpic->num_sources; i++) {
		mpic->save_data[i].vecprio =
			mpic_irq_read(i, MPIC_INFO(IRQ_VECTOR_PRI));
		mpic->save_data[i].dest =
			mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION));
	}
1912 1913 1914 1915 1916 1917 1918 1919 1920 1921
}

static int mpic_suspend(void)
{
	struct mpic *mpic = mpics;

	while (mpic) {
		mpic_suspend_one(mpic);
		mpic = mpic->next;
	}
1922 1923 1924 1925

	return 0;
}

1926
static void mpic_resume_one(struct mpic *mpic)
1927 1928 1929 1930 1931 1932 1933 1934 1935 1936
{
	int i;

	for (i = 0; i < mpic->num_sources; i++) {
		mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI),
			       mpic->save_data[i].vecprio);
		mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
			       mpic->save_data[i].dest);

#ifdef CONFIG_MPIC_U3_HT_IRQS
1937
	if (mpic->fixups) {
1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953
		struct mpic_irq_fixup *fixup = &mpic->fixups[i];

		if (fixup->base) {
			/* we use the lowest bit in an inverted meaning */
			if ((mpic->save_data[i].fixup_data & 1) == 0)
				continue;

			/* Enable and configure */
			writeb(0x10 + 2 * fixup->index, fixup->base + 2);

			writel(mpic->save_data[i].fixup_data & ~1,
			       fixup->base + 4);
		}
	}
#endif
	} /* end for loop */
1954
}
1955

1956 1957 1958 1959 1960 1961 1962 1963
static void mpic_resume(void)
{
	struct mpic *mpic = mpics;

	while (mpic) {
		mpic_resume_one(mpic);
		mpic = mpic->next;
	}
1964 1965
}

1966
static struct syscore_ops mpic_syscore_ops = {
1967 1968 1969 1970 1971 1972
	.resume = mpic_resume,
	.suspend = mpic_suspend,
};

static int mpic_init_sys(void)
{
1973 1974
	register_syscore_ops(&mpic_syscore_ops);
	return 0;
1975 1976 1977
}

device_initcall(mpic_init_sys);
1978
#endif