Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Simple synchronous userspace interface to SPI devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2006 SWAPP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *	Andrea Paterniani <a.paterniani@swapp-eng.it>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Copyright (C) 2007 David Brownell (simplification, cleanup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/spi/spidev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * This supports access to SPI devices using normal userspace I/O calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * Note that while traditional UNIX/POSIX I/O semantics are half duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * and often mask message boundaries, full SPI support requires full duplex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * transfers.  There are several kinds of internal message boundaries to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * handle chipselect management and other protocol options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * SPI has a character major number assigned.  We allocate minor numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * dynamically using a bitmask.  You must use hotplug tools, such as udev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * (or mdev with busybox) to create and destroy the /dev/spidevB.C device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * nodes, since there is no fixed association of minor numbers with any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  * particular SPI bus or device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define SPIDEV_MAJOR			153	/* assigned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define N_SPI_MINORS			32	/* ... up to 256 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static DECLARE_BITMAP(minors, N_SPI_MINORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) /* Bit masks for spi_device.mode management.  Note that incorrect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * settings for some settings can cause *lots* of trouble for other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  * devices on a shared bus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  *  - CS_HIGH ... this device will be active when it shouldn't be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  *  - 3WIRE ... when active, it won't behave as it should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  *  - NO_CS ... there will be no explicit message boundaries; this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  *	is completely incompatible with the shared bus model
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  *  - READY ... transfers may proceed when they shouldn't.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  * REVISIT should changing those flags be privileged?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define SPI_MODE_MASK		(SPI_CPHA | SPI_CPOL | SPI_CS_HIGH \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 				| SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 				| SPI_NO_CS | SPI_READY | SPI_TX_DUAL \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 				| SPI_TX_QUAD | SPI_TX_OCTAL | SPI_RX_DUAL \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 				| SPI_RX_QUAD | SPI_RX_OCTAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) struct spidev_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	dev_t			devt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	spinlock_t		spi_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct spi_device	*spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	struct list_head	device_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	/* TX/RX buffers are NULL unless this device is open (users > 0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	struct mutex		buf_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	unsigned		users;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	u8			*tx_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	u8			*rx_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	u32			speed_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) static LIST_HEAD(device_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) static DEFINE_MUTEX(device_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) static unsigned bufsiz = 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) module_param(bufsiz, uint, S_IRUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) MODULE_PARM_DESC(bufsiz, "data bytes in biggest supported SPI message");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) spidev_sync(struct spidev_data *spidev, struct spi_message *message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	struct spi_device *spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	spin_lock_irq(&spidev->spi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	spi = spidev->spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	spin_unlock_irq(&spidev->spi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	if (spi == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		status = -ESHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		status = spi_sync(spi, message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		status = message->actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static inline ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) spidev_sync_write(struct spidev_data *spidev, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	struct spi_transfer	t = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			.tx_buf		= spidev->tx_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			.len		= len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 			.speed_hz	= spidev->speed_hz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	struct spi_message	m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	spi_message_init(&m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	spi_message_add_tail(&t, &m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	return spidev_sync(spidev, &m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static inline ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) spidev_sync_read(struct spidev_data *spidev, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	struct spi_transfer	t = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			.rx_buf		= spidev->rx_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 			.len		= len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 			.speed_hz	= spidev->speed_hz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	struct spi_message	m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	spi_message_init(&m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	spi_message_add_tail(&t, &m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	return spidev_sync(spidev, &m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* Read-only message with current device setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	struct spidev_data	*spidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	ssize_t			status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	/* chipselect only toggles at start or end of operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	if (count > bufsiz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	spidev = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	mutex_lock(&spidev->buf_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	status = spidev_sync_read(spidev, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	if (status > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		unsigned long	missing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		missing = copy_to_user(buf, spidev->rx_buffer, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		if (missing == status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			status = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			status = status - missing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	mutex_unlock(&spidev->buf_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* Write-only message with current device setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) spidev_write(struct file *filp, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		size_t count, loff_t *f_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	struct spidev_data	*spidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	ssize_t			status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	unsigned long		missing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	/* chipselect only toggles at start or end of operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (count > bufsiz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	spidev = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	mutex_lock(&spidev->buf_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	missing = copy_from_user(spidev->tx_buffer, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	if (missing == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		status = spidev_sync_write(spidev, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		status = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	mutex_unlock(&spidev->buf_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static int spidev_message(struct spidev_data *spidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		struct spi_ioc_transfer *u_xfers, unsigned n_xfers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	struct spi_message	msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	struct spi_transfer	*k_xfers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	struct spi_transfer	*k_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	struct spi_ioc_transfer *u_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	unsigned		n, total, tx_total, rx_total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	u8			*tx_buf, *rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	int			status = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	spi_message_init(&msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	k_xfers = kcalloc(n_xfers, sizeof(*k_tmp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	if (k_xfers == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	/* Construct spi_message, copying any tx data to bounce buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	 * We walk the array of user-provided transfers, using each one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	 * to initialize a kernel version of the same transfer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	tx_buf = spidev->tx_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	rx_buf = spidev->rx_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	total = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	tx_total = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	rx_total = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			n--, k_tmp++, u_tmp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		/* Ensure that also following allocations from rx_buf/tx_buf will meet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		 * DMA alignment requirements.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		unsigned int len_aligned = ALIGN(u_tmp->len, ARCH_KMALLOC_MINALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		k_tmp->len = u_tmp->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		total += k_tmp->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		/* Since the function returns the total length of transfers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		 * on success, restrict the total to positive int values to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		 * avoid the return value looking like an error.  Also check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		 * each transfer length to avoid arithmetic overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		if (total > INT_MAX || k_tmp->len > INT_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			status = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		if (u_tmp->rx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			/* this transfer needs space in RX bounce buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			rx_total += len_aligned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			if (rx_total > bufsiz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 				status = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 			k_tmp->rx_buf = rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			rx_buf += len_aligned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		if (u_tmp->tx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 			/* this transfer needs space in TX bounce buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 			tx_total += len_aligned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 			if (tx_total > bufsiz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 				status = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 			k_tmp->tx_buf = tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			if (copy_from_user(tx_buf, (const u8 __user *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 						(uintptr_t) u_tmp->tx_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 					u_tmp->len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 			tx_buf += len_aligned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		k_tmp->cs_change = !!u_tmp->cs_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		k_tmp->tx_nbits = u_tmp->tx_nbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		k_tmp->rx_nbits = u_tmp->rx_nbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		k_tmp->bits_per_word = u_tmp->bits_per_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		k_tmp->delay.value = u_tmp->delay_usecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		k_tmp->delay.unit = SPI_DELAY_UNIT_USECS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		k_tmp->speed_hz = u_tmp->speed_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		k_tmp->word_delay.value = u_tmp->word_delay_usecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		k_tmp->word_delay.unit = SPI_DELAY_UNIT_USECS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		if (!k_tmp->speed_hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			k_tmp->speed_hz = spidev->speed_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) #ifdef VERBOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		dev_dbg(&spidev->spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 			"  xfer len %u %s%s%s%dbits %u usec %u usec %uHz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			k_tmp->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 			k_tmp->rx_buf ? "rx " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			k_tmp->tx_buf ? "tx " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 			k_tmp->cs_change ? "cs " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 			k_tmp->bits_per_word ? : spidev->spi->bits_per_word,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			k_tmp->delay.value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 			k_tmp->word_delay.value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 			k_tmp->speed_hz ? : spidev->spi->max_speed_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		spi_message_add_tail(k_tmp, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	status = spidev_sync(spidev, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	/* copy any rx data out of bounce buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 			n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 			n--, k_tmp++, u_tmp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		if (u_tmp->rx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			if (copy_to_user((u8 __user *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 					(uintptr_t) u_tmp->rx_buf, k_tmp->rx_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 					u_tmp->len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 				status = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	status = total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	kfree(k_xfers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static struct spi_ioc_transfer *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) spidev_get_ioc_message(unsigned int cmd, struct spi_ioc_transfer __user *u_ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		unsigned *n_ioc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	u32	tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	/* Check type, command number and direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	if (_IOC_TYPE(cmd) != SPI_IOC_MAGIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 			|| _IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 			|| _IOC_DIR(cmd) != _IOC_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		return ERR_PTR(-ENOTTY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	tmp = _IOC_SIZE(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	if ((tmp % sizeof(struct spi_ioc_transfer)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	*n_ioc = tmp / sizeof(struct spi_ioc_transfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	if (*n_ioc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	/* copy into scratch area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	return memdup_user(u_ioc, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	int			retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	struct spidev_data	*spidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	struct spi_device	*spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	u32			tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	unsigned		n_ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	struct spi_ioc_transfer	*ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	/* Check type and command number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	if (_IOC_TYPE(cmd) != SPI_IOC_MAGIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	/* guard against device removal before, or while,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	 * we issue this ioctl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	spidev = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	spin_lock_irq(&spidev->spi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	spi = spi_dev_get(spidev->spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	spin_unlock_irq(&spidev->spi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	if (spi == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		return -ESHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	/* use the buffer lock here for triple duty:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	 *  - prevent I/O (from us) so calling spi_setup() is safe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	 *  - prevent concurrent SPI_IOC_WR_* from morphing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	 *    data fields while SPI_IOC_RD_* reads them;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	 *  - SPI_IOC_MESSAGE needs the buffer locked "normally".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	mutex_lock(&spidev->buf_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	/* read requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	case SPI_IOC_RD_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		retval = put_user(spi->mode & SPI_MODE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 					(__u8 __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	case SPI_IOC_RD_MODE32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		retval = put_user(spi->mode & SPI_MODE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 					(__u32 __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	case SPI_IOC_RD_LSB_FIRST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		retval = put_user((spi->mode & SPI_LSB_FIRST) ?  1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 					(__u8 __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	case SPI_IOC_RD_BITS_PER_WORD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		retval = put_user(spi->bits_per_word, (__u8 __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	case SPI_IOC_RD_MAX_SPEED_HZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		retval = put_user(spidev->speed_hz, (__u32 __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	/* write requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	case SPI_IOC_WR_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	case SPI_IOC_WR_MODE32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		if (cmd == SPI_IOC_WR_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 			retval = get_user(tmp, (u8 __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			retval = get_user(tmp, (u32 __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		if (retval == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			struct spi_controller *ctlr = spi->controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 			u32	save = spi->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 			if (tmp & ~SPI_MODE_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 				retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 			if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 			    ctlr->cs_gpiods[spi->chip_select])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 				tmp |= SPI_CS_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 			tmp |= spi->mode & ~SPI_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 			spi->mode = (u16)tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			retval = spi_setup(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 			if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 				spi->mode = save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 				dev_dbg(&spi->dev, "spi mode %x\n", tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	case SPI_IOC_WR_LSB_FIRST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		retval = get_user(tmp, (__u8 __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		if (retval == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 			u32	save = spi->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 			if (tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 				spi->mode |= SPI_LSB_FIRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 				spi->mode &= ~SPI_LSB_FIRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 			retval = spi_setup(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 				spi->mode = save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 				dev_dbg(&spi->dev, "%csb first\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 						tmp ? 'l' : 'm');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	case SPI_IOC_WR_BITS_PER_WORD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		retval = get_user(tmp, (__u8 __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		if (retval == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 			u8	save = spi->bits_per_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 			spi->bits_per_word = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 			retval = spi_setup(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 			if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 				spi->bits_per_word = save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 				dev_dbg(&spi->dev, "%d bits per word\n", tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	case SPI_IOC_WR_MAX_SPEED_HZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		retval = get_user(tmp, (__u32 __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		if (retval == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 			u32	save = spi->max_speed_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 			spi->max_speed_hz = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 			retval = spi_setup(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 			if (retval == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 				spidev->speed_hz = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 				dev_dbg(&spi->dev, "%d Hz (max)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 					spidev->speed_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 			spi->max_speed_hz = save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		/* segmented and/or full-duplex I/O request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		/* Check message and copy into scratch area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		ioc = spidev_get_ioc_message(cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 				(struct spi_ioc_transfer __user *)arg, &n_ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		if (IS_ERR(ioc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 			retval = PTR_ERR(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		if (!ioc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 			break;	/* n_ioc is also 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		/* translate to spi_message, execute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		retval = spidev_message(spidev, ioc, n_ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		kfree(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	mutex_unlock(&spidev->buf_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	spi_dev_put(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) static long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) spidev_compat_ioc_message(struct file *filp, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	struct spi_ioc_transfer __user	*u_ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	int				retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	struct spidev_data		*spidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	struct spi_device		*spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	unsigned			n_ioc, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	struct spi_ioc_transfer		*ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	u_ioc = (struct spi_ioc_transfer __user *) compat_ptr(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	/* guard against device removal before, or while,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	 * we issue this ioctl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	spidev = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	spin_lock_irq(&spidev->spi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	spi = spi_dev_get(spidev->spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	spin_unlock_irq(&spidev->spi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	if (spi == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		return -ESHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	/* SPI_IOC_MESSAGE needs the buffer locked "normally" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	mutex_lock(&spidev->buf_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	/* Check message and copy into scratch area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	ioc = spidev_get_ioc_message(cmd, u_ioc, &n_ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	if (IS_ERR(ioc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		retval = PTR_ERR(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	if (!ioc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		goto done;	/* n_ioc is also 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	/* Convert buffer pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	for (n = 0; n < n_ioc; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		ioc[n].rx_buf = (uintptr_t) compat_ptr(ioc[n].rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		ioc[n].tx_buf = (uintptr_t) compat_ptr(ioc[n].tx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	/* translate to spi_message, execute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	retval = spidev_message(spidev, ioc, n_ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	kfree(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	mutex_unlock(&spidev->buf_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	spi_dev_put(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) static long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) spidev_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	if (_IOC_TYPE(cmd) == SPI_IOC_MAGIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 			&& _IOC_NR(cmd) == _IOC_NR(SPI_IOC_MESSAGE(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 			&& _IOC_DIR(cmd) == _IOC_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		return spidev_compat_ioc_message(filp, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	return spidev_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) #define spidev_compat_ioctl NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) #endif /* CONFIG_COMPAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) static int spidev_open(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	struct spidev_data	*spidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	int			status = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	mutex_lock(&device_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	list_for_each_entry(spidev, &device_list, device_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		if (spidev->devt == inode->i_rdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 			status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		pr_debug("spidev: nothing for minor %d\n", iminor(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		goto err_find_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	if (!spidev->tx_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 		spidev->tx_buffer = kmalloc(bufsiz, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		if (!spidev->tx_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 			dev_dbg(&spidev->spi->dev, "open/ENOMEM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 			status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 			goto err_find_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	if (!spidev->rx_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 		spidev->rx_buffer = kmalloc(bufsiz, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 		if (!spidev->rx_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 			dev_dbg(&spidev->spi->dev, "open/ENOMEM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 			status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 			goto err_alloc_rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	spidev->users++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	filp->private_data = spidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	stream_open(inode, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	mutex_unlock(&device_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) err_alloc_rx_buf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	kfree(spidev->tx_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	spidev->tx_buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) err_find_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	mutex_unlock(&device_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static int spidev_release(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	struct spidev_data	*spidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	int			dofree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	mutex_lock(&device_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	spidev = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	filp->private_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	spin_lock_irq(&spidev->spi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	/* ... after we unbound from the underlying device? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	dofree = (spidev->spi == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	spin_unlock_irq(&spidev->spi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	/* last close? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	spidev->users--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	if (!spidev->users) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 		kfree(spidev->tx_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 		spidev->tx_buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		kfree(spidev->rx_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		spidev->rx_buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		if (dofree)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 			kfree(spidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 			spidev->speed_hz = spidev->spi->max_speed_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) #ifdef CONFIG_SPI_SLAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	if (!dofree)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 		spi_slave_abort(spidev->spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	mutex_unlock(&device_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static const struct file_operations spidev_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	.owner =	THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	/* REVISIT switch to aio primitives, so that userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	 * gets more complete API coverage.  It'll simplify things
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	 * too, except for the locking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	.write =	spidev_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	.read =		spidev_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	.unlocked_ioctl = spidev_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	.compat_ioctl = spidev_compat_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	.open =		spidev_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	.release =	spidev_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	.llseek =	no_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /* The main reason to have this class is to make mdev/udev create the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)  * /dev/spidevB.C character device nodes exposing our userspace API.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)  * It also simplifies memory management.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static struct class *spidev_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static const struct of_device_id spidev_dt_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	{ .compatible = "rohm,dh2228fv" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	{ .compatible = "lineartechnology,ltc2488" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	{ .compatible = "ge,achc" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	{ .compatible = "semtech,sx1301" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	{ .compatible = "lwn,bk4" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	{ .compatible = "dh,dhcom-board" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	{ .compatible = "menlo,m53cpld" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	{ .compatible = "rockchip,spidev" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) MODULE_DEVICE_TABLE(of, spidev_dt_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /* Dummy SPI devices not to be used in production systems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) #define SPIDEV_ACPI_DUMMY	1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) static const struct acpi_device_id spidev_acpi_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	 * The ACPI SPT000* devices are only meant for development and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	 * testing. Systems used in production should have a proper ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	 * description of the connected peripheral and they should also use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	 * a proper driver instead of poking directly to the SPI bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	{ "SPT0001", SPIDEV_ACPI_DUMMY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	{ "SPT0002", SPIDEV_ACPI_DUMMY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	{ "SPT0003", SPIDEV_ACPI_DUMMY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) MODULE_DEVICE_TABLE(acpi, spidev_acpi_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) static void spidev_probe_acpi(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	const struct acpi_device_id *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	if (!has_acpi_companion(&spi->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	id = acpi_match_device(spidev_acpi_ids, &spi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	if (WARN_ON(!id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	if (id->driver_data == SPIDEV_ACPI_DUMMY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		dev_warn(&spi->dev, "do not use this driver in production systems!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) static inline void spidev_probe_acpi(struct spi_device *spi) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static int spidev_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	struct spidev_data	*spidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	int			status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	unsigned long		minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	 * spidev should never be referenced in DT without a specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	 * compatible string, it is a Linux implementation thing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	 * rather than a description of the hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	WARN(spi->dev.of_node &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	     of_device_is_compatible(spi->dev.of_node, "spidev"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	     "%pOF: buggy DT: spidev listed directly in DT\n", spi->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	spidev_probe_acpi(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	/* Allocate driver data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	spidev = kzalloc(sizeof(*spidev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	if (!spidev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 	/* Initialize the driver data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	spidev->spi = spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	spin_lock_init(&spidev->spi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	mutex_init(&spidev->buf_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	INIT_LIST_HEAD(&spidev->device_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	/* If we can allocate a minor number, hook up this device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	 * Reusing minors is fine so long as udev or mdev is working.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	mutex_lock(&device_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	minor = find_first_zero_bit(minors, N_SPI_MINORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	if (minor < N_SPI_MINORS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 		struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 		spidev->devt = MKDEV(SPIDEV_MAJOR, minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 		dev = device_create(spidev_class, &spi->dev, spidev->devt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 				    spidev, "spidev%d.%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 				    spi->master->bus_num, spi->chip_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 		status = PTR_ERR_OR_ZERO(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 		dev_dbg(&spi->dev, "no minor number available!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 		status = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	if (status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		set_bit(minor, minors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 		list_add(&spidev->device_entry, &device_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	mutex_unlock(&device_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	spidev->speed_hz = spi->max_speed_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 		spi_set_drvdata(spi, spidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 		kfree(spidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static int spidev_remove(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 	struct spidev_data	*spidev = spi_get_drvdata(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 	/* prevent new opens */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	mutex_lock(&device_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	/* make sure ops on existing fds can abort cleanly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	spin_lock_irq(&spidev->spi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	spidev->spi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 	spin_unlock_irq(&spidev->spi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 	list_del(&spidev->device_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 	device_destroy(spidev_class, spidev->devt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 	clear_bit(MINOR(spidev->devt), minors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	if (spidev->users == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 		kfree(spidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	mutex_unlock(&device_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) static struct spi_driver spidev_spi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 		.name =		"spidev",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 		.of_match_table = of_match_ptr(spidev_dt_ids),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 		.acpi_match_table = ACPI_PTR(spidev_acpi_ids),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 	.probe =	spidev_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 	.remove =	spidev_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 	/* NOTE:  suspend/resume methods are not necessary here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 	 * We don't do anything except pass the requests to/from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 	 * the underlying controller.  The refrigerator handles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 	 * most issues; the controller driver handles the rest.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) static int __init spidev_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	/* Claim our 256 reserved device numbers.  Then register a class
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 	 * that will key udev/mdev to add/remove /dev nodes.  Last, register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 	 * the driver which manages those device numbers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 	BUILD_BUG_ON(N_SPI_MINORS > 256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	status = register_chrdev(SPIDEV_MAJOR, "spi", &spidev_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 	spidev_class = class_create(THIS_MODULE, "spidev");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 	if (IS_ERR(spidev_class)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 		unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 		return PTR_ERR(spidev_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 	status = spi_register_driver(&spidev_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 	if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 		class_destroy(spidev_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 		unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) module_init(spidev_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) static void __exit spidev_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 	spi_unregister_driver(&spidev_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 	class_destroy(spidev_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 	unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) module_exit(spidev_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) MODULE_AUTHOR("Andrea Paterniani, <a.paterniani@swapp-eng.it>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) MODULE_DESCRIPTION("User mode SPI device interface");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) MODULE_ALIAS("spi:spidev");