Loading drivers/usb/pd/policy_engine.c +34 −6 Original line number Diff line number Diff line Loading @@ -457,6 +457,7 @@ struct usbpd { struct mutex svid_handler_lock; struct list_head svid_handlers; ktime_t svdm_start_time; bool vdm_in_suspend; struct list_head instance; Loading Loading @@ -659,15 +660,21 @@ static struct usbpd_svid_handler *find_svid_handler(struct usbpd *pd, u16 svid) { struct usbpd_svid_handler *handler; /* in_interrupt() == true when handling VDM RX during suspend */ if (!in_interrupt()) mutex_lock(&pd->svid_handler_lock); list_for_each_entry(handler, &pd->svid_handlers, entry) { if (svid == handler->svid) { if (!in_interrupt()) mutex_unlock(&pd->svid_handler_lock); return handler; } } if (!in_interrupt()) mutex_unlock(&pd->svid_handler_lock); return NULL; } Loading Loading @@ -1074,6 +1081,8 @@ static struct rx_msg *pd_ext_msg_received(struct usbpd *pd, u16 header, u8 *buf, return rx_msg; /* queue it for usbpd_sm */ } static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg); static void phy_msg_received(struct usbpd *pd, enum pd_sop_type sop, u8 *buf, size_t len) { Loading Loading @@ -1146,6 +1155,13 @@ static void phy_msg_received(struct usbpd *pd, enum pd_sop_type sop, return; } if (pd->vdm_in_suspend && msg_type == MSG_VDM) { usbpd_dbg(&pd->dev, "Skip wq and handle VDM directly\n"); handle_vdm_rx(pd, rx_msg); kfree(rx_msg); return; } spin_lock_irqsave(&pd->rx_lock, flags); list_add_tail(&rx_msg->entry, &pd->rx_q); spin_unlock_irqrestore(&pd->rx_lock, flags); Loading Loading @@ -1324,6 +1340,7 @@ int usbpd_send_vdm(struct usbpd *pd, u32 vdm_hdr, const u32 *vdos, int num_vdos) /* VDM will get sent in PE_SRC/SNK_READY state handling */ pd->vdm_tx = vdm_tx; pd->vdm_in_suspend = false; /* slight delay before queuing to prioritize handling of incoming VDM */ if (pd->in_explicit_contract) Loading @@ -1346,6 +1363,14 @@ int usbpd_send_svdm(struct usbpd *pd, u16 svid, u8 cmd, } EXPORT_SYMBOL(usbpd_send_svdm); void usbpd_vdm_in_suspend(struct usbpd *pd, bool in_suspend) { usbpd_dbg(&pd->dev, "VDM in_suspend:%d\n", in_suspend); pd->vdm_in_suspend = in_suspend; } EXPORT_SYMBOL(usbpd_vdm_in_suspend); static void handle_vdm_resp_ack(struct usbpd *pd, u32 *vdos, u8 num_vdos, u16 vdm_hdr) { Loading Loading @@ -1529,6 +1554,10 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) return; } if (cmd_type != SVDM_CMD_TYPE_INITIATOR && pd->current_state != PE_SRC_STARTUP_WAIT_FOR_VDM_RESP) start_src_ams(pd, false); if (handler && handler->svdm_received) { handler->svdm_received(handler, cmd, cmd_type, vdos, num_vdos); Loading Loading @@ -1685,6 +1714,7 @@ static void reset_vdm_state(struct usbpd *pd) kfree(pd->vdm_tx); pd->vdm_tx = NULL; pd->ss_lane_svid = 0x0; pd->vdm_in_suspend = false; } static void handle_get_src_cap_extended(struct usbpd *pd) Loading Loading @@ -2300,7 +2330,7 @@ static void enter_state_src_ready(struct usbpd *pd) pd->in_explicit_contract = true; if (pd->vdm_tx) if (pd->vdm_tx && !pd->sm_queued) kick_sm(pd, 0); else if (pd->current_dr == DR_DFP && pd->vdm_state == VDM_NONE) usbpd_send_svdm(pd, USBPD_SID, Loading Loading @@ -2361,8 +2391,6 @@ static void handle_state_src_ready(struct usbpd *pd, struct rx_msg *rx_msg) } vconn_swap(pd); if (!pd->vdm_tx) start_src_ams(pd, false); } else if (IS_DATA(rx_msg, MSG_VDM)) { handle_vdm_rx(pd, rx_msg); } else if (IS_CTRL(rx_msg, MSG_GET_SOURCE_CAP_EXTENDED)) { Loading include/linux/usb/usbpd.h +4 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,8 @@ int usbpd_send_svdm(struct usbpd *pd, u16 svid, u8 cmd, * otherwise ORIENTATION_NONE if not attached */ enum plug_orientation usbpd_get_plug_orientation(struct usbpd *pd); void usbpd_vdm_in_suspend(struct usbpd *pd, bool in_suspend); #else static inline struct usbpd *devm_usbpd_get_by_phandle(struct device *dev, const char *phandle) Loading Loading @@ -134,6 +136,8 @@ static inline enum plug_orientation usbpd_get_plug_orientation(struct usbpd *pd) { return ORIENTATION_NONE; } static inline void usbpd_vdm_in_suspend(struct usbpd *pd, bool in_suspend) { } #endif /* IS_ENABLED(CONFIG_USB_PD_POLICY) */ /* Loading Loading
drivers/usb/pd/policy_engine.c +34 −6 Original line number Diff line number Diff line Loading @@ -457,6 +457,7 @@ struct usbpd { struct mutex svid_handler_lock; struct list_head svid_handlers; ktime_t svdm_start_time; bool vdm_in_suspend; struct list_head instance; Loading Loading @@ -659,15 +660,21 @@ static struct usbpd_svid_handler *find_svid_handler(struct usbpd *pd, u16 svid) { struct usbpd_svid_handler *handler; /* in_interrupt() == true when handling VDM RX during suspend */ if (!in_interrupt()) mutex_lock(&pd->svid_handler_lock); list_for_each_entry(handler, &pd->svid_handlers, entry) { if (svid == handler->svid) { if (!in_interrupt()) mutex_unlock(&pd->svid_handler_lock); return handler; } } if (!in_interrupt()) mutex_unlock(&pd->svid_handler_lock); return NULL; } Loading Loading @@ -1074,6 +1081,8 @@ static struct rx_msg *pd_ext_msg_received(struct usbpd *pd, u16 header, u8 *buf, return rx_msg; /* queue it for usbpd_sm */ } static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg); static void phy_msg_received(struct usbpd *pd, enum pd_sop_type sop, u8 *buf, size_t len) { Loading Loading @@ -1146,6 +1155,13 @@ static void phy_msg_received(struct usbpd *pd, enum pd_sop_type sop, return; } if (pd->vdm_in_suspend && msg_type == MSG_VDM) { usbpd_dbg(&pd->dev, "Skip wq and handle VDM directly\n"); handle_vdm_rx(pd, rx_msg); kfree(rx_msg); return; } spin_lock_irqsave(&pd->rx_lock, flags); list_add_tail(&rx_msg->entry, &pd->rx_q); spin_unlock_irqrestore(&pd->rx_lock, flags); Loading Loading @@ -1324,6 +1340,7 @@ int usbpd_send_vdm(struct usbpd *pd, u32 vdm_hdr, const u32 *vdos, int num_vdos) /* VDM will get sent in PE_SRC/SNK_READY state handling */ pd->vdm_tx = vdm_tx; pd->vdm_in_suspend = false; /* slight delay before queuing to prioritize handling of incoming VDM */ if (pd->in_explicit_contract) Loading @@ -1346,6 +1363,14 @@ int usbpd_send_svdm(struct usbpd *pd, u16 svid, u8 cmd, } EXPORT_SYMBOL(usbpd_send_svdm); void usbpd_vdm_in_suspend(struct usbpd *pd, bool in_suspend) { usbpd_dbg(&pd->dev, "VDM in_suspend:%d\n", in_suspend); pd->vdm_in_suspend = in_suspend; } EXPORT_SYMBOL(usbpd_vdm_in_suspend); static void handle_vdm_resp_ack(struct usbpd *pd, u32 *vdos, u8 num_vdos, u16 vdm_hdr) { Loading Loading @@ -1529,6 +1554,10 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) return; } if (cmd_type != SVDM_CMD_TYPE_INITIATOR && pd->current_state != PE_SRC_STARTUP_WAIT_FOR_VDM_RESP) start_src_ams(pd, false); if (handler && handler->svdm_received) { handler->svdm_received(handler, cmd, cmd_type, vdos, num_vdos); Loading Loading @@ -1685,6 +1714,7 @@ static void reset_vdm_state(struct usbpd *pd) kfree(pd->vdm_tx); pd->vdm_tx = NULL; pd->ss_lane_svid = 0x0; pd->vdm_in_suspend = false; } static void handle_get_src_cap_extended(struct usbpd *pd) Loading Loading @@ -2300,7 +2330,7 @@ static void enter_state_src_ready(struct usbpd *pd) pd->in_explicit_contract = true; if (pd->vdm_tx) if (pd->vdm_tx && !pd->sm_queued) kick_sm(pd, 0); else if (pd->current_dr == DR_DFP && pd->vdm_state == VDM_NONE) usbpd_send_svdm(pd, USBPD_SID, Loading Loading @@ -2361,8 +2391,6 @@ static void handle_state_src_ready(struct usbpd *pd, struct rx_msg *rx_msg) } vconn_swap(pd); if (!pd->vdm_tx) start_src_ams(pd, false); } else if (IS_DATA(rx_msg, MSG_VDM)) { handle_vdm_rx(pd, rx_msg); } else if (IS_CTRL(rx_msg, MSG_GET_SOURCE_CAP_EXTENDED)) { Loading
include/linux/usb/usbpd.h +4 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,8 @@ int usbpd_send_svdm(struct usbpd *pd, u16 svid, u8 cmd, * otherwise ORIENTATION_NONE if not attached */ enum plug_orientation usbpd_get_plug_orientation(struct usbpd *pd); void usbpd_vdm_in_suspend(struct usbpd *pd, bool in_suspend); #else static inline struct usbpd *devm_usbpd_get_by_phandle(struct device *dev, const char *phandle) Loading Loading @@ -134,6 +136,8 @@ static inline enum plug_orientation usbpd_get_plug_orientation(struct usbpd *pd) { return ORIENTATION_NONE; } static inline void usbpd_vdm_in_suspend(struct usbpd *pd, bool in_suspend) { } #endif /* IS_ENABLED(CONFIG_USB_PD_POLICY) */ /* Loading