mirror of https://github.com/torvalds/linux.git
Char/Misc/IIO driver fixes for 6.15-rc6
Here are a bunch of small driver fixes (mostly all IIO) for 6.15-rc6.
Included in here are:
- loads of tiny IIO driver fixes for reported issues
- hyperv driver fix for a much-reported and worked on sysfs ring
buffer creation bug
All of these have been in linux-next for over a week (the IIO ones for
many weeks now), with no reported issues.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-----BEGIN PGP SIGNATURE-----
iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCaB9YVQ8cZ3JlZ0Brcm9h
aC5jb20ACgkQMUfUDdst+ynaIwCfTPZseJ558irNFrethcxPqtAAlc0An3z4Jyij
diV9XrxG+Afasvqviyi/
=sjUN
-----END PGP SIGNATURE-----
Merge tag 'char-misc-6.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc/IIO driver fixes from Greg KH:
"Here are a bunch of small driver fixes (mostly all IIO) for 6.15-rc6.
Included in here are:
- loads of tiny IIO driver fixes for reported issues
- hyperv driver fix for a much-reported and worked on sysfs ring
buffer creation bug
All of these have been in linux-next for over a week (the IIO ones for
many weeks now), with no reported issues"
* tag 'char-misc-6.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (30 commits)
Drivers: hv: Make the sysfs node size for the ring buffer dynamic
uio_hv_generic: Fix sysfs creation path for ring buffer
iio: adis16201: Correct inclinometer channel resolution
iio: adc: ad7606: fix serial register access
iio: pressure: mprls0025pa: use aligned_s64 for timestamp
iio: imu: adis16550: align buffers for timestamp
staging: iio: adc: ad7816: Correct conditional logic for store mode
iio: adc: ad7266: Fix potential timestamp alignment issue.
iio: adc: ad7768-1: Fix insufficient alignment of timestamp.
iio: adc: dln2: Use aligned_s64 for timestamp
iio: accel: adxl355: Make timestamp 64-bit aligned using aligned_s64
iio: temp: maxim-thermocouple: Fix potential lack of DMA safe buffer.
iio: chemical: pms7003: use aligned_s64 for timestamp
iio: chemical: sps30: use aligned_s64 for timestamp
iio: imu: inv_mpu6050: align buffer for timestamp
iio: imu: st_lsm6dsx: Fix wakeup source leaks on device unbind
iio: adc: qcom-spmi-iadc: Fix wakeup source leaks on device unbind
iio: accel: fxls8962af: Fix wakeup source leaks on device unbind
iio: adc: ad7380: fix event threshold shift
iio: hid-sensor-prox: Fix incorrect OFFSET calculation
...
This commit is contained in:
commit
914a1fe5f8
|
|
@ -477,4 +477,10 @@ static inline int hv_debug_add_dev_dir(struct hv_device *dev)
|
|||
|
||||
#endif /* CONFIG_HYPERV_TESTING */
|
||||
|
||||
/* Create and remove sysfs entry for memory mapped ring buffers for a channel */
|
||||
int hv_create_ring_sysfs(struct vmbus_channel *channel,
|
||||
int (*hv_mmap_ring_buffer)(struct vmbus_channel *channel,
|
||||
struct vm_area_struct *vma));
|
||||
int hv_remove_ring_sysfs(struct vmbus_channel *channel);
|
||||
|
||||
#endif /* _HYPERV_VMBUS_H */
|
||||
|
|
|
|||
|
|
@ -1802,6 +1802,26 @@ static ssize_t subchannel_id_show(struct vmbus_channel *channel,
|
|||
}
|
||||
static VMBUS_CHAN_ATTR_RO(subchannel_id);
|
||||
|
||||
static int hv_mmap_ring_buffer_wrapper(struct file *filp, struct kobject *kobj,
|
||||
const struct bin_attribute *attr,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
struct vmbus_channel *channel = container_of(kobj, struct vmbus_channel, kobj);
|
||||
|
||||
/*
|
||||
* hv_(create|remove)_ring_sysfs implementation ensures that mmap_ring_buffer
|
||||
* is not NULL.
|
||||
*/
|
||||
return channel->mmap_ring_buffer(channel, vma);
|
||||
}
|
||||
|
||||
static struct bin_attribute chan_attr_ring_buffer = {
|
||||
.attr = {
|
||||
.name = "ring",
|
||||
.mode = 0600,
|
||||
},
|
||||
.mmap = hv_mmap_ring_buffer_wrapper,
|
||||
};
|
||||
static struct attribute *vmbus_chan_attrs[] = {
|
||||
&chan_attr_out_mask.attr,
|
||||
&chan_attr_in_mask.attr,
|
||||
|
|
@ -1821,6 +1841,11 @@ static struct attribute *vmbus_chan_attrs[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
static struct bin_attribute *vmbus_chan_bin_attrs[] = {
|
||||
&chan_attr_ring_buffer,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Channel-level attribute_group callback function. Returns the permission for
|
||||
* each attribute, and returns 0 if an attribute is not visible.
|
||||
|
|
@ -1841,9 +1866,34 @@ static umode_t vmbus_chan_attr_is_visible(struct kobject *kobj,
|
|||
return attr->mode;
|
||||
}
|
||||
|
||||
static umode_t vmbus_chan_bin_attr_is_visible(struct kobject *kobj,
|
||||
const struct bin_attribute *attr, int idx)
|
||||
{
|
||||
const struct vmbus_channel *channel =
|
||||
container_of(kobj, struct vmbus_channel, kobj);
|
||||
|
||||
/* Hide ring attribute if channel's ring_sysfs_visible is set to false */
|
||||
if (attr == &chan_attr_ring_buffer && !channel->ring_sysfs_visible)
|
||||
return 0;
|
||||
|
||||
return attr->attr.mode;
|
||||
}
|
||||
|
||||
static size_t vmbus_chan_bin_size(struct kobject *kobj,
|
||||
const struct bin_attribute *bin_attr, int a)
|
||||
{
|
||||
const struct vmbus_channel *channel =
|
||||
container_of(kobj, struct vmbus_channel, kobj);
|
||||
|
||||
return channel->ringbuffer_pagecount << PAGE_SHIFT;
|
||||
}
|
||||
|
||||
static const struct attribute_group vmbus_chan_group = {
|
||||
.attrs = vmbus_chan_attrs,
|
||||
.is_visible = vmbus_chan_attr_is_visible
|
||||
.bin_attrs = vmbus_chan_bin_attrs,
|
||||
.is_visible = vmbus_chan_attr_is_visible,
|
||||
.is_bin_visible = vmbus_chan_bin_attr_is_visible,
|
||||
.bin_size = vmbus_chan_bin_size,
|
||||
};
|
||||
|
||||
static const struct kobj_type vmbus_chan_ktype = {
|
||||
|
|
@ -1851,6 +1901,63 @@ static const struct kobj_type vmbus_chan_ktype = {
|
|||
.release = vmbus_chan_release,
|
||||
};
|
||||
|
||||
/**
|
||||
* hv_create_ring_sysfs() - create "ring" sysfs entry corresponding to ring buffers for a channel.
|
||||
* @channel: Pointer to vmbus_channel structure
|
||||
* @hv_mmap_ring_buffer: function pointer for initializing the function to be called on mmap of
|
||||
* channel's "ring" sysfs node, which is for the ring buffer of that channel.
|
||||
* Function pointer is of below type:
|
||||
* int (*hv_mmap_ring_buffer)(struct vmbus_channel *channel,
|
||||
* struct vm_area_struct *vma))
|
||||
* This has a pointer to the channel and a pointer to vm_area_struct,
|
||||
* used for mmap, as arguments.
|
||||
*
|
||||
* Sysfs node for ring buffer of a channel is created along with other fields, however its
|
||||
* visibility is disabled by default. Sysfs creation needs to be controlled when the use-case
|
||||
* is running.
|
||||
* For example, HV_NIC device is used either by uio_hv_generic or hv_netvsc at any given point of
|
||||
* time, and "ring" sysfs is needed only when uio_hv_generic is bound to that device. To avoid
|
||||
* exposing the ring buffer by default, this function is reponsible to enable visibility of
|
||||
* ring for userspace to use.
|
||||
* Note: Race conditions can happen with userspace and it is not encouraged to create new
|
||||
* use-cases for this. This was added to maintain backward compatibility, while solving
|
||||
* one of the race conditions in uio_hv_generic while creating sysfs.
|
||||
*
|
||||
* Returns 0 on success or error code on failure.
|
||||
*/
|
||||
int hv_create_ring_sysfs(struct vmbus_channel *channel,
|
||||
int (*hv_mmap_ring_buffer)(struct vmbus_channel *channel,
|
||||
struct vm_area_struct *vma))
|
||||
{
|
||||
struct kobject *kobj = &channel->kobj;
|
||||
|
||||
channel->mmap_ring_buffer = hv_mmap_ring_buffer;
|
||||
channel->ring_sysfs_visible = true;
|
||||
|
||||
return sysfs_update_group(kobj, &vmbus_chan_group);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hv_create_ring_sysfs);
|
||||
|
||||
/**
|
||||
* hv_remove_ring_sysfs() - remove ring sysfs entry corresponding to ring buffers for a channel.
|
||||
* @channel: Pointer to vmbus_channel structure
|
||||
*
|
||||
* Hide "ring" sysfs for a channel by changing its is_visible attribute and updating sysfs group.
|
||||
*
|
||||
* Returns 0 on success or error code on failure.
|
||||
*/
|
||||
int hv_remove_ring_sysfs(struct vmbus_channel *channel)
|
||||
{
|
||||
struct kobject *kobj = &channel->kobj;
|
||||
int ret;
|
||||
|
||||
channel->ring_sysfs_visible = false;
|
||||
ret = sysfs_update_group(kobj, &vmbus_chan_group);
|
||||
channel->mmap_ring_buffer = NULL;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hv_remove_ring_sysfs);
|
||||
|
||||
/*
|
||||
* vmbus_add_channel_kobj - setup a sub-directory under device/channels
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -211,9 +211,9 @@ static const struct iio_chan_spec adis16201_channels[] = {
|
|||
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
|
||||
ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC_REG, ADIS16201_SCAN_AUX_ADC, 0, 12),
|
||||
ADIS_INCLI_CHAN(X, ADIS16201_XINCL_OUT_REG, ADIS16201_SCAN_INCLI_X,
|
||||
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
|
||||
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 12),
|
||||
ADIS_INCLI_CHAN(Y, ADIS16201_YINCL_OUT_REG, ADIS16201_SCAN_INCLI_Y,
|
||||
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
|
||||
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 12),
|
||||
IIO_CHAN_SOFT_TIMESTAMP(7)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ struct adxl355_data {
|
|||
u8 transf_buf[3];
|
||||
struct {
|
||||
u8 buf[14];
|
||||
s64 ts;
|
||||
aligned_s64 ts;
|
||||
} buffer;
|
||||
} __aligned(IIO_DMA_MINALIGN);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -601,18 +601,14 @@ static int _adxl367_set_odr(struct adxl367_state *st, enum adxl367_odr odr)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
st->odr = odr;
|
||||
|
||||
/* Activity timers depend on ODR */
|
||||
ret = _adxl367_set_act_time_ms(st, st->act_time_ms);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = _adxl367_set_inact_time_ms(st, st->inact_time_ms);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
st->odr = odr;
|
||||
|
||||
return 0;
|
||||
return _adxl367_set_inact_time_ms(st, st->inact_time_ms);
|
||||
}
|
||||
|
||||
static int adxl367_set_odr(struct iio_dev *indio_dev, enum adxl367_odr odr)
|
||||
|
|
|
|||
|
|
@ -1226,8 +1226,11 @@ int fxls8962af_core_probe(struct device *dev, struct regmap *regmap, int irq)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (device_property_read_bool(dev, "wakeup-source"))
|
||||
device_init_wakeup(dev, true);
|
||||
if (device_property_read_bool(dev, "wakeup-source")) {
|
||||
ret = devm_device_init_wakeup(dev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to init wakeup\n");
|
||||
}
|
||||
|
||||
return devm_iio_device_register(dev, indio_dev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ struct ad7266_state {
|
|||
*/
|
||||
struct {
|
||||
__be16 sample[2];
|
||||
s64 timestamp;
|
||||
aligned_s64 timestamp;
|
||||
} data __aligned(IIO_DMA_MINALIGN);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1211,6 +1211,9 @@ static int ad7380_offload_buffer_predisable(struct iio_dev *indio_dev)
|
|||
struct ad7380_state *st = iio_priv(indio_dev);
|
||||
int ret;
|
||||
|
||||
spi_offload_trigger_disable(st->offload, st->offload_trigger);
|
||||
spi_unoptimize_message(&st->offload_msg);
|
||||
|
||||
if (st->seq) {
|
||||
ret = regmap_update_bits(st->regmap,
|
||||
AD7380_REG_ADDR_CONFIG1,
|
||||
|
|
@ -1222,10 +1225,6 @@ static int ad7380_offload_buffer_predisable(struct iio_dev *indio_dev)
|
|||
st->seq = false;
|
||||
}
|
||||
|
||||
spi_offload_trigger_disable(st->offload, st->offload_trigger);
|
||||
|
||||
spi_unoptimize_message(&st->offload_msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1611,11 +1610,25 @@ static int ad7380_write_event_config(struct iio_dev *indio_dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ad7380_get_alert_th(struct ad7380_state *st,
|
||||
static int ad7380_get_alert_th(struct iio_dev *indio_dev,
|
||||
const struct iio_chan_spec *chan,
|
||||
enum iio_event_direction dir,
|
||||
int *val)
|
||||
{
|
||||
int ret, tmp;
|
||||
struct ad7380_state *st = iio_priv(indio_dev);
|
||||
const struct iio_scan_type *scan_type;
|
||||
int ret, tmp, shift;
|
||||
|
||||
scan_type = iio_get_current_scan_type(indio_dev, chan);
|
||||
if (IS_ERR(scan_type))
|
||||
return PTR_ERR(scan_type);
|
||||
|
||||
/*
|
||||
* The register value is 12-bits and is compared to the most significant
|
||||
* bits of raw value, therefore a shift is required to convert this to
|
||||
* the same scale as the raw value.
|
||||
*/
|
||||
shift = scan_type->realbits - 12;
|
||||
|
||||
switch (dir) {
|
||||
case IIO_EV_DIR_RISING:
|
||||
|
|
@ -1625,7 +1638,7 @@ static int ad7380_get_alert_th(struct ad7380_state *st,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
*val = FIELD_GET(AD7380_ALERT_HIGH_TH, tmp);
|
||||
*val = FIELD_GET(AD7380_ALERT_HIGH_TH, tmp) << shift;
|
||||
return IIO_VAL_INT;
|
||||
case IIO_EV_DIR_FALLING:
|
||||
ret = regmap_read(st->regmap,
|
||||
|
|
@ -1634,7 +1647,7 @@ static int ad7380_get_alert_th(struct ad7380_state *st,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
*val = FIELD_GET(AD7380_ALERT_LOW_TH, tmp);
|
||||
*val = FIELD_GET(AD7380_ALERT_LOW_TH, tmp) << shift;
|
||||
return IIO_VAL_INT;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
|
@ -1648,7 +1661,6 @@ static int ad7380_read_event_value(struct iio_dev *indio_dev,
|
|||
enum iio_event_info info,
|
||||
int *val, int *val2)
|
||||
{
|
||||
struct ad7380_state *st = iio_priv(indio_dev);
|
||||
int ret;
|
||||
|
||||
switch (info) {
|
||||
|
|
@ -1656,7 +1668,7 @@ static int ad7380_read_event_value(struct iio_dev *indio_dev,
|
|||
if (!iio_device_claim_direct(indio_dev))
|
||||
return -EBUSY;
|
||||
|
||||
ret = ad7380_get_alert_th(st, dir, val);
|
||||
ret = ad7380_get_alert_th(indio_dev, chan, dir, val);
|
||||
|
||||
iio_device_release_direct(indio_dev);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -1236,9 +1236,11 @@ static int ad7616_sw_mode_setup(struct iio_dev *indio_dev)
|
|||
st->write_scale = ad7616_write_scale_sw;
|
||||
st->write_os = &ad7616_write_os_sw;
|
||||
|
||||
ret = st->bops->sw_mode_config(indio_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (st->bops->sw_mode_config) {
|
||||
ret = st->bops->sw_mode_config(indio_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Activate Burst mode and SEQEN MODE */
|
||||
return ad7606_write_mask(st, AD7616_CONFIGURATION_REGISTER,
|
||||
|
|
@ -1268,6 +1270,9 @@ static int ad7606b_sw_mode_setup(struct iio_dev *indio_dev)
|
|||
st->write_scale = ad7606_write_scale_sw;
|
||||
st->write_os = &ad7606_write_os_sw;
|
||||
|
||||
if (!st->bops->sw_mode_config)
|
||||
return 0;
|
||||
|
||||
return st->bops->sw_mode_config(indio_dev);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ static int ad7606_spi_reg_read(struct ad7606_state *st, unsigned int addr)
|
|||
{
|
||||
.tx_buf = &st->d16[0],
|
||||
.len = 2,
|
||||
.cs_change = 0,
|
||||
.cs_change = 1,
|
||||
}, {
|
||||
.rx_buf = &st->d16[1],
|
||||
.len = 2,
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ struct ad7768_state {
|
|||
union {
|
||||
struct {
|
||||
__be32 chan;
|
||||
s64 timestamp;
|
||||
aligned_s64 timestamp;
|
||||
} scan;
|
||||
__be32 d32;
|
||||
u8 d8[2];
|
||||
|
|
|
|||
|
|
@ -466,7 +466,7 @@ static irqreturn_t dln2_adc_trigger_h(int irq, void *p)
|
|||
struct iio_dev *indio_dev = pf->indio_dev;
|
||||
struct {
|
||||
__le16 values[DLN2_ADC_MAX_CHANNELS];
|
||||
int64_t timestamp_space;
|
||||
aligned_s64 timestamp_space;
|
||||
} data;
|
||||
struct dln2_adc_get_all_vals dev_data;
|
||||
struct dln2_adc *dln2 = iio_priv(indio_dev);
|
||||
|
|
|
|||
|
|
@ -543,7 +543,9 @@ static int iadc_probe(struct platform_device *pdev)
|
|||
else
|
||||
return ret;
|
||||
} else {
|
||||
device_init_wakeup(iadc->dev, 1);
|
||||
ret = devm_device_init_wakeup(iadc->dev);
|
||||
if (ret)
|
||||
return dev_err_probe(iadc->dev, ret, "Failed to init wakeup\n");
|
||||
}
|
||||
|
||||
ret = iadc_update_offset(iadc);
|
||||
|
|
|
|||
|
|
@ -520,15 +520,6 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
|
|||
if (info->reset)
|
||||
rockchip_saradc_reset_controller(info->reset);
|
||||
|
||||
/*
|
||||
* Use a default value for the converter clock.
|
||||
* This may become user-configurable in the future.
|
||||
*/
|
||||
ret = clk_set_rate(info->clk, info->data->clk_rate);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(&pdev->dev, ret,
|
||||
"failed to set adc clk rate\n");
|
||||
|
||||
ret = regulator_enable(info->vref);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(&pdev->dev, ret,
|
||||
|
|
@ -555,6 +546,14 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(info->clk))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(info->clk),
|
||||
"failed to get adc clock\n");
|
||||
/*
|
||||
* Use a default value for the converter clock.
|
||||
* This may become user-configurable in the future.
|
||||
*/
|
||||
ret = clk_set_rate(info->clk, info->data->clk_rate);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(&pdev->dev, ret,
|
||||
"failed to set adc clk rate\n");
|
||||
|
||||
platform_set_drvdata(pdev, indio_dev);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
* Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/unaligned.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/errno.h>
|
||||
|
|
@ -19,6 +18,8 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/serdev.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/unaligned.h>
|
||||
|
||||
#define PMS7003_DRIVER_NAME "pms7003"
|
||||
|
||||
|
|
@ -76,7 +77,7 @@ struct pms7003_state {
|
|||
/* Used to construct scan to push to the IIO buffer */
|
||||
struct {
|
||||
u16 data[3]; /* PM1, PM2P5, PM10 */
|
||||
s64 ts;
|
||||
aligned_s64 ts;
|
||||
} scan;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ static irqreturn_t sps30_trigger_handler(int irq, void *p)
|
|||
int ret;
|
||||
struct {
|
||||
s32 data[4]; /* PM1, PM2P5, PM4, PM10 */
|
||||
s64 ts;
|
||||
aligned_s64 ts;
|
||||
} scan;
|
||||
|
||||
mutex_lock(&state->lock);
|
||||
|
|
|
|||
|
|
@ -66,6 +66,10 @@ static struct {
|
|||
{HID_USAGE_SENSOR_HUMIDITY, 0, 1000, 0},
|
||||
{HID_USAGE_SENSOR_HINGE, 0, 0, 17453293},
|
||||
{HID_USAGE_SENSOR_HINGE, HID_USAGE_SENSOR_UNITS_DEGREES, 0, 17453293},
|
||||
|
||||
{HID_USAGE_SENSOR_HUMAN_PRESENCE, 0, 1, 0},
|
||||
{HID_USAGE_SENSOR_HUMAN_PROXIMITY, 0, 1, 0},
|
||||
{HID_USAGE_SENSOR_HUMAN_ATTENTION, 0, 1, 0},
|
||||
};
|
||||
|
||||
static void simple_div(int dividend, int divisor, int *whole,
|
||||
|
|
|
|||
|
|
@ -836,7 +836,7 @@ static irqreturn_t adis16550_trigger_handler(int irq, void *p)
|
|||
u16 dummy;
|
||||
bool valid;
|
||||
struct iio_poll_func *pf = p;
|
||||
__be32 data[ADIS16550_MAX_SCAN_DATA];
|
||||
__be32 data[ADIS16550_MAX_SCAN_DATA] __aligned(8);
|
||||
struct iio_dev *indio_dev = pf->indio_dev;
|
||||
struct adis16550 *st = iio_priv(indio_dev);
|
||||
struct adis *adis = iio_device_get_drvdata(indio_dev);
|
||||
|
|
|
|||
|
|
@ -918,8 +918,7 @@ static int bmi270_configure_imu(struct bmi270_data *data)
|
|||
FIELD_PREP(BMI270_ACC_CONF_ODR_MSK,
|
||||
BMI270_ACC_CONF_ODR_100HZ) |
|
||||
FIELD_PREP(BMI270_ACC_CONF_BWP_MSK,
|
||||
BMI270_ACC_CONF_BWP_NORMAL_MODE) |
|
||||
BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
|
||||
BMI270_ACC_CONF_BWP_NORMAL_MODE));
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to configure accelerometer");
|
||||
|
||||
|
|
@ -927,8 +926,7 @@ static int bmi270_configure_imu(struct bmi270_data *data)
|
|||
FIELD_PREP(BMI270_GYR_CONF_ODR_MSK,
|
||||
BMI270_GYR_CONF_ODR_200HZ) |
|
||||
FIELD_PREP(BMI270_GYR_CONF_BWP_MSK,
|
||||
BMI270_GYR_CONF_BWP_NORMAL_MODE) |
|
||||
BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
|
||||
BMI270_GYR_CONF_BWP_NORMAL_MODE));
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to configure gyroscope");
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
|
|||
u16 fifo_count;
|
||||
u32 fifo_period;
|
||||
s64 timestamp;
|
||||
u8 data[INV_MPU6050_OUTPUT_DATA_SIZE];
|
||||
u8 data[INV_MPU6050_OUTPUT_DATA_SIZE] __aligned(8);
|
||||
size_t i, nb;
|
||||
|
||||
mutex_lock(&st->lock);
|
||||
|
|
|
|||
|
|
@ -392,6 +392,9 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
|
|||
if (fifo_status & cpu_to_le16(ST_LSM6DSX_FIFO_EMPTY_MASK))
|
||||
return 0;
|
||||
|
||||
if (!pattern_len)
|
||||
pattern_len = ST_LSM6DSX_SAMPLE_SIZE;
|
||||
|
||||
fifo_len = (le16_to_cpu(fifo_status) & fifo_diff_mask) *
|
||||
ST_LSM6DSX_CHAN_SIZE;
|
||||
fifo_len = (fifo_len / pattern_len) * pattern_len;
|
||||
|
|
@ -623,6 +626,9 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
|
|||
if (!fifo_len)
|
||||
return 0;
|
||||
|
||||
if (!pattern_len)
|
||||
pattern_len = ST_LSM6DSX_TAGGED_SAMPLE_SIZE;
|
||||
|
||||
for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
|
||||
err = st_lsm6dsx_read_block(hw,
|
||||
ST_LSM6DSX_REG_FIFO_OUT_TAG_ADDR,
|
||||
|
|
|
|||
|
|
@ -2719,8 +2719,11 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
|
|||
}
|
||||
|
||||
if (device_property_read_bool(dev, "wakeup-source") ||
|
||||
(pdata && pdata->wakeup_source))
|
||||
device_init_wakeup(dev, true);
|
||||
(pdata && pdata->wakeup_source)) {
|
||||
err = devm_device_init_wakeup(dev);
|
||||
if (err)
|
||||
return dev_err_probe(dev, err, "Failed to init wakeup\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@ struct prox_state {
|
|||
struct iio_chan_spec channels[MAX_CHANNELS];
|
||||
u32 channel2usage[MAX_CHANNELS];
|
||||
u32 human_presence[MAX_CHANNELS];
|
||||
int scale_pre_decml;
|
||||
int scale_post_decml;
|
||||
int scale_precision;
|
||||
int scale_pre_decml[MAX_CHANNELS];
|
||||
int scale_post_decml[MAX_CHANNELS];
|
||||
int scale_precision[MAX_CHANNELS];
|
||||
unsigned long scan_mask[2]; /* One entry plus one terminator. */
|
||||
int num_channels;
|
||||
};
|
||||
|
|
@ -116,13 +116,15 @@ static int prox_read_raw(struct iio_dev *indio_dev,
|
|||
ret_type = IIO_VAL_INT;
|
||||
break;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*val = prox_state->scale_pre_decml;
|
||||
*val2 = prox_state->scale_post_decml;
|
||||
ret_type = prox_state->scale_precision;
|
||||
if (chan->scan_index >= prox_state->num_channels)
|
||||
return -EINVAL;
|
||||
|
||||
*val = prox_state->scale_pre_decml[chan->scan_index];
|
||||
*val2 = prox_state->scale_post_decml[chan->scan_index];
|
||||
ret_type = prox_state->scale_precision[chan->scan_index];
|
||||
break;
|
||||
case IIO_CHAN_INFO_OFFSET:
|
||||
*val = hid_sensor_convert_exponent(
|
||||
prox_state->prox_attr[chan->scan_index].unit_expo);
|
||||
*val = 0;
|
||||
ret_type = IIO_VAL_INT;
|
||||
break;
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
|
|
@ -249,6 +251,10 @@ static int prox_parse_report(struct platform_device *pdev,
|
|||
st->prox_attr[index].size);
|
||||
dev_dbg(&pdev->dev, "prox %x:%x\n", st->prox_attr[index].index,
|
||||
st->prox_attr[index].report_id);
|
||||
st->scale_precision[index] =
|
||||
hid_sensor_format_scale(usage_id, &st->prox_attr[index],
|
||||
&st->scale_pre_decml[index],
|
||||
&st->scale_post_decml[index]);
|
||||
index++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -788,8 +788,9 @@ static irqreturn_t opt3001_irq(int irq, void *_iio)
|
|||
int ret;
|
||||
bool wake_result_ready_queue = false;
|
||||
enum iio_chan_type chan_type = opt->chip_info->chan_type;
|
||||
bool ok_to_ignore_lock = opt->ok_to_ignore_lock;
|
||||
|
||||
if (!opt->ok_to_ignore_lock)
|
||||
if (!ok_to_ignore_lock)
|
||||
mutex_lock(&opt->lock);
|
||||
|
||||
ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_CONFIGURATION);
|
||||
|
|
@ -826,7 +827,7 @@ static irqreturn_t opt3001_irq(int irq, void *_iio)
|
|||
}
|
||||
|
||||
out:
|
||||
if (!opt->ok_to_ignore_lock)
|
||||
if (!ok_to_ignore_lock)
|
||||
mutex_unlock(&opt->lock);
|
||||
|
||||
if (wake_result_ready_queue)
|
||||
|
|
|
|||
|
|
@ -34,16 +34,6 @@ struct iio_dev;
|
|||
struct mpr_data;
|
||||
struct mpr_ops;
|
||||
|
||||
/**
|
||||
* struct mpr_chan
|
||||
* @pres: pressure value
|
||||
* @ts: timestamp
|
||||
*/
|
||||
struct mpr_chan {
|
||||
s32 pres;
|
||||
s64 ts;
|
||||
};
|
||||
|
||||
enum mpr_func_id {
|
||||
MPR_FUNCTION_A,
|
||||
MPR_FUNCTION_B,
|
||||
|
|
@ -69,6 +59,8 @@ enum mpr_func_id {
|
|||
* reading in a loop until data is ready
|
||||
* @completion: handshake from irq to read
|
||||
* @chan: channel values for buffered mode
|
||||
* @chan.pres: pressure value
|
||||
* @chan.ts: timestamp
|
||||
* @buffer: raw conversion data
|
||||
*/
|
||||
struct mpr_data {
|
||||
|
|
@ -87,7 +79,10 @@ struct mpr_data {
|
|||
struct gpio_desc *gpiod_reset;
|
||||
int irq;
|
||||
struct completion completion;
|
||||
struct mpr_chan chan;
|
||||
struct {
|
||||
s32 pres;
|
||||
aligned_s64 ts;
|
||||
} chan;
|
||||
u8 buffer[MPR_MEASUREMENT_RD_SIZE] __aligned(IIO_DMA_MINALIGN);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -121,9 +121,9 @@ static const struct maxim_thermocouple_chip maxim_thermocouple_chips[] = {
|
|||
struct maxim_thermocouple_data {
|
||||
struct spi_device *spi;
|
||||
const struct maxim_thermocouple_chip *chip;
|
||||
char tc_type;
|
||||
|
||||
u8 buffer[16] __aligned(IIO_DMA_MINALIGN);
|
||||
char tc_type;
|
||||
};
|
||||
|
||||
static int maxim_thermocouple_read(struct maxim_thermocouple_data *data,
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ static ssize_t ad7816_store_mode(struct device *dev,
|
|||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||
struct ad7816_chip_info *chip = iio_priv(indio_dev);
|
||||
|
||||
if (strcmp(buf, "full")) {
|
||||
if (strcmp(buf, "full") == 0) {
|
||||
gpiod_set_value(chip->rdwr_pin, 1);
|
||||
chip->mode = AD7816_FULL;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -131,15 +131,12 @@ static void hv_uio_rescind(struct vmbus_channel *channel)
|
|||
vmbus_device_unregister(channel->device_obj);
|
||||
}
|
||||
|
||||
/* Sysfs API to allow mmap of the ring buffers
|
||||
/* Function used for mmap of ring buffer sysfs interface.
|
||||
* The ring buffer is allocated as contiguous memory by vmbus_open
|
||||
*/
|
||||
static int hv_uio_ring_mmap(struct file *filp, struct kobject *kobj,
|
||||
const struct bin_attribute *attr,
|
||||
struct vm_area_struct *vma)
|
||||
static int
|
||||
hv_uio_ring_mmap(struct vmbus_channel *channel, struct vm_area_struct *vma)
|
||||
{
|
||||
struct vmbus_channel *channel
|
||||
= container_of(kobj, struct vmbus_channel, kobj);
|
||||
void *ring_buffer = page_address(channel->ringbuffer_page);
|
||||
|
||||
if (channel->state != CHANNEL_OPENED_STATE)
|
||||
|
|
@ -149,15 +146,6 @@ static int hv_uio_ring_mmap(struct file *filp, struct kobject *kobj,
|
|||
channel->ringbuffer_pagecount << PAGE_SHIFT);
|
||||
}
|
||||
|
||||
static const struct bin_attribute ring_buffer_bin_attr = {
|
||||
.attr = {
|
||||
.name = "ring",
|
||||
.mode = 0600,
|
||||
},
|
||||
.size = 2 * SZ_2M,
|
||||
.mmap = hv_uio_ring_mmap,
|
||||
};
|
||||
|
||||
/* Callback from VMBUS subsystem when new channel created. */
|
||||
static void
|
||||
hv_uio_new_channel(struct vmbus_channel *new_sc)
|
||||
|
|
@ -178,8 +166,7 @@ hv_uio_new_channel(struct vmbus_channel *new_sc)
|
|||
/* Disable interrupts on sub channel */
|
||||
new_sc->inbound.ring_buffer->interrupt_mask = 1;
|
||||
set_channel_read_mode(new_sc, HV_CALL_ISR);
|
||||
|
||||
ret = sysfs_create_bin_file(&new_sc->kobj, &ring_buffer_bin_attr);
|
||||
ret = hv_create_ring_sysfs(new_sc, hv_uio_ring_mmap);
|
||||
if (ret) {
|
||||
dev_err(device, "sysfs create ring bin file failed; %d\n", ret);
|
||||
vmbus_close(new_sc);
|
||||
|
|
@ -350,10 +337,18 @@ hv_uio_probe(struct hv_device *dev,
|
|||
goto fail_close;
|
||||
}
|
||||
|
||||
ret = sysfs_create_bin_file(&channel->kobj, &ring_buffer_bin_attr);
|
||||
if (ret)
|
||||
dev_notice(&dev->device,
|
||||
"sysfs create ring bin file failed; %d\n", ret);
|
||||
/*
|
||||
* This internally calls sysfs_update_group, which returns a non-zero value if it executes
|
||||
* before sysfs_create_group. This is expected as the 'ring' will be created later in
|
||||
* vmbus_device_register() -> vmbus_add_channel_kobj(). Thus, no need to check the return
|
||||
* value and print warning.
|
||||
*
|
||||
* Creating/exposing sysfs in driver probe is not encouraged as it can lead to race
|
||||
* conditions with userspace. For backward compatibility, "ring" sysfs could not be removed
|
||||
* or decoupled from uio_hv_generic probe. Userspace programs can make use of inotify
|
||||
* APIs to make sure that ring is created.
|
||||
*/
|
||||
hv_create_ring_sysfs(channel, hv_uio_ring_mmap);
|
||||
|
||||
hv_set_drvdata(dev, pdata);
|
||||
|
||||
|
|
@ -375,7 +370,7 @@ hv_uio_remove(struct hv_device *dev)
|
|||
if (!pdata)
|
||||
return;
|
||||
|
||||
sysfs_remove_bin_file(&dev->channel->kobj, &ring_buffer_bin_attr);
|
||||
hv_remove_ring_sysfs(dev->channel);
|
||||
uio_unregister_device(&pdata->info);
|
||||
hv_uio_cleanup(dev, pdata);
|
||||
|
||||
|
|
|
|||
|
|
@ -1002,6 +1002,12 @@ struct vmbus_channel {
|
|||
|
||||
/* The max size of a packet on this channel */
|
||||
u32 max_pkt_size;
|
||||
|
||||
/* function to mmap ring buffer memory to the channel's sysfs ring attribute */
|
||||
int (*mmap_ring_buffer)(struct vmbus_channel *channel, struct vm_area_struct *vma);
|
||||
|
||||
/* boolean to control visibility of sysfs for ring buffer */
|
||||
bool ring_sysfs_visible;
|
||||
};
|
||||
|
||||
#define lock_requestor(channel, flags) \
|
||||
|
|
|
|||
Loading…
Reference in New Issue