From patchwork Tue Mar 24 17:43:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 202879 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3E646C2BAEE for ; Tue, 24 Mar 2020 17:45:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1A04C206F6 for ; Tue, 24 Mar 2020 17:45:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727273AbgCXRo7 (ORCPT ); Tue, 24 Mar 2020 13:44:59 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:42882 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727304AbgCXRo7 (ORCPT ); Tue, 24 Mar 2020 13:44:59 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id A1AF880307CB; Tue, 24 Mar 2020 17:44:52 +0000 (UTC) X-Virus-Scanned: amavisd-new at baikalelectronics.ru Received: from mail.baikalelectronics.ru ([127.0.0.1]) by localhost (mail.baikalelectronics.ru [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id KXsgvLYIv_Vq; Tue, 24 Mar 2020 20:44:51 +0300 (MSK) From: To: Alessandro Zummo , Alexandre Belloni , Rob Herring , Mark Rutland CC: Serge Semin , Serge Semin , Alexey Malahov , Thomas Bogendoerfer , Paul Burton , Ralf Baechle , Daniel Lezcano , Thomas Gleixner , Arnd Bergmann , Andy Shevchenko , , , Subject: [PATCH v2 1/6] dt-bindings: rtc: Convert snps, dw-apb-timer to DT schema Date: Tue, 24 Mar 2020 20:43:20 +0300 Message-ID: <20200324174325.14213-2-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20200324174325.14213-1-Sergey.Semin@baikalelectronics.ru> References: <20200306125622.839ED80307C4@mail.baikalelectronics.ru> <20200324174325.14213-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Serge Semin Modern device tree bindings are supposed to be created as YAML-files in accordance with DT schema. This commit replaces Synopsys DW Timer legacy bare text binding with YAML file. As before the binding file states that the corresponding dts node is supposed to be compatible with generic DW APB Timer indicated by the "snps,dw-apb-timer" compatible string and to provide a mandatory registers memory range, one timer interrupt, either reference clock source or a fixed clock rate value. It may also have an optional APB bus reference clock phandle specified. Signed-off-by: Serge Semin Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Paul Burton Cc: Ralf Baechle Cc: Alessandro Zummo Cc: Alexandre Belloni Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Arnd Bergmann Cc: Andy Shevchenko Cc: Rob Herring Cc: Mark Rutland Cc: devicetree@vger.kernel.org Cc: linux-rtc@vger.kernel.org --- I have doubts that this binding file belongs to the bindings/rtc directory seeing it's a pure timer with no rtc facilities like days/months/years counting and alarms. What about moving it to the "Documentation/devicetree/bindings/timer/" directory? I also don't know who is the corresponding driver maintainer, so I added Daniel Lezcano to the maintainers schema. Any idea what email should be specified there instead? Please also note, that "oneOf: - required: ..." pattern isn't working here. So if you omit any of the clock-related property the dt_binding_check procedure won't fail. Seeing the anyOf schema is working I suppose this happens due to the dtschema/lib.py script, which replaces the global oneOf with a fixup for the interrupts/interrupts-extended properties: > def fixup_interrupts(schema): > # Supporting 'interrupts' implies 'interrupts-extended' is also supported. > if not 'interrupts' in schema['properties'].keys(): > return > > # Any node with 'interrupts' can have 'interrupt-parent' > schema['properties']['interrupt-parent'] = True > > schema['properties']['interrupts-extended'] = { "$ref": "#/properties/interrupts" }; > > if not ('required' in schema.keys() and 'interrupts' in schema['required']): > return > !> # Currently no better way to express either 'interrupts' or 'interrupts-extended' !> # is required. If this fails validation, the error reporting is the whole !> # schema file fails validation !> schema['oneOf'] = [ {'required': ['interrupts']}, {'required': ['interrupts-extended']} ] --- .../devicetree/bindings/rtc/dw-apb.txt | 32 ------- .../bindings/rtc/snps,dw-apb-timer.yaml | 88 +++++++++++++++++++ 2 files changed, 88 insertions(+), 32 deletions(-) delete mode 100644 Documentation/devicetree/bindings/rtc/dw-apb.txt create mode 100644 Documentation/devicetree/bindings/rtc/snps,dw-apb-timer.yaml diff --git a/Documentation/devicetree/bindings/rtc/dw-apb.txt b/Documentation/devicetree/bindings/rtc/dw-apb.txt deleted file mode 100644 index c703d51abb6c..000000000000 --- a/Documentation/devicetree/bindings/rtc/dw-apb.txt +++ /dev/null @@ -1,32 +0,0 @@ -* Designware APB timer - -Required properties: -- compatible: One of: - "snps,dw-apb-timer" - "snps,dw-apb-timer-sp" - "snps,dw-apb-timer-osc" -- reg: physical base address of the controller and length of memory mapped - region. -- interrupts: IRQ line for the timer. -- either clocks+clock-names or clock-frequency properties - -Optional properties: -- clocks : list of clock specifiers, corresponding to entries in - the clock-names property; -- clock-names : should contain "timer" and "pclk" entries, matching entries - in the clocks property. -- clock-frequency: The frequency in HZ of the timer. -- clock-freq: For backwards compatibility with picoxcell - -If using the clock specifiers, the pclk clock is optional, as not all -systems may use one. - - -Example: - timer@ffe00000 { - compatible = "snps,dw-apb-timer"; - interrupts = <0 170 4>; - reg = <0xffe00000 0x1000>; - clocks = <&timer_clk>, <&timer_pclk>; - clock-names = "timer", "pclk"; - }; diff --git a/Documentation/devicetree/bindings/rtc/snps,dw-apb-timer.yaml b/Documentation/devicetree/bindings/rtc/snps,dw-apb-timer.yaml new file mode 100644 index 000000000000..88d939ed1b0b --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/snps,dw-apb-timer.yaml @@ -0,0 +1,88 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/snps,dw-apb-timer.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Synopsys DesignWare APB Timer + +maintainers: + - Daniel Lezcano + +properties: + compatible: + oneOf: + - const: snps,dw-apb-timer + - enum: + - snps,dw-apb-timer-sp + - snps,dw-apb-timer-osc + deprecated: true + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + minItems: 1 + items: + - description: Timer ticks reference clock source + - description: APB interface clock source + + clock-names: + minItems: 1 + items: + - const: timer + - const: pclk + + clock-frequency: true + + clock-freq: + $ref: "/schemas/types.yaml#/definitions/uint32" + description: | + Has the same meaning as the 'clock-frequency' property - timer clock + frequency in HZ, but is defined only for the backwards compatibility + with the picoxcell platform. + +additionalProperties: false + +required: + - compatible + - reg + - interrupts + +oneOf: + - required: + - clocks + - clock-names + - required: + - clock-frequency + - required: + - clock-freq + +examples: + - | + timer@ffe00000 { + compatible = "snps,dw-apb-timer"; + interrupts = <0 170 4>; + reg = <0xffe00000 0x1000>; + clocks = <&timer_clk>, <&timer_pclk>; + clock-names = "timer", "pclk"; + }; + - | + timer@ffe00000 { + compatible = "snps,dw-apb-timer"; + interrupts = <0 170 4>; + reg = <0xffe00000 0x1000>; + clocks = <&timer_clk>; + clock-names = "timer"; + }; + - | + timer@ffe00000 { + compatible = "snps,dw-apb-timer"; + interrupts = <0 170 4>; + reg = <0xffe00000 0x1000>; + clock-frequency = <25000000>; + }; +... From patchwork Wed May 6 21:41:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 200989 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4873CC38A2A for ; Wed, 6 May 2020 21:41:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 252EB2070B for ; Wed, 6 May 2020 21:41:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730137AbgEFVle (ORCPT ); Wed, 6 May 2020 17:41:34 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:33866 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729600AbgEFVle (ORCPT ); Wed, 6 May 2020 17:41:34 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 9712E8030808; Wed, 6 May 2020 21:41:30 +0000 (UTC) X-Virus-Scanned: amavisd-new at baikalelectronics.ru Received: from mail.baikalelectronics.ru ([127.0.0.1]) by localhost (mail.baikalelectronics.ru [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id eEFPn27T9Bdr; Thu, 7 May 2020 00:41:29 +0300 (MSK) From: Serge Semin To: Thomas Bogendoerfer , Alessandro Zummo , Alexandre Belloni , Rob Herring , Daniel Lezcano , Thomas Gleixner CC: Serge Semin , Serge Semin , Alexey Malahov , Paul Burton , Ralf Baechle , Arnd Bergmann , , Rob Herring , , , Subject: [PATCH v3 2/7] dt-bindings: timer: Move snps, dw-apb-timer DT schema from rtc Date: Thu, 7 May 2020 00:41:02 +0300 Message-ID: <20200506214107.25956-3-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20200506214107.25956-1-Sergey.Semin@baikalelectronics.ru> References: <20200324174325.14213-1-Sergey.Semin@baikalelectronics.ru> <20200506214107.25956-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This binding file doesn't belong to the rtc seeing it's a pure timer with no rtc facilities like days/months/years counting and alarms. So move the YAML-file to the Documentation/devicetree/bindings/timer/ directory. Signed-off-by: Serge Semin Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Paul Burton Cc: Ralf Baechle Cc: Arnd Bergmann Cc: linux-mips@vger.kernel.org --- .../devicetree/bindings/{rtc => timer}/snps,dw-apb-timer.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename Documentation/devicetree/bindings/{rtc => timer}/snps,dw-apb-timer.yaml (96%) diff --git a/Documentation/devicetree/bindings/rtc/snps,dw-apb-timer.yaml b/Documentation/devicetree/bindings/timer/snps,dw-apb-timer.yaml similarity index 96% rename from Documentation/devicetree/bindings/rtc/snps,dw-apb-timer.yaml rename to Documentation/devicetree/bindings/timer/snps,dw-apb-timer.yaml index 002fe1ee709b..5d300efdf0ca 100644 --- a/Documentation/devicetree/bindings/rtc/snps,dw-apb-timer.yaml +++ b/Documentation/devicetree/bindings/timer/snps,dw-apb-timer.yaml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only %YAML 1.2 --- -$id: http://devicetree.org/schemas/rtc/snps,dw-apb-timer.yaml# +$id: http://devicetree.org/schemas/timer/snps,dw-apb-timer.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Synopsys DesignWare APB Timer From patchwork Tue Mar 24 17:43:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 202881 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C5202C54EEB for ; Tue, 24 Mar 2020 17:45:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9D976206F6 for ; Tue, 24 Mar 2020 17:45:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727848AbgCXRpC (ORCPT ); Tue, 24 Mar 2020 13:45:02 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:42944 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727304AbgCXRpC (ORCPT ); Tue, 24 Mar 2020 13:45:02 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id CF7728030786; Tue, 24 Mar 2020 17:44:59 +0000 (UTC) X-Virus-Scanned: amavisd-new at baikalelectronics.ru Received: from mail.baikalelectronics.ru ([127.0.0.1]) by localhost (mail.baikalelectronics.ru [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Ay0uddZimZzh; Tue, 24 Mar 2020 20:44:59 +0300 (MSK) From: To: Daniel Lezcano , Thomas Gleixner CC: Serge Semin , Serge Semin , Alexey Malahov , Thomas Bogendoerfer , Paul Burton , Ralf Baechle , Arnd Bergmann , Andy Shevchenko , Rob Herring , Mark Rutland , , Greg Kroah-Hartman , Allison Randal , Enrico Weigelt , Alexios Zavras , Kate Stewart , Subject: [PATCH v2 3/6] clocksource: dw_apb_timer: Set clockevent any-possible-CPU mask Date: Tue, 24 Mar 2020 20:43:22 +0300 Message-ID: <20200324174325.14213-4-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20200324174325.14213-1-Sergey.Semin@baikalelectronics.ru> References: <20200306125622.839ED80307C4@mail.baikalelectronics.ru> <20200324174325.14213-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Serge Semin Currently the DW APB Timer driver binds all clockevent timers to CPU #0. This isn't good for multiple reasons. First of all seeing the device is placed on APB bus (which makes it accessible from any CPU core), accessible over MMIO and having the DYNIRQ flag set we can be sure that manually binding the timer to any CPU just isn't correct. By doing so we just set an extra limitation on device usage. This also doesn't reflect the device actual capability, since by setting the IRQ affinity we can make it virtually local to any CPU. Secondly imagine if you had a real CPU-local timer with the same rating and the same CPU-affinity. In this case if DW APB timer was registered first, then due to the clockevent framework tick-timer selection procedure we'll end up with the real CPU-local timer being left unselected for clock-events tracking. But on most of the platforms (MIPS/ARM/etc) such timers are normally embedded into the CPU core and are accessible with much better performance then devices placed on APB. For instance in MIPS architectures there is r4k-timer, which is CPU-local, assigned with the same rating, and normally its clockevent device is registered after the platform-specific one. So in order to fix all of these issues lets set the DW APB clockevent timer cpumask to be 'cpu_possible_mask'. By doing so the clockevent framework would prefer to select the real CPU-local timer instead of DW APB one. Otherwise if there is no other than DW APB device for clockevents tracking then it will be selected. Signed-off-by: Serge Semin Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Paul Burton Cc: Ralf Baechle Cc: Thomas Gleixner Cc: Arnd Bergmann Cc: Andy Shevchenko Cc: Rob Herring Cc: Mark Rutland Cc: devicetree@vger.kernel.org --- drivers/clocksource/dw_apb_timer.c | 18 +++++++----------- drivers/clocksource/dw_apb_timer_of.c | 3 +-- include/linux/dw_apb_timer.h | 2 +- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/clocksource/dw_apb_timer.c b/drivers/clocksource/dw_apb_timer.c index 654766538f93..f213bcb4cf71 100644 --- a/drivers/clocksource/dw_apb_timer.c +++ b/drivers/clocksource/dw_apb_timer.c @@ -106,6 +106,7 @@ static irqreturn_t dw_apb_clockevent_irq(int irq, void *data) dw_ced->eoi(&dw_ced->timer); evt->event_handler(evt); + return IRQ_HANDLED; } @@ -123,8 +124,7 @@ static int apbt_shutdown(struct clock_event_device *evt) struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); u32 ctrl; - pr_debug("%s CPU %d state=shutdown\n", __func__, - cpumask_first(evt->cpumask)); + pr_debug("%s state=shutdown\n", __func__); ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); ctrl &= ~APBTMR_CONTROL_ENABLE; @@ -137,8 +137,7 @@ static int apbt_set_oneshot(struct clock_event_device *evt) struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); u32 ctrl; - pr_debug("%s CPU %d state=oneshot\n", __func__, - cpumask_first(evt->cpumask)); + pr_debug("%s state=oneshot\n", __func__); ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); /* @@ -170,8 +169,7 @@ static int apbt_set_periodic(struct clock_event_device *evt) unsigned long period = DIV_ROUND_UP(dw_ced->timer.freq, HZ); u32 ctrl; - pr_debug("%s CPU %d state=periodic\n", __func__, - cpumask_first(evt->cpumask)); + pr_debug("%s state=periodic\n", __func__); ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); ctrl |= APBTMR_CONTROL_MODE_PERIODIC; @@ -194,8 +192,7 @@ static int apbt_resume(struct clock_event_device *evt) { struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); - pr_debug("%s CPU %d state=resume\n", __func__, - cpumask_first(evt->cpumask)); + pr_debug("%s state=resume\n", __func__); apbt_enable_int(&dw_ced->timer); return 0; @@ -222,7 +219,6 @@ static int apbt_next_event(unsigned long delta, /** * dw_apb_clockevent_init() - use an APB timer as a clock_event_device * - * @cpu: The CPU the events will be targeted at. * @name: The name used for the timer and the IRQ for it. * @rating: The rating to give the timer. * @base: I/O base for the timer registers. @@ -237,7 +233,7 @@ static int apbt_next_event(unsigned long delta, * releasing the IRQ. */ struct dw_apb_clock_event_device * -dw_apb_clockevent_init(int cpu, const char *name, unsigned rating, +dw_apb_clockevent_init(const char *name, unsigned int rating, void __iomem *base, int irq, unsigned long freq) { struct dw_apb_clock_event_device *dw_ced = @@ -257,7 +253,7 @@ dw_apb_clockevent_init(int cpu, const char *name, unsigned rating, dw_ced->ced.max_delta_ticks = 0x7fffffff; dw_ced->ced.min_delta_ns = clockevent_delta2ns(5000, &dw_ced->ced); dw_ced->ced.min_delta_ticks = 5000; - dw_ced->ced.cpumask = cpumask_of(cpu); + dw_ced->ced.cpumask = cpu_possible_mask; dw_ced->ced.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ; dw_ced->ced.set_state_shutdown = apbt_shutdown; diff --git a/drivers/clocksource/dw_apb_timer_of.c b/drivers/clocksource/dw_apb_timer_of.c index 8c28b127759f..0a2505b323d7 100644 --- a/drivers/clocksource/dw_apb_timer_of.c +++ b/drivers/clocksource/dw_apb_timer_of.c @@ -73,8 +73,7 @@ static void __init add_clockevent(struct device_node *event_timer) timer_get_base_and_rate(event_timer, &iobase, &rate); - ced = dw_apb_clockevent_init(0, event_timer->name, 300, iobase, irq, - rate); + ced = dw_apb_clockevent_init(event_timer->name, 300, iobase, irq, rate); if (!ced) panic("Unable to initialise clockevent device"); diff --git a/include/linux/dw_apb_timer.h b/include/linux/dw_apb_timer.h index 14f072edbca5..2f3597a199bb 100644 --- a/include/linux/dw_apb_timer.h +++ b/include/linux/dw_apb_timer.h @@ -40,7 +40,7 @@ void dw_apb_clockevent_resume(struct dw_apb_clock_event_device *dw_ced); void dw_apb_clockevent_stop(struct dw_apb_clock_event_device *dw_ced); struct dw_apb_clock_event_device * -dw_apb_clockevent_init(int cpu, const char *name, unsigned rating, +dw_apb_clockevent_init(const char *name, unsigned int rating, void __iomem *base, int irq, unsigned long freq); struct dw_apb_clocksource * dw_apb_clocksource_init(unsigned rating, const char *name, void __iomem *base, From patchwork Wed May 6 21:41:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 200987 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E632DC54E4A for ; Wed, 6 May 2020 21:42:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CF7C72076D for ; Wed, 6 May 2020 21:42:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730210AbgEFVlp (ORCPT ); Wed, 6 May 2020 17:41:45 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:33932 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729199AbgEFVln (ORCPT ); Wed, 6 May 2020 17:41:43 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id ECD7B80307C7; Wed, 6 May 2020 21:41:39 +0000 (UTC) X-Virus-Scanned: amavisd-new at baikalelectronics.ru Received: from mail.baikalelectronics.ru ([127.0.0.1]) by localhost (mail.baikalelectronics.ru [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DXaSAmVBtWQe; Thu, 7 May 2020 00:41:39 +0300 (MSK) From: Serge Semin To: Thomas Bogendoerfer , Daniel Lezcano , Thomas Gleixner CC: Serge Semin , Serge Semin , Alexey Malahov , Paul Burton , Ralf Baechle , Alessandro Zummo , Alexandre Belloni , Arnd Bergmann , Rob Herring , , , , Greg Kroah-Hartman , Kate Stewart , afzal mohammed , Enrico Weigelt , Allison Randal , Subject: [PATCH v3 4/7] clocksource: dw_apb_timer: Set clockevent any-possible-CPU mask Date: Thu, 7 May 2020 00:41:04 +0300 Message-ID: <20200506214107.25956-5-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20200506214107.25956-1-Sergey.Semin@baikalelectronics.ru> References: <20200324174325.14213-1-Sergey.Semin@baikalelectronics.ru> <20200506214107.25956-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Currently the DW APB Timer driver binds all clockevent timers to CPU #0. This isn't good for multiple reasons. First of all seeing the device is placed on APB bus (which makes it accessible from any CPU core), accessible over MMIO and having the DYNIRQ flag set we can be sure that manually binding the timer to any CPU just isn't correct. By doing so we just set an extra limitation on device usage. This also doesn't reflect the device actual capability, since by setting the IRQ affinity we can make it virtually local to any CPU. Secondly imagine if you had a real CPU-local timer with the same rating and the same CPU-affinity. In this case if DW APB timer was registered first, then due to the clockevent framework tick-timer selection procedure we'll end up with the real CPU-local timer being left unselected for clock-events tracking. But on most of the platforms (MIPS/ARM/etc) such timers are normally embedded into the CPU core and are accessible with much better performance then devices placed on APB. For instance in MIPS architectures there is r4k-timer, which is CPU-local, assigned with the same rating, and normally its clockevent device is registered after the platform-specific one. So in order to fix all of these issues lets set the DW APB clockevent timer cpumask to be 'cpu_possible_mask'. By doing so the clockevent framework would prefer to select the real CPU-local timer instead of DW APB one. Otherwise if there is no other than DW APB device for clockevents tracking then it will be selected. Signed-off-by: Serge Semin Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Paul Burton Cc: Ralf Baechle Cc: Alessandro Zummo Cc: Alexandre Belloni Cc: Arnd Bergmann Cc: Rob Herring Cc: linux-mips@vger.kernel.org Cc: linux-rtc@vger.kernel.org Cc: devicetree@vger.kernel.org --- drivers/clocksource/dw_apb_timer.c | 18 +++++++----------- drivers/clocksource/dw_apb_timer_of.c | 3 +-- include/linux/dw_apb_timer.h | 2 +- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/clocksource/dw_apb_timer.c b/drivers/clocksource/dw_apb_timer.c index b207a77b0831..8ebb43916423 100644 --- a/drivers/clocksource/dw_apb_timer.c +++ b/drivers/clocksource/dw_apb_timer.c @@ -106,6 +106,7 @@ static irqreturn_t dw_apb_clockevent_irq(int irq, void *data) dw_ced->eoi(&dw_ced->timer); evt->event_handler(evt); + return IRQ_HANDLED; } @@ -123,8 +124,7 @@ static int apbt_shutdown(struct clock_event_device *evt) struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); u32 ctrl; - pr_debug("%s CPU %d state=shutdown\n", __func__, - cpumask_first(evt->cpumask)); + pr_debug("%s state=shutdown\n", __func__); ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); ctrl &= ~APBTMR_CONTROL_ENABLE; @@ -137,8 +137,7 @@ static int apbt_set_oneshot(struct clock_event_device *evt) struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); u32 ctrl; - pr_debug("%s CPU %d state=oneshot\n", __func__, - cpumask_first(evt->cpumask)); + pr_debug("%s state=oneshot\n", __func__); ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); /* @@ -170,8 +169,7 @@ static int apbt_set_periodic(struct clock_event_device *evt) unsigned long period = DIV_ROUND_UP(dw_ced->timer.freq, HZ); u32 ctrl; - pr_debug("%s CPU %d state=periodic\n", __func__, - cpumask_first(evt->cpumask)); + pr_debug("%s state=periodic\n", __func__); ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); ctrl |= APBTMR_CONTROL_MODE_PERIODIC; @@ -194,8 +192,7 @@ static int apbt_resume(struct clock_event_device *evt) { struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); - pr_debug("%s CPU %d state=resume\n", __func__, - cpumask_first(evt->cpumask)); + pr_debug("%s state=resume\n", __func__); apbt_enable_int(&dw_ced->timer); return 0; @@ -222,7 +219,6 @@ static int apbt_next_event(unsigned long delta, /** * dw_apb_clockevent_init() - use an APB timer as a clock_event_device * - * @cpu: The CPU the events will be targeted at. * @name: The name used for the timer and the IRQ for it. * @rating: The rating to give the timer. * @base: I/O base for the timer registers. @@ -237,7 +233,7 @@ static int apbt_next_event(unsigned long delta, * releasing the IRQ. */ struct dw_apb_clock_event_device * -dw_apb_clockevent_init(int cpu, const char *name, unsigned rating, +dw_apb_clockevent_init(const char *name, unsigned int rating, void __iomem *base, int irq, unsigned long freq) { struct dw_apb_clock_event_device *dw_ced = @@ -257,7 +253,7 @@ dw_apb_clockevent_init(int cpu, const char *name, unsigned rating, dw_ced->ced.max_delta_ticks = 0x7fffffff; dw_ced->ced.min_delta_ns = clockevent_delta2ns(5000, &dw_ced->ced); dw_ced->ced.min_delta_ticks = 5000; - dw_ced->ced.cpumask = cpumask_of(cpu); + dw_ced->ced.cpumask = cpu_possible_mask; dw_ced->ced.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ; dw_ced->ced.set_state_shutdown = apbt_shutdown; diff --git a/drivers/clocksource/dw_apb_timer_of.c b/drivers/clocksource/dw_apb_timer_of.c index 8c28b127759f..0a2505b323d7 100644 --- a/drivers/clocksource/dw_apb_timer_of.c +++ b/drivers/clocksource/dw_apb_timer_of.c @@ -73,8 +73,7 @@ static void __init add_clockevent(struct device_node *event_timer) timer_get_base_and_rate(event_timer, &iobase, &rate); - ced = dw_apb_clockevent_init(0, event_timer->name, 300, iobase, irq, - rate); + ced = dw_apb_clockevent_init(event_timer->name, 300, iobase, irq, rate); if (!ced) panic("Unable to initialise clockevent device"); diff --git a/include/linux/dw_apb_timer.h b/include/linux/dw_apb_timer.h index 82ebf9223948..689022bc8d17 100644 --- a/include/linux/dw_apb_timer.h +++ b/include/linux/dw_apb_timer.h @@ -39,7 +39,7 @@ void dw_apb_clockevent_resume(struct dw_apb_clock_event_device *dw_ced); void dw_apb_clockevent_stop(struct dw_apb_clock_event_device *dw_ced); struct dw_apb_clock_event_device * -dw_apb_clockevent_init(int cpu, const char *name, unsigned rating, +dw_apb_clockevent_init(const char *name, unsigned int rating, void __iomem *base, int irq, unsigned long freq); struct dw_apb_clocksource * dw_apb_clocksource_init(unsigned rating, const char *name, void __iomem *base, From patchwork Wed May 6 21:41:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 200988 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7D12CC54E7F for ; Wed, 6 May 2020 21:42:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6253D2078C for ; Wed, 6 May 2020 21:42:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730252AbgEFVls (ORCPT ); Wed, 6 May 2020 17:41:48 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:34002 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729600AbgEFVlr (ORCPT ); Wed, 6 May 2020 17:41:47 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 1458080307C2; Wed, 6 May 2020 21:41:44 +0000 (UTC) X-Virus-Scanned: amavisd-new at baikalelectronics.ru Received: from mail.baikalelectronics.ru ([127.0.0.1]) by localhost (mail.baikalelectronics.ru [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id eu4OaYG3xEuT; Thu, 7 May 2020 00:41:43 +0300 (MSK) From: Serge Semin To: Thomas Bogendoerfer , Daniel Lezcano , Thomas Gleixner CC: Serge Semin , Serge Semin , Paul Burton , Alexey Malahov , Ralf Baechle , Alessandro Zummo , Alexandre Belloni , Arnd Bergmann , Rob Herring , , , , Vincenzo Frascino , Subject: [PATCH v3 6/7] clocksource: mips-gic-timer: Register as sched_clock Date: Thu, 7 May 2020 00:41:06 +0300 Message-ID: <20200506214107.25956-7-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20200506214107.25956-1-Sergey.Semin@baikalelectronics.ru> References: <20200324174325.14213-1-Sergey.Semin@baikalelectronics.ru> <20200506214107.25956-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Paul Burton From: Paul Burton The MIPS GIC timer is well suited for use as sched_clock, so register it as such. Whilst the existing gic_read_count() function matches the prototype needed by sched_clock_register() already, we split it into 2 functions in order to remove the need to evaluate the mips_cm_is64 condition within each call since sched_clock should be as fast as possible. Signed-off-by: Paul Burton Signed-off-by: Serge Semin Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Ralf Baechle Cc: Alessandro Zummo Cc: Alexandre Belloni Cc: Arnd Bergmann Cc: Rob Herring Cc: linux-mips@vger.kernel.org Cc: linux-rtc@vger.kernel.org Cc: devicetree@vger.kernel.org --- drivers/clocksource/mips-gic-timer.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index 8b5f8ae723cb..802b93fe3ae7 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -24,13 +25,10 @@ static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); static int gic_timer_irq; static unsigned int gic_frequency; -static u64 notrace gic_read_count(void) +static u64 notrace gic_read_count_2x32(void) { unsigned int hi, hi2, lo; - if (mips_cm_is64) - return read_gic_counter(); - do { hi = read_gic_counter_32h(); lo = read_gic_counter_32l(); @@ -40,6 +38,19 @@ static u64 notrace gic_read_count(void) return (((u64) hi) << 32) + lo; } +static u64 notrace gic_read_count_64(void) +{ + return read_gic_counter(); +} + +static u64 notrace gic_read_count(void) +{ + if (mips_cm_is64) + return gic_read_count_64(); + + return gic_read_count_2x32(); +} + static int gic_next_event(unsigned long delta, struct clock_event_device *evt) { int cpu = cpumask_first(evt->cpumask); @@ -228,6 +239,10 @@ static int __init gic_clocksource_of_init(struct device_node *node) /* And finally start the counter */ clear_gic_config(GIC_CONFIG_COUNTSTOP); + sched_clock_register(mips_cm_is64 ? + gic_read_count_64 : gic_read_count_2x32, + 64, gic_frequency); + return 0; } TIMER_OF_DECLARE(mips_gic_timer, "mti,gic-timer",