^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * tifm_sd.c - TI FlashMedia driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2006 Alex Dubov <oakad@yahoo.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Special thanks to Brad Campbell for extensive testing of this driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/tifm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mmc/host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/scatterlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define DRIVER_NAME "tifm_sd"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define DRIVER_VERSION "0.8"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static bool no_dma = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static bool fixed_timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) module_param(no_dma, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) module_param(fixed_timeout, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* Constants here are mostly from OMAP5912 datasheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define TIFM_MMCSD_RESET 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define TIFM_MMCSD_CLKMASK 0x03ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define TIFM_MMCSD_POWER 0x0800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define TIFM_MMCSD_4BBUS 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define TIFM_MMCSD_RXDE 0x8000 /* rx dma enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define TIFM_MMCSD_TXDE 0x0080 /* tx dma enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define TIFM_MMCSD_BUFINT 0x0c00 /* set bits: AE, AF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define TIFM_MMCSD_DPE 0x0020 /* data timeout counted in kilocycles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define TIFM_MMCSD_INAB 0x0080 /* abort / initialize command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define TIFM_MMCSD_READ 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define TIFM_MMCSD_ERRMASK 0x01e0 /* set bits: CCRC, CTO, DCRC, DTO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define TIFM_MMCSD_EOC 0x0001 /* end of command phase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define TIFM_MMCSD_CD 0x0002 /* card detect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define TIFM_MMCSD_CB 0x0004 /* card enter busy state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define TIFM_MMCSD_BRS 0x0008 /* block received/sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define TIFM_MMCSD_EOFB 0x0010 /* card exit busy state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define TIFM_MMCSD_DTO 0x0020 /* data time-out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define TIFM_MMCSD_DCRC 0x0040 /* data crc error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define TIFM_MMCSD_CTO 0x0080 /* command time-out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define TIFM_MMCSD_CCRC 0x0100 /* command crc error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define TIFM_MMCSD_AF 0x0400 /* fifo almost full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define TIFM_MMCSD_AE 0x0800 /* fifo almost empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define TIFM_MMCSD_OCRB 0x1000 /* OCR busy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define TIFM_MMCSD_CIRQ 0x2000 /* card irq (cmd40/sdio) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define TIFM_MMCSD_CERR 0x4000 /* card status error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define TIFM_MMCSD_ODTO 0x0040 /* open drain / extended timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define TIFM_MMCSD_CARD_RO 0x0200 /* card is read-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define TIFM_MMCSD_FIFO_SIZE 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define TIFM_MMCSD_RSP_R0 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define TIFM_MMCSD_RSP_R1 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define TIFM_MMCSD_RSP_R2 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define TIFM_MMCSD_RSP_R3 0x0300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define TIFM_MMCSD_RSP_R4 0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define TIFM_MMCSD_RSP_R5 0x0500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define TIFM_MMCSD_RSP_R6 0x0600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define TIFM_MMCSD_RSP_BUSY 0x0800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define TIFM_MMCSD_CMD_BC 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define TIFM_MMCSD_CMD_BCR 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define TIFM_MMCSD_CMD_AC 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define TIFM_MMCSD_CMD_ADTC 0x3000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define TIFM_MMCSD_MAX_BLOCK_SIZE 0x0800UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define TIFM_MMCSD_REQ_TIMEOUT_MS 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) CMD_READY = 0x0001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) FIFO_READY = 0x0002,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) BRS_READY = 0x0004,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) SCMD_ACTIVE = 0x0008,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) SCMD_READY = 0x0010,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) CARD_BUSY = 0x0020,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) DATA_CARRY = 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct tifm_sd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct tifm_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) unsigned short eject:1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) open_drain:1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) no_dma:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) unsigned short cmd_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned int clk_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) unsigned int clk_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned long timeout_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct tasklet_struct finish_tasklet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct timer_list timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct mmc_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int sg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int sg_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned int block_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct scatterlist bounce_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) unsigned char bounce_buf_data[TIFM_MMCSD_MAX_BLOCK_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* for some reason, host won't respond correctly to readw/writew */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static void tifm_sd_read_fifo(struct tifm_sd *host, struct page *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) unsigned int off, unsigned int cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) unsigned int pos = 0, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) buf = kmap_atomic(pg) + off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (host->cmd_flags & DATA_CARRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) buf[pos++] = host->bounce_buf_data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) host->cmd_flags &= ~DATA_CARRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) while (pos < cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) val = readl(sock->addr + SOCK_MMCSD_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) buf[pos++] = val & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (pos == cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) host->bounce_buf_data[0] = (val >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) host->cmd_flags |= DATA_CARRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) buf[pos++] = (val >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) kunmap_atomic(buf - off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) unsigned int off, unsigned int cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) unsigned int pos = 0, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) buf = kmap_atomic(pg) + off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (host->cmd_flags & DATA_CARRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) val = host->bounce_buf_data[0] | ((buf[pos++] << 8) & 0xff00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) writel(val, sock->addr + SOCK_MMCSD_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) host->cmd_flags &= ~DATA_CARRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) while (pos < cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) val = buf[pos++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (pos == cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) host->bounce_buf_data[0] = val & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) host->cmd_flags |= DATA_CARRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) val |= (buf[pos++] << 8) & 0xff00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) writel(val, sock->addr + SOCK_MMCSD_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) kunmap_atomic(buf - off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static void tifm_sd_transfer_data(struct tifm_sd *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct mmc_data *r_data = host->req->cmd->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct scatterlist *sg = r_data->sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) unsigned int off, cnt, t_size = TIFM_MMCSD_FIFO_SIZE * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) unsigned int p_off, p_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct page *pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (host->sg_pos == host->sg_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) while (t_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) cnt = sg[host->sg_pos].length - host->block_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (!cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) host->block_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) host->sg_pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (host->sg_pos == host->sg_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if ((r_data->flags & MMC_DATA_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) && (host->cmd_flags & DATA_CARRY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) writel(host->bounce_buf_data[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) host->dev->addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) + SOCK_MMCSD_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) cnt = sg[host->sg_pos].length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) off = sg[host->sg_pos].offset + host->block_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) p_off = offset_in_page(off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) p_cnt = PAGE_SIZE - p_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) p_cnt = min(p_cnt, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) p_cnt = min(p_cnt, t_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (r_data->flags & MMC_DATA_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) tifm_sd_read_fifo(host, pg, p_off, p_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) else if (r_data->flags & MMC_DATA_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) tifm_sd_write_fifo(host, pg, p_off, p_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) t_size -= p_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) host->block_pos += p_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static void tifm_sd_copy_page(struct page *dst, unsigned int dst_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct page *src, unsigned int src_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) unsigned char *src_buf = kmap_atomic(src) + src_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) unsigned char *dst_buf = kmap_atomic(dst) + dst_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) memcpy(dst_buf, src_buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) kunmap_atomic(dst_buf - dst_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) kunmap_atomic(src_buf - src_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct scatterlist *sg = r_data->sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) unsigned int t_size = r_data->blksz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) unsigned int off, cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) unsigned int p_off, p_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct page *pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) dev_dbg(&host->dev->dev, "bouncing block\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) while (t_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) cnt = sg[host->sg_pos].length - host->block_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (!cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) host->block_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) host->sg_pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (host->sg_pos == host->sg_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) cnt = sg[host->sg_pos].length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) off = sg[host->sg_pos].offset + host->block_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) p_off = offset_in_page(off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) p_cnt = PAGE_SIZE - p_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) p_cnt = min(p_cnt, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) p_cnt = min(p_cnt, t_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (r_data->flags & MMC_DATA_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) tifm_sd_copy_page(sg_page(&host->bounce_buf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) r_data->blksz - t_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) pg, p_off, p_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) else if (r_data->flags & MMC_DATA_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) tifm_sd_copy_page(pg, p_off, sg_page(&host->bounce_buf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) r_data->blksz - t_size, p_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) t_size -= p_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) host->block_pos += p_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static int tifm_sd_set_dma_data(struct tifm_sd *host, struct mmc_data *r_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) unsigned int t_size = TIFM_DMA_TSIZE * r_data->blksz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) unsigned int dma_len, dma_blk_cnt, dma_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct scatterlist *sg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (host->sg_pos == host->sg_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (host->cmd_flags & DATA_CARRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) host->cmd_flags &= ~DATA_CARRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) tifm_sd_bounce_block(host, r_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (host->sg_pos == host->sg_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) dma_len = sg_dma_len(&r_data->sg[host->sg_pos]) - host->block_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (!dma_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) host->block_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) host->sg_pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (host->sg_pos == host->sg_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) dma_len = sg_dma_len(&r_data->sg[host->sg_pos]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (dma_len < t_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) dma_blk_cnt = dma_len / r_data->blksz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) dma_off = host->block_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) host->block_pos += dma_blk_cnt * r_data->blksz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) dma_blk_cnt = TIFM_DMA_TSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) dma_off = host->block_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) host->block_pos += t_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (dma_blk_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) sg = &r_data->sg[host->sg_pos];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) else if (dma_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (r_data->flags & MMC_DATA_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) tifm_sd_bounce_block(host, r_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) host->cmd_flags |= DATA_CARRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) sg = &host->bounce_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) dma_off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) dma_blk_cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) dev_dbg(&sock->dev, "setting dma for %d blocks\n", dma_blk_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) writel(sg_dma_address(sg) + dma_off, sock->addr + SOCK_DMA_ADDRESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (r_data->flags & MMC_DATA_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) writel((dma_blk_cnt << 8) | TIFM_DMA_TX | TIFM_DMA_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) sock->addr + SOCK_DMA_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) writel((dma_blk_cnt << 8) | TIFM_DMA_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) sock->addr + SOCK_DMA_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static unsigned int tifm_sd_op_flags(struct mmc_command *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) unsigned int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) switch (mmc_resp_type(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) case MMC_RSP_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) rc |= TIFM_MMCSD_RSP_R0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) case MMC_RSP_R1B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) rc |= TIFM_MMCSD_RSP_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) case MMC_RSP_R1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) rc |= TIFM_MMCSD_RSP_R1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) case MMC_RSP_R2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) rc |= TIFM_MMCSD_RSP_R2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) case MMC_RSP_R3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) rc |= TIFM_MMCSD_RSP_R3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) switch (mmc_cmd_type(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) case MMC_CMD_BC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) rc |= TIFM_MMCSD_CMD_BC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) case MMC_CMD_BCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) rc |= TIFM_MMCSD_CMD_BCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) case MMC_CMD_AC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) rc |= TIFM_MMCSD_CMD_AC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) case MMC_CMD_ADTC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) rc |= TIFM_MMCSD_CMD_ADTC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static void tifm_sd_exec(struct tifm_sd *host, struct mmc_command *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) unsigned int cmd_mask = tifm_sd_op_flags(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (host->open_drain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) cmd_mask |= TIFM_MMCSD_ODTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (cmd->data && (cmd->data->flags & MMC_DATA_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) cmd_mask |= TIFM_MMCSD_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) dev_dbg(&sock->dev, "executing opcode 0x%x, arg: 0x%x, mask: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) cmd->opcode, cmd->arg, cmd_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) writel((cmd->arg >> 16) & 0xffff, sock->addr + SOCK_MMCSD_ARG_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) writel(cmd->arg & 0xffff, sock->addr + SOCK_MMCSD_ARG_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) writel(cmd->opcode | cmd_mask, sock->addr + SOCK_MMCSD_COMMAND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static void tifm_sd_fetch_resp(struct mmc_command *cmd, struct tifm_dev *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) cmd->resp[0] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x1c) << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) cmd->resp[1] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x14) << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) cmd->resp[2] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x0c) << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) cmd->resp[3] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x04) << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static void tifm_sd_check_status(struct tifm_sd *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct mmc_command *cmd = host->req->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (cmd->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) goto finish_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (!(host->cmd_flags & CMD_READY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (cmd->data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (cmd->data->error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if ((host->cmd_flags & SCMD_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) && !(host->cmd_flags & SCMD_READY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) goto finish_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (!(host->cmd_flags & BRS_READY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (!(host->no_dma || (host->cmd_flags & FIFO_READY)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (cmd->data->flags & MMC_DATA_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (host->req->stop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (!(host->cmd_flags & SCMD_ACTIVE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) host->cmd_flags |= SCMD_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) writel(TIFM_MMCSD_EOFB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) | readl(sock->addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) + SOCK_MMCSD_INT_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) sock->addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) + SOCK_MMCSD_INT_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) tifm_sd_exec(host, host->req->stop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (!(host->cmd_flags & SCMD_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) || (host->cmd_flags & CARD_BUSY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) writel((~TIFM_MMCSD_EOFB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) & readl(sock->addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) + SOCK_MMCSD_INT_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) sock->addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) + SOCK_MMCSD_INT_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (host->cmd_flags & CARD_BUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) writel((~TIFM_MMCSD_EOFB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) & readl(sock->addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) + SOCK_MMCSD_INT_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) sock->addr + SOCK_MMCSD_INT_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (host->req->stop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (!(host->cmd_flags & SCMD_ACTIVE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) host->cmd_flags |= SCMD_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) tifm_sd_exec(host, host->req->stop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (!(host->cmd_flags & SCMD_READY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) finish_request:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) tasklet_schedule(&host->finish_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /* Called from interrupt handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) static void tifm_sd_data_event(struct tifm_dev *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct tifm_sd *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) unsigned int fifo_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct mmc_data *r_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) spin_lock(&sock->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) dev_dbg(&sock->dev, "data event: fifo_status %x, flags %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) fifo_status, host->cmd_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (host->req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) r_data = host->req->cmd->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (r_data && (fifo_status & TIFM_FIFO_READY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (tifm_sd_set_dma_data(host, r_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) host->cmd_flags |= FIFO_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) tifm_sd_check_status(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) writel(fifo_status, sock->addr + SOCK_DMA_FIFO_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) spin_unlock(&sock->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) /* Called from interrupt handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) static void tifm_sd_card_event(struct tifm_dev *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct tifm_sd *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) unsigned int host_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) int cmd_error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) struct mmc_command *cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) spin_lock(&sock->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) host_status = readl(sock->addr + SOCK_MMCSD_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) dev_dbg(&sock->dev, "host event: host_status %x, flags %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) host_status, host->cmd_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (host->req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) cmd = host->req->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (host_status & TIFM_MMCSD_ERRMASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) writel(host_status & TIFM_MMCSD_ERRMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) sock->addr + SOCK_MMCSD_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (host_status & TIFM_MMCSD_CTO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) cmd_error = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) else if (host_status & TIFM_MMCSD_CCRC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) cmd_error = -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (cmd->data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (host_status & TIFM_MMCSD_DTO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) cmd->data->error = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) else if (host_status & TIFM_MMCSD_DCRC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) cmd->data->error = -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) writel(TIFM_FIFO_INT_SETALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (host->req->stop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (host->cmd_flags & SCMD_ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) host->req->stop->error = cmd_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) host->cmd_flags |= SCMD_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) cmd->error = cmd_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) host->cmd_flags |= SCMD_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) tifm_sd_exec(host, host->req->stop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) cmd->error = cmd_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (host_status & (TIFM_MMCSD_EOC | TIFM_MMCSD_CERR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (!(host->cmd_flags & CMD_READY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) host->cmd_flags |= CMD_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) tifm_sd_fetch_resp(cmd, sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) } else if (host->cmd_flags & SCMD_ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) host->cmd_flags |= SCMD_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) tifm_sd_fetch_resp(host->req->stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (host_status & TIFM_MMCSD_BRS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) host->cmd_flags |= BRS_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (host->no_dma && cmd->data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (host_status & TIFM_MMCSD_AE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) writel(host_status & TIFM_MMCSD_AE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) sock->addr + SOCK_MMCSD_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (host_status & (TIFM_MMCSD_AE | TIFM_MMCSD_AF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) | TIFM_MMCSD_BRS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) tifm_sd_transfer_data(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) host_status &= ~TIFM_MMCSD_AE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (host_status & TIFM_MMCSD_EOFB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) host->cmd_flags &= ~CARD_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) else if (host_status & TIFM_MMCSD_CB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) host->cmd_flags |= CARD_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) tifm_sd_check_status(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) writel(host_status, sock->addr + SOCK_MMCSD_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) spin_unlock(&sock->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static void tifm_sd_set_data_timeout(struct tifm_sd *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) struct mmc_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) unsigned int data_timeout = data->timeout_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (fixed_timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) data_timeout += data->timeout_ns /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) ((1000000000UL / host->clk_freq) * host->clk_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (data_timeout < 0xffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) writel((~TIFM_MMCSD_DPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) & readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) data_timeout = (data_timeout >> 10) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (data_timeout > 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) data_timeout = 0; /* set to unlimited */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) writel(TIFM_MMCSD_DPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) | readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct tifm_sd *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) struct mmc_data *r_data = mrq->cmd->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) spin_lock_irqsave(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (host->eject) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) mrq->cmd->error = -ENOMEDIUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (host->req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) pr_err("%s : unfinished request detected\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) dev_name(&sock->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) mrq->cmd->error = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) host->cmd_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) host->block_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) host->sg_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (mrq->data && !is_power_of_2(mrq->data->blksz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) host->no_dma = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) host->no_dma = no_dma ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (r_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) tifm_sd_set_data_timeout(host, r_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if ((r_data->flags & MMC_DATA_WRITE) && !mrq->stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) writel(TIFM_MMCSD_EOFB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) | readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) sock->addr + SOCK_MMCSD_INT_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (host->no_dma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) writel(TIFM_MMCSD_BUFINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) | readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) sock->addr + SOCK_MMCSD_INT_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) | (TIFM_MMCSD_FIFO_SIZE - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) host->sg_len = r_data->sg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) sg_init_one(&host->bounce_buf, host->bounce_buf_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) r_data->blksz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if(1 != tifm_map_sg(sock, &host->bounce_buf, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) r_data->flags & MMC_DATA_WRITE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) ? PCI_DMA_TODEVICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) : PCI_DMA_FROMDEVICE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) pr_err("%s : scatterlist map failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) dev_name(&sock->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) mrq->cmd->error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) host->sg_len = tifm_map_sg(sock, r_data->sg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) r_data->sg_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) r_data->flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) & MMC_DATA_WRITE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) ? PCI_DMA_TODEVICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) : PCI_DMA_FROMDEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (host->sg_len < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) pr_err("%s : scatterlist map failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) dev_name(&sock->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) tifm_unmap_sg(sock, &host->bounce_buf, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) r_data->flags & MMC_DATA_WRITE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) ? PCI_DMA_TODEVICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) : PCI_DMA_FROMDEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) mrq->cmd->error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) writel(TIFM_FIFO_INT_SETALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) writel(ilog2(r_data->blksz) - 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) sock->addr + SOCK_FIFO_PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) writel(TIFM_FIFO_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) sock->addr + SOCK_FIFO_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) writel(TIFM_FIFO_INTMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (r_data->flags & MMC_DATA_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) writel(TIFM_MMCSD_TXDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) writel(TIFM_MMCSD_RXDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) tifm_sd_set_dma_data(host, r_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) writel(r_data->blocks - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) sock->addr + SOCK_MMCSD_NUM_BLOCKS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) writel(r_data->blksz - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) sock->addr + SOCK_MMCSD_BLOCK_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) host->req = mrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) mod_timer(&host->timer, jiffies + host->timeout_jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) sock->addr + SOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) tifm_sd_exec(host, mrq->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) spin_unlock_irqrestore(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) spin_unlock_irqrestore(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) mmc_request_done(mmc, mrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static void tifm_sd_end_cmd(unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) struct tifm_sd *host = (struct tifm_sd*)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct mmc_host *mmc = tifm_get_drvdata(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) struct mmc_request *mrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct mmc_data *r_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) spin_lock_irqsave(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) del_timer(&host->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) mrq = host->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) host->req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (!mrq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) pr_err(" %s : no request to complete?\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) dev_name(&sock->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) spin_unlock_irqrestore(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) r_data = mrq->cmd->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (r_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (host->no_dma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) writel((~TIFM_MMCSD_BUFINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) & readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) sock->addr + SOCK_MMCSD_INT_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) tifm_unmap_sg(sock, &host->bounce_buf, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) (r_data->flags & MMC_DATA_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) tifm_unmap_sg(sock, r_data->sg, r_data->sg_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) (r_data->flags & MMC_DATA_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) r_data->bytes_xfered = r_data->blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) - readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) r_data->bytes_xfered *= r_data->blksz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) r_data->bytes_xfered += r_data->blksz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) - readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) sock->addr + SOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) spin_unlock_irqrestore(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) mmc_request_done(mmc, mrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) static void tifm_sd_abort(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) struct tifm_sd *host = from_timer(host, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) pr_err("%s : card failed to respond for a long period of time "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) "(%x, %x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) dev_name(&host->dev->dev), host->req->cmd->opcode, host->cmd_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) tifm_eject(host->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) struct tifm_sd *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) unsigned int clk_div1, clk_div2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) spin_lock_irqsave(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) dev_dbg(&sock->dev, "ios: clock = %u, vdd = %x, bus_mode = %x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) "chip_select = %x, power_mode = %x, bus_width = %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) ios->clock, ios->vdd, ios->bus_mode, ios->chip_select,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) ios->power_mode, ios->bus_width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (ios->bus_width == MMC_BUS_WIDTH_4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) sock->addr + SOCK_MMCSD_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) writel((~TIFM_MMCSD_4BBUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) & readl(sock->addr + SOCK_MMCSD_CONFIG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) sock->addr + SOCK_MMCSD_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (ios->clock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) clk_div1 = 20000000 / ios->clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (!clk_div1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) clk_div1 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) clk_div2 = 24000000 / ios->clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (!clk_div2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) clk_div2 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if ((20000000 / clk_div1) > ios->clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) clk_div1++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if ((24000000 / clk_div2) > ios->clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) clk_div2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if ((20000000 / clk_div1) > (24000000 / clk_div2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) host->clk_freq = 20000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) host->clk_div = clk_div1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) writel((~TIFM_CTRL_FAST_CLK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) & readl(sock->addr + SOCK_CONTROL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) sock->addr + SOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) host->clk_freq = 24000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) host->clk_div = clk_div2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) writel(TIFM_CTRL_FAST_CLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) | readl(sock->addr + SOCK_CONTROL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) sock->addr + SOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) host->clk_div = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) host->clk_div &= TIFM_MMCSD_CLKMASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) writel(host->clk_div
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) | ((~TIFM_MMCSD_CLKMASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) & readl(sock->addr + SOCK_MMCSD_CONFIG)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) sock->addr + SOCK_MMCSD_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) host->open_drain = (ios->bus_mode == MMC_BUSMODE_OPENDRAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) /* chip_select : maybe later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) //vdd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) //power is set before probe / after remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) spin_unlock_irqrestore(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) static int tifm_sd_ro(struct mmc_host *mmc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) struct tifm_sd *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) spin_lock_irqsave(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (TIFM_MMCSD_CARD_RO & readl(sock->addr + SOCK_PRESENT_STATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) spin_unlock_irqrestore(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) static const struct mmc_host_ops tifm_sd_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) .request = tifm_sd_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) .set_ios = tifm_sd_ios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) .get_ro = tifm_sd_ro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) static int tifm_sd_initialize_host(struct tifm_sd *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) unsigned int host_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) host->clk_div = 61;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) host->clk_freq = 20000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) writel(TIFM_MMCSD_RESET, sock->addr + SOCK_MMCSD_SYSTEM_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) writel(host->clk_div | TIFM_MMCSD_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) sock->addr + SOCK_MMCSD_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) /* wait up to 0.51 sec for reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) for (rc = 32; rc <= 256; rc <<= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (1 & readl(sock->addr + SOCK_MMCSD_SYSTEM_STATUS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) msleep(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) pr_err("%s : controller failed to reset\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) dev_name(&sock->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) writel(0, sock->addr + SOCK_MMCSD_NUM_BLOCKS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) writel(host->clk_div | TIFM_MMCSD_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) sock->addr + SOCK_MMCSD_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) // command timeout fixed to 64 clocks for now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) writel(64, sock->addr + SOCK_MMCSD_COMMAND_TO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) writel(TIFM_MMCSD_INAB, sock->addr + SOCK_MMCSD_COMMAND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) for (rc = 16; rc <= 64; rc <<= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) host_status = readl(sock->addr + SOCK_MMCSD_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) writel(host_status, sock->addr + SOCK_MMCSD_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (!(host_status & TIFM_MMCSD_ERRMASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) && (host_status & TIFM_MMCSD_EOC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) msleep(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) pr_err("%s : card not ready - probe failed on initialization\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) dev_name(&sock->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) writel(TIFM_MMCSD_CERR | TIFM_MMCSD_BRS | TIFM_MMCSD_EOC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) | TIFM_MMCSD_ERRMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) sock->addr + SOCK_MMCSD_INT_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) static int tifm_sd_probe(struct tifm_dev *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) struct mmc_host *mmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) struct tifm_sd *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) int rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (!(TIFM_SOCK_STATE_OCCUPIED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) & readl(sock->addr + SOCK_PRESENT_STATE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) pr_warn("%s : card gone, unexpectedly\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) dev_name(&sock->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) mmc = mmc_alloc_host(sizeof(struct tifm_sd), &sock->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (!mmc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) tifm_set_drvdata(sock, mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) host->dev = sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) host->timeout_jiffies = msecs_to_jiffies(TIFM_MMCSD_REQ_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) * We use a fixed request timeout of 1s, hence inform the core about it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) * A future improvement should instead respect the cmd->busy_timeout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) mmc->max_busy_timeout = TIFM_MMCSD_REQ_TIMEOUT_MS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) tasklet_init(&host->finish_tasklet, tifm_sd_end_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) (unsigned long)host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) timer_setup(&host->timer, tifm_sd_abort, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) mmc->ops = &tifm_sd_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) mmc->caps = MMC_CAP_4_BIT_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) mmc->f_min = 20000000 / 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) mmc->f_max = 24000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) mmc->max_blk_count = 2048;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) mmc->max_segs = mmc->max_blk_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) mmc->max_blk_size = min(TIFM_MMCSD_MAX_BLOCK_SIZE, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) mmc->max_seg_size = mmc->max_blk_count * mmc->max_blk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) mmc->max_req_size = mmc->max_seg_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) sock->card_event = tifm_sd_card_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) sock->data_event = tifm_sd_data_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) rc = tifm_sd_initialize_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) rc = mmc_add_host(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) mmc_free_host(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static void tifm_sd_remove(struct tifm_dev *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) struct mmc_host *mmc = tifm_get_drvdata(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) struct tifm_sd *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) spin_lock_irqsave(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) host->eject = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) spin_unlock_irqrestore(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) tasklet_kill(&host->finish_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) spin_lock_irqsave(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (host->req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) writel(TIFM_FIFO_INT_SETALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) host->req->cmd->error = -ENOMEDIUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (host->req->stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) host->req->stop->error = -ENOMEDIUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) tasklet_schedule(&host->finish_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) spin_unlock_irqrestore(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) mmc_remove_host(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) dev_dbg(&sock->dev, "after remove\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) mmc_free_host(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) static int tifm_sd_suspend(struct tifm_dev *sock, pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) static int tifm_sd_resume(struct tifm_dev *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) struct mmc_host *mmc = tifm_get_drvdata(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) struct tifm_sd *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) rc = tifm_sd_initialize_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) dev_dbg(&sock->dev, "resume initialize %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) host->eject = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) #define tifm_sd_suspend NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) #define tifm_sd_resume NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) static struct tifm_device_id tifm_sd_id_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) { TIFM_TYPE_SD }, { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) static struct tifm_driver tifm_sd_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) .name = DRIVER_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) .owner = THIS_MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) .id_table = tifm_sd_id_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) .probe = tifm_sd_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) .remove = tifm_sd_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) .suspend = tifm_sd_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) .resume = tifm_sd_resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) static int __init tifm_sd_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) return tifm_register_driver(&tifm_sd_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) static void __exit tifm_sd_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) tifm_unregister_driver(&tifm_sd_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) MODULE_AUTHOR("Alex Dubov");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) MODULE_DESCRIPTION("TI FlashMedia SD driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) MODULE_DEVICE_TABLE(tifm, tifm_sd_id_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) MODULE_VERSION(DRIVER_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) module_init(tifm_sd_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) module_exit(tifm_sd_exit);