Linux Audio

Check our new training course

Buildroot integration, development and maintenance

Need a Buildroot system for your embedded project?
Loading...
Note: File does not exist in v6.13.7.
  1/*
  2 * Written by: Garry Forsgren, Unisys Corporation
  3 *             Natalie Protasevich, Unisys Corporation
  4 *
  5 * This file contains the code to configure and interface
  6 * with Unisys ES7000 series hardware system manager.
  7 *
  8 * Copyright (c) 2003 Unisys Corporation.
  9 * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar
 10 *
 11 *   All Rights Reserved.
 12 *
 13 * This program is free software; you can redistribute it and/or modify it
 14 * under the terms of version 2 of the GNU General Public License as
 15 * published by the Free Software Foundation.
 16 *
 17 * This program is distributed in the hope that it would be useful, but
 18 * WITHOUT ANY WARRANTY; without even the implied warranty of
 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 20 *
 21 * You should have received a copy of the GNU General Public License along
 22 * with this program; if not, write the Free Software Foundation, Inc., 59
 23 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
 24 *
 25 * Contact information: Unisys Corporation, Township Line & Union Meeting
 26 * Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or:
 27 *
 28 * http://www.unisys.com
 29 */
 30
 31#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 32
 33#include <linux/notifier.h>
 34#include <linux/spinlock.h>
 35#include <linux/cpumask.h>
 36#include <linux/threads.h>
 37#include <linux/kernel.h>
 38#include <linux/module.h>
 39#include <linux/reboot.h>
 40#include <linux/string.h>
 41#include <linux/types.h>
 42#include <linux/errno.h>
 43#include <linux/acpi.h>
 44#include <linux/init.h>
 45#include <linux/gfp.h>
 46#include <linux/nmi.h>
 47#include <linux/smp.h>
 48#include <linux/io.h>
 49
 50#include <asm/apicdef.h>
 51#include <linux/atomic.h>
 52#include <asm/fixmap.h>
 53#include <asm/mpspec.h>
 54#include <asm/setup.h>
 55#include <asm/apic.h>
 56#include <asm/ipi.h>
 57
 58/*
 59 * ES7000 chipsets
 60 */
 61
 62#define NON_UNISYS			0
 63#define ES7000_CLASSIC			1
 64#define ES7000_ZORRO			2
 65
 66#define	MIP_REG				1
 67#define	MIP_PSAI_REG			4
 68
 69#define	MIP_BUSY			1
 70#define	MIP_SPIN			0xf0000
 71#define	MIP_VALID			0x0100000000000000ULL
 72#define	MIP_SW_APIC			0x1020b
 73
 74#define	MIP_PORT(val)			((val >> 32) & 0xffff)
 75
 76#define	MIP_RD_LO(val)			(val & 0xffffffff)
 77
 78struct mip_reg {
 79	unsigned long long		off_0x00;
 80	unsigned long long		off_0x08;
 81	unsigned long long		off_0x10;
 82	unsigned long long		off_0x18;
 83	unsigned long long		off_0x20;
 84	unsigned long long		off_0x28;
 85	unsigned long long		off_0x30;
 86	unsigned long long		off_0x38;
 87};
 88
 89struct mip_reg_info {
 90	unsigned long long		mip_info;
 91	unsigned long long		delivery_info;
 92	unsigned long long		host_reg;
 93	unsigned long long		mip_reg;
 94};
 95
 96struct psai {
 97	unsigned long long		entry_type;
 98	unsigned long long		addr;
 99	unsigned long long		bep_addr;
100};
101
102#ifdef CONFIG_ACPI
103
104struct es7000_oem_table {
105	struct acpi_table_header	Header;
106	u32				OEMTableAddr;
107	u32				OEMTableSize;
108};
109
110static unsigned long			oem_addrX;
111static unsigned long			oem_size;
112
113#endif
114
115/*
116 * ES7000 Globals
117 */
118
119static volatile unsigned long		*psai;
120static struct mip_reg			*mip_reg;
121static struct mip_reg			*host_reg;
122static int 				mip_port;
123static unsigned long			mip_addr;
124static unsigned long			host_addr;
125
126int					es7000_plat;
127
128/*
129 * GSI override for ES7000 platforms.
130 */
131
132
133static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
134{
135	unsigned long vect = 0, psaival = 0;
136
137	if (psai == NULL)
138		return -1;
139
140	vect = ((unsigned long)__pa(eip)/0x1000) << 16;
141	psaival = (0x1000000 | vect | cpu);
142
143	while (*psai & 0x1000000)
144		;
145
146	*psai = psaival;
147
148	return 0;
149}
150
151static int es7000_apic_is_cluster(void)
152{
153	/* MPENTIUMIII */
154	if (boot_cpu_data.x86 == 6 &&
155	    (boot_cpu_data.x86_model >= 7 && boot_cpu_data.x86_model <= 11))
156		return 1;
157
158	return 0;
159}
160
161static void setup_unisys(void)
162{
163	/*
164	 * Determine the generation of the ES7000 currently running.
165	 *
166	 * es7000_plat = 1 if the machine is a 5xx ES7000 box
167	 * es7000_plat = 2 if the machine is a x86_64 ES7000 box
168	 *
169	 */
170	if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2))
171		es7000_plat = ES7000_ZORRO;
172	else
173		es7000_plat = ES7000_CLASSIC;
174}
175
176/*
177 * Parse the OEM Table:
178 */
179static int parse_unisys_oem(char *oemptr)
180{
181	int			i;
182	int 			success = 0;
183	unsigned char		type, size;
184	unsigned long		val;
185	char			*tp = NULL;
186	struct psai		*psaip = NULL;
187	struct mip_reg_info 	*mi;
188	struct mip_reg		*host, *mip;
189
190	tp = oemptr;
191
192	tp += 8;
193
194	for (i = 0; i <= 6; i++) {
195		type = *tp++;
196		size = *tp++;
197		tp -= 2;
198		switch (type) {
199		case MIP_REG:
200			mi = (struct mip_reg_info *)tp;
201			val = MIP_RD_LO(mi->host_reg);
202			host_addr = val;
203			host = (struct mip_reg *)val;
204			host_reg = __va(host);
205			val = MIP_RD_LO(mi->mip_reg);
206			mip_port = MIP_PORT(mi->mip_info);
207			mip_addr = val;
208			mip = (struct mip_reg *)val;
209			mip_reg = __va(mip);
210			pr_debug("host_reg = 0x%lx\n",
211				 (unsigned long)host_reg);
212			pr_debug("mip_reg = 0x%lx\n",
213				 (unsigned long)mip_reg);
214			success++;
215			break;
216		case MIP_PSAI_REG:
217			psaip = (struct psai *)tp;
218			if (tp != NULL) {
219				if (psaip->addr)
220					psai = __va(psaip->addr);
221				else
222					psai = NULL;
223				success++;
224			}
225			break;
226		default:
227			break;
228		}
229		tp += size;
230	}
231
232	if (success < 2)
233		es7000_plat = NON_UNISYS;
234	else
235		setup_unisys();
236
237	return es7000_plat;
238}
239
240#ifdef CONFIG_ACPI
241static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr)
242{
243	struct acpi_table_header *header = NULL;
244	struct es7000_oem_table *table;
245	acpi_size tbl_size;
246	acpi_status ret;
247	int i = 0;
248
249	for (;;) {
250		ret = acpi_get_table_with_size("OEM1", i++, &header, &tbl_size);
251		if (!ACPI_SUCCESS(ret))
252			return -1;
253
254		if (!memcmp((char *) &header->oem_id, "UNISYS", 6))
255			break;
256
257		early_acpi_os_unmap_memory(header, tbl_size);
258	}
259
260	table = (void *)header;
261
262	oem_addrX	= table->OEMTableAddr;
263	oem_size	= table->OEMTableSize;
264
265	early_acpi_os_unmap_memory(header, tbl_size);
266
267	*oem_addr	= (unsigned long)__acpi_map_table(oem_addrX, oem_size);
268
269	return 0;
270}
271
272static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr)
273{
274	if (!oem_addr)
275		return;
276
277	__acpi_unmap_table((char *)oem_addr, oem_size);
278}
279
280static int es7000_check_dsdt(void)
281{
282	struct acpi_table_header header;
283
284	if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) &&
285	    !strncmp(header.oem_id, "UNISYS", 6))
286		return 1;
287	return 0;
288}
289
290static int es7000_acpi_ret;
291
292/* Hook from generic ACPI tables.c */
293static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
294{
295	unsigned long oem_addr = 0;
296	int check_dsdt;
297	int ret = 0;
298
299	/* check dsdt at first to avoid clear fix_map for oem_addr */
300	check_dsdt = es7000_check_dsdt();
301
302	if (!find_unisys_acpi_oem_table(&oem_addr)) {
303		if (check_dsdt) {
304			ret = parse_unisys_oem((char *)oem_addr);
305		} else {
306			setup_unisys();
307			ret = 1;
308		}
309		/*
310		 * we need to unmap it
311		 */
312		unmap_unisys_acpi_oem_table(oem_addr);
313	}
314
315	es7000_acpi_ret = ret;
316
317	return ret && !es7000_apic_is_cluster();
318}
319
320static int es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id)
321{
322	int ret = es7000_acpi_ret;
323
324	return ret && es7000_apic_is_cluster();
325}
326
327#else /* !CONFIG_ACPI: */
328static int es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
329{
330	return 0;
331}
332
333static int es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id)
334{
335	return 0;
336}
337#endif /* !CONFIG_ACPI */
338
339static void es7000_spin(int n)
340{
341	int i = 0;
342
343	while (i++ < n)
344		rep_nop();
345}
346
347static int es7000_mip_write(struct mip_reg *mip_reg)
348{
349	int status = 0;
350	int spin;
351
352	spin = MIP_SPIN;
353	while ((host_reg->off_0x38 & MIP_VALID) != 0) {
354		if (--spin <= 0) {
355			WARN(1,	"Timeout waiting for Host Valid Flag\n");
356			return -1;
357		}
358		es7000_spin(MIP_SPIN);
359	}
360
361	memcpy(host_reg, mip_reg, sizeof(struct mip_reg));
362	outb(1, mip_port);
363
364	spin = MIP_SPIN;
365
366	while ((mip_reg->off_0x38 & MIP_VALID) == 0) {
367		if (--spin <= 0) {
368			WARN(1,	"Timeout waiting for MIP Valid Flag\n");
369			return -1;
370		}
371		es7000_spin(MIP_SPIN);
372	}
373
374	status = (mip_reg->off_0x00 & 0xffff0000000000ULL) >> 48;
375	mip_reg->off_0x38 &= ~MIP_VALID;
376
377	return status;
378}
379
380static void es7000_enable_apic_mode(void)
381{
382	struct mip_reg es7000_mip_reg;
383	int mip_status;
384
385	if (!es7000_plat)
386		return;
387
388	pr_info("Enabling APIC mode.\n");
389	memset(&es7000_mip_reg, 0, sizeof(struct mip_reg));
390	es7000_mip_reg.off_0x00 = MIP_SW_APIC;
391	es7000_mip_reg.off_0x38 = MIP_VALID;
392
393	while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0)
394		WARN(1, "Command failed, status = %x\n", mip_status);
395}
396
397static void es7000_vector_allocation_domain(int cpu, struct cpumask *retmask)
398{
399	/* Careful. Some cpus do not strictly honor the set of cpus
400	 * specified in the interrupt destination when using lowest
401	 * priority interrupt delivery mode.
402	 *
403	 * In particular there was a hyperthreading cpu observed to
404	 * deliver interrupts to the wrong hyperthread when only one
405	 * hyperthread was specified in the interrupt desitination.
406	 */
407	cpumask_clear(retmask);
408	cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
409}
410
411
412static void es7000_wait_for_init_deassert(atomic_t *deassert)
413{
414	while (!atomic_read(deassert))
415		cpu_relax();
416}
417
418static unsigned int es7000_get_apic_id(unsigned long x)
419{
420	return (x >> 24) & 0xFF;
421}
422
423static void es7000_send_IPI_mask(const struct cpumask *mask, int vector)
424{
425	default_send_IPI_mask_sequence_phys(mask, vector);
426}
427
428static void es7000_send_IPI_allbutself(int vector)
429{
430	default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
431}
432
433static void es7000_send_IPI_all(int vector)
434{
435	es7000_send_IPI_mask(cpu_online_mask, vector);
436}
437
438static int es7000_apic_id_registered(void)
439{
440	return 1;
441}
442
443static const struct cpumask *target_cpus_cluster(void)
444{
445	return cpu_all_mask;
446}
447
448static const struct cpumask *es7000_target_cpus(void)
449{
450	return cpumask_of(smp_processor_id());
451}
452
453static unsigned long es7000_check_apicid_used(physid_mask_t *map, int apicid)
454{
455	return 0;
456}
457
458static unsigned long es7000_check_apicid_present(int bit)
459{
460	return physid_isset(bit, phys_cpu_present_map);
461}
462
463static int es7000_early_logical_apicid(int cpu)
464{
465	/* on es7000, logical apicid is the same as physical */
466	return early_per_cpu(x86_bios_cpu_apicid, cpu);
467}
468
469static unsigned long calculate_ldr(int cpu)
470{
471	unsigned long id = per_cpu(x86_bios_cpu_apicid, cpu);
472
473	return SET_APIC_LOGICAL_ID(id);
474}
475
476/*
477 * Set up the logical destination ID.
478 *
479 * Intel recommends to set DFR, LdR and TPR before enabling
480 * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
481 * document number 292116).  So here it goes...
482 */
483static void es7000_init_apic_ldr_cluster(void)
484{
485	unsigned long val;
486	int cpu = smp_processor_id();
487
488	apic_write(APIC_DFR, APIC_DFR_CLUSTER);
489	val = calculate_ldr(cpu);
490	apic_write(APIC_LDR, val);
491}
492
493static void es7000_init_apic_ldr(void)
494{
495	unsigned long val;
496	int cpu = smp_processor_id();
497
498	apic_write(APIC_DFR, APIC_DFR_FLAT);
499	val = calculate_ldr(cpu);
500	apic_write(APIC_LDR, val);
501}
502
503static void es7000_setup_apic_routing(void)
504{
505	int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id());
506
507	pr_info("Enabling APIC mode:  %s. Using %d I/O APICs, target cpus %lx\n",
508		(apic_version[apic] == 0x14) ?
509			"Physical Cluster" : "Logical Cluster",
510		nr_ioapics, cpumask_bits(es7000_target_cpus())[0]);
511}
512
513static int es7000_cpu_present_to_apicid(int mps_cpu)
514{
515	if (!mps_cpu)
516		return boot_cpu_physical_apicid;
517	else if (mps_cpu < nr_cpu_ids)
518		return per_cpu(x86_bios_cpu_apicid, mps_cpu);
519	else
520		return BAD_APICID;
521}
522
523static int cpu_id;
524
525static void es7000_apicid_to_cpu_present(int phys_apicid, physid_mask_t *retmap)
526{
527	physid_set_mask_of_physid(cpu_id, retmap);
528	++cpu_id;
529}
530
531static void es7000_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
532{
533	/* For clustered we don't have a good way to do this yet - hack */
534	physids_promote(0xFFL, retmap);
535}
536
537static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
538{
539	boot_cpu_physical_apicid = read_apic_id();
540	return 1;
541}
542
543static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask)
544{
545	unsigned int round = 0;
546	int cpu, uninitialized_var(apicid);
547
548	/*
549	 * The cpus in the mask must all be on the apic cluster.
550	 */
551	for_each_cpu(cpu, cpumask) {
552		int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
553
554		if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
555			WARN(1, "Not a valid mask!");
556
557			return BAD_APICID;
558		}
559		apicid = new_apicid;
560		round++;
561	}
562	return apicid;
563}
564
565static unsigned int
566es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask,
567			      const struct cpumask *andmask)
568{
569	int apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0);
570	cpumask_var_t cpumask;
571
572	if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
573		return apicid;
574
575	cpumask_and(cpumask, inmask, andmask);
576	cpumask_and(cpumask, cpumask, cpu_online_mask);
577	apicid = es7000_cpu_mask_to_apicid(cpumask);
578
579	free_cpumask_var(cpumask);
580
581	return apicid;
582}
583
584static int es7000_phys_pkg_id(int cpuid_apic, int index_msb)
585{
586	return cpuid_apic >> index_msb;
587}
588
589static int probe_es7000(void)
590{
591	/* probed later in mptable/ACPI hooks */
592	return 0;
593}
594
595static int es7000_mps_ret;
596static int es7000_mps_oem_check(struct mpc_table *mpc, char *oem,
597		char *productid)
598{
599	int ret = 0;
600
601	if (mpc->oemptr) {
602		struct mpc_oemtable *oem_table =
603			(struct mpc_oemtable *)mpc->oemptr;
604
605		if (!strncmp(oem, "UNISYS", 6))
606			ret = parse_unisys_oem((char *)oem_table);
607	}
608
609	es7000_mps_ret = ret;
610
611	return ret && !es7000_apic_is_cluster();
612}
613
614static int es7000_mps_oem_check_cluster(struct mpc_table *mpc, char *oem,
615		char *productid)
616{
617	int ret = es7000_mps_ret;
618
619	return ret && es7000_apic_is_cluster();
620}
621
622/* We've been warned by a false positive warning.Use __refdata to keep calm. */
623static struct apic __refdata apic_es7000_cluster = {
624
625	.name				= "es7000",
626	.probe				= probe_es7000,
627	.acpi_madt_oem_check		= es7000_acpi_madt_oem_check_cluster,
628	.apic_id_registered		= es7000_apic_id_registered,
629
630	.irq_delivery_mode		= dest_LowestPrio,
631	/* logical delivery broadcast to all procs: */
632	.irq_dest_mode			= 1,
633
634	.target_cpus			= target_cpus_cluster,
635	.disable_esr			= 1,
636	.dest_logical			= 0,
637	.check_apicid_used		= es7000_check_apicid_used,
638	.check_apicid_present		= es7000_check_apicid_present,
639
640	.vector_allocation_domain	= es7000_vector_allocation_domain,
641	.init_apic_ldr			= es7000_init_apic_ldr_cluster,
642
643	.ioapic_phys_id_map		= es7000_ioapic_phys_id_map,
644	.setup_apic_routing		= es7000_setup_apic_routing,
645	.multi_timer_check		= NULL,
646	.cpu_present_to_apicid		= es7000_cpu_present_to_apicid,
647	.apicid_to_cpu_present		= es7000_apicid_to_cpu_present,
648	.setup_portio_remap		= NULL,
649	.check_phys_apicid_present	= es7000_check_phys_apicid_present,
650	.enable_apic_mode		= es7000_enable_apic_mode,
651	.phys_pkg_id			= es7000_phys_pkg_id,
652	.mps_oem_check			= es7000_mps_oem_check_cluster,
653
654	.get_apic_id			= es7000_get_apic_id,
655	.set_apic_id			= NULL,
656	.apic_id_mask			= 0xFF << 24,
657
658	.cpu_mask_to_apicid		= es7000_cpu_mask_to_apicid,
659	.cpu_mask_to_apicid_and		= es7000_cpu_mask_to_apicid_and,
660
661	.send_IPI_mask			= es7000_send_IPI_mask,
662	.send_IPI_mask_allbutself	= NULL,
663	.send_IPI_allbutself		= es7000_send_IPI_allbutself,
664	.send_IPI_all			= es7000_send_IPI_all,
665	.send_IPI_self			= default_send_IPI_self,
666
667	.wakeup_secondary_cpu		= wakeup_secondary_cpu_via_mip,
668
669	.trampoline_phys_low		= 0x467,
670	.trampoline_phys_high		= 0x469,
671
672	.wait_for_init_deassert		= NULL,
673
674	/* Nothing to do for most platforms, since cleared by the INIT cycle: */
675	.smp_callin_clear_local_apic	= NULL,
676	.inquire_remote_apic		= default_inquire_remote_apic,
677
678	.read				= native_apic_mem_read,
679	.write				= native_apic_mem_write,
680	.icr_read			= native_apic_icr_read,
681	.icr_write			= native_apic_icr_write,
682	.wait_icr_idle			= native_apic_wait_icr_idle,
683	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
684
685	.x86_32_early_logical_apicid	= es7000_early_logical_apicid,
686};
687
688static struct apic __refdata apic_es7000 = {
689
690	.name				= "es7000",
691	.probe				= probe_es7000,
692	.acpi_madt_oem_check		= es7000_acpi_madt_oem_check,
693	.apic_id_registered		= es7000_apic_id_registered,
694
695	.irq_delivery_mode		= dest_Fixed,
696	/* phys delivery to target CPUs: */
697	.irq_dest_mode			= 0,
698
699	.target_cpus			= es7000_target_cpus,
700	.disable_esr			= 1,
701	.dest_logical			= 0,
702	.check_apicid_used		= es7000_check_apicid_used,
703	.check_apicid_present		= es7000_check_apicid_present,
704
705	.vector_allocation_domain	= es7000_vector_allocation_domain,
706	.init_apic_ldr			= es7000_init_apic_ldr,
707
708	.ioapic_phys_id_map		= es7000_ioapic_phys_id_map,
709	.setup_apic_routing		= es7000_setup_apic_routing,
710	.multi_timer_check		= NULL,
711	.cpu_present_to_apicid		= es7000_cpu_present_to_apicid,
712	.apicid_to_cpu_present		= es7000_apicid_to_cpu_present,
713	.setup_portio_remap		= NULL,
714	.check_phys_apicid_present	= es7000_check_phys_apicid_present,
715	.enable_apic_mode		= es7000_enable_apic_mode,
716	.phys_pkg_id			= es7000_phys_pkg_id,
717	.mps_oem_check			= es7000_mps_oem_check,
718
719	.get_apic_id			= es7000_get_apic_id,
720	.set_apic_id			= NULL,
721	.apic_id_mask			= 0xFF << 24,
722
723	.cpu_mask_to_apicid		= es7000_cpu_mask_to_apicid,
724	.cpu_mask_to_apicid_and		= es7000_cpu_mask_to_apicid_and,
725
726	.send_IPI_mask			= es7000_send_IPI_mask,
727	.send_IPI_mask_allbutself	= NULL,
728	.send_IPI_allbutself		= es7000_send_IPI_allbutself,
729	.send_IPI_all			= es7000_send_IPI_all,
730	.send_IPI_self			= default_send_IPI_self,
731
732	.trampoline_phys_low		= 0x467,
733	.trampoline_phys_high		= 0x469,
734
735	.wait_for_init_deassert		= es7000_wait_for_init_deassert,
736
737	/* Nothing to do for most platforms, since cleared by the INIT cycle: */
738	.smp_callin_clear_local_apic	= NULL,
739	.inquire_remote_apic		= default_inquire_remote_apic,
740
741	.read				= native_apic_mem_read,
742	.write				= native_apic_mem_write,
743	.icr_read			= native_apic_icr_read,
744	.icr_write			= native_apic_icr_write,
745	.wait_icr_idle			= native_apic_wait_icr_idle,
746	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
747
748	.x86_32_early_logical_apicid	= es7000_early_logical_apicid,
749};
750
751/*
752 * Need to check for es7000 followed by es7000_cluster, so this order
753 * in apic_drivers is important.
754 */
755apic_drivers(apic_es7000, apic_es7000_cluster);