Skip to content

Commit 843cc92

Browse files
poescheldavem330
authored andcommitted
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 32ecc75 ("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 <[email protected]> Cc: Claudiu Beznea <[email protected]> Cc: Jakub Kicinski <[email protected]> Signed-off-by: Lars Poeschel <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0bf2840 commit 843cc92

File tree

4 files changed

+80
-52
lines changed

4 files changed

+80
-52
lines changed

drivers/nfc/pn533/i2c.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -193,19 +193,20 @@ static int pn533_i2c_probe(struct i2c_client *client,
193193
phy->i2c_dev = client;
194194
i2c_set_clientdata(client, phy);
195195

196-
priv = pn533_register_device(PN533_DEVICE_PN532,
197-
PN533_NO_TYPE_B_PROTOCOLS,
198-
PN533_PROTO_REQ_ACK_RESP,
199-
phy, &i2c_phy_ops, NULL,
200-
&phy->i2c_dev->dev,
201-
&client->dev);
196+
priv = pn53x_common_init(PN533_DEVICE_PN532,
197+
PN533_PROTO_REQ_ACK_RESP,
198+
phy, &i2c_phy_ops, NULL,
199+
&phy->i2c_dev->dev);
202200

203201
if (IS_ERR(priv)) {
204202
r = PTR_ERR(priv);
205203
return r;
206204
}
207205

208206
phy->priv = priv;
207+
r = pn532_i2c_nfc_alloc(priv, PN533_NO_TYPE_B_PROTOCOLS, &client->dev);
208+
if (r)
209+
goto nfc_alloc_err;
209210

210211
r = request_threaded_irq(client->irq, NULL, pn533_i2c_irq_thread_fn,
211212
IRQF_TRIGGER_FALLING |
@@ -220,13 +221,20 @@ static int pn533_i2c_probe(struct i2c_client *client,
220221
if (r)
221222
goto fn_setup_err;
222223

223-
return 0;
224+
r = nfc_register_device(priv->nfc_dev);
225+
if (r)
226+
goto fn_setup_err;
227+
228+
return r;
224229

225230
fn_setup_err:
226231
free_irq(client->irq, phy);
227232

228233
irq_rqst_err:
229-
pn533_unregister_device(phy->priv);
234+
nfc_free_device(priv->nfc_dev);
235+
236+
nfc_alloc_err:
237+
pn53x_common_clean(phy->priv);
230238

231239
return r;
232240
}
@@ -239,7 +247,8 @@ static int pn533_i2c_remove(struct i2c_client *client)
239247

240248
free_irq(client->irq, phy);
241249

242-
pn533_unregister_device(phy->priv);
250+
pn53x_unregister_nfc(phy->priv);
251+
pn53x_common_clean(phy->priv);
243252

244253
return 0;
245254
}

drivers/nfc/pn533/pn533.c

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2590,14 +2590,12 @@ int pn533_finalize_setup(struct pn533 *dev)
25902590
}
25912591
EXPORT_SYMBOL_GPL(pn533_finalize_setup);
25922592

2593-
struct pn533 *pn533_register_device(u32 device_type,
2594-
u32 protocols,
2593+
struct pn533 *pn53x_common_init(u32 device_type,
25952594
enum pn533_protocol_type protocol_type,
25962595
void *phy,
25972596
struct pn533_phy_ops *phy_ops,
25982597
struct pn533_frame_ops *fops,
2599-
struct device *dev,
2600-
struct device *parent)
2598+
struct device *dev)
26012599
{
26022600
struct pn533 *priv;
26032601
int rc = -ENOMEM;
@@ -2638,43 +2636,18 @@ struct pn533 *pn533_register_device(u32 device_type,
26382636
skb_queue_head_init(&priv->fragment_skb);
26392637

26402638
INIT_LIST_HEAD(&priv->cmd_queue);
2641-
2642-
priv->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols,
2643-
priv->ops->tx_header_len +
2644-
PN533_CMD_DATAEXCH_HEAD_LEN,
2645-
priv->ops->tx_tail_len);
2646-
if (!priv->nfc_dev) {
2647-
rc = -ENOMEM;
2648-
goto destroy_wq;
2649-
}
2650-
2651-
nfc_set_parent_dev(priv->nfc_dev, parent);
2652-
nfc_set_drvdata(priv->nfc_dev, priv);
2653-
2654-
rc = nfc_register_device(priv->nfc_dev);
2655-
if (rc)
2656-
goto free_nfc_dev;
2657-
26582639
return priv;
26592640

2660-
free_nfc_dev:
2661-
nfc_free_device(priv->nfc_dev);
2662-
2663-
destroy_wq:
2664-
destroy_workqueue(priv->wq);
26652641
error:
26662642
kfree(priv);
26672643
return ERR_PTR(rc);
26682644
}
2669-
EXPORT_SYMBOL_GPL(pn533_register_device);
2645+
EXPORT_SYMBOL_GPL(pn53x_common_init);
26702646

2671-
void pn533_unregister_device(struct pn533 *priv)
2647+
void pn53x_common_clean(struct pn533 *priv)
26722648
{
26732649
struct pn533_cmd *cmd, *n;
26742650

2675-
nfc_unregister_device(priv->nfc_dev);
2676-
nfc_free_device(priv->nfc_dev);
2677-
26782651
flush_delayed_work(&priv->poll_work);
26792652
destroy_workqueue(priv->wq);
26802653

@@ -2689,8 +2662,47 @@ void pn533_unregister_device(struct pn533 *priv)
26892662

26902663
kfree(priv);
26912664
}
2692-
EXPORT_SYMBOL_GPL(pn533_unregister_device);
2665+
EXPORT_SYMBOL_GPL(pn53x_common_clean);
2666+
2667+
int pn532_i2c_nfc_alloc(struct pn533 *priv, u32 protocols,
2668+
struct device *parent)
2669+
{
2670+
priv->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols,
2671+
priv->ops->tx_header_len +
2672+
PN533_CMD_DATAEXCH_HEAD_LEN,
2673+
priv->ops->tx_tail_len);
2674+
if (!priv->nfc_dev)
2675+
return -ENOMEM;
2676+
2677+
nfc_set_parent_dev(priv->nfc_dev, parent);
2678+
nfc_set_drvdata(priv->nfc_dev, priv);
2679+
return 0;
2680+
}
2681+
EXPORT_SYMBOL_GPL(pn532_i2c_nfc_alloc);
2682+
2683+
int pn53x_register_nfc(struct pn533 *priv, u32 protocols,
2684+
struct device *parent)
2685+
{
2686+
int rc;
2687+
2688+
rc = pn532_i2c_nfc_alloc(priv, protocols, parent);
2689+
if (rc)
2690+
return rc;
2691+
2692+
rc = nfc_register_device(priv->nfc_dev);
2693+
if (rc)
2694+
nfc_free_device(priv->nfc_dev);
2695+
2696+
return rc;
2697+
}
2698+
EXPORT_SYMBOL_GPL(pn53x_register_nfc);
26932699

