2012-03-28 22:27:07 +05:30
/*
* Driver for the ST Microelectronics SPEAr pinmux
*
* Copyright ( C ) 2012 ST Microelectronics
2015-07-17 16:23:50 -07:00
* Viresh Kumar < vireshk @ kernel . org >
2012-03-28 22:27:07 +05:30
*
* Inspired from :
* - U300 Pinctl drivers
* - Tegra Pinctl drivers
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed " as is " without any
* warranty of any kind , whether express or implied .
*/
# include <linux/err.h>
2021-12-02 10:52:50 +01:00
# include <linux/mfd/syscon.h>
2012-03-28 22:27:07 +05:30
# include <linux/module.h>
# include <linux/of.h>
# include <linux/of_address.h>
2012-10-27 15:21:38 +05:30
# include <linux/of_gpio.h>
2012-03-28 22:27:07 +05:30
# include <linux/pinctrl/machine.h>
# include <linux/pinctrl/pinctrl.h>
# include <linux/pinctrl/pinmux.h>
# include <linux/platform_device.h>
# include <linux/slab.h>
# include "pinctrl-spear.h"
# define DRIVER_NAME "spear-pinmux"
2012-10-27 15:21:38 +05:30
static void muxregs_endisable ( struct spear_pmx * pmx ,
struct spear_muxreg * muxregs , u8 count , bool enable )
{
struct spear_muxreg * muxreg ;
u32 val , temp , j ;
for ( j = 0 ; j < count ; j + + ) {
muxreg = & muxregs [ j ] ;
val = pmx_readl ( pmx , muxreg - > reg ) ;
val & = ~ muxreg - > mask ;
if ( enable )
temp = muxreg - > val ;
else
temp = ~ muxreg - > val ;
val | = muxreg - > mask & temp ;
pmx_writel ( pmx , val , muxreg - > reg ) ;
}
}
2012-03-28 22:27:07 +05:30
static int set_mode ( struct spear_pmx * pmx , int mode )
{
struct spear_pmx_mode * pmx_mode = NULL ;
int i ;
u32 val ;
if ( ! pmx - > machdata - > pmx_modes | | ! pmx - > machdata - > npmx_modes )
return - EINVAL ;
for ( i = 0 ; i < pmx - > machdata - > npmx_modes ; i + + ) {
if ( pmx - > machdata - > pmx_modes [ i ] - > mode = = ( 1 < < mode ) ) {
pmx_mode = pmx - > machdata - > pmx_modes [ i ] ;
break ;
}
}
if ( ! pmx_mode )
return - EINVAL ;
val = pmx_readl ( pmx , pmx_mode - > reg ) ;
val & = ~ pmx_mode - > mask ;
val | = pmx_mode - > val ;
pmx_writel ( pmx , val , pmx_mode - > reg ) ;
pmx - > machdata - > mode = pmx_mode - > mode ;
dev_info ( pmx - > dev , " Configured Mode: %s with id: %x \n \n " ,
pmx_mode - > name ? pmx_mode - > name : " no_name " ,
pmx_mode - > reg ) ;
return 0 ;
}
2012-12-21 13:10:23 -08:00
void pmx_init_gpio_pingroup_addr ( struct spear_gpio_pingroup * gpio_pingroup ,
unsigned count , u16 reg )
2012-10-27 15:21:38 +05:30
{
2012-11-13 15:31:41 +08:00
int i , j ;
2012-10-27 15:21:38 +05:30
2012-11-13 15:31:41 +08:00
for ( i = 0 ; i < count ; i + + )
for ( j = 0 ; j < gpio_pingroup [ i ] . nmuxregs ; j + + )
2012-10-27 15:21:38 +05:30
gpio_pingroup [ i ] . muxregs [ j ] . reg = reg ;
}
2012-12-21 13:10:23 -08:00
void pmx_init_addr ( struct spear_pinctrl_machdata * machdata , u16 reg )
2012-03-28 22:27:07 +05:30
{
struct spear_pingroup * pgroup ;
struct spear_modemux * modemux ;
int i , j , group ;
for ( group = 0 ; group < machdata - > ngroups ; group + + ) {
pgroup = machdata - > groups [ group ] ;
for ( i = 0 ; i < pgroup - > nmodemuxs ; i + + ) {
modemux = & pgroup - > modemuxs [ i ] ;
for ( j = 0 ; j < modemux - > nmuxregs ; j + + )
if ( modemux - > muxregs [ j ] . reg = = 0xFFFF )
modemux - > muxregs [ j ] . reg = reg ;
}
}
}
static int spear_pinctrl_get_groups_cnt ( struct pinctrl_dev * pctldev )
{
struct spear_pmx * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
return pmx - > machdata - > ngroups ;
}
static const char * spear_pinctrl_get_group_name ( struct pinctrl_dev * pctldev ,
unsigned group )
{
struct spear_pmx * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
return pmx - > machdata - > groups [ group ] - > name ;
}
static int spear_pinctrl_get_group_pins ( struct pinctrl_dev * pctldev ,
unsigned group , const unsigned * * pins , unsigned * num_pins )
{
struct spear_pmx * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
* pins = pmx - > machdata - > groups [ group ] - > pins ;
* num_pins = pmx - > machdata - > groups [ group ] - > npins ;
return 0 ;
}
static void spear_pinctrl_pin_dbg_show ( struct pinctrl_dev * pctldev ,
struct seq_file * s , unsigned offset )
{
seq_printf ( s , " " DRIVER_NAME ) ;
}
2012-11-11 10:29:40 +08:00
static int spear_pinctrl_dt_node_to_map ( struct pinctrl_dev * pctldev ,
struct device_node * np_config ,
struct pinctrl_map * * map ,
unsigned * num_maps )
2012-03-28 22:27:07 +05:30
{
struct spear_pmx * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
struct device_node * np ;
struct property * prop ;
const char * function , * group ;
int ret , index = 0 , count = 0 ;
/* calculate number of maps required */
for_each_child_of_node ( np_config , np ) {
ret = of_property_read_string ( np , " st,function " , & function ) ;
2019-08-04 21:19:48 +05:30
if ( ret < 0 ) {
of_node_put ( np ) ;
2012-03-28 22:27:07 +05:30
return ret ;
2019-08-04 21:19:48 +05:30
}
2012-03-28 22:27:07 +05:30
ret = of_property_count_strings ( np , " st,pins " ) ;
2019-08-04 21:19:48 +05:30
if ( ret < 0 ) {
of_node_put ( np ) ;
2012-03-28 22:27:07 +05:30
return ret ;
2019-08-04 21:19:48 +05:30
}
2012-03-28 22:27:07 +05:30
count + = ret ;
}
if ( ! count ) {
dev_err ( pmx - > dev , " No child nodes passed via DT \n " ) ;
return - ENODEV ;
}
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-12 14:03:40 -07:00
* map = kcalloc ( count , sizeof ( * * map ) , GFP_KERNEL ) ;
2012-03-28 22:27:07 +05:30
if ( ! * map )
return - ENOMEM ;
for_each_child_of_node ( np_config , np ) {
of_property_read_string ( np , " st,function " , & function ) ;
of_property_for_each_string ( np , " st,pins " , prop , group ) {
( * map ) [ index ] . type = PIN_MAP_TYPE_MUX_GROUP ;
( * map ) [ index ] . data . mux . group = group ;
( * map ) [ index ] . data . mux . function = function ;
index + + ;
}
}
* num_maps = count ;
return 0 ;
}
2012-11-11 10:29:40 +08:00
static void spear_pinctrl_dt_free_map ( struct pinctrl_dev * pctldev ,
struct pinctrl_map * map ,
unsigned num_maps )
2012-03-28 22:27:07 +05:30
{
kfree ( map ) ;
}
2013-02-16 10:25:07 +01:00
static const struct pinctrl_ops spear_pinctrl_ops = {
2012-03-28 22:27:07 +05:30
. get_groups_count = spear_pinctrl_get_groups_cnt ,
. get_group_name = spear_pinctrl_get_group_name ,
. get_group_pins = spear_pinctrl_get_group_pins ,
. pin_dbg_show = spear_pinctrl_pin_dbg_show ,
. dt_node_to_map = spear_pinctrl_dt_node_to_map ,
. dt_free_map = spear_pinctrl_dt_free_map ,
} ;
static int spear_pinctrl_get_funcs_count ( struct pinctrl_dev * pctldev )
{
struct spear_pmx * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
return pmx - > machdata - > nfunctions ;
}
static const char * spear_pinctrl_get_func_name ( struct pinctrl_dev * pctldev ,
unsigned function )
{
struct spear_pmx * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
return pmx - > machdata - > functions [ function ] - > name ;
}
static int spear_pinctrl_get_func_groups ( struct pinctrl_dev * pctldev ,
unsigned function , const char * const * * groups ,
unsigned * const ngroups )
{
struct spear_pmx * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
* groups = pmx - > machdata - > functions [ function ] - > groups ;
* ngroups = pmx - > machdata - > functions [ function ] - > ngroups ;
return 0 ;
}
static int spear_pinctrl_endisable ( struct pinctrl_dev * pctldev ,
unsigned function , unsigned group , bool enable )
{
struct spear_pmx * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
const struct spear_pingroup * pgroup ;
const struct spear_modemux * modemux ;
2012-10-27 15:21:38 +05:30
int i ;
2012-03-28 22:27:07 +05:30
bool found = false ;
pgroup = pmx - > machdata - > groups [ group ] ;
for ( i = 0 ; i < pgroup - > nmodemuxs ; i + + ) {
modemux = & pgroup - > modemuxs [ i ] ;
/* SoC have any modes */
if ( pmx - > machdata - > modes_supported ) {
if ( ! ( pmx - > machdata - > mode & modemux - > modes ) )
continue ;
}
found = true ;
2012-10-27 15:21:38 +05:30
muxregs_endisable ( pmx , modemux - > muxregs , modemux - > nmuxregs ,
enable ) ;
2012-03-28 22:27:07 +05:30
}
if ( ! found ) {
dev_err ( pmx - > dev , " pinmux group: %s not supported \n " ,
pgroup - > name ) ;
return - ENODEV ;
}
return 0 ;
}
2014-09-03 13:02:56 +02:00
static int spear_pinctrl_set_mux ( struct pinctrl_dev * pctldev , unsigned function ,
2012-03-28 22:27:07 +05:30
unsigned group )
{
return spear_pinctrl_endisable ( pctldev , function , group , true ) ;
}
2012-10-27 15:21:38 +05:30
/* gpio with pinmux */
static struct spear_gpio_pingroup * get_gpio_pingroup ( struct spear_pmx * pmx ,
unsigned pin )
{
struct spear_gpio_pingroup * gpio_pingroup ;
2012-11-13 20:20:50 +08:00
int i , j ;
2012-10-27 15:21:38 +05:30
if ( ! pmx - > machdata - > gpio_pingroups )
return NULL ;
2012-11-13 20:20:50 +08:00
for ( i = 0 ; i < pmx - > machdata - > ngpio_pingroups ; i + + ) {
2012-10-27 15:21:38 +05:30
gpio_pingroup = & pmx - > machdata - > gpio_pingroups [ i ] ;
for ( j = 0 ; j < gpio_pingroup - > npins ; j + + ) {
if ( gpio_pingroup - > pins [ j ] = = pin )
return gpio_pingroup ;
}
}
2012-11-13 20:20:50 +08:00
return NULL ;
2012-10-27 15:21:38 +05:30
}
static int gpio_request_endisable ( struct pinctrl_dev * pctldev ,
struct pinctrl_gpio_range * range , unsigned offset , bool enable )
{
struct spear_pmx * pmx = pinctrl_dev_get_drvdata ( pctldev ) ;
2012-11-07 20:07:25 +05:30
struct spear_pinctrl_machdata * machdata = pmx - > machdata ;
2012-10-27 15:21:38 +05:30
struct spear_gpio_pingroup * gpio_pingroup ;
2012-11-07 20:07:25 +05:30
/*
* Some SoC have configuration options applicable to group of pins ,
* rather than a single pin .
*/
2012-10-27 15:21:38 +05:30
gpio_pingroup = get_gpio_pingroup ( pmx , offset ) ;
if ( gpio_pingroup )
muxregs_endisable ( pmx , gpio_pingroup - > muxregs ,
gpio_pingroup - > nmuxregs , enable ) ;
2012-11-07 20:07:25 +05:30
/*
* SoC may need some extra configurations , or configurations for single
* pin
*/
if ( machdata - > gpio_request_endisable )
machdata - > gpio_request_endisable ( pmx , offset , enable ) ;
2012-10-27 15:21:38 +05:30
return 0 ;
}
static int gpio_request_enable ( struct pinctrl_dev * pctldev ,
struct pinctrl_gpio_range * range , unsigned offset )
{
return gpio_request_endisable ( pctldev , range , offset , true ) ;
}
static void gpio_disable_free ( struct pinctrl_dev * pctldev ,
struct pinctrl_gpio_range * range , unsigned offset )
{
gpio_request_endisable ( pctldev , range , offset , false ) ;
}
2013-02-16 10:25:07 +01:00
static const struct pinmux_ops spear_pinmux_ops = {
2012-03-28 22:27:07 +05:30
. get_functions_count = spear_pinctrl_get_funcs_count ,
. get_function_name = spear_pinctrl_get_func_name ,
. get_function_groups = spear_pinctrl_get_func_groups ,
2014-09-03 13:02:56 +02:00
. set_mux = spear_pinctrl_set_mux ,
2012-10-27 15:21:38 +05:30
. gpio_request_enable = gpio_request_enable ,
. gpio_disable_free = gpio_disable_free ,
2012-03-28 22:27:07 +05:30
} ;
static struct pinctrl_desc spear_pinctrl_desc = {
. name = DRIVER_NAME ,
. pctlops = & spear_pinctrl_ops ,
. pmxops = & spear_pinmux_ops ,
. owner = THIS_MODULE ,
} ;
2012-12-21 13:10:23 -08:00
int spear_pinctrl_probe ( struct platform_device * pdev ,
struct spear_pinctrl_machdata * machdata )
2012-03-28 22:27:07 +05:30
{
struct device_node * np = pdev - > dev . of_node ;
struct spear_pmx * pmx ;
if ( ! machdata )
return - ENODEV ;
pmx = devm_kzalloc ( & pdev - > dev , sizeof ( * pmx ) , GFP_KERNEL ) ;
2017-12-27 22:44:04 +01:00
if ( ! pmx )
2012-03-28 22:27:07 +05:30
return - ENOMEM ;
2021-12-02 10:52:50 +01:00
pmx - > regmap = device_node_to_regmap ( np ) ;
if ( IS_ERR ( pmx - > regmap ) ) {
dev_err ( & pdev - > dev , " Init regmap failed (%pe). \n " ,
pmx - > regmap ) ;
return PTR_ERR ( pmx - > regmap ) ;
}
2012-03-28 22:27:07 +05:30
pmx - > dev = & pdev - > dev ;
pmx - > machdata = machdata ;
/* configure mode, if supported by SoC */
if ( machdata - > modes_supported ) {
int mode = 0 ;
if ( of_property_read_u32 ( np , " st,pinmux-mode " , & mode ) ) {
dev_err ( & pdev - > dev , " OF: pinmux mode not passed \n " ) ;
return - EINVAL ;
}
if ( set_mode ( pmx , mode ) ) {
dev_err ( & pdev - > dev , " OF: Couldn't configure mode: %x \n " ,
mode ) ;
return - EINVAL ;
}
}
platform_set_drvdata ( pdev , pmx ) ;
spear_pinctrl_desc . pins = machdata - > pins ;
spear_pinctrl_desc . npins = machdata - > npins ;
2016-02-24 14:44:07 +05:30
pmx - > pctl = devm_pinctrl_register ( & pdev - > dev , & spear_pinctrl_desc , pmx ) ;
2015-06-09 13:01:16 +09:00
if ( IS_ERR ( pmx - > pctl ) ) {
2012-03-28 22:27:07 +05:30
dev_err ( & pdev - > dev , " Couldn't register pinctrl driver \n " ) ;
2015-06-09 13:01:16 +09:00
return PTR_ERR ( pmx - > pctl ) ;
2012-03-28 22:27:07 +05:30
}
return 0 ;
}