summaryrefslogtreecommitdiff
path: root/drivers/mfd/rsmu_spi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-05-02 20:41:31 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2023-05-02 20:41:31 +0300
commit3af49062b0115b55a54615109172b44f618daf97 (patch)
tree54bc04f20c95dc27362978c04e7d00e2399f9904 /drivers/mfd/rsmu_spi.c
parentc5eb8bf76718cf2e2f36aac216a99014f00927de (diff)
parent9e9ff39243ea8795a4833708613f884b39dc91f9 (diff)
downloadlinux-3af49062b0115b55a54615109172b44f618daf97.tar.xz
Merge tag 'mfd-next-6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones: "New Drivers: - Add support for Renesas RZ/G2L MTU3 New Device Support: - Add support for Lenovo Yoga Book X90F to Intel CHT WC - Add support for MAX5970 and MAX5978 to Simple MFD (I2C) - Add support for Meteor Lake PCH-S LPSS PCI to Intel LPSS PCI - Add support for AXP15060 PMIC to X-Powers PMIC collection Remove Device Support: - Remove support for Samsung 5M8751 and S5M8763 PMIC devices New Functionality: - Convert deprecated QCOM IRQ Chip to config registers - Add support for 32-bit address spaces to Renesas SMUs Fix-ups: - Make use of APIs / MACROs designed to simplify and demystify - Add / improve Device Tree bindings - Memory saving struct layout optimisations - Remove old / deprecated functionality - Factor out unassigned register addresses from ranges - Trivial: Spelling fixes, renames and coding style fixes - Rid 'defined but not used' warnings - Remove ineffective casts and pointer stubs Bug Fixes: - Fix incorrectly non-inverted mask/unmask IRQs on QCOM platforms - Remove MODULE_*() helpers from non-tristate drivers - Do not attempt to use out-of-range memory addresses associated with io_base - Provide missing export helpers - Fix remap bulk read optimisation fallout - Fix memory leak issues in error paths" * tag 'mfd-next-6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (88 commits) dt-bindings: mfd: ti,j721e-system-controller: Add SoC chip ID leds: bd2606mvv: Driver for the Rohm 6 Channel i2c LED driver dt-bindings: mfd: qcom,spmi-pmic: Document flash LED controller dt-bindings: mfd: x-powers,axp152: Document the AXP15060 variant mfd: axp20x: Add support for AXP15060 PMIC dt-bindings: mfd: x-powers,axp152: Document the AXP313a variant counter: rz-mtu3-cnt: Unlock on error in rz_mtu3_count_ceiling_write() dt-bindings: mfd: dlg,da9063: Document voltage monitoring dt-bindings: mfd: stm32: Remove unnecessary blank lines dt-bindings: mfd: qcom,spmi-pmic: Use generic ADC node name in examples dt-bindings: mfd: syscon: Add nuvoton,ma35d1-sys compatible MAINTAINERS: Add entries for Renesas RZ/G2L MTU3a counter driver counter: Add Renesas RZ/G2L MTU3a counter driver Documentation: ABI: sysfs-bus-counter: add cascade_counts_enable and external_input_phase_clock_select mfd: Add Renesas RZ/G2L MTU3a core driver dt-bindings: timer: Document RZ/G2L MTU3a bindings mfd: rsmu_i2c: Convert to i2c's .probe_new() again mfd: intel-lpss: Add Intel Meteor Lake PCH-S LPSS PCI IDs mfd: dln2: Fix memory leak in dln2_probe() mfd: axp20x: Fix axp288 writable-ranges ...
Diffstat (limited to 'drivers/mfd/rsmu_spi.c')
-rw-r--r--drivers/mfd/rsmu_spi.c48
1 files changed, 31 insertions, 17 deletions
diff --git a/drivers/mfd/rsmu_spi.c b/drivers/mfd/rsmu_spi.c
index d2f3d8f1e05a..a4a595bb8d0d 100644
--- a/drivers/mfd/rsmu_spi.c
+++ b/drivers/mfd/rsmu_spi.c
@@ -19,19 +19,21 @@
#define RSMU_CM_PAGE_ADDR 0x7C
#define RSMU_SABRE_PAGE_ADDR 0x7F
-#define RSMU_HIGHER_ADDR_MASK 0xFF80
-#define RSMU_HIGHER_ADDR_SHIFT 7
-#define RSMU_LOWER_ADDR_MASK 0x7F
+#define RSMU_PAGE_MASK 0xFFFFFF80
+#define RSMU_ADDR_MASK 0x7F
static int rsmu_read_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes)
{
struct spi_device *client = to_spi_device(rsmu->dev);
struct spi_transfer xfer = {0};
struct spi_message msg;
- u8 cmd[256] = {0};
- u8 rsp[256] = {0};
+ u8 cmd[RSMU_MAX_READ_COUNT + 1] = {0};
+ u8 rsp[RSMU_MAX_READ_COUNT + 1] = {0};
int ret;
+ if (bytes > RSMU_MAX_READ_COUNT)
+ return -EINVAL;
+
cmd[0] = reg | 0x80;
xfer.rx_buf = rsp;
xfer.len = bytes + 1;
@@ -66,7 +68,10 @@ static int rsmu_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes
struct spi_device *client = to_spi_device(rsmu->dev);
struct spi_transfer xfer = {0};
struct spi_message msg;
- u8 cmd[256] = {0};
+ u8 cmd[RSMU_MAX_WRITE_COUNT + 1] = {0};
+
+ if (bytes > RSMU_MAX_WRITE_COUNT)
+ return -EINVAL;
cmd[0] = reg;
memcpy(&cmd[1], buf, bytes);
@@ -86,26 +91,35 @@ static int rsmu_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes
* 16-bit register address: the lower 7 bits of the register address come
* from the offset addr byte and the upper 9 bits come from the page register.
*/
-static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u16 reg)
+static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u32 reg)
{
u8 page_reg;
- u8 buf[2];
+ u8 buf[4];
u16 bytes;
- u16 page;
+ u32 page;
int err;
switch (rsmu->type) {
case RSMU_CM:
+ /* Do not modify page register for none-scsr registers */
+ if (reg < RSMU_CM_SCSR_BASE)
+ return 0;
page_reg = RSMU_CM_PAGE_ADDR;
- page = reg & RSMU_HIGHER_ADDR_MASK;
+ page = reg & RSMU_PAGE_MASK;
buf[0] = (u8)(page & 0xff);
buf[1] = (u8)((page >> 8) & 0xff);
- bytes = 2;
+ buf[2] = (u8)((page >> 16) & 0xff);
+ buf[3] = (u8)((page >> 24) & 0xff);
+ bytes = 4;
break;
case RSMU_SABRE:
+ /* Do not modify page register if reg is page register itself */
+ if ((reg & RSMU_ADDR_MASK) == RSMU_ADDR_MASK)
+ return 0;
page_reg = RSMU_SABRE_PAGE_ADDR;
- page = reg >> RSMU_HIGHER_ADDR_SHIFT;
- buf[0] = (u8)(page & 0xff);
+ page = reg & RSMU_PAGE_MASK;
+ /* The three page bits are located in the single Page Register */
+ buf[0] = (u8)((page >> 7) & 0x7);
bytes = 1;
break;
default:
@@ -130,7 +144,7 @@ static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u16 reg)
static int rsmu_reg_read(void *context, unsigned int reg, unsigned int *val)
{
struct rsmu_ddata *rsmu = spi_get_drvdata((struct spi_device *)context);
- u8 addr = (u8)(reg & RSMU_LOWER_ADDR_MASK);
+ u8 addr = (u8)(reg & RSMU_ADDR_MASK);
int err;
err = rsmu_write_page_register(rsmu, reg);
@@ -147,7 +161,7 @@ static int rsmu_reg_read(void *context, unsigned int reg, unsigned int *val)
static int rsmu_reg_write(void *context, unsigned int reg, unsigned int val)
{
struct rsmu_ddata *rsmu = spi_get_drvdata((struct spi_device *)context);
- u8 addr = (u8)(reg & RSMU_LOWER_ADDR_MASK);
+ u8 addr = (u8)(reg & RSMU_ADDR_MASK);
u8 data = (u8)val;
int err;
@@ -164,9 +178,9 @@ static int rsmu_reg_write(void *context, unsigned int reg, unsigned int val)
}
static const struct regmap_config rsmu_cm_regmap_config = {
- .reg_bits = 16,
+ .reg_bits = 32,
.val_bits = 8,
- .max_register = 0xD000,
+ .max_register = 0x20120000,
.reg_read = rsmu_reg_read,
.reg_write = rsmu_reg_write,
.cache_type = REGCACHE_NONE,