[PATCH 1/2] hwmon/applesmc: add MMIO for newer macs

Subu Dwevedi posted 2 patches 11 months ago
[PATCH 1/2] hwmon/applesmc: add MMIO for newer macs
Posted by Subu Dwevedi 11 months ago
Add basic MMIO support to AppleSMC for T2 Macs,
enabling it only when supported.
This replaces the legacy port-based method for
key reading, writing, and metadata operations
(retrieving keys by index and obtaining key information)

Signed-off-by: Subu Dwevedi <messigoatcr7nop@gmail.com>
---
 drivers/hwmon/applesmc.c | 223 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 213 insertions(+), 10 deletions(-)

diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index fc6d6a9053ce..1be4a4026a6e 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -17,6 +17,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/acpi.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
@@ -142,7 +143,9 @@ static struct platform_device *pdev;
 static s16 rest_x;
 static s16 rest_y;
 static u8 backlight_state[2];
-
+static u8 *__iomem mmio_base;
+static bool is_mmio;
+static u32 mmio_base_addr, mmio_base_size;
 static struct device *hwmon_dev;
 static struct input_dev *applesmc_idev;
 
@@ -245,7 +248,108 @@ static int send_argument(const char *key)
 	return 0;
 }
 
-static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)
+/*
+ * MMIO Impliementation
+ */
+
+static void clearArbitration(void)
+{
+	if (ioread8(mmio_base + 0x4005))
+		return iowrite8(0, mmio_base + 0x4005);
+}
+static int waitForKeyDone(void)
+{
+	int i = 1000; //millisecounds
+	u8 status;
+
+	while (i) {
+		msleep(1);
+		i--;
+
+		status = ioread8(mmio_base + 0x4005);
+		if (status & 0x20)
+			return 0;
+	}
+
+	return -EIO;
+}
+static int mmio_read_smc(u8 cmd, const char *key, u8 *buffer, u64 len)
+{
+	u8 i, u = 0;
+
+	clearArbitration();
+	iowrite32(*((u32 *)key), mmio_base + 0x78);
+	iowrite8(0x15, mmio_base + 0x7E);
+	iowrite8(cmd, mmio_base + 0x7F);
+
+	if (waitForKeyDone())
+		return -EIO;
+
+	i = ioread8(mmio_base + 0x7F);
+	if (i)
+		return -EIO;
+	if (cmd == APPLESMC_READ_CMD) {
+		i = ioread8(mmio_base + 0x7D);
+		if (i > len || !i)
+			return -EIO;
+
+		while (u < i) {
+			if ((i - u) < 4) {
+				if ((i - u) < 2) {
+					buffer[u] = ioread8(mmio_base + u);
+					u += 1;
+				} else {
+					*(u16 *)&buffer[u] = ioread16(mmio_base + u);
+					u += 2;
+				}
+			} else {
+				*(u32 *)&buffer[u] = ioread32(mmio_base + u);
+				u += 4;
+			}
+		}
+	} else
+		memcpy_fromio(buffer, mmio_base + 0x0, len);
+
+	return 0;
+}
+static int mmio_write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len)
+{
+	u8 i = 0;
+
+	clearArbitration();
+	iowrite32(*((u32 *)key), mmio_base + 0x78);
+	while (i < len) {
+		if (len - i < 4) {
+			if (len - i < 2) {
+				iowrite8(buffer[i], mmio_base + i);
+				i += 1;
+			} else {
+				iowrite16(*(u16 *)&buffer[i], mmio_base + i);
+				i += 2;
+			}
+		} else {
+			iowrite32(*(u32 *)&buffer[i], mmio_base + i);
+			i += 4;
+		}
+	}
+	iowrite8(len, mmio_base + 0x7D);
+	iowrite8(0x15, mmio_base + 0x7E);
+	iowrite8(cmd, mmio_base + 0x7F);
+	if (waitForKeyDone())
+		return -EIO;
+
+	i = ioread8(mmio_base + 0x7F);
+	if (i)
+		return -EIO;
+
+	return 0;
+}
+
+/*
+ * Port Based IO implementation
+ *
+ */
+static int port_read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)
 {
 	u8 status, data = 0;
 	int i;
@@ -289,7 +393,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)
 	return wait_status(0, SMC_STATUS_BUSY);
 }
 
