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
intelspi_txfifo_full(struct intelspi_softc * sc)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
intelspi_rxfifo_empty(struct intelspi_softc * sc)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
intelspi_fill_tx_fifo(struct intelspi_softc * sc)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
intelspi_drain_rx_fifo(struct intelspi_softc * sc)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
intelspi_transaction_done(struct intelspi_softc * sc)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
intelspi_transact(struct intelspi_softc * sc)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
intelspi_intr(void * arg)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
intelspi_init(struct intelspi_softc * sc)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
intelspi_set_cs(struct intelspi_softc * sc,int level)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
intelspi_transfer(device_t dev,device_t child,struct spi_command * cmd)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
intelspi_attach(device_t dev)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", DEVICE_UNIT_ANY);
531
532 bus_delayed_attach_children(dev);
533 return (0);
534
535 error:
536 INTELSPI_LOCK_DESTROY(sc);
537
538 if (sc->sc_mem_res != NULL)
539 bus_release_resource(dev, SYS_RES_MEMORY,
540 sc->sc_mem_rid, sc->sc_mem_res);
541
542 if (sc->sc_irq_res != NULL)
543 bus_release_resource(dev, SYS_RES_IRQ,
544 sc->sc_irq_rid, sc->sc_irq_res);
545
546 return (ENXIO);
547 }
548
549 int
intelspi_detach(device_t dev)550 intelspi_detach(device_t dev)
551 {
552 struct intelspi_softc *sc;
553 int error;
554
555 sc = device_get_softc(dev);
556
557 error = bus_generic_detach(dev);
558 if (error != 0)
559 return (error);
560
561 INTELSPI_LOCK_DESTROY(sc);
562
563 if (sc->sc_irq_ih)
564 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_ih);
565
566 if (sc->sc_mem_res != NULL)
567 bus_release_resource(dev, SYS_RES_MEMORY,
568 sc->sc_mem_rid, sc->sc_mem_res);
569
570 if (sc->sc_irq_res != NULL)
571 bus_release_resource(dev, SYS_RES_IRQ,
572 sc->sc_irq_rid, sc->sc_irq_res);
573
574 return (0);
575 }
576
577 int
intelspi_suspend(device_t dev)578 intelspi_suspend(device_t dev)
579 {
580 struct intelspi_softc *sc;
581 int err, i;
582
583 sc = device_get_softc(dev);
584
585 err = bus_generic_suspend(dev);
586 if (err)
587 return (err);
588
589 for (i = 0; i < 9; i++) {
590 unsigned long offset = i * sizeof(uint32_t);
591 sc->sc_regs[i] = INTELSPI_READ(sc,
592 intelspi_infos[sc->sc_vers].reg_lpss_base + offset);
593 }
594
595 /* Shutdown just in case */
596 INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR0, 0);
597
598 return (0);
599 }
600
601 int
intelspi_resume(device_t dev)602 intelspi_resume(device_t dev)
603 {
604 struct intelspi_softc *sc;
605 int i;
606
607 sc = device_get_softc(dev);
608
609 for (i = 0; i < 9; i++) {
610 unsigned long offset = i * sizeof(uint32_t);
611 INTELSPI_WRITE(sc,
612 intelspi_infos[sc->sc_vers].reg_lpss_base + offset,
613 sc->sc_regs[i]);
614 }
615
616 intelspi_init(sc);
617
618 /* Ensure the next transfer would reconfigure these */
619 sc->sc_clock = 0;
620 sc->sc_mode = 0;
621
622 return (bus_generic_resume(dev));
623 }
624