Commit 17e9d9d437d1bb52077e562fae9457236dbaa76f

Authored by Samuel Ortiz
1 parent f1abed171f

NFC: pn533: Fix the pn533 polling loop

By turning the radio off after each failed polling try, we dramatically
improve the pn533 polling loop efficiency.
Without this fix, all Android phones running the broadcom NFC stack are
almost never detected.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

Showing 1 changed file with 54 additions and 1 deletions Side-by-side Diff

... ... @@ -359,6 +359,7 @@
359 359 struct work_struct poll_work;
360 360 struct work_struct mi_work;
361 361 struct work_struct tg_work;
  362 + struct work_struct rf_work;
362 363  
363 364 struct list_head cmd_queue;
364 365 struct pn533_cmd *cmd;
... ... @@ -1660,6 +1661,53 @@
1660 1661 queue_work(dev->wq, &dev->poll_work);
1661 1662 }
1662 1663  
  1664 +static int pn533_rf_complete(struct pn533 *dev, void *arg,
  1665 + struct sk_buff *resp)
  1666 +{
  1667 + int rc = 0;
  1668 +
  1669 + nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
  1670 +
  1671 + if (IS_ERR(resp)) {
  1672 + rc = PTR_ERR(resp);
  1673 +
  1674 + nfc_dev_err(&dev->interface->dev, "%s RF setting error %d",
  1675 + __func__, rc);
  1676 +
  1677 + return rc;
  1678 + }
  1679 +
  1680 + queue_work(dev->wq, &dev->poll_work);
  1681 +
  1682 + dev_kfree_skb(resp);
  1683 + return rc;
  1684 +}
  1685 +
  1686 +static void pn533_wq_rf(struct work_struct *work)
  1687 +{
  1688 + struct pn533 *dev = container_of(work, struct pn533, rf_work);
  1689 + struct sk_buff *skb;
  1690 + int rc;
  1691 +
  1692 + nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
  1693 +
  1694 + skb = pn533_alloc_skb(dev, 2);
  1695 + if (!skb)
  1696 + return;
  1697 +
  1698 + *skb_put(skb, 1) = PN533_CFGITEM_RF_FIELD;
  1699 + *skb_put(skb, 1) = 0;
  1700 +
  1701 + rc = pn533_send_cmd_async(dev, PN533_CMD_RF_CONFIGURATION, skb,
  1702 + pn533_rf_complete, NULL);
  1703 + if (rc < 0) {
  1704 + dev_kfree_skb(skb);
  1705 + nfc_dev_err(&dev->interface->dev, "RF setting error %d", rc);
  1706 + }
  1707 +
  1708 + return;
  1709 +}
  1710 +
1663 1711 static int pn533_poll_complete(struct pn533 *dev, void *arg,
1664 1712 struct sk_buff *resp)
1665 1713 {
... ... @@ -1705,7 +1753,8 @@
1705 1753 }
1706 1754  
1707 1755 pn533_poll_next_mod(dev);
1708   - queue_work(dev->wq, &dev->poll_work);
  1756 + /* Not target found, turn radio off */
  1757 + queue_work(dev->wq, &dev->rf_work);
1709 1758  
1710 1759 done:
1711 1760 dev_kfree_skb(resp);
... ... @@ -2051,6 +2100,7 @@
2051 2100 }
2052 2101 }
2053 2102  
  2103 +static int pn533_rf_field(struct nfc_dev *nfc_dev, u8 rf);
2054 2104 #define PASSIVE_DATA_LEN 5
2055 2105 static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target,
2056 2106 u8 comm_mode, u8 *gb, size_t gb_len)
... ... @@ -2127,6 +2177,8 @@
2127 2177  
2128 2178 *arg = !comm_mode;
2129 2179  
  2180 + pn533_rf_field(dev->nfc_dev, 0);
  2181 +
2130 2182 rc = pn533_send_cmd_async(dev, PN533_CMD_IN_JUMP_FOR_DEP, skb,
2131 2183 pn533_in_dep_link_up_complete, arg);
2132 2184  
... ... @@ -2721,6 +2773,7 @@
2721 2773 INIT_WORK(&dev->mi_work, pn533_wq_mi_recv);
2722 2774 INIT_WORK(&dev->tg_work, pn533_wq_tg_get_data);
2723 2775 INIT_WORK(&dev->poll_work, pn533_wq_poll);
  2776 + INIT_WORK(&dev->rf_work, pn533_wq_rf);
2724 2777 dev->wq = alloc_ordered_workqueue("pn533", 0);
2725 2778 if (dev->wq == NULL)
2726 2779 goto error;