pic.c 17.7 KB
Newer Older
1 2 3 4 5 6 7
/*
 *  Support for the interrupt controllers found on Power Macintosh,
 *  currently Apple's "Grand Central" interrupt controller in all
 *  it's incarnations. OpenPIC support used on newer machines is
 *  in a separate file
 *
 *  Copyright (C) 1997 Paul Mackerras (paulus@samba.org)
8 9
 *  Copyright (C) 2005 Benjamin Herrenschmidt (benh@kernel.crashing.org)
 *                     IBM, Corp.
10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version
 *  2 of the License, or (at your option) any later version.
 *
 */

#include <linux/stddef.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
24
#include <linux/syscore_ops.h>
25 26 27 28 29 30 31 32 33 34 35
#include <linux/adb.h>
#include <linux/pmu.h>

#include <asm/sections.h>
#include <asm/io.h>
#include <asm/smp.h>
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#include <asm/time.h>
#include <asm/pmac_feature.h>
#include <asm/mpic.h>
36
#include <asm/xmon.h>
37

38
#include "pmac.h"
39

40
#ifdef CONFIG_PPC32
41 42 43 44 45 46 47
struct pmac_irq_hw {
        unsigned int    event;
        unsigned int    enable;
        unsigned int    ack;
        unsigned int    level;
};

48 49 50 51
/* Workaround flags for 32bit powermac machines */
unsigned int of_irq_workarounds;
struct device_node *of_irq_dflt_pic;

52
/* Default addresses */
53
static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4];
54 55 56 57

static int max_irqs;
static int max_real_irqs;

58
static DEFINE_RAW_SPINLOCK(pmac_pic_lock);
59

S
Stephen Rothwell 已提交
60 61
#define NR_MASK_WORDS	((NR_IRQS + 31) / 32)
static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
62 63
static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
static int pmac_irq_cascade = -1;
64
static struct irq_domain *pmac_pic_host;
S
Stephen Rothwell 已提交
65

66
static void __pmac_retrigger(unsigned int irq_nr)
67
{
68 69 70 71 72 73
	if (irq_nr >= max_real_irqs && pmac_irq_cascade > 0) {
		__set_bit(irq_nr, ppc_lost_interrupts);
		irq_nr = pmac_irq_cascade;
		mb();
	}
	if (!__test_and_set_bit(irq_nr, ppc_lost_interrupts)) {
74
		atomic_inc(&ppc_n_lost_interrupts);
75
		set_dec(1);
76 77 78
	}
}

79
static void pmac_mask_and_ack_irq(struct irq_data *d)
80
{
81
	unsigned int src = irqd_to_hwirq(d);
82 83
        unsigned long bit = 1UL << (src & 0x1f);
        int i = src >> 5;
84 85
        unsigned long flags;

86
	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
87 88
        __clear_bit(src, ppc_cached_irq_mask);
        if (__test_and_clear_bit(src, ppc_lost_interrupts))
89
                atomic_dec(&ppc_n_lost_interrupts);
90 91 92 93 94 95 96 97
        out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
        out_le32(&pmac_irq_hw[i]->ack, bit);
        do {
                /* make sure ack gets to controller before we enable
                   interrupts */
                mb();
        } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
                != (ppc_cached_irq_mask[i] & bit));
98
	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
99 100
}

101
static void pmac_ack_irq(struct irq_data *d)
102
{
103
	unsigned int src = irqd_to_hwirq(d);
104 105
        unsigned long bit = 1UL << (src & 0x1f);
        int i = src >> 5;
106 107
        unsigned long flags;

108
	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
109
	if (__test_and_clear_bit(src, ppc_lost_interrupts))
110 111 112
                atomic_dec(&ppc_n_lost_interrupts);
        out_le32(&pmac_irq_hw[i]->ack, bit);
        (void)in_le32(&pmac_irq_hw[i]->ack);
113
	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
114 115 116 117 118 119 120 121 122 123
}

static void __pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
{
        unsigned long bit = 1UL << (irq_nr & 0x1f);
        int i = irq_nr >> 5;

        if ((unsigned)irq_nr >= max_irqs)
                return;

124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
        /* enable unmasked interrupts */
        out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);

        do {
                /* make sure mask gets to controller before we
                   return to user */
                mb();
        } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
                != (ppc_cached_irq_mask[i] & bit));

        /*
         * Unfortunately, setting the bit in the enable register
         * when the device interrupt is already on *doesn't* set
         * the bit in the flag register or request another interrupt.
         */
        if (bit & ppc_cached_irq_mask[i] & in_le32(&pmac_irq_hw[i]->level))
