linux/drivers/iio/trigger/iio-trig-sysfs.c
Greg Kroah-Hartman 56d784d177 1st set of IIO new device support, feature and cleanup for 6.2 (take2)
We have finally managed to take the mlock mutex entirely private so as
 to avoid it being used for multiple purposes.  Now it is just used to
 protect device mode transitions (typically to and from buffered capture).
 
 Includes merge of an immutable i2c branch to get the new
 i2c_client_get_device_id() (thanks to Wolfram for providing the branch).
 
 Based on rc3 to pick up some precursor fixes from early in the cycle and
 avoid an unnecessarily messy history.
 
 New device support
 * adi,ad4310
   - New driver to support this very flexible measurement device including
     a 24 bit ADC. Later fix for documentation build issue.
 * adi,adxl355
   - Add support of the ADXL359 accelerometer.
 * adi,ltc2983
   - Support additional variants of the temperatures sensor:
     LTC2984 with an EEPROM
     LTC2985, LTC2986 with only 10 channels.
 * invensense,icm42600
   - Add support for icm42631 (needed only ID and WHOAMI)
 * kionix,kx022a
   - New driver for this 3 axis accelerometer.
 * maxim,max11401
   - New driver to support this 24-bit 10 channel ADC.
     Includes some new ABI to support configuration of notch filters.
 * mediatek,mt6370
   - Add new driver to support the ADC part of the mt6370.
 * st,lsm6dsx
   - Add support for LSM6DSV accelerometer and gyroscope. Simple additional
     of chip specific data and IDs.
   - Add support for LSM6DSV16X accelerometer and gyroscope.  Compatible with
     features currently implemented for the LSM6DSV.
 * st,stm32-adc
   - Add support for stm32pm13x SoCs.
 
 core / subsystem wide:
  - Add new IIO_STATIC_CONST_DEVICE_ATTR() which is a dance necessary to
    allow for the wrapping of attributes in the code that duplicates them
    for multiple buffers.
  - Harden against future issues with expectation that all buffer attributes
    are iio_dev_attrs by changing the code to take an array of pointers
    of the correct type.
  - Last transitions of drivers to local locks rather than missuses of mlock.
  - Add an iio_device_claim_buffer_mode() callback to avoid a race in the
    max30100 driver without directly using mlock.
  - Move mlock to the opaque IIO device structure to prevent misuse.
  - Add missing spi_device_id tables to support auto loading of modules.
  - Update some ADI maintainers in DT bindings.
  - A few more moves of bus drivers and core module sets to export
    name spaces.
  - Extensive use of new devm_regulator_get_enable() and friends.
  - Switch a bunch of i2c drivers to probe_new() including the bmp280
    which makes use of the new i2c_client_get_device_id() helper to
    simplify this change.
 
 dt-bindings:
  - More use of spi-peripheral-props.yaml.
 
 Features
 * freescale,mpl115
   - Use runtime PM to implement shutdown GPIO support.
 * melexis,mlx90632
   - More sophisticated runtime power management
   - Provide access to sampling frequency.
   - Trivial follow up fixes.
 * microchip,mcp3911
   - Support control of PGA.
 * st,lsm6dsx
   - Add support for software triggers for cases where the IRQ lines
     are not wired up.
 * vishay,vcnl4000
   - Add control of integration time.
 
 Minor cleanups and fixes
 * adi,ad4130
   - Improve ABI documentation formatting.
   - Kconfig dependency fixup.
 * adi,ad5758
   - Minor dt binding fix.
 * adi,ad9834
   - Tidy up line breaks.
 * adi,ade7854
   - Minor improvement in code clarity by replacing a ternary.
 * adi,admv8818
   - Harden code against hardware returning wrong values.
 * adi,adxl355
   - Warn only if unknown device ID detected to allow for fall back
     device tree compatibles on future devices.
 * adi,ltc2983
   - dt-bindings clarifications and general improvements.
   - Ensure DMA safe buffer for bulk writes without relying on current
     regmap implementation choices.
 * avago,adps9960
   - Fix up a disconnect between event enable attributes and what was
     enabled.
 * bosch,bma400
   - Switch to dev_err_probe() from open coded EPROBE_DEFER handling.
 * cosmic,cc10001
   - Fully devm managed probe() and related tidying up.
 * meas,ms5611
   - Add an example of spi-max-frequency.
 * meleixs,mlx90632
   - Tidy up confusing error return value.
   - Style improvements.
 * multiplexer
   - Switch to dev_err_probe() from open coded EPROBE_DEFER handling.
 * qcom,spmi-vadc
   - Minor dt binding improvements.
 * rockchip,saradc
   - Add ID for rv1126.
 * semtech,sx9360
   - Add SAMM0208 ACPI ID. Doesn't appear to be a valid vendor prefix
     but is in the wild.
 * st,lsm6dsx
   - Factor out common code as _device_set_enable().
   - Fix up wrong docs after LSM6DSV addition.
 * st,stm32-adc
   - Manage the min sampling time on all internal channels.
 * trig,sysfs
   - Improve error labels.
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAmN+fI4RHGppYzIzQGtl
 cm5lbC5vcmcACgkQVIU0mcT0FogY1Q/7BTdKLbRuFoE4aK9AABv+m4w91s+RlBg6
 eXRw3Gt4IHHht7gIUVZByYztyoKkmW3RzsPafIlfJJkWAsiBpv6gXTW2h6UvjHg8
 SW3k91oVk5iLEeTaUSfJqxHCXX+VRYanyeti53MkpUvR2QUgAengP11N6bWmNXav
 D6OFGSTn9QpJ0XRmEmfxXt3pt/Miuz7GT2sN5ut1ZvTgN0wZ2aMMdEa8w3UQvxoN
 +Iu0Z3kRtltbw5zqTTdJfXPHS3K1I+361zTT6E4KDVun2939C3Tzw6ziy6MIsng+
 nysaMbZTc5MmdIDPYtSlIV+i4S4DyqvAKsv5PBqqbD3oQfo8AkmnyY6Hdygbv23O
 vK23x19GYcpgLQ42C0g+LFUYxJOJMnMiOocISq8V7Df9+CQRNnk4e7s8MvmhAXmu
 VrOT1VDEL8bJFeukiMRtVTsDo/KRHOWUjEi+1dxJ7aOqry8FGrlR4L+ZtjbMTnmw
 V+7CN0euOdpiDV6jJwmXHQvLWlG3wgq7ZHHj6toaFtq8FI4OaQiA7Ko5WuBLTBxw
 V0jtK/Fru77P0aR7dAd5ck6Rwek8N2rSuOvpucLmImt9asZP3uzoM/LRmtv4Gzjq
 Dp8koqSwx6YMtMAHmXgB/2GkSoOV7eByvIkYCoFCxEp2tst+mIOKSQPDKP8PKuRd
 VBSmvuEilis=
 =Fo38
 -----END PGP SIGNATURE-----

