Skip to content

Commit d872bed

Browse files
committed
reset: Add devres helpers to request pre-deasserted reset controls
Add devres helpers - devm_reset_control_bulk_get_exclusive_deasserted - devm_reset_control_bulk_get_optional_exclusive_deasserted - devm_reset_control_bulk_get_optional_shared_deasserted - devm_reset_control_bulk_get_shared_deasserted - devm_reset_control_get_exclusive_deasserted - devm_reset_control_get_optional_exclusive_deasserted - devm_reset_control_get_optional_shared_deasserted - devm_reset_control_get_shared_deasserted to request and immediately deassert reset controls. During cleanup, reset_control_assert() will be called automatically on the returned reset controls. Acked-by: Uwe Kleine-König <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Philipp Zabel <[email protected]>
1 parent dad35f7 commit d872bed

File tree

2 files changed

+159
-2
lines changed

2 files changed

+159
-2
lines changed

drivers/reset/core.c

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,23 +1236,46 @@ static void devm_reset_control_release(struct device *dev, void *res)
12361236
reset_control_put(*(struct reset_control **)res);
12371237
}
12381238

1239+
static void devm_reset_control_release_deasserted(struct device *dev, void *res)
1240+
{
1241+
struct reset_control *rstc = *(struct reset_control **)res;
1242+
1243+
reset_control_assert(rstc);
1244+
reset_control_put(rstc);
1245+
}
1246+
12391247
struct reset_control *
12401248
__devm_reset_control_get(struct device *dev, const char *id, int index,
12411249
enum reset_control_flags flags)
12421250
{
12431251
struct reset_control **ptr, *rstc;
1252+
bool deasserted = flags & RESET_CONTROL_FLAGS_BIT_DEASSERTED;
12441253

1245-
ptr = devres_alloc(devm_reset_control_release, sizeof(*ptr),
1254+
ptr = devres_alloc(deasserted ? devm_reset_control_release_deasserted :
1255+
devm_reset_control_release, sizeof(*ptr),
12461256
GFP_KERNEL);
12471257
if (!ptr)
12481258
return ERR_PTR(-ENOMEM);
12491259

1260+
flags &= ~RESET_CONTROL_FLAGS_BIT_DEASSERTED;
1261+
12501262
rstc = __reset_control_get(dev, id, index, flags);
12511263
if (IS_ERR_OR_NULL(rstc)) {
12521264
devres_free(ptr);
12531265
return rstc;
12541266
}
12551267

1268+
if (deasserted) {
1269+
int ret;
1270+
1271+
ret = reset_control_deassert(rstc);
1272+
if (ret) {
1273+
reset_control_put(rstc);
1274+
devres_free(ptr);
1275+
return ERR_PTR(ret);
1276+
}
1277+
}
1278+
12561279
*ptr = rstc;
12571280
devres_add(dev, ptr);
12581281

@@ -1272,24 +1295,45 @@ static void devm_reset_control_bulk_release(struct device *dev, void *res)
12721295
reset_control_bulk_put(devres->num_rstcs, devres->rstcs);
12731296
}
12741297

1298+
static void devm_reset_control_bulk_release_deasserted(struct device *dev, void *res)
1299+
{
1300+
struct reset_control_bulk_devres *devres = res;
1301+
1302+
reset_control_bulk_assert(devres->num_rstcs, devres->rstcs);
1303+
reset_control_bulk_put(devres->num_rstcs, devres->rstcs);
1304+
}
1305+
12751306
int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
12761307
struct reset_control_bulk_data *rstcs,
12771308
enum reset_control_flags flags)
12781309
{
12791310
struct reset_control_bulk_devres *ptr;
1311+
bool deasserted = flags & RESET_CONTROL_FLAGS_BIT_DEASSERTED;
12801312
int ret;
12811313

1282-
ptr = devres_alloc(devm_reset_control_bulk_release, sizeof(*ptr),
1314+
ptr = devres_alloc(deasserted ? devm_reset_control_bulk_release_deasserted :
1315+
devm_reset_control_bulk_release, sizeof(*ptr),
12831316
GFP_KERNEL);
12841317
if (!ptr)
12851318
return -ENOMEM;
12861319

1320+
flags &= ~RESET_CONTROL_FLAGS_BIT_DEASSERTED;
1321+
12871322
ret = __reset_control_bulk_get(dev, num_rstcs, rstcs, flags);
12881323
if (ret < 0) {
12891324
devres_free(ptr);
12901325
return ret;
12911326
}
12921327

1328+
if (deasserted) {
1329+
ret = reset_control_bulk_deassert(num_rstcs, rstcs);
1330+
if (ret) {
1331+
reset_control_bulk_put(num_rstcs, rstcs);
1332+
devres_free(ptr);
1333+
return ret;
1334+
}
1335+
}
1336+
12931337
ptr->num_rstcs = num_rstcs;
12941338
ptr->rstcs = rstcs;
12951339
devres_add(dev, ptr);

include/linux/reset.h

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,43 @@ struct reset_control_bulk_data {
2828
#define RESET_CONTROL_FLAGS_BIT_SHARED BIT(0) /* not exclusive */
2929
#define RESET_CONTROL_FLAGS_BIT_OPTIONAL BIT(1)
3030
#define RESET_CONTROL_FLAGS_BIT_ACQUIRED BIT(2) /* iff exclusive, not released */
31+
#define RESET_CONTROL_FLAGS_BIT_DEASSERTED BIT(3)
3132

3233
/**
3334
* enum reset_control_flags - Flags that can be passed to the reset_control_get functions
3435
* to determine the type of reset control.
3536
* These values cannot be OR'd.
3637
*
3738
* @RESET_CONTROL_EXCLUSIVE: exclusive, acquired,
39+
* @RESET_CONTROL_EXCLUSIVE_DEASSERTED: exclusive, acquired, deasserted
3840
* @RESET_CONTROL_EXCLUSIVE_RELEASED: exclusive, released,
3941
* @RESET_CONTROL_SHARED: shared
42+
* @RESET_CONTROL_SHARED_DEASSERTED: shared, deasserted
4043
* @RESET_CONTROL_OPTIONAL_EXCLUSIVE: optional, exclusive, acquired
44+
* @RESET_CONTROL_OPTIONAL_EXCLUSIVE_DEASSERTED: optional, exclusive, acquired, deasserted
4145
* @RESET_CONTROL_OPTIONAL_EXCLUSIVE_RELEASED: optional, exclusive, released
4246
* @RESET_CONTROL_OPTIONAL_SHARED: optional, shared
47+
* @RESET_CONTROL_OPTIONAL_SHARED_DEASSERTED: optional, shared, deasserted
4348
*/
4449
enum reset_control_flags {
4550
RESET_CONTROL_EXCLUSIVE = RESET_CONTROL_FLAGS_BIT_ACQUIRED,
51+
RESET_CONTROL_EXCLUSIVE_DEASSERTED = RESET_CONTROL_FLAGS_BIT_ACQUIRED |
52+
RESET_CONTROL_FLAGS_BIT_DEASSERTED,
4653
RESET_CONTROL_EXCLUSIVE_RELEASED = 0,
4754
RESET_CONTROL_SHARED = RESET_CONTROL_FLAGS_BIT_SHARED,
55+
RESET_CONTROL_SHARED_DEASSERTED = RESET_CONTROL_FLAGS_BIT_SHARED |
56+
RESET_CONTROL_FLAGS_BIT_DEASSERTED,
4857
RESET_CONTROL_OPTIONAL_EXCLUSIVE = RESET_CONTROL_FLAGS_BIT_OPTIONAL |
4958
RESET_CONTROL_FLAGS_BIT_ACQUIRED,
59+
RESET_CONTROL_OPTIONAL_EXCLUSIVE_DEASSERTED = RESET_CONTROL_FLAGS_BIT_OPTIONAL |
60+
RESET_CONTROL_FLAGS_BIT_ACQUIRED |
61+
RESET_CONTROL_FLAGS_BIT_DEASSERTED,
5062
RESET_CONTROL_OPTIONAL_EXCLUSIVE_RELEASED = RESET_CONTROL_FLAGS_BIT_OPTIONAL,
5163
RESET_CONTROL_OPTIONAL_SHARED = RESET_CONTROL_FLAGS_BIT_OPTIONAL |
5264
RESET_CONTROL_FLAGS_BIT_SHARED,
65+
RESET_CONTROL_OPTIONAL_SHARED_DEASSERTED = RESET_CONTROL_FLAGS_BIT_OPTIONAL |
66+
RESET_CONTROL_FLAGS_BIT_SHARED |
67+
RESET_CONTROL_FLAGS_BIT_DEASSERTED,
5368
};
5469

5570
#ifdef CONFIG_RESET_CONTROLLER
@@ -596,6 +611,25 @@ __must_check devm_reset_control_get_exclusive(struct device *dev,
596611
return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_EXCLUSIVE);
597612
}
598613

614+
/**
615+
* devm_reset_control_get_exclusive_deasserted - resource managed
616+
* reset_control_get_exclusive() +
617+
* reset_control_deassert()
618+
* @dev: device to be reset by the controller
619+
* @id: reset line name
620+
*
621+
* Managed reset_control_get_exclusive() + reset_control_deassert(). For reset
622+
* controllers returned from this function, reset_control_assert() +
623+
* reset_control_put() is called automatically on driver detach.
624+
*
625+
* See reset_control_get_exclusive() for more information.
626+
*/
627+
static inline struct reset_control * __must_check
628+
devm_reset_control_get_exclusive_deasserted(struct device *dev, const char *id)
629+
{
630+
return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_EXCLUSIVE_DEASSERTED);
631+
}
632+
599633
/**
600634
* devm_reset_control_bulk_get_exclusive - resource managed
601635
* reset_control_bulk_get_exclusive()
@@ -712,6 +746,25 @@ static inline struct reset_control *devm_reset_control_get_shared(
712746
return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_SHARED);
713747
}
714748

749+
/**
750+
* devm_reset_control_get_shared_deasserted - resource managed
751+
* reset_control_get_shared() +
752+
* reset_control_deassert()
753+
* @dev: device to be reset by the controller
754+
* @id: reset line name
755+
*
756+
* Managed reset_control_get_shared() + reset_control_deassert(). For reset
757+
* controllers returned from this function, reset_control_assert() +
758+
* reset_control_put() is called automatically on driver detach.
759+
*
760+
* See devm_reset_control_get_shared() for more information.
761+
*/
762+
static inline struct reset_control * __must_check
763+
devm_reset_control_get_shared_deasserted(struct device *dev, const char *id)
764+
{
765+
return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_SHARED_DEASSERTED);
766+
}
767+
715768
/**
716769
* devm_reset_control_bulk_get_shared - resource managed
717770
* reset_control_bulk_get_shared()
@@ -732,6 +785,28 @@ devm_reset_control_bulk_get_shared(struct device *dev, int num_rstcs,
732785
return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, RESET_CONTROL_SHARED);
733786
}
734787

788+
/**
789+
* devm_reset_control_bulk_get_shared_deasserted - resource managed
790+
* reset_control_bulk_get_shared() +
791+
* reset_control_bulk_deassert()
792+
* @dev: device to be reset by the controller
793+
* @num_rstcs: number of entries in rstcs array
794+
* @rstcs: array of struct reset_control_bulk_data with reset line names set
795+
*
796+
* Managed reset_control_bulk_get_shared() + reset_control_bulk_deassert(). For
797+
* reset controllers returned from this function, reset_control_bulk_assert() +
798+
* reset_control_bulk_put() are called automatically on driver detach.
799+
*
800+
* See devm_reset_control_bulk_get_shared() for more information.
801+
*/
802+
static inline int __must_check
803+
devm_reset_control_bulk_get_shared_deasserted(struct device *dev, int num_rstcs,
804+
struct reset_control_bulk_data *rstcs)
805+
{
806+
return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs,
807+
RESET_CONTROL_SHARED_DEASSERTED);
808+
}
809+
735810
/**
736811
* devm_reset_control_get_optional_exclusive - resource managed
737812
* reset_control_get_optional_exclusive()
@@ -750,6 +825,25 @@ static inline struct reset_control *devm_reset_control_get_optional_exclusive(
750825
return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_OPTIONAL_EXCLUSIVE);
751826
}
752827

828+
/**
829+
* devm_reset_control_get_optional_exclusive_deasserted - resource managed
830+
* reset_control_get_optional_exclusive() +
831+
* reset_control_deassert()
832+
* @dev: device to be reset by the controller
833+
* @id: reset line name
834+
*
835+
* Managed reset_control_get_optional_exclusive() + reset_control_deassert().
836+
* For reset controllers returned from this function, reset_control_assert() +
837+
* reset_control_put() is called automatically on driver detach.
838+
*
839+
* See devm_reset_control_get_optional_exclusive() for more information.
840+
*/
841+
static inline struct reset_control *
842+
devm_reset_control_get_optional_exclusive_deasserted(struct device *dev, const char *id)
843+
{
844+
return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_OPTIONAL_EXCLUSIVE_DEASSERTED);
845+
}
846+
753847
/**
754848
* devm_reset_control_bulk_get_optional_exclusive - resource managed
755849
* reset_control_bulk_get_optional_exclusive()
@@ -789,6 +883,25 @@ static inline struct reset_control *devm_reset_control_get_optional_shared(
789883
return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_OPTIONAL_SHARED);
790884
}
791885

886+
/**
887+
* devm_reset_control_get_optional_shared_deasserted - resource managed
888+
* reset_control_get_optional_shared() +
889+
* reset_control_deassert()
890+
* @dev: device to be reset by the controller
891+
* @id: reset line name
892+
*
893+
* Managed reset_control_get_optional_shared() + reset_control_deassert(). For
894+
* reset controllers returned from this function, reset_control_assert() +
895+
* reset_control_put() is called automatically on driver detach.
896+
*
897+
* See devm_reset_control_get_optional_shared() for more information.
898+
*/
899+
static inline struct reset_control *
900+
devm_reset_control_get_optional_shared_deasserted(struct device *dev, const char *id)
901+
{
902+
return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_OPTIONAL_SHARED_DEASSERTED);
903+
}
904+
792905
/**
793906
* devm_reset_control_bulk_get_optional_shared - resource managed
794907
* reset_control_bulk_get_optional_shared()

0 commit comments

Comments
 (0)