Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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)  *  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) 2007 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 Carlos Corbacho for providing various MemoryStick cards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * that made this driver possible.
^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/memstick.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/log2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define DRIVER_NAME "tifm_ms"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) static bool no_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) module_param(no_dma, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * Some control bits of TIFM appear to conform to Sony's reference design,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * so I'm just assuming they all are.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define TIFM_MS_STAT_DRQ     0x04000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define TIFM_MS_STAT_MSINT   0x02000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define TIFM_MS_STAT_RDY     0x01000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define TIFM_MS_STAT_CRC     0x00200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define TIFM_MS_STAT_TOE     0x00100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define TIFM_MS_STAT_EMP     0x00020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define TIFM_MS_STAT_FUL     0x00010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define TIFM_MS_STAT_CED     0x00008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define TIFM_MS_STAT_ERR     0x00004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define TIFM_MS_STAT_BRQ     0x00002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define TIFM_MS_STAT_CNK     0x00001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define TIFM_MS_SYS_DMA      0x10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define TIFM_MS_SYS_RESET    0x08000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define TIFM_MS_SYS_SRAC     0x04000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define TIFM_MS_SYS_INTEN    0x02000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define TIFM_MS_SYS_NOCRC    0x01000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define TIFM_MS_SYS_INTCLR   0x00800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define TIFM_MS_SYS_MSIEN    0x00400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define TIFM_MS_SYS_FCLR     0x00200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define TIFM_MS_SYS_FDIR     0x00100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define TIFM_MS_SYS_DAM      0x00080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define TIFM_MS_SYS_DRM      0x00040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define TIFM_MS_SYS_DRQSL    0x00020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define TIFM_MS_SYS_REI      0x00010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define TIFM_MS_SYS_REO      0x00008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define TIFM_MS_SYS_BSY_MASK 0x00007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define TIFM_MS_SYS_FIFO     (TIFM_MS_SYS_INTEN | TIFM_MS_SYS_MSIEN \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 			      | TIFM_MS_SYS_FCLR | TIFM_MS_SYS_BSY_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) /* Hardware flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	CMD_READY  = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	FIFO_READY = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	CARD_INT   = 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) struct tifm_ms {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	struct tifm_dev         *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	struct timer_list       timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	struct memstick_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct tasklet_struct   notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	unsigned int            mode_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	unsigned int            block_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	unsigned long           timeout_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	unsigned char           eject:1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 				use_dma:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	unsigned char           cmd_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	unsigned char           io_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	unsigned int            io_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) static unsigned int tifm_ms_read_data(struct tifm_ms *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 				      unsigned char *buf, unsigned int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	unsigned int off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	while (host->io_pos && length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		buf[off++] = host->io_word & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		host->io_word >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		length--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		host->io_pos--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	if (!length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		return off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	while (!(TIFM_MS_STAT_EMP & readl(sock->addr + SOCK_MS_STATUS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		if (length < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		*(unsigned int *)(buf + off) = __raw_readl(sock->addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 							   + SOCK_MS_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		length -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		off += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	if (length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	    && !(TIFM_MS_STAT_EMP & readl(sock->addr + SOCK_MS_STATUS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		host->io_word = readl(sock->addr + SOCK_MS_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		for (host->io_pos = 4; host->io_pos; --host->io_pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			buf[off++] = host->io_word & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			host->io_word >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			length--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 			if (!length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	return off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static unsigned int tifm_ms_write_data(struct tifm_ms *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 				       unsigned char *buf, unsigned int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	unsigned int off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	if (host->io_pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		while (host->io_pos < 4 && length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 			host->io_word |=  buf[off++] << (host->io_pos * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			host->io_pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 			length--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	if (host->io_pos == 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	    && !(TIFM_MS_STAT_FUL & readl(sock->addr + SOCK_MS_STATUS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		writel(TIFM_MS_SYS_FDIR | readl(sock->addr + SOCK_MS_SYSTEM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		       sock->addr + SOCK_MS_SYSTEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		writel(host->io_word, sock->addr + SOCK_MS_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		host->io_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		host->io_word = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	} else if (host->io_pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		return off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	if (!length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		return off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	while (!(TIFM_MS_STAT_FUL & readl(sock->addr + SOCK_MS_STATUS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		if (length < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		writel(TIFM_MS_SYS_FDIR | readl(sock->addr + SOCK_MS_SYSTEM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		       sock->addr + SOCK_MS_SYSTEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		__raw_writel(*(unsigned int *)(buf + off),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 			     sock->addr + SOCK_MS_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		length -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		off += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	switch (length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		host->io_word |= buf[off + 2] << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		host->io_pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		host->io_word |= buf[off + 1] << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		host->io_pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		host->io_word |= buf[off];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		host->io_pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	off += host->io_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	return off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static unsigned int tifm_ms_transfer_data(struct tifm_ms *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	unsigned int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	unsigned int off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	unsigned int t_size, p_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	struct page *pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	if (host->req->long_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		length = host->req->sg.length - host->block_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		off = host->req->sg.offset + host->block_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		length = host->req->data_len - host->block_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	dev_dbg(&sock->dev, "fifo data transfer, %d, %d\n", length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		host->block_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	while (length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		unsigned int p_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		if (host->req->long_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			pg = nth_page(sg_page(&host->req->sg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 				      off >> PAGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			p_off = offset_in_page(off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			p_cnt = PAGE_SIZE - p_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 			p_cnt = min(p_cnt, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 			local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 			buf = kmap_atomic(pg) + p_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			buf = host->req->data + host->block_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 			p_cnt = host->req->data_len - host->block_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		t_size = host->req->data_dir == WRITE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			 ? tifm_ms_write_data(host, buf, p_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 			 : tifm_ms_read_data(host, buf, p_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		if (host->req->long_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 			kunmap_atomic(buf - p_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 			local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		if (!t_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		host->block_pos += t_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		length -= t_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		off += t_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	dev_dbg(&sock->dev, "fifo data transfer, %d remaining\n", length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	if (!length && (host->req->data_dir == WRITE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		if (host->io_pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 			writel(TIFM_MS_SYS_FDIR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			       | readl(sock->addr + SOCK_MS_SYSTEM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			       sock->addr + SOCK_MS_SYSTEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			writel(host->io_word, sock->addr + SOCK_MS_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		writel(TIFM_MS_SYS_FDIR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		       | readl(sock->addr + SOCK_MS_SYSTEM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		       sock->addr + SOCK_MS_SYSTEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		writel(0, sock->addr + SOCK_MS_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		readl(sock->addr + SOCK_MS_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	return length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static int tifm_ms_issue_cmd(struct tifm_ms *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	unsigned int data_len, cmd, sys_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	host->cmd_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	host->block_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	host->io_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	host->io_word = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	host->cmd_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	host->use_dma = !no_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	if (host->req->long_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		data_len = host->req->sg.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		if (!is_power_of_2(data_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 			host->use_dma = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		data_len = host->req->data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		host->use_dma = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	writel(TIFM_FIFO_INT_SETALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	       sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	writel(TIFM_FIFO_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	       sock->addr + SOCK_FIFO_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	if (host->use_dma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		if (1 != tifm_map_sg(sock, &host->req->sg, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 				     host->req->data_dir == READ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 				     ? PCI_DMA_FROMDEVICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 				     : PCI_DMA_TODEVICE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			host->req->error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 			return host->req->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		data_len = sg_dma_len(&host->req->sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		writel(ilog2(data_len) - 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		       sock->addr + SOCK_FIFO_PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		writel(TIFM_FIFO_INTMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		       sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		sys_param = TIFM_DMA_EN | (1 << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		if (host->req->data_dir == WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 			sys_param |= TIFM_DMA_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		writel(TIFM_FIFO_INTMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		       sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		writel(sg_dma_address(&host->req->sg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		       sock->addr + SOCK_DMA_ADDRESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		writel(sys_param, sock->addr + SOCK_DMA_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		writel(host->mode_mask | TIFM_MS_SYS_FIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		       sock->addr + SOCK_MS_SYSTEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		writel(TIFM_FIFO_MORE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		       sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	mod_timer(&host->timer, jiffies + host->timeout_jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	       sock->addr + SOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	host->req->error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	sys_param = readl(sock->addr + SOCK_MS_SYSTEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	sys_param |= TIFM_MS_SYS_INTCLR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	if (host->use_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		sys_param |= TIFM_MS_SYS_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		sys_param &= ~TIFM_MS_SYS_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	writel(sys_param, sock->addr + SOCK_MS_SYSTEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	cmd = (host->req->tpc & 0xf) << 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	cmd |= data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	writel(cmd, sock->addr + SOCK_MS_COMMAND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	dev_dbg(&sock->dev, "executing TPC %x, %x\n", cmd, sys_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static void tifm_ms_complete_cmd(struct tifm_ms *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	struct memstick_host *msh = tifm_get_drvdata(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	del_timer(&host->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	host->req->int_reg = readl(sock->addr + SOCK_MS_STATUS) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	host->req->int_reg = (host->req->int_reg & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			     | ((host->req->int_reg << 4) & 0xe0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	writel(TIFM_FIFO_INT_SETALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	       sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	if (host->use_dma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		tifm_unmap_sg(sock, &host->req->sg, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 			      host->req->data_dir == READ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 			      ? PCI_DMA_FROMDEVICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 			      : PCI_DMA_TODEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	       sock->addr + SOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	dev_dbg(&sock->dev, "TPC complete\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		rc = memstick_next_req(msh, &host->req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	} while (!rc && tifm_ms_issue_cmd(host));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static int tifm_ms_check_status(struct tifm_ms *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	if (!host->req->error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		if (!(host->cmd_flags & CMD_READY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		if (!(host->cmd_flags & FIFO_READY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		if (host->req->need_card_int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		    && !(host->cmd_flags & CARD_INT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* Called from interrupt handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static void tifm_ms_data_event(struct tifm_dev *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	struct tifm_ms *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	unsigned int fifo_status = 0, host_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	int rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	spin_lock(&sock->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	host = memstick_priv((struct memstick_host *)tifm_get_drvdata(sock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	host_status = readl(sock->addr + SOCK_MS_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	dev_dbg(&sock->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		"data event: fifo_status %x, host_status %x, flags %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		fifo_status, host_status, host->cmd_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	if (host->req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		if (host->use_dma && (fifo_status & 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 			host->cmd_flags |= FIFO_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 			rc = tifm_ms_check_status(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		if (!host->use_dma && (fifo_status & TIFM_FIFO_MORE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 			if (!tifm_ms_transfer_data(host)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 				host->cmd_flags |= FIFO_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 				rc = tifm_ms_check_status(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	writel(fifo_status, sock->addr + SOCK_DMA_FIFO_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		tifm_ms_complete_cmd(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	spin_unlock(&sock->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* Called from interrupt handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static void tifm_ms_card_event(struct tifm_dev *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	struct tifm_ms *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	unsigned int host_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	int rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	spin_lock(&sock->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	host = memstick_priv((struct memstick_host *)tifm_get_drvdata(sock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	host_status = readl(sock->addr + SOCK_MS_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	dev_dbg(&sock->dev, "host event: host_status %x, flags %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		host_status, host->cmd_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	if (host->req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		if (host_status & TIFM_MS_STAT_TOE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 			host->req->error = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		else if (host_status & TIFM_MS_STAT_CRC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 			host->req->error = -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		if (host_status & TIFM_MS_STAT_RDY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			host->cmd_flags |= CMD_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		if (host_status & TIFM_MS_STAT_MSINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 			host->cmd_flags |= CARD_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		rc = tifm_ms_check_status(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	writel(TIFM_MS_SYS_INTCLR | readl(sock->addr + SOCK_MS_SYSTEM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	       sock->addr + SOCK_MS_SYSTEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		tifm_ms_complete_cmd(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	spin_unlock(&sock->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static void tifm_ms_req_tasklet(unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	struct memstick_host *msh = (struct memstick_host *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	struct tifm_ms *host = memstick_priv(msh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	spin_lock_irqsave(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	if (!host->req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		if (host->eject) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 			do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 				rc = memstick_next_req(msh, &host->req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 				if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 					host->req->error = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 			} while (!rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 			spin_unlock_irqrestore(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 			rc = memstick_next_req(msh, &host->req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		} while (!rc && tifm_ms_issue_cmd(host));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	spin_unlock_irqrestore(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static void tifm_ms_dummy_submit(struct memstick_host *msh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static void tifm_ms_submit_req(struct memstick_host *msh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	struct tifm_ms *host = memstick_priv(msh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	tasklet_schedule(&host->notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static int tifm_ms_set_param(struct memstick_host *msh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 			     enum memstick_param param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 			     int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	struct tifm_ms *host = memstick_priv(msh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	struct tifm_dev *sock = host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	case MEMSTICK_POWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		/* also affected by media detection mechanism */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		if (value == MEMSTICK_POWER_ON) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 			host->mode_mask = TIFM_MS_SYS_SRAC | TIFM_MS_SYS_REI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 			writel(TIFM_MS_SYS_RESET, sock->addr + SOCK_MS_SYSTEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 			writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 			       sock->addr + SOCK_MS_SYSTEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 			writel(0xffffffff, sock->addr + SOCK_MS_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		} else if (value == MEMSTICK_POWER_OFF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 			writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 			       sock->addr + SOCK_MS_SYSTEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 			writel(0xffffffff, sock->addr + SOCK_MS_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	case MEMSTICK_INTERFACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		if (value == MEMSTICK_SERIAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 			host->mode_mask = TIFM_MS_SYS_SRAC | TIFM_MS_SYS_REI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 			writel((~TIFM_CTRL_FAST_CLK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 			       & readl(sock->addr + SOCK_CONTROL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 			       sock->addr + SOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		} else if (value == MEMSTICK_PAR4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 			host->mode_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 			writel(TIFM_CTRL_FAST_CLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 			       | readl(sock->addr + SOCK_CONTROL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 			       sock->addr + SOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static void tifm_ms_abort(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	struct tifm_ms *host = from_timer(host, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	dev_dbg(&host->dev->dev, "status %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		readl(host->dev->addr + SOCK_MS_STATUS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	       "%s : card failed to respond for a long period of time "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	       "(%x, %x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	       dev_name(&host->dev->dev), host->req ? host->req->tpc : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	       host->cmd_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	tifm_eject(host->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) static int tifm_ms_probe(struct tifm_dev *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	struct memstick_host *msh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	struct tifm_ms *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	int rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	if (!(TIFM_SOCK_STATE_OCCUPIED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	      & readl(sock->addr + SOCK_PRESENT_STATE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		printk(KERN_WARNING "%s : card gone, unexpectedly\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		       dev_name(&sock->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	msh = memstick_alloc_host(sizeof(struct tifm_ms), &sock->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	if (!msh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	host = memstick_priv(msh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	tifm_set_drvdata(sock, msh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	host->dev = sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	host->timeout_jiffies = msecs_to_jiffies(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	timer_setup(&host->timer, tifm_ms_abort, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	tasklet_init(&host->notify, tifm_ms_req_tasklet, (unsigned long)msh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	msh->request = tifm_ms_submit_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	msh->set_param = tifm_ms_set_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	sock->card_event = tifm_ms_card_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	sock->data_event = tifm_ms_data_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	if (tifm_has_ms_pif(sock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		msh->caps |= MEMSTICK_CAP_PAR4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	rc = memstick_add_host(msh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	memstick_free_host(msh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) static void tifm_ms_remove(struct tifm_dev *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	struct memstick_host *msh = tifm_get_drvdata(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	struct tifm_ms *host = memstick_priv(msh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	msh->request = tifm_ms_dummy_submit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	tasklet_kill(&host->notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	spin_lock_irqsave(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	host->eject = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	if (host->req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 		del_timer(&host->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		writel(TIFM_FIFO_INT_SETALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		       sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 		writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		if (host->use_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 			tifm_unmap_sg(sock, &host->req->sg, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 				      host->req->data_dir == READ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 				      ? PCI_DMA_TODEVICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 				      : PCI_DMA_FROMDEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		host->req->error = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 			rc = memstick_next_req(msh, &host->req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 			if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 				host->req->error = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		} while (!rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	spin_unlock_irqrestore(&sock->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	memstick_remove_host(msh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	memstick_free_host(msh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static int tifm_ms_suspend(struct tifm_dev *sock, pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	struct memstick_host *msh = tifm_get_drvdata(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	memstick_suspend_host(msh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) static int tifm_ms_resume(struct tifm_dev *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	struct memstick_host *msh = tifm_get_drvdata(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	memstick_resume_host(msh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) #define tifm_ms_suspend NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) #define tifm_ms_resume NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static struct tifm_device_id tifm_ms_id_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	{ TIFM_TYPE_MS }, { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static struct tifm_driver tifm_ms_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 		.name  = DRIVER_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		.owner = THIS_MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	.id_table = tifm_ms_id_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	.probe    = tifm_ms_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	.remove   = tifm_ms_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	.suspend  = tifm_ms_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	.resume   = tifm_ms_resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static int __init tifm_ms_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	return tifm_register_driver(&tifm_ms_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) static void __exit tifm_ms_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	tifm_unregister_driver(&tifm_ms_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) MODULE_AUTHOR("Alex Dubov");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) MODULE_DESCRIPTION("TI FlashMedia MemoryStick driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) MODULE_DEVICE_TABLE(tifm, tifm_ms_id_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) module_init(tifm_ms_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) module_exit(tifm_ms_exit);