Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *	IDE tuning and bus mastering support for the CS5510/CS5520
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *	chipsets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *	The CS5510/CS5520 are slightly unusual devices. Unlike the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *	typical IDE controllers they do bus mastering with the drive in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *	PIO mode and smarter silicon.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *	The practical upshot of this is that we must always tune the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *	drive for the right PIO mode. We must also ignore all the blacklists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *	and the drive bus mastering DMA information. Also to confuse matters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *	further we can do DMA on PIO only drives.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *	DMA on the 5510 also requires we disable_hlt() during DMA on early
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *	revisions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *	*** This driver is strictly experimental ***
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *	(c) Copyright Red Hat Inc 2002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * Documentation:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *	Not publicly available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <linux/libata.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define DRV_NAME	"pata_cs5520"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define DRV_VERSION	"0.6.6"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) struct pio_clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	int address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	int assert;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	int recovery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) static const struct pio_clocks cs5520_pio_clocks[]={
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	{3, 6, 11},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	{2, 5, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	{1, 4, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	{1, 3, 2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	{1, 2, 1}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  *	cs5520_set_timings	-	program PIO timings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  *	@ap: ATA port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  *	@adev: ATA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  *	Program the PIO mode timings for the controller according to the pio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  *	clocking table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) static void cs5520_set_timings(struct ata_port *ap, struct ata_device *adev, int pio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	int slave = adev->devno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	pio -= XFER_PIO_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	/* Channel command timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	pci_write_config_byte(pdev, 0x62 + ap->port_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 				(cs5520_pio_clocks[pio].recovery << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 				(cs5520_pio_clocks[pio].assert));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	/* FIXME: should these use address ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	/* Read command timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	pci_write_config_byte(pdev, 0x64 +  4*ap->port_no + slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 				(cs5520_pio_clocks[pio].recovery << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 				(cs5520_pio_clocks[pio].assert));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	/* Write command timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	pci_write_config_byte(pdev, 0x66 +  4*ap->port_no + slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 				(cs5520_pio_clocks[pio].recovery << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 				(cs5520_pio_clocks[pio].assert));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  *	cs5520_set_piomode	-	program PIO timings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  *	@ap: ATA port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  *	@adev: ATA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  *	Program the PIO mode timings for the controller according to the pio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  *	clocking table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) static void cs5520_set_piomode(struct ata_port *ap, struct ata_device *adev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	cs5520_set_timings(ap, adev, adev->pio_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) static struct scsi_host_template cs5520_sht = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	ATA_BMDMA_SHT(DRV_NAME),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	.sg_tablesize		= LIBATA_DUMB_MAX_PRD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static struct ata_port_operations cs5520_port_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	.inherits		= &ata_bmdma_port_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	.qc_prep		= ata_bmdma_dumb_qc_prep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	.cable_detect		= ata_cable_40wire,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	.set_piomode		= cs5520_set_piomode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	static const unsigned int cmd_port[] = { 0x1F0, 0x170 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	static const unsigned int ctl_port[] = { 0x3F6, 0x376 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	struct ata_port_info pi = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		.flags		= ATA_FLAG_SLAVE_POSS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		.pio_mask	= ATA_PIO4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		.port_ops	= &cs5520_port_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	const struct ata_port_info *ppi[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	u8 pcicfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	void __iomem *iomap[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	struct ata_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	struct ata_ioports *ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	int i, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	rc = pcim_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	/* IDE port enable bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	pci_read_config_byte(pdev, 0x60, &pcicfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	/* Check if the ATA ports are enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	if ((pcicfg & 3) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	ppi[0] = ppi[1] = &ata_dummy_port_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	if (pcicfg & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		ppi[0] = &pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	if (pcicfg & 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		ppi[1] = &pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	if ((pcicfg & 0x40) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		dev_warn(&pdev->dev, "DMA mode disabled. Enabling.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	pi.mwdma_mask = id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	if (!host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	/* Perform set up for DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	if (pci_enable_device_io(pdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	/* Map IO ports and initialize host accordingly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	iomap[0] = devm_ioport_map(&pdev->dev, cmd_port[0], 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	iomap[1] = devm_ioport_map(&pdev->dev, ctl_port[0], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	iomap[2] = devm_ioport_map(&pdev->dev, cmd_port[1], 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	iomap[3] = devm_ioport_map(&pdev->dev, ctl_port[1], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	iomap[4] = pcim_iomap(pdev, 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	if (!iomap[0] || !iomap[1] || !iomap[2] || !iomap[3] || !iomap[4])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	ioaddr = &host->ports[0]->ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	ioaddr->cmd_addr = iomap[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	ioaddr->ctl_addr = iomap[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	ioaddr->altstatus_addr = iomap[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	ioaddr->bmdma_addr = iomap[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	ata_sff_std_ports(ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	ata_port_desc(host->ports[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		      "cmd 0x%x ctl 0x%x", cmd_port[0], ctl_port[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	ata_port_pbar_desc(host->ports[0], 4, 0, "bmdma");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	ioaddr = &host->ports[1]->ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	ioaddr->cmd_addr = iomap[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	ioaddr->ctl_addr = iomap[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	ioaddr->altstatus_addr = iomap[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	ioaddr->bmdma_addr = iomap[4] + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	ata_sff_std_ports(ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	ata_port_desc(host->ports[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		      "cmd 0x%x ctl 0x%x", cmd_port[1], ctl_port[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	ata_port_pbar_desc(host->ports[1], 4, 8, "bmdma");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	/* activate the host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	pci_set_master(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	rc = ata_host_start(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		static const int irq[] = { 14, 15 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		struct ata_port *ap = host->ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		if (ata_port_is_dummy(ap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		rc = devm_request_irq(&pdev->dev, irq[ap->port_no],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 				      ata_bmdma_interrupt, 0, DRV_NAME, host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		ata_port_desc(ap, "irq %d", irq[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	return ata_host_register(host, &cs5520_sht);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)  *	cs5520_reinit_one	-	device resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  *	@pdev: PCI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)  *	Do any reconfiguration work needed by a resume from RAM. We need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)  *	to restore DMA mode support on BIOSen which disabled it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static int cs5520_reinit_one(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	struct ata_host *host = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	u8 pcicfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	rc = ata_pci_device_do_resume(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	pci_read_config_byte(pdev, 0x60, &pcicfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	if ((pcicfg & 0x40) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	ata_host_resume(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)  *	cs5520_pci_device_suspend	-	device suspend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)  *	@pdev: PCI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)  *	We have to cut and waste bits from the standard method because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)  *	the 5520 is a bit odd and not just a pure ATA device. As a result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)  *	we must not disable it. The needed code is short and this avoids
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)  *	chip specific mess in the core code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) static int cs5520_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	struct ata_host *host = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	rc = ata_host_suspend(host, mesg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	pci_save_state(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* For now keep DMA off. We can set it for all but A rev CS5510 once the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)    core ATA code can handle it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static const struct pci_device_id pata_cs5520[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5520), },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static struct pci_driver cs5520_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	.name 		= DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	.id_table	= pata_cs5520,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	.probe 		= cs5520_init_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	.remove		= ata_pci_remove_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	.suspend	= cs5520_pci_device_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	.resume		= cs5520_reinit_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) module_pci_driver(cs5520_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) MODULE_AUTHOR("Alan Cox");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) MODULE_DESCRIPTION("low-level driver for Cyrix CS5510/5520");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) MODULE_DEVICE_TABLE(pci, pata_cs5520);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) MODULE_VERSION(DRV_VERSION);