Merge branch 'devicetree/for-x86' of git://git.secretlab.ca/git/linux-2.6 into x86/platform
Reason: x86 devicetree support for ce4100 depends on those device tree changes scheduled for .39. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
这个提交包含在:
@@ -103,7 +103,7 @@ struct dw_spi_reg {
|
||||
static unsigned long mrst_spi_paddr = MRST_REGBASE_SPI0;
|
||||
|
||||
static u32 *pclk_spi0;
|
||||
/* Always contains an accessable address, start with 0 */
|
||||
/* Always contains an accessible address, start with 0 */
|
||||
static struct dw_spi_reg *pspi;
|
||||
|
||||
static struct kmsg_dumper dw_dumper;
|
||||
|
@@ -72,32 +72,6 @@ struct sfi_rtc_table_entry sfi_mrtc_array[SFI_MRTC_MAX];
|
||||
EXPORT_SYMBOL_GPL(sfi_mrtc_array);
|
||||
int sfi_mrtc_num;
|
||||
|
||||
static inline void assign_to_mp_irq(struct mpc_intsrc *m,
|
||||
struct mpc_intsrc *mp_irq)
|
||||
{
|
||||
memcpy(mp_irq, m, sizeof(struct mpc_intsrc));
|
||||
}
|
||||
|
||||
static inline int mp_irq_cmp(struct mpc_intsrc *mp_irq,
|
||||
struct mpc_intsrc *m)
|
||||
{
|
||||
return memcmp(mp_irq, m, sizeof(struct mpc_intsrc));
|
||||
}
|
||||
|
||||
static void save_mp_irq(struct mpc_intsrc *m)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mp_irq_entries; i++) {
|
||||
if (!mp_irq_cmp(&mp_irqs[i], m))
|
||||
return;
|
||||
}
|
||||
|
||||
assign_to_mp_irq(m, &mp_irqs[mp_irq_entries]);
|
||||
if (++mp_irq_entries == MAX_IRQ_SOURCES)
|
||||
panic("Max # of irq sources exceeded!!\n");
|
||||
}
|
||||
|
||||
/* parse all the mtimer info to a static mtimer array */
|
||||
static int __init sfi_parse_mtmr(struct sfi_table_header *table)
|
||||
{
|
||||
@@ -131,7 +105,7 @@ static int __init sfi_parse_mtmr(struct sfi_table_header *table)
|
||||
mp_irq.srcbusirq = pentry->irq; /* IRQ */
|
||||
mp_irq.dstapic = MP_APIC_ALL;
|
||||
mp_irq.dstirq = pentry->irq;
|
||||
save_mp_irq(&mp_irq);
|
||||
mp_save_irq(&mp_irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -201,7 +175,7 @@ int __init sfi_parse_mrtc(struct sfi_table_header *table)
|
||||
mp_irq.srcbusirq = pentry->irq; /* IRQ */
|
||||
mp_irq.dstapic = MP_APIC_ALL;
|
||||
mp_irq.dstirq = pentry->irq;
|
||||
save_mp_irq(&mp_irq);
|
||||
mp_save_irq(&mp_irq);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,3 +1,4 @@
|
||||
obj-$(CONFIG_OLPC) += olpc.o
|
||||
obj-$(CONFIG_OLPC_XO1) += olpc-xo1.o
|
||||
obj-$(CONFIG_OLPC_OPENFIRMWARE) += olpc_ofw.o
|
||||
obj-$(CONFIG_OLPC_OPENFIRMWARE_DT) += olpc_dt.o
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Support for features of the OLPC XO-1 laptop
|
||||
*
|
||||
* Copyright (C) 2010 Andres Salomon <dilinger@queued.net>
|
||||
* Copyright (C) 2010 One Laptop per Child
|
||||
* Copyright (C) 2006 Red Hat, Inc.
|
||||
* Copyright (C) 2006 Advanced Micro Devices, Inc.
|
||||
@@ -12,8 +13,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci_ids.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm.h>
|
||||
|
||||
@@ -22,9 +21,6 @@
|
||||
|
||||
#define DRV_NAME "olpc-xo1"
|
||||
|
||||
#define PMS_BAR 4
|
||||
#define ACPI_BAR 5
|
||||
|
||||
/* PMC registers (PMS block) */
|
||||
#define PM_SCLK 0x10
|
||||
#define PM_IN_SLPCTL 0x20
|
||||
@@ -57,65 +53,67 @@ static void xo1_power_off(void)
|
||||
outl(0x00002000, acpi_base + PM1_CNT);
|
||||
}
|
||||
|
||||
/* Read the base addresses from the PCI BAR info */
|
||||
static int __devinit setup_bases(struct pci_dev *pdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = pci_enable_device_io(pdev);
|
||||
if (r) {
|
||||
dev_err(&pdev->dev, "can't enable device IO\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
r = pci_request_region(pdev, ACPI_BAR, DRV_NAME);
|
||||
if (r) {
|
||||
dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", ACPI_BAR);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = pci_request_region(pdev, PMS_BAR, DRV_NAME);
|
||||
if (r) {
|
||||
dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", PMS_BAR);
|
||||
pci_release_region(pdev, ACPI_BAR);
|
||||
return r;
|
||||
}
|
||||
|
||||
acpi_base = pci_resource_start(pdev, ACPI_BAR);
|
||||
pms_base = pci_resource_start(pdev, PMS_BAR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit olpc_xo1_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
int r;
|
||||
struct resource *res;
|
||||
|
||||
pcidev = pci_get_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA,
|
||||
NULL);
|
||||
if (!pdev)
|
||||
/* don't run on non-XOs */
|
||||
if (!machine_is_olpc())
|
||||
return -ENODEV;
|
||||
|
||||
r = setup_bases(pcidev);
|
||||
if (r)
|
||||
return r;
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "can't fetch device resource info\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
pm_power_off = xo1_power_off;
|
||||
if (!request_region(res->start, resource_size(res), DRV_NAME)) {
|
||||
dev_err(&pdev->dev, "can't request region\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (strcmp(pdev->name, "cs5535-pms") == 0)
|
||||
pms_base = res->start;
|
||||
else if (strcmp(pdev->name, "cs5535-acpi") == 0)
|
||||
acpi_base = res->start;
|
||||
|
||||
/* If we have both addresses, we can override the poweroff hook */
|
||||
if (pms_base && acpi_base) {
|
||||
pm_power_off = xo1_power_off;
|
||||
printk(KERN_INFO "OLPC XO-1 support registered\n");
|
||||
}
|
||||
|
||||
printk(KERN_INFO "OLPC XO-1 support registered\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devexit olpc_xo1_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *r;
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
release_region(r->start, resource_size(r));
|
||||
|
||||
if (strcmp(pdev->name, "cs5535-pms") == 0)
|
||||
pms_base = 0;
|
||||
else if (strcmp(pdev->name, "cs5535-acpi") == 0)
|
||||
acpi_base = 0;
|
||||
|
||||
pm_power_off = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver olpc_xo1_driver = {
|
||||
static struct platform_driver cs5535_pms_drv = {
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.name = "cs5535-pms",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = olpc_xo1_probe,
|
||||
.remove = __devexit_p(olpc_xo1_remove),
|
||||
};
|
||||
|
||||
static struct platform_driver cs5535_acpi_drv = {
|
||||
.driver = {
|
||||
.name = "cs5535-acpi",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = olpc_xo1_probe,
|
||||
@@ -124,12 +122,23 @@ static struct platform_driver olpc_xo1_driver = {
|
||||
|
||||
static int __init olpc_xo1_init(void)
|
||||
{
|
||||
return platform_driver_register(&olpc_xo1_driver);
|
||||
int r;
|
||||
|
||||
r = platform_driver_register(&cs5535_pms_drv);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = platform_driver_register(&cs5535_acpi_drv);
|
||||
if (r)
|
||||
platform_driver_unregister(&cs5535_pms_drv);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void __exit olpc_xo1_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&olpc_xo1_driver);
|
||||
platform_driver_unregister(&cs5535_acpi_drv);
|
||||
platform_driver_unregister(&cs5535_pms_drv);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>");
|
||||
|
183
arch/x86/platform/olpc/olpc_dt.c
普通文件
183
arch/x86/platform/olpc/olpc_dt.c
普通文件
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* OLPC-specific OFW device tree support code.
|
||||
*
|
||||
* Paul Mackerras August 1996.
|
||||
* Copyright (C) 1996-2005 Paul Mackerras.
|
||||
*
|
||||
* Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
|
||||
* {engebret|bergner}@us.ibm.com
|
||||
*
|
||||
* Adapted for sparc by David S. Miller davem@davemloft.net
|
||||
* Adapted for x86/OLPC by Andres Salomon <dilinger@queued.net>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_pdt.h>
|
||||
#include <asm/olpc_ofw.h>
|
||||
|
||||
static phandle __init olpc_dt_getsibling(phandle node)
|
||||
{
|
||||
const void *args[] = { (void *)node };
|
||||
void *res[] = { &node };
|
||||
|
||||
if ((s32)node == -1)
|
||||
return 0;
|
||||
|
||||
if (olpc_ofw("peer", args, res) || (s32)node == -1)
|
||||
return 0;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static phandle __init olpc_dt_getchild(phandle node)
|
||||
{
|
||||
const void *args[] = { (void *)node };
|
||||
void *res[] = { &node };
|
||||
|
||||
if ((s32)node == -1)
|
||||
return 0;
|
||||
|
||||
if (olpc_ofw("child", args, res) || (s32)node == -1) {
|
||||
pr_err("PROM: %s: fetching child failed!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static int __init olpc_dt_getproplen(phandle node, const char *prop)
|
||||
{
|
||||
const void *args[] = { (void *)node, prop };
|
||||
int len;
|
||||
void *res[] = { &len };
|
||||
|
||||
if ((s32)node == -1)
|
||||
return -1;
|
||||
|
||||
if (olpc_ofw("getproplen", args, res)) {
|
||||
pr_err("PROM: %s: getproplen failed!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int __init olpc_dt_getproperty(phandle node, const char *prop,
|
||||
char *buf, int bufsize)
|
||||
{
|
||||
int plen;
|
||||
|
||||
plen = olpc_dt_getproplen(node, prop);
|
||||
if (plen > bufsize || plen < 1) {
|
||||
return -1;
|
||||
} else {
|
||||
const void *args[] = { (void *)node, prop, buf, (void *)plen };
|
||||
void *res[] = { &plen };
|
||||
|
||||
if (olpc_ofw("getprop", args, res)) {
|
||||
pr_err("PROM: %s: getprop failed!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return plen;
|
||||
}
|
||||
|
||||
static int __init olpc_dt_nextprop(phandle node, char *prev, char *buf)
|
||||
{
|
||||
const void *args[] = { (void *)node, prev, buf };
|
||||
int success;
|
||||
void *res[] = { &success };
|
||||
|
||||
buf[0] = '\0';
|
||||
|
||||
if ((s32)node == -1)
|
||||
return -1;
|
||||
|
||||
if (olpc_ofw("nextprop", args, res) || success != 1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init olpc_dt_pkg2path(phandle node, char *buf,
|
||||
const int buflen, int *len)
|
||||
{
|
||||
const void *args[] = { (void *)node, buf, (void *)buflen };
|
||||
void *res[] = { len };
|
||||
|
||||
if ((s32)node == -1)
|
||||
return -1;
|
||||
|
||||
if (olpc_ofw("package-to-path", args, res) || *len < 1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int prom_early_allocated __initdata;
|
||||
|
||||
void * __init prom_early_alloc(unsigned long size)
|
||||
{
|
||||
static u8 *mem;
|
||||
static size_t free_mem;
|
||||
void *res;
|
||||
|
||||
if (free_mem < size) {
|
||||
const size_t chunk_size = max(PAGE_SIZE, size);
|
||||
|
||||
/*
|
||||
* To mimimize the number of allocations, grab at least
|
||||
* PAGE_SIZE of memory (that's an arbitrary choice that's
|
||||
* fast enough on the platforms we care about while minimizing
|
||||
* wasted bootmem) and hand off chunks of it to callers.
|
||||
*/
|
||||
res = alloc_bootmem(chunk_size);
|
||||
if (!res)
|
||||
return NULL;
|
||||
prom_early_allocated += chunk_size;
|
||||
memset(res, 0, chunk_size);
|
||||
free_mem = chunk_size;
|
||||
mem = res;
|
||||
}
|
||||
|
||||
/* allocate from the local cache */
|
||||
free_mem -= size;
|
||||
res = mem;
|
||||
mem += size;
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct of_pdt_ops prom_olpc_ops __initdata = {
|
||||
.nextprop = olpc_dt_nextprop,
|
||||
.getproplen = olpc_dt_getproplen,
|
||||
.getproperty = olpc_dt_getproperty,
|
||||
.getchild = olpc_dt_getchild,
|
||||
.getsibling = olpc_dt_getsibling,
|
||||
.pkg2path = olpc_dt_pkg2path,
|
||||
};
|
||||
|
||||
void __init olpc_dt_build_devicetree(void)
|
||||
{
|
||||
phandle root;
|
||||
|
||||
if (!olpc_ofw_is_installed())
|
||||
return;
|
||||
|
||||
root = olpc_dt_getsibling(0);
|
||||
if (!root) {
|
||||
pr_err("PROM: unable to get root node from OFW!\n");
|
||||
return;
|
||||
}
|
||||
of_pdt_build_devicetree(root, &prom_olpc_ops);
|
||||
|
||||
pr_info("PROM DT: Built device tree with %u bytes of memory.\n",
|
||||
prom_early_allocated);
|
||||
}
|
@@ -110,3 +110,8 @@ void __init olpc_ofw_detect(void)
|
||||
(unsigned long)olpc_ofw_cif, (-start) >> 20);
|
||||
reserve_top_address(-start);
|
||||
}
|
||||
|
||||
bool __init olpc_ofw_is_installed(void)
|
||||
{
|
||||
return olpc_ofw_cif != NULL;
|
||||
}
|
||||
|
@@ -34,23 +34,12 @@
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
static unsigned long sfi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
|
||||
|
||||
static void __init mp_sfi_register_lapic_address(unsigned long address)
|
||||
{
|
||||
mp_lapic_addr = address;
|
||||
|
||||
set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
|
||||
if (boot_cpu_physical_apicid == -1U)
|
||||
boot_cpu_physical_apicid = read_apic_id();
|
||||
|
||||
pr_info("Boot CPU = %d\n", boot_cpu_physical_apicid);
|
||||
}
|
||||
|
||||
/* All CPUs enumerated by SFI must be present and enabled */
|
||||
static void __cpuinit mp_sfi_register_lapic(u8 id)
|
||||
{
|
||||
if (MAX_APICS - id <= 0) {
|
||||
if (MAX_LOCAL_APIC - id <= 0) {
|
||||
pr_warning("Processor #%d invalid (max %d)\n",
|
||||
id, MAX_APICS);
|
||||
id, MAX_LOCAL_APIC);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -110,7 +99,7 @@ static int __init sfi_parse_ioapic(struct sfi_table_header *table)
|
||||
int __init sfi_platform_init(void)
|
||||
{
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
mp_sfi_register_lapic_address(sfi_lapic_addr);
|
||||
register_lapic_address(sfi_lapic_addr);
|
||||
sfi_table_parse(SFI_SIG_CPUS, NULL, NULL, sfi_parse_cpus);
|
||||
#endif
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
|
@@ -1341,10 +1341,10 @@ uv_activation_descriptor_init(int node, int pnode)
|
||||
|
||||
/*
|
||||
* each bau_desc is 64 bytes; there are 8 (UV_ITEMS_PER_DESCRIPTOR)
|
||||
* per cpu; and up to 32 (UV_ADP_SIZE) cpu's per uvhub
|
||||
* per cpu; and one per cpu on the uvhub (UV_ADP_SIZE)
|
||||
*/
|
||||
bau_desc = (struct bau_desc *)kmalloc_node(sizeof(struct bau_desc)*
|
||||
UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node);
|
||||
bau_desc = kmalloc_node(sizeof(struct bau_desc) * UV_ADP_SIZE
|
||||
* UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node);
|
||||
BUG_ON(!bau_desc);
|
||||
|
||||
pa = uv_gpa(bau_desc); /* need the real nasid*/
|
||||
@@ -1402,9 +1402,9 @@ uv_payload_queue_init(int node, int pnode)
|
||||
struct bau_payload_queue_entry *pqp_malloc;
|
||||
struct bau_control *bcp;
|
||||
|
||||
pqp = (struct bau_payload_queue_entry *) kmalloc_node(
|
||||
(DEST_Q_SIZE + 1) * sizeof(struct bau_payload_queue_entry),
|
||||
GFP_KERNEL, node);
|
||||
pqp = kmalloc_node((DEST_Q_SIZE + 1)
|
||||
* sizeof(struct bau_payload_queue_entry),
|
||||
GFP_KERNEL, node);
|
||||
BUG_ON(!pqp);
|
||||
pqp_malloc = pqp;
|
||||
|
||||
@@ -1455,7 +1455,7 @@ static void __init uv_init_uvhub(int uvhub, int vector)
|
||||
* the below initialization can't be in firmware because the
|
||||
* messaging IRQ will be determined by the OS
|
||||
*/
|
||||
apicid = uvhub_to_first_apicid(uvhub);
|
||||
apicid = uvhub_to_first_apicid(uvhub) | uv_apicid_hibits;
|
||||
uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG,
|
||||
((apicid << 32) | vector));
|
||||
}
|
||||
@@ -1490,7 +1490,7 @@ calculate_destination_timeout(void)
|
||||
/*
|
||||
* initialize the bau_control structure for each cpu
|
||||
*/
|
||||
static void __init uv_init_per_cpu(int nuvhubs)
|
||||
static int __init uv_init_per_cpu(int nuvhubs)
|
||||
{
|
||||
int i;
|
||||
int cpu;
|
||||
@@ -1507,7 +1507,7 @@ static void __init uv_init_per_cpu(int nuvhubs)
|
||||
struct bau_control *smaster = NULL;
|
||||
struct socket_desc {
|
||||
short num_cpus;
|
||||
short cpu_number[16];
|
||||
short cpu_number[MAX_CPUS_PER_SOCKET];
|
||||
};
|
||||
struct uvhub_desc {
|
||||
unsigned short socket_mask;
|
||||
@@ -1520,8 +1520,7 @@ static void __init uv_init_per_cpu(int nuvhubs)
|
||||
|
||||
timeout_us = calculate_destination_timeout();
|
||||
|
||||
uvhub_descs = (struct uvhub_desc *)
|
||||
kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL);
|
||||
uvhub_descs = kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL);
|
||||
memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc));
|
||||
uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL);
|
||||
for_each_present_cpu(cpu) {
|
||||
@@ -1541,6 +1540,10 @@ static void __init uv_init_per_cpu(int nuvhubs)
|
||||
sdp = &bdp->socket[socket];
|
||||
sdp->cpu_number[sdp->num_cpus] = cpu;
|
||||
sdp->num_cpus++;
|
||||
if (sdp->num_cpus > MAX_CPUS_PER_SOCKET) {
|
||||
printk(KERN_EMERG "%d cpus per socket invalid\n", sdp->num_cpus);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (uvhub = 0; uvhub < nuvhubs; uvhub++) {
|
||||
if (!(*(uvhub_mask + (uvhub/8)) & (1 << (uvhub%8))))
|
||||
@@ -1571,6 +1574,12 @@ static void __init uv_init_per_cpu(int nuvhubs)
|
||||
bcp->uvhub_master = hmaster;
|
||||
bcp->uvhub_cpu = uv_cpu_hub_info(cpu)->
|
||||
blade_processor_id;
|
||||
if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) {
|
||||
printk(KERN_EMERG
|
||||
"%d cpus per uvhub invalid\n",
|
||||
bcp->uvhub_cpu);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
nextsocket:
|
||||
socket++;
|
||||
@@ -1596,6 +1605,7 @@ nextsocket:
|
||||
bcp->congested_reps = congested_reps;
|
||||
bcp->congested_period = congested_period;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1626,7 +1636,10 @@ static int __init uv_bau_init(void)
|
||||
spin_lock_init(&disable_lock);
|
||||
congested_cycles = microsec_2_cycles(congested_response_us);
|
||||
|
||||
uv_init_per_cpu(nuvhubs);
|
||||
if (uv_init_per_cpu(nuvhubs)) {
|
||||
nobau = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uv_partition_base_pnode = 0x7fffffff;
|
||||
for (uvhub = 0; uvhub < nuvhubs; uvhub++)
|
||||
|
@@ -89,6 +89,7 @@ static void uv_rtc_send_IPI(int cpu)
|
||||
|
||||
apicid = cpu_physical_id(cpu);
|
||||
pnode = uv_apicid_to_pnode(apicid);
|
||||
apicid |= uv_apicid_hibits;
|
||||
val = (1UL << UVH_IPI_INT_SEND_SHFT) |
|
||||
(apicid << UVH_IPI_INT_APIC_ID_SHFT) |
|
||||
(X86_PLATFORM_IPI_VECTOR << UVH_IPI_INT_VECTOR_SHFT);
|
||||
@@ -107,6 +108,7 @@ static int uv_intr_pending(int pnode)
|
||||
static int uv_setup_intr(int cpu, u64 expires)
|
||||
{
|
||||
u64 val;
|
||||
unsigned long apicid = cpu_physical_id(cpu) | uv_apicid_hibits;
|
||||
int pnode = uv_cpu_to_pnode(cpu);
|
||||
|
||||
uv_write_global_mmr64(pnode, UVH_RTC1_INT_CONFIG,
|
||||
@@ -117,7 +119,7 @@ static int uv_setup_intr(int cpu, u64 expires)
|
||||
UVH_EVENT_OCCURRED0_RTC1_MASK);
|
||||
|
||||
val = (X86_PLATFORM_IPI_VECTOR << UVH_RTC1_INT_CONFIG_VECTOR_SHFT) |
|
||||
((u64)cpu_physical_id(cpu) << UVH_RTC1_INT_CONFIG_APIC_ID_SHFT);
|
||||
((u64)apicid << UVH_RTC1_INT_CONFIG_APIC_ID_SHFT);
|
||||
|
||||
/* Set configuration */
|
||||
uv_write_global_mmr64(pnode, UVH_RTC1_INT_CONFIG, val);
|
||||
|
@@ -171,7 +171,7 @@ static void __init MP_processor_info(struct mpc_cpu *m)
|
||||
ver = m->apicver;
|
||||
if ((ver >= 0x14 && m->apicid >= 0xff) || m->apicid >= 0xf) {
|
||||
printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n",
|
||||
m->apicid, MAX_APICS);
|
||||
m->apicid, MAX_LOCAL_APIC);
|
||||
return;
|
||||
}
|
||||
|
||||
|
在新工单中引用
屏蔽一个用户