Skip to contentSkip to conversation

hwmon: xgene: Add support for X-Gene hwmon driver

PATCH Applied Hoan Tran 6 participants 32 messages Jul 21, 2016 – Sep 9, 2016

Subsystems (5)

v3 of 4 Applied Latest is v4 →

lore
Share & tools
lore

Hoan Tran

author
#0 lore raw

v3 cover hwmon: xgene: Add support for X-Gene hwmon driver

This patch set adds hardware temperature and power reading support for APM X-Gene SoC using the mailbox communication interface. For device tree, it is the standard DT mailbox.
For ACPI, it is the PCC mailbox.

For ACPI, this patch is built on top and depends on patch[1]:
[1] http://www.spinics.net/lists/linux-acpi/msg66041.html
- [PATCH v3] mailbox: pcc: Support HW-Reduced Communication Subspace type 2

v3
- Order include files alphabetically
- Use sign_extend32() to decode temperature
- Use DEVICE_ATTR_RO() for temperature and power attributes
- Temperature and power attributes start with index 1
- Use !!amsg->param2
- Fix checkpatch WARNING with --strict flag
- Use hwmon_device_register_with_groups()
- Check invalid sensor data

v2
- Increase power reading accurateness by using 2 registers
(a register for Watt, another for milli-Watt)
- Remove power reading for SoC
- Fix review comments from Guenter

v1
- Initial

Hoan Tran (3):
Documentation: dtb: xgene: Add hwmon dts binding documentation
hwmon: xgene: Add hwmon driver
arm64: dts: apm: Add X-Gene SoC hwmon to device tree

 .../devicetree/bindings/hwmon/apm-xgene-hwmon.txt  |  14 +
 Documentation/hwmon/xgene-hwmon                    |  30 +
 arch/arm64/boot/dts/apm/apm-shadowcat.dtsi         |   5 +
 arch/arm64/boot/dts/apm/apm-storm.dtsi             |   5 +
 drivers/hwmon/Kconfig                              |   7 +
 drivers/hwmon/Makefile                             |   1 +
 drivers/hwmon/xgene-hwmon.c                        | 755 +++++++++++++++++++++
 7 files changed, 817 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwmon/apm-xgene-hwmon.txt
 create mode 100644 Documentation/hwmon/xgene-hwmon
 create mode 100644 drivers/hwmon/xgene-hwmon.c
Signature · 1 line
1.9.1
author
#1 lore raw

PATCH v3 1/3 Documentation: dtb: xgene: Add hwmon dts binding documentation

This patch adds the APM X-Gene hwmon device tree node documentation.

---
 .../devicetree/bindings/hwmon/apm-xgene-hwmon.txt          | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwmon/apm-xgene-hwmon.txt
Documentation/devicetree/bindings/hwmon/apm-xgene-hwmon.txt new file +14 -0
new file mode 100644
index 0000000..59b3855
@@ -0,0 +1,14 @@
+APM X-Gene hwmon driver
+
+APM X-Gene SOC sensors are accessed over the "SLIMpro" mailbox.
+
+Required properties :
+ - compatible : should be "apm,xgene-slimpro-hwmon"
+ - mboxes : use the label reference for the mailbox as the first parameter.
+	    The second parameter is the channel number.
+
+Example :
+	hwmonslimpro {
+		compatible = "apm,xgene-slimpro-hwmon";
+		mboxes = <&mailbox 7>;
+	};
Signature · 1 line
1.9.1
author
#3 lore raw

PATCH v3 2/3 hwmon: xgene: Add hwmon driver

In reply to Hoan Tran

This patch adds hardware temperature and power reading support for APM X-Gene SoC using the mailbox communication interface.

---
 Documentation/hwmon/xgene-hwmon |  30 ++
 drivers/hwmon/Kconfig           |   7 +
 drivers/hwmon/Makefile          |   1 +
 drivers/hwmon/xgene-hwmon.c     | 755 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 793 insertions(+)
 create mode 100644 Documentation/hwmon/xgene-hwmon
 create mode 100644 drivers/hwmon/xgene-hwmon.c
Documentation/hwmon/xgene-hwmon new file +30 -0
new file mode 100644
index 0000000..6ec50ed
@@ -0,0 +1,30 @@
+Kernel driver xgene-hwmon
+========================
+
+Supported chips:
+ * APM X-Gene SoC
+
+Description
+-----------
+
+This driver adds hardware temperature and power reading support for
+APM X-Gene SoC using the mailbox communication interface.
+For device tree, it is the standard DT mailbox.
+For ACPI, it is the PCC mailbox.
+
+The following sensors are supported
+
+  * Temperature
+    - SoC on-die temperature in milli-degree C
+    - Alarm when high/over temperature occurs
+  * Power
+    - CPU power in uW
+    - IO power in uW
+
+sysfs-Interface
+---------------
+
+temp0_input - SoC on-die temperature (milli-degree C)
+temp0_critical_alarm - An 1 would indicates on-die temperature exceeded threshold
+power0_input - CPU power in (uW)
+power1_input - IO power in (uW)
drivers/hwmon/Kconfig +7 -0
index ff94007..55218c6 100644
@@ -1787,6 +1787,13 @@ config SENSORS_ULTRA45
 	  This driver provides support for the Ultra45 workstation environmental
 	  sensors.
 
+config SENSORS_XGENE
+	tristate "APM X-Gene SoC hardware monitoring driver"
+	depends on XGENE_SLIMPRO_MBOX || PCC
+	help
+	  If you say yes here you get support for the temperature
+	  and power sensors for APM X-Gene SoC.
+
 if ACPI
 
 comment "ACPI drivers"
drivers/hwmon/Makefile +1 -0
index 2ef5b7c..a2460dd 100644
@@ -162,6 +162,7 @@ obj-$(CONFIG_SENSORS_W83L785TS)	+= w83l785ts.o
 obj-$(CONFIG_SENSORS_W83L786NG)	+= w83l786ng.o
 obj-$(CONFIG_SENSORS_WM831X)	+= wm831x-hwmon.o
 obj-$(CONFIG_SENSORS_WM8350)	+= wm8350-hwmon.o
+obj-$(CONFIG_SENSORS_XGENE)	+= xgene-hwmon.o
 
 obj-$(CONFIG_PMBUS)		+= pmbus/
 
drivers/hwmon/xgene-hwmon.c new file +755 -0

755 lines not on this page · raw message

Signature · 1 line
1.9.1
maintainer Reviewed-by on v3 2/3
#4 lore raw

Re: [PATCH v3 2/3] hwmon: xgene: Add hwmon driver

Quoted 5 lines · Hoan Tran

This patch adds hardware temperature and power reading support for APM X-Gene SoC using the mailbox communication interface.

---

[ ... ]

drivers/hwmon/xgene-hwmon.c line 703

Quoted 5 lines
drivers/hwmon/xgene-hwmon.c new file +5 -0
+
+	dev_info(&pdev->dev, "APM X-Gene SoC HW monitor driver registered\n");
+
+	return rc;
+

Nitpick: rc == 0 here, so return 0; is a better choice. Otherwise looks good.

Note that I can not apply the patch at this time due to its dependency.

Guenter

author
#5 lore raw

Re: [PATCH v3 2/3] hwmon: xgene: Add hwmon driver

Hi Guenter,

Quoted 9 lines · Guenter Roeck
Quoted 5 lines · Hoan Tran

This patch adds hardware temperature and power reading support for APM X-Gene SoC using the mailbox communication interface.

---

[ ... ]

Quoted 8 lines

drivers/hwmon/xgene-hwmon.c line 703

Quoted 5 lines
drivers/hwmon/xgene-hwmon.c new file +5 -0
+
+     dev_info(&pdev->dev, "APM X-Gene SoC HW monitor driver registered\n");
+
+     return rc;
+

Nitpick: rc == 0 here, so return 0; is a better choice. Otherwise looks good.

Yes, I'll fix it then send v4 shortly.

Quoted 4 lines

Note that I can not apply the patch at this time due to its dependency.

Thanks ! I'll let you know when Rafael applies that dependent patch into linux-next.

Thanks
Hoan

Quoted 2 lines

Guenter

#6 lore raw

Re: [PATCH v3 2/3] hwmon: xgene: Add hwmon driver

In reply to Hoan Tran
reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree…

