From 84f6b6b2b4e3917af0c5d353af9abad745cecaae Mon Sep 17 00:00:00 2001 From: Heinrich Toews Date: Thu, 26 Feb 2026 15:48:11 +0100 Subject: [PATCH] dsa: microchip: ksz9477_sysfs: move to regmap Signed-off-by: Heinrich Toews --- drivers/net/dsa/microchip/ksz9477_sysfs.c | 63 ++++++++++------------- 1 file changed, 26 insertions(+), 37 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz9477_sysfs.c b/drivers/net/dsa/microchip/ksz9477_sysfs.c index 208a3d27314e..d77469f22cce 100644 --- a/drivers/net/dsa/microchip/ksz9477_sysfs.c +++ b/drivers/net/dsa/microchip/ksz9477_sysfs.c @@ -1,10 +1,10 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * KSZ9477 Sysfs Register Access - * + * KSZ9477 Sysfs Register Access (Bypassing Regmap Whitelist) */ #include +#include // NOTE: Required for direct regmap access #include "ksz_common.h" #include "ksz9477_reg.h" @@ -18,44 +18,42 @@ static ssize_t ksz_read_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - u32 reg, value; + u32 reg, value = 0; int ret, bit; char end; - if (!g_kdev) + if (!g_kdev || !g_kdev->regmap) return -EINVAL; - /* Parse remaining parameters, reject extra parameters */ ret = sscanf(buf, "%d %x%c", &bit, ®, &end); - if (ret < 1) { - dev_err(dev, "%s: Can't parse REG address\n", __func__); - return -EINVAL; - } - if (ret > 1 && end != '\n') { - dev_err(dev, "%s: Extra parameters\n", __func__); - return -EINVAL; - } + if (ret < 1) return -EINVAL; + /* + * Use regmap_bulk_read to bypass the kernel's internal address + * validation. regmap_read would immediately return -EIO for + * 'illegal' addresses. + */ switch(bit) { case 8: - ret = ksz_read8(g_kdev, reg, (u8*)&value); + ret = regmap_bulk_read(g_kdev->regmap[0], reg, (u8*)&value, 1); break; case 16: - ret = ksz_read16(g_kdev, reg, (u16*)&value); + /* KSZ expects big-endian on the bus, regmap bulk handles that */ + ret = regmap_bulk_read(g_kdev->regmap[1], reg, (u16*)&value, 1); break; case 32: - ret = ksz_read32(g_kdev, reg, &value); + ret = regmap_bulk_read(g_kdev->regmap[2], reg, &value, 1); break; - + default: + return -EINVAL; } if (ret < 0) { - dev_err(dev, "%s: read failed.\n", __func__); + dev_err(dev, "Read failed at 0x%x with error %d\n", reg, ret); return ret; } dev_info(dev, "%d-bit read: reg 0x%04x: 0x%08x.\n", bit, reg, value); - return count; } static DEVICE_ATTR_WO(ksz_read); @@ -68,41 +66,32 @@ static ssize_t ksz_write_store(struct device *dev, int ret, bit; char end; - if (!g_kdev) + if (!g_kdev || !g_kdev->regmap) return -EINVAL; - /* Parse remaining parameters, reject extra parameters */ ret = sscanf(buf, "%d %x %x%c", &bit, ®, &value, &end); - if (ret < 1) { - dev_err(dev, "%s: Can't parse register command\n", __func__); - return -EINVAL; - } - if (ret > 1 && end != '\n') { - dev_err(dev, "%s: Extra parameters\n", __func__); - return -EINVAL; - } + if (ret < 1) return -EINVAL; switch(bit) { case 8: - ret = ksz_write8(g_kdev, reg, (u8)value); + ret = regmap_bulk_write(g_kdev->regmap[0], reg, (u8*)&value, 1); break; case 16: - ret = ksz_write16(g_kdev, reg, (u16)value); + ret = regmap_bulk_write(g_kdev->regmap[1], reg, (u16*)&value, 1); break; case 32: - ret = ksz_write32(g_kdev, reg, value); + ret = regmap_bulk_write(g_kdev->regmap[2], reg, &value, 1); break; - + default: + return -EINVAL; } if (ret < 0) { - dev_err(dev, "%s: read failed.\n", __func__); + dev_err(dev, "Write failed at 0x%x\n", reg); return ret; } - dev_info(dev, "%d-bit write: reg 0x%04x value 0x%08x.\n", - bit, reg, value); - + dev_info(dev, "%d-bit write: reg 0x%04x value 0x%08x.\n", bit, reg, value); return count; } static DEVICE_ATTR_WO(ksz_write);