-static int write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len)
+static int port_write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len)
 {
 	int i;
 	int ret;
@@ -317,7 +421,23 @@ static int write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len)
 
 	return wait_status(0, SMC_STATUS_BUSY);
 }
+static int write_smc(u8 cmd, const char *key, const u8 *buffer,
+		u8 len)
+{
+	if (is_mmio)
+		return mmio_write_smc(cmd, key, buffer, len);
+
+	return port_write_smc(cmd, key, buffer, len);
+}
 
+static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)
+{
+	if (is_mmio)
+		return mmio_read_smc(cmd, key, buffer, len);
+
+
+	return port_read_smc(cmd, key, buffer, len);
+}
 static int read_register_count(unsigned int *count)
 {
 	__be32 be;
@@ -379,18 +499,39 @@ static const struct applesmc_entry *applesmc_get_entry_by_index(int index)
 
 	if (cache->valid)
 		goto out;
+
 	be = cpu_to_be32(index);
-	ret = read_smc(APPLESMC_GET_KEY_BY_INDEX_CMD, (u8 *)&be, key, 4);
-	if (ret)
-		goto out;
-	ret = read_smc(APPLESMC_GET_KEY_TYPE_CMD, key, info, 6);
+	ret = read_smc(APPLESMC_GET_KEY_BY_INDEX_CMD, (const char *) &be, (u8 *) key, 4);
 	if (ret)
 		goto out;
 
+	if (is_mmio) {
+		clearArbitration();
+		iowrite32(*((u32 *)key), mmio_base + 0x78);
+		iowrite8(0, mmio_base + 0x7E);
+		iowrite8(APPLESMC_GET_KEY_TYPE_CMD, mmio_base + 0x7F);
+		ret = waitForKeyDone();
+		if (ret)
+			goto out;
+
+		ret = ioread8(mmio_base + 0x7F);
+		if (ret)
+			goto out;
+
+		*(u32 *)cache->type = ioread32(mmio_base + 0x7F);
+		cache->len = ioread8(mmio_base + 5);
+		cache->flags = ioread8(mmio_base + 6);
+
+	} else {
+		ret = read_smc(APPLESMC_GET_KEY_TYPE_CMD, key, info, 6);
+		if (ret)
+			goto out;
+
+		cache->len = info[0];
+		memcpy(cache->type, &info[1], 4);
+		cache->flags = info[5];
+	}
 	memcpy(cache->key, key, 4);
-	cache->len = info[0];
-	memcpy(cache->type, &info[1], 4);
-	cache->flags = info[5];
 	cache->valid = true;
 
 out:
@@ -558,7 +699,64 @@ static int applesmc_init_index(struct applesmc_registers *s)
 
 	return 0;
 }
+/*
+ * applesmc_init_mmio_try - Try to initialize MMIO
+ */
+static int applesmc_init_mmio_try(void)
+{
+	u8 ldkn_version;
+	acpi_status status;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_device *adev;
+	struct acpi_resource *res;
+
+	adev = acpi_dev_get_first_match_dev("APP0001", NULL, -1);
+	if (!adev)
+		return -ENXIO;
+
+	status = acpi_get_current_resources(adev->handle, &buffer);
+	if (ACPI_FAILURE(status))
+		return -ENXIO;
+
+	res = buffer.pointer;
+	while (res->type != ACPI_RESOURCE_TYPE_END_TAG) {
+		if (res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) {
+			if (res->data.fixed_memory32.address_length < 0x4006)
+				return -ENXIO;
+
+			mmio_base_addr = res->data.fixed_memory32.address;
+			mmio_base_size = res->data.fixed_memory32.address_length;
+			is_mmio = true;
+			break;
+		}
+		res = ACPI_NEXT_RESOURCE(res);
+	}
+	kfree(buffer.pointer);
+	acpi_dev_put(adev);
+
+	if (!is_mmio)
+		return -ENXIO;
+
+	mmio_base = ioremap(mmio_base_addr, mmio_base_size);
+
+	if (!mmio_base)
+		return -ENXIO;
 
+	if (ioread8(mmio_base + 0x4005) == 0xFF)
+		goto out;
+
+	if (read_smc(APPLESMC_READ_CMD, "LDKN", &ldkn_version, 1))
+		goto out;
+
+	if (ldkn_version < 2)
+		goto out;
+
+	return 0;
+out:
+	pr_warn("cannot enable MMIO will use PMIO\n");
+	iounmap(mmio_base);
+	return -ENXIO;
+}
 /*
  * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent.
  */
@@ -1321,6 +1519,8 @@ static int __init applesmc_init(void)
 		ret = -ENXIO;
 		goto out;
 	}
+	if (applesmc_init_mmio_try())
+		is_mmio = false;
 
 	ret = platform_driver_register(&applesmc_driver);
 	if (ret)
@@ -1407,6 +1607,9 @@ static void __exit applesmc_exit(void)
 	applesmc_destroy_smcreg();
 	platform_device_unregister(pdev);
 	platform_driver_unregister(&applesmc_driver);
+	if (is_mmio)
+		iounmap(mmio_base);
+
 	release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
 }
 
-- 
2.43.0
Re: [PATCH 1/2] hwmon/applesmc: add MMIO for newer macs
Posted by Guenter Roeck 10 months, 4 weeks ago
On Wed, Mar 12, 2025 at 06:00:22PM +0530, Subu Dwevedi wrote:
> Add basic MMIO support to AppleSMC for T2 Macs,
> enabling it only when supported.
> This replaces the legacy port-based method for
> key reading, writing, and metadata operations
> (retrieving keys by index and obtaining key information)
> 
> Signed-off-by: Subu Dwevedi <messigoatcr7nop@gmail.com>

I expect the errors reported by the kernel test robot to be fixed before
I have a closer look at the patches.

Guenter
Re: [PATCH 1/2] hwmon/applesmc: add MMIO for newer macs
Posted by kernel test robot 11 months ago
Hi Subu,

kernel test robot noticed the following build warnings:

