es7000.c 4.2 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 24 25 26
	apic->target_cpus = target_cpus_cluster;
	apic->int_delivery_mode = INT_DELIVERY_MODE_CLUSTER;
	apic->int_dest_mode = INT_DEST_MODE_CLUSTER;
	apic->no_balance_irq = NO_BALANCE_IRQ_CLUSTER;
27

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

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

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

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

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

#ifdef CONFIG_ACPI
/* Hook from generic ACPI tables.c */
static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
62 63 64 65 66 67 68
	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();

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

90
static void vector_allocation_domain(int cpu, cpumask_t *retmask)
91 92 93 94 95 96 97 98 99
{
	/* 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.
	 */
100
	*retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
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 154 155 156 157 158 159
struct genapic apic_es7000 = {

	.name				= "es7000",
	.probe				= probe_es7000,
	.acpi_madt_oem_check		= acpi_madt_oem_check,
	.apic_id_registered		= apic_id_registered,

	.int_delivery_mode		= INT_DELIVERY_MODE,
	.int_dest_mode			= INT_DEST_MODE,

	.target_cpus			= target_cpus,
	.ESR_DISABLE			= esr_disable,
	.apic_destination_logical	= APIC_DEST_LOGICAL,
	.check_apicid_used		= check_apicid_used,
	.check_apicid_present		= check_apicid_present,

	.no_balance_irq			= NO_BALANCE_IRQ,
	.no_ioapic_check		= 0,

	.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,
};