From 0bf2840ccc6efcba82d83b224dcde19dea9f1ee3 Mon Sep 17 00:00:00 2001 From: Lars Poeschel Date: Tue, 29 Oct 2019 15:46:29 +0100 Subject: nfc: pn533: Add dev_up/dev_down hooks to phy_ops This adds hooks for dev_up and dev_down to the phy_ops. They are optional. The idea is to inform the phy driver when the nfc chip is really going to be used. When it is not used, the phy driver can suspend it's interface to the nfc chip to save some power. The nfc chip is considered not in use before dev_up and after dev_down. Cc: Johan Hovold Signed-off-by: Lars Poeschel Signed-off-by: David S. Miller --- drivers/nfc/pn533/pn533.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers/nfc/pn533/pn533.c') diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index a172a32aa9d9..64836c727aee 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -2458,6 +2458,9 @@ static int pn533_dev_up(struct nfc_dev *nfc_dev) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); + if (dev->phy_ops->dev_up) + dev->phy_ops->dev_up(dev); + if (dev->device_type == PN533_DEVICE_PN532) { int rc = pn532_sam_configuration(nfc_dev); @@ -2470,7 +2473,14 @@ static int pn533_dev_up(struct nfc_dev *nfc_dev) static int pn533_dev_down(struct nfc_dev *nfc_dev) { - return pn533_rf_field(nfc_dev, 0); + struct pn533 *dev = nfc_get_drvdata(nfc_dev); + int ret; + + ret = pn533_rf_field(nfc_dev, 0); + if (dev->phy_ops->dev_down && !ret) + dev->phy_ops->dev_down(dev); + + return ret; } static struct nfc_ops pn533_nfc_ops = { -- cgit v1.2.3-59-g8ed1b From 843cc92ed323692943c94d7e6ce97a0353b8c2d7 Mon Sep 17 00:00:00 2001 From: Lars Poeschel Date: Tue, 29 Oct 2019 15:46:46 +0100 Subject: nfc: pn533: Split pn533 init & nfc_register There is a problem in the initialisation and setup of the pn533: It registers with nfc too early. It could happen, that it finished registering with nfc and someone starts using it. But setup of the pn533 is not yet finished. Bad or at least unintended things could happen. So I split out nfc registering (and unregistering) to seperate functions that have to be called late in probe then. i2c requires a bit more love: i2c requests an irq in it's probe function. 'Commit 32ecc75ded72 ("NFC: pn533: change order operations in dev registation")' shows, this can not happen too early. An irq can be served before structs are fully initialized. The way chosen to prevent this is to request the irq after nfc_alloc_device initialized the structs, but before nfc_register_device. So there is now this pn532_i2c_nfc_alloc function. Cc: Johan Hovold Cc: Claudiu Beznea Cc: Jakub Kicinski Signed-off-by: Lars Poeschel Signed-off-by: David S. Miller --- drivers/nfc/pn533/i2c.c | 27 +++++++++++------ drivers/nfc/pn533/pn533.c | 76 +++++++++++++++++++++++++++-------------------- drivers/nfc/pn533/pn533.h | 13 ++++---- drivers/nfc/pn533/usb.c | 16 ++++++---- 4 files changed, 80 insertions(+), 52 deletions(-) (limited to 'drivers/nfc/pn533/pn533.c') diff --git a/drivers/nfc/pn533/i2c.c b/drivers/nfc/pn533/i2c.c index 1abd40398a5a..7507176cca0a 100644 --- a/drivers/nfc/pn533/i2c.c +++ b/drivers/nfc/pn533/i2c.c @@ -193,12 +193,10 @@ static int pn533_i2c_probe(struct i2c_client *client, phy->i2c_dev = client; i2c_set_clientdata(client, phy); - priv = pn533_register_device(PN533_DEVICE_PN532, - PN533_NO_TYPE_B_PROTOCOLS, - PN533_PROTO_REQ_ACK_RESP, - phy, &i2c_phy_ops, NULL, - &phy->i2c_dev->dev, - &client->dev); + priv = pn53x_common_init(PN533_DEVICE_PN532, + PN533_PROTO_REQ_ACK_RESP, + phy, &i2c_phy_ops, NULL, + &phy->i2c_dev->dev); if (IS_ERR(priv)) { r = PTR_ERR(priv); @@ -206,6 +204,9 @@ static int pn533_i2c_probe(struct i2c_client *client, } phy->priv = priv; + r = pn532_i2c_nfc_alloc(priv, PN533_NO_TYPE_B_PROTOCOLS, &client->dev); + if (r) + goto nfc_alloc_err; r = request_threaded_irq(client->irq, NULL, pn533_i2c_irq_thread_fn, IRQF_TRIGGER_FALLING | @@ -220,13 +221,20 @@ static int pn533_i2c_probe(struct i2c_client *client, if (r) goto fn_setup_err; - return 0; + r = nfc_register_device(priv->nfc_dev); + if (r) + goto fn_setup_err; + + return r; fn_setup_err: free_irq(client->irq, phy); irq_rqst_err: - pn533_unregister_device(phy->priv); + nfc_free_device(priv->nfc_dev); + +nfc_alloc_err: + pn53x_common_clean(phy->priv); return r; } @@ -239,7 +247,8 @@ static int pn533_i2c_remove(struct i2c_client *client) free_irq(client->irq, phy); - pn533_unregister_device(phy->priv); + pn53x_unregister_nfc(phy->priv); + pn53x_common_clean(phy->priv); return 0; } diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index 64836c727aee..e185dc5f12b9 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -2590,14 +2590,12 @@ int pn533_finalize_setup(struct pn533 *dev) } EXPORT_SYMBOL_GPL(pn533_finalize_setup); -struct pn533 *pn533_register_device(u32 device_type, - u32 protocols, +struct pn533 *pn53x_common_init(u32 device_type, enum pn533_protocol_type protocol_type, void *phy, struct pn533_phy_ops *phy_ops, struct pn533_frame_ops *fops, - struct device *dev, - struct device *parent) + struct device *dev) { struct pn533 *priv; int rc = -ENOMEM; @@ -2638,43 +2636,18 @@ struct pn533 *pn533_register_device(u32 device_type, skb_queue_head_init(&priv->fragment_skb); INIT_LIST_HEAD(&priv->cmd_queue); - - priv->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols, - priv->ops->tx_header_len + - PN533_CMD_DATAEXCH_HEAD_LEN, - priv->ops->tx_tail_len); - if (!priv->nfc_dev) { - rc = -ENOMEM; - goto destroy_wq; - } - - nfc_set_parent_dev(priv->nfc_dev, parent); - nfc_set_drvdata(priv->nfc_dev, priv); - - rc = nfc_register_device(priv->nfc_dev); - if (rc) - goto free_nfc_dev; - return priv; -free_nfc_dev: - nfc_free_device(priv->nfc_dev); - -destroy_wq: - destroy_workqueue(priv->wq); error: kfree(priv); return ERR_PTR(rc); } -EXPORT_SYMBOL_GPL(pn533_register_device); +EXPORT_SYMBOL_GPL(pn53x_common_init); -void pn533_unregister_device(struct pn533 *priv) +void pn53x_common_clean(struct pn533 *priv) { struct pn533_cmd *cmd, *n; - nfc_unregister_device(priv->nfc_dev); - nfc_free_device(priv->nfc_dev); - flush_delayed_work(&priv->poll_work); destroy_workqueue(priv->wq); @@ -2689,8 +2662,47 @@ void pn533_unregister_device(struct pn533 *priv) kfree(priv); } -EXPORT_SYMBOL_GPL(pn533_unregister_device); +EXPORT_SYMBOL_GPL(pn53x_common_clean); + +int pn532_i2c_nfc_alloc(struct pn533 *priv, u32 protocols, + struct device *parent) +{ + priv->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols, + priv->ops->tx_header_len + + PN533_CMD_DATAEXCH_HEAD_LEN, + priv->ops->tx_tail_len); + if (!priv->nfc_dev) + return -ENOMEM; + + nfc_set_parent_dev(priv->nfc_dev, parent); + nfc_set_drvdata(priv->nfc_dev, priv); + return 0; +} +EXPORT_SYMBOL_GPL(pn532_i2c_nfc_alloc); + +int pn53x_register_nfc(struct pn533 *priv, u32 protocols, + struct device *parent) +{ + int rc; + + rc = pn532_i2c_nfc_alloc(priv, protocols, parent); + if (rc) + return rc; + + rc = nfc_register_device(priv->nfc_dev); + if (rc) + nfc_free_device(priv->nfc_dev); + + return rc; +} +EXPORT_SYMBOL_GPL(pn53x_register_nfc); +void pn53x_unregister_nfc(struct pn533 *priv) +{ + nfc_unregister_device(priv->nfc_dev); + nfc_free_device(priv->nfc_dev); +} +EXPORT_SYMBOL_GPL(pn53x_unregister_nfc); MODULE_AUTHOR("Lauro Ramos Venancio "); MODULE_AUTHOR("Aloisio Almeida Jr "); diff --git a/drivers/nfc/pn533/pn533.h b/drivers/nfc/pn533/pn533.h index 570ee0a3e832..984f79fef59e 100644 --- a/drivers/nfc/pn533/pn533.h +++ b/drivers/nfc/pn533/pn533.h @@ -219,18 +219,21 @@ struct pn533_phy_ops { }; -struct pn533 *pn533_register_device(u32 device_type, - u32 protocols, +struct pn533 *pn53x_common_init(u32 device_type, enum pn533_protocol_type protocol_type, void *phy, struct pn533_phy_ops *phy_ops, struct pn533_frame_ops *fops, - struct device *dev, - struct device *parent); + struct device *dev); int pn533_finalize_setup(struct pn533 *dev); -void pn533_unregister_device(struct pn533 *priv); +void pn53x_common_clean(struct pn533 *priv); void pn533_recv_frame(struct pn533 *dev, struct sk_buff *skb, int status); +int pn532_i2c_nfc_alloc(struct pn533 *priv, u32 protocols, + struct device *parent); +int pn53x_register_nfc(struct pn533 *priv, u32 protocols, + struct device *parent); +void pn53x_unregister_nfc(struct pn533 *priv); bool pn533_rx_frame_is_cmd_response(struct pn533 *dev, void *frame); bool pn533_rx_frame_is_ack(void *_frame); diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c index e897e4d768ef..4590fbf82dc2 100644 --- a/drivers/nfc/pn533/usb.c +++ b/drivers/nfc/pn533/usb.c @@ -534,9 +534,9 @@ static int pn533_usb_probe(struct usb_interface *interface, goto error; } - priv = pn533_register_device(id->driver_info, protocols, protocol_type, + priv = pn53x_common_init(id->driver_info, protocol_type, phy, &usb_phy_ops, fops, - &phy->udev->dev, &interface->dev); + &phy->udev->dev); if (IS_ERR(priv)) { rc = PTR_ERR(priv); @@ -547,14 +547,17 @@ static int pn533_usb_probe(struct usb_interface *interface, rc = pn533_finalize_setup(priv); if (rc) - goto err_deregister; + goto err_clean; usb_set_intfdata(interface, phy); + rc = pn53x_register_nfc(priv, protocols, &interface->dev); + if (rc) + goto err_clean; return 0; -err_deregister: - pn533_unregister_device(phy->priv); +err_clean: + pn53x_common_clean(priv); error: usb_kill_urb(phy->in_urb); usb_kill_urb(phy->out_urb); @@ -577,7 +580,8 @@ static void pn533_usb_disconnect(struct usb_interface *interface) if (!phy) return; - pn533_unregister_device(phy->priv); + pn53x_unregister_nfc(phy->priv); + pn53x_common_clean(phy->priv); usb_set_intfdata(interface, NULL); -- cgit v1.2.3-59-g8ed1b From c64b875fe1e1f6b30e3a15cb74d623349c571001 Mon Sep 17 00:00:00 2001 From: Lars Poeschel Date: Tue, 29 Oct 2019 15:47:43 +0100 Subject: nfc: pn533: Add autopoll capability pn532 devices support an autopoll command, that lets the chip automatically poll for selected nfc technologies instead of manually looping through every single nfc technology the user is interested in. This is faster and less cpu and bus intensive than manually polling. This adds this autopoll capability to the pn533 driver. Cc: Johan Hovold Cc: David Miller Signed-off-by: Lars Poeschel Signed-off-by: David S. Miller --- drivers/nfc/pn533/pn533.c | 193 +++++++++++++++++++++++++++++++++++++++++++++- drivers/nfc/pn533/pn533.h | 10 ++- 2 files changed, 197 insertions(+), 6 deletions(-) (limited to 'drivers/nfc/pn533/pn533.c') diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index e185dc5f12b9..aa766e7ece70 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -185,6 +185,32 @@ struct pn533_cmd_jump_dep_response { u8 gt[]; } __packed; +struct pn532_autopoll_resp { + u8 type; + u8 ln; + u8 tg; + u8 tgdata[]; +}; + +/* PN532_CMD_IN_AUTOPOLL */ +#define PN532_AUTOPOLL_POLLNR_INFINITE 0xff +#define PN532_AUTOPOLL_PERIOD 0x03 /* in units of 150 ms */ + +#define PN532_AUTOPOLL_TYPE_GENERIC_106 0x00 +#define PN532_AUTOPOLL_TYPE_GENERIC_212 0x01 +#define PN532_AUTOPOLL_TYPE_GENERIC_424 0x02 +#define PN532_AUTOPOLL_TYPE_JEWEL 0x04 +#define PN532_AUTOPOLL_TYPE_MIFARE 0x10 +#define PN532_AUTOPOLL_TYPE_FELICA212 0x11 +#define PN532_AUTOPOLL_TYPE_FELICA424 0x12 +#define PN532_AUTOPOLL_TYPE_ISOA 0x20 +#define PN532_AUTOPOLL_TYPE_ISOB 0x23 +#define PN532_AUTOPOLL_TYPE_DEP_PASSIVE_106 0x40 +#define PN532_AUTOPOLL_TYPE_DEP_PASSIVE_212 0x41 +#define PN532_AUTOPOLL_TYPE_DEP_PASSIVE_424 0x42 +#define PN532_AUTOPOLL_TYPE_DEP_ACTIVE_106 0x80 +#define PN532_AUTOPOLL_TYPE_DEP_ACTIVE_212 0x81 +#define PN532_AUTOPOLL_TYPE_DEP_ACTIVE_424 0x82 /* PN533_TG_INIT_AS_TARGET */ #define PN533_INIT_TARGET_PASSIVE 0x1 @@ -1389,6 +1415,101 @@ static int pn533_poll_dep(struct nfc_dev *nfc_dev) return rc; } +static int pn533_autopoll_complete(struct pn533 *dev, void *arg, + struct sk_buff *resp) +{ + struct pn532_autopoll_resp *apr; + struct nfc_target nfc_tgt; + u8 nbtg; + int rc; + + if (IS_ERR(resp)) { + rc = PTR_ERR(resp); + + nfc_err(dev->dev, "%s autopoll complete error %d\n", + __func__, rc); + + if (rc == -ENOENT) { + if (dev->poll_mod_count != 0) + return rc; + goto stop_poll; + } else if (rc < 0) { + nfc_err(dev->dev, + "Error %d when running autopoll\n", rc); + goto stop_poll; + } + } + + nbtg = resp->data[0]; + if ((nbtg > 2) || (nbtg <= 0)) + return -EAGAIN; + + apr = (struct pn532_autopoll_resp *)&resp->data[1]; + while (nbtg--) { + memset(&nfc_tgt, 0, sizeof(struct nfc_target)); + switch (apr->type) { + case PN532_AUTOPOLL_TYPE_ISOA: + dev_dbg(dev->dev, "ISOA\n"); + rc = pn533_target_found_type_a(&nfc_tgt, apr->tgdata, + apr->ln - 1); + break; + case PN532_AUTOPOLL_TYPE_FELICA212: + case PN532_AUTOPOLL_TYPE_FELICA424: + dev_dbg(dev->dev, "FELICA\n"); + rc = pn533_target_found_felica(&nfc_tgt, apr->tgdata, + apr->ln - 1); + break; + case PN532_AUTOPOLL_TYPE_JEWEL: + dev_dbg(dev->dev, "JEWEL\n"); + rc = pn533_target_found_jewel(&nfc_tgt, apr->tgdata, + apr->ln - 1); + break; + case PN532_AUTOPOLL_TYPE_ISOB: + dev_dbg(dev->dev, "ISOB\n"); + rc = pn533_target_found_type_b(&nfc_tgt, apr->tgdata, + apr->ln - 1); + break; + case PN532_AUTOPOLL_TYPE_MIFARE: + dev_dbg(dev->dev, "Mifare\n"); + rc = pn533_target_found_type_a(&nfc_tgt, apr->tgdata, + apr->ln - 1); + break; + default: + nfc_err(dev->dev, + "Unknown current poll modulation\n"); + rc = -EPROTO; + } + + if (rc) + goto done; + + if (!(nfc_tgt.supported_protocols & dev->poll_protocols)) { + nfc_err(dev->dev, + "The Tg found doesn't have the desired protocol\n"); + rc = -EAGAIN; + goto done; + } + + dev->tgt_available_prots = nfc_tgt.supported_protocols; + apr = (struct pn532_autopoll_resp *) + (apr->tgdata + (apr->ln - 1)); + } + + pn533_poll_reset_mod_list(dev); + nfc_targets_found(dev->nfc_dev, &nfc_tgt, 1); + +done: + dev_kfree_skb(resp); + return rc; + +stop_poll: + nfc_err(dev->dev, "autopoll operation has been stopped\n"); + + pn533_poll_reset_mod_list(dev); + dev->poll_protocols = 0; + return rc; +} + static int pn533_poll_complete(struct pn533 *dev, void *arg, struct sk_buff *resp) { @@ -1532,6 +1653,7 @@ static int pn533_start_poll(struct nfc_dev *nfc_dev, { struct pn533 *dev = nfc_get_drvdata(nfc_dev); struct pn533_poll_modulations *cur_mod; + struct sk_buff *skb; u8 rand_mod; int rc; @@ -1557,9 +1679,73 @@ static int pn533_start_poll(struct nfc_dev *nfc_dev, tm_protocols = 0; } - pn533_poll_create_mod_list(dev, im_protocols, tm_protocols); dev->poll_protocols = im_protocols; dev->listen_protocols = tm_protocols; + if (dev->device_type == PN533_DEVICE_PN532_AUTOPOLL) { + skb = pn533_alloc_skb(dev, 4 + 6); + if (!skb) + return -ENOMEM; + + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_POLLNR_INFINITE; + *((u8 *)skb_put(skb, sizeof(u8))) = PN532_AUTOPOLL_PERIOD; + + if ((im_protocols & NFC_PROTO_MIFARE_MASK) && + (im_protocols & NFC_PROTO_ISO14443_MASK) && + (im_protocols & NFC_PROTO_NFC_DEP_MASK)) + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_GENERIC_106; + else { + if (im_protocols & NFC_PROTO_MIFARE_MASK) + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_MIFARE; + + if (im_protocols & NFC_PROTO_ISO14443_MASK) + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_ISOA; + + if (im_protocols & NFC_PROTO_NFC_DEP_MASK) { + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_DEP_PASSIVE_106; + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_DEP_PASSIVE_212; + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_DEP_PASSIVE_424; + } + } + + if (im_protocols & NFC_PROTO_FELICA_MASK || + im_protocols & NFC_PROTO_NFC_DEP_MASK) { + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_FELICA212; + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_FELICA424; + } + + if (im_protocols & NFC_PROTO_JEWEL_MASK) + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_JEWEL; + + if (im_protocols & NFC_PROTO_ISO14443_B_MASK) + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_ISOB; + + if (tm_protocols) + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_DEP_ACTIVE_106; + + rc = pn533_send_cmd_async(dev, PN533_CMD_IN_AUTOPOLL, skb, + pn533_autopoll_complete, NULL); + + if (rc < 0) + dev_kfree_skb(skb); + else + dev->poll_mod_count++; + + return rc; + } + + pn533_poll_create_mod_list(dev, im_protocols, tm_protocols); /* Do not always start polling from the same modulation */ get_random_bytes(&rand_mod, sizeof(rand_mod)); @@ -2461,7 +2647,8 @@ static int pn533_dev_up(struct nfc_dev *nfc_dev) if (dev->phy_ops->dev_up) dev->phy_ops->dev_up(dev); - if (dev->device_type == PN533_DEVICE_PN532) { + if ((dev->device_type == PN533_DEVICE_PN532) || + (dev->device_type == PN533_DEVICE_PN532_AUTOPOLL)) { int rc = pn532_sam_configuration(nfc_dev); if (rc) @@ -2508,6 +2695,7 @@ static int pn533_setup(struct pn533 *dev) case PN533_DEVICE_PASORI: case PN533_DEVICE_ACR122U: case PN533_DEVICE_PN532: + case PN533_DEVICE_PN532_AUTOPOLL: max_retries.mx_rty_atr = 0x2; max_retries.mx_rty_psl = 0x1; max_retries.mx_rty_passive_act = @@ -2544,6 +2732,7 @@ static int pn533_setup(struct pn533 *dev) switch (dev->device_type) { case PN533_DEVICE_STD: case PN533_DEVICE_PN532: + case PN533_DEVICE_PN532_AUTOPOLL: break; case PN533_DEVICE_PASORI: diff --git a/drivers/nfc/pn533/pn533.h b/drivers/nfc/pn533/pn533.h index 47d4a6bf9420..b66f02a53167 100644 --- a/drivers/nfc/pn533/pn533.h +++ b/drivers/nfc/pn533/pn533.h @@ -6,10 +6,11 @@ * Copyright (C) 2012-2013 Tieto Poland */ -#define PN533_DEVICE_STD 0x1 -#define PN533_DEVICE_PASORI 0x2 -#define PN533_DEVICE_ACR122U 0x3 -#define PN533_DEVICE_PN532 0x4 +#define PN533_DEVICE_STD 0x1 +#define PN533_DEVICE_PASORI 0x2 +#define PN533_DEVICE_ACR122U 0x3 +#define PN533_DEVICE_PN532 0x4 +#define PN533_DEVICE_PN532_AUTOPOLL 0x5 #define PN533_ALL_PROTOCOLS (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK |\ NFC_PROTO_FELICA_MASK | NFC_PROTO_ISO14443_MASK |\ @@ -75,6 +76,7 @@ #define PN533_CMD_IN_ATR 0x50 #define PN533_CMD_IN_RELEASE 0x52 #define PN533_CMD_IN_JUMP_FOR_DEP 0x56 +#define PN533_CMD_IN_AUTOPOLL 0x60 #define PN533_CMD_TG_INIT_AS_TARGET 0x8c #define PN533_CMD_TG_GET_DATA 0x86 -- cgit v1.2.3-59-g8ed1b From 1e37be7d27d086ca72c38af14a9783eb9d7e9fa9 Mon Sep 17 00:00:00 2001 From: Lars Poeschel Date: Wed, 13 Nov 2019 14:50:22 +0100 Subject: nfc: pn533: pn533_phy_ops dev_[up, down] return int Change dev_up and dev_down functions of struct pn533_phy_ops to return int. This way the pn533 core can report errors in the phy layer to upper layers. The only user of this is currently uart.c and it is changed to report the error of a possibly failing call to serdev_device_open. Reported-by: coverity-bot Addresses-Coverity-ID: 1487395 ("Error handling issues") Fixes: c656aa4c27b1 ("nfc: pn533: add UART phy driver") Signed-off-by: Lars Poeschel Signed-off-by: David S. Miller --- drivers/nfc/pn533/pn533.c | 12 ++++++++---- drivers/nfc/pn533/pn533.h | 4 ++-- drivers/nfc/pn533/uart.c | 13 ++++++++++--- 3 files changed, 20 insertions(+), 9 deletions(-) (limited to 'drivers/nfc/pn533/pn533.c') diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index aa766e7ece70..346e084387f7 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -2643,13 +2643,17 @@ static int pn532_sam_configuration(struct nfc_dev *nfc_dev) static int pn533_dev_up(struct nfc_dev *nfc_dev) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); + int rc; - if (dev->phy_ops->dev_up) - dev->phy_ops->dev_up(dev); + if (dev->phy_ops->dev_up) { + rc = dev->phy_ops->dev_up(dev); + if (rc) + return rc; + } if ((dev->device_type == PN533_DEVICE_PN532) || (dev->device_type == PN533_DEVICE_PN532_AUTOPOLL)) { - int rc = pn532_sam_configuration(nfc_dev); + rc = pn532_sam_configuration(nfc_dev); if (rc) return rc; @@ -2665,7 +2669,7 @@ static int pn533_dev_down(struct nfc_dev *nfc_dev) ret = pn533_rf_field(nfc_dev, 0); if (dev->phy_ops->dev_down && !ret) - dev->phy_ops->dev_down(dev); + ret = dev->phy_ops->dev_down(dev); return ret; } diff --git a/drivers/nfc/pn533/pn533.h b/drivers/nfc/pn533/pn533.h index b66f02a53167..5f94f38a2a08 100644 --- a/drivers/nfc/pn533/pn533.h +++ b/drivers/nfc/pn533/pn533.h @@ -224,8 +224,8 @@ struct pn533_phy_ops { * bring up it's interface to the chip and have it suspended for power * saving reasons otherwise. */ - void (*dev_up)(struct pn533 *priv); - void (*dev_down)(struct pn533 *priv); + int (*dev_up)(struct pn533 *priv); + int (*dev_down)(struct pn533 *priv); }; diff --git a/drivers/nfc/pn533/uart.c b/drivers/nfc/pn533/uart.c index 46e5ff16f699..a0665d8ea85b 100644 --- a/drivers/nfc/pn533/uart.c +++ b/drivers/nfc/pn533/uart.c @@ -100,20 +100,27 @@ static void pn532_uart_abort_cmd(struct pn533 *dev, gfp_t flags) pn533_recv_frame(dev, NULL, -ENOENT); } -static void pn532_dev_up(struct pn533 *dev) +static int pn532_dev_up(struct pn533 *dev) { struct pn532_uart_phy *pn532 = dev->phy; + int ret = 0; + + ret = serdev_device_open(pn532->serdev); + if (ret) + return ret; - serdev_device_open(pn532->serdev); pn532->send_wakeup = PN532_SEND_LAST_WAKEUP; + return ret; } -static void pn532_dev_down(struct pn533 *dev) +static int pn532_dev_down(struct pn533 *dev) { struct pn532_uart_phy *pn532 = dev->phy; serdev_device_close(pn532->serdev); pn532->send_wakeup = PN532_SEND_WAKEUP; + + return 0; } static struct pn533_phy_ops uart_phy_ops = { -- cgit v1.2.3-59-g8ed1b