mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-18 19:05:39 +00:00
gpiolib: provide a dedicated function for setting lineinfo
We'll soon be filling out the gpioline_info structure in multiple places. Add a separate function that given a gpio_desc sets all relevant fields. Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
This commit is contained in:
parent
248ae1752e
commit
d2ac257982
@ -1147,6 +1147,60 @@ out_free_le:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
|
||||
struct gpioline_info *info)
|
||||
{
|
||||
struct gpio_chip *chip = desc->gdev->chip;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&gpio_lock, flags);
|
||||
|
||||
if (desc->name) {
|
||||
strncpy(info->name, desc->name, sizeof(info->name));
|
||||
info->name[sizeof(info->name) - 1] = '\0';
|
||||
} else {
|
||||
info->name[0] = '\0';
|
||||
}
|
||||
|
||||
if (desc->label) {
|
||||
strncpy(info->consumer, desc->label, sizeof(info->consumer));
|
||||
info->consumer[sizeof(info->consumer) - 1] = '\0';
|
||||
} else {
|
||||
info->consumer[0] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* Userspace only need to know that the kernel is using this GPIO so
|
||||
* it can't use it.
|
||||
*/
|
||||
info->flags = 0;
|
||||
if (test_bit(FLAG_REQUESTED, &desc->flags) ||
|
||||
test_bit(FLAG_IS_HOGGED, &desc->flags) ||
|
||||
test_bit(FLAG_USED_AS_IRQ, &desc->flags) ||
|
||||
test_bit(FLAG_EXPORT, &desc->flags) ||
|
||||
test_bit(FLAG_SYSFS, &desc->flags) ||
|
||||
!pinctrl_gpio_can_use_line(chip->base + info->line_offset))
|
||||
info->flags |= GPIOLINE_FLAG_KERNEL;
|
||||
if (test_bit(FLAG_IS_OUT, &desc->flags))
|
||||
info->flags |= GPIOLINE_FLAG_IS_OUT;
|
||||
if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
|
||||
info->flags |= GPIOLINE_FLAG_ACTIVE_LOW;
|
||||
if (test_bit(FLAG_OPEN_DRAIN, &desc->flags))
|
||||
info->flags |= (GPIOLINE_FLAG_OPEN_DRAIN |
|
||||
GPIOLINE_FLAG_IS_OUT);
|
||||
if (test_bit(FLAG_OPEN_SOURCE, &desc->flags))
|
||||
info->flags |= (GPIOLINE_FLAG_OPEN_SOURCE |
|
||||
GPIOLINE_FLAG_IS_OUT);
|
||||
if (test_bit(FLAG_BIAS_DISABLE, &desc->flags))
|
||||
info->flags |= GPIOLINE_FLAG_BIAS_DISABLE;
|
||||
if (test_bit(FLAG_PULL_DOWN, &desc->flags))
|
||||
info->flags |= GPIOLINE_FLAG_BIAS_PULL_DOWN;
|
||||
if (test_bit(FLAG_PULL_UP, &desc->flags))
|
||||
info->flags |= GPIOLINE_FLAG_BIAS_PULL_UP;
|
||||
|
||||
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* gpio_ioctl() - ioctl handler for the GPIO chardev
|
||||
*/
|
||||
@ -1187,49 +1241,7 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
if (IS_ERR(desc))
|
||||
return PTR_ERR(desc);
|
||||
|
||||
if (desc->name) {
|
||||
strncpy(lineinfo.name, desc->name,
|
||||
sizeof(lineinfo.name));
|
||||
lineinfo.name[sizeof(lineinfo.name)-1] = '\0';
|
||||
} else {
|
||||
lineinfo.name[0] = '\0';
|
||||
}
|
||||
if (desc->label) {
|
||||
strncpy(lineinfo.consumer, desc->label,
|
||||
sizeof(lineinfo.consumer));
|
||||
lineinfo.consumer[sizeof(lineinfo.consumer)-1] = '\0';
|
||||
} else {
|
||||
lineinfo.consumer[0] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* Userspace only need to know that the kernel is using
|
||||
* this GPIO so it can't use it.
|
||||
*/
|
||||
lineinfo.flags = 0;
|
||||
if (test_bit(FLAG_REQUESTED, &desc->flags) ||
|
||||
test_bit(FLAG_IS_HOGGED, &desc->flags) ||
|
||||
test_bit(FLAG_USED_AS_IRQ, &desc->flags) ||
|
||||
test_bit(FLAG_EXPORT, &desc->flags) ||
|
||||
test_bit(FLAG_SYSFS, &desc->flags) ||
|
||||
!pinctrl_gpio_can_use_line(chip->base + lineinfo.line_offset))
|
||||
lineinfo.flags |= GPIOLINE_FLAG_KERNEL;
|
||||
if (test_bit(FLAG_IS_OUT, &desc->flags))
|
||||
lineinfo.flags |= GPIOLINE_FLAG_IS_OUT;
|
||||
if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
|
||||
lineinfo.flags |= GPIOLINE_FLAG_ACTIVE_LOW;
|
||||
if (test_bit(FLAG_OPEN_DRAIN, &desc->flags))
|
||||
lineinfo.flags |= (GPIOLINE_FLAG_OPEN_DRAIN |
|
||||
GPIOLINE_FLAG_IS_OUT);
|
||||
if (test_bit(FLAG_OPEN_SOURCE, &desc->flags))
|
||||
lineinfo.flags |= (GPIOLINE_FLAG_OPEN_SOURCE |
|
||||
GPIOLINE_FLAG_IS_OUT);
|
||||
if (test_bit(FLAG_BIAS_DISABLE, &desc->flags))
|
||||
lineinfo.flags |= GPIOLINE_FLAG_BIAS_DISABLE;
|
||||
if (test_bit(FLAG_PULL_DOWN, &desc->flags))
|
||||
lineinfo.flags |= GPIOLINE_FLAG_BIAS_PULL_DOWN;
|
||||
if (test_bit(FLAG_PULL_UP, &desc->flags))
|
||||
lineinfo.flags |= GPIOLINE_FLAG_BIAS_PULL_UP;
|
||||
gpio_desc_to_lineinfo(desc, &lineinfo);
|
||||
|
||||
if (copy_to_user(ip, &lineinfo, sizeof(lineinfo)))
|
||||
return -EFAULT;
|
||||
|
Loading…
x
Reference in New Issue
Block a user