Skip to content

Commit b9762be

Browse files
jkrzysztlinusw
authored andcommitted
gpiolib: Pass bitmaps, not integer arrays, to get/set array
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 <corbet@lwn.net> Cc: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com> Cc: Sebastien Bourdelin <sebastien.bourdelin@savoirfairelinux.com> Cc: Lukas Wunner <lukas@wunner.de> Cc: Peter Korsgaard <peter.korsgaard@barco.com> Cc: Peter Rosin <peda@axentia.se> Cc: Andrew Lunn <andrew@lunn.ch> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: "David S. Miller" <davem@davemloft.net> Cc: Rojhalat Ibrahim <imr@rtschenk.de> Cc: Dominik Brodowski <linux@dominikbrodowski.net> Cc: Russell King <rmk+kernel@armlinux.org.uk> Cc: Kishon Vijay Abraham I <kishon@ti.com> Cc: Tony Lindgren <tony@atomide.com> Cc: Lars-Peter Clausen <lars@metafoo.de> Cc: Michael Hennerich <Michael.Hennerich@analog.com> Cc: Jonathan Cameron <jic23@kernel.org> Cc: Hartmut Knaack <knaack.h@gmx.de> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Jiri Slaby <jslaby@suse.com> Cc: Yegor Yefremov <yegorslists@googlemail.com> Cc: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com> Acked-by: Ulf Hansson <ulf.hansson@linaro.org> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
1 parent 5b394b2 commit b9762be

File tree

15 files changed

+137
-177
lines changed

15 files changed

+137
-177
lines changed

Documentation/driver-api/gpio/consumer.rst

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -323,29 +323,29 @@ The following functions get or set the values of an array of GPIOs::
323323

324324
int gpiod_get_array_value(unsigned int array_size,
325325
struct gpio_desc **desc_array,
326-
int *value_array);
326+
unsigned long *value_bitmap);
327327
int gpiod_get_raw_array_value(unsigned int array_size,
328328
struct gpio_desc **desc_array,
329-
int *value_array);
329+
unsigned long *value_bitmap);
330330
int gpiod_get_array_value_cansleep(unsigned int array_size,
331331
struct gpio_desc **desc_array,
332-
int *value_array);
332+
unsigned long *value_bitmap);
333333
int gpiod_get_raw_array_value_cansleep(unsigned int array_size,
334334
struct gpio_desc **desc_array,
335-
int *value_array);
335+
unsigned long *value_bitmap);
336336

337337
void gpiod_set_array_value(unsigned int array_size,
338338
struct gpio_desc **desc_array,
339-
int *value_array)
339+
unsigned long *value_bitmap)
340340
void gpiod_set_raw_array_value(unsigned int array_size,
341341
struct gpio_desc **desc_array,
342-
int *value_array)
342+
unsigned long *value_bitmap)
343343
void gpiod_set_array_value_cansleep(unsigned int array_size,
344344
struct gpio_desc **desc_array,
345-
int *value_array)
345+
unsigned long *value_bitmap)
346346
void gpiod_set_raw_array_value_cansleep(unsigned int array_size,
347347
struct gpio_desc **desc_array,
348-
int *value_array)
348+
unsigned long *value_bitmap)
349349

350350
The array can be an arbitrary set of GPIOs. The functions will try to access
351351
GPIOs belonging to the same bank or chip simultaneously if supported by the
@@ -356,8 +356,8 @@ accessed sequentially.
356356
The functions take three arguments:
357357
* array_size - the number of array elements
358358
* desc_array - an array of GPIO descriptors
359-
* value_array - an array to store the GPIOs' values (get) or
360-
an array of values to assign to the GPIOs (set)
359+
* value_bitmap - a bitmap to store the GPIOs' values (get) or
360+
a bitmap of values to assign to the GPIOs (set)
361361

362362
The descriptor array can be obtained using the gpiod_get_array() function
363363
or one of its variants. If the group of descriptors returned by that function
@@ -366,7 +366,7 @@ the struct gpio_descs returned by gpiod_get_array()::
366366

367367
struct gpio_descs *my_gpio_descs = gpiod_get_array(...);
368368
gpiod_set_array_value(my_gpio_descs->ndescs, my_gpio_descs->desc,
369-
my_gpio_values);
369+
my_gpio_value_bitmap);
370370

371371
It is also possible to access a completely arbitrary array of descriptors. The
372372
descriptors may be obtained using any combination of gpiod_get() and

drivers/auxdisplay/hd44780.c