Hi Hoan,

[auto build test ERROR on hwmon/hwmon-next]
[also build test ERROR on v4.7]
[cannot apply to next-20160801]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Hoan-Tran/hwmon-xgene-Add-support-for-X-Gene-hwmon-driver/20160725-015356
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
config: arm64-allmodconfig (attached as .config)
compiler: aarch64-linux-gnu-gcc (Debian 5.4.0-6) 5.4.0 20160609

reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm64

All errors (new ones prefixed by >>):

>> drivers/hwmon/xgene-hwmon.c:38:22: fatal error: acpi/pcc.h: No such file or directory

compilation terminated.

vim +38 drivers/hwmon/xgene-hwmon.c

32 #include <linux/mailbox_controller.h>
33 #include <linux/mailbox_client.h>
34 #include <linux/module.h>
35 #include <linux/of.h>
36 #include <linux/platform_device.h>
37 #include <acpi/acpi_io.h>

  > 38	#include <acpi/pcc.h>
    39	
    40	/* SLIMpro message defines */
    41	#define MSG_TYPE_DBG			0

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/octet-stream
Size: 50305 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160801/b7c0a236/attachment-0001.obj>

author
#7 lore raw

Re: [PATCH v3 2/3] hwmon: xgene: Add hwmon driver

Hi,

Quoted 17 lines · kbuild test robot

Hi Hoan,

[auto build test ERROR on hwmon/hwmon-next]
[also build test ERROR on v4.7]
[cannot apply to next-20160801]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Hoan-Tran/hwmon-xgene-Add-support-for-X-Gene-hwmon-driver/20160725-015356
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
config: arm64-allmodconfig (attached as .config)
compiler: aarch64-linux-gnu-gcc (Debian 5.4.0-6) 5.4.0 20160609

reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm64

Quoted 4 lines

All errors (new ones prefixed by >>):

Quoted 1 line
Quoted 1 line

drivers/hwmon/xgene-hwmon.c:38:22: fatal error: acpi/pcc.h: No such file or directory

compilation terminated.

This driver should be built with kernel 4.8 and above where the "pcc.h" file is available.

Thanks
Hoan

Quoted 17 lines

vim +38 drivers/hwmon/xgene-hwmon.c

    32  #include <linux/mailbox_controller.h>
    33  #include <linux/mailbox_client.h>
    34  #include <linux/module.h>
    35  #include <linux/of.h>
    36  #include <linux/platform_device.h>
    37  #include <acpi/acpi_io.h>
  > 38  #include <acpi/pcc.h>

39
40 /* SLIMpro message defines */
41 #define MSG_TYPE_DBG 0

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation

#8 lore raw

Re: [PATCH v3 2/3] hwmon: xgene: Add hwmon driver

In reply to Hoan Tran

drivers/hwmon/xgene-hwmon.c line 657

