2018-09-07 05:13:29 +03:00
// SPDX-License-Identifier: GPL-2.0
2012-07-10 07:08:14 +04:00
/*
* SuperH Pin Function Controller pinmux support .
*
* Copyright ( C ) 2012 Paul Mundt
*/
2012-07-20 11:18:21 +04:00
2012-12-16 02:50:47 +04:00
# define DRV_NAME "sh-pfc"
2012-07-10 07:08:14 +04:00
2012-12-16 02:50:48 +04:00
# include <linux/device.h>
2012-12-16 02:50:52 +04:00
# include <linux/err.h>
2012-07-10 07:08:14 +04:00
# include <linux/init.h>
# include <linux/module.h>
2013-06-17 22:50:02 +04:00
# include <linux/of.h>
2012-07-10 07:08:14 +04:00
# include <linux/pinctrl/consumer.h>
2013-06-17 22:50:02 +04:00
# include <linux/pinctrl/machine.h>
2012-07-10 07:08:14 +04:00
# include <linux/pinctrl/pinconf.h>
# include <linux/pinctrl/pinconf-generic.h>
2012-12-16 02:50:52 +04:00
# include <linux/pinctrl/pinctrl.h>
# include <linux/pinctrl/pinmux.h>
# include <linux/slab.h>
# include <linux/spinlock.h>
2012-07-10 07:08:14 +04:00
2012-12-16 02:50:44 +04:00
# include "core.h"
2013-03-10 19:44:02 +04:00
# include "../core.h"
# include "../pinconf.h"
2012-12-16 02:50:44 +04:00
2013-03-08 20:43:54 +04:00
struct sh_pfc_pin_config {
u32 type ;
} ;
2012-07-10 07:08:14 +04:00
struct sh_pfc_pinctrl {
struct pinctrl_dev * pctl ;
2013-02-16 19:38:30 +04:00
struct pinctrl_desc pctl_desc ;
2012-07-10 07:08:14 +04:00
struct sh_pfc * pfc ;
2013-01-03 17:33:13 +04:00
struct pinctrl_pin_desc * pins ;
2013-03-08 20:43:54 +04:00
struct sh_pfc_pin_config * configs ;
2015-06-30 11:29:57 +03:00
const char * func_prop_name ;
const char * groups_prop_name ;
const char * pins_prop_name ;
2012-07-10 07:08:14 +04:00
} ;
2012-07-17 10:48:18 +04:00
static int sh_pfc_get_groups_count ( struct pinctrl_dev * pctldev )
2012-07-10 07:08:14 +04:00
{
2012-07-17 10:48:18 +04:00
struct sh_pfc_pinctrl * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
2013-01-03 17:33:13 +04:00
return pmx - > pfc - > info - > nr_groups ;
2012-07-10 07:08:14 +04:00
}
2012-07-17 10:48:18 +04:00
static const char * sh_pfc_get_group_name ( struct pinctrl_dev * pctldev ,
2012-07-10 07:08:14 +04:00
unsigned selector )
{
2012-07-17 10:48:18 +04:00
struct sh_pfc_pinctrl * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
2013-01-03 17:33:13 +04:00
return pmx - > pfc - > info - > groups [ selector ] . name ;
2012-07-10 07:08:14 +04:00
}
2013-01-03 17:33:13 +04:00
static int sh_pfc_get_group_pins ( struct pinctrl_dev * pctldev , unsigned selector ,
2012-07-10 07:08:14 +04:00
const unsigned * * pins , unsigned * num_pins )
{
2012-07-17 10:48:18 +04:00
struct sh_pfc_pinctrl * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
2013-01-03 17:33:13 +04:00
* pins = pmx - > pfc - > info - > groups [ selector ] . pins ;
* num_pins = pmx - > pfc - > info - > groups [ selector ] . nr_pins ;
2012-07-17 10:48:18 +04:00
return 0 ;
2012-07-10 07:08:14 +04:00
}
2012-07-20 11:39:09 +04:00
static void sh_pfc_pin_dbg_show ( struct pinctrl_dev * pctldev , struct seq_file * s ,
unsigned offset )
{
2018-01-06 23:50:20 +03:00
seq_puts ( s , DRV_NAME ) ;
2012-07-20 11:39:09 +04:00
}
2013-06-19 15:26:02 +04:00
# ifdef CONFIG_OF
2013-06-17 22:50:03 +04:00
static int sh_pfc_map_add_config ( struct pinctrl_map * map ,
const char * group_or_pin ,
enum pinctrl_map_type type ,
unsigned long * configs ,
unsigned int num_configs )
{
unsigned long * cfgs ;
cfgs = kmemdup ( configs , num_configs * sizeof ( * cfgs ) ,
GFP_KERNEL ) ;
if ( cfgs = = NULL )
return - ENOMEM ;
map - > type = type ;
map - > data . configs . group_or_pin = group_or_pin ;
map - > data . configs . configs = cfgs ;
map - > data . configs . num_configs = num_configs ;
return 0 ;
}
2015-06-30 11:29:57 +03:00
static int sh_pfc_dt_subnode_to_map ( struct pinctrl_dev * pctldev ,
struct device_node * np ,
2013-06-17 22:50:02 +04:00
struct pinctrl_map * * map ,
unsigned int * num_maps , unsigned int * index )
{
2015-06-30 11:29:57 +03:00
struct sh_pfc_pinctrl * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
struct device * dev = pmx - > pfc - > dev ;
2013-06-17 22:50:02 +04:00
struct pinctrl_map * maps = * map ;
unsigned int nmaps = * num_maps ;
unsigned int idx = * index ;
2013-06-17 22:50:03 +04:00
unsigned int num_configs ;
2013-06-17 22:50:02 +04:00
const char * function = NULL ;
2013-06-17 22:50:03 +04:00
unsigned long * configs ;
2013-06-17 22:50:02 +04:00
struct property * prop ;
2013-06-17 22:50:03 +04:00
unsigned int num_groups ;
unsigned int num_pins ;
2013-06-17 22:50:02 +04:00
const char * group ;
2013-06-17 22:50:03 +04:00
const char * pin ;
2013-06-17 22:50:02 +04:00
int ret ;
2015-06-30 11:29:57 +03:00
/* Support both the old Renesas-specific properties and the new standard
* properties . Mixing old and new properties isn ' t allowed , neither
* inside a subnode nor across subnodes .
*/
if ( ! pmx - > func_prop_name ) {
if ( of_find_property ( np , " groups " , NULL ) | |
of_find_property ( np , " pins " , NULL ) ) {
pmx - > func_prop_name = " function " ;
pmx - > groups_prop_name = " groups " ;
pmx - > pins_prop_name = " pins " ;
} else {
pmx - > func_prop_name = " renesas,function " ;
pmx - > groups_prop_name = " renesas,groups " ;
pmx - > pins_prop_name = " renesas,pins " ;
}
}
2013-06-17 22:50:02 +04:00
/* Parse the function and configuration properties. At least a function
* or one configuration must be specified .
*/
2015-06-30 11:29:57 +03:00
ret = of_property_read_string ( np , pmx - > func_prop_name , & function ) ;
2013-06-17 22:50:02 +04:00
if ( ret < 0 & & ret ! = - EINVAL ) {
dev_err ( dev , " Invalid function in DT \n " ) ;
return ret ;
}
2015-01-09 18:43:46 +03:00
ret = pinconf_generic_parse_dt_config ( np , NULL , & configs , & num_configs ) ;
2013-06-17 22:50:03 +04:00
if ( ret < 0 )
return ret ;
if ( ! function & & num_configs = = 0 ) {
dev_err ( dev ,
" DT node must contain at least a function or config \n " ) ;
2015-06-30 11:29:57 +03:00
ret = - ENODEV ;
2013-06-17 22:50:02 +04:00
goto done ;
}
2013-06-17 22:50:03 +04:00
/* Count the number of pins and groups and reallocate mappings. */
2015-06-30 11:29:57 +03:00
ret = of_property_count_strings ( np , pmx - > pins_prop_name ) ;
2013-06-17 22:50:03 +04:00
if ( ret = = - EINVAL ) {
num_pins = 0 ;
} else if ( ret < 0 ) {
dev_err ( dev , " Invalid pins list in DT \n " ) ;
goto done ;
} else {
num_pins = ret ;
}
2015-06-30 11:29:57 +03:00
ret = of_property_count_strings ( np , pmx - > groups_prop_name ) ;
2013-06-17 22:50:03 +04:00
if ( ret = = - EINVAL ) {
num_groups = 0 ;
} else if ( ret < 0 ) {
2013-06-17 22:50:02 +04:00
dev_err ( dev , " Invalid pin groups list in DT \n " ) ;
goto done ;
2013-06-17 22:50:03 +04:00
} else {
num_groups = ret ;
2013-06-17 22:50:02 +04:00
}
2013-06-17 22:50:03 +04:00
if ( ! num_pins & & ! num_groups ) {
dev_err ( dev , " No pin or group provided in DT node \n " ) ;
2013-06-17 22:50:02 +04:00
ret = - ENODEV ;
goto done ;
}
2013-06-17 22:50:03 +04:00
if ( function )
nmaps + = num_groups ;
if ( configs )
nmaps + = num_pins + num_groups ;
2013-06-17 22:50:02 +04:00
maps = krealloc ( maps , sizeof ( * maps ) * nmaps , GFP_KERNEL ) ;
if ( maps = = NULL ) {
ret = - ENOMEM ;
goto done ;
}
* map = maps ;
* num_maps = nmaps ;
/* Iterate over pins and groups and create the mappings. */
2015-06-30 11:29:57 +03:00
of_property_for_each_string ( np , pmx - > groups_prop_name , prop , group ) {
2013-06-17 22:50:03 +04:00
if ( function ) {
maps [ idx ] . type = PIN_MAP_TYPE_MUX_GROUP ;
maps [ idx ] . data . mux . group = group ;
maps [ idx ] . data . mux . function = function ;
idx + + ;
}
if ( configs ) {
ret = sh_pfc_map_add_config ( & maps [ idx ] , group ,
PIN_MAP_TYPE_CONFIGS_GROUP ,
configs , num_configs ) ;
if ( ret < 0 )
goto done ;
idx + + ;
}
2013-06-17 22:50:02 +04:00
}
2013-06-17 22:50:03 +04:00
if ( ! configs ) {
ret = 0 ;
goto done ;
}
2015-06-30 11:29:57 +03:00
of_property_for_each_string ( np , pmx - > pins_prop_name , prop , pin ) {
2013-06-17 22:50:03 +04:00
ret = sh_pfc_map_add_config ( & maps [ idx ] , pin ,
PIN_MAP_TYPE_CONFIGS_PIN ,
configs , num_configs ) ;
if ( ret < 0 )
goto done ;
idx + + ;
}
2013-06-17 22:50:02 +04:00
done :
* index = idx ;
2013-06-17 22:50:03 +04:00
kfree ( configs ) ;
2013-06-17 22:50:02 +04:00
return ret ;
}
static void sh_pfc_dt_free_map ( struct pinctrl_dev * pctldev ,
struct pinctrl_map * map , unsigned num_maps )
{
2013-06-17 22:50:03 +04:00
unsigned int i ;
if ( map = = NULL )
return ;
for ( i = 0 ; i < num_maps ; + + i ) {
if ( map [ i ] . type = = PIN_MAP_TYPE_CONFIGS_GROUP | |
map [ i ] . type = = PIN_MAP_TYPE_CONFIGS_PIN )
kfree ( map [ i ] . data . configs . configs ) ;
}
2013-06-17 22:50:02 +04:00
kfree ( map ) ;
}
static int sh_pfc_dt_node_to_map ( struct pinctrl_dev * pctldev ,
struct device_node * np ,
struct pinctrl_map * * map , unsigned * num_maps )
{
struct sh_pfc_pinctrl * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
struct device * dev = pmx - > pfc - > dev ;
struct device_node * child ;
unsigned int index ;
int ret ;
* map = NULL ;
* num_maps = 0 ;
index = 0 ;
for_each_child_of_node ( np , child ) {
2015-06-30 11:29:57 +03:00
ret = sh_pfc_dt_subnode_to_map ( pctldev , child , map , num_maps ,
2013-06-17 22:50:02 +04:00
& index ) ;
2015-12-21 19:39:46 +03:00
if ( ret < 0 ) {
of_node_put ( child ) ;
2013-06-17 22:50:02 +04:00
goto done ;
2015-12-21 19:39:46 +03:00
}
2013-06-17 22:50:02 +04:00
}
/* If no mapping has been found in child nodes try the config node. */
if ( * num_maps = = 0 ) {
2015-06-30 11:29:57 +03:00
ret = sh_pfc_dt_subnode_to_map ( pctldev , np , map , num_maps ,
& index ) ;
2013-06-17 22:50:02 +04:00
if ( ret < 0 )
goto done ;
}
if ( * num_maps )
return 0 ;
2017-07-19 00:43:23 +03:00
dev_err ( dev , " no mapping found in node %pOF \n " , np ) ;
2013-06-17 22:50:02 +04:00
ret = - EINVAL ;
done :
if ( ret < 0 )
sh_pfc_dt_free_map ( pctldev , * map , * num_maps ) ;
return ret ;
}
2013-06-19 15:26:02 +04:00
# endif /* CONFIG_OF */
2013-06-17 22:50:02 +04:00
2013-02-15 19:04:47 +04:00
static const struct pinctrl_ops sh_pfc_pinctrl_ops = {
2012-07-17 10:48:18 +04:00
. get_groups_count = sh_pfc_get_groups_count ,
. get_group_name = sh_pfc_get_group_name ,
2012-07-10 07:08:14 +04:00
. get_group_pins = sh_pfc_get_group_pins ,
2012-07-20 11:39:09 +04:00
. pin_dbg_show = sh_pfc_pin_dbg_show ,
2013-06-19 15:26:02 +04:00
# ifdef CONFIG_OF
2013-06-17 22:50:02 +04:00
. dt_node_to_map = sh_pfc_dt_node_to_map ,
. dt_free_map = sh_pfc_dt_free_map ,
2013-06-19 15:26:02 +04:00
# endif
2012-07-10 07:08:14 +04:00
} ;
2012-07-11 12:17:10 +04:00
static int sh_pfc_get_functions_count ( struct pinctrl_dev * pctldev )
{
struct sh_pfc_pinctrl * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
2013-01-03 17:33:13 +04:00
return pmx - > pfc - > info - > nr_functions ;
2012-07-11 12:17:10 +04:00
}
static const char * sh_pfc_get_function_name ( struct pinctrl_dev * pctldev ,
unsigned selector )
{
struct sh_pfc_pinctrl * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
2013-01-03 17:33:13 +04:00
return pmx - > pfc - > info - > functions [ selector ] . name ;
2012-07-11 12:17:10 +04:00
}
2012-07-10 07:08:14 +04:00
2013-01-03 17:33:13 +04:00
static int sh_pfc_get_function_groups ( struct pinctrl_dev * pctldev ,
unsigned selector ,
2012-07-10 07:08:14 +04:00
const char * const * * groups ,
unsigned * const num_groups )
{
2012-07-11 12:17:10 +04:00
struct sh_pfc_pinctrl * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
2013-01-03 17:33:13 +04:00
* groups = pmx - > pfc - > info - > functions [ selector ] . groups ;
* num_groups = pmx - > pfc - > info - > functions [ selector ] . nr_groups ;
2012-07-11 12:17:10 +04:00
2012-07-10 07:08:14 +04:00
return 0 ;
}
2014-09-03 15:02:56 +04:00
static int sh_pfc_func_set_mux ( struct pinctrl_dev * pctldev , unsigned selector ,
unsigned group )
2012-07-10 07:08:14 +04:00
{
2013-01-03 17:33:13 +04:00
struct sh_pfc_pinctrl * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
struct sh_pfc * pfc = pmx - > pfc ;
const struct sh_pfc_pin_group * grp = & pfc - > info - > groups [ group ] ;
unsigned long flags ;
unsigned int i ;
2013-03-10 19:38:23 +04:00
int ret = 0 ;
2013-01-03 17:33:13 +04:00
2018-12-26 11:23:27 +03:00
dev_dbg ( pctldev - > dev , " Configuring pin group %s \n " , grp - > name ) ;
2013-01-03 17:33:13 +04:00
spin_lock_irqsave ( & pfc - > lock , flags ) ;
2013-03-10 20:25:29 +04:00
for ( i = 0 ; i < grp - > nr_pins ; + + i ) {
int idx = sh_pfc_get_pin_index ( pfc , grp - > pins [ i ] ) ;
struct sh_pfc_pin_config * cfg = & pmx - > configs [ idx ] ;
if ( cfg - > type ! = PINMUX_TYPE_NONE ) {
ret = - EBUSY ;
goto done ;
}
}
2013-01-03 17:33:13 +04:00
for ( i = 0 ; i < grp - > nr_pins ; + + i ) {
2013-03-10 19:38:23 +04:00
ret = sh_pfc_config_mux ( pfc , grp - > mux [ i ] , PINMUX_TYPE_FUNCTION ) ;
if ( ret < 0 )
break ;
2013-01-03 17:33:13 +04:00
}
2013-03-10 20:25:29 +04:00
done :
2013-01-03 17:33:13 +04:00
spin_unlock_irqrestore ( & pfc - > lock , flags ) ;
return ret ;
2012-07-10 07:08:14 +04:00
}
static int sh_pfc_gpio_request_enable ( struct pinctrl_dev * pctldev ,
struct pinctrl_gpio_range * range ,
unsigned offset )
{
struct sh_pfc_pinctrl * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
struct sh_pfc * pfc = pmx - > pfc ;
2013-03-08 20:43:54 +04:00
int idx = sh_pfc_get_pin_index ( pfc , offset ) ;
struct sh_pfc_pin_config * cfg = & pmx - > configs [ idx ] ;
2012-07-10 07:08:14 +04:00
unsigned long flags ;
2013-03-08 20:43:54 +04:00
int ret ;
2012-07-10 07:08:14 +04:00
spin_lock_irqsave ( & pfc - > lock , flags ) ;
2013-03-10 20:25:29 +04:00
if ( cfg - > type ! = PINMUX_TYPE_NONE ) {
2013-03-10 21:00:02 +04:00
dev_err ( pfc - > dev ,
" Pin %u is busy, can't configure it as GPIO. \n " ,
offset ) ;
2013-03-10 20:25:29 +04:00
ret = - EBUSY ;
goto done ;
2012-07-11 12:17:10 +04:00
}
2012-07-10 07:08:14 +04:00
2013-03-10 20:30:25 +04:00
if ( ! pfc - > gpio ) {
/* If GPIOs are handled externally the pin mux type need to be
* set to GPIO here .
*/
const struct sh_pfc_pin * pin = & pfc - > info - > pins [ idx ] ;
ret = sh_pfc_config_mux ( pfc , pin - > enum_id , PINMUX_TYPE_GPIO ) ;
if ( ret < 0 )
goto done ;
}
2013-03-10 20:25:29 +04:00
cfg - > type = PINMUX_TYPE_GPIO ;
2012-07-10 07:08:14 +04:00
ret = 0 ;
2013-03-10 20:25:29 +04:00
done :
2012-07-10 07:08:14 +04:00
spin_unlock_irqrestore ( & pfc - > lock , flags ) ;
return ret ;
}
static void sh_pfc_gpio_disable_free ( struct pinctrl_dev * pctldev ,
struct pinctrl_gpio_range * range ,
unsigned offset )
{
2013-03-10 20:25:29 +04:00
struct sh_pfc_pinctrl * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
struct sh_pfc * pfc = pmx - > pfc ;
int idx = sh_pfc_get_pin_index ( pfc , offset ) ;
struct sh_pfc_pin_config * cfg = & pmx - > configs [ idx ] ;
unsigned long flags ;
spin_lock_irqsave ( & pfc - > lock , flags ) ;
cfg - > type = PINMUX_TYPE_NONE ;
spin_unlock_irqrestore ( & pfc - > lock , flags ) ;
2012-07-10 07:08:14 +04:00
}
static int sh_pfc_gpio_set_direction ( struct pinctrl_dev * pctldev ,
struct pinctrl_gpio_range * range ,
unsigned offset , bool input )
{
struct sh_pfc_pinctrl * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
2013-03-10 19:55:19 +04:00
struct sh_pfc * pfc = pmx - > pfc ;
int new_type = input ? PINMUX_TYPE_INPUT : PINMUX_TYPE_OUTPUT ;
int idx = sh_pfc_get_pin_index ( pfc , offset ) ;
const struct sh_pfc_pin * pin = & pfc - > info - > pins [ idx ] ;
2013-03-10 20:25:29 +04:00
struct sh_pfc_pin_config * cfg = & pmx - > configs [ idx ] ;
2013-03-10 19:55:19 +04:00
unsigned long flags ;
2013-03-13 21:18:30 +04:00
unsigned int dir ;
2013-03-10 19:55:19 +04:00
int ret ;
2012-07-10 07:08:14 +04:00
2013-03-13 21:18:30 +04:00
/* Check if the requested direction is supported by the pin. Not all SoC
* provide pin config data , so perform the check conditionally .
*/
if ( pin - > configs ) {
dir = input ? SH_PFC_PIN_CFG_INPUT : SH_PFC_PIN_CFG_OUTPUT ;
if ( ! ( pin - > configs & dir ) )
return - EINVAL ;
}
2013-03-10 19:55:19 +04:00
spin_lock_irqsave ( & pfc - > lock , flags ) ;
2013-03-10 20:25:29 +04:00
ret = sh_pfc_config_mux ( pfc , pin - > enum_id , new_type ) ;
2013-03-10 19:55:19 +04:00
if ( ret < 0 )
goto done ;
cfg - > type = new_type ;
done :
spin_unlock_irqrestore ( & pfc - > lock , flags ) ;
return ret ;
2012-07-10 07:08:14 +04:00
}
2013-02-15 19:04:47 +04:00
static const struct pinmux_ops sh_pfc_pinmux_ops = {
2012-07-11 12:17:10 +04:00
. get_functions_count = sh_pfc_get_functions_count ,
. get_function_name = sh_pfc_get_function_name ,
2012-07-10 07:08:14 +04:00
. get_function_groups = sh_pfc_get_function_groups ,
2014-09-03 15:02:56 +04:00
. set_mux = sh_pfc_func_set_mux ,
2012-07-10 07:08:14 +04:00
. gpio_request_enable = sh_pfc_gpio_request_enable ,
. gpio_disable_free = sh_pfc_gpio_disable_free ,
. gpio_set_direction = sh_pfc_gpio_set_direction ,
} ;
2016-03-23 17:06:00 +03:00
static u32 sh_pfc_pinconf_find_drive_strength_reg ( struct sh_pfc * pfc ,
unsigned int pin , unsigned int * offset , unsigned int * size )
{
const struct pinmux_drive_reg_field * field ;
const struct pinmux_drive_reg * reg ;
unsigned int i ;
for ( reg = pfc - > info - > drive_regs ; reg - > reg ; + + reg ) {
for ( i = 0 ; i < ARRAY_SIZE ( reg - > fields ) ; + + i ) {
field = & reg - > fields [ i ] ;
if ( field - > size & & field - > pin = = pin ) {
* offset = field - > offset ;
* size = field - > size ;
return reg - > reg ;
}
}
}
return 0 ;
}
static int sh_pfc_pinconf_get_drive_strength ( struct sh_pfc * pfc ,
unsigned int pin )
{
unsigned long flags ;
unsigned int offset ;
unsigned int size ;
u32 reg ;
u32 val ;
reg = sh_pfc_pinconf_find_drive_strength_reg ( pfc , pin , & offset , & size ) ;
if ( ! reg )
return - EINVAL ;
spin_lock_irqsave ( & pfc - > lock , flags ) ;
2017-09-29 12:03:11 +03:00
val = sh_pfc_read ( pfc , reg ) ;
2016-03-23 17:06:00 +03:00
spin_unlock_irqrestore ( & pfc - > lock , flags ) ;
val = ( val > > offset ) & GENMASK ( size - 1 , 0 ) ;
/* Convert the value to mA based on a full drive strength value of 24mA.
* We can make the full value configurable later if needed .
*/
return ( val + 1 ) * ( size = = 2 ? 6 : 3 ) ;
}
static int sh_pfc_pinconf_set_drive_strength ( struct sh_pfc * pfc ,
unsigned int pin , u16 strength )
{
unsigned long flags ;
unsigned int offset ;
unsigned int size ;
unsigned int step ;
u32 reg ;
u32 val ;
reg = sh_pfc_pinconf_find_drive_strength_reg ( pfc , pin , & offset , & size ) ;
if ( ! reg )
return - EINVAL ;
step = size = = 2 ? 6 : 3 ;
if ( strength < step | | strength > 24 )
return - EINVAL ;
/* Convert the value from mA based on a full drive strength value of
* 24 mA . We can make the full value configurable later if needed .
*/
strength = strength / step - 1 ;
spin_lock_irqsave ( & pfc - > lock , flags ) ;
2017-09-29 12:03:11 +03:00
val = sh_pfc_read ( pfc , reg ) ;
2016-03-23 17:06:00 +03:00
val & = ~ GENMASK ( offset + size - 1 , offset ) ;
val | = strength < < offset ;
2017-09-29 12:03:11 +03:00
sh_pfc_write ( pfc , reg , val ) ;
2016-03-23 17:06:00 +03:00
spin_unlock_irqrestore ( & pfc - > lock , flags ) ;
return 0 ;
}
2013-03-10 19:44:02 +04:00
/* Check whether the requested parameter is supported for a pin. */
static bool sh_pfc_pinconf_validate ( struct sh_pfc * pfc , unsigned int _pin ,
enum pin_config_param param )
{
int idx = sh_pfc_get_pin_index ( pfc , _pin ) ;
const struct sh_pfc_pin * pin = & pfc - > info - > pins [ idx ] ;
switch ( param ) {
case PIN_CONFIG_BIAS_DISABLE :
2016-11-12 19:04:24 +03:00
return pin - > configs &
( SH_PFC_PIN_CFG_PULL_UP | SH_PFC_PIN_CFG_PULL_DOWN ) ;
2013-03-10 19:44:02 +04:00
case PIN_CONFIG_BIAS_PULL_UP :
return pin - > configs & SH_PFC_PIN_CFG_PULL_UP ;
case PIN_CONFIG_BIAS_PULL_DOWN :
return pin - > configs & SH_PFC_PIN_CFG_PULL_DOWN ;
2016-03-23 17:06:00 +03:00
case PIN_CONFIG_DRIVE_STRENGTH :
return pin - > configs & SH_PFC_PIN_CFG_DRIVE_STRENGTH ;
2015-06-30 19:53:59 +03:00
case PIN_CONFIG_POWER_SOURCE :
return pin - > configs & SH_PFC_PIN_CFG_IO_VOLTAGE ;
2013-03-10 19:44:02 +04:00
default :
return false ;
}
}
2013-02-15 01:35:09 +04:00
static int sh_pfc_pinconf_get ( struct pinctrl_dev * pctldev , unsigned _pin ,
2012-07-10 07:08:14 +04:00
unsigned long * config )
{
2012-07-20 11:39:09 +04:00
struct sh_pfc_pinctrl * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
struct sh_pfc * pfc = pmx - > pfc ;
2013-03-10 19:44:02 +04:00
enum pin_config_param param = pinconf_to_config_param ( * config ) ;
unsigned long flags ;
2016-09-06 18:14:14 +03:00
unsigned int arg ;
2013-03-10 19:44:02 +04:00
if ( ! sh_pfc_pinconf_validate ( pfc , _pin , param ) )
return - ENOTSUPP ;
switch ( param ) {
case PIN_CONFIG_BIAS_DISABLE :
case PIN_CONFIG_BIAS_PULL_UP :
2015-06-30 19:53:59 +03:00
case PIN_CONFIG_BIAS_PULL_DOWN : {
unsigned int bias ;
2013-03-10 19:44:02 +04:00
if ( ! pfc - > info - > ops | | ! pfc - > info - > ops - > get_bias )
return - ENOTSUPP ;
spin_lock_irqsave ( & pfc - > lock , flags ) ;
bias = pfc - > info - > ops - > get_bias ( pfc , _pin ) ;
spin_unlock_irqrestore ( & pfc - > lock , flags ) ;
if ( bias ! = param )
return - EINVAL ;
2016-09-06 18:14:14 +03:00
arg = 0 ;
2013-03-10 19:44:02 +04:00
break ;
2015-06-30 19:53:59 +03:00
}
2016-03-23 17:06:00 +03:00
case PIN_CONFIG_DRIVE_STRENGTH : {
int ret ;
ret = sh_pfc_pinconf_get_drive_strength ( pfc , _pin ) ;
if ( ret < 0 )
return ret ;
2016-09-06 18:14:14 +03:00
arg = ret ;
2016-03-23 17:06:00 +03:00
break ;
}
2015-06-30 19:53:59 +03:00
case PIN_CONFIG_POWER_SOURCE : {
2016-06-06 19:08:25 +03:00
u32 pocctrl , val ;
int bit ;
2015-06-30 19:53:59 +03:00
2016-06-06 19:08:25 +03:00
if ( ! pfc - > info - > ops | | ! pfc - > info - > ops - > pin_to_pocctrl )
2015-06-30 19:53:59 +03:00
return - ENOTSUPP ;
2016-06-06 19:08:25 +03:00
bit = pfc - > info - > ops - > pin_to_pocctrl ( pfc , _pin , & pocctrl ) ;
if ( WARN ( bit < 0 , " invalid pin %#x " , _pin ) )
return bit ;
2015-06-30 19:53:59 +03:00
spin_lock_irqsave ( & pfc - > lock , flags ) ;
2017-09-29 12:03:11 +03:00
val = sh_pfc_read ( pfc , pocctrl ) ;
2015-06-30 19:53:59 +03:00
spin_unlock_irqrestore ( & pfc - > lock , flags ) ;
2016-09-06 18:14:14 +03:00
arg = ( val & BIT ( bit ) ) ? 3300 : 1800 ;
2015-06-30 19:53:59 +03:00
break ;
}
2012-07-11 12:17:10 +04:00
2013-03-10 19:44:02 +04:00
default :
return - ENOTSUPP ;
}
2012-07-11 12:17:10 +04:00
2016-09-06 18:14:14 +03:00
* config = pinconf_to_config_packed ( param , arg ) ;
2012-07-20 11:39:09 +04:00
return 0 ;
2012-07-10 07:08:14 +04:00
}
2013-03-10 19:44:02 +04:00
static int sh_pfc_pinconf_set ( struct pinctrl_dev * pctldev , unsigned _pin ,
2013-08-27 22:32:12 +04:00
unsigned long * configs , unsigned num_configs )
2012-07-10 07:08:14 +04:00
{
2012-07-20 11:39:09 +04:00
struct sh_pfc_pinctrl * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
2013-03-10 19:44:02 +04:00
struct sh_pfc * pfc = pmx - > pfc ;
2013-08-27 22:32:12 +04:00
enum pin_config_param param ;
2013-03-10 19:44:02 +04:00
unsigned long flags ;
2013-08-27 22:32:12 +04:00
unsigned int i ;
2012-07-20 11:39:09 +04:00
2013-08-27 22:32:12 +04:00
for ( i = 0 ; i < num_configs ; i + + ) {
param = pinconf_to_config_param ( configs [ i ] ) ;
2012-07-20 11:39:09 +04:00
2013-08-27 22:32:12 +04:00
if ( ! sh_pfc_pinconf_validate ( pfc , _pin , param ) )
2013-03-10 19:44:02 +04:00
return - ENOTSUPP ;
2013-08-27 22:32:12 +04:00
switch ( param ) {
case PIN_CONFIG_BIAS_PULL_UP :
case PIN_CONFIG_BIAS_PULL_DOWN :
case PIN_CONFIG_BIAS_DISABLE :
if ( ! pfc - > info - > ops | | ! pfc - > info - > ops - > set_bias )
return - ENOTSUPP ;
2013-03-10 19:44:02 +04:00
2013-08-27 22:32:12 +04:00
spin_lock_irqsave ( & pfc - > lock , flags ) ;
pfc - > info - > ops - > set_bias ( pfc , _pin , param ) ;
spin_unlock_irqrestore ( & pfc - > lock , flags ) ;
2013-03-10 19:44:02 +04:00
2013-08-27 22:32:12 +04:00
break ;
2016-03-23 17:06:00 +03:00
case PIN_CONFIG_DRIVE_STRENGTH : {
unsigned int arg =
pinconf_to_config_argument ( configs [ i ] ) ;
int ret ;
ret = sh_pfc_pinconf_set_drive_strength ( pfc , _pin , arg ) ;
if ( ret < 0 )
return ret ;
break ;
}
2015-06-30 19:53:59 +03:00
case PIN_CONFIG_POWER_SOURCE : {
2016-06-06 19:08:25 +03:00
unsigned int mV = pinconf_to_config_argument ( configs [ i ] ) ;
u32 pocctrl , val ;
int bit ;
2015-06-30 19:53:59 +03:00
2016-06-06 19:08:25 +03:00
if ( ! pfc - > info - > ops | | ! pfc - > info - > ops - > pin_to_pocctrl )
2015-06-30 19:53:59 +03:00
return - ENOTSUPP ;
2016-06-06 19:08:25 +03:00
bit = pfc - > info - > ops - > pin_to_pocctrl ( pfc , _pin , & pocctrl ) ;
if ( WARN ( bit < 0 , " invalid pin %#x " , _pin ) )
return bit ;
if ( mV ! = 1800 & & mV ! = 3300 )
return - EINVAL ;
2015-06-30 19:53:59 +03:00
spin_lock_irqsave ( & pfc - > lock , flags ) ;
2017-09-29 12:03:11 +03:00
val = sh_pfc_read ( pfc , pocctrl ) ;
2016-06-06 19:08:25 +03:00
if ( mV = = 3300 )
val | = BIT ( bit ) ;
else
val & = ~ BIT ( bit ) ;
2017-09-29 12:03:11 +03:00
sh_pfc_write ( pfc , pocctrl , val ) ;
2015-06-30 19:53:59 +03:00
spin_unlock_irqrestore ( & pfc - > lock , flags ) ;
break ;
}
2013-08-27 22:32:12 +04:00
default :
return - ENOTSUPP ;
}
} /* for each config */
2013-03-10 19:44:02 +04:00
return 0 ;
2012-07-20 11:39:09 +04:00
}
2013-03-10 19:44:02 +04:00
static int sh_pfc_pinconf_group_set ( struct pinctrl_dev * pctldev , unsigned group ,
2013-08-27 22:32:12 +04:00
unsigned long * configs ,
unsigned num_configs )
2012-07-20 11:39:09 +04:00
{
2013-03-10 19:44:02 +04:00
struct sh_pfc_pinctrl * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
const unsigned int * pins ;
unsigned int num_pins ;
2016-06-20 09:40:22 +03:00
unsigned int i , ret ;
2013-03-10 19:44:02 +04:00
pins = pmx - > pfc - > info - > groups [ group ] . pins ;
num_pins = pmx - > pfc - > info - > groups [ group ] . nr_pins ;
2016-06-20 09:40:22 +03:00
for ( i = 0 ; i < num_pins ; + + i ) {
ret = sh_pfc_pinconf_set ( pctldev , pins [ i ] , configs , num_configs ) ;
if ( ret )
return ret ;
}
2013-03-10 19:44:02 +04:00
return 0 ;
2012-07-10 07:08:14 +04:00
}
2013-02-15 19:04:47 +04:00
static const struct pinconf_ops sh_pfc_pinconf_ops = {
2013-03-10 19:44:02 +04:00
. is_generic = true ,
. pin_config_get = sh_pfc_pinconf_get ,
. pin_config_set = sh_pfc_pinconf_set ,
. pin_config_group_set = sh_pfc_pinconf_group_set ,
. pin_config_config_dbg_show = pinconf_generic_dump_config ,
2012-07-10 07:08:14 +04:00
} ;
2013-02-15 04:33:38 +04:00
/* PFC ranges -> pinctrl pin descs */
static int sh_pfc_map_pins ( struct sh_pfc * pfc , struct sh_pfc_pinctrl * pmx )
2012-07-10 07:08:14 +04:00
{
2013-02-15 04:33:38 +04:00
unsigned int i ;
2013-07-15 20:38:30 +04:00
/* Allocate and initialize the pins and configs arrays. */
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
pmx - > pins = devm_kcalloc ( pfc - > dev ,
pfc - > info - > nr_pins , sizeof ( * pmx - > pins ) ,
2012-12-16 02:50:48 +04:00
GFP_KERNEL ) ;
2013-01-03 17:33:13 +04:00
if ( unlikely ( ! pmx - > pins ) )
2012-07-10 07:08:14 +04:00
return - ENOMEM ;
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
pmx - > configs = devm_kcalloc ( pfc - > dev ,
pfc - > info - > nr_pins , sizeof ( * pmx - > configs ) ,
2013-03-08 20:43:54 +04:00
GFP_KERNEL ) ;
if ( unlikely ( ! pmx - > configs ) )
return - ENOMEM ;
2013-07-15 20:38:30 +04:00
for ( i = 0 ; i < pfc - > info - > nr_pins ; + + i ) {
const struct sh_pfc_pin * info = & pfc - > info - > pins [ i ] ;
struct sh_pfc_pin_config * cfg = & pmx - > configs [ i ] ;
struct pinctrl_pin_desc * pin = & pmx - > pins [ i ] ;
2013-02-15 04:33:38 +04:00
2013-07-15 20:38:30 +04:00
/* If the pin number is equal to -1 all pins are considered */
pin - > number = info - > pin ! = ( u16 ) - 1 ? info - > pin : i ;
pin - > name = info - > name ;
cfg - > type = PINMUX_TYPE_NONE ;
2012-07-10 07:08:14 +04:00
}
2013-07-15 20:38:30 +04:00
return 0 ;
2012-07-10 07:08:14 +04:00
}
2012-12-16 02:50:47 +04:00
int sh_pfc_register_pinctrl ( struct sh_pfc * pfc )
2012-07-10 07:08:14 +04:00
{
2012-12-16 02:50:47 +04:00
struct sh_pfc_pinctrl * pmx ;
2013-07-15 20:38:30 +04:00
int ret ;
2012-07-10 07:08:14 +04:00
2012-12-16 02:50:48 +04:00
pmx = devm_kzalloc ( pfc - > dev , sizeof ( * pmx ) , GFP_KERNEL ) ;
2012-12-16 02:50:47 +04:00
if ( unlikely ( ! pmx ) )
return - ENOMEM ;
pmx - > pfc = pfc ;
2012-07-10 07:08:14 +04:00
2013-07-15 20:38:30 +04:00
ret = sh_pfc_map_pins ( pfc , pmx ) ;
if ( ret < 0 )
return ret ;
2012-07-10 07:08:14 +04:00
2013-02-16 19:38:30 +04:00
pmx - > pctl_desc . name = DRV_NAME ;
pmx - > pctl_desc . owner = THIS_MODULE ;
pmx - > pctl_desc . pctlops = & sh_pfc_pinctrl_ops ;
pmx - > pctl_desc . pmxops = & sh_pfc_pinmux_ops ;
pmx - > pctl_desc . confops = & sh_pfc_pinconf_ops ;
2013-01-03 17:33:13 +04:00
pmx - > pctl_desc . pins = pmx - > pins ;
2013-02-15 04:33:38 +04:00
pmx - > pctl_desc . npins = pfc - > info - > nr_pins ;
2013-02-16 19:38:30 +04:00
2017-03-30 19:16:39 +03:00
ret = devm_pinctrl_register_and_init ( pfc - > dev , & pmx - > pctl_desc , pmx ,
& pmx - > pctl ) ;
if ( ret ) {
dev_err ( pfc - > dev , " could not register: %i \n " , ret ) ;
return ret ;
}
return pinctrl_enable ( pmx - > pctl ) ;
2012-07-10 07:08:14 +04:00
}