mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
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:
commit
10d48d70e8
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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, }
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user