aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/reset/core.c38
-rw-r--r--include/linux/reset-controller.h14
2 files changed, 39 insertions, 13 deletions
diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 06fa4907afc4..6488292e129c 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -153,12 +153,10 @@ EXPORT_SYMBOL_GPL(devm_reset_controller_register);
153 153
154/** 154/**
155 * reset_controller_add_lookup - register a set of lookup entries 155 * reset_controller_add_lookup - register a set of lookup entries
156 * @rcdev: initialized reset controller device owning the reset line
157 * @lookup: array of reset lookup entries 156 * @lookup: array of reset lookup entries
158 * @num_entries: number of entries in the lookup array 157 * @num_entries: number of entries in the lookup array
159 */ 158 */
160void reset_controller_add_lookup(struct reset_controller_dev *rcdev, 159void reset_controller_add_lookup(struct reset_control_lookup *lookup,
161 struct reset_control_lookup *lookup,
162 unsigned int num_entries) 160 unsigned int num_entries)
163{ 161{
164 struct reset_control_lookup *entry; 162 struct reset_control_lookup *entry;
@@ -168,13 +166,12 @@ void reset_controller_add_lookup(struct reset_controller_dev *rcdev,
168 for (i = 0; i < num_entries; i++) { 166 for (i = 0; i < num_entries; i++) {
169 entry = &lookup[i]; 167 entry = &lookup[i];
170 168
171 if (!entry->dev_id) { 169 if (!entry->dev_id || !entry->provider) {
172 pr_warn("%s(): reset lookup entry has no dev_id, skipping\n", 170 pr_warn("%s(): reset lookup entry badly specified, skipping\n",
173 __func__); 171 __func__);
174 continue; 172 continue;
175 } 173 }
176 174
177 entry->rcdev = rcdev;
178 list_add_tail(&entry->list, &reset_lookup_list); 175 list_add_tail(&entry->list, &reset_lookup_list);
179 } 176 }
180 mutex_unlock(&reset_lookup_mutex); 177 mutex_unlock(&reset_lookup_mutex);
@@ -526,11 +523,30 @@ struct reset_control *__of_reset_control_get(struct device_node *node,
526} 523}
527EXPORT_SYMBOL_GPL(__of_reset_control_get); 524EXPORT_SYMBOL_GPL(__of_reset_control_get);
528 525
526static struct reset_controller_dev *
527__reset_controller_by_name(const char *name)
528{
529 struct reset_controller_dev *rcdev;
530
531 lockdep_assert_held(&reset_list_mutex);
532
533 list_for_each_entry(rcdev, &reset_controller_list, list) {
534 if (!rcdev->dev)
535 continue;
536
537 if (!strcmp(name, dev_name(rcdev->dev)))
538 return rcdev;
539 }
540
541 return NULL;
542}
543
529static struct reset_control * 544static struct reset_control *
530__reset_control_get_from_lookup(struct device *dev, const char *con_id, 545__reset_control_get_from_lookup(struct device *dev, const char *con_id,
531 bool shared, bool optional) 546 bool shared, bool optional)
532{ 547{
533 const struct reset_control_lookup *lookup; 548 const struct reset_control_lookup *lookup;
549 struct reset_controller_dev *rcdev;
534 const char *dev_id = dev_name(dev); 550 const char *dev_id = dev_name(dev);
535 struct reset_control *rstc = NULL; 551 struct reset_control *rstc = NULL;
536 552
@@ -547,7 +563,15 @@ __reset_control_get_from_lookup(struct device *dev, const char *con_id,
547 ((con_id && lookup->con_id) && 563 ((con_id && lookup->con_id) &&
548 !strcmp(con_id, lookup->con_id))) { 564 !strcmp(con_id, lookup->con_id))) {
549 mutex_lock(&reset_list_mutex); 565 mutex_lock(&reset_list_mutex);
550 rstc = __reset_control_get_internal(lookup->rcdev, 566 rcdev = __reset_controller_by_name(lookup->provider);
567 if (!rcdev) {
568 mutex_unlock(&reset_list_mutex);
569 mutex_unlock(&reset_lookup_mutex);
570 /* Reset provider may not be ready yet. */
571 return ERR_PTR(-EPROBE_DEFER);
572 }
573
574 rstc = __reset_control_get_internal(rcdev,
551 lookup->index, 575 lookup->index,
552 shared); 576 shared);
553 mutex_unlock(&reset_list_mutex); 577 mutex_unlock(&reset_list_mutex);
diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h
index 25698f6c1fae..9326d671b6e6 100644
--- a/include/linux/reset-controller.h
+++ b/include/linux/reset-controller.h
@@ -30,24 +30,25 @@ struct of_phandle_args;
30 * struct reset_control_lookup - represents a single lookup entry 30 * struct reset_control_lookup - represents a single lookup entry
31 * 31 *
32 * @list: internal list of all reset lookup entries 32 * @list: internal list of all reset lookup entries
33 * @rcdev: reset controller device controlling this reset line 33 * @provider: name of the reset controller device controlling this reset line
34 * @index: ID of the reset controller in the reset controller device 34 * @index: ID of the reset controller in the reset controller device
35 * @dev_id: name of the device associated with this reset line 35 * @dev_id: name of the device associated with this reset line
36 * @con_id name of the reset line (can be NULL) 36 * @con_id name of the reset line (can be NULL)
37 */ 37 */
38struct reset_control_lookup { 38struct reset_control_lookup {
39 struct list_head list; 39 struct list_head list;
40 struct reset_controller_dev *rcdev; 40 const char *provider;
41 unsigned int index; 41 unsigned int index;
42 const char *dev_id; 42 const char *dev_id;
43 const char *con_id; 43 const char *con_id;
44}; 44};
45 45
46#define RESET_LOOKUP(_dev_id, _con_id, _index) \ 46#define RESET_LOOKUP(_provider, _index, _dev_id, _con_id) \
47 { \ 47 { \
48 .provider = _provider, \
49 .index = _index, \
48 .dev_id = _dev_id, \ 50 .dev_id = _dev_id, \
49 .con_id = _con_id, \ 51 .con_id = _con_id, \
50 .index = _index, \
51 } 52 }
52 53
53/** 54/**
@@ -57,6 +58,7 @@ struct reset_control_lookup {
57 * @owner: kernel module of the reset controller driver 58 * @owner: kernel module of the reset controller driver
58 * @list: internal list of reset controller devices 59 * @list: internal list of reset controller devices
59 * @reset_control_head: head of internal list of requested reset controls 60 * @reset_control_head: head of internal list of requested reset controls
61 * @dev: corresponding driver model device struct
60 * @of_node: corresponding device tree node as phandle target 62 * @of_node: corresponding device tree node as phandle target
61 * @of_reset_n_cells: number of cells in reset line specifiers 63 * @of_reset_n_cells: number of cells in reset line specifiers
62 * @of_xlate: translation function to translate from specifier as found in the 64 * @of_xlate: translation function to translate from specifier as found in the
@@ -68,6 +70,7 @@ struct reset_controller_dev {
68 struct module *owner; 70 struct module *owner;
69 struct list_head list; 71 struct list_head list;
70 struct list_head reset_control_head; 72 struct list_head reset_control_head;
73 struct device *dev;
71 struct device_node *of_node; 74 struct device_node *of_node;
72 int of_reset_n_cells; 75 int of_reset_n_cells;
73 int (*of_xlate)(struct reset_controller_dev *rcdev, 76 int (*of_xlate)(struct reset_controller_dev *rcdev,
@@ -82,8 +85,7 @@ struct device;
82int devm_reset_controller_register(struct device *dev, 85int devm_reset_controller_register(struct device *dev,
83 struct reset_controller_dev *rcdev); 86 struct reset_controller_dev *rcdev);
84 87
85void reset_controller_add_lookup(struct reset_controller_dev *rcdev, 88void reset_controller_add_lookup(struct reset_control_lookup *lookup,
86 struct reset_control_lookup *lookup,
87 unsigned int num_entries); 89 unsigned int num_entries);
88 90
89#endif 91#endif