Char/Misc driver changes for 6.8-rc8 (or -final)

Here are a few small char/misc and other driver subsystem fixes for
 reported issues that have been in my tree for inclusion in 6.8-rc8 or
 -final, which ever is next.
 
 Included in here are fixes for:
   - iio driver fixes for reported problems
   - much reported bugfix for a lis3lv02d_i2c regression
   - comedi driver bugfix
   - mei new device ids
   - mei driver fixes
   - counter core fix
 
 All of these have been in linux-next with no reported issues, some for
 many weeks.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCZetI4A8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ylm6wCfT0KKJhCWFtUrEmvgu3NWjdRVHmMAnj01w5j0
 t2aTmnRJd+TeA/yTTDSz
 =Wsg2
 -----END PGP SIGNATURE-----

Merge tag 'char-misc-6.8-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull char/misc driver fixes from Greg KH:
 "Here are a few small char/misc and other driver subsystem fixes for
  reported issues that have been in my tree.

  Included in here are fixes for:

   - iio driver fixes for reported problems

   - much reported bugfix for a lis3lv02d_i2c regression

   - comedi driver bugfix

   - mei new device ids

   - mei driver fixes

   - counter core fix

  All of these have been in linux-next with no reported issues, some for
  many weeks"

* tag 'char-misc-6.8-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
  mei: gsc_proxy: match component when GSC is on different bus
  misc: fastrpc: Pass proper arguments to scm call
  comedi: comedi_test: Prevent timers rescheduling during deletion
  comedi: comedi_8255: Correct error in subdevice initialization
  misc: lis3lv02d_i2c: Fix regulators getting en-/dis-abled twice on suspend/resume
  iio: accel: adxl367: fix I2C FIFO data register
  iio: accel: adxl367: fix DEVID read after reset
  iio: pressure: dlhl60d: Initialize empty DLH bytes
  iio: imu: inv_mpu6050: fix frequency setting when chip is off
  iio: pressure: Fixes BMP38x and BMP390 SPI support
  iio: imu: inv_mpu6050: fix FIFO parsing when empty
  mei: Add Meteor Lake support for IVSC device
  mei: me: add arrow lake point H DID
  mei: me: add arrow lake point S DID
  counter: fix privdata alignment
This commit is contained in:
Linus Torvalds 2024-03-08 13:39:28 -08:00
commit 10d48d70e8
15 changed files with 126 additions and 30 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -4,6 +4,7 @@
*
* Inspired by the older BMP085 driver drivers/misc/bmp085-spi.c
*/
#include <linux/bits.h>
#include <linux/module.h>
#include <linux/spi/spi.h>
#include <linux/err.h>
@ -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)) {

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -112,6 +112,8 @@
#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 */
#define MEI_DEV_ID_ARL_H 0x7770 /* Arrow Lake Point H */
/*
* MEI HW Section

View File

@ -119,6 +119,8 @@ 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)},
{MEI_PCI_DEVICE(MEI_DEV_ID_ARL_H, MEI_ME_PCH15_CFG)},
/* required last entry */
{0, }

View File

@ -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);