diff options
author | Jack Pham <jackp@codeaurora.org> | 2016-10-31 16:05:37 -0700 |
---|---|---|
committer | Jack Pham <jackp@codeaurora.org> | 2016-11-02 20:22:11 -0700 |
commit | 64d72675d7d89a8e842987bf0650c67eb8626f8d (patch) | |
tree | ffa2edba4fb0b5bad75f787627c583f1ddc1e294 /drivers/usb/pd | |
parent | 9d735f227869417635bb126a4aa0382d45ec8df3 (diff) |
usb: pd: Avoid calling SVID disconnect if not previously connected
Only call an SVID handler's disconnect function only if it was
previously connected, i.e. when the state machine had proceeded
received a successful DISCOVER_SVIDs response. This helps to
avoid excessive notification to SVID clients.
While at it, require that .connect and .disconnect callbacks
are supplied during registration. This helps to eliminate NULL
checks each time they are called.
Change-Id: I030153a6b2106a6504ed51b5cb00a27f842e2488
Signed-off-by: Jack Pham <jackp@codeaurora.org>
Diffstat (limited to 'drivers/usb/pd')
-rw-r--r-- | drivers/usb/pd/policy_engine.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index 8b82d3960752..b4d7c7d8bddf 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -942,6 +942,13 @@ int usbpd_register_svid(struct usbpd *pd, struct usbpd_svid_handler *hdlr) return -EINVAL; } + /* require connect/disconnect callbacks be implemented */ + if (!hdlr->connect || !hdlr->disconnect) { + usbpd_err(&pd->dev, "SVID 0x%04x connect/disconnect must be non-NULL\n", + hdlr->svid); + return -EINVAL; + } + usbpd_dbg(&pd->dev, "registered handler for SVID 0x%04x\n", hdlr->svid); list_add_tail(&hdlr->entry, &pd->svid_handlers); @@ -952,8 +959,8 @@ int usbpd_register_svid(struct usbpd *pd, struct usbpd_svid_handler *hdlr) for (i = 0; i < pd->num_svids; i++) { if (pd->discovered_svids[i] == hdlr->svid) { - if (hdlr->connect) - hdlr->connect(hdlr); + hdlr->connect(hdlr); + hdlr->discovered = true; break; } } @@ -1165,8 +1172,10 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) svid = pd->discovered_svids[i]; if (svid) { handler = find_svid_handler(pd, svid); - if (handler && handler->connect) + if (handler) { handler->connect(handler); + handler->discovered = true; + } } } @@ -1271,10 +1280,14 @@ static void reset_vdm_state(struct usbpd *pd) { struct usbpd_svid_handler *handler; - pd->vdm_state = VDM_NONE; - list_for_each_entry(handler, &pd->svid_handlers, entry) - if (handler->disconnect) + list_for_each_entry(handler, &pd->svid_handlers, entry) { + if (handler->discovered) { handler->disconnect(handler); + handler->discovered = false; + } + } + + pd->vdm_state = VDM_NONE; kfree(pd->vdm_tx_retry); pd->vdm_tx_retry = NULL; kfree(pd->discovered_svids); |