Lines 46-52
Link Here
|
46 |
#include <sys/endian.h> |
46 |
#include <sys/endian.h> |
47 |
|
47 |
|
48 |
#include <machine/bus.h> |
48 |
#include <machine/bus.h> |
|
|
49 |
#include <sys/mutex.h> |
49 |
#include <sys/rman.h> |
50 |
#include <sys/rman.h> |
|
|
51 |
#include <sys/queue.h> |
52 |
#include <sys/taskqueue.h> |
50 |
#include <machine/resource.h> |
53 |
#include <machine/resource.h> |
51 |
#include <sys/sysctl.h> |
54 |
#include <sys/sysctl.h> |
52 |
|
55 |
|
Lines 59-65
Link Here
|
59 |
|
62 |
|
60 |
#include "mmcbr_if.h" |
63 |
#include "mmcbr_if.h" |
61 |
|
64 |
|
62 |
#include <dev/rtsx/rtsxreg.h> |
65 |
#include "rtsxreg.h" |
63 |
|
66 |
|
64 |
#define RTSX_NREG ((0XFDAE - 0XFDA0) + (0xFD69 - 0xFD32) + (0xFE34 - 0xFE20)) |
67 |
#define RTSX_NREG ((0XFDAE - 0XFDA0) + (0xFD69 - 0xFD32) + (0xFE34 - 0xFE20)) |
65 |
#define SDMMC_MAXNSEGS ((MAXPHYS / PAGE_SIZE) + 1) |
68 |
#define SDMMC_MAXNSEGS ((MAXPHYS / PAGE_SIZE) + 1) |
Lines 82-87
Link Here
|
82 |
device_t rtsx_dev; /* device */ |
85 |
device_t rtsx_dev; /* device */ |
83 |
int rtsx_flags; /* device flags */ |
86 |
int rtsx_flags; /* device flags */ |
84 |
device_t rtsx_mmc_dev; /* device of mmc bus */ |
87 |
device_t rtsx_mmc_dev; /* device of mmc bus */ |
|
|
88 |
/* for card insert/remove - from dwmmc.c */ |
89 |
struct task card_task; /* Card presence check task */ |
90 |
struct timeout_task card_delayed_task;/* Card insert delayed task */ |
91 |
|
85 |
int rtsx_irq_res_id; /* bus IRQ resource id */ |
92 |
int rtsx_irq_res_id; /* bus IRQ resource id */ |
86 |
struct resource *rtsx_irq_res; /* bus IRQ resource */ |
93 |
struct resource *rtsx_irq_res; /* bus IRQ resource */ |
87 |
void *rtsx_irq_cookie; /* bus IRQ resource cookie */ |
94 |
void *rtsx_irq_cookie; /* bus IRQ resource cookie */ |
Lines 135-142
Link Here
|
135 |
static void rtsx_dma_free(struct rtsx_softc *sc); |
142 |
static void rtsx_dma_free(struct rtsx_softc *sc); |
136 |
static void rtsx_intr(void *arg); |
143 |
static void rtsx_intr(void *arg); |
137 |
static int rtsx_init(struct rtsx_softc *sc); |
144 |
static int rtsx_init(struct rtsx_softc *sc); |
138 |
static void rtsx_start(struct rtsx_softc *sc); |
145 |
static int rtsx_stop(struct rtsx_softc *sc); |
139 |
static void rtsx_stop(struct rtsx_softc *sc); |
|
|
140 |
static int rtsx_read(struct rtsx_softc *, uint16_t, uint8_t *); |
146 |
static int rtsx_read(struct rtsx_softc *, uint16_t, uint8_t *); |
141 |
static int rtsx_read_cfg(struct rtsx_softc *sc, uint8_t func, uint16_t addr, uint32_t *val); |
147 |
static int rtsx_read_cfg(struct rtsx_softc *sc, uint8_t func, uint16_t addr, uint32_t *val); |
142 |
static int rtsx_write(struct rtsx_softc *, uint16_t, uint8_t, uint8_t); |
148 |
static int rtsx_write(struct rtsx_softc *, uint16_t, uint8_t, uint8_t); |
Lines 148-155
Link Here
|
148 |
static int rtsx_bus_power_up(struct rtsx_softc *sc); |
154 |
static int rtsx_bus_power_up(struct rtsx_softc *sc); |
149 |
static int rtsx_bus_power_on(struct rtsx_softc *sc); |
155 |
static int rtsx_bus_power_on(struct rtsx_softc *sc); |
150 |
static int rtsx_is_card_present(struct rtsx_softc *sc); |
156 |
static int rtsx_is_card_present(struct rtsx_softc *sc); |
|
|
157 |
#if 0 /* done in task */ |
158 |
static void rtsx_start(struct rtsx_softc *sc); |
151 |
static void rtsx_card_insert(struct rtsx_softc *sc); |
159 |
static void rtsx_card_insert(struct rtsx_softc *sc); |
152 |
static void rtsx_card_remove(struct rtsx_softc *sc); |
160 |
static void rtsx_card_remove(struct rtsx_softc *sc); |
|
|
161 |
#endif |
153 |
static int rtsx_led_enable(struct rtsx_softc *sc); |
162 |
static int rtsx_led_enable(struct rtsx_softc *sc); |
154 |
static int rtsx_led_disable(struct rtsx_softc *sc); |
163 |
static int rtsx_led_disable(struct rtsx_softc *sc); |
155 |
|
164 |
|
Lines 185-190
Link Here
|
185 |
static int rtsx_mmcbr_get_ro(device_t bus, device_t child __unused); |
194 |
static int rtsx_mmcbr_get_ro(device_t bus, device_t child __unused); |
186 |
static int rtsx_mmcbr_acquire_host(device_t bus, device_t child __unused); |
195 |
static int rtsx_mmcbr_acquire_host(device_t bus, device_t child __unused); |
187 |
static int rtsx_mmcbr_release_host(device_t bus, device_t child __unused); |
196 |
static int rtsx_mmcbr_release_host(device_t bus, device_t child __unused); |
|
|
197 |
static void rtsx_card_task(void *arg, int pending __unused); |
198 |
static void rtsx_handle_card_present(struct rtsx_softc *sc); |
188 |
|
199 |
|
189 |
#define RTSX_LOCK_INIT(_sc) mtx_init(&(_sc)->rtsx_mtx, \ |
200 |
#define RTSX_LOCK_INIT(_sc) mtx_init(&(_sc)->rtsx_mtx, \ |
190 |
device_get_nameunit(sc->rtsx_dev), "rtsx", MTX_DEF) |
201 |
device_get_nameunit(sc->rtsx_dev), "rtsx", MTX_DEF) |
Lines 411-417
Link Here
|
411 |
} |
422 |
} |
412 |
} |
423 |
} |
413 |
|
424 |
|
|
|
425 |
/* from dwmmc.c */ |
426 |
/* called from the IRQ handler */ |
414 |
static void |
427 |
static void |
|
|
428 |
rtsx_handle_card_present(struct rtsx_softc *sc) |
429 |
{ |
430 |
bool was_present; |
431 |
bool is_present; |
432 |
|
433 |
was_present = sc->rtsx_mmc_dev != NULL; |
434 |
is_present = (rtsx_is_card_present(sc) != 0); |
435 |
|
436 |
if (!was_present && is_present) { |
437 |
/* small delay for the controller */ |
438 |
taskqueue_enqueue_timeout(taskqueue_swi_giant, |
439 |
&sc->card_delayed_task, -(hz / 2)); |
440 |
} else if (was_present && !is_present) { |
441 |
taskqueue_enqueue(taskqueue_swi_giant, &sc->card_task); |
442 |
} |
443 |
} |
444 |
|
445 |
/* this is called at startup */ |
446 |
static void |
447 |
rtsx_card_task(void *arg, int pending __unused) |
448 |
{ |
449 |
struct rtsx_softc *sc = arg; |
450 |
|
451 |
RTSX_LOCK(sc); |
452 |
|
453 |
if (rtsx_is_card_present(sc) != 0) { |
454 |
sc->rtsx_flags |= RTSX_F_CARD_PRESENT; |
455 |
/* Card is present, attach if necessary */ |
456 |
if (sc->rtsx_mmc_dev == NULL) { |
457 |
if (bootverbose) |
458 |
device_printf(sc->rtsx_dev, "Card inserted\n"); |
459 |
|
460 |
sc->rtsx_mmc_dev = device_add_child(sc->rtsx_dev, "mmc", -1); |
461 |
RTSX_UNLOCK(sc); |
462 |
if (sc->rtsx_mmc_dev != NULL) { |
463 |
device_set_ivars(sc->rtsx_mmc_dev, sc); |
464 |
(void)device_probe_and_attach(sc->rtsx_mmc_dev); |
465 |
} |
466 |
} else |
467 |
RTSX_UNLOCK(sc); |
468 |
|
469 |
} else { |
470 |
sc->rtsx_flags &= ~RTSX_F_CARD_PRESENT; |
471 |
/* Card isn't present, detach if necessary */ |
472 |
if (sc->rtsx_mmc_dev != NULL) { |
473 |
if (bootverbose) |
474 |
device_printf(sc->rtsx_dev, "Card removed\n"); |
475 |
|
476 |
RTSX_UNLOCK(sc); |
477 |
device_delete_child(sc->rtsx_dev, sc->rtsx_mmc_dev); |
478 |
sc->rtsx_mmc_dev = NULL; |
479 |
} else |
480 |
RTSX_UNLOCK(sc); |
481 |
} |
482 |
} |
483 |
|
484 |
static void |
415 |
rtsx_intr(void *arg) |
485 |
rtsx_intr(void *arg) |
416 |
{ |
486 |
{ |
417 |
struct rtsx_softc *sc = arg; |
487 |
struct rtsx_softc *sc = arg; |
Lines 428-447
Link Here
|
428 |
WRITE4(sc, RTSX_BIPR, status); |
498 |
WRITE4(sc, RTSX_BIPR, status); |
429 |
|
499 |
|
430 |
if (((enabled & status) == 0) || status == 0xffffffff) { |
500 |
if (((enabled & status) == 0) || status == 0xffffffff) { |
|
|
501 |
device_printf(sc->rtsx_dev, "FLAGS\n"); |
431 |
RTSX_UNLOCK(sc); |
502 |
RTSX_UNLOCK(sc); |
432 |
return; |
503 |
return; |
433 |
} |
504 |
} |
|
|
505 |
|
506 |
/* start task to handle SD card status change */ |
507 |
/* from dwmmc.c */ |
508 |
if (status & RTSX_SD_INT) { |
509 |
device_printf(sc->rtsx_dev, "A\n"); |
510 |
rtsx_handle_card_present(sc); |
511 |
} |
434 |
if (sc->rtsx_req == NULL) { |
512 |
if (sc->rtsx_req == NULL) { |
|
|
513 |
device_printf(sc->rtsx_dev, "B\n"); |
514 |
#if 0 /* might have been SD int */ |
435 |
device_printf(sc->rtsx_dev, "Spurious interrupt - no active request\n"); |
515 |
device_printf(sc->rtsx_dev, "Spurious interrupt - no active request\n"); |
|
|
516 |
#endif |
436 |
RTSX_UNLOCK(sc); |
517 |
RTSX_UNLOCK(sc); |
437 |
return; |
518 |
return; |
438 |
} |
519 |
} |
439 |
if (status & (RTSX_TRANS_OK_INT | RTSX_TRANS_FAIL_INT)) { |
520 |
if (status & (RTSX_TRANS_OK_INT | RTSX_TRANS_FAIL_INT)) { |
440 |
sc->rtsx_intr_status |= status; |
521 |
sc->rtsx_intr_status |= status; |
441 |
wakeup(&sc->rtsx_intr_status); |
522 |
wakeup(&sc->rtsx_intr_status); |
442 |
} |
523 |
} else |
|
|
524 |
device_printf(sc->rtsx_dev, "NODMA\n"); |
525 |
|
443 |
RTSX_UNLOCK(sc); |
526 |
RTSX_UNLOCK(sc); |
444 |
|
527 |
|
|
|
528 |
|
445 |
/*--- See taskqueue_enqueue_timeout() |
529 |
/*--- See taskqueue_enqueue_timeout() |
446 |
|
530 |
|
447 |
if (status & RTSX_SD_INT) { |
531 |
if (status & RTSX_SD_INT) { |
Lines 600-605
Link Here
|
600 |
return (0); |
684 |
return (0); |
601 |
} |
685 |
} |
602 |
|
686 |
|
|
|
687 |
#if 0 /* done in task */ |
603 |
static void |
688 |
static void |
604 |
rtsx_start(struct rtsx_softc *sc) |
689 |
rtsx_start(struct rtsx_softc *sc) |
605 |
{ |
690 |
{ |
Lines 608-622
Link Here
|
608 |
else |
693 |
else |
609 |
rtsx_card_remove(sc); |
694 |
rtsx_card_remove(sc); |
610 |
} |
695 |
} |
|
|
696 |
#endif |
611 |
|
697 |
|
612 |
static void |
698 |
static int |
613 |
rtsx_stop(struct rtsx_softc *sc) |
699 |
rtsx_stop(struct rtsx_softc *sc) |
614 |
{ |
700 |
{ |
615 |
if (sc->rtsx_mmc_dev != NULL) { |
701 |
int ret = 0; |
616 |
/* detach mmc bus */ |
702 |
|
617 |
device_delete_child(sc->rtsx_dev, sc->rtsx_mmc_dev); |
703 |
/* automatically deletes any children */ |
618 |
sc->rtsx_mmc_dev = NULL; |
704 |
ret = device_delete_children(sc->rtsx_dev); |
619 |
} |
705 |
sc->rtsx_mmc_dev = NULL; |
|
|
706 |
|
707 |
return (ret); |
620 |
} |
708 |
} |
621 |
|
709 |
|
622 |
static int |
710 |
static int |
Lines 1049-1054
Link Here
|
1049 |
return (status & RTSX_SD_EXIST); |
1137 |
return (status & RTSX_SD_EXIST); |
1050 |
} |
1138 |
} |
1051 |
|
1139 |
|
|
|
1140 |
#if 0 /* done in the task */ |
1052 |
static void |
1141 |
static void |
1053 |
rtsx_card_insert(struct rtsx_softc *sc) |
1142 |
rtsx_card_insert(struct rtsx_softc *sc) |
1054 |
{ |
1143 |
{ |
Lines 1097-1102
Link Here
|
1097 |
} |
1186 |
} |
1098 |
rtsx_led_disable(sc); |
1187 |
rtsx_led_disable(sc); |
1099 |
} |
1188 |
} |
|
|
1189 |
#endif |
1100 |
|
1190 |
|
1101 |
static int |
1191 |
static int |
1102 |
rtsx_led_enable(struct rtsx_softc *sc) |
1192 |
rtsx_led_enable(struct rtsx_softc *sc) |
Lines 1948-1954
Link Here
|
1948 |
struct rtsx_softc *sc; |
2038 |
struct rtsx_softc *sc; |
1949 |
|
2039 |
|
1950 |
if (bootverbose) |
2040 |
if (bootverbose) |
1951 |
device_printf(bus, "rtsx_mmcbr_acquite_host()\n"); |
2041 |
device_printf(bus, "rtsx_mmcbr_acquire_host()\n"); |
1952 |
|
2042 |
|
1953 |
sc = device_get_softc(bus); |
2043 |
sc = device_get_softc(bus); |
1954 |
RTSX_LOCK(sc); |
2044 |
RTSX_LOCK(sc); |
Lines 2101-2109
Link Here
|
2101 |
if (error) { |
2191 |
if (error) { |
2102 |
goto destroy_rtsx_irq; |
2192 |
goto destroy_rtsx_irq; |
2103 |
} |
2193 |
} |
|
|
2194 |
#if 0 /* done in task */ |
2104 |
/* Start device */ |
2195 |
/* Start device */ |
2105 |
rtsx_start(sc); |
2196 |
rtsx_start(sc); |
|
|
2197 |
#else |
2198 |
/* from dwmmc.c */ |
2199 |
TASK_INIT(&sc->card_task, 0, rtsx_card_task, sc); |
2200 |
/* really giant? */ |
2201 |
TIMEOUT_TASK_INIT(taskqueue_swi_giant, &sc->card_delayed_task, 0, |
2202 |
rtsx_card_task, sc); |
2106 |
|
2203 |
|
|
|
2204 |
/* |
2205 |
* Schedule a card detection as we won't get an interrupt |
2206 |
* if the card is inserted when we attach |
2207 |
*/ |
2208 |
rtsx_card_task(sc, 0); |
2209 |
#endif |
2210 |
|
2107 |
if (bootverbose) |
2211 |
if (bootverbose) |
2108 |
device_printf(dev, "Device attached\n"); |
2212 |
device_printf(dev, "Device attached\n"); |
2109 |
|
2213 |
|
Lines 2127-2140
Link Here
|
2127 |
rtsx_detach(device_t dev) |
2231 |
rtsx_detach(device_t dev) |
2128 |
{ |
2232 |
{ |
2129 |
struct rtsx_softc *sc = device_get_softc(dev); |
2233 |
struct rtsx_softc *sc = device_get_softc(dev); |
|
|
2234 |
int err; |
2130 |
|
2235 |
|
2131 |
if (bootverbose) |
2236 |
if (bootverbose) |
2132 |
device_printf(dev, "Detach - Vendor ID: 0x%x - Device ID: 0x%x\n", |
2237 |
device_printf(dev, "Detach - Vendor ID: 0x%x - Device ID: 0x%x\n", |
2133 |
pci_get_vendor(dev), pci_get_device(dev)); |
2238 |
pci_get_vendor(dev), pci_get_device(dev)); |
2134 |
|
2239 |
|
2135 |
/* Stop device */ |
2240 |
/* Stop device */ |
2136 |
rtsx_stop(sc); |
2241 |
err = rtsx_stop(sc); |
|
|
2242 |
if (err != 0) |
2243 |
return err; |
2137 |
|
2244 |
|
|
|
2245 |
taskqueue_drain(taskqueue_swi_giant, &sc->card_task); |
2246 |
taskqueue_drain_timeout(taskqueue_swi_giant, &sc->card_delayed_task); |
2247 |
|
2138 |
/* Teardown the state in our softc created in our attach routine. */ |
2248 |
/* Teardown the state in our softc created in our attach routine. */ |
2139 |
rtsx_dma_free(sc); |
2249 |
rtsx_dma_free(sc); |
2140 |
if (sc->rtsx_res != NULL) |
2250 |
if (sc->rtsx_res != NULL) |
Lines 2148-2153
Link Here
|
2148 |
pci_release_msi(dev); |
2258 |
pci_release_msi(dev); |
2149 |
} |
2259 |
} |
2150 |
RTSX_LOCK_DESTROY(sc); |
2260 |
RTSX_LOCK_DESTROY(sc); |
|
|
2261 |
|
2151 |
return (0); |
2262 |
return (0); |
2152 |
} |
2263 |
} |
2153 |
|
2264 |
|