From 1ad2533758d50fee10e3dbd117e300c402b37e3b Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 9 May 2005 20:52:51 +0100 Subject: [PATCH] --- yaml --- r: 1098 b: refs/heads/master c: 155bb14482cc567761c13b4efc064de400c55e18 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/arm/mm/mm-armv.c | 23 +- trunk/drivers/mmc/Kconfig | 2 +- trunk/drivers/mmc/wbsd.c | 716 ++++++++++-------------------------- trunk/drivers/mmc/wbsd.h | 12 - 5 files changed, 202 insertions(+), 553 deletions(-) diff --git a/[refs] b/[refs] index 7fd71df41bb4..1adf17bc6112 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 85bcc13072c54592596c5b41d40d1c6a18b04e19 +refs/heads/master: 155bb14482cc567761c13b4efc064de400c55e18 diff --git a/trunk/arch/arm/mm/mm-armv.c b/trunk/arch/arm/mm/mm-armv.c index 585dfb8e20b9..2a514b05cd5c 100644 --- a/trunk/arch/arm/mm/mm-armv.c +++ b/trunk/arch/arm/mm/mm-armv.c @@ -142,6 +142,16 @@ __setup("noalign", noalign_setup); #define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) +static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) +{ + return pmd_offset(pgd, virt); +} + +static inline pmd_t *pmd_off_k(unsigned long virt) +{ + return pmd_off(pgd_offset_k(virt), virt); +} + /* * need to get a 16k page for level 1 */ @@ -220,7 +230,7 @@ void free_pgd_slow(pgd_t *pgd) return; /* pgd is always present and good */ - pmd = (pmd_t *)pgd; + pmd = pmd_off(pgd, 0); if (pmd_none(*pmd)) goto free; if (pmd_bad(*pmd)) { @@ -246,9 +256,8 @@ void free_pgd_slow(pgd_t *pgd) static inline void alloc_init_section(unsigned long virt, unsigned long phys, int prot) { - pmd_t *pmdp; + pmd_t *pmdp = pmd_off_k(virt); - pmdp = pmd_offset(pgd_offset_k(virt), virt); if (virt & (1 << 20)) pmdp++; @@ -283,11 +292,9 @@ alloc_init_supersection(unsigned long virt, unsigned long phys, int prot) static inline void alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot) { - pmd_t *pmdp; + pmd_t *pmdp = pmd_off_k(virt); pte_t *ptep; - pmdp = pmd_offset(pgd_offset_k(virt), virt); - if (pmd_none(*pmdp)) { unsigned long pmdval; ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * @@ -310,7 +317,7 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg */ static inline void clear_mapping(unsigned long virt) { - pmd_clear(pmd_offset(pgd_offset_k(virt), virt)); + pmd_clear(pmd_off_k(virt)); } struct mem_types { @@ -578,7 +585,7 @@ void setup_mm_for_reboot(char mode) PMD_TYPE_SECT; if (cpu_arch <= CPU_ARCH_ARMv5) pmdval |= PMD_BIT4; - pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT); + pmd = pmd_off(pgd, i << PGDIR_SHIFT); pmd[0] = __pmd(pmdval); pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); flush_pmd_entry(pmd); diff --git a/trunk/drivers/mmc/Kconfig b/trunk/drivers/mmc/Kconfig index 4991bbd054f3..2e70d74fbdee 100644 --- a/trunk/drivers/mmc/Kconfig +++ b/trunk/drivers/mmc/Kconfig @@ -51,7 +51,7 @@ config MMC_PXA config MMC_WBSD tristate "Winbond W83L51xD SD/MMC Card Interface support" - depends on MMC && ISA_DMA_API + depends on MMC && ISA && ISA_DMA_API help This selects the Winbond(R) W83L51xD Secure digital and Multimedia card Interface. diff --git a/trunk/drivers/mmc/wbsd.c b/trunk/drivers/mmc/wbsd.c index b7fbd30b49a0..39747526c719 100644 --- a/trunk/drivers/mmc/wbsd.c +++ b/trunk/drivers/mmc/wbsd.c @@ -28,9 +28,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -42,7 +40,7 @@ #include "wbsd.h" #define DRIVER_NAME "wbsd" -#define DRIVER_VERSION "1.2" +#define DRIVER_VERSION "1.1" #ifdef CONFIG_MMC_DEBUG #define DBG(x...) \ @@ -54,6 +52,10 @@ #define DBGF(x...) do { } while (0) #endif +static unsigned int io = 0x248; +static unsigned int irq = 6; +static int dma = 2; + #ifdef CONFIG_MMC_DEBUG void DBG_REG(int reg, u8 value) { @@ -76,62 +78,29 @@ void DBG_REG(int reg, u8 value) #define DBG_REG(r, v) do {} while (0) #endif -/* - * Device resources - */ - -#ifdef CONFIG_PNP - -static const struct pnp_device_id pnp_dev_table[] = { - { "WEC0517", 0 }, - { "WEC0518", 0 }, - { "", 0 }, -}; - -MODULE_DEVICE_TABLE(pnp, pnp_dev_table); - -#endif /* CONFIG_PNP */ - -#ifdef CONFIG_PNP -static unsigned int nopnp = 0; -#else -static const unsigned int nopnp = 1; -#endif -static unsigned int io = 0x248; -static unsigned int irq = 6; -static int dma = 2; - /* * Basic functions */ static inline void wbsd_unlock_config(struct wbsd_host* host) { - BUG_ON(host->config == 0); - outb(host->unlock_code, host->config); outb(host->unlock_code, host->config); } static inline void wbsd_lock_config(struct wbsd_host* host) { - BUG_ON(host->config == 0); - outb(LOCK_CODE, host->config); } static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value) { - BUG_ON(host->config == 0); - outb(reg, host->config); outb(value, host->config + 1); } static inline u8 wbsd_read_config(struct wbsd_host* host, u8 reg) { - BUG_ON(host->config == 0); - outb(reg, host->config); return inb(host->config + 1); } @@ -163,13 +132,6 @@ static void wbsd_init_device(struct wbsd_host* host) setup |= WBSD_FIFO_RESET | WBSD_SOFT_RESET; wbsd_write_index(host, WBSD_IDX_SETUP, setup); - /* - * Set DAT3 to input - */ - setup &= ~WBSD_DAT3_H; - wbsd_write_index(host, WBSD_IDX_SETUP, setup); - host->flags &= ~WBSD_FIGNORE_DETECT; - /* * Read back default clock. */ @@ -185,14 +147,6 @@ static void wbsd_init_device(struct wbsd_host* host) */ wbsd_write_index(host, WBSD_IDX_TAAC, 0x7F); - /* - * Test for card presence - */ - if (inb(host->base + WBSD_CSR) & WBSD_CARDPRESENT) - host->flags |= WBSD_FCARD_PRESENT; - else - host->flags &= ~WBSD_FCARD_PRESENT; - /* * Enable interesting interrupts. */ @@ -453,6 +407,8 @@ static inline void wbsd_get_long_reply(struct wbsd_host* host, } } +static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs); + static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd) { int i; @@ -690,13 +646,6 @@ static void wbsd_fill_fifo(struct wbsd_host* host) } wbsd_kunmap_sg(host); - - /* - * The controller stops sending interrupts for - * 'FIFO empty' under certain conditions. So we - * need to be a bit more pro-active. - */ - tasklet_schedule(&host->fifo_tasklet); } static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) @@ -901,11 +850,9 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data) wbsd_request_end(host, host->mrq); } -/*****************************************************************************\ - * * - * MMC layer callbacks * - * * -\*****************************************************************************/ +/* + * MMC Callbacks + */ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq) { @@ -927,7 +874,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq) * If there is no card in the slot then * timeout immediatly. */ - if (!(host->flags & WBSD_FCARD_PRESENT)) + if (!(inb(host->base + WBSD_CSR) & WBSD_CARDPRESENT)) { cmd->error = MMC_ERR_TIMEOUT; goto done; @@ -1006,50 +953,33 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) host->clk = clk; } - /* - * Power up card. - */ if (ios->power_mode != MMC_POWER_OFF) { + /* + * Power up card. + */ pwr = inb(host->base + WBSD_CSR); pwr &= ~WBSD_POWER_N; outb(pwr, host->base + WBSD_CSR); - } - /* - * MMC cards need to have pin 1 high during init. - * Init time corresponds rather nicely with the bus mode. - * It wreaks havoc with the card detection though so - * that needs to be disabed. - */ - setup = wbsd_read_index(host, WBSD_IDX_SETUP); - if ((ios->power_mode == MMC_POWER_ON) && - (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)) - { - setup |= WBSD_DAT3_H; - host->flags |= WBSD_FIGNORE_DETECT; - } - else - { - setup &= ~WBSD_DAT3_H; - host->flags &= ~WBSD_FIGNORE_DETECT; + /* + * This behaviour is stolen from the + * Windows driver. Don't know why, but + * it is needed. + */ + setup = wbsd_read_index(host, WBSD_IDX_SETUP); + if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) + setup |= WBSD_DAT3_H; + else + setup &= ~WBSD_DAT3_H; + wbsd_write_index(host, WBSD_IDX_SETUP, setup); + + mdelay(1); } - wbsd_write_index(host, WBSD_IDX_SETUP, setup); - + spin_unlock_bh(&host->lock); } -static struct mmc_host_ops wbsd_ops = { - .request = wbsd_request, - .set_ios = wbsd_set_ios, -}; - -/*****************************************************************************\ - * * - * Interrupt handling * - * * -\*****************************************************************************/ - /* * Tasklets */ @@ -1075,33 +1005,17 @@ static void wbsd_tasklet_card(unsigned long param) { struct wbsd_host* host = (struct wbsd_host*)param; u8 csr; - int change = 0; spin_lock(&host->lock); - if (host->flags & WBSD_FIGNORE_DETECT) - { - spin_unlock(&host->lock); - return; - } - csr = inb(host->base + WBSD_CSR); WARN_ON(csr == 0xff); if (csr & WBSD_CARDPRESENT) - { - if (!(host->flags & WBSD_FCARD_PRESENT)) - { - DBG("Card inserted\n"); - host->flags |= WBSD_FCARD_PRESENT; - change = 1; - } - } - else if (host->flags & WBSD_FCARD_PRESENT) + DBG("Card inserted\n"); + else { DBG("Card removed\n"); - host->flags &= ~WBSD_FCARD_PRESENT; - change = 1; if (host->mrq) { @@ -1119,8 +1033,7 @@ static void wbsd_tasklet_card(unsigned long param) */ spin_unlock(&host->lock); - if (change) - mmc_detect_change(host->mmc); + mmc_detect_change(host->mmc); } static void wbsd_tasklet_fifo(unsigned long param) @@ -1287,85 +1200,11 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs) return IRQ_HANDLED; } -/*****************************************************************************\ - * * - * Device initialisation and shutdown * - * * -\*****************************************************************************/ - /* - * Allocate/free MMC structure. + * Support functions for probe */ -static int __devinit wbsd_alloc_mmc(struct device* dev) -{ - struct mmc_host* mmc; - struct wbsd_host* host; - - /* - * Allocate MMC structure. - */ - mmc = mmc_alloc_host(sizeof(struct wbsd_host), dev); - if (!mmc) - return -ENOMEM; - - host = mmc_priv(mmc); - host->mmc = mmc; - - host->dma = -1; - - /* - * Set host parameters. - */ - mmc->ops = &wbsd_ops; - mmc->f_min = 375000; - mmc->f_max = 24000000; - mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; - - spin_lock_init(&host->lock); - - /* - * Maximum number of segments. Worst case is one sector per segment - * so this will be 64kB/512. - */ - mmc->max_hw_segs = 128; - mmc->max_phys_segs = 128; - - /* - * Maximum number of sectors in one transfer. Also limited by 64kB - * buffer. - */ - mmc->max_sectors = 128; - - /* - * Maximum segment size. Could be one segment with the maximum number - * of segments. - */ - mmc->max_seg_size = mmc->max_sectors * 512; - - dev_set_drvdata(dev, mmc); - - return 0; -} - -static void __devexit wbsd_free_mmc(struct device* dev) -{ - struct mmc_host* mmc; - - mmc = dev_get_drvdata(dev); - if (!mmc) - return; - - mmc_free_host(mmc); - - dev_set_drvdata(dev, NULL); -} - -/* - * Scan for known chip id:s - */ - -static int __devinit wbsd_scan(struct wbsd_host* host) +static int wbsd_scan(struct wbsd_host* host) { int i, j, k; int id; @@ -1419,16 +1258,12 @@ static int __devinit wbsd_scan(struct wbsd_host* host) return -ENODEV; } -/* - * Allocate/free io port ranges - */ - -static int __devinit wbsd_request_region(struct wbsd_host* host, int base) +static int wbsd_request_regions(struct wbsd_host* host) { if (io & 0x7) return -EINVAL; - if (!request_region(base, 8, DRIVER_NAME)) + if (!request_region(io, 8, DRIVER_NAME)) return -EIO; host->base = io; @@ -1436,25 +1271,19 @@ static int __devinit wbsd_request_region(struct wbsd_host* host, int base) return 0; } -static void __devexit wbsd_release_regions(struct wbsd_host* host) +static void wbsd_release_regions(struct wbsd_host* host) { if (host->base) release_region(host->base, 8); - - host->base = 0; if (host->config) release_region(host->config, 2); - - host->config = 0; } -/* - * Allocate/free DMA port and buffer - */ - -static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma) +static void wbsd_init_dma(struct wbsd_host* host) { + host->dma = -1; + if (dma < 0) return; @@ -1465,7 +1294,7 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma) * We need to allocate a special buffer in * order for ISA to be able to DMA to it. */ - host->dma_buffer = kmalloc(WBSD_DMA_SIZE, + host->dma_buffer = kmalloc(65536, GFP_NOIO | GFP_DMA | __GFP_REPEAT | __GFP_NOWARN); if (!host->dma_buffer) goto free; @@ -1473,8 +1302,7 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma) /* * Translate the address to a physical address. */ - host->dma_addr = dma_map_single(host->mmc->dev, host->dma_buffer, - WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); + host->dma_addr = isa_virt_to_bus(host->dma_buffer); /* * ISA DMA must be aligned on a 64k basis. @@ -1497,10 +1325,6 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma) */ BUG_ON(1); - dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE, - DMA_BIDIRECTIONAL); - host->dma_addr = (dma_addr_t)NULL; - kfree(host->dma_buffer); host->dma_buffer = NULL; @@ -1512,122 +1336,60 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma) "Falling back on FIFO.\n", dma); } -static void __devexit wbsd_release_dma(struct wbsd_host* host) -{ - if (host->dma_addr) - dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE, - DMA_BIDIRECTIONAL); - if (host->dma_buffer) - kfree(host->dma_buffer); - if (host->dma >= 0) - free_dma(host->dma); - - host->dma = -1; - host->dma_buffer = NULL; - host->dma_addr = (dma_addr_t)NULL; -} +static struct mmc_host_ops wbsd_ops = { + .request = wbsd_request, + .set_ios = wbsd_set_ios, +}; /* - * Allocate/free IRQ. + * Device probe */ -static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq) +static int wbsd_probe(struct device* dev) { + struct wbsd_host* host = NULL; + struct mmc_host* mmc = NULL; int ret; /* - * Allocate interrupt. - */ - - ret = request_irq(irq, wbsd_irq, SA_SHIRQ, DRIVER_NAME, host); - if (ret) - return ret; - - host->irq = irq; - - /* - * Set up tasklets. + * Allocate MMC structure. */ - tasklet_init(&host->card_tasklet, wbsd_tasklet_card, (unsigned long)host); - tasklet_init(&host->fifo_tasklet, wbsd_tasklet_fifo, (unsigned long)host); - tasklet_init(&host->crc_tasklet, wbsd_tasklet_crc, (unsigned long)host); - tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, (unsigned long)host); - tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host); - tasklet_init(&host->block_tasklet, wbsd_tasklet_block, (unsigned long)host); - - return 0; -} - -static void __devexit wbsd_release_irq(struct wbsd_host* host) -{ - if (!host->irq) - return; - - free_irq(host->irq, host); + mmc = mmc_alloc_host(sizeof(struct wbsd_host), dev); + if (!mmc) + return -ENOMEM; - host->irq = 0; - - tasklet_kill(&host->card_tasklet); - tasklet_kill(&host->fifo_tasklet); - tasklet_kill(&host->crc_tasklet); - tasklet_kill(&host->timeout_tasklet); - tasklet_kill(&host->finish_tasklet); - tasklet_kill(&host->block_tasklet); -} - -/* - * Allocate all resources for the host. - */ - -static int __devinit wbsd_request_resources(struct wbsd_host* host, - int base, int irq, int dma) -{ - int ret; + host = mmc_priv(mmc); + host->mmc = mmc; /* - * Allocate I/O ports. + * Scan for hardware. */ - ret = wbsd_request_region(host, base); + ret = wbsd_scan(host); if (ret) - return ret; + goto freemmc; /* - * Allocate interrupt. + * Reset the chip. + */ + wbsd_write_config(host, WBSD_CONF_SWRST, 1); + wbsd_write_config(host, WBSD_CONF_SWRST, 0); + + /* + * Allocate I/O ports. */ - ret = wbsd_request_irq(host, irq); + ret = wbsd_request_regions(host); if (ret) - return ret; + goto release; /* - * Allocate DMA. + * Set host parameters. */ - wbsd_request_dma(host, dma); + mmc->ops = &wbsd_ops; + mmc->f_min = 375000; + mmc->f_max = 24000000; + mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; - return 0; -} - -/* - * Release all resources for the host. - */ - -static void __devexit wbsd_release_resources(struct wbsd_host* host) -{ - wbsd_release_dma(host); - wbsd_release_irq(host); - wbsd_release_regions(host); -} - -/* - * Configure the resources the chip should use. - */ - -static void __devinit wbsd_chip_config(struct wbsd_host* host) -{ - /* - * Reset the chip. - */ - wbsd_write_config(host, WBSD_CONF_SWRST, 1); - wbsd_write_config(host, WBSD_CONF_SWRST, 0); + spin_lock_init(&host->lock); /* * Select SD/MMC function. @@ -1637,241 +1399,165 @@ static void __devinit wbsd_chip_config(struct wbsd_host* host) /* * Set up card detection. */ - wbsd_write_config(host, WBSD_CONF_PINS, WBSD_PINS_DETECT_GP11); + wbsd_write_config(host, WBSD_CONF_PINS, 0x02); /* - * Configure chip + * Configure I/O port. */ wbsd_write_config(host, WBSD_CONF_PORT_HI, host->base >> 8); wbsd_write_config(host, WBSD_CONF_PORT_LO, host->base & 0xff); + + /* + * Allocate interrupt. + */ + ret = request_irq(irq, wbsd_irq, SA_SHIRQ, DRIVER_NAME, host); + if (ret) + goto release; - wbsd_write_config(host, WBSD_CONF_IRQ, host->irq); - - if (host->dma >= 0) - wbsd_write_config(host, WBSD_CONF_DRQ, host->dma); + host->irq = irq; /* - * Enable and power up chip. + * Set up tasklets. */ - wbsd_write_config(host, WBSD_CONF_ENABLE, 1); - wbsd_write_config(host, WBSD_CONF_POWER, 0x20); -} - -/* - * Check that configured resources are correct. - */ - -static int __devinit wbsd_chip_validate(struct wbsd_host* host) -{ - int base, irq, dma; + tasklet_init(&host->card_tasklet, wbsd_tasklet_card, (unsigned long)host); + tasklet_init(&host->fifo_tasklet, wbsd_tasklet_fifo, (unsigned long)host); + tasklet_init(&host->crc_tasklet, wbsd_tasklet_crc, (unsigned long)host); + tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, (unsigned long)host); + tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host); + tasklet_init(&host->block_tasklet, wbsd_tasklet_block, (unsigned long)host); /* - * Select SD/MMC function. + * Configure interrupt. */ - wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD); + wbsd_write_config(host, WBSD_CONF_IRQ, host->irq); /* - * Read configuration. + * Allocate DMA. */ - base = wbsd_read_config(host, WBSD_CONF_PORT_HI) << 8; - base |= wbsd_read_config(host, WBSD_CONF_PORT_LO); - - irq = wbsd_read_config(host, WBSD_CONF_IRQ); - - dma = wbsd_read_config(host, WBSD_CONF_DRQ); + wbsd_init_dma(host); /* - * Validate against given configuration. + * If all went well, then configure DMA. */ - if (base != host->base) - return 0; - if (irq != host->irq) - return 0; - if ((dma != host->dma) && (host->dma != -1)) - return 0; - - return 1; -} - -/*****************************************************************************\ - * * - * Devices setup and shutdown * - * * -\*****************************************************************************/ - -static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, - int pnp) -{ - struct wbsd_host* host = NULL; - struct mmc_host* mmc = NULL; - int ret; + if (host->dma >= 0) + wbsd_write_config(host, WBSD_CONF_DRQ, host->dma); - ret = wbsd_alloc_mmc(dev); - if (ret) - return ret; + /* + * Maximum number of segments. Worst case is one sector per segment + * so this will be 64kB/512. + */ + mmc->max_hw_segs = 128; + mmc->max_phys_segs = 128; - mmc = dev_get_drvdata(dev); - host = mmc_priv(mmc); + /* + * Maximum number of sectors in one transfer. Also limited by 64kB + * buffer. + */ + mmc->max_sectors = 128; /* - * Scan for hardware. + * Maximum segment size. Could be one segment with the maximum number + * of segments. */ - ret = wbsd_scan(host); - if (ret) - { - if (pnp && (ret == -ENODEV)) - { - printk(KERN_WARNING DRIVER_NAME - ": Unable to confirm device presence. You may " - "experience lock-ups.\n"); - } - else - { - wbsd_free_mmc(dev); - return ret; - } - } + mmc->max_seg_size = mmc->max_sectors * 512; /* - * Request resources. + * Enable chip. */ - ret = wbsd_request_resources(host, io, irq, dma); - if (ret) - { - wbsd_release_resources(host); - wbsd_free_mmc(dev); - return ret; - } + wbsd_write_config(host, WBSD_CONF_ENABLE, 1); /* - * See if chip needs to be configured. + * Power up chip. */ - if (pnp && (host->config != 0)) - { - if (!wbsd_chip_validate(host)) - { - printk(KERN_WARNING DRIVER_NAME - ": PnP active but chip not configured! " - "You probably have a buggy BIOS. " - "Configuring chip manually.\n"); - wbsd_chip_config(host); - } - } - else - wbsd_chip_config(host); + wbsd_write_config(host, WBSD_CONF_POWER, 0x20); /* * Power Management stuff. No idea how this works. * Not tested. */ #ifdef CONFIG_PM - if (host->config) - wbsd_write_config(host, WBSD_CONF_PME, 0xA0); + wbsd_write_config(host, WBSD_CONF_PME, 0xA0); #endif - /* - * Allow device to initialise itself properly. - */ - mdelay(5); /* * Reset the chip into a known state. */ wbsd_init_device(host); + dev_set_drvdata(dev, mmc); + + /* + * Add host to MMC layer. + */ mmc_add_host(mmc); - printk(KERN_INFO "%s: W83L51xD", mmc->host_name); - if (host->chip_id != 0) - printk(" id %x", (int)host->chip_id); - printk(" at 0x%x irq %d", (int)host->base, (int)host->irq); - if (host->dma >= 0) - printk(" dma %d", (int)host->dma); - else - printk(" FIFO"); - if (pnp) - printk(" PnP"); - printk("\n"); + printk(KERN_INFO "%s: W83L51xD id %x at 0x%x irq %d dma %d\n", + mmc->host_name, (int)host->chip_id, (int)host->base, + (int)host->irq, (int)host->dma); return 0; + +release: + wbsd_release_regions(host); + +freemmc: + mmc_free_host(mmc); + + return ret; } -static void __devexit wbsd_shutdown(struct device* dev, int pnp) +/* + * Device remove + */ + +static int wbsd_remove(struct device* dev) { struct mmc_host* mmc = dev_get_drvdata(dev); struct wbsd_host* host; if (!mmc) - return; + return 0; host = mmc_priv(mmc); + /* + * Unregister host with MMC layer. + */ mmc_remove_host(mmc); - if (!pnp) - { - /* - * Power down the SD/MMC function. - */ - wbsd_unlock_config(host); - wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD); - wbsd_write_config(host, WBSD_CONF_ENABLE, 0); - wbsd_lock_config(host); - } + /* + * Power down the SD/MMC function. + */ + wbsd_unlock_config(host); + wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD); + wbsd_write_config(host, WBSD_CONF_ENABLE, 0); + wbsd_lock_config(host); - wbsd_release_resources(host); + /* + * Free resources. + */ + if (host->dma_buffer) + kfree(host->dma_buffer); - wbsd_free_mmc(dev); -} - -/* - * Non-PnP - */ - -static int __devinit wbsd_probe(struct device* dev) -{ - return wbsd_init(dev, io, irq, dma, 0); -} - -static int __devexit wbsd_remove(struct device* dev) -{ - wbsd_shutdown(dev, 0); - - return 0; -} - -/* - * PnP - */ - -#ifdef CONFIG_PNP + if (host->dma >= 0) + free_dma(host->dma); -static int __devinit -wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id) -{ - int io, irq, dma; + free_irq(host->irq, host); - /* - * Get resources from PnP layer. - */ - io = pnp_port_start(pnpdev, 0); - irq = pnp_irq(pnpdev, 0); - if (pnp_dma_valid(pnpdev, 0)) - dma = pnp_dma(pnpdev, 0); - else - dma = -1; + tasklet_kill(&host->card_tasklet); + tasklet_kill(&host->fifo_tasklet); + tasklet_kill(&host->crc_tasklet); + tasklet_kill(&host->timeout_tasklet); + tasklet_kill(&host->finish_tasklet); + tasklet_kill(&host->block_tasklet); - DBGF("PnP resources: port %3x irq %d dma %d\n", io, irq, dma); + wbsd_release_regions(host); - return wbsd_init(&pnpdev->dev, io, irq, dma, 1); -} + mmc_free_host(mmc); -static void __devexit wbsd_pnp_remove(struct pnp_dev * dev) -{ - wbsd_shutdown(&dev->dev, 1); + return 0; } -#endif /* CONFIG_PNP */ - /* * Power management */ @@ -1895,7 +1581,17 @@ static int wbsd_resume(struct device *dev, u32 level) #define wbsd_resume NULL #endif -static struct platform_device *wbsd_device; +static void wbsd_release(struct device *dev) +{ +} + +static struct platform_device wbsd_device = { + .name = DRIVER_NAME, + .id = -1, + .dev = { + .release = wbsd_release, + }, +}; static struct device_driver wbsd_driver = { .name = DRIVER_NAME, @@ -1907,17 +1603,6 @@ static struct device_driver wbsd_driver = { .resume = wbsd_resume, }; -#ifdef CONFIG_PNP - -static struct pnp_driver wbsd_pnp_driver = { - .name = DRIVER_NAME, - .id_table = pnp_dev_table, - .probe = wbsd_pnp_probe, - .remove = wbsd_pnp_remove, -}; - -#endif /* CONFIG_PNP */ - /* * Module loading/unloading */ @@ -1930,57 +1615,29 @@ static int __init wbsd_drv_init(void) ": Winbond W83L51xD SD/MMC card interface driver, " DRIVER_VERSION "\n"); printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n"); - -#ifdef CONFIG_PNP - - if (!nopnp) - { - result = pnp_register_driver(&wbsd_pnp_driver); - if (result < 0) - return result; - } - -#endif /* CONFIG_PNP */ - if (nopnp) - { - result = driver_register(&wbsd_driver); - if (result < 0) - return result; - - wbsd_device = platform_device_register_simple(DRIVER_NAME, -1, - NULL, 0); - if (IS_ERR(wbsd_device)) - return PTR_ERR(wbsd_device); - } + result = driver_register(&wbsd_driver); + if (result < 0) + return result; + + result = platform_device_register(&wbsd_device); + if (result < 0) + return result; return 0; } static void __exit wbsd_drv_exit(void) { -#ifdef CONFIG_PNP - - if (!nopnp) - pnp_unregister_driver(&wbsd_pnp_driver); + platform_device_unregister(&wbsd_device); -#endif /* CONFIG_PNP */ - - if (nopnp) - { - platform_device_unregister(wbsd_device); - - driver_unregister(&wbsd_driver); - } + driver_unregister(&wbsd_driver); DBG("unloaded\n"); } module_init(wbsd_drv_init); module_exit(wbsd_drv_exit); -#ifdef CONFIG_PNP -module_param(nopnp, uint, 0444); -#endif module_param(io, uint, 0444); module_param(irq, uint, 0444); module_param(dma, int, 0444); @@ -1989,9 +1646,6 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Winbond W83L51xD SD/MMC card interface driver"); MODULE_VERSION(DRIVER_VERSION); -#ifdef CONFIG_PNP -MODULE_PARM_DESC(nopnp, "Scan for device instead of relying on PNP. (default 0)"); -#endif MODULE_PARM_DESC(io, "I/O base to allocate. Must be 8 byte aligned. (default 0x248)"); MODULE_PARM_DESC(irq, "IRQ to allocate. (default 6)"); MODULE_PARM_DESC(dma, "DMA channel to allocate. -1 for no DMA. (default 2)"); diff --git a/trunk/drivers/mmc/wbsd.h b/trunk/drivers/mmc/wbsd.h index 864f30828d01..fdc03b56a81f 100644 --- a/trunk/drivers/mmc/wbsd.h +++ b/trunk/drivers/mmc/wbsd.h @@ -35,12 +35,6 @@ const int valid_ids[] = { #define DEVICE_SD 0x03 -#define WBSD_PINS_DAT3_HI 0x20 -#define WBSD_PINS_DAT3_OUT 0x10 -#define WBSD_PINS_GP11_HI 0x04 -#define WBSD_PINS_DETECT_GP11 0x02 -#define WBSD_PINS_DETECT_DAT3 0x01 - #define WBSD_CMDR 0x00 #define WBSD_DFR 0x01 #define WBSD_EIR 0x02 @@ -139,7 +133,6 @@ const int valid_ids[] = { #define WBSD_CRC_OK 0x05 /* S010E (00101) */ #define WBSD_CRC_FAIL 0x0B /* S101E (01011) */ -#define WBSD_DMA_SIZE 65536 struct wbsd_host { @@ -147,11 +140,6 @@ struct wbsd_host spinlock_t lock; /* Mutex */ - int flags; /* Driver states */ - -#define WBSD_FCARD_PRESENT (1<<0) /* Card is present */ -#define WBSD_FIGNORE_DETECT (1<<1) /* Ignore card detection */ - struct mmc_request* mrq; /* Current request */ u8 isr; /* Accumulated ISR */