Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b39dba5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* '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
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -2682,7 +2682,6 @@ MOTOROLA IMX MMC/SD HOST CONTROLLER INTERFACE DRIVER
P:	Pavel Pisa
M:	ppisa@pikron.com
L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
W:	http://mmc.drzeus.cx/wiki/Controllers/Freescale/SDHC
S:	Maintained

MOUSE AND MISC DEVICES [GENERAL]
@@ -3716,7 +3715,6 @@ SECURE DIGITAL HOST CONTROLLER INTERFACE DRIVER
P:	Pierre Ossman
M:	drzeus-sdhci@drzeus.cx
L:	sdhci-devel@list.drzeus.cx
W:	http://mmc.drzeus.cx/wiki/Linux/Drivers/sdhci
S:	Maintained

SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS
@@ -4286,7 +4284,6 @@ W83L51xD SD/MMC CARD INTERFACE DRIVER
P:	Pierre Ossman
M:	drzeus-wbsd@drzeus.cx
L:	linux-kernel@vger.kernel.org
W:	http://projects.drzeus.cx/wbsd
S:	Maintained

WATCHDOG DEVICE DRIVERS
+4 −4
Original line number Diff line number Diff line
@@ -25,8 +25,8 @@ config MMC_PXA
	  If unsure, say N.

config MMC_SDHCI
	tristate "Secure Digital Host Controller Interface support  (EXPERIMENTAL)"
	depends on PCI && EXPERIMENTAL
	tristate "Secure Digital Host Controller Interface support"
	depends on PCI
	help
	  This select the generic Secure Digital Host Controller Interface.
	  It is used by manufacturers such as Texas Instruments(R), Ricoh(R)
@@ -118,8 +118,8 @@ config MMC_TIFM_SD
	  module will be called tifm_sd.

config MMC_SPI
	tristate "MMC/SD over SPI (EXPERIMENTAL)"
	depends on MMC && SPI_MASTER && !HIGHMEM && EXPERIMENTAL
	tristate "MMC/SD over SPI"
	depends on MMC && SPI_MASTER && !HIGHMEM
	select CRC7
	select CRC_ITU_T
	help
+80 −34
Original line number Diff line number Diff line
@@ -70,10 +70,11 @@

#include <asm/io.h>
#include <asm/irq.h>
#include <asm/gpio.h>

#include <asm/mach/mmc.h>
#include <asm/arch/board.h>
#include <asm/arch/cpu.h>
#include <asm/arch/gpio.h>
#include <asm/arch/at91_mci.h>

#define DRIVER_NAME "at91_mci"
@@ -659,11 +660,11 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
	if (host->board->vcc_pin) {
		switch (ios->power_mode) {
			case MMC_POWER_OFF:
				at91_set_gpio_value(host->board->vcc_pin, 0);
				gpio_set_value(host->board->vcc_pin, 0);
				break;
			case MMC_POWER_UP:
			case MMC_POWER_ON:
				at91_set_gpio_value(host->board->vcc_pin, 1);
				gpio_set_value(host->board->vcc_pin, 1);
				break;
		}
	}
@@ -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)
{
	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,
@@ -793,7 +794,7 @@ static int at91_mci_get_ro(struct mmc_host *mmc)
	struct at91mci_host *host = mmc_priv(mmc);

	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),
				(read_only ? "read-only" : "read-write") );
	}
@@ -820,8 +821,6 @@ static int __init at91_mci_probe(struct platform_device *pdev)
	struct resource *res;
	int ret;

	pr_debug("Probe MCI devices\n");

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENXIO;
@@ -831,9 +830,9 @@ static int __init at91_mci_probe(struct platform_device *pdev)

	mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev);
	if (!mmc) {
		pr_debug("Failed to allocate mmc host\n");
		release_mem_region(res->start, res->end - res->start + 1);
		return -ENOMEM;
		ret = -ENOMEM;
		dev_dbg(&pdev->dev, "couldn't allocate mmc host\n");
		goto fail6;
	}

	mmc->ops = &at91_mci_ops;
