From c83ccdc9586b3e9882da9e27507c046751999d59 Mon Sep 17 00:00:00 2001 From: Nuno Sa Date: Fri, 9 Feb 2024 16:50:34 +0100 Subject: counter: fix privdata alignment Aligning to the L1 cache does not guarantee the same alignment as kmallocing an object [1]. Furthermore, in some platforms, that alignment is not sufficient for DMA safety (in case someone wants to have a DMA safe buffer in privdata) [2]. Sometime ago, we had the same fixes in IIO. [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/base/devres.c#n35 [2]: https://lore.kernel.org/linux-iio/20220508175712.647246-2-jic23@kernel.org/ Fixes: c18e2760308e ("counter: Provide alternative counter registration functions") Signed-off-by: Nuno Sa Link: https://lore.kernel.org/r/20240209-counter-align-fix-v2-1-5777ea0a2722@analog.com Signed-off-by: William Breathitt Gray --- drivers/counter/counter-core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/counter/counter-core.c b/drivers/counter/counter-core.c index 09c77afb33ca..3f24481fc04a 100644 --- a/drivers/counter/counter-core.c +++ b/drivers/counter/counter-core.c @@ -31,10 +31,11 @@ struct counter_device_allochelper { struct counter_device counter; /* - * This is cache line aligned to ensure private data behaves like if it - * were kmalloced separately. + * This ensures private data behaves like if it were kmalloced + * separately. Also ensures the minimum alignment for safe DMA + * operations (which may or may not mean cache alignment). */ - unsigned long privdata[] ____cacheline_aligned; + unsigned long privdata[] __aligned(ARCH_DMA_MINALIGN); }; static void counter_device_release(struct device *dev) -- cgit v1.2.3 From 7a9b9012043e126f6d6f4683e67409312d1b707b Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Sun, 11 Feb 2024 12:39:11 +0200 Subject: mei: me: add arrow lake point S DID Add Arrow Lake S device id. Cc: stable@vger.kernel.org Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Link: https://lore.kernel.org/r/20240211103912.117105-1-tomas.winkler@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw-me-regs.h | 1 + drivers/misc/mei/pci-me.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h index 961e5d53a27a..b10536e4974d 100644 --- a/drivers/misc/mei/hw-me-regs.h +++ b/drivers/misc/mei/hw-me-regs.h @@ -112,6 +112,7 @@ #define MEI_DEV_ID_RPL_S 0x7A68 /* Raptor Lake Point S */ #define MEI_DEV_ID_MTL_M 0x7E70 /* Meteor Lake Point M */ +#define MEI_DEV_ID_ARL_S 0x7F68 /* Arrow Lake Point S */ /* * MEI HW Section diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 676d566f38dd..1a614fb7fdb6 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -119,6 +119,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = { {MEI_PCI_DEVICE(MEI_DEV_ID_RPL_S, MEI_ME_PCH15_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_MTL_M, MEI_ME_PCH15_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ARL_S, MEI_ME_PCH15_CFG)}, /* required last entry */ {0, } -- cgit v1.2.3 From 8436f25802ec028ac7254990893f3e01926d9b79 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Sun, 11 Feb 2024 12:39:12 +0200 Subject: mei: me: add arrow lake point H DID Add Arrow Lake H device id. Cc: stable@vger.kernel.org Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Link: https://lore.kernel.org/r/20240211103912.117105-2-tomas.winkler@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw-me-regs.h | 1 + drivers/misc/mei/pci-me.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h index b10536e4974d..aac36750d2c5 100644 --- a/drivers/misc/mei/hw-me-regs.h +++ b/drivers/misc/mei/hw-me-regs.h @@ -113,6 +113,7 @@ #define MEI_DEV_ID_MTL_M 0x7E70 /* Meteor Lake Point M */ #define MEI_DEV_ID_ARL_S 0x7F68 /* Arrow Lake Point S */ +#define MEI_DEV_ID_ARL_H 0x7770 /* Arrow Lake Point H */ /* * MEI HW Section diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 1a614fb7fdb6..8cf636c54032 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -120,6 +120,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = { {MEI_PCI_DEVICE(MEI_DEV_ID_MTL_M, MEI_ME_PCH15_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_ARL_S, MEI_ME_PCH15_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ARL_H, MEI_ME_PCH15_CFG)}, /* required last entry */ {0, } -- cgit v1.2.3 From daaf5286b6d2528a73c651aa2d4059bc1bd67c2e Mon Sep 17 00:00:00 2001 From: Wentong Wu Date: Wed, 7 Feb 2024 08:43:04 +0800 Subject: mei: Add Meteor Lake support for IVSC device Add IVSC device support on Meteor Lake platform. Signed-off-by: Wentong Wu Cc: stable Reviewed-by: Sakari Ailus Acked-by: Tomas Winkler Link: https://lore.kernel.org/r/20240207004304.31862-1-wentong.wu@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/vsc-tp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/misc/mei/vsc-tp.c b/drivers/misc/mei/vsc-tp.c index 6f4a4be6ccb5..55f7db490d3b 100644 --- a/drivers/misc/mei/vsc-tp.c +++ b/drivers/misc/mei/vsc-tp.c @@ -535,6 +535,7 @@ static const struct acpi_device_id vsc_tp_acpi_ids[] = { { "INTC1009" }, /* Raptor Lake */ { "INTC1058" }, /* Tiger Lake */ { "INTC1094" }, /* Alder Lake */ + { "INTC10D0" }, /* Meteor Lake */ {} }; MODULE_DEVICE_TABLE(acpi, vsc_tp_acpi_ids); -- cgit v1.2.3 From 60caa8b33bd682a9ed99d1fc3f91d74e1acc9922 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Maneyrol Date: Mon, 19 Feb 2024 15:48:25 +0000 Subject: iio: imu: inv_mpu6050: fix FIFO parsing when empty Now that we are reading the full FIFO in the interrupt handler, it is possible to have an emply FIFO since we are still receiving 1 interrupt per data. Handle correctly this case instead of having an error causing a reset of the FIFO. Fixes: 0829edc43e0a ("iio: imu: inv_mpu6050: read the full fifo when processing data") Cc: stable@vger.kernel.org Signed-off-by: Jean-Baptiste Maneyrol Link: https://lore.kernel.org/r/20240219154825.90656-1-inv.git-commit@tdk.com Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c index 66d4ba088e70..d4f9b5d8d28d 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c @@ -109,6 +109,8 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) /* compute and process only all complete datum */ nb = fifo_count / bytes_per_datum; fifo_count = nb * bytes_per_datum; + if (nb == 0) + goto end_session; /* Each FIFO data contains all sensors, so same number for FIFO and sensor data */ fifo_period = NSEC_PER_SEC / INV_MPU6050_DIVIDER_TO_FIFO_RATE(st->chip_config.divider); inv_sensors_timestamp_interrupt(&st->timestamp, fifo_period, nb, nb, pf->timestamp); -- cgit v1.2.3 From a9dd9ba323114f366eb07f1d9630822f8df6cbb2 Mon Sep 17 00:00:00 2001 From: Vasileios Amoiridis Date: Mon, 19 Feb 2024 20:13:59 +0100 Subject: iio: pressure: Fixes BMP38x and BMP390 SPI support According to the datasheet of BMP38x and BMP390 devices, for an SPI read operation the first byte that is returned needs to be dropped, and the rest of the bytes are the actual data returned from the sensor. Reviewed-by: Andy Shevchenko Fixes: 8d329309184d ("iio: pressure: bmp280: Add support for BMP380 sensor family") Signed-off-by: Vasileios Amoiridis Acked-by: Angel Iglesias Link: https://lore.kernel.org/r/20240219191359.18367-1-vassilisamir@gmail.com Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/bmp280-spi.c | 50 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c index e8a5fed07e88..a444d4b2978b 100644 --- a/drivers/iio/pressure/bmp280-spi.c +++ b/drivers/iio/pressure/bmp280-spi.c @@ -4,6 +4,7 @@ * * Inspired by the older BMP085 driver drivers/misc/bmp085-spi.c */ +#include #include #include #include @@ -35,6 +36,34 @@ static int bmp280_regmap_spi_read(void *context, const void *reg, return spi_write_then_read(spi, reg, reg_size, val, val_size); } +static int bmp380_regmap_spi_read(void *context, const void *reg, + size_t reg_size, void *val, size_t val_size) +{ + struct spi_device *spi = to_spi_device(context); + u8 rx_buf[4]; + ssize_t status; + + /* + * Maximum number of consecutive bytes read for a temperature or + * pressure measurement is 3. + */ + if (val_size > 3) + return -EINVAL; + + /* + * According to the BMP3xx datasheets, for a basic SPI read opertion, + * the first byte needs to be dropped and the rest are the requested + * data. + */ + status = spi_write_then_read(spi, reg, 1, rx_buf, val_size + 1); + if (status) + return status; + + memcpy(val, rx_buf + 1, val_size); + + return 0; +} + static struct regmap_bus bmp280_regmap_bus = { .write = bmp280_regmap_spi_write, .read = bmp280_regmap_spi_read, @@ -42,10 +71,19 @@ static struct regmap_bus bmp280_regmap_bus = { .val_format_endian_default = REGMAP_ENDIAN_BIG, }; +static struct regmap_bus bmp380_regmap_bus = { + .write = bmp280_regmap_spi_write, + .read = bmp380_regmap_spi_read, + .read_flag_mask = BIT(7), + .reg_format_endian_default = REGMAP_ENDIAN_BIG, + .val_format_endian_default = REGMAP_ENDIAN_BIG, +}; + static int bmp280_spi_probe(struct spi_device *spi) { const struct spi_device_id *id = spi_get_device_id(spi); const struct bmp280_chip_info *chip_info; + struct regmap_bus *bmp_regmap_bus; struct regmap *regmap; int ret; @@ -58,8 +96,18 @@ static int bmp280_spi_probe(struct spi_device *spi) chip_info = spi_get_device_match_data(spi); + switch (chip_info->chip_id[0]) { + case BMP380_CHIP_ID: + case BMP390_CHIP_ID: + bmp_regmap_bus = &bmp380_regmap_bus; + break; + default: + bmp_regmap_bus = &bmp280_regmap_bus; + break; + } + regmap = devm_regmap_init(&spi->dev, - &bmp280_regmap_bus, + bmp_regmap_bus, &spi->dev, chip_info->regmap_config); if (IS_ERR(regmap)) { -- cgit v1.2.3 From daec424cc57b33a28f8621eb7ac85f8bd327bd6b Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Maneyrol Date: Mon, 19 Feb 2024 15:47:41 +0000 Subject: iio: imu: inv_mpu6050: fix frequency setting when chip is off Track correctly FIFO state and apply ODR change before starting the chip. Without the fix, you cannot change ODR more than 1 time when data buffering is off. This restriction on a single pending ODR change should only apply when the FIFO is on. Fixes: 111e1abd0045 ("iio: imu: inv_mpu6050: use the common inv_sensors timestamp module") Cc: stable@vger.kernel.org Signed-off-by: Jean-Baptiste Maneyrol Link: https://lore.kernel.org/r/20240219154741.90601-1-inv.git-commit@tdk.com Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c index 676704f9151f..e6e6e94452a3 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c @@ -111,6 +111,7 @@ int inv_mpu6050_prepare_fifo(struct inv_mpu6050_state *st, bool enable) if (enable) { /* reset timestamping */ inv_sensors_timestamp_reset(&st->timestamp); + inv_sensors_timestamp_apply_odr(&st->timestamp, 0, 0, 0); /* reset FIFO */ d = st->chip_config.user_ctrl | INV_MPU6050_BIT_FIFO_RST; ret = regmap_write(st->map, st->reg->user_ctrl, d); @@ -184,6 +185,10 @@ static int inv_mpu6050_set_enable(struct iio_dev *indio_dev, bool enable) if (result) goto error_power_off; } else { + st->chip_config.gyro_fifo_enable = 0; + st->chip_config.accl_fifo_enable = 0; + st->chip_config.temp_fifo_enable = 0; + st->chip_config.magn_fifo_enable = 0; result = inv_mpu6050_prepare_fifo(st, false); if (result) goto error_power_off; -- cgit v1.2.3 From a1c9f508db2543aae59ea2378b07a026f6c917cf Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 23 Feb 2024 09:29:39 -0800 Subject: iio: pressure: dlhl60d: Initialize empty DLH bytes 3 bytes were being read but 4 were being written. Explicitly initialize the unused bytes to 0 and refactor the loop to use direct array indexing, which appears to silence a Clang false positive warning[1]. Indent improvement included for readability of the fixed code. Link: https://github.com/ClangBuiltLinux/linux/issues/2000 [1] Fixes: ac78c6aa4a5d ("iio: pressure: Add driver for DLH pressure sensors") Signed-off-by: Kees Cook Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20240223172936.it.875-kees@kernel.org Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/dlhl60d.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/pressure/dlhl60d.c b/drivers/iio/pressure/dlhl60d.c index 28c8269ba65d..0bba4c5a8d40 100644 --- a/drivers/iio/pressure/dlhl60d.c +++ b/drivers/iio/pressure/dlhl60d.c @@ -250,18 +250,17 @@ static irqreturn_t dlh_trigger_handler(int irq, void *private) struct dlh_state *st = iio_priv(indio_dev); int ret; unsigned int chn, i = 0; - __be32 tmp_buf[2]; + __be32 tmp_buf[2] = { }; ret = dlh_start_capture_and_read(st); if (ret) goto out; for_each_set_bit(chn, indio_dev->active_scan_mask, - indio_dev->masklength) { - memcpy(tmp_buf + i, + indio_dev->masklength) { + memcpy(&tmp_buf[i++], &st->rx_buf[1] + chn * DLH_NUM_DATA_BYTES, DLH_NUM_DATA_BYTES); - i++; } iio_push_to_buffers(indio_dev, tmp_buf); -- cgit v1.2.3 From 1b926914bbe4e30cb32f268893ef7d82a85275b8 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Wed, 7 Feb 2024 05:36:50 +0200 Subject: iio: accel: adxl367: fix DEVID read after reset regmap_read_poll_timeout() will not sleep before reading, causing the first read to return -ENXIO on I2C, since the chip does not respond to it while it is being reset. The datasheet specifies that a soft reset operation has a latency of 7.5ms. Add a 15ms sleep between reset and reading the DEVID register, and switch to a simple regmap_read() call. Fixes: cbab791c5e2a ("iio: accel: add ADXL367 driver") Signed-off-by: Cosmin Tanislav Reviewed-by: Nuno Sa Link: https://lore.kernel.org/r/20240207033657.206171-1-demonsingur@gmail.com Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adxl367.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/adxl367.c b/drivers/iio/accel/adxl367.c index 90b7ae6d42b7..484fe2e9fb17 100644 --- a/drivers/iio/accel/adxl367.c +++ b/drivers/iio/accel/adxl367.c @@ -1429,9 +1429,11 @@ static int adxl367_verify_devid(struct adxl367_state *st) unsigned int val; int ret; - ret = regmap_read_poll_timeout(st->regmap, ADXL367_REG_DEVID, val, - val == ADXL367_DEVID_AD, 1000, 10000); + ret = regmap_read(st->regmap, ADXL367_REG_DEVID, &val); if (ret) + return dev_err_probe(st->dev, ret, "Failed to read dev id\n"); + + if (val != ADXL367_DEVID_AD) return dev_err_probe(st->dev, -ENODEV, "Invalid dev id 0x%02X, expected 0x%02X\n", val, ADXL367_DEVID_AD); @@ -1510,6 +1512,8 @@ int adxl367_probe(struct device *dev, const struct adxl367_ops *ops, if (ret) return ret; + fsleep(15000); + ret = adxl367_verify_devid(st); if (ret) return ret; -- cgit v1.2.3 From 11dadb631007324c7a8bcb2650eda88ed2b9eed0 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Wed, 7 Feb 2024 05:36:51 +0200 Subject: iio: accel: adxl367: fix I2C FIFO data register As specified in the datasheet, the I2C FIFO data register is 0x18, not 0x42. 0x42 was used by mistake when adapting the ADXL372 driver. Fix this mistake. Fixes: cbab791c5e2a ("iio: accel: add ADXL367 driver") Signed-off-by: Cosmin Tanislav Reviewed-by: Nuno Sa Link: https://lore.kernel.org/r/20240207033657.206171-2-demonsingur@gmail.com Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adxl367_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/accel/adxl367_i2c.c b/drivers/iio/accel/adxl367_i2c.c index b595fe94f3a3..62c74bdc0d77 100644 --- a/drivers/iio/accel/adxl367_i2c.c +++ b/drivers/iio/accel/adxl367_i2c.c @@ -11,7 +11,7 @@ #include "adxl367.h" -#define ADXL367_I2C_FIFO_DATA 0x42 +#define ADXL367_I2C_FIFO_DATA 0x18 struct adxl367_i2c_state { struct regmap *regmap; -- cgit v1.2.3 From ac3e0384073b2408d6cb0d972fee9fcc3776053d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 20 Feb 2024 20:00:35 +0100 Subject: misc: lis3lv02d_i2c: Fix regulators getting en-/dis-abled twice on suspend/resume When not configured for wakeup lis3lv02d_i2c_suspend() will call lis3lv02d_poweroff() even if the device has already been turned off by the runtime-suspend handler and if configured for wakeup and the device is runtime-suspended at this point then it is not turned back on to serve as a wakeup source. Before commit b1b9f7a49440 ("misc: lis3lv02d_i2c: Add missing setting of the reg_ctrl callback"), lis3lv02d_poweroff() failed to disable the regulators which as a side effect made calling poweroff() twice ok. Now that poweroff() correctly disables the regulators, doing this twice triggers a WARN() in the regulator core: unbalanced disables for regulator-dummy WARNING: CPU: 1 PID: 92 at drivers/regulator/core.c:2999 _regulator_disable ... Fix lis3lv02d_i2c_suspend() to not call poweroff() a second time if already runtime-suspended and add a poweron() call when necessary to make wakeup work. lis3lv02d_i2c_resume() has similar issues, with an added weirness that it always powers on the device if it is runtime suspended, after which the first runtime-resume will call poweron() again, causing the enabled count for the regulator to increase by 1 every suspend/resume. These unbalanced regulator_enable() calls cause the regulator to never be turned off and trigger the following WARN() on driver unbind: WARNING: CPU: 1 PID: 1724 at drivers/regulator/core.c:2396 _regulator_put Fix this by making lis3lv02d_i2c_resume() mirror the new suspend(). Fixes: b1b9f7a49440 ("misc: lis3lv02d_i2c: Add missing setting of the reg_ctrl callback") Reported-by: Paul Menzel Closes: https://lore.kernel.org/regressions/5fc6da74-af0a-4aac-b4d5-a000b39a63a5@molgen.mpg.de/ Cc: stable@vger.kernel.org Cc: regressions@lists.linux.dev Signed-off-by: Hans de Goede Tested-by: Paul Menzel # Dell XPS 15 7590 Reviewed-by: Paul Menzel Link: https://lore.kernel.org/r/20240220190035.53402-1-hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/lis3lv02d/lis3lv02d_i2c.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c index c6eb27d46cb0..15119584473c 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c @@ -198,8 +198,14 @@ static int lis3lv02d_i2c_suspend(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct lis3lv02d *lis3 = i2c_get_clientdata(client); - if (!lis3->pdata || !lis3->pdata->wakeup_flags) + /* Turn on for wakeup if turned off by runtime suspend */ + if (lis3->pdata && lis3->pdata->wakeup_flags) { + if (pm_runtime_suspended(dev)) + lis3lv02d_poweron(lis3); + /* For non wakeup turn off if not already turned off by runtime suspend */ + } else if (!pm_runtime_suspended(dev)) lis3lv02d_poweroff(lis3); + return 0; } @@ -208,13 +214,12 @@ static int lis3lv02d_i2c_resume(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct lis3lv02d *lis3 = i2c_get_clientdata(client); - /* - * pm_runtime documentation says that devices should always - * be powered on at resume. Pm_runtime turns them off after system - * wide resume is complete. - */ - if (!lis3->pdata || !lis3->pdata->wakeup_flags || - pm_runtime_suspended(dev)) + /* Turn back off if turned on for wakeup and runtime suspended*/ + if (lis3->pdata && lis3->pdata->wakeup_flags) { + if (pm_runtime_suspended(dev)) + lis3lv02d_poweroff(lis3); + /* For non wakeup turn back on if not runtime suspended */ + } else if (!pm_runtime_suspended(dev)) lis3lv02d_poweron(lis3); return 0; -- cgit v1.2.3 From cfa9ba1ae0bef0681833a22d326174fe633caab5 Mon Sep 17 00:00:00 2001 From: Frej Drejhammar Date: Sun, 11 Feb 2024 18:58:22 +0100 Subject: comedi: comedi_8255: Correct error in subdevice initialization The refactoring done in commit 5c57b1ccecc7 ("comedi: comedi_8255: Rework subdevice initialization functions") to the initialization of the io field of struct subdev_8255_private broke all cards using the drivers/comedi/drivers/comedi_8255.c module. Prior to 5c57b1ccecc7, __subdev_8255_init() initialized the io field in the newly allocated struct subdev_8255_private to the non-NULL callback given to the function, otherwise it used a flag parameter to select between subdev_8255_mmio and subdev_8255_io. The refactoring removed that logic and the flag, as subdev_8255_mm_init() and subdev_8255_io_init() now explicitly pass subdev_8255_mmio and subdev_8255_io respectively to __subdev_8255_init(), only __subdev_8255_init() never sets spriv->io to the supplied callback. That spriv->io is NULL leads to a later BUG: BUG: kernel NULL pointer dereference, address: 0000000000000000 PGD 0 P4D 0 Oops: 0010 [#1] SMP PTI CPU: 1 PID: 1210 Comm: systemd-udevd Not tainted 6.7.3-x86_64 #1 Hardware name: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX RIP: 0010:0x0 Code: Unable to access opcode bytes at 0xffffffffffffffd6. RSP: 0018:ffffa3f1c02d7b78 EFLAGS: 00010202 RAX: 0000000000000000 RBX: ffff91f847aefd00 RCX: 000000000000009b RDX: 0000000000000003 RSI: 0000000000000001 RDI: ffff91f840f6fc00 RBP: ffff91f840f6fc00 R08: 0000000000000000 R09: 0000000000000001 R10: 0000000000000000 R11: 000000000000005f R12: 0000000000000000 R13: 0000000000000000 R14: ffffffffc0102498 R15: ffff91f847ce6ba8 FS: 00007f72f4e8f500(0000) GS:ffff91f8d5c80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffffffffd6 CR3: 000000010540e000 CR4: 00000000000406f0 Call Trace: ? __die_body+0x15/0x57 ? page_fault_oops+0x2ef/0x33c ? insert_vmap_area.constprop.0+0xb6/0xd5 ? alloc_vmap_area+0x529/0x5ee ? exc_page_fault+0x15a/0x489 ? asm_exc_page_fault+0x22/0x30 __subdev_8255_init+0x79/0x8d [comedi_8255] pci_8255_auto_attach+0x11a/0x139 [8255_pci] comedi_auto_config+0xac/0x117 [comedi] ? __pfx___driver_attach+0x10/0x10 pci_device_probe+0x88/0xf9 really_probe+0x101/0x248 __driver_probe_device+0xbb/0xed driver_probe_device+0x1a/0x72 __driver_attach+0xd4/0xed bus_for_each_dev+0x76/0xb8 bus_add_driver+0xbe/0x1be driver_register+0x9a/0xd8 comedi_pci_driver_register+0x28/0x48 [comedi_pci] ? __pfx_pci_8255_driver_init+0x10/0x10 [8255_pci] do_one_initcall+0x72/0x183 do_init_module+0x5b/0x1e8 init_module_from_file+0x86/0xac __do_sys_finit_module+0x151/0x218 do_syscall_64+0x72/0xdb entry_SYSCALL_64_after_hwframe+0x6e/0x76 RIP: 0033:0x7f72f50a0cb9 Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 47 71 0c 00 f7 d8 64 89 01 48 RSP: 002b:00007ffd47e512d8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 RAX: ffffffffffffffda RBX: 0000562dd06ae070 RCX: 00007f72f50a0cb9 RDX: 0000000000000000 RSI: 00007f72f52d32df RDI: 000000000000000e RBP: 0000000000000000 R08: 00007f72f5168b20 R09: 0000000000000000 R10: 0000000000000050 R11: 0000000000000246 R12: 00007f72f52d32df R13: 0000000000020000 R14: 0000562dd06785c0 R15: 0000562dcfd0e9a8 Modules linked in: 8255_pci(+) comedi_8255 comedi_pci comedi intel_gtt e100(+) acpi_cpufreq rtc_cmos usbhid CR2: 0000000000000000 ---[ end trace 0000000000000000 ]--- RIP: 0010:0x0 Code: Unable to access opcode bytes at 0xffffffffffffffd6. RSP: 0018:ffffa3f1c02d7b78 EFLAGS: 00010202 RAX: 0000000000000000 RBX: ffff91f847aefd00 RCX: 000000000000009b RDX: 0000000000000003 RSI: 0000000000000001 RDI: ffff91f840f6fc00 RBP: ffff91f840f6fc00 R08: 0000000000000000 R09: 0000000000000001 R10: 0000000000000000 R11: 000000000000005f R12: 0000000000000000 R13: 0000000000000000 R14: ffffffffc0102498 R15: ffff91f847ce6ba8 FS: 00007f72f4e8f500(0000) GS:ffff91f8d5c80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffffffffd6 CR3: 000000010540e000 CR4: 00000000000406f0 This patch simply corrects the above mistake by initializing spriv->io to the given io callback. Fixes: 5c57b1ccecc7 ("comedi: comedi_8255: Rework subdevice initialization functions") Signed-off-by: Frej Drejhammar Cc: stable@vger.kernel.org Acked-by: Ian Abbott Reviewed-by: Ian Abbott Link: https://lore.kernel.org/r/20240211175822.1357-1-frej.drejhammar@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/comedi/drivers/comedi_8255.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/comedi/drivers/comedi_8255.c b/drivers/comedi/drivers/comedi_8255.c index e4974b508328..a933ef53845a 100644 --- a/drivers/comedi/drivers/comedi_8255.c +++ b/drivers/comedi/drivers/comedi_8255.c @@ -159,6 +159,7 @@ static int __subdev_8255_init(struct comedi_device *dev, return -ENOMEM; spriv->context = context; + spriv->io = io; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; -- cgit v1.2.3 From f53641a6e849034a44bf80f50245a75d7a376025 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 14 Feb 2024 10:07:25 +0000 Subject: comedi: comedi_test: Prevent timers rescheduling during deletion The comedi_test devices have a couple of timers (ai_timer and ao_timer) that can be started to simulate hardware interrupts. Their expiry functions normally reschedule the timer. The driver code calls either del_timer_sync() or del_timer() to delete the timers from the queue, but does not currently prevent the timers from rescheduling themselves so synchronized deletion may be ineffective. Add a couple of boolean members (one for each timer: ai_timer_enable and ao_timer_enable) to the device private data structure to indicate whether the timers are allowed to reschedule themselves. Set the member to true when adding the timer to the queue, and to false when deleting the timer from the queue in the waveform_ai_cancel() and waveform_ao_cancel() functions. The del_timer_sync() function is also called from the waveform_detach() function, but the timer enable members will already be set to false when that function is called, so no change is needed there. Fixes: 403fe7f34e33 ("staging: comedi: comedi_test: fix timer race conditions") Cc: stable@vger.kernel.org # 4.4+ Signed-off-by: Ian Abbott Link: https://lore.kernel.org/r/20240214100747.16203-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman --- drivers/comedi/drivers/comedi_test.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/comedi/drivers/comedi_test.c b/drivers/comedi/drivers/comedi_test.c index 30ea8b53ebf8..05ae9122823f 100644 --- a/drivers/comedi/drivers/comedi_test.c +++ b/drivers/comedi/drivers/comedi_test.c @@ -87,6 +87,8 @@ struct waveform_private { struct comedi_device *dev; /* parent comedi device */ u64 ao_last_scan_time; /* time of previous AO scan in usec */ unsigned int ao_scan_period; /* AO scan period in usec */ + bool ai_timer_enable:1; /* should AI timer be running? */ + bool ao_timer_enable:1; /* should AO timer be running? */ unsigned short ao_loopbacks[N_CHANS]; }; @@ -236,8 +238,12 @@ static void waveform_ai_timer(struct timer_list *t) time_increment = devpriv->ai_convert_time - now; else time_increment = 1; - mod_timer(&devpriv->ai_timer, - jiffies + usecs_to_jiffies(time_increment)); + spin_lock(&dev->spinlock); + if (devpriv->ai_timer_enable) { + mod_timer(&devpriv->ai_timer, + jiffies + usecs_to_jiffies(time_increment)); + } + spin_unlock(&dev->spinlock); } overrun: @@ -393,9 +399,12 @@ static int waveform_ai_cmd(struct comedi_device *dev, * Seem to need an extra jiffy here, otherwise timer expires slightly * early! */ + spin_lock_bh(&dev->spinlock); + devpriv->ai_timer_enable = true; devpriv->ai_timer.expires = jiffies + usecs_to_jiffies(devpriv->ai_convert_period) + 1; add_timer(&devpriv->ai_timer); + spin_unlock_bh(&dev->spinlock); return 0; } @@ -404,6 +413,9 @@ static int waveform_ai_cancel(struct comedi_device *dev, { struct waveform_private *devpriv = dev->private; + spin_lock_bh(&dev->spinlock); + devpriv->ai_timer_enable = false; + spin_unlock_bh(&dev->spinlock); if (in_softirq()) { /* Assume we were called from the timer routine itself. */ del_timer(&devpriv->ai_timer); @@ -495,8 +507,12 @@ static void waveform_ao_timer(struct timer_list *t) unsigned int time_inc = devpriv->ao_last_scan_time + devpriv->ao_scan_period - now; - mod_timer(&devpriv->ao_timer, - jiffies + usecs_to_jiffies(time_inc)); + spin_lock(&dev->spinlock); + if (devpriv->ao_timer_enable) { + mod_timer(&devpriv->ao_timer, + jiffies + usecs_to_jiffies(time_inc)); + } + spin_unlock(&dev->spinlock); } underrun: @@ -517,9 +533,12 @@ static int waveform_ao_inttrig_start(struct comedi_device *dev, async->inttrig = NULL; devpriv->ao_last_scan_time = ktime_to_us(ktime_get()); + spin_lock_bh(&dev->spinlock); + devpriv->ao_timer_enable = true; devpriv->ao_timer.expires = jiffies + usecs_to_jiffies(devpriv->ao_scan_period); add_timer(&devpriv->ao_timer); + spin_unlock_bh(&dev->spinlock); return 1; } @@ -604,6 +623,9 @@ static int waveform_ao_cancel(struct comedi_device *dev, struct waveform_private *devpriv = dev->private; s->async->inttrig = NULL; + spin_lock_bh(&dev->spinlock); + devpriv->ao_timer_enable = false; + spin_unlock_bh(&dev->spinlock); if (in_softirq()) { /* Assume we were called from the timer routine itself. */ del_timer(&devpriv->ao_timer); -- cgit v1.2.3 From a283d7f179ff83976af27bcc71f7474cb4d7c348 Mon Sep 17 00:00:00 2001 From: Ekansh Gupta Date: Sat, 24 Feb 2024 11:42:47 +0000 Subject: misc: fastrpc: Pass proper arguments to scm call For CMA memory allocation, ownership is assigned to DSP to make it accessible by the PD running on the DSP. With current implementation HLOS VM is stored in the channel structure during rpmsg_probe and this VM is passed to qcom_scm call as the source VM. The qcom_scm call will overwrite the passed source VM with the next VM which would cause a problem in case the scm call is again needed. Adding a local copy of source VM whereever scm call is made to avoid this problem. Fixes: 0871561055e6 ("misc: fastrpc: Add support for audiopd") Cc: stable Signed-off-by: Ekansh Gupta Reviewed-by: Elliot Berman Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20240224114247.85953-2-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/fastrpc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 03319a1fa97f..dbd26c3b245b 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -263,7 +263,6 @@ struct fastrpc_channel_ctx { int domain_id; int sesscount; int vmcount; - u64 perms; struct qcom_scm_vmperm vmperms[FASTRPC_MAX_VMIDS]; struct rpmsg_device *rpdev; struct fastrpc_session_ctx session[FASTRPC_MAX_SESSIONS]; @@ -1279,9 +1278,11 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, /* Map if we have any heap VMIDs associated with this ADSP Static Process. */ if (fl->cctx->vmcount) { + u64 src_perms = BIT(QCOM_SCM_VMID_HLOS); + err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys, (u64)fl->cctx->remote_heap->size, - &fl->cctx->perms, + &src_perms, fl->cctx->vmperms, fl->cctx->vmcount); if (err) { dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d", @@ -1915,8 +1916,10 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) /* Add memory to static PD pool, protection thru hypervisor */ if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) { + u64 src_perms = BIT(QCOM_SCM_VMID_HLOS); + err = qcom_scm_assign_mem(buf->phys, (u64)buf->size, - &fl->cctx->perms, fl->cctx->vmperms, fl->cctx->vmcount); + &src_perms, fl->cctx->vmperms, fl->cctx->vmcount); if (err) { dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d", buf->phys, buf->size, err); @@ -2290,7 +2293,6 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) if (vmcount) { data->vmcount = vmcount; - data->perms = BIT(QCOM_SCM_VMID_HLOS); for (i = 0; i < data->vmcount; i++) { data->vmperms[i].vmid = vmids[i]; data->vmperms[i].perm = QCOM_SCM_PERM_RWX; -- cgit v1.2.3 From a0776c214d47ea4f7aaef138095beaa41cff03ef Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Tue, 20 Feb 2024 22:00:20 +0200 Subject: mei: gsc_proxy: match component when GSC is on different bus On Arrow Lake S systems, MEI is no longer strictly connected to bus 0, while graphics remain exclusively on bus 0. Adapt the component matching logic to accommodate this change: Original behavior: Required both MEI and graphics to be on the same bus 0. New behavior: Only enforces graphics to be on bus 0 (integrated), allowing MEI to reside on any bus. This ensures compatibility with Arrow Lake S and maintains functionality for the legacy systems. Fixes: 1dd924f6885b ("mei: gsc_proxy: add gsc proxy driver") Cc: stable@vger.kernel.org # v6.3+ Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Link: https://lore.kernel.org/r/20240220200020.231192-1-tomas.winkler@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c b/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c index be52b113aea9..89364bdbb129 100644 --- a/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c +++ b/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c @@ -96,7 +96,8 @@ static const struct component_master_ops mei_component_master_ops = { * * The function checks if the device is pci device and * Intel VGA adapter, the subcomponent is SW Proxy - * and the parent of MEI PCI and the parent of VGA are the same PCH device. + * and the VGA is on the bus 0 reserved for built-in devices + * to reject discrete GFX. * * @dev: master device * @subcomponent: subcomponent to match (I915_COMPONENT_SWPROXY) @@ -123,7 +124,8 @@ static int mei_gsc_proxy_component_match(struct device *dev, int subcomponent, if (subcomponent != I915_COMPONENT_GSC_PROXY) return 0; - return component_compare_dev(dev->parent, ((struct device *)data)->parent); + /* Only built-in GFX */ + return (pdev->bus->number == 0); } static int mei_gsc_proxy_probe(struct mei_cl_device *cldev, @@ -146,7 +148,7 @@ static int mei_gsc_proxy_probe(struct mei_cl_device *cldev, } component_match_add_typed(&cldev->dev, &master_match, - mei_gsc_proxy_component_match, cldev->dev.parent); + mei_gsc_proxy_component_match, NULL); if (IS_ERR_OR_NULL(master_match)) { ret = -ENOMEM; goto err_exit; -- cgit v1.2.3