diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/scan.c | 39 | ||||
-rw-r--r-- | drivers/clocksource/Kconfig | 9 | ||||
-rw-r--r-- | drivers/clocksource/Makefile | 2 | ||||
-rw-r--r-- | drivers/clocksource/arm_arch_timer.c | 10 | ||||
-rw-r--r-- | drivers/clocksource/clksrc-probe.c (renamed from drivers/clocksource/clksrc-of.c) | 6 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic.c | 69 | ||||
-rw-r--r-- | drivers/irqchip/irqchip.c | 5 |
7 files changed, 92 insertions, 48 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index f834b8c6d8d1..daf9fc8329e6 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1913,3 +1913,42 @@ int __init acpi_scan_init(void) mutex_unlock(&acpi_scan_lock); return result; } + +static struct acpi_probe_entry *ape; +static int acpi_probe_count; +static DEFINE_SPINLOCK(acpi_probe_lock); + +static int __init acpi_match_madt(struct acpi_subtable_header *header, + const unsigned long end) +{ + if (!ape->subtable_valid || ape->subtable_valid(header, ape)) + if (!ape->probe_subtbl(header, end)) + acpi_probe_count++; + + return 0; +} + +int __init __acpi_probe_device_table(struct acpi_probe_entry *ap_head, int nr) +{ + int count = 0; + + if (acpi_disabled) + return 0; + + spin_lock(&acpi_probe_lock); + for (ape = ap_head; nr; ape++, nr--) { + if (ACPI_COMPARE_NAME(ACPI_SIG_MADT, ape->id)) { + acpi_probe_count = 0; + acpi_table_parse_madt(ape->type, acpi_match_madt, 0); + count += acpi_probe_count; + } else { + int res; + res = acpi_table_parse(ape->id, ape->probe_table); + if (!res) + count++; + } + } + spin_unlock(&acpi_probe_lock); + + return count; +} diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index a7726db13abb..1a9c5dc1e5f9 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -2,6 +2,14 @@ menu "Clock Source drivers" config CLKSRC_OF bool + select CLKSRC_PROBE + +config CLKSRC_ACPI + bool + select CLKSRC_PROBE + +config CLKSRC_PROBE + bool config CLKSRC_I8253 bool @@ -123,6 +131,7 @@ config CLKSRC_STM32 config ARM_ARCH_TIMER bool select CLKSRC_OF if OF + select CLKSRC_ACPI if ACPI config ARM_ARCH_TIMER_EVTSTREAM bool "Support for ARM architected timer event stream generation" diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 5c00863c3e33..51856d50bccc 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -1,4 +1,4 @@ -obj-$(CONFIG_CLKSRC_OF) += clksrc-of.o +obj-$(CONFIG_CLKSRC_PROBE) += clksrc-probe.o obj-$(CONFIG_ATMEL_PIT) += timer-atmel-pit.o obj-$(CONFIG_ATMEL_ST) += timer-atmel-st.o obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index d6e3e49399dd..c64d543d64bf 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -864,13 +864,5 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table) arch_timer_init(); return 0; } - -/* Initialize all the generic timers presented in GTDT */ -void __init acpi_generic_timer_init(void) -{ - if (acpi_disabled) - return; - - acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init); -} +CLOCKSOURCE_ACPI_DECLARE(arch_timer, ACPI_SIG_GTDT, arch_timer_acpi_init); #endif diff --git a/drivers/clocksource/clksrc-of.c b/drivers/clocksource/clksrc-probe.c index 0093a8e49e14..7cb6c923a836 100644 --- a/drivers/clocksource/clksrc-of.c +++ b/drivers/clocksource/clksrc-probe.c @@ -14,6 +14,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <linux/acpi.h> #include <linux/init.h> #include <linux/of.h> #include <linux/clocksource.h> @@ -23,7 +24,7 @@ extern struct of_device_id __clksrc_of_table[]; static const struct of_device_id __clksrc_of_table_sentinel __used __section(__clksrc_of_table_end); -void __init clocksource_of_init(void) +void __init clocksource_probe(void) { struct device_node *np; const struct of_device_id *match; @@ -38,6 +39,9 @@ void __init clocksource_of_init(void) init_func(np); clocksources++; } + + clocksources += acpi_probe_device_table(clksrc); + if (!clocksources) pr_crit("%s: no matching clocksources found\n", __func__); } diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 982c09c2d791..d4add30d1d46 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -41,7 +41,6 @@ #include <linux/irqchip.h> #include <linux/irqchip/chained_irq.h> #include <linux/irqchip/arm-gic.h> -#include <linux/irqchip/arm-gic-acpi.h> #include <asm/cputype.h> #include <asm/irq.h> @@ -1195,7 +1194,7 @@ IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init); #endif #ifdef CONFIG_ACPI -static phys_addr_t dist_phy_base, cpu_phy_base __initdata; +static phys_addr_t cpu_phy_base __initdata; static int __init gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header, @@ -1223,60 +1222,56 @@ gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header, return 0; } -static int __init -gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header, - const unsigned long end) +/* The things you have to do to just *count* something... */ +static int __init acpi_dummy_func(struct acpi_subtable_header *header, + const unsigned long end) { - struct acpi_madt_generic_distributor *dist; + return 0; +} - dist = (struct acpi_madt_generic_distributor *)header; +static bool __init acpi_gic_redist_is_present(void) +{ + return acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, + acpi_dummy_func, 0) > 0; +} - if (BAD_MADT_ENTRY(dist, end)) - return -EINVAL; +static bool __init gic_validate_dist(struct acpi_subtable_header *header, + struct acpi_probe_entry *ape) +{ + struct acpi_madt_generic_distributor *dist; + dist = (struct acpi_madt_generic_distributor *)header; - dist_phy_base = dist->base_address; - return 0; + return (dist->version == ape->driver_data && + (dist->version != ACPI_MADT_GIC_VERSION_NONE || + !acpi_gic_redist_is_present())); } -int __init -gic_v2_acpi_init(struct acpi_table_header *table) +#define ACPI_GICV2_DIST_MEM_SIZE (SZ_4K) +#define ACPI_GIC_CPU_IF_MEM_SIZE (SZ_8K) + +static int __init gic_v2_acpi_init(struct acpi_subtable_header *header, + const unsigned long end) { + struct acpi_madt_generic_distributor *dist; void __iomem *cpu_base, *dist_base; int count; /* Collect CPU base addresses */ - count = acpi_parse_entries(ACPI_SIG_MADT, - sizeof(struct acpi_table_madt), - gic_acpi_parse_madt_cpu, table, - ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0); + count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, + gic_acpi_parse_madt_cpu, 0); if (count <= 0) { pr_err("No valid GICC entries exist\n"); return -EINVAL; } - /* - * Find distributor base address. We expect one distributor entry since - * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade. - */ - count = acpi_parse_entries(ACPI_SIG_MADT, - sizeof(struct acpi_table_madt), - gic_acpi_parse_madt_distributor, table, - ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0); - if (count <= 0) { - pr_err("No valid GICD entries exist\n"); - return -EINVAL; - } else if (count > 1) { - pr_err("More than one GICD entry detected\n"); - return -EINVAL; - } - cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE); if (!cpu_base) { pr_err("Unable to map GICC registers\n"); return -ENOMEM; } - dist_base = ioremap(dist_phy_base, ACPI_GICV2_DIST_MEM_SIZE); + dist = (struct acpi_madt_generic_distributor *)header; + dist_base = ioremap(dist->base_address, ACPI_GICV2_DIST_MEM_SIZE); if (!dist_base) { pr_err("Unable to map GICD registers\n"); iounmap(cpu_base); @@ -1302,4 +1297,10 @@ gic_v2_acpi_init(struct acpi_table_header *table) acpi_irq_model = ACPI_IRQ_MODEL_GIC; return 0; } +IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, + gic_validate_dist, ACPI_MADT_GIC_VERSION_V2, + gic_v2_acpi_init); +IRQCHIP_ACPI_DECLARE(gic_v2_maybe, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, + gic_validate_dist, ACPI_MADT_GIC_VERSION_NONE, + gic_v2_acpi_init); #endif diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c index afd1af3dfe5a..2b35e68bea82 100644 --- a/drivers/irqchip/irqchip.c +++ b/drivers/irqchip/irqchip.c @@ -8,7 +8,7 @@ * warranty of any kind, whether express or implied. */ -#include <linux/acpi_irq.h> +#include <linux/acpi.h> #include <linux/init.h> #include <linux/of_irq.h> #include <linux/irqchip.h> @@ -27,6 +27,5 @@ extern struct of_device_id __irqchip_of_table[]; void __init irqchip_init(void) { of_irq_init(__irqchip_of_table); - - acpi_irq_init(); + acpi_probe_device_table(irqchip); } |