xref: /OK3568_Linux_fs/kernel/drivers/spi/spi-cadence.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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