aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@overt.org>2007-12-29 03:11:42 -0500
committerPierre Ossman <drzeus@drzeus.cx>2008-02-08 03:02:46 -0500
commit1f090bf5245115e404103d35e7f5597bfe653aac (patch)
treeecf54a191a527a8fe3d45bc19aba3556e730b00d /drivers/mmc/host
parent488b5ec871191359b9b79262a3d48456dae7ea5f (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>
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r--drivers/mmc/host/ricoh_mmc.c97
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
42MODULE_DEVICE_TABLE(pci, pci_ids); 42MODULE_DEVICE_TABLE(pci, pci_ids);
43 43
44static 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
67static 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
44static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, 84static 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
97static void __devexit ricoh_mmc_remove(struct pci_dev *pdev) 123static 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
135static 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
149static 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
118static struct pci_driver ricoh_mmc_driver = { 163static 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/*****************************************************************************\