diff options
-rw-r--r-- | MAINTAINERS | 3 | ||||
-rw-r--r-- | drivers/mmc/host/Kconfig | 8 | ||||
-rw-r--r-- | drivers/mmc/host/at91_mci.c | 114 | ||||
-rw-r--r-- | drivers/mmc/host/ricoh_mmc.c | 162 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 13 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 1 |
6 files changed, 231 insertions, 70 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 5740aa216e11..c40f0ae96552 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2682,7 +2682,6 @@ MOTOROLA IMX MMC/SD HOST CONTROLLER INTERFACE DRIVER | |||
2682 | P: Pavel Pisa | 2682 | P: Pavel Pisa |
2683 | M: ppisa@pikron.com | 2683 | M: ppisa@pikron.com |
2684 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 2684 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
2685 | W: http://mmc.drzeus.cx/wiki/Controllers/Freescale/SDHC | ||
2686 | S: Maintained | 2685 | S: Maintained |
2687 | 2686 | ||
2688 | MOUSE AND MISC DEVICES [GENERAL] | 2687 | MOUSE AND MISC DEVICES [GENERAL] |
@@ -3716,7 +3715,6 @@ SECURE DIGITAL HOST CONTROLLER INTERFACE DRIVER | |||
3716 | P: Pierre Ossman | 3715 | P: Pierre Ossman |
3717 | M: drzeus-sdhci@drzeus.cx | 3716 | M: drzeus-sdhci@drzeus.cx |
3718 | L: sdhci-devel@list.drzeus.cx | 3717 | L: sdhci-devel@list.drzeus.cx |
3719 | W: http://mmc.drzeus.cx/wiki/Linux/Drivers/sdhci | ||
3720 | S: Maintained | 3718 | S: Maintained |
3721 | 3719 | ||
3722 | SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS | 3720 | SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS |
@@ -4286,7 +4284,6 @@ W83L51xD SD/MMC CARD INTERFACE DRIVER | |||
4286 | P: Pierre Ossman | 4284 | P: Pierre Ossman |
4287 | M: drzeus-wbsd@drzeus.cx | 4285 | M: drzeus-wbsd@drzeus.cx |
4288 | L: linux-kernel@vger.kernel.org | 4286 | L: linux-kernel@vger.kernel.org |
4289 | W: http://projects.drzeus.cx/wbsd | ||
4290 | S: Maintained | 4287 | S: Maintained |
4291 | 4288 | ||
4292 | WATCHDOG DEVICE DRIVERS | 4289 | WATCHDOG DEVICE DRIVERS |
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 5fef6783c716..3b3cd0e74715 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -25,8 +25,8 @@ config MMC_PXA | |||
25 | If unsure, say N. | 25 | If unsure, say N. |
26 | 26 | ||
27 | config MMC_SDHCI | 27 | config MMC_SDHCI |
28 | tristate "Secure Digital Host Controller Interface support (EXPERIMENTAL)" | 28 | tristate "Secure Digital Host Controller Interface support" |
29 | depends on PCI && EXPERIMENTAL | 29 | depends on PCI |
30 | help | 30 | help |
31 | This select the generic Secure Digital Host Controller Interface. | 31 | This select the generic Secure Digital Host Controller Interface. |
32 | It is used by manufacturers such as Texas Instruments(R), Ricoh(R) | 32 | It is used by manufacturers such as Texas Instruments(R), Ricoh(R) |
@@ -118,8 +118,8 @@ config MMC_TIFM_SD | |||
118 | module will be called tifm_sd. | 118 | module will be called tifm_sd. |
119 | 119 | ||
120 | config MMC_SPI | 120 | config MMC_SPI |
121 | tristate "MMC/SD over SPI (EXPERIMENTAL)" | 121 | tristate "MMC/SD over SPI" |
122 | depends on MMC && SPI_MASTER && !HIGHMEM && EXPERIMENTAL | 122 | depends on MMC && SPI_MASTER && !HIGHMEM |
123 | select CRC7 | 123 | select CRC7 |
124 | select CRC_ITU_T | 124 | select CRC_ITU_T |
125 | help | 125 | help |
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index b1edcefdd4f9..21acecc9fe3a 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c | |||
@@ -70,10 +70,11 @@ | |||
70 | 70 | ||
71 | #include <asm/io.h> | 71 | #include <asm/io.h> |
72 | #include <asm/irq.h> | 72 | #include <asm/irq.h> |
73 | #include <asm/gpio.h> | ||
74 | |||
73 | #include <asm/mach/mmc.h> | 75 | #include <asm/mach/mmc.h> |
74 | #include <asm/arch/board.h> | 76 | #include <asm/arch/board.h> |
75 | #include <asm/arch/cpu.h> | 77 | #include <asm/arch/cpu.h> |
76 | #include <asm/arch/gpio.h> | ||
77 | #include <asm/arch/at91_mci.h> | 78 | #include <asm/arch/at91_mci.h> |
78 | 79 | ||
79 | #define DRIVER_NAME "at91_mci" | 80 | #define DRIVER_NAME "at91_mci" |
@@ -659,11 +660,11 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
659 | if (host->board->vcc_pin) { | 660 | if (host->board->vcc_pin) { |
660 | switch (ios->power_mode) { | 661 | switch (ios->power_mode) { |
661 | case MMC_POWER_OFF: | 662 | case MMC_POWER_OFF: |
662 | at91_set_gpio_value(host->board->vcc_pin, 0); | 663 | gpio_set_value(host->board->vcc_pin, 0); |
663 | break; | 664 | break; |
664 | case MMC_POWER_UP: | 665 | case MMC_POWER_UP: |
665 | case MMC_POWER_ON: | 666 | case MMC_POWER_ON: |
666 | at91_set_gpio_value(host->board->vcc_pin, 1); | 667 | gpio_set_value(host->board->vcc_pin, 1); |
667 | break; | 668 | break; |
668 | } | 669 | } |
669 | } | 670 | } |
@@ -768,7 +769,7 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) | |||
768 | static irqreturn_t at91_mmc_det_irq(int irq, void *_host) | 769 | static irqreturn_t at91_mmc_det_irq(int irq, void *_host) |
769 | { | 770 | { |
770 | struct at91mci_host *host = _host; | 771 | struct at91mci_host *host = _host; |
771 | int present = !at91_get_gpio_value(irq); | 772 | int present = !gpio_get_value(irq_to_gpio(irq)); |
772 | 773 | ||
773 | /* | 774 | /* |
774 | * we expect this irq on both insert and remove, | 775 | * we expect this irq on both insert and remove, |
@@ -793,7 +794,7 @@ static int at91_mci_get_ro(struct mmc_host *mmc) | |||
793 | struct at91mci_host *host = mmc_priv(mmc); | 794 | struct at91mci_host *host = mmc_priv(mmc); |
794 | 795 | ||
795 | if (host->board->wp_pin) { | 796 | if (host->board->wp_pin) { |
796 | read_only = at91_get_gpio_value(host->board->wp_pin); | 797 | read_only = gpio_get_value(host->board->wp_pin); |
797 | printk(KERN_WARNING "%s: card is %s\n", mmc_hostname(mmc), | 798 | printk(KERN_WARNING "%s: card is %s\n", mmc_hostname(mmc), |
798 | (read_only ? "read-only" : "read-write") ); | 799 | (read_only ? "read-only" : "read-write") ); |
799 | } | 800 | } |
@@ -820,8 +821,6 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
820 | struct resource *res; | 821 | struct resource *res; |
821 | int ret; | 822 | int ret; |
822 | 823 | ||
823 | pr_debug("Probe MCI devices\n"); | ||
824 | |||
825 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 824 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
826 | if (!res) | 825 | if (!res) |
827 | return -ENXIO; | 826 | return -ENXIO; |
@@ -831,9 +830,9 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
831 | 830 | ||
832 | mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev); | 831 | mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev); |
833 | if (!mmc) { | 832 | if (!mmc) { |
834 | pr_debug("Failed to allocate mmc host\n"); | 833 | ret = -ENOMEM; |
835 | release_mem_region(res->start, res->end - res->start + 1); | 834 | dev_dbg(&pdev->dev, "couldn't allocate mmc host\n"); |
836 | return -ENOMEM; | 835 | goto fail6; |
837 | } | 836 | } |
838 | 837 | ||
839 | mmc->ops = &at91_mci_ops; | 838 | mmc->ops = &at91_mci_ops; |
@@ -853,19 +852,44 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
853 | if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) | 852 | if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) |
854 | mmc->caps |= MMC_CAP_4_BIT_DATA; | 853 | mmc->caps |= MMC_CAP_4_BIT_DATA; |
855 | else | 854 | else |
856 | printk("AT91 MMC: 4 wire bus mode not supported" | 855 | dev_warn(&pdev->dev, "4 wire bus mode not supported" |
857 | " - using 1 wire\n"); | 856 | " - using 1 wire\n"); |
858 | } | 857 | } |
859 | 858 | ||
860 | /* | 859 | /* |
860 | * Reserve GPIOs ... board init code makes sure these pins are set | ||
861 | * up as GPIOs with the right direction (input, except for vcc) | ||
862 | */ | ||
863 | if (host->board->det_pin) { | ||
864 | ret = gpio_request(host->board->det_pin, "mmc_detect"); | ||
865 | if (ret < 0) { | ||
866 | dev_dbg(&pdev->dev, "couldn't claim card detect pin\n"); | ||
867 | goto fail5; | ||
868 | } | ||
869 | } | ||
870 | if (host->board->wp_pin) { | ||
871 | ret = gpio_request(host->board->wp_pin, "mmc_wp"); | ||
872 | if (ret < 0) { | ||
873 | dev_dbg(&pdev->dev, "couldn't claim wp sense pin\n"); | ||
874 | goto fail4; | ||
875 | } | ||
876 | } | ||
877 | if (host->board->vcc_pin) { | ||
878 | ret = gpio_request(host->board->vcc_pin, "mmc_vcc"); | ||
879 | if (ret < 0) { | ||
880 | dev_dbg(&pdev->dev, "couldn't claim vcc switch pin\n"); | ||
881 | goto fail3; | ||
882 | } | ||
883 | } | ||
884 | |||
885 | /* | ||
861 | * Get Clock | 886 | * Get Clock |
862 | */ | 887 | */ |
863 | host->mci_clk = clk_get(&pdev->dev, "mci_clk"); | 888 | host->mci_clk = clk_get(&pdev->dev, "mci_clk"); |
864 | if (IS_ERR(host->mci_clk)) { | 889 | if (IS_ERR(host->mci_clk)) { |
865 | printk(KERN_ERR "AT91 MMC: no clock defined.\n"); | 890 | ret = -ENODEV; |
866 | mmc_free_host(mmc); | 891 | dev_dbg(&pdev->dev, "no mci_clk?\n"); |
867 | release_mem_region(res->start, res->end - res->start + 1); | 892 | goto fail2; |
868 | return -ENODEV; | ||
869 | } | 893 | } |
870 | 894 | ||
871 | /* | 895 | /* |
@@ -873,10 +897,8 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
873 | */ | 897 | */ |
874 | host->baseaddr = ioremap(res->start, res->end - res->start + 1); | 898 | host->baseaddr = ioremap(res->start, res->end - res->start + 1); |
875 | if (!host->baseaddr) { | 899 | if (!host->baseaddr) { |
876 | clk_put(host->mci_clk); | 900 | ret = -ENOMEM; |
877 | mmc_free_host(mmc); | 901 | goto fail1; |
878 | release_mem_region(res->start, res->end - res->start + 1); | ||
879 | return -ENOMEM; | ||
880 | } | 902 | } |
881 | 903 | ||
882 | /* | 904 | /* |
@@ -890,15 +912,11 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
890 | * Allocate the MCI interrupt | 912 | * Allocate the MCI interrupt |
891 | */ | 913 | */ |
892 | host->irq = platform_get_irq(pdev, 0); | 914 | host->irq = platform_get_irq(pdev, 0); |
893 | ret = request_irq(host->irq, at91_mci_irq, IRQF_SHARED, DRIVER_NAME, host); | 915 | ret = request_irq(host->irq, at91_mci_irq, IRQF_SHARED, |
916 | mmc_hostname(mmc), host); | ||
894 | if (ret) { | 917 | if (ret) { |
895 | printk(KERN_ERR "AT91 MMC: Failed to request MCI interrupt\n"); | 918 | dev_dbg(&pdev->dev, "request MCI interrupt failed\n"); |
896 | clk_disable(host->mci_clk); | 919 | goto fail0; |
897 | clk_put(host->mci_clk); | ||
898 | mmc_free_host(mmc); | ||
899 | iounmap(host->baseaddr); | ||
900 | release_mem_region(res->start, res->end - res->start + 1); | ||
901 | return ret; | ||
902 | } | 920 | } |
903 | 921 | ||
904 | platform_set_drvdata(pdev, mmc); | 922 | platform_set_drvdata(pdev, mmc); |
@@ -907,8 +925,7 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
907 | * Add host to MMC layer | 925 | * Add host to MMC layer |
908 | */ | 926 | */ |
909 | if (host->board->det_pin) { | 927 | if (host->board->det_pin) { |
910 | host->present = !at91_get_gpio_value(host->board->det_pin); | 928 | host->present = !gpio_get_value(host->board->det_pin); |
911 | device_init_wakeup(&pdev->dev, 1); | ||
912 | } | 929 | } |
913 | else | 930 | else |
914 | host->present = -1; | 931 | host->present = -1; |
@@ -919,15 +936,38 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
919 | * monitor card insertion/removal if we can | 936 | * monitor card insertion/removal if we can |
920 | */ | 937 | */ |
921 | if (host->board->det_pin) { | 938 | if (host->board->det_pin) { |
922 | ret = request_irq(host->board->det_pin, at91_mmc_det_irq, | 939 | ret = request_irq(gpio_to_irq(host->board->det_pin), |
923 | 0, DRIVER_NAME, host); | 940 | at91_mmc_det_irq, 0, mmc_hostname(mmc), host); |
924 | if (ret) | 941 | if (ret) |
925 | printk(KERN_ERR "AT91 MMC: Couldn't allocate MMC detect irq\n"); | 942 | dev_warn(&pdev->dev, "request MMC detect irq failed\n"); |
943 | else | ||
944 | device_init_wakeup(&pdev->dev, 1); | ||
926 | } | 945 | } |
927 | 946 | ||
928 | pr_debug("Added MCI driver\n"); | 947 | pr_debug("Added MCI driver\n"); |
929 | 948 | ||
930 | return 0; | 949 | return 0; |
950 | |||
951 | fail0: | ||
952 | clk_disable(host->mci_clk); | ||
953 | iounmap(host->baseaddr); | ||
954 | fail1: | ||
955 | clk_put(host->mci_clk); | ||
956 | fail2: | ||
957 | if (host->board->vcc_pin) | ||
958 | gpio_free(host->board->vcc_pin); | ||
959 | fail3: | ||
960 | if (host->board->wp_pin) | ||
961 | gpio_free(host->board->wp_pin); | ||
962 | fail4: | ||
963 | if (host->board->det_pin) | ||
964 | gpio_free(host->board->det_pin); | ||
965 | fail5: | ||
966 | mmc_free_host(mmc); | ||
967 | fail6: | ||
968 | release_mem_region(res->start, res->end - res->start + 1); | ||
969 | dev_err(&pdev->dev, "probe failed, err %d\n", ret); | ||
970 | return ret; | ||
931 | } | 971 | } |
932 | 972 | ||
933 | /* | 973 | /* |
@@ -945,9 +985,10 @@ static int __exit at91_mci_remove(struct platform_device *pdev) | |||
945 | host = mmc_priv(mmc); | 985 | host = mmc_priv(mmc); |
946 | 986 | ||
947 | if (host->board->det_pin) { | 987 | if (host->board->det_pin) { |
988 | if (device_can_wakeup(&pdev->dev)) | ||
989 | free_irq(gpio_to_irq(host->board->det_pin), host); | ||
948 | device_init_wakeup(&pdev->dev, 0); | 990 | device_init_wakeup(&pdev->dev, 0); |
949 | free_irq(host->board->det_pin, host); | 991 | gpio_free(host->board->det_pin); |
950 | cancel_delayed_work(&host->mmc->detect); | ||
951 | } | 992 | } |
952 | 993 | ||
953 | at91_mci_disable(host); | 994 | at91_mci_disable(host); |
@@ -957,6 +998,11 @@ static int __exit at91_mci_remove(struct platform_device *pdev) | |||
957 | clk_disable(host->mci_clk); /* Disable the peripheral clock */ | 998 | clk_disable(host->mci_clk); /* Disable the peripheral clock */ |
958 | clk_put(host->mci_clk); | 999 | clk_put(host->mci_clk); |
959 | 1000 | ||
1001 | if (host->board->vcc_pin) | ||
1002 | gpio_free(host->board->vcc_pin); | ||
1003 | if (host->board->wp_pin) | ||
1004 | gpio_free(host->board->wp_pin); | ||
1005 | |||
960 | iounmap(host->baseaddr); | 1006 | iounmap(host->baseaddr); |
961 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1007 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
962 | release_mem_region(res->start, res->end - res->start + 1); | 1008 | release_mem_region(res->start, res->end - res->start + 1); |
diff --git a/drivers/mmc/host/ricoh_mmc.c b/drivers/mmc/host/ricoh_mmc.c index 1e8704533bc5..a16d7609e4ee 100644 --- a/drivers/mmc/host/ricoh_mmc.c +++ b/drivers/mmc/host/ricoh_mmc.c | |||
@@ -41,10 +41,91 @@ static const struct pci_device_id pci_ids[] __devinitdata = { | |||
41 | 41 | ||
42 | MODULE_DEVICE_TABLE(pci, pci_ids); | 42 | MODULE_DEVICE_TABLE(pci, pci_ids); |
43 | 43 | ||
44 | static int ricoh_mmc_disable(struct pci_dev *fw_dev) | ||
45 | { | ||
46 | u8 write_enable; | ||
47 | u8 write_target; | ||
48 | u8 disable; | ||
49 | |||
50 | if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) { | ||
51 | /* via RL5C476 */ | ||
52 | |||
53 | pci_read_config_byte(fw_dev, 0xB7, &disable); | ||
54 | if (disable & 0x02) { | ||
55 | printk(KERN_INFO DRIVER_NAME | ||
56 | ": Controller already disabled. " \ | ||
57 | "Nothing to do.\n"); | ||
58 | return -ENODEV; | ||
59 | } | ||
60 | |||
61 | pci_read_config_byte(fw_dev, 0x8E, &write_enable); | ||
62 | pci_write_config_byte(fw_dev, 0x8E, 0xAA); | ||
63 | pci_read_config_byte(fw_dev, 0x8D, &write_target); | ||
64 | pci_write_config_byte(fw_dev, 0x8D, 0xB7); | ||
65 | pci_write_config_byte(fw_dev, 0xB7, disable | 0x02); | ||
66 | pci_write_config_byte(fw_dev, 0x8E, write_enable); | ||
67 | pci_write_config_byte(fw_dev, 0x8D, write_target); | ||
68 | } else { | ||
69 | /* via R5C832 */ | ||
70 | |||
71 | pci_read_config_byte(fw_dev, 0xCB, &disable); | ||
72 | if (disable & 0x02) { | ||
73 | printk(KERN_INFO DRIVER_NAME | ||
74 | ": Controller already disabled. " \ | ||
75 | "Nothing to do.\n"); | ||
76 | return -ENODEV; | ||
77 | } | ||
78 | |||
79 | pci_read_config_byte(fw_dev, 0xCA, &write_enable); | ||
80 | pci_write_config_byte(fw_dev, 0xCA, 0x57); | ||
81 | pci_write_config_byte(fw_dev, 0xCB, disable | 0x02); | ||
82 | pci_write_config_byte(fw_dev, 0xCA, write_enable); | ||
83 | } | ||
84 | |||
85 | printk(KERN_INFO DRIVER_NAME | ||
86 | ": Controller is now disabled.\n"); | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static int ricoh_mmc_enable(struct pci_dev *fw_dev) | ||
92 | { | ||
93 | u8 write_enable; | ||
94 | u8 write_target; | ||
95 | u8 disable; | ||
96 | |||
97 | if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) { | ||
98 | /* via RL5C476 */ | ||
99 | |||
100 | pci_read_config_byte(fw_dev, 0x8E, &write_enable); | ||
101 | pci_write_config_byte(fw_dev, 0x8E, 0xAA); | ||
102 | pci_read_config_byte(fw_dev, 0x8D, &write_target); | ||
103 | pci_write_config_byte(fw_dev, 0x8D, 0xB7); | ||
104 | pci_read_config_byte(fw_dev, 0xB7, &disable); | ||
105 | pci_write_config_byte(fw_dev, 0xB7, disable & ~0x02); | ||
106 | pci_write_config_byte(fw_dev, 0x8E, write_enable); | ||
107 | pci_write_config_byte(fw_dev, 0x8D, write_target); | ||
108 | } else { | ||
109 | /* via R5C832 */ | ||
110 | |||
111 | pci_read_config_byte(fw_dev, 0xCA, &write_enable); | ||
112 | pci_read_config_byte(fw_dev, 0xCB, &disable); | ||
113 | pci_write_config_byte(fw_dev, 0xCA, 0x57); | ||
114 | pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02); | ||
115 | pci_write_config_byte(fw_dev, 0xCA, write_enable); | ||
116 | } | ||
117 | |||
118 | printk(KERN_INFO DRIVER_NAME | ||
119 | ": Controller is now re-enabled.\n"); | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
44 | static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, | 124 | static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, |
45 | const struct pci_device_id *ent) | 125 | const struct pci_device_id *ent) |
46 | { | 126 | { |
47 | u8 rev; | 127 | u8 rev; |
128 | u8 ctrlfound = 0; | ||
48 | 129 | ||
49 | struct pci_dev *fw_dev = NULL; | 130 | struct pci_dev *fw_dev = NULL; |
50 | 131 | ||
@@ -58,34 +139,38 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, | |||
58 | pci_name(pdev), (int)pdev->vendor, (int)pdev->device, | 139 | pci_name(pdev), (int)pdev->vendor, (int)pdev->device, |
59 | (int)rev); | 140 | (int)rev); |
60 | 141 | ||
61 | while ((fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { | 142 | while ((fw_dev = |
143 | pci_get_device(PCI_VENDOR_ID_RICOH, | ||
144 | PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) { | ||
62 | if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && | 145 | if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && |
63 | pdev->bus == fw_dev->bus) { | 146 | pdev->bus == fw_dev->bus) { |
64 | u8 write_enable; | 147 | if (ricoh_mmc_disable(fw_dev) != 0) |
65 | u8 disable; | ||
66 | |||
67 | pci_read_config_byte(fw_dev, 0xCB, &disable); | ||
68 | if (disable & 0x02) { | ||
69 | printk(KERN_INFO DRIVER_NAME | ||
70 | ": Controller already disabled. Nothing to do.\n"); | ||
71 | return -ENODEV; | 148 | return -ENODEV; |
72 | } | ||
73 | |||
74 | pci_read_config_byte(fw_dev, 0xCA, &write_enable); | ||
75 | pci_write_config_byte(fw_dev, 0xCA, 0x57); | ||
76 | pci_write_config_byte(fw_dev, 0xCB, disable | 0x02); | ||
77 | pci_write_config_byte(fw_dev, 0xCA, write_enable); | ||
78 | 149 | ||
79 | pci_set_drvdata(pdev, fw_dev); | 150 | pci_set_drvdata(pdev, fw_dev); |
80 | 151 | ||
81 | printk(KERN_INFO DRIVER_NAME | 152 | ++ctrlfound; |
82 | ": Controller is now disabled.\n"); | ||
83 | |||
84 | break; | 153 | break; |
85 | } | 154 | } |
86 | } | 155 | } |
87 | 156 | ||
88 | if (pci_get_drvdata(pdev) == NULL) { | 157 | fw_dev = NULL; |
158 | |||
159 | while (!ctrlfound && | ||
160 | (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, | ||
161 | PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { | ||
162 | if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && | ||
163 | pdev->bus == fw_dev->bus) { | ||
164 | if (ricoh_mmc_disable(fw_dev) != 0) | ||
165 | return -ENODEV; | ||
166 | |||
167 | pci_set_drvdata(pdev, fw_dev); | ||
168 | |||
169 | ++ctrlfound; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | if (!ctrlfound) { | ||
89 | printk(KERN_WARNING DRIVER_NAME | 174 | printk(KERN_WARNING DRIVER_NAME |
90 | ": Main firewire function not found. Cannot disable controller.\n"); | 175 | ": Main firewire function not found. Cannot disable controller.\n"); |
91 | return -ENODEV; | 176 | return -ENODEV; |
@@ -96,30 +181,51 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, | |||
96 | 181 | ||
97 | static void __devexit ricoh_mmc_remove(struct pci_dev *pdev) | 182 | static void __devexit ricoh_mmc_remove(struct pci_dev *pdev) |
98 | { | 183 | { |
99 | u8 write_enable; | ||
100 | u8 disable; | ||
101 | struct pci_dev *fw_dev = NULL; | 184 | struct pci_dev *fw_dev = NULL; |
102 | 185 | ||
103 | fw_dev = pci_get_drvdata(pdev); | 186 | fw_dev = pci_get_drvdata(pdev); |
104 | BUG_ON(fw_dev == NULL); | 187 | BUG_ON(fw_dev == NULL); |
105 | 188 | ||
106 | pci_read_config_byte(fw_dev, 0xCA, &write_enable); | 189 | ricoh_mmc_enable(fw_dev); |
107 | pci_read_config_byte(fw_dev, 0xCB, &disable); | ||
108 | pci_write_config_byte(fw_dev, 0xCA, 0x57); | ||
109 | pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02); | ||
110 | pci_write_config_byte(fw_dev, 0xCA, write_enable); | ||
111 | |||
112 | printk(KERN_INFO DRIVER_NAME | ||
113 | ": Controller is now re-enabled.\n"); | ||
114 | 190 | ||
115 | pci_set_drvdata(pdev, NULL); | 191 | pci_set_drvdata(pdev, NULL); |
116 | } | 192 | } |
117 | 193 | ||
194 | static int ricoh_mmc_suspend(struct pci_dev *pdev, pm_message_t state) | ||
195 | { | ||
196 | struct pci_dev *fw_dev = NULL; | ||
197 | |||
198 | fw_dev = pci_get_drvdata(pdev); | ||
199 | BUG_ON(fw_dev == NULL); | ||
200 | |||
201 | printk(KERN_INFO DRIVER_NAME ": Suspending.\n"); | ||
202 | |||
203 | ricoh_mmc_enable(fw_dev); | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | static int ricoh_mmc_resume(struct pci_dev *pdev) | ||
209 | { | ||
210 | struct pci_dev *fw_dev = NULL; | ||
211 | |||
212 | fw_dev = pci_get_drvdata(pdev); | ||
213 | BUG_ON(fw_dev == NULL); | ||
214 | |||
215 | printk(KERN_INFO DRIVER_NAME ": Resuming.\n"); | ||
216 | |||
217 | ricoh_mmc_disable(fw_dev); | ||
218 | |||
219 | return 0; | ||
220 | } | ||
221 | |||
118 | static struct pci_driver ricoh_mmc_driver = { | 222 | static struct pci_driver ricoh_mmc_driver = { |
119 | .name = DRIVER_NAME, | 223 | .name = DRIVER_NAME, |
120 | .id_table = pci_ids, | 224 | .id_table = pci_ids, |
121 | .probe = ricoh_mmc_probe, | 225 | .probe = ricoh_mmc_probe, |
122 | .remove = __devexit_p(ricoh_mmc_remove), | 226 | .remove = __devexit_p(ricoh_mmc_remove), |
227 | .suspend = ricoh_mmc_suspend, | ||
228 | .resume = ricoh_mmc_resume, | ||
123 | }; | 229 | }; |
124 | 230 | ||
125 | /*****************************************************************************\ | 231 | /*****************************************************************************\ |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 785bbdcf4a58..4b673aa2dc3c 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -30,6 +30,10 @@ | |||
30 | 30 | ||
31 | static unsigned int debug_quirks = 0; | 31 | static unsigned int debug_quirks = 0; |
32 | 32 | ||
33 | /* For multi controllers in one platform case */ | ||
34 | static u16 chip_index = 0; | ||
35 | static spinlock_t index_lock; | ||
36 | |||
33 | /* | 37 | /* |
34 | * Different quirks to handle when the hardware deviates from a strict | 38 | * Different quirks to handle when the hardware deviates from a strict |
35 | * interpretation of the SDHCI specification. | 39 | * interpretation of the SDHCI specification. |
@@ -1320,7 +1324,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) | |||
1320 | 1324 | ||
1321 | DBG("slot %d at 0x%08lx, irq %d\n", slot, host->addr, host->irq); | 1325 | DBG("slot %d at 0x%08lx, irq %d\n", slot, host->addr, host->irq); |
1322 | 1326 | ||
1323 | snprintf(host->slot_descr, 20, "sdhci:slot%d", slot); | 1327 | snprintf(host->slot_descr, 20, "sdhc%d:slot%d", chip->index, slot); |
1324 | 1328 | ||
1325 | ret = pci_request_region(pdev, host->bar, host->slot_descr); | 1329 | ret = pci_request_region(pdev, host->bar, host->slot_descr); |
1326 | if (ret) | 1330 | if (ret) |
@@ -1585,6 +1589,11 @@ static int __devinit sdhci_probe(struct pci_dev *pdev, | |||
1585 | chip->num_slots = slots; | 1589 | chip->num_slots = slots; |
1586 | pci_set_drvdata(pdev, chip); | 1590 | pci_set_drvdata(pdev, chip); |
1587 | 1591 | ||
1592 | /* Add for multi controller case */ | ||
1593 | spin_lock(&index_lock); | ||
1594 | chip->index = chip_index++; | ||
1595 | spin_unlock(&index_lock); | ||
1596 | |||
1588 | for (i = 0;i < slots;i++) { | 1597 | for (i = 0;i < slots;i++) { |
1589 | ret = sdhci_probe_slot(pdev, i); | 1598 | ret = sdhci_probe_slot(pdev, i); |
1590 | if (ret) { | 1599 | if (ret) { |
@@ -1645,6 +1654,8 @@ static int __init sdhci_drv_init(void) | |||
1645 | ": Secure Digital Host Controller Interface driver\n"); | 1654 | ": Secure Digital Host Controller Interface driver\n"); |
1646 | printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n"); | 1655 | printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n"); |
1647 | 1656 | ||
1657 | spin_lock_init(&index_lock); | ||
1658 | |||
1648 | return pci_register_driver(&sdhci_driver); | 1659 | return pci_register_driver(&sdhci_driver); |
1649 | } | 1660 | } |
1650 | 1661 | ||
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index e4d77b038bfa..d5a38f1b755a 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -208,6 +208,7 @@ struct sdhci_chip { | |||
208 | 208 | ||
209 | unsigned long quirks; | 209 | unsigned long quirks; |
210 | 210 | ||
211 | int index; /* Index for chip0, chip1 ...*/ | ||
211 | int num_slots; /* Slots on controller */ | 212 | int num_slots; /* Slots on controller */ |
212 | struct sdhci_host *hosts[0]; /* Pointers to hosts */ | 213 | struct sdhci_host *hosts[0]; /* Pointers to hosts */ |
213 | }; | 214 | }; |