1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Cadence SPI controller driver (master mode only)
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2008 - 2014 Xilinx, Inc.
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * based on Blackfin On-Chip SPI Driver (spi_bfin5xx.c)
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <linux/clk.h>
11*4882a593Smuzhiyun #include <linux/delay.h>
12*4882a593Smuzhiyun #include <linux/gpio/consumer.h>
13*4882a593Smuzhiyun #include <linux/interrupt.h>
14*4882a593Smuzhiyun #include <linux/io.h>
15*4882a593Smuzhiyun #include <linux/module.h>
16*4882a593Smuzhiyun #include <linux/of_irq.h>
17*4882a593Smuzhiyun #include <linux/of_address.h>
18*4882a593Smuzhiyun #include <linux/platform_device.h>
19*4882a593Smuzhiyun #include <linux/pm_runtime.h>
20*4882a593Smuzhiyun #include <linux/spi/spi.h>
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun /* Name of this driver */
23*4882a593Smuzhiyun #define CDNS_SPI_NAME "cdns-spi"
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun /* Register offset definitions */
26*4882a593Smuzhiyun #define CDNS_SPI_CR 0x00 /* Configuration Register, RW */
27*4882a593Smuzhiyun #define CDNS_SPI_ISR 0x04 /* Interrupt Status Register, RO */
28*4882a593Smuzhiyun #define CDNS_SPI_IER 0x08 /* Interrupt Enable Register, WO */
29*4882a593Smuzhiyun #define CDNS_SPI_IDR 0x0c /* Interrupt Disable Register, WO */
30*4882a593Smuzhiyun #define CDNS_SPI_IMR 0x10 /* Interrupt Enabled Mask Register, RO */
31*4882a593Smuzhiyun #define CDNS_SPI_ER 0x14 /* Enable/Disable Register, RW */
32*4882a593Smuzhiyun #define CDNS_SPI_DR 0x18 /* Delay Register, RW */
33*4882a593Smuzhiyun #define CDNS_SPI_TXD 0x1C /* Data Transmit Register, WO */
34*4882a593Smuzhiyun #define CDNS_SPI_RXD 0x20 /* Data Receive Register, RO */
35*4882a593Smuzhiyun #define CDNS_SPI_SICR 0x24 /* Slave Idle Count Register, RW */
36*4882a593Smuzhiyun #define CDNS_SPI_THLD 0x28 /* Transmit FIFO Watermark Register,RW */
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun #define SPI_AUTOSUSPEND_TIMEOUT 3000
39*4882a593Smuzhiyun /*
40*4882a593Smuzhiyun * SPI Configuration Register bit Masks
41*4882a593Smuzhiyun *
42*4882a593Smuzhiyun * This register contains various control bits that affect the operation
43*4882a593Smuzhiyun * of the SPI controller
44*4882a593Smuzhiyun */
45*4882a593Smuzhiyun #define CDNS_SPI_CR_MANSTRT 0x00010000 /* Manual TX Start */
46*4882a593Smuzhiyun #define CDNS_SPI_CR_CPHA 0x00000004 /* Clock Phase Control */
47*4882a593Smuzhiyun #define CDNS_SPI_CR_CPOL 0x00000002 /* Clock Polarity Control */
48*4882a593Smuzhiyun #define CDNS_SPI_CR_SSCTRL 0x00003C00 /* Slave Select Mask */
49*4882a593Smuzhiyun #define CDNS_SPI_CR_PERI_SEL 0x00000200 /* Peripheral Select Decode */
50*4882a593Smuzhiyun #define CDNS_SPI_CR_BAUD_DIV 0x00000038 /* Baud Rate Divisor Mask */
51*4882a593Smuzhiyun #define CDNS_SPI_CR_MSTREN 0x00000001 /* Master Enable Mask */
52*4882a593Smuzhiyun #define CDNS_SPI_CR_MANSTRTEN 0x00008000 /* Manual TX Enable Mask */
53*4882a593Smuzhiyun #define CDNS_SPI_CR_SSFORCE 0x00004000 /* Manual SS Enable Mask */
54*4882a593Smuzhiyun #define CDNS_SPI_CR_BAUD_DIV_4 0x00000008 /* Default Baud Div Mask */
55*4882a593Smuzhiyun #define CDNS_SPI_CR_DEFAULT (CDNS_SPI_CR_MSTREN | \
56*4882a593Smuzhiyun CDNS_SPI_CR_SSCTRL | \
57*4882a593Smuzhiyun CDNS_SPI_CR_SSFORCE | \
58*4882a593Smuzhiyun CDNS_SPI_CR_BAUD_DIV_4)
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun /*
61*4882a593Smuzhiyun * SPI Configuration Register - Baud rate and slave select
62*4882a593Smuzhiyun *
63*4882a593Smuzhiyun * These are the values used in the calculation of baud rate divisor and
64*4882a593Smuzhiyun * setting the slave select.
65*4882a593Smuzhiyun */
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun #define CDNS_SPI_BAUD_DIV_MAX 7 /* Baud rate divisor maximum */
68*4882a593Smuzhiyun #define CDNS_SPI_BAUD_DIV_MIN 1 /* Baud rate divisor minimum */
69*4882a593Smuzhiyun #define CDNS_SPI_BAUD_DIV_SHIFT 3 /* Baud rate divisor shift in CR */
70*4882a593Smuzhiyun #define CDNS_SPI_SS_SHIFT 10 /* Slave Select field shift in CR */
71*4882a593Smuzhiyun #define CDNS_SPI_SS0 0x1 /* Slave Select zero */
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun /*
74*4882a593Smuzhiyun * SPI Interrupt Registers bit Masks
75*4882a593Smuzhiyun *
76*4882a593Smuzhiyun * All the four interrupt registers (Status/Mask/Enable/Disable) have the same
77*4882a593Smuzhiyun * bit definitions.
78*4882a593Smuzhiyun */
79*4882a593Smuzhiyun #define CDNS_SPI_IXR_TXOW 0x00000004 /* SPI TX FIFO Overwater */
80*4882a593Smuzhiyun #define CDNS_SPI_IXR_MODF 0x00000002 /* SPI Mode Fault */
81*4882a593Smuzhiyun #define CDNS_SPI_IXR_RXNEMTY 0x00000010 /* SPI RX FIFO Not Empty */
82*4882a593Smuzhiyun #define CDNS_SPI_IXR_DEFAULT (CDNS_SPI_IXR_TXOW | \
83*4882a593Smuzhiyun CDNS_SPI_IXR_MODF)
84*4882a593Smuzhiyun #define CDNS_SPI_IXR_TXFULL 0x00000008 /* SPI TX Full */
85*4882a593Smuzhiyun #define CDNS_SPI_IXR_ALL 0x0000007F /* SPI all interrupts */
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun /*
88*4882a593Smuzhiyun * SPI Enable Register bit Masks
89*4882a593Smuzhiyun *
90*4882a593Smuzhiyun * This register is used to enable or disable the SPI controller
91*4882a593Smuzhiyun */
92*4882a593Smuzhiyun #define CDNS_SPI_ER_ENABLE 0x00000001 /* SPI Enable Bit Mask */
93*4882a593Smuzhiyun #define CDNS_SPI_ER_DISABLE 0x0 /* SPI Disable Bit Mask */
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun /* SPI FIFO depth in bytes */
96*4882a593Smuzhiyun #define CDNS_SPI_FIFO_DEPTH 128
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun /* Default number of chip select lines */
99*4882a593Smuzhiyun #define CDNS_SPI_DEFAULT_NUM_CS 4
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun /**
102*4882a593Smuzhiyun * struct cdns_spi - This definition defines spi driver instance
103*4882a593Smuzhiyun * @regs: Virtual address of the SPI controller registers
104*4882a593Smuzhiyun * @ref_clk: Pointer to the peripheral clock
105*4882a593Smuzhiyun * @pclk: Pointer to the APB clock
106*4882a593Smuzhiyun * @speed_hz: Current SPI bus clock speed in Hz
107*4882a593Smuzhiyun * @txbuf: Pointer to the TX buffer
108*4882a593Smuzhiyun * @rxbuf: Pointer to the RX buffer
109*4882a593Smuzhiyun * @tx_bytes: Number of bytes left to transfer
110*4882a593Smuzhiyun * @rx_bytes: Number of bytes requested
111*4882a593Smuzhiyun * @dev_busy: Device busy flag
112*4882a593Smuzhiyun * @is_decoded_cs: Flag for decoder property set or not
113*4882a593Smuzhiyun */
114*4882a593Smuzhiyun struct cdns_spi {
115*4882a593Smuzhiyun void __iomem *regs;
116*4882a593Smuzhiyun struct clk *ref_clk;
117*4882a593Smuzhiyun struct clk *pclk;
118*4882a593Smuzhiyun unsigned int clk_rate;
119*4882a593Smuzhiyun u32 speed_hz;
120*4882a593Smuzhiyun const u8 *txbuf;
121*4882a593Smuzhiyun u8 *rxbuf;
122*4882a593Smuzhiyun int tx_bytes;
123*4882a593Smuzhiyun int rx_bytes;
124*4882a593Smuzhiyun u8 dev_busy;
125*4882a593Smuzhiyun u32 is_decoded_cs;
126*4882a593Smuzhiyun };
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun /* Macros for the SPI controller read/write */
cdns_spi_read(struct cdns_spi * xspi,u32 offset)129*4882a593Smuzhiyun static inline u32 cdns_spi_read(struct cdns_spi *xspi, u32 offset)
130*4882a593Smuzhiyun {
131*4882a593Smuzhiyun return readl_relaxed(xspi->regs + offset);
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun
cdns_spi_write(struct cdns_spi * xspi,u32 offset,u32 val)134*4882a593Smuzhiyun static inline void cdns_spi_write(struct cdns_spi *xspi, u32 offset, u32 val)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun writel_relaxed(val, xspi->regs + offset);
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun /**
140*4882a593Smuzhiyun * cdns_spi_init_hw - Initialize the hardware and configure the SPI controller
141*4882a593Smuzhiyun * @xspi: Pointer to the cdns_spi structure
142*4882a593Smuzhiyun *
143*4882a593Smuzhiyun * On reset the SPI controller is configured to be in master mode, baud rate
144*4882a593Smuzhiyun * divisor is set to 4, threshold value for TX FIFO not full interrupt is set
145*4882a593Smuzhiyun * to 1 and size of the word to be transferred as 8 bit.
146*4882a593Smuzhiyun * This function initializes the SPI controller to disable and clear all the
147*4882a593Smuzhiyun * interrupts, enable manual slave select and manual start, deselect all the
148*4882a593Smuzhiyun * chip select lines, and enable the SPI controller.
149*4882a593Smuzhiyun */
cdns_spi_init_hw(struct cdns_spi * xspi)150*4882a593Smuzhiyun static void cdns_spi_init_hw(struct cdns_spi *xspi)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun u32 ctrl_reg = CDNS_SPI_CR_DEFAULT;
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun if (xspi->is_decoded_cs)
155*4882a593Smuzhiyun ctrl_reg |= CDNS_SPI_CR_PERI_SEL;
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);
158*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_IDR, CDNS_SPI_IXR_ALL);
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun /* Clear the RX FIFO */
161*4882a593Smuzhiyun while (cdns_spi_read(xspi, CDNS_SPI_ISR) & CDNS_SPI_IXR_RXNEMTY)
162*4882a593Smuzhiyun cdns_spi_read(xspi, CDNS_SPI_RXD);
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_ISR, CDNS_SPI_IXR_ALL);
165*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_CR, ctrl_reg);
166*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_ENABLE);
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun /**
170*4882a593Smuzhiyun * cdns_spi_chipselect - Select or deselect the chip select line
171*4882a593Smuzhiyun * @spi: Pointer to the spi_device structure
172*4882a593Smuzhiyun * @is_high: Select(0) or deselect (1) the chip select line
173*4882a593Smuzhiyun */
cdns_spi_chipselect(struct spi_device * spi,bool is_high)174*4882a593Smuzhiyun static void cdns_spi_chipselect(struct spi_device *spi, bool is_high)
175*4882a593Smuzhiyun {
176*4882a593Smuzhiyun struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
177*4882a593Smuzhiyun u32 ctrl_reg;
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun if (is_high) {
182*4882a593Smuzhiyun /* Deselect the slave */
183*4882a593Smuzhiyun ctrl_reg |= CDNS_SPI_CR_SSCTRL;
184*4882a593Smuzhiyun } else {
185*4882a593Smuzhiyun /* Select the slave */
186*4882a593Smuzhiyun ctrl_reg &= ~CDNS_SPI_CR_SSCTRL;
187*4882a593Smuzhiyun if (!(xspi->is_decoded_cs))
188*4882a593Smuzhiyun ctrl_reg |= ((~(CDNS_SPI_SS0 << spi->chip_select)) <<
189*4882a593Smuzhiyun CDNS_SPI_SS_SHIFT) &
190*4882a593Smuzhiyun CDNS_SPI_CR_SSCTRL;
191*4882a593Smuzhiyun else
192*4882a593Smuzhiyun ctrl_reg |= (spi->chip_select << CDNS_SPI_SS_SHIFT) &
193*4882a593Smuzhiyun CDNS_SPI_CR_SSCTRL;
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_CR, ctrl_reg);
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun /**
200*4882a593Smuzhiyun * cdns_spi_config_clock_mode - Sets clock polarity and phase
201*4882a593Smuzhiyun * @spi: Pointer to the spi_device structure
202*4882a593Smuzhiyun *
203*4882a593Smuzhiyun * Sets the requested clock polarity and phase.
204*4882a593Smuzhiyun */
cdns_spi_config_clock_mode(struct spi_device * spi)205*4882a593Smuzhiyun static void cdns_spi_config_clock_mode(struct spi_device *spi)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
208*4882a593Smuzhiyun u32 ctrl_reg, new_ctrl_reg;
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun new_ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);
211*4882a593Smuzhiyun ctrl_reg = new_ctrl_reg;
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun /* Set the SPI clock phase and clock polarity */
214*4882a593Smuzhiyun new_ctrl_reg &= ~(CDNS_SPI_CR_CPHA | CDNS_SPI_CR_CPOL);
215*4882a593Smuzhiyun if (spi->mode & SPI_CPHA)
216*4882a593Smuzhiyun new_ctrl_reg |= CDNS_SPI_CR_CPHA;
217*4882a593Smuzhiyun if (spi->mode & SPI_CPOL)
218*4882a593Smuzhiyun new_ctrl_reg |= CDNS_SPI_CR_CPOL;
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun if (new_ctrl_reg != ctrl_reg) {
221*4882a593Smuzhiyun /*
222*4882a593Smuzhiyun * Just writing the CR register does not seem to apply the clock
223*4882a593Smuzhiyun * setting changes. This is problematic when changing the clock
224*4882a593Smuzhiyun * polarity as it will cause the SPI slave to see spurious clock
225*4882a593Smuzhiyun * transitions. To workaround the issue toggle the ER register.
226*4882a593Smuzhiyun */
227*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);
228*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_CR, new_ctrl_reg);
229*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_ENABLE);
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun /**
234*4882a593Smuzhiyun * cdns_spi_config_clock_freq - Sets clock frequency
235*4882a593Smuzhiyun * @spi: Pointer to the spi_device structure
236*4882a593Smuzhiyun * @transfer: Pointer to the spi_transfer structure which provides
237*4882a593Smuzhiyun * information about next transfer setup parameters
238*4882a593Smuzhiyun *
239*4882a593Smuzhiyun * Sets the requested clock frequency.
240*4882a593Smuzhiyun * Note: If the requested frequency is not an exact match with what can be
241*4882a593Smuzhiyun * obtained using the prescalar value the driver sets the clock frequency which
242*4882a593Smuzhiyun * is lower than the requested frequency (maximum lower) for the transfer. If
243*4882a593Smuzhiyun * the requested frequency is higher or lower than that is supported by the SPI
244*4882a593Smuzhiyun * controller the driver will set the highest or lowest frequency supported by
245*4882a593Smuzhiyun * controller.
246*4882a593Smuzhiyun */
cdns_spi_config_clock_freq(struct spi_device * spi,struct spi_transfer * transfer)247*4882a593Smuzhiyun static void cdns_spi_config_clock_freq(struct spi_device *spi,
248*4882a593Smuzhiyun struct spi_transfer *transfer)
249*4882a593Smuzhiyun {
250*4882a593Smuzhiyun struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
251*4882a593Smuzhiyun u32 ctrl_reg, baud_rate_val;
252*4882a593Smuzhiyun unsigned long frequency;
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun frequency = xspi->clk_rate;
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun /* Set the clock frequency */
259*4882a593Smuzhiyun if (xspi->speed_hz != transfer->speed_hz) {
260*4882a593Smuzhiyun /* first valid value is 1 */
261*4882a593Smuzhiyun baud_rate_val = CDNS_SPI_BAUD_DIV_MIN;
262*4882a593Smuzhiyun while ((baud_rate_val < CDNS_SPI_BAUD_DIV_MAX) &&
263*4882a593Smuzhiyun (frequency / (2 << baud_rate_val)) > transfer->speed_hz)
264*4882a593Smuzhiyun baud_rate_val++;
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun ctrl_reg &= ~CDNS_SPI_CR_BAUD_DIV;
267*4882a593Smuzhiyun ctrl_reg |= baud_rate_val << CDNS_SPI_BAUD_DIV_SHIFT;
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun xspi->speed_hz = frequency / (2 << baud_rate_val);
270*4882a593Smuzhiyun }
271*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_CR, ctrl_reg);
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun /**
275*4882a593Smuzhiyun * cdns_spi_setup_transfer - Configure SPI controller for specified transfer
276*4882a593Smuzhiyun * @spi: Pointer to the spi_device structure
277*4882a593Smuzhiyun * @transfer: Pointer to the spi_transfer structure which provides
278*4882a593Smuzhiyun * information about next transfer setup parameters
279*4882a593Smuzhiyun *
280*4882a593Smuzhiyun * Sets the operational mode of SPI controller for the next SPI transfer and
281*4882a593Smuzhiyun * sets the requested clock frequency.
282*4882a593Smuzhiyun *
283*4882a593Smuzhiyun * Return: Always 0
284*4882a593Smuzhiyun */
cdns_spi_setup_transfer(struct spi_device * spi,struct spi_transfer * transfer)285*4882a593Smuzhiyun static int cdns_spi_setup_transfer(struct spi_device *spi,
286*4882a593Smuzhiyun struct spi_transfer *transfer)
287*4882a593Smuzhiyun {
288*4882a593Smuzhiyun struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun cdns_spi_config_clock_freq(spi, transfer);
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u clock speed\n",
293*4882a593Smuzhiyun __func__, spi->mode, spi->bits_per_word,
294*4882a593Smuzhiyun xspi->speed_hz);
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun return 0;
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun /**
300*4882a593Smuzhiyun * cdns_spi_fill_tx_fifo - Fills the TX FIFO with as many bytes as possible
301*4882a593Smuzhiyun * @xspi: Pointer to the cdns_spi structure
302*4882a593Smuzhiyun */
cdns_spi_fill_tx_fifo(struct cdns_spi * xspi)303*4882a593Smuzhiyun static void cdns_spi_fill_tx_fifo(struct cdns_spi *xspi)
304*4882a593Smuzhiyun {
305*4882a593Smuzhiyun unsigned long trans_cnt = 0;
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun while ((trans_cnt < CDNS_SPI_FIFO_DEPTH) &&
308*4882a593Smuzhiyun (xspi->tx_bytes > 0)) {
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun /* When xspi in busy condition, bytes may send failed,
311*4882a593Smuzhiyun * then spi control did't work thoroughly, add one byte delay
312*4882a593Smuzhiyun */
313*4882a593Smuzhiyun if (cdns_spi_read(xspi, CDNS_SPI_ISR) &
314*4882a593Smuzhiyun CDNS_SPI_IXR_TXFULL)
315*4882a593Smuzhiyun udelay(10);
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun if (xspi->txbuf)
318*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++);
319*4882a593Smuzhiyun else
320*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_TXD, 0);
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun xspi->tx_bytes--;
323*4882a593Smuzhiyun trans_cnt++;
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun /**
328*4882a593Smuzhiyun * cdns_spi_irq - Interrupt service routine of the SPI controller
329*4882a593Smuzhiyun * @irq: IRQ number
330*4882a593Smuzhiyun * @dev_id: Pointer to the xspi structure
331*4882a593Smuzhiyun *
332*4882a593Smuzhiyun * This function handles TX empty and Mode Fault interrupts only.
333*4882a593Smuzhiyun * On TX empty interrupt this function reads the received data from RX FIFO and
334*4882a593Smuzhiyun * fills the TX FIFO if there is any data remaining to be transferred.
335*4882a593Smuzhiyun * On Mode Fault interrupt this function indicates that transfer is completed,
336*4882a593Smuzhiyun * the SPI subsystem will identify the error as the remaining bytes to be
337*4882a593Smuzhiyun * transferred is non-zero.
338*4882a593Smuzhiyun *
339*4882a593Smuzhiyun * Return: IRQ_HANDLED when handled; IRQ_NONE otherwise.
340*4882a593Smuzhiyun */
cdns_spi_irq(int irq,void * dev_id)341*4882a593Smuzhiyun static irqreturn_t cdns_spi_irq(int irq, void *dev_id)
342*4882a593Smuzhiyun {
343*4882a593Smuzhiyun struct spi_master *master = dev_id;
344*4882a593Smuzhiyun struct cdns_spi *xspi = spi_master_get_devdata(master);
345*4882a593Smuzhiyun u32 intr_status, status;
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun status = IRQ_NONE;
348*4882a593Smuzhiyun intr_status = cdns_spi_read(xspi, CDNS_SPI_ISR);
349*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_ISR, intr_status);
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun if (intr_status & CDNS_SPI_IXR_MODF) {
352*4882a593Smuzhiyun /* Indicate that transfer is completed, the SPI subsystem will
353*4882a593Smuzhiyun * identify the error as the remaining bytes to be
354*4882a593Smuzhiyun * transferred is non-zero
355*4882a593Smuzhiyun */
356*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_IDR, CDNS_SPI_IXR_DEFAULT);
357*4882a593Smuzhiyun spi_finalize_current_transfer(master);
358*4882a593Smuzhiyun status = IRQ_HANDLED;
359*4882a593Smuzhiyun } else if (intr_status & CDNS_SPI_IXR_TXOW) {
360*4882a593Smuzhiyun unsigned long trans_cnt;
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun trans_cnt = xspi->rx_bytes - xspi->tx_bytes;
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun /* Read out the data from the RX FIFO */
365*4882a593Smuzhiyun while (trans_cnt) {
366*4882a593Smuzhiyun u8 data;
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun data = cdns_spi_read(xspi, CDNS_SPI_RXD);
369*4882a593Smuzhiyun if (xspi->rxbuf)
370*4882a593Smuzhiyun *xspi->rxbuf++ = data;
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun xspi->rx_bytes--;
373*4882a593Smuzhiyun trans_cnt--;
374*4882a593Smuzhiyun }
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun if (xspi->tx_bytes) {
377*4882a593Smuzhiyun /* There is more data to send */
378*4882a593Smuzhiyun cdns_spi_fill_tx_fifo(xspi);
379*4882a593Smuzhiyun } else {
380*4882a593Smuzhiyun /* Transfer is completed */
381*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_IDR,
382*4882a593Smuzhiyun CDNS_SPI_IXR_DEFAULT);
383*4882a593Smuzhiyun spi_finalize_current_transfer(master);
384*4882a593Smuzhiyun }
385*4882a593Smuzhiyun status = IRQ_HANDLED;
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun return status;
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun
cdns_prepare_message(struct spi_master * master,struct spi_message * msg)391*4882a593Smuzhiyun static int cdns_prepare_message(struct spi_master *master,
392*4882a593Smuzhiyun struct spi_message *msg)
393*4882a593Smuzhiyun {
394*4882a593Smuzhiyun cdns_spi_config_clock_mode(msg->spi);
395*4882a593Smuzhiyun return 0;
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun /**
399*4882a593Smuzhiyun * cdns_transfer_one - Initiates the SPI transfer
400*4882a593Smuzhiyun * @master: Pointer to spi_master structure
401*4882a593Smuzhiyun * @spi: Pointer to the spi_device structure
402*4882a593Smuzhiyun * @transfer: Pointer to the spi_transfer structure which provides
403*4882a593Smuzhiyun * information about next transfer parameters
404*4882a593Smuzhiyun *
405*4882a593Smuzhiyun * This function fills the TX FIFO, starts the SPI transfer and
406*4882a593Smuzhiyun * returns a positive transfer count so that core will wait for completion.
407*4882a593Smuzhiyun *
408*4882a593Smuzhiyun * Return: Number of bytes transferred in the last transfer
409*4882a593Smuzhiyun */
cdns_transfer_one(struct spi_master * master,struct spi_device * spi,struct spi_transfer * transfer)410*4882a593Smuzhiyun static int cdns_transfer_one(struct spi_master *master,
411*4882a593Smuzhiyun struct spi_device *spi,
412*4882a593Smuzhiyun struct spi_transfer *transfer)
413*4882a593Smuzhiyun {
414*4882a593Smuzhiyun struct cdns_spi *xspi = spi_master_get_devdata(master);
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun xspi->txbuf = transfer->tx_buf;
417*4882a593Smuzhiyun xspi->rxbuf = transfer->rx_buf;
418*4882a593Smuzhiyun xspi->tx_bytes = transfer->len;
419*4882a593Smuzhiyun xspi->rx_bytes = transfer->len;
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun cdns_spi_setup_transfer(spi, transfer);
422*4882a593Smuzhiyun cdns_spi_fill_tx_fifo(xspi);
423*4882a593Smuzhiyun spi_transfer_delay_exec(transfer);
424*4882a593Smuzhiyun
425*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_IER, CDNS_SPI_IXR_DEFAULT);
426*4882a593Smuzhiyun return transfer->len;
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun /**
430*4882a593Smuzhiyun * cdns_prepare_transfer_hardware - Prepares hardware for transfer.
431*4882a593Smuzhiyun * @master: Pointer to the spi_master structure which provides
432*4882a593Smuzhiyun * information about the controller.
433*4882a593Smuzhiyun *
434*4882a593Smuzhiyun * This function enables SPI master controller.
435*4882a593Smuzhiyun *
436*4882a593Smuzhiyun * Return: 0 always
437*4882a593Smuzhiyun */
cdns_prepare_transfer_hardware(struct spi_master * master)438*4882a593Smuzhiyun static int cdns_prepare_transfer_hardware(struct spi_master *master)
439*4882a593Smuzhiyun {
440*4882a593Smuzhiyun struct cdns_spi *xspi = spi_master_get_devdata(master);
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_ENABLE);
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun return 0;
445*4882a593Smuzhiyun }
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun /**
448*4882a593Smuzhiyun * cdns_unprepare_transfer_hardware - Relaxes hardware after transfer
449*4882a593Smuzhiyun * @master: Pointer to the spi_master structure which provides
450*4882a593Smuzhiyun * information about the controller.
451*4882a593Smuzhiyun *
452*4882a593Smuzhiyun * This function disables the SPI master controller.
453*4882a593Smuzhiyun *
454*4882a593Smuzhiyun * Return: 0 always
455*4882a593Smuzhiyun */
cdns_unprepare_transfer_hardware(struct spi_master * master)456*4882a593Smuzhiyun static int cdns_unprepare_transfer_hardware(struct spi_master *master)
457*4882a593Smuzhiyun {
458*4882a593Smuzhiyun struct cdns_spi *xspi = spi_master_get_devdata(master);
459*4882a593Smuzhiyun
460*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun return 0;
463*4882a593Smuzhiyun }
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun /**
466*4882a593Smuzhiyun * cdns_spi_probe - Probe method for the SPI driver
467*4882a593Smuzhiyun * @pdev: Pointer to the platform_device structure
468*4882a593Smuzhiyun *
469*4882a593Smuzhiyun * This function initializes the driver data structures and the hardware.
470*4882a593Smuzhiyun *
471*4882a593Smuzhiyun * Return: 0 on success and error value on error
472*4882a593Smuzhiyun */
cdns_spi_probe(struct platform_device * pdev)473*4882a593Smuzhiyun static int cdns_spi_probe(struct platform_device *pdev)
474*4882a593Smuzhiyun {
475*4882a593Smuzhiyun int ret = 0, irq;
476*4882a593Smuzhiyun struct spi_master *master;
477*4882a593Smuzhiyun struct cdns_spi *xspi;
478*4882a593Smuzhiyun u32 num_cs;
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun master = spi_alloc_master(&pdev->dev, sizeof(*xspi));
481*4882a593Smuzhiyun if (!master)
482*4882a593Smuzhiyun return -ENOMEM;
483*4882a593Smuzhiyun
484*4882a593Smuzhiyun xspi = spi_master_get_devdata(master);
485*4882a593Smuzhiyun master->dev.of_node = pdev->dev.of_node;
486*4882a593Smuzhiyun platform_set_drvdata(pdev, master);
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun xspi->regs = devm_platform_ioremap_resource(pdev, 0);
489*4882a593Smuzhiyun if (IS_ERR(xspi->regs)) {
490*4882a593Smuzhiyun ret = PTR_ERR(xspi->regs);
491*4882a593Smuzhiyun goto remove_master;
492*4882a593Smuzhiyun }
493*4882a593Smuzhiyun
494*4882a593Smuzhiyun xspi->pclk = devm_clk_get(&pdev->dev, "pclk");
495*4882a593Smuzhiyun if (IS_ERR(xspi->pclk)) {
496*4882a593Smuzhiyun dev_err(&pdev->dev, "pclk clock not found.\n");
497*4882a593Smuzhiyun ret = PTR_ERR(xspi->pclk);
498*4882a593Smuzhiyun goto remove_master;
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun xspi->ref_clk = devm_clk_get(&pdev->dev, "ref_clk");
502*4882a593Smuzhiyun if (IS_ERR(xspi->ref_clk)) {
503*4882a593Smuzhiyun dev_err(&pdev->dev, "ref_clk clock not found.\n");
504*4882a593Smuzhiyun ret = PTR_ERR(xspi->ref_clk);
505*4882a593Smuzhiyun goto remove_master;
506*4882a593Smuzhiyun }
507*4882a593Smuzhiyun
508*4882a593Smuzhiyun ret = clk_prepare_enable(xspi->pclk);
509*4882a593Smuzhiyun if (ret) {
510*4882a593Smuzhiyun dev_err(&pdev->dev, "Unable to enable APB clock.\n");
511*4882a593Smuzhiyun goto remove_master;
512*4882a593Smuzhiyun }
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun ret = clk_prepare_enable(xspi->ref_clk);
515*4882a593Smuzhiyun if (ret) {
516*4882a593Smuzhiyun dev_err(&pdev->dev, "Unable to enable device clock.\n");
517*4882a593Smuzhiyun goto clk_dis_apb;
518*4882a593Smuzhiyun }
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun pm_runtime_use_autosuspend(&pdev->dev);
521*4882a593Smuzhiyun pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
522*4882a593Smuzhiyun pm_runtime_get_noresume(&pdev->dev);
523*4882a593Smuzhiyun pm_runtime_set_active(&pdev->dev);
524*4882a593Smuzhiyun pm_runtime_enable(&pdev->dev);
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs);
527*4882a593Smuzhiyun if (ret < 0)
528*4882a593Smuzhiyun master->num_chipselect = CDNS_SPI_DEFAULT_NUM_CS;
529*4882a593Smuzhiyun else
530*4882a593Smuzhiyun master->num_chipselect = num_cs;
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun ret = of_property_read_u32(pdev->dev.of_node, "is-decoded-cs",
533*4882a593Smuzhiyun &xspi->is_decoded_cs);
534*4882a593Smuzhiyun if (ret < 0)
535*4882a593Smuzhiyun xspi->is_decoded_cs = 0;
536*4882a593Smuzhiyun
537*4882a593Smuzhiyun /* SPI controller initializations */
538*4882a593Smuzhiyun cdns_spi_init_hw(xspi);
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun irq = platform_get_irq(pdev, 0);
541*4882a593Smuzhiyun if (irq <= 0) {
542*4882a593Smuzhiyun ret = -ENXIO;
543*4882a593Smuzhiyun goto clk_dis_all;
544*4882a593Smuzhiyun }
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun ret = devm_request_irq(&pdev->dev, irq, cdns_spi_irq,
547*4882a593Smuzhiyun 0, pdev->name, master);
548*4882a593Smuzhiyun if (ret != 0) {
549*4882a593Smuzhiyun ret = -ENXIO;
550*4882a593Smuzhiyun dev_err(&pdev->dev, "request_irq failed\n");
551*4882a593Smuzhiyun goto clk_dis_all;
552*4882a593Smuzhiyun }
553*4882a593Smuzhiyun
554*4882a593Smuzhiyun master->use_gpio_descriptors = true;
555*4882a593Smuzhiyun master->prepare_transfer_hardware = cdns_prepare_transfer_hardware;
556*4882a593Smuzhiyun master->prepare_message = cdns_prepare_message;
557*4882a593Smuzhiyun master->transfer_one = cdns_transfer_one;
558*4882a593Smuzhiyun master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware;
559*4882a593Smuzhiyun master->set_cs = cdns_spi_chipselect;
560*4882a593Smuzhiyun master->auto_runtime_pm = true;
561*4882a593Smuzhiyun master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
562*4882a593Smuzhiyun
563*4882a593Smuzhiyun xspi->clk_rate = clk_get_rate(xspi->ref_clk);
564*4882a593Smuzhiyun /* Set to default valid value */
565*4882a593Smuzhiyun master->max_speed_hz = xspi->clk_rate / 4;
566*4882a593Smuzhiyun xspi->speed_hz = master->max_speed_hz;
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun master->bits_per_word_mask = SPI_BPW_MASK(8);
569*4882a593Smuzhiyun
570*4882a593Smuzhiyun pm_runtime_mark_last_busy(&pdev->dev);
571*4882a593Smuzhiyun pm_runtime_put_autosuspend(&pdev->dev);
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun ret = spi_register_master(master);
574*4882a593Smuzhiyun if (ret) {
575*4882a593Smuzhiyun dev_err(&pdev->dev, "spi_register_master failed\n");
576*4882a593Smuzhiyun goto clk_dis_all;
577*4882a593Smuzhiyun }
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun return ret;
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun clk_dis_all:
582*4882a593Smuzhiyun pm_runtime_set_suspended(&pdev->dev);
583*4882a593Smuzhiyun pm_runtime_disable(&pdev->dev);
584*4882a593Smuzhiyun clk_disable_unprepare(xspi->ref_clk);
585*4882a593Smuzhiyun clk_dis_apb:
586*4882a593Smuzhiyun clk_disable_unprepare(xspi->pclk);
587*4882a593Smuzhiyun remove_master:
588*4882a593Smuzhiyun spi_master_put(master);
589*4882a593Smuzhiyun return ret;
590*4882a593Smuzhiyun }
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun /**
593*4882a593Smuzhiyun * cdns_spi_remove - Remove method for the SPI driver
594*4882a593Smuzhiyun * @pdev: Pointer to the platform_device structure
595*4882a593Smuzhiyun *
596*4882a593Smuzhiyun * This function is called if a device is physically removed from the system or
597*4882a593Smuzhiyun * if the driver module is being unloaded. It frees all resources allocated to
598*4882a593Smuzhiyun * the device.
599*4882a593Smuzhiyun *
600*4882a593Smuzhiyun * Return: 0 on success and error value on error
601*4882a593Smuzhiyun */
cdns_spi_remove(struct platform_device * pdev)602*4882a593Smuzhiyun static int cdns_spi_remove(struct platform_device *pdev)
603*4882a593Smuzhiyun {
604*4882a593Smuzhiyun struct spi_master *master = platform_get_drvdata(pdev);
605*4882a593Smuzhiyun struct cdns_spi *xspi = spi_master_get_devdata(master);
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);
608*4882a593Smuzhiyun
609*4882a593Smuzhiyun clk_disable_unprepare(xspi->ref_clk);
610*4882a593Smuzhiyun clk_disable_unprepare(xspi->pclk);
611*4882a593Smuzhiyun pm_runtime_set_suspended(&pdev->dev);
612*4882a593Smuzhiyun pm_runtime_disable(&pdev->dev);
613*4882a593Smuzhiyun
614*4882a593Smuzhiyun spi_unregister_master(master);
615*4882a593Smuzhiyun
616*4882a593Smuzhiyun return 0;
617*4882a593Smuzhiyun }
618*4882a593Smuzhiyun
619*4882a593Smuzhiyun /**
620*4882a593Smuzhiyun * cdns_spi_suspend - Suspend method for the SPI driver
621*4882a593Smuzhiyun * @dev: Address of the platform_device structure
622*4882a593Smuzhiyun *
623*4882a593Smuzhiyun * This function disables the SPI controller and
624*4882a593Smuzhiyun * changes the driver state to "suspend"
625*4882a593Smuzhiyun *
626*4882a593Smuzhiyun * Return: 0 on success and error value on error
627*4882a593Smuzhiyun */
cdns_spi_suspend(struct device * dev)628*4882a593Smuzhiyun static int __maybe_unused cdns_spi_suspend(struct device *dev)
629*4882a593Smuzhiyun {
630*4882a593Smuzhiyun struct spi_master *master = dev_get_drvdata(dev);
631*4882a593Smuzhiyun
632*4882a593Smuzhiyun return spi_master_suspend(master);
633*4882a593Smuzhiyun }
634*4882a593Smuzhiyun
635*4882a593Smuzhiyun /**
636*4882a593Smuzhiyun * cdns_spi_resume - Resume method for the SPI driver
637*4882a593Smuzhiyun * @dev: Address of the platform_device structure
638*4882a593Smuzhiyun *
639*4882a593Smuzhiyun * This function changes the driver state to "ready"
640*4882a593Smuzhiyun *
641*4882a593Smuzhiyun * Return: 0 on success and error value on error
642*4882a593Smuzhiyun */
cdns_spi_resume(struct device * dev)643*4882a593Smuzhiyun static int __maybe_unused cdns_spi_resume(struct device *dev)
644*4882a593Smuzhiyun {
645*4882a593Smuzhiyun struct spi_master *master = dev_get_drvdata(dev);
646*4882a593Smuzhiyun struct cdns_spi *xspi = spi_master_get_devdata(master);
647*4882a593Smuzhiyun
648*4882a593Smuzhiyun cdns_spi_init_hw(xspi);
649*4882a593Smuzhiyun return spi_master_resume(master);
650*4882a593Smuzhiyun }
651*4882a593Smuzhiyun
652*4882a593Smuzhiyun /**
653*4882a593Smuzhiyun * cdns_spi_runtime_resume - Runtime resume method for the SPI driver
654*4882a593Smuzhiyun * @dev: Address of the platform_device structure
655*4882a593Smuzhiyun *
656*4882a593Smuzhiyun * This function enables the clocks
657*4882a593Smuzhiyun *
658*4882a593Smuzhiyun * Return: 0 on success and error value on error
659*4882a593Smuzhiyun */
cnds_runtime_resume(struct device * dev)660*4882a593Smuzhiyun static int __maybe_unused cnds_runtime_resume(struct device *dev)
661*4882a593Smuzhiyun {
662*4882a593Smuzhiyun struct spi_master *master = dev_get_drvdata(dev);
663*4882a593Smuzhiyun struct cdns_spi *xspi = spi_master_get_devdata(master);
664*4882a593Smuzhiyun int ret;
665*4882a593Smuzhiyun
666*4882a593Smuzhiyun ret = clk_prepare_enable(xspi->pclk);
667*4882a593Smuzhiyun if (ret) {
668*4882a593Smuzhiyun dev_err(dev, "Cannot enable APB clock.\n");
669*4882a593Smuzhiyun return ret;
670*4882a593Smuzhiyun }
671*4882a593Smuzhiyun
672*4882a593Smuzhiyun ret = clk_prepare_enable(xspi->ref_clk);
673*4882a593Smuzhiyun if (ret) {
674*4882a593Smuzhiyun dev_err(dev, "Cannot enable device clock.\n");
675*4882a593Smuzhiyun clk_disable_unprepare(xspi->pclk);
676*4882a593Smuzhiyun return ret;
677*4882a593Smuzhiyun }
678*4882a593Smuzhiyun return 0;
679*4882a593Smuzhiyun }
680*4882a593Smuzhiyun
681*4882a593Smuzhiyun /**
682*4882a593Smuzhiyun * cdns_spi_runtime_suspend - Runtime suspend method for the SPI driver
683*4882a593Smuzhiyun * @dev: Address of the platform_device structure
684*4882a593Smuzhiyun *
685*4882a593Smuzhiyun * This function disables the clocks
686*4882a593Smuzhiyun *
687*4882a593Smuzhiyun * Return: Always 0
688*4882a593Smuzhiyun */
cnds_runtime_suspend(struct device * dev)689*4882a593Smuzhiyun static int __maybe_unused cnds_runtime_suspend(struct device *dev)
690*4882a593Smuzhiyun {
691*4882a593Smuzhiyun struct spi_master *master = dev_get_drvdata(dev);
692*4882a593Smuzhiyun struct cdns_spi *xspi = spi_master_get_devdata(master);
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun clk_disable_unprepare(xspi->ref_clk);
695*4882a593Smuzhiyun clk_disable_unprepare(xspi->pclk);
696*4882a593Smuzhiyun
697*4882a593Smuzhiyun return 0;
698*4882a593Smuzhiyun }
699*4882a593Smuzhiyun
700*4882a593Smuzhiyun static const struct dev_pm_ops cdns_spi_dev_pm_ops = {
701*4882a593Smuzhiyun SET_RUNTIME_PM_OPS(cnds_runtime_suspend,
702*4882a593Smuzhiyun cnds_runtime_resume, NULL)
703*4882a593Smuzhiyun SET_SYSTEM_SLEEP_PM_OPS(cdns_spi_suspend, cdns_spi_resume)
704*4882a593Smuzhiyun };
705*4882a593Smuzhiyun
706*4882a593Smuzhiyun static const struct of_device_id cdns_spi_of_match[] = {
707*4882a593Smuzhiyun { .compatible = "xlnx,zynq-spi-r1p6" },
708*4882a593Smuzhiyun { .compatible = "cdns,spi-r1p6" },
709*4882a593Smuzhiyun { /* end of table */ }
710*4882a593Smuzhiyun };
711*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, cdns_spi_of_match);
712*4882a593Smuzhiyun
713*4882a593Smuzhiyun /* cdns_spi_driver - This structure defines the SPI subsystem platform driver */
714*4882a593Smuzhiyun static struct platform_driver cdns_spi_driver = {
715*4882a593Smuzhiyun .probe = cdns_spi_probe,
716*4882a593Smuzhiyun .remove = cdns_spi_remove,
717*4882a593Smuzhiyun .driver = {
718*4882a593Smuzhiyun .name = CDNS_SPI_NAME,
719*4882a593Smuzhiyun .of_match_table = cdns_spi_of_match,
720*4882a593Smuzhiyun .pm = &cdns_spi_dev_pm_ops,
721*4882a593Smuzhiyun },
722*4882a593Smuzhiyun };
723*4882a593Smuzhiyun
724*4882a593Smuzhiyun module_platform_driver(cdns_spi_driver);
725*4882a593Smuzhiyun
726*4882a593Smuzhiyun MODULE_AUTHOR("Xilinx, Inc.");
727*4882a593Smuzhiyun MODULE_DESCRIPTION("Cadence SPI driver");
728*4882a593Smuzhiyun MODULE_LICENSE("GPL");
729