setup.c 2.8 KB
Newer Older
1 2 3 4 5 6 7 8 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 61 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 90 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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
/*
 * PowerNV setup code.
 *
 * Copyright 2011 IBM Corp.
 *
 * 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.
 */

#undef DEBUG

#include <linux/cpu.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/of.h>
#include <linux/interrupt.h>
#include <linux/bug.h>

#include <asm/machdep.h>
#include <asm/firmware.h>
#include <asm/xics.h>

#include "powernv.h"

static void __init pnv_setup_arch(void)
{
	/* Force console to hvc for now until we have sorted out the
	 * real console situation for the platform. This will make
	 * hvc_udbg work at least.
	 */
	add_preferred_console("hvc", 0, NULL);

	/* Initialize SMP */
	pnv_smp_init();

	/* XXX PCI */

	/* XXX NVRAM */

	/* Enable NAP mode */
	powersave_nap = 1;

	/* XXX PMCS */
}

static void __init pnv_init_early(void)
{
	/* XXX IOMMU */
}

static void __init pnv_init_IRQ(void)
{
	xics_init();

	WARN_ON(!ppc_md.get_irq);
}

static void pnv_show_cpuinfo(struct seq_file *m)
{
	struct device_node *root;
	const char *model = "";

	root = of_find_node_by_path("/");
	if (root)
		model = of_get_property(root, "model", NULL);
	seq_printf(m, "machine\t\t: PowerNV %s\n", model);
	of_node_put(root);
}

static void pnv_restart(char *cmd)
{
	for (;;);
}

static void pnv_power_off(void)
{
	for (;;);
}

static void pnv_halt(void)
{
	for (;;);
}

static unsigned long __init pnv_get_boot_time(void)
{
	return 0;
}

static void pnv_get_rtc_time(struct rtc_time *rtc_tm)
{
}

static int pnv_set_rtc_time(struct rtc_time *tm)
{
	return 0;
}

static void pnv_progress(char *s, unsigned short hex)
{
}

#ifdef CONFIG_KEXEC
static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)
{
	xics_kexec_teardown_cpu(secondary);
}
#endif /* CONFIG_KEXEC */

static int __init pnv_probe(void)
{
	unsigned long root = of_get_flat_dt_root();

	if (!of_flat_dt_is_compatible(root, "ibm,powernv"))
		return 0;

	hpte_init_native();

	pr_debug("PowerNV detected !\n");

	return 1;
}

define_machine(powernv) {
	.name			= "PowerNV",
	.probe			= pnv_probe,
	.setup_arch		= pnv_setup_arch,
	.init_early		= pnv_init_early,
	.init_IRQ		= pnv_init_IRQ,
	.show_cpuinfo		= pnv_show_cpuinfo,
	.restart		= pnv_restart,
	.power_off		= pnv_power_off,
	.halt			= pnv_halt,
	.get_boot_time		= pnv_get_boot_time,
	.get_rtc_time		= pnv_get_rtc_time,
	.set_rtc_time		= pnv_set_rtc_time,
	.progress		= pnv_progress,
	.power_save             = power7_idle,
	.calibrate_decr		= generic_calibrate_decr,
#ifdef CONFIG_KEXEC
	.kexec_cpu_down		= pnv_kexec_cpu_down,
#endif
};