Skip to content

Commit 584e8df

Browse files
lumaggregkh
authored andcommitted
usb: typec: ucsi: extract common code for command handling
Extract common functions to handle command sending and to handle events from UCSI. This ensures that all UCSI glue drivers handle the ACKs in the same way. The CCG driver used DEV_CMD_PENDING both for internal firmware-related commands and for UCSI control handling. Leave the former use case intact. Tested-by: Heikki Krogerus <[email protected]> Reviewed-by: Heikki Krogerus <[email protected]> Signed-off-by: Dmitry Baryshkov <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e1870c1 commit 584e8df

File tree

7 files changed

+67
-203
lines changed

7 files changed

+67
-203
lines changed

drivers/usb/typec/ucsi/ucsi.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,48 @@
3636
*/
3737
#define UCSI_SWAP_TIMEOUT_MS 5000
3838

39+
void ucsi_notify_common(struct ucsi *ucsi, u32 cci)
40+
{
41+
if (UCSI_CCI_CONNECTOR(cci))
42+
ucsi_connector_change(ucsi, UCSI_CCI_CONNECTOR(cci));
43+
44+
if (cci & UCSI_CCI_ACK_COMPLETE &&
45+
test_bit(ACK_PENDING, &ucsi->flags))
46+
complete(&ucsi->complete);
47+
48+
if (cci & UCSI_CCI_COMMAND_COMPLETE &&
49+
test_bit(COMMAND_PENDING, &ucsi->flags))
50+
complete(&ucsi->complete);
51+
}
52+
EXPORT_SYMBOL_GPL(ucsi_notify_common);
53+
54+
int ucsi_sync_control_common(struct ucsi *ucsi, u64 command)
55+
{
56+
bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI;
57+
int ret;
58+
59+
if (ack)
60+
set_bit(ACK_PENDING, &ucsi->flags);
61+
else
62+
set_bit(COMMAND_PENDING, &ucsi->flags);
63+
64+
ret = ucsi->ops->async_control(ucsi, command);
65+
if (ret)
66+
goto out_clear_bit;
67+
68+
if (!wait_for_completion_timeout(&ucsi->complete, 5 * HZ))
69+
ret = -ETIMEDOUT;
70+
71+
out_clear_bit:
72+
if (ack)
73+
clear_bit(ACK_PENDING, &ucsi->flags);
74+
else
75+
clear_bit(COMMAND_PENDING, &ucsi->flags);
76+
77+
return ret;
78+
}
79+
EXPORT_SYMBOL_GPL(ucsi_sync_control_common);
80+
3981
static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack)
4082
{
4183
u64 ctrl;
@@ -1919,6 +1961,7 @@ struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops)
19191961
INIT_WORK(&ucsi->resume_work, ucsi_resume_work);
19201962
INIT_DELAYED_WORK(&ucsi->work, ucsi_init_work);
19211963
mutex_init(&ucsi->ppm_lock);
1964+
init_completion(&ucsi->complete);
19221965
ucsi->dev = dev;
19231966
ucsi->ops = ops;
19241967

drivers/usb/typec/ucsi/ucsi.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#define __DRIVER_USB_TYPEC_UCSI_H
55

66
#include <linux/bitops.h>
7+
#include <linux/completion.h>
78
#include <linux/device.h>
89
#include <linux/power_supply.h>
910
#include <linux/types.h>
@@ -425,6 +426,9 @@ struct ucsi {
425426
/* PPM communication flags */
426427
unsigned long flags;
427428
#define EVENT_PENDING 0
429+
#define COMMAND_PENDING 1
430+
#define ACK_PENDING 2
431+
struct completion complete;
428432

429433
unsigned long quirks;
430434
#define UCSI_NO_PARTNER_PDOS BIT(0) /* Don't read partner's PDOs */
@@ -489,6 +493,9 @@ int ucsi_send_command(struct ucsi *ucsi, u64 command,
489493
void ucsi_altmode_update_active(struct ucsi_connector *con);
490494
int ucsi_resume(struct ucsi *ucsi);
491495

496+
void ucsi_notify_common(struct ucsi *ucsi, u32 cci);
497+
int ucsi_sync_control_common(struct ucsi *ucsi, u64 command);
498+
492499
#if IS_ENABLED(CONFIG_POWER_SUPPLY)
493500
int ucsi_register_port_psy(struct ucsi_connector *con);
494501
void ucsi_unregister_port_psy(struct ucsi_connector *con);

drivers/usb/typec/ucsi/ucsi_acpi.c

Lines changed: 8 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,7 @@ struct ucsi_acpi {
2121
struct device *dev;
2222
struct ucsi *ucsi;
2323
void *base;
24-
struct completion complete;
25-
unsigned long flags;
26-
#define UCSI_ACPI_COMMAND_PENDING 1
27-
#define UCSI_ACPI_ACK_PENDING 2
28-
#define UCSI_ACPI_CHECK_BOGUS_EVENT 3
24+
bool check_bogus_event;
2925
guid_t guid;
3026
u64 cmd;
3127
};
@@ -98,38 +94,11 @@ static int ucsi_acpi_async_control(struct ucsi *ucsi, u64 command)
9894
return ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_WRITE);
9995
}
10096

101-
static int ucsi_acpi_sync_control(struct ucsi *ucsi, u64 command)
102-
{
103-
struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
104-
bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI;
105-
int ret;
106-
107-
if (ack)
108-
set_bit(UCSI_ACPI_ACK_PENDING, &ua->flags);
109-
else
110-
set_bit(UCSI_ACPI_COMMAND_PENDING, &ua->flags);
111-
112-
ret = ucsi_acpi_async_control(ucsi, command);
113-
if (ret)
114-
goto out_clear_bit;
115-
116-
if (!wait_for_completion_timeout(&ua->complete, 5 * HZ))
117-
ret = -ETIMEDOUT;
118-
119-
out_clear_bit:
120-
if (ack)
121-
clear_bit(UCSI_ACPI_ACK_PENDING, &ua->flags);
122-
else
123-
clear_bit(UCSI_ACPI_COMMAND_PENDING, &ua->flags);
124-
125-
return ret;
126-
}
127-
12897
static const struct ucsi_operations ucsi_acpi_ops = {
12998
.read_version = ucsi_acpi_read_version,
13099
.read_cci = ucsi_acpi_read_cci,
131100
.read_message_in = ucsi_acpi_read_message_in,
132-
.sync_control = ucsi_acpi_sync_control,
101+
.sync_control = ucsi_sync_control_common,
133102
.async_control = ucsi_acpi_async_control
134103
};
135104

@@ -165,7 +134,7 @@ static const struct ucsi_operations ucsi_zenbook_ops = {
165134
.read_version = ucsi_acpi_read_version,
166135
.read_cci = ucsi_zenbook_read_cci,
167136
.read_message_in = ucsi_zenbook_read_message_in,
168-
.sync_control = ucsi_acpi_sync_control,
137+
.sync_control = ucsi_sync_control_common,
169138
.async_control = ucsi_acpi_async_control
170139
};
171140

@@ -182,14 +151,14 @@ static int ucsi_gram_read_message_in(struct ucsi *ucsi, void *val, size_t val_le
182151
return ret;
183152

184153
if (UCSI_COMMAND(ua->cmd) == UCSI_GET_CONNECTOR_STATUS &&
185-
test_bit(UCSI_ACPI_CHECK_BOGUS_EVENT, &ua->flags)) {
154+
ua->check_bogus_event) {
186155
status = (struct ucsi_connector_status *)val;
187156

188157
/* Clear the bogus change */
189158
if (status->change == bogus_change)
190159
status->change = 0;
191160

192-
clear_bit(UCSI_ACPI_CHECK_BOGUS_EVENT, &ua->flags);
161+
ua->check_bogus_event = false;
193162
}
194163

195164
return ret;
@@ -200,14 +169,14 @@ static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command)
200169
struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
201170
int ret;
202171

203-
ret = ucsi_acpi_sync_control(ucsi, command);
172+
ret = ucsi_sync_control_common(ucsi, command);
204173
if (ret < 0)
205174
return ret;
206175

207176
if (UCSI_COMMAND(ua->cmd) == UCSI_GET_PDOS &&
208177
ua->cmd & UCSI_GET_PDOS_PARTNER_PDO(1) &&
209178
ua->cmd & UCSI_GET_PDOS_SRC_PDOS)
210-
set_bit(UCSI_ACPI_CHECK_BOGUS_EVENT, &ua->flags);
179+
ua->check_bogus_event = true;
211180