2700+
void pn53x_unregister_nfc(struct pn533 *priv)
2701+
{
2702+
nfc_unregister_device(priv->nfc_dev);
2703+
nfc_free_device(priv->nfc_dev);
2704+
}
2705+
EXPORT_SYMBOL_GPL(pn53x_unregister_nfc);
26942706

26952707
MODULE_AUTHOR("Lauro Ramos Venancio <[email protected]>");
26962708
MODULE_AUTHOR("Aloisio Almeida Jr <[email protected]>");

drivers/nfc/pn533/pn533.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -219,18 +219,21 @@ struct pn533_phy_ops {
219219
};
220220

221221

222-
struct pn533 *pn533_register_device(u32 device_type,
223-
u32 protocols,
222+
struct pn533 *pn53x_common_init(u32 device_type,
224223
enum pn533_protocol_type protocol_type,
225224
void *phy,
226225
struct pn533_phy_ops *phy_ops,
227226
struct pn533_frame_ops *fops,
228-
struct device *dev,
229-
struct device *parent);
227+
struct device *dev);
230228

231229
int pn533_finalize_setup(struct pn533 *dev);
232-
void pn533_unregister_device(struct pn533 *priv);
230+
void pn53x_common_clean(struct pn533 *priv);
233231
void pn533_recv_frame(struct pn533 *dev, struct sk_buff *skb, int status);
232+
int pn532_i2c_nfc_alloc(struct pn533 *priv, u32 protocols,
233+
struct device *parent);
234+
int pn53x_register_nfc(struct pn533 *priv, u32 protocols,
235+
struct device *parent);
236+
void pn53x_unregister_nfc(struct pn533 *priv);
234237

235238
bool pn533_rx_frame_is_cmd_response(struct pn533 *dev, void *frame);
236239
bool pn533_rx_frame_is_ack(void *_frame);

drivers/nfc/pn533/usb.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -534,9 +534,9 @@ static int pn533_usb_probe(struct usb_interface *interface,
534534
goto error;
535535
}
536536

537-
priv = pn533_register_device(id->driver_info, protocols, protocol_type,
537+
priv = pn53x_common_init(id->driver_info, protocol_type,
538538
phy, &usb_phy_ops, fops,
539-
&phy->udev->dev, &interface->dev);
539+
&phy->udev->dev);
540540

541541
if (IS_ERR(priv)) {
542542
rc = PTR_ERR(priv);
@@ -547,14 +547,17 @@ static int pn533_usb_probe(struct usb_interface *interface,
547547

548548
rc = pn533_finalize_setup(priv);
549549
if (rc)
550-
goto err_deregister;
550+
goto err_clean;
551551

552552
usb_set_intfdata(interface, phy);
553+
rc = pn53x_register_nfc(priv, protocols, &interface->dev);
554+
if (rc)
555+
goto err_clean;
553556

554557
return 0;
555558

556-
err_deregister:
557-
pn533_unregister_device(phy->priv);
559+
err_clean:
560+
pn53x_common_clean(priv);
558561
error:
559562
usb_kill_urb(phy->in_urb);
560563
usb_kill_urb(phy->out_urb);
@@ -577,7 +580,8 @@ static void pn533_usb_disconnect(struct usb_interface *interface)
577580
if (!phy)
578581
return;
579582

580-
pn533_unregister_device(phy->priv);
583+
pn53x_unregister_nfc(phy->priv);
584+
pn53x_common_clean(phy->priv);
581585

582586
usb_set_intfdata(interface, NULL);
583587

0 commit comments

Comments
 (0)