Search code examples
linuxlinux-kernellinux-device-driversysfsiio

Linux Kernel IIO events sysfs files only readable


I have the problem that I registered IIO events for rising and falling thresholds. I can see the sysfs files in events subfolder and can read them, but when I try to write a new threshold it says "permission denied".

following setup:

static const struct iio_event_spec as6200_events[] = {
  {
    .type = IIO_EV_TYPE_THRESH,
    .dir = IIO_EV_DIR_RISING,
    .mask_separate = BIT(IIO_EV_INFO_VALUE),
  }, {
    .type = IIO_EV_TYPE_THRESH,
    .dir = IIO_EV_DIR_FALLING,
    .mask_separate = BIT(IIO_EV_INFO_VALUE),
  }
};

static const struct iio_chan_spec as6200_channels[] = {
  {
    .type = IIO_TEMP,
    .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
      BIT(IIO_CHAN_INFO_PROCESSED) |
      BIT(IIO_CHAN_INFO_SCALE),
    .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ),
    .event_spec = as6200_events,
    .num_event_specs = ARRAY_SIZE(as6200_events),
  }
};

Solution

  • finding: it works when I change the permissions of the in_temp_thresh_rising_value file to 666 via sudo. But why is it not created with this permissions via IIO subsystem?

    This is common practice for sysfs files, as writing to those files can alter system's behavior and even compromise or break the system. So if you want to write to those files, you should do that from root, or add your user to corresponding group, or change that file mode (by udev rule or by hand).

    Here is how it's done in IIO code:

    • IIO sysfs node names are derived from next tables in drivers/iio/industrialio-event.c: iio_ev_type_text, iio_ev_dir_text and iio_ev_info_text
    • node creation path is next: iio_device_add_event() -> __iio_add_chan_devattr() -> __iio_device_attr_init()
    • file mode for sysfs node is being set in __iio_device_attr_init():

      • for reading: dev_attr->attr.mode |= S_IRUGO;

        • so every user can read the node (because S_IRUGO allows Reading for User, Group and Others)
      • for writing: dev_attr->attr.mode |= S_IWUSR;

        • so it only can be written by root (because S_IWUSR allows writing only for file owner, which is root)