diff options
| author | Christophe Ricard <christophe.ricard@gmail.com> | 2015-10-25 17:54:39 -0400 |
|---|---|---|
| committer | Samuel Ortiz <sameo@linux.intel.com> | 2015-10-26 22:55:10 -0400 |
| commit | 3648dc6d27f648b8e3ce9b48874627a833d53c3a (patch) | |
| tree | 196aee67d701a3856d0ca3bfed0d43f1de20d0c6 /drivers/nfc | |
| parent | be73c2cbc857a4a3424c0e3cdd70002d5a27a756 (diff) | |
NFC: st-nci: Add ese-present/uicc-present dts properties
In order to align with st21nfca, dts configuration properties
ese_present and uicc_present are made available in st-nci driver.
So far, in early development firmware, because
nci_nfcee_mode_set(DISABLE) was not supported we had to try to
enable it during the secure element discovery phase.
After several trials on commercial and qualified firmware it appears
that nci_nfcee_mode_set(ENABLE) and nci_nfcee_mode_set(DISABLE) are
properly supported.
Such feature also help us to eventually save some time (~5ms) when
only one secure element is connected.
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Christophe Ricard <christophe-h.ricard@st.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/nfc')
| -rw-r--r-- | drivers/nfc/st-nci/core.c | 4 | ||||
| -rw-r--r-- | drivers/nfc/st-nci/i2c.c | 12 | ||||
| -rw-r--r-- | drivers/nfc/st-nci/ndlc.c | 6 | ||||
| -rw-r--r-- | drivers/nfc/st-nci/ndlc.h | 5 | ||||
| -rw-r--r-- | drivers/nfc/st-nci/se.c | 98 | ||||
| -rw-r--r-- | drivers/nfc/st-nci/spi.c | 12 | ||||
| -rw-r--r-- | drivers/nfc/st-nci/st-nci.h | 13 |
7 files changed, 105 insertions, 45 deletions
diff --git a/drivers/nfc/st-nci/core.c b/drivers/nfc/st-nci/core.c index 73d36dd8345c..c693128ee6fb 100644 --- a/drivers/nfc/st-nci/core.c +++ b/drivers/nfc/st-nci/core.c | |||
| @@ -123,7 +123,7 @@ static struct nci_ops st_nci_ops = { | |||
| 123 | }; | 123 | }; |
| 124 | 124 | ||
| 125 | int st_nci_probe(struct llt_ndlc *ndlc, int phy_headroom, | 125 | int st_nci_probe(struct llt_ndlc *ndlc, int phy_headroom, |
| 126 | int phy_tailroom) | 126 | int phy_tailroom, struct st_nci_se_status *se_status) |
| 127 | { | 127 | { |
| 128 | struct st_nci_info *info; | 128 | struct st_nci_info *info; |
| 129 | int r; | 129 | int r; |
| @@ -164,7 +164,7 @@ int st_nci_probe(struct llt_ndlc *ndlc, int phy_headroom, | |||
| 164 | goto err_reg_dev; | 164 | goto err_reg_dev; |
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | return st_nci_se_init(ndlc->ndev); | 167 | return st_nci_se_init(ndlc->ndev, se_status); |
| 168 | 168 | ||
| 169 | err_reg_dev: | 169 | err_reg_dev: |
| 170 | nci_free_device(ndlc->ndev); | 170 | nci_free_device(ndlc->ndev); |
diff --git a/drivers/nfc/st-nci/i2c.c b/drivers/nfc/st-nci/i2c.c index 02e585f2be74..172cbc34cc9f 100644 --- a/drivers/nfc/st-nci/i2c.c +++ b/drivers/nfc/st-nci/i2c.c | |||
| @@ -52,6 +52,8 @@ struct st_nci_i2c_phy { | |||
| 52 | 52 | ||
| 53 | unsigned int gpio_reset; | 53 | unsigned int gpio_reset; |
| 54 | unsigned int irq_polarity; | 54 | unsigned int irq_polarity; |
| 55 | |||
| 56 | struct st_nci_se_status se_status; | ||
| 55 | }; | 57 | }; |
| 56 | 58 | ||
| 57 | #define I2C_DUMP_SKB(info, skb) \ | 59 | #define I2C_DUMP_SKB(info, skb) \ |
| @@ -245,6 +247,11 @@ static int st_nci_i2c_of_request_resources(struct i2c_client *client) | |||
| 245 | 247 | ||
| 246 | phy->irq_polarity = irq_get_trigger_type(client->irq); | 248 | phy->irq_polarity = irq_get_trigger_type(client->irq); |
| 247 | 249 | ||
| 250 | phy->se_status.is_ese_present = | ||
| 251 | of_property_read_bool(pp, "ese-present"); | ||
| 252 | phy->se_status.is_uicc_present = | ||
| 253 | of_property_read_bool(pp, "uicc-present"); | ||
| 254 | |||
| 248 | return 0; | 255 | return 0; |
| 249 | } | 256 | } |
| 250 | #else | 257 | #else |
| @@ -277,6 +284,9 @@ static int st_nci_i2c_request_resources(struct i2c_client *client) | |||
| 277 | return r; | 284 | return r; |
| 278 | } | 285 | } |
| 279 | 286 | ||
| 287 | phy->se_status.is_ese_present = pdata->is_ese_present; | ||
| 288 | phy->se_status.is_uicc_present = pdata->is_uicc_present; | ||
| 289 | |||
| 280 | return 0; | 290 | return 0; |
| 281 | } | 291 | } |
| 282 | 292 | ||
| @@ -326,7 +336,7 @@ static int st_nci_i2c_probe(struct i2c_client *client, | |||
| 326 | 336 | ||
| 327 | r = ndlc_probe(phy, &i2c_phy_ops, &client->dev, | 337 | r = ndlc_probe(phy, &i2c_phy_ops, &client->dev, |
| 328 | ST_NCI_FRAME_HEADROOM, ST_NCI_FRAME_TAILROOM, | 338 | ST_NCI_FRAME_HEADROOM, ST_NCI_FRAME_TAILROOM, |
| 329 | &phy->ndlc); | 339 | &phy->ndlc, &phy->se_status); |
| 330 | if (r < 0) { | 340 | if (r < 0) { |
| 331 | nfc_err(&client->dev, "Unable to register ndlc layer\n"); | 341 | nfc_err(&client->dev, "Unable to register ndlc layer\n"); |
| 332 | return r; | 342 | return r; |
diff --git a/drivers/nfc/st-nci/ndlc.c b/drivers/nfc/st-nci/ndlc.c index fb50007ac32a..0884b11001ef 100644 --- a/drivers/nfc/st-nci/ndlc.c +++ b/drivers/nfc/st-nci/ndlc.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <net/nfc/nci_core.h> | 20 | #include <net/nfc/nci_core.h> |
| 21 | 21 | ||
| 22 | #include "st-nci.h" | 22 | #include "st-nci.h" |
| 23 | #include "ndlc.h" | ||
| 23 | 24 | ||
| 24 | #define NDLC_TIMER_T1 100 | 25 | #define NDLC_TIMER_T1 100 |
| 25 | #define NDLC_TIMER_T1_WAIT 400 | 26 | #define NDLC_TIMER_T1_WAIT 400 |
| @@ -265,7 +266,8 @@ static void ndlc_t2_timeout(unsigned long data) | |||
| 265 | } | 266 | } |
| 266 | 267 | ||
| 267 | int ndlc_probe(void *phy_id, struct nfc_phy_ops *phy_ops, struct device *dev, | 268 | int ndlc_probe(void *phy_id, struct nfc_phy_ops *phy_ops, struct device *dev, |
| 268 | int phy_headroom, int phy_tailroom, struct llt_ndlc **ndlc_id) | 269 | int phy_headroom, int phy_tailroom, struct llt_ndlc **ndlc_id, |
| 270 | struct st_nci_se_status *se_status) | ||
| 269 | { | 271 | { |
| 270 | struct llt_ndlc *ndlc; | 272 | struct llt_ndlc *ndlc; |
| 271 | 273 | ||
| @@ -295,7 +297,7 @@ int ndlc_probe(void *phy_id, struct nfc_phy_ops *phy_ops, struct device *dev, | |||
| 295 | 297 | ||
| 296 | INIT_WORK(&ndlc->sm_work, llt_ndlc_sm_work); | 298 | INIT_WORK(&ndlc->sm_work, llt_ndlc_sm_work); |
| 297 | 299 | ||
| 298 | return st_nci_probe(ndlc, phy_headroom, phy_tailroom); | 300 | return st_nci_probe(ndlc, phy_headroom, phy_tailroom, se_status); |
| 299 | } | 301 | } |
| 300 | EXPORT_SYMBOL(ndlc_probe); | 302 | EXPORT_SYMBOL(ndlc_probe); |
| 301 | 303 | ||
diff --git a/drivers/nfc/st-nci/ndlc.h b/drivers/nfc/st-nci/ndlc.h index 6361005ef003..bdf78ffd5bb7 100644 --- a/drivers/nfc/st-nci/ndlc.h +++ b/drivers/nfc/st-nci/ndlc.h | |||
| @@ -22,6 +22,8 @@ | |||
| 22 | #include <linux/skbuff.h> | 22 | #include <linux/skbuff.h> |
| 23 | #include <net/nfc/nfc.h> | 23 | #include <net/nfc/nfc.h> |
| 24 | 24 | ||
| 25 | struct st_nci_se_status; | ||
| 26 | |||
| 25 | /* Low Level Transport description */ | 27 | /* Low Level Transport description */ |
| 26 | struct llt_ndlc { | 28 | struct llt_ndlc { |
| 27 | struct nci_dev *ndev; | 29 | struct nci_dev *ndev; |
| @@ -55,6 +57,7 @@ void ndlc_close(struct llt_ndlc *ndlc); | |||
| 55 | int ndlc_send(struct llt_ndlc *ndlc, struct sk_buff *skb); | 57 | int ndlc_send(struct llt_ndlc *ndlc, struct sk_buff *skb); |
| 56 | void ndlc_recv(struct llt_ndlc *ndlc, struct sk_buff *skb); | 58 | void ndlc_recv(struct llt_ndlc *ndlc, struct sk_buff *skb); |
| 57 | int ndlc_probe(void *phy_id, struct nfc_phy_ops *phy_ops, struct device *dev, | 59 | int ndlc_probe(void *phy_id, struct nfc_phy_ops *phy_ops, struct device *dev, |
| 58 | int phy_headroom, int phy_tailroom, struct llt_ndlc **ndlc_id); | 60 | int phy_headroom, int phy_tailroom, struct llt_ndlc **ndlc_id, |
| 61 | struct st_nci_se_status *se_status); | ||
| 59 | void ndlc_remove(struct llt_ndlc *ndlc); | 62 | void ndlc_remove(struct llt_ndlc *ndlc); |
| 60 | #endif /* __LOCAL_NDLC_H__ */ | 63 | #endif /* __LOCAL_NDLC_H__ */ |
diff --git a/drivers/nfc/st-nci/se.c b/drivers/nfc/st-nci/se.c index 281288484794..147e2d904c63 100644 --- a/drivers/nfc/st-nci/se.c +++ b/drivers/nfc/st-nci/se.c | |||
| @@ -419,12 +419,8 @@ void st_nci_hci_cmd_received(struct nci_dev *ndev, u8 pipe, u8 cmd, | |||
| 419 | } | 419 | } |
| 420 | EXPORT_SYMBOL_GPL(st_nci_hci_cmd_received); | 420 | EXPORT_SYMBOL_GPL(st_nci_hci_cmd_received); |
| 421 | 421 | ||
| 422 | /* | ||
| 423 | * Remarks: On some early st_nci firmware, nci_nfcee_mode_set(0) | ||
| 424 | * is rejected | ||
| 425 | */ | ||
| 426 | static int st_nci_control_se(struct nci_dev *ndev, u8 se_idx, | 422 | static int st_nci_control_se(struct nci_dev *ndev, u8 se_idx, |
| 427 | u8 state) | 423 | u8 state) |
| 428 | { | 424 | { |
| 429 | struct st_nci_info *info = nci_get_drvdata(ndev); | 425 | struct st_nci_info *info = nci_get_drvdata(ndev); |
| 430 | int r; | 426 | int r; |
| @@ -449,7 +445,7 @@ static int st_nci_control_se(struct nci_dev *ndev, u8 se_idx, | |||
| 449 | * retrieve a relevant host list. | 445 | * retrieve a relevant host list. |
| 450 | */ | 446 | */ |
| 451 | reinit_completion(&info->se_info.req_completion); | 447 | reinit_completion(&info->se_info.req_completion); |
| 452 | r = nci_nfcee_mode_set(ndev, se_idx, NCI_NFCEE_ENABLE); | 448 | r = nci_nfcee_mode_set(ndev, se_idx, state); |
| 453 | if (r != NCI_STATUS_OK) | 449 | if (r != NCI_STATUS_OK) |
| 454 | return r; | 450 | return r; |
| 455 | 451 | ||
| @@ -465,7 +461,9 @@ static int st_nci_control_se(struct nci_dev *ndev, u8 se_idx, | |||
| 465 | * There is no possible synchronization to prevent this. | 461 | * There is no possible synchronization to prevent this. |
| 466 | * Adding a small delay is the only way to solve the issue. | 462 | * Adding a small delay is the only way to solve the issue. |
| 467 | */ | 463 | */ |
| 468 | usleep_range(3000, 5000); | 464 | if (info->se_info.se_status->is_ese_present && |
| 465 | info->se_info.se_status->is_uicc_present) | ||
| 466 | usleep_range(3000, 5000); | ||
| 469 | 467 | ||
| 470 | r = nci_hci_get_param(ndev, NCI_HCI_ADMIN_GATE, | 468 | r = nci_hci_get_param(ndev, NCI_HCI_ADMIN_GATE, |
| 471 | NCI_HCI_ADMIN_PARAM_HOST_LIST, &sk_host_list); | 469 | NCI_HCI_ADMIN_PARAM_HOST_LIST, &sk_host_list); |
| @@ -488,11 +486,20 @@ int st_nci_disable_se(struct nci_dev *ndev, u32 se_idx) | |||
| 488 | 486 | ||
| 489 | pr_debug("st_nci_disable_se\n"); | 487 | pr_debug("st_nci_disable_se\n"); |
| 490 | 488 | ||
| 491 | if (se_idx == NFC_SE_EMBEDDED) { | 489 | /* |
| 492 | r = nci_hci_send_event(ndev, ST_NCI_APDU_READER_GATE, | 490 | * According to upper layer, se_idx == NFC_SE_UICC when |
| 493 | ST_NCI_EVT_SE_END_OF_APDU_TRANSFER, NULL, 0); | 491 | * info->se_info.se_status->is_uicc_enable is true should never happen |
| 494 | if (r < 0) | 492 | * Same for eSE. |
| 495 | return r; | 493 | */ |
| 494 | r = st_nci_control_se(ndev, se_idx, ST_NCI_SE_MODE_OFF); | ||
| 495 | if (r < 0) { | ||
| 496 | /* Do best effort to release SWP */ | ||
| 497 | if (se_idx == NFC_SE_EMBEDDED) { | ||
| 498 | r = nci_hci_send_event(ndev, ST_NCI_APDU_READER_GATE, | ||
| 499 | ST_NCI_EVT_SE_END_OF_APDU_TRANSFER, | ||
| 500 | NULL, 0); | ||
| 501 | } | ||
| 502 | return r; | ||
| 496 | } | 503 | } |
| 497 | 504 | ||
| 498 | return 0; | 505 | return 0; |
| @@ -505,11 +512,25 @@ int st_nci_enable_se(struct nci_dev *ndev, u32 se_idx) | |||
| 505 | 512 | ||
| 506 | pr_debug("st_nci_enable_se\n"); | 513 | pr_debug("st_nci_enable_se\n"); |
| 507 | 514 | ||
| 508 | if (se_idx == ST_NCI_HCI_HOST_ID_ESE) { | 515 | /* |
| 516 | * According to upper layer, se_idx == NFC_SE_UICC when | ||
| 517 | * info->se_info.se_status->is_uicc_enable is true should never happen. | ||
| 518 | * Same for eSE. | ||
| 519 | */ | ||
| 520 | r = st_nci_control_se(ndev, se_idx, ST_NCI_SE_MODE_ON); | ||
| 521 | if (r == ST_NCI_HCI_HOST_ID_ESE) { | ||
| 522 | st_nci_se_get_atr(ndev); | ||
| 509 | r = nci_hci_send_event(ndev, ST_NCI_APDU_READER_GATE, | 523 | r = nci_hci_send_event(ndev, ST_NCI_APDU_READER_GATE, |
| 510 | ST_NCI_EVT_SE_SOFT_RESET, NULL, 0); | 524 | ST_NCI_EVT_SE_SOFT_RESET, NULL, 0); |
| 511 | if (r < 0) | 525 | } |
| 512 | return r; | 526 | |
| 527 | if (r < 0) { | ||
| 528 | /* | ||
| 529 | * The activation procedure failed, the secure element | ||
| 530 | * is not connected. Remove from the list. | ||
| 531 | */ | ||
| 532 | nfc_remove_se(ndev->nfc_dev, se_idx); | ||
| 533 | return r; | ||
| 513 | } | 534 | } |
| 514 | 535 | ||
| 515 | return 0; | 536 | return 0; |
| @@ -592,8 +613,8 @@ exit: | |||
| 592 | 613 | ||
| 593 | int st_nci_discover_se(struct nci_dev *ndev) | 614 | int st_nci_discover_se(struct nci_dev *ndev) |
| 594 | { | 615 | { |
| 595 | u8 param[2]; | 616 | u8 white_list[2]; |
| 596 | int r; | 617 | int r, wl_size = 0; |
| 597 | int se_count = 0; | 618 | int se_count = 0; |
| 598 | struct st_nci_info *info = nci_get_drvdata(ndev); | 619 | struct st_nci_info *info = nci_get_drvdata(ndev); |
| 599 | 620 | ||
| @@ -606,29 +627,34 @@ int st_nci_discover_se(struct nci_dev *ndev) | |||
| 606 | if (test_bit(ST_NCI_FACTORY_MODE, &info->flags)) | 627 | if (test_bit(ST_NCI_FACTORY_MODE, &info->flags)) |
| 607 | return 0; | 628 | return 0; |
| 608 | 629 | ||
| 609 | param[0] = ST_NCI_UICC_HOST_ID; | 630 | if (info->se_info.se_status->is_ese_present && |
| 610 | param[1] = ST_NCI_HCI_HOST_ID_ESE; | 631 | info->se_info.se_status->is_uicc_present) { |
| 611 | r = nci_hci_set_param(ndev, NCI_HCI_ADMIN_GATE, | 632 | white_list[wl_size++] = ST_NCI_UICC_HOST_ID; |
| 612 | NCI_HCI_ADMIN_PARAM_WHITELIST, | 633 | white_list[wl_size++] = ST_NCI_ESE_HOST_ID; |
| 613 | param, sizeof(param)); | 634 | } else if (!info->se_info.se_status->is_ese_present && |
| 614 | if (r != NCI_HCI_ANY_OK) | 635 | info->se_info.se_status->is_uicc_present) { |
| 615 | return r; | 636 | white_list[wl_size++] = ST_NCI_UICC_HOST_ID; |
| 637 | } else if (info->se_info.se_status->is_ese_present && | ||
| 638 | !info->se_info.se_status->is_uicc_present) { | ||
| 639 | white_list[wl_size++] = ST_NCI_ESE_HOST_ID; | ||
| 640 | } | ||
| 641 | |||
| 642 | if (wl_size) { | ||
| 643 | r = nci_hci_set_param(ndev, NCI_HCI_ADMIN_GATE, | ||
| 644 | NCI_HCI_ADMIN_PARAM_WHITELIST, | ||
| 645 | white_list, wl_size); | ||
| 646 | if (r != NCI_HCI_ANY_OK) | ||
| 647 | return r; | ||
| 648 | } | ||
| 616 | 649 | ||
| 617 | r = st_nci_control_se(ndev, ST_NCI_UICC_HOST_ID, | 650 | if (info->se_info.se_status->is_uicc_present) { |
| 618 | ST_NCI_SE_MODE_ON); | ||
| 619 | if (r == ST_NCI_UICC_HOST_ID) { | ||
| 620 | nfc_add_se(ndev->nfc_dev, ST_NCI_UICC_HOST_ID, NFC_SE_UICC); | 651 | nfc_add_se(ndev->nfc_dev, ST_NCI_UICC_HOST_ID, NFC_SE_UICC); |
| 621 | se_count++; | 652 | se_count++; |
| 622 | } | 653 | } |
| 623 | 654 | ||
| 624 | /* Try to enable eSE in order to check availability */ | 655 | if (info->se_info.se_status->is_ese_present) { |
| 625 | r = st_nci_control_se(ndev, ST_NCI_HCI_HOST_ID_ESE, | 656 | nfc_add_se(ndev->nfc_dev, ST_NCI_ESE_HOST_ID, NFC_SE_EMBEDDED); |
| 626 | ST_NCI_SE_MODE_ON); | ||
| 627 | if (r == ST_NCI_HCI_HOST_ID_ESE) { | ||
| 628 | nfc_add_se(ndev->nfc_dev, ST_NCI_HCI_HOST_ID_ESE, | ||
| 629 | NFC_SE_EMBEDDED); | ||
| 630 | se_count++; | 657 | se_count++; |
| 631 | st_nci_se_get_atr(ndev); | ||
| 632 | } | 658 | } |
| 633 | 659 | ||
| 634 | return !se_count; | 660 | return !se_count; |
| @@ -701,7 +727,7 @@ static void st_nci_se_activation_timeout(unsigned long data) | |||
| 701 | complete(&info->se_info.req_completion); | 727 | complete(&info->se_info.req_completion); |
| 702 | } | 728 | } |
| 703 | 729 | ||
| 704 | int st_nci_se_init(struct nci_dev *ndev) | 730 | int st_nci_se_init(struct nci_dev *ndev, struct st_nci_se_status *se_status) |
| 705 | { | 731 | { |
| 706 | struct st_nci_info *info = nci_get_drvdata(ndev); | 732 | struct st_nci_info *info = nci_get_drvdata(ndev); |
| 707 | 733 | ||
| @@ -723,6 +749,8 @@ int st_nci_se_init(struct nci_dev *ndev) | |||
| 723 | info->se_info.wt_timeout = | 749 | info->se_info.wt_timeout = |
| 724 | ST_NCI_BWI_TO_TIMEOUT(ST_NCI_ATR_DEFAULT_BWI); | 750 | ST_NCI_BWI_TO_TIMEOUT(ST_NCI_ATR_DEFAULT_BWI); |
| 725 | 751 | ||
| 752 | info->se_info.se_status = se_status; | ||
| 753 | |||
| 726 | return 0; | 754 | return 0; |
| 727 | } | 755 | } |
| 728 | EXPORT_SYMBOL(st_nci_se_init); | 756 | EXPORT_SYMBOL(st_nci_se_init); |
diff --git a/drivers/nfc/st-nci/spi.c b/drivers/nfc/st-nci/spi.c index b43f448b8d78..889720336474 100644 --- a/drivers/nfc/st-nci/spi.c +++ b/drivers/nfc/st-nci/spi.c | |||
| @@ -53,6 +53,8 @@ struct st_nci_spi_phy { | |||
| 53 | 53 | ||
| 54 | unsigned int gpio_reset; | 54 | unsigned int gpio_reset; |
| 55 | unsigned int irq_polarity; | 55 | unsigned int irq_polarity; |
| 56 | |||
| 57 | struct st_nci_se_status se_status; | ||
| 56 | }; | 58 | }; |
| 57 | 59 | ||
| 58 | #define SPI_DUMP_SKB(info, skb) \ | 60 | #define SPI_DUMP_SKB(info, skb) \ |
| @@ -260,6 +262,11 @@ static int st_nci_spi_of_request_resources(struct spi_device *dev) | |||
| 260 | 262 | ||
| 261 | phy->irq_polarity = irq_get_trigger_type(dev->irq); | 263 | phy->irq_polarity = irq_get_trigger_type(dev->irq); |
| 262 | 264 | ||
| 265 | phy->se_status.is_ese_present = | ||
| 266 | of_property_read_bool(pp, "ese-present"); | ||
| 267 | phy->se_status.is_uicc_present = | ||
| 268 | of_property_read_bool(pp, "uicc-present"); | ||
| 269 | |||
| 263 | return 0; | 270 | return 0; |
| 264 | } | 271 | } |
| 265 | #else | 272 | #else |
| @@ -292,6 +299,9 @@ static int st_nci_spi_request_resources(struct spi_device *dev) | |||
| 292 | return r; | 299 | return r; |
| 293 | } | 300 | } |
| 294 | 301 | ||
| 302 | phy->se_status.is_ese_present = pdata->is_ese_present; | ||
| 303 | phy->se_status.is_uicc_present = pdata->is_uicc_present; | ||
| 304 | |||
| 295 | return 0; | 305 | return 0; |
| 296 | } | 306 | } |
| 297 | 307 | ||
| @@ -342,7 +352,7 @@ static int st_nci_spi_probe(struct spi_device *dev) | |||
| 342 | 352 | ||
| 343 | r = ndlc_probe(phy, &spi_phy_ops, &dev->dev, | 353 | r = ndlc_probe(phy, &spi_phy_ops, &dev->dev, |
| 344 | ST_NCI_FRAME_HEADROOM, ST_NCI_FRAME_TAILROOM, | 354 | ST_NCI_FRAME_HEADROOM, ST_NCI_FRAME_TAILROOM, |
| 345 | &phy->ndlc); | 355 | &phy->ndlc, &phy->se_status); |
| 346 | if (r < 0) { | 356 | if (r < 0) { |
| 347 | nfc_err(&dev->dev, "Unable to register ndlc layer\n"); | 357 | nfc_err(&dev->dev, "Unable to register ndlc layer\n"); |
| 348 | return r; | 358 | return r; |
diff --git a/drivers/nfc/st-nci/st-nci.h b/drivers/nfc/st-nci/st-nci.h index 9c9bb19cc9ff..8b9f77b0249c 100644 --- a/drivers/nfc/st-nci/st-nci.h +++ b/drivers/nfc/st-nci/st-nci.h | |||
| @@ -48,7 +48,13 @@ struct nci_mode_set_rsp { | |||
| 48 | u8 status; | 48 | u8 status; |
| 49 | } __packed; | 49 | } __packed; |
| 50 | 50 | ||
| 51 | struct st_nci_se_status { | ||
| 52 | bool is_ese_present; | ||
| 53 | bool is_uicc_present; | ||
| 54 | }; | ||
| 55 | |||
| 51 | struct st_nci_se_info { | 56 | struct st_nci_se_info { |
| 57 | struct st_nci_se_status *se_status; | ||
| 52 | u8 atr[ST_NCI_ESE_MAX_LENGTH]; | 58 | u8 atr[ST_NCI_ESE_MAX_LENGTH]; |
| 53 | struct completion req_completion; | 59 | struct completion req_completion; |
| 54 | 60 | ||
| @@ -126,15 +132,16 @@ struct st_nci_vendor_info { | |||
| 126 | struct st_nci_info { | 132 | struct st_nci_info { |
| 127 | struct llt_ndlc *ndlc; | 133 | struct llt_ndlc *ndlc; |
| 128 | unsigned long flags; | 134 | unsigned long flags; |
| 135 | |||
| 129 | struct st_nci_se_info se_info; | 136 | struct st_nci_se_info se_info; |
| 130 | struct st_nci_vendor_info vendor_info; | 137 | struct st_nci_vendor_info vendor_info; |
| 131 | }; | 138 | }; |
| 132 | 139 | ||
| 133 | void st_nci_remove(struct nci_dev *ndev); | 140 | void st_nci_remove(struct nci_dev *ndev); |
| 134 | int st_nci_probe(struct llt_ndlc *ndlc, int phy_headroom, | 141 | int st_nci_probe(struct llt_ndlc *ndlc, int phy_headroom, |
| 135 | int phy_tailroom); | 142 | int phy_tailroom, struct st_nci_se_status *se_status); |
| 136 | 143 | ||
| 137 | int st_nci_se_init(struct nci_dev *ndev); | 144 | int st_nci_se_init(struct nci_dev *ndev, struct st_nci_se_status *se_status); |
| 138 | void st_nci_se_deinit(struct nci_dev *ndev); | 145 | void st_nci_se_deinit(struct nci_dev *ndev); |
| 139 | 146 | ||
| 140 | int st_nci_discover_se(struct nci_dev *ndev); | 147 | int st_nci_discover_se(struct nci_dev *ndev); |
| @@ -150,7 +157,7 @@ void st_nci_hci_cmd_received(struct nci_dev *ndev, u8 pipe, u8 cmd, | |||
| 150 | struct sk_buff *skb); | 157 | struct sk_buff *skb); |
| 151 | 158 | ||
| 152 | void st_nci_hci_loopback_event_received(struct nci_dev *ndev, u8 event, | 159 | void st_nci_hci_loopback_event_received(struct nci_dev *ndev, u8 event, |
| 153 | struct sk_buff *skb); | 160 | struct sk_buff *skb); |
| 154 | int st_nci_vendor_cmds_init(struct nci_dev *ndev); | 161 | int st_nci_vendor_cmds_init(struct nci_dev *ndev); |
| 155 | 162 | ||
| 156 | #endif /* __LOCAL_ST_NCI_H_ */ | 163 | #endif /* __LOCAL_ST_NCI_H_ */ |