Quoted 6 lines · CEST Hoan Tran
drivers/hwmon/xgene-hwmon.c new file +5 -0
+               ctx->comm_base_addr = cppc_ss->base_address;
+               if (ctx->comm_base_addr) {
+                       ctx->pcc_comm_addr =
+                                       acpi_os_ioremap(ctx->comm_base_addr,
+                                                       cppc_ss->length);

This causes the arm64 allmodconfig build to fail now, according to kernelci:

1 ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

Should this perhaps call ioremap() or memremap() instead?

Arnd

maintainer
#9 lore raw

Re: [PATCH v3 2/3] hwmon: xgene: Add hwmon driver

Quoted 8 lines · Arnd Bergmann

drivers/hwmon/xgene-hwmon.c line 657

Quoted 6 lines · CEST Hoan Tran
drivers/hwmon/xgene-hwmon.c new file +5 -0
+               ctx->comm_base_addr = cppc_ss->base_address;
+               if (ctx->comm_base_addr) {
+                       ctx->pcc_comm_addr =
+                                       acpi_os_ioremap(ctx->comm_base_addr,
+                                                       cppc_ss->length);
Quoted 5 lines

This causes the arm64 allmodconfig build to fail now, according to kernelci:

1 ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

How do you even get there ? arm64:allmodconfig fails for me in -next with

drivers/pwm/pwm-berlin.c: In function ?berlin_pwm_suspend?:
drivers/pwm/pwm-berlin.c:245:35: error: ?struct berlin_pwm_chip? has no member named ?chips?

Guenter

#10 lore raw

Re: [PATCH v3 2/3] hwmon: xgene: Add hwmon driver

Quoted 12 lines · CEST Guenter Roeck
Quoted 11 lines · Arnd Bergmann

drivers/hwmon/xgene-hwmon.c line 657

Quoted 6 lines · CEST Hoan Tran
drivers/hwmon/xgene-hwmon.c new file +5 -0
+               ctx->comm_base_addr = cppc_ss->base_address;
+               if (ctx->comm_base_addr) {
+                       ctx->pcc_comm_addr =
+                                       acpi_os_ioremap(ctx->comm_base_addr,
+                                                       cppc_ss->length);

This causes the arm64 allmodconfig build to fail now, according to kernelci:

Quoted 6 lines
Quoted 2 lines

1 ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

How do you even get there ? arm64:allmodconfig fails for me in -next with

drivers/pwm/pwm-berlin.c: In function ?berlin_pwm_suspend?:
drivers/pwm/pwm-berlin.c:245:35: error: ?struct berlin_pwm_chip? has no member named ?chips?

That was fixed in yesterday's linux-next.

Arnd

maintainer
#11 lore raw

Re: [PATCH v3 2/3] hwmon: xgene: Add hwmon driver

Quoted 13 lines · Arnd Bergmann
Quoted 12 lines · CEST Guenter Roeck
Quoted 11 lines · Arnd Bergmann

drivers/hwmon/xgene-hwmon.c line 657

Quoted 6 lines · CEST Hoan Tran
drivers/hwmon/xgene-hwmon.c new file +5 -0
+               ctx->comm_base_addr = cppc_ss->base_address;
+               if (ctx->comm_base_addr) {
+                       ctx->pcc_comm_addr =
+                                       acpi_os_ioremap(ctx->comm_base_addr,
+                                                       cppc_ss->length);

This causes the arm64 allmodconfig build to fail now, according to kernelci:

Quoted 9 lines
Quoted 6 lines
Quoted 2 lines

1 ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

How do you even get there ? arm64:allmodconfig fails for me in -next with

drivers/pwm/pwm-berlin.c: In function ?berlin_pwm_suspend?:
drivers/pwm/pwm-berlin.c:245:35: error: ?struct berlin_pwm_chip? has no member named ?chips?

That was fixed in yesterday's linux-next.

Maybe, but now I get

Building arm:allmodconfig ... failed
--------------
Error log:
crypto/crypto_engine.c: In function 'crypto_transfer_hash_request':
crypto/crypto_engine.c:234:3: error: implicit declaration of function 'queue_kthread_work'

Building arm64:allmodconfig ... failed
--------------
Error log:
arch/arm64/kvm/../../../virt/kvm/arm/arch_timer.c: In function ?kvm_timer_hyp_init?:
arch/arm64/kvm/../../../virt/kvm/arm/arch_timer.c:457:1: warning: label ?out_free? defined but not used

Guenter

#12 lore raw

Re: [PATCH v3 2/3] hwmon: xgene: Add hwmon driver

Quoted 8 lines · CEST Guenter Roeck

Maybe, but now I get

Building arm:allmodconfig ... failed
--------------
Error log:
crypto/crypto_engine.c: In function 'crypto_transfer_hash_request':
crypto/crypto_engine.c:234:3: error: implicit declaration of function 'queue_kthread_work'

Quoted 5 lines

Building arm64:allmodconfig ... failed
--------------
Error log:
arch/arm64/kvm/../../../virt/kvm/arm/arch_timer.c: In function ?kvm_timer_hyp_init?:
arch/arm64/kvm/../../../virt/kvm/arm/arch_timer.c:457:1: warning: label ?out_free? defined but not used

Right, I sent fixes for both. I think we had a clean build yesterday, probably tomorrow those will both be fixed.

The time between -rc5 and -rc7 seems to be the worst for build testing ;-)

Arnd

maintainer
#13 lore raw

Re: [PATCH v3 2/3] hwmon: xgene: Add hwmon driver

In reply to Arnd Bergmann
Quoted 8 lines · Arnd Bergmann

drivers/hwmon/xgene-hwmon.c line 657

Quoted 6 lines · CEST Hoan Tran
drivers/hwmon/xgene-hwmon.c new file +5 -0
+               ctx->comm_base_addr = cppc_ss->base_address;
+               if (ctx->comm_base_addr) {
+                       ctx->pcc_comm_addr =
+                                       acpi_os_ioremap(ctx->comm_base_addr,
+                                                       cppc_ss->length);
Quoted 7 lines

This causes the arm64 allmodconfig build to fail now, according to kernelci:

1 ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

Should this perhaps call ioremap() or memremap() instead?

Hmmm ... almost sounds to me like blaming the messenger. e7cd190385d1 ("arm64:
mark reserved memblock regions explicitly in iomem") starts using a function in acpi_os_ioremap() which is not exported. On top of that, memblock_is_memory() is declared as __init_memblock, which makes me really uncomfortable. If acpi_os_ioremap() must not be used by modules, and possibly only during early (?) initialization, maybe its declaration should state those limitations ?

Thanks,
Guenter

#14 lore raw

Re: [PATCH v3 2/3] hwmon: xgene: Add hwmon driver

Quoted 14 lines · CEST Guenter Roeck
Quoted 13 lines · Arnd Bergmann

drivers/hwmon/xgene-hwmon.c line 657

Quoted 6 lines · CEST Hoan Tran
drivers/hwmon/xgene-hwmon.c new file +5 -0
+               ctx->comm_base_addr = cppc_ss->base_address;
+               if (ctx->comm_base_addr) {
+                       ctx->pcc_comm_addr =
+                                       acpi_os_ioremap(ctx->comm_base_addr,
+                                                       cppc_ss->length);

This causes the arm64 allmodconfig build to fail now, according to kernelci:

1 ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

Quoted 8 lines
Quoted 2 lines

Should this perhaps call ioremap() or memremap() instead?

Hmmm ... almost sounds to me like blaming the messenger. e7cd190385d1 ("arm64:
mark reserved memblock regions explicitly in iomem") starts using a function in acpi_os_ioremap() which is not exported. On top of that, memblock_is_memory() is declared as __init_memblock, which makes me really uncomfortable. If acpi_os_ioremap() must not be used by modules, and possibly only during early (?) initialization, maybe its declaration should state those limitations ?

Ah, I didn't notice that. I guess both patches were correct individually and got added to linux-next around the same time but caused allmodconfig to blow up when used together.

Adding everyone who was involved in the memblock patch to Cc here, maybe one of them has an idea what the correct fix is. There are only two other drivers using acpi_os_ioremap() and one of them is x86-specific, so it's still likely that drivers are not actually supposed to use this symbol. Making acpi_os_ioremap() an exported function in arm64 would also work.

Arnd

#15 lore raw

Re: [PATCH v3 2/3] hwmon: xgene: Add hwmon driver

Hi,

Quoted 28 lines · Arnd Bergmann
Quoted 14 lines · CEST Guenter Roeck
Quoted 13 lines · Arnd Bergmann

drivers/hwmon/xgene-hwmon.c line 657

Quoted 6 lines · CEST Hoan Tran
drivers/hwmon/xgene-hwmon.c new file +5 -0
+               ctx->comm_base_addr = cppc_ss->base_address;
+               if (ctx->comm_base_addr) {
+                       ctx->pcc_comm_addr =
+                                       acpi_os_ioremap(ctx->comm_base_addr,
+                                                       cppc_ss->length);

This causes the arm64 allmodconfig build to fail now, according to kernelci:

1 ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

Quoted 8 lines
Quoted 2 lines

Should this perhaps call ioremap() or memremap() instead?

Hmmm ... almost sounds to me like blaming the messenger. e7cd190385d1 ("arm64:
mark reserved memblock regions explicitly in iomem") starts using a function in acpi_os_ioremap() which is not exported. On top of that, memblock_is_memory() is declared as __init_memblock, which makes me really uncomfortable. If acpi_os_ioremap() must not be used by modules, and possibly only during early (?) initialization, maybe its declaration should state those limitations ?

Ah, I didn't notice that. I guess both patches were correct individually and got added to linux-next around the same time but caused allmodconfig to blow up when used together.

Quoted 5 lines

Adding everyone who was involved in the memblock patch to Cc here, maybe one of them has an idea what the correct fix is. There are only two other drivers using acpi_os_ioremap() and one of them is x86-specific, so it's still likely that drivers are not actually supposed to use this symbol. Making acpi_os_ioremap() an exported function in arm64 would also work.

You could use acpi_os_map_iomem()/acpi_os_unmap_iomem() from acpi/acpi_io.h. If there isn't an existing mapping these end up in acpi_os_ioremap(), and are already EXPORT_SYMBOL_GPL().

(I'm still waiting for allmodconfig on linux-next to finish building)

Thanks,

James

#16 lore raw

Re: [PATCH v3 2/3] hwmon: xgene: Add hwmon driver

Quoted 37 lines · James Morse

Hi,

Quoted 28 lines · Arnd Bergmann
Quoted 14 lines · CEST Guenter Roeck
Quoted 13 lines · Arnd Bergmann

Review

Quoted 6 lines · CEST Hoan Tran
(quoted diff) +5 -0
+               ctx->comm_base_addr = cppc_ss->base_address;
+               if (ctx->comm_base_addr) {
+                       ctx->pcc_comm_addr =
+                                       acpi_os_ioremap(ctx->comm_base_addr,
+                                                       cppc_ss->length);

This causes the arm64 allmodconfig build to fail now, according to kernelci:

1 ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

Quoted 8 lines
Quoted 2 lines

Should this perhaps call ioremap() or memremap() instead?

Hmmm ... almost sounds to me like blaming the messenger. e7cd190385d1 ("arm64:
mark reserved memblock regions explicitly in iomem") starts using a function in acpi_os_ioremap() which is not exported. On top of that, memblock_is_memory() is declared as __init_memblock, which makes me really uncomfortable. If acpi_os_ioremap() must not be used by modules, and possibly only during early (?) initialization, maybe its declaration should state those limitations ?

Ah, I didn't notice that. I guess both patches were correct individually and got added to linux-next around the same time but caused allmodconfig to blow up when used together.

Quoted 5 lines

Adding everyone who was involved in the memblock patch to Cc here, maybe one of them has an idea what the correct fix is. There are only two other drivers using acpi_os_ioremap() and one of them is x86-specific, so it's still likely that drivers are not actually supposed to use this symbol. Making acpi_os_ioremap() an exported function in arm64 would also work.

Quoted 3 lines

You could use acpi_os_map_iomem()/acpi_os_unmap_iomem() from acpi/acpi_io.h. If there isn't an existing mapping these end up in acpi_os_ioremap(), and are already EXPORT_SYMBOL_GPL().

acpi_os_ioremap() is re-defined in arm64/include/asm/acpi.h.

The problem is that, as memblock_is_memory() is declared as __init, we cannot build any drivers which call acpi_os_ioremap() as modules.

As far as this specific issue is concerned, if we make a change like:

===8<===

arch/arm64/kernel/setup.c +1 -1
@@ -207,7 +207,7 @@ static void __init request_standard_resources(void)
                res = alloc_bootmem_low(sizeof(*res));
                if (memblock_is_nomap(region)) {
                        res->name  = "reserved";
-                       res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+                       res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
                } else {
                        res->name  = "System RAM";
                        res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;

===>8===

and revert the following hunk from the commit:

===8<===

arch/arm64/include/asm/acpi.h +6 -2
@@ -12,7 +12,7 @@
 #ifndef _ASM_ACPI_H
 #define _ASM_ACPI_H
 
-#include <linux/mm.h>
+#include <linux/memblock.h>
 #include <linux/psci.h>
 
 #include <asm/cputype.h>
@@ -32,7 +32,11 @@
 static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
                                            acpi_size size)
 {
-       if (!page_is_ram(phys >> PAGE_SHIFT))
+       /*
+        * EFI's reserve_regions() call adds memory with the WB attribute
+        * to memblock via early_init_dt_add_memory_arch().
+        */
+       if (!memblock_is_memory(phys))
                return ioremap(phys, size);
 
        return ioremap_cache(phys, size);
arch/arm64/kernel/setup.c +0 -0

===>8===

The build error will be gone. (and still kdump should work.)

But I don't know how we should distinguish IORESOURCE_MEM and IORESOURCE_SYSTEM_RAM.

Thanks,
-Takahiro AKASHI

Quoted 8 lines

(I'm still waiting for allmodconfig on linux-next to finish building)

Thanks,

James

#17 lore raw

Re: [PATCH v3 2/3] hwmon: xgene: Add hwmon driver

Hi,

Quoted 36 lines · AKASHI Takahiro
Quoted 35 lines · James Morse
Quoted 33 lines · Arnd Bergmann
Quoted 14 lines · CEST Guenter Roeck
Quoted 13 lines · Arnd Bergmann

Review

Quoted 6 lines · CEST Hoan Tran
(quoted diff) +5 -0
+               ctx->comm_base_addr = cppc_ss->base_address;
+               if (ctx->comm_base_addr) {
+                       ctx->pcc_comm_addr =
+                                       acpi_os_ioremap(ctx->comm_base_addr,
+                                                       cppc_ss->length);

This causes the arm64 allmodconfig build to fail now, according to kernelci:

1 ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

Quoted 8 lines
Quoted 2 lines

Should this perhaps call ioremap() or memremap() instead?

Hmmm ... almost sounds to me like blaming the messenger. e7cd190385d1 ("arm64:
mark reserved memblock regions explicitly in iomem") starts using a function in acpi_os_ioremap() which is not exported. On top of that, memblock_is_memory() is declared as __init_memblock, which makes me really uncomfortable. If acpi_os_ioremap() must not be used by modules, and possibly only during early (?) initialization, maybe its declaration should state those limitations ?

Ah, I didn't notice that. I guess both patches were correct individually and got added to linux-next around the same time but caused allmodconfig to blow up when used together.

Adding everyone who was involved in the memblock patch to Cc here, maybe one of them has an idea what the correct fix is. There are only two other drivers using acpi_os_ioremap() and one of them is x86-specific, so it's still likely that drivers are not actually supposed to use this symbol. Making acpi_os_ioremap() an exported function in arm64 would also work.

Quoted 7 lines
Quoted 3 lines

You could use acpi_os_map_iomem()/acpi_os_unmap_iomem() from acpi/acpi_io.h. If there isn't an existing mapping these end up in acpi_os_ioremap(), and are already EXPORT_SYMBOL_GPL().

acpi_os_ioremap() is re-defined in arm64/include/asm/acpi.h.

The problem is that, as memblock_is_memory() is declared as __init,

__init_memblock ...

... as is memblock_is_map_memory(), which we call from pfn_valid() which is EXPORT_SYMBOL()'d
and used from modules, (e.g. mac80211.ko). So something fishy is going on...

Quoted 8 lines

From include/linux/memblock.h:
#ifdef CONFIG_ARCH_DISCARD_MEMBLOCK
#define __init_memblock __meminit
#define __initdata_memblock __meminitdata
#else
#define __init_memblock
#define __initdata_memblock
#endif

arm64 doesn't define ARCH_DISCARD_MEMBLOCK, so we always keep these symbols. If we didn't, pfn_valid() would break too.

Thanks,

James

#18 lore raw

Re: [PATCH v3 2/3] hwmon: xgene: Add hwmon driver

In reply to Guenter Roeck
Quoted 14 lines · CEST Guenter Roeck
Quoted 13 lines · Arnd Bergmann

drivers/hwmon/xgene-hwmon.c line 657

Quoted 6 lines · CEST Hoan Tran
drivers/hwmon/xgene-hwmon.c new file +5 -0
+               ctx->comm_base_addr = cppc_ss->base_address;
+               if (ctx->comm_base_addr) {
+                       ctx->pcc_comm_addr =
+                                       acpi_os_ioremap(ctx->comm_base_addr,
+                                                       cppc_ss->length);

This causes the arm64 allmodconfig build to fail now, according to kernelci:

1 ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

Quoted 8 lines
Quoted 2 lines

Should this perhaps call ioremap() or memremap() instead?

Hmmm ... almost sounds to me like blaming the messenger. e7cd190385d1 ("arm64:
mark reserved memblock regions explicitly in iomem") starts using a function in acpi_os_ioremap() which is not exported. On top of that, memblock_is_memory() is declared as __init_memblock, which makes me really uncomfortable. If acpi_os_ioremap() must not be used by modules, and possibly only during early (?) initialization, maybe its declaration should state those limitations ?

I think there is more wrong with it, the driver also accesses a shared memory area with kernel pointers using readl_relaxed/writel_relaxed, which are only valid on MMIO registers.

I've prepared a patch, please have a look at the follow-up email.

Arnd

#19 lore raw

PATCH 1/1 hwmon: xgene: access mailbox as RAM

In reply to Guenter Roeck

The newly added hwmon driver fails to build in an allmodconfig kernel:

1 ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

According to comments in the code, the mailbox is a shared memory region, not a set of MMIO registers, so we should use memremap() for mapping it instead of ioremap or acpi_os_ioremap, and pointer dereferences instead of readl/writel.

The driver already uses plain kernel pointers, so it's a bit unusual to work with functions that operate on __iomem pointers, and this fixes that part too.

I'm using READ_ONCE/WRITE_ONCE here to keep the existing behavior regarding the ordering of the accesses from the CPU, but note that there are no barriers (also unchanged from before).

I'm also keeping the endianess behavior, though I'm unsure whether the message data was supposed to be in LE32 format in the first place, it's possible this was meant to be interpreted as a byte stream instead.

drivers/hwmon/xgene-hwmon.c +15 -14
index bc78a5d10182..e834dfb3acca 100644
@@ -34,7 +34,8 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
-#include <acpi/acpi_io.h>
+#include <linux/io.h>
+
 #include <acpi/pcc.h>
 
 /* SLIMpro message defines */
@@ -126,10 +127,10 @@ static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask)
 {
 	u16 ret, val;
 
-	val = readw_relaxed(addr);
+	val = le16_to_cpu(READ_ONCE(*addr));
 	ret = val & mask;
 	val &= ~mask;
-	writew_relaxed(val, addr);
+	WRITE_ONCE(*addr, cpu_to_le16(val));
 
 	return ret;
 }
@@ -137,7 +138,7 @@ static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask)
 static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
 {
 	struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr;
-	void *ptr = generic_comm_base + 1;
+	u32 *ptr = (void*)(generic_comm_base + 1);
 	int rc, i;
 	u16 val;
 
@@ -146,21 +147,21 @@ static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
 	ctx->resp_pending = true;
 
 	/* Write signature for subspace */
-	writel_relaxed(PCC_SIGNATURE_MASK | ctx->mbox_idx,
-		       &generic_comm_base->signature);
+	WRITE_ONCE(generic_comm_base->signature,
+		   cpu_to_le32(PCC_SIGNATURE_MASK | ctx->mbox_idx));
 
 	/* Write to the shared command region */
-	writew_relaxed(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT,
-		       &generic_comm_base->command);
+	WRITE_ONCE(generic_comm_base->command,
+		   cpu_to_le16(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT));
 
 	/* Flip CMD COMPLETE bit */
-	val = readw_relaxed(&generic_comm_base->status);
+	val = le16_to_cpu(READ_ONCE(generic_comm_base->status));
 	val &= ~PCCS_CMD_COMPLETE;
-	writew_relaxed(val, &generic_comm_base->status);
+	WRITE_ONCE(generic_comm_base->status, cpu_to_le16(val));
 
 	/* Copy the message to the PCC comm space */
 	for (i = 0; i < sizeof(struct slimpro_resp_msg) / 4; i++)
-		writel_relaxed(msg[i], ptr + i * 4);
+		WRITE_ONCE(ptr[i], cpu_to_le32(msg[i]));
 
 	/* Ring the doorbell */
 	rc = mbox_send_message(ctx->mbox_chan, msg);
@@ -652,9 +653,9 @@ static int xgene_hwmon_probe(struct platform_device *pdev)
 		 */
 		ctx->comm_base_addr = cppc_ss->base_address;
 		if (ctx->comm_base_addr) {
-			ctx->pcc_comm_addr =
-					acpi_os_ioremap(ctx->comm_base_addr,
-							cppc_ss->length);
+			ctx->pcc_comm_addr = memremap(ctx->comm_base_addr,
+							cppc_ss->length,
+							MEMREMAP_WT);
 		} else {
 			dev_err(&pdev->dev, "Failed to get PCC comm region\n");
 			rc = -ENODEV;
maintainer
#20 lore raw

Re: [PATCH] hwmon: xgene: access mailbox as RAM

Hi Arnd,

Quoted 18 lines · Arnd Bergmann

The newly added hwmon driver fails to build in an allmodconfig kernel:

1 ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

According to comments in the code, the mailbox is a shared memory region, not a set of MMIO registers, so we should use memremap() for mapping it instead of ioremap or acpi_os_ioremap, and pointer dereferences instead of readl/writel.

The driver already uses plain kernel pointers, so it's a bit unusual to work with functions that operate on __iomem pointers, and this fixes that part too.

I'm using READ_ONCE/WRITE_ONCE here to keep the existing behavior regarding the ordering of the accesses from the CPU, but note that there are no barriers (also unchanged from before).

Quoted 7 lines

I'm also keeping the endianess behavior, though I'm unsure whether the message data was supposed to be in LE32 format in the first place, it's possible this was meant to be interpreted as a byte stream instead.

Thanks a lot for looking into this.

I'll apply this patch to address the build problem. Much better than my rude "depends on BROKEN". It would be great to get a Tested-by:
from someone with access to the hardware.

Guenter

Quoted 79 lines
drivers/hwmon/xgene-hwmon.c +15 -14
index bc78a5d10182..e834dfb3acca 100644
@@ -34,7 +34,8 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
-#include <acpi/acpi_io.h>
+#include <linux/io.h>
+
 #include <acpi/pcc.h>
 
 /* SLIMpro message defines */
@@ -126,10 +127,10 @@ static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask)
 {
 	u16 ret, val;
 
-	val = readw_relaxed(addr);
+	val = le16_to_cpu(READ_ONCE(*addr));
 	ret = val & mask;
 	val &= ~mask;
-	writew_relaxed(val, addr);
+	WRITE_ONCE(*addr, cpu_to_le16(val));
 
 	return ret;
 }
@@ -137,7 +138,7 @@ static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask)
 static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
 {
 	struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr;
-	void *ptr = generic_comm_base + 1;
+	u32 *ptr = (void*)(generic_comm_base + 1);
 	int rc, i;
 	u16 val;
 
@@ -146,21 +147,21 @@ static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
 	ctx->resp_pending = true;
 
 	/* Write signature for subspace */
-	writel_relaxed(PCC_SIGNATURE_MASK | ctx->mbox_idx,
-		       &generic_comm_base->signature);
+	WRITE_ONCE(generic_comm_base->signature,
+		   cpu_to_le32(PCC_SIGNATURE_MASK | ctx->mbox_idx));
 
 	/* Write to the shared command region */
-	writew_relaxed(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT,
-		       &generic_comm_base->command);
+	WRITE_ONCE(generic_comm_base->command,
+		   cpu_to_le16(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT));
 
 	/* Flip CMD COMPLETE bit */
-	val = readw_relaxed(&generic_comm_base->status);
+	val = le16_to_cpu(READ_ONCE(generic_comm_base->status));
 	val &= ~PCCS_CMD_COMPLETE;
-	writew_relaxed(val, &generic_comm_base->status);
+	WRITE_ONCE(generic_comm_base->status, cpu_to_le16(val));
 
 	/* Copy the message to the PCC comm space */
 	for (i = 0; i < sizeof(struct slimpro_resp_msg) / 4; i++)
-		writel_relaxed(msg[i], ptr + i * 4);
+		WRITE_ONCE(ptr[i], cpu_to_le32(msg[i]));
 
 	/* Ring the doorbell */
 	rc = mbox_send_message(ctx->mbox_chan, msg);
@@ -652,9 +653,9 @@ static int xgene_hwmon_probe(struct platform_device *pdev)
 		 */
 		ctx->comm_base_addr = cppc_ss->base_address;
 		if (ctx->comm_base_addr) {
-			ctx->pcc_comm_addr =
-					acpi_os_ioremap(ctx->comm_base_addr,
-							cppc_ss->length);
+			ctx->pcc_comm_addr = memremap(ctx->comm_base_addr,
+							cppc_ss->length,
+							MEMREMAP_WT);
 		} else {
 			dev_err(&pdev->dev, "Failed to get PCC comm region\n");
 			rc = -ENODEV;
author
#21 lore raw

Re: [PATCH] hwmon: xgene: access mailbox as RAM

Quoted 26 lines · Guenter Roeck

Hi Arnd,

Quoted 23 lines · Arnd Bergmann

The newly added hwmon driver fails to build in an allmodconfig kernel:

1 ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

According to comments in the code, the mailbox is a shared memory region, not a set of MMIO registers, so we should use memremap() for mapping it instead of ioremap or acpi_os_ioremap, and pointer dereferences instead of readl/writel.

The driver already uses plain kernel pointers, so it's a bit unusual to work with functions that operate on __iomem pointers, and this fixes that part too.

I'm using READ_ONCE/WRITE_ONCE here to keep the existing behavior regarding the ordering of the accesses from the CPU, but note that there are no barriers (also unchanged from before).

I'm also keeping the endianess behavior, though I'm unsure whether the message data was supposed to be in LE32 format in the first place, it's possible this was meant to be interpreted as a byte stream instead.

Quoted 9 lines
Quoted 2 lines

Thanks a lot for looking into this.

I'll apply this patch to address the build problem. Much better than my rude "depends on BROKEN". It would be great to get a Tested-by:
from someone with access to the hardware.

Hi Arnd and Guenter,

Thanks for the patch. I'm testing it out.

Hoan

Quoted 81 lines

Guenter

Quoted 79 lines
drivers/hwmon/xgene-hwmon.c +15 -14
index bc78a5d10182..e834dfb3acca 100644
@@ -34,7 +34,8 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
-#include <acpi/acpi_io.h>
+#include <linux/io.h>
+
 #include <acpi/pcc.h>
 
 /* SLIMpro message defines */
@@ -126,10 +127,10 @@ static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask)
 {
      u16 ret, val;
 
-     val = readw_relaxed(addr);
+     val = le16_to_cpu(READ_ONCE(*addr));
      ret = val & mask;
      val &= ~mask;
-     writew_relaxed(val, addr);
+     WRITE_ONCE(*addr, cpu_to_le16(val));
 
      return ret;
 }
@@ -137,7 +138,7 @@ static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask)
 static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
 {
      struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr;
-     void *ptr = generic_comm_base + 1;
+     u32 *ptr = (void*)(generic_comm_base + 1);
      int rc, i;
      u16 val;
 
@@ -146,21 +147,21 @@ static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
      ctx->resp_pending = true;
 
      /* Write signature for subspace */
-     writel_relaxed(PCC_SIGNATURE_MASK | ctx->mbox_idx,
-                    &generic_comm_base->signature);
+     WRITE_ONCE(generic_comm_base->signature,
+                cpu_to_le32(PCC_SIGNATURE_MASK | ctx->mbox_idx));
 
      /* Write to the shared command region */
-     writew_relaxed(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT,
-                    &generic_comm_base->command);
+     WRITE_ONCE(generic_comm_base->command,
+                cpu_to_le16(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT));
 
      /* Flip CMD COMPLETE bit */
-     val = readw_relaxed(&generic_comm_base->status);
+     val = le16_to_cpu(READ_ONCE(generic_comm_base->status));
      val &= ~PCCS_CMD_COMPLETE;
-     writew_relaxed(val, &generic_comm_base->status);
+     WRITE_ONCE(generic_comm_base->status, cpu_to_le16(val));
 
      /* Copy the message to the PCC comm space */
      for (i = 0; i < sizeof(struct slimpro_resp_msg) / 4; i++)
-             writel_relaxed(msg[i], ptr + i * 4);
+             WRITE_ONCE(ptr[i], cpu_to_le32(msg[i]));
 
      /* Ring the doorbell */
      rc = mbox_send_message(ctx->mbox_chan, msg);
@@ -652,9 +653,9 @@ static int xgene_hwmon_probe(struct platform_device *pdev)
               */
              ctx->comm_base_addr = cppc_ss->base_address;
              if (ctx->comm_base_addr) {
-                     ctx->pcc_comm_addr =
-                                     acpi_os_ioremap(ctx->comm_base_addr,
-                                                     cppc_ss->length);
+                     ctx->pcc_comm_addr = memremap(ctx->comm_base_addr,
+                                                     cppc_ss->length,
+                                                     MEMREMAP_WT);
              } else {
                      dev_err(&pdev->dev, "Failed to get PCC comm region\n");
                      rc = -ENODEV;
author
#22 lore raw

Re: [PATCH] hwmon: xgene: access mailbox as RAM

In reply to Arnd Bergmann

Hi Arnd,

Quoted 30 lines · Arnd Bergmann

The newly added hwmon driver fails to build in an allmodconfig kernel:

1 ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

According to comments in the code, the mailbox is a shared memory region, not a set of MMIO registers, so we should use memremap() for mapping it instead of ioremap or acpi_os_ioremap, and pointer dereferences instead of readl/writel.

The driver already uses plain kernel pointers, so it's a bit unusual to work with functions that operate on __iomem pointers, and this fixes that part too.

I'm using READ_ONCE/WRITE_ONCE here to keep the existing behavior regarding the ordering of the accesses from the CPU, but note that there are no barriers (also unchanged from before).

I'm also keeping the endianess behavior, though I'm unsure whether the message data was supposed to be in LE32 format in the first place, it's possible this was meant to be interpreted as a byte stream instead.

drivers/hwmon/xgene-hwmon.c +0 -0
index bc78a5d10182..e834dfb3acca 100644

drivers/hwmon/xgene-hwmon.c line 37

Quoted 5 lines
drivers/hwmon/xgene-hwmon.c +1 -1
@@ -34,7 +34,8 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
-#include <acpi/acpi_io.h>
+#include <linux/io.h>

Alphabetical order.

Quoted 18 lines
drivers/hwmon/xgene-hwmon.c +3 -2
+
 #include <acpi/pcc.h>
 
 /* SLIMpro message defines */
@@ -126,10 +127,10 @@ static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask)
 {
        u16 ret, val;
 
-       val = readw_relaxed(addr);
+       val = le16_to_cpu(READ_ONCE(*addr));
        ret = val & mask;
        val &= ~mask;
-       writew_relaxed(val, addr);
+       WRITE_ONCE(*addr, cpu_to_le16(val));
 
        return ret;
 }

drivers/hwmon/xgene-hwmon.c static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask) · line 141

Quoted 5 lines
drivers/hwmon/xgene-hwmon.c +1 -1
@@ -137,7 +138,7 @@ static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask)
 static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
 {
        struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr;
-       void *ptr = generic_comm_base + 1;
+       u32 *ptr = (void*)(generic_comm_base + 1);

Space before "*".

Quoted 33 lines
drivers/hwmon/xgene-hwmon.c +7 -7
        int rc, i;
        u16 val;
 
@@ -146,21 +147,21 @@ static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
        ctx->resp_pending = true;
 
        /* Write signature for subspace */
-       writel_relaxed(PCC_SIGNATURE_MASK | ctx->mbox_idx,
-                      &generic_comm_base->signature);
+       WRITE_ONCE(generic_comm_base->signature,
+                  cpu_to_le32(PCC_SIGNATURE_MASK | ctx->mbox_idx));
 
        /* Write to the shared command region */
-       writew_relaxed(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT,
-                      &generic_comm_base->command);
+       WRITE_ONCE(generic_comm_base->command,
+                  cpu_to_le16(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT));
 
        /* Flip CMD COMPLETE bit */
-       val = readw_relaxed(&generic_comm_base->status);
+       val = le16_to_cpu(READ_ONCE(generic_comm_base->status));
        val &= ~PCCS_CMD_COMPLETE;
-       writew_relaxed(val, &generic_comm_base->status);
+       WRITE_ONCE(generic_comm_base->status, cpu_to_le16(val));
 
        /* Copy the message to the PCC comm space */
        for (i = 0; i < sizeof(struct slimpro_resp_msg) / 4; i++)
-               writel_relaxed(msg[i], ptr + i * 4);
+               WRITE_ONCE(ptr[i], cpu_to_le32(msg[i]));
 
        /* Ring the doorbell */
        rc = mbox_send_message(ctx->mbox_chan, msg);

drivers/hwmon/xgene-hwmon.c static int xgene_hwmon_probe(struct platform_device *pdev) · line 658

Quoted 9 lines
drivers/hwmon/xgene-hwmon.c +3 -3
@@ -652,9 +653,9 @@ static int xgene_hwmon_probe(struct platform_device *pdev)
                 */
                ctx->comm_base_addr = cppc_ss->base_address;
                if (ctx->comm_base_addr) {
-                       ctx->pcc_comm_addr =
-                                       acpi_os_ioremap(ctx->comm_base_addr,
-                                                       cppc_ss->length);
+                       ctx->pcc_comm_addr = memremap(ctx->comm_base_addr,
+                                                       cppc_ss->length,
+                                                       MEMREMAP_WT);

It should be MEMREMAP_WB. As mailbox shared memory is on RAM and our co-processor is also in the coherency domain.

Thanks
Hoan

Quoted 4 lines
drivers/hwmon/xgene-hwmon.c +0 -0
                } else {
                        dev_err(&pdev->dev, "Failed to get PCC comm region\n");
                        rc = -ENODEV;
#23 lore raw

Re: [PATCH] hwmon: xgene: access mailbox as RAM

Quoted 14 lines · CEST Hoan Tran

drivers/hwmon/xgene-hwmon.c line 37

Quoted 10 lines · Arnd Bergmann

The newly added hwmon driver fails to build in an allmodconfig index bc78a5d10182..e834dfb3acca 100644

drivers/hwmon/xgene-hwmon.c +1 -1
@@ -34,7 +34,8 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
-#include <acpi/acpi_io.h>
+#include <linux/io.h>

Alphabetical order.

Quoted 5 lines

drivers/hwmon/xgene-hwmon.c static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask) · line 141

Quoted 3 lines
drivers/hwmon/xgene-hwmon.c +1 -1
        struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr;
-       void *ptr = generic_comm_base + 1;
+       u32 *ptr = (void*)(generic_comm_base + 1);

Space before "*".

Ok.

Quoted 5 lines
Quoted 5 lines
drivers/hwmon/xgene-hwmon.c +0 -1
@@ -652,9 +653,9 @@ static int xgene_hwmon_probe(struct platform_device *pdev)
                 */
                ctx->comm_base_addr = cppc_ss->base_address;
                if (ctx->comm_base_addr) {
-                       ctx->pcc_comm_addr =
Quoted 8 lines

drivers/hwmon/xgene-hwmon.c static int xgene_hwmon_probe(struct platform_device *pdev) · line 658

Quoted 5 lines
drivers/hwmon/xgene-hwmon.c +3 -2
-                                       acpi_os_ioremap(ctx->comm_base_addr,
-                                                       cppc_ss->length);
+                       ctx->pcc_comm_addr = memremap(ctx->comm_base_addr,
+                                                       cppc_ss->length,
+                                                       MEMREMAP_WT);

It should be MEMREMAP_WB. As mailbox shared memory is on RAM and our co-processor is also in the coherency domain.

Right, I was wondering about this, since I could not figure out what the other side is (hardware, service processor or firmware). So MEMREMAP_WB makes sense here.

Two more questions:

* Any comment on the byte ordering of the data in this line:

        /* Copy the message to the PCC comm space */
        for (i = 0; i < sizeof(struct slimpro_resp_msg) / 4; i++)

- writel_relaxed(msg[i], ptr + i * 4);
+ WRITE_ONCE(ptr[i], cpu_to_le32(msg[i]));

This assumes that the old code was correct even when running on big-endian kernels and the message data consists of 32-bit data words. If the message has some other format instead, we would need to treat this as a byte stream and not do swapping here but instead do it (if any) in the code that reads or writes the actual data here.

* Are you sure you don't need any smp_rmb()/smp_wmb() barriers between the accesses?

Arnd

#24 lore raw

PATCH v2 1/1 hwmon: xgene: access mailbox as RAM

The newly added hwmon driver fails to build in an allmodconfig kernel:

ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

According to comments in the code, the mailbox is a shared memory region, not a set of MMIO registers, so we should use memremap() for mapping it instead of ioremap or acpi_os_ioremap, and pointer dereferences instead of readl/writel.

The driver already uses plain kernel pointers, so it's a bit unusual to work with functions that operate on __iomem pointers, and this fixes that part too.

I'm using READ_ONCE/WRITE_ONCE here to keep the existing behavior regarding the ordering of the accesses from the CPU, but note that there are no barriers (also unchanged from before).

I'm also keeping the endianess behavior, though I'm unsure whether the message data was supposed to be in LE32 format in the first place, it's possible this was meant to be interpreted as a byte stream instead.

---
v2: use write-back mapping instead of write-thru,
minor coding style changes

drivers/hwmon/xgene-hwmon.c +15 -14
index bc78a5d10182..e5470bd49067 100644
@@ -27,6 +27,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/kfifo.h>
 #include <linux/mailbox_controller.h>
@@ -34,7 +35,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
-#include <acpi/acpi_io.h>
+
 #include <acpi/pcc.h>
 
 /* SLIMpro message defines */
@@ -126,10 +127,10 @@ static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask)
 {
 	u16 ret, val;
 
-	val = readw_relaxed(addr);
+	val = le16_to_cpu(READ_ONCE(*addr));
 	ret = val & mask;
 	val &= ~mask;
-	writew_relaxed(val, addr);
+	WRITE_ONCE(*addr, cpu_to_le16(val));
 
 	return ret;
 }
@@ -137,7 +138,7 @@ static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask)
 static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
 {
 	struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr;
-	void *ptr = generic_comm_base + 1;
+	u32 *ptr = (void *)(generic_comm_base + 1);
 	int rc, i;
 	u16 val;
 
@@ -146,21 +147,21 @@ static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
 	ctx->resp_pending = true;
 
 	/* Write signature for subspace */
-	writel_relaxed(PCC_SIGNATURE_MASK | ctx->mbox_idx,
-		       &generic_comm_base->signature);
+	WRITE_ONCE(generic_comm_base->signature,
+		   cpu_to_le32(PCC_SIGNATURE_MASK | ctx->mbox_idx));
 
 	/* Write to the shared command region */
-	writew_relaxed(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT,
-		       &generic_comm_base->command);
+	WRITE_ONCE(generic_comm_base->command,
+		   cpu_to_le16(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT));
 
 	/* Flip CMD COMPLETE bit */
-	val = readw_relaxed(&generic_comm_base->status);
+	val = le16_to_cpu(READ_ONCE(generic_comm_base->status));
 	val &= ~PCCS_CMD_COMPLETE;
-	writew_relaxed(val, &generic_comm_base->status);
+	WRITE_ONCE(generic_comm_base->status, cpu_to_le16(val));
 
 	/* Copy the message to the PCC comm space */
 	for (i = 0; i < sizeof(struct slimpro_resp_msg) / 4; i++)
-		writel_relaxed(msg[i], ptr + i * 4);
+		WRITE_ONCE(ptr[i], cpu_to_le32(msg[i]));
 
 	/* Ring the doorbell */
 	rc = mbox_send_message(ctx->mbox_chan, msg);
@@ -652,9 +653,9 @@ static int xgene_hwmon_probe(struct platform_device *pdev)
 		 */
 		ctx->comm_base_addr = cppc_ss->base_address;
 		if (ctx->comm_base_addr) {
-			ctx->pcc_comm_addr =
-					acpi_os_ioremap(ctx->comm_base_addr,
-							cppc_ss->length);
+			ctx->pcc_comm_addr = memremap(ctx->comm_base_addr,
+							cppc_ss->length,
+							MEMREMAP_WB);
 		} else {
 			dev_err(&pdev->dev, "Failed to get PCC comm region\n");
 			rc = -ENODEV;
author Acked-by Tested-by on v2 1/1
#25 lore raw

Re: [PATCH v2] hwmon: xgene: access mailbox as RAM

Hi Arnd,

Quoted 104 lines · Arnd Bergmann

The newly added hwmon driver fails to build in an allmodconfig kernel:

ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

According to comments in the code, the mailbox is a shared memory region, not a set of MMIO registers, so we should use memremap() for mapping it instead of ioremap or acpi_os_ioremap, and pointer dereferences instead of readl/writel.

The driver already uses plain kernel pointers, so it's a bit unusual to work with functions that operate on __iomem pointers, and this fixes that part too.

I'm using READ_ONCE/WRITE_ONCE here to keep the existing behavior regarding the ordering of the accesses from the CPU, but note that there are no barriers (also unchanged from before).

I'm also keeping the endianess behavior, though I'm unsure whether the message data was supposed to be in LE32 format in the first place, it's possible this was meant to be interpreted as a byte stream instead.

---
v2: use write-back mapping instead of write-thru,
minor coding style changes

drivers/hwmon/xgene-hwmon.c +12 -11
index bc78a5d10182..e5470bd49067 100644
@@ -27,6 +27,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/kfifo.h>
 #include <linux/mailbox_controller.h>
@@ -34,7 +35,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
-#include <acpi/acpi_io.h>
+
 #include <acpi/pcc.h>
 
 /* SLIMpro message defines */
@@ -126,10 +127,10 @@ static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask)
 {
        u16 ret, val;
 
-       val = readw_relaxed(addr);
+       val = le16_to_cpu(READ_ONCE(*addr));
        ret = val & mask;
        val &= ~mask;
-       writew_relaxed(val, addr);
+       WRITE_ONCE(*addr, cpu_to_le16(val));
 
        return ret;
 }
@@ -137,7 +138,7 @@ static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask)
 static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
 {
        struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr;
-       void *ptr = generic_comm_base + 1;
+       u32 *ptr = (void *)(generic_comm_base + 1);
        int rc, i;
        u16 val;
 
@@ -146,21 +147,21 @@ static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
        ctx->resp_pending = true;
 
        /* Write signature for subspace */
-       writel_relaxed(PCC_SIGNATURE_MASK | ctx->mbox_idx,
-                      &generic_comm_base->signature);
+       WRITE_ONCE(generic_comm_base->signature,
+                  cpu_to_le32(PCC_SIGNATURE_MASK | ctx->mbox_idx));
 
        /* Write to the shared command region */
-       writew_relaxed(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT,
-                      &generic_comm_base->command);
+       WRITE_ONCE(generic_comm_base->command,
+                  cpu_to_le16(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT));
 
        /* Flip CMD COMPLETE bit */
-       val = readw_relaxed(&generic_comm_base->status);
+       val = le16_to_cpu(READ_ONCE(generic_comm_base->status));
        val &= ~PCCS_CMD_COMPLETE;
-       writew_relaxed(val, &generic_comm_base->status);
+       WRITE_ONCE(generic_comm_base->status, cpu_to_le16(val));
 
        /* Copy the message to the PCC comm space */
        for (i = 0; i < sizeof(struct slimpro_resp_msg) / 4; i++)
-               writel_relaxed(msg[i], ptr + i * 4);
+               WRITE_ONCE(ptr[i], cpu_to_le32(msg[i]));
 
        /* Ring the doorbell */
        rc = mbox_send_message(ctx->mbox_chan, msg);
@@ -652,9 +653,9 @@ static int xgene_hwmon_probe(struct platform_device *pdev)
                 */
                ctx->comm_base_addr = cppc_ss->base_address;

drivers/hwmon/xgene-hwmon.c static int xgene_hwmon_probe(struct platform_device *pdev) · line 661

Quoted 10 lines
drivers/hwmon/xgene-hwmon.c +3 -3
                if (ctx->comm_base_addr) {
-                       ctx->pcc_comm_addr =
-                                       acpi_os_ioremap(ctx->comm_base_addr,
-                                                       cppc_ss->length);
+                       ctx->pcc_comm_addr = memremap(ctx->comm_base_addr,
+                                                       cppc_ss->length,
+                                                       MEMREMAP_WB);
                } else {
                        dev_err(&pdev->dev, "Failed to get PCC comm region\n");
                        rc = -ENODEV;

Thanks
Hoan

maintainer
#26 lore raw

Re: [PATCH v2] hwmon: xgene: access mailbox as RAM

In reply to Arnd Bergmann
Quoted 18 lines · Arnd Bergmann

The newly added hwmon driver fails to build in an allmodconfig kernel:

ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined!

According to comments in the code, the mailbox is a shared memory region, not a set of MMIO registers, so we should use memremap() for mapping it instead of ioremap or acpi_os_ioremap, and pointer dereferences instead of readl/writel.

The driver already uses plain kernel pointers, so it's a bit unusual to work with functions that operate on __iomem pointers, and this fixes that part too.

I'm using READ_ONCE/WRITE_ONCE here to keep the existing behavior regarding the ordering of the accesses from the CPU, but note that there are no barriers (also unchanged from before).

Quoted 6 lines

I'm also keeping the endianess behavior, though I'm unsure whether the message data was supposed to be in LE32 format in the first place, it's possible this was meant to be interpreted as a byte stream instead.

Applied after 's/endianess/endianness/' to make checkpatch happy.

Thanks,
Guenter

author
#27 lore raw

Re: [PATCH] hwmon: xgene: access mailbox as RAM

In reply to Arnd Bergmann
Quoted 50 lines · Arnd Bergmann
Quoted 14 lines · CEST Hoan Tran

drivers/hwmon/xgene-hwmon.c line 37

Quoted 10 lines · Arnd Bergmann

The newly added hwmon driver fails to build in an allmodconfig index bc78a5d10182..e834dfb3acca 100644

drivers/hwmon/xgene-hwmon.c +1 -1
@@ -34,7 +34,8 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
-#include <acpi/acpi_io.h>
+#include <linux/io.h>

Alphabetical order.

Quoted 5 lines

drivers/hwmon/xgene-hwmon.c static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask) · line 141

Quoted 3 lines
drivers/hwmon/xgene-hwmon.c +1 -1
        struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr;
-       void *ptr = generic_comm_base + 1;
+       u32 *ptr = (void*)(generic_comm_base + 1);

Space before "*".

Ok.

Quoted 5 lines
Quoted 5 lines
drivers/hwmon/xgene-hwmon.c +0 -1
@@ -652,9 +653,9 @@ static int xgene_hwmon_probe(struct platform_device *pdev)
                 */
                ctx->comm_base_addr = cppc_ss->base_address;
                if (ctx->comm_base_addr) {
-                       ctx->pcc_comm_addr =
Quoted 8 lines

drivers/hwmon/xgene-hwmon.c static int xgene_hwmon_probe(struct platform_device *pdev) · line 658

Quoted 5 lines
drivers/hwmon/xgene-hwmon.c +3 -2
-                                       acpi_os_ioremap(ctx->comm_base_addr,
-                                                       cppc_ss->length);
+                       ctx->pcc_comm_addr = memremap(ctx->comm_base_addr,
+                                                       cppc_ss->length,
+                                                       MEMREMAP_WT);

It should be MEMREMAP_WB. As mailbox shared memory is on RAM and our co-processor is also in the coherency domain.

Right, I was wondering about this, since I could not figure out what the other side is (hardware, service processor or firmware). So MEMREMAP_WB makes sense here.

Two more questions:

* Any comment on the byte ordering of the data in this line:

        /* Copy the message to the PCC comm space */
        for (i = 0; i < sizeof(struct slimpro_resp_msg) / 4; i++)
drivers/hwmon/xgene-hwmon.c +1 -1
-               writel_relaxed(msg[i], ptr + i * 4);
+               WRITE_ONCE(ptr[i], cpu_to_le32(msg[i]));
Quoted 5 lines

This assumes that the old code was correct even when running on big-endian kernels and the message data consists of 32-bit data words. If the message has some other format instead, we would need to treat this as a byte stream and not do swapping here but instead do it (if any) in the code that reads or writes the actual data here.

This is 32-bit data words.

Quoted 3 lines

* Are you sure you don't need any smp_rmb()/smp_wmb() barriers between the accesses?

No, we don't need a strict read/write during access PCC subspace. Just make sure all access is committed before PCC send message to the platform which done by PCC mailbox driver.

Thanks
Hoan

Quoted 2 lines

Arnd

#28 lore raw

Re: [PATCH] hwmon: xgene: access mailbox as RAM

Quoted 8 lines · CEST Hoan Tran
Quoted 3 lines

* Are you sure you don't need any smp_rmb()/smp_wmb() barriers between the accesses?

No, we don't need a strict read/write during access PCC subspace. Just make sure all access is committed before PCC send message to the platform which done by PCC mailbox driver.

Ok, got it. The PCC mailbox driver presumably uses writel() to send the message, and that implies the necessary barrier (unlike writel_relaxed), right?

Arnd

author
#29 lore raw

Re: [PATCH] hwmon: xgene: access mailbox as RAM

Quoted 5 lines · Arnd Bergmann
Quoted 4 lines · CEST Hoan Tran
Quoted 3 lines

* Are you sure you don't need any smp_rmb()/smp_wmb() barriers between the accesses?

Quoted 8 lines
Quoted 4 lines

No, we don't need a strict read/write during access PCC subspace. Just make sure all access is committed before PCC send message to the platform which done by PCC mailbox driver.

Ok, got it. The PCC mailbox driver presumably uses writel() to send the message, and that implies the necessary barrier (unlike writel_relaxed), right?

Yes,

Hoan

Quoted 3 lines

Arnd

author
#30 lore raw

PATCH v3 3/3 arm64: dts: apm: Add X-Gene SoC hwmon to device tree

In reply to Hoan Tran

This patch adds DT node to enable hwmon driver for APM X-Gene SoC.

---
 arch/arm64/boot/dts/apm/apm-shadowcat.dtsi | 5 +++++
 arch/arm64/boot/dts/apm/apm-storm.dtsi     | 5 +++++
 2 files changed, 10 insertions(+)
arch/arm64/boot/dts/apm/apm-shadowcat.dtsi +5 -0
index c569f76..a5935f5 100644
@@ -472,6 +472,11 @@
 			mboxes = <&mailbox 0>;
 		};
 
+		hwmonslimpro {
+			compatible = "apm,xgene-slimpro-hwmon";
+			mboxes = <&mailbox 7>;
+		};
+
 		serial0: serial at 10600000 {
 			device_type = "serial";
 			compatible = "ns16550";
arch/arm64/boot/dts/apm/apm-storm.dtsi +5 -0
index 5147d76..f8ea5b5 100644
@@ -716,6 +716,11 @@
 			mboxes = <&mailbox 0>;
 		};
 
+		hwmonslimpro {
+			compatible = "apm,xgene-slimpro-hwmon";
+			mboxes = <&mailbox 7>;
+		};
+
 		serial0: serial at 1c020000 {
 			status = "disabled";
 			device_type = "serial";
Signature · 1 line
1.9.1
maintainer Acked-by on v3 3/3
#31 lore raw

Re: [PATCH v3 3/3] arm64: dts: apm: Add X-Gene SoC hwmon to device tree

Quoted 3 lines · Hoan Tran

This patch adds DT node to enable hwmon driver for APM X-Gene SoC.

Quoted 40 lines
---
 arch/arm64/boot/dts/apm/apm-shadowcat.dtsi | 5 +++++
 arch/arm64/boot/dts/apm/apm-storm.dtsi     | 5 +++++
 2 files changed, 10 insertions(+)
arch/arm64/boot/dts/apm/apm-shadowcat.dtsi +5 -0
index c569f76..a5935f5 100644
@@ -472,6 +472,11 @@
 			mboxes = <&mailbox 0>;
 		};
 
+		hwmonslimpro {
+			compatible = "apm,xgene-slimpro-hwmon";
+			mboxes = <&mailbox 7>;
+		};
+
 		serial0: serial at 10600000 {
 			device_type = "serial";
 			compatible = "ns16550";
arch/arm64/boot/dts/apm/apm-storm.dtsi +5 -0
index 5147d76..f8ea5b5 100644
@@ -716,6 +716,11 @@
 			mboxes = <&mailbox 0>;
 		};
 
+		hwmonslimpro {
+			compatible = "apm,xgene-slimpro-hwmon";
+			mboxes = <&mailbox 7>;
+		};
+
 		serial0: serial at 1c020000 {
 			status = "disabled";
 			device_type = "serial";
Signature · 1 line
1.9.1