tmio_mmc.h 5.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * linux/drivers/mmc/host/tmio_mmc.h
 *
 * Copyright (C) 2007 Ian Molton
 * Copyright (C) 2004 Ian Molton
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Driver for the MMC / SD / SDIO cell found in:
 *
 * TC6393XB TC6391XB TC6387XB T7L66XB ASIC3
 */

#ifndef TMIO_MMC_H
#define TMIO_MMC_H

#include <linux/highmem.h>
20
#include <linux/mmc/tmio.h>
21
#include <linux/mutex.h>
22
#include <linux/pagemap.h>
23
#include <linux/scatterlist.h>
24
#include <linux/spinlock.h>
25 26

/* Definitions for values the CTRL_SDIO_STATUS register can take. */
27
#define TMIO_SDIO_STAT_IOIRQ	0x0001
28
#define TMIO_SDIO_STAT_EXPUB52	0x4000
29 30
#define TMIO_SDIO_STAT_EXWT	0x8000
#define TMIO_SDIO_MASK_ALL	0xc007
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

/* Define some IRQ masks */
/* This is the mask used at reset by the chip */
#define TMIO_MASK_ALL           0x837f031d
#define TMIO_MASK_READOP  (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND)
#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND)
#define TMIO_MASK_CMD     (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \
		TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
#define TMIO_MASK_IRQ     (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD)

struct tmio_mmc_data;

struct tmio_mmc_host {
	void __iomem *ctl;
	struct mmc_command      *cmd;
	struct mmc_request      *mrq;
	struct mmc_data         *data;
	struct mmc_host         *mmc;

	/* Callbacks for clock / power control */
	void (*set_pwr)(struct platform_device *host, int state);
	void (*set_clk_div)(struct platform_device *host, int state);

	/* pio related stuff */
	struct scatterlist      *sg_ptr;
	struct scatterlist      *sg_orig;
	unsigned int            sg_len;
	unsigned int            sg_off;

	struct platform_device *pdev;
	struct tmio_mmc_data *pdata;

	/* DMA support */
	bool			force_pio;
	struct dma_chan		*chan_rx;
	struct dma_chan		*chan_tx;
	struct tasklet_struct	dma_complete;
	struct tasklet_struct	dma_issue;
	struct scatterlist	bounce_sg;
	u8			*bounce_buf;

	/* Track lost interrupts */
	struct delayed_work	delayed_reset_work;
74 75
	struct work_struct	done;

76
	/* Cache */
S
Simon Horman 已提交
77 78
	u32			sdcard_irq_mask;
	u32			sdio_irq_mask;
79
	unsigned int		clk_cache;
S
Simon Horman 已提交
80

81
	spinlock_t		lock;		/* protect host private data */
82
	unsigned long		last_req_ts;
83
	struct mutex		ios_lock;	/* protect set_ios() context */
84
	bool			native_hotplug;
85
	bool			sdio_irq_enabled;
86 87
};

88 89 90
struct tmio_mmc_host *tmio_mmc_host_alloc(struct platform_device *pdev);
void tmio_mmc_host_free(struct tmio_mmc_host *host);
int tmio_mmc_host_probe(struct tmio_mmc_host *host,
91 92 93 94 95 96
			struct tmio_mmc_data *pdata);
void tmio_mmc_host_remove(struct tmio_mmc_host *host);
void tmio_mmc_do_data_irq(struct tmio_mmc_host *host);

void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
97
irqreturn_t tmio_mmc_irq(int irq, void *devid);
98 99 100
irqreturn_t tmio_mmc_sdcard_irq(int irq, void *devid);
irqreturn_t tmio_mmc_card_detect_irq(int irq, void *devid);
irqreturn_t tmio_mmc_sdio_irq(int irq, void *devid);
101 102 103 104 105

static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg,
					 unsigned long *flags)
{
	local_irq_save(*flags);
106
	return kmap_atomic(sg_page(sg)) + sg->offset;
107 108 109 110 111
}

static inline void tmio_mmc_kunmap_atomic(struct scatterlist *sg,
					  unsigned long *flags, void *virt)
{
112
	kunmap_atomic(virt - sg->offset);
113 114 115
	local_irq_restore(*flags);
}

116
#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
117
void tmio_mmc_start_dma(struct tmio_mmc_host *host, struct mmc_data *data);
118
void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable);
119 120
void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata);
void tmio_mmc_release_dma(struct tmio_mmc_host *host);
121
void tmio_mmc_abort_dma(struct tmio_mmc_host *host);
122 123 124 125 126 127
#else
static inline void tmio_mmc_start_dma(struct tmio_mmc_host *host,
			       struct mmc_data *data)
{
}

128 129 130 131
static inline void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
{
}

132 133 134 135 136 137 138 139 140 141
static inline void tmio_mmc_request_dma(struct tmio_mmc_host *host,
				 struct tmio_mmc_data *pdata)
{
	host->chan_tx = NULL;
	host->chan_rx = NULL;
}

static inline void tmio_mmc_release_dma(struct tmio_mmc_host *host)
{
}
142 143 144 145

static inline void tmio_mmc_abort_dma(struct tmio_mmc_host *host)
{
}
146 147
#endif

148
#ifdef CONFIG_PM
149 150
int tmio_mmc_host_runtime_suspend(struct device *dev);
int tmio_mmc_host_runtime_resume(struct device *dev);
151
#endif
152

153 154
static inline u16 sd_ctrl_read16(struct tmio_mmc_host *host, int addr)
{
155
	return readw(host->ctl + (addr << host->pdata->bus_shift));
156 157 158 159 160
}

static inline void sd_ctrl_read16_rep(struct tmio_mmc_host *host, int addr,
		u16 *buf, int count)
{
161
	readsw(host->ctl + (addr << host->pdata->bus_shift), buf, count);
162 163 164 165
}

static inline u32 sd_ctrl_read32(struct tmio_mmc_host *host, int addr)
{
166 167
	return readw(host->ctl + (addr << host->pdata->bus_shift)) |
	       readw(host->ctl + ((addr + 2) << host->pdata->bus_shift)) << 16;
168 169 170 171
}

static inline void sd_ctrl_write16(struct tmio_mmc_host *host, int addr, u16 val)
{
S
Simon Horman 已提交
172 173 174 175 176
	/* If there is a hook and it returns non-zero then there
	 * is an error and the write should be skipped
	 */
	if (host->pdata->write16_hook && host->pdata->write16_hook(host, addr))
		return;
177
	writew(val, host->ctl + (addr << host->pdata->bus_shift));
178 179 180 181 182
}

static inline void sd_ctrl_write16_rep(struct tmio_mmc_host *host, int addr,
		u16 *buf, int count)
{
183
	writesw(host->ctl + (addr << host->pdata->bus_shift), buf, count);
184 185 186 187
}

static inline void sd_ctrl_write32(struct tmio_mmc_host *host, int addr, u32 val)
{
188 189
	writew(val, host->ctl + (addr << host->pdata->bus_shift));
	writew(val >> 16, host->ctl + ((addr + 2) << host->pdata->bus_shift));
190 191 192
}


193
#endif