2019-05-30 02:57:46 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2012-08-28 14:44:59 +04:00
/*
* linux / drivers / pinctrl / pinctrl - lantiq . c
* based on linux / drivers / pinctrl / pinctrl - pxa3xx . c
*
2016-12-20 21:55:41 +03:00
* Copyright ( C ) 2012 John Crispin < john @ phrozen . org >
2012-08-28 14:44:59 +04:00
*/
# include <linux/module.h>
# include <linux/device.h>
# include <linux/io.h>
# include <linux/platform_device.h>
# include <linux/slab.h>
# include <linux/of.h>
# include "pinctrl-lantiq.h"
static int ltq_get_group_count ( struct pinctrl_dev * pctrldev )
{
struct ltq_pinmux_info * info = pinctrl_dev_get_drvdata ( pctrldev ) ;
return info - > num_grps ;
}
static const char * ltq_get_group_name ( struct pinctrl_dev * pctrldev ,
unsigned selector )
{
struct ltq_pinmux_info * info = pinctrl_dev_get_drvdata ( pctrldev ) ;
if ( selector > = info - > num_grps )
return NULL ;
return info - > grps [ selector ] . name ;
}
static int ltq_get_group_pins ( struct pinctrl_dev * pctrldev ,
unsigned selector ,
const unsigned * * pins ,
unsigned * num_pins )
{
struct ltq_pinmux_info * info = pinctrl_dev_get_drvdata ( pctrldev ) ;
if ( selector > = info - > num_grps )
return - EINVAL ;
* pins = info - > grps [ selector ] . pins ;
* num_pins = info - > grps [ selector ] . npins ;
return 0 ;
}
2012-11-07 20:10:17 +04:00
static void ltq_pinctrl_dt_free_map ( struct pinctrl_dev * pctldev ,
struct pinctrl_map * map , unsigned num_maps )
2012-08-28 14:44:59 +04:00
{
int i ;
for ( i = 0 ; i < num_maps ; i + + )
2013-05-14 19:00:38 +04:00
if ( map [ i ] . type = = PIN_MAP_TYPE_CONFIGS_PIN | |
map [ i ] . type = = PIN_MAP_TYPE_CONFIGS_GROUP )
2012-08-28 14:44:59 +04:00
kfree ( map [ i ] . data . configs . configs ) ;
kfree ( map ) ;
}
static void ltq_pinctrl_pin_dbg_show ( struct pinctrl_dev * pctldev ,
struct seq_file * s ,
unsigned offset )
{
seq_printf ( s , " %s " , dev_name ( pctldev - > dev ) ) ;
}
2013-02-01 16:04:57 +04:00
static void ltq_pinctrl_dt_subnode_to_map ( struct pinctrl_dev * pctldev ,
2012-08-28 14:44:59 +04:00
struct device_node * np ,
struct pinctrl_map * * map )
{
struct ltq_pinmux_info * info = pinctrl_dev_get_drvdata ( pctldev ) ;
2013-02-01 16:04:57 +04:00
struct property * pins = of_find_property ( np , " lantiq,pins " , NULL ) ;
struct property * groups = of_find_property ( np , " lantiq,groups " , NULL ) ;
2012-08-28 14:44:59 +04:00
unsigned long configs [ 3 ] ;
unsigned num_configs = 0 ;
struct property * prop ;
const char * group , * pin ;
const char * function ;
int ret , i ;
2013-02-01 16:04:57 +04:00
if ( ! pins & & ! groups ) {
2018-08-28 04:52:41 +03:00
dev_err ( pctldev - > dev , " %pOFn defines neither pins nor groups \n " ,
np ) ;
2013-02-01 16:04:57 +04:00
return ;
}
if ( pins & & groups ) {
2018-08-28 04:52:41 +03:00
dev_err ( pctldev - > dev , " %pOFn defines both pins and groups \n " ,
np ) ;
2013-02-01 16:04:57 +04:00
return ;
}
2012-08-28 14:44:59 +04:00
ret = of_property_read_string ( np , " lantiq,function " , & function ) ;
2013-02-01 16:04:57 +04:00
if ( groups & & ! ret ) {
2012-08-28 14:44:59 +04:00
of_property_for_each_string ( np , " lantiq,groups " , prop , group ) {
( * map ) - > type = PIN_MAP_TYPE_MUX_GROUP ;
( * map ) - > name = function ;
( * map ) - > data . mux . group = group ;
( * map ) - > data . mux . function = function ;
( * map ) + + ;
}
}
for ( i = 0 ; i < info - > num_params ; i + + ) {
u32 val ;
int ret = of_property_read_u32 ( np ,
info - > params [ i ] . property , & val ) ;
if ( ! ret )
configs [ num_configs + + ] =
LTQ_PINCONF_PACK ( info - > params [ i ] . param ,
val ) ;
}
if ( ! num_configs )
2013-02-01 16:04:57 +04:00
return ;
2012-08-28 14:44:59 +04:00
of_property_for_each_string ( np , " lantiq,pins " , prop , pin ) {
( * map ) - > data . configs . configs = kmemdup ( configs ,
num_configs * sizeof ( unsigned long ) ,
GFP_KERNEL ) ;
( * map ) - > type = PIN_MAP_TYPE_CONFIGS_PIN ;
( * map ) - > name = pin ;
( * map ) - > data . configs . group_or_pin = pin ;
( * map ) - > data . configs . num_configs = num_configs ;
( * map ) + + ;
}
2013-02-01 16:04:57 +04:00
of_property_for_each_string ( np , " lantiq,groups " , prop , group ) {
( * map ) - > data . configs . configs = kmemdup ( configs ,
num_configs * sizeof ( unsigned long ) ,
GFP_KERNEL ) ;
( * map ) - > type = PIN_MAP_TYPE_CONFIGS_GROUP ;
( * map ) - > name = group ;
( * map ) - > data . configs . group_or_pin = group ;
( * map ) - > data . configs . num_configs = num_configs ;
( * map ) + + ;
}
2012-08-28 14:44:59 +04:00
}
static int ltq_pinctrl_dt_subnode_size ( struct device_node * np )
{
int ret ;
ret = of_property_count_strings ( np , " lantiq,groups " ) ;
if ( ret < 0 )
ret = of_property_count_strings ( np , " lantiq,pins " ) ;
return ret ;
}
2012-11-07 20:10:17 +04:00
static int ltq_pinctrl_dt_node_to_map ( struct pinctrl_dev * pctldev ,
struct device_node * np_config ,
struct pinctrl_map * * map ,
unsigned * num_maps )
2012-08-28 14:44:59 +04:00
{
struct pinctrl_map * tmp ;
struct device_node * np ;
2013-02-01 16:04:57 +04:00
int max_maps = 0 ;
2012-08-28 14:44:59 +04:00
for_each_child_of_node ( np_config , np )
2013-02-01 16:04:57 +04:00
max_maps + = ltq_pinctrl_dt_subnode_size ( np ) ;
treewide: kzalloc() -> kcalloc()
The kzalloc() function has a 2-factor argument form, kcalloc(). This
patch replaces cases of:
kzalloc(a * b, gfp)
with:
kcalloc(a * b, gfp)
as well as handling cases of:
kzalloc(a * b * c, gfp)
with:
kzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kzalloc_array(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kzalloc(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.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kzalloc
+ kcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- 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 E1, E2, E3;
constant C1, C2, C3;
@@
(
kzalloc(C1 * C2 * C3, ...)
|
kzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- 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 THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kzalloc(sizeof(THING) * C2, ...)
|
kzalloc(sizeof(TYPE) * C2, ...)
|
kzalloc(C1 * C2 * C3, ...)
|
kzalloc(C1 * C2, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kzalloc
+ kcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kzalloc
+ kcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:03:40 +03:00
* map = kzalloc ( array3_size ( max_maps , sizeof ( struct pinctrl_map ) , 2 ) ,
GFP_KERNEL ) ;
2012-08-28 14:44:59 +04:00
if ( ! * map )
return - ENOMEM ;
tmp = * map ;
2013-02-01 16:04:57 +04:00
for_each_child_of_node ( np_config , np )
ltq_pinctrl_dt_subnode_to_map ( pctldev , np , & tmp ) ;
* num_maps = ( ( int ) ( tmp - * map ) ) ;
2012-08-28 14:44:59 +04:00
return 0 ;
}
2013-02-16 13:25:07 +04:00
static const struct pinctrl_ops ltq_pctrl_ops = {
2012-08-28 14:44:59 +04:00
. get_groups_count = ltq_get_group_count ,
. get_group_name = ltq_get_group_name ,
. get_group_pins = ltq_get_group_pins ,
. pin_dbg_show = ltq_pinctrl_pin_dbg_show ,
. dt_node_to_map = ltq_pinctrl_dt_node_to_map ,
. dt_free_map = ltq_pinctrl_dt_free_map ,
} ;
static int ltq_pmx_func_count ( struct pinctrl_dev * pctrldev )
{
struct ltq_pinmux_info * info = pinctrl_dev_get_drvdata ( pctrldev ) ;
return info - > num_funcs ;
}
static const char * ltq_pmx_func_name ( struct pinctrl_dev * pctrldev ,
unsigned selector )
{
struct ltq_pinmux_info * info = pinctrl_dev_get_drvdata ( pctrldev ) ;
if ( selector > = info - > num_funcs )
return NULL ;
return info - > funcs [ selector ] . name ;
}
static int ltq_pmx_get_groups ( struct pinctrl_dev * pctrldev ,
unsigned func ,
const char * const * * groups ,
unsigned * const num_groups )
{
struct ltq_pinmux_info * info = pinctrl_dev_get_drvdata ( pctrldev ) ;
* groups = info - > funcs [ func ] . groups ;
* num_groups = info - > funcs [ func ] . num_groups ;
return 0 ;
}
/* Return function number. If failure, return negative value. */
static int match_mux ( const struct ltq_mfp_pin * mfp , unsigned mux )
{
int i ;
for ( i = 0 ; i < LTQ_MAX_MUX ; i + + ) {
if ( mfp - > func [ i ] = = mux )
break ;
}
if ( i > = LTQ_MAX_MUX )
return - EINVAL ;
return i ;
}
2020-04-21 17:24:02 +03:00
/* don't assume .mfp is linearly mapped. find the mfp with the correct .pin */
2012-08-28 14:44:59 +04:00
static int match_mfp ( const struct ltq_pinmux_info * info , int pin )
{
int i ;
for ( i = 0 ; i < info - > num_mfp ; i + + ) {
if ( info - > mfp [ i ] . pin = = pin )
return i ;
}
return - 1 ;
}
/* check whether current pin configuration is valid. Negative for failure */
static int match_group_mux ( const struct ltq_pin_group * grp ,
const struct ltq_pinmux_info * info ,
unsigned mux )
{
int i , pin , ret = 0 ;
for ( i = 0 ; i < grp - > npins ; i + + ) {
pin = match_mfp ( info , grp - > pins [ i ] ) ;
if ( pin < 0 ) {
dev_err ( info - > dev , " could not find mfp for pin %d \n " ,
grp - > pins [ i ] ) ;
return - EINVAL ;
}
ret = match_mux ( & info - > mfp [ pin ] , mux ) ;
if ( ret < 0 ) {
dev_err ( info - > dev , " Can't find mux %d on pin%d \n " ,
mux , pin ) ;
break ;
}
}
return ret ;
}
2014-09-03 15:02:56 +04:00
static int ltq_pmx_set ( struct pinctrl_dev * pctrldev ,
unsigned func ,
unsigned group )
2012-08-28 14:44:59 +04:00
{
struct ltq_pinmux_info * info = pinctrl_dev_get_drvdata ( pctrldev ) ;
const struct ltq_pin_group * pin_grp = & info - > grps [ group ] ;
int i , pin , pin_func , ret ;
if ( ! pin_grp - > npins | |
( match_group_mux ( pin_grp , info , pin_grp - > mux ) < 0 ) ) {
dev_err ( info - > dev , " Failed to set the pin group: %s \n " ,
info - > grps [ group ] . name ) ;
return - EINVAL ;
}
for ( i = 0 ; i < pin_grp - > npins ; i + + ) {
pin = match_mfp ( info , pin_grp - > pins [ i ] ) ;
if ( pin < 0 ) {
dev_err ( info - > dev , " could not find mfp for pin %d \n " ,
pin_grp - > pins [ i ] ) ;
return - EINVAL ;
}
pin_func = match_mux ( & info - > mfp [ pin ] , pin_grp - > mux ) ;
ret = info - > apply_mux ( pctrldev , pin , pin_func ) ;
if ( ret ) {
dev_err ( info - > dev ,
" failed to apply mux %d for pin %d \n " ,
pin_func , pin ) ;
return ret ;
}
}
return 0 ;
}
static int ltq_pmx_gpio_request_enable ( struct pinctrl_dev * pctrldev ,
struct pinctrl_gpio_range * range ,
unsigned pin )
{
struct ltq_pinmux_info * info = pinctrl_dev_get_drvdata ( pctrldev ) ;
2013-02-01 16:05:05 +04:00
int mfp = match_mfp ( info , pin ) ;
2012-08-28 14:44:59 +04:00
int pin_func ;
if ( mfp < 0 ) {
dev_err ( info - > dev , " could not find mfp for pin %d \n " , pin ) ;
return - EINVAL ;
}
pin_func = match_mux ( & info - > mfp [ mfp ] , 0 ) ;
if ( pin_func < 0 ) {
dev_err ( info - > dev , " No GPIO function on pin%d \n " , mfp ) ;
return - EINVAL ;
}
return info - > apply_mux ( pctrldev , mfp , pin_func ) ;
}
2013-02-16 13:25:07 +04:00
static const struct pinmux_ops ltq_pmx_ops = {
2012-08-28 14:44:59 +04:00
. get_functions_count = ltq_pmx_func_count ,
. get_function_name = ltq_pmx_func_name ,
. get_function_groups = ltq_pmx_get_groups ,
2014-09-03 15:02:56 +04:00
. set_mux = ltq_pmx_set ,
2012-08-28 14:44:59 +04:00
. gpio_request_enable = ltq_pmx_gpio_request_enable ,
} ;
/*
* allow different socs to register with the generic part of the lanti
* pinctrl code
*/
int ltq_pinctrl_register ( struct platform_device * pdev ,
struct ltq_pinmux_info * info )
{
struct pinctrl_desc * desc ;
if ( ! info )
return - EINVAL ;
desc = info - > desc ;
desc - > pctlops = & ltq_pctrl_ops ;
desc - > pmxops = & ltq_pmx_ops ;
info - > dev = & pdev - > dev ;
2016-02-24 12:14:07 +03:00
info - > pctrl = devm_pinctrl_register ( & pdev - > dev , desc , info ) ;
2015-06-09 07:01:16 +03:00
if ( IS_ERR ( info - > pctrl ) ) {
2012-08-28 14:44:59 +04:00
dev_err ( & pdev - > dev , " failed to register LTQ pinmux driver \n " ) ;
2015-06-09 07:01:16 +03:00
return PTR_ERR ( info - > pctrl ) ;
2012-08-28 14:44:59 +04:00
}
platform_set_drvdata ( pdev , info ) ;
return 0 ;
}