diff options
author | Pawel Moll <pawel.moll@arm.com> | 2013-04-25 13:14:51 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-04-26 10:10:03 -0400 |
commit | 367764a4d1c8dfbf3e24bb0ffbc5eb8c5d5bf6eb (patch) | |
tree | d5eeeee09c3541532fc351ed1ff1063638e4a690 | |
parent | 8bf874a474f17e2d0fca13456e773a11fa4715ca (diff) |
mfd: vexpress: Handle pending config transactions
The config transactions "scheduler" was hopelessly broken,
repeating completed transaction instead of picking up
next pending one.
Fixed now. Also improved debug messages.
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
Reviewed-by: Jon Medhurst <tixy@linaro.org>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | drivers/mfd/vexpress-config.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/drivers/mfd/vexpress-config.c b/drivers/mfd/vexpress-config.c index 3c1723aa6225..84ce6b9daa3d 100644 --- a/drivers/mfd/vexpress-config.c +++ b/drivers/mfd/vexpress-config.c | |||
@@ -184,13 +184,14 @@ static int vexpress_config_schedule(struct vexpress_config_trans *trans) | |||
184 | 184 | ||
185 | spin_lock_irqsave(&bridge->transactions_lock, flags); | 185 | spin_lock_irqsave(&bridge->transactions_lock, flags); |
186 | 186 | ||
187 | vexpress_config_dump_trans("Executing", trans); | 187 | if (list_empty(&bridge->transactions)) { |
188 | 188 | vexpress_config_dump_trans("Executing", trans); | |
189 | if (list_empty(&bridge->transactions)) | ||
190 | status = bridge->info->func_exec(trans->func->func, | 189 | status = bridge->info->func_exec(trans->func->func, |
191 | trans->offset, trans->write, trans->data); | 190 | trans->offset, trans->write, trans->data); |
192 | else | 191 | } else { |
192 | vexpress_config_dump_trans("Queuing", trans); | ||
193 | status = VEXPRESS_CONFIG_STATUS_WAIT; | 193 | status = VEXPRESS_CONFIG_STATUS_WAIT; |
194 | } | ||
194 | 195 | ||
195 | switch (status) { | 196 | switch (status) { |
196 | case VEXPRESS_CONFIG_STATUS_DONE: | 197 | case VEXPRESS_CONFIG_STATUS_DONE: |
@@ -212,25 +213,31 @@ void vexpress_config_complete(struct vexpress_config_bridge *bridge, | |||
212 | { | 213 | { |
213 | struct vexpress_config_trans *trans; | 214 | struct vexpress_config_trans *trans; |
214 | unsigned long flags; | 215 | unsigned long flags; |
216 | const char *message = "Completed"; | ||
215 | 217 | ||
216 | spin_lock_irqsave(&bridge->transactions_lock, flags); | 218 | spin_lock_irqsave(&bridge->transactions_lock, flags); |
217 | 219 | ||
218 | trans = list_first_entry(&bridge->transactions, | 220 | trans = list_first_entry(&bridge->transactions, |
219 | struct vexpress_config_trans, list); | 221 | struct vexpress_config_trans, list); |
220 | vexpress_config_dump_trans("Completed", trans); | ||
221 | |||
222 | trans->status = status; | 222 | trans->status = status; |
223 | list_del(&trans->list); | ||
224 | 223 | ||
225 | if (!list_empty(&bridge->transactions)) { | 224 | do { |
226 | vexpress_config_dump_trans("Pending", trans); | 225 | vexpress_config_dump_trans(message, trans); |
226 | list_del(&trans->list); | ||
227 | complete(&trans->completion); | ||
227 | 228 | ||
228 | bridge->info->func_exec(trans->func->func, trans->offset, | 229 | if (list_empty(&bridge->transactions)) |
229 | trans->write, trans->data); | 230 | break; |
230 | } | 231 | |
231 | spin_unlock_irqrestore(&bridge->transactions_lock, flags); | 232 | trans = list_first_entry(&bridge->transactions, |
233 | struct vexpress_config_trans, list); | ||
234 | vexpress_config_dump_trans("Executing pending", trans); | ||
235 | trans->status = bridge->info->func_exec(trans->func->func, | ||
236 | trans->offset, trans->write, trans->data); | ||
237 | message = "Finished pending"; | ||
238 | } while (trans->status == VEXPRESS_CONFIG_STATUS_DONE); | ||
232 | 239 | ||
233 | complete(&trans->completion); | 240 | spin_unlock_irqrestore(&bridge->transactions_lock, flags); |
234 | } | 241 | } |
235 | EXPORT_SYMBOL(vexpress_config_complete); | 242 | EXPORT_SYMBOL(vexpress_config_complete); |
236 | 243 | ||