setup.c 15.9 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 54 55 56 57 58 59 60
 *
 *  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>

#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 已提交
61
#include <asm/kexec.h>
62 63 64 65 66 67 68 69 70 71
#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/of_device.h>
72
#include <asm/of_platform.h>
73
#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 98
#ifdef CONFIG_PPC64
#include <asm/udbg.h>
int sccdbg;
99 100
#endif

101 102
extern void zs_kgdb_hook(int tty_num);

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

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

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

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

125 126 127 128 129 130
	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)
131 132 133 134
		mbname = "Unknown";

	/* find motherboard type */
	seq_printf(m, "machine\t\t: ");
135
	np = of_find_node_by_path("/");
136
	if (np != NULL) {
137
		pp = of_get_property(np, "model", NULL);
138 139 140 141
		if (pp != NULL)
			seq_printf(m, "%s\n", pp);
		else
			seq_printf(m, "PowerMac\n");
142
		pp = of_get_property(np, "compatible", &plen);
143 144 145 146 147 148 149 150 151 152
		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");
		}
153
		of_node_put(np);
154 155 156 157 158 159 160 161
	} 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 */
162 163 164 165
	np = of_find_node_by_name(NULL, "l2-cache");
	if (np == NULL)
		np = of_find_node_by_type(NULL, "cache");
	if (np != NULL) {
166 167 168 169
		const unsigned int *ic =
			of_get_property(np, "i-cache-size", NULL);
		const unsigned int *dc =
			of_get_property(np, "d-cache-size", NULL);
170 171
		seq_printf(m, "L2 cache\t:");
		has_l2cache = 1;
172
		if (of_get_property(np, "cache-unified", NULL) != 0 && dc) {
173 174 175 176 177 178 179 180
			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);
		}
181
		pp = of_get_property(np, "ram-type", NULL);
182 183 184
		if (pp)
			seq_printf(m, " %s", pp);
		seq_printf(m, "\n");
185
		of_node_put(np);
186 187 188 189 190 191 192
	}

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

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

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

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

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

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

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

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

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

240 241 242 243 244
	/*
	 * Turn on the L2 cache.
	 * We assume that we have a PSX memory controller iff
	 * we have an ohare I/O controller.
	 */
245 246 247
	dn = of_find_node_by_name(NULL, "ohare");
	if (dn) {
		of_node_put(dn);
248 249 250 251 252 253 254 255 256 257
		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");
		}
	}
}
258

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

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

288
static void __init pmac_setup_arch(void)
289
{
P
Paul Mackerras 已提交
290
	struct device_node *cpu, *ic;
291
	const int *fp;
292 293 294 295 296 297 298 299 300
	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) {
301
		fp = of_get_property(cpu, "clock-frequency", NULL);
302 303 304 305 306 307 308 309 310 311 312 313 314 315
		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 已提交
316
	/* See if newworld or oldworld */
317
	for (ic = NULL; (ic = of_find_all_nodes(ic)) != NULL; )
318
		if (of_get_property(ic, "interrupt-controller", NULL))
319
			break;
320 321
	if (ic) {
		pmac_newworld = 1;
P
Paul Mackerras 已提交
322
		of_node_put(ic);
323
	}
P
Paul Mackerras 已提交
324

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

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

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

	find_via_cuda();
	find_via_pmu();
339 340
	smu_init();

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

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

#ifdef CONFIG_SMP
	/* Check for Core99 */
356 357 358 359 360 361 362
	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);
363
		smp_ops = &core99_smp_ops;
364
	}
365
#ifdef CONFIG_PPC32
366 367 368 369 370 371 372 373 374 375 376
	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);
377
		smp_ops = &psurge_smp_ops;
378
	}
379
#endif
380
#endif /* CONFIG_SMP */
381 382 383 384 385 386 387

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

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

397 398
static int initializing = 1;

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

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

late_initcall(pmac_late_init);

413 414 415 416 417 418 419
/*
 * 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)
420 421 422 423 424 425 426 427
{
	char *p;

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

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

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

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 471
	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)
{
472 473
	switch (sys_ctrler) {
	case SYS_CTRLER_CUDA:
474
		cuda_restart();
475 476 477 478
		break;
	case SYS_CTRLER_PMU:
		pmu_restart();
		break;
479 480 481
	case SYS_CTRLER_SMU:
		smu_restart();
		break;
482 483 484 485
	default: ;
	}
}

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

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

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

519 520 521 522 523 524 525 526
	/* 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
527
	iommu_init_early_dart();
528 529 530 531
#endif
}

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

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

	if (!machine_is(powermac))
		return 0;

541
	np = of_find_node_by_name(NULL, "valkyrie");
542 543
	if (np)
		of_platform_device_create(np, "valkyrie", NULL);
544
	np = of_find_node_by_name(NULL, "platinum");
545 546 547 548 549 550 551
	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);
	}
552 553 554 555 556

	return 0;
}

device_initcall(pmac_declare_of_platform_devices);
557 558 559 560

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

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

569
#ifdef CONFIG_PPC64
570 571 572 573 574 575
	/*
	 * 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
	 */
576
	alloc_dart_table();
577 578

	hpte_init_native();
579 580
#endif

581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
#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 */

596 597 598 599 600 601 602 603 604 605 606 607 608
#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
609 610
/* Move that to pci.c */
static int pmac_pci_probe_mode(struct pci_bus *bus)
611 612 613 614
{
	struct device_node *node = bus->sysdata;

	/* We need to use normal PCI probing for the AGP bus,
615 616
	 * since the device for the AGP bridge isn't in the tree.
	 */
617 618
	if (bus->self == NULL && (of_device_is_compatible(node, "u3-agp") ||
				  of_device_is_compatible(node, "u4-pcie")))
619 620 621
		return PCI_PROBE_NORMAL;
	return PCI_PROBE_DEVTREE;
}
622 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

#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 */
668

669 670
define_machine(powermac) {
	.name			= "PowerMac",
671 672 673 674 675
	.probe			= pmac_probe,
	.setup_arch		= pmac_setup_arch,
	.init_early		= pmac_init_early,
	.show_cpuinfo		= pmac_show_cpuinfo,
	.init_IRQ		= pmac_pic_init,
676
	.get_irq		= NULL,	/* changed later */
677
	.pci_irq_fixup		= pmac_pci_irq_fixup,
678 679 680 681 682 683 684 685 686
	.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,
687
	.progress		= udbg_progress,
688
#ifdef CONFIG_PPC64
689
	.pci_probe_mode		= pmac_pci_probe_mode,
690
	.power_save		= power4_idle,
691
	.enable_pmcs		= power4_enable_pmcs,
M
Michael Ellerman 已提交
692 693 694
#ifdef CONFIG_KEXEC
	.machine_kexec		= default_machine_kexec,
	.machine_kexec_prepare	= default_machine_kexec_prepare,
695
	.machine_crash_shutdown	= default_machine_crash_shutdown,
696
#endif
M
Michael Ellerman 已提交
697
#endif /* CONFIG_PPC64 */
698 699 700 701 702
#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
703
#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64)
704
	.cpu_die		= pmac_cpu_die,
705
#endif
706
};