Commit a2ab1703 authored by Linus Walleij's avatar Linus Walleij

Merge branch 'ib-array-bitmaps' into devel

parents c02980d6 b17566a6
...@@ -193,3 +193,18 @@ And the table can be added to the board code as follows:: ...@@ -193,3 +193,18 @@ And the table can be added to the board code as follows::
The line will be hogged as soon as the gpiochip is created or - in case the The line will be hogged as soon as the gpiochip is created or - in case the
chip was created earlier - when the hog table is registered. chip was created earlier - when the hog table is registered.
Arrays of pins
--------------
In addition to requesting pins belonging to a function one by one, a device may
also request an array of pins assigned to the function. The way those pins are
mapped to the device determines if the array qualifies for fast bitmap
processing. If yes, a bitmap is passed over get/set array functions directly
between a caller and a respective .get/set_multiple() callback of a GPIO chip.
In order to qualify for fast bitmap processing, the pin mapping must meet the
following requirements:
- it must belong to the same chip as other 'fast' pins of the function,
- its index within the function must match its hardware number within the chip.
Open drain and open source pins are excluded from fast bitmap output processing.
...@@ -109,9 +109,11 @@ For a function using multiple GPIOs all of those can be obtained with one call:: ...@@ -109,9 +109,11 @@ For a function using multiple GPIOs all of those can be obtained with one call::
enum gpiod_flags flags) enum gpiod_flags flags)
This function returns a struct gpio_descs which contains an array of This function returns a struct gpio_descs which contains an array of
descriptors:: descriptors. It also contains a pointer to a gpiolib private structure which,
if passed back to get/set array functions, may speed up I/O proocessing::
struct gpio_descs { struct gpio_descs {
struct gpio_array *info;
unsigned int ndescs; unsigned int ndescs;
struct gpio_desc *desc[]; struct gpio_desc *desc[];
} }
...@@ -323,29 +325,37 @@ The following functions get or set the values of an array of GPIOs:: ...@@ -323,29 +325,37 @@ The following functions get or set the values of an array of GPIOs::
int gpiod_get_array_value(unsigned int array_size, int gpiod_get_array_value(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array); struct gpio_array *array_info,
unsigned long *value_bitmap);
int gpiod_get_raw_array_value(unsigned int array_size, int gpiod_get_raw_array_value(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array); struct gpio_array *array_info,
unsigned long *value_bitmap);
int gpiod_get_array_value_cansleep(unsigned int array_size, int gpiod_get_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array); struct gpio_array *array_info,
unsigned long *value_bitmap);
int gpiod_get_raw_array_value_cansleep(unsigned int array_size, int gpiod_get_raw_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array); struct gpio_array *array_info,
unsigned long *value_bitmap);
void gpiod_set_array_value(unsigned int array_size, void gpiod_set_array_value(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array) struct gpio_array *array_info,
unsigned long *value_bitmap)
void gpiod_set_raw_array_value(unsigned int array_size, void gpiod_set_raw_array_value(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array) struct gpio_array *array_info,
unsigned long *value_bitmap)
void gpiod_set_array_value_cansleep(unsigned int array_size, void gpiod_set_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array) struct gpio_array *array_info,
unsigned long *value_bitmap)
void gpiod_set_raw_array_value_cansleep(unsigned int array_size, void gpiod_set_raw_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array) struct gpio_array *array_info,
unsigned long *value_bitmap)
The array can be an arbitrary set of GPIOs. The functions will try to access The array can be an arbitrary set of GPIOs. The functions will try to access
GPIOs belonging to the same bank or chip simultaneously if supported by the GPIOs belonging to the same bank or chip simultaneously if supported by the
...@@ -356,8 +366,9 @@ accessed sequentially. ...@@ -356,8 +366,9 @@ accessed sequentially.
The functions take three arguments: The functions take three arguments:
* array_size - the number of array elements * array_size - the number of array elements
* desc_array - an array of GPIO descriptors * desc_array - an array of GPIO descriptors
* value_array - an array to store the GPIOs' values (get) or * array_info - optional information obtained from gpiod_array_get()
an array of values to assign to the GPIOs (set) * value_bitmap - a bitmap to store the GPIOs' values (get) or
a bitmap of values to assign to the GPIOs (set)
The descriptor array can be obtained using the gpiod_get_array() function The descriptor array can be obtained using the gpiod_get_array() function
or one of its variants. If the group of descriptors returned by that function or one of its variants. If the group of descriptors returned by that function
...@@ -366,16 +377,25 @@ the struct gpio_descs returned by gpiod_get_array():: ...@@ -366,16 +377,25 @@ the struct gpio_descs returned by gpiod_get_array()::
struct gpio_descs *my_gpio_descs = gpiod_get_array(...); struct gpio_descs *my_gpio_descs = gpiod_get_array(...);
gpiod_set_array_value(my_gpio_descs->ndescs, my_gpio_descs->desc, gpiod_set_array_value(my_gpio_descs->ndescs, my_gpio_descs->desc,
my_gpio_values); my_gpio_descs->info, my_gpio_value_bitmap);
It is also possible to access a completely arbitrary array of descriptors. The It is also possible to access a completely arbitrary array of descriptors. The
descriptors may be obtained using any combination of gpiod_get() and descriptors may be obtained using any combination of gpiod_get() and
gpiod_get_array(). Afterwards the array of descriptors has to be setup gpiod_get_array(). Afterwards the array of descriptors has to be setup
manually before it can be passed to one of the above functions. manually before it can be passed to one of the above functions. In that case,
array_info should be set to NULL.
Note that for optimal performance GPIOs belonging to the same chip should be Note that for optimal performance GPIOs belonging to the same chip should be
contiguous within the array of descriptors. contiguous within the array of descriptors.
Still better performance may be achieved if array indexes of the descriptors
match hardware pin numbers of a single chip. If an array passed to a get/set
array function matches the one obtained from gpiod_get_array() and array_info
associated with the array is also passed, the function may take a fast bitmap
processing path, passing the value_bitmap argument directly to the respective
.get/set_multiple() callback of the chip. That allows for utilization of GPIO
banks as data I/O ports without much loss of performance.
The return value of gpiod_get_array_value() and its variants is 0 on success The return value of gpiod_get_array_value() and its variants is 0 on success
or negative on error. Note the difference to gpiod_get_value(), which returns or negative on error. Note the difference to gpiod_get_value(), which returns
0 or 1 on success to convey the GPIO value. With the array functions, the GPIO 0 or 1 on success to convey the GPIO value. With the array functions, the GPIO
......
...@@ -62,20 +62,15 @@ static void hd44780_strobe_gpio(struct hd44780 *hd) ...@@ -62,20 +62,15 @@ static void hd44780_strobe_gpio(struct hd44780 *hd)
/* write to an LCD panel register in 8 bit GPIO mode */ /* write to an LCD panel register in 8 bit GPIO mode */
static void hd44780_write_gpio8(struct hd44780 *hd, u8 val, unsigned int rs) static void hd44780_write_gpio8(struct hd44780 *hd, u8 val, unsigned int rs)
{ {
int values[10]; /* for DATA[0-7], RS, RW */ DECLARE_BITMAP(values, 10); /* for DATA[0-7], RS, RW */
unsigned int i, n; unsigned int n;
for (i = 0; i < 8; i++) values[0] = val;
values[PIN_DATA0 + i] = !!(val & BIT(i)); __assign_bit(8, values, rs);
values[PIN_CTRL_RS] = rs; n = hd->pins[PIN_CTRL_RW] ? 10 : 9;
n = 9;
if (hd->pins[PIN_CTRL_RW]) {
values[PIN_CTRL_RW] = 0;
n++;
}
/* Present the data to the port */ /* Present the data to the port */
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA0], values); gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA0], NULL, values);
hd44780_strobe_gpio(hd); hd44780_strobe_gpio(hd);
} }
...@@ -83,32 +78,25 @@ static void hd44780_write_gpio8(struct hd44780 *hd, u8 val, unsigned int rs) ...@@ -83,32 +78,25 @@ static void hd44780_write_gpio8(struct hd44780 *hd, u8 val, unsigned int rs)
/* write to an LCD panel register in 4 bit GPIO mode */ /* write to an LCD panel register in 4 bit GPIO mode */
static void hd44780_write_gpio4(struct hd44780 *hd, u8 val, unsigned int rs) static void hd44780_write_gpio4(struct hd44780 *hd, u8 val, unsigned int rs)
{ {
int values[10]; /* for DATA[0-7], RS, RW, but DATA[0-3] is unused */ DECLARE_BITMAP(values, 6); /* for DATA[4-7], RS, RW */
unsigned int i, n; unsigned int n;
/* High nibble + RS, RW */ /* High nibble + RS, RW */
for (i = 4; i < 8; i++) values[0] = val >> 4;
values[PIN_DATA0 + i] = !!(val & BIT(i)); __assign_bit(4, values, rs);
values[PIN_CTRL_RS] = rs; n = hd->pins[PIN_CTRL_RW] ? 6 : 5;
n = 5;
if (hd->pins[PIN_CTRL_RW]) {
values[PIN_CTRL_RW] = 0;
n++;
}
/* Present the data to the port */ /* Present the data to the port */
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], NULL, values);
&values[PIN_DATA4]);
hd44780_strobe_gpio(hd); hd44780_strobe_gpio(hd);
/* Low nibble */ /* Low nibble */
for (i = 0; i < 4; i++) values[0] &= ~0x0fUL;
values[PIN_DATA4 + i] = !!(val & BIT(i)); values[0] |= val & 0x0f;
/* Present the data to the port */ /* Present the data to the port */
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], NULL, values);
&values[PIN_DATA4]);
hd44780_strobe_gpio(hd); hd44780_strobe_gpio(hd);
} }
...@@ -155,23 +143,16 @@ static void hd44780_write_cmd_gpio4(struct charlcd *lcd, int cmd) ...@@ -155,23 +143,16 @@ static void hd44780_write_cmd_gpio4(struct charlcd *lcd, int cmd)
/* Send 4-bits of a command to the LCD panel in raw 4 bit GPIO mode */ /* Send 4-bits of a command to the LCD panel in raw 4 bit GPIO mode */
static void hd44780_write_cmd_raw_gpio4(struct charlcd *lcd, int cmd) static void hd44780_write_cmd_raw_gpio4(struct charlcd *lcd, int cmd)
{ {
int values[10]; /* for DATA[0-7], RS, RW, but DATA[0-3] is unused */ DECLARE_BITMAP(values, 6); /* for DATA[4-7], RS, RW */
struct hd44780 *hd = lcd->drvdata; struct hd44780 *hd = lcd->drvdata;
unsigned int i, n; unsigned int n;
/* Command nibble + RS, RW */ /* Command nibble + RS, RW */
for (i = 0; i < 4; i++) values[0] = cmd & 0x0f;
values[PIN_DATA4 + i] = !!(cmd & BIT(i)); n = hd->pins[PIN_CTRL_RW] ? 6 : 5;
values[PIN_CTRL_RS] = 0;
n = 5;
if (hd->pins[PIN_CTRL_RW]) {
values[PIN_CTRL_RW] = 0;
n++;
}
/* Present the data to the port */ /* Present the data to the port */
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], NULL, values);
&values[PIN_DATA4]);
hd44780_strobe_gpio(hd); hd44780_strobe_gpio(hd);
} }
......
...@@ -110,13 +110,12 @@ static void ts_nbus_set_direction(struct ts_nbus *ts_nbus, int direction) ...@@ -110,13 +110,12 @@ static void ts_nbus_set_direction(struct ts_nbus *ts_nbus, int direction)
*/ */
static void ts_nbus_reset_bus(struct ts_nbus *ts_nbus) static void ts_nbus_reset_bus(struct ts_nbus *ts_nbus)
{ {
int i; DECLARE_BITMAP(values, 8);
int values[8];
for (i = 0; i < 8; i++) values[0] = 0;
values[i] = 0;
gpiod_set_array_value_cansleep(8, ts_nbus->data->desc, values); gpiod_set_array_value_cansleep(8, ts_nbus->data->desc,
ts_nbus->data->info, values);
gpiod_set_value_cansleep(ts_nbus->csn, 0); gpiod_set_value_cansleep(ts_nbus->csn, 0);
gpiod_set_value_cansleep(ts_nbus->strobe, 0); gpiod_set_value_cansleep(ts_nbus->strobe, 0);
gpiod_set_value_cansleep(ts_nbus->ale, 0); gpiod_set_value_cansleep(ts_nbus->ale, 0);
...@@ -157,16 +156,11 @@ static int ts_nbus_read_byte(struct ts_nbus *ts_nbus, u8 *val) ...@@ -157,16 +156,11 @@ static int ts_nbus_read_byte(struct ts_nbus *ts_nbus, u8 *val)
static void ts_nbus_write_byte(struct ts_nbus *ts_nbus, u8 byte) static void ts_nbus_write_byte(struct ts_nbus *ts_nbus, u8 byte)
{ {
struct gpio_descs *gpios = ts_nbus->data; struct gpio_descs *gpios = ts_nbus->data;
int i; DECLARE_BITMAP(values, 8);
int values[8];
for (i = 0; i < 8; i++) values[0] = byte;
if (byte & BIT(i))
values[i] = 1;
else
values[i] = 0;
gpiod_set_array_value_cansleep(8, gpios->desc, values); gpiod_set_array_value_cansleep(8, gpios->desc, gpios->info, values);
} }
/* /*
......
...@@ -313,18 +313,21 @@ static int max3191x_set_config(struct gpio_chip *gpio, unsigned int offset, ...@@ -313,18 +313,21 @@ static int max3191x_set_config(struct gpio_chip *gpio, unsigned int offset,
static void gpiod_set_array_single_value_cansleep(unsigned int ndescs, static void gpiod_set_array_single_value_cansleep(unsigned int ndescs,
struct gpio_desc **desc, struct gpio_desc **desc,
struct gpio_array *info,
int value) int value)
{ {
int i, *values; unsigned long *values;
values = kmalloc_array(ndescs, sizeof(*values), GFP_KERNEL); values = bitmap_alloc(ndescs, GFP_KERNEL);
if (!values) if (!values)
return; return;
for (i = 0; i < ndescs; i++) if (value)
values[i] = value; bitmap_fill(values, ndescs);
else
bitmap_zero(values, ndescs);
gpiod_set_array_value_cansleep(ndescs, desc, values); gpiod_set_array_value_cansleep(ndescs, desc, info, values);
kfree(values); kfree(values);
} }
...@@ -397,7 +400,8 @@ static int max3191x_probe(struct spi_device *spi) ...@@ -397,7 +400,8 @@ static int max3191x_probe(struct spi_device *spi)
if (max3191x->modesel_pins) if (max3191x->modesel_pins)
gpiod_set_array_single_value_cansleep( gpiod_set_array_single_value_cansleep(
max3191x->modesel_pins->ndescs, max3191x->modesel_pins->ndescs,
max3191x->modesel_pins->desc, max3191x->mode); max3191x->modesel_pins->desc,
max3191x->modesel_pins->info, max3191x->mode);
max3191x->ignore_uv = device_property_read_bool(dev, max3191x->ignore_uv = device_property_read_bool(dev,
"maxim,ignore-undervoltage"); "maxim,ignore-undervoltage");
......
This diff is collapsed.
...@@ -183,15 +183,26 @@ static inline bool acpi_can_fallback_to_crs(struct acpi_device *adev, ...@@ -183,15 +183,26 @@ static inline bool acpi_can_fallback_to_crs(struct acpi_device *adev,
} }
#endif #endif
struct gpio_array {
struct gpio_desc **desc;
unsigned int size;
struct gpio_chip *chip;
unsigned long *get_mask;
unsigned long *set_mask;
unsigned long invert_mask[];
};
struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip, u16 hwnum); struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip, u16 hwnum);
int gpiod_get_array_value_complex(bool raw, bool can_sleep, int gpiod_get_array_value_complex(bool raw, bool can_sleep,
unsigned int array_size, unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array); struct gpio_array *array_info,
unsigned long *value_bitmap);
int gpiod_set_array_value_complex(bool raw, bool can_sleep, int gpiod_set_array_value_complex(bool raw, bool can_sleep,
unsigned int array_size, unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array); struct gpio_array *array_info,
unsigned long *value_bitmap);
/* This is just passed between gpiolib and devres */ /* This is just passed between gpiolib and devres */
struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, struct gpio_desc *gpiod_get_from_of_node(struct device_node *node,
......
...@@ -22,18 +22,16 @@ struct gpiomux { ...@@ -22,18 +22,16 @@ struct gpiomux {
struct i2c_mux_gpio_platform_data data; struct i2c_mux_gpio_platform_data data;
unsigned gpio_base; unsigned gpio_base;
struct gpio_desc **gpios; struct gpio_desc **gpios;
int *values;
}; };
static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val) static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
{ {
int i; DECLARE_BITMAP(values, BITS_PER_TYPE(val));
for (i = 0; i < mux->data.n_gpios; i++) values[0] = val;
mux->values[i] = (val >> i) & 1;
gpiod_set_array_value_cansleep(mux->data.n_gpios, gpiod_set_array_value_cansleep(mux->data.n_gpios, mux->gpios, NULL,
mux->gpios, mux->values); values);
} }
static int i2c_mux_gpio_select(struct i2c_mux_core *muxc, u32 chan) static int i2c_mux_gpio_select(struct i2c_mux_core *muxc, u32 chan)
...@@ -182,15 +180,13 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev) ...@@ -182,15 +180,13 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
return -EPROBE_DEFER; return -EPROBE_DEFER;
muxc = i2c_mux_alloc(parent, &pdev->dev, mux->data.n_values, muxc = i2c_mux_alloc(parent, &pdev->dev, mux->data.n_values,
mux->data.n_gpios * sizeof(*mux->gpios) + mux->data.n_gpios * sizeof(*mux->gpios), 0,
mux->data.n_gpios * sizeof(*mux->values), 0,
i2c_mux_gpio_select, NULL); i2c_mux_gpio_select, NULL);
if (!muxc) { if (!muxc) {
ret = -ENOMEM; ret = -ENOMEM;
goto alloc_failed; goto alloc_failed;
} }
mux->gpios = muxc->priv; mux->gpios = muxc->priv;
mux->values = (int *)(mux->gpios + mux->data.n_gpios);
muxc->priv = mux; muxc->priv = mux;
platform_set_drvdata(pdev, muxc); platform_set_drvdata(pdev, muxc);
......
...@@ -40,18 +40,13 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq, ...@@ -40,18 +40,13 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,
struct gpio_descs *reset_gpios = pwrseq->reset_gpios; struct gpio_descs *reset_gpios = pwrseq->reset_gpios;
if (!IS_ERR(reset_gpios)) { if (!IS_ERR(reset_gpios)) {
int i, *values; DECLARE_BITMAP(values, BITS_PER_TYPE(value));
int nvalues = reset_gpios->ndescs; int nvalues = reset_gpios->ndescs;
values = kmalloc_array(nvalues, sizeof(int), GFP_KERNEL); values[0] = value;
if (!values)
return;
for (i = 0; i < nvalues; i++) gpiod_set_array_value_cansleep(nvalues, reset_gpios->desc,
values[i] = value; reset_gpios->info, values);
gpiod_set_array_value_cansleep(nvalues, reset_gpios->desc, values);
kfree(values);
} }
} }
......
...@@ -17,20 +17,18 @@ ...@@ -17,20 +17,18 @@
struct mux_gpio { struct mux_gpio {
struct gpio_descs *gpios; struct gpio_descs *gpios;
int *val;
}; };
static int mux_gpio_set(struct mux_control *mux, int state) static int mux_gpio_set(struct mux_control *mux, int state)
{ {
struct mux_gpio *mux_gpio = mux_chip_priv(mux->chip); struct mux_gpio *mux_gpio = mux_chip_priv(mux->chip);
int i; DECLARE_BITMAP(values, BITS_PER_TYPE(state));
for (i = 0; i < mux_gpio->gpios->ndescs; i++) values[0] = state;
mux_gpio->val[i] = (state >> i) & 1;
gpiod_set_array_value_cansleep(mux_gpio->gpios->ndescs, gpiod_set_array_value_cansleep(mux_gpio->gpios->ndescs,
mux_gpio->gpios->desc, mux_gpio->gpios->desc,
mux_gpio->val); mux_gpio->gpios->info, values);
return 0; return 0;
} }
...@@ -58,13 +56,11 @@ static int mux_gpio_probe(struct platform_device *pdev) ...@@ -58,13 +56,11 @@ static int mux_gpio_probe(struct platform_device *pdev)
if (pins < 0) if (pins < 0)
return pins; return pins;
mux_chip = devm_mux_chip_alloc(dev, 1, sizeof(*mux_gpio) + mux_chip = devm_mux_chip_alloc(dev, 1, sizeof(*mux_gpio));
pins * sizeof(*mux_gpio->val));
if (IS_ERR(mux_chip)) if (IS_ERR(mux_chip))
return PTR_ERR(mux_chip); return PTR_ERR(mux_chip);
mux_gpio = mux_chip_priv(mux_chip); mux_gpio = mux_chip_priv(mux_chip);
mux_gpio->val = (int *)(mux_gpio + 1);
mux_chip->ops = &mux_gpio_ops; mux_chip->ops = &mux_gpio_ops;
mux_gpio->gpios = devm_gpiod_get_array(dev, "mux", GPIOD_OUT_LOW); mux_gpio->gpios = devm_gpiod_get_array(dev, "mux", GPIOD_OUT_LOW);
......
...@@ -20,23 +20,21 @@ ...@@ -20,23 +20,21 @@
struct mdio_mux_gpio_state { struct mdio_mux_gpio_state {
struct gpio_descs *gpios; struct gpio_descs *gpios;
void *mux_handle; void *mux_handle;
int values[];
}; };
static int mdio_mux_gpio_switch_fn(int current_child, int desired_child, static int mdio_mux_gpio_switch_fn(int current_child, int desired_child,
void *data) void *data)
{ {
struct mdio_mux_gpio_state *s = data; struct mdio_mux_gpio_state *s = data;
unsigned int n; DECLARE_BITMAP(values, BITS_PER_TYPE(desired_child));
if (current_child == desired_child) if (current_child == desired_child)
return 0; return 0;
for (n = 0; n < s->gpios->ndescs; n++) values[0] = desired_child;
s->values[n] = (desired_child >> n) & 1;
gpiod_set_array_value_cansleep(s->gpios->ndescs, s->gpios->desc, gpiod_set_array_value_cansleep(s->gpios->ndescs, s->gpios->desc,
s->values); s->gpios->info, values);
return 0; return 0;
} }
...@@ -51,8 +49,7 @@ static int mdio_mux_gpio_probe(struct platform_device *pdev) ...@@ -51,8 +49,7 @@ static int mdio_mux_gpio_probe(struct platform_device *pdev)
if (IS_ERR(gpios)) if (IS_ERR(gpios))
return PTR_ERR(gpios); return PTR_ERR(gpios);
s = devm_kzalloc(&pdev->dev, struct_size(s, values, gpios->ndescs), s = devm_kzalloc(&pdev->dev, sizeof(*s), GFP_KERNEL);
GFP_KERNEL);
if (!s) { if (!s) {
gpiod_put_array(gpios); gpiod_put_array(gpios);
return -ENOMEM; return -ENOMEM;
......
...@@ -351,19 +351,20 @@ static int soc_common_pcmcia_config_skt( ...@@ -351,19 +351,20 @@ static int soc_common_pcmcia_config_skt(
if (ret == 0) { if (ret == 0) {
struct gpio_desc *descs[2]; struct gpio_desc *descs[2];
int values[2], n = 0; DECLARE_BITMAP(values, 2);
int n = 0;
if (skt->gpio_reset) { if (skt->gpio_reset) {
descs[n] = skt->gpio_reset; descs[n] = skt->gpio_reset;
values[n++] = !!(state->flags & SS_RESET); __assign_bit(n++, values, state->flags & SS_RESET);
} }
if (skt->gpio_bus_enable) { if (skt->gpio_bus_enable) {
descs[n] = skt->gpio_bus_enable; descs[n] = skt->gpio_bus_enable;
values[n++] = !!(state->flags & SS_OUTPUT_ENA); __assign_bit(n++, values, state->flags & SS_OUTPUT_ENA);
} }
if (n) if (n)
gpiod_set_array_value_cansleep(n, descs, values); gpiod_set_array_value_cansleep(n, descs, NULL, values);
/* /*
* This really needs a better solution. The IRQ * This really needs a better solution. The IRQ
......
...@@ -157,15 +157,13 @@ static const struct phy_ops gpio_usb_ops = { ...@@ -157,15 +157,13 @@ static const struct phy_ops gpio_usb_ops = {
*/ */
static void phy_mdm6600_cmd(struct phy_mdm6600 *ddata, int val) static void phy_mdm6600_cmd(struct phy_mdm6600 *ddata, int val)
{ {
int values[PHY_MDM6600_NR_CMD_LINES]; DECLARE_BITMAP(values, PHY_MDM6600_NR_CMD_LINES);
int i;
val &= (1 << PHY_MDM6600_NR_CMD_LINES) - 1; values[0] = val;
for (i = 0; i < PHY_MDM6600_NR_CMD_LINES; i++)
values[i] = (val & BIT(i)) >> i;
gpiod_set_array_value_cansleep(PHY_MDM6600_NR_CMD_LINES, gpiod_set_array_value_cansleep(PHY_MDM6600_NR_CMD_LINES,
ddata->cmd_gpios->desc, values); ddata->cmd_gpios->desc,
ddata->cmd_gpios->info, values);
} }
/** /**
...@@ -176,7 +174,7 @@ static void phy_mdm6600_status(struct work_struct *work) ...@@ -176,7 +174,7 @@ static void phy_mdm6600_status(struct work_struct *work)
{ {
struct phy_mdm6600 *ddata; struct phy_mdm6600 *ddata;
struct device *dev; struct device *dev;
int values[PHY_MDM6600_NR_STATUS_LINES]; DECLARE_BITMAP(values, PHY_MDM6600_NR_STATUS_LINES);
int error, i, val = 0; int error, i, val = 0;
ddata = container_of(work, struct phy_mdm6600, status_work.work); ddata = container_of(work, struct phy_mdm6600, status_work.work);
...@@ -184,16 +182,17 @@ static void phy_mdm6600_status(struct work_struct *work) ...@@ -184,16 +182,17 @@ static void phy_mdm6600_status(struct work_struct *work)
error = gpiod_get_array_value_cansleep(PHY_MDM6600_NR_STATUS_LINES, error = gpiod_get_array_value_cansleep(PHY_MDM6600_NR_STATUS_LINES,
ddata->status_gpios->desc, ddata->status_gpios->desc,
ddata->status_gpios->info,
values); values);
if (error) if (error)
return; return;
for (i = 0; i < PHY_MDM6600_NR_STATUS_LINES; i++) { for (i = 0; i < PHY_MDM6600_NR_STATUS_LINES; i++) {
val |= values[i] << i; val |= test_bit(i, values) << i;
dev_dbg(ddata->dev, "XXX %s: i: %i values[i]: %i val: %i\n", dev_dbg(ddata->dev, "XXX %s: i: %i values[i]: %i val: %i\n",
__func__, i, values[i], val); __func__, i, test_bit(i, values), val);
} }
ddata->status = val; ddata->status = values[0];
dev_info(dev, "modem status: %i %s\n", dev_info(dev, "modem status: %i %s\n",
ddata->status, ddata->status,
......
...@@ -202,7 +202,7 @@ static int ad7606_write_raw(struct iio_dev *indio_dev, ...@@ -202,7 +202,7 @@ static int ad7606_write_raw(struct iio_dev *indio_dev,
long mask) long mask)
{ {
struct ad7606_state *st = iio_priv(indio_dev); struct ad7606_state *st = iio_priv(indio_dev);
int values[3]; DECLARE_BITMAP(values, 3);
int ret, i; int ret, i;
switch (mask) { switch (mask) {
...@@ -227,12 +227,10 @@ static int ad7606_write_raw(struct iio_dev *indio_dev, ...@@ -227,12 +227,10 @@ static int ad7606_write_raw(struct iio_dev *indio_dev,
if (ret < 0) if (ret < 0)
return ret; return ret;
values[0] = (ret >> 0) & 1; values[0] = ret;
values[1] = (ret >> 1) & 1;
values[2] = (ret >> 2) & 1;
mutex_lock(&st->lock); mutex_lock(&st->lock);
gpiod_set_array_value(ARRAY_SIZE(values), st->gpio_os->desc, gpiod_set_array_value(3, st->gpio_os->desc, st->gpio_os->info,
values); values);
st->oversampling = val; st->oversampling = val;
mutex_unlock(&st->lock); mutex_unlock(&st->lock);
......
...@@ -40,7 +40,7 @@ void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl) ...@@ -40,7 +40,7 @@ void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl)
{ {
enum mctrl_gpio_idx i; enum mctrl_gpio_idx i;
struct gpio_desc *desc_array[UART_GPIO_MAX]; struct gpio_desc *desc_array[UART_GPIO_MAX];
int value_array[UART_GPIO_MAX]; DECLARE_BITMAP(values, UART_GPIO_MAX);
unsigned int count = 0; unsigned int count = 0;
if (gpios == NULL) if (gpios == NULL)
...@@ -49,10 +49,11 @@ void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl) ...@@ -49,10 +49,11 @@ void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl)
for (i = 0; i < UART_GPIO_MAX; i++) for (i = 0; i < UART_GPIO_MAX; i++)
if (gpios->gpio[i] && mctrl_gpios_desc[i].dir_out) { if (gpios->gpio[i] && mctrl_gpios_desc[i].dir_out) {
desc_array[count] = gpios->gpio[i]; desc_array[count] = gpios->gpio[i];
value_array[count] = !!(mctrl & mctrl_gpios_desc[i].mctrl); __assign_bit(count, values,
mctrl & mctrl_gpios_desc[i].mctrl);
count++; count++;
} }
gpiod_set_array_value(count, desc_array, value_array); gpiod_set_array_value(count, desc_array, NULL, values);
} }
EXPORT_SYMBOL_GPL(mctrl_gpio_set); EXPORT_SYMBOL_GPL(mctrl_gpio_set);
......
...@@ -17,11 +17,20 @@ struct device; ...@@ -17,11 +17,20 @@ struct device;
*/ */
struct gpio_desc; struct gpio_desc;
/**
* Opaque descriptor for a structure of GPIO array attributes. This structure
* is attached to struct gpiod_descs obtained from gpiod_get_array() and can be
* passed back to get/set array functions in order to activate fast processing
* path if applicable.
*/
struct gpio_array;
/** /**
* Struct containing an array of descriptors that can be obtained using * Struct containing an array of descriptors that can be obtained using
* gpiod_get_array(). * gpiod_get_array().
*/ */
struct gpio_descs { struct gpio_descs {
struct gpio_array *info;
unsigned int ndescs; unsigned int ndescs;
struct gpio_desc *desc[]; struct gpio_desc *desc[];
}; };
...@@ -104,36 +113,46 @@ int gpiod_direction_output_raw(struct gpio_desc *desc, int value); ...@@ -104,36 +113,46 @@ int gpiod_direction_output_raw(struct gpio_desc *desc, int value);
/* Value get/set from non-sleeping context */ /* Value get/set from non-sleeping context */
int gpiod_get_value(const struct gpio_desc *desc); int gpiod_get_value(const struct gpio_desc *desc);
int gpiod_get_array_value(unsigned int array_size, int gpiod_get_array_value(unsigned int array_size,
struct gpio_desc **desc_array, int *value_array); struct gpio_desc **desc_array,
struct gpio_array *array_info,
unsigned long *value_bitmap);
void gpiod_set_value(struct gpio_desc *desc, int value); void gpiod_set_value(struct gpio_desc *desc, int value);
void gpiod_set_array_value(unsigned int array_size, void gpiod_set_array_value(unsigned int array_size,
struct gpio_desc **desc_array, int *value_array); struct gpio_desc **desc_array,
struct gpio_array *array_info,
unsigned long *value_bitmap);
int gpiod_get_raw_value(const struct gpio_desc *desc); int gpiod_get_raw_value(const struct gpio_desc *desc);
int gpiod_get_raw_array_value(unsigned int array_size, int gpiod_get_raw_array_value(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array); struct gpio_array *array_info,
unsigned long *value_bitmap);
void gpiod_set_raw_value(struct gpio_desc *desc, int value); void gpiod_set_raw_value(struct gpio_desc *desc, int value);
int gpiod_set_raw_array_value(unsigned int array_size, int gpiod_set_raw_array_value(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array); struct gpio_array *array_info,
unsigned long *value_bitmap);
/* Value get/set from sleeping context */ /* Value get/set from sleeping context */
int gpiod_get_value_cansleep(const struct gpio_desc *desc); int gpiod_get_value_cansleep(const struct gpio_desc *desc);
int gpiod_get_array_value_cansleep(unsigned int array_size, int gpiod_get_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array); struct gpio_array *array_info,
unsigned long *value_bitmap);
void gpiod_set_value_cansleep(struct gpio_desc *desc, int value); void gpiod_set_value_cansleep(struct gpio_desc *desc, int value);
void gpiod_set_array_value_cansleep(unsigned int array_size, void gpiod_set_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array); struct gpio_array *array_info,
unsigned long *value_bitmap);
int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc); int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc);
int gpiod_get_raw_array_value_cansleep(unsigned int array_size, int gpiod_get_raw_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array); struct gpio_array *array_info,
unsigned long *value_bitmap);
void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value); void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value);
int gpiod_set_raw_array_value_cansleep(unsigned int array_size, int gpiod_set_raw_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array); struct gpio_array *array_info,
unsigned long *value_bitmap);
int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce); int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce);
int gpiod_set_transitory(struct gpio_desc *desc, bool transitory); int gpiod_set_transitory(struct gpio_desc *desc, bool transitory);
...@@ -330,7 +349,8 @@ static inline int gpiod_get_value(const struct gpio_desc *desc) ...@@ -330,7 +349,8 @@ static inline int gpiod_get_value(const struct gpio_desc *desc)
} }
static inline int gpiod_get_array_value(unsigned int array_size, static inline int gpiod_get_array_value(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array) struct gpio_array *array_info,
unsigned long *value_bitmap)
{ {
/* GPIO can never have been requested */ /* GPIO can never have been requested */
WARN_ON(1); WARN_ON(1);
...@@ -343,7 +363,8 @@ static inline void gpiod_set_value(struct gpio_desc *desc, int value) ...@@ -343,7 +363,8 @@ static inline void gpiod_set_value(struct gpio_desc *desc, int value)
} }
static inline void gpiod_set_array_value(unsigned int array_size, static inline void gpiod_set_array_value(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array) struct gpio_array *array_info,
unsigned long *value_bitmap)
{ {
/* GPIO can never have been requested */ /* GPIO can never have been requested */
WARN_ON(1); WARN_ON(1);
...@@ -356,7 +377,8 @@ static inline int gpiod_get_raw_value(const struct gpio_desc *desc) ...@@ -356,7 +377,8 @@ static inline int gpiod_get_raw_value(const struct gpio_desc *desc)
} }
static inline int gpiod_get_raw_array_value(unsigned int array_size, static inline int gpiod_get_raw_array_value(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array) struct gpio_array *array_info,
unsigned long *value_bitmap)
{ {
/* GPIO can never have been requested */ /* GPIO can never have been requested */
WARN_ON(1); WARN_ON(1);
...@@ -369,7 +391,8 @@ static inline void gpiod_set_raw_value(struct gpio_desc *desc, int value) ...@@ -369,7 +391,8 @@ static inline void gpiod_set_raw_value(struct gpio_desc *desc, int value)
} }
static inline int gpiod_set_raw_array_value(unsigned int array_size, static inline int gpiod_set_raw_array_value(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array) struct gpio_array *array_info,
unsigned long *value_bitmap)
{ {
/* GPIO can never have been requested */ /* GPIO can never have been requested */
WARN_ON(1); WARN_ON(1);
...@@ -384,7 +407,8 @@ static inline int gpiod_get_value_cansleep(const struct gpio_desc *desc) ...@@ -384,7 +407,8 @@ static inline int gpiod_get_value_cansleep(const struct gpio_desc *desc)
} }
static inline int gpiod_get_array_value_cansleep(unsigned int array_size, static inline int gpiod_get_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array) struct gpio_array *array_info,
unsigned long *value_bitmap)
{ {
/* GPIO can never have been requested */ /* GPIO can never have been requested */
WARN_ON(1); WARN_ON(1);
...@@ -397,7 +421,8 @@ static inline void gpiod_set_value_cansleep(struct gpio_desc *desc, int value) ...@@ -397,7 +421,8 @@ static inline void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
} }
static inline void gpiod_set_array_value_cansleep(unsigned int array_size, static inline void gpiod_set_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array) struct gpio_array *array_info,
unsigned long *value_bitmap)
{ {
/* GPIO can never have been requested */ /* GPIO can never have been requested */
WARN_ON(1); WARN_ON(1);
...@@ -410,7 +435,8 @@ static inline int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc) ...@@ -410,7 +435,8 @@ static inline int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc)
} }
static inline int gpiod_get_raw_array_value_cansleep(unsigned int array_size, static inline int gpiod_get_raw_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array) struct gpio_array *array_info,
unsigned long *value_bitmap)
{ {
/* GPIO can never have been requested */ /* GPIO can never have been requested */
WARN_ON(1); WARN_ON(1);
...@@ -424,7 +450,8 @@ static inline void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, ...@@ -424,7 +450,8 @@ static inline void gpiod_set_raw_value_cansleep(struct gpio_desc *desc,
} }
static inline int gpiod_set_raw_array_value_cansleep(unsigned int array_size, static inline int gpiod_set_raw_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array, struct gpio_desc **desc_array,
int *value_array) struct gpio_array *array_info,
unsigned long *value_bitmap)
{ {
/* GPIO can never have been requested */ /* GPIO can never have been requested */
WARN_ON(1); WARN_ON(1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment