From patchwork Mon Feb 6 18:50:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fu Wei Fu X-Patchwork-Id: 93473 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp1834298qgi; Mon, 6 Feb 2017 10:51:17 -0800 (PST) X-Received: by 10.98.90.196 with SMTP id o187mr14698270pfb.30.1486407077187; Mon, 06 Feb 2017 10:51:17 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l127si1466605pga.348.2017.02.06.10.51.16; Mon, 06 Feb 2017 10:51:17 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752309AbdBFSvN (ORCPT + 25 others); Mon, 6 Feb 2017 13:51:13 -0500 Received: from mx1.redhat.com ([209.132.183.28]:56146 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752213AbdBFSvL (ORCPT ); Mon, 6 Feb 2017 13:51:11 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7A1ED3A768B; Mon, 6 Feb 2017 18:51:11 +0000 (UTC) Received: from Rei-Ayanami.localdomain (vpn1-7-227.pek2.redhat.com [10.72.7.227]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v16Ioopb003413; Mon, 6 Feb 2017 13:51:01 -0500 From: fu.wei@linaro.org To: rjw@rjwysocki.net, lenb@kernel.org, daniel.lezcano@linaro.org, tglx@linutronix.de, marc.zyngier@arm.com, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, sudeep.holla@arm.com, hanjun.guo@linaro.org Cc: linux-arm-kernel@lists.infradead.org, linaro-acpi@lists.linaro.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, rruigrok@codeaurora.org, harba@codeaurora.org, cov@codeaurora.org, timur@codeaurora.org, graeme.gregory@linaro.org, al.stone@linaro.org, jcm@redhat.com, wei@redhat.com, arnd@arndb.de, catalin.marinas@arm.com, will.deacon@arm.com, Suravee.Suthikulpanit@amd.com, leo.duran@amd.com, wim@iguana.be, linux@roeck-us.net, linux-watchdog@vger.kernel.org, tn@semihalf.com, christoffer.dall@linaro.org, julien.grall@arm.com, Fu Wei Subject: [PATCH v21 01/13] clocksource: arm_arch_timer: introduce two functions to get the frequency from mmio and sysreg. Date: Tue, 7 Feb 2017 02:50:03 +0800 Message-Id: <20170206185015.12296-2-fu.wei@linaro.org> In-Reply-To: <20170206185015.12296-1-fu.wei@linaro.org> References: <20170206185015.12296-1-fu.wei@linaro.org> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Mon, 06 Feb 2017 18:51:11 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Fu Wei The patch introduce two new functions: arch_timer_get_sysreg_freq and arch_timer_get_mmio_freq, and applys them in arch_timer_detect_rate. These will be used for getting the frequency from mmio and sysreg to prepare for reworking counter frequency detection. Signed-off-by: Fu Wei --- drivers/clocksource/arm_arch_timer.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) -- 2.9.3 diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 46a1709..1d273d6 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -554,6 +554,23 @@ static int arch_timer_starting_cpu(unsigned int cpu) return 0; } +static u32 arch_timer_get_sysreg_freq(void) +{ + /* + * Try to get the frequency from the CNTFRQ of sysreg. + */ + return arch_timer_get_cntfrq(); +} + +static u32 arch_timer_get_mmio_freq(void __iomem *cntbase) +{ + /* + * Try to get the frequency from the CNTFRQ of timer frame registers. + * Note: please verify cntbase in caller. + */ + return readl_relaxed(cntbase + CNTFRQ); +} + static void arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np) { @@ -568,9 +585,9 @@ arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np) if (!acpi_disabled || of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) { if (cntbase) - arch_timer_rate = readl_relaxed(cntbase + CNTFRQ); + arch_timer_rate = arch_timer_get_mmio_freq(cntbase); else - arch_timer_rate = arch_timer_get_cntfrq(); + arch_timer_rate = arch_timer_get_sysreg_freq(); } /* Check the timer frequency. */ From patchwork Mon Feb 6 18:50:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fu Wei Fu X-Patchwork-Id: 93475 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp1834584qgi; Mon, 6 Feb 2017 10:51:59 -0800 (PST) X-Received: by 10.99.217.17 with SMTP id r17mr15145792pgg.140.1486407119823; Mon, 06 Feb 2017 10:51:59 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p12si1475433pgf.304.2017.02.06.10.51.59; Mon, 06 Feb 2017 10:51:59 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752418AbdBFSvd (ORCPT + 25 others); Mon, 6 Feb 2017 13:51:33 -0500 Received: from mx1.redhat.com ([209.132.183.28]:51202 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752377AbdBFSvb (ORCPT ); Mon, 6 Feb 2017 13:51:31 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A96178046B; Mon, 6 Feb 2017 18:51:31 +0000 (UTC) Received: from Rei-Ayanami.localdomain (vpn1-7-227.pek2.redhat.com [10.72.7.227]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v16Ioopd003413; Mon, 6 Feb 2017 13:51:22 -0500 From: fu.wei@linaro.org To: rjw@rjwysocki.net, lenb@kernel.org, daniel.lezcano@linaro.org, tglx@linutronix.de, marc.zyngier@arm.com, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, sudeep.holla@arm.com, hanjun.guo@linaro.org Cc: linux-arm-kernel@lists.infradead.org, linaro-acpi@lists.linaro.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, rruigrok@codeaurora.org, harba@codeaurora.org, cov@codeaurora.org, timur@codeaurora.org, graeme.gregory@linaro.org, al.stone@linaro.org, jcm@redhat.com, wei@redhat.com, arnd@arndb.de, catalin.marinas@arm.com, will.deacon@arm.com, Suravee.Suthikulpanit@amd.com, leo.duran@amd.com, wim@iguana.be, linux@roeck-us.net, linux-watchdog@vger.kernel.org, tn@semihalf.com, christoffer.dall@linaro.org, julien.grall@arm.com, Fu Wei Subject: [PATCH v21 03/13] clocksource: arm_arch_timer: remove arch_timer_detect_rate Date: Tue, 7 Feb 2017 02:50:05 +0800 Message-Id: <20170206185015.12296-4-fu.wei@linaro.org> In-Reply-To: <20170206185015.12296-1-fu.wei@linaro.org> References: <20170206185015.12296-1-fu.wei@linaro.org> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Mon, 06 Feb 2017 18:51:32 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Fu Wei The original counter frequency detection call(arch_timer_detect_rate) include getting the frequency from the per-cpu arch-timer and the memory-mapped (MMIO) timer interfaces. But they will be needed only when the system initializes the relevant timer. This patch remove arch_timer_detect_rate founction, and use the arch_timer_get_sysreg_freq and arch_timer_get_mmio_freq directly. Signed-off-by: Fu Wei --- drivers/clocksource/arm_arch_timer.c | 38 +++++++++++++++--------------------- 1 file changed, 16 insertions(+), 22 deletions(-) -- 2.9.3 diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index aa14305..63fb441 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -571,25 +571,6 @@ static u32 arch_timer_get_mmio_freq(void __iomem *cntbase) return readl_relaxed(cntbase + CNTFRQ); } -static void arch_timer_detect_rate(void __iomem *cntbase) -{ - /* Who has more than one independent system counter? */ - if (arch_timer_rate) - return; - - /* - * Try to determine the frequency from the MMIO timer or the sysreg. - */ - if (cntbase) - arch_timer_rate = arch_timer_get_mmio_freq(cntbase); - else - arch_timer_rate = arch_timer_get_sysreg_freq(); - - /* Check the timer frequency. */ - if (arch_timer_rate == 0) - pr_warn("frequency not available\n"); -} - static void arch_timer_banner(unsigned type) { pr_info("%s%s%s timer(s) running at %lu.%02luMHz (%s%s%s).\n", @@ -970,7 +951,11 @@ static int __init arch_timer_of_init(struct device_node *np) */ if (!arch_timer_rate && of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) - arch_timer_detect_rate(NULL); + arch_timer_rate = arch_timer_get_sysreg_freq(); + if (!arch_timer_rate) { + pr_err(FW_BUG "frequency not available.\n"); + return -EINVAL; + } arch_timer_c3stop = !of_property_read_bool(np, "always-on"); @@ -1087,7 +1072,12 @@ static int __init arch_timer_mem_init(struct device_node *np) */ if (!arch_timer_rate && of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) - arch_timer_detect_rate(base); + arch_timer_rate = arch_timer_get_mmio_freq(base); + if (!arch_timer_rate) { + pr_err(FW_BUG "frequency not available for MMIO timer.\n"); + ret = -EINVAL; + goto out; + } ret = arch_timer_mem_register(base, irq); if (ret) @@ -1150,7 +1140,11 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table) gtdt->non_secure_el2_flags); /* Get the frequency from the sysreg CNTFRQ */ - arch_timer_detect_rate(NULL); + arch_timer_rate = arch_timer_get_sysreg_freq(); + if (!arch_timer_rate) { + pr_err(FW_BUG "frequency not available.\n"); + return -EINVAL; + } arch_timer_uses_ppi = arch_timer_select_ppi(); if (!arch_timer_ppi[arch_timer_uses_ppi]) { From patchwork Mon Feb 6 18:50:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fu Wei Fu X-Patchwork-Id: 93476 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp1834588qgi; Mon, 6 Feb 2017 10:52:00 -0800 (PST) X-Received: by 10.98.14.84 with SMTP id w81mr14868255pfi.168.1486407120166; Mon, 06 Feb 2017 10:52:00 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p12si1475433pgf.304.2017.02.06.10.51.59; Mon, 06 Feb 2017 10:52:00 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752471AbdBFSvo (ORCPT + 25 others); Mon, 6 Feb 2017 13:51:44 -0500 Received: from mx1.redhat.com ([209.132.183.28]:51276 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752424AbdBFSvl (ORCPT ); Mon, 6 Feb 2017 13:51:41 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BC8518046D; Mon, 6 Feb 2017 18:51:41 +0000 (UTC) Received: from Rei-Ayanami.localdomain (vpn1-7-227.pek2.redhat.com [10.72.7.227]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v16Ioope003413; Mon, 6 Feb 2017 13:51:32 -0500 From: fu.wei@linaro.org To: rjw@rjwysocki.net, lenb@kernel.org, daniel.lezcano@linaro.org, tglx@linutronix.de, marc.zyngier@arm.com, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, sudeep.holla@arm.com, hanjun.guo@linaro.org Cc: linux-arm-kernel@lists.infradead.org, linaro-acpi@lists.linaro.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, rruigrok@codeaurora.org, harba@codeaurora.org, cov@codeaurora.org, timur@codeaurora.org, graeme.gregory@linaro.org, al.stone@linaro.org, jcm@redhat.com, wei@redhat.com, arnd@arndb.de, catalin.marinas@arm.com, will.deacon@arm.com, Suravee.Suthikulpanit@amd.com, leo.duran@amd.com, wim@iguana.be, linux@roeck-us.net, linux-watchdog@vger.kernel.org, tn@semihalf.com, christoffer.dall@linaro.org, julien.grall@arm.com, Fu Wei Subject: [PATCH v21 04/13] clocksource: arm_arch_timer: split arch_timer_rate for different types of timer Date: Tue, 7 Feb 2017 02:50:06 +0800 Message-Id: <20170206185015.12296-5-fu.wei@linaro.org> In-Reply-To: <20170206185015.12296-1-fu.wei@linaro.org> References: <20170206185015.12296-1-fu.wei@linaro.org> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Mon, 06 Feb 2017 18:51:42 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Fu Wei Currently, arch_timer_rate is used to store the frequency got from per-cpu arch-timer or the memory-mapped (MMIO) timers. But those values come from different registers which should all be initialized by firmware. This patch remove arch_timer_rate, and use arch_timer_sysreg_freq and arch_timer_mmio_freq instead. Signed-off-by: Fu Wei --- drivers/clocksource/arm_arch_timer.c | 42 ++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 18 deletions(-) -- 2.9.3 diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 63fb441..97a4e90 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -65,7 +65,8 @@ struct arch_timer { #define to_arch_timer(e) container_of(e, struct arch_timer, evt) -static u32 arch_timer_rate; +static u32 arch_timer_sysreg_freq; +static u32 arch_timer_mmio_freq; static int arch_timer_ppi[ARCH_TIMER_MAX_TIMER_PPI]; static struct clock_event_device __percpu *arch_timer_evt; @@ -417,6 +418,7 @@ static void erratum_workaround_set_sne(struct clock_event_device *clk) static void __arch_timer_setup(unsigned type, struct clock_event_device *clk) { + u32 freq; clk->features = CLOCK_EVT_FEAT_ONESHOT; if (type == ARCH_TIMER_TYPE_CP15) { @@ -444,6 +446,7 @@ static void __arch_timer_setup(unsigned type, } erratum_workaround_set_sne(clk); + freq = arch_timer_sysreg_freq; } else { clk->features |= CLOCK_EVT_FEAT_DYNIRQ; clk->name = "arch_mem_timer"; @@ -460,11 +463,12 @@ static void __arch_timer_setup(unsigned type, clk->set_next_event = arch_timer_set_next_event_phys_mem; } + freq = arch_timer_mmio_freq; } clk->set_state_shutdown(clk); - clockevents_config_and_register(clk, arch_timer_rate, 0xf, 0x7fffffff); + clockevents_config_and_register(clk, freq, 0xf, 0x7fffffff); } static void arch_timer_evtstrm_enable(int divider) @@ -487,7 +491,7 @@ static void arch_timer_configure_evtstream(void) int evt_stream_div, pos; /* Find the closest power of two to the divisor */ - evt_stream_div = arch_timer_rate / ARCH_TIMER_EVT_STREAM_FREQ; + evt_stream_div = arch_timer_sysreg_freq / ARCH_TIMER_EVT_STREAM_FREQ; pos = fls(evt_stream_div); if (pos > 1 && !(evt_stream_div & (1 << (pos - 2)))) pos--; @@ -578,8 +582,8 @@ static void arch_timer_banner(unsigned type) type == (ARCH_TIMER_TYPE_CP15 | ARCH_TIMER_TYPE_MEM) ? " and " : "", type & ARCH_TIMER_TYPE_MEM ? "mmio" : "", - (unsigned long)arch_timer_rate / 1000000, - (unsigned long)(arch_timer_rate / 10000) % 100, + (unsigned long)arch_timer_sysreg_freq / 1000000, + (unsigned long)(arch_timer_sysreg_freq / 10000) % 100, type & ARCH_TIMER_TYPE_CP15 ? (arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) ? "virt" : "phys" : "", @@ -591,7 +595,7 @@ static void arch_timer_banner(unsigned type) u32 arch_timer_get_rate(void) { - return arch_timer_rate; + return arch_timer_sysreg_freq; } static u64 arch_counter_get_cntvct_mem(void) @@ -648,6 +652,7 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) static void __init arch_counter_register(unsigned type) { u64 start_count; + u32 freq; /* Register the CP15 based counter if we have one */ if (type & ARCH_TIMER_TYPE_CP15) { @@ -657,6 +662,8 @@ static void __init arch_counter_register(unsigned type) else arch_timer_read_counter = arch_counter_get_cntpct; + freq = arch_timer_sysreg_freq; + clocksource_counter.archdata.vdso_direct = true; #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND @@ -669,19 +676,20 @@ static void __init arch_counter_register(unsigned type) #endif } else { arch_timer_read_counter = arch_counter_get_cntvct_mem; + freq = arch_timer_mmio_freq; } if (!arch_counter_suspend_stop) clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP; start_count = arch_timer_read_counter(); - clocksource_register_hz(&clocksource_counter, arch_timer_rate); + clocksource_register_hz(&clocksource_counter, freq); cyclecounter.mult = clocksource_counter.mult; cyclecounter.shift = clocksource_counter.shift; timecounter_init(&arch_timer_kvm_info.timecounter, &cyclecounter, start_count); /* 56 bits minimum, so we assume worst case rollover */ - sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate); + sched_clock_register(arch_timer_read_counter, 56, freq); } static void arch_timer_stop(struct clock_event_device *clk) @@ -949,10 +957,9 @@ static int __init arch_timer_of_init(struct device_node *np) * Try to determine the frequency from the device tree, * if fail, get the frequency from the sysreg CNTFRQ. */ - if (!arch_timer_rate && - of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) - arch_timer_rate = arch_timer_get_sysreg_freq(); - if (!arch_timer_rate) { + if (of_property_read_u32(np, "clock-frequency", &arch_timer_sysreg_freq)) + arch_timer_sysreg_freq = arch_timer_get_sysreg_freq(); + if (!arch_timer_sysreg_freq) { pr_err(FW_BUG "frequency not available.\n"); return -EINVAL; } @@ -1070,10 +1077,9 @@ static int __init arch_timer_mem_init(struct device_node *np) * Try to determine the frequency from the device tree, * if fail, get the frequency from the CNTFRQ reg of MMIO timer. */ - if (!arch_timer_rate && - of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) - arch_timer_rate = arch_timer_get_mmio_freq(base); - if (!arch_timer_rate) { + if (of_property_read_u32(np, "clock-frequency", &arch_timer_mmio_freq)) + arch_timer_mmio_freq = arch_timer_get_mmio_freq(base); + if (!arch_timer_mmio_freq) { pr_err(FW_BUG "frequency not available for MMIO timer.\n"); ret = -EINVAL; goto out; @@ -1140,8 +1146,8 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table) gtdt->non_secure_el2_flags); /* Get the frequency from the sysreg CNTFRQ */ - arch_timer_rate = arch_timer_get_sysreg_freq(); - if (!arch_timer_rate) { + arch_timer_sysreg_freq = arch_timer_get_sysreg_freq(); + if (!arch_timer_sysreg_freq) { pr_err(FW_BUG "frequency not available.\n"); return -EINVAL; } From patchwork Mon Feb 6 18:50:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fu Wei Fu X-Patchwork-Id: 93478 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp1834636qgi; Mon, 6 Feb 2017 10:52:07 -0800 (PST) X-Received: by 10.98.134.2 with SMTP id x2mr14858592pfd.158.1486407127653; Mon, 06 Feb 2017 10:52:07 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p12si1475433pgf.304.2017.02.06.10.52.07; Mon, 06 Feb 2017 10:52:07 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752529AbdBFSwF (ORCPT + 25 others); Mon, 6 Feb 2017 13:52:05 -0500 Received: from mx1.redhat.com ([209.132.183.28]:33884 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751321AbdBFSwB (ORCPT ); Mon, 6 Feb 2017 13:52:01 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D05A58123A; Mon, 6 Feb 2017 18:51:51 +0000 (UTC) Received: from Rei-Ayanami.localdomain (vpn1-7-227.pek2.redhat.com [10.72.7.227]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v16Ioopf003413; Mon, 6 Feb 2017 13:51:42 -0500 From: fu.wei@linaro.org To: rjw@rjwysocki.net, lenb@kernel.org, daniel.lezcano@linaro.org, tglx@linutronix.de, marc.zyngier@arm.com, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, sudeep.holla@arm.com, hanjun.guo@linaro.org Cc: linux-arm-kernel@lists.infradead.org, linaro-acpi@lists.linaro.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, rruigrok@codeaurora.org, harba@codeaurora.org, cov@codeaurora.org, timur@codeaurora.org, graeme.gregory@linaro.org, al.stone@linaro.org, jcm@redhat.com, wei@redhat.com, arnd@arndb.de, catalin.marinas@arm.com, will.deacon@arm.com, Suravee.Suthikulpanit@amd.com, leo.duran@amd.com, wim@iguana.be, linux@roeck-us.net, linux-watchdog@vger.kernel.org, tn@semihalf.com, christoffer.dall@linaro.org, julien.grall@arm.com, Fu Wei Subject: [PATCH v21 05/13] clocksource: arm_arch_timer: refactor arch_timer_needs_probing Date: Tue, 7 Feb 2017 02:50:07 +0800 Message-Id: <20170206185015.12296-6-fu.wei@linaro.org> In-Reply-To: <20170206185015.12296-1-fu.wei@linaro.org> References: <20170206185015.12296-1-fu.wei@linaro.org> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Mon, 06 Feb 2017 18:51:52 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Fu Wei When system init with device-tree, we don't know which node will be initialized first. And the code in arch_timer_common_init should wait until per-cpu timer and MMIO timer are both initialized. So we need arch_timer_needs_probing to detect the init status of system. But currently the code is dispersed in arch_timer_needs_probing and arch_timer_common_init. And the function name doesn't specify that it's only for device-tree. This is somewhat confusing. This patch move all related code from arch_timer_common_init to arch_timer_needs_probing, refactor it, and rename it to arch_timer_needs_of_probing. And make sure that it will be called only if acpi is disabled. Signed-off-by: Fu Wei Reviewed-by: Hanjun Guo --- drivers/clocksource/arm_arch_timer.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) -- 2.9.3 diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 97a4e90..97ed103 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -858,15 +858,28 @@ static const struct of_device_id arch_timer_mem_of_match[] __initconst = { {}, }; -static bool __init -arch_timer_needs_probing(int type, const struct of_device_id *matches) +static bool __init arch_timer_needs_of_probing(void) { struct device_node *dn; bool needs_probing = false; + unsigned int mask = ARCH_TIMER_TYPE_CP15 | ARCH_TIMER_TYPE_MEM; - dn = of_find_matching_node(NULL, matches); - if (dn && of_device_is_available(dn) && !(arch_timers_present & type)) + /* We have two timers, and both device-tree nodes are probed. */ + if ((arch_timers_present & mask) == mask) + return false; + + /* + * Only one type of timer is probed, + * check if we have another type of timer node in device-tree. + */ + if (arch_timers_present & ARCH_TIMER_TYPE_CP15) + dn = of_find_matching_node(NULL, arch_timer_mem_of_match); + else + dn = of_find_matching_node(NULL, arch_timer_of_match); + + if (dn && of_device_is_available(dn)) needs_probing = true; + of_node_put(dn); return needs_probing; @@ -874,17 +887,8 @@ arch_timer_needs_probing(int type, const struct of_device_id *matches) static int __init arch_timer_common_init(void) { - unsigned mask = ARCH_TIMER_TYPE_CP15 | ARCH_TIMER_TYPE_MEM; - - /* Wait until both nodes are probed if we have two timers */ - if ((arch_timers_present & mask) != mask) { - if (arch_timer_needs_probing(ARCH_TIMER_TYPE_MEM, - arch_timer_mem_of_match)) - return 0; - if (arch_timer_needs_probing(ARCH_TIMER_TYPE_CP15, - arch_timer_of_match)) - return 0; - } + if (acpi_disabled && arch_timer_needs_of_probing()) + return 0; arch_timer_banner(arch_timers_present); arch_counter_register(arch_timers_present); From patchwork Mon Feb 6 18:50:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fu Wei Fu X-Patchwork-Id: 93477 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp1834627qgi; Mon, 6 Feb 2017 10:52:06 -0800 (PST) X-Received: by 10.99.100.70 with SMTP id y67mr14822404pgb.74.1486407126334; Mon, 06 Feb 2017 10:52:06 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p12si1475433pgf.304.2017.02.06.10.52.05; Mon, 06 Feb 2017 10:52:06 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752102AbdBFSwE (ORCPT + 25 others); Mon, 6 Feb 2017 13:52:04 -0500 Received: from mx1.redhat.com ([209.132.183.28]:56578 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751716AbdBFSwB (ORCPT ); Mon, 6 Feb 2017 13:52:01 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D76044DB14; Mon, 6 Feb 2017 18:52:01 +0000 (UTC) Received: from Rei-Ayanami.localdomain (vpn1-7-227.pek2.redhat.com [10.72.7.227]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v16Ioopg003413; Mon, 6 Feb 2017 13:51:52 -0500 From: fu.wei@linaro.org To: rjw@rjwysocki.net, lenb@kernel.org, daniel.lezcano@linaro.org, tglx@linutronix.de, marc.zyngier@arm.com, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, sudeep.holla@arm.com, hanjun.guo@linaro.org Cc: linux-arm-kernel@lists.infradead.org, linaro-acpi@lists.linaro.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, rruigrok@codeaurora.org, harba@codeaurora.org, cov@codeaurora.org, timur@codeaurora.org, graeme.gregory@linaro.org, al.stone@linaro.org, jcm@redhat.com, wei@redhat.com, arnd@arndb.de, catalin.marinas@arm.com, will.deacon@arm.com, Suravee.Suthikulpanit@amd.com, leo.duran@amd.com, wim@iguana.be, linux@roeck-us.net, linux-watchdog@vger.kernel.org, tn@semihalf.com, christoffer.dall@linaro.org, julien.grall@arm.com, Fu Wei Subject: [PATCH v21 06/13] clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call Date: Tue, 7 Feb 2017 02:50:08 +0800 Message-Id: <20170206185015.12296-7-fu.wei@linaro.org> In-Reply-To: <20170206185015.12296-1-fu.wei@linaro.org> References: <20170206185015.12296-1-fu.wei@linaro.org> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Mon, 06 Feb 2017 18:52:02 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Fu Wei Because arch_timer_needs_of_probing is only for booting with device-tree, but arch_timer_common_init is a generic init call which shouldn't include the FW-specific code. It's better to put arch_timer_needs_of_probing into DT init function. But for per-cpu timer, the arch_timer_common_init is called from arch_timer_init. For reaching the goal above, this patch disassemble arch_timer_init and use arch_timer_register and arch_timer_common_init directly, just like arch_timer_mem init code is doing. By this way, all the DT relevant code are only called from DT init call. Signed-off-by: Fu Wei Reviewed-by: Hanjun Guo --- drivers/clocksource/arm_arch_timer.c | 46 ++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 25 deletions(-) -- 2.9.3 diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 97ed103..f2b9ec4 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -887,9 +887,6 @@ static bool __init arch_timer_needs_of_probing(void) static int __init arch_timer_common_init(void) { - if (acpi_disabled && arch_timer_needs_of_probing()) - return 0; - arch_timer_banner(arch_timers_present); arch_counter_register(arch_timers_present); return arch_timer_arch_init(); @@ -927,26 +924,9 @@ static enum arch_timer_ppi_nr __init arch_timer_select_ppi(void) return ARCH_TIMER_PHYS_SECURE_PPI; } -static int __init arch_timer_init(void) -{ - int ret; - - ret = arch_timer_register(); - if (ret) - return ret; - - ret = arch_timer_common_init(); - if (ret) - return ret; - - arch_timer_kvm_info.virtual_irq = arch_timer_ppi[ARCH_TIMER_VIRT_PPI]; - - return 0; -} - static int __init arch_timer_of_init(struct device_node *np) { - int i; + int i, ret; if (arch_timers_present & ARCH_TIMER_TYPE_CP15) { pr_warn("multiple nodes in dt, skipping\n"); @@ -957,6 +937,8 @@ static int __init arch_timer_of_init(struct device_node *np) for (i = ARCH_TIMER_PHYS_SECURE_PPI; i < ARCH_TIMER_MAX_TIMER_PPI; i++) arch_timer_ppi[i] = irq_of_parse_and_map(np, i); + arch_timer_kvm_info.virtual_irq = arch_timer_ppi[ARCH_TIMER_VIRT_PPI]; + /* * Try to determine the frequency from the device tree, * if fail, get the frequency from the sysreg CNTFRQ. @@ -1001,7 +983,14 @@ static int __init arch_timer_of_init(struct device_node *np) arch_counter_suspend_stop = of_property_read_bool(np, "arm,no-tick-in-suspend"); - return arch_timer_init(); + ret = arch_timer_register(); + if (ret) + return ret; + + if (arch_timer_needs_of_probing()) + return 0; + + return arch_timer_common_init(); } 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); @@ -1093,7 +1082,8 @@ static int __init arch_timer_mem_init(struct device_node *np) if (ret) goto out; - return arch_timer_common_init(); + if (!arch_timer_needs_of_probing()) + ret = arch_timer_common_init(); out: iounmap(cntctlbase); of_node_put(best_frame); @@ -1122,6 +1112,7 @@ static int __init map_generic_timer_interrupt(u32 interrupt, u32 flags) /* Initialize per-processor generic timer */ static int __init arch_timer_acpi_init(struct acpi_table_header *table) { + int ret; struct acpi_table_gtdt *gtdt; if (arch_timers_present & ARCH_TIMER_TYPE_CP15) { @@ -1149,6 +1140,8 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table) map_generic_timer_interrupt(gtdt->non_secure_el2_interrupt, gtdt->non_secure_el2_flags); + arch_timer_kvm_info.virtual_irq = arch_timer_ppi[ARCH_TIMER_VIRT_PPI]; + /* Get the frequency from the sysreg CNTFRQ */ arch_timer_sysreg_freq = arch_timer_get_sysreg_freq(); if (!arch_timer_sysreg_freq) { @@ -1165,8 +1158,11 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table) /* Always-on capability */ arch_timer_c3stop = !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON); - arch_timer_init(); - return 0; + ret = arch_timer_register(); + if (ret) + return ret; + + return arch_timer_common_init(); } CLOCKSOURCE_ACPI_DECLARE(arch_timer, ACPI_SIG_GTDT, arch_timer_acpi_init); #endif From patchwork Mon Feb 6 18:50:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fu Wei Fu X-Patchwork-Id: 93479 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp1834728qgi; Mon, 6 Feb 2017 10:52:20 -0800 (PST) X-Received: by 10.99.53.195 with SMTP id c186mr14909787pga.24.1486407140475; Mon, 06 Feb 2017 10:52:20 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l187si1481777pfl.162.2017.02.06.10.52.20; Mon, 06 Feb 2017 10:52:20 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752564AbdBFSwO (ORCPT + 25 others); Mon, 6 Feb 2017 13:52:14 -0500 Received: from mx1.redhat.com ([209.132.183.28]:40306 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751321AbdBFSwL (ORCPT ); Mon, 6 Feb 2017 13:52:11 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E4B9927486E; Mon, 6 Feb 2017 18:52:11 +0000 (UTC) Received: from Rei-Ayanami.localdomain (vpn1-7-227.pek2.redhat.com [10.72.7.227]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v16Iooph003413; Mon, 6 Feb 2017 13:52:02 -0500 From: fu.wei@linaro.org To: rjw@rjwysocki.net, lenb@kernel.org, daniel.lezcano@linaro.org, tglx@linutronix.de, marc.zyngier@arm.com, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, sudeep.holla@arm.com, hanjun.guo@linaro.org Cc: linux-arm-kernel@lists.infradead.org, linaro-acpi@lists.linaro.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, rruigrok@codeaurora.org, harba@codeaurora.org, cov@codeaurora.org, timur@codeaurora.org, graeme.gregory@linaro.org, al.stone@linaro.org, jcm@redhat.com, wei@redhat.com, arnd@arndb.de, catalin.marinas@arm.com, will.deacon@arm.com, Suravee.Suthikulpanit@amd.com, leo.duran@amd.com, wim@iguana.be, linux@roeck-us.net, linux-watchdog@vger.kernel.org, tn@semihalf.com, christoffer.dall@linaro.org, julien.grall@arm.com, Fu Wei Subject: [PATCH v21 07/13] clocksource: arm_arch_timer: introduce some new structs to prepare for GTDT Date: Tue, 7 Feb 2017 02:50:09 +0800 Message-Id: <20170206185015.12296-8-fu.wei@linaro.org> In-Reply-To: <20170206185015.12296-1-fu.wei@linaro.org> References: <20170206185015.12296-1-fu.wei@linaro.org> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Mon, 06 Feb 2017 18:52:12 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Fu Wei The patch introduce two new structs: arch_timer_mem, arch_timer_mem_frame. And also introduce a new define: ARCH_TIMER_MEM_MAX_FRAMES These will be used for refactoring the memory-mapped timer init code to prepare for GTDT Signed-off-by: Fu Wei Reviewed-by: Hanjun Guo --- include/clocksource/arm_arch_timer.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) -- 2.9.3 diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h index 4a98c06..b7dd185 100644 --- a/include/clocksource/arm_arch_timer.h +++ b/include/clocksource/arm_arch_timer.h @@ -57,6 +57,8 @@ enum arch_timer_spi_nr { #define ARCH_TIMER_MEM_PHYS_ACCESS 2 #define ARCH_TIMER_MEM_VIRT_ACCESS 3 +#define ARCH_TIMER_MEM_MAX_FRAMES 8 + #define ARCH_TIMER_USR_PCT_ACCESS_EN (1 << 0) /* physical counter */ #define ARCH_TIMER_USR_VCT_ACCESS_EN (1 << 1) /* virtual counter */ #define ARCH_TIMER_VIRT_EVT_EN (1 << 2) @@ -72,6 +74,21 @@ struct arch_timer_kvm_info { int virtual_irq; }; +struct arch_timer_mem_frame { + int frame_nr; + phys_addr_t cntbase; + size_t size; + int phys_irq; + int virt_irq; +}; + +struct arch_timer_mem { + phys_addr_t cntctlbase; + size_t size; + int num_frames; + struct arch_timer_mem_frame frame[ARCH_TIMER_MEM_MAX_FRAMES]; +}; + #ifdef CONFIG_ARM_ARCH_TIMER extern u32 arch_timer_get_rate(void); From patchwork Mon Feb 6 18:50:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fu Wei Fu X-Patchwork-Id: 93480 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp1834799qgi; Mon, 6 Feb 2017 10:52:31 -0800 (PST) X-Received: by 10.84.215.15 with SMTP id k15mr19238575pli.58.1486407150969; Mon, 06 Feb 2017 10:52:30 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l187si1481777pfl.162.2017.02.06.10.52.30; Mon, 06 Feb 2017 10:52:30 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752589AbdBFSw3 (ORCPT + 25 others); Mon, 6 Feb 2017 13:52:29 -0500 Received: from mx1.redhat.com ([209.132.183.28]:43572 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751321AbdBFSw0 (ORCPT ); Mon, 6 Feb 2017 13:52:26 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 04A79C04B302; Mon, 6 Feb 2017 18:52:22 +0000 (UTC) Received: from Rei-Ayanami.localdomain (vpn1-7-227.pek2.redhat.com [10.72.7.227]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v16Ioopi003413; Mon, 6 Feb 2017 13:52:12 -0500 From: fu.wei@linaro.org To: rjw@rjwysocki.net, lenb@kernel.org, daniel.lezcano@linaro.org, tglx@linutronix.de, marc.zyngier@arm.com, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, sudeep.holla@arm.com, hanjun.guo@linaro.org Cc: linux-arm-kernel@lists.infradead.org, linaro-acpi@lists.linaro.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, rruigrok@codeaurora.org, harba@codeaurora.org, cov@codeaurora.org, timur@codeaurora.org, graeme.gregory@linaro.org, al.stone@linaro.org, jcm@redhat.com, wei@redhat.com, arnd@arndb.de, catalin.marinas@arm.com, will.deacon@arm.com, Suravee.Suthikulpanit@amd.com, leo.duran@amd.com, wim@iguana.be, linux@roeck-us.net, linux-watchdog@vger.kernel.org, tn@semihalf.com, christoffer.dall@linaro.org, julien.grall@arm.com, Fu Wei Subject: [PATCH v21 08/13] clocksource: arm_arch_timer: refactor MMIO timer probing. Date: Tue, 7 Feb 2017 02:50:10 +0800 Message-Id: <20170206185015.12296-9-fu.wei@linaro.org> In-Reply-To: <20170206185015.12296-1-fu.wei@linaro.org> References: <20170206185015.12296-1-fu.wei@linaro.org> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Mon, 06 Feb 2017 18:52:22 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Fu Wei Currently the code to probe MMIO architected timers mixes DT parsing with actual poking of hardware. This makes the code harder than necessary to understand, and makes it difficult to add support for probing via ACPI. This patch factors all the DT-specific logic out of arch_timer_mem_init(), into a new function arch_timer_mem_of_init(). The former pokes the hardware and determines the suitablility of frames based on a datastructure populated by the latter. This cleanly separates the two and will make it possible to add probing using the ACPI GTDT in subsequent patches. Signed-off-by: Fu Wei Reviewed-by: Hanjun Guo --- drivers/clocksource/arm_arch_timer.c | 156 +++++++++++++++++++++++++---------- 1 file changed, 111 insertions(+), 45 deletions(-) -- 2.9.3 diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index f2b9ec4..73e875d 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -995,17 +995,20 @@ static int __init arch_timer_of_init(struct device_node *np) 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); -static int __init arch_timer_mem_init(struct device_node *np) +static int __init arch_timer_mem_init(struct arch_timer_mem *timer_mem) { - struct device_node *frame, *best_frame = NULL; void __iomem *cntctlbase, *base; - unsigned int irq, ret = -EINVAL; + struct arch_timer_mem_frame *best_frame = NULL; + unsigned int irq; u32 cnttidr; + int i, ret; - arch_timers_present |= ARCH_TIMER_TYPE_MEM; - cntctlbase = of_iomap(np, 0); + if (!timer_mem->num_frames) + return -ENODEV; + + cntctlbase = ioremap(timer_mem->cntctlbase, timer_mem->size); if (!cntctlbase) { - pr_err("Can't find CNTCTLBase\n"); + pr_err("Can't map CNTCTLBase.\n"); return -ENXIO; } @@ -1015,26 +1018,18 @@ static int __init arch_timer_mem_init(struct device_node *np) * Try to find a virtual capable frame. Otherwise fall back to a * physical capable frame. */ - for_each_available_child_of_node(np, frame) { - int n; - u32 cntacr; - - if (of_property_read_u32(frame, "frame-number", &n)) { - pr_err("Missing frame-number\n"); - of_node_put(frame); - goto out; - } + for (i = 0; i < timer_mem->num_frames; i++) { + u32 cntacr = CNTACR_RFRQ | CNTACR_RWPT | CNTACR_RPCT | + CNTACR_RWVT | CNTACR_RVOFF | CNTACR_RVCT; + int n = timer_mem->frame[i].frame_nr; /* Try enabling everything, and see what sticks */ - cntacr = CNTACR_RFRQ | CNTACR_RWPT | CNTACR_RPCT | - CNTACR_RWVT | CNTACR_RVOFF | CNTACR_RVCT; writel_relaxed(cntacr, cntctlbase + CNTACR(n)); cntacr = readl_relaxed(cntctlbase + CNTACR(n)); if ((cnttidr & CNTTIDR_VIRT(n)) && !(~cntacr & (CNTACR_RWVT | CNTACR_RVCT))) { - of_node_put(best_frame); - best_frame = frame; + best_frame = &timer_mem->frame[i]; arch_timer_mem_use_virtual = true; break; } @@ -1042,55 +1037,126 @@ static int __init arch_timer_mem_init(struct device_node *np) if (~cntacr & (CNTACR_RWPT | CNTACR_RPCT)) continue; - of_node_put(best_frame); - best_frame = of_node_get(frame); + best_frame = &timer_mem->frame[i]; } + iounmap(cntctlbase); - ret= -ENXIO; - base = arch_counter_base = of_io_request_and_map(best_frame, 0, - "arch_mem_timer"); - if (IS_ERR(base)) { - pr_err("Can't map frame's registers\n"); - goto out; + if (!best_frame) { + pr_err("Can't find frame for register\n"); + return -EINVAL; } if (arch_timer_mem_use_virtual) - irq = irq_of_parse_and_map(best_frame, ARCH_TIMER_VIRT_SPI); + irq = best_frame->virt_irq; else - irq = irq_of_parse_and_map(best_frame, ARCH_TIMER_PHYS_SPI); + irq = best_frame->phys_irq; - ret = -EINVAL; if (!irq) { pr_err("Frame missing %s irq.\n", arch_timer_mem_use_virtual ? "virt" : "phys"); - goto out; + return -EINVAL; } - /* - * Try to determine the frequency from the device tree, - * if fail, get the frequency from the CNTFRQ reg of MMIO timer. - */ - if (of_property_read_u32(np, "clock-frequency", &arch_timer_mmio_freq)) + if (!request_mem_region(best_frame->cntbase, best_frame->size, + "arch_mem_timer")) + return -EBUSY; + + base = ioremap(best_frame->cntbase, best_frame->size); + if (!base) { + pr_err("Can't map frame's registers\n"); + return -ENXIO; + } + + if (!arch_timer_mmio_freq) arch_timer_mmio_freq = arch_timer_get_mmio_freq(base); - if (!arch_timer_mmio_freq) { - pr_err(FW_BUG "frequency not available for MMIO timer.\n"); - ret = -EINVAL; - goto out; + if (!arch_timer_mmio_freq || + (arch_timer_sysreg_freq && + arch_timer_mmio_freq != arch_timer_sysreg_freq)) { + pr_err(FW_BUG "invalid frequency for MMIO timer.\n"); + arch_timer_mmio_freq = 0; + iounmap(base); + return -EINVAL; } ret = arch_timer_mem_register(base, irq); - if (ret) + if (ret) { + iounmap(base); + return ret; + } + + arch_counter_base = base; + arch_timers_present |= ARCH_TIMER_TYPE_MEM; + + return 0; +} + +static int __init arch_timer_mem_of_init(struct device_node *np) +{ + struct arch_timer_mem *timer_mem; + struct device_node *frame_node; + struct resource res; + int i, ret = -EINVAL; + + timer_mem = kzalloc(sizeof(*timer_mem), GFP_KERNEL); + if (!timer_mem) + return -ENOMEM; + + if (of_address_to_resource(np, 0, &res)) goto out; + timer_mem->cntctlbase = res.start; + timer_mem->size = resource_size(&res); + + i = 0; + for_each_available_child_of_node(np, frame_node) { + int n; + struct arch_timer_mem_frame *frame; + + if (i >= ARCH_TIMER_MEM_MAX_FRAMES) { + pr_err(FW_BUG "too many frames, only %u are permitted.\n", + ARCH_TIMER_MEM_MAX_FRAMES); + goto out; + } - if (!arch_timer_needs_of_probing()) + frame = &timer_mem->frame[i]; + + if (of_property_read_u32(frame_node, "frame-number", &n)) { + pr_err(FW_BUG "Missing frame-number\n"); + of_node_put(frame_node); + goto out; + } + frame->frame_nr = n; + + if (of_address_to_resource(frame_node, 0, &res)) { + of_node_put(frame_node); + goto out; + } + frame->cntbase = res.start; + frame->size = resource_size(&res); + + frame->virt_irq = irq_of_parse_and_map(frame_node, + ARCH_TIMER_VIRT_SPI); + frame->phys_irq = irq_of_parse_and_map(frame_node, + ARCH_TIMER_PHYS_SPI); + + i++; + } + timer_mem->num_frames = i; + + /* + * Try to get the frequency from the device tree, + * if fail, we will try the CNTFRQ register in arch_timer_mem_init. + */ + of_property_read_u32(np, "clock-frequency", &arch_timer_mmio_freq); + + ret = arch_timer_mem_init(timer_mem); + if (!ret && !arch_timer_needs_of_probing()) ret = arch_timer_common_init(); out: - iounmap(cntctlbase); - of_node_put(best_frame); + kfree(timer_mem); return ret; } CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem", - arch_timer_mem_init); + arch_timer_mem_of_init); #ifdef CONFIG_ACPI static int __init map_generic_timer_interrupt(u32 interrupt, u32 flags) From patchwork Mon Feb 6 18:50:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fu Wei Fu X-Patchwork-Id: 93481 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp1834960qgi; Mon, 6 Feb 2017 10:52:57 -0800 (PST) X-Received: by 10.98.93.152 with SMTP id n24mr14833179pfj.107.1486407177312; Mon, 06 Feb 2017 10:52:57 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f1si1489151plf.165.2017.02.06.10.52.56; Mon, 06 Feb 2017 10:52:57 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752616AbdBFSwk (ORCPT + 25 others); Mon, 6 Feb 2017 13:52:40 -0500 Received: from mx1.redhat.com ([209.132.183.28]:46772 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751321AbdBFSwg (ORCPT ); Mon, 6 Feb 2017 13:52:36 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2C75A80F7C; Mon, 6 Feb 2017 18:52:32 +0000 (UTC) Received: from Rei-Ayanami.localdomain (vpn1-7-227.pek2.redhat.com [10.72.7.227]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v16Ioopj003413; Mon, 6 Feb 2017 13:52:22 -0500 From: fu.wei@linaro.org To: rjw@rjwysocki.net, lenb@kernel.org, daniel.lezcano@linaro.org, tglx@linutronix.de, marc.zyngier@arm.com, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, sudeep.holla@arm.com, hanjun.guo@linaro.org Cc: linux-arm-kernel@lists.infradead.org, linaro-acpi@lists.linaro.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, rruigrok@codeaurora.org, harba@codeaurora.org, cov@codeaurora.org, timur@codeaurora.org, graeme.gregory@linaro.org, al.stone@linaro.org, jcm@redhat.com, wei@redhat.com, arnd@arndb.de, catalin.marinas@arm.com, will.deacon@arm.com, Suravee.Suthikulpanit@amd.com, leo.duran@amd.com, wim@iguana.be, linux@roeck-us.net, linux-watchdog@vger.kernel.org, tn@semihalf.com, christoffer.dall@linaro.org, julien.grall@arm.com, Fu Wei Subject: [PATCH v21 09/13] acpi/arm64: Add GTDT table parse driver Date: Tue, 7 Feb 2017 02:50:11 +0800 Message-Id: <20170206185015.12296-10-fu.wei@linaro.org> In-Reply-To: <20170206185015.12296-1-fu.wei@linaro.org> References: <20170206185015.12296-1-fu.wei@linaro.org> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Mon, 06 Feb 2017 18:52:32 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Fu Wei This patch adds support for parsing arch timer info in GTDT, provides some kernel APIs to parse all the PPIs and always-on info in GTDT and export them. By this driver, we can simplify arm_arch_timer drivers, and separate the ACPI GTDT knowledge from it. Signed-off-by: Fu Wei Signed-off-by: Hanjun Guo Acked-by: Rafael J. Wysocki Tested-by: Xiongfeng Wang Reviewed-by: Hanjun Guo Tested-by: Hanjun Guo --- arch/arm64/Kconfig | 1 + drivers/acpi/arm64/Kconfig | 3 + drivers/acpi/arm64/Makefile | 1 + drivers/acpi/arm64/gtdt.c | 157 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/acpi.h | 6 ++ 5 files changed, 168 insertions(+) -- 2.9.3 diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 1117421..ab1ee10 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -2,6 +2,7 @@ config ARM64 def_bool y select ACPI_CCA_REQUIRED if ACPI select ACPI_GENERIC_GSI if ACPI + select ACPI_GTDT if ACPI select ACPI_REDUCED_HARDWARE_ONLY if ACPI select ACPI_MCFG if ACPI select ACPI_SPCR_TABLE if ACPI diff --git a/drivers/acpi/arm64/Kconfig b/drivers/acpi/arm64/Kconfig index 4616da4..5a6f80f 100644 --- a/drivers/acpi/arm64/Kconfig +++ b/drivers/acpi/arm64/Kconfig @@ -4,3 +4,6 @@ config ACPI_IORT bool + +config ACPI_GTDT + bool diff --git a/drivers/acpi/arm64/Makefile b/drivers/acpi/arm64/Makefile index 72331f2..1017def 100644 --- a/drivers/acpi/arm64/Makefile +++ b/drivers/acpi/arm64/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_ACPI_IORT) += iort.o +obj-$(CONFIG_ACPI_GTDT) += gtdt.o diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c new file mode 100644 index 0000000..8a03b4b --- /dev/null +++ b/drivers/acpi/arm64/gtdt.c @@ -0,0 +1,157 @@ +/* + * ARM Specific GTDT table Support + * + * Copyright (C) 2016, Linaro Ltd. + * Author: Daniel Lezcano + * Fu Wei + * Hanjun Guo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +#include + +#undef pr_fmt +#define pr_fmt(fmt) "ACPI GTDT: " fmt + +/** + * struct acpi_gtdt_descriptor - Store the key info of GTDT for all functions + * @gtdt: The pointer to the struct acpi_table_gtdt of GTDT table. + * @gtdt_end: The pointer to the end of GTDT table. + * @platform_timer: The pointer to the start of Platform Timer Structure + * + * The struct store the key info of GTDT table, it should be initialized by + * acpi_gtdt_init. + */ +struct acpi_gtdt_descriptor { + struct acpi_table_gtdt *gtdt; + void *gtdt_end; + void *platform_timer; +}; + +static struct acpi_gtdt_descriptor acpi_gtdt_desc __initdata; + +static int __init map_gt_gsi(u32 interrupt, u32 flags) +{ + int trigger, polarity; + + trigger = (flags & ACPI_GTDT_INTERRUPT_MODE) ? ACPI_EDGE_SENSITIVE + : ACPI_LEVEL_SENSITIVE; + + polarity = (flags & ACPI_GTDT_INTERRUPT_POLARITY) ? ACPI_ACTIVE_LOW + : ACPI_ACTIVE_HIGH; + + return acpi_register_gsi(NULL, interrupt, trigger, polarity); +} + +/** + * acpi_gtdt_map_ppi() - Map the PPIs of per-cpu arch_timer. + * @type: the type of PPI. + * + * Note: Linux on arm64 isn't supported on the secure side. + * So we only handle the non-secure timer PPIs, + * ARCH_TIMER_PHYS_SECURE_PPI is treated as invalid type. + * + * Return: the mapped PPI value, 0 if error. + */ +int __init acpi_gtdt_map_ppi(int type) +{ + struct acpi_table_gtdt *gtdt = acpi_gtdt_desc.gtdt; + + switch (type) { + case ARCH_TIMER_PHYS_NONSECURE_PPI: + return map_gt_gsi(gtdt->non_secure_el1_interrupt, + gtdt->non_secure_el1_flags); + case ARCH_TIMER_VIRT_PPI: + return map_gt_gsi(gtdt->virtual_timer_interrupt, + gtdt->virtual_timer_flags); + + case ARCH_TIMER_HYP_PPI: + return map_gt_gsi(gtdt->non_secure_el2_interrupt, + gtdt->non_secure_el2_flags); + default: + pr_err("Failed to map timer interrupt: invalid type.\n"); + } + + return 0; +} + +/** + * acpi_gtdt_c3stop() - Got c3stop info from GTDT according to the type of PPI. + * @type: the type of PPI. + * + * Return: 1 if the timer can be in deep idle state, 0 otherwise. + */ +bool __init acpi_gtdt_c3stop(int type) +{ + struct acpi_table_gtdt *gtdt = acpi_gtdt_desc.gtdt; + + switch (type) { + case ARCH_TIMER_PHYS_NONSECURE_PPI: + return !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON); + + case ARCH_TIMER_VIRT_PPI: + return !(gtdt->virtual_timer_flags & ACPI_GTDT_ALWAYS_ON); + + case ARCH_TIMER_HYP_PPI: + return !(gtdt->non_secure_el2_flags & ACPI_GTDT_ALWAYS_ON); + + default: + pr_err("Failed to get c3stop info: invalid type.\n"); + } + + return 0; +} + +/** + * acpi_gtdt_init() - Get the info of GTDT table to prepare for further init. + * @table: The pointer to GTDT table. + * @platform_timer_count: The pointer of int variate for returning the + * number of platform timers. It can be NULL, if + * driver don't need this info. + * + * Return: 0 if success, -EINVAL if error. + */ +int __init acpi_gtdt_init(struct acpi_table_header *table, + int *platform_timer_count) +{ + int ret = 0; + int timer_count = 0; + void *platform_timer = NULL; + struct acpi_table_gtdt *gtdt; + + gtdt = container_of(table, struct acpi_table_gtdt, header); + acpi_gtdt_desc.gtdt = gtdt; + acpi_gtdt_desc.gtdt_end = (void *)table + table->length; + + if (table->revision < 2) + pr_warn("Revision:%d doesn't support Platform Timers.\n", + table->revision); + else if (!gtdt->platform_timer_count) + pr_debug("No Platform Timer.\n"); + else + timer_count = gtdt->platform_timer_count; + + if (timer_count) { + platform_timer = (void *)gtdt + gtdt->platform_timer_offset; + if (platform_timer < (void *)table + + sizeof(struct acpi_table_gtdt)) { + pr_err(FW_BUG "invalid timer data.\n"); + timer_count = 0; + platform_timer = NULL; + ret = -EINVAL; + } + } + + acpi_gtdt_desc.platform_timer = platform_timer; + if (platform_timer_count) + *platform_timer_count = timer_count; + + return ret; +} diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 5b36974..d0b271e 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -597,6 +597,12 @@ enum acpi_reconfig_event { int acpi_reconfig_notifier_register(struct notifier_block *nb); int acpi_reconfig_notifier_unregister(struct notifier_block *nb); +#ifdef CONFIG_ACPI_GTDT +int acpi_gtdt_init(struct acpi_table_header *table, int *platform_timer_count); +int acpi_gtdt_map_ppi(int type); +bool acpi_gtdt_c3stop(int type); +#endif + #else /* !CONFIG_ACPI */ #define acpi_disabled 1 From patchwork Mon Feb 6 18:50:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fu Wei Fu X-Patchwork-Id: 93482 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp1834964qgi; Mon, 6 Feb 2017 10:52:57 -0800 (PST) X-Received: by 10.98.152.218 with SMTP id d87mr14550244pfk.17.1486407177644; Mon, 06 Feb 2017 10:52:57 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f1si1489151plf.165.2017.02.06.10.52.57; Mon, 06 Feb 2017 10:52:57 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752637AbdBFSwq (ORCPT + 25 others); Mon, 6 Feb 2017 13:52:46 -0500 Received: from mx1.redhat.com ([209.132.183.28]:55818 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752105AbdBFSwl (ORCPT ); Mon, 6 Feb 2017 13:52:41 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3FF8F369C3; Mon, 6 Feb 2017 18:52:42 +0000 (UTC) Received: from Rei-Ayanami.localdomain (vpn1-7-227.pek2.redhat.com [10.72.7.227]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v16Ioopk003413; Mon, 6 Feb 2017 13:52:32 -0500 From: fu.wei@linaro.org To: rjw@rjwysocki.net, lenb@kernel.org, daniel.lezcano@linaro.org, tglx@linutronix.de, marc.zyngier@arm.com, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, sudeep.holla@arm.com, hanjun.guo@linaro.org Cc: linux-arm-kernel@lists.infradead.org, linaro-acpi@lists.linaro.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, rruigrok@codeaurora.org, harba@codeaurora.org, cov@codeaurora.org, timur@codeaurora.org, graeme.gregory@linaro.org, al.stone@linaro.org, jcm@redhat.com, wei@redhat.com, arnd@arndb.de, catalin.marinas@arm.com, will.deacon@arm.com, Suravee.Suthikulpanit@amd.com, leo.duran@amd.com, wim@iguana.be, linux@roeck-us.net, linux-watchdog@vger.kernel.org, tn@semihalf.com, christoffer.dall@linaro.org, julien.grall@arm.com, Fu Wei Subject: [PATCH v21 10/13] clocksource: arm_arch_timer: simplify ACPI support code. Date: Tue, 7 Feb 2017 02:50:12 +0800 Message-Id: <20170206185015.12296-11-fu.wei@linaro.org> In-Reply-To: <20170206185015.12296-1-fu.wei@linaro.org> References: <20170206185015.12296-1-fu.wei@linaro.org> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Mon, 06 Feb 2017 18:52:42 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Fu Wei The patch update arm_arch_timer driver to use the function provided by the new GTDT driver of ACPI. By this way, arm_arch_timer.c can be simplified, and separate all the ACPI GTDT knowledge from this timer driver. Signed-off-by: Fu Wei Signed-off-by: Hanjun Guo Tested-by: Xiongfeng Wang Reviewed-by: Hanjun Guo Tested-by: Hanjun Guo --- drivers/clocksource/arm_arch_timer.c | 54 ++++++++++++------------------------ 1 file changed, 17 insertions(+), 37 deletions(-) -- 2.9.3 diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 73e875d..35e0b66 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -1158,63 +1158,36 @@ static int __init arch_timer_mem_of_init(struct device_node *np) CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem", arch_timer_mem_of_init); -#ifdef CONFIG_ACPI -static int __init map_generic_timer_interrupt(u32 interrupt, u32 flags) -{ - int trigger, polarity; - - if (!interrupt) - return 0; - - trigger = (flags & ACPI_GTDT_INTERRUPT_MODE) ? ACPI_EDGE_SENSITIVE - : ACPI_LEVEL_SENSITIVE; - - polarity = (flags & ACPI_GTDT_INTERRUPT_POLARITY) ? ACPI_ACTIVE_LOW - : ACPI_ACTIVE_HIGH; - - return acpi_register_gsi(NULL, interrupt, trigger, polarity); -} - +#ifdef CONFIG_ACPI_GTDT /* Initialize per-processor generic timer */ static int __init arch_timer_acpi_init(struct acpi_table_header *table) { int ret; - struct acpi_table_gtdt *gtdt; if (arch_timers_present & ARCH_TIMER_TYPE_CP15) { pr_warn("already initialized, skipping\n"); return -EINVAL; } - gtdt = container_of(table, struct acpi_table_gtdt, header); - arch_timers_present |= ARCH_TIMER_TYPE_CP15; - arch_timer_ppi[ARCH_TIMER_PHYS_SECURE_PPI] = - map_generic_timer_interrupt(gtdt->secure_el1_interrupt, - gtdt->secure_el1_flags); + ret = acpi_gtdt_init(table, NULL); + if (ret) { + pr_err("Failed to init GTDT table.\n"); + return ret; + } arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI] = - map_generic_timer_interrupt(gtdt->non_secure_el1_interrupt, - gtdt->non_secure_el1_flags); + acpi_gtdt_map_ppi(ARCH_TIMER_PHYS_NONSECURE_PPI); arch_timer_ppi[ARCH_TIMER_VIRT_PPI] = - map_generic_timer_interrupt(gtdt->virtual_timer_interrupt, - gtdt->virtual_timer_flags); + acpi_gtdt_map_ppi(ARCH_TIMER_VIRT_PPI); arch_timer_ppi[ARCH_TIMER_HYP_PPI] = - map_generic_timer_interrupt(gtdt->non_secure_el2_interrupt, - gtdt->non_secure_el2_flags); + acpi_gtdt_map_ppi(ARCH_TIMER_HYP_PPI); arch_timer_kvm_info.virtual_irq = arch_timer_ppi[ARCH_TIMER_VIRT_PPI]; - /* Get the frequency from the sysreg CNTFRQ */ - arch_timer_sysreg_freq = arch_timer_get_sysreg_freq(); - if (!arch_timer_sysreg_freq) { - pr_err(FW_BUG "frequency not available.\n"); - return -EINVAL; - } - arch_timer_uses_ppi = arch_timer_select_ppi(); if (!arch_timer_ppi[arch_timer_uses_ppi]) { pr_err("No interrupt available, giving up\n"); @@ -1222,7 +1195,14 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table) } /* Always-on capability */ - arch_timer_c3stop = !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON); + arch_timer_c3stop = acpi_gtdt_c3stop(arch_timer_uses_ppi); + + /* Get the frequency from the sysreg CNTFRQ */ + arch_timer_sysreg_freq = arch_timer_get_sysreg_freq(); + if (!arch_timer_sysreg_freq) { + pr_err(FW_BUG "frequency not available.\n"); + return -EINVAL; + } ret = arch_timer_register(); if (ret) From patchwork Mon Feb 6 18:50:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fu Wei Fu X-Patchwork-Id: 93483 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp1834994qgi; Mon, 6 Feb 2017 10:53:01 -0800 (PST) X-Received: by 10.84.217.221 with SMTP id d29mr19599365plj.47.1486407181594; Mon, 06 Feb 2017 10:53:01 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f1si1489151plf.165.2017.02.06.10.53.01; Mon, 06 Feb 2017 10:53:01 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752656AbdBFSxA (ORCPT + 25 others); Mon, 6 Feb 2017 13:53:00 -0500 Received: from mx1.redhat.com ([209.132.183.28]:40708 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752176AbdBFSw5 (ORCPT ); Mon, 6 Feb 2017 13:52:57 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6210B6666; Mon, 6 Feb 2017 18:52:52 +0000 (UTC) Received: from Rei-Ayanami.localdomain (vpn1-7-227.pek2.redhat.com [10.72.7.227]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v16Ioopl003413; Mon, 6 Feb 2017 13:52:42 -0500 From: fu.wei@linaro.org To: rjw@rjwysocki.net, lenb@kernel.org, daniel.lezcano@linaro.org, tglx@linutronix.de, marc.zyngier@arm.com, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, sudeep.holla@arm.com, hanjun.guo@linaro.org Cc: linux-arm-kernel@lists.infradead.org, linaro-acpi@lists.linaro.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, rruigrok@codeaurora.org, harba@codeaurora.org, cov@codeaurora.org, timur@codeaurora.org, graeme.gregory@linaro.org, al.stone@linaro.org, jcm@redhat.com, wei@redhat.com, arnd@arndb.de, catalin.marinas@arm.com, will.deacon@arm.com, Suravee.Suthikulpanit@amd.com, leo.duran@amd.com, wim@iguana.be, linux@roeck-us.net, linux-watchdog@vger.kernel.org, tn@semihalf.com, christoffer.dall@linaro.org, julien.grall@arm.com, Fu Wei Subject: [PATCH v21 11/13] acpi/arm64: Add memory-mapped timer support in GTDT driver Date: Tue, 7 Feb 2017 02:50:13 +0800 Message-Id: <20170206185015.12296-12-fu.wei@linaro.org> In-Reply-To: <20170206185015.12296-1-fu.wei@linaro.org> References: <20170206185015.12296-1-fu.wei@linaro.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Mon, 06 Feb 2017 18:52:52 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Fu Wei On platforms booting with ACPI, architected memory-mapped timers' configuration data is provided by firmware through the ACPI GTDT static table. The clocksource architected timer kernel driver requires a firmware interface to collect timer configuration and configure its driver. this infrastructure is present for device tree systems, but it is missing on systems booting with ACPI. Implement the kernel infrastructure required to parse the static ACPI GTDT table so that the architected timer clocksource driver can make use of it on systems booting with ACPI, therefore enabling the corresponding timers configuration. Signed-off-by: Fu Wei Signed-off-by: Hanjun Guo --- drivers/acpi/arm64/gtdt.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/acpi.h | 1 + 2 files changed, 129 insertions(+) -- 2.9.3 diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c index 8a03b4b..29b9acc 100644 --- a/drivers/acpi/arm64/gtdt.c +++ b/drivers/acpi/arm64/gtdt.c @@ -37,6 +37,28 @@ struct acpi_gtdt_descriptor { static struct acpi_gtdt_descriptor acpi_gtdt_desc __initdata; +static inline void *next_platform_timer(void *platform_timer) +{ + struct acpi_gtdt_header *gh = platform_timer; + + platform_timer += gh->length; + if (platform_timer < acpi_gtdt_desc.gtdt_end) + return platform_timer; + + return NULL; +} + +#define for_each_platform_timer(_g) \ + for (_g = acpi_gtdt_desc.platform_timer; _g; \ + _g = next_platform_timer(_g)) + +static inline bool is_timer_block(void *platform_timer) +{ + struct acpi_gtdt_header *gh = platform_timer; + + return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK; +} + static int __init map_gt_gsi(u32 interrupt, u32 flags) { int trigger, polarity; @@ -155,3 +177,109 @@ int __init acpi_gtdt_init(struct acpi_table_header *table, return ret; } + +static int __init gtdt_parse_timer_block(struct acpi_gtdt_timer_block *block, + struct arch_timer_mem *data) +{ + int i, j; + struct acpi_gtdt_timer_entry *frame; + + if (!block->timer_count) { + pr_err(FW_BUG "GT block present, but frame count is zero."); + return -ENODEV; + } + + if (block->timer_count > ARCH_TIMER_MEM_MAX_FRAMES) { + pr_err(FW_BUG "GT block lists %d frames, ACPI spec only allows 8\n", + block->timer_count); + return -EINVAL; + } + + data->cntctlbase = (phys_addr_t)block->block_address; + /* + * According to "Table * CNTCTLBase memory map" of + * for ARMv8, + * The size of the CNTCTLBase frame is 4KB(Offset 0x000 – 0xFFC). + */ + data->size = SZ_4K; + + frame = (void *)block + block->timer_offset; + if (frame + block->timer_count != (void *)block + block->header.length) + return -EINVAL; + + /* + * Get the GT timer Frame data for every GT Block Timer + */ + for (i = 0, j = 0; i < block->timer_count; i++, frame++) { + if (frame->common_flags & ACPI_GTDT_GT_IS_SECURE_TIMER) + continue; + + if (!frame->base_address || !frame->timer_interrupt) + return -EINVAL; + + data->frame[j].phys_irq = map_gt_gsi(frame->timer_interrupt, + frame->timer_flags); + if (data->frame[j].phys_irq <= 0) { + pr_warn("failed to map physical timer irq in frame %d.\n", + i); + return -EINVAL; + } + + data->frame[j].virt_irq = + map_gt_gsi(frame->virtual_timer_interrupt, + frame->virtual_timer_flags); + if (data->frame[j].virt_irq <= 0) { + pr_warn("failed to map virtual timer irq in frame %d.\n", + i); + acpi_unregister_gsi(frame->timer_interrupt); + return -EINVAL; + } + + data->frame[j].frame_nr = frame->frame_number; + data->frame[j].cntbase = frame->base_address; + /* + * According to "Table * CNTBaseN memory map" of + * for ARMv8, + * The size of the CNTBaseN frame is 4KB(Offset 0x000 – 0xFFC). + */ + data->frame[j].size = SZ_4K; + j++; + } + data->num_frames = j; + + return 0; +} + +/** + * acpi_arch_timer_mem_init() - Get the info of all GT blocks in GTDT table. + * @data: the pointer to the array of struct arch_timer_mem for returning + * the result of parsing. The element number of this array should + * be platform_timer_count(the total number of platform timers). + * @count: The pointer of int variate for returning the number of GT + * blocks we have parsed. + * + * Return: 0 if success, -EINVAL/-ENODEV if error. + */ +int __init acpi_arch_timer_mem_init(struct arch_timer_mem *data, + int *timer_count) +{ + int ret; + void *platform_timer; + + *timer_count = 0; + for_each_platform_timer(platform_timer) { + if (is_timer_block(platform_timer)) { + ret = gtdt_parse_timer_block(platform_timer, data); + if (ret) + return ret; + data++; + (*timer_count)++; + } + } + + if (*timer_count) + pr_info("found %d memory-mapped timer block(s).\n", + *timer_count); + + return 0; +} diff --git a/include/linux/acpi.h b/include/linux/acpi.h index d0b271e..51e85b9 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -601,6 +601,7 @@ int acpi_reconfig_notifier_unregister(struct notifier_block *nb); int acpi_gtdt_init(struct acpi_table_header *table, int *platform_timer_count); int acpi_gtdt_map_ppi(int type); bool acpi_gtdt_c3stop(int type); +int acpi_arch_timer_mem_init(struct arch_timer_mem *data, int *timer_count); #endif #else /* !CONFIG_ACPI */ From patchwork Mon Feb 6 18:50:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fu Wei Fu X-Patchwork-Id: 93485 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp1835202qgi; Mon, 6 Feb 2017 10:53:34 -0800 (PST) X-Received: by 10.98.252.203 with SMTP id e194mr14693003pfh.8.1486407214288; Mon, 06 Feb 2017 10:53:34 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c137si1475138pga.301.2017.02.06.10.53.33; Mon, 06 Feb 2017 10:53:34 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752698AbdBFSxU (ORCPT + 25 others); Mon, 6 Feb 2017 13:53:20 -0500 Received: from mx1.redhat.com ([209.132.183.28]:59406 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752212AbdBFSxR (ORCPT ); Mon, 6 Feb 2017 13:53:17 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6DB8461E5B; Mon, 6 Feb 2017 18:53:02 +0000 (UTC) Received: from Rei-Ayanami.localdomain (vpn1-7-227.pek2.redhat.com [10.72.7.227]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v16Ioopm003413; Mon, 6 Feb 2017 13:52:52 -0500 From: fu.wei@linaro.org To: rjw@rjwysocki.net, lenb@kernel.org, daniel.lezcano@linaro.org, tglx@linutronix.de, marc.zyngier@arm.com, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, sudeep.holla@arm.com, hanjun.guo@linaro.org Cc: linux-arm-kernel@lists.infradead.org, linaro-acpi@lists.linaro.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, rruigrok@codeaurora.org, harba@codeaurora.org, cov@codeaurora.org, timur@codeaurora.org, graeme.gregory@linaro.org, al.stone@linaro.org, jcm@redhat.com, wei@redhat.com, arnd@arndb.de, catalin.marinas@arm.com, will.deacon@arm.com, Suravee.Suthikulpanit@amd.com, leo.duran@amd.com, wim@iguana.be, linux@roeck-us.net, linux-watchdog@vger.kernel.org, tn@semihalf.com, christoffer.dall@linaro.org, julien.grall@arm.com, Fu Wei Subject: [PATCH v21 12/13] clocksource: arm_arch_timer: add GTDT support for memory-mapped timer Date: Tue, 7 Feb 2017 02:50:14 +0800 Message-Id: <20170206185015.12296-13-fu.wei@linaro.org> In-Reply-To: <20170206185015.12296-1-fu.wei@linaro.org> References: <20170206185015.12296-1-fu.wei@linaro.org> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Mon, 06 Feb 2017 18:53:02 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Fu Wei The patch add memory-mapped timer register support by using the information provided by the new GTDT driver of ACPI. Signed-off-by: Fu Wei Reviewed-by: Hanjun Guo --- drivers/clocksource/arm_arch_timer.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) -- 2.9.3 diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 35e0b66..44c55ec 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -1159,10 +1159,35 @@ CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem", arch_timer_mem_of_init); #ifdef CONFIG_ACPI_GTDT -/* Initialize per-processor generic timer */ +static int __init arch_timer_mem_acpi_init(int platform_timer_count) +{ + struct arch_timer_mem *timer_mem; + int timer_count, i, ret; + + timer_mem = kcalloc(platform_timer_count, sizeof(*timer_mem), + GFP_KERNEL); + if (!timer_mem) + return -ENOMEM; + + ret = acpi_arch_timer_mem_init(timer_mem, &timer_count); + if (ret || !timer_count) + goto error; + + for (i = 0; i < timer_count; i++) { + ret = arch_timer_mem_init(timer_mem + i); + if (!ret) + break; + } + +error: + kfree(timer_mem); + return ret; +} + +/* Initialize per-processor generic timer and memory-mapped timer(if present) */ static int __init arch_timer_acpi_init(struct acpi_table_header *table) { - int ret; + int ret, platform_timer_count; if (arch_timers_present & ARCH_TIMER_TYPE_CP15) { pr_warn("already initialized, skipping\n"); @@ -1171,7 +1196,7 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table) arch_timers_present |= ARCH_TIMER_TYPE_CP15; - ret = acpi_gtdt_init(table, NULL); + ret = acpi_gtdt_init(table, &platform_timer_count); if (ret) { pr_err("Failed to init GTDT table.\n"); return ret; @@ -1208,6 +1233,10 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table) if (ret) return ret; + if (platform_timer_count && + arch_timer_mem_acpi_init(platform_timer_count)) + pr_err("Failed to initialize memory-mapped timer.\n"); + return arch_timer_common_init(); } CLOCKSOURCE_ACPI_DECLARE(arch_timer, ACPI_SIG_GTDT, arch_timer_acpi_init); From patchwork Mon Feb 6 18:50:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fu Wei Fu X-Patchwork-Id: 93484 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp1835102qgi; Mon, 6 Feb 2017 10:53:18 -0800 (PST) X-Received: by 10.99.63.193 with SMTP id m184mr15001671pga.123.1486407198841; Mon, 06 Feb 2017 10:53:18 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p22si1488187pli.181.2017.02.06.10.53.18; Mon, 06 Feb 2017 10:53:18 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752689AbdBFSxP (ORCPT + 25 others); Mon, 6 Feb 2017 13:53:15 -0500 Received: from mx1.redhat.com ([209.132.183.28]:44060 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752466AbdBFSxM (ORCPT ); Mon, 6 Feb 2017 13:53:12 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 85CECC04B939; Mon, 6 Feb 2017 18:53:12 +0000 (UTC) Received: from Rei-Ayanami.localdomain (vpn1-7-227.pek2.redhat.com [10.72.7.227]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v16Ioopn003413; Mon, 6 Feb 2017 13:53:02 -0500 From: fu.wei@linaro.org To: rjw@rjwysocki.net, lenb@kernel.org, daniel.lezcano@linaro.org, tglx@linutronix.de, marc.zyngier@arm.com, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, sudeep.holla@arm.com, hanjun.guo@linaro.org Cc: linux-arm-kernel@lists.infradead.org, linaro-acpi@lists.linaro.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, rruigrok@codeaurora.org, harba@codeaurora.org, cov@codeaurora.org, timur@codeaurora.org, graeme.gregory@linaro.org, al.stone@linaro.org, jcm@redhat.com, wei@redhat.com, arnd@arndb.de, catalin.marinas@arm.com, will.deacon@arm.com, Suravee.Suthikulpanit@amd.com, leo.duran@amd.com, wim@iguana.be, linux@roeck-us.net, linux-watchdog@vger.kernel.org, tn@semihalf.com, christoffer.dall@linaro.org, julien.grall@arm.com, Fu Wei Subject: [PATCH v21 13/13] acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver Date: Tue, 7 Feb 2017 02:50:15 +0800 Message-Id: <20170206185015.12296-14-fu.wei@linaro.org> In-Reply-To: <20170206185015.12296-1-fu.wei@linaro.org> References: <20170206185015.12296-1-fu.wei@linaro.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Mon, 06 Feb 2017 18:53:13 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Fu Wei This driver adds support for parsing SBSA Generic Watchdog timer in GTDT, parse all info in SBSA Generic Watchdog Structure in GTDT, and creating a platform device with that information. This allows the operating system to obtain device data from the resource of platform device. The platform device named "sbsa-gwdt" can be used by the ARM SBSA Generic Watchdog driver. Signed-off-by: Fu Wei Signed-off-by: Hanjun Guo Tested-by: Xiongfeng Wang --- drivers/acpi/arm64/gtdt.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/watchdog/Kconfig | 1 + 2 files changed, 94 insertions(+) -- 2.9.3 diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c index 29b9acc..3a2eb57 100644 --- a/drivers/acpi/arm64/gtdt.c +++ b/drivers/acpi/arm64/gtdt.c @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -59,6 +60,13 @@ static inline bool is_timer_block(void *platform_timer) return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK; } +static inline bool is_watchdog(void *platform_timer) +{ + struct acpi_gtdt_header *gh = platform_timer; + + return gh->type == ACPI_GTDT_TYPE_WATCHDOG; +} + static int __init map_gt_gsi(u32 interrupt, u32 flags) { int trigger, polarity; @@ -283,3 +291,88 @@ int __init acpi_arch_timer_mem_init(struct arch_timer_mem *data, return 0; } + +/* + * Initialize a SBSA generic Watchdog platform device info from GTDT + */ +static int __init gtdt_import_sbsa_gwdt(struct acpi_gtdt_watchdog *wd, + int index) +{ + struct platform_device *pdev; + int irq = map_gt_gsi(wd->timer_interrupt, wd->timer_flags); + int no_irq = 1; + + /* + * According to SBSA specification the size of refresh and control + * frames of SBSA Generic Watchdog is SZ_4K(Offset 0x000 – 0xFFF). + */ + struct resource res[] = { + DEFINE_RES_MEM(wd->control_frame_address, SZ_4K), + DEFINE_RES_MEM(wd->refresh_frame_address, SZ_4K), + DEFINE_RES_IRQ(irq), + }; + + pr_debug("found a Watchdog (0x%llx/0x%llx gsi:%u flags:0x%x).\n", + wd->refresh_frame_address, wd->control_frame_address, + wd->timer_interrupt, wd->timer_flags); + + if (!(wd->refresh_frame_address && wd->control_frame_address)) { + pr_err(FW_BUG "failed to get the Watchdog base address.\n"); + return -EINVAL; + } + + if (!wd->timer_interrupt) + pr_warn(FW_BUG "failed to get the Watchdog interrupt.\n"); + else if (irq <= 0) + pr_warn("failed to map the Watchdog interrupt.\n"); + else + no_irq = 0; + + /* + * Add a platform device named "sbsa-gwdt" to match the platform driver. + * "sbsa-gwdt": SBSA(Server Base System Architecture) Generic Watchdog + * The platform driver (like drivers/watchdog/sbsa_gwdt.c)can get device + * info below by matching this name. + */ + pdev = platform_device_register_simple("sbsa-gwdt", index, res, + ARRAY_SIZE(res) - no_irq); + if (IS_ERR(pdev)) { + acpi_unregister_gsi(wd->timer_interrupt); + return PTR_ERR(pdev); + } + + return 0; +} + +static int __init gtdt_sbsa_gwdt_init(void) +{ + int ret, i = 0; + void *platform_timer; + struct acpi_table_header *table; + + if (acpi_disabled) + return 0; + + if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_GTDT, 0, &table))) + return -EINVAL; + + ret = acpi_gtdt_init(table, NULL); + if (ret) + return ret; + + for_each_platform_timer(platform_timer) { + if (is_watchdog(platform_timer)) { + ret = gtdt_import_sbsa_gwdt(platform_timer, i); + if (ret) + break; + i++; + } + } + + if (i) + pr_info("found %d SBSA generic Watchdog(s).\n", i); + + return ret; +} + +device_initcall(gtdt_sbsa_gwdt_init); diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index acb00b5..c899df1 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -219,6 +219,7 @@ config ARM_SBSA_WATCHDOG tristate "ARM SBSA Generic Watchdog" depends on ARM64 depends on ARM_ARCH_TIMER + depends on ACPI_GTDT || !ACPI select WATCHDOG_CORE help ARM SBSA Generic Watchdog has two stage timeouts: