18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci// SPI init/core code 38c2ecf20Sopenharmony_ci// 48c2ecf20Sopenharmony_ci// Copyright (C) 2005 David Brownell 58c2ecf20Sopenharmony_ci// Copyright (C) 2008 Secret Lab Technologies Ltd. 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/kernel.h> 88c2ecf20Sopenharmony_ci#include <linux/device.h> 98c2ecf20Sopenharmony_ci#include <linux/init.h> 108c2ecf20Sopenharmony_ci#include <linux/cache.h> 118c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h> 128c2ecf20Sopenharmony_ci#include <linux/dmaengine.h> 138c2ecf20Sopenharmony_ci#include <linux/mutex.h> 148c2ecf20Sopenharmony_ci#include <linux/of_device.h> 158c2ecf20Sopenharmony_ci#include <linux/of_irq.h> 168c2ecf20Sopenharmony_ci#include <linux/clk/clk-conf.h> 178c2ecf20Sopenharmony_ci#include <linux/slab.h> 188c2ecf20Sopenharmony_ci#include <linux/mod_devicetable.h> 198c2ecf20Sopenharmony_ci#include <linux/spi/spi.h> 208c2ecf20Sopenharmony_ci#include <linux/spi/spi-mem.h> 218c2ecf20Sopenharmony_ci#include <linux/of_gpio.h> 228c2ecf20Sopenharmony_ci#include <linux/gpio/consumer.h> 238c2ecf20Sopenharmony_ci#include <linux/pm_runtime.h> 248c2ecf20Sopenharmony_ci#include <linux/pm_domain.h> 258c2ecf20Sopenharmony_ci#include <linux/property.h> 268c2ecf20Sopenharmony_ci#include <linux/export.h> 278c2ecf20Sopenharmony_ci#include <linux/sched/rt.h> 288c2ecf20Sopenharmony_ci#include <uapi/linux/sched/types.h> 298c2ecf20Sopenharmony_ci#include <linux/delay.h> 308c2ecf20Sopenharmony_ci#include <linux/kthread.h> 318c2ecf20Sopenharmony_ci#include <linux/ioport.h> 328c2ecf20Sopenharmony_ci#include <linux/acpi.h> 338c2ecf20Sopenharmony_ci#include <linux/highmem.h> 348c2ecf20Sopenharmony_ci#include <linux/idr.h> 358c2ecf20Sopenharmony_ci#include <linux/platform_data/x86/apple.h> 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#define CREATE_TRACE_POINTS 388c2ecf20Sopenharmony_ci#include <trace/events/spi.h> 398c2ecf20Sopenharmony_ciEXPORT_TRACEPOINT_SYMBOL(spi_transfer_start); 408c2ecf20Sopenharmony_ciEXPORT_TRACEPOINT_SYMBOL(spi_transfer_stop); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci#include "internals.h" 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cistatic DEFINE_IDR(spi_master_idr); 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic void spidev_release(struct device *dev) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci struct spi_device *spi = to_spi_device(dev); 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci spi_controller_put(spi->controller); 518c2ecf20Sopenharmony_ci kfree(spi->driver_override); 528c2ecf20Sopenharmony_ci kfree(spi); 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistatic ssize_t 568c2ecf20Sopenharmony_cimodalias_show(struct device *dev, struct device_attribute *a, char *buf) 578c2ecf20Sopenharmony_ci{ 588c2ecf20Sopenharmony_ci const struct spi_device *spi = to_spi_device(dev); 598c2ecf20Sopenharmony_ci int len; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci len = acpi_device_modalias(dev, buf, PAGE_SIZE - 1); 628c2ecf20Sopenharmony_ci if (len != -ENODEV) 638c2ecf20Sopenharmony_ci return len; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci return sprintf(buf, "%s%s\n", SPI_MODULE_PREFIX, spi->modalias); 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(modalias); 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_cistatic ssize_t driver_override_store(struct device *dev, 708c2ecf20Sopenharmony_ci struct device_attribute *a, 718c2ecf20Sopenharmony_ci const char *buf, size_t count) 728c2ecf20Sopenharmony_ci{ 738c2ecf20Sopenharmony_ci struct spi_device *spi = to_spi_device(dev); 748c2ecf20Sopenharmony_ci const char *end = memchr(buf, '\n', count); 758c2ecf20Sopenharmony_ci const size_t len = end ? end - buf : count; 768c2ecf20Sopenharmony_ci const char *driver_override, *old; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci /* We need to keep extra room for a newline when displaying value */ 798c2ecf20Sopenharmony_ci if (len >= (PAGE_SIZE - 1)) 808c2ecf20Sopenharmony_ci return -EINVAL; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci driver_override = kstrndup(buf, len, GFP_KERNEL); 838c2ecf20Sopenharmony_ci if (!driver_override) 848c2ecf20Sopenharmony_ci return -ENOMEM; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci device_lock(dev); 878c2ecf20Sopenharmony_ci old = spi->driver_override; 888c2ecf20Sopenharmony_ci if (len) { 898c2ecf20Sopenharmony_ci spi->driver_override = driver_override; 908c2ecf20Sopenharmony_ci } else { 918c2ecf20Sopenharmony_ci /* Empty string, disable driver override */ 928c2ecf20Sopenharmony_ci spi->driver_override = NULL; 938c2ecf20Sopenharmony_ci kfree(driver_override); 948c2ecf20Sopenharmony_ci } 958c2ecf20Sopenharmony_ci device_unlock(dev); 968c2ecf20Sopenharmony_ci kfree(old); 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci return count; 998c2ecf20Sopenharmony_ci} 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_cistatic ssize_t driver_override_show(struct device *dev, 1028c2ecf20Sopenharmony_ci struct device_attribute *a, char *buf) 1038c2ecf20Sopenharmony_ci{ 1048c2ecf20Sopenharmony_ci const struct spi_device *spi = to_spi_device(dev); 1058c2ecf20Sopenharmony_ci ssize_t len; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci device_lock(dev); 1088c2ecf20Sopenharmony_ci len = snprintf(buf, PAGE_SIZE, "%s\n", spi->driver_override ? : ""); 1098c2ecf20Sopenharmony_ci device_unlock(dev); 1108c2ecf20Sopenharmony_ci return len; 1118c2ecf20Sopenharmony_ci} 1128c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RW(driver_override); 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci#define SPI_STATISTICS_ATTRS(field, file) \ 1158c2ecf20Sopenharmony_cistatic ssize_t spi_controller_##field##_show(struct device *dev, \ 1168c2ecf20Sopenharmony_ci struct device_attribute *attr, \ 1178c2ecf20Sopenharmony_ci char *buf) \ 1188c2ecf20Sopenharmony_ci{ \ 1198c2ecf20Sopenharmony_ci struct spi_controller *ctlr = container_of(dev, \ 1208c2ecf20Sopenharmony_ci struct spi_controller, dev); \ 1218c2ecf20Sopenharmony_ci return spi_statistics_##field##_show(&ctlr->statistics, buf); \ 1228c2ecf20Sopenharmony_ci} \ 1238c2ecf20Sopenharmony_cistatic struct device_attribute dev_attr_spi_controller_##field = { \ 1248c2ecf20Sopenharmony_ci .attr = { .name = file, .mode = 0444 }, \ 1258c2ecf20Sopenharmony_ci .show = spi_controller_##field##_show, \ 1268c2ecf20Sopenharmony_ci}; \ 1278c2ecf20Sopenharmony_cistatic ssize_t spi_device_##field##_show(struct device *dev, \ 1288c2ecf20Sopenharmony_ci struct device_attribute *attr, \ 1298c2ecf20Sopenharmony_ci char *buf) \ 1308c2ecf20Sopenharmony_ci{ \ 1318c2ecf20Sopenharmony_ci struct spi_device *spi = to_spi_device(dev); \ 1328c2ecf20Sopenharmony_ci return spi_statistics_##field##_show(&spi->statistics, buf); \ 1338c2ecf20Sopenharmony_ci} \ 1348c2ecf20Sopenharmony_cistatic struct device_attribute dev_attr_spi_device_##field = { \ 1358c2ecf20Sopenharmony_ci .attr = { .name = file, .mode = 0444 }, \ 1368c2ecf20Sopenharmony_ci .show = spi_device_##field##_show, \ 1378c2ecf20Sopenharmony_ci} 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci#define SPI_STATISTICS_SHOW_NAME(name, file, field, format_string) \ 1408c2ecf20Sopenharmony_cistatic ssize_t spi_statistics_##name##_show(struct spi_statistics *stat, \ 1418c2ecf20Sopenharmony_ci char *buf) \ 1428c2ecf20Sopenharmony_ci{ \ 1438c2ecf20Sopenharmony_ci unsigned long flags; \ 1448c2ecf20Sopenharmony_ci ssize_t len; \ 1458c2ecf20Sopenharmony_ci spin_lock_irqsave(&stat->lock, flags); \ 1468c2ecf20Sopenharmony_ci len = sprintf(buf, format_string, stat->field); \ 1478c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&stat->lock, flags); \ 1488c2ecf20Sopenharmony_ci return len; \ 1498c2ecf20Sopenharmony_ci} \ 1508c2ecf20Sopenharmony_ciSPI_STATISTICS_ATTRS(name, file) 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci#define SPI_STATISTICS_SHOW(field, format_string) \ 1538c2ecf20Sopenharmony_ci SPI_STATISTICS_SHOW_NAME(field, __stringify(field), \ 1548c2ecf20Sopenharmony_ci field, format_string) 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ciSPI_STATISTICS_SHOW(messages, "%lu"); 1578c2ecf20Sopenharmony_ciSPI_STATISTICS_SHOW(transfers, "%lu"); 1588c2ecf20Sopenharmony_ciSPI_STATISTICS_SHOW(errors, "%lu"); 1598c2ecf20Sopenharmony_ciSPI_STATISTICS_SHOW(timedout, "%lu"); 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ciSPI_STATISTICS_SHOW(spi_sync, "%lu"); 1628c2ecf20Sopenharmony_ciSPI_STATISTICS_SHOW(spi_sync_immediate, "%lu"); 1638c2ecf20Sopenharmony_ciSPI_STATISTICS_SHOW(spi_async, "%lu"); 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ciSPI_STATISTICS_SHOW(bytes, "%llu"); 1668c2ecf20Sopenharmony_ciSPI_STATISTICS_SHOW(bytes_rx, "%llu"); 1678c2ecf20Sopenharmony_ciSPI_STATISTICS_SHOW(bytes_tx, "%llu"); 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci#define SPI_STATISTICS_TRANSFER_BYTES_HISTO(index, number) \ 1708c2ecf20Sopenharmony_ci SPI_STATISTICS_SHOW_NAME(transfer_bytes_histo##index, \ 1718c2ecf20Sopenharmony_ci "transfer_bytes_histo_" number, \ 1728c2ecf20Sopenharmony_ci transfer_bytes_histo[index], "%lu") 1738c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(0, "0-1"); 1748c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(1, "2-3"); 1758c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(2, "4-7"); 1768c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(3, "8-15"); 1778c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(4, "16-31"); 1788c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(5, "32-63"); 1798c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(6, "64-127"); 1808c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(7, "128-255"); 1818c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(8, "256-511"); 1828c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(9, "512-1023"); 1838c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(10, "1024-2047"); 1848c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(11, "2048-4095"); 1858c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(12, "4096-8191"); 1868c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(13, "8192-16383"); 1878c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(14, "16384-32767"); 1888c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(15, "32768-65535"); 1898c2ecf20Sopenharmony_ciSPI_STATISTICS_TRANSFER_BYTES_HISTO(16, "65536+"); 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ciSPI_STATISTICS_SHOW(transfers_split_maxsize, "%lu"); 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cistatic struct attribute *spi_dev_attrs[] = { 1948c2ecf20Sopenharmony_ci &dev_attr_modalias.attr, 1958c2ecf20Sopenharmony_ci &dev_attr_driver_override.attr, 1968c2ecf20Sopenharmony_ci NULL, 1978c2ecf20Sopenharmony_ci}; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_cistatic const struct attribute_group spi_dev_group = { 2008c2ecf20Sopenharmony_ci .attrs = spi_dev_attrs, 2018c2ecf20Sopenharmony_ci}; 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_cistatic struct attribute *spi_device_statistics_attrs[] = { 2048c2ecf20Sopenharmony_ci &dev_attr_spi_device_messages.attr, 2058c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfers.attr, 2068c2ecf20Sopenharmony_ci &dev_attr_spi_device_errors.attr, 2078c2ecf20Sopenharmony_ci &dev_attr_spi_device_timedout.attr, 2088c2ecf20Sopenharmony_ci &dev_attr_spi_device_spi_sync.attr, 2098c2ecf20Sopenharmony_ci &dev_attr_spi_device_spi_sync_immediate.attr, 2108c2ecf20Sopenharmony_ci &dev_attr_spi_device_spi_async.attr, 2118c2ecf20Sopenharmony_ci &dev_attr_spi_device_bytes.attr, 2128c2ecf20Sopenharmony_ci &dev_attr_spi_device_bytes_rx.attr, 2138c2ecf20Sopenharmony_ci &dev_attr_spi_device_bytes_tx.attr, 2148c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo0.attr, 2158c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo1.attr, 2168c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo2.attr, 2178c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo3.attr, 2188c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo4.attr, 2198c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo5.attr, 2208c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo6.attr, 2218c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo7.attr, 2228c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo8.attr, 2238c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo9.attr, 2248c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo10.attr, 2258c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo11.attr, 2268c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo12.attr, 2278c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo13.attr, 2288c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo14.attr, 2298c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo15.attr, 2308c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfer_bytes_histo16.attr, 2318c2ecf20Sopenharmony_ci &dev_attr_spi_device_transfers_split_maxsize.attr, 2328c2ecf20Sopenharmony_ci NULL, 2338c2ecf20Sopenharmony_ci}; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_cistatic const struct attribute_group spi_device_statistics_group = { 2368c2ecf20Sopenharmony_ci .name = "statistics", 2378c2ecf20Sopenharmony_ci .attrs = spi_device_statistics_attrs, 2388c2ecf20Sopenharmony_ci}; 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_cistatic const struct attribute_group *spi_dev_groups[] = { 2418c2ecf20Sopenharmony_ci &spi_dev_group, 2428c2ecf20Sopenharmony_ci &spi_device_statistics_group, 2438c2ecf20Sopenharmony_ci NULL, 2448c2ecf20Sopenharmony_ci}; 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_cistatic struct attribute *spi_controller_statistics_attrs[] = { 2478c2ecf20Sopenharmony_ci &dev_attr_spi_controller_messages.attr, 2488c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfers.attr, 2498c2ecf20Sopenharmony_ci &dev_attr_spi_controller_errors.attr, 2508c2ecf20Sopenharmony_ci &dev_attr_spi_controller_timedout.attr, 2518c2ecf20Sopenharmony_ci &dev_attr_spi_controller_spi_sync.attr, 2528c2ecf20Sopenharmony_ci &dev_attr_spi_controller_spi_sync_immediate.attr, 2538c2ecf20Sopenharmony_ci &dev_attr_spi_controller_spi_async.attr, 2548c2ecf20Sopenharmony_ci &dev_attr_spi_controller_bytes.attr, 2558c2ecf20Sopenharmony_ci &dev_attr_spi_controller_bytes_rx.attr, 2568c2ecf20Sopenharmony_ci &dev_attr_spi_controller_bytes_tx.attr, 2578c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo0.attr, 2588c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo1.attr, 2598c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo2.attr, 2608c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo3.attr, 2618c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo4.attr, 2628c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo5.attr, 2638c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo6.attr, 2648c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo7.attr, 2658c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo8.attr, 2668c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo9.attr, 2678c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo10.attr, 2688c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo11.attr, 2698c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo12.attr, 2708c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo13.attr, 2718c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo14.attr, 2728c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo15.attr, 2738c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfer_bytes_histo16.attr, 2748c2ecf20Sopenharmony_ci &dev_attr_spi_controller_transfers_split_maxsize.attr, 2758c2ecf20Sopenharmony_ci NULL, 2768c2ecf20Sopenharmony_ci}; 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_cistatic const struct attribute_group spi_controller_statistics_group = { 2798c2ecf20Sopenharmony_ci .name = "statistics", 2808c2ecf20Sopenharmony_ci .attrs = spi_controller_statistics_attrs, 2818c2ecf20Sopenharmony_ci}; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_cistatic const struct attribute_group *spi_master_groups[] = { 2848c2ecf20Sopenharmony_ci &spi_controller_statistics_group, 2858c2ecf20Sopenharmony_ci NULL, 2868c2ecf20Sopenharmony_ci}; 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_civoid spi_statistics_add_transfer_stats(struct spi_statistics *stats, 2898c2ecf20Sopenharmony_ci struct spi_transfer *xfer, 2908c2ecf20Sopenharmony_ci struct spi_controller *ctlr) 2918c2ecf20Sopenharmony_ci{ 2928c2ecf20Sopenharmony_ci unsigned long flags; 2938c2ecf20Sopenharmony_ci int l2len = min(fls(xfer->len), SPI_STATISTICS_HISTO_SIZE) - 1; 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci if (l2len < 0) 2968c2ecf20Sopenharmony_ci l2len = 0; 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci spin_lock_irqsave(&stats->lock, flags); 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci stats->transfers++; 3018c2ecf20Sopenharmony_ci stats->transfer_bytes_histo[l2len]++; 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci stats->bytes += xfer->len; 3048c2ecf20Sopenharmony_ci if ((xfer->tx_buf) && 3058c2ecf20Sopenharmony_ci (xfer->tx_buf != ctlr->dummy_tx)) 3068c2ecf20Sopenharmony_ci stats->bytes_tx += xfer->len; 3078c2ecf20Sopenharmony_ci if ((xfer->rx_buf) && 3088c2ecf20Sopenharmony_ci (xfer->rx_buf != ctlr->dummy_rx)) 3098c2ecf20Sopenharmony_ci stats->bytes_rx += xfer->len; 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&stats->lock, flags); 3128c2ecf20Sopenharmony_ci} 3138c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_statistics_add_transfer_stats); 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci/* modalias support makes "modprobe $MODALIAS" new-style hotplug work, 3168c2ecf20Sopenharmony_ci * and the sysfs version makes coldplug work too. 3178c2ecf20Sopenharmony_ci */ 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_cistatic const struct spi_device_id *spi_match_id(const struct spi_device_id *id, 3208c2ecf20Sopenharmony_ci const struct spi_device *sdev) 3218c2ecf20Sopenharmony_ci{ 3228c2ecf20Sopenharmony_ci while (id->name[0]) { 3238c2ecf20Sopenharmony_ci if (!strcmp(sdev->modalias, id->name)) 3248c2ecf20Sopenharmony_ci return id; 3258c2ecf20Sopenharmony_ci id++; 3268c2ecf20Sopenharmony_ci } 3278c2ecf20Sopenharmony_ci return NULL; 3288c2ecf20Sopenharmony_ci} 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ciconst struct spi_device_id *spi_get_device_id(const struct spi_device *sdev) 3318c2ecf20Sopenharmony_ci{ 3328c2ecf20Sopenharmony_ci const struct spi_driver *sdrv = to_spi_driver(sdev->dev.driver); 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci return spi_match_id(sdrv->id_table, sdev); 3358c2ecf20Sopenharmony_ci} 3368c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_get_device_id); 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_cistatic int spi_match_device(struct device *dev, struct device_driver *drv) 3398c2ecf20Sopenharmony_ci{ 3408c2ecf20Sopenharmony_ci const struct spi_device *spi = to_spi_device(dev); 3418c2ecf20Sopenharmony_ci const struct spi_driver *sdrv = to_spi_driver(drv); 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci /* Check override first, and if set, only use the named driver */ 3448c2ecf20Sopenharmony_ci if (spi->driver_override) 3458c2ecf20Sopenharmony_ci return strcmp(spi->driver_override, drv->name) == 0; 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci /* Attempt an OF style match */ 3488c2ecf20Sopenharmony_ci if (of_driver_match_device(dev, drv)) 3498c2ecf20Sopenharmony_ci return 1; 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci /* Then try ACPI */ 3528c2ecf20Sopenharmony_ci if (acpi_driver_match_device(dev, drv)) 3538c2ecf20Sopenharmony_ci return 1; 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci if (sdrv->id_table) 3568c2ecf20Sopenharmony_ci return !!spi_match_id(sdrv->id_table, spi); 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci return strcmp(spi->modalias, drv->name) == 0; 3598c2ecf20Sopenharmony_ci} 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_cistatic int spi_uevent(struct device *dev, struct kobj_uevent_env *env) 3628c2ecf20Sopenharmony_ci{ 3638c2ecf20Sopenharmony_ci const struct spi_device *spi = to_spi_device(dev); 3648c2ecf20Sopenharmony_ci int rc; 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci rc = acpi_device_uevent_modalias(dev, env); 3678c2ecf20Sopenharmony_ci if (rc != -ENODEV) 3688c2ecf20Sopenharmony_ci return rc; 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci return add_uevent_var(env, "MODALIAS=%s%s", SPI_MODULE_PREFIX, spi->modalias); 3718c2ecf20Sopenharmony_ci} 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_cistruct bus_type spi_bus_type = { 3748c2ecf20Sopenharmony_ci .name = "spi", 3758c2ecf20Sopenharmony_ci .dev_groups = spi_dev_groups, 3768c2ecf20Sopenharmony_ci .match = spi_match_device, 3778c2ecf20Sopenharmony_ci .uevent = spi_uevent, 3788c2ecf20Sopenharmony_ci}; 3798c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_bus_type); 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_cistatic int spi_drv_probe(struct device *dev) 3838c2ecf20Sopenharmony_ci{ 3848c2ecf20Sopenharmony_ci const struct spi_driver *sdrv = to_spi_driver(dev->driver); 3858c2ecf20Sopenharmony_ci struct spi_device *spi = to_spi_device(dev); 3868c2ecf20Sopenharmony_ci int ret; 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci ret = of_clk_set_defaults(dev->of_node, false); 3898c2ecf20Sopenharmony_ci if (ret) 3908c2ecf20Sopenharmony_ci return ret; 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_ci if (dev->of_node) { 3938c2ecf20Sopenharmony_ci spi->irq = of_irq_get(dev->of_node, 0); 3948c2ecf20Sopenharmony_ci if (spi->irq == -EPROBE_DEFER) 3958c2ecf20Sopenharmony_ci return -EPROBE_DEFER; 3968c2ecf20Sopenharmony_ci if (spi->irq < 0) 3978c2ecf20Sopenharmony_ci spi->irq = 0; 3988c2ecf20Sopenharmony_ci } 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci ret = dev_pm_domain_attach(dev, true); 4018c2ecf20Sopenharmony_ci if (ret) 4028c2ecf20Sopenharmony_ci return ret; 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci if (sdrv->probe) { 4058c2ecf20Sopenharmony_ci ret = sdrv->probe(spi); 4068c2ecf20Sopenharmony_ci if (ret) 4078c2ecf20Sopenharmony_ci dev_pm_domain_detach(dev, true); 4088c2ecf20Sopenharmony_ci } 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci return ret; 4118c2ecf20Sopenharmony_ci} 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_cistatic int spi_drv_remove(struct device *dev) 4148c2ecf20Sopenharmony_ci{ 4158c2ecf20Sopenharmony_ci const struct spi_driver *sdrv = to_spi_driver(dev->driver); 4168c2ecf20Sopenharmony_ci int ret = 0; 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci if (sdrv->remove) 4198c2ecf20Sopenharmony_ci ret = sdrv->remove(to_spi_device(dev)); 4208c2ecf20Sopenharmony_ci dev_pm_domain_detach(dev, true); 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ci return ret; 4238c2ecf20Sopenharmony_ci} 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_cistatic void spi_drv_shutdown(struct device *dev) 4268c2ecf20Sopenharmony_ci{ 4278c2ecf20Sopenharmony_ci const struct spi_driver *sdrv = to_spi_driver(dev->driver); 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci sdrv->shutdown(to_spi_device(dev)); 4308c2ecf20Sopenharmony_ci} 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_ci/** 4338c2ecf20Sopenharmony_ci * __spi_register_driver - register a SPI driver 4348c2ecf20Sopenharmony_ci * @owner: owner module of the driver to register 4358c2ecf20Sopenharmony_ci * @sdrv: the driver to register 4368c2ecf20Sopenharmony_ci * Context: can sleep 4378c2ecf20Sopenharmony_ci * 4388c2ecf20Sopenharmony_ci * Return: zero on success, else a negative error code. 4398c2ecf20Sopenharmony_ci */ 4408c2ecf20Sopenharmony_ciint __spi_register_driver(struct module *owner, struct spi_driver *sdrv) 4418c2ecf20Sopenharmony_ci{ 4428c2ecf20Sopenharmony_ci sdrv->driver.owner = owner; 4438c2ecf20Sopenharmony_ci sdrv->driver.bus = &spi_bus_type; 4448c2ecf20Sopenharmony_ci sdrv->driver.probe = spi_drv_probe; 4458c2ecf20Sopenharmony_ci sdrv->driver.remove = spi_drv_remove; 4468c2ecf20Sopenharmony_ci if (sdrv->shutdown) 4478c2ecf20Sopenharmony_ci sdrv->driver.shutdown = spi_drv_shutdown; 4488c2ecf20Sopenharmony_ci return driver_register(&sdrv->driver); 4498c2ecf20Sopenharmony_ci} 4508c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(__spi_register_driver); 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_ci/*-------------------------------------------------------------------------*/ 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci/* SPI devices should normally not be created by SPI device drivers; that 4558c2ecf20Sopenharmony_ci * would make them board-specific. Similarly with SPI controller drivers. 4568c2ecf20Sopenharmony_ci * Device registration normally goes into like arch/.../mach.../board-YYY.c 4578c2ecf20Sopenharmony_ci * with other readonly (flashable) information about mainboard devices. 4588c2ecf20Sopenharmony_ci */ 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_cistruct boardinfo { 4618c2ecf20Sopenharmony_ci struct list_head list; 4628c2ecf20Sopenharmony_ci struct spi_board_info board_info; 4638c2ecf20Sopenharmony_ci}; 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_cistatic LIST_HEAD(board_list); 4668c2ecf20Sopenharmony_cistatic LIST_HEAD(spi_controller_list); 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_ci/* 4698c2ecf20Sopenharmony_ci * Used to protect add/del operation for board_info list and 4708c2ecf20Sopenharmony_ci * spi_controller list, and their matching process 4718c2ecf20Sopenharmony_ci * also used to protect object of type struct idr 4728c2ecf20Sopenharmony_ci */ 4738c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(board_lock); 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci/** 4768c2ecf20Sopenharmony_ci * spi_alloc_device - Allocate a new SPI device 4778c2ecf20Sopenharmony_ci * @ctlr: Controller to which device is connected 4788c2ecf20Sopenharmony_ci * Context: can sleep 4798c2ecf20Sopenharmony_ci * 4808c2ecf20Sopenharmony_ci * Allows a driver to allocate and initialize a spi_device without 4818c2ecf20Sopenharmony_ci * registering it immediately. This allows a driver to directly 4828c2ecf20Sopenharmony_ci * fill the spi_device with device parameters before calling 4838c2ecf20Sopenharmony_ci * spi_add_device() on it. 4848c2ecf20Sopenharmony_ci * 4858c2ecf20Sopenharmony_ci * Caller is responsible to call spi_add_device() on the returned 4868c2ecf20Sopenharmony_ci * spi_device structure to add it to the SPI controller. If the caller 4878c2ecf20Sopenharmony_ci * needs to discard the spi_device without adding it, then it should 4888c2ecf20Sopenharmony_ci * call spi_dev_put() on it. 4898c2ecf20Sopenharmony_ci * 4908c2ecf20Sopenharmony_ci * Return: a pointer to the new device, or NULL. 4918c2ecf20Sopenharmony_ci */ 4928c2ecf20Sopenharmony_cistruct spi_device *spi_alloc_device(struct spi_controller *ctlr) 4938c2ecf20Sopenharmony_ci{ 4948c2ecf20Sopenharmony_ci struct spi_device *spi; 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci if (!spi_controller_get(ctlr)) 4978c2ecf20Sopenharmony_ci return NULL; 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_ci spi = kzalloc(sizeof(*spi), GFP_KERNEL); 5008c2ecf20Sopenharmony_ci if (!spi) { 5018c2ecf20Sopenharmony_ci spi_controller_put(ctlr); 5028c2ecf20Sopenharmony_ci return NULL; 5038c2ecf20Sopenharmony_ci } 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci spi->master = spi->controller = ctlr; 5068c2ecf20Sopenharmony_ci spi->dev.parent = &ctlr->dev; 5078c2ecf20Sopenharmony_ci spi->dev.bus = &spi_bus_type; 5088c2ecf20Sopenharmony_ci spi->dev.release = spidev_release; 5098c2ecf20Sopenharmony_ci spi->cs_gpio = -ENOENT; 5108c2ecf20Sopenharmony_ci spi->mode = ctlr->buswidth_override_bits; 5118c2ecf20Sopenharmony_ci 5128c2ecf20Sopenharmony_ci spin_lock_init(&spi->statistics.lock); 5138c2ecf20Sopenharmony_ci 5148c2ecf20Sopenharmony_ci device_initialize(&spi->dev); 5158c2ecf20Sopenharmony_ci return spi; 5168c2ecf20Sopenharmony_ci} 5178c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_alloc_device); 5188c2ecf20Sopenharmony_ci 5198c2ecf20Sopenharmony_cistatic void spi_dev_set_name(struct spi_device *spi) 5208c2ecf20Sopenharmony_ci{ 5218c2ecf20Sopenharmony_ci struct acpi_device *adev = ACPI_COMPANION(&spi->dev); 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_ci if (adev) { 5248c2ecf20Sopenharmony_ci dev_set_name(&spi->dev, "spi-%s", acpi_dev_name(adev)); 5258c2ecf20Sopenharmony_ci return; 5268c2ecf20Sopenharmony_ci } 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_ci dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->controller->dev), 5298c2ecf20Sopenharmony_ci spi->chip_select); 5308c2ecf20Sopenharmony_ci} 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_cistatic int spi_dev_check(struct device *dev, void *data) 5338c2ecf20Sopenharmony_ci{ 5348c2ecf20Sopenharmony_ci struct spi_device *spi = to_spi_device(dev); 5358c2ecf20Sopenharmony_ci struct spi_device *new_spi = data; 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci if (spi->controller == new_spi->controller && 5388c2ecf20Sopenharmony_ci spi->chip_select == new_spi->chip_select) 5398c2ecf20Sopenharmony_ci return -EBUSY; 5408c2ecf20Sopenharmony_ci return 0; 5418c2ecf20Sopenharmony_ci} 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_cistatic void spi_cleanup(struct spi_device *spi) 5448c2ecf20Sopenharmony_ci{ 5458c2ecf20Sopenharmony_ci if (spi->controller->cleanup) 5468c2ecf20Sopenharmony_ci spi->controller->cleanup(spi); 5478c2ecf20Sopenharmony_ci} 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_ci/** 5508c2ecf20Sopenharmony_ci * spi_add_device - Add spi_device allocated with spi_alloc_device 5518c2ecf20Sopenharmony_ci * @spi: spi_device to register 5528c2ecf20Sopenharmony_ci * 5538c2ecf20Sopenharmony_ci * Companion function to spi_alloc_device. Devices allocated with 5548c2ecf20Sopenharmony_ci * spi_alloc_device can be added onto the spi bus with this function. 5558c2ecf20Sopenharmony_ci * 5568c2ecf20Sopenharmony_ci * Return: 0 on success; negative errno on failure 5578c2ecf20Sopenharmony_ci */ 5588c2ecf20Sopenharmony_ciint spi_add_device(struct spi_device *spi) 5598c2ecf20Sopenharmony_ci{ 5608c2ecf20Sopenharmony_ci struct spi_controller *ctlr = spi->controller; 5618c2ecf20Sopenharmony_ci struct device *dev = ctlr->dev.parent; 5628c2ecf20Sopenharmony_ci int status; 5638c2ecf20Sopenharmony_ci 5648c2ecf20Sopenharmony_ci /* Chipselects are numbered 0..max; validate. */ 5658c2ecf20Sopenharmony_ci if (spi->chip_select >= ctlr->num_chipselect) { 5668c2ecf20Sopenharmony_ci dev_err(dev, "cs%d >= max %d\n", spi->chip_select, 5678c2ecf20Sopenharmony_ci ctlr->num_chipselect); 5688c2ecf20Sopenharmony_ci return -EINVAL; 5698c2ecf20Sopenharmony_ci } 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci /* Set the bus ID string */ 5728c2ecf20Sopenharmony_ci spi_dev_set_name(spi); 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_ci /* We need to make sure there's no other device with this 5758c2ecf20Sopenharmony_ci * chipselect **BEFORE** we call setup(), else we'll trash 5768c2ecf20Sopenharmony_ci * its configuration. Lock against concurrent add() calls. 5778c2ecf20Sopenharmony_ci */ 5788c2ecf20Sopenharmony_ci mutex_lock(&ctlr->add_lock); 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check); 5818c2ecf20Sopenharmony_ci if (status) { 5828c2ecf20Sopenharmony_ci dev_err(dev, "chipselect %d already in use\n", 5838c2ecf20Sopenharmony_ci spi->chip_select); 5848c2ecf20Sopenharmony_ci goto done; 5858c2ecf20Sopenharmony_ci } 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ci /* Controller may unregister concurrently */ 5888c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_SPI_DYNAMIC) && 5898c2ecf20Sopenharmony_ci !device_is_registered(&ctlr->dev)) { 5908c2ecf20Sopenharmony_ci status = -ENODEV; 5918c2ecf20Sopenharmony_ci goto done; 5928c2ecf20Sopenharmony_ci } 5938c2ecf20Sopenharmony_ci 5948c2ecf20Sopenharmony_ci /* Descriptors take precedence */ 5958c2ecf20Sopenharmony_ci if (ctlr->cs_gpiods) 5968c2ecf20Sopenharmony_ci spi->cs_gpiod = ctlr->cs_gpiods[spi->chip_select]; 5978c2ecf20Sopenharmony_ci else if (ctlr->cs_gpios) 5988c2ecf20Sopenharmony_ci spi->cs_gpio = ctlr->cs_gpios[spi->chip_select]; 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_ci /* Drivers may modify this initial i/o setup, but will 6018c2ecf20Sopenharmony_ci * normally rely on the device being setup. Devices 6028c2ecf20Sopenharmony_ci * using SPI_CS_HIGH can't coexist well otherwise... 6038c2ecf20Sopenharmony_ci */ 6048c2ecf20Sopenharmony_ci status = spi_setup(spi); 6058c2ecf20Sopenharmony_ci if (status < 0) { 6068c2ecf20Sopenharmony_ci dev_err(dev, "can't setup %s, status %d\n", 6078c2ecf20Sopenharmony_ci dev_name(&spi->dev), status); 6088c2ecf20Sopenharmony_ci goto done; 6098c2ecf20Sopenharmony_ci } 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_ci /* Device may be bound to an active driver when this returns */ 6128c2ecf20Sopenharmony_ci status = device_add(&spi->dev); 6138c2ecf20Sopenharmony_ci if (status < 0) { 6148c2ecf20Sopenharmony_ci dev_err(dev, "can't add %s, status %d\n", 6158c2ecf20Sopenharmony_ci dev_name(&spi->dev), status); 6168c2ecf20Sopenharmony_ci spi_cleanup(spi); 6178c2ecf20Sopenharmony_ci } else { 6188c2ecf20Sopenharmony_ci dev_dbg(dev, "registered child %s\n", dev_name(&spi->dev)); 6198c2ecf20Sopenharmony_ci } 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_cidone: 6228c2ecf20Sopenharmony_ci mutex_unlock(&ctlr->add_lock); 6238c2ecf20Sopenharmony_ci return status; 6248c2ecf20Sopenharmony_ci} 6258c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_add_device); 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci/** 6288c2ecf20Sopenharmony_ci * spi_new_device - instantiate one new SPI device 6298c2ecf20Sopenharmony_ci * @ctlr: Controller to which device is connected 6308c2ecf20Sopenharmony_ci * @chip: Describes the SPI device 6318c2ecf20Sopenharmony_ci * Context: can sleep 6328c2ecf20Sopenharmony_ci * 6338c2ecf20Sopenharmony_ci * On typical mainboards, this is purely internal; and it's not needed 6348c2ecf20Sopenharmony_ci * after board init creates the hard-wired devices. Some development 6358c2ecf20Sopenharmony_ci * platforms may not be able to use spi_register_board_info though, and 6368c2ecf20Sopenharmony_ci * this is exported so that for example a USB or parport based adapter 6378c2ecf20Sopenharmony_ci * driver could add devices (which it would learn about out-of-band). 6388c2ecf20Sopenharmony_ci * 6398c2ecf20Sopenharmony_ci * Return: the new device, or NULL. 6408c2ecf20Sopenharmony_ci */ 6418c2ecf20Sopenharmony_cistruct spi_device *spi_new_device(struct spi_controller *ctlr, 6428c2ecf20Sopenharmony_ci struct spi_board_info *chip) 6438c2ecf20Sopenharmony_ci{ 6448c2ecf20Sopenharmony_ci struct spi_device *proxy; 6458c2ecf20Sopenharmony_ci int status; 6468c2ecf20Sopenharmony_ci 6478c2ecf20Sopenharmony_ci /* NOTE: caller did any chip->bus_num checks necessary. 6488c2ecf20Sopenharmony_ci * 6498c2ecf20Sopenharmony_ci * Also, unless we change the return value convention to use 6508c2ecf20Sopenharmony_ci * error-or-pointer (not NULL-or-pointer), troubleshootability 6518c2ecf20Sopenharmony_ci * suggests syslogged diagnostics are best here (ugh). 6528c2ecf20Sopenharmony_ci */ 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_ci proxy = spi_alloc_device(ctlr); 6558c2ecf20Sopenharmony_ci if (!proxy) 6568c2ecf20Sopenharmony_ci return NULL; 6578c2ecf20Sopenharmony_ci 6588c2ecf20Sopenharmony_ci WARN_ON(strlen(chip->modalias) >= sizeof(proxy->modalias)); 6598c2ecf20Sopenharmony_ci 6608c2ecf20Sopenharmony_ci proxy->chip_select = chip->chip_select; 6618c2ecf20Sopenharmony_ci proxy->max_speed_hz = chip->max_speed_hz; 6628c2ecf20Sopenharmony_ci proxy->mode = chip->mode; 6638c2ecf20Sopenharmony_ci proxy->irq = chip->irq; 6648c2ecf20Sopenharmony_ci strlcpy(proxy->modalias, chip->modalias, sizeof(proxy->modalias)); 6658c2ecf20Sopenharmony_ci proxy->dev.platform_data = (void *) chip->platform_data; 6668c2ecf20Sopenharmony_ci proxy->controller_data = chip->controller_data; 6678c2ecf20Sopenharmony_ci proxy->controller_state = NULL; 6688c2ecf20Sopenharmony_ci 6698c2ecf20Sopenharmony_ci if (chip->properties) { 6708c2ecf20Sopenharmony_ci status = device_add_properties(&proxy->dev, chip->properties); 6718c2ecf20Sopenharmony_ci if (status) { 6728c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, 6738c2ecf20Sopenharmony_ci "failed to add properties to '%s': %d\n", 6748c2ecf20Sopenharmony_ci chip->modalias, status); 6758c2ecf20Sopenharmony_ci goto err_dev_put; 6768c2ecf20Sopenharmony_ci } 6778c2ecf20Sopenharmony_ci } 6788c2ecf20Sopenharmony_ci 6798c2ecf20Sopenharmony_ci status = spi_add_device(proxy); 6808c2ecf20Sopenharmony_ci if (status < 0) 6818c2ecf20Sopenharmony_ci goto err_remove_props; 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_ci return proxy; 6848c2ecf20Sopenharmony_ci 6858c2ecf20Sopenharmony_cierr_remove_props: 6868c2ecf20Sopenharmony_ci if (chip->properties) 6878c2ecf20Sopenharmony_ci device_remove_properties(&proxy->dev); 6888c2ecf20Sopenharmony_cierr_dev_put: 6898c2ecf20Sopenharmony_ci spi_dev_put(proxy); 6908c2ecf20Sopenharmony_ci return NULL; 6918c2ecf20Sopenharmony_ci} 6928c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_new_device); 6938c2ecf20Sopenharmony_ci 6948c2ecf20Sopenharmony_ci/** 6958c2ecf20Sopenharmony_ci * spi_unregister_device - unregister a single SPI device 6968c2ecf20Sopenharmony_ci * @spi: spi_device to unregister 6978c2ecf20Sopenharmony_ci * 6988c2ecf20Sopenharmony_ci * Start making the passed SPI device vanish. Normally this would be handled 6998c2ecf20Sopenharmony_ci * by spi_unregister_controller(). 7008c2ecf20Sopenharmony_ci */ 7018c2ecf20Sopenharmony_civoid spi_unregister_device(struct spi_device *spi) 7028c2ecf20Sopenharmony_ci{ 7038c2ecf20Sopenharmony_ci if (!spi) 7048c2ecf20Sopenharmony_ci return; 7058c2ecf20Sopenharmony_ci 7068c2ecf20Sopenharmony_ci if (spi->dev.of_node) { 7078c2ecf20Sopenharmony_ci of_node_clear_flag(spi->dev.of_node, OF_POPULATED); 7088c2ecf20Sopenharmony_ci of_node_put(spi->dev.of_node); 7098c2ecf20Sopenharmony_ci } 7108c2ecf20Sopenharmony_ci if (ACPI_COMPANION(&spi->dev)) 7118c2ecf20Sopenharmony_ci acpi_device_clear_enumerated(ACPI_COMPANION(&spi->dev)); 7128c2ecf20Sopenharmony_ci device_del(&spi->dev); 7138c2ecf20Sopenharmony_ci spi_cleanup(spi); 7148c2ecf20Sopenharmony_ci put_device(&spi->dev); 7158c2ecf20Sopenharmony_ci} 7168c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_unregister_device); 7178c2ecf20Sopenharmony_ci 7188c2ecf20Sopenharmony_cistatic void spi_match_controller_to_boardinfo(struct spi_controller *ctlr, 7198c2ecf20Sopenharmony_ci struct spi_board_info *bi) 7208c2ecf20Sopenharmony_ci{ 7218c2ecf20Sopenharmony_ci struct spi_device *dev; 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci if (ctlr->bus_num != bi->bus_num) 7248c2ecf20Sopenharmony_ci return; 7258c2ecf20Sopenharmony_ci 7268c2ecf20Sopenharmony_ci dev = spi_new_device(ctlr, bi); 7278c2ecf20Sopenharmony_ci if (!dev) 7288c2ecf20Sopenharmony_ci dev_err(ctlr->dev.parent, "can't create new device for %s\n", 7298c2ecf20Sopenharmony_ci bi->modalias); 7308c2ecf20Sopenharmony_ci} 7318c2ecf20Sopenharmony_ci 7328c2ecf20Sopenharmony_ci/** 7338c2ecf20Sopenharmony_ci * spi_register_board_info - register SPI devices for a given board 7348c2ecf20Sopenharmony_ci * @info: array of chip descriptors 7358c2ecf20Sopenharmony_ci * @n: how many descriptors are provided 7368c2ecf20Sopenharmony_ci * Context: can sleep 7378c2ecf20Sopenharmony_ci * 7388c2ecf20Sopenharmony_ci * Board-specific early init code calls this (probably during arch_initcall) 7398c2ecf20Sopenharmony_ci * with segments of the SPI device table. Any device nodes are created later, 7408c2ecf20Sopenharmony_ci * after the relevant parent SPI controller (bus_num) is defined. We keep 7418c2ecf20Sopenharmony_ci * this table of devices forever, so that reloading a controller driver will 7428c2ecf20Sopenharmony_ci * not make Linux forget about these hard-wired devices. 7438c2ecf20Sopenharmony_ci * 7448c2ecf20Sopenharmony_ci * Other code can also call this, e.g. a particular add-on board might provide 7458c2ecf20Sopenharmony_ci * SPI devices through its expansion connector, so code initializing that board 7468c2ecf20Sopenharmony_ci * would naturally declare its SPI devices. 7478c2ecf20Sopenharmony_ci * 7488c2ecf20Sopenharmony_ci * The board info passed can safely be __initdata ... but be careful of 7498c2ecf20Sopenharmony_ci * any embedded pointers (platform_data, etc), they're copied as-is. 7508c2ecf20Sopenharmony_ci * Device properties are deep-copied though. 7518c2ecf20Sopenharmony_ci * 7528c2ecf20Sopenharmony_ci * Return: zero on success, else a negative error code. 7538c2ecf20Sopenharmony_ci */ 7548c2ecf20Sopenharmony_ciint spi_register_board_info(struct spi_board_info const *info, unsigned n) 7558c2ecf20Sopenharmony_ci{ 7568c2ecf20Sopenharmony_ci struct boardinfo *bi; 7578c2ecf20Sopenharmony_ci int i; 7588c2ecf20Sopenharmony_ci 7598c2ecf20Sopenharmony_ci if (!n) 7608c2ecf20Sopenharmony_ci return 0; 7618c2ecf20Sopenharmony_ci 7628c2ecf20Sopenharmony_ci bi = kcalloc(n, sizeof(*bi), GFP_KERNEL); 7638c2ecf20Sopenharmony_ci if (!bi) 7648c2ecf20Sopenharmony_ci return -ENOMEM; 7658c2ecf20Sopenharmony_ci 7668c2ecf20Sopenharmony_ci for (i = 0; i < n; i++, bi++, info++) { 7678c2ecf20Sopenharmony_ci struct spi_controller *ctlr; 7688c2ecf20Sopenharmony_ci 7698c2ecf20Sopenharmony_ci memcpy(&bi->board_info, info, sizeof(*info)); 7708c2ecf20Sopenharmony_ci if (info->properties) { 7718c2ecf20Sopenharmony_ci bi->board_info.properties = 7728c2ecf20Sopenharmony_ci property_entries_dup(info->properties); 7738c2ecf20Sopenharmony_ci if (IS_ERR(bi->board_info.properties)) 7748c2ecf20Sopenharmony_ci return PTR_ERR(bi->board_info.properties); 7758c2ecf20Sopenharmony_ci } 7768c2ecf20Sopenharmony_ci 7778c2ecf20Sopenharmony_ci mutex_lock(&board_lock); 7788c2ecf20Sopenharmony_ci list_add_tail(&bi->list, &board_list); 7798c2ecf20Sopenharmony_ci list_for_each_entry(ctlr, &spi_controller_list, list) 7808c2ecf20Sopenharmony_ci spi_match_controller_to_boardinfo(ctlr, 7818c2ecf20Sopenharmony_ci &bi->board_info); 7828c2ecf20Sopenharmony_ci mutex_unlock(&board_lock); 7838c2ecf20Sopenharmony_ci } 7848c2ecf20Sopenharmony_ci 7858c2ecf20Sopenharmony_ci return 0; 7868c2ecf20Sopenharmony_ci} 7878c2ecf20Sopenharmony_ci 7888c2ecf20Sopenharmony_ci/*-------------------------------------------------------------------------*/ 7898c2ecf20Sopenharmony_ci 7908c2ecf20Sopenharmony_cistatic void spi_set_cs(struct spi_device *spi, bool enable, bool force) 7918c2ecf20Sopenharmony_ci{ 7928c2ecf20Sopenharmony_ci bool enable1 = enable; 7938c2ecf20Sopenharmony_ci 7948c2ecf20Sopenharmony_ci /* 7958c2ecf20Sopenharmony_ci * Avoid calling into the driver (or doing delays) if the chip select 7968c2ecf20Sopenharmony_ci * isn't actually changing from the last time this was called. 7978c2ecf20Sopenharmony_ci */ 7988c2ecf20Sopenharmony_ci if (!force && (spi->controller->last_cs_enable == enable) && 7998c2ecf20Sopenharmony_ci (spi->controller->last_cs_mode_high == (spi->mode & SPI_CS_HIGH))) 8008c2ecf20Sopenharmony_ci return; 8018c2ecf20Sopenharmony_ci 8028c2ecf20Sopenharmony_ci spi->controller->last_cs_enable = enable; 8038c2ecf20Sopenharmony_ci spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH; 8048c2ecf20Sopenharmony_ci 8058c2ecf20Sopenharmony_ci if (!spi->controller->set_cs_timing) { 8068c2ecf20Sopenharmony_ci if (enable1) 8078c2ecf20Sopenharmony_ci spi_delay_exec(&spi->controller->cs_setup, NULL); 8088c2ecf20Sopenharmony_ci else 8098c2ecf20Sopenharmony_ci spi_delay_exec(&spi->controller->cs_hold, NULL); 8108c2ecf20Sopenharmony_ci } 8118c2ecf20Sopenharmony_ci 8128c2ecf20Sopenharmony_ci if (spi->mode & SPI_CS_HIGH) 8138c2ecf20Sopenharmony_ci enable = !enable; 8148c2ecf20Sopenharmony_ci 8158c2ecf20Sopenharmony_ci if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio)) { 8168c2ecf20Sopenharmony_ci if (!(spi->mode & SPI_NO_CS)) { 8178c2ecf20Sopenharmony_ci if (spi->cs_gpiod) { 8188c2ecf20Sopenharmony_ci /* 8198c2ecf20Sopenharmony_ci * Historically ACPI has no means of the GPIO polarity and 8208c2ecf20Sopenharmony_ci * thus the SPISerialBus() resource defines it on the per-chip 8218c2ecf20Sopenharmony_ci * basis. In order to avoid a chain of negations, the GPIO 8228c2ecf20Sopenharmony_ci * polarity is considered being Active High. Even for the cases 8238c2ecf20Sopenharmony_ci * when _DSD() is involved (in the updated versions of ACPI) 8248c2ecf20Sopenharmony_ci * the GPIO CS polarity must be defined Active High to avoid 8258c2ecf20Sopenharmony_ci * ambiguity. That's why we use enable, that takes SPI_CS_HIGH 8268c2ecf20Sopenharmony_ci * into account. 8278c2ecf20Sopenharmony_ci */ 8288c2ecf20Sopenharmony_ci if (has_acpi_companion(&spi->dev)) 8298c2ecf20Sopenharmony_ci gpiod_set_value_cansleep(spi->cs_gpiod, !enable); 8308c2ecf20Sopenharmony_ci else 8318c2ecf20Sopenharmony_ci /* Polarity handled by GPIO library */ 8328c2ecf20Sopenharmony_ci gpiod_set_value_cansleep(spi->cs_gpiod, enable1); 8338c2ecf20Sopenharmony_ci } else { 8348c2ecf20Sopenharmony_ci /* 8358c2ecf20Sopenharmony_ci * invert the enable line, as active low is 8368c2ecf20Sopenharmony_ci * default for SPI. 8378c2ecf20Sopenharmony_ci */ 8388c2ecf20Sopenharmony_ci gpio_set_value_cansleep(spi->cs_gpio, !enable); 8398c2ecf20Sopenharmony_ci } 8408c2ecf20Sopenharmony_ci } 8418c2ecf20Sopenharmony_ci /* Some SPI masters need both GPIO CS & slave_select */ 8428c2ecf20Sopenharmony_ci if ((spi->controller->flags & SPI_MASTER_GPIO_SS) && 8438c2ecf20Sopenharmony_ci spi->controller->set_cs) 8448c2ecf20Sopenharmony_ci spi->controller->set_cs(spi, !enable); 8458c2ecf20Sopenharmony_ci } else if (spi->controller->set_cs) { 8468c2ecf20Sopenharmony_ci spi->controller->set_cs(spi, !enable); 8478c2ecf20Sopenharmony_ci } 8488c2ecf20Sopenharmony_ci 8498c2ecf20Sopenharmony_ci if (!spi->controller->set_cs_timing) { 8508c2ecf20Sopenharmony_ci if (!enable1) 8518c2ecf20Sopenharmony_ci spi_delay_exec(&spi->controller->cs_inactive, NULL); 8528c2ecf20Sopenharmony_ci } 8538c2ecf20Sopenharmony_ci} 8548c2ecf20Sopenharmony_ci 8558c2ecf20Sopenharmony_ci#ifdef CONFIG_HAS_DMA 8568c2ecf20Sopenharmony_ciint spi_map_buf(struct spi_controller *ctlr, struct device *dev, 8578c2ecf20Sopenharmony_ci struct sg_table *sgt, void *buf, size_t len, 8588c2ecf20Sopenharmony_ci enum dma_data_direction dir) 8598c2ecf20Sopenharmony_ci{ 8608c2ecf20Sopenharmony_ci const bool vmalloced_buf = is_vmalloc_addr(buf); 8618c2ecf20Sopenharmony_ci unsigned int max_seg_size = dma_get_max_seg_size(dev); 8628c2ecf20Sopenharmony_ci#ifdef CONFIG_HIGHMEM 8638c2ecf20Sopenharmony_ci const bool kmap_buf = ((unsigned long)buf >= PKMAP_BASE && 8648c2ecf20Sopenharmony_ci (unsigned long)buf < (PKMAP_BASE + 8658c2ecf20Sopenharmony_ci (LAST_PKMAP * PAGE_SIZE))); 8668c2ecf20Sopenharmony_ci#else 8678c2ecf20Sopenharmony_ci const bool kmap_buf = false; 8688c2ecf20Sopenharmony_ci#endif 8698c2ecf20Sopenharmony_ci int desc_len; 8708c2ecf20Sopenharmony_ci int sgs; 8718c2ecf20Sopenharmony_ci struct page *vm_page; 8728c2ecf20Sopenharmony_ci struct scatterlist *sg; 8738c2ecf20Sopenharmony_ci void *sg_buf; 8748c2ecf20Sopenharmony_ci size_t min; 8758c2ecf20Sopenharmony_ci int i, ret; 8768c2ecf20Sopenharmony_ci 8778c2ecf20Sopenharmony_ci if (vmalloced_buf || kmap_buf) { 8788c2ecf20Sopenharmony_ci desc_len = min_t(unsigned long, max_seg_size, PAGE_SIZE); 8798c2ecf20Sopenharmony_ci sgs = DIV_ROUND_UP(len + offset_in_page(buf), desc_len); 8808c2ecf20Sopenharmony_ci } else if (virt_addr_valid(buf)) { 8818c2ecf20Sopenharmony_ci desc_len = min_t(size_t, max_seg_size, ctlr->max_dma_len); 8828c2ecf20Sopenharmony_ci sgs = DIV_ROUND_UP(len, desc_len); 8838c2ecf20Sopenharmony_ci } else { 8848c2ecf20Sopenharmony_ci return -EINVAL; 8858c2ecf20Sopenharmony_ci } 8868c2ecf20Sopenharmony_ci 8878c2ecf20Sopenharmony_ci ret = sg_alloc_table(sgt, sgs, GFP_KERNEL); 8888c2ecf20Sopenharmony_ci if (ret != 0) 8898c2ecf20Sopenharmony_ci return ret; 8908c2ecf20Sopenharmony_ci 8918c2ecf20Sopenharmony_ci sg = &sgt->sgl[0]; 8928c2ecf20Sopenharmony_ci for (i = 0; i < sgs; i++) { 8938c2ecf20Sopenharmony_ci 8948c2ecf20Sopenharmony_ci if (vmalloced_buf || kmap_buf) { 8958c2ecf20Sopenharmony_ci /* 8968c2ecf20Sopenharmony_ci * Next scatterlist entry size is the minimum between 8978c2ecf20Sopenharmony_ci * the desc_len and the remaining buffer length that 8988c2ecf20Sopenharmony_ci * fits in a page. 8998c2ecf20Sopenharmony_ci */ 9008c2ecf20Sopenharmony_ci min = min_t(size_t, desc_len, 9018c2ecf20Sopenharmony_ci min_t(size_t, len, 9028c2ecf20Sopenharmony_ci PAGE_SIZE - offset_in_page(buf))); 9038c2ecf20Sopenharmony_ci if (vmalloced_buf) 9048c2ecf20Sopenharmony_ci vm_page = vmalloc_to_page(buf); 9058c2ecf20Sopenharmony_ci else 9068c2ecf20Sopenharmony_ci vm_page = kmap_to_page(buf); 9078c2ecf20Sopenharmony_ci if (!vm_page) { 9088c2ecf20Sopenharmony_ci sg_free_table(sgt); 9098c2ecf20Sopenharmony_ci return -ENOMEM; 9108c2ecf20Sopenharmony_ci } 9118c2ecf20Sopenharmony_ci sg_set_page(sg, vm_page, 9128c2ecf20Sopenharmony_ci min, offset_in_page(buf)); 9138c2ecf20Sopenharmony_ci } else { 9148c2ecf20Sopenharmony_ci min = min_t(size_t, len, desc_len); 9158c2ecf20Sopenharmony_ci sg_buf = buf; 9168c2ecf20Sopenharmony_ci sg_set_buf(sg, sg_buf, min); 9178c2ecf20Sopenharmony_ci } 9188c2ecf20Sopenharmony_ci 9198c2ecf20Sopenharmony_ci buf += min; 9208c2ecf20Sopenharmony_ci len -= min; 9218c2ecf20Sopenharmony_ci sg = sg_next(sg); 9228c2ecf20Sopenharmony_ci } 9238c2ecf20Sopenharmony_ci 9248c2ecf20Sopenharmony_ci ret = dma_map_sg(dev, sgt->sgl, sgt->nents, dir); 9258c2ecf20Sopenharmony_ci if (!ret) 9268c2ecf20Sopenharmony_ci ret = -ENOMEM; 9278c2ecf20Sopenharmony_ci if (ret < 0) { 9288c2ecf20Sopenharmony_ci sg_free_table(sgt); 9298c2ecf20Sopenharmony_ci return ret; 9308c2ecf20Sopenharmony_ci } 9318c2ecf20Sopenharmony_ci 9328c2ecf20Sopenharmony_ci sgt->nents = ret; 9338c2ecf20Sopenharmony_ci 9348c2ecf20Sopenharmony_ci return 0; 9358c2ecf20Sopenharmony_ci} 9368c2ecf20Sopenharmony_ci 9378c2ecf20Sopenharmony_civoid spi_unmap_buf(struct spi_controller *ctlr, struct device *dev, 9388c2ecf20Sopenharmony_ci struct sg_table *sgt, enum dma_data_direction dir) 9398c2ecf20Sopenharmony_ci{ 9408c2ecf20Sopenharmony_ci if (sgt->orig_nents) { 9418c2ecf20Sopenharmony_ci dma_unmap_sg(dev, sgt->sgl, sgt->orig_nents, dir); 9428c2ecf20Sopenharmony_ci sg_free_table(sgt); 9438c2ecf20Sopenharmony_ci sgt->orig_nents = 0; 9448c2ecf20Sopenharmony_ci sgt->nents = 0; 9458c2ecf20Sopenharmony_ci } 9468c2ecf20Sopenharmony_ci} 9478c2ecf20Sopenharmony_ci 9488c2ecf20Sopenharmony_cistatic int __spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg) 9498c2ecf20Sopenharmony_ci{ 9508c2ecf20Sopenharmony_ci struct device *tx_dev, *rx_dev; 9518c2ecf20Sopenharmony_ci struct spi_transfer *xfer; 9528c2ecf20Sopenharmony_ci int ret; 9538c2ecf20Sopenharmony_ci 9548c2ecf20Sopenharmony_ci if (!ctlr->can_dma) 9558c2ecf20Sopenharmony_ci return 0; 9568c2ecf20Sopenharmony_ci 9578c2ecf20Sopenharmony_ci if (ctlr->dma_tx) 9588c2ecf20Sopenharmony_ci tx_dev = ctlr->dma_tx->device->dev; 9598c2ecf20Sopenharmony_ci else 9608c2ecf20Sopenharmony_ci tx_dev = ctlr->dev.parent; 9618c2ecf20Sopenharmony_ci 9628c2ecf20Sopenharmony_ci if (ctlr->dma_rx) 9638c2ecf20Sopenharmony_ci rx_dev = ctlr->dma_rx->device->dev; 9648c2ecf20Sopenharmony_ci else 9658c2ecf20Sopenharmony_ci rx_dev = ctlr->dev.parent; 9668c2ecf20Sopenharmony_ci 9678c2ecf20Sopenharmony_ci list_for_each_entry(xfer, &msg->transfers, transfer_list) { 9688c2ecf20Sopenharmony_ci if (!ctlr->can_dma(ctlr, msg->spi, xfer)) 9698c2ecf20Sopenharmony_ci continue; 9708c2ecf20Sopenharmony_ci 9718c2ecf20Sopenharmony_ci if (xfer->tx_buf != NULL) { 9728c2ecf20Sopenharmony_ci ret = spi_map_buf(ctlr, tx_dev, &xfer->tx_sg, 9738c2ecf20Sopenharmony_ci (void *)xfer->tx_buf, xfer->len, 9748c2ecf20Sopenharmony_ci DMA_TO_DEVICE); 9758c2ecf20Sopenharmony_ci if (ret != 0) 9768c2ecf20Sopenharmony_ci return ret; 9778c2ecf20Sopenharmony_ci } 9788c2ecf20Sopenharmony_ci 9798c2ecf20Sopenharmony_ci if (xfer->rx_buf != NULL) { 9808c2ecf20Sopenharmony_ci ret = spi_map_buf(ctlr, rx_dev, &xfer->rx_sg, 9818c2ecf20Sopenharmony_ci xfer->rx_buf, xfer->len, 9828c2ecf20Sopenharmony_ci DMA_FROM_DEVICE); 9838c2ecf20Sopenharmony_ci if (ret != 0) { 9848c2ecf20Sopenharmony_ci spi_unmap_buf(ctlr, tx_dev, &xfer->tx_sg, 9858c2ecf20Sopenharmony_ci DMA_TO_DEVICE); 9868c2ecf20Sopenharmony_ci return ret; 9878c2ecf20Sopenharmony_ci } 9888c2ecf20Sopenharmony_ci } 9898c2ecf20Sopenharmony_ci } 9908c2ecf20Sopenharmony_ci 9918c2ecf20Sopenharmony_ci ctlr->cur_msg_mapped = true; 9928c2ecf20Sopenharmony_ci 9938c2ecf20Sopenharmony_ci return 0; 9948c2ecf20Sopenharmony_ci} 9958c2ecf20Sopenharmony_ci 9968c2ecf20Sopenharmony_cistatic int __spi_unmap_msg(struct spi_controller *ctlr, struct spi_message *msg) 9978c2ecf20Sopenharmony_ci{ 9988c2ecf20Sopenharmony_ci struct spi_transfer *xfer; 9998c2ecf20Sopenharmony_ci struct device *tx_dev, *rx_dev; 10008c2ecf20Sopenharmony_ci 10018c2ecf20Sopenharmony_ci if (!ctlr->cur_msg_mapped || !ctlr->can_dma) 10028c2ecf20Sopenharmony_ci return 0; 10038c2ecf20Sopenharmony_ci 10048c2ecf20Sopenharmony_ci if (ctlr->dma_tx) 10058c2ecf20Sopenharmony_ci tx_dev = ctlr->dma_tx->device->dev; 10068c2ecf20Sopenharmony_ci else 10078c2ecf20Sopenharmony_ci tx_dev = ctlr->dev.parent; 10088c2ecf20Sopenharmony_ci 10098c2ecf20Sopenharmony_ci if (ctlr->dma_rx) 10108c2ecf20Sopenharmony_ci rx_dev = ctlr->dma_rx->device->dev; 10118c2ecf20Sopenharmony_ci else 10128c2ecf20Sopenharmony_ci rx_dev = ctlr->dev.parent; 10138c2ecf20Sopenharmony_ci 10148c2ecf20Sopenharmony_ci list_for_each_entry(xfer, &msg->transfers, transfer_list) { 10158c2ecf20Sopenharmony_ci if (!ctlr->can_dma(ctlr, msg->spi, xfer)) 10168c2ecf20Sopenharmony_ci continue; 10178c2ecf20Sopenharmony_ci 10188c2ecf20Sopenharmony_ci spi_unmap_buf(ctlr, rx_dev, &xfer->rx_sg, DMA_FROM_DEVICE); 10198c2ecf20Sopenharmony_ci spi_unmap_buf(ctlr, tx_dev, &xfer->tx_sg, DMA_TO_DEVICE); 10208c2ecf20Sopenharmony_ci } 10218c2ecf20Sopenharmony_ci 10228c2ecf20Sopenharmony_ci ctlr->cur_msg_mapped = false; 10238c2ecf20Sopenharmony_ci 10248c2ecf20Sopenharmony_ci return 0; 10258c2ecf20Sopenharmony_ci} 10268c2ecf20Sopenharmony_ci#else /* !CONFIG_HAS_DMA */ 10278c2ecf20Sopenharmony_cistatic inline int __spi_map_msg(struct spi_controller *ctlr, 10288c2ecf20Sopenharmony_ci struct spi_message *msg) 10298c2ecf20Sopenharmony_ci{ 10308c2ecf20Sopenharmony_ci return 0; 10318c2ecf20Sopenharmony_ci} 10328c2ecf20Sopenharmony_ci 10338c2ecf20Sopenharmony_cistatic inline int __spi_unmap_msg(struct spi_controller *ctlr, 10348c2ecf20Sopenharmony_ci struct spi_message *msg) 10358c2ecf20Sopenharmony_ci{ 10368c2ecf20Sopenharmony_ci return 0; 10378c2ecf20Sopenharmony_ci} 10388c2ecf20Sopenharmony_ci#endif /* !CONFIG_HAS_DMA */ 10398c2ecf20Sopenharmony_ci 10408c2ecf20Sopenharmony_cistatic inline int spi_unmap_msg(struct spi_controller *ctlr, 10418c2ecf20Sopenharmony_ci struct spi_message *msg) 10428c2ecf20Sopenharmony_ci{ 10438c2ecf20Sopenharmony_ci struct spi_transfer *xfer; 10448c2ecf20Sopenharmony_ci 10458c2ecf20Sopenharmony_ci list_for_each_entry(xfer, &msg->transfers, transfer_list) { 10468c2ecf20Sopenharmony_ci /* 10478c2ecf20Sopenharmony_ci * Restore the original value of tx_buf or rx_buf if they are 10488c2ecf20Sopenharmony_ci * NULL. 10498c2ecf20Sopenharmony_ci */ 10508c2ecf20Sopenharmony_ci if (xfer->tx_buf == ctlr->dummy_tx) 10518c2ecf20Sopenharmony_ci xfer->tx_buf = NULL; 10528c2ecf20Sopenharmony_ci if (xfer->rx_buf == ctlr->dummy_rx) 10538c2ecf20Sopenharmony_ci xfer->rx_buf = NULL; 10548c2ecf20Sopenharmony_ci } 10558c2ecf20Sopenharmony_ci 10568c2ecf20Sopenharmony_ci return __spi_unmap_msg(ctlr, msg); 10578c2ecf20Sopenharmony_ci} 10588c2ecf20Sopenharmony_ci 10598c2ecf20Sopenharmony_cistatic int spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg) 10608c2ecf20Sopenharmony_ci{ 10618c2ecf20Sopenharmony_ci struct spi_transfer *xfer; 10628c2ecf20Sopenharmony_ci void *tmp; 10638c2ecf20Sopenharmony_ci unsigned int max_tx, max_rx; 10648c2ecf20Sopenharmony_ci 10658c2ecf20Sopenharmony_ci if ((ctlr->flags & (SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX)) 10668c2ecf20Sopenharmony_ci && !(msg->spi->mode & SPI_3WIRE)) { 10678c2ecf20Sopenharmony_ci max_tx = 0; 10688c2ecf20Sopenharmony_ci max_rx = 0; 10698c2ecf20Sopenharmony_ci 10708c2ecf20Sopenharmony_ci list_for_each_entry(xfer, &msg->transfers, transfer_list) { 10718c2ecf20Sopenharmony_ci if ((ctlr->flags & SPI_CONTROLLER_MUST_TX) && 10728c2ecf20Sopenharmony_ci !xfer->tx_buf) 10738c2ecf20Sopenharmony_ci max_tx = max(xfer->len, max_tx); 10748c2ecf20Sopenharmony_ci if ((ctlr->flags & SPI_CONTROLLER_MUST_RX) && 10758c2ecf20Sopenharmony_ci !xfer->rx_buf) 10768c2ecf20Sopenharmony_ci max_rx = max(xfer->len, max_rx); 10778c2ecf20Sopenharmony_ci } 10788c2ecf20Sopenharmony_ci 10798c2ecf20Sopenharmony_ci if (max_tx) { 10808c2ecf20Sopenharmony_ci tmp = krealloc(ctlr->dummy_tx, max_tx, 10818c2ecf20Sopenharmony_ci GFP_KERNEL | GFP_DMA); 10828c2ecf20Sopenharmony_ci if (!tmp) 10838c2ecf20Sopenharmony_ci return -ENOMEM; 10848c2ecf20Sopenharmony_ci ctlr->dummy_tx = tmp; 10858c2ecf20Sopenharmony_ci memset(tmp, 0, max_tx); 10868c2ecf20Sopenharmony_ci } 10878c2ecf20Sopenharmony_ci 10888c2ecf20Sopenharmony_ci if (max_rx) { 10898c2ecf20Sopenharmony_ci tmp = krealloc(ctlr->dummy_rx, max_rx, 10908c2ecf20Sopenharmony_ci GFP_KERNEL | GFP_DMA); 10918c2ecf20Sopenharmony_ci if (!tmp) 10928c2ecf20Sopenharmony_ci return -ENOMEM; 10938c2ecf20Sopenharmony_ci ctlr->dummy_rx = tmp; 10948c2ecf20Sopenharmony_ci } 10958c2ecf20Sopenharmony_ci 10968c2ecf20Sopenharmony_ci if (max_tx || max_rx) { 10978c2ecf20Sopenharmony_ci list_for_each_entry(xfer, &msg->transfers, 10988c2ecf20Sopenharmony_ci transfer_list) { 10998c2ecf20Sopenharmony_ci if (!xfer->len) 11008c2ecf20Sopenharmony_ci continue; 11018c2ecf20Sopenharmony_ci if (!xfer->tx_buf) 11028c2ecf20Sopenharmony_ci xfer->tx_buf = ctlr->dummy_tx; 11038c2ecf20Sopenharmony_ci if (!xfer->rx_buf) 11048c2ecf20Sopenharmony_ci xfer->rx_buf = ctlr->dummy_rx; 11058c2ecf20Sopenharmony_ci } 11068c2ecf20Sopenharmony_ci } 11078c2ecf20Sopenharmony_ci } 11088c2ecf20Sopenharmony_ci 11098c2ecf20Sopenharmony_ci return __spi_map_msg(ctlr, msg); 11108c2ecf20Sopenharmony_ci} 11118c2ecf20Sopenharmony_ci 11128c2ecf20Sopenharmony_cistatic int spi_transfer_wait(struct spi_controller *ctlr, 11138c2ecf20Sopenharmony_ci struct spi_message *msg, 11148c2ecf20Sopenharmony_ci struct spi_transfer *xfer) 11158c2ecf20Sopenharmony_ci{ 11168c2ecf20Sopenharmony_ci struct spi_statistics *statm = &ctlr->statistics; 11178c2ecf20Sopenharmony_ci struct spi_statistics *stats = &msg->spi->statistics; 11188c2ecf20Sopenharmony_ci u32 speed_hz = xfer->speed_hz; 11198c2ecf20Sopenharmony_ci unsigned long long ms; 11208c2ecf20Sopenharmony_ci 11218c2ecf20Sopenharmony_ci if (spi_controller_is_slave(ctlr)) { 11228c2ecf20Sopenharmony_ci if (wait_for_completion_interruptible(&ctlr->xfer_completion)) { 11238c2ecf20Sopenharmony_ci dev_dbg(&msg->spi->dev, "SPI transfer interrupted\n"); 11248c2ecf20Sopenharmony_ci return -EINTR; 11258c2ecf20Sopenharmony_ci } 11268c2ecf20Sopenharmony_ci } else { 11278c2ecf20Sopenharmony_ci if (!speed_hz) 11288c2ecf20Sopenharmony_ci speed_hz = 100000; 11298c2ecf20Sopenharmony_ci 11308c2ecf20Sopenharmony_ci ms = 8LL * 1000LL * xfer->len; 11318c2ecf20Sopenharmony_ci do_div(ms, speed_hz); 11328c2ecf20Sopenharmony_ci ms += ms + 200; /* some tolerance */ 11338c2ecf20Sopenharmony_ci 11348c2ecf20Sopenharmony_ci if (ms > UINT_MAX) 11358c2ecf20Sopenharmony_ci ms = UINT_MAX; 11368c2ecf20Sopenharmony_ci 11378c2ecf20Sopenharmony_ci ms = wait_for_completion_timeout(&ctlr->xfer_completion, 11388c2ecf20Sopenharmony_ci msecs_to_jiffies(ms)); 11398c2ecf20Sopenharmony_ci 11408c2ecf20Sopenharmony_ci if (ms == 0) { 11418c2ecf20Sopenharmony_ci SPI_STATISTICS_INCREMENT_FIELD(statm, timedout); 11428c2ecf20Sopenharmony_ci SPI_STATISTICS_INCREMENT_FIELD(stats, timedout); 11438c2ecf20Sopenharmony_ci dev_err(&msg->spi->dev, 11448c2ecf20Sopenharmony_ci "SPI transfer timed out\n"); 11458c2ecf20Sopenharmony_ci return -ETIMEDOUT; 11468c2ecf20Sopenharmony_ci } 11478c2ecf20Sopenharmony_ci } 11488c2ecf20Sopenharmony_ci 11498c2ecf20Sopenharmony_ci return 0; 11508c2ecf20Sopenharmony_ci} 11518c2ecf20Sopenharmony_ci 11528c2ecf20Sopenharmony_cistatic void _spi_transfer_delay_ns(u32 ns) 11538c2ecf20Sopenharmony_ci{ 11548c2ecf20Sopenharmony_ci if (!ns) 11558c2ecf20Sopenharmony_ci return; 11568c2ecf20Sopenharmony_ci if (ns <= 1000) { 11578c2ecf20Sopenharmony_ci ndelay(ns); 11588c2ecf20Sopenharmony_ci } else { 11598c2ecf20Sopenharmony_ci u32 us = DIV_ROUND_UP(ns, 1000); 11608c2ecf20Sopenharmony_ci 11618c2ecf20Sopenharmony_ci if (us <= 10) 11628c2ecf20Sopenharmony_ci udelay(us); 11638c2ecf20Sopenharmony_ci else 11648c2ecf20Sopenharmony_ci usleep_range(us, us + DIV_ROUND_UP(us, 10)); 11658c2ecf20Sopenharmony_ci } 11668c2ecf20Sopenharmony_ci} 11678c2ecf20Sopenharmony_ci 11688c2ecf20Sopenharmony_ciint spi_delay_to_ns(struct spi_delay *_delay, struct spi_transfer *xfer) 11698c2ecf20Sopenharmony_ci{ 11708c2ecf20Sopenharmony_ci u32 delay = _delay->value; 11718c2ecf20Sopenharmony_ci u32 unit = _delay->unit; 11728c2ecf20Sopenharmony_ci u32 hz; 11738c2ecf20Sopenharmony_ci 11748c2ecf20Sopenharmony_ci if (!delay) 11758c2ecf20Sopenharmony_ci return 0; 11768c2ecf20Sopenharmony_ci 11778c2ecf20Sopenharmony_ci switch (unit) { 11788c2ecf20Sopenharmony_ci case SPI_DELAY_UNIT_USECS: 11798c2ecf20Sopenharmony_ci delay *= 1000; 11808c2ecf20Sopenharmony_ci break; 11818c2ecf20Sopenharmony_ci case SPI_DELAY_UNIT_NSECS: /* nothing to do here */ 11828c2ecf20Sopenharmony_ci break; 11838c2ecf20Sopenharmony_ci case SPI_DELAY_UNIT_SCK: 11848c2ecf20Sopenharmony_ci /* clock cycles need to be obtained from spi_transfer */ 11858c2ecf20Sopenharmony_ci if (!xfer) 11868c2ecf20Sopenharmony_ci return -EINVAL; 11878c2ecf20Sopenharmony_ci /* if there is no effective speed know, then approximate 11888c2ecf20Sopenharmony_ci * by underestimating with half the requested hz 11898c2ecf20Sopenharmony_ci */ 11908c2ecf20Sopenharmony_ci hz = xfer->effective_speed_hz ?: xfer->speed_hz / 2; 11918c2ecf20Sopenharmony_ci if (!hz) 11928c2ecf20Sopenharmony_ci return -EINVAL; 11938c2ecf20Sopenharmony_ci delay *= DIV_ROUND_UP(1000000000, hz); 11948c2ecf20Sopenharmony_ci break; 11958c2ecf20Sopenharmony_ci default: 11968c2ecf20Sopenharmony_ci return -EINVAL; 11978c2ecf20Sopenharmony_ci } 11988c2ecf20Sopenharmony_ci 11998c2ecf20Sopenharmony_ci return delay; 12008c2ecf20Sopenharmony_ci} 12018c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_delay_to_ns); 12028c2ecf20Sopenharmony_ci 12038c2ecf20Sopenharmony_ciint spi_delay_exec(struct spi_delay *_delay, struct spi_transfer *xfer) 12048c2ecf20Sopenharmony_ci{ 12058c2ecf20Sopenharmony_ci int delay; 12068c2ecf20Sopenharmony_ci 12078c2ecf20Sopenharmony_ci might_sleep(); 12088c2ecf20Sopenharmony_ci 12098c2ecf20Sopenharmony_ci if (!_delay) 12108c2ecf20Sopenharmony_ci return -EINVAL; 12118c2ecf20Sopenharmony_ci 12128c2ecf20Sopenharmony_ci delay = spi_delay_to_ns(_delay, xfer); 12138c2ecf20Sopenharmony_ci if (delay < 0) 12148c2ecf20Sopenharmony_ci return delay; 12158c2ecf20Sopenharmony_ci 12168c2ecf20Sopenharmony_ci _spi_transfer_delay_ns(delay); 12178c2ecf20Sopenharmony_ci 12188c2ecf20Sopenharmony_ci return 0; 12198c2ecf20Sopenharmony_ci} 12208c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_delay_exec); 12218c2ecf20Sopenharmony_ci 12228c2ecf20Sopenharmony_cistatic void _spi_transfer_cs_change_delay(struct spi_message *msg, 12238c2ecf20Sopenharmony_ci struct spi_transfer *xfer) 12248c2ecf20Sopenharmony_ci{ 12258c2ecf20Sopenharmony_ci u32 delay = xfer->cs_change_delay.value; 12268c2ecf20Sopenharmony_ci u32 unit = xfer->cs_change_delay.unit; 12278c2ecf20Sopenharmony_ci int ret; 12288c2ecf20Sopenharmony_ci 12298c2ecf20Sopenharmony_ci /* return early on "fast" mode - for everything but USECS */ 12308c2ecf20Sopenharmony_ci if (!delay) { 12318c2ecf20Sopenharmony_ci if (unit == SPI_DELAY_UNIT_USECS) 12328c2ecf20Sopenharmony_ci _spi_transfer_delay_ns(10000); 12338c2ecf20Sopenharmony_ci return; 12348c2ecf20Sopenharmony_ci } 12358c2ecf20Sopenharmony_ci 12368c2ecf20Sopenharmony_ci ret = spi_delay_exec(&xfer->cs_change_delay, xfer); 12378c2ecf20Sopenharmony_ci if (ret) { 12388c2ecf20Sopenharmony_ci dev_err_once(&msg->spi->dev, 12398c2ecf20Sopenharmony_ci "Use of unsupported delay unit %i, using default of 10us\n", 12408c2ecf20Sopenharmony_ci unit); 12418c2ecf20Sopenharmony_ci _spi_transfer_delay_ns(10000); 12428c2ecf20Sopenharmony_ci } 12438c2ecf20Sopenharmony_ci} 12448c2ecf20Sopenharmony_ci 12458c2ecf20Sopenharmony_ci/* 12468c2ecf20Sopenharmony_ci * spi_transfer_one_message - Default implementation of transfer_one_message() 12478c2ecf20Sopenharmony_ci * 12488c2ecf20Sopenharmony_ci * This is a standard implementation of transfer_one_message() for 12498c2ecf20Sopenharmony_ci * drivers which implement a transfer_one() operation. It provides 12508c2ecf20Sopenharmony_ci * standard handling of delays and chip select management. 12518c2ecf20Sopenharmony_ci */ 12528c2ecf20Sopenharmony_cistatic int spi_transfer_one_message(struct spi_controller *ctlr, 12538c2ecf20Sopenharmony_ci struct spi_message *msg) 12548c2ecf20Sopenharmony_ci{ 12558c2ecf20Sopenharmony_ci struct spi_transfer *xfer; 12568c2ecf20Sopenharmony_ci bool keep_cs = false; 12578c2ecf20Sopenharmony_ci int ret = 0; 12588c2ecf20Sopenharmony_ci struct spi_statistics *statm = &ctlr->statistics; 12598c2ecf20Sopenharmony_ci struct spi_statistics *stats = &msg->spi->statistics; 12608c2ecf20Sopenharmony_ci 12618c2ecf20Sopenharmony_ci spi_set_cs(msg->spi, true, false); 12628c2ecf20Sopenharmony_ci 12638c2ecf20Sopenharmony_ci SPI_STATISTICS_INCREMENT_FIELD(statm, messages); 12648c2ecf20Sopenharmony_ci SPI_STATISTICS_INCREMENT_FIELD(stats, messages); 12658c2ecf20Sopenharmony_ci 12668c2ecf20Sopenharmony_ci list_for_each_entry(xfer, &msg->transfers, transfer_list) { 12678c2ecf20Sopenharmony_ci trace_spi_transfer_start(msg, xfer); 12688c2ecf20Sopenharmony_ci 12698c2ecf20Sopenharmony_ci spi_statistics_add_transfer_stats(statm, xfer, ctlr); 12708c2ecf20Sopenharmony_ci spi_statistics_add_transfer_stats(stats, xfer, ctlr); 12718c2ecf20Sopenharmony_ci 12728c2ecf20Sopenharmony_ci if (!ctlr->ptp_sts_supported) { 12738c2ecf20Sopenharmony_ci xfer->ptp_sts_word_pre = 0; 12748c2ecf20Sopenharmony_ci ptp_read_system_prets(xfer->ptp_sts); 12758c2ecf20Sopenharmony_ci } 12768c2ecf20Sopenharmony_ci 12778c2ecf20Sopenharmony_ci if ((xfer->tx_buf || xfer->rx_buf) && xfer->len) { 12788c2ecf20Sopenharmony_ci reinit_completion(&ctlr->xfer_completion); 12798c2ecf20Sopenharmony_ci 12808c2ecf20Sopenharmony_cifallback_pio: 12818c2ecf20Sopenharmony_ci ret = ctlr->transfer_one(ctlr, msg->spi, xfer); 12828c2ecf20Sopenharmony_ci if (ret < 0) { 12838c2ecf20Sopenharmony_ci if (ctlr->cur_msg_mapped && 12848c2ecf20Sopenharmony_ci (xfer->error & SPI_TRANS_FAIL_NO_START)) { 12858c2ecf20Sopenharmony_ci __spi_unmap_msg(ctlr, msg); 12868c2ecf20Sopenharmony_ci ctlr->fallback = true; 12878c2ecf20Sopenharmony_ci xfer->error &= ~SPI_TRANS_FAIL_NO_START; 12888c2ecf20Sopenharmony_ci goto fallback_pio; 12898c2ecf20Sopenharmony_ci } 12908c2ecf20Sopenharmony_ci 12918c2ecf20Sopenharmony_ci SPI_STATISTICS_INCREMENT_FIELD(statm, 12928c2ecf20Sopenharmony_ci errors); 12938c2ecf20Sopenharmony_ci SPI_STATISTICS_INCREMENT_FIELD(stats, 12948c2ecf20Sopenharmony_ci errors); 12958c2ecf20Sopenharmony_ci dev_err(&msg->spi->dev, 12968c2ecf20Sopenharmony_ci "SPI transfer failed: %d\n", ret); 12978c2ecf20Sopenharmony_ci goto out; 12988c2ecf20Sopenharmony_ci } 12998c2ecf20Sopenharmony_ci 13008c2ecf20Sopenharmony_ci if (ret > 0) { 13018c2ecf20Sopenharmony_ci ret = spi_transfer_wait(ctlr, msg, xfer); 13028c2ecf20Sopenharmony_ci if (ret < 0) 13038c2ecf20Sopenharmony_ci msg->status = ret; 13048c2ecf20Sopenharmony_ci } 13058c2ecf20Sopenharmony_ci } else { 13068c2ecf20Sopenharmony_ci if (xfer->len) 13078c2ecf20Sopenharmony_ci dev_err(&msg->spi->dev, 13088c2ecf20Sopenharmony_ci "Bufferless transfer has length %u\n", 13098c2ecf20Sopenharmony_ci xfer->len); 13108c2ecf20Sopenharmony_ci } 13118c2ecf20Sopenharmony_ci 13128c2ecf20Sopenharmony_ci if (!ctlr->ptp_sts_supported) { 13138c2ecf20Sopenharmony_ci ptp_read_system_postts(xfer->ptp_sts); 13148c2ecf20Sopenharmony_ci xfer->ptp_sts_word_post = xfer->len; 13158c2ecf20Sopenharmony_ci } 13168c2ecf20Sopenharmony_ci 13178c2ecf20Sopenharmony_ci trace_spi_transfer_stop(msg, xfer); 13188c2ecf20Sopenharmony_ci 13198c2ecf20Sopenharmony_ci if (msg->status != -EINPROGRESS) 13208c2ecf20Sopenharmony_ci goto out; 13218c2ecf20Sopenharmony_ci 13228c2ecf20Sopenharmony_ci spi_transfer_delay_exec(xfer); 13238c2ecf20Sopenharmony_ci 13248c2ecf20Sopenharmony_ci if (xfer->cs_change) { 13258c2ecf20Sopenharmony_ci if (list_is_last(&xfer->transfer_list, 13268c2ecf20Sopenharmony_ci &msg->transfers)) { 13278c2ecf20Sopenharmony_ci keep_cs = true; 13288c2ecf20Sopenharmony_ci } else { 13298c2ecf20Sopenharmony_ci spi_set_cs(msg->spi, false, false); 13308c2ecf20Sopenharmony_ci _spi_transfer_cs_change_delay(msg, xfer); 13318c2ecf20Sopenharmony_ci spi_set_cs(msg->spi, true, false); 13328c2ecf20Sopenharmony_ci } 13338c2ecf20Sopenharmony_ci } 13348c2ecf20Sopenharmony_ci 13358c2ecf20Sopenharmony_ci msg->actual_length += xfer->len; 13368c2ecf20Sopenharmony_ci } 13378c2ecf20Sopenharmony_ci 13388c2ecf20Sopenharmony_ciout: 13398c2ecf20Sopenharmony_ci if (ret != 0 || !keep_cs) 13408c2ecf20Sopenharmony_ci spi_set_cs(msg->spi, false, false); 13418c2ecf20Sopenharmony_ci 13428c2ecf20Sopenharmony_ci if (msg->status == -EINPROGRESS) 13438c2ecf20Sopenharmony_ci msg->status = ret; 13448c2ecf20Sopenharmony_ci 13458c2ecf20Sopenharmony_ci if (msg->status && ctlr->handle_err) 13468c2ecf20Sopenharmony_ci ctlr->handle_err(ctlr, msg); 13478c2ecf20Sopenharmony_ci 13488c2ecf20Sopenharmony_ci spi_finalize_current_message(ctlr); 13498c2ecf20Sopenharmony_ci 13508c2ecf20Sopenharmony_ci return ret; 13518c2ecf20Sopenharmony_ci} 13528c2ecf20Sopenharmony_ci 13538c2ecf20Sopenharmony_ci/** 13548c2ecf20Sopenharmony_ci * spi_finalize_current_transfer - report completion of a transfer 13558c2ecf20Sopenharmony_ci * @ctlr: the controller reporting completion 13568c2ecf20Sopenharmony_ci * 13578c2ecf20Sopenharmony_ci * Called by SPI drivers using the core transfer_one_message() 13588c2ecf20Sopenharmony_ci * implementation to notify it that the current interrupt driven 13598c2ecf20Sopenharmony_ci * transfer has finished and the next one may be scheduled. 13608c2ecf20Sopenharmony_ci */ 13618c2ecf20Sopenharmony_civoid spi_finalize_current_transfer(struct spi_controller *ctlr) 13628c2ecf20Sopenharmony_ci{ 13638c2ecf20Sopenharmony_ci complete(&ctlr->xfer_completion); 13648c2ecf20Sopenharmony_ci} 13658c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_finalize_current_transfer); 13668c2ecf20Sopenharmony_ci 13678c2ecf20Sopenharmony_cistatic void spi_idle_runtime_pm(struct spi_controller *ctlr) 13688c2ecf20Sopenharmony_ci{ 13698c2ecf20Sopenharmony_ci if (ctlr->auto_runtime_pm) { 13708c2ecf20Sopenharmony_ci pm_runtime_mark_last_busy(ctlr->dev.parent); 13718c2ecf20Sopenharmony_ci pm_runtime_put_autosuspend(ctlr->dev.parent); 13728c2ecf20Sopenharmony_ci } 13738c2ecf20Sopenharmony_ci} 13748c2ecf20Sopenharmony_ci 13758c2ecf20Sopenharmony_ci/** 13768c2ecf20Sopenharmony_ci * __spi_pump_messages - function which processes spi message queue 13778c2ecf20Sopenharmony_ci * @ctlr: controller to process queue for 13788c2ecf20Sopenharmony_ci * @in_kthread: true if we are in the context of the message pump thread 13798c2ecf20Sopenharmony_ci * 13808c2ecf20Sopenharmony_ci * This function checks if there is any spi message in the queue that 13818c2ecf20Sopenharmony_ci * needs processing and if so call out to the driver to initialize hardware 13828c2ecf20Sopenharmony_ci * and transfer each message. 13838c2ecf20Sopenharmony_ci * 13848c2ecf20Sopenharmony_ci * Note that it is called both from the kthread itself and also from 13858c2ecf20Sopenharmony_ci * inside spi_sync(); the queue extraction handling at the top of the 13868c2ecf20Sopenharmony_ci * function should deal with this safely. 13878c2ecf20Sopenharmony_ci */ 13888c2ecf20Sopenharmony_cistatic void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) 13898c2ecf20Sopenharmony_ci{ 13908c2ecf20Sopenharmony_ci struct spi_transfer *xfer; 13918c2ecf20Sopenharmony_ci struct spi_message *msg; 13928c2ecf20Sopenharmony_ci bool was_busy = false; 13938c2ecf20Sopenharmony_ci unsigned long flags; 13948c2ecf20Sopenharmony_ci int ret; 13958c2ecf20Sopenharmony_ci 13968c2ecf20Sopenharmony_ci /* Lock queue */ 13978c2ecf20Sopenharmony_ci spin_lock_irqsave(&ctlr->queue_lock, flags); 13988c2ecf20Sopenharmony_ci 13998c2ecf20Sopenharmony_ci /* Make sure we are not already running a message */ 14008c2ecf20Sopenharmony_ci if (ctlr->cur_msg) { 14018c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->queue_lock, flags); 14028c2ecf20Sopenharmony_ci return; 14038c2ecf20Sopenharmony_ci } 14048c2ecf20Sopenharmony_ci 14058c2ecf20Sopenharmony_ci /* If another context is idling the device then defer */ 14068c2ecf20Sopenharmony_ci if (ctlr->idling) { 14078c2ecf20Sopenharmony_ci kthread_queue_work(ctlr->kworker, &ctlr->pump_messages); 14088c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->queue_lock, flags); 14098c2ecf20Sopenharmony_ci return; 14108c2ecf20Sopenharmony_ci } 14118c2ecf20Sopenharmony_ci 14128c2ecf20Sopenharmony_ci /* Check if the queue is idle */ 14138c2ecf20Sopenharmony_ci if (list_empty(&ctlr->queue) || !ctlr->running) { 14148c2ecf20Sopenharmony_ci if (!ctlr->busy) { 14158c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->queue_lock, flags); 14168c2ecf20Sopenharmony_ci return; 14178c2ecf20Sopenharmony_ci } 14188c2ecf20Sopenharmony_ci 14198c2ecf20Sopenharmony_ci /* Defer any non-atomic teardown to the thread */ 14208c2ecf20Sopenharmony_ci if (!in_kthread) { 14218c2ecf20Sopenharmony_ci if (!ctlr->dummy_rx && !ctlr->dummy_tx && 14228c2ecf20Sopenharmony_ci !ctlr->unprepare_transfer_hardware) { 14238c2ecf20Sopenharmony_ci spi_idle_runtime_pm(ctlr); 14248c2ecf20Sopenharmony_ci ctlr->busy = false; 14258c2ecf20Sopenharmony_ci trace_spi_controller_idle(ctlr); 14268c2ecf20Sopenharmony_ci } else { 14278c2ecf20Sopenharmony_ci kthread_queue_work(ctlr->kworker, 14288c2ecf20Sopenharmony_ci &ctlr->pump_messages); 14298c2ecf20Sopenharmony_ci } 14308c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->queue_lock, flags); 14318c2ecf20Sopenharmony_ci return; 14328c2ecf20Sopenharmony_ci } 14338c2ecf20Sopenharmony_ci 14348c2ecf20Sopenharmony_ci ctlr->busy = false; 14358c2ecf20Sopenharmony_ci ctlr->idling = true; 14368c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->queue_lock, flags); 14378c2ecf20Sopenharmony_ci 14388c2ecf20Sopenharmony_ci kfree(ctlr->dummy_rx); 14398c2ecf20Sopenharmony_ci ctlr->dummy_rx = NULL; 14408c2ecf20Sopenharmony_ci kfree(ctlr->dummy_tx); 14418c2ecf20Sopenharmony_ci ctlr->dummy_tx = NULL; 14428c2ecf20Sopenharmony_ci if (ctlr->unprepare_transfer_hardware && 14438c2ecf20Sopenharmony_ci ctlr->unprepare_transfer_hardware(ctlr)) 14448c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, 14458c2ecf20Sopenharmony_ci "failed to unprepare transfer hardware\n"); 14468c2ecf20Sopenharmony_ci spi_idle_runtime_pm(ctlr); 14478c2ecf20Sopenharmony_ci trace_spi_controller_idle(ctlr); 14488c2ecf20Sopenharmony_ci 14498c2ecf20Sopenharmony_ci spin_lock_irqsave(&ctlr->queue_lock, flags); 14508c2ecf20Sopenharmony_ci ctlr->idling = false; 14518c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->queue_lock, flags); 14528c2ecf20Sopenharmony_ci return; 14538c2ecf20Sopenharmony_ci } 14548c2ecf20Sopenharmony_ci 14558c2ecf20Sopenharmony_ci /* Extract head of queue */ 14568c2ecf20Sopenharmony_ci msg = list_first_entry(&ctlr->queue, struct spi_message, queue); 14578c2ecf20Sopenharmony_ci ctlr->cur_msg = msg; 14588c2ecf20Sopenharmony_ci 14598c2ecf20Sopenharmony_ci list_del_init(&msg->queue); 14608c2ecf20Sopenharmony_ci if (ctlr->busy) 14618c2ecf20Sopenharmony_ci was_busy = true; 14628c2ecf20Sopenharmony_ci else 14638c2ecf20Sopenharmony_ci ctlr->busy = true; 14648c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->queue_lock, flags); 14658c2ecf20Sopenharmony_ci 14668c2ecf20Sopenharmony_ci mutex_lock(&ctlr->io_mutex); 14678c2ecf20Sopenharmony_ci 14688c2ecf20Sopenharmony_ci if (!was_busy && ctlr->auto_runtime_pm) { 14698c2ecf20Sopenharmony_ci ret = pm_runtime_get_sync(ctlr->dev.parent); 14708c2ecf20Sopenharmony_ci if (ret < 0) { 14718c2ecf20Sopenharmony_ci pm_runtime_put_noidle(ctlr->dev.parent); 14728c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "Failed to power device: %d\n", 14738c2ecf20Sopenharmony_ci ret); 14748c2ecf20Sopenharmony_ci mutex_unlock(&ctlr->io_mutex); 14758c2ecf20Sopenharmony_ci return; 14768c2ecf20Sopenharmony_ci } 14778c2ecf20Sopenharmony_ci } 14788c2ecf20Sopenharmony_ci 14798c2ecf20Sopenharmony_ci if (!was_busy) 14808c2ecf20Sopenharmony_ci trace_spi_controller_busy(ctlr); 14818c2ecf20Sopenharmony_ci 14828c2ecf20Sopenharmony_ci if (!was_busy && ctlr->prepare_transfer_hardware) { 14838c2ecf20Sopenharmony_ci ret = ctlr->prepare_transfer_hardware(ctlr); 14848c2ecf20Sopenharmony_ci if (ret) { 14858c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, 14868c2ecf20Sopenharmony_ci "failed to prepare transfer hardware: %d\n", 14878c2ecf20Sopenharmony_ci ret); 14888c2ecf20Sopenharmony_ci 14898c2ecf20Sopenharmony_ci if (ctlr->auto_runtime_pm) 14908c2ecf20Sopenharmony_ci pm_runtime_put(ctlr->dev.parent); 14918c2ecf20Sopenharmony_ci 14928c2ecf20Sopenharmony_ci msg->status = ret; 14938c2ecf20Sopenharmony_ci spi_finalize_current_message(ctlr); 14948c2ecf20Sopenharmony_ci 14958c2ecf20Sopenharmony_ci mutex_unlock(&ctlr->io_mutex); 14968c2ecf20Sopenharmony_ci return; 14978c2ecf20Sopenharmony_ci } 14988c2ecf20Sopenharmony_ci } 14998c2ecf20Sopenharmony_ci 15008c2ecf20Sopenharmony_ci trace_spi_message_start(msg); 15018c2ecf20Sopenharmony_ci 15028c2ecf20Sopenharmony_ci if (ctlr->prepare_message) { 15038c2ecf20Sopenharmony_ci ret = ctlr->prepare_message(ctlr, msg); 15048c2ecf20Sopenharmony_ci if (ret) { 15058c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "failed to prepare message: %d\n", 15068c2ecf20Sopenharmony_ci ret); 15078c2ecf20Sopenharmony_ci msg->status = ret; 15088c2ecf20Sopenharmony_ci spi_finalize_current_message(ctlr); 15098c2ecf20Sopenharmony_ci goto out; 15108c2ecf20Sopenharmony_ci } 15118c2ecf20Sopenharmony_ci ctlr->cur_msg_prepared = true; 15128c2ecf20Sopenharmony_ci } 15138c2ecf20Sopenharmony_ci 15148c2ecf20Sopenharmony_ci ret = spi_map_msg(ctlr, msg); 15158c2ecf20Sopenharmony_ci if (ret) { 15168c2ecf20Sopenharmony_ci msg->status = ret; 15178c2ecf20Sopenharmony_ci spi_finalize_current_message(ctlr); 15188c2ecf20Sopenharmony_ci goto out; 15198c2ecf20Sopenharmony_ci } 15208c2ecf20Sopenharmony_ci 15218c2ecf20Sopenharmony_ci if (!ctlr->ptp_sts_supported && !ctlr->transfer_one) { 15228c2ecf20Sopenharmony_ci list_for_each_entry(xfer, &msg->transfers, transfer_list) { 15238c2ecf20Sopenharmony_ci xfer->ptp_sts_word_pre = 0; 15248c2ecf20Sopenharmony_ci ptp_read_system_prets(xfer->ptp_sts); 15258c2ecf20Sopenharmony_ci } 15268c2ecf20Sopenharmony_ci } 15278c2ecf20Sopenharmony_ci 15288c2ecf20Sopenharmony_ci ret = ctlr->transfer_one_message(ctlr, msg); 15298c2ecf20Sopenharmony_ci if (ret) { 15308c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, 15318c2ecf20Sopenharmony_ci "failed to transfer one message from queue\n"); 15328c2ecf20Sopenharmony_ci goto out; 15338c2ecf20Sopenharmony_ci } 15348c2ecf20Sopenharmony_ci 15358c2ecf20Sopenharmony_ciout: 15368c2ecf20Sopenharmony_ci mutex_unlock(&ctlr->io_mutex); 15378c2ecf20Sopenharmony_ci 15388c2ecf20Sopenharmony_ci /* Prod the scheduler in case transfer_one() was busy waiting */ 15398c2ecf20Sopenharmony_ci if (!ret) 15408c2ecf20Sopenharmony_ci cond_resched(); 15418c2ecf20Sopenharmony_ci} 15428c2ecf20Sopenharmony_ci 15438c2ecf20Sopenharmony_ci/** 15448c2ecf20Sopenharmony_ci * spi_pump_messages - kthread work function which processes spi message queue 15458c2ecf20Sopenharmony_ci * @work: pointer to kthread work struct contained in the controller struct 15468c2ecf20Sopenharmony_ci */ 15478c2ecf20Sopenharmony_cistatic void spi_pump_messages(struct kthread_work *work) 15488c2ecf20Sopenharmony_ci{ 15498c2ecf20Sopenharmony_ci struct spi_controller *ctlr = 15508c2ecf20Sopenharmony_ci container_of(work, struct spi_controller, pump_messages); 15518c2ecf20Sopenharmony_ci 15528c2ecf20Sopenharmony_ci __spi_pump_messages(ctlr, true); 15538c2ecf20Sopenharmony_ci} 15548c2ecf20Sopenharmony_ci 15558c2ecf20Sopenharmony_ci/** 15568c2ecf20Sopenharmony_ci * spi_take_timestamp_pre - helper for drivers to collect the beginning of the 15578c2ecf20Sopenharmony_ci * TX timestamp for the requested byte from the SPI 15588c2ecf20Sopenharmony_ci * transfer. The frequency with which this function 15598c2ecf20Sopenharmony_ci * must be called (once per word, once for the whole 15608c2ecf20Sopenharmony_ci * transfer, once per batch of words etc) is arbitrary 15618c2ecf20Sopenharmony_ci * as long as the @tx buffer offset is greater than or 15628c2ecf20Sopenharmony_ci * equal to the requested byte at the time of the 15638c2ecf20Sopenharmony_ci * call. The timestamp is only taken once, at the 15648c2ecf20Sopenharmony_ci * first such call. It is assumed that the driver 15658c2ecf20Sopenharmony_ci * advances its @tx buffer pointer monotonically. 15668c2ecf20Sopenharmony_ci * @ctlr: Pointer to the spi_controller structure of the driver 15678c2ecf20Sopenharmony_ci * @xfer: Pointer to the transfer being timestamped 15688c2ecf20Sopenharmony_ci * @progress: How many words (not bytes) have been transferred so far 15698c2ecf20Sopenharmony_ci * @irqs_off: If true, will disable IRQs and preemption for the duration of the 15708c2ecf20Sopenharmony_ci * transfer, for less jitter in time measurement. Only compatible 15718c2ecf20Sopenharmony_ci * with PIO drivers. If true, must follow up with 15728c2ecf20Sopenharmony_ci * spi_take_timestamp_post or otherwise system will crash. 15738c2ecf20Sopenharmony_ci * WARNING: for fully predictable results, the CPU frequency must 15748c2ecf20Sopenharmony_ci * also be under control (governor). 15758c2ecf20Sopenharmony_ci */ 15768c2ecf20Sopenharmony_civoid spi_take_timestamp_pre(struct spi_controller *ctlr, 15778c2ecf20Sopenharmony_ci struct spi_transfer *xfer, 15788c2ecf20Sopenharmony_ci size_t progress, bool irqs_off) 15798c2ecf20Sopenharmony_ci{ 15808c2ecf20Sopenharmony_ci if (!xfer->ptp_sts) 15818c2ecf20Sopenharmony_ci return; 15828c2ecf20Sopenharmony_ci 15838c2ecf20Sopenharmony_ci if (xfer->timestamped) 15848c2ecf20Sopenharmony_ci return; 15858c2ecf20Sopenharmony_ci 15868c2ecf20Sopenharmony_ci if (progress > xfer->ptp_sts_word_pre) 15878c2ecf20Sopenharmony_ci return; 15888c2ecf20Sopenharmony_ci 15898c2ecf20Sopenharmony_ci /* Capture the resolution of the timestamp */ 15908c2ecf20Sopenharmony_ci xfer->ptp_sts_word_pre = progress; 15918c2ecf20Sopenharmony_ci 15928c2ecf20Sopenharmony_ci if (irqs_off) { 15938c2ecf20Sopenharmony_ci local_irq_save(ctlr->irq_flags); 15948c2ecf20Sopenharmony_ci preempt_disable(); 15958c2ecf20Sopenharmony_ci } 15968c2ecf20Sopenharmony_ci 15978c2ecf20Sopenharmony_ci ptp_read_system_prets(xfer->ptp_sts); 15988c2ecf20Sopenharmony_ci} 15998c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_take_timestamp_pre); 16008c2ecf20Sopenharmony_ci 16018c2ecf20Sopenharmony_ci/** 16028c2ecf20Sopenharmony_ci * spi_take_timestamp_post - helper for drivers to collect the end of the 16038c2ecf20Sopenharmony_ci * TX timestamp for the requested byte from the SPI 16048c2ecf20Sopenharmony_ci * transfer. Can be called with an arbitrary 16058c2ecf20Sopenharmony_ci * frequency: only the first call where @tx exceeds 16068c2ecf20Sopenharmony_ci * or is equal to the requested word will be 16078c2ecf20Sopenharmony_ci * timestamped. 16088c2ecf20Sopenharmony_ci * @ctlr: Pointer to the spi_controller structure of the driver 16098c2ecf20Sopenharmony_ci * @xfer: Pointer to the transfer being timestamped 16108c2ecf20Sopenharmony_ci * @progress: How many words (not bytes) have been transferred so far 16118c2ecf20Sopenharmony_ci * @irqs_off: If true, will re-enable IRQs and preemption for the local CPU. 16128c2ecf20Sopenharmony_ci */ 16138c2ecf20Sopenharmony_civoid spi_take_timestamp_post(struct spi_controller *ctlr, 16148c2ecf20Sopenharmony_ci struct spi_transfer *xfer, 16158c2ecf20Sopenharmony_ci size_t progress, bool irqs_off) 16168c2ecf20Sopenharmony_ci{ 16178c2ecf20Sopenharmony_ci if (!xfer->ptp_sts) 16188c2ecf20Sopenharmony_ci return; 16198c2ecf20Sopenharmony_ci 16208c2ecf20Sopenharmony_ci if (xfer->timestamped) 16218c2ecf20Sopenharmony_ci return; 16228c2ecf20Sopenharmony_ci 16238c2ecf20Sopenharmony_ci if (progress < xfer->ptp_sts_word_post) 16248c2ecf20Sopenharmony_ci return; 16258c2ecf20Sopenharmony_ci 16268c2ecf20Sopenharmony_ci ptp_read_system_postts(xfer->ptp_sts); 16278c2ecf20Sopenharmony_ci 16288c2ecf20Sopenharmony_ci if (irqs_off) { 16298c2ecf20Sopenharmony_ci local_irq_restore(ctlr->irq_flags); 16308c2ecf20Sopenharmony_ci preempt_enable(); 16318c2ecf20Sopenharmony_ci } 16328c2ecf20Sopenharmony_ci 16338c2ecf20Sopenharmony_ci /* Capture the resolution of the timestamp */ 16348c2ecf20Sopenharmony_ci xfer->ptp_sts_word_post = progress; 16358c2ecf20Sopenharmony_ci 16368c2ecf20Sopenharmony_ci xfer->timestamped = true; 16378c2ecf20Sopenharmony_ci} 16388c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_take_timestamp_post); 16398c2ecf20Sopenharmony_ci 16408c2ecf20Sopenharmony_ci/** 16418c2ecf20Sopenharmony_ci * spi_set_thread_rt - set the controller to pump at realtime priority 16428c2ecf20Sopenharmony_ci * @ctlr: controller to boost priority of 16438c2ecf20Sopenharmony_ci * 16448c2ecf20Sopenharmony_ci * This can be called because the controller requested realtime priority 16458c2ecf20Sopenharmony_ci * (by setting the ->rt value before calling spi_register_controller()) or 16468c2ecf20Sopenharmony_ci * because a device on the bus said that its transfers needed realtime 16478c2ecf20Sopenharmony_ci * priority. 16488c2ecf20Sopenharmony_ci * 16498c2ecf20Sopenharmony_ci * NOTE: at the moment if any device on a bus says it needs realtime then 16508c2ecf20Sopenharmony_ci * the thread will be at realtime priority for all transfers on that 16518c2ecf20Sopenharmony_ci * controller. If this eventually becomes a problem we may see if we can 16528c2ecf20Sopenharmony_ci * find a way to boost the priority only temporarily during relevant 16538c2ecf20Sopenharmony_ci * transfers. 16548c2ecf20Sopenharmony_ci */ 16558c2ecf20Sopenharmony_cistatic void spi_set_thread_rt(struct spi_controller *ctlr) 16568c2ecf20Sopenharmony_ci{ 16578c2ecf20Sopenharmony_ci dev_info(&ctlr->dev, 16588c2ecf20Sopenharmony_ci "will run message pump with realtime priority\n"); 16598c2ecf20Sopenharmony_ci sched_set_fifo(ctlr->kworker->task); 16608c2ecf20Sopenharmony_ci} 16618c2ecf20Sopenharmony_ci 16628c2ecf20Sopenharmony_cistatic int spi_init_queue(struct spi_controller *ctlr) 16638c2ecf20Sopenharmony_ci{ 16648c2ecf20Sopenharmony_ci ctlr->running = false; 16658c2ecf20Sopenharmony_ci ctlr->busy = false; 16668c2ecf20Sopenharmony_ci 16678c2ecf20Sopenharmony_ci ctlr->kworker = kthread_create_worker(0, dev_name(&ctlr->dev)); 16688c2ecf20Sopenharmony_ci if (IS_ERR(ctlr->kworker)) { 16698c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "failed to create message pump kworker\n"); 16708c2ecf20Sopenharmony_ci return PTR_ERR(ctlr->kworker); 16718c2ecf20Sopenharmony_ci } 16728c2ecf20Sopenharmony_ci 16738c2ecf20Sopenharmony_ci kthread_init_work(&ctlr->pump_messages, spi_pump_messages); 16748c2ecf20Sopenharmony_ci 16758c2ecf20Sopenharmony_ci /* 16768c2ecf20Sopenharmony_ci * Controller config will indicate if this controller should run the 16778c2ecf20Sopenharmony_ci * message pump with high (realtime) priority to reduce the transfer 16788c2ecf20Sopenharmony_ci * latency on the bus by minimising the delay between a transfer 16798c2ecf20Sopenharmony_ci * request and the scheduling of the message pump thread. Without this 16808c2ecf20Sopenharmony_ci * setting the message pump thread will remain at default priority. 16818c2ecf20Sopenharmony_ci */ 16828c2ecf20Sopenharmony_ci if (ctlr->rt) 16838c2ecf20Sopenharmony_ci spi_set_thread_rt(ctlr); 16848c2ecf20Sopenharmony_ci 16858c2ecf20Sopenharmony_ci return 0; 16868c2ecf20Sopenharmony_ci} 16878c2ecf20Sopenharmony_ci 16888c2ecf20Sopenharmony_ci/** 16898c2ecf20Sopenharmony_ci * spi_get_next_queued_message() - called by driver to check for queued 16908c2ecf20Sopenharmony_ci * messages 16918c2ecf20Sopenharmony_ci * @ctlr: the controller to check for queued messages 16928c2ecf20Sopenharmony_ci * 16938c2ecf20Sopenharmony_ci * If there are more messages in the queue, the next message is returned from 16948c2ecf20Sopenharmony_ci * this call. 16958c2ecf20Sopenharmony_ci * 16968c2ecf20Sopenharmony_ci * Return: the next message in the queue, else NULL if the queue is empty. 16978c2ecf20Sopenharmony_ci */ 16988c2ecf20Sopenharmony_cistruct spi_message *spi_get_next_queued_message(struct spi_controller *ctlr) 16998c2ecf20Sopenharmony_ci{ 17008c2ecf20Sopenharmony_ci struct spi_message *next; 17018c2ecf20Sopenharmony_ci unsigned long flags; 17028c2ecf20Sopenharmony_ci 17038c2ecf20Sopenharmony_ci /* get a pointer to the next message, if any */ 17048c2ecf20Sopenharmony_ci spin_lock_irqsave(&ctlr->queue_lock, flags); 17058c2ecf20Sopenharmony_ci next = list_first_entry_or_null(&ctlr->queue, struct spi_message, 17068c2ecf20Sopenharmony_ci queue); 17078c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->queue_lock, flags); 17088c2ecf20Sopenharmony_ci 17098c2ecf20Sopenharmony_ci return next; 17108c2ecf20Sopenharmony_ci} 17118c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_get_next_queued_message); 17128c2ecf20Sopenharmony_ci 17138c2ecf20Sopenharmony_ci/** 17148c2ecf20Sopenharmony_ci * spi_finalize_current_message() - the current message is complete 17158c2ecf20Sopenharmony_ci * @ctlr: the controller to return the message to 17168c2ecf20Sopenharmony_ci * 17178c2ecf20Sopenharmony_ci * Called by the driver to notify the core that the message in the front of the 17188c2ecf20Sopenharmony_ci * queue is complete and can be removed from the queue. 17198c2ecf20Sopenharmony_ci */ 17208c2ecf20Sopenharmony_civoid spi_finalize_current_message(struct spi_controller *ctlr) 17218c2ecf20Sopenharmony_ci{ 17228c2ecf20Sopenharmony_ci struct spi_transfer *xfer; 17238c2ecf20Sopenharmony_ci struct spi_message *mesg; 17248c2ecf20Sopenharmony_ci unsigned long flags; 17258c2ecf20Sopenharmony_ci int ret; 17268c2ecf20Sopenharmony_ci 17278c2ecf20Sopenharmony_ci spin_lock_irqsave(&ctlr->queue_lock, flags); 17288c2ecf20Sopenharmony_ci mesg = ctlr->cur_msg; 17298c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->queue_lock, flags); 17308c2ecf20Sopenharmony_ci 17318c2ecf20Sopenharmony_ci if (!ctlr->ptp_sts_supported && !ctlr->transfer_one) { 17328c2ecf20Sopenharmony_ci list_for_each_entry(xfer, &mesg->transfers, transfer_list) { 17338c2ecf20Sopenharmony_ci ptp_read_system_postts(xfer->ptp_sts); 17348c2ecf20Sopenharmony_ci xfer->ptp_sts_word_post = xfer->len; 17358c2ecf20Sopenharmony_ci } 17368c2ecf20Sopenharmony_ci } 17378c2ecf20Sopenharmony_ci 17388c2ecf20Sopenharmony_ci if (unlikely(ctlr->ptp_sts_supported)) 17398c2ecf20Sopenharmony_ci list_for_each_entry(xfer, &mesg->transfers, transfer_list) 17408c2ecf20Sopenharmony_ci WARN_ON_ONCE(xfer->ptp_sts && !xfer->timestamped); 17418c2ecf20Sopenharmony_ci 17428c2ecf20Sopenharmony_ci spi_unmap_msg(ctlr, mesg); 17438c2ecf20Sopenharmony_ci 17448c2ecf20Sopenharmony_ci /* In the prepare_messages callback the spi bus has the opportunity to 17458c2ecf20Sopenharmony_ci * split a transfer to smaller chunks. 17468c2ecf20Sopenharmony_ci * Release splited transfers here since spi_map_msg is done on the 17478c2ecf20Sopenharmony_ci * splited transfers. 17488c2ecf20Sopenharmony_ci */ 17498c2ecf20Sopenharmony_ci spi_res_release(ctlr, mesg); 17508c2ecf20Sopenharmony_ci 17518c2ecf20Sopenharmony_ci if (ctlr->cur_msg_prepared && ctlr->unprepare_message) { 17528c2ecf20Sopenharmony_ci ret = ctlr->unprepare_message(ctlr, mesg); 17538c2ecf20Sopenharmony_ci if (ret) { 17548c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "failed to unprepare message: %d\n", 17558c2ecf20Sopenharmony_ci ret); 17568c2ecf20Sopenharmony_ci } 17578c2ecf20Sopenharmony_ci } 17588c2ecf20Sopenharmony_ci 17598c2ecf20Sopenharmony_ci spin_lock_irqsave(&ctlr->queue_lock, flags); 17608c2ecf20Sopenharmony_ci ctlr->cur_msg = NULL; 17618c2ecf20Sopenharmony_ci ctlr->cur_msg_prepared = false; 17628c2ecf20Sopenharmony_ci ctlr->fallback = false; 17638c2ecf20Sopenharmony_ci kthread_queue_work(ctlr->kworker, &ctlr->pump_messages); 17648c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->queue_lock, flags); 17658c2ecf20Sopenharmony_ci 17668c2ecf20Sopenharmony_ci trace_spi_message_done(mesg); 17678c2ecf20Sopenharmony_ci 17688c2ecf20Sopenharmony_ci mesg->state = NULL; 17698c2ecf20Sopenharmony_ci if (mesg->complete) 17708c2ecf20Sopenharmony_ci mesg->complete(mesg->context); 17718c2ecf20Sopenharmony_ci} 17728c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_finalize_current_message); 17738c2ecf20Sopenharmony_ci 17748c2ecf20Sopenharmony_cistatic int spi_start_queue(struct spi_controller *ctlr) 17758c2ecf20Sopenharmony_ci{ 17768c2ecf20Sopenharmony_ci unsigned long flags; 17778c2ecf20Sopenharmony_ci 17788c2ecf20Sopenharmony_ci spin_lock_irqsave(&ctlr->queue_lock, flags); 17798c2ecf20Sopenharmony_ci 17808c2ecf20Sopenharmony_ci if (ctlr->running || ctlr->busy) { 17818c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->queue_lock, flags); 17828c2ecf20Sopenharmony_ci return -EBUSY; 17838c2ecf20Sopenharmony_ci } 17848c2ecf20Sopenharmony_ci 17858c2ecf20Sopenharmony_ci ctlr->running = true; 17868c2ecf20Sopenharmony_ci ctlr->cur_msg = NULL; 17878c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->queue_lock, flags); 17888c2ecf20Sopenharmony_ci 17898c2ecf20Sopenharmony_ci kthread_queue_work(ctlr->kworker, &ctlr->pump_messages); 17908c2ecf20Sopenharmony_ci 17918c2ecf20Sopenharmony_ci return 0; 17928c2ecf20Sopenharmony_ci} 17938c2ecf20Sopenharmony_ci 17948c2ecf20Sopenharmony_cistatic int spi_stop_queue(struct spi_controller *ctlr) 17958c2ecf20Sopenharmony_ci{ 17968c2ecf20Sopenharmony_ci unsigned long flags; 17978c2ecf20Sopenharmony_ci unsigned limit = 500; 17988c2ecf20Sopenharmony_ci int ret = 0; 17998c2ecf20Sopenharmony_ci 18008c2ecf20Sopenharmony_ci spin_lock_irqsave(&ctlr->queue_lock, flags); 18018c2ecf20Sopenharmony_ci 18028c2ecf20Sopenharmony_ci /* 18038c2ecf20Sopenharmony_ci * This is a bit lame, but is optimized for the common execution path. 18048c2ecf20Sopenharmony_ci * A wait_queue on the ctlr->busy could be used, but then the common 18058c2ecf20Sopenharmony_ci * execution path (pump_messages) would be required to call wake_up or 18068c2ecf20Sopenharmony_ci * friends on every SPI message. Do this instead. 18078c2ecf20Sopenharmony_ci */ 18088c2ecf20Sopenharmony_ci while ((!list_empty(&ctlr->queue) || ctlr->busy) && limit--) { 18098c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->queue_lock, flags); 18108c2ecf20Sopenharmony_ci usleep_range(10000, 11000); 18118c2ecf20Sopenharmony_ci spin_lock_irqsave(&ctlr->queue_lock, flags); 18128c2ecf20Sopenharmony_ci } 18138c2ecf20Sopenharmony_ci 18148c2ecf20Sopenharmony_ci if (!list_empty(&ctlr->queue) || ctlr->busy) 18158c2ecf20Sopenharmony_ci ret = -EBUSY; 18168c2ecf20Sopenharmony_ci else 18178c2ecf20Sopenharmony_ci ctlr->running = false; 18188c2ecf20Sopenharmony_ci 18198c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->queue_lock, flags); 18208c2ecf20Sopenharmony_ci 18218c2ecf20Sopenharmony_ci if (ret) { 18228c2ecf20Sopenharmony_ci dev_warn(&ctlr->dev, "could not stop message queue\n"); 18238c2ecf20Sopenharmony_ci return ret; 18248c2ecf20Sopenharmony_ci } 18258c2ecf20Sopenharmony_ci return ret; 18268c2ecf20Sopenharmony_ci} 18278c2ecf20Sopenharmony_ci 18288c2ecf20Sopenharmony_cistatic int spi_destroy_queue(struct spi_controller *ctlr) 18298c2ecf20Sopenharmony_ci{ 18308c2ecf20Sopenharmony_ci int ret; 18318c2ecf20Sopenharmony_ci 18328c2ecf20Sopenharmony_ci ret = spi_stop_queue(ctlr); 18338c2ecf20Sopenharmony_ci 18348c2ecf20Sopenharmony_ci /* 18358c2ecf20Sopenharmony_ci * kthread_flush_worker will block until all work is done. 18368c2ecf20Sopenharmony_ci * If the reason that stop_queue timed out is that the work will never 18378c2ecf20Sopenharmony_ci * finish, then it does no good to call flush/stop thread, so 18388c2ecf20Sopenharmony_ci * return anyway. 18398c2ecf20Sopenharmony_ci */ 18408c2ecf20Sopenharmony_ci if (ret) { 18418c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "problem destroying queue\n"); 18428c2ecf20Sopenharmony_ci return ret; 18438c2ecf20Sopenharmony_ci } 18448c2ecf20Sopenharmony_ci 18458c2ecf20Sopenharmony_ci kthread_destroy_worker(ctlr->kworker); 18468c2ecf20Sopenharmony_ci 18478c2ecf20Sopenharmony_ci return 0; 18488c2ecf20Sopenharmony_ci} 18498c2ecf20Sopenharmony_ci 18508c2ecf20Sopenharmony_cistatic int __spi_queued_transfer(struct spi_device *spi, 18518c2ecf20Sopenharmony_ci struct spi_message *msg, 18528c2ecf20Sopenharmony_ci bool need_pump) 18538c2ecf20Sopenharmony_ci{ 18548c2ecf20Sopenharmony_ci struct spi_controller *ctlr = spi->controller; 18558c2ecf20Sopenharmony_ci unsigned long flags; 18568c2ecf20Sopenharmony_ci 18578c2ecf20Sopenharmony_ci spin_lock_irqsave(&ctlr->queue_lock, flags); 18588c2ecf20Sopenharmony_ci 18598c2ecf20Sopenharmony_ci if (!ctlr->running) { 18608c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->queue_lock, flags); 18618c2ecf20Sopenharmony_ci return -ESHUTDOWN; 18628c2ecf20Sopenharmony_ci } 18638c2ecf20Sopenharmony_ci msg->actual_length = 0; 18648c2ecf20Sopenharmony_ci msg->status = -EINPROGRESS; 18658c2ecf20Sopenharmony_ci 18668c2ecf20Sopenharmony_ci list_add_tail(&msg->queue, &ctlr->queue); 18678c2ecf20Sopenharmony_ci if (!ctlr->busy && need_pump) 18688c2ecf20Sopenharmony_ci kthread_queue_work(ctlr->kworker, &ctlr->pump_messages); 18698c2ecf20Sopenharmony_ci 18708c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->queue_lock, flags); 18718c2ecf20Sopenharmony_ci return 0; 18728c2ecf20Sopenharmony_ci} 18738c2ecf20Sopenharmony_ci 18748c2ecf20Sopenharmony_ci/** 18758c2ecf20Sopenharmony_ci * spi_queued_transfer - transfer function for queued transfers 18768c2ecf20Sopenharmony_ci * @spi: spi device which is requesting transfer 18778c2ecf20Sopenharmony_ci * @msg: spi message which is to handled is queued to driver queue 18788c2ecf20Sopenharmony_ci * 18798c2ecf20Sopenharmony_ci * Return: zero on success, else a negative error code. 18808c2ecf20Sopenharmony_ci */ 18818c2ecf20Sopenharmony_cistatic int spi_queued_transfer(struct spi_device *spi, struct spi_message *msg) 18828c2ecf20Sopenharmony_ci{ 18838c2ecf20Sopenharmony_ci return __spi_queued_transfer(spi, msg, true); 18848c2ecf20Sopenharmony_ci} 18858c2ecf20Sopenharmony_ci 18868c2ecf20Sopenharmony_cistatic int spi_controller_initialize_queue(struct spi_controller *ctlr) 18878c2ecf20Sopenharmony_ci{ 18888c2ecf20Sopenharmony_ci int ret; 18898c2ecf20Sopenharmony_ci 18908c2ecf20Sopenharmony_ci ctlr->transfer = spi_queued_transfer; 18918c2ecf20Sopenharmony_ci if (!ctlr->transfer_one_message) 18928c2ecf20Sopenharmony_ci ctlr->transfer_one_message = spi_transfer_one_message; 18938c2ecf20Sopenharmony_ci 18948c2ecf20Sopenharmony_ci /* Initialize and start queue */ 18958c2ecf20Sopenharmony_ci ret = spi_init_queue(ctlr); 18968c2ecf20Sopenharmony_ci if (ret) { 18978c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "problem initializing queue\n"); 18988c2ecf20Sopenharmony_ci goto err_init_queue; 18998c2ecf20Sopenharmony_ci } 19008c2ecf20Sopenharmony_ci ctlr->queued = true; 19018c2ecf20Sopenharmony_ci ret = spi_start_queue(ctlr); 19028c2ecf20Sopenharmony_ci if (ret) { 19038c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "problem starting queue\n"); 19048c2ecf20Sopenharmony_ci goto err_start_queue; 19058c2ecf20Sopenharmony_ci } 19068c2ecf20Sopenharmony_ci 19078c2ecf20Sopenharmony_ci return 0; 19088c2ecf20Sopenharmony_ci 19098c2ecf20Sopenharmony_cierr_start_queue: 19108c2ecf20Sopenharmony_ci spi_destroy_queue(ctlr); 19118c2ecf20Sopenharmony_cierr_init_queue: 19128c2ecf20Sopenharmony_ci return ret; 19138c2ecf20Sopenharmony_ci} 19148c2ecf20Sopenharmony_ci 19158c2ecf20Sopenharmony_ci/** 19168c2ecf20Sopenharmony_ci * spi_flush_queue - Send all pending messages in the queue from the callers' 19178c2ecf20Sopenharmony_ci * context 19188c2ecf20Sopenharmony_ci * @ctlr: controller to process queue for 19198c2ecf20Sopenharmony_ci * 19208c2ecf20Sopenharmony_ci * This should be used when one wants to ensure all pending messages have been 19218c2ecf20Sopenharmony_ci * sent before doing something. Is used by the spi-mem code to make sure SPI 19228c2ecf20Sopenharmony_ci * memory operations do not preempt regular SPI transfers that have been queued 19238c2ecf20Sopenharmony_ci * before the spi-mem operation. 19248c2ecf20Sopenharmony_ci */ 19258c2ecf20Sopenharmony_civoid spi_flush_queue(struct spi_controller *ctlr) 19268c2ecf20Sopenharmony_ci{ 19278c2ecf20Sopenharmony_ci if (ctlr->transfer == spi_queued_transfer) 19288c2ecf20Sopenharmony_ci __spi_pump_messages(ctlr, false); 19298c2ecf20Sopenharmony_ci} 19308c2ecf20Sopenharmony_ci 19318c2ecf20Sopenharmony_ci/*-------------------------------------------------------------------------*/ 19328c2ecf20Sopenharmony_ci 19338c2ecf20Sopenharmony_ci#if defined(CONFIG_OF) 19348c2ecf20Sopenharmony_cistatic int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, 19358c2ecf20Sopenharmony_ci struct device_node *nc) 19368c2ecf20Sopenharmony_ci{ 19378c2ecf20Sopenharmony_ci u32 value; 19388c2ecf20Sopenharmony_ci int rc; 19398c2ecf20Sopenharmony_ci 19408c2ecf20Sopenharmony_ci /* Mode (clock phase/polarity/etc.) */ 19418c2ecf20Sopenharmony_ci if (of_property_read_bool(nc, "spi-cpha")) 19428c2ecf20Sopenharmony_ci spi->mode |= SPI_CPHA; 19438c2ecf20Sopenharmony_ci if (of_property_read_bool(nc, "spi-cpol")) 19448c2ecf20Sopenharmony_ci spi->mode |= SPI_CPOL; 19458c2ecf20Sopenharmony_ci if (of_property_read_bool(nc, "spi-3wire")) 19468c2ecf20Sopenharmony_ci spi->mode |= SPI_3WIRE; 19478c2ecf20Sopenharmony_ci if (of_property_read_bool(nc, "spi-lsb-first")) 19488c2ecf20Sopenharmony_ci spi->mode |= SPI_LSB_FIRST; 19498c2ecf20Sopenharmony_ci if (of_property_read_bool(nc, "spi-cs-high")) 19508c2ecf20Sopenharmony_ci spi->mode |= SPI_CS_HIGH; 19518c2ecf20Sopenharmony_ci 19528c2ecf20Sopenharmony_ci /* Device DUAL/QUAD mode */ 19538c2ecf20Sopenharmony_ci if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) { 19548c2ecf20Sopenharmony_ci switch (value) { 19558c2ecf20Sopenharmony_ci case 1: 19568c2ecf20Sopenharmony_ci break; 19578c2ecf20Sopenharmony_ci case 2: 19588c2ecf20Sopenharmony_ci spi->mode |= SPI_TX_DUAL; 19598c2ecf20Sopenharmony_ci break; 19608c2ecf20Sopenharmony_ci case 4: 19618c2ecf20Sopenharmony_ci spi->mode |= SPI_TX_QUAD; 19628c2ecf20Sopenharmony_ci break; 19638c2ecf20Sopenharmony_ci case 8: 19648c2ecf20Sopenharmony_ci spi->mode |= SPI_TX_OCTAL; 19658c2ecf20Sopenharmony_ci break; 19668c2ecf20Sopenharmony_ci default: 19678c2ecf20Sopenharmony_ci dev_warn(&ctlr->dev, 19688c2ecf20Sopenharmony_ci "spi-tx-bus-width %d not supported\n", 19698c2ecf20Sopenharmony_ci value); 19708c2ecf20Sopenharmony_ci break; 19718c2ecf20Sopenharmony_ci } 19728c2ecf20Sopenharmony_ci } 19738c2ecf20Sopenharmony_ci 19748c2ecf20Sopenharmony_ci if (!of_property_read_u32(nc, "spi-rx-bus-width", &value)) { 19758c2ecf20Sopenharmony_ci switch (value) { 19768c2ecf20Sopenharmony_ci case 1: 19778c2ecf20Sopenharmony_ci break; 19788c2ecf20Sopenharmony_ci case 2: 19798c2ecf20Sopenharmony_ci spi->mode |= SPI_RX_DUAL; 19808c2ecf20Sopenharmony_ci break; 19818c2ecf20Sopenharmony_ci case 4: 19828c2ecf20Sopenharmony_ci spi->mode |= SPI_RX_QUAD; 19838c2ecf20Sopenharmony_ci break; 19848c2ecf20Sopenharmony_ci case 8: 19858c2ecf20Sopenharmony_ci spi->mode |= SPI_RX_OCTAL; 19868c2ecf20Sopenharmony_ci break; 19878c2ecf20Sopenharmony_ci default: 19888c2ecf20Sopenharmony_ci dev_warn(&ctlr->dev, 19898c2ecf20Sopenharmony_ci "spi-rx-bus-width %d not supported\n", 19908c2ecf20Sopenharmony_ci value); 19918c2ecf20Sopenharmony_ci break; 19928c2ecf20Sopenharmony_ci } 19938c2ecf20Sopenharmony_ci } 19948c2ecf20Sopenharmony_ci 19958c2ecf20Sopenharmony_ci if (spi_controller_is_slave(ctlr)) { 19968c2ecf20Sopenharmony_ci if (!of_node_name_eq(nc, "slave")) { 19978c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "%pOF is not called 'slave'\n", 19988c2ecf20Sopenharmony_ci nc); 19998c2ecf20Sopenharmony_ci return -EINVAL; 20008c2ecf20Sopenharmony_ci } 20018c2ecf20Sopenharmony_ci return 0; 20028c2ecf20Sopenharmony_ci } 20038c2ecf20Sopenharmony_ci 20048c2ecf20Sopenharmony_ci /* Device address */ 20058c2ecf20Sopenharmony_ci rc = of_property_read_u32(nc, "reg", &value); 20068c2ecf20Sopenharmony_ci if (rc) { 20078c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "%pOF has no valid 'reg' property (%d)\n", 20088c2ecf20Sopenharmony_ci nc, rc); 20098c2ecf20Sopenharmony_ci return rc; 20108c2ecf20Sopenharmony_ci } 20118c2ecf20Sopenharmony_ci spi->chip_select = value; 20128c2ecf20Sopenharmony_ci 20138c2ecf20Sopenharmony_ci /* Device speed */ 20148c2ecf20Sopenharmony_ci if (!of_property_read_u32(nc, "spi-max-frequency", &value)) 20158c2ecf20Sopenharmony_ci spi->max_speed_hz = value; 20168c2ecf20Sopenharmony_ci 20178c2ecf20Sopenharmony_ci return 0; 20188c2ecf20Sopenharmony_ci} 20198c2ecf20Sopenharmony_ci 20208c2ecf20Sopenharmony_cistatic struct spi_device * 20218c2ecf20Sopenharmony_ciof_register_spi_device(struct spi_controller *ctlr, struct device_node *nc) 20228c2ecf20Sopenharmony_ci{ 20238c2ecf20Sopenharmony_ci struct spi_device *spi; 20248c2ecf20Sopenharmony_ci int rc; 20258c2ecf20Sopenharmony_ci 20268c2ecf20Sopenharmony_ci /* Alloc an spi_device */ 20278c2ecf20Sopenharmony_ci spi = spi_alloc_device(ctlr); 20288c2ecf20Sopenharmony_ci if (!spi) { 20298c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "spi_device alloc error for %pOF\n", nc); 20308c2ecf20Sopenharmony_ci rc = -ENOMEM; 20318c2ecf20Sopenharmony_ci goto err_out; 20328c2ecf20Sopenharmony_ci } 20338c2ecf20Sopenharmony_ci 20348c2ecf20Sopenharmony_ci /* Select device driver */ 20358c2ecf20Sopenharmony_ci rc = of_modalias_node(nc, spi->modalias, 20368c2ecf20Sopenharmony_ci sizeof(spi->modalias)); 20378c2ecf20Sopenharmony_ci if (rc < 0) { 20388c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "cannot find modalias for %pOF\n", nc); 20398c2ecf20Sopenharmony_ci goto err_out; 20408c2ecf20Sopenharmony_ci } 20418c2ecf20Sopenharmony_ci 20428c2ecf20Sopenharmony_ci rc = of_spi_parse_dt(ctlr, spi, nc); 20438c2ecf20Sopenharmony_ci if (rc) 20448c2ecf20Sopenharmony_ci goto err_out; 20458c2ecf20Sopenharmony_ci 20468c2ecf20Sopenharmony_ci /* Store a pointer to the node in the device structure */ 20478c2ecf20Sopenharmony_ci of_node_get(nc); 20488c2ecf20Sopenharmony_ci spi->dev.of_node = nc; 20498c2ecf20Sopenharmony_ci spi->dev.fwnode = of_fwnode_handle(nc); 20508c2ecf20Sopenharmony_ci 20518c2ecf20Sopenharmony_ci /* Register the new device */ 20528c2ecf20Sopenharmony_ci rc = spi_add_device(spi); 20538c2ecf20Sopenharmony_ci if (rc) { 20548c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "spi_device register error %pOF\n", nc); 20558c2ecf20Sopenharmony_ci goto err_of_node_put; 20568c2ecf20Sopenharmony_ci } 20578c2ecf20Sopenharmony_ci 20588c2ecf20Sopenharmony_ci return spi; 20598c2ecf20Sopenharmony_ci 20608c2ecf20Sopenharmony_cierr_of_node_put: 20618c2ecf20Sopenharmony_ci of_node_put(nc); 20628c2ecf20Sopenharmony_cierr_out: 20638c2ecf20Sopenharmony_ci spi_dev_put(spi); 20648c2ecf20Sopenharmony_ci return ERR_PTR(rc); 20658c2ecf20Sopenharmony_ci} 20668c2ecf20Sopenharmony_ci 20678c2ecf20Sopenharmony_ci/** 20688c2ecf20Sopenharmony_ci * of_register_spi_devices() - Register child devices onto the SPI bus 20698c2ecf20Sopenharmony_ci * @ctlr: Pointer to spi_controller device 20708c2ecf20Sopenharmony_ci * 20718c2ecf20Sopenharmony_ci * Registers an spi_device for each child node of controller node which 20728c2ecf20Sopenharmony_ci * represents a valid SPI slave. 20738c2ecf20Sopenharmony_ci */ 20748c2ecf20Sopenharmony_cistatic void of_register_spi_devices(struct spi_controller *ctlr) 20758c2ecf20Sopenharmony_ci{ 20768c2ecf20Sopenharmony_ci struct spi_device *spi; 20778c2ecf20Sopenharmony_ci struct device_node *nc; 20788c2ecf20Sopenharmony_ci 20798c2ecf20Sopenharmony_ci if (!ctlr->dev.of_node) 20808c2ecf20Sopenharmony_ci return; 20818c2ecf20Sopenharmony_ci 20828c2ecf20Sopenharmony_ci for_each_available_child_of_node(ctlr->dev.of_node, nc) { 20838c2ecf20Sopenharmony_ci if (of_node_test_and_set_flag(nc, OF_POPULATED)) 20848c2ecf20Sopenharmony_ci continue; 20858c2ecf20Sopenharmony_ci spi = of_register_spi_device(ctlr, nc); 20868c2ecf20Sopenharmony_ci if (IS_ERR(spi)) { 20878c2ecf20Sopenharmony_ci dev_warn(&ctlr->dev, 20888c2ecf20Sopenharmony_ci "Failed to create SPI device for %pOF\n", nc); 20898c2ecf20Sopenharmony_ci of_node_clear_flag(nc, OF_POPULATED); 20908c2ecf20Sopenharmony_ci } 20918c2ecf20Sopenharmony_ci } 20928c2ecf20Sopenharmony_ci} 20938c2ecf20Sopenharmony_ci#else 20948c2ecf20Sopenharmony_cistatic void of_register_spi_devices(struct spi_controller *ctlr) { } 20958c2ecf20Sopenharmony_ci#endif 20968c2ecf20Sopenharmony_ci 20978c2ecf20Sopenharmony_ci#ifdef CONFIG_ACPI 20988c2ecf20Sopenharmony_cistruct acpi_spi_lookup { 20998c2ecf20Sopenharmony_ci struct spi_controller *ctlr; 21008c2ecf20Sopenharmony_ci u32 max_speed_hz; 21018c2ecf20Sopenharmony_ci u32 mode; 21028c2ecf20Sopenharmony_ci int irq; 21038c2ecf20Sopenharmony_ci u8 bits_per_word; 21048c2ecf20Sopenharmony_ci u8 chip_select; 21058c2ecf20Sopenharmony_ci}; 21068c2ecf20Sopenharmony_ci 21078c2ecf20Sopenharmony_cistatic void acpi_spi_parse_apple_properties(struct acpi_device *dev, 21088c2ecf20Sopenharmony_ci struct acpi_spi_lookup *lookup) 21098c2ecf20Sopenharmony_ci{ 21108c2ecf20Sopenharmony_ci const union acpi_object *obj; 21118c2ecf20Sopenharmony_ci 21128c2ecf20Sopenharmony_ci if (!x86_apple_machine) 21138c2ecf20Sopenharmony_ci return; 21148c2ecf20Sopenharmony_ci 21158c2ecf20Sopenharmony_ci if (!acpi_dev_get_property(dev, "spiSclkPeriod", ACPI_TYPE_BUFFER, &obj) 21168c2ecf20Sopenharmony_ci && obj->buffer.length >= 4) 21178c2ecf20Sopenharmony_ci lookup->max_speed_hz = NSEC_PER_SEC / *(u32 *)obj->buffer.pointer; 21188c2ecf20Sopenharmony_ci 21198c2ecf20Sopenharmony_ci if (!acpi_dev_get_property(dev, "spiWordSize", ACPI_TYPE_BUFFER, &obj) 21208c2ecf20Sopenharmony_ci && obj->buffer.length == 8) 21218c2ecf20Sopenharmony_ci lookup->bits_per_word = *(u64 *)obj->buffer.pointer; 21228c2ecf20Sopenharmony_ci 21238c2ecf20Sopenharmony_ci if (!acpi_dev_get_property(dev, "spiBitOrder", ACPI_TYPE_BUFFER, &obj) 21248c2ecf20Sopenharmony_ci && obj->buffer.length == 8 && !*(u64 *)obj->buffer.pointer) 21258c2ecf20Sopenharmony_ci lookup->mode |= SPI_LSB_FIRST; 21268c2ecf20Sopenharmony_ci 21278c2ecf20Sopenharmony_ci if (!acpi_dev_get_property(dev, "spiSPO", ACPI_TYPE_BUFFER, &obj) 21288c2ecf20Sopenharmony_ci && obj->buffer.length == 8 && *(u64 *)obj->buffer.pointer) 21298c2ecf20Sopenharmony_ci lookup->mode |= SPI_CPOL; 21308c2ecf20Sopenharmony_ci 21318c2ecf20Sopenharmony_ci if (!acpi_dev_get_property(dev, "spiSPH", ACPI_TYPE_BUFFER, &obj) 21328c2ecf20Sopenharmony_ci && obj->buffer.length == 8 && *(u64 *)obj->buffer.pointer) 21338c2ecf20Sopenharmony_ci lookup->mode |= SPI_CPHA; 21348c2ecf20Sopenharmony_ci} 21358c2ecf20Sopenharmony_ci 21368c2ecf20Sopenharmony_cistatic int acpi_spi_add_resource(struct acpi_resource *ares, void *data) 21378c2ecf20Sopenharmony_ci{ 21388c2ecf20Sopenharmony_ci struct acpi_spi_lookup *lookup = data; 21398c2ecf20Sopenharmony_ci struct spi_controller *ctlr = lookup->ctlr; 21408c2ecf20Sopenharmony_ci 21418c2ecf20Sopenharmony_ci if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { 21428c2ecf20Sopenharmony_ci struct acpi_resource_spi_serialbus *sb; 21438c2ecf20Sopenharmony_ci acpi_handle parent_handle; 21448c2ecf20Sopenharmony_ci acpi_status status; 21458c2ecf20Sopenharmony_ci 21468c2ecf20Sopenharmony_ci sb = &ares->data.spi_serial_bus; 21478c2ecf20Sopenharmony_ci if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) { 21488c2ecf20Sopenharmony_ci 21498c2ecf20Sopenharmony_ci status = acpi_get_handle(NULL, 21508c2ecf20Sopenharmony_ci sb->resource_source.string_ptr, 21518c2ecf20Sopenharmony_ci &parent_handle); 21528c2ecf20Sopenharmony_ci 21538c2ecf20Sopenharmony_ci if (ACPI_FAILURE(status) || 21548c2ecf20Sopenharmony_ci ACPI_HANDLE(ctlr->dev.parent) != parent_handle) 21558c2ecf20Sopenharmony_ci return -ENODEV; 21568c2ecf20Sopenharmony_ci 21578c2ecf20Sopenharmony_ci /* 21588c2ecf20Sopenharmony_ci * ACPI DeviceSelection numbering is handled by the 21598c2ecf20Sopenharmony_ci * host controller driver in Windows and can vary 21608c2ecf20Sopenharmony_ci * from driver to driver. In Linux we always expect 21618c2ecf20Sopenharmony_ci * 0 .. max - 1 so we need to ask the driver to 21628c2ecf20Sopenharmony_ci * translate between the two schemes. 21638c2ecf20Sopenharmony_ci */ 21648c2ecf20Sopenharmony_ci if (ctlr->fw_translate_cs) { 21658c2ecf20Sopenharmony_ci int cs = ctlr->fw_translate_cs(ctlr, 21668c2ecf20Sopenharmony_ci sb->device_selection); 21678c2ecf20Sopenharmony_ci if (cs < 0) 21688c2ecf20Sopenharmony_ci return cs; 21698c2ecf20Sopenharmony_ci lookup->chip_select = cs; 21708c2ecf20Sopenharmony_ci } else { 21718c2ecf20Sopenharmony_ci lookup->chip_select = sb->device_selection; 21728c2ecf20Sopenharmony_ci } 21738c2ecf20Sopenharmony_ci 21748c2ecf20Sopenharmony_ci lookup->max_speed_hz = sb->connection_speed; 21758c2ecf20Sopenharmony_ci lookup->bits_per_word = sb->data_bit_length; 21768c2ecf20Sopenharmony_ci 21778c2ecf20Sopenharmony_ci if (sb->clock_phase == ACPI_SPI_SECOND_PHASE) 21788c2ecf20Sopenharmony_ci lookup->mode |= SPI_CPHA; 21798c2ecf20Sopenharmony_ci if (sb->clock_polarity == ACPI_SPI_START_HIGH) 21808c2ecf20Sopenharmony_ci lookup->mode |= SPI_CPOL; 21818c2ecf20Sopenharmony_ci if (sb->device_polarity == ACPI_SPI_ACTIVE_HIGH) 21828c2ecf20Sopenharmony_ci lookup->mode |= SPI_CS_HIGH; 21838c2ecf20Sopenharmony_ci } 21848c2ecf20Sopenharmony_ci } else if (lookup->irq < 0) { 21858c2ecf20Sopenharmony_ci struct resource r; 21868c2ecf20Sopenharmony_ci 21878c2ecf20Sopenharmony_ci if (acpi_dev_resource_interrupt(ares, 0, &r)) 21888c2ecf20Sopenharmony_ci lookup->irq = r.start; 21898c2ecf20Sopenharmony_ci } 21908c2ecf20Sopenharmony_ci 21918c2ecf20Sopenharmony_ci /* Always tell the ACPI core to skip this resource */ 21928c2ecf20Sopenharmony_ci return 1; 21938c2ecf20Sopenharmony_ci} 21948c2ecf20Sopenharmony_ci 21958c2ecf20Sopenharmony_cistatic acpi_status acpi_register_spi_device(struct spi_controller *ctlr, 21968c2ecf20Sopenharmony_ci struct acpi_device *adev) 21978c2ecf20Sopenharmony_ci{ 21988c2ecf20Sopenharmony_ci acpi_handle parent_handle = NULL; 21998c2ecf20Sopenharmony_ci struct list_head resource_list; 22008c2ecf20Sopenharmony_ci struct acpi_spi_lookup lookup = {}; 22018c2ecf20Sopenharmony_ci struct spi_device *spi; 22028c2ecf20Sopenharmony_ci int ret; 22038c2ecf20Sopenharmony_ci 22048c2ecf20Sopenharmony_ci if (acpi_bus_get_status(adev) || !adev->status.present || 22058c2ecf20Sopenharmony_ci acpi_device_enumerated(adev)) 22068c2ecf20Sopenharmony_ci return AE_OK; 22078c2ecf20Sopenharmony_ci 22088c2ecf20Sopenharmony_ci lookup.ctlr = ctlr; 22098c2ecf20Sopenharmony_ci lookup.irq = -1; 22108c2ecf20Sopenharmony_ci 22118c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&resource_list); 22128c2ecf20Sopenharmony_ci ret = acpi_dev_get_resources(adev, &resource_list, 22138c2ecf20Sopenharmony_ci acpi_spi_add_resource, &lookup); 22148c2ecf20Sopenharmony_ci acpi_dev_free_resource_list(&resource_list); 22158c2ecf20Sopenharmony_ci 22168c2ecf20Sopenharmony_ci if (ret < 0) 22178c2ecf20Sopenharmony_ci /* found SPI in _CRS but it points to another controller */ 22188c2ecf20Sopenharmony_ci return AE_OK; 22198c2ecf20Sopenharmony_ci 22208c2ecf20Sopenharmony_ci if (!lookup.max_speed_hz && 22218c2ecf20Sopenharmony_ci !ACPI_FAILURE(acpi_get_parent(adev->handle, &parent_handle)) && 22228c2ecf20Sopenharmony_ci ACPI_HANDLE(ctlr->dev.parent) == parent_handle) { 22238c2ecf20Sopenharmony_ci /* Apple does not use _CRS but nested devices for SPI slaves */ 22248c2ecf20Sopenharmony_ci acpi_spi_parse_apple_properties(adev, &lookup); 22258c2ecf20Sopenharmony_ci } 22268c2ecf20Sopenharmony_ci 22278c2ecf20Sopenharmony_ci if (!lookup.max_speed_hz) 22288c2ecf20Sopenharmony_ci return AE_OK; 22298c2ecf20Sopenharmony_ci 22308c2ecf20Sopenharmony_ci spi = spi_alloc_device(ctlr); 22318c2ecf20Sopenharmony_ci if (!spi) { 22328c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "failed to allocate SPI device for %s\n", 22338c2ecf20Sopenharmony_ci dev_name(&adev->dev)); 22348c2ecf20Sopenharmony_ci return AE_NO_MEMORY; 22358c2ecf20Sopenharmony_ci } 22368c2ecf20Sopenharmony_ci 22378c2ecf20Sopenharmony_ci 22388c2ecf20Sopenharmony_ci ACPI_COMPANION_SET(&spi->dev, adev); 22398c2ecf20Sopenharmony_ci spi->max_speed_hz = lookup.max_speed_hz; 22408c2ecf20Sopenharmony_ci spi->mode |= lookup.mode; 22418c2ecf20Sopenharmony_ci spi->irq = lookup.irq; 22428c2ecf20Sopenharmony_ci spi->bits_per_word = lookup.bits_per_word; 22438c2ecf20Sopenharmony_ci spi->chip_select = lookup.chip_select; 22448c2ecf20Sopenharmony_ci 22458c2ecf20Sopenharmony_ci acpi_set_modalias(adev, acpi_device_hid(adev), spi->modalias, 22468c2ecf20Sopenharmony_ci sizeof(spi->modalias)); 22478c2ecf20Sopenharmony_ci 22488c2ecf20Sopenharmony_ci if (spi->irq < 0) 22498c2ecf20Sopenharmony_ci spi->irq = acpi_dev_gpio_irq_get(adev, 0); 22508c2ecf20Sopenharmony_ci 22518c2ecf20Sopenharmony_ci acpi_device_set_enumerated(adev); 22528c2ecf20Sopenharmony_ci 22538c2ecf20Sopenharmony_ci adev->power.flags.ignore_parent = true; 22548c2ecf20Sopenharmony_ci if (spi_add_device(spi)) { 22558c2ecf20Sopenharmony_ci adev->power.flags.ignore_parent = false; 22568c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "failed to add SPI device %s from ACPI\n", 22578c2ecf20Sopenharmony_ci dev_name(&adev->dev)); 22588c2ecf20Sopenharmony_ci spi_dev_put(spi); 22598c2ecf20Sopenharmony_ci } 22608c2ecf20Sopenharmony_ci 22618c2ecf20Sopenharmony_ci return AE_OK; 22628c2ecf20Sopenharmony_ci} 22638c2ecf20Sopenharmony_ci 22648c2ecf20Sopenharmony_cistatic acpi_status acpi_spi_add_device(acpi_handle handle, u32 level, 22658c2ecf20Sopenharmony_ci void *data, void **return_value) 22668c2ecf20Sopenharmony_ci{ 22678c2ecf20Sopenharmony_ci struct spi_controller *ctlr = data; 22688c2ecf20Sopenharmony_ci struct acpi_device *adev; 22698c2ecf20Sopenharmony_ci 22708c2ecf20Sopenharmony_ci if (acpi_bus_get_device(handle, &adev)) 22718c2ecf20Sopenharmony_ci return AE_OK; 22728c2ecf20Sopenharmony_ci 22738c2ecf20Sopenharmony_ci return acpi_register_spi_device(ctlr, adev); 22748c2ecf20Sopenharmony_ci} 22758c2ecf20Sopenharmony_ci 22768c2ecf20Sopenharmony_ci#define SPI_ACPI_ENUMERATE_MAX_DEPTH 32 22778c2ecf20Sopenharmony_ci 22788c2ecf20Sopenharmony_cistatic void acpi_register_spi_devices(struct spi_controller *ctlr) 22798c2ecf20Sopenharmony_ci{ 22808c2ecf20Sopenharmony_ci acpi_status status; 22818c2ecf20Sopenharmony_ci acpi_handle handle; 22828c2ecf20Sopenharmony_ci 22838c2ecf20Sopenharmony_ci handle = ACPI_HANDLE(ctlr->dev.parent); 22848c2ecf20Sopenharmony_ci if (!handle) 22858c2ecf20Sopenharmony_ci return; 22868c2ecf20Sopenharmony_ci 22878c2ecf20Sopenharmony_ci status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 22888c2ecf20Sopenharmony_ci SPI_ACPI_ENUMERATE_MAX_DEPTH, 22898c2ecf20Sopenharmony_ci acpi_spi_add_device, NULL, ctlr, NULL); 22908c2ecf20Sopenharmony_ci if (ACPI_FAILURE(status)) 22918c2ecf20Sopenharmony_ci dev_warn(&ctlr->dev, "failed to enumerate SPI slaves\n"); 22928c2ecf20Sopenharmony_ci} 22938c2ecf20Sopenharmony_ci#else 22948c2ecf20Sopenharmony_cistatic inline void acpi_register_spi_devices(struct spi_controller *ctlr) {} 22958c2ecf20Sopenharmony_ci#endif /* CONFIG_ACPI */ 22968c2ecf20Sopenharmony_ci 22978c2ecf20Sopenharmony_cistatic void spi_controller_release(struct device *dev) 22988c2ecf20Sopenharmony_ci{ 22998c2ecf20Sopenharmony_ci struct spi_controller *ctlr; 23008c2ecf20Sopenharmony_ci 23018c2ecf20Sopenharmony_ci ctlr = container_of(dev, struct spi_controller, dev); 23028c2ecf20Sopenharmony_ci kfree(ctlr); 23038c2ecf20Sopenharmony_ci} 23048c2ecf20Sopenharmony_ci 23058c2ecf20Sopenharmony_cistatic struct class spi_master_class = { 23068c2ecf20Sopenharmony_ci .name = "spi_master", 23078c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 23088c2ecf20Sopenharmony_ci .dev_release = spi_controller_release, 23098c2ecf20Sopenharmony_ci .dev_groups = spi_master_groups, 23108c2ecf20Sopenharmony_ci}; 23118c2ecf20Sopenharmony_ci 23128c2ecf20Sopenharmony_ci#ifdef CONFIG_SPI_SLAVE 23138c2ecf20Sopenharmony_ci/** 23148c2ecf20Sopenharmony_ci * spi_slave_abort - abort the ongoing transfer request on an SPI slave 23158c2ecf20Sopenharmony_ci * controller 23168c2ecf20Sopenharmony_ci * @spi: device used for the current transfer 23178c2ecf20Sopenharmony_ci */ 23188c2ecf20Sopenharmony_ciint spi_slave_abort(struct spi_device *spi) 23198c2ecf20Sopenharmony_ci{ 23208c2ecf20Sopenharmony_ci struct spi_controller *ctlr = spi->controller; 23218c2ecf20Sopenharmony_ci 23228c2ecf20Sopenharmony_ci if (spi_controller_is_slave(ctlr) && ctlr->slave_abort) 23238c2ecf20Sopenharmony_ci return ctlr->slave_abort(ctlr); 23248c2ecf20Sopenharmony_ci 23258c2ecf20Sopenharmony_ci return -ENOTSUPP; 23268c2ecf20Sopenharmony_ci} 23278c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_slave_abort); 23288c2ecf20Sopenharmony_ci 23298c2ecf20Sopenharmony_cistatic int match_true(struct device *dev, void *data) 23308c2ecf20Sopenharmony_ci{ 23318c2ecf20Sopenharmony_ci return 1; 23328c2ecf20Sopenharmony_ci} 23338c2ecf20Sopenharmony_ci 23348c2ecf20Sopenharmony_cistatic ssize_t slave_show(struct device *dev, struct device_attribute *attr, 23358c2ecf20Sopenharmony_ci char *buf) 23368c2ecf20Sopenharmony_ci{ 23378c2ecf20Sopenharmony_ci struct spi_controller *ctlr = container_of(dev, struct spi_controller, 23388c2ecf20Sopenharmony_ci dev); 23398c2ecf20Sopenharmony_ci struct device *child; 23408c2ecf20Sopenharmony_ci 23418c2ecf20Sopenharmony_ci child = device_find_child(&ctlr->dev, NULL, match_true); 23428c2ecf20Sopenharmony_ci return sprintf(buf, "%s\n", 23438c2ecf20Sopenharmony_ci child ? to_spi_device(child)->modalias : NULL); 23448c2ecf20Sopenharmony_ci} 23458c2ecf20Sopenharmony_ci 23468c2ecf20Sopenharmony_cistatic ssize_t slave_store(struct device *dev, struct device_attribute *attr, 23478c2ecf20Sopenharmony_ci const char *buf, size_t count) 23488c2ecf20Sopenharmony_ci{ 23498c2ecf20Sopenharmony_ci struct spi_controller *ctlr = container_of(dev, struct spi_controller, 23508c2ecf20Sopenharmony_ci dev); 23518c2ecf20Sopenharmony_ci struct spi_device *spi; 23528c2ecf20Sopenharmony_ci struct device *child; 23538c2ecf20Sopenharmony_ci char name[32]; 23548c2ecf20Sopenharmony_ci int rc; 23558c2ecf20Sopenharmony_ci 23568c2ecf20Sopenharmony_ci rc = sscanf(buf, "%31s", name); 23578c2ecf20Sopenharmony_ci if (rc != 1 || !name[0]) 23588c2ecf20Sopenharmony_ci return -EINVAL; 23598c2ecf20Sopenharmony_ci 23608c2ecf20Sopenharmony_ci child = device_find_child(&ctlr->dev, NULL, match_true); 23618c2ecf20Sopenharmony_ci if (child) { 23628c2ecf20Sopenharmony_ci /* Remove registered slave */ 23638c2ecf20Sopenharmony_ci device_unregister(child); 23648c2ecf20Sopenharmony_ci put_device(child); 23658c2ecf20Sopenharmony_ci } 23668c2ecf20Sopenharmony_ci 23678c2ecf20Sopenharmony_ci if (strcmp(name, "(null)")) { 23688c2ecf20Sopenharmony_ci /* Register new slave */ 23698c2ecf20Sopenharmony_ci spi = spi_alloc_device(ctlr); 23708c2ecf20Sopenharmony_ci if (!spi) 23718c2ecf20Sopenharmony_ci return -ENOMEM; 23728c2ecf20Sopenharmony_ci 23738c2ecf20Sopenharmony_ci strlcpy(spi->modalias, name, sizeof(spi->modalias)); 23748c2ecf20Sopenharmony_ci 23758c2ecf20Sopenharmony_ci rc = spi_add_device(spi); 23768c2ecf20Sopenharmony_ci if (rc) { 23778c2ecf20Sopenharmony_ci spi_dev_put(spi); 23788c2ecf20Sopenharmony_ci return rc; 23798c2ecf20Sopenharmony_ci } 23808c2ecf20Sopenharmony_ci } 23818c2ecf20Sopenharmony_ci 23828c2ecf20Sopenharmony_ci return count; 23838c2ecf20Sopenharmony_ci} 23848c2ecf20Sopenharmony_ci 23858c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RW(slave); 23868c2ecf20Sopenharmony_ci 23878c2ecf20Sopenharmony_cistatic struct attribute *spi_slave_attrs[] = { 23888c2ecf20Sopenharmony_ci &dev_attr_slave.attr, 23898c2ecf20Sopenharmony_ci NULL, 23908c2ecf20Sopenharmony_ci}; 23918c2ecf20Sopenharmony_ci 23928c2ecf20Sopenharmony_cistatic const struct attribute_group spi_slave_group = { 23938c2ecf20Sopenharmony_ci .attrs = spi_slave_attrs, 23948c2ecf20Sopenharmony_ci}; 23958c2ecf20Sopenharmony_ci 23968c2ecf20Sopenharmony_cistatic const struct attribute_group *spi_slave_groups[] = { 23978c2ecf20Sopenharmony_ci &spi_controller_statistics_group, 23988c2ecf20Sopenharmony_ci &spi_slave_group, 23998c2ecf20Sopenharmony_ci NULL, 24008c2ecf20Sopenharmony_ci}; 24018c2ecf20Sopenharmony_ci 24028c2ecf20Sopenharmony_cistatic struct class spi_slave_class = { 24038c2ecf20Sopenharmony_ci .name = "spi_slave", 24048c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 24058c2ecf20Sopenharmony_ci .dev_release = spi_controller_release, 24068c2ecf20Sopenharmony_ci .dev_groups = spi_slave_groups, 24078c2ecf20Sopenharmony_ci}; 24088c2ecf20Sopenharmony_ci#else 24098c2ecf20Sopenharmony_ciextern struct class spi_slave_class; /* dummy */ 24108c2ecf20Sopenharmony_ci#endif 24118c2ecf20Sopenharmony_ci 24128c2ecf20Sopenharmony_ci/** 24138c2ecf20Sopenharmony_ci * __spi_alloc_controller - allocate an SPI master or slave controller 24148c2ecf20Sopenharmony_ci * @dev: the controller, possibly using the platform_bus 24158c2ecf20Sopenharmony_ci * @size: how much zeroed driver-private data to allocate; the pointer to this 24168c2ecf20Sopenharmony_ci * memory is in the driver_data field of the returned device, accessible 24178c2ecf20Sopenharmony_ci * with spi_controller_get_devdata(); the memory is cacheline aligned; 24188c2ecf20Sopenharmony_ci * drivers granting DMA access to portions of their private data need to 24198c2ecf20Sopenharmony_ci * round up @size using ALIGN(size, dma_get_cache_alignment()). 24208c2ecf20Sopenharmony_ci * @slave: flag indicating whether to allocate an SPI master (false) or SPI 24218c2ecf20Sopenharmony_ci * slave (true) controller 24228c2ecf20Sopenharmony_ci * Context: can sleep 24238c2ecf20Sopenharmony_ci * 24248c2ecf20Sopenharmony_ci * This call is used only by SPI controller drivers, which are the 24258c2ecf20Sopenharmony_ci * only ones directly touching chip registers. It's how they allocate 24268c2ecf20Sopenharmony_ci * an spi_controller structure, prior to calling spi_register_controller(). 24278c2ecf20Sopenharmony_ci * 24288c2ecf20Sopenharmony_ci * This must be called from context that can sleep. 24298c2ecf20Sopenharmony_ci * 24308c2ecf20Sopenharmony_ci * The caller is responsible for assigning the bus number and initializing the 24318c2ecf20Sopenharmony_ci * controller's methods before calling spi_register_controller(); and (after 24328c2ecf20Sopenharmony_ci * errors adding the device) calling spi_controller_put() to prevent a memory 24338c2ecf20Sopenharmony_ci * leak. 24348c2ecf20Sopenharmony_ci * 24358c2ecf20Sopenharmony_ci * Return: the SPI controller structure on success, else NULL. 24368c2ecf20Sopenharmony_ci */ 24378c2ecf20Sopenharmony_cistruct spi_controller *__spi_alloc_controller(struct device *dev, 24388c2ecf20Sopenharmony_ci unsigned int size, bool slave) 24398c2ecf20Sopenharmony_ci{ 24408c2ecf20Sopenharmony_ci struct spi_controller *ctlr; 24418c2ecf20Sopenharmony_ci size_t ctlr_size = ALIGN(sizeof(*ctlr), dma_get_cache_alignment()); 24428c2ecf20Sopenharmony_ci 24438c2ecf20Sopenharmony_ci if (!dev) 24448c2ecf20Sopenharmony_ci return NULL; 24458c2ecf20Sopenharmony_ci 24468c2ecf20Sopenharmony_ci ctlr = kzalloc(size + ctlr_size, GFP_KERNEL); 24478c2ecf20Sopenharmony_ci if (!ctlr) 24488c2ecf20Sopenharmony_ci return NULL; 24498c2ecf20Sopenharmony_ci 24508c2ecf20Sopenharmony_ci device_initialize(&ctlr->dev); 24518c2ecf20Sopenharmony_ci ctlr->bus_num = -1; 24528c2ecf20Sopenharmony_ci ctlr->num_chipselect = 1; 24538c2ecf20Sopenharmony_ci ctlr->slave = slave; 24548c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_SPI_SLAVE) && slave) 24558c2ecf20Sopenharmony_ci ctlr->dev.class = &spi_slave_class; 24568c2ecf20Sopenharmony_ci else 24578c2ecf20Sopenharmony_ci ctlr->dev.class = &spi_master_class; 24588c2ecf20Sopenharmony_ci ctlr->dev.parent = dev; 24598c2ecf20Sopenharmony_ci pm_suspend_ignore_children(&ctlr->dev, true); 24608c2ecf20Sopenharmony_ci spi_controller_set_devdata(ctlr, (void *)ctlr + ctlr_size); 24618c2ecf20Sopenharmony_ci 24628c2ecf20Sopenharmony_ci return ctlr; 24638c2ecf20Sopenharmony_ci} 24648c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(__spi_alloc_controller); 24658c2ecf20Sopenharmony_ci 24668c2ecf20Sopenharmony_cistatic void devm_spi_release_controller(struct device *dev, void *ctlr) 24678c2ecf20Sopenharmony_ci{ 24688c2ecf20Sopenharmony_ci spi_controller_put(*(struct spi_controller **)ctlr); 24698c2ecf20Sopenharmony_ci} 24708c2ecf20Sopenharmony_ci 24718c2ecf20Sopenharmony_ci/** 24728c2ecf20Sopenharmony_ci * __devm_spi_alloc_controller - resource-managed __spi_alloc_controller() 24738c2ecf20Sopenharmony_ci * @dev: physical device of SPI controller 24748c2ecf20Sopenharmony_ci * @size: how much zeroed driver-private data to allocate 24758c2ecf20Sopenharmony_ci * @slave: whether to allocate an SPI master (false) or SPI slave (true) 24768c2ecf20Sopenharmony_ci * Context: can sleep 24778c2ecf20Sopenharmony_ci * 24788c2ecf20Sopenharmony_ci * Allocate an SPI controller and automatically release a reference on it 24798c2ecf20Sopenharmony_ci * when @dev is unbound from its driver. Drivers are thus relieved from 24808c2ecf20Sopenharmony_ci * having to call spi_controller_put(). 24818c2ecf20Sopenharmony_ci * 24828c2ecf20Sopenharmony_ci * The arguments to this function are identical to __spi_alloc_controller(). 24838c2ecf20Sopenharmony_ci * 24848c2ecf20Sopenharmony_ci * Return: the SPI controller structure on success, else NULL. 24858c2ecf20Sopenharmony_ci */ 24868c2ecf20Sopenharmony_cistruct spi_controller *__devm_spi_alloc_controller(struct device *dev, 24878c2ecf20Sopenharmony_ci unsigned int size, 24888c2ecf20Sopenharmony_ci bool slave) 24898c2ecf20Sopenharmony_ci{ 24908c2ecf20Sopenharmony_ci struct spi_controller **ptr, *ctlr; 24918c2ecf20Sopenharmony_ci 24928c2ecf20Sopenharmony_ci ptr = devres_alloc(devm_spi_release_controller, sizeof(*ptr), 24938c2ecf20Sopenharmony_ci GFP_KERNEL); 24948c2ecf20Sopenharmony_ci if (!ptr) 24958c2ecf20Sopenharmony_ci return NULL; 24968c2ecf20Sopenharmony_ci 24978c2ecf20Sopenharmony_ci ctlr = __spi_alloc_controller(dev, size, slave); 24988c2ecf20Sopenharmony_ci if (ctlr) { 24998c2ecf20Sopenharmony_ci ctlr->devm_allocated = true; 25008c2ecf20Sopenharmony_ci *ptr = ctlr; 25018c2ecf20Sopenharmony_ci devres_add(dev, ptr); 25028c2ecf20Sopenharmony_ci } else { 25038c2ecf20Sopenharmony_ci devres_free(ptr); 25048c2ecf20Sopenharmony_ci } 25058c2ecf20Sopenharmony_ci 25068c2ecf20Sopenharmony_ci return ctlr; 25078c2ecf20Sopenharmony_ci} 25088c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(__devm_spi_alloc_controller); 25098c2ecf20Sopenharmony_ci 25108c2ecf20Sopenharmony_ci#ifdef CONFIG_OF 25118c2ecf20Sopenharmony_cistatic int of_spi_get_gpio_numbers(struct spi_controller *ctlr) 25128c2ecf20Sopenharmony_ci{ 25138c2ecf20Sopenharmony_ci int nb, i, *cs; 25148c2ecf20Sopenharmony_ci struct device_node *np = ctlr->dev.of_node; 25158c2ecf20Sopenharmony_ci 25168c2ecf20Sopenharmony_ci if (!np) 25178c2ecf20Sopenharmony_ci return 0; 25188c2ecf20Sopenharmony_ci 25198c2ecf20Sopenharmony_ci nb = of_gpio_named_count(np, "cs-gpios"); 25208c2ecf20Sopenharmony_ci ctlr->num_chipselect = max_t(int, nb, ctlr->num_chipselect); 25218c2ecf20Sopenharmony_ci 25228c2ecf20Sopenharmony_ci /* Return error only for an incorrectly formed cs-gpios property */ 25238c2ecf20Sopenharmony_ci if (nb == 0 || nb == -ENOENT) 25248c2ecf20Sopenharmony_ci return 0; 25258c2ecf20Sopenharmony_ci else if (nb < 0) 25268c2ecf20Sopenharmony_ci return nb; 25278c2ecf20Sopenharmony_ci 25288c2ecf20Sopenharmony_ci cs = devm_kcalloc(&ctlr->dev, ctlr->num_chipselect, sizeof(int), 25298c2ecf20Sopenharmony_ci GFP_KERNEL); 25308c2ecf20Sopenharmony_ci ctlr->cs_gpios = cs; 25318c2ecf20Sopenharmony_ci 25328c2ecf20Sopenharmony_ci if (!ctlr->cs_gpios) 25338c2ecf20Sopenharmony_ci return -ENOMEM; 25348c2ecf20Sopenharmony_ci 25358c2ecf20Sopenharmony_ci for (i = 0; i < ctlr->num_chipselect; i++) 25368c2ecf20Sopenharmony_ci cs[i] = -ENOENT; 25378c2ecf20Sopenharmony_ci 25388c2ecf20Sopenharmony_ci for (i = 0; i < nb; i++) 25398c2ecf20Sopenharmony_ci cs[i] = of_get_named_gpio(np, "cs-gpios", i); 25408c2ecf20Sopenharmony_ci 25418c2ecf20Sopenharmony_ci return 0; 25428c2ecf20Sopenharmony_ci} 25438c2ecf20Sopenharmony_ci#else 25448c2ecf20Sopenharmony_cistatic int of_spi_get_gpio_numbers(struct spi_controller *ctlr) 25458c2ecf20Sopenharmony_ci{ 25468c2ecf20Sopenharmony_ci return 0; 25478c2ecf20Sopenharmony_ci} 25488c2ecf20Sopenharmony_ci#endif 25498c2ecf20Sopenharmony_ci 25508c2ecf20Sopenharmony_ci/** 25518c2ecf20Sopenharmony_ci * spi_get_gpio_descs() - grab chip select GPIOs for the master 25528c2ecf20Sopenharmony_ci * @ctlr: The SPI master to grab GPIO descriptors for 25538c2ecf20Sopenharmony_ci */ 25548c2ecf20Sopenharmony_cistatic int spi_get_gpio_descs(struct spi_controller *ctlr) 25558c2ecf20Sopenharmony_ci{ 25568c2ecf20Sopenharmony_ci int nb, i; 25578c2ecf20Sopenharmony_ci struct gpio_desc **cs; 25588c2ecf20Sopenharmony_ci struct device *dev = &ctlr->dev; 25598c2ecf20Sopenharmony_ci unsigned long native_cs_mask = 0; 25608c2ecf20Sopenharmony_ci unsigned int num_cs_gpios = 0; 25618c2ecf20Sopenharmony_ci 25628c2ecf20Sopenharmony_ci nb = gpiod_count(dev, "cs"); 25638c2ecf20Sopenharmony_ci ctlr->num_chipselect = max_t(int, nb, ctlr->num_chipselect); 25648c2ecf20Sopenharmony_ci 25658c2ecf20Sopenharmony_ci /* No GPIOs at all is fine, else return the error */ 25668c2ecf20Sopenharmony_ci if (nb == 0 || nb == -ENOENT) 25678c2ecf20Sopenharmony_ci return 0; 25688c2ecf20Sopenharmony_ci else if (nb < 0) 25698c2ecf20Sopenharmony_ci return nb; 25708c2ecf20Sopenharmony_ci 25718c2ecf20Sopenharmony_ci cs = devm_kcalloc(dev, ctlr->num_chipselect, sizeof(*cs), 25728c2ecf20Sopenharmony_ci GFP_KERNEL); 25738c2ecf20Sopenharmony_ci if (!cs) 25748c2ecf20Sopenharmony_ci return -ENOMEM; 25758c2ecf20Sopenharmony_ci ctlr->cs_gpiods = cs; 25768c2ecf20Sopenharmony_ci 25778c2ecf20Sopenharmony_ci for (i = 0; i < nb; i++) { 25788c2ecf20Sopenharmony_ci /* 25798c2ecf20Sopenharmony_ci * Most chipselects are active low, the inverted 25808c2ecf20Sopenharmony_ci * semantics are handled by special quirks in gpiolib, 25818c2ecf20Sopenharmony_ci * so initializing them GPIOD_OUT_LOW here means 25828c2ecf20Sopenharmony_ci * "unasserted", in most cases this will drive the physical 25838c2ecf20Sopenharmony_ci * line high. 25848c2ecf20Sopenharmony_ci */ 25858c2ecf20Sopenharmony_ci cs[i] = devm_gpiod_get_index_optional(dev, "cs", i, 25868c2ecf20Sopenharmony_ci GPIOD_OUT_LOW); 25878c2ecf20Sopenharmony_ci if (IS_ERR(cs[i])) 25888c2ecf20Sopenharmony_ci return PTR_ERR(cs[i]); 25898c2ecf20Sopenharmony_ci 25908c2ecf20Sopenharmony_ci if (cs[i]) { 25918c2ecf20Sopenharmony_ci /* 25928c2ecf20Sopenharmony_ci * If we find a CS GPIO, name it after the device and 25938c2ecf20Sopenharmony_ci * chip select line. 25948c2ecf20Sopenharmony_ci */ 25958c2ecf20Sopenharmony_ci char *gpioname; 25968c2ecf20Sopenharmony_ci 25978c2ecf20Sopenharmony_ci gpioname = devm_kasprintf(dev, GFP_KERNEL, "%s CS%d", 25988c2ecf20Sopenharmony_ci dev_name(dev), i); 25998c2ecf20Sopenharmony_ci if (!gpioname) 26008c2ecf20Sopenharmony_ci return -ENOMEM; 26018c2ecf20Sopenharmony_ci gpiod_set_consumer_name(cs[i], gpioname); 26028c2ecf20Sopenharmony_ci num_cs_gpios++; 26038c2ecf20Sopenharmony_ci continue; 26048c2ecf20Sopenharmony_ci } 26058c2ecf20Sopenharmony_ci 26068c2ecf20Sopenharmony_ci if (ctlr->max_native_cs && i >= ctlr->max_native_cs) { 26078c2ecf20Sopenharmony_ci dev_err(dev, "Invalid native chip select %d\n", i); 26088c2ecf20Sopenharmony_ci return -EINVAL; 26098c2ecf20Sopenharmony_ci } 26108c2ecf20Sopenharmony_ci native_cs_mask |= BIT(i); 26118c2ecf20Sopenharmony_ci } 26128c2ecf20Sopenharmony_ci 26138c2ecf20Sopenharmony_ci ctlr->unused_native_cs = ffs(~native_cs_mask) - 1; 26148c2ecf20Sopenharmony_ci 26158c2ecf20Sopenharmony_ci if ((ctlr->flags & SPI_MASTER_GPIO_SS) && num_cs_gpios && 26168c2ecf20Sopenharmony_ci ctlr->max_native_cs && ctlr->unused_native_cs >= ctlr->max_native_cs) { 26178c2ecf20Sopenharmony_ci dev_err(dev, "No unused native chip select available\n"); 26188c2ecf20Sopenharmony_ci return -EINVAL; 26198c2ecf20Sopenharmony_ci } 26208c2ecf20Sopenharmony_ci 26218c2ecf20Sopenharmony_ci return 0; 26228c2ecf20Sopenharmony_ci} 26238c2ecf20Sopenharmony_ci 26248c2ecf20Sopenharmony_cistatic int spi_controller_check_ops(struct spi_controller *ctlr) 26258c2ecf20Sopenharmony_ci{ 26268c2ecf20Sopenharmony_ci /* 26278c2ecf20Sopenharmony_ci * The controller may implement only the high-level SPI-memory like 26288c2ecf20Sopenharmony_ci * operations if it does not support regular SPI transfers, and this is 26298c2ecf20Sopenharmony_ci * valid use case. 26308c2ecf20Sopenharmony_ci * If ->mem_ops is NULL, we request that at least one of the 26318c2ecf20Sopenharmony_ci * ->transfer_xxx() method be implemented. 26328c2ecf20Sopenharmony_ci */ 26338c2ecf20Sopenharmony_ci if (ctlr->mem_ops) { 26348c2ecf20Sopenharmony_ci if (!ctlr->mem_ops->exec_op) 26358c2ecf20Sopenharmony_ci return -EINVAL; 26368c2ecf20Sopenharmony_ci } else if (!ctlr->transfer && !ctlr->transfer_one && 26378c2ecf20Sopenharmony_ci !ctlr->transfer_one_message) { 26388c2ecf20Sopenharmony_ci return -EINVAL; 26398c2ecf20Sopenharmony_ci } 26408c2ecf20Sopenharmony_ci 26418c2ecf20Sopenharmony_ci return 0; 26428c2ecf20Sopenharmony_ci} 26438c2ecf20Sopenharmony_ci 26448c2ecf20Sopenharmony_ci/** 26458c2ecf20Sopenharmony_ci * spi_register_controller - register SPI master or slave controller 26468c2ecf20Sopenharmony_ci * @ctlr: initialized master, originally from spi_alloc_master() or 26478c2ecf20Sopenharmony_ci * spi_alloc_slave() 26488c2ecf20Sopenharmony_ci * Context: can sleep 26498c2ecf20Sopenharmony_ci * 26508c2ecf20Sopenharmony_ci * SPI controllers connect to their drivers using some non-SPI bus, 26518c2ecf20Sopenharmony_ci * such as the platform bus. The final stage of probe() in that code 26528c2ecf20Sopenharmony_ci * includes calling spi_register_controller() to hook up to this SPI bus glue. 26538c2ecf20Sopenharmony_ci * 26548c2ecf20Sopenharmony_ci * SPI controllers use board specific (often SOC specific) bus numbers, 26558c2ecf20Sopenharmony_ci * and board-specific addressing for SPI devices combines those numbers 26568c2ecf20Sopenharmony_ci * with chip select numbers. Since SPI does not directly support dynamic 26578c2ecf20Sopenharmony_ci * device identification, boards need configuration tables telling which 26588c2ecf20Sopenharmony_ci * chip is at which address. 26598c2ecf20Sopenharmony_ci * 26608c2ecf20Sopenharmony_ci * This must be called from context that can sleep. It returns zero on 26618c2ecf20Sopenharmony_ci * success, else a negative error code (dropping the controller's refcount). 26628c2ecf20Sopenharmony_ci * After a successful return, the caller is responsible for calling 26638c2ecf20Sopenharmony_ci * spi_unregister_controller(). 26648c2ecf20Sopenharmony_ci * 26658c2ecf20Sopenharmony_ci * Return: zero on success, else a negative error code. 26668c2ecf20Sopenharmony_ci */ 26678c2ecf20Sopenharmony_ciint spi_register_controller(struct spi_controller *ctlr) 26688c2ecf20Sopenharmony_ci{ 26698c2ecf20Sopenharmony_ci struct device *dev = ctlr->dev.parent; 26708c2ecf20Sopenharmony_ci struct boardinfo *bi; 26718c2ecf20Sopenharmony_ci int status; 26728c2ecf20Sopenharmony_ci int id, first_dynamic; 26738c2ecf20Sopenharmony_ci 26748c2ecf20Sopenharmony_ci if (!dev) 26758c2ecf20Sopenharmony_ci return -ENODEV; 26768c2ecf20Sopenharmony_ci 26778c2ecf20Sopenharmony_ci /* 26788c2ecf20Sopenharmony_ci * Make sure all necessary hooks are implemented before registering 26798c2ecf20Sopenharmony_ci * the SPI controller. 26808c2ecf20Sopenharmony_ci */ 26818c2ecf20Sopenharmony_ci status = spi_controller_check_ops(ctlr); 26828c2ecf20Sopenharmony_ci if (status) 26838c2ecf20Sopenharmony_ci return status; 26848c2ecf20Sopenharmony_ci 26858c2ecf20Sopenharmony_ci if (ctlr->bus_num >= 0) { 26868c2ecf20Sopenharmony_ci /* devices with a fixed bus num must check-in with the num */ 26878c2ecf20Sopenharmony_ci mutex_lock(&board_lock); 26888c2ecf20Sopenharmony_ci id = idr_alloc(&spi_master_idr, ctlr, ctlr->bus_num, 26898c2ecf20Sopenharmony_ci ctlr->bus_num + 1, GFP_KERNEL); 26908c2ecf20Sopenharmony_ci mutex_unlock(&board_lock); 26918c2ecf20Sopenharmony_ci if (WARN(id < 0, "couldn't get idr")) 26928c2ecf20Sopenharmony_ci return id == -ENOSPC ? -EBUSY : id; 26938c2ecf20Sopenharmony_ci ctlr->bus_num = id; 26948c2ecf20Sopenharmony_ci } else if (ctlr->dev.of_node) { 26958c2ecf20Sopenharmony_ci /* allocate dynamic bus number using Linux idr */ 26968c2ecf20Sopenharmony_ci id = of_alias_get_id(ctlr->dev.of_node, "spi"); 26978c2ecf20Sopenharmony_ci if (id >= 0) { 26988c2ecf20Sopenharmony_ci ctlr->bus_num = id; 26998c2ecf20Sopenharmony_ci mutex_lock(&board_lock); 27008c2ecf20Sopenharmony_ci id = idr_alloc(&spi_master_idr, ctlr, ctlr->bus_num, 27018c2ecf20Sopenharmony_ci ctlr->bus_num + 1, GFP_KERNEL); 27028c2ecf20Sopenharmony_ci mutex_unlock(&board_lock); 27038c2ecf20Sopenharmony_ci if (WARN(id < 0, "couldn't get idr")) 27048c2ecf20Sopenharmony_ci return id == -ENOSPC ? -EBUSY : id; 27058c2ecf20Sopenharmony_ci } 27068c2ecf20Sopenharmony_ci } 27078c2ecf20Sopenharmony_ci if (ctlr->bus_num < 0) { 27088c2ecf20Sopenharmony_ci first_dynamic = of_alias_get_highest_id("spi"); 27098c2ecf20Sopenharmony_ci if (first_dynamic < 0) 27108c2ecf20Sopenharmony_ci first_dynamic = 0; 27118c2ecf20Sopenharmony_ci else 27128c2ecf20Sopenharmony_ci first_dynamic++; 27138c2ecf20Sopenharmony_ci 27148c2ecf20Sopenharmony_ci mutex_lock(&board_lock); 27158c2ecf20Sopenharmony_ci id = idr_alloc(&spi_master_idr, ctlr, first_dynamic, 27168c2ecf20Sopenharmony_ci 0, GFP_KERNEL); 27178c2ecf20Sopenharmony_ci mutex_unlock(&board_lock); 27188c2ecf20Sopenharmony_ci if (WARN(id < 0, "couldn't get idr")) 27198c2ecf20Sopenharmony_ci return id; 27208c2ecf20Sopenharmony_ci ctlr->bus_num = id; 27218c2ecf20Sopenharmony_ci } 27228c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&ctlr->queue); 27238c2ecf20Sopenharmony_ci spin_lock_init(&ctlr->queue_lock); 27248c2ecf20Sopenharmony_ci spin_lock_init(&ctlr->bus_lock_spinlock); 27258c2ecf20Sopenharmony_ci mutex_init(&ctlr->bus_lock_mutex); 27268c2ecf20Sopenharmony_ci mutex_init(&ctlr->io_mutex); 27278c2ecf20Sopenharmony_ci mutex_init(&ctlr->add_lock); 27288c2ecf20Sopenharmony_ci ctlr->bus_lock_flag = 0; 27298c2ecf20Sopenharmony_ci init_completion(&ctlr->xfer_completion); 27308c2ecf20Sopenharmony_ci if (!ctlr->max_dma_len) 27318c2ecf20Sopenharmony_ci ctlr->max_dma_len = INT_MAX; 27328c2ecf20Sopenharmony_ci 27338c2ecf20Sopenharmony_ci /* register the device, then userspace will see it. 27348c2ecf20Sopenharmony_ci * registration fails if the bus ID is in use. 27358c2ecf20Sopenharmony_ci */ 27368c2ecf20Sopenharmony_ci dev_set_name(&ctlr->dev, "spi%u", ctlr->bus_num); 27378c2ecf20Sopenharmony_ci 27388c2ecf20Sopenharmony_ci if (!spi_controller_is_slave(ctlr)) { 27398c2ecf20Sopenharmony_ci if (ctlr->use_gpio_descriptors) { 27408c2ecf20Sopenharmony_ci status = spi_get_gpio_descs(ctlr); 27418c2ecf20Sopenharmony_ci if (status) 27428c2ecf20Sopenharmony_ci goto free_bus_id; 27438c2ecf20Sopenharmony_ci /* 27448c2ecf20Sopenharmony_ci * A controller using GPIO descriptors always 27458c2ecf20Sopenharmony_ci * supports SPI_CS_HIGH if need be. 27468c2ecf20Sopenharmony_ci */ 27478c2ecf20Sopenharmony_ci ctlr->mode_bits |= SPI_CS_HIGH; 27488c2ecf20Sopenharmony_ci } else { 27498c2ecf20Sopenharmony_ci /* Legacy code path for GPIOs from DT */ 27508c2ecf20Sopenharmony_ci status = of_spi_get_gpio_numbers(ctlr); 27518c2ecf20Sopenharmony_ci if (status) 27528c2ecf20Sopenharmony_ci goto free_bus_id; 27538c2ecf20Sopenharmony_ci } 27548c2ecf20Sopenharmony_ci } 27558c2ecf20Sopenharmony_ci 27568c2ecf20Sopenharmony_ci /* 27578c2ecf20Sopenharmony_ci * Even if it's just one always-selected device, there must 27588c2ecf20Sopenharmony_ci * be at least one chipselect. 27598c2ecf20Sopenharmony_ci */ 27608c2ecf20Sopenharmony_ci if (!ctlr->num_chipselect) { 27618c2ecf20Sopenharmony_ci status = -EINVAL; 27628c2ecf20Sopenharmony_ci goto free_bus_id; 27638c2ecf20Sopenharmony_ci } 27648c2ecf20Sopenharmony_ci 27658c2ecf20Sopenharmony_ci status = device_add(&ctlr->dev); 27668c2ecf20Sopenharmony_ci if (status < 0) 27678c2ecf20Sopenharmony_ci goto free_bus_id; 27688c2ecf20Sopenharmony_ci dev_dbg(dev, "registered %s %s\n", 27698c2ecf20Sopenharmony_ci spi_controller_is_slave(ctlr) ? "slave" : "master", 27708c2ecf20Sopenharmony_ci dev_name(&ctlr->dev)); 27718c2ecf20Sopenharmony_ci 27728c2ecf20Sopenharmony_ci /* 27738c2ecf20Sopenharmony_ci * If we're using a queued driver, start the queue. Note that we don't 27748c2ecf20Sopenharmony_ci * need the queueing logic if the driver is only supporting high-level 27758c2ecf20Sopenharmony_ci * memory operations. 27768c2ecf20Sopenharmony_ci */ 27778c2ecf20Sopenharmony_ci if (ctlr->transfer) { 27788c2ecf20Sopenharmony_ci dev_info(dev, "controller is unqueued, this is deprecated\n"); 27798c2ecf20Sopenharmony_ci } else if (ctlr->transfer_one || ctlr->transfer_one_message) { 27808c2ecf20Sopenharmony_ci status = spi_controller_initialize_queue(ctlr); 27818c2ecf20Sopenharmony_ci if (status) { 27828c2ecf20Sopenharmony_ci device_del(&ctlr->dev); 27838c2ecf20Sopenharmony_ci goto free_bus_id; 27848c2ecf20Sopenharmony_ci } 27858c2ecf20Sopenharmony_ci } 27868c2ecf20Sopenharmony_ci /* add statistics */ 27878c2ecf20Sopenharmony_ci spin_lock_init(&ctlr->statistics.lock); 27888c2ecf20Sopenharmony_ci 27898c2ecf20Sopenharmony_ci mutex_lock(&board_lock); 27908c2ecf20Sopenharmony_ci list_add_tail(&ctlr->list, &spi_controller_list); 27918c2ecf20Sopenharmony_ci list_for_each_entry(bi, &board_list, list) 27928c2ecf20Sopenharmony_ci spi_match_controller_to_boardinfo(ctlr, &bi->board_info); 27938c2ecf20Sopenharmony_ci mutex_unlock(&board_lock); 27948c2ecf20Sopenharmony_ci 27958c2ecf20Sopenharmony_ci /* Register devices from the device tree and ACPI */ 27968c2ecf20Sopenharmony_ci of_register_spi_devices(ctlr); 27978c2ecf20Sopenharmony_ci acpi_register_spi_devices(ctlr); 27988c2ecf20Sopenharmony_ci return status; 27998c2ecf20Sopenharmony_ci 28008c2ecf20Sopenharmony_cifree_bus_id: 28018c2ecf20Sopenharmony_ci mutex_lock(&board_lock); 28028c2ecf20Sopenharmony_ci idr_remove(&spi_master_idr, ctlr->bus_num); 28038c2ecf20Sopenharmony_ci mutex_unlock(&board_lock); 28048c2ecf20Sopenharmony_ci return status; 28058c2ecf20Sopenharmony_ci} 28068c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_register_controller); 28078c2ecf20Sopenharmony_ci 28088c2ecf20Sopenharmony_cistatic void devm_spi_unregister(struct device *dev, void *res) 28098c2ecf20Sopenharmony_ci{ 28108c2ecf20Sopenharmony_ci spi_unregister_controller(*(struct spi_controller **)res); 28118c2ecf20Sopenharmony_ci} 28128c2ecf20Sopenharmony_ci 28138c2ecf20Sopenharmony_ci/** 28148c2ecf20Sopenharmony_ci * devm_spi_register_controller - register managed SPI master or slave 28158c2ecf20Sopenharmony_ci * controller 28168c2ecf20Sopenharmony_ci * @dev: device managing SPI controller 28178c2ecf20Sopenharmony_ci * @ctlr: initialized controller, originally from spi_alloc_master() or 28188c2ecf20Sopenharmony_ci * spi_alloc_slave() 28198c2ecf20Sopenharmony_ci * Context: can sleep 28208c2ecf20Sopenharmony_ci * 28218c2ecf20Sopenharmony_ci * Register a SPI device as with spi_register_controller() which will 28228c2ecf20Sopenharmony_ci * automatically be unregistered and freed. 28238c2ecf20Sopenharmony_ci * 28248c2ecf20Sopenharmony_ci * Return: zero on success, else a negative error code. 28258c2ecf20Sopenharmony_ci */ 28268c2ecf20Sopenharmony_ciint devm_spi_register_controller(struct device *dev, 28278c2ecf20Sopenharmony_ci struct spi_controller *ctlr) 28288c2ecf20Sopenharmony_ci{ 28298c2ecf20Sopenharmony_ci struct spi_controller **ptr; 28308c2ecf20Sopenharmony_ci int ret; 28318c2ecf20Sopenharmony_ci 28328c2ecf20Sopenharmony_ci ptr = devres_alloc(devm_spi_unregister, sizeof(*ptr), GFP_KERNEL); 28338c2ecf20Sopenharmony_ci if (!ptr) 28348c2ecf20Sopenharmony_ci return -ENOMEM; 28358c2ecf20Sopenharmony_ci 28368c2ecf20Sopenharmony_ci ret = spi_register_controller(ctlr); 28378c2ecf20Sopenharmony_ci if (!ret) { 28388c2ecf20Sopenharmony_ci *ptr = ctlr; 28398c2ecf20Sopenharmony_ci devres_add(dev, ptr); 28408c2ecf20Sopenharmony_ci } else { 28418c2ecf20Sopenharmony_ci devres_free(ptr); 28428c2ecf20Sopenharmony_ci } 28438c2ecf20Sopenharmony_ci 28448c2ecf20Sopenharmony_ci return ret; 28458c2ecf20Sopenharmony_ci} 28468c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(devm_spi_register_controller); 28478c2ecf20Sopenharmony_ci 28488c2ecf20Sopenharmony_cistatic int __unregister(struct device *dev, void *null) 28498c2ecf20Sopenharmony_ci{ 28508c2ecf20Sopenharmony_ci spi_unregister_device(to_spi_device(dev)); 28518c2ecf20Sopenharmony_ci return 0; 28528c2ecf20Sopenharmony_ci} 28538c2ecf20Sopenharmony_ci 28548c2ecf20Sopenharmony_ci/** 28558c2ecf20Sopenharmony_ci * spi_unregister_controller - unregister SPI master or slave controller 28568c2ecf20Sopenharmony_ci * @ctlr: the controller being unregistered 28578c2ecf20Sopenharmony_ci * Context: can sleep 28588c2ecf20Sopenharmony_ci * 28598c2ecf20Sopenharmony_ci * This call is used only by SPI controller drivers, which are the 28608c2ecf20Sopenharmony_ci * only ones directly touching chip registers. 28618c2ecf20Sopenharmony_ci * 28628c2ecf20Sopenharmony_ci * This must be called from context that can sleep. 28638c2ecf20Sopenharmony_ci * 28648c2ecf20Sopenharmony_ci * Note that this function also drops a reference to the controller. 28658c2ecf20Sopenharmony_ci */ 28668c2ecf20Sopenharmony_civoid spi_unregister_controller(struct spi_controller *ctlr) 28678c2ecf20Sopenharmony_ci{ 28688c2ecf20Sopenharmony_ci struct spi_controller *found; 28698c2ecf20Sopenharmony_ci int id = ctlr->bus_num; 28708c2ecf20Sopenharmony_ci 28718c2ecf20Sopenharmony_ci /* Prevent addition of new devices, unregister existing ones */ 28728c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_SPI_DYNAMIC)) 28738c2ecf20Sopenharmony_ci mutex_lock(&ctlr->add_lock); 28748c2ecf20Sopenharmony_ci 28758c2ecf20Sopenharmony_ci device_for_each_child(&ctlr->dev, NULL, __unregister); 28768c2ecf20Sopenharmony_ci 28778c2ecf20Sopenharmony_ci /* First make sure that this controller was ever added */ 28788c2ecf20Sopenharmony_ci mutex_lock(&board_lock); 28798c2ecf20Sopenharmony_ci found = idr_find(&spi_master_idr, id); 28808c2ecf20Sopenharmony_ci mutex_unlock(&board_lock); 28818c2ecf20Sopenharmony_ci if (ctlr->queued) { 28828c2ecf20Sopenharmony_ci if (spi_destroy_queue(ctlr)) 28838c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "queue remove failed\n"); 28848c2ecf20Sopenharmony_ci } 28858c2ecf20Sopenharmony_ci mutex_lock(&board_lock); 28868c2ecf20Sopenharmony_ci list_del(&ctlr->list); 28878c2ecf20Sopenharmony_ci mutex_unlock(&board_lock); 28888c2ecf20Sopenharmony_ci 28898c2ecf20Sopenharmony_ci device_del(&ctlr->dev); 28908c2ecf20Sopenharmony_ci 28918c2ecf20Sopenharmony_ci /* Release the last reference on the controller if its driver 28928c2ecf20Sopenharmony_ci * has not yet been converted to devm_spi_alloc_master/slave(). 28938c2ecf20Sopenharmony_ci */ 28948c2ecf20Sopenharmony_ci if (!ctlr->devm_allocated) 28958c2ecf20Sopenharmony_ci put_device(&ctlr->dev); 28968c2ecf20Sopenharmony_ci 28978c2ecf20Sopenharmony_ci /* free bus id */ 28988c2ecf20Sopenharmony_ci mutex_lock(&board_lock); 28998c2ecf20Sopenharmony_ci if (found == ctlr) 29008c2ecf20Sopenharmony_ci idr_remove(&spi_master_idr, id); 29018c2ecf20Sopenharmony_ci mutex_unlock(&board_lock); 29028c2ecf20Sopenharmony_ci 29038c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_SPI_DYNAMIC)) 29048c2ecf20Sopenharmony_ci mutex_unlock(&ctlr->add_lock); 29058c2ecf20Sopenharmony_ci} 29068c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_unregister_controller); 29078c2ecf20Sopenharmony_ci 29088c2ecf20Sopenharmony_ciint spi_controller_suspend(struct spi_controller *ctlr) 29098c2ecf20Sopenharmony_ci{ 29108c2ecf20Sopenharmony_ci int ret; 29118c2ecf20Sopenharmony_ci 29128c2ecf20Sopenharmony_ci /* Basically no-ops for non-queued controllers */ 29138c2ecf20Sopenharmony_ci if (!ctlr->queued) 29148c2ecf20Sopenharmony_ci return 0; 29158c2ecf20Sopenharmony_ci 29168c2ecf20Sopenharmony_ci ret = spi_stop_queue(ctlr); 29178c2ecf20Sopenharmony_ci if (ret) 29188c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "queue stop failed\n"); 29198c2ecf20Sopenharmony_ci 29208c2ecf20Sopenharmony_ci return ret; 29218c2ecf20Sopenharmony_ci} 29228c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_controller_suspend); 29238c2ecf20Sopenharmony_ci 29248c2ecf20Sopenharmony_ciint spi_controller_resume(struct spi_controller *ctlr) 29258c2ecf20Sopenharmony_ci{ 29268c2ecf20Sopenharmony_ci int ret; 29278c2ecf20Sopenharmony_ci 29288c2ecf20Sopenharmony_ci if (!ctlr->queued) 29298c2ecf20Sopenharmony_ci return 0; 29308c2ecf20Sopenharmony_ci 29318c2ecf20Sopenharmony_ci ret = spi_start_queue(ctlr); 29328c2ecf20Sopenharmony_ci if (ret) 29338c2ecf20Sopenharmony_ci dev_err(&ctlr->dev, "queue restart failed\n"); 29348c2ecf20Sopenharmony_ci 29358c2ecf20Sopenharmony_ci return ret; 29368c2ecf20Sopenharmony_ci} 29378c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_controller_resume); 29388c2ecf20Sopenharmony_ci 29398c2ecf20Sopenharmony_cistatic int __spi_controller_match(struct device *dev, const void *data) 29408c2ecf20Sopenharmony_ci{ 29418c2ecf20Sopenharmony_ci struct spi_controller *ctlr; 29428c2ecf20Sopenharmony_ci const u16 *bus_num = data; 29438c2ecf20Sopenharmony_ci 29448c2ecf20Sopenharmony_ci ctlr = container_of(dev, struct spi_controller, dev); 29458c2ecf20Sopenharmony_ci return ctlr->bus_num == *bus_num; 29468c2ecf20Sopenharmony_ci} 29478c2ecf20Sopenharmony_ci 29488c2ecf20Sopenharmony_ci/** 29498c2ecf20Sopenharmony_ci * spi_busnum_to_master - look up master associated with bus_num 29508c2ecf20Sopenharmony_ci * @bus_num: the master's bus number 29518c2ecf20Sopenharmony_ci * Context: can sleep 29528c2ecf20Sopenharmony_ci * 29538c2ecf20Sopenharmony_ci * This call may be used with devices that are registered after 29548c2ecf20Sopenharmony_ci * arch init time. It returns a refcounted pointer to the relevant 29558c2ecf20Sopenharmony_ci * spi_controller (which the caller must release), or NULL if there is 29568c2ecf20Sopenharmony_ci * no such master registered. 29578c2ecf20Sopenharmony_ci * 29588c2ecf20Sopenharmony_ci * Return: the SPI master structure on success, else NULL. 29598c2ecf20Sopenharmony_ci */ 29608c2ecf20Sopenharmony_cistruct spi_controller *spi_busnum_to_master(u16 bus_num) 29618c2ecf20Sopenharmony_ci{ 29628c2ecf20Sopenharmony_ci struct device *dev; 29638c2ecf20Sopenharmony_ci struct spi_controller *ctlr = NULL; 29648c2ecf20Sopenharmony_ci 29658c2ecf20Sopenharmony_ci dev = class_find_device(&spi_master_class, NULL, &bus_num, 29668c2ecf20Sopenharmony_ci __spi_controller_match); 29678c2ecf20Sopenharmony_ci if (dev) 29688c2ecf20Sopenharmony_ci ctlr = container_of(dev, struct spi_controller, dev); 29698c2ecf20Sopenharmony_ci /* reference got in class_find_device */ 29708c2ecf20Sopenharmony_ci return ctlr; 29718c2ecf20Sopenharmony_ci} 29728c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_busnum_to_master); 29738c2ecf20Sopenharmony_ci 29748c2ecf20Sopenharmony_ci/*-------------------------------------------------------------------------*/ 29758c2ecf20Sopenharmony_ci 29768c2ecf20Sopenharmony_ci/* Core methods for SPI resource management */ 29778c2ecf20Sopenharmony_ci 29788c2ecf20Sopenharmony_ci/** 29798c2ecf20Sopenharmony_ci * spi_res_alloc - allocate a spi resource that is life-cycle managed 29808c2ecf20Sopenharmony_ci * during the processing of a spi_message while using 29818c2ecf20Sopenharmony_ci * spi_transfer_one 29828c2ecf20Sopenharmony_ci * @spi: the spi device for which we allocate memory 29838c2ecf20Sopenharmony_ci * @release: the release code to execute for this resource 29848c2ecf20Sopenharmony_ci * @size: size to alloc and return 29858c2ecf20Sopenharmony_ci * @gfp: GFP allocation flags 29868c2ecf20Sopenharmony_ci * 29878c2ecf20Sopenharmony_ci * Return: the pointer to the allocated data 29888c2ecf20Sopenharmony_ci * 29898c2ecf20Sopenharmony_ci * This may get enhanced in the future to allocate from a memory pool 29908c2ecf20Sopenharmony_ci * of the @spi_device or @spi_controller to avoid repeated allocations. 29918c2ecf20Sopenharmony_ci */ 29928c2ecf20Sopenharmony_civoid *spi_res_alloc(struct spi_device *spi, 29938c2ecf20Sopenharmony_ci spi_res_release_t release, 29948c2ecf20Sopenharmony_ci size_t size, gfp_t gfp) 29958c2ecf20Sopenharmony_ci{ 29968c2ecf20Sopenharmony_ci struct spi_res *sres; 29978c2ecf20Sopenharmony_ci 29988c2ecf20Sopenharmony_ci sres = kzalloc(sizeof(*sres) + size, gfp); 29998c2ecf20Sopenharmony_ci if (!sres) 30008c2ecf20Sopenharmony_ci return NULL; 30018c2ecf20Sopenharmony_ci 30028c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&sres->entry); 30038c2ecf20Sopenharmony_ci sres->release = release; 30048c2ecf20Sopenharmony_ci 30058c2ecf20Sopenharmony_ci return sres->data; 30068c2ecf20Sopenharmony_ci} 30078c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_res_alloc); 30088c2ecf20Sopenharmony_ci 30098c2ecf20Sopenharmony_ci/** 30108c2ecf20Sopenharmony_ci * spi_res_free - free an spi resource 30118c2ecf20Sopenharmony_ci * @res: pointer to the custom data of a resource 30128c2ecf20Sopenharmony_ci * 30138c2ecf20Sopenharmony_ci */ 30148c2ecf20Sopenharmony_civoid spi_res_free(void *res) 30158c2ecf20Sopenharmony_ci{ 30168c2ecf20Sopenharmony_ci struct spi_res *sres = container_of(res, struct spi_res, data); 30178c2ecf20Sopenharmony_ci 30188c2ecf20Sopenharmony_ci if (!res) 30198c2ecf20Sopenharmony_ci return; 30208c2ecf20Sopenharmony_ci 30218c2ecf20Sopenharmony_ci WARN_ON(!list_empty(&sres->entry)); 30228c2ecf20Sopenharmony_ci kfree(sres); 30238c2ecf20Sopenharmony_ci} 30248c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_res_free); 30258c2ecf20Sopenharmony_ci 30268c2ecf20Sopenharmony_ci/** 30278c2ecf20Sopenharmony_ci * spi_res_add - add a spi_res to the spi_message 30288c2ecf20Sopenharmony_ci * @message: the spi message 30298c2ecf20Sopenharmony_ci * @res: the spi_resource 30308c2ecf20Sopenharmony_ci */ 30318c2ecf20Sopenharmony_civoid spi_res_add(struct spi_message *message, void *res) 30328c2ecf20Sopenharmony_ci{ 30338c2ecf20Sopenharmony_ci struct spi_res *sres = container_of(res, struct spi_res, data); 30348c2ecf20Sopenharmony_ci 30358c2ecf20Sopenharmony_ci WARN_ON(!list_empty(&sres->entry)); 30368c2ecf20Sopenharmony_ci list_add_tail(&sres->entry, &message->resources); 30378c2ecf20Sopenharmony_ci} 30388c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_res_add); 30398c2ecf20Sopenharmony_ci 30408c2ecf20Sopenharmony_ci/** 30418c2ecf20Sopenharmony_ci * spi_res_release - release all spi resources for this message 30428c2ecf20Sopenharmony_ci * @ctlr: the @spi_controller 30438c2ecf20Sopenharmony_ci * @message: the @spi_message 30448c2ecf20Sopenharmony_ci */ 30458c2ecf20Sopenharmony_civoid spi_res_release(struct spi_controller *ctlr, struct spi_message *message) 30468c2ecf20Sopenharmony_ci{ 30478c2ecf20Sopenharmony_ci struct spi_res *res, *tmp; 30488c2ecf20Sopenharmony_ci 30498c2ecf20Sopenharmony_ci list_for_each_entry_safe_reverse(res, tmp, &message->resources, entry) { 30508c2ecf20Sopenharmony_ci if (res->release) 30518c2ecf20Sopenharmony_ci res->release(ctlr, message, res->data); 30528c2ecf20Sopenharmony_ci 30538c2ecf20Sopenharmony_ci list_del(&res->entry); 30548c2ecf20Sopenharmony_ci 30558c2ecf20Sopenharmony_ci kfree(res); 30568c2ecf20Sopenharmony_ci } 30578c2ecf20Sopenharmony_ci} 30588c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_res_release); 30598c2ecf20Sopenharmony_ci 30608c2ecf20Sopenharmony_ci/*-------------------------------------------------------------------------*/ 30618c2ecf20Sopenharmony_ci 30628c2ecf20Sopenharmony_ci/* Core methods for spi_message alterations */ 30638c2ecf20Sopenharmony_ci 30648c2ecf20Sopenharmony_cistatic void __spi_replace_transfers_release(struct spi_controller *ctlr, 30658c2ecf20Sopenharmony_ci struct spi_message *msg, 30668c2ecf20Sopenharmony_ci void *res) 30678c2ecf20Sopenharmony_ci{ 30688c2ecf20Sopenharmony_ci struct spi_replaced_transfers *rxfer = res; 30698c2ecf20Sopenharmony_ci size_t i; 30708c2ecf20Sopenharmony_ci 30718c2ecf20Sopenharmony_ci /* call extra callback if requested */ 30728c2ecf20Sopenharmony_ci if (rxfer->release) 30738c2ecf20Sopenharmony_ci rxfer->release(ctlr, msg, res); 30748c2ecf20Sopenharmony_ci 30758c2ecf20Sopenharmony_ci /* insert replaced transfers back into the message */ 30768c2ecf20Sopenharmony_ci list_splice(&rxfer->replaced_transfers, rxfer->replaced_after); 30778c2ecf20Sopenharmony_ci 30788c2ecf20Sopenharmony_ci /* remove the formerly inserted entries */ 30798c2ecf20Sopenharmony_ci for (i = 0; i < rxfer->inserted; i++) 30808c2ecf20Sopenharmony_ci list_del(&rxfer->inserted_transfers[i].transfer_list); 30818c2ecf20Sopenharmony_ci} 30828c2ecf20Sopenharmony_ci 30838c2ecf20Sopenharmony_ci/** 30848c2ecf20Sopenharmony_ci * spi_replace_transfers - replace transfers with several transfers 30858c2ecf20Sopenharmony_ci * and register change with spi_message.resources 30868c2ecf20Sopenharmony_ci * @msg: the spi_message we work upon 30878c2ecf20Sopenharmony_ci * @xfer_first: the first spi_transfer we want to replace 30888c2ecf20Sopenharmony_ci * @remove: number of transfers to remove 30898c2ecf20Sopenharmony_ci * @insert: the number of transfers we want to insert instead 30908c2ecf20Sopenharmony_ci * @release: extra release code necessary in some circumstances 30918c2ecf20Sopenharmony_ci * @extradatasize: extra data to allocate (with alignment guarantees 30928c2ecf20Sopenharmony_ci * of struct @spi_transfer) 30938c2ecf20Sopenharmony_ci * @gfp: gfp flags 30948c2ecf20Sopenharmony_ci * 30958c2ecf20Sopenharmony_ci * Returns: pointer to @spi_replaced_transfers, 30968c2ecf20Sopenharmony_ci * PTR_ERR(...) in case of errors. 30978c2ecf20Sopenharmony_ci */ 30988c2ecf20Sopenharmony_cistruct spi_replaced_transfers *spi_replace_transfers( 30998c2ecf20Sopenharmony_ci struct spi_message *msg, 31008c2ecf20Sopenharmony_ci struct spi_transfer *xfer_first, 31018c2ecf20Sopenharmony_ci size_t remove, 31028c2ecf20Sopenharmony_ci size_t insert, 31038c2ecf20Sopenharmony_ci spi_replaced_release_t release, 31048c2ecf20Sopenharmony_ci size_t extradatasize, 31058c2ecf20Sopenharmony_ci gfp_t gfp) 31068c2ecf20Sopenharmony_ci{ 31078c2ecf20Sopenharmony_ci struct spi_replaced_transfers *rxfer; 31088c2ecf20Sopenharmony_ci struct spi_transfer *xfer; 31098c2ecf20Sopenharmony_ci size_t i; 31108c2ecf20Sopenharmony_ci 31118c2ecf20Sopenharmony_ci /* allocate the structure using spi_res */ 31128c2ecf20Sopenharmony_ci rxfer = spi_res_alloc(msg->spi, __spi_replace_transfers_release, 31138c2ecf20Sopenharmony_ci struct_size(rxfer, inserted_transfers, insert) 31148c2ecf20Sopenharmony_ci + extradatasize, 31158c2ecf20Sopenharmony_ci gfp); 31168c2ecf20Sopenharmony_ci if (!rxfer) 31178c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 31188c2ecf20Sopenharmony_ci 31198c2ecf20Sopenharmony_ci /* the release code to invoke before running the generic release */ 31208c2ecf20Sopenharmony_ci rxfer->release = release; 31218c2ecf20Sopenharmony_ci 31228c2ecf20Sopenharmony_ci /* assign extradata */ 31238c2ecf20Sopenharmony_ci if (extradatasize) 31248c2ecf20Sopenharmony_ci rxfer->extradata = 31258c2ecf20Sopenharmony_ci &rxfer->inserted_transfers[insert]; 31268c2ecf20Sopenharmony_ci 31278c2ecf20Sopenharmony_ci /* init the replaced_transfers list */ 31288c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&rxfer->replaced_transfers); 31298c2ecf20Sopenharmony_ci 31308c2ecf20Sopenharmony_ci /* assign the list_entry after which we should reinsert 31318c2ecf20Sopenharmony_ci * the @replaced_transfers - it may be spi_message.messages! 31328c2ecf20Sopenharmony_ci */ 31338c2ecf20Sopenharmony_ci rxfer->replaced_after = xfer_first->transfer_list.prev; 31348c2ecf20Sopenharmony_ci 31358c2ecf20Sopenharmony_ci /* remove the requested number of transfers */ 31368c2ecf20Sopenharmony_ci for (i = 0; i < remove; i++) { 31378c2ecf20Sopenharmony_ci /* if the entry after replaced_after it is msg->transfers 31388c2ecf20Sopenharmony_ci * then we have been requested to remove more transfers 31398c2ecf20Sopenharmony_ci * than are in the list 31408c2ecf20Sopenharmony_ci */ 31418c2ecf20Sopenharmony_ci if (rxfer->replaced_after->next == &msg->transfers) { 31428c2ecf20Sopenharmony_ci dev_err(&msg->spi->dev, 31438c2ecf20Sopenharmony_ci "requested to remove more spi_transfers than are available\n"); 31448c2ecf20Sopenharmony_ci /* insert replaced transfers back into the message */ 31458c2ecf20Sopenharmony_ci list_splice(&rxfer->replaced_transfers, 31468c2ecf20Sopenharmony_ci rxfer->replaced_after); 31478c2ecf20Sopenharmony_ci 31488c2ecf20Sopenharmony_ci /* free the spi_replace_transfer structure */ 31498c2ecf20Sopenharmony_ci spi_res_free(rxfer); 31508c2ecf20Sopenharmony_ci 31518c2ecf20Sopenharmony_ci /* and return with an error */ 31528c2ecf20Sopenharmony_ci return ERR_PTR(-EINVAL); 31538c2ecf20Sopenharmony_ci } 31548c2ecf20Sopenharmony_ci 31558c2ecf20Sopenharmony_ci /* remove the entry after replaced_after from list of 31568c2ecf20Sopenharmony_ci * transfers and add it to list of replaced_transfers 31578c2ecf20Sopenharmony_ci */ 31588c2ecf20Sopenharmony_ci list_move_tail(rxfer->replaced_after->next, 31598c2ecf20Sopenharmony_ci &rxfer->replaced_transfers); 31608c2ecf20Sopenharmony_ci } 31618c2ecf20Sopenharmony_ci 31628c2ecf20Sopenharmony_ci /* create copy of the given xfer with identical settings 31638c2ecf20Sopenharmony_ci * based on the first transfer to get removed 31648c2ecf20Sopenharmony_ci */ 31658c2ecf20Sopenharmony_ci for (i = 0; i < insert; i++) { 31668c2ecf20Sopenharmony_ci /* we need to run in reverse order */ 31678c2ecf20Sopenharmony_ci xfer = &rxfer->inserted_transfers[insert - 1 - i]; 31688c2ecf20Sopenharmony_ci 31698c2ecf20Sopenharmony_ci /* copy all spi_transfer data */ 31708c2ecf20Sopenharmony_ci memcpy(xfer, xfer_first, sizeof(*xfer)); 31718c2ecf20Sopenharmony_ci 31728c2ecf20Sopenharmony_ci /* add to list */ 31738c2ecf20Sopenharmony_ci list_add(&xfer->transfer_list, rxfer->replaced_after); 31748c2ecf20Sopenharmony_ci 31758c2ecf20Sopenharmony_ci /* clear cs_change and delay for all but the last */ 31768c2ecf20Sopenharmony_ci if (i) { 31778c2ecf20Sopenharmony_ci xfer->cs_change = false; 31788c2ecf20Sopenharmony_ci xfer->delay_usecs = 0; 31798c2ecf20Sopenharmony_ci xfer->delay.value = 0; 31808c2ecf20Sopenharmony_ci } 31818c2ecf20Sopenharmony_ci } 31828c2ecf20Sopenharmony_ci 31838c2ecf20Sopenharmony_ci /* set up inserted */ 31848c2ecf20Sopenharmony_ci rxfer->inserted = insert; 31858c2ecf20Sopenharmony_ci 31868c2ecf20Sopenharmony_ci /* and register it with spi_res/spi_message */ 31878c2ecf20Sopenharmony_ci spi_res_add(msg, rxfer); 31888c2ecf20Sopenharmony_ci 31898c2ecf20Sopenharmony_ci return rxfer; 31908c2ecf20Sopenharmony_ci} 31918c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_replace_transfers); 31928c2ecf20Sopenharmony_ci 31938c2ecf20Sopenharmony_cistatic int __spi_split_transfer_maxsize(struct spi_controller *ctlr, 31948c2ecf20Sopenharmony_ci struct spi_message *msg, 31958c2ecf20Sopenharmony_ci struct spi_transfer **xferp, 31968c2ecf20Sopenharmony_ci size_t maxsize, 31978c2ecf20Sopenharmony_ci gfp_t gfp) 31988c2ecf20Sopenharmony_ci{ 31998c2ecf20Sopenharmony_ci struct spi_transfer *xfer = *xferp, *xfers; 32008c2ecf20Sopenharmony_ci struct spi_replaced_transfers *srt; 32018c2ecf20Sopenharmony_ci size_t offset; 32028c2ecf20Sopenharmony_ci size_t count, i; 32038c2ecf20Sopenharmony_ci 32048c2ecf20Sopenharmony_ci /* calculate how many we have to replace */ 32058c2ecf20Sopenharmony_ci count = DIV_ROUND_UP(xfer->len, maxsize); 32068c2ecf20Sopenharmony_ci 32078c2ecf20Sopenharmony_ci /* create replacement */ 32088c2ecf20Sopenharmony_ci srt = spi_replace_transfers(msg, xfer, 1, count, NULL, 0, gfp); 32098c2ecf20Sopenharmony_ci if (IS_ERR(srt)) 32108c2ecf20Sopenharmony_ci return PTR_ERR(srt); 32118c2ecf20Sopenharmony_ci xfers = srt->inserted_transfers; 32128c2ecf20Sopenharmony_ci 32138c2ecf20Sopenharmony_ci /* now handle each of those newly inserted spi_transfers 32148c2ecf20Sopenharmony_ci * note that the replacements spi_transfers all are preset 32158c2ecf20Sopenharmony_ci * to the same values as *xferp, so tx_buf, rx_buf and len 32168c2ecf20Sopenharmony_ci * are all identical (as well as most others) 32178c2ecf20Sopenharmony_ci * so we just have to fix up len and the pointers. 32188c2ecf20Sopenharmony_ci * 32198c2ecf20Sopenharmony_ci * this also includes support for the depreciated 32208c2ecf20Sopenharmony_ci * spi_message.is_dma_mapped interface 32218c2ecf20Sopenharmony_ci */ 32228c2ecf20Sopenharmony_ci 32238c2ecf20Sopenharmony_ci /* the first transfer just needs the length modified, so we 32248c2ecf20Sopenharmony_ci * run it outside the loop 32258c2ecf20Sopenharmony_ci */ 32268c2ecf20Sopenharmony_ci xfers[0].len = min_t(size_t, maxsize, xfer[0].len); 32278c2ecf20Sopenharmony_ci 32288c2ecf20Sopenharmony_ci /* all the others need rx_buf/tx_buf also set */ 32298c2ecf20Sopenharmony_ci for (i = 1, offset = maxsize; i < count; offset += maxsize, i++) { 32308c2ecf20Sopenharmony_ci /* update rx_buf, tx_buf and dma */ 32318c2ecf20Sopenharmony_ci if (xfers[i].rx_buf) 32328c2ecf20Sopenharmony_ci xfers[i].rx_buf += offset; 32338c2ecf20Sopenharmony_ci if (xfers[i].rx_dma) 32348c2ecf20Sopenharmony_ci xfers[i].rx_dma += offset; 32358c2ecf20Sopenharmony_ci if (xfers[i].tx_buf) 32368c2ecf20Sopenharmony_ci xfers[i].tx_buf += offset; 32378c2ecf20Sopenharmony_ci if (xfers[i].tx_dma) 32388c2ecf20Sopenharmony_ci xfers[i].tx_dma += offset; 32398c2ecf20Sopenharmony_ci 32408c2ecf20Sopenharmony_ci /* update length */ 32418c2ecf20Sopenharmony_ci xfers[i].len = min(maxsize, xfers[i].len - offset); 32428c2ecf20Sopenharmony_ci } 32438c2ecf20Sopenharmony_ci 32448c2ecf20Sopenharmony_ci /* we set up xferp to the last entry we have inserted, 32458c2ecf20Sopenharmony_ci * so that we skip those already split transfers 32468c2ecf20Sopenharmony_ci */ 32478c2ecf20Sopenharmony_ci *xferp = &xfers[count - 1]; 32488c2ecf20Sopenharmony_ci 32498c2ecf20Sopenharmony_ci /* increment statistics counters */ 32508c2ecf20Sopenharmony_ci SPI_STATISTICS_INCREMENT_FIELD(&ctlr->statistics, 32518c2ecf20Sopenharmony_ci transfers_split_maxsize); 32528c2ecf20Sopenharmony_ci SPI_STATISTICS_INCREMENT_FIELD(&msg->spi->statistics, 32538c2ecf20Sopenharmony_ci transfers_split_maxsize); 32548c2ecf20Sopenharmony_ci 32558c2ecf20Sopenharmony_ci return 0; 32568c2ecf20Sopenharmony_ci} 32578c2ecf20Sopenharmony_ci 32588c2ecf20Sopenharmony_ci/** 32598c2ecf20Sopenharmony_ci * spi_split_tranfers_maxsize - split spi transfers into multiple transfers 32608c2ecf20Sopenharmony_ci * when an individual transfer exceeds a 32618c2ecf20Sopenharmony_ci * certain size 32628c2ecf20Sopenharmony_ci * @ctlr: the @spi_controller for this transfer 32638c2ecf20Sopenharmony_ci * @msg: the @spi_message to transform 32648c2ecf20Sopenharmony_ci * @maxsize: the maximum when to apply this 32658c2ecf20Sopenharmony_ci * @gfp: GFP allocation flags 32668c2ecf20Sopenharmony_ci * 32678c2ecf20Sopenharmony_ci * Return: status of transformation 32688c2ecf20Sopenharmony_ci */ 32698c2ecf20Sopenharmony_ciint spi_split_transfers_maxsize(struct spi_controller *ctlr, 32708c2ecf20Sopenharmony_ci struct spi_message *msg, 32718c2ecf20Sopenharmony_ci size_t maxsize, 32728c2ecf20Sopenharmony_ci gfp_t gfp) 32738c2ecf20Sopenharmony_ci{ 32748c2ecf20Sopenharmony_ci struct spi_transfer *xfer; 32758c2ecf20Sopenharmony_ci int ret; 32768c2ecf20Sopenharmony_ci 32778c2ecf20Sopenharmony_ci /* iterate over the transfer_list, 32788c2ecf20Sopenharmony_ci * but note that xfer is advanced to the last transfer inserted 32798c2ecf20Sopenharmony_ci * to avoid checking sizes again unnecessarily (also xfer does 32808c2ecf20Sopenharmony_ci * potentiall belong to a different list by the time the 32818c2ecf20Sopenharmony_ci * replacement has happened 32828c2ecf20Sopenharmony_ci */ 32838c2ecf20Sopenharmony_ci list_for_each_entry(xfer, &msg->transfers, transfer_list) { 32848c2ecf20Sopenharmony_ci if (xfer->len > maxsize) { 32858c2ecf20Sopenharmony_ci ret = __spi_split_transfer_maxsize(ctlr, msg, &xfer, 32868c2ecf20Sopenharmony_ci maxsize, gfp); 32878c2ecf20Sopenharmony_ci if (ret) 32888c2ecf20Sopenharmony_ci return ret; 32898c2ecf20Sopenharmony_ci } 32908c2ecf20Sopenharmony_ci } 32918c2ecf20Sopenharmony_ci 32928c2ecf20Sopenharmony_ci return 0; 32938c2ecf20Sopenharmony_ci} 32948c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_split_transfers_maxsize); 32958c2ecf20Sopenharmony_ci 32968c2ecf20Sopenharmony_ci/*-------------------------------------------------------------------------*/ 32978c2ecf20Sopenharmony_ci 32988c2ecf20Sopenharmony_ci/* Core methods for SPI controller protocol drivers. Some of the 32998c2ecf20Sopenharmony_ci * other core methods are currently defined as inline functions. 33008c2ecf20Sopenharmony_ci */ 33018c2ecf20Sopenharmony_ci 33028c2ecf20Sopenharmony_cistatic int __spi_validate_bits_per_word(struct spi_controller *ctlr, 33038c2ecf20Sopenharmony_ci u8 bits_per_word) 33048c2ecf20Sopenharmony_ci{ 33058c2ecf20Sopenharmony_ci if (ctlr->bits_per_word_mask) { 33068c2ecf20Sopenharmony_ci /* Only 32 bits fit in the mask */ 33078c2ecf20Sopenharmony_ci if (bits_per_word > 32) 33088c2ecf20Sopenharmony_ci return -EINVAL; 33098c2ecf20Sopenharmony_ci if (!(ctlr->bits_per_word_mask & SPI_BPW_MASK(bits_per_word))) 33108c2ecf20Sopenharmony_ci return -EINVAL; 33118c2ecf20Sopenharmony_ci } 33128c2ecf20Sopenharmony_ci 33138c2ecf20Sopenharmony_ci return 0; 33148c2ecf20Sopenharmony_ci} 33158c2ecf20Sopenharmony_ci 33168c2ecf20Sopenharmony_ci/** 33178c2ecf20Sopenharmony_ci * spi_setup - setup SPI mode and clock rate 33188c2ecf20Sopenharmony_ci * @spi: the device whose settings are being modified 33198c2ecf20Sopenharmony_ci * Context: can sleep, and no requests are queued to the device 33208c2ecf20Sopenharmony_ci * 33218c2ecf20Sopenharmony_ci * SPI protocol drivers may need to update the transfer mode if the 33228c2ecf20Sopenharmony_ci * device doesn't work with its default. They may likewise need 33238c2ecf20Sopenharmony_ci * to update clock rates or word sizes from initial values. This function 33248c2ecf20Sopenharmony_ci * changes those settings, and must be called from a context that can sleep. 33258c2ecf20Sopenharmony_ci * Except for SPI_CS_HIGH, which takes effect immediately, the changes take 33268c2ecf20Sopenharmony_ci * effect the next time the device is selected and data is transferred to 33278c2ecf20Sopenharmony_ci * or from it. When this function returns, the spi device is deselected. 33288c2ecf20Sopenharmony_ci * 33298c2ecf20Sopenharmony_ci * Note that this call will fail if the protocol driver specifies an option 33308c2ecf20Sopenharmony_ci * that the underlying controller or its driver does not support. For 33318c2ecf20Sopenharmony_ci * example, not all hardware supports wire transfers using nine bit words, 33328c2ecf20Sopenharmony_ci * LSB-first wire encoding, or active-high chipselects. 33338c2ecf20Sopenharmony_ci * 33348c2ecf20Sopenharmony_ci * Return: zero on success, else a negative error code. 33358c2ecf20Sopenharmony_ci */ 33368c2ecf20Sopenharmony_ciint spi_setup(struct spi_device *spi) 33378c2ecf20Sopenharmony_ci{ 33388c2ecf20Sopenharmony_ci unsigned bad_bits, ugly_bits; 33398c2ecf20Sopenharmony_ci int status; 33408c2ecf20Sopenharmony_ci 33418c2ecf20Sopenharmony_ci /* check mode to prevent that DUAL and QUAD set at the same time 33428c2ecf20Sopenharmony_ci */ 33438c2ecf20Sopenharmony_ci if (((spi->mode & SPI_TX_DUAL) && (spi->mode & SPI_TX_QUAD)) || 33448c2ecf20Sopenharmony_ci ((spi->mode & SPI_RX_DUAL) && (spi->mode & SPI_RX_QUAD))) { 33458c2ecf20Sopenharmony_ci dev_err(&spi->dev, 33468c2ecf20Sopenharmony_ci "setup: can not select dual and quad at the same time\n"); 33478c2ecf20Sopenharmony_ci return -EINVAL; 33488c2ecf20Sopenharmony_ci } 33498c2ecf20Sopenharmony_ci /* if it is SPI_3WIRE mode, DUAL and QUAD should be forbidden 33508c2ecf20Sopenharmony_ci */ 33518c2ecf20Sopenharmony_ci if ((spi->mode & SPI_3WIRE) && (spi->mode & 33528c2ecf20Sopenharmony_ci (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL | 33538c2ecf20Sopenharmony_ci SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL))) 33548c2ecf20Sopenharmony_ci return -EINVAL; 33558c2ecf20Sopenharmony_ci /* help drivers fail *cleanly* when they need options 33568c2ecf20Sopenharmony_ci * that aren't supported with their current controller 33578c2ecf20Sopenharmony_ci * SPI_CS_WORD has a fallback software implementation, 33588c2ecf20Sopenharmony_ci * so it is ignored here. 33598c2ecf20Sopenharmony_ci */ 33608c2ecf20Sopenharmony_ci bad_bits = spi->mode & ~(spi->controller->mode_bits | SPI_CS_WORD); 33618c2ecf20Sopenharmony_ci /* nothing prevents from working with active-high CS in case if it 33628c2ecf20Sopenharmony_ci * is driven by GPIO. 33638c2ecf20Sopenharmony_ci */ 33648c2ecf20Sopenharmony_ci if (gpio_is_valid(spi->cs_gpio)) 33658c2ecf20Sopenharmony_ci bad_bits &= ~SPI_CS_HIGH; 33668c2ecf20Sopenharmony_ci ugly_bits = bad_bits & 33678c2ecf20Sopenharmony_ci (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL | 33688c2ecf20Sopenharmony_ci SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL); 33698c2ecf20Sopenharmony_ci if (ugly_bits) { 33708c2ecf20Sopenharmony_ci dev_warn(&spi->dev, 33718c2ecf20Sopenharmony_ci "setup: ignoring unsupported mode bits %x\n", 33728c2ecf20Sopenharmony_ci ugly_bits); 33738c2ecf20Sopenharmony_ci spi->mode &= ~ugly_bits; 33748c2ecf20Sopenharmony_ci bad_bits &= ~ugly_bits; 33758c2ecf20Sopenharmony_ci } 33768c2ecf20Sopenharmony_ci if (bad_bits) { 33778c2ecf20Sopenharmony_ci dev_err(&spi->dev, "setup: unsupported mode bits %x\n", 33788c2ecf20Sopenharmony_ci bad_bits); 33798c2ecf20Sopenharmony_ci return -EINVAL; 33808c2ecf20Sopenharmony_ci } 33818c2ecf20Sopenharmony_ci 33828c2ecf20Sopenharmony_ci if (!spi->bits_per_word) 33838c2ecf20Sopenharmony_ci spi->bits_per_word = 8; 33848c2ecf20Sopenharmony_ci 33858c2ecf20Sopenharmony_ci status = __spi_validate_bits_per_word(spi->controller, 33868c2ecf20Sopenharmony_ci spi->bits_per_word); 33878c2ecf20Sopenharmony_ci if (status) 33888c2ecf20Sopenharmony_ci return status; 33898c2ecf20Sopenharmony_ci 33908c2ecf20Sopenharmony_ci if (!spi->max_speed_hz) 33918c2ecf20Sopenharmony_ci spi->max_speed_hz = spi->controller->max_speed_hz; 33928c2ecf20Sopenharmony_ci 33938c2ecf20Sopenharmony_ci mutex_lock(&spi->controller->io_mutex); 33948c2ecf20Sopenharmony_ci 33958c2ecf20Sopenharmony_ci if (spi->controller->setup) 33968c2ecf20Sopenharmony_ci status = spi->controller->setup(spi); 33978c2ecf20Sopenharmony_ci 33988c2ecf20Sopenharmony_ci if (spi->controller->auto_runtime_pm && spi->controller->set_cs) { 33998c2ecf20Sopenharmony_ci status = pm_runtime_get_sync(spi->controller->dev.parent); 34008c2ecf20Sopenharmony_ci if (status < 0) { 34018c2ecf20Sopenharmony_ci mutex_unlock(&spi->controller->io_mutex); 34028c2ecf20Sopenharmony_ci pm_runtime_put_noidle(spi->controller->dev.parent); 34038c2ecf20Sopenharmony_ci dev_err(&spi->controller->dev, "Failed to power device: %d\n", 34048c2ecf20Sopenharmony_ci status); 34058c2ecf20Sopenharmony_ci return status; 34068c2ecf20Sopenharmony_ci } 34078c2ecf20Sopenharmony_ci 34088c2ecf20Sopenharmony_ci /* 34098c2ecf20Sopenharmony_ci * We do not want to return positive value from pm_runtime_get, 34108c2ecf20Sopenharmony_ci * there are many instances of devices calling spi_setup() and 34118c2ecf20Sopenharmony_ci * checking for a non-zero return value instead of a negative 34128c2ecf20Sopenharmony_ci * return value. 34138c2ecf20Sopenharmony_ci */ 34148c2ecf20Sopenharmony_ci status = 0; 34158c2ecf20Sopenharmony_ci 34168c2ecf20Sopenharmony_ci spi_set_cs(spi, false, true); 34178c2ecf20Sopenharmony_ci pm_runtime_mark_last_busy(spi->controller->dev.parent); 34188c2ecf20Sopenharmony_ci pm_runtime_put_autosuspend(spi->controller->dev.parent); 34198c2ecf20Sopenharmony_ci } else { 34208c2ecf20Sopenharmony_ci spi_set_cs(spi, false, true); 34218c2ecf20Sopenharmony_ci } 34228c2ecf20Sopenharmony_ci 34238c2ecf20Sopenharmony_ci mutex_unlock(&spi->controller->io_mutex); 34248c2ecf20Sopenharmony_ci 34258c2ecf20Sopenharmony_ci if (spi->rt && !spi->controller->rt) { 34268c2ecf20Sopenharmony_ci spi->controller->rt = true; 34278c2ecf20Sopenharmony_ci spi_set_thread_rt(spi->controller); 34288c2ecf20Sopenharmony_ci } 34298c2ecf20Sopenharmony_ci 34308c2ecf20Sopenharmony_ci dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s%u bits/w, %u Hz max --> %d\n", 34318c2ecf20Sopenharmony_ci (int) (spi->mode & (SPI_CPOL | SPI_CPHA)), 34328c2ecf20Sopenharmony_ci (spi->mode & SPI_CS_HIGH) ? "cs_high, " : "", 34338c2ecf20Sopenharmony_ci (spi->mode & SPI_LSB_FIRST) ? "lsb, " : "", 34348c2ecf20Sopenharmony_ci (spi->mode & SPI_3WIRE) ? "3wire, " : "", 34358c2ecf20Sopenharmony_ci (spi->mode & SPI_LOOP) ? "loopback, " : "", 34368c2ecf20Sopenharmony_ci spi->bits_per_word, spi->max_speed_hz, 34378c2ecf20Sopenharmony_ci status); 34388c2ecf20Sopenharmony_ci 34398c2ecf20Sopenharmony_ci return status; 34408c2ecf20Sopenharmony_ci} 34418c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_setup); 34428c2ecf20Sopenharmony_ci 34438c2ecf20Sopenharmony_ci/** 34448c2ecf20Sopenharmony_ci * spi_set_cs_timing - configure CS setup, hold, and inactive delays 34458c2ecf20Sopenharmony_ci * @spi: the device that requires specific CS timing configuration 34468c2ecf20Sopenharmony_ci * @setup: CS setup time specified via @spi_delay 34478c2ecf20Sopenharmony_ci * @hold: CS hold time specified via @spi_delay 34488c2ecf20Sopenharmony_ci * @inactive: CS inactive delay between transfers specified via @spi_delay 34498c2ecf20Sopenharmony_ci * 34508c2ecf20Sopenharmony_ci * Return: zero on success, else a negative error code. 34518c2ecf20Sopenharmony_ci */ 34528c2ecf20Sopenharmony_ciint spi_set_cs_timing(struct spi_device *spi, struct spi_delay *setup, 34538c2ecf20Sopenharmony_ci struct spi_delay *hold, struct spi_delay *inactive) 34548c2ecf20Sopenharmony_ci{ 34558c2ecf20Sopenharmony_ci size_t len; 34568c2ecf20Sopenharmony_ci 34578c2ecf20Sopenharmony_ci if (spi->controller->set_cs_timing) 34588c2ecf20Sopenharmony_ci return spi->controller->set_cs_timing(spi, setup, hold, 34598c2ecf20Sopenharmony_ci inactive); 34608c2ecf20Sopenharmony_ci 34618c2ecf20Sopenharmony_ci if ((setup && setup->unit == SPI_DELAY_UNIT_SCK) || 34628c2ecf20Sopenharmony_ci (hold && hold->unit == SPI_DELAY_UNIT_SCK) || 34638c2ecf20Sopenharmony_ci (inactive && inactive->unit == SPI_DELAY_UNIT_SCK)) { 34648c2ecf20Sopenharmony_ci dev_err(&spi->dev, 34658c2ecf20Sopenharmony_ci "Clock-cycle delays for CS not supported in SW mode\n"); 34668c2ecf20Sopenharmony_ci return -ENOTSUPP; 34678c2ecf20Sopenharmony_ci } 34688c2ecf20Sopenharmony_ci 34698c2ecf20Sopenharmony_ci len = sizeof(struct spi_delay); 34708c2ecf20Sopenharmony_ci 34718c2ecf20Sopenharmony_ci /* copy delays to controller */ 34728c2ecf20Sopenharmony_ci if (setup) 34738c2ecf20Sopenharmony_ci memcpy(&spi->controller->cs_setup, setup, len); 34748c2ecf20Sopenharmony_ci else 34758c2ecf20Sopenharmony_ci memset(&spi->controller->cs_setup, 0, len); 34768c2ecf20Sopenharmony_ci 34778c2ecf20Sopenharmony_ci if (hold) 34788c2ecf20Sopenharmony_ci memcpy(&spi->controller->cs_hold, hold, len); 34798c2ecf20Sopenharmony_ci else 34808c2ecf20Sopenharmony_ci memset(&spi->controller->cs_hold, 0, len); 34818c2ecf20Sopenharmony_ci 34828c2ecf20Sopenharmony_ci if (inactive) 34838c2ecf20Sopenharmony_ci memcpy(&spi->controller->cs_inactive, inactive, len); 34848c2ecf20Sopenharmony_ci else 34858c2ecf20Sopenharmony_ci memset(&spi->controller->cs_inactive, 0, len); 34868c2ecf20Sopenharmony_ci 34878c2ecf20Sopenharmony_ci return 0; 34888c2ecf20Sopenharmony_ci} 34898c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_set_cs_timing); 34908c2ecf20Sopenharmony_ci 34918c2ecf20Sopenharmony_cistatic int _spi_xfer_word_delay_update(struct spi_transfer *xfer, 34928c2ecf20Sopenharmony_ci struct spi_device *spi) 34938c2ecf20Sopenharmony_ci{ 34948c2ecf20Sopenharmony_ci int delay1, delay2; 34958c2ecf20Sopenharmony_ci 34968c2ecf20Sopenharmony_ci delay1 = spi_delay_to_ns(&xfer->word_delay, xfer); 34978c2ecf20Sopenharmony_ci if (delay1 < 0) 34988c2ecf20Sopenharmony_ci return delay1; 34998c2ecf20Sopenharmony_ci 35008c2ecf20Sopenharmony_ci delay2 = spi_delay_to_ns(&spi->word_delay, xfer); 35018c2ecf20Sopenharmony_ci if (delay2 < 0) 35028c2ecf20Sopenharmony_ci return delay2; 35038c2ecf20Sopenharmony_ci 35048c2ecf20Sopenharmony_ci if (delay1 < delay2) 35058c2ecf20Sopenharmony_ci memcpy(&xfer->word_delay, &spi->word_delay, 35068c2ecf20Sopenharmony_ci sizeof(xfer->word_delay)); 35078c2ecf20Sopenharmony_ci 35088c2ecf20Sopenharmony_ci return 0; 35098c2ecf20Sopenharmony_ci} 35108c2ecf20Sopenharmony_ci 35118c2ecf20Sopenharmony_cistatic int __spi_validate(struct spi_device *spi, struct spi_message *message) 35128c2ecf20Sopenharmony_ci{ 35138c2ecf20Sopenharmony_ci struct spi_controller *ctlr = spi->controller; 35148c2ecf20Sopenharmony_ci struct spi_transfer *xfer; 35158c2ecf20Sopenharmony_ci int w_size; 35168c2ecf20Sopenharmony_ci 35178c2ecf20Sopenharmony_ci if (list_empty(&message->transfers)) 35188c2ecf20Sopenharmony_ci return -EINVAL; 35198c2ecf20Sopenharmony_ci 35208c2ecf20Sopenharmony_ci /* If an SPI controller does not support toggling the CS line on each 35218c2ecf20Sopenharmony_ci * transfer (indicated by the SPI_CS_WORD flag) or we are using a GPIO 35228c2ecf20Sopenharmony_ci * for the CS line, we can emulate the CS-per-word hardware function by 35238c2ecf20Sopenharmony_ci * splitting transfers into one-word transfers and ensuring that 35248c2ecf20Sopenharmony_ci * cs_change is set for each transfer. 35258c2ecf20Sopenharmony_ci */ 35268c2ecf20Sopenharmony_ci if ((spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) || 35278c2ecf20Sopenharmony_ci spi->cs_gpiod || 35288c2ecf20Sopenharmony_ci gpio_is_valid(spi->cs_gpio))) { 35298c2ecf20Sopenharmony_ci size_t maxsize; 35308c2ecf20Sopenharmony_ci int ret; 35318c2ecf20Sopenharmony_ci 35328c2ecf20Sopenharmony_ci maxsize = (spi->bits_per_word + 7) / 8; 35338c2ecf20Sopenharmony_ci 35348c2ecf20Sopenharmony_ci /* spi_split_transfers_maxsize() requires message->spi */ 35358c2ecf20Sopenharmony_ci message->spi = spi; 35368c2ecf20Sopenharmony_ci 35378c2ecf20Sopenharmony_ci ret = spi_split_transfers_maxsize(ctlr, message, maxsize, 35388c2ecf20Sopenharmony_ci GFP_KERNEL); 35398c2ecf20Sopenharmony_ci if (ret) 35408c2ecf20Sopenharmony_ci return ret; 35418c2ecf20Sopenharmony_ci 35428c2ecf20Sopenharmony_ci list_for_each_entry(xfer, &message->transfers, transfer_list) { 35438c2ecf20Sopenharmony_ci /* don't change cs_change on the last entry in the list */ 35448c2ecf20Sopenharmony_ci if (list_is_last(&xfer->transfer_list, &message->transfers)) 35458c2ecf20Sopenharmony_ci break; 35468c2ecf20Sopenharmony_ci xfer->cs_change = 1; 35478c2ecf20Sopenharmony_ci } 35488c2ecf20Sopenharmony_ci } 35498c2ecf20Sopenharmony_ci 35508c2ecf20Sopenharmony_ci /* Half-duplex links include original MicroWire, and ones with 35518c2ecf20Sopenharmony_ci * only one data pin like SPI_3WIRE (switches direction) or where 35528c2ecf20Sopenharmony_ci * either MOSI or MISO is missing. They can also be caused by 35538c2ecf20Sopenharmony_ci * software limitations. 35548c2ecf20Sopenharmony_ci */ 35558c2ecf20Sopenharmony_ci if ((ctlr->flags & SPI_CONTROLLER_HALF_DUPLEX) || 35568c2ecf20Sopenharmony_ci (spi->mode & SPI_3WIRE)) { 35578c2ecf20Sopenharmony_ci unsigned flags = ctlr->flags; 35588c2ecf20Sopenharmony_ci 35598c2ecf20Sopenharmony_ci list_for_each_entry(xfer, &message->transfers, transfer_list) { 35608c2ecf20Sopenharmony_ci if (xfer->rx_buf && xfer->tx_buf) 35618c2ecf20Sopenharmony_ci return -EINVAL; 35628c2ecf20Sopenharmony_ci if ((flags & SPI_CONTROLLER_NO_TX) && xfer->tx_buf) 35638c2ecf20Sopenharmony_ci return -EINVAL; 35648c2ecf20Sopenharmony_ci if ((flags & SPI_CONTROLLER_NO_RX) && xfer->rx_buf) 35658c2ecf20Sopenharmony_ci return -EINVAL; 35668c2ecf20Sopenharmony_ci } 35678c2ecf20Sopenharmony_ci } 35688c2ecf20Sopenharmony_ci 35698c2ecf20Sopenharmony_ci /** 35708c2ecf20Sopenharmony_ci * Set transfer bits_per_word and max speed as spi device default if 35718c2ecf20Sopenharmony_ci * it is not set for this transfer. 35728c2ecf20Sopenharmony_ci * Set transfer tx_nbits and rx_nbits as single transfer default 35738c2ecf20Sopenharmony_ci * (SPI_NBITS_SINGLE) if it is not set for this transfer. 35748c2ecf20Sopenharmony_ci * Ensure transfer word_delay is at least as long as that required by 35758c2ecf20Sopenharmony_ci * device itself. 35768c2ecf20Sopenharmony_ci */ 35778c2ecf20Sopenharmony_ci message->frame_length = 0; 35788c2ecf20Sopenharmony_ci list_for_each_entry(xfer, &message->transfers, transfer_list) { 35798c2ecf20Sopenharmony_ci xfer->effective_speed_hz = 0; 35808c2ecf20Sopenharmony_ci message->frame_length += xfer->len; 35818c2ecf20Sopenharmony_ci if (!xfer->bits_per_word) 35828c2ecf20Sopenharmony_ci xfer->bits_per_word = spi->bits_per_word; 35838c2ecf20Sopenharmony_ci 35848c2ecf20Sopenharmony_ci if (!xfer->speed_hz) 35858c2ecf20Sopenharmony_ci xfer->speed_hz = spi->max_speed_hz; 35868c2ecf20Sopenharmony_ci 35878c2ecf20Sopenharmony_ci if (ctlr->max_speed_hz && xfer->speed_hz > ctlr->max_speed_hz) 35888c2ecf20Sopenharmony_ci xfer->speed_hz = ctlr->max_speed_hz; 35898c2ecf20Sopenharmony_ci 35908c2ecf20Sopenharmony_ci if (__spi_validate_bits_per_word(ctlr, xfer->bits_per_word)) 35918c2ecf20Sopenharmony_ci return -EINVAL; 35928c2ecf20Sopenharmony_ci 35938c2ecf20Sopenharmony_ci /* 35948c2ecf20Sopenharmony_ci * SPI transfer length should be multiple of SPI word size 35958c2ecf20Sopenharmony_ci * where SPI word size should be power-of-two multiple 35968c2ecf20Sopenharmony_ci */ 35978c2ecf20Sopenharmony_ci if (xfer->bits_per_word <= 8) 35988c2ecf20Sopenharmony_ci w_size = 1; 35998c2ecf20Sopenharmony_ci else if (xfer->bits_per_word <= 16) 36008c2ecf20Sopenharmony_ci w_size = 2; 36018c2ecf20Sopenharmony_ci else 36028c2ecf20Sopenharmony_ci w_size = 4; 36038c2ecf20Sopenharmony_ci 36048c2ecf20Sopenharmony_ci /* No partial transfers accepted */ 36058c2ecf20Sopenharmony_ci if (xfer->len % w_size) 36068c2ecf20Sopenharmony_ci return -EINVAL; 36078c2ecf20Sopenharmony_ci 36088c2ecf20Sopenharmony_ci if (xfer->speed_hz && ctlr->min_speed_hz && 36098c2ecf20Sopenharmony_ci xfer->speed_hz < ctlr->min_speed_hz) 36108c2ecf20Sopenharmony_ci return -EINVAL; 36118c2ecf20Sopenharmony_ci 36128c2ecf20Sopenharmony_ci if (xfer->tx_buf && !xfer->tx_nbits) 36138c2ecf20Sopenharmony_ci xfer->tx_nbits = SPI_NBITS_SINGLE; 36148c2ecf20Sopenharmony_ci if (xfer->rx_buf && !xfer->rx_nbits) 36158c2ecf20Sopenharmony_ci xfer->rx_nbits = SPI_NBITS_SINGLE; 36168c2ecf20Sopenharmony_ci /* check transfer tx/rx_nbits: 36178c2ecf20Sopenharmony_ci * 1. check the value matches one of single, dual and quad 36188c2ecf20Sopenharmony_ci * 2. check tx/rx_nbits match the mode in spi_device 36198c2ecf20Sopenharmony_ci */ 36208c2ecf20Sopenharmony_ci if (xfer->tx_buf) { 36218c2ecf20Sopenharmony_ci if (xfer->tx_nbits != SPI_NBITS_SINGLE && 36228c2ecf20Sopenharmony_ci xfer->tx_nbits != SPI_NBITS_DUAL && 36238c2ecf20Sopenharmony_ci xfer->tx_nbits != SPI_NBITS_QUAD) 36248c2ecf20Sopenharmony_ci return -EINVAL; 36258c2ecf20Sopenharmony_ci if ((xfer->tx_nbits == SPI_NBITS_DUAL) && 36268c2ecf20Sopenharmony_ci !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD))) 36278c2ecf20Sopenharmony_ci return -EINVAL; 36288c2ecf20Sopenharmony_ci if ((xfer->tx_nbits == SPI_NBITS_QUAD) && 36298c2ecf20Sopenharmony_ci !(spi->mode & SPI_TX_QUAD)) 36308c2ecf20Sopenharmony_ci return -EINVAL; 36318c2ecf20Sopenharmony_ci } 36328c2ecf20Sopenharmony_ci /* check transfer rx_nbits */ 36338c2ecf20Sopenharmony_ci if (xfer->rx_buf) { 36348c2ecf20Sopenharmony_ci if (xfer->rx_nbits != SPI_NBITS_SINGLE && 36358c2ecf20Sopenharmony_ci xfer->rx_nbits != SPI_NBITS_DUAL && 36368c2ecf20Sopenharmony_ci xfer->rx_nbits != SPI_NBITS_QUAD) 36378c2ecf20Sopenharmony_ci return -EINVAL; 36388c2ecf20Sopenharmony_ci if ((xfer->rx_nbits == SPI_NBITS_DUAL) && 36398c2ecf20Sopenharmony_ci !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD))) 36408c2ecf20Sopenharmony_ci return -EINVAL; 36418c2ecf20Sopenharmony_ci if ((xfer->rx_nbits == SPI_NBITS_QUAD) && 36428c2ecf20Sopenharmony_ci !(spi->mode & SPI_RX_QUAD)) 36438c2ecf20Sopenharmony_ci return -EINVAL; 36448c2ecf20Sopenharmony_ci } 36458c2ecf20Sopenharmony_ci 36468c2ecf20Sopenharmony_ci if (_spi_xfer_word_delay_update(xfer, spi)) 36478c2ecf20Sopenharmony_ci return -EINVAL; 36488c2ecf20Sopenharmony_ci } 36498c2ecf20Sopenharmony_ci 36508c2ecf20Sopenharmony_ci message->status = -EINPROGRESS; 36518c2ecf20Sopenharmony_ci 36528c2ecf20Sopenharmony_ci return 0; 36538c2ecf20Sopenharmony_ci} 36548c2ecf20Sopenharmony_ci 36558c2ecf20Sopenharmony_cistatic int __spi_async(struct spi_device *spi, struct spi_message *message) 36568c2ecf20Sopenharmony_ci{ 36578c2ecf20Sopenharmony_ci struct spi_controller *ctlr = spi->controller; 36588c2ecf20Sopenharmony_ci struct spi_transfer *xfer; 36598c2ecf20Sopenharmony_ci 36608c2ecf20Sopenharmony_ci /* 36618c2ecf20Sopenharmony_ci * Some controllers do not support doing regular SPI transfers. Return 36628c2ecf20Sopenharmony_ci * ENOTSUPP when this is the case. 36638c2ecf20Sopenharmony_ci */ 36648c2ecf20Sopenharmony_ci if (!ctlr->transfer) 36658c2ecf20Sopenharmony_ci return -ENOTSUPP; 36668c2ecf20Sopenharmony_ci 36678c2ecf20Sopenharmony_ci message->spi = spi; 36688c2ecf20Sopenharmony_ci 36698c2ecf20Sopenharmony_ci SPI_STATISTICS_INCREMENT_FIELD(&ctlr->statistics, spi_async); 36708c2ecf20Sopenharmony_ci SPI_STATISTICS_INCREMENT_FIELD(&spi->statistics, spi_async); 36718c2ecf20Sopenharmony_ci 36728c2ecf20Sopenharmony_ci trace_spi_message_submit(message); 36738c2ecf20Sopenharmony_ci 36748c2ecf20Sopenharmony_ci if (!ctlr->ptp_sts_supported) { 36758c2ecf20Sopenharmony_ci list_for_each_entry(xfer, &message->transfers, transfer_list) { 36768c2ecf20Sopenharmony_ci xfer->ptp_sts_word_pre = 0; 36778c2ecf20Sopenharmony_ci ptp_read_system_prets(xfer->ptp_sts); 36788c2ecf20Sopenharmony_ci } 36798c2ecf20Sopenharmony_ci } 36808c2ecf20Sopenharmony_ci 36818c2ecf20Sopenharmony_ci return ctlr->transfer(spi, message); 36828c2ecf20Sopenharmony_ci} 36838c2ecf20Sopenharmony_ci 36848c2ecf20Sopenharmony_ci/** 36858c2ecf20Sopenharmony_ci * spi_async - asynchronous SPI transfer 36868c2ecf20Sopenharmony_ci * @spi: device with which data will be exchanged 36878c2ecf20Sopenharmony_ci * @message: describes the data transfers, including completion callback 36888c2ecf20Sopenharmony_ci * Context: any (irqs may be blocked, etc) 36898c2ecf20Sopenharmony_ci * 36908c2ecf20Sopenharmony_ci * This call may be used in_irq and other contexts which can't sleep, 36918c2ecf20Sopenharmony_ci * as well as from task contexts which can sleep. 36928c2ecf20Sopenharmony_ci * 36938c2ecf20Sopenharmony_ci * The completion callback is invoked in a context which can't sleep. 36948c2ecf20Sopenharmony_ci * Before that invocation, the value of message->status is undefined. 36958c2ecf20Sopenharmony_ci * When the callback is issued, message->status holds either zero (to 36968c2ecf20Sopenharmony_ci * indicate complete success) or a negative error code. After that 36978c2ecf20Sopenharmony_ci * callback returns, the driver which issued the transfer request may 36988c2ecf20Sopenharmony_ci * deallocate the associated memory; it's no longer in use by any SPI 36998c2ecf20Sopenharmony_ci * core or controller driver code. 37008c2ecf20Sopenharmony_ci * 37018c2ecf20Sopenharmony_ci * Note that although all messages to a spi_device are handled in 37028c2ecf20Sopenharmony_ci * FIFO order, messages may go to different devices in other orders. 37038c2ecf20Sopenharmony_ci * Some device might be higher priority, or have various "hard" access 37048c2ecf20Sopenharmony_ci * time requirements, for example. 37058c2ecf20Sopenharmony_ci * 37068c2ecf20Sopenharmony_ci * On detection of any fault during the transfer, processing of 37078c2ecf20Sopenharmony_ci * the entire message is aborted, and the device is deselected. 37088c2ecf20Sopenharmony_ci * Until returning from the associated message completion callback, 37098c2ecf20Sopenharmony_ci * no other spi_message queued to that device will be processed. 37108c2ecf20Sopenharmony_ci * (This rule applies equally to all the synchronous transfer calls, 37118c2ecf20Sopenharmony_ci * which are wrappers around this core asynchronous primitive.) 37128c2ecf20Sopenharmony_ci * 37138c2ecf20Sopenharmony_ci * Return: zero on success, else a negative error code. 37148c2ecf20Sopenharmony_ci */ 37158c2ecf20Sopenharmony_ciint spi_async(struct spi_device *spi, struct spi_message *message) 37168c2ecf20Sopenharmony_ci{ 37178c2ecf20Sopenharmony_ci struct spi_controller *ctlr = spi->controller; 37188c2ecf20Sopenharmony_ci int ret; 37198c2ecf20Sopenharmony_ci unsigned long flags; 37208c2ecf20Sopenharmony_ci 37218c2ecf20Sopenharmony_ci ret = __spi_validate(spi, message); 37228c2ecf20Sopenharmony_ci if (ret != 0) 37238c2ecf20Sopenharmony_ci return ret; 37248c2ecf20Sopenharmony_ci 37258c2ecf20Sopenharmony_ci spin_lock_irqsave(&ctlr->bus_lock_spinlock, flags); 37268c2ecf20Sopenharmony_ci 37278c2ecf20Sopenharmony_ci if (ctlr->bus_lock_flag) 37288c2ecf20Sopenharmony_ci ret = -EBUSY; 37298c2ecf20Sopenharmony_ci else 37308c2ecf20Sopenharmony_ci ret = __spi_async(spi, message); 37318c2ecf20Sopenharmony_ci 37328c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->bus_lock_spinlock, flags); 37338c2ecf20Sopenharmony_ci 37348c2ecf20Sopenharmony_ci return ret; 37358c2ecf20Sopenharmony_ci} 37368c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_async); 37378c2ecf20Sopenharmony_ci 37388c2ecf20Sopenharmony_ci/** 37398c2ecf20Sopenharmony_ci * spi_async_locked - version of spi_async with exclusive bus usage 37408c2ecf20Sopenharmony_ci * @spi: device with which data will be exchanged 37418c2ecf20Sopenharmony_ci * @message: describes the data transfers, including completion callback 37428c2ecf20Sopenharmony_ci * Context: any (irqs may be blocked, etc) 37438c2ecf20Sopenharmony_ci * 37448c2ecf20Sopenharmony_ci * This call may be used in_irq and other contexts which can't sleep, 37458c2ecf20Sopenharmony_ci * as well as from task contexts which can sleep. 37468c2ecf20Sopenharmony_ci * 37478c2ecf20Sopenharmony_ci * The completion callback is invoked in a context which can't sleep. 37488c2ecf20Sopenharmony_ci * Before that invocation, the value of message->status is undefined. 37498c2ecf20Sopenharmony_ci * When the callback is issued, message->status holds either zero (to 37508c2ecf20Sopenharmony_ci * indicate complete success) or a negative error code. After that 37518c2ecf20Sopenharmony_ci * callback returns, the driver which issued the transfer request may 37528c2ecf20Sopenharmony_ci * deallocate the associated memory; it's no longer in use by any SPI 37538c2ecf20Sopenharmony_ci * core or controller driver code. 37548c2ecf20Sopenharmony_ci * 37558c2ecf20Sopenharmony_ci * Note that although all messages to a spi_device are handled in 37568c2ecf20Sopenharmony_ci * FIFO order, messages may go to different devices in other orders. 37578c2ecf20Sopenharmony_ci * Some device might be higher priority, or have various "hard" access 37588c2ecf20Sopenharmony_ci * time requirements, for example. 37598c2ecf20Sopenharmony_ci * 37608c2ecf20Sopenharmony_ci * On detection of any fault during the transfer, processing of 37618c2ecf20Sopenharmony_ci * the entire message is aborted, and the device is deselected. 37628c2ecf20Sopenharmony_ci * Until returning from the associated message completion callback, 37638c2ecf20Sopenharmony_ci * no other spi_message queued to that device will be processed. 37648c2ecf20Sopenharmony_ci * (This rule applies equally to all the synchronous transfer calls, 37658c2ecf20Sopenharmony_ci * which are wrappers around this core asynchronous primitive.) 37668c2ecf20Sopenharmony_ci * 37678c2ecf20Sopenharmony_ci * Return: zero on success, else a negative error code. 37688c2ecf20Sopenharmony_ci */ 37698c2ecf20Sopenharmony_ciint spi_async_locked(struct spi_device *spi, struct spi_message *message) 37708c2ecf20Sopenharmony_ci{ 37718c2ecf20Sopenharmony_ci struct spi_controller *ctlr = spi->controller; 37728c2ecf20Sopenharmony_ci int ret; 37738c2ecf20Sopenharmony_ci unsigned long flags; 37748c2ecf20Sopenharmony_ci 37758c2ecf20Sopenharmony_ci ret = __spi_validate(spi, message); 37768c2ecf20Sopenharmony_ci if (ret != 0) 37778c2ecf20Sopenharmony_ci return ret; 37788c2ecf20Sopenharmony_ci 37798c2ecf20Sopenharmony_ci spin_lock_irqsave(&ctlr->bus_lock_spinlock, flags); 37808c2ecf20Sopenharmony_ci 37818c2ecf20Sopenharmony_ci ret = __spi_async(spi, message); 37828c2ecf20Sopenharmony_ci 37838c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->bus_lock_spinlock, flags); 37848c2ecf20Sopenharmony_ci 37858c2ecf20Sopenharmony_ci return ret; 37868c2ecf20Sopenharmony_ci 37878c2ecf20Sopenharmony_ci} 37888c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_async_locked); 37898c2ecf20Sopenharmony_ci 37908c2ecf20Sopenharmony_ci/*-------------------------------------------------------------------------*/ 37918c2ecf20Sopenharmony_ci 37928c2ecf20Sopenharmony_ci/* Utility methods for SPI protocol drivers, layered on 37938c2ecf20Sopenharmony_ci * top of the core. Some other utility methods are defined as 37948c2ecf20Sopenharmony_ci * inline functions. 37958c2ecf20Sopenharmony_ci */ 37968c2ecf20Sopenharmony_ci 37978c2ecf20Sopenharmony_cistatic void spi_complete(void *arg) 37988c2ecf20Sopenharmony_ci{ 37998c2ecf20Sopenharmony_ci complete(arg); 38008c2ecf20Sopenharmony_ci} 38018c2ecf20Sopenharmony_ci 38028c2ecf20Sopenharmony_cistatic int __spi_sync(struct spi_device *spi, struct spi_message *message) 38038c2ecf20Sopenharmony_ci{ 38048c2ecf20Sopenharmony_ci DECLARE_COMPLETION_ONSTACK(done); 38058c2ecf20Sopenharmony_ci int status; 38068c2ecf20Sopenharmony_ci struct spi_controller *ctlr = spi->controller; 38078c2ecf20Sopenharmony_ci unsigned long flags; 38088c2ecf20Sopenharmony_ci 38098c2ecf20Sopenharmony_ci status = __spi_validate(spi, message); 38108c2ecf20Sopenharmony_ci if (status != 0) 38118c2ecf20Sopenharmony_ci return status; 38128c2ecf20Sopenharmony_ci 38138c2ecf20Sopenharmony_ci message->complete = spi_complete; 38148c2ecf20Sopenharmony_ci message->context = &done; 38158c2ecf20Sopenharmony_ci message->spi = spi; 38168c2ecf20Sopenharmony_ci 38178c2ecf20Sopenharmony_ci SPI_STATISTICS_INCREMENT_FIELD(&ctlr->statistics, spi_sync); 38188c2ecf20Sopenharmony_ci SPI_STATISTICS_INCREMENT_FIELD(&spi->statistics, spi_sync); 38198c2ecf20Sopenharmony_ci 38208c2ecf20Sopenharmony_ci /* If we're not using the legacy transfer method then we will 38218c2ecf20Sopenharmony_ci * try to transfer in the calling context so special case. 38228c2ecf20Sopenharmony_ci * This code would be less tricky if we could remove the 38238c2ecf20Sopenharmony_ci * support for driver implemented message queues. 38248c2ecf20Sopenharmony_ci */ 38258c2ecf20Sopenharmony_ci if (ctlr->transfer == spi_queued_transfer) { 38268c2ecf20Sopenharmony_ci spin_lock_irqsave(&ctlr->bus_lock_spinlock, flags); 38278c2ecf20Sopenharmony_ci 38288c2ecf20Sopenharmony_ci trace_spi_message_submit(message); 38298c2ecf20Sopenharmony_ci 38308c2ecf20Sopenharmony_ci status = __spi_queued_transfer(spi, message, false); 38318c2ecf20Sopenharmony_ci 38328c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->bus_lock_spinlock, flags); 38338c2ecf20Sopenharmony_ci } else { 38348c2ecf20Sopenharmony_ci status = spi_async_locked(spi, message); 38358c2ecf20Sopenharmony_ci } 38368c2ecf20Sopenharmony_ci 38378c2ecf20Sopenharmony_ci if (status == 0) { 38388c2ecf20Sopenharmony_ci /* Push out the messages in the calling context if we 38398c2ecf20Sopenharmony_ci * can. 38408c2ecf20Sopenharmony_ci */ 38418c2ecf20Sopenharmony_ci if (ctlr->transfer == spi_queued_transfer) { 38428c2ecf20Sopenharmony_ci SPI_STATISTICS_INCREMENT_FIELD(&ctlr->statistics, 38438c2ecf20Sopenharmony_ci spi_sync_immediate); 38448c2ecf20Sopenharmony_ci SPI_STATISTICS_INCREMENT_FIELD(&spi->statistics, 38458c2ecf20Sopenharmony_ci spi_sync_immediate); 38468c2ecf20Sopenharmony_ci __spi_pump_messages(ctlr, false); 38478c2ecf20Sopenharmony_ci } 38488c2ecf20Sopenharmony_ci 38498c2ecf20Sopenharmony_ci wait_for_completion(&done); 38508c2ecf20Sopenharmony_ci status = message->status; 38518c2ecf20Sopenharmony_ci } 38528c2ecf20Sopenharmony_ci message->context = NULL; 38538c2ecf20Sopenharmony_ci return status; 38548c2ecf20Sopenharmony_ci} 38558c2ecf20Sopenharmony_ci 38568c2ecf20Sopenharmony_ci/** 38578c2ecf20Sopenharmony_ci * spi_sync - blocking/synchronous SPI data transfers 38588c2ecf20Sopenharmony_ci * @spi: device with which data will be exchanged 38598c2ecf20Sopenharmony_ci * @message: describes the data transfers 38608c2ecf20Sopenharmony_ci * Context: can sleep 38618c2ecf20Sopenharmony_ci * 38628c2ecf20Sopenharmony_ci * This call may only be used from a context that may sleep. The sleep 38638c2ecf20Sopenharmony_ci * is non-interruptible, and has no timeout. Low-overhead controller 38648c2ecf20Sopenharmony_ci * drivers may DMA directly into and out of the message buffers. 38658c2ecf20Sopenharmony_ci * 38668c2ecf20Sopenharmony_ci * Note that the SPI device's chip select is active during the message, 38678c2ecf20Sopenharmony_ci * and then is normally disabled between messages. Drivers for some 38688c2ecf20Sopenharmony_ci * frequently-used devices may want to minimize costs of selecting a chip, 38698c2ecf20Sopenharmony_ci * by leaving it selected in anticipation that the next message will go 38708c2ecf20Sopenharmony_ci * to the same chip. (That may increase power usage.) 38718c2ecf20Sopenharmony_ci * 38728c2ecf20Sopenharmony_ci * Also, the caller is guaranteeing that the memory associated with the 38738c2ecf20Sopenharmony_ci * message will not be freed before this call returns. 38748c2ecf20Sopenharmony_ci * 38758c2ecf20Sopenharmony_ci * Return: zero on success, else a negative error code. 38768c2ecf20Sopenharmony_ci */ 38778c2ecf20Sopenharmony_ciint spi_sync(struct spi_device *spi, struct spi_message *message) 38788c2ecf20Sopenharmony_ci{ 38798c2ecf20Sopenharmony_ci int ret; 38808c2ecf20Sopenharmony_ci 38818c2ecf20Sopenharmony_ci mutex_lock(&spi->controller->bus_lock_mutex); 38828c2ecf20Sopenharmony_ci ret = __spi_sync(spi, message); 38838c2ecf20Sopenharmony_ci mutex_unlock(&spi->controller->bus_lock_mutex); 38848c2ecf20Sopenharmony_ci 38858c2ecf20Sopenharmony_ci return ret; 38868c2ecf20Sopenharmony_ci} 38878c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_sync); 38888c2ecf20Sopenharmony_ci 38898c2ecf20Sopenharmony_ci/** 38908c2ecf20Sopenharmony_ci * spi_sync_locked - version of spi_sync with exclusive bus usage 38918c2ecf20Sopenharmony_ci * @spi: device with which data will be exchanged 38928c2ecf20Sopenharmony_ci * @message: describes the data transfers 38938c2ecf20Sopenharmony_ci * Context: can sleep 38948c2ecf20Sopenharmony_ci * 38958c2ecf20Sopenharmony_ci * This call may only be used from a context that may sleep. The sleep 38968c2ecf20Sopenharmony_ci * is non-interruptible, and has no timeout. Low-overhead controller 38978c2ecf20Sopenharmony_ci * drivers may DMA directly into and out of the message buffers. 38988c2ecf20Sopenharmony_ci * 38998c2ecf20Sopenharmony_ci * This call should be used by drivers that require exclusive access to the 39008c2ecf20Sopenharmony_ci * SPI bus. It has to be preceded by a spi_bus_lock call. The SPI bus must 39018c2ecf20Sopenharmony_ci * be released by a spi_bus_unlock call when the exclusive access is over. 39028c2ecf20Sopenharmony_ci * 39038c2ecf20Sopenharmony_ci * Return: zero on success, else a negative error code. 39048c2ecf20Sopenharmony_ci */ 39058c2ecf20Sopenharmony_ciint spi_sync_locked(struct spi_device *spi, struct spi_message *message) 39068c2ecf20Sopenharmony_ci{ 39078c2ecf20Sopenharmony_ci return __spi_sync(spi, message); 39088c2ecf20Sopenharmony_ci} 39098c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_sync_locked); 39108c2ecf20Sopenharmony_ci 39118c2ecf20Sopenharmony_ci/** 39128c2ecf20Sopenharmony_ci * spi_bus_lock - obtain a lock for exclusive SPI bus usage 39138c2ecf20Sopenharmony_ci * @ctlr: SPI bus master that should be locked for exclusive bus access 39148c2ecf20Sopenharmony_ci * Context: can sleep 39158c2ecf20Sopenharmony_ci * 39168c2ecf20Sopenharmony_ci * This call may only be used from a context that may sleep. The sleep 39178c2ecf20Sopenharmony_ci * is non-interruptible, and has no timeout. 39188c2ecf20Sopenharmony_ci * 39198c2ecf20Sopenharmony_ci * This call should be used by drivers that require exclusive access to the 39208c2ecf20Sopenharmony_ci * SPI bus. The SPI bus must be released by a spi_bus_unlock call when the 39218c2ecf20Sopenharmony_ci * exclusive access is over. Data transfer must be done by spi_sync_locked 39228c2ecf20Sopenharmony_ci * and spi_async_locked calls when the SPI bus lock is held. 39238c2ecf20Sopenharmony_ci * 39248c2ecf20Sopenharmony_ci * Return: always zero. 39258c2ecf20Sopenharmony_ci */ 39268c2ecf20Sopenharmony_ciint spi_bus_lock(struct spi_controller *ctlr) 39278c2ecf20Sopenharmony_ci{ 39288c2ecf20Sopenharmony_ci unsigned long flags; 39298c2ecf20Sopenharmony_ci 39308c2ecf20Sopenharmony_ci mutex_lock(&ctlr->bus_lock_mutex); 39318c2ecf20Sopenharmony_ci 39328c2ecf20Sopenharmony_ci spin_lock_irqsave(&ctlr->bus_lock_spinlock, flags); 39338c2ecf20Sopenharmony_ci ctlr->bus_lock_flag = 1; 39348c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ctlr->bus_lock_spinlock, flags); 39358c2ecf20Sopenharmony_ci 39368c2ecf20Sopenharmony_ci /* mutex remains locked until spi_bus_unlock is called */ 39378c2ecf20Sopenharmony_ci 39388c2ecf20Sopenharmony_ci return 0; 39398c2ecf20Sopenharmony_ci} 39408c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_bus_lock); 39418c2ecf20Sopenharmony_ci 39428c2ecf20Sopenharmony_ci/** 39438c2ecf20Sopenharmony_ci * spi_bus_unlock - release the lock for exclusive SPI bus usage 39448c2ecf20Sopenharmony_ci * @ctlr: SPI bus master that was locked for exclusive bus access 39458c2ecf20Sopenharmony_ci * Context: can sleep 39468c2ecf20Sopenharmony_ci * 39478c2ecf20Sopenharmony_ci * This call may only be used from a context that may sleep. The sleep 39488c2ecf20Sopenharmony_ci * is non-interruptible, and has no timeout. 39498c2ecf20Sopenharmony_ci * 39508c2ecf20Sopenharmony_ci * This call releases an SPI bus lock previously obtained by an spi_bus_lock 39518c2ecf20Sopenharmony_ci * call. 39528c2ecf20Sopenharmony_ci * 39538c2ecf20Sopenharmony_ci * Return: always zero. 39548c2ecf20Sopenharmony_ci */ 39558c2ecf20Sopenharmony_ciint spi_bus_unlock(struct spi_controller *ctlr) 39568c2ecf20Sopenharmony_ci{ 39578c2ecf20Sopenharmony_ci ctlr->bus_lock_flag = 0; 39588c2ecf20Sopenharmony_ci 39598c2ecf20Sopenharmony_ci mutex_unlock(&ctlr->bus_lock_mutex); 39608c2ecf20Sopenharmony_ci 39618c2ecf20Sopenharmony_ci return 0; 39628c2ecf20Sopenharmony_ci} 39638c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_bus_unlock); 39648c2ecf20Sopenharmony_ci 39658c2ecf20Sopenharmony_ci/* portable code must never pass more than 32 bytes */ 39668c2ecf20Sopenharmony_ci#define SPI_BUFSIZ max(32, SMP_CACHE_BYTES) 39678c2ecf20Sopenharmony_ci 39688c2ecf20Sopenharmony_cistatic u8 *buf; 39698c2ecf20Sopenharmony_ci 39708c2ecf20Sopenharmony_ci/** 39718c2ecf20Sopenharmony_ci * spi_write_then_read - SPI synchronous write followed by read 39728c2ecf20Sopenharmony_ci * @spi: device with which data will be exchanged 39738c2ecf20Sopenharmony_ci * @txbuf: data to be written (need not be dma-safe) 39748c2ecf20Sopenharmony_ci * @n_tx: size of txbuf, in bytes 39758c2ecf20Sopenharmony_ci * @rxbuf: buffer into which data will be read (need not be dma-safe) 39768c2ecf20Sopenharmony_ci * @n_rx: size of rxbuf, in bytes 39778c2ecf20Sopenharmony_ci * Context: can sleep 39788c2ecf20Sopenharmony_ci * 39798c2ecf20Sopenharmony_ci * This performs a half duplex MicroWire style transaction with the 39808c2ecf20Sopenharmony_ci * device, sending txbuf and then reading rxbuf. The return value 39818c2ecf20Sopenharmony_ci * is zero for success, else a negative errno status code. 39828c2ecf20Sopenharmony_ci * This call may only be used from a context that may sleep. 39838c2ecf20Sopenharmony_ci * 39848c2ecf20Sopenharmony_ci * Parameters to this routine are always copied using a small buffer. 39858c2ecf20Sopenharmony_ci * Performance-sensitive or bulk transfer code should instead use 39868c2ecf20Sopenharmony_ci * spi_{async,sync}() calls with dma-safe buffers. 39878c2ecf20Sopenharmony_ci * 39888c2ecf20Sopenharmony_ci * Return: zero on success, else a negative error code. 39898c2ecf20Sopenharmony_ci */ 39908c2ecf20Sopenharmony_ciint spi_write_then_read(struct spi_device *spi, 39918c2ecf20Sopenharmony_ci const void *txbuf, unsigned n_tx, 39928c2ecf20Sopenharmony_ci void *rxbuf, unsigned n_rx) 39938c2ecf20Sopenharmony_ci{ 39948c2ecf20Sopenharmony_ci static DEFINE_MUTEX(lock); 39958c2ecf20Sopenharmony_ci 39968c2ecf20Sopenharmony_ci int status; 39978c2ecf20Sopenharmony_ci struct spi_message message; 39988c2ecf20Sopenharmony_ci struct spi_transfer x[2]; 39998c2ecf20Sopenharmony_ci u8 *local_buf; 40008c2ecf20Sopenharmony_ci 40018c2ecf20Sopenharmony_ci /* Use preallocated DMA-safe buffer if we can. We can't avoid 40028c2ecf20Sopenharmony_ci * copying here, (as a pure convenience thing), but we can 40038c2ecf20Sopenharmony_ci * keep heap costs out of the hot path unless someone else is 40048c2ecf20Sopenharmony_ci * using the pre-allocated buffer or the transfer is too large. 40058c2ecf20Sopenharmony_ci */ 40068c2ecf20Sopenharmony_ci if ((n_tx + n_rx) > SPI_BUFSIZ || !mutex_trylock(&lock)) { 40078c2ecf20Sopenharmony_ci local_buf = kmalloc(max((unsigned)SPI_BUFSIZ, n_tx + n_rx), 40088c2ecf20Sopenharmony_ci GFP_KERNEL | GFP_DMA); 40098c2ecf20Sopenharmony_ci if (!local_buf) 40108c2ecf20Sopenharmony_ci return -ENOMEM; 40118c2ecf20Sopenharmony_ci } else { 40128c2ecf20Sopenharmony_ci local_buf = buf; 40138c2ecf20Sopenharmony_ci } 40148c2ecf20Sopenharmony_ci 40158c2ecf20Sopenharmony_ci spi_message_init(&message); 40168c2ecf20Sopenharmony_ci memset(x, 0, sizeof(x)); 40178c2ecf20Sopenharmony_ci if (n_tx) { 40188c2ecf20Sopenharmony_ci x[0].len = n_tx; 40198c2ecf20Sopenharmony_ci spi_message_add_tail(&x[0], &message); 40208c2ecf20Sopenharmony_ci } 40218c2ecf20Sopenharmony_ci if (n_rx) { 40228c2ecf20Sopenharmony_ci x[1].len = n_rx; 40238c2ecf20Sopenharmony_ci spi_message_add_tail(&x[1], &message); 40248c2ecf20Sopenharmony_ci } 40258c2ecf20Sopenharmony_ci 40268c2ecf20Sopenharmony_ci memcpy(local_buf, txbuf, n_tx); 40278c2ecf20Sopenharmony_ci x[0].tx_buf = local_buf; 40288c2ecf20Sopenharmony_ci x[1].rx_buf = local_buf + n_tx; 40298c2ecf20Sopenharmony_ci 40308c2ecf20Sopenharmony_ci /* do the i/o */ 40318c2ecf20Sopenharmony_ci status = spi_sync(spi, &message); 40328c2ecf20Sopenharmony_ci if (status == 0) 40338c2ecf20Sopenharmony_ci memcpy(rxbuf, x[1].rx_buf, n_rx); 40348c2ecf20Sopenharmony_ci 40358c2ecf20Sopenharmony_ci if (x[0].tx_buf == buf) 40368c2ecf20Sopenharmony_ci mutex_unlock(&lock); 40378c2ecf20Sopenharmony_ci else 40388c2ecf20Sopenharmony_ci kfree(local_buf); 40398c2ecf20Sopenharmony_ci 40408c2ecf20Sopenharmony_ci return status; 40418c2ecf20Sopenharmony_ci} 40428c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spi_write_then_read); 40438c2ecf20Sopenharmony_ci 40448c2ecf20Sopenharmony_ci/*-------------------------------------------------------------------------*/ 40458c2ecf20Sopenharmony_ci 40468c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_OF) 40478c2ecf20Sopenharmony_ci/* must call put_device() when done with returned spi_device device */ 40488c2ecf20Sopenharmony_cistruct spi_device *of_find_spi_device_by_node(struct device_node *node) 40498c2ecf20Sopenharmony_ci{ 40508c2ecf20Sopenharmony_ci struct device *dev = bus_find_device_by_of_node(&spi_bus_type, node); 40518c2ecf20Sopenharmony_ci 40528c2ecf20Sopenharmony_ci return dev ? to_spi_device(dev) : NULL; 40538c2ecf20Sopenharmony_ci} 40548c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(of_find_spi_device_by_node); 40558c2ecf20Sopenharmony_ci#endif /* IS_ENABLED(CONFIG_OF) */ 40568c2ecf20Sopenharmony_ci 40578c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_OF_DYNAMIC) 40588c2ecf20Sopenharmony_ci/* the spi controllers are not using spi_bus, so we find it with another way */ 40598c2ecf20Sopenharmony_cistatic struct spi_controller *of_find_spi_controller_by_node(struct device_node *node) 40608c2ecf20Sopenharmony_ci{ 40618c2ecf20Sopenharmony_ci struct device *dev; 40628c2ecf20Sopenharmony_ci 40638c2ecf20Sopenharmony_ci dev = class_find_device_by_of_node(&spi_master_class, node); 40648c2ecf20Sopenharmony_ci if (!dev && IS_ENABLED(CONFIG_SPI_SLAVE)) 40658c2ecf20Sopenharmony_ci dev = class_find_device_by_of_node(&spi_slave_class, node); 40668c2ecf20Sopenharmony_ci if (!dev) 40678c2ecf20Sopenharmony_ci return NULL; 40688c2ecf20Sopenharmony_ci 40698c2ecf20Sopenharmony_ci /* reference got in class_find_device */ 40708c2ecf20Sopenharmony_ci return container_of(dev, struct spi_controller, dev); 40718c2ecf20Sopenharmony_ci} 40728c2ecf20Sopenharmony_ci 40738c2ecf20Sopenharmony_cistatic int of_spi_notify(struct notifier_block *nb, unsigned long action, 40748c2ecf20Sopenharmony_ci void *arg) 40758c2ecf20Sopenharmony_ci{ 40768c2ecf20Sopenharmony_ci struct of_reconfig_data *rd = arg; 40778c2ecf20Sopenharmony_ci struct spi_controller *ctlr; 40788c2ecf20Sopenharmony_ci struct spi_device *spi; 40798c2ecf20Sopenharmony_ci 40808c2ecf20Sopenharmony_ci switch (of_reconfig_get_state_change(action, arg)) { 40818c2ecf20Sopenharmony_ci case OF_RECONFIG_CHANGE_ADD: 40828c2ecf20Sopenharmony_ci ctlr = of_find_spi_controller_by_node(rd->dn->parent); 40838c2ecf20Sopenharmony_ci if (ctlr == NULL) 40848c2ecf20Sopenharmony_ci return NOTIFY_OK; /* not for us */ 40858c2ecf20Sopenharmony_ci 40868c2ecf20Sopenharmony_ci if (of_node_test_and_set_flag(rd->dn, OF_POPULATED)) { 40878c2ecf20Sopenharmony_ci put_device(&ctlr->dev); 40888c2ecf20Sopenharmony_ci return NOTIFY_OK; 40898c2ecf20Sopenharmony_ci } 40908c2ecf20Sopenharmony_ci 40918c2ecf20Sopenharmony_ci spi = of_register_spi_device(ctlr, rd->dn); 40928c2ecf20Sopenharmony_ci put_device(&ctlr->dev); 40938c2ecf20Sopenharmony_ci 40948c2ecf20Sopenharmony_ci if (IS_ERR(spi)) { 40958c2ecf20Sopenharmony_ci pr_err("%s: failed to create for '%pOF'\n", 40968c2ecf20Sopenharmony_ci __func__, rd->dn); 40978c2ecf20Sopenharmony_ci of_node_clear_flag(rd->dn, OF_POPULATED); 40988c2ecf20Sopenharmony_ci return notifier_from_errno(PTR_ERR(spi)); 40998c2ecf20Sopenharmony_ci } 41008c2ecf20Sopenharmony_ci break; 41018c2ecf20Sopenharmony_ci 41028c2ecf20Sopenharmony_ci case OF_RECONFIG_CHANGE_REMOVE: 41038c2ecf20Sopenharmony_ci /* already depopulated? */ 41048c2ecf20Sopenharmony_ci if (!of_node_check_flag(rd->dn, OF_POPULATED)) 41058c2ecf20Sopenharmony_ci return NOTIFY_OK; 41068c2ecf20Sopenharmony_ci 41078c2ecf20Sopenharmony_ci /* find our device by node */ 41088c2ecf20Sopenharmony_ci spi = of_find_spi_device_by_node(rd->dn); 41098c2ecf20Sopenharmony_ci if (spi == NULL) 41108c2ecf20Sopenharmony_ci return NOTIFY_OK; /* no? not meant for us */ 41118c2ecf20Sopenharmony_ci 41128c2ecf20Sopenharmony_ci /* unregister takes one ref away */ 41138c2ecf20Sopenharmony_ci spi_unregister_device(spi); 41148c2ecf20Sopenharmony_ci 41158c2ecf20Sopenharmony_ci /* and put the reference of the find */ 41168c2ecf20Sopenharmony_ci put_device(&spi->dev); 41178c2ecf20Sopenharmony_ci break; 41188c2ecf20Sopenharmony_ci } 41198c2ecf20Sopenharmony_ci 41208c2ecf20Sopenharmony_ci return NOTIFY_OK; 41218c2ecf20Sopenharmony_ci} 41228c2ecf20Sopenharmony_ci 41238c2ecf20Sopenharmony_cistatic struct notifier_block spi_of_notifier = { 41248c2ecf20Sopenharmony_ci .notifier_call = of_spi_notify, 41258c2ecf20Sopenharmony_ci}; 41268c2ecf20Sopenharmony_ci#else /* IS_ENABLED(CONFIG_OF_DYNAMIC) */ 41278c2ecf20Sopenharmony_ciextern struct notifier_block spi_of_notifier; 41288c2ecf20Sopenharmony_ci#endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */ 41298c2ecf20Sopenharmony_ci 41308c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_ACPI) 41318c2ecf20Sopenharmony_cistatic int spi_acpi_controller_match(struct device *dev, const void *data) 41328c2ecf20Sopenharmony_ci{ 41338c2ecf20Sopenharmony_ci return ACPI_COMPANION(dev->parent) == data; 41348c2ecf20Sopenharmony_ci} 41358c2ecf20Sopenharmony_ci 41368c2ecf20Sopenharmony_cistatic struct spi_controller *acpi_spi_find_controller_by_adev(struct acpi_device *adev) 41378c2ecf20Sopenharmony_ci{ 41388c2ecf20Sopenharmony_ci struct device *dev; 41398c2ecf20Sopenharmony_ci 41408c2ecf20Sopenharmony_ci dev = class_find_device(&spi_master_class, NULL, adev, 41418c2ecf20Sopenharmony_ci spi_acpi_controller_match); 41428c2ecf20Sopenharmony_ci if (!dev && IS_ENABLED(CONFIG_SPI_SLAVE)) 41438c2ecf20Sopenharmony_ci dev = class_find_device(&spi_slave_class, NULL, adev, 41448c2ecf20Sopenharmony_ci spi_acpi_controller_match); 41458c2ecf20Sopenharmony_ci if (!dev) 41468c2ecf20Sopenharmony_ci return NULL; 41478c2ecf20Sopenharmony_ci 41488c2ecf20Sopenharmony_ci return container_of(dev, struct spi_controller, dev); 41498c2ecf20Sopenharmony_ci} 41508c2ecf20Sopenharmony_ci 41518c2ecf20Sopenharmony_cistatic struct spi_device *acpi_spi_find_device_by_adev(struct acpi_device *adev) 41528c2ecf20Sopenharmony_ci{ 41538c2ecf20Sopenharmony_ci struct device *dev; 41548c2ecf20Sopenharmony_ci 41558c2ecf20Sopenharmony_ci dev = bus_find_device_by_acpi_dev(&spi_bus_type, adev); 41568c2ecf20Sopenharmony_ci return to_spi_device(dev); 41578c2ecf20Sopenharmony_ci} 41588c2ecf20Sopenharmony_ci 41598c2ecf20Sopenharmony_cistatic int acpi_spi_notify(struct notifier_block *nb, unsigned long value, 41608c2ecf20Sopenharmony_ci void *arg) 41618c2ecf20Sopenharmony_ci{ 41628c2ecf20Sopenharmony_ci struct acpi_device *adev = arg; 41638c2ecf20Sopenharmony_ci struct spi_controller *ctlr; 41648c2ecf20Sopenharmony_ci struct spi_device *spi; 41658c2ecf20Sopenharmony_ci 41668c2ecf20Sopenharmony_ci switch (value) { 41678c2ecf20Sopenharmony_ci case ACPI_RECONFIG_DEVICE_ADD: 41688c2ecf20Sopenharmony_ci ctlr = acpi_spi_find_controller_by_adev(adev->parent); 41698c2ecf20Sopenharmony_ci if (!ctlr) 41708c2ecf20Sopenharmony_ci break; 41718c2ecf20Sopenharmony_ci 41728c2ecf20Sopenharmony_ci acpi_register_spi_device(ctlr, adev); 41738c2ecf20Sopenharmony_ci put_device(&ctlr->dev); 41748c2ecf20Sopenharmony_ci break; 41758c2ecf20Sopenharmony_ci case ACPI_RECONFIG_DEVICE_REMOVE: 41768c2ecf20Sopenharmony_ci if (!acpi_device_enumerated(adev)) 41778c2ecf20Sopenharmony_ci break; 41788c2ecf20Sopenharmony_ci 41798c2ecf20Sopenharmony_ci spi = acpi_spi_find_device_by_adev(adev); 41808c2ecf20Sopenharmony_ci if (!spi) 41818c2ecf20Sopenharmony_ci break; 41828c2ecf20Sopenharmony_ci 41838c2ecf20Sopenharmony_ci spi_unregister_device(spi); 41848c2ecf20Sopenharmony_ci put_device(&spi->dev); 41858c2ecf20Sopenharmony_ci break; 41868c2ecf20Sopenharmony_ci } 41878c2ecf20Sopenharmony_ci 41888c2ecf20Sopenharmony_ci return NOTIFY_OK; 41898c2ecf20Sopenharmony_ci} 41908c2ecf20Sopenharmony_ci 41918c2ecf20Sopenharmony_cistatic struct notifier_block spi_acpi_notifier = { 41928c2ecf20Sopenharmony_ci .notifier_call = acpi_spi_notify, 41938c2ecf20Sopenharmony_ci}; 41948c2ecf20Sopenharmony_ci#else 41958c2ecf20Sopenharmony_ciextern struct notifier_block spi_acpi_notifier; 41968c2ecf20Sopenharmony_ci#endif 41978c2ecf20Sopenharmony_ci 41988c2ecf20Sopenharmony_cistatic int __init spi_init(void) 41998c2ecf20Sopenharmony_ci{ 42008c2ecf20Sopenharmony_ci int status; 42018c2ecf20Sopenharmony_ci 42028c2ecf20Sopenharmony_ci buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL); 42038c2ecf20Sopenharmony_ci if (!buf) { 42048c2ecf20Sopenharmony_ci status = -ENOMEM; 42058c2ecf20Sopenharmony_ci goto err0; 42068c2ecf20Sopenharmony_ci } 42078c2ecf20Sopenharmony_ci 42088c2ecf20Sopenharmony_ci status = bus_register(&spi_bus_type); 42098c2ecf20Sopenharmony_ci if (status < 0) 42108c2ecf20Sopenharmony_ci goto err1; 42118c2ecf20Sopenharmony_ci 42128c2ecf20Sopenharmony_ci status = class_register(&spi_master_class); 42138c2ecf20Sopenharmony_ci if (status < 0) 42148c2ecf20Sopenharmony_ci goto err2; 42158c2ecf20Sopenharmony_ci 42168c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_SPI_SLAVE)) { 42178c2ecf20Sopenharmony_ci status = class_register(&spi_slave_class); 42188c2ecf20Sopenharmony_ci if (status < 0) 42198c2ecf20Sopenharmony_ci goto err3; 42208c2ecf20Sopenharmony_ci } 42218c2ecf20Sopenharmony_ci 42228c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_OF_DYNAMIC)) 42238c2ecf20Sopenharmony_ci WARN_ON(of_reconfig_notifier_register(&spi_of_notifier)); 42248c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_ACPI)) 42258c2ecf20Sopenharmony_ci WARN_ON(acpi_reconfig_notifier_register(&spi_acpi_notifier)); 42268c2ecf20Sopenharmony_ci 42278c2ecf20Sopenharmony_ci return 0; 42288c2ecf20Sopenharmony_ci 42298c2ecf20Sopenharmony_cierr3: 42308c2ecf20Sopenharmony_ci class_unregister(&spi_master_class); 42318c2ecf20Sopenharmony_cierr2: 42328c2ecf20Sopenharmony_ci bus_unregister(&spi_bus_type); 42338c2ecf20Sopenharmony_cierr1: 42348c2ecf20Sopenharmony_ci kfree(buf); 42358c2ecf20Sopenharmony_ci buf = NULL; 42368c2ecf20Sopenharmony_cierr0: 42378c2ecf20Sopenharmony_ci return status; 42388c2ecf20Sopenharmony_ci} 42398c2ecf20Sopenharmony_ci 42408c2ecf20Sopenharmony_ci/* board_info is normally registered in arch_initcall(), 42418c2ecf20Sopenharmony_ci * but even essential drivers wait till later 42428c2ecf20Sopenharmony_ci * 42438c2ecf20Sopenharmony_ci * REVISIT only boardinfo really needs static linking. the rest (device and 42448c2ecf20Sopenharmony_ci * driver registration) _could_ be dynamically linked (modular) ... costs 42458c2ecf20Sopenharmony_ci * include needing to have boardinfo data structures be much more public. 42468c2ecf20Sopenharmony_ci */ 42478c2ecf20Sopenharmony_cipostcore_initcall(spi_init); 4248