diff options
-rw-r--r-- | drivers/pinctrl/core.c | 29 | ||||
-rw-r--r-- | include/linux/pinctrl/machine.h | 5 |
2 files changed, 31 insertions, 3 deletions
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 138e72f74377..a6386b3a3c15 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c | |||
@@ -43,6 +43,8 @@ struct pinctrl_maps { | |||
43 | unsigned num_maps; | 43 | unsigned num_maps; |
44 | }; | 44 | }; |
45 | 45 | ||
46 | static bool pinctrl_dummy_state; | ||
47 | |||
46 | /* Mutex taken by all entry points */ | 48 | /* Mutex taken by all entry points */ |
47 | DEFINE_MUTEX(pinctrl_mutex); | 49 | DEFINE_MUTEX(pinctrl_mutex); |
48 | 50 | ||
@@ -61,6 +63,19 @@ static LIST_HEAD(pinctrl_maps); | |||
61 | _i_ < _maps_node_->num_maps; \ | 63 | _i_ < _maps_node_->num_maps; \ |
62 | i++, _map_ = &_maps_node_->maps[_i_]) | 64 | i++, _map_ = &_maps_node_->maps[_i_]) |
63 | 65 | ||
66 | /** | ||
67 | * pinctrl_provide_dummies() - indicate if pinctrl provides dummy state support | ||
68 | * | ||
69 | * Usually this function is called by platforms without pinctrl driver support | ||
70 | * but run with some shared drivers using pinctrl APIs. | ||
71 | * After calling this function, the pinctrl core will return successfully | ||
72 | * with creating a dummy state for the driver to keep going smoothly. | ||
73 | */ | ||
74 | void pinctrl_provide_dummies(void) | ||
75 | { | ||
76 | pinctrl_dummy_state = true; | ||
77 | } | ||
78 | |||
64 | const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev) | 79 | const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev) |
65 | { | 80 | { |
66 | /* We're not allowed to register devices without name */ | 81 | /* We're not allowed to register devices without name */ |
@@ -719,8 +734,18 @@ static struct pinctrl_state *pinctrl_lookup_state_locked(struct pinctrl *p, | |||
719 | struct pinctrl_state *state; | 734 | struct pinctrl_state *state; |
720 | 735 | ||
721 | state = find_state(p, name); | 736 | state = find_state(p, name); |
722 | if (!state) | 737 | if (!state) { |
723 | return ERR_PTR(-ENODEV); | 738 | if (pinctrl_dummy_state) { |
739 | /* create dummy state */ | ||
740 | dev_dbg(p->dev, "using pinctrl dummy state (%s)\n", | ||
741 | name); | ||
742 | state = create_state(p, name); | ||
743 | if (IS_ERR(state)) | ||
744 | return state; | ||
745 | } else { | ||
746 | return ERR_PTR(-ENODEV); | ||
747 | } | ||
748 | } | ||
724 | 749 | ||
725 | return state; | 750 | return state; |
726 | } | 751 | } |
diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index 9c4a19867289..7d22ab00343f 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h | |||
@@ -154,7 +154,7 @@ struct pinctrl_map { | |||
154 | 154 | ||
155 | extern int pinctrl_register_mappings(struct pinctrl_map const *map, | 155 | extern int pinctrl_register_mappings(struct pinctrl_map const *map, |
156 | unsigned num_maps); | 156 | unsigned num_maps); |
157 | 157 | extern void pinctrl_provide_dummies(void); | |
158 | #else | 158 | #else |
159 | 159 | ||
160 | static inline int pinctrl_register_mappings(struct pinctrl_map const *map, | 160 | static inline int pinctrl_register_mappings(struct pinctrl_map const *map, |
@@ -163,5 +163,8 @@ static inline int pinctrl_register_mappings(struct pinctrl_map const *map, | |||
163 | return 0; | 163 | return 0; |
164 | } | 164 | } |
165 | 165 | ||
166 | static inline void pinctrl_provide_dummies(void) | ||
167 | { | ||
168 | } | ||
166 | #endif /* !CONFIG_PINCTRL */ | 169 | #endif /* !CONFIG_PINCTRL */ |
167 | #endif | 170 | #endif |