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

NFC: Add dev_up and dev_down control operations

Add 2 new nfc control operations:
dev_up to turn on the nfc device
dev_down to turn off the nfc device

Signed-off-by: Ilan Elias <ilane@ti.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Ilan Elias and committed by
John W. Linville
8b3fe7b5 a7ce1c94

+149
+2
drivers/nfc/pn533.c
··· 1432 1432 } 1433 1433 1434 1434 struct nfc_ops pn533_nfc_ops = { 1435 + .dev_up = NULL, 1436 + .dev_down = NULL, 1435 1437 .start_poll = pn533_start_poll, 1436 1438 .stop_poll = pn533_stop_poll, 1437 1439 .activate_target = pn533_activate_target,
+6
include/linux/nfc.h
··· 39 39 * 40 40 * @NFC_CMD_GET_DEVICE: request information about a device (requires 41 41 * %NFC_ATTR_DEVICE_INDEX) or dump request to get a list of all nfc devices 42 + * @NFC_CMD_DEV_UP: turn on the nfc device 43 + * (requires %NFC_ATTR_DEVICE_INDEX) 44 + * @NFC_CMD_DEV_DOWN: turn off the nfc device 45 + * (requires %NFC_ATTR_DEVICE_INDEX) 42 46 * @NFC_CMD_START_POLL: start polling for targets using the given protocols 43 47 * (requires %NFC_ATTR_DEVICE_INDEX and %NFC_ATTR_PROTOCOLS) 44 48 * @NFC_CMD_STOP_POLL: stop polling for targets (requires ··· 60 56 enum nfc_commands { 61 57 NFC_CMD_UNSPEC, 62 58 NFC_CMD_GET_DEVICE, 59 + NFC_CMD_DEV_UP, 60 + NFC_CMD_DEV_DOWN, 63 61 NFC_CMD_START_POLL, 64 62 NFC_CMD_STOP_POLL, 65 63 NFC_CMD_GET_TARGET,
+4
include/net/nfc.h
··· 48 48 int err); 49 49 50 50 struct nfc_ops { 51 + int (*dev_up)(struct nfc_dev *dev); 52 + int (*dev_down)(struct nfc_dev *dev); 51 53 int (*start_poll)(struct nfc_dev *dev, u32 protocols); 52 54 void (*stop_poll)(struct nfc_dev *dev); 53 55 int (*activate_target)(struct nfc_dev *dev, u32 target_idx, ··· 80 78 int targets_generation; 81 79 spinlock_t targets_lock; 82 80 struct device dev; 81 + bool dev_up; 83 82 bool polling; 83 + bool remote_activated; 84 84 struct nfc_genl_data genl_data; 85 85 u32 supported_protocols; 86 86
+77
net/nfc/core.c
··· 53 53 EXPORT_SYMBOL(nfc_printk); 54 54 55 55 /** 56 + * nfc_dev_up - turn on the NFC device 57 + * 58 + * @dev: The nfc device to be turned on 59 + * 60 + * The device remains up until the nfc_dev_down function is called. 61 + */ 62 + int nfc_dev_up(struct nfc_dev *dev) 63 + { 64 + int rc = 0; 65 + 66 + nfc_dbg("dev_name=%s", dev_name(&dev->dev)); 67 + 68 + device_lock(&dev->dev); 69 + 70 + if (!device_is_registered(&dev->dev)) { 71 + rc = -ENODEV; 72 + goto error; 73 + } 74 + 75 + if (dev->dev_up) { 76 + rc = -EALREADY; 77 + goto error; 78 + } 79 + 80 + if (dev->ops->dev_up) 81 + rc = dev->ops->dev_up(dev); 82 + 83 + if (!rc) 84 + dev->dev_up = true; 85 + 86 + error: 87 + device_unlock(&dev->dev); 88 + return rc; 89 + } 90 + 91 + /** 92 + * nfc_dev_down - turn off the NFC device 93 + * 94 + * @dev: The nfc device to be turned off 95 + */ 96 + int nfc_dev_down(struct nfc_dev *dev) 97 + { 98 + int rc = 0; 99 + 100 + nfc_dbg("dev_name=%s", dev_name(&dev->dev)); 101 + 102 + device_lock(&dev->dev); 103 + 104 + if (!device_is_registered(&dev->dev)) { 105 + rc = -ENODEV; 106 + goto error; 107 + } 108 + 109 + if (!dev->dev_up) { 110 + rc = -EALREADY; 111 + goto error; 112 + } 113 + 114 + if (dev->polling || dev->remote_activated) { 115 + rc = -EBUSY; 116 + goto error; 117 + } 118 + 119 + if (dev->ops->dev_down) 120 + dev->ops->dev_down(dev); 121 + 122 + dev->dev_up = false; 123 + 124 + error: 125 + device_unlock(&dev->dev); 126 + return rc; 127 + } 128 + 129 + /** 56 130 * nfc_start_poll - start polling for nfc targets 57 131 * 58 132 * @dev: The nfc device that must start polling ··· 218 144 } 219 145 220 146 rc = dev->ops->activate_target(dev, target_idx, protocol); 147 + if (!rc) 148 + dev->remote_activated = true; 221 149 222 150 error: 223 151 device_unlock(&dev->dev); ··· 246 170 } 247 171 248 172 dev->ops->deactivate_target(dev, target_idx); 173 + dev->remote_activated = false; 249 174 250 175 error: 251 176 device_unlock(&dev->dev);
+56
net/nfc/netlink.c
··· 367 367 return rc; 368 368 } 369 369 370 + static int nfc_genl_dev_up(struct sk_buff *skb, struct genl_info *info) 371 + { 372 + struct nfc_dev *dev; 373 + int rc; 374 + u32 idx; 375 + 376 + nfc_dbg("entry"); 377 + 378 + if (!info->attrs[NFC_ATTR_DEVICE_INDEX]) 379 + return -EINVAL; 380 + 381 + idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); 382 + 383 + dev = nfc_get_device(idx); 384 + if (!dev) 385 + return -ENODEV; 386 + 387 + rc = nfc_dev_up(dev); 388 + 389 + nfc_put_device(dev); 390 + return rc; 391 + } 392 + 393 + static int nfc_genl_dev_down(struct sk_buff *skb, struct genl_info *info) 394 + { 395 + struct nfc_dev *dev; 396 + int rc; 397 + u32 idx; 398 + 399 + nfc_dbg("entry"); 400 + 401 + if (!info->attrs[NFC_ATTR_DEVICE_INDEX]) 402 + return -EINVAL; 403 + 404 + idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); 405 + 406 + dev = nfc_get_device(idx); 407 + if (!dev) 408 + return -ENODEV; 409 + 410 + rc = nfc_dev_down(dev); 411 + 412 + nfc_put_device(dev); 413 + return rc; 414 + } 415 + 370 416 static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info) 371 417 { 372 418 struct nfc_dev *dev; ··· 484 438 .doit = nfc_genl_get_device, 485 439 .dumpit = nfc_genl_dump_devices, 486 440 .done = nfc_genl_dump_devices_done, 441 + .policy = nfc_genl_policy, 442 + }, 443 + { 444 + .cmd = NFC_CMD_DEV_UP, 445 + .doit = nfc_genl_dev_up, 446 + .policy = nfc_genl_policy, 447 + }, 448 + { 449 + .cmd = NFC_CMD_DEV_DOWN, 450 + .doit = nfc_genl_dev_down, 487 451 .policy = nfc_genl_policy, 488 452 }, 489 453 {
+4
net/nfc/nfc.h
··· 101 101 class_dev_iter_exit(iter); 102 102 } 103 103 104 + int nfc_dev_up(struct nfc_dev *dev); 105 + 106 + int nfc_dev_down(struct nfc_dev *dev); 107 + 104 108 int nfc_start_poll(struct nfc_dev *dev, u32 protocols); 105 109 106 110 int nfc_stop_poll(struct nfc_dev *dev);