Skip to content

Day17 - sysfs Control Plane

Goal

Expose debounce_ms through sysfs and verify interaction with ioctl.


Step 1: Add device pointer

struct device *chardev;

Step 2: Create device

mydev->chardev = device_create(mygpio_class, NULL, mydev->devt, mydev, "mygpio");
if (IS_ERR(mydev->chardev)) {
    ret = PTR_ERR(mydev->chardev);
    mydev->chardev = NULL;
    goto err;
}

dev_set_drvdata(mydev->chardev, mydev);

Step 3: Define sysfs attribute

static ssize_t debounce_ms_show(struct device *dev,
                                struct device_attribute *attr,
                                char *buf)
{
    struct mygpio_dev *mydev = dev_get_drvdata(dev);

    if (!mydev)
        return -ENODEV;

    return sysfs_emit(buf, "%u\n", mydev->debounce_ms);
}

static ssize_t debounce_ms_store(struct device *dev,
                                 struct device_attribute *attr,
                                 const char *buf,
                                 size_t count)
{
    struct mygpio_dev *mydev = dev_get_drvdata(dev);
    unsigned int value;
    int ret;

    if (!mydev)
        return -ENODEV;

    ret = kstrtouint(buf, 0, &value);
    if (ret)
        return ret;

    mydev->debounce_ms = value;

    return count;
}

static DEVICE_ATTR_RW(debounce_ms);

Step 4: Create sysfs file

ret = device_create_file(mydev->chardev, &dev_attr_debounce_ms);
if (ret)
    goto err_device_destroy;

Step 5: Remove sysfs file

device_remove_file(mydev->chardev, &dev_attr_debounce_ms);

Step 6: Test sysfs

ls /sys/class/mygpio/mygpio

cat /sys/class/mygpio/mygpio/debounce_ms

echo 35 | sudo tee /sys/class/mygpio/mygpio/debounce_ms
cat /sys/class/mygpio/mygpio/debounce_ms

Step 7: Verify with ioctl

  1. Set debounce via sysfs
  2. Read status via ioctl
  3. Set debounce via ioctl
  4. Read via sysfs

Confirm both interfaces modify the same driver state.