@@ -853,19 +852,44 @@ static int __init at91_mci_probe(struct platform_device *pdev)
		if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
			mmc->caps |= MMC_CAP_4_BIT_DATA;
		else
			printk("AT91 MMC: 4 wire bus mode not supported"
			dev_warn(&pdev->dev, "4 wire bus mode not supported"
				" - 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
	 */
	host->mci_clk = clk_get(&pdev->dev, "mci_clk");
	if (IS_ERR(host->mci_clk)) {
		printk(KERN_ERR "AT91 MMC: no clock defined.\n");
		mmc_free_host(mmc);
		release_mem_region(res->start, res->end - res->start + 1);
		return -ENODEV;
		ret = -ENODEV;
		dev_dbg(&pdev->dev, "no mci_clk?\n");
		goto fail2;
	}

	/*
@@ -873,10 +897,8 @@ static int __init at91_mci_probe(struct platform_device *pdev)
	 */
	host->baseaddr = ioremap(res->start, res->end - res->start + 1);
	if (!host->baseaddr) {
		clk_put(host->mci_clk);
		mmc_free_host(mmc);
		release_mem_region(res->start, res->end - res->start + 1);
		return -ENOMEM;
		ret = -ENOMEM;
		goto fail1;
	}

	/*
@@ -890,15 +912,11 @@ static int __init at91_mci_probe(struct platform_device *pdev)
	 * Allocate the MCI interrupt
	 */
	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) {
		printk(KERN_ERR "AT91 MMC: Failed to request MCI interrupt\n");
		clk_disable(host->mci_clk);
		clk_put(host->mci_clk);
		mmc_free_host(mmc);
		iounmap(host->baseaddr);
		release_mem_region(res->start, res->end - res->start + 1);
		return ret;
		dev_dbg(&pdev->dev, "request MCI interrupt failed\n");
		goto fail0;
	}

	platform_set_drvdata(pdev, mmc);
@@ -907,8 +925,7 @@ static int __init at91_mci_probe(struct platform_device *pdev)
	 * Add host to MMC layer
	 */
	if (host->board->det_pin) {
		host->present = !at91_get_gpio_value(host->board->det_pin);
		device_init_wakeup(&pdev->dev, 1);
		host->present = !gpio_get_value(host->board->det_pin);
	}
	else
		host->present = -1;
@@ -919,15 +936,38 @@ static int __init at91_mci_probe(struct platform_device *pdev)
	 * monitor card insertion/removal if we can
	 */
	if (host->board->det_pin) {
		ret = request_irq(host->board->det_pin, at91_mmc_det_irq,
				0, DRIVER_NAME, host);
		ret = request_irq(gpio_to_irq(host->board->det_pin),
				at91_mmc_det_irq, 0, mmc_hostname(mmc), host);
		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");

	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)
	host = mmc_priv(mmc);

	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);
		free_irq(host->board->det_pin, host);
		cancel_delayed_work(&host->mmc->detect);
		gpio_free(host->board->det_pin);
	}

	at91_mci_disable(host);
@@ -957,6 +998,11 @@ static int __exit at91_mci_remove(struct platform_device *pdev)
	clk_disable(host->mci_clk);			/* Disable the peripheral clock */
	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);
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	release_mem_region(res->start, res->end - res->start + 1);
+134 −28
Original line number Diff line number Diff line
@@ -41,10 +41,91 @@ static const struct pci_device_id pci_ids[] __devinitdata = {

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,
				     const struct pci_device_id *ent)
{
	u8 rev;
	u8 ctrlfound = 0;

	struct pci_dev *fw_dev = NULL;

@@ -58,34 +139,38 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
		pci_name(pdev), (int)pdev->vendor, (int)pdev->device,
		(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) &&
		    pdev->bus == fw_dev->bus) {
			u8 write_enable;
			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");
			if (ricoh_mmc_disable(fw_dev) != 0)
				return -ENODEV;

			pci_set_drvdata(pdev, fw_dev);

			++ctrlfound;
			break;
		}
	}

			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);
	fw_dev = NULL;

			pci_set_drvdata(pdev, fw_dev);
	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;

			printk(KERN_INFO DRIVER_NAME
			       ": Controller is now disabled.\n");
			pci_set_drvdata(pdev, fw_dev);

			break;
			++ctrlfound;
		}
	}

	if (pci_get_drvdata(pdev) == NULL) {
	if (!ctrlfound) {
		printk(KERN_WARNING DRIVER_NAME
		       ": Main firewire function not found. Cannot disable controller.\n");
		return -ENODEV;
@@ -96,30 +181,51 @@ static int __devinit ricoh_mmc_probe(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;

	fw_dev = pci_get_drvdata(pdev);
	BUG_ON(fw_dev == NULL);

	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");
	ricoh_mmc_enable(fw_dev);

	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 = {
	.name = 	DRIVER_NAME,
	.id_table =	pci_ids,
	.probe = 	ricoh_mmc_probe,
	.remove =	__devexit_p(ricoh_mmc_remove),
	.suspend =	ricoh_mmc_suspend,
	.resume =	ricoh_mmc_resume,
};

/*****************************************************************************\
+12 −1
Original line number Diff line number Diff line
@@ -30,6 +30,10 @@

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
 * interpretation of the SDHCI specification.
@@ -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);

	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);
	if (ret)
@@ -1585,6 +1589,11 @@ static int __devinit sdhci_probe(struct pci_dev *pdev,
	chip->num_slots = slots;
	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++) {
		ret = sdhci_probe_slot(pdev, i);
		if (ret) {
@@ -1645,6 +1654,8 @@ static int __init sdhci_drv_init(void)
		": Secure Digital Host Controller Interface driver\n");
	printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n");

	spin_lock_init(&index_lock);

	return pci_register_driver(&sdhci_driver);
}

Loading