From 044486a957e6ef63cafce84d2bb595e924c221a1 Mon Sep 17 00:00:00 2001 From: claxten10 Date: Sat, 9 Nov 2024 12:59:40 +0000 Subject: [PATCH] spi: Import Xiaomi changes Signed-off-by: claxten10 --- drivers/spi/spidev.c | 66 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index e444e7cc6968..5892f0998bae 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -90,7 +90,7 @@ struct spidev_data { static LIST_HEAD(device_list); static DEFINE_MUTEX(device_list_lock); -static unsigned bufsiz = 4096; +static unsigned bufsiz = 4096 * 10; module_param(bufsiz, uint, S_IRUGO); MODULE_PARM_DESC(bufsiz, "data bytes in biggest supported SPI message"); @@ -123,7 +123,9 @@ spidev_sync_write(struct spidev_data *spidev, size_t len) struct spi_transfer t = { .tx_buf = spidev->tx_buffer, .len = len, - .speed_hz = spidev->speed_hz, + .speed_hz = 960000, // spidev->speed_hz + .delay_usecs = 0, + .cs_change = 0, }; struct spi_message m; @@ -163,6 +165,14 @@ spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) spidev = filp->private_data; mutex_lock(&spidev->buf_lock); + if (!spidev->rx_buffer) { + spidev->rx_buffer = kmalloc(bufsiz, GFP_KERNEL); + if (!spidev->rx_buffer) { + dev_dbg(&spidev->spi->dev, "open/ENOMEM\n"); + status = -ENOMEM; + goto read_unlock; + } + } status = spidev_sync_read(spidev, count); if (status > 0) { unsigned long missing; @@ -173,6 +183,10 @@ spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) else status = status - missing; } + kfree(spidev->rx_buffer); + spidev->rx_buffer = NULL; + +read_unlock: mutex_unlock(&spidev->buf_lock); return status; @@ -188,17 +202,30 @@ spidev_write(struct file *filp, const char __user *buf, unsigned long missing; /* chipselect only toggles at start or end of operation */ - if (count > bufsiz) + /*if (count > bufsiz) return -EMSGSIZE; + */ spidev = filp->private_data; mutex_lock(&spidev->buf_lock); + if (!spidev->tx_buffer) { + spidev->tx_buffer = kmalloc(count, GFP_KERNEL); + if (!spidev->tx_buffer) { + dev_dbg(&spidev->spi->dev, "open/ENOMEM\n"); + status = -ENOMEM; + goto write_unlock; + } + } missing = copy_from_user(spidev->tx_buffer, buf, count); if (missing == 0) status = spidev_sync_write(spidev, count); else status = -EFAULT; + kfree(spidev->tx_buffer); + spidev->tx_buffer = NULL; + +write_unlock: mutex_unlock(&spidev->buf_lock); return status; @@ -224,6 +251,22 @@ static int spidev_message(struct spidev_data *spidev, * We walk the array of user-provided transfers, using each one * to initialize a kernel version of the same transfer. */ + if (!spidev->rx_buffer) { + spidev->rx_buffer = kmalloc(bufsiz, GFP_KERNEL); + if (!spidev->rx_buffer) { + dev_dbg(&spidev->spi->dev, "open/ENOMEM\n"); + status = -ENOMEM; + goto rxbuffer_err; + } + } + if (!spidev->tx_buffer) { + spidev->tx_buffer = kmalloc(bufsiz, GFP_KERNEL); + if (!spidev->tx_buffer) { + dev_dbg(&spidev->spi->dev, "open/ENOMEM\n"); + status = -ENOMEM; + goto txbuffer_err; + } + } tx_buf = spidev->tx_buffer; rx_buf = spidev->rx_buffer; total = 0; @@ -317,6 +360,12 @@ static int spidev_message(struct spidev_data *spidev, status = total; done: + kfree(spidev->tx_buffer); + spidev->tx_buffer = NULL; +txbuffer_err: + kfree(spidev->rx_buffer); + spidev->rx_buffer = NULL; +rxbuffer_err: kfree(k_xfers); return status; } @@ -575,7 +624,7 @@ static int spidev_open(struct inode *inode, struct file *filp) pr_debug("spidev: nothing for minor %d\n", iminor(inode)); goto err_find_dev; } - +/* if (!spidev->tx_buffer) { spidev->tx_buffer = kmalloc(bufsiz, GFP_KERNEL); if (!spidev->tx_buffer) { @@ -593,6 +642,7 @@ static int spidev_open(struct inode *inode, struct file *filp) goto err_alloc_rx_buf; } } +*/ spidev->users++; filp->private_data = spidev; @@ -600,10 +650,11 @@ static int spidev_open(struct inode *inode, struct file *filp) mutex_unlock(&device_list_lock); return 0; - +/* err_alloc_rx_buf: kfree(spidev->tx_buffer); spidev->tx_buffer = NULL; +*/ err_find_dev: mutex_unlock(&device_list_lock); return status; @@ -626,13 +677,13 @@ static int spidev_release(struct inode *inode, struct file *filp) /* last close? */ spidev->users--; if (!spidev->users) { - +/* kfree(spidev->tx_buffer); spidev->tx_buffer = NULL; kfree(spidev->rx_buffer); spidev->rx_buffer = NULL; - +*/ if (dofree) kfree(spidev); else @@ -676,6 +727,7 @@ static const struct of_device_id spidev_dt_ids[] = { { .compatible = "rohm,dh2228fv" }, { .compatible = "lineartechnology,ltc2488" }, { .compatible = "ge,achc" }, + { .compatible = "ir,ir_spi" }, { .compatible = "semtech,sx1301" }, {}, };