diff mbox

[v16,06/15] clocksource/drivers/arm_arch_timer: separate out arch_timer_uses_ppi init code to prepare for GTDT.

Message ID 1479304148-2965-7-git-send-email-fu.wei@linaro.org (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

fu.wei@linaro.org Nov. 16, 2016, 1:48 p.m. UTC
From: Fu Wei <fu.wei@linaro.org>

The patch refactor original arch_timer_uses_ppi init code:
(1) Extract a subfunction: arch_timer_uses_ppi_init
(2) Use the new subfunction in arch_timer_of_init and
arch_timer_acpi_init

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

Comments

Mark Rutland Nov. 18, 2016, 7:30 p.m. UTC | #1
On Wed, Nov 16, 2016 at 09:48:59PM +0800, fu.wei@linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> The patch refactor original arch_timer_uses_ppi init code:
> (1) Extract a subfunction: arch_timer_uses_ppi_init
> (2) Use the new subfunction in arch_timer_of_init and
> arch_timer_acpi_init

This isn't a strict refactoring, since this now assigns
ARCH_TIMER_PHYS_NONSECURE_PPI to arch_timer_uses_ppi, which we didn't do
previously.

As a general note, please write your commit messages as prose rather
than a list of bullet points. Please also explain the rationale for the
change, rather than enumerating the changes. Call out things which are
important and/or likely to surprise reviewers, for example:

* Can 32-bit ARM still use non-secure interrupts afer this change?

* Does the "arm,cpu-registers-not-fw-configured"  proeprty still work?

That will make it vastly easier to have this code reviewed, and it will
be far more helpful for anyone looking at this in future.

For example:

  arm_arch_timer: rework PPI determination

  Currently, the arch timer driver uses ARCH_TIMER_PHYS_SECURE_PPI to
  mean the driver will use the secure PPI *and* potentialy also use the
  non-secure PPI. This is somewhat confusing.

  For arm64, where it never makes sense to use the secure PPI, this
  means we must always request the useless secure PPI, adding to the
  confusion. For ACPI, where we may not even have a valid secure PPI
  number, this is additionally problematic. We need the driver to be
  able to use *only* the non-secure PPI.

  The logic to choose which PPI to use is intertwined with other logic
  in arch_timer_init(). This patch factors the PPI determination out
  into a new function, and then reworks it so that we can handle having
  only a non-secure PPI.

[...]

> +/*
> + * If HYP mode is available, we know that the physical timer
> + * has been configured to be accessible from PL1. Use it, so
> + * that a guest can use the virtual timer instead.
> + *
> + * If no interrupt provided for virtual timer, we'll have to
> + * stick to the physical timer. It'd better be accessible...
> + * On ARM64, we we only use ARCH_TIMER_PHYS_NONSECURE_PPI in Linux.

It would be better to say that for arm64 we never use the secure
interrupt.

> + *
> + * On ARMv8.1 with VH extensions, the kernel runs in HYP. VHE
> + * accesses to CNTP_*_EL1 registers are silently redirected to
> + * their CNTHP_*_EL2 counterparts, and use a different PPI
> + * number.
> + */
> +static int __init arch_timer_uses_ppi_init(void)

It would be better to call this something like arch_timer_select_ppi().
As it stands, the name is difficult to read.

> @@ -902,6 +904,10 @@ static int __init arch_timer_of_init(struct device_node *np)
>  	    of_property_read_bool(np, "arm,cpu-registers-not-fw-configured"))
>  		arch_timer_uses_ppi = ARCH_TIMER_PHYS_SECURE_PPI;
>  
> +	ret = arch_timer_uses_ppi_init();
> +	if (ret)
> +		return ret;

This is clearly broken if you consider what the statement above is
doing.

Thanks,
Mark.
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
fu.wei@linaro.org Nov. 21, 2016, 9:45 a.m. UTC | #2
Hi Mark,

