^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");