diff --git a/drivers/nfc/nxp-nci/core.c b/drivers/nfc/nxp-nci/core.c index 66b198663387..1bb5995fcdb4 100644 --- a/drivers/nfc/nxp-nci/core.c +++ b/drivers/nfc/nxp-nci/core.c @@ -190,10 +190,10 @@ void nxp_nci_remove(struct nci_dev *ndev) if (info->phy_ops->set_mode) info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_COLD); + mutex_unlock(&info->info_lock); + nci_unregister_device(ndev); nci_free_device(ndev); - - mutex_unlock(&info->info_lock); } EXPORT_SYMBOL(nxp_nci_remove); diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c index 7aaab92c616c..1e344e7afeab 100644 --- a/drivers/nfc/nxp-nci/i2c.c +++ b/drivers/nfc/nxp-nci/i2c.c @@ -43,19 +43,24 @@ struct nxp_nci_i2c_phy { */ }; -static int nxp_nci_i2c_set_mode(void *phy_id, - enum nxp_nci_mode mode) +static int nxp_nci_i2c_set_mode(void *phy_id, enum nxp_nci_mode mode) { - struct nxp_nci_i2c_phy *phy = (struct nxp_nci_i2c_phy *) phy_id; - - gpiod_set_value(phy->gpiod_fw, (mode == NXP_NCI_MODE_FW) ? 1 : 0); - gpiod_set_value(phy->gpiod_en, (mode != NXP_NCI_MODE_COLD) ? 1 : 0); - usleep_range(10000, 15000); - - if (mode == NXP_NCI_MODE_COLD) - phy->hard_fault = 0; - - return 0; + struct nxp_nci_i2c_phy *phy = (struct nxp_nci_i2c_phy *) phy_id; + + if (mode == NXP_NCI_MODE_COLD) { + disable_irq(phy->i2c_dev->irq); + gpiod_set_value(phy->gpiod_fw, 0); + gpiod_set_value(phy->gpiod_en, 0); + phy->hard_fault = 0; + usleep_range(10000, 15000); + } else { + gpiod_set_value(phy->gpiod_fw, (mode == NXP_NCI_MODE_FW) ? 1 : 0); + gpiod_set_value(phy->gpiod_en, 1); + msleep(150); + phy->hard_fault = 0; + enable_irq(phy->i2c_dev->irq); + } + return 0; } static int nxp_nci_i2c_write(void *phy_id, struct sk_buff *skb) @@ -317,8 +322,12 @@ static int nxp_nci_i2c_probe(struct i2c_client *client) nxp_nci_i2c_irq_thread_fn, irqflags | IRQF_ONESHOT, NXP_NCI_I2C_DRIVER_NAME, phy); - if (r < 0) + if (r < 0) { nfc_err(&client->dev, "Unable to register IRQ handler\n"); + return r; + } + + disable_irq(client->irq); return r; } @@ -327,8 +336,8 @@ static void nxp_nci_i2c_remove(struct i2c_client *client) { struct nxp_nci_i2c_phy *phy = i2c_get_clientdata(client); - nxp_nci_remove(phy->ndev); free_irq(client->irq, phy); + nxp_nci_remove(phy->ndev); } static const struct i2c_device_id nxp_nci_i2c_id_table[] = {