On Sat, Oct 12, 2013 at 8:07 PM, Hanjun Guo hanjun.guo@linaro.org wrote:
On 2013年10月09日 19:47, Amit Daniel Kachhap wrote:
This code changes uses GTDT ACPI table to gather IRQ number, frequency etc. Arm timer is registered with the ACPI timer table. GTDT table device name is matched with all the registered timers and matching initialisation function is called.
Signed-off-by: Amit Daniel Kachhap amit.daniel@samsung.com
drivers/clocksource/arm_arch_timer.c | 111 +++++++++++++++++++++++++++++----- drivers/clocksource/clksrc-of.c | 32 ++++++++++ 2 files changed, 128 insertions(+), 15 deletions(-)
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index fbd9ccd..8b747f4 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -25,6 +25,10 @@ #include <clocksource/arm_arch_timer.h> +#ifdef CONFIG_ACPI +#include <linux/acpi.h> +#endif
- #define CNTTIDR 0x08 #define CNTTIDR_VIRT(n) (BIT(1) << ((n) * 4)) @@ -579,20 +583,8 @@ static void __init arch_timer_common_init(void) arch_timer_arch_init(); } -static void __init arch_timer_init(struct device_node *np)
+static void __init arch_timer_init(void) {
int i;
if (arch_timers_present & ARCH_CP15_TIMER) {
pr_warn("arch_timer: multiple nodes in dt, skipping\n");
return;
}
arch_timers_present |= ARCH_CP15_TIMER;
for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
arch_timer_detect_rate(NULL, np);
/* * If HYP mode is available, we know that the physical timer * has been configured to be accessible from PL1. Use it, so
@@ -614,8 +606,97 @@ static void __init arch_timer_init(struct device_node *np) arch_timer_register(); arch_timer_common_init(); } -CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_init); -CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_init);
+static void __init arch_timer_of_init(struct device_node *np) +{
int i;
if (arch_timers_present & ARCH_CP15_TIMER) {
pr_warn("arch_timer: multiple nodes in dt, skipping\n");
return;
}
arch_timers_present |= ARCH_CP15_TIMER;
for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
arch_timer_detect_rate(NULL, np);
arch_timer_init();
+}
+#ifdef CONFIG_ACPI +static void __init arch_timer_acpi_init(void) +{
struct acpi_table_gtdt *gtdt;
int trigger, polarity;
if (arch_timers_present & ARCH_CP15_TIMER) {
pr_warn("arch_timer: multiple nodes in dt, skipping\n");
return;
}
arch_timers_present |= ARCH_CP15_TIMER;
if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_GTDT, 0,
(struct acpi_table_header **)>dt))) {
pr_err("arch_timer: GTDT table not defined\n");
return;
}
/* Read the GTDT table to get the frequency */
if (gtdt->freq)
arch_timer_rate = gtdt->freq;
else
arch_timer_rate = arch_timer_get_cntfrq();
if (gtdt->secure_pl1_interrupt) {
trigger = (gtdt->secure_pl1_flags &
ACPI_GTDT_INTERRUPT_MODE) ?
ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
polarity =
(gtdt->secure_pl1_flags &
ACPI_GTDT_INTERRUPT_POLARITY)
? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
arch_timer_ppi[0] = acpi_register_gsi(NULL,
gtdt->secure_pl1_interrupt, trigger,
polarity);
}
if (gtdt->non_secure_pl1_interrupt) {
trigger =
(gtdt->non_secure_pl1_flags &
ACPI_GTDT_INTERRUPT_MODE)
? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
polarity =
(gtdt->non_secure_pl1_flags &
ACPI_GTDT_INTERRUPT_POLARITY)
? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
arch_timer_ppi[1] = acpi_register_gsi(NULL,
gtdt->non_secure_pl1_interrupt, trigger,
polarity);
}
if (gtdt->virtual_timer_interrupt) {
trigger = (gtdt->virtual_timer_flags &
ACPI_GTDT_INTERRUPT_MODE)
? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
polarity =
(gtdt->virtual_timer_flags & ACPI_GTDT_INTERRUPT_POLARITY)
? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
arch_timer_ppi[2] = acpi_register_gsi(NULL,
gtdt->virtual_timer_interrupt, trigger, polarity);
}
if (gtdt->non_secure_pl2_interrupt) {
trigger =
(gtdt->non_secure_pl2_flags &
ACPI_GTDT_INTERRUPT_MODE)
? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
polarity =
(gtdt->non_secure_pl2_flags &
ACPI_GTDT_INTERRUPT_POLARITY)
? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
arch_timer_ppi[3] = acpi_register_gsi(NULL,
gtdt->non_secure_pl2_interrupt, trigger,
polarity);
}
arch_timer_init();
+} +#else +#define arch_timer_acpi_init NULL +#endif
+CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init); +CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_of_init); +CLOCKSOURCE_ACPI_DECLARE(armv7_arch_timer, "ARMV7", arch_timer_acpi_init); +CLOCKSOURCE_ACPI_DECLARE(armv8_arch_timer, "ARMV8", arch_timer_acpi_init); static void __init arch_timer_mem_init(struct device_node *np) { diff --git a/drivers/clocksource/clksrc-of.c b/drivers/clocksource/clksrc-of.c index 37f5325..8d70903 100644 --- a/drivers/clocksource/clksrc-of.c +++ b/drivers/clocksource/clksrc-of.c @@ -17,12 +17,23 @@ #include <linux/init.h> #include <linux/of.h> #include <linux/clocksource.h> +#ifdef CONFIG_ACPI +#include <linux/acpi.h> +#endif extern struct of_device_id __clksrc_of_table[]; static const struct of_device_id __clksrc_of_table_sentinel __used __section(__clksrc_of_table_end); +#if CONFIG_ACPI +extern struct acpi_device_id __clksrc_acpi_table[];
+static const struct acpi_device_id __clksrc_acpi_table_sentinel
__used __section(__clksrc_acpi_table_end);
+#endif
- void __init clocksource_of_init(void) { struct device_node *np;
@@ -33,4 +44,25 @@ void __init clocksource_of_init(void) init_func = match->data; init_func(np); } +#if CONFIG_ACPI
/* This code section uses the GTDT table TIMER
* id to match the correct clock source device */
struct acpi_table_gtdt *tdt;
const struct acpi_device_id *id;
clocksource_acpi_init_fn acpi_init_func;
if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_GTDT, 0,
(struct acpi_table_header **)&tdt))) {
return;
}
for (id = __clksrc_acpi_table; id->id[0]; id++) {
if (!strncmp((char *) id->id, tdt->id, strlen(id->id))) {
acpi_init_func =
(clocksource_acpi_init_fn)id->driver_data;
acpi_init_func();
break;
}
}
+#endif
This function is *clocksource_of_init*, can we introduce a new function for ACPI only?
Right this function can renamed to something generic.
Thanks Hanjun
}
Linaro-acpi mailing list Linaro-acpi@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-acpi
On Sat, Oct 12, 2013 at 8:07 PM, Hanjun Guo hanjun.guo@linaro.org wrote:
On 2013年10月09日 19:47, Amit Daniel Kachhap wrote:
This code changes uses GTDT ACPI table to gather IRQ number, frequency etc. Arm timer is registered with the ACPI timer table. GTDT table device name is matched with all the registered timers and matching initialisation function is called.
Signed-off-by: Amit Daniel Kachhap amit.daniel@samsung.com
drivers/clocksource/arm_arch_timer.c | 111 +++++++++++++++++++++++++++++----- drivers/clocksource/clksrc-of.c | 32 ++++++++++ 2 files changed, 128 insertions(+), 15 deletions(-)
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index fbd9ccd..8b747f4 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -25,6 +25,10 @@ #include <clocksource/arm_arch_timer.h> +#ifdef CONFIG_ACPI +#include <linux/acpi.h> +#endif
- #define CNTTIDR 0x08 #define CNTTIDR_VIRT(n) (BIT(1) << ((n) * 4)) @@ -579,20 +583,8 @@ static void __init arch_timer_common_init(void) arch_timer_arch_init(); } -static void __init arch_timer_init(struct device_node *np)
+static void __init arch_timer_init(void) {
int i;
if (arch_timers_present & ARCH_CP15_TIMER) {
pr_warn("arch_timer: multiple nodes in dt, skipping\n");
return;
}
arch_timers_present |= ARCH_CP15_TIMER;
for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
arch_timer_detect_rate(NULL, np);
/* * If HYP mode is available, we know that the physical timer * has been configured to be accessible from PL1. Use it, so
@@ -614,8 +606,97 @@ static void __init arch_timer_init(struct device_node *np) arch_timer_register(); arch_timer_common_init(); } -CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_init); -CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_init);
+static void __init arch_timer_of_init(struct device_node *np) +{
int i;
if (arch_timers_present & ARCH_CP15_TIMER) {
pr_warn("arch_timer: multiple nodes in dt, skipping\n");
return;
}
arch_timers_present |= ARCH_CP15_TIMER;
for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
arch_timer_detect_rate(NULL, np);
arch_timer_init();
+}
+#ifdef CONFIG_ACPI +static void __init arch_timer_acpi_init(void) +{
struct acpi_table_gtdt *gtdt;
int trigger, polarity;
if (arch_timers_present & ARCH_CP15_TIMER) {
pr_warn("arch_timer: multiple nodes in dt, skipping\n");
return;
}
arch_timers_present |= ARCH_CP15_TIMER;
if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_GTDT, 0,
(struct acpi_table_header **)>dt))) {
pr_err("arch_timer: GTDT table not defined\n");
return;
}
/* Read the GTDT table to get the frequency */
if (gtdt->freq)
arch_timer_rate = gtdt->freq;
else
arch_timer_rate = arch_timer_get_cntfrq();
if (gtdt->secure_pl1_interrupt) {
trigger = (gtdt->secure_pl1_flags &
ACPI_GTDT_INTERRUPT_MODE) ?
ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
polarity =
(gtdt->secure_pl1_flags &
ACPI_GTDT_INTERRUPT_POLARITY)
? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
arch_timer_ppi[0] = acpi_register_gsi(NULL,
gtdt->secure_pl1_interrupt, trigger,
polarity);
}
if (gtdt->non_secure_pl1_interrupt) {
trigger =
(gtdt->non_secure_pl1_flags &
ACPI_GTDT_INTERRUPT_MODE)
? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
polarity =
(gtdt->non_secure_pl1_flags &
ACPI_GTDT_INTERRUPT_POLARITY)
? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
arch_timer_ppi[1] = acpi_register_gsi(NULL,
gtdt->non_secure_pl1_interrupt, trigger,
polarity);
}
if (gtdt->virtual_timer_interrupt) {
trigger = (gtdt->virtual_timer_flags &
ACPI_GTDT_INTERRUPT_MODE)
? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
polarity =
(gtdt->virtual_timer_flags & ACPI_GTDT_INTERRUPT_POLARITY)
? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
arch_timer_ppi[2] = acpi_register_gsi(NULL,
gtdt->virtual_timer_interrupt, trigger, polarity);
}
if (gtdt->non_secure_pl2_interrupt) {
trigger =
(gtdt->non_secure_pl2_flags &
ACPI_GTDT_INTERRUPT_MODE)
? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
polarity =
(gtdt->non_secure_pl2_flags &
ACPI_GTDT_INTERRUPT_POLARITY)
? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
arch_timer_ppi[3] = acpi_register_gsi(NULL,
gtdt->non_secure_pl2_interrupt, trigger,
polarity);
}
arch_timer_init();
+} +#else +#define arch_timer_acpi_init NULL +#endif
+CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init); +CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_of_init); +CLOCKSOURCE_ACPI_DECLARE(armv7_arch_timer, "ARMV7", arch_timer_acpi_init); +CLOCKSOURCE_ACPI_DECLARE(armv8_arch_timer, "ARMV8", arch_timer_acpi_init); static void __init arch_timer_mem_init(struct device_node *np) { diff --git a/drivers/clocksource/clksrc-of.c b/drivers/clocksource/clksrc-of.c index 37f5325..8d70903 100644 --- a/drivers/clocksource/clksrc-of.c +++ b/drivers/clocksource/clksrc-of.c @@ -17,12 +17,23 @@ #include <linux/init.h> #include <linux/of.h> #include <linux/clocksource.h> +#ifdef CONFIG_ACPI +#include <linux/acpi.h> +#endif extern struct of_device_id __clksrc_of_table[]; static const struct of_device_id __clksrc_of_table_sentinel __used __section(__clksrc_of_table_end); +#if CONFIG_ACPI +extern struct acpi_device_id __clksrc_acpi_table[];
+static const struct acpi_device_id __clksrc_acpi_table_sentinel
__used __section(__clksrc_acpi_table_end);
+#endif
- void __init clocksource_of_init(void) { struct device_node *np;
@@ -33,4 +44,25 @@ void __init clocksource_of_init(void) init_func = match->data; init_func(np); } +#if CONFIG_ACPI
/* This code section uses the GTDT table TIMER
* id to match the correct clock source device */
struct acpi_table_gtdt *tdt;
const struct acpi_device_id *id;
clocksource_acpi_init_fn acpi_init_func;
if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_GTDT, 0,
(struct acpi_table_header **)&tdt))) {
return;
}
for (id = __clksrc_acpi_table; id->id[0]; id++) {
if (!strncmp((char *) id->id, tdt->id, strlen(id->id))) {
acpi_init_func =
(clocksource_acpi_init_fn)id->driver_data;
acpi_init_func();
break;
}
}
+#endif
This function is *clocksource_of_init*, can we introduce a new function for ACPI only?
Thanks Hanjun
}
Linaro-acpi mailing list Linaro-acpi@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-acpi