setup.c 16.0 KB
Newer Older
1
/*
2
 *  Powermac setup and early boot code plus other random bits.
3 4 5 6 7
 *
 *  PowerPC version
 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
 *
 *  Adapted for Power Macintosh by Paul Mackerras
8
 *    Copyright (C) 1996 Paul Mackerras (paulus@samba.org)
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
 *
 *  Derived from "arch/alpha/kernel/setup.c"
 *    Copyright (C) 1995 Linus Torvalds
 *
 *  Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org)
 *
 *  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.
 *
 */

/*
 * bootup setup stuff..
 */

#include <linux/init.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/tty.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/major.h>
#include <linux/initrd.h>
#include <linux/vt_kern.h>
#include <linux/console.h>
#include <linux/pci.h>
#include <linux/adb.h>
#include <linux/cuda.h>
#include <linux/pmu.h>
#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/bitops.h>
#include <linux/suspend.h>
54 55
#include <linux/of_device.h>
#include <linux/of_platform.h>
56 57 58 59 60 61 62

#include <asm/reg.h>
#include <asm/sections.h>
#include <asm/prom.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/io.h>
M
Michael Ellerman 已提交
63
#include <asm/kexec.h>
64 65 66 67 68 69 70 71 72 73
#include <asm/pci-bridge.h>
#include <asm/ohare.h>
#include <asm/mediabay.h>
#include <asm/machdep.h>
#include <asm/dma.h>
#include <asm/cputable.h>
#include <asm/btext.h>
#include <asm/pmac_feature.h>
#include <asm/time.h>
#include <asm/mmu_context.h>
74 75 76
#include <asm/iommu.h>
#include <asm/smu.h>
#include <asm/pmc.h>
77
#include <asm/lmb.h>
78
#include <asm/udbg.h>
79

80
#include "pmac.h"
81 82 83 84 85 86 87

#undef SHOW_GATWICK_IRQS

int ppc_override_l2cr = 0;
int ppc_override_l2cr_value;
int has_l2cache = 0;

88
int pmac_newworld;
89

90 91
static int current_root_goodness = -1;

92
extern struct machdep_calls pmac_md;
93 94 95

#define DEFAULT_ROOT_DEVICE Root_SDA1	/* sda1 - slightly silly choice */

96 97
#ifdef CONFIG_PPC64
int sccdbg;
98 99
#endif

100 101
extern void zs_kgdb_hook(int tty_num);

102
sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN;
103 104 105 106 107 108
EXPORT_SYMBOL(sys_ctrler);

#ifdef CONFIG_PMAC_SMU
unsigned long smu_cmdbuf_abs;
EXPORT_SYMBOL(smu_cmdbuf_abs);
#endif
109 110 111 112 113 114

#ifdef CONFIG_SMP
extern struct smp_ops_t psurge_smp_ops;
extern struct smp_ops_t core99_smp_ops;
#endif /* CONFIG_SMP */

115
static void pmac_show_cpuinfo(struct seq_file *m)
116 117
{
	struct device_node *np;
118
	const char *pp;
119
	int plen;
120 121
	int mbmodel;
	unsigned int mbflags;
122 123
	char* mbname;

124 125 126 127 128 129
	mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
				    PMAC_MB_INFO_MODEL, 0);
	mbflags = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
				    PMAC_MB_INFO_FLAGS, 0);
	if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME,
			      (long) &mbname) != 0)
130 131 132 133
		mbname = "Unknown";

	/* find motherboard type */
	seq_printf(m, "machine\t\t: ");
134
	np = of_find_node_by_path("/");
135
	if (np != NULL) {
136
		pp = of_get_property(np, "model", NULL);
137 138 139 140
		if (pp != NULL)
			seq_printf(m, "%s\n", pp);
		else
			seq_printf(m, "PowerMac\n");
141
		pp = of_get_property(np, "compatible", &plen);
142 143 144 145 146 147 148 149 150 151
		if (pp != NULL) {
			seq_printf(m, "motherboard\t:");
			while (plen > 0) {
				int l = strlen(pp) + 1;
				seq_printf(m, " %s", pp);
				plen -= l;
				pp += l;
			}
			seq_printf(m, "\n");
		}
152
		of_node_put(np);
153 154 155 156 157 158 159 160
	} else
		seq_printf(m, "PowerMac\n");

	/* print parsed model */
	seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
	seq_printf(m, "pmac flags\t: %08x\n", mbflags);

	/* find l2 cache info */
161 162 163 164
	np = of_find_node_by_name(NULL, "l2-cache");
	if (np == NULL)
		np = of_find_node_by_type(NULL, "cache");
	if (np != NULL) {
165 166 167 168
		const unsigned int *ic =
			of_get_property(np, "i-cache-size", NULL);
		const unsigned int *dc =
			of_get_property(np, "d-cache-size", NULL);
169 170
		seq_printf(m, "L2 cache\t:");
		has_l2cache = 1;
171
		if (of_get_property(np, "cache-unified", NULL) != 0 && dc) {
172 173 174 175 176 177 178 179
			seq_printf(m, " %dK unified", *dc / 1024);
		} else {
			if (ic)
				seq_printf(m, " %dK instruction", *ic / 1024);
			if (dc)
				seq_printf(m, "%s %dK data",
					   (ic? " +": ""), *dc / 1024);
		}
180
		pp = of_get_property(np, "ram-type", NULL);
181 182 183
		if (pp)
			seq_printf(m, " %s", pp);
		seq_printf(m, "\n");
184
		of_node_put(np);
185 186 187 188 189 190 191
	}

	/* Indicate newworld/oldworld */
	seq_printf(m, "pmac-generation\t: %s\n",
		   pmac_newworld ? "NewWorld" : "OldWorld");
}

192 193 194
#ifndef CONFIG_ADB_CUDA
int find_via_cuda(void)
{
195 196 197
	struct device_node *dn = of_find_node_by_name(NULL, "via-cuda");

	if (!dn)
198
		return 0;
199
	of_node_put(dn);
200 201 202 203 204
	printk("WARNING ! Your machine is CUDA-based but your kernel\n");
	printk("          wasn't compiled with CONFIG_ADB_CUDA option !\n");
	return 0;
}
#endif
205

206 207
#ifndef CONFIG_ADB_PMU
int find_via_pmu(void)
208
{
209 210 211
	struct device_node *dn = of_find_node_by_name(NULL, "via-pmu");

	if (!dn)
212
		return 0;
213
	of_node_put(dn);
214 215
	printk("WARNING ! Your machine is PMU-based but your kernel\n");
	printk("          wasn't compiled with CONFIG_ADB_PMU option !\n");
P
Paul Mackerras 已提交
216
	return 0;
217 218
}
#endif
219

220 221 222 223 224 225 226
#ifndef CONFIG_PMAC_SMU
int smu_init(void)
{
	/* should check and warn if SMU is present */
	return 0;
}
#endif
227

228 229
#ifdef CONFIG_PPC32
static volatile u32 *sysctrl_regs;
230

231 232
static void __init ohare_init(void)
{
233 234
	struct device_node *dn;

235 236 237 238
	/* this area has the CPU identification register
	   and some registers used by smp boards */
	sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000);

239 240 241 242 243
	/*
	 * Turn on the L2 cache.
	 * We assume that we have a PSX memory controller iff
	 * we have an ohare I/O controller.
	 */
244 245 246
	dn = of_find_node_by_name(NULL, "ohare");
	if (dn) {
		of_node_put(dn);
247 248 249 250 251 252 253 254 255 256
		if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) {
			if (sysctrl_regs[4] & 0x10)
				sysctrl_regs[4] |= 0x04000020;
			else
				sysctrl_regs[4] |= 0x04000000;
			if(has_l2cache)
				printk(KERN_INFO "Level 2 cache enabled\n");
		}
	}
}
257

