Linux 内核设备驱动之GPIO驱动之GPIO sysfs支持

    xiaoxiao2021-03-25  62

    需要内核配置CONFIG_GPIO_SYSFS

    int gpiochip_sysfs_register(struct gpio_device *gdev) {  struct device *dev;  struct device *parent;  struct gpio_chip *chip = gdev->chip;

     /*   * Many systems add gpio chips for SOC support very early,   * before driver model support is available.  In those cases we   * register later, in gpiolib_sysfs_init() ... here we just   * verify that _some_ field of gpio_class got initialized.   */  if (!gpio_class.p)   return 0;

     /*   * For sysfs backward compatibility we need to preserve this   * preferred parenting to the gpio_chip parent field, if set.   */  if (chip->parent)   parent = chip->parent;  else   parent = &gdev->dev;

     /* use chip->base for the ID; it's already known to be unique */  dev = device_create_with_groups(&gpio_class, parent,      MKDEV(0, 0),      chip, gpiochip_groups,      "gpiochip%d", chip->base);  if (IS_ERR(dev))   return PTR_ERR(dev);

     mutex_lock(&sysfs_lock);  gdev->mockdev = dev;  mutex_unlock(&sysfs_lock);

     return 0; }

    void gpiochip_sysfs_unregister(struct gpio_device *gdev) {  struct gpio_desc *desc;  struct gpio_chip *chip = gdev->chip;  unsigned int i;

     if (!gdev->mockdev)   return;

     device_unregister(gdev->mockdev);

     /* prevent further gpiod exports */  mutex_lock(&sysfs_lock);  gdev->mockdev = NULL;  mutex_unlock(&sysfs_lock);

     /* unregister gpiod class devices owned by sysfs */  for (i = 0; i < chip->ngpio; i++) {   desc = &gdev->descs[i];   if (test_and_clear_bit(FLAG_SYSFS, &desc->flags))    gpiod_free(desc);  } }

    static int __init gpiolib_sysfs_init(void) {  int  status;  unsigned long flags;  struct gpio_device *gdev;

     status = class_register(&gpio_class);  if (status < 0)   return status;

     /* Scan and register the gpio_chips which registered very   * early (e.g. before the class_register above was called).   *   * We run before arch_initcall() so chip->dev nodes can have   * registered, and so arch_initcall() can always gpio_export().   */  spin_lock_irqsave(&gpio_lock, flags);  list_for_each_entry(gdev, &gpio_devices, list) {   if (gdev->mockdev)    continue;

      /*    * TODO we yield gpio_lock here because    * gpiochip_sysfs_register() acquires a mutex. This is unsafe    * and needs to be fixed.    *    * Also it would be nice to use gpiochip_find() here so we    * can keep gpio_chips local to gpiolib.c, but the yield of    * gpio_lock prevents us from doing this.    */   spin_unlock_irqrestore(&gpio_lock, flags);   status = gpiochip_sysfs_register(gdev);   spin_lock_irqsave(&gpio_lock, flags);  }  spin_unlock_irqrestore(&gpio_lock, flags);

     return status; } postcore_initcall(gpiolib_sysfs_init);

     
    转载请注明原文地址: https://ju.6miu.com/read-17948.html

    最新回复(0)