Merge tag 'iio-for-6.2a-take2' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-next

Jonathan writes:

1st set of IIO new device support, feature and cleanup for 6.2 (take2)

We have finally managed to take the mlock mutex entirely private so as
to avoid it being used for multiple purposes.  Now it is just used to
protect device mode transitions (typically to and from buffered capture).

Includes merge of an immutable i2c branch to get the new
i2c_client_get_device_id() (thanks to Wolfram for providing the branch).

Based on rc3 to pick up some precursor fixes from early in the cycle and
avoid an unnecessarily messy history.

New device support
* adi,ad4310
  - New driver to support this very flexible measurement device including
    a 24 bit ADC. Later fix for documentation build issue.
* adi,adxl355
  - Add support of the ADXL359 accelerometer.
* adi,ltc2983
  - Support additional variants of the temperatures sensor:
    LTC2984 with an EEPROM
    LTC2985, LTC2986 with only 10 channels.
* invensense,icm42600
  - Add support for icm42631 (needed only ID and WHOAMI)
* kionix,kx022a
  - New driver for this 3 axis accelerometer.
* maxim,max11401
  - New driver to support this 24-bit 10 channel ADC.
    Includes some new ABI to support configuration of notch filters.
* mediatek,mt6370
  - Add new driver to support the ADC part of the mt6370.
* st,lsm6dsx
  - Add support for LSM6DSV accelerometer and gyroscope. Simple additional
    of chip specific data and IDs.
  - Add support for LSM6DSV16X accelerometer and gyroscope.  Compatible with
    features currently implemented for the LSM6DSV.
* st,stm32-adc
  - Add support for stm32pm13x SoCs.

core / subsystem wide:
 - Add new IIO_STATIC_CONST_DEVICE_ATTR() which is a dance necessary to
   allow for the wrapping of attributes in the code that duplicates them
   for multiple buffers.
 - Harden against future issues with expectation that all buffer attributes
   are iio_dev_attrs by changing the code to take an array of pointers
   of the correct type.
 - Last transitions of drivers to local locks rather than missuses of mlock.
 - Add an iio_device_claim_buffer_mode() callback to avoid a race in the
   max30100 driver without directly using mlock.
 - Move mlock to the opaque IIO device structure to prevent misuse.
 - Add missing spi_device_id tables to support auto loading of modules.
 - Update some ADI maintainers in DT bindings.
 - A few more moves of bus drivers and core module sets to export
   name spaces.
 - Extensive use of new devm_regulator_get_enable() and friends.
 - Switch a bunch of i2c drivers to probe_new() including the bmp280
   which makes use of the new i2c_client_get_device_id() helper to
   simplify this change.

