diff options
| -rw-r--r-- | drivers/reset/core.c | 71 | ||||
| -rw-r--r-- | include/linux/reset.h | 65 |
2 files changed, 96 insertions, 40 deletions
diff --git a/drivers/reset/core.c b/drivers/reset/core.c index d1b6089a0ef8..baeaf82d40d9 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c | |||
| @@ -43,7 +43,7 @@ struct reset_control { | |||
| 43 | * This simple translation function should be used for reset controllers | 43 | * This simple translation function should be used for reset controllers |
| 44 | * with 1:1 mapping, where reset lines can be indexed by number without gaps. | 44 | * with 1:1 mapping, where reset lines can be indexed by number without gaps. |
| 45 | */ | 45 | */ |
| 46 | int of_reset_simple_xlate(struct reset_controller_dev *rcdev, | 46 | static int of_reset_simple_xlate(struct reset_controller_dev *rcdev, |
| 47 | const struct of_phandle_args *reset_spec) | 47 | const struct of_phandle_args *reset_spec) |
| 48 | { | 48 | { |
| 49 | if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells)) | 49 | if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells)) |
| @@ -54,7 +54,6 @@ int of_reset_simple_xlate(struct reset_controller_dev *rcdev, | |||
| 54 | 54 | ||
| 55 | return reset_spec->args[0]; | 55 | return reset_spec->args[0]; |
| 56 | } | 56 | } |
| 57 | EXPORT_SYMBOL_GPL(of_reset_simple_xlate); | ||
| 58 | 57 | ||
| 59 | /** | 58 | /** |
| 60 | * reset_controller_register - register a reset controller device | 59 | * reset_controller_register - register a reset controller device |
| @@ -127,15 +126,16 @@ int reset_control_deassert(struct reset_control *rstc) | |||
| 127 | EXPORT_SYMBOL_GPL(reset_control_deassert); | 126 | EXPORT_SYMBOL_GPL(reset_control_deassert); |
| 128 | 127 | ||
| 129 | /** | 128 | /** |
| 130 | * reset_control_get - Lookup and obtain a reference to a reset controller. | 129 | * of_reset_control_get - Lookup and obtain a reference to a reset controller. |
| 131 | * @dev: device to be reset by the controller | 130 | * @node: device to be reset by the controller |
| 132 | * @id: reset line name | 131 | * @id: reset line name |
| 133 | * | 132 | * |
| 134 | * Returns a struct reset_control or IS_ERR() condition containing errno. | 133 | * Returns a struct reset_control or IS_ERR() condition containing errno. |
| 135 | * | 134 | * |
| 136 | * Use of id names is optional. | 135 | * Use of id names is optional. |
| 137 | */ | 136 | */ |
| 138 | struct reset_control *reset_control_get(struct device *dev, const char *id) | 137 | struct reset_control *of_reset_control_get(struct device_node *node, |
| 138 | const char *id) | ||
| 139 | { | 139 | { |
| 140 | struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER); | 140 | struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER); |
| 141 | struct reset_controller_dev *r, *rcdev; | 141 | struct reset_controller_dev *r, *rcdev; |
| @@ -144,13 +144,10 @@ struct reset_control *reset_control_get(struct device *dev, const char *id) | |||
| 144 | int rstc_id; | 144 | int rstc_id; |
| 145 | int ret; | 145 | int ret; |
| 146 | 146 | ||
| 147 | if (!dev) | ||
| 148 | return ERR_PTR(-EINVAL); | ||
| 149 | |||
| 150 | if (id) | 147 | if (id) |
| 151 | index = of_property_match_string(dev->of_node, | 148 | index = of_property_match_string(node, |
| 152 | "reset-names", id); | 149 | "reset-names", id); |
| 153 | ret = of_parse_phandle_with_args(dev->of_node, "resets", "#reset-cells", | 150 | ret = of_parse_phandle_with_args(node, "resets", "#reset-cells", |
| 154 | index, &args); | 151 | index, &args); |
| 155 | if (ret) | 152 | if (ret) |
| 156 | return ERR_PTR(ret); | 153 | return ERR_PTR(ret); |
| @@ -167,7 +164,7 @@ struct reset_control *reset_control_get(struct device *dev, const char *id) | |||
| 167 | 164 | ||
| 168 | if (!rcdev) { | 165 | if (!rcdev) { |
| 169 | mutex_unlock(&reset_controller_list_mutex); | 166 | mutex_unlock(&reset_controller_list_mutex); |
| 170 | return ERR_PTR(-ENODEV); | 167 | return ERR_PTR(-EPROBE_DEFER); |
| 171 | } | 168 | } |
| 172 | 169 | ||
| 173 | rstc_id = rcdev->of_xlate(rcdev, &args); | 170 | rstc_id = rcdev->of_xlate(rcdev, &args); |
| @@ -185,12 +182,35 @@ struct reset_control *reset_control_get(struct device *dev, const char *id) | |||
| 185 | return ERR_PTR(-ENOMEM); | 182 | return ERR_PTR(-ENOMEM); |
| 186 | } | 183 | } |
| 187 | 184 | ||
| 188 | rstc->dev = dev; | ||
| 189 | rstc->rcdev = rcdev; | 185 | rstc->rcdev = rcdev; |
| 190 | rstc->id = rstc_id; | 186 | rstc->id = rstc_id; |
| 191 | 187 | ||
| 192 | return rstc; | 188 | return rstc; |
| 193 | } | 189 | } |
| 190 | EXPORT_SYMBOL_GPL(of_reset_control_get); | ||
| 191 | |||
| 192 | /** | ||
| 193 | * reset_control_get - Lookup and obtain a reference to a reset controller. | ||
| 194 | * @dev: device to be reset by the controller | ||
| 195 | * @id: reset line name | ||
| 196 | * | ||
| 197 | * Returns a struct reset_control or IS_ERR() condition containing errno. | ||
| 198 | * | ||
| 199 | * Use of id names is optional. | ||
| 200 | */ | ||
| 201 | struct reset_control *reset_control_get(struct device *dev, const char *id) | ||
| 202 | { | ||
| 203 | struct reset_control *rstc; | ||
| 204 | |||
| 205 | if (!dev) | ||
| 206 | return ERR_PTR(-EINVAL); | ||
| 207 | |||
| 208 | rstc = of_reset_control_get(dev->of_node, id); | ||
| 209 | if (!IS_ERR(rstc)) | ||
| 210 | rstc->dev = dev; | ||
| 211 | |||
| 212 | return rstc; | ||
| 213 | } | ||
| 194 | EXPORT_SYMBOL_GPL(reset_control_get); | 214 | EXPORT_SYMBOL_GPL(reset_control_get); |
| 195 | 215 | ||
| 196 | /** | 216 | /** |
| @@ -243,33 +263,6 @@ struct reset_control *devm_reset_control_get(struct device *dev, const char *id) | |||
| 243 | } | 263 | } |
| 244 | EXPORT_SYMBOL_GPL(devm_reset_control_get); | 264 | EXPORT_SYMBOL_GPL(devm_reset_control_get); |
| 245 | 265 | ||
| 246 | static int devm_reset_control_match(struct device *dev, void *res, void *data) | ||
| 247 | { | ||
| 248 | struct reset_control **rstc = res; | ||
| 249 | if (WARN_ON(!rstc || !*rstc)) | ||
| 250 | return 0; | ||
| 251 | return *rstc == data; | ||
| 252 | } | ||
| 253 | |||
| 254 | /** | ||
| 255 | * devm_reset_control_put - resource managed reset_control_put() | ||
| 256 | * @rstc: reset controller to free | ||
| 257 | * | ||
| 258 | * Deallocate a reset control allocated withd devm_reset_control_get(). | ||
| 259 | * This function will not need to be called normally, as devres will take | ||
| 260 | * care of freeing the resource. | ||
| 261 | */ | ||
| 262 | void devm_reset_control_put(struct reset_control *rstc) | ||
| 263 | { | ||
| 264 | int ret; | ||
| 265 | |||
| 266 | ret = devres_release(rstc->dev, devm_reset_control_release, | ||
| 267 | devm_reset_control_match, rstc); | ||
| 268 | if (ret) | ||
| 269 | WARN_ON(ret); | ||
| 270 | } | ||
| 271 | EXPORT_SYMBOL_GPL(devm_reset_control_put); | ||
| 272 | |||
| 273 | /** | 266 | /** |
| 274 | * device_reset - find reset controller associated with the device | 267 | * device_reset - find reset controller associated with the device |
| 275 | * and perform reset | 268 | * and perform reset |
diff --git a/include/linux/reset.h b/include/linux/reset.h index 6082247feab1..c0eda5023d74 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h | |||
| @@ -4,6 +4,8 @@ | |||
| 4 | struct device; | 4 | struct device; |
| 5 | struct reset_control; | 5 | struct reset_control; |
| 6 | 6 | ||
| 7 | #ifdef CONFIG_RESET_CONTROLLER | ||
| 8 | |||
| 7 | int reset_control_reset(struct reset_control *rstc); | 9 | int reset_control_reset(struct reset_control *rstc); |
| 8 | int reset_control_assert(struct reset_control *rstc); | 10 | int reset_control_assert(struct reset_control *rstc); |
| 9 | int reset_control_deassert(struct reset_control *rstc); | 11 | int reset_control_deassert(struct reset_control *rstc); |
| @@ -12,6 +14,67 @@ struct reset_control *reset_control_get(struct device *dev, const char *id); | |||
| 12 | void reset_control_put(struct reset_control *rstc); | 14 | void reset_control_put(struct reset_control *rstc); |
| 13 | struct reset_control *devm_reset_control_get(struct device *dev, const char *id); | 15 | struct reset_control *devm_reset_control_get(struct device *dev, const char *id); |
| 14 | 16 | ||
| 15 | int device_reset(struct device *dev); | 17 | int __must_check device_reset(struct device *dev); |
| 18 | |||
| 19 | static inline int device_reset_optional(struct device *dev) | ||
| 20 | { | ||
| 21 | return device_reset(dev); | ||
| 22 | } | ||
| 23 | |||
| 24 | static inline struct reset_control *reset_control_get_optional( | ||
| 25 | struct device *dev, const char *id) | ||
| 26 | { | ||
| 27 | return reset_control_get(dev, id); | ||
| 28 | } | ||
| 29 | |||
| 30 | static inline struct reset_control *devm_reset_control_get_optional( | ||
| 31 | struct device *dev, const char *id) | ||
| 32 | { | ||
| 33 | return devm_reset_control_get(dev, id); | ||
| 34 | } | ||
| 35 | |||
| 36 | #else | ||
| 37 | |||
| 38 | static inline int reset_control_reset(struct reset_control *rstc) | ||
| 39 | { | ||
| 40 | WARN_ON(1); | ||
| 41 | return 0; | ||
| 42 | } | ||
| 43 | |||
| 44 | static inline int reset_control_assert(struct reset_control *rstc) | ||
| 45 | { | ||
| 46 | WARN_ON(1); | ||
| 47 | return 0; | ||
| 48 | } | ||
| 49 | |||
| 50 | static inline int reset_control_deassert(struct reset_control *rstc) | ||
| 51 | { | ||
| 52 | WARN_ON(1); | ||
| 53 | return 0; | ||
| 54 | } | ||
| 55 | |||
| 56 | static inline void reset_control_put(struct reset_control *rstc) | ||
| 57 | { | ||
| 58 | WARN_ON(1); | ||
| 59 | } | ||
| 60 | |||
| 61 | static inline int device_reset_optional(struct device *dev) | ||
| 62 | { | ||
| 63 | return -ENOSYS; | ||
| 64 | } | ||
| 65 | |||
| 66 | static inline struct reset_control *reset_control_get_optional( | ||
| 67 | struct device *dev, const char *id) | ||
| 68 | { | ||
| 69 | return ERR_PTR(-ENOSYS); | ||
| 70 | } | ||
| 71 | |||
| 72 | static inline struct reset_control *devm_reset_control_get_optional( | ||
| 73 | struct device *dev, const char *id) | ||
| 74 | { | ||
| 75 | return ERR_PTR(-ENOSYS); | ||
| 76 | } | ||
| 77 | |||
| 78 | #endif /* CONFIG_RESET_CONTROLLER */ | ||
| 16 | 79 | ||
| 17 | #endif | 80 | #endif |
