0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include <linux/kernel.h>
0026 #include <linux/module.h>
0027 #include <linux/pci.h>
0028 #include <linux/blkdev.h>
0029 #include <linux/delay.h>
0030 #include <scsi/scsi_host.h>
0031 #include <linux/libata.h>
0032
0033 #define DRV_NAME "pata_cs5520"
0034 #define DRV_VERSION "0.6.6"
0035
0036 struct pio_clocks
0037 {
0038 int address;
0039 int assert;
0040 int recovery;
0041 };
0042
0043 static const struct pio_clocks cs5520_pio_clocks[]={
0044 {3, 6, 11},
0045 {2, 5, 6},
0046 {1, 4, 3},
0047 {1, 3, 2},
0048 {1, 2, 1}
0049 };
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 static void cs5520_set_timings(struct ata_port *ap, struct ata_device *adev, int pio)
0062 {
0063 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
0064 int slave = adev->devno;
0065
0066 pio -= XFER_PIO_0;
0067
0068
0069 pci_write_config_byte(pdev, 0x62 + ap->port_no,
0070 (cs5520_pio_clocks[pio].recovery << 4) |
0071 (cs5520_pio_clocks[pio].assert));
0072
0073
0074 pci_write_config_byte(pdev, 0x64 + 4*ap->port_no + slave,
0075 (cs5520_pio_clocks[pio].recovery << 4) |
0076 (cs5520_pio_clocks[pio].assert));
0077
0078 pci_write_config_byte(pdev, 0x66 + 4*ap->port_no + slave,
0079 (cs5520_pio_clocks[pio].recovery << 4) |
0080 (cs5520_pio_clocks[pio].assert));
0081 }
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092 static void cs5520_set_piomode(struct ata_port *ap, struct ata_device *adev)
0093 {
0094 cs5520_set_timings(ap, adev, adev->pio_mode);
0095 }
0096
0097 static struct scsi_host_template cs5520_sht = {
0098 ATA_BASE_SHT(DRV_NAME),
0099 .sg_tablesize = LIBATA_DUMB_MAX_PRD,
0100 .dma_boundary = ATA_DMA_BOUNDARY,
0101 };
0102
0103 static struct ata_port_operations cs5520_port_ops = {
0104 .inherits = &ata_bmdma_port_ops,
0105 .qc_prep = ata_bmdma_dumb_qc_prep,
0106 .cable_detect = ata_cable_40wire,
0107 .set_piomode = cs5520_set_piomode,
0108 };
0109
0110 static int cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
0111 {
0112 static const unsigned int cmd_port[] = { 0x1F0, 0x170 };
0113 static const unsigned int ctl_port[] = { 0x3F6, 0x376 };
0114 struct ata_port_info pi = {
0115 .flags = ATA_FLAG_SLAVE_POSS,
0116 .pio_mask = ATA_PIO4,
0117 .port_ops = &cs5520_port_ops,
0118 };
0119 const struct ata_port_info *ppi[2];
0120 u8 pcicfg;
0121 void __iomem *iomap[5];
0122 struct ata_host *host;
0123 struct ata_ioports *ioaddr;
0124 int i, rc;
0125
0126 rc = pcim_enable_device(pdev);
0127 if (rc)
0128 return rc;
0129
0130
0131 pci_read_config_byte(pdev, 0x60, &pcicfg);
0132
0133
0134 if ((pcicfg & 3) == 0)
0135 return -ENODEV;
0136
0137 ppi[0] = ppi[1] = &ata_dummy_port_info;
0138 if (pcicfg & 1)
0139 ppi[0] = π
0140 if (pcicfg & 2)
0141 ppi[1] = π
0142
0143 if ((pcicfg & 0x40) == 0) {
0144 dev_warn(&pdev->dev, "DMA mode disabled. Enabling.\n");
0145 pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
0146 }
0147
0148 pi.mwdma_mask = id->driver_data;
0149
0150 host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
0151 if (!host)
0152 return -ENOMEM;
0153
0154
0155 if (pci_enable_device_io(pdev)) {
0156 dev_err(&pdev->dev, "unable to configure BAR2.\n");
0157 return -ENODEV;
0158 }
0159
0160 if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
0161 dev_err(&pdev->dev, "unable to configure DMA mask.\n");
0162 return -ENODEV;
0163 }
0164
0165
0166 iomap[0] = devm_ioport_map(&pdev->dev, cmd_port[0], 8);
0167 iomap[1] = devm_ioport_map(&pdev->dev, ctl_port[0], 1);
0168 iomap[2] = devm_ioport_map(&pdev->dev, cmd_port[1], 8);
0169 iomap[3] = devm_ioport_map(&pdev->dev, ctl_port[1], 1);
0170 iomap[4] = pcim_iomap(pdev, 2, 0);
0171
0172 if (!iomap[0] || !iomap[1] || !iomap[2] || !iomap[3] || !iomap[4])
0173 return -ENOMEM;
0174
0175 ioaddr = &host->ports[0]->ioaddr;
0176 ioaddr->cmd_addr = iomap[0];
0177 ioaddr->ctl_addr = iomap[1];
0178 ioaddr->altstatus_addr = iomap[1];
0179 ioaddr->bmdma_addr = iomap[4];
0180 ata_sff_std_ports(ioaddr);
0181
0182 ata_port_desc(host->ports[0],
0183 "cmd 0x%x ctl 0x%x", cmd_port[0], ctl_port[0]);
0184 ata_port_pbar_desc(host->ports[0], 4, 0, "bmdma");
0185
0186 ioaddr = &host->ports[1]->ioaddr;
0187 ioaddr->cmd_addr = iomap[2];
0188 ioaddr->ctl_addr = iomap[3];
0189 ioaddr->altstatus_addr = iomap[3];
0190 ioaddr->bmdma_addr = iomap[4] + 8;
0191 ata_sff_std_ports(ioaddr);
0192
0193 ata_port_desc(host->ports[1],
0194 "cmd 0x%x ctl 0x%x", cmd_port[1], ctl_port[1]);
0195 ata_port_pbar_desc(host->ports[1], 4, 8, "bmdma");
0196
0197
0198 pci_set_master(pdev);
0199 rc = ata_host_start(host);
0200 if (rc)
0201 return rc;
0202
0203 for (i = 0; i < 2; i++) {
0204 static const int irq[] = { 14, 15 };
0205 struct ata_port *ap = host->ports[i];
0206
0207 if (ata_port_is_dummy(ap))
0208 continue;
0209
0210 rc = devm_request_irq(&pdev->dev, irq[ap->port_no],
0211 ata_bmdma_interrupt, 0, DRV_NAME, host);
0212 if (rc)
0213 return rc;
0214
0215 ata_port_desc(ap, "irq %d", irq[i]);
0216 }
0217
0218 return ata_host_register(host, &cs5520_sht);
0219 }
0220
0221 #ifdef CONFIG_PM_SLEEP
0222
0223
0224
0225
0226
0227
0228
0229
0230 static int cs5520_reinit_one(struct pci_dev *pdev)
0231 {
0232 struct ata_host *host = pci_get_drvdata(pdev);
0233 u8 pcicfg;
0234 int rc;
0235
0236 rc = ata_pci_device_do_resume(pdev);
0237 if (rc)
0238 return rc;
0239
0240 pci_read_config_byte(pdev, 0x60, &pcicfg);
0241 if ((pcicfg & 0x40) == 0)
0242 pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
0243
0244 ata_host_resume(host);
0245 return 0;
0246 }
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259 static int cs5520_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
0260 {
0261 struct ata_host *host = pci_get_drvdata(pdev);
0262
0263 ata_host_suspend(host, mesg);
0264
0265 pci_save_state(pdev);
0266 return 0;
0267 }
0268 #endif
0269
0270
0271
0272
0273 static const struct pci_device_id pata_cs5520[] = {
0274 { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), },
0275 { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5520), },
0276
0277 { },
0278 };
0279
0280 static struct pci_driver cs5520_pci_driver = {
0281 .name = DRV_NAME,
0282 .id_table = pata_cs5520,
0283 .probe = cs5520_init_one,
0284 .remove = ata_pci_remove_one,
0285 #ifdef CONFIG_PM_SLEEP
0286 .suspend = cs5520_pci_device_suspend,
0287 .resume = cs5520_reinit_one,
0288 #endif
0289 };
0290
0291 module_pci_driver(cs5520_pci_driver);
0292
0293 MODULE_AUTHOR("Alan Cox");
0294 MODULE_DESCRIPTION("low-level driver for Cyrix CS5510/5520");
0295 MODULE_LICENSE("GPL");
0296 MODULE_DEVICE_TABLE(pci, pata_cs5520);
0297 MODULE_VERSION(DRV_VERSION);