Skip to content

Commit 57a18cc

Browse files
author
Desnes Nunes
committed
usb: typec: tcpci: Prevent Sink disconnection before vPpsShutdown in SPR PPS
JIRA: https://issues.redhat.com/browse/RHEL-78931 commit 4d27afb Author: Kyle Tso <[email protected]> Date: Tue, 14 Jan 2025 22:24:35 +0800 The Source can drop its output voltage to the minimum of the requested PPS APDO voltage range when it is in Current Limit Mode. If this voltage falls within the range of vPpsShutdown, the Source initiates a Hard Reset and discharges Vbus. However, currently the Sink may disconnect before the voltage reaches vPpsShutdown, leading to unexpected behavior. Prevent premature disconnection by setting the Sink's disconnect threshold to the minimum vPpsShutdown value. Additionally, consider the voltage drop due to IR drop when calculating the appropriate threshold. This ensures a robust and reliable interaction between the Source and Sink during SPR PPS Current Limit Mode operation. Fixes: 4288deb ("usb: typec: tcpci: Fix up sink disconnect thresholds for PD") Cc: stable <[email protected]> Signed-off-by: Kyle Tso <[email protected]> Reviewed-by: Heikki Krogerus <[email protected]> Reviewed-by: Badhri Jagan Sridharan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Desnes Nunes <[email protected]>
1 parent 65d70ab commit 57a18cc

File tree

3 files changed

+16
-8
lines changed

3 files changed

+16
-8
lines changed

drivers/usb/typec/tcpm/tcpci.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#define VPPS_NEW_MIN_PERCENT 95
2828
#define VPPS_VALID_MIN_MV 100
2929
#define VSINKDISCONNECT_PD_MIN_PERCENT 90
30+
#define VPPS_SHUTDOWN_MIN_PERCENT 85
3031

3132
struct tcpci {
3233
struct device *dev;
@@ -366,7 +367,8 @@ static int tcpci_enable_auto_vbus_discharge(struct tcpc_dev *dev, bool enable)
366367
}
367368

368369
static int tcpci_set_auto_vbus_discharge_threshold(struct tcpc_dev *dev, enum typec_pwr_opmode mode,
369-
bool pps_active, u32 requested_vbus_voltage_mv)
370+
bool pps_active, u32 requested_vbus_voltage_mv,
371+
u32 apdo_min_voltage_mv)
370372
{
371373
struct tcpci *tcpci = tcpc_to_tcpci(dev);
372374
unsigned int pwr_ctrl, threshold = 0;
@@ -388,9 +390,12 @@ static int tcpci_set_auto_vbus_discharge_threshold(struct tcpc_dev *dev, enum ty
388390
threshold = AUTO_DISCHARGE_DEFAULT_THRESHOLD_MV;
389391
} else if (mode == TYPEC_PWR_MODE_PD) {
390392
if (pps_active)
391-
threshold = ((VPPS_NEW_MIN_PERCENT * requested_vbus_voltage_mv / 100) -
392-
VSINKPD_MIN_IR_DROP_MV - VPPS_VALID_MIN_MV) *
393-
VSINKDISCONNECT_PD_MIN_PERCENT / 100;
393+
/*
394+
* To prevent disconnect when the source is in Current Limit Mode.
395+
* Set the threshold to the lowest possible voltage vPpsShutdown (min)
396+
*/
397+
threshold = VPPS_SHUTDOWN_MIN_PERCENT * apdo_min_voltage_mv / 100 -
398+
VSINKPD_MIN_IR_DROP_MV;
394399
else
395400
threshold = ((VSRC_NEW_MIN_PERCENT * requested_vbus_voltage_mv / 100) -
396401
VSINKPD_MIN_IR_DROP_MV - VSRC_VALID_MIN_MV) *

drivers/usb/typec/tcpm/tcpm.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2974,10 +2974,12 @@ static int tcpm_set_auto_vbus_discharge_threshold(struct tcpm_port *port,
29742974
return 0;
29752975

29762976
ret = port->tcpc->set_auto_vbus_discharge_threshold(port->tcpc, mode, pps_active,
2977-
requested_vbus_voltage);
2977+
requested_vbus_voltage,
2978+
port->pps_data.min_volt);
29782979
tcpm_log_force(port,
2979-
"set_auto_vbus_discharge_threshold mode:%d pps_active:%c vbus:%u ret:%d",
2980-
mode, pps_active ? 'y' : 'n', requested_vbus_voltage, ret);
2980+
"set_auto_vbus_discharge_threshold mode:%d pps_active:%c vbus:%u pps_apdo_min_volt:%u ret:%d",
2981+
mode, pps_active ? 'y' : 'n', requested_vbus_voltage,
2982+
port->pps_data.min_volt, ret);
29812983

29822984
return ret;
29832985
}

include/linux/usb/tcpm.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ struct tcpc_dev {
163163
void (*frs_sourcing_vbus)(struct tcpc_dev *dev);
164164
int (*enable_auto_vbus_discharge)(struct tcpc_dev *dev, bool enable);
165165
int (*set_auto_vbus_discharge_threshold)(struct tcpc_dev *dev, enum typec_pwr_opmode mode,
166-
bool pps_active, u32 requested_vbus_voltage);
166+
bool pps_active, u32 requested_vbus_voltage,
167+
u32 pps_apdo_min_voltage);
167168
bool (*is_vbus_vsafe0v)(struct tcpc_dev *dev);
168169
void (*set_partner_usb_comm_capable)(struct tcpc_dev *dev, bool enable);
169170
void (*check_contaminant)(struct tcpc_dev *dev);

0 commit comments

Comments
 (0)