Updated corresponding to - NFC_AR_00_1E800_13.0B.00_OpnSrc
This commit is contained in:
24
nfc/common.c
24
nfc/common.c
@@ -127,7 +127,7 @@ int configure_gpio(unsigned int gpio, int flag)
|
|||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("%s: unable to set direction for nfc gpio [%d]\n",
|
pr_err("%s: unable to set direction for nfc gpio [%d]\n",
|
||||||
__func__, gpio);
|
__func__, gpio);
|
||||||
gpio_free(gpio);
|
gpio_free(gpio);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -301,10 +301,11 @@ static int nfc_ioctl_power_states(struct nfc_dev *nfc_dev, unsigned long arg)
|
|||||||
* and error ret code otherwise
|
* and error ret code otherwise
|
||||||
*/
|
*/
|
||||||
long nfc_dev_compat_ioctl(struct file *pfile, unsigned int cmd,
|
long nfc_dev_compat_ioctl(struct file *pfile, unsigned int cmd,
|
||||||
unsigned long arg)
|
unsigned long arg)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
arg = (compat_u64)arg;
|
|
||||||
|
arg = (compat_u64) arg;
|
||||||
pr_debug("%s: cmd = %x arg = %zx\n", __func__, cmd, arg);
|
pr_debug("%s: cmd = %x arg = %zx\n", __func__, cmd, arg);
|
||||||
ret = nfc_dev_ioctl(pfile, cmd, arg);
|
ret = nfc_dev_ioctl(pfile, cmd, arg);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -337,6 +338,19 @@ long nfc_dev_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg)
|
|||||||
case NFC_SET_PWR:
|
case NFC_SET_PWR:
|
||||||
ret = nfc_ioctl_power_states(nfc_dev, arg);
|
ret = nfc_ioctl_power_states(nfc_dev, arg);
|
||||||
break;
|
break;
|
||||||
|
case NFC_SET_RESET_READ_PENDING:
|
||||||
|
if (arg == NFC_SET_READ_PENDING) {
|
||||||
|
nfc_dev->cold_reset.is_nfc_read_pending = true;
|
||||||
|
/* Set default NFC state as NCI for Nfc read pending request */
|
||||||
|
nfc_dev->nfc_state = NFC_STATE_NCI;
|
||||||
|
}
|
||||||
|
else if (arg == NFC_RESET_READ_PENDING){
|
||||||
|
nfc_dev->cold_reset.is_nfc_read_pending = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = -EINVAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ESE_SET_PWR:
|
case ESE_SET_PWR:
|
||||||
ret = nfc_ese_pwr(nfc_dev, arg);
|
ret = nfc_ese_pwr(nfc_dev, arg);
|
||||||
break;
|
break;
|
||||||
@@ -353,6 +367,7 @@ long nfc_dev_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg)
|
|||||||
int nfc_dev_open(struct inode *inode, struct file *filp)
|
int nfc_dev_open(struct inode *inode, struct file *filp)
|
||||||
{
|
{
|
||||||
struct nfc_dev *nfc_dev = NULL;
|
struct nfc_dev *nfc_dev = NULL;
|
||||||
|
|
||||||
nfc_dev = container_of(inode->i_cdev, struct nfc_dev, c_dev);
|
nfc_dev = container_of(inode->i_cdev, struct nfc_dev, c_dev);
|
||||||
|
|
||||||
if (!nfc_dev)
|
if (!nfc_dev)
|
||||||
@@ -400,6 +415,7 @@ int nfc_dev_flush(struct file *pfile, fl_owner_t id)
|
|||||||
int nfc_dev_close(struct inode *inode, struct file *filp)
|
int nfc_dev_close(struct inode *inode, struct file *filp)
|
||||||
{
|
{
|
||||||
struct nfc_dev *nfc_dev = NULL;
|
struct nfc_dev *nfc_dev = NULL;
|
||||||
|
|
||||||
nfc_dev = container_of(inode->i_cdev, struct nfc_dev, c_dev);
|
nfc_dev = container_of(inode->i_cdev, struct nfc_dev, c_dev);
|
||||||
|
|
||||||
if (!nfc_dev)
|
if (!nfc_dev)
|
||||||
@@ -415,7 +431,9 @@ int nfc_dev_close(struct inode *inode, struct file *filp)
|
|||||||
* if eSE calls flow is via NFC driver
|
* if eSE calls flow is via NFC driver
|
||||||
* i.e. direct calls from SPI HAL to NFC driver
|
* i.e. direct calls from SPI HAL to NFC driver
|
||||||
*/
|
*/
|
||||||
|
mutex_unlock(&nfc_dev->dev_ref_mutex);
|
||||||
nfc_ese_pwr(nfc_dev, ESE_RST_PROT_DIS_NFC);
|
nfc_ese_pwr(nfc_dev, ESE_RST_PROT_DIS_NFC);
|
||||||
|
mutex_lock(&nfc_dev->dev_ref_mutex);
|
||||||
}
|
}
|
||||||
if (nfc_dev->dev_ref_count > 0)
|
if (nfc_dev->dev_ref_count > 0)
|
||||||
nfc_dev->dev_ref_count = nfc_dev->dev_ref_count - 1;
|
nfc_dev->dev_ref_count = nfc_dev->dev_ref_count - 1;
|
||||||
|
16
nfc/common.h
16
nfc/common.h
@@ -51,7 +51,6 @@
|
|||||||
#define MAX_DL_BUFFER_SIZE (DL_HDR_LEN + DL_CRC_LEN + \
|
#define MAX_DL_BUFFER_SIZE (DL_HDR_LEN + DL_CRC_LEN + \
|
||||||
MAX_DL_PAYLOAD_LEN)
|
MAX_DL_PAYLOAD_LEN)
|
||||||
|
|
||||||
|
|
||||||
/* Retry count for normal write */
|
/* Retry count for normal write */
|
||||||
#define NO_RETRY (1)
|
#define NO_RETRY (1)
|
||||||
/* Maximum retry count for standby writes */
|
/* Maximum retry count for standby writes */
|
||||||
@@ -72,9 +71,10 @@
|
|||||||
|
|
||||||
/* Ioctls */
|
/* Ioctls */
|
||||||
/* The type should be aligned with MW HAL definitions */
|
/* The type should be aligned with MW HAL definitions */
|
||||||
#define NFC_SET_PWR _IOW(NFC_MAGIC, 0x01, uint32_t)
|
#define NFC_SET_PWR _IOW(NFC_MAGIC, 0x01, uint32_t)
|
||||||
#define ESE_SET_PWR _IOW(NFC_MAGIC, 0x02, uint32_t)
|
#define ESE_SET_PWR _IOW(NFC_MAGIC, 0x02, uint32_t)
|
||||||
#define ESE_GET_PWR _IOR(NFC_MAGIC, 0x03, uint32_t)
|
#define ESE_GET_PWR _IOR(NFC_MAGIC, 0x03, uint32_t)
|
||||||
|
#define NFC_SET_RESET_READ_PENDING _IOW(NFC_MAGIC, 0x04, uint32_t)
|
||||||
|
|
||||||
#define DTS_IRQ_GPIO_STR "nxp,sn-irq"
|
#define DTS_IRQ_GPIO_STR "nxp,sn-irq"
|
||||||
#define DTS_VEN_GPIO_STR "nxp,sn-ven-rstn"
|
#define DTS_VEN_GPIO_STR "nxp,sn-ven-rstn"
|
||||||
@@ -97,6 +97,11 @@ enum nfcc_ioctl_request {
|
|||||||
NFC_FW_DWL_LOW,
|
NFC_FW_DWL_LOW,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum nfc_read_pending {
|
||||||
|
NFC_RESET_READ_PENDING,
|
||||||
|
NFC_SET_READ_PENDING,
|
||||||
|
};
|
||||||
|
|
||||||
/* nfc platform interface type */
|
/* nfc platform interface type */
|
||||||
enum interface_flags {
|
enum interface_flags {
|
||||||
/* I2C physical IF for NFCC */
|
/* I2C physical IF for NFCC */
|
||||||
@@ -154,6 +159,7 @@ struct cold_reset {
|
|||||||
uint8_t rst_prot_src; /* reset protection source (SPI, NFC) */
|
uint8_t rst_prot_src; /* reset protection source (SPI, NFC) */
|
||||||
struct timer_list timer;
|
struct timer_list timer;
|
||||||
wait_queue_head_t read_wq;
|
wait_queue_head_t read_wq;
|
||||||
|
bool is_nfc_read_pending;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Device specific structure */
|
/* Device specific structure */
|
||||||
@@ -195,7 +201,7 @@ int nfc_dev_open(struct inode *inode, struct file *filp);
|
|||||||
int nfc_dev_flush(struct file *pfile, fl_owner_t id);
|
int nfc_dev_flush(struct file *pfile, fl_owner_t id);
|
||||||
int nfc_dev_close(struct inode *inode, struct file *filp);
|
int nfc_dev_close(struct inode *inode, struct file *filp);
|
||||||
long nfc_dev_compat_ioctl(struct file *pfile, unsigned int cmd,
|
long nfc_dev_compat_ioctl(struct file *pfile, unsigned int cmd,
|
||||||
unsigned long arg);
|
unsigned long arg);
|
||||||
long nfc_dev_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,
|
int nfc_parse_dt(struct device *dev, struct platform_configs *nfc_configs,
|
||||||
uint8_t interface);
|
uint8_t interface);
|
||||||
|
@@ -56,11 +56,11 @@ static int send_cold_reset_protection_cmd(struct nfc_dev *nfc_dev,
|
|||||||
|
|
||||||
*cmd++ = NCI_PROP_MSG_CMD;
|
*cmd++ = NCI_PROP_MSG_CMD;
|
||||||
|
|
||||||
if (requestType) { /* reset protection */
|
if (requestType) { /* reset protection */
|
||||||
*cmd++ = RST_PROT_OID;
|
*cmd++ = RST_PROT_OID;
|
||||||
*cmd++ = RST_PROT_PAYLOAD_SIZE;
|
*cmd++ = RST_PROT_PAYLOAD_SIZE;
|
||||||
*cmd++ = (!cold_reset->reset_protection) ? 1 : 0;
|
*cmd++ = (!cold_reset->reset_protection) ? 1 : 0;
|
||||||
} else { /* cold reset */
|
} else { /* cold reset */
|
||||||
*cmd++ = CLD_RST_OID;
|
*cmd++ = CLD_RST_OID;
|
||||||
*cmd++ = CLD_RST_PAYLOAD_SIZE;
|
*cmd++ = CLD_RST_PAYLOAD_SIZE;
|
||||||
}
|
}
|
||||||
@@ -149,6 +149,7 @@ static int perform_cold_reset_protection(struct nfc_dev *nfc_dev,
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int timeout = 0;
|
int timeout = 0;
|
||||||
|
int retry_cnt = 0;
|
||||||
char *rsp = nfc_dev->read_kbuf;
|
char *rsp = nfc_dev->read_kbuf;
|
||||||
struct cold_reset *cold_reset = &nfc_dev->cold_reset;
|
struct cold_reset *cold_reset = &nfc_dev->cold_reset;
|
||||||
|
|
||||||
@@ -203,41 +204,50 @@ static int perform_cold_reset_protection(struct nfc_dev *nfc_dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
timeout = NCI_CMD_RSP_TIMEOUT_MS;
|
timeout = NCI_CMD_RSP_TIMEOUT_MS;
|
||||||
|
mutex_lock(&nfc_dev->dev_ref_mutex);
|
||||||
do {
|
do {
|
||||||
/* call read api directly if reader thread is not blocked */
|
if (nfc_dev->cold_reset.is_nfc_read_pending) {
|
||||||
if (mutex_trylock(&nfc_dev->read_mutex)) {
|
if (!wait_event_interruptible_timeout
|
||||||
pr_debug("%s: reader thread not pending\n", __func__);
|
(cold_reset->read_wq,
|
||||||
ret = nfc_dev->nfc_read(nfc_dev, rsp, 3,
|
cold_reset->rsp_pending == false,
|
||||||
timeout);
|
msecs_to_jiffies(timeout))) {
|
||||||
mutex_unlock(&nfc_dev->read_mutex);
|
pr_err("%s: cold reset/prot response timeout\n",
|
||||||
|
__func__);
|
||||||
|
if (retry_cnt <= 1) {
|
||||||
|
retry_cnt = retry_cnt + 1;
|
||||||
|
ret = -EAGAIN;
|
||||||
|
} else {
|
||||||
|
pr_debug("%s: Maximum retry reached",
|
||||||
|
__func__);
|
||||||
|
ret = -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = nfc_dev->nfc_read(nfc_dev, rsp, 3, timeout);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
break;
|
break;
|
||||||
usleep_range(READ_RETRY_WAIT_TIME_US,
|
usleep_range(READ_RETRY_WAIT_TIME_US,
|
||||||
READ_RETRY_WAIT_TIME_US + 500);
|
READ_RETRY_WAIT_TIME_US + 500);
|
||||||
/* Read pending response form the HAL service */
|
|
||||||
} 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);
|
} while (ret == -ERESTARTSYS || ret == -EFAULT || ret == -EAGAIN);
|
||||||
|
mutex_unlock(&nfc_dev->dev_ref_mutex);
|
||||||
mutex_unlock(&nfc_dev->write_mutex);
|
mutex_unlock(&nfc_dev->write_mutex);
|
||||||
|
|
||||||
timeout = ESE_CLD_RST_REBOOT_GUARD_TIME_MS;
|
timeout = ESE_CLD_RST_REBOOT_GUARD_TIME_MS;
|
||||||
if (ret == 0) { /* success case */
|
if (ret == 0) { /* success case */
|
||||||
ret = cold_reset->status;
|
ret = cold_reset->status;
|
||||||
if (IS_RST_PROT_REQ(arg)) {
|
if (IS_RST_PROT_REQ(arg)) {
|
||||||
cold_reset->reset_protection = IS_RST_PROT_EN_REQ(arg);
|
cold_reset->reset_protection = IS_RST_PROT_EN_REQ(arg);
|
||||||
cold_reset->rst_prot_src = IS_RST_PROT_EN_REQ(arg) ?
|
cold_reset->rst_prot_src = IS_RST_PROT_EN_REQ(arg) ?
|
||||||
GET_SRC(arg) :
|
GET_SRC(arg) : SRC_NONE;
|
||||||
SRC_NONE;
|
|
||||||
/* wait for reboot guard timer */
|
/* wait for reboot guard timer */
|
||||||
} else if (wait_event_interruptible_timeout(
|
} else {
|
||||||
cold_reset->read_wq, true,
|
if (wait_event_interruptible_timeout
|
||||||
msecs_to_jiffies(timeout)) == 0) {
|
(cold_reset->read_wq, true,
|
||||||
pr_info("%s: reboot guard timer timeout\n", __func__);
|
msecs_to_jiffies(timeout)) == 0) {
|
||||||
|
pr_info("%s: reboot guard timer timeout\n",
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err:
|
err:
|
||||||
|
Reference in New Issue
Block a user