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