From: Hao Wu <hao.wu@xxxxxxxxx> This patch updates langwell_update_transceiver function to add NULL pointer check. And switch to use such function for state machine update instead of invoking queue_work directly. Signed-off-by: Hao Wu <hao.wu@xxxxxxxxx> Signed-off-by: Alan Cox <alan@xxxxxxxxxxxxxxx> --- drivers/usb/otg/langwell_otg.c | 62 +++++++++++++++++++++------------------- 1 files changed, 32 insertions(+), 30 deletions(-) diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c index 852b5df..83d7941 100644 --- a/drivers/usb/otg/langwell_otg.c +++ b/drivers/usb/otg/langwell_otg.c @@ -142,6 +142,9 @@ void langwell_update_transceiver() dev_dbg(&lnw->pdev->dev, "transceiver is updated\n"); + if (!lnw->qwork) + return ; + queue_work(lnw->qwork, &lnw->work); } EXPORT_SYMBOL(langwell_update_transceiver); @@ -271,7 +274,7 @@ static int langwell_otg_start_srp(struct otg_transceiver *otg) dev_dbg(&lnw->pdev->dev, "no b_sess_vld interrupt\n"); lnw->hsm.b_sess_vld = 1; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } dev_dbg(&lnw->pdev->dev, "%s <---\n", __func__); @@ -791,8 +794,7 @@ static irqreturn_t otg_dummy_irq(int irq, void *_dev) if (the_transceiver->hsm.b_conn) { the_transceiver->hsm.b_conn = 0; if (spin_trylock(&the_transceiver->wq_lock)) { - queue_work(the_transceiver->qwork, - &the_transceiver->work); + langwell_update_transceiver(); spin_unlock(&the_transceiver->wq_lock); } } @@ -864,7 +866,7 @@ static irqreturn_t otg_irq(int irq, void *_dev) writel((int_sts & ~OTGSC_INTSTS_MASK) | int_mask, lnw->regs + CI_OTGSC); if (flag) - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); return IRQ_HANDLED; } @@ -891,7 +893,7 @@ static void langwell_otg_work(struct work_struct *work) set_host_mode(); langwell_otg_phy_low_power(1); lnw->otg.state = OTG_STATE_A_IDLE; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } else if (lnw->hsm.b_sess_vld) { langwell_otg_del_timer(b_srp_init_tmr); del_timer_sync(&lnw->hsm_timer); @@ -945,7 +947,7 @@ static void langwell_otg_work(struct work_struct *work) set_host_mode(); langwell_otg_phy_low_power(1); lnw->otg.state = OTG_STATE_A_IDLE; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } else if (lnw->hsm.b_sess_vld) { langwell_otg_chrg_vbus(0); if (lnw->client_ops) { @@ -973,7 +975,7 @@ static void langwell_otg_work(struct work_struct *work) set_host_mode(); langwell_otg_phy_low_power(1); lnw->otg.state = OTG_STATE_A_IDLE; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } else if (!lnw->hsm.b_sess_vld) { lnw->hsm.b_hnp_enable = 0; @@ -1031,7 +1033,7 @@ static void langwell_otg_work(struct work_struct *work) set_host_mode(); langwell_otg_phy_low_power(1); lnw->otg.state = OTG_STATE_A_IDLE; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } else if (!lnw->hsm.b_sess_vld) { /* delete hsm timer for b_ase0_brst_tmr */ del_timer_sync(&lnw->hsm_timer); @@ -1055,7 +1057,7 @@ static void langwell_otg_work(struct work_struct *work) del_timer_sync(&lnw->hsm_timer); langwell_otg_HAAR(0); lnw->otg.state = OTG_STATE_B_HOST; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } else if (lnw->hsm.a_bus_resume || lnw->hsm.b_ase0_brst_tmout) { /* delete hsm timer for b_ase0_brst_tmr */ @@ -1097,7 +1099,7 @@ static void langwell_otg_work(struct work_struct *work) set_host_mode(); langwell_otg_phy_low_power(1); lnw->otg.state = OTG_STATE_A_IDLE; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } else if (!lnw->hsm.b_sess_vld) { lnw->hsm.b_hnp_enable = 0; lnw->hsm.b_bus_req = 0; @@ -1143,7 +1145,7 @@ static void langwell_otg_work(struct work_struct *work) set_client_mode(); langwell_otg_phy_low_power(1); lnw->otg.state = OTG_STATE_B_IDLE; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } else if (!lnw->hsm.a_bus_drop && (lnw->hsm.a_srp_det || lnw->hsm.a_bus_req)) { langwell_otg_phy_low_power(0); @@ -1152,7 +1154,7 @@ static void langwell_otg_work(struct work_struct *work) lnw->hsm.a_wait_vrise_tmout = 0; langwell_otg_add_timer(a_wait_vrise_tmr); lnw->otg.state = OTG_STATE_A_WAIT_VRISE; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } else if (!lnw->hsm.a_bus_drop && lnw->hsm.a_sess_vld) { lnw->hsm.vbus_srp_up = 1; } else if (!lnw->hsm.a_sess_vld && lnw->hsm.vbus_srp_up) { @@ -1164,7 +1166,7 @@ static void langwell_otg_work(struct work_struct *work) lnw->hsm.a_wait_vrise_tmout = 0; langwell_otg_add_timer(a_wait_vrise_tmr); lnw->otg.state = OTG_STATE_A_WAIT_VRISE; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } else if (!lnw->hsm.a_sess_vld && !lnw->hsm.vbus_srp_up) { langwell_otg_phy_low_power(1); @@ -1230,7 +1232,7 @@ static void langwell_otg_work(struct work_struct *work) set_client_mode(); langwell_otg_phy_low_power_wait(1); lnw->otg.state = OTG_STATE_B_IDLE; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } else if (!lnw->hsm.a_vbus_vld) { /* delete hsm timer for a_wait_bcon_tmr */ del_timer_sync(&lnw->hsm_timer); @@ -1318,7 +1320,7 @@ static void langwell_otg_work(struct work_struct *work) set_client_mode(); langwell_otg_phy_low_power_wait(1); lnw->otg.state = OTG_STATE_B_IDLE; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } else if (lnw->hsm.a_bus_drop || (!lnw->otg.host->b_hnp_enable && !lnw->hsm.a_bus_req)) { @@ -1384,7 +1386,7 @@ static void langwell_otg_work(struct work_struct *work) set_client_mode(); langwell_otg_phy_low_power(1); lnw->otg.state = OTG_STATE_B_IDLE; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } else if (lnw->hsm.a_bus_req || lnw->hsm.b_bus_resume) { langwell_otg_del_timer(a_aidl_bdis_tmr); @@ -1460,7 +1462,7 @@ static void langwell_otg_work(struct work_struct *work) set_client_mode(); langwell_otg_phy_low_power_wait(1); lnw->otg.state = OTG_STATE_B_IDLE; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } else if (!lnw->hsm.a_vbus_vld) { /* delete hsm timer for b_bus_suspend_tmr */ del_timer_sync(&lnw->hsm_timer); @@ -1531,14 +1533,14 @@ static void langwell_otg_work(struct work_struct *work) set_client_mode(); langwell_otg_phy_low_power(1); lnw->otg.state = OTG_STATE_B_IDLE; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } else if (lnw->hsm.a_clr_err) { lnw->hsm.a_clr_err = 0; lnw->hsm.a_srp_det = 0; reset_otg(); init_hsm(); if (lnw->otg.state == OTG_STATE_A_IDLE) - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } else { /* FW will clear PHCD bit when any VBus * event detected. Reset PHCD to 1 again */ @@ -1551,7 +1553,7 @@ static void langwell_otg_work(struct work_struct *work) set_client_mode(); langwell_otg_phy_low_power(1); lnw->otg.state = OTG_STATE_B_IDLE; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); } else if (lnw->hsm.a_bus_req) { langwell_otg_drv_vbus(1); lnw->hsm.a_wait_vrise_tmout = 0; @@ -1729,7 +1731,7 @@ set_a_bus_req(struct device *dev, struct device_attribute *attr, dev_dbg(&lnw->pdev->dev, "User request: a_bus_req = 1\n"); } if (spin_trylock(&lnw->wq_lock)) { - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); spin_unlock(&lnw->wq_lock); } return count; @@ -1774,7 +1776,7 @@ set_a_bus_drop(struct device *dev, struct device_attribute *attr, dev_dbg(&lnw->pdev->dev, "User request: and a_bus_req = 0\n"); } if (spin_trylock(&lnw->wq_lock)) { - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); spin_unlock(&lnw->wq_lock); } return count; @@ -1819,7 +1821,7 @@ set_b_bus_req(struct device *dev, struct device_attribute *attr, dev_dbg(&lnw->pdev->dev, "User request: b_bus_req = 1\n"); } if (spin_trylock(&lnw->wq_lock)) { - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); spin_unlock(&lnw->wq_lock); } return count; @@ -1842,7 +1844,7 @@ set_a_clr_err(struct device *dev, struct device_attribute *attr, dev_dbg(&lnw->pdev->dev, "User request: a_clr_err = 1\n"); } if (spin_trylock(&lnw->wq_lock)) { - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); spin_unlock(&lnw->wq_lock); } return count; @@ -1868,7 +1870,7 @@ int langwell_register_host(struct pci_driver *host_driver) int ret = 0; lnw->host_ops = host_driver; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); dev_dbg(&lnw->pdev->dev, "host controller driver is registered\n"); return ret; @@ -1883,7 +1885,7 @@ void langwell_unregister_host(struct pci_driver *host_driver) lnw->host_ops->remove(lnw->pdev); lnw->host_ops = NULL; lnw->hsm.a_bus_drop = 1; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); dev_dbg(&lnw->pdev->dev, "host controller driver is unregistered\n"); } EXPORT_SYMBOL(langwell_unregister_host); @@ -1898,7 +1900,7 @@ int langwell_register_peripheral(struct pci_driver *client_driver) client_driver->id_table); if (!ret) { lnw->client_ops = client_driver; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); dev_dbg(&lnw->pdev->dev, "client controller driver is registered\n"); } @@ -1915,7 +1917,7 @@ void langwell_unregister_peripheral(struct pci_driver *client_driver) lnw->client_ops->remove(lnw->pdev); lnw->client_ops = NULL; lnw->hsm.b_bus_req = 0; - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); dev_dbg(&lnw->pdev->dev, "client controller driver is unregistered\n"); } @@ -2049,7 +2051,7 @@ static int langwell_otg_probe(struct pci_dev *pdev, } if (langwell->otg.state == OTG_STATE_A_IDLE) - queue_work(langwell->qwork, &langwell->work); + langwell_update_transceiver(); return 0; @@ -2258,7 +2260,7 @@ static int langwell_otg_resume(struct pci_dev *pdev) update_hsm(); - queue_work(lnw->qwork, &lnw->work); + langwell_update_transceiver(); return ret; error: -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html