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>
This commit is contained in:
parent
8bf874a474
commit
367764a4d1
|
@ -184,13 +184,14 @@ static int vexpress_config_schedule(struct vexpress_config_trans *trans)
|
||||||
|
|
||||||
spin_lock_irqsave(&bridge->transactions_lock, flags);
|
spin_lock_irqsave(&bridge->transactions_lock, flags);
|
||||||
|
|
||||||
|
if (list_empty(&bridge->transactions)) {
|
||||||
vexpress_config_dump_trans("Executing", trans);
|
vexpress_config_dump_trans("Executing", trans);
|
||||||
|
|
||||||
if (list_empty(&bridge->transactions))
|
|
||||||
status = bridge->info->func_exec(trans->func->func,
|
status = bridge->info->func_exec(trans->func->func,
|
||||||
trans->offset, trans->write, trans->data);
|
trans->offset, trans->write, trans->data);
|
||||||
else
|
} else {
|
||||||
|
vexpress_config_dump_trans("Queuing", trans);
|
||||||
status = VEXPRESS_CONFIG_STATUS_WAIT;
|
status = VEXPRESS_CONFIG_STATUS_WAIT;
|
||||||
|
}
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case VEXPRESS_CONFIG_STATUS_DONE:
|
case VEXPRESS_CONFIG_STATUS_DONE:
|
||||||
|
@ -212,25 +213,31 @@ void vexpress_config_complete(struct vexpress_config_bridge *bridge,
|
||||||
{
|
{
|
||||||
struct vexpress_config_trans *trans;
|
struct vexpress_config_trans *trans;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
const char *message = "Completed";
|
||||||
|
|
||||||
spin_lock_irqsave(&bridge->transactions_lock, flags);
|
spin_lock_irqsave(&bridge->transactions_lock, flags);
|
||||||
|
|
||||||
trans = list_first_entry(&bridge->transactions,
|
trans = list_first_entry(&bridge->transactions,
|
||||||
struct vexpress_config_trans, list);
|
struct vexpress_config_trans, list);
|
||||||
vexpress_config_dump_trans("Completed", trans);
|
|
||||||
|
|
||||||
trans->status = status;
|
trans->status = status;
|
||||||
|
|
||||||
|
do {
|
||||||
|
vexpress_config_dump_trans(message, trans);
|
||||||
list_del(&trans->list);
|
list_del(&trans->list);
|
||||||
|
|
||||||
if (!list_empty(&bridge->transactions)) {
|
|
||||||
vexpress_config_dump_trans("Pending", trans);
|
|
||||||
|
|
||||||
bridge->info->func_exec(trans->func->func, trans->offset,
|
|
||||||
trans->write, trans->data);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&bridge->transactions_lock, flags);
|
|
||||||
|
|
||||||
complete(&trans->completion);
|
complete(&trans->completion);
|
||||||
|
|
||||||
|
if (list_empty(&bridge->transactions))
|
||||||
|
break;
|
||||||
|
|
||||||
|
trans = list_first_entry(&bridge->transactions,
|
||||||
|
struct vexpress_config_trans, list);
|
||||||
|
vexpress_config_dump_trans("Executing pending", trans);
|
||||||
|
trans->status = bridge->info->func_exec(trans->func->func,
|
||||||
|
trans->offset, trans->write, trans->data);
|
||||||
|
message = "Finished pending";
|
||||||
|
} while (trans->status == VEXPRESS_CONFIG_STATUS_DONE);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&bridge->transactions_lock, flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(vexpress_config_complete);
|
EXPORT_SYMBOL(vexpress_config_complete);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue