Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NFC: RFKILL support

All NFC devices will now get proper RFKILL support as long as they provide
some dev_up and dev_down hooks. Rfkilling an NFC device will bring it down
while it is left to userspace to bring it back up when being rfkill unblocked.
This is very similar to what Bluetooth does.

Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

+40
+2
include/net/nfc/nfc.h
··· 122 122 123 123 bool shutting_down; 124 124 125 + struct rfkill *rfkill; 126 + 125 127 struct nfc_ops *ops; 126 128 }; 127 129 #define to_nfc_dev(_dev) container_of(_dev, struct nfc_dev, dev)
+38
net/nfc/core.c
··· 27 27 #include <linux/kernel.h> 28 28 #include <linux/module.h> 29 29 #include <linux/slab.h> 30 + #include <linux/rfkill.h> 30 31 #include <linux/nfc.h> 31 32 32 33 #include <net/genetlink.h> ··· 58 57 pr_debug("dev_name=%s\n", dev_name(&dev->dev)); 59 58 60 59 device_lock(&dev->dev); 60 + 61 + if (dev->rfkill && rfkill_blocked(dev->rfkill)) { 62 + rc = -ERFKILL; 63 + goto error; 64 + } 61 65 62 66 if (!device_is_registered(&dev->dev)) { 63 67 rc = -ENODEV; ··· 122 116 device_unlock(&dev->dev); 123 117 return rc; 124 118 } 119 + 120 + static int nfc_rfkill_set_block(void *data, bool blocked) 121 + { 122 + struct nfc_dev *dev = data; 123 + 124 + pr_debug("%s blocked %d", dev_name(&dev->dev), blocked); 125 + 126 + if (!blocked) 127 + return 0; 128 + 129 + nfc_dev_down(dev); 130 + 131 + return 0; 132 + } 133 + 134 + static const struct rfkill_ops nfc_rfkill_ops = { 135 + .set_block = nfc_rfkill_set_block, 136 + }; 125 137 126 138 /** 127 139 * nfc_start_poll - start polling for nfc targets ··· 864 840 pr_debug("The userspace won't be notified that the device %s was added\n", 865 841 dev_name(&dev->dev)); 866 842 843 + dev->rfkill = rfkill_alloc(dev_name(&dev->dev), &dev->dev, 844 + RFKILL_TYPE_NFC, &nfc_rfkill_ops, dev); 845 + if (dev->rfkill) { 846 + if (rfkill_register(dev->rfkill) < 0) { 847 + rfkill_destroy(dev->rfkill); 848 + dev->rfkill = NULL; 849 + } 850 + } 851 + 867 852 return 0; 868 853 } 869 854 EXPORT_SYMBOL(nfc_register_device); ··· 889 856 pr_debug("dev_name=%s\n", dev_name(&dev->dev)); 890 857 891 858 id = dev->idx; 859 + 860 + if (dev->rfkill) { 861 + rfkill_unregister(dev->rfkill); 862 + rfkill_destroy(dev->rfkill); 863 + } 892 864 893 865 if (dev->ops->check_presence) { 894 866 device_lock(&dev->dev);