xref: /openbmc/linux/drivers/ata/pata_via.c (revision cf5792d20cdc9a88abf9984a2224f57de1952926)
1669a5db4SJeff Garzik /*
2669a5db4SJeff Garzik  * pata_via.c 	- VIA PATA for new ATA layer
3669a5db4SJeff Garzik  *			  (C) 2005-2006 Red Hat Inc
4669a5db4SJeff Garzik  *			  Alan Cox <alan@redhat.com>
5669a5db4SJeff Garzik  *
6669a5db4SJeff Garzik  *  Documentation
7669a5db4SJeff Garzik  *	Most chipset documentation available under NDA only
8669a5db4SJeff Garzik  *
9669a5db4SJeff Garzik  *  VIA version guide
10669a5db4SJeff Garzik  *	VIA VT82C561	-	early design, uses ata_generic currently
11669a5db4SJeff Garzik  *	VIA VT82C576	-	MWDMA, 33Mhz
12669a5db4SJeff Garzik  *	VIA VT82C586	-	MWDMA, 33Mhz
13669a5db4SJeff Garzik  *	VIA VT82C586a	-	Added UDMA to 33Mhz
14669a5db4SJeff Garzik  *	VIA VT82C586b	-	UDMA33
15669a5db4SJeff Garzik  *	VIA VT82C596a	-	Nonfunctional UDMA66
16669a5db4SJeff Garzik  *	VIA VT82C596b	-	Working UDMA66
17669a5db4SJeff Garzik  *	VIA VT82C686	-	Nonfunctional UDMA66
18669a5db4SJeff Garzik  *	VIA VT82C686a	-	Working UDMA66
19669a5db4SJeff Garzik  *	VIA VT82C686b	-	Updated to UDMA100
20669a5db4SJeff Garzik  *	VIA VT8231	-	UDMA100
21669a5db4SJeff Garzik  *	VIA VT8233	-	UDMA100
22669a5db4SJeff Garzik  *	VIA VT8233a	-	UDMA133
23669a5db4SJeff Garzik  *	VIA VT8233c	-	UDMA100
24669a5db4SJeff Garzik  *	VIA VT8235	-	UDMA133
25669a5db4SJeff Garzik  *	VIA VT8237	-	UDMA133
2605c39e50SAlan  *	VIA VT8237S	-	UDMA133
2775f609d2SAlan  *	VIA VT8251	-	UDMA133
28669a5db4SJeff Garzik  *
29669a5db4SJeff Garzik  *	Most registers remain compatible across chips. Others start reserved
30669a5db4SJeff Garzik  *	and acquire sensible semantics if set to 1 (eg cable detect). A few
31669a5db4SJeff Garzik  *	exceptions exist, notably around the FIFO settings.
32669a5db4SJeff Garzik  *
33669a5db4SJeff Garzik  *	One additional quirk of the VIA design is that like ALi they use few
34669a5db4SJeff Garzik  *	PCI IDs for a lot of chips.
35669a5db4SJeff Garzik  *
36669a5db4SJeff Garzik  *	Based heavily on:
37669a5db4SJeff Garzik  *
38669a5db4SJeff Garzik  * Version 3.38
39669a5db4SJeff Garzik  *
40669a5db4SJeff Garzik  * VIA IDE driver for Linux. Supported southbridges:
41669a5db4SJeff Garzik  *
42669a5db4SJeff Garzik  *   vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
43669a5db4SJeff Garzik  *   vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a,
44669a5db4SJeff Garzik  *   vt8235, vt8237
45669a5db4SJeff Garzik  *
46669a5db4SJeff Garzik  * Copyright (c) 2000-2002 Vojtech Pavlik
47669a5db4SJeff Garzik  *
48669a5db4SJeff Garzik  * Based on the work of:
49669a5db4SJeff Garzik  *	Michel Aubry
50669a5db4SJeff Garzik  *	Jeff Garzik
51669a5db4SJeff Garzik  *	Andre Hedrick
52669a5db4SJeff Garzik 
53669a5db4SJeff Garzik  */
54669a5db4SJeff Garzik 
55669a5db4SJeff Garzik #include <linux/kernel.h>
56669a5db4SJeff Garzik #include <linux/module.h>
57669a5db4SJeff Garzik #include <linux/pci.h>
58669a5db4SJeff Garzik #include <linux/init.h>
59669a5db4SJeff Garzik #include <linux/blkdev.h>
60669a5db4SJeff Garzik #include <linux/delay.h>
61669a5db4SJeff Garzik #include <scsi/scsi_host.h>
62669a5db4SJeff Garzik #include <linux/libata.h>
63*cf5792d2SAlan Cox #include <linux/dmi.h>
64669a5db4SJeff Garzik 
65669a5db4SJeff Garzik #define DRV_NAME "pata_via"
6697cb81c3SAlan Cox #define DRV_VERSION "0.3.1"
67669a5db4SJeff Garzik 
68669a5db4SJeff Garzik /*
69669a5db4SJeff Garzik  *	The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx
70669a5db4SJeff Garzik  *	driver.
71669a5db4SJeff Garzik  */
72669a5db4SJeff Garzik 
73669a5db4SJeff Garzik enum {
74669a5db4SJeff Garzik 	VIA_UDMA	= 0x007,
75669a5db4SJeff Garzik 	VIA_UDMA_NONE	= 0x000,
76669a5db4SJeff Garzik 	VIA_UDMA_33	= 0x001,
77669a5db4SJeff Garzik 	VIA_UDMA_66	= 0x002,
78669a5db4SJeff Garzik 	VIA_UDMA_100	= 0x003,
79669a5db4SJeff Garzik 	VIA_UDMA_133	= 0x004,
80669a5db4SJeff Garzik 	VIA_BAD_PREQ	= 0x010, /* Crashes if PREQ# till DDACK# set */
81669a5db4SJeff Garzik 	VIA_BAD_CLK66	= 0x020, /* 66 MHz clock doesn't work correctly */
82669a5db4SJeff Garzik 	VIA_SET_FIFO	= 0x040, /* Needs to have FIFO split set */
83669a5db4SJeff Garzik 	VIA_NO_UNMASK	= 0x080, /* Doesn't work with IRQ unmasking on */
84669a5db4SJeff Garzik 	VIA_BAD_ID	= 0x100, /* Has wrong vendor ID (0x1107) */
85669a5db4SJeff Garzik 	VIA_BAD_AST	= 0x200, /* Don't touch Address Setup Timing */
86669a5db4SJeff Garzik 	VIA_NO_ENABLES	= 0x400, /* Has no enablebits */
87669a5db4SJeff Garzik };
88669a5db4SJeff Garzik 
89669a5db4SJeff Garzik /*
90669a5db4SJeff Garzik  * VIA SouthBridge chips.
91669a5db4SJeff Garzik  */
92669a5db4SJeff Garzik 
93669a5db4SJeff Garzik static const struct via_isa_bridge {
94669a5db4SJeff Garzik 	const char *name;
95669a5db4SJeff Garzik 	u16 id;
96669a5db4SJeff Garzik 	u8 rev_min;
97669a5db4SJeff Garzik 	u8 rev_max;
98669a5db4SJeff Garzik 	u16 flags;
99669a5db4SJeff Garzik } via_isa_bridges[] = {
100e0b874dfSJosepch Chan 	{ "vt8237s",	PCI_DEVICE_ID_VIA_8237S,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
10175f609d2SAlan 	{ "vt8251",	PCI_DEVICE_ID_VIA_8251,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
102669a5db4SJeff Garzik 	{ "cx700",	PCI_DEVICE_ID_VIA_CX700,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
103669a5db4SJeff Garzik 	{ "vt6410",	PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES},
104669a5db4SJeff Garzik 	{ "vt8237a",	PCI_DEVICE_ID_VIA_8237A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
105669a5db4SJeff Garzik 	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
106669a5db4SJeff Garzik 	{ "vt8235",	PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
107669a5db4SJeff Garzik 	{ "vt8233a",	PCI_DEVICE_ID_VIA_8233A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
108669a5db4SJeff Garzik 	{ "vt8233c",	PCI_DEVICE_ID_VIA_8233C_0,  0x00, 0x2f, VIA_UDMA_100 },
109669a5db4SJeff Garzik 	{ "vt8233",	PCI_DEVICE_ID_VIA_8233_0,   0x00, 0x2f, VIA_UDMA_100 },
110669a5db4SJeff Garzik 	{ "vt8231",	PCI_DEVICE_ID_VIA_8231,     0x00, 0x2f, VIA_UDMA_100 },
111669a5db4SJeff Garzik 	{ "vt82c686b",	PCI_DEVICE_ID_VIA_82C686,   0x40, 0x4f, VIA_UDMA_100 },
112669a5db4SJeff Garzik 	{ "vt82c686a",	PCI_DEVICE_ID_VIA_82C686,   0x10, 0x2f, VIA_UDMA_66 },
113669a5db4SJeff Garzik 	{ "vt82c686",	PCI_DEVICE_ID_VIA_82C686,   0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 },
114669a5db4SJeff Garzik 	{ "vt82c596b",	PCI_DEVICE_ID_VIA_82C596,   0x10, 0x2f, VIA_UDMA_66 },
115669a5db4SJeff Garzik 	{ "vt82c596a",	PCI_DEVICE_ID_VIA_82C596,   0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 },
116669a5db4SJeff Garzik 	{ "vt82c586b",	PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, VIA_UDMA_33 | VIA_SET_FIFO },
117669a5db4SJeff Garzik 	{ "vt82c586b",	PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, VIA_UDMA_33 | VIA_SET_FIFO | VIA_BAD_PREQ },
118669a5db4SJeff Garzik 	{ "vt82c586b",	PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, VIA_UDMA_33 | VIA_SET_FIFO },
119669a5db4SJeff Garzik 	{ "vt82c586a",	PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, VIA_UDMA_33 | VIA_SET_FIFO },
120669a5db4SJeff Garzik 	{ "vt82c586",	PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO },
121669a5db4SJeff Garzik 	{ "vt82c576",	PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK },
122669a5db4SJeff Garzik 	{ "vt82c576",	PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID },
123669a5db4SJeff Garzik 	{ NULL }
124669a5db4SJeff Garzik };
125669a5db4SJeff Garzik 
126*cf5792d2SAlan Cox 
127*cf5792d2SAlan Cox /*
128*cf5792d2SAlan Cox  *	Cable special cases
129*cf5792d2SAlan Cox  */
130*cf5792d2SAlan Cox 
131*cf5792d2SAlan Cox static struct dmi_system_id cable_dmi_table[] = {
132*cf5792d2SAlan Cox 	{
133*cf5792d2SAlan Cox 		.ident = "Acer Ferrari 3400",
134*cf5792d2SAlan Cox 		.matches = {
135*cf5792d2SAlan Cox 			DMI_MATCH(DMI_BOARD_VENDOR, "Acer,Inc."),
136*cf5792d2SAlan Cox 			DMI_MATCH(DMI_BOARD_NAME, "Ferrari 3400"),
137*cf5792d2SAlan Cox 		},
138*cf5792d2SAlan Cox 	},
139*cf5792d2SAlan Cox 	{ }
140*cf5792d2SAlan Cox };
141*cf5792d2SAlan Cox 
142*cf5792d2SAlan Cox static int via_cable_override(struct pci_dev *pdev)
143*cf5792d2SAlan Cox {
144*cf5792d2SAlan Cox 	/* Systems by DMI */
145*cf5792d2SAlan Cox 	if (dmi_check_system(cable_dmi_table))
146*cf5792d2SAlan Cox 		return 1;
147*cf5792d2SAlan Cox 	return 0;
148*cf5792d2SAlan Cox }
149*cf5792d2SAlan Cox 
150*cf5792d2SAlan Cox 
151669a5db4SJeff Garzik /**
152669a5db4SJeff Garzik  *	via_cable_detect	-	cable detection
153669a5db4SJeff Garzik  *	@ap: ATA port
154669a5db4SJeff Garzik  *
155669a5db4SJeff Garzik  *	Perform cable detection. Actually for the VIA case the BIOS
156669a5db4SJeff Garzik  *	already did this for us. We read the values provided by the
157669a5db4SJeff Garzik  *	BIOS. If you are using an 8235 in a non-PC configuration you
158669a5db4SJeff Garzik  *	may need to update this code.
159669a5db4SJeff Garzik  *
160669a5db4SJeff Garzik  *	Hotplug also impacts on this.
161669a5db4SJeff Garzik  */
162669a5db4SJeff Garzik 
163669a5db4SJeff Garzik static int via_cable_detect(struct ata_port *ap) {
16497cb81c3SAlan Cox 	const struct via_isa_bridge *config = ap->host->private_data;
165669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
166669a5db4SJeff Garzik 	u32 ata66;
167669a5db4SJeff Garzik 
168*cf5792d2SAlan Cox 	if (via_cable_override(pdev))
169*cf5792d2SAlan Cox 		return ATA_CBL_PATA40_SHORT;
170*cf5792d2SAlan Cox 
17197cb81c3SAlan Cox 	/* Early chips are 40 wire */
17297cb81c3SAlan Cox 	if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
17397cb81c3SAlan Cox 		return ATA_CBL_PATA40;
17497cb81c3SAlan Cox 	/* UDMA 66 chips have only drive side logic */
17597cb81c3SAlan Cox 	else if((config->flags & VIA_UDMA) < VIA_UDMA_100)
17697cb81c3SAlan Cox 		return ATA_CBL_PATA_UNK;
17797cb81c3SAlan Cox 	/* UDMA 100 or later */
178669a5db4SJeff Garzik 	pci_read_config_dword(pdev, 0x50, &ata66);
179669a5db4SJeff Garzik 	/* Check both the drive cable reporting bits, we might not have
180669a5db4SJeff Garzik 	   two drives */
181669a5db4SJeff Garzik 	if (ata66 & (0x10100000 >> (16 * ap->port_no)))
182669a5db4SJeff Garzik 		return ATA_CBL_PATA80;
183669a5db4SJeff Garzik 	return ATA_CBL_PATA40;
184669a5db4SJeff Garzik }
185669a5db4SJeff Garzik 
186d4b2bab4STejun Heo static int via_pre_reset(struct ata_port *ap, unsigned long deadline)
187669a5db4SJeff Garzik {
188669a5db4SJeff Garzik 	const struct via_isa_bridge *config = ap->host->private_data;
189669a5db4SJeff Garzik 
190669a5db4SJeff Garzik 	if (!(config->flags & VIA_NO_ENABLES)) {
191669a5db4SJeff Garzik 		static const struct pci_bits via_enable_bits[] = {
192669a5db4SJeff Garzik 			{ 0x40, 1, 0x02, 0x02 },
193669a5db4SJeff Garzik 			{ 0x40, 1, 0x01, 0x01 }
194669a5db4SJeff Garzik 		};
195669a5db4SJeff Garzik 		struct pci_dev *pdev = to_pci_dev(ap->host->dev);
196c961922bSAlan Cox 		if (!pci_test_config_bits(pdev, &via_enable_bits[ap->port_no]))
197c961922bSAlan Cox 			return -ENOENT;
198669a5db4SJeff Garzik 	}
199d4b2bab4STejun Heo 
200d4b2bab4STejun Heo 	return ata_std_prereset(ap, deadline);
201669a5db4SJeff Garzik }
202669a5db4SJeff Garzik 
203669a5db4SJeff Garzik 
204669a5db4SJeff Garzik /**
205669a5db4SJeff Garzik  *	via_error_handler		-	reset for VIA chips
206669a5db4SJeff Garzik  *	@ap: ATA port
207669a5db4SJeff Garzik  *
208669a5db4SJeff Garzik  *	Handle the reset callback for the later chips with cable detect
209669a5db4SJeff Garzik  */
210669a5db4SJeff Garzik 
211669a5db4SJeff Garzik static void via_error_handler(struct ata_port *ap)
212669a5db4SJeff Garzik {
213669a5db4SJeff Garzik 	ata_bmdma_drive_eh(ap, via_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
214669a5db4SJeff Garzik }
215669a5db4SJeff Garzik 
216669a5db4SJeff Garzik /**
217669a5db4SJeff Garzik  *	via_do_set_mode	-	set initial PIO mode data
218669a5db4SJeff Garzik  *	@ap: ATA interface
219669a5db4SJeff Garzik  *	@adev: ATA device
220669a5db4SJeff Garzik  *	@mode: ATA mode being programmed
221669a5db4SJeff Garzik  *	@tdiv: Clocks per PCI clock
222669a5db4SJeff Garzik  *	@set_ast: Set to program address setup
223669a5db4SJeff Garzik  *	@udma_type: UDMA mode/format of registers
224669a5db4SJeff Garzik  *
225669a5db4SJeff Garzik  *	Program the VIA registers for DMA and PIO modes. Uses the ata timing
226669a5db4SJeff Garzik  *	support in order to compute modes.
227669a5db4SJeff Garzik  *
228669a5db4SJeff Garzik  *	FIXME: Hotplug will require we serialize multiple mode changes
229669a5db4SJeff Garzik  *	on the two channels.
230669a5db4SJeff Garzik  */
231669a5db4SJeff Garzik 
232669a5db4SJeff Garzik static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mode, int tdiv, int set_ast, int udma_type)
233669a5db4SJeff Garzik {
234669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
235669a5db4SJeff Garzik 	struct ata_device *peer = ata_dev_pair(adev);
236669a5db4SJeff Garzik 	struct ata_timing t, p;
237669a5db4SJeff Garzik 	static int via_clock = 33333;	/* Bus clock in kHZ - ought to be tunable one day */
238669a5db4SJeff Garzik 	unsigned long T =  1000000000 / via_clock;
239669a5db4SJeff Garzik 	unsigned long UT = T/tdiv;
240669a5db4SJeff Garzik 	int ut;
241669a5db4SJeff Garzik 	int offset = 3 - (2*ap->port_no) - adev->devno;
242669a5db4SJeff Garzik 
243669a5db4SJeff Garzik 
244669a5db4SJeff Garzik 	/* Calculate the timing values we require */
245669a5db4SJeff Garzik 	ata_timing_compute(adev, mode, &t, T, UT);
246669a5db4SJeff Garzik 
247669a5db4SJeff Garzik 	/* We share 8bit timing so we must merge the constraints */
248669a5db4SJeff Garzik 	if (peer) {
249669a5db4SJeff Garzik 		if (peer->pio_mode) {
250669a5db4SJeff Garzik 			ata_timing_compute(peer, peer->pio_mode, &p, T, UT);
251669a5db4SJeff Garzik 			ata_timing_merge(&p, &t, &t, ATA_TIMING_8BIT);
252669a5db4SJeff Garzik 		}
253669a5db4SJeff Garzik 	}
254669a5db4SJeff Garzik 
255669a5db4SJeff Garzik 	/* Address setup is programmable but breaks on UDMA133 setups */
256669a5db4SJeff Garzik 	if (set_ast) {
257669a5db4SJeff Garzik 		u8 setup;	/* 2 bits per drive */
258669a5db4SJeff Garzik 		int shift = 2 * offset;
259669a5db4SJeff Garzik 
260669a5db4SJeff Garzik 		pci_read_config_byte(pdev, 0x4C, &setup);
261669a5db4SJeff Garzik 		setup &= ~(3 << shift);
262669a5db4SJeff Garzik 		setup |= FIT(t.setup, 1, 4) << shift;	/* 1,4 or 1,4 - 1  FIXME */
263669a5db4SJeff Garzik 		pci_write_config_byte(pdev, 0x4C, setup);
264669a5db4SJeff Garzik 	}
265669a5db4SJeff Garzik 
266669a5db4SJeff Garzik 	/* Load the PIO mode bits */
267669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x4F - ap->port_no,
268669a5db4SJeff Garzik 		((FIT(t.act8b, 1, 16) - 1) << 4) | (FIT(t.rec8b, 1, 16) - 1));
269669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x48 + offset,
270669a5db4SJeff Garzik 		((FIT(t.active, 1, 16) - 1) << 4) | (FIT(t.recover, 1, 16) - 1));
271669a5db4SJeff Garzik 
272669a5db4SJeff Garzik 	/* Load the UDMA bits according to type */
273669a5db4SJeff Garzik 	switch(udma_type) {
274669a5db4SJeff Garzik 		default:
275669a5db4SJeff Garzik 			/* BUG() ? */
276669a5db4SJeff Garzik 			/* fall through */
277669a5db4SJeff Garzik 		case 33:
278669a5db4SJeff Garzik 			ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 5) - 2)) : 0x03;
279669a5db4SJeff Garzik 			break;
280669a5db4SJeff Garzik 		case 66:
281669a5db4SJeff Garzik 			ut = t.udma ? (0xe8 | (FIT(t.udma, 2, 9) - 2)) : 0x0f;
282669a5db4SJeff Garzik 			break;
283669a5db4SJeff Garzik 		case 100:
284669a5db4SJeff Garzik 			ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 9) - 2)) : 0x07;
285669a5db4SJeff Garzik 			break;
286669a5db4SJeff Garzik 		case 133:
287669a5db4SJeff Garzik 			ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 9) - 2)) : 0x07;
288669a5db4SJeff Garzik 			break;
289669a5db4SJeff Garzik 	}
290669a5db4SJeff Garzik 	/* Set UDMA unless device is not UDMA capable */
291669a5db4SJeff Garzik 	if (udma_type)
292669a5db4SJeff Garzik 		pci_write_config_byte(pdev, 0x50 + offset, ut);
293669a5db4SJeff Garzik }
294669a5db4SJeff Garzik 
295669a5db4SJeff Garzik static void via_set_piomode(struct ata_port *ap, struct ata_device *adev)
296669a5db4SJeff Garzik {
297669a5db4SJeff Garzik 	const struct via_isa_bridge *config = ap->host->private_data;
298669a5db4SJeff Garzik 	int set_ast = (config->flags & VIA_BAD_AST) ? 0 : 1;
299669a5db4SJeff Garzik 	int mode = config->flags & VIA_UDMA;
300669a5db4SJeff Garzik 	static u8 tclock[5] = { 1, 1, 2, 3, 4 };
301669a5db4SJeff Garzik 	static u8 udma[5] = { 0, 33, 66, 100, 133 };
302669a5db4SJeff Garzik 
303669a5db4SJeff Garzik 	via_do_set_mode(ap, adev, adev->pio_mode, tclock[mode], set_ast, udma[mode]);
304669a5db4SJeff Garzik }
305669a5db4SJeff Garzik 
306669a5db4SJeff Garzik static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev)
307669a5db4SJeff Garzik {
308669a5db4SJeff Garzik 	const struct via_isa_bridge *config = ap->host->private_data;
309669a5db4SJeff Garzik 	int set_ast = (config->flags & VIA_BAD_AST) ? 0 : 1;
310669a5db4SJeff Garzik 	int mode = config->flags & VIA_UDMA;
311669a5db4SJeff Garzik 	static u8 tclock[5] = { 1, 1, 2, 3, 4 };
312669a5db4SJeff Garzik 	static u8 udma[5] = { 0, 33, 66, 100, 133 };
313669a5db4SJeff Garzik 
314669a5db4SJeff Garzik 	via_do_set_mode(ap, adev, adev->dma_mode, tclock[mode], set_ast, udma[mode]);
315669a5db4SJeff Garzik }
316669a5db4SJeff Garzik 
317669a5db4SJeff Garzik static struct scsi_host_template via_sht = {
318669a5db4SJeff Garzik 	.module			= THIS_MODULE,
319669a5db4SJeff Garzik 	.name			= DRV_NAME,
320669a5db4SJeff Garzik 	.ioctl			= ata_scsi_ioctl,
321669a5db4SJeff Garzik 	.queuecommand		= ata_scsi_queuecmd,
322669a5db4SJeff Garzik 	.can_queue		= ATA_DEF_QUEUE,
323669a5db4SJeff Garzik 	.this_id		= ATA_SHT_THIS_ID,
324669a5db4SJeff Garzik 	.sg_tablesize		= LIBATA_MAX_PRD,
325669a5db4SJeff Garzik 	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
326669a5db4SJeff Garzik 	.emulated		= ATA_SHT_EMULATED,
327669a5db4SJeff Garzik 	.use_clustering		= ATA_SHT_USE_CLUSTERING,
328669a5db4SJeff Garzik 	.proc_name		= DRV_NAME,
329669a5db4SJeff Garzik 	.dma_boundary		= ATA_DMA_BOUNDARY,
330669a5db4SJeff Garzik 	.slave_configure	= ata_scsi_slave_config,
331afdfe899STejun Heo 	.slave_destroy		= ata_scsi_slave_destroy,
332669a5db4SJeff Garzik 	.bios_param		= ata_std_bios_param,
333669a5db4SJeff Garzik };
334669a5db4SJeff Garzik 
335669a5db4SJeff Garzik static struct ata_port_operations via_port_ops = {
336669a5db4SJeff Garzik 	.port_disable	= ata_port_disable,
337669a5db4SJeff Garzik 	.set_piomode	= via_set_piomode,
338669a5db4SJeff Garzik 	.set_dmamode	= via_set_dmamode,
339669a5db4SJeff Garzik 	.mode_filter	= ata_pci_default_filter,
340669a5db4SJeff Garzik 
341669a5db4SJeff Garzik 	.tf_load	= ata_tf_load,
342669a5db4SJeff Garzik 	.tf_read	= ata_tf_read,
343669a5db4SJeff Garzik 	.check_status 	= ata_check_status,
344669a5db4SJeff Garzik 	.exec_command	= ata_exec_command,
345669a5db4SJeff Garzik 	.dev_select 	= ata_std_dev_select,
346669a5db4SJeff Garzik 
347669a5db4SJeff Garzik 	.freeze		= ata_bmdma_freeze,
348669a5db4SJeff Garzik 	.thaw		= ata_bmdma_thaw,
349669a5db4SJeff Garzik 	.error_handler	= via_error_handler,
350669a5db4SJeff Garzik 	.post_internal_cmd = ata_bmdma_post_internal_cmd,
35197cb81c3SAlan Cox 	.cable_detect	= via_cable_detect,
352669a5db4SJeff Garzik 
353669a5db4SJeff Garzik 	.bmdma_setup 	= ata_bmdma_setup,
354669a5db4SJeff Garzik 	.bmdma_start 	= ata_bmdma_start,
355669a5db4SJeff Garzik 	.bmdma_stop	= ata_bmdma_stop,
356669a5db4SJeff Garzik 	.bmdma_status 	= ata_bmdma_status,
357669a5db4SJeff Garzik 
358669a5db4SJeff Garzik 	.qc_prep 	= ata_qc_prep,
359669a5db4SJeff Garzik 	.qc_issue	= ata_qc_issue_prot,
360bda30288SJeff Garzik 
3610d5ff566STejun Heo 	.data_xfer	= ata_data_xfer,
362669a5db4SJeff Garzik 
363669a5db4SJeff Garzik 	.irq_handler	= ata_interrupt,
364669a5db4SJeff Garzik 	.irq_clear	= ata_bmdma_irq_clear,
365246ce3b6SAkira Iguchi 	.irq_on		= ata_irq_on,
366246ce3b6SAkira Iguchi 	.irq_ack	= ata_irq_ack,
367669a5db4SJeff Garzik 
368669a5db4SJeff Garzik 	.port_start	= ata_port_start,
369669a5db4SJeff Garzik };
370669a5db4SJeff Garzik 
371669a5db4SJeff Garzik static struct ata_port_operations via_port_ops_noirq = {
372669a5db4SJeff Garzik 	.port_disable	= ata_port_disable,
373669a5db4SJeff Garzik 	.set_piomode	= via_set_piomode,
374669a5db4SJeff Garzik 	.set_dmamode	= via_set_dmamode,
375669a5db4SJeff Garzik 	.mode_filter	= ata_pci_default_filter,
376669a5db4SJeff Garzik 
377669a5db4SJeff Garzik 	.tf_load	= ata_tf_load,
378669a5db4SJeff Garzik 	.tf_read	= ata_tf_read,
379669a5db4SJeff Garzik 	.check_status 	= ata_check_status,
380669a5db4SJeff Garzik 	.exec_command	= ata_exec_command,
381669a5db4SJeff Garzik 	.dev_select 	= ata_std_dev_select,
382669a5db4SJeff Garzik 
383669a5db4SJeff Garzik 	.freeze		= ata_bmdma_freeze,
384669a5db4SJeff Garzik 	.thaw		= ata_bmdma_thaw,
385669a5db4SJeff Garzik 	.error_handler	= via_error_handler,
386669a5db4SJeff Garzik 	.post_internal_cmd = ata_bmdma_post_internal_cmd,
38797cb81c3SAlan Cox 	.cable_detect	= via_cable_detect,
388669a5db4SJeff Garzik 
389669a5db4SJeff Garzik 	.bmdma_setup 	= ata_bmdma_setup,
390669a5db4SJeff Garzik 	.bmdma_start 	= ata_bmdma_start,
391669a5db4SJeff Garzik 	.bmdma_stop	= ata_bmdma_stop,
392669a5db4SJeff Garzik 	.bmdma_status 	= ata_bmdma_status,
393669a5db4SJeff Garzik 
394669a5db4SJeff Garzik 	.qc_prep 	= ata_qc_prep,
395669a5db4SJeff Garzik 	.qc_issue	= ata_qc_issue_prot,
396bda30288SJeff Garzik 
3970d5ff566STejun Heo 	.data_xfer	= ata_data_xfer_noirq,
398669a5db4SJeff Garzik 
399669a5db4SJeff Garzik 	.irq_handler	= ata_interrupt,
400669a5db4SJeff Garzik 	.irq_clear	= ata_bmdma_irq_clear,
401246ce3b6SAkira Iguchi 	.irq_on		= ata_irq_on,
402246ce3b6SAkira Iguchi 	.irq_ack	= ata_irq_ack,
403669a5db4SJeff Garzik 
404669a5db4SJeff Garzik 	.port_start	= ata_port_start,
405669a5db4SJeff Garzik };
406669a5db4SJeff Garzik 
407669a5db4SJeff Garzik /**
408627d2d32SAlan  *	via_config_fifo		-	set up the FIFO
409627d2d32SAlan  *	@pdev: PCI device
410627d2d32SAlan  *	@flags: configuration flags
411627d2d32SAlan  *
412627d2d32SAlan  *	Set the FIFO properties for this device if neccessary. Used both on
413627d2d32SAlan  *	set up and on and the resume path
414627d2d32SAlan  */
415627d2d32SAlan 
416627d2d32SAlan static void via_config_fifo(struct pci_dev *pdev, unsigned int flags)
417627d2d32SAlan {
418627d2d32SAlan 	u8 enable;
419627d2d32SAlan 
420627d2d32SAlan 	/* 0x40 low bits indicate enabled channels */
421627d2d32SAlan 	pci_read_config_byte(pdev, 0x40 , &enable);
422627d2d32SAlan 	enable &= 3;
423627d2d32SAlan 
424627d2d32SAlan 	if (flags & VIA_SET_FIFO) {
42573720861SAndrew Morton 		static const u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
426627d2d32SAlan 		u8 fifo;
427627d2d32SAlan 
428627d2d32SAlan 		pci_read_config_byte(pdev, 0x43, &fifo);
429627d2d32SAlan 
430627d2d32SAlan 		/* Clear PREQ# until DDACK# for errata */
431627d2d32SAlan 		if (flags & VIA_BAD_PREQ)
432627d2d32SAlan 			fifo &= 0x7F;
433627d2d32SAlan 		else
434627d2d32SAlan 			fifo &= 0x9f;
435627d2d32SAlan 		/* Turn on FIFO for enabled channels */
436627d2d32SAlan 		fifo |= fifo_setting[enable];
437627d2d32SAlan 		pci_write_config_byte(pdev, 0x43, fifo);
438627d2d32SAlan 	}
439627d2d32SAlan }
440627d2d32SAlan 
441627d2d32SAlan /**
442669a5db4SJeff Garzik  *	via_init_one		-	discovery callback
443627d2d32SAlan  *	@pdev: PCI device
444669a5db4SJeff Garzik  *	@id: PCI table info
445669a5db4SJeff Garzik  *
446669a5db4SJeff Garzik  *	A VIA IDE interface has been discovered. Figure out what revision
447669a5db4SJeff Garzik  *	and perform configuration work before handing it to the ATA layer
448669a5db4SJeff Garzik  */
449669a5db4SJeff Garzik 
450669a5db4SJeff Garzik static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
451669a5db4SJeff Garzik {
452669a5db4SJeff Garzik 	/* Early VIA without UDMA support */
4531626aeb8STejun Heo 	static const struct ata_port_info via_mwdma_info = {
454669a5db4SJeff Garzik 		.sht = &via_sht,
4553d3cca37STejun Heo 		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
456669a5db4SJeff Garzik 		.pio_mask = 0x1f,
457669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
458669a5db4SJeff Garzik 		.port_ops = &via_port_ops
459669a5db4SJeff Garzik 	};
460669a5db4SJeff Garzik 	/* Ditto with IRQ masking required */
4611626aeb8STejun Heo 	static const struct ata_port_info via_mwdma_info_borked = {
462669a5db4SJeff Garzik 		.sht = &via_sht,
4633d3cca37STejun Heo 		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
464669a5db4SJeff Garzik 		.pio_mask = 0x1f,
465669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
466669a5db4SJeff Garzik 		.port_ops = &via_port_ops_noirq,
467669a5db4SJeff Garzik 	};
468669a5db4SJeff Garzik 	/* VIA UDMA 33 devices (and borked 66) */
4691626aeb8STejun Heo 	static const struct ata_port_info via_udma33_info = {
470669a5db4SJeff Garzik 		.sht = &via_sht,
4713d3cca37STejun Heo 		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
472669a5db4SJeff Garzik 		.pio_mask = 0x1f,
473669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
474669a5db4SJeff Garzik 		.udma_mask = 0x7,
475669a5db4SJeff Garzik 		.port_ops = &via_port_ops
476669a5db4SJeff Garzik 	};
477669a5db4SJeff Garzik 	/* VIA UDMA 66 devices */
4781626aeb8STejun Heo 	static const struct ata_port_info via_udma66_info = {
479669a5db4SJeff Garzik 		.sht = &via_sht,
4803d3cca37STejun Heo 		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
481669a5db4SJeff Garzik 		.pio_mask = 0x1f,
482669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
483669a5db4SJeff Garzik 		.udma_mask = 0x1f,
484669a5db4SJeff Garzik 		.port_ops = &via_port_ops
485669a5db4SJeff Garzik 	};
486669a5db4SJeff Garzik 	/* VIA UDMA 100 devices */
4871626aeb8STejun Heo 	static const struct ata_port_info via_udma100_info = {
488669a5db4SJeff Garzik 		.sht = &via_sht,
4893d3cca37STejun Heo 		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
490669a5db4SJeff Garzik 		.pio_mask = 0x1f,
491669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
492669a5db4SJeff Garzik 		.udma_mask = 0x3f,
493669a5db4SJeff Garzik 		.port_ops = &via_port_ops
494669a5db4SJeff Garzik 	};
495669a5db4SJeff Garzik 	/* UDMA133 with bad AST (All current 133) */
4961626aeb8STejun Heo 	static const struct ata_port_info via_udma133_info = {
497669a5db4SJeff Garzik 		.sht = &via_sht,
4983d3cca37STejun Heo 		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
499669a5db4SJeff Garzik 		.pio_mask = 0x1f,
500669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
501669a5db4SJeff Garzik 		.udma_mask = 0x7f,	/* FIXME: should check north bridge */
502669a5db4SJeff Garzik 		.port_ops = &via_port_ops
503669a5db4SJeff Garzik 	};
5041626aeb8STejun Heo 	struct ata_port_info type;
5051626aeb8STejun Heo 	const struct ata_port_info *ppi[] = { &type, NULL };
506669a5db4SJeff Garzik 	struct pci_dev *isa = NULL;
507669a5db4SJeff Garzik 	const struct via_isa_bridge *config;
508669a5db4SJeff Garzik 	static int printed_version;
509669a5db4SJeff Garzik 	u8 t;
510669a5db4SJeff Garzik 	u8 enable;
511669a5db4SJeff Garzik 	u32 timing;
512669a5db4SJeff Garzik 
513669a5db4SJeff Garzik 	if (!printed_version++)
514669a5db4SJeff Garzik 		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
515669a5db4SJeff Garzik 
516669a5db4SJeff Garzik 	/* To find out how the IDE will behave and what features we
517669a5db4SJeff Garzik 	   actually have to look at the bridge not the IDE controller */
518669a5db4SJeff Garzik 	for (config = via_isa_bridges; config->id; config++)
519669a5db4SJeff Garzik 		if ((isa = pci_get_device(PCI_VENDOR_ID_VIA +
520669a5db4SJeff Garzik 			!!(config->flags & VIA_BAD_ID),
521669a5db4SJeff Garzik 			config->id, NULL))) {
522669a5db4SJeff Garzik 
523669a5db4SJeff Garzik 			pci_read_config_byte(isa, PCI_REVISION_ID, &t);
524669a5db4SJeff Garzik 			if (t >= config->rev_min &&
525669a5db4SJeff Garzik 			    t <= config->rev_max)
526669a5db4SJeff Garzik 				break;
527669a5db4SJeff Garzik 			pci_dev_put(isa);
528669a5db4SJeff Garzik 		}
529669a5db4SJeff Garzik 
530669a5db4SJeff Garzik 	if (!config->id) {
531669a5db4SJeff Garzik 		printk(KERN_WARNING "via: Unknown VIA SouthBridge, disabling.\n");
532669a5db4SJeff Garzik 		return -ENODEV;
533669a5db4SJeff Garzik 	}
534669a5db4SJeff Garzik 	pci_dev_put(isa);
535669a5db4SJeff Garzik 
536669a5db4SJeff Garzik 	/* 0x40 low bits indicate enabled channels */
537669a5db4SJeff Garzik 	pci_read_config_byte(pdev, 0x40 , &enable);
538669a5db4SJeff Garzik 	enable &= 3;
539669a5db4SJeff Garzik 	if (enable == 0) {
540669a5db4SJeff Garzik 		return -ENODEV;
541669a5db4SJeff Garzik 	}
542669a5db4SJeff Garzik 
543669a5db4SJeff Garzik 	/* Initialise the FIFO for the enabled channels. */
544627d2d32SAlan 	via_config_fifo(pdev, config->flags);
545669a5db4SJeff Garzik 
546669a5db4SJeff Garzik 	/* Clock set up */
547669a5db4SJeff Garzik 	switch(config->flags & VIA_UDMA) {
548669a5db4SJeff Garzik 		case VIA_UDMA_NONE:
549669a5db4SJeff Garzik 			if (config->flags & VIA_NO_UNMASK)
5501626aeb8STejun Heo 				type = via_mwdma_info_borked;
551669a5db4SJeff Garzik 			else
5521626aeb8STejun Heo 				type = via_mwdma_info;
553669a5db4SJeff Garzik 			break;
554669a5db4SJeff Garzik 		case VIA_UDMA_33:
5551626aeb8STejun Heo 			type = via_udma33_info;
556669a5db4SJeff Garzik 			break;
557669a5db4SJeff Garzik 		case VIA_UDMA_66:
5581626aeb8STejun Heo 			type = via_udma66_info;
559669a5db4SJeff Garzik 			/* The 66 MHz devices require we enable the clock */
560669a5db4SJeff Garzik 			pci_read_config_dword(pdev, 0x50, &timing);
561669a5db4SJeff Garzik 			timing |= 0x80008;
562669a5db4SJeff Garzik 			pci_write_config_dword(pdev, 0x50, timing);
563669a5db4SJeff Garzik 			break;
564669a5db4SJeff Garzik 		case VIA_UDMA_100:
5651626aeb8STejun Heo 			type = via_udma100_info;
566669a5db4SJeff Garzik 			break;
567669a5db4SJeff Garzik 		case VIA_UDMA_133:
5681626aeb8STejun Heo 			type = via_udma133_info;
569669a5db4SJeff Garzik 			break;
570669a5db4SJeff Garzik 		default:
571669a5db4SJeff Garzik 			WARN_ON(1);
572669a5db4SJeff Garzik 			return -ENODEV;
573669a5db4SJeff Garzik 	}
574669a5db4SJeff Garzik 
575669a5db4SJeff Garzik 	if (config->flags & VIA_BAD_CLK66) {
576669a5db4SJeff Garzik 		/* Disable the 66MHz clock on problem devices */
577669a5db4SJeff Garzik 		pci_read_config_dword(pdev, 0x50, &timing);
578669a5db4SJeff Garzik 		timing &= ~0x80008;
579669a5db4SJeff Garzik 		pci_write_config_dword(pdev, 0x50, timing);
580669a5db4SJeff Garzik 	}
581669a5db4SJeff Garzik 
582669a5db4SJeff Garzik 	/* We have established the device type, now fire it up */
5831626aeb8STejun Heo 	type.private_data = (void *)config;
584669a5db4SJeff Garzik 
5851626aeb8STejun Heo 	return ata_pci_init_one(pdev, ppi);
586669a5db4SJeff Garzik }
587669a5db4SJeff Garzik 
588438ac6d5STejun Heo #ifdef CONFIG_PM
589627d2d32SAlan /**
590627d2d32SAlan  *	via_reinit_one		-	reinit after resume
591627d2d32SAlan  *	@pdev; PCI device
592627d2d32SAlan  *
593627d2d32SAlan  *	Called when the VIA PATA device is resumed. We must then
594627d2d32SAlan  *	reconfigure the fifo and other setup we may have altered. In
595627d2d32SAlan  *	addition the kernel needs to have the resume methods on PCI
596627d2d32SAlan  *	quirk supported.
597627d2d32SAlan  */
598627d2d32SAlan 
599627d2d32SAlan static int via_reinit_one(struct pci_dev *pdev)
600627d2d32SAlan {
601627d2d32SAlan 	u32 timing;
602627d2d32SAlan 	struct ata_host *host = dev_get_drvdata(&pdev->dev);
603627d2d32SAlan 	const struct via_isa_bridge *config = host->private_data;
604627d2d32SAlan 
605627d2d32SAlan 	via_config_fifo(pdev, config->flags);
606627d2d32SAlan 
607627d2d32SAlan 	if ((config->flags & VIA_UDMA) == VIA_UDMA_66) {
608627d2d32SAlan 		/* The 66 MHz devices require we enable the clock */
609627d2d32SAlan 		pci_read_config_dword(pdev, 0x50, &timing);
610627d2d32SAlan 		timing |= 0x80008;
611627d2d32SAlan 		pci_write_config_dword(pdev, 0x50, timing);
612627d2d32SAlan 	}
613627d2d32SAlan 	if (config->flags & VIA_BAD_CLK66) {
614627d2d32SAlan 		/* Disable the 66MHz clock on problem devices */
615627d2d32SAlan 		pci_read_config_dword(pdev, 0x50, &timing);
616627d2d32SAlan 		timing &= ~0x80008;
617627d2d32SAlan 		pci_write_config_dword(pdev, 0x50, timing);
618627d2d32SAlan 	}
619627d2d32SAlan 	return ata_pci_device_resume(pdev);
620627d2d32SAlan }
621438ac6d5STejun Heo #endif
622627d2d32SAlan 
623669a5db4SJeff Garzik static const struct pci_device_id via[] = {
6242d2744fcSJeff Garzik 	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), },
6252d2744fcSJeff Garzik 	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), },
6262d2744fcSJeff Garzik 	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), },
6272d2744fcSJeff Garzik 	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), },
6282d2744fcSJeff Garzik 
6292d2744fcSJeff Garzik 	{ },
630669a5db4SJeff Garzik };
631669a5db4SJeff Garzik 
632669a5db4SJeff Garzik static struct pci_driver via_pci_driver = {
633669a5db4SJeff Garzik 	.name 		= DRV_NAME,
634669a5db4SJeff Garzik 	.id_table	= via,
635669a5db4SJeff Garzik 	.probe 		= via_init_one,
636627d2d32SAlan 	.remove		= ata_pci_remove_one,
637438ac6d5STejun Heo #ifdef CONFIG_PM
638627d2d32SAlan 	.suspend	= ata_pci_device_suspend,
639627d2d32SAlan 	.resume		= via_reinit_one,
640438ac6d5STejun Heo #endif
641669a5db4SJeff Garzik };
642669a5db4SJeff Garzik 
643669a5db4SJeff Garzik static int __init via_init(void)
644669a5db4SJeff Garzik {
645669a5db4SJeff Garzik 	return pci_register_driver(&via_pci_driver);
646669a5db4SJeff Garzik }
647669a5db4SJeff Garzik 
648669a5db4SJeff Garzik static void __exit via_exit(void)
649669a5db4SJeff Garzik {
650669a5db4SJeff Garzik 	pci_unregister_driver(&via_pci_driver);
651669a5db4SJeff Garzik }
652669a5db4SJeff Garzik 
653669a5db4SJeff Garzik MODULE_AUTHOR("Alan Cox");
654669a5db4SJeff Garzik MODULE_DESCRIPTION("low-level driver for VIA PATA");
655669a5db4SJeff Garzik MODULE_LICENSE("GPL");
656669a5db4SJeff Garzik MODULE_DEVICE_TABLE(pci, via);
657669a5db4SJeff Garzik MODULE_VERSION(DRV_VERSION);
658669a5db4SJeff Garzik 
659669a5db4SJeff Garzik module_init(via_init);
660669a5db4SJeff Garzik module_exit(via_exit);
661