258 259
static void __init l2cr_init(void)
{
260 261
	/* Checks "l2cr-value" property in the registry */
	if (cpu_has_feature(CPU_FTR_L2CR)) {
262
		struct device_node *np = of_find_node_by_name(NULL, "cpus");
263
		if (np == 0)
264
			np = of_find_node_by_type(NULL, "cpu");
265
		if (np != 0) {
266
			const unsigned int *l2cr =
267
				of_get_property(np, "l2cr-value", NULL);
268 269 270 271 272 273
			if (l2cr != 0) {
				ppc_override_l2cr = 1;
				ppc_override_l2cr_value = *l2cr;
				_set_L2CR(0);
				_set_L2CR(ppc_override_l2cr_value);
			}
274
			of_node_put(np);
275 276 277 278
		}
	}

	if (ppc_override_l2cr)
279 280 281 282
		printk(KERN_INFO "L2CR overridden (0x%x), "
		       "backside cache is %s\n",
		       ppc_override_l2cr_value,
		       (ppc_override_l2cr_value & 0x80000000)
283
				? "enabled" : "disabled");
284 285 286
}
#endif

287
static void __init pmac_setup_arch(void)
288
{
P
Paul Mackerras 已提交
289
	struct device_node *cpu, *ic;
290
	const int *fp;
291 292 293 294 295 296 297 298 299
	unsigned long pvr;

	pvr = PVR_VER(mfspr(SPRN_PVR));

	/* Set loops_per_jiffy to a half-way reasonable value,
	   for use until calibrate_delay gets called. */
	loops_per_jiffy = 50000000 / HZ;
	cpu = of_find_node_by_type(NULL, "cpu");
	if (cpu != NULL) {
300
		fp = of_get_property(cpu, "clock-frequency", NULL);
301 302 303 304 305 306 307 308 309 310 311 312 313 314
		if (fp != NULL) {
			if (pvr >= 0x30 && pvr < 0x80)
				/* PPC970 etc. */
				loops_per_jiffy = *fp / (3 * HZ);
			else if (pvr == 4 || pvr >= 8)
				/* 604, G3, G4 etc. */
				loops_per_jiffy = *fp / HZ;
			else
				/* 601, 603, etc. */
				loops_per_jiffy = *fp / (2 * HZ);
		}
		of_node_put(cpu);
	}

P
Paul Mackerras 已提交
315
	/* See if newworld or oldworld */
316
	for (ic = NULL; (ic = of_find_all_nodes(ic)) != NULL; )
317
		if (of_get_property(ic, "interrupt-controller", NULL))
318
			break;
319 320
	if (ic) {
		pmac_newworld = 1;
P
Paul Mackerras 已提交
321
		of_node_put(ic);
322
	}
P
Paul Mackerras 已提交
323

324 325 326 327 328 329 330 331
	/* Lookup PCI hosts */
	pmac_pci_init();

#ifdef CONFIG_PPC32
	ohare_init();
	l2cr_init();
#endif /* CONFIG_PPC32 */

332 333 334 335 336 337
#ifdef CONFIG_KGDB
	zs_kgdb_hook(0);
#endif

	find_via_cuda();
	find_via_pmu();
338 339
	smu_init();

340
#if defined(CONFIG_NVRAM) || defined(CONFIG_PPC64)
341 342
	pmac_nvram_init();
#endif
343 344

#ifdef CONFIG_PPC32
345 346 347 348 349 350
#ifdef CONFIG_BLK_DEV_INITRD
	if (initrd_start)
		ROOT_DEV = Root_RAM0;
	else
#endif
		ROOT_DEV = DEFAULT_ROOT_DEVICE;
351
#endif
352 353 354

#ifdef CONFIG_SMP
	/* Check for Core99 */
355 356 357 358 359 360 361
	ic = of_find_node_by_name(NULL, "uni-n");
	if (!ic)
		ic = of_find_node_by_name(NULL, "u3");
	if (!ic)
		ic = of_find_node_by_name(NULL, "u4");
	if (ic) {
		of_node_put(ic);
362
		smp_ops = &core99_smp_ops;
363
	}
364
#ifdef CONFIG_PPC32
365 366 367 368 369 370 371 372 373 374 375
	else {
		/*
		 * We have to set bits in cpu_possible_map here since the
		 * secondary CPU(s) aren't in the device tree, and
		 * setup_per_cpu_areas only allocates per-cpu data for
		 * CPUs in the cpu_possible_map.
		 */
		int cpu;

		for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu)
			cpu_set(cpu, cpu_possible_map);
376
		smp_ops = &psurge_smp_ops;
377
	}
