summaryrefslogtreecommitdiff
path: root/goodix_brl_spi.c
diff options
context:
space:
mode:
authorWendly Li <wendlyli@google.com>2022-01-13 16:13:36 +0000
committerWendly Li <wendlyli@google.com>2022-01-21 08:51:15 +0000
commitf117c02fc3bc53deb32cd0c55a2cc4e10ec3a6ef (patch)
tree09573ee0d12204c34a82d1c78a1ca7e47e09d46d /goodix_brl_spi.c
parent39aab1926632e1b0b0e08ba4575ea447ef8dbc50 (diff)
downloadgoodix_touch-f117c02fc3bc53deb32cd0c55a2cc4e10ec3a6ef.tar.gz
Avoid allocating memory frequently
Bug: 214118883 Test: Check memory allocation Change-Id: I97ef74a66e1b9d3304979e221a469c9dc97aea02 Signed-off-by: Wendly Li <wendlyli@google.com>
Diffstat (limited to 'goodix_brl_spi.c')
-rw-r--r--goodix_brl_spi.c134
1 files changed, 89 insertions, 45 deletions
diff --git a/goodix_brl_spi.c b/goodix_brl_spi.c
index bc35268..1356e52 100644
--- a/goodix_brl_spi.c
+++ b/goodix_brl_spi.c
@@ -27,6 +27,8 @@
#define SPI_READ_PREFIX_LEN \
(SPI_TRANS_PREFIX_LEN + REGISTER_WIDTH + SPI_READ_DUMMY_LEN)
#define SPI_WRITE_PREFIX_LEN (SPI_TRANS_PREFIX_LEN + REGISTER_WIDTH)
+#define SPI_PREALLOC_RX_BUF_SIZE 4096 + SPI_READ_PREFIX_LEN
+#define SPI_PREALLOC_TX_BUF_SIZE 4096 + SPI_WRITE_PREFIX_LEN
#define SPI_WRITE_FLAG 0xF0
#define SPI_READ_FLAG 0xF1
@@ -51,20 +53,26 @@ static int goodix_spi_read_bra(struct device *dev, unsigned int addr,
struct spi_transfer xfers;
struct spi_message spi_msg;
int ret = 0;
-
- rx_buf = kzalloc(SPI_READ_PREFIX_LEN + len, GFP_KERNEL);
- if (!rx_buf) {
- ts_err("alloc rx_buf failed, size:%d",
- SPI_READ_PREFIX_LEN + len);
- return -ENOMEM;
- }
-
- tx_buf = kzalloc(SPI_READ_PREFIX_LEN + len, GFP_KERNEL);
- if (!tx_buf) {
- ts_err("alloc tx_buf failed, size:%d",
- SPI_READ_PREFIX_LEN + len);
- ret = -ENOMEM;
- goto err_alloc_rx_buf;
+ int buf_len = SPI_READ_PREFIX_LEN + len;
+
+ if (buf_len <= SPI_PREALLOC_RX_BUF_SIZE &&
+ buf_len <= SPI_PREALLOC_TX_BUF_SIZE) {
+ rx_buf = goodix_spi_bus.rx_buf;
+ tx_buf = goodix_spi_bus.tx_buf;
+ memset(tx_buf, 0, buf_len);
+ } else {
+ rx_buf = kzalloc(buf_len, GFP_KERNEL);
+ if (!rx_buf) {
+ ts_err("alloc rx_buf failed, size:%d", buf_len);
+ return -ENOMEM;
+ }
+
+ tx_buf = kzalloc(buf_len, GFP_KERNEL);
+ if (!tx_buf) {
+ ts_err("alloc tx_buf failed, size:%d", buf_len);
+ ret = -ENOMEM;
+ goto err_alloc_rx_buf;
+ }
}
spi_message_init(&spi_msg);
@@ -83,7 +91,7 @@ static int goodix_spi_read_bra(struct device *dev, unsigned int addr,
xfers.tx_buf = tx_buf;
xfers.rx_buf = rx_buf;
- xfers.len = SPI_READ_PREFIX_LEN + len;
+ xfers.len = buf_len;
xfers.cs_change = 0;
spi_message_add_tail(&xfers, &spi_msg);
ret = spi_sync(spi, &spi_msg);
@@ -94,9 +102,11 @@ static int goodix_spi_read_bra(struct device *dev, unsigned int addr,
memcpy(data, &rx_buf[SPI_READ_PREFIX_LEN], len);
err_spi_transfer:
- kfree(rx_buf);
+ if (rx_buf != goodix_spi_bus.rx_buf)
+ kfree(rx_buf);
err_alloc_rx_buf:
- kfree(tx_buf);
+ if (tx_buf != goodix_spi_bus.tx_buf)
+ kfree(tx_buf);
return ret;
}
@@ -109,20 +119,26 @@ static int goodix_spi_read(struct device *dev, unsigned int addr,
struct spi_transfer xfers;
struct spi_message spi_msg;
int ret = 0;
-
- rx_buf = kzalloc(SPI_READ_PREFIX_LEN - 1 + len, GFP_KERNEL);
- if (!rx_buf) {
- ts_err("alloc rx_buf failed, size:%d",
- SPI_READ_PREFIX_LEN + len);
- return -ENOMEM;
- }
-
- tx_buf = kzalloc(SPI_READ_PREFIX_LEN - 1 + len, GFP_KERNEL);
- if (!tx_buf) {
- ts_err("alloc tx_buf failed, size:%d",
- SPI_READ_PREFIX_LEN + len);
- ret = -ENOMEM;
- goto err_alloc_rx_buf;
+ int buf_len = SPI_READ_PREFIX_LEN - 1 + len;
+
+ if (buf_len <= SPI_PREALLOC_RX_BUF_SIZE &&
+ buf_len <= SPI_PREALLOC_TX_BUF_SIZE) {
+ rx_buf = goodix_spi_bus.rx_buf;
+ tx_buf = goodix_spi_bus.tx_buf;
+ memset(tx_buf, 0, buf_len);
+ } else {
+ rx_buf = kzalloc(buf_len, GFP_KERNEL);
+ if (!rx_buf) {
+ ts_err("alloc rx_buf failed, size:%d", buf_len);
+ return -ENOMEM;
+ }
+
+ tx_buf = kzalloc(buf_len, GFP_KERNEL);
+ if (!tx_buf) {
+ ts_err("alloc tx_buf failed, size:%d", buf_len);
+ ret = -ENOMEM;
+ goto err_alloc_rx_buf;
+ }
}
spi_message_init(&spi_msg);
@@ -140,7 +156,7 @@ static int goodix_spi_read(struct device *dev, unsigned int addr,
xfers.tx_buf = tx_buf;
xfers.rx_buf = rx_buf;
- xfers.len = SPI_READ_PREFIX_LEN - 1 + len;
+ xfers.len = buf_len;
xfers.cs_change = 0;
spi_message_add_tail(&xfers, &spi_msg);
ret = spi_sync(spi, &spi_msg);
@@ -151,9 +167,11 @@ static int goodix_spi_read(struct device *dev, unsigned int addr,
memcpy(data, &rx_buf[SPI_READ_PREFIX_LEN - 1], len);
err_spi_transfer:
- kfree(rx_buf);
+ if (rx_buf != goodix_spi_bus.rx_buf)
+ kfree(rx_buf);
err_alloc_rx_buf:
- kfree(tx_buf);
+ if (tx_buf != goodix_spi_bus.tx_buf)
+ kfree(tx_buf);
return ret;
}
@@ -173,10 +191,17 @@ static int goodix_spi_write(struct device *dev, unsigned int addr,
struct spi_transfer xfers;
struct spi_message spi_msg;
int ret = 0;
-
- tx_buf = kzalloc(SPI_WRITE_PREFIX_LEN + len, GFP_KERNEL);
- if (!tx_buf)
- return -ENOMEM;
+ int buf_len = SPI_WRITE_PREFIX_LEN + len;
+
+ if (buf_len <= SPI_PREALLOC_TX_BUF_SIZE) {
+ tx_buf = goodix_spi_bus.tx_buf;
+ } else {
+ tx_buf = kzalloc(buf_len, GFP_KERNEL);
+ if (!tx_buf) {
+ ts_err("alloc tx_buf failed, size:%d", buf_len);
+ return -ENOMEM;
+ }
+ }
spi_message_init(&spi_msg);
memset(&xfers, 0, sizeof(xfers));
@@ -188,14 +213,15 @@ static int goodix_spi_write(struct device *dev, unsigned int addr,
tx_buf[4] = addr & 0xFF;
memcpy(&tx_buf[SPI_WRITE_PREFIX_LEN], data, len);
xfers.tx_buf = tx_buf;
- xfers.len = SPI_WRITE_PREFIX_LEN + len;
+ xfers.len = buf_len;
xfers.cs_change = 0;
spi_message_add_tail(&xfers, &spi_msg);
ret = spi_sync(spi, &spi_msg);
if (ret < 0)
ts_err("spi transfer error:%d", ret);
- kfree(tx_buf);
+ if (tx_buf != goodix_spi_bus.tx_buf)
+ kfree(tx_buf);
return ret;
}
@@ -233,10 +259,24 @@ static int goodix_spi_probe(struct spi_device *spi)
else
goodix_spi_bus.read = goodix_spi_read;
goodix_spi_bus.write = goodix_spi_write;
+
+ goodix_spi_bus.rx_buf = kzalloc(SPI_PREALLOC_RX_BUF_SIZE, GFP_KERNEL);
+ if (!goodix_spi_bus.rx_buf) {
+ return -ENOMEM;
+ }
+
+ goodix_spi_bus.tx_buf = kzalloc(SPI_PREALLOC_TX_BUF_SIZE, GFP_KERNEL);
+ if (!goodix_spi_bus.tx_buf) {
+ ret = -ENOMEM;
+ goto err_alloc_tx_buf;
+ }
+
/* ts core device */
goodix_pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
- if (!goodix_pdev)
- return -ENOMEM;
+ if (!goodix_pdev) {
+ ret = -ENOMEM;
+ goto err_alloc_pdev;
+ }
goodix_pdev->name = GOODIX_CORE_DRIVER_NAME;
goodix_pdev->id = 0;
@@ -255,14 +295,18 @@ static int goodix_spi_probe(struct spi_device *spi)
ret = platform_device_register(goodix_pdev);
if (ret) {
ts_err("failed register goodix platform device, %d", ret);
- goto err_pdev;
+ goto err_register_platform_device;
}
ts_info("spi probe out");
return 0;
-err_pdev:
+err_register_platform_device:
kfree(goodix_pdev);
- goodix_pdev = NULL;
+err_alloc_pdev:
+ kfree(goodix_spi_bus.tx_buf);
+err_alloc_tx_buf:
+ kfree(goodix_spi_bus.rx_buf);
+
ts_info("spi probe out, %d", ret);
return ret;
}