需要内核配置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);