@@ -122,8 +122,8 @@ static int add_map_configs(struct device *dev, struct pinctrl_map **map,
122
122
if (WARN_ON (* num_maps == * reserved_maps ))
123
123
return - ENOSPC ;
124
124
125
- dup_configs = kmemdup (configs , num_configs * sizeof (* dup_configs ),
126
- GFP_KERNEL );
125
+ dup_configs = kmemdup_array (configs , num_configs , sizeof (* dup_configs ),
126
+ GFP_KERNEL );
127
127
if (!dup_configs )
128
128
return - ENOMEM ;
129
129
@@ -251,7 +251,6 @@ static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
251
251
{
252
252
struct samsung_pinctrl_drv_data * drvdata ;
253
253
unsigned reserved_maps ;
254
- struct device_node * np ;
255
254
int ret ;
256
255
257
256
drvdata = pinctrl_dev_get_drvdata (pctldev );
@@ -266,12 +265,11 @@ static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
266
265
& reserved_maps ,
267
266
num_maps );
268
267
269
- for_each_child_of_node (np_config , np ) {
268
+ for_each_child_of_node_scoped (np_config , np ) {
270
269
ret = samsung_dt_subnode_to_map (drvdata , pctldev -> dev , np , map ,
271
270
& reserved_maps , num_maps );
272
271
if (ret < 0 ) {
273
272
samsung_dt_free_map (pctldev , * map , * num_maps );
274
- of_node_put (np );
275
273
return ret ;
276
274
}
277
275
}
@@ -823,16 +821,16 @@ static struct samsung_pmx_func *samsung_pinctrl_create_functions(
823
821
struct device_node * func_np ;
824
822
825
823
if (!of_get_child_count (cfg_np )) {
826
- if (!of_find_property (cfg_np ,
827
- "samsung,pin-function" , NULL ))
824
+ if (!of_property_present (cfg_np ,
825
+ "samsung,pin-function" ))
828
826
continue ;
829
827
++ func_cnt ;
830
828
continue ;
831
829
}
832
830
833
831
for_each_child_of_node (cfg_np , func_np ) {
834
- if (!of_find_property (func_np ,
835
- "samsung,pin-function" , NULL ))
832
+ if (!of_property_present (func_np ,
833
+ "samsung,pin-function" ))
836
834
continue ;
837
835
++ func_cnt ;
838
836
}
@@ -849,31 +847,24 @@ static struct samsung_pmx_func *samsung_pinctrl_create_functions(
849
847
* and create pin groups and pin function lists.
850
848
*/
851
849
func_cnt = 0 ;
852
- for_each_child_of_node (dev_np , cfg_np ) {
853
- struct device_node * func_np ;
854
-
850
+ for_each_child_of_node_scoped (dev_np , cfg_np ) {
855
851
if (!of_get_child_count (cfg_np )) {
856
852
ret = samsung_pinctrl_create_function (dev , drvdata ,
857
853
cfg_np , func );
858
- if (ret < 0 ) {
859
- of_node_put (cfg_np );
854
+ if (ret < 0 )
860
855
return ERR_PTR (ret );
861
- }
862
856
if (ret > 0 ) {
863
857
++ func ;
864
858
++ func_cnt ;
865
859
}
866
860
continue ;
867
861
}
868
862
869
- for_each_child_of_node (cfg_np , func_np ) {
863
+ for_each_child_of_node_scoped (cfg_np , func_np ) {
870
864
ret = samsung_pinctrl_create_function (dev , drvdata ,
871
865
func_np , func );
872
- if (ret < 0 ) {
873
- of_node_put (func_np );
874
- of_node_put (cfg_np );
866
+ if (ret < 0 )
875
867
return ERR_PTR (ret );
876
- }
877
868
if (ret > 0 ) {
878
869
++ func ;
879
870
++ func_cnt ;
@@ -997,6 +988,77 @@ static int samsung_pinctrl_unregister(struct platform_device *pdev,
997
988
return 0 ;
998
989
}
999
990
991
+ static void samsung_pud_value_init (struct samsung_pinctrl_drv_data * drvdata )
992
+ {
993
+ unsigned int * pud_val = drvdata -> pud_val ;
994
+
995
+ pud_val [PUD_PULL_DISABLE ] = EXYNOS_PIN_PUD_PULL_DISABLE ;
996
+ pud_val [PUD_PULL_DOWN ] = EXYNOS_PIN_PID_PULL_DOWN ;
997
+ pud_val [PUD_PULL_UP ] = EXYNOS_PIN_PID_PULL_UP ;
998
+ }
999
+
1000
+ /*
1001
+ * Enable or Disable the pull-down and pull-up for the gpio pins in the
1002
+ * PUD register.
1003
+ */
1004
+ static void samsung_gpio_set_pud (struct gpio_chip * gc , unsigned int offset ,
1005
+ unsigned int value )
1006
+ {
1007
+ struct samsung_pin_bank * bank = gpiochip_get_data (gc );
1008
+ const struct samsung_pin_bank_type * type = bank -> type ;
1009
+ void __iomem * reg ;
1010
+ unsigned int data , mask ;
1011
+
1012
+ reg = bank -> pctl_base + bank -> pctl_offset ;
1013
+ data = readl (reg + type -> reg_offset [PINCFG_TYPE_PUD ]);
1014
+ mask = (1 << type -> fld_width [PINCFG_TYPE_PUD ]) - 1 ;
1015
+ data &= ~(mask << (offset * type -> fld_width [PINCFG_TYPE_PUD ]));
1016
+ data |= value << (offset * type -> fld_width [PINCFG_TYPE_PUD ]);
1017
+ writel (data , reg + type -> reg_offset [PINCFG_TYPE_PUD ]);
1018
+ }
1019
+
1020
+ /*
1021
+ * Identify the type of PUD config based on the gpiolib request to enable
1022
+ * or disable the PUD config.
1023
+ */
1024
+ static int samsung_gpio_set_config (struct gpio_chip * gc , unsigned int offset ,
1025
+ unsigned long config )
1026
+ {
1027
+ struct samsung_pin_bank * bank = gpiochip_get_data (gc );
1028
+ struct samsung_pinctrl_drv_data * drvdata = bank -> drvdata ;
1029
+ unsigned int value ;
1030
+ int ret = 0 ;
1031
+ unsigned long flags ;
1032
+
1033
+ switch (pinconf_to_config_param (config )) {
1034
+ case PIN_CONFIG_BIAS_DISABLE :
1035
+ value = drvdata -> pud_val [PUD_PULL_DISABLE ];
1036
+ break ;
1037
+ case PIN_CONFIG_BIAS_PULL_DOWN :
1038
+ value = drvdata -> pud_val [PUD_PULL_DOWN ];
1039
+ break ;
1040
+ case PIN_CONFIG_BIAS_PULL_UP :
1041
+ value = drvdata -> pud_val [PUD_PULL_UP ];
1042
+ break ;
1043
+ default :
1044
+ return - ENOTSUPP ;
1045
+ }
1046
+
1047
+ ret = clk_enable (drvdata -> pclk );
1048
+ if (ret ) {
1049
+ dev_err (drvdata -> dev , "failed to enable clock\n" );
1050
+ return ret ;
1051
+ }
1052
+
1053
+ raw_spin_lock_irqsave (& bank -> slock , flags );
1054
+ samsung_gpio_set_pud (gc , offset , value );
1055
+ raw_spin_unlock_irqrestore (& bank -> slock , flags );
1056
+
1057
+ clk_disable (drvdata -> pclk );
1058
+
1059
+ return ret ;
1060
+ }
1061
+
1000
1062
static const struct gpio_chip samsung_gpiolib_chip = {
1001
1063
.request = gpiochip_generic_request ,
1002
1064
.free = gpiochip_generic_free ,
@@ -1006,6 +1068,7 @@ static const struct gpio_chip samsung_gpiolib_chip = {
1006
1068
.direction_output = samsung_gpio_direction_output ,
1007
1069
.to_irq = samsung_gpio_to_irq ,
1008
1070
.add_pin_ranges = samsung_add_pin_ranges ,
1071
+ .set_config = samsung_gpio_set_config ,
1009
1072
.owner = THIS_MODULE ,
1010
1073
};
1011
1074
@@ -1237,6 +1300,11 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
1237
1300
if (ctrl -> eint_wkup_init )
1238
1301
ctrl -> eint_wkup_init (drvdata );
1239
1302
1303
+ if (ctrl -> pud_value_init )
1304
+ ctrl -> pud_value_init (drvdata );
1305
+ else
1306
+ samsung_pud_value_init (drvdata );
1307
+
1240
1308
ret = samsung_gpiolib_register (pdev , drvdata );
1241
1309
if (ret )
1242
1310
goto err_unregister ;
0 commit comments