1d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee/*
2d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * pata_atp867x.c - ARTOP 867X 64bit 4-channel UDMA133 ATA controller driver
3d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee *
4d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee *	(C) 2009 Google Inc. John(Jung-Ik) Lee <jilee@google.com>
5d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee *
6d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * Per Atp867 data sheet rev 1.2, Acard.
7d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * Based in part on early ide code from
8d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee *	2003-2004 by Eric Uhrhane, Google, Inc.
9d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee *
10d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * This program is free software; you can redistribute it and/or modify
11d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * it under the terms of the GNU General Public License as published by
12d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * the Free Software Foundation; either version 2 of the License, or
13d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * (at your option) any later version.
14d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee *
15d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * This program is distributed in the hope that it will be useful,
16d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * but WITHOUT ANY WARRANTY; without even the implied warranty of
17d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * GNU General Public License for more details.
19d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee *
20d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * You should have received a copy of the GNU General Public License
21d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * along with this program; if not, write to the Free Software
22d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee *
24d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee *
25d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * TODO:
26d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee *   1. RAID features [comparison, XOR, striping, mirroring, etc.]
27d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee */
28d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
29d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#include <linux/kernel.h>
30d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#include <linux/module.h>
31d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#include <linux/pci.h>
32d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#include <linux/init.h>
33d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#include <linux/blkdev.h>
34d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#include <linux/delay.h>
35d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#include <linux/device.h>
365a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/gfp.h>
37d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#include <scsi/scsi_host.h>
38d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#include <linux/libata.h>
39d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
40d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#define	DRV_NAME	"pata_atp867x"
41d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#define	DRV_VERSION	"0.7.5"
42d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
43d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee/*
44d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * IO Registers
45d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * Note that all runtime hot priv ports are cached in ap private_data
46d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee */
47d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
48d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leeenum {
49d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_CHANNEL_OFFSET	= 0x10,
50d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
51d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	/*
52d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 * IO Register Bitfields
53d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 */
54d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
55d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_PIOSPD_ACTIVE_SHIFT	= 4,
56d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_PIOSPD_RECOVER_SHIFT	= 0,
57d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
58d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_DMAMODE_MSTR_SHIFT	= 0,
59d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_DMAMODE_MSTR_MASK	= 0x07,
60d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_DMAMODE_SLAVE_SHIFT	= 4,
61d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_DMAMODE_SLAVE_MASK	= 0x70,
62d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
63d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_DMAMODE_UDMA_6	= 0x07,
64d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_DMAMODE_UDMA_5	= 0x06,
65d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_DMAMODE_UDMA_4	= 0x05,
66d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_DMAMODE_UDMA_3	= 0x04,
67d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_DMAMODE_UDMA_2	= 0x03,
68d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_DMAMODE_UDMA_1	= 0x02,
69d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_DMAMODE_UDMA_0	= 0x01,
70d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_DMAMODE_DISABLE	= 0x00,
71d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
72d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_SYS_INFO_66MHZ	= 0x04,
73d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_SYS_INFO_SLOW_UDMA5	= 0x02,
74d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_SYS_MASK_RESERVED	= (~0xf1),
75d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
76d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_IO_PORTSPD_VAL		= 0x1143,
77d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_PREREAD_VAL		= 0x0200,
78d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
79d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_NUM_PORTS		= 4,
80d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_BAR_IOBASE		= 0,
81d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATP867X_BAR_ROMBASE		= 6,
82d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee};
83d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
84d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#define ATP867X_IOBASE(ap)		((ap)->host->iomap[0])
85d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#define ATP867X_SYS_INFO(ap)		(0x3F + ATP867X_IOBASE(ap))
86d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
87d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#define ATP867X_IO_PORTBASE(ap, port)	(0x00 + ATP867X_IOBASE(ap) + \
88d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee					(port) * ATP867X_IO_CHANNEL_OFFSET)
89d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#define ATP867X_IO_DMABASE(ap, port)	(0x40 + \
90d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee					ATP867X_IO_PORTBASE((ap), (port)))
91d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
92d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#define ATP867X_IO_STATUS(ap, port)	(0x07 + \
93d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee					ATP867X_IO_PORTBASE((ap), (port)))
94d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#define ATP867X_IO_ALTSTATUS(ap, port)	(0x0E + \
95d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee					ATP867X_IO_PORTBASE((ap), (port)))
96d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
97d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee/*
98d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee * hot priv ports
99d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee */
100d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#define ATP867X_IO_MSTRPIOSPD(ap, port)	(0x08 + \
101d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee					ATP867X_IO_DMABASE((ap), (port)))
102d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#define ATP867X_IO_SLAVPIOSPD(ap, port)	(0x09 + \
103d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee					ATP867X_IO_DMABASE((ap), (port)))
104d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#define ATP867X_IO_8BPIOSPD(ap, port)	(0x0A + \
105d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee					ATP867X_IO_DMABASE((ap), (port)))
106d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#define ATP867X_IO_DMAMODE(ap, port)	(0x0B + \
107d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee					ATP867X_IO_DMABASE((ap), (port)))
108d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
109d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#define ATP867X_IO_PORTSPD(ap, port)	(0x4A + \
110d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee					ATP867X_IO_PORTBASE((ap), (port)))
111d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#define ATP867X_IO_PREREAD(ap, port)	(0x4C + \
112d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee					ATP867X_IO_PORTBASE((ap), (port)))
113d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
114d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestruct atp867x_priv {
115d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	void __iomem *dma_mode;
116d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	void __iomem *mstr_piospd;
117d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	void __iomem *slave_piospd;
118d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	void __iomem *eightb_piospd;
119d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	int		pci66mhz;
120d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee};
121d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
122d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestatic void atp867x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
123d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee{
124d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	struct pci_dev *pdev	= to_pci_dev(ap->host->dev);
125d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	struct atp867x_priv *dp = ap->private_data;
126d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	u8 speed = adev->dma_mode;
127d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	u8 b;
128566b54c8a491654b145b6ae246039e5b4a56e587Bartlomiej Zolnierkiewicz	u8 mode = speed - XFER_UDMA_0 + 1;
129d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
130d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	/*
131d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 * Doc 6.6.9: decrease the udma mode value by 1 for safer UDMA speed
132d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 * on 66MHz bus
133d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 *   rev-A: UDMA_1~4 (5, 6 no change)
134d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 *   rev-B: all UDMA modes
135d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 *   UDMA_0 stays not to disable UDMA
136d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 */
137d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	if (dp->pci66mhz && mode > ATP867X_IO_DMAMODE_UDMA_0  &&
138d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	   (pdev->device == PCI_DEVICE_ID_ARTOP_ATP867B ||
139d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	    mode < ATP867X_IO_DMAMODE_UDMA_5))
140d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		mode--;
141d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
142d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	b = ioread8(dp->dma_mode);
143d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	if (adev->devno & 1) {
144d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		b = (b & ~ATP867X_IO_DMAMODE_SLAVE_MASK) |
145d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee			(mode << ATP867X_IO_DMAMODE_SLAVE_SHIFT);
146d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	} else {
147d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		b = (b & ~ATP867X_IO_DMAMODE_MSTR_MASK) |
148d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee			(mode << ATP867X_IO_DMAMODE_MSTR_SHIFT);
149d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	}
150d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	iowrite8(b, dp->dma_mode);
151d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee}
152d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
15364207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Leestatic int atp867x_get_active_clocks_shifted(struct ata_port *ap,
15464207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee	unsigned int clk)
155d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee{
15664207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee	struct atp867x_priv *dp = ap->private_data;
157d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	unsigned char clocks = clk;
158d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
159c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz	/*
160c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz	 * Doc 6.6.9: increase the clock value by 1 for safer PIO speed
161c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz	 * on 66MHz bus
162c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz	 */
163c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz	if (dp->pci66mhz)
164c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz		clocks++;
165c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz
166d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	switch (clocks) {
167d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	case 0:
168d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		clocks = 1;
169d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		break;
170c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz	case 1 ... 6:
171d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		break;
172d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	default:
173d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		printk(KERN_WARNING "ATP867X: active %dclk is invalid. "
174c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz			"Using 12clk.\n", clk);
175c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz	case 9 ... 12:
176c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz		clocks = 7;	/* 12 clk */
177c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz		break;
178c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz	case 7:
17964207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee	case 8:	/* default 8 clk */
18064207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee		clocks = 0;
18164207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee		goto active_clock_shift_done;
182d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	}
18364207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee
18464207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Leeactive_clock_shift_done:
185d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	return clocks << ATP867X_IO_PIOSPD_ACTIVE_SHIFT;
186d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee}
187d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
188d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestatic int atp867x_get_recover_clocks_shifted(unsigned int clk)
189d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee{
190d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	unsigned char clocks = clk;
191d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
192d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	switch (clocks) {
193d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	case 0:
194d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		clocks = 1;
195d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		break;
196d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	case 1 ... 11:
197d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		break;
198c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz	case 13:
199c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz	case 14:
20064207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee		--clocks;	/* by the spec */
201d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		break;
202d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	case 15:
203d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		break;
204d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	default:
205d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		printk(KERN_WARNING "ATP867X: recover %dclk is invalid. "
20664207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee			"Using default 12clk.\n", clk);
20764207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee	case 12:	/* default 12 clk */
20864207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee		clocks = 0;
209d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		break;
210d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	}
21164207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee
212d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	return clocks << ATP867X_IO_PIOSPD_RECOVER_SHIFT;
213d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee}
214d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
215d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestatic void atp867x_set_piomode(struct ata_port *ap, struct ata_device *adev)
216d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee{
217d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	struct ata_device *peer = ata_dev_pair(adev);
218d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	struct atp867x_priv *dp = ap->private_data;
219d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	u8 speed = adev->pio_mode;
220d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	struct ata_timing t, p;
221d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	int T, UT;
222d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	u8 b;
223d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
224d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	T = 1000000000 / 33333;
225d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	UT = T / 4;
226d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
227d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ata_timing_compute(adev, speed, &t, T, UT);
228d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	if (peer && peer->pio_mode) {
229d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		ata_timing_compute(peer, peer->pio_mode, &p, T, UT);
230d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		ata_timing_merge(&p, &t, &t, ATA_TIMING_8BIT);
231d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	}
232d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
233d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	b = ioread8(dp->dma_mode);
234d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	if (adev->devno & 1)
235d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		b = (b & ~ATP867X_IO_DMAMODE_SLAVE_MASK);
236d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	else
237d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		b = (b & ~ATP867X_IO_DMAMODE_MSTR_MASK);
238d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	iowrite8(b, dp->dma_mode);
239d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
24064207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee	b = atp867x_get_active_clocks_shifted(ap, t.active) |
241c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz	    atp867x_get_recover_clocks_shifted(t.recover);
242d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
243d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	if (adev->devno & 1)
244d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		iowrite8(b, dp->slave_piospd);
245d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	else
246d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		iowrite8(b, dp->mstr_piospd);
247d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
248c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz	b = atp867x_get_active_clocks_shifted(ap, t.act8b) |
249c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz	    atp867x_get_recover_clocks_shifted(t.rec8b);
250c59bcc37cb56e00ae0582339bea948853d600436Bartlomiej Zolnierkiewicz
251d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	iowrite8(b, dp->eightb_piospd);
252d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee}
253d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
25464207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Leestatic int atp867x_cable_override(struct pci_dev *pdev)
25564207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee{
25664207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee	if (pdev->subsystem_vendor == PCI_VENDOR_ID_ARTOP &&
25764207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee		(pdev->subsystem_device == PCI_DEVICE_ID_ARTOP_ATP867A ||
25864207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee		 pdev->subsystem_device == PCI_DEVICE_ID_ARTOP_ATP867B)) {
25964207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee		return 1;
26064207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee	}
26164207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee	return 0;
26264207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee}
26364207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee
264d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestatic int atp867x_cable_detect(struct ata_port *ap)
265d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee{
26664207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
26764207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee
26864207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee	if (atp867x_cable_override(pdev))
26964207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee		return ATA_CBL_PATA40_SHORT;
27064207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee
27164207f59137fd300a869e35b14c15f775c64c6fcJohn(Jung-Ik) Lee	return ATA_CBL_PATA_UNK;
272d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee}
273d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
274d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestatic struct scsi_host_template atp867x_sht = {
275d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	ATA_BMDMA_SHT(DRV_NAME),
276d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee};
277d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
278d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestatic struct ata_port_operations atp867x_ops = {
279d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	.inherits		= &ata_bmdma_port_ops,
280d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	.cable_detect		= atp867x_cable_detect,
281d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	.set_piomode		= atp867x_set_piomode,
282d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	.set_dmamode		= atp867x_set_dmamode,
283d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee};
284d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
285d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
286d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#ifdef	ATP867X_DEBUG
287d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestatic void atp867x_check_res(struct pci_dev *pdev)
288d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee{
289d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	int i;
290d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	unsigned long start, len;
291d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
292d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	/* Check the PCI resources for this channel are enabled */
293d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
294d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		start = pci_resource_start(pdev, i);
295d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		len   = pci_resource_len(pdev, i);
296d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		printk(KERN_DEBUG "ATP867X: resource start:len=%lx:%lx\n",
297d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee			start, len);
298d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	}
299d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee}
300d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
301d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestatic void atp867x_check_ports(struct ata_port *ap, int port)
302d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee{
303d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	struct ata_ioports *ioaddr = &ap->ioaddr;
304d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	struct atp867x_priv *dp = ap->private_data;
305d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
306d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	printk(KERN_DEBUG "ATP867X: port[%d] addresses\n"
307d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  cmd_addr	=0x%llx, 0x%llx\n"
308d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  ctl_addr	=0x%llx, 0x%llx\n"
309d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  bmdma_addr	=0x%llx, 0x%llx\n"
310d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  data_addr	=0x%llx\n"
311d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  error_addr	=0x%llx\n"
312d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  feature_addr	=0x%llx\n"
313d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  nsect_addr	=0x%llx\n"
314d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  lbal_addr	=0x%llx\n"
315d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  lbam_addr	=0x%llx\n"
316d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  lbah_addr	=0x%llx\n"
317d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  device_addr	=0x%llx\n"
318d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  status_addr	=0x%llx\n"
319d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  command_addr	=0x%llx\n"
320d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  dp->dma_mode	=0x%llx\n"
321d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  dp->mstr_piospd	=0x%llx\n"
322d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  dp->slave_piospd	=0x%llx\n"
323d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  dp->eightb_piospd	=0x%llx\n"
324d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		"  dp->pci66mhz		=0x%lx\n",
325d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		port,
326d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)ioaddr->cmd_addr,
327d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)ATP867X_IO_PORTBASE(ap, port),
328d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)ioaddr->ctl_addr,
329d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)ATP867X_IO_ALTSTATUS(ap, port),
330d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)ioaddr->bmdma_addr,
331d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)ATP867X_IO_DMABASE(ap, port),
332d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)ioaddr->data_addr,
333d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)ioaddr->error_addr,
334d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)ioaddr->feature_addr,
335d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)ioaddr->nsect_addr,
336d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)ioaddr->lbal_addr,
337d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)ioaddr->lbam_addr,
338d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)ioaddr->lbah_addr,
339d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)ioaddr->device_addr,
340d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)ioaddr->status_addr,
341d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)ioaddr->command_addr,
342d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)dp->dma_mode,
343d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)dp->mstr_piospd,
344d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)dp->slave_piospd,
345d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long long)dp->eightb_piospd,
346d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		(unsigned long)dp->pci66mhz);
347d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee}
348d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#endif
349d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
350d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestatic int atp867x_set_priv(struct ata_port *ap)
351d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee{
352d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
353d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	struct atp867x_priv *dp;
354d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	int port = ap->port_no;
355d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
356d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	dp = ap->private_data =
357d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		devm_kzalloc(&pdev->dev, sizeof(*dp), GFP_KERNEL);
358d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	if (dp == NULL)
359d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		return -ENOMEM;
360d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
361d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	dp->dma_mode	 = ATP867X_IO_DMAMODE(ap, port);
362d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	dp->mstr_piospd	 = ATP867X_IO_MSTRPIOSPD(ap, port);
363d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	dp->slave_piospd = ATP867X_IO_SLAVPIOSPD(ap, port);
364d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	dp->eightb_piospd = ATP867X_IO_8BPIOSPD(ap, port);
365d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
366d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	dp->pci66mhz =
367d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		ioread8(ATP867X_SYS_INFO(ap)) & ATP867X_IO_SYS_INFO_66MHZ;
368d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
369d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	return 0;
370d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee}
371d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
372d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestatic void atp867x_fixup(struct ata_host *host)
373d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee{
374d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	struct pci_dev *pdev = to_pci_dev(host->dev);
375d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	struct ata_port *ap = host->ports[0];
376d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	int i;
377d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	u8 v;
378d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
379d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	/*
380d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 * Broken BIOS might not set latency high enough
381d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 */
382d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &v);
383d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	if (v < 0x80) {
384d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		v = 0x80;
385d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		pci_write_config_byte(pdev, PCI_LATENCY_TIMER, v);
386d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		printk(KERN_DEBUG "ATP867X: set latency timer of device %s"
387d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee			" to %d\n", pci_name(pdev), v);
388d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	}
389d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
390d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	/*
391d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 * init 8bit io ports speed(0aaarrrr) to 43h and
392d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 * init udma modes of master/slave to 0/0(11h)
393d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 */
394d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	for (i = 0; i < ATP867X_NUM_PORTS; i++)
395d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		iowrite16(ATP867X_IO_PORTSPD_VAL, ATP867X_IO_PORTSPD(ap, i));
396d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
397d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	/*
398d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 * init PreREAD counts
399d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 */
400d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	for (i = 0; i < ATP867X_NUM_PORTS; i++)
401d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		iowrite16(ATP867X_PREREAD_VAL, ATP867X_IO_PREREAD(ap, i));
402d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
403d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	v = ioread8(ATP867X_IOBASE(ap) + 0x28);
404d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	v &= 0xcf;	/* Enable INTA#: bit4=0 means enable */
405d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	v |= 0xc0;	/* Enable PCI burst, MRM & not immediate interrupts */
406d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	iowrite8(v, ATP867X_IOBASE(ap) + 0x28);
407d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
408d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	/*
409d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 * Turn off the over clocked udma5 mode, only for Rev-B
410d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 */
411d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	v = ioread8(ATP867X_SYS_INFO(ap));
412d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	v &= ATP867X_IO_SYS_MASK_RESERVED;
413d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	if (pdev->device == PCI_DEVICE_ID_ARTOP_ATP867B)
414d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		v |= ATP867X_IO_SYS_INFO_SLOW_UDMA5;
415d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	iowrite8(v, ATP867X_SYS_INFO(ap));
416d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee}
417d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
418d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestatic int atp867x_ata_pci_sff_init_host(struct ata_host *host)
419d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee{
420d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	struct device *gdev = host->dev;
421d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	struct pci_dev *pdev = to_pci_dev(gdev);
422d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	unsigned int mask = 0;
423d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	int i, rc;
424d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
425d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	/*
426d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 * do not map rombase
427d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 */
428d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	rc = pcim_iomap_regions(pdev, 1 << ATP867X_BAR_IOBASE, DRV_NAME);
429d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	if (rc == -EBUSY)
430d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		pcim_pin_device(pdev);
431d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	if (rc)
432d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		return rc;
433d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	host->iomap = pcim_iomap_table(pdev);
434d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
435d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#ifdef	ATP867X_DEBUG
436d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	atp867x_check_res(pdev);
437d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
438d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	for (i = 0; i < PCI_ROM_RESOURCE; i++)
439d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		printk(KERN_DEBUG "ATP867X: iomap[%d]=0x%llx\n", i,
440d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee			(unsigned long long)(host->iomap[i]));
441d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#endif
442d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
443d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	/*
444d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 * request, iomap BARs and init port addresses accordingly
445d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	 */
446d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	for (i = 0; i < host->n_ports; i++) {
447d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		struct ata_port *ap = host->ports[i];
448d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		struct ata_ioports *ioaddr = &ap->ioaddr;
449d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
450d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		ioaddr->cmd_addr = ATP867X_IO_PORTBASE(ap, i);
451d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		ioaddr->ctl_addr = ioaddr->altstatus_addr
452d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee				 = ATP867X_IO_ALTSTATUS(ap, i);
453d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		ioaddr->bmdma_addr = ATP867X_IO_DMABASE(ap, i);
454d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
455d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		ata_sff_std_ports(ioaddr);
456d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		rc = atp867x_set_priv(ap);
457d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		if (rc)
458d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee			return rc;
459d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
460d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#ifdef	ATP867X_DEBUG
461d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		atp867x_check_ports(ap, i);
462d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee#endif
463d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx",
464d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee			(unsigned long)ioaddr->cmd_addr,
465d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee			(unsigned long)ioaddr->ctl_addr);
466d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		ata_port_desc(ap, "bmdma 0x%lx",
467d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee			(unsigned long)ioaddr->bmdma_addr);
468d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
469d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		mask |= 1 << i;
470d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	}
471d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
472d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	if (!mask) {
473a44fec1fce5d5d14cc3ac4545b8da346394de666Joe Perches		dev_err(gdev, "no available native port\n");
474d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		return -ENODEV;
475d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	}
476d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
477d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	atp867x_fixup(host);
478d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
479d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
480d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	if (rc)
481d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		return rc;
482d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
483d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
484d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	return rc;
485d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee}
486d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
487d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestatic int atp867x_init_one(struct pci_dev *pdev,
488d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	const struct pci_device_id *id)
489d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee{
490d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	static const struct ata_port_info info_867x = {
491d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		.flags		= ATA_FLAG_SLAVE_POSS,
492d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		.pio_mask	= ATA_PIO4,
493d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		.udma_mask 	= ATA_UDMA6,
494d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		.port_ops	= &atp867x_ops,
495d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	};
496d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
497d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	struct ata_host *host;
498d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	const struct ata_port_info *ppi[] = { &info_867x, NULL };
499d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	int rc;
500d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
50106296a1e684bcd40b9a28d5d8030809e4295528bJoe Perches	ata_print_version_once(&pdev->dev, DRV_VERSION);
502d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
503d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	rc = pcim_enable_device(pdev);
504d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	if (rc)
505d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		return rc;
506d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
507d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	printk(KERN_INFO "ATP867X: ATP867 ATA UDMA133 controller (rev %02X)",
508d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		pdev->device);
509d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
510d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	host = ata_host_alloc_pinfo(&pdev->dev, ppi, ATP867X_NUM_PORTS);
511d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	if (!host) {
512a44fec1fce5d5d14cc3ac4545b8da346394de666Joe Perches		dev_err(&pdev->dev, "failed to allocate ATA host\n");
513d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		rc = -ENOMEM;
514d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		goto err_out;
515d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	}
516d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
517d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	rc = atp867x_ata_pci_sff_init_host(host);
518d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	if (rc) {
519a44fec1fce5d5d14cc3ac4545b8da346394de666Joe Perches		dev_err(&pdev->dev, "failed to init host\n");
520d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee		goto err_out;
521d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	}
522d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
523d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	pci_set_master(pdev);
524d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
525c3b2889424c26f3b42962b6f39aabb4f1fd1b576Tejun Heo	rc = ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
526d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee				IRQF_SHARED, &atp867x_sht);
527d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	if (rc)
528a44fec1fce5d5d14cc3ac4545b8da346394de666Joe Perches		dev_err(&pdev->dev, "failed to activate host\n");
529d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
530d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leeerr_out:
531d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	return rc;
532d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee}
533d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
5347affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz#ifdef CONFIG_PM
5357affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewiczstatic int atp867x_reinit_one(struct pci_dev *pdev)
5367affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz{
5377affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz	struct ata_host *host = dev_get_drvdata(&pdev->dev);
5387affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz	int rc;
5397affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz
5407affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz	rc = ata_pci_device_do_resume(pdev);
5417affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz	if (rc)
5427affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz		return rc;
5437affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz
5447affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz	atp867x_fixup(host);
5457affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz
5467affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz	ata_host_resume(host);
5477affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz	return 0;
5487affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz}
5497affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz#endif
5507affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz
551d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestatic struct pci_device_id atp867x_pci_tbl[] = {
552d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	{ PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP867A),	0 },
553d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	{ PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP867B),	0 },
554d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	{ },
555d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee};
556d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
557d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestatic struct pci_driver atp867x_driver = {
558d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	.name 		= DRV_NAME,
559d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	.id_table 	= atp867x_pci_tbl,
560d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	.probe 		= atp867x_init_one,
561d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	.remove		= ata_pci_remove_one,
5627affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz#ifdef CONFIG_PM
5637affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz	.suspend	= ata_pci_device_suspend,
5647affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz	.resume		= atp867x_reinit_one,
5657affb32a32eabbbe42d6746923ec1d0bf7327234Bartlomiej Zolnierkiewicz#endif
566d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee};
567d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
568d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestatic int __init atp867x_init(void)
569d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee{
570d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	return pci_register_driver(&atp867x_driver);
571d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee}
572d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
573d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leestatic void __exit atp867x_exit(void)
574d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee{
575d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee	pci_unregister_driver(&atp867x_driver);
576d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee}
577d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
578d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) LeeMODULE_AUTHOR("John(Jung-Ik) Lee, Google Inc.");
579d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) LeeMODULE_DESCRIPTION("low level driver for Artop/Acard 867x ATA controller");
580d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) LeeMODULE_LICENSE("GPL");
581d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) LeeMODULE_DEVICE_TABLE(pci, atp867x_pci_tbl);
582d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) LeeMODULE_VERSION(DRV_VERSION);
583d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Lee
584d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leemodule_init(atp867x_init);
585d15d6e6cc340566d53d953ffdec2c9e96816fa52John(Jung-Ik) Leemodule_exit(atp867x_exit);
586