Commit a3c5d8fb authored by Christophe Ricard's avatar Christophe Ricard Committed by Samuel Ortiz

NFC: st21nfca: Synchronize i2c Tx and Rx path

Stabilize communication by using a mutex.
This avoids running a write transaction during a read retry or a read
transaction during a write retry.
Signed-off-by: default avatarChristophe Ricard <christophe-h.ricard@st.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent c97ffdbf
...@@ -89,6 +89,7 @@ struct st21nfca_i2c_phy { ...@@ -89,6 +89,7 @@ struct st21nfca_i2c_phy {
* and prevents normal operation. * and prevents normal operation.
*/ */
int hard_fault; int hard_fault;
struct mutex phy_lock;
}; };
static u8 len_seq[] = { 13, 24, 15, 29 }; static u8 len_seq[] = { 13, 24, 15, 29 };
static u16 wait_tab[] = { 2, 3, 5, 15, 20, 40}; static u16 wait_tab[] = { 2, 3, 5, 15, 20, 40};
...@@ -245,11 +246,13 @@ static int st21nfca_hci_i2c_write(void *phy_id, struct sk_buff *skb) ...@@ -245,11 +246,13 @@ static int st21nfca_hci_i2c_write(void *phy_id, struct sk_buff *skb)
* Manage sleep mode * Manage sleep mode
* Try 3 times to send data with delay between each * Try 3 times to send data with delay between each
*/ */
mutex_lock(&phy->phy_lock);
for (i = 0; i < ARRAY_SIZE(wait_tab) && r < 0; i++) { for (i = 0; i < ARRAY_SIZE(wait_tab) && r < 0; i++) {
r = i2c_master_send(client, tmp, j); r = i2c_master_send(client, tmp, j);
if (r < 0) if (r < 0)
msleep(wait_tab[i]); msleep(wait_tab[i]);
} }
mutex_unlock(&phy->phy_lock);
if (r >= 0) { if (r >= 0) {
if (r != j) if (r != j)
...@@ -375,11 +378,13 @@ static int st21nfca_hci_i2c_read(struct st21nfca_i2c_phy *phy, ...@@ -375,11 +378,13 @@ static int st21nfca_hci_i2c_read(struct st21nfca_i2c_phy *phy,
* RF or SWP interface * RF or SWP interface
*/ */
r = 0; r = 0;
mutex_lock(&phy->phy_lock);
for (i = 0; i < ARRAY_SIZE(wait_tab) && r <= 0; i++) { for (i = 0; i < ARRAY_SIZE(wait_tab) && r <= 0; i++) {
r = i2c_master_recv(client, buf, len); r = i2c_master_recv(client, buf, len);
if (r < 0) if (r < 0)
msleep(wait_tab[i]); msleep(wait_tab[i]);
} }
mutex_unlock(&phy->phy_lock);
if (r != len) { if (r != len) {
phy->current_read_len = 0; phy->current_read_len = 0;
...@@ -575,6 +580,7 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, ...@@ -575,6 +580,7 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client,
phy->current_read_len = 0; phy->current_read_len = 0;
phy->crc_trials = 0; phy->crc_trials = 0;
mutex_init(&phy->phy_lock);
i2c_set_clientdata(client, phy); i2c_set_clientdata(client, phy);
pdata = client->dev.platform_data; pdata = client->dev.platform_data;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment