diff options
| -rw-r--r-- | drivers/reset/core.c | 49 | ||||
| -rw-r--r-- | include/linux/reset.h | 45 |
2 files changed, 65 insertions, 29 deletions
diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 272c1e4ecb5c..c79cce3a7b6d 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c | |||
| @@ -143,12 +143,18 @@ EXPORT_SYMBOL_GPL(devm_reset_controller_register); | |||
| 143 | * a no-op. | 143 | * a no-op. |
| 144 | * Consumers must not use reset_control_(de)assert on shared reset lines when | 144 | * Consumers must not use reset_control_(de)assert on shared reset lines when |
| 145 | * reset_control_reset has been used. | 145 | * reset_control_reset has been used. |
| 146 | * | ||
| 147 | * If rstc is NULL it is an optional reset and the function will just | ||
| 148 | * return 0. | ||
| 146 | */ | 149 | */ |
| 147 | int reset_control_reset(struct reset_control *rstc) | 150 | int reset_control_reset(struct reset_control *rstc) |
| 148 | { | 151 | { |
| 149 | int ret; | 152 | int ret; |
| 150 | 153 | ||
| 151 | if (WARN_ON(IS_ERR_OR_NULL(rstc))) | 154 | if (!rstc) |
| 155 | return 0; | ||
| 156 | |||
| 157 | if (WARN_ON(IS_ERR(rstc))) | ||
| 152 | return -EINVAL; | 158 | return -EINVAL; |
| 153 | 159 | ||
| 154 | if (!rstc->rcdev->ops->reset) | 160 | if (!rstc->rcdev->ops->reset) |
| @@ -182,10 +188,17 @@ EXPORT_SYMBOL_GPL(reset_control_reset); | |||
| 182 | * internal state to be reset, but must be prepared for this to happen. | 188 | * internal state to be reset, but must be prepared for this to happen. |
| 183 | * Consumers must not use reset_control_reset on shared reset lines when | 189 | * Consumers must not use reset_control_reset on shared reset lines when |
| 184 | * reset_control_(de)assert has been used. | 190 | * reset_control_(de)assert has been used. |
| 191 | * return 0. | ||
| 192 | * | ||
| 193 | * If rstc is NULL it is an optional reset and the function will just | ||
| 194 | * return 0. | ||
| 185 | */ | 195 | */ |
| 186 | int reset_control_assert(struct reset_control *rstc) | 196 | int reset_control_assert(struct reset_control *rstc) |
| 187 | { | 197 | { |
| 188 | if (WARN_ON(IS_ERR_OR_NULL(rstc))) | 198 | if (!rstc) |
| 199 | return 0; | ||
| 200 | |||
| 201 | if (WARN_ON(IS_ERR(rstc))) | ||
| 189 | return -EINVAL; | 202 | return -EINVAL; |
| 190 | 203 | ||
| 191 | if (!rstc->rcdev->ops->assert) | 204 | if (!rstc->rcdev->ops->assert) |
| @@ -213,10 +226,17 @@ EXPORT_SYMBOL_GPL(reset_control_assert); | |||
| 213 | * After calling this function, the reset is guaranteed to be deasserted. | 226 | * After calling this function, the reset is guaranteed to be deasserted. |
| 214 | * Consumers must not use reset_control_reset on shared reset lines when | 227 | * Consumers must not use reset_control_reset on shared reset lines when |
| 215 | * reset_control_(de)assert has been used. | 228 | * reset_control_(de)assert has been used. |
| 229 | * return 0. | ||
| 230 | * | ||
| 231 | * If rstc is NULL it is an optional reset and the function will just | ||
| 232 | * return 0. | ||
| 216 | */ | 233 | */ |
| 217 | int reset_control_deassert(struct reset_control *rstc) | 234 | int reset_control_deassert(struct reset_control *rstc) |
| 218 | { | 235 | { |
| 219 | if (WARN_ON(IS_ERR_OR_NULL(rstc))) | 236 | if (!rstc) |
| 237 | return 0; | ||
| 238 | |||
| 239 | if (WARN_ON(IS_ERR(rstc))) | ||
| 220 | return -EINVAL; | 240 | return -EINVAL; |
| 221 | 241 | ||
| 222 | if (!rstc->rcdev->ops->deassert) | 242 | if (!rstc->rcdev->ops->deassert) |
| @@ -237,12 +257,15 @@ EXPORT_SYMBOL_GPL(reset_control_deassert); | |||
| 237 | /** | 257 | /** |
| 238 | * reset_control_status - returns a negative errno if not supported, a | 258 | * reset_control_status - returns a negative errno if not supported, a |
| 239 | * positive value if the reset line is asserted, or zero if the reset | 259 | * positive value if the reset line is asserted, or zero if the reset |
| 240 | * line is not asserted. | 260 | * line is not asserted or if the desc is NULL (optional reset). |
| 241 | * @rstc: reset controller | 261 | * @rstc: reset controller |
| 242 | */ | 262 | */ |
| 243 | int reset_control_status(struct reset_control *rstc) | 263 | int reset_control_status(struct reset_control *rstc) |
| 244 | { | 264 | { |
| 245 | if (WARN_ON(IS_ERR_OR_NULL(rstc))) | 265 | if (!rstc) |
| 266 | return 0; | ||
| 267 | |||
| 268 | if (WARN_ON(IS_ERR(rstc))) | ||
| 246 | return -EINVAL; | 269 | return -EINVAL; |
| 247 | 270 | ||
| 248 | if (rstc->rcdev->ops->status) | 271 | if (rstc->rcdev->ops->status) |
| @@ -299,7 +322,8 @@ static void __reset_control_put(struct reset_control *rstc) | |||
| 299 | } | 322 | } |
| 300 | 323 | ||
| 301 | struct reset_control *__of_reset_control_get(struct device_node *node, | 324 | struct reset_control *__of_reset_control_get(struct device_node *node, |
| 302 | const char *id, int index, bool shared) | 325 | const char *id, int index, bool shared, |
| 326 | bool optional) | ||
| 303 | { | 327 | { |
| 304 | struct reset_control *rstc; | 328 | struct reset_control *rstc; |
| 305 | struct reset_controller_dev *r, *rcdev; | 329 | struct reset_controller_dev *r, *rcdev; |
| @@ -313,14 +337,18 @@ struct reset_control *__of_reset_control_get(struct device_node *node, | |||
| 313 | if (id) { | 337 | if (id) { |
| 314 | index = of_property_match_string(node, | 338 | index = of_property_match_string(node, |
| 315 | "reset-names", id); | 339 | "reset-names", id); |
| 340 | if (index == -EILSEQ) | ||
| 341 | return ERR_PTR(index); | ||
| 316 | if (index < 0) | 342 | if (index < 0) |
| 317 | return ERR_PTR(-ENOENT); | 343 | return optional ? NULL : ERR_PTR(-ENOENT); |
| 318 | } | 344 | } |
| 319 | 345 | ||
| 320 | ret = of_parse_phandle_with_args(node, "resets", "#reset-cells", | 346 | ret = of_parse_phandle_with_args(node, "resets", "#reset-cells", |
| 321 | index, &args); | 347 | index, &args); |
| 322 | if (ret) | 348 | if (ret == -EINVAL) |
| 323 | return ERR_PTR(ret); | 349 | return ERR_PTR(ret); |
| 350 | if (ret) | ||
| 351 | return optional ? NULL : ERR_PTR(ret); | ||
| 324 | 352 | ||
| 325 | mutex_lock(&reset_list_mutex); | 353 | mutex_lock(&reset_list_mutex); |
| 326 | rcdev = NULL; | 354 | rcdev = NULL; |
| @@ -379,7 +407,8 @@ static void devm_reset_control_release(struct device *dev, void *res) | |||
| 379 | } | 407 | } |
| 380 | 408 | ||
| 381 | struct reset_control *__devm_reset_control_get(struct device *dev, | 409 | struct reset_control *__devm_reset_control_get(struct device *dev, |
| 382 | const char *id, int index, bool shared) | 410 | const char *id, int index, bool shared, |
| 411 | bool optional) | ||
| 383 | { | 412 | { |
| 384 | struct reset_control **ptr, *rstc; | 413 | struct reset_control **ptr, *rstc; |
| 385 | 414 | ||
| @@ -389,7 +418,7 @@ struct reset_control *__devm_reset_control_get(struct device *dev, | |||
| 389 | return ERR_PTR(-ENOMEM); | 418 | return ERR_PTR(-ENOMEM); |
| 390 | 419 | ||
| 391 | rstc = __of_reset_control_get(dev ? dev->of_node : NULL, | 420 | rstc = __of_reset_control_get(dev ? dev->of_node : NULL, |
| 392 | id, index, shared); | 421 | id, index, shared, optional); |
| 393 | if (!IS_ERR(rstc)) { | 422 | if (!IS_ERR(rstc)) { |
| 394 | *ptr = rstc; | 423 | *ptr = rstc; |
| 395 | devres_add(dev, ptr); | 424 | devres_add(dev, ptr); |
diff --git a/include/linux/reset.h b/include/linux/reset.h index ec1d1fd28f5f..86b4ed75359e 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h | |||
| @@ -13,10 +13,12 @@ int reset_control_deassert(struct reset_control *rstc); | |||
| 13 | int reset_control_status(struct reset_control *rstc); | 13 | int reset_control_status(struct reset_control *rstc); |
| 14 | 14 | ||
| 15 | struct reset_control *__of_reset_control_get(struct device_node *node, | 15 | struct reset_control *__of_reset_control_get(struct device_node *node, |
| 16 | const char *id, int index, bool shared); | 16 | const char *id, int index, bool shared, |
| 17 | bool optional); | ||
| 17 | void reset_control_put(struct reset_control *rstc); | 18 | void reset_control_put(struct reset_control *rstc); |
| 18 | struct reset_control *__devm_reset_control_get(struct device *dev, | 19 | struct reset_control *__devm_reset_control_get(struct device *dev, |
| 19 | const char *id, int index, bool shared); | 20 | const char *id, int index, bool shared, |
| 21 | bool optional); | ||
| 20 | 22 | ||
| 21 | int __must_check device_reset(struct device *dev); | 23 | int __must_check device_reset(struct device *dev); |
| 22 | 24 | ||
| @@ -69,14 +71,15 @@ static inline int device_reset_optional(struct device *dev) | |||
| 69 | 71 | ||
| 70 | static inline struct reset_control *__of_reset_control_get( | 72 | static inline struct reset_control *__of_reset_control_get( |
| 71 | struct device_node *node, | 73 | struct device_node *node, |
| 72 | const char *id, int index, bool shared) | 74 | const char *id, int index, bool shared, |
| 75 | bool optional) | ||
| 73 | { | 76 | { |
| 74 | return ERR_PTR(-ENOTSUPP); | 77 | return ERR_PTR(-ENOTSUPP); |
| 75 | } | 78 | } |
| 76 | 79 | ||
| 77 | static inline struct reset_control *__devm_reset_control_get( | 80 | static inline struct reset_control *__devm_reset_control_get( |
| 78 | struct device *dev, | 81 | struct device *dev, const char *id, |
| 79 | const char *id, int index, bool shared) | 82 | int index, bool shared, bool optional) |
| 80 | { | 83 | { |
| 81 | return ERR_PTR(-ENOTSUPP); | 84 | return ERR_PTR(-ENOTSUPP); |
| 82 | } | 85 | } |
| @@ -104,7 +107,8 @@ __must_check reset_control_get_exclusive(struct device *dev, const char *id) | |||
| 104 | #ifndef CONFIG_RESET_CONTROLLER | 107 | #ifndef CONFIG_RESET_CONTROLLER |
| 105 | WARN_ON(1); | 108 | WARN_ON(1); |
| 106 | #endif | 109 | #endif |
| 107 | return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 0); | 110 | return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, false, |
| 111 | false); | ||
| 108 | } | 112 | } |
| 109 | 113 | ||
| 110 | /** | 114 | /** |
| @@ -132,19 +136,22 @@ __must_check reset_control_get_exclusive(struct device *dev, const char *id) | |||
| 132 | static inline struct reset_control *reset_control_get_shared( | 136 | static inline struct reset_control *reset_control_get_shared( |
| 133 | struct device *dev, const char *id) | 137 | struct device *dev, const char *id) |
| 134 | { | 138 | { |
| 135 | return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, true); | 139 | return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, true, |
| 140 | false); | ||
| 136 | } | 141 | } |
| 137 | 142 | ||
| 138 | static inline struct reset_control *reset_control_get_optional_exclusive( | 143 | static inline struct reset_control *reset_control_get_optional_exclusive( |
| 139 | struct device *dev, const char *id) | 144 | struct device *dev, const char *id) |
| 140 | { | 145 | { |
| 141 | return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, false); | 146 | return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, false, |
| 147 | true); | ||
| 142 | } | 148 | } |
| 143 | 149 | ||
| 144 | static inline struct reset_control *reset_control_get_optional_shared( | 150 | static inline struct reset_control *reset_control_get_optional_shared( |
| 145 | struct device *dev, const char *id) | 151 | struct device *dev, const char *id) |
| 146 | { | 152 | { |
| 147 | return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, true); | 153 | return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, true, |
| 154 | true); | ||
| 148 | } | 155 | } |
| 149 | 156 | ||
| 150 | /** | 157 | /** |
| @@ -160,7 +167,7 @@ static inline struct reset_control *reset_control_get_optional_shared( | |||
| 160 | static inline struct reset_control *of_reset_control_get_exclusive( | 167 | static inline struct reset_control *of_reset_control_get_exclusive( |
| 161 | struct device_node *node, const char *id) | 168 | struct device_node *node, const char *id) |
| 162 | { | 169 | { |
| 163 | return __of_reset_control_get(node, id, 0, 0); | 170 | return __of_reset_control_get(node, id, 0, false, false); |
| 164 | } | 171 | } |
| 165 | 172 | ||
| 166 | /** | 173 | /** |
| @@ -185,7 +192,7 @@ static inline struct reset_control *of_reset_control_get_exclusive( | |||
| 185 | static inline struct reset_control *of_reset_control_get_shared( | 192 | static inline struct reset_control *of_reset_control_get_shared( |
| 186 | struct device_node *node, const char *id) | 193 | struct device_node *node, const char *id) |
| 187 | { | 194 | { |
| 188 | return __of_reset_control_get(node, id, 0, true); | 195 | return __of_reset_control_get(node, id, 0, true, false); |
| 189 | } | 196 | } |
| 190 | 197 | ||
| 191 | /** | 198 | /** |
| @@ -202,7 +209,7 @@ static inline struct reset_control *of_reset_control_get_shared( | |||
| 202 | static inline struct reset_control *of_reset_control_get_exclusive_by_index( | 209 | static inline struct reset_control *of_reset_control_get_exclusive_by_index( |
| 203 | struct device_node *node, int index) | 210 | struct device_node *node, int index) |
| 204 | { | 211 | { |
| 205 | return __of_reset_control_get(node, NULL, index, false); | 212 | return __of_reset_control_get(node, NULL, index, false, false); |
| 206 | } | 213 | } |
| 207 | 214 | ||
| 208 | /** | 215 | /** |
| @@ -230,7 +237,7 @@ static inline struct reset_control *of_reset_control_get_exclusive_by_index( | |||
| 230 | static inline struct reset_control *of_reset_control_get_shared_by_index( | 237 | static inline struct reset_control *of_reset_control_get_shared_by_index( |
| 231 | struct device_node *node, int index) | 238 | struct device_node *node, int index) |
| 232 | { | 239 | { |
| 233 | return __of_reset_control_get(node, NULL, index, true); | 240 | return __of_reset_control_get(node, NULL, index, true, false); |
| 234 | } | 241 | } |
| 235 | 242 | ||
| 236 | /** | 243 | /** |
| @@ -252,7 +259,7 @@ __must_check devm_reset_control_get_exclusive(struct device *dev, | |||
| 252 | #ifndef CONFIG_RESET_CONTROLLER | 259 | #ifndef CONFIG_RESET_CONTROLLER |
| 253 | WARN_ON(1); | 260 | WARN_ON(1); |
| 254 | #endif | 261 | #endif |
| 255 | return __devm_reset_control_get(dev, id, 0, false); | 262 | return __devm_reset_control_get(dev, id, 0, false, false); |
| 256 | } | 263 | } |
| 257 | 264 | ||
| 258 | /** | 265 | /** |
| @@ -267,19 +274,19 @@ __must_check devm_reset_control_get_exclusive(struct device *dev, | |||
| 267 | static inline struct reset_control *devm_reset_control_get_shared( | 274 | static inline struct reset_control *devm_reset_control_get_shared( |
| 268 | struct device *dev, const char *id) | 275 | struct device *dev, const char *id) |
| 269 | { | 276 | { |
| 270 | return __devm_reset_control_get(dev, id, 0, true); | 277 | return __devm_reset_control_get(dev, id, 0, true, false); |
| 271 | } | 278 | } |
| 272 | 279 | ||
| 273 | static inline struct reset_control *devm_reset_control_get_optional_exclusive( | 280 | static inline struct reset_control *devm_reset_control_get_optional_exclusive( |
| 274 | struct device *dev, const char *id) | 281 | struct device *dev, const char *id) |
| 275 | { | 282 | { |
| 276 | return __devm_reset_control_get(dev, id, 0, false); | 283 | return __devm_reset_control_get(dev, id, 0, false, true); |
| 277 | } | 284 | } |
| 278 | 285 | ||
| 279 | static inline struct reset_control *devm_reset_control_get_optional_shared( | 286 | static inline struct reset_control *devm_reset_control_get_optional_shared( |
| 280 | struct device *dev, const char *id) | 287 | struct device *dev, const char *id) |
| 281 | { | 288 | { |
| 282 | return __devm_reset_control_get(dev, id, 0, true); | 289 | return __devm_reset_control_get(dev, id, 0, true, true); |
| 283 | } | 290 | } |
| 284 | 291 | ||
| 285 | /** | 292 | /** |
| @@ -297,7 +304,7 @@ static inline struct reset_control *devm_reset_control_get_optional_shared( | |||
| 297 | static inline struct reset_control * | 304 | static inline struct reset_control * |
| 298 | devm_reset_control_get_exclusive_by_index(struct device *dev, int index) | 305 | devm_reset_control_get_exclusive_by_index(struct device *dev, int index) |
| 299 | { | 306 | { |
| 300 | return __devm_reset_control_get(dev, NULL, index, false); | 307 | return __devm_reset_control_get(dev, NULL, index, false, false); |
| 301 | } | 308 | } |
| 302 | 309 | ||
| 303 | /** | 310 | /** |
| @@ -313,7 +320,7 @@ devm_reset_control_get_exclusive_by_index(struct device *dev, int index) | |||
| 313 | static inline struct reset_control * | 320 | static inline struct reset_control * |
| 314 | devm_reset_control_get_shared_by_index(struct device *dev, int index) | 321 | devm_reset_control_get_shared_by_index(struct device *dev, int index) |
| 315 | { | 322 | { |
| 316 | return __devm_reset_control_get(dev, NULL, index, true); | 323 | return __devm_reset_control_get(dev, NULL, index, true, false); |
| 317 | } | 324 | } |
| 318 | 325 | ||
| 319 | /* | 326 | /* |