Lines changed: 20 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,12 @@ static void hd44780_strobe_gpio(struct hd44780 *hd)
6262
/* write to an LCD panel register in 8 bit GPIO mode */
6363
static void hd44780_write_gpio8(struct hd44780 *hd, u8 val, unsigned int rs)
6464
{
65-
int values[10]; /* for DATA[0-7], RS, RW */
66-
unsigned int i, n;
67-
68-
for (i = 0; i < 8; i++)
69-
values[PIN_DATA0 + i] = !!(val & BIT(i));
70-
values[PIN_CTRL_RS] = rs;
71-
n = 9;
72-
if (hd->pins[PIN_CTRL_RW]) {
73-
values[PIN_CTRL_RW] = 0;
74-
n++;
75-
}
65+
DECLARE_BITMAP(values, 10); /* for DATA[0-7], RS, RW */
66+
unsigned int n;
67+
68+
values[0] = val;
69+
__assign_bit(8, values, rs);
70+
n = hd->pins[PIN_CTRL_RW] ? 10 : 9;
7671

7772
/* Present the data to the port */
7873
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA0], values);
@@ -83,32 +78,25 @@ static void hd44780_write_gpio8(struct hd44780 *hd, u8 val, unsigned int rs)
8378
/* write to an LCD panel register in 4 bit GPIO mode */
8479
static void hd44780_write_gpio4(struct hd44780 *hd, u8 val, unsigned int rs)
8580
{
86-
int values[10]; /* for DATA[0-7], RS, RW, but DATA[0-3] is unused */
87-
unsigned int i, n;
81+
DECLARE_BITMAP(values, 6); /* for DATA[4-7], RS, RW */
82+
unsigned int n;
8883

8984
/* High nibble + RS, RW */
90-
for (i = 4; i < 8; i++)
91-
values[PIN_DATA0 + i] = !!(val & BIT(i));
92-
values[PIN_CTRL_RS] = rs;
93-
n = 5;
94-
if (hd->pins[PIN_CTRL_RW]) {
95-
values[PIN_CTRL_RW] = 0;
96-
n++;
97-
}
85+
values[0] = val >> 4;
86+
__assign_bit(4, values, rs);
87+
n = hd->pins[PIN_CTRL_RW] ? 6 : 5;
9888

9989
/* Present the data to the port */
100-
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4],
101-
&values[PIN_DATA4]);
90+
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], values);
10291

10392
hd44780_strobe_gpio(hd);
10493

10594
/* Low nibble */
106-
for (i = 0; i < 4; i++)
107-
values[PIN_DATA4 + i] = !!(val & BIT(i));
95+
values[0] &= ~0x0fUL;
96+
values[0] |= val & 0x0f;
10897

10998
/* Present the data to the port */
110-
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4],
111-
&values[PIN_DATA4]);
99+
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], values);
112100

113101
hd44780_strobe_gpio(hd);
114102
}
@@ -155,23 +143,16 @@ static void hd44780_write_cmd_gpio4(struct charlcd *lcd, int cmd)
155143
/* Send 4-bits of a command to the LCD panel in raw 4 bit GPIO mode */
156144
static void hd44780_write_cmd_raw_gpio4(struct charlcd *lcd, int cmd)
157145
{
158-
int values[10]; /* for DATA[0-7], RS, RW, but DATA[0-3] is unused */
146+
DECLARE_BITMAP(values, 6); /* for DATA[4-7], RS, RW */
159147
struct hd44780 *hd = lcd->drvdata;
160-
unsigned int i, n;
148+
unsigned int n;
161149

162150
/* Command nibble + RS, RW */
163-
for (i = 0; i < 4; i++)
164-
values[PIN_DATA4 + i] = !!(cmd & BIT(i));
165-
values[PIN_CTRL_RS] = 0;
166-
n = 5;
167-
if (hd->pins[PIN_CTRL_RW]) {
168-
values[PIN_CTRL_RW] = 0;
169-
n++;
170-
}
151+
values[0] = cmd & 0x0f;
152+
n = hd->pins[PIN_CTRL_RW] ? 6 : 5;
171153

172154
/* Present the data to the port */
173-
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4],
174-
&values[PIN_DATA4]);
155+
gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], values);
175156

176157
hd44780_strobe_gpio(hd);
177158
}

drivers/bus/ts-nbus.c

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,9 @@ static void ts_nbus_set_direction(struct ts_nbus *ts_nbus, int direction)
110110
*/
111111
static void ts_nbus_reset_bus(struct ts_nbus *ts_nbus)
112112
{
113-
int i;
114-
int values[8];
113+
DECLARE_BITMAP(values, 8);
115114

116-
for (i = 0; i < 8; i++)
117-
values[i] = 0;
115+
values[0] = 0;
118116

119117
gpiod_set_array_value_cansleep(8, ts_nbus->data->desc, values);
120118
gpiod_set_value_cansleep(ts_nbus->csn, 0);
@@ -157,14 +155,9 @@ static int ts_nbus_read_byte(struct ts_nbus *ts_nbus, u8 *val)
157155
static void ts_nbus_write_byte(struct ts_nbus *ts_nbus, u8 byte)
158156
{
159157
struct gpio_descs *gpios = ts_nbus->data;
160-
int i;
161-
int values[8];
158+
DECLARE_BITMAP(values, 8);
162159

163-
for (i = 0; i < 8; i++)
164-
if (byte & BIT(i))
165-
values[i] = 1;
166-
else
167-
values[i] = 0;
160+
values[0] = byte;
168161

169162
gpiod_set_array_value_cansleep(8, gpios->desc, values);
170163
}

drivers/gpio/gpio-max3191x.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -315,14 +315,16 @@ static void gpiod_set_array_single_value_cansleep(unsigned int ndescs,
315315
struct gpio_desc **desc,
316316
int value)
317317
{
318-
int i, *values;
318+
unsigned long *values;
319319

320-
values = kmalloc_array(ndescs, sizeof(*values), GFP_KERNEL);
320+
values = bitmap_alloc(ndescs, GFP_KERNEL);
321321
if (!values)
322322
return;
323323

324-
for (i = 0; i < ndescs; i++)
325-
values[i] = value;
324+
if (value)
325+
bitmap_fill(values, ndescs);
326+
else
327+
bitmap_zero(values, ndescs);
326328

327329
gpiod_set_array_value_cansleep(ndescs, desc, values);
328330
kfree(values);

0 commit comments

Comments
 (0)