xref: /freebsd/sys/dev/intel/spi.c (revision 815b7436a7c6302365b6514194d27d41cb736227)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2016 Oleksandr Tymoshenko <gonzo@FreeBSD.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include "opt_acpi.h"
30 
31 #include <sys/param.h>
32 #include <sys/bus.h>
33 #include <sys/kdb.h>
34 #include <sys/kernel.h>
35 #include <sys/module.h>
36 #include <sys/proc.h>
37 #include <sys/rman.h>
38 
39 #include <machine/bus.h>
40 #include <machine/resource.h>
41 
42 #include <dev/spibus/spi.h>
43 #include <dev/spibus/spibusvar.h>
44 
45 #include <dev/intel/spi.h>
46 
47 /**
48  *	Macros for driver mutex locking
49  */
50 #define	INTELSPI_IN_POLLING_MODE()	(SCHEDULER_STOPPED() || kdb_active)
51 #define	INTELSPI_LOCK(_sc)		do {		\
52 	if(!INTELSPI_IN_POLLING_MODE())			\
53 		mtx_lock(&(_sc)->sc_mtx);		\
54 } while (0)
55 #define	INTELSPI_UNLOCK(_sc)		do {		\
56 	if(!INTELSPI_IN_POLLING_MODE())			\
57 		mtx_unlock(&(_sc)->sc_mtx);		\
58 } while (0)
59 #define	INTELSPI_LOCK_INIT(_sc)		\
60 	mtx_init(&_sc->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
61 	    "intelspi", MTX_DEF)
62 #define	INTELSPI_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->sc_mtx)
63 #define	INTELSPI_ASSERT_LOCKED(_sc)	do {		\
64 	if(!INTELSPI_IN_POLLING_MODE())			\
65 		mtx_assert(&(_sc)->sc_mtx, MA_OWNED);	\
66 } while (0)
67 #define	INTELSPI_ASSERT_UNLOCKED(_sc)	do {		\
68 	if(!INTELSPI_IN_POLLING_MODE())			\
69 		mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED);\
70 } while (0)
71 
72 #define INTELSPI_WRITE(_sc, _off, _val)		\
73     bus_write_4((_sc)->sc_mem_res, (_off), (_val))
74 #define INTELSPI_READ(_sc, _off)			\
75     bus_read_4((_sc)->sc_mem_res, (_off))
76 
77 #define	INTELSPI_BUSY		0x1
78 #define	TX_FIFO_THRESHOLD	2
79 #define	RX_FIFO_THRESHOLD	2
80 #define	CLOCK_DIV_10MHZ		5
81 #define	DATA_SIZE_8BITS		8
82 #define	MAX_CLOCK_RATE		50000000
83 
84 #define	CS_LOW		0
85 #define	CS_HIGH		1
86 
87 #define	INTELSPI_SSPREG_SSCR0	 	0x0
88 #define	 SSCR0_SCR(n)				((((n) - 1) & 0xfff) << 8)
89 #define	 SSCR0_SSE				(1 << 7)
90 #define	 SSCR0_FRF_SPI				(0 << 4)
91 #define	 SSCR0_DSS(n)				(((n) - 1) << 0)
92 #define	INTELSPI_SSPREG_SSCR1	 	0x4
93 #define	 SSCR1_TINTE				(1 << 19)
94 #define	 SSCR1_RFT(n)				(((n) - 1) << 10)
95 #define	 SSCR1_RFT_MASK				(0xf << 10)
96 #define	 SSCR1_TFT(n)				(((n) - 1) << 6)
97 #define	 SSCR1_SPI_SPH				(1 << 4)
98 #define	 SSCR1_SPI_SPO				(1 << 3)
99 #define	 SSCR1_MODE_MASK				(SSCR1_SPI_SPO | SSCR1_SPI_SPH)
100 #define	 SSCR1_TIE				(1 << 1)
101 #define	 SSCR1_RIE				(1 << 0)
102 #define	INTELSPI_SSPREG_SSSR	 	0x8
103 #define	 SSSR_RFL_MASK				(0xf << 12)
104 #define	 SSSR_TFL_MASK				(0xf << 8)
105 #define	 SSSR_RNE				(1 << 3)
106 #define	 SSSR_TNF				(1 << 2)
107 #define	INTELSPI_SSPREG_SSITR	 	0xC
108 #define	INTELSPI_SSPREG_SSDR	 	0x10
109 #define	INTELSPI_SSPREG_SSTO	 	0x28
110 #define	INTELSPI_SSPREG_SSPSP	 	0x2C
111 #define	INTELSPI_SSPREG_SSTSA	 	0x30
112 #define	INTELSPI_SSPREG_SSRSA	 	0x34
113 #define	INTELSPI_SSPREG_SSTSS	 	0x38
114 #define	INTELSPI_SSPREG_SSACD	 	0x3C
115 #define	INTELSPI_SSPREG_ITF	 	0x40
116 #define	INTELSPI_SSPREG_SITF	 	0x44
117 #define	INTELSPI_SSPREG_SIRF	 	0x48
118 #define SPI_CS_CTRL(sc) \
119 	(intelspi_infos[sc->sc_vers].reg_lpss_base + \
120 	 intelspi_infos[sc->sc_vers].reg_cs_ctrl)
121 #define	 SPI_CS_CTRL_CS_MASK			(3)
122 #define	 SPI_CS_CTRL_SW_MODE			(1 << 0)
123 #define	 SPI_CS_CTRL_HW_MODE			(1 << 0)
124 #define	 SPI_CS_CTRL_CS_HIGH			(1 << 1)
125 
126 #define	INTELSPI_RESETS			0x204
127 #define	 INTELSPI_RESET_HOST			(1 << 0) | (1 << 1)
128 #define	 INTELSPI_RESET_DMA			(1 << 2)
129 
130 /* Same order as intelspi_vers */
131 static const struct intelspi_info {
132 	uint32_t reg_lpss_base;
133 	uint32_t reg_cs_ctrl;
134 } intelspi_infos[] = {
135 	[SPI_BAYTRAIL] = {
136 		.reg_lpss_base = 0x400,
137 		.reg_cs_ctrl = 0x18,
138 	},
139 	[SPI_BRASWELL] = {
140 		.reg_lpss_base = 0x400,
141 		.reg_cs_ctrl = 0x18,
142 	},
143 	[SPI_LYNXPOINT] = {
144 		.reg_lpss_base = 0x800,
145 		.reg_cs_ctrl = 0x18,
146 	},
147 	[SPI_SUNRISEPOINT] = {
148 		.reg_lpss_base = 0x200,
149 		.reg_cs_ctrl = 0x24,
150 	},
151 };
152 
153 static void	intelspi_intr(void *);
154 
155 static int
156 intelspi_txfifo_full(struct intelspi_softc *sc)
157 {
158 	uint32_t sssr;
159 
160 	INTELSPI_ASSERT_LOCKED(sc);
161 
162 	sssr = INTELSPI_READ(sc, INTELSPI_SSPREG_SSSR);
163 	if (sssr & SSSR_TNF)
164 		return (0);
165 
166 	return (1);
167 }
168 
169 static int
170 intelspi_rxfifo_empty(struct intelspi_softc *sc)
171 {
172 	uint32_t sssr;
173 
174 	INTELSPI_ASSERT_LOCKED(sc);
175 
176 	sssr = INTELSPI_READ(sc, INTELSPI_SSPREG_SSSR);
177 	if (sssr & SSSR_RNE)
178 		return (0);
179 	else
180 		return (1);
181 }
182 
183 static void
184 intelspi_fill_tx_fifo(struct intelspi_softc *sc)
185 {
186 	struct spi_command *cmd;
187 	uint32_t written;
188 	uint8_t *data;
189 
190 	INTELSPI_ASSERT_LOCKED(sc);
191 
192 	cmd = sc->sc_cmd;
193 	while (sc->sc_written < sc->sc_len &&
194 	    !intelspi_txfifo_full(sc)) {
195 		data = (uint8_t *)cmd->tx_cmd;
196 		written = sc->sc_written++;
197 
198 		if (written >= cmd->tx_cmd_sz) {
199 			data = (uint8_t *)cmd->tx_data;
200 			written -= cmd->tx_cmd_sz;
201 		}
202 		INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSDR, data[written]);
203 	}
204 }
205 
206 static void
207 intelspi_drain_rx_fifo(struct intelspi_softc *sc)
208 {
209 	struct spi_command *cmd;
210 	uint32_t  read;
211 	uint8_t *data;
212 
213 	INTELSPI_ASSERT_LOCKED(sc);
214 
215 	cmd = sc->sc_cmd;
216 	while (sc->sc_read < sc->sc_len &&
217 	    !intelspi_rxfifo_empty(sc)) {
218 		data = (uint8_t *)cmd->rx_cmd;
219 		read = sc->sc_read++;
220 		if (read >= cmd->rx_cmd_sz) {
221 			data = (uint8_t *)cmd->rx_data;
222 			read -= cmd->rx_cmd_sz;
223 		}
224 		data[read] = INTELSPI_READ(sc, INTELSPI_SSPREG_SSDR) & 0xff;
225 	}
226 }
227 
228 static int
229 intelspi_transaction_done(struct intelspi_softc *sc)
230 {
231 	int txfifo_empty;
232 	uint32_t sssr;
233 
234 	INTELSPI_ASSERT_LOCKED(sc);
235 
236 	if (sc->sc_written != sc->sc_len ||
237 	    sc->sc_read != sc->sc_len)
238 		return (0);
239 
240 	sssr = INTELSPI_READ(sc, INTELSPI_SSPREG_SSSR);
241 	txfifo_empty = ((sssr & SSSR_TFL_MASK) == 0) &&
242 		(sssr & SSSR_TNF);
243 
244 	if (txfifo_empty && !(sssr & SSSR_RNE))
245 		return (1);
246 
247 	return (0);
248 }
249 
250 static int
251 intelspi_transact(struct intelspi_softc *sc)
252 {
253 
254 	INTELSPI_ASSERT_LOCKED(sc);
255 
256 	/* TX - Fill up the FIFO. */
257 	intelspi_fill_tx_fifo(sc);
258 
259 	/* RX - Drain the FIFO. */
260 	intelspi_drain_rx_fifo(sc);
261 
262 	/* Check for end of transfer. */
263 	return intelspi_transaction_done(sc);
264 }
265 
266 static void
267 intelspi_intr(void *arg)
268 {
269 	struct intelspi_softc *sc;
270 	uint32_t reg;
271 
272 	sc = (struct intelspi_softc *)arg;
273 
274 	INTELSPI_LOCK(sc);
275 	if ((sc->sc_flags & INTELSPI_BUSY) == 0) {
276 		INTELSPI_UNLOCK(sc);
277 		return;
278 	}
279 
280 	/* Check if SSP if off */
281 	reg = INTELSPI_READ(sc, INTELSPI_SSPREG_SSSR);
282 	if (reg == 0xffffffffU) {
283 		INTELSPI_UNLOCK(sc);
284 		return;
285 	}
286 
287 	/* Check for end of transfer. */
288 	if (intelspi_transact(sc)) {
289 		/* Disable interrupts */
290 		reg = INTELSPI_READ(sc, INTELSPI_SSPREG_SSCR1);
291 		reg &= ~(SSCR1_TIE | SSCR1_RIE | SSCR1_TINTE);
292 		INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR1, reg);
293 		wakeup(sc->sc_dev);
294 	}
295 
296 	INTELSPI_UNLOCK(sc);
297 }
298 
299 static void
300 intelspi_init(struct intelspi_softc *sc)
301 {
302 	uint32_t reg;
303 
304 	INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR0, 0);
305 
306 	/* Manual CS control */
307 	reg = INTELSPI_READ(sc, SPI_CS_CTRL(sc));
308 	reg &= ~(SPI_CS_CTRL_CS_MASK);
309 	reg |= (SPI_CS_CTRL_SW_MODE | SPI_CS_CTRL_CS_HIGH);
310 	INTELSPI_WRITE(sc, SPI_CS_CTRL(sc), reg);
311 
312 	/* Set TX/RX FIFO IRQ threshold levels */
313 	reg = SSCR1_TFT(TX_FIFO_THRESHOLD) | SSCR1_RFT(RX_FIFO_THRESHOLD);
314 	INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR1, reg);
315 
316 	reg = SSCR0_SCR(CLOCK_DIV_10MHZ);
317 	/* Put SSP in SPI mode */
318 	reg |= SSCR0_FRF_SPI;
319 	/* Data size */
320 	reg |= SSCR0_DSS(DATA_SIZE_8BITS);
321 	/* Enable SSP */
322 	reg |= SSCR0_SSE;
323 	INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR0, reg);
324 }
325 
326 static void
327 intelspi_set_cs(struct intelspi_softc *sc, int level)
328 {
329 	uint32_t reg;
330 
331 	reg = INTELSPI_READ(sc, SPI_CS_CTRL(sc));
332 	reg &= ~(SPI_CS_CTRL_CS_MASK);
333 	reg |= SPI_CS_CTRL_SW_MODE;
334 
335 	if (level == CS_HIGH)
336 		reg |= SPI_CS_CTRL_CS_HIGH;
337 
338 	INTELSPI_WRITE(sc, SPI_CS_CTRL(sc), reg);
339 }
340 
341 int
342 intelspi_transfer(device_t dev, device_t child, struct spi_command *cmd)
343 {
344 	struct intelspi_softc *sc;
345 	int err, poll_limit;
346 	uint32_t sscr0, sscr1, mode, clock, cs_delay;
347 	bool restart = false;
348 
349 	sc = device_get_softc(dev);
350 	err = 0;
351 
352 	KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz,
353 	    ("TX/RX command sizes should be equal"));
354 	KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
355 	    ("TX/RX data sizes should be equal"));
356 
357 	INTELSPI_LOCK(sc);
358 
359 	if (!INTELSPI_IN_POLLING_MODE()) {
360 		/* If the controller is in use wait until it is available. */
361 		while (sc->sc_flags & INTELSPI_BUSY) {
362 			if ((cmd->flags & SPI_FLAG_NO_SLEEP) != 0) {
363 				INTELSPI_UNLOCK(sc);
364 				return (EBUSY);
365 			}
366 			err = mtx_sleep(dev, &sc->sc_mtx, 0, "intelspi", 0);
367 			if (err == EINTR) {
368 				INTELSPI_UNLOCK(sc);
369 				return (err);
370 			}
371 		}
372 	} else {
373 		/*
374 		 * Now we are in the middle of other transfer. Try to reset
375 		 * controller state to get predictable context.
376 		 */
377 		if ((sc->sc_flags & INTELSPI_BUSY) != 0)
378 			intelspi_init(sc);
379 	}
380 
381 	/* Now we have control over SPI controller. */
382 	sc->sc_flags = INTELSPI_BUSY;
383 
384 	/* Configure the clock rate and SPI mode. */
385 	spibus_get_clock(child, &clock);
386 	spibus_get_mode(child, &mode);
387 
388 	if (clock != sc->sc_clock || mode != sc->sc_mode) {
389 		sscr0 = INTELSPI_READ(sc, INTELSPI_SSPREG_SSCR0);
390 		sscr0 &= ~SSCR0_SSE;
391 		INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR0, sscr0);
392 		restart = true;
393 	}
394 
395 	if (clock != sc->sc_clock) {
396 		sscr0 = INTELSPI_READ(sc, INTELSPI_SSPREG_SSCR0);
397 		sscr0 &= ~SSCR0_SCR(0xfff);
398 		if (clock == 0)
399 			sscr0 |= SSCR0_SCR(CLOCK_DIV_10MHZ);
400 		else
401 			sscr0 |= SSCR0_SCR(howmany(MAX_CLOCK_RATE, min(MAX_CLOCK_RATE, clock)));
402 		INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR0, sscr0);
403 		sc->sc_clock = clock;
404 	}
405 
406 	if (mode != sc->sc_mode) {
407 		sscr1 = INTELSPI_READ(sc, INTELSPI_SSPREG_SSCR1);
408 		sscr1 &= ~SSCR1_MODE_MASK;
409 		if (mode & SPIBUS_MODE_CPHA)
410 			sscr1 |= SSCR1_SPI_SPH;
411 		if (mode & SPIBUS_MODE_CPOL)
412 			sscr1 |= SSCR1_SPI_SPO;
413 		INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR1, sscr1);
414 		sc->sc_mode = mode;
415 	}
416 
417 	if (restart) {
418 		sscr0 = INTELSPI_READ(sc, INTELSPI_SSPREG_SSCR0);
419 		sscr0 |= SSCR0_SSE;
420 		INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR0, sscr0);
421 	}
422 
423 	/* Save a pointer to the SPI command. */
424 	sc->sc_cmd = cmd;
425 	sc->sc_read = 0;
426 	sc->sc_written = 0;
427 	sc->sc_len = cmd->tx_cmd_sz + cmd->tx_data_sz;
428 
429 	/* Enable CS */
430 	intelspi_set_cs(sc, CS_LOW);
431 
432 	/* Wait the CS delay */
433 	spibus_get_cs_delay(child, &cs_delay);
434 	DELAY(cs_delay);
435 
436 	/* Transfer as much as possible to FIFOs */
437 	if ((cmd->flags & SPI_FLAG_NO_SLEEP) != 0 ||
438 	     INTELSPI_IN_POLLING_MODE() || cold) {
439 		/* We cannot wait with mtx_sleep if we're called from e.g. an ithread */
440 		poll_limit = 2000;
441 		while (!intelspi_transact(sc) && poll_limit-- > 0)
442 			DELAY(1000);
443 		if (poll_limit == 0) {
444 			device_printf(dev, "polling was stuck, transaction not finished\n");
445 			err = EIO;
446 		}
447 	} else {
448 		if (!intelspi_transact(sc)) {
449 			/* If FIFO is not large enough - enable interrupts */
450 			sscr1 = INTELSPI_READ(sc, INTELSPI_SSPREG_SSCR1);
451 			sscr1 |= (SSCR1_TIE | SSCR1_RIE | SSCR1_TINTE);
452 			INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR1, sscr1);
453 
454 			/* and wait for transaction to complete */
455 			err = mtx_sleep(dev, &sc->sc_mtx, 0, "intelspi", hz * 2);
456 		}
457 	}
458 
459 	/* De-assert CS */
460 	if ((cmd->flags & SPI_FLAG_KEEP_CS) == 0)
461 		intelspi_set_cs(sc, CS_HIGH);
462 
463 	/* Clear transaction details */
464 	sc->sc_cmd = NULL;
465 	sc->sc_read = 0;
466 	sc->sc_written = 0;
467 	sc->sc_len = 0;
468 
469 	/* Make sure the SPI engine and interrupts are disabled. */
470 	sscr1 = INTELSPI_READ(sc, INTELSPI_SSPREG_SSCR1);
471 	sscr1 &= ~(SSCR1_TIE | SSCR1_RIE | SSCR1_TINTE);
472 	INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR1, sscr1);
473 
474 	/* Release the controller and wakeup the next thread waiting for it. */
475 	sc->sc_flags = 0;
476 	if (!INTELSPI_IN_POLLING_MODE())
477 		wakeup_one(dev);
478 	INTELSPI_UNLOCK(sc);
479 
480 	/*
481 	 * Check for transfer timeout.  The SPI controller doesn't
482 	 * return errors.
483 	 */
484 	if (err == EWOULDBLOCK) {
485 		device_printf(sc->sc_dev, "transfer timeout\n");
486 		err = EIO;
487 	}
488 
489 	return (err);
490 }
491 
492 int
493 intelspi_attach(device_t dev)
494 {
495 	struct intelspi_softc	*sc;
496 
497 	sc = device_get_softc(dev);
498 	sc->sc_dev = dev;
499 
500 	INTELSPI_LOCK_INIT(sc);
501 
502 	sc->sc_mem_res = bus_alloc_resource_any(sc->sc_dev,
503 	    SYS_RES_MEMORY, &sc->sc_mem_rid, RF_ACTIVE);
504 	if (sc->sc_mem_res == NULL) {
505 		device_printf(dev, "can't allocate memory resource\n");
506 		goto error;
507 	}
508 
509 	/* Release LPSS reset */
510 	if (sc->sc_vers == SPI_SUNRISEPOINT)
511 		INTELSPI_WRITE(sc, INTELSPI_RESETS,
512 		    (INTELSPI_RESET_HOST | INTELSPI_RESET_DMA));
513 
514 	sc->sc_irq_res = bus_alloc_resource_any(sc->sc_dev,
515 	    SYS_RES_IRQ, &sc->sc_irq_rid, RF_ACTIVE | RF_SHAREABLE);
516 	if (sc->sc_irq_res == NULL) {
517 		device_printf(dev, "can't allocate IRQ resource\n");
518 		goto error;
519 	}
520 
521 	/* Hook up our interrupt handler. */
522 	if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
523 	    NULL, intelspi_intr, sc, &sc->sc_irq_ih)) {
524 		device_printf(dev, "cannot setup the interrupt handler\n");
525 		goto error;
526 	}
527 
528 	intelspi_init(sc);
529 
530 	device_add_child(dev, "spibus", -1);
531 
532 	return (bus_delayed_attach_children(dev));
533 
534 error:
535 	INTELSPI_LOCK_DESTROY(sc);
536 
537 	if (sc->sc_mem_res != NULL)
538 		bus_release_resource(dev, SYS_RES_MEMORY,
539 		    sc->sc_mem_rid, sc->sc_mem_res);
540 
541 	if (sc->sc_irq_res != NULL)
542 		bus_release_resource(dev, SYS_RES_IRQ,
543 		    sc->sc_irq_rid, sc->sc_irq_res);
544 
545 	return (ENXIO);
546 }
547 
548 int
549 intelspi_detach(device_t dev)
550 {
551 	struct intelspi_softc	*sc;
552 
553 	sc = device_get_softc(dev);
554 
555 	INTELSPI_LOCK_DESTROY(sc);
556 
557 	if (sc->sc_irq_ih)
558 		bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_ih);
559 
560 	if (sc->sc_mem_res != NULL)
561 		bus_release_resource(dev, SYS_RES_MEMORY,
562 		    sc->sc_mem_rid, sc->sc_mem_res);
563 
564 	if (sc->sc_irq_res != NULL)
565 		bus_release_resource(dev, SYS_RES_IRQ,
566 		    sc->sc_irq_rid, sc->sc_irq_res);
567 
568 	return (device_delete_children(dev));
569 }
570 
571 int
572 intelspi_suspend(device_t dev)
573 {
574 	struct intelspi_softc        *sc;
575 	int err, i;
576 
577 	sc = device_get_softc(dev);
578 
579 	err = bus_generic_suspend(dev);
580 	if (err)
581 		return (err);
582 
583 	for (i = 0; i < 9; i++) {
584 		unsigned long offset = i * sizeof(uint32_t);
585 		sc->sc_regs[i] = INTELSPI_READ(sc,
586 		    intelspi_infos[sc->sc_vers].reg_lpss_base + offset);
587 	}
588 
589 	/* Shutdown just in case */
590 	INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR0, 0);
591 
592 	return (0);
593 }
594 
595 int
596 intelspi_resume(device_t dev)
597 {
598 	struct intelspi_softc   *sc;
599 	int i;
600 
601 	sc = device_get_softc(dev);
602 
603 	for (i = 0; i < 9; i++) {
604 		unsigned long offset = i * sizeof(uint32_t);
605 		INTELSPI_WRITE(sc,
606 		    intelspi_infos[sc->sc_vers].reg_lpss_base + offset,
607 		    sc->sc_regs[i]);
608 	}
609 
610 	intelspi_init(sc);
611 
612 	/* Ensure the next transfer would reconfigure these */
613 	sc->sc_clock = 0;
614 	sc->sc_mode = 0;
615 
616 	return (bus_generic_resume(dev));
617 }
618