1
0
Fork 0

MLK-18744 staging: typec: tcpm: qos handling fix

Commit 661b7ec2359e ("MLK-17921-2 staging: typec: tcpm: add qos for
PD transfer") introduce qos for tcpm transfer between typec controller
and CPU, but the request and remove are not balanced well, the initial
request should be moved to tcpm_port_register as tcpm_init will be called
for every hard reset, and also move qos hold&release to where port state
changes.

Fixes: 661b7ec2359e ("MLK-17921-2 staging: typec: tcpm: add qos for PD transfer")
Acked-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Li Jun <jun.li@nxp.com>
pull/10/head
Li Jun 2018-07-03 09:22:22 +08:00 committed by Jason Liu
parent 7478ba3911
commit 50b9d0b752
1 changed files with 32 additions and 33 deletions

View File

@ -846,6 +846,33 @@ static int tcpm_pd_send_sink_caps(struct tcpm_port *port)
return tcpm_pd_transmit(port, TCPC_TX_SOP, &msg);
}
static void tcpm_qos_handling(struct tcpm_port *port)
{
enum tcpm_state idle_state;
if (port->typec_caps.type == TYPEC_PORT_UFP)
idle_state = SNK_UNATTACHED;
else if (port->typec_caps.type == TYPEC_PORT_DFP)
idle_state = SNK_UNATTACHED;
else if (port->typec_caps.type == TYPEC_PORT_DRP)
idle_state = DRP_TOGGLING;
else
return;
if ((port->prev_state == SNK_READY || port->prev_state == SRC_READY ||
port->prev_state == idle_state)) {
/* Hold high bus before leave those states */
request_bus_freq(BUS_FREQ_HIGH);
pm_qos_add_request(&port->pm_qos_req,
PM_QOS_CPU_DMA_LATENCY, 0);
} else if ((port->state == SNK_READY || port->state == SRC_READY ||
port->state == idle_state)) {
/* Release high bus after enter those states */
pm_qos_remove_request(&port->pm_qos_req);
release_bus_freq(BUS_FREQ_HIGH);
}
}
static void tcpm_set_state(struct tcpm_port *port, enum tcpm_state state,
unsigned int delay_ms)
{
@ -864,6 +891,7 @@ static void tcpm_set_state(struct tcpm_port *port, enum tcpm_state state,
port->delayed_state = INVALID_STATE;
port->prev_state = port->state;
port->state = state;
tcpm_qos_handling(port);
/*
* Don't re-queue the state machine work item if we're currently
* in the state machine and we're immediately changing states.
@ -2911,33 +2939,6 @@ static void run_state_machine(struct tcpm_port *port)
}
}
static void tcpm_qos_active(struct tcpm_port *port, bool on)
{
enum tcpm_state idle_state;
if (port->typec_caps.type == TYPEC_PORT_UFP)
idle_state = SNK_UNATTACHED;
else if (port->typec_caps.type == TYPEC_PORT_DFP)
idle_state = SNK_UNATTACHED;
else if (port->typec_caps.type == TYPEC_PORT_DRP)
idle_state = DRP_TOGGLING;
else
return;
if ((port->prev_state == SNK_READY || port->prev_state == SRC_READY ||
port->prev_state == idle_state) && on) {
/* Hold high bus before leave those states */
request_bus_freq(BUS_FREQ_HIGH);
pm_qos_add_request(&port->pm_qos_req,
PM_QOS_CPU_DMA_LATENCY, 0);
} else if ((port->state == SNK_READY || port->state == SRC_READY ||
port->state == idle_state) && !on) {
/* Release high bus after enter those states */
pm_qos_remove_request(&port->pm_qos_req);
release_bus_freq(BUS_FREQ_HIGH);
}
}
static void tcpm_state_machine_work(struct work_struct *work)
{
struct tcpm_port *port = container_of(work, struct tcpm_port,
@ -2958,9 +2959,9 @@ static void tcpm_state_machine_work(struct work_struct *work)
port->prev_state = port->state;
port->state = port->delayed_state;
port->delayed_state = INVALID_STATE;
tcpm_qos_handling(port);
}
tcpm_qos_active(port, true);
/*
* Continue running as long as we have (non-delayed) state changes
* to make.
@ -2971,8 +2972,6 @@ static void tcpm_state_machine_work(struct work_struct *work)
if (port->queued_message)
tcpm_send_queued_message(port);
} while (port->state != prev_state && !port->delayed_state);
tcpm_qos_active(port, false);
done:
port->state_machine_running = false;
mutex_unlock(&port->lock);
@ -3568,9 +3567,6 @@ static void tcpm_init(struct tcpm_port *port)
tcpm_reset_port(port);
request_bus_freq(BUS_FREQ_HIGH);
pm_qos_add_request(&port->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 0);
tcpm_set_state(port, tcpm_default_state(port), 0);
_tcpm_cc_change(port, cc1, cc2);
@ -3799,6 +3795,9 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
tcpm_debugfs_init(port);
mutex_lock(&port->lock);
request_bus_freq(BUS_FREQ_HIGH);
pm_qos_add_request(&port->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 0);
tcpm_init(port);
mutex_unlock(&port->lock);