diff options
Diffstat (limited to 'net/nfc/core.c')
-rw-r--r-- | net/nfc/core.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/net/nfc/core.c b/net/nfc/core.c index 6ceee8e181ca..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 | * |
@@ -143,6 +167,11 @@ int nfc_start_poll(struct nfc_dev *dev, u32 im_protocols, u32 tm_protocols) | |||
143 | goto error; | 167 | goto error; |
144 | } | 168 | } |
145 | 169 | ||
170 | if (!dev->dev_up) { | ||
171 | rc = -ENODEV; | ||
172 | goto error; | ||
173 | } | ||
174 | |||
146 | if (dev->polling) { | 175 | if (dev->polling) { |
147 | rc = -EBUSY; | 176 | rc = -EBUSY; |
148 | goto error; | 177 | goto error; |
@@ -835,6 +864,15 @@ int nfc_register_device(struct nfc_dev *dev) | |||
835 | 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", |
836 | dev_name(&dev->dev)); | 865 | dev_name(&dev->dev)); |
837 | 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 | |||
838 | return 0; | 876 | return 0; |
839 | } | 877 | } |
840 | EXPORT_SYMBOL(nfc_register_device); | 878 | EXPORT_SYMBOL(nfc_register_device); |
@@ -852,6 +890,11 @@ void nfc_unregister_device(struct nfc_dev *dev) | |||
852 | 890 | ||
853 | id = dev->idx; | 891 | id = dev->idx; |
854 | 892 | ||
893 | if (dev->rfkill) { | ||
894 | rfkill_unregister(dev->rfkill); | ||
895 | rfkill_destroy(dev->rfkill); | ||
896 | } | ||
897 | |||
855 | if (dev->ops->check_presence) { | 898 | if (dev->ops->check_presence) { |
856 | device_lock(&dev->dev); | 899 | device_lock(&dev->dev); |
857 | dev->shutting_down = true; | 900 | dev->shutting_down = true; |