2018-09-07 05:13:29 +03:00
// SPDX-License-Identifier: GPL-2.0
2012-06-20 12:29:04 +04:00
/*
* SuperH Pin Function Controller GPIO driver .
*
* Copyright ( C ) 2008 Magnus Damm
* Copyright ( C ) 2009 - 2012 Paul Mundt
*/
2012-12-16 02:50:47 +04:00
2012-12-16 02:50:48 +04:00
# include <linux/device.h>
2019-08-14 10:20:32 +03:00
# include <linux/gpio/driver.h>
2012-12-16 02:50:52 +04:00
# include <linux/init.h>
2012-06-20 12:29:04 +04:00
# include <linux/module.h>
2012-07-10 07:08:14 +04:00
# include <linux/pinctrl/consumer.h>
2012-12-16 02:50:52 +04:00
# include <linux/slab.h>
# include <linux/spinlock.h>
2012-06-20 12:29:04 +04:00
2012-12-16 02:50:44 +04:00
# include "core.h"
2013-02-16 21:34:32 +04:00
struct sh_pfc_gpio_data_reg {
const struct pinmux_data_reg * info ;
2015-02-27 20:38:04 +03:00
u32 shadow ;
2013-02-16 21:34:32 +04:00
} ;
2013-03-08 20:43:54 +04:00
struct sh_pfc_gpio_pin {
u8 dbit ;
u8 dreg ;
} ;
2012-06-20 12:29:04 +04:00
struct sh_pfc_chip {
2013-03-08 20:43:54 +04:00
struct sh_pfc * pfc ;
struct gpio_chip gpio_chip ;
2013-02-17 03:26:33 +04:00
2013-03-08 20:43:54 +04:00
struct sh_pfc_window * mem ;
2013-02-16 21:34:32 +04:00
struct sh_pfc_gpio_data_reg * regs ;
2013-03-08 20:43:54 +04:00
struct sh_pfc_gpio_pin * pins ;
2012-06-20 12:29:04 +04:00
} ;
static struct sh_pfc * gpio_to_pfc ( struct gpio_chip * gc )
{
2015-12-08 12:24:54 +03:00
struct sh_pfc_chip * chip = gpiochip_get_data ( gc ) ;
return chip - > pfc ;
2012-06-20 12:29:04 +04:00
}
2013-07-15 15:25:08 +04:00
static void gpio_get_data_reg ( struct sh_pfc_chip * chip , unsigned int offset ,
2013-02-16 21:34:32 +04:00
struct sh_pfc_gpio_data_reg * * reg ,
unsigned int * bit )
2013-02-15 05:04:55 +04:00
{
2013-07-15 15:25:08 +04:00
int idx = sh_pfc_get_pin_index ( chip - > pfc , offset ) ;
2013-03-08 20:43:54 +04:00
struct sh_pfc_gpio_pin * gpio_pin = & chip - > pins [ idx ] ;
2013-02-15 05:04:55 +04:00
2013-03-08 20:43:54 +04:00
* reg = & chip - > regs [ gpio_pin - > dreg ] ;
* bit = gpio_pin - > dbit ;
2013-02-15 05:04:55 +04:00
}
2015-02-27 20:38:04 +03:00
static u32 gpio_read_data_reg ( struct sh_pfc_chip * chip ,
const struct pinmux_data_reg * dreg )
2013-02-15 05:04:55 +04:00
{
2015-03-12 13:09:16 +03:00
phys_addr_t address = dreg - > reg ;
void __iomem * mem = address - chip - > mem - > phys + chip - > mem - > virt ;
2013-02-17 03:26:33 +04:00
return sh_pfc_read_raw_reg ( mem , dreg - > reg_width ) ;
}
2013-02-15 05:04:55 +04:00
2013-02-17 03:26:33 +04:00
static void gpio_write_data_reg ( struct sh_pfc_chip * chip ,
2015-02-27 20:38:04 +03:00
const struct pinmux_data_reg * dreg , u32 value )
2013-02-17 03:26:33 +04:00
{
2015-03-12 13:09:16 +03:00
phys_addr_t address = dreg - > reg ;
void __iomem * mem = address - chip - > mem - > phys + chip - > mem - > virt ;
2013-02-15 05:04:55 +04:00
2013-02-17 03:26:33 +04:00
sh_pfc_write_raw_reg ( mem , dreg - > reg_width , value ) ;
}
2013-02-15 05:04:55 +04:00
2013-07-15 15:25:08 +04:00
static void gpio_setup_data_reg ( struct sh_pfc_chip * chip , unsigned idx )
2013-02-17 03:26:33 +04:00
{
2013-03-08 20:43:54 +04:00
struct sh_pfc * pfc = chip - > pfc ;
2013-07-15 15:25:08 +04:00
struct sh_pfc_gpio_pin * gpio_pin = & chip - > pins [ idx ] ;
const struct sh_pfc_pin * pin = & pfc - > info - > pins [ idx ] ;
2013-02-17 03:26:33 +04:00
const struct pinmux_data_reg * dreg ;
unsigned int bit ;
unsigned int i ;
2013-02-15 05:04:55 +04:00
2015-03-12 13:09:15 +03:00
for ( i = 0 , dreg = pfc - > info - > data_regs ; dreg - > reg_width ; + + i , + + dreg ) {
2013-02-17 03:26:33 +04:00
for ( bit = 0 ; bit < dreg - > reg_width ; bit + + ) {
2013-03-08 20:43:54 +04:00
if ( dreg - > enum_ids [ bit ] = = pin - > enum_id ) {
gpio_pin - > dreg = i ;
gpio_pin - > dbit = bit ;
2013-02-15 05:04:55 +04:00
return ;
}
}
}
BUG ( ) ;
}
2013-02-17 03:26:33 +04:00
static int gpio_setup_data_regs ( struct sh_pfc_chip * chip )
2013-02-15 05:04:55 +04:00
{
2013-02-17 03:26:33 +04:00
struct sh_pfc * pfc = chip - > pfc ;
2013-02-16 21:34:32 +04:00
const struct pinmux_data_reg * dreg ;
2013-02-17 03:26:33 +04:00
unsigned int i ;
2013-02-15 05:04:55 +04:00
2013-02-16 21:34:32 +04:00
/* Count the number of data registers, allocate memory and initialize
* them .
*/
for ( i = 0 ; pfc - > info - > data_regs [ i ] . reg_width ; + + i )
;
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:07:58 +03:00
chip - > regs = devm_kcalloc ( pfc - > dev , i , sizeof ( * chip - > regs ) ,
2013-02-16 21:34:32 +04:00
GFP_KERNEL ) ;
if ( chip - > regs = = NULL )
return - ENOMEM ;
for ( i = 0 , dreg = pfc - > info - > data_regs ; dreg - > reg_width ; + + i , + + dreg ) {
chip - > regs [ i ] . info = dreg ;
chip - > regs [ i ] . shadow = gpio_read_data_reg ( chip , dreg ) ;
}
2013-02-15 05:04:55 +04:00
2013-02-17 03:26:33 +04:00
for ( i = 0 ; i < pfc - > info - > nr_pins ; i + + ) {
if ( pfc - > info - > pins [ i ] . enum_id = = 0 )
continue ;
2013-03-08 20:43:54 +04:00
gpio_setup_data_reg ( chip , i ) ;
2013-02-15 05:04:55 +04:00
}
2013-02-17 03:26:33 +04:00
return 0 ;
2013-02-15 05:04:55 +04:00
}
2012-12-06 17:49:25 +04:00
/* -----------------------------------------------------------------------------
* Pin GPIOs
*/
2012-06-20 12:29:04 +04:00
2012-12-06 17:49:25 +04:00
static int gpio_pin_request ( struct gpio_chip * gc , unsigned offset )
2012-06-20 12:29:04 +04:00
{
2013-02-15 01:12:11 +04:00
struct sh_pfc * pfc = gpio_to_pfc ( gc ) ;
2013-03-08 20:43:54 +04:00
int idx = sh_pfc_get_pin_index ( pfc , offset ) ;
2013-02-15 01:12:11 +04:00
2013-03-08 20:43:54 +04:00
if ( idx < 0 | | pfc - > info - > pins [ idx ] . enum_id = = 0 )
2013-02-15 01:12:11 +04:00
return - EINVAL ;
2017-09-22 12:02:10 +03:00
return pinctrl_gpio_request ( offset ) ;
2012-06-20 12:29:04 +04:00
}
2012-12-06 17:49:25 +04:00
static void gpio_pin_free ( struct gpio_chip * gc , unsigned offset )
2012-06-20 12:29:04 +04:00
{
2017-09-22 12:02:10 +03:00
return pinctrl_gpio_free ( offset ) ;
2012-06-20 12:29:04 +04:00
}
2013-02-17 03:26:33 +04:00
static void gpio_pin_set_value ( struct sh_pfc_chip * chip , unsigned offset ,
int value )
2012-06-20 12:29:04 +04:00
{
2013-02-16 21:34:32 +04:00
struct sh_pfc_gpio_data_reg * reg ;
2013-02-15 05:04:55 +04:00
unsigned int bit ;
2015-03-12 13:09:14 +03:00
unsigned int pos ;
2012-06-20 12:29:04 +04:00
2013-02-16 21:34:32 +04:00
gpio_get_data_reg ( chip , offset , & reg , & bit ) ;
2013-02-15 05:04:55 +04:00
2013-02-16 21:34:32 +04:00
pos = reg - > info - > reg_width - ( bit + 1 ) ;
2013-02-15 05:04:55 +04:00
if ( value )
2015-02-27 20:38:04 +03:00
reg - > shadow | = BIT ( pos ) ;
2013-02-15 05:04:55 +04:00
else
2015-02-27 20:38:04 +03:00
reg - > shadow & = ~ BIT ( pos ) ;
2013-02-15 05:04:55 +04:00
2013-02-16 21:34:32 +04:00
gpio_write_data_reg ( chip , reg - > info , reg - > shadow ) ;
2012-06-20 12:29:04 +04:00
}
2012-12-06 17:49:25 +04:00
static int gpio_pin_direction_input ( struct gpio_chip * gc , unsigned offset )
2012-07-10 07:08:14 +04:00
{
return pinctrl_gpio_direction_input ( offset ) ;
}
2012-12-06 17:49:25 +04:00
static int gpio_pin_direction_output ( struct gpio_chip * gc , unsigned offset ,
2012-07-10 07:08:14 +04:00
int value )
{
2015-12-08 12:24:54 +03:00
gpio_pin_set_value ( gpiochip_get_data ( gc ) , offset , value ) ;
2012-07-10 07:08:14 +04:00
return pinctrl_gpio_direction_output ( offset ) ;
}
2012-12-06 17:49:25 +04:00
static int gpio_pin_get ( struct gpio_chip * gc , unsigned offset )
2012-06-20 12:29:04 +04:00
{
2015-12-08 12:24:54 +03:00
struct sh_pfc_chip * chip = gpiochip_get_data ( gc ) ;
2013-02-16 21:34:32 +04:00
struct sh_pfc_gpio_data_reg * reg ;
2013-02-15 05:04:55 +04:00
unsigned int bit ;
2015-03-12 13:09:14 +03:00
unsigned int pos ;
2012-12-06 17:49:25 +04:00
2013-02-16 21:34:32 +04:00
gpio_get_data_reg ( chip , offset , & reg , & bit ) ;
2013-02-15 05:04:55 +04:00
2013-02-16 21:34:32 +04:00
pos = reg - > info - > reg_width - ( bit + 1 ) ;
2013-02-15 05:04:55 +04:00
2013-02-16 21:34:32 +04:00
return ( gpio_read_data_reg ( chip , reg - > info ) > > pos ) & 1 ;
2012-06-20 12:29:04 +04:00
}
2012-12-06 17:49:25 +04:00
static void gpio_pin_set ( struct gpio_chip * gc , unsigned offset , int value )
2012-06-20 12:29:04 +04:00
{
2015-12-08 12:24:54 +03:00
gpio_pin_set_value ( gpiochip_get_data ( gc ) , offset , value ) ;
2012-06-20 12:29:04 +04:00
}
2012-12-06 17:49:25 +04:00
static int gpio_pin_to_irq ( struct gpio_chip * gc , unsigned offset )
2012-06-20 12:29:04 +04:00
{
struct sh_pfc * pfc = gpio_to_pfc ( gc ) ;
2013-12-11 07:26:21 +04:00
unsigned int i , k ;
2013-01-03 17:12:14 +04:00
for ( i = 0 ; i < pfc - > info - > gpio_irq_size ; i + + ) {
2013-12-16 23:25:15 +04:00
const short * gpios = pfc - > info - > gpio_irq [ i ] . gpios ;
2013-01-03 17:12:14 +04:00
2013-12-11 07:26:22 +04:00
for ( k = 0 ; gpios [ k ] > = 0 ; k + + ) {
2013-01-03 17:12:14 +04:00
if ( gpios [ k ] = = offset )
2020-02-12 12:02:00 +03:00
return pfc - > irqs [ i ] ;
2012-06-20 12:29:04 +04:00
}
}
2016-05-04 11:21:53 +03:00
return 0 ;
2012-06-20 12:29:04 +04:00
}
2013-02-17 03:26:33 +04:00
static int gpio_pin_setup ( struct sh_pfc_chip * chip )
2012-06-20 12:29:04 +04:00
{
struct sh_pfc * pfc = chip - > pfc ;
struct gpio_chip * gc = & chip - > gpio_chip ;
2013-02-17 03:26:33 +04:00
int ret ;
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:07:58 +03:00
chip - > pins = devm_kcalloc ( pfc - > dev ,
pfc - > info - > nr_pins , sizeof ( * chip - > pins ) ,
GFP_KERNEL ) ;
2013-03-08 20:43:54 +04:00
if ( chip - > pins = = NULL )
return - ENOMEM ;
2013-02-17 03:26:33 +04:00
ret = gpio_setup_data_regs ( chip ) ;
if ( ret < 0 )
return ret ;
2012-06-20 12:29:04 +04:00
2012-12-06 17:49:25 +04:00
gc - > request = gpio_pin_request ;
gc - > free = gpio_pin_free ;
gc - > direction_input = gpio_pin_direction_input ;
gc - > get = gpio_pin_get ;
gc - > direction_output = gpio_pin_direction_output ;
gc - > set = gpio_pin_set ;
gc - > to_irq = gpio_pin_to_irq ;
2012-06-20 12:29:04 +04:00
2012-12-16 02:51:20 +04:00
gc - > label = pfc - > info - > name ;
2015-11-04 11:56:26 +03:00
gc - > parent = pfc - > dev ;
2012-06-20 12:29:04 +04:00
gc - > owner = THIS_MODULE ;
2012-11-28 20:51:00 +04:00
gc - > base = 0 ;
2013-07-15 15:48:56 +04:00
gc - > ngpio = pfc - > nr_gpio_pins ;
2013-02-17 03:26:33 +04:00
return 0 ;
2012-06-20 12:29:04 +04:00
}
2012-12-06 17:49:25 +04:00
/* -----------------------------------------------------------------------------
* Function GPIOs
*/
2019-01-21 19:05:45 +03:00
# ifdef CONFIG_PINCTRL_SH_FUNC_GPIO
2012-12-06 17:49:25 +04:00
static int gpio_function_request ( struct gpio_chip * gc , unsigned offset )
{
struct sh_pfc * pfc = gpio_to_pfc ( gc ) ;
2013-02-14 20:36:56 +04:00
unsigned int mark = pfc - > info - > func_gpios [ offset ] . enum_id ;
2012-12-06 17:49:25 +04:00
unsigned long flags ;
2013-03-10 19:38:23 +04:00
int ret ;
2012-12-06 17:49:25 +04:00
2019-07-31 12:41:16 +03:00
dev_notice_once ( pfc - > dev ,
" Use of GPIO API for function requests is deprecated, convert to pinctrl \n " ) ;
2012-12-06 17:49:25 +04:00
2013-02-14 20:36:56 +04:00
if ( mark = = 0 )
2013-03-10 19:38:23 +04:00
return - EINVAL ;
2012-12-06 17:49:25 +04:00
spin_lock_irqsave ( & pfc - > lock , flags ) ;
2013-03-10 19:38:23 +04:00
ret = sh_pfc_config_mux ( pfc , mark , PINMUX_TYPE_FUNCTION ) ;
2012-12-06 17:49:25 +04:00
spin_unlock_irqrestore ( & pfc - > lock , flags ) ;
2013-03-10 19:38:23 +04:00
2012-12-06 17:49:25 +04:00
return ret ;
}
2013-02-17 03:26:33 +04:00
static int gpio_function_setup ( struct sh_pfc_chip * chip )
2012-12-06 17:49:25 +04:00
{
struct sh_pfc * pfc = chip - > pfc ;
struct gpio_chip * gc = & chip - > gpio_chip ;
gc - > request = gpio_function_request ;
gc - > label = pfc - > info - > name ;
gc - > owner = THIS_MODULE ;
2013-07-15 15:48:56 +04:00
gc - > base = pfc - > nr_gpio_pins ;
2012-12-06 17:49:25 +04:00
gc - > ngpio = pfc - > info - > nr_func_gpios ;
2013-02-17 03:26:33 +04:00
return 0 ;
2012-12-06 17:49:25 +04:00
}
2019-01-21 19:05:45 +03:00
# endif /* CONFIG_PINCTRL_SH_FUNC_GPIO */
2012-12-06 17:49:25 +04:00
/* -----------------------------------------------------------------------------
* Register / unregister
*/
static struct sh_pfc_chip *
2013-03-10 06:19:44 +04:00
sh_pfc_add_gpiochip ( struct sh_pfc * pfc , int ( * setup ) ( struct sh_pfc_chip * ) ,
struct sh_pfc_window * mem )
2012-06-20 12:29:04 +04:00
{
struct sh_pfc_chip * chip ;
int ret ;
2012-12-16 02:50:48 +04:00
chip = devm_kzalloc ( pfc - > dev , sizeof ( * chip ) , GFP_KERNEL ) ;
2012-06-20 12:29:04 +04:00
if ( unlikely ( ! chip ) )
2012-12-06 17:49:25 +04:00
return ERR_PTR ( - ENOMEM ) ;
2012-06-20 12:29:04 +04:00
2013-03-10 06:19:44 +04:00
chip - > mem = mem ;
2012-06-20 12:29:04 +04:00
chip - > pfc = pfc ;
2013-02-17 03:26:33 +04:00
ret = setup ( chip ) ;
if ( ret < 0 )
return ERR_PTR ( ret ) ;
2012-06-20 12:29:04 +04:00
2016-06-10 12:22:44 +03:00
ret = devm_gpiochip_add_data ( pfc - > dev , & chip - > gpio_chip , chip ) ;
2012-12-16 02:50:48 +04:00
if ( unlikely ( ret < 0 ) )
2012-12-06 17:49:25 +04:00
return ERR_PTR ( ret ) ;
2013-03-10 21:00:02 +04:00
dev_info ( pfc - > dev , " %s handling gpio %u -> %u \n " ,
chip - > gpio_chip . label , chip - > gpio_chip . base ,
chip - > gpio_chip . base + chip - > gpio_chip . ngpio - 1 ) ;
2012-12-06 17:49:25 +04:00
return chip ;
}
int sh_pfc_register_gpiochip ( struct sh_pfc * pfc )
{
struct sh_pfc_chip * chip ;
2015-03-12 13:09:16 +03:00
phys_addr_t address ;
2013-02-15 04:33:38 +04:00
unsigned int i ;
2012-12-06 17:49:25 +04:00
2013-03-10 06:19:44 +04:00
if ( pfc - > info - > data_regs = = NULL )
return 0 ;
2020-10-28 18:16:31 +03:00
/* Find the memory window that contains the GPIO registers. Boards that
2013-03-10 06:19:44 +04:00
* register a separate GPIO device will not supply a memory resource
* that covers the data registers . In that case don ' t try to handle
* GPIOs .
*/
2015-03-12 13:09:16 +03:00
address = pfc - > info - > data_regs [ 0 ] . reg ;
2013-03-10 06:19:44 +04:00
for ( i = 0 ; i < pfc - > num_windows ; + + i ) {
2013-12-11 07:26:25 +04:00
struct sh_pfc_window * window = & pfc - > windows [ i ] ;
2013-03-10 06:19:44 +04:00
2015-03-12 13:09:16 +03:00
if ( address > = window - > phys & &
address < window - > phys + window - > size )
2013-03-10 06:19:44 +04:00
break ;
}
if ( i = = pfc - > num_windows )
return 0 ;
2013-12-11 07:26:26 +04:00
/* If we have IRQ resources make sure their number is correct. */
2015-09-22 10:08:13 +03:00
if ( pfc - > num_irqs ! = pfc - > info - > gpio_irq_size ) {
2013-12-11 07:26:26 +04:00
dev_err ( pfc - > dev , " invalid number of IRQ resources \n " ) ;
return - EINVAL ;
}
2013-02-15 04:33:38 +04:00
/* Register the real GPIOs chip. */
2013-12-11 07:26:25 +04:00
chip = sh_pfc_add_gpiochip ( pfc , gpio_pin_setup , & pfc - > windows [ i ] ) ;
2012-12-06 17:49:25 +04:00
if ( IS_ERR ( chip ) )
return PTR_ERR ( chip ) ;
2012-12-16 02:50:46 +04:00
pfc - > gpio = chip ;
2012-06-20 12:29:04 +04:00
2015-08-04 16:55:17 +03:00
if ( IS_ENABLED ( CONFIG_OF ) & & pfc - > dev - > of_node )
return 0 ;
2013-07-15 23:10:54 +04:00
2019-01-21 19:05:45 +03:00
# ifdef CONFIG_PINCTRL_SH_FUNC_GPIO
2015-08-27 23:07:23 +03:00
/*
* Register the GPIO to pin mappings . As pins with GPIO ports
* must come first in the ranges , skip the pins without GPIO
* ports by stopping at the first range that contains such a
* pin .
*/
for ( i = 0 ; i < pfc - > nr_ranges ; + + i ) {
const struct sh_pfc_pin_range * range = & pfc - > ranges [ i ] ;
int ret ;
if ( range - > start > = pfc - > nr_gpio_pins )
break ;
ret = gpiochip_add_pin_range ( & chip - > gpio_chip ,
dev_name ( pfc - > dev ) , range - > start , range - > start ,
range - > end - range - > start + 1 ) ;
if ( ret < 0 )
return ret ;
2013-02-15 04:33:38 +04:00
}
2013-03-08 03:45:12 +04:00
2013-02-15 04:33:38 +04:00
/* Register the function GPIOs chip. */
2019-11-13 13:18:09 +03:00
if ( pfc - > info - > nr_func_gpios ) {
chip = sh_pfc_add_gpiochip ( pfc , gpio_function_setup , NULL ) ;
if ( IS_ERR ( chip ) )
return PTR_ERR ( chip ) ;
}
2019-01-21 19:05:45 +03:00
# endif /* CONFIG_PINCTRL_SH_FUNC_GPIO */
2012-06-20 12:29:04 +04:00
return 0 ;
}