Skip to content

Commit

Permalink
gpiolib: Pass bitmaps, not integer arrays, to get/set array
Browse files Browse the repository at this point in the history
Most users of get/set array functions iterate consecutive bits of data,
usually a single integer, while processing array of results obtained
from, or building an array of values to be passed to those functions.
Save time wasted on those iterations by changing the functions' API to
accept bitmaps.

All current users are updated as well.

More benefits from the change are expected as soon as planned support
for accepting/passing those bitmaps directly from/to respective GPIO
chip callbacks if applicable is implemented.

Cc: Jonathan Corbet <[email protected]>
Cc: Miguel Ojeda Sandonis <[email protected]>
Cc: Sebastien Bourdelin <[email protected]>
Cc: Lukas Wunner <[email protected]>
Cc: Peter Korsgaard <[email protected]>
Cc: Peter Rosin <[email protected]>
Cc: Andrew Lunn <[email protected]>
Cc: Florian Fainelli <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Rojhalat Ibrahim <[email protected]>
Cc: Dominik Brodowski <[email protected]>
Cc: Russell King <[email protected]>
Cc: Kishon Vijay Abraham I <[email protected]>
Cc: Tony Lindgren <[email protected]>
Cc: Lars-Peter Clausen <[email protected]>
Cc: Michael Hennerich <[email protected]>
Cc: Jonathan Cameron <[email protected]>
Cc: Hartmut Knaack <[email protected]>
Cc: Peter Meerwald-Stadler <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Jiri Slaby <[email protected]>
Cc: Yegor Yefremov <[email protected]>
Cc: Uwe Kleine-König <[email protected]>
Signed-off-by: Janusz Krzysztofik <[email protected]>
Acked-by: Ulf Hansson <[email protected]>
Reviewed-by: Geert Uytterhoeven <[email protected]>
Tested-by: Geert Uytterhoeven <[email protected]>
Signed-off-by: Linus Walleij <[email protected]>
  • Loading branch information
jkrzyszt authored and linusw committed Sep 13, 2018
1 parent 5b394b2 commit b9762be
Show file tree
Hide file tree
Showing 15 changed files with 137 additions and 177 deletions.
22 changes: 11 additions & 11 deletions Documentation/driver-api/gpio/consumer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -323,29 +323,29 @@ The following functions get or set the values of an array of GPIOs::

int gpiod_get_array_value(unsigned int array_size,
struct gpio_desc **desc_array,
int *value_array);
unsigned long *value_bitmap);
int gpiod_get_raw_array_value(unsigned int array_size,
struct gpio_desc **desc_array,
int *value_array);
unsigned long *value_bitmap);
int gpiod_get_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array,
int *value_array);
unsigned long *value_bitmap);
int gpiod_get_raw_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array,
int *value_array);
unsigned long *value_bitmap);

void gpiod_set_array_value(unsigned int array_size,
struct gpio_desc **desc_array,
int *value_array)
unsigned long *value_bitmap)
void gpiod_set_raw_array_value(unsigned int array_size,
struct gpio_desc **desc_array,
int *value_array)
unsigned long *value_bitmap)
void gpiod_set_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array,
int *value_array)
unsigned long *value_bitmap)
void gpiod_set_raw_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array,
int *value_array)
unsigned long *value_bitmap)

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
Expand All @@ -356,8 +356,8 @@ accessed sequentially.
The functions take three arguments:
* array_size - the number of array elements
* desc_array - an array of GPIO descriptors
* value_array - an array to store the GPIOs' values (get) or
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
or one of its variants. If the group of descriptors returned by that function
Expand All @@ -366,7 +366,7 @@ the struct gpio_descs returned by gpiod_get_array()::

struct gpio_descs *my_gpio_descs = gpiod_get_array(...);
gpiod_set_array_value(my_gpio_descs->ndescs, my_gpio_descs->desc,
my_gpio_values);
my_gpio_value_bitmap);

It is also possible to access a completely arbitrary array of descriptors. The
descriptors may be obtained using any combination of gpiod_get() and
Expand Down
59 changes: 20 additions & 39 deletions drivers/auxdisplay/hd44780.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,12 @@ static void hd44780_strobe_gpio(struct hd44780 *hd)
/* write to an LCD panel register in 8 bit GPIO mode */
static void hd44780_write_gpio8(struct hd44780 *hd, u8 val, unsigned int rs)
{
int values[10]; /* for DATA[0-7], RS, RW */
unsigned int i, n;

for (i = 0; i < 8; i++)
values[PIN_DATA0 + i] = !!(val & BIT(i));
values[PIN_CTRL_RS] = rs;
n = 9;
if (hd->pins[PIN_CTRL_RW]) {
values[PIN_CTRL_RW] = 0;
n++;
}
DECLARE_BITMAP(values, 10); /* for DATA[0-7], RS, RW */
unsigned int n;

values[0] = val;
__assign_bit(8, values, rs);
n = hd->pins[PIN_CTRL_RW] ? 10 : 9;

/* Present the data to the port */
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA0], values);
Expand All @@ -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 */
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 */
unsigned int i, n;
DECLARE_BITMAP(values, 6); /* for DATA[4-7], RS, RW */
unsigned int n;

/* High nibble + RS, RW */
for (i = 4; i < 8; i++)
values[PIN_DATA0 + i] = !!(val & BIT(i));
values[PIN_CTRL_RS] = rs;
n = 5;
if (hd->pins[PIN_CTRL_RW]) {
values[PIN_CTRL_RW] = 0;
n++;
}
values[0] = val >> 4;
__assign_bit(4, values, rs);
n = hd->pins[PIN_CTRL_RW] ? 6 : 5;

/* Present the data to the port */
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4],
&values[PIN_DATA4]);
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], values);

hd44780_strobe_gpio(hd);

/* Low nibble */
for (i = 0; i < 4; i++)
values[PIN_DATA4 + i] = !!(val & BIT(i));
values[0] &= ~0x0fUL;
values[0] |= val & 0x0f;

/* Present the data to the port */
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4],
&values[PIN_DATA4]);
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], values);

hd44780_strobe_gpio(hd);
}
Expand Down Expand Up @@ -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 */
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;
unsigned int i, n;
unsigned int n;

/* Command nibble + RS, RW */
for (i = 0; i < 4; i++)
values[PIN_DATA4 + i] = !!(cmd & BIT(i));
values[PIN_CTRL_RS] = 0;
n = 5;
if (hd->pins[PIN_CTRL_RW]) {
values[PIN_CTRL_RW] = 0;
n++;
}
values[0] = cmd & 0x0f;
n = hd->pins[PIN_CTRL_RW] ? 6 : 5;

/* Present the data to the port */
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4],
&values[PIN_DATA4]);
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], values);

hd44780_strobe_gpio(hd);
}
Expand Down
15 changes: 4 additions & 11 deletions drivers/bus/ts-nbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,9 @@ static void ts_nbus_set_direction(struct ts_nbus *ts_nbus, int direction)
*/
static void ts_nbus_reset_bus(struct ts_nbus *ts_nbus)
{
int i;
int values[8];
DECLARE_BITMAP(values, 8);

for (i = 0; i < 8; i++)
values[i] = 0;
values[0] = 0;

gpiod_set_array_value_cansleep(8, ts_nbus->data->desc, values);
gpiod_set_value_cansleep(ts_nbus->csn, 0);
Expand Down Expand Up @@ -157,14 +155,9 @@ 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)
{
struct gpio_descs *gpios = ts_nbus->data;
int i;
int values[8];
DECLARE_BITMAP(values, 8);

for (i = 0; i < 8; i++)
if (byte & BIT(i))
values[i] = 1;
else
values[i] = 0;
values[0] = byte;

gpiod_set_array_value_cansleep(8, gpios->desc, values);
}
Expand Down
10 changes: 6 additions & 4 deletions drivers/gpio/gpio-max3191x.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,14 +315,16 @@ static void gpiod_set_array_single_value_cansleep(unsigned int ndescs,
struct gpio_desc **desc,
int value)
{
int i, *values;
unsigned long *values;

values = kmalloc_array(ndescs, sizeof(*values), GFP_KERNEL);
values = bitmap_alloc(ndescs, GFP_KERNEL);
if (!values)
return;

for (i = 0; i < ndescs; i++)
values[i] = value;
if (value)
bitmap_fill(values, ndescs);
else
bitmap_zero(values, ndescs);

gpiod_set_array_value_cansleep(ndescs, desc, values);
kfree(values);
Expand Down
Loading

0 comments on commit b9762be

Please sign in to comment.