dt-bindings:
 - More use of spi-peripheral-props.yaml.

Features
* freescale,mpl115
  - Use runtime PM to implement shutdown GPIO support.
* melexis,mlx90632
  - More sophisticated runtime power management
  - Provide access to sampling frequency.
  - Trivial follow up fixes.
* microchip,mcp3911
  - Support control of PGA.
* st,lsm6dsx
  - Add support for software triggers for cases where the IRQ lines
    are not wired up.
* vishay,vcnl4000
  - Add control of integration time.

Minor cleanups and fixes
* adi,ad4130
  - Improve ABI documentation formatting.
  - Kconfig dependency fixup.
* adi,ad5758
  - Minor dt binding fix.
* adi,ad9834
  - Tidy up line breaks.
* adi,ade7854
  - Minor improvement in code clarity by replacing a ternary.
* adi,admv8818
  - Harden code against hardware returning wrong values.
* adi,adxl355
  - Warn only if unknown device ID detected to allow for fall back
    device tree compatibles on future devices.
* adi,ltc2983
  - dt-bindings clarifications and general improvements.
  - Ensure DMA safe buffer for bulk writes without relying on current
    regmap implementation choices.
* avago,adps9960
  - Fix up a disconnect between event enable attributes and what was
    enabled.
* bosch,bma400
  - Switch to dev_err_probe() from open coded EPROBE_DEFER handling.
* cosmic,cc10001
  - Fully devm managed probe() and related tidying up.
* meas,ms5611
  - Add an example of spi-max-frequency.
* meleixs,mlx90632
  - Tidy up confusing error return value.
  - Style improvements.
* multiplexer
  - Switch to dev_err_probe() from open coded EPROBE_DEFER handling.
* qcom,spmi-vadc
  - Minor dt binding improvements.
* rockchip,saradc
  - Add ID for rv1126.
* semtech,sx9360
  - Add SAMM0208 ACPI ID. Doesn't appear to be a valid vendor prefix
    but is in the wild.
* st,lsm6dsx
  - Factor out common code as _device_set_enable().
  - Fix up wrong docs after LSM6DSV addition.
* st,stm32-adc
  - Manage the min sampling time on all internal channels.
* trig,sysfs
  - Improve error labels.

* tag 'iio-for-6.2a-take2' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (146 commits)
  iio: pressure: bmp280: convert to i2c's .probe_new()
  iio: imu: st_lsm6dsx: fix LSM6DSV sensor description
  iio: adc: ad4130: depend on GPIOLIB
  staging: iio: meter: replace ternary operator by if condition
  iio: light: apds9960: Fix iio_event_spec structures
  dt-bindings: iio: imu: Add inv_icm42600 documentation
  iio: imu: inv_icm42600: Add support for icm42631
  dt-bindings: iio: adc: rockchip-saradc: Add saradc for rv1126
  dt-bindings: iio: dac: adi,ad5758: Drop 'contains' from 'adi,dc-dc-mode'
  dt-bindings: iio: imu: st_lsm6dsx: add lsm6dsv16x
  iio: imu: st_lsm6dsx: add support to LSM6DSV16X
  iio: proximity: sx9360: Add a new ACPI hardware ID
  iio: temperature: mlx90632: Add missing static marking on devm_pm_ops
  iio: temperature: mlx90632: Add error handling for devm_pm_runtime_enable()
  iio: temperature: ltc2983: support more parts
  dt-bindings: iio: temperature: ltc2983: support more parts
  dt-bindings: iio: temperature: ltc2983: use generic node name in example
  dt-bindings: iio: temperature: ltc2983: describe broken mux delay property
  dt-bindings: iio: temperature: ltc2983: refine descriptions
  dt-bindings: iio: temperature: ltc2983: change default excitation for custom thermistors
  ...
2022-11-25 18:35:16 +01:00

226 lines
4.8 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright 2011 Analog Devices Inc.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/irq_work.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
struct iio_sysfs_trig {
struct iio_trigger *trig;
struct irq_work work;
int id;
struct list_head l;
};
static LIST_HEAD(iio_sysfs_trig_list);
static DEFINE_MUTEX(iio_sysfs_trig_list_mut);
static int iio_sysfs_trigger_probe(int id);
static ssize_t iio_sysfs_trig_add(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t len)
{
int ret;
unsigned long input;
ret = kstrtoul(buf, 10, &input);
if (ret)
return ret;
ret = iio_sysfs_trigger_probe(input);
if (ret)
return ret;
return len;
}
static DEVICE_ATTR(add_trigger, S_IWUSR, NULL, &iio_sysfs_trig_add);
static int iio_sysfs_trigger_remove(int id);
static ssize_t iio_sysfs_trig_remove(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t len)
{
int ret;
unsigned long input;
ret = kstrtoul(buf, 10, &input);
if (ret)
return ret;
ret = iio_sysfs_trigger_remove(input);
if (ret)
return ret;
return len;
}
static DEVICE_ATTR(remove_trigger, S_IWUSR, NULL, &iio_sysfs_trig_remove);
static struct attribute *iio_sysfs_trig_attrs[] = {
&dev_attr_add_trigger.attr,
&dev_attr_remove_trigger.attr,
NULL,
};
static const struct attribute_group iio_sysfs_trig_group = {
.attrs = iio_sysfs_trig_attrs,
};
static const struct attribute_group *iio_sysfs_trig_groups[] = {
&iio_sysfs_trig_group,
NULL
};
/* Nothing to actually do upon release */
static void iio_trigger_sysfs_release(struct device *dev)
{
}
static struct device iio_sysfs_trig_dev = {
.bus = &iio_bus_type,
.groups = iio_sysfs_trig_groups,
.release = &iio_trigger_sysfs_release,
};
static void iio_sysfs_trigger_work(struct irq_work *work)
{
struct iio_sysfs_trig *trig = container_of(work, struct iio_sysfs_trig,
work);
iio_trigger_poll(trig->trig);
}
static ssize_t iio_sysfs_trigger_poll(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct iio_trigger *trig = to_iio_trigger(dev);
struct iio_sysfs_trig *sysfs_trig = iio_trigger_get_drvdata(trig);
irq_work_queue(&sysfs_trig->work);
return count;
}
static DEVICE_ATTR(trigger_now, S_IWUSR, NULL, iio_sysfs_trigger_poll);
static struct attribute *iio_sysfs_trigger_attrs[] = {
&dev_attr_trigger_now.attr,
NULL,
};
static const struct attribute_group iio_sysfs_trigger_attr_group = {
.attrs = iio_sysfs_trigger_attrs,
};
static const struct attribute_group *iio_sysfs_trigger_attr_groups[] = {
&iio_sysfs_trigger_attr_group,
NULL
};
static int iio_sysfs_trigger_probe(int id)
{
struct iio_sysfs_trig *t;
int ret;
bool foundit = false;
mutex_lock(&iio_sysfs_trig_list_mut);
list_for_each_entry(t, &iio_sysfs_trig_list, l)
if (id == t->id) {
foundit = true;
break;
}
if (foundit) {
ret = -EINVAL;
goto err_unlock;
}
t = kmalloc(sizeof(*t), GFP_KERNEL);
if (t == NULL) {
ret = -ENOMEM;
goto err_unlock;
}
t->id = id;
t->trig = iio_trigger_alloc(&iio_sysfs_trig_dev, "sysfstrig%d", id);
if (!t->trig) {
ret = -ENOMEM;
goto err_free_sys_trig;
}
t->trig->dev.groups = iio_sysfs_trigger_attr_groups;
iio_trigger_set_drvdata(t->trig, t);
t->work = IRQ_WORK_INIT_HARD(iio_sysfs_trigger_work);
ret = iio_trigger_register(t->trig);
if (ret)
goto err_free_trig;
list_add(&t->l, &iio_sysfs_trig_list);
__module_get(THIS_MODULE);
mutex_unlock(&iio_sysfs_trig_list_mut);
return 0;
err_free_trig:
iio_trigger_free(t->trig);
err_free_sys_trig:
kfree(t);
err_unlock:
mutex_unlock(&iio_sysfs_trig_list_mut);
return ret;
}
static int iio_sysfs_trigger_remove(int id)
{
struct iio_sysfs_trig *t = NULL, *iter;
mutex_lock(&iio_sysfs_trig_list_mut);
list_for_each_entry(iter, &iio_sysfs_trig_list, l)
if (id == iter->id) {
t = iter;
break;
}
if (!t) {
mutex_unlock(&iio_sysfs_trig_list_mut);
return -EINVAL;
}
iio_trigger_unregister(t->trig);
irq_work_sync(&t->work);
iio_trigger_free(t->trig);
list_del(&t->l);
kfree(t);
module_put(THIS_MODULE);
mutex_unlock(&iio_sysfs_trig_list_mut);
return 0;
}
static int __init iio_sysfs_trig_init(void)
{
int ret;
device_initialize(&iio_sysfs_trig_dev);
dev_set_name(&iio_sysfs_trig_dev, "iio_sysfs_trigger");
ret = device_add(&iio_sysfs_trig_dev);
if (ret)
put_device(&iio_sysfs_trig_dev);
return ret;
}
module_init(iio_sysfs_trig_init);
static void __exit iio_sysfs_trig_exit(void)
{
device_unregister(&iio_sysfs_trig_dev);
}
module_exit(iio_sysfs_trig_exit);
MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
MODULE_DESCRIPTION("Sysfs based trigger for the iio subsystem");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:iio-trig-sysfs");