@@ -122,8 +122,8 @@ static int add_map_configs(struct device *dev, struct pinctrl_map **map,
122122 if (WARN_ON (* num_maps == * reserved_maps ))
123123 return - ENOSPC ;
124124
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 );
127127 if (!dup_configs )
128128 return - ENOMEM ;
129129
@@ -251,7 +251,6 @@ static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
251251{
252252 struct samsung_pinctrl_drv_data * drvdata ;
253253 unsigned reserved_maps ;
254- struct device_node * np ;
255254 int ret ;
256255
257256 drvdata = pinctrl_dev_get_drvdata (pctldev );
@@ -266,12 +265,11 @@ static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
266265 & reserved_maps ,
267266 num_maps );
268267
269- for_each_child_of_node (np_config , np ) {
268+ for_each_child_of_node_scoped (np_config , np ) {
270269 ret = samsung_dt_subnode_to_map (drvdata , pctldev -> dev , np , map ,
271270 & reserved_maps , num_maps );
272271 if (ret < 0 ) {
273272 samsung_dt_free_map (pctldev , * map , * num_maps );
274- of_node_put (np );
275273 return ret ;
276274 }
277275 }
@@ -823,16 +821,16 @@ static struct samsung_pmx_func *samsung_pinctrl_create_functions(
823821 struct device_node * func_np ;
824822
825823 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" ))
828826 continue ;
829827 ++ func_cnt ;
830828 continue ;
831829 }
832830
833831 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" ))
836834 continue ;
837835 ++ func_cnt ;
838836 }
@@ -849,31 +847,24 @@ static struct samsung_pmx_func *samsung_pinctrl_create_functions(
849847 * and create pin groups and pin function lists.
850848 */
851849 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 ) {
855851 if (!of_get_child_count (cfg_np )) {
856852 ret = samsung_pinctrl_create_function (dev , drvdata ,
857853 cfg_np , func );
858- if (ret < 0 ) {
859- of_node_put (cfg_np );
854+ if (ret < 0 )
860855 return ERR_PTR (ret );
861- }
862856 if (ret > 0 ) {
863857 ++ func ;
864858 ++ func_cnt ;
865859 }
866860 continue ;
867861 }
868862
869- for_each_child_of_node (cfg_np , func_np ) {
863+ for_each_child_of_node_scoped (cfg_np , func_np ) {
870864 ret = samsung_pinctrl_create_function (dev , drvdata ,
871865 func_np , func );
872- if (ret < 0 ) {
873- of_node_put (func_np );
874- of_node_put (cfg_np );
866+ if (ret < 0 )
875867 return ERR_PTR (ret );
876- }
877868 if (ret > 0 ) {
878869 ++ func ;
879870 ++ func_cnt ;
@@ -997,6 +988,77 @@ static int samsung_pinctrl_unregister(struct platform_device *pdev,
997988 return 0 ;
998989}
999990
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+
10001062static const struct gpio_chip samsung_gpiolib_chip = {
10011063 .request = gpiochip_generic_request ,
10021064 .free = gpiochip_generic_free ,
@@ -1006,6 +1068,7 @@ static const struct gpio_chip samsung_gpiolib_chip = {
10061068 .direction_output = samsung_gpio_direction_output ,
10071069 .to_irq = samsung_gpio_to_irq ,
10081070 .add_pin_ranges = samsung_add_pin_ranges ,
1071+ .set_config = samsung_gpio_set_config ,
10091072 .owner = THIS_MODULE ,
10101073};
10111074
@@ -1237,6 +1300,11 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
12371300 if (ctrl -> eint_wkup_init )
12381301 ctrl -> eint_wkup_init (drvdata );
12391302
1303+ if (ctrl -> pud_value_init )
1304+ ctrl -> pud_value_init (drvdata );
1305+ else
1306+ samsung_pud_value_init (drvdata );
1307+
12401308 ret = samsung_gpiolib_register (pdev , drvdata );
12411309 if (ret )
12421310 goto err_unregister ;
0 commit comments