Merge "NFC: Add IPC logging of NCI Commands and responses of NFC I2C driver"

This commit is contained in:
qctecmdr 2020-10-08 21:56:17 -07:00 • committed by Gerrit - the friendly Code Review server
commit 87d9d76131
3 changed files with 63 additions and 3 deletions

View file

@ -248,6 +248,8 @@ void nfc_misc_remove(struct nfc_dev *nfc_dev, int count)
cdev_del(&nfc_dev->c_dev);
class_destroy(nfc_dev->nfc_class);
unregister_chrdev_region(nfc_dev->devno, count);
if (nfc_dev->ipcl)
ipc_log_context_destroy(nfc_dev->ipcl);
}
int nfc_misc_probe(struct nfc_dev *nfc_dev,
@ -290,10 +292,23 @@ int nfc_misc_probe(struct nfc_dev *nfc_dev,
return ret;
}
nfc_dev->ipcl = ipc_log_context_create(NUM_OF_IPC_LOG_PAGES,
dev_name(nfc_dev->nfc_device), 0);
if (!nfc_dev->ipcl) {
pr_err("nfc ipc log create failed\n");
device_destroy(nfc_dev->nfc_class, nfc_dev->devno);
cdev_del(&nfc_dev->c_dev);
class_destroy(nfc_dev->nfc_class);
unregister_chrdev_region(nfc_dev->devno, count);
return -ENXIO;
}
nfc_dev->kbuflen = MAX_BUFFER_SIZE;
nfc_dev->kbuf = kzalloc(MAX_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
if (!nfc_dev->kbuf)
if (!nfc_dev->kbuf) {
nfc_misc_remove(nfc_dev, count);
return -ENOMEM;
}
nfc_dev->cold_reset.rsp_pending = false;
nfc_dev->cold_reset.is_nfc_enabled = false;
@ -756,6 +771,8 @@ int nfcc_hw_check(struct nfc_dev *nfc_dev)
char *nci_get_version_cmd = NULL;
char *nci_get_version_rsp = NULL;
NFCLOG_IPC(nfc_dev, false, "%s", __func__);
nci_reset_cmd = kzalloc(NCI_RESET_CMD_LEN + 1, GFP_DMA | GFP_KERNEL);
if (!nci_reset_cmd)
return -ENOMEM;

View file

@ -24,7 +24,7 @@
#include <linux/slab.h>
#include <linux/nfcinfo.h>
#include <linux/regulator/consumer.h>
#include <linux/ipc_logging.h>
#include "nfc_i2c_drv.h"
#include "nfc_i3c_drv.h"
@ -102,6 +102,23 @@
#define NFC_VDDIO_MAX 1950000 //in uV
#define NFC_CURRENT_MAX 157000 //in uA
#define NUM_OF_IPC_LOG_PAGES (2)
#define PKT_MAX_LEN (4) // no of max bytes to print for cmd/resp
#define GET_IPCLOG_MAX_PKT_LEN(c) ((c > PKT_MAX_LEN) ? PKT_MAX_LEN : c)
#define NFCLOG_IPC(nfc_dev, log_to_dmesg, x...) \
do { \
ipc_log_string(nfc_dev->ipcl, x); \
if (log_to_dmesg) { \
if (nfc_dev->nfc_device) \
dev_err((nfc_dev->nfc_device), x); \
else \
pr_err(x); \
} \
} while (0)
enum ese_ioctl_request {
/* eSE POWER ON */
ESE_POWER_ON = 0,
@ -224,6 +241,8 @@ struct nfc_dev {
union nqx_uinfo nqx_info;
void *ipcl;
int (*nfc_read)(struct nfc_dev *dev,
char *buf, size_t count);
int (*nfc_write)(struct nfc_dev *dev,

View file

@ -66,10 +66,15 @@ static irqreturn_t i2c_irq_handler(int irq, void *dev_id)
int i2c_read(struct nfc_dev *dev, char *buf, size_t count)
{
int ret;
uint16_t i = 0;
uint16_t disp_len = GET_IPCLOG_MAX_PKT_LEN(count);
pr_debug("%s : reading %zu bytes.\n", __func__, count);
/* Read data */
ret = i2c_master_recv(dev->i2c_dev.client, buf, count);
NFCLOG_IPC(dev, false, "%s of %d bytes, ret %d", __func__, count,
ret);
if (ret <= 0) {
pr_err("%s: i2c_master_recv returned %d\n", __func__, ret);
goto i2c_read_err;
@ -79,7 +84,11 @@ int i2c_read(struct nfc_dev *dev, char *buf, size_t count)
__func__, ret);
ret = -EIO;
}
/* delay for the slow nfc devices between susequent read operation */
for (i = 0; i < disp_len; i++)
NFCLOG_IPC(dev, false, " %02x", buf[i]);
/* delay for the slow nfc devices between susequent read operation */
usleep_range(1000, 1100);
i2c_read_err:
return ret;
@ -90,11 +99,20 @@ int i2c_write(struct nfc_dev *dev, const char *buf, size_t count,
{
int ret = -EINVAL;
int retry_cnt;
uint16_t i = 0;
uint16_t disp_len = GET_IPCLOG_MAX_PKT_LEN(count);
pr_debug("%s : writing %zu bytes.\n", __func__, count);
NFCLOG_IPC(dev, false, "%s sending %d B", __func__, count);
for (i = 0; i < disp_len; i++)
NFCLOG_IPC(dev, false, " %02x", buf[i]);
for (retry_cnt = 1; retry_cnt <= max_retry_cnt; retry_cnt++) {
ret = i2c_master_send(dev->i2c_dev.client, buf, count);
NFCLOG_IPC(dev, false, "%s ret %d", __func__, ret);
if (ret <= 0) {
pr_warn("%s: write failed, Maybe in Standby Mode - Retry(%d)\n",
__func__, retry_cnt);
@ -436,6 +454,9 @@ int nfc_i2c_dev_suspend(struct device *device)
struct nfc_dev *nfc_dev = i2c_get_clientdata(client);
struct i2c_dev *i2c_dev = &nfc_dev->i2c_dev;
NFCLOG_IPC(nfc_dev, false, "%s: irq_enabled = %d", __func__,
i2c_dev->irq_enabled);
if (device_may_wakeup(&client->dev) && i2c_dev->irq_enabled) {
if (!enable_irq_wake(client->irq))
i2c_dev->irq_wake_up = true;
@ -449,6 +470,9 @@ int nfc_i2c_dev_resume(struct device *device)
struct nfc_dev *nfc_dev = i2c_get_clientdata(client);
struct i2c_dev *i2c_dev = &nfc_dev->i2c_dev;
NFCLOG_IPC(nfc_dev, false, "%s: irq_wake_up = %d", __func__,
i2c_dev->irq_wake_up);
if (device_may_wakeup(&client->dev) && i2c_dev->irq_wake_up) {
if (!disable_irq_wake(client->irq))
i2c_dev->irq_wake_up = false;