es7000.c 4.1 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * APIC driver for the Unisys ES7000 chipset.
 */
#define APIC_DEFINITION 1
#include <linux/threads.h>
#include <linux/cpumask.h>
#include <asm/mpspec.h>
#include <asm/genapic.h>
#include <asm/fixmap.h>
#include <asm/apicdef.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/init.h>
Y
Yinghai Lu 已提交
14
#include <asm/es7000/apicdef.h>
15
#include <linux/smp.h>
Y
Yinghai Lu 已提交
16 17 18
#include <asm/es7000/apic.h>
#include <asm/es7000/ipi.h>
#include <asm/es7000/mpparse.h>
19 20 21 22
#include <asm/mach-default/mach_wakecpu.h>

void __init es7000_update_genapic_to_cluster(void)
{
I
Ingo Molnar 已提交
23
	apic->target_cpus = target_cpus_cluster;
24 25
	apic->irq_delivery_mode = INT_DELIVERY_MODE_CLUSTER;
	apic->irq_dest_mode = INT_DEST_MODE_CLUSTER;
26

I
Ingo Molnar 已提交
27
	apic->init_apic_ldr = init_apic_ldr_cluster;
28

I
Ingo Molnar 已提交
29
	apic->cpu_mask_to_apicid = cpu_mask_to_apicid_cluster;
30
}
L
Linus Torvalds 已提交
31

32
static int probe_es7000(void)
L
Linus Torvalds 已提交
33 34 35 36 37
{
	/* probed later in mptable/ACPI hooks */
	return 0;
}

38 39 40 41 42 43 44
extern void es7000_sw_apic(void);
static void __init enable_apic_mode(void)
{
	es7000_sw_apic();
	return;
}

45 46
static __init int
mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
47
{
48
	if (mpc->oemptr) {
49
		struct mpc_oemtable *oem_table =
50
			(struct mpc_oemtable *)mpc->oemptr;
51 52 53 54 55 56 57 58
		if (!strncmp(oem, "UNISYS", 6))
			return parse_unisys_oem((char *)oem_table);
	}
	return 0;
}

#ifdef CONFIG_ACPI
/* Hook from generic ACPI tables.c */
59
static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
60
{
61 62 63 64 65 66 67
	unsigned long oem_addr = 0;
	int check_dsdt;
	int ret = 0;

	/* check dsdt at first to avoid clear fix_map for oem_addr */
	check_dsdt = es7000_check_dsdt();

68
	if (!find_unisys_acpi_oem_table(&oem_addr)) {
69 70
		if (check_dsdt)
			ret = parse_unisys_oem((char *)oem_addr);
71 72
		else {
			setup_unisys();
73
			ret = 1;
74
		}
75 76 77 78
		/*
		 * we need to unmap it
		 */
		unmap_unisys_acpi_oem_table(oem_addr);
79
	}
80
	return ret;
81 82
}
#else
83
static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
84 85 86 87 88
{
	return 0;
}
#endif

89
static void vector_allocation_domain(int cpu, cpumask_t *retmask)
90 91 92 93 94 95 96 97 98
{
	/* Careful. Some cpus do not strictly honor the set of cpus
	 * specified in the interrupt destination when using lowest
	 * priority interrupt delivery mode.
	 *
	 * In particular there was a hyperthreading cpu observed to
	 * deliver interrupts to the wrong hyperthread when only one
	 * hyperthread was specified in the interrupt desitination.
	 */
99
	*retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
100 101
}

102 103 104 105
struct genapic apic_es7000 = {

	.name				= "es7000",
	.probe				= probe_es7000,
106
	.acpi_madt_oem_check		= es7000_acpi_madt_oem_check,
107
	.apic_id_registered		= es7000_apic_id_registered,
108

109 110 111
	.irq_delivery_mode		= dest_Fixed,
	/* phys delivery to target CPUs: */
	.irq_dest_mode			= 0,
112

113
	.target_cpus			= es7000_target_cpus,
114
	.disable_esr			= 1,
115
	.dest_logical			= 0,
116 117
	.check_apicid_used		= es7000_check_apicid_used,
	.check_apicid_present		= es7000_check_apicid_present,
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 154 155 156

	.vector_allocation_domain	= vector_allocation_domain,
	.init_apic_ldr			= init_apic_ldr,

	.ioapic_phys_id_map		= ioapic_phys_id_map,
	.setup_apic_routing		= setup_apic_routing,
	.multi_timer_check		= multi_timer_check,
	.apicid_to_node			= apicid_to_node,
	.cpu_to_logical_apicid		= cpu_to_logical_apicid,
	.cpu_present_to_apicid		= cpu_present_to_apicid,
	.apicid_to_cpu_present		= apicid_to_cpu_present,
	.setup_portio_remap		= setup_portio_remap,
	.check_phys_apicid_present	= check_phys_apicid_present,
	.enable_apic_mode		= enable_apic_mode,
	.phys_pkg_id			= phys_pkg_id,
	.mps_oem_check			= mps_oem_check,

	.get_apic_id			= get_apic_id,
	.set_apic_id			= NULL,
	.apic_id_mask			= APIC_ID_MASK,

	.cpu_mask_to_apicid		= cpu_mask_to_apicid,
	.cpu_mask_to_apicid_and		= cpu_mask_to_apicid_and,

	.send_IPI_mask			= send_IPI_mask,
	.send_IPI_mask_allbutself	= NULL,
	.send_IPI_allbutself		= send_IPI_allbutself,
	.send_IPI_all			= send_IPI_all,
	.send_IPI_self			= NULL,

	.wakeup_cpu			= NULL,
	.trampoline_phys_low		= TRAMPOLINE_PHYS_LOW,
	.trampoline_phys_high		= TRAMPOLINE_PHYS_HIGH,
	.wait_for_init_deassert		= wait_for_init_deassert,
	.smp_callin_clear_local_apic	= smp_callin_clear_local_apic,
	.store_NMI_vector		= store_NMI_vector,
	.restore_NMI_vector		= restore_NMI_vector,
	.inquire_remote_apic		= inquire_remote_apic,
};