aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-tz1090.c
diff options
context:
space:
mode:
authorSherman Yin <syin@broadcom.com>2013-08-27 14:32:12 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-08-28 07:34:41 -0400
commit03b054e9696c3cbd3d5905ec96da15acd0a2fe8d (patch)
tree7123b780c194d350b3e5134c267e17262effb385 /drivers/pinctrl/pinctrl-tz1090.c
parentf5ba9c52bf1e236c4698c240955e5f119db62a28 (diff)
pinctrl: Pass all configs to driver on pin_config_set()
When setting pin configuration in the pinctrl framework, pin_config_set() or pin_config_group_set() is called in a loop to set one configuration at a time for the specified pin or group. This patch 1) removes the loop and 2) changes the API to pass the whole pin config array to the driver. It is now up to the driver to loop through the configs. This allows the driver to potentially combine configs and reduce the number of writes to pin config registers. All c files changed have been build-tested to verify the change compiles and that the corresponding .o is successfully generated. Signed-off-by: Sherman Yin <syin@broadcom.com> Reviewed-by: Christian Daudt <csd@broadcom.com> Reviewed-by: Matt Porter <matt.porter@linaro.org> Tested-by: Stephen Warren <swarren@nvidia.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-tz1090.c')
-rw-r--r--drivers/pinctrl/pinctrl-tz1090.c140
1 files changed, 80 insertions, 60 deletions
diff --git a/drivers/pinctrl/pinctrl-tz1090.c b/drivers/pinctrl/pinctrl-tz1090.c
index 72d955252e41..bc9cd7a7602e 100644
--- a/drivers/pinctrl/pinctrl-tz1090.c
+++ b/drivers/pinctrl/pinctrl-tz1090.c
@@ -1762,39 +1762,46 @@ static int tz1090_pinconf_get(struct pinctrl_dev *pctldev,
1762} 1762}
1763 1763
1764static int tz1090_pinconf_set(struct pinctrl_dev *pctldev, 1764static int tz1090_pinconf_set(struct pinctrl_dev *pctldev,
1765 unsigned int pin, unsigned long config) 1765 unsigned int pin, unsigned long *configs,
1766 unsigned num_configs)
1766{ 1767{
1767 struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 1768 struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
1768 enum pin_config_param param = pinconf_to_config_param(config); 1769 enum pin_config_param param;
1769 unsigned int arg = pinconf_to_config_argument(config); 1770 unsigned int arg;
1770 int ret; 1771 int ret;
1771 u32 reg, width, mask, shift, val, tmp; 1772 u32 reg, width, mask, shift, val, tmp;
1772 unsigned long flags; 1773 unsigned long flags;
1774 int i;
1773 1775
1774 dev_dbg(pctldev->dev, "%s(pin=%s, config=%#lx)\n", 1776 for (i = 0; i < num_configs; i++) {
1775 __func__, tz1090_pins[pin].name, config); 1777 param = pinconf_to_config_param(configs[i]);
1778 arg = pinconf_to_config_argument(configs[i]);
1776 1779
1777 /* Get register information */ 1780 dev_dbg(pctldev->dev, "%s(pin=%s, config=%#lx)\n",
1778 ret = tz1090_pinconf_reg(pctldev, pin, param, true, 1781 __func__, tz1090_pins[pin].name, configs[i]);
1779 &reg, &width, &mask, &shift, &val);
1780 if (ret < 0)
1781 return ret;
1782 1782
1783 /* Unpack argument and range check it */ 1783 /* Get register information */
1784 if (arg > 1) { 1784 ret = tz1090_pinconf_reg(pctldev, pin, param, true,
1785 dev_dbg(pctldev->dev, "%s: arg %u out of range\n", 1785 &reg, &width, &mask, &shift, &val);
1786 __func__, arg); 1786 if (ret < 0)
1787 return -EINVAL; 1787 return ret;
1788 }
1789 1788
1790 /* Write register field */ 1789 /* Unpack argument and range check it */
1791 __global_lock2(flags); 1790 if (arg > 1) {
1792 tmp = pmx_read(pmx, reg); 1791 dev_dbg(pctldev->dev, "%s: arg %u out of range\n",
1793 tmp &= ~mask; 1792 __func__, arg);
1794 if (arg) 1793 return -EINVAL;
1795 tmp |= val << shift; 1794 }
1796 pmx_write(pmx, tmp, reg); 1795
1797 __global_unlock2(flags); 1796 /* Write register field */
1797 __global_lock2(flags);
1798 tmp = pmx_read(pmx, reg);
1799 tmp &= ~mask;
1800 if (arg)
1801 tmp |= val << shift;
1802 pmx_write(pmx, tmp, reg);
1803 __global_unlock2(flags);
1804 } /* for each config */
1798 1805
1799 return 0; 1806 return 0;
1800} 1807}
@@ -1894,68 +1901,81 @@ static int tz1090_pinconf_group_get(struct pinctrl_dev *pctldev,
1894} 1901}
1895 1902
1896static int tz1090_pinconf_group_set(struct pinctrl_dev *pctldev, 1903static int tz1090_pinconf_group_set(struct pinctrl_dev *pctldev,
1897 unsigned int group, unsigned long config) 1904 unsigned int group, unsigned long *configs,
1905 unsigned num_configs)
1898{ 1906{
1899 struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 1907 struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
1900 const struct tz1090_pingroup *g; 1908 const struct tz1090_pingroup *g;
1901 enum pin_config_param param = pinconf_to_config_param(config); 1909 enum pin_config_param param;
1902 unsigned int arg, pin, i; 1910 unsigned int arg, pin, i;
1903 const unsigned int *pit; 1911 const unsigned int *pit;
1904 int ret; 1912 int ret;
1905 u32 reg, width, mask, shift, val; 1913 u32 reg, width, mask, shift, val;
1906 unsigned long flags; 1914 unsigned long flags;
1907 const int *map; 1915 const int *map;
1916 int j;
1908 1917
1909 if (group >= ARRAY_SIZE(tz1090_groups)) { 1918 if (group >= ARRAY_SIZE(tz1090_groups)) {
1910 pin = group - ARRAY_SIZE(tz1090_groups); 1919 pin = group - ARRAY_SIZE(tz1090_groups);
1911 return tz1090_pinconf_set(pctldev, pin, config); 1920 return tz1090_pinconf_set(pctldev, pin, configs, num_configs);
1912 } 1921 }
1913 1922
1914 g = &tz1090_groups[group]; 1923 g = &tz1090_groups[group];
1915 if (g->npins == 1) { 1924 if (g->npins == 1) {
1916 pin = g->pins[0]; 1925 pin = g->pins[0];
1917 ret = tz1090_pinconf_set(pctldev, pin, config); 1926 ret = tz1090_pinconf_set(pctldev, pin, configs, num_configs);
1918 if (ret != -ENOTSUPP) 1927 if (ret != -ENOTSUPP)
1919 return ret; 1928 return ret;
1920 } 1929 }
1921 1930
1922 dev_dbg(pctldev->dev, "%s(group=%s, config=%#lx)\n", 1931 for (j = 0; j < num_configs; j++) {
1923 __func__, g->name, config); 1932 param = pinconf_to_config_param(configs[j]);
1924 1933
1925 /* Get register information */ 1934 dev_dbg(pctldev->dev, "%s(group=%s, config=%#lx)\n",
1926 ret = tz1090_pinconf_group_reg(pctldev, g, param, true, 1935 __func__, g->name, configs[j]);
1927 &reg, &width, &mask, &shift, &map);
1928 if (ret < 0) {
1929 /*
1930 * Maybe we're trying to set a per-pin configuration of a group,
1931 * so do the pins one by one. This is mainly as a convenience.
1932 */
1933 for (i = 0, pit = g->pins; i < g->npins; ++i, ++pit) {
1934 ret = tz1090_pinconf_set(pctldev, *pit, config);
1935 if (ret)
1936 return ret;
1937 }
1938 return 0;
1939 }
1940 1936
1941 /* Unpack argument and map it to register value */ 1937 /* Get register information */
1942 arg = pinconf_to_config_argument(config); 1938 ret = tz1090_pinconf_group_reg(pctldev, g, param, true, &reg,
1943 for (i = 0; i < BIT(width); ++i) { 1939 &width, &mask, &shift, &map);
1944 if (map[i] == arg || (map[i] == -EINVAL && !arg)) { 1940 if (ret < 0) {
1945 /* Write register field */ 1941 /*
1946 __global_lock2(flags); 1942 * Maybe we're trying to set a per-pin configuration
1947 val = pmx_read(pmx, reg); 1943 * of a group, so do the pins one by one. This is
1948 val &= ~mask; 1944 * mainly as a convenience.
1949 val |= i << shift; 1945 */
1950 pmx_write(pmx, val, reg); 1946 for (i = 0, pit = g->pins; i < g->npins; ++i, ++pit) {
1951 __global_unlock2(flags); 1947 ret = tz1090_pinconf_set(pctldev, *pit, configs,
1948 num_configs);
1949 if (ret)
1950 return ret;
1951 }
1952 return 0; 1952 return 0;
1953 } 1953 }
1954 }
1955 1954
1956 dev_dbg(pctldev->dev, "%s: arg %u not supported\n", 1955 /* Unpack argument and map it to register value */
1957 __func__, arg); 1956 arg = pinconf_to_config_argument(configs[j]);
1958 return -EINVAL; 1957 for (i = 0; i < BIT(width); ++i) {
1958 if (map[i] == arg || (map[i] == -EINVAL && !arg)) {
1959 /* Write register field */
1960 __global_lock2(flags);
1961 val = pmx_read(pmx, reg);
1962 val &= ~mask;
1963 val |= i << shift;
1964 pmx_write(pmx, val, reg);
1965 __global_unlock2(flags);
1966 goto next_config;
1967 }
1968 }
1969
1970 dev_dbg(pctldev->dev, "%s: arg %u not supported\n",
1971 __func__, arg);
1972 return -EINVAL;
1973
1974next_config:
1975 ;
1976 } /* for each config */
1977
1978 return 0;
1959} 1979}
1960 1980
1961static struct pinconf_ops tz1090_pinconf_ops = { 1981static struct pinconf_ops tz1090_pinconf_ops = {