aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPawel Moll <pawel.moll@arm.com>2013-04-25 13:14:51 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2013-04-26 10:10:03 -0400
commit367764a4d1c8dfbf3e24bb0ffbc5eb8c5d5bf6eb (patch)
treed5eeeee09c3541532fc351ed1ff1063638e4a690
parent8bf874a474f17e2d0fca13456e773a11fa4715ca (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.c35
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}
235EXPORT_SYMBOL(vexpress_config_complete); 242EXPORT_SYMBOL(vexpress_config_complete);
236 243