Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'spi-fix-v6.7-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi fixes from Mark Brown:
"A couple of fixes that came in during the merge window: one Kconfig
dependency fix and another fix for a long standing issue where a sync
transfer races with system suspend"

* tag 'spi-fix-v6.7-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
spi: Fix null dereference on suspend
spi: spi-zynq-qspi: add spi-mem to driver kconfig dependencies

+41 -17
+1
drivers/spi/Kconfig
··· 1169 1169 config SPI_ZYNQ_QSPI 1170 1170 tristate "Xilinx Zynq QSPI controller" 1171 1171 depends on ARCH_ZYNQ || COMPILE_TEST 1172 + depends on SPI_MEM 1172 1173 help 1173 1174 This enables support for the Zynq Quad SPI controller 1174 1175 in master mode.
+39 -17
drivers/spi/spi.c
··· 3317 3317 } 3318 3318 EXPORT_SYMBOL_GPL(spi_unregister_controller); 3319 3319 3320 + static inline int __spi_check_suspended(const struct spi_controller *ctlr) 3321 + { 3322 + return ctlr->flags & SPI_CONTROLLER_SUSPENDED ? -ESHUTDOWN : 0; 3323 + } 3324 + 3325 + static inline void __spi_mark_suspended(struct spi_controller *ctlr) 3326 + { 3327 + mutex_lock(&ctlr->bus_lock_mutex); 3328 + ctlr->flags |= SPI_CONTROLLER_SUSPENDED; 3329 + mutex_unlock(&ctlr->bus_lock_mutex); 3330 + } 3331 + 3332 + static inline void __spi_mark_resumed(struct spi_controller *ctlr) 3333 + { 3334 + mutex_lock(&ctlr->bus_lock_mutex); 3335 + ctlr->flags &= ~SPI_CONTROLLER_SUSPENDED; 3336 + mutex_unlock(&ctlr->bus_lock_mutex); 3337 + } 3338 + 3320 3339 int spi_controller_suspend(struct spi_controller *ctlr) 3321 3340 { 3322 - int ret; 3341 + int ret = 0; 3323 3342 3324 3343 /* Basically no-ops for non-queued controllers */ 3325 - if (!ctlr->queued) 3326 - return 0; 3344 + if (ctlr->queued) { 3345 + ret = spi_stop_queue(ctlr); 3346 + if (ret) 3347 + dev_err(&ctlr->dev, "queue stop failed\n"); 3348 + } 3327 3349 3328 - ret = spi_stop_queue(ctlr); 3329 - if (ret) 3330 - dev_err(&ctlr->dev, "queue stop failed\n"); 3331 - 3350 + __spi_mark_suspended(ctlr); 3332 3351 return ret; 3333 3352 } 3334 3353 EXPORT_SYMBOL_GPL(spi_controller_suspend); 3335 3354 3336 3355 int spi_controller_resume(struct spi_controller *ctlr) 3337 3356 { 3338 - int ret; 3357 + int ret = 0; 3339 3358 3340 - if (!ctlr->queued) 3341 - return 0; 3359 + __spi_mark_resumed(ctlr); 3342 3360 3343 - ret = spi_start_queue(ctlr); 3344 - if (ret) 3345 - dev_err(&ctlr->dev, "queue restart failed\n"); 3346 - 3361 + if (ctlr->queued) { 3362 + ret = spi_start_queue(ctlr); 3363 + if (ret) 3364 + dev_err(&ctlr->dev, "queue restart failed\n"); 3365 + } 3347 3366 return ret; 3348 3367 } 3349 3368 EXPORT_SYMBOL_GPL(spi_controller_resume); ··· 4166 4147 ctlr->cur_msg = msg; 4167 4148 ret = __spi_pump_transfer_message(ctlr, msg, was_busy); 4168 4149 if (ret) 4169 - goto out; 4170 - 4150 + dev_err(&ctlr->dev, "noqueue transfer failed\n"); 4171 4151 ctlr->cur_msg = NULL; 4172 4152 ctlr->fallback = false; 4173 4153 ··· 4182 4164 spi_idle_runtime_pm(ctlr); 4183 4165 } 4184 4166 4185 - out: 4186 4167 mutex_unlock(&ctlr->io_mutex); 4187 4168 } 4188 4169 ··· 4203 4186 DECLARE_COMPLETION_ONSTACK(done); 4204 4187 int status; 4205 4188 struct spi_controller *ctlr = spi->controller; 4189 + 4190 + if (__spi_check_suspended(ctlr)) { 4191 + dev_warn_once(&spi->dev, "Attempted to sync while suspend\n"); 4192 + return -ESHUTDOWN; 4193 + } 4206 4194 4207 4195 status = __spi_validate(spi, message); 4208 4196 if (status != 0)
+1
include/linux/spi/spi.h
··· 566 566 #define SPI_CONTROLLER_MUST_RX BIT(3) /* Requires rx */ 567 567 #define SPI_CONTROLLER_MUST_TX BIT(4) /* Requires tx */ 568 568 #define SPI_CONTROLLER_GPIO_SS BIT(5) /* GPIO CS must select slave */ 569 + #define SPI_CONTROLLER_SUSPENDED BIT(6) /* Currently suspended */ 569 570 570 571 /* Flag indicating if the allocation of this struct is devres-managed */ 571 572 bool devm_allocated;