Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Philip Langdale and committed by
Pierre Ossman
1f090bf5 488b5ec8

+72 -25
+72 -25
drivers/mmc/host/ricoh_mmc.c
··· 41 41 42 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 84 static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, 45 85 const struct pci_device_id *ent) 46 86 { ··· 101 61 while ((fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { 102 62 if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && 103 63 pdev->bus == fw_dev->bus) { 104 - u8 write_enable; 105 - u8 disable; 106 - 107 - pci_read_config_byte(fw_dev, 0xCB, &disable); 108 - if (disable & 0x02) { 109 - printk(KERN_INFO DRIVER_NAME 110 - ": Controller already disabled. Nothing to do.\n"); 64 + if (ricoh_mmc_disable(fw_dev) != 0) { 111 65 return -ENODEV; 112 66 } 113 67 114 - pci_read_config_byte(fw_dev, 0xCA, &write_enable); 115 - pci_write_config_byte(fw_dev, 0xCA, 0x57); 116 - pci_write_config_byte(fw_dev, 0xCB, disable | 0x02); 117 - pci_write_config_byte(fw_dev, 0xCA, write_enable); 118 - 119 68 pci_set_drvdata(pdev, fw_dev); 120 - 121 - printk(KERN_INFO DRIVER_NAME 122 - ": Controller is now disabled.\n"); 123 69 124 70 break; 125 71 } ··· 122 96 123 97 static void __devexit ricoh_mmc_remove(struct pci_dev *pdev) 124 98 { 125 - u8 write_enable; 126 - u8 disable; 127 99 struct pci_dev *fw_dev = NULL; 128 100 129 101 fw_dev = pci_get_drvdata(pdev); 130 102 BUG_ON(fw_dev == NULL); 131 103 132 - pci_read_config_byte(fw_dev, 0xCA, &write_enable); 133 - pci_read_config_byte(fw_dev, 0xCB, &disable); 134 - pci_write_config_byte(fw_dev, 0xCA, 0x57); 135 - pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02); 136 - pci_write_config_byte(fw_dev, 0xCA, write_enable); 137 - 138 - printk(KERN_INFO DRIVER_NAME 139 - ": Controller is now re-enabled.\n"); 104 + ricoh_mmc_enable(fw_dev); 140 105 141 106 pci_set_drvdata(pdev, NULL); 107 + } 108 + 109 + static int ricoh_mmc_suspend (struct pci_dev *pdev, pm_message_t state) 110 + { 111 + struct pci_dev *fw_dev = NULL; 112 + 113 + fw_dev = pci_get_drvdata(pdev); 114 + BUG_ON(fw_dev == NULL); 115 + 116 + printk(KERN_INFO DRIVER_NAME ": Suspending.\n"); 117 + 118 + ricoh_mmc_enable(fw_dev); 119 + 120 + return 0; 121 + } 122 + 123 + static int ricoh_mmc_resume (struct pci_dev *pdev) 124 + { 125 + struct pci_dev *fw_dev = NULL; 126 + 127 + fw_dev = pci_get_drvdata(pdev); 128 + BUG_ON(fw_dev == NULL); 129 + 130 + printk(KERN_INFO DRIVER_NAME ": Resuming.\n"); 131 + 132 + ricoh_mmc_disable(fw_dev); 133 + 134 + return 0; 142 135 } 143 136 144 137 static struct pci_driver ricoh_mmc_driver = { ··· 165 120 .id_table = pci_ids, 166 121 .probe = ricoh_mmc_probe, 167 122 .remove = __devexit_p(ricoh_mmc_remove), 123 + .suspend = ricoh_mmc_suspend, 124 + .resume = ricoh_mmc_resume, 168 125 }; 169 126 170 127 /*****************************************************************************\