140
		__pmac_retrigger(irq_nr);
141 142 143 144 145
}

/* When an irq gets requested for the first client, if it's an
 * edge interrupt, we clear any previous one on the controller
 */
146
static unsigned int pmac_startup_irq(struct irq_data *d)
147
{
148
	unsigned long flags;
149
	unsigned int src = irqd_to_hwirq(d);
150 151
        unsigned long bit = 1UL << (src & 0x1f);
        int i = src >> 5;
152

153
	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
154
	if (!irqd_is_level_type(d))
155
		out_le32(&pmac_irq_hw[i]->ack, bit);
156 157
        __set_bit(src, ppc_cached_irq_mask);
        __pmac_set_irq_mask(src, 0);
158
	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
159 160 161 162

	return 0;
}

163
static void pmac_mask_irq(struct irq_data *d)
164
{
165
	unsigned long flags;
166
	unsigned int src = irqd_to_hwirq(d);
167

168
	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
169
        __clear_bit(src, ppc_cached_irq_mask);
170
        __pmac_set_irq_mask(src, 1);
171
	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
172 173
}

174
static void pmac_unmask_irq(struct irq_data *d)
175
{
176
	unsigned long flags;
177
	unsigned int src = irqd_to_hwirq(d);
178

179
	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
180 181
	__set_bit(src, ppc_cached_irq_mask);
        __pmac_set_irq_mask(src, 0);
182
	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
183 184
}

185
static int pmac_retrigger(struct irq_data *d)
186
{
187
	unsigned long flags;
188

189
	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
190
	__pmac_retrigger(irqd_to_hwirq(d));
191
	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
192 193
	return 1;
}
194

195
static struct irq_chip pmac_pic = {
196
	.name		= "PMAC-PIC",
197 198 199 200 201 202
	.irq_startup	= pmac_startup_irq,
	.irq_mask	= pmac_mask_irq,
	.irq_ack	= pmac_ack_irq,
	.irq_mask_ack	= pmac_mask_and_ack_irq,
	.irq_unmask	= pmac_unmask_irq,
	.irq_retrigger	= pmac_retrigger,
203 204
};

O
Olaf Hering 已提交
205
static irqreturn_t gatwick_action(int cpl, void *dev_id)
206
{
207
	unsigned long flags;
208
	int irq, bits;
209
	int rc = IRQ_NONE;
210

211
	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
212 213 214
	for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) {
		int i = irq >> 5;
		bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
215
		bits |= in_le32(&pmac_irq_hw[i]->level);
216 217 218 219
		bits &= ppc_cached_irq_mask[i];
		if (bits == 0)
			continue;
		irq += __ilog2(bits);
220
		raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
221
		generic_handle_irq(irq);
222
		raw_spin_lock_irqsave(&pmac_pic_lock, flags);
223
		rc = IRQ_HANDLED;
224
	}
225
	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
226
	return rc;
227 228
}

O
Olaf Hering 已提交
229
static unsigned int pmac_pic_get_irq(void)
230 231 232
{
	int irq;
	unsigned long bits = 0;
233
	unsigned long flags;
234

235
#ifdef CONFIG_PPC_PMAC32_PSURGE
236 237 238
	/* IPI's are a hack on the powersurge -- Cort */
	if (smp_processor_id() != 0) {
		return  psurge_secondary_virq;
239
        }
240
#endif /* CONFIG_PPC_PMAC32_PSURGE */
241
	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
242 243 244
	for (irq = max_real_irqs; (irq -= 32) >= 0; ) {
		int i = irq >> 5;
		bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
245
		bits |= in_le32(&pmac_irq_hw[i]->level);
246 247 248 249 250 251
		bits &= ppc_cached_irq_mask[i];
		if (bits == 0)
			continue;
		irq += __ilog2(bits);
		break;
	}
252
	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
253 254 255
	if (unlikely(irq < 0))
		return NO_IRQ;
	return irq_linear_revmap(pmac_pic_host, irq);
256 257 258 259 260 261 262 263 264 265 266 267 268 269
}

#ifdef CONFIG_XMON
static struct irqaction xmon_action = {
	.handler	= xmon_irq,
	.flags		= 0,
	.name		= "NMI - XMON"
};
#endif

static struct irqaction gatwick_cascade_action = {
	.handler	= gatwick_action,
	.name		= "cascade",
};
270

271
static int pmac_pic_host_match(struct irq_domain *h, struct device_node *node)
272 273 274 275 276
{
	/* We match all, we don't always have a node anyway */
	return 1;
}

277
static int pmac_pic_host_map(struct irq_domain *h, unsigned int virq,
278
			     irq_hw_number_t hw)
279 280 281 282 283 284 285
{
	if (hw >= max_irqs)
		return -EINVAL;

	/* Mark level interrupts, set delayed disable for edge ones and set
	 * handlers
	 */
286 287
	irq_set_status_flags(virq, IRQ_LEVEL);
	irq_set_chip_and_handler(virq, &pmac_pic, handle_level_irq);
288 289 290
	return 0;
}

291
static int pmac_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
292
			       const u32 *intspec, unsigned int intsize,
293 294 295 296
			       irq_hw_number_t *out_hwirq,
			       unsigned int *out_flags)

{
297
	*out_flags = IRQ_TYPE_NONE;
298 299 300 301
	*out_hwirq = *intspec;
	return 0;
}

302
static struct irq_domain_ops pmac_pic_host_ops = {
303 304 305 306 307
	.match = pmac_pic_host_match,
	.map = pmac_pic_host_map,
	.xlate = pmac_pic_host_xlate,
};

308
static void __init pmac_pic_probe_oldstyle(void)
309 310
{
        int i;
311 312 313 314
        struct device_node *master = NULL;
	struct device_node *slave = NULL;
	u8 __iomem *addr;
	struct resource r;
315

316
	/* Set our get_irq function */
317
	ppc_md.get_irq = pmac_pic_get_irq;
318

319 320
	/*
	 * Find the interrupt controller type & node
321
	 */
322 323 324 325 326

	if ((master = of_find_node_by_name(NULL, "gc")) != NULL) {
		max_irqs = max_real_irqs = 32;
	} else if ((master = of_find_node_by_name(NULL, "ohare")) != NULL) {
		max_irqs = max_real_irqs = 32;
327
		/* We might have a second cascaded ohare */
328
		slave = of_find_node_by_name(NULL, "pci106b,7");
329
		if (slave)
330 331 332 333
			max_irqs = 64;
	} else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) {
		max_irqs = max_real_irqs = 64;

334
		/* We might have a second cascaded heathrow */
335 336 337
		slave = of_find_node_by_name(master, "mac-io");

		/* Check ordering of master & slave */
338
		if (of_device_is_compatible(master, "gatwick")) {
339 340 341 342 343 344
			struct device_node *tmp;
			BUG_ON(slave == NULL);
			tmp = master;
			master = slave;
			slave = tmp;
		}
345

346
		/* We found a slave */
347
		if (slave)
348 349
			max_irqs = 128;
	}
350 351
	BUG_ON(master == NULL);

352 353 354
	/*
	 * Allocate an irq host
	 */
355
	pmac_pic_host = irq_alloc_host(master, IRQ_DOMAIN_MAP_LINEAR, max_irqs,
356 357 358 359
				       &pmac_pic_host_ops,
				       max_irqs);
	BUG_ON(pmac_pic_host == NULL);
	irq_set_default_host(pmac_pic_host);
360

361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
	/* Get addresses of first controller if we have a node for it */
	BUG_ON(of_address_to_resource(master, 0, &r));

	/* Map interrupts of primary controller */
	addr = (u8 __iomem *) ioremap(r.start, 0x40);
	i = 0;
	pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *)
		(addr + 0x20);
	if (max_real_irqs > 32)
		pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *)
			(addr + 0x10);
	of_node_put(master);

	printk(KERN_INFO "irq: Found primary Apple PIC %s for %d irqs\n",
	       master->full_name, max_real_irqs);

	/* Map interrupts of cascaded controller */
	if (slave && !of_address_to_resource(slave, 0, &r)) {
		addr = (u8 __iomem *)ioremap(r.start, 0x40);
		pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *)
			(addr + 0x20);
		if (max_irqs > 64)
			pmac_irq_hw[i++] =
				(volatile struct pmac_irq_hw __iomem *)
				(addr + 0x10);
386
		pmac_irq_cascade = irq_of_parse_and_map(slave, 0);
387 388 389

		printk(KERN_INFO "irq: Found slave Apple PIC %s for %d irqs"
		       " cascade: %d\n", slave->full_name,
390
		       max_irqs - max_real_irqs, pmac_irq_cascade);
391
	}
392
	of_node_put(slave);
393

394
	/* Disable all interrupts in all controllers */
395 396
	for (i = 0; i * 32 < max_irqs; ++i)
		out_le32(&pmac_irq_hw[i]->enable, 0);
397

398
	/* Hookup cascade irq */
399
	if (slave && pmac_irq_cascade != NO_IRQ)
400
		setup_irq(pmac_irq_cascade, &gatwick_cascade_action);
401

402
	printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs);
403
#ifdef CONFIG_XMON
404
	setup_irq(irq_create_mapping(NULL, 20), &xmon_action);
405 406
#endif
}
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442

int of_irq_map_oldworld(struct device_node *device, int index,
			struct of_irq *out_irq)
{
	const u32 *ints = NULL;
	int intlen;

	/*
	 * Old machines just have a list of interrupt numbers
	 * and no interrupt-controller nodes. We also have dodgy
	 * cases where the APPL,interrupts property is completely
	 * missing behind pci-pci bridges and we have to get it
	 * from the parent (the bridge itself, as apple just wired
	 * everything together on these)
	 */
	while (device) {
		ints = of_get_property(device, "AAPL,interrupts", &intlen);
		if (ints != NULL)
			break;
		device = device->parent;
		if (device && strcmp(device->type, "pci") != 0)
			break;
	}
	if (ints == NULL)
		return -EINVAL;
	intlen /= sizeof(u32);

	if (index >= intlen)
		return -EINVAL;

	out_irq->controller = NULL;
	out_irq->specifier[0] = ints[index];
	out_irq->size = 1;

	return 0;
}
443 444 445 446 447 448 449 450 451
#endif /* CONFIG_PPC32 */

static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic)
{
#if defined(CONFIG_XMON) && defined(CONFIG_PPC32)
	struct device_node* pswitch;
	int nmi_irq;

	pswitch = of_find_node_by_name(NULL, "programmer-switch");
452 453 454 455 456 457 458
	if (pswitch) {
		nmi_irq = irq_of_parse_and_map(pswitch, 0);
		if (nmi_irq != NO_IRQ) {
			mpic_irq_set_priority(nmi_irq, 9);
			setup_irq(nmi_irq, &xmon_action);
		}
		of_node_put(pswitch);
459 460 461 462
	}
#endif	/* defined(CONFIG_XMON) && defined(CONFIG_PPC32) */
}

463 464 465 466 467
static struct mpic * __init pmac_setup_one_mpic(struct device_node *np,
						int master)
{
	const char *name = master ? " MPIC 1   " : " MPIC 2   ";
	struct mpic *mpic;
468
	unsigned int flags = master ? 0 : MPIC_SECONDARY;
469 470 471 472

	pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0);

	flags |= MPIC_WANTS_RESET;
473
	if (of_get_property(np, "big-endian", NULL))
474 475 476 477 478 479
		flags |= MPIC_BIG_ENDIAN;

	/* Primary Big Endian means HT interrupts. This is quite dodgy
	 * but works until I find a better way
	 */
	if (master && (flags & MPIC_BIG_ENDIAN))
480
		flags |= MPIC_U3_HT_IRQS;
481

482
	mpic = mpic_alloc(np, 0, flags, 0, 0, name);
483 484 485 486 487 488 489 490
	if (mpic == NULL)
		return NULL;

	mpic_init(mpic);

	return mpic;
 }

491 492 493 494 495 496 497 498 499
static int __init pmac_pic_probe_mpic(void)
{
	struct mpic *mpic1, *mpic2;
	struct device_node *np, *master = NULL, *slave = NULL;

	/* We can have up to 2 MPICs cascaded */
	for (np = NULL; (np = of_find_node_by_type(np, "open-pic"))
		     != NULL;) {
		if (master == NULL &&
500
		    of_get_property(np, "interrupts", NULL) == NULL)
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
			master = of_node_get(np);
		else if (slave == NULL)
			slave = of_node_get(np);
		if (master && slave)
			break;
	}

	/* Check for bogus setups */
	if (master == NULL && slave != NULL) {
		master = slave;
		slave = NULL;
	}

	/* Not found, default to good old pmac pic */
	if (master == NULL)
		return -ENODEV;

	/* Set master handler */
	ppc_md.get_irq = mpic_get_irq;

	/* Setup master */
522
	mpic1 = pmac_setup_one_mpic(master, 1);
523 524 525 526 527 528 529
	BUG_ON(mpic1 == NULL);

	/* Install NMI if any */
	pmac_pic_setup_mpic_nmi(mpic1);

	of_node_put(master);

530 531 532 533 534
	/* Set up a cascaded controller, if present */
	if (slave) {
		mpic2 = pmac_setup_one_mpic(slave, 0);
		if (mpic2 == NULL)
			printk(KERN_ERR "Failed to setup slave MPIC\n");
535
		of_node_put(slave);
536 537 538 539 540 541 542 543
	}

	return 0;
}


