xref: /openbmc/linux/drivers/ata/pata_ns87415.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
109c434b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2c4b5b7b6SAlan Cox /*
32e34ae02SHelge Deller  *    pata_ns87415.c - NS87415 (and PARISC SUPERIO 87560) PATA
4c4b5b7b6SAlan Cox  *
5ab771630SAlan Cox  *	(C) 2005 Red Hat <alan@lxorguk.ukuu.org.uk>
6c4b5b7b6SAlan Cox  *
7c4b5b7b6SAlan Cox  *    This is a fairly generic MWDMA controller. It has some limitations
8c4b5b7b6SAlan Cox  *    as it requires timing reloads on PIO/DMA transitions but it is otherwise
9c4b5b7b6SAlan Cox  *    fairly well designed.
10c4b5b7b6SAlan Cox  *
11c4b5b7b6SAlan Cox  *    This driver assumes the firmware has left the chip in a valid ST506
12c4b5b7b6SAlan Cox  *    compliant state, either legacy IRQ 14/15 or native INTA shared. You
13c4b5b7b6SAlan Cox  *    may need to add platform code if your system fails to do this.
14c4b5b7b6SAlan Cox  *
15c4b5b7b6SAlan Cox  *    The same cell appears in the 87560 controller used by some PARISC
16c4b5b7b6SAlan Cox  *    systems. This has its own special mountain of errata.
17c4b5b7b6SAlan Cox  *
18c4b5b7b6SAlan Cox  *    TODO:
19c4b5b7b6SAlan Cox  *	Get someone to test on SPARC
20c4b5b7b6SAlan Cox  *	Implement lazy pio/dma switching for better performance
21c4b5b7b6SAlan Cox  *	8bit shared timing.
22c4b5b7b6SAlan Cox  *	See if we need to kill the FIFO for ATAPI
23c4b5b7b6SAlan Cox  */
24c4b5b7b6SAlan Cox 
25c4b5b7b6SAlan Cox #include <linux/kernel.h>
26c4b5b7b6SAlan Cox #include <linux/module.h>
27c4b5b7b6SAlan Cox #include <linux/pci.h>
28c4b5b7b6SAlan Cox #include <linux/blkdev.h>
29c4b5b7b6SAlan Cox #include <linux/delay.h>
30c4b5b7b6SAlan Cox #include <linux/device.h>
31c4b5b7b6SAlan Cox #include <scsi/scsi_host.h>
32c4b5b7b6SAlan Cox #include <linux/libata.h>
33c4b5b7b6SAlan Cox #include <linux/ata.h>
34c4b5b7b6SAlan Cox 
35c4b5b7b6SAlan Cox #define DRV_NAME	"pata_ns87415"
36c4b5b7b6SAlan Cox #define DRV_VERSION	"0.0.1"
37c4b5b7b6SAlan Cox 
38c4b5b7b6SAlan Cox /**
39c4b5b7b6SAlan Cox  *	ns87415_set_mode - Initialize host controller mode timings
40c4b5b7b6SAlan Cox  *	@ap: Port whose timings we are configuring
41c4b5b7b6SAlan Cox  *	@adev: Device whose timings we are configuring
42c4b5b7b6SAlan Cox  *	@mode: Mode to set
43c4b5b7b6SAlan Cox  *
44c4b5b7b6SAlan Cox  *	Program the mode registers for this controller, channel and
45c4b5b7b6SAlan Cox  *	device. Because the chip is quite an old design we have to do this
46c4b5b7b6SAlan Cox  *	for PIO/DMA switches.
47c4b5b7b6SAlan Cox  *
48c4b5b7b6SAlan Cox  *	LOCKING:
49c4b5b7b6SAlan Cox  *	None (inherited from caller).
50c4b5b7b6SAlan Cox  */
51c4b5b7b6SAlan Cox 
ns87415_set_mode(struct ata_port * ap,struct ata_device * adev,u8 mode)52c4b5b7b6SAlan Cox static void ns87415_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mode)
53c4b5b7b6SAlan Cox {
54c4b5b7b6SAlan Cox 	struct pci_dev *dev	= to_pci_dev(ap->host->dev);
55c4b5b7b6SAlan Cox 	int unit		= 2 * ap->port_no + adev->devno;
56c4b5b7b6SAlan Cox 	int timing		= 0x44 + 2 * unit;
57c4b5b7b6SAlan Cox 	unsigned long T		= 1000000000 / 33333;	/* PCI clocks */
58c4b5b7b6SAlan Cox 	struct ata_timing t;
59c4b5b7b6SAlan Cox 	u16 clocking;
60c4b5b7b6SAlan Cox 	u8 iordy;
61c4b5b7b6SAlan Cox 	u8 status;
62c4b5b7b6SAlan Cox 
63c4b5b7b6SAlan Cox 	/* Timing register format is 17 - low nybble read timing with
64c4b5b7b6SAlan Cox 	   the high nybble being 16 - x for recovery time in PCI clocks */
65c4b5b7b6SAlan Cox 
66c4b5b7b6SAlan Cox 	ata_timing_compute(adev, adev->pio_mode, &t, T, 0);
67c4b5b7b6SAlan Cox 
6807633b5dSHarvey Harrison 	clocking = 17 - clamp_val(t.active, 2, 17);
6907633b5dSHarvey Harrison 	clocking |= (16 - clamp_val(t.recover, 1, 16)) << 4;
70c4b5b7b6SAlan Cox  	/* Use the same timing for read and write bytes */
71c4b5b7b6SAlan Cox 	clocking |= (clocking << 8);
72c4b5b7b6SAlan Cox 	pci_write_config_word(dev, timing, clocking);
73c4b5b7b6SAlan Cox 
74c4b5b7b6SAlan Cox 	/* Set the IORDY enable versus DMA enable on or off properly */
75c4b5b7b6SAlan Cox 	pci_read_config_byte(dev, 0x42, &iordy);
76c4b5b7b6SAlan Cox 	iordy &= ~(1 << (4 + unit));
77c4b5b7b6SAlan Cox 	if (mode >= XFER_MW_DMA_0 || !ata_pio_need_iordy(adev))
78c4b5b7b6SAlan Cox 		iordy |= (1 << (4 + unit));
79c4b5b7b6SAlan Cox 
80c4b5b7b6SAlan Cox 	/* Paranoia: We shouldn't ever get here with busy write buffers
81c4b5b7b6SAlan Cox 	   but if so wait */
82c4b5b7b6SAlan Cox 
83c4b5b7b6SAlan Cox 	pci_read_config_byte(dev, 0x43, &status);
84c4b5b7b6SAlan Cox 	while (status & 0x03) {
85c4b5b7b6SAlan Cox 		udelay(1);
86c4b5b7b6SAlan Cox 		pci_read_config_byte(dev, 0x43, &status);
87c4b5b7b6SAlan Cox 	}
88c4b5b7b6SAlan Cox 	/* Flip the IORDY/DMA bits now we are sure the write buffers are
89c4b5b7b6SAlan Cox 	   clear */
90c4b5b7b6SAlan Cox 	pci_write_config_byte(dev, 0x42, iordy);
91c4b5b7b6SAlan Cox 
92c4b5b7b6SAlan Cox 	/* TODO: Set byte 54 command timing to the best 8bit
93c4b5b7b6SAlan Cox 	   mode shared by all four devices */
94c4b5b7b6SAlan Cox }
95c4b5b7b6SAlan Cox 
96c4b5b7b6SAlan Cox /**
97c4b5b7b6SAlan Cox  *	ns87415_set_piomode - Initialize host controller PATA PIO timings
98c4b5b7b6SAlan Cox  *	@ap: Port whose timings we are configuring
99c4b5b7b6SAlan Cox  *	@adev: Device to program
100c4b5b7b6SAlan Cox  *
101c4b5b7b6SAlan Cox  *	Set PIO mode for device, in host controller PCI config space.
102c4b5b7b6SAlan Cox  *
103c4b5b7b6SAlan Cox  *	LOCKING:
104c4b5b7b6SAlan Cox  *	None (inherited from caller).
105c4b5b7b6SAlan Cox  */
106c4b5b7b6SAlan Cox 
ns87415_set_piomode(struct ata_port * ap,struct ata_device * adev)107c4b5b7b6SAlan Cox static void ns87415_set_piomode(struct ata_port *ap, struct ata_device *adev)
108c4b5b7b6SAlan Cox {
109c4b5b7b6SAlan Cox 	ns87415_set_mode(ap, adev, adev->pio_mode);
110c4b5b7b6SAlan Cox }
111c4b5b7b6SAlan Cox 
112c4b5b7b6SAlan Cox /**
113c4b5b7b6SAlan Cox  *	ns87415_bmdma_setup		-	Set up DMA
114c4b5b7b6SAlan Cox  *	@qc: Command block
115c4b5b7b6SAlan Cox  *
1162b0a9946SBhaskar Chowdhury  *	Set up for bus mastering DMA. We have to do this ourselves
117c4b5b7b6SAlan Cox  *	rather than use the helper due to a chip erratum
118c4b5b7b6SAlan Cox  */
119c4b5b7b6SAlan Cox 
ns87415_bmdma_setup(struct ata_queued_cmd * qc)120c4b5b7b6SAlan Cox static void ns87415_bmdma_setup(struct ata_queued_cmd *qc)
121c4b5b7b6SAlan Cox {
122c4b5b7b6SAlan Cox 	struct ata_port *ap = qc->ap;
123c4b5b7b6SAlan Cox 	unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
124c4b5b7b6SAlan Cox 	u8 dmactl;
125c4b5b7b6SAlan Cox 
126c4b5b7b6SAlan Cox 	/* load PRD table addr. */
127c4b5b7b6SAlan Cox 	mb();	/* make sure PRD table writes are visible to controller */
128f60d7011STejun Heo 	iowrite32(ap->bmdma_prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
129c4b5b7b6SAlan Cox 
130c4b5b7b6SAlan Cox 	/* specify data direction, triple-check start bit is clear */
131c4b5b7b6SAlan Cox 	dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
132c4b5b7b6SAlan Cox 	dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
133c4b5b7b6SAlan Cox 	/* Due to an erratum we need to write these bits to the wrong
134c4b5b7b6SAlan Cox 	   place - which does save us an I/O bizarrely */
135c4b5b7b6SAlan Cox 	dmactl |= ATA_DMA_INTR | ATA_DMA_ERR;
136c4b5b7b6SAlan Cox 	if (!rw)
137c4b5b7b6SAlan Cox 		dmactl |= ATA_DMA_WR;
138c4b5b7b6SAlan Cox 	iowrite8(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
139c4b5b7b6SAlan Cox 	/* issue r/w command */
1405682ed33STejun Heo 	ap->ops->sff_exec_command(ap, &qc->tf);
141c4b5b7b6SAlan Cox }
142c4b5b7b6SAlan Cox 
143c4b5b7b6SAlan Cox /**
144c4b5b7b6SAlan Cox  *	ns87415_bmdma_start		-	Begin DMA transfer
145c4b5b7b6SAlan Cox  *	@qc: Command block
146c4b5b7b6SAlan Cox  *
147c4b5b7b6SAlan Cox  *	Switch the timings for the chip and set up for a DMA transfer
148c4b5b7b6SAlan Cox  *	before the DMA burst begins.
149c4b5b7b6SAlan Cox  *
150c4b5b7b6SAlan Cox  *	FIXME: We should do lazy switching on bmdma_start versus
151c4b5b7b6SAlan Cox  *	ata_pio_data_xfer for better performance.
152c4b5b7b6SAlan Cox  */
153c4b5b7b6SAlan Cox 
ns87415_bmdma_start(struct ata_queued_cmd * qc)154c4b5b7b6SAlan Cox static void ns87415_bmdma_start(struct ata_queued_cmd *qc)
155c4b5b7b6SAlan Cox {
156c4b5b7b6SAlan Cox 	ns87415_set_mode(qc->ap, qc->dev, qc->dev->dma_mode);
157c4b5b7b6SAlan Cox 	ata_bmdma_start(qc);
158c4b5b7b6SAlan Cox }
159c4b5b7b6SAlan Cox 
160c4b5b7b6SAlan Cox /**
161c4b5b7b6SAlan Cox  *	ns87415_bmdma_stop		-	End DMA transfer
162c4b5b7b6SAlan Cox  *	@qc: Command block
163c4b5b7b6SAlan Cox  *
164c4b5b7b6SAlan Cox  *	End DMA mode and switch the controller back into PIO mode
165c4b5b7b6SAlan Cox  */
166c4b5b7b6SAlan Cox 
ns87415_bmdma_stop(struct ata_queued_cmd * qc)167c4b5b7b6SAlan Cox static void ns87415_bmdma_stop(struct ata_queued_cmd *qc)
168c4b5b7b6SAlan Cox {
169c4b5b7b6SAlan Cox 	ata_bmdma_stop(qc);
170c4b5b7b6SAlan Cox 	ns87415_set_mode(qc->ap, qc->dev, qc->dev->pio_mode);
171c4b5b7b6SAlan Cox }
172c4b5b7b6SAlan Cox 
173c4b5b7b6SAlan Cox /**
1749363c382STejun Heo  *	ns87415_irq_clear		-	Clear interrupt
175c4b5b7b6SAlan Cox  *	@ap: Channel to clear
176c4b5b7b6SAlan Cox  *
1772b0a9946SBhaskar Chowdhury  *	Erratum: Due to a chip bug registers 02 and 0A bit 1 and 2 (the
178c4b5b7b6SAlan Cox  *	error bits) are reset by writing to register 00 or 08.
179c4b5b7b6SAlan Cox  */
180c4b5b7b6SAlan Cox 
ns87415_irq_clear(struct ata_port * ap)1819363c382STejun Heo static void ns87415_irq_clear(struct ata_port *ap)
182c4b5b7b6SAlan Cox {
183c4b5b7b6SAlan Cox 	void __iomem *mmio = ap->ioaddr.bmdma_addr;
184c4b5b7b6SAlan Cox 
185c4b5b7b6SAlan Cox 	if (!mmio)
186c4b5b7b6SAlan Cox 		return;
187c4b5b7b6SAlan Cox 	iowrite8((ioread8(mmio + ATA_DMA_CMD) | ATA_DMA_INTR | ATA_DMA_ERR),
188c4b5b7b6SAlan Cox 			mmio + ATA_DMA_CMD);
189c4b5b7b6SAlan Cox }
190c4b5b7b6SAlan Cox 
191c4b5b7b6SAlan Cox /**
192c4b5b7b6SAlan Cox  *	ns87415_check_atapi_dma		-	ATAPI DMA filter
193c4b5b7b6SAlan Cox  *	@qc: Command block
194c4b5b7b6SAlan Cox  *
195c4b5b7b6SAlan Cox  *	Disable ATAPI DMA (for now). We may be able to do DMA if we
196c4b5b7b6SAlan Cox  *	kill the prefetching. This isn't clear.
197c4b5b7b6SAlan Cox  */
198c4b5b7b6SAlan Cox 
ns87415_check_atapi_dma(struct ata_queued_cmd * qc)199c4b5b7b6SAlan Cox static int ns87415_check_atapi_dma(struct ata_queued_cmd *qc)
200c4b5b7b6SAlan Cox {
201c4b5b7b6SAlan Cox 	return -EOPNOTSUPP;
202c4b5b7b6SAlan Cox }
203c4b5b7b6SAlan Cox 
204c4b5b7b6SAlan Cox #if defined(CONFIG_SUPERIO)
205c4b5b7b6SAlan Cox 
206c4b5b7b6SAlan Cox /* SUPERIO 87560 is a PoS chip that NatSem denies exists.
207c4b5b7b6SAlan Cox  * Unfortunately, it's built-in on all Astro-based PA-RISC workstations
208c4b5b7b6SAlan Cox  * which use the integrated NS87514 cell for CD-ROM support.
209c4b5b7b6SAlan Cox  * i.e we have to support for CD-ROM installs.
210c4b5b7b6SAlan Cox  * See drivers/parisc/superio.c for more gory details.
211c4b5b7b6SAlan Cox  *
212c4b5b7b6SAlan Cox  * Workarounds taken from drivers/ide/pci/ns87415.c
213c4b5b7b6SAlan Cox  */
214c4b5b7b6SAlan Cox 
215c4b5b7b6SAlan Cox #include <asm/superio.h>
216c4b5b7b6SAlan Cox 
217a9efacbaSFrank Lichtenheld #define SUPERIO_IDE_MAX_RETRIES 25
218a9efacbaSFrank Lichtenheld 
219c4b5b7b6SAlan Cox /**
220c4b5b7b6SAlan Cox  *	ns87560_read_buggy	-	workaround buggy Super I/O chip
221c4b5b7b6SAlan Cox  *	@port: Port to read
222c4b5b7b6SAlan Cox  *
223c4b5b7b6SAlan Cox  *	Work around chipset problems in the 87560 SuperIO chip
224c4b5b7b6SAlan Cox  */
225c4b5b7b6SAlan Cox 
ns87560_read_buggy(void __iomem * port)226c4b5b7b6SAlan Cox static u8 ns87560_read_buggy(void __iomem *port)
227c4b5b7b6SAlan Cox {
228c4b5b7b6SAlan Cox 	u8 tmp;
229c4b5b7b6SAlan Cox 	int retries = SUPERIO_IDE_MAX_RETRIES;
230c4b5b7b6SAlan Cox 	do {
231c4b5b7b6SAlan Cox 		tmp = ioread8(port);
232c4b5b7b6SAlan Cox 		if (tmp != 0)
233c4b5b7b6SAlan Cox 			return tmp;
234c4b5b7b6SAlan Cox 		udelay(50);
235c4b5b7b6SAlan Cox 	} while(retries-- > 0);
236c4b5b7b6SAlan Cox 	return tmp;
237c4b5b7b6SAlan Cox }
238c4b5b7b6SAlan Cox 
239c4b5b7b6SAlan Cox /**
240c4b5b7b6SAlan Cox  *	ns87560_check_status
241c4b5b7b6SAlan Cox  *	@ap: channel to check
242c4b5b7b6SAlan Cox  *
243c4b5b7b6SAlan Cox  *	Return the status of the channel working around the
244c4b5b7b6SAlan Cox  *	87560 flaws.
245c4b5b7b6SAlan Cox  */
246c4b5b7b6SAlan Cox 
ns87560_check_status(struct ata_port * ap)247c4b5b7b6SAlan Cox static u8 ns87560_check_status(struct ata_port *ap)
248c4b5b7b6SAlan Cox {
249c4b5b7b6SAlan Cox 	return ns87560_read_buggy(ap->ioaddr.status_addr);
250c4b5b7b6SAlan Cox }
251c4b5b7b6SAlan Cox 
252c4b5b7b6SAlan Cox /**
253c4b5b7b6SAlan Cox  *	ns87560_tf_read - input device's ATA taskfile shadow registers
254c4b5b7b6SAlan Cox  *	@ap: Port from which input is read
255c4b5b7b6SAlan Cox  *	@tf: ATA taskfile register set for storing input
256c4b5b7b6SAlan Cox  *
257c4b5b7b6SAlan Cox  *	Reads ATA taskfile registers for currently-selected device
258c4b5b7b6SAlan Cox  *	into @tf. Work around the 87560 bugs.
259c4b5b7b6SAlan Cox  *
260c4b5b7b6SAlan Cox  *	LOCKING:
261c4b5b7b6SAlan Cox  *	Inherited from caller.
262c4b5b7b6SAlan Cox  */
ns87560_tf_read(struct ata_port * ap,struct ata_taskfile * tf)263*3fc2febbSArnd Bergmann static void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
264c4b5b7b6SAlan Cox {
265c4b5b7b6SAlan Cox 	struct ata_ioports *ioaddr = &ap->ioaddr;
266c4b5b7b6SAlan Cox 
267efcef265SSergey Shtylyov 	tf->status = ns87560_check_status(ap);
268efcef265SSergey Shtylyov 	tf->error = ioread8(ioaddr->error_addr);
269c4b5b7b6SAlan Cox 	tf->nsect = ioread8(ioaddr->nsect_addr);
270c4b5b7b6SAlan Cox 	tf->lbal = ioread8(ioaddr->lbal_addr);
271c4b5b7b6SAlan Cox 	tf->lbam = ioread8(ioaddr->lbam_addr);
272c4b5b7b6SAlan Cox 	tf->lbah = ioread8(ioaddr->lbah_addr);
273c4b5b7b6SAlan Cox 	tf->device = ns87560_read_buggy(ioaddr->device_addr);
274c4b5b7b6SAlan Cox 
275c4b5b7b6SAlan Cox 	if (tf->flags & ATA_TFLAG_LBA48) {
276c4b5b7b6SAlan Cox 		iowrite8(tf->ctl | ATA_HOB, ioaddr->ctl_addr);
277c4b5b7b6SAlan Cox 		tf->hob_feature = ioread8(ioaddr->error_addr);
278c4b5b7b6SAlan Cox 		tf->hob_nsect = ioread8(ioaddr->nsect_addr);
279c4b5b7b6SAlan Cox 		tf->hob_lbal = ioread8(ioaddr->lbal_addr);
280c4b5b7b6SAlan Cox 		tf->hob_lbam = ioread8(ioaddr->lbam_addr);
281c4b5b7b6SAlan Cox 		tf->hob_lbah = ioread8(ioaddr->lbah_addr);
282c4b5b7b6SAlan Cox 		iowrite8(tf->ctl, ioaddr->ctl_addr);
283c4b5b7b6SAlan Cox 		ap->last_ctl = tf->ctl;
284c4b5b7b6SAlan Cox 	}
285c4b5b7b6SAlan Cox }
286c4b5b7b6SAlan Cox 
287c4b5b7b6SAlan Cox /**
288c4b5b7b6SAlan Cox  *	ns87560_bmdma_status
289c4b5b7b6SAlan Cox  *	@ap: channel to check
290c4b5b7b6SAlan Cox  *
291c4b5b7b6SAlan Cox  *	Return the DMA status of the channel working around the
292c4b5b7b6SAlan Cox  *	87560 flaws.
293c4b5b7b6SAlan Cox  */
294c4b5b7b6SAlan Cox 
ns87560_bmdma_status(struct ata_port * ap)295c4b5b7b6SAlan Cox static u8 ns87560_bmdma_status(struct ata_port *ap)
296c4b5b7b6SAlan Cox {
297c4b5b7b6SAlan Cox 	return ns87560_read_buggy(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
298c4b5b7b6SAlan Cox }
299c4b5b7b6SAlan Cox #endif		/* 87560 SuperIO Support */
300c4b5b7b6SAlan Cox 
301029cfd6bSTejun Heo static struct ata_port_operations ns87415_pata_ops = {
302029cfd6bSTejun Heo 	.inherits		= &ata_bmdma_port_ops,
303c4b5b7b6SAlan Cox 
304c4b5b7b6SAlan Cox 	.check_atapi_dma	= ns87415_check_atapi_dma,
305c4b5b7b6SAlan Cox 	.bmdma_setup		= ns87415_bmdma_setup,
306c4b5b7b6SAlan Cox 	.bmdma_start		= ns87415_bmdma_start,
307c4b5b7b6SAlan Cox 	.bmdma_stop		= ns87415_bmdma_stop,
3085682ed33STejun Heo 	.sff_irq_clear		= ns87415_irq_clear,
309c4b5b7b6SAlan Cox 
310029cfd6bSTejun Heo 	.cable_detect		= ata_cable_40wire,
311029cfd6bSTejun Heo 	.set_piomode		= ns87415_set_piomode,
312c4b5b7b6SAlan Cox };
313c4b5b7b6SAlan Cox 
314029cfd6bSTejun Heo #if defined(CONFIG_SUPERIO)
315029cfd6bSTejun Heo static struct ata_port_operations ns87560_pata_ops = {
316029cfd6bSTejun Heo 	.inherits		= &ns87415_pata_ops,
3175682ed33STejun Heo 	.sff_tf_read		= ns87560_tf_read,
3185682ed33STejun Heo 	.sff_check_status	= ns87560_check_status,
319029cfd6bSTejun Heo 	.bmdma_status		= ns87560_bmdma_status,
320029cfd6bSTejun Heo };
321029cfd6bSTejun Heo #endif
322029cfd6bSTejun Heo 
32325df73d9SBart Van Assche static const struct scsi_host_template ns87415_sht = {
32468d1d07bSTejun Heo 	ATA_BMDMA_SHT(DRV_NAME),
325c4b5b7b6SAlan Cox };
326c4b5b7b6SAlan Cox 
ns87415_fixup(struct pci_dev * pdev)327a809c687SBartlomiej Zolnierkiewicz static void ns87415_fixup(struct pci_dev *pdev)
328a809c687SBartlomiej Zolnierkiewicz {
329a809c687SBartlomiej Zolnierkiewicz 	/* Select 512 byte sectors */
330a809c687SBartlomiej Zolnierkiewicz 	pci_write_config_byte(pdev, 0x55, 0xEE);
331a809c687SBartlomiej Zolnierkiewicz 	/* Select PIO0 8bit clocking */
332a809c687SBartlomiej Zolnierkiewicz 	pci_write_config_byte(pdev, 0x54, 0xB7);
333a809c687SBartlomiej Zolnierkiewicz }
334c4b5b7b6SAlan Cox 
335c4b5b7b6SAlan Cox /**
336c4b5b7b6SAlan Cox  *	ns87415_init_one - Register 87415 ATA PCI device with kernel services
337c4b5b7b6SAlan Cox  *	@pdev: PCI device to register
338c4b5b7b6SAlan Cox  *	@ent: Entry in ns87415_pci_tbl matching with @pdev
339c4b5b7b6SAlan Cox  *
340c4b5b7b6SAlan Cox  *	Called from kernel PCI layer.  We probe for combined mode (sigh),
341c4b5b7b6SAlan Cox  *	and then hand over control to libata, for it to do the rest.
342c4b5b7b6SAlan Cox  *
343c4b5b7b6SAlan Cox  *	LOCKING:
344c4b5b7b6SAlan Cox  *	Inherited from PCI layer (may sleep).
345c4b5b7b6SAlan Cox  *
346c4b5b7b6SAlan Cox  *	RETURNS:
347c4b5b7b6SAlan Cox  *	Zero on success, or -ERRNO value.
348c4b5b7b6SAlan Cox  */
349c4b5b7b6SAlan Cox 
ns87415_init_one(struct pci_dev * pdev,const struct pci_device_id * ent)350c4b5b7b6SAlan Cox static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
351c4b5b7b6SAlan Cox {
352c4b5b7b6SAlan Cox 	static const struct ata_port_info info = {
353c4b5b7b6SAlan Cox 		.flags		= ATA_FLAG_SLAVE_POSS,
35414bdef98SErik Inge Bolsø 		.pio_mask	= ATA_PIO4,
35514bdef98SErik Inge Bolsø 		.mwdma_mask	= ATA_MWDMA2,
356c4b5b7b6SAlan Cox 		.port_ops	= &ns87415_pata_ops,
357c4b5b7b6SAlan Cox 	};
358c4b5b7b6SAlan Cox 	const struct ata_port_info *ppi[] = { &info, NULL };
359f08048e9STejun Heo 	int rc;
360c4b5b7b6SAlan Cox #if defined(CONFIG_SUPERIO)
361c4b5b7b6SAlan Cox 	static const struct ata_port_info info87560 = {
362c4b5b7b6SAlan Cox 		.flags		= ATA_FLAG_SLAVE_POSS,
36314bdef98SErik Inge Bolsø 		.pio_mask	= ATA_PIO4,
36414bdef98SErik Inge Bolsø 		.mwdma_mask	= ATA_MWDMA2,
365c4b5b7b6SAlan Cox 		.port_ops	= &ns87560_pata_ops,
366c4b5b7b6SAlan Cox 	};
367c4b5b7b6SAlan Cox 
368c4b5b7b6SAlan Cox 	if (PCI_SLOT(pdev->devfn) == 0x0E)
369c4b5b7b6SAlan Cox 		ppi[0] = &info87560;
370c4b5b7b6SAlan Cox #endif
37106296a1eSJoe Perches 	ata_print_version_once(&pdev->dev, DRV_VERSION);
372f08048e9STejun Heo 
373f08048e9STejun Heo 	rc = pcim_enable_device(pdev);
374f08048e9STejun Heo 	if (rc)
375f08048e9STejun Heo 		return rc;
376f08048e9STejun Heo 
377a809c687SBartlomiej Zolnierkiewicz 	ns87415_fixup(pdev);
378a809c687SBartlomiej Zolnierkiewicz 
3791c5afdf7STejun Heo 	return ata_pci_bmdma_init_one(pdev, ppi, &ns87415_sht, NULL, 0);
380c4b5b7b6SAlan Cox }
381c4b5b7b6SAlan Cox 
382c4b5b7b6SAlan Cox static const struct pci_device_id ns87415_pci_tbl[] = {
383c4b5b7b6SAlan Cox 	{ PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_87415), },
384c4b5b7b6SAlan Cox 
385c4b5b7b6SAlan Cox 	{ }	/* terminate list */
386c4b5b7b6SAlan Cox };
387c4b5b7b6SAlan Cox 
38858eb8cd5SBartlomiej Zolnierkiewicz #ifdef CONFIG_PM_SLEEP
ns87415_reinit_one(struct pci_dev * pdev)389a809c687SBartlomiej Zolnierkiewicz static int ns87415_reinit_one(struct pci_dev *pdev)
390a809c687SBartlomiej Zolnierkiewicz {
3910a86e1c8SJingoo Han 	struct ata_host *host = pci_get_drvdata(pdev);
392a809c687SBartlomiej Zolnierkiewicz 	int rc;
393a809c687SBartlomiej Zolnierkiewicz 
394a809c687SBartlomiej Zolnierkiewicz 	rc = ata_pci_device_do_resume(pdev);
395a809c687SBartlomiej Zolnierkiewicz 	if (rc)
396a809c687SBartlomiej Zolnierkiewicz 		return rc;
397a809c687SBartlomiej Zolnierkiewicz 
398a809c687SBartlomiej Zolnierkiewicz 	ns87415_fixup(pdev);
399a809c687SBartlomiej Zolnierkiewicz 
400a809c687SBartlomiej Zolnierkiewicz 	ata_host_resume(host);
401a809c687SBartlomiej Zolnierkiewicz 	return 0;
402a809c687SBartlomiej Zolnierkiewicz }
403a809c687SBartlomiej Zolnierkiewicz #endif
404a809c687SBartlomiej Zolnierkiewicz 
405c4b5b7b6SAlan Cox static struct pci_driver ns87415_pci_driver = {
406c4b5b7b6SAlan Cox 	.name			= DRV_NAME,
407c4b5b7b6SAlan Cox 	.id_table		= ns87415_pci_tbl,
408c4b5b7b6SAlan Cox 	.probe			= ns87415_init_one,
409c4b5b7b6SAlan Cox 	.remove			= ata_pci_remove_one,
41058eb8cd5SBartlomiej Zolnierkiewicz #ifdef CONFIG_PM_SLEEP
411c4b5b7b6SAlan Cox 	.suspend		= ata_pci_device_suspend,
412a809c687SBartlomiej Zolnierkiewicz 	.resume			= ns87415_reinit_one,
413c4b5b7b6SAlan Cox #endif
414c4b5b7b6SAlan Cox };
415c4b5b7b6SAlan Cox 
4162fc75da0SAxel Lin module_pci_driver(ns87415_pci_driver);
417c4b5b7b6SAlan Cox 
418c4b5b7b6SAlan Cox MODULE_AUTHOR("Alan Cox");
419c4b5b7b6SAlan Cox MODULE_DESCRIPTION("ATA low-level driver for NS87415 controllers");
420c4b5b7b6SAlan Cox MODULE_LICENSE("GPL");
421c4b5b7b6SAlan Cox MODULE_DEVICE_TABLE(pci, ns87415_pci_tbl);
422c4b5b7b6SAlan Cox MODULE_VERSION(DRV_VERSION);
423