diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt index 32b35a07abe4..c627bbb3009e 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: @@ -21,6 +21,8 @@ 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): @@ -39,10 +41,12 @@ 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; t5t-rmb-extra-byte-quirk; + clock-frequency = <27120000>; status = "okay"; }; }; diff --git a/MAINTAINERS b/MAINTAINERS index 39aa09100a48..700d8906ff15 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8876,8 +8876,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) 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/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) diff --git a/drivers/nfc/nfcmrvl/fw_dnld.c b/drivers/nfc/nfcmrvl/fw_dnld.c index f8dcdf4b24f6..c38bdd6a5a82 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 @@ -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/nfcmrvl/spi.c b/drivers/nfc/nfcmrvl/spi.c index a7faa0bcc01e..8e0ddb434770 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 @@ -96,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; } 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"); 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..ff22d761183c 100644 --- a/drivers/nfc/nxp-nci/i2c.c +++ b/drivers/nfc/nxp-nci/i2c.c @@ -29,14 +29,13 @@ #include #include #include -#include #include #include #include #include #include #include -#include +#include #include @@ -86,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); } @@ -127,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); diff --git a/drivers/nfc/pn533/i2c.c b/drivers/nfc/pn533/i2c.c index 1dc89248e58e..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; @@ -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; } @@ -242,10 +250,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; } diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index a966c6a85ea8..65bbaa5fcdda 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 { @@ -2556,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, @@ -2565,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; @@ -2608,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, @@ -2633,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..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); @@ -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; diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c index f837c39a8017..71ac0836c9f4 100644 --- a/drivers/nfc/pn544/i2c.c +++ b/drivers/nfc/pn544/i2c.c @@ -21,17 +21,13 @@ #include #include #include -#include -#include -#include #include -#include #include #include #include #include #include -#include + #include #include @@ -165,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; @@ -208,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 */ @@ -239,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; @@ -269,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; @@ -874,106 +869,20 @@ 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; +static const struct acpi_gpio_params enable_gpios = { 1, 0, false }; +static const struct acpi_gpio_params firmware_gpios = { 2, 0, false }; - /* 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)) { - nfc_err(dev, "Unable to get EN GPIO\n"); - return -ENODEV; - } - - 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)) { - nfc_err(dev, "Unable to get FW GPIO\n"); - return -ENODEV; - } - - 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; - } - - /* 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; - } - 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; - } - - return 0; - -err_gpio_fw: - gpio_free(phy->gpio_fw); -err_gpio_en: - gpio_free(phy->gpio_en); -err_dt: - return ret; -} +static const struct acpi_gpio_mapping acpi_pn544_gpios[] = { + { "enable-gpios", &enable_gpios, 1 }, + { "firmware-gpios", &firmware_gpios, 1 }, + { }, +}; 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; - struct pn544_nfc_platform_data *pdata; int r = 0; dev_dbg(&client->dev, "%s\n", __func__); @@ -995,53 +904,33 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, phy->i2c_dev = client; i2c_set_clientdata(client, phy); - pdata = client->dev.platform_data; + r = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), acpi_pn544_gpios); + if (r) + dev_dbg(dev, "Unable to add GPIO mapping table\n"); - /* No platform data, using device tree. */ - if (!pdata && 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) { + /* 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); + } - 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); - if (r) { - nfc_err(&client->dev, - "Cannot get ACPI data\n"); - return r; - } - } else { - nfc_err(&client->dev, "No platform data\n"); - return -EINVAL; + /* 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); - 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"); - goto err_rti; + return r; } r = pn544_hci_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME, @@ -1049,28 +938,14 @@ 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); - -err_rti: - if (!pdata) { - gpio_free(phy->gpio_en); - gpio_free(phy->gpio_fw); - } else if (pdata->free_resources) { - pdata->free_resources(); - } - - return r; } 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__); @@ -1083,17 +958,7 @@ static int pn544_hci_i2c_remove(struct i2c_client *client) if (phy->powered) pn544_hci_i2c_disable(phy); - 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(); - } - + acpi_dev_remove_driver_gpios(ACPI_COMPANION(&client->dev)); return 0; } diff --git a/drivers/nfc/port100.c b/drivers/nfc/port100.c index 2b2330b235e6..19be93e177fe 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 | \ @@ -725,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); - - 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); - - /* 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(). + /* + * 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. */ - dev->cmd_cancel = !rc; + if (!dev->cmd_cancel) { + reinit_completion(&dev->cmd_cancel_done); + + 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); + + /* + * 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); @@ -928,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) { @@ -1477,7 +1488,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); @@ -1538,11 +1550,13 @@ 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; 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 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); diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c index 5a82f553906c..02a920ca07c8 100644 --- a/drivers/nfc/st21nfca/i2c.c +++ b/drivers/nfc/st21nfca/i2c.c @@ -20,17 +20,15 @@ #include #include #include -#include #include #include #include #include -#include #include #include #include #include -#include + #include #include @@ -60,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" @@ -68,9 +67,7 @@ struct st21nfca_i2c_phy { struct i2c_client *i2c_dev; struct nfc_hci_dev *hdev; - unsigned int gpio_ena; - unsigned int irq_polarity; - + struct gpio_desc *gpiod_ena; struct st21nfca_se_status se_status; struct sk_buff *pending_skb; @@ -151,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; @@ -164,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; } @@ -507,33 +504,14 @@ 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 -ENODEV; - } - - 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; - - 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 PTR_ERR(phy->gpiod_ena); } return 0; @@ -542,70 +520,16 @@ 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_node *pp; - int gpio; - int r; - - pp = client->dev.of_node; - if (!pp) - return -ENODEV; + struct device *dev = &client->dev; /* 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->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 = - of_property_read_bool(pp, "uicc-present"); - - 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; } @@ -613,7 +537,6 @@ 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__); @@ -639,19 +562,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) { @@ -663,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"); @@ -671,7 +592,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"); diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c index 26c9dbbccb0c..2d1c8ca6e679 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 @@ -441,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; @@ -1048,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; @@ -1056,12 +1065,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 +1189,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 +1589,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); @@ -1749,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; @@ -1885,8 +1909,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 +1940,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) @@ -1987,6 +2014,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"); @@ -2032,15 +2060,23 @@ 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; + 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; + } } - 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; + 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")) @@ -2077,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 | 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_ */ 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_ */ 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__) diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 529443acd3bc..6b0850e63e09 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -304,6 +304,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; @@ -318,10 +329,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); @@ -597,11 +605,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); @@ -919,7 +923,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)