void __init pmac_pic_init(void)
{
544 545 546 547 548
	/* We configure the OF parsing based on our oldworld vs. newworld
	 * platform type and wether we were booted by BootX.
	 */
#ifdef CONFIG_PPC32
	if (!pmac_newworld)
549
		of_irq_workarounds |= OF_IMAP_OLDWORLD_MAC;
550
	if (of_get_property(of_chosen, "linux,bootx", NULL) != NULL)
551
		of_irq_workarounds |= OF_IMAP_NO_PHANDLE;
552

553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
	/* If we don't have phandles on a newworld, then try to locate a
	 * default interrupt controller (happens when booting with BootX).
	 * We do a first match here, hopefully, that only ever happens on
	 * machines with one controller.
	 */
	if (pmac_newworld && (of_irq_workarounds & OF_IMAP_NO_PHANDLE)) {
		struct device_node *np;

		for_each_node_with_property(np, "interrupt-controller") {
			/* Skip /chosen/interrupt-controller */
			if (strcmp(np->name, "chosen") == 0)
				continue;
			/* It seems like at least one person wants
			 * to use BootX on a machine with an AppleKiwi
			 * controller which happens to pretend to be an
			 * interrupt controller too. */
			if (strcmp(np->name, "AppleKiwi") == 0)
				continue;
			/* I think we found one ! */
			of_irq_dflt_pic = np;
			break;
		}
	}
#endif /* CONFIG_PPC32 */
577

578 579 580 581 582 583 584 585 586
	/* We first try to detect Apple's new Core99 chipset, since mac-io
	 * is quite different on those machines and contains an IBM MPIC2.
	 */
	if (pmac_pic_probe_mpic() == 0)
		return;

#ifdef CONFIG_PPC32
	pmac_pic_probe_oldstyle();
#endif
587 588
}

589
#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
590 591 592 593 594 595 596 597 598 599
/*
 * These procedures are used in implementing sleep on the powerbooks.
 * sleep_save_intrs() saves the states of all interrupt enables
 * and disables all interrupts except for the nominated one.
 * sleep_restore_intrs() restores the states of all interrupt enables.
 */
unsigned long sleep_save_mask[2];

/* This used to be passed by the PMU driver but that link got
 * broken with the new driver model. We use this tweak for now...
600
 * We really want to do things differently though...
601 602 603 604 605 606 607 608 609 610 611 612 613
 */
static int pmacpic_find_viaint(void)
{
	int viaint = -1;

#ifdef CONFIG_ADB_PMU
	struct device_node *np;

	if (pmu_get_model() != PMU_OHARE_BASED)
		goto not_found;
	np = of_find_node_by_name(NULL, "via-pmu");
	if (np == NULL)
		goto not_found;
614
	viaint = irq_of_parse_and_map(np, 0);
615 616

not_found:
617
#endif /* CONFIG_ADB_PMU */
618 619 620
	return viaint;
}

621
static int pmacpic_suspend(void)
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
{
	int viaint = pmacpic_find_viaint();

	sleep_save_mask[0] = ppc_cached_irq_mask[0];
	sleep_save_mask[1] = ppc_cached_irq_mask[1];
	ppc_cached_irq_mask[0] = 0;
	ppc_cached_irq_mask[1] = 0;
	if (viaint > 0)
		set_bit(viaint, ppc_cached_irq_mask);
	out_le32(&pmac_irq_hw[0]->enable, ppc_cached_irq_mask[0]);
	if (max_real_irqs > 32)
		out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]);
	(void)in_le32(&pmac_irq_hw[0]->event);
	/* make sure mask gets to controller before we return to caller */
	mb();
        (void)in_le32(&pmac_irq_hw[0]->enable);

        return 0;
}

642
static void pmacpic_resume(void)
643 644 645 646 647 648 649 650 651
{
	int i;

	out_le32(&pmac_irq_hw[0]->enable, 0);
	if (max_real_irqs > 32)
		out_le32(&pmac_irq_hw[1]->enable, 0);
	mb();
	for (i = 0; i < max_real_irqs; ++i)
		if (test_bit(i, sleep_save_mask))
652
			pmac_unmask_irq(irq_get_irq_data(i));
653 654
}

655 656 657
static struct syscore_ops pmacpic_syscore_ops = {
	.suspend	= pmacpic_suspend,
	.resume		= pmacpic_resume,
658 659
};

660
static int __init init_pmacpic_syscore(void)
661
{
662 663
	if (pmac_irq_hw[0])
		register_syscore_ops(&pmacpic_syscore_ops);
664 665 666
	return 0;
}

667 668 669
machine_subsys_initcall(powermac, init_pmacpic_syscore);

#endif /* CONFIG_PM && CONFIG_PPC32 */