summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/kernel/time.c2
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c2
-rw-r--r--arch/arm/mach-omap2/timer.c4
-rw-r--r--arch/arm/mach-rockchip/rockchip.c2
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7779.c2
-rw-r--r--arch/arm/mach-shmobile/setup-rcar-gen2.c2
-rw-r--r--arch/arm/mach-spear/spear13xx.c2
-rw-r--r--arch/arm/mach-sunxi/sunxi.c2
-rw-r--r--arch/arm/mach-u300/core.c2
-rw-r--r--arch/arm/mach-ux500/timer.c2
-rw-r--r--arch/arm/mach-zynq/common.c2
-rw-r--r--arch/arm64/include/asm/acpi.h1
-rw-r--r--arch/arm64/include/asm/irq.h13
-rw-r--r--arch/arm64/kernel/acpi.c25
-rw-r--r--arch/arm64/kernel/time.c8
-rw-r--r--arch/ia64/include/asm/pci.h5
-rw-r--r--arch/ia64/pci/pci.c368
-rw-r--r--arch/microblaze/kernel/setup.c2
-rw-r--r--arch/mips/pistachio/time.c2
-rw-r--r--arch/mips/ralink/clk.c2
-rw-r--r--arch/nios2/kernel/time.c2
-rw-r--r--arch/x86/include/asm/msr-index.h7
-rw-r--r--arch/x86/kernel/acpi/boot.c22
-rw-r--r--arch/x86/pci/acpi.c296
-rw-r--r--arch/xtensa/kernel/time.c2
25 files changed, 231 insertions, 548 deletions
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index a66e37e211a9..97b22fa7cb3a 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -120,6 +120,6 @@ void __init time_init(void)
#ifdef CONFIG_COMMON_CLK
of_clk_init(NULL);
#endif
- clocksource_of_init();
+ clocksource_probe();
}
}
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 9602cc12d2f1..3878494bd118 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -350,7 +350,7 @@ static void __init imx6q_opp_init(void)
return;
}
- if (of_init_opp_table(cpu_dev)) {
+ if (dev_pm_opp_of_add_table(cpu_dev)) {
pr_warn("failed to init OPP table\n");
goto put_node;
}
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index a55655127ef2..bef41837bf7f 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -647,7 +647,7 @@ static OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon",
void __init omap4_local_timer_init(void)
{
omap4_sync32k_timer_init();
- clocksource_of_init();
+ clocksource_probe();
}
#else
void __init omap4_local_timer_init(void)
@@ -663,7 +663,7 @@ void __init omap5_realtime_timer_init(void)
omap4_sync32k_timer_init();
realtime_counter_init();
- clocksource_of_init();
+ clocksource_probe();
}
#endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */
diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c
index b6cf3b449428..251c7b9c5f9b 100644
--- a/arch/arm/mach-rockchip/rockchip.c
+++ b/arch/arm/mach-rockchip/rockchip.c
@@ -67,7 +67,7 @@ static void __init rockchip_timer_init(void)
}
of_clk_init(NULL);
- clocksource_of_init();
+ clocksource_probe();
}
static void __init rockchip_dt_init(void)
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index 6bfa6407a27c..1e572a903f8e 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -97,7 +97,7 @@ static u32 __init r8a7779_read_mode_pins(void)
static void __init r8a7779_init_time(void)
{
r8a7779_clocks_init(r8a7779_read_mode_pins());
- clocksource_of_init();
+ clocksource_probe();
}
static const char *const r8a7779_compat_dt[] __initconst = {
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c
index aa3339258d9c..9eccde3c7b13 100644
--- a/arch/arm/mach-shmobile/setup-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c
@@ -128,7 +128,7 @@ void __init rcar_gen2_timer_init(void)
#endif /* CONFIG_ARM_ARCH_TIMER */
rcar_gen2_clocks_init(mode);
- clocksource_of_init();
+ clocksource_probe();
}
struct memory_reserve_config {
diff --git a/arch/arm/mach-spear/spear13xx.c b/arch/arm/mach-spear/spear13xx.c
index b7afce6795f4..ca2f6a82a414 100644
--- a/arch/arm/mach-spear/spear13xx.c
+++ b/arch/arm/mach-spear/spear13xx.c
@@ -124,5 +124,5 @@ void __init spear13xx_timer_init(void)
clk_put(pclk);
spear_setup_of_timer();
- clocksource_of_init();
+ clocksource_probe();
}
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
index 65bab2876343..223c9e99380d 100644
--- a/arch/arm/mach-sunxi/sunxi.c
+++ b/arch/arm/mach-sunxi/sunxi.c
@@ -46,7 +46,7 @@ static void __init sun6i_timer_init(void)
of_clk_init(NULL);
if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
sun6i_reset_init();
- clocksource_of_init();
+ clocksource_probe();
}
DT_MACHINE_START(SUN6I_DT, "Allwinner sun6i (A31) Family")
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index 35670b15f281..546338bbacf8 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -408,7 +408,7 @@ static const char * u300_board_compat[] = {
DT_MACHINE_START(U300_DT, "U300 S335/B335 (Device Tree)")
.map_io = u300_map_io,
.init_irq = u300_init_irq_dt,
- .init_time = clocksource_of_init,
+ .init_time = clocksource_probe,
.init_machine = u300_init_machine_dt,
.restart = u300_restart,
.dt_compat = u300_board_compat,
diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c
index ff28d8ad1ed7..8d2d233f8e6c 100644
--- a/arch/arm/mach-ux500/timer.c
+++ b/arch/arm/mach-ux500/timer.c
@@ -44,5 +44,5 @@ void __init ux500_timer_init(void)
dt_fail:
clksrc_dbx500_prcmu_init(prcmu_timer_base);
- clocksource_of_init();
+ clocksource_probe();
}
diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
index 5a6e4e20ca0a..6f39d03cc27e 100644
--- a/arch/arm/mach-zynq/common.c
+++ b/arch/arm/mach-zynq/common.c
@@ -154,7 +154,7 @@ static void __init zynq_timer_init(void)
zynq_clock_init();
of_clk_init(NULL);
- clocksource_of_init();
+ clocksource_probe();
}
static struct map_desc zynq_cortex_a9_scu_map __initdata = {
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 5f8a38dee274..caafd63b8092 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -12,7 +12,6 @@
#ifndef _ASM_ACPI_H
#define _ASM_ACPI_H
-#include <linux/irqchip/arm-gic-acpi.h>
#include <linux/mm.h>
#include <linux/psci.h>
diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h
index 09169296c3cc..23eb450b820b 100644
--- a/arch/arm64/include/asm/irq.h
+++ b/arch/arm64/include/asm/irq.h
@@ -1,23 +1,10 @@
#ifndef __ASM_IRQ_H
#define __ASM_IRQ_H
-#include <linux/irqchip/arm-gic-acpi.h>
-
#include <asm-generic/irq.h>
struct pt_regs;
extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
-static inline void acpi_irq_init(void)
-{
- /*
- * Hardcode ACPI IRQ chip initialization to GICv2 for now.
- * Proper irqchip infrastructure will be implemented along with
- * incoming GICv2m|GICv3|ITS bits.
- */
- acpi_gic_init();
-}
-#define acpi_irq_init acpi_irq_init
-
#endif
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 137d537ddceb..d1ce8e2f98b9 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -211,31 +211,6 @@ void __init acpi_boot_table_init(void)
}
}
-void __init acpi_gic_init(void)
-{
- struct acpi_table_header *table;
- acpi_status status;
- acpi_size tbl_size;
- int err;
-
- if (acpi_disabled)
- return;
-
- status = acpi_get_table_with_size(ACPI_SIG_MADT, 0, &table, &tbl_size);
- if (ACPI_FAILURE(status)) {
- const char *msg = acpi_format_exception(status);
-
- pr_err("Failed to get MADT table, %s\n", msg);
- return;
- }
-
- err = gic_v2_acpi_init(table);
- if (err)
- pr_err("Failed to initialize GIC IRQ controller");
-
- early_acpi_os_unmap_memory((char *)table, tbl_size);
-}
-
#ifdef CONFIG_ACPI_APEI
pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr)
{
diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
index 149151fb42bb..13339b6ffc1a 100644
--- a/arch/arm64/kernel/time.c
+++ b/arch/arm64/kernel/time.c
@@ -67,16 +67,10 @@ void __init time_init(void)
u32 arch_timer_rate;
of_clk_init(NULL);
- clocksource_of_init();
+ clocksource_probe();
tick_setup_hrtimer_broadcast();
- /*
- * Since ACPI or FDT will only one be available in the system,
- * we can use acpi_generic_timer_init() here safely
- */
- acpi_generic_timer_init();
-
arch_timer_rate = arch_timer_get_rate();
if (!arch_timer_rate)
panic("Unable to initialise architected timer.\n");
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index 36d2c1e3928b..07039d168f37 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -64,11 +64,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
#define pci_legacy_read platform_pci_legacy_read
#define pci_legacy_write platform_pci_legacy_write
-struct iospace_resource {
- struct list_head list;
- struct resource res;
-};
-
struct pci_controller {
struct acpi_device *companion;
void *iommu;
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 7cc3be9fa7c6..8f6ac2f8ae4c 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -115,33 +115,13 @@ struct pci_ops pci_root_ops = {
.write = pci_write,
};
-/* Called by ACPI when it finds a new root bus. */
-
-static struct pci_controller *alloc_pci_controller(int seg)
-{
- struct pci_controller *controller;
-
- controller = kzalloc(sizeof(*controller), GFP_KERNEL);
- if (!controller)
- return NULL;
-
- controller->segment = seg;
- return controller;
-}
-
struct pci_root_info {
- struct acpi_device *bridge;
- struct pci_controller *controller;
- struct list_head resources;
- struct resource *res;
- resource_size_t *res_offset;
- unsigned int res_num;
+ struct acpi_pci_root_info common;
+ struct pci_controller controller;
struct list_head io_resources;
- char *name;
};
-static unsigned int
-new_space (u64 phys_base, int sparse)
+static unsigned int new_space(u64 phys_base, int sparse)
{
u64 mmio_base;
int i;
@@ -168,39 +148,36 @@ new_space (u64 phys_base, int sparse)
return i;
}
-static u64 add_io_space(struct pci_root_info *info,
- struct acpi_resource_address64 *addr)
+static int add_io_space(struct device *dev, struct pci_root_info *info,
+ struct resource_entry *entry)
{
- struct iospace_resource *iospace;
- struct resource *resource;
+ struct resource_entry *iospace;
+ struct resource *resource, *res = entry->res;
char *name;
unsigned long base, min, max, base_port;
unsigned int sparse = 0, space_nr, len;
- len = strlen(info->name) + 32;
- iospace = kzalloc(sizeof(*iospace) + len, GFP_KERNEL);
+ len = strlen(info->common.name) + 32;
+ iospace = resource_list_create_entry(NULL, len);
if (!iospace) {
- dev_err(&info->bridge->dev,
- "PCI: No memory for %s I/O port space\n",
- info->name);
- goto out;
+ dev_err(dev, "PCI: No memory for %s I/O port space\n",
+ info->common.name);
+ return -ENOMEM;
}
- name = (char *)(iospace + 1);
-
- min = addr->address.minimum;
- max = min + addr->address.address_length - 1;
- if (addr->info.io.translation_type == ACPI_SPARSE_TRANSLATION)
+ if (res->flags & IORESOURCE_IO_SPARSE)
sparse = 1;
-
- space_nr = new_space(addr->address.translation_offset, sparse);
+ space_nr = new_space(entry->offset, sparse);
if (space_nr == ~0)
goto free_resource;
+ name = (char *)(iospace + 1);
+ min = res->start - entry->offset;
+ max = res->end - entry->offset;
base = __pa(io_space[space_nr].mmio_base);
base_port = IO_SPACE_BASE(space_nr);
- snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->name,
- base_port + min, base_port + max);
+ snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->common.name,
+ base_port + min, base_port + max);
/*
* The SDM guarantees the legacy 0-64K space is sparse, but if the
@@ -210,270 +187,125 @@ static u64 add_io_space(struct pci_root_info *info,
if (space_nr == 0)
sparse = 1;
- resource = &iospace->res;
+ resource = iospace->res;
resource->name = name;
resource->flags = IORESOURCE_MEM;
resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min);
resource->end = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max);
if (insert_resource(&iomem_resource, resource)) {
- dev_err(&info->bridge->dev,
- "can't allocate host bridge io space resource %pR\n",
- resource);
+ dev_err(dev,
+ "can't allocate host bridge io space resource %pR\n",
+ resource);
goto free_resource;
}
- list_add_tail(&iospace->list, &info->io_resources);
- return base_port;
+ entry->offset = base_port;
+ res->start = min + base_port;
+ res->end = max + base_port;
+ resource_list_add_tail(iospace, &info->io_resources);
-free_resource:
- kfree(iospace);
-out:
- return ~0;
-}
-
-static acpi_status resource_to_window(struct acpi_resource *resource,
- struct acpi_resource_address64 *addr)
-{
- acpi_status status;
+ return 0;
- /*
- * We're only interested in _CRS descriptors that are
- * - address space descriptors for memory or I/O space
- * - non-zero size
- */
- status = acpi_resource_to_address64(resource, addr);
- if (ACPI_SUCCESS(status) &&
- (addr->resource_type == ACPI_MEMORY_RANGE ||
- addr->resource_type == ACPI_IO_RANGE) &&
- addr->address.address_length)
- return AE_OK;
-
- return AE_ERROR;
+free_resource:
+ resource_list_free_entry(iospace);
+ return -ENOSPC;
}
-static acpi_status count_window(struct acpi_resource *resource, void *data)
+/*
+ * An IO port or MMIO resource assigned to a PCI host bridge may be
+ * consumed by the host bridge itself or available to its child
+ * bus/devices. The ACPI specification defines a bit (Producer/Consumer)
+ * to tell whether the resource is consumed by the host bridge itself,
+ * but firmware hasn't used that bit consistently, so we can't rely on it.
+ *
+ * On x86 and IA64 platforms, all IO port and MMIO resources are assumed
+ * to be available to child bus/devices except one special case:
+ * IO port [0xCF8-0xCFF] is consumed by the host bridge itself
+ * to access PCI configuration space.
+ *
+ * So explicitly filter out PCI CFG IO ports[0xCF8-0xCFF].
+ */
+static bool resource_is_pcicfg_ioport(struct resource *res)
{
- unsigned int *windows = (unsigned int *) data;
- struct acpi_resource_address64 addr;
- acpi_status status;
-
- status = resource_to_window(resource, &addr);
- if (ACPI_SUCCESS(status))
- (*windows)++;
-
- return AE_OK;
+ return (res->flags & IORESOURCE_IO) &&
+ res->start == 0xCF8 && res->end == 0xCFF;
}
-static acpi_status add_window(struct acpi_resource *res, void *data)
+static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
{
- struct pci_root_info *info = data;
- struct resource *resource;
- struct acpi_resource_address64 addr;
- acpi_status status;
- unsigned long flags, offset = 0;
- struct resource *root;
-
- /* Return AE_OK for non-window resources to keep scanning for more */
- status = resource_to_window(res, &addr);
- if (!ACPI_SUCCESS(status))
- return AE_OK;
-
- if (addr.resource_type == ACPI_MEMORY_RANGE) {
- flags = IORESOURCE_MEM;
- root = &iomem_resource;
- offset = addr.address.translation_offset;
- } else if (addr.resource_type == ACPI_IO_RANGE) {
- flags = IORESOURCE_IO;
- root = &ioport_resource;
- offset = add_io_space(info, &addr);
- if (offset == ~0)
- return AE_OK;
- } else
- return AE_OK;
-
- resource = &info->res[info->res_num];
- resource->name = info->name;
- resource->flags = flags;
- resource->start = addr.address.minimum + offset;
- resource->end = resource->start + addr.address.address_length - 1;
- info->res_offset[info->res_num] = offset;
-
- if (insert_resource(root, resource)) {
- dev_err(&info->bridge->dev,
- "can't allocate host bridge window %pR\n",
- resource);
- } else {
- if (offset)
- dev_info(&info->bridge->dev, "host bridge window %pR "
- "(PCI address [%#llx-%#llx])\n",
- resource,
- resource->start - offset,
- resource->end - offset);
- else
- dev_info(&info->bridge->dev,
- "host bridge window %pR\n", resource);
+ struct device *dev = &ci->bridge->dev;
+ struct pci_root_info *info;
+ struct resource *res;
+ struct resource_entry *entry, *tmp;
+ int status;
+
+ status = acpi_pci_probe_root_resources(ci);
+ if (status > 0) {
+ info = container_of(ci, struct pci_root_info, common);
+ resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
+ res = entry->res;
+ if (res->flags & IORESOURCE_MEM) {
+ /*
+ * HP's firmware has a hack to work around a
+ * Windows bug. Ignore these tiny memory ranges.
+ */
+ if (resource_size(res) <= 16) {
+ resource_list_del(entry);
+ insert_resource(&iomem_resource,
+ entry->res);
+ resource_list_add_tail(entry,
+ &info->io_resources);
+ }
+ } else if (res->flags & IORESOURCE_IO) {
+ if (resource_is_pcicfg_ioport(entry->res))
+ resource_list_destroy_entry(entry);
+ else if (add_io_space(dev, info, entry))
+ resource_list_destroy_entry(entry);
+ }
+ }
}
- /* HP's firmware has a hack to work around a Windows bug.
- * Ignore these tiny memory ranges */
- if (!((resource->flags & IORESOURCE_MEM) &&
- (resource->end - resource->start < 16)))
- pci_add_resource_offset(&info->resources, resource,
- info->res_offset[info->res_num]);
-
- info->res_num++;
- return AE_OK;
-}
-static void free_pci_root_info_res(struct pci_root_info *info)
-{
- struct iospace_resource *iospace, *tmp;
-
- list_for_each_entry_safe(iospace, tmp, &info->io_resources, list)
- kfree(iospace);
-
- kfree(info->name);
- kfree(info->res);
- info->res = NULL;
- kfree(info->res_offset);
- info->res_offset = NULL;
- info->res_num = 0;
- kfree(info->controller);
- info->controller = NULL;
+ return status;
}
-static void __release_pci_root_info(struct pci_root_info *info)
+static void pci_acpi_root_release_info(struct acpi_pci_root_info *ci)
{
- int i;
- struct resource *res;
- struct iospace_resource *iospace;
+ struct pci_root_info *info;
+ struct resource_entry *entry, *tmp;
- list_for_each_entry(iospace, &info->io_resources, list)
- release_resource(&iospace->res);
-
- for (i = 0; i < info->res_num; i++) {
- res = &info->res[i];
-
- if (!res->parent)
- continue;
-
- if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
- continue;
-
- release_resource(res);
+ info = container_of(ci, struct pci_root_info, common);
+ resource_list_for_each_entry_safe(entry, tmp, &info->io_resources) {
+ release_resource(entry->res);
+ resource_list_destroy_entry(entry);
}
-
- free_pci_root_info_res(info);
kfree(info);
}
-static void release_pci_root_info(struct pci_host_bridge *bridge)
-{
- struct pci_root_info *info = bridge->release_data;
-
- __release_pci_root_info(info);
-}
-
-static int
-probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device,
- int busnum, int domain)
-{
- char *name;
-
- name = kmalloc(16, GFP_KERNEL);
- if (!name)
- return -ENOMEM;
-
- sprintf(name, "PCI Bus %04x:%02x", domain, busnum);
- info->bridge = device;
- info->name = name;
-
- acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
- &info->res_num);
- if (info->res_num) {
- info->res =
- kzalloc_node(sizeof(*info->res) * info->res_num,
- GFP_KERNEL, info->controller->node);
- if (!info->res) {
- kfree(name);
- return -ENOMEM;
- }
-
- info->res_offset =
- kzalloc_node(sizeof(*info->res_offset) * info->res_num,
- GFP_KERNEL, info->controller->node);
- if (!info->res_offset) {
- kfree(name);
- kfree(info->res);
- info->res = NULL;
- return -ENOMEM;
- }
-
- info->res_num = 0;
- acpi_walk_resources(device->handle, METHOD_NAME__CRS,
- add_window, info);
- } else
- kfree(name);
-
- return 0;
-}
+static struct acpi_pci_root_ops pci_acpi_root_ops = {
+ .pci_ops = &pci_root_ops,
+ .release_info = pci_acpi_root_release_info,
+ .prepare_resources = pci_acpi_root_prepare_resources,
+};
struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
{
struct acpi_device *device = root->device;
- int domain = root->segment;
- int bus = root->secondary.start;
- struct pci_controller *controller;
- struct pci_root_info *info = NULL;
- int busnum = root->secondary.start;
- struct pci_bus *pbus;
- int ret;
-
- controller = alloc_pci_controller(domain);
- if (!controller)
- return NULL;
-
- controller->companion = device;
- controller->node = acpi_get_node(device->handle);
+ struct pci_root_info *info;
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
dev_err(&device->dev,
- "pci_bus %04x:%02x: ignored (out of memory)\n",
- domain, busnum);
- kfree(controller);
+ "pci_bus %04x:%02x: ignored (out of memory)\n",
+ root->segment, (int)root->secondary.start);
return NULL;
}
- info->controller = controller;
+ info->controller.segment = root->segment;
+ info->controller.companion = device;
+ info->controller.node = acpi_get_node(device->handle);
INIT_LIST_HEAD(&info->io_resources);
- INIT_LIST_HEAD(&info->resources);
-
- ret = probe_pci_root_info(info, device, busnum, domain);
- if (ret) {
- kfree(info->controller);
- kfree(info);
- return NULL;
- }
- /* insert busn resource at first */
- pci_add_resource(&info->resources, &root->secondary);
- /*
- * See arch/x86/pci/acpi.c.
- * The desired pci bus might already be scanned in a quirk. We
- * should handle the case here, but it appears that IA64 hasn't
- * such quirk. So we just ignore the case now.
- */
- pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, controller,
- &info->resources);
- if (!pbus) {
- pci_free_resource_list(&info->resources);
- __release_pci_root_info(info);
- return NULL;
- }
-
- pci_set_host_bridge_release(to_pci_host_bridge(pbus->bridge),
- release_pci_root_info, info);
- pci_scan_child_bus(pbus);
- return pbus;
+ return acpi_pci_root_create(root, &pci_acpi_root_ops,
+ &info->common, &info->controller);
}
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index ab5b488e1fde..89a2a9394927 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -194,7 +194,7 @@ void __init time_init(void)
{
of_clk_init(NULL);
setup_cpuinfo_clk();
- clocksource_of_init();
+ clocksource_probe();
}
#ifdef CONFIG_DEBUG_FS
diff --git a/arch/mips/pistachio/time.c b/arch/mips/pistachio/time.c
index 8a377346f0ca..1022201b2beb 100644
--- a/arch/mips/pistachio/time.c
+++ b/arch/mips/pistachio/time.c
@@ -39,7 +39,7 @@ void __init plat_time_init(void)
struct clk *clk;
of_clk_init(NULL);
- clocksource_of_init();
+ clocksource_probe();
np = of_get_cpu_node(0, NULL);
if (!np) {
diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c
index feb5a9bf98b4..25c4a61779f1 100644
--- a/arch/mips/ralink/clk.c
+++ b/arch/mips/ralink/clk.c
@@ -75,5 +75,5 @@ void __init plat_time_init(void)
pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
mips_hpt_frequency = clk_get_rate(clk) / 2;
clk_put(clk);
- clocksource_of_init();
+ clocksource_probe();
}
diff --git a/arch/nios2/kernel/time.c b/arch/nios2/kernel/time.c
index bbc3f9157f9c..e835dda2bfe2 100644
--- a/arch/nios2/kernel/time.c
+++ b/arch/nios2/kernel/time.c
@@ -324,7 +324,7 @@ void __init time_init(void)
if (count < 2)
panic("%d timer is found, it needs 2 timers in system\n", count);
- clocksource_of_init();
+ clocksource_probe();
}
CLOCKSOURCE_OF_DECLARE(nios2_timer, ALTR_TIMER_COMPATIBLE, nios2_time_init);
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index b8c14bb7fc8f..9f3905697f12 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -206,6 +206,13 @@
#define MSR_GFX_PERF_LIMIT_REASONS 0x000006B0
#define MSR_RING_PERF_LIMIT_REASONS 0x000006B1
+/* Config TDP MSRs */
+#define MSR_CONFIG_TDP_NOMINAL 0x00000648
+#define MSR_CONFIG_TDP_LEVEL1 0x00000649
+#define MSR_CONFIG_TDP_LEVEL2 0x0000064A
+#define MSR_CONFIG_TDP_CONTROL 0x0000064B
+#define MSR_TURBO_ACTIVATION_RATIO 0x0000064C
+
/* Hardware P state interface */
#define MSR_PPERF 0x0000064e
#define MSR_PERF_LIMIT_REASONS 0x0000064f
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index ded848c20e05..e75907601a41 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -976,6 +976,8 @@ static int __init acpi_parse_madt_lapic_entries(void)
{
int count;
int x2count = 0;
+ int ret;
+ struct acpi_subtable_proc madt_proc[2];
if (!cpu_has_apic)
return -ENODEV;
@@ -999,10 +1001,22 @@ static int __init acpi_parse_madt_lapic_entries(void)
acpi_parse_sapic, MAX_LOCAL_APIC);
if (!count) {
- x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
- acpi_parse_x2apic, MAX_LOCAL_APIC);
- count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
- acpi_parse_lapic, MAX_LOCAL_APIC);
+ memset(madt_proc, 0, sizeof(madt_proc));
+ madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC;
+ madt_proc[0].handler = acpi_parse_lapic;
+ madt_proc[1].id = ACPI_MADT_TYPE_LOCAL_X2APIC;
+ madt_proc[1].handler = acpi_parse_x2apic;
+ ret = acpi_table_parse_entries_array(ACPI_SIG_MADT,
+ sizeof(struct acpi_table_madt),
+ madt_proc, ARRAY_SIZE(madt_proc), MAX_LOCAL_APIC);
+ if (ret < 0) {
+ printk(KERN_ERR PREFIX
+ "Error parsing LAPIC/X2APIC entries\n");
+ return ret;
+ }
+
+ x2count = madt_proc[0].count;
+ count = madt_proc[1].count;
}
if (!count && !x2count) {
printk(KERN_ERR PREFIX "No LAPIC entries present\n");
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index ff9911707160..3cd69832d7f4 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -4,16 +4,15 @@
#include <linux/irq.h>
#include <linux/dmi.h>
#include <linux/slab.h>
+#include <linux/pci-acpi.h>
#include <asm/numa.h>
#include <asm/pci_x86.h>
struct pci_root_info {
- struct acpi_device *bridge;
- char name[16];
+ struct acpi_pci_root_info common;
struct pci_sysdata sd;
#ifdef CONFIG_PCI_MMCONFIG
bool mcfg_added;
- u16 segment;
u8 start_bus;
u8 end_bus;
#endif
@@ -178,15 +177,18 @@ static int check_segment(u16 seg, struct device *dev, char *estr)
return 0;
}
-static int setup_mcfg_map(struct pci_root_info *info, u16 seg, u8 start,
- u8 end, phys_addr_t addr)
+static int setup_mcfg_map(struct acpi_pci_root_info *ci)
{
- int result;
- struct device *dev = &info->bridge->dev;
+ int result, seg;
+ struct pci_root_info *info;
+ struct acpi_pci_root *root = ci->root;
+ struct device *dev = &ci->bridge->dev;
- info->start_bus = start;
- info->end_bus = end;
+ info = container_of(ci, struct pci_root_info, common);
+ info->start_bus = (u8)root->secondary.start;
+ info->end_bus = (u8)root->secondary.end;
info->mcfg_added = false;
+ seg = info->sd.domain;
/* return success if MMCFG is not in use */
if (raw_pci_ext_ops && raw_pci_ext_ops != &pci_mmcfg)
@@ -195,7 +197,8 @@ static int setup_mcfg_map(struct pci_root_info *info, u16 seg, u8 start,
if (!(pci_probe & PCI_PROBE_MMCONF))
return check_segment(seg, dev, "MMCONFIG is disabled,");
- result = pci_mmconfig_insert(dev, seg, start, end, addr);
+ result = pci_mmconfig_insert(dev, seg, info->start_bus, info->end_bus,
+ root->mcfg_addr);
if (result == 0) {
/* enable MMCFG if it hasn't been enabled yet */
if (raw_pci_ext_ops == NULL)
@@ -208,134 +211,55 @@ static int setup_mcfg_map(struct pci_root_info *info, u16 seg, u8 start,
return 0;
}
-static void teardown_mcfg_map(struct pci_root_info *info)
+static void teardown_mcfg_map(struct acpi_pci_root_info *ci)
{
+ struct pci_root_info *info;
+
+ info = container_of(ci, struct pci_root_info, common);
if (info->mcfg_added) {
- pci_mmconfig_delete(info->segment, info->start_bus,
- info->end_bus);
+ pci_mmconfig_delete(info->sd.domain,
+ info->start_bus, info->end_bus);
info->mcfg_added = false;
}
}
#else
-static int setup_mcfg_map(struct pci_root_info *info,
- u16 seg, u8 start, u8 end,
- phys_addr_t addr)
+static int setup_mcfg_map(struct acpi_pci_root_info *ci)
{
return 0;
}
-static void teardown_mcfg_map(struct pci_root_info *info)
+
+static void teardown_mcfg_map(struct acpi_pci_root_info *ci)
{
}
#endif
-static void validate_resources(struct device *dev, struct list_head *crs_res,
- unsigned long type)
+static int pci_acpi_root_get_node(struct acpi_pci_root *root)
{
- LIST_HEAD(list);
- struct resource *res1, *res2, *root = NULL;
- struct resource_entry *tmp, *entry, *entry2;
-
- BUG_ON((type & (IORESOURCE_MEM | IORESOURCE_IO)) == 0);
- root = (type & IORESOURCE_MEM) ? &iomem_resource : &ioport_resource;
-
- list_splice_init(crs_res, &list);
- resource_list_for_each_entry_safe(entry, tmp, &list) {
- bool free = false;
- resource_size_t end;
-
- res1 = entry->res;
- if (!(res1->flags & type))
- goto next;
-
- /* Exclude non-addressable range or non-addressable portion */
- end = min(res1->end, root->end);
- if (end <= res1->start) {
- dev_info(dev, "host bridge window %pR (ignored, not CPU addressable)\n",
- res1);
- free = true;
- goto next;
- } else if (res1->end != end) {
- dev_info(dev, "host bridge window %pR ([%#llx-%#llx] ignored, not CPU addressable)\n",
- res1, (unsigned long long)end + 1,
- (unsigned long long)res1->end);
- res1->end = end;
- }
-
- resource_list_for_each_entry(entry2, crs_res) {
- res2 = entry2->res;
- if (!(res2->flags & type))
- continue;
-
- /*
- * I don't like throwing away windows because then
- * our resources no longer match the ACPI _CRS, but
- * the kernel resource tree doesn't allow overlaps.
- */
- if (resource_overlaps(res1, res2)) {
- res2->start = min(res1->start, res2->start);
- res2->end = max(res1->end, res2->end);
- dev_info(dev, "host bridge window expanded to %pR; %pR ignored\n",
- res2, res1);
- free = true;
- goto next;
- }
- }
+ int busnum = root->secondary.start;
+ struct acpi_device *device = root->device;
+ int node = acpi_get_node(device->handle);
-next:
- resource_list_del(entry);
- if (free)
- resource_list_free_entry(entry);
- else
- resource_list_add_tail(entry, crs_res);
+ if (node == NUMA_NO_NODE) {
+ node = x86_pci_root_bus_node(busnum);
+ if (node != 0 && node != NUMA_NO_NODE)
+ dev_info(&device->dev, FW_BUG "no _PXM; falling back to node %d from hardware (may be inconsistent with ACPI node numbers)\n",
+ node);
}
+ if (node != NUMA_NO_NODE && !node_online(node))
+ node = NUMA_NO_NODE;
+
+ return node;
}
-static void add_resources(struct pci_root_info *info,
- struct list_head *resources,
- struct list_head *crs_res)
+static int pci_acpi_root_init_info(struct acpi_pci_root_info *ci)
{
- struct resource_entry *entry, *tmp;
- struct resource *res, *conflict, *root = NULL;
-
- validate_resources(&info->bridge->dev, crs_res, IORESOURCE_MEM);
- validate_resources(&info->bridge->dev, crs_res, IORESOURCE_IO);
-
- resource_list_for_each_entry_safe(entry, tmp, crs_res) {
- res = entry->res;
- if (res->flags & IORESOURCE_MEM)
- root = &iomem_resource;
- else if (res->flags & IORESOURCE_IO)
- root = &ioport_resource;
- else
- BUG_ON(res);
-
- conflict = insert_resource_conflict(root, res);
- if (conflict) {
- dev_info(&info->bridge->dev,
- "ignoring host bridge window %pR (conflicts with %s %pR)\n",
- res, conflict->name, conflict);
- resource_list_destroy_entry(entry);
- }
- }
-
- list_splice_tail(crs_res, resources);
+ return setup_mcfg_map(ci);
}
-static void release_pci_root_info(struct pci_host_bridge *bridge)
+static void pci_acpi_root_release_info(struct acpi_pci_root_info *ci)
{
- struct resource *res;
- struct resource_entry *entry;
- struct pci_root_info *info = bridge->release_data;
-
- resource_list_for_each_entry(entry, &bridge->windows) {
- res = entry->res;
- if (res->parent &&
- (res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
- release_resource(res);
- }
-
- teardown_mcfg_map(info);
- kfree(info);
+ teardown_mcfg_map(ci);
+ kfree(container_of(ci, struct pci_root_info, common));
}
/*
@@ -358,50 +282,47 @@ static bool resource_is_pcicfg_ioport(struct resource *res)
res->start == 0xCF8 && res->end == 0xCFF;
}
-static void probe_pci_root_info(struct pci_root_info *info,
- struct acpi_device *device,
- int busnum, int domain,
- struct list_head *list)
+static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
{
- int ret;
+ struct acpi_device *device = ci->bridge;
+ int busnum = ci->root->secondary.start;
struct resource_entry *entry, *tmp;
+ int status;
- sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum);
- info->bridge = device;
- ret = acpi_dev_get_resources(device, list,
- acpi_dev_filter_resource_type_cb,
- (void *)(IORESOURCE_IO | IORESOURCE_MEM));
- if (ret < 0)
- dev_warn(&device->dev,
- "failed to parse _CRS method, error code %d\n", ret);
- else if (ret == 0)
- dev_dbg(&device->dev,
- "no IO and memory resources present in _CRS\n");
- else
- resource_list_for_each_entry_safe(entry, tmp, list) {
- if ((entry->res->flags & IORESOURCE_DISABLED) ||
- resource_is_pcicfg_ioport(entry->res))
+ status = acpi_pci_probe_root_resources(ci);
+ if (pci_use_crs) {
+ resource_list_for_each_entry_safe(entry, tmp, &ci->resources)
+ if (resource_is_pcicfg_ioport(entry->res))
resource_list_destroy_entry(entry);
- else
- entry->res->name = info->name;
- }
+ return status;
+ }
+
+ resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
+ dev_printk(KERN_DEBUG, &device->dev,
+ "host bridge window %pR (ignored)\n", entry->res);
+ resource_list_destroy_entry(entry);
+ }
+ x86_pci_root_bus_resources(busnum, &ci->resources);
+
+ return 0;
}
+static struct acpi_pci_root_ops acpi_pci_root_ops = {
+ .pci_ops = &pci_root_ops,
+ .init_info = pci_acpi_root_init_info,
+ .release_info = pci_acpi_root_release_info,
+ .prepare_resources = pci_acpi_root_prepare_resources,
+};
+
struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
{
- struct acpi_device *device = root->device;
- struct pci_root_info *info;
int domain = root->segment;
int busnum = root->secondary.start;
- struct resource_entry *res_entry;
- LIST_HEAD(crs_res);
- LIST_HEAD(resources);
+ int node = pci_acpi_root_get_node(root);
struct pci_bus *bus;
- struct pci_sysdata *sd;
- int node;
if (pci_ignore_seg)
- domain = 0;
+ root->segment = domain = 0;
if (domain && !pci_domains_supported) {
printk(KERN_WARNING "pci_bus %04x:%02x: "
@@ -410,71 +331,33 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
return NULL;
}
- node = acpi_get_node(device->handle);
- if (node == NUMA_NO_NODE) {
- node = x86_pci_root_bus_node(busnum);
- if (node != 0 && node != NUMA_NO_NODE)
- dev_info(&device->dev, FW_BUG "no _PXM; falling back to node %d from hardware (may be inconsistent with ACPI node numbers)\n",
- node);
- }
-
- if (node != NUMA_NO_NODE && !node_online(node))
- node = NUMA_NO_NODE;
-
- info = kzalloc_node(sizeof(*info), GFP_KERNEL, node);
- if (!info) {
- printk(KERN_WARNING "pci_bus %04x:%02x: "
- "ignored (out of memory)\n", domain, busnum);
- return NULL;
- }
-
- sd = &info->sd;
- sd->domain = domain;
- sd->node = node;
- sd->companion = device;
-
bus = pci_find_bus(domain, busnum);
if (bus) {
/*
* If the desired bus has been scanned already, replace
* its bus->sysdata.
*/
- memcpy(bus->sysdata, sd, sizeof(*sd));
- kfree(info);
- } else {
- /* insert busn res at first */
- pci_add_resource(&resources, &root->secondary);
+ struct pci_sysdata sd = {
+ .domain = domain,
+ .node = node,
+ .companion = root->device
+ };
- /*
- * _CRS with no apertures is normal, so only fall back to
- * defaults or native bridge info if we're ignoring _CRS.
- */
- probe_pci_root_info(info, device, busnum, domain, &crs_res);
- if (pci_use_crs) {
- add_resources(info, &resources, &crs_res);
- } else {
- resource_list_for_each_entry(res_entry, &crs_res)
- dev_printk(KERN_DEBUG, &device->dev,
- "host bridge window %pR (ignored)\n",
- res_entry->res);
- resource_list_free(&crs_res);
- x86_pci_root_bus_resources(busnum, &resources);
- }
-
- if (!setup_mcfg_map(info, domain, (u8)root->secondary.start,
- (u8)root->secondary.end, root->mcfg_addr))
- bus = pci_create_root_bus(NULL, busnum, &pci_root_ops,
- sd, &resources);
-
- if (bus) {
- pci_scan_child_bus(bus);
- pci_set_host_bridge_release(
- to_pci_host_bridge(bus->bridge),
- release_pci_root_info, info);
- } else {
- resource_list_free(&resources);
- teardown_mcfg_map(info);
- kfree(info);
+ memcpy(bus->sysdata, &sd, sizeof(sd));
+ } else {
+ struct pci_root_info *info;
+
+ info = kzalloc_node(sizeof(*info), GFP_KERNEL, node);
+ if (!info)
+ dev_err(&root->device->dev,
+ "pci_bus %04x:%02x: ignored (out of memory)\n",
+ domain, busnum);
+ else {
+ info->sd.domain = domain;
+ info->sd.node = node;
+ info->sd.companion = root->device;
+ bus = acpi_pci_root_create(root, &acpi_pci_root_ops,
+ &info->common, &info->sd);
}
}
@@ -487,9 +370,6 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
pcie_bus_configure_settings(child);
}
- if (bus && node != NUMA_NO_NODE)
- dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d\n", node);
-
return bus;
}
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index b97767dbc7c8..b9ad9feadc2d 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -148,7 +148,7 @@ void __init time_init(void)
local_timer_setup(0);
setup_irq(this_cpu_ptr(&ccount_timer)->evt.irq, &timer_irqaction);
sched_clock_register(ccount_sched_clock_read, 32, ccount_freq);
- clocksource_of_init();
+ clocksource_probe();
}
/*