1316 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * drivers/mmc/host/via-sdmmc.c - VIA SD/MMC Card Reader driver4 * Copyright (c) 2008, VIA Technologies Inc. All Rights Reserved.5 */6 7#include <linux/pci.h>8#include <linux/module.h>9#include <linux/dma-mapping.h>10#include <linux/highmem.h>11#include <linux/delay.h>12#include <linux/interrupt.h>13 14#include <linux/mmc/host.h>15#include <linux/workqueue.h>16 17#define DRV_NAME "via_sdmmc"18 19#define PCI_DEVICE_ID_VIA_9530 0x953020 21#define VIA_CRDR_SDC_OFF 0x20022#define VIA_CRDR_DDMA_OFF 0x40023#define VIA_CRDR_PCICTRL_OFF 0x60024 25#define VIA_CRDR_MIN_CLOCK 37500026#define VIA_CRDR_MAX_CLOCK 4800000027 28/*29 * PCI registers30 */31 32#define VIA_CRDR_PCI_WORK_MODE 0x4033#define VIA_CRDR_PCI_DBG_MODE 0x4134 35/*36 * SDC MMIO Registers37 */38 39#define VIA_CRDR_SDCTRL 0x040#define VIA_CRDR_SDCTRL_START 0x0141#define VIA_CRDR_SDCTRL_WRITE 0x0442#define VIA_CRDR_SDCTRL_SINGLE_WR 0x1043#define VIA_CRDR_SDCTRL_SINGLE_RD 0x2044#define VIA_CRDR_SDCTRL_MULTI_WR 0x3045#define VIA_CRDR_SDCTRL_MULTI_RD 0x4046#define VIA_CRDR_SDCTRL_STOP 0x7047 48#define VIA_CRDR_SDCTRL_RSP_NONE 0x049#define VIA_CRDR_SDCTRL_RSP_R1 0x1000050#define VIA_CRDR_SDCTRL_RSP_R2 0x2000051#define VIA_CRDR_SDCTRL_RSP_R3 0x3000052#define VIA_CRDR_SDCTRL_RSP_R1B 0x9000053 54#define VIA_CRDR_SDCARG 0x455 56#define VIA_CRDR_SDBUSMODE 0x857#define VIA_CRDR_SDMODE_4BIT 0x0258#define VIA_CRDR_SDMODE_CLK_ON 0x4059 60#define VIA_CRDR_SDBLKLEN 0xc61/*62 * Bit 0 -Bit 10 : Block length. So, the maximum block length should be 2048.63 * Bit 11 - Bit 13 : Reserved.64 * GPIDET : Select GPI pin to detect card, GPI means CR_CD# in top design.65 * INTEN : Enable SD host interrupt.66 * Bit 16 - Bit 31 : Block count. So, the maximun block count should be 65536.67 */68#define VIA_CRDR_SDBLKLEN_GPIDET 0x200069#define VIA_CRDR_SDBLKLEN_INTEN 0x800070#define VIA_CRDR_MAX_BLOCK_COUNT 6553671#define VIA_CRDR_MAX_BLOCK_LENGTH 204872 73#define VIA_CRDR_SDRESP0 0x1074#define VIA_CRDR_SDRESP1 0x1475#define VIA_CRDR_SDRESP2 0x1876#define VIA_CRDR_SDRESP3 0x1c77 78#define VIA_CRDR_SDCURBLKCNT 0x2079 80#define VIA_CRDR_SDINTMASK 0x2481/*82 * MBDIE : Multiple Blocks transfer Done Interrupt Enable83 * BDDIE : Block Data transfer Done Interrupt Enable84 * CIRIE : Card Insertion or Removal Interrupt Enable85 * CRDIE : Command-Response transfer Done Interrupt Enable86 * CRTOIE : Command-Response response TimeOut Interrupt Enable87 * ASCRDIE : Auto Stop Command-Response transfer Done Interrupt Enable88 * DTIE : Data access Timeout Interrupt Enable89 * SCIE : reSponse CRC error Interrupt Enable90 * RCIE : Read data CRC error Interrupt Enable91 * WCIE : Write data CRC error Interrupt Enable92 */93#define VIA_CRDR_SDINTMASK_MBDIE 0x1094#define VIA_CRDR_SDINTMASK_BDDIE 0x2095#define VIA_CRDR_SDINTMASK_CIRIE 0x8096#define VIA_CRDR_SDINTMASK_CRDIE 0x20097#define VIA_CRDR_SDINTMASK_CRTOIE 0x40098#define VIA_CRDR_SDINTMASK_ASCRDIE 0x80099#define VIA_CRDR_SDINTMASK_DTIE 0x1000100#define VIA_CRDR_SDINTMASK_SCIE 0x2000101#define VIA_CRDR_SDINTMASK_RCIE 0x4000102#define VIA_CRDR_SDINTMASK_WCIE 0x8000103 104#define VIA_CRDR_SDACTIVE_INTMASK \105 (VIA_CRDR_SDINTMASK_MBDIE | VIA_CRDR_SDINTMASK_CIRIE \106 | VIA_CRDR_SDINTMASK_CRDIE | VIA_CRDR_SDINTMASK_CRTOIE \107 | VIA_CRDR_SDINTMASK_DTIE | VIA_CRDR_SDINTMASK_SCIE \108 | VIA_CRDR_SDINTMASK_RCIE | VIA_CRDR_SDINTMASK_WCIE)109 110#define VIA_CRDR_SDSTATUS 0x28111/*112 * CECC : Reserved113 * WP : SD card Write Protect status114 * SLOTD : Reserved115 * SLOTG : SD SLOT status(Gpi pin status)116 * MBD : Multiple Blocks transfer Done interrupt status117 * BDD : Block Data transfer Done interrupt status118 * CD : Reserved119 * CIR : Card Insertion or Removal interrupt detected on GPI pin120 * IO : Reserved121 * CRD : Command-Response transfer Done interrupt status122 * CRTO : Command-Response response TimeOut interrupt status123 * ASCRDIE : Auto Stop Command-Response transfer Done interrupt status124 * DT : Data access Timeout interrupt status125 * SC : reSponse CRC error interrupt status126 * RC : Read data CRC error interrupt status127 * WC : Write data CRC error interrupt status128 */129#define VIA_CRDR_SDSTS_CECC 0x01130#define VIA_CRDR_SDSTS_WP 0x02131#define VIA_CRDR_SDSTS_SLOTD 0x04132#define VIA_CRDR_SDSTS_SLOTG 0x08133#define VIA_CRDR_SDSTS_MBD 0x10134#define VIA_CRDR_SDSTS_BDD 0x20135#define VIA_CRDR_SDSTS_CD 0x40136#define VIA_CRDR_SDSTS_CIR 0x80137#define VIA_CRDR_SDSTS_IO 0x100138#define VIA_CRDR_SDSTS_CRD 0x200139#define VIA_CRDR_SDSTS_CRTO 0x400140#define VIA_CRDR_SDSTS_ASCRDIE 0x800141#define VIA_CRDR_SDSTS_DT 0x1000142#define VIA_CRDR_SDSTS_SC 0x2000143#define VIA_CRDR_SDSTS_RC 0x4000144#define VIA_CRDR_SDSTS_WC 0x8000145 146#define VIA_CRDR_SDSTS_IGN_MASK\147 (VIA_CRDR_SDSTS_BDD | VIA_CRDR_SDSTS_ASCRDIE | VIA_CRDR_SDSTS_IO)148#define VIA_CRDR_SDSTS_INT_MASK \149 (VIA_CRDR_SDSTS_MBD | VIA_CRDR_SDSTS_BDD | VIA_CRDR_SDSTS_CD \150 | VIA_CRDR_SDSTS_CIR | VIA_CRDR_SDSTS_IO | VIA_CRDR_SDSTS_CRD \151 | VIA_CRDR_SDSTS_CRTO | VIA_CRDR_SDSTS_ASCRDIE | VIA_CRDR_SDSTS_DT \152 | VIA_CRDR_SDSTS_SC | VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC)153#define VIA_CRDR_SDSTS_W1C_MASK \154 (VIA_CRDR_SDSTS_CECC | VIA_CRDR_SDSTS_MBD | VIA_CRDR_SDSTS_BDD \155 | VIA_CRDR_SDSTS_CD | VIA_CRDR_SDSTS_CIR | VIA_CRDR_SDSTS_CRD \156 | VIA_CRDR_SDSTS_CRTO | VIA_CRDR_SDSTS_ASCRDIE | VIA_CRDR_SDSTS_DT \157 | VIA_CRDR_SDSTS_SC | VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC)158#define VIA_CRDR_SDSTS_CMD_MASK \159 (VIA_CRDR_SDSTS_CRD | VIA_CRDR_SDSTS_CRTO | VIA_CRDR_SDSTS_SC)160#define VIA_CRDR_SDSTS_DATA_MASK\161 (VIA_CRDR_SDSTS_MBD | VIA_CRDR_SDSTS_DT \162 | VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC)163 164#define VIA_CRDR_SDSTATUS2 0x2a165/*166 * CFE : Enable SD host automatic Clock FReezing167 */168#define VIA_CRDR_SDSTS_CFE 0x80169 170#define VIA_CRDR_SDRSPTMO 0x2C171 172#define VIA_CRDR_SDCLKSEL 0x30173 174#define VIA_CRDR_SDEXTCTRL 0x34175#define VIS_CRDR_SDEXTCTRL_AUTOSTOP_SD 0x01176#define VIS_CRDR_SDEXTCTRL_SHIFT_9 0x02177#define VIS_CRDR_SDEXTCTRL_MMC_8BIT 0x04178#define VIS_CRDR_SDEXTCTRL_RELD_BLK 0x08179#define VIS_CRDR_SDEXTCTRL_BAD_CMDA 0x10180#define VIS_CRDR_SDEXTCTRL_BAD_DATA 0x20181#define VIS_CRDR_SDEXTCTRL_AUTOSTOP_SPI 0x40182#define VIA_CRDR_SDEXTCTRL_HISPD 0x80183/* 0x38-0xFF reserved */184 185/*186 * Data DMA Control Registers187 */188 189#define VIA_CRDR_DMABASEADD 0x0190#define VIA_CRDR_DMACOUNTER 0x4191 192#define VIA_CRDR_DMACTRL 0x8193/*194 * DIR :Transaction Direction195 * 0 : From card to memory196 * 1 : From memory to card197 */198#define VIA_CRDR_DMACTRL_DIR 0x100199#define VIA_CRDR_DMACTRL_ENIRQ 0x10000200#define VIA_CRDR_DMACTRL_SFTRST 0x1000000201 202#define VIA_CRDR_DMASTS 0xc203 204#define VIA_CRDR_DMASTART 0x10205/*0x14-0xFF reserved*/206 207/*208 * PCI Control Registers209 */210 211/*0x0 - 0x1 reserved*/212#define VIA_CRDR_PCICLKGATT 0x2213/*214 * SFTRST :215 * 0 : Soft reset all the controller and it will be de-asserted automatically216 * 1 : Soft reset is de-asserted217 */218#define VIA_CRDR_PCICLKGATT_SFTRST 0x01219/*220 * 3V3 : Pad power select221 * 0 : 1.8V222 * 1 : 3.3V223 * NOTE : No mater what the actual value should be, this bit always224 * read as 0. This is a hardware bug.225 */226#define VIA_CRDR_PCICLKGATT_3V3 0x10227/*228 * PAD_PWRON : Pad Power on/off select229 * 0 : Power off230 * 1 : Power on231 * NOTE : No mater what the actual value should be, this bit always232 * read as 0. This is a hardware bug.233 */234#define VIA_CRDR_PCICLKGATT_PAD_PWRON 0x20235 236#define VIA_CRDR_PCISDCCLK 0x5237 238#define VIA_CRDR_PCIDMACLK 0x7239#define VIA_CRDR_PCIDMACLK_SDC 0x2240 241#define VIA_CRDR_PCIINTCTRL 0x8242#define VIA_CRDR_PCIINTCTRL_SDCIRQEN 0x04243 244#define VIA_CRDR_PCIINTSTATUS 0x9245#define VIA_CRDR_PCIINTSTATUS_SDC 0x04246 247#define VIA_CRDR_PCITMOCTRL 0xa248#define VIA_CRDR_PCITMOCTRL_NO 0x0249#define VIA_CRDR_PCITMOCTRL_32US 0x1250#define VIA_CRDR_PCITMOCTRL_256US 0x2251#define VIA_CRDR_PCITMOCTRL_1024US 0x3252#define VIA_CRDR_PCITMOCTRL_256MS 0x4253#define VIA_CRDR_PCITMOCTRL_512MS 0x5254#define VIA_CRDR_PCITMOCTRL_1024MS 0x6255 256/*0xB-0xFF reserved*/257 258enum PCI_HOST_CLK_CONTROL {259 PCI_CLK_375K = 0x03,260 PCI_CLK_8M = 0x04,261 PCI_CLK_12M = 0x00,262 PCI_CLK_16M = 0x05,263 PCI_CLK_24M = 0x01,264 PCI_CLK_33M = 0x06,265 PCI_CLK_48M = 0x02266};267 268struct sdhcreg {269 u32 sdcontrol_reg;270 u32 sdcmdarg_reg;271 u32 sdbusmode_reg;272 u32 sdblklen_reg;273 u32 sdresp_reg[4];274 u32 sdcurblkcnt_reg;275 u32 sdintmask_reg;276 u32 sdstatus_reg;277 u32 sdrsptmo_reg;278 u32 sdclksel_reg;279 u32 sdextctrl_reg;280};281 282struct pcictrlreg {283 u8 reserve[2];284 u8 pciclkgat_reg;285 u8 pcinfcclk_reg;286 u8 pcimscclk_reg;287 u8 pcisdclk_reg;288 u8 pcicaclk_reg;289 u8 pcidmaclk_reg;290 u8 pciintctrl_reg;291 u8 pciintstatus_reg;292 u8 pcitmoctrl_reg;293 u8 Resv;294};295 296struct via_crdr_mmc_host {297 struct mmc_host *mmc;298 struct mmc_request *mrq;299 struct mmc_command *cmd;300 struct mmc_data *data;301 302 void __iomem *mmiobase;303 void __iomem *sdhc_mmiobase;304 void __iomem *ddma_mmiobase;305 void __iomem *pcictrl_mmiobase;306 307 struct pcictrlreg pm_pcictrl_reg;308 struct sdhcreg pm_sdhc_reg;309 310 struct work_struct carddet_work;311 struct work_struct finish_bh_work;312 313 struct timer_list timer;314 spinlock_t lock;315 u8 power;316 int reject;317 unsigned int quirks;318};319 320/* some devices need a very long delay for power to stabilize */321#define VIA_CRDR_QUIRK_300MS_PWRDELAY 0x0001322 323#define VIA_CMD_TIMEOUT_MS 1000324 325static const struct pci_device_id via_ids[] = {326 {PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_9530,327 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,},328 {0,}329};330 331MODULE_DEVICE_TABLE(pci, via_ids);332 333static void via_print_sdchc(struct via_crdr_mmc_host *host)334{335 void __iomem *addrbase = host->sdhc_mmiobase;336 337 pr_debug("SDC MMIO Registers:\n");338 pr_debug("SDCONTROL=%08x, SDCMDARG=%08x, SDBUSMODE=%08x\n",339 readl(addrbase + VIA_CRDR_SDCTRL),340 readl(addrbase + VIA_CRDR_SDCARG),341 readl(addrbase + VIA_CRDR_SDBUSMODE));342 pr_debug("SDBLKLEN=%08x, SDCURBLKCNT=%08x, SDINTMASK=%08x\n",343 readl(addrbase + VIA_CRDR_SDBLKLEN),344 readl(addrbase + VIA_CRDR_SDCURBLKCNT),345 readl(addrbase + VIA_CRDR_SDINTMASK));346 pr_debug("SDSTATUS=%08x, SDCLKSEL=%08x, SDEXTCTRL=%08x\n",347 readl(addrbase + VIA_CRDR_SDSTATUS),348 readl(addrbase + VIA_CRDR_SDCLKSEL),349 readl(addrbase + VIA_CRDR_SDEXTCTRL));350}351 352static void via_print_pcictrl(struct via_crdr_mmc_host *host)353{354 void __iomem *addrbase = host->pcictrl_mmiobase;355 356 pr_debug("PCI Control Registers:\n");357 pr_debug("PCICLKGATT=%02x, PCISDCCLK=%02x, PCIDMACLK=%02x\n",358 readb(addrbase + VIA_CRDR_PCICLKGATT),359 readb(addrbase + VIA_CRDR_PCISDCCLK),360 readb(addrbase + VIA_CRDR_PCIDMACLK));361 pr_debug("PCIINTCTRL=%02x, PCIINTSTATUS=%02x\n",362 readb(addrbase + VIA_CRDR_PCIINTCTRL),363 readb(addrbase + VIA_CRDR_PCIINTSTATUS));364}365 366static void via_save_pcictrlreg(struct via_crdr_mmc_host *host)367{368 struct pcictrlreg *pm_pcictrl_reg;369 void __iomem *addrbase;370 371 pm_pcictrl_reg = &(host->pm_pcictrl_reg);372 addrbase = host->pcictrl_mmiobase;373 374 pm_pcictrl_reg->pciclkgat_reg = readb(addrbase + VIA_CRDR_PCICLKGATT);375 pm_pcictrl_reg->pciclkgat_reg |=376 VIA_CRDR_PCICLKGATT_3V3 | VIA_CRDR_PCICLKGATT_PAD_PWRON;377 pm_pcictrl_reg->pcisdclk_reg = readb(addrbase + VIA_CRDR_PCISDCCLK);378 pm_pcictrl_reg->pcidmaclk_reg = readb(addrbase + VIA_CRDR_PCIDMACLK);379 pm_pcictrl_reg->pciintctrl_reg = readb(addrbase + VIA_CRDR_PCIINTCTRL);380 pm_pcictrl_reg->pciintstatus_reg =381 readb(addrbase + VIA_CRDR_PCIINTSTATUS);382 pm_pcictrl_reg->pcitmoctrl_reg = readb(addrbase + VIA_CRDR_PCITMOCTRL);383}384 385static void via_restore_pcictrlreg(struct via_crdr_mmc_host *host)386{387 struct pcictrlreg *pm_pcictrl_reg;388 void __iomem *addrbase;389 390 pm_pcictrl_reg = &(host->pm_pcictrl_reg);391 addrbase = host->pcictrl_mmiobase;392 393 writeb(pm_pcictrl_reg->pciclkgat_reg, addrbase + VIA_CRDR_PCICLKGATT);394 writeb(pm_pcictrl_reg->pcisdclk_reg, addrbase + VIA_CRDR_PCISDCCLK);395 writeb(pm_pcictrl_reg->pcidmaclk_reg, addrbase + VIA_CRDR_PCIDMACLK);396 writeb(pm_pcictrl_reg->pciintctrl_reg, addrbase + VIA_CRDR_PCIINTCTRL);397 writeb(pm_pcictrl_reg->pciintstatus_reg,398 addrbase + VIA_CRDR_PCIINTSTATUS);399 writeb(pm_pcictrl_reg->pcitmoctrl_reg, addrbase + VIA_CRDR_PCITMOCTRL);400}401 402static void via_save_sdcreg(struct via_crdr_mmc_host *host)403{404 struct sdhcreg *pm_sdhc_reg;405 void __iomem *addrbase;406 407 pm_sdhc_reg = &(host->pm_sdhc_reg);408 addrbase = host->sdhc_mmiobase;409 410 pm_sdhc_reg->sdcontrol_reg = readl(addrbase + VIA_CRDR_SDCTRL);411 pm_sdhc_reg->sdcmdarg_reg = readl(addrbase + VIA_CRDR_SDCARG);412 pm_sdhc_reg->sdbusmode_reg = readl(addrbase + VIA_CRDR_SDBUSMODE);413 pm_sdhc_reg->sdblklen_reg = readl(addrbase + VIA_CRDR_SDBLKLEN);414 pm_sdhc_reg->sdcurblkcnt_reg = readl(addrbase + VIA_CRDR_SDCURBLKCNT);415 pm_sdhc_reg->sdintmask_reg = readl(addrbase + VIA_CRDR_SDINTMASK);416 pm_sdhc_reg->sdstatus_reg = readl(addrbase + VIA_CRDR_SDSTATUS);417 pm_sdhc_reg->sdrsptmo_reg = readl(addrbase + VIA_CRDR_SDRSPTMO);418 pm_sdhc_reg->sdclksel_reg = readl(addrbase + VIA_CRDR_SDCLKSEL);419 pm_sdhc_reg->sdextctrl_reg = readl(addrbase + VIA_CRDR_SDEXTCTRL);420}421 422static void via_restore_sdcreg(struct via_crdr_mmc_host *host)423{424 struct sdhcreg *pm_sdhc_reg;425 void __iomem *addrbase;426 427 pm_sdhc_reg = &(host->pm_sdhc_reg);428 addrbase = host->sdhc_mmiobase;429 430 writel(pm_sdhc_reg->sdcontrol_reg, addrbase + VIA_CRDR_SDCTRL);431 writel(pm_sdhc_reg->sdcmdarg_reg, addrbase + VIA_CRDR_SDCARG);432 writel(pm_sdhc_reg->sdbusmode_reg, addrbase + VIA_CRDR_SDBUSMODE);433 writel(pm_sdhc_reg->sdblklen_reg, addrbase + VIA_CRDR_SDBLKLEN);434 writel(pm_sdhc_reg->sdcurblkcnt_reg, addrbase + VIA_CRDR_SDCURBLKCNT);435 writel(pm_sdhc_reg->sdintmask_reg, addrbase + VIA_CRDR_SDINTMASK);436 writel(pm_sdhc_reg->sdstatus_reg, addrbase + VIA_CRDR_SDSTATUS);437 writel(pm_sdhc_reg->sdrsptmo_reg, addrbase + VIA_CRDR_SDRSPTMO);438 writel(pm_sdhc_reg->sdclksel_reg, addrbase + VIA_CRDR_SDCLKSEL);439 writel(pm_sdhc_reg->sdextctrl_reg, addrbase + VIA_CRDR_SDEXTCTRL);440}441 442static void via_pwron_sleep(struct via_crdr_mmc_host *sdhost)443{444 if (sdhost->quirks & VIA_CRDR_QUIRK_300MS_PWRDELAY)445 msleep(300);446 else447 msleep(3);448}449 450static void via_set_ddma(struct via_crdr_mmc_host *host,451 dma_addr_t dmaaddr, u32 count, int dir, int enirq)452{453 void __iomem *addrbase;454 u32 ctrl_data = 0;455 456 if (enirq)457 ctrl_data |= VIA_CRDR_DMACTRL_ENIRQ;458 459 if (dir)460 ctrl_data |= VIA_CRDR_DMACTRL_DIR;461 462 addrbase = host->ddma_mmiobase;463 464 writel(dmaaddr, addrbase + VIA_CRDR_DMABASEADD);465 writel(count, addrbase + VIA_CRDR_DMACOUNTER);466 writel(ctrl_data, addrbase + VIA_CRDR_DMACTRL);467 writel(0x01, addrbase + VIA_CRDR_DMASTART);468 469 /* It seems that our DMA can not work normally with 375kHz clock */470 /* FIXME: don't brute-force 8MHz but use PIO at 375kHz !! */471 addrbase = host->pcictrl_mmiobase;472 if (readb(addrbase + VIA_CRDR_PCISDCCLK) == PCI_CLK_375K) {473 dev_info(host->mmc->parent, "forcing card speed to 8MHz\n");474 writeb(PCI_CLK_8M, addrbase + VIA_CRDR_PCISDCCLK);475 }476}477 478static void via_sdc_preparedata(struct via_crdr_mmc_host *host,479 struct mmc_data *data)480{481 void __iomem *addrbase;482 u32 blk_reg;483 int count;484 485 WARN_ON(host->data);486 487 /* Sanity checks */488 BUG_ON(data->blksz > host->mmc->max_blk_size);489 BUG_ON(data->blocks > host->mmc->max_blk_count);490 491 host->data = data;492 493 count = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,494 ((data->flags & MMC_DATA_READ) ?495 DMA_FROM_DEVICE : DMA_TO_DEVICE));496 BUG_ON(count != 1);497 498 via_set_ddma(host, sg_dma_address(data->sg), sg_dma_len(data->sg),499 (data->flags & MMC_DATA_WRITE) ? 1 : 0, 1);500 501 addrbase = host->sdhc_mmiobase;502 503 blk_reg = data->blksz - 1;504 blk_reg |= VIA_CRDR_SDBLKLEN_GPIDET | VIA_CRDR_SDBLKLEN_INTEN;505 blk_reg |= (data->blocks) << 16;506 507 writel(blk_reg, addrbase + VIA_CRDR_SDBLKLEN);508}509 510static void via_sdc_get_response(struct via_crdr_mmc_host *host,511 struct mmc_command *cmd)512{513 void __iomem *addrbase = host->sdhc_mmiobase;514 u32 dwdata0 = readl(addrbase + VIA_CRDR_SDRESP0);515 u32 dwdata1 = readl(addrbase + VIA_CRDR_SDRESP1);516 u32 dwdata2 = readl(addrbase + VIA_CRDR_SDRESP2);517 u32 dwdata3 = readl(addrbase + VIA_CRDR_SDRESP3);518 519 if (cmd->flags & MMC_RSP_136) {520 cmd->resp[0] = ((u8) (dwdata1)) |521 (((u8) (dwdata0 >> 24)) << 8) |522 (((u8) (dwdata0 >> 16)) << 16) |523 (((u8) (dwdata0 >> 8)) << 24);524 525 cmd->resp[1] = ((u8) (dwdata2)) |526 (((u8) (dwdata1 >> 24)) << 8) |527 (((u8) (dwdata1 >> 16)) << 16) |528 (((u8) (dwdata1 >> 8)) << 24);529 530 cmd->resp[2] = ((u8) (dwdata3)) |531 (((u8) (dwdata2 >> 24)) << 8) |532 (((u8) (dwdata2 >> 16)) << 16) |533 (((u8) (dwdata2 >> 8)) << 24);534 535 cmd->resp[3] = 0xff |536 ((((u8) (dwdata3 >> 24))) << 8) |537 (((u8) (dwdata3 >> 16)) << 16) |538 (((u8) (dwdata3 >> 8)) << 24);539 } else {540 dwdata0 >>= 8;541 cmd->resp[0] = ((dwdata0 & 0xff) << 24) |542 (((dwdata0 >> 8) & 0xff) << 16) |543 (((dwdata0 >> 16) & 0xff) << 8) | (dwdata1 & 0xff);544 545 dwdata1 >>= 8;546 cmd->resp[1] = ((dwdata1 & 0xff) << 24) |547 (((dwdata1 >> 8) & 0xff) << 16) |548 (((dwdata1 >> 16) & 0xff) << 8);549 }550}551 552static void via_sdc_send_command(struct via_crdr_mmc_host *host,553 struct mmc_command *cmd)554{555 void __iomem *addrbase;556 struct mmc_data *data;557 unsigned int timeout_ms;558 u32 cmdctrl = 0;559 560 WARN_ON(host->cmd);561 562 data = cmd->data;563 host->cmd = cmd;564 565 timeout_ms = cmd->busy_timeout ? cmd->busy_timeout : VIA_CMD_TIMEOUT_MS;566 mod_timer(&host->timer, jiffies + msecs_to_jiffies(timeout_ms));567 568 /*Command index*/569 cmdctrl = cmd->opcode << 8;570 571 /*Response type*/572 switch (mmc_resp_type(cmd)) {573 case MMC_RSP_NONE:574 cmdctrl |= VIA_CRDR_SDCTRL_RSP_NONE;575 break;576 case MMC_RSP_R1:577 cmdctrl |= VIA_CRDR_SDCTRL_RSP_R1;578 break;579 case MMC_RSP_R1B:580 cmdctrl |= VIA_CRDR_SDCTRL_RSP_R1B;581 break;582 case MMC_RSP_R2:583 cmdctrl |= VIA_CRDR_SDCTRL_RSP_R2;584 break;585 case MMC_RSP_R3:586 cmdctrl |= VIA_CRDR_SDCTRL_RSP_R3;587 break;588 default:589 pr_err("%s: cmd->flag is not valid\n", mmc_hostname(host->mmc));590 break;591 }592 593 if (!(cmd->data))594 goto nodata;595 596 via_sdc_preparedata(host, data);597 598 /*Command control*/599 if (data->blocks > 1) {600 if (data->flags & MMC_DATA_WRITE) {601 cmdctrl |= VIA_CRDR_SDCTRL_WRITE;602 cmdctrl |= VIA_CRDR_SDCTRL_MULTI_WR;603 } else {604 cmdctrl |= VIA_CRDR_SDCTRL_MULTI_RD;605 }606 } else {607 if (data->flags & MMC_DATA_WRITE) {608 cmdctrl |= VIA_CRDR_SDCTRL_WRITE;609 cmdctrl |= VIA_CRDR_SDCTRL_SINGLE_WR;610 } else {611 cmdctrl |= VIA_CRDR_SDCTRL_SINGLE_RD;612 }613 }614 615nodata:616 if (cmd == host->mrq->stop)617 cmdctrl |= VIA_CRDR_SDCTRL_STOP;618 619 cmdctrl |= VIA_CRDR_SDCTRL_START;620 621 addrbase = host->sdhc_mmiobase;622 writel(cmd->arg, addrbase + VIA_CRDR_SDCARG);623 writel(cmdctrl, addrbase + VIA_CRDR_SDCTRL);624}625 626static void via_sdc_finish_data(struct via_crdr_mmc_host *host)627{628 struct mmc_data *data;629 630 BUG_ON(!host->data);631 632 data = host->data;633 host->data = NULL;634 635 if (data->error)636 data->bytes_xfered = 0;637 else638 data->bytes_xfered = data->blocks * data->blksz;639 640 dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,641 ((data->flags & MMC_DATA_READ) ?642 DMA_FROM_DEVICE : DMA_TO_DEVICE));643 644 if (data->stop)645 via_sdc_send_command(host, data->stop);646 else647 queue_work(system_bh_wq, &host->finish_bh_work);648}649 650static void via_sdc_finish_command(struct via_crdr_mmc_host *host)651{652 via_sdc_get_response(host, host->cmd);653 654 host->cmd->error = 0;655 656 if (!host->cmd->data)657 queue_work(system_bh_wq, &host->finish_bh_work);658 659 host->cmd = NULL;660}661 662static void via_sdc_request(struct mmc_host *mmc, struct mmc_request *mrq)663{664 void __iomem *addrbase;665 struct via_crdr_mmc_host *host;666 unsigned long flags;667 u16 status;668 669 host = mmc_priv(mmc);670 671 spin_lock_irqsave(&host->lock, flags);672 673 addrbase = host->pcictrl_mmiobase;674 writeb(VIA_CRDR_PCIDMACLK_SDC, addrbase + VIA_CRDR_PCIDMACLK);675 676 status = readw(host->sdhc_mmiobase + VIA_CRDR_SDSTATUS);677 status &= VIA_CRDR_SDSTS_W1C_MASK;678 writew(status, host->sdhc_mmiobase + VIA_CRDR_SDSTATUS);679 680 WARN_ON(host->mrq != NULL);681 host->mrq = mrq;682 683 status = readw(host->sdhc_mmiobase + VIA_CRDR_SDSTATUS);684 if (!(status & VIA_CRDR_SDSTS_SLOTG) || host->reject) {685 host->mrq->cmd->error = -ENOMEDIUM;686 queue_work(system_bh_wq, &host->finish_bh_work);687 } else {688 via_sdc_send_command(host, mrq->cmd);689 }690 691 spin_unlock_irqrestore(&host->lock, flags);692}693 694static void via_sdc_set_power(struct via_crdr_mmc_host *host,695 unsigned short power, unsigned int on)696{697 unsigned long flags;698 u8 gatt;699 700 spin_lock_irqsave(&host->lock, flags);701 702 host->power = (1 << power);703 704 gatt = readb(host->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);705 if (host->power == MMC_VDD_165_195)706 gatt &= ~VIA_CRDR_PCICLKGATT_3V3;707 else708 gatt |= VIA_CRDR_PCICLKGATT_3V3;709 if (on)710 gatt |= VIA_CRDR_PCICLKGATT_PAD_PWRON;711 else712 gatt &= ~VIA_CRDR_PCICLKGATT_PAD_PWRON;713 writeb(gatt, host->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);714 715 spin_unlock_irqrestore(&host->lock, flags);716 717 via_pwron_sleep(host);718}719 720static void via_sdc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)721{722 struct via_crdr_mmc_host *host;723 unsigned long flags;724 void __iomem *addrbase;725 u32 org_data, sdextctrl;726 u8 clock;727 728 host = mmc_priv(mmc);729 730 spin_lock_irqsave(&host->lock, flags);731 732 addrbase = host->sdhc_mmiobase;733 org_data = readl(addrbase + VIA_CRDR_SDBUSMODE);734 sdextctrl = readl(addrbase + VIA_CRDR_SDEXTCTRL);735 736 if (ios->bus_width == MMC_BUS_WIDTH_1)737 org_data &= ~VIA_CRDR_SDMODE_4BIT;738 else739 org_data |= VIA_CRDR_SDMODE_4BIT;740 741 if (ios->power_mode == MMC_POWER_OFF)742 org_data &= ~VIA_CRDR_SDMODE_CLK_ON;743 else744 org_data |= VIA_CRDR_SDMODE_CLK_ON;745 746 if (ios->timing == MMC_TIMING_SD_HS)747 sdextctrl |= VIA_CRDR_SDEXTCTRL_HISPD;748 else749 sdextctrl &= ~VIA_CRDR_SDEXTCTRL_HISPD;750 751 writel(org_data, addrbase + VIA_CRDR_SDBUSMODE);752 writel(sdextctrl, addrbase + VIA_CRDR_SDEXTCTRL);753 754 if (ios->clock >= 48000000)755 clock = PCI_CLK_48M;756 else if (ios->clock >= 33000000)757 clock = PCI_CLK_33M;758 else if (ios->clock >= 24000000)759 clock = PCI_CLK_24M;760 else if (ios->clock >= 16000000)761 clock = PCI_CLK_16M;762 else if (ios->clock >= 12000000)763 clock = PCI_CLK_12M;764 else if (ios->clock >= 8000000)765 clock = PCI_CLK_8M;766 else767 clock = PCI_CLK_375K;768 769 addrbase = host->pcictrl_mmiobase;770 if (readb(addrbase + VIA_CRDR_PCISDCCLK) != clock)771 writeb(clock, addrbase + VIA_CRDR_PCISDCCLK);772 773 spin_unlock_irqrestore(&host->lock, flags);774 775 if (ios->power_mode != MMC_POWER_OFF)776 via_sdc_set_power(host, ios->vdd, 1);777 else778 via_sdc_set_power(host, ios->vdd, 0);779}780 781static int via_sdc_get_ro(struct mmc_host *mmc)782{783 struct via_crdr_mmc_host *host;784 unsigned long flags;785 u16 status;786 787 host = mmc_priv(mmc);788 789 spin_lock_irqsave(&host->lock, flags);790 791 status = readw(host->sdhc_mmiobase + VIA_CRDR_SDSTATUS);792 793 spin_unlock_irqrestore(&host->lock, flags);794 795 return !(status & VIA_CRDR_SDSTS_WP);796}797 798static const struct mmc_host_ops via_sdc_ops = {799 .request = via_sdc_request,800 .set_ios = via_sdc_set_ios,801 .get_ro = via_sdc_get_ro,802};803 804static void via_reset_pcictrl(struct via_crdr_mmc_host *host)805{806 unsigned long flags;807 u8 gatt;808 809 spin_lock_irqsave(&host->lock, flags);810 811 via_save_pcictrlreg(host);812 via_save_sdcreg(host);813 814 spin_unlock_irqrestore(&host->lock, flags);815 816 gatt = VIA_CRDR_PCICLKGATT_PAD_PWRON;817 if (host->power == MMC_VDD_165_195)818 gatt &= VIA_CRDR_PCICLKGATT_3V3;819 else820 gatt |= VIA_CRDR_PCICLKGATT_3V3;821 writeb(gatt, host->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);822 via_pwron_sleep(host);823 gatt |= VIA_CRDR_PCICLKGATT_SFTRST;824 writeb(gatt, host->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);825 msleep(3);826 827 spin_lock_irqsave(&host->lock, flags);828 829 via_restore_pcictrlreg(host);830 via_restore_sdcreg(host);831 832 spin_unlock_irqrestore(&host->lock, flags);833}834 835static void via_sdc_cmd_isr(struct via_crdr_mmc_host *host, u16 intmask)836{837 BUG_ON(intmask == 0);838 839 if (!host->cmd) {840 pr_err("%s: Got command interrupt 0x%x even "841 "though no command operation was in progress.\n",842 mmc_hostname(host->mmc), intmask);843 return;844 }845 846 if (intmask & VIA_CRDR_SDSTS_CRTO)847 host->cmd->error = -ETIMEDOUT;848 else if (intmask & VIA_CRDR_SDSTS_SC)849 host->cmd->error = -EILSEQ;850 851 if (host->cmd->error)852 queue_work(system_bh_wq, &host->finish_bh_work);853 else if (intmask & VIA_CRDR_SDSTS_CRD)854 via_sdc_finish_command(host);855}856 857static void via_sdc_data_isr(struct via_crdr_mmc_host *host, u16 intmask)858{859 BUG_ON(intmask == 0);860 861 if (!host->data)862 return;863 864 if (intmask & VIA_CRDR_SDSTS_DT)865 host->data->error = -ETIMEDOUT;866 else if (intmask & (VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC))867 host->data->error = -EILSEQ;868 869 via_sdc_finish_data(host);870}871 872static irqreturn_t via_sdc_isr(int irq, void *dev_id)873{874 struct via_crdr_mmc_host *sdhost = dev_id;875 void __iomem *addrbase;876 u8 pci_status;877 u16 sd_status;878 irqreturn_t result;879 880 if (!sdhost)881 return IRQ_NONE;882 883 spin_lock(&sdhost->lock);884 885 addrbase = sdhost->pcictrl_mmiobase;886 pci_status = readb(addrbase + VIA_CRDR_PCIINTSTATUS);887 if (!(pci_status & VIA_CRDR_PCIINTSTATUS_SDC)) {888 result = IRQ_NONE;889 goto out;890 }891 892 addrbase = sdhost->sdhc_mmiobase;893 sd_status = readw(addrbase + VIA_CRDR_SDSTATUS);894 sd_status &= VIA_CRDR_SDSTS_INT_MASK;895 sd_status &= ~VIA_CRDR_SDSTS_IGN_MASK;896 if (!sd_status) {897 result = IRQ_NONE;898 goto out;899 }900 901 if (sd_status & VIA_CRDR_SDSTS_CIR) {902 writew(sd_status & VIA_CRDR_SDSTS_CIR,903 addrbase + VIA_CRDR_SDSTATUS);904 905 schedule_work(&sdhost->carddet_work);906 }907 908 sd_status &= ~VIA_CRDR_SDSTS_CIR;909 if (sd_status & VIA_CRDR_SDSTS_CMD_MASK) {910 writew(sd_status & VIA_CRDR_SDSTS_CMD_MASK,911 addrbase + VIA_CRDR_SDSTATUS);912 via_sdc_cmd_isr(sdhost, sd_status & VIA_CRDR_SDSTS_CMD_MASK);913 }914 if (sd_status & VIA_CRDR_SDSTS_DATA_MASK) {915 writew(sd_status & VIA_CRDR_SDSTS_DATA_MASK,916 addrbase + VIA_CRDR_SDSTATUS);917 via_sdc_data_isr(sdhost, sd_status & VIA_CRDR_SDSTS_DATA_MASK);918 }919 920 sd_status &= ~(VIA_CRDR_SDSTS_CMD_MASK | VIA_CRDR_SDSTS_DATA_MASK);921 if (sd_status) {922 pr_err("%s: Unexpected interrupt 0x%x\n",923 mmc_hostname(sdhost->mmc), sd_status);924 writew(sd_status, addrbase + VIA_CRDR_SDSTATUS);925 }926 927 result = IRQ_HANDLED;928 929out:930 spin_unlock(&sdhost->lock);931 932 return result;933}934 935static void via_sdc_timeout(struct timer_list *t)936{937 struct via_crdr_mmc_host *sdhost;938 unsigned long flags;939 940 sdhost = from_timer(sdhost, t, timer);941 942 spin_lock_irqsave(&sdhost->lock, flags);943 944 if (sdhost->mrq) {945 pr_err("%s: Timeout waiting for hardware interrupt."946 "cmd:0x%x\n", mmc_hostname(sdhost->mmc),947 sdhost->mrq->cmd->opcode);948 949 if (sdhost->data) {950 writel(VIA_CRDR_DMACTRL_SFTRST,951 sdhost->ddma_mmiobase + VIA_CRDR_DMACTRL);952 sdhost->data->error = -ETIMEDOUT;953 via_sdc_finish_data(sdhost);954 } else {955 if (sdhost->cmd)956 sdhost->cmd->error = -ETIMEDOUT;957 else958 sdhost->mrq->cmd->error = -ETIMEDOUT;959 queue_work(system_bh_wq, &sdhost->finish_bh_work);960 }961 }962 963 spin_unlock_irqrestore(&sdhost->lock, flags);964}965 966static void via_sdc_finish_bh_work(struct work_struct *t)967{968 struct via_crdr_mmc_host *host = from_work(host, t, finish_bh_work);969 unsigned long flags;970 struct mmc_request *mrq;971 972 spin_lock_irqsave(&host->lock, flags);973 974 del_timer(&host->timer);975 mrq = host->mrq;976 host->mrq = NULL;977 host->cmd = NULL;978 host->data = NULL;979 980 spin_unlock_irqrestore(&host->lock, flags);981 982 mmc_request_done(host->mmc, mrq);983}984 985static void via_sdc_card_detect(struct work_struct *work)986{987 struct via_crdr_mmc_host *host;988 void __iomem *addrbase;989 unsigned long flags;990 u16 status;991 992 host = container_of(work, struct via_crdr_mmc_host, carddet_work);993 994 addrbase = host->ddma_mmiobase;995 writel(VIA_CRDR_DMACTRL_SFTRST, addrbase + VIA_CRDR_DMACTRL);996 997 spin_lock_irqsave(&host->lock, flags);998 999 addrbase = host->pcictrl_mmiobase;1000 writeb(VIA_CRDR_PCIDMACLK_SDC, addrbase + VIA_CRDR_PCIDMACLK);1001 1002 addrbase = host->sdhc_mmiobase;1003 status = readw(addrbase + VIA_CRDR_SDSTATUS);1004 if (!(status & VIA_CRDR_SDSTS_SLOTG)) {1005 if (host->mrq) {1006 pr_err("%s: Card removed during transfer!\n",1007 mmc_hostname(host->mmc));1008 host->mrq->cmd->error = -ENOMEDIUM;1009 queue_work(system_bh_wq, &host->finish_bh_work);1010 }1011 1012 spin_unlock_irqrestore(&host->lock, flags);1013 1014 via_reset_pcictrl(host);1015 1016 spin_lock_irqsave(&host->lock, flags);1017 }1018 1019 spin_unlock_irqrestore(&host->lock, flags);1020 1021 via_print_pcictrl(host);1022 via_print_sdchc(host);1023 1024 mmc_detect_change(host->mmc, msecs_to_jiffies(500));1025}1026 1027static void via_init_mmc_host(struct via_crdr_mmc_host *host)1028{1029 struct mmc_host *mmc = host->mmc;1030 void __iomem *addrbase;1031 u32 lenreg;1032 u32 status;1033 1034 timer_setup(&host->timer, via_sdc_timeout, 0);1035 1036 spin_lock_init(&host->lock);1037 1038 mmc->f_min = VIA_CRDR_MIN_CLOCK;1039 mmc->f_max = VIA_CRDR_MAX_CLOCK;1040 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;1041 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED;1042 mmc->ops = &via_sdc_ops;1043 1044 /*Hardware cannot do scatter lists*/1045 mmc->max_segs = 1;1046 1047 mmc->max_blk_size = VIA_CRDR_MAX_BLOCK_LENGTH;1048 mmc->max_blk_count = VIA_CRDR_MAX_BLOCK_COUNT;1049 1050 mmc->max_seg_size = mmc->max_blk_size * mmc->max_blk_count;1051 mmc->max_req_size = mmc->max_seg_size;1052 1053 INIT_WORK(&host->carddet_work, via_sdc_card_detect);1054 1055 INIT_WORK(&host->finish_bh_work, via_sdc_finish_bh_work);1056 1057 addrbase = host->sdhc_mmiobase;1058 writel(0x0, addrbase + VIA_CRDR_SDINTMASK);1059 msleep(1);1060 1061 lenreg = VIA_CRDR_SDBLKLEN_GPIDET | VIA_CRDR_SDBLKLEN_INTEN;1062 writel(lenreg, addrbase + VIA_CRDR_SDBLKLEN);1063 1064 status = readw(addrbase + VIA_CRDR_SDSTATUS);1065 status &= VIA_CRDR_SDSTS_W1C_MASK;1066 writew(status, addrbase + VIA_CRDR_SDSTATUS);1067 1068 status = readw(addrbase + VIA_CRDR_SDSTATUS2);1069 status |= VIA_CRDR_SDSTS_CFE;1070 writew(status, addrbase + VIA_CRDR_SDSTATUS2);1071 1072 writeb(0x0, addrbase + VIA_CRDR_SDEXTCTRL);1073 1074 writel(VIA_CRDR_SDACTIVE_INTMASK, addrbase + VIA_CRDR_SDINTMASK);1075 msleep(1);1076}1077 1078static int via_sd_probe(struct pci_dev *pcidev,1079 const struct pci_device_id *id)1080{1081 struct mmc_host *mmc;1082 struct via_crdr_mmc_host *sdhost;1083 u32 base, len;1084 u8 gatt;1085 int ret;1086 1087 pr_info(DRV_NAME1088 ": VIA SDMMC controller found at %s [%04x:%04x] (rev %x)\n",1089 pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device,1090 (int)pcidev->revision);1091 1092 ret = pci_enable_device(pcidev);1093 if (ret)1094 return ret;1095 1096 ret = pci_request_regions(pcidev, DRV_NAME);1097 if (ret)1098 goto disable;1099 1100 pci_write_config_byte(pcidev, VIA_CRDR_PCI_WORK_MODE, 0);1101 pci_write_config_byte(pcidev, VIA_CRDR_PCI_DBG_MODE, 0);1102 1103 mmc = mmc_alloc_host(sizeof(struct via_crdr_mmc_host), &pcidev->dev);1104 if (!mmc) {1105 ret = -ENOMEM;1106 goto release;1107 }1108 1109 sdhost = mmc_priv(mmc);1110 sdhost->mmc = mmc;1111 dev_set_drvdata(&pcidev->dev, sdhost);1112 1113 len = pci_resource_len(pcidev, 0);1114 base = pci_resource_start(pcidev, 0);1115 sdhost->mmiobase = ioremap(base, len);1116 if (!sdhost->mmiobase) {1117 ret = -ENOMEM;1118 goto free_mmc_host;1119 }1120 1121 sdhost->sdhc_mmiobase =1122 sdhost->mmiobase + VIA_CRDR_SDC_OFF;1123 sdhost->ddma_mmiobase =1124 sdhost->mmiobase + VIA_CRDR_DDMA_OFF;1125 sdhost->pcictrl_mmiobase =1126 sdhost->mmiobase + VIA_CRDR_PCICTRL_OFF;1127 1128 sdhost->power = MMC_VDD_165_195;1129 1130 gatt = VIA_CRDR_PCICLKGATT_3V3 | VIA_CRDR_PCICLKGATT_PAD_PWRON;1131 writeb(gatt, sdhost->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);1132 via_pwron_sleep(sdhost);1133 gatt |= VIA_CRDR_PCICLKGATT_SFTRST;1134 writeb(gatt, sdhost->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);1135 msleep(3);1136 1137 via_init_mmc_host(sdhost);1138 1139 ret =1140 request_irq(pcidev->irq, via_sdc_isr, IRQF_SHARED, DRV_NAME,1141 sdhost);1142 if (ret)1143 goto unmap;1144 1145 writeb(VIA_CRDR_PCIINTCTRL_SDCIRQEN,1146 sdhost->pcictrl_mmiobase + VIA_CRDR_PCIINTCTRL);1147 writeb(VIA_CRDR_PCITMOCTRL_1024MS,1148 sdhost->pcictrl_mmiobase + VIA_CRDR_PCITMOCTRL);1149 1150 /* device-specific quirks */1151 if (pcidev->subsystem_vendor == PCI_VENDOR_ID_LENOVO &&1152 pcidev->subsystem_device == 0x3891)1153 sdhost->quirks = VIA_CRDR_QUIRK_300MS_PWRDELAY;1154 1155 ret = mmc_add_host(mmc);1156 if (ret)1157 goto unmap;1158 1159 return 0;1160 1161unmap:1162 iounmap(sdhost->mmiobase);1163free_mmc_host:1164 mmc_free_host(mmc);1165release:1166 pci_release_regions(pcidev);1167disable:1168 pci_disable_device(pcidev);1169 1170 return ret;1171}1172 1173static void via_sd_remove(struct pci_dev *pcidev)1174{1175 struct via_crdr_mmc_host *sdhost = pci_get_drvdata(pcidev);1176 unsigned long flags;1177 u8 gatt;1178 1179 spin_lock_irqsave(&sdhost->lock, flags);1180 1181 /* Ensure we don't accept more commands from mmc layer */1182 sdhost->reject = 1;1183 1184 /* Disable generating further interrupts */1185 writeb(0x0, sdhost->pcictrl_mmiobase + VIA_CRDR_PCIINTCTRL);1186 1187 if (sdhost->mrq) {1188 pr_err("%s: Controller removed during "1189 "transfer\n", mmc_hostname(sdhost->mmc));1190 1191 /* make sure all DMA is stopped */1192 writel(VIA_CRDR_DMACTRL_SFTRST,1193 sdhost->ddma_mmiobase + VIA_CRDR_DMACTRL);1194 sdhost->mrq->cmd->error = -ENOMEDIUM;1195 if (sdhost->mrq->stop)1196 sdhost->mrq->stop->error = -ENOMEDIUM;1197 queue_work(system_bh_wq, &sdhost->finish_bh_work);1198 }1199 spin_unlock_irqrestore(&sdhost->lock, flags);1200 1201 mmc_remove_host(sdhost->mmc);1202 1203 free_irq(pcidev->irq, sdhost);1204 1205 del_timer_sync(&sdhost->timer);1206 1207 cancel_work_sync(&sdhost->finish_bh_work);1208 1209 /* switch off power */1210 gatt = readb(sdhost->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);1211 gatt &= ~VIA_CRDR_PCICLKGATT_PAD_PWRON;1212 writeb(gatt, sdhost->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);1213 1214 iounmap(sdhost->mmiobase);1215 mmc_free_host(sdhost->mmc);1216 pci_release_regions(pcidev);1217 pci_disable_device(pcidev);1218 1219 pr_info(DRV_NAME1220 ": VIA SDMMC controller at %s [%04x:%04x] has been removed\n",1221 pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device);1222}1223 1224static void __maybe_unused via_init_sdc_pm(struct via_crdr_mmc_host *host)1225{1226 struct sdhcreg *pm_sdhcreg;1227 void __iomem *addrbase;1228 u32 lenreg;1229 u16 status;1230 1231 pm_sdhcreg = &(host->pm_sdhc_reg);1232 addrbase = host->sdhc_mmiobase;1233 1234 writel(0x0, addrbase + VIA_CRDR_SDINTMASK);1235 1236 lenreg = VIA_CRDR_SDBLKLEN_GPIDET | VIA_CRDR_SDBLKLEN_INTEN;1237 writel(lenreg, addrbase + VIA_CRDR_SDBLKLEN);1238 1239 status = readw(addrbase + VIA_CRDR_SDSTATUS);1240 status &= VIA_CRDR_SDSTS_W1C_MASK;1241 writew(status, addrbase + VIA_CRDR_SDSTATUS);1242 1243 status = readw(addrbase + VIA_CRDR_SDSTATUS2);1244 status |= VIA_CRDR_SDSTS_CFE;1245 writew(status, addrbase + VIA_CRDR_SDSTATUS2);1246 1247 writel(pm_sdhcreg->sdcontrol_reg, addrbase + VIA_CRDR_SDCTRL);1248 writel(pm_sdhcreg->sdcmdarg_reg, addrbase + VIA_CRDR_SDCARG);1249 writel(pm_sdhcreg->sdintmask_reg, addrbase + VIA_CRDR_SDINTMASK);1250 writel(pm_sdhcreg->sdrsptmo_reg, addrbase + VIA_CRDR_SDRSPTMO);1251 writel(pm_sdhcreg->sdclksel_reg, addrbase + VIA_CRDR_SDCLKSEL);1252 writel(pm_sdhcreg->sdextctrl_reg, addrbase + VIA_CRDR_SDEXTCTRL);1253 1254 via_print_pcictrl(host);1255 via_print_sdchc(host);1256}1257 1258static int __maybe_unused via_sd_suspend(struct device *dev)1259{1260 struct via_crdr_mmc_host *host;1261 unsigned long flags;1262 1263 host = dev_get_drvdata(dev);1264 1265 spin_lock_irqsave(&host->lock, flags);1266 via_save_pcictrlreg(host);1267 via_save_sdcreg(host);1268 spin_unlock_irqrestore(&host->lock, flags);1269 1270 device_wakeup_enable(dev);1271 1272 return 0;1273}1274 1275static int __maybe_unused via_sd_resume(struct device *dev)1276{1277 struct via_crdr_mmc_host *sdhost;1278 u8 gatt;1279 1280 sdhost = dev_get_drvdata(dev);1281 1282 gatt = VIA_CRDR_PCICLKGATT_PAD_PWRON;1283 if (sdhost->power == MMC_VDD_165_195)1284 gatt &= ~VIA_CRDR_PCICLKGATT_3V3;1285 else1286 gatt |= VIA_CRDR_PCICLKGATT_3V3;1287 writeb(gatt, sdhost->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);1288 via_pwron_sleep(sdhost);1289 gatt |= VIA_CRDR_PCICLKGATT_SFTRST;1290 writeb(gatt, sdhost->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);1291 msleep(3);1292 1293 msleep(100);1294 1295 via_restore_pcictrlreg(sdhost);1296 via_init_sdc_pm(sdhost);1297 1298 return 0;1299}1300 1301static SIMPLE_DEV_PM_OPS(via_sd_pm_ops, via_sd_suspend, via_sd_resume);1302 1303static struct pci_driver via_sd_driver = {1304 .name = DRV_NAME,1305 .id_table = via_ids,1306 .probe = via_sd_probe,1307 .remove = via_sd_remove,1308 .driver.pm = &via_sd_pm_ops,1309};1310 1311module_pci_driver(via_sd_driver);1312 1313MODULE_LICENSE("GPL");1314MODULE_AUTHOR("VIA Technologies Inc.");1315MODULE_DESCRIPTION("VIA SD/MMC Card Interface driver");1316