|
@@ -365,28 +365,28 @@ static long linehandle_ioctl(struct file *filep, unsigned int cmd,
|
|
|
struct linehandle_state *lh = filep->private_data;
|
|
|
void __user *ip = (void __user *)arg;
|
|
|
struct gpiohandle_data ghd;
|
|
|
+ int vals[GPIOHANDLES_MAX];
|
|
|
int i;
|
|
|
|
|
|
if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) {
|
|
|
- int val;
|
|
|
+ /* TODO: check if descriptors are really input */
|
|
|
+ int ret = gpiod_get_array_value_complex(false,
|
|
|
+ true,
|
|
|
+ lh->numdescs,
|
|
|
+ lh->descs,
|
|
|
+ vals);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
|
|
|
memset(&ghd, 0, sizeof(ghd));
|
|
|
-
|
|
|
- /* TODO: check if descriptors are really input */
|
|
|
- for (i = 0; i < lh->numdescs; i++) {
|
|
|
- val = gpiod_get_value_cansleep(lh->descs[i]);
|
|
|
- if (val < 0)
|
|
|
- return val;
|
|
|
- ghd.values[i] = val;
|
|
|
- }
|
|
|
+ for (i = 0; i < lh->numdescs; i++)
|
|
|
+ ghd.values[i] = vals[i];
|
|
|
|
|
|
if (copy_to_user(ip, &ghd, sizeof(ghd)))
|
|
|
return -EFAULT;
|
|
|
|
|
|
return 0;
|
|
|
} else if (cmd == GPIOHANDLE_SET_LINE_VALUES_IOCTL) {
|
|
|
- int vals[GPIOHANDLES_MAX];
|
|
|
-
|
|
|
/* TODO: check if descriptors are really output */
|
|
|
if (copy_from_user(&ghd, ip, sizeof(ghd)))
|
|
|
return -EFAULT;
|
|
@@ -2466,6 +2466,71 @@ static int gpiod_get_raw_value_commit(const struct gpio_desc *desc)
|
|
|
return value;
|
|
|
}
|
|
|
|
|
|
+static int gpio_chip_get_multiple(struct gpio_chip *chip,
|
|
|
+ unsigned long *mask, unsigned long *bits)
|
|
|
+{
|
|
|
+ if (chip->get_multiple) {
|
|
|
+ return chip->get_multiple(chip, mask, bits);
|
|
|
+ } else if (chip->get) {
|
|
|
+ int i, value;
|
|
|
+
|
|
|
+ for_each_set_bit(i, mask, chip->ngpio) {
|
|
|
+ value = chip->get(chip, i);
|
|
|
+ if (value < 0)
|
|
|
+ return value;
|
|
|
+ __assign_bit(i, bits, value);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return -EIO;
|
|
|
+}
|
|
|
+
|
|
|
+int gpiod_get_array_value_complex(bool raw, bool can_sleep,
|
|
|
+ unsigned int array_size,
|
|
|
+ struct gpio_desc **desc_array,
|
|
|
+ int *value_array)
|
|
|
+{
|
|
|
+ int i = 0;
|
|
|
+
|
|
|
+ while (i < array_size) {
|
|
|
+ struct gpio_chip *chip = desc_array[i]->gdev->chip;
|
|
|
+ unsigned long mask[BITS_TO_LONGS(chip->ngpio)];
|
|
|
+ unsigned long bits[BITS_TO_LONGS(chip->ngpio)];
|
|
|
+ int first, j, ret;
|
|
|
+
|
|
|
+ if (!can_sleep)
|
|
|
+ WARN_ON(chip->can_sleep);
|
|
|
+
|
|
|
+ /* collect all inputs belonging to the same chip */
|
|
|
+ first = i;
|
|
|
+ memset(mask, 0, sizeof(mask));
|
|
|
+ do {
|
|
|
+ const struct gpio_desc *desc = desc_array[i];
|
|
|
+ int hwgpio = gpio_chip_hwgpio(desc);
|
|
|
+
|
|
|
+ __set_bit(hwgpio, mask);
|
|
|
+ i++;
|
|
|
+ } while ((i < array_size) &&
|
|
|
+ (desc_array[i]->gdev->chip == chip));
|
|
|
+
|
|
|
+ ret = gpio_chip_get_multiple(chip, mask, bits);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ for (j = first; j < i; j++) {
|
|
|
+ const struct gpio_desc *desc = desc_array[j];
|
|
|
+ int hwgpio = gpio_chip_hwgpio(desc);
|
|
|
+ int value = test_bit(hwgpio, bits);
|
|
|
+
|
|
|
+ if (!raw && test_bit(FLAG_ACTIVE_LOW, &desc->flags))
|
|
|
+ value = !value;
|
|
|
+ value_array[j] = value;
|
|
|
+ trace_gpio_value(desc_to_gpio(desc), 1, value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* gpiod_get_raw_value() - return a gpio's raw value
|
|
|
* @desc: gpio whose value will be returned
|
|
@@ -2514,6 +2579,51 @@ int gpiod_get_value(const struct gpio_desc *desc)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(gpiod_get_value);
|
|
|
|
|
|
+/**
|
|
|
+ * gpiod_get_raw_array_value() - read raw values from an array of GPIOs
|
|
|
+ * @array_size: number of elements in the descriptor / value arrays
|
|
|
+ * @desc_array: array of GPIO descriptors whose values will be read
|
|
|
+ * @value_array: array to store the read values
|
|
|
+ *
|
|
|
+ * Read the raw values of the GPIOs, i.e. the values of the physical lines
|
|
|
+ * without regard for their ACTIVE_LOW status. Return 0 in case of success,
|
|
|
+ * else an error code.
|
|
|
+ *
|
|
|
+ * This function should be called from contexts where we cannot sleep,
|
|
|
+ * and it will complain if the GPIO chip functions potentially sleep.
|
|
|
+ */
|
|
|
+int gpiod_get_raw_array_value(unsigned int array_size,
|
|
|
+ struct gpio_desc **desc_array, int *value_array)
|
|
|
+{
|
|
|
+ if (!desc_array)
|
|
|
+ return -EINVAL;
|
|
|
+ return gpiod_get_array_value_complex(true, false, array_size,
|
|
|
+ desc_array, value_array);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(gpiod_get_raw_array_value);
|
|
|
+
|
|
|
+/**
|
|
|
+ * gpiod_get_array_value() - read values from an array of GPIOs
|
|
|
+ * @array_size: number of elements in the descriptor / value arrays
|
|
|
+ * @desc_array: array of GPIO descriptors whose values will be read
|
|
|
+ * @value_array: array to store the read values
|
|
|
+ *
|
|
|
+ * Read the logical values of the GPIOs, i.e. taking their ACTIVE_LOW status
|
|
|
+ * into account. Return 0 in case of success, else an error code.
|
|
|
+ *
|
|
|
+ * This function should be called from contexts where we cannot sleep,
|
|
|
+ * and it will complain if the GPIO chip functions potentially sleep.
|
|
|
+ */
|
|
|
+int gpiod_get_array_value(unsigned int array_size,
|
|
|
+ struct gpio_desc **desc_array, int *value_array)
|
|
|
+{
|
|
|
+ if (!desc_array)
|
|
|
+ return -EINVAL;
|
|
|
+ return gpiod_get_array_value_complex(false, false, array_size,
|
|
|
+ desc_array, value_array);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(gpiod_get_array_value);
|
|
|
+
|
|
|
/*
|
|
|
* gpio_set_open_drain_value_commit() - Set the open drain gpio's value.
|
|
|
* @desc: gpio descriptor whose state need to be set.
|
|
@@ -2942,6 +3052,53 @@ int gpiod_get_value_cansleep(const struct gpio_desc *desc)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(gpiod_get_value_cansleep);
|
|
|
|
|
|
+/**
|
|
|
+ * gpiod_get_raw_array_value_cansleep() - read raw values from an array of GPIOs
|
|
|
+ * @array_size: number of elements in the descriptor / value arrays
|
|
|
+ * @desc_array: array of GPIO descriptors whose values will be read
|
|
|
+ * @value_array: array to store the read values
|
|
|
+ *
|
|
|
+ * Read the raw values of the GPIOs, i.e. the values of the physical lines
|
|
|
+ * without regard for their ACTIVE_LOW status. Return 0 in case of success,
|
|
|
+ * else an error code.
|
|
|
+ *
|
|
|
+ * This function is to be called from contexts that can sleep.
|
|
|
+ */
|
|
|
+int gpiod_get_raw_array_value_cansleep(unsigned int array_size,
|
|
|
+ struct gpio_desc **desc_array,
|
|
|
+ int *value_array)
|
|
|
+{
|
|
|
+ might_sleep_if(extra_checks);
|
|
|
+ if (!desc_array)
|
|
|
+ return -EINVAL;
|
|
|
+ return gpiod_get_array_value_complex(true, true, array_size,
|
|
|
+ desc_array, value_array);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(gpiod_get_raw_array_value_cansleep);
|
|
|
+
|
|
|
+/**
|
|
|
+ * gpiod_get_array_value_cansleep() - read values from an array of GPIOs
|
|
|
+ * @array_size: number of elements in the descriptor / value arrays
|
|
|
+ * @desc_array: array of GPIO descriptors whose values will be read
|
|
|
+ * @value_array: array to store the read values
|
|
|
+ *
|
|
|
+ * Read the logical values of the GPIOs, i.e. taking their ACTIVE_LOW status
|
|
|
+ * into account. Return 0 in case of success, else an error code.
|
|
|
+ *
|
|
|
+ * This function is to be called from contexts that can sleep.
|
|
|
+ */
|
|
|
+int gpiod_get_array_value_cansleep(unsigned int array_size,
|
|
|
+ struct gpio_desc **desc_array,
|
|
|
+ int *value_array)
|
|
|
+{
|
|
|
+ might_sleep_if(extra_checks);
|
|
|
+ if (!desc_array)
|
|
|
+ return -EINVAL;
|
|
|
+ return gpiod_get_array_value_complex(false, true, array_size,
|
|
|
+ desc_array, value_array);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(gpiod_get_array_value_cansleep);
|
|
|
+
|
|
|
/**
|
|
|
* gpiod_set_raw_value_cansleep() - assign a gpio's raw value
|
|
|
* @desc: gpio whose value will be assigned
|