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

mmc: extend ricoh_mmc to support Ricoh RL5c476

This patch adds support for the Ricoh RL5c476 chip: with this
the mmc adapter that needs this disabler (R5C843) can also be
handled correctly when it sits on a RL5c476.

Signed-off-by: Frank Seidel <fseidel@suse.de>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>

authored by

Frank Seidel and committed by
Pierre Ossman
882c4916 6e996ee8

+80 -21
+80 -21
drivers/mmc/host/ricoh_mmc.c
··· 44 44 static int ricoh_mmc_disable(struct pci_dev *fw_dev) 45 45 { 46 46 u8 write_enable; 47 + u8 write_target; 47 48 u8 disable; 48 49 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 - } 50 + if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) { 51 + /* via RL5C476 */ 55 52 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); 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 + } 60 84 61 85 printk(KERN_INFO DRIVER_NAME 62 86 ": Controller is now disabled.\n"); ··· 91 67 static int ricoh_mmc_enable(struct pci_dev *fw_dev) 92 68 { 93 69 u8 write_enable; 70 + u8 write_target; 94 71 u8 disable; 95 72 96 - pci_read_config_byte(fw_dev, 0xCA, &write_enable); 97 - pci_read_config_byte(fw_dev, 0xCB, &disable); 98 - pci_write_config_byte(fw_dev, 0xCA, 0x57); 99 - pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02); 100 - pci_write_config_byte(fw_dev, 0xCA, write_enable); 73 + if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) { 74 + /* via RL5C476 */ 75 + 76 + pci_read_config_byte(fw_dev, 0x8E, &write_enable); 77 + pci_write_config_byte(fw_dev, 0x8E, 0xAA); 78 + pci_read_config_byte(fw_dev, 0x8D, &write_target); 79 + pci_write_config_byte(fw_dev, 0x8D, 0xB7); 80 + pci_read_config_byte(fw_dev, 0xB7, &disable); 81 + pci_write_config_byte(fw_dev, 0xB7, disable & ~0x02); 82 + pci_write_config_byte(fw_dev, 0x8E, write_enable); 83 + pci_write_config_byte(fw_dev, 0x8D, write_target); 84 + } else { 85 + /* via R5C832 */ 86 + 87 + pci_read_config_byte(fw_dev, 0xCA, &write_enable); 88 + pci_read_config_byte(fw_dev, 0xCB, &disable); 89 + pci_write_config_byte(fw_dev, 0xCA, 0x57); 90 + pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02); 91 + pci_write_config_byte(fw_dev, 0xCA, write_enable); 92 + } 101 93 102 94 printk(KERN_INFO DRIVER_NAME 103 95 ": Controller is now re-enabled.\n"); ··· 125 85 const struct pci_device_id *ent) 126 86 { 127 87 u8 rev; 88 + u8 ctrlfound = 0; 128 89 129 90 struct pci_dev *fw_dev = NULL; 130 91 ··· 139 98 pci_name(pdev), (int)pdev->vendor, (int)pdev->device, 140 99 (int)rev); 141 100 142 - while ((fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { 101 + while ((fw_dev = 102 + pci_get_device(PCI_VENDOR_ID_RICOH, 103 + PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) { 143 104 if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && 144 105 pdev->bus == fw_dev->bus) { 145 - if (ricoh_mmc_disable(fw_dev) != 0) { 106 + if (ricoh_mmc_disable(fw_dev) != 0) 146 107 return -ENODEV; 147 - } 148 108 149 109 pci_set_drvdata(pdev, fw_dev); 150 110 111 + ++ctrlfound; 151 112 break; 152 113 } 153 114 } 154 115 155 - if (pci_get_drvdata(pdev) == NULL) { 116 + fw_dev = NULL; 117 + 118 + while (!ctrlfound && 119 + (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, 120 + PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { 121 + if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && 122 + pdev->bus == fw_dev->bus) { 123 + if (ricoh_mmc_disable(fw_dev) != 0) 124 + return -ENODEV; 125 + 126 + pci_set_drvdata(pdev, fw_dev); 127 + 128 + ++ctrlfound; 129 + } 130 + } 131 + 132 + if (!ctrlfound) { 156 133 printk(KERN_WARNING DRIVER_NAME 157 134 ": Main firewire function not found. Cannot disable controller.\n"); 158 135 return -ENODEV; ··· 191 132 pci_set_drvdata(pdev, NULL); 192 133 } 193 134 194 - static int ricoh_mmc_suspend (struct pci_dev *pdev, pm_message_t state) 135 + static int ricoh_mmc_suspend(struct pci_dev *pdev, pm_message_t state) 195 136 { 196 137 struct pci_dev *fw_dev = NULL; 197 138 ··· 205 146 return 0; 206 147 } 207 148 208 - static int ricoh_mmc_resume (struct pci_dev *pdev) 149 + static int ricoh_mmc_resume(struct pci_dev *pdev) 209 150 { 210 151 struct pci_dev *fw_dev = NULL; 211 152