// SPDX-License-Identifier: GPL-2.0 // // STMicroelectronics STM32 SPI Controller driver // // Copyright (C) 2017, STMicroelectronics - All Rights Reserved // Author(s): Amelie Delaunay <[email protected]> for STMicroelectronics. #include <linux/bitfield.h> #include <linux/debugfs.h> #include <linux/clk.h> #include <linux/delay.h> #include <linux/dmaengine.h> #include <linux/interrupt.h> #include <linux/iopoll.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pinctrl/consumer.h> #include <linux/pm_runtime.h> #include <linux/reset.h> #include <linux/spi/spi.h> #define DRIVER_NAME … /* STM32F4/7 SPI registers */ #define STM32FX_SPI_CR1 … #define STM32FX_SPI_CR2 … #define STM32FX_SPI_SR … #define STM32FX_SPI_DR … #define STM32FX_SPI_I2SCFGR … /* STM32FX_SPI_CR1 bit fields */ #define STM32FX_SPI_CR1_CPHA … #define STM32FX_SPI_CR1_CPOL … #define STM32FX_SPI_CR1_MSTR … #define STM32FX_SPI_CR1_BR_SHIFT … #define STM32FX_SPI_CR1_BR … #define STM32FX_SPI_CR1_SPE … #define STM32FX_SPI_CR1_LSBFRST … #define STM32FX_SPI_CR1_SSI … #define STM32FX_SPI_CR1_SSM … #define STM32FX_SPI_CR1_RXONLY … #define STM32F4_SPI_CR1_DFF … #define STM32F7_SPI_CR1_CRCL … #define STM32FX_SPI_CR1_CRCNEXT … #define STM32FX_SPI_CR1_CRCEN … #define STM32FX_SPI_CR1_BIDIOE … #define STM32FX_SPI_CR1_BIDIMODE … #define STM32FX_SPI_CR1_BR_MIN … #define STM32FX_SPI_CR1_BR_MAX … /* STM32FX_SPI_CR2 bit fields */ #define STM32FX_SPI_CR2_RXDMAEN … #define STM32FX_SPI_CR2_TXDMAEN … #define STM32FX_SPI_CR2_SSOE … #define STM32FX_SPI_CR2_FRF … #define STM32FX_SPI_CR2_ERRIE … #define STM32FX_SPI_CR2_RXNEIE … #define STM32FX_SPI_CR2_TXEIE … #define STM32F7_SPI_CR2_DS … #define STM32F7_SPI_CR2_FRXTH … #define STM32F7_SPI_CR2_LDMA_RX … #define STM32F7_SPI_CR2_LDMA_TX … /* STM32FX_SPI_SR bit fields */ #define STM32FX_SPI_SR_RXNE … #define STM32FX_SPI_SR_TXE … #define STM32FX_SPI_SR_CHSIDE … #define STM32FX_SPI_SR_UDR … #define STM32FX_SPI_SR_CRCERR … #define STM32FX_SPI_SR_MODF … #define STM32FX_SPI_SR_OVR … #define STM32FX_SPI_SR_BSY … #define STM32FX_SPI_SR_FRE … #define STM32F7_SPI_SR_FRLVL … #define STM32F7_SPI_SR_FTLVL … /* STM32FX_SPI_I2SCFGR bit fields */ #define STM32FX_SPI_I2SCFGR_I2SMOD … /* STM32F4 SPI Baud Rate min/max divisor */ #define STM32FX_SPI_BR_DIV_MIN … #define STM32FX_SPI_BR_DIV_MAX … /* STM32H7 SPI registers */ #define STM32H7_SPI_CR1 … #define STM32H7_SPI_CR2 … #define STM32H7_SPI_CFG1 … #define STM32H7_SPI_CFG2 … #define STM32H7_SPI_IER … #define STM32H7_SPI_SR … #define STM32H7_SPI_IFCR … #define STM32H7_SPI_TXDR … #define STM32H7_SPI_RXDR … #define STM32H7_SPI_I2SCFGR … /* STM32H7_SPI_CR1 bit fields */ #define STM32H7_SPI_CR1_SPE … #define STM32H7_SPI_CR1_MASRX … #define STM32H7_SPI_CR1_CSTART … #define STM32H7_SPI_CR1_CSUSP … #define STM32H7_SPI_CR1_HDDIR … #define STM32H7_SPI_CR1_SSI … /* STM32H7_SPI_CR2 bit fields */ #define STM32H7_SPI_CR2_TSIZE … #define STM32H7_SPI_TSIZE_MAX … /* STM32H7_SPI_CFG1 bit fields */ #define STM32H7_SPI_CFG1_DSIZE … #define STM32H7_SPI_CFG1_FTHLV … #define STM32H7_SPI_CFG1_RXDMAEN … #define STM32H7_SPI_CFG1_TXDMAEN … #define STM32H7_SPI_CFG1_MBR … #define STM32H7_SPI_CFG1_MBR_SHIFT … #define STM32H7_SPI_CFG1_MBR_MIN … #define STM32H7_SPI_CFG1_MBR_MAX … /* STM32H7_SPI_CFG2 bit fields */ #define STM32H7_SPI_CFG2_MIDI … #define STM32H7_SPI_CFG2_COMM … #define STM32H7_SPI_CFG2_SP … #define STM32H7_SPI_CFG2_MASTER … #define STM32H7_SPI_CFG2_LSBFRST … #define STM32H7_SPI_CFG2_CPHA … #define STM32H7_SPI_CFG2_CPOL … #define STM32H7_SPI_CFG2_SSM … #define STM32H7_SPI_CFG2_SSIOP … #define STM32H7_SPI_CFG2_AFCNTR … /* STM32H7_SPI_IER bit fields */ #define STM32H7_SPI_IER_RXPIE … #define STM32H7_SPI_IER_TXPIE … #define STM32H7_SPI_IER_DXPIE … #define STM32H7_SPI_IER_EOTIE … #define STM32H7_SPI_IER_TXTFIE … #define STM32H7_SPI_IER_OVRIE … #define STM32H7_SPI_IER_MODFIE … #define STM32H7_SPI_IER_ALL … /* STM32H7_SPI_SR bit fields */ #define STM32H7_SPI_SR_RXP … #define STM32H7_SPI_SR_TXP … #define STM32H7_SPI_SR_EOT … #define STM32H7_SPI_SR_OVR … #define STM32H7_SPI_SR_MODF … #define STM32H7_SPI_SR_SUSP … #define STM32H7_SPI_SR_RXPLVL … #define STM32H7_SPI_SR_RXWNE … /* STM32H7_SPI_IFCR bit fields */ #define STM32H7_SPI_IFCR_ALL … /* STM32H7_SPI_I2SCFGR bit fields */ #define STM32H7_SPI_I2SCFGR_I2SMOD … /* STM32MP25 SPI registers bit fields */ #define STM32MP25_SPI_HWCFGR1 … /* STM32MP25_SPI_CR2 bit fields */ #define STM32MP25_SPI_TSIZE_MAX_LIMITED … /* STM32MP25_SPI_HWCFGR1 */ #define STM32MP25_SPI_HWCFGR1_FULLCFG … #define STM32MP25_SPI_HWCFGR1_FULLCFG_LIMITED … #define STM32MP25_SPI_HWCFGR1_FULLCFG_FULL … #define STM32MP25_SPI_HWCFGR1_DSCFG … #define STM32MP25_SPI_HWCFGR1_DSCFG_16_B … #define STM32MP25_SPI_HWCFGR1_DSCFG_32_B … /* STM32H7 SPI Master Baud Rate min/max divisor */ #define STM32H7_SPI_MBR_DIV_MIN … #define STM32H7_SPI_MBR_DIV_MAX … /* STM32H7 SPI Communication mode */ #define STM32H7_SPI_FULL_DUPLEX … #define STM32H7_SPI_SIMPLEX_TX … #define STM32H7_SPI_SIMPLEX_RX … #define STM32H7_SPI_HALF_DUPLEX … /* SPI Communication type */ #define SPI_FULL_DUPLEX … #define SPI_SIMPLEX_TX … #define SPI_SIMPLEX_RX … #define SPI_3WIRE_TX … #define SPI_3WIRE_RX … #define STM32_SPI_AUTOSUSPEND_DELAY … /* * use PIO for small transfers, avoiding DMA setup/teardown overhead for drivers * without fifo buffers. */ #define SPI_DMA_MIN_BYTES … /* STM32 SPI driver helpers */ #define STM32_SPI_HOST_MODE(stm32_spi) … #define STM32_SPI_DEVICE_MODE(stm32_spi) … /** * struct stm32_spi_reg - stm32 SPI register & bitfield desc * @reg: register offset * @mask: bitfield mask * @shift: left shift */ struct stm32_spi_reg { … }; /** * struct stm32_spi_regspec - stm32 registers definition, compatible dependent data * @en: enable register and SPI enable bit * @dma_rx_en: SPI DMA RX enable register end SPI DMA RX enable bit * @dma_tx_en: SPI DMA TX enable register end SPI DMA TX enable bit * @cpol: clock polarity register and polarity bit * @cpha: clock phase register and phase bit * @lsb_first: LSB transmitted first register and bit * @cs_high: chips select active value * @br: baud rate register and bitfields * @rx: SPI RX data register * @tx: SPI TX data register * @fullcfg: SPI full or limited feature set register */ struct stm32_spi_regspec { … }; struct stm32_spi; /** * struct stm32_spi_cfg - stm32 compatible configuration data * @regs: registers descriptions * @get_fifo_size: routine to get fifo size * @get_bpw_mask: routine to get bits per word mask * @disable: routine to disable controller * @config: routine to configure controller as SPI Host * @set_bpw: routine to configure registers to for bits per word * @set_mode: routine to configure registers to desired mode * @set_data_idleness: optional routine to configure registers to desired idle * time between frames (if driver has this functionality) * @set_number_of_data: optional routine to configure registers to desired * number of data (if driver has this functionality) * @write_tx: routine to write to transmit register/FIFO * @read_rx: routine to read from receive register/FIFO * @transfer_one_dma_start: routine to start transfer a single spi_transfer * using DMA * @dma_rx_cb: routine to call after DMA RX channel operation is complete * @dma_tx_cb: routine to call after DMA TX channel operation is complete * @transfer_one_irq: routine to configure interrupts for driver * @irq_handler_event: Interrupt handler for SPI controller events * @irq_handler_thread: thread of interrupt handler for SPI controller * @baud_rate_div_min: minimum baud rate divisor * @baud_rate_div_max: maximum baud rate divisor * @has_fifo: boolean to know if fifo is used for driver * @has_device_mode: is this compatible capable to switch on device mode * @flags: compatible specific SPI controller flags used at registration time * @prevent_dma_burst: boolean to indicate to prevent DMA burst */ struct stm32_spi_cfg { … }; /** * struct stm32_spi - private data of the SPI controller * @dev: driver model representation of the controller * @ctrl: controller interface * @cfg: compatible configuration data * @base: virtual memory area * @clk: hw kernel clock feeding the SPI clock generator * @clk_rate: rate of the hw kernel clock feeding the SPI clock generator * @lock: prevent I/O concurrent access * @irq: SPI controller interrupt line * @fifo_size: size of the embedded fifo in bytes * @t_size_max: maximum number of data of one transfer * @feature_set: SPI full or limited feature set * @cur_midi: host inter-data idleness in ns * @cur_speed: speed configured in Hz * @cur_half_period: time of a half bit in us * @cur_bpw: number of bits in a single SPI data frame * @cur_fthlv: fifo threshold level (data frames in a single data packet) * @cur_comm: SPI communication mode * @cur_xferlen: current transfer length in bytes * @cur_usedma: boolean to know if dma is used in current transfer * @tx_buf: data to be written, or NULL * @rx_buf: data to be read, or NULL * @tx_len: number of data to be written in bytes * @rx_len: number of data to be read in bytes * @dma_tx: dma channel for TX transfer * @dma_rx: dma channel for RX transfer * @phys_addr: SPI registers physical base address * @device_mode: the controller is configured as SPI device */ struct stm32_spi { … }; static const struct stm32_spi_regspec stm32fx_spi_regspec = …; static const struct stm32_spi_regspec stm32h7_spi_regspec = …; static const struct stm32_spi_regspec stm32mp25_spi_regspec = …; static inline void stm32_spi_set_bits(struct stm32_spi *spi, u32 offset, u32 bits) { … } static inline void stm32_spi_clr_bits(struct stm32_spi *spi, u32 offset, u32 bits) { … } /** * stm32h7_spi_get_fifo_size - Return fifo size * @spi: pointer to the spi controller data structure */ static int stm32h7_spi_get_fifo_size(struct stm32_spi *spi) { … } /** * stm32f4_spi_get_bpw_mask - Return bits per word mask * @spi: pointer to the spi controller data structure */ static int stm32f4_spi_get_bpw_mask(struct stm32_spi *spi) { … } /** * stm32f7_spi_get_bpw_mask - Return bits per word mask * @spi: pointer to the spi controller data structure */ static int stm32f7_spi_get_bpw_mask(struct stm32_spi *spi) { … } /** * stm32h7_spi_get_bpw_mask - Return bits per word mask * @spi: pointer to the spi controller data structure */ static int stm32h7_spi_get_bpw_mask(struct stm32_spi *spi) { … } /** * stm32mp25_spi_get_bpw_mask - Return bits per word mask * @spi: pointer to the spi controller data structure */ static int stm32mp25_spi_get_bpw_mask(struct stm32_spi *spi) { … } /** * stm32_spi_prepare_mbr - Determine baud rate divisor value * @spi: pointer to the spi controller data structure * @speed_hz: requested speed * @min_div: minimum baud rate divisor * @max_div: maximum baud rate divisor * * Return baud rate divisor value in case of success or -EINVAL */ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz, u32 min_div, u32 max_div) { … } /** * stm32h7_spi_prepare_fthlv - Determine FIFO threshold level * @spi: pointer to the spi controller data structure * @xfer_len: length of the message to be transferred */ static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi, u32 xfer_len) { … } /** * stm32f4_spi_write_tx - Write bytes to Transmit Data Register * @spi: pointer to the spi controller data structure * * Read from tx_buf depends on remaining bytes to avoid to read beyond * tx_buf end. */ static void stm32f4_spi_write_tx(struct stm32_spi *spi) { … } /** * stm32f7_spi_write_tx - Write bytes to Transmit Data Register * @spi: pointer to the spi controller data structure * * Read from tx_buf depends on remaining bytes to avoid to read beyond * tx_buf end. */ static void stm32f7_spi_write_tx(struct stm32_spi *spi) { … } /** * stm32h7_spi_write_txfifo - Write bytes in Transmit Data Register * @spi: pointer to the spi controller data structure * * Read from tx_buf depends on remaining bytes to avoid to read beyond * tx_buf end. */ static void stm32h7_spi_write_txfifo(struct stm32_spi *spi) { … } /** * stm32f4_spi_read_rx - Read bytes from Receive Data Register * @spi: pointer to the spi controller data structure * * Write in rx_buf depends on remaining bytes to avoid to write beyond * rx_buf end. */ static void stm32f4_spi_read_rx(struct stm32_spi *spi) { … } /** * stm32f7_spi_read_rx - Read bytes from Receive Data Register * @spi: pointer to the spi controller data structure * * Write in rx_buf depends on remaining bytes to avoid to write beyond * rx_buf end. */ static void stm32f7_spi_read_rx(struct stm32_spi *spi) { … } /** * stm32h7_spi_read_rxfifo - Read bytes in Receive Data Register * @spi: pointer to the spi controller data structure * * Write in rx_buf depends on remaining bytes to avoid to write beyond * rx_buf end. */ static void stm32h7_spi_read_rxfifo(struct stm32_spi *spi) { … } /** * stm32_spi_enable - Enable SPI controller * @spi: pointer to the spi controller data structure */ static void stm32_spi_enable(struct stm32_spi *spi) { … } /** * stm32fx_spi_disable - Disable SPI controller * @spi: pointer to the spi controller data structure */ static void stm32fx_spi_disable(struct stm32_spi *spi) { … } /** * stm32h7_spi_disable - Disable SPI controller * @spi: pointer to the spi controller data structure * * RX-Fifo is flushed when SPI controller is disabled. */ static void stm32h7_spi_disable(struct stm32_spi *spi) { … } /** * stm32_spi_can_dma - Determine if the transfer is eligible for DMA use * @ctrl: controller interface * @spi_dev: pointer to the spi device * @transfer: pointer to spi transfer * * If driver has fifo and the current transfer size is greater than fifo size, * use DMA. Otherwise use DMA for transfer longer than defined DMA min bytes. */ static bool stm32_spi_can_dma(struct spi_controller *ctrl, struct spi_device *spi_dev, struct spi_transfer *transfer) { … } /** * stm32fx_spi_irq_event - Interrupt handler for SPI controller events * @irq: interrupt line * @dev_id: SPI controller ctrl interface */ static irqreturn_t stm32fx_spi_irq_event(int irq, void *dev_id) { … } /** * stm32fx_spi_irq_thread - Thread of interrupt handler for SPI controller * @irq: interrupt line * @dev_id: SPI controller interface */ static irqreturn_t stm32fx_spi_irq_thread(int irq, void *dev_id) { … } /** * stm32h7_spi_irq_thread - Thread of interrupt handler for SPI controller * @irq: interrupt line * @dev_id: SPI controller interface */ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id) { … } static int stm32_spi_optimize_message(struct spi_message *msg) { … } /** * stm32_spi_prepare_msg - set up the controller to transfer a single message * @ctrl: controller interface * @msg: pointer to spi message */ static int stm32_spi_prepare_msg(struct spi_controller *ctrl, struct spi_message *msg) { … } /** * stm32fx_spi_dma_tx_cb - dma callback * @data: pointer to the spi controller data structure * * DMA callback is called when the transfer is complete for DMA TX channel. */ static void stm32fx_spi_dma_tx_cb(void *data) { … } /** * stm32_spi_dma_rx_cb - dma callback * @data: pointer to the spi controller data structure * * DMA callback is called when the transfer is complete for DMA RX channel. */ static void stm32_spi_dma_rx_cb(void *data) { … } /** * stm32_spi_dma_config - configure dma slave channel depending on current * transfer bits_per_word. * @spi: pointer to the spi controller data structure * @dma_chan: pointer to the DMA channel * @dma_conf: pointer to the dma_slave_config structure * @dir: direction of the dma transfer */ static void stm32_spi_dma_config(struct stm32_spi *spi, struct dma_chan *dma_chan, struct dma_slave_config *dma_conf, enum dma_transfer_direction dir) { … } /** * stm32fx_spi_transfer_one_irq - transfer a single spi_transfer using * interrupts * @spi: pointer to the spi controller data structure * * It must returns 0 if the transfer is finished or 1 if the transfer is still * in progress. */ static int stm32fx_spi_transfer_one_irq(struct stm32_spi *spi) { … } /** * stm32h7_spi_transfer_one_irq - transfer a single spi_transfer using * interrupts * @spi: pointer to the spi controller data structure * * It must returns 0 if the transfer is finished or 1 if the transfer is still * in progress. */ static int stm32h7_spi_transfer_one_irq(struct stm32_spi *spi) { … } /** * stm32fx_spi_transfer_one_dma_start - Set SPI driver registers to start * transfer using DMA * @spi: pointer to the spi controller data structure */ static void stm32fx_spi_transfer_one_dma_start(struct stm32_spi *spi) { … } /** * stm32f7_spi_transfer_one_dma_start - Set SPI driver registers to start * transfer using DMA * @spi: pointer to the spi controller data structure */ static void stm32f7_spi_transfer_one_dma_start(struct stm32_spi *spi) { … } /** * stm32h7_spi_transfer_one_dma_start - Set SPI driver registers to start * transfer using DMA * @spi: pointer to the spi controller data structure */ static void stm32h7_spi_transfer_one_dma_start(struct stm32_spi *spi) { … } /** * stm32_spi_transfer_one_dma - transfer a single spi_transfer using DMA * @spi: pointer to the spi controller data structure * @xfer: pointer to the spi_transfer structure * * It must returns 0 if the transfer is finished or 1 if the transfer is still * in progress. */ static int stm32_spi_transfer_one_dma(struct stm32_spi *spi, struct spi_transfer *xfer) { … } /** * stm32f4_spi_set_bpw - Configure bits per word * @spi: pointer to the spi controller data structure */ static void stm32f4_spi_set_bpw(struct stm32_spi *spi) { … } /** * stm32f7_spi_set_bpw - Configure bits per word * @spi: pointer to the spi controller data structure */ static void stm32f7_spi_set_bpw(struct stm32_spi *spi) { … } /** * stm32h7_spi_set_bpw - configure bits per word * @spi: pointer to the spi controller data structure */ static void stm32h7_spi_set_bpw(struct stm32_spi *spi) { … } /** * stm32_spi_set_mbr - Configure baud rate divisor in host mode * @spi: pointer to the spi controller data structure * @mbrdiv: baud rate divisor value */ static void stm32_spi_set_mbr(struct stm32_spi *spi, u32 mbrdiv) { … } /** * stm32_spi_communication_type - return transfer communication type * @spi_dev: pointer to the spi device * @transfer: pointer to spi transfer */ static unsigned int stm32_spi_communication_type(struct spi_device *spi_dev, struct spi_transfer *transfer) { … } /** * stm32fx_spi_set_mode - configure communication mode * @spi: pointer to the spi controller data structure * @comm_type: type of communication to configure */ static int stm32fx_spi_set_mode(struct stm32_spi *spi, unsigned int comm_type) { … } /** * stm32h7_spi_set_mode - configure communication mode * @spi: pointer to the spi controller data structure * @comm_type: type of communication to configure */ static int stm32h7_spi_set_mode(struct stm32_spi *spi, unsigned int comm_type) { … } /** * stm32h7_spi_data_idleness - configure minimum time delay inserted between two * consecutive data frames in host mode * @spi: pointer to the spi controller data structure * @len: transfer len */ static void stm32h7_spi_data_idleness(struct stm32_spi *spi, u32 len) { … } /** * stm32h7_spi_number_of_data - configure number of data at current transfer * @spi: pointer to the spi controller data structure * @nb_words: transfer length (in words) */ static int stm32h7_spi_number_of_data(struct stm32_spi *spi, u32 nb_words) { … } /** * stm32_spi_transfer_one_setup - common setup to transfer a single * spi_transfer either using DMA or * interrupts. * @spi: pointer to the spi controller data structure * @spi_dev: pointer to the spi device * @transfer: pointer to spi transfer */ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi, struct spi_device *spi_dev, struct spi_transfer *transfer) { … } /** * stm32_spi_transfer_one - transfer a single spi_transfer * @ctrl: controller interface * @spi_dev: pointer to the spi device * @transfer: pointer to spi transfer * * It must return 0 if the transfer is finished or 1 if the transfer is still * in progress. */ static int stm32_spi_transfer_one(struct spi_controller *ctrl, struct spi_device *spi_dev, struct spi_transfer *transfer) { … } /** * stm32_spi_unprepare_msg - relax the hardware * @ctrl: controller interface * @msg: pointer to the spi message */ static int stm32_spi_unprepare_msg(struct spi_controller *ctrl, struct spi_message *msg) { … } /** * stm32fx_spi_config - Configure SPI controller as SPI host * @spi: pointer to the spi controller data structure */ static int stm32fx_spi_config(struct stm32_spi *spi) { … } /** * stm32h7_spi_config - Configure SPI controller * @spi: pointer to the spi controller data structure */ static int stm32h7_spi_config(struct stm32_spi *spi) { … } static const struct stm32_spi_cfg stm32f4_spi_cfg = …; static const struct stm32_spi_cfg stm32f7_spi_cfg = …; static const struct stm32_spi_cfg stm32h7_spi_cfg = …; /* * STM32MP2 is compatible with the STM32H7 except: * - enforce the DMA maxburst value to 1 * - spi8 have limited feature set (TSIZE_MAX = 1024, BPW of 8 OR 16) */ static const struct stm32_spi_cfg stm32mp25_spi_cfg = …; static const struct of_device_id stm32_spi_of_match[] = …; MODULE_DEVICE_TABLE(of, stm32_spi_of_match); static int stm32h7_spi_device_abort(struct spi_controller *ctrl) { … } static int stm32_spi_probe(struct platform_device *pdev) { … } static void stm32_spi_remove(struct platform_device *pdev) { … } static int __maybe_unused stm32_spi_runtime_suspend(struct device *dev) { … } static int __maybe_unused stm32_spi_runtime_resume(struct device *dev) { … } static int __maybe_unused stm32_spi_suspend(struct device *dev) { … } static int __maybe_unused stm32_spi_resume(struct device *dev) { … } static const struct dev_pm_ops stm32_spi_pm_ops = …; static struct platform_driver stm32_spi_driver = …; module_platform_driver(…) …; MODULE_ALIAS(…) …; MODULE_DESCRIPTION(…) …; MODULE_AUTHOR(…) …; MODULE_LICENSE(…) …;