gpio: aggregator: Refactor ->{get, set}_multiple() to make Sparse happy
Sparse can't see locking scheme used in ->get_multiple() and ->set_multiple() callbacks. CHECK .../drivers/gpio/gpio-aggregator.c .../spinlock.h:409:9: warning: context imbalance in 'gpio_fwd_get_multiple' - unexpected unlock .../spinlock.h:409:9: warning: context imbalance in 'gpio_fwd_set_multiple' - unexpected unlock Refactor them to have better readability and make Sparse happy. Code size impact is +52 bytes with arm-linux-gnueabihf-gcc 7.5.0. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
This commit is contained in:
committed by
Bartosz Golaszewski
parent
329afb94e0
commit
01e8d85b68
@@ -333,20 +333,14 @@ static int gpio_fwd_get(struct gpio_chip *chip, unsigned int offset)
|
|||||||
return gpiod_get_value(fwd->descs[offset]);
|
return gpiod_get_value(fwd->descs[offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gpio_fwd_get_multiple(struct gpio_chip *chip, unsigned long *mask,
|
static int gpio_fwd_get_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
|
||||||
unsigned long *bits)
|
unsigned long *bits)
|
||||||
{
|
{
|
||||||
struct gpiochip_fwd *fwd = gpiochip_get_data(chip);
|
|
||||||
unsigned long *values, flags = 0;
|
|
||||||
struct gpio_desc **descs;
|
struct gpio_desc **descs;
|
||||||
|
unsigned long *values;
|
||||||
unsigned int i, j = 0;
|
unsigned int i, j = 0;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (chip->can_sleep)
|
|
||||||
mutex_lock(&fwd->mlock);
|
|
||||||
else
|
|
||||||
spin_lock_irqsave(&fwd->slock, flags);
|
|
||||||
|
|
||||||
/* Both values bitmap and desc pointers are stored in tmp[] */
|
/* Both values bitmap and desc pointers are stored in tmp[] */
|
||||||
values = &fwd->tmp[0];
|
values = &fwd->tmp[0];
|
||||||
descs = (void *)&fwd->tmp[BITS_TO_LONGS(fwd->chip.ngpio)];
|
descs = (void *)&fwd->tmp[BITS_TO_LONGS(fwd->chip.ngpio)];
|
||||||
@@ -356,16 +350,32 @@ static int gpio_fwd_get_multiple(struct gpio_chip *chip, unsigned long *mask,
|
|||||||
descs[j++] = fwd->descs[i];
|
descs[j++] = fwd->descs[i];
|
||||||
|
|
||||||
error = gpiod_get_array_value(j, descs, NULL, values);
|
error = gpiod_get_array_value(j, descs, NULL, values);
|
||||||
if (!error) {
|
if (error)
|
||||||
j = 0;
|
return error;
|
||||||
for_each_set_bit(i, mask, fwd->chip.ngpio)
|
|
||||||
__assign_bit(i, bits, test_bit(j++, values));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chip->can_sleep)
|
j = 0;
|
||||||
|
for_each_set_bit(i, mask, fwd->chip.ngpio)
|
||||||
|
__assign_bit(i, bits, test_bit(j++, values));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gpio_fwd_get_multiple_locked(struct gpio_chip *chip,
|
||||||
|
unsigned long *mask, unsigned long *bits)
|
||||||
|
{
|
||||||
|
struct gpiochip_fwd *fwd = gpiochip_get_data(chip);
|
||||||
|
unsigned long flags;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (chip->can_sleep) {
|
||||||
|
mutex_lock(&fwd->mlock);
|
||||||
|
error = gpio_fwd_get_multiple(fwd, mask, bits);
|
||||||
mutex_unlock(&fwd->mlock);
|
mutex_unlock(&fwd->mlock);
|
||||||
else
|
} else {
|
||||||
|
spin_lock_irqsave(&fwd->slock, flags);
|
||||||
|
error = gpio_fwd_get_multiple(fwd, mask, bits);
|
||||||
spin_unlock_irqrestore(&fwd->slock, flags);
|
spin_unlock_irqrestore(&fwd->slock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -377,19 +387,13 @@ static void gpio_fwd_set(struct gpio_chip *chip, unsigned int offset, int value)
|
|||||||
gpiod_set_value(fwd->descs[offset], value);
|
gpiod_set_value(fwd->descs[offset], value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gpio_fwd_set_multiple(struct gpio_chip *chip, unsigned long *mask,
|
static void gpio_fwd_set_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
|
||||||
unsigned long *bits)
|
unsigned long *bits)
|
||||||
{
|
{
|
||||||
struct gpiochip_fwd *fwd = gpiochip_get_data(chip);
|
|
||||||
unsigned long *values, flags = 0;
|
|
||||||
struct gpio_desc **descs;
|
struct gpio_desc **descs;
|
||||||
|
unsigned long *values;
|
||||||
unsigned int i, j = 0;
|
unsigned int i, j = 0;
|
||||||
|
|
||||||
if (chip->can_sleep)
|
|
||||||
mutex_lock(&fwd->mlock);
|
|
||||||
else
|
|
||||||
spin_lock_irqsave(&fwd->slock, flags);
|
|
||||||
|
|
||||||
/* Both values bitmap and desc pointers are stored in tmp[] */
|
/* Both values bitmap and desc pointers are stored in tmp[] */
|
||||||
values = &fwd->tmp[0];
|
values = &fwd->tmp[0];
|
||||||
descs = (void *)&fwd->tmp[BITS_TO_LONGS(fwd->chip.ngpio)];
|
descs = (void *)&fwd->tmp[BITS_TO_LONGS(fwd->chip.ngpio)];
|
||||||
@@ -400,11 +404,23 @@ static void gpio_fwd_set_multiple(struct gpio_chip *chip, unsigned long *mask,
|
|||||||
}
|
}
|
||||||
|
|
||||||
gpiod_set_array_value(j, descs, NULL, values);
|
gpiod_set_array_value(j, descs, NULL, values);
|
||||||
|
}
|
||||||
|
|
||||||
if (chip->can_sleep)
|
static void gpio_fwd_set_multiple_locked(struct gpio_chip *chip,
|
||||||
|
unsigned long *mask, unsigned long *bits)
|
||||||
|
{
|
||||||
|
struct gpiochip_fwd *fwd = gpiochip_get_data(chip);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (chip->can_sleep) {
|
||||||
|
mutex_lock(&fwd->mlock);
|
||||||
|
gpio_fwd_set_multiple(fwd, mask, bits);
|
||||||
mutex_unlock(&fwd->mlock);
|
mutex_unlock(&fwd->mlock);
|
||||||
else
|
} else {
|
||||||
|
spin_lock_irqsave(&fwd->slock, flags);
|
||||||
|
gpio_fwd_set_multiple(fwd, mask, bits);
|
||||||
spin_unlock_irqrestore(&fwd->slock, flags);
|
spin_unlock_irqrestore(&fwd->slock, flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gpio_fwd_set_config(struct gpio_chip *chip, unsigned int offset,
|
static int gpio_fwd_set_config(struct gpio_chip *chip, unsigned int offset,
|
||||||
@@ -470,9 +486,9 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struct device *dev,
|
|||||||
chip->direction_input = gpio_fwd_direction_input;
|
chip->direction_input = gpio_fwd_direction_input;
|
||||||
chip->direction_output = gpio_fwd_direction_output;
|
chip->direction_output = gpio_fwd_direction_output;
|
||||||
chip->get = gpio_fwd_get;
|
chip->get = gpio_fwd_get;
|
||||||
chip->get_multiple = gpio_fwd_get_multiple;
|
chip->get_multiple = gpio_fwd_get_multiple_locked;
|
||||||
chip->set = gpio_fwd_set;
|
chip->set = gpio_fwd_set;
|
||||||
chip->set_multiple = gpio_fwd_set_multiple;
|
chip->set_multiple = gpio_fwd_set_multiple_locked;
|
||||||
chip->base = -1;
|
chip->base = -1;
|
||||||
chip->ngpio = ngpios;
|
chip->ngpio = ngpios;
|
||||||
fwd->descs = descs;
|
fwd->descs = descs;
|
||||||
|
|||||||
Reference in New Issue
Block a user