From: Benson Leung bleung@chromium.org
[ Upstream commit af833e7f7db3cf4c82f063668e1b52297a30ec18 ]
ucsi_psy_get_current_max would return 0mA as the maximum current if UCSI detected a BC or a Default USB Power sporce.
The comment in this function is true that we can't tell the difference between DCP/CDP or SDP chargers, but we can guarantee that at least 1-unit of USB 1.1/2.0 power is available, which is 100mA, which is a better fallback value than 0, which causes some userspaces, including the ChromeOS power manager, to regard this as a power source that is not providing any power.
In reality, 100mA is guaranteed from all sources in these classes.
Signed-off-by: Benson Leung bleung@chromium.org Reviewed-by: Jameson Thies jthies@google.com Reviewed-by: Heikki Krogerus heikki.krogerus@linux.intel.com Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.com Link: https://lore.kernel.org/r/20250717200805.3710473-1-bleung@chromium.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
Let me analyze the code changes more carefully. The commit introduces a new constant `UCSI_TYPEC_DEFAULT_CURRENT` set to 100mA and changes the behavior for BC 1.2 and Default USB power sources from returning 0mA to returning 100mA.
**Backport Status: YES**
This commit should be backported to stable kernel trees for the following reasons:
1. **Bug Fix for User-Facing Issue**: The commit fixes a clear bug where the UCSI driver was reporting 0mA as the maximum current for BC 1.2 and Default USB power sources. This incorrect value causes userspace power managers (specifically mentioned: ChromeOS power manager) to incorrectly interpret these power sources as not providing any power. This is a functionality bug that affects end users.
2. **Small and Contained Change**: The fix is minimal - it only changes two lines in the actual logic: - Line 167 in `ucsi_psy_get_current_max()`: Changes from `val->intval = 0;` to `val->intval = UCSI_TYPEC_DEFAULT_CURRENT * 1000;` - Adds a new constant definition in the header file
3. **Minimal Risk of Regression**: The change is very conservative: - It only affects the BC (Battery Charging) and DEFAULT power operation modes - The 100mA value is the guaranteed minimum from USB 1.1/2.0 specification (1 unit load) - It doesn't change behavior for any other power modes (PD, TypeC 1.5A, TypeC 3.0A) - The change is read-only (only affects reported values, doesn't change any hardware behavior)
4. **Clear Technical Justification**: The commit message correctly explains that while UCSI cannot distinguish between DCP/CDP or SDP chargers, all USB sources in these classes guarantee at least 100mA (1 unit load per USB specification). This is technically accurate and represents the minimum guaranteed current.
5. **No Architectural Changes**: This is a simple value correction that doesn't introduce new features or change any interfaces. It maintains the existing API while providing more accurate information.
6. **Fixes Real-World Issues**: The commit explicitly mentions that returning 0mA causes problems with userspace power management software, which would treat the power source as non-functional. This could lead to incorrect battery status reporting or power management decisions.
The change follows stable kernel rules by being a targeted fix for a specific bug that affects users, with minimal code changes and low regression risk.
drivers/usb/typec/ucsi/psy.c | 2 +- drivers/usb/typec/ucsi/ucsi.h | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/typec/ucsi/psy.c b/drivers/usb/typec/ucsi/psy.c index b35c6e07911e..9b0157063df0 100644 --- a/drivers/usb/typec/ucsi/psy.c +++ b/drivers/usb/typec/ucsi/psy.c @@ -163,7 +163,7 @@ static int ucsi_psy_get_current_max(struct ucsi_connector *con, case UCSI_CONSTAT_PWR_OPMODE_DEFAULT: /* UCSI can't tell b/w DCP/CDP or USB2/3x1/3x2 SDP chargers */ default: - val->intval = 0; + val->intval = UCSI_TYPEC_DEFAULT_CURRENT * 1000; break; } return 0; diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h index 7706f4e95125..51e745117dcb 100644 --- a/drivers/usb/typec/ucsi/ucsi.h +++ b/drivers/usb/typec/ucsi/ucsi.h @@ -340,9 +340,10 @@ struct ucsi { #define UCSI_MAX_SVID 5 #define UCSI_MAX_ALTMODES (UCSI_MAX_SVID * 6)
-#define UCSI_TYPEC_VSAFE5V 5000 -#define UCSI_TYPEC_1_5_CURRENT 1500 -#define UCSI_TYPEC_3_0_CURRENT 3000 +#define UCSI_TYPEC_VSAFE5V 5000 +#define UCSI_TYPEC_DEFAULT_CURRENT 100 +#define UCSI_TYPEC_1_5_CURRENT 1500 +#define UCSI_TYPEC_3_0_CURRENT 3000
struct ucsi_connector { int num;