aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBarry Song <Baohua.Song@csr.com>2012-08-22 22:47:54 -0400
committerBarry Song <Barry.Song@csr.com>2012-09-05 02:48:10 -0400
commit056876f6c73406c06d530d16d020177f5ec4a0bd (patch)
treef2ccb5d676cc62e2a9ef7ea759b3abaebc8b85e2 /drivers
parent434e1c574cc304eaff630f4e92ed239f7886815f (diff)
pinctrl: sirf: add DT-binding pinmux mapping support
This makes us possible to define pinmux mapping in board-specific DTS. prima2.dtsi provides all possible (groups,functions) configuration, and device in .dts select configurations from dtsi files. Signed-off-by: Barry Song <Baohua.Song@csr.com> Acked-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pinctrl/pinctrl-sirf.c58
1 files changed, 57 insertions, 1 deletions
diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c
index 7fca6ce5952b..304360cd213e 100644
--- a/drivers/pinctrl/pinctrl-sirf.c
+++ b/drivers/pinctrl/pinctrl-sirf.c
@@ -17,6 +17,7 @@
17#include <linux/pinctrl/pinctrl.h> 17#include <linux/pinctrl/pinctrl.h>
18#include <linux/pinctrl/pinmux.h> 18#include <linux/pinctrl/pinmux.h>
19#include <linux/pinctrl/consumer.h> 19#include <linux/pinctrl/consumer.h>
20#include <linux/pinctrl/machine.h>
20#include <linux/of.h> 21#include <linux/of.h>
21#include <linux/of_address.h> 22#include <linux/of_address.h>
22#include <linux/of_device.h> 23#include <linux/of_device.h>
@@ -916,11 +917,66 @@ static void sirfsoc_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s
916 seq_printf(s, " " DRIVER_NAME); 917 seq_printf(s, " " DRIVER_NAME);
917} 918}
918 919
920static int sirfsoc_dt_node_to_map(struct pinctrl_dev *pctldev,
921 struct device_node *np_config,
922 struct pinctrl_map **map, unsigned *num_maps)
923{
924 struct sirfsoc_pmx *spmx = pinctrl_dev_get_drvdata(pctldev);
925 struct device_node *np;
926 struct property *prop;
927 const char *function, *group;
928 int ret, index = 0, count = 0;
929
930 /* calculate number of maps required */
931 for_each_child_of_node(np_config, np) {
932 ret = of_property_read_string(np, "sirf,function", &function);
933 if (ret < 0)
934 return ret;
935
936 ret = of_property_count_strings(np, "sirf,pins");
937 if (ret < 0)
938 return ret;
939
940 count += ret;
941 }
942
943 if (!count) {
944 dev_err(spmx->dev, "No child nodes passed via DT\n");
945 return -ENODEV;
946 }
947
948 *map = kzalloc(sizeof(**map) * count, GFP_KERNEL);
949 if (!*map)
950 return -ENOMEM;
951
952 for_each_child_of_node(np_config, np) {
953 of_property_read_string(np, "sirf,function", &function);
954 of_property_for_each_string(np, "sirf,pins", prop, group) {
955 (*map)[index].type = PIN_MAP_TYPE_MUX_GROUP;
956 (*map)[index].data.mux.group = group;
957 (*map)[index].data.mux.function = function;
958 index++;
959 }
960 }
961
962 *num_maps = count;
963
964 return 0;
965}
966
967static void sirfsoc_dt_free_map(struct pinctrl_dev *pctldev,
968 struct pinctrl_map *map, unsigned num_maps)
969{
970 kfree(map);
971}
972
919static struct pinctrl_ops sirfsoc_pctrl_ops = { 973static struct pinctrl_ops sirfsoc_pctrl_ops = {
920 .get_groups_count = sirfsoc_get_groups_count, 974 .get_groups_count = sirfsoc_get_groups_count,
921 .get_group_name = sirfsoc_get_group_name, 975 .get_group_name = sirfsoc_get_group_name,
922 .get_group_pins = sirfsoc_get_group_pins, 976 .get_group_pins = sirfsoc_get_group_pins,
923 .pin_dbg_show = sirfsoc_pin_dbg_show, 977 .pin_dbg_show = sirfsoc_pin_dbg_show,
978 .dt_node_to_map = sirfsoc_dt_node_to_map,
979 .dt_free_map = sirfsoc_dt_free_map,
924}; 980};
925 981
926struct sirfsoc_pmx_func { 982struct sirfsoc_pmx_func {
@@ -1221,7 +1277,7 @@ out_no_gpio_remap:
1221} 1277}
1222 1278
1223static const struct of_device_id pinmux_ids[] __devinitconst = { 1279static const struct of_device_id pinmux_ids[] __devinitconst = {
1224 { .compatible = "sirf,prima2-gpio-pinmux" }, 1280 { .compatible = "sirf,prima2-pinctrl" },
1225 {} 1281 {}
1226}; 1282};
1227 1283