Commit 5b39dba5 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc:
  mmc: extend ricoh_mmc to support Ricoh RL5c476
  at91_mci: use generic GPIO calls
  sdhci: add num index for multi controllers case
  MAINTAINERS: remove non-existant URLs
  mmc: remove sdhci and mmc_spi experimental markers
  mmc: Handle suspend/resume in Ricoh MMC disabler
parents 11eb3b0d 882c4916
...@@ -2682,7 +2682,6 @@ MOTOROLA IMX MMC/SD HOST CONTROLLER INTERFACE DRIVER ...@@ -2682,7 +2682,6 @@ MOTOROLA IMX MMC/SD HOST CONTROLLER INTERFACE DRIVER
P: Pavel Pisa P: Pavel Pisa
M: ppisa@pikron.com M: ppisa@pikron.com
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
W: http://mmc.drzeus.cx/wiki/Controllers/Freescale/SDHC
S: Maintained S: Maintained
MOUSE AND MISC DEVICES [GENERAL] MOUSE AND MISC DEVICES [GENERAL]
...@@ -3716,7 +3715,6 @@ SECURE DIGITAL HOST CONTROLLER INTERFACE DRIVER ...@@ -3716,7 +3715,6 @@ SECURE DIGITAL HOST CONTROLLER INTERFACE DRIVER
P: Pierre Ossman P: Pierre Ossman
M: drzeus-sdhci@drzeus.cx M: drzeus-sdhci@drzeus.cx
L: sdhci-devel@list.drzeus.cx L: sdhci-devel@list.drzeus.cx
W: http://mmc.drzeus.cx/wiki/Linux/Drivers/sdhci
S: Maintained S: Maintained
SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS
...@@ -4286,7 +4284,6 @@ W83L51xD SD/MMC CARD INTERFACE DRIVER ...@@ -4286,7 +4284,6 @@ W83L51xD SD/MMC CARD INTERFACE DRIVER
P: Pierre Ossman P: Pierre Ossman
M: drzeus-wbsd@drzeus.cx M: drzeus-wbsd@drzeus.cx
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
W: http://projects.drzeus.cx/wbsd
S: Maintained S: Maintained
WATCHDOG DEVICE DRIVERS WATCHDOG DEVICE DRIVERS
......
...@@ -25,8 +25,8 @@ config MMC_PXA ...@@ -25,8 +25,8 @@ config MMC_PXA
If unsure, say N. If unsure, say N.
config MMC_SDHCI config MMC_SDHCI
tristate "Secure Digital Host Controller Interface support (EXPERIMENTAL)" tristate "Secure Digital Host Controller Interface support"
depends on PCI && EXPERIMENTAL depends on PCI
help help
This select the generic Secure Digital Host Controller Interface. This select the generic Secure Digital Host Controller Interface.
It is used by manufacturers such as Texas Instruments(R), Ricoh(R) It is used by manufacturers such as Texas Instruments(R), Ricoh(R)
...@@ -118,8 +118,8 @@ config MMC_TIFM_SD ...@@ -118,8 +118,8 @@ config MMC_TIFM_SD
module will be called tifm_sd. module will be called tifm_sd.
config MMC_SPI config MMC_SPI
tristate "MMC/SD over SPI (EXPERIMENTAL)" tristate "MMC/SD over SPI"
depends on MMC && SPI_MASTER && !HIGHMEM && EXPERIMENTAL depends on MMC && SPI_MASTER && !HIGHMEM
select CRC7 select CRC7
select CRC_ITU_T select CRC_ITU_T
help help
......
...@@ -70,10 +70,11 @@ ...@@ -70,10 +70,11 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/gpio.h>
#include <asm/mach/mmc.h> #include <asm/mach/mmc.h>
#include <asm/arch/board.h> #include <asm/arch/board.h>
#include <asm/arch/cpu.h> #include <asm/arch/cpu.h>
#include <asm/arch/gpio.h>
#include <asm/arch/at91_mci.h> #include <asm/arch/at91_mci.h>
#define DRIVER_NAME "at91_mci" #define DRIVER_NAME "at91_mci"
...@@ -659,11 +660,11 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ...@@ -659,11 +660,11 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (host->board->vcc_pin) { if (host->board->vcc_pin) {
switch (ios->power_mode) { switch (ios->power_mode) {
case MMC_POWER_OFF: case MMC_POWER_OFF:
at91_set_gpio_value(host->board->vcc_pin, 0); gpio_set_value(host->board->vcc_pin, 0);
break; break;
case MMC_POWER_UP: case MMC_POWER_UP:
case MMC_POWER_ON: case MMC_POWER_ON:
at91_set_gpio_value(host->board->vcc_pin, 1); gpio_set_value(host->board->vcc_pin, 1);
break; break;
} }
} }
...@@ -768,7 +769,7 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) ...@@ -768,7 +769,7 @@ static irqreturn_t at91_mci_irq(int irq, void *devid)
static irqreturn_t at91_mmc_det_irq(int irq, void *_host) static irqreturn_t at91_mmc_det_irq(int irq, void *_host)
{ {
struct at91mci_host *host = _host; struct at91mci_host *host = _host;
int present = !at91_get_gpio_value(irq); int present = !gpio_get_value(irq_to_gpio(irq));
/* /*
* we expect this irq on both insert and remove, * we expect this irq on both insert and remove,
...@@ -793,7 +794,7 @@ static int at91_mci_get_ro(struct mmc_host *mmc) ...@@ -793,7 +794,7 @@ static int at91_mci_get_ro(struct mmc_host *mmc)
struct at91mci_host *host = mmc_priv(mmc); struct at91mci_host *host = mmc_priv(mmc);
if (host->board->wp_pin) { if (host->board->wp_pin) {
read_only = at91_get_gpio_value(host->board->wp_pin); read_only = gpio_get_value(host->board->wp_pin);
printk(KERN_WARNING "%s: card is %s\n", mmc_hostname(mmc), printk(KERN_WARNING "%s: card is %s\n", mmc_hostname(mmc),
(read_only ? "read-only" : "read-write") ); (read_only ? "read-only" : "read-write") );
} }
...@@ -820,8 +821,6 @@ static int __init at91_mci_probe(struct platform_device *pdev) ...@@ -820,8 +821,6 @@ static int __init at91_mci_probe(struct platform_device *pdev)
struct resource *res; struct resource *res;
int ret; int ret;
pr_debug("Probe MCI devices\n");
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) if (!res)
return -ENXIO; return -ENXIO;
...@@ -831,9 +830,9 @@ static int __init at91_mci_probe(struct platform_device *pdev) ...@@ -831,9 +830,9 @@ static int __init at91_mci_probe(struct platform_device *pdev)
mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev); mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev);
if (!mmc) { if (!mmc) {
pr_debug("Failed to allocate mmc host\n"); ret = -ENOMEM;
release_mem_region(res->start, res->end - res->start + 1); dev_dbg(&pdev->dev, "couldn't allocate mmc host\n");
return -ENOMEM; goto fail6;
} }
mmc->ops = &at91_mci_ops; mmc->ops = &at91_mci_ops;
...@@ -853,19 +852,44 @@ static int __init at91_mci_probe(struct platform_device *pdev) ...@@ -853,19 +852,44 @@ static int __init at91_mci_probe(struct platform_device *pdev)
if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
mmc->caps |= MMC_CAP_4_BIT_DATA; mmc->caps |= MMC_CAP_4_BIT_DATA;
else else
printk("AT91 MMC: 4 wire bus mode not supported" dev_warn(&pdev->dev, "4 wire bus mode not supported"
" - using 1 wire\n"); " - using 1 wire\n");
} }
/*
* Reserve GPIOs ... board init code makes sure these pins are set
* up as GPIOs with the right direction (input, except for vcc)
*/
if (host->board->det_pin) {
ret = gpio_request(host->board->det_pin, "mmc_detect");
if (ret < 0) {
dev_dbg(&pdev->dev, "couldn't claim card detect pin\n");
goto fail5;
}
}
if (host->board->wp_pin) {
ret = gpio_request(host->board->wp_pin, "mmc_wp");
if (ret < 0) {
dev_dbg(&pdev->dev, "couldn't claim wp sense pin\n");
goto fail4;
}
}
if (host->board->vcc_pin) {
ret = gpio_request(host->board->vcc_pin, "mmc_vcc");
if (ret < 0) {
dev_dbg(&pdev->dev, "couldn't claim vcc switch pin\n");
goto fail3;
}
}
/* /*
* Get Clock * Get Clock
*/ */
host->mci_clk = clk_get(&pdev->dev, "mci_clk"); host->mci_clk = clk_get(&pdev->dev, "mci_clk");
if (IS_ERR(host->mci_clk)) { if (IS_ERR(host->mci_clk)) {
printk(KERN_ERR "AT91 MMC: no clock defined.\n"); ret = -ENODEV;
mmc_free_host(mmc); dev_dbg(&pdev->dev, "no mci_clk?\n");
release_mem_region(res->start, res->end - res->start + 1); goto fail2;
return -ENODEV;
} }
/* /*
...@@ -873,10 +897,8 @@ static int __init at91_mci_probe(struct platform_device *pdev) ...@@ -873,10 +897,8 @@ static int __init at91_mci_probe(struct platform_device *pdev)
*/ */
host->baseaddr = ioremap(res->start, res->end - res->start + 1); host->baseaddr = ioremap(res->start, res->end - res->start + 1);
if (!host->baseaddr) { if (!host->baseaddr) {
clk_put(host->mci_clk); ret = -ENOMEM;
mmc_free_host(mmc); goto fail1;
release_mem_region(res->start, res->end - res->start + 1);
return -ENOMEM;
} }
/* /*
...@@ -890,15 +912,11 @@ static int __init at91_mci_probe(struct platform_device *pdev) ...@@ -890,15 +912,11 @@ static int __init at91_mci_probe(struct platform_device *pdev)
* Allocate the MCI interrupt * Allocate the MCI interrupt
*/ */
host->irq = platform_get_irq(pdev, 0); host->irq = platform_get_irq(pdev, 0);
ret = request_irq(host->irq, at91_mci_irq, IRQF_SHARED, DRIVER_NAME, host); ret = request_irq(host->irq, at91_mci_irq, IRQF_SHARED,
mmc_hostname(mmc), host);
if (ret) { if (ret) {
printk(KERN_ERR "AT91 MMC: Failed to request MCI interrupt\n"); dev_dbg(&pdev->dev, "request MCI interrupt failed\n");
clk_disable(host->mci_clk); goto fail0;
clk_put(host->mci_clk);
mmc_free_host(mmc);
iounmap(host->baseaddr);
release_mem_region(res->start, res->end - res->start + 1);
return ret;
} }
platform_set_drvdata(pdev, mmc); platform_set_drvdata(pdev, mmc);
...@@ -907,8 +925,7 @@ static int __init at91_mci_probe(struct platform_device *pdev) ...@@ -907,8 +925,7 @@ static int __init at91_mci_probe(struct platform_device *pdev)
* Add host to MMC layer * Add host to MMC layer
*/ */
if (host->board->det_pin) { if (host->board->det_pin) {
host->present = !at91_get_gpio_value(host->board->det_pin); host->present = !gpio_get_value(host->board->det_pin);
device_init_wakeup(&pdev->dev, 1);
} }
else else
host->present = -1; host->present = -1;
...@@ -919,15 +936,38 @@ static int __init at91_mci_probe(struct platform_device *pdev) ...@@ -919,15 +936,38 @@ static int __init at91_mci_probe(struct platform_device *pdev)
* monitor card insertion/removal if we can * monitor card insertion/removal if we can
*/ */
if (host->board->det_pin) { if (host->board->det_pin) {
ret = request_irq(host->board->det_pin, at91_mmc_det_irq, ret = request_irq(gpio_to_irq(host->board->det_pin),
0, DRIVER_NAME, host); at91_mmc_det_irq, 0, mmc_hostname(mmc), host);
if (ret) if (ret)
printk(KERN_ERR "AT91 MMC: Couldn't allocate MMC detect irq\n"); dev_warn(&pdev->dev, "request MMC detect irq failed\n");
else
device_init_wakeup(&pdev->dev, 1);
} }
pr_debug("Added MCI driver\n"); pr_debug("Added MCI driver\n");
return 0; return 0;
fail0:
clk_disable(host->mci_clk);
iounmap(host->baseaddr);
fail1:
clk_put(host->mci_clk);
fail2:
if (host->board->vcc_pin)
gpio_free(host->board->vcc_pin);
fail3:
if (host->board->wp_pin)
gpio_free(host->board->wp_pin);
fail4:
if (host->board->det_pin)
gpio_free(host->board->det_pin);
fail5:
mmc_free_host(mmc);
fail6:
release_mem_region(res->start, res->end - res->start + 1);
dev_err(&pdev->dev, "probe failed, err %d\n", ret);
return ret;
} }
/* /*
...@@ -945,9 +985,10 @@ static int __exit at91_mci_remove(struct platform_device *pdev) ...@@ -945,9 +985,10 @@ static int __exit at91_mci_remove(struct platform_device *pdev)
host = mmc_priv(mmc); host = mmc_priv(mmc);
if (host->board->det_pin) { if (host->board->det_pin) {
if (device_can_wakeup(&pdev->dev))
free_irq(gpio_to_irq(host->board->det_pin), host);
device_init_wakeup(&pdev->dev, 0); device_init_wakeup(&pdev->dev, 0);
free_irq(host->board->det_pin, host); gpio_free(host->board->det_pin);
cancel_delayed_work(&host->mmc->detect);
} }
at91_mci_disable(host); at91_mci_disable(host);
...@@ -957,6 +998,11 @@ static int __exit at91_mci_remove(struct platform_device *pdev) ...@@ -957,6 +998,11 @@ static int __exit at91_mci_remove(struct platform_device *pdev)
clk_disable(host->mci_clk); /* Disable the peripheral clock */ clk_disable(host->mci_clk); /* Disable the peripheral clock */
clk_put(host->mci_clk); clk_put(host->mci_clk);
if (host->board->vcc_pin)
gpio_free(host->board->vcc_pin);
if (host->board->wp_pin)
gpio_free(host->board->wp_pin);
iounmap(host->baseaddr); iounmap(host->baseaddr);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(res->start, res->end - res->start + 1); release_mem_region(res->start, res->end - res->start + 1);
......
...@@ -41,10 +41,91 @@ static const struct pci_device_id pci_ids[] __devinitdata = { ...@@ -41,10 +41,91 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, pci_ids); MODULE_DEVICE_TABLE(pci, pci_ids);
static int ricoh_mmc_disable(struct pci_dev *fw_dev)
{
u8 write_enable;
u8 write_target;
u8 disable;
if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) {
/* via RL5C476 */
pci_read_config_byte(fw_dev, 0xB7, &disable);
if (disable & 0x02) {
printk(KERN_INFO DRIVER_NAME
": Controller already disabled. " \
"Nothing to do.\n");
return -ENODEV;
}
pci_read_config_byte(fw_dev, 0x8E, &write_enable);
pci_write_config_byte(fw_dev, 0x8E, 0xAA);
pci_read_config_byte(fw_dev, 0x8D, &write_target);
pci_write_config_byte(fw_dev, 0x8D, 0xB7);
pci_write_config_byte(fw_dev, 0xB7, disable | 0x02);
pci_write_config_byte(fw_dev, 0x8E, write_enable);
pci_write_config_byte(fw_dev, 0x8D, write_target);
} else {
/* via R5C832 */
pci_read_config_byte(fw_dev, 0xCB, &disable);
if (disable & 0x02) {
printk(KERN_INFO DRIVER_NAME
": Controller already disabled. " \
"Nothing to do.\n");
return -ENODEV;
}
pci_read_config_byte(fw_dev, 0xCA, &write_enable);
pci_write_config_byte(fw_dev, 0xCA, 0x57);
pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
pci_write_config_byte(fw_dev, 0xCA, write_enable);
}
printk(KERN_INFO DRIVER_NAME
": Controller is now disabled.\n");
return 0;
}
static int ricoh_mmc_enable(struct pci_dev *fw_dev)
{
u8 write_enable;
u8 write_target;
u8 disable;
if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) {
/* via RL5C476 */
pci_read_config_byte(fw_dev, 0x8E, &write_enable);
pci_write_config_byte(fw_dev, 0x8E, 0xAA);
pci_read_config_byte(fw_dev, 0x8D, &write_target);
pci_write_config_byte(fw_dev, 0x8D, 0xB7);
pci_read_config_byte(fw_dev, 0xB7, &disable);
pci_write_config_byte(fw_dev, 0xB7, disable & ~0x02);
pci_write_config_byte(fw_dev, 0x8E, write_enable);
pci_write_config_byte(fw_dev, 0x8D, write_target);
} else {
/* via R5C832 */
pci_read_config_byte(fw_dev, 0xCA, &write_enable);
pci_read_config_byte(fw_dev, 0xCB, &disable);
pci_write_config_byte(fw_dev, 0xCA, 0x57);
pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
pci_write_config_byte(fw_dev, 0xCA, write_enable);
}
printk(KERN_INFO DRIVER_NAME
": Controller is now re-enabled.\n");
return 0;
}
static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
u8 rev; u8 rev;
u8 ctrlfound = 0;
struct pci_dev *fw_dev = NULL; struct pci_dev *fw_dev = NULL;
...@@ -58,34 +139,38 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, ...@@ -58,34 +139,38 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
pci_name(pdev), (int)pdev->vendor, (int)pdev->device, pci_name(pdev), (int)pdev->vendor, (int)pdev->device,
(int)rev); (int)rev);
while ((fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { while ((fw_dev =
pci_get_device(PCI_VENDOR_ID_RICOH,
PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) {
if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) &&
pdev->bus == fw_dev->bus) { pdev->bus == fw_dev->bus) {
u8 write_enable; if (ricoh_mmc_disable(fw_dev) != 0)
u8 disable;
pci_read_config_byte(fw_dev, 0xCB, &disable);
if (disable & 0x02) {
printk(KERN_INFO DRIVER_NAME
": Controller already disabled. Nothing to do.\n");
return -ENODEV; return -ENODEV;
}
pci_read_config_byte(fw_dev, 0xCA, &write_enable);
pci_write_config_byte(fw_dev, 0xCA, 0x57);
pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
pci_write_config_byte(fw_dev, 0xCA, write_enable);
pci_set_drvdata(pdev, fw_dev); pci_set_drvdata(pdev, fw_dev);
printk(KERN_INFO DRIVER_NAME ++ctrlfound;
": Controller is now disabled.\n");
break; break;
} }
} }
if (pci_get_drvdata(pdev) == NULL) { fw_dev = NULL;
while (!ctrlfound &&
(fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH,
PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) {
if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) &&
pdev->bus == fw_dev->bus) {
if (ricoh_mmc_disable(fw_dev) != 0)
return -ENODEV;
pci_set_drvdata(pdev, fw_dev);
++ctrlfound;
}
}
if (!ctrlfound) {
printk(KERN_WARNING DRIVER_NAME printk(KERN_WARNING DRIVER_NAME
": Main firewire function not found. Cannot disable controller.\n"); ": Main firewire function not found. Cannot disable controller.\n");
return -ENODEV; return -ENODEV;
...@@ -96,30 +181,51 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, ...@@ -96,30 +181,51 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
static void __devexit ricoh_mmc_remove(struct pci_dev *pdev) static void __devexit ricoh_mmc_remove(struct pci_dev *pdev)
{ {
u8 write_enable;
u8 disable;
struct pci_dev *fw_dev = NULL; struct pci_dev *fw_dev = NULL;
fw_dev = pci_get_drvdata(pdev); fw_dev = pci_get_drvdata(pdev);
BUG_ON(fw_dev == NULL); BUG_ON(fw_dev == NULL);
pci_read_config_byte(fw_dev, 0xCA, &write_enable); ricoh_mmc_enable(fw_dev);
pci_read_config_byte(fw_dev, 0xCB, &disable);
pci_write_config_byte(fw_dev, 0xCA, 0x57);
pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
pci_write_config_byte(fw_dev, 0xCA, write_enable);
printk(KERN_INFO DRIVER_NAME
": Controller is now re-enabled.\n");
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
} }
static int ricoh_mmc_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct pci_dev *fw_dev = NULL;
fw_dev = pci_get_drvdata(pdev);
BUG_ON(fw_dev == NULL);
printk(KERN_INFO DRIVER_NAME ": Suspending.\n");
ricoh_mmc_enable(fw_dev);
return 0;
}
static int ricoh_mmc_resume(struct pci_dev *pdev)
{
struct pci_dev *fw_dev = NULL;
fw_dev = pci_get_drvdata(pdev);
BUG_ON(fw_dev == NULL);
printk(KERN_INFO DRIVER_NAME ": Resuming.\n");
ricoh_mmc_disable(fw_dev);
return 0;
}
static struct pci_driver ricoh_mmc_driver = { static struct pci_driver ricoh_mmc_driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.id_table = pci_ids, .id_table = pci_ids,
.probe = ricoh_mmc_probe, .probe = ricoh_mmc_probe,
.remove = __devexit_p(ricoh_mmc_remove), .remove = __devexit_p(ricoh_mmc_remove),
.suspend = ricoh_mmc_suspend,
.resume = ricoh_mmc_resume,
}; };
/*****************************************************************************\ /*****************************************************************************\
......
...@@ -30,6 +30,10 @@ ...@@ -30,6 +30,10 @@
static unsigned int debug_quirks = 0; static unsigned int debug_quirks = 0;
/* For multi controllers in one platform case */
static u16 chip_index = 0;
static spinlock_t index_lock;
/* /*
* Different quirks to handle when the hardware deviates from a strict * Different quirks to handle when the hardware deviates from a strict
* interpretation of the SDHCI specification. * interpretation of the SDHCI specification.
...@@ -1320,7 +1324,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) ...@@ -1320,7 +1324,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
DBG("slot %d at 0x%08lx, irq %d\n", slot, host->addr, host->irq); DBG("slot %d at 0x%08lx, irq %d\n", slot, host->addr, host->irq);
snprintf(host->slot_descr, 20, "sdhci:slot%d", slot); snprintf(host->slot_descr, 20, "sdhc%d:slot%d", chip->index, slot);
ret = pci_request_region(pdev, host->bar, host->slot_descr); ret = pci_request_region(pdev, host->bar, host->slot_descr);
if (ret) if (ret)
...@@ -1585,6 +1589,11 @@ static int __devinit sdhci_probe(struct pci_dev *pdev, ...@@ -1585,6 +1589,11 @@ static int __devinit sdhci_probe(struct pci_dev *pdev,
chip->num_slots = slots; chip->num_slots = slots;
pci_set_drvdata(pdev, chip); pci_set_drvdata(pdev, chip);
/* Add for multi controller case */
spin_lock(&index_lock);
chip->index = chip_index++;
spin_unlock(&index_lock);
for (i = 0;i < slots;i++) { for (i = 0;i < slots;i++) {
ret = sdhci_probe_slot(pdev, i); ret = sdhci_probe_slot(pdev, i);
if (ret) { if (ret) {
...@@ -1645,6 +1654,8 @@ static int __init sdhci_drv_init(void) ...@@ -1645,6 +1654,8 @@ static int __init sdhci_drv_init(void)
": Secure Digital Host Controller Interface driver\n"); ": Secure Digital Host Controller Interface driver\n");
printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n"); printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n");
spin_lock_init(&index_lock);
return pci_register_driver(&sdhci_driver); return pci_register_driver(&sdhci_driver);
} }
......
...@@ -208,6 +208,7 @@ struct sdhci_chip { ...@@ -208,6 +208,7 @@ struct sdhci_chip {
unsigned long quirks; unsigned long quirks;
int index; /* Index for chip0, chip1 ...*/
int num_slots; /* Slots on controller */ int num_slots; /* Slots on controller */
struct sdhci_host *hosts[0]; /* Pointers to hosts */ struct sdhci_host *hosts[0]; /* Pointers to hosts */
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment