diff options
| -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 | ||
