Changeset View
Changeset View
Standalone View
Standalone View
sys/arm/allwinner/aw_mmc.c
Show First 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | |||||
#include "opt_mmccam.h" | #include "opt_mmccam.h" | ||||
#ifdef MMCCAM | #ifdef MMCCAM | ||||
#include <cam/cam.h> | #include <cam/cam.h> | ||||
#include <cam/cam_ccb.h> | #include <cam/cam_ccb.h> | ||||
#include <cam/cam_debug.h> | #include <cam/cam_debug.h> | ||||
#include <cam/cam_sim.h> | #include <cam/cam_sim.h> | ||||
#include <cam/cam_xpt_sim.h> | #include <cam/cam_xpt_sim.h> | ||||
#include <cam/mmc/mmc_sim.h> | |||||
#include "mmc_sim_if.h" | |||||
#endif | #endif | ||||
#define AW_MMC_MEMRES 0 | #define AW_MMC_MEMRES 0 | ||||
#define AW_MMC_IRQRES 1 | #define AW_MMC_IRQRES 1 | ||||
#define AW_MMC_RESSZ 2 | #define AW_MMC_RESSZ 2 | ||||
#define AW_MMC_DMA_SEGS (PAGE_SIZE / sizeof(struct aw_mmc_dma_desc)) | #define AW_MMC_DMA_SEGS (PAGE_SIZE / sizeof(struct aw_mmc_dma_desc)) | ||||
#define AW_MMC_DMA_DESC_SIZE (sizeof(struct aw_mmc_dma_desc) * AW_MMC_DMA_SEGS) | #define AW_MMC_DMA_DESC_SIZE (sizeof(struct aw_mmc_dma_desc) * AW_MMC_DMA_SEGS) | ||||
#define AW_MMC_DMA_FTRGLEVEL 0x20070008 | #define AW_MMC_DMA_FTRGLEVEL 0x20070008 | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | struct aw_mmc_softc { | ||||
int aw_bus_busy; | int aw_bus_busy; | ||||
int aw_resid; | int aw_resid; | ||||
int aw_timeout; | int aw_timeout; | ||||
struct callout aw_timeoutc; | struct callout aw_timeoutc; | ||||
struct mmc_host aw_host; | struct mmc_host aw_host; | ||||
struct mmc_fdt_helper mmc_helper; | struct mmc_fdt_helper mmc_helper; | ||||
#ifdef MMCCAM | #ifdef MMCCAM | ||||
union ccb * ccb; | union ccb * ccb; | ||||
struct cam_devq * devq; | struct mmc_sim mmc_sim; | ||||
struct cam_sim * sim; | |||||
struct mtx sim_mtx; | |||||
#else | #else | ||||
struct mmc_request * aw_req; | struct mmc_request * aw_req; | ||||
#endif | #endif | ||||
struct mtx aw_mtx; | struct mtx aw_mtx; | ||||
struct resource * aw_res[AW_MMC_RESSZ]; | struct resource * aw_res[AW_MMC_RESSZ]; | ||||
struct aw_mmc_conf * aw_mmc_conf; | struct aw_mmc_conf * aw_mmc_conf; | ||||
uint32_t aw_intr; | uint32_t aw_intr; | ||||
uint32_t aw_intr_wait; | uint32_t aw_intr_wait; | ||||
Show All 26 Lines | |||||
static int aw_mmc_init(struct aw_mmc_softc *); | static int aw_mmc_init(struct aw_mmc_softc *); | ||||
static void aw_mmc_intr(void *); | static void aw_mmc_intr(void *); | ||||
static int aw_mmc_update_clock(struct aw_mmc_softc *, uint32_t); | static int aw_mmc_update_clock(struct aw_mmc_softc *, uint32_t); | ||||
static void aw_mmc_helper_cd_handler(device_t, bool); | static void aw_mmc_helper_cd_handler(device_t, bool); | ||||
static void aw_mmc_print_error(uint32_t); | static void aw_mmc_print_error(uint32_t); | ||||
static int aw_mmc_update_ios(device_t, device_t); | static int aw_mmc_update_ios(device_t, device_t); | ||||
static int aw_mmc_request(device_t, device_t, struct mmc_request *); | static int aw_mmc_request(device_t, device_t, struct mmc_request *); | ||||
#ifndef MMCCAM | |||||
static int aw_mmc_get_ro(device_t, device_t); | static int aw_mmc_get_ro(device_t, device_t); | ||||
static int aw_mmc_acquire_host(device_t, device_t); | static int aw_mmc_acquire_host(device_t, device_t); | ||||
static int aw_mmc_release_host(device_t, device_t); | static int aw_mmc_release_host(device_t, device_t); | ||||
#ifdef MMCCAM | |||||
static void aw_mmc_cam_action(struct cam_sim *, union ccb *); | |||||
static void aw_mmc_cam_poll(struct cam_sim *); | |||||
static int aw_mmc_cam_settran_settings(struct aw_mmc_softc *, union ccb *); | |||||
static int aw_mmc_cam_request(struct aw_mmc_softc *, union ccb *); | |||||
static void aw_mmc_cam_handle_mmcio(struct cam_sim *, union ccb *); | |||||
#endif | #endif | ||||
#define AW_MMC_LOCK(_sc) mtx_lock(&(_sc)->aw_mtx) | #define AW_MMC_LOCK(_sc) mtx_lock(&(_sc)->aw_mtx) | ||||
#define AW_MMC_UNLOCK(_sc) mtx_unlock(&(_sc)->aw_mtx) | #define AW_MMC_UNLOCK(_sc) mtx_unlock(&(_sc)->aw_mtx) | ||||
#define AW_MMC_READ_4(_sc, _reg) \ | #define AW_MMC_READ_4(_sc, _reg) \ | ||||
bus_read_4((_sc)->aw_res[AW_MMC_MEMRES], _reg) | bus_read_4((_sc)->aw_res[AW_MMC_MEMRES], _reg) | ||||
#define AW_MMC_WRITE_4(_sc, _reg, _value) \ | #define AW_MMC_WRITE_4(_sc, _reg, _value) \ | ||||
bus_write_4((_sc)->aw_res[AW_MMC_MEMRES], _reg, _value) | bus_write_4((_sc)->aw_res[AW_MMC_MEMRES], _reg, _value) | ||||
SYSCTL_NODE(_hw, OID_AUTO, aw_mmc, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, | SYSCTL_NODE(_hw, OID_AUTO, aw_mmc, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, | ||||
"aw_mmc driver"); | "aw_mmc driver"); | ||||
static int aw_mmc_debug = 0; | static int aw_mmc_debug = 0; | ||||
SYSCTL_INT(_hw_aw_mmc, OID_AUTO, debug, CTLFLAG_RWTUN, &aw_mmc_debug, 0, | SYSCTL_INT(_hw_aw_mmc, OID_AUTO, debug, CTLFLAG_RWTUN, &aw_mmc_debug, 0, | ||||
"Debug level bit0=card changes bit1=ios changes, bit2=interrupts, bit3=commands"); | "Debug level bit0=card changes bit1=ios changes, bit2=interrupts, bit3=commands"); | ||||
#define AW_MMC_DEBUG_CARD 0x1 | #define AW_MMC_DEBUG_CARD 0x1 | ||||
#define AW_MMC_DEBUG_IOS 0x2 | #define AW_MMC_DEBUG_IOS 0x2 | ||||
#define AW_MMC_DEBUG_INT 0x4 | #define AW_MMC_DEBUG_INT 0x4 | ||||
#define AW_MMC_DEBUG_CMD 0x8 | #define AW_MMC_DEBUG_CMD 0x8 | ||||
#ifdef MMCCAM | #ifdef MMCCAM | ||||
static void | static int | ||||
aw_mmc_cam_handle_mmcio(struct cam_sim *sim, union ccb *ccb) | aw_mmc_get_tran_settings(device_t dev, struct ccb_trans_settings_mmc *cts) | ||||
{ | { | ||||
struct aw_mmc_softc *sc; | struct aw_mmc_softc *sc; | ||||
sc = cam_sim_softc(sim); | sc = device_get_softc(dev); | ||||
aw_mmc_cam_request(sc, ccb); | cts->host_ocr = sc->aw_host.host_ocr; | ||||
} | cts->host_f_min = sc->aw_host.f_min; | ||||
cts->host_f_max = sc->aw_host.f_max; | |||||
static void | cts->host_caps = sc->aw_host.caps; | ||||
aw_mmc_cam_action(struct cam_sim *sim, union ccb *ccb) | cts->host_max_data = (sc->aw_mmc_conf->dma_xferlen * | ||||
{ | |||||
struct aw_mmc_softc *sc; | |||||
sc = cam_sim_softc(sim); | |||||
if (sc == NULL) { | |||||
ccb->ccb_h.status = CAM_SEL_TIMEOUT; | |||||
xpt_done(ccb); | |||||
return; | |||||
} | |||||
mtx_assert(&sc->sim_mtx, MA_OWNED); | |||||
switch (ccb->ccb_h.func_code) { | |||||
case XPT_PATH_INQ: | |||||
mmc_path_inq(&ccb->cpi, "Deglitch Networks", sim, | |||||
(sc->aw_mmc_conf->dma_xferlen * AW_MMC_DMA_SEGS) / | |||||
MMC_SECTOR_SIZE); | |||||
break; | |||||
case XPT_GET_TRAN_SETTINGS: | |||||
{ | |||||
struct ccb_trans_settings *cts = &ccb->cts; | |||||
if (__predict_false(aw_mmc_debug & AW_MMC_DEBUG_IOS)) | |||||
device_printf(sc->aw_dev, "Got XPT_GET_TRAN_SETTINGS\n"); | |||||
cts->protocol = PROTO_MMCSD; | |||||
cts->protocol_version = 1; | |||||
cts->transport = XPORT_MMCSD; | |||||
cts->transport_version = 1; | |||||
cts->xport_specific.valid = 0; | |||||
cts->proto_specific.mmc.host_ocr = sc->aw_host.host_ocr; | |||||
cts->proto_specific.mmc.host_f_min = sc->aw_host.f_min; | |||||
cts->proto_specific.mmc.host_f_max = sc->aw_host.f_max; | |||||
cts->proto_specific.mmc.host_caps = sc->aw_host.caps; | |||||
cts->proto_specific.mmc.host_max_data = (sc->aw_mmc_conf->dma_xferlen * | |||||
AW_MMC_DMA_SEGS) / MMC_SECTOR_SIZE; | AW_MMC_DMA_SEGS) / MMC_SECTOR_SIZE; | ||||
memcpy(&cts->proto_specific.mmc.ios, &sc->aw_host.ios, sizeof(struct mmc_ios)); | memcpy(&cts->ios, &sc->aw_host.ios, sizeof(struct mmc_ios)); | ||||
ccb->ccb_h.status = CAM_REQ_CMP; | |||||
break; | |||||
} | |||||
case XPT_SET_TRAN_SETTINGS: | |||||
{ | |||||
if (__predict_false(aw_mmc_debug & AW_MMC_DEBUG_IOS)) | |||||
device_printf(sc->aw_dev, "Got XPT_SET_TRAN_SETTINGS\n"); | |||||
aw_mmc_cam_settran_settings(sc, ccb); | |||||
ccb->ccb_h.status = CAM_REQ_CMP; | |||||
break; | |||||
} | |||||
case XPT_RESET_BUS: | |||||
if (__predict_false(aw_mmc_debug & AW_MMC_DEBUG_IOS)) | |||||
device_printf(sc->aw_dev, "Got XPT_RESET_BUS, ACK it...\n"); | |||||
ccb->ccb_h.status = CAM_REQ_CMP; | |||||
break; | |||||
case XPT_MMC_IO: | |||||
/* | |||||
* Here is the HW-dependent part of | |||||
* sending the command to the underlying h/w | |||||
* At some point in the future an interrupt comes. | |||||
* Then the request will be marked as completed. | |||||
*/ | |||||
ccb->ccb_h.status = CAM_REQ_INPROG; | |||||
aw_mmc_cam_handle_mmcio(sim, ccb); | return (0); | ||||
return; | |||||
/* NOTREACHED */ | |||||
break; | |||||
default: | |||||
ccb->ccb_h.status = CAM_REQ_INVALID; | |||||
break; | |||||
} | } | ||||
xpt_done(ccb); | |||||
return; | |||||
} | |||||
static void | |||||
aw_mmc_cam_poll(struct cam_sim *sim) | |||||
{ | |||||
return; | |||||
} | |||||
static int | static int | ||||
aw_mmc_cam_settran_settings(struct aw_mmc_softc *sc, union ccb *ccb) | aw_mmc_set_tran_settings(device_t dev, struct ccb_trans_settings_mmc *cts) | ||||
{ | { | ||||
struct aw_mmc_softc *sc; | |||||
struct mmc_ios *ios; | struct mmc_ios *ios; | ||||
struct mmc_ios *new_ios; | struct mmc_ios *new_ios; | ||||
struct ccb_trans_settings_mmc *cts; | |||||
sc = device_get_softc(dev); | |||||
ios = &sc->aw_host.ios; | ios = &sc->aw_host.ios; | ||||
cts = &ccb->cts.proto_specific.mmc; | |||||
new_ios = &cts->ios; | new_ios = &cts->ios; | ||||
/* Update only requested fields */ | /* Update only requested fields */ | ||||
if (cts->ios_valid & MMC_CLK) { | if (cts->ios_valid & MMC_CLK) { | ||||
ios->clock = new_ios->clock; | ios->clock = new_ios->clock; | ||||
if (__predict_false(aw_mmc_debug & AW_MMC_DEBUG_IOS)) | if (__predict_false(aw_mmc_debug & AW_MMC_DEBUG_IOS)) | ||||
device_printf(sc->aw_dev, "Clock => %d\n", ios->clock); | device_printf(sc->aw_dev, "Clock => %d\n", ios->clock); | ||||
} | } | ||||
Show All 27 Lines | if (cts->ios_valid & MMC_BM) { | ||||
if (__predict_false(aw_mmc_debug & AW_MMC_DEBUG_IOS)) | if (__predict_false(aw_mmc_debug & AW_MMC_DEBUG_IOS)) | ||||
device_printf(sc->aw_dev, "Bus mode => %d\n", ios->bus_mode); | device_printf(sc->aw_dev, "Bus mode => %d\n", ios->bus_mode); | ||||
} | } | ||||
return (aw_mmc_update_ios(sc->aw_dev, NULL)); | return (aw_mmc_update_ios(sc->aw_dev, NULL)); | ||||
} | } | ||||
static int | static int | ||||
aw_mmc_cam_request(struct aw_mmc_softc *sc, union ccb *ccb) | aw_mmc_cam_request(device_t dev, union ccb *ccb) | ||||
{ | { | ||||
struct aw_mmc_softc *sc; | |||||
struct ccb_mmcio *mmcio; | struct ccb_mmcio *mmcio; | ||||
sc = device_get_softc(dev); | |||||
mmcio = &ccb->mmcio; | mmcio = &ccb->mmcio; | ||||
AW_MMC_LOCK(sc); | AW_MMC_LOCK(sc); | ||||
if (__predict_false(aw_mmc_debug & AW_MMC_DEBUG_CMD)) { | if (__predict_false(aw_mmc_debug & AW_MMC_DEBUG_CMD)) { | ||||
device_printf(sc->aw_dev, "CMD%u arg %#x flags %#x dlen %u dflags %#x\n", | device_printf(sc->aw_dev, "CMD%u arg %#x flags %#x dlen %u dflags %#x\n", | ||||
mmcio->cmd.opcode, mmcio->cmd.arg, mmcio->cmd.flags, | mmcio->cmd.opcode, mmcio->cmd.arg, mmcio->cmd.flags, | ||||
mmcio->cmd.data != NULL ? (unsigned int) mmcio->cmd.data->len : 0, | mmcio->cmd.data != NULL ? (unsigned int) mmcio->cmd.data->len : 0, | ||||
Show All 19 Lines | |||||
static void | static void | ||||
aw_mmc_helper_cd_handler(device_t dev, bool present) | aw_mmc_helper_cd_handler(device_t dev, bool present) | ||||
{ | { | ||||
struct aw_mmc_softc *sc; | struct aw_mmc_softc *sc; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
#ifdef MMCCAM | #ifdef MMCCAM | ||||
mmccam_start_discovery(sc->sim); | mmc_cam_sim_discover(&sc->mmc_sim); | ||||
#else | #else | ||||
AW_MMC_LOCK(sc); | AW_MMC_LOCK(sc); | ||||
if (present) { | if (present) { | ||||
if (sc->child == NULL) { | if (sc->child == NULL) { | ||||
if (__predict_false(aw_mmc_debug & AW_MMC_DEBUG_CARD)) | if (__predict_false(aw_mmc_debug & AW_MMC_DEBUG_CARD)) | ||||
device_printf(sc->aw_dev, "Card inserted\n"); | device_printf(sc->aw_dev, "Card inserted\n"); | ||||
sc->child = device_add_child(sc->aw_dev, "mmc", -1); | sc->child = device_add_child(sc->aw_dev, "mmc", -1); | ||||
▲ Show 20 Lines • Show All 123 Lines • ▼ Show 20 Lines | #endif | ||||
sc->aw_host.f_max = 52000000; | sc->aw_host.f_max = 52000000; | ||||
sc->aw_host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340; | sc->aw_host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340; | ||||
sc->aw_host.caps |= MMC_CAP_HSPEED | MMC_CAP_SIGNALING_330; | sc->aw_host.caps |= MMC_CAP_HSPEED | MMC_CAP_SIGNALING_330; | ||||
mmc_fdt_parse(dev, 0, &sc->mmc_helper, &sc->aw_host); | mmc_fdt_parse(dev, 0, &sc->mmc_helper, &sc->aw_host); | ||||
mmc_fdt_gpio_setup(dev, 0, &sc->mmc_helper, aw_mmc_helper_cd_handler); | mmc_fdt_gpio_setup(dev, 0, &sc->mmc_helper, aw_mmc_helper_cd_handler); | ||||
#ifdef MMCCAM | #ifdef MMCCAM | ||||
sc->ccb = NULL; | sc->ccb = NULL; | ||||
if ((sc->devq = cam_simq_alloc(1)) == NULL) { | |||||
goto fail; | |||||
} | |||||
mtx_init(&sc->sim_mtx, "awmmcsim", NULL, MTX_DEF); | if (mmc_cam_sim_alloc(dev, "aw_mmc", &sc->mmc_sim) != 0) { | ||||
sc->sim = cam_sim_alloc_dev(aw_mmc_cam_action, aw_mmc_cam_poll, | device_printf(dev, "cannot alloc cam sim\n"); | ||||
"aw_mmc_sim", sc, dev, | |||||
&sc->sim_mtx, 1, 1, sc->devq); | |||||
if (sc->sim == NULL) { | |||||
cam_simq_free(sc->devq); | |||||
device_printf(dev, "cannot allocate CAM SIM\n"); | |||||
goto fail; | goto fail; | ||||
} | } | ||||
mtx_lock(&sc->sim_mtx); | |||||
if (xpt_bus_register(sc->sim, sc->aw_dev, 0) != 0) { | |||||
device_printf(dev, "cannot register SCSI pass-through bus\n"); | |||||
cam_sim_free(sc->sim, FALSE); | |||||
cam_simq_free(sc->devq); | |||||
mtx_unlock(&sc->sim_mtx); | |||||
goto fail; | |||||
} | |||||
mtx_unlock(&sc->sim_mtx); | |||||
#endif /* MMCCAM */ | #endif /* MMCCAM */ | ||||
return (0); | return (0); | ||||
fail: | fail: | ||||
callout_drain(&sc->aw_timeoutc); | callout_drain(&sc->aw_timeoutc); | ||||
mtx_destroy(&sc->aw_mtx); | mtx_destroy(&sc->aw_mtx); | ||||
bus_teardown_intr(dev, sc->aw_res[AW_MMC_IRQRES], sc->aw_intrhand); | bus_teardown_intr(dev, sc->aw_res[AW_MMC_IRQRES], sc->aw_intrhand); | ||||
bus_release_resources(dev, aw_mmc_res_spec, sc->aw_res); | bus_release_resources(dev, aw_mmc_res_spec, sc->aw_res); | ||||
#ifdef MMCCAM | |||||
if (sc->sim != NULL) { | |||||
mtx_lock(&sc->sim_mtx); | |||||
xpt_bus_deregister(cam_sim_path(sc->sim)); | |||||
cam_sim_free(sc->sim, FALSE); | |||||
mtx_unlock(&sc->sim_mtx); | |||||
} | |||||
if (sc->devq != NULL) | |||||
cam_simq_free(sc->devq); | |||||
#endif | |||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
static int | static int | ||||
aw_mmc_detach(device_t dev) | aw_mmc_detach(device_t dev) | ||||
{ | { | ||||
struct aw_mmc_softc *sc; | struct aw_mmc_softc *sc; | ||||
device_t d; | device_t d; | ||||
Show All 18 Lines | aw_mmc_detach(device_t dev) | ||||
aw_mmc_teardown_dma(sc); | aw_mmc_teardown_dma(sc); | ||||
mtx_destroy(&sc->aw_mtx); | mtx_destroy(&sc->aw_mtx); | ||||
bus_teardown_intr(dev, sc->aw_res[AW_MMC_IRQRES], sc->aw_intrhand); | bus_teardown_intr(dev, sc->aw_res[AW_MMC_IRQRES], sc->aw_intrhand); | ||||
bus_release_resources(dev, aw_mmc_res_spec, sc->aw_res); | bus_release_resources(dev, aw_mmc_res_spec, sc->aw_res); | ||||
#ifdef MMCCAM | #ifdef MMCCAM | ||||
if (sc->sim != NULL) { | mmc_cam_sim_free(&sc->mmc_sim); | ||||
mtx_lock(&sc->sim_mtx); | |||||
xpt_bus_deregister(cam_sim_path(sc->sim)); | |||||
cam_sim_free(sc->sim, FALSE); | |||||
mtx_unlock(&sc->sim_mtx); | |||||
} | |||||
if (sc->devq != NULL) | |||||
cam_simq_free(sc->devq); | |||||
#endif | #endif | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
aw_dma_desc_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int err) | aw_dma_desc_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int err) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 682 Lines • ▼ Show 20 Lines | aw_mmc_write_ivar(device_t bus, device_t child, int which, | ||||
case MMCBR_IVAR_F_MAX: | case MMCBR_IVAR_F_MAX: | ||||
case MMCBR_IVAR_MAX_DATA: | case MMCBR_IVAR_MAX_DATA: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
#ifdef MMCCAM | |||||
#endif | |||||
imp: You can safely omit this, I think.
| |||||
manuAuthorUnsubmitted Done Inline ActionsYeah, will update, leftover from the conversion obviously. manu: Yeah, will update, leftover from the conversion obviously. | |||||
static int | static int | ||||
aw_mmc_update_clock(struct aw_mmc_softc *sc, uint32_t clkon) | aw_mmc_update_clock(struct aw_mmc_softc *sc, uint32_t clkon) | ||||
{ | { | ||||
uint32_t reg; | uint32_t reg; | ||||
int retry; | int retry; | ||||
reg = AW_MMC_READ_4(sc, AW_MMC_CKCR); | reg = AW_MMC_READ_4(sc, AW_MMC_CKCR); | ||||
reg &= ~(AW_MMC_CKCR_ENB | AW_MMC_CKCR_LOW_POWER | | reg &= ~(AW_MMC_CKCR_ENB | AW_MMC_CKCR_LOW_POWER | | ||||
Show All 26 Lines | if (sc->aw_mmc_conf->mask_data0) { | ||||
reg = AW_MMC_READ_4(sc, AW_MMC_CKCR); | reg = AW_MMC_READ_4(sc, AW_MMC_CKCR); | ||||
reg &= ~AW_MMC_CKCR_MASK_DATA0; | reg &= ~AW_MMC_CKCR_MASK_DATA0; | ||||
AW_MMC_WRITE_4(sc, AW_MMC_CKCR, reg); | AW_MMC_WRITE_4(sc, AW_MMC_CKCR, reg); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
#ifndef MMCCAM | |||||
static int | static int | ||||
aw_mmc_switch_vccq(device_t bus, device_t child) | aw_mmc_switch_vccq(device_t bus, device_t child) | ||||
{ | { | ||||
struct aw_mmc_softc *sc; | struct aw_mmc_softc *sc; | ||||
int uvolt, err; | int uvolt, err; | ||||
sc = device_get_softc(bus); | sc = device_get_softc(bus); | ||||
Show All 17 Lines | device_printf(sc->aw_dev, | ||||
"Cannot set vqmmc to %d<->%d\n", | "Cannot set vqmmc to %d<->%d\n", | ||||
uvolt, | uvolt, | ||||
uvolt); | uvolt); | ||||
return (err); | return (err); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
#endif | |||||
static int | static int | ||||
aw_mmc_update_ios(device_t bus, device_t child) | aw_mmc_update_ios(device_t bus, device_t child) | ||||
{ | { | ||||
int error; | int error; | ||||
struct aw_mmc_softc *sc; | struct aw_mmc_softc *sc; | ||||
struct mmc_ios *ios; | struct mmc_ios *ios; | ||||
unsigned int clock; | unsigned int clock; | ||||
▲ Show 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | if (ios->clock && ios->clock != sc->aw_clock) { | ||||
error = aw_mmc_update_clock(sc, 1); | error = aw_mmc_update_clock(sc, 1); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
#ifndef MMCCAM | |||||
static int | static int | ||||
aw_mmc_get_ro(device_t bus, device_t child) | aw_mmc_get_ro(device_t bus, device_t child) | ||||
{ | { | ||||
struct aw_mmc_softc *sc; | struct aw_mmc_softc *sc; | ||||
sc = device_get_softc(bus); | sc = device_get_softc(bus); | ||||
return (mmc_fdt_gpio_get_readonly(&sc->mmc_helper)); | return (mmc_fdt_gpio_get_readonly(&sc->mmc_helper)); | ||||
Show All 28 Lines | aw_mmc_release_host(device_t bus, device_t child) | ||||
sc = device_get_softc(bus); | sc = device_get_softc(bus); | ||||
AW_MMC_LOCK(sc); | AW_MMC_LOCK(sc); | ||||
sc->aw_bus_busy--; | sc->aw_bus_busy--; | ||||
wakeup(sc); | wakeup(sc); | ||||
AW_MMC_UNLOCK(sc); | AW_MMC_UNLOCK(sc); | ||||
return (0); | return (0); | ||||
} | } | ||||
#endif | |||||
static device_method_t aw_mmc_methods[] = { | static device_method_t aw_mmc_methods[] = { | ||||
/* Device interface */ | /* Device interface */ | ||||
DEVMETHOD(device_probe, aw_mmc_probe), | DEVMETHOD(device_probe, aw_mmc_probe), | ||||
DEVMETHOD(device_attach, aw_mmc_attach), | DEVMETHOD(device_attach, aw_mmc_attach), | ||||
DEVMETHOD(device_detach, aw_mmc_detach), | DEVMETHOD(device_detach, aw_mmc_detach), | ||||
/* Bus interface */ | /* Bus interface */ | ||||
DEVMETHOD(bus_read_ivar, aw_mmc_read_ivar), | DEVMETHOD(bus_read_ivar, aw_mmc_read_ivar), | ||||
DEVMETHOD(bus_write_ivar, aw_mmc_write_ivar), | DEVMETHOD(bus_write_ivar, aw_mmc_write_ivar), | ||||
DEVMETHOD(bus_add_child, bus_generic_add_child), | DEVMETHOD(bus_add_child, bus_generic_add_child), | ||||
#ifndef MMCCAM | |||||
/* MMC bridge interface */ | /* MMC bridge interface */ | ||||
DEVMETHOD(mmcbr_update_ios, aw_mmc_update_ios), | DEVMETHOD(mmcbr_update_ios, aw_mmc_update_ios), | ||||
DEVMETHOD(mmcbr_request, aw_mmc_request), | DEVMETHOD(mmcbr_request, aw_mmc_request), | ||||
DEVMETHOD(mmcbr_get_ro, aw_mmc_get_ro), | DEVMETHOD(mmcbr_get_ro, aw_mmc_get_ro), | ||||
DEVMETHOD(mmcbr_switch_vccq, aw_mmc_switch_vccq), | DEVMETHOD(mmcbr_switch_vccq, aw_mmc_switch_vccq), | ||||
DEVMETHOD(mmcbr_acquire_host, aw_mmc_acquire_host), | DEVMETHOD(mmcbr_acquire_host, aw_mmc_acquire_host), | ||||
DEVMETHOD(mmcbr_release_host, aw_mmc_release_host), | DEVMETHOD(mmcbr_release_host, aw_mmc_release_host), | ||||
#endif | |||||
#ifdef MMCCAM | |||||
/* MMCCAM interface */ | |||||
DEVMETHOD(mmc_sim_get_tran_settings, aw_mmc_get_tran_settings), | |||||
DEVMETHOD(mmc_sim_set_tran_settings, aw_mmc_set_tran_settings), | |||||
DEVMETHOD(mmc_sim_cam_request, aw_mmc_cam_request), | |||||
#endif | |||||
DEVMETHOD_END | DEVMETHOD_END | ||||
}; | }; | ||||
static devclass_t aw_mmc_devclass; | static devclass_t aw_mmc_devclass; | ||||
static driver_t aw_mmc_driver = { | static driver_t aw_mmc_driver = { | ||||
"aw_mmc", | "aw_mmc", | ||||
Show All 10 Lines |
You can safely omit this, I think.