[auto build test WARNING on groeck-staging/hwmon-next]
[also build test WARNING on linus/master v6.14-rc6 next-20250313]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Subu-Dwevedi/hwmon-applesmc-add-MMIO-for-newer-macs/20250312-203248
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
patch link:    https://lore.kernel.org/r/20250312123055.1735-2-messigoatcr7nop%40gmail.com
patch subject: [PATCH 1/2] hwmon/applesmc: add MMIO for newer macs
config: x86_64-randconfig-122-20250313 (https://download.01.org/0day-ci/archive/20250314/202503141052.v7b9psFM-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250314/202503141052.v7b9psFM-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202503141052.v7b9psFM-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/hwmon/applesmc.c:257:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:257:31: sparse:     expected void const [noderef] __iomem *
   drivers/hwmon/applesmc.c:257:31: sparse:     got unsigned char [usertype] *
>> drivers/hwmon/applesmc.c:258:46: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:258:46: sparse:     expected void [noderef] __iomem *
   drivers/hwmon/applesmc.c:258:46: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:269:44: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:269:44: sparse:     expected void const [noderef] __iomem *
   drivers/hwmon/applesmc.c:269:44: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:281:44: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:281:44: sparse:     expected void [noderef] __iomem *
   drivers/hwmon/applesmc.c:281:44: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:282:34: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:282:34: sparse:     expected void [noderef] __iomem *
   drivers/hwmon/applesmc.c:282:34: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:283:33: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:283:33: sparse:     expected void [noderef] __iomem *
   drivers/hwmon/applesmc.c:283:33: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:288:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:288:31: sparse:     expected void const [noderef] __iomem *
   drivers/hwmon/applesmc.c:288:31: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:292:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:292:39: sparse:     expected void const [noderef] __iomem *
   drivers/hwmon/applesmc.c:292:39: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:299:71: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:299:71: sparse:     expected void const [noderef] __iomem *
   drivers/hwmon/applesmc.c:299:71: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:302:81: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:302:81: sparse:     expected void const [noderef] __iomem *
   drivers/hwmon/applesmc.c:302:81: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:306:73: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:306:73: sparse:     expected void const [noderef] __iomem *
   drivers/hwmon/applesmc.c:306:73: sparse:     got unsigned char [usertype] *
>> drivers/hwmon/applesmc.c:311:49: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void const volatile [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:311:49: sparse:     expected void const volatile [noderef] __iomem *
   drivers/hwmon/applesmc.c:311:49: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:320:44: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:320:44: sparse:     expected void [noderef] __iomem *
   drivers/hwmon/applesmc.c:320:44: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:324:63: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:324:63: sparse:     expected void [noderef] __iomem *
   drivers/hwmon/applesmc.c:324:63: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:327:73: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:327:73: sparse:     expected void [noderef] __iomem *
   drivers/hwmon/applesmc.c:327:73: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:331:65: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:331:65: sparse:     expected void [noderef] __iomem *
   drivers/hwmon/applesmc.c:331:65: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:335:33: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:335:33: sparse:     expected void [noderef] __iomem *
   drivers/hwmon/applesmc.c:335:33: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:336:34: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:336:34: sparse:     expected void [noderef] __iomem *
   drivers/hwmon/applesmc.c:336:34: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:337:33: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:337:33: sparse:     expected void [noderef] __iomem *
   drivers/hwmon/applesmc.c:337:33: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:341:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:341:31: sparse:     expected void const [noderef] __iomem *
   drivers/hwmon/applesmc.c:341:31: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:510:52: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:510:52: sparse:     expected void [noderef] __iomem *
   drivers/hwmon/applesmc.c:510:52: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:511:39: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:511:39: sparse:     expected void [noderef] __iomem *
   drivers/hwmon/applesmc.c:511:39: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:512:63: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:512:63: sparse:     expected void [noderef] __iomem *
   drivers/hwmon/applesmc.c:512:63: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:517:41: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:517:41: sparse:     expected void const [noderef] __iomem *
   drivers/hwmon/applesmc.c:517:41: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:521:58: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:521:58: sparse:     expected void const [noderef] __iomem *
   drivers/hwmon/applesmc.c:521:58: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:522:48: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:522:48: sparse:     expected void const [noderef] __iomem *
   drivers/hwmon/applesmc.c:522:48: sparse:     got unsigned char [usertype] *
   drivers/hwmon/applesmc.c:523:50: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:523:50: sparse:     expected void const [noderef] __iomem *
   drivers/hwmon/applesmc.c:523:50: sparse:     got unsigned char [usertype] *
>> drivers/hwmon/applesmc.c:740:19: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected unsigned char [usertype] *static [noderef] [toplevel] __iomem mmio_base @@     got void [noderef] __iomem * @@
   drivers/hwmon/applesmc.c:740:19: sparse:     expected unsigned char [usertype] *static [noderef] [toplevel] __iomem mmio_base
   drivers/hwmon/applesmc.c:740:19: sparse:     got void [noderef] __iomem *
   drivers/hwmon/applesmc.c:745:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const [noderef] __iomem * @@     got unsigned char [usertype] * @@
   drivers/hwmon/applesmc.c:745:31: sparse:     expected void const [noderef] __iomem *
   drivers/hwmon/applesmc.c:745:31: sparse:     got unsigned char [usertype] *
>> drivers/hwmon/applesmc.c:757:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void volatile [noderef] __iomem *addr @@     got unsigned char [usertype] *static [noderef] [toplevel] __iomem mmio_base @@
   drivers/hwmon/applesmc.c:757:17: sparse:     expected void volatile [noderef] __iomem *addr
   drivers/hwmon/applesmc.c:757:17: sparse:     got unsigned char [usertype] *static [noderef] [toplevel] __iomem mmio_base
   drivers/hwmon/applesmc.c:1611:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void volatile [noderef] __iomem *addr @@     got unsigned char [usertype] *static [noderef] [toplevel] __iomem mmio_base @@
   drivers/hwmon/applesmc.c:1611:25: sparse:     expected void volatile [noderef] __iomem *addr
   drivers/hwmon/applesmc.c:1611:25: sparse:     got unsigned char [usertype] *static [noderef] [toplevel] __iomem mmio_base
>> drivers/hwmon/applesmc.c:257:21: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:258:36: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:269:34: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:281:34: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:282:24: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:283:23: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:288:21: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:292:29: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:299:61: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:302:71: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:306:63: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:311:39: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:320:34: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:324:53: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:327:63: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:331:55: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:335:23: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:336:24: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:337:23: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:341:21: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:510:42: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:511:29: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:512:53: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:517:31: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:521:48: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:522:38: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:523:40: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:742:14: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:745:21: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:757:17: sparse: sparse: dereference of noderef expression
   drivers/hwmon/applesmc.c:1611:25: sparse: sparse: dereference of noderef expression

vim +257 drivers/hwmon/applesmc.c

   250	
   251	/*
   252	 * MMIO Impliementation
   253	 */
   254	
   255	static void clearArbitration(void)
   256	{
 > 257		if (ioread8(mmio_base + 0x4005))
 > 258			return iowrite8(0, mmio_base + 0x4005);
   259	}
   260	static int waitForKeyDone(void)
   261	{
   262		int i = 1000; //millisecounds
   263		u8 status;
   264	
   265		while (i) {
   266			msleep(1);
   267			i--;
   268	
   269			status = ioread8(mmio_base + 0x4005);
   270			if (status & 0x20)
   271				return 0;
   272		}
   273	
   274		return -EIO;
   275	}
   276	static int mmio_read_smc(u8 cmd, const char *key, u8 *buffer, u64 len)
   277	{
   278		u8 i, u = 0;
   279	
   280		clearArbitration();
   281		iowrite32(*((u32 *)key), mmio_base + 0x78);
   282		iowrite8(0x15, mmio_base + 0x7E);
   283		iowrite8(cmd, mmio_base + 0x7F);
   284	
   285		if (waitForKeyDone())
   286			return -EIO;
   287	
   288		i = ioread8(mmio_base + 0x7F);
   289		if (i)
   290			return -EIO;
   291		if (cmd == APPLESMC_READ_CMD) {
   292			i = ioread8(mmio_base + 0x7D);
   293			if (i > len || !i)
   294				return -EIO;
   295	
   296			while (u < i) {
   297				if ((i - u) < 4) {
   298					if ((i - u) < 2) {
   299						buffer[u] = ioread8(mmio_base + u);
   300						u += 1;
   301					} else {
   302						*(u16 *)&buffer[u] = ioread16(mmio_base + u);
   303						u += 2;
   304					}
   305				} else {
   306					*(u32 *)&buffer[u] = ioread32(mmio_base + u);
   307					u += 4;
   308				}
   309			}
   310		} else
 > 311			memcpy_fromio(buffer, mmio_base + 0x0, len);
   312	
   313		return 0;
   314	}
   315	static int mmio_write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len)
   316	{
   317		u8 i = 0;
   318	
   319		clearArbitration();
   320		iowrite32(*((u32 *)key), mmio_base + 0x78);
   321		while (i < len) {
   322			if (len - i < 4) {
   323				if (len - i < 2) {
   324					iowrite8(buffer[i], mmio_base + i);
   325					i += 1;
   326				} else {
   327					iowrite16(*(u16 *)&buffer[i], mmio_base + i);
   328					i += 2;
   329				}
   330			} else {
   331				iowrite32(*(u32 *)&buffer[i], mmio_base + i);
   332				i += 4;
   333			}
   334		}
   335		iowrite8(len, mmio_base + 0x7D);
   336		iowrite8(0x15, mmio_base + 0x7E);
   337		iowrite8(cmd, mmio_base + 0x7F);
   338		if (waitForKeyDone())
   339			return -EIO;
   340	
   341		i = ioread8(mmio_base + 0x7F);
   342		if (i)
   343			return -EIO;
   344	
   345		return 0;
   346	}
   347	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH 1/2] hwmon/applesmc: add MMIO for newer macs
Posted by kernel test robot 11 months ago
Hi Subu,

kernel test robot noticed the following build errors:

[auto build test ERROR on groeck-staging/hwmon-next]
[also build test ERROR on linus/master v6.14-rc6 next-20250313]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Subu-Dwevedi/hwmon-applesmc-add-MMIO-for-newer-macs/20250312-203248
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
patch link:    https://lore.kernel.org/r/20250312123055.1735-2-messigoatcr7nop%40gmail.com
patch subject: [PATCH 1/2] hwmon/applesmc: add MMIO for newer macs
config: x86_64-buildonly-randconfig-002-20250313 (https://download.01.org/0day-ci/archive/20250314/202503140229.R49CaAYj-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250314/202503140229.R49CaAYj-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202503140229.R49CaAYj-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/hwmon/applesmc.c:717:42: error: incomplete definition of type 'struct acpi_device'
     717 |         status = acpi_get_current_resources(adev->handle, &buffer);
         |                                             ~~~~^
   include/linux/acpi.h:801:8: note: forward declaration of 'struct acpi_device'
     801 | struct acpi_device;
         |        ^
   1 error generated.


vim +717 drivers/hwmon/applesmc.c

   678	
   679	static int applesmc_init_index(struct applesmc_registers *s)
   680	{
   681		const struct applesmc_entry *entry;
   682		unsigned int i;
   683	
   684		if (s->index)
   685			return 0;
   686	
   687		s->index = kcalloc(s->temp_count, sizeof(s->index[0]), GFP_KERNEL);
   688		if (!s->index)
   689			return -ENOMEM;
   690	
   691		for (i = s->temp_begin; i < s->temp_end; i++) {
   692			entry = applesmc_get_entry_by_index(i);
   693			if (IS_ERR(entry))
   694				continue;
   695			if (strcmp(entry->type, TEMP_SENSOR_TYPE))
   696				continue;
   697			s->index[s->index_count++] = entry->key;
   698		}
   699	
   700		return 0;
   701	}
   702	/*
   703	 * applesmc_init_mmio_try - Try to initialize MMIO
   704	 */
   705	static int applesmc_init_mmio_try(void)
   706	{
   707		u8 ldkn_version;
   708		acpi_status status;
   709		struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
   710		struct acpi_device *adev;
   711		struct acpi_resource *res;
   712	
   713		adev = acpi_dev_get_first_match_dev("APP0001", NULL, -1);
   714		if (!adev)
   715			return -ENXIO;
   716	
 > 717		status = acpi_get_current_resources(adev->handle, &buffer);
   718		if (ACPI_FAILURE(status))
   719			return -ENXIO;
   720	
   721		res = buffer.pointer;
   722		while (res->type != ACPI_RESOURCE_TYPE_END_TAG) {
   723			if (res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) {
   724				if (res->data.fixed_memory32.address_length < 0x4006)
   725					return -ENXIO;
   726	
   727				mmio_base_addr = res->data.fixed_memory32.address;
   728				mmio_base_size = res->data.fixed_memory32.address_length;
   729				is_mmio = true;
   730				break;
   731			}
   732			res = ACPI_NEXT_RESOURCE(res);
   733		}
   734		kfree(buffer.pointer);
   735		acpi_dev_put(adev);
   736	
   737		if (!is_mmio)
   738			return -ENXIO;
   739	
   740		mmio_base = ioremap(mmio_base_addr, mmio_base_size);
   741	
   742		if (!mmio_base)
   743			return -ENXIO;
   744	
   745		if (ioread8(mmio_base + 0x4005) == 0xFF)
   746			goto out;
   747	
   748		if (read_smc(APPLESMC_READ_CMD, "LDKN", &ldkn_version, 1))
   749			goto out;
   750	
   751		if (ldkn_version < 2)
   752			goto out;
   753	
   754		return 0;
   755	out:
   756		pr_warn("cannot enable MMIO will use PMIO\n");
   757		iounmap(mmio_base);
   758		return -ENXIO;
   759	}
   760	/*
   761	 * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent.
   762	 */
   763	static int applesmc_init_smcreg_try(void)
   764	{
   765		struct applesmc_registers *s = &smcreg;
   766		bool left_light_sensor = false, right_light_sensor = false;
   767		unsigned int count;
   768		u8 tmp[1];
   769		int ret;
   770	
   771		if (s->init_complete)
   772			return 0;
   773	
   774		ret = read_register_count(&count);
   775		if (ret)
   776			return ret;
   777	
   778		if (s->cache && s->key_count != count) {
   779			pr_warn("key count changed from %d to %d\n",
   780				s->key_count, count);
   781			kfree(s->cache);
   782			s->cache = NULL;
   783		}
   784		s->key_count = count;
   785	
   786		if (!s->cache)
   787			s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL);
   788		if (!s->cache)
   789			return -ENOMEM;
   790	
   791		ret = applesmc_read_key(FANS_COUNT, tmp, 1);
   792		if (ret)
   793			return ret;
   794		s->fan_count = tmp[0];
   795		if (s->fan_count > 10)
   796			s->fan_count = 10;
   797	
   798		ret = applesmc_get_lower_bound(&s->temp_begin, "T");
   799		if (ret)
   800			return ret;
   801		ret = applesmc_get_lower_bound(&s->temp_end, "U");
   802		if (ret)
   803			return ret;
   804		s->temp_count = s->temp_end - s->temp_begin;
   805	
   806		ret = applesmc_init_index(s);
   807		if (ret)
   808			return ret;
   809	
   810		ret = applesmc_has_key(LIGHT_SENSOR_LEFT_KEY, &left_light_sensor);
   811		if (ret)
   812			return ret;
   813		ret = applesmc_has_key(LIGHT_SENSOR_RIGHT_KEY, &right_light_sensor);
   814		if (ret)
   815			return ret;
   816		ret = applesmc_has_key(MOTION_SENSOR_KEY, &s->has_accelerometer);
   817		if (ret)
   818			return ret;
   819		ret = applesmc_has_key(BACKLIGHT_KEY, &s->has_key_backlight);
   820		if (ret)
   821			return ret;
   822	
   823		s->num_light_sensors = left_light_sensor + right_light_sensor;
   824		s->init_complete = true;
   825	
   826		pr_info("key=%d fan=%d temp=%d index=%d acc=%d lux=%d kbd=%d\n",
   827		       s->key_count, s->fan_count, s->temp_count, s->index_count,
   828		       s->has_accelerometer,
   829		       s->num_light_sensors,
   830		       s->has_key_backlight);
   831	
   832		return 0;
   833	}
   834	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki