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

NFC: mei_phy: move all nfc logic from mei driver to nfc

move nfc logic to mei_phy module, we prefer as much as
possible not to deal with a particualr client protocol
in the mei generic infrasutcutre

Cc: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Tomas Winkler and committed by
Greg Kroah-Hartman
be9b720a 007d64eb

+304 -242
+6 -30
drivers/misc/mei/bus.c
··· 220 220 struct mei_cl_device *mei_cl_add_device(struct mei_device *dev, 221 221 struct mei_me_client *me_cl, 222 222 struct mei_cl *cl, 223 - char *name, 224 - struct mei_cl_ops *ops) 223 + char *name) 225 224 { 226 225 struct mei_cl_device *device; 227 226 int status; ··· 234 235 kfree(device); 235 236 return NULL; 236 237 } 237 - device->cl = cl; 238 - device->ops = ops; 239 238 239 + device->cl = cl; 240 240 device->dev.parent = dev->dev; 241 241 device->dev.bus = &mei_cl_bus_type; 242 242 device->dev.type = &mei_cl_device_type; ··· 292 294 } 293 295 EXPORT_SYMBOL_GPL(mei_cl_driver_unregister); 294 296 295 - static ssize_t ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, 297 + ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, 296 298 bool blocking) 297 299 { 298 300 struct mei_device *dev; ··· 406 408 return rets; 407 409 } 408 410 409 - inline ssize_t __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length) 410 - { 411 - return ___mei_cl_send(cl, buf, length, 0); 412 - } 413 - 414 - inline ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length) 415 - { 416 - return ___mei_cl_send(cl, buf, length, 1); 417 - } 418 - 419 411 ssize_t mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length) 420 412 { 421 413 struct mei_cl *cl = device->cl; ··· 413 425 if (cl == NULL) 414 426 return -ENODEV; 415 427 416 - if (device->ops && device->ops->send) 417 - return device->ops->send(device, buf, length); 418 - 419 - return __mei_cl_send(cl, buf, length); 428 + return __mei_cl_send(cl, buf, length, 1); 420 429 } 421 430 EXPORT_SYMBOL_GPL(mei_cl_send); 422 431 423 432 ssize_t mei_cl_recv(struct mei_cl_device *device, u8 *buf, size_t length) 424 433 { 425 - struct mei_cl *cl = device->cl; 434 + struct mei_cl *cl = device->cl; 426 435 427 436 if (cl == NULL) 428 437 return -ENODEV; 429 - 430 - if (device->ops && device->ops->recv) 431 - return device->ops->recv(device, buf, length); 432 438 433 439 return __mei_cl_recv(cl, buf, length); 434 440 } ··· 504 522 if (device->event_cb) 505 523 mei_cl_read_start(device->cl, 0, NULL); 506 524 507 - if (!device->ops || !device->ops->enable) 508 - return 0; 509 - 510 - return device->ops->enable(device); 525 + return 0; 511 526 } 512 527 EXPORT_SYMBOL_GPL(mei_cl_enable_device); 513 528 ··· 518 539 return -ENODEV; 519 540 520 541 dev = cl->dev; 521 - 522 - if (device->ops && device->ops->disable) 523 - device->ops->disable(device); 524 542 525 543 device->event_cb = NULL; 526 544
+3 -4
drivers/misc/mei/mei_dev.h
··· 352 352 struct mei_cl_device *mei_cl_add_device(struct mei_device *dev, 353 353 struct mei_me_client *me_cl, 354 354 struct mei_cl *cl, 355 - char *name, 356 - struct mei_cl_ops *ops); 355 + char *name); 357 356 void mei_cl_remove_device(struct mei_cl_device *device); 358 357 359 - ssize_t __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length); 360 - ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length); 358 + ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, 359 + bool blocking); 361 360 ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length); 362 361 void mei_cl_bus_rx_event(struct mei_cl *cl); 363 362 void mei_cl_bus_remove_devices(struct mei_device *dev);
+2 -173
drivers/misc/mei/nfc.c
··· 95 95 * @cl: NFC host client 96 96 * @cl_info: NFC info host client 97 97 * @init_work: perform connection to the info client 98 - * @send_wq: send completion wait queue 99 98 * @fw_ivn: NFC Interface Version Number 100 99 * @vendor_id: NFC manufacturer ID 101 100 * @radio_type: NFC radio type 102 101 * @bus_name: bus name 103 102 * 104 - * @req_id: message counter 105 - * @recv_req_id: reception message counter 106 103 */ 107 104 struct mei_nfc_dev { 108 105 struct mei_me_client *me_cl; 109 106 struct mei_cl *cl; 110 107 struct mei_cl *cl_info; 111 108 struct work_struct init_work; 112 - wait_queue_head_t send_wq; 113 109 u8 fw_ivn; 114 110 u8 vendor_id; 115 111 u8 radio_type; 116 112 char *bus_name; 117 - 118 - u16 req_id; 119 - u16 recv_req_id; 120 113 }; 121 114 122 115 /* UUIDs for NFC F/W clients */ ··· 195 202 return 0; 196 203 } 197 204 198 - static int mei_nfc_connect(struct mei_nfc_dev *ndev) 199 - { 200 - struct mei_device *dev; 201 - struct mei_cl *cl; 202 - struct mei_nfc_cmd *cmd, *reply; 203 - struct mei_nfc_connect *connect; 204 - struct mei_nfc_connect_resp *connect_resp; 205 - size_t connect_length, connect_resp_length; 206 - int bytes_recv, ret; 207 - 208 - cl = ndev->cl; 209 - dev = cl->dev; 210 - 211 - connect_length = sizeof(struct mei_nfc_cmd) + 212 - sizeof(struct mei_nfc_connect); 213 - 214 - connect_resp_length = sizeof(struct mei_nfc_cmd) + 215 - sizeof(struct mei_nfc_connect_resp); 216 - 217 - cmd = kzalloc(connect_length, GFP_KERNEL); 218 - if (!cmd) 219 - return -ENOMEM; 220 - connect = (struct mei_nfc_connect *)cmd->data; 221 - 222 - reply = kzalloc(connect_resp_length, GFP_KERNEL); 223 - if (!reply) { 224 - kfree(cmd); 225 - return -ENOMEM; 226 - } 227 - 228 - connect_resp = (struct mei_nfc_connect_resp *)reply->data; 229 - 230 - cmd->command = MEI_NFC_CMD_MAINTENANCE; 231 - cmd->data_size = 3; 232 - cmd->sub_command = MEI_NFC_SUBCMD_CONNECT; 233 - connect->fw_ivn = ndev->fw_ivn; 234 - connect->vendor_id = ndev->vendor_id; 235 - 236 - ret = __mei_cl_send(cl, (u8 *)cmd, connect_length); 237 - if (ret < 0) { 238 - dev_err(dev->dev, "Could not send connect cmd\n"); 239 - goto err; 240 - } 241 - 242 - bytes_recv = __mei_cl_recv(cl, (u8 *)reply, connect_resp_length); 243 - if (bytes_recv < 0) { 244 - dev_err(dev->dev, "Could not read connect response\n"); 245 - ret = bytes_recv; 246 - goto err; 247 - } 248 - 249 - dev_info(dev->dev, "IVN 0x%x Vendor ID 0x%x\n", 250 - connect_resp->fw_ivn, connect_resp->vendor_id); 251 - 252 - dev_info(dev->dev, "ME FW %d.%d.%d.%d\n", 253 - connect_resp->me_major, connect_resp->me_minor, 254 - connect_resp->me_hotfix, connect_resp->me_build); 255 - 256 - ret = 0; 257 - 258 - err: 259 - kfree(reply); 260 - kfree(cmd); 261 - 262 - return ret; 263 - } 264 - 265 205 static int mei_nfc_if_version(struct mei_nfc_dev *ndev) 266 206 { 267 207 struct mei_device *dev; ··· 214 288 cmd.data_size = 1; 215 289 cmd.sub_command = MEI_NFC_SUBCMD_IF_VERSION; 216 290 217 - ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(struct mei_nfc_cmd)); 291 + ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(struct mei_nfc_cmd), 1); 218 292 if (ret < 0) { 219 293 dev_err(dev->dev, "Could not send IF version cmd\n"); 220 294 return ret; ··· 245 319 kfree(reply); 246 320 return ret; 247 321 } 248 - 249 - static int mei_nfc_enable(struct mei_cl_device *cldev) 250 - { 251 - struct mei_device *dev; 252 - struct mei_nfc_dev *ndev; 253 - int ret; 254 - 255 - ndev = (struct mei_nfc_dev *)cldev->priv_data; 256 - dev = ndev->cl->dev; 257 - 258 - ret = mei_nfc_connect(ndev); 259 - if (ret < 0) { 260 - dev_err(dev->dev, "Could not connect to NFC"); 261 - return ret; 262 - } 263 - 264 - return 0; 265 - } 266 - 267 - static int mei_nfc_disable(struct mei_cl_device *cldev) 268 - { 269 - return 0; 270 - } 271 - 272 - static int mei_nfc_send(struct mei_cl_device *cldev, u8 *buf, size_t length) 273 - { 274 - struct mei_device *dev; 275 - struct mei_nfc_dev *ndev; 276 - struct mei_nfc_hci_hdr *hdr; 277 - u8 *mei_buf; 278 - int err; 279 - 280 - ndev = (struct mei_nfc_dev *) cldev->priv_data; 281 - dev = ndev->cl->dev; 282 - 283 - err = -ENOMEM; 284 - mei_buf = kzalloc(length + MEI_NFC_HEADER_SIZE, GFP_KERNEL); 285 - if (!mei_buf) 286 - goto out; 287 - 288 - hdr = (struct mei_nfc_hci_hdr *) mei_buf; 289 - hdr->cmd = MEI_NFC_CMD_HCI_SEND; 290 - hdr->status = 0; 291 - hdr->req_id = ndev->req_id; 292 - hdr->reserved = 0; 293 - hdr->data_size = length; 294 - 295 - memcpy(mei_buf + MEI_NFC_HEADER_SIZE, buf, length); 296 - err = __mei_cl_send(ndev->cl, mei_buf, length + MEI_NFC_HEADER_SIZE); 297 - if (err < 0) 298 - goto out; 299 - 300 - if (!wait_event_interruptible_timeout(ndev->send_wq, 301 - ndev->recv_req_id == ndev->req_id, HZ)) { 302 - dev_err(dev->dev, "NFC MEI command timeout\n"); 303 - err = -ETIME; 304 - } else { 305 - ndev->req_id++; 306 - } 307 - out: 308 - kfree(mei_buf); 309 - return err; 310 - } 311 - 312 - static int mei_nfc_recv(struct mei_cl_device *cldev, u8 *buf, size_t length) 313 - { 314 - struct mei_nfc_dev *ndev; 315 - struct mei_nfc_hci_hdr *hci_hdr; 316 - int received_length; 317 - 318 - ndev = (struct mei_nfc_dev *)cldev->priv_data; 319 - 320 - received_length = __mei_cl_recv(ndev->cl, buf, length); 321 - if (received_length < 0) 322 - return received_length; 323 - 324 - hci_hdr = (struct mei_nfc_hci_hdr *) buf; 325 - 326 - if (hci_hdr->cmd == MEI_NFC_CMD_HCI_SEND) { 327 - ndev->recv_req_id = hci_hdr->req_id; 328 - wake_up(&ndev->send_wq); 329 - 330 - return 0; 331 - } 332 - 333 - return received_length; 334 - } 335 - 336 - static struct mei_cl_ops nfc_ops = { 337 - .enable = mei_nfc_enable, 338 - .disable = mei_nfc_disable, 339 - .send = mei_nfc_send, 340 - .recv = mei_nfc_recv, 341 - }; 342 322 343 323 static void mei_nfc_init(struct work_struct *work) 344 324 { ··· 305 473 } 306 474 307 475 cldev = mei_cl_add_device(dev, ndev->me_cl, ndev->cl, 308 - ndev->bus_name, &nfc_ops); 476 + ndev->bus_name); 309 477 if (!cldev) { 310 478 dev_err(dev->dev, "Could not add the NFC device to the MEI bus\n"); 311 479 ··· 371 539 372 540 ndev->cl = cl; 373 541 374 - ndev->req_id = 1; 375 - 376 542 INIT_WORK(&ndev->init_work, mei_nfc_init); 377 - init_waitqueue_head(&ndev->send_wq); 378 543 schedule_work(&ndev->init_work); 379 544 380 545 return 0;
+266 -27
drivers/nfc/mei_phy.c
··· 24 24 25 25 #include "mei_phy.h" 26 26 27 - struct mei_nfc_hdr { 27 + struct mei_nfc_cmd { 28 + u8 command; 29 + u8 status; 30 + u16 req_id; 31 + u32 reserved; 32 + u16 data_size; 33 + u8 sub_command; 34 + u8 data[]; 35 + } __packed; 36 + 37 + struct mei_nfc_reply { 38 + u8 command; 39 + u8 status; 40 + u16 req_id; 41 + u32 reserved; 42 + u16 data_size; 43 + u8 sub_command; 44 + u8 reply_status; 45 + u8 data[]; 46 + } __packed; 47 + 48 + struct mei_nfc_if_version { 49 + u8 radio_version_sw[3]; 50 + u8 reserved[3]; 51 + u8 radio_version_hw[3]; 52 + u8 i2c_addr; 53 + u8 fw_ivn; 54 + u8 vendor_id; 55 + u8 radio_type; 56 + } __packed; 57 + 58 + struct mei_nfc_connect { 59 + u8 fw_ivn; 60 + u8 vendor_id; 61 + } __packed; 62 + 63 + struct mei_nfc_connect_resp { 64 + u8 fw_ivn; 65 + u8 vendor_id; 66 + u16 me_major; 67 + u16 me_minor; 68 + u16 me_hotfix; 69 + u16 me_build; 70 + } __packed; 71 + 72 + struct mei_nfc_hci_hdr { 28 73 u8 cmd; 29 74 u8 status; 30 75 u16 req_id; 31 76 u32 reserved; 32 77 u16 data_size; 33 78 } __packed; 79 + 80 + #define MEI_NFC_CMD_MAINTENANCE 0x00 81 + #define MEI_NFC_CMD_HCI_SEND 0x01 82 + #define MEI_NFC_CMD_HCI_RECV 0x02 83 + 84 + #define MEI_NFC_SUBCMD_CONNECT 0x00 85 + #define MEI_NFC_SUBCMD_IF_VERSION 0x01 86 + 87 + #define MEI_NFC_HEADER_SIZE 10 88 + 34 89 35 90 #define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD) 36 91 ··· 100 45 do { \ 101 46 pr_debug("%s:\n", info); \ 102 47 print_hex_dump_debug("mei out: ", DUMP_PREFIX_OFFSET, \ 103 - 16, 1, (skb)->data, (skb)->len, false); \ 48 + 16, 1, (skb)->data, (skb)->len, false); \ 104 49 } while (0) 105 50 106 - int nfc_mei_phy_enable(void *phy_id) 51 + 52 + static int mei_nfc_if_version(struct nfc_mei_phy *phy) 107 53 { 108 - int r; 109 - struct nfc_mei_phy *phy = phy_id; 54 + 55 + struct mei_nfc_cmd cmd; 56 + struct mei_nfc_reply *reply = NULL; 57 + struct mei_nfc_if_version *version; 58 + size_t if_version_length; 59 + int bytes_recv, r; 110 60 111 61 pr_info("%s\n", __func__); 112 62 113 - if (phy->powered == 1) 114 - return 0; 63 + memset(&cmd, 0, sizeof(struct mei_nfc_cmd)); 64 + cmd.command = MEI_NFC_CMD_MAINTENANCE; 65 + cmd.data_size = 1; 66 + cmd.sub_command = MEI_NFC_SUBCMD_IF_VERSION; 115 67 116 - r = mei_cl_enable_device(phy->device); 68 + r = mei_cl_send(phy->device, (u8 *)&cmd, sizeof(struct mei_nfc_cmd)); 117 69 if (r < 0) { 118 - pr_err("Could not enable device\n"); 70 + pr_err("Could not send IF version cmd\n"); 119 71 return r; 120 72 } 121 73 122 - r = mei_cl_register_event_cb(phy->device, nfc_mei_event_cb, phy); 123 - if (r) { 124 - pr_err("Event cb registration failed\n"); 125 - mei_cl_disable_device(phy->device); 126 - phy->powered = 0; 74 + /* to be sure on the stack we alloc memory */ 75 + if_version_length = sizeof(struct mei_nfc_reply) + 76 + sizeof(struct mei_nfc_if_version); 127 77 128 - return r; 78 + reply = kzalloc(if_version_length, GFP_KERNEL); 79 + if (!reply) 80 + return -ENOMEM; 81 + 82 + bytes_recv = mei_cl_recv(phy->device, (u8 *)reply, if_version_length); 83 + if (bytes_recv < 0 || bytes_recv < sizeof(struct mei_nfc_reply)) { 84 + pr_err("Could not read IF version\n"); 85 + r = -EIO; 86 + goto err; 129 87 } 130 88 131 - phy->powered = 1; 89 + version = (struct mei_nfc_if_version *)reply->data; 132 90 133 - return 0; 91 + phy->fw_ivn = version->fw_ivn; 92 + phy->vendor_id = version->vendor_id; 93 + phy->radio_type = version->radio_type; 94 + 95 + err: 96 + kfree(reply); 97 + return r; 134 98 } 135 - EXPORT_SYMBOL_GPL(nfc_mei_phy_enable); 136 99 137 - void nfc_mei_phy_disable(void *phy_id) 100 + static int mei_nfc_connect(struct nfc_mei_phy *phy) 138 101 { 139 - struct nfc_mei_phy *phy = phy_id; 102 + struct mei_nfc_cmd *cmd, *reply; 103 + struct mei_nfc_connect *connect; 104 + struct mei_nfc_connect_resp *connect_resp; 105 + size_t connect_length, connect_resp_length; 106 + int bytes_recv, r; 140 107 141 108 pr_info("%s\n", __func__); 142 109 143 - mei_cl_disable_device(phy->device); 110 + connect_length = sizeof(struct mei_nfc_cmd) + 111 + sizeof(struct mei_nfc_connect); 144 112 145 - phy->powered = 0; 113 + connect_resp_length = sizeof(struct mei_nfc_cmd) + 114 + sizeof(struct mei_nfc_connect_resp); 115 + 116 + cmd = kzalloc(connect_length, GFP_KERNEL); 117 + if (!cmd) 118 + return -ENOMEM; 119 + connect = (struct mei_nfc_connect *)cmd->data; 120 + 121 + reply = kzalloc(connect_resp_length, GFP_KERNEL); 122 + if (!reply) { 123 + kfree(cmd); 124 + return -ENOMEM; 125 + } 126 + 127 + connect_resp = (struct mei_nfc_connect_resp *)reply->data; 128 + 129 + cmd->command = MEI_NFC_CMD_MAINTENANCE; 130 + cmd->data_size = 3; 131 + cmd->sub_command = MEI_NFC_SUBCMD_CONNECT; 132 + connect->fw_ivn = phy->fw_ivn; 133 + connect->vendor_id = phy->vendor_id; 134 + 135 + r = mei_cl_send(phy->device, (u8 *)cmd, connect_length); 136 + if (r < 0) { 137 + pr_err("Could not send connect cmd %d\n", r); 138 + goto err; 139 + } 140 + 141 + bytes_recv = mei_cl_recv(phy->device, (u8 *)reply, connect_resp_length); 142 + if (bytes_recv < 0) { 143 + r = bytes_recv; 144 + pr_err("Could not read connect response %d\n", r); 145 + goto err; 146 + } 147 + 148 + pr_info("IVN 0x%x Vendor ID 0x%x\n", 149 + connect_resp->fw_ivn, connect_resp->vendor_id); 150 + 151 + pr_info("ME FW %d.%d.%d.%d\n", 152 + connect_resp->me_major, connect_resp->me_minor, 153 + connect_resp->me_hotfix, connect_resp->me_build); 154 + 155 + r = 0; 156 + 157 + err: 158 + kfree(reply); 159 + kfree(cmd); 160 + 161 + return r; 146 162 } 147 - EXPORT_SYMBOL_GPL(nfc_mei_phy_disable); 163 + 164 + static int mei_nfc_send(struct nfc_mei_phy *phy, u8 *buf, size_t length) 165 + { 166 + struct mei_nfc_hci_hdr *hdr; 167 + u8 *mei_buf; 168 + int err; 169 + 170 + err = -ENOMEM; 171 + mei_buf = kzalloc(length + MEI_NFC_HEADER_SIZE, GFP_KERNEL); 172 + if (!mei_buf) 173 + goto out; 174 + 175 + hdr = (struct mei_nfc_hci_hdr *) mei_buf; 176 + hdr->cmd = MEI_NFC_CMD_HCI_SEND; 177 + hdr->status = 0; 178 + hdr->req_id = phy->req_id; 179 + hdr->reserved = 0; 180 + hdr->data_size = length; 181 + 182 + memcpy(mei_buf + MEI_NFC_HEADER_SIZE, buf, length); 183 + err = mei_cl_send(phy->device, mei_buf, length + MEI_NFC_HEADER_SIZE); 184 + if (err < 0) 185 + goto out; 186 + 187 + if (!wait_event_interruptible_timeout(phy->send_wq, 188 + phy->recv_req_id == phy->req_id, HZ)) { 189 + pr_err("NFC MEI command timeout\n"); 190 + err = -ETIME; 191 + } else { 192 + phy->req_id++; 193 + } 194 + out: 195 + kfree(mei_buf); 196 + return err; 197 + } 148 198 149 199 /* 150 200 * Writing a frame must not return the number of written bytes. ··· 263 103 264 104 MEI_DUMP_SKB_OUT("mei frame sent", skb); 265 105 266 - r = mei_cl_send(phy->device, skb->data, skb->len); 106 + r = mei_nfc_send(phy, skb->data, skb->len); 267 107 if (r > 0) 268 108 r = 0; 269 109 270 110 return r; 271 111 } 272 112 273 - void nfc_mei_event_cb(struct mei_cl_device *device, u32 events, void *context) 113 + static int mei_nfc_recv(struct nfc_mei_phy *phy, u8 *buf, size_t length) 114 + { 115 + struct mei_nfc_hci_hdr *hci_hdr; 116 + int received_length; 117 + 118 + received_length = mei_cl_recv(phy->device, buf, length); 119 + if (received_length < 0) 120 + return received_length; 121 + 122 + hci_hdr = (struct mei_nfc_hci_hdr *) buf; 123 + 124 + if (hci_hdr->cmd == MEI_NFC_CMD_HCI_SEND) { 125 + phy->recv_req_id = hci_hdr->req_id; 126 + wake_up(&phy->send_wq); 127 + 128 + return 0; 129 + } 130 + 131 + return received_length; 132 + } 133 + 134 + 135 + static void nfc_mei_event_cb(struct mei_cl_device *device, u32 events, 136 + void *context) 274 137 { 275 138 struct nfc_mei_phy *phy = context; 276 139 ··· 308 125 if (!skb) 309 126 return; 310 127 311 - reply_size = mei_cl_recv(device, skb->data, MEI_NFC_MAX_READ); 128 + reply_size = mei_nfc_recv(phy, skb->data, MEI_NFC_MAX_READ); 312 129 if (reply_size < MEI_NFC_HEADER_SIZE) { 313 130 kfree_skb(skb); 314 131 return; ··· 322 139 nfc_hci_recv_frame(phy->hdev, skb); 323 140 } 324 141 } 325 - EXPORT_SYMBOL_GPL(nfc_mei_event_cb); 142 + 143 + static int nfc_mei_phy_enable(void *phy_id) 144 + { 145 + int r; 146 + struct nfc_mei_phy *phy = phy_id; 147 + 148 + pr_info("%s\n", __func__); 149 + 150 + if (phy->powered == 1) 151 + return 0; 152 + 153 + r = mei_cl_enable_device(phy->device); 154 + if (r < 0) { 155 + pr_err("Could not enable device %d\n", r); 156 + return r; 157 + } 158 + 159 + r = mei_nfc_if_version(phy); 160 + if (r < 0) { 161 + pr_err("Could not enable device %d\n", r); 162 + goto err; 163 + } 164 + 165 + r = mei_nfc_connect(phy); 166 + if (r < 0) { 167 + pr_err("Could not connect to device %d\n", r); 168 + goto err; 169 + } 170 + 171 + r = mei_cl_register_event_cb(phy->device, nfc_mei_event_cb, phy); 172 + if (r) { 173 + pr_err("Event cb registration failed %d\n", r); 174 + goto err; 175 + } 176 + 177 + phy->powered = 1; 178 + 179 + return 0; 180 + 181 + err: 182 + phy->powered = 0; 183 + mei_cl_disable_device(phy->device); 184 + return r; 185 + } 186 + 187 + static void nfc_mei_phy_disable(void *phy_id) 188 + { 189 + struct nfc_mei_phy *phy = phy_id; 190 + 191 + pr_info("%s\n", __func__); 192 + 193 + mei_cl_disable_device(phy->device); 194 + 195 + phy->powered = 0; 196 + } 326 197 327 198 struct nfc_phy_ops mei_phy_ops = { 328 199 .write = nfc_mei_phy_write, ··· 394 157 return NULL; 395 158 396 159 phy->device = device; 160 + init_waitqueue_head(&phy->send_wq); 397 161 mei_cl_set_drvdata(device, phy); 398 162 399 163 return phy; ··· 403 165 404 166 void nfc_mei_phy_free(struct nfc_mei_phy *phy) 405 167 { 168 + mei_cl_disable_device(phy->device); 406 169 kfree(phy); 407 170 } 408 171 EXPORT_SYMBOL_GPL(nfc_mei_phy_free);
+27 -8
drivers/nfc/mei_phy.h
··· 10 10 #define MEI_NFC_HEADER_SIZE 10 11 11 #define MEI_NFC_MAX_HCI_PAYLOAD 300 12 12 13 + /** 14 + * struct nfc_mei_phy 15 + * 16 + * @device: mei device 17 + * @hdev: nfc hci device 18 + 19 + * @send_wq: send completion wait queue 20 + * @fw_ivn: NFC Interface Version Number 21 + * @vendor_id: NFC manufacturer ID 22 + * @radio_type: NFC radio type 23 + * @reserved: reserved for alignment 24 + * @req_id: message counter 25 + * @recv_req_id: reception message counter 26 + * @powered: the device is in powered state 27 + * @hard_fault: < 0 if hardware error occurred 28 + * and prevents normal operation. 29 + */ 13 30 struct nfc_mei_phy { 14 31 struct mei_cl_device *device; 15 32 struct nfc_hci_dev *hdev; 16 33 17 - int powered; 34 + wait_queue_head_t send_wq; 35 + u8 fw_ivn; 36 + u8 vendor_id; 37 + u8 radio_type; 38 + u8 reserved; 18 39 19 - int hard_fault; /* 20 - * < 0 if hardware error occured 21 - * and prevents normal operation. 22 - */ 40 + u16 req_id; 41 + u16 recv_req_id; 42 + 43 + int powered; 44 + int hard_fault; 23 45 }; 24 46 25 47 extern struct nfc_phy_ops mei_phy_ops; 26 48 27 - int nfc_mei_phy_enable(void *phy_id); 28 - void nfc_mei_phy_disable(void *phy_id); 29 - void nfc_mei_event_cb(struct mei_cl_device *device, u32 events, void *context); 30 49 struct nfc_mei_phy *nfc_mei_phy_alloc(struct mei_cl_device *device); 31 50 void nfc_mei_phy_free(struct nfc_mei_phy *phy); 32 51