diff options
-rw-r--r-- | include/net/nfc/nfc.h | 2 | ||||
-rw-r--r-- | net/nfc/core.c | 38 |
2 files changed, 40 insertions, 0 deletions
diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 87a6417fc934..5eb80bb3cbb2 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h | |||
@@ -122,6 +122,8 @@ struct nfc_dev { | |||
122 | 122 | ||
123 | bool shutting_down; | 123 | bool shutting_down; |
124 | 124 | ||
125 | struct rfkill *rfkill; | ||
126 | |||
125 | struct nfc_ops *ops; | 127 | struct nfc_ops *ops; |
126 | }; | 128 | }; |
127 | #define to_nfc_dev(_dev) container_of(_dev, struct nfc_dev, dev) | 129 | #define to_nfc_dev(_dev) container_of(_dev, struct nfc_dev, dev) |
diff --git a/net/nfc/core.c b/net/nfc/core.c index c571ca9a960c..40d2527693da 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/rfkill.h> | ||
30 | #include <linux/nfc.h> | 31 | #include <linux/nfc.h> |
31 | 32 | ||
32 | #include <net/genetlink.h> | 33 | #include <net/genetlink.h> |
@@ -58,6 +59,11 @@ int nfc_dev_up(struct nfc_dev *dev) | |||
58 | 59 | ||
59 | device_lock(&dev->dev); | 60 | device_lock(&dev->dev); |
60 | 61 | ||
62 | if (dev->rfkill && rfkill_blocked(dev->rfkill)) { | ||
63 | rc = -ERFKILL; | ||
64 | goto error; | ||
65 | } | ||
66 | |||
61 | if (!device_is_registered(&dev->dev)) { | 67 | if (!device_is_registered(&dev->dev)) { |
62 | rc = -ENODEV; | 68 | rc = -ENODEV; |
63 | goto error; | 69 | goto error; |
@@ -117,6 +123,24 @@ error: | |||
117 | return rc; | 123 | return rc; |
118 | } | 124 | } |
119 | 125 | ||
126 | static int nfc_rfkill_set_block(void *data, bool blocked) | ||
127 | { | ||
128 | struct nfc_dev *dev = data; | ||
129 | |||
130 | pr_debug("%s blocked %d", dev_name(&dev->dev), blocked); | ||
131 | |||
132 | if (!blocked) | ||
133 | return 0; | ||
134 | |||
135 | nfc_dev_down(dev); | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static const struct rfkill_ops nfc_rfkill_ops = { | ||
141 | .set_block = nfc_rfkill_set_block, | ||
142 | }; | ||
143 | |||
120 | /** | 144 | /** |
121 | * nfc_start_poll - start polling for nfc targets | 145 | * nfc_start_poll - start polling for nfc targets |
122 | * | 146 | * |
@@ -840,6 +864,15 @@ int nfc_register_device(struct nfc_dev *dev) | |||
840 | pr_debug("The userspace won't be notified that the device %s was added\n", | 864 | pr_debug("The userspace won't be notified that the device %s was added\n", |
841 | dev_name(&dev->dev)); | 865 | dev_name(&dev->dev)); |
842 | 866 | ||
867 | dev->rfkill = rfkill_alloc(dev_name(&dev->dev), &dev->dev, | ||
868 | RFKILL_TYPE_NFC, &nfc_rfkill_ops, dev); | ||
869 | if (dev->rfkill) { | ||
870 | if (rfkill_register(dev->rfkill) < 0) { | ||
871 | rfkill_destroy(dev->rfkill); | ||
872 | dev->rfkill = NULL; | ||
873 | } | ||
874 | } | ||
875 | |||
843 | return 0; | 876 | return 0; |
844 | } | 877 | } |
845 | EXPORT_SYMBOL(nfc_register_device); | 878 | EXPORT_SYMBOL(nfc_register_device); |
@@ -857,6 +890,11 @@ void nfc_unregister_device(struct nfc_dev *dev) | |||
857 | 890 | ||
858 | id = dev->idx; | 891 | id = dev->idx; |
859 | 892 | ||
893 | if (dev->rfkill) { | ||
894 | rfkill_unregister(dev->rfkill); | ||
895 | rfkill_destroy(dev->rfkill); | ||
896 | } | ||
897 | |||
860 | if (dev->ops->check_presence) { | 898 | if (dev->ops->check_presence) { |
861 | device_lock(&dev->dev); | 899 | device_lock(&dev->dev); |
862 | dev->shutting_down = true; | 900 | dev->shutting_down = true; |