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

cb710-mmc.c (21974B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  cb710/mmc.c
      4 *
      5 *  Copyright by Michał Mirosław, 2008-2009
      6 */
      7#include <linux/kernel.h>
      8#include <linux/module.h>
      9#include <linux/pci.h>
     10#include <linux/delay.h>
     11#include "cb710-mmc.h"
     12
     13#define CB710_MMC_REQ_TIMEOUT_MS	2000
     14
     15static const u8 cb710_clock_divider_log2[8] = {
     16/*	1, 2, 4, 8, 16, 32, 128, 512 */
     17	0, 1, 2, 3,  4,  5,   7,   9
     18};
     19#define CB710_MAX_DIVIDER_IDX	\
     20	(ARRAY_SIZE(cb710_clock_divider_log2) - 1)
     21
     22static const u8 cb710_src_freq_mhz[16] = {
     23	33, 10, 20, 25, 30, 35, 40, 45,
     24	50, 55, 60, 65, 70, 75, 80, 85
     25};
     26
     27static void cb710_mmc_select_clock_divider(struct mmc_host *mmc, int hz)
     28{
     29	struct cb710_slot *slot = cb710_mmc_to_slot(mmc);
     30	struct pci_dev *pdev = cb710_slot_to_chip(slot)->pdev;
     31	u32 src_freq_idx;
     32	u32 divider_idx;
     33	int src_hz;
     34
     35	/* on CB710 in HP nx9500:
     36	 *   src_freq_idx == 0
     37	 *   indexes 1-7 work as written in the table
     38	 *   indexes 0,8-15 give no clock output
     39	 */
     40	pci_read_config_dword(pdev, 0x48, &src_freq_idx);
     41	src_freq_idx = (src_freq_idx >> 16) & 0xF;
     42	src_hz = cb710_src_freq_mhz[src_freq_idx] * 1000000;
     43
     44	for (divider_idx = 0; divider_idx < CB710_MAX_DIVIDER_IDX; ++divider_idx) {
     45		if (hz >= src_hz >> cb710_clock_divider_log2[divider_idx])
     46			break;
     47	}
     48
     49	if (src_freq_idx)
     50		divider_idx |= 0x8;
     51	else if (divider_idx == 0)
     52		divider_idx = 1;
     53
     54	cb710_pci_update_config_reg(pdev, 0x40, ~0xF0000000, divider_idx << 28);
     55
     56	dev_dbg(cb710_slot_dev(slot),
     57		"clock set to %d Hz, wanted %d Hz; src_freq_idx = %d, divider_idx = %d|%d\n",
     58		src_hz >> cb710_clock_divider_log2[divider_idx & 7],
     59		hz, src_freq_idx, divider_idx & 7, divider_idx & 8);
     60}
     61
     62static void __cb710_mmc_enable_irq(struct cb710_slot *slot,
     63	unsigned short enable, unsigned short mask)
     64{
     65	/* clear global IE
     66	 * - it gets set later if any interrupt sources are enabled */
     67	mask |= CB710_MMC_IE_IRQ_ENABLE;
     68
     69	/* look like interrupt is fired whenever
     70	 * WORD[0x0C] & WORD[0x10] != 0;
     71	 * -> bit 15 port 0x0C seems to be global interrupt enable
     72	 */
     73
     74	enable = (cb710_read_port_16(slot, CB710_MMC_IRQ_ENABLE_PORT)
     75		& ~mask) | enable;
     76
     77	if (enable)
     78		enable |= CB710_MMC_IE_IRQ_ENABLE;
     79
     80	cb710_write_port_16(slot, CB710_MMC_IRQ_ENABLE_PORT, enable);
     81}
     82
     83static void cb710_mmc_enable_irq(struct cb710_slot *slot,
     84	unsigned short enable, unsigned short mask)
     85{
     86	struct cb710_mmc_reader *reader = mmc_priv(cb710_slot_to_mmc(slot));
     87	unsigned long flags;
     88
     89	spin_lock_irqsave(&reader->irq_lock, flags);
     90	/* this is the only thing irq_lock protects */
     91	__cb710_mmc_enable_irq(slot, enable, mask);
     92	spin_unlock_irqrestore(&reader->irq_lock, flags);
     93}
     94
     95static void cb710_mmc_reset_events(struct cb710_slot *slot)
     96{
     97	cb710_write_port_8(slot, CB710_MMC_STATUS0_PORT, 0xFF);
     98	cb710_write_port_8(slot, CB710_MMC_STATUS1_PORT, 0xFF);
     99	cb710_write_port_8(slot, CB710_MMC_STATUS2_PORT, 0xFF);
    100}
    101
    102static void cb710_mmc_enable_4bit_data(struct cb710_slot *slot, int enable)
    103{
    104	if (enable)
    105		cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT,
    106			CB710_MMC_C1_4BIT_DATA_BUS, 0);
    107	else
    108		cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT,
    109			0, CB710_MMC_C1_4BIT_DATA_BUS);
    110}
    111
    112static int cb710_check_event(struct cb710_slot *slot, u8 what)
    113{
    114	u16 status;
    115
    116	status = cb710_read_port_16(slot, CB710_MMC_STATUS_PORT);
    117
    118	if (status & CB710_MMC_S0_FIFO_UNDERFLOW) {
    119		/* it is just a guess, so log it */
    120		dev_dbg(cb710_slot_dev(slot),
    121			"CHECK : ignoring bit 6 in status %04X\n", status);
    122		cb710_write_port_8(slot, CB710_MMC_STATUS0_PORT,
    123			CB710_MMC_S0_FIFO_UNDERFLOW);
    124		status &= ~CB710_MMC_S0_FIFO_UNDERFLOW;
    125	}
    126
    127	if (status & CB710_MMC_STATUS_ERROR_EVENTS) {
    128		dev_dbg(cb710_slot_dev(slot),
    129			"CHECK : returning EIO on status %04X\n", status);
    130		cb710_write_port_8(slot, CB710_MMC_STATUS0_PORT, status & 0xFF);
    131		cb710_write_port_8(slot, CB710_MMC_STATUS1_PORT,
    132			CB710_MMC_S1_RESET);
    133		return -EIO;
    134	}
    135
    136	/* 'what' is a bit in MMC_STATUS1 */
    137	if ((status >> 8) & what) {
    138		cb710_write_port_8(slot, CB710_MMC_STATUS1_PORT, what);
    139		return 1;
    140	}
    141
    142	return 0;
    143}
    144
    145static int cb710_wait_for_event(struct cb710_slot *slot, u8 what)
    146{
    147	int err = 0;
    148	unsigned limit = 2000000;	/* FIXME: real timeout */
    149
    150#ifdef CONFIG_CB710_DEBUG
    151	u32 e, x;
    152	e = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
    153#endif
    154
    155	while (!(err = cb710_check_event(slot, what))) {
    156		if (!--limit) {
    157			cb710_dump_regs(cb710_slot_to_chip(slot),
    158				CB710_DUMP_REGS_MMC);
    159			err = -ETIMEDOUT;
    160			break;
    161		}
    162		udelay(1);
    163	}
    164
    165#ifdef CONFIG_CB710_DEBUG
    166	x = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
    167
    168	limit = 2000000 - limit;
    169	if (limit > 100)
    170		dev_dbg(cb710_slot_dev(slot),
    171			"WAIT10: waited %d loops, what %d, entry val %08X, exit val %08X\n",
    172			limit, what, e, x);
    173#endif
    174	return err < 0 ? err : 0;
    175}
    176
    177
    178static int cb710_wait_while_busy(struct cb710_slot *slot, uint8_t mask)
    179{
    180	unsigned limit = 500000;	/* FIXME: real timeout */
    181	int err = 0;
    182
    183#ifdef CONFIG_CB710_DEBUG
    184	u32 e, x;
    185	e = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
    186#endif
    187
    188	while (cb710_read_port_8(slot, CB710_MMC_STATUS2_PORT) & mask) {
    189		if (!--limit) {
    190			cb710_dump_regs(cb710_slot_to_chip(slot),
    191				CB710_DUMP_REGS_MMC);
    192			err = -ETIMEDOUT;
    193			break;
    194		}
    195		udelay(1);
    196	}
    197
    198#ifdef CONFIG_CB710_DEBUG
    199	x = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
    200
    201	limit = 500000 - limit;
    202	if (limit > 100)
    203		dev_dbg(cb710_slot_dev(slot),
    204			"WAIT12: waited %d loops, mask %02X, entry val %08X, exit val %08X\n",
    205			limit, mask, e, x);
    206#endif
    207	return err;
    208}
    209
    210static void cb710_mmc_set_transfer_size(struct cb710_slot *slot,
    211	size_t count, size_t blocksize)
    212{
    213	cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
    214	cb710_write_port_32(slot, CB710_MMC_TRANSFER_SIZE_PORT,
    215		((count - 1) << 16)|(blocksize - 1));
    216
    217	dev_vdbg(cb710_slot_dev(slot), "set up for %zu block%s of %zu bytes\n",
    218		count, count == 1 ? "" : "s", blocksize);
    219}
    220
    221static void cb710_mmc_fifo_hack(struct cb710_slot *slot)
    222{
    223	/* without this, received data is prepended with 8-bytes of zeroes */
    224	u32 r1, r2;
    225	int ok = 0;
    226
    227	r1 = cb710_read_port_32(slot, CB710_MMC_DATA_PORT);
    228	r2 = cb710_read_port_32(slot, CB710_MMC_DATA_PORT);
    229	if (cb710_read_port_8(slot, CB710_MMC_STATUS0_PORT)
    230	    & CB710_MMC_S0_FIFO_UNDERFLOW) {
    231		cb710_write_port_8(slot, CB710_MMC_STATUS0_PORT,
    232			CB710_MMC_S0_FIFO_UNDERFLOW);
    233		ok = 1;
    234	}
    235
    236	dev_dbg(cb710_slot_dev(slot),
    237		"FIFO-read-hack: expected STATUS0 bit was %s\n",
    238		ok ? "set." : "NOT SET!");
    239	dev_dbg(cb710_slot_dev(slot),
    240		"FIFO-read-hack: dwords ignored: %08X %08X - %s\n",
    241		r1, r2, (r1|r2) ? "BAD (NOT ZERO)!" : "ok");
    242}
    243
    244static int cb710_mmc_receive_pio(struct cb710_slot *slot,
    245	struct sg_mapping_iter *miter, size_t dw_count)
    246{
    247	if (!(cb710_read_port_8(slot, CB710_MMC_STATUS2_PORT) & CB710_MMC_S2_FIFO_READY)) {
    248		int err = cb710_wait_for_event(slot,
    249			CB710_MMC_S1_PIO_TRANSFER_DONE);
    250		if (err)
    251			return err;
    252	}
    253
    254	cb710_sg_dwiter_write_from_io(miter,
    255		slot->iobase + CB710_MMC_DATA_PORT, dw_count);
    256
    257	return 0;
    258}
    259
    260static bool cb710_is_transfer_size_supported(struct mmc_data *data)
    261{
    262	return !(data->blksz & 15 && (data->blocks != 1 || data->blksz != 8));
    263}
    264
    265static int cb710_mmc_receive(struct cb710_slot *slot, struct mmc_data *data)
    266{
    267	struct sg_mapping_iter miter;
    268	size_t len, blocks = data->blocks;
    269	int err = 0;
    270
    271	/* TODO: I don't know how/if the hardware handles non-16B-boundary blocks
    272	 * except single 8B block */
    273	if (unlikely(data->blksz & 15 && (data->blocks != 1 || data->blksz != 8)))
    274		return -EINVAL;
    275
    276	sg_miter_start(&miter, data->sg, data->sg_len, SG_MITER_TO_SG);
    277
    278	cb710_modify_port_8(slot, CB710_MMC_CONFIG2_PORT,
    279		15, CB710_MMC_C2_READ_PIO_SIZE_MASK);
    280
    281	cb710_mmc_fifo_hack(slot);
    282
    283	while (blocks-- > 0) {
    284		len = data->blksz;
    285
    286		while (len >= 16) {
    287			err = cb710_mmc_receive_pio(slot, &miter, 4);
    288			if (err)
    289				goto out;
    290			len -= 16;
    291		}
    292
    293		if (!len)
    294			continue;
    295
    296		cb710_modify_port_8(slot, CB710_MMC_CONFIG2_PORT,
    297			len - 1, CB710_MMC_C2_READ_PIO_SIZE_MASK);
    298
    299		len = (len >= 8) ? 4 : 2;
    300		err = cb710_mmc_receive_pio(slot, &miter, len);
    301		if (err)
    302			goto out;
    303	}
    304out:
    305	sg_miter_stop(&miter);
    306	return err;
    307}
    308
    309static int cb710_mmc_send(struct cb710_slot *slot, struct mmc_data *data)
    310{
    311	struct sg_mapping_iter miter;
    312	size_t len, blocks = data->blocks;
    313	int err = 0;
    314
    315	/* TODO: I don't know how/if the hardware handles multiple
    316	 * non-16B-boundary blocks */
    317	if (unlikely(data->blocks > 1 && data->blksz & 15))
    318		return -EINVAL;
    319
    320	sg_miter_start(&miter, data->sg, data->sg_len, SG_MITER_FROM_SG);
    321
    322	cb710_modify_port_8(slot, CB710_MMC_CONFIG2_PORT,
    323		0, CB710_MMC_C2_READ_PIO_SIZE_MASK);
    324
    325	while (blocks-- > 0) {
    326		len = (data->blksz + 15) >> 4;
    327		do {
    328			if (!(cb710_read_port_8(slot, CB710_MMC_STATUS2_PORT)
    329			    & CB710_MMC_S2_FIFO_EMPTY)) {
    330				err = cb710_wait_for_event(slot,
    331					CB710_MMC_S1_PIO_TRANSFER_DONE);
    332				if (err)
    333					goto out;
    334			}
    335			cb710_sg_dwiter_read_to_io(&miter,
    336				slot->iobase + CB710_MMC_DATA_PORT, 4);
    337		} while (--len);
    338	}
    339out:
    340	sg_miter_stop(&miter);
    341	return err;
    342}
    343
    344static u16 cb710_encode_cmd_flags(struct cb710_mmc_reader *reader,
    345	struct mmc_command *cmd)
    346{
    347	unsigned int flags = cmd->flags;
    348	u16 cb_flags = 0;
    349
    350	/* Windows driver returned 0 for commands for which no response
    351	 * is expected. It happened that there were only two such commands
    352	 * used: MMC_GO_IDLE_STATE and MMC_GO_INACTIVE_STATE so it might
    353	 * as well be a bug in that driver.
    354	 *
    355	 * Original driver set bit 14 for MMC/SD application
    356	 * commands. There's no difference 'on the wire' and
    357	 * it apparently works without it anyway.
    358	 */
    359
    360	switch (flags & MMC_CMD_MASK) {
    361	case MMC_CMD_AC:	cb_flags = CB710_MMC_CMD_AC;	break;
    362	case MMC_CMD_ADTC:	cb_flags = CB710_MMC_CMD_ADTC;	break;
    363	case MMC_CMD_BC:	cb_flags = CB710_MMC_CMD_BC;	break;
    364	case MMC_CMD_BCR:	cb_flags = CB710_MMC_CMD_BCR;	break;
    365	}
    366
    367	if (flags & MMC_RSP_BUSY)
    368		cb_flags |= CB710_MMC_RSP_BUSY;
    369
    370	cb_flags |= cmd->opcode << CB710_MMC_CMD_CODE_SHIFT;
    371
    372	if (cmd->data && (cmd->data->flags & MMC_DATA_READ))
    373		cb_flags |= CB710_MMC_DATA_READ;
    374
    375	if (flags & MMC_RSP_PRESENT) {
    376		/* Windows driver set 01 at bits 4,3 except for
    377		 * MMC_SET_BLOCKLEN where it set 10. Maybe the
    378		 * hardware can do something special about this
    379		 * command? The original driver looks buggy/incomplete
    380		 * anyway so we ignore this for now.
    381		 *
    382		 * I assume that 00 here means no response is expected.
    383		 */
    384		cb_flags |= CB710_MMC_RSP_PRESENT;
    385
    386		if (flags & MMC_RSP_136)
    387			cb_flags |= CB710_MMC_RSP_136;
    388		if (!(flags & MMC_RSP_CRC))
    389			cb_flags |= CB710_MMC_RSP_NO_CRC;
    390	}
    391
    392	return cb_flags;
    393}
    394
    395static void cb710_receive_response(struct cb710_slot *slot,
    396	struct mmc_command *cmd)
    397{
    398	unsigned rsp_opcode, wanted_opcode;
    399
    400	/* Looks like final byte with CRC is always stripped (same as SDHCI) */
    401	if (cmd->flags & MMC_RSP_136) {
    402		u32 resp[4];
    403
    404		resp[0] = cb710_read_port_32(slot, CB710_MMC_RESPONSE3_PORT);
    405		resp[1] = cb710_read_port_32(slot, CB710_MMC_RESPONSE2_PORT);
    406		resp[2] = cb710_read_port_32(slot, CB710_MMC_RESPONSE1_PORT);
    407		resp[3] = cb710_read_port_32(slot, CB710_MMC_RESPONSE0_PORT);
    408		rsp_opcode = resp[0] >> 24;
    409
    410		cmd->resp[0] = (resp[0] << 8)|(resp[1] >> 24);
    411		cmd->resp[1] = (resp[1] << 8)|(resp[2] >> 24);
    412		cmd->resp[2] = (resp[2] << 8)|(resp[3] >> 24);
    413		cmd->resp[3] = (resp[3] << 8);
    414	} else {
    415		rsp_opcode = cb710_read_port_32(slot, CB710_MMC_RESPONSE1_PORT) & 0x3F;
    416		cmd->resp[0] = cb710_read_port_32(slot, CB710_MMC_RESPONSE0_PORT);
    417	}
    418
    419	wanted_opcode = (cmd->flags & MMC_RSP_OPCODE) ? cmd->opcode : 0x3F;
    420	if (rsp_opcode != wanted_opcode)
    421		cmd->error = -EILSEQ;
    422}
    423
    424static int cb710_mmc_transfer_data(struct cb710_slot *slot,
    425	struct mmc_data *data)
    426{
    427	int error, to;
    428
    429	if (data->flags & MMC_DATA_READ)
    430		error = cb710_mmc_receive(slot, data);
    431	else
    432		error = cb710_mmc_send(slot, data);
    433
    434	to = cb710_wait_for_event(slot, CB710_MMC_S1_DATA_TRANSFER_DONE);
    435	if (!error)
    436		error = to;
    437
    438	if (!error)
    439		data->bytes_xfered = data->blksz * data->blocks;
    440	return error;
    441}
    442
    443static int cb710_mmc_command(struct mmc_host *mmc, struct mmc_command *cmd)
    444{
    445	struct cb710_slot *slot = cb710_mmc_to_slot(mmc);
    446	struct cb710_mmc_reader *reader = mmc_priv(mmc);
    447	struct mmc_data *data = cmd->data;
    448
    449	u16 cb_cmd = cb710_encode_cmd_flags(reader, cmd);
    450	dev_dbg(cb710_slot_dev(slot), "cmd request: 0x%04X\n", cb_cmd);
    451
    452	if (data) {
    453		if (!cb710_is_transfer_size_supported(data)) {
    454			data->error = -EINVAL;
    455			return -1;
    456		}
    457		cb710_mmc_set_transfer_size(slot, data->blocks, data->blksz);
    458	}
    459
    460	cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20|CB710_MMC_S2_BUSY_10);
    461	cb710_write_port_16(slot, CB710_MMC_CMD_TYPE_PORT, cb_cmd);
    462	cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
    463	cb710_write_port_32(slot, CB710_MMC_CMD_PARAM_PORT, cmd->arg);
    464	cb710_mmc_reset_events(slot);
    465	cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
    466	cb710_modify_port_8(slot, CB710_MMC_CONFIG0_PORT, 0x01, 0);
    467
    468	cmd->error = cb710_wait_for_event(slot, CB710_MMC_S1_COMMAND_SENT);
    469	if (cmd->error)
    470		return -1;
    471
    472	if (cmd->flags & MMC_RSP_PRESENT) {
    473		cb710_receive_response(slot, cmd);
    474		if (cmd->error)
    475			return -1;
    476	}
    477
    478	if (data)
    479		data->error = cb710_mmc_transfer_data(slot, data);
    480	return 0;
    481}
    482
    483static void cb710_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
    484{
    485	struct cb710_slot *slot = cb710_mmc_to_slot(mmc);
    486	struct cb710_mmc_reader *reader = mmc_priv(mmc);
    487
    488	WARN_ON(reader->mrq != NULL);
    489
    490	reader->mrq = mrq;
    491	cb710_mmc_enable_irq(slot, CB710_MMC_IE_TEST_MASK, 0);
    492
    493	if (!cb710_mmc_command(mmc, mrq->cmd) && mrq->stop)
    494		cb710_mmc_command(mmc, mrq->stop);
    495
    496	tasklet_schedule(&reader->finish_req_tasklet);
    497}
    498
    499static int cb710_mmc_powerup(struct cb710_slot *slot)
    500{
    501#ifdef CONFIG_CB710_DEBUG
    502	struct cb710_chip *chip = cb710_slot_to_chip(slot);
    503#endif
    504	int err;
    505
    506	/* a lot of magic for now */
    507	dev_dbg(cb710_slot_dev(slot), "bus powerup\n");
    508	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
    509	err = cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
    510	if (unlikely(err))
    511		return err;
    512	cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, 0x80, 0);
    513	cb710_modify_port_8(slot, CB710_MMC_CONFIG3_PORT, 0x80, 0);
    514	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
    515	mdelay(1);
    516	dev_dbg(cb710_slot_dev(slot), "after delay 1\n");
    517	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
    518	err = cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
    519	if (unlikely(err))
    520		return err;
    521	cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, 0x09, 0);
    522	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
    523	mdelay(1);
    524	dev_dbg(cb710_slot_dev(slot), "after delay 2\n");
    525	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
    526	err = cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
    527	if (unlikely(err))
    528		return err;
    529	cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, 0, 0x08);
    530	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
    531	mdelay(2);
    532	dev_dbg(cb710_slot_dev(slot), "after delay 3\n");
    533	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
    534	cb710_modify_port_8(slot, CB710_MMC_CONFIG0_PORT, 0x06, 0);
    535	cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, 0x70, 0);
    536	cb710_modify_port_8(slot, CB710_MMC_CONFIG2_PORT, 0x80, 0);
    537	cb710_modify_port_8(slot, CB710_MMC_CONFIG3_PORT, 0x03, 0);
    538	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
    539	err = cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
    540	if (unlikely(err))
    541		return err;
    542	/* This port behaves weird: quick byte reads of 0x08,0x09 return
    543	 * 0xFF,0x00 after writing 0xFFFF to 0x08; it works correctly when
    544	 * read/written from userspace...  What am I missing here?
    545	 * (it doesn't depend on write-to-read delay) */
    546	cb710_write_port_16(slot, CB710_MMC_CONFIGB_PORT, 0xFFFF);
    547	cb710_modify_port_8(slot, CB710_MMC_CONFIG0_PORT, 0x06, 0);
    548	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
    549	dev_dbg(cb710_slot_dev(slot), "bus powerup finished\n");
    550
    551	return cb710_check_event(slot, 0);
    552}
    553
    554static void cb710_mmc_powerdown(struct cb710_slot *slot)
    555{
    556	cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, 0, 0x81);
    557	cb710_modify_port_8(slot, CB710_MMC_CONFIG3_PORT, 0, 0x80);
    558}
    559
    560static void cb710_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
    561{
    562	struct cb710_slot *slot = cb710_mmc_to_slot(mmc);
    563	struct cb710_mmc_reader *reader = mmc_priv(mmc);
    564	int err;
    565
    566	cb710_mmc_select_clock_divider(mmc, ios->clock);
    567
    568	if (ios->power_mode != reader->last_power_mode) {
    569		switch (ios->power_mode) {
    570		case MMC_POWER_ON:
    571			err = cb710_mmc_powerup(slot);
    572			if (err) {
    573				dev_warn(cb710_slot_dev(slot),
    574					"powerup failed (%d)- retrying\n", err);
    575				cb710_mmc_powerdown(slot);
    576				udelay(1);
    577				err = cb710_mmc_powerup(slot);
    578				if (err)
    579					dev_warn(cb710_slot_dev(slot),
    580						"powerup retry failed (%d) - expect errors\n",
    581					err);
    582			}
    583			reader->last_power_mode = MMC_POWER_ON;
    584			break;
    585		case MMC_POWER_OFF:
    586			cb710_mmc_powerdown(slot);
    587			reader->last_power_mode = MMC_POWER_OFF;
    588			break;
    589		case MMC_POWER_UP:
    590		default:
    591			/* ignore */
    592			break;
    593		}
    594	}
    595
    596	cb710_mmc_enable_4bit_data(slot, ios->bus_width != MMC_BUS_WIDTH_1);
    597
    598	cb710_mmc_enable_irq(slot, CB710_MMC_IE_TEST_MASK, 0);
    599}
    600
    601static int cb710_mmc_get_ro(struct mmc_host *mmc)
    602{
    603	struct cb710_slot *slot = cb710_mmc_to_slot(mmc);
    604
    605	return cb710_read_port_8(slot, CB710_MMC_STATUS3_PORT)
    606		& CB710_MMC_S3_WRITE_PROTECTED;
    607}
    608
    609static int cb710_mmc_get_cd(struct mmc_host *mmc)
    610{
    611	struct cb710_slot *slot = cb710_mmc_to_slot(mmc);
    612
    613	return cb710_read_port_8(slot, CB710_MMC_STATUS3_PORT)
    614		& CB710_MMC_S3_CARD_DETECTED;
    615}
    616
    617static int cb710_mmc_irq_handler(struct cb710_slot *slot)
    618{
    619	struct mmc_host *mmc = cb710_slot_to_mmc(slot);
    620	struct cb710_mmc_reader *reader = mmc_priv(mmc);
    621	u32 status, config1, config2, irqen;
    622
    623	status = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
    624	irqen = cb710_read_port_32(slot, CB710_MMC_IRQ_ENABLE_PORT);
    625	config2 = cb710_read_port_32(slot, CB710_MMC_CONFIGB_PORT);
    626	config1 = cb710_read_port_32(slot, CB710_MMC_CONFIG_PORT);
    627
    628	dev_dbg(cb710_slot_dev(slot), "interrupt; status: %08X, "
    629		"ie: %08X, c2: %08X, c1: %08X\n",
    630		status, irqen, config2, config1);
    631
    632	if (status & (CB710_MMC_S1_CARD_CHANGED << 8)) {
    633		/* ack the event */
    634		cb710_write_port_8(slot, CB710_MMC_STATUS1_PORT,
    635			CB710_MMC_S1_CARD_CHANGED);
    636		if ((irqen & CB710_MMC_IE_CISTATUS_MASK)
    637		    == CB710_MMC_IE_CISTATUS_MASK)
    638			mmc_detect_change(mmc, HZ/5);
    639	} else {
    640		dev_dbg(cb710_slot_dev(slot), "unknown interrupt (test)\n");
    641		spin_lock(&reader->irq_lock);
    642		__cb710_mmc_enable_irq(slot, 0, CB710_MMC_IE_TEST_MASK);
    643		spin_unlock(&reader->irq_lock);
    644	}
    645
    646	return 1;
    647}
    648
    649static void cb710_mmc_finish_request_tasklet(struct tasklet_struct *t)
    650{
    651	struct cb710_mmc_reader *reader = from_tasklet(reader, t,
    652						       finish_req_tasklet);
    653	struct mmc_request *mrq = reader->mrq;
    654
    655	reader->mrq = NULL;
    656	mmc_request_done(mmc_from_priv(reader), mrq);
    657}
    658
    659static const struct mmc_host_ops cb710_mmc_host = {
    660	.request = cb710_mmc_request,
    661	.set_ios = cb710_mmc_set_ios,
    662	.get_ro = cb710_mmc_get_ro,
    663	.get_cd = cb710_mmc_get_cd,
    664};
    665
    666#ifdef CONFIG_PM
    667
    668static int cb710_mmc_suspend(struct platform_device *pdev, pm_message_t state)
    669{
    670	struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
    671
    672	cb710_mmc_enable_irq(slot, 0, ~0);
    673	return 0;
    674}
    675
    676static int cb710_mmc_resume(struct platform_device *pdev)
    677{
    678	struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
    679
    680	cb710_mmc_enable_irq(slot, 0, ~0);
    681	return 0;
    682}
    683
    684#endif /* CONFIG_PM */
    685
    686static int cb710_mmc_init(struct platform_device *pdev)
    687{
    688	struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
    689	struct cb710_chip *chip = cb710_slot_to_chip(slot);
    690	struct mmc_host *mmc;
    691	struct cb710_mmc_reader *reader;
    692	int err;
    693	u32 val;
    694
    695	mmc = mmc_alloc_host(sizeof(*reader), cb710_slot_dev(slot));
    696	if (!mmc)
    697		return -ENOMEM;
    698
    699	platform_set_drvdata(pdev, mmc);
    700
    701	/* harmless (maybe) magic */
    702	pci_read_config_dword(chip->pdev, 0x48, &val);
    703	val = cb710_src_freq_mhz[(val >> 16) & 0xF];
    704	dev_dbg(cb710_slot_dev(slot), "source frequency: %dMHz\n", val);
    705	val *= 1000000;
    706
    707	mmc->ops = &cb710_mmc_host;
    708	mmc->f_max = val;
    709	mmc->f_min = val >> cb710_clock_divider_log2[CB710_MAX_DIVIDER_IDX];
    710	mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
    711	mmc->caps = MMC_CAP_4_BIT_DATA;
    712	/*
    713	 * In cb710_wait_for_event() we use a fixed timeout of ~2s, hence let's
    714	 * inform the core about it. A future improvement should instead make
    715	 * use of the cmd->busy_timeout.
    716	 */
    717	mmc->max_busy_timeout = CB710_MMC_REQ_TIMEOUT_MS;
    718
    719	reader = mmc_priv(mmc);
    720
    721	tasklet_setup(&reader->finish_req_tasklet,
    722		      cb710_mmc_finish_request_tasklet);
    723	spin_lock_init(&reader->irq_lock);
    724	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
    725
    726	cb710_mmc_enable_irq(slot, 0, ~0);
    727	cb710_set_irq_handler(slot, cb710_mmc_irq_handler);
    728
    729	err = mmc_add_host(mmc);
    730	if (unlikely(err))
    731		goto err_free_mmc;
    732
    733	dev_dbg(cb710_slot_dev(slot), "mmc_hostname is %s\n",
    734		mmc_hostname(mmc));
    735
    736	cb710_mmc_enable_irq(slot, CB710_MMC_IE_CARD_INSERTION_STATUS, 0);
    737
    738	return 0;
    739
    740err_free_mmc:
    741	dev_dbg(cb710_slot_dev(slot), "mmc_add_host() failed: %d\n", err);
    742
    743	cb710_set_irq_handler(slot, NULL);
    744	mmc_free_host(mmc);
    745	return err;
    746}
    747
    748static int cb710_mmc_exit(struct platform_device *pdev)
    749{
    750	struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
    751	struct mmc_host *mmc = cb710_slot_to_mmc(slot);
    752	struct cb710_mmc_reader *reader = mmc_priv(mmc);
    753
    754	cb710_mmc_enable_irq(slot, 0, CB710_MMC_IE_CARD_INSERTION_STATUS);
    755
    756	mmc_remove_host(mmc);
    757
    758	/* IRQs should be disabled now, but let's stay on the safe side */
    759	cb710_mmc_enable_irq(slot, 0, ~0);
    760	cb710_set_irq_handler(slot, NULL);
    761
    762	/* clear config ports - just in case */
    763	cb710_write_port_32(slot, CB710_MMC_CONFIG_PORT, 0);
    764	cb710_write_port_16(slot, CB710_MMC_CONFIGB_PORT, 0);
    765
    766	tasklet_kill(&reader->finish_req_tasklet);
    767
    768	mmc_free_host(mmc);
    769	return 0;
    770}
    771
    772static struct platform_driver cb710_mmc_driver = {
    773	.driver.name = "cb710-mmc",
    774	.probe = cb710_mmc_init,
    775	.remove = cb710_mmc_exit,
    776#ifdef CONFIG_PM
    777	.suspend = cb710_mmc_suspend,
    778	.resume = cb710_mmc_resume,
    779#endif
    780};
    781
    782module_platform_driver(cb710_mmc_driver);
    783
    784MODULE_AUTHOR("Michał Mirosław <mirq-linux@rere.qmqm.pl>");
    785MODULE_DESCRIPTION("ENE CB710 memory card reader driver - MMC/SD part");
    786MODULE_LICENSE("GPL");
    787MODULE_ALIAS("platform:cb710-mmc");