Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.30-rc4 734 lines 17 kB view raw
1/* linux/drivers/mmc/host/sdhci-pci.c - SDHCI on PCI bus interface 2 * 3 * Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or (at 8 * your option) any later version. 9 * 10 * Thanks to the following companies for their support: 11 * 12 * - JMicron (hardware and technical support) 13 */ 14 15#include <linux/delay.h> 16#include <linux/highmem.h> 17#include <linux/pci.h> 18#include <linux/dma-mapping.h> 19 20#include <linux/mmc/host.h> 21 22#include <asm/scatterlist.h> 23#include <asm/io.h> 24 25#include "sdhci.h" 26 27/* 28 * PCI registers 29 */ 30 31#define PCI_SDHCI_IFPIO 0x00 32#define PCI_SDHCI_IFDMA 0x01 33#define PCI_SDHCI_IFVENDOR 0x02 34 35#define PCI_SLOT_INFO 0x40 /* 8 bits */ 36#define PCI_SLOT_INFO_SLOTS(x) ((x >> 4) & 7) 37#define PCI_SLOT_INFO_FIRST_BAR_MASK 0x07 38 39#define MAX_SLOTS 8 40 41struct sdhci_pci_chip; 42struct sdhci_pci_slot; 43 44struct sdhci_pci_fixes { 45 unsigned int quirks; 46 47 int (*probe)(struct sdhci_pci_chip*); 48 49 int (*probe_slot)(struct sdhci_pci_slot*); 50 void (*remove_slot)(struct sdhci_pci_slot*, int); 51 52 int (*suspend)(struct sdhci_pci_chip*, 53 pm_message_t); 54 int (*resume)(struct sdhci_pci_chip*); 55}; 56 57struct sdhci_pci_slot { 58 struct sdhci_pci_chip *chip; 59 struct sdhci_host *host; 60 61 int pci_bar; 62}; 63 64struct sdhci_pci_chip { 65 struct pci_dev *pdev; 66 67 unsigned int quirks; 68 const struct sdhci_pci_fixes *fixes; 69 70 int num_slots; /* Slots on controller */ 71 struct sdhci_pci_slot *slots[MAX_SLOTS]; /* Pointers to host slots */ 72}; 73 74 75/*****************************************************************************\ 76 * * 77 * Hardware specific quirk handling * 78 * * 79\*****************************************************************************/ 80 81static int ricoh_probe(struct sdhci_pci_chip *chip) 82{ 83 if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) 84 chip->quirks |= SDHCI_QUIRK_CLOCK_BEFORE_RESET; 85 86 if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG) 87 chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET; 88 89 return 0; 90} 91 92static const struct sdhci_pci_fixes sdhci_ricoh = { 93 .probe = ricoh_probe, 94 .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR, 95}; 96 97static const struct sdhci_pci_fixes sdhci_ene_712 = { 98 .quirks = SDHCI_QUIRK_SINGLE_POWER_WRITE | 99 SDHCI_QUIRK_BROKEN_DMA, 100}; 101 102static const struct sdhci_pci_fixes sdhci_ene_714 = { 103 .quirks = SDHCI_QUIRK_SINGLE_POWER_WRITE | 104 SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS | 105 SDHCI_QUIRK_BROKEN_DMA, 106}; 107 108static const struct sdhci_pci_fixes sdhci_cafe = { 109 .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER | 110 SDHCI_QUIRK_NO_BUSY_IRQ | 111 SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, 112}; 113 114static int jmicron_pmos(struct sdhci_pci_chip *chip, int on) 115{ 116 u8 scratch; 117 int ret; 118 119 ret = pci_read_config_byte(chip->pdev, 0xAE, &scratch); 120 if (ret) 121 return ret; 122 123 /* 124 * Turn PMOS on [bit 0], set over current detection to 2.4 V 125 * [bit 1:2] and enable over current debouncing [bit 6]. 126 */ 127 if (on) 128 scratch |= 0x47; 129 else 130 scratch &= ~0x47; 131 132 ret = pci_write_config_byte(chip->pdev, 0xAE, scratch); 133 if (ret) 134 return ret; 135 136 return 0; 137} 138 139static int jmicron_probe(struct sdhci_pci_chip *chip) 140{ 141 int ret; 142 143 if (chip->pdev->revision == 0) { 144 chip->quirks |= SDHCI_QUIRK_32BIT_DMA_ADDR | 145 SDHCI_QUIRK_32BIT_DMA_SIZE | 146 SDHCI_QUIRK_32BIT_ADMA_SIZE | 147 SDHCI_QUIRK_RESET_AFTER_REQUEST | 148 SDHCI_QUIRK_BROKEN_SMALL_PIO; 149 } 150 151 /* 152 * JMicron chips can have two interfaces to the same hardware 153 * in order to work around limitations in Microsoft's driver. 154 * We need to make sure we only bind to one of them. 155 * 156 * This code assumes two things: 157 * 158 * 1. The PCI code adds subfunctions in order. 159 * 160 * 2. The MMC interface has a lower subfunction number 161 * than the SD interface. 162 */ 163 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_SD) { 164 struct pci_dev *sd_dev; 165 166 sd_dev = NULL; 167 while ((sd_dev = pci_get_device(PCI_VENDOR_ID_JMICRON, 168 PCI_DEVICE_ID_JMICRON_JMB38X_MMC, sd_dev)) != NULL) { 169 if ((PCI_SLOT(chip->pdev->devfn) == 170 PCI_SLOT(sd_dev->devfn)) && 171 (chip->pdev->bus == sd_dev->bus)) 172 break; 173 } 174 175 if (sd_dev) { 176 pci_dev_put(sd_dev); 177 dev_info(&chip->pdev->dev, "Refusing to bind to " 178 "secondary interface.\n"); 179 return -ENODEV; 180 } 181 } 182 183 /* 184 * JMicron chips need a bit of a nudge to enable the power 185 * output pins. 186 */ 187 ret = jmicron_pmos(chip, 1); 188 if (ret) { 189 dev_err(&chip->pdev->dev, "Failure enabling card power\n"); 190 return ret; 191 } 192 193 return 0; 194} 195 196static void jmicron_enable_mmc(struct sdhci_host *host, int on) 197{ 198 u8 scratch; 199 200 scratch = readb(host->ioaddr + 0xC0); 201 202 if (on) 203 scratch |= 0x01; 204 else 205 scratch &= ~0x01; 206 207 writeb(scratch, host->ioaddr + 0xC0); 208} 209 210static int jmicron_probe_slot(struct sdhci_pci_slot *slot) 211{ 212 if (slot->chip->pdev->revision == 0) { 213 u16 version; 214 215 version = readl(slot->host->ioaddr + SDHCI_HOST_VERSION); 216 version = (version & SDHCI_VENDOR_VER_MASK) >> 217 SDHCI_VENDOR_VER_SHIFT; 218 219 /* 220 * Older versions of the chip have lots of nasty glitches 221 * in the ADMA engine. It's best just to avoid it 222 * completely. 223 */ 224 if (version < 0xAC) 225 slot->host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; 226 } 227 228 /* 229 * The secondary interface requires a bit set to get the 230 * interrupts. 231 */ 232 if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC) 233 jmicron_enable_mmc(slot->host, 1); 234 235 return 0; 236} 237 238static void jmicron_remove_slot(struct sdhci_pci_slot *slot, int dead) 239{ 240 if (dead) 241 return; 242 243 if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC) 244 jmicron_enable_mmc(slot->host, 0); 245} 246 247static int jmicron_suspend(struct sdhci_pci_chip *chip, pm_message_t state) 248{ 249 int i; 250 251 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC) { 252 for (i = 0;i < chip->num_slots;i++) 253 jmicron_enable_mmc(chip->slots[i]->host, 0); 254 } 255 256 return 0; 257} 258 259static int jmicron_resume(struct sdhci_pci_chip *chip) 260{ 261 int ret, i; 262 263 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC) { 264 for (i = 0;i < chip->num_slots;i++) 265 jmicron_enable_mmc(chip->slots[i]->host, 1); 266 } 267 268 ret = jmicron_pmos(chip, 1); 269 if (ret) { 270 dev_err(&chip->pdev->dev, "Failure enabling card power\n"); 271 return ret; 272 } 273 274 return 0; 275} 276 277static const struct sdhci_pci_fixes sdhci_jmicron = { 278 .probe = jmicron_probe, 279 280 .probe_slot = jmicron_probe_slot, 281 .remove_slot = jmicron_remove_slot, 282 283 .suspend = jmicron_suspend, 284 .resume = jmicron_resume, 285}; 286 287static const struct pci_device_id pci_ids[] __devinitdata = { 288 { 289 .vendor = PCI_VENDOR_ID_RICOH, 290 .device = PCI_DEVICE_ID_RICOH_R5C822, 291 .subvendor = PCI_ANY_ID, 292 .subdevice = PCI_ANY_ID, 293 .driver_data = (kernel_ulong_t)&sdhci_ricoh, 294 }, 295 296 { 297 .vendor = PCI_VENDOR_ID_ENE, 298 .device = PCI_DEVICE_ID_ENE_CB712_SD, 299 .subvendor = PCI_ANY_ID, 300 .subdevice = PCI_ANY_ID, 301 .driver_data = (kernel_ulong_t)&sdhci_ene_712, 302 }, 303 304 { 305 .vendor = PCI_VENDOR_ID_ENE, 306 .device = PCI_DEVICE_ID_ENE_CB712_SD_2, 307 .subvendor = PCI_ANY_ID, 308 .subdevice = PCI_ANY_ID, 309 .driver_data = (kernel_ulong_t)&sdhci_ene_712, 310 }, 311 312 { 313 .vendor = PCI_VENDOR_ID_ENE, 314 .device = PCI_DEVICE_ID_ENE_CB714_SD, 315 .subvendor = PCI_ANY_ID, 316 .subdevice = PCI_ANY_ID, 317 .driver_data = (kernel_ulong_t)&sdhci_ene_714, 318 }, 319 320 { 321 .vendor = PCI_VENDOR_ID_ENE, 322 .device = PCI_DEVICE_ID_ENE_CB714_SD_2, 323 .subvendor = PCI_ANY_ID, 324 .subdevice = PCI_ANY_ID, 325 .driver_data = (kernel_ulong_t)&sdhci_ene_714, 326 }, 327 328 { 329 .vendor = PCI_VENDOR_ID_MARVELL, 330 .device = PCI_DEVICE_ID_MARVELL_88ALP01_SD, 331 .subvendor = PCI_ANY_ID, 332 .subdevice = PCI_ANY_ID, 333 .driver_data = (kernel_ulong_t)&sdhci_cafe, 334 }, 335 336 { 337 .vendor = PCI_VENDOR_ID_JMICRON, 338 .device = PCI_DEVICE_ID_JMICRON_JMB38X_SD, 339 .subvendor = PCI_ANY_ID, 340 .subdevice = PCI_ANY_ID, 341 .driver_data = (kernel_ulong_t)&sdhci_jmicron, 342 }, 343 344 { 345 .vendor = PCI_VENDOR_ID_JMICRON, 346 .device = PCI_DEVICE_ID_JMICRON_JMB38X_MMC, 347 .subvendor = PCI_ANY_ID, 348 .subdevice = PCI_ANY_ID, 349 .driver_data = (kernel_ulong_t)&sdhci_jmicron, 350 }, 351 352 { /* Generic SD host controller */ 353 PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) 354 }, 355 356 { /* end: all zeroes */ }, 357}; 358 359MODULE_DEVICE_TABLE(pci, pci_ids); 360 361/*****************************************************************************\ 362 * * 363 * SDHCI core callbacks * 364 * * 365\*****************************************************************************/ 366 367static int sdhci_pci_enable_dma(struct sdhci_host *host) 368{ 369 struct sdhci_pci_slot *slot; 370 struct pci_dev *pdev; 371 int ret; 372 373 slot = sdhci_priv(host); 374 pdev = slot->chip->pdev; 375 376 if (((pdev->class & 0xFFFF00) == (PCI_CLASS_SYSTEM_SDHCI << 8)) && 377 ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) && 378 (host->flags & SDHCI_USE_DMA)) { 379 dev_warn(&pdev->dev, "Will use DMA mode even though HW " 380 "doesn't fully claim to support it.\n"); 381 } 382 383 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); 384 if (ret) 385 return ret; 386 387 pci_set_master(pdev); 388 389 return 0; 390} 391 392static struct sdhci_ops sdhci_pci_ops = { 393 .enable_dma = sdhci_pci_enable_dma, 394}; 395 396/*****************************************************************************\ 397 * * 398 * Suspend/resume * 399 * * 400\*****************************************************************************/ 401 402#ifdef CONFIG_PM 403 404static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) 405{ 406 struct sdhci_pci_chip *chip; 407 struct sdhci_pci_slot *slot; 408 int i, ret; 409 410 chip = pci_get_drvdata(pdev); 411 if (!chip) 412 return 0; 413 414 for (i = 0;i < chip->num_slots;i++) { 415 slot = chip->slots[i]; 416 if (!slot) 417 continue; 418 419 ret = sdhci_suspend_host(slot->host, state); 420 421 if (ret) { 422 for (i--;i >= 0;i--) 423 sdhci_resume_host(chip->slots[i]->host); 424 return ret; 425 } 426 } 427 428 if (chip->fixes && chip->fixes->suspend) { 429 ret = chip->fixes->suspend(chip, state); 430 if (ret) { 431 for (i = chip->num_slots - 1;i >= 0;i--) 432 sdhci_resume_host(chip->slots[i]->host); 433 return ret; 434 } 435 } 436 437 pci_save_state(pdev); 438 pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); 439 pci_disable_device(pdev); 440 pci_set_power_state(pdev, pci_choose_state(pdev, state)); 441 442 return 0; 443} 444 445static int sdhci_pci_resume (struct pci_dev *pdev) 446{ 447 struct sdhci_pci_chip *chip; 448 struct sdhci_pci_slot *slot; 449 int i, ret; 450 451 chip = pci_get_drvdata(pdev); 452 if (!chip) 453 return 0; 454 455 pci_set_power_state(pdev, PCI_D0); 456 pci_restore_state(pdev); 457 ret = pci_enable_device(pdev); 458 if (ret) 459 return ret; 460 461 if (chip->fixes && chip->fixes->resume) { 462 ret = chip->fixes->resume(chip); 463 if (ret) 464 return ret; 465 } 466 467 for (i = 0;i < chip->num_slots;i++) { 468 slot = chip->slots[i]; 469 if (!slot) 470 continue; 471 472 ret = sdhci_resume_host(slot->host); 473 if (ret) 474 return ret; 475 } 476 477 return 0; 478} 479 480#else /* CONFIG_PM */ 481 482#define sdhci_pci_suspend NULL 483#define sdhci_pci_resume NULL 484 485#endif /* CONFIG_PM */ 486 487/*****************************************************************************\ 488 * * 489 * Device probing/removal * 490 * * 491\*****************************************************************************/ 492 493static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( 494 struct pci_dev *pdev, struct sdhci_pci_chip *chip, int bar) 495{ 496 struct sdhci_pci_slot *slot; 497 struct sdhci_host *host; 498 499 resource_size_t addr; 500 501 int ret; 502 503 if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { 504 dev_err(&pdev->dev, "BAR %d is not iomem. Aborting.\n", bar); 505 return ERR_PTR(-ENODEV); 506 } 507 508 if (pci_resource_len(pdev, bar) != 0x100) { 509 dev_err(&pdev->dev, "Invalid iomem size. You may " 510 "experience problems.\n"); 511 } 512 513 if ((pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) { 514 dev_err(&pdev->dev, "Vendor specific interface. Aborting.\n"); 515 return ERR_PTR(-ENODEV); 516 } 517 518 if ((pdev->class & 0x0000FF) > PCI_SDHCI_IFVENDOR) { 519 dev_err(&pdev->dev, "Unknown interface. Aborting.\n"); 520 return ERR_PTR(-ENODEV); 521 } 522 523 host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_pci_slot)); 524 if (IS_ERR(host)) { 525 ret = PTR_ERR(host); 526 goto unmap; 527 } 528 529 slot = sdhci_priv(host); 530 531 slot->chip = chip; 532 slot->host = host; 533 slot->pci_bar = bar; 534 535 host->hw_name = "PCI"; 536 host->ops = &sdhci_pci_ops; 537 host->quirks = chip->quirks; 538 539 host->irq = pdev->irq; 540 541 ret = pci_request_region(pdev, bar, mmc_hostname(host->mmc)); 542 if (ret) { 543 dev_err(&pdev->dev, "cannot request region\n"); 544 return ERR_PTR(ret); 545 } 546 547 addr = pci_resource_start(pdev, bar); 548 host->ioaddr = pci_ioremap_bar(pdev, bar); 549 if (!host->ioaddr) { 550 dev_err(&pdev->dev, "failed to remap registers\n"); 551 goto release; 552 } 553 554 if (chip->fixes && chip->fixes->probe_slot) { 555 ret = chip->fixes->probe_slot(slot); 556 if (ret) 557 goto unmap; 558 } 559 560 ret = sdhci_add_host(host); 561 if (ret) 562 goto remove; 563 564 return slot; 565 566remove: 567 if (chip->fixes && chip->fixes->remove_slot) 568 chip->fixes->remove_slot(slot, 0); 569 570unmap: 571 iounmap(host->ioaddr); 572 573release: 574 pci_release_region(pdev, bar); 575 sdhci_free_host(host); 576 577 return ERR_PTR(ret); 578} 579 580static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot) 581{ 582 int dead; 583 u32 scratch; 584 585 dead = 0; 586 scratch = readl(slot->host->ioaddr + SDHCI_INT_STATUS); 587 if (scratch == (u32)-1) 588 dead = 1; 589 590 sdhci_remove_host(slot->host, dead); 591 592 if (slot->chip->fixes && slot->chip->fixes->remove_slot) 593 slot->chip->fixes->remove_slot(slot, dead); 594 595 pci_release_region(slot->chip->pdev, slot->pci_bar); 596 597 sdhci_free_host(slot->host); 598} 599 600static int __devinit sdhci_pci_probe(struct pci_dev *pdev, 601 const struct pci_device_id *ent) 602{ 603 struct sdhci_pci_chip *chip; 604 struct sdhci_pci_slot *slot; 605 606 u8 slots, rev, first_bar; 607 int ret, i; 608 609 BUG_ON(pdev == NULL); 610 BUG_ON(ent == NULL); 611 612 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev); 613 614 dev_info(&pdev->dev, "SDHCI controller found [%04x:%04x] (rev %x)\n", 615 (int)pdev->vendor, (int)pdev->device, (int)rev); 616 617 ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots); 618 if (ret) 619 return ret; 620 621 slots = PCI_SLOT_INFO_SLOTS(slots) + 1; 622 dev_dbg(&pdev->dev, "found %d slot(s)\n", slots); 623 if (slots == 0) 624 return -ENODEV; 625 626 BUG_ON(slots > MAX_SLOTS); 627 628 ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar); 629 if (ret) 630 return ret; 631 632 first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK; 633 634 if (first_bar > 5) { 635 dev_err(&pdev->dev, "Invalid first BAR. Aborting.\n"); 636 return -ENODEV; 637 } 638 639 ret = pci_enable_device(pdev); 640 if (ret) 641 return ret; 642 643 chip = kzalloc(sizeof(struct sdhci_pci_chip), GFP_KERNEL); 644 if (!chip) { 645 ret = -ENOMEM; 646 goto err; 647 } 648 649 chip->pdev = pdev; 650 chip->fixes = (const struct sdhci_pci_fixes*)ent->driver_data; 651 if (chip->fixes) 652 chip->quirks = chip->fixes->quirks; 653 chip->num_slots = slots; 654 655 pci_set_drvdata(pdev, chip); 656 657 if (chip->fixes && chip->fixes->probe) { 658 ret = chip->fixes->probe(chip); 659 if (ret) 660 goto free; 661 } 662 663 for (i = 0;i < slots;i++) { 664 slot = sdhci_pci_probe_slot(pdev, chip, first_bar + i); 665 if (IS_ERR(slot)) { 666 for (i--;i >= 0;i--) 667 sdhci_pci_remove_slot(chip->slots[i]); 668 ret = PTR_ERR(slot); 669 goto free; 670 } 671 672 chip->slots[i] = slot; 673 } 674 675 return 0; 676 677free: 678 pci_set_drvdata(pdev, NULL); 679 kfree(chip); 680 681err: 682 pci_disable_device(pdev); 683 return ret; 684} 685 686static void __devexit sdhci_pci_remove(struct pci_dev *pdev) 687{ 688 int i; 689 struct sdhci_pci_chip *chip; 690 691 chip = pci_get_drvdata(pdev); 692 693 if (chip) { 694 for (i = 0;i < chip->num_slots; i++) 695 sdhci_pci_remove_slot(chip->slots[i]); 696 697 pci_set_drvdata(pdev, NULL); 698 kfree(chip); 699 } 700 701 pci_disable_device(pdev); 702} 703 704static struct pci_driver sdhci_driver = { 705 .name = "sdhci-pci", 706 .id_table = pci_ids, 707 .probe = sdhci_pci_probe, 708 .remove = __devexit_p(sdhci_pci_remove), 709 .suspend = sdhci_pci_suspend, 710 .resume = sdhci_pci_resume, 711}; 712 713/*****************************************************************************\ 714 * * 715 * Driver init/exit * 716 * * 717\*****************************************************************************/ 718 719static int __init sdhci_drv_init(void) 720{ 721 return pci_register_driver(&sdhci_driver); 722} 723 724static void __exit sdhci_drv_exit(void) 725{ 726 pci_unregister_driver(&sdhci_driver); 727} 728 729module_init(sdhci_drv_init); 730module_exit(sdhci_drv_exit); 731 732MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>"); 733MODULE_DESCRIPTION("Secure Digital Host Controller Interface PCI driver"); 734MODULE_LICENSE("GPL");