Loading Documentation/driver-api/gpio/board.rst +15 −0 Original line number Diff line number Diff line Loading @@ -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 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. Documentation/driver-api/gpio/consumer.rst +33 −13 Original line number Diff line number Diff line Loading @@ -109,9 +109,11 @@ For a function using multiple GPIOs all of those can be obtained with one call:: enum gpiod_flags flags) 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_array *info; unsigned int ndescs; struct gpio_desc *desc[]; } Loading Loading @@ -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, 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, 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, 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, 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, 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, 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, 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, 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 GPIOs belonging to the same bank or chip simultaneously if supported by the Loading @@ -356,8 +366,9 @@ 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) * array_info - optional information obtained from gpiod_array_get() * 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 Loading @@ -366,16 +377,25 @@ 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_descs->info, 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 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 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 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 Loading drivers/auxdisplay/hd44780.c +21 −40 Original line number Diff line number Diff line Loading @@ -62,20 +62,15 @@ 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); gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA0], NULL, values); hd44780_strobe_gpio(hd); } Loading @@ -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], NULL, 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], NULL, values); hd44780_strobe_gpio(hd); } Loading Loading @@ -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], NULL, values); hd44780_strobe_gpio(hd); } Loading drivers/bus/ts-nbus.c +7 −13 Original line number Diff line number Diff line Loading @@ -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) { 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_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->strobe, 0); gpiod_set_value_cansleep(ts_nbus->ale, 0); Loading Loading @@ -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) { 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); gpiod_set_array_value_cansleep(8, gpios->desc, gpios->info, values); } /* Loading drivers/gpio/gpio-max3191x.c +10 −6 Original line number Diff line number Diff line Loading @@ -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, struct gpio_desc **desc, struct gpio_array *info, 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); gpiod_set_array_value_cansleep(ndescs, desc, info, values); kfree(values); } Loading Loading @@ -397,7 +400,8 @@ static int max3191x_probe(struct spi_device *spi) if (max3191x->modesel_pins) gpiod_set_array_single_value_cansleep( 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, "maxim,ignore-undervoltage"); Loading Loading
Documentation/driver-api/gpio/board.rst +15 −0 Original line number Diff line number Diff line Loading @@ -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 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.
Documentation/driver-api/gpio/consumer.rst +33 −13 Original line number Diff line number Diff line Loading @@ -109,9 +109,11 @@ For a function using multiple GPIOs all of those can be obtained with one call:: enum gpiod_flags flags) 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_array *info; unsigned int ndescs; struct gpio_desc *desc[]; } Loading Loading @@ -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, 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, 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, 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, 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, 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, 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, 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, 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 GPIOs belonging to the same bank or chip simultaneously if supported by the Loading @@ -356,8 +366,9 @@ 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) * array_info - optional information obtained from gpiod_array_get() * 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 Loading @@ -366,16 +377,25 @@ 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_descs->info, 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 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 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 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 Loading
drivers/auxdisplay/hd44780.c +21 −40 Original line number Diff line number Diff line Loading @@ -62,20 +62,15 @@ 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); gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA0], NULL, values); hd44780_strobe_gpio(hd); } Loading @@ -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], NULL, 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], NULL, values); hd44780_strobe_gpio(hd); } Loading Loading @@ -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], NULL, values); hd44780_strobe_gpio(hd); } Loading
drivers/bus/ts-nbus.c +7 −13 Original line number Diff line number Diff line Loading @@ -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) { 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_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->strobe, 0); gpiod_set_value_cansleep(ts_nbus->ale, 0); Loading Loading @@ -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) { 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); gpiod_set_array_value_cansleep(8, gpios->desc, gpios->info, values); } /* Loading
drivers/gpio/gpio-max3191x.c +10 −6 Original line number Diff line number Diff line Loading @@ -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, struct gpio_desc **desc, struct gpio_array *info, 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); gpiod_set_array_value_cansleep(ndescs, desc, info, values); kfree(values); } Loading Loading @@ -397,7 +400,8 @@ static int max3191x_probe(struct spi_device *spi) if (max3191x->modesel_pins) gpiod_set_array_single_value_cansleep( 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, "maxim,ignore-undervoltage"); Loading