aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2005-10-28 16:37:29 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-10-28 16:37:29 -0400
commit19c1f3ca4272008a256cc153f3e3feb097799070 (patch)
treeaf788b540d68396d9a94d6abf2379c1efc8e4e08 /drivers
parent84860bf0644d7c45afe7ddbd30731c3e3c371fae (diff)
[MMC] wbsd suspend support
Proper handling of suspend/resume in the wbsd driver. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/wbsd.c119
1 files changed, 91 insertions, 28 deletions
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index 25f7ce7b3bc0..3ace875decc4 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -1033,13 +1033,16 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
1033 } 1033 }
1034 else 1034 else
1035 { 1035 {
1036 setup &= ~WBSD_DAT3_H; 1036 if (setup & WBSD_DAT3_H)
1037 {
1038 setup &= ~WBSD_DAT3_H;
1037 1039
1038 /* 1040 /*
1039 * We cannot resume card detection immediatly 1041 * We cannot resume card detection immediatly
1040 * because of capacitance and delays in the chip. 1042 * because of capacitance and delays in the chip.
1041 */ 1043 */
1042 mod_timer(&host->ignore_timer, jiffies + HZ/100); 1044 mod_timer(&host->ignore_timer, jiffies + HZ/100);
1045 }
1043 } 1046 }
1044 wbsd_write_index(host, WBSD_IDX_SETUP, setup); 1047 wbsd_write_index(host, WBSD_IDX_SETUP, setup);
1045 1048
@@ -1461,8 +1464,10 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
1461 { 1464 {
1462 id = 0xFFFF; 1465 id = 0xFFFF;
1463 1466
1464 outb(unlock_codes[j], config_ports[i]); 1467 host->config = config_ports[i];
1465 outb(unlock_codes[j], config_ports[i]); 1468 host->unlock_code = unlock_codes[j];
1469
1470 wbsd_unlock_config(host);
1466 1471
1467 outb(WBSD_CONF_ID_HI, config_ports[i]); 1472 outb(WBSD_CONF_ID_HI, config_ports[i]);
1468 id = inb(config_ports[i] + 1) << 8; 1473 id = inb(config_ports[i] + 1) << 8;
@@ -1470,13 +1475,13 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
1470 outb(WBSD_CONF_ID_LO, config_ports[i]); 1475 outb(WBSD_CONF_ID_LO, config_ports[i]);
1471 id |= inb(config_ports[i] + 1); 1476 id |= inb(config_ports[i] + 1);
1472 1477
1478 wbsd_lock_config(host);
1479
1473 for (k = 0;k < sizeof(valid_ids)/sizeof(int);k++) 1480 for (k = 0;k < sizeof(valid_ids)/sizeof(int);k++)
1474 { 1481 {
1475 if (id == valid_ids[k]) 1482 if (id == valid_ids[k])
1476 { 1483 {
1477 host->chip_id = id; 1484 host->chip_id = id;
1478 host->config = config_ports[i];
1479 host->unlock_code = unlock_codes[i];
1480 1485
1481 return 0; 1486 return 0;
1482 } 1487 }
@@ -1487,13 +1492,14 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
1487 DBG("Unknown hardware (id %x) found at %x\n", 1492 DBG("Unknown hardware (id %x) found at %x\n",
1488 id, config_ports[i]); 1493 id, config_ports[i]);
1489 } 1494 }
1490
1491 outb(LOCK_CODE, config_ports[i]);
1492 } 1495 }
1493 1496
1494 release_region(config_ports[i], 2); 1497 release_region(config_ports[i], 2);
1495 } 1498 }
1496 1499
1500 host->config = 0;
1501 host->unlock_code = 0;
1502
1497 return -ENODEV; 1503 return -ENODEV;
1498} 1504}
1499 1505
@@ -1699,8 +1705,10 @@ static void __devexit wbsd_release_resources(struct wbsd_host* host)
1699 * Configure the resources the chip should use. 1705 * Configure the resources the chip should use.
1700 */ 1706 */
1701 1707
1702static void __devinit wbsd_chip_config(struct wbsd_host* host) 1708static void wbsd_chip_config(struct wbsd_host* host)
1703{ 1709{
1710 wbsd_unlock_config(host);
1711
1704 /* 1712 /*
1705 * Reset the chip. 1713 * Reset the chip.
1706 */ 1714 */
@@ -1733,16 +1741,20 @@ static void __devinit wbsd_chip_config(struct wbsd_host* host)
1733 */ 1741 */
1734 wbsd_write_config(host, WBSD_CONF_ENABLE, 1); 1742 wbsd_write_config(host, WBSD_CONF_ENABLE, 1);
1735 wbsd_write_config(host, WBSD_CONF_POWER, 0x20); 1743 wbsd_write_config(host, WBSD_CONF_POWER, 0x20);
1744
1745 wbsd_lock_config(host);
1736} 1746}
1737 1747
1738/* 1748/*
1739 * Check that configured resources are correct. 1749 * Check that configured resources are correct.
1740 */ 1750 */
1741 1751
1742static int __devinit wbsd_chip_validate(struct wbsd_host* host) 1752static int wbsd_chip_validate(struct wbsd_host* host)
1743{ 1753{
1744 int base, irq, dma; 1754 int base, irq, dma;
1745 1755
1756 wbsd_unlock_config(host);
1757
1746 /* 1758 /*
1747 * Select SD/MMC function. 1759 * Select SD/MMC function.
1748 */ 1760 */
@@ -1758,6 +1770,8 @@ static int __devinit wbsd_chip_validate(struct wbsd_host* host)
1758 1770
1759 dma = wbsd_read_config(host, WBSD_CONF_DRQ); 1771 dma = wbsd_read_config(host, WBSD_CONF_DRQ);
1760 1772
1773 wbsd_lock_config(host);
1774
1761 /* 1775 /*
1762 * Validate against given configuration. 1776 * Validate against given configuration.
1763 */ 1777 */
@@ -1771,6 +1785,20 @@ static int __devinit wbsd_chip_validate(struct wbsd_host* host)
1771 return 1; 1785 return 1;
1772} 1786}
1773 1787
1788/*
1789 * Powers down the SD function
1790 */
1791
1792static void wbsd_chip_poweroff(struct wbsd_host* host)
1793{
1794 wbsd_unlock_config(host);
1795
1796 wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);
1797 wbsd_write_config(host, WBSD_CONF_ENABLE, 0);
1798
1799 wbsd_lock_config(host);
1800}
1801
1774/*****************************************************************************\ 1802/*****************************************************************************\
1775 * * 1803 * *
1776 * Devices setup and shutdown * 1804 * Devices setup and shutdown *
@@ -1844,7 +1872,11 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
1844 */ 1872 */
1845#ifdef CONFIG_PM 1873#ifdef CONFIG_PM
1846 if (host->config) 1874 if (host->config)
1875 {
1876 wbsd_unlock_config(host);
1847 wbsd_write_config(host, WBSD_CONF_PME, 0xA0); 1877 wbsd_write_config(host, WBSD_CONF_PME, 0xA0);
1878 wbsd_lock_config(host);
1879 }
1848#endif 1880#endif
1849 /* 1881 /*
1850 * Allow device to initialise itself properly. 1882 * Allow device to initialise itself properly.
@@ -1885,16 +1917,11 @@ static void __devexit wbsd_shutdown(struct device* dev, int pnp)
1885 1917
1886 mmc_remove_host(mmc); 1918 mmc_remove_host(mmc);
1887 1919
1920 /*
1921 * Power down the SD/MMC function.
1922 */
1888 if (!pnp) 1923 if (!pnp)
1889 { 1924 wbsd_chip_poweroff(host);
1890 /*
1891 * Power down the SD/MMC function.
1892 */
1893 wbsd_unlock_config(host);
1894 wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);
1895 wbsd_write_config(host, WBSD_CONF_ENABLE, 0);
1896 wbsd_lock_config(host);
1897 }
1898 1925
1899 wbsd_release_resources(host); 1926 wbsd_release_resources(host);
1900 1927
@@ -1955,23 +1982,59 @@ static void __devexit wbsd_pnp_remove(struct pnp_dev * dev)
1955 */ 1982 */
1956 1983
1957#ifdef CONFIG_PM 1984#ifdef CONFIG_PM
1985
1958static int wbsd_suspend(struct device *dev, pm_message_t state) 1986static int wbsd_suspend(struct device *dev, pm_message_t state)
1959{ 1987{
1960 DBGF("Not yet supported\n"); 1988 struct mmc_host *mmc = dev_get_drvdata(dev);
1989 struct wbsd_host *host;
1990 int ret;
1991
1992 if (!mmc)
1993 return 0;
1994
1995 DBG("Suspending...\n");
1996
1997 ret = mmc_suspend_host(mmc, state);
1998 if (!ret)
1999 return ret;
2000
2001 host = mmc_priv(mmc);
2002
2003 wbsd_chip_poweroff(host);
1961 2004
1962 return 0; 2005 return 0;
1963} 2006}
1964 2007
1965static int wbsd_resume(struct device *dev) 2008static int wbsd_resume(struct device *dev)
1966{ 2009{
1967 DBGF("Not yet supported\n"); 2010 struct mmc_host *mmc = dev_get_drvdata(dev);
2011 struct wbsd_host *host;
1968 2012
1969 return 0; 2013 if (!mmc)
2014 return 0;
2015
2016 DBG("Resuming...\n");
2017
2018 host = mmc_priv(mmc);
2019
2020 wbsd_chip_config(host);
2021
2022 /*
2023 * Allow device to initialise itself properly.
2024 */
2025 mdelay(5);
2026
2027 wbsd_init_device(host);
2028
2029 return mmc_resume_host(mmc);
1970} 2030}
1971#else 2031
2032#else /* CONFIG_PM */
2033
1972#define wbsd_suspend NULL 2034#define wbsd_suspend NULL
1973#define wbsd_resume NULL 2035#define wbsd_resume NULL
1974#endif 2036
2037#endif /* CONFIG_PM */
1975 2038
1976static struct platform_device *wbsd_device; 2039static struct platform_device *wbsd_device;
1977 2040