From 55d2657f94c157da0ac322163acc5b55ad29eff5 Mon Sep 17 00:00:00 2001 From: nxf35421 Date: Fri, 17 Dec 2021 17:25:16 +0530 Subject: [PATCH] Updated corresponding to - NFC_AR_00_E800_12.10.00_OpnSrc --- nfc/common.c | 25 ++++++++++++++++++++ nfc/common.h | 8 ++++--- nfc/common_ese.c | 61 ++++++++++++++++++++++-------------------------- nfc/i2c_drv.c | 32 ++++++++++++++++++++++--- 4 files changed, 87 insertions(+), 39 deletions(-) diff --git a/nfc/common.c b/nfc/common.c index 094eb40c81..a4f8029fa1 100644 --- a/nfc/common.c +++ b/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. diff --git a/nfc/common.h b/nfc/common.h index c4f3388ad7..bcdd26dd33 100644 --- a/nfc/common.h +++ b/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); diff --git a/nfc/common_ese.c b/nfc/common_ese.c index c1795063d4..5c725a6845 100644 --- a/nfc/common_ese.c +++ b/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 */ + + /* 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; - - /* enable interrupt before sending cmd, when devnode not opened by HAL */ - if (!nfc_dev_opened) - nfc_dev->nfc_enable_intr(nfc_dev); - 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; diff --git a/nfc/i2c_drv.c b/nfc/i2c_drv.c index e65d1a8792..2792484263 100644 --- a/nfc/i2c_drv.c +++ b/nfc/i2c_drv.c @@ -40,7 +40,9 @@ #include #include #include - +#ifdef CONFIG_COMPAT +#include +#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; }