2016-07-20 17:11:36 +03:00
/*
2017-12-05 17:46:41 +03:00
* AXP20x pinctrl and GPIO driver
2016-07-20 17:11:36 +03:00
*
* Copyright ( C ) 2016 Maxime Ripard < maxime . ripard @ free - electrons . com >
2017-12-05 17:46:41 +03:00
* Copyright ( C ) 2017 Quentin Schulz < quentin . schulz @ free - electrons . com >
2016-07-20 17:11:36 +03:00
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation ; either version 2 of the License , or ( at your
* option ) any later version .
*/
# include <linux/bitops.h>
# include <linux/device.h>
# include <linux/gpio/driver.h>
# include <linux/init.h>
# include <linux/interrupt.h>
# include <linux/kernel.h>
# include <linux/mfd/axp20x.h>
# include <linux/module.h>
# include <linux/of.h>
2017-12-05 17:46:46 +03:00
# include <linux/of_device.h>
2017-12-05 17:46:41 +03:00
# include <linux/pinctrl/pinconf-generic.h>
# include <linux/pinctrl/pinctrl.h>
# include <linux/pinctrl/pinmux.h>
2016-07-20 17:11:36 +03:00
# include <linux/platform_device.h>
# include <linux/regmap.h>
# include <linux/slab.h>
# define AXP20X_GPIO_FUNCTIONS 0x7
# define AXP20X_GPIO_FUNCTION_OUT_LOW 0
# define AXP20X_GPIO_FUNCTION_OUT_HIGH 1
# define AXP20X_GPIO_FUNCTION_INPUT 2
2017-12-05 17:46:41 +03:00
# define AXP20X_FUNC_GPIO_OUT 0
# define AXP20X_FUNC_GPIO_IN 1
# define AXP20X_FUNC_LDO 2
# define AXP20X_FUNC_ADC 3
# define AXP20X_FUNCS_NB 4
# define AXP20X_MUX_GPIO_OUT 0
# define AXP20X_MUX_GPIO_IN BIT(1)
# define AXP20X_MUX_ADC BIT(2)
2017-12-05 17:46:46 +03:00
# define AXP813_MUX_ADC (BIT(2) | BIT(0))
2017-12-05 17:46:41 +03:00
struct axp20x_pctrl_desc {
const struct pinctrl_pin_desc * pins ;
unsigned int npins ;
/* Stores the pins supporting LDO function. Bit offset is pin number. */
u8 ldo_mask ;
/* Stores the pins supporting ADC function. Bit offset is pin number. */
u8 adc_mask ;
2017-12-05 17:46:44 +03:00
u8 gpio_status_offset ;
2017-12-05 17:46:45 +03:00
u8 adc_mux ;
2017-12-05 17:46:41 +03:00
} ;
struct axp20x_pinctrl_function {
const char * name ;
unsigned int muxval ;
const char * * groups ;
unsigned int ngroups ;
} ;
2017-12-05 17:46:43 +03:00
struct axp20x_pctl {
2016-07-20 17:11:36 +03:00
struct gpio_chip chip ;
struct regmap * regmap ;
2017-12-05 17:46:41 +03:00
struct pinctrl_dev * pctl_dev ;
struct device * dev ;
const struct axp20x_pctrl_desc * desc ;
struct axp20x_pinctrl_function funcs [ AXP20X_FUNCS_NB ] ;
} ;
static const struct pinctrl_pin_desc axp209_pins [ ] = {
PINCTRL_PIN ( 0 , " GPIO0 " ) ,
PINCTRL_PIN ( 1 , " GPIO1 " ) ,
PINCTRL_PIN ( 2 , " GPIO2 " ) ,
} ;
2017-12-05 17:46:46 +03:00
static const struct pinctrl_pin_desc axp813_pins [ ] = {
PINCTRL_PIN ( 0 , " GPIO0 " ) ,
PINCTRL_PIN ( 1 , " GPIO1 " ) ,
} ;
2017-12-05 17:46:41 +03:00
static const struct axp20x_pctrl_desc axp20x_data = {
. pins = axp209_pins ,
. npins = ARRAY_SIZE ( axp209_pins ) ,
. ldo_mask = BIT ( 0 ) | BIT ( 1 ) ,
. adc_mask = BIT ( 0 ) | BIT ( 1 ) ,
2017-12-05 17:46:44 +03:00
. gpio_status_offset = 4 ,
2017-12-05 17:46:45 +03:00
. adc_mux = AXP20X_MUX_ADC ,
2016-07-20 17:11:36 +03:00
} ;
2017-12-05 17:46:46 +03:00
static const struct axp20x_pctrl_desc axp813_data = {
. pins = axp813_pins ,
. npins = ARRAY_SIZE ( axp813_pins ) ,
. ldo_mask = BIT ( 0 ) | BIT ( 1 ) ,
. adc_mask = BIT ( 0 ) ,
. gpio_status_offset = 0 ,
. adc_mux = AXP813_MUX_ADC ,
} ;
2017-12-05 17:46:39 +03:00
static int axp20x_gpio_get_reg ( unsigned int offset )
2016-07-20 17:11:36 +03:00
{
switch ( offset ) {
case 0 :
return AXP20X_GPIO0_CTRL ;
case 1 :
return AXP20X_GPIO1_CTRL ;
case 2 :
return AXP20X_GPIO2_CTRL ;
}
return - EINVAL ;
}
2017-12-05 17:46:39 +03:00
static int axp20x_gpio_input ( struct gpio_chip * chip , unsigned int offset )
2016-07-20 17:11:36 +03:00
{
2017-12-05 17:46:41 +03:00
return pinctrl_gpio_direction_input ( chip - > base + offset ) ;
2016-07-20 17:11:36 +03:00
}
2017-12-05 17:46:39 +03:00
static int axp20x_gpio_get ( struct gpio_chip * chip , unsigned int offset )
2016-07-20 17:11:36 +03:00
{
2017-12-05 17:46:43 +03:00
struct axp20x_pctl * pctl = gpiochip_get_data ( chip ) ;
2016-07-20 17:11:36 +03:00
unsigned int val ;
2016-11-23 17:11:50 +03:00
int ret ;
2016-07-20 17:11:36 +03:00
2017-12-05 17:46:43 +03:00
ret = regmap_read ( pctl - > regmap , AXP20X_GPIO20_SS , & val ) ;
2016-07-20 17:11:36 +03:00
if ( ret )
return ret ;
2017-12-05 17:46:44 +03:00
return ! ! ( val & BIT ( offset + pctl - > desc - > gpio_status_offset ) ) ;
2016-07-20 17:11:36 +03:00
}
2017-12-05 17:46:39 +03:00
static int axp20x_gpio_get_direction ( struct gpio_chip * chip ,
unsigned int offset )
2016-09-21 23:51:22 +03:00
{
2017-12-05 17:46:43 +03:00
struct axp20x_pctl * pctl = gpiochip_get_data ( chip ) ;
2016-09-21 23:51:22 +03:00
unsigned int val ;
int reg , ret ;
reg = axp20x_gpio_get_reg ( offset ) ;
if ( reg < 0 )
return reg ;
2017-12-05 17:46:43 +03:00
ret = regmap_read ( pctl - > regmap , reg , & val ) ;
2016-09-21 23:51:22 +03:00
if ( ret )
return ret ;
/*
* This shouldn ' t really happen if the pin is in use already ,
* or if it ' s not in use yet , it doesn ' t matter since we ' re
* going to change the value soon anyway . Default to output .
*/
if ( ( val & AXP20X_GPIO_FUNCTIONS ) > 2 )
return 0 ;
/*
* The GPIO directions are the three lowest values .
* 2 is input , 0 and 1 are output
*/
return val & 2 ;
}
2017-12-05 17:46:39 +03:00
static int axp20x_gpio_output ( struct gpio_chip * chip , unsigned int offset ,
2016-07-20 17:11:36 +03:00
int value )
2017-12-05 17:46:41 +03:00
{
chip - > set ( chip , offset , value ) ;
return 0 ;
}
static void axp20x_gpio_set ( struct gpio_chip * chip , unsigned int offset ,
int value )
2016-07-20 17:11:36 +03:00
{
2017-12-05 17:46:43 +03:00
struct axp20x_pctl * pctl = gpiochip_get_data ( chip ) ;
2016-07-20 17:11:36 +03:00
int reg ;
2017-12-05 17:46:41 +03:00
reg = axp20x_gpio_get_reg ( offset ) ;
if ( reg < 0 )
return ;
2017-12-05 17:46:43 +03:00
regmap_update_bits ( pctl - > regmap , reg ,
2017-12-05 17:46:41 +03:00
AXP20X_GPIO_FUNCTIONS ,
value ? AXP20X_GPIO_FUNCTION_OUT_HIGH :
AXP20X_GPIO_FUNCTION_OUT_LOW ) ;
}
static int axp20x_pmx_set ( struct pinctrl_dev * pctldev , unsigned int offset ,
u8 config )
{
2017-12-05 17:46:43 +03:00
struct axp20x_pctl * pctl = pinctrl_dev_get_drvdata ( pctldev ) ;
2017-12-05 17:46:41 +03:00
int reg ;
2016-07-20 17:11:36 +03:00
reg = axp20x_gpio_get_reg ( offset ) ;
if ( reg < 0 )
return reg ;
2017-12-05 17:46:43 +03:00
return regmap_update_bits ( pctl - > regmap , reg , AXP20X_GPIO_FUNCTIONS ,
2017-12-05 17:46:41 +03:00
config ) ;
2016-07-20 17:11:36 +03:00
}
2017-12-05 17:46:41 +03:00
static int axp20x_pmx_func_cnt ( struct pinctrl_dev * pctldev )
{
2017-12-05 17:46:43 +03:00
struct axp20x_pctl * pctl = pinctrl_dev_get_drvdata ( pctldev ) ;
2017-12-05 17:46:41 +03:00
2017-12-05 17:46:43 +03:00
return ARRAY_SIZE ( pctl - > funcs ) ;
2017-12-05 17:46:41 +03:00
}
static const char * axp20x_pmx_func_name ( struct pinctrl_dev * pctldev ,
unsigned int selector )
{
2017-12-05 17:46:43 +03:00
struct axp20x_pctl * pctl = pinctrl_dev_get_drvdata ( pctldev ) ;
2017-12-05 17:46:41 +03:00
2017-12-05 17:46:43 +03:00
return pctl - > funcs [ selector ] . name ;
2017-12-05 17:46:41 +03:00
}
static int axp20x_pmx_func_groups ( struct pinctrl_dev * pctldev ,
unsigned int selector ,
const char * const * * groups ,
unsigned int * num_groups )
{
2017-12-05 17:46:43 +03:00
struct axp20x_pctl * pctl = pinctrl_dev_get_drvdata ( pctldev ) ;
2017-12-05 17:46:41 +03:00
2017-12-05 17:46:43 +03:00
* groups = pctl - > funcs [ selector ] . groups ;
* num_groups = pctl - > funcs [ selector ] . ngroups ;
2017-12-05 17:46:41 +03:00
return 0 ;
}
static int axp20x_pmx_set_mux ( struct pinctrl_dev * pctldev ,
unsigned int function , unsigned int group )
{
2017-12-05 17:46:43 +03:00
struct axp20x_pctl * pctl = pinctrl_dev_get_drvdata ( pctldev ) ;
2017-12-05 17:46:41 +03:00
unsigned int mask ;
/* Every pin supports GPIO_OUT and GPIO_IN functions */
if ( function < = AXP20X_FUNC_GPIO_IN )
return axp20x_pmx_set ( pctldev , group ,
2017-12-05 17:46:43 +03:00
pctl - > funcs [ function ] . muxval ) ;
2017-12-05 17:46:41 +03:00
if ( function = = AXP20X_FUNC_LDO )
2017-12-05 17:46:43 +03:00
mask = pctl - > desc - > ldo_mask ;
2017-12-05 17:46:41 +03:00
else
2017-12-05 17:46:43 +03:00
mask = pctl - > desc - > adc_mask ;
2017-12-05 17:46:41 +03:00
if ( ! ( BIT ( group ) & mask ) )
return - EINVAL ;
/*
* We let the regulator framework handle the LDO muxing as muxing bits
* are basically also regulators on / off bits . It ' s better not to enforce
* any state of the regulator when selecting LDO mux so that we don ' t
* interfere with the regulator driver .
*/
if ( function = = AXP20X_FUNC_LDO )
return 0 ;
2017-12-05 17:46:43 +03:00
return axp20x_pmx_set ( pctldev , group , pctl - > funcs [ function ] . muxval ) ;
2017-12-05 17:46:41 +03:00
}
static int axp20x_pmx_gpio_set_direction ( struct pinctrl_dev * pctldev ,
struct pinctrl_gpio_range * range ,
unsigned int offset , bool input )
{
2017-12-05 17:46:43 +03:00
struct axp20x_pctl * pctl = pinctrl_dev_get_drvdata ( pctldev ) ;
2017-12-05 17:46:41 +03:00
if ( input )
return axp20x_pmx_set ( pctldev , offset ,
2017-12-05 17:46:43 +03:00
pctl - > funcs [ AXP20X_FUNC_GPIO_IN ] . muxval ) ;
2017-12-05 17:46:41 +03:00
return axp20x_pmx_set ( pctldev , offset ,
2017-12-05 17:46:43 +03:00
pctl - > funcs [ AXP20X_FUNC_GPIO_OUT ] . muxval ) ;
2017-12-05 17:46:41 +03:00
}
static const struct pinmux_ops axp20x_pmx_ops = {
. get_functions_count = axp20x_pmx_func_cnt ,
. get_function_name = axp20x_pmx_func_name ,
. get_function_groups = axp20x_pmx_func_groups ,
. set_mux = axp20x_pmx_set_mux ,
. gpio_set_direction = axp20x_pmx_gpio_set_direction ,
. strict = true ,
} ;
static int axp20x_groups_cnt ( struct pinctrl_dev * pctldev )
{
2017-12-05 17:46:43 +03:00
struct axp20x_pctl * pctl = pinctrl_dev_get_drvdata ( pctldev ) ;
2017-12-05 17:46:41 +03:00
2017-12-05 17:46:43 +03:00
return pctl - > desc - > npins ;
2017-12-05 17:46:41 +03:00
}
static int axp20x_group_pins ( struct pinctrl_dev * pctldev , unsigned int selector ,
const unsigned int * * pins , unsigned int * num_pins )
{
2017-12-05 17:46:43 +03:00
struct axp20x_pctl * pctl = pinctrl_dev_get_drvdata ( pctldev ) ;
2017-12-05 17:46:41 +03:00
2017-12-05 17:46:43 +03:00
* pins = ( unsigned int * ) & pctl - > desc - > pins [ selector ] ;
2017-12-05 17:46:41 +03:00
* num_pins = 1 ;
return 0 ;
}
static const char * axp20x_group_name ( struct pinctrl_dev * pctldev ,
unsigned int selector )
2016-07-20 17:11:36 +03:00
{
2017-12-05 17:46:43 +03:00
struct axp20x_pctl * pctl = pinctrl_dev_get_drvdata ( pctldev ) ;
2017-12-05 17:46:41 +03:00
2017-12-05 17:46:43 +03:00
return pctl - > desc - > pins [ selector ] . name ;
2017-12-05 17:46:41 +03:00
}
static const struct pinctrl_ops axp20x_pctrl_ops = {
. dt_node_to_map = pinconf_generic_dt_node_to_map_group ,
. dt_free_map = pinconf_generic_dt_free_map ,
. get_groups_count = axp20x_groups_cnt ,
. get_group_name = axp20x_group_name ,
. get_group_pins = axp20x_group_pins ,
} ;
2018-08-06 19:06:35 +03:00
static int axp20x_funcs_groups_from_mask ( struct device * dev , unsigned int mask ,
2017-12-05 17:46:41 +03:00
unsigned int mask_len ,
struct axp20x_pinctrl_function * func ,
const struct pinctrl_pin_desc * pins )
{
unsigned long int mask_cpy = mask ;
const char * * group ;
unsigned int ngroups = hweight8 ( mask ) ;
int bit ;
func - > ngroups = ngroups ;
if ( func - > ngroups > 0 ) {
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
func - > groups = devm_kcalloc ( dev ,
ngroups , sizeof ( const char * ) ,
2017-12-05 17:46:41 +03:00
GFP_KERNEL ) ;
2018-08-06 19:06:35 +03:00
if ( ! func - > groups )
return - ENOMEM ;
2017-12-05 17:46:41 +03:00
group = func - > groups ;
for_each_set_bit ( bit , & mask_cpy , mask_len ) {
* group = pins [ bit ] . name ;
group + + ;
}
}
2018-08-06 19:06:35 +03:00
return 0 ;
2017-12-05 17:46:41 +03:00
}
2018-08-06 19:06:35 +03:00
static int axp20x_build_funcs_groups ( struct platform_device * pdev )
2017-12-05 17:46:41 +03:00
{
2017-12-05 17:46:43 +03:00
struct axp20x_pctl * pctl = platform_get_drvdata ( pdev ) ;
2018-08-06 19:06:35 +03:00
int i , ret , pin , npins = pctl - > desc - > npins ;
2017-12-05 17:46:43 +03:00
pctl - > funcs [ AXP20X_FUNC_GPIO_OUT ] . name = " gpio_out " ;
pctl - > funcs [ AXP20X_FUNC_GPIO_OUT ] . muxval = AXP20X_MUX_GPIO_OUT ;
pctl - > funcs [ AXP20X_FUNC_GPIO_IN ] . name = " gpio_in " ;
pctl - > funcs [ AXP20X_FUNC_GPIO_IN ] . muxval = AXP20X_MUX_GPIO_IN ;
pctl - > funcs [ AXP20X_FUNC_LDO ] . name = " ldo " ;
2017-12-05 17:46:41 +03:00
/*
* Muxval for LDO is useless as we won ' t use it .
* See comment in axp20x_pmx_set_mux .
*/
2017-12-05 17:46:43 +03:00
pctl - > funcs [ AXP20X_FUNC_ADC ] . name = " adc " ;
2017-12-05 17:46:45 +03:00
pctl - > funcs [ AXP20X_FUNC_ADC ] . muxval = pctl - > desc - > adc_mux ;
2017-12-05 17:46:41 +03:00
/* Every pin supports GPIO_OUT and GPIO_IN functions */
for ( i = 0 ; i < = AXP20X_FUNC_GPIO_IN ; i + + ) {
2017-12-05 17:46:43 +03:00
pctl - > funcs [ i ] . ngroups = npins ;
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
pctl - > funcs [ i ] . groups = devm_kcalloc ( & pdev - > dev ,
npins , sizeof ( char * ) ,
2017-12-05 17:46:41 +03:00
GFP_KERNEL ) ;
for ( pin = 0 ; pin < npins ; pin + + )
2017-12-05 17:46:43 +03:00
pctl - > funcs [ i ] . groups [ pin ] = pctl - > desc - > pins [ pin ] . name ;
2017-12-05 17:46:41 +03:00
}
2018-08-06 19:06:35 +03:00
ret = axp20x_funcs_groups_from_mask ( & pdev - > dev , pctl - > desc - > ldo_mask ,
2017-12-05 17:46:43 +03:00
npins , & pctl - > funcs [ AXP20X_FUNC_LDO ] ,
pctl - > desc - > pins ) ;
2018-08-06 19:06:35 +03:00
if ( ret )
return ret ;
2017-12-05 17:46:41 +03:00
2018-08-06 19:06:35 +03:00
ret = axp20x_funcs_groups_from_mask ( & pdev - > dev , pctl - > desc - > adc_mask ,
2017-12-05 17:46:43 +03:00
npins , & pctl - > funcs [ AXP20X_FUNC_ADC ] ,
pctl - > desc - > pins ) ;
2018-08-06 19:06:35 +03:00
if ( ret )
return ret ;
return 0 ;
2016-07-20 17:11:36 +03:00
}
2017-12-05 17:46:46 +03:00
static const struct of_device_id axp20x_pctl_match [ ] = {
{ . compatible = " x-powers,axp209-gpio " , . data = & axp20x_data , } ,
{ . compatible = " x-powers,axp813-gpio " , . data = & axp813_data , } ,
{ }
} ;
MODULE_DEVICE_TABLE ( of , axp20x_pctl_match ) ;
2017-12-05 17:46:43 +03:00
static int axp20x_pctl_probe ( struct platform_device * pdev )
2016-07-20 17:11:36 +03:00
{
struct axp20x_dev * axp20x = dev_get_drvdata ( pdev - > dev . parent ) ;
2017-12-05 17:46:43 +03:00
struct axp20x_pctl * pctl ;
2017-12-05 17:46:46 +03:00
struct device * dev = & pdev - > dev ;
2017-12-05 17:46:41 +03:00
struct pinctrl_desc * pctrl_desc ;
2016-07-20 17:11:36 +03:00
int ret ;
if ( ! of_device_is_available ( pdev - > dev . of_node ) )
return - ENODEV ;
if ( ! axp20x ) {
dev_err ( & pdev - > dev , " Parent drvdata not set \n " ) ;
return - EINVAL ;
}
2017-12-05 17:46:43 +03:00
pctl = devm_kzalloc ( & pdev - > dev , sizeof ( * pctl ) , GFP_KERNEL ) ;
if ( ! pctl )
2016-07-20 17:11:36 +03:00
return - ENOMEM ;
2017-12-05 17:46:43 +03:00
pctl - > chip . base = - 1 ;
pctl - > chip . can_sleep = true ;
pctl - > chip . request = gpiochip_generic_request ;
pctl - > chip . free = gpiochip_generic_free ;
pctl - > chip . parent = & pdev - > dev ;
pctl - > chip . label = dev_name ( & pdev - > dev ) ;
pctl - > chip . owner = THIS_MODULE ;
pctl - > chip . get = axp20x_gpio_get ;
pctl - > chip . get_direction = axp20x_gpio_get_direction ;
pctl - > chip . set = axp20x_gpio_set ;
pctl - > chip . direction_input = axp20x_gpio_input ;
pctl - > chip . direction_output = axp20x_gpio_output ;
2018-01-02 16:28:04 +03:00
pctl - > desc = of_device_get_match_data ( dev ) ;
2017-12-13 11:55:03 +03:00
pctl - > chip . ngpio = pctl - > desc - > npins ;
2017-12-05 17:46:43 +03:00
pctl - > regmap = axp20x - > regmap ;
pctl - > dev = & pdev - > dev ;
platform_set_drvdata ( pdev , pctl ) ;
2017-12-05 17:46:41 +03:00
2018-08-06 19:06:35 +03:00
ret = axp20x_build_funcs_groups ( pdev ) ;
if ( ret ) {
dev_err ( & pdev - > dev , " failed to build groups \n " ) ;
return ret ;
}
2017-12-05 17:46:41 +03:00
pctrl_desc = devm_kzalloc ( & pdev - > dev , sizeof ( * pctrl_desc ) , GFP_KERNEL ) ;
if ( ! pctrl_desc )
return - ENOMEM ;
pctrl_desc - > name = dev_name ( & pdev - > dev ) ;
pctrl_desc - > owner = THIS_MODULE ;
2017-12-05 17:46:43 +03:00
pctrl_desc - > pins = pctl - > desc - > pins ;
pctrl_desc - > npins = pctl - > desc - > npins ;
2017-12-05 17:46:41 +03:00
pctrl_desc - > pctlops = & axp20x_pctrl_ops ;
pctrl_desc - > pmxops = & axp20x_pmx_ops ;
2017-12-05 17:46:43 +03:00
pctl - > pctl_dev = devm_pinctrl_register ( & pdev - > dev , pctrl_desc , pctl ) ;
if ( IS_ERR ( pctl - > pctl_dev ) ) {
2017-12-05 17:46:41 +03:00
dev_err ( & pdev - > dev , " couldn't register pinctrl driver \n " ) ;
2017-12-05 17:46:43 +03:00
return PTR_ERR ( pctl - > pctl_dev ) ;
2017-12-05 17:46:41 +03:00
}
2016-07-20 17:11:36 +03:00
2017-12-05 17:46:43 +03:00
ret = devm_gpiochip_add_data ( & pdev - > dev , & pctl - > chip , pctl ) ;
2016-07-20 17:11:36 +03:00
if ( ret ) {
dev_err ( & pdev - > dev , " Failed to register GPIO chip \n " ) ;
return ret ;
}
2017-12-05 17:46:43 +03:00
ret = gpiochip_add_pin_range ( & pctl - > chip , dev_name ( & pdev - > dev ) ,
pctl - > desc - > pins - > number ,
pctl - > desc - > pins - > number ,
pctl - > desc - > npins ) ;
2017-12-05 17:46:41 +03:00
if ( ret ) {
dev_err ( & pdev - > dev , " failed to add pin range \n " ) ;
return ret ;
}
dev_info ( & pdev - > dev , " AXP209 pinctrl and GPIO driver loaded \n " ) ;
2016-07-20 17:11:36 +03:00
return 0 ;
}
2017-12-05 17:46:43 +03:00
static struct platform_driver axp20x_pctl_driver = {
. probe = axp20x_pctl_probe ,
2016-07-20 17:11:36 +03:00
. driver = {
. name = " axp20x-gpio " ,
2017-12-05 17:46:43 +03:00
. of_match_table = axp20x_pctl_match ,
2016-07-20 17:11:36 +03:00
} ,
} ;
2017-12-05 17:46:43 +03:00
module_platform_driver ( axp20x_pctl_driver ) ;
2016-07-20 17:11:36 +03:00
MODULE_AUTHOR ( " Maxime Ripard <maxime.ripard@free-electrons.com> " ) ;
2017-12-05 17:46:41 +03:00
MODULE_AUTHOR ( " Quentin Schulz <quentin.schulz@free-electrons.com> " ) ;
MODULE_DESCRIPTION ( " AXP20x PMIC pinctrl and GPIO driver " ) ;
2016-07-20 17:11:36 +03:00
MODULE_LICENSE ( " GPL " ) ;