378
#endif
379
#endif /* CONFIG_SMP */
380 381 382 383 384 385 386

#ifdef CONFIG_ADB
	if (strstr(cmd_line, "adb_sync")) {
		extern int __adb_probe_sync;
		__adb_probe_sync = 1;
	}
#endif /* CONFIG_ADB */
387 388 389
}

#ifdef CONFIG_SCSI
390
void note_scsi_host(struct device_node *node, void *host)
391 392
{
}
393
EXPORT_SYMBOL(note_scsi_host);
394 395
#endif

396 397
static int initializing = 1;

398 399
static int pmac_late_init(void)
{
400 401 402
	if (!machine_is(powermac))
		return -ENODEV;

403
	initializing = 0;
404 405 406
	/* this is udbg (which is __init) and we can later use it during
	 * cpu hotplug (in smp_core99_kick_cpu) */
	ppc_md.progress = NULL;
407 408 409 410 411
	return 0;
}

late_initcall(pmac_late_init);

412 413 414 415 416 417 418
/*
 * This is __init_refok because we check for "initializing" before
 * touching any of the __init sensitive things and "initializing"
 * will be false after __init time. This can't be __init because it
 * can be called whenever a disk is first accessed.
 */
void __init_refok note_bootable_part(dev_t dev, int part, int goodness)
419 420 421 422 423 424 425 426
{
	char *p;

	if (!initializing)
		return;
	if ((goodness <= current_root_goodness) &&
	    ROOT_DEV != DEFAULT_ROOT_DEVICE)
		return;
427 428
	p = strstr(boot_command_line, "root=");
	if (p != NULL && (p == boot_command_line || p[-1] == ' '))
429 430
		return;

431 432
	ROOT_DEV = dev + part;
	current_root_goodness = goodness;
433 434 435
}

#ifdef CONFIG_ADB_CUDA
436 437
static void cuda_restart(void)
{
438 439
	struct adb_request req;

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 470
	cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM);
	for (;;)
		cuda_poll();
}

static void cuda_shutdown(void)
{
	struct adb_request req;

	cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN);
	for (;;)
		cuda_poll();
}

#else
#define cuda_restart()
#define cuda_shutdown()
#endif

#ifndef CONFIG_ADB_PMU
#define pmu_restart()
#define pmu_shutdown()
#endif

#ifndef CONFIG_PMAC_SMU
#define smu_restart()
#define smu_shutdown()
#endif

static void pmac_restart(char *cmd)
{
471 472
	switch (sys_ctrler) {
	case SYS_CTRLER_CUDA:
473
		cuda_restart();
474 475 476 477
		break;
	case SYS_CTRLER_PMU:
		pmu_restart();
		break;
478 479 480
	case SYS_CTRLER_SMU:
		smu_restart();
		break;
481 482 483 484
	default: ;
	}
}

485
static void pmac_power_off(void)
486 487 488
{
	switch (sys_ctrler) {
	case SYS_CTRLER_CUDA:
489
		cuda_shutdown();
490 491 492 493
		break;
	case SYS_CTRLER_PMU:
		pmu_shutdown();
		break;
494 495 496
	case SYS_CTRLER_SMU:
		smu_shutdown();
		break;
497 498 499 500 501 502 503 504 505 506
	default: ;
	}
}

static void
pmac_halt(void)
{
	pmac_power_off();
}

507 508 509 510 511
/* 
 * Early initialization.
 */
static void __init pmac_init_early(void)
{
512 513 514 515
	/* Enable early btext debug if requested */
	if (strstr(cmd_line, "btextdbg")) {
		udbg_adb_init_early();
		register_early_udbg_console();
516 517
	}

518 519 520 521 522 523 524 525
	/* Probe motherboard chipset */
	pmac_feature_init();

	/* Initialize debug stuff */
	udbg_scc_init(!!strstr(cmd_line, "sccdbg"));
	udbg_adb_init(!!strstr(cmd_line, "btextdbg"));

#ifdef CONFIG_PPC64
526
	iommu_init_early_dart();
527 528 529 530
#endif
}

static int __init pmac_declare_of_platform_devices(void)
531
{
532
	struct device_node *np;
533

534 535 536 537 538 539
	if (machine_is(chrp))
		return -1;

	if (!machine_is(powermac))
		return 0;

540
	np = of_find_node_by_name(NULL, "valkyrie");
541 542
	if (np)
		of_platform_device_create(np, "valkyrie", NULL);
543
	np = of_find_node_by_name(NULL, "platinum");
544 545 546 547 548 549 550
	if (np)
		of_platform_device_create(np, "platinum", NULL);
        np = of_find_node_by_type(NULL, "smu");
        if (np) {
		of_platform_device_create(np, "smu", NULL);
		of_node_put(np);
	}
551 552 553 554 555

	return 0;
}

device_initcall(pmac_declare_of_platform_devices);
556 557 558 559

/*
 * Called very early, MMU is off, device-tree isn't unflattened
 */
560
static int __init pmac_probe(void)
561
{
562 563 564 565
	unsigned long root = of_get_flat_dt_root();

	if (!of_flat_dt_is_compatible(root, "Power Macintosh") &&
	    !of_flat_dt_is_compatible(root, "MacRISC"))
566 567
		return 0;

568
#ifdef CONFIG_PPC64
569 570 571 572 573 574
	/*
	 * On U3, the DART (iommu) must be allocated now since it
	 * has an impact on htab_initialize (due to the large page it
	 * occupies having to be broken up so the DART itself is not
	 * part of the cacheable linar mapping
	 */
575
	alloc_dart_table();
576 577

	hpte_init_native();
578 579
#endif

580 581 582 583 584 585 586 587 588 589 590 591 592 593 594
#ifdef CONFIG_PPC32
	/* isa_io_base gets set in pmac_pci_init */
	ISA_DMA_THRESHOLD = ~0L;
	DMA_MODE_READ = 1;
	DMA_MODE_WRITE = 2;

#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
#ifdef CONFIG_BLK_DEV_IDE_PMAC
        ppc_ide_md.ide_init_hwif	= pmac_ide_init_hwif_ports;
        ppc_ide_md.default_io_base	= pmac_ide_get_base;
#endif /* CONFIG_BLK_DEV_IDE_PMAC */
#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */

#endif /* CONFIG_PPC32 */

595 596 597 598 599 600 601 602 603 604 605 606 607
#ifdef CONFIG_PMAC_SMU
	/*
	 * SMU based G5s need some memory below 2Gb, at least the current
	 * driver needs that. We have to allocate it now. We allocate 4k
	 * (1 small page) for now.
	 */
	smu_cmdbuf_abs = lmb_alloc_base(4096, 4096, 0x80000000UL);
#endif /* CONFIG_PMAC_SMU */

	return 1;
}

#ifdef CONFIG_PPC64
608 609
/* Move that to pci.c */
static int pmac_pci_probe_mode(struct pci_bus *bus)
610 611 612 613
{
	struct device_node *node = bus->sysdata;

	/* We need to use normal PCI probing for the AGP bus,
614
	 * since the device for the AGP bridge isn't in the tree.
615
	 * Same for the PCIe host on U4 and the HT host bridge.
616
	 */
617
	if (bus->self == NULL && (of_device_is_compatible(node, "u3-agp") ||
618 619
				  of_device_is_compatible(node, "u4-pcie") ||
				  of_device_is_compatible(node, "u3-ht")))
620 621 622
		return PCI_PROBE_NORMAL;
	return PCI_PROBE_DEVTREE;
}
623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668

#ifdef CONFIG_HOTPLUG_CPU
/* access per cpu vars from generic smp.c */
DECLARE_PER_CPU(int, cpu_state);

static void pmac_cpu_die(void)
{
	/*
	 * turn off as much as possible, we'll be
	 * kicked out as this will only be invoked
	 * on core99 platforms for now ...
	 */

	printk(KERN_INFO "CPU#%d offline\n", smp_processor_id());
	__get_cpu_var(cpu_state) = CPU_DEAD;
	smp_wmb();

	/*
	 * during the path that leads here preemption is disabled,
	 * reenable it now so that when coming up preempt count is
	 * zero correctly
	 */
	preempt_enable();

	/*
	 * hard-disable interrupts for the non-NAP case, the NAP code
	 * needs to re-enable interrupts (but soft-disables them)
	 */
	hard_irq_disable();

	while (1) {
		/* let's not take timer interrupts too often ... */
		set_dec(0x7fffffff);

		/* should always be true at this point */
		if (cpu_has_feature(CPU_FTR_CAN_NAP))
			power4_cpu_offline_powersave();
		else {
			HMT_low();
			HMT_very_low();
		}
	}
}
#endif /* CONFIG_HOTPLUG_CPU */

#endif /* CONFIG_PPC64 */
669

670 671
define_machine(powermac) {
	.name			= "PowerMac",
672 673 674 675 676
	.probe			= pmac_probe,
	.setup_arch		= pmac_setup_arch,
	.init_early		= pmac_init_early,
	.show_cpuinfo		= pmac_show_cpuinfo,
	.init_IRQ		= pmac_pic_init,
677
	.get_irq		= NULL,	/* changed later */
678
	.pci_irq_fixup		= pmac_pci_irq_fixup,
679 680 681 682 683 684 685 686 687
	.restart		= pmac_restart,
	.power_off		= pmac_power_off,
	.halt			= pmac_halt,
	.time_init		= pmac_time_init,
	.get_boot_time		= pmac_get_boot_time,
	.set_rtc_time		= pmac_set_rtc_time,
	.get_rtc_time		= pmac_get_rtc_time,
	.calibrate_decr		= pmac_calibrate_decr,
	.feature_call		= pmac_do_feature_call,
688
	.progress		= udbg_progress,
689
#ifdef CONFIG_PPC64
690
	.pci_probe_mode		= pmac_pci_probe_mode,
691
	.power_save		= power4_idle,
692
	.enable_pmcs		= power4_enable_pmcs,
M
Michael Ellerman 已提交
693 694 695
#ifdef CONFIG_KEXEC
	.machine_kexec		= default_machine_kexec,
	.machine_kexec_prepare	= default_machine_kexec_prepare,
696
	.machine_crash_shutdown	= default_machine_crash_shutdown,
697
#endif
M
Michael Ellerman 已提交
698
#endif /* CONFIG_PPC64 */
699 700 701 702 703
#ifdef CONFIG_PPC32
	.pcibios_enable_device_hook = pmac_pci_enable_device_hook,
	.pcibios_after_init	= pmac_pcibios_after_init,
	.phys_mem_access_prot	= pci_phys_mem_access_prot,
#endif
704
#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64)
705
	.cpu_die		= pmac_cpu_die,
706
#endif
707
};