From 9728ee92f740acc65d54e6c62b9124cd0676cba9 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Sat, 4 Feb 2017 10:15:22 +0900 Subject: nfc: Add support RC-S380P to port100 Signed-off-by: OGAWA Hirofumi Signed-off-by: Samuel Ortiz --- drivers/nfc/port100.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/nfc/port100.c b/drivers/nfc/port100.c index 2b2330b235e6..32258525513e 100644 --- a/drivers/nfc/port100.c +++ b/drivers/nfc/port100.c @@ -21,8 +21,9 @@ #define VERSION "0.1" -#define SONY_VENDOR_ID 0x054c -#define RCS380_PRODUCT_ID 0x06c1 +#define SONY_VENDOR_ID 0x054c +#define RCS380S_PRODUCT_ID 0x06c1 +#define RCS380P_PRODUCT_ID 0x06c3 #define PORT100_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \ NFC_PROTO_MIFARE_MASK | \ @@ -1477,7 +1478,8 @@ static struct nfc_digital_ops port100_digital_ops = { }; static const struct usb_device_id port100_table[] = { - { USB_DEVICE(SONY_VENDOR_ID, RCS380_PRODUCT_ID), }, + { USB_DEVICE(SONY_VENDOR_ID, RCS380S_PRODUCT_ID), }, + { USB_DEVICE(SONY_VENDOR_ID, RCS380P_PRODUCT_ID), }, { } }; MODULE_DEVICE_TABLE(usb, port100_table); -- cgit From 85a2566d70a851c85806f687b93a9559bb8a3b11 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Sat, 4 Feb 2017 10:15:55 +0900 Subject: nfc: Send same info for both of NFC_CMD_GET_DEVICE and NFC_EVENT_DEVICE_ADDED Now, NFC_EVENT_DEVICE_ADDED doesn't send NFC_ATTR_RF_MODE. But NFC_CMD_GET_DEVICE send. To get NFC_ATTR_RF_MODE, we have to call NFC_CMD_GET_DEVICE just for NFC_ATTR_RF_MODE when get NFC_EVENT_DEVICE_ADDED. This fixes those inconsistent. Signed-off-by: OGAWA Hirofumi Signed-off-by: Samuel Ortiz --- net/nfc/netlink.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 03f3d5c7beb8..4c95319dc22b 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -303,6 +303,17 @@ free_msg: return -EMSGSIZE; } +static int nfc_genl_setup_device_added(struct nfc_dev *dev, struct sk_buff *msg) +{ + if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) || + nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) || + nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) || + nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up) || + nla_put_u8(msg, NFC_ATTR_RF_MODE, dev->rf_mode)) + return -1; + return 0; +} + int nfc_genl_device_added(struct nfc_dev *dev) { struct sk_buff *msg; @@ -317,10 +328,7 @@ int nfc_genl_device_added(struct nfc_dev *dev) if (!hdr) goto free_msg; - if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) || - nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) || - nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) || - nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up)) + if (nfc_genl_setup_device_added(dev, msg)) goto nla_put_failure; genlmsg_end(msg, hdr); @@ -596,11 +604,7 @@ static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev, if (cb) genl_dump_check_consistent(cb, hdr, &nfc_genl_family); - if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) || - nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) || - nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) || - nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up) || - nla_put_u8(msg, NFC_ATTR_RF_MODE, dev->rf_mode)) + if (nfc_genl_setup_device_added(dev, msg)) goto nla_put_failure; genlmsg_end(msg, hdr); -- cgit From 0ada076819529203e11fcd5d3d52a2c9ada21879 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Sat, 4 Feb 2017 10:16:28 +0900 Subject: nfc: Fix RC-S380* needs zero-length packet If sent packet size is wMaxPacketSize boundary, this device doesn't answer. To fix this, we have to send zero-length packet in usb spec. Signed-off-by: OGAWA Hirofumi Signed-off-by: Samuel Ortiz --- drivers/nfc/port100.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/nfc/port100.c b/drivers/nfc/port100.c index 32258525513e..382985d3fee0 100644 --- a/drivers/nfc/port100.c +++ b/drivers/nfc/port100.c @@ -1540,6 +1540,7 @@ static int port100_probe(struct usb_interface *interface, usb_fill_bulk_urb(dev->out_urb, dev->udev, usb_sndbulkpipe(dev->udev, out_endpoint), NULL, 0, port100_send_complete, dev); + dev->out_urb->transfer_flags = URB_ZERO_PACKET; dev->skb_headroom = PORT100_FRAME_HEADER_LEN + PORT100_COMM_RF_HEAD_MAX_LEN; -- cgit From 2497128133f8169b24b928852ba6eae34fc495e5 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Sat, 4 Feb 2017 10:16:56 +0900 Subject: nfc: Fix hangup of RC-S380* in port100_send_ack() If port100_send_ack() was called twice or more, it has race to hangup. port100_send_ack() port100_send_ack() init_completion() [...] dev->cmd_cancel = true /* this removes previous from completion */ init_completion() [...] dev->cmd_cancel = true wait_for_completion() /* never be waked up */ wait_for_completion() Like above race, this code is not assuming port100_send_ack() is called twice or more. To fix, this checks dev->cmd_cancel to know if prior cancel is in-flight or not. And never be remove prior task from completion by using reinit_completion(), so this guarantees to be waked up properly soon or later. Signed-off-by: OGAWA Hirofumi Signed-off-by: Samuel Ortiz --- drivers/nfc/port100.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/nfc/port100.c b/drivers/nfc/port100.c index 382985d3fee0..19be93e177fe 100644 --- a/drivers/nfc/port100.c +++ b/drivers/nfc/port100.c @@ -726,23 +726,33 @@ static int port100_submit_urb_for_ack(struct port100 *dev, gfp_t flags) static int port100_send_ack(struct port100 *dev) { - int rc; + int rc = 0; mutex_lock(&dev->out_urb_lock); - init_completion(&dev->cmd_cancel_done); + /* + * If prior cancel is in-flight (dev->cmd_cancel == true), we + * can skip to send cancel. Then this will wait the prior + * cancel, or merged into the next cancel rarely if next + * cancel was started before waiting done. In any case, this + * will be waked up soon or later. + */ + if (!dev->cmd_cancel) { + reinit_completion(&dev->cmd_cancel_done); - usb_kill_urb(dev->out_urb); + usb_kill_urb(dev->out_urb); - dev->out_urb->transfer_buffer = ack_frame; - dev->out_urb->transfer_buffer_length = sizeof(ack_frame); - rc = usb_submit_urb(dev->out_urb, GFP_KERNEL); + dev->out_urb->transfer_buffer = ack_frame; + dev->out_urb->transfer_buffer_length = sizeof(ack_frame); + rc = usb_submit_urb(dev->out_urb, GFP_KERNEL); - /* Set the cmd_cancel flag only if the URB has been successfully - * submitted. It will be reset by the out URB completion callback - * port100_send_complete(). - */ - dev->cmd_cancel = !rc; + /* + * Set the cmd_cancel flag only if the URB has been + * successfully submitted. It will be reset by the out + * URB completion callback port100_send_complete(). + */ + dev->cmd_cancel = !rc; + } mutex_unlock(&dev->out_urb_lock); @@ -929,8 +939,8 @@ static void port100_send_complete(struct urb *urb) struct port100 *dev = urb->context; if (dev->cmd_cancel) { + complete_all(&dev->cmd_cancel_done); dev->cmd_cancel = false; - complete(&dev->cmd_cancel_done); } switch (urb->status) { @@ -1546,6 +1556,7 @@ static int port100_probe(struct usb_interface *interface, PORT100_COMM_RF_HEAD_MAX_LEN; dev->skb_tailroom = PORT100_FRAME_TAIL_LEN; + init_completion(&dev->cmd_cancel_done); INIT_WORK(&dev->cmd_complete_work, port100_wq_cmd_complete); /* The first thing to do with the Port-100 is to set the command type -- cgit From 0b73ef7992e2a18250c1ff2f67bbb2a6d2acbef1 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 25 Jan 2017 16:23:07 -0600 Subject: NFC: remove TI nfcwilink driver It appears that TI WiLink devices including NFC (WL185x/WL189x) never shipped. The only information I found were announcements in Feb 2012 about the parts. There's been no activity on this driver besided common changes since initially added in Jan 2012. There's also no in users that instantiate the platform device (nor DT bindings). This is a first step in removing TI ST (shared transport) driver in favor of extending the BT hci_ll driver to support WL183x chips. Cc: Ilan Elias Cc: Marcel Holtmann Cc: Samuel Ortiz Cc: Lauro Ramos Venancio Cc: Aloisio Almeida Jr Cc: linux-wireless@vger.kernel.org Signed-off-by: Rob Herring Signed-off-by: Samuel Ortiz --- drivers/nfc/Kconfig | 11 - drivers/nfc/Makefile | 1 - drivers/nfc/nfcwilink.c | 578 ------------------------------------------------ 3 files changed, 590 deletions(-) delete mode 100644 drivers/nfc/nfcwilink.c diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig index 9d2369269abf..c4208487fadc 100644 --- a/drivers/nfc/Kconfig +++ b/drivers/nfc/Kconfig @@ -5,17 +5,6 @@ menu "Near Field Communication (NFC) devices" depends on NFC -config NFC_WILINK - tristate "Texas Instruments NFC WiLink driver" - depends on TI_ST && NFC_NCI - help - This enables the NFC driver for Texas Instrument's BT/FM/GPS/NFC - combo devices. This makes use of shared transport line discipline - core driver to communicate with the NFC core of the combo chip. - - Say Y here to compile support for Texas Instrument's NFC WiLink driver - into the kernel or say M to compile it as module. - config NFC_TRF7970A tristate "Texas Instruments TRF7970a NFC driver" depends on SPI && NFC_DIGITAL diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile index bab8ef06ae35..640b7274371c 100644 --- a/drivers/nfc/Makefile +++ b/drivers/nfc/Makefile @@ -6,7 +6,6 @@ obj-$(CONFIG_NFC_FDP) += fdp/ obj-$(CONFIG_NFC_PN544) += pn544/ obj-$(CONFIG_NFC_MICROREAD) += microread/ obj-$(CONFIG_NFC_PN533) += pn533/ -obj-$(CONFIG_NFC_WILINK) += nfcwilink.o obj-$(CONFIG_NFC_MEI_PHY) += mei_phy.o obj-$(CONFIG_NFC_SIM) += nfcsim.o obj-$(CONFIG_NFC_PORT100) += port100.o diff --git a/drivers/nfc/nfcwilink.c b/drivers/nfc/nfcwilink.c deleted file mode 100644 index 3fbd18b8e473..000000000000 --- a/drivers/nfc/nfcwilink.c +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Texas Instrument's NFC Driver For Shared Transport. - * - * NFC Driver acts as interface between NCI core and - * TI Shared Transport Layer. - * - * Copyright (C) 2011 Texas Instruments, Inc. - * - * Written by Ilan Elias - * - * Acknowledgements: - * This file is based on btwilink.c, which was written - * by Raja Mani and Pavan Savoy. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#define NFCWILINK_CHNL 12 -#define NFCWILINK_OPCODE 7 -#define NFCWILINK_MAX_FRAME_SIZE 300 -#define NFCWILINK_HDR_LEN 4 -#define NFCWILINK_OFFSET_LEN_IN_HDR 1 -#define NFCWILINK_LEN_SIZE 2 -#define NFCWILINK_REGISTER_TIMEOUT 8000 /* 8 sec */ -#define NFCWILINK_CMD_TIMEOUT 5000 /* 5 sec */ - -#define BTS_FILE_NAME_MAX_SIZE 40 -#define BTS_FILE_HDR_MAGIC 0x42535442 -#define BTS_FILE_CMD_MAX_LEN 0xff -#define BTS_FILE_ACTION_TYPE_SEND_CMD 1 - -#define NCI_VS_NFCC_INFO_CMD_GID 0x2f -#define NCI_VS_NFCC_INFO_CMD_OID 0x12 -#define NCI_VS_NFCC_INFO_RSP_GID 0x4f -#define NCI_VS_NFCC_INFO_RSP_OID 0x12 - -struct nfcwilink_hdr { - __u8 chnl; - __u8 opcode; - __le16 len; -} __packed; - -struct nci_vs_nfcc_info_cmd { - __u8 gid; - __u8 oid; - __u8 plen; -} __packed; - -struct nci_vs_nfcc_info_rsp { - __u8 gid; - __u8 oid; - __u8 plen; - __u8 status; - __u8 hw_id; - __u8 sw_ver_x; - __u8 sw_ver_z; - __u8 patch_id; -} __packed; - -struct bts_file_hdr { - __le32 magic; - __le32 ver; - __u8 rfu[24]; - __u8 actions[0]; -} __packed; - -struct bts_file_action { - __le16 type; - __le16 len; - __u8 data[0]; -} __packed; - -struct nfcwilink { - struct platform_device *pdev; - struct nci_dev *ndev; - unsigned long flags; - - int st_register_cb_status; - long (*st_write) (struct sk_buff *); - - struct completion completed; - - struct nci_vs_nfcc_info_rsp nfcc_info; -}; - -/* NFCWILINK driver flags */ -enum { - NFCWILINK_RUNNING, - NFCWILINK_FW_DOWNLOAD, -}; - -static int nfcwilink_send(struct nci_dev *ndev, struct sk_buff *skb); - -static inline struct sk_buff *nfcwilink_skb_alloc(unsigned int len, gfp_t how) -{ - struct sk_buff *skb; - - skb = alloc_skb(len + NFCWILINK_HDR_LEN, how); - if (skb) - skb_reserve(skb, NFCWILINK_HDR_LEN); - - return skb; -} - -static void nfcwilink_fw_download_receive(struct nfcwilink *drv, - struct sk_buff *skb) -{ - struct nci_vs_nfcc_info_rsp *rsp = (void *)skb->data; - - /* Detect NCI_VS_NFCC_INFO_RSP and store the result */ - if ((skb->len > 3) && (rsp->gid == NCI_VS_NFCC_INFO_RSP_GID) && - (rsp->oid == NCI_VS_NFCC_INFO_RSP_OID)) { - memcpy(&drv->nfcc_info, rsp, - sizeof(struct nci_vs_nfcc_info_rsp)); - } - - kfree_skb(skb); - - complete(&drv->completed); -} - -static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name) -{ - struct nci_vs_nfcc_info_cmd *cmd; - struct sk_buff *skb; - unsigned long comp_ret; - int rc; - - skb = nfcwilink_skb_alloc(sizeof(struct nci_vs_nfcc_info_cmd), - GFP_KERNEL); - if (!skb) { - nfc_err(&drv->pdev->dev, - "no memory for nci_vs_nfcc_info_cmd\n"); - return -ENOMEM; - } - - cmd = (struct nci_vs_nfcc_info_cmd *) - skb_put(skb, sizeof(struct nci_vs_nfcc_info_cmd)); - cmd->gid = NCI_VS_NFCC_INFO_CMD_GID; - cmd->oid = NCI_VS_NFCC_INFO_CMD_OID; - cmd->plen = 0; - - drv->nfcc_info.plen = 0; - - rc = nfcwilink_send(drv->ndev, skb); - if (rc) - return rc; - - comp_ret = wait_for_completion_timeout(&drv->completed, - msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT)); - dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld\n", - comp_ret); - if (comp_ret == 0) { - nfc_err(&drv->pdev->dev, - "timeout on wait_for_completion_timeout\n"); - return -ETIMEDOUT; - } - - dev_dbg(&drv->pdev->dev, "nci_vs_nfcc_info_rsp: plen %d, status %d\n", - drv->nfcc_info.plen, drv->nfcc_info.status); - - if ((drv->nfcc_info.plen != 5) || (drv->nfcc_info.status != 0)) { - nfc_err(&drv->pdev->dev, "invalid nci_vs_nfcc_info_rsp\n"); - return -EINVAL; - } - - snprintf(file_name, BTS_FILE_NAME_MAX_SIZE, - "TINfcInit_%d.%d.%d.%d.bts", - drv->nfcc_info.hw_id, - drv->nfcc_info.sw_ver_x, - drv->nfcc_info.sw_ver_z, - drv->nfcc_info.patch_id); - - nfc_info(&drv->pdev->dev, "nfcwilink FW file name: %s\n", file_name); - - return 0; -} - -static int nfcwilink_send_bts_cmd(struct nfcwilink *drv, __u8 *data, int len) -{ - struct nfcwilink_hdr *hdr = (struct nfcwilink_hdr *)data; - struct sk_buff *skb; - unsigned long comp_ret; - int rc; - - /* verify valid cmd for the NFC channel */ - if ((len <= sizeof(struct nfcwilink_hdr)) || - (len > BTS_FILE_CMD_MAX_LEN) || - (hdr->chnl != NFCWILINK_CHNL) || - (hdr->opcode != NFCWILINK_OPCODE)) { - nfc_err(&drv->pdev->dev, - "ignoring invalid bts cmd, len %d, chnl %d, opcode %d\n", - len, hdr->chnl, hdr->opcode); - return 0; - } - - /* remove the ST header */ - len -= sizeof(struct nfcwilink_hdr); - data += sizeof(struct nfcwilink_hdr); - - skb = nfcwilink_skb_alloc(len, GFP_KERNEL); - if (!skb) { - nfc_err(&drv->pdev->dev, "no memory for bts cmd\n"); - return -ENOMEM; - } - - memcpy(skb_put(skb, len), data, len); - - rc = nfcwilink_send(drv->ndev, skb); - if (rc) - return rc; - - comp_ret = wait_for_completion_timeout(&drv->completed, - msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT)); - dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld\n", - comp_ret); - if (comp_ret == 0) { - nfc_err(&drv->pdev->dev, - "timeout on wait_for_completion_timeout\n"); - return -ETIMEDOUT; - } - - return 0; -} - -static int nfcwilink_download_fw(struct nfcwilink *drv) -{ - unsigned char file_name[BTS_FILE_NAME_MAX_SIZE]; - const struct firmware *fw; - __u16 action_type, action_len; - __u8 *ptr; - int len, rc; - - set_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags); - - rc = nfcwilink_get_bts_file_name(drv, file_name); - if (rc) - goto exit; - - rc = request_firmware(&fw, file_name, &drv->pdev->dev); - if (rc) { - nfc_err(&drv->pdev->dev, "request_firmware failed %d\n", rc); - - /* if the file is not found, don't exit with failure */ - if (rc == -ENOENT) - rc = 0; - - goto exit; - } - - len = fw->size; - ptr = (__u8 *)fw->data; - - if ((len == 0) || (ptr == NULL)) { - dev_dbg(&drv->pdev->dev, - "request_firmware returned size %d\n", len); - goto release_fw; - } - - if (__le32_to_cpu(((struct bts_file_hdr *)ptr)->magic) != - BTS_FILE_HDR_MAGIC) { - nfc_err(&drv->pdev->dev, "wrong bts magic number\n"); - rc = -EINVAL; - goto release_fw; - } - - /* remove the BTS header */ - len -= sizeof(struct bts_file_hdr); - ptr += sizeof(struct bts_file_hdr); - - while (len > 0) { - action_type = - __le16_to_cpu(((struct bts_file_action *)ptr)->type); - action_len = - __le16_to_cpu(((struct bts_file_action *)ptr)->len); - - dev_dbg(&drv->pdev->dev, "bts_file_action type %d, len %d\n", - action_type, action_len); - - switch (action_type) { - case BTS_FILE_ACTION_TYPE_SEND_CMD: - rc = nfcwilink_send_bts_cmd(drv, - ((struct bts_file_action *)ptr)->data, - action_len); - if (rc) - goto release_fw; - break; - } - - /* advance to the next action */ - len -= (sizeof(struct bts_file_action) + action_len); - ptr += (sizeof(struct bts_file_action) + action_len); - } - -release_fw: - release_firmware(fw); - -exit: - clear_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags); - return rc; -} - -/* Called by ST when registration is complete */ -static void nfcwilink_register_complete(void *priv_data, int data) -{ - struct nfcwilink *drv = priv_data; - - /* store ST registration status */ - drv->st_register_cb_status = data; - - /* complete the wait in nfc_st_open() */ - complete(&drv->completed); -} - -/* Called by ST when receive data is available */ -static long nfcwilink_receive(void *priv_data, struct sk_buff *skb) -{ - struct nfcwilink *drv = priv_data; - int rc; - - if (!skb) - return -EFAULT; - - if (!drv) { - kfree_skb(skb); - return -EFAULT; - } - - dev_dbg(&drv->pdev->dev, "receive entry, len %d\n", skb->len); - - /* strip the ST header - (apart for the chnl byte, which is not received in the hdr) */ - skb_pull(skb, (NFCWILINK_HDR_LEN-1)); - - if (test_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags)) { - nfcwilink_fw_download_receive(drv, skb); - return 0; - } - - /* Forward skb to NCI core layer */ - rc = nci_recv_frame(drv->ndev, skb); - if (rc < 0) { - nfc_err(&drv->pdev->dev, "nci_recv_frame failed %d\n", rc); - return rc; - } - - return 0; -} - -/* protocol structure registered with ST */ -static struct st_proto_s nfcwilink_proto = { - .chnl_id = NFCWILINK_CHNL, - .max_frame_size = NFCWILINK_MAX_FRAME_SIZE, - .hdr_len = (NFCWILINK_HDR_LEN-1), /* not including chnl byte */ - .offset_len_in_hdr = NFCWILINK_OFFSET_LEN_IN_HDR, - .len_size = NFCWILINK_LEN_SIZE, - .reserve = 0, - .recv = nfcwilink_receive, - .reg_complete_cb = nfcwilink_register_complete, - .write = NULL, -}; - -static int nfcwilink_open(struct nci_dev *ndev) -{ - struct nfcwilink *drv = nci_get_drvdata(ndev); - unsigned long comp_ret; - int rc; - - if (test_and_set_bit(NFCWILINK_RUNNING, &drv->flags)) { - rc = -EBUSY; - goto exit; - } - - nfcwilink_proto.priv_data = drv; - - init_completion(&drv->completed); - drv->st_register_cb_status = -EINPROGRESS; - - rc = st_register(&nfcwilink_proto); - if (rc < 0) { - if (rc == -EINPROGRESS) { - comp_ret = wait_for_completion_timeout( - &drv->completed, - msecs_to_jiffies(NFCWILINK_REGISTER_TIMEOUT)); - - dev_dbg(&drv->pdev->dev, - "wait_for_completion_timeout returned %ld\n", - comp_ret); - - if (comp_ret == 0) { - /* timeout */ - rc = -ETIMEDOUT; - goto clear_exit; - } else if (drv->st_register_cb_status != 0) { - rc = drv->st_register_cb_status; - nfc_err(&drv->pdev->dev, - "st_register_cb failed %d\n", rc); - goto clear_exit; - } - } else { - nfc_err(&drv->pdev->dev, "st_register failed %d\n", rc); - goto clear_exit; - } - } - - /* st_register MUST fill the write callback */ - BUG_ON(nfcwilink_proto.write == NULL); - drv->st_write = nfcwilink_proto.write; - - if (nfcwilink_download_fw(drv)) { - nfc_err(&drv->pdev->dev, "nfcwilink_download_fw failed %d\n", - rc); - /* open should succeed, even if the FW download failed */ - } - - goto exit; - -clear_exit: - clear_bit(NFCWILINK_RUNNING, &drv->flags); - -exit: - return rc; -} - -static int nfcwilink_close(struct nci_dev *ndev) -{ - struct nfcwilink *drv = nci_get_drvdata(ndev); - int rc; - - if (!test_and_clear_bit(NFCWILINK_RUNNING, &drv->flags)) - return 0; - - rc = st_unregister(&nfcwilink_proto); - if (rc) - nfc_err(&drv->pdev->dev, "st_unregister failed %d\n", rc); - - drv->st_write = NULL; - - return rc; -} - -static int nfcwilink_send(struct nci_dev *ndev, struct sk_buff *skb) -{ - struct nfcwilink *drv = nci_get_drvdata(ndev); - struct nfcwilink_hdr hdr = {NFCWILINK_CHNL, NFCWILINK_OPCODE, 0x0000}; - long len; - - dev_dbg(&drv->pdev->dev, "send entry, len %d\n", skb->len); - - if (!test_bit(NFCWILINK_RUNNING, &drv->flags)) { - kfree_skb(skb); - return -EINVAL; - } - - /* add the ST hdr to the start of the buffer */ - hdr.len = cpu_to_le16(skb->len); - memcpy(skb_push(skb, NFCWILINK_HDR_LEN), &hdr, NFCWILINK_HDR_LEN); - - /* Insert skb to shared transport layer's transmit queue. - * Freeing skb memory is taken care in shared transport layer, - * so don't free skb memory here. - */ - len = drv->st_write(skb); - if (len < 0) { - kfree_skb(skb); - nfc_err(&drv->pdev->dev, "st_write failed %ld\n", len); - return -EFAULT; - } - - return 0; -} - -static struct nci_ops nfcwilink_ops = { - .open = nfcwilink_open, - .close = nfcwilink_close, - .send = nfcwilink_send, -}; - -static int nfcwilink_probe(struct platform_device *pdev) -{ - struct nfcwilink *drv; - int rc; - __u32 protocols; - - drv = devm_kzalloc(&pdev->dev, sizeof(struct nfcwilink), GFP_KERNEL); - if (!drv) { - rc = -ENOMEM; - goto exit; - } - - drv->pdev = pdev; - - protocols = NFC_PROTO_JEWEL_MASK - | NFC_PROTO_MIFARE_MASK | NFC_PROTO_FELICA_MASK - | NFC_PROTO_ISO14443_MASK - | NFC_PROTO_ISO14443_B_MASK - | NFC_PROTO_NFC_DEP_MASK; - - drv->ndev = nci_allocate_device(&nfcwilink_ops, - protocols, - NFCWILINK_HDR_LEN, - 0); - if (!drv->ndev) { - nfc_err(&pdev->dev, "nci_allocate_device failed\n"); - rc = -ENOMEM; - goto exit; - } - - nci_set_parent_dev(drv->ndev, &pdev->dev); - nci_set_drvdata(drv->ndev, drv); - - rc = nci_register_device(drv->ndev); - if (rc < 0) { - nfc_err(&pdev->dev, "nci_register_device failed %d\n", rc); - goto free_dev_exit; - } - - dev_set_drvdata(&pdev->dev, drv); - - goto exit; - -free_dev_exit: - nci_free_device(drv->ndev); - -exit: - return rc; -} - -static int nfcwilink_remove(struct platform_device *pdev) -{ - struct nfcwilink *drv = dev_get_drvdata(&pdev->dev); - struct nci_dev *ndev; - - if (!drv) - return -EFAULT; - - ndev = drv->ndev; - - nci_unregister_device(ndev); - nci_free_device(ndev); - - return 0; -} - -static struct platform_driver nfcwilink_driver = { - .probe = nfcwilink_probe, - .remove = nfcwilink_remove, - .driver = { - .name = "nfcwilink", - }, -}; - -module_platform_driver(nfcwilink_driver); - -/* ------ Module Info ------ */ - -MODULE_AUTHOR("Ilan Elias "); -MODULE_DESCRIPTION("NFC Driver for TI Shared Transport"); -MODULE_LICENSE("GPL"); -- cgit From d689530be68054ae2f927d539b69169d1f25fad0 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 24 Nov 2016 21:58:34 +0800 Subject: NFC: nfcmrvl: drop duplicate header gpio.h Drop duplicate header gpio.h from nfcmrvl/spi.c. Signed-off-by: Geliang Tang Signed-off-by: Samuel Ortiz --- drivers/nfc/nfcmrvl/spi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/nfc/nfcmrvl/spi.c b/drivers/nfc/nfcmrvl/spi.c index a7faa0bcc01e..e2881b15ce6c 100644 --- a/drivers/nfc/nfcmrvl/spi.c +++ b/drivers/nfc/nfcmrvl/spi.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "nfcmrvl.h" #define SPI_WAIT_HANDSHAKE 1 -- cgit From d916d923724d59cde99ee588f15eec59dd863bbd Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 26 Oct 2016 11:00:12 +0200 Subject: NFC: nfcmrvl: Include unaligned.h instead of access_ok.h Including linux/unaligned/access_ok.h causes the allmodconfig build on ia64 (and maybe others) to fail with the following warnings: include/linux/unaligned/access_ok.h:7:19: error: redefinition of 'get_unaligned_le16' include/linux/unaligned/access_ok.h:12:19: error: redefinition of 'get_unaligned_le32' include/linux/unaligned/access_ok.h:17:19: error: redefinition of 'get_unaligned_le64' include/linux/unaligned/access_ok.h:22:19: error: redefinition of 'get_unaligned_be16' include/linux/unaligned/access_ok.h:27:19: error: redefinition of 'get_unaligned_be32' include/linux/unaligned/access_ok.h:32:19: error: redefinition of 'get_unaligned_be64' include/linux/unaligned/access_ok.h:37:20: error: redefinition of 'put_unaligned_le16' include/linux/unaligned/access_ok.h:42:20: error: redefinition of 'put_unaligned_le32' include/linux/unaligned/access_ok.h:42:20: error: redefinition of 'put_unaligned_le64' include/linux/unaligned/access_ok.h:42:20: error: redefinition of 'put_unaligned_be16' include/linux/unaligned/access_ok.h:42:20: error: redefinition of 'put_unaligned_be32' include/linux/unaligned/access_ok.h:42:20: error: redefinition of 'put_unaligned_be64' Fix these by including asm/unaligned.h instead and leave it up to the architecture to decide how to implement unaligned accesses. Fixes: 3194c6870158 ("NFC: nfcmrvl: add firmware download support") Reported-by: kbuild test robot Link: https://lkml.org/lkml/2016/10/22/247 Cc: Vincent Cuissard Signed-off-by: Tobias Klauser Signed-off-by: Samuel Ortiz --- drivers/nfc/nfcmrvl/fw_dnld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nfc/nfcmrvl/fw_dnld.c b/drivers/nfc/nfcmrvl/fw_dnld.c index f8dcdf4b24f6..441c1b0ec7b5 100644 --- a/drivers/nfc/nfcmrvl/fw_dnld.c +++ b/drivers/nfc/nfcmrvl/fw_dnld.c @@ -17,7 +17,7 @@ */ #include -#include +#include #include #include #include -- cgit From 2eee74b7e2a496dea49847c36fd09320505f45b7 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 1 Aug 2015 06:59:29 -0700 Subject: NFC: nxp-nci: Include unaligned.h instead of access_ok.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Directly including access_ok.h can result in the following compile errors if an architecture such as ia64 does not support direct unaligned accesses. include/linux/unaligned/access_ok.h:7:19: error: redefinition of 'get_unaligned_le16' include/linux/unaligned/le_struct.h:6:19: note: previous definition of 'get_unaligned_le16' was here include/linux/unaligned/access_ok.h:12:19: error: redefinition of 'get_unaligned_le32' include/linux/unaligned/le_struct.h:11:19: note: previous definition of 'get_unaligned_le32' was here Include asm/unaligned.h instead and let the architecture decide which access functions to use. Cc: Clément Perrochaud Cc: Samuel Ortiz Signed-off-by: Guenter Roeck Signed-off-by: Samuel Ortiz --- drivers/nfc/nxp-nci/firmware.c | 2 +- drivers/nfc/nxp-nci/i2c.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/nfc/nxp-nci/firmware.c b/drivers/nfc/nxp-nci/firmware.c index 5291797324ba..553011f58339 100644 --- a/drivers/nfc/nxp-nci/firmware.c +++ b/drivers/nfc/nxp-nci/firmware.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include "nxp-nci.h" diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c index 36099e557730..06a157c63416 100644 --- a/drivers/nfc/nxp-nci/i2c.c +++ b/drivers/nfc/nxp-nci/i2c.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include -- cgit From f92cb58318745d9b59a30ff1e37d4fb298d4b75f Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Thu, 15 Dec 2016 15:22:44 +0100 Subject: nfc: nxp-nci: Remove unneeded linux/miscdevice.h include drivers/nfc/nxp-nci/i2c.c does not use any miscdevice, so this patch remove this unnecessary inclusion. Signed-off-by: Corentin Labbe Signed-off-by: Samuel Ortiz --- drivers/nfc/nxp-nci/i2c.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c index 06a157c63416..ae69d2f73700 100644 --- a/drivers/nfc/nxp-nci/i2c.c +++ b/drivers/nfc/nxp-nci/i2c.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include -- cgit From 17a0180be18050a96466671ed18430ad20d8346f Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Thu, 15 Dec 2016 15:22:45 +0100 Subject: nfc: pn544: Remove unneeded linux/miscdevice.h include drivers/nfc/pn544/i2c.c does not use any miscdevice, so this patch remove this unnecessary inclusion. Signed-off-by: Corentin Labbe Signed-off-by: Samuel Ortiz --- drivers/nfc/pn544/i2c.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c index f837c39a8017..7030a47fe379 100644 --- a/drivers/nfc/pn544/i2c.c +++ b/drivers/nfc/pn544/i2c.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include -- cgit From 52fdede5c9b96de355ab5e45e35503b9da6b86f6 Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Thu, 15 Dec 2016 15:22:46 +0100 Subject: nfc: st21nfca: Remove unneeded linux/miscdevice.h include drivers/nfc/st21nfca/i2c.c does not use any miscdevice, so this patch remove this unnecessary inclusion. Signed-off-by: Corentin Labbe Signed-off-by: Samuel Ortiz --- drivers/nfc/st21nfca/i2c.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c index 5a82f553906c..d16f58ac09bc 100644 --- a/drivers/nfc/st21nfca/i2c.c +++ b/drivers/nfc/st21nfca/i2c.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include -- cgit From ca42fb9e52d155547e6cf18cf26bce3e1a6af4ea Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 8 Mar 2017 08:22:37 +0300 Subject: NFC: nfcmrvl: double free on error path The nci_spi_send() function calls kfree_skb(skb) on both error and success so this extra kfree_skb() is a double free. Fixes: caf6e49bf6d0 ("NFC: nfcmrvl: add spi driver") Signed-off-by: Dan Carpenter Signed-off-by: Samuel Ortiz --- drivers/nfc/nfcmrvl/spi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/nfc/nfcmrvl/spi.c b/drivers/nfc/nfcmrvl/spi.c index e2881b15ce6c..8e0ddb434770 100644 --- a/drivers/nfc/nfcmrvl/spi.c +++ b/drivers/nfc/nfcmrvl/spi.c @@ -95,10 +95,9 @@ static int nfcmrvl_spi_nci_send(struct nfcmrvl_private *priv, /* Send the SPI packet */ err = nci_spi_send(drv_data->nci_spi, &drv_data->handshake_completion, skb); - if (err != 0) { + if (err) nfc_err(priv->dev, "spi_send failed %d", err); - kfree_skb(skb); - } + return err; } -- cgit From 8f79ded95934154d4454b6e422a18a3fbcd7a268 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 19 Feb 2017 10:58:47 +0100 Subject: NFC: st21nfca: Fix potential memory leak If all bits of 'dev_mask' are already set, there is a memory leak because 'info' should be freed before returning. While fixing it, 'return -ENOMEM' directly if the first kzalloc fails. This makes the code more readable. Signed-off-by: Christophe JAILLET Signed-off-by: Samuel Ortiz --- drivers/nfc/st21nfca/core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/nfc/st21nfca/core.c b/drivers/nfc/st21nfca/core.c index dacb9166081b..50be3b788f1c 100644 --- a/drivers/nfc/st21nfca/core.c +++ b/drivers/nfc/st21nfca/core.c @@ -959,10 +959,8 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, unsigned long quirks = 0; info = kzalloc(sizeof(struct st21nfca_hci_info), GFP_KERNEL); - if (!info) { - r = -ENOMEM; - goto err_alloc_hdev; - } + if (!info) + return -ENOMEM; info->phy_ops = phy_ops; info->phy_id = phy_id; @@ -978,8 +976,10 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, * persistent info to discriminate 2 identical chips */ dev_num = find_first_zero_bit(dev_mask, ST21NFCA_NUM_DEVICES); - if (dev_num >= ST21NFCA_NUM_DEVICES) - return -ENODEV; + if (dev_num >= ST21NFCA_NUM_DEVICES) { + r = -ENODEV; + goto err_alloc_hdev; + } set_bit(dev_num, dev_mask); -- cgit From 96bd0b5e550f26e8472c624d1aabe7448d0a7c27 Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Sun, 22 Jan 2017 13:28:39 +0100 Subject: nfc: nxp-nci: use msleep for long delays ulseep_range() uses hrtimers and provides no advantage over msleep() for larger delays. For this large delay msleep() is preferable. Fixes: commit 6be88670fc59 ("NFC: nxp-nci_i2c: Add I2C support to NXP NCI driver") Link: http://lkml.org/lkml/2017/1/11/377 Signed-off-by: Nicholas Mc Guire Signed-off-by: Samuel Ortiz --- drivers/nfc/nxp-nci/i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c index ae69d2f73700..c6a04a950225 100644 --- a/drivers/nfc/nxp-nci/i2c.c +++ b/drivers/nfc/nxp-nci/i2c.c @@ -85,7 +85,7 @@ static int nxp_nci_i2c_write(void *phy_id, struct sk_buff *skb) r = i2c_master_send(client, skb->data, skb->len); if (r < 0) { /* Retry, chip was in standby */ - usleep_range(110000, 120000); + msleep(110); r = i2c_master_send(client, skb->data, skb->len); } -- cgit From ce69b95ca4e459f54b5afad717d2129d3ba1ff6e Mon Sep 17 00:00:00 2001 From: Guan Ben Date: Tue, 7 Feb 2017 06:22:04 +0100 Subject: NFC: Make EN2 pin optional in the TRF7970A driver Make the EN2 pin optional. This is useful for boards, which have this pin fix wired, for example to ground. Acked-by: Rob Herring Signed-off-by: Guan Ben Signed-off-by: Mark Jonas Signed-off-by: Heiko Schocher Signed-off-by: Samuel Ortiz --- .../devicetree/bindings/net/nfc/trf7970a.txt | 4 ++-- drivers/nfc/trf7970a.c | 26 ++++++++++++---------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt index 32b35a07abe4..5889a3d133b2 100644 --- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt +++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt @@ -5,8 +5,8 @@ Required properties: - spi-max-frequency: Maximum SPI frequency (<= 2000000). - interrupt-parent: phandle of parent interrupt handler. - interrupts: A single interrupt specifier. -- ti,enable-gpios: Two GPIO entries used for 'EN' and 'EN2' pins on the - TRF7970A. +- ti,enable-gpios: One or two GPIO entries used for 'EN' and 'EN2' pins on the + TRF7970A. EN2 is optional. - vin-supply: Regulator for supply voltage to VIN pin Optional SoC Specific Properties: diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c index 26c9dbbccb0c..75079fb16f22 100644 --- a/drivers/nfc/trf7970a.c +++ b/drivers/nfc/trf7970a.c @@ -1885,8 +1885,10 @@ static int trf7970a_power_up(struct trf7970a *trf) usleep_range(5000, 6000); if (!(trf->quirks & TRF7970A_QUIRK_EN2_MUST_STAY_LOW)) { - gpio_set_value(trf->en2_gpio, 1); - usleep_range(1000, 2000); + if (gpio_is_valid(trf->en2_gpio)) { + gpio_set_value(trf->en2_gpio, 1); + usleep_range(1000, 2000); + } } gpio_set_value(trf->en_gpio, 1); @@ -1914,7 +1916,8 @@ static int trf7970a_power_down(struct trf7970a *trf) } gpio_set_value(trf->en_gpio, 0); - gpio_set_value(trf->en2_gpio, 0); + if (gpio_is_valid(trf->en2_gpio)) + gpio_set_value(trf->en2_gpio, 0); ret = regulator_disable(trf->regulator); if (ret) @@ -2032,15 +2035,14 @@ static int trf7970a_probe(struct spi_device *spi) trf->en2_gpio = of_get_named_gpio(np, "ti,enable-gpios", 1); if (!gpio_is_valid(trf->en2_gpio)) { - dev_err(trf->dev, "No EN2 GPIO property\n"); - return trf->en2_gpio; - } - - ret = devm_gpio_request_one(trf->dev, trf->en2_gpio, - GPIOF_DIR_OUT | GPIOF_INIT_LOW, "trf7970a EN2"); - if (ret) { - dev_err(trf->dev, "Can't request EN2 GPIO: %d\n", ret); - return ret; + dev_info(trf->dev, "No EN2 GPIO property\n"); + } else { + ret = devm_gpio_request_one(trf->dev, trf->en2_gpio, + GPIOF_DIR_OUT | GPIOF_INIT_LOW, "trf7970a EN2"); + if (ret) { + dev_err(trf->dev, "Can't request EN2 GPIO: %d\n", ret); + return ret; + } } if (of_property_read_bool(np, "en2-rf-quirk")) -- cgit From b6355fb3f5f40bbce165847d277e64896cab8f95 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 20 Dec 2016 21:09:04 +0000 Subject: nfc: fdp: fix NULL pointer dereference We are checking phy after dereferencing it. We can print the debug information after checking it. If phy is NULL then we will get a good stack trace to tell us that we are in this irq handler. Signed-off-by: Sudip Mukherjee Signed-off-by: Samuel Ortiz --- drivers/nfc/fdp/i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/nfc/fdp/i2c.c b/drivers/nfc/fdp/i2c.c index 5e797d5c38ed..712936f5d2d6 100644 --- a/drivers/nfc/fdp/i2c.c +++ b/drivers/nfc/fdp/i2c.c @@ -210,14 +210,14 @@ static irqreturn_t fdp_nci_i2c_irq_thread_fn(int irq, void *phy_id) struct sk_buff *skb; int r; - client = phy->i2c_dev; - dev_dbg(&client->dev, "%s\n", __func__); - if (!phy || irq != phy->i2c_dev->irq) { WARN_ON_ONCE(1); return IRQ_NONE; } + client = phy->i2c_dev; + dev_dbg(&client->dev, "%s\n", __func__); + r = fdp_nci_i2c_read(phy, &skb); if (r == -EREMOTEIO) -- cgit From 068a496c4525c638ffab56449d905b88ef97fe32 Mon Sep 17 00:00:00 2001 From: Andrey Rusalin Date: Wed, 28 Dec 2016 20:10:57 +0300 Subject: NFC: pn533: change order of free_irq and dev unregistration Change order of free_irq and dev unregistration. It fixes situation when device already unregistered and an interrupt happens and nobody can handle it. Signed-off-by: Andrey Rusalin Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533/i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/nfc/pn533/i2c.c b/drivers/nfc/pn533/i2c.c index 1dc89248e58e..11d78b43cf76 100644 --- a/drivers/nfc/pn533/i2c.c +++ b/drivers/nfc/pn533/i2c.c @@ -242,10 +242,10 @@ static int pn533_i2c_remove(struct i2c_client *client) dev_dbg(&client->dev, "%s\n", __func__); - pn533_unregister_device(phy->priv); - free_irq(client->irq, phy); + pn533_unregister_device(phy->priv); + return 0; } -- cgit From 5dd9c1bd61a7b684e54897a3a2546124c4077eda Mon Sep 17 00:00:00 2001 From: Andrey Rusalin Date: Wed, 28 Dec 2016 20:10:58 +0300 Subject: NFC: pn533: improve cmd queue handling Make sure cmd is set before a frame is passed to the transport layer for sending. In addition pn533_send_async_complete checks if cmd is set before accessing its members. Signed-off-by: Michael Thalmeier Rework a little bit changes in pn532_send_async_complete. Signed-off-by: Andrey Rusalin Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533/pn533.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index a966c6a85ea8..712aa67e1770 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -383,14 +383,18 @@ static void pn533_build_cmd_frame(struct pn533 *dev, u8 cmd_code, static int pn533_send_async_complete(struct pn533 *dev) { struct pn533_cmd *cmd = dev->cmd; - int status = cmd->status; + struct sk_buff *resp; + int status, rc = 0; - struct sk_buff *req = cmd->req; - struct sk_buff *resp = cmd->resp; + if (!cmd) { + dev_dbg(dev->dev, "%s: cmd not set\n", __func__); + goto done; + } - int rc; + dev_kfree_skb(cmd->req); - dev_kfree_skb(req); + status = cmd->status; + resp = cmd->resp; if (status < 0) { rc = cmd->complete_cb(dev, cmd->complete_cb_context, @@ -399,8 +403,14 @@ static int pn533_send_async_complete(struct pn533 *dev) goto done; } - skb_pull(resp, dev->ops->rx_header_len); - skb_trim(resp, resp->len - dev->ops->rx_tail_len); + /* when no response is set we got interrupted */ + if (!resp) + resp = ERR_PTR(-EINTR); + + if (!IS_ERR(resp)) { + skb_pull(resp, dev->ops->rx_header_len); + skb_trim(resp, resp->len - dev->ops->rx_tail_len); + } rc = cmd->complete_cb(dev, cmd->complete_cb_context, resp); @@ -434,12 +444,14 @@ static int __pn533_send_async(struct pn533 *dev, u8 cmd_code, mutex_lock(&dev->cmd_lock); if (!dev->cmd_pending) { + dev->cmd = cmd; rc = dev->phy_ops->send_frame(dev, req); - if (rc) + if (rc) { + dev->cmd = NULL; goto error; + } dev->cmd_pending = 1; - dev->cmd = cmd; goto unlock; } @@ -511,11 +523,12 @@ static int pn533_send_cmd_direct_async(struct pn533 *dev, u8 cmd_code, pn533_build_cmd_frame(dev, cmd_code, req); + dev->cmd = cmd; rc = dev->phy_ops->send_frame(dev, req); - if (rc < 0) + if (rc < 0) { + dev->cmd = NULL; kfree(cmd); - else - dev->cmd = cmd; + } return rc; } @@ -550,14 +563,15 @@ static void pn533_wq_cmd(struct work_struct *work) mutex_unlock(&dev->cmd_lock); + dev->cmd = cmd; rc = dev->phy_ops->send_frame(dev, cmd->req); if (rc < 0) { + dev->cmd = NULL; dev_kfree_skb(cmd->req); kfree(cmd); return; } - dev->cmd = cmd; } struct pn533_sync_cmd_response { -- cgit From 32ecc75ded72e0425713a7ffe2050fef6e54e564 Mon Sep 17 00:00:00 2001 From: Andrey Rusalin Date: Wed, 28 Dec 2016 20:10:59 +0300 Subject: NFC: pn533: change order operations in dev registation Sometimes during probing and registration of pn533_i2c NULL pointer dereference happens. Reproduced in cycle of inserting and removing pn533_i2c and pn533 modules. Backtrace: [<8004205c>] (__queue_work) from [<80042324>] (queue_work_on+0x50/0x5c) r10:acdc7c80 r9:8006b330 r8:ac0dfb40 r7:ac50c600 r6:00000004 r5:acbbee40 r4:600f0113 [<800422d4>] (queue_work_on) from [<7f7d5b6c>] (pn533_recv_frame+0x158/0x1fc [pn533]) r7:ffffff87 r6:00000000 r5:acbbee40 r4:acbbee00 [<7f7d5a14>] (pn533_recv_frame [pn533]) from [<7f7df4b8>] (pn533_i2c_irq_thread_fn+0x184/0x) r6:acb2a000 r5:00000000 r4:acdc7b90 [<7f7df334>] (pn533_i2c_irq_thread_fn [pn533_i2c]) from [<8006b354>] (irq_thread_fn+0x24/0x) r7:00000000 r6:accde000 r5:ac0dfb40 r4:acdc7c80 ... Seems there is some race condition due registration of irq handler until all data stuctures that could be needed are ready. So I re-ordered some ops. After this, problem has gone. Changes in USB part was not tested, but it should not break anything. Signed-off-by: Andrey Rusalin Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533/i2c.c | 28 ++++++++++++++++++---------- drivers/nfc/pn533/pn533.c | 42 +++++++++++++++++++++++++----------------- drivers/nfc/pn533/pn533.h | 1 + drivers/nfc/pn533/usb.c | 4 ++++ 4 files changed, 48 insertions(+), 27 deletions(-) diff --git a/drivers/nfc/pn533/i2c.c b/drivers/nfc/pn533/i2c.c index 11d78b43cf76..2c2fb9cfe10a 100644 --- a/drivers/nfc/pn533/i2c.c +++ b/drivers/nfc/pn533/i2c.c @@ -206,14 +206,6 @@ static int pn533_i2c_probe(struct i2c_client *client, phy->i2c_dev = client; i2c_set_clientdata(client, phy); - r = request_threaded_irq(client->irq, NULL, pn533_i2c_irq_thread_fn, - IRQF_TRIGGER_FALLING | - IRQF_SHARED | IRQF_ONESHOT, - PN533_I2C_DRIVER_NAME, phy); - - if (r < 0) - nfc_err(&client->dev, "Unable to register IRQ handler\n"); - priv = pn533_register_device(PN533_DEVICE_PN532, PN533_NO_TYPE_B_PROTOCOLS, PN533_PROTO_REQ_ACK_RESP, @@ -223,16 +215,32 @@ static int pn533_i2c_probe(struct i2c_client *client, if (IS_ERR(priv)) { r = PTR_ERR(priv); - goto err_register; + return r; } phy->priv = priv; + r = request_threaded_irq(client->irq, NULL, pn533_i2c_irq_thread_fn, + IRQF_TRIGGER_FALLING | + IRQF_SHARED | IRQF_ONESHOT, + PN533_I2C_DRIVER_NAME, phy); + if (r < 0) { + nfc_err(&client->dev, "Unable to register IRQ handler\n"); + goto irq_rqst_err; + } + + r = pn533_finalize_setup(priv); + if (r) + goto fn_setup_err; + return 0; -err_register: +fn_setup_err: free_irq(client->irq, phy); +irq_rqst_err: + pn533_unregister_device(phy->priv); + return r; } diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index 712aa67e1770..65bbaa5fcdda 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -2570,6 +2570,31 @@ static int pn533_setup(struct pn533 *dev) return 0; } +int pn533_finalize_setup(struct pn533 *dev) +{ + + struct pn533_fw_version fw_ver; + int rc; + + memset(&fw_ver, 0, sizeof(fw_ver)); + + rc = pn533_get_firmware_version(dev, &fw_ver); + if (rc) { + nfc_err(dev->dev, "Unable to get FW version\n"); + return rc; + } + + nfc_info(dev->dev, "NXP PN5%02X firmware ver %d.%d now attached\n", + fw_ver.ic, fw_ver.ver, fw_ver.rev); + + rc = pn533_setup(dev); + if (rc) + return rc; + + return 0; +} +EXPORT_SYMBOL_GPL(pn533_finalize_setup); + struct pn533 *pn533_register_device(u32 device_type, u32 protocols, enum pn533_protocol_type protocol_type, @@ -2579,7 +2604,6 @@ struct pn533 *pn533_register_device(u32 device_type, struct device *dev, struct device *parent) { - struct pn533_fw_version fw_ver; struct pn533 *priv; int rc = -ENOMEM; @@ -2622,15 +2646,6 @@ struct pn533 *pn533_register_device(u32 device_type, INIT_LIST_HEAD(&priv->cmd_queue); - memset(&fw_ver, 0, sizeof(fw_ver)); - rc = pn533_get_firmware_version(priv, &fw_ver); - if (rc < 0) - goto destroy_wq; - - nfc_info(dev, "NXP PN5%02X firmware ver %d.%d now attached\n", - fw_ver.ic, fw_ver.ver, fw_ver.rev); - - priv->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols, priv->ops->tx_header_len + PN533_CMD_DATAEXCH_HEAD_LEN, @@ -2647,15 +2662,8 @@ struct pn533 *pn533_register_device(u32 device_type, if (rc) goto free_nfc_dev; - rc = pn533_setup(priv); - if (rc) - goto unregister_nfc_dev; - return priv; -unregister_nfc_dev: - nfc_unregister_device(priv->nfc_dev); - free_nfc_dev: nfc_free_device(priv->nfc_dev); diff --git a/drivers/nfc/pn533/pn533.h b/drivers/nfc/pn533/pn533.h index 553c7d171fd1..88d569666c51 100644 --- a/drivers/nfc/pn533/pn533.h +++ b/drivers/nfc/pn533/pn533.h @@ -231,6 +231,7 @@ struct pn533 *pn533_register_device(u32 device_type, struct device *dev, struct device *parent); +int pn533_finalize_setup(struct pn533 *dev); void pn533_unregister_device(struct pn533 *priv); void pn533_recv_frame(struct pn533 *dev, struct sk_buff *skb, int status); diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c index 33ed78be2750..000159ea9c5f 100644 --- a/drivers/nfc/pn533/usb.c +++ b/drivers/nfc/pn533/usb.c @@ -543,6 +543,10 @@ static int pn533_usb_probe(struct usb_interface *interface, phy->priv = priv; + rc = pn533_finalize_setup(priv); + if (rc) + goto error; + usb_set_intfdata(interface, phy); return 0; -- cgit From 4334d8fc638aea4f36fc69042f699e44fed98b16 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Sun, 2 Apr 2017 01:07:53 +0200 Subject: MAINTAINERS: Remove Lauro and Aloisio from the NFC maintainers list They are no longer active and their email addresses bounce. Signed-off-by: Samuel Ortiz --- MAINTAINERS | 2 -- 1 file changed, 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index a1ce88e91444..a8eaa0a8e522 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8853,8 +8853,6 @@ S: Supported F: drivers/net/ethernet/qlogic/netxen/ NFC SUBSYSTEM -M: Lauro Ramos Venancio -M: Aloisio Almeida Jr M: Samuel Ortiz L: linux-wireless@vger.kernel.org L: linux-nfc@lists.01.org (subscribers-only) -- cgit From e7f6ccaab127147c52ac4b624c54ad0059bd08e9 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 28 Mar 2017 12:36:35 +0300 Subject: NFC: pn544: Get rid of platform data Legacy platform data must go away. We are on the safe side here since there are no users of it in the kernel. If anyone by any odd reason needs it the GPIO lookup tables and built-in device properties at your service. Signed-off-by: Andy Shevchenko Signed-off-by: Samuel Ortiz --- drivers/nfc/pn544/i2c.c | 43 ++++++------------------------------- include/linux/platform_data/pn544.h | 43 ------------------------------------- 2 files changed, 6 insertions(+), 80 deletions(-) delete mode 100644 include/linux/platform_data/pn544.h diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c index 7030a47fe379..4afc92a54444 100644 --- a/drivers/nfc/pn544/i2c.c +++ b/drivers/nfc/pn544/i2c.c @@ -30,7 +30,7 @@ #include #include #include -#include + #include #include @@ -972,7 +972,6 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct pn544_i2c_phy *phy; - struct pn544_nfc_platform_data *pdata; int r = 0; dev_dbg(&client->dev, "%s\n", __func__); @@ -994,32 +993,13 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, phy->i2c_dev = client; i2c_set_clientdata(client, phy); - pdata = client->dev.platform_data; - /* No platform data, using device tree. */ - if (!pdata && client->dev.of_node) { + if (client->dev.of_node) { r = pn544_hci_i2c_of_request_resources(client); if (r) { nfc_err(&client->dev, "No DT data\n"); return r; } - /* Using platform data. */ - } else if (pdata) { - - if (pdata->request_resources == NULL) { - nfc_err(&client->dev, "request_resources() missing\n"); - return -EINVAL; - } - - r = pdata->request_resources(client); - if (r) { - nfc_err(&client->dev, - "Cannot get platform resources\n"); - return r; - } - - phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE); - phy->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET); /* Using ACPI */ } else if (ACPI_HANDLE(&client->dev)) { r = pn544_hci_i2c_acpi_request_resources(client); @@ -1056,12 +1036,8 @@ err_hci: free_irq(client->irq, phy); err_rti: - if (!pdata) { - gpio_free(phy->gpio_en); - gpio_free(phy->gpio_fw); - } else if (pdata->free_resources) { - pdata->free_resources(); - } + gpio_free(phy->gpio_en); + gpio_free(phy->gpio_fw); return r; } @@ -1069,7 +1045,6 @@ err_rti: static int pn544_hci_i2c_remove(struct i2c_client *client) { struct pn544_i2c_phy *phy = i2c_get_clientdata(client); - struct pn544_nfc_platform_data *pdata = client->dev.platform_data; dev_dbg(&client->dev, "%s\n", __func__); @@ -1084,14 +1059,8 @@ static int pn544_hci_i2c_remove(struct i2c_client *client) free_irq(client->irq, phy); - /* No platform data, GPIOs have been requested by this driver */ - if (!pdata) { - gpio_free(phy->gpio_en); - gpio_free(phy->gpio_fw); - /* Using platform data */ - } else if (pdata->free_resources) { - pdata->free_resources(); - } + gpio_free(phy->gpio_en); + gpio_free(phy->gpio_fw); return 0; } diff --git a/include/linux/platform_data/pn544.h b/include/linux/platform_data/pn544.h deleted file mode 100644 index 5ce1ab983f44..000000000000 --- a/include/linux/platform_data/pn544.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Driver include for the PN544 NFC chip. - * - * Copyright (C) Nokia Corporation - * - * Author: Jari Vanhala - * Contact: Matti Aaltoenn - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#ifndef _PN544_H_ -#define _PN544_H_ - -#include - -enum { - NFC_GPIO_ENABLE, - NFC_GPIO_FW_RESET, - NFC_GPIO_IRQ -}; - -/* board config */ -struct pn544_nfc_platform_data { - int (*request_resources) (struct i2c_client *client); - void (*free_resources) (void); - void (*enable) (int fw); - int (*test) (void); - void (*disable) (void); - int (*get_gpio)(int type); -}; - -#endif /* _PN544_H_ */ -- cgit From e2c518c6c9987bf832bb1475de38911da96bd3db Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 28 Mar 2017 12:36:36 +0300 Subject: NFC: pn544: Convert to use GPIO descriptor Since we got rid of platform data, the driver may use GPIO descriptor directly. This change fixes a potential issue of double freeing GPIOs in ACPI case by converting to devm_gpiod_get(). Signed-off-by: Andy Shevchenko Signed-off-by: Samuel Ortiz --- drivers/nfc/pn544/i2c.c | 126 +++++++++++++----------------------------------- 1 file changed, 33 insertions(+), 93 deletions(-) diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c index 4afc92a54444..23485304ce91 100644 --- a/drivers/nfc/pn544/i2c.c +++ b/drivers/nfc/pn544/i2c.c @@ -21,9 +21,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -164,8 +161,9 @@ struct pn544_i2c_phy { struct i2c_client *i2c_dev; struct nfc_hci_dev *hdev; - unsigned int gpio_en; - unsigned int gpio_fw; + struct gpio_desc *gpiod_en; + struct gpio_desc *gpiod_fw; + unsigned int en_polarity; u8 hw_variant; @@ -207,19 +205,18 @@ static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy) nfc_info(&phy->i2c_dev->dev, "Detecting nfc_en polarity\n"); /* Disable fw download */ - gpio_set_value_cansleep(phy->gpio_fw, 0); + gpiod_set_value_cansleep(phy->gpiod_fw, 0); for (polarity = 0; polarity < 2; polarity++) { phy->en_polarity = polarity; retry = 3; while (retry--) { /* power off */ - gpio_set_value_cansleep(phy->gpio_en, - !phy->en_polarity); + gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity); usleep_range(10000, 15000); /* power on */ - gpio_set_value_cansleep(phy->gpio_en, phy->en_polarity); + gpiod_set_value_cansleep(phy->gpiod_en, phy->en_polarity); usleep_range(10000, 15000); /* send reset */ @@ -238,14 +235,13 @@ static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy) "Could not detect nfc_en polarity, fallback to active high\n"); out: - gpio_set_value_cansleep(phy->gpio_en, !phy->en_polarity); + gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity); } static void pn544_hci_i2c_enable_mode(struct pn544_i2c_phy *phy, int run_mode) { - gpio_set_value_cansleep(phy->gpio_fw, - run_mode == PN544_FW_MODE ? 1 : 0); - gpio_set_value_cansleep(phy->gpio_en, phy->en_polarity); + gpiod_set_value_cansleep(phy->gpiod_fw, run_mode == PN544_FW_MODE ? 1 : 0); + gpiod_set_value_cansleep(phy->gpiod_en, phy->en_polarity); usleep_range(10000, 15000); phy->run_mode = run_mode; @@ -268,14 +264,14 @@ static void pn544_hci_i2c_disable(void *phy_id) { struct pn544_i2c_phy *phy = phy_id; - gpio_set_value_cansleep(phy->gpio_fw, 0); - gpio_set_value_cansleep(phy->gpio_en, !phy->en_polarity); + gpiod_set_value_cansleep(phy->gpiod_fw, 0); + gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity); usleep_range(10000, 15000); - gpio_set_value_cansleep(phy->gpio_en, phy->en_polarity); + gpiod_set_value_cansleep(phy->gpiod_en, phy->en_polarity); usleep_range(10000, 15000); - gpio_set_value_cansleep(phy->gpio_en, !phy->en_polarity); + gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity); usleep_range(10000, 15000); phy->powered = 0; @@ -876,96 +872,47 @@ exit_state_wait_secure_write_answer: static int pn544_hci_i2c_acpi_request_resources(struct i2c_client *client) { struct pn544_i2c_phy *phy = i2c_get_clientdata(client); - struct gpio_desc *gpiod_en, *gpiod_fw; struct device *dev = &client->dev; /* Get EN GPIO from ACPI */ - gpiod_en = devm_gpiod_get_index(dev, PN544_GPIO_NAME_EN, 1, - GPIOD_OUT_LOW); - if (IS_ERR(gpiod_en)) { + phy->gpiod_en = devm_gpiod_get_index(dev, PN544_GPIO_NAME_EN, 1, + GPIOD_OUT_LOW); + if (IS_ERR(phy->gpiod_en)) { nfc_err(dev, "Unable to get EN GPIO\n"); - return -ENODEV; + return PTR_ERR(phy->gpiod_en); } - phy->gpio_en = desc_to_gpio(gpiod_en); - /* Get FW GPIO from ACPI */ - gpiod_fw = devm_gpiod_get_index(dev, PN544_GPIO_NAME_FW, 2, - GPIOD_OUT_LOW); - if (IS_ERR(gpiod_fw)) { + phy->gpiod_fw = devm_gpiod_get_index(dev, PN544_GPIO_NAME_FW, 2, + GPIOD_OUT_LOW); + if (IS_ERR(phy->gpiod_fw)) { nfc_err(dev, "Unable to get FW GPIO\n"); - return -ENODEV; + return PTR_ERR(phy->gpiod_fw); } - phy->gpio_fw = desc_to_gpio(gpiod_fw); - return 0; } static int pn544_hci_i2c_of_request_resources(struct i2c_client *client) { struct pn544_i2c_phy *phy = i2c_get_clientdata(client); - struct device_node *pp; - int ret; - - pp = client->dev.of_node; - if (!pp) { - ret = -ENODEV; - goto err_dt; - } - - /* Obtention of EN GPIO from device tree */ - ret = of_get_named_gpio(pp, "enable-gpios", 0); - if (ret < 0) { - if (ret != -EPROBE_DEFER) - nfc_err(&client->dev, - "Failed to get EN gpio, error: %d\n", ret); - goto err_dt; - } - phy->gpio_en = ret; - - /* Configuration of EN GPIO */ - ret = gpio_request(phy->gpio_en, PN544_GPIO_NAME_EN); - if (ret) { - nfc_err(&client->dev, "Fail EN pin\n"); - goto err_dt; - } - ret = gpio_direction_output(phy->gpio_en, 0); - if (ret) { - nfc_err(&client->dev, "Fail EN pin direction\n"); - goto err_gpio_en; - } + struct device *dev = &client->dev; - /* Obtention of FW GPIO from device tree */ - ret = of_get_named_gpio(pp, "firmware-gpios", 0); - if (ret < 0) { - if (ret != -EPROBE_DEFER) - nfc_err(&client->dev, - "Failed to get FW gpio, error: %d\n", ret); - goto err_gpio_en; + /* Obtaining EN GPIO from device tree */ + phy->gpiod_en = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(phy->gpiod_en)) { + nfc_err(dev, "Failed to get EN gpio\n"); + return PTR_ERR(phy->gpiod_en); } - phy->gpio_fw = ret; - /* Configuration of FW GPIO */ - ret = gpio_request(phy->gpio_fw, PN544_GPIO_NAME_FW); - if (ret) { - nfc_err(&client->dev, "Fail FW pin\n"); - goto err_gpio_en; - } - ret = gpio_direction_output(phy->gpio_fw, 0); - if (ret) { - nfc_err(&client->dev, "Fail FW pin direction\n"); - goto err_gpio_fw; + /* Obtaining FW GPIO from device tree */ + phy->gpiod_fw = devm_gpiod_get(dev, "firmware", GPIOD_OUT_LOW); + if (IS_ERR(phy->gpiod_fw)) { + nfc_err(dev, "Failed to get FW gpio\n"); + return PTR_ERR(phy->gpiod_fw); } return 0; - -err_gpio_fw: - gpio_free(phy->gpio_fw); -err_gpio_en: - gpio_free(phy->gpio_en); -err_dt: - return ret; } static int pn544_hci_i2c_probe(struct i2c_client *client, @@ -1020,7 +967,7 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, PN544_HCI_I2C_DRIVER_NAME, phy); if (r < 0) { nfc_err(&client->dev, "Unable to register IRQ handler\n"); - goto err_rti; + return r; } r = pn544_hci_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME, @@ -1035,10 +982,6 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, err_hci: free_irq(client->irq, phy); -err_rti: - gpio_free(phy->gpio_en); - gpio_free(phy->gpio_fw); - return r; } @@ -1059,9 +1002,6 @@ static int pn544_hci_i2c_remove(struct i2c_client *client) free_irq(client->irq, phy); - gpio_free(phy->gpio_en); - gpio_free(phy->gpio_fw); - return 0; } -- cgit From 182d4e860845bbf388f5f60d9e651611f3dbd351 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 28 Mar 2017 12:36:37 +0300 Subject: NFC: pn544: Convert to use devm_request_threaded_irq() The error handling will be neat and short when using managed resources. Convert the driver to use devm_request_threaded_irq(). Signed-off-by: Andy Shevchenko Signed-off-by: Samuel Ortiz --- drivers/nfc/pn544/i2c.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c index 23485304ce91..327c33df5b22 100644 --- a/drivers/nfc/pn544/i2c.c +++ b/drivers/nfc/pn544/i2c.c @@ -962,9 +962,10 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, pn544_hci_i2c_platform_init(phy); - r = request_threaded_irq(client->irq, NULL, pn544_hci_i2c_irq_thread_fn, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, - PN544_HCI_I2C_DRIVER_NAME, phy); + r = devm_request_threaded_irq(&client->dev, client->irq, NULL, + pn544_hci_i2c_irq_thread_fn, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + PN544_HCI_I2C_DRIVER_NAME, phy); if (r < 0) { nfc_err(&client->dev, "Unable to register IRQ handler\n"); return r; @@ -975,14 +976,9 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, PN544_HCI_I2C_LLC_MAX_PAYLOAD, pn544_hci_i2c_fw_download, &phy->hdev); if (r < 0) - goto err_hci; + return r; return 0; - -err_hci: - free_irq(client->irq, phy); - - return r; } static int pn544_hci_i2c_remove(struct i2c_client *client) @@ -1000,8 +996,6 @@ static int pn544_hci_i2c_remove(struct i2c_client *client) if (phy->powered) pn544_hci_i2c_disable(phy); - free_irq(client->irq, phy); - return 0; } -- cgit From a4a0eb783b112e45563dcf020388dfa186961010 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 28 Mar 2017 12:36:38 +0300 Subject: NFC: pn544: Add GPIO ACPI mapping table In order to make GPIO ACPI library stricter prepare users of gpiod_get_index() to correctly behave when there no mapping is provided by firmware. Here we add explicit mapping between _CRS GpioIo() resources and their names used in the driver. Signed-off-by: Andy Shevchenko Signed-off-by: Samuel Ortiz --- drivers/nfc/pn544/i2c.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c index 327c33df5b22..6f2a9dff6b71 100644 --- a/drivers/nfc/pn544/i2c.c +++ b/drivers/nfc/pn544/i2c.c @@ -869,22 +869,34 @@ exit_state_wait_secure_write_answer: } } +static const struct acpi_gpio_params enable_gpios = { 1, 0, false }; +static const struct acpi_gpio_params firmware_gpios = { 2, 0, false }; + +static const struct acpi_gpio_mapping acpi_pn544_gpios[] = { + { "enable-gpios", &enable_gpios, 1 }, + { "firmware-gpios", &firmware_gpios, 1 }, + { }, +}; + static int pn544_hci_i2c_acpi_request_resources(struct i2c_client *client) { struct pn544_i2c_phy *phy = i2c_get_clientdata(client); struct device *dev = &client->dev; + int ret; + + ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), acpi_pn544_gpios); + if (ret) + return ret; /* Get EN GPIO from ACPI */ - phy->gpiod_en = devm_gpiod_get_index(dev, PN544_GPIO_NAME_EN, 1, - GPIOD_OUT_LOW); + phy->gpiod_en = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); if (IS_ERR(phy->gpiod_en)) { nfc_err(dev, "Unable to get EN GPIO\n"); return PTR_ERR(phy->gpiod_en); } /* Get FW GPIO from ACPI */ - phy->gpiod_fw = devm_gpiod_get_index(dev, PN544_GPIO_NAME_FW, 2, - GPIOD_OUT_LOW); + phy->gpiod_fw = devm_gpiod_get(dev, "firmware", GPIOD_OUT_LOW); if (IS_ERR(phy->gpiod_fw)) { nfc_err(dev, "Unable to get FW GPIO\n"); return PTR_ERR(phy->gpiod_fw); @@ -996,6 +1008,7 @@ static int pn544_hci_i2c_remove(struct i2c_client *client) if (phy->powered) pn544_hci_i2c_disable(phy); + acpi_dev_remove_driver_gpios(ACPI_COMPANION(&client->dev)); return 0; } -- cgit From 95129b6f0806d1ba6109dc1df4d9753ad3d4a94c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 28 Mar 2017 12:36:39 +0300 Subject: NFC: pn544: Get rid of code duplication in ->probe() Since OF and ACPI case almost the same get rid of code duplication by moving gpiod_get() calls directly to ->probe(). Signed-off-by: Andy Shevchenko Signed-off-by: Samuel Ortiz --- drivers/nfc/pn544/i2c.c | 84 ++++++++++--------------------------------------- 1 file changed, 17 insertions(+), 67 deletions(-) diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c index 6f2a9dff6b71..71ac0836c9f4 100644 --- a/drivers/nfc/pn544/i2c.c +++ b/drivers/nfc/pn544/i2c.c @@ -878,58 +878,10 @@ static const struct acpi_gpio_mapping acpi_pn544_gpios[] = { { }, }; -static int pn544_hci_i2c_acpi_request_resources(struct i2c_client *client) -{ - struct pn544_i2c_phy *phy = i2c_get_clientdata(client); - struct device *dev = &client->dev; - int ret; - - ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), acpi_pn544_gpios); - if (ret) - return ret; - - /* Get EN GPIO from ACPI */ - phy->gpiod_en = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); - if (IS_ERR(phy->gpiod_en)) { - nfc_err(dev, "Unable to get EN GPIO\n"); - return PTR_ERR(phy->gpiod_en); - } - - /* Get FW GPIO from ACPI */ - phy->gpiod_fw = devm_gpiod_get(dev, "firmware", GPIOD_OUT_LOW); - if (IS_ERR(phy->gpiod_fw)) { - nfc_err(dev, "Unable to get FW GPIO\n"); - return PTR_ERR(phy->gpiod_fw); - } - - return 0; -} - -static int pn544_hci_i2c_of_request_resources(struct i2c_client *client) -{ - struct pn544_i2c_phy *phy = i2c_get_clientdata(client); - struct device *dev = &client->dev; - - /* Obtaining EN GPIO from device tree */ - phy->gpiod_en = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); - if (IS_ERR(phy->gpiod_en)) { - nfc_err(dev, "Failed to get EN gpio\n"); - return PTR_ERR(phy->gpiod_en); - } - - /* Obtaining FW GPIO from device tree */ - phy->gpiod_fw = devm_gpiod_get(dev, "firmware", GPIOD_OUT_LOW); - if (IS_ERR(phy->gpiod_fw)) { - nfc_err(dev, "Failed to get FW gpio\n"); - return PTR_ERR(phy->gpiod_fw); - } - - return 0; -} - static int pn544_hci_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct device *dev = &client->dev; struct pn544_i2c_phy *phy; int r = 0; @@ -952,24 +904,22 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, phy->i2c_dev = client; i2c_set_clientdata(client, phy); - /* No platform data, using device tree. */ - if (client->dev.of_node) { - r = pn544_hci_i2c_of_request_resources(client); - if (r) { - nfc_err(&client->dev, "No DT data\n"); - return r; - } - /* Using ACPI */ - } else if (ACPI_HANDLE(&client->dev)) { - r = pn544_hci_i2c_acpi_request_resources(client); - if (r) { - nfc_err(&client->dev, - "Cannot get ACPI data\n"); - return r; - } - } else { - nfc_err(&client->dev, "No platform data\n"); - return -EINVAL; + r = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), acpi_pn544_gpios); + if (r) + dev_dbg(dev, "Unable to add GPIO mapping table\n"); + + /* Get EN GPIO */ + phy->gpiod_en = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(phy->gpiod_en)) { + nfc_err(dev, "Unable to get EN GPIO\n"); + return PTR_ERR(phy->gpiod_en); + } + + /* Get FW GPIO */ + phy->gpiod_fw = devm_gpiod_get(dev, "firmware", GPIOD_OUT_LOW); + if (IS_ERR(phy->gpiod_fw)) { + nfc_err(dev, "Unable to get FW GPIO\n"); + return PTR_ERR(phy->gpiod_fw); } pn544_hci_i2c_platform_init(phy); -- cgit From bacf2a6a05726e3f10aa94ef7a20feba62ee5579 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 7 Mar 2017 12:25:42 +0200 Subject: NFC: st21nfca: Fix obvious typo when check error code We return -ENODEV if ACPI provides a GPIO resource. Looks really wrong. If it has even been tested? Signed-off-by: Andy Shevchenko Signed-off-by: Samuel Ortiz --- drivers/nfc/st21nfca/i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c index d16f58ac09bc..c4f0d048359b 100644 --- a/drivers/nfc/st21nfca/i2c.c +++ b/drivers/nfc/st21nfca/i2c.c @@ -513,9 +513,9 @@ static int st21nfca_hci_i2c_acpi_request_resources(struct i2c_client *client) /* Get EN GPIO from ACPI */ gpiod_ena = devm_gpiod_get_index(dev, ST21NFCA_GPIO_NAME_EN, 1, GPIOD_OUT_LOW); - if (!IS_ERR(gpiod_ena)) { + if (IS_ERR(gpiod_ena)) { nfc_err(dev, "Unable to get ENABLE GPIO\n"); - return -ENODEV; + return PTR_ERR(gpiod_ena); } phy->gpio_ena = desc_to_gpio(gpiod_ena); -- cgit From 79557b33cca2fa005235b45ab16b81f95f441bd8 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 7 Mar 2017 12:25:43 +0200 Subject: NFC: st21nfca: Get rid of platform data Legacy platform data must go away. We are on the safe side here since there are no users of it in the kernel. If anyone by any odd reason needs it the GPIO lookup tables and built-in device properties at your service. Signed-off-by: Andy Shevchenko Signed-off-by: Samuel Ortiz --- drivers/nfc/st21nfca/i2c.c | 46 +++------------------------------- include/linux/platform_data/st21nfca.h | 33 ------------------------ 2 files changed, 3 insertions(+), 76 deletions(-) delete mode 100644 include/linux/platform_data/st21nfca.h diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c index c4f0d048359b..443733502251 100644 --- a/drivers/nfc/st21nfca/i2c.c +++ b/drivers/nfc/st21nfca/i2c.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -29,7 +28,7 @@ #include #include #include -#include + #include #include @@ -59,6 +58,7 @@ #define IS_START_OF_FRAME(buf) (buf[0] == ST21NFCA_SOF_EOF && \ buf[1] == 0) +#define ST21NFCA_HCI_DRIVER_NAME "st21nfca_hci" #define ST21NFCA_HCI_I2C_DRIVER_NAME "st21nfca_hci_i2c" #define ST21NFCA_GPIO_NAME_EN "enable" @@ -576,43 +576,10 @@ static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client) return 0; } -static int st21nfca_hci_i2c_request_resources(struct i2c_client *client) -{ - struct st21nfca_nfc_platform_data *pdata; - struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client); - int r; - - pdata = client->dev.platform_data; - if (pdata == NULL) { - nfc_err(&client->dev, "No platform data\n"); - return -EINVAL; - } - - /* store for later use */ - phy->gpio_ena = pdata->gpio_ena; - phy->irq_polarity = pdata->irq_polarity; - - if (phy->gpio_ena > 0) { - r = devm_gpio_request_one(&client->dev, phy->gpio_ena, - GPIOF_OUT_INIT_HIGH, - ST21NFCA_GPIO_NAME_EN); - if (r) { - pr_err("%s : ena gpio_request failed\n", __FILE__); - return r; - } - } - - phy->se_status.is_ese_present = pdata->is_ese_present; - phy->se_status.is_uicc_present = pdata->is_uicc_present; - - return 0; -} - static int st21nfca_hci_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct st21nfca_i2c_phy *phy; - struct st21nfca_nfc_platform_data *pdata; int r; dev_dbg(&client->dev, "%s\n", __func__); @@ -638,19 +605,12 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, mutex_init(&phy->phy_lock); i2c_set_clientdata(client, phy); - pdata = client->dev.platform_data; - if (!pdata && client->dev.of_node) { + if (client->dev.of_node) { r = st21nfca_hci_i2c_of_request_resources(client); if (r) { nfc_err(&client->dev, "No platform data\n"); return r; } - } else if (pdata) { - r = st21nfca_hci_i2c_request_resources(client); - if (r) { - nfc_err(&client->dev, "Cannot get platform resources\n"); - return r; - } } else if (ACPI_HANDLE(&client->dev)) { r = st21nfca_hci_i2c_acpi_request_resources(client); if (r) { diff --git a/include/linux/platform_data/st21nfca.h b/include/linux/platform_data/st21nfca.h deleted file mode 100644 index cc2bdafb0c69..000000000000 --- a/include/linux/platform_data/st21nfca.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Driver include for the ST21NFCA NFC chip. - * - * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#ifndef _ST21NFCA_HCI_H_ -#define _ST21NFCA_HCI_H_ - -#include - -#define ST21NFCA_HCI_DRIVER_NAME "st21nfca_hci" - -struct st21nfca_nfc_platform_data { - unsigned int gpio_ena; - unsigned int irq_polarity; - bool is_ese_present; - bool is_uicc_present; -}; - -#endif /* _ST21NFCA_HCI_H_ */ -- cgit From 8e7836d030a2e08290a8df25d45a2fad00957738 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 7 Mar 2017 12:25:44 +0200 Subject: NFC: st21nfca: Get rid of "interesting" use of interrupt polarity I2C framework followed by IRQ framework does set interrupt polarity correctly if it's properly specified in firmware (ACPI or DT). Get rid of the redundant trick when requesting interrupt. Signed-off-by: Andy Shevchenko Signed-off-by: Samuel Ortiz --- drivers/nfc/st21nfca/i2c.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c index 443733502251..6cfc7b9c68a2 100644 --- a/drivers/nfc/st21nfca/i2c.c +++ b/drivers/nfc/st21nfca/i2c.c @@ -68,7 +68,6 @@ struct st21nfca_i2c_phy { struct nfc_hci_dev *hdev; unsigned int gpio_ena; - unsigned int irq_polarity; struct st21nfca_se_status se_status; @@ -520,8 +519,6 @@ static int st21nfca_hci_i2c_acpi_request_resources(struct i2c_client *client) phy->gpio_ena = desc_to_gpio(gpiod_ena); - phy->irq_polarity = irq_get_trigger_type(client->irq); - phy->se_status.is_ese_present = false; phy->se_status.is_uicc_present = false; @@ -566,8 +563,6 @@ static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client) phy->gpio_ena = gpio; - phy->irq_polarity = irq_get_trigger_type(client->irq); - phy->se_status.is_ese_present = of_property_read_bool(pp, "ese-present"); phy->se_status.is_uicc_present = @@ -630,7 +625,7 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, r = devm_request_threaded_irq(&client->dev, client->irq, NULL, st21nfca_hci_irq_thread_fn, - phy->irq_polarity | IRQF_ONESHOT, + IRQF_ONESHOT, ST21NFCA_HCI_DRIVER_NAME, phy); if (r < 0) { nfc_err(&client->dev, "Unable to register IRQ handler\n"); -- cgit From 8d3c50e2f290585f000638c3e3a8a1b1208e49cf Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 7 Mar 2017 12:25:45 +0200 Subject: NFC: st21nfca: Covert to use GPIO descriptor Since we got rid of platform data, the driver may use GPIO descriptor directly. Looking deeply to the use of the GPIO pin it looks like it should be a fixed voltage regulator rather than custom GPIO handling. But this is out of scope of the change. Signed-off-by: Andy Shevchenko Signed-off-by: Samuel Ortiz --- drivers/nfc/st21nfca/i2c.c | 40 +++++++++++++--------------------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c index 6cfc7b9c68a2..4946816f0011 100644 --- a/drivers/nfc/st21nfca/i2c.c +++ b/drivers/nfc/st21nfca/i2c.c @@ -67,8 +67,7 @@ struct st21nfca_i2c_phy { struct i2c_client *i2c_dev; struct nfc_hci_dev *hdev; - unsigned int gpio_ena; - + struct gpio_desc *gpiod_ena; struct st21nfca_se_status se_status; struct sk_buff *pending_skb; @@ -149,7 +148,7 @@ static int st21nfca_hci_i2c_enable(void *phy_id) { struct st21nfca_i2c_phy *phy = phy_id; - gpio_set_value(phy->gpio_ena, 1); + gpiod_set_value(phy->gpiod_ena, 1); phy->powered = 1; phy->run_mode = ST21NFCA_HCI_MODE; @@ -162,7 +161,7 @@ static void st21nfca_hci_i2c_disable(void *phy_id) { struct st21nfca_i2c_phy *phy = phy_id; - gpio_set_value(phy->gpio_ena, 0); + gpiod_set_value(phy->gpiod_ena, 0); phy->powered = 0; } @@ -505,20 +504,17 @@ static struct nfc_phy_ops i2c_phy_ops = { static int st21nfca_hci_i2c_acpi_request_resources(struct i2c_client *client) { struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client); - struct gpio_desc *gpiod_ena; struct device *dev = &client->dev; u8 tmp; /* Get EN GPIO from ACPI */ - gpiod_ena = devm_gpiod_get_index(dev, ST21NFCA_GPIO_NAME_EN, 1, - GPIOD_OUT_LOW); - if (IS_ERR(gpiod_ena)) { + phy->gpiod_ena = devm_gpiod_get_index(dev, ST21NFCA_GPIO_NAME_EN, 1, + GPIOD_OUT_LOW); + if (IS_ERR(phy->gpiod_ena)) { nfc_err(dev, "Unable to get ENABLE GPIO\n"); - return PTR_ERR(gpiod_ena); + return PTR_ERR(phy->gpiod_ena); } - phy->gpio_ena = desc_to_gpio(gpiod_ena); - phy->se_status.is_ese_present = false; phy->se_status.is_uicc_present = false; @@ -538,31 +534,21 @@ static int st21nfca_hci_i2c_acpi_request_resources(struct i2c_client *client) static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client) { struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client); + struct device *dev = &client->dev; struct device_node *pp; - int gpio; - int r; pp = client->dev.of_node; if (!pp) return -ENODEV; /* Get GPIO from device tree */ - gpio = of_get_named_gpio(pp, "enable-gpios", 0); - if (gpio < 0) { - nfc_err(&client->dev, "Failed to retrieve enable-gpios from device tree\n"); - return gpio; + phy->gpiod_ena = devm_gpiod_get_index(dev, ST21NFCA_GPIO_NAME_EN, 0, + GPIOD_OUT_HIGH); + if (IS_ERR(phy->gpiod_ena)) { + nfc_err(dev, "Failed to request enable pin\n"); + return PTR_ERR(phy->gpiod_ena); } - /* GPIO request and configuration */ - r = devm_gpio_request_one(&client->dev, gpio, GPIOF_OUT_INIT_HIGH, - ST21NFCA_GPIO_NAME_EN); - if (r) { - nfc_err(&client->dev, "Failed to request enable pin\n"); - return r; - } - - phy->gpio_ena = gpio; - phy->se_status.is_ese_present = of_property_read_bool(pp, "ese-present"); phy->se_status.is_uicc_present = -- cgit From 682fd6185053875bb16efb1037f3d2ae9680b015 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 7 Mar 2017 12:25:46 +0200 Subject: NFC: st21nfca: Use unified device property API meaningfully Another place in the code that unveils non-tested at all ACPI case. Use unified device property API in meaningful way. Signed-off-by: Andy Shevchenko Signed-off-by: Samuel Ortiz --- drivers/nfc/st21nfca/i2c.c | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c index 4946816f0011..02a920ca07c8 100644 --- a/drivers/nfc/st21nfca/i2c.c +++ b/drivers/nfc/st21nfca/i2c.c @@ -505,7 +505,6 @@ static int st21nfca_hci_i2c_acpi_request_resources(struct i2c_client *client) { struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client); struct device *dev = &client->dev; - u8 tmp; /* Get EN GPIO from ACPI */ phy->gpiod_ena = devm_gpiod_get_index(dev, ST21NFCA_GPIO_NAME_EN, 1, @@ -515,19 +514,6 @@ static int st21nfca_hci_i2c_acpi_request_resources(struct i2c_client *client) return PTR_ERR(phy->gpiod_ena); } - phy->se_status.is_ese_present = false; - phy->se_status.is_uicc_present = false; - - if (device_property_present(dev, "ese-present")) { - device_property_read_u8(dev, "ese-present", &tmp); - phy->se_status.is_ese_present = tmp; - } - - if (device_property_present(dev, "uicc-present")) { - device_property_read_u8(dev, "uicc-present", &tmp); - phy->se_status.is_uicc_present = tmp; - } - return 0; } @@ -535,11 +521,6 @@ static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client) { struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client); struct device *dev = &client->dev; - struct device_node *pp; - - pp = client->dev.of_node; - if (!pp) - return -ENODEV; /* Get GPIO from device tree */ phy->gpiod_ena = devm_gpiod_get_index(dev, ST21NFCA_GPIO_NAME_EN, 0, @@ -549,11 +530,6 @@ static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client) return PTR_ERR(phy->gpiod_ena); } - phy->se_status.is_ese_present = - of_property_read_bool(pp, "ese-present"); - phy->se_status.is_uicc_present = - of_property_read_bool(pp, "uicc-present"); - return 0; } @@ -603,6 +579,11 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, return -ENODEV; } + phy->se_status.is_ese_present = + device_property_read_bool(&client->dev, "ese-present"); + phy->se_status.is_uicc_present = + device_property_read_bool(&client->dev, "uicc-present"); + r = st21nfca_hci_platform_init(phy); if (r < 0) { nfc_err(&client->dev, "Unable to reboot st21nfca\n"); -- cgit From 3267183c3d1a6612c00961d7334413f9976c751a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 22 Mar 2017 21:20:58 +0200 Subject: NFC: netlink: Use error code from nfc_activate_target() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It looks like a typo to assign a return code to a variable which is not used. Found due to a compiler warning: net/nfc/netlink.c: In function ‘nfc_genl_activate_target’: net/nfc/netlink.c:903:6: warning: variable ‘rc’ set but not used [-Wunused-but-set-variable] int rc; ^~ Signed-off-by: Andy Shevchenko Signed-off-by: Samuel Ortiz --- net/nfc/netlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 4c95319dc22b..23a6e01f35ed 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -922,7 +922,7 @@ static int nfc_genl_activate_target(struct sk_buff *skb, struct genl_info *info) rc = nfc_activate_target(dev, target_idx, protocol); nfc_put_device(dev); - return 0; + return rc; } static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info) -- cgit From 2891f2d5c13b7386331250d59920bdf8a54bfccb Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 22 Mar 2017 21:22:51 +0200 Subject: NFC: Add nfc_dbg() macro In some cases nfc_dbg() is useful. Add such macro to a header. Signed-off-by: Andy Shevchenko Signed-off-by: Samuel Ortiz --- include/net/nfc/nfc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 1a3de8b34ad2..bbdc73a3239d 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -27,6 +27,7 @@ #include #include +#define nfc_dbg(dev, fmt, ...) dev_dbg((dev), "NFC: " fmt, ##__VA_ARGS__) #define nfc_info(dev, fmt, ...) dev_info((dev), "NFC: " fmt, ##__VA_ARGS__) #define nfc_err(dev, fmt, ...) dev_err((dev), "NFC: " fmt, ##__VA_ARGS__) -- cgit From 837eb4d21ecde7bde7a1fe523594fdf509055f3f Mon Sep 17 00:00:00 2001 From: Geoff Lansberry Date: Wed, 21 Dec 2016 23:18:32 -0500 Subject: NFC: trf7970a: add device tree option for 27MHz clock The TRF7970A has configuration options to support hardware designs which use a 27.12MHz clock. This commit adds a device tree option 'clock-frequency' to support configuring the this chip for default 13.56MHz clock or the optional 27.12MHz clock. Acked-by: Rob Herring Acked-by: Mark Greer Signed-off-by: Geoff Lansberry Signed-off-by: Samuel Ortiz --- .../devicetree/bindings/net/nfc/trf7970a.txt | 2 + drivers/nfc/trf7970a.c | 50 +++++++++++++++++----- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt index 5889a3d133b2..1d186cd9817b 100644 --- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt +++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt @@ -21,6 +21,7 @@ Optional SoC Specific Properties: - t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum where an extra byte is returned by Read Multiple Block commands issued to Type 5 tags. +- clock-frequency: Set to specify that the input frequency to the trf7970a is 13560000Hz or 27120000Hz Example (for ARM-based BeagleBone with TRF7970A on SPI1): @@ -43,6 +44,7 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1): irq-status-read-quirk; en2-rf-quirk; t5t-rmb-extra-byte-quirk; + clock-frequency = <27120000>; status = "okay"; }; }; diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c index 75079fb16f22..ecb786283ffa 100644 --- a/drivers/nfc/trf7970a.c +++ b/drivers/nfc/trf7970a.c @@ -124,6 +124,9 @@ NFC_PROTO_ISO15693_MASK | NFC_PROTO_NFC_DEP_MASK) #define TRF7970A_AUTOSUSPEND_DELAY 30000 /* 30 seconds */ +#define TRF7970A_13MHZ_CLOCK_FREQUENCY 13560000 +#define TRF7970A_27MHZ_CLOCK_FREQUENCY 27120000 + #define TRF7970A_RX_SKB_ALLOC_SIZE 256 @@ -1056,12 +1059,11 @@ static int trf7970a_init(struct trf7970a *trf) trf->chip_status_ctrl &= ~TRF7970A_CHIP_STATUS_RF_ON; - ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL, 0); + ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL, + trf->modulator_sys_clk_ctrl); if (ret) goto err_out; - trf->modulator_sys_clk_ctrl = 0; - ret = trf7970a_write(trf, TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS, TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_96 | TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32); @@ -1181,27 +1183,37 @@ static int trf7970a_in_config_rf_tech(struct trf7970a *trf, int tech) switch (tech) { case NFC_DIGITAL_RF_TECH_106A: trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443A_106; - trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK; + trf->modulator_sys_clk_ctrl = + (trf->modulator_sys_clk_ctrl & 0xf8) | + TRF7970A_MODULATOR_DEPTH_OOK; trf->guard_time = TRF7970A_GUARD_TIME_NFCA; break; case NFC_DIGITAL_RF_TECH_106B: trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443B_106; - trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10; + trf->modulator_sys_clk_ctrl = + (trf->modulator_sys_clk_ctrl & 0xf8) | + TRF7970A_MODULATOR_DEPTH_ASK10; trf->guard_time = TRF7970A_GUARD_TIME_NFCB; break; case NFC_DIGITAL_RF_TECH_212F: trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_212; - trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10; + trf->modulator_sys_clk_ctrl = + (trf->modulator_sys_clk_ctrl & 0xf8) | + TRF7970A_MODULATOR_DEPTH_ASK10; trf->guard_time = TRF7970A_GUARD_TIME_NFCF; break; case NFC_DIGITAL_RF_TECH_424F: trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_424; - trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10; + trf->modulator_sys_clk_ctrl = + (trf->modulator_sys_clk_ctrl & 0xf8) | + TRF7970A_MODULATOR_DEPTH_ASK10; trf->guard_time = TRF7970A_GUARD_TIME_NFCF; break; case NFC_DIGITAL_RF_TECH_ISO15693: trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648; - trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK; + trf->modulator_sys_clk_ctrl = + (trf->modulator_sys_clk_ctrl & 0xf8) | + TRF7970A_MODULATOR_DEPTH_OOK; trf->guard_time = TRF7970A_GUARD_TIME_15693; break; default: @@ -1571,17 +1583,23 @@ static int trf7970a_tg_config_rf_tech(struct trf7970a *trf, int tech) trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE | TRF7970A_ISO_CTRL_NFC_CE | TRF7970A_ISO_CTRL_NFC_CE_14443A; - trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK; + trf->modulator_sys_clk_ctrl = + (trf->modulator_sys_clk_ctrl & 0xf8) | + TRF7970A_MODULATOR_DEPTH_OOK; break; case NFC_DIGITAL_RF_TECH_212F: trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE | TRF7970A_ISO_CTRL_NFC_NFCF_212; - trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10; + trf->modulator_sys_clk_ctrl = + (trf->modulator_sys_clk_ctrl & 0xf8) | + TRF7970A_MODULATOR_DEPTH_ASK10; break; case NFC_DIGITAL_RF_TECH_424F: trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE | TRF7970A_ISO_CTRL_NFC_NFCF_424; - trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10; + trf->modulator_sys_clk_ctrl = + (trf->modulator_sys_clk_ctrl & 0xf8) | + TRF7970A_MODULATOR_DEPTH_ASK10; break; default: dev_dbg(trf->dev, "Unsupported rf technology: %d\n", tech); @@ -1990,6 +2008,7 @@ static int trf7970a_probe(struct spi_device *spi) struct device_node *np = spi->dev.of_node; struct trf7970a *trf; int uvolts, autosuspend_delay, ret; + u32 clk_freq = TRF7970A_13MHZ_CLOCK_FREQUENCY; if (!np) { dev_err(&spi->dev, "No Device Tree entry\n"); @@ -2045,6 +2064,15 @@ static int trf7970a_probe(struct spi_device *spi) } } + of_property_read_u32(np, "clock-frequency", &clk_freq); + if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) || + (clk_freq != TRF7970A_13MHZ_CLOCK_FREQUENCY)) { + dev_err(trf->dev, + "clock-frequency (%u Hz) unsupported\n", + clk_freq); + return -EINVAL; + } + if (of_property_read_bool(np, "en2-rf-quirk")) trf->quirks |= TRF7970A_QUIRK_EN2_MUST_STAY_LOW; -- cgit From 49d22c70aaf07cd7e33346b247f5df3ddb072ee0 Mon Sep 17 00:00:00 2001 From: Geoff Lansberry Date: Wed, 21 Dec 2016 23:18:33 -0500 Subject: NFC: trf7970a: Add device tree option of 1.8 Volt IO voltage The TRF7970A has configuration options for supporting hardware designs with 1.8 Volt or 3.3 Volt IO. This commit adds a device tree option, using a fixed regulator binding, for setting the io voltage to match the hardware configuration. If no option is supplied it defaults to 3.3 volt configuration. Acked-by: Rob Herring Acked-by: Mark Greer Signed-off-by: Geoff Lansberry Signed-off-by: Samuel Ortiz --- .../devicetree/bindings/net/nfc/trf7970a.txt | 2 ++ drivers/nfc/trf7970a.c | 26 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt index 1d186cd9817b..c627bbb3009e 100644 --- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt +++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt @@ -21,6 +21,7 @@ Optional SoC Specific Properties: - t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum where an extra byte is returned by Read Multiple Block commands issued to Type 5 tags. +- vdd-io-supply: Regulator specifying voltage for vdd-io - clock-frequency: Set to specify that the input frequency to the trf7970a is 13560000Hz or 27120000Hz Example (for ARM-based BeagleBone with TRF7970A on SPI1): @@ -40,6 +41,7 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1): <&gpio2 5 GPIO_ACTIVE_LOW>; vin-supply = <&ldo3_reg>; vin-voltage-override = <5000000>; + vdd-io-supply = <&ldo2_reg>; autosuspend-delay = <30000>; irq-status-read-quirk; en2-rf-quirk; diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c index ecb786283ffa..2d1c8ca6e679 100644 --- a/drivers/nfc/trf7970a.c +++ b/drivers/nfc/trf7970a.c @@ -444,6 +444,7 @@ struct trf7970a { u8 iso_ctrl_tech; u8 modulator_sys_clk_ctrl; u8 special_fcn_reg1; + u8 io_ctrl; unsigned int guard_time; int technology; int framing; @@ -1051,6 +1052,11 @@ static int trf7970a_init(struct trf7970a *trf) if (ret) goto err_out; + ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL, + trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1)); + if (ret) + goto err_out; + ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL, 0); if (ret) goto err_out; @@ -1767,7 +1773,7 @@ static int _trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout, goto out_err; ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL, - TRF7970A_REG_IO_CTRL_VRS(0x1)); + trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1)); if (ret) goto out_err; @@ -2107,6 +2113,24 @@ static int trf7970a_probe(struct spi_device *spi) if (uvolts > 4000000) trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3; + trf->regulator = devm_regulator_get(&spi->dev, "vdd-io"); + if (IS_ERR(trf->regulator)) { + ret = PTR_ERR(trf->regulator); + dev_err(trf->dev, "Can't get VDD_IO regulator: %d\n", ret); + goto err_destroy_lock; + } + + ret = regulator_enable(trf->regulator); + if (ret) { + dev_err(trf->dev, "Can't enable VDD_IO: %d\n", ret); + goto err_destroy_lock; + } + + if (regulator_get_voltage(trf->regulator) == 1800000) { + trf->io_ctrl = TRF7970A_REG_IO_CTRL_IO_LOW; + dev_dbg(trf->dev, "trf7970a config vdd_io to 1.8V\n"); + } + trf->ddev = nfc_digital_allocate_device(&trf7970a_nfc_ops, TRF7970A_SUPPORTED_PROTOCOLS, NFC_DIGITAL_DRV_CAPS_IN_CRC | -- cgit From 8b55d7581fc5dccc658b9a169879c46dda807d5e Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Thu, 6 Apr 2017 05:49:02 +0200 Subject: NFC: pn533: use constant off-stack buffer for sending acks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix for WARN: usb 3-2.4.1: NFC: Exchanging data failed (error 0x13) llcp: nfc_llcp_recv: err -5 llcp: nfc_llcp_symm_timer: SYMM timeout ------------[ cut here ]------------ WARNING: CPU: 1 PID: 26397 at .../drivers/usb/core/hcd.c:1584 usb_hcd_map_urb_for_dma+0x370/0x550 transfer buffer not dma capable [...] Workqueue: events nfc_llcp_timeout_work [nfc] Call Trace: ? dump_stack+0x46/0x5a ? __warn+0xb9/0xe0 ? warn_slowpath_fmt+0x5a/0x80 ? usb_hcd_map_urb_for_dma+0x370/0x550 ? usb_hcd_submit_urb+0x2fb/0xa60 ? dequeue_entity+0x3f2/0xc30 ? pn533_usb_send_ack+0x5d/0x80 [pn533_usb] ? pn533_usb_abort_cmd+0x13/0x20 [pn533_usb] ? pn533_dep_link_down+0x32/0x70 [pn533] ? nfc_dep_link_down+0x87/0xd0 [nfc] [...] usb 3-2.4.1: NFC: Exchanging data failed (error 0x13) llcp: nfc_llcp_recv: err -5 llcp: nfc_llcp_symm_timer: SYMM timeout Signed-off-by: Michał Mirosław Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533/i2c.c | 2 +- drivers/nfc/pn533/usb.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/nfc/pn533/i2c.c b/drivers/nfc/pn533/i2c.c index 2c2fb9cfe10a..8f60ce039b0d 100644 --- a/drivers/nfc/pn533/i2c.c +++ b/drivers/nfc/pn533/i2c.c @@ -51,7 +51,7 @@ static int pn533_i2c_send_ack(struct pn533 *dev, gfp_t flags) { struct pn533_i2c_phy *phy = dev->phy; struct i2c_client *client = phy->i2c_dev; - u8 ack[6] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00}; + static const u8 ack[6] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00}; /* spec 6.2.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */ int rc; diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c index 000159ea9c5f..8ed203ea21ea 100644 --- a/drivers/nfc/pn533/usb.c +++ b/drivers/nfc/pn533/usb.c @@ -148,11 +148,11 @@ static int pn533_submit_urb_for_ack(struct pn533_usb_phy *phy, gfp_t flags) static int pn533_usb_send_ack(struct pn533 *dev, gfp_t flags) { struct pn533_usb_phy *phy = dev->phy; - u8 ack[6] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00}; + static const u8 ack[6] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00}; /* spec 7.1.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */ int rc; - phy->out_urb->transfer_buffer = ack; + phy->out_urb->transfer_buffer = (u8 *)ack; phy->out_urb->transfer_buffer_length = sizeof(ack); rc = usb_submit_urb(phy->out_urb, flags); -- cgit From 4ea206395d3aede32bab94a75ec573530486fa44 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 17 Apr 2017 00:42:22 +0200 Subject: nfc: fix get_unaligned_...() misuses * if a local variable of type uint16_t is unaligned, your compiler is FUBAR * the whole point of get_unaligned_... is to avoid memcpy + ..._to_cpu(). Using it *after* memcpy() (into aligned object, no less) is pointless. Signed-off-by: Al Viro Signed-off-by: Samuel Ortiz --- drivers/nfc/nfcmrvl/fw_dnld.c | 5 ++--- drivers/nfc/nxp-nci/i2c.c | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/nfc/nfcmrvl/fw_dnld.c b/drivers/nfc/nfcmrvl/fw_dnld.c index 441c1b0ec7b5..c38bdd6a5a82 100644 --- a/drivers/nfc/nfcmrvl/fw_dnld.c +++ b/drivers/nfc/nfcmrvl/fw_dnld.c @@ -281,12 +281,11 @@ static int process_state_fw_dnld(struct nfcmrvl_private *priv, return -EINVAL; } skb_pull(skb, 1); - memcpy(&len, skb->data, 2); + len = get_unaligned_le16(skb->data); skb_pull(skb, 2); + comp_len = get_unaligned_le16(skb->data); memcpy(&comp_len, skb->data, 2); skb_pull(skb, 2); - len = get_unaligned_le16(&len); - comp_len = get_unaligned_le16(&comp_len); if (((~len) & 0xFFFF) != comp_len) { nfc_err(priv->dev, "bad len complement: %x %x %x", len, comp_len, (~len & 0xFFFF)); diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c index c6a04a950225..ff22d761183c 100644 --- a/drivers/nfc/nxp-nci/i2c.c +++ b/drivers/nfc/nxp-nci/i2c.c @@ -126,7 +126,7 @@ static int nxp_nci_i2c_fw_read(struct nxp_nci_i2c_phy *phy, goto fw_read_exit; } - frame_len = (get_unaligned_be16(&header) & NXP_NCI_FW_FRAME_LEN_MASK) + + frame_len = (be16_to_cpu(header) & NXP_NCI_FW_FRAME_LEN_MASK) + NXP_NCI_FW_CRC_LEN; *skb = alloc_skb(NXP_NCI_FW_HDR_LEN + frame_len, GFP_KERNEL); -- cgit