212181
return ret;
213182
}
@@ -249,15 +218,7 @@ static void ucsi_acpi_notify(acpi_handle handle, u32 event, void *data)
249218
if (ret)
250219
return;
251220

252-
if (UCSI_CCI_CONNECTOR(cci))
253-
ucsi_connector_change(ua->ucsi, UCSI_CCI_CONNECTOR(cci));
254-
255-
if (cci & UCSI_CCI_ACK_COMPLETE &&
256-
test_bit(UCSI_ACPI_ACK_PENDING, &ua->flags))
257-
complete(&ua->complete);
258-
if (cci & UCSI_CCI_COMMAND_COMPLETE &&
259-
test_bit(UCSI_ACPI_COMMAND_PENDING, &ua->flags))
260-
complete(&ua->complete);
221+
ucsi_notify_common(ua->ucsi, cci);
261222
}
262223

263224
static int ucsi_acpi_probe(struct platform_device *pdev)
@@ -291,7 +252,6 @@ static int ucsi_acpi_probe(struct platform_device *pdev)
291252
if (ret)
292253
return ret;
293254

294-
init_completion(&ua->complete);
295255
ua->dev = &pdev->dev;
296256

297257
id = dmi_first_match(ucsi_acpi_quirks);

drivers/usb/typec/ucsi/ucsi_ccg.c

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,6 @@ struct ucsi_ccg {
222222
u16 fw_build;
223223
struct work_struct pm_work;
224224

225-
struct completion complete;
226-
227225
u64 last_cmd_sent;
228226
bool has_multiple_dp;
229227
struct ucsi_ccg_altmode orig[UCSI_MAX_ALTMODES];
@@ -637,7 +635,6 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command)
637635

638636
mutex_lock(&uc->lock);
639637
pm_runtime_get_sync(uc->dev);
640-
set_bit(DEV_CMD_PENDING, &uc->flags);
641638

642639
uc->last_cmd_sent = command;
643640

@@ -649,15 +646,8 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command)
649646
ucsi_ccg_update_set_new_cam_cmd(uc, con, &command);
650647
}
651648

652-
ret = ucsi_ccg_async_control(ucsi, command);
653-
if (ret)
654-
goto err_clear_bit;
655-
656-
if (!wait_for_completion_timeout(&uc->complete, msecs_to_jiffies(5000)))
657-
ret = -ETIMEDOUT;
649+
ret = ucsi_sync_control_common(ucsi, command);
658650

659-
err_clear_bit:
660-
clear_bit(DEV_CMD_PENDING, &uc->flags);
661651
pm_runtime_put_sync(uc->dev);
662652
mutex_unlock(&uc->lock);
663653

@@ -694,9 +684,6 @@ static irqreturn_t ccg_irq_handler(int irq, void *data)
694684
if (ret)
695685
goto err_clear_irq;
696686

697-
if (UCSI_CCI_CONNECTOR(cci))
698-
ucsi_connector_change(uc->ucsi, UCSI_CCI_CONNECTOR(cci));
699-
700687
/*
701688
* As per CCGx UCSI interface guide, copy CCI and MESSAGE_IN
702689
* to the OpRegion before clear the UCSI interrupt
@@ -708,9 +695,8 @@ static irqreturn_t ccg_irq_handler(int irq, void *data)
708695
err_clear_irq:
709696
ccg_write(uc, CCGX_RAB_INTR_REG, &intr_reg, sizeof(intr_reg));
710697

711-
if (!ret && test_bit(DEV_CMD_PENDING, &uc->flags) &&
712-
cci & (UCSI_CCI_ACK_COMPLETE | UCSI_CCI_COMMAND_COMPLETE))
713-
complete(&uc->complete);
698+
if (!ret)
699+
ucsi_notify_common(uc->ucsi, cci);
714700

715701
return IRQ_HANDLED;
716702
}
@@ -1429,7 +1415,6 @@ static int ucsi_ccg_probe(struct i2c_client *client)
14291415
uc->client = client;
14301416
uc->irq = client->irq;
14311417
mutex_init(&uc->lock);
1432-
init_completion(&uc->complete);
14331418
INIT_WORK(&uc->work, ccg_update_firmware);
14341419
INIT_WORK(&uc->pm_work, ccg_pm_workaround_work);
14351420

drivers/usb/typec/ucsi/ucsi_glink.c

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,8 @@ struct pmic_glink_ucsi {
6464
struct ucsi *ucsi;
6565
struct completion read_ack;
6666
struct completion write_ack;
67-
struct completion sync_ack;
68-
bool sync_pending;
6967
struct mutex lock; /* protects concurrent access to PMIC Glink interface */
7068

71-
int sync_val;
72-
7369
struct work_struct notify_work;
7470
struct work_struct register_work;
7571

@@ -170,35 +166,6 @@ static int pmic_glink_ucsi_async_control(struct ucsi *__ucsi, u64 command)
170166
return ret;
171167
}
172168

173-
static int pmic_glink_ucsi_sync_control(struct ucsi *__ucsi, u64 command)
174-
{
175-
struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(__ucsi);
176-
unsigned long left;
177-
int ret;
178-
179-
/* TOFIX: Downstream forces recipient to CON when UCSI_GET_ALTERNATE_MODES command */
180-
181-
mutex_lock(&ucsi->lock);
182-
ucsi->sync_val = 0;
183-
reinit_completion(&ucsi->sync_ack);
184-
ucsi->sync_pending = true;
185-
ret = pmic_glink_ucsi_locked_write(ucsi, UCSI_CONTROL, &command, sizeof(command));
186-
mutex_unlock(&ucsi->lock);
187-
188-
left = wait_for_completion_timeout(&ucsi->sync_ack, 5 * HZ);
189-
if (!left) {
190-
dev_err(ucsi->dev, "timeout waiting for UCSI sync write response\n");
191-
/* return 0 here and let core UCSI code handle the CCI_BUSY */
192-
ret = 0;
193-
} else if (ucsi->sync_val) {
194-
dev_err(ucsi->dev, "sync write returned: %d\n", ucsi->sync_val);
195-
}
196-
197-
ucsi->sync_pending = false;
198-
199-
return ret;
200-
}
201-
202169
static void pmic_glink_ucsi_update_connector(struct ucsi_connector *con)
203170
{
204171
struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi);
@@ -232,7 +199,7 @@ static const struct ucsi_operations pmic_glink_ucsi_ops = {
232199
.read_version = pmic_glink_ucsi_read_version,
233200
.read_cci = pmic_glink_ucsi_read_cci,
234201
.read_message_in = pmic_glink_ucsi_read_message_in,
235-
.sync_control = pmic_glink_ucsi_sync_control,
202+
.sync_control = ucsi_sync_control_common,
236203
.async_control = pmic_glink_ucsi_async_control,
237204
.update_connector = pmic_glink_ucsi_update_connector,
238205
.connector_status = pmic_glink_ucsi_connector_status,
@@ -256,14 +223,12 @@ static void pmic_glink_ucsi_write_ack(struct pmic_glink_ucsi *ucsi, const void *
256223
if (resp->ret_code)
257224
return;
258225

259-
ucsi->sync_val = resp->ret_code;
260226
complete(&ucsi->write_ack);
261227
}
262228

263229
static void pmic_glink_ucsi_notify(struct work_struct *work)
264230
{
265231
struct pmic_glink_ucsi *ucsi = container_of(work, struct pmic_glink_ucsi, notify_work);
266-
unsigned int con_num;
267232
u32 cci;
268233
int ret;
269234

@@ -273,14 +238,7 @@ static void pmic_glink_ucsi_notify(struct work_struct *work)
273238
return;
274239
}
275240

276-
con_num = UCSI_CCI_CONNECTOR(cci);
277-
if (con_num)
278-
ucsi_connector_change(ucsi->ucsi, con_num);
279-
280-
if (ucsi->sync_pending &&
281-
(cci & (UCSI_CCI_ACK_COMPLETE | UCSI_CCI_COMMAND_COMPLETE))) {
282-
complete(&ucsi->sync_ack);
283-
}
241+
ucsi_notify_common(ucsi->ucsi, cci);
284242
}
285243

286244
static void pmic_glink_ucsi_register(struct work_struct *work)
@@ -362,7 +320,6 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev,
362320
INIT_WORK(&ucsi->register_work, pmic_glink_ucsi_register);
363321
init_completion(&ucsi->read_ack);
364322
init_completion(&ucsi->write_ack);
365-
init_completion(&ucsi->sync_ack);
366323
mutex_init(&ucsi->lock);
367324

368325
ucsi->ucsi = ucsi_create(dev, &pmic_glink_ucsi_ops);

0 commit comments

Comments
 (0)