|
@@ -504,6 +504,51 @@ static int match_export(struct device *dev, void *data)
|
|
|
return dev_get_drvdata(dev) == data;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * gpio_export_link - create a sysfs link to an exported GPIO node
|
|
|
+ * @dev: device under which to create symlink
|
|
|
+ * @name: name of the symlink
|
|
|
+ * @gpio: gpio to create symlink to, already exported
|
|
|
+ *
|
|
|
+ * Set up a symlink from /sys/.../dev/name to /sys/class/gpio/gpioN
|
|
|
+ * node. Caller is responsible for unlinking.
|
|
|
+ *
|
|
|
+ * Returns zero on success, else an error.
|
|
|
+ */
|
|
|
+int gpio_export_link(struct device *dev, const char *name, unsigned gpio)
|
|
|
+{
|
|
|
+ struct gpio_desc *desc;
|
|
|
+ int status = -EINVAL;
|
|
|
+
|
|
|
+ if (!gpio_is_valid(gpio))
|
|
|
+ goto done;
|
|
|
+
|
|
|
+ mutex_lock(&sysfs_lock);
|
|
|
+
|
|
|
+ desc = &gpio_desc[gpio];
|
|
|
+
|
|
|
+ if (test_bit(FLAG_EXPORT, &desc->flags)) {
|
|
|
+ struct device *tdev;
|
|
|
+
|
|
|
+ tdev = class_find_device(&gpio_class, NULL, desc, match_export);
|
|
|
+ if (tdev != NULL) {
|
|
|
+ status = sysfs_create_link(&dev->kobj, &tdev->kobj,
|
|
|
+ name);
|
|
|
+ } else {
|
|
|
+ status = -ENODEV;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ mutex_unlock(&sysfs_lock);
|
|
|
+
|
|
|
+done:
|
|
|
+ if (status)
|
|
|
+ pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(gpio_export_link);
|
|
|
+
|
|
|
/**
|
|
|
* gpio_unexport - reverse effect of gpio_export()
|
|
|
* @gpio: gpio to make unavailable
|