static irqreturn_t nxp_nci_i2c_irq_thread_fn()

in nxp-nci/i2c.c [182:248]


static irqreturn_t nxp_nci_i2c_irq_thread_fn(int irq, void *phy_id)
{
	struct nxp_nci_i2c_phy *phy = phy_id;
	struct i2c_client *client;
	struct nxp_nci_info *info;

	struct sk_buff *skb = NULL;
	int r = 0;

	if (!phy || !phy->ndev)
		goto exit_irq_none;

	client = phy->i2c_dev;

	if (!client || irq != client->irq)
		goto exit_irq_none;

	info = nci_get_drvdata(phy->ndev);

	if (!info)
		goto exit_irq_none;

	mutex_lock(&info->info_lock);

	if (phy->hard_fault != 0)
		goto exit_irq_handled;

	switch (info->mode) {
	case NXP_NCI_MODE_NCI:
		r = nxp_nci_i2c_nci_read(phy, &skb);
		break;
	case NXP_NCI_MODE_FW:
		r = nxp_nci_i2c_fw_read(phy, &skb);
		break;
	case NXP_NCI_MODE_COLD:
		r = -EREMOTEIO;
		break;
	}

	if (r == -EREMOTEIO) {
		phy->hard_fault = r;
		if (info->mode == NXP_NCI_MODE_FW)
			nxp_nci_fw_recv_frame(phy->ndev, NULL);
	}
	if (r < 0) {
		nfc_err(&client->dev, "Read failed with error %d\n", r);
		goto exit_irq_handled;
	}

	switch (info->mode) {
	case NXP_NCI_MODE_NCI:
		nci_recv_frame(phy->ndev, skb);
		break;
	case NXP_NCI_MODE_FW:
		nxp_nci_fw_recv_frame(phy->ndev, skb);
		break;
	case NXP_NCI_MODE_COLD:
		break;
	}

exit_irq_handled:
	mutex_unlock(&info->info_lock);
	return IRQ_HANDLED;
exit_irq_none:
	WARN_ON_ONCE(1);
	return IRQ_NONE;
}