summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2016-12-27 12:19:59 -0500
committerLinus Walleij <linus.walleij@linaro.org>2017-01-03 03:26:16 -0500
commit99e4f67508e1dd51e21ebae2150c6e4f4eae068b (patch)
tree9c8b6d2e865a0f06988ca14e77a75f7bc2d5f03a
parenta51c158bf0f7cab3bd593586801a1a8b51c7c741 (diff)
pinctrl: core: Use delayed work for hogs
Having the pin control framework call pin controller functions before it's probe has finished is not nice as the pin controller device driver does not yet have struct pinctrl_dev handle. Let's fix this issue by adding deferred work for late init. This is needed to be able to add pinctrl generic helper functions that expect to know struct pinctrl_dev handle. Note that we now need to call create_pinctrl() directly as we don't want to add the pin controller to the list of controllers until the hogs are claimed. We also need to pass the pinctrl_dev to the device tree parser functions as they otherwise won't find the right controller at this point. Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/pinctrl/core.c90
-rw-r--r--drivers/pinctrl/core.h2
-rw-r--r--drivers/pinctrl/devicetree.c28
-rw-r--r--drivers/pinctrl/devicetree.h12
4 files changed, 93 insertions, 39 deletions
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index fb38e208f32d..d02e8def9506 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -720,7 +720,8 @@ static struct pinctrl_state *create_state(struct pinctrl *p,
720 return state; 720 return state;
721} 721}
722 722
723static int add_setting(struct pinctrl *p, struct pinctrl_map const *map) 723static int add_setting(struct pinctrl *p, struct pinctrl_dev *pctldev,
724 struct pinctrl_map const *map)
724{ 725{
725 struct pinctrl_state *state; 726 struct pinctrl_state *state;
726 struct pinctrl_setting *setting; 727 struct pinctrl_setting *setting;
@@ -744,7 +745,11 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map)
744 745
745 setting->type = map->type; 746 setting->type = map->type;
746 747
747 setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); 748 if (pctldev)
749 setting->pctldev = pctldev;
750 else
751 setting->pctldev =
752 get_pinctrl_dev_from_devname(map->ctrl_dev_name);
748 if (setting->pctldev == NULL) { 753 if (setting->pctldev == NULL) {
749 kfree(setting); 754 kfree(setting);
750 /* Do not defer probing of hogs (circular loop) */ 755 /* Do not defer probing of hogs (circular loop) */
@@ -800,7 +805,8 @@ static struct pinctrl *find_pinctrl(struct device *dev)
800 805
801static void pinctrl_free(struct pinctrl *p, bool inlist); 806static void pinctrl_free(struct pinctrl *p, bool inlist);
802 807
803static struct pinctrl *create_pinctrl(struct device *dev) 808static struct pinctrl *create_pinctrl(struct device *dev,
809 struct pinctrl_dev *pctldev)
804{ 810{
805 struct pinctrl *p; 811 struct pinctrl *p;
806 const char *devname; 812 const char *devname;
@@ -823,7 +829,7 @@ static struct pinctrl *create_pinctrl(struct device *dev)
823 INIT_LIST_HEAD(&p->states); 829 INIT_LIST_HEAD(&p->states);
824 INIT_LIST_HEAD(&p->dt_maps); 830 INIT_LIST_HEAD(&p->dt_maps);
825 831
826 ret = pinctrl_dt_to_map(p); 832 ret = pinctrl_dt_to_map(p, pctldev);
827 if (ret < 0) { 833 if (ret < 0) {
828 kfree(p); 834 kfree(p);
829 return ERR_PTR(ret); 835 return ERR_PTR(ret);
@@ -838,7 +844,7 @@ static struct pinctrl *create_pinctrl(struct device *dev)
838 if (strcmp(map->dev_name, devname)) 844 if (strcmp(map->dev_name, devname))
839 continue; 845 continue;
840 846
841 ret = add_setting(p, map); 847 ret = add_setting(p, pctldev, map);
842 /* 848 /*
843 * At this point the adding of a setting may: 849 * At this point the adding of a setting may:
844 * 850 *
@@ -899,7 +905,7 @@ struct pinctrl *pinctrl_get(struct device *dev)
899 return p; 905 return p;
900 } 906 }
901 907
902 return create_pinctrl(dev); 908 return create_pinctrl(dev, NULL);
903} 909}
904EXPORT_SYMBOL_GPL(pinctrl_get); 910EXPORT_SYMBOL_GPL(pinctrl_get);
905 911
@@ -1738,6 +1744,46 @@ static int pinctrl_check_ops(struct pinctrl_dev *pctldev)
1738} 1744}
1739 1745
1740/** 1746/**
1747 * pinctrl_late_init() - finish pin controller device registration
1748 * @work: work struct
1749 */
1750static void pinctrl_late_init(struct work_struct *work)
1751{
1752 struct pinctrl_dev *pctldev;
1753
1754 pctldev = container_of(work, struct pinctrl_dev, late_init.work);
1755
1756 pctldev->p = create_pinctrl(pctldev->dev, pctldev);
1757 if (!IS_ERR(pctldev->p)) {
1758 kref_get(&pctldev->p->users);
1759 pctldev->hog_default =
1760 pinctrl_lookup_state(pctldev->p, PINCTRL_STATE_DEFAULT);
1761 if (IS_ERR(pctldev->hog_default)) {
1762 dev_dbg(pctldev->dev,
1763 "failed to lookup the default state\n");
1764 } else {
1765 if (pinctrl_select_state(pctldev->p,
1766 pctldev->hog_default))
1767 dev_err(pctldev->dev,
1768 "failed to select default state\n");
1769 }
1770
1771 pctldev->hog_sleep =
1772 pinctrl_lookup_state(pctldev->p,
1773 PINCTRL_STATE_SLEEP);
1774 if (IS_ERR(pctldev->hog_sleep))
1775 dev_dbg(pctldev->dev,
1776 "failed to lookup the sleep state\n");
1777 }
1778
1779 mutex_lock(&pinctrldev_list_mutex);
1780 list_add_tail(&pctldev->node, &pinctrldev_list);
1781 mutex_unlock(&pinctrldev_list_mutex);
1782
1783 pinctrl_init_device_debugfs(pctldev);
1784}
1785
1786/**
1741 * pinctrl_register() - register a pin controller device 1787 * pinctrl_register() - register a pin controller device
1742 * @pctldesc: descriptor for this pin controller 1788 * @pctldesc: descriptor for this pin controller
1743 * @dev: parent device for this pin controller 1789 * @dev: parent device for this pin controller
@@ -1766,6 +1812,7 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
1766 pctldev->driver_data = driver_data; 1812 pctldev->driver_data = driver_data;
1767 INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL); 1813 INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL);
1768 INIT_LIST_HEAD(&pctldev->gpio_ranges); 1814 INIT_LIST_HEAD(&pctldev->gpio_ranges);
1815 INIT_DELAYED_WORK(&pctldev->late_init, pinctrl_late_init);
1769 pctldev->dev = dev; 1816 pctldev->dev = dev;
1770 mutex_init(&pctldev->mutex); 1817 mutex_init(&pctldev->mutex);
1771 1818
@@ -1800,32 +1847,10 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
1800 goto out_err; 1847 goto out_err;
1801 } 1848 }
1802 1849
1803 mutex_lock(&pinctrldev_list_mutex); 1850 if (pinctrl_dt_has_hogs(pctldev))
1804 list_add_tail(&pctldev->node, &pinctrldev_list); 1851 schedule_delayed_work(&pctldev->late_init, 0);
1805 mutex_unlock(&pinctrldev_list_mutex); 1852 else
1806 1853 pinctrl_late_init(&pctldev->late_init.work);
1807 pctldev->p = pinctrl_get(pctldev->dev);
1808
1809 if (!IS_ERR(pctldev->p)) {
1810 pctldev->hog_default =
1811 pinctrl_lookup_state(pctldev->p, PINCTRL_STATE_DEFAULT);
1812 if (IS_ERR(pctldev->hog_default)) {
1813 dev_dbg(dev, "failed to lookup the default state\n");
1814 } else {
1815 if (pinctrl_select_state(pctldev->p,
1816 pctldev->hog_default))
1817 dev_err(dev,
1818 "failed to select default state\n");
1819 }
1820
1821 pctldev->hog_sleep =
1822 pinctrl_lookup_state(pctldev->p,
1823 PINCTRL_STATE_SLEEP);
1824 if (IS_ERR(pctldev->hog_sleep))
1825 dev_dbg(dev, "failed to lookup the sleep state\n");
1826 }
1827
1828 pinctrl_init_device_debugfs(pctldev);
1829 1854
1830 return pctldev; 1855 return pctldev;
1831 1856
@@ -1848,6 +1873,7 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev)
1848 if (pctldev == NULL) 1873 if (pctldev == NULL)
1849 return; 1874 return;
1850 1875
1876 cancel_delayed_work_sync(&pctldev->late_init);
1851 mutex_lock(&pctldev->mutex); 1877 mutex_lock(&pctldev->mutex);
1852 pinctrl_remove_device_debugfs(pctldev); 1878 pinctrl_remove_device_debugfs(pctldev);
1853 mutex_unlock(&pctldev->mutex); 1879 mutex_unlock(&pctldev->mutex);
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h
index 747c423c11f3..722b2579166d 100644
--- a/drivers/pinctrl/core.h
+++ b/drivers/pinctrl/core.h
@@ -33,6 +33,7 @@ struct pinctrl_gpio_range;
33 * @p: result of pinctrl_get() for this device 33 * @p: result of pinctrl_get() for this device
34 * @hog_default: default state for pins hogged by this device 34 * @hog_default: default state for pins hogged by this device
35 * @hog_sleep: sleep state for pins hogged by this device 35 * @hog_sleep: sleep state for pins hogged by this device
36 * @late_init: delayed work for pin controller to finish registration
36 * @mutex: mutex taken on each pin controller specific action 37 * @mutex: mutex taken on each pin controller specific action
37 * @device_root: debugfs root for this device 38 * @device_root: debugfs root for this device
38 */ 39 */
@@ -47,6 +48,7 @@ struct pinctrl_dev {
47 struct pinctrl *p; 48 struct pinctrl *p;
48 struct pinctrl_state *hog_default; 49 struct pinctrl_state *hog_default;
49 struct pinctrl_state *hog_sleep; 50 struct pinctrl_state *hog_sleep;
51 struct delayed_work late_init;
50 struct mutex mutex; 52 struct mutex mutex;
51#ifdef CONFIG_DEBUG_FS 53#ifdef CONFIG_DEBUG_FS
52 struct dentry *device_root; 54 struct dentry *device_root;
diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
index 260908480075..e082bddad83a 100644
--- a/drivers/pinctrl/devicetree.c
+++ b/drivers/pinctrl/devicetree.c
@@ -100,11 +100,12 @@ struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
100 return get_pinctrl_dev_from_of_node(np); 100 return get_pinctrl_dev_from_of_node(np);
101} 101}
102 102
103static int dt_to_map_one_config(struct pinctrl *p, const char *statename, 103static int dt_to_map_one_config(struct pinctrl *p,
104 struct pinctrl_dev *pctldev,
105 const char *statename,
104 struct device_node *np_config) 106 struct device_node *np_config)
105{ 107{
106 struct device_node *np_pctldev; 108 struct device_node *np_pctldev;
107 struct pinctrl_dev *pctldev;
108 const struct pinctrl_ops *ops; 109 const struct pinctrl_ops *ops;
109 int ret; 110 int ret;
110 struct pinctrl_map *map; 111 struct pinctrl_map *map;
@@ -121,7 +122,8 @@ static int dt_to_map_one_config(struct pinctrl *p, const char *statename,
121 /* OK let's just assume this will appear later then */ 122 /* OK let's just assume this will appear later then */
122 return -EPROBE_DEFER; 123 return -EPROBE_DEFER;
123 } 124 }
124 pctldev = get_pinctrl_dev_from_of_node(np_pctldev); 125 if (!pctldev)
126 pctldev = get_pinctrl_dev_from_of_node(np_pctldev);
125 if (pctldev) 127 if (pctldev)
126 break; 128 break;
127 /* Do not defer probing of hogs (circular loop) */ 129 /* Do not defer probing of hogs (circular loop) */
@@ -166,7 +168,22 @@ static int dt_remember_dummy_state(struct pinctrl *p, const char *statename)
166 return dt_remember_or_free_map(p, statename, NULL, map, 1); 168 return dt_remember_or_free_map(p, statename, NULL, map, 1);
167} 169}
168 170
169int pinctrl_dt_to_map(struct pinctrl *p) 171bool pinctrl_dt_has_hogs(struct pinctrl_dev *pctldev)
172{
173 struct device_node *np;
174 struct property *prop;
175 int size;
176
177 np = pctldev->dev->of_node;
178 if (!np)
179 return false;
180
181 prop = of_find_property(np, "pinctrl-0", &size);
182
183 return prop ? true : false;
184}
185
186int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)
170{ 187{
171 struct device_node *np = p->dev->of_node; 188 struct device_node *np = p->dev->of_node;
172 int state, ret; 189 int state, ret;
@@ -233,7 +250,8 @@ int pinctrl_dt_to_map(struct pinctrl *p)
233 } 250 }
234 251
235 /* Parse the node */ 252 /* Parse the node */
236 ret = dt_to_map_one_config(p, statename, np_config); 253 ret = dt_to_map_one_config(p, pctldev, statename,
254 np_config);
237 of_node_put(np_config); 255 of_node_put(np_config);
238 if (ret < 0) 256 if (ret < 0)
239 goto err; 257 goto err;
diff --git a/drivers/pinctrl/devicetree.h b/drivers/pinctrl/devicetree.h
index c2d1a5505850..43d8d19aa5ee 100644
--- a/drivers/pinctrl/devicetree.h
+++ b/drivers/pinctrl/devicetree.h
@@ -20,8 +20,10 @@ struct of_phandle_args;
20 20
21#ifdef CONFIG_OF 21#ifdef CONFIG_OF
22 22
23bool pinctrl_dt_has_hogs(struct pinctrl_dev *pctldev);
24
23void pinctrl_dt_free_maps(struct pinctrl *p); 25void pinctrl_dt_free_maps(struct pinctrl *p);
24int pinctrl_dt_to_map(struct pinctrl *p); 26int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev);
25 27
26int pinctrl_count_index_with_args(const struct device_node *np, 28int pinctrl_count_index_with_args(const struct device_node *np,
27 const char *list_name); 29 const char *list_name);
@@ -32,7 +34,13 @@ int pinctrl_parse_index_with_args(const struct device_node *np,
32 34
33#else 35#else
34 36
35static inline int pinctrl_dt_to_map(struct pinctrl *p) 37static inline bool pinctrl_dt_has_hogs(struct pinctrl_dev *pctldev)
38{
39 return false;
40}
41
42static inline int pinctrl_dt_to_map(struct pinctrl *p,
43 struct pinctrl_dev *pctldev)
36{ 44{
37 return 0; 45 return 0;
38} 46}