diff options
| author | Philip Langdale <philipl@overt.org> | 2007-12-29 03:11:42 -0500 |
|---|---|---|
| committer | Pierre Ossman <drzeus@drzeus.cx> | 2008-02-08 03:02:46 -0500 |
| commit | 1f090bf5245115e404103d35e7f5597bfe653aac (patch) | |
| tree | ecf54a191a527a8fe3d45bc19aba3556e730b00d | |
| parent | 488b5ec871191359b9b79262a3d48456dae7ea5f (diff) | |
mmc: Handle suspend/resume in Ricoh MMC disabler
As pci config space is reinitialised on a suspend/resume cycle, the
disabler needs to work its magic at resume time. For symmetry this
change also explicitly enables the controller at suspend time but
it's not strictly necessary.
Signed-off-by: Philipl Langdale <philipl@overt.org>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
| -rw-r--r-- | drivers/mmc/host/ricoh_mmc.c | 97 |
1 files changed, 72 insertions, 25 deletions
diff --git a/drivers/mmc/host/ricoh_mmc.c b/drivers/mmc/host/ricoh_mmc.c index 1e8704533bc5..898e7991caef 100644 --- a/drivers/mmc/host/ricoh_mmc.c +++ b/drivers/mmc/host/ricoh_mmc.c | |||
| @@ -41,6 +41,46 @@ 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 disable; | ||
| 48 | |||
| 49 | pci_read_config_byte(fw_dev, 0xCB, &disable); | ||
| 50 | if (disable & 0x02) { | ||
| 51 | printk(KERN_INFO DRIVER_NAME | ||
| 52 | ": Controller already disabled. Nothing to do.\n"); | ||
| 53 | return -ENODEV; | ||
| 54 | } | ||
| 55 | |||
| 56 | pci_read_config_byte(fw_dev, 0xCA, &write_enable); | ||
| 57 | pci_write_config_byte(fw_dev, 0xCA, 0x57); | ||
| 58 | pci_write_config_byte(fw_dev, 0xCB, disable | 0x02); | ||
| 59 | pci_write_config_byte(fw_dev, 0xCA, write_enable); | ||
| 60 | |||
| 61 | printk(KERN_INFO DRIVER_NAME | ||
| 62 | ": Controller is now disabled.\n"); | ||
| 63 | |||
| 64 | return 0; | ||
| 65 | } | ||
| 66 | |||
| 67 | static int ricoh_mmc_enable(struct pci_dev *fw_dev) | ||
| 68 | { | ||
| 69 | u8 write_enable; | ||
| 70 | u8 disable; | ||
| 71 | |||
| 72 | pci_read_config_byte(fw_dev, 0xCA, &write_enable); | ||
| 73 | pci_read_config_byte(fw_dev, 0xCB, &disable); | ||
| 74 | pci_write_config_byte(fw_dev, 0xCA, 0x57); | ||
| 75 | pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02); | ||
| 76 | pci_write_config_byte(fw_dev, 0xCA, write_enable); | ||
| 77 | |||
| 78 | printk(KERN_INFO DRIVER_NAME | ||
| 79 | ": Controller is now re-enabled.\n"); | ||
| 80 | |||
| 81 | return 0; | ||
| 82 | } | ||
| 83 | |||
| 44 | static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, | 84 | static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, |
| 45 | const struct pci_device_id *ent) | 85 | const struct pci_device_id *ent) |
| 46 | { | 86 | { |
| @@ -61,26 +101,12 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, | |||
| 61 | while ((fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { | 101 | while ((fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { |
| 62 | if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && | 102 | if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && |
| 63 | pdev->bus == fw_dev->bus) { | 103 | pdev->bus == fw_dev->bus) { |
| 64 | u8 write_enable; | 104 | 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; | 105 | return -ENODEV; |
| 72 | } | 106 | } |
| 73 | 107 | ||
| 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 | |||
| 79 | pci_set_drvdata(pdev, fw_dev); | 108 | pci_set_drvdata(pdev, fw_dev); |
| 80 | 109 | ||
| 81 | printk(KERN_INFO DRIVER_NAME | ||
| 82 | ": Controller is now disabled.\n"); | ||
| 83 | |||
| 84 | break; | 110 | break; |
| 85 | } | 111 | } |
| 86 | } | 112 | } |
| @@ -96,30 +122,51 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, | |||
| 96 | 122 | ||
| 97 | static void __devexit ricoh_mmc_remove(struct pci_dev *pdev) | 123 | static void __devexit ricoh_mmc_remove(struct pci_dev *pdev) |
| 98 | { | 124 | { |
| 99 | u8 write_enable; | ||
| 100 | u8 disable; | ||
| 101 | struct pci_dev *fw_dev = NULL; | 125 | struct pci_dev *fw_dev = NULL; |
| 102 | 126 | ||
| 103 | fw_dev = pci_get_drvdata(pdev); | 127 | fw_dev = pci_get_drvdata(pdev); |
| 104 | BUG_ON(fw_dev == NULL); | 128 | BUG_ON(fw_dev == NULL); |
| 105 | 129 | ||
| 106 | pci_read_config_byte(fw_dev, 0xCA, &write_enable); | 130 | 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 | 131 | ||
| 115 | pci_set_drvdata(pdev, NULL); | 132 | pci_set_drvdata(pdev, NULL); |
| 116 | } | 133 | } |
| 117 | 134 | ||
| 135 | static int ricoh_mmc_suspend (struct pci_dev *pdev, pm_message_t state) | ||
| 136 | { | ||
| 137 | struct pci_dev *fw_dev = NULL; | ||
| 138 | |||
| 139 | fw_dev = pci_get_drvdata(pdev); | ||
| 140 | BUG_ON(fw_dev == NULL); | ||
| 141 | |||
| 142 | printk(KERN_INFO DRIVER_NAME ": Suspending.\n"); | ||
| 143 | |||
| 144 | ricoh_mmc_enable(fw_dev); | ||
| 145 | |||
| 146 | return 0; | ||
| 147 | } | ||
| 148 | |||
| 149 | static int ricoh_mmc_resume (struct pci_dev *pdev) | ||
| 150 | { | ||
| 151 | struct pci_dev *fw_dev = NULL; | ||
| 152 | |||
| 153 | fw_dev = pci_get_drvdata(pdev); | ||
| 154 | BUG_ON(fw_dev == NULL); | ||
| 155 | |||
| 156 | printk(KERN_INFO DRIVER_NAME ": Resuming.\n"); | ||
| 157 | |||
| 158 | ricoh_mmc_disable(fw_dev); | ||
| 159 | |||
| 160 | return 0; | ||
| 161 | } | ||
| 162 | |||
| 118 | static struct pci_driver ricoh_mmc_driver = { | 163 | static struct pci_driver ricoh_mmc_driver = { |
| 119 | .name = DRIVER_NAME, | 164 | .name = DRIVER_NAME, |
| 120 | .id_table = pci_ids, | 165 | .id_table = pci_ids, |
| 121 | .probe = ricoh_mmc_probe, | 166 | .probe = ricoh_mmc_probe, |
| 122 | .remove = __devexit_p(ricoh_mmc_remove), | 167 | .remove = __devexit_p(ricoh_mmc_remove), |
| 168 | .suspend = ricoh_mmc_suspend, | ||
| 169 | .resume = ricoh_mmc_resume, | ||
| 123 | }; | 170 | }; |
| 124 | 171 | ||
| 125 | /*****************************************************************************\ | 172 | /*****************************************************************************\ |