On 19 November 2016 at 03:30, Mark Rutland <mark.rutland@arm.com> wrote:
> On Wed, Nov 16, 2016 at 09:48:59PM +0800, fu.wei@linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> The patch refactor original arch_timer_uses_ppi init code:
>> (1) Extract a subfunction: arch_timer_uses_ppi_init
>> (2) Use the new subfunction in arch_timer_of_init and
>> arch_timer_acpi_init
>
> This isn't a strict refactoring, since this now assigns
> ARCH_TIMER_PHYS_NONSECURE_PPI to arch_timer_uses_ppi, which we didn't do
> previously.
>
> As a general note, please write your commit messages as prose rather
> than a list of bullet points. Please also explain the rationale for the
> change, rather than enumerating the changes. Call out things which are
> important and/or likely to surprise reviewers, for example:
>
> * Can 32-bit ARM still use non-secure interrupts afer this change?
>
> * Does the "arm,cpu-registers-not-fw-configured"  proeprty still work?
>
> That will make it vastly easier to have this code reviewed, and it will
> be far more helpful for anyone looking at this in future.
>
> For example:
>
>   arm_arch_timer: rework PPI determination
>
>   Currently, the arch timer driver uses ARCH_TIMER_PHYS_SECURE_PPI to
>   mean the driver will use the secure PPI *and* potentialy also use the
>   non-secure PPI. This is somewhat confusing.
>
>   For arm64, where it never makes sense to use the secure PPI, this
>   means we must always request the useless secure PPI, adding to the
>   confusion. For ACPI, where we may not even have a valid secure PPI
>   number, this is additionally problematic. We need the driver to be
>   able to use *only* the non-secure PPI.
>
>   The logic to choose which PPI to use is intertwined with other logic
>   in arch_timer_init(). This patch factors the PPI determination out
>   into a new function, and then reworks it so that we can handle having
>   only a non-secure PPI.

Great thanks for your example, will use this,  :-)

maybe add :
For ARM32, it still can use non-secure interrupts after this change, and
the "arm,cpu-registers-not-fw-configured"  property still works.

>
> [...]
>
>> +/*
>> + * If HYP mode is available, we know that the physical timer
>> + * has been configured to be accessible from PL1. Use it, so
>> + * that a guest can use the virtual timer instead.
>> + *
>> + * If no interrupt provided for virtual timer, we'll have to
>> + * stick to the physical timer. It'd better be accessible...
>> + * On ARM64, we we only use ARCH_TIMER_PHYS_NONSECURE_PPI in Linux.
>
> It would be better to say that for arm64 we never use the secure
> interrupt.

For ARM64, we never use the secure interrupt, so it will be set to
ARCH_TIMER_PHYS_NONSECURE_PPI instead.

>
>> + *
>> + * On ARMv8.1 with VH extensions, the kernel runs in HYP. VHE
>> + * accesses to CNTP_*_EL1 registers are silently redirected to
>> + * their CNTHP_*_EL2 counterparts, and use a different PPI
>> + * number.
>> + */
>> +static int __init arch_timer_uses_ppi_init(void)
>
> It would be better to call this something like arch_timer_select_ppi().
> As it stands, the name is difficult to read.

Yes, good idea, will do

>
>> @@ -902,6 +904,10 @@ static int __init arch_timer_of_init(struct device_node *np)
>>           of_property_read_bool(np, "arm,cpu-registers-not-fw-configured"))
>>               arch_timer_uses_ppi = ARCH_TIMER_PHYS_SECURE_PPI;
>>
>> +     ret = arch_timer_uses_ppi_init();
>> +     if (ret)
>> +             return ret;
>
> This is clearly broken if you consider what the statement above is
> doing.

Maybe I misunderstand this, I tried to follow the original logic.

Are you saying: we should use arch_timer_select_ppi() first,
then (maybe) change arch_timer_uses_ppi according to
"arm,cpu-registers-not-fw-configured"?

Please correct me, if I misunderstand this.

>
> Thanks,
> Mark.
diff mbox

Patch

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 6de164f..af22953 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -821,40 +821,42 @@  static int __init arch_timer_common_init(void)
 	return arch_timer_arch_init();
 }
 
-static int __init arch_timer_init(void)
+/*
+ * If HYP mode is available, we know that the physical timer
+ * has been configured to be accessible from PL1. Use it, so
+ * that a guest can use the virtual timer instead.
+ *
+ * If no interrupt provided for virtual timer, we'll have to
+ * stick to the physical timer. It'd better be accessible...
+ * On ARM64, we we only use ARCH_TIMER_PHYS_NONSECURE_PPI in Linux.
+ *
+ * On ARMv8.1 with VH extensions, the kernel runs in HYP. VHE
+ * accesses to CNTP_*_EL1 registers are silently redirected to
+ * their CNTHP_*_EL2 counterparts, and use a different PPI
+ * number.
+ */
+static int __init arch_timer_uses_ppi_init(void)
 {
-	int ret;
-	/*
-	 * If HYP mode is available, we know that the physical timer
-	 * has been configured to be accessible from PL1. Use it, so
-	 * that a guest can use the virtual timer instead.
-	 *
-	 * If no interrupt provided for virtual timer, we'll have to
-	 * stick to the physical timer. It'd better be accessible...
-	 *
-	 * On ARMv8.1 with VH extensions, the kernel runs in HYP. VHE
-	 * accesses to CNTP_*_EL1 registers are silently redirected to
-	 * their CNTHP_*_EL2 counterparts, and use a different PPI
-	 * number.
-	 */
-	if (is_hyp_mode_available() || !arch_timer_ppi[ARCH_TIMER_VIRT_PPI]) {
-		bool has_ppi;
-
-		if (is_kernel_in_hyp_mode()) {
-			arch_timer_uses_ppi = ARCH_TIMER_HYP_PPI;
-			has_ppi = !!arch_timer_ppi[ARCH_TIMER_HYP_PPI];
-		} else {
+	if (is_hyp_mode_available() && is_kernel_in_hyp_mode()) {
+		arch_timer_uses_ppi = ARCH_TIMER_HYP_PPI;
+	} else if (!arch_timer_ppi[ARCH_TIMER_VIRT_PPI]) {
+		if (IS_ENABLED(CONFIG_ARM64))
+			arch_timer_uses_ppi = ARCH_TIMER_PHYS_NONSECURE_PPI;
+		else
 			arch_timer_uses_ppi = ARCH_TIMER_PHYS_SECURE_PPI;
-			has_ppi = (!!arch_timer_ppi[ARCH_TIMER_PHYS_SECURE_PPI] ||
-				   !!arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]);
-		}
-
-		if (!has_ppi) {
-			pr_warn("No interrupt available, giving up\n");
-			return -EINVAL;
-		}
 	}
 
+	if (arch_timer_ppi[arch_timer_uses_ppi])
+		return 0;
+
+	pr_warn("No interrupt available, giving up\n");
+	return -EINVAL;
+}
+
+static int __init arch_timer_init(void)
+{
+	int ret;
+
 	ret = arch_timer_register();
 	if (ret)
 		return ret;
@@ -870,7 +872,7 @@  static int __init arch_timer_init(void)
 
 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");
@@ -902,6 +904,10 @@  static int __init arch_timer_of_init(struct device_node *np)
 	    of_property_read_bool(np, "arm,cpu-registers-not-fw-configured"))
 		arch_timer_uses_ppi = ARCH_TIMER_PHYS_SECURE_PPI;
 
+	ret = arch_timer_uses_ppi_init();
+	if (ret)
+		return ret;
+
 	return arch_timer_init();
 }
 CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init);
@@ -1011,6 +1017,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) {
@@ -1041,6 +1048,10 @@  static int __init arch_timer_acpi_init(struct acpi_table_header *table)
 	/* Get the frequency from CNTFRQ */
 	arch_timer_detect_rate(NULL, NULL);
 
+	ret = arch_timer_uses_ppi_init();
+	if (ret)
+		return ret;
+
 	/* Always-on capability */
 	arch_timer_c3stop = !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON);