diff options
| -rw-r--r-- | drivers/reset/core.c | 38 | ||||
| -rw-r--r-- | include/linux/reset-controller.h | 14 |
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 | */ |
| 160 | void reset_controller_add_lookup(struct reset_controller_dev *rcdev, | 159 | void 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 | } |
| 527 | EXPORT_SYMBOL_GPL(__of_reset_control_get); | 524 | EXPORT_SYMBOL_GPL(__of_reset_control_get); |
| 528 | 525 | ||
| 526 | static 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 | |||
| 529 | static struct reset_control * | 544 | static 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 | */ |
| 38 | struct reset_control_lookup { | 38 | struct 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; | |||
| 82 | int devm_reset_controller_register(struct device *dev, | 85 | int devm_reset_controller_register(struct device *dev, |
| 83 | struct reset_controller_dev *rcdev); | 86 | struct reset_controller_dev *rcdev); |
| 84 | 87 | ||
| 85 | void reset_controller_add_lookup(struct reset_controller_dev *rcdev, | 88 | void 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 |
