cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

tifm_ms.c (16813B)


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