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>
这个提交包含在:
Thomas Gleixner
2011-02-22 18:24:26 +01:00
当前提交 695884fb8a
修改 9156 个文件,包含 581542 行新增278018 行删除

查看文件

@@ -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>");

查看文件

@@ -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;
}