drivers: spi: Import xiaomi changes

Signed-off-by: Adithya R <gh0strider.2k18.reborn@gmail.com>
Signed-off-by: azrim <mirzaspc@gmail.com>
This commit is contained in:
Adithya R 2021-01-08 21:43:30 +05:30 committed by azrim
parent 3787afdadb
commit c27672260d
No known key found for this signature in database
GPG Key ID: 497F8FB059B45D1C
2 changed files with 65 additions and 35 deletions

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* Copyright (C) 2020 XiaoMi, Inc.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
@ -29,7 +29,7 @@
#include <soc/qcom/boot_stats.h>
#define SPI_NUM_CHIPSELECT (4)
#define SPI_XFER_TIMEOUT_MS (250)
#define SPI_XFER_TIMEOUT_MS (1000)
#define SPI_AUTO_SUSPEND_DELAY (250)
/* SPI SE specific registers */
#define SE_SPI_CPHA (0x224)

View File

@ -2,7 +2,7 @@
* Simple synchronous userspace interface to SPI devices
*
* Copyright (C) 2006 SWAPP
* Andrea Paterniani <a.paterniani@swapp-eng.it>
* Copyright (C) 2020 XiaoMi, Inc.
* Copyright (C) 2007 David Brownell (simplification, cleanup)
*
* This program is free software; you can redistribute it and/or modify
@ -90,7 +90,7 @@ struct spidev_data {
static LIST_HEAD(device_list);
static DEFINE_MUTEX(device_list_lock);
static unsigned bufsiz = 4096;
static unsigned int 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,17 @@ 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;
}
}
/* added buffer kmalloc size end by haouanling */
status = spidev_sync_read(spidev, count);
if (status > 0) {
unsigned long missing;
@ -173,6 +186,11 @@ 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 +206,33 @@ spidev_write(struct file *filp, const char __user *buf,
unsigned long missing;
/* chipselect only toggles at start or end of operation */
if (count > bufsiz)
return -EMSGSIZE;
/* removed buffer kmalloc size by hayanling */
/*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 +258,24 @@ 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 +369,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;
}
@ -576,24 +634,6 @@ static int spidev_open(struct inode *inode, struct file *filp)
goto err_find_dev;
}
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 err_find_dev;
}
}
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 err_alloc_rx_buf;
}
}
spidev->users++;
filp->private_data = spidev;
nonseekable_open(inode, filp);
@ -601,9 +641,6 @@ 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 +663,6 @@ 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