Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
a2ab1703
Commit
a2ab1703
authored
Sep 20, 2018
by
Linus Walleij
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'ib-array-bitmaps' into devel
parents
c02980d6
b17566a6
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
400 additions
and
190 deletions
+400
-190
Documentation/driver-api/gpio/board.rst
Documentation/driver-api/gpio/board.rst
+15
-0
Documentation/driver-api/gpio/consumer.rst
Documentation/driver-api/gpio/consumer.rst
+33
-13
drivers/auxdisplay/hd44780.c
drivers/auxdisplay/hd44780.c
+21
-40
drivers/bus/ts-nbus.c
drivers/bus/ts-nbus.c
+7
-13
drivers/gpio/gpio-max3191x.c
drivers/gpio/gpio-max3191x.c
+10
-6
drivers/gpio/gpiolib.c
drivers/gpio/gpiolib.c
+220
-45
drivers/gpio/gpiolib.h
drivers/gpio/gpiolib.h
+13
-2
drivers/i2c/muxes/i2c-mux-gpio.c
drivers/i2c/muxes/i2c-mux-gpio.c
+5
-9
drivers/mmc/core/pwrseq_simple.c
drivers/mmc/core/pwrseq_simple.c
+4
-9
drivers/mux/gpio.c
drivers/mux/gpio.c
+4
-8
drivers/net/phy/mdio-mux-gpio.c
drivers/net/phy/mdio-mux-gpio.c
+4
-7
drivers/pcmcia/soc_common.c
drivers/pcmcia/soc_common.c
+5
-4
drivers/phy/motorola/phy-mapphone-mdm6600.c
drivers/phy/motorola/phy-mapphone-mdm6600.c
+9
-10
drivers/staging/iio/adc/ad7606.c
drivers/staging/iio/adc/ad7606.c
+3
-5
drivers/tty/serial/serial_mctrl_gpio.c
drivers/tty/serial/serial_mctrl_gpio.c
+4
-3
include/linux/gpio/consumer.h
include/linux/gpio/consumer.h
+43
-16
No files found.
Documentation/driver-api/gpio/board.rst
View file @
a2ab1703
...
...
@@ -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
View file @
a2ab1703
...
...
@@ -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[];
}
...
...
@@ -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
...
...
@@ -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
...
...
@@ -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
...
...
drivers/auxdisplay/hd44780.c
View file @
a2ab1703
...
...
@@ -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
);
}
...
...
@@ -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
);
}
...
...
@@ -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
);
}
...
...
drivers/bus/ts-nbus.c
View file @
a2ab1703
...
...
@@ -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
);
...
...
@@ -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
);
}
/*
...
...
drivers/gpio/gpio-max3191x.c
View file @
a2ab1703
...
...
@@ -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
);
}
...
...
@@ -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"
);
...
...
drivers/gpio/gpiolib.c
View file @
a2ab1703
...
...
@@ -427,7 +427,7 @@ 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
]
;
DECLARE_BITMAP
(
vals
,
GPIOHANDLES_MAX
)
;
int
i
;
if
(
cmd
==
GPIOHANDLE_GET_LINE_VALUES_IOCTL
)
{
...
...
@@ -436,13 +436,14 @@ static long linehandle_ioctl(struct file *filep, unsigned int cmd,
true
,
lh
->
numdescs
,
lh
->
descs
,
NULL
,
vals
);
if
(
ret
)
return
ret
;
memset
(
&
ghd
,
0
,
sizeof
(
ghd
));
for
(
i
=
0
;
i
<
lh
->
numdescs
;
i
++
)
ghd
.
values
[
i
]
=
vals
[
i
]
;
ghd
.
values
[
i
]
=
test_bit
(
i
,
vals
)
;
if
(
copy_to_user
(
ip
,
&
ghd
,
sizeof
(
ghd
)))
return
-
EFAULT
;
...
...
@@ -461,13 +462,14 @@ static long linehandle_ioctl(struct file *filep, unsigned int cmd,
/* Clamp all values to [0,1] */
for
(
i
=
0
;
i
<
lh
->
numdescs
;
i
++
)
vals
[
i
]
=
!!
ghd
.
values
[
i
]
;
__assign_bit
(
i
,
vals
,
ghd
.
values
[
i
])
;
/* Reuse the array setting function */
return
gpiod_set_array_value_complex
(
false
,
true
,
lh
->
numdescs
,
lh
->
descs
,
NULL
,
vals
);
}
return
-
EINVAL
;
...
...
@@ -2813,9 +2815,39 @@ static int gpio_chip_get_multiple(struct gpio_chip *chip,
int
gpiod_get_array_value_complex
(
bool
raw
,
bool
can_sleep
,
unsigned
int
array_size
,
struct
gpio_desc
**
desc_array
,
int
*
value_array
)
struct
gpio_array
*
array_info
,
unsigned
long
*
value_bitmap
)
{
int
i
=
0
;
int
err
,
i
=
0
;
/*
* Validate array_info against desc_array and its size.
* It should immediately follow desc_array if both
* have been obtained from the same gpiod_get_array() call.
*/
if
(
array_info
&&
array_info
->
desc
==
desc_array
&&
array_size
<=
array_info
->
size
&&
(
void
*
)
array_info
==
desc_array
+
array_info
->
size
)
{
if
(
!
can_sleep
)
WARN_ON
(
array_info
->
chip
->
can_sleep
);
err
=
gpio_chip_get_multiple
(
array_info
->
chip
,
array_info
->
get_mask
,
value_bitmap
);
if
(
err
)
return
err
;
if
(
!
raw
&&
!
bitmap_empty
(
array_info
->
invert_mask
,
array_size
))
bitmap_xor
(
value_bitmap
,
value_bitmap
,
array_info
->
invert_mask
,
array_size
);
if
(
bitmap_full
(
array_info
->
get_mask
,
array_size
))
return
0
;
i
=
find_first_zero_bit
(
array_info
->
get_mask
,
array_size
);
}
else
{
array_info
=
NULL
;
}
while
(
i
<
array_size
)
{
struct
gpio_chip
*
chip
=
desc_array
[
i
]
->
gdev
->
chip
;
...
...
@@ -2846,7 +2878,12 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
int
hwgpio
=
gpio_chip_hwgpio
(
desc
);
__set_bit
(
hwgpio
,
mask
);
i
++
;
if
(
array_info
)
find_next_zero_bit
(
array_info
->
get_mask
,
array_size
,
i
);
else
i
++
;
}
while
((
i
<
array_size
)
&&
(
desc_array
[
i
]
->
gdev
->
chip
==
chip
));
...
...
@@ -2857,15 +2894,20 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
return
ret
;
}
for
(
j
=
first
;
j
<
i
;
j
++
)
{
for
(
j
=
first
;
j
<
i
;
)
{
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
;
__assign_bit
(
j
,
value_bitmap
,
value
)
;
trace_gpio_value
(
desc_to_gpio
(
desc
),
1
,
value
);
if
(
array_info
)
find_next_zero_bit
(
array_info
->
get_mask
,
i
,
j
);
else
j
++
;
}
if
(
mask
!=
fastpath
)
...
...
@@ -2924,9 +2966,10 @@ 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
* @array_size: number of elements in the descriptor
array / value bitmap
* @desc_array: array of GPIO descriptors whose values will be read
* @value_array: array to store the read values
* @array_info: information on applicability of fast bitmap processing path
* @value_bitmap: bitmap 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,
...
...
@@ -2936,20 +2979,24 @@ EXPORT_SYMBOL_GPL(gpiod_get_value);
* 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
)
struct
gpio_desc
**
desc_array
,
struct
gpio_array
*
array_info
,
unsigned
long
*
value_bitmap
)
{
if
(
!
desc_array
)
return
-
EINVAL
;
return
gpiod_get_array_value_complex
(
true
,
false
,
array_size
,
desc_array
,
value_array
);
desc_array
,
array_info
,
value_bitmap
);
}
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
* @array_size: number of elements in the descriptor
array / value bitmap
* @desc_array: array of GPIO descriptors whose values will be read
* @value_array: array to store the read values
* @array_info: information on applicability of fast bitmap processing path
* @value_bitmap: bitmap 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.
...
...
@@ -2958,12 +3005,15 @@ EXPORT_SYMBOL_GPL(gpiod_get_raw_array_value);
* 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
)
struct
gpio_desc
**
desc_array
,
struct
gpio_array
*
array_info
,
unsigned
long
*
value_bitmap
)
{
if
(
!
desc_array
)
return
-
EINVAL
;
return
gpiod_get_array_value_complex
(
false
,
false
,
array_size
,
desc_array
,
value_array
);
desc_array
,
array_info
,
value_bitmap
);
}
EXPORT_SYMBOL_GPL
(
gpiod_get_array_value
);
...
...
@@ -3056,10 +3106,37 @@ static void gpio_chip_set_multiple(struct gpio_chip *chip,
int
gpiod_set_array_value_complex
(
bool
raw
,
bool
can_sleep
,
unsigned
int
array_size
,
struct
gpio_desc
**
desc_array
,
int
*
value_array
)
struct
gpio_array
*
array_info
,
unsigned
long
*
value_bitmap
)
{
int
i
=
0
;
/*
* Validate array_info against desc_array and its size.
* It should immediately follow desc_array if both
* have been obtained from the same gpiod_get_array() call.
*/
if
(
array_info
&&
array_info
->
desc
==
desc_array
&&
array_size
<=
array_info
->
size
&&
(
void
*
)
array_info
==
desc_array
+
array_info
->
size
)
{
if
(
!
can_sleep
)
WARN_ON
(
array_info
->
chip
->
can_sleep
);
if
(
!
raw
&&
!
bitmap_empty
(
array_info
->
invert_mask
,
array_size
))
bitmap_xor
(
value_bitmap
,
value_bitmap
,
array_info
->
invert_mask
,
array_size
);
gpio_chip_set_multiple
(
array_info
->
chip
,
array_info
->
set_mask
,
value_bitmap
);
if
(
bitmap_full
(
array_info
->
set_mask
,
array_size
))
return
0
;
i
=
find_first_zero_bit
(
array_info
->
set_mask
,
array_size
);
}
else
{
array_info
=
NULL
;
}
while
(
i
<
array_size
)
{
struct
gpio_chip
*
chip
=
desc_array
[
i
]
->
gdev
->
chip
;
unsigned
long
fastpath
[
2
*
BITS_TO_LONGS
(
FASTPATH_NGPIO
)];
...
...
@@ -3085,9 +3162,16 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
do
{
struct
gpio_desc
*
desc
=
desc_array
[
i
];
int
hwgpio
=
gpio_chip_hwgpio
(
desc
);
int
value
=
value_array
[
i
]
;
int
value
=
test_bit
(
i
,
value_bitmap
)
;
if
(
!
raw
&&
test_bit
(
FLAG_ACTIVE_LOW
,
&
desc
->
flags
))
/*
* Pins applicable for fast input but not for
* fast output processing may have been already
* inverted inside the fast path, skip them.
*/
if
(
!
raw
&&
!
(
array_info
&&
test_bit
(
i
,
array_info
->
invert_mask
))
&&
test_bit
(
FLAG_ACTIVE_LOW
,
&
desc
->
flags
))
value
=
!
value
;
trace_gpio_value
(
desc_to_gpio
(
desc
),
0
,
value
);
/*
...
...
@@ -3106,7 +3190,12 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
__clear_bit
(
hwgpio
,
bits
);
count
++
;
}
i
++
;
if
(
array_info
)
find_next_zero_bit
(
array_info
->
set_mask
,
array_size
,
i
);
else
i
++
;
}
while
((
i
<
array_size
)
&&
(
desc_array
[
i
]
->
gdev
->
chip
==
chip
));
/* push collected bits to outputs */
...
...
@@ -3181,9 +3270,10 @@ EXPORT_SYMBOL_GPL(gpiod_set_value);
/**
* gpiod_set_raw_array_value() - assign values to an array of GPIOs
* @array_size: number of elements in the descriptor
/ value arrays
* @array_size: number of elements in the descriptor
array / value bitmap
* @desc_array: array of GPIO descriptors whose values will be assigned
* @value_array: array of values to assign
* @array_info: information on applicability of fast bitmap processing path
* @value_bitmap: bitmap of values to assign
*
* Set the raw values of the GPIOs, i.e. the values of the physical lines
* without regard for their ACTIVE_LOW status.
...
...
@@ -3192,20 +3282,23 @@ EXPORT_SYMBOL_GPL(gpiod_set_value);
* complain if the GPIO chip functions potentially sleep.
*/
int
gpiod_set_raw_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
)
{
if
(
!
desc_array
)
return
-
EINVAL
;
return
gpiod_set_array_value_complex
(
true
,
false
,
array_size
,
desc_array
,
value_array
);
desc_array
,
array_info
,
value_bitmap
);
}
EXPORT_SYMBOL_GPL
(
gpiod_set_raw_array_value
);
/**
* gpiod_set_array_value() - assign values to an array of GPIOs
* @array_size: number of elements in the descriptor
/ value arrays
* @array_size: number of elements in the descriptor
array / value bitmap
* @desc_array: array of GPIO descriptors whose values will be assigned
* @value_array: array of values to assign
* @array_info: information on applicability of fast bitmap processing path
* @value_bitmap: bitmap of values to assign
*
* Set the logical values of the GPIOs, i.e. taking their ACTIVE_LOW status
* into account.
...
...
@@ -3214,12 +3307,14 @@ EXPORT_SYMBOL_GPL(gpiod_set_raw_array_value);
* complain if the GPIO chip functions potentially sleep.
*/
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
)
{
if
(
!
desc_array
)
return
;
gpiod_set_array_value_complex
(
false
,
false
,
array_size
,
desc_array
,
value_array
);
array_info
,
value_bitmap
);
}
EXPORT_SYMBOL_GPL
(
gpiod_set_array_value
);
...
...
@@ -3487,9 +3582,10 @@ 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
* @array_size: number of elements in the descriptor
array / value bitmap
* @desc_array: array of GPIO descriptors whose values will be read
* @value_array: array to store the read values
* @array_info: information on applicability of fast bitmap processing path
* @value_bitmap: bitmap 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,
...
...
@@ -3499,21 +3595,24 @@ EXPORT_SYMBOL_GPL(gpiod_get_value_cansleep);
*/
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
)
{
might_sleep_if
(
extra_checks
);
if
(
!
desc_array
)
return
-
EINVAL
;
return
gpiod_get_array_value_complex
(
true
,
true
,
array_size
,
desc_array
,
value_array
);
desc_array
,
array_info
,
value_bitmap
);
}
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
* @array_size: number of elements in the descriptor
array / value bitmap
* @desc_array: array of GPIO descriptors whose values will be read
* @value_array: array to store the read values
* @array_info: information on applicability of fast bitmap processing path
* @value_bitmap: bitmap 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.
...
...
@@ -3522,13 +3621,15 @@ EXPORT_SYMBOL_GPL(gpiod_get_raw_array_value_cansleep);
*/
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
)
{
might_sleep_if
(
extra_checks
);
if
(
!
desc_array
)
return
-
EINVAL
;
return
gpiod_get_array_value_complex
(
false
,
true
,
array_size
,
desc_array
,
value_array
);
desc_array
,
array_info
,
value_bitmap
);
}
EXPORT_SYMBOL_GPL
(
gpiod_get_array_value_cansleep
);
...
...
@@ -3570,9 +3671,10 @@ EXPORT_SYMBOL_GPL(gpiod_set_value_cansleep);
/**
* gpiod_set_raw_array_value_cansleep() - assign values to an array of GPIOs
* @array_size: number of elements in the descriptor
/ value arrays
* @array_size: number of elements in the descriptor
array / value bitmap
* @desc_array: array of GPIO descriptors whose values will be assigned
* @value_array: array of values to assign
* @array_info: information on applicability of fast bitmap processing path
* @value_bitmap: bitmap of values to assign
*
* Set the raw values of the GPIOs, i.e. the values of the physical lines
* without regard for their ACTIVE_LOW status.
...
...
@@ -3581,13 +3683,14 @@ EXPORT_SYMBOL_GPL(gpiod_set_value_cansleep);
*/
int
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
)
{
might_sleep_if
(
extra_checks
);
if
(
!
desc_array
)
return
-
EINVAL
;
return
gpiod_set_array_value_complex
(
true
,
true
,
array_size
,
desc_array
,
value_array
);
array_info
,
value_bitmap
);
}
EXPORT_SYMBOL_GPL
(
gpiod_set_raw_array_value_cansleep
);
...
...
@@ -3610,9 +3713,10 @@ void gpiod_add_lookup_tables(struct gpiod_lookup_table **tables, size_t n)
/**
* gpiod_set_array_value_cansleep() - assign values to an array of GPIOs
* @array_size: number of elements in the descriptor
/ value arrays
* @array_size: number of elements in the descriptor
array / value bitmap
* @desc_array: array of GPIO descriptors whose values will be assigned
* @value_array: array of values to assign
* @array_info: information on applicability of fast bitmap processing path
* @value_bitmap: bitmap of values to assign
*
* Set the logical values of the GPIOs, i.e. taking their ACTIVE_LOW status
* into account.
...
...
@@ -3621,13 +3725,14 @@ void gpiod_add_lookup_tables(struct gpiod_lookup_table **tables, size_t n)
*/
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
)
{
might_sleep_if
(
extra_checks
);
if
(
!
desc_array
)
return
;
gpiod_set_array_value_complex
(
false
,
true
,
array_size
,
desc_array
,
value_array
);
array_info
,
value_bitmap
);
}
EXPORT_SYMBOL_GPL
(
gpiod_set_array_value_cansleep
);
...
...
@@ -4247,7 +4352,9 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
{
struct
gpio_desc
*
desc
;
struct
gpio_descs
*
descs
;
int
count
;
struct
gpio_array
*
array_info
=
NULL
;
struct
gpio_chip
*
chip
;
int
count
,
bitmap_size
;
count
=
gpiod_count
(
dev
,
con_id
);
if
(
count
<
0
)
...
...
@@ -4263,9 +4370,77 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
gpiod_put_array
(
descs
);
return
ERR_CAST
(
desc
);
}
descs
->
desc
[
descs
->
ndescs
]
=
desc
;
chip
=
gpiod_to_chip
(
desc
);
/*
* Select a chip of first array member
* whose index matches its pin hardware number
* as a candidate for fast bitmap processing.
*/
if
(
!
array_info
&&
gpio_chip_hwgpio
(
desc
)
==
descs
->
ndescs
)
{
struct
gpio_descs
*
array
;
bitmap_size
=
BITS_TO_LONGS
(
chip
->
ngpio
>
count
?
chip
->
ngpio
:
count
);
array
=
kzalloc
(
struct_size
(
descs
,
desc
,
count
)
+
struct_size
(
array_info
,
invert_mask
,
3
*
bitmap_size
),
GFP_KERNEL
);
if
(
!
array
)
{
gpiod_put_array
(
descs
);
return
ERR_PTR
(
-
ENOMEM
);
}
memcpy
(
array
,
descs
,
struct_size
(
descs
,
desc
,
descs
->
ndescs
+
1
));
kfree
(
descs
);
descs
=
array
;
array_info
=
(
void
*
)(
descs
->
desc
+
count
);
array_info
->
get_mask
=
array_info
->
invert_mask
+
bitmap_size
;
array_info
->
set_mask
=
array_info
->
get_mask
+
bitmap_size
;
array_info
->
desc
=
descs
->
desc
;
array_info
->
size
=
count
;
array_info
->
chip
=
chip
;
bitmap_set
(
array_info
->
get_mask
,
descs
->
ndescs
,
count
-
descs
->
ndescs
);
bitmap_set
(
array_info
->
set_mask
,
descs
->
ndescs
,
count
-
descs
->
ndescs
);
descs
->
info
=
array_info
;
}
/*
* Unmark members which don't qualify for fast bitmap
* processing (different chip, not in hardware order)
*/
if
(
array_info
&&
(
chip
!=
array_info
->
chip
||
gpio_chip_hwgpio
(
desc
)
!=
descs
->
ndescs
))
{
__clear_bit
(
descs
->
ndescs
,
array_info
->
get_mask
);
__clear_bit
(
descs
->
ndescs
,
array_info
->
set_mask
);
}
else
if
(
array_info
)
{
/* Exclude open drain or open source from fast output */
if
(
gpiochip_line_is_open_drain
(
chip
,
descs
->
ndescs
)
||
gpiochip_line_is_open_source
(
chip
,
descs
->
ndescs
))
__clear_bit
(
descs
->
ndescs
,
array_info
->
set_mask
);
/* Identify 'fast' pins which require invertion */
if
(
gpiod_is_active_low
(
desc
))
__set_bit
(
descs
->
ndescs
,
array_info
->
invert_mask
);
}
descs
->
ndescs
++
;
}
if
(
array_info
)
dev_dbg
(
dev
,
"GPIO array info: chip=%s, size=%d, get_mask=%lx, set_mask=%lx, invert_mask=%lx
\n
"
,
array_info
->
chip
->
label
,
array_info
->
size
,
*
array_info
->
get_mask
,
*
array_info
->
set_mask
,
*
array_info
->
invert_mask
);
return
descs
;
}
EXPORT_SYMBOL_GPL
(
gpiod_get_array
);
...
...
drivers/gpio/gpiolib.h
View file @
a2ab1703
...
...
@@ -183,15 +183,26 @@ static inline bool acpi_can_fallback_to_crs(struct acpi_device *adev,
}
#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
);
int
gpiod_get_array_value_complex
(
bool
raw
,
bool
can_sleep
,
unsigned
int
array_size
,
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
,
unsigned
int
array_size
,
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 */
struct
gpio_desc
*
gpiod_get_from_of_node
(
struct
device_node
*
node
,
...
...
drivers/i2c/muxes/i2c-mux-gpio.c
View file @
a2ab1703
...
...
@@ -22,18 +22,16 @@ struct gpiomux {
struct
i2c_mux_gpio_platform_data
data
;
unsigned
gpio_base
;
struct
gpio_desc
**
gpios
;
int
*
values
;
};
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
++
)
mux
->
values
[
i
]
=
(
val
>>
i
)
&
1
;
values
[
0
]
=
val
;
gpiod_set_array_value_cansleep
(
mux
->
data
.
n_gpios
,
mux
->
gpios
,
mux
->
values
);
gpiod_set_array_value_cansleep
(
mux
->
data
.
n_gpios
,
mux
->
gpios
,
NULL
,
values
);
}
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)
return
-
EPROBE_DEFER
;
muxc
=
i2c_mux_alloc
(
parent
,
&
pdev
->
dev
,
mux
->
data
.
n_values
,
mux
->
data
.
n_gpios
*
sizeof
(
*
mux
->
gpios
)
+
mux
->
data
.
n_gpios
*
sizeof
(
*
mux
->
values
),
0
,
mux
->
data
.
n_gpios
*
sizeof
(
*
mux
->
gpios
),
0
,
i2c_mux_gpio_select
,
NULL
);
if
(
!
muxc
)
{
ret
=
-
ENOMEM
;
goto
alloc_failed
;
}
mux
->
gpios
=
muxc
->
priv
;
mux
->
values
=
(
int
*
)(
mux
->
gpios
+
mux
->
data
.
n_gpios
);
muxc
->
priv
=
mux
;
platform_set_drvdata
(
pdev
,
muxc
);
...
...
drivers/mmc/core/pwrseq_simple.c
View file @
a2ab1703
...
...
@@ -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
;
if
(
!
IS_ERR
(
reset_gpios
))
{
int
i
,
*
values
;
DECLARE_BITMAP
(
values
,
BITS_PER_TYPE
(
value
))
;
int
nvalues
=
reset_gpios
->
ndescs
;
values
=
kmalloc_array
(
nvalues
,
sizeof
(
int
),
GFP_KERNEL
);
if
(
!
values
)
return
;
values
[
0
]
=
value
;
for
(
i
=
0
;
i
<
nvalues
;
i
++
)
values
[
i
]
=
value
;
gpiod_set_array_value_cansleep
(
nvalues
,
reset_gpios
->
desc
,
values
);
kfree
(
values
);
gpiod_set_array_value_cansleep
(
nvalues
,
reset_gpios
->
desc
,
reset_gpios
->
info
,
values
);
}
}
...
...
drivers/mux/gpio.c
View file @
a2ab1703
...
...
@@ -17,20 +17,18 @@
struct
mux_gpio
{
struct
gpio_descs
*
gpios
;
int
*
val
;
};
static
int
mux_gpio_set
(
struct
mux_control
*
mux
,
int
state
)
{
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
++
)
mux_gpio
->
val
[
i
]
=
(
state
>>
i
)
&
1
;
values
[
0
]
=
state
;
gpiod_set_array_value_cansleep
(
mux_gpio
->
gpios
->
ndescs
,
mux_gpio
->
gpios
->
desc
,
mux_gpio
->
val
);
mux_gpio
->
gpios
->
info
,
values
);
return
0
;
}
...
...
@@ -58,13 +56,11 @@ static int mux_gpio_probe(struct platform_device *pdev)
if
(
pins
<
0
)
return
pins
;
mux_chip
=
devm_mux_chip_alloc
(
dev
,
1
,
sizeof
(
*
mux_gpio
)
+
pins
*
sizeof
(
*
mux_gpio
->
val
));
mux_chip
=
devm_mux_chip_alloc
(
dev
,
1
,
sizeof
(
*
mux_gpio
));
if
(
IS_ERR
(
mux_chip
))
return
PTR_ERR
(
mux_chip
);
mux_gpio
=
mux_chip_priv
(
mux_chip
);
mux_gpio
->
val
=
(
int
*
)(
mux_gpio
+
1
);
mux_chip
->
ops
=
&
mux_gpio_ops
;
mux_gpio
->
gpios
=
devm_gpiod_get_array
(
dev
,
"mux"
,
GPIOD_OUT_LOW
);
...
...
drivers/net/phy/mdio-mux-gpio.c
View file @
a2ab1703
...
...
@@ -20,23 +20,21 @@
struct
mdio_mux_gpio_state
{
struct
gpio_descs
*
gpios
;
void
*
mux_handle
;
int
values
[];
};
static
int
mdio_mux_gpio_switch_fn
(
int
current_child
,
int
desired_child
,
void
*
data
)
{
struct
mdio_mux_gpio_state
*
s
=
data
;
unsigned
int
n
;
DECLARE_BITMAP
(
values
,
BITS_PER_TYPE
(
desired_child
))
;
if
(
current_child
==
desired_child
)
return
0
;
for
(
n
=
0
;
n
<
s
->
gpios
->
ndescs
;
n
++
)
s
->
values
[
n
]
=
(
desired_child
>>
n
)
&
1
;
values
[
0
]
=
desired_child
;
gpiod_set_array_value_cansleep
(
s
->
gpios
->
ndescs
,
s
->
gpios
->
desc
,
s
->
values
);
s
->
gpios
->
info
,
values
);
return
0
;
}
...
...
@@ -51,8 +49,7 @@ static int mdio_mux_gpio_probe(struct platform_device *pdev)
if
(
IS_ERR
(
gpios
))
return
PTR_ERR
(
gpios
);
s
=
devm_kzalloc
(
&
pdev
->
dev
,
struct_size
(
s
,
values
,
gpios
->
ndescs
),
GFP_KERNEL
);
s
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
s
),
GFP_KERNEL
);
if
(
!
s
)
{
gpiod_put_array
(
gpios
);
return
-
ENOMEM
;
...
...
drivers/pcmcia/soc_common.c
View file @
a2ab1703
...
...
@@ -351,19 +351,20 @@ static int soc_common_pcmcia_config_skt(
if
(
ret
==
0
)
{
struct
gpio_desc
*
descs
[
2
];
int
values
[
2
],
n
=
0
;
DECLARE_BITMAP
(
values
,
2
);
int
n
=
0
;
if
(
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
)
{
descs
[
n
]
=
skt
->
gpio_bus_enable
;
values
[
n
++
]
=
!!
(
state
->
flags
&
SS_OUTPUT_ENA
);
__assign_bit
(
n
++
,
values
,
state
->
flags
&
SS_OUTPUT_ENA
);
}
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
...
...
drivers/phy/motorola/phy-mapphone-mdm6600.c
View file @
a2ab1703
...
...
@@ -157,15 +157,13 @@ static const struct phy_ops gpio_usb_ops = {
*/
static
void
phy_mdm6600_cmd
(
struct
phy_mdm6600
*
ddata
,
int
val
)
{
int
values
[
PHY_MDM6600_NR_CMD_LINES
];
int
i
;
DECLARE_BITMAP
(
values
,
PHY_MDM6600_NR_CMD_LINES
);
val
&=
(
1
<<
PHY_MDM6600_NR_CMD_LINES
)
-
1
;
for
(
i
=
0
;
i
<
PHY_MDM6600_NR_CMD_LINES
;
i
++
)
values
[
i
]
=
(
val
&
BIT
(
i
))
>>
i
;
values
[
0
]
=
val
;
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)
{
struct
phy_mdm6600
*
ddata
;
struct
device
*
dev
;
int
values
[
PHY_MDM6600_NR_STATUS_LINES
]
;
DECLARE_BITMAP
(
values
,
PHY_MDM6600_NR_STATUS_LINES
)
;
int
error
,
i
,
val
=
0
;
ddata
=
container_of
(
work
,
struct
phy_mdm6600
,
status_work
.
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
,
ddata
->
status_gpios
->
desc
,
ddata
->
status_gpios
->
info
,
values
);
if
(
error
)
return
;
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
"
,
__func__
,
i
,
values
[
i
]
,
val
);
__func__
,
i
,
test_bit
(
i
,
values
)
,
val
);
}
ddata
->
status
=
val
;
ddata
->
status
=
val
ues
[
0
]
;
dev_info
(
dev
,
"modem status: %i %s
\n
"
,
ddata
->
status
,
...
...
drivers/staging/iio/adc/ad7606.c
View file @
a2ab1703
...
...
@@ -202,7 +202,7 @@ static int ad7606_write_raw(struct iio_dev *indio_dev,
long
mask
)
{
struct
ad7606_state
*
st
=
iio_priv
(
indio_dev
);
int
values
[
3
]
;
DECLARE_BITMAP
(
values
,
3
)
;
int
ret
,
i
;
switch
(
mask
)
{
...
...
@@ -227,12 +227,10 @@ static int ad7606_write_raw(struct iio_dev *indio_dev,
if
(
ret
<
0
)
return
ret
;
values
[
0
]
=
(
ret
>>
0
)
&
1
;
values
[
1
]
=
(
ret
>>
1
)
&
1
;
values
[
2
]
=
(
ret
>>
2
)
&
1
;
values
[
0
]
=
ret
;
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
);
st
->
oversampling
=
val
;
mutex_unlock
(
&
st
->
lock
);
...
...
drivers/tty/serial/serial_mctrl_gpio.c
View file @
a2ab1703
...
...
@@ -40,7 +40,7 @@ void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl)
{
enum
mctrl_gpio_idx
i
;
struct
gpio_desc
*
desc_array
[
UART_GPIO_MAX
];
int
value_array
[
UART_GPIO_MAX
]
;
DECLARE_BITMAP
(
values
,
UART_GPIO_MAX
)
;
unsigned
int
count
=
0
;
if
(
gpios
==
NULL
)
...
...
@@ -49,10 +49,11 @@ void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl)
for
(
i
=
0
;
i
<
UART_GPIO_MAX
;
i
++
)
if
(
gpios
->
gpio
[
i
]
&&
mctrl_gpios_desc
[
i
].
dir_out
)
{
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
++
;
}
gpiod_set_array_value
(
count
,
desc_array
,
value_array
);
gpiod_set_array_value
(
count
,
desc_array
,
NULL
,
values
);
}
EXPORT_SYMBOL_GPL
(
mctrl_gpio_set
);
...
...
include/linux/gpio/consumer.h
View file @
a2ab1703
...
...
@@ -17,11 +17,20 @@ struct device;
*/
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
* gpiod_get_array().
*/
struct
gpio_descs
{
struct
gpio_array
*
info
;
unsigned
int
ndescs
;
struct
gpio_desc
*
desc
[];
};
...
...
@@ -104,36 +113,46 @@ int gpiod_direction_output_raw(struct gpio_desc *desc, int value);
/* Value get/set from non-sleeping context */
int
gpiod_get_value
(
const
struct
gpio_desc
*
desc
);
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_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_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_value
(
struct
gpio_desc
*
desc
,
int
value
);
int
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
);
/* Value get/set from sleeping context */
int
gpiod_get_value_cansleep
(
const
struct
gpio_desc
*
desc
);
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
);
void
gpiod_set_value_cansleep
(
struct
gpio_desc
*
desc
,
int
value
);
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
);
int
gpiod_get_raw_value_cansleep
(
const
struct
gpio_desc
*
desc
);
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_raw_value_cansleep
(
struct
gpio_desc
*
desc
,
int
value
);
int
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
);
int
gpiod_set_debounce
(
struct
gpio_desc
*
desc
,
unsigned
debounce
);
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)
}
static
inline
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
)
{
/* GPIO can never have been requested */
WARN_ON
(
1
);
...
...
@@ -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
,
struct
gpio_desc
**
desc_array
,
int
*
value_array
)
struct
gpio_array
*
array_info
,
unsigned
long
*
value_bitmap
)
{
/* GPIO can never have been requested */
WARN_ON
(
1
);
...
...
@@ -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
,
struct
gpio_desc
**
desc_array
,
int
*
value_array
)
struct
gpio_array
*
array_info
,
unsigned
long
*
value_bitmap
)
{
/* GPIO can never have been requested */
WARN_ON
(
1
);
...
...
@@ -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
,
struct
gpio_desc
**
desc_array
,
int
*
value_array
)
struct
gpio_array
*
array_info
,
unsigned
long
*
value_bitmap
)
{
/* GPIO can never have been requested */
WARN_ON
(
1
);
...
...
@@ -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
,
struct
gpio_desc
**
desc_array
,
int
*
value_array
)
struct
gpio_array
*
array_info
,
unsigned
long
*
value_bitmap
)
{
/* GPIO can never have been requested */
WARN_ON
(
1
);
...
...
@@ -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
,
struct
gpio_desc
**
desc_array
,
int
*
value_array
)
struct
gpio_array
*
array_info
,
unsigned
long
*
value_bitmap
)
{
/* GPIO can never have been requested */
WARN_ON
(
1
);
...
...
@@ -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
,
struct
gpio_desc
**
desc_array
,
int
*
value_array
)
struct
gpio_array
*
array_info
,
unsigned
long
*
value_bitmap
)
{
/* GPIO can never have been requested */
WARN_ON
(
1
);
...
...
@@ -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
,
struct
gpio_desc
**
desc_array
,
int
*
value_array
)
struct
gpio_array
*
array_info
,
unsigned
long
*
value_bitmap
)
{
/* GPIO can never have been requested */
WARN_ON
(
1
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment