Ver Fonte

Updated corresponding to - NFC_AR_00_E800_12.10.00_OpnSrc

nxf35421 há 3 anos atrás
pai
commit
55d2657f94
4 ficheiros alterados com 87 adições e 39 exclusões
  1. 25 0
      nfc/common.c
  2. 5 3
      nfc/common.h
  3. 28 33
      nfc/common_ese.c
  4. 29 3
      nfc/i2c_drv.c

+ 25 - 0
nfc/common.c

@@ -286,6 +286,31 @@ static int nfc_ioctl_power_states(struct nfc_dev *nfc_dev, unsigned long arg)
 	return ret;
 }
 
+#ifdef CONFIG_COMPAT
+/**
+ * nfc_dev_compat_ioctl - used to set or get data from upper layer.
+ * @pfile   file node for opened device.
+ * @cmd     ioctl type from upper layer.
+ * @arg     ioctl arg from upper layer.
+ *
+ * NFC and ESE Device power control, based on the argument value
+ *
+ * Return: -ENOIOCTLCMD if arg is not supported
+ * 0 if Success(or no issue)
+ * 0 or 1 in case of arg is ESE_GET_PWR/ESE_POWER_STATE
+ * and error ret code otherwise
+ */
+long nfc_dev_compat_ioctl(struct file *pfile, unsigned int cmd,
+		      unsigned long arg)
+{
+	int ret = 0;
+	arg = (compat_u64)arg;
+	pr_debug("%s: cmd = %x arg = %zx\n", __func__, cmd, arg);
+	ret = nfc_dev_ioctl(pfile, cmd, arg);
+	return ret;
+}
+#endif
+
 /**
  * nfc_dev_ioctl - used to set or get data from upper layer.
  * @pfile   file node for opened device.

+ 5 - 3
nfc/common.h

@@ -74,9 +74,9 @@
 
 /* Ioctls */
 /* The type should be aligned with MW HAL definitions */
-#define NFC_SET_PWR			_IOW(NFC_MAGIC, 0x01, long)
-#define ESE_SET_PWR			_IOW(NFC_MAGIC, 0x02, long)
-#define ESE_GET_PWR			_IOR(NFC_MAGIC, 0x03, long)
+#define NFC_SET_PWR			_IOW(NFC_MAGIC, 0x01, uint32_t)
+#define ESE_SET_PWR			_IOW(NFC_MAGIC, 0x02, uint32_t)
+#define ESE_GET_PWR			_IOR(NFC_MAGIC, 0x03, uint32_t)
 
 #define DTS_IRQ_GPIO_STR		"nxp,pn544-irq"
 #define DTS_VEN_GPIO_STR		"nxp,pn544-ven"
@@ -196,6 +196,8 @@ struct nfc_dev {
 int nfc_dev_open(struct inode *inode, struct file *filp);
 int nfc_dev_flush(struct file *pfile, fl_owner_t id);
 int nfc_dev_close(struct inode *inode, struct file *filp);
+long nfc_dev_compat_ioctl(struct file *pfile, unsigned int cmd,
+		      unsigned long arg);
 long nfc_dev_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg);
 int nfc_parse_dt(struct device *dev, struct platform_configs *nfc_configs,
 		 uint8_t interface);

+ 28 - 33
nfc/common_ese.c

@@ -54,7 +54,6 @@ static int send_cold_reset_protection_cmd(struct nfc_dev *nfc_dev,
 	uint8_t *cmd = nfc_dev->write_kbuf;
 	struct cold_reset *cold_reset = &nfc_dev->cold_reset;
 
-	mutex_lock(&nfc_dev->write_mutex);
 	*cmd++ = NCI_PROP_MSG_CMD;
 
 	if (requestType) { /* reset protection */
@@ -84,7 +83,6 @@ static int send_cold_reset_protection_cmd(struct nfc_dev *nfc_dev,
 			 cmd[NCI_HDR_IDX], cmd[NCI_HDR_OID_IDX],
 			 cmd[NCI_PAYLOAD_LEN_IDX]);
 exit:
-	mutex_unlock(&nfc_dev->write_mutex);
 	return ret;
 }
 
@@ -152,7 +150,6 @@ static int perform_cold_reset_protection(struct nfc_dev *nfc_dev,
 	int timeout = 0;
 	char *rsp = nfc_dev->read_kbuf;
 	struct cold_reset *cold_reset = &nfc_dev->cold_reset;
-	bool nfc_dev_opened = false;
 
 	/* check if NFCC not in the FW download or hard reset state */
 	ret = validate_nfc_state_nci(nfc_dev);
@@ -161,10 +158,6 @@ static int perform_cold_reset_protection(struct nfc_dev *nfc_dev,
 		return ret;
 	}
 
-	/* check if NFC is enabled */
-	mutex_lock(&nfc_dev->dev_ref_mutex);
-	nfc_dev_opened = (nfc_dev->dev_ref_count > 0) ? true : false;
-
 	/* check if NFCC not in the FW download or hard reset state */
 	ret = validate_cold_reset_protection_request(cold_reset, arg);
 	if (ret < 0) {
@@ -178,21 +171,23 @@ static int perform_cold_reset_protection(struct nfc_dev *nfc_dev,
 		ret = -EBUSY;
 		goto err;
 	}
-	/* set default value for status as failure */
-	cold_reset->status = -EIO;
-	cold_reset->rsp_pending = true;
 
-	/* enable interrupt before sending cmd, when devnode not opened by HAL */
-	if (!nfc_dev_opened)
-		nfc_dev->nfc_enable_intr(nfc_dev);
+	/* enable interrupt if not enabled incase when devnode not opened by HAL */
+	nfc_dev->nfc_enable_intr(nfc_dev);
 
+	mutex_lock(&nfc_dev->write_mutex);
+	/* write api has 15ms maximum wait to clear any pending read before */
+	cold_reset->status = -EIO;
+	cold_reset->rsp_pending = true;
 	ret = send_cold_reset_protection_cmd(nfc_dev, IS_RST_PROT_REQ(arg));
 	if (ret < 0) {
+		mutex_unlock(&nfc_dev->write_mutex);
+		cold_reset->rsp_pending = false;
 		pr_err("%s: failed to send cold reset/protection cmd\n",
 		       __func__);
-		cold_reset->rsp_pending = false;
 		goto err;
 	}
+
 	ret = 0;
 	/* start the cold reset guard timer */
 	if (IS_CLD_RST_REQ(arg)) {
@@ -200,6 +195,7 @@ static int perform_cold_reset_protection(struct nfc_dev *nfc_dev,
 		if (!(cold_reset->reset_protection && IS_SRC_NFC(arg))) {
 			ret = start_cold_reset_guard_timer(cold_reset);
 			if (ret) {
+				mutex_unlock(&nfc_dev->write_mutex);
 				pr_err("%s: error in mod_timer\n", __func__);
 				goto err;
 			}
@@ -208,28 +204,27 @@ static int perform_cold_reset_protection(struct nfc_dev *nfc_dev,
 
 	timeout = NCI_CMD_RSP_TIMEOUT_MS;
 	do {
+		/* call read api directly if reader thread is not blocked */
+		if (mutex_trylock(&nfc_dev->read_mutex)) {
+			pr_debug("%s: reader thread not pending\n", __func__);
+			ret = nfc_dev->nfc_read(nfc_dev, rsp, 3,
+						timeout);
+			mutex_unlock(&nfc_dev->read_mutex);
+			if (!ret)
+				break;
+			usleep_range(READ_RETRY_WAIT_TIME_US,
+					 READ_RETRY_WAIT_TIME_US + 500);
 		/* Read pending response form the HAL service */
-		if (nfc_dev_opened) {
-			if (!wait_event_interruptible_timeout(
-				    cold_reset->read_wq,
-				    cold_reset->rsp_pending == false,
-				    msecs_to_jiffies(timeout))) {
-				pr_err("%s: cold reset/prot response timeout\n",
-				       __func__);
-				ret = -EAGAIN;
-			}
-		} else {
-			/* Read response here as NFC thread is not active */
-			if (nfc_dev->interface == PLATFORM_IF_I2C) {
-				ret = nfc_dev->nfc_read(nfc_dev, rsp, 3,
-							timeout);
-				if (!ret)
-					break;
-				usleep_range(READ_RETRY_WAIT_TIME_US,
-					     READ_RETRY_WAIT_TIME_US + 500);
-			}
+		} else if (!wait_event_interruptible_timeout(
+					cold_reset->read_wq,
+					cold_reset->rsp_pending == false,
+					msecs_to_jiffies(timeout))) {
+			pr_err("%s: cold reset/prot response timeout\n", __func__);
+			ret = -EAGAIN;
 		}
 	} while (ret == -ERESTARTSYS || ret == -EFAULT);
+	mutex_unlock(&nfc_dev->write_mutex);
+
 	timeout = ESE_CLD_RST_REBOOT_GUARD_TIME_MS;
 	if (ret == 0) { /* success case */
 		ret = cold_reset->status;

+ 29 - 3
nfc/i2c_drv.c

@@ -40,7 +40,9 @@
 #include <linux/delay.h>
 #include <linux/uaccess.h>
 #include <linux/gpio.h>
-
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+#endif
 #include "common_ese.h"
 
 /**
@@ -256,6 +258,10 @@ ssize_t nfc_i2c_dev_read(struct file *filp, char __user *buf, size_t count,
 	int ret;
 	struct nfc_dev *nfc_dev = (struct nfc_dev *)filp->private_data;
 
+	if (!nfc_dev) {
+		pr_err("%s: device doesn't exist anymore\n", __func__);
+		return -ENODEV;
+	}
 	mutex_lock(&nfc_dev->read_mutex);
 	if (filp->f_flags & O_NONBLOCK) {
 		ret = i2c_master_recv(nfc_dev->i2c_dev.client, nfc_dev->read_kbuf, count);
@@ -282,6 +288,11 @@ ssize_t nfc_i2c_dev_write(struct file *filp, const char __user *buf,
 	if (count > MAX_DL_BUFFER_SIZE)
 		count = MAX_DL_BUFFER_SIZE;
 
+	if (!nfc_dev) {
+		pr_err("%s: device doesn't exist anymore\n", __func__);
+		return -ENODEV;
+	}
+
 	mutex_lock(&nfc_dev->write_mutex);
 	if (copy_from_user(nfc_dev->write_kbuf, buf, count)) {
 		pr_err("%s: failed to copy from user space\n", __func__);
@@ -302,6 +313,9 @@ static const struct file_operations nfc_i2c_dev_fops = {
 	.flush = nfc_dev_flush,
 	.release = nfc_dev_close,
 	.unlocked_ioctl = nfc_dev_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = nfc_dev_compat_ioctl,
+#endif
 };
 
 int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id)
@@ -454,12 +468,18 @@ int nfc_i2c_dev_suspend(struct device *device)
 {
 	struct i2c_client *client = to_i2c_client(device);
 	struct nfc_dev *nfc_dev = i2c_get_clientdata(client);
-	struct i2c_dev *i2c_dev = &nfc_dev->i2c_dev;
+	struct i2c_dev *i2c_dev = NULL;
+	if (!nfc_dev) {
+		pr_err("%s: device doesn't exist anymore\n", __func__);
+		return -ENODEV;
+	}
+	i2c_dev = &nfc_dev->i2c_dev;
 
 	if (device_may_wakeup(&client->dev) && i2c_dev->irq_enabled) {
 		if (!enable_irq_wake(client->irq))
 			i2c_dev->irq_wake_up = true;
 	}
+	pr_debug("%s: irq_wake_up = %d", __func__, i2c_dev->irq_wake_up);
 	return 0;
 }
 
@@ -467,12 +487,18 @@ int nfc_i2c_dev_resume(struct device *device)
 {
 	struct i2c_client *client = to_i2c_client(device);
 	struct nfc_dev *nfc_dev = i2c_get_clientdata(client);
-	struct i2c_dev *i2c_dev = &nfc_dev->i2c_dev;
+	struct i2c_dev *i2c_dev = NULL;
+	if (!nfc_dev) {
+		pr_err("%s: device doesn't exist anymore\n", __func__);
+		return -ENODEV;
+	}
+	i2c_dev = &nfc_dev->i2c_dev;
 
 	if (device_may_wakeup(&client->dev) && i2c_dev->irq_wake_up) {
 		if (!disable_irq_wake(client->irq))
 			i2c_dev->irq_wake_up = false;
 	}
+	pr_debug("%s: irq_wake_up = %d", __func__, i2c_dev->irq_wake_up);
 	return 0;
 }