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