Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 336811
b: refs/heads/master
c: fc4e251
h: refs/heads/master
i:
  336809: c348e39
  336807: e96c5a6
v: v3
  • Loading branch information
Ryan Mallon authored and Linus Walleij committed Oct 22, 2012
1 parent fd5f273 commit f11d9c8
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 40 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 67a0d4993d85ee2f42c9909127794553df69dd59
refs/heads/master: fc4e2514995d9cd7f3e1a67098ce65d72acf8ec7
85 changes: 46 additions & 39 deletions trunk/drivers/gpio/gpiolib.c
Original file line number Diff line number Diff line change
Expand Up @@ -702,68 +702,75 @@ int gpio_export(unsigned gpio, bool direction_may_change)
{
unsigned long flags;
struct gpio_desc *desc;
int status = -EINVAL;
int status;
const char *ioname = NULL;
struct device *dev;

/* can't export until sysfs is available ... */
if (!gpio_class.p) {
pr_debug("%s: called too early!\n", __func__);
return -ENOENT;
}

if (!gpio_is_valid(gpio))
goto done;
if (!gpio_is_valid(gpio)) {
pr_debug("%s: gpio %d is not valid\n", __func__, gpio);
return -EINVAL;
}

mutex_lock(&sysfs_lock);

spin_lock_irqsave(&gpio_lock, flags);
desc = &gpio_desc[gpio];
if (test_bit(FLAG_REQUESTED, &desc->flags)
&& !test_bit(FLAG_EXPORT, &desc->flags)) {
status = 0;
if (!desc->chip->direction_input
|| !desc->chip->direction_output)
direction_may_change = false;
if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
test_bit(FLAG_EXPORT, &desc->flags)) {
spin_unlock_irqrestore(&gpio_lock, flags);
pr_debug("%s: gpio %d unavailable (requested=%d, exported=%d)\n",
__func__, gpio,
test_bit(FLAG_REQUESTED, &desc->flags),
test_bit(FLAG_EXPORT, &desc->flags));
return -EPERM;
}

if (!desc->chip->direction_input || !desc->chip->direction_output)
direction_may_change = false;
spin_unlock_irqrestore(&gpio_lock, flags);

if (desc->chip->names && desc->chip->names[gpio - desc->chip->base])
ioname = desc->chip->names[gpio - desc->chip->base];

if (status == 0) {
struct device *dev;

dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
desc, ioname ? ioname : "gpio%u", gpio);
if (!IS_ERR(dev)) {
status = sysfs_create_group(&dev->kobj,
&gpio_attr_group);

if (!status && direction_may_change)
status = device_create_file(dev,
&dev_attr_direction);

if (!status && gpio_to_irq(gpio) >= 0
&& (direction_may_change
|| !test_bit(FLAG_IS_OUT,
&desc->flags)))
status = device_create_file(dev,
&dev_attr_edge);

if (status != 0)
device_unregister(dev);
} else
status = PTR_ERR(dev);
if (status == 0)
set_bit(FLAG_EXPORT, &desc->flags);
dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
desc, ioname ? ioname : "gpio%u", gpio);
if (IS_ERR(dev)) {
status = PTR_ERR(dev);
goto fail_unlock;
}

mutex_unlock(&sysfs_lock);

done:
status = sysfs_create_group(&dev->kobj, &gpio_attr_group);
if (status)
pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
goto fail_unregister_device;

if (direction_may_change) {
status = device_create_file(dev, &dev_attr_direction);
if (status)
goto fail_unregister_device;
}

if (gpio_to_irq(gpio) >= 0 && (direction_may_change ||
!test_bit(FLAG_IS_OUT, &desc->flags))) {
status = device_create_file(dev, &dev_attr_edge);
if (status)
goto fail_unregister_device;
}

set_bit(FLAG_EXPORT, &desc->flags);
mutex_unlock(&sysfs_lock);
return 0;

fail_unregister_device:
device_unregister(dev);
fail_unlock:
mutex_unlock(&sysfs_lock);
pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
return status;
}
EXPORT_SYMBOL_GPL(gpio_export);
Expand Down

0 comments on commit f11d9c8

Please sign in to comment.