diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2009-07-11 19:07:15 +0000 |
---|---|---|
committer | Lars-Peter Clausen <lars@metafoo.de> | 2009-07-11 19:07:15 +0000 |
commit | 4147b632e9930e42167b9ba399604be10fc753b0 (patch) | |
tree | de6633283a173055452d11383c870c383ce52214 | |
parent | a21bf40453f475a1e44a351e09b169e885e601c8 (diff) | |
download | mtk-20170518-4147b632e9930e42167b9ba399604be10fc753b0.zip mtk-20170518-4147b632e9930e42167b9ba399604be10fc753b0.tar.gz mtk-20170518-4147b632e9930e42167b9ba399604be10fc753b0.tar.bz2 |
Cleanup glamo mmc driver.
SVN-Revision: 16786
4 files changed, 320 insertions, 580 deletions
diff --git a/target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-core.c b/target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-core.c index a27f785..42284e6 100644 --- a/target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-core.c +++ b/target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-core.c @@ -45,8 +45,6 @@ #include <asm/uaccess.h> #include <asm/div64.h> -//#include <mach/regs-irq.h> - #ifdef CONFIG_PM #include <linux/pm.h> #endif @@ -54,11 +52,8 @@ #include "glamo-regs.h" #include "glamo-core.h" -#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1) - #define GLAMO_MEM_REFRESH_COUNT 0x100 - /* * Glamo internal settings * @@ -151,27 +146,6 @@ static inline void __reg_clear_bit(struct glamo_core *glamo, __reg_set_bit_mask(glamo, reg, bit, 0); } -static inline void glamo_vmem_write(struct glamo_core *glamo, u_int32_t addr, - u_int16_t *src, int len) -{ - if (addr & 0x0001 || (unsigned long)src & 0x0001 || len & 0x0001) { - dev_err(&glamo->pdev->dev, "unaligned write(0x%08x, 0x%p, " - "0x%x)!!\n", addr, src, len); - } - -} - -static inline void glamo_vmem_read(struct glamo_core *glamo, u_int16_t *buf, - u_int32_t addr, int len) -{ - if (addr & 0x0001 || (unsigned long) buf & 0x0001 || len & 0x0001) { - dev_err(&glamo->pdev->dev, "unaligned read(0x%p, 0x08%x, " - "0x%x)!!\n", buf, addr, len); - } - - -} - /*********************************************************************** * resources of sibling devices ***********************************************************************/ @@ -307,10 +281,10 @@ static struct resource glamo_mmc_resources[] = { }, }; -struct glamo_mci_pdata glamo_mci_def_pdata = { +static struct glamo_mci_pdata glamo_mci_def_pdata = { .gpio_detect = 0, .glamo_can_set_mci_power = NULL, /* filled in from MFD platform data */ - .ocr_avail = MMC_VDD_20_21 | +/* .ocr_avail = MMC_VDD_20_21 | MMC_VDD_21_22 | MMC_VDD_22_23 | MMC_VDD_23_24 | @@ -321,14 +295,11 @@ struct glamo_mci_pdata glamo_mci_def_pdata = { MMC_VDD_28_29 | MMC_VDD_29_30 | MMC_VDD_30_31 | - MMC_VDD_32_33, + MMC_VDD_32_33,*/ .glamo_irq_is_wired = NULL, /* filled in from MFD platform data */ .mci_suspending = NULL, /* filled in from MFD platform data */ .mci_all_dependencies_resumed = NULL, /* filled in from MFD platform data */ }; -EXPORT_SYMBOL_GPL(glamo_mci_def_pdata); - - static void mangle_mem_resources(struct resource *res, int num_res, struct resource *parent) @@ -1377,7 +1348,8 @@ static int __init glamo_probe(struct platform_device *pdev) glamo_mmc_dev->name = "glamo-mci"; glamo_mmc_dev->dev.parent = &pdev->dev; glamo_mmc_dev->resource = glamo_mmc_resources; - glamo_mmc_dev->num_resources = ARRAY_SIZE(glamo_mmc_resources); + glamo_mmc_dev->num_resources = ARRAY_SIZE(glamo_mmc_resources); + glamo_mmc_dev->dev.platform_data = &glamo_mci_def_pdata; /* we need it later to give to the engine enable and disable */ glamo_mci_def_pdata.pglamo = glamo; diff --git a/target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-core.h b/target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-core.h index 8a7907e..c0340a6 100644 --- a/target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-core.h +++ b/target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-core.h @@ -45,7 +45,6 @@ struct glamo_mci_pdata { struct glamo_core * pglamo; unsigned int gpio_detect; unsigned int gpio_wprotect; - unsigned long ocr_avail; int (*glamo_can_set_mci_power)(void); /* glamo-mci asking if it should use the slow clock to card */ int (*glamo_mci_use_slow)(void); diff --git a/target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-mci.c b/target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-mci.c index 956be57..b7808be 100644 --- a/target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-mci.c +++ b/target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-mci.c @@ -14,6 +14,7 @@ #include <linux/dma-mapping.h> #include <linux/clk.h> #include <linux/mmc/mmc.h> +#include <linux/mmc/sd.h> #include <linux/mmc/host.h> #include <linux/platform_device.h> #include <linux/irq.h> @@ -21,6 +22,7 @@ #include <linux/interrupt.h> #include <linux/spinlock.h> #include <linux/workqueue.h> +#include <linux/crc7.h> #include <asm/dma.h> #include <asm/dma-mapping.h> @@ -30,15 +32,11 @@ #include "glamo-core.h" #include "glamo-regs.h" -/* from glamo-core.c */ -extern struct glamo_mci_pdata glamo_mci_def_pdata; - -static spinlock_t clock_lock; - #define DRIVER_NAME "glamo-mci" -#define RESSIZE(ressource) (((ressource)->end - (ressource)->start) + 1) static void glamo_mci_send_request(struct mmc_host *mmc); +static void glamo_mci_send_command(struct glamo_mci_host *host, + struct mmc_command *cmd); /* * Max SD clock rate @@ -119,215 +117,137 @@ module_param(sd_idleclk, int, 0644); /* used to stash real idleclk state in suspend: we force it to run in there */ static int suspend_sd_idleclk; - -unsigned char CRC7(u8 * pu8, int cnt) +static inline void glamo_reg_write(struct glamo_mci_host *glamo, + u_int16_t reg, u_int16_t val) { - u8 crc = 0; - - while (cnt--) { - int n; - u8 d = *pu8++; - for (n = 0; n < 8; n++) { - crc <<= 1; - if ((d & 0x80) ^ (crc & 0x80)) - crc ^= 0x09; - d <<= 1; - } - } - return (crc << 1) | 1; + writew(val, glamo->mmio_base + reg); } -static int get_data_buffer(struct glamo_mci_host *host, - volatile u32 *words, volatile u16 **pointer) +static inline u_int16_t glamo_reg_read(struct glamo_mci_host *glamo, + u_int16_t reg) { - struct scatterlist *sg; - - *words = 0; - *pointer = NULL; - - if (host->pio_active == XFER_NONE) - return -EINVAL; - - if ((!host->mrq) || (!host->mrq->data)) - return -EINVAL; - - if (host->pio_sgptr >= host->mrq->data->sg_len) { - dev_dbg(&host->pdev->dev, "no more buffers (%i/%i)\n", - host->pio_sgptr, host->mrq->data->sg_len); - return -EBUSY; - } - sg = &host->mrq->data->sg[host->pio_sgptr]; - - *words = sg->length >> 1; /* we are working with a 16-bit data bus */ - *pointer = page_address(sg_page(sg)) + sg->offset; + return readw(glamo->mmio_base + reg); +} - BUG_ON(((long)(*pointer)) & 1); +static void glamo_reg_set_bit_mask(struct glamo_mci_host *glamo, + u_int16_t reg, u_int16_t mask, + u_int16_t val) +{ + u_int16_t tmp; - host->pio_sgptr++; + val &= mask; - /* dev_info(&host->pdev->dev, "new buffer (%i/%i)\n", - host->pio_sgptr, host->mrq->data->sg_len); */ - return 0; + tmp = glamo_reg_read(glamo, reg); + tmp &= ~mask; + tmp |= val; + glamo_reg_write(glamo, reg, tmp); } static void do_pio_read(struct glamo_mci_host *host) { - int res; - u16 __iomem *from_ptr = host->base_data + (RESSIZE(host->mem_data) / - sizeof(u16) / 2); -#ifdef DEBUG - u16 * block; -#endif - - while (1) { - res = get_data_buffer(host, &host->pio_words, &host->pio_ptr); - if (res) { - host->pio_active = XFER_NONE; - host->complete_what = COMPLETION_FINALIZE; - - dev_dbg(&host->pdev->dev, "pio_read(): " - "complete (no more data).\n"); - return; - } + struct scatterlist *sg; + u16 __iomem *from_ptr = host->data_base; + struct mmc_data *data = host->mrq->data; + void *sg_pointer; - dev_dbg(&host->pdev->dev, "pio_read(): host->pio_words: %d\n", - host->pio_words); - - host->pio_count += host->pio_words << 1; - -#ifdef DEBUG - block = (u16 *)host->pio_ptr; - res = host->pio_words << 1; -#endif -#if 0 - /* u16-centric memcpy */ - while (host->pio_words--) - *host->pio_ptr++ = *from_ptr++; -#else - /* memcpy can be faster? */ - memcpy((void *)host->pio_ptr, from_ptr, host->pio_words << 1); - host->pio_ptr += host->pio_words; -#endif - -#ifdef DEBUG - print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, - (void *)block, res, 1); -#endif + dev_dbg(&host->pdev->dev, "pio_read():\n"); + for (sg = data->sg; sg; sg = sg_next(sg)) { + sg_pointer = page_address(sg_page(sg)) + sg->offset; + + + memcpy(sg_pointer, from_ptr, sg->length); + from_ptr += sg->length >> 1; + + data->bytes_xfered += sg->length; } + + dev_dbg(&host->pdev->dev, "pio_read(): " + "complete (no more data).\n"); } -static int do_pio_write(struct glamo_mci_host *host) +static void do_pio_write(struct glamo_mci_host *host) { - int res = 0; - volatile u16 __iomem *to_ptr = host->base_data; - int err = 0; + struct scatterlist *sg; + u16 __iomem *to_ptr = host->data_base; + struct mmc_data *data = host->mrq->data; + void *sg_pointer; dev_dbg(&host->pdev->dev, "pio_write():\n"); - while (!res) { - res = get_data_buffer(host, &host->pio_words, &host->pio_ptr); - if (res) - continue; + for (sg = data->sg; sg; sg = sg_next(sg)) { + sg_pointer = page_address(sg_page(sg)) + sg->offset; - dev_dbg(&host->pdev->dev, "pio_write():new source: [%i]@[%p]\n", - host->pio_words, host->pio_ptr); + data->bytes_xfered += sg->length; - host->pio_count += host->pio_words << 1; - while (host->pio_words--) - writew(*host->pio_ptr++, to_ptr++); + memcpy(to_ptr, sg_pointer, sg->length); + to_ptr += sg->length >> 1; } dev_dbg(&host->pdev->dev, "pio_write(): complete\n"); - host->pio_active = XFER_NONE; - return err; } -static void __glamo_mci_fix_card_div(struct glamo_mci_host *host, int div) +static void glamo_mci_fix_card_div(struct glamo_mci_host *host, int div) { unsigned long flags; - spin_lock_irqsave(&clock_lock, flags); + spin_lock_irqsave(&host->pdata->pglamo->lock, flags); if (div < 0) { /* stop clock - remove clock from divider input */ - writew(readw(glamo_mci_def_pdata.pglamo->base + + writew(readw(host->pdata->pglamo->base + GLAMO_REG_CLOCK_GEN5_1) & (~GLAMO_CLOCK_GEN51_EN_DIV_TCLK), - glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN5_1); - - goto done; + host->pdata->pglamo->base + GLAMO_REG_CLOCK_GEN5_1); } else { - /* set the nearest prescaler factor - * - * register shared with SCLK divisor -- no chance of race because - * we don't use sensor interface - */ - writew((readw(glamo_mci_def_pdata.pglamo->base + - GLAMO_REG_CLOCK_GEN8) & 0xff00) | div, - glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN8); - /* enable clock to divider input */ - writew(readw(glamo_mci_def_pdata.pglamo->base + - GLAMO_REG_CLOCK_GEN5_1) | GLAMO_CLOCK_GEN51_EN_DIV_TCLK, - glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN5_1); - } - - if (host->force_slow_during_powerup) - div = host->clk_rate / sd_post_power_clock; - else - if (host->pdata->glamo_mci_use_slow) - if ((host->pdata->glamo_mci_use_slow)()) - div = div * sd_slow_ratio; - if (div > 255) - div = 255; + if (host->force_slow_during_powerup) + div = host->clk_rate / sd_post_power_clock; + else if (host->pdata->glamo_mci_use_slow && + host->pdata->glamo_mci_use_slow()) + div = div * sd_slow_ratio; - /* - * set the nearest prescaler factor - * - * register shared with SCLK divisor -- no chance of race because - * we don't use sensor interface - */ - writew((readw(glamo_mci_def_pdata.pglamo->base + - GLAMO_REG_CLOCK_GEN8) & 0xff00) | div, - glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN8); - /* enable clock to divider input */ - writew(readw(glamo_mci_def_pdata.pglamo->base + - GLAMO_REG_CLOCK_GEN5_1) | GLAMO_CLOCK_GEN51_EN_DIV_TCLK, - glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN5_1); - -done: - spin_unlock_irqrestore(&clock_lock, flags); + if (div > 255) + div = 255; + /* + * set the nearest prescaler factor + * + * register shared with SCLK divisor -- no chance of race because + * we don't use sensor interface + */ + writew((readw(host->pdata->pglamo->base + + GLAMO_REG_CLOCK_GEN8) & 0xff00) | div, + host->pdata->pglamo->base + GLAMO_REG_CLOCK_GEN8); + /* enable clock to divider input */ + writew(readw(host->pdata->pglamo->base + + GLAMO_REG_CLOCK_GEN5_1) | GLAMO_CLOCK_GEN51_EN_DIV_TCLK, + host->pdata->pglamo->base + GLAMO_REG_CLOCK_GEN5_1); + mdelay(5); + } + spin_unlock_irqrestore(&host->pdata->pglamo->lock, flags); } -static int __glamo_mci_set_card_clock(struct glamo_mci_host *host, int freq, - int *division) +static int glamo_mci_set_card_clock(struct glamo_mci_host *host, int freq) { int div = 0; int real_rate = 0; if (freq) { /* Set clock */ - for (div = 0; div < 256; div++) { + for (div = 0; div < 255; div++) { real_rate = host->clk_rate / (div + 1); if (real_rate <= freq) break; } - if (div > 255) - div = 255; - - if (division) - *division = div; - - __glamo_mci_fix_card_div(host, div); + host->clk_div = div; + glamo_mci_fix_card_div(host, div); } else { /* stop clock */ - if (division) - *division = 0xff; + host->clk_div = 0xff; if (!sd_idleclk && !host->force_slow_during_powerup) /* clock off */ - __glamo_mci_fix_card_div(host, -1); + glamo_mci_fix_card_div(host, -1); } - + host->real_rate = real_rate; return real_rate; } @@ -338,54 +258,46 @@ static void glamo_mci_irq_worker(struct work_struct *work) container_of(work, struct glamo_mci_host, irq_work); struct mmc_command *cmd = host->mrq->cmd; - if (host->pio_active == XFER_READ) + if (cmd->data->flags & MMC_DATA_READ) { do_pio_read(host); - - host->mrq->data->bytes_xfered = host->pio_count; - dev_dbg(&host->pdev->dev, "count=%d\n", host->pio_count); + } /* issue STOP if we have been given one to use */ if (host->mrq->stop) { - host->cmd_is_stop = 1; - glamo_mci_send_request(host->mmc); - host->cmd_is_stop = 0; + glamo_mci_send_command(host, host->mrq->stop); } if (!sd_idleclk && !host->force_slow_during_powerup) /* clock off */ - __glamo_mci_fix_card_div(host, -1); + glamo_mci_fix_card_div(host, -1); - host->complete_what = COMPLETION_NONE; host->mrq = NULL; mmc_request_done(host->mmc, cmd->mrq); } -static void glamo_mci_irq_host(struct glamo_mci_host *host) +static irqreturn_t glamo_mci_irq(int irq, void *devid) { + struct glamo_mci_host *host = (struct glamo_mci_host*)devid; u16 status; struct mmc_command *cmd; - unsigned long iflags; + unsigned long flags; if (host->suspending) { /* bad news, dangerous time */ dev_err(&host->pdev->dev, "****glamo_mci_irq before resumed\n"); - return; + goto leave; } if (!host->mrq) - return; + goto leave; cmd = host->mrq->cmd; if (!cmd) - return; + goto leave; - spin_lock_irqsave(&host->complete_lock, iflags); + spin_lock_irqsave(&host->lock, flags); - status = readw(host->base + GLAMO_REG_MMC_RB_STAT1); + status = readw(host->mmio_base + GLAMO_REG_MMC_RB_STAT1); dev_dbg(&host->pdev->dev, "status = 0x%04x\n", status); - /* ack this interrupt source */ - writew(GLAMO_IRQ_MMC, - glamo_mci_def_pdata.pglamo->base + GLAMO_REG_IRQ_CLEAR); - /* we ignore a data timeout report if we are also told the data came */ if (status & GLAMO_STAT1_MMC_RB_DRDY) status &= ~GLAMO_STAT1_MMC_DTOUT; @@ -413,39 +325,33 @@ static void glamo_mci_irq_host(struct glamo_mci_host *host) */ schedule_work(&host->irq_work); - goto leave; + goto unlock; done: - host->complete_what = COMPLETION_NONE; host->mrq = NULL; mmc_request_done(host->mmc, cmd->mrq); +unlock: + spin_unlock_irqrestore(&host->lock, flags); leave: - spin_unlock_irqrestore(&host->complete_lock, iflags); -} - -static void glamo_mci_irq(unsigned int irq, struct irq_desc *desc) -{ - struct glamo_mci_host *host = (struct glamo_mci_host *) - desc->handler_data; - - if (host) - glamo_mci_irq_host(host); - + return IRQ_HANDLED; } -static int glamo_mci_send_command(struct glamo_mci_host *host, +static void glamo_mci_send_command(struct glamo_mci_host *host, struct mmc_command *cmd) { u8 u8a[6]; u16 fire = 0; + unsigned int timeout = 1000000; + u16 * reg_resp = (u16 *)(host->mmio_base + GLAMO_REG_MMC_CMD_RSP1); + u16 status; /* if we can't do it, reject as busy */ - if (!readw(host->base + GLAMO_REG_MMC_RB_STAT1) & + if (!readw(host->mmio_base + GLAMO_REG_MMC_RB_STAT1) & GLAMO_STAT1_MMC_IDLE) { host->mrq = NULL; cmd->error = -EBUSY; mmc_request_done(host->mmc, host->mrq); - return -EBUSY; + return; } /* create an array in wire order for CRC computation */ @@ -454,15 +360,15 @@ static int glamo_mci_send_command(struct glamo_mci_host *host, u8a[2] = (u8)(cmd->arg >> 16); u8a[3] = (u8)(cmd->arg >> 8); u8a[4] = (u8)cmd->arg; - u8a[5] = CRC7(&u8a[0], 5); /* CRC7 on first 5 bytes of packet */ + u8a[5] = (crc7(0, u8a, 5) << 1) | 0x01; /* crc7 on first 5 bytes of packet */ /* issue the wire-order array including CRC in register order */ - writew((u8a[4] << 8) | u8a[5], host->base + GLAMO_REG_MMC_CMD_REG1); - writew((u8a[2] << 8) | u8a[3], host->base + GLAMO_REG_MMC_CMD_REG2); - writew((u8a[0] << 8) | u8a[1], host->base + GLAMO_REG_MMC_CMD_REG3); + writew((u8a[4] << 8) | u8a[5], host->mmio_base + GLAMO_REG_MMC_CMD_REG1); + writew((u8a[2] << 8) | u8a[3], host->mmio_base + GLAMO_REG_MMC_CMD_REG2); + writew((u8a[0] << 8) | u8a[1], host->mmio_base + GLAMO_REG_MMC_CMD_REG3); /* command index toggle */ - fire |= (host->ccnt & 1) << 12; + fire |= (host->request_counter & 1) << 12; /* set type of command */ switch (mmc_cmd_type(cmd)) { @@ -493,7 +399,7 @@ static int glamo_mci_send_command(struct glamo_mci_host *host, * check pattern, CRC7) */ switch (mmc_resp_type(cmd)) { - case MMC_RSP_R6: /* same index as R7 and R1 */ + case MMC_RSP_R1: /* same index as R6 and R7 */ fire |= GLAMO_FIRE_MMC_RSPT_R1; break; case MMC_RSP_R1B: @@ -519,7 +425,7 @@ static int glamo_mci_send_command(struct glamo_mci_host *host, fire |= GLAMO_FIRE_MMC_CC_SBR; /* single block read */ break; case MMC_SWITCH: /* 64 byte payload */ - case 0x33: /* observed issued by MCI */ + case SD_APP_SEND_SCR: case MMC_READ_MULTIPLE_BLOCK: /* we will get an interrupt off this */ if (!cmd->mrq->stop) @@ -537,7 +443,7 @@ static int glamo_mci_send_command(struct glamo_mci_host *host, /* multiblock with stop */ fire |= GLAMO_FIRE_MMC_CC_MBWS; else -// /* multiblock NO stop-- 'RESERVED'? */ + /* multiblock NO stop-- 'RESERVED'? */ fire |= GLAMO_FIRE_MMC_CC_MBWNS; break; case MMC_STOP_TRANSMISSION: @@ -547,58 +453,77 @@ static int glamo_mci_send_command(struct glamo_mci_host *host, fire |= GLAMO_FIRE_MMC_CC_BASIC; /* "basic command" */ break; } - /* always largest timeout */ - writew(0xfff, host->base + GLAMO_REG_MMC_TIMEOUT); + writew(0xfff, host->mmio_base + GLAMO_REG_MMC_TIMEOUT); /* Generate interrupt on txfer */ - writew((readw(host->base + GLAMO_REG_MMC_BASIC) & 0x3e) | + glamo_reg_set_bit_mask(host, GLAMO_REG_MMC_BASIC, ~0x3e, 0x0800 | GLAMO_BASIC_MMC_NO_CLK_RD_WAIT | - GLAMO_BASIC_MMC_EN_COMPL_INT | (sd_drive << 6), - host->base + GLAMO_REG_MMC_BASIC); + GLAMO_BASIC_MMC_EN_COMPL_INT | (sd_drive << 6)); /* send the command out on the wire */ /* dev_info(&host->pdev->dev, "Using FIRE %04X\n", fire); */ - writew(fire, host->base + GLAMO_REG_MMC_CMD_FIRE); - cmd->error = 0; - return 0; -} + writew(fire, host->mmio_base + GLAMO_REG_MMC_CMD_FIRE); + + /* we are deselecting card? because it isn't going to ack then... */ + if ((cmd->opcode == 7) && (cmd->arg == 0)) + return; -static int glamo_mci_prepare_pio(struct glamo_mci_host *host, - struct mmc_data *data) -{ /* - * the S-Media-internal RAM offset for our MMC buffer - * Read is halfway up the buffer and write is at the start + * we must spin until response is ready or timed out + * -- we don't get interrupts unless there is a bulk rx */ - if (data->flags & MMC_DATA_READ) { - writew((u16)(GLAMO_FB_SIZE + (RESSIZE(host->mem_data) / 2)), - host->base + GLAMO_REG_MMC_WDATADS1); - writew((u16)((GLAMO_FB_SIZE + - (RESSIZE(host->mem_data) / 2)) >> 16), - host->base + GLAMO_REG_MMC_WDATADS2); - } else { - writew((u16)GLAMO_FB_SIZE, host->base + - GLAMO_REG_MMC_RDATADS1); - writew((u16)(GLAMO_FB_SIZE >> 16), host->base + - GLAMO_REG_MMC_RDATADS2); + udelay(5); + do + status = readw(host->mmio_base + GLAMO_REG_MMC_RB_STAT1); + while (((((status >> 15) & 1) != (host->request_counter & 1)) || + (!(status & (GLAMO_STAT1_MMC_RB_RRDY | + GLAMO_STAT1_MMC_RTOUT | + GLAMO_STAT1_MMC_DTOUT | + GLAMO_STAT1_MMC_BWERR | + GLAMO_STAT1_MMC_BRERR)))) && (timeout--)); + + if ((status & (GLAMO_STAT1_MMC_RTOUT | + GLAMO_STAT1_MMC_DTOUT)) || + (timeout == 0)) { + cmd->error = -ETIMEDOUT; + } else if (status & (GLAMO_STAT1_MMC_BWERR | + GLAMO_STAT1_MMC_BRERR)) { + cmd->error = -EILSEQ; + } + + if (cmd->flags & MMC_RSP_PRESENT) { + if (cmd->flags & MMC_RSP_136) { + cmd->resp[3] = readw(®_resp[0]) | + (readw(®_resp[1]) << 16); + cmd->resp[2] = readw(®_resp[2]) | + (readw(®_resp[3]) << 16); + cmd->resp[1] = readw(®_resp[4]) | + (readw(®_resp[5]) << 16); + cmd->resp[0] = readw(®_resp[6]) | + (readw(®_resp[7]) << 16); + } else { + cmd->resp[0] = (readw(®_resp[0]) >> 8) | + (readw(®_resp[1]) << 8) | + ((readw(®_resp[2])) << 24); + } } +} +static int glamo_mci_prepare_pio(struct glamo_mci_host *host, + struct mmc_data *data) +{ /* set up the block info */ - writew(data->blksz, host->base + GLAMO_REG_MMC_DATBLKLEN); - writew(data->blocks, host->base + GLAMO_REG_MMC_DATBLKCNT); + writew(data->blksz, host->mmio_base + GLAMO_REG_MMC_DATBLKLEN); + writew(data->blocks, host->mmio_base + GLAMO_REG_MMC_DATBLKCNT); dev_dbg(&host->pdev->dev, "(blksz=%d, count=%d)\n", data->blksz, data->blocks); - host->pio_sgptr = 0; - host->pio_words = 0; - host->pio_count = 0; - host->pio_active = 0; + data->bytes_xfered = 0; + /* if write, prep the write into the shared RAM before the command */ if (data->flags & MMC_DATA_WRITE) { - host->pio_active = XFER_WRITE; - return do_pio_write(host); + do_pio_write(host); } - host->pio_active = XFER_READ; return 0; } @@ -606,43 +531,15 @@ static void glamo_mci_send_request(struct mmc_host *mmc) { struct glamo_mci_host *host = mmc_priv(mmc); struct mmc_request *mrq = host->mrq; - struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd; - u16 * pu16 = (u16 *)&cmd->resp[0]; - u16 * reg_resp = (u16 *)(host->base + GLAMO_REG_MMC_CMD_RSP1); - u16 status; - int n; + struct mmc_command *cmd = mrq->cmd; int timeout = 1000000; - int insanity_timeout = 1000000; - if (host->suspending) { - dev_err(&host->pdev->dev, "IGNORING glamo_mci_send_request while " - "suspended\n"); - cmd->error = -EIO; - if (cmd->data) + host->request_counter++; + /* this guy has data to read/write? */ + if (cmd->data) { + if(glamo_mci_prepare_pio(host, cmd->data)) { cmd->data->error = -EIO; - mmc_request_done(mmc, mrq); - return; - } - - host->ccnt++; - /* - * somehow 2.6.24 MCI manages to issue MMC_WRITE_BLOCK *without* the - * MMC_DATA_WRITE flag, WTF? Work around the madness. - */ - if (cmd->opcode == MMC_WRITE_BLOCK) - if (mrq->data) - mrq->data->flags |= MMC_DATA_WRITE; - - /* this guy has data to read/write? */ - if ((!host->cmd_is_stop) && cmd->data) { - int res; - host->dcnt++; - res = glamo_mci_prepare_pio(host, cmd->data); - if (res) { - cmd->error = -EIO; - cmd->data->error = -EIO; - mmc_request_done(mmc, mrq); - return; + goto done; } } @@ -654,63 +551,14 @@ static void glamo_mci_send_request(struct mmc_host *mmc) /* resume requested clock rate * scale it down by sd_slow_ratio if platform requests it */ - __glamo_mci_fix_card_div(host, host->clk_div); - - if (glamo_mci_send_command(host, cmd)) - goto bail; + glamo_mci_fix_card_div(host, host->clk_div); - /* we are deselecting card? because it isn't going to ack then... */ - if ((cmd->opcode == 7) && (cmd->arg == 0)) - goto done; + glamo_mci_send_command(host, cmd); /* - * we must spin until response is ready or timed out - * -- we don't get interrupts unless there is a bulk rx - */ - do - status = readw(host->base + GLAMO_REG_MMC_RB_STAT1); - while (((((status >> 15) & 1) != (host->ccnt & 1)) || - (!(status & (GLAMO_STAT1_MMC_RB_RRDY | - GLAMO_STAT1_MMC_RTOUT | - GLAMO_STAT1_MMC_DTOUT | - GLAMO_STAT1_MMC_BWERR | - GLAMO_STAT1_MMC_BRERR)))) && (insanity_timeout--)); - - if (insanity_timeout < 0) - dev_info(&host->pdev->dev, "command timeout, continuing\n"); - - if (status & (GLAMO_STAT1_MMC_RTOUT | - GLAMO_STAT1_MMC_DTOUT)) - cmd->error = -ETIMEDOUT; - if (status & (GLAMO_STAT1_MMC_BWERR | - GLAMO_STAT1_MMC_BRERR)) - cmd->error = -EILSEQ; - - if (host->cmd_is_stop) - goto bail; - - if (cmd->error) { - dev_info(&host->pdev->dev, "Error after cmd: 0x%x\n", status); - goto done; - } - /* - * mangle the response registers in two different exciting - * undocumented ways discovered by trial and error - */ - if (mmc_resp_type(cmd) == MMC_RSP_R2) - /* grab the response */ - for (n = 0; n < 8; n++) /* super mangle power 1 */ - pu16[n ^ 6] = readw(®_resp[n]); - else - for (n = 0; n < 3; n++) /* super mangle power 2 */ - pu16[n] = (readw(®_resp[n]) >> 8) | - (readw(®_resp[n + 1]) << 8); - /* * if we don't have bulk data to take care of, we're done */ - if (!cmd->data) - goto done; - if (!(cmd->data->flags & (MMC_DATA_READ | MMC_DATA_WRITE))) + if (!cmd->data || cmd->error) goto done; /* @@ -725,16 +573,15 @@ static void glamo_mci_send_request(struct mmc_host *mmc) * I'm afraid we have to spin on the IRQ status bit and "be * our own INT# line" */ - if (!glamo_mci_def_pdata.pglamo->irq_works) { + if (!host->pdata->pglamo->irq_works) { /* * we have faith we will get an "interrupt"... * but something insane like suspend problems can mean * we spin here forever, so we timeout after a LONG time */ - while ((!(readw(glamo_mci_def_pdata.pglamo->base + + while ((!(readw(host->pdata->pglamo->base + GLAMO_REG_IRQ_STATUS) & GLAMO_IRQ_MMC)) && - (timeout--)) - ; + (timeout--)); if (timeout < 0) { if (cmd->data->error) @@ -742,73 +589,38 @@ static void glamo_mci_send_request(struct mmc_host *mmc) dev_err(&host->pdev->dev, "Payload timeout\n"); goto bail; } + /* ack this interrupt source */ + writew(GLAMO_IRQ_MMC, host->pdata->pglamo->base + + GLAMO_REG_IRQ_CLEAR); /* yay we are an interrupt controller! -- call the ISR * it will stop clock to card */ - glamo_mci_irq_host(host); + glamo_mci_irq(IRQ_GLAMO(GLAMO_IRQIDX_MMC), host); } - return; - + return; done: - host->complete_what = COMPLETION_NONE; host->mrq = NULL; mmc_request_done(host->mmc, cmd->mrq); bail: if (!sd_idleclk && !host->force_slow_during_powerup) /* stop the clock to card */ - __glamo_mci_fix_card_div(host, -1); + glamo_mci_fix_card_div(host, -1); } static void glamo_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct glamo_mci_host *host = mmc_priv(mmc); - host->cmd_is_stop = 0; host->mrq = mrq; glamo_mci_send_request(mmc); } -#if 1 -static void glamo_mci_reset(struct glamo_mci_host *host) -{ - if (host->suspending) { - dev_err(&host->pdev->dev, "IGNORING glamo_mci_reset while " - "suspended\n"); - return; - } - dev_dbg(&host->pdev->dev, "******* glamo_mci_reset\n"); - /* reset MMC controller */ - writew(GLAMO_CLOCK_MMC_RESET | GLAMO_CLOCK_MMC_DG_TCLK | - GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK | - GLAMO_CLOCK_MMC_EN_M9CLK, - glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_MMC); - udelay(10); - /* and disable reset */ - writew(GLAMO_CLOCK_MMC_DG_TCLK | - GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK | - GLAMO_CLOCK_MMC_EN_M9CLK, - glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_MMC); -} -#endif -static inline int glamo_mci_get_mv(int vdd) -{ - int mv = 1650; - - if (vdd > 7) - mv += 350 + 100 * (vdd - 8); - - return mv; -} - static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct glamo_mci_host *host = mmc_priv(mmc); - struct regulator *regulator; - int n = 0; - int div; + int bus_width = 0; int powering = 0; - int mv; if (host->suspending) { dev_err(&host->pdev->dev, "IGNORING glamo_mci_set_ios while " @@ -816,16 +628,11 @@ static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) return; } - regulator = host->regulator; - /* Set power */ switch(ios->power_mode) { case MMC_POWER_UP: - if (host->pdata->glamo_can_set_mci_power()) { - mv = glamo_mci_get_mv(ios->vdd); - regulator_set_voltage(regulator, mv * 1000, mv * 1000); - regulator_enable(regulator); - } + mmc_regulator_set_ocr(host->regulator, ios->vdd); + host->vdd_current = ios->vdd; break; case MMC_POWER_ON: /* @@ -835,15 +642,11 @@ static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) host->force_slow_during_powerup = 1; if (host->vdd_current != ios->vdd) { - if (host->pdata->glamo_can_set_mci_power()) { - mv = glamo_mci_get_mv(ios->vdd); - regulator_set_voltage(regulator, mv * 1000, mv * 1000); - printk(KERN_INFO "SD power -> %dmV\n", mv); - } + mmc_regulator_set_ocr(host->regulator, ios->vdd); host->vdd_current = ios->vdd; } if (host->power_mode_current == MMC_POWER_OFF) { - glamo_engine_enable(glamo_mci_def_pdata.pglamo, + glamo_engine_enable(host->pdata->pglamo, GLAMO_ENGINE_MMC); powering = 1; } @@ -854,18 +657,18 @@ static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (host->power_mode_current == MMC_POWER_OFF) break; /* never want clocking with dead card */ - __glamo_mci_fix_card_div(host, -1); + glamo_mci_fix_card_div(host, -1); - glamo_engine_disable(glamo_mci_def_pdata.pglamo, + glamo_engine_disable(host->pdata->pglamo, GLAMO_ENGINE_MMC); - regulator_disable(regulator); + + mmc_regulator_set_ocr(host->regulator, 0); host->vdd_current = -1; break; } host->power_mode_current = ios->power_mode; - host->real_rate = __glamo_mci_set_card_clock(host, ios->clock, &div); - host->clk_div = div; + glamo_mci_set_card_clock(host, ios->clock); /* after power-up, we are meant to give it >= 74 clocks so it can * initialize itself. Doubt any modern cards need it but anyway... @@ -875,7 +678,7 @@ static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (!sd_idleclk && !host->force_slow_during_powerup) /* stop the clock to card, because we are idle until transfer */ - __glamo_mci_fix_card_div(host, -1); + glamo_mci_fix_card_div(host, -1); if ((ios->power_mode == MMC_POWER_ON) || (ios->power_mode == MMC_POWER_UP)) { @@ -888,14 +691,13 @@ static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) dev_info(&host->pdev->dev, "glamo_mci_set_ios: power down.\n"); /* set bus width */ - host->bus_width = ios->bus_width; - if (host->bus_width == MMC_BUS_WIDTH_4) - n = GLAMO_BASIC_MMC_EN_4BIT_DATA; - writew((readw(host->base + GLAMO_REG_MMC_BASIC) & - (~(GLAMO_BASIC_MMC_EN_4BIT_DATA | - GLAMO_BASIC_MMC_EN_DR_STR0 | - GLAMO_BASIC_MMC_EN_DR_STR1))) | n | - sd_drive << 6, host->base + GLAMO_REG_MMC_BASIC); + if (ios->bus_width == MMC_BUS_WIDTH_4) + bus_width = GLAMO_BASIC_MMC_EN_4BIT_DATA; + glamo_reg_set_bit_mask(host, GLAMO_REG_MMC_BASIC, + GLAMO_BASIC_MMC_EN_4BIT_DATA | + GLAMO_BASIC_MMC_EN_DR_STR0 | + GLAMO_BASIC_MMC_EN_DR_STR1, + bus_width | sd_drive << 6); } @@ -930,149 +732,160 @@ static int glamo_mci_probe(struct platform_device *pdev) host = mmc_priv(mmc); host->mmc = mmc; host->pdev = pdev; - host->pdata = &glamo_mci_def_pdata; + host->pdata = pdev->dev.platform_data; host->power_mode_current = MMC_POWER_OFF; - host->complete_what = COMPLETION_NONE; - host->pio_active = XFER_NONE; - - spin_lock_init(&host->complete_lock); + spin_lock_init(&host->lock); INIT_WORK(&host->irq_work, glamo_mci_irq_worker); - host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!host->mem) { + host->regulator = regulator_get(&pdev->dev, "SD_3V3"); + if (!host->regulator) { + dev_err(&pdev->dev, "Cannot proceed without regulator.\n"); + ret = -ENODEV; + goto probe_free_host; + } + + host->mmio_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!host->mmio_mem) { dev_err(&pdev->dev, "failed to get io memory region resouce.\n"); - ret = -ENOENT; - goto probe_free_host; + goto probe_regulator_put; } - host->mem = request_mem_region(host->mem->start, - RESSIZE(host->mem), pdev->name); + host->mmio_mem = request_mem_region(host->mmio_mem->start, + resource_size(host->mmio_mem), + pdev->name); - if (!host->mem) { + if (!host->mmio_mem) { dev_err(&pdev->dev, "failed to request io memory region.\n"); ret = -ENOENT; - goto probe_free_host; + goto probe_regulator_put; } - host->base = ioremap(host->mem->start, RESSIZE(host->mem)); - if (!host->base) { + host->mmio_base = ioremap(host->mmio_mem->start, + resource_size(host->mmio_mem)); + if (!host->mmio_base) { dev_err(&pdev->dev, "failed to ioremap() io memory region.\n"); ret = -EINVAL; - goto probe_free_mem_region; - } - - host->regulator = regulator_get(&pdev->dev, "SD_3V3"); - if (!host->regulator) { - dev_err(&pdev->dev, "Cannot proceed without regulator.\n"); - return -ENODEV; + goto probe_free_mem_region_mmio; } - /* set the handler for our bit of the shared chip irq register */ - set_irq_handler(IRQ_GLAMO(GLAMO_IRQIDX_MMC), glamo_mci_irq); - /* stash host as our handler's private data */ - set_irq_data(IRQ_GLAMO(GLAMO_IRQIDX_MMC), host); /* Get ahold of our data buffer we use for data in and out on MMC */ - host->mem_data = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!host->mem_data) { + host->data_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!host->data_mem) { dev_err(&pdev->dev, "failed to get io memory region resource.\n"); ret = -ENOENT; - goto probe_iounmap; + goto probe_iounmap_mmio; } - host->mem_data = request_mem_region(host->mem_data->start, - RESSIZE(host->mem_data), pdev->name); + host->data_mem = request_mem_region(host->data_mem->start, + resource_size(host->data_mem), + pdev->name); - if (!host->mem_data) { + if (!host->data_mem) { dev_err(&pdev->dev, "failed to request io memory region.\n"); ret = -ENOENT; - goto probe_iounmap; + goto probe_iounmap_mmio; } - host->base_data = ioremap(host->mem_data->start, - RESSIZE(host->mem_data)); - host->data_max_size = RESSIZE(host->mem_data); + host->data_base = ioremap(host->data_mem->start, + resource_size(host->data_mem)); - if (host->base_data == 0) { + if (host->data_base == 0) { dev_err(&pdev->dev, "failed to ioremap() io memory region.\n"); ret = -EINVAL; goto probe_free_mem_region_data; } - host->vdd_current = 0; + ret = request_irq(IRQ_GLAMO(GLAMO_IRQIDX_MMC), glamo_mci_irq, IRQF_SHARED, + pdev->name, host); + if (ret) { + dev_err(&pdev->dev, "failed to register irq.\n"); + goto probe_iounmap_data; + } + + + host->vdd_current = -1; host->clk_rate = 50000000; /* really it's 49152000 */ host->clk_div = 16; /* explain our host controller capabilities */ - mmc->ops = &glamo_mci_ops; - mmc->ocr_avail = host->pdata->ocr_avail; - mmc->caps = MMC_CAP_4_BIT_DATA | - MMC_CAP_MMC_HIGHSPEED | - MMC_CAP_SD_HIGHSPEED; - mmc->f_min = host->clk_rate / 256; - mmc->f_max = sd_max_clk; - - mmc->max_blk_count = (1 << 16) - 1; /* GLAMO_REG_MMC_RB_BLKCNT */ - mmc->max_blk_size = (1 << 12) - 1; /* GLAMO_REG_MMC_RB_BLKLEN */ - mmc->max_req_size = RESSIZE(host->mem_data) / 2; - mmc->max_seg_size = mmc->max_req_size; - mmc->max_phys_segs = 1; /* hw doesn't talk about segs??? */ - mmc->max_hw_segs = 1; - - dev_info(&host->pdev->dev, "probe: mapped mci_base:%p irq:%u.\n", - host->base, host->irq); + mmc->ops = &glamo_mci_ops; + mmc->ocr_avail = mmc_regulator_get_ocrmask(host->regulator); + mmc->caps = MMC_CAP_4_BIT_DATA | + MMC_CAP_MMC_HIGHSPEED | + MMC_CAP_SD_HIGHSPEED; + mmc->f_min = host->clk_rate / 256; + mmc->f_max = sd_max_clk; + + mmc->max_blk_count = (1 << 16) - 1; /* GLAMO_REG_MMC_RB_BLKCNT */ + mmc->max_blk_size = (1 << 12) - 1; /* GLAMO_REG_MMC_RB_BLKLEN */ + mmc->max_req_size = resource_size(host->data_mem); + mmc->max_seg_size = mmc->max_req_size; + mmc->max_phys_segs = 128; + mmc->max_hw_segs = 128; platform_set_drvdata(pdev, mmc); - glamo_engine_enable(glamo_mci_def_pdata.pglamo, GLAMO_ENGINE_MMC); - glamo_mci_reset(host); + glamo_engine_enable(host->pdata->pglamo, GLAMO_ENGINE_MMC); + glamo_engine_reset(host->pdata->pglamo, GLAMO_ENGINE_MMC); if ((ret = mmc_add_host(mmc))) { dev_err(&pdev->dev, "failed to add mmc host.\n"); - goto probe_free_mem_region_data; + goto probe_freeirq; } - dev_info(&pdev->dev,"initialisation done.\n"); - return 0; - - probe_free_mem_region_data: - release_mem_region(host->mem_data->start, RESSIZE(host->mem_data)); + writew((u16)(host->data_mem->start), + host->mmio_base + GLAMO_REG_MMC_WDATADS1); + writew((u16)((host->data_mem->start) >> 16), + host->mmio_base + GLAMO_REG_MMC_WDATADS2); - probe_iounmap: - iounmap(host->base); + writew((u16)host->data_mem->start, host->mmio_base + + GLAMO_REG_MMC_RDATADS1); + writew((u16)(host->data_mem->start >> 16), host->mmio_base + + GLAMO_REG_MMC_RDATADS2); - probe_free_mem_region: - release_mem_region(host->mem->start, RESSIZE(host->mem)); + dev_info(&pdev->dev,"initialisation done.\n"); + return 0; - probe_free_host: +probe_freeirq: + free_irq(IRQ_GLAMO(GLAMO_IRQIDX_MMC), host); +probe_iounmap_data: + iounmap(host->data_base); +probe_free_mem_region_data: + release_mem_region(host->data_mem->start, resource_size(host->data_mem)); +probe_iounmap_mmio: + iounmap(host->mmio_base); +probe_free_mem_region_mmio: + release_mem_region(host->mmio_mem->start, resource_size(host->mmio_mem)); +probe_regulator_put: + regulator_put(host->regulator); +probe_free_host: mmc_free_host(mmc); - probe_out: +probe_out: return ret; } static int glamo_mci_remove(struct platform_device *pdev) { - struct mmc_host *mmc = platform_get_drvdata(pdev); - struct glamo_mci_host *host = mmc_priv(mmc); - struct regulator *regulator; + struct mmc_host *mmc = platform_get_drvdata(pdev); + struct glamo_mci_host *host = mmc_priv(mmc); + + free_irq(IRQ_GLAMO(GLAMO_IRQIDX_MMC), host); mmc_remove_host(mmc); - /* stop using our handler, revert it to default */ - set_irq_handler(IRQ_GLAMO(GLAMO_IRQIDX_MMC), handle_level_irq); - iounmap(host->base); - iounmap(host->base_data); - release_mem_region(host->mem->start, RESSIZE(host->mem)); - release_mem_region(host->mem_data->start, RESSIZE(host->mem_data)); - - regulator = host->regulator; - regulator_put(regulator); - + iounmap(host->mmio_base); + iounmap(host->data_base); + release_mem_region(host->mmio_mem->start, resource_size(host->mmio_mem)); + release_mem_region(host->data_mem->start, resource_size(host->data_mem)); + + regulator_put(host->regulator); + mmc_free_host(mmc); - glamo_engine_disable(glamo_mci_def_pdata.pglamo, GLAMO_ENGINE_MMC); + glamo_engine_disable(host->pdata->pglamo, GLAMO_ENGINE_MMC); return 0; } @@ -1092,7 +905,7 @@ static int glamo_mci_suspend(struct platform_device *dev, pm_message_t state) * make sure the clock was running during suspend and consequently * resume */ - __glamo_mci_fix_card_div(host, host->clk_div); + glamo_mci_fix_card_div(host, host->clk_div); /* we are going to do more commands to override this in * mmc_suspend_host(), so we need to change sd_idleclk for the @@ -1104,8 +917,6 @@ static int glamo_mci_suspend(struct platform_device *dev, pm_message_t state) ret = mmc_suspend_host(mmc, state); host->suspending++; - /* so that when we resume, we use any modified max rate */ - mmc->f_max = sd_max_clk; return ret; } @@ -1119,7 +930,7 @@ int glamo_mci_resume(struct platform_device *dev) sd_idleclk = 1; glamo_engine_enable(host->pdata->pglamo, GLAMO_ENGINE_MMC); - glamo_mci_reset(host); + glamo_engine_reset(host->pdata->pglamo, GLAMO_ENGINE_MMC); host->suspending--; @@ -1149,7 +960,6 @@ static struct platform_driver glamo_mci_driver = static int __init glamo_mci_init(void) { - spin_lock_init(&clock_lock); platform_driver_register(&glamo_mci_driver); return 0; } diff --git a/target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-mci.h b/target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-mci.h index daae7a3..ae29dd8 100644 --- a/target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-mci.h +++ b/target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-mci.h @@ -12,73 +12,32 @@ #include <linux/regulator/consumer.h> -enum glamo_mci_waitfor { - COMPLETION_NONE, - COMPLETION_FINALIZE, - COMPLETION_CMDSENT, - COMPLETION_RSPFIN, - COMPLETION_XFERFINISH, - COMPLETION_XFERFINISH_RSPFIN, -}; - struct glamo_mci_host { - struct platform_device *pdev; - struct glamo_mci_pdata *pdata; - struct mmc_host *mmc; - struct resource *mem; - struct resource *mem_data; - struct clk *clk; - void __iomem *base; - u16 __iomem *base_data; - int irq; - int irq_cd; - int dma; - int data_max_size; - - int suspending; - - int power_mode_current; - unsigned int vdd_current; - - unsigned long clk_rate; - unsigned long clk_div; - unsigned long real_rate; - u8 prescaler; - - int force_slow_during_powerup; - - unsigned sdiimsk; - int dodma; - - volatile int dmatogo; + struct platform_device *pdev; + struct glamo_mci_pdata *pdata; + struct mmc_host *mmc; + struct resource *mmio_mem; + struct resource *data_mem; + void __iomem *mmio_base; + u16 __iomem *data_base; - struct mmc_request *mrq; - int cmd_is_stop; - struct work_struct irq_work; + int suspending; - spinlock_t complete_lock; - volatile enum glamo_mci_waitfor - complete_what; + int power_mode_current; + unsigned int vdd_current; - volatile int dma_complete; + unsigned long clk_rate; + unsigned long clk_div; + unsigned long real_rate; - volatile u32 pio_sgptr; - volatile u32 pio_words; - volatile u32 pio_count; - volatile u16 *pio_ptr; -#define XFER_NONE 0 -#define XFER_READ 1 -#define XFER_WRITE 2 - volatile u32 pio_active; + int force_slow_during_powerup; - int bus_width; + struct mmc_request *mrq; + struct work_struct irq_work; - char dbgmsg_cmd[301]; - char dbgmsg_dat[301]; - volatile char *status; + spinlock_t lock; - unsigned int ccnt, dcnt; - struct tasklet_struct pio_tasklet; + unsigned int request_counter; - struct regulator *regulator; + struct regulator *regulator; }; |