Skip to content

Commit

Permalink
usb: typec: ucsi: Convert connector specific commands to bitmaps
Browse files Browse the repository at this point in the history
That allows the fields in those command data structures to
be easily validated. If an unsupported field is accessed, a
warning is generated.

This will not force UCSI version checks to be made in every
place where these data structures are accessed, but it will
make it easier to pinpoint issues that are caused by the
unconditional accesses to those fields, and perhaps more
importantly, allow those issues to be noticed immediately.

Signed-off-by: Heikki Krogerus <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
Heikki Krogerus authored and gregkh committed Nov 7, 2024
1 parent 474538b commit 226ff2e
Show file tree
Hide file tree
Showing 5 changed files with 240 additions and 196 deletions.
28 changes: 12 additions & 16 deletions drivers/usb/typec/ucsi/psy.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ static int ucsi_psy_get_online(struct ucsi_connector *con,
union power_supply_propval *val)
{
val->intval = UCSI_PSY_OFFLINE;
if (con->status.flags & UCSI_CONSTAT_CONNECTED &&
(con->status.flags & UCSI_CONSTAT_PWR_DIR) == TYPEC_SINK)
if (UCSI_CONSTAT(con, CONNECTED) &&
(UCSI_CONSTAT(con, PWR_DIR) == TYPEC_SINK))
val->intval = UCSI_PSY_FIXED_ONLINE;
return 0;
}
Expand All @@ -66,7 +66,7 @@ static int ucsi_psy_get_voltage_min(struct ucsi_connector *con,
{
u32 pdo;

switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) {
switch (UCSI_CONSTAT(con, PWR_OPMODE)) {
case UCSI_CONSTAT_PWR_OPMODE_PD:
pdo = con->src_pdos[0];
val->intval = pdo_fixed_voltage(pdo) * 1000;
Expand All @@ -89,7 +89,7 @@ static int ucsi_psy_get_voltage_max(struct ucsi_connector *con,
{
u32 pdo;

switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) {
switch (UCSI_CONSTAT(con, PWR_OPMODE)) {
case UCSI_CONSTAT_PWR_OPMODE_PD:
if (con->num_pdos > 0) {
pdo = con->src_pdos[con->num_pdos - 1];
Expand Down Expand Up @@ -117,7 +117,7 @@ static int ucsi_psy_get_voltage_now(struct ucsi_connector *con,
int index;
u32 pdo;

switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) {
switch (UCSI_CONSTAT(con, PWR_OPMODE)) {
case UCSI_CONSTAT_PWR_OPMODE_PD:
index = rdo_index(con->rdo);
if (index > 0) {
Expand Down Expand Up @@ -145,7 +145,7 @@ static int ucsi_psy_get_current_max(struct ucsi_connector *con,
{
u32 pdo;

switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) {
switch (UCSI_CONSTAT(con, PWR_OPMODE)) {
case UCSI_CONSTAT_PWR_OPMODE_PD:
if (con->num_pdos > 0) {
pdo = con->src_pdos[con->num_pdos - 1];
Expand Down Expand Up @@ -173,9 +173,7 @@ static int ucsi_psy_get_current_max(struct ucsi_connector *con,
static int ucsi_psy_get_current_now(struct ucsi_connector *con,
union power_supply_propval *val)
{
u16 flags = con->status.flags;

if (UCSI_CONSTAT_PWR_OPMODE(flags) == UCSI_CONSTAT_PWR_OPMODE_PD)
if (UCSI_CONSTAT(con, PWR_OPMODE) == UCSI_CONSTAT_PWR_OPMODE_PD)
val->intval = rdo_op_current(con->rdo) * 1000;
else
val->intval = 0;
Expand All @@ -185,30 +183,28 @@ static int ucsi_psy_get_current_now(struct ucsi_connector *con,
static int ucsi_psy_get_usb_type(struct ucsi_connector *con,
union power_supply_propval *val)
{
u16 flags = con->status.flags;

val->intval = POWER_SUPPLY_USB_TYPE_C;
if (flags & UCSI_CONSTAT_CONNECTED &&
UCSI_CONSTAT_PWR_OPMODE(flags) == UCSI_CONSTAT_PWR_OPMODE_PD)
if (UCSI_CONSTAT(con, CONNECTED) &&
UCSI_CONSTAT(con, PWR_OPMODE) == UCSI_CONSTAT_PWR_OPMODE_PD)
val->intval = POWER_SUPPLY_USB_TYPE_PD;

return 0;
}

static int ucsi_psy_get_charge_type(struct ucsi_connector *con, union power_supply_propval *val)
{
if (!(con->status.flags & UCSI_CONSTAT_CONNECTED)) {
if (!(UCSI_CONSTAT(con, CONNECTED))) {
val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
return 0;
}

/* The Battery Charging Cabability Status field is only valid in sink role. */
if ((con->status.flags & UCSI_CONSTAT_PWR_DIR) != TYPEC_SINK) {
if (UCSI_CONSTAT(con, PWR_DIR) != TYPEC_SINK) {
val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
return 0;
}

switch (UCSI_CONSTAT_BC_STATUS(con->status.pwr_status)) {
switch (UCSI_CONSTAT(con, BC_STATUS)) {
case UCSI_CONSTAT_BC_NOMINAL_CHARGING:
val->intval = POWER_SUPPLY_CHARGE_TYPE_STANDARD;
break;
Expand Down
28 changes: 14 additions & 14 deletions drivers/usb/typec/ucsi/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ DEFINE_EVENT(ucsi_log_command, ucsi_reset_ppm,
);

DECLARE_EVENT_CLASS(ucsi_log_connector_status,
TP_PROTO(int port, struct ucsi_connector_status *status),
TP_ARGS(port, status),
TP_PROTO(int port, struct ucsi_connector *con),
TP_ARGS(port, con),
TP_STRUCT__entry(
__field(int, port)
__field(u16, change)
Expand All @@ -55,14 +55,14 @@ DECLARE_EVENT_CLASS(ucsi_log_connector_status,
),
TP_fast_assign(
__entry->port = port - 1;
__entry->change = status->change;
__entry->opmode = UCSI_CONSTAT_PWR_OPMODE(status->flags);
__entry->connected = !!(status->flags & UCSI_CONSTAT_CONNECTED);
__entry->pwr_dir = !!(status->flags & UCSI_CONSTAT_PWR_DIR);
__entry->partner_flags = UCSI_CONSTAT_PARTNER_FLAGS(status->flags);
__entry->partner_type = UCSI_CONSTAT_PARTNER_TYPE(status->flags);
__entry->request_data_obj = status->request_data_obj;
__entry->bc_status = UCSI_CONSTAT_BC_STATUS(status->pwr_status);
__entry->change = UCSI_CONSTAT(con, CHANGE);
__entry->opmode = UCSI_CONSTAT(con, PWR_OPMODE);
__entry->connected = UCSI_CONSTAT(con, CONNECTED);
__entry->pwr_dir = UCSI_CONSTAT(con, PWR_DIR);
__entry->partner_flags = UCSI_CONSTAT(con, PARTNER_FLAGS);
__entry->partner_type = UCSI_CONSTAT(con, PARTNER_TYPE);
__entry->request_data_obj = UCSI_CONSTAT(con, RDO);
__entry->bc_status = UCSI_CONSTAT(con, BC_STATUS);
),
TP_printk("port%d status: change=%04x, opmode=%x, connected=%d, "
"sourcing=%d, partner_flags=%x, partner_type=%x, "
Expand All @@ -73,13 +73,13 @@ DECLARE_EVENT_CLASS(ucsi_log_connector_status,
);

DEFINE_EVENT(ucsi_log_connector_status, ucsi_connector_change,
TP_PROTO(int port, struct ucsi_connector_status *status),
TP_ARGS(port, status)
TP_PROTO(int port, struct ucsi_connector *con),
TP_ARGS(port, con)
);

DEFINE_EVENT(ucsi_log_connector_status, ucsi_register_port,
TP_PROTO(int port, struct ucsi_connector_status *status),
TP_ARGS(port, status)
TP_PROTO(int port, struct ucsi_connector *con),
TP_ARGS(port, con)
);

DECLARE_EVENT_CLASS(ucsi_log_register_altmode,
Expand Down
Loading

0 comments on commit 226ff2e

Please sign in to comment.