Skip to content

Commit 914a1fe

Browse files
committed
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 ...
2 parents ed36b43 + 65995e9 commit 914a1fe

29 files changed

+241
-96
lines changed

drivers/hv/hyperv_vmbus.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,4 +477,10 @@ static inline int hv_debug_add_dev_dir(struct hv_device *dev)
477477

478478
#endif /* CONFIG_HYPERV_TESTING */
479479

480+
/* Create and remove sysfs entry for memory mapped ring buffers for a channel */
481+
int hv_create_ring_sysfs(struct vmbus_channel *channel,
482+
int (*hv_mmap_ring_buffer)(struct vmbus_channel *channel,
483+
struct vm_area_struct *vma));
484+
int hv_remove_ring_sysfs(struct vmbus_channel *channel);
485+
480486
#endif /* _HYPERV_VMBUS_H */

drivers/hv/vmbus_drv.c

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1802,6 +1802,26 @@ static ssize_t subchannel_id_show(struct vmbus_channel *channel,
18021802
}
18031803
static VMBUS_CHAN_ATTR_RO(subchannel_id);
18041804

1805+
static int hv_mmap_ring_buffer_wrapper(struct file *filp, struct kobject *kobj,
1806+
const struct bin_attribute *attr,
1807+
struct vm_area_struct *vma)
1808+
{
1809+
struct vmbus_channel *channel = container_of(kobj, struct vmbus_channel, kobj);
1810+
1811+
/*
1812+
* hv_(create|remove)_ring_sysfs implementation ensures that mmap_ring_buffer
1813+
* is not NULL.
1814+
*/
1815+
return channel->mmap_ring_buffer(channel, vma);
1816+
}
1817+
1818+
static struct bin_attribute chan_attr_ring_buffer = {
1819+
.attr = {
1820+
.name = "ring",
1821+
.mode = 0600,
1822+
},
1823+
.mmap = hv_mmap_ring_buffer_wrapper,
1824+
};
18051825
static struct attribute *vmbus_chan_attrs[] = {
18061826
&chan_attr_out_mask.attr,
18071827
&chan_attr_in_mask.attr,
@@ -1821,6 +1841,11 @@ static struct attribute *vmbus_chan_attrs[] = {
18211841
NULL
18221842
};
18231843

1844+
static struct bin_attribute *vmbus_chan_bin_attrs[] = {
1845+
&chan_attr_ring_buffer,
1846+
NULL
1847+
};
1848+
18241849
/*
18251850
* Channel-level attribute_group callback function. Returns the permission for
18261851
* each attribute, and returns 0 if an attribute is not visible.
@@ -1841,16 +1866,98 @@ static umode_t vmbus_chan_attr_is_visible(struct kobject *kobj,
18411866
return attr->mode;
18421867
}
18431868

1869+
static umode_t vmbus_chan_bin_attr_is_visible(struct kobject *kobj,
1870+
const struct bin_attribute *attr, int idx)
1871+
{
1872+
const struct vmbus_channel *channel =
1873+
container_of(kobj, struct vmbus_channel, kobj);
1874+
1875+
/* Hide ring attribute if channel's ring_sysfs_visible is set to false */
1876+
if (attr == &chan_attr_ring_buffer && !channel->ring_sysfs_visible)
1877+
return 0;
1878+
1879+
return attr->attr.mode;
1880+
}
1881+
1882+
static size_t vmbus_chan_bin_size(struct kobject *kobj,
1883+
const struct bin_attribute *bin_attr, int a)
1884+
{
1885+
const struct vmbus_channel *channel =
1886+
container_of(kobj, struct vmbus_channel, kobj);
1887+
1888+
return channel->ringbuffer_pagecount << PAGE_SHIFT;
1889+
}
1890+
18441891
static const struct attribute_group vmbus_chan_group = {
18451892
.attrs = vmbus_chan_attrs,
1846-
.is_visible = vmbus_chan_attr_is_visible
1893+
.bin_attrs = vmbus_chan_bin_attrs,
1894+
.is_visible = vmbus_chan_attr_is_visible,
1895+
.is_bin_visible = vmbus_chan_bin_attr_is_visible,
1896+
.bin_size = vmbus_chan_bin_size,
18471897
};
18481898

18491899
static const struct kobj_type vmbus_chan_ktype = {
18501900
.sysfs_ops = &vmbus_chan_sysfs_ops,
18511901
.release = vmbus_chan_release,
18521902
};
18531903

1904+
/**
1905+
* hv_create_ring_sysfs() - create "ring" sysfs entry corresponding to ring buffers for a channel.
1906+
* @channel: Pointer to vmbus_channel structure
1907+
* @hv_mmap_ring_buffer: function pointer for initializing the function to be called on mmap of
1908+
* channel's "ring" sysfs node, which is for the ring buffer of that channel.
1909+
* Function pointer is of below type:
1910+
* int (*hv_mmap_ring_buffer)(struct vmbus_channel *channel,
1911+
* struct vm_area_struct *vma))
1912+
* This has a pointer to the channel and a pointer to vm_area_struct,
1913+
* used for mmap, as arguments.
1914+
*
1915+
* Sysfs node for ring buffer of a channel is created along with other fields, however its
1916+
* visibility is disabled by default. Sysfs creation needs to be controlled when the use-case
1917+
* is running.
1918+
* For example, HV_NIC device is used either by uio_hv_generic or hv_netvsc at any given point of
1919+
* time, and "ring" sysfs is needed only when uio_hv_generic is bound to that device. To avoid
1920+
* exposing the ring buffer by default, this function is reponsible to enable visibility of
1921+
* ring for userspace to use.
1922+
* Note: Race conditions can happen with userspace and it is not encouraged to create new
1923+
* use-cases for this. This was added to maintain backward compatibility, while solving
1924+
* one of the race conditions in uio_hv_generic while creating sysfs.
1925+
*
1926+
* Returns 0 on success or error code on failure.
1927+
*/
1928+
int hv_create_ring_sysfs(struct vmbus_channel *channel,
1929+
int (*hv_mmap_ring_buffer)(struct vmbus_channel *channel,
1930+
struct vm_area_struct *vma))
1931+
{
1932+
struct kobject *kobj = &channel->kobj;
1933+
1934+
channel->mmap_ring_buffer = hv_mmap_ring_buffer;
1935+
channel->ring_sysfs_visible = true;
1936+
1937+
return sysfs_update_group(kobj, &vmbus_chan_group);
1938+
}
1939+
EXPORT_SYMBOL_GPL(hv_create_ring_sysfs);
1940+
1941+
/**
1942+
* hv_remove_ring_sysfs() - remove ring sysfs entry corresponding to ring buffers for a channel.
1943+
* @channel: Pointer to vmbus_channel structure
1944+
*
1945+
* Hide "ring" sysfs for a channel by changing its is_visible attribute and updating sysfs group.
1946+
*
1947+
* Returns 0 on success or error code on failure.
1948+
*/
1949+
int hv_remove_ring_sysfs(struct vmbus_channel *channel)
1950+
{
1951+
struct kobject *kobj = &channel->kobj;
1952+
int ret;
1953+
1954+
channel->ring_sysfs_visible = false;
1955+
ret = sysfs_update_group(kobj, &vmbus_chan_group);
1956+
channel->mmap_ring_buffer = NULL;
1957+
return ret;
1958+
}
1959+
EXPORT_SYMBOL_GPL(hv_remove_ring_sysfs);
1960+
18541961
/*
18551962
* vmbus_add_channel_kobj - setup a sub-directory under device/channels
18561963
*/

drivers/iio/accel/adis16201.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,9 @@ static const struct iio_chan_spec adis16201_channels[] = {
211211
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
212212
ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC_REG, ADIS16201_SCAN_AUX_ADC, 0, 12),
213213
ADIS_INCLI_CHAN(X, ADIS16201_XINCL_OUT_REG, ADIS16201_SCAN_INCLI_X,
214-
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
214+
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 12),
215215
ADIS_INCLI_CHAN(Y, ADIS16201_YINCL_OUT_REG, ADIS16201_SCAN_INCLI_Y,
216-
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
216+
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 12),
217217
IIO_CHAN_SOFT_TIMESTAMP(7)
218218
};
219219

drivers/iio/accel/adxl355_core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ struct adxl355_data {
231231
u8 transf_buf[3];
232232
struct {
233233
u8 buf[14];
234-
s64 ts;
234+
aligned_s64 ts;
235235
} buffer;
236236
} __aligned(IIO_DMA_MINALIGN);
237237
};

drivers/iio/accel/adxl367.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -601,18 +601,14 @@ static int _adxl367_set_odr(struct adxl367_state *st, enum adxl367_odr odr)
601601
if (ret)
602602
return ret;
603603

604+
st->odr = odr;
605+
604606
/* Activity timers depend on ODR */
605607
ret = _adxl367_set_act_time_ms(st, st->act_time_ms);
606608
if (ret)
607609
return ret;
608610

609-
ret = _adxl367_set_inact_time_ms(st, st->inact_time_ms);
610-
if (ret)
611-
return ret;
612-
613-
st->odr = odr;
614-
615-
return 0;
611+
return _adxl367_set_inact_time_ms(st, st->inact_time_ms);
616612
}
617613

618614
static int adxl367_set_odr(struct iio_dev *indio_dev, enum adxl367_odr odr)

drivers/iio/accel/fxls8962af-core.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,8 +1226,11 @@ int fxls8962af_core_probe(struct device *dev, struct regmap *regmap, int irq)
12261226
if (ret)
12271227
return ret;
12281228

1229-
if (device_property_read_bool(dev, "wakeup-source"))
1230-
device_init_wakeup(dev, true);
1229+
if (device_property_read_bool(dev, "wakeup-source")) {
1230+
ret = devm_device_init_wakeup(dev);
1231+
if (ret)
1232+
return dev_err_probe(dev, ret, "Failed to init wakeup\n");
1233+
}
12311234

12321235
return devm_iio_device_register(dev, indio_dev);
12331236
}

drivers/iio/adc/ad7266.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct ad7266_state {
4545
*/
4646
struct {
4747
__be16 sample[2];
48-
s64 timestamp;
48+
aligned_s64 timestamp;
4949
} data __aligned(IIO_DMA_MINALIGN);
5050
};
5151

drivers/iio/adc/ad7380.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,6 +1211,9 @@ static int ad7380_offload_buffer_predisable(struct iio_dev *indio_dev)
12111211
struct ad7380_state *st = iio_priv(indio_dev);
12121212
int ret;
12131213

1214+
spi_offload_trigger_disable(st->offload, st->offload_trigger);
1215+
spi_unoptimize_message(&st->offload_msg);
1216+
12141217
if (st->seq) {
12151218
ret = regmap_update_bits(st->regmap,
12161219
AD7380_REG_ADDR_CONFIG1,
@@ -1222,10 +1225,6 @@ static int ad7380_offload_buffer_predisable(struct iio_dev *indio_dev)
12221225
st->seq = false;
12231226
}
12241227

1225-
spi_offload_trigger_disable(st->offload, st->offload_trigger);
1226-
1227-
spi_unoptimize_message(&st->offload_msg);
1228-
12291228
return 0;
12301229
}
12311230

@@ -1611,11 +1610,25 @@ static int ad7380_write_event_config(struct iio_dev *indio_dev,
16111610
return ret;
16121611
}
16131612

1614-
static int ad7380_get_alert_th(struct ad7380_state *st,
1613+
static int ad7380_get_alert_th(struct iio_dev *indio_dev,
1614+
const struct iio_chan_spec *chan,
16151615
enum iio_event_direction dir,
16161616
int *val)
16171617
{
1618-
int ret, tmp;
1618+
struct ad7380_state *st = iio_priv(indio_dev);
1619+
const struct iio_scan_type *scan_type;
1620+
int ret, tmp, shift;
1621+
1622+
scan_type = iio_get_current_scan_type(indio_dev, chan);
1623+
if (IS_ERR(scan_type))
1624+
return PTR_ERR(scan_type);
1625+
1626+
/*
1627+
* The register value is 12-bits and is compared to the most significant
1628+
* bits of raw value, therefore a shift is required to convert this to
1629+
* the same scale as the raw value.
1630+
*/
1631+
shift = scan_type->realbits - 12;
16191632

16201633
switch (dir) {
16211634
case IIO_EV_DIR_RISING:
@@ -1625,7 +1638,7 @@ static int ad7380_get_alert_th(struct ad7380_state *st,
16251638
if (ret)
16261639
return ret;
16271640

1628-
*val = FIELD_GET(AD7380_ALERT_HIGH_TH, tmp);
1641+
*val = FIELD_GET(AD7380_ALERT_HIGH_TH, tmp) << shift;
16291642
return IIO_VAL_INT;
16301643
case IIO_EV_DIR_FALLING:
16311644
ret = regmap_read(st->regmap,
@@ -1634,7 +1647,7 @@ static int ad7380_get_alert_th(struct ad7380_state *st,
16341647
if (ret)
16351648
return ret;
16361649

1637-
*val = FIELD_GET(AD7380_ALERT_LOW_TH, tmp);
1650+
*val = FIELD_GET(AD7380_ALERT_LOW_TH, tmp) << shift;
16381651
return IIO_VAL_INT;
16391652
default:
16401653
return -EINVAL;
@@ -1648,15 +1661,14 @@ static int ad7380_read_event_value(struct iio_dev *indio_dev,
16481661
enum iio_event_info info,
16491662
int *val, int *val2)
16501663
{
1651-
struct ad7380_state *st = iio_priv(indio_dev);
16521664
int ret;
16531665

16541666
switch (info) {
16551667
case IIO_EV_INFO_VALUE:
16561668
if (!iio_device_claim_direct(indio_dev))
16571669
return -EBUSY;
16581670

1659-
ret = ad7380_get_alert_th(st, dir, val);
1671+
ret = ad7380_get_alert_th(indio_dev, chan, dir, val);
16601672

16611673
iio_device_release_direct(indio_dev);
16621674
return ret;

drivers/iio/adc/ad7606.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,9 +1236,11 @@ static int ad7616_sw_mode_setup(struct iio_dev *indio_dev)
12361236
st->write_scale = ad7616_write_scale_sw;
12371237
st->write_os = &ad7616_write_os_sw;
12381238

1239-
ret = st->bops->sw_mode_config(indio_dev);
1240-
if (ret)
1241-
return ret;
1239+
if (st->bops->sw_mode_config) {
1240+
ret = st->bops->sw_mode_config(indio_dev);
1241+
if (ret)
1242+
return ret;
1243+
}
12421244

12431245
/* Activate Burst mode and SEQEN MODE */
12441246
return ad7606_write_mask(st, AD7616_CONFIGURATION_REGISTER,
@@ -1268,6 +1270,9 @@ static int ad7606b_sw_mode_setup(struct iio_dev *indio_dev)
12681270
st->write_scale = ad7606_write_scale_sw;
12691271
st->write_os = &ad7606_write_os_sw;
12701272

1273+
if (!st->bops->sw_mode_config)
1274+
return 0;
1275+
12711276
return st->bops->sw_mode_config(indio_dev);
12721277
}
12731278

drivers/iio/adc/ad7606_spi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ static int ad7606_spi_reg_read(struct ad7606_state *st, unsigned int addr)
131131
{
132132
.tx_buf = &st->d16[0],
133133
.len = 2,
134-
.cs_change = 0,
134+
.cs_change = 1,
135135
}, {
136136
.rx_buf = &st->d16[1],
137137
.len = 2,

0 commit comments

Comments
 (0)