All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
@ 2017-03-21 16:31 ` fu.wei
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei-QSEj5FYQhm4dnm+yROfE0A @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ, marc.zyngier-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, lorenzo.pieralisi-5wv7dgnIgG8,
	sudeep.holla-5wv7dgnIgG8, hanjun.guo-QSEj5FYQhm4dnm+yROfE0A
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linaro-acpi-cunTk1MwBs8s++Sfvej+rw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	rruigrok-sgV2jX0FEOL9JmXXK+q4OQ, harba-sgV2jX0FEOL9JmXXK+q4OQ,
	cov-sgV2jX0FEOL9JmXXK+q4OQ, timur-sgV2jX0FEOL9JmXXK+q4OQ,
	graeme.gregory-QSEj5FYQhm4dnm+yROfE0A,
	al.stone-QSEj5FYQhm4dnm+yROfE0A, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	wei-H+wXaHxf7aLQT0dZR+AlfA, arnd-r2nGTMty4D4,
	catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	Suravee.Suthikulpanit-5C7GfCeVMHo, leo.duran-5C7GfCeVMHo,
	wim-IQzOog9fTRqzQB+pC5nmwQ, linux-0h96xk9xTtrk1uMJSBkQmQ,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	christoffer.dall-QSEj5FYQhm4dnm+yROfE0A,
	julien.grall-5wv7dgnIgG8, Fu Wei

From: Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

This patchset:
    (1)Preparation for adding GTDT support in arm_arch_timer:
        1. Introduce a wrapper function to get the frequency from mmio.
        2. separate out device-tree code from arch_timer_detect_rate
        3. remove arch_timer_detect_rate use arch_timer_*get_cntfrq directly
        4. Refactor arch_timer_needs_probing, and move it into DT init call
        5. Introduce some new structs and refactor the MMIO timer init code
        for reusing some common code.

    (2)Introduce ACPI GTDT parser: drivers/acpi/arm64/acpi_gtdt.c
    Parse all kinds of timer in GTDT table of ACPI:arch timer,
    memory-mapped timer and SBSA Generic Watchdog timer.
    This driver can help to simplify all the relevant timer drivers,
    and separate all the ACPI GTDT knowledge from them.

    (3)Simplify ACPI code for arm_arch_timer

    (4)Add GTDT support for ARM memory-mapped timer.

This patchset has been tested on the following platforms with ACPI enabled:
    (1)ARM Foundation v8 model

Changelog:
v22: https://lkml.org/lkml/2017/3/21/
     Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arch-timer/cleanup
     Only Introduce arch_timer_mem_get_cntfrq to get the frequency from mmio.
     Merged patch 2,3(about arch_timer_detect_rate).
     Keep arch_timer_rate, do NOT split it for different types of timer.
     Improve  memory-mapped timer support by comments and variable name:
         data-->timer_mem
         frame-->gtdt_frame
     Delete zero check for SBSA watchdog irq.
     Skip secure SBSA watchdog in GTDT driver.
     Delete Kconfig modification for SBSA watchdog driver.
     Delete no_irq, using nr_res instead.

v21: https://lkml.org/lkml/2017/2/6/734
     Introduce two functions to get the frequency from mmio and sysreg.
     Remove arch_timer_detect_rate use arch_timer_get_*_freq directly
     Split arch_timer_rate for different types of timer.
     Skip secure timer frame in GTDT driver.
     Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arch-timer/cleanup
     (The first 6 patches in v20 have been merged into arch-timer/cleanup branch)

v20: https://lkml.org/lkml/2017/1/18/534
     Reorder the first 4 patches and split the 4th patches.
     Leave CNTHCTL_* as they originally were.
     Fix the bug in arch_timer_select_ppi.
     Split "Rework counter frequency detection" patch.
     Rework the arch_timer_detect_rate function.
     Improve the commit message of "Refactor MMIO timer probing".
     Rebase to 4.10.0-rc4

v19: https://lkml.org/lkml/2016/12/21/25
     Fix a '\n' missing in a error message in arch_timer_mem_init.
     Add "request_mem_region" for ioremapping cntbase, according to
     f947ee1 clocksource/drivers/arm_arch_timer: Map frame with of_io_request_and_map()
     Rebase to 4.9.0-gfb779ff

v18: https://lkml.org/lkml/2016/12/8/446
     Fix 8/15 patch problem of "int ret;" in arch_timer_acpi_init.
     Rebase to 4.9.0-rc8-g9269898

v17: https://lkml.org/lkml/2016/11/25/140
     Take out some cleanups from 4/15.
     Merge 5/15 and 6/15, improve PPI determination code,
     improve commit message.
     Rework counter frequency detection.
     Move arch_timer_needs_of_probing into DT init call.
     Move Platform Timer scan loop back to timer init call to avoid allocating
     and free memory.
     Improve all the exported functions' comment.

v16: https://lkml.org/lkml/2016/11/16/268
     Fix patchset problem about static enum ppi_nr of 01/13 in v15.
     Refactor arch_timer_detect_rate.
     Refactor arch_timer_needs_probing.

v15: https://lkml.org/lkml/2016/11/15/366
     Re-order patches
     Add arm_arch_timer refactoring patches to prepare for GTDT:
         1. rename some  enums and defines, and some cleanups
         2. separate out arch_timer_uses_ppi init code and fix a potential bug
         3. Improve some new structs, refactor the timer init code.
     Since the some structs have been changed, GTDT parser for memory-mapped
     timer and SBSA Generic Watchdog timer have been update.

v14: https://lkml.org/lkml/2016/9/28/573
     Separate memory-mapped timer GTDT support into two patches
         1. Refactor the timer init code to prepare for GTDT
         2. Add GTDT support for memory-mapped timer

v13: http://www.mail-archive.com/linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org/msg1231717.html
     Improve arm_arch_timer code for memory-mapped
     timer GTDT support, refactor original memory-mapped timer
     dt support for reusing some common code.

v12: https://lkml.org/lkml/2016/9/13/250
     Rebase to latest Linux 4.8-rc6
     Delete the confusing "skipping" in the error message.

V11: https://lkml.org/lkml/2016/9/6/354
     Rebase to latest Linux 4.8-rc5
     Delete typedef (suggested by checkpatch.pl)

V10: https://lkml.org/lkml/2016/7/26/215
     Drop the "readq" patch.
     Rebase to latest Linux 4.7.

V9: https://lkml.org/lkml/2016/7/25/345
    Improve pr_err message in acpi gtdt driver.
    Update Commit message for 7/9
    shorten the irq mapping function name
    Improve GTDT driver for memory-mapped timer

v8: https://lkml.org/lkml/2016/7/19/660
    Improve "pr_fmt(fmt)" definition: add "ACPI" in front of "GTDT",
    and also improve printk message.
    Simplify is_timer_block and is_watchdog.
    Merge acpi_gtdt_desc_init and gtdt_arch_timer_init into acpi_gtdt_init();
    Delete __init in include/linux/acpi.h for GTDT API
    Make ARM64 select GTDT.
    Delete "#include <linux/module.h>" from acpi_gtdt.c
    Simplify GT block parse code.

v7: https://lkml.org/lkml/2016/7/13/769
    Move the GTDT driver to drivers/acpi/arm64
    Add add the ARM64-specific ACPI Support maintainers in MAINTAINERS
    Merge 3 patches of GTDT parser driver.
    Fix the for_each_platform_timer bug.

v6: https://lkml.org/lkml/2016/6/29/580
    split the GTDT driver to 4 parts: basic, arch_timer, memory-mapped timer,
    and SBSA Generic Watchdog timer
    Improve driver by suggestions and example code from Daniel Lezcano

v5: https://lkml.org/lkml/2016/5/24/356
    Sorting out all patches, simplify the API of GTDT driver:
    GTDT driver just fills the data struct for arm_arch_timer driver.

v4: https://lists.linaro.org/pipermail/linaro-acpi/2016-March/006667.html
    Delete the kvm relevant patches
    Separate two patches for sorting out the code for arm_arch_timer.
    Improve irq info export code to allow missing irq info in GTDT table.

v3: https://lkml.org/lkml/2016/2/1/658
    Improve GTDT driver code:
      (1)improve pr_* by defining pr_fmt(fmt)
      (2)simplify gtdt_sbsa_gwdt_init
      (3)improve gtdt_arch_timer_data_init, if table is NULL, it will try
      to get GTDT table.
    Move enum ppi_nr to arm_arch_timer.h, and add enum spi_nr.
    Add arm_arch_timer get ppi from DT and GTDT support for kvm.

v2: https://lkml.org/lkml/2015/12/2/10
    Rebase to latest kernel version(4.4-rc3).
    Fix the bug about the config problem,
    use CONFIG_ACPI_GTDT instead of CONFIG_ACPI in arm_arch_timer.c

v1: The first upstreaming version: https://lkml.org/lkml/2015/10/28/553

Fu Wei (11):
  clocksource: arm_arch_timer: introduce a wrapper function to get the
    frequency from mmio.
  clocksource: arm_arch_timer: separate out device-tree code and remove
    arch_timer_detect_rate
  clocksource: arm_arch_timer: refactor arch_timer_needs_probing
  clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT
    init call
  clocksource: arm_arch_timer: introduce some new structs to prepare for
    GTDT
  clocksource: arm_arch_timer: refactor MMIO timer probing.
  acpi/arm64: Add GTDT table parse driver
  clocksource: arm_arch_timer: simplify ACPI support code.
  acpi/arm64: Add memory-mapped timer support in GTDT driver
  clocksource: arm_arch_timer: add GTDT support for memory-mapped timer
  acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver

 arch/arm64/Kconfig                   |   1 +
 drivers/acpi/arm64/Kconfig           |   3 +
 drivers/acpi/arm64/Makefile          |   1 +
 drivers/acpi/arm64/gtdt.c            | 381 +++++++++++++++++++++++++++++++++++
 drivers/clocksource/arm_arch_timer.c | 326 +++++++++++++++++++-----------
 include/clocksource/arm_arch_timer.h |  17 ++
 include/linux/acpi.h                 |   7 +
 7 files changed, 614 insertions(+), 122 deletions(-)
 create mode 100644 drivers/acpi/arm64/gtdt.c

-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
@ 2017-03-21 16:31 ` fu.wei
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	lorenzo.pieralisi, sudeep.holla, hanjun.guo
  Cc: linux-arm-kernel, linaro-acpi, linux-kernel, linux-acpi,
	rruigrok, harba, cov, timur, graeme.gregory, al.stone, jcm, wei,
	arnd, catalin.marinas, will.deacon, Suravee.Suthikulpanit,
	leo.duran, wim, linux, linux-watchdog, tn, christoffer.dall,
	julien.grall, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

This patchset:
    (1)Preparation for adding GTDT support in arm_arch_timer:
        1. Introduce a wrapper function to get the frequency from mmio.
        2. separate out device-tree code from arch_timer_detect_rate
        3. remove arch_timer_detect_rate use arch_timer_*get_cntfrq directly
        4. Refactor arch_timer_needs_probing, and move it into DT init call
        5. Introduce some new structs and refactor the MMIO timer init code
        for reusing some common code.

    (2)Introduce ACPI GTDT parser: drivers/acpi/arm64/acpi_gtdt.c
    Parse all kinds of timer in GTDT table of ACPI:arch timer,
    memory-mapped timer and SBSA Generic Watchdog timer.
    This driver can help to simplify all the relevant timer drivers,
    and separate all the ACPI GTDT knowledge from them.

    (3)Simplify ACPI code for arm_arch_timer

    (4)Add GTDT support for ARM memory-mapped timer.

This patchset has been tested on the following platforms with ACPI enabled:
    (1)ARM Foundation v8 model

Changelog:
v22: https://lkml.org/lkml/2017/3/21/
     Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arch-timer/cleanup
     Only Introduce arch_timer_mem_get_cntfrq to get the frequency from mmio.
     Merged patch 2,3(about arch_timer_detect_rate).
     Keep arch_timer_rate, do NOT split it for different types of timer.
     Improve  memory-mapped timer support by comments and variable name:
         data-->timer_mem
         frame-->gtdt_frame
     Delete zero check for SBSA watchdog irq.
     Skip secure SBSA watchdog in GTDT driver.
     Delete Kconfig modification for SBSA watchdog driver.
     Delete no_irq, using nr_res instead.

v21: https://lkml.org/lkml/2017/2/6/734
     Introduce two functions to get the frequency from mmio and sysreg.
     Remove arch_timer_detect_rate use arch_timer_get_*_freq directly
     Split arch_timer_rate for different types of timer.
     Skip secure timer frame in GTDT driver.
     Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arch-timer/cleanup
     (The first 6 patches in v20 have been merged into arch-timer/cleanup branch)

v20: https://lkml.org/lkml/2017/1/18/534
     Reorder the first 4 patches and split the 4th patches.
     Leave CNTHCTL_* as they originally were.
     Fix the bug in arch_timer_select_ppi.
     Split "Rework counter frequency detection" patch.
     Rework the arch_timer_detect_rate function.
     Improve the commit message of "Refactor MMIO timer probing".
     Rebase to 4.10.0-rc4

v19: https://lkml.org/lkml/2016/12/21/25
     Fix a '\n' missing in a error message in arch_timer_mem_init.
     Add "request_mem_region" for ioremapping cntbase, according to
     f947ee1 clocksource/drivers/arm_arch_timer: Map frame with of_io_request_and_map()
     Rebase to 4.9.0-gfb779ff

v18: https://lkml.org/lkml/2016/12/8/446
     Fix 8/15 patch problem of "int ret;" in arch_timer_acpi_init.
     Rebase to 4.9.0-rc8-g9269898

v17: https://lkml.org/lkml/2016/11/25/140
     Take out some cleanups from 4/15.
     Merge 5/15 and 6/15, improve PPI determination code,
     improve commit message.
     Rework counter frequency detection.
     Move arch_timer_needs_of_probing into DT init call.
     Move Platform Timer scan loop back to timer init call to avoid allocating
     and free memory.
     Improve all the exported functions' comment.

v16: https://lkml.org/lkml/2016/11/16/268
     Fix patchset problem about static enum ppi_nr of 01/13 in v15.
     Refactor arch_timer_detect_rate.
     Refactor arch_timer_needs_probing.

v15: https://lkml.org/lkml/2016/11/15/366
     Re-order patches
     Add arm_arch_timer refactoring patches to prepare for GTDT:
         1. rename some  enums and defines, and some cleanups
         2. separate out arch_timer_uses_ppi init code and fix a potential bug
         3. Improve some new structs, refactor the timer init code.
     Since the some structs have been changed, GTDT parser for memory-mapped
     timer and SBSA Generic Watchdog timer have been update.

v14: https://lkml.org/lkml/2016/9/28/573
     Separate memory-mapped timer GTDT support into two patches
         1. Refactor the timer init code to prepare for GTDT
         2. Add GTDT support for memory-mapped timer

v13: http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1231717.html
     Improve arm_arch_timer code for memory-mapped
     timer GTDT support, refactor original memory-mapped timer
     dt support for reusing some common code.

v12: https://lkml.org/lkml/2016/9/13/250
     Rebase to latest Linux 4.8-rc6
     Delete the confusing "skipping" in the error message.

V11: https://lkml.org/lkml/2016/9/6/354
     Rebase to latest Linux 4.8-rc5
     Delete typedef (suggested by checkpatch.pl)

V10: https://lkml.org/lkml/2016/7/26/215
     Drop the "readq" patch.
     Rebase to latest Linux 4.7.

V9: https://lkml.org/lkml/2016/7/25/345
    Improve pr_err message in acpi gtdt driver.
    Update Commit message for 7/9
    shorten the irq mapping function name
    Improve GTDT driver for memory-mapped timer

v8: https://lkml.org/lkml/2016/7/19/660
    Improve "pr_fmt(fmt)" definition: add "ACPI" in front of "GTDT",
    and also improve printk message.
    Simplify is_timer_block and is_watchdog.
    Merge acpi_gtdt_desc_init and gtdt_arch_timer_init into acpi_gtdt_init();
    Delete __init in include/linux/acpi.h for GTDT API
    Make ARM64 select GTDT.
    Delete "#include <linux/module.h>" from acpi_gtdt.c
    Simplify GT block parse code.

v7: https://lkml.org/lkml/2016/7/13/769
    Move the GTDT driver to drivers/acpi/arm64
    Add add the ARM64-specific ACPI Support maintainers in MAINTAINERS
    Merge 3 patches of GTDT parser driver.
    Fix the for_each_platform_timer bug.

v6: https://lkml.org/lkml/2016/6/29/580
    split the GTDT driver to 4 parts: basic, arch_timer, memory-mapped timer,
    and SBSA Generic Watchdog timer
    Improve driver by suggestions and example code from Daniel Lezcano

v5: https://lkml.org/lkml/2016/5/24/356
    Sorting out all patches, simplify the API of GTDT driver:
    GTDT driver just fills the data struct for arm_arch_timer driver.

v4: https://lists.linaro.org/pipermail/linaro-acpi/2016-March/006667.html
    Delete the kvm relevant patches
    Separate two patches for sorting out the code for arm_arch_timer.
    Improve irq info export code to allow missing irq info in GTDT table.

v3: https://lkml.org/lkml/2016/2/1/658
    Improve GTDT driver code:
      (1)improve pr_* by defining pr_fmt(fmt)
      (2)simplify gtdt_sbsa_gwdt_init
      (3)improve gtdt_arch_timer_data_init, if table is NULL, it will try
      to get GTDT table.
    Move enum ppi_nr to arm_arch_timer.h, and add enum spi_nr.
    Add arm_arch_timer get ppi from DT and GTDT support for kvm.

v2: https://lkml.org/lkml/2015/12/2/10
    Rebase to latest kernel version(4.4-rc3).
    Fix the bug about the config problem,
    use CONFIG_ACPI_GTDT instead of CONFIG_ACPI in arm_arch_timer.c

v1: The first upstreaming version: https://lkml.org/lkml/2015/10/28/553

Fu Wei (11):
  clocksource: arm_arch_timer: introduce a wrapper function to get the
    frequency from mmio.
  clocksource: arm_arch_timer: separate out device-tree code and remove
    arch_timer_detect_rate
  clocksource: arm_arch_timer: refactor arch_timer_needs_probing
  clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT
    init call
  clocksource: arm_arch_timer: introduce some new structs to prepare for
    GTDT
  clocksource: arm_arch_timer: refactor MMIO timer probing.
  acpi/arm64: Add GTDT table parse driver
  clocksource: arm_arch_timer: simplify ACPI support code.
  acpi/arm64: Add memory-mapped timer support in GTDT driver
  clocksource: arm_arch_timer: add GTDT support for memory-mapped timer
  acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver

 arch/arm64/Kconfig                   |   1 +
 drivers/acpi/arm64/Kconfig           |   3 +
 drivers/acpi/arm64/Makefile          |   1 +
 drivers/acpi/arm64/gtdt.c            | 381 +++++++++++++++++++++++++++++++++++
 drivers/clocksource/arm_arch_timer.c | 326 +++++++++++++++++++-----------
 include/clocksource/arm_arch_timer.h |  17 ++
 include/linux/acpi.h                 |   7 +
 7 files changed, 614 insertions(+), 122 deletions(-)
 create mode 100644 drivers/acpi/arm64/gtdt.c

-- 
2.9.3

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
@ 2017-03-21 16:31 ` fu.wei
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei at linaro.org @ 2017-03-21 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Fu Wei <fu.wei@linaro.org>

This patchset:
    (1)Preparation for adding GTDT support in arm_arch_timer:
        1. Introduce a wrapper function to get the frequency from mmio.
        2. separate out device-tree code from arch_timer_detect_rate
        3. remove arch_timer_detect_rate use arch_timer_*get_cntfrq directly
        4. Refactor arch_timer_needs_probing, and move it into DT init call
        5. Introduce some new structs and refactor the MMIO timer init code
        for reusing some common code.

    (2)Introduce ACPI GTDT parser: drivers/acpi/arm64/acpi_gtdt.c
    Parse all kinds of timer in GTDT table of ACPI:arch timer,
    memory-mapped timer and SBSA Generic Watchdog timer.
    This driver can help to simplify all the relevant timer drivers,
    and separate all the ACPI GTDT knowledge from them.

    (3)Simplify ACPI code for arm_arch_timer

    (4)Add GTDT support for ARM memory-mapped timer.

This patchset has been tested on the following platforms with ACPI enabled:
    (1)ARM Foundation v8 model

Changelog:
v22: https://lkml.org/lkml/2017/3/21/
     Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arch-timer/cleanup
     Only Introduce arch_timer_mem_get_cntfrq to get the frequency from mmio.
     Merged patch 2,3(about arch_timer_detect_rate).
     Keep arch_timer_rate, do NOT split it for different types of timer.
     Improve  memory-mapped timer support by comments and variable name:
         data-->timer_mem
         frame-->gtdt_frame
     Delete zero check for SBSA watchdog irq.
     Skip secure SBSA watchdog in GTDT driver.
     Delete Kconfig modification for SBSA watchdog driver.
     Delete no_irq, using nr_res instead.

v21: https://lkml.org/lkml/2017/2/6/734
     Introduce two functions to get the frequency from mmio and sysreg.
     Remove arch_timer_detect_rate use arch_timer_get_*_freq directly
     Split arch_timer_rate for different types of timer.
     Skip secure timer frame in GTDT driver.
     Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arch-timer/cleanup
     (The first 6 patches in v20 have been merged into arch-timer/cleanup branch)

v20: https://lkml.org/lkml/2017/1/18/534
     Reorder the first 4 patches and split the 4th patches.
     Leave CNTHCTL_* as they originally were.
     Fix the bug in arch_timer_select_ppi.
     Split "Rework counter frequency detection" patch.
     Rework the arch_timer_detect_rate function.
     Improve the commit message of "Refactor MMIO timer probing".
     Rebase to 4.10.0-rc4

v19: https://lkml.org/lkml/2016/12/21/25
     Fix a '\n' missing in a error message in arch_timer_mem_init.
     Add "request_mem_region" for ioremapping cntbase, according to
     f947ee1 clocksource/drivers/arm_arch_timer: Map frame with of_io_request_and_map()
     Rebase to 4.9.0-gfb779ff

v18: https://lkml.org/lkml/2016/12/8/446
     Fix 8/15 patch problem of "int ret;" in arch_timer_acpi_init.
     Rebase to 4.9.0-rc8-g9269898

v17: https://lkml.org/lkml/2016/11/25/140
     Take out some cleanups from 4/15.
     Merge 5/15 and 6/15, improve PPI determination code,
     improve commit message.
     Rework counter frequency detection.
     Move arch_timer_needs_of_probing into DT init call.
     Move Platform Timer scan loop back to timer init call to avoid allocating
     and free memory.
     Improve all the exported functions' comment.

v16: https://lkml.org/lkml/2016/11/16/268
     Fix patchset problem about static enum ppi_nr of 01/13 in v15.
     Refactor arch_timer_detect_rate.
     Refactor arch_timer_needs_probing.

v15: https://lkml.org/lkml/2016/11/15/366
     Re-order patches
     Add arm_arch_timer refactoring patches to prepare for GTDT:
         1. rename some  enums and defines, and some cleanups
         2. separate out arch_timer_uses_ppi init code and fix a potential bug
         3. Improve some new structs, refactor the timer init code.
     Since the some structs have been changed, GTDT parser for memory-mapped
     timer and SBSA Generic Watchdog timer have been update.

v14: https://lkml.org/lkml/2016/9/28/573
     Separate memory-mapped timer GTDT support into two patches
         1. Refactor the timer init code to prepare for GTDT
         2. Add GTDT support for memory-mapped timer

v13: http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1231717.html
     Improve arm_arch_timer code for memory-mapped
     timer GTDT support, refactor original memory-mapped timer
     dt support for reusing some common code.

v12: https://lkml.org/lkml/2016/9/13/250
     Rebase to latest Linux 4.8-rc6
     Delete the confusing "skipping" in the error message.

V11: https://lkml.org/lkml/2016/9/6/354
     Rebase to latest Linux 4.8-rc5
     Delete typedef (suggested by checkpatch.pl)

V10: https://lkml.org/lkml/2016/7/26/215
     Drop the "readq" patch.
     Rebase to latest Linux 4.7.

V9: https://lkml.org/lkml/2016/7/25/345
    Improve pr_err message in acpi gtdt driver.
    Update Commit message for 7/9
    shorten the irq mapping function name
    Improve GTDT driver for memory-mapped timer

v8: https://lkml.org/lkml/2016/7/19/660
    Improve "pr_fmt(fmt)" definition: add "ACPI" in front of "GTDT",
    and also improve printk message.
    Simplify is_timer_block and is_watchdog.
    Merge acpi_gtdt_desc_init and gtdt_arch_timer_init into acpi_gtdt_init();
    Delete __init in include/linux/acpi.h for GTDT API
    Make ARM64 select GTDT.
    Delete "#include <linux/module.h>" from acpi_gtdt.c
    Simplify GT block parse code.

v7: https://lkml.org/lkml/2016/7/13/769
    Move the GTDT driver to drivers/acpi/arm64
    Add add the ARM64-specific ACPI Support maintainers in MAINTAINERS
    Merge 3 patches of GTDT parser driver.
    Fix the for_each_platform_timer bug.

v6: https://lkml.org/lkml/2016/6/29/580
    split the GTDT driver to 4 parts: basic, arch_timer, memory-mapped timer,
    and SBSA Generic Watchdog timer
    Improve driver by suggestions and example code from Daniel Lezcano

v5: https://lkml.org/lkml/2016/5/24/356
    Sorting out all patches, simplify the API of GTDT driver:
    GTDT driver just fills the data struct for arm_arch_timer driver.

v4: https://lists.linaro.org/pipermail/linaro-acpi/2016-March/006667.html
    Delete the kvm relevant patches
    Separate two patches for sorting out the code for arm_arch_timer.
    Improve irq info export code to allow missing irq info in GTDT table.

v3: https://lkml.org/lkml/2016/2/1/658
    Improve GTDT driver code:
      (1)improve pr_* by defining pr_fmt(fmt)
      (2)simplify gtdt_sbsa_gwdt_init
      (3)improve gtdt_arch_timer_data_init, if table is NULL, it will try
      to get GTDT table.
    Move enum ppi_nr to arm_arch_timer.h, and add enum spi_nr.
    Add arm_arch_timer get ppi from DT and GTDT support for kvm.

v2: https://lkml.org/lkml/2015/12/2/10
    Rebase to latest kernel version(4.4-rc3).
    Fix the bug about the config problem,
    use CONFIG_ACPI_GTDT instead of CONFIG_ACPI in arm_arch_timer.c

v1: The first upstreaming version: https://lkml.org/lkml/2015/10/28/553

Fu Wei (11):
  clocksource: arm_arch_timer: introduce a wrapper function to get the
    frequency from mmio.
  clocksource: arm_arch_timer: separate out device-tree code and remove
    arch_timer_detect_rate
  clocksource: arm_arch_timer: refactor arch_timer_needs_probing
  clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT
    init call
  clocksource: arm_arch_timer: introduce some new structs to prepare for
    GTDT
  clocksource: arm_arch_timer: refactor MMIO timer probing.
  acpi/arm64: Add GTDT table parse driver
  clocksource: arm_arch_timer: simplify ACPI support code.
  acpi/arm64: Add memory-mapped timer support in GTDT driver
  clocksource: arm_arch_timer: add GTDT support for memory-mapped timer
  acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver

 arch/arm64/Kconfig                   |   1 +
 drivers/acpi/arm64/Kconfig           |   3 +
 drivers/acpi/arm64/Makefile          |   1 +
 drivers/acpi/arm64/gtdt.c            | 381 +++++++++++++++++++++++++++++++++++
 drivers/clocksource/arm_arch_timer.c | 326 +++++++++++++++++++-----------
 include/clocksource/arm_arch_timer.h |  17 ++
 include/linux/acpi.h                 |   7 +
 7 files changed, 614 insertions(+), 122 deletions(-)
 create mode 100644 drivers/acpi/arm64/gtdt.c

-- 
2.9.3

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 01/11] clocksource: arm_arch_timer: introduce a wrapper function to get the frequency from mmio.
  2017-03-21 16:31 ` fu.wei
@ 2017-03-21 16:31   ` fu.wei at linaro.org
  -1 siblings, 0 replies; 113+ messages in thread
From: fu.wei @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	lorenzo.pieralisi, sudeep.holla, hanjun.guo
  Cc: linux-arm-kernel, linaro-acpi, linux-kernel, linux-acpi,
	rruigrok, harba, cov, timur, graeme.gregory, al.stone, jcm, wei,
	arnd, catalin.marinas, will.deacon, Suravee.Suthikulpanit,
	leo.duran, wim, linux, linux-watchdog, tn, christoffer.dall,
	julien.grall, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

The patch introduce a new functions: arch_timer_mem_get_cntfrq, and applies
it in arch_timer_detect_rate.
This function will be used for getting the frequency from mmio to prepare
for reworking counter frequency detection.

Signed-off-by: Fu Wei <fu.wei@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 3faed19..843f923 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -555,6 +555,11 @@ static int arch_timer_starting_cpu(unsigned int cpu)
 	return 0;
 }
 
+static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
+{
+	return readl_relaxed(cntbase + CNTFRQ);
+}
+
 static void
 arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
 {
@@ -569,7 +574,7 @@ 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_mem_get_cntfrq(cntbase);
 		else
 			arch_timer_rate = arch_timer_get_cntfrq();
 	}
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 01/11] clocksource: arm_arch_timer: introduce a wrapper function to get the frequency from mmio.
@ 2017-03-21 16:31   ` fu.wei at linaro.org
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei at linaro.org @ 2017-03-21 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Fu Wei <fu.wei@linaro.org>

The patch introduce a new functions: arch_timer_mem_get_cntfrq, and applies
it in arch_timer_detect_rate.
This function will be used for getting the frequency from mmio to prepare
for reworking counter frequency detection.

Signed-off-by: Fu Wei <fu.wei@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 3faed19..843f923 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -555,6 +555,11 @@ static int arch_timer_starting_cpu(unsigned int cpu)
 	return 0;
 }
 
+static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
+{
+	return readl_relaxed(cntbase + CNTFRQ);
+}
+
 static void
 arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
 {
@@ -569,7 +574,7 @@ 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_mem_get_cntfrq(cntbase);
 		else
 			arch_timer_rate = arch_timer_get_cntfrq();
 	}
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
  2017-03-21 16:31 ` fu.wei
@ 2017-03-21 16:31   ` fu.wei at linaro.org
  -1 siblings, 0 replies; 113+ messages in thread
From: fu.wei @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	lorenzo.pieralisi, sudeep.holla, hanjun.guo
  Cc: linux-arm-kernel, linaro-acpi, linux-kernel, linux-acpi,
	rruigrok, harba, cov, timur, graeme.gregory, al.stone, jcm, wei,
	arnd, catalin.marinas, will.deacon, Suravee.Suthikulpanit,
	leo.duran, wim, linux, linux-watchdog, tn, christoffer.dall,
	julien.grall, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

Currently, the counter frequency detection call(arch_timer_detect_rate)
includes getting the frequency from the device-tree property, the per-cpu
arch-timer and the memory-mapped (MMIO) timer interfaces.
But reading device-tree property will be needed only when system boot with
device-tree, and reading from the per-cpu arch-timer and the memory-mapped
(MMIO) timer interfaces will be needed only when the system initializes
the relevant timer.

This patch separates out device-tree code, keep them in device-tree init
function, and removes arch_timer_detect_rate founction, then uses the
arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.

Signed-off-by: Fu Wei <fu.wei@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
 1 file changed, 30 insertions(+), 28 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 843f923..29ca7d6 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
 	return readl_relaxed(cntbase + CNTFRQ);
 }
 
-static void
-arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
-{
-	/* Who has more than one independent system counter? */
-	if (arch_timer_rate)
-		return;
-
-	/*
-	 * Try to determine the frequency from the device tree or CNTFRQ,
-	 * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
-	 */
-	if (!acpi_disabled ||
-	    of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
-		if (cntbase)
-			arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
-		else
-			arch_timer_rate = arch_timer_get_cntfrq();
-	}
-
-	/* 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",
@@ -958,7 +934,17 @@ 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_detect_rate(NULL, 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_cntfrq();
+	if (!arch_timer_rate) {
+		pr_err(FW_BUG "frequency not available.\n");
+		return -EINVAL;
+	}
 
 	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
 
@@ -1069,7 +1055,19 @@ static int __init arch_timer_mem_init(struct device_node *np)
 		goto out;
 	}
 
-	arch_timer_detect_rate(base, 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_mem_get_cntfrq(base);
+	if (!arch_timer_rate) {
+		pr_err(FW_BUG "MMIO frequency not available.\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
 	ret = arch_timer_mem_register(base, irq);
 	if (ret)
 		goto out;
@@ -1130,8 +1128,12 @@ 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);
 
-	/* Get the frequency from CNTFRQ */
-	arch_timer_detect_rate(NULL, NULL);
+	/* Get the frequency from the sysreg CNTFRQ */
+	arch_timer_rate = arch_timer_get_cntfrq();
+	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]) {
-- 
2.9.3


^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
@ 2017-03-21 16:31   ` fu.wei at linaro.org
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei at linaro.org @ 2017-03-21 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Fu Wei <fu.wei@linaro.org>

Currently, the counter frequency detection call(arch_timer_detect_rate)
includes getting the frequency from the device-tree property, the per-cpu
arch-timer and the memory-mapped (MMIO) timer interfaces.
But reading device-tree property will be needed only when system boot with
device-tree, and reading from the per-cpu arch-timer and the memory-mapped
(MMIO) timer interfaces will be needed only when the system initializes
the relevant timer.

This patch separates out device-tree code, keep them in device-tree init
function, and removes arch_timer_detect_rate founction, then uses the
arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.

Signed-off-by: Fu Wei <fu.wei@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
 1 file changed, 30 insertions(+), 28 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 843f923..29ca7d6 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
 	return readl_relaxed(cntbase + CNTFRQ);
 }
 
-static void
-arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
-{
-	/* Who has more than one independent system counter? */
-	if (arch_timer_rate)
-		return;
-
-	/*
-	 * Try to determine the frequency from the device tree or CNTFRQ,
-	 * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
-	 */
-	if (!acpi_disabled ||
-	    of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
-		if (cntbase)
-			arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
-		else
-			arch_timer_rate = arch_timer_get_cntfrq();
-	}
-
-	/* 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",
@@ -958,7 +934,17 @@ 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_detect_rate(NULL, 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_cntfrq();
+	if (!arch_timer_rate) {
+		pr_err(FW_BUG "frequency not available.\n");
+		return -EINVAL;
+	}
 
 	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
 
@@ -1069,7 +1055,19 @@ static int __init arch_timer_mem_init(struct device_node *np)
 		goto out;
 	}
 
-	arch_timer_detect_rate(base, 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_mem_get_cntfrq(base);
+	if (!arch_timer_rate) {
+		pr_err(FW_BUG "MMIO frequency not available.\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
 	ret = arch_timer_mem_register(base, irq);
 	if (ret)
 		goto out;
@@ -1130,8 +1128,12 @@ 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);
 
-	/* Get the frequency from CNTFRQ */
-	arch_timer_detect_rate(NULL, NULL);
+	/* Get the frequency from the sysreg CNTFRQ */
+	arch_timer_rate = arch_timer_get_cntfrq();
+	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]) {
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 03/11] clocksource: arm_arch_timer: refactor arch_timer_needs_probing
  2017-03-21 16:31 ` fu.wei
@ 2017-03-21 16:31   ` fu.wei at linaro.org
  -1 siblings, 0 replies; 113+ messages in thread
From: fu.wei @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	lorenzo.pieralisi, sudeep.holla, hanjun.guo
  Cc: linux-arm-kernel, linaro-acpi, linux-kernel, linux-acpi,
	rruigrok, harba, cov, timur, graeme.gregory, al.stone, jcm, wei,
	arnd, catalin.marinas, will.deacon, Suravee.Suthikulpanit,
	leo.duran, wim, linux, linux-watchdog, tn, christoffer.dall,
	julien.grall, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c | 34 +++++++++++++++++++---------------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 29ca7d6..d1a05d9 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -839,15 +839,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;
@@ -855,17 +868,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);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 03/11] clocksource: arm_arch_timer: refactor arch_timer_needs_probing
@ 2017-03-21 16:31   ` fu.wei at linaro.org
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei at linaro.org @ 2017-03-21 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c | 34 +++++++++++++++++++---------------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 29ca7d6..d1a05d9 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -839,15 +839,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;
@@ -855,17 +868,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);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 04/11] clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call
  2017-03-21 16:31 ` fu.wei
  (?)
@ 2017-03-21 16:31     ` fu.wei
  -1 siblings, 0 replies; 113+ messages in thread
From: fu.wei-QSEj5FYQhm4dnm+yROfE0A @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ, marc.zyngier-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, lorenzo.pieralisi-5wv7dgnIgG8,
	sudeep.holla-5wv7dgnIgG8, hanjun.guo-QSEj5FYQhm4dnm+yROfE0A
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linaro-acpi-cunTk1MwBs8s++Sfvej+rw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	rruigrok-sgV2jX0FEOL9JmXXK+q4OQ, harba-sgV2jX0FEOL9JmXXK+q4OQ,
	cov-sgV2jX0FEOL9JmXXK+q4OQ, timur-sgV2jX0FEOL9JmXXK+q4OQ,
	graeme.gregory-QSEj5FYQhm4dnm+yROfE0A,
	al.stone-QSEj5FYQhm4dnm+yROfE0A, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	wei-H+wXaHxf7aLQT0dZR+AlfA, arnd-r2nGTMty4D4,
	catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	Suravee.Suthikulpanit-5C7GfCeVMHo, leo.duran-5C7GfCeVMHo,
	wim-IQzOog9fTRqzQB+pC5nmwQ, linux-0h96xk9xTtrk1uMJSBkQmQ,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	christoffer.dall-QSEj5FYQhm4dnm+yROfE0A,
	julien.grall-5wv7dgnIgG8, Fu Wei

From: Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

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 <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 drivers/clocksource/arm_arch_timer.c | 46 ++++++++++++++++--------------------
 1 file changed, 21 insertions(+), 25 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index d1a05d9..4b29a6d 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -868,9 +868,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();
@@ -908,26 +905,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");
@@ -938,6 +918,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.
@@ -983,7 +965,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);
@@ -1076,7 +1065,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);
@@ -1105,6 +1095,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) {
@@ -1132,6 +1123,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_rate = arch_timer_get_cntfrq();
 	if (!arch_timer_rate) {
@@ -1148,8 +1141,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
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 04/11] clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call
@ 2017-03-21 16:31     ` fu.wei
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	lorenzo.pieralisi, sudeep.holla, hanjun.guo
  Cc: linux-arm-kernel, linaro-acpi, linux-kernel, linux-acpi,
	rruigrok, harba, cov, timur, graeme.gregory, al.stone, jcm, wei,
	arnd, catalin.marinas, will.deacon, Suravee.Suthikulpanit,
	leo.duran, wim, linux, linux-watchdog, tn, christoffer.dall,
	julien.grall, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c | 46 ++++++++++++++++--------------------
 1 file changed, 21 insertions(+), 25 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index d1a05d9..4b29a6d 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -868,9 +868,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();
@@ -908,26 +905,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");
@@ -938,6 +918,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.
@@ -983,7 +965,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);
@@ -1076,7 +1065,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);
@@ -1105,6 +1095,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) {
@@ -1132,6 +1123,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_rate = arch_timer_get_cntfrq();
 	if (!arch_timer_rate) {
@@ -1148,8 +1141,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
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 04/11] clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call
@ 2017-03-21 16:31     ` fu.wei
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei at linaro.org @ 2017-03-21 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c | 46 ++++++++++++++++--------------------
 1 file changed, 21 insertions(+), 25 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index d1a05d9..4b29a6d 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -868,9 +868,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();
@@ -908,26 +905,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");
@@ -938,6 +918,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.
@@ -983,7 +965,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);
@@ -1076,7 +1065,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);
@@ -1105,6 +1095,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) {
@@ -1132,6 +1123,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_rate = arch_timer_get_cntfrq();
 	if (!arch_timer_rate) {
@@ -1148,8 +1141,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
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 05/11] clocksource: arm_arch_timer: introduce some new structs to prepare for GTDT
  2017-03-21 16:31 ` fu.wei
@ 2017-03-21 16:31   ` fu.wei at linaro.org
  -1 siblings, 0 replies; 113+ messages in thread
From: fu.wei @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	lorenzo.pieralisi, sudeep.holla, hanjun.guo
  Cc: linux-arm-kernel, linaro-acpi, linux-kernel, linux-acpi,
	rruigrok, harba, cov, timur, graeme.gregory, al.stone, jcm, wei,
	arnd, catalin.marinas, will.deacon, Suravee.Suthikulpanit,
	leo.duran, wim, linux, linux-watchdog, tn, christoffer.dall,
	julien.grall, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 include/clocksource/arm_arch_timer.h | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

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);
-- 
2.9.3


^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 05/11] clocksource: arm_arch_timer: introduce some new structs to prepare for GTDT
@ 2017-03-21 16:31   ` fu.wei at linaro.org
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei at linaro.org @ 2017-03-21 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 include/clocksource/arm_arch_timer.h | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

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);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 06/11] clocksource: arm_arch_timer: refactor MMIO timer probing.
  2017-03-21 16:31 ` fu.wei
  (?)
@ 2017-03-21 16:31     ` fu.wei
  -1 siblings, 0 replies; 113+ messages in thread
From: fu.wei-QSEj5FYQhm4dnm+yROfE0A @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ, marc.zyngier-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, lorenzo.pieralisi-5wv7dgnIgG8,
	sudeep.holla-5wv7dgnIgG8, hanjun.guo-QSEj5FYQhm4dnm+yROfE0A
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linaro-acpi-cunTk1MwBs8s++Sfvej+rw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	rruigrok-sgV2jX0FEOL9JmXXK+q4OQ, harba-sgV2jX0FEOL9JmXXK+q4OQ,
	cov-sgV2jX0FEOL9JmXXK+q4OQ, timur-sgV2jX0FEOL9JmXXK+q4OQ,
	graeme.gregory-QSEj5FYQhm4dnm+yROfE0A,
	al.stone-QSEj5FYQhm4dnm+yROfE0A, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	wei-H+wXaHxf7aLQT0dZR+AlfA, arnd-r2nGTMty4D4,
	catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	Suravee.Suthikulpanit-5C7GfCeVMHo, leo.duran-5C7GfCeVMHo,
	wim-IQzOog9fTRqzQB+pC5nmwQ, linux-0h96xk9xTtrk1uMJSBkQmQ,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	christoffer.dall-QSEj5FYQhm4dnm+yROfE0A,
	julien.grall-5wv7dgnIgG8, Fu Wei

From: Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

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 <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 drivers/clocksource/arm_arch_timer.c | 158 +++++++++++++++++++++++++----------
 1 file changed, 112 insertions(+), 46 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 4b29a6d..3ada5dc 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -977,17 +977,21 @@ 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;
+	u32 arch_timer_mem_freq;
+	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;
 	}
 
@@ -997,26 +1001,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;
 		}
@@ -1024,56 +1020,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");
+		return -EINVAL;
+	}
+
+	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;
+	}
+
+	arch_timer_mem_freq = arch_timer_mem_get_cntfrq(base);
+	if (!arch_timer_rate && arch_timer_mem_freq) {
+		arch_timer_rate = arch_timer_mem_freq;
+	} else if (!arch_timer_rate || arch_timer_rate != arch_timer_mem_freq) {
+		pr_err(FW_BUG "invalid MMIO frequency.\n");
+		iounmap(base);
+		return -EINVAL;
+	}
+
+	ret = arch_timer_mem_register(base, irq);
+	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;
+		}
+
+		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 determine the frequency from the device tree,
-	 * if fail, get the frequency from the CNTFRQ reg of MMIO timer.
+	 * Try to get the frequency from the device tree,
+	 * if fail, we will try the CNTFRQ register in arch_timer_mem_init.
 	 */
-	if (!arch_timer_rate &&
-	    of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
-		arch_timer_rate = arch_timer_mem_get_cntfrq(base);
 	if (!arch_timer_rate) {
-		pr_err(FW_BUG "MMIO frequency not available.\n");
-		ret = -EINVAL;
-		goto out;
+		of_property_read_u32(np, "clock-frequency", &arch_timer_rate);
 	}
 
-	ret = arch_timer_mem_register(base, irq);
-	if (ret)
-		goto out;
-
-	if (!arch_timer_needs_of_probing())
+	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)
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 06/11] clocksource: arm_arch_timer: refactor MMIO timer probing.
@ 2017-03-21 16:31     ` fu.wei
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	lorenzo.pieralisi, sudeep.holla, hanjun.guo
  Cc: linux-arm-kernel, linaro-acpi, linux-kernel, linux-acpi,
	rruigrok, harba, cov, timur, graeme.gregory, al.stone, jcm, wei,
	arnd, catalin.marinas, will.deacon, Suravee.Suthikulpanit,
	leo.duran, wim, linux, linux-watchdog, tn, christoffer.dall,
	julien.grall, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c | 158 +++++++++++++++++++++++++----------
 1 file changed, 112 insertions(+), 46 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 4b29a6d..3ada5dc 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -977,17 +977,21 @@ 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;
+	u32 arch_timer_mem_freq;
+	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;
 	}
 
@@ -997,26 +1001,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;
 		}
@@ -1024,56 +1020,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");
+		return -EINVAL;
+	}
+
+	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;
+	}
+
+	arch_timer_mem_freq = arch_timer_mem_get_cntfrq(base);
+	if (!arch_timer_rate && arch_timer_mem_freq) {
+		arch_timer_rate = arch_timer_mem_freq;
+	} else if (!arch_timer_rate || arch_timer_rate != arch_timer_mem_freq) {
+		pr_err(FW_BUG "invalid MMIO frequency.\n");
+		iounmap(base);
+		return -EINVAL;
+	}
+
+	ret = arch_timer_mem_register(base, irq);
+	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;
+		}
+
+		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 determine the frequency from the device tree,
-	 * if fail, get the frequency from the CNTFRQ reg of MMIO timer.
+	 * Try to get the frequency from the device tree,
+	 * if fail, we will try the CNTFRQ register in arch_timer_mem_init.
 	 */
-	if (!arch_timer_rate &&
-	    of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
-		arch_timer_rate = arch_timer_mem_get_cntfrq(base);
 	if (!arch_timer_rate) {
-		pr_err(FW_BUG "MMIO frequency not available.\n");
-		ret = -EINVAL;
-		goto out;
+		of_property_read_u32(np, "clock-frequency", &arch_timer_rate);
 	}
 
-	ret = arch_timer_mem_register(base, irq);
-	if (ret)
-		goto out;
-
-	if (!arch_timer_needs_of_probing())
+	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)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 06/11] clocksource: arm_arch_timer: refactor MMIO timer probing.
@ 2017-03-21 16:31     ` fu.wei
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei at linaro.org @ 2017-03-21 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c | 158 +++++++++++++++++++++++++----------
 1 file changed, 112 insertions(+), 46 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 4b29a6d..3ada5dc 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -977,17 +977,21 @@ 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;
+	u32 arch_timer_mem_freq;
+	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;
 	}
 
@@ -997,26 +1001,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;
 		}
@@ -1024,56 +1020,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");
+		return -EINVAL;
+	}
+
+	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;
+	}
+
+	arch_timer_mem_freq = arch_timer_mem_get_cntfrq(base);
+	if (!arch_timer_rate && arch_timer_mem_freq) {
+		arch_timer_rate = arch_timer_mem_freq;
+	} else if (!arch_timer_rate || arch_timer_rate != arch_timer_mem_freq) {
+		pr_err(FW_BUG "invalid MMIO frequency.\n");
+		iounmap(base);
+		return -EINVAL;
+	}
+
+	ret = arch_timer_mem_register(base, irq);
+	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;
+		}
+
+		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 determine the frequency from the device tree,
-	 * if fail, get the frequency from the CNTFRQ reg of MMIO timer.
+	 * Try to get the frequency from the device tree,
+	 * if fail, we will try the CNTFRQ register in arch_timer_mem_init.
 	 */
-	if (!arch_timer_rate &&
-	    of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
-		arch_timer_rate = arch_timer_mem_get_cntfrq(base);
 	if (!arch_timer_rate) {
-		pr_err(FW_BUG "MMIO frequency not available.\n");
-		ret = -EINVAL;
-		goto out;
+		of_property_read_u32(np, "clock-frequency", &arch_timer_rate);
 	}
 
-	ret = arch_timer_mem_register(base, irq);
-	if (ret)
-		goto out;
-
-	if (!arch_timer_needs_of_probing())
+	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)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
  2017-03-21 16:31 ` fu.wei
@ 2017-03-21 16:31   ` fu.wei at linaro.org
  -1 siblings, 0 replies; 113+ messages in thread
From: fu.wei @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	lorenzo.pieralisi, sudeep.holla, hanjun.guo
  Cc: linux-arm-kernel, linaro-acpi, linux-kernel, linux-acpi,
	rruigrok, harba, cov, timur, graeme.gregory, al.stone, jcm, wei,
	arnd, catalin.marinas, will.deacon, Suravee.Suthikulpanit,
	leo.duran, wim, linux, linux-watchdog, tn, christoffer.dall,
	julien.grall, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 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(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3741859..7e2baec 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 <daniel.lezcano@linaro.org>
+ *         Fu Wei <fu.wei@linaro.org>
+ *         Hanjun Guo <hanjun.guo@linaro.org>
+ *
+ * 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 <linux/acpi.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <clocksource/arm_arch_timer.h>
+
+#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 9b05886..4b5c146 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -595,6 +595,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
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-21 16:31   ` fu.wei at linaro.org
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei at linaro.org @ 2017-03-21 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 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(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3741859..7e2baec 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 <daniel.lezcano@linaro.org>
+ *         Fu Wei <fu.wei@linaro.org>
+ *         Hanjun Guo <hanjun.guo@linaro.org>
+ *
+ * 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 <linux/acpi.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <clocksource/arm_arch_timer.h>
+
+#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 9b05886..4b5c146 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -595,6 +595,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
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 08/11] clocksource: arm_arch_timer: simplify ACPI support code.
  2017-03-21 16:31 ` fu.wei
  (?)
@ 2017-03-21 16:31   ` fu.wei
  -1 siblings, 0 replies; 113+ messages in thread
From: fu.wei @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	lorenzo.pieralisi, sudeep.holla, hanjun.guo
  Cc: linaro-acpi, catalin.marinas, will.deacon, linux-kernel, wim,
	Fu Wei, wei, al.stone, tn, timur, linux-acpi, linux, harba,
	julien.grall, linux-watchdog, arnd, jcm, cov, linux-arm-kernel,
	graeme.gregory, rruigrok, leo.duran, Suravee.Suthikulpanit,
	christoffer.dall

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c | 54 ++++++++++++------------------------
 1 file changed, 17 insertions(+), 37 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 3ada5dc..ef747f3 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -1141,63 +1141,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_rate = arch_timer_get_cntfrq();
-	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]) {
 		pr_err("No interrupt available, giving up\n");
@@ -1205,7 +1178,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_rate = arch_timer_get_cntfrq();
+	if (!arch_timer_rate) {
+		pr_err(FW_BUG "frequency not available.\n");
+		return -EINVAL;
+	}
 
 	ret = arch_timer_register();
 	if (ret)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 08/11] clocksource: arm_arch_timer: simplify ACPI support code.
@ 2017-03-21 16:31   ` fu.wei
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	lorenzo.pieralisi, sudeep.holla, hanjun.guo
  Cc: linux-arm-kernel, linaro-acpi, linux-kernel, linux-acpi,
	rruigrok, harba, cov, timur, graeme.gregory, al.stone, jcm, wei,
	arnd, catalin.marinas, will.deacon, Suravee.Suthikulpanit,
	leo.duran, wim, linux, linux-watchdog, tn, christoffer.dall,
	julien.grall, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c | 54 ++++++++++++------------------------
 1 file changed, 17 insertions(+), 37 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 3ada5dc..ef747f3 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -1141,63 +1141,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_rate = arch_timer_get_cntfrq();
-	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]) {
 		pr_err("No interrupt available, giving up\n");
@@ -1205,7 +1178,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_rate = arch_timer_get_cntfrq();
+	if (!arch_timer_rate) {
+		pr_err(FW_BUG "frequency not available.\n");
+		return -EINVAL;
+	}
 
 	ret = arch_timer_register();
 	if (ret)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 08/11] clocksource: arm_arch_timer: simplify ACPI support code.
@ 2017-03-21 16:31   ` fu.wei
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei at linaro.org @ 2017-03-21 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c | 54 ++++++++++++------------------------
 1 file changed, 17 insertions(+), 37 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 3ada5dc..ef747f3 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -1141,63 +1141,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_rate = arch_timer_get_cntfrq();
-	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]) {
 		pr_err("No interrupt available, giving up\n");
@@ -1205,7 +1178,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_rate = arch_timer_get_cntfrq();
+	if (!arch_timer_rate) {
+		pr_err(FW_BUG "frequency not available.\n");
+		return -EINVAL;
+	}
 
 	ret = arch_timer_register();
 	if (ret)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 09/11] acpi/arm64: Add memory-mapped timer support in GTDT driver
  2017-03-21 16:31 ` fu.wei
@ 2017-03-21 16:31   ` fu.wei at linaro.org
  -1 siblings, 0 replies; 113+ messages in thread
From: fu.wei @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	lorenzo.pieralisi, sudeep.holla, hanjun.guo
  Cc: linux-arm-kernel, linaro-acpi, linux-kernel, linux-acpi,
	rruigrok, harba, cov, timur, graeme.gregory, al.stone, jcm, wei,
	arnd, catalin.marinas, will.deacon, Suravee.Suthikulpanit,
	leo.duran, wim, linux, linux-watchdog, tn, christoffer.dall,
	julien.grall, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/arm64/gtdt.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/acpi.h      |   1 +
 2 files changed, 131 insertions(+)

diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
index 8a03b4b..f471873 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,111 @@ 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 *timer_mem)
+{
+	int i, j;
+	struct acpi_gtdt_timer_entry *gtdt_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;
+	}
+
+	timer_mem->cntctlbase = (phys_addr_t)block->block_address;
+	/*
+	 * The CNTCTLBase frame is 4KB (register offsets 0x000 - 0xFFC).
+	 * See ARM DDI 0487A.k_iss10775, page I1-5129, Table I1-3
+	 * "CNTCTLBase memory map".
+	 */
+	timer_mem->size = SZ_4K;
+
+	gtdt_frame = (void *)block + block->timer_offset;
+	if (gtdt_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++, gtdt_frame++) {
+		struct arch_timer_mem_frame *frame = &timer_mem->frame[j];
+
+		if (gtdt_frame->common_flags & ACPI_GTDT_GT_IS_SECURE_TIMER)
+			continue;
+
+		if (!gtdt_frame->base_address || !gtdt_frame->timer_interrupt)
+			return -EINVAL;
+
+		frame->phys_irq = map_gt_gsi(gtdt_frame->timer_interrupt,
+					     gtdt_frame->timer_flags);
+		if (frame->phys_irq <= 0) {
+			pr_warn("failed to map physical timer irq in frame %d.\n",
+				i);
+			return -EINVAL;
+		}
+
+		frame->virt_irq =
+			map_gt_gsi(gtdt_frame->virtual_timer_interrupt,
+				   gtdt_frame->virtual_timer_flags);
+		if (frame->virt_irq <= 0) {
+			pr_warn("failed to map virtual timer irq in frame %d.\n",
+				i);
+			acpi_unregister_gsi(gtdt_frame->timer_interrupt);
+			return -EINVAL;
+		}
+
+		frame->frame_nr = gtdt_frame->frame_number;
+		frame->cntbase = gtdt_frame->base_address;
+		/*
+		 * The CNTBaseN frame is 4KB (register offsets 0x000 - 0xFFC).
+		 * See ARM DDI 0487A.k_iss10775, page I1-5130, Table I1-4
+		 * "CNTBaseN memory map".
+		 */
+		frame->size = SZ_4K;
+		j++;
+	}
+	timer_mem->num_frames = j;
+
+	return 0;
+}
+
+/**
+ * acpi_arch_timer_mem_init() - Get the info of all GT blocks in GTDT table.
+ * @timer_mem:	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 *timer_mem,
+				    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, timer_mem);
+			if (ret)
+				return ret;
+			timer_mem++;
+			(*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 4b5c146..3193724 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -599,6 +599,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 *timer_mem, int *timer_count);
 #endif
 
 #else	/* !CONFIG_ACPI */
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 09/11] acpi/arm64: Add memory-mapped timer support in GTDT driver
@ 2017-03-21 16:31   ` fu.wei at linaro.org
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei at linaro.org @ 2017-03-21 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/arm64/gtdt.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/acpi.h      |   1 +
 2 files changed, 131 insertions(+)

diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
index 8a03b4b..f471873 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,111 @@ 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 *timer_mem)
+{
+	int i, j;
+	struct acpi_gtdt_timer_entry *gtdt_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;
+	}
+
+	timer_mem->cntctlbase = (phys_addr_t)block->block_address;
+	/*
+	 * The CNTCTLBase frame is 4KB (register offsets 0x000 - 0xFFC).
+	 * See ARM DDI 0487A.k_iss10775, page I1-5129, Table I1-3
+	 * "CNTCTLBase memory map".
+	 */
+	timer_mem->size = SZ_4K;
+
+	gtdt_frame = (void *)block + block->timer_offset;
+	if (gtdt_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++, gtdt_frame++) {
+		struct arch_timer_mem_frame *frame = &timer_mem->frame[j];
+
+		if (gtdt_frame->common_flags & ACPI_GTDT_GT_IS_SECURE_TIMER)
+			continue;
+
+		if (!gtdt_frame->base_address || !gtdt_frame->timer_interrupt)
+			return -EINVAL;
+
+		frame->phys_irq = map_gt_gsi(gtdt_frame->timer_interrupt,
+					     gtdt_frame->timer_flags);
+		if (frame->phys_irq <= 0) {
+			pr_warn("failed to map physical timer irq in frame %d.\n",
+				i);
+			return -EINVAL;
+		}
+
+		frame->virt_irq =
+			map_gt_gsi(gtdt_frame->virtual_timer_interrupt,
+				   gtdt_frame->virtual_timer_flags);
+		if (frame->virt_irq <= 0) {
+			pr_warn("failed to map virtual timer irq in frame %d.\n",
+				i);
+			acpi_unregister_gsi(gtdt_frame->timer_interrupt);
+			return -EINVAL;
+		}
+
+		frame->frame_nr = gtdt_frame->frame_number;
+		frame->cntbase = gtdt_frame->base_address;
+		/*
+		 * The CNTBaseN frame is 4KB (register offsets 0x000 - 0xFFC).
+		 * See ARM DDI 0487A.k_iss10775, page I1-5130, Table I1-4
+		 * "CNTBaseN memory map".
+		 */
+		frame->size = SZ_4K;
+		j++;
+	}
+	timer_mem->num_frames = j;
+
+	return 0;
+}
+
+/**
+ * acpi_arch_timer_mem_init() - Get the info of all GT blocks in GTDT table.
+ * @timer_mem:	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 *timer_mem,
+				    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, timer_mem);
+			if (ret)
+				return ret;
+			timer_mem++;
+			(*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 4b5c146..3193724 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -599,6 +599,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 *timer_mem, int *timer_count);
 #endif
 
 #else	/* !CONFIG_ACPI */
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 10/11] clocksource: arm_arch_timer: add GTDT support for memory-mapped timer
  2017-03-21 16:31 ` fu.wei
@ 2017-03-21 16:31   ` fu.wei at linaro.org
  -1 siblings, 0 replies; 113+ messages in thread
From: fu.wei @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	lorenzo.pieralisi, sudeep.holla, hanjun.guo
  Cc: linux-arm-kernel, linaro-acpi, linux-kernel, linux-acpi,
	rruigrok, harba, cov, timur, graeme.gregory, al.stone, jcm, wei,
	arnd, catalin.marinas, will.deacon, Suravee.Suthikulpanit,
	leo.duran, wim, linux, linux-watchdog, tn, christoffer.dall,
	julien.grall, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c | 35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index ef747f3..f8aa5a0 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -1142,10 +1142,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");
@@ -1154,7 +1179,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;
@@ -1191,6 +1216,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);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 10/11] clocksource: arm_arch_timer: add GTDT support for memory-mapped timer
@ 2017-03-21 16:31   ` fu.wei at linaro.org
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei at linaro.org @ 2017-03-21 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c | 35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index ef747f3..f8aa5a0 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -1142,10 +1142,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");
@@ -1154,7 +1179,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;
@@ -1191,6 +1216,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);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 11/11] acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
  2017-03-21 16:31 ` fu.wei
  (?)
@ 2017-03-21 16:31   ` fu.wei
  -1 siblings, 0 replies; 113+ messages in thread
From: fu.wei @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	lorenzo.pieralisi, sudeep.holla, hanjun.guo
  Cc: linux-arm-kernel, linaro-acpi, linux-kernel, linux-acpi,
	rruigrok, harba, cov, timur, graeme.gregory, al.stone, jcm, wei,
	arnd, catalin.marinas, will.deacon, Suravee.Suthikulpanit,
	leo.duran, wim, linux, linux-watchdog, tn, christoffer.dall,
	julien.grall, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
---
 drivers/acpi/arm64/gtdt.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
index f471873..5d167f0 100644
--- a/drivers/acpi/arm64/gtdt.c
+++ b/drivers/acpi/arm64/gtdt.c
@@ -14,6 +14,7 @@
 #include <linux/acpi.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/platform_device.h>
 
 #include <clocksource/arm_arch_timer.h>
 
@@ -59,6 +60,17 @@ static inline bool is_timer_block(void *platform_timer)
 	return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK;
 }
 
+static inline bool is_non_secure_watchdog(void *platform_timer)
+{
+	struct acpi_gtdt_header *gh = platform_timer;
+	struct acpi_gtdt_watchdog *wd = platform_timer;
+
+	if (gh->type != ACPI_GTDT_TYPE_WATCHDOG)
+		return false;
+
+	return !(wd->timer_flags & ACPI_GTDT_WATCHDOG_SECURE);
+}
+
 static int __init map_gt_gsi(u32 interrupt, u32 flags)
 {
 	int trigger, polarity;
@@ -285,3 +297,85 @@ int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
 
 	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);
+
+	/*
+	 * 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),
+	};
+	int nr_res = ARRAY_SIZE(res);
+
+	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 (irq <= 0) {
+		pr_warn("failed to map the Watchdog interrupt.\n");
+		nr_res--;
+	}
+
+	/*
+	 * 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, nr_res);
+	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_non_secure_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);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 11/11] acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
@ 2017-03-21 16:31   ` fu.wei
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei @ 2017-03-21 16:31 UTC (permalink / raw)
  To: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	lorenzo.pieralisi, sudeep.holla, hanjun.guo
  Cc: linux-arm-kernel, linaro-acpi, linux-kernel, linux-acpi,
	rruigrok, harba, cov, timur, graeme.gregory, al.stone, jcm, wei,
	arnd, catalin.marinas, will.deacon, Suravee.Suthikulpanit,
	leo.duran, wim, linux, linux-watchdog, tn, christoffer.dall,
	julien.grall, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
---
 drivers/acpi/arm64/gtdt.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
index f471873..5d167f0 100644
--- a/drivers/acpi/arm64/gtdt.c
+++ b/drivers/acpi/arm64/gtdt.c
@@ -14,6 +14,7 @@
 #include <linux/acpi.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/platform_device.h>
 
 #include <clocksource/arm_arch_timer.h>
 
@@ -59,6 +60,17 @@ static inline bool is_timer_block(void *platform_timer)
 	return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK;
 }
 
+static inline bool is_non_secure_watchdog(void *platform_timer)
+{
+	struct acpi_gtdt_header *gh = platform_timer;
+	struct acpi_gtdt_watchdog *wd = platform_timer;
+
+	if (gh->type != ACPI_GTDT_TYPE_WATCHDOG)
+		return false;
+
+	return !(wd->timer_flags & ACPI_GTDT_WATCHDOG_SECURE);
+}
+
 static int __init map_gt_gsi(u32 interrupt, u32 flags)
 {
 	int trigger, polarity;
@@ -285,3 +297,85 @@ int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
 
 	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);
+
+	/*
+	 * 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),
+	};
+	int nr_res = ARRAY_SIZE(res);
+
+	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 (irq <= 0) {
+		pr_warn("failed to map the Watchdog interrupt.\n");
+		nr_res--;
+	}
+
+	/*
+	 * 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, nr_res);
+	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_non_secure_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);
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* [PATCH v22 11/11] acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
@ 2017-03-21 16:31   ` fu.wei
  0 siblings, 0 replies; 113+ messages in thread
From: fu.wei at linaro.org @ 2017-03-21 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Fu Wei <fu.wei@linaro.org>

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 <fu.wei@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
---
 drivers/acpi/arm64/gtdt.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
index f471873..5d167f0 100644
--- a/drivers/acpi/arm64/gtdt.c
+++ b/drivers/acpi/arm64/gtdt.c
@@ -14,6 +14,7 @@
 #include <linux/acpi.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/platform_device.h>
 
 #include <clocksource/arm_arch_timer.h>
 
@@ -59,6 +60,17 @@ static inline bool is_timer_block(void *platform_timer)
 	return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK;
 }
 
+static inline bool is_non_secure_watchdog(void *platform_timer)
+{
+	struct acpi_gtdt_header *gh = platform_timer;
+	struct acpi_gtdt_watchdog *wd = platform_timer;
+
+	if (gh->type != ACPI_GTDT_TYPE_WATCHDOG)
+		return false;
+
+	return !(wd->timer_flags & ACPI_GTDT_WATCHDOG_SECURE);
+}
+
 static int __init map_gt_gsi(u32 interrupt, u32 flags)
 {
 	int trigger, polarity;
@@ -285,3 +297,85 @@ int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
 
 	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);
+
+	/*
+	 * 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),
+	};
+	int nr_res = ARRAY_SIZE(res);
+
+	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 (irq <= 0) {
+		pr_warn("failed to map the Watchdog interrupt.\n");
+		nr_res--;
+	}
+
+	/*
+	 * 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, nr_res);
+	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_non_secure_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);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
  2017-03-21 16:31 ` fu.wei
@ 2017-03-28 11:32   ` Jon Masters
  -1 siblings, 0 replies; 113+ messages in thread
From: Jon Masters @ 2017-03-28 11:32 UTC (permalink / raw)
  To: fu.wei, rjw, lenb, daniel.lezcano, tglx, marc.zyngier,
	mark.rutland, lorenzo.pieralisi, sudeep.holla, hanjun.guo
  Cc: linux-arm-kernel, linaro-acpi, linux-kernel, linux-acpi,
	rruigrok, harba, cov, timur, graeme.gregory, al.stone, jcm, wei,
	arnd, catalin.marinas, will.deacon, Suravee.Suthikulpanit,
	leo.duran, wim, linux, linux-watchdog, tn, christoffer.dall,
	julien.grall

Anyone got review comments for this series?

On 03/21/2017 12:31 PM, fu.wei@linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> This patchset:
>     (1)Preparation for adding GTDT support in arm_arch_timer:
>         1. Introduce a wrapper function to get the frequency from mmio.
>         2. separate out device-tree code from arch_timer_detect_rate
>         3. remove arch_timer_detect_rate use arch_timer_*get_cntfrq directly
>         4. Refactor arch_timer_needs_probing, and move it into DT init call
>         5. Introduce some new structs and refactor the MMIO timer init code
>         for reusing some common code.
> 
>     (2)Introduce ACPI GTDT parser: drivers/acpi/arm64/acpi_gtdt.c
>     Parse all kinds of timer in GTDT table of ACPI:arch timer,
>     memory-mapped timer and SBSA Generic Watchdog timer.
>     This driver can help to simplify all the relevant timer drivers,
>     and separate all the ACPI GTDT knowledge from them.
> 
>     (3)Simplify ACPI code for arm_arch_timer
> 
>     (4)Add GTDT support for ARM memory-mapped timer.
> 
> This patchset has been tested on the following platforms with ACPI enabled:
>     (1)ARM Foundation v8 model
> 
> Changelog:
> v22: https://lkml.org/lkml/2017/3/21/
>      Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arch-timer/cleanup
>      Only Introduce arch_timer_mem_get_cntfrq to get the frequency from mmio.
>      Merged patch 2,3(about arch_timer_detect_rate).
>      Keep arch_timer_rate, do NOT split it for different types of timer.
>      Improve  memory-mapped timer support by comments and variable name:
>          data-->timer_mem
>          frame-->gtdt_frame
>      Delete zero check for SBSA watchdog irq.
>      Skip secure SBSA watchdog in GTDT driver.
>      Delete Kconfig modification for SBSA watchdog driver.
>      Delete no_irq, using nr_res instead.
> 
> v21: https://lkml.org/lkml/2017/2/6/734
>      Introduce two functions to get the frequency from mmio and sysreg.
>      Remove arch_timer_detect_rate use arch_timer_get_*_freq directly
>      Split arch_timer_rate for different types of timer.
>      Skip secure timer frame in GTDT driver.
>      Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arch-timer/cleanup
>      (The first 6 patches in v20 have been merged into arch-timer/cleanup branch)
> 
> v20: https://lkml.org/lkml/2017/1/18/534
>      Reorder the first 4 patches and split the 4th patches.
>      Leave CNTHCTL_* as they originally were.
>      Fix the bug in arch_timer_select_ppi.
>      Split "Rework counter frequency detection" patch.
>      Rework the arch_timer_detect_rate function.
>      Improve the commit message of "Refactor MMIO timer probing".
>      Rebase to 4.10.0-rc4
> 
> v19: https://lkml.org/lkml/2016/12/21/25
>      Fix a '\n' missing in a error message in arch_timer_mem_init.
>      Add "request_mem_region" for ioremapping cntbase, according to
>      f947ee1 clocksource/drivers/arm_arch_timer: Map frame with of_io_request_and_map()
>      Rebase to 4.9.0-gfb779ff
> 
> v18: https://lkml.org/lkml/2016/12/8/446
>      Fix 8/15 patch problem of "int ret;" in arch_timer_acpi_init.
>      Rebase to 4.9.0-rc8-g9269898
> 
> v17: https://lkml.org/lkml/2016/11/25/140
>      Take out some cleanups from 4/15.
>      Merge 5/15 and 6/15, improve PPI determination code,
>      improve commit message.
>      Rework counter frequency detection.
>      Move arch_timer_needs_of_probing into DT init call.
>      Move Platform Timer scan loop back to timer init call to avoid allocating
>      and free memory.
>      Improve all the exported functions' comment.
> 
> v16: https://lkml.org/lkml/2016/11/16/268
>      Fix patchset problem about static enum ppi_nr of 01/13 in v15.
>      Refactor arch_timer_detect_rate.
>      Refactor arch_timer_needs_probing.
> 
> v15: https://lkml.org/lkml/2016/11/15/366
>      Re-order patches
>      Add arm_arch_timer refactoring patches to prepare for GTDT:
>          1. rename some  enums and defines, and some cleanups
>          2. separate out arch_timer_uses_ppi init code and fix a potential bug
>          3. Improve some new structs, refactor the timer init code.
>      Since the some structs have been changed, GTDT parser for memory-mapped
>      timer and SBSA Generic Watchdog timer have been update.
> 
> v14: https://lkml.org/lkml/2016/9/28/573
>      Separate memory-mapped timer GTDT support into two patches
>          1. Refactor the timer init code to prepare for GTDT
>          2. Add GTDT support for memory-mapped timer
> 
> v13: http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1231717.html
>      Improve arm_arch_timer code for memory-mapped
>      timer GTDT support, refactor original memory-mapped timer
>      dt support for reusing some common code.
> 
> v12: https://lkml.org/lkml/2016/9/13/250
>      Rebase to latest Linux 4.8-rc6
>      Delete the confusing "skipping" in the error message.
> 
> V11: https://lkml.org/lkml/2016/9/6/354
>      Rebase to latest Linux 4.8-rc5
>      Delete typedef (suggested by checkpatch.pl)
> 
> V10: https://lkml.org/lkml/2016/7/26/215
>      Drop the "readq" patch.
>      Rebase to latest Linux 4.7.
> 
> V9: https://lkml.org/lkml/2016/7/25/345
>     Improve pr_err message in acpi gtdt driver.
>     Update Commit message for 7/9
>     shorten the irq mapping function name
>     Improve GTDT driver for memory-mapped timer
> 
> v8: https://lkml.org/lkml/2016/7/19/660
>     Improve "pr_fmt(fmt)" definition: add "ACPI" in front of "GTDT",
>     and also improve printk message.
>     Simplify is_timer_block and is_watchdog.
>     Merge acpi_gtdt_desc_init and gtdt_arch_timer_init into acpi_gtdt_init();
>     Delete __init in include/linux/acpi.h for GTDT API
>     Make ARM64 select GTDT.
>     Delete "#include <linux/module.h>" from acpi_gtdt.c
>     Simplify GT block parse code.
> 
> v7: https://lkml.org/lkml/2016/7/13/769
>     Move the GTDT driver to drivers/acpi/arm64
>     Add add the ARM64-specific ACPI Support maintainers in MAINTAINERS
>     Merge 3 patches of GTDT parser driver.
>     Fix the for_each_platform_timer bug.
> 
> v6: https://lkml.org/lkml/2016/6/29/580
>     split the GTDT driver to 4 parts: basic, arch_timer, memory-mapped timer,
>     and SBSA Generic Watchdog timer
>     Improve driver by suggestions and example code from Daniel Lezcano
> 
> v5: https://lkml.org/lkml/2016/5/24/356
>     Sorting out all patches, simplify the API of GTDT driver:
>     GTDT driver just fills the data struct for arm_arch_timer driver.
> 
> v4: https://lists.linaro.org/pipermail/linaro-acpi/2016-March/006667.html
>     Delete the kvm relevant patches
>     Separate two patches for sorting out the code for arm_arch_timer.
>     Improve irq info export code to allow missing irq info in GTDT table.
> 
> v3: https://lkml.org/lkml/2016/2/1/658
>     Improve GTDT driver code:
>       (1)improve pr_* by defining pr_fmt(fmt)
>       (2)simplify gtdt_sbsa_gwdt_init
>       (3)improve gtdt_arch_timer_data_init, if table is NULL, it will try
>       to get GTDT table.
>     Move enum ppi_nr to arm_arch_timer.h, and add enum spi_nr.
>     Add arm_arch_timer get ppi from DT and GTDT support for kvm.
> 
> v2: https://lkml.org/lkml/2015/12/2/10
>     Rebase to latest kernel version(4.4-rc3).
>     Fix the bug about the config problem,
>     use CONFIG_ACPI_GTDT instead of CONFIG_ACPI in arm_arch_timer.c
> 
> v1: The first upstreaming version: https://lkml.org/lkml/2015/10/28/553
> 
> Fu Wei (11):
>   clocksource: arm_arch_timer: introduce a wrapper function to get the
>     frequency from mmio.
>   clocksource: arm_arch_timer: separate out device-tree code and remove
>     arch_timer_detect_rate
>   clocksource: arm_arch_timer: refactor arch_timer_needs_probing
>   clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT
>     init call
>   clocksource: arm_arch_timer: introduce some new structs to prepare for
>     GTDT
>   clocksource: arm_arch_timer: refactor MMIO timer probing.
>   acpi/arm64: Add GTDT table parse driver
>   clocksource: arm_arch_timer: simplify ACPI support code.
>   acpi/arm64: Add memory-mapped timer support in GTDT driver
>   clocksource: arm_arch_timer: add GTDT support for memory-mapped timer
>   acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
> 
>  arch/arm64/Kconfig                   |   1 +
>  drivers/acpi/arm64/Kconfig           |   3 +
>  drivers/acpi/arm64/Makefile          |   1 +
>  drivers/acpi/arm64/gtdt.c            | 381 +++++++++++++++++++++++++++++++++++
>  drivers/clocksource/arm_arch_timer.c | 326 +++++++++++++++++++-----------
>  include/clocksource/arm_arch_timer.h |  17 ++
>  include/linux/acpi.h                 |   7 +
>  7 files changed, 614 insertions(+), 122 deletions(-)
>  create mode 100644 drivers/acpi/arm64/gtdt.c
> 

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
@ 2017-03-28 11:32   ` Jon Masters
  0 siblings, 0 replies; 113+ messages in thread
From: Jon Masters @ 2017-03-28 11:32 UTC (permalink / raw)
  To: linux-arm-kernel

Anyone got review comments for this series?

On 03/21/2017 12:31 PM, fu.wei at linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> This patchset:
>     (1)Preparation for adding GTDT support in arm_arch_timer:
>         1. Introduce a wrapper function to get the frequency from mmio.
>         2. separate out device-tree code from arch_timer_detect_rate
>         3. remove arch_timer_detect_rate use arch_timer_*get_cntfrq directly
>         4. Refactor arch_timer_needs_probing, and move it into DT init call
>         5. Introduce some new structs and refactor the MMIO timer init code
>         for reusing some common code.
> 
>     (2)Introduce ACPI GTDT parser: drivers/acpi/arm64/acpi_gtdt.c
>     Parse all kinds of timer in GTDT table of ACPI:arch timer,
>     memory-mapped timer and SBSA Generic Watchdog timer.
>     This driver can help to simplify all the relevant timer drivers,
>     and separate all the ACPI GTDT knowledge from them.
> 
>     (3)Simplify ACPI code for arm_arch_timer
> 
>     (4)Add GTDT support for ARM memory-mapped timer.
> 
> This patchset has been tested on the following platforms with ACPI enabled:
>     (1)ARM Foundation v8 model
> 
> Changelog:
> v22: https://lkml.org/lkml/2017/3/21/
>      Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arch-timer/cleanup
>      Only Introduce arch_timer_mem_get_cntfrq to get the frequency from mmio.
>      Merged patch 2,3(about arch_timer_detect_rate).
>      Keep arch_timer_rate, do NOT split it for different types of timer.
>      Improve  memory-mapped timer support by comments and variable name:
>          data-->timer_mem
>          frame-->gtdt_frame
>      Delete zero check for SBSA watchdog irq.
>      Skip secure SBSA watchdog in GTDT driver.
>      Delete Kconfig modification for SBSA watchdog driver.
>      Delete no_irq, using nr_res instead.
> 
> v21: https://lkml.org/lkml/2017/2/6/734
>      Introduce two functions to get the frequency from mmio and sysreg.
>      Remove arch_timer_detect_rate use arch_timer_get_*_freq directly
>      Split arch_timer_rate for different types of timer.
>      Skip secure timer frame in GTDT driver.
>      Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arch-timer/cleanup
>      (The first 6 patches in v20 have been merged into arch-timer/cleanup branch)
> 
> v20: https://lkml.org/lkml/2017/1/18/534
>      Reorder the first 4 patches and split the 4th patches.
>      Leave CNTHCTL_* as they originally were.
>      Fix the bug in arch_timer_select_ppi.
>      Split "Rework counter frequency detection" patch.
>      Rework the arch_timer_detect_rate function.
>      Improve the commit message of "Refactor MMIO timer probing".
>      Rebase to 4.10.0-rc4
> 
> v19: https://lkml.org/lkml/2016/12/21/25
>      Fix a '\n' missing in a error message in arch_timer_mem_init.
>      Add "request_mem_region" for ioremapping cntbase, according to
>      f947ee1 clocksource/drivers/arm_arch_timer: Map frame with of_io_request_and_map()
>      Rebase to 4.9.0-gfb779ff
> 
> v18: https://lkml.org/lkml/2016/12/8/446
>      Fix 8/15 patch problem of "int ret;" in arch_timer_acpi_init.
>      Rebase to 4.9.0-rc8-g9269898
> 
> v17: https://lkml.org/lkml/2016/11/25/140
>      Take out some cleanups from 4/15.
>      Merge 5/15 and 6/15, improve PPI determination code,
>      improve commit message.
>      Rework counter frequency detection.
>      Move arch_timer_needs_of_probing into DT init call.
>      Move Platform Timer scan loop back to timer init call to avoid allocating
>      and free memory.
>      Improve all the exported functions' comment.
> 
> v16: https://lkml.org/lkml/2016/11/16/268
>      Fix patchset problem about static enum ppi_nr of 01/13 in v15.
>      Refactor arch_timer_detect_rate.
>      Refactor arch_timer_needs_probing.
> 
> v15: https://lkml.org/lkml/2016/11/15/366
>      Re-order patches
>      Add arm_arch_timer refactoring patches to prepare for GTDT:
>          1. rename some  enums and defines, and some cleanups
>          2. separate out arch_timer_uses_ppi init code and fix a potential bug
>          3. Improve some new structs, refactor the timer init code.
>      Since the some structs have been changed, GTDT parser for memory-mapped
>      timer and SBSA Generic Watchdog timer have been update.
> 
> v14: https://lkml.org/lkml/2016/9/28/573
>      Separate memory-mapped timer GTDT support into two patches
>          1. Refactor the timer init code to prepare for GTDT
>          2. Add GTDT support for memory-mapped timer
> 
> v13: http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1231717.html
>      Improve arm_arch_timer code for memory-mapped
>      timer GTDT support, refactor original memory-mapped timer
>      dt support for reusing some common code.
> 
> v12: https://lkml.org/lkml/2016/9/13/250
>      Rebase to latest Linux 4.8-rc6
>      Delete the confusing "skipping" in the error message.
> 
> V11: https://lkml.org/lkml/2016/9/6/354
>      Rebase to latest Linux 4.8-rc5
>      Delete typedef (suggested by checkpatch.pl)
> 
> V10: https://lkml.org/lkml/2016/7/26/215
>      Drop the "readq" patch.
>      Rebase to latest Linux 4.7.
> 
> V9: https://lkml.org/lkml/2016/7/25/345
>     Improve pr_err message in acpi gtdt driver.
>     Update Commit message for 7/9
>     shorten the irq mapping function name
>     Improve GTDT driver for memory-mapped timer
> 
> v8: https://lkml.org/lkml/2016/7/19/660
>     Improve "pr_fmt(fmt)" definition: add "ACPI" in front of "GTDT",
>     and also improve printk message.
>     Simplify is_timer_block and is_watchdog.
>     Merge acpi_gtdt_desc_init and gtdt_arch_timer_init into acpi_gtdt_init();
>     Delete __init in include/linux/acpi.h for GTDT API
>     Make ARM64 select GTDT.
>     Delete "#include <linux/module.h>" from acpi_gtdt.c
>     Simplify GT block parse code.
> 
> v7: https://lkml.org/lkml/2016/7/13/769
>     Move the GTDT driver to drivers/acpi/arm64
>     Add add the ARM64-specific ACPI Support maintainers in MAINTAINERS
>     Merge 3 patches of GTDT parser driver.
>     Fix the for_each_platform_timer bug.
> 
> v6: https://lkml.org/lkml/2016/6/29/580
>     split the GTDT driver to 4 parts: basic, arch_timer, memory-mapped timer,
>     and SBSA Generic Watchdog timer
>     Improve driver by suggestions and example code from Daniel Lezcano
> 
> v5: https://lkml.org/lkml/2016/5/24/356
>     Sorting out all patches, simplify the API of GTDT driver:
>     GTDT driver just fills the data struct for arm_arch_timer driver.
> 
> v4: https://lists.linaro.org/pipermail/linaro-acpi/2016-March/006667.html
>     Delete the kvm relevant patches
>     Separate two patches for sorting out the code for arm_arch_timer.
>     Improve irq info export code to allow missing irq info in GTDT table.
> 
> v3: https://lkml.org/lkml/2016/2/1/658
>     Improve GTDT driver code:
>       (1)improve pr_* by defining pr_fmt(fmt)
>       (2)simplify gtdt_sbsa_gwdt_init
>       (3)improve gtdt_arch_timer_data_init, if table is NULL, it will try
>       to get GTDT table.
>     Move enum ppi_nr to arm_arch_timer.h, and add enum spi_nr.
>     Add arm_arch_timer get ppi from DT and GTDT support for kvm.
> 
> v2: https://lkml.org/lkml/2015/12/2/10
>     Rebase to latest kernel version(4.4-rc3).
>     Fix the bug about the config problem,
>     use CONFIG_ACPI_GTDT instead of CONFIG_ACPI in arm_arch_timer.c
> 
> v1: The first upstreaming version: https://lkml.org/lkml/2015/10/28/553
> 
> Fu Wei (11):
>   clocksource: arm_arch_timer: introduce a wrapper function to get the
>     frequency from mmio.
>   clocksource: arm_arch_timer: separate out device-tree code and remove
>     arch_timer_detect_rate
>   clocksource: arm_arch_timer: refactor arch_timer_needs_probing
>   clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT
>     init call
>   clocksource: arm_arch_timer: introduce some new structs to prepare for
>     GTDT
>   clocksource: arm_arch_timer: refactor MMIO timer probing.
>   acpi/arm64: Add GTDT table parse driver
>   clocksource: arm_arch_timer: simplify ACPI support code.
>   acpi/arm64: Add memory-mapped timer support in GTDT driver
>   clocksource: arm_arch_timer: add GTDT support for memory-mapped timer
>   acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
> 
>  arch/arm64/Kconfig                   |   1 +
>  drivers/acpi/arm64/Kconfig           |   3 +
>  drivers/acpi/arm64/Makefile          |   1 +
>  drivers/acpi/arm64/gtdt.c            | 381 +++++++++++++++++++++++++++++++++++
>  drivers/clocksource/arm_arch_timer.c | 326 +++++++++++++++++++-----------
>  include/clocksource/arm_arch_timer.h |  17 ++
>  include/linux/acpi.h                 |   7 +
>  7 files changed, 614 insertions(+), 122 deletions(-)
>  create mode 100644 drivers/acpi/arm64/gtdt.c
> 

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
  2017-03-21 16:31   ` fu.wei at linaro.org
@ 2017-03-28 11:35     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-28 11:35 UTC (permalink / raw)
  To: fu.wei
  Cc: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	sudeep.holla, hanjun.guo, linux-arm-kernel, linaro-acpi,
	linux-kernel, linux-acpi, rruigrok, harba, cov, timur,
	graeme.gregory, al.stone, jcm, wei, arnd, catalin.marinas,
	will.deacon, Suravee.Suthikulpanit, leo.duran, wim, linux,
	linux-watchdog, tn, christoffer.dall, julien.grall

On Wed, Mar 22, 2017 at 12:31:18AM +0800, fu.wei@linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> 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 <fu.wei@linaro.org>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

Some nits below.

> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  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(+)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 3741859..7e2baec 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 <daniel.lezcano@linaro.org>
> + *         Fu Wei <fu.wei@linaro.org>
> + *         Hanjun Guo <hanjun.guo@linaro.org>
> + *
> + * 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 <linux/acpi.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +
> +#include <clocksource/arm_arch_timer.h>
> +
> +#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.

Note: Secure state is not managed by the kernel on ARM64 systems.

Is that what you wanted to say ?

> + * 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.

Return: true if the timer HW state is lost when a CPU enters an idle
	state, false 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

I do not understand what this means.

> + *				number of platform timers. It can be NULL, if
> + *				driver don't need this info.

driver doesn't

> + *
> + * 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);

Ok, two points here. First, I am not sure why you should warn if the
table revision is < 2, is that a FW bug ? I do not think it is, you
can just return 0.

> +	else if (!gtdt->platform_timer_count)
> +		pr_debug("No Platform Timer.\n");

Ditto. Why keep executing ? There is nothing to do, just bail out
with a return 0.

> +	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;

Same here, I suspect you want to consolidate the return path (I missed
previous rounds of reviews so you should not worry too much, I can clean
this up later) but to me a:

return -EINVAL;

would just do.

Lorenzo

> +		}
> +	}
> +
> +	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 9b05886..4b5c146 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -595,6 +595,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
> -- 
> 2.9.3
> 

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-28 11:35     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-28 11:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 22, 2017 at 12:31:18AM +0800, fu.wei at linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> 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 <fu.wei@linaro.org>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

Some nits below.

> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  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(+)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 3741859..7e2baec 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 <daniel.lezcano@linaro.org>
> + *         Fu Wei <fu.wei@linaro.org>
> + *         Hanjun Guo <hanjun.guo@linaro.org>
> + *
> + * 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 <linux/acpi.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +
> +#include <clocksource/arm_arch_timer.h>
> +
> +#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.

Note: Secure state is not managed by the kernel on ARM64 systems.

Is that what you wanted to say ?

> + * 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.

Return: true if the timer HW state is lost when a CPU enters an idle
	state, false 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

I do not understand what this means.

> + *				number of platform timers. It can be NULL, if
> + *				driver don't need this info.

driver doesn't

> + *
> + * 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);

Ok, two points here. First, I am not sure why you should warn if the
table revision is < 2, is that a FW bug ? I do not think it is, you
can just return 0.

> +	else if (!gtdt->platform_timer_count)
> +		pr_debug("No Platform Timer.\n");

Ditto. Why keep executing ? There is nothing to do, just bail out
with a return 0.

> +	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;

Same here, I suspect you want to consolidate the return path (I missed
previous rounds of reviews so you should not worry too much, I can clean
this up later) but to me a:

return -EINVAL;

would just do.

Lorenzo

> +		}
> +	}
> +
> +	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 9b05886..4b5c146 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -595,6 +595,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
> -- 
> 2.9.3
> 

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
  2017-03-28 11:32   ` Jon Masters
  (?)
@ 2017-03-28 12:34     ` Fu Wei
  -1 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-28 12:34 UTC (permalink / raw)
  To: Jon Masters
  Cc: Mark Rutland, Linaro ACPI Mailman List, Catalin Marinas,
	Will Deacon, rruigrok, Wim Van Sebroeck, Wei Huang,
	Lorenzo Pieralisi, Al Stone, Tomasz Nowicki, Timur Tabi,
	Daniel Lezcano, ACPI Devel Maling List, Guenter Roeck, Len Brown,
	Abdulhamid, Harb, Julien Grall, linux-watchdog, Arnd Bergmann,
	Marc Zyngier, Jon Masters, Christopher Covington,
	Thomas Gleixner, linux-arm-kernel

Hi Jon,

Thanks for your email
 An hour ago, I just got some feedback from Lorenzo, will update my
patchset ASAP according to his suggestion.

But I still need some feedback form Mark, I can see some progress here:
https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt

I guess I should rebase my patchset to his gtdt branch for v23.

So now, I am waiting for Mark's feedback to move on.

On 28 March 2017 at 19:32, Jon Masters <jcm@jonmasters.org> wrote:
> Anyone got review comments for this series?
>
> On 03/21/2017 12:31 PM, fu.wei@linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> This patchset:
>>     (1)Preparation for adding GTDT support in arm_arch_timer:
>>         1. Introduce a wrapper function to get the frequency from mmio.
>>         2. separate out device-tree code from arch_timer_detect_rate
>>         3. remove arch_timer_detect_rate use arch_timer_*get_cntfrq directly
>>         4. Refactor arch_timer_needs_probing, and move it into DT init call
>>         5. Introduce some new structs and refactor the MMIO timer init code
>>         for reusing some common code.
>>
>>     (2)Introduce ACPI GTDT parser: drivers/acpi/arm64/acpi_gtdt.c
>>     Parse all kinds of timer in GTDT table of ACPI:arch timer,
>>     memory-mapped timer and SBSA Generic Watchdog timer.
>>     This driver can help to simplify all the relevant timer drivers,
>>     and separate all the ACPI GTDT knowledge from them.
>>
>>     (3)Simplify ACPI code for arm_arch_timer
>>
>>     (4)Add GTDT support for ARM memory-mapped timer.
>>
>> This patchset has been tested on the following platforms with ACPI enabled:
>>     (1)ARM Foundation v8 model
>>
>> Changelog:
>> v22: https://lkml.org/lkml/2017/3/21/
>>      Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arch-timer/cleanup
>>      Only Introduce arch_timer_mem_get_cntfrq to get the frequency from mmio.
>>      Merged patch 2,3(about arch_timer_detect_rate).
>>      Keep arch_timer_rate, do NOT split it for different types of timer.
>>      Improve  memory-mapped timer support by comments and variable name:
>>          data-->timer_mem
>>          frame-->gtdt_frame
>>      Delete zero check for SBSA watchdog irq.
>>      Skip secure SBSA watchdog in GTDT driver.
>>      Delete Kconfig modification for SBSA watchdog driver.
>>      Delete no_irq, using nr_res instead.
>>
>> v21: https://lkml.org/lkml/2017/2/6/734
>>      Introduce two functions to get the frequency from mmio and sysreg.
>>      Remove arch_timer_detect_rate use arch_timer_get_*_freq directly
>>      Split arch_timer_rate for different types of timer.
>>      Skip secure timer frame in GTDT driver.
>>      Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arch-timer/cleanup
>>      (The first 6 patches in v20 have been merged into arch-timer/cleanup branch)
>>
>> v20: https://lkml.org/lkml/2017/1/18/534
>>      Reorder the first 4 patches and split the 4th patches.
>>      Leave CNTHCTL_* as they originally were.
>>      Fix the bug in arch_timer_select_ppi.
>>      Split "Rework counter frequency detection" patch.
>>      Rework the arch_timer_detect_rate function.
>>      Improve the commit message of "Refactor MMIO timer probing".
>>      Rebase to 4.10.0-rc4
>>
>> v19: https://lkml.org/lkml/2016/12/21/25
>>      Fix a '\n' missing in a error message in arch_timer_mem_init.
>>      Add "request_mem_region" for ioremapping cntbase, according to
>>      f947ee1 clocksource/drivers/arm_arch_timer: Map frame with of_io_request_and_map()
>>      Rebase to 4.9.0-gfb779ff
>>
>> v18: https://lkml.org/lkml/2016/12/8/446
>>      Fix 8/15 patch problem of "int ret;" in arch_timer_acpi_init.
>>      Rebase to 4.9.0-rc8-g9269898
>>
>> v17: https://lkml.org/lkml/2016/11/25/140
>>      Take out some cleanups from 4/15.
>>      Merge 5/15 and 6/15, improve PPI determination code,
>>      improve commit message.
>>      Rework counter frequency detection.
>>      Move arch_timer_needs_of_probing into DT init call.
>>      Move Platform Timer scan loop back to timer init call to avoid allocating
>>      and free memory.
>>      Improve all the exported functions' comment.
>>
>> v16: https://lkml.org/lkml/2016/11/16/268
>>      Fix patchset problem about static enum ppi_nr of 01/13 in v15.
>>      Refactor arch_timer_detect_rate.
>>      Refactor arch_timer_needs_probing.
>>
>> v15: https://lkml.org/lkml/2016/11/15/366
>>      Re-order patches
>>      Add arm_arch_timer refactoring patches to prepare for GTDT:
>>          1. rename some  enums and defines, and some cleanups
>>          2. separate out arch_timer_uses_ppi init code and fix a potential bug
>>          3. Improve some new structs, refactor the timer init code.
>>      Since the some structs have been changed, GTDT parser for memory-mapped
>>      timer and SBSA Generic Watchdog timer have been update.
>>
>> v14: https://lkml.org/lkml/2016/9/28/573
>>      Separate memory-mapped timer GTDT support into two patches
>>          1. Refactor the timer init code to prepare for GTDT
>>          2. Add GTDT support for memory-mapped timer
>>
>> v13: http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1231717.html
>>      Improve arm_arch_timer code for memory-mapped
>>      timer GTDT support, refactor original memory-mapped timer
>>      dt support for reusing some common code.
>>
>> v12: https://lkml.org/lkml/2016/9/13/250
>>      Rebase to latest Linux 4.8-rc6
>>      Delete the confusing "skipping" in the error message.
>>
>> V11: https://lkml.org/lkml/2016/9/6/354
>>      Rebase to latest Linux 4.8-rc5
>>      Delete typedef (suggested by checkpatch.pl)
>>
>> V10: https://lkml.org/lkml/2016/7/26/215
>>      Drop the "readq" patch.
>>      Rebase to latest Linux 4.7.
>>
>> V9: https://lkml.org/lkml/2016/7/25/345
>>     Improve pr_err message in acpi gtdt driver.
>>     Update Commit message for 7/9
>>     shorten the irq mapping function name
>>     Improve GTDT driver for memory-mapped timer
>>
>> v8: https://lkml.org/lkml/2016/7/19/660
>>     Improve "pr_fmt(fmt)" definition: add "ACPI" in front of "GTDT",
>>     and also improve printk message.
>>     Simplify is_timer_block and is_watchdog.
>>     Merge acpi_gtdt_desc_init and gtdt_arch_timer_init into acpi_gtdt_init();
>>     Delete __init in include/linux/acpi.h for GTDT API
>>     Make ARM64 select GTDT.
>>     Delete "#include <linux/module.h>" from acpi_gtdt.c
>>     Simplify GT block parse code.
>>
>> v7: https://lkml.org/lkml/2016/7/13/769
>>     Move the GTDT driver to drivers/acpi/arm64
>>     Add add the ARM64-specific ACPI Support maintainers in MAINTAINERS
>>     Merge 3 patches of GTDT parser driver.
>>     Fix the for_each_platform_timer bug.
>>
>> v6: https://lkml.org/lkml/2016/6/29/580
>>     split the GTDT driver to 4 parts: basic, arch_timer, memory-mapped timer,
>>     and SBSA Generic Watchdog timer
>>     Improve driver by suggestions and example code from Daniel Lezcano
>>
>> v5: https://lkml.org/lkml/2016/5/24/356
>>     Sorting out all patches, simplify the API of GTDT driver:
>>     GTDT driver just fills the data struct for arm_arch_timer driver.
>>
>> v4: https://lists.linaro.org/pipermail/linaro-acpi/2016-March/006667.html
>>     Delete the kvm relevant patches
>>     Separate two patches for sorting out the code for arm_arch_timer.
>>     Improve irq info export code to allow missing irq info in GTDT table.
>>
>> v3: https://lkml.org/lkml/2016/2/1/658
>>     Improve GTDT driver code:
>>       (1)improve pr_* by defining pr_fmt(fmt)
>>       (2)simplify gtdt_sbsa_gwdt_init
>>       (3)improve gtdt_arch_timer_data_init, if table is NULL, it will try
>>       to get GTDT table.
>>     Move enum ppi_nr to arm_arch_timer.h, and add enum spi_nr.
>>     Add arm_arch_timer get ppi from DT and GTDT support for kvm.
>>
>> v2: https://lkml.org/lkml/2015/12/2/10
>>     Rebase to latest kernel version(4.4-rc3).
>>     Fix the bug about the config problem,
>>     use CONFIG_ACPI_GTDT instead of CONFIG_ACPI in arm_arch_timer.c
>>
>> v1: The first upstreaming version: https://lkml.org/lkml/2015/10/28/553
>>
>> Fu Wei (11):
>>   clocksource: arm_arch_timer: introduce a wrapper function to get the
>>     frequency from mmio.
>>   clocksource: arm_arch_timer: separate out device-tree code and remove
>>     arch_timer_detect_rate
>>   clocksource: arm_arch_timer: refactor arch_timer_needs_probing
>>   clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT
>>     init call
>>   clocksource: arm_arch_timer: introduce some new structs to prepare for
>>     GTDT
>>   clocksource: arm_arch_timer: refactor MMIO timer probing.
>>   acpi/arm64: Add GTDT table parse driver
>>   clocksource: arm_arch_timer: simplify ACPI support code.
>>   acpi/arm64: Add memory-mapped timer support in GTDT driver
>>   clocksource: arm_arch_timer: add GTDT support for memory-mapped timer
>>   acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
>>
>>  arch/arm64/Kconfig                   |   1 +
>>  drivers/acpi/arm64/Kconfig           |   3 +
>>  drivers/acpi/arm64/Makefile          |   1 +
>>  drivers/acpi/arm64/gtdt.c            | 381 +++++++++++++++++++++++++++++++++++
>>  drivers/clocksource/arm_arch_timer.c | 326 +++++++++++++++++++-----------
>>  include/clocksource/arm_arch_timer.h |  17 ++
>>  include/linux/acpi.h                 |   7 +
>>  7 files changed, 614 insertions(+), 122 deletions(-)
>>  create mode 100644 drivers/acpi/arm64/gtdt.c
>>
>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
@ 2017-03-28 12:34     ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-28 12:34 UTC (permalink / raw)
  To: Jon Masters
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Lorenzo Pieralisi, Sudeep Holla,
	Hanjun Guo, linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

Hi Jon,

Thanks for your email
 An hour ago, I just got some feedback from Lorenzo, will update my
patchset ASAP according to his suggestion.

But I still need some feedback form Mark, I can see some progress here:
https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt

I guess I should rebase my patchset to his gtdt branch for v23.

So now, I am waiting for Mark's feedback to move on.

On 28 March 2017 at 19:32, Jon Masters <jcm@jonmasters.org> wrote:
> Anyone got review comments for this series?
>
> On 03/21/2017 12:31 PM, fu.wei@linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> This patchset:
>>     (1)Preparation for adding GTDT support in arm_arch_timer:
>>         1. Introduce a wrapper function to get the frequency from mmio.
>>         2. separate out device-tree code from arch_timer_detect_rate
>>         3. remove arch_timer_detect_rate use arch_timer_*get_cntfrq directly
>>         4. Refactor arch_timer_needs_probing, and move it into DT init call
>>         5. Introduce some new structs and refactor the MMIO timer init code
>>         for reusing some common code.
>>
>>     (2)Introduce ACPI GTDT parser: drivers/acpi/arm64/acpi_gtdt.c
>>     Parse all kinds of timer in GTDT table of ACPI:arch timer,
>>     memory-mapped timer and SBSA Generic Watchdog timer.
>>     This driver can help to simplify all the relevant timer drivers,
>>     and separate all the ACPI GTDT knowledge from them.
>>
>>     (3)Simplify ACPI code for arm_arch_timer
>>
>>     (4)Add GTDT support for ARM memory-mapped timer.
>>
>> This patchset has been tested on the following platforms with ACPI enabled:
>>     (1)ARM Foundation v8 model
>>
>> Changelog:
>> v22: https://lkml.org/lkml/2017/3/21/
>>      Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arch-timer/cleanup
>>      Only Introduce arch_timer_mem_get_cntfrq to get the frequency from mmio.
>>      Merged patch 2,3(about arch_timer_detect_rate).
>>      Keep arch_timer_rate, do NOT split it for different types of timer.
>>      Improve  memory-mapped timer support by comments and variable name:
>>          data-->timer_mem
>>          frame-->gtdt_frame
>>      Delete zero check for SBSA watchdog irq.
>>      Skip secure SBSA watchdog in GTDT driver.
>>      Delete Kconfig modification for SBSA watchdog driver.
>>      Delete no_irq, using nr_res instead.
>>
>> v21: https://lkml.org/lkml/2017/2/6/734
>>      Introduce two functions to get the frequency from mmio and sysreg.
>>      Remove arch_timer_detect_rate use arch_timer_get_*_freq directly
>>      Split arch_timer_rate for different types of timer.
>>      Skip secure timer frame in GTDT driver.
>>      Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arch-timer/cleanup
>>      (The first 6 patches in v20 have been merged into arch-timer/cleanup branch)
>>
>> v20: https://lkml.org/lkml/2017/1/18/534
>>      Reorder the first 4 patches and split the 4th patches.
>>      Leave CNTHCTL_* as they originally were.
>>      Fix the bug in arch_timer_select_ppi.
>>      Split "Rework counter frequency detection" patch.
>>      Rework the arch_timer_detect_rate function.
>>      Improve the commit message of "Refactor MMIO timer probing".
>>      Rebase to 4.10.0-rc4
>>
>> v19: https://lkml.org/lkml/2016/12/21/25
>>      Fix a '\n' missing in a error message in arch_timer_mem_init.
>>      Add "request_mem_region" for ioremapping cntbase, according to
>>      f947ee1 clocksource/drivers/arm_arch_timer: Map frame with of_io_request_and_map()
>>      Rebase to 4.9.0-gfb779ff
>>
>> v18: https://lkml.org/lkml/2016/12/8/446
>>      Fix 8/15 patch problem of "int ret;" in arch_timer_acpi_init.
>>      Rebase to 4.9.0-rc8-g9269898
>>
>> v17: https://lkml.org/lkml/2016/11/25/140
>>      Take out some cleanups from 4/15.
>>      Merge 5/15 and 6/15, improve PPI determination code,
>>      improve commit message.
>>      Rework counter frequency detection.
>>      Move arch_timer_needs_of_probing into DT init call.
>>      Move Platform Timer scan loop back to timer init call to avoid allocating
>>      and free memory.
>>      Improve all the exported functions' comment.
>>
>> v16: https://lkml.org/lkml/2016/11/16/268
>>      Fix patchset problem about static enum ppi_nr of 01/13 in v15.
>>      Refactor arch_timer_detect_rate.
>>      Refactor arch_timer_needs_probing.
>>
>> v15: https://lkml.org/lkml/2016/11/15/366
>>      Re-order patches
>>      Add arm_arch_timer refactoring patches to prepare for GTDT:
>>          1. rename some  enums and defines, and some cleanups
>>          2. separate out arch_timer_uses_ppi init code and fix a potential bug
>>          3. Improve some new structs, refactor the timer init code.
>>      Since the some structs have been changed, GTDT parser for memory-mapped
>>      timer and SBSA Generic Watchdog timer have been update.
>>
>> v14: https://lkml.org/lkml/2016/9/28/573
>>      Separate memory-mapped timer GTDT support into two patches
>>          1. Refactor the timer init code to prepare for GTDT
>>          2. Add GTDT support for memory-mapped timer
>>
>> v13: http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1231717.html
>>      Improve arm_arch_timer code for memory-mapped
>>      timer GTDT support, refactor original memory-mapped timer
>>      dt support for reusing some common code.
>>
>> v12: https://lkml.org/lkml/2016/9/13/250
>>      Rebase to latest Linux 4.8-rc6
>>      Delete the confusing "skipping" in the error message.
>>
>> V11: https://lkml.org/lkml/2016/9/6/354
>>      Rebase to latest Linux 4.8-rc5
>>      Delete typedef (suggested by checkpatch.pl)
>>
>> V10: https://lkml.org/lkml/2016/7/26/215
>>      Drop the "readq" patch.
>>      Rebase to latest Linux 4.7.
>>
>> V9: https://lkml.org/lkml/2016/7/25/345
>>     Improve pr_err message in acpi gtdt driver.
>>     Update Commit message for 7/9
>>     shorten the irq mapping function name
>>     Improve GTDT driver for memory-mapped timer
>>
>> v8: https://lkml.org/lkml/2016/7/19/660
>>     Improve "pr_fmt(fmt)" definition: add "ACPI" in front of "GTDT",
>>     and also improve printk message.
>>     Simplify is_timer_block and is_watchdog.
>>     Merge acpi_gtdt_desc_init and gtdt_arch_timer_init into acpi_gtdt_init();
>>     Delete __init in include/linux/acpi.h for GTDT API
>>     Make ARM64 select GTDT.
>>     Delete "#include <linux/module.h>" from acpi_gtdt.c
>>     Simplify GT block parse code.
>>
>> v7: https://lkml.org/lkml/2016/7/13/769
>>     Move the GTDT driver to drivers/acpi/arm64
>>     Add add the ARM64-specific ACPI Support maintainers in MAINTAINERS
>>     Merge 3 patches of GTDT parser driver.
>>     Fix the for_each_platform_timer bug.
>>
>> v6: https://lkml.org/lkml/2016/6/29/580
>>     split the GTDT driver to 4 parts: basic, arch_timer, memory-mapped timer,
>>     and SBSA Generic Watchdog timer
>>     Improve driver by suggestions and example code from Daniel Lezcano
>>
>> v5: https://lkml.org/lkml/2016/5/24/356
>>     Sorting out all patches, simplify the API of GTDT driver:
>>     GTDT driver just fills the data struct for arm_arch_timer driver.
>>
>> v4: https://lists.linaro.org/pipermail/linaro-acpi/2016-March/006667.html
>>     Delete the kvm relevant patches
>>     Separate two patches for sorting out the code for arm_arch_timer.
>>     Improve irq info export code to allow missing irq info in GTDT table.
>>
>> v3: https://lkml.org/lkml/2016/2/1/658
>>     Improve GTDT driver code:
>>       (1)improve pr_* by defining pr_fmt(fmt)
>>       (2)simplify gtdt_sbsa_gwdt_init
>>       (3)improve gtdt_arch_timer_data_init, if table is NULL, it will try
>>       to get GTDT table.
>>     Move enum ppi_nr to arm_arch_timer.h, and add enum spi_nr.
>>     Add arm_arch_timer get ppi from DT and GTDT support for kvm.
>>
>> v2: https://lkml.org/lkml/2015/12/2/10
>>     Rebase to latest kernel version(4.4-rc3).
>>     Fix the bug about the config problem,
>>     use CONFIG_ACPI_GTDT instead of CONFIG_ACPI in arm_arch_timer.c
>>
>> v1: The first upstreaming version: https://lkml.org/lkml/2015/10/28/553
>>
>> Fu Wei (11):
>>   clocksource: arm_arch_timer: introduce a wrapper function to get the
>>     frequency from mmio.
>>   clocksource: arm_arch_timer: separate out device-tree code and remove
>>     arch_timer_detect_rate
>>   clocksource: arm_arch_timer: refactor arch_timer_needs_probing
>>   clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT
>>     init call
>>   clocksource: arm_arch_timer: introduce some new structs to prepare for
>>     GTDT
>>   clocksource: arm_arch_timer: refactor MMIO timer probing.
>>   acpi/arm64: Add GTDT table parse driver
>>   clocksource: arm_arch_timer: simplify ACPI support code.
>>   acpi/arm64: Add memory-mapped timer support in GTDT driver
>>   clocksource: arm_arch_timer: add GTDT support for memory-mapped timer
>>   acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
>>
>>  arch/arm64/Kconfig                   |   1 +
>>  drivers/acpi/arm64/Kconfig           |   3 +
>>  drivers/acpi/arm64/Makefile          |   1 +
>>  drivers/acpi/arm64/gtdt.c            | 381 +++++++++++++++++++++++++++++++++++
>>  drivers/clocksource/arm_arch_timer.c | 326 +++++++++++++++++++-----------
>>  include/clocksource/arm_arch_timer.h |  17 ++
>>  include/linux/acpi.h                 |   7 +
>>  7 files changed, 614 insertions(+), 122 deletions(-)
>>  create mode 100644 drivers/acpi/arm64/gtdt.c
>>
>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
@ 2017-03-28 12:34     ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-28 12:34 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jon,

Thanks for your email
 An hour ago, I just got some feedback from Lorenzo, will update my
patchset ASAP according to his suggestion.

But I still need some feedback form Mark, I can see some progress here:
https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt

I guess I should rebase my patchset to his gtdt branch for v23.

So now, I am waiting for Mark's feedback to move on.

On 28 March 2017 at 19:32, Jon Masters <jcm@jonmasters.org> wrote:
> Anyone got review comments for this series?
>
> On 03/21/2017 12:31 PM, fu.wei at linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> This patchset:
>>     (1)Preparation for adding GTDT support in arm_arch_timer:
>>         1. Introduce a wrapper function to get the frequency from mmio.
>>         2. separate out device-tree code from arch_timer_detect_rate
>>         3. remove arch_timer_detect_rate use arch_timer_*get_cntfrq directly
>>         4. Refactor arch_timer_needs_probing, and move it into DT init call
>>         5. Introduce some new structs and refactor the MMIO timer init code
>>         for reusing some common code.
>>
>>     (2)Introduce ACPI GTDT parser: drivers/acpi/arm64/acpi_gtdt.c
>>     Parse all kinds of timer in GTDT table of ACPI:arch timer,
>>     memory-mapped timer and SBSA Generic Watchdog timer.
>>     This driver can help to simplify all the relevant timer drivers,
>>     and separate all the ACPI GTDT knowledge from them.
>>
>>     (3)Simplify ACPI code for arm_arch_timer
>>
>>     (4)Add GTDT support for ARM memory-mapped timer.
>>
>> This patchset has been tested on the following platforms with ACPI enabled:
>>     (1)ARM Foundation v8 model
>>
>> Changelog:
>> v22: https://lkml.org/lkml/2017/3/21/
>>      Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arch-timer/cleanup
>>      Only Introduce arch_timer_mem_get_cntfrq to get the frequency from mmio.
>>      Merged patch 2,3(about arch_timer_detect_rate).
>>      Keep arch_timer_rate, do NOT split it for different types of timer.
>>      Improve  memory-mapped timer support by comments and variable name:
>>          data-->timer_mem
>>          frame-->gtdt_frame
>>      Delete zero check for SBSA watchdog irq.
>>      Skip secure SBSA watchdog in GTDT driver.
>>      Delete Kconfig modification for SBSA watchdog driver.
>>      Delete no_irq, using nr_res instead.
>>
>> v21: https://lkml.org/lkml/2017/2/6/734
>>      Introduce two functions to get the frequency from mmio and sysreg.
>>      Remove arch_timer_detect_rate use arch_timer_get_*_freq directly
>>      Split arch_timer_rate for different types of timer.
>>      Skip secure timer frame in GTDT driver.
>>      Rebase to git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arch-timer/cleanup
>>      (The first 6 patches in v20 have been merged into arch-timer/cleanup branch)
>>
>> v20: https://lkml.org/lkml/2017/1/18/534
>>      Reorder the first 4 patches and split the 4th patches.
>>      Leave CNTHCTL_* as they originally were.
>>      Fix the bug in arch_timer_select_ppi.
>>      Split "Rework counter frequency detection" patch.
>>      Rework the arch_timer_detect_rate function.
>>      Improve the commit message of "Refactor MMIO timer probing".
>>      Rebase to 4.10.0-rc4
>>
>> v19: https://lkml.org/lkml/2016/12/21/25
>>      Fix a '\n' missing in a error message in arch_timer_mem_init.
>>      Add "request_mem_region" for ioremapping cntbase, according to
>>      f947ee1 clocksource/drivers/arm_arch_timer: Map frame with of_io_request_and_map()
>>      Rebase to 4.9.0-gfb779ff
>>
>> v18: https://lkml.org/lkml/2016/12/8/446
>>      Fix 8/15 patch problem of "int ret;" in arch_timer_acpi_init.
>>      Rebase to 4.9.0-rc8-g9269898
>>
>> v17: https://lkml.org/lkml/2016/11/25/140
>>      Take out some cleanups from 4/15.
>>      Merge 5/15 and 6/15, improve PPI determination code,
>>      improve commit message.
>>      Rework counter frequency detection.
>>      Move arch_timer_needs_of_probing into DT init call.
>>      Move Platform Timer scan loop back to timer init call to avoid allocating
>>      and free memory.
>>      Improve all the exported functions' comment.
>>
>> v16: https://lkml.org/lkml/2016/11/16/268
>>      Fix patchset problem about static enum ppi_nr of 01/13 in v15.
>>      Refactor arch_timer_detect_rate.
>>      Refactor arch_timer_needs_probing.
>>
>> v15: https://lkml.org/lkml/2016/11/15/366
>>      Re-order patches
>>      Add arm_arch_timer refactoring patches to prepare for GTDT:
>>          1. rename some  enums and defines, and some cleanups
>>          2. separate out arch_timer_uses_ppi init code and fix a potential bug
>>          3. Improve some new structs, refactor the timer init code.
>>      Since the some structs have been changed, GTDT parser for memory-mapped
>>      timer and SBSA Generic Watchdog timer have been update.
>>
>> v14: https://lkml.org/lkml/2016/9/28/573
>>      Separate memory-mapped timer GTDT support into two patches
>>          1. Refactor the timer init code to prepare for GTDT
>>          2. Add GTDT support for memory-mapped timer
>>
>> v13: http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1231717.html
>>      Improve arm_arch_timer code for memory-mapped
>>      timer GTDT support, refactor original memory-mapped timer
>>      dt support for reusing some common code.
>>
>> v12: https://lkml.org/lkml/2016/9/13/250
>>      Rebase to latest Linux 4.8-rc6
>>      Delete the confusing "skipping" in the error message.
>>
>> V11: https://lkml.org/lkml/2016/9/6/354
>>      Rebase to latest Linux 4.8-rc5
>>      Delete typedef (suggested by checkpatch.pl)
>>
>> V10: https://lkml.org/lkml/2016/7/26/215
>>      Drop the "readq" patch.
>>      Rebase to latest Linux 4.7.
>>
>> V9: https://lkml.org/lkml/2016/7/25/345
>>     Improve pr_err message in acpi gtdt driver.
>>     Update Commit message for 7/9
>>     shorten the irq mapping function name
>>     Improve GTDT driver for memory-mapped timer
>>
>> v8: https://lkml.org/lkml/2016/7/19/660
>>     Improve "pr_fmt(fmt)" definition: add "ACPI" in front of "GTDT",
>>     and also improve printk message.
>>     Simplify is_timer_block and is_watchdog.
>>     Merge acpi_gtdt_desc_init and gtdt_arch_timer_init into acpi_gtdt_init();
>>     Delete __init in include/linux/acpi.h for GTDT API
>>     Make ARM64 select GTDT.
>>     Delete "#include <linux/module.h>" from acpi_gtdt.c
>>     Simplify GT block parse code.
>>
>> v7: https://lkml.org/lkml/2016/7/13/769
>>     Move the GTDT driver to drivers/acpi/arm64
>>     Add add the ARM64-specific ACPI Support maintainers in MAINTAINERS
>>     Merge 3 patches of GTDT parser driver.
>>     Fix the for_each_platform_timer bug.
>>
>> v6: https://lkml.org/lkml/2016/6/29/580
>>     split the GTDT driver to 4 parts: basic, arch_timer, memory-mapped timer,
>>     and SBSA Generic Watchdog timer
>>     Improve driver by suggestions and example code from Daniel Lezcano
>>
>> v5: https://lkml.org/lkml/2016/5/24/356
>>     Sorting out all patches, simplify the API of GTDT driver:
>>     GTDT driver just fills the data struct for arm_arch_timer driver.
>>
>> v4: https://lists.linaro.org/pipermail/linaro-acpi/2016-March/006667.html
>>     Delete the kvm relevant patches
>>     Separate two patches for sorting out the code for arm_arch_timer.
>>     Improve irq info export code to allow missing irq info in GTDT table.
>>
>> v3: https://lkml.org/lkml/2016/2/1/658
>>     Improve GTDT driver code:
>>       (1)improve pr_* by defining pr_fmt(fmt)
>>       (2)simplify gtdt_sbsa_gwdt_init
>>       (3)improve gtdt_arch_timer_data_init, if table is NULL, it will try
>>       to get GTDT table.
>>     Move enum ppi_nr to arm_arch_timer.h, and add enum spi_nr.
>>     Add arm_arch_timer get ppi from DT and GTDT support for kvm.
>>
>> v2: https://lkml.org/lkml/2015/12/2/10
>>     Rebase to latest kernel version(4.4-rc3).
>>     Fix the bug about the config problem,
>>     use CONFIG_ACPI_GTDT instead of CONFIG_ACPI in arm_arch_timer.c
>>
>> v1: The first upstreaming version: https://lkml.org/lkml/2015/10/28/553
>>
>> Fu Wei (11):
>>   clocksource: arm_arch_timer: introduce a wrapper function to get the
>>     frequency from mmio.
>>   clocksource: arm_arch_timer: separate out device-tree code and remove
>>     arch_timer_detect_rate
>>   clocksource: arm_arch_timer: refactor arch_timer_needs_probing
>>   clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT
>>     init call
>>   clocksource: arm_arch_timer: introduce some new structs to prepare for
>>     GTDT
>>   clocksource: arm_arch_timer: refactor MMIO timer probing.
>>   acpi/arm64: Add GTDT table parse driver
>>   clocksource: arm_arch_timer: simplify ACPI support code.
>>   acpi/arm64: Add memory-mapped timer support in GTDT driver
>>   clocksource: arm_arch_timer: add GTDT support for memory-mapped timer
>>   acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
>>
>>  arch/arm64/Kconfig                   |   1 +
>>  drivers/acpi/arm64/Kconfig           |   3 +
>>  drivers/acpi/arm64/Makefile          |   1 +
>>  drivers/acpi/arm64/gtdt.c            | 381 +++++++++++++++++++++++++++++++++++
>>  drivers/clocksource/arm_arch_timer.c | 326 +++++++++++++++++++-----------
>>  include/clocksource/arm_arch_timer.h |  17 ++
>>  include/linux/acpi.h                 |   7 +
>>  7 files changed, 614 insertions(+), 122 deletions(-)
>>  create mode 100644 drivers/acpi/arm64/gtdt.c
>>
>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
  2017-03-28 12:34     ` Fu Wei
  (?)
@ 2017-03-28 13:05       ` Mark Rutland
  -1 siblings, 0 replies; 113+ messages in thread
From: Mark Rutland @ 2017-03-28 13:05 UTC (permalink / raw)
  To: Fu Wei
  Cc: Linaro ACPI Mailman List, Catalin Marinas, Will Deacon, rruigrok,
	Wim Van Sebroeck, Wei Huang, Lorenzo Pieralisi, Arnd Bergmann,
	Al Stone, Tomasz Nowicki, Timur Tabi, Daniel Lezcano,
	ACPI Devel Maling List, Guenter Roeck, Len Brown, Abdulhamid,
	Harb, Julien Grall, linux-watchdog, Jon Masters, Marc Zyngier,
	Jon Masters, Christopher Covington, Thomas Gleixner,
	linux-arm-kernel

On Tue, Mar 28, 2017 at 08:34:12PM +0800, Fu Wei wrote:
> Hi Jon,
> 
> Thanks for your email
>  An hour ago, I just got some feedback from Lorenzo, will update my
> patchset ASAP according to his suggestion.
> 
> But I still need some feedback form Mark, I can see some progress here:
> https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt
> 
> I guess I should rebase my patchset to his gtdt branch for v23.
> 
> So now, I am waiting for Mark's feedback to move on.

Sorry for the delay; I have not had the time to focus on this as I would
like to. I'm happy with patches 1-4, but from patch 5 onwards, there's
one change I'd like to see.

I'd prefer that mmio timer frame rame N was always stored at
arch_timer_mem::frame[N], rather than arch_timer_mem::frame[] being in
an arbitrary order. That will make arch_timer_mem_frame::frame_nr
redundant.

To allow arch_timer_mem::frame[] this to be sparse, I'm happy to have a
bool arch_timer_mem_frame::valid field that we set when probing each
frame. Then we don't need arch_timer_mem::num_frames.

This will make iterating over the frames far less confusing, and makes
it simple to detect when a frame number is erroneously reused.

Otherwise, I'm largely happy to pick the rest and apply any fixups
myself.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
@ 2017-03-28 13:05       ` Mark Rutland
  0 siblings, 0 replies; 113+ messages in thread
From: Mark Rutland @ 2017-03-28 13:05 UTC (permalink / raw)
  To: Fu Wei
  Cc: Jon Masters, Rafael J. Wysocki, Len Brown, Daniel Lezcano,
	Thomas Gleixner, Marc Zyngier, Lorenzo Pieralisi, Sudeep Holla,
	Hanjun Guo, linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

On Tue, Mar 28, 2017 at 08:34:12PM +0800, Fu Wei wrote:
> Hi Jon,
> 
> Thanks for your email
>  An hour ago, I just got some feedback from Lorenzo, will update my
> patchset ASAP according to his suggestion.
> 
> But I still need some feedback form Mark, I can see some progress here:
> https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt
> 
> I guess I should rebase my patchset to his gtdt branch for v23.
> 
> So now, I am waiting for Mark's feedback to move on.

Sorry for the delay; I have not had the time to focus on this as I would
like to. I'm happy with patches 1-4, but from patch 5 onwards, there's
one change I'd like to see.

I'd prefer that mmio timer frame rame N was always stored at
arch_timer_mem::frame[N], rather than arch_timer_mem::frame[] being in
an arbitrary order. That will make arch_timer_mem_frame::frame_nr
redundant.

To allow arch_timer_mem::frame[] this to be sparse, I'm happy to have a
bool arch_timer_mem_frame::valid field that we set when probing each
frame. Then we don't need arch_timer_mem::num_frames.

This will make iterating over the frames far less confusing, and makes
it simple to detect when a frame number is erroneously reused.

Otherwise, I'm largely happy to pick the rest and apply any fixups
myself.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
@ 2017-03-28 13:05       ` Mark Rutland
  0 siblings, 0 replies; 113+ messages in thread
From: Mark Rutland @ 2017-03-28 13:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 28, 2017 at 08:34:12PM +0800, Fu Wei wrote:
> Hi Jon,
> 
> Thanks for your email
>  An hour ago, I just got some feedback from Lorenzo, will update my
> patchset ASAP according to his suggestion.
> 
> But I still need some feedback form Mark, I can see some progress here:
> https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt
> 
> I guess I should rebase my patchset to his gtdt branch for v23.
> 
> So now, I am waiting for Mark's feedback to move on.

Sorry for the delay; I have not had the time to focus on this as I would
like to. I'm happy with patches 1-4, but from patch 5 onwards, there's
one change I'd like to see.

I'd prefer that mmio timer frame rame N was always stored at
arch_timer_mem::frame[N], rather than arch_timer_mem::frame[] being in
an arbitrary order. That will make arch_timer_mem_frame::frame_nr
redundant.

To allow arch_timer_mem::frame[] this to be sparse, I'm happy to have a
bool arch_timer_mem_frame::valid field that we set when probing each
frame. Then we don't need arch_timer_mem::num_frames.

This will make iterating over the frames far less confusing, and makes
it simple to detect when a frame number is erroneously reused.

Otherwise, I'm largely happy to pick the rest and apply any fixups
myself.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
  2017-03-28 13:05       ` Mark Rutland
  (?)
@ 2017-03-28 14:29         ` Fu Wei
  -1 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-28 14:29 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Jon Masters, Rafael J. Wysocki, Len Brown, Daniel Lezcano,
	Thomas Gleixner, Marc Zyngier, Lorenzo Pieralisi, Sudeep Holla,
	Hanjun Guo, linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone

Hi Mark,

On 28 March 2017 at 21:05, Mark Rutland <mark.rutland@arm.com> wrote:
> On Tue, Mar 28, 2017 at 08:34:12PM +0800, Fu Wei wrote:
>> Hi Jon,
>>
>> Thanks for your email
>>  An hour ago, I just got some feedback from Lorenzo, will update my
>> patchset ASAP according to his suggestion.
>>
>> But I still need some feedback form Mark, I can see some progress here:
>> https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt
>>
>> I guess I should rebase my patchset to his gtdt branch for v23.
>>
>> So now, I am waiting for Mark's feedback to move on.
>
> Sorry for the delay; I have not had the time to focus on this as I would
> like to. I'm happy with patches 1-4, but from patch 5 onwards, there's
> one change I'd like to see.
>
> I'd prefer that mmio timer frame rame N was always stored at
> arch_timer_mem::frame[N], rather than arch_timer_mem::frame[] being in
> an arbitrary order. That will make arch_timer_mem_frame::frame_nr
> redundant.
>
> To allow arch_timer_mem::frame[] this to be sparse, I'm happy to have a
> bool arch_timer_mem_frame::valid field that we set when probing each
> frame. Then we don't need arch_timer_mem::num_frames.
>
> This will make iterating over the frames far less confusing, and makes
> it simple to detect when a frame number is erroneously reused.
>
> Otherwise, I'm largely happy to pick the rest and apply any fixups
> myself.

Great thanks for your feedback!
I will follow your suggestion to improve my patches, then post it in a day.

So I will rebase my patchset on arch-timer/gtdt branch of your REPO
https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt

>
> Thanks,
> Mark.



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
@ 2017-03-28 14:29         ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-28 14:29 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Jon Masters, Rafael J. Wysocki, Len Brown, Daniel Lezcano,
	Thomas Gleixner, Marc Zyngier, Lorenzo Pieralisi, Sudeep Holla,
	Hanjun Guo, linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

Hi Mark,

On 28 March 2017 at 21:05, Mark Rutland <mark.rutland@arm.com> wrote:
> On Tue, Mar 28, 2017 at 08:34:12PM +0800, Fu Wei wrote:
>> Hi Jon,
>>
>> Thanks for your email
>>  An hour ago, I just got some feedback from Lorenzo, will update my
>> patchset ASAP according to his suggestion.
>>
>> But I still need some feedback form Mark, I can see some progress here:
>> https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt
>>
>> I guess I should rebase my patchset to his gtdt branch for v23.
>>
>> So now, I am waiting for Mark's feedback to move on.
>
> Sorry for the delay; I have not had the time to focus on this as I would
> like to. I'm happy with patches 1-4, but from patch 5 onwards, there's
> one change I'd like to see.
>
> I'd prefer that mmio timer frame rame N was always stored at
> arch_timer_mem::frame[N], rather than arch_timer_mem::frame[] being in
> an arbitrary order. That will make arch_timer_mem_frame::frame_nr
> redundant.
>
> To allow arch_timer_mem::frame[] this to be sparse, I'm happy to have a
> bool arch_timer_mem_frame::valid field that we set when probing each
> frame. Then we don't need arch_timer_mem::num_frames.
>
> This will make iterating over the frames far less confusing, and makes
> it simple to detect when a frame number is erroneously reused.
>
> Otherwise, I'm largely happy to pick the rest and apply any fixups
> myself.

Great thanks for your feedback!
I will follow your suggestion to improve my patches, then post it in a day.

So I will rebase my patchset on arch-timer/gtdt branch of your REPO
https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt

>
> Thanks,
> Mark.



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
@ 2017-03-28 14:29         ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-28 14:29 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark,

On 28 March 2017 at 21:05, Mark Rutland <mark.rutland@arm.com> wrote:
> On Tue, Mar 28, 2017 at 08:34:12PM +0800, Fu Wei wrote:
>> Hi Jon,
>>
>> Thanks for your email
>>  An hour ago, I just got some feedback from Lorenzo, will update my
>> patchset ASAP according to his suggestion.
>>
>> But I still need some feedback form Mark, I can see some progress here:
>> https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt
>>
>> I guess I should rebase my patchset to his gtdt branch for v23.
>>
>> So now, I am waiting for Mark's feedback to move on.
>
> Sorry for the delay; I have not had the time to focus on this as I would
> like to. I'm happy with patches 1-4, but from patch 5 onwards, there's
> one change I'd like to see.
>
> I'd prefer that mmio timer frame rame N was always stored at
> arch_timer_mem::frame[N], rather than arch_timer_mem::frame[] being in
> an arbitrary order. That will make arch_timer_mem_frame::frame_nr
> redundant.
>
> To allow arch_timer_mem::frame[] this to be sparse, I'm happy to have a
> bool arch_timer_mem_frame::valid field that we set when probing each
> frame. Then we don't need arch_timer_mem::num_frames.
>
> This will make iterating over the frames far less confusing, and makes
> it simple to detect when a frame number is erroneously reused.
>
> Otherwise, I'm largely happy to pick the rest and apply any fixups
> myself.

Great thanks for your feedback!
I will follow your suggestion to improve my patches, then post it in a day.

So I will rebase my patchset on arch-timer/gtdt branch of your REPO
https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt

>
> Thanks,
> Mark.



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
  2017-03-28 14:29         ` Fu Wei
  (?)
@ 2017-03-28 14:53           ` Mark Rutland
  -1 siblings, 0 replies; 113+ messages in thread
From: Mark Rutland @ 2017-03-28 14:53 UTC (permalink / raw)
  To: Fu Wei
  Cc: Linaro ACPI Mailman List, Catalin Marinas, Will Deacon, rruigrok,
	Wim Van Sebroeck, Wei Huang, Lorenzo Pieralisi, Arnd Bergmann,
	Al Stone, Tomasz Nowicki, Timur Tabi, Daniel Lezcano,
	ACPI Devel Maling List, Guenter Roeck, Len Brown, Abdulhamid,
	Harb, Julien Grall, linux-watchdog, Jon Masters, Marc Zyngier,
	Jon Masters, Christopher Covington, Thomas Gleixner,
	linux-arm-kernel

Hi,

On Tue, Mar 28, 2017 at 10:29:10PM +0800, Fu Wei wrote:
> On 28 March 2017 at 21:05, Mark Rutland <mark.rutland@arm.com> wrote:
> > Sorry for the delay; I have not had the time to focus on this as I would
> > like to. I'm happy with patches 1-4, but from patch 5 onwards, there's
> > one change I'd like to see.
> >
> > I'd prefer that mmio timer frame rame N was always stored at
> > arch_timer_mem::frame[N], rather than arch_timer_mem::frame[] being in
> > an arbitrary order. That will make arch_timer_mem_frame::frame_nr
> > redundant.
> >
> > To allow arch_timer_mem::frame[] this to be sparse, I'm happy to have a
> > bool arch_timer_mem_frame::valid field that we set when probing each
> > frame. Then we don't need arch_timer_mem::num_frames.
> >
> > This will make iterating over the frames far less confusing, and makes
> > it simple to detect when a frame number is erroneously reused.
> >
> > Otherwise, I'm largely happy to pick the rest and apply any fixups
> > myself.
> 
> Great thanks for your feedback!
> I will follow your suggestion to improve my patches, then post it in a day.

Thanks, that is much appreciated.

> So I will rebase my patchset on arch-timer/gtdt branch of your REPO
> https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt

Yes please! The current HEAD should be:

ebbfe8889cffa12f ("clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call").

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
@ 2017-03-28 14:53           ` Mark Rutland
  0 siblings, 0 replies; 113+ messages in thread
From: Mark Rutland @ 2017-03-28 14:53 UTC (permalink / raw)
  To: Fu Wei
  Cc: Jon Masters, Rafael J. Wysocki, Len Brown, Daniel Lezcano,
	Thomas Gleixner, Marc Zyngier, Lorenzo Pieralisi, Sudeep Holla,
	Hanjun Guo, linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

Hi,

On Tue, Mar 28, 2017 at 10:29:10PM +0800, Fu Wei wrote:
> On 28 March 2017 at 21:05, Mark Rutland <mark.rutland@arm.com> wrote:
> > Sorry for the delay; I have not had the time to focus on this as I would
> > like to. I'm happy with patches 1-4, but from patch 5 onwards, there's
> > one change I'd like to see.
> >
> > I'd prefer that mmio timer frame rame N was always stored at
> > arch_timer_mem::frame[N], rather than arch_timer_mem::frame[] being in
> > an arbitrary order. That will make arch_timer_mem_frame::frame_nr
> > redundant.
> >
> > To allow arch_timer_mem::frame[] this to be sparse, I'm happy to have a
> > bool arch_timer_mem_frame::valid field that we set when probing each
> > frame. Then we don't need arch_timer_mem::num_frames.
> >
> > This will make iterating over the frames far less confusing, and makes
> > it simple to detect when a frame number is erroneously reused.
> >
> > Otherwise, I'm largely happy to pick the rest and apply any fixups
> > myself.
> 
> Great thanks for your feedback!
> I will follow your suggestion to improve my patches, then post it in a day.

Thanks, that is much appreciated.

> So I will rebase my patchset on arch-timer/gtdt branch of your REPO
> https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt

Yes please! The current HEAD should be:

ebbfe8889cffa12f ("clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call").

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
@ 2017-03-28 14:53           ` Mark Rutland
  0 siblings, 0 replies; 113+ messages in thread
From: Mark Rutland @ 2017-03-28 14:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tue, Mar 28, 2017 at 10:29:10PM +0800, Fu Wei wrote:
> On 28 March 2017 at 21:05, Mark Rutland <mark.rutland@arm.com> wrote:
> > Sorry for the delay; I have not had the time to focus on this as I would
> > like to. I'm happy with patches 1-4, but from patch 5 onwards, there's
> > one change I'd like to see.
> >
> > I'd prefer that mmio timer frame rame N was always stored at
> > arch_timer_mem::frame[N], rather than arch_timer_mem::frame[] being in
> > an arbitrary order. That will make arch_timer_mem_frame::frame_nr
> > redundant.
> >
> > To allow arch_timer_mem::frame[] this to be sparse, I'm happy to have a
> > bool arch_timer_mem_frame::valid field that we set when probing each
> > frame. Then we don't need arch_timer_mem::num_frames.
> >
> > This will make iterating over the frames far less confusing, and makes
> > it simple to detect when a frame number is erroneously reused.
> >
> > Otherwise, I'm largely happy to pick the rest and apply any fixups
> > myself.
> 
> Great thanks for your feedback!
> I will follow your suggestion to improve my patches, then post it in a day.

Thanks, that is much appreciated.

> So I will rebase my patchset on arch-timer/gtdt branch of your REPO
> https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt

Yes please! The current HEAD should be:

ebbfe8889cffa12f ("clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call").

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
  2017-03-21 16:31   ` fu.wei at linaro.org
  (?)
@ 2017-03-28 14:58     ` Daniel Lezcano
  -1 siblings, 0 replies; 113+ messages in thread
From: Daniel Lezcano @ 2017-03-28 14:58 UTC (permalink / raw)
  To: fu.wei
  Cc: rjw, lenb, tglx, marc.zyngier, mark.rutland, lorenzo.pieralisi,
	sudeep.holla, hanjun.guo, linux-arm-kernel, linaro-acpi,
	linux-kernel, linux-acpi, rruigrok, harba, cov, timur,
	graeme.gregory, al.stone, jcm, wei, arnd, catalin.marinas,
	will.deacon, Suravee.Suthikulpanit, leo.duran, wim, linux,
	linux-watchdog, tn, christoffer.dall, julien.grall

On Wed, Mar 22, 2017 at 12:31:13AM +0800, fu.wei@linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> Currently, the counter frequency detection call(arch_timer_detect_rate)
> includes getting the frequency from the device-tree property, the per-cpu
> arch-timer and the memory-mapped (MMIO) timer interfaces.
> But reading device-tree property will be needed only when system boot with
> device-tree, and reading from the per-cpu arch-timer and the memory-mapped
> (MMIO) timer interfaces will be needed only when the system initializes
> the relevant timer.
> 
> This patch separates out device-tree code, keep them in device-tree init
> function, and removes arch_timer_detect_rate founction, then uses the
> arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.
> 
> Signed-off-by: Fu Wei <fu.wei@linaro.org>
> ---
>  drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
>  1 file changed, 30 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 843f923..29ca7d6 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
>  	return readl_relaxed(cntbase + CNTFRQ);
>  }
>  
> -static void
> -arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
> -{
> -	/* Who has more than one independent system counter? */
> -	if (arch_timer_rate)
> -		return;
> -
> -	/*
> -	 * Try to determine the frequency from the device tree or CNTFRQ,
> -	 * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
> -	 */
> -	if (!acpi_disabled ||
> -	    of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
> -		if (cntbase)
> -			arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
> -		else
> -			arch_timer_rate = arch_timer_get_cntfrq();
> -	}
> -
> -	/* 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",
> @@ -958,7 +934,17 @@ 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_detect_rate(NULL, np);
> +	/*
> +	 * Try to determine the frequency from the device tree,
> +	 * if fail, get the frequency from the sysreg CNTFRQ.
> +	 */
> +	if (!arch_timer_rate &&

This variable is set only if "arm,armv7-timer" and "arm,armv7-timer-mem" are
declared together in the DT, right ?

Two declarations for a single variable ? Ignore the !arch_timer_rate.

> +	    of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
> +		arch_timer_rate = arch_timer_get_cntfrq();
> +	if (!arch_timer_rate) {
> +		pr_err(FW_BUG "frequency not available.\n");
> +		return -EINVAL;
> +	}

Please, clarify this block, the conditions are unclear.

>  
>  	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
>  
> @@ -1069,7 +1055,19 @@ static int __init arch_timer_mem_init(struct device_node *np)
>  		goto out;
>  	}
>  
> -	arch_timer_detect_rate(base, 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_mem_get_cntfrq(base);
> +	if (!arch_timer_rate) {
> +		pr_err(FW_BUG "MMIO frequency not available.\n");
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
>  	ret = arch_timer_mem_register(base, irq);
>  	if (ret)
>  		goto out;
> @@ -1130,8 +1128,12 @@ 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);
>  
> -	/* Get the frequency from CNTFRQ */
> -	arch_timer_detect_rate(NULL, NULL);
> +	/* Get the frequency from the sysreg CNTFRQ */
> +	arch_timer_rate = arch_timer_get_cntfrq();
> +	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]) {
> -- 
> 2.9.3
> 

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
@ 2017-03-28 14:58     ` Daniel Lezcano
  0 siblings, 0 replies; 113+ messages in thread
From: Daniel Lezcano @ 2017-03-28 14:58 UTC (permalink / raw)
  To: fu.wei
  Cc: rjw, lenb, tglx, marc.zyngier, mark.rutland, lorenzo.pieralisi,
	sudeep.holla, hanjun.guo, linux-arm-kernel, linaro-acpi,
	linux-kernel, linux-acpi, rruigrok, harba, cov, timur,
	graeme.gregory, al.stone, jcm, wei, arnd, catalin.marinas,
	will.deacon, Suravee.Suthikulpanit, leo.duran, wim, linux,
	linux-watchdog, tn, christoffer.dall, julien.grall

On Wed, Mar 22, 2017 at 12:31:13AM +0800, fu.wei@linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> Currently, the counter frequency detection call(arch_timer_detect_rate)
> includes getting the frequency from the device-tree property, the per-cpu
> arch-timer and the memory-mapped (MMIO) timer interfaces.
> But reading device-tree property will be needed only when system boot with
> device-tree, and reading from the per-cpu arch-timer and the memory-mapped
> (MMIO) timer interfaces will be needed only when the system initializes
> the relevant timer.
> 
> This patch separates out device-tree code, keep them in device-tree init
> function, and removes arch_timer_detect_rate founction, then uses the
> arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.
> 
> Signed-off-by: Fu Wei <fu.wei@linaro.org>
> ---
>  drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
>  1 file changed, 30 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 843f923..29ca7d6 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
>  	return readl_relaxed(cntbase + CNTFRQ);
>  }
>  
> -static void
> -arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
> -{
> -	/* Who has more than one independent system counter? */
> -	if (arch_timer_rate)
> -		return;
> -
> -	/*
> -	 * Try to determine the frequency from the device tree or CNTFRQ,
> -	 * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
> -	 */
> -	if (!acpi_disabled ||
> -	    of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
> -		if (cntbase)
> -			arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
> -		else
> -			arch_timer_rate = arch_timer_get_cntfrq();
> -	}
> -
> -	/* 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",
> @@ -958,7 +934,17 @@ 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_detect_rate(NULL, np);
> +	/*
> +	 * Try to determine the frequency from the device tree,
> +	 * if fail, get the frequency from the sysreg CNTFRQ.
> +	 */
> +	if (!arch_timer_rate &&

This variable is set only if "arm,armv7-timer" and "arm,armv7-timer-mem" are
declared together in the DT, right ?

Two declarations for a single variable ? Ignore the !arch_timer_rate.

> +	    of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
> +		arch_timer_rate = arch_timer_get_cntfrq();
> +	if (!arch_timer_rate) {
> +		pr_err(FW_BUG "frequency not available.\n");
> +		return -EINVAL;
> +	}

Please, clarify this block, the conditions are unclear.

>  
>  	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
>  
> @@ -1069,7 +1055,19 @@ static int __init arch_timer_mem_init(struct device_node *np)
>  		goto out;
>  	}
>  
> -	arch_timer_detect_rate(base, 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_mem_get_cntfrq(base);
> +	if (!arch_timer_rate) {
> +		pr_err(FW_BUG "MMIO frequency not available.\n");
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
>  	ret = arch_timer_mem_register(base, irq);
>  	if (ret)
>  		goto out;
> @@ -1130,8 +1128,12 @@ 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);
>  
> -	/* Get the frequency from CNTFRQ */
> -	arch_timer_detect_rate(NULL, NULL);
> +	/* Get the frequency from the sysreg CNTFRQ */
> +	arch_timer_rate = arch_timer_get_cntfrq();
> +	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]) {
> -- 
> 2.9.3
> 

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
@ 2017-03-28 14:58     ` Daniel Lezcano
  0 siblings, 0 replies; 113+ messages in thread
From: Daniel Lezcano @ 2017-03-28 14:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 22, 2017 at 12:31:13AM +0800, fu.wei at linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> Currently, the counter frequency detection call(arch_timer_detect_rate)
> includes getting the frequency from the device-tree property, the per-cpu
> arch-timer and the memory-mapped (MMIO) timer interfaces.
> But reading device-tree property will be needed only when system boot with
> device-tree, and reading from the per-cpu arch-timer and the memory-mapped
> (MMIO) timer interfaces will be needed only when the system initializes
> the relevant timer.
> 
> This patch separates out device-tree code, keep them in device-tree init
> function, and removes arch_timer_detect_rate founction, then uses the
> arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.
> 
> Signed-off-by: Fu Wei <fu.wei@linaro.org>
> ---
>  drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
>  1 file changed, 30 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 843f923..29ca7d6 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
>  	return readl_relaxed(cntbase + CNTFRQ);
>  }
>  
> -static void
> -arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
> -{
> -	/* Who has more than one independent system counter? */
> -	if (arch_timer_rate)
> -		return;
> -
> -	/*
> -	 * Try to determine the frequency from the device tree or CNTFRQ,
> -	 * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
> -	 */
> -	if (!acpi_disabled ||
> -	    of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
> -		if (cntbase)
> -			arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
> -		else
> -			arch_timer_rate = arch_timer_get_cntfrq();
> -	}
> -
> -	/* 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",
> @@ -958,7 +934,17 @@ 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_detect_rate(NULL, np);
> +	/*
> +	 * Try to determine the frequency from the device tree,
> +	 * if fail, get the frequency from the sysreg CNTFRQ.
> +	 */
> +	if (!arch_timer_rate &&

This variable is set only if "arm,armv7-timer" and "arm,armv7-timer-mem" are
declared together in the DT, right ?

Two declarations for a single variable ? Ignore the !arch_timer_rate.

> +	    of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
> +		arch_timer_rate = arch_timer_get_cntfrq();
> +	if (!arch_timer_rate) {
> +		pr_err(FW_BUG "frequency not available.\n");
> +		return -EINVAL;
> +	}

Please, clarify this block, the conditions are unclear.

>  
>  	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
>  
> @@ -1069,7 +1055,19 @@ static int __init arch_timer_mem_init(struct device_node *np)
>  		goto out;
>  	}
>  
> -	arch_timer_detect_rate(base, 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_mem_get_cntfrq(base);
> +	if (!arch_timer_rate) {
> +		pr_err(FW_BUG "MMIO frequency not available.\n");
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
>  	ret = arch_timer_mem_register(base, irq);
>  	if (ret)
>  		goto out;
> @@ -1130,8 +1128,12 @@ 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);
>  
> -	/* Get the frequency from CNTFRQ */
> -	arch_timer_detect_rate(NULL, NULL);
> +	/* Get the frequency from the sysreg CNTFRQ */
> +	arch_timer_rate = arch_timer_get_cntfrq();
> +	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]) {
> -- 
> 2.9.3
> 

-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 03/11] clocksource: arm_arch_timer: refactor arch_timer_needs_probing
  2017-03-21 16:31   ` fu.wei at linaro.org
  (?)
@ 2017-03-28 15:02     ` Daniel Lezcano
  -1 siblings, 0 replies; 113+ messages in thread
From: Daniel Lezcano @ 2017-03-28 15:02 UTC (permalink / raw)
  To: fu.wei
  Cc: rjw, lenb, tglx, marc.zyngier, mark.rutland, lorenzo.pieralisi,
	sudeep.holla, hanjun.guo, linux-arm-kernel, linaro-acpi,
	linux-kernel, linux-acpi, rruigrok, harba, cov, timur,
	graeme.gregory, al.stone, jcm, wei, arnd, catalin.marinas,
	will.deacon, Suravee.Suthikulpanit, leo.duran, wim, linux,
	linux-watchdog, tn, christoffer.dall, julien.grall

On Wed, Mar 22, 2017 at 12:31:14AM +0800, fu.wei@linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> 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.

Can the following patch help you to solve nicely the situation ?

https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1360007.html
 
> 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 <fu.wei@linaro.org>
> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/clocksource/arm_arch_timer.c | 34 +++++++++++++++++++---------------
>  1 file changed, 19 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 29ca7d6..d1a05d9 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -839,15 +839,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;
> @@ -855,17 +868,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);
> -- 
> 2.9.3
> 

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 03/11] clocksource: arm_arch_timer: refactor arch_timer_needs_probing
@ 2017-03-28 15:02     ` Daniel Lezcano
  0 siblings, 0 replies; 113+ messages in thread
From: Daniel Lezcano @ 2017-03-28 15:02 UTC (permalink / raw)
  To: fu.wei
  Cc: rjw, lenb, tglx, marc.zyngier, mark.rutland, lorenzo.pieralisi,
	sudeep.holla, hanjun.guo, linux-arm-kernel, linaro-acpi,
	linux-kernel, linux-acpi, rruigrok, harba, cov, timur,
	graeme.gregory, al.stone, jcm, wei, arnd, catalin.marinas,
	will.deacon, Suravee.Suthikulpanit, leo.duran, wim, linux,
	linux-watchdog, tn, christoffer.dall, julien.grall

On Wed, Mar 22, 2017 at 12:31:14AM +0800, fu.wei@linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> 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.

Can the following patch help you to solve nicely the situation ?

https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1360007.html
 
> 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 <fu.wei@linaro.org>
> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/clocksource/arm_arch_timer.c | 34 +++++++++++++++++++---------------
>  1 file changed, 19 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 29ca7d6..d1a05d9 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -839,15 +839,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;
> @@ -855,17 +868,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);
> -- 
> 2.9.3
> 

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 03/11] clocksource: arm_arch_timer: refactor arch_timer_needs_probing
@ 2017-03-28 15:02     ` Daniel Lezcano
  0 siblings, 0 replies; 113+ messages in thread
From: Daniel Lezcano @ 2017-03-28 15:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 22, 2017 at 12:31:14AM +0800, fu.wei at linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> 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.

Can the following patch help you to solve nicely the situation ?

https://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1360007.html
 
> 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 <fu.wei@linaro.org>
> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/clocksource/arm_arch_timer.c | 34 +++++++++++++++++++---------------
>  1 file changed, 19 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 29ca7d6..d1a05d9 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -839,15 +839,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;
> @@ -855,17 +868,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);
> -- 
> 2.9.3
> 

-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 11/11] acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
  2017-03-21 16:31   ` fu.wei
  (?)
@ 2017-03-28 15:41     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-28 15:41 UTC (permalink / raw)
  To: fu.wei
  Cc: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	sudeep.holla, hanjun.guo, linux-arm-kernel, linaro-acpi,
	linux-kernel, linux-acpi, rruigrok, harba, cov, timur,
	graeme.gregory, al.stone, jcm, wei, arnd, catalin.marinas,
	will.deacon, Suravee.Suthikulpanit, leo.duran, wim, linux,
	linux-watchdog, tn, christoffer.dall, julien.grall

On Wed, Mar 22, 2017 at 12:31:22AM +0800, fu.wei@linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> 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 <fu.wei@linaro.org>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
> ---
>  drivers/acpi/arm64/gtdt.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 94 insertions(+)
> 
> diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
> index f471873..5d167f0 100644
> --- a/drivers/acpi/arm64/gtdt.c
> +++ b/drivers/acpi/arm64/gtdt.c
> @@ -14,6 +14,7 @@
>  #include <linux/acpi.h>
>  #include <linux/init.h>
>  #include <linux/kernel.h>
> +#include <linux/platform_device.h>
>  
>  #include <clocksource/arm_arch_timer.h>
>  
> @@ -59,6 +60,17 @@ static inline bool is_timer_block(void *platform_timer)
>  	return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK;
>  }
>  
> +static inline bool is_non_secure_watchdog(void *platform_timer)
> +{
> +	struct acpi_gtdt_header *gh = platform_timer;
> +	struct acpi_gtdt_watchdog *wd = platform_timer;
> +
> +	if (gh->type != ACPI_GTDT_TYPE_WATCHDOG)
> +		return false;
> +
> +	return !(wd->timer_flags & ACPI_GTDT_WATCHDOG_SECURE);
> +}
> +
>  static int __init map_gt_gsi(u32 interrupt, u32 flags)
>  {
>  	int trigger, polarity;
> @@ -285,3 +297,85 @@ int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
>  
>  	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);
> +
> +	/*
> +	 * 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),
> +	};
> +	int nr_res = ARRAY_SIZE(res);
> +
> +	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;

You should unmap the gsi here.

> +	}
> +
> +	if (irq <= 0) {
> +		pr_warn("failed to map the Watchdog interrupt.\n");
> +		nr_res--;
> +	}
> +
> +	/*
> +	 * 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

Nit: I would not hardcode drivers paths in comments.

> +	 * info below by matching this name.
> +	 */
> +	pdev = platform_device_register_simple("sbsa-gwdt", index, res, nr_res);
> +	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;

Ok, I missed previous versions reviews so I miss the background
here and I apologise.

I do not understand why you call acpi_gtdt_init() again (or better,
why acpi_gtdt_init() does not return straight away) here if the
stashed pointer in acpi_gtdt_desc is already set. I am not a big fan
of the for_each_platform_timer macro either, here you can just read
the ACPI_SIG_GTDT and parse its entries, I see no point in calling
acpi_gtdt_init() again, there is nothing to stash for later probing,
is there ?

Or it is just to reuse common parsing code ? Regardless, if the
acpi_gtdt_desc struct is already initialized acpi_gtdt_init() should
just return or I am missing the point.

I would like clarifications on the acpi_gtdt_init() call above please
(plus GSI unmap fix), apart from that:

Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

> +	for_each_platform_timer(platform_timer) {
> +		if (is_non_secure_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);
> -- 
> 2.9.3
> 

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 11/11] acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
@ 2017-03-28 15:41     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-28 15:41 UTC (permalink / raw)
  To: fu.wei
  Cc: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	sudeep.holla, hanjun.guo, linux-arm-kernel, linaro-acpi,
	linux-kernel, linux-acpi, rruigrok, harba, cov, timur,
	graeme.gregory, al.stone, jcm, wei, arnd, catalin.marinas,
	will.deacon, Suravee.Suthikulpanit, leo.duran, wim, linux,
	linux-watchdog, tn, christoffer.dall, julien.grall

On Wed, Mar 22, 2017 at 12:31:22AM +0800, fu.wei@linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> 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 <fu.wei@linaro.org>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
> ---
>  drivers/acpi/arm64/gtdt.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 94 insertions(+)
> 
> diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
> index f471873..5d167f0 100644
> --- a/drivers/acpi/arm64/gtdt.c
> +++ b/drivers/acpi/arm64/gtdt.c
> @@ -14,6 +14,7 @@
>  #include <linux/acpi.h>
>  #include <linux/init.h>
>  #include <linux/kernel.h>
> +#include <linux/platform_device.h>
>  
>  #include <clocksource/arm_arch_timer.h>
>  
> @@ -59,6 +60,17 @@ static inline bool is_timer_block(void *platform_timer)
>  	return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK;
>  }
>  
> +static inline bool is_non_secure_watchdog(void *platform_timer)
> +{
> +	struct acpi_gtdt_header *gh = platform_timer;
> +	struct acpi_gtdt_watchdog *wd = platform_timer;
> +
> +	if (gh->type != ACPI_GTDT_TYPE_WATCHDOG)
> +		return false;
> +
> +	return !(wd->timer_flags & ACPI_GTDT_WATCHDOG_SECURE);
> +}
> +
>  static int __init map_gt_gsi(u32 interrupt, u32 flags)
>  {
>  	int trigger, polarity;
> @@ -285,3 +297,85 @@ int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
>  
>  	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);
> +
> +	/*
> +	 * 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),
> +	};
> +	int nr_res = ARRAY_SIZE(res);
> +
> +	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;

You should unmap the gsi here.

> +	}
> +
> +	if (irq <= 0) {
> +		pr_warn("failed to map the Watchdog interrupt.\n");
> +		nr_res--;
> +	}
> +
> +	/*
> +	 * 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

Nit: I would not hardcode drivers paths in comments.

> +	 * info below by matching this name.
> +	 */
> +	pdev = platform_device_register_simple("sbsa-gwdt", index, res, nr_res);
> +	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;

Ok, I missed previous versions reviews so I miss the background
here and I apologise.

I do not understand why you call acpi_gtdt_init() again (or better,
why acpi_gtdt_init() does not return straight away) here if the
stashed pointer in acpi_gtdt_desc is already set. I am not a big fan
of the for_each_platform_timer macro either, here you can just read
the ACPI_SIG_GTDT and parse its entries, I see no point in calling
acpi_gtdt_init() again, there is nothing to stash for later probing,
is there ?

Or it is just to reuse common parsing code ? Regardless, if the
acpi_gtdt_desc struct is already initialized acpi_gtdt_init() should
just return or I am missing the point.

I would like clarifications on the acpi_gtdt_init() call above please
(plus GSI unmap fix), apart from that:

Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

> +	for_each_platform_timer(platform_timer) {
> +		if (is_non_secure_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);
> -- 
> 2.9.3
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 11/11] acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
@ 2017-03-28 15:41     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-28 15:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 22, 2017 at 12:31:22AM +0800, fu.wei at linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> 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 <fu.wei@linaro.org>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
> ---
>  drivers/acpi/arm64/gtdt.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 94 insertions(+)
> 
> diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
> index f471873..5d167f0 100644
> --- a/drivers/acpi/arm64/gtdt.c
> +++ b/drivers/acpi/arm64/gtdt.c
> @@ -14,6 +14,7 @@
>  #include <linux/acpi.h>
>  #include <linux/init.h>
>  #include <linux/kernel.h>
> +#include <linux/platform_device.h>
>  
>  #include <clocksource/arm_arch_timer.h>
>  
> @@ -59,6 +60,17 @@ static inline bool is_timer_block(void *platform_timer)
>  	return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK;
>  }
>  
> +static inline bool is_non_secure_watchdog(void *platform_timer)
> +{
> +	struct acpi_gtdt_header *gh = platform_timer;
> +	struct acpi_gtdt_watchdog *wd = platform_timer;
> +
> +	if (gh->type != ACPI_GTDT_TYPE_WATCHDOG)
> +		return false;
> +
> +	return !(wd->timer_flags & ACPI_GTDT_WATCHDOG_SECURE);
> +}
> +
>  static int __init map_gt_gsi(u32 interrupt, u32 flags)
>  {
>  	int trigger, polarity;
> @@ -285,3 +297,85 @@ int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
>  
>  	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);
> +
> +	/*
> +	 * 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),
> +	};
> +	int nr_res = ARRAY_SIZE(res);
> +
> +	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;

You should unmap the gsi here.

> +	}
> +
> +	if (irq <= 0) {
> +		pr_warn("failed to map the Watchdog interrupt.\n");
> +		nr_res--;
> +	}
> +
> +	/*
> +	 * 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

Nit: I would not hardcode drivers paths in comments.

> +	 * info below by matching this name.
> +	 */
> +	pdev = platform_device_register_simple("sbsa-gwdt", index, res, nr_res);
> +	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;

Ok, I missed previous versions reviews so I miss the background
here and I apologise.

I do not understand why you call acpi_gtdt_init() again (or better,
why acpi_gtdt_init() does not return straight away) here if the
stashed pointer in acpi_gtdt_desc is already set. I am not a big fan
of the for_each_platform_timer macro either, here you can just read
the ACPI_SIG_GTDT and parse its entries, I see no point in calling
acpi_gtdt_init() again, there is nothing to stash for later probing,
is there ?

Or it is just to reuse common parsing code ? Regardless, if the
acpi_gtdt_desc struct is already initialized acpi_gtdt_init() should
just return or I am missing the point.

I would like clarifications on the acpi_gtdt_init() call above please
(plus GSI unmap fix), apart from that:

Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

> +	for_each_platform_timer(platform_timer) {
> +		if (is_non_secure_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);
> -- 
> 2.9.3
> 

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
  2017-03-28 14:58     ` Daniel Lezcano
  (?)
@ 2017-03-29  3:41       ` Fu Wei
  -1 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29  3:41 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Rafael J. Wysocki, Len Brown, Thomas Gleixner, Marc Zyngier,
	Mark Rutland, Lorenzo Pieralisi, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Linaro ACPI Mailman List, Linux Kernel Mailing List,
	ACPI Devel Maling List, rruigrok-sgV2jX0FEOL9JmXXK+q4OQ,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei

Hi Daniel,

Great thanks for your review, allow me to answer your question below:

On 28 March 2017 at 22:58, Daniel Lezcano <daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> On Wed, Mar 22, 2017 at 12:31:13AM +0800, fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org wrote:
>> From: Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>
>> Currently, the counter frequency detection call(arch_timer_detect_rate)
>> includes getting the frequency from the device-tree property, the per-cpu
>> arch-timer and the memory-mapped (MMIO) timer interfaces.
>> But reading device-tree property will be needed only when system boot with
>> device-tree, and reading from the per-cpu arch-timer and the memory-mapped
>> (MMIO) timer interfaces will be needed only when the system initializes
>> the relevant timer.
>>
>> This patch separates out device-tree code, keep them in device-tree init
>> function, and removes arch_timer_detect_rate founction, then uses the
>> arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.
>>
>> Signed-off-by: Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> ---
>>  drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
>>  1 file changed, 30 insertions(+), 28 deletions(-)
>>
>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>> index 843f923..29ca7d6 100644
>> --- a/drivers/clocksource/arm_arch_timer.c
>> +++ b/drivers/clocksource/arm_arch_timer.c
>> @@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
>>       return readl_relaxed(cntbase + CNTFRQ);
>>  }
>>
>> -static void
>> -arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
>> -{
>> -     /* Who has more than one independent system counter? */
>> -     if (arch_timer_rate)
>> -             return;
>> -
>> -     /*
>> -      * Try to determine the frequency from the device tree or CNTFRQ,
>> -      * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
>> -      */
>> -     if (!acpi_disabled ||
>> -         of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
>> -             if (cntbase)
>> -                     arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
>> -             else
>> -                     arch_timer_rate = arch_timer_get_cntfrq();
>> -     }
>> -
>> -     /* 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",
>> @@ -958,7 +934,17 @@ 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_detect_rate(NULL, np);
>> +     /*
>> +      * Try to determine the frequency from the device tree,
>> +      * if fail, get the frequency from the sysreg CNTFRQ.
>> +      */
>> +     if (!arch_timer_rate &&
>
> This variable is set only if "arm,armv7-timer" and "arm,armv7-timer-mem" are
> declared together in the DT, right ?
>
> Two declarations for a single variable ? Ignore the !arch_timer_rate.

In this function, we try to initialize per-CPU arm arch_timer by DT.
this "!arch_timer_rate" is for testing that if we have got system
counter frequency from the memory-mapped timer. If so, we just skip
getting the frequency from DT or sysreg cntfrq again.
This variable is set only if "arm,armv7-timer-mem" is initialized
earlier than "arm,armv7-timer", in another word, maybe the node of
"arm,armv7-timer-mem" is declared earlier than  "arm,armv7-timer-mem"
one in DT.

we do this check is for keeping the same init logic as before in the
DT, try to avoid any possibility of  breaking devices which boot by
DT.

>
>> +         of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
>> +             arch_timer_rate = arch_timer_get_cntfrq();
>> +     if (!arch_timer_rate) {
>> +             pr_err(FW_BUG "frequency not available.\n");
>> +             return -EINVAL;
>> +     }
>
> Please, clarify this block, the conditions are unclear.

this "!arch_timer_rate" is for verifying that if the system counter
frequency we just got from DT or sysreg cntfrq is valid(non-zero).

So here, you can see I check arch_timer_rate twice, but they are for
different cases.

>
>>
>>       arch_timer_c3stop = !of_property_read_bool(np, "always-on");
>>
>> @@ -1069,7 +1055,19 @@ static int __init arch_timer_mem_init(struct device_node *np)
>>               goto out;
>>       }
>>
>> -     arch_timer_detect_rate(base, 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_mem_get_cntfrq(base);
>> +     if (!arch_timer_rate) {
>> +             pr_err(FW_BUG "MMIO frequency not available.\n");
>> +             ret = -EINVAL;
>> +             goto out;
>> +     }
>> +
>>       ret = arch_timer_mem_register(base, irq);
>>       if (ret)
>>               goto out;
>> @@ -1130,8 +1128,12 @@ 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);
>>
>> -     /* Get the frequency from CNTFRQ */
>> -     arch_timer_detect_rate(NULL, NULL);
>> +     /* Get the frequency from the sysreg CNTFRQ */
>> +     arch_timer_rate = arch_timer_get_cntfrq();
>> +     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]) {
>> --
>> 2.9.3
>>
>
> --
>
>  <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
>
> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
> <http://twitter.com/#!/linaroorg> Twitter |
> <http://www.linaro.org/linaro-blog/> Blog



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
@ 2017-03-29  3:41       ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29  3:41 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Rafael J. Wysocki, Len Brown, Thomas Gleixner, Marc Zyngier,
	Mark Rutland, Lorenzo Pieralisi, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

Hi Daniel,

Great thanks for your review, allow me to answer your question below:

On 28 March 2017 at 22:58, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
> On Wed, Mar 22, 2017 at 12:31:13AM +0800, fu.wei@linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> Currently, the counter frequency detection call(arch_timer_detect_rate)
>> includes getting the frequency from the device-tree property, the per-cpu
>> arch-timer and the memory-mapped (MMIO) timer interfaces.
>> But reading device-tree property will be needed only when system boot with
>> device-tree, and reading from the per-cpu arch-timer and the memory-mapped
>> (MMIO) timer interfaces will be needed only when the system initializes
>> the relevant timer.
>>
>> This patch separates out device-tree code, keep them in device-tree init
>> function, and removes arch_timer_detect_rate founction, then uses the
>> arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.
>>
>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>> ---
>>  drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
>>  1 file changed, 30 insertions(+), 28 deletions(-)
>>
>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>> index 843f923..29ca7d6 100644
>> --- a/drivers/clocksource/arm_arch_timer.c
>> +++ b/drivers/clocksource/arm_arch_timer.c
>> @@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
>>       return readl_relaxed(cntbase + CNTFRQ);
>>  }
>>
>> -static void
>> -arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
>> -{
>> -     /* Who has more than one independent system counter? */
>> -     if (arch_timer_rate)
>> -             return;
>> -
>> -     /*
>> -      * Try to determine the frequency from the device tree or CNTFRQ,
>> -      * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
>> -      */
>> -     if (!acpi_disabled ||
>> -         of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
>> -             if (cntbase)
>> -                     arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
>> -             else
>> -                     arch_timer_rate = arch_timer_get_cntfrq();
>> -     }
>> -
>> -     /* 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",
>> @@ -958,7 +934,17 @@ 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_detect_rate(NULL, np);
>> +     /*
>> +      * Try to determine the frequency from the device tree,
>> +      * if fail, get the frequency from the sysreg CNTFRQ.
>> +      */
>> +     if (!arch_timer_rate &&
>
> This variable is set only if "arm,armv7-timer" and "arm,armv7-timer-mem" are
> declared together in the DT, right ?
>
> Two declarations for a single variable ? Ignore the !arch_timer_rate.

In this function, we try to initialize per-CPU arm arch_timer by DT.
this "!arch_timer_rate" is for testing that if we have got system
counter frequency from the memory-mapped timer. If so, we just skip
getting the frequency from DT or sysreg cntfrq again.
This variable is set only if "arm,armv7-timer-mem" is initialized
earlier than "arm,armv7-timer", in another word, maybe the node of
"arm,armv7-timer-mem" is declared earlier than  "arm,armv7-timer-mem"
one in DT.

we do this check is for keeping the same init logic as before in the
DT, try to avoid any possibility of  breaking devices which boot by
DT.

>
>> +         of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
>> +             arch_timer_rate = arch_timer_get_cntfrq();
>> +     if (!arch_timer_rate) {
>> +             pr_err(FW_BUG "frequency not available.\n");
>> +             return -EINVAL;
>> +     }
>
> Please, clarify this block, the conditions are unclear.

this "!arch_timer_rate" is for verifying that if the system counter
frequency we just got from DT or sysreg cntfrq is valid(non-zero).

So here, you can see I check arch_timer_rate twice, but they are for
different cases.

>
>>
>>       arch_timer_c3stop = !of_property_read_bool(np, "always-on");
>>
>> @@ -1069,7 +1055,19 @@ static int __init arch_timer_mem_init(struct device_node *np)
>>               goto out;
>>       }
>>
>> -     arch_timer_detect_rate(base, 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_mem_get_cntfrq(base);
>> +     if (!arch_timer_rate) {
>> +             pr_err(FW_BUG "MMIO frequency not available.\n");
>> +             ret = -EINVAL;
>> +             goto out;
>> +     }
>> +
>>       ret = arch_timer_mem_register(base, irq);
>>       if (ret)
>>               goto out;
>> @@ -1130,8 +1128,12 @@ 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);
>>
>> -     /* Get the frequency from CNTFRQ */
>> -     arch_timer_detect_rate(NULL, NULL);
>> +     /* Get the frequency from the sysreg CNTFRQ */
>> +     arch_timer_rate = arch_timer_get_cntfrq();
>> +     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]) {
>> --
>> 2.9.3
>>
>
> --
>
>  <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
>
> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
> <http://twitter.com/#!/linaroorg> Twitter |
> <http://www.linaro.org/linaro-blog/> Blog



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
@ 2017-03-29  3:41       ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29  3:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Daniel,

Great thanks for your review, allow me to answer your question below:

On 28 March 2017 at 22:58, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
> On Wed, Mar 22, 2017 at 12:31:13AM +0800, fu.wei at linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> Currently, the counter frequency detection call(arch_timer_detect_rate)
>> includes getting the frequency from the device-tree property, the per-cpu
>> arch-timer and the memory-mapped (MMIO) timer interfaces.
>> But reading device-tree property will be needed only when system boot with
>> device-tree, and reading from the per-cpu arch-timer and the memory-mapped
>> (MMIO) timer interfaces will be needed only when the system initializes
>> the relevant timer.
>>
>> This patch separates out device-tree code, keep them in device-tree init
>> function, and removes arch_timer_detect_rate founction, then uses the
>> arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.
>>
>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>> ---
>>  drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
>>  1 file changed, 30 insertions(+), 28 deletions(-)
>>
>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>> index 843f923..29ca7d6 100644
>> --- a/drivers/clocksource/arm_arch_timer.c
>> +++ b/drivers/clocksource/arm_arch_timer.c
>> @@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
>>       return readl_relaxed(cntbase + CNTFRQ);
>>  }
>>
>> -static void
>> -arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
>> -{
>> -     /* Who has more than one independent system counter? */
>> -     if (arch_timer_rate)
>> -             return;
>> -
>> -     /*
>> -      * Try to determine the frequency from the device tree or CNTFRQ,
>> -      * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
>> -      */
>> -     if (!acpi_disabled ||
>> -         of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
>> -             if (cntbase)
>> -                     arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
>> -             else
>> -                     arch_timer_rate = arch_timer_get_cntfrq();
>> -     }
>> -
>> -     /* 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",
>> @@ -958,7 +934,17 @@ 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_detect_rate(NULL, np);
>> +     /*
>> +      * Try to determine the frequency from the device tree,
>> +      * if fail, get the frequency from the sysreg CNTFRQ.
>> +      */
>> +     if (!arch_timer_rate &&
>
> This variable is set only if "arm,armv7-timer" and "arm,armv7-timer-mem" are
> declared together in the DT, right ?
>
> Two declarations for a single variable ? Ignore the !arch_timer_rate.

In this function, we try to initialize per-CPU arm arch_timer by DT.
this "!arch_timer_rate" is for testing that if we have got system
counter frequency from the memory-mapped timer. If so, we just skip
getting the frequency from DT or sysreg cntfrq again.
This variable is set only if "arm,armv7-timer-mem" is initialized
earlier than "arm,armv7-timer", in another word, maybe the node of
"arm,armv7-timer-mem" is declared earlier than  "arm,armv7-timer-mem"
one in DT.

we do this check is for keeping the same init logic as before in the
DT, try to avoid any possibility of  breaking devices which boot by
DT.

>
>> +         of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
>> +             arch_timer_rate = arch_timer_get_cntfrq();
>> +     if (!arch_timer_rate) {
>> +             pr_err(FW_BUG "frequency not available.\n");
>> +             return -EINVAL;
>> +     }
>
> Please, clarify this block, the conditions are unclear.

this "!arch_timer_rate" is for verifying that if the system counter
frequency we just got from DT or sysreg cntfrq is valid(non-zero).

So here, you can see I check arch_timer_rate twice, but they are for
different cases.

>
>>
>>       arch_timer_c3stop = !of_property_read_bool(np, "always-on");
>>
>> @@ -1069,7 +1055,19 @@ static int __init arch_timer_mem_init(struct device_node *np)
>>               goto out;
>>       }
>>
>> -     arch_timer_detect_rate(base, 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_mem_get_cntfrq(base);
>> +     if (!arch_timer_rate) {
>> +             pr_err(FW_BUG "MMIO frequency not available.\n");
>> +             ret = -EINVAL;
>> +             goto out;
>> +     }
>> +
>>       ret = arch_timer_mem_register(base, irq);
>>       if (ret)
>>               goto out;
>> @@ -1130,8 +1128,12 @@ 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);
>>
>> -     /* Get the frequency from CNTFRQ */
>> -     arch_timer_detect_rate(NULL, NULL);
>> +     /* Get the frequency from the sysreg CNTFRQ */
>> +     arch_timer_rate = arch_timer_get_cntfrq();
>> +     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]) {
>> --
>> 2.9.3
>>
>
> --
>
>  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs
>
> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
> <http://twitter.com/#!/linaroorg> Twitter |
> <http://www.linaro.org/linaro-blog/> Blog



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
  2017-03-29  3:41       ` Fu Wei
  (?)
@ 2017-03-29  5:11         ` Fu Wei
  -1 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29  5:11 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Rafael J. Wysocki, Len Brown, Thomas Gleixner, Marc Zyngier,
	Mark Rutland, Lorenzo Pieralisi, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei

Hi Daniel,

On 29 March 2017 at 11:41, Fu Wei <fu.wei@linaro.org> wrote:
> Hi Daniel,
>
> Great thanks for your review, allow me to answer your question below:
>
> On 28 March 2017 at 22:58, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
>> On Wed, Mar 22, 2017 at 12:31:13AM +0800, fu.wei@linaro.org wrote:
>>> From: Fu Wei <fu.wei@linaro.org>
>>>
>>> Currently, the counter frequency detection call(arch_timer_detect_rate)
>>> includes getting the frequency from the device-tree property, the per-cpu
>>> arch-timer and the memory-mapped (MMIO) timer interfaces.
>>> But reading device-tree property will be needed only when system boot with
>>> device-tree, and reading from the per-cpu arch-timer and the memory-mapped
>>> (MMIO) timer interfaces will be needed only when the system initializes
>>> the relevant timer.
>>>
>>> This patch separates out device-tree code, keep them in device-tree init
>>> function, and removes arch_timer_detect_rate founction, then uses the
>>> arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.
>>>
>>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>>> ---
>>>  drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
>>>  1 file changed, 30 insertions(+), 28 deletions(-)
>>>
>>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>>> index 843f923..29ca7d6 100644
>>> --- a/drivers/clocksource/arm_arch_timer.c
>>> +++ b/drivers/clocksource/arm_arch_timer.c
>>> @@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
>>>       return readl_relaxed(cntbase + CNTFRQ);
>>>  }
>>>
>>> -static void
>>> -arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
>>> -{
>>> -     /* Who has more than one independent system counter? */
>>> -     if (arch_timer_rate)
>>> -             return;
>>> -
>>> -     /*
>>> -      * Try to determine the frequency from the device tree or CNTFRQ,
>>> -      * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
>>> -      */
>>> -     if (!acpi_disabled ||
>>> -         of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
>>> -             if (cntbase)
>>> -                     arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
>>> -             else
>>> -                     arch_timer_rate = arch_timer_get_cntfrq();
>>> -     }
>>> -
>>> -     /* 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",
>>> @@ -958,7 +934,17 @@ 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_detect_rate(NULL, np);
>>> +     /*
>>> +      * Try to determine the frequency from the device tree,
>>> +      * if fail, get the frequency from the sysreg CNTFRQ.
>>> +      */
>>> +     if (!arch_timer_rate &&
>>
>> This variable is set only if "arm,armv7-timer" and "arm,armv7-timer-mem" are
>> declared together in the DT, right ?
>>
>> Two declarations for a single variable ? Ignore the !arch_timer_rate.
>
> In this function, we try to initialize per-CPU arm arch_timer by DT.
> this "!arch_timer_rate" is for testing that if we have got system
> counter frequency from the memory-mapped timer. If so, we just skip
> getting the frequency from DT or sysreg cntfrq again.
> This variable is set only if "arm,armv7-timer-mem" is initialized
> earlier than "arm,armv7-timer", in another word, maybe the node of
> "arm,armv7-timer-mem" is declared earlier than  "arm,armv7-timer-mem"
> one in DT.
>
> we do this check is for keeping the same init logic as before in the
> DT, try to avoid any possibility of  breaking devices which boot by
> DT.
>
>>
>>> +         of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
>>> +             arch_timer_rate = arch_timer_get_cntfrq();
>>> +     if (!arch_timer_rate) {
>>> +             pr_err(FW_BUG "frequency not available.\n");
>>> +             return -EINVAL;
>>> +     }
>>
>> Please, clarify this block, the conditions are unclear.
>
> this "!arch_timer_rate" is for verifying that if the system counter
> frequency we just got from DT or sysreg cntfrq is valid(non-zero).
>
> So here, you can see I check arch_timer_rate twice, but they are for
> different cases.

I think about this several times,
For this block, it is a little unclear, so I think this will be better:

+ /*
+ * Try to determine the frequency:
+ * If we have got it in arch_timer_mem_of_init, we don't need to get
it again, skip.
+ * Otherwise, try to get the frequency from the device tree,
+ * if fail, try to get it from the sysreg CNTFRQ.
+ * Last, verify the arch_timer_rate before leaving this block.
+ */
+ if (!arch_timer_rate) {
+         if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
+                 arch_timer_rate = arch_timer_get_cntfrq();
+         if (!arch_timer_rate) {
+                 pr_err(FW_BUG "frequency not available.\n");
+                 return -EINVAL;
+         }
+ }

>
>>
>>>
>>>       arch_timer_c3stop = !of_property_read_bool(np, "always-on");
>>>
>>> @@ -1069,7 +1055,19 @@ static int __init arch_timer_mem_init(struct device_node *np)
>>>               goto out;
>>>       }
>>>
>>> -     arch_timer_detect_rate(base, 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_mem_get_cntfrq(base);
>>> +     if (!arch_timer_rate) {
>>> +             pr_err(FW_BUG "MMIO frequency not available.\n");
>>> +             ret = -EINVAL;
>>> +             goto out;
>>> +     }
>>> +
>>>       ret = arch_timer_mem_register(base, irq);
>>>       if (ret)
>>>               goto out;
>>> @@ -1130,8 +1128,12 @@ 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);
>>>
>>> -     /* Get the frequency from CNTFRQ */
>>> -     arch_timer_detect_rate(NULL, NULL);
>>> +     /* Get the frequency from the sysreg CNTFRQ */
>>> +     arch_timer_rate = arch_timer_get_cntfrq();
>>> +     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]) {
>>> --
>>> 2.9.3
>>>
>>
>> --
>>
>>  <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
>>
>> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
>> <http://twitter.com/#!/linaroorg> Twitter |
>> <http://www.linaro.org/linaro-blog/> Blog
>
>
>
> --
> Best regards,
>
> Fu Wei
> Software Engineer
> Red Hat



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
@ 2017-03-29  5:11         ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29  5:11 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Rafael J. Wysocki, Len Brown, Thomas Gleixner, Marc Zyngier,
	Mark Rutland, Lorenzo Pieralisi, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

Hi Daniel,

On 29 March 2017 at 11:41, Fu Wei <fu.wei@linaro.org> wrote:
> Hi Daniel,
>
> Great thanks for your review, allow me to answer your question below:
>
> On 28 March 2017 at 22:58, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
>> On Wed, Mar 22, 2017 at 12:31:13AM +0800, fu.wei@linaro.org wrote:
>>> From: Fu Wei <fu.wei@linaro.org>
>>>
>>> Currently, the counter frequency detection call(arch_timer_detect_rate)
>>> includes getting the frequency from the device-tree property, the per-cpu
>>> arch-timer and the memory-mapped (MMIO) timer interfaces.
>>> But reading device-tree property will be needed only when system boot with
>>> device-tree, and reading from the per-cpu arch-timer and the memory-mapped
>>> (MMIO) timer interfaces will be needed only when the system initializes
>>> the relevant timer.
>>>
>>> This patch separates out device-tree code, keep them in device-tree init
>>> function, and removes arch_timer_detect_rate founction, then uses the
>>> arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.
>>>
>>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>>> ---
>>>  drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
>>>  1 file changed, 30 insertions(+), 28 deletions(-)
>>>
>>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>>> index 843f923..29ca7d6 100644
>>> --- a/drivers/clocksource/arm_arch_timer.c
>>> +++ b/drivers/clocksource/arm_arch_timer.c
>>> @@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
>>>       return readl_relaxed(cntbase + CNTFRQ);
>>>  }
>>>
>>> -static void
>>> -arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
>>> -{
>>> -     /* Who has more than one independent system counter? */
>>> -     if (arch_timer_rate)
>>> -             return;
>>> -
>>> -     /*
>>> -      * Try to determine the frequency from the device tree or CNTFRQ,
>>> -      * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
>>> -      */
>>> -     if (!acpi_disabled ||
>>> -         of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
>>> -             if (cntbase)
>>> -                     arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
>>> -             else
>>> -                     arch_timer_rate = arch_timer_get_cntfrq();
>>> -     }
>>> -
>>> -     /* 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",
>>> @@ -958,7 +934,17 @@ 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_detect_rate(NULL, np);
>>> +     /*
>>> +      * Try to determine the frequency from the device tree,
>>> +      * if fail, get the frequency from the sysreg CNTFRQ.
>>> +      */
>>> +     if (!arch_timer_rate &&
>>
>> This variable is set only if "arm,armv7-timer" and "arm,armv7-timer-mem" are
>> declared together in the DT, right ?
>>
>> Two declarations for a single variable ? Ignore the !arch_timer_rate.
>
> In this function, we try to initialize per-CPU arm arch_timer by DT.
> this "!arch_timer_rate" is for testing that if we have got system
> counter frequency from the memory-mapped timer. If so, we just skip
> getting the frequency from DT or sysreg cntfrq again.
> This variable is set only if "arm,armv7-timer-mem" is initialized
> earlier than "arm,armv7-timer", in another word, maybe the node of
> "arm,armv7-timer-mem" is declared earlier than  "arm,armv7-timer-mem"
> one in DT.
>
> we do this check is for keeping the same init logic as before in the
> DT, try to avoid any possibility of  breaking devices which boot by
> DT.
>
>>
>>> +         of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
>>> +             arch_timer_rate = arch_timer_get_cntfrq();
>>> +     if (!arch_timer_rate) {
>>> +             pr_err(FW_BUG "frequency not available.\n");
>>> +             return -EINVAL;
>>> +     }
>>
>> Please, clarify this block, the conditions are unclear.
>
> this "!arch_timer_rate" is for verifying that if the system counter
> frequency we just got from DT or sysreg cntfrq is valid(non-zero).
>
> So here, you can see I check arch_timer_rate twice, but they are for
> different cases.

I think about this several times,
For this block, it is a little unclear, so I think this will be better:

+ /*
+ * Try to determine the frequency:
+ * If we have got it in arch_timer_mem_of_init, we don't need to get
it again, skip.
+ * Otherwise, try to get the frequency from the device tree,
+ * if fail, try to get it from the sysreg CNTFRQ.
+ * Last, verify the arch_timer_rate before leaving this block.
+ */
+ if (!arch_timer_rate) {
+         if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
+                 arch_timer_rate = arch_timer_get_cntfrq();
+         if (!arch_timer_rate) {
+                 pr_err(FW_BUG "frequency not available.\n");
+                 return -EINVAL;
+         }
+ }

>
>>
>>>
>>>       arch_timer_c3stop = !of_property_read_bool(np, "always-on");
>>>
>>> @@ -1069,7 +1055,19 @@ static int __init arch_timer_mem_init(struct device_node *np)
>>>               goto out;
>>>       }
>>>
>>> -     arch_timer_detect_rate(base, 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_mem_get_cntfrq(base);
>>> +     if (!arch_timer_rate) {
>>> +             pr_err(FW_BUG "MMIO frequency not available.\n");
>>> +             ret = -EINVAL;
>>> +             goto out;
>>> +     }
>>> +
>>>       ret = arch_timer_mem_register(base, irq);
>>>       if (ret)
>>>               goto out;
>>> @@ -1130,8 +1128,12 @@ 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);
>>>
>>> -     /* Get the frequency from CNTFRQ */
>>> -     arch_timer_detect_rate(NULL, NULL);
>>> +     /* Get the frequency from the sysreg CNTFRQ */
>>> +     arch_timer_rate = arch_timer_get_cntfrq();
>>> +     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]) {
>>> --
>>> 2.9.3
>>>
>>
>> --
>>
>>  <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
>>
>> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
>> <http://twitter.com/#!/linaroorg> Twitter |
>> <http://www.linaro.org/linaro-blog/> Blog
>
>
>
> --
> Best regards,
>
> Fu Wei
> Software Engineer
> Red Hat



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
@ 2017-03-29  5:11         ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29  5:11 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Daniel,

On 29 March 2017 at 11:41, Fu Wei <fu.wei@linaro.org> wrote:
> Hi Daniel,
>
> Great thanks for your review, allow me to answer your question below:
>
> On 28 March 2017 at 22:58, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
>> On Wed, Mar 22, 2017 at 12:31:13AM +0800, fu.wei at linaro.org wrote:
>>> From: Fu Wei <fu.wei@linaro.org>
>>>
>>> Currently, the counter frequency detection call(arch_timer_detect_rate)
>>> includes getting the frequency from the device-tree property, the per-cpu
>>> arch-timer and the memory-mapped (MMIO) timer interfaces.
>>> But reading device-tree property will be needed only when system boot with
>>> device-tree, and reading from the per-cpu arch-timer and the memory-mapped
>>> (MMIO) timer interfaces will be needed only when the system initializes
>>> the relevant timer.
>>>
>>> This patch separates out device-tree code, keep them in device-tree init
>>> function, and removes arch_timer_detect_rate founction, then uses the
>>> arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.
>>>
>>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>>> ---
>>>  drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
>>>  1 file changed, 30 insertions(+), 28 deletions(-)
>>>
>>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>>> index 843f923..29ca7d6 100644
>>> --- a/drivers/clocksource/arm_arch_timer.c
>>> +++ b/drivers/clocksource/arm_arch_timer.c
>>> @@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
>>>       return readl_relaxed(cntbase + CNTFRQ);
>>>  }
>>>
>>> -static void
>>> -arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
>>> -{
>>> -     /* Who has more than one independent system counter? */
>>> -     if (arch_timer_rate)
>>> -             return;
>>> -
>>> -     /*
>>> -      * Try to determine the frequency from the device tree or CNTFRQ,
>>> -      * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
>>> -      */
>>> -     if (!acpi_disabled ||
>>> -         of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
>>> -             if (cntbase)
>>> -                     arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
>>> -             else
>>> -                     arch_timer_rate = arch_timer_get_cntfrq();
>>> -     }
>>> -
>>> -     /* 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",
>>> @@ -958,7 +934,17 @@ 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_detect_rate(NULL, np);
>>> +     /*
>>> +      * Try to determine the frequency from the device tree,
>>> +      * if fail, get the frequency from the sysreg CNTFRQ.
>>> +      */
>>> +     if (!arch_timer_rate &&
>>
>> This variable is set only if "arm,armv7-timer" and "arm,armv7-timer-mem" are
>> declared together in the DT, right ?
>>
>> Two declarations for a single variable ? Ignore the !arch_timer_rate.
>
> In this function, we try to initialize per-CPU arm arch_timer by DT.
> this "!arch_timer_rate" is for testing that if we have got system
> counter frequency from the memory-mapped timer. If so, we just skip
> getting the frequency from DT or sysreg cntfrq again.
> This variable is set only if "arm,armv7-timer-mem" is initialized
> earlier than "arm,armv7-timer", in another word, maybe the node of
> "arm,armv7-timer-mem" is declared earlier than  "arm,armv7-timer-mem"
> one in DT.
>
> we do this check is for keeping the same init logic as before in the
> DT, try to avoid any possibility of  breaking devices which boot by
> DT.
>
>>
>>> +         of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
>>> +             arch_timer_rate = arch_timer_get_cntfrq();
>>> +     if (!arch_timer_rate) {
>>> +             pr_err(FW_BUG "frequency not available.\n");
>>> +             return -EINVAL;
>>> +     }
>>
>> Please, clarify this block, the conditions are unclear.
>
> this "!arch_timer_rate" is for verifying that if the system counter
> frequency we just got from DT or sysreg cntfrq is valid(non-zero).
>
> So here, you can see I check arch_timer_rate twice, but they are for
> different cases.

I think about this several times,
For this block, it is a little unclear, so I think this will be better:

+ /*
+ * Try to determine the frequency:
+ * If we have got it in arch_timer_mem_of_init, we don't need to get
it again, skip.
+ * Otherwise, try to get the frequency from the device tree,
+ * if fail, try to get it from the sysreg CNTFRQ.
+ * Last, verify the arch_timer_rate before leaving this block.
+ */
+ if (!arch_timer_rate) {
+         if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
+                 arch_timer_rate = arch_timer_get_cntfrq();
+         if (!arch_timer_rate) {
+                 pr_err(FW_BUG "frequency not available.\n");
+                 return -EINVAL;
+         }
+ }

>
>>
>>>
>>>       arch_timer_c3stop = !of_property_read_bool(np, "always-on");
>>>
>>> @@ -1069,7 +1055,19 @@ static int __init arch_timer_mem_init(struct device_node *np)
>>>               goto out;
>>>       }
>>>
>>> -     arch_timer_detect_rate(base, 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_mem_get_cntfrq(base);
>>> +     if (!arch_timer_rate) {
>>> +             pr_err(FW_BUG "MMIO frequency not available.\n");
>>> +             ret = -EINVAL;
>>> +             goto out;
>>> +     }
>>> +
>>>       ret = arch_timer_mem_register(base, irq);
>>>       if (ret)
>>>               goto out;
>>> @@ -1130,8 +1128,12 @@ 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);
>>>
>>> -     /* Get the frequency from CNTFRQ */
>>> -     arch_timer_detect_rate(NULL, NULL);
>>> +     /* Get the frequency from the sysreg CNTFRQ */
>>> +     arch_timer_rate = arch_timer_get_cntfrq();
>>> +     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]) {
>>> --
>>> 2.9.3
>>>
>>
>> --
>>
>>  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs
>>
>> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
>> <http://twitter.com/#!/linaroorg> Twitter |
>> <http://www.linaro.org/linaro-blog/> Blog
>
>
>
> --
> Best regards,
>
> Fu Wei
> Software Engineer
> Red Hat



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
  2017-03-28 11:35     ` Lorenzo Pieralisi
  (?)
@ 2017-03-29  9:48       ` Fu Wei
  -1 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29  9:48 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei

Hi Lorenzo,

Great thanks for your review and help, I will take most of your suggestions,
But one or two comments have been discussed in previous patchset,
please allow me to explain these. :-)

On 28 March 2017 at 19:35, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Wed, Mar 22, 2017 at 12:31:18AM +0800, fu.wei@linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> 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 <fu.wei@linaro.org>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>
> Some nits below.

Great thanks!

>
>> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>  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(+)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 3741859..7e2baec 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 <daniel.lezcano@linaro.org>
>> + *         Fu Wei <fu.wei@linaro.org>
>> + *         Hanjun Guo <hanjun.guo@linaro.org>
>> + *
>> + * 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 <linux/acpi.h>
>> +#include <linux/init.h>
>> +#include <linux/kernel.h>
>> +
>> +#include <clocksource/arm_arch_timer.h>
>> +
>> +#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.
>
> Note: Secure state is not managed by the kernel on ARM64 systems.
>
> Is that what you wanted to say ?

yes, you are right, thanks! :-)
Will do so.

>
>> + * 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.
>
> Return: true if the timer HW state is lost when a CPU enters an idle
>         state, false otherwise

Thanks , will do

>
>> + */
>> +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
>
> I do not understand what this means.
>
>> + *                           number of platform timers. It can be NULL, if
>> + *                           driver don't need this info.
>
> driver doesn't

Sorry, this is not clear, I will fix it by :

 * @platform_timer_count: It points to a integer variable which is used
 *                           for storing the number of platform timers.
 *                           This pointer could be NULL, if the caller
 *                           doesn'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);
>
> Ok, two points here. First, I am not sure why you should warn if the
> table revision is < 2, is that a FW bug ? I do not think it is, you
> can just return 0.

I used pr_debug here before v20, then I got Hanjun's suggestion:
-------
GTDT table revision is updated to 2 in ACPI 5.1, we will
not support ACPI version under 5.1 and disable ACPI in FADT
parse before this code is called, so if we get revision
<2 here, I think we need to print warning (we need to keep
the firmware stick to the spec on ARM64).
-------
https://lkml.org/lkml/2017/1/19/82

So I started to use pr_warn.

>
>> +     else if (!gtdt->platform_timer_count)
>> +             pr_debug("No Platform Timer.\n");
>
> Ditto. Why keep executing ? There is nothing to do, just bail out
> with a return 0.
>
>> +     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;
>
> Same here, I suspect you want to consolidate the return path (I missed
> previous rounds of reviews so you should not worry too much, I can clean
> this up later) but to me a:
>
> return -EINVAL;
>
> would just do.

yes, you are right, I try to consolidate the return path. :-)
It may can return earlier, let me try.

>
> Lorenzo
>
>> +             }
>> +     }
>> +
>> +     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 9b05886..4b5c146 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -595,6 +595,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
>> --
>> 2.9.3
>>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29  9:48       ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29  9:48 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

Hi Lorenzo,

Great thanks for your review and help, I will take most of your suggestions,
But one or two comments have been discussed in previous patchset,
please allow me to explain these. :-)

On 28 March 2017 at 19:35, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Wed, Mar 22, 2017 at 12:31:18AM +0800, fu.wei@linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> 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 <fu.wei@linaro.org>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>
> Some nits below.

Great thanks!

>
>> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>  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(+)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 3741859..7e2baec 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 <daniel.lezcano@linaro.org>
>> + *         Fu Wei <fu.wei@linaro.org>
>> + *         Hanjun Guo <hanjun.guo@linaro.org>
>> + *
>> + * 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 <linux/acpi.h>
>> +#include <linux/init.h>
>> +#include <linux/kernel.h>
>> +
>> +#include <clocksource/arm_arch_timer.h>
>> +
>> +#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.
>
> Note: Secure state is not managed by the kernel on ARM64 systems.
>
> Is that what you wanted to say ?

yes, you are right, thanks! :-)
Will do so.

>
>> + * 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.
>
> Return: true if the timer HW state is lost when a CPU enters an idle
>         state, false otherwise

Thanks , will do

>
>> + */
>> +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
>
> I do not understand what this means.
>
>> + *                           number of platform timers. It can be NULL, if
>> + *                           driver don't need this info.
>
> driver doesn't

Sorry, this is not clear, I will fix it by :

 * @platform_timer_count: It points to a integer variable which is used
 *                           for storing the number of platform timers.
 *                           This pointer could be NULL, if the caller
 *                           doesn'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);
>
> Ok, two points here. First, I am not sure why you should warn if the
> table revision is < 2, is that a FW bug ? I do not think it is, you
> can just return 0.

I used pr_debug here before v20, then I got Hanjun's suggestion:
-------
GTDT table revision is updated to 2 in ACPI 5.1, we will
not support ACPI version under 5.1 and disable ACPI in FADT
parse before this code is called, so if we get revision
<2 here, I think we need to print warning (we need to keep
the firmware stick to the spec on ARM64).
-------
https://lkml.org/lkml/2017/1/19/82

So I started to use pr_warn.

>
>> +     else if (!gtdt->platform_timer_count)
>> +             pr_debug("No Platform Timer.\n");
>
> Ditto. Why keep executing ? There is nothing to do, just bail out
> with a return 0.
>
>> +     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;
>
> Same here, I suspect you want to consolidate the return path (I missed
> previous rounds of reviews so you should not worry too much, I can clean
> this up later) but to me a:
>
> return -EINVAL;
>
> would just do.

yes, you are right, I try to consolidate the return path. :-)
It may can return earlier, let me try.

>
> Lorenzo
>
>> +             }
>> +     }
>> +
>> +     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 9b05886..4b5c146 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -595,6 +595,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
>> --
>> 2.9.3
>>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29  9:48       ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29  9:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lorenzo,

Great thanks for your review and help, I will take most of your suggestions,
But one or two comments have been discussed in previous patchset,
please allow me to explain these. :-)

On 28 March 2017 at 19:35, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Wed, Mar 22, 2017 at 12:31:18AM +0800, fu.wei at linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> 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 <fu.wei@linaro.org>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>
> Some nits below.

Great thanks!

>
>> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>  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(+)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 3741859..7e2baec 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 <daniel.lezcano@linaro.org>
>> + *         Fu Wei <fu.wei@linaro.org>
>> + *         Hanjun Guo <hanjun.guo@linaro.org>
>> + *
>> + * 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 <linux/acpi.h>
>> +#include <linux/init.h>
>> +#include <linux/kernel.h>
>> +
>> +#include <clocksource/arm_arch_timer.h>
>> +
>> +#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.
>
> Note: Secure state is not managed by the kernel on ARM64 systems.
>
> Is that what you wanted to say ?

yes, you are right, thanks! :-)
Will do so.

>
>> + * 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.
>
> Return: true if the timer HW state is lost when a CPU enters an idle
>         state, false otherwise

Thanks , will do

>
>> + */
>> +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
>
> I do not understand what this means.
>
>> + *                           number of platform timers. It can be NULL, if
>> + *                           driver don't need this info.
>
> driver doesn't

Sorry, this is not clear, I will fix it by :

 * @platform_timer_count: It points to a integer variable which is used
 *                           for storing the number of platform timers.
 *                           This pointer could be NULL, if the caller
 *                           doesn'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);
>
> Ok, two points here. First, I am not sure why you should warn if the
> table revision is < 2, is that a FW bug ? I do not think it is, you
> can just return 0.

I used pr_debug here before v20, then I got Hanjun's suggestion:
-------
GTDT table revision is updated to 2 in ACPI 5.1, we will
not support ACPI version under 5.1 and disable ACPI in FADT
parse before this code is called, so if we get revision
<2 here, I think we need to print warning (we need to keep
the firmware stick to the spec on ARM64).
-------
https://lkml.org/lkml/2017/1/19/82

So I started to use pr_warn.

>
>> +     else if (!gtdt->platform_timer_count)
>> +             pr_debug("No Platform Timer.\n");
>
> Ditto. Why keep executing ? There is nothing to do, just bail out
> with a return 0.
>
>> +     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;
>
> Same here, I suspect you want to consolidate the return path (I missed
> previous rounds of reviews so you should not worry too much, I can clean
> this up later) but to me a:
>
> return -EINVAL;
>
> would just do.

yes, you are right, I try to consolidate the return path. :-)
It may can return earlier, let me try.

>
> Lorenzo
>
>> +             }
>> +     }
>> +
>> +     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 9b05886..4b5c146 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -595,6 +595,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
>> --
>> 2.9.3
>>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
  2017-03-29  9:48       ` Fu Wei
  (?)
@ 2017-03-29 10:21         ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-29 10:21 UTC (permalink / raw)
  To: Fu Wei
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei

On Wed, Mar 29, 2017 at 05:48:17PM +0800, Fu Wei wrote:

[...]

>  * @platform_timer_count: It points to a integer variable which is used
>  *                           for storing the number of platform timers.
>  *                           This pointer could be NULL, if the caller
>  *                           doesn'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);
> >
> > Ok, two points here. First, I am not sure why you should warn if the
> > table revision is < 2, is that a FW bug ? I do not think it is, you
> > can just return 0.
> 
> I used pr_debug here before v20, then I got Hanjun's suggestion:
> -------
> GTDT table revision is updated to 2 in ACPI 5.1, we will
> not support ACPI version under 5.1 and disable ACPI in FADT
> parse before this code is called, so if we get revision
> <2 here, I think we need to print warning (we need to keep
> the firmware stick to the spec on ARM64).
> -------
> https://lkml.org/lkml/2017/1/19/82
> 
> So I started to use pr_warn.

Thanks for the explanation, so it is a FW bug and the warning
is granted :) just leave it there.

Still, please check my comment on acpi_gtdt_init() being called
multiple times on patch 11.

Thanks,
Lorenzo

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29 10:21         ` Lorenzo Pieralisi
  0 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-29 10:21 UTC (permalink / raw)
  To: Fu Wei
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

On Wed, Mar 29, 2017 at 05:48:17PM +0800, Fu Wei wrote:

[...]

>  * @platform_timer_count: It points to a integer variable which is used
>  *                           for storing the number of platform timers.
>  *                           This pointer could be NULL, if the caller
>  *                           doesn'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);
> >
> > Ok, two points here. First, I am not sure why you should warn if the
> > table revision is < 2, is that a FW bug ? I do not think it is, you
> > can just return 0.
> 
> I used pr_debug here before v20, then I got Hanjun's suggestion:
> -------
> GTDT table revision is updated to 2 in ACPI 5.1, we will
> not support ACPI version under 5.1 and disable ACPI in FADT
> parse before this code is called, so if we get revision
> <2 here, I think we need to print warning (we need to keep
> the firmware stick to the spec on ARM64).
> -------
> https://lkml.org/lkml/2017/1/19/82
> 
> So I started to use pr_warn.

Thanks for the explanation, so it is a FW bug and the warning
is granted :) just leave it there.

Still, please check my comment on acpi_gtdt_init() being called
multiple times on patch 11.

Thanks,
Lorenzo

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29 10:21         ` Lorenzo Pieralisi
  0 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-29 10:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 29, 2017 at 05:48:17PM +0800, Fu Wei wrote:

[...]

>  * @platform_timer_count: It points to a integer variable which is used
>  *                           for storing the number of platform timers.
>  *                           This pointer could be NULL, if the caller
>  *                           doesn'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);
> >
> > Ok, two points here. First, I am not sure why you should warn if the
> > table revision is < 2, is that a FW bug ? I do not think it is, you
> > can just return 0.
> 
> I used pr_debug here before v20, then I got Hanjun's suggestion:
> -------
> GTDT table revision is updated to 2 in ACPI 5.1, we will
> not support ACPI version under 5.1 and disable ACPI in FADT
> parse before this code is called, so if we get revision
> <2 here, I think we need to print warning (we need to keep
> the firmware stick to the spec on ARM64).
> -------
> https://lkml.org/lkml/2017/1/19/82
> 
> So I started to use pr_warn.

Thanks for the explanation, so it is a FW bug and the warning
is granted :) just leave it there.

Still, please check my comment on acpi_gtdt_init() being called
multiple times on patch 11.

Thanks,
Lorenzo

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
  2017-03-29 10:21         ` Lorenzo Pieralisi
  (?)
@ 2017-03-29 10:48           ` Fu Wei
  -1 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29 10:48 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei

Hi Lorenzo,

On 29 March 2017 at 18:21, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Wed, Mar 29, 2017 at 05:48:17PM +0800, Fu Wei wrote:
>
> [...]
>
>>  * @platform_timer_count: It points to a integer variable which is used
>>  *                           for storing the number of platform timers.
>>  *                           This pointer could be NULL, if the caller
>>  *                           doesn'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);
>> >
>> > Ok, two points here. First, I am not sure why you should warn if the
>> > table revision is < 2, is that a FW bug ? I do not think it is, you
>> > can just return 0.
>>
>> I used pr_debug here before v20, then I got Hanjun's suggestion:
>> -------
>> GTDT table revision is updated to 2 in ACPI 5.1, we will
>> not support ACPI version under 5.1 and disable ACPI in FADT
>> parse before this code is called, so if we get revision
>> <2 here, I think we need to print warning (we need to keep
>> the firmware stick to the spec on ARM64).
>> -------
>> https://lkml.org/lkml/2017/1/19/82
>>
>> So I started to use pr_warn.
>
> Thanks for the explanation, so it is a FW bug and the warning
> is granted :) just leave it there.
>
> Still, please check my comment on acpi_gtdt_init() being called
> multiple times on patch 11.

Thanks

For calling acpi_gtdt_init() twice:
(1) 1st time: in early boot(bootmem), for init arch_timer and
memory-mapped timer, we initialize the acpi_gtdt_desc.
you can see that all the items in this struct are pointer.
(2) 2nd time: when system switch from bootmem to slab, all the
pointers in the acpi_gtdt_desc are invalid, so we have to
re-initialize(re-map) them.

I have tested it, if we don't re-initialize  the acpi_gtdt_desc,
system will go wrong.

>
> Thanks,
> Lorenzo



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29 10:48           ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29 10:48 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

Hi Lorenzo,

On 29 March 2017 at 18:21, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Wed, Mar 29, 2017 at 05:48:17PM +0800, Fu Wei wrote:
>
> [...]
>
>>  * @platform_timer_count: It points to a integer variable which is used
>>  *                           for storing the number of platform timers.
>>  *                           This pointer could be NULL, if the caller
>>  *                           doesn'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);
>> >
>> > Ok, two points here. First, I am not sure why you should warn if the
>> > table revision is < 2, is that a FW bug ? I do not think it is, you
>> > can just return 0.
>>
>> I used pr_debug here before v20, then I got Hanjun's suggestion:
>> -------
>> GTDT table revision is updated to 2 in ACPI 5.1, we will
>> not support ACPI version under 5.1 and disable ACPI in FADT
>> parse before this code is called, so if we get revision
>> <2 here, I think we need to print warning (we need to keep
>> the firmware stick to the spec on ARM64).
>> -------
>> https://lkml.org/lkml/2017/1/19/82
>>
>> So I started to use pr_warn.
>
> Thanks for the explanation, so it is a FW bug and the warning
> is granted :) just leave it there.
>
> Still, please check my comment on acpi_gtdt_init() being called
> multiple times on patch 11.

Thanks

For calling acpi_gtdt_init() twice:
(1) 1st time: in early boot(bootmem), for init arch_timer and
memory-mapped timer, we initialize the acpi_gtdt_desc.
you can see that all the items in this struct are pointer.
(2) 2nd time: when system switch from bootmem to slab, all the
pointers in the acpi_gtdt_desc are invalid, so we have to
re-initialize(re-map) them.

I have tested it, if we don't re-initialize  the acpi_gtdt_desc,
system will go wrong.

>
> Thanks,
> Lorenzo



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29 10:48           ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29 10:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lorenzo,

On 29 March 2017 at 18:21, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Wed, Mar 29, 2017 at 05:48:17PM +0800, Fu Wei wrote:
>
> [...]
>
>>  * @platform_timer_count: It points to a integer variable which is used
>>  *                           for storing the number of platform timers.
>>  *                           This pointer could be NULL, if the caller
>>  *                           doesn'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);
>> >
>> > Ok, two points here. First, I am not sure why you should warn if the
>> > table revision is < 2, is that a FW bug ? I do not think it is, you
>> > can just return 0.
>>
>> I used pr_debug here before v20, then I got Hanjun's suggestion:
>> -------
>> GTDT table revision is updated to 2 in ACPI 5.1, we will
>> not support ACPI version under 5.1 and disable ACPI in FADT
>> parse before this code is called, so if we get revision
>> <2 here, I think we need to print warning (we need to keep
>> the firmware stick to the spec on ARM64).
>> -------
>> https://lkml.org/lkml/2017/1/19/82
>>
>> So I started to use pr_warn.
>
> Thanks for the explanation, so it is a FW bug and the warning
> is granted :) just leave it there.
>
> Still, please check my comment on acpi_gtdt_init() being called
> multiple times on patch 11.

Thanks

For calling acpi_gtdt_init() twice:
(1) 1st time: in early boot(bootmem), for init arch_timer and
memory-mapped timer, we initialize the acpi_gtdt_desc.
you can see that all the items in this struct are pointer.
(2) 2nd time: when system switch from bootmem to slab, all the
pointers in the acpi_gtdt_desc are invalid, so we have to
re-initialize(re-map) them.

I have tested it, if we don't re-initialize  the acpi_gtdt_desc,
system will go wrong.

>
> Thanks,
> Lorenzo



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
  2017-03-29 10:48           ` Fu Wei
  (?)
@ 2017-03-29 11:33             ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-29 11:33 UTC (permalink / raw)
  To: Fu Wei
  Cc: Mark Rutland, Linaro ACPI Mailman List, Catalin Marinas,
	Will Deacon, rruigrok, Wim Van Sebroeck, Wei Huang, Al Stone,
	Tomasz Nowicki, Timur Tabi, Daniel Lezcano,
	ACPI Devel Maling List, Guenter Roeck, Len Brown, Abdulhamid,
	Harb, Julien Grall, linux-watchdog, Arnd Bergmann, Marc Zyngier,
	Jon Masters, Christopher Covington, Thomas Gleixner,
	linux-arm-kernel, G Gregory

On Wed, Mar 29, 2017 at 06:48:26PM +0800, Fu Wei wrote:
> Hi Lorenzo,
> 
> On 29 March 2017 at 18:21, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> > On Wed, Mar 29, 2017 at 05:48:17PM +0800, Fu Wei wrote:
> >
> > [...]
> >
> >>  * @platform_timer_count: It points to a integer variable which is used
> >>  *                           for storing the number of platform timers.
> >>  *                           This pointer could be NULL, if the caller
> >>  *                           doesn'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);
> >> >
> >> > Ok, two points here. First, I am not sure why you should warn if the
> >> > table revision is < 2, is that a FW bug ? I do not think it is, you
> >> > can just return 0.
> >>
> >> I used pr_debug here before v20, then I got Hanjun's suggestion:
> >> -------
> >> GTDT table revision is updated to 2 in ACPI 5.1, we will
> >> not support ACPI version under 5.1 and disable ACPI in FADT
> >> parse before this code is called, so if we get revision
> >> <2 here, I think we need to print warning (we need to keep
> >> the firmware stick to the spec on ARM64).
> >> -------
> >> https://lkml.org/lkml/2017/1/19/82
> >>
> >> So I started to use pr_warn.
> >
> > Thanks for the explanation, so it is a FW bug and the warning
> > is granted :) just leave it there.
> >
> > Still, please check my comment on acpi_gtdt_init() being called
> > multiple times on patch 11.
> 
> Thanks
> 
> For calling acpi_gtdt_init() twice:
> (1) 1st time: in early boot(bootmem), for init arch_timer and
> memory-mapped timer, we initialize the acpi_gtdt_desc.
> you can see that all the items in this struct are pointer.
> (2) 2nd time: when system switch from bootmem to slab, all the
> pointers in the acpi_gtdt_desc are invalid, so we have to
> re-initialize(re-map) them.
> 
> I have tested it, if we don't re-initialize  the acpi_gtdt_desc,
> system will go wrong.

Ok, that's what I feared. My complaint on patch 11 is that:

1) Stashing the GTDT pointer in acpi_gtdt_desc is not needed to
   parse SBSA watchdogs
2) It is not clear at all from the code or the commit log _why_ you
   need to call acpi_gtdt_init() again (ie technically you don't need
   to call it - you grab a valid pointer to the table and parse the
   watchdogs in the _same_ function gtdt_sbsa_gwdt_init())

I do not think there is much you can do to improve the arch timer gtdt
interface (and it is too late for that anyway) but in patch 11 it would
be ideal if you avoid calling acpi_gtdt_init() again, just parse GTDT
entries and initialize the corresponding watchdogs (ie pointers stashed
in acpi_gtdt_desc are stale anyway but that's __initdata so I can live
with that).

You should add comments to summarize this issue so that it can be
easily understood by anyone maintaining this code, it is not crystal
clear by reading the code why you need to multiple acpi_gtdt_init()
calls and that's not a piffling detail.

The ACPI patches are fine with me otherwise, I will complete the
review shortly.

Thanks !
Lorenzo

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29 11:33             ` Lorenzo Pieralisi
  0 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-29 11:33 UTC (permalink / raw)
  To: Fu Wei
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

On Wed, Mar 29, 2017 at 06:48:26PM +0800, Fu Wei wrote:
> Hi Lorenzo,
> 
> On 29 March 2017 at 18:21, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> > On Wed, Mar 29, 2017 at 05:48:17PM +0800, Fu Wei wrote:
> >
> > [...]
> >
> >>  * @platform_timer_count: It points to a integer variable which is used
> >>  *                           for storing the number of platform timers.
> >>  *                           This pointer could be NULL, if the caller
> >>  *                           doesn'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);
> >> >
> >> > Ok, two points here. First, I am not sure why you should warn if the
> >> > table revision is < 2, is that a FW bug ? I do not think it is, you
> >> > can just return 0.
> >>
> >> I used pr_debug here before v20, then I got Hanjun's suggestion:
> >> -------
> >> GTDT table revision is updated to 2 in ACPI 5.1, we will
> >> not support ACPI version under 5.1 and disable ACPI in FADT
> >> parse before this code is called, so if we get revision
> >> <2 here, I think we need to print warning (we need to keep
> >> the firmware stick to the spec on ARM64).
> >> -------
> >> https://lkml.org/lkml/2017/1/19/82
> >>
> >> So I started to use pr_warn.
> >
> > Thanks for the explanation, so it is a FW bug and the warning
> > is granted :) just leave it there.
> >
> > Still, please check my comment on acpi_gtdt_init() being called
> > multiple times on patch 11.
> 
> Thanks
> 
> For calling acpi_gtdt_init() twice:
> (1) 1st time: in early boot(bootmem), for init arch_timer and
> memory-mapped timer, we initialize the acpi_gtdt_desc.
> you can see that all the items in this struct are pointer.
> (2) 2nd time: when system switch from bootmem to slab, all the
> pointers in the acpi_gtdt_desc are invalid, so we have to
> re-initialize(re-map) them.
> 
> I have tested it, if we don't re-initialize  the acpi_gtdt_desc,
> system will go wrong.

Ok, that's what I feared. My complaint on patch 11 is that:

1) Stashing the GTDT pointer in acpi_gtdt_desc is not needed to
   parse SBSA watchdogs
2) It is not clear at all from the code or the commit log _why_ you
   need to call acpi_gtdt_init() again (ie technically you don't need
   to call it - you grab a valid pointer to the table and parse the
   watchdogs in the _same_ function gtdt_sbsa_gwdt_init())

I do not think there is much you can do to improve the arch timer gtdt
interface (and it is too late for that anyway) but in patch 11 it would
be ideal if you avoid calling acpi_gtdt_init() again, just parse GTDT
entries and initialize the corresponding watchdogs (ie pointers stashed
in acpi_gtdt_desc are stale anyway but that's __initdata so I can live
with that).

You should add comments to summarize this issue so that it can be
easily understood by anyone maintaining this code, it is not crystal
clear by reading the code why you need to multiple acpi_gtdt_init()
calls and that's not a piffling detail.

The ACPI patches are fine with me otherwise, I will complete the
review shortly.

Thanks !
Lorenzo

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29 11:33             ` Lorenzo Pieralisi
  0 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-29 11:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 29, 2017 at 06:48:26PM +0800, Fu Wei wrote:
> Hi Lorenzo,
> 
> On 29 March 2017 at 18:21, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> > On Wed, Mar 29, 2017 at 05:48:17PM +0800, Fu Wei wrote:
> >
> > [...]
> >
> >>  * @platform_timer_count: It points to a integer variable which is used
> >>  *                           for storing the number of platform timers.
> >>  *                           This pointer could be NULL, if the caller
> >>  *                           doesn'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);
> >> >
> >> > Ok, two points here. First, I am not sure why you should warn if the
> >> > table revision is < 2, is that a FW bug ? I do not think it is, you
> >> > can just return 0.
> >>
> >> I used pr_debug here before v20, then I got Hanjun's suggestion:
> >> -------
> >> GTDT table revision is updated to 2 in ACPI 5.1, we will
> >> not support ACPI version under 5.1 and disable ACPI in FADT
> >> parse before this code is called, so if we get revision
> >> <2 here, I think we need to print warning (we need to keep
> >> the firmware stick to the spec on ARM64).
> >> -------
> >> https://lkml.org/lkml/2017/1/19/82
> >>
> >> So I started to use pr_warn.
> >
> > Thanks for the explanation, so it is a FW bug and the warning
> > is granted :) just leave it there.
> >
> > Still, please check my comment on acpi_gtdt_init() being called
> > multiple times on patch 11.
> 
> Thanks
> 
> For calling acpi_gtdt_init() twice:
> (1) 1st time: in early boot(bootmem), for init arch_timer and
> memory-mapped timer, we initialize the acpi_gtdt_desc.
> you can see that all the items in this struct are pointer.
> (2) 2nd time: when system switch from bootmem to slab, all the
> pointers in the acpi_gtdt_desc are invalid, so we have to
> re-initialize(re-map) them.
> 
> I have tested it, if we don't re-initialize  the acpi_gtdt_desc,
> system will go wrong.

Ok, that's what I feared. My complaint on patch 11 is that:

1) Stashing the GTDT pointer in acpi_gtdt_desc is not needed to
   parse SBSA watchdogs
2) It is not clear at all from the code or the commit log _why_ you
   need to call acpi_gtdt_init() again (ie technically you don't need
   to call it - you grab a valid pointer to the table and parse the
   watchdogs in the _same_ function gtdt_sbsa_gwdt_init())

I do not think there is much you can do to improve the arch timer gtdt
interface (and it is too late for that anyway) but in patch 11 it would
be ideal if you avoid calling acpi_gtdt_init() again, just parse GTDT
entries and initialize the corresponding watchdogs (ie pointers stashed
in acpi_gtdt_desc are stale anyway but that's __initdata so I can live
with that).

You should add comments to summarize this issue so that it can be
easily understood by anyone maintaining this code, it is not crystal
clear by reading the code why you need to multiple acpi_gtdt_init()
calls and that's not a piffling detail.

The ACPI patches are fine with me otherwise, I will complete the
review shortly.

Thanks !
Lorenzo

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
  2017-03-29 11:33             ` Lorenzo Pieralisi
  (?)
@ 2017-03-29 13:42               ` Fu Wei
  -1 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29 13:42 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei

Hi Lorenzo,

On 29 March 2017 at 19:33, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Wed, Mar 29, 2017 at 06:48:26PM +0800, Fu Wei wrote:
>> Hi Lorenzo,
>>
>> On 29 March 2017 at 18:21, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
>> > On Wed, Mar 29, 2017 at 05:48:17PM +0800, Fu Wei wrote:
>> >
>> > [...]
>> >
>> >>  * @platform_timer_count: It points to a integer variable which is used
>> >>  *                           for storing the number of platform timers.
>> >>  *                           This pointer could be NULL, if the caller
>> >>  *                           doesn'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);
>> >> >
>> >> > Ok, two points here. First, I am not sure why you should warn if the
>> >> > table revision is < 2, is that a FW bug ? I do not think it is, you
>> >> > can just return 0.
>> >>
>> >> I used pr_debug here before v20, then I got Hanjun's suggestion:
>> >> -------
>> >> GTDT table revision is updated to 2 in ACPI 5.1, we will
>> >> not support ACPI version under 5.1 and disable ACPI in FADT
>> >> parse before this code is called, so if we get revision
>> >> <2 here, I think we need to print warning (we need to keep
>> >> the firmware stick to the spec on ARM64).
>> >> -------
>> >> https://lkml.org/lkml/2017/1/19/82
>> >>
>> >> So I started to use pr_warn.
>> >
>> > Thanks for the explanation, so it is a FW bug and the warning
>> > is granted :) just leave it there.
>> >
>> > Still, please check my comment on acpi_gtdt_init() being called
>> > multiple times on patch 11.
>>
>> Thanks
>>
>> For calling acpi_gtdt_init() twice:
>> (1) 1st time: in early boot(bootmem), for init arch_timer and
>> memory-mapped timer, we initialize the acpi_gtdt_desc.
>> you can see that all the items in this struct are pointer.
>> (2) 2nd time: when system switch from bootmem to slab, all the
>> pointers in the acpi_gtdt_desc are invalid, so we have to
>> re-initialize(re-map) them.
>>
>> I have tested it, if we don't re-initialize  the acpi_gtdt_desc,
>> system will go wrong.
>
> Ok, that's what I feared. My complaint on patch 11 is that:
>
> 1) Stashing the GTDT pointer in acpi_gtdt_desc is not needed to
>    parse SBSA watchdogs

The acpi_gtdt_desc is for sharing the info between acpi_gtdt_init and
acpi_gtdt_c3stop, ;acpi_gtdt_map_ppi
I re-use it in parsing SBSA watchdogs, because I try to re-use acpi_gtdt_init.

> 2) It is not clear at all from the code or the commit log _why_ you
>    need to call acpi_gtdt_init() again (ie technically you don't need
>    to call it - you grab a valid pointer to the table and parse the
>    watchdogs in the _same_ function gtdt_sbsa_gwdt_init())

yes, we can avoid calling acpi_gtdt_init(), do the same thing in
parsing SBSA watchdogs info.
But if we will do the same thing(getting gtdt, platform_timer,
timer_count), why not just re-using the same function?

So my suggestion is that:
Could we re-use acpi_gtdt_init, and a comment at the head of SBSA
watchdogs info parsing function to summarize this issue?
The comment like this

Note: although the global variable acpi_gtdt_desc has been initialized
by acpi_gtdt_init, when we initialized arch_timer. But when we call this
function to get SBSA watchdogs info from GTDT, the system has switch
from bootmem  to slab, so the pointers in acpi_gtdt_desc are dated, we
need to  re-initialize(remap) them. So we call acpi_gtdt_init again here.

Is that OK for you? :-)

>
> I do not think there is much you can do to improve the arch timer gtdt
> interface (and it is too late for that anyway) but in patch 11 it would
> be ideal if you avoid calling acpi_gtdt_init() again, just parse GTDT
> entries and initialize the corresponding watchdogs (ie pointers stashed
> in acpi_gtdt_desc are stale anyway but that's __initdata so I can live
> with that).
>
> You should add comments to summarize this issue so that it can be
> easily understood by anyone maintaining this code, it is not crystal
> clear by reading the code why you need to multiple acpi_gtdt_init()
> calls and that's not a piffling detail.
>
> The ACPI patches are fine with me otherwise, I will complete the
> review shortly.
>
> Thanks !
> Lorenzo



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29 13:42               ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29 13:42 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

Hi Lorenzo,

On 29 March 2017 at 19:33, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Wed, Mar 29, 2017 at 06:48:26PM +0800, Fu Wei wrote:
>> Hi Lorenzo,
>>
>> On 29 March 2017 at 18:21, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
>> > On Wed, Mar 29, 2017 at 05:48:17PM +0800, Fu Wei wrote:
>> >
>> > [...]
>> >
>> >>  * @platform_timer_count: It points to a integer variable which is used
>> >>  *                           for storing the number of platform timers.
>> >>  *                           This pointer could be NULL, if the caller
>> >>  *                           doesn'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);
>> >> >
>> >> > Ok, two points here. First, I am not sure why you should warn if the
>> >> > table revision is < 2, is that a FW bug ? I do not think it is, you
>> >> > can just return 0.
>> >>
>> >> I used pr_debug here before v20, then I got Hanjun's suggestion:
>> >> -------
>> >> GTDT table revision is updated to 2 in ACPI 5.1, we will
>> >> not support ACPI version under 5.1 and disable ACPI in FADT
>> >> parse before this code is called, so if we get revision
>> >> <2 here, I think we need to print warning (we need to keep
>> >> the firmware stick to the spec on ARM64).
>> >> -------
>> >> https://lkml.org/lkml/2017/1/19/82
>> >>
>> >> So I started to use pr_warn.
>> >
>> > Thanks for the explanation, so it is a FW bug and the warning
>> > is granted :) just leave it there.
>> >
>> > Still, please check my comment on acpi_gtdt_init() being called
>> > multiple times on patch 11.
>>
>> Thanks
>>
>> For calling acpi_gtdt_init() twice:
>> (1) 1st time: in early boot(bootmem), for init arch_timer and
>> memory-mapped timer, we initialize the acpi_gtdt_desc.
>> you can see that all the items in this struct are pointer.
>> (2) 2nd time: when system switch from bootmem to slab, all the
>> pointers in the acpi_gtdt_desc are invalid, so we have to
>> re-initialize(re-map) them.
>>
>> I have tested it, if we don't re-initialize  the acpi_gtdt_desc,
>> system will go wrong.
>
> Ok, that's what I feared. My complaint on patch 11 is that:
>
> 1) Stashing the GTDT pointer in acpi_gtdt_desc is not needed to
>    parse SBSA watchdogs

The acpi_gtdt_desc is for sharing the info between acpi_gtdt_init and
acpi_gtdt_c3stop, ;acpi_gtdt_map_ppi
I re-use it in parsing SBSA watchdogs, because I try to re-use acpi_gtdt_init.

> 2) It is not clear at all from the code or the commit log _why_ you
>    need to call acpi_gtdt_init() again (ie technically you don't need
>    to call it - you grab a valid pointer to the table and parse the
>    watchdogs in the _same_ function gtdt_sbsa_gwdt_init())

yes, we can avoid calling acpi_gtdt_init(), do the same thing in
parsing SBSA watchdogs info.
But if we will do the same thing(getting gtdt, platform_timer,
timer_count), why not just re-using the same function?

So my suggestion is that:
Could we re-use acpi_gtdt_init, and a comment at the head of SBSA
watchdogs info parsing function to summarize this issue?
The comment like this

Note: although the global variable acpi_gtdt_desc has been initialized
by acpi_gtdt_init, when we initialized arch_timer. But when we call this
function to get SBSA watchdogs info from GTDT, the system has switch
from bootmem  to slab, so the pointers in acpi_gtdt_desc are dated, we
need to  re-initialize(remap) them. So we call acpi_gtdt_init again here.

Is that OK for you? :-)

>
> I do not think there is much you can do to improve the arch timer gtdt
> interface (and it is too late for that anyway) but in patch 11 it would
> be ideal if you avoid calling acpi_gtdt_init() again, just parse GTDT
> entries and initialize the corresponding watchdogs (ie pointers stashed
> in acpi_gtdt_desc are stale anyway but that's __initdata so I can live
> with that).
>
> You should add comments to summarize this issue so that it can be
> easily understood by anyone maintaining this code, it is not crystal
> clear by reading the code why you need to multiple acpi_gtdt_init()
> calls and that's not a piffling detail.
>
> The ACPI patches are fine with me otherwise, I will complete the
> review shortly.
>
> Thanks !
> Lorenzo



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29 13:42               ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29 13:42 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lorenzo,

On 29 March 2017 at 19:33, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Wed, Mar 29, 2017 at 06:48:26PM +0800, Fu Wei wrote:
>> Hi Lorenzo,
>>
>> On 29 March 2017 at 18:21, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
>> > On Wed, Mar 29, 2017 at 05:48:17PM +0800, Fu Wei wrote:
>> >
>> > [...]
>> >
>> >>  * @platform_timer_count: It points to a integer variable which is used
>> >>  *                           for storing the number of platform timers.
>> >>  *                           This pointer could be NULL, if the caller
>> >>  *                           doesn'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);
>> >> >
>> >> > Ok, two points here. First, I am not sure why you should warn if the
>> >> > table revision is < 2, is that a FW bug ? I do not think it is, you
>> >> > can just return 0.
>> >>
>> >> I used pr_debug here before v20, then I got Hanjun's suggestion:
>> >> -------
>> >> GTDT table revision is updated to 2 in ACPI 5.1, we will
>> >> not support ACPI version under 5.1 and disable ACPI in FADT
>> >> parse before this code is called, so if we get revision
>> >> <2 here, I think we need to print warning (we need to keep
>> >> the firmware stick to the spec on ARM64).
>> >> -------
>> >> https://lkml.org/lkml/2017/1/19/82
>> >>
>> >> So I started to use pr_warn.
>> >
>> > Thanks for the explanation, so it is a FW bug and the warning
>> > is granted :) just leave it there.
>> >
>> > Still, please check my comment on acpi_gtdt_init() being called
>> > multiple times on patch 11.
>>
>> Thanks
>>
>> For calling acpi_gtdt_init() twice:
>> (1) 1st time: in early boot(bootmem), for init arch_timer and
>> memory-mapped timer, we initialize the acpi_gtdt_desc.
>> you can see that all the items in this struct are pointer.
>> (2) 2nd time: when system switch from bootmem to slab, all the
>> pointers in the acpi_gtdt_desc are invalid, so we have to
>> re-initialize(re-map) them.
>>
>> I have tested it, if we don't re-initialize  the acpi_gtdt_desc,
>> system will go wrong.
>
> Ok, that's what I feared. My complaint on patch 11 is that:
>
> 1) Stashing the GTDT pointer in acpi_gtdt_desc is not needed to
>    parse SBSA watchdogs

The acpi_gtdt_desc is for sharing the info between acpi_gtdt_init and
acpi_gtdt_c3stop, ;acpi_gtdt_map_ppi
I re-use it in parsing SBSA watchdogs, because I try to re-use acpi_gtdt_init.

> 2) It is not clear at all from the code or the commit log _why_ you
>    need to call acpi_gtdt_init() again (ie technically you don't need
>    to call it - you grab a valid pointer to the table and parse the
>    watchdogs in the _same_ function gtdt_sbsa_gwdt_init())

yes, we can avoid calling acpi_gtdt_init(), do the same thing in
parsing SBSA watchdogs info.
But if we will do the same thing(getting gtdt, platform_timer,
timer_count), why not just re-using the same function?

So my suggestion is that:
Could we re-use acpi_gtdt_init, and a comment at the head of SBSA
watchdogs info parsing function to summarize this issue?
The comment like this

Note: although the global variable acpi_gtdt_desc has been initialized
by acpi_gtdt_init, when we initialized arch_timer. But when we call this
function to get SBSA watchdogs info from GTDT, the system has switch
from bootmem  to slab, so the pointers in acpi_gtdt_desc are dated, we
need to  re-initialize(remap) them. So we call acpi_gtdt_init again here.

Is that OK for you? :-)

>
> I do not think there is much you can do to improve the arch timer gtdt
> interface (and it is too late for that anyway) but in patch 11 it would
> be ideal if you avoid calling acpi_gtdt_init() again, just parse GTDT
> entries and initialize the corresponding watchdogs (ie pointers stashed
> in acpi_gtdt_desc are stale anyway but that's __initdata so I can live
> with that).
>
> You should add comments to summarize this issue so that it can be
> easily understood by anyone maintaining this code, it is not crystal
> clear by reading the code why you need to multiple acpi_gtdt_init()
> calls and that's not a piffling detail.
>
> The ACPI patches are fine with me otherwise, I will complete the
> review shortly.
>
> Thanks !
> Lorenzo



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
  2017-03-28 11:35     ` Lorenzo Pieralisi
  (?)
@ 2017-03-29 14:29       ` Fu Wei
  -1 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29 14:29 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Linaro ACPI Mailman List, Linux Kernel Mailing List,
	ACPI Devel Maling List, rruigrok-sgV2jX0FEOL9JmXXK+q4OQ,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei

Hi Lorenzo,

On 28 March 2017 at 19:35, Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org> wrote:
> On Wed, Mar 22, 2017 at 12:31:18AM +0800, fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org wrote:
>> From: Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>
>> 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 <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> Signed-off-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> Acked-by: Rafael J. Wysocki <rafael.j.wysocki-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>
> Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
>
> Some nits below.
>
>> Tested-by: Xiongfeng Wang <wangxiongfeng2-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>> Reviewed-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> Tested-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> ---
>>  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(+)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 3741859..7e2baec 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 <daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> + *         Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> + *         Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> + *
>> + * 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 <linux/acpi.h>
>> +#include <linux/init.h>
>> +#include <linux/kernel.h>
>> +
>> +#include <clocksource/arm_arch_timer.h>
>> +
>> +#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.
>
> Note: Secure state is not managed by the kernel on ARM64 systems.
>
> Is that what you wanted to say ?
>
>> + * 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.
>
> Return: true if the timer HW state is lost when a CPU enters an idle
>         state, false 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
>
> I do not understand what this means.
>
>> + *                           number of platform timers. It can be NULL, if
>> + *                           driver don't need this info.
>
> driver doesn't
>
>> + *
>> + * 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);
>
> Ok, two points here. First, I am not sure why you should warn if the
> table revision is < 2, is that a FW bug ? I do not think it is, you
> can just return 0.
>
>> +     else if (!gtdt->platform_timer_count)
>> +             pr_debug("No Platform Timer.\n");
>
> Ditto. Why keep executing ? There is nothing to do, just bail out
> with a return 0.
>
>> +     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;
>
> Same here, I suspect you want to consolidate the return path (I missed
> previous rounds of reviews so you should not worry too much, I can clean
> this up later) but to me a:
>
> return -EINVAL;
>
> would just do.

For this problem, Can I do this:

/**
 * acpi_gtdt_init() - Get the info of GTDT table to prepare for further init.
 * @table:                        The pointer to GTDT table.
 * @platform_timer_count:        It points to a integer variable which is used
 *                                for storing the number of platform timers.
 *                                This pointer could be NULL, if the caller
 *                                doesn'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)
{
        void *platform_timer;
        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;
        acpi_gtdt_desc.platform_timer = NULL;
        if (platform_timer_count)
                *platform_timer_count = 0;

        if (table->revision < 2) {
                pr_warn("Revision:%d doesn't support Platform Timers.\n",
                        table->revision);
                return 0;
        }

        if (!gtdt->platform_timer_count) {
                pr_debug("No Platform Timer.\n");
                return 0;
        }
        if (platform_timer_count)
                *platform_timer_count = gtdt->platform_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");
                return -EINVAL;
        }
        acpi_gtdt_desc.platform_timer = platform_timer;

        return 0;
}


>
> Lorenzo
>
>> +             }
>> +     }
>> +
>> +     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 9b05886..4b5c146 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -595,6 +595,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
>> --
>> 2.9.3
>>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29 14:29       ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29 14:29 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

Hi Lorenzo,

On 28 March 2017 at 19:35, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Wed, Mar 22, 2017 at 12:31:18AM +0800, fu.wei@linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> 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 <fu.wei@linaro.org>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>
> Some nits below.
>
>> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>  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(+)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 3741859..7e2baec 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 <daniel.lezcano@linaro.org>
>> + *         Fu Wei <fu.wei@linaro.org>
>> + *         Hanjun Guo <hanjun.guo@linaro.org>
>> + *
>> + * 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 <linux/acpi.h>
>> +#include <linux/init.h>
>> +#include <linux/kernel.h>
>> +
>> +#include <clocksource/arm_arch_timer.h>
>> +
>> +#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.
>
> Note: Secure state is not managed by the kernel on ARM64 systems.
>
> Is that what you wanted to say ?
>
>> + * 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.
>
> Return: true if the timer HW state is lost when a CPU enters an idle
>         state, false 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
>
> I do not understand what this means.
>
>> + *                           number of platform timers. It can be NULL, if
>> + *                           driver don't need this info.
>
> driver doesn't
>
>> + *
>> + * 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);
>
> Ok, two points here. First, I am not sure why you should warn if the
> table revision is < 2, is that a FW bug ? I do not think it is, you
> can just return 0.
>
>> +     else if (!gtdt->platform_timer_count)
>> +             pr_debug("No Platform Timer.\n");
>
> Ditto. Why keep executing ? There is nothing to do, just bail out
> with a return 0.
>
>> +     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;
>
> Same here, I suspect you want to consolidate the return path (I missed
> previous rounds of reviews so you should not worry too much, I can clean
> this up later) but to me a:
>
> return -EINVAL;
>
> would just do.

For this problem, Can I do this:

/**
 * acpi_gtdt_init() - Get the info of GTDT table to prepare for further init.
 * @table:                        The pointer to GTDT table.
 * @platform_timer_count:        It points to a integer variable which is used
 *                                for storing the number of platform timers.
 *                                This pointer could be NULL, if the caller
 *                                doesn'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)
{
        void *platform_timer;
        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;
        acpi_gtdt_desc.platform_timer = NULL;
        if (platform_timer_count)
                *platform_timer_count = 0;

        if (table->revision < 2) {
                pr_warn("Revision:%d doesn't support Platform Timers.\n",
                        table->revision);
                return 0;
        }

        if (!gtdt->platform_timer_count) {
                pr_debug("No Platform Timer.\n");
                return 0;
        }
        if (platform_timer_count)
                *platform_timer_count = gtdt->platform_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");
                return -EINVAL;
        }
        acpi_gtdt_desc.platform_timer = platform_timer;

        return 0;
}


>
> Lorenzo
>
>> +             }
>> +     }
>> +
>> +     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 9b05886..4b5c146 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -595,6 +595,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
>> --
>> 2.9.3
>>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29 14:29       ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29 14:29 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lorenzo,

On 28 March 2017 at 19:35, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Wed, Mar 22, 2017 at 12:31:18AM +0800, fu.wei at linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> 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 <fu.wei@linaro.org>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>
> Some nits below.
>
>> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>  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(+)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 3741859..7e2baec 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 <daniel.lezcano@linaro.org>
>> + *         Fu Wei <fu.wei@linaro.org>
>> + *         Hanjun Guo <hanjun.guo@linaro.org>
>> + *
>> + * 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 <linux/acpi.h>
>> +#include <linux/init.h>
>> +#include <linux/kernel.h>
>> +
>> +#include <clocksource/arm_arch_timer.h>
>> +
>> +#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.
>
> Note: Secure state is not managed by the kernel on ARM64 systems.
>
> Is that what you wanted to say ?
>
>> + * 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.
>
> Return: true if the timer HW state is lost when a CPU enters an idle
>         state, false 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
>
> I do not understand what this means.
>
>> + *                           number of platform timers. It can be NULL, if
>> + *                           driver don't need this info.
>
> driver doesn't
>
>> + *
>> + * 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);
>
> Ok, two points here. First, I am not sure why you should warn if the
> table revision is < 2, is that a FW bug ? I do not think it is, you
> can just return 0.
>
>> +     else if (!gtdt->platform_timer_count)
>> +             pr_debug("No Platform Timer.\n");
>
> Ditto. Why keep executing ? There is nothing to do, just bail out
> with a return 0.
>
>> +     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;
>
> Same here, I suspect you want to consolidate the return path (I missed
> previous rounds of reviews so you should not worry too much, I can clean
> this up later) but to me a:
>
> return -EINVAL;
>
> would just do.

For this problem, Can I do this:

/**
 * acpi_gtdt_init() - Get the info of GTDT table to prepare for further init.
 * @table:                        The pointer to GTDT table.
 * @platform_timer_count:        It points to a integer variable which is used
 *                                for storing the number of platform timers.
 *                                This pointer could be NULL, if the caller
 *                                doesn'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)
{
        void *platform_timer;
        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;
        acpi_gtdt_desc.platform_timer = NULL;
        if (platform_timer_count)
                *platform_timer_count = 0;

        if (table->revision < 2) {
                pr_warn("Revision:%d doesn't support Platform Timers.\n",
                        table->revision);
                return 0;
        }

        if (!gtdt->platform_timer_count) {
                pr_debug("No Platform Timer.\n");
                return 0;
        }
        if (platform_timer_count)
                *platform_timer_count = gtdt->platform_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");
                return -EINVAL;
        }
        acpi_gtdt_desc.platform_timer = platform_timer;

        return 0;
}


>
> Lorenzo
>
>> +             }
>> +     }
>> +
>> +     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 9b05886..4b5c146 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -595,6 +595,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
>> --
>> 2.9.3
>>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
  2017-03-29 14:29       ` Fu Wei
  (?)
@ 2017-03-29 14:31         ` Fu Wei
  -1 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29 14:31 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei

On 29 March 2017 at 22:29, Fu Wei <fu.wei@linaro.org> wrote:
> Hi Lorenzo,
>
> On 28 March 2017 at 19:35, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
>> On Wed, Mar 22, 2017 at 12:31:18AM +0800, fu.wei@linaro.org wrote:
>>> From: Fu Wei <fu.wei@linaro.org>
>>>
>>> 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 <fu.wei@linaro.org>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>>
>> Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>>
>> Some nits below.
>>
>>> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
>>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>>  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(+)
>>>
>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>> index 3741859..7e2baec 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 <daniel.lezcano@linaro.org>
>>> + *         Fu Wei <fu.wei@linaro.org>
>>> + *         Hanjun Guo <hanjun.guo@linaro.org>
>>> + *
>>> + * 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 <linux/acpi.h>
>>> +#include <linux/init.h>
>>> +#include <linux/kernel.h>
>>> +
>>> +#include <clocksource/arm_arch_timer.h>
>>> +
>>> +#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.
>>
>> Note: Secure state is not managed by the kernel on ARM64 systems.
>>
>> Is that what you wanted to say ?
>>
>>> + * 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.
>>
>> Return: true if the timer HW state is lost when a CPU enters an idle
>>         state, false 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
>>
>> I do not understand what this means.
>>
>>> + *                           number of platform timers. It can be NULL, if
>>> + *                           driver don't need this info.
>>
>> driver doesn't
>>
>>> + *
>>> + * 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);
>>
>> Ok, two points here. First, I am not sure why you should warn if the
>> table revision is < 2, is that a FW bug ? I do not think it is, you
>> can just return 0.
>>
>>> +     else if (!gtdt->platform_timer_count)
>>> +             pr_debug("No Platform Timer.\n");
>>
>> Ditto. Why keep executing ? There is nothing to do, just bail out
>> with a return 0.
>>
>>> +     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;
>>
>> Same here, I suspect you want to consolidate the return path (I missed
>> previous rounds of reviews so you should not worry too much, I can clean
>> this up later) but to me a:
>>
>> return -EINVAL;
>>
>> would just do.
>
> For this problem, Can I do this:
>
> /**
>  * acpi_gtdt_init() - Get the info of GTDT table to prepare for further init.
>  * @table:                        The pointer to GTDT table.
>  * @platform_timer_count:        It points to a integer variable which is used
>  *                                for storing the number of platform timers.
>  *                                This pointer could be NULL, if the caller
>  *                                doesn'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)
> {
>         void *platform_timer;
>         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;
>         acpi_gtdt_desc.platform_timer = NULL;
>         if (platform_timer_count)
>                 *platform_timer_count = 0;
>
>         if (table->revision < 2) {
>                 pr_warn("Revision:%d doesn't support Platform Timers.\n",
>                         table->revision);
>                 return 0;
>         }
>
>         if (!gtdt->platform_timer_count) {
>                 pr_debug("No Platform Timer.\n");
>                 return 0;
>         }
>         if (platform_timer_count)
>                 *platform_timer_count = gtdt->platform_timer_count;

sorry , this should be moved,


>
>         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");
>                 return -EINVAL;
>         }
>         acpi_gtdt_desc.platform_timer = platform_timer;

         if (platform_timer_count)
                 *platform_timer_count = gtdt->platform_timer_count;

Here is the right place

>
>         return 0;
> }
>
>
>>
>> Lorenzo
>>
>>> +             }
>>> +     }
>>> +
>>> +     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 9b05886..4b5c146 100644
>>> --- a/include/linux/acpi.h
>>> +++ b/include/linux/acpi.h
>>> @@ -595,6 +595,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
>>> --
>>> 2.9.3
>>>
>
>
>
> --
> Best regards,
>
> Fu Wei
> Software Engineer
> Red Hat



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29 14:31         ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29 14:31 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

On 29 March 2017 at 22:29, Fu Wei <fu.wei@linaro.org> wrote:
> Hi Lorenzo,
>
> On 28 March 2017 at 19:35, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
>> On Wed, Mar 22, 2017 at 12:31:18AM +0800, fu.wei@linaro.org wrote:
>>> From: Fu Wei <fu.wei@linaro.org>
>>>
>>> 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 <fu.wei@linaro.org>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>>
>> Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>>
>> Some nits below.
>>
>>> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
>>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>>  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(+)
>>>
>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>> index 3741859..7e2baec 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 <daniel.lezcano@linaro.org>
>>> + *         Fu Wei <fu.wei@linaro.org>
>>> + *         Hanjun Guo <hanjun.guo@linaro.org>
>>> + *
>>> + * 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 <linux/acpi.h>
>>> +#include <linux/init.h>
>>> +#include <linux/kernel.h>
>>> +
>>> +#include <clocksource/arm_arch_timer.h>
>>> +
>>> +#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.
>>
>> Note: Secure state is not managed by the kernel on ARM64 systems.
>>
>> Is that what you wanted to say ?
>>
>>> + * 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.
>>
>> Return: true if the timer HW state is lost when a CPU enters an idle
>>         state, false 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
>>
>> I do not understand what this means.
>>
>>> + *                           number of platform timers. It can be NULL, if
>>> + *                           driver don't need this info.
>>
>> driver doesn't
>>
>>> + *
>>> + * 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);
>>
>> Ok, two points here. First, I am not sure why you should warn if the
>> table revision is < 2, is that a FW bug ? I do not think it is, you
>> can just return 0.
>>
>>> +     else if (!gtdt->platform_timer_count)
>>> +             pr_debug("No Platform Timer.\n");
>>
>> Ditto. Why keep executing ? There is nothing to do, just bail out
>> with a return 0.
>>
>>> +     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;
>>
>> Same here, I suspect you want to consolidate the return path (I missed
>> previous rounds of reviews so you should not worry too much, I can clean
>> this up later) but to me a:
>>
>> return -EINVAL;
>>
>> would just do.
>
> For this problem, Can I do this:
>
> /**
>  * acpi_gtdt_init() - Get the info of GTDT table to prepare for further init.
>  * @table:                        The pointer to GTDT table.
>  * @platform_timer_count:        It points to a integer variable which is used
>  *                                for storing the number of platform timers.
>  *                                This pointer could be NULL, if the caller
>  *                                doesn'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)
> {
>         void *platform_timer;
>         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;
>         acpi_gtdt_desc.platform_timer = NULL;
>         if (platform_timer_count)
>                 *platform_timer_count = 0;
>
>         if (table->revision < 2) {
>                 pr_warn("Revision:%d doesn't support Platform Timers.\n",
>                         table->revision);
>                 return 0;
>         }
>
>         if (!gtdt->platform_timer_count) {
>                 pr_debug("No Platform Timer.\n");
>                 return 0;
>         }
>         if (platform_timer_count)
>                 *platform_timer_count = gtdt->platform_timer_count;

sorry , this should be moved,


>
>         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");
>                 return -EINVAL;
>         }
>         acpi_gtdt_desc.platform_timer = platform_timer;

         if (platform_timer_count)
                 *platform_timer_count = gtdt->platform_timer_count;

Here is the right place

>
>         return 0;
> }
>
>
>>
>> Lorenzo
>>
>>> +             }
>>> +     }
>>> +
>>> +     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 9b05886..4b5c146 100644
>>> --- a/include/linux/acpi.h
>>> +++ b/include/linux/acpi.h
>>> @@ -595,6 +595,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
>>> --
>>> 2.9.3
>>>
>
>
>
> --
> Best regards,
>
> Fu Wei
> Software Engineer
> Red Hat



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29 14:31         ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29 14:31 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 March 2017 at 22:29, Fu Wei <fu.wei@linaro.org> wrote:
> Hi Lorenzo,
>
> On 28 March 2017 at 19:35, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
>> On Wed, Mar 22, 2017 at 12:31:18AM +0800, fu.wei at linaro.org wrote:
>>> From: Fu Wei <fu.wei@linaro.org>
>>>
>>> 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 <fu.wei@linaro.org>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>>
>> Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>>
>> Some nits below.
>>
>>> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
>>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>>  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(+)
>>>
>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>> index 3741859..7e2baec 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 <daniel.lezcano@linaro.org>
>>> + *         Fu Wei <fu.wei@linaro.org>
>>> + *         Hanjun Guo <hanjun.guo@linaro.org>
>>> + *
>>> + * 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 <linux/acpi.h>
>>> +#include <linux/init.h>
>>> +#include <linux/kernel.h>
>>> +
>>> +#include <clocksource/arm_arch_timer.h>
>>> +
>>> +#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.
>>
>> Note: Secure state is not managed by the kernel on ARM64 systems.
>>
>> Is that what you wanted to say ?
>>
>>> + * 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.
>>
>> Return: true if the timer HW state is lost when a CPU enters an idle
>>         state, false 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
>>
>> I do not understand what this means.
>>
>>> + *                           number of platform timers. It can be NULL, if
>>> + *                           driver don't need this info.
>>
>> driver doesn't
>>
>>> + *
>>> + * 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);
>>
>> Ok, two points here. First, I am not sure why you should warn if the
>> table revision is < 2, is that a FW bug ? I do not think it is, you
>> can just return 0.
>>
>>> +     else if (!gtdt->platform_timer_count)
>>> +             pr_debug("No Platform Timer.\n");
>>
>> Ditto. Why keep executing ? There is nothing to do, just bail out
>> with a return 0.
>>
>>> +     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;
>>
>> Same here, I suspect you want to consolidate the return path (I missed
>> previous rounds of reviews so you should not worry too much, I can clean
>> this up later) but to me a:
>>
>> return -EINVAL;
>>
>> would just do.
>
> For this problem, Can I do this:
>
> /**
>  * acpi_gtdt_init() - Get the info of GTDT table to prepare for further init.
>  * @table:                        The pointer to GTDT table.
>  * @platform_timer_count:        It points to a integer variable which is used
>  *                                for storing the number of platform timers.
>  *                                This pointer could be NULL, if the caller
>  *                                doesn'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)
> {
>         void *platform_timer;
>         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;
>         acpi_gtdt_desc.platform_timer = NULL;
>         if (platform_timer_count)
>                 *platform_timer_count = 0;
>
>         if (table->revision < 2) {
>                 pr_warn("Revision:%d doesn't support Platform Timers.\n",
>                         table->revision);
>                 return 0;
>         }
>
>         if (!gtdt->platform_timer_count) {
>                 pr_debug("No Platform Timer.\n");
>                 return 0;
>         }
>         if (platform_timer_count)
>                 *platform_timer_count = gtdt->platform_timer_count;

sorry , this should be moved,


>
>         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");
>                 return -EINVAL;
>         }
>         acpi_gtdt_desc.platform_timer = platform_timer;

         if (platform_timer_count)
                 *platform_timer_count = gtdt->platform_timer_count;

Here is the right place

>
>         return 0;
> }
>
>
>>
>> Lorenzo
>>
>>> +             }
>>> +     }
>>> +
>>> +     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 9b05886..4b5c146 100644
>>> --- a/include/linux/acpi.h
>>> +++ b/include/linux/acpi.h
>>> @@ -595,6 +595,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
>>> --
>>> 2.9.3
>>>
>
>
>
> --
> Best regards,
>
> Fu Wei
> Software Engineer
> Red Hat



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
  2017-03-29  5:11         ` Fu Wei
  (?)
@ 2017-03-29 14:41             ` Daniel Lezcano
  -1 siblings, 0 replies; 113+ messages in thread
From: Daniel Lezcano @ 2017-03-29 14:41 UTC (permalink / raw)
  To: Fu Wei
  Cc: Rafael J. Wysocki, Len Brown, Thomas Gleixner, Marc Zyngier,
	Mark Rutland, Lorenzo Pieralisi, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Linaro ACPI Mailman List, Linux Kernel Mailing List,
	ACPI Devel Maling List, rruigrok-sgV2jX0FEOL9JmXXK+q4OQ,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei

On Wed, Mar 29, 2017 at 01:11:58PM +0800, Fu Wei wrote:
> Hi Daniel,
> 
> On 29 March 2017 at 11:41, Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> > Hi Daniel,
> >
> > Great thanks for your review, allow me to answer your question below:
> >
> > On 28 March 2017 at 22:58, Daniel Lezcano <daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> >> On Wed, Mar 22, 2017 at 12:31:13AM +0800, fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org wrote:
> >>> From: Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> >>>
> >>> Currently, the counter frequency detection call(arch_timer_detect_rate)
> >>> includes getting the frequency from the device-tree property, the per-cpu
> >>> arch-timer and the memory-mapped (MMIO) timer interfaces.
> >>> But reading device-tree property will be needed only when system boot with
> >>> device-tree, and reading from the per-cpu arch-timer and the memory-mapped
> >>> (MMIO) timer interfaces will be needed only when the system initializes
> >>> the relevant timer.
> >>>
> >>> This patch separates out device-tree code, keep them in device-tree init
> >>> function, and removes arch_timer_detect_rate founction, then uses the
> >>> arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.
> >>>
> >>> Signed-off-by: Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> >>> ---
> >>>  drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
> >>>  1 file changed, 30 insertions(+), 28 deletions(-)
> >>>
> >>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> >>> index 843f923..29ca7d6 100644
> >>> --- a/drivers/clocksource/arm_arch_timer.c
> >>> +++ b/drivers/clocksource/arm_arch_timer.c
> >>> @@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
> >>>       return readl_relaxed(cntbase + CNTFRQ);
> >>>  }
> >>>
> >>> -static void
> >>> -arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
> >>> -{
> >>> -     /* Who has more than one independent system counter? */
> >>> -     if (arch_timer_rate)
> >>> -             return;
> >>> -
> >>> -     /*
> >>> -      * Try to determine the frequency from the device tree or CNTFRQ,
> >>> -      * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
> >>> -      */
> >>> -     if (!acpi_disabled ||
> >>> -         of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
> >>> -             if (cntbase)
> >>> -                     arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
> >>> -             else
> >>> -                     arch_timer_rate = arch_timer_get_cntfrq();
> >>> -     }
> >>> -
> >>> -     /* 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",
> >>> @@ -958,7 +934,17 @@ 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_detect_rate(NULL, np);
> >>> +     /*
> >>> +      * Try to determine the frequency from the device tree,
> >>> +      * if fail, get the frequency from the sysreg CNTFRQ.
> >>> +      */
> >>> +     if (!arch_timer_rate &&
> >>
> >> This variable is set only if "arm,armv7-timer" and "arm,armv7-timer-mem" are
> >> declared together in the DT, right ?
> >>
> >> Two declarations for a single variable ? Ignore the !arch_timer_rate.
> >
> > In this function, we try to initialize per-CPU arm arch_timer by DT.
> > this "!arch_timer_rate" is for testing that if we have got system
> > counter frequency from the memory-mapped timer. If so, we just skip
> > getting the frequency from DT or sysreg cntfrq again.
> > This variable is set only if "arm,armv7-timer-mem" is initialized
> > earlier than "arm,armv7-timer", in another word, maybe the node of
> > "arm,armv7-timer-mem" is declared earlier than  "arm,armv7-timer-mem"
> > one in DT.
> >
> > we do this check is for keeping the same init logic as before in the
> > DT, try to avoid any possibility of  breaking devices which boot by
> > DT.
> >
> >>
> >>> +         of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
> >>> +             arch_timer_rate = arch_timer_get_cntfrq();
> >>> +     if (!arch_timer_rate) {
> >>> +             pr_err(FW_BUG "frequency not available.\n");
> >>> +             return -EINVAL;
> >>> +     }
> >>
> >> Please, clarify this block, the conditions are unclear.
> >
> > this "!arch_timer_rate" is for verifying that if the system counter
> > frequency we just got from DT or sysreg cntfrq is valid(non-zero).
> >
> > So here, you can see I check arch_timer_rate twice, but they are for
> > different cases.
> 
> I think about this several times,
> For this block, it is a little unclear, so I think this will be better:
> 
> + /*
> + * Try to determine the frequency:
> + * If we have got it in arch_timer_mem_of_init, we don't need to get
> it again, skip.
> + * Otherwise, try to get the frequency from the device tree,
> + * if fail, try to get it from the sysreg CNTFRQ.
> + * Last, verify the arch_timer_rate before leaving this block.
> + */
> + if (!arch_timer_rate) {
> +         if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
> +                 arch_timer_rate = arch_timer_get_cntfrq();
> +         if (!arch_timer_rate) {
> +                 pr_err(FW_BUG "frequency not available.\n");
> +                 return -EINVAL;
> +         }
> + }

Hi Fu Wei,

in my previous comment, I was suggesting to remove the first arch_timer_rate
check.

The code assumes something else initialized this variable. There is clearly a
conflict in the variable assignment. So if a node is defined twice for this
variable, then it is more sane to consider the second pass overwrites the first
one. As the DT are specifying the same rate, for -mem and !-mem, then it should
have not an impact (to be verified).
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
@ 2017-03-29 14:41             ` Daniel Lezcano
  0 siblings, 0 replies; 113+ messages in thread
From: Daniel Lezcano @ 2017-03-29 14:41 UTC (permalink / raw)
  To: Fu Wei
  Cc: Rafael J. Wysocki, Len Brown, Thomas Gleixner, Marc Zyngier,
	Mark Rutland, Lorenzo Pieralisi, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

On Wed, Mar 29, 2017 at 01:11:58PM +0800, Fu Wei wrote:
> Hi Daniel,
> 
> On 29 March 2017 at 11:41, Fu Wei <fu.wei@linaro.org> wrote:
> > Hi Daniel,
> >
> > Great thanks for your review, allow me to answer your question below:
> >
> > On 28 March 2017 at 22:58, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
> >> On Wed, Mar 22, 2017 at 12:31:13AM +0800, fu.wei@linaro.org wrote:
> >>> From: Fu Wei <fu.wei@linaro.org>
> >>>
> >>> Currently, the counter frequency detection call(arch_timer_detect_rate)
> >>> includes getting the frequency from the device-tree property, the per-cpu
> >>> arch-timer and the memory-mapped (MMIO) timer interfaces.
> >>> But reading device-tree property will be needed only when system boot with
> >>> device-tree, and reading from the per-cpu arch-timer and the memory-mapped
> >>> (MMIO) timer interfaces will be needed only when the system initializes
> >>> the relevant timer.
> >>>
> >>> This patch separates out device-tree code, keep them in device-tree init
> >>> function, and removes arch_timer_detect_rate founction, then uses the
> >>> arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.
> >>>
> >>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
> >>> ---
> >>>  drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
> >>>  1 file changed, 30 insertions(+), 28 deletions(-)
> >>>
> >>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> >>> index 843f923..29ca7d6 100644
> >>> --- a/drivers/clocksource/arm_arch_timer.c
> >>> +++ b/drivers/clocksource/arm_arch_timer.c
> >>> @@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
> >>>       return readl_relaxed(cntbase + CNTFRQ);
> >>>  }
> >>>
> >>> -static void
> >>> -arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
> >>> -{
> >>> -     /* Who has more than one independent system counter? */
> >>> -     if (arch_timer_rate)
> >>> -             return;
> >>> -
> >>> -     /*
> >>> -      * Try to determine the frequency from the device tree or CNTFRQ,
> >>> -      * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
> >>> -      */
> >>> -     if (!acpi_disabled ||
> >>> -         of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
> >>> -             if (cntbase)
> >>> -                     arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
> >>> -             else
> >>> -                     arch_timer_rate = arch_timer_get_cntfrq();
> >>> -     }
> >>> -
> >>> -     /* 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",
> >>> @@ -958,7 +934,17 @@ 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_detect_rate(NULL, np);
> >>> +     /*
> >>> +      * Try to determine the frequency from the device tree,
> >>> +      * if fail, get the frequency from the sysreg CNTFRQ.
> >>> +      */
> >>> +     if (!arch_timer_rate &&
> >>
> >> This variable is set only if "arm,armv7-timer" and "arm,armv7-timer-mem" are
> >> declared together in the DT, right ?
> >>
> >> Two declarations for a single variable ? Ignore the !arch_timer_rate.
> >
> > In this function, we try to initialize per-CPU arm arch_timer by DT.
> > this "!arch_timer_rate" is for testing that if we have got system
> > counter frequency from the memory-mapped timer. If so, we just skip
> > getting the frequency from DT or sysreg cntfrq again.
> > This variable is set only if "arm,armv7-timer-mem" is initialized
> > earlier than "arm,armv7-timer", in another word, maybe the node of
> > "arm,armv7-timer-mem" is declared earlier than  "arm,armv7-timer-mem"
> > one in DT.
> >
> > we do this check is for keeping the same init logic as before in the
> > DT, try to avoid any possibility of  breaking devices which boot by
> > DT.
> >
> >>
> >>> +         of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
> >>> +             arch_timer_rate = arch_timer_get_cntfrq();
> >>> +     if (!arch_timer_rate) {
> >>> +             pr_err(FW_BUG "frequency not available.\n");
> >>> +             return -EINVAL;
> >>> +     }
> >>
> >> Please, clarify this block, the conditions are unclear.
> >
> > this "!arch_timer_rate" is for verifying that if the system counter
> > frequency we just got from DT or sysreg cntfrq is valid(non-zero).
> >
> > So here, you can see I check arch_timer_rate twice, but they are for
> > different cases.
> 
> I think about this several times,
> For this block, it is a little unclear, so I think this will be better:
> 
> + /*
> + * Try to determine the frequency:
> + * If we have got it in arch_timer_mem_of_init, we don't need to get
> it again, skip.
> + * Otherwise, try to get the frequency from the device tree,
> + * if fail, try to get it from the sysreg CNTFRQ.
> + * Last, verify the arch_timer_rate before leaving this block.
> + */
> + if (!arch_timer_rate) {
> +         if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
> +                 arch_timer_rate = arch_timer_get_cntfrq();
> +         if (!arch_timer_rate) {
> +                 pr_err(FW_BUG "frequency not available.\n");
> +                 return -EINVAL;
> +         }
> + }

Hi Fu Wei,

in my previous comment, I was suggesting to remove the first arch_timer_rate
check.

The code assumes something else initialized this variable. There is clearly a
conflict in the variable assignment. So if a node is defined twice for this
variable, then it is more sane to consider the second pass overwrites the first
one. As the DT are specifying the same rate, for -mem and !-mem, then it should
have not an impact (to be verified).

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
@ 2017-03-29 14:41             ` Daniel Lezcano
  0 siblings, 0 replies; 113+ messages in thread
From: Daniel Lezcano @ 2017-03-29 14:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 29, 2017 at 01:11:58PM +0800, Fu Wei wrote:
> Hi Daniel,
> 
> On 29 March 2017 at 11:41, Fu Wei <fu.wei@linaro.org> wrote:
> > Hi Daniel,
> >
> > Great thanks for your review, allow me to answer your question below:
> >
> > On 28 March 2017 at 22:58, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
> >> On Wed, Mar 22, 2017 at 12:31:13AM +0800, fu.wei at linaro.org wrote:
> >>> From: Fu Wei <fu.wei@linaro.org>
> >>>
> >>> Currently, the counter frequency detection call(arch_timer_detect_rate)
> >>> includes getting the frequency from the device-tree property, the per-cpu
> >>> arch-timer and the memory-mapped (MMIO) timer interfaces.
> >>> But reading device-tree property will be needed only when system boot with
> >>> device-tree, and reading from the per-cpu arch-timer and the memory-mapped
> >>> (MMIO) timer interfaces will be needed only when the system initializes
> >>> the relevant timer.
> >>>
> >>> This patch separates out device-tree code, keep them in device-tree init
> >>> function, and removes arch_timer_detect_rate founction, then uses the
> >>> arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.
> >>>
> >>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
> >>> ---
> >>>  drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
> >>>  1 file changed, 30 insertions(+), 28 deletions(-)
> >>>
> >>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> >>> index 843f923..29ca7d6 100644
> >>> --- a/drivers/clocksource/arm_arch_timer.c
> >>> +++ b/drivers/clocksource/arm_arch_timer.c
> >>> @@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
> >>>       return readl_relaxed(cntbase + CNTFRQ);
> >>>  }
> >>>
> >>> -static void
> >>> -arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
> >>> -{
> >>> -     /* Who has more than one independent system counter? */
> >>> -     if (arch_timer_rate)
> >>> -             return;
> >>> -
> >>> -     /*
> >>> -      * Try to determine the frequency from the device tree or CNTFRQ,
> >>> -      * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
> >>> -      */
> >>> -     if (!acpi_disabled ||
> >>> -         of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
> >>> -             if (cntbase)
> >>> -                     arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
> >>> -             else
> >>> -                     arch_timer_rate = arch_timer_get_cntfrq();
> >>> -     }
> >>> -
> >>> -     /* 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",
> >>> @@ -958,7 +934,17 @@ 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_detect_rate(NULL, np);
> >>> +     /*
> >>> +      * Try to determine the frequency from the device tree,
> >>> +      * if fail, get the frequency from the sysreg CNTFRQ.
> >>> +      */
> >>> +     if (!arch_timer_rate &&
> >>
> >> This variable is set only if "arm,armv7-timer" and "arm,armv7-timer-mem" are
> >> declared together in the DT, right ?
> >>
> >> Two declarations for a single variable ? Ignore the !arch_timer_rate.
> >
> > In this function, we try to initialize per-CPU arm arch_timer by DT.
> > this "!arch_timer_rate" is for testing that if we have got system
> > counter frequency from the memory-mapped timer. If so, we just skip
> > getting the frequency from DT or sysreg cntfrq again.
> > This variable is set only if "arm,armv7-timer-mem" is initialized
> > earlier than "arm,armv7-timer", in another word, maybe the node of
> > "arm,armv7-timer-mem" is declared earlier than  "arm,armv7-timer-mem"
> > one in DT.
> >
> > we do this check is for keeping the same init logic as before in the
> > DT, try to avoid any possibility of  breaking devices which boot by
> > DT.
> >
> >>
> >>> +         of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
> >>> +             arch_timer_rate = arch_timer_get_cntfrq();
> >>> +     if (!arch_timer_rate) {
> >>> +             pr_err(FW_BUG "frequency not available.\n");
> >>> +             return -EINVAL;
> >>> +     }
> >>
> >> Please, clarify this block, the conditions are unclear.
> >
> > this "!arch_timer_rate" is for verifying that if the system counter
> > frequency we just got from DT or sysreg cntfrq is valid(non-zero).
> >
> > So here, you can see I check arch_timer_rate twice, but they are for
> > different cases.
> 
> I think about this several times,
> For this block, it is a little unclear, so I think this will be better:
> 
> + /*
> + * Try to determine the frequency:
> + * If we have got it in arch_timer_mem_of_init, we don't need to get
> it again, skip.
> + * Otherwise, try to get the frequency from the device tree,
> + * if fail, try to get it from the sysreg CNTFRQ.
> + * Last, verify the arch_timer_rate before leaving this block.
> + */
> + if (!arch_timer_rate) {
> +         if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
> +                 arch_timer_rate = arch_timer_get_cntfrq();
> +         if (!arch_timer_rate) {
> +                 pr_err(FW_BUG "frequency not available.\n");
> +                 return -EINVAL;
> +         }
> + }

Hi Fu Wei,

in my previous comment, I was suggesting to remove the first arch_timer_rate
check.

The code assumes something else initialized this variable. There is clearly a
conflict in the variable assignment. So if a node is defined twice for this
variable, then it is more sane to consider the second pass overwrites the first
one. As the DT are specifying the same rate, for -mem and !-mem, then it should
have not an impact (to be verified).

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
  2017-03-29 14:41             ` Daniel Lezcano
  (?)
@ 2017-03-29 15:01               ` Fu Wei
  -1 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29 15:01 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Rafael J. Wysocki, Len Brown, Thomas Gleixner, Marc Zyngier,
	Mark Rutland, Lorenzo Pieralisi, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei

On 29 March 2017 at 22:41, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
> On Wed, Mar 29, 2017 at 01:11:58PM +0800, Fu Wei wrote:
>> Hi Daniel,
>>
>> On 29 March 2017 at 11:41, Fu Wei <fu.wei@linaro.org> wrote:
>> > Hi Daniel,
>> >
>> > Great thanks for your review, allow me to answer your question below:
>> >
>> > On 28 March 2017 at 22:58, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
>> >> On Wed, Mar 22, 2017 at 12:31:13AM +0800, fu.wei@linaro.org wrote:
>> >>> From: Fu Wei <fu.wei@linaro.org>
>> >>>
>> >>> Currently, the counter frequency detection call(arch_timer_detect_rate)
>> >>> includes getting the frequency from the device-tree property, the per-cpu
>> >>> arch-timer and the memory-mapped (MMIO) timer interfaces.
>> >>> But reading device-tree property will be needed only when system boot with
>> >>> device-tree, and reading from the per-cpu arch-timer and the memory-mapped
>> >>> (MMIO) timer interfaces will be needed only when the system initializes
>> >>> the relevant timer.
>> >>>
>> >>> This patch separates out device-tree code, keep them in device-tree init
>> >>> function, and removes arch_timer_detect_rate founction, then uses the
>> >>> arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.
>> >>>
>> >>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>> >>> ---
>> >>>  drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
>> >>>  1 file changed, 30 insertions(+), 28 deletions(-)
>> >>>
>> >>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>> >>> index 843f923..29ca7d6 100644
>> >>> --- a/drivers/clocksource/arm_arch_timer.c
>> >>> +++ b/drivers/clocksource/arm_arch_timer.c
>> >>> @@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
>> >>>       return readl_relaxed(cntbase + CNTFRQ);
>> >>>  }
>> >>>
>> >>> -static void
>> >>> -arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
>> >>> -{
>> >>> -     /* Who has more than one independent system counter? */
>> >>> -     if (arch_timer_rate)
>> >>> -             return;
>> >>> -
>> >>> -     /*
>> >>> -      * Try to determine the frequency from the device tree or CNTFRQ,
>> >>> -      * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
>> >>> -      */
>> >>> -     if (!acpi_disabled ||
>> >>> -         of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
>> >>> -             if (cntbase)
>> >>> -                     arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
>> >>> -             else
>> >>> -                     arch_timer_rate = arch_timer_get_cntfrq();
>> >>> -     }
>> >>> -
>> >>> -     /* 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",
>> >>> @@ -958,7 +934,17 @@ 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_detect_rate(NULL, np);
>> >>> +     /*
>> >>> +      * Try to determine the frequency from the device tree,
>> >>> +      * if fail, get the frequency from the sysreg CNTFRQ.
>> >>> +      */
>> >>> +     if (!arch_timer_rate &&
>> >>
>> >> This variable is set only if "arm,armv7-timer" and "arm,armv7-timer-mem" are
>> >> declared together in the DT, right ?
>> >>
>> >> Two declarations for a single variable ? Ignore the !arch_timer_rate.
>> >
>> > In this function, we try to initialize per-CPU arm arch_timer by DT.
>> > this "!arch_timer_rate" is for testing that if we have got system
>> > counter frequency from the memory-mapped timer. If so, we just skip
>> > getting the frequency from DT or sysreg cntfrq again.
>> > This variable is set only if "arm,armv7-timer-mem" is initialized
>> > earlier than "arm,armv7-timer", in another word, maybe the node of
>> > "arm,armv7-timer-mem" is declared earlier than  "arm,armv7-timer-mem"
>> > one in DT.
>> >
>> > we do this check is for keeping the same init logic as before in the
>> > DT, try to avoid any possibility of  breaking devices which boot by
>> > DT.
>> >
>> >>
>> >>> +         of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
>> >>> +             arch_timer_rate = arch_timer_get_cntfrq();
>> >>> +     if (!arch_timer_rate) {
>> >>> +             pr_err(FW_BUG "frequency not available.\n");
>> >>> +             return -EINVAL;
>> >>> +     }
>> >>
>> >> Please, clarify this block, the conditions are unclear.
>> >
>> > this "!arch_timer_rate" is for verifying that if the system counter
>> > frequency we just got from DT or sysreg cntfrq is valid(non-zero).
>> >
>> > So here, you can see I check arch_timer_rate twice, but they are for
>> > different cases.
>>
>> I think about this several times,
>> For this block, it is a little unclear, so I think this will be better:
>>
>> + /*
>> + * Try to determine the frequency:
>> + * If we have got it in arch_timer_mem_of_init, we don't need to get
>> it again, skip.
>> + * Otherwise, try to get the frequency from the device tree,
>> + * if fail, try to get it from the sysreg CNTFRQ.
>> + * Last, verify the arch_timer_rate before leaving this block.
>> + */
>> + if (!arch_timer_rate) {
>> +         if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
>> +                 arch_timer_rate = arch_timer_get_cntfrq();
>> +         if (!arch_timer_rate) {
>> +                 pr_err(FW_BUG "frequency not available.\n");
>> +                 return -EINVAL;
>> +         }
>> + }
>
> Hi Fu Wei,
>
> in my previous comment, I was suggesting to remove the first arch_timer_rate
> check.
>
> The code assumes something else initialized this variable. There is clearly a
> conflict in the variable assignment. So if a node is defined twice for this
> variable, then it is more sane to consider the second pass overwrites the first
> one. As the DT are specifying the same rate, for -mem and !-mem, then it should
> have not an impact (to be verified).

So the code will be like this:

+ /*
+ * Try to determine the frequency:
+ * If we try to get the frequency from the device tree,
+ * if fail, try to get it from the sysreg CNTFRQ.
+ * Then verify the arch_timer_rate.
+ */
+ if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
+         arch_timer_rate = arch_timer_get_cntfrq();
+ if (!arch_timer_rate) {
+         pr_err(FW_BUG "frequency not available.\n");
+         return -EINVAL;
+ }

I am OK to delete the  first arch_timer_rate check,
If arch_timer_mem is initialized first,  we just overwrite the
existing rate to arch_timer rate.
This makes sense to me.

-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
@ 2017-03-29 15:01               ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29 15:01 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Rafael J. Wysocki, Len Brown, Thomas Gleixner, Marc Zyngier,
	Mark Rutland, Lorenzo Pieralisi, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

On 29 March 2017 at 22:41, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
> On Wed, Mar 29, 2017 at 01:11:58PM +0800, Fu Wei wrote:
>> Hi Daniel,
>>
>> On 29 March 2017 at 11:41, Fu Wei <fu.wei@linaro.org> wrote:
>> > Hi Daniel,
>> >
>> > Great thanks for your review, allow me to answer your question below:
>> >
>> > On 28 March 2017 at 22:58, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
>> >> On Wed, Mar 22, 2017 at 12:31:13AM +0800, fu.wei@linaro.org wrote:
>> >>> From: Fu Wei <fu.wei@linaro.org>
>> >>>
>> >>> Currently, the counter frequency detection call(arch_timer_detect_rate)
>> >>> includes getting the frequency from the device-tree property, the per-cpu
>> >>> arch-timer and the memory-mapped (MMIO) timer interfaces.
>> >>> But reading device-tree property will be needed only when system boot with
>> >>> device-tree, and reading from the per-cpu arch-timer and the memory-mapped
>> >>> (MMIO) timer interfaces will be needed only when the system initializes
>> >>> the relevant timer.
>> >>>
>> >>> This patch separates out device-tree code, keep them in device-tree init
>> >>> function, and removes arch_timer_detect_rate founction, then uses the
>> >>> arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.
>> >>>
>> >>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>> >>> ---
>> >>>  drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
>> >>>  1 file changed, 30 insertions(+), 28 deletions(-)
>> >>>
>> >>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>> >>> index 843f923..29ca7d6 100644
>> >>> --- a/drivers/clocksource/arm_arch_timer.c
>> >>> +++ b/drivers/clocksource/arm_arch_timer.c
>> >>> @@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
>> >>>       return readl_relaxed(cntbase + CNTFRQ);
>> >>>  }
>> >>>
>> >>> -static void
>> >>> -arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
>> >>> -{
>> >>> -     /* Who has more than one independent system counter? */
>> >>> -     if (arch_timer_rate)
>> >>> -             return;
>> >>> -
>> >>> -     /*
>> >>> -      * Try to determine the frequency from the device tree or CNTFRQ,
>> >>> -      * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
>> >>> -      */
>> >>> -     if (!acpi_disabled ||
>> >>> -         of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
>> >>> -             if (cntbase)
>> >>> -                     arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
>> >>> -             else
>> >>> -                     arch_timer_rate = arch_timer_get_cntfrq();
>> >>> -     }
>> >>> -
>> >>> -     /* 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",
>> >>> @@ -958,7 +934,17 @@ 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_detect_rate(NULL, np);
>> >>> +     /*
>> >>> +      * Try to determine the frequency from the device tree,
>> >>> +      * if fail, get the frequency from the sysreg CNTFRQ.
>> >>> +      */
>> >>> +     if (!arch_timer_rate &&
>> >>
>> >> This variable is set only if "arm,armv7-timer" and "arm,armv7-timer-mem" are
>> >> declared together in the DT, right ?
>> >>
>> >> Two declarations for a single variable ? Ignore the !arch_timer_rate.
>> >
>> > In this function, we try to initialize per-CPU arm arch_timer by DT.
>> > this "!arch_timer_rate" is for testing that if we have got system
>> > counter frequency from the memory-mapped timer. If so, we just skip
>> > getting the frequency from DT or sysreg cntfrq again.
>> > This variable is set only if "arm,armv7-timer-mem" is initialized
>> > earlier than "arm,armv7-timer", in another word, maybe the node of
>> > "arm,armv7-timer-mem" is declared earlier than  "arm,armv7-timer-mem"
>> > one in DT.
>> >
>> > we do this check is for keeping the same init logic as before in the
>> > DT, try to avoid any possibility of  breaking devices which boot by
>> > DT.
>> >
>> >>
>> >>> +         of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
>> >>> +             arch_timer_rate = arch_timer_get_cntfrq();
>> >>> +     if (!arch_timer_rate) {
>> >>> +             pr_err(FW_BUG "frequency not available.\n");
>> >>> +             return -EINVAL;
>> >>> +     }
>> >>
>> >> Please, clarify this block, the conditions are unclear.
>> >
>> > this "!arch_timer_rate" is for verifying that if the system counter
>> > frequency we just got from DT or sysreg cntfrq is valid(non-zero).
>> >
>> > So here, you can see I check arch_timer_rate twice, but they are for
>> > different cases.
>>
>> I think about this several times,
>> For this block, it is a little unclear, so I think this will be better:
>>
>> + /*
>> + * Try to determine the frequency:
>> + * If we have got it in arch_timer_mem_of_init, we don't need to get
>> it again, skip.
>> + * Otherwise, try to get the frequency from the device tree,
>> + * if fail, try to get it from the sysreg CNTFRQ.
>> + * Last, verify the arch_timer_rate before leaving this block.
>> + */
>> + if (!arch_timer_rate) {
>> +         if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
>> +                 arch_timer_rate = arch_timer_get_cntfrq();
>> +         if (!arch_timer_rate) {
>> +                 pr_err(FW_BUG "frequency not available.\n");
>> +                 return -EINVAL;
>> +         }
>> + }
>
> Hi Fu Wei,
>
> in my previous comment, I was suggesting to remove the first arch_timer_rate
> check.
>
> The code assumes something else initialized this variable. There is clearly a
> conflict in the variable assignment. So if a node is defined twice for this
> variable, then it is more sane to consider the second pass overwrites the first
> one. As the DT are specifying the same rate, for -mem and !-mem, then it should
> have not an impact (to be verified).

So the code will be like this:

+ /*
+ * Try to determine the frequency:
+ * If we try to get the frequency from the device tree,
+ * if fail, try to get it from the sysreg CNTFRQ.
+ * Then verify the arch_timer_rate.
+ */
+ if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
+         arch_timer_rate = arch_timer_get_cntfrq();
+ if (!arch_timer_rate) {
+         pr_err(FW_BUG "frequency not available.\n");
+         return -EINVAL;
+ }

I am OK to delete the  first arch_timer_rate check,
If arch_timer_mem is initialized first,  we just overwrite the
existing rate to arch_timer rate.
This makes sense to me.

-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate
@ 2017-03-29 15:01               ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-29 15:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 March 2017 at 22:41, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
> On Wed, Mar 29, 2017 at 01:11:58PM +0800, Fu Wei wrote:
>> Hi Daniel,
>>
>> On 29 March 2017 at 11:41, Fu Wei <fu.wei@linaro.org> wrote:
>> > Hi Daniel,
>> >
>> > Great thanks for your review, allow me to answer your question below:
>> >
>> > On 28 March 2017 at 22:58, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
>> >> On Wed, Mar 22, 2017 at 12:31:13AM +0800, fu.wei at linaro.org wrote:
>> >>> From: Fu Wei <fu.wei@linaro.org>
>> >>>
>> >>> Currently, the counter frequency detection call(arch_timer_detect_rate)
>> >>> includes getting the frequency from the device-tree property, the per-cpu
>> >>> arch-timer and the memory-mapped (MMIO) timer interfaces.
>> >>> But reading device-tree property will be needed only when system boot with
>> >>> device-tree, and reading from the per-cpu arch-timer and the memory-mapped
>> >>> (MMIO) timer interfaces will be needed only when the system initializes
>> >>> the relevant timer.
>> >>>
>> >>> This patch separates out device-tree code, keep them in device-tree init
>> >>> function, and removes arch_timer_detect_rate founction, then uses the
>> >>> arch_timer_get_cntfrq and arch_timer_mem_get_cntfrq directly.
>> >>>
>> >>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>> >>> ---
>> >>>  drivers/clocksource/arm_arch_timer.c | 58 +++++++++++++++++++-----------------
>> >>>  1 file changed, 30 insertions(+), 28 deletions(-)
>> >>>
>> >>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>> >>> index 843f923..29ca7d6 100644
>> >>> --- a/drivers/clocksource/arm_arch_timer.c
>> >>> +++ b/drivers/clocksource/arm_arch_timer.c
>> >>> @@ -560,30 +560,6 @@ static u32 arch_timer_mem_get_cntfrq(void __iomem *cntbase)
>> >>>       return readl_relaxed(cntbase + CNTFRQ);
>> >>>  }
>> >>>
>> >>> -static void
>> >>> -arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
>> >>> -{
>> >>> -     /* Who has more than one independent system counter? */
>> >>> -     if (arch_timer_rate)
>> >>> -             return;
>> >>> -
>> >>> -     /*
>> >>> -      * Try to determine the frequency from the device tree or CNTFRQ,
>> >>> -      * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
>> >>> -      */
>> >>> -     if (!acpi_disabled ||
>> >>> -         of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
>> >>> -             if (cntbase)
>> >>> -                     arch_timer_rate = arch_timer_mem_get_cntfrq(cntbase);
>> >>> -             else
>> >>> -                     arch_timer_rate = arch_timer_get_cntfrq();
>> >>> -     }
>> >>> -
>> >>> -     /* 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",
>> >>> @@ -958,7 +934,17 @@ 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_detect_rate(NULL, np);
>> >>> +     /*
>> >>> +      * Try to determine the frequency from the device tree,
>> >>> +      * if fail, get the frequency from the sysreg CNTFRQ.
>> >>> +      */
>> >>> +     if (!arch_timer_rate &&
>> >>
>> >> This variable is set only if "arm,armv7-timer" and "arm,armv7-timer-mem" are
>> >> declared together in the DT, right ?
>> >>
>> >> Two declarations for a single variable ? Ignore the !arch_timer_rate.
>> >
>> > In this function, we try to initialize per-CPU arm arch_timer by DT.
>> > this "!arch_timer_rate" is for testing that if we have got system
>> > counter frequency from the memory-mapped timer. If so, we just skip
>> > getting the frequency from DT or sysreg cntfrq again.
>> > This variable is set only if "arm,armv7-timer-mem" is initialized
>> > earlier than "arm,armv7-timer", in another word, maybe the node of
>> > "arm,armv7-timer-mem" is declared earlier than  "arm,armv7-timer-mem"
>> > one in DT.
>> >
>> > we do this check is for keeping the same init logic as before in the
>> > DT, try to avoid any possibility of  breaking devices which boot by
>> > DT.
>> >
>> >>
>> >>> +         of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
>> >>> +             arch_timer_rate = arch_timer_get_cntfrq();
>> >>> +     if (!arch_timer_rate) {
>> >>> +             pr_err(FW_BUG "frequency not available.\n");
>> >>> +             return -EINVAL;
>> >>> +     }
>> >>
>> >> Please, clarify this block, the conditions are unclear.
>> >
>> > this "!arch_timer_rate" is for verifying that if the system counter
>> > frequency we just got from DT or sysreg cntfrq is valid(non-zero).
>> >
>> > So here, you can see I check arch_timer_rate twice, but they are for
>> > different cases.
>>
>> I think about this several times,
>> For this block, it is a little unclear, so I think this will be better:
>>
>> + /*
>> + * Try to determine the frequency:
>> + * If we have got it in arch_timer_mem_of_init, we don't need to get
>> it again, skip.
>> + * Otherwise, try to get the frequency from the device tree,
>> + * if fail, try to get it from the sysreg CNTFRQ.
>> + * Last, verify the arch_timer_rate before leaving this block.
>> + */
>> + if (!arch_timer_rate) {
>> +         if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
>> +                 arch_timer_rate = arch_timer_get_cntfrq();
>> +         if (!arch_timer_rate) {
>> +                 pr_err(FW_BUG "frequency not available.\n");
>> +                 return -EINVAL;
>> +         }
>> + }
>
> Hi Fu Wei,
>
> in my previous comment, I was suggesting to remove the first arch_timer_rate
> check.
>
> The code assumes something else initialized this variable. There is clearly a
> conflict in the variable assignment. So if a node is defined twice for this
> variable, then it is more sane to consider the second pass overwrites the first
> one. As the DT are specifying the same rate, for -mem and !-mem, then it should
> have not an impact (to be verified).

So the code will be like this:

+ /*
+ * Try to determine the frequency:
+ * If we try to get the frequency from the device tree,
+ * if fail, try to get it from the sysreg CNTFRQ.
+ * Then verify the arch_timer_rate.
+ */
+ if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
+         arch_timer_rate = arch_timer_get_cntfrq();
+ if (!arch_timer_rate) {
+         pr_err(FW_BUG "frequency not available.\n");
+         return -EINVAL;
+ }

I am OK to delete the  first arch_timer_rate check,
If arch_timer_mem is initialized first,  we just overwrite the
existing rate to arch_timer rate.
This makes sense to me.

-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
  2017-03-29 14:31         ` Fu Wei
  (?)
@ 2017-03-29 15:19           ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-29 15:19 UTC (permalink / raw)
  To: Fu Wei
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei

On Wed, Mar 29, 2017 at 10:31:42PM +0800, Fu Wei wrote:
> On 29 March 2017 at 22:29, Fu Wei <fu.wei@linaro.org> wrote:
> > Hi Lorenzo,
> >
> > On 28 March 2017 at 19:35, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> >> On Wed, Mar 22, 2017 at 12:31:18AM +0800, fu.wei@linaro.org wrote:
> >>> From: Fu Wei <fu.wei@linaro.org>
> >>>
> >>> 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 <fu.wei@linaro.org>
> >>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> >>> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >>
> >> Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >>
> >> Some nits below.
> >>
> >>> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
> >>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> >>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> >>> ---
> >>>  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(+)
> >>>
> >>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> >>> index 3741859..7e2baec 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 <daniel.lezcano@linaro.org>
> >>> + *         Fu Wei <fu.wei@linaro.org>
> >>> + *         Hanjun Guo <hanjun.guo@linaro.org>
> >>> + *
> >>> + * 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 <linux/acpi.h>
> >>> +#include <linux/init.h>
> >>> +#include <linux/kernel.h>
> >>> +
> >>> +#include <clocksource/arm_arch_timer.h>
> >>> +
> >>> +#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.
> >>
> >> Note: Secure state is not managed by the kernel on ARM64 systems.
> >>
> >> Is that what you wanted to say ?
> >>
> >>> + * 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.
> >>
> >> Return: true if the timer HW state is lost when a CPU enters an idle
> >>         state, false 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
> >>
> >> I do not understand what this means.
> >>
> >>> + *                           number of platform timers. It can be NULL, if
> >>> + *                           driver don't need this info.
> >>
> >> driver doesn't
> >>
> >>> + *
> >>> + * 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);
> >>
> >> Ok, two points here. First, I am not sure why you should warn if the
> >> table revision is < 2, is that a FW bug ? I do not think it is, you
> >> can just return 0.
> >>
> >>> +     else if (!gtdt->platform_timer_count)
> >>> +             pr_debug("No Platform Timer.\n");
> >>
> >> Ditto. Why keep executing ? There is nothing to do, just bail out
> >> with a return 0.
> >>
> >>> +     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;
> >>
> >> Same here, I suspect you want to consolidate the return path (I missed
> >> previous rounds of reviews so you should not worry too much, I can clean
> >> this up later) but to me a:
> >>
> >> return -EINVAL;
> >>
> >> would just do.
> >
> > For this problem, Can I do this:
> >
> > /**
> >  * acpi_gtdt_init() - Get the info of GTDT table to prepare for further init.
> >  * @table:                        The pointer to GTDT table.
> >  * @platform_timer_count:        It points to a integer variable which is used
> >  *                                for storing the number of platform timers.
> >  *                                This pointer could be NULL, if the caller
> >  *                                doesn'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)
> > {
> >         void *platform_timer;
> >         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;
> >         acpi_gtdt_desc.platform_timer = NULL;
> >         if (platform_timer_count)
> >                 *platform_timer_count = 0;
> >
> >         if (table->revision < 2) {
> >                 pr_warn("Revision:%d doesn't support Platform Timers.\n",
> >                         table->revision);
> >                 return 0;
> >         }
> >
> >         if (!gtdt->platform_timer_count) {
> >                 pr_debug("No Platform Timer.\n");
> >                 return 0;
> >         }
> >         if (platform_timer_count)
> >                 *platform_timer_count = gtdt->platform_timer_count;
> 
> sorry , this should be moved,
> 
> 
> >
> >         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");
> >                 return -EINVAL;
> >         }
> >         acpi_gtdt_desc.platform_timer = platform_timer;
> 
>          if (platform_timer_count)
>                  *platform_timer_count = gtdt->platform_timer_count;
> 
> Here is the right place

Ok, to avoid adding bugs to code that has been tested already keep
the current function version (as of v22) and send me a patch to clean
this up at -rc1.

Multiple calls to acpi_gtdt_init() were my main concern.

Thanks,
Lorenzo

> 
> >
> >         return 0;
> > }
> >
> >
> >>
> >> Lorenzo
> >>
> >>> +             }
> >>> +     }
> >>> +
> >>> +     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 9b05886..4b5c146 100644
> >>> --- a/include/linux/acpi.h
> >>> +++ b/include/linux/acpi.h
> >>> @@ -595,6 +595,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
> >>> --
> >>> 2.9.3
> >>>
> >
> >
> >
> > --
> > Best regards,
> >
> > Fu Wei
> > Software Engineer
> > Red Hat
> 
> 
> 
> -- 
> Best regards,
> 
> Fu Wei
> Software Engineer
> Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29 15:19           ` Lorenzo Pieralisi
  0 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-29 15:19 UTC (permalink / raw)
  To: Fu Wei
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

On Wed, Mar 29, 2017 at 10:31:42PM +0800, Fu Wei wrote:
> On 29 March 2017 at 22:29, Fu Wei <fu.wei@linaro.org> wrote:
> > Hi Lorenzo,
> >
> > On 28 March 2017 at 19:35, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> >> On Wed, Mar 22, 2017 at 12:31:18AM +0800, fu.wei@linaro.org wrote:
> >>> From: Fu Wei <fu.wei@linaro.org>
> >>>
> >>> 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 <fu.wei@linaro.org>
> >>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> >>> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >>
> >> Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >>
> >> Some nits below.
> >>
> >>> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
> >>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> >>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> >>> ---
> >>>  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(+)
> >>>
> >>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> >>> index 3741859..7e2baec 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 <daniel.lezcano@linaro.org>
> >>> + *         Fu Wei <fu.wei@linaro.org>
> >>> + *         Hanjun Guo <hanjun.guo@linaro.org>
> >>> + *
> >>> + * 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 <linux/acpi.h>
> >>> +#include <linux/init.h>
> >>> +#include <linux/kernel.h>
> >>> +
> >>> +#include <clocksource/arm_arch_timer.h>
> >>> +
> >>> +#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.
> >>
> >> Note: Secure state is not managed by the kernel on ARM64 systems.
> >>
> >> Is that what you wanted to say ?
> >>
> >>> + * 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.
> >>
> >> Return: true if the timer HW state is lost when a CPU enters an idle
> >>         state, false 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
> >>
> >> I do not understand what this means.
> >>
> >>> + *                           number of platform timers. It can be NULL, if
> >>> + *                           driver don't need this info.
> >>
> >> driver doesn't
> >>
> >>> + *
> >>> + * 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);
> >>
> >> Ok, two points here. First, I am not sure why you should warn if the
> >> table revision is < 2, is that a FW bug ? I do not think it is, you
> >> can just return 0.
> >>
> >>> +     else if (!gtdt->platform_timer_count)
> >>> +             pr_debug("No Platform Timer.\n");
> >>
> >> Ditto. Why keep executing ? There is nothing to do, just bail out
> >> with a return 0.
> >>
> >>> +     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;
> >>
> >> Same here, I suspect you want to consolidate the return path (I missed
> >> previous rounds of reviews so you should not worry too much, I can clean
> >> this up later) but to me a:
> >>
> >> return -EINVAL;
> >>
> >> would just do.
> >
> > For this problem, Can I do this:
> >
> > /**
> >  * acpi_gtdt_init() - Get the info of GTDT table to prepare for further init.
> >  * @table:                        The pointer to GTDT table.
> >  * @platform_timer_count:        It points to a integer variable which is used
> >  *                                for storing the number of platform timers.
> >  *                                This pointer could be NULL, if the caller
> >  *                                doesn'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)
> > {
> >         void *platform_timer;
> >         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;
> >         acpi_gtdt_desc.platform_timer = NULL;
> >         if (platform_timer_count)
> >                 *platform_timer_count = 0;
> >
> >         if (table->revision < 2) {
> >                 pr_warn("Revision:%d doesn't support Platform Timers.\n",
> >                         table->revision);
> >                 return 0;
> >         }
> >
> >         if (!gtdt->platform_timer_count) {
> >                 pr_debug("No Platform Timer.\n");
> >                 return 0;
> >         }
> >         if (platform_timer_count)
> >                 *platform_timer_count = gtdt->platform_timer_count;
> 
> sorry , this should be moved,
> 
> 
> >
> >         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");
> >                 return -EINVAL;
> >         }
> >         acpi_gtdt_desc.platform_timer = platform_timer;
> 
>          if (platform_timer_count)
>                  *platform_timer_count = gtdt->platform_timer_count;
> 
> Here is the right place

Ok, to avoid adding bugs to code that has been tested already keep
the current function version (as of v22) and send me a patch to clean
this up at -rc1.

Multiple calls to acpi_gtdt_init() were my main concern.

Thanks,
Lorenzo

> 
> >
> >         return 0;
> > }
> >
> >
> >>
> >> Lorenzo
> >>
> >>> +             }
> >>> +     }
> >>> +
> >>> +     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 9b05886..4b5c146 100644
> >>> --- a/include/linux/acpi.h
> >>> +++ b/include/linux/acpi.h
> >>> @@ -595,6 +595,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
> >>> --
> >>> 2.9.3
> >>>
> >
> >
> >
> > --
> > Best regards,
> >
> > Fu Wei
> > Software Engineer
> > Red Hat
> 
> 
> 
> -- 
> Best regards,
> 
> Fu Wei
> Software Engineer
> Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29 15:19           ` Lorenzo Pieralisi
  0 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-29 15:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 29, 2017 at 10:31:42PM +0800, Fu Wei wrote:
> On 29 March 2017 at 22:29, Fu Wei <fu.wei@linaro.org> wrote:
> > Hi Lorenzo,
> >
> > On 28 March 2017 at 19:35, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> >> On Wed, Mar 22, 2017 at 12:31:18AM +0800, fu.wei at linaro.org wrote:
> >>> From: Fu Wei <fu.wei@linaro.org>
> >>>
> >>> 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 <fu.wei@linaro.org>
> >>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> >>> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >>
> >> Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >>
> >> Some nits below.
> >>
> >>> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
> >>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> >>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> >>> ---
> >>>  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(+)
> >>>
> >>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> >>> index 3741859..7e2baec 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 <daniel.lezcano@linaro.org>
> >>> + *         Fu Wei <fu.wei@linaro.org>
> >>> + *         Hanjun Guo <hanjun.guo@linaro.org>
> >>> + *
> >>> + * 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 <linux/acpi.h>
> >>> +#include <linux/init.h>
> >>> +#include <linux/kernel.h>
> >>> +
> >>> +#include <clocksource/arm_arch_timer.h>
> >>> +
> >>> +#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.
> >>
> >> Note: Secure state is not managed by the kernel on ARM64 systems.
> >>
> >> Is that what you wanted to say ?
> >>
> >>> + * 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.
> >>
> >> Return: true if the timer HW state is lost when a CPU enters an idle
> >>         state, false 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
> >>
> >> I do not understand what this means.
> >>
> >>> + *                           number of platform timers. It can be NULL, if
> >>> + *                           driver don't need this info.
> >>
> >> driver doesn't
> >>
> >>> + *
> >>> + * 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);
> >>
> >> Ok, two points here. First, I am not sure why you should warn if the
> >> table revision is < 2, is that a FW bug ? I do not think it is, you
> >> can just return 0.
> >>
> >>> +     else if (!gtdt->platform_timer_count)
> >>> +             pr_debug("No Platform Timer.\n");
> >>
> >> Ditto. Why keep executing ? There is nothing to do, just bail out
> >> with a return 0.
> >>
> >>> +     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;
> >>
> >> Same here, I suspect you want to consolidate the return path (I missed
> >> previous rounds of reviews so you should not worry too much, I can clean
> >> this up later) but to me a:
> >>
> >> return -EINVAL;
> >>
> >> would just do.
> >
> > For this problem, Can I do this:
> >
> > /**
> >  * acpi_gtdt_init() - Get the info of GTDT table to prepare for further init.
> >  * @table:                        The pointer to GTDT table.
> >  * @platform_timer_count:        It points to a integer variable which is used
> >  *                                for storing the number of platform timers.
> >  *                                This pointer could be NULL, if the caller
> >  *                                doesn'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)
> > {
> >         void *platform_timer;
> >         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;
> >         acpi_gtdt_desc.platform_timer = NULL;
> >         if (platform_timer_count)
> >                 *platform_timer_count = 0;
> >
> >         if (table->revision < 2) {
> >                 pr_warn("Revision:%d doesn't support Platform Timers.\n",
> >                         table->revision);
> >                 return 0;
> >         }
> >
> >         if (!gtdt->platform_timer_count) {
> >                 pr_debug("No Platform Timer.\n");
> >                 return 0;
> >         }
> >         if (platform_timer_count)
> >                 *platform_timer_count = gtdt->platform_timer_count;
> 
> sorry , this should be moved,
> 
> 
> >
> >         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");
> >                 return -EINVAL;
> >         }
> >         acpi_gtdt_desc.platform_timer = platform_timer;
> 
>          if (platform_timer_count)
>                  *platform_timer_count = gtdt->platform_timer_count;
> 
> Here is the right place

Ok, to avoid adding bugs to code that has been tested already keep
the current function version (as of v22) and send me a patch to clean
this up at -rc1.

Multiple calls to acpi_gtdt_init() were my main concern.

Thanks,
Lorenzo

> 
> >
> >         return 0;
> > }
> >
> >
> >>
> >> Lorenzo
> >>
> >>> +             }
> >>> +     }
> >>> +
> >>> +     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 9b05886..4b5c146 100644
> >>> --- a/include/linux/acpi.h
> >>> +++ b/include/linux/acpi.h
> >>> @@ -595,6 +595,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
> >>> --
> >>> 2.9.3
> >>>
> >
> >
> >
> > --
> > Best regards,
> >
> > Fu Wei
> > Software Engineer
> > Red Hat
> 
> 
> 
> -- 
> Best regards,
> 
> Fu Wei
> Software Engineer
> Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 03/11] clocksource: arm_arch_timer: refactor arch_timer_needs_probing
  2017-03-28 15:02     ` Daniel Lezcano
@ 2017-03-29 15:24       ` Mark Rutland
  -1 siblings, 0 replies; 113+ messages in thread
From: Mark Rutland @ 2017-03-29 15:24 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: fu.wei, rjw, lenb, tglx, marc.zyngier, lorenzo.pieralisi,
	sudeep.holla, hanjun.guo, linux-arm-kernel, linaro-acpi,
	linux-kernel, linux-acpi, rruigrok, harba, cov, timur,
	graeme.gregory, al.stone, jcm, wei, arnd, catalin.marinas,
	will.deacon, Suravee.Suthikulpanit, leo.duran, wim, linux,
	linux-watchdog, tn, christoffer.dall, julien.grall

On Tue, Mar 28, 2017 at 05:02:20PM +0200, Daniel Lezcano wrote:
> On Wed, Mar 22, 2017 at 12:31:14AM +0800, fu.wei@linaro.org wrote:
> > From: Fu Wei <fu.wei@linaro.org>
> > 
> > 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.
> 
> Can the following patch help you to solve nicely the situation ?
> 
> https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1360007.html

This does not help.

The needs_probing logic is all there to bodge around a problem with
registering sched_clock, when you have two sources of the same
frequency, but one is otherwise better.

The sysreg clocksource has much lower latency than the MMIO clocksource,
so we always want to use that as the sched_clock if we have it.
Currently, the code ensures this by deferring registration of
sched_clock.

Ideally, we'd figure that out dynamically, or we'd have a rating
argument.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 03/11] clocksource: arm_arch_timer: refactor arch_timer_needs_probing
@ 2017-03-29 15:24       ` Mark Rutland
  0 siblings, 0 replies; 113+ messages in thread
From: Mark Rutland @ 2017-03-29 15:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 28, 2017 at 05:02:20PM +0200, Daniel Lezcano wrote:
> On Wed, Mar 22, 2017 at 12:31:14AM +0800, fu.wei at linaro.org wrote:
> > From: Fu Wei <fu.wei@linaro.org>
> > 
> > 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.
> 
> Can the following patch help you to solve nicely the situation ?
> 
> https://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1360007.html

This does not help.

The needs_probing logic is all there to bodge around a problem with
registering sched_clock, when you have two sources of the same
frequency, but one is otherwise better.

The sysreg clocksource has much lower latency than the MMIO clocksource,
so we always want to use that as the sched_clock if we have it.
Currently, the code ensures this by deferring registration of
sched_clock.

Ideally, we'd figure that out dynamically, or we'd have a rating
argument.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 03/11] clocksource: arm_arch_timer: refactor arch_timer_needs_probing
  2017-03-29 15:24       ` Mark Rutland
  (?)
@ 2017-03-29 15:32         ` Daniel Lezcano
  -1 siblings, 0 replies; 113+ messages in thread
From: Daniel Lezcano @ 2017-03-29 15:32 UTC (permalink / raw)
  To: Mark Rutland
  Cc: fu.wei, rjw, lenb, tglx, marc.zyngier, lorenzo.pieralisi,
	sudeep.holla, hanjun.guo, linux-arm-kernel, linaro-acpi,
	linux-kernel, linux-acpi, rruigrok, harba, cov, timur,
	graeme.gregory, al.stone, jcm, wei, arnd, catalin.marinas,
	will.deacon, Suravee.Suthikulpanit, leo.duran, wim, linux,
	linux-watchdog, tn, christoffer.dall, julien.grall

On Wed, Mar 29, 2017 at 04:24:08PM +0100, Mark Rutland wrote:
> On Tue, Mar 28, 2017 at 05:02:20PM +0200, Daniel Lezcano wrote:
> > On Wed, Mar 22, 2017 at 12:31:14AM +0800, fu.wei@linaro.org wrote:
> > > From: Fu Wei <fu.wei@linaro.org>
> > > 
> > > 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.
> > 
> > Can the following patch help you to solve nicely the situation ?
> > 
> > https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1360007.html
> 
> This does not help.
> 
> The needs_probing logic is all there to bodge around a problem with
> registering sched_clock, when you have two sources of the same
> frequency, but one is otherwise better.
> 
> The sysreg clocksource has much lower latency than the MMIO clocksource,
> so we always want to use that as the sched_clock if we have it.
> Currently, the code ensures this by deferring registration of
> sched_clock.
> 
> Ideally, we'd figure that out dynamically, or we'd have a rating
> argument.
> 

Ok, I see. Thanks.

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 03/11] clocksource: arm_arch_timer: refactor arch_timer_needs_probing
@ 2017-03-29 15:32         ` Daniel Lezcano
  0 siblings, 0 replies; 113+ messages in thread
From: Daniel Lezcano @ 2017-03-29 15:32 UTC (permalink / raw)
  To: Mark Rutland
  Cc: fu.wei, rjw, lenb, tglx, marc.zyngier, lorenzo.pieralisi,
	sudeep.holla, hanjun.guo, linux-arm-kernel, linaro-acpi,
	linux-kernel, linux-acpi, rruigrok, harba, cov, timur,
	graeme.gregory, al.stone, jcm, wei, arnd, catalin.marinas,
	will.deacon, Suravee.Suthikulpanit, leo.duran, wim, linux,
	linux-watchdog, tn, christoffer.dall, julien.grall

On Wed, Mar 29, 2017 at 04:24:08PM +0100, Mark Rutland wrote:
> On Tue, Mar 28, 2017 at 05:02:20PM +0200, Daniel Lezcano wrote:
> > On Wed, Mar 22, 2017 at 12:31:14AM +0800, fu.wei@linaro.org wrote:
> > > From: Fu Wei <fu.wei@linaro.org>
> > > 
> > > 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.
> > 
> > Can the following patch help you to solve nicely the situation ?
> > 
> > https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1360007.html
> 
> This does not help.
> 
> The needs_probing logic is all there to bodge around a problem with
> registering sched_clock, when you have two sources of the same
> frequency, but one is otherwise better.
> 
> The sysreg clocksource has much lower latency than the MMIO clocksource,
> so we always want to use that as the sched_clock if we have it.
> Currently, the code ensures this by deferring registration of
> sched_clock.
> 
> Ideally, we'd figure that out dynamically, or we'd have a rating
> argument.
> 

Ok, I see. Thanks.

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 03/11] clocksource: arm_arch_timer: refactor arch_timer_needs_probing
@ 2017-03-29 15:32         ` Daniel Lezcano
  0 siblings, 0 replies; 113+ messages in thread
From: Daniel Lezcano @ 2017-03-29 15:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 29, 2017 at 04:24:08PM +0100, Mark Rutland wrote:
> On Tue, Mar 28, 2017 at 05:02:20PM +0200, Daniel Lezcano wrote:
> > On Wed, Mar 22, 2017 at 12:31:14AM +0800, fu.wei at linaro.org wrote:
> > > From: Fu Wei <fu.wei@linaro.org>
> > > 
> > > 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.
> > 
> > Can the following patch help you to solve nicely the situation ?
> > 
> > https://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1360007.html
> 
> This does not help.
> 
> The needs_probing logic is all there to bodge around a problem with
> registering sched_clock, when you have two sources of the same
> frequency, but one is otherwise better.
> 
> The sysreg clocksource has much lower latency than the MMIO clocksource,
> so we always want to use that as the sched_clock if we have it.
> Currently, the code ensures this by deferring registration of
> sched_clock.
> 
> Ideally, we'd figure that out dynamically, or we'd have a rating
> argument.
> 

Ok, I see. Thanks.

-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
  2017-03-29 13:42               ` Fu Wei
  (?)
@ 2017-03-29 16:02                   ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-29 16:02 UTC (permalink / raw)
  To: Fu Wei
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Linaro ACPI Mailman List, Linux Kernel Mailing List,
	ACPI Devel Maling List, rruigrok-sgV2jX0FEOL9JmXXK+q4OQ,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei

On Wed, Mar 29, 2017 at 09:42:39PM +0800, Fu Wei wrote:

[...]

> >> For calling acpi_gtdt_init() twice:
> >> (1) 1st time: in early boot(bootmem), for init arch_timer and
> >> memory-mapped timer, we initialize the acpi_gtdt_desc.
> >> you can see that all the items in this struct are pointer.
> >> (2) 2nd time: when system switch from bootmem to slab, all the
> >> pointers in the acpi_gtdt_desc are invalid, so we have to
> >> re-initialize(re-map) them.
> >>
> >> I have tested it, if we don't re-initialize  the acpi_gtdt_desc,
> >> system will go wrong.
> >
> > Ok, that's what I feared. My complaint on patch 11 is that:
> >
> > 1) Stashing the GTDT pointer in acpi_gtdt_desc is not needed to
> >    parse SBSA watchdogs
> 
> The acpi_gtdt_desc is for sharing the info between acpi_gtdt_init and
> acpi_gtdt_c3stop, ;acpi_gtdt_map_ppi
> I re-use it in parsing SBSA watchdogs, because I try to re-use acpi_gtdt_init.
> 
> > 2) It is not clear at all from the code or the commit log _why_ you
> >    need to call acpi_gtdt_init() again (ie technically you don't need
> >    to call it - you grab a valid pointer to the table and parse the
> >    watchdogs in the _same_ function gtdt_sbsa_gwdt_init())
> 
> yes, we can avoid calling acpi_gtdt_init(), do the same thing in
> parsing SBSA watchdogs info.
> But if we will do the same thing(getting gtdt, platform_timer,
> timer_count), why not just re-using the same function?

Because that's not trivial to understand why it is needed,
it actually isn't :). Anyway, instead of painting the bikeshed
let's add the comment below and be done with this.

> So my suggestion is that:
> Could we re-use acpi_gtdt_init, and a comment at the head of SBSA
> watchdogs info parsing function to summarize this issue?
> The comment like this
> 
> Note: although the global variable acpi_gtdt_desc has been initialized
> by acpi_gtdt_init, when we initialized arch_timer. But when we call this
> function to get SBSA watchdogs info from GTDT, the system has switch
> from bootmem  to slab, so the pointers in acpi_gtdt_desc are dated, we
> need to  re-initialize(remap) them. So we call acpi_gtdt_init again here.
"Note: Even though the global variable acpi_gtdt_desc has been
initialized by acpi_gtdt_init() while initializing the arch timers, when
we call this function to get SBSA watchdogs info from GTDT, the pointers
stashed in it are stale (since they are early temporary mappings carried
out before acpi_permanent_mmap is set) and we need to
re-initialize them with permanent mapped pointer values to let the
GTDT parsing possible".

I still think that if we write the code by omitting acpi_gtdt_init()
call (which does things that are completely useless for SBSA watchdog)
it becomes simpler and much easier to understand, up to you, either you
do it or I will at -rc1 ;-)

Lorenzo

> 
> 
> Is that OK for you? :-)
> 
> >
> > I do not think there is much you can do to improve the arch timer gtdt
> > interface (and it is too late for that anyway) but in patch 11 it would
> > be ideal if you avoid calling acpi_gtdt_init() again, just parse GTDT
> > entries and initialize the corresponding watchdogs (ie pointers stashed
> > in acpi_gtdt_desc are stale anyway but that's __initdata so I can live
> > with that).
> >
> > You should add comments to summarize this issue so that it can be
> > easily understood by anyone maintaining this code, it is not crystal
> > clear by reading the code why you need to multiple acpi_gtdt_init()
> > calls and that's not a piffling detail.
> >
> > The ACPI patches are fine with me otherwise, I will complete the
> > review shortly.
> >
> > Thanks !
> > Lorenzo
> 
> 
> 
> -- 
> Best regards,
> 
> Fu Wei
> Software Engineer
> Red Hat
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29 16:02                   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-29 16:02 UTC (permalink / raw)
  To: Fu Wei
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

On Wed, Mar 29, 2017 at 09:42:39PM +0800, Fu Wei wrote:

[...]

> >> For calling acpi_gtdt_init() twice:
> >> (1) 1st time: in early boot(bootmem), for init arch_timer and
> >> memory-mapped timer, we initialize the acpi_gtdt_desc.
> >> you can see that all the items in this struct are pointer.
> >> (2) 2nd time: when system switch from bootmem to slab, all the
> >> pointers in the acpi_gtdt_desc are invalid, so we have to
> >> re-initialize(re-map) them.
> >>
> >> I have tested it, if we don't re-initialize  the acpi_gtdt_desc,
> >> system will go wrong.
> >
> > Ok, that's what I feared. My complaint on patch 11 is that:
> >
> > 1) Stashing the GTDT pointer in acpi_gtdt_desc is not needed to
> >    parse SBSA watchdogs
> 
> The acpi_gtdt_desc is for sharing the info between acpi_gtdt_init and
> acpi_gtdt_c3stop, ;acpi_gtdt_map_ppi
> I re-use it in parsing SBSA watchdogs, because I try to re-use acpi_gtdt_init.
> 
> > 2) It is not clear at all from the code or the commit log _why_ you
> >    need to call acpi_gtdt_init() again (ie technically you don't need
> >    to call it - you grab a valid pointer to the table and parse the
> >    watchdogs in the _same_ function gtdt_sbsa_gwdt_init())
> 
> yes, we can avoid calling acpi_gtdt_init(), do the same thing in
> parsing SBSA watchdogs info.
> But if we will do the same thing(getting gtdt, platform_timer,
> timer_count), why not just re-using the same function?

Because that's not trivial to understand why it is needed,
it actually isn't :). Anyway, instead of painting the bikeshed
let's add the comment below and be done with this.

> So my suggestion is that:
> Could we re-use acpi_gtdt_init, and a comment at the head of SBSA
> watchdogs info parsing function to summarize this issue?
> The comment like this
> 
> Note: although the global variable acpi_gtdt_desc has been initialized
> by acpi_gtdt_init, when we initialized arch_timer. But when we call this
> function to get SBSA watchdogs info from GTDT, the system has switch
> from bootmem  to slab, so the pointers in acpi_gtdt_desc are dated, we
> need to  re-initialize(remap) them. So we call acpi_gtdt_init again here.
"Note: Even though the global variable acpi_gtdt_desc has been
initialized by acpi_gtdt_init() while initializing the arch timers, when
we call this function to get SBSA watchdogs info from GTDT, the pointers
stashed in it are stale (since they are early temporary mappings carried
out before acpi_permanent_mmap is set) and we need to
re-initialize them with permanent mapped pointer values to let the
GTDT parsing possible".

I still think that if we write the code by omitting acpi_gtdt_init()
call (which does things that are completely useless for SBSA watchdog)
it becomes simpler and much easier to understand, up to you, either you
do it or I will at -rc1 ;-)

Lorenzo

> 
> 
> Is that OK for you? :-)
> 
> >
> > I do not think there is much you can do to improve the arch timer gtdt
> > interface (and it is too late for that anyway) but in patch 11 it would
> > be ideal if you avoid calling acpi_gtdt_init() again, just parse GTDT
> > entries and initialize the corresponding watchdogs (ie pointers stashed
> > in acpi_gtdt_desc are stale anyway but that's __initdata so I can live
> > with that).
> >
> > You should add comments to summarize this issue so that it can be
> > easily understood by anyone maintaining this code, it is not crystal
> > clear by reading the code why you need to multiple acpi_gtdt_init()
> > calls and that's not a piffling detail.
> >
> > The ACPI patches are fine with me otherwise, I will complete the
> > review shortly.
> >
> > Thanks !
> > Lorenzo
> 
> 
> 
> -- 
> Best regards,
> 
> Fu Wei
> Software Engineer
> Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver
@ 2017-03-29 16:02                   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-29 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 29, 2017 at 09:42:39PM +0800, Fu Wei wrote:

[...]

> >> For calling acpi_gtdt_init() twice:
> >> (1) 1st time: in early boot(bootmem), for init arch_timer and
> >> memory-mapped timer, we initialize the acpi_gtdt_desc.
> >> you can see that all the items in this struct are pointer.
> >> (2) 2nd time: when system switch from bootmem to slab, all the
> >> pointers in the acpi_gtdt_desc are invalid, so we have to
> >> re-initialize(re-map) them.
> >>
> >> I have tested it, if we don't re-initialize  the acpi_gtdt_desc,
> >> system will go wrong.
> >
> > Ok, that's what I feared. My complaint on patch 11 is that:
> >
> > 1) Stashing the GTDT pointer in acpi_gtdt_desc is not needed to
> >    parse SBSA watchdogs
> 
> The acpi_gtdt_desc is for sharing the info between acpi_gtdt_init and
> acpi_gtdt_c3stop, ;acpi_gtdt_map_ppi
> I re-use it in parsing SBSA watchdogs, because I try to re-use acpi_gtdt_init.
> 
> > 2) It is not clear at all from the code or the commit log _why_ you
> >    need to call acpi_gtdt_init() again (ie technically you don't need
> >    to call it - you grab a valid pointer to the table and parse the
> >    watchdogs in the _same_ function gtdt_sbsa_gwdt_init())
> 
> yes, we can avoid calling acpi_gtdt_init(), do the same thing in
> parsing SBSA watchdogs info.
> But if we will do the same thing(getting gtdt, platform_timer,
> timer_count), why not just re-using the same function?

Because that's not trivial to understand why it is needed,
it actually isn't :). Anyway, instead of painting the bikeshed
let's add the comment below and be done with this.

> So my suggestion is that:
> Could we re-use acpi_gtdt_init, and a comment at the head of SBSA
> watchdogs info parsing function to summarize this issue?
> The comment like this
> 
> Note: although the global variable acpi_gtdt_desc has been initialized
> by acpi_gtdt_init, when we initialized arch_timer. But when we call this
> function to get SBSA watchdogs info from GTDT, the system has switch
> from bootmem  to slab, so the pointers in acpi_gtdt_desc are dated, we
> need to  re-initialize(remap) them. So we call acpi_gtdt_init again here.
"Note: Even though the global variable acpi_gtdt_desc has been
initialized by acpi_gtdt_init() while initializing the arch timers, when
we call this function to get SBSA watchdogs info from GTDT, the pointers
stashed in it are stale (since they are early temporary mappings carried
out before acpi_permanent_mmap is set) and we need to
re-initialize them with permanent mapped pointer values to let the
GTDT parsing possible".

I still think that if we write the code by omitting acpi_gtdt_init()
call (which does things that are completely useless for SBSA watchdog)
it becomes simpler and much easier to understand, up to you, either you
do it or I will at -rc1 ;-)

Lorenzo

> 
> 
> Is that OK for you? :-)
> 
> >
> > I do not think there is much you can do to improve the arch timer gtdt
> > interface (and it is too late for that anyway) but in patch 11 it would
> > be ideal if you avoid calling acpi_gtdt_init() again, just parse GTDT
> > entries and initialize the corresponding watchdogs (ie pointers stashed
> > in acpi_gtdt_desc are stale anyway but that's __initdata so I can live
> > with that).
> >
> > You should add comments to summarize this issue so that it can be
> > easily understood by anyone maintaining this code, it is not crystal
> > clear by reading the code why you need to multiple acpi_gtdt_init()
> > calls and that's not a piffling detail.
> >
> > The ACPI patches are fine with me otherwise, I will complete the
> > review shortly.
> >
> > Thanks !
> > Lorenzo
> 
> 
> 
> -- 
> Best regards,
> 
> Fu Wei
> Software Engineer
> Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 09/11] acpi/arm64: Add memory-mapped timer support in GTDT driver
  2017-03-21 16:31   ` fu.wei at linaro.org
  (?)
@ 2017-03-29 16:47       ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-29 16:47 UTC (permalink / raw)
  To: fu.wei-QSEj5FYQhm4dnm+yROfE0A
  Cc: rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ, marc.zyngier-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, sudeep.holla-5wv7dgnIgG8,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linaro-acpi-cunTk1MwBs8s++Sfvej+rw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	rruigrok-sgV2jX0FEOL9JmXXK+q4OQ, harba-sgV2jX0FEOL9JmXXK+q4OQ,
	cov-sgV2jX0FEOL9JmXXK+q4OQ, timur-sgV2jX0FEOL9JmXXK+q4OQ,
	graeme.gregory-QSEj5FYQhm4dnm+yROfE0A,
	al.stone-QSEj5FYQhm4dnm+yROfE0A, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	wei-H+wXaHxf7aLQT0dZR+AlfA, arnd-r2nGTMty4D4,
	catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	Suravee.Suthikulpanit-5C7GfCeVMHo, leo.duran-5C7GfCeVMHo,
	wim-IQzOog9fTRqzQB+pC5nmwQ, linux-0h96xk9xTtrk1uMJSBkQmQ,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	christoffer.dall-QSEj5FYQhm4dnm+yROfE0A,
	julien.grall-5wv7dgnIgG8

On Wed, Mar 22, 2017 at 12:31:20AM +0800, fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org wrote:
> From: Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> 
> 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 <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Signed-off-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
>  drivers/acpi/arm64/gtdt.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/acpi.h      |   1 +
>  2 files changed, 131 insertions(+)
> 
> diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
> index 8a03b4b..f471873 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,111 @@ 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 *timer_mem)
> +{
> +	int i, j;
> +	struct acpi_gtdt_timer_entry *gtdt_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;
> +	}
> +
> +	timer_mem->cntctlbase = (phys_addr_t)block->block_address;
> +	/*
> +	 * The CNTCTLBase frame is 4KB (register offsets 0x000 - 0xFFC).
> +	 * See ARM DDI 0487A.k_iss10775, page I1-5129, Table I1-3
> +	 * "CNTCTLBase memory map".
> +	 */
> +	timer_mem->size = SZ_4K;
> +
> +	gtdt_frame = (void *)block + block->timer_offset;
> +	if (gtdt_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++, gtdt_frame++) {
> +		struct arch_timer_mem_frame *frame = &timer_mem->frame[j];
> +
> +		if (gtdt_frame->common_flags & ACPI_GTDT_GT_IS_SECURE_TIMER)
> +			continue;
> +
> +		if (!gtdt_frame->base_address || !gtdt_frame->timer_interrupt)
> +			return -EINVAL;
> +
> +		frame->phys_irq = map_gt_gsi(gtdt_frame->timer_interrupt,
> +					     gtdt_frame->timer_flags);
> +		if (frame->phys_irq <= 0) {
> +			pr_warn("failed to map physical timer irq in frame %d.\n",
> +				i);
> +			return -EINVAL;
> +		}
> +
> +		frame->virt_irq =
> +			map_gt_gsi(gtdt_frame->virtual_timer_interrupt,
> +				   gtdt_frame->virtual_timer_flags);
> +		if (frame->virt_irq <= 0) {
> +			pr_warn("failed to map virtual timer irq in frame %d.\n",
> +				i);
> +			acpi_unregister_gsi(gtdt_frame->timer_interrupt);
> +			return -EINVAL;
> +		}
> +
> +		frame->frame_nr = gtdt_frame->frame_number;
> +		frame->cntbase = gtdt_frame->base_address;
> +		/*
> +		 * The CNTBaseN frame is 4KB (register offsets 0x000 - 0xFFC).
> +		 * See ARM DDI 0487A.k_iss10775, page I1-5130, Table I1-4
> +		 * "CNTBaseN memory map".
> +		 */
> +		frame->size = SZ_4K;
> +		j++;
> +	}
> +	timer_mem->num_frames = j;
> +
> +	return 0;
> +}
> +
> +/**
> + * acpi_arch_timer_mem_init() - Get the info of all GT blocks in GTDT table.
> + * @timer_mem:	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.

Nit: this comment was wrong on all the patches I reviewed :) must be
some copy and paste.

> + *
> + * Return: 0 if success, -EINVAL/-ENODEV if error.
> + */
> +int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
> +				    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, timer_mem);
> +			if (ret)
> +				return ret;

Isn't there some unwinding to carry out here (eg GSI) ?

Otherwise it looks fine (minus Mark's request for using frame numbers
as indexes that you should change).

Lorenzo

> +			timer_mem++;
> +			(*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 4b5c146..3193724 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -599,6 +599,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 *timer_mem, int *timer_count);
>  #endif
>  
>  #else	/* !CONFIG_ACPI */
> -- 
> 2.9.3
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 09/11] acpi/arm64: Add memory-mapped timer support in GTDT driver
@ 2017-03-29 16:47       ` Lorenzo Pieralisi
  0 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-29 16:47 UTC (permalink / raw)
  To: fu.wei
  Cc: rjw, lenb, daniel.lezcano, tglx, marc.zyngier, mark.rutland,
	sudeep.holla, hanjun.guo, linux-arm-kernel, linaro-acpi,
	linux-kernel, linux-acpi, rruigrok, harba, cov, timur,
	graeme.gregory, al.stone, jcm, wei, arnd, catalin.marinas,
	will.deacon, Suravee.Suthikulpanit, leo.duran, wim, linux,
	linux-watchdog, tn, christoffer.dall, julien.grall

On Wed, Mar 22, 2017 at 12:31:20AM +0800, fu.wei@linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> 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 <fu.wei@linaro.org>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/acpi/arm64/gtdt.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/acpi.h      |   1 +
>  2 files changed, 131 insertions(+)
> 
> diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
> index 8a03b4b..f471873 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,111 @@ 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 *timer_mem)
> +{
> +	int i, j;
> +	struct acpi_gtdt_timer_entry *gtdt_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;
> +	}
> +
> +	timer_mem->cntctlbase = (phys_addr_t)block->block_address;
> +	/*
> +	 * The CNTCTLBase frame is 4KB (register offsets 0x000 - 0xFFC).
> +	 * See ARM DDI 0487A.k_iss10775, page I1-5129, Table I1-3
> +	 * "CNTCTLBase memory map".
> +	 */
> +	timer_mem->size = SZ_4K;
> +
> +	gtdt_frame = (void *)block + block->timer_offset;
> +	if (gtdt_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++, gtdt_frame++) {
> +		struct arch_timer_mem_frame *frame = &timer_mem->frame[j];
> +
> +		if (gtdt_frame->common_flags & ACPI_GTDT_GT_IS_SECURE_TIMER)
> +			continue;
> +
> +		if (!gtdt_frame->base_address || !gtdt_frame->timer_interrupt)
> +			return -EINVAL;
> +
> +		frame->phys_irq = map_gt_gsi(gtdt_frame->timer_interrupt,
> +					     gtdt_frame->timer_flags);
> +		if (frame->phys_irq <= 0) {
> +			pr_warn("failed to map physical timer irq in frame %d.\n",
> +				i);
> +			return -EINVAL;
> +		}
> +
> +		frame->virt_irq =
> +			map_gt_gsi(gtdt_frame->virtual_timer_interrupt,
> +				   gtdt_frame->virtual_timer_flags);
> +		if (frame->virt_irq <= 0) {
> +			pr_warn("failed to map virtual timer irq in frame %d.\n",
> +				i);
> +			acpi_unregister_gsi(gtdt_frame->timer_interrupt);
> +			return -EINVAL;
> +		}
> +
> +		frame->frame_nr = gtdt_frame->frame_number;
> +		frame->cntbase = gtdt_frame->base_address;
> +		/*
> +		 * The CNTBaseN frame is 4KB (register offsets 0x000 - 0xFFC).
> +		 * See ARM DDI 0487A.k_iss10775, page I1-5130, Table I1-4
> +		 * "CNTBaseN memory map".
> +		 */
> +		frame->size = SZ_4K;
> +		j++;
> +	}
> +	timer_mem->num_frames = j;
> +
> +	return 0;
> +}
> +
> +/**
> + * acpi_arch_timer_mem_init() - Get the info of all GT blocks in GTDT table.
> + * @timer_mem:	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.

Nit: this comment was wrong on all the patches I reviewed :) must be
some copy and paste.

> + *
> + * Return: 0 if success, -EINVAL/-ENODEV if error.
> + */
> +int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
> +				    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, timer_mem);
> +			if (ret)
> +				return ret;

Isn't there some unwinding to carry out here (eg GSI) ?

Otherwise it looks fine (minus Mark's request for using frame numbers
as indexes that you should change).

Lorenzo

> +			timer_mem++;
> +			(*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 4b5c146..3193724 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -599,6 +599,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 *timer_mem, int *timer_count);
>  #endif
>  
>  #else	/* !CONFIG_ACPI */
> -- 
> 2.9.3
> 

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 09/11] acpi/arm64: Add memory-mapped timer support in GTDT driver
@ 2017-03-29 16:47       ` Lorenzo Pieralisi
  0 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-29 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 22, 2017 at 12:31:20AM +0800, fu.wei at linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> 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 <fu.wei@linaro.org>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/acpi/arm64/gtdt.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/acpi.h      |   1 +
>  2 files changed, 131 insertions(+)
> 
> diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
> index 8a03b4b..f471873 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,111 @@ 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 *timer_mem)
> +{
> +	int i, j;
> +	struct acpi_gtdt_timer_entry *gtdt_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;
> +	}
> +
> +	timer_mem->cntctlbase = (phys_addr_t)block->block_address;
> +	/*
> +	 * The CNTCTLBase frame is 4KB (register offsets 0x000 - 0xFFC).
> +	 * See ARM DDI 0487A.k_iss10775, page I1-5129, Table I1-3
> +	 * "CNTCTLBase memory map".
> +	 */
> +	timer_mem->size = SZ_4K;
> +
> +	gtdt_frame = (void *)block + block->timer_offset;
> +	if (gtdt_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++, gtdt_frame++) {
> +		struct arch_timer_mem_frame *frame = &timer_mem->frame[j];
> +
> +		if (gtdt_frame->common_flags & ACPI_GTDT_GT_IS_SECURE_TIMER)
> +			continue;
> +
> +		if (!gtdt_frame->base_address || !gtdt_frame->timer_interrupt)
> +			return -EINVAL;
> +
> +		frame->phys_irq = map_gt_gsi(gtdt_frame->timer_interrupt,
> +					     gtdt_frame->timer_flags);
> +		if (frame->phys_irq <= 0) {
> +			pr_warn("failed to map physical timer irq in frame %d.\n",
> +				i);
> +			return -EINVAL;
> +		}
> +
> +		frame->virt_irq =
> +			map_gt_gsi(gtdt_frame->virtual_timer_interrupt,
> +				   gtdt_frame->virtual_timer_flags);
> +		if (frame->virt_irq <= 0) {
> +			pr_warn("failed to map virtual timer irq in frame %d.\n",
> +				i);
> +			acpi_unregister_gsi(gtdt_frame->timer_interrupt);
> +			return -EINVAL;
> +		}
> +
> +		frame->frame_nr = gtdt_frame->frame_number;
> +		frame->cntbase = gtdt_frame->base_address;
> +		/*
> +		 * The CNTBaseN frame is 4KB (register offsets 0x000 - 0xFFC).
> +		 * See ARM DDI 0487A.k_iss10775, page I1-5130, Table I1-4
> +		 * "CNTBaseN memory map".
> +		 */
> +		frame->size = SZ_4K;
> +		j++;
> +	}
> +	timer_mem->num_frames = j;
> +
> +	return 0;
> +}
> +
> +/**
> + * acpi_arch_timer_mem_init() - Get the info of all GT blocks in GTDT table.
> + * @timer_mem:	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.

Nit: this comment was wrong on all the patches I reviewed :) must be
some copy and paste.

> + *
> + * Return: 0 if success, -EINVAL/-ENODEV if error.
> + */
> +int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
> +				    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, timer_mem);
> +			if (ret)
> +				return ret;

Isn't there some unwinding to carry out here (eg GSI) ?

Otherwise it looks fine (minus Mark's request for using frame numbers
as indexes that you should change).

Lorenzo

> +			timer_mem++;
> +			(*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 4b5c146..3193724 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -599,6 +599,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 *timer_mem, int *timer_count);
>  #endif
>  
>  #else	/* !CONFIG_ACPI */
> -- 
> 2.9.3
> 

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 09/11] acpi/arm64: Add memory-mapped timer support in GTDT driver
  2017-03-29 16:47       ` Lorenzo Pieralisi
  (?)
@ 2017-03-30  7:54         ` Fu Wei
  -1 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-30  7:54 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Linaro ACPI Mailman List, Linux Kernel Mailing List,
	ACPI Devel Maling List, rruigrok-sgV2jX0FEOL9JmXXK+q4OQ,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei

Hi Lorenzo,

On 30 March 2017 at 00:47, Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org> wrote:
> On Wed, Mar 22, 2017 at 12:31:20AM +0800, fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org wrote:
>> From: Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>
>> 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 <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> Signed-off-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> ---
>>  drivers/acpi/arm64/gtdt.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/acpi.h      |   1 +
>>  2 files changed, 131 insertions(+)
>>
>> diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
>> index 8a03b4b..f471873 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,111 @@ 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 *timer_mem)
>> +{
>> +     int i, j;
>> +     struct acpi_gtdt_timer_entry *gtdt_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;
>> +     }
>> +
>> +     timer_mem->cntctlbase = (phys_addr_t)block->block_address;
>> +     /*
>> +      * The CNTCTLBase frame is 4KB (register offsets 0x000 - 0xFFC).
>> +      * See ARM DDI 0487A.k_iss10775, page I1-5129, Table I1-3
>> +      * "CNTCTLBase memory map".
>> +      */
>> +     timer_mem->size = SZ_4K;
>> +
>> +     gtdt_frame = (void *)block + block->timer_offset;
>> +     if (gtdt_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++, gtdt_frame++) {
>> +             struct arch_timer_mem_frame *frame = &timer_mem->frame[j];
>> +
>> +             if (gtdt_frame->common_flags & ACPI_GTDT_GT_IS_SECURE_TIMER)
>> +                     continue;
>> +
>> +             if (!gtdt_frame->base_address || !gtdt_frame->timer_interrupt)
>> +                     return -EINVAL;
>> +
>> +             frame->phys_irq = map_gt_gsi(gtdt_frame->timer_interrupt,
>> +                                          gtdt_frame->timer_flags);
>> +             if (frame->phys_irq <= 0) {
>> +                     pr_warn("failed to map physical timer irq in frame %d.\n",
>> +                             i);
>> +                     return -EINVAL;
>> +             }
>> +
>> +             frame->virt_irq =
>> +                     map_gt_gsi(gtdt_frame->virtual_timer_interrupt,
>> +                                gtdt_frame->virtual_timer_flags);
>> +             if (frame->virt_irq <= 0) {
>> +                     pr_warn("failed to map virtual timer irq in frame %d.\n",
>> +                             i);
>> +                     acpi_unregister_gsi(gtdt_frame->timer_interrupt);
>> +                     return -EINVAL;
>> +             }
>> +
>> +             frame->frame_nr = gtdt_frame->frame_number;
>> +             frame->cntbase = gtdt_frame->base_address;
>> +             /*
>> +              * The CNTBaseN frame is 4KB (register offsets 0x000 - 0xFFC).
>> +              * See ARM DDI 0487A.k_iss10775, page I1-5130, Table I1-4
>> +              * "CNTBaseN memory map".
>> +              */
>> +             frame->size = SZ_4K;
>> +             j++;
>> +     }
>> +     timer_mem->num_frames = j;
>> +
>> +     return 0;
>> +}
>> +
>> +/**
>> + * acpi_arch_timer_mem_init() - Get the info of all GT blocks in GTDT table.
>> + * @timer_mem:       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.
>
> Nit: this comment was wrong on all the patches I reviewed :) must be
> some copy and paste.

Thanks ,

 * @timer_count: It points to a integer variable which is used for storing the
 *                         number of GT blocks we have parsed.

Is that OK for you?
>
>> + *
>> + * Return: 0 if success, -EINVAL/-ENODEV if error.
>> + */
>> +int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
>> +                                 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, timer_mem);
>> +                     if (ret)
>> +                             return ret;
>
> Isn't there some unwinding to carry out here (eg GSI) ?

Thanks for your reminding,
it should be in gtdt_parse_timer_block, will do

>
> Otherwise it looks fine (minus Mark's request for using frame numbers
> as indexes that you should change).
>
> Lorenzo
>
>> +                     timer_mem++;
>> +                     (*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 4b5c146..3193724 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -599,6 +599,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 *timer_mem, int *timer_count);
>>  #endif
>>
>>  #else        /* !CONFIG_ACPI */
>> --
>> 2.9.3
>>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 09/11] acpi/arm64: Add memory-mapped timer support in GTDT driver
@ 2017-03-30  7:54         ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-30  7:54 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

Hi Lorenzo,

On 30 March 2017 at 00:47, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Wed, Mar 22, 2017 at 12:31:20AM +0800, fu.wei@linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> 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 <fu.wei@linaro.org>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>  drivers/acpi/arm64/gtdt.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/acpi.h      |   1 +
>>  2 files changed, 131 insertions(+)
>>
>> diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
>> index 8a03b4b..f471873 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,111 @@ 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 *timer_mem)
>> +{
>> +     int i, j;
>> +     struct acpi_gtdt_timer_entry *gtdt_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;
>> +     }
>> +
>> +     timer_mem->cntctlbase = (phys_addr_t)block->block_address;
>> +     /*
>> +      * The CNTCTLBase frame is 4KB (register offsets 0x000 - 0xFFC).
>> +      * See ARM DDI 0487A.k_iss10775, page I1-5129, Table I1-3
>> +      * "CNTCTLBase memory map".
>> +      */
>> +     timer_mem->size = SZ_4K;
>> +
>> +     gtdt_frame = (void *)block + block->timer_offset;
>> +     if (gtdt_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++, gtdt_frame++) {
>> +             struct arch_timer_mem_frame *frame = &timer_mem->frame[j];
>> +
>> +             if (gtdt_frame->common_flags & ACPI_GTDT_GT_IS_SECURE_TIMER)
>> +                     continue;
>> +
>> +             if (!gtdt_frame->base_address || !gtdt_frame->timer_interrupt)
>> +                     return -EINVAL;
>> +
>> +             frame->phys_irq = map_gt_gsi(gtdt_frame->timer_interrupt,
>> +                                          gtdt_frame->timer_flags);
>> +             if (frame->phys_irq <= 0) {
>> +                     pr_warn("failed to map physical timer irq in frame %d.\n",
>> +                             i);
>> +                     return -EINVAL;
>> +             }
>> +
>> +             frame->virt_irq =
>> +                     map_gt_gsi(gtdt_frame->virtual_timer_interrupt,
>> +                                gtdt_frame->virtual_timer_flags);
>> +             if (frame->virt_irq <= 0) {
>> +                     pr_warn("failed to map virtual timer irq in frame %d.\n",
>> +                             i);
>> +                     acpi_unregister_gsi(gtdt_frame->timer_interrupt);
>> +                     return -EINVAL;
>> +             }
>> +
>> +             frame->frame_nr = gtdt_frame->frame_number;
>> +             frame->cntbase = gtdt_frame->base_address;
>> +             /*
>> +              * The CNTBaseN frame is 4KB (register offsets 0x000 - 0xFFC).
>> +              * See ARM DDI 0487A.k_iss10775, page I1-5130, Table I1-4
>> +              * "CNTBaseN memory map".
>> +              */
>> +             frame->size = SZ_4K;
>> +             j++;
>> +     }
>> +     timer_mem->num_frames = j;
>> +
>> +     return 0;
>> +}
>> +
>> +/**
>> + * acpi_arch_timer_mem_init() - Get the info of all GT blocks in GTDT table.
>> + * @timer_mem:       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.
>
> Nit: this comment was wrong on all the patches I reviewed :) must be
> some copy and paste.

Thanks ,

 * @timer_count: It points to a integer variable which is used for storing the
 *                         number of GT blocks we have parsed.

Is that OK for you?
>
>> + *
>> + * Return: 0 if success, -EINVAL/-ENODEV if error.
>> + */
>> +int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
>> +                                 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, timer_mem);
>> +                     if (ret)
>> +                             return ret;
>
> Isn't there some unwinding to carry out here (eg GSI) ?

Thanks for your reminding,
it should be in gtdt_parse_timer_block, will do

>
> Otherwise it looks fine (minus Mark's request for using frame numbers
> as indexes that you should change).
>
> Lorenzo
>
>> +                     timer_mem++;
>> +                     (*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 4b5c146..3193724 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -599,6 +599,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 *timer_mem, int *timer_count);
>>  #endif
>>
>>  #else        /* !CONFIG_ACPI */
>> --
>> 2.9.3
>>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 09/11] acpi/arm64: Add memory-mapped timer support in GTDT driver
@ 2017-03-30  7:54         ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-30  7:54 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lorenzo,

On 30 March 2017 at 00:47, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Wed, Mar 22, 2017 at 12:31:20AM +0800, fu.wei at linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> 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 <fu.wei@linaro.org>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>  drivers/acpi/arm64/gtdt.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/acpi.h      |   1 +
>>  2 files changed, 131 insertions(+)
>>
>> diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
>> index 8a03b4b..f471873 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,111 @@ 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 *timer_mem)
>> +{
>> +     int i, j;
>> +     struct acpi_gtdt_timer_entry *gtdt_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;
>> +     }
>> +
>> +     timer_mem->cntctlbase = (phys_addr_t)block->block_address;
>> +     /*
>> +      * The CNTCTLBase frame is 4KB (register offsets 0x000 - 0xFFC).
>> +      * See ARM DDI 0487A.k_iss10775, page I1-5129, Table I1-3
>> +      * "CNTCTLBase memory map".
>> +      */
>> +     timer_mem->size = SZ_4K;
>> +
>> +     gtdt_frame = (void *)block + block->timer_offset;
>> +     if (gtdt_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++, gtdt_frame++) {
>> +             struct arch_timer_mem_frame *frame = &timer_mem->frame[j];
>> +
>> +             if (gtdt_frame->common_flags & ACPI_GTDT_GT_IS_SECURE_TIMER)
>> +                     continue;
>> +
>> +             if (!gtdt_frame->base_address || !gtdt_frame->timer_interrupt)
>> +                     return -EINVAL;
>> +
>> +             frame->phys_irq = map_gt_gsi(gtdt_frame->timer_interrupt,
>> +                                          gtdt_frame->timer_flags);
>> +             if (frame->phys_irq <= 0) {
>> +                     pr_warn("failed to map physical timer irq in frame %d.\n",
>> +                             i);
>> +                     return -EINVAL;
>> +             }
>> +
>> +             frame->virt_irq =
>> +                     map_gt_gsi(gtdt_frame->virtual_timer_interrupt,
>> +                                gtdt_frame->virtual_timer_flags);
>> +             if (frame->virt_irq <= 0) {
>> +                     pr_warn("failed to map virtual timer irq in frame %d.\n",
>> +                             i);
>> +                     acpi_unregister_gsi(gtdt_frame->timer_interrupt);
>> +                     return -EINVAL;
>> +             }
>> +
>> +             frame->frame_nr = gtdt_frame->frame_number;
>> +             frame->cntbase = gtdt_frame->base_address;
>> +             /*
>> +              * The CNTBaseN frame is 4KB (register offsets 0x000 - 0xFFC).
>> +              * See ARM DDI 0487A.k_iss10775, page I1-5130, Table I1-4
>> +              * "CNTBaseN memory map".
>> +              */
>> +             frame->size = SZ_4K;
>> +             j++;
>> +     }
>> +     timer_mem->num_frames = j;
>> +
>> +     return 0;
>> +}
>> +
>> +/**
>> + * acpi_arch_timer_mem_init() - Get the info of all GT blocks in GTDT table.
>> + * @timer_mem:       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.
>
> Nit: this comment was wrong on all the patches I reviewed :) must be
> some copy and paste.

Thanks ,

 * @timer_count: It points to a integer variable which is used for storing the
 *                         number of GT blocks we have parsed.

Is that OK for you?
>
>> + *
>> + * Return: 0 if success, -EINVAL/-ENODEV if error.
>> + */
>> +int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
>> +                                 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, timer_mem);
>> +                     if (ret)
>> +                             return ret;
>
> Isn't there some unwinding to carry out here (eg GSI) ?

Thanks for your reminding,
it should be in gtdt_parse_timer_block, will do

>
> Otherwise it looks fine (minus Mark's request for using frame numbers
> as indexes that you should change).
>
> Lorenzo
>
>> +                     timer_mem++;
>> +                     (*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 4b5c146..3193724 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -599,6 +599,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 *timer_mem, int *timer_count);
>>  #endif
>>
>>  #else        /* !CONFIG_ACPI */
>> --
>> 2.9.3
>>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 11/11] acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
  2017-03-28 15:41     ` Lorenzo Pieralisi
  (?)
@ 2017-03-31  8:10       ` Fu Wei
  -1 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-31  8:10 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Linaro ACPI Mailman List, Linux Kernel Mailing List,
	ACPI Devel Maling List, rruigrok-sgV2jX0FEOL9JmXXK+q4OQ,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei

Hi Lorenzo,

On 28 March 2017 at 23:41, Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org> wrote:
> On Wed, Mar 22, 2017 at 12:31:22AM +0800, fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org wrote:
>> From: Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>
>> 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 <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> Signed-off-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> Tested-by: Xiongfeng Wang <wangxiongfeng2-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>> ---
>>  drivers/acpi/arm64/gtdt.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 94 insertions(+)
>>
>> diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
>> index f471873..5d167f0 100644
>> --- a/drivers/acpi/arm64/gtdt.c
>> +++ b/drivers/acpi/arm64/gtdt.c
>> @@ -14,6 +14,7 @@
>>  #include <linux/acpi.h>
>>  #include <linux/init.h>
>>  #include <linux/kernel.h>
>> +#include <linux/platform_device.h>
>>
>>  #include <clocksource/arm_arch_timer.h>
>>
>> @@ -59,6 +60,17 @@ static inline bool is_timer_block(void *platform_timer)
>>       return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK;
>>  }
>>
>> +static inline bool is_non_secure_watchdog(void *platform_timer)
>> +{
>> +     struct acpi_gtdt_header *gh = platform_timer;
>> +     struct acpi_gtdt_watchdog *wd = platform_timer;
>> +
>> +     if (gh->type != ACPI_GTDT_TYPE_WATCHDOG)
>> +             return false;
>> +
>> +     return !(wd->timer_flags & ACPI_GTDT_WATCHDOG_SECURE);
>> +}
>> +
>>  static int __init map_gt_gsi(u32 interrupt, u32 flags)
>>  {
>>       int trigger, polarity;
>> @@ -285,3 +297,85 @@ int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
>>
>>       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);
>> +
>> +     /*
>> +      * 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),
>> +     };
>> +     int nr_res = ARRAY_SIZE(res);
>> +
>> +     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");


+             acpi_unregister_gsi(wd->timer_interrupt);


>> +             return -EINVAL;
>
> You should unmap the gsi here.

yes, you are right, fixed it.

>
>> +     }
>> +
>> +     if (irq <= 0) {
>> +             pr_warn("failed to map the Watchdog interrupt.\n");
>> +             nr_res--;
>> +     }
>> +
>> +     /*
>> +      * 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

+      * The platform driver can get device info below by matching this name.

>
> Nit: I would not hardcode drivers paths in comments.


OK, deleted it

>
>> +      * info below by matching this name.
>> +      */
>> +     pdev = platform_device_register_simple("sbsa-gwdt", index, res, nr_res);
>> +     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;
>
> Ok, I missed previous versions reviews so I miss the background
> here and I apologise.
>
> I do not understand why you call acpi_gtdt_init() again (or better,
> why acpi_gtdt_init() does not return straight away) here if the
> stashed pointer in acpi_gtdt_desc is already set. I am not a big fan
> of the for_each_platform_timer macro either, here you can just read
> the ACPI_SIG_GTDT and parse its entries, I see no point in calling
> acpi_gtdt_init() again, there is nothing to stash for later probing,
> is there ?
>
> Or it is just to reuse common parsing code ? Regardless, if the
> acpi_gtdt_desc struct is already initialized acpi_gtdt_init() should
> just return or I am missing the point.
>
> I would like clarifications on the acpi_gtdt_init() call above please
> (plus GSI unmap fix), apart from that:
>
> Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>

Actually, after the discussion in the 7th patch, I have tried to do
this, see if that can make the code simpler.
Then I found out that
(1) If we would like to reuse "for_each_platform_timer" (and
"next_platform_timer") to scan the GTDT for SBSA watchdog, we have to
re-initialize acpi_gtdt_desc, too.
     So we still need to explain that why we have to re-initialize
acpi_gtdt_desc.
(2) If we totally ignore acpi_gtdt_desc, and acpi_gtdt_init(), we
can't re-use  "for_each_platform_timer" (and "next_platform_timer") .
we have to re-write  the loop of scanning the GTDT for SBSA watchdog,

So may I suggest that maybe we can keep using acpi_gtdt_init, only add
the comment to explain why we have to re-initialize
acpi_gtdt_desc(Just what you have said in the 7th patch. Thanks for
your correction for the comment, I will use that ), this way maybe can
make the code simpler.

But If you still concern about this,  we still can discuss this at -rc1.

Great thanks for your help! :-)

>
>> +     for_each_platform_timer(platform_timer) {
>> +             if (is_non_secure_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);
>> --
>> 2.9.3
>>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 11/11] acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
@ 2017-03-31  8:10       ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-31  8:10 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

Hi Lorenzo,

On 28 March 2017 at 23:41, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Wed, Mar 22, 2017 at 12:31:22AM +0800, fu.wei@linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> 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 <fu.wei@linaro.org>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
>> ---
>>  drivers/acpi/arm64/gtdt.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 94 insertions(+)
>>
>> diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
>> index f471873..5d167f0 100644
>> --- a/drivers/acpi/arm64/gtdt.c
>> +++ b/drivers/acpi/arm64/gtdt.c
>> @@ -14,6 +14,7 @@
>>  #include <linux/acpi.h>
>>  #include <linux/init.h>
>>  #include <linux/kernel.h>
>> +#include <linux/platform_device.h>
>>
>>  #include <clocksource/arm_arch_timer.h>
>>
>> @@ -59,6 +60,17 @@ static inline bool is_timer_block(void *platform_timer)
>>       return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK;
>>  }
>>
>> +static inline bool is_non_secure_watchdog(void *platform_timer)
>> +{
>> +     struct acpi_gtdt_header *gh = platform_timer;
>> +     struct acpi_gtdt_watchdog *wd = platform_timer;
>> +
>> +     if (gh->type != ACPI_GTDT_TYPE_WATCHDOG)
>> +             return false;
>> +
>> +     return !(wd->timer_flags & ACPI_GTDT_WATCHDOG_SECURE);
>> +}
>> +
>>  static int __init map_gt_gsi(u32 interrupt, u32 flags)
>>  {
>>       int trigger, polarity;
>> @@ -285,3 +297,85 @@ int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
>>
>>       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);
>> +
>> +     /*
>> +      * 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),
>> +     };
>> +     int nr_res = ARRAY_SIZE(res);
>> +
>> +     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");


+             acpi_unregister_gsi(wd->timer_interrupt);


>> +             return -EINVAL;
>
> You should unmap the gsi here.

yes, you are right, fixed it.

>
>> +     }
>> +
>> +     if (irq <= 0) {
>> +             pr_warn("failed to map the Watchdog interrupt.\n");
>> +             nr_res--;
>> +     }
>> +
>> +     /*
>> +      * 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

+      * The platform driver can get device info below by matching this name.

>
> Nit: I would not hardcode drivers paths in comments.


OK, deleted it

>
>> +      * info below by matching this name.
>> +      */
>> +     pdev = platform_device_register_simple("sbsa-gwdt", index, res, nr_res);
>> +     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;
>
> Ok, I missed previous versions reviews so I miss the background
> here and I apologise.
>
> I do not understand why you call acpi_gtdt_init() again (or better,
> why acpi_gtdt_init() does not return straight away) here if the
> stashed pointer in acpi_gtdt_desc is already set. I am not a big fan
> of the for_each_platform_timer macro either, here you can just read
> the ACPI_SIG_GTDT and parse its entries, I see no point in calling
> acpi_gtdt_init() again, there is nothing to stash for later probing,
> is there ?
>
> Or it is just to reuse common parsing code ? Regardless, if the
> acpi_gtdt_desc struct is already initialized acpi_gtdt_init() should
> just return or I am missing the point.
>
> I would like clarifications on the acpi_gtdt_init() call above please
> (plus GSI unmap fix), apart from that:
>
> Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

Actually, after the discussion in the 7th patch, I have tried to do
this, see if that can make the code simpler.
Then I found out that
(1) If we would like to reuse "for_each_platform_timer" (and
"next_platform_timer") to scan the GTDT for SBSA watchdog, we have to
re-initialize acpi_gtdt_desc, too.
     So we still need to explain that why we have to re-initialize
acpi_gtdt_desc.
(2) If we totally ignore acpi_gtdt_desc, and acpi_gtdt_init(), we
can't re-use  "for_each_platform_timer" (and "next_platform_timer") .
we have to re-write  the loop of scanning the GTDT for SBSA watchdog,

So may I suggest that maybe we can keep using acpi_gtdt_init, only add
the comment to explain why we have to re-initialize
acpi_gtdt_desc(Just what you have said in the 7th patch. Thanks for
your correction for the comment, I will use that ), this way maybe can
make the code simpler.

But If you still concern about this,  we still can discuss this at -rc1.

Great thanks for your help! :-)

>
>> +     for_each_platform_timer(platform_timer) {
>> +             if (is_non_secure_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);
>> --
>> 2.9.3
>>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 11/11] acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
@ 2017-03-31  8:10       ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-31  8:10 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lorenzo,

On 28 March 2017 at 23:41, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Wed, Mar 22, 2017 at 12:31:22AM +0800, fu.wei at linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> 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 <fu.wei@linaro.org>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
>> ---
>>  drivers/acpi/arm64/gtdt.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 94 insertions(+)
>>
>> diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
>> index f471873..5d167f0 100644
>> --- a/drivers/acpi/arm64/gtdt.c
>> +++ b/drivers/acpi/arm64/gtdt.c
>> @@ -14,6 +14,7 @@
>>  #include <linux/acpi.h>
>>  #include <linux/init.h>
>>  #include <linux/kernel.h>
>> +#include <linux/platform_device.h>
>>
>>  #include <clocksource/arm_arch_timer.h>
>>
>> @@ -59,6 +60,17 @@ static inline bool is_timer_block(void *platform_timer)
>>       return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK;
>>  }
>>
>> +static inline bool is_non_secure_watchdog(void *platform_timer)
>> +{
>> +     struct acpi_gtdt_header *gh = platform_timer;
>> +     struct acpi_gtdt_watchdog *wd = platform_timer;
>> +
>> +     if (gh->type != ACPI_GTDT_TYPE_WATCHDOG)
>> +             return false;
>> +
>> +     return !(wd->timer_flags & ACPI_GTDT_WATCHDOG_SECURE);
>> +}
>> +
>>  static int __init map_gt_gsi(u32 interrupt, u32 flags)
>>  {
>>       int trigger, polarity;
>> @@ -285,3 +297,85 @@ int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
>>
>>       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);
>> +
>> +     /*
>> +      * 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),
>> +     };
>> +     int nr_res = ARRAY_SIZE(res);
>> +
>> +     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");


+             acpi_unregister_gsi(wd->timer_interrupt);


>> +             return -EINVAL;
>
> You should unmap the gsi here.

yes, you are right, fixed it.

>
>> +     }
>> +
>> +     if (irq <= 0) {
>> +             pr_warn("failed to map the Watchdog interrupt.\n");
>> +             nr_res--;
>> +     }
>> +
>> +     /*
>> +      * 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

+      * The platform driver can get device info below by matching this name.

>
> Nit: I would not hardcode drivers paths in comments.


OK, deleted it

>
>> +      * info below by matching this name.
>> +      */
>> +     pdev = platform_device_register_simple("sbsa-gwdt", index, res, nr_res);
>> +     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;
>
> Ok, I missed previous versions reviews so I miss the background
> here and I apologise.
>
> I do not understand why you call acpi_gtdt_init() again (or better,
> why acpi_gtdt_init() does not return straight away) here if the
> stashed pointer in acpi_gtdt_desc is already set. I am not a big fan
> of the for_each_platform_timer macro either, here you can just read
> the ACPI_SIG_GTDT and parse its entries, I see no point in calling
> acpi_gtdt_init() again, there is nothing to stash for later probing,
> is there ?
>
> Or it is just to reuse common parsing code ? Regardless, if the
> acpi_gtdt_desc struct is already initialized acpi_gtdt_init() should
> just return or I am missing the point.
>
> I would like clarifications on the acpi_gtdt_init() call above please
> (plus GSI unmap fix), apart from that:
>
> Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

Actually, after the discussion in the 7th patch, I have tried to do
this, see if that can make the code simpler.
Then I found out that
(1) If we would like to reuse "for_each_platform_timer" (and
"next_platform_timer") to scan the GTDT for SBSA watchdog, we have to
re-initialize acpi_gtdt_desc, too.
     So we still need to explain that why we have to re-initialize
acpi_gtdt_desc.
(2) If we totally ignore acpi_gtdt_desc, and acpi_gtdt_init(), we
can't re-use  "for_each_platform_timer" (and "next_platform_timer") .
we have to re-write  the loop of scanning the GTDT for SBSA watchdog,

So may I suggest that maybe we can keep using acpi_gtdt_init, only add
the comment to explain why we have to re-initialize
acpi_gtdt_desc(Just what you have said in the 7th patch. Thanks for
your correction for the comment, I will use that ), this way maybe can
make the code simpler.

But If you still concern about this,  we still can discuss this at -rc1.

Great thanks for your help! :-)

>
>> +     for_each_platform_timer(platform_timer) {
>> +             if (is_non_secure_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);
>> --
>> 2.9.3
>>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 11/11] acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
  2017-03-31  8:10       ` Fu Wei
  (?)
@ 2017-03-31 11:54         ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-31 11:54 UTC (permalink / raw)
  To: Fu Wei
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei

On Fri, Mar 31, 2017 at 04:10:43PM +0800, Fu Wei wrote:

[...]

> >> +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;
> >
> > Ok, I missed previous versions reviews so I miss the background
> > here and I apologise.
> >
> > I do not understand why you call acpi_gtdt_init() again (or better,
> > why acpi_gtdt_init() does not return straight away) here if the
> > stashed pointer in acpi_gtdt_desc is already set. I am not a big fan
> > of the for_each_platform_timer macro either, here you can just read
> > the ACPI_SIG_GTDT and parse its entries, I see no point in calling
> > acpi_gtdt_init() again, there is nothing to stash for later probing,
> > is there ?
> >
> > Or it is just to reuse common parsing code ? Regardless, if the
> > acpi_gtdt_desc struct is already initialized acpi_gtdt_init() should
> > just return or I am missing the point.
> >
> > I would like clarifications on the acpi_gtdt_init() call above please
> > (plus GSI unmap fix), apart from that:
> >
> > Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> 
> Actually, after the discussion in the 7th patch, I have tried to do
> this, see if that can make the code simpler.
> Then I found out that
> (1) If we would like to reuse "for_each_platform_timer" (and
> "next_platform_timer") to scan the GTDT for SBSA watchdog, we have to
> re-initialize acpi_gtdt_desc, too.
>      So we still need to explain that why we have to re-initialize
> acpi_gtdt_desc.
> (2) If we totally ignore acpi_gtdt_desc, and acpi_gtdt_init(), we
> can't re-use  "for_each_platform_timer" (and "next_platform_timer") .
> we have to re-write  the loop of scanning the GTDT for SBSA watchdog,

Or we get rid of for_each_platform_timer altogether that for me
is not useful at all and just obfuscates.

Anyway, add the comment below and you are done with this, at this point
in time it is best to avoid changing the code we'd just risk adding
bugs.

At -rc1 we will send patches to reshape this code as per this
discussion.

Thanks !
Lorenzo

> So may I suggest that maybe we can keep using acpi_gtdt_init, only add
> the comment to explain why we have to re-initialize
> acpi_gtdt_desc(Just what you have said in the 7th patch. Thanks for
> your correction for the comment, I will use that ), this way maybe can
> make the code simpler.
> 
> But If you still concern about this,  we still can discuss this at -rc1.
> 
> Great thanks for your help! :-)
> 
> >
> >> +     for_each_platform_timer(platform_timer) {
> >> +             if (is_non_secure_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);
> >> --
> >> 2.9.3
> >>
> 
> 
> 
> -- 
> Best regards,
> 
> Fu Wei
> Software Engineer
> Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 11/11] acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
@ 2017-03-31 11:54         ` Lorenzo Pieralisi
  0 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-31 11:54 UTC (permalink / raw)
  To: Fu Wei
  Cc: Rafael J. Wysocki, Len Brown, Daniel Lezcano, Thomas Gleixner,
	Marc Zyngier, Mark Rutland, Sudeep Holla, Hanjun Guo,
	linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

On Fri, Mar 31, 2017 at 04:10:43PM +0800, Fu Wei wrote:

[...]

> >> +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;
> >
> > Ok, I missed previous versions reviews so I miss the background
> > here and I apologise.
> >
> > I do not understand why you call acpi_gtdt_init() again (or better,
> > why acpi_gtdt_init() does not return straight away) here if the
> > stashed pointer in acpi_gtdt_desc is already set. I am not a big fan
> > of the for_each_platform_timer macro either, here you can just read
> > the ACPI_SIG_GTDT and parse its entries, I see no point in calling
> > acpi_gtdt_init() again, there is nothing to stash for later probing,
> > is there ?
> >
> > Or it is just to reuse common parsing code ? Regardless, if the
> > acpi_gtdt_desc struct is already initialized acpi_gtdt_init() should
> > just return or I am missing the point.
> >
> > I would like clarifications on the acpi_gtdt_init() call above please
> > (plus GSI unmap fix), apart from that:
> >
> > Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> 
> Actually, after the discussion in the 7th patch, I have tried to do
> this, see if that can make the code simpler.
> Then I found out that
> (1) If we would like to reuse "for_each_platform_timer" (and
> "next_platform_timer") to scan the GTDT for SBSA watchdog, we have to
> re-initialize acpi_gtdt_desc, too.
>      So we still need to explain that why we have to re-initialize
> acpi_gtdt_desc.
> (2) If we totally ignore acpi_gtdt_desc, and acpi_gtdt_init(), we
> can't re-use  "for_each_platform_timer" (and "next_platform_timer") .
> we have to re-write  the loop of scanning the GTDT for SBSA watchdog,

Or we get rid of for_each_platform_timer altogether that for me
is not useful at all and just obfuscates.

Anyway, add the comment below and you are done with this, at this point
in time it is best to avoid changing the code we'd just risk adding
bugs.

At -rc1 we will send patches to reshape this code as per this
discussion.

Thanks !
Lorenzo

> So may I suggest that maybe we can keep using acpi_gtdt_init, only add
> the comment to explain why we have to re-initialize
> acpi_gtdt_desc(Just what you have said in the 7th patch. Thanks for
> your correction for the comment, I will use that ), this way maybe can
> make the code simpler.
> 
> But If you still concern about this,  we still can discuss this at -rc1.
> 
> Great thanks for your help! :-)
> 
> >
> >> +     for_each_platform_timer(platform_timer) {
> >> +             if (is_non_secure_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);
> >> --
> >> 2.9.3
> >>
> 
> 
> 
> -- 
> Best regards,
> 
> Fu Wei
> Software Engineer
> Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 11/11] acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
@ 2017-03-31 11:54         ` Lorenzo Pieralisi
  0 siblings, 0 replies; 113+ messages in thread
From: Lorenzo Pieralisi @ 2017-03-31 11:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 31, 2017 at 04:10:43PM +0800, Fu Wei wrote:

[...]

> >> +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;
> >
> > Ok, I missed previous versions reviews so I miss the background
> > here and I apologise.
> >
> > I do not understand why you call acpi_gtdt_init() again (or better,
> > why acpi_gtdt_init() does not return straight away) here if the
> > stashed pointer in acpi_gtdt_desc is already set. I am not a big fan
> > of the for_each_platform_timer macro either, here you can just read
> > the ACPI_SIG_GTDT and parse its entries, I see no point in calling
> > acpi_gtdt_init() again, there is nothing to stash for later probing,
> > is there ?
> >
> > Or it is just to reuse common parsing code ? Regardless, if the
> > acpi_gtdt_desc struct is already initialized acpi_gtdt_init() should
> > just return or I am missing the point.
> >
> > I would like clarifications on the acpi_gtdt_init() call above please
> > (plus GSI unmap fix), apart from that:
> >
> > Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> 
> Actually, after the discussion in the 7th patch, I have tried to do
> this, see if that can make the code simpler.
> Then I found out that
> (1) If we would like to reuse "for_each_platform_timer" (and
> "next_platform_timer") to scan the GTDT for SBSA watchdog, we have to
> re-initialize acpi_gtdt_desc, too.
>      So we still need to explain that why we have to re-initialize
> acpi_gtdt_desc.
> (2) If we totally ignore acpi_gtdt_desc, and acpi_gtdt_init(), we
> can't re-use  "for_each_platform_timer" (and "next_platform_timer") .
> we have to re-write  the loop of scanning the GTDT for SBSA watchdog,

Or we get rid of for_each_platform_timer altogether that for me
is not useful at all and just obfuscates.

Anyway, add the comment below and you are done with this, at this point
in time it is best to avoid changing the code we'd just risk adding
bugs.

At -rc1 we will send patches to reshape this code as per this
discussion.

Thanks !
Lorenzo

> So may I suggest that maybe we can keep using acpi_gtdt_init, only add
> the comment to explain why we have to re-initialize
> acpi_gtdt_desc(Just what you have said in the 7th patch. Thanks for
> your correction for the comment, I will use that ), this way maybe can
> make the code simpler.
> 
> But If you still concern about this,  we still can discuss this at -rc1.
> 
> Great thanks for your help! :-)
> 
> >
> >> +     for_each_platform_timer(platform_timer) {
> >> +             if (is_non_secure_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);
> >> --
> >> 2.9.3
> >>
> 
> 
> 
> -- 
> Best regards,
> 
> Fu Wei
> Software Engineer
> Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
  2017-03-28 14:53           ` Mark Rutland
  (?)
@ 2017-03-31 17:55             ` Fu Wei
  -1 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-31 17:55 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Jon Masters, Rafael J. Wysocki, Len Brown, Daniel Lezcano,
	Thomas Gleixner, Marc Zyngier, Lorenzo Pieralisi, Sudeep Holla,
	Hanjun Guo, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Linaro ACPI Mailman List, Linux Kernel Mailing List,
	ACPI Devel Maling List, rruigrok-sgV2jX0FEOL9JmXXK+q4OQ,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone

Hi Mark,

On 28 March 2017 at 22:53, Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org> wrote:
> Hi,
>
> On Tue, Mar 28, 2017 at 10:29:10PM +0800, Fu Wei wrote:
>> On 28 March 2017 at 21:05, Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org> wrote:
>> > Sorry for the delay; I have not had the time to focus on this as I would
>> > like to. I'm happy with patches 1-4, but from patch 5 onwards, there's
>> > one change I'd like to see.
>> >
>> > I'd prefer that mmio timer frame rame N was always stored at
>> > arch_timer_mem::frame[N], rather than arch_timer_mem::frame[] being in
>> > an arbitrary order. That will make arch_timer_mem_frame::frame_nr
>> > redundant.
>> >
>> > To allow arch_timer_mem::frame[] this to be sparse, I'm happy to have a
>> > bool arch_timer_mem_frame::valid field that we set when probing each
>> > frame. Then we don't need arch_timer_mem::num_frames.
>> >
>> > This will make iterating over the frames far less confusing, and makes
>> > it simple to detect when a frame number is erroneously reused.
>> >
>> > Otherwise, I'm largely happy to pick the rest and apply any fixups
>> > myself.
>>
>> Great thanks for your feedback!
>> I will follow your suggestion to improve my patches, then post it in a day.
>
> Thanks, that is much appreciated.
>
>> So I will rebase my patchset on arch-timer/gtdt branch of your REPO
>> https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt
>
> Yes please! The current HEAD should be:
>
> ebbfe8889cffa12f ("clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call").

Because there are some improvements on the first 4 patches, so I
fetched your gtdt branch, then rebase my v23  to the
arch-timer/cleanup

Thanks for your help! :-)

>
> Thanks,
> Mark.



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 113+ messages in thread

* Re: [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
@ 2017-03-31 17:55             ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-31 17:55 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Jon Masters, Rafael J. Wysocki, Len Brown, Daniel Lezcano,
	Thomas Gleixner, Marc Zyngier, Lorenzo Pieralisi, Sudeep Holla,
	Hanjun Guo, linux-arm-kernel, Linaro ACPI Mailman List,
	Linux Kernel Mailing List, ACPI Devel Maling List, rruigrok,
	Abdulhamid, Harb, Christopher Covington, Timur Tabi, G Gregory,
	Al Stone, Jon Masters, Wei Huang, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Suravee Suthikulpanit, Leo Duran, Wim Van Sebroeck,
	Guenter Roeck, linux-watchdog, Tomasz Nowicki, Christoffer Dall,
	Julien Grall

Hi Mark,

On 28 March 2017 at 22:53, Mark Rutland <mark.rutland@arm.com> wrote:
> Hi,
>
> On Tue, Mar 28, 2017 at 10:29:10PM +0800, Fu Wei wrote:
>> On 28 March 2017 at 21:05, Mark Rutland <mark.rutland@arm.com> wrote:
>> > Sorry for the delay; I have not had the time to focus on this as I would
>> > like to. I'm happy with patches 1-4, but from patch 5 onwards, there's
>> > one change I'd like to see.
>> >
>> > I'd prefer that mmio timer frame rame N was always stored at
>> > arch_timer_mem::frame[N], rather than arch_timer_mem::frame[] being in
>> > an arbitrary order. That will make arch_timer_mem_frame::frame_nr
>> > redundant.
>> >
>> > To allow arch_timer_mem::frame[] this to be sparse, I'm happy to have a
>> > bool arch_timer_mem_frame::valid field that we set when probing each
>> > frame. Then we don't need arch_timer_mem::num_frames.
>> >
>> > This will make iterating over the frames far less confusing, and makes
>> > it simple to detect when a frame number is erroneously reused.
>> >
>> > Otherwise, I'm largely happy to pick the rest and apply any fixups
>> > myself.
>>
>> Great thanks for your feedback!
>> I will follow your suggestion to improve my patches, then post it in a day.
>
> Thanks, that is much appreciated.
>
>> So I will rebase my patchset on arch-timer/gtdt branch of your REPO
>> https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt
>
> Yes please! The current HEAD should be:
>
> ebbfe8889cffa12f ("clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call").

Because there are some improvements on the first 4 patches, so I
fetched your gtdt branch, then rebase my v23  to the
arch-timer/cleanup

Thanks for your help! :-)

>
> Thanks,
> Mark.



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

* [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
@ 2017-03-31 17:55             ` Fu Wei
  0 siblings, 0 replies; 113+ messages in thread
From: Fu Wei @ 2017-03-31 17:55 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark,

On 28 March 2017 at 22:53, Mark Rutland <mark.rutland@arm.com> wrote:
> Hi,
>
> On Tue, Mar 28, 2017 at 10:29:10PM +0800, Fu Wei wrote:
>> On 28 March 2017 at 21:05, Mark Rutland <mark.rutland@arm.com> wrote:
>> > Sorry for the delay; I have not had the time to focus on this as I would
>> > like to. I'm happy with patches 1-4, but from patch 5 onwards, there's
>> > one change I'd like to see.
>> >
>> > I'd prefer that mmio timer frame rame N was always stored at
>> > arch_timer_mem::frame[N], rather than arch_timer_mem::frame[] being in
>> > an arbitrary order. That will make arch_timer_mem_frame::frame_nr
>> > redundant.
>> >
>> > To allow arch_timer_mem::frame[] this to be sparse, I'm happy to have a
>> > bool arch_timer_mem_frame::valid field that we set when probing each
>> > frame. Then we don't need arch_timer_mem::num_frames.
>> >
>> > This will make iterating over the frames far less confusing, and makes
>> > it simple to detect when a frame number is erroneously reused.
>> >
>> > Otherwise, I'm largely happy to pick the rest and apply any fixups
>> > myself.
>>
>> Great thanks for your feedback!
>> I will follow your suggestion to improve my patches, then post it in a day.
>
> Thanks, that is much appreciated.
>
>> So I will rebase my patchset on arch-timer/gtdt branch of your REPO
>> https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arch-timer/gtdt
>
> Yes please! The current HEAD should be:
>
> ebbfe8889cffa12f ("clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call").

Because there are some improvements on the first 4 patches, so I
fetched your gtdt branch, then rebase my v23  to the
arch-timer/cleanup

Thanks for your help! :-)

>
> Thanks,
> Mark.



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat

^ permalink raw reply	[flat|nested] 113+ messages in thread

end of thread, other threads:[~2017-03-31 17:55 UTC | newest]

Thread overview: 113+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-21 16:31 [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer fu.wei-QSEj5FYQhm4dnm+yROfE0A
2017-03-21 16:31 ` fu.wei at linaro.org
2017-03-21 16:31 ` fu.wei
2017-03-21 16:31 ` [PATCH v22 01/11] clocksource: arm_arch_timer: introduce a wrapper function to get the frequency from mmio fu.wei
2017-03-21 16:31   ` fu.wei at linaro.org
2017-03-21 16:31 ` [PATCH v22 02/11] clocksource: arm_arch_timer: separate out device-tree code and remove arch_timer_detect_rate fu.wei
2017-03-21 16:31   ` fu.wei at linaro.org
2017-03-28 14:58   ` Daniel Lezcano
2017-03-28 14:58     ` Daniel Lezcano
2017-03-28 14:58     ` Daniel Lezcano
2017-03-29  3:41     ` Fu Wei
2017-03-29  3:41       ` Fu Wei
2017-03-29  3:41       ` Fu Wei
2017-03-29  5:11       ` Fu Wei
2017-03-29  5:11         ` Fu Wei
2017-03-29  5:11         ` Fu Wei
     [not found]         ` <CADyBb7tzJAuvG73v6ZoBVO4ehCC3RMsc1pq5gKF2eQ94j6GXrg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-03-29 14:41           ` Daniel Lezcano
2017-03-29 14:41             ` Daniel Lezcano
2017-03-29 14:41             ` Daniel Lezcano
2017-03-29 15:01             ` Fu Wei
2017-03-29 15:01               ` Fu Wei
2017-03-29 15:01               ` Fu Wei
2017-03-21 16:31 ` [PATCH v22 03/11] clocksource: arm_arch_timer: refactor arch_timer_needs_probing fu.wei
2017-03-21 16:31   ` fu.wei at linaro.org
2017-03-28 15:02   ` Daniel Lezcano
2017-03-28 15:02     ` Daniel Lezcano
2017-03-28 15:02     ` Daniel Lezcano
2017-03-29 15:24     ` Mark Rutland
2017-03-29 15:24       ` Mark Rutland
2017-03-29 15:32       ` Daniel Lezcano
2017-03-29 15:32         ` Daniel Lezcano
2017-03-29 15:32         ` Daniel Lezcano
2017-03-21 16:31 ` [PATCH v22 05/11] clocksource: arm_arch_timer: introduce some new structs to prepare for GTDT fu.wei
2017-03-21 16:31   ` fu.wei at linaro.org
     [not found] ` <20170321163122.9183-1-fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2017-03-21 16:31   ` [PATCH v22 04/11] clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call fu.wei-QSEj5FYQhm4dnm+yROfE0A
2017-03-21 16:31     ` fu.wei at linaro.org
2017-03-21 16:31     ` fu.wei
2017-03-21 16:31   ` [PATCH v22 06/11] clocksource: arm_arch_timer: refactor MMIO timer probing fu.wei-QSEj5FYQhm4dnm+yROfE0A
2017-03-21 16:31     ` fu.wei at linaro.org
2017-03-21 16:31     ` fu.wei
2017-03-21 16:31 ` [PATCH v22 07/11] acpi/arm64: Add GTDT table parse driver fu.wei
2017-03-21 16:31   ` fu.wei at linaro.org
2017-03-28 11:35   ` Lorenzo Pieralisi
2017-03-28 11:35     ` Lorenzo Pieralisi
2017-03-29  9:48     ` Fu Wei
2017-03-29  9:48       ` Fu Wei
2017-03-29  9:48       ` Fu Wei
2017-03-29 10:21       ` Lorenzo Pieralisi
2017-03-29 10:21         ` Lorenzo Pieralisi
2017-03-29 10:21         ` Lorenzo Pieralisi
2017-03-29 10:48         ` Fu Wei
2017-03-29 10:48           ` Fu Wei
2017-03-29 10:48           ` Fu Wei
2017-03-29 11:33           ` Lorenzo Pieralisi
2017-03-29 11:33             ` Lorenzo Pieralisi
2017-03-29 11:33             ` Lorenzo Pieralisi
2017-03-29 13:42             ` Fu Wei
2017-03-29 13:42               ` Fu Wei
2017-03-29 13:42               ` Fu Wei
     [not found]               ` <CADyBb7snT+fvZYDyjUW7ZCVLX-ha4VXYBhfZsi8a3wOeYtdHkQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-03-29 16:02                 ` Lorenzo Pieralisi
2017-03-29 16:02                   ` Lorenzo Pieralisi
2017-03-29 16:02                   ` Lorenzo Pieralisi
2017-03-29 14:29     ` Fu Wei
2017-03-29 14:29       ` Fu Wei
2017-03-29 14:29       ` Fu Wei
2017-03-29 14:31       ` Fu Wei
2017-03-29 14:31         ` Fu Wei
2017-03-29 14:31         ` Fu Wei
2017-03-29 15:19         ` Lorenzo Pieralisi
2017-03-29 15:19           ` Lorenzo Pieralisi
2017-03-29 15:19           ` Lorenzo Pieralisi
2017-03-21 16:31 ` [PATCH v22 08/11] clocksource: arm_arch_timer: simplify ACPI support code fu.wei
2017-03-21 16:31   ` fu.wei at linaro.org
2017-03-21 16:31   ` fu.wei
2017-03-21 16:31 ` [PATCH v22 09/11] acpi/arm64: Add memory-mapped timer support in GTDT driver fu.wei
2017-03-21 16:31   ` fu.wei at linaro.org
     [not found]   ` <20170321163122.9183-10-fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2017-03-29 16:47     ` Lorenzo Pieralisi
2017-03-29 16:47       ` Lorenzo Pieralisi
2017-03-29 16:47       ` Lorenzo Pieralisi
2017-03-30  7:54       ` Fu Wei
2017-03-30  7:54         ` Fu Wei
2017-03-30  7:54         ` Fu Wei
2017-03-21 16:31 ` [PATCH v22 10/11] clocksource: arm_arch_timer: add GTDT support for memory-mapped timer fu.wei
2017-03-21 16:31   ` fu.wei at linaro.org
2017-03-21 16:31 ` [PATCH v22 11/11] acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver fu.wei
2017-03-21 16:31   ` fu.wei at linaro.org
2017-03-21 16:31   ` fu.wei
2017-03-28 15:41   ` Lorenzo Pieralisi
2017-03-28 15:41     ` Lorenzo Pieralisi
2017-03-28 15:41     ` Lorenzo Pieralisi
2017-03-31  8:10     ` Fu Wei
2017-03-31  8:10       ` Fu Wei
2017-03-31  8:10       ` Fu Wei
2017-03-31 11:54       ` Lorenzo Pieralisi
2017-03-31 11:54         ` Lorenzo Pieralisi
2017-03-31 11:54         ` Lorenzo Pieralisi
2017-03-28 11:32 ` [PATCH v22 00/11] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer Jon Masters
2017-03-28 11:32   ` Jon Masters
2017-03-28 12:34   ` Fu Wei
2017-03-28 12:34     ` Fu Wei
2017-03-28 12:34     ` Fu Wei
2017-03-28 13:05     ` Mark Rutland
2017-03-28 13:05       ` Mark Rutland
2017-03-28 13:05       ` Mark Rutland
2017-03-28 14:29       ` Fu Wei
2017-03-28 14:29         ` Fu Wei
2017-03-28 14:29         ` Fu Wei
2017-03-28 14:53         ` Mark Rutland
2017-03-28 14:53           ` Mark Rutland
2017-03-28 14:53           ` Mark Rutland
2017-03-31 17:55           ` Fu Wei
2017-03-31 17:55             ` Fu Wei
2017-03-31 17:55             ` Fu Wei

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.