PageRenderTime 55ms CodeModel.GetById 2ms app.highlight 47ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/ide/arm/icside.c

https://bitbucket.org/evzijst/gittest
C | 870 lines | 580 code | 162 blank | 128 comment | 56 complexity | 0a79e40ee31298115bca1383c4e34bda MD5 | raw file
  1/*
  2 * linux/drivers/ide/arm/icside.c
  3 *
  4 * Copyright (c) 1996-2004 Russell King.
  5 *
  6 * Please note that this platform does not support 32-bit IDE IO.
  7 */
  8
  9#include <linux/config.h>
 10#include <linux/string.h>
 11#include <linux/module.h>
 12#include <linux/ioport.h>
 13#include <linux/slab.h>
 14#include <linux/blkdev.h>
 15#include <linux/errno.h>
 16#include <linux/hdreg.h>
 17#include <linux/ide.h>
 18#include <linux/dma-mapping.h>
 19#include <linux/device.h>
 20#include <linux/init.h>
 21#include <linux/scatterlist.h>
 22
 23#include <asm/dma.h>
 24#include <asm/ecard.h>
 25#include <asm/io.h>
 26
 27#define ICS_IDENT_OFFSET		0x2280
 28
 29#define ICS_ARCIN_V5_INTRSTAT		0x0000
 30#define ICS_ARCIN_V5_INTROFFSET		0x0004
 31#define ICS_ARCIN_V5_IDEOFFSET		0x2800
 32#define ICS_ARCIN_V5_IDEALTOFFSET	0x2b80
 33#define ICS_ARCIN_V5_IDESTEPPING	6
 34
 35#define ICS_ARCIN_V6_IDEOFFSET_1	0x2000
 36#define ICS_ARCIN_V6_INTROFFSET_1	0x2200
 37#define ICS_ARCIN_V6_INTRSTAT_1		0x2290
 38#define ICS_ARCIN_V6_IDEALTOFFSET_1	0x2380
 39#define ICS_ARCIN_V6_IDEOFFSET_2	0x3000
 40#define ICS_ARCIN_V6_INTROFFSET_2	0x3200
 41#define ICS_ARCIN_V6_INTRSTAT_2		0x3290
 42#define ICS_ARCIN_V6_IDEALTOFFSET_2	0x3380
 43#define ICS_ARCIN_V6_IDESTEPPING	6
 44
 45struct cardinfo {
 46	unsigned int dataoffset;
 47	unsigned int ctrloffset;
 48	unsigned int stepping;
 49};
 50
 51static struct cardinfo icside_cardinfo_v5 = {
 52	.dataoffset	= ICS_ARCIN_V5_IDEOFFSET,
 53	.ctrloffset	= ICS_ARCIN_V5_IDEALTOFFSET,
 54	.stepping	= ICS_ARCIN_V5_IDESTEPPING,
 55};
 56
 57static struct cardinfo icside_cardinfo_v6_1 = {
 58	.dataoffset	= ICS_ARCIN_V6_IDEOFFSET_1,
 59	.ctrloffset	= ICS_ARCIN_V6_IDEALTOFFSET_1,
 60	.stepping	= ICS_ARCIN_V6_IDESTEPPING,
 61};
 62
 63static struct cardinfo icside_cardinfo_v6_2 = {
 64	.dataoffset	= ICS_ARCIN_V6_IDEOFFSET_2,
 65	.ctrloffset	= ICS_ARCIN_V6_IDEALTOFFSET_2,
 66	.stepping	= ICS_ARCIN_V6_IDESTEPPING,
 67};
 68
 69struct icside_state {
 70	unsigned int channel;
 71	unsigned int enabled;
 72	void __iomem *irq_port;
 73	void __iomem *ioc_base;
 74	unsigned int type;
 75	/* parent device... until the IDE core gets one of its own */
 76	struct device *dev;
 77	ide_hwif_t *hwif[2];
 78};
 79
 80#define ICS_TYPE_A3IN	0
 81#define ICS_TYPE_A3USER	1
 82#define ICS_TYPE_V6	3
 83#define ICS_TYPE_V5	15
 84#define ICS_TYPE_NOTYPE	((unsigned int)-1)
 85
 86/* ---------------- Version 5 PCB Support Functions --------------------- */
 87/* Prototype: icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
 88 * Purpose  : enable interrupts from card
 89 */
 90static void icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
 91{
 92	struct icside_state *state = ec->irq_data;
 93
 94	writeb(0, state->irq_port + ICS_ARCIN_V5_INTROFFSET);
 95}
 96
 97/* Prototype: icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
 98 * Purpose  : disable interrupts from card
 99 */
100static void icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
101{
102	struct icside_state *state = ec->irq_data;
103
104	readb(state->irq_port + ICS_ARCIN_V5_INTROFFSET);
105}
106
107static const expansioncard_ops_t icside_ops_arcin_v5 = {
108	.irqenable	= icside_irqenable_arcin_v5,
109	.irqdisable	= icside_irqdisable_arcin_v5,
110};
111
112
113/* ---------------- Version 6 PCB Support Functions --------------------- */
114/* Prototype: icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
115 * Purpose  : enable interrupts from card
116 */
117static void icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
118{
119	struct icside_state *state = ec->irq_data;
120	void __iomem *base = state->irq_port;
121
122	state->enabled = 1;
123
124	switch (state->channel) {
125	case 0:
126		writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
127		readb(base + ICS_ARCIN_V6_INTROFFSET_2);
128		break;
129	case 1:
130		writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
131		readb(base + ICS_ARCIN_V6_INTROFFSET_1);
132		break;
133	}
134}
135
136/* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
137 * Purpose  : disable interrupts from card
138 */
139static void icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
140{
141	struct icside_state *state = ec->irq_data;
142
143	state->enabled = 0;
144
145	readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
146	readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
147}
148
149/* Prototype: icside_irqprobe(struct expansion_card *ec)
150 * Purpose  : detect an active interrupt from card
151 */
152static int icside_irqpending_arcin_v6(struct expansion_card *ec)
153{
154	struct icside_state *state = ec->irq_data;
155
156	return readb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 ||
157	       readb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_2) & 1;
158}
159
160static const expansioncard_ops_t icside_ops_arcin_v6 = {
161	.irqenable	= icside_irqenable_arcin_v6,
162	.irqdisable	= icside_irqdisable_arcin_v6,
163	.irqpending	= icside_irqpending_arcin_v6,
164};
165
166/*
167 * Handle routing of interrupts.  This is called before
168 * we write the command to the drive.
169 */
170static void icside_maskproc(ide_drive_t *drive, int mask)
171{
172	ide_hwif_t *hwif = HWIF(drive);
173	struct icside_state *state = hwif->hwif_data;
174	unsigned long flags;
175
176	local_irq_save(flags);
177
178	state->channel = hwif->channel;
179
180	if (state->enabled && !mask) {
181		switch (hwif->channel) {
182		case 0:
183			writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
184			readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
185			break;
186		case 1:
187			writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
188			readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
189			break;
190		}
191	} else {
192		readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
193		readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
194	}
195
196	local_irq_restore(flags);
197}
198
199#ifdef CONFIG_BLK_DEV_IDEDMA_ICS
200
201#ifndef CONFIG_IDEDMA_ICS_AUTO
202#warning CONFIG_IDEDMA_ICS_AUTO=n support is obsolete, and will be removed soon.
203#endif
204
205/*
206 * SG-DMA support.
207 *
208 * Similar to the BM-DMA, but we use the RiscPCs IOMD DMA controllers.
209 * There is only one DMA controller per card, which means that only
210 * one drive can be accessed at one time.  NOTE! We do not enforce that
211 * here, but we rely on the main IDE driver spotting that both
212 * interfaces use the same IRQ, which should guarantee this.
213 */
214
215static void icside_build_sglist(ide_drive_t *drive, struct request *rq)
216{
217	ide_hwif_t *hwif = drive->hwif;
218	struct icside_state *state = hwif->hwif_data;
219	struct scatterlist *sg = hwif->sg_table;
220
221	ide_map_sg(drive, rq);
222
223	if (rq_data_dir(rq) == READ)
224		hwif->sg_dma_direction = DMA_FROM_DEVICE;
225	else
226		hwif->sg_dma_direction = DMA_TO_DEVICE;
227
228	hwif->sg_nents = dma_map_sg(state->dev, sg, hwif->sg_nents,
229				    hwif->sg_dma_direction);
230}
231
232/*
233 * Configure the IOMD to give the appropriate timings for the transfer
234 * mode being requested.  We take the advice of the ATA standards, and
235 * calculate the cycle time based on the transfer mode, and the EIDE
236 * MW DMA specs that the drive provides in the IDENTIFY command.
237 *
238 * We have the following IOMD DMA modes to choose from:
239 *
240 *	Type	Active		Recovery	Cycle
241 *	A	250 (250)	312 (550)	562 (800)
242 *	B	187		250		437
243 *	C	125 (125)	125 (375)	250 (500)
244 *	D	62		125		187
245 *
246 * (figures in brackets are actual measured timings)
247 *
248 * However, we also need to take care of the read/write active and
249 * recovery timings:
250 *
251 *			Read	Write
252 *  	Mode	Active	-- Recovery --	Cycle	IOMD type
253 *	MW0	215	50	215	480	A
254 *	MW1	80	50	50	150	C
255 *	MW2	70	25	25	120	C
256 */
257static int icside_set_speed(ide_drive_t *drive, u8 xfer_mode)
258{
259	int on = 0, cycle_time = 0, use_dma_info = 0;
260
261	/*
262	 * Limit the transfer speed to MW_DMA_2.
263	 */
264	if (xfer_mode > XFER_MW_DMA_2)
265		xfer_mode = XFER_MW_DMA_2;
266
267	switch (xfer_mode) {
268	case XFER_MW_DMA_2:
269		cycle_time = 250;
270		use_dma_info = 1;
271		break;
272
273	case XFER_MW_DMA_1:
274		cycle_time = 250;
275		use_dma_info = 1;
276		break;
277
278	case XFER_MW_DMA_0:
279		cycle_time = 480;
280		break;
281
282	case XFER_SW_DMA_2:
283	case XFER_SW_DMA_1:
284	case XFER_SW_DMA_0:
285		cycle_time = 480;
286		break;
287	}
288
289	/*
290	 * If we're going to be doing MW_DMA_1 or MW_DMA_2, we should
291	 * take care to note the values in the ID...
292	 */
293	if (use_dma_info && drive->id->eide_dma_time > cycle_time)
294		cycle_time = drive->id->eide_dma_time;
295
296	drive->drive_data = cycle_time;
297
298	if (cycle_time && ide_config_drive_speed(drive, xfer_mode) == 0)
299		on = 1;
300	else
301		drive->drive_data = 480;
302
303	printk("%s: %s selected (peak %dMB/s)\n", drive->name,
304		ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data);
305
306	drive->current_speed = xfer_mode;
307
308	return on;
309}
310
311static int icside_dma_host_off(ide_drive_t *drive)
312{
313	return 0;
314}
315
316static int icside_dma_off_quietly(ide_drive_t *drive)
317{
318	drive->using_dma = 0;
319	return icside_dma_host_off(drive);
320}
321
322static int icside_dma_host_on(ide_drive_t *drive)
323{
324	return 0;
325}
326
327static int icside_dma_on(ide_drive_t *drive)
328{
329	drive->using_dma = 1;
330	return icside_dma_host_on(drive);
331}
332
333static int icside_dma_check(ide_drive_t *drive)
334{
335	struct hd_driveid *id = drive->id;
336	ide_hwif_t *hwif = HWIF(drive);
337	int xfer_mode = XFER_PIO_2;
338	int on;
339
340	if (!(id->capability & 1) || !hwif->autodma)
341		goto out;
342
343	/*
344	 * Consult the list of known "bad" drives
345	 */
346	if (__ide_dma_bad_drive(drive))
347		goto out;
348
349	/*
350	 * Enable DMA on any drive that has multiword DMA
351	 */
352	if (id->field_valid & 2) {
353		xfer_mode = ide_dma_speed(drive, 0);
354		goto out;
355	}
356
357	/*
358	 * Consult the list of known "good" drives
359	 */
360	if (__ide_dma_good_drive(drive)) {
361		if (id->eide_dma_time > 150)
362			goto out;
363		xfer_mode = XFER_MW_DMA_1;
364	}
365
366out:
367	on = icside_set_speed(drive, xfer_mode);
368
369	if (on)
370		return icside_dma_on(drive);
371	else
372		return icside_dma_off_quietly(drive);
373}
374
375static int icside_dma_end(ide_drive_t *drive)
376{
377	ide_hwif_t *hwif = HWIF(drive);
378	struct icside_state *state = hwif->hwif_data;
379
380	drive->waiting_for_dma = 0;
381
382	disable_dma(hwif->hw.dma);
383
384	/* Teardown mappings after DMA has completed. */
385	dma_unmap_sg(state->dev, hwif->sg_table, hwif->sg_nents,
386		     hwif->sg_dma_direction);
387
388	return get_dma_residue(hwif->hw.dma) != 0;
389}
390
391static void icside_dma_start(ide_drive_t *drive)
392{
393	ide_hwif_t *hwif = HWIF(drive);
394
395	/* We can not enable DMA on both channels simultaneously. */
396	BUG_ON(dma_channel_active(hwif->hw.dma));
397	enable_dma(hwif->hw.dma);
398}
399
400static int icside_dma_setup(ide_drive_t *drive)
401{
402	ide_hwif_t *hwif = HWIF(drive);
403	struct request *rq = hwif->hwgroup->rq;
404	unsigned int dma_mode;
405
406	if (rq_data_dir(rq))
407		dma_mode = DMA_MODE_WRITE;
408	else
409		dma_mode = DMA_MODE_READ;
410
411	/*
412	 * We can not enable DMA on both channels.
413	 */
414	BUG_ON(dma_channel_active(hwif->hw.dma));
415
416	icside_build_sglist(drive, rq);
417
418	/*
419	 * Ensure that we have the right interrupt routed.
420	 */
421	icside_maskproc(drive, 0);
422
423	/*
424	 * Route the DMA signals to the correct interface.
425	 */
426	writeb(hwif->select_data, hwif->config_data);
427
428	/*
429	 * Select the correct timing for this drive.
430	 */
431	set_dma_speed(hwif->hw.dma, drive->drive_data);
432
433	/*
434	 * Tell the DMA engine about the SG table and
435	 * data direction.
436	 */
437	set_dma_sg(hwif->hw.dma, hwif->sg_table, hwif->sg_nents);
438	set_dma_mode(hwif->hw.dma, dma_mode);
439
440	drive->waiting_for_dma = 1;
441
442	return 0;
443}
444
445static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd)
446{
447	/* issue cmd to drive */
448	ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD, NULL);
449}
450
451static int icside_dma_test_irq(ide_drive_t *drive)
452{
453	ide_hwif_t *hwif = HWIF(drive);
454	struct icside_state *state = hwif->hwif_data;
455
456	return readb(state->irq_port +
457		     (hwif->channel ?
458			ICS_ARCIN_V6_INTRSTAT_2 :
459			ICS_ARCIN_V6_INTRSTAT_1)) & 1;
460}
461
462static int icside_dma_timeout(ide_drive_t *drive)
463{
464	printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
465
466	if (icside_dma_test_irq(drive))
467		return 0;
468
469	ide_dump_status(drive, "DMA timeout",
470		HWIF(drive)->INB(IDE_STATUS_REG));
471
472	return icside_dma_end(drive);
473}
474
475static int icside_dma_lostirq(ide_drive_t *drive)
476{
477	printk(KERN_ERR "%s: IRQ lost\n", drive->name);
478	return 1;
479}
480
481static void icside_dma_init(ide_hwif_t *hwif)
482{
483	int autodma = 0;
484
485#ifdef CONFIG_IDEDMA_ICS_AUTO
486	autodma = 1;
487#endif
488
489	printk("    %s: SG-DMA", hwif->name);
490
491	hwif->atapi_dma		= 1;
492	hwif->mwdma_mask	= 7; /* MW0..2 */
493	hwif->swdma_mask	= 7; /* SW0..2 */
494
495	hwif->dmatable_cpu	= NULL;
496	hwif->dmatable_dma	= 0;
497	hwif->speedproc		= icside_set_speed;
498	hwif->autodma		= autodma;
499
500	hwif->ide_dma_check	= icside_dma_check;
501	hwif->ide_dma_host_off	= icside_dma_host_off;
502	hwif->ide_dma_off_quietly = icside_dma_off_quietly;
503	hwif->ide_dma_host_on	= icside_dma_host_on;
504	hwif->ide_dma_on	= icside_dma_on;
505	hwif->dma_setup		= icside_dma_setup;
506	hwif->dma_exec_cmd	= icside_dma_exec_cmd;
507	hwif->dma_start		= icside_dma_start;
508	hwif->ide_dma_end	= icside_dma_end;
509	hwif->ide_dma_test_irq	= icside_dma_test_irq;
510	hwif->ide_dma_timeout	= icside_dma_timeout;
511	hwif->ide_dma_lostirq	= icside_dma_lostirq;
512
513	hwif->drives[0].autodma = hwif->autodma;
514	hwif->drives[1].autodma = hwif->autodma;
515
516	printk(" capable%s\n", hwif->autodma ? ", auto-enable" : "");
517}
518#else
519#define icside_dma_init(hwif)	(0)
520#endif
521
522static ide_hwif_t *icside_find_hwif(unsigned long dataport)
523{
524	ide_hwif_t *hwif;
525	int index;
526
527	for (index = 0; index < MAX_HWIFS; ++index) {
528		hwif = &ide_hwifs[index];
529		if (hwif->io_ports[IDE_DATA_OFFSET] == dataport)
530			goto found;
531	}
532
533	for (index = 0; index < MAX_HWIFS; ++index) {
534		hwif = &ide_hwifs[index];
535		if (!hwif->io_ports[IDE_DATA_OFFSET])
536			goto found;
537	}
538
539	hwif = NULL;
540found:
541	return hwif;
542}
543
544static ide_hwif_t *
545icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *ec)
546{
547	unsigned long port = (unsigned long)base + info->dataoffset;
548	ide_hwif_t *hwif;
549
550	hwif = icside_find_hwif(port);
551	if (hwif) {
552		int i;
553
554		memset(&hwif->hw, 0, sizeof(hw_regs_t));
555
556		/*
557		 * Ensure we're using MMIO
558		 */
559		default_hwif_mmiops(hwif);
560		hwif->mmio = 2;
561
562		for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
563			hwif->hw.io_ports[i] = port;
564			hwif->io_ports[i] = port;
565			port += 1 << info->stepping;
566		}
567		hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)base + info->ctrloffset;
568		hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)base + info->ctrloffset;
569		hwif->hw.irq  = ec->irq;
570		hwif->irq     = ec->irq;
571		hwif->noprobe = 0;
572		hwif->chipset = ide_acorn;
573		hwif->gendev.parent = &ec->dev;
574	}
575
576	return hwif;
577}
578
579static int __init
580icside_register_v5(struct icside_state *state, struct expansion_card *ec)
581{
582	ide_hwif_t *hwif;
583	void __iomem *base;
584
585	base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
586		       ecard_resource_len(ec, ECARD_RES_MEMC));
587	if (!base)
588		return -ENOMEM;
589
590	state->irq_port = base;
591
592	ec->irqaddr  = base + ICS_ARCIN_V5_INTRSTAT;
593	ec->irqmask  = 1;
594	ec->irq_data = state;
595	ec->ops      = &icside_ops_arcin_v5;
596
597	/*
598	 * Be on the safe side - disable interrupts
599	 */
600	icside_irqdisable_arcin_v5(ec, 0);
601
602	hwif = icside_setup(base, &icside_cardinfo_v5, ec);
603	if (!hwif) {
604		iounmap(base);
605		return -ENODEV;
606	}
607
608	state->hwif[0] = hwif;
609
610	probe_hwif_init(hwif);
611	create_proc_ide_interfaces();
612
613	return 0;
614}
615
616static int __init
617icside_register_v6(struct icside_state *state, struct expansion_card *ec)
618{
619	ide_hwif_t *hwif, *mate;
620	void __iomem *ioc_base, *easi_base;
621	unsigned int sel = 0;
622	int ret;
623
624	ioc_base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST),
625			   ecard_resource_len(ec, ECARD_RES_IOCFAST));
626	if (!ioc_base) {
627		ret = -ENOMEM;
628		goto out;
629	}
630
631	easi_base = ioc_base;
632
633	if (ecard_resource_flags(ec, ECARD_RES_EASI)) {
634		easi_base = ioremap(ecard_resource_start(ec, ECARD_RES_EASI),
635				    ecard_resource_len(ec, ECARD_RES_EASI));
636		if (!easi_base) {
637			ret = -ENOMEM;
638			goto unmap_slot;
639		}
640
641		/*
642		 * Enable access to the EASI region.
643		 */
644		sel = 1 << 5;
645	}
646
647	writeb(sel, ioc_base);
648
649	ec->irq_data      = state;
650	ec->ops           = &icside_ops_arcin_v6;
651
652	state->irq_port   = easi_base;
653	state->ioc_base   = ioc_base;
654
655	/*
656	 * Be on the safe side - disable interrupts
657	 */
658	icside_irqdisable_arcin_v6(ec, 0);
659
660	/*
661	 * Find and register the interfaces.
662	 */
663	hwif = icside_setup(easi_base, &icside_cardinfo_v6_1, ec);
664	mate = icside_setup(easi_base, &icside_cardinfo_v6_2, ec);
665
666	if (!hwif || !mate) {
667		ret = -ENODEV;
668		goto unmap_port;
669	}
670
671	state->hwif[0]    = hwif;
672	state->hwif[1]    = mate;
673
674	hwif->maskproc    = icside_maskproc;
675	hwif->channel     = 0;
676	hwif->hwif_data   = state;
677	hwif->mate        = mate;
678	hwif->serialized  = 1;
679	hwif->config_data = (unsigned long)ioc_base;
680	hwif->select_data = sel;
681	hwif->hw.dma      = ec->dma;
682
683	mate->maskproc    = icside_maskproc;
684	mate->channel     = 1;
685	mate->hwif_data   = state;
686	mate->mate        = hwif;
687	mate->serialized  = 1;
688	mate->config_data = (unsigned long)ioc_base;
689	mate->select_data = sel | 1;
690	mate->hw.dma      = ec->dma;
691
692	if (ec->dma != NO_DMA && !request_dma(ec->dma, hwif->name)) {
693		icside_dma_init(hwif);
694		icside_dma_init(mate);
695	}
696
697	probe_hwif_init(hwif);
698	probe_hwif_init(mate);
699	create_proc_ide_interfaces();
700
701	return 0;
702
703 unmap_port:
704	if (easi_base != ioc_base)
705		iounmap(easi_base);
706 unmap_slot:
707	iounmap(ioc_base);
708 out:
709	return ret;
710}
711
712static int __devinit
713icside_probe(struct expansion_card *ec, const struct ecard_id *id)
714{
715	struct icside_state *state;
716	void __iomem *idmem;
717	int ret;
718
719	ret = ecard_request_resources(ec);
720	if (ret)
721		goto out;
722
723	state = kmalloc(sizeof(struct icside_state), GFP_KERNEL);
724	if (!state) {
725		ret = -ENOMEM;
726		goto release;
727	}
728
729	memset(state, 0, sizeof(state));
730	state->type	= ICS_TYPE_NOTYPE;
731	state->dev	= &ec->dev;
732
733	idmem = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST),
734			ecard_resource_len(ec, ECARD_RES_IOCFAST));
735	if (idmem) {
736		unsigned int type;
737
738		type = readb(idmem + ICS_IDENT_OFFSET) & 1;
739		type |= (readb(idmem + ICS_IDENT_OFFSET + 4) & 1) << 1;
740		type |= (readb(idmem + ICS_IDENT_OFFSET + 8) & 1) << 2;
741		type |= (readb(idmem + ICS_IDENT_OFFSET + 12) & 1) << 3;
742		iounmap(idmem);
743
744		state->type = type;
745	}
746
747	switch (state->type) {
748	case ICS_TYPE_A3IN:
749		dev_warn(&ec->dev, "A3IN unsupported\n");
750		ret = -ENODEV;
751		break;
752
753	case ICS_TYPE_A3USER:
754		dev_warn(&ec->dev, "A3USER unsupported\n");
755		ret = -ENODEV;
756		break;
757
758	case ICS_TYPE_V5:
759		ret = icside_register_v5(state, ec);
760		break;
761
762	case ICS_TYPE_V6:
763		ret = icside_register_v6(state, ec);
764		break;
765
766	default:
767		dev_warn(&ec->dev, "unknown interface type\n");
768		ret = -ENODEV;
769		break;
770	}
771
772	if (ret == 0) {
773		ecard_set_drvdata(ec, state);
774		goto out;
775	}
776
777	kfree(state);
778 release:
779	ecard_release_resources(ec);
780 out:
781	return ret;
782}
783
784static void __devexit icside_remove(struct expansion_card *ec)
785{
786	struct icside_state *state = ecard_get_drvdata(ec);
787
788	switch (state->type) {
789	case ICS_TYPE_V5:
790		/* FIXME: tell IDE to stop using the interface */
791
792		/* Disable interrupts */
793		icside_irqdisable_arcin_v5(ec, 0);
794		break;
795
796	case ICS_TYPE_V6:
797		/* FIXME: tell IDE to stop using the interface */
798		if (ec->dma != NO_DMA)
799			free_dma(ec->dma);
800
801		/* Disable interrupts */
802		icside_irqdisable_arcin_v6(ec, 0);
803
804		/* Reset the ROM pointer/EASI selection */
805		writeb(0, state->ioc_base);
806		break;
807	}
808
809	ecard_set_drvdata(ec, NULL);
810	ec->ops = NULL;
811	ec->irq_data = NULL;
812
813	if (state->ioc_base)
814		iounmap(state->ioc_base);
815	if (state->ioc_base != state->irq_port)
816		iounmap(state->irq_port);
817
818	kfree(state);
819	ecard_release_resources(ec);
820}
821
822static void icside_shutdown(struct expansion_card *ec)
823{
824	struct icside_state *state = ecard_get_drvdata(ec);
825	unsigned long flags;
826
827	/*
828	 * Disable interrupts from this card.  We need to do
829	 * this before disabling EASI since we may be accessing
830	 * this register via that region.
831	 */
832	local_irq_save(flags);
833	ec->ops->irqdisable(ec, 0);
834	local_irq_restore(flags);
835
836	/*
837	 * Reset the ROM pointer so that we can read the ROM
838	 * after a soft reboot.  This also disables access to
839	 * the IDE taskfile via the EASI region.
840	 */
841	if (state->ioc_base)
842		writeb(0, state->ioc_base);
843}
844
845static const struct ecard_id icside_ids[] = {
846	{ MANU_ICS,  PROD_ICS_IDE  },
847	{ MANU_ICS2, PROD_ICS2_IDE },
848	{ 0xffff, 0xffff }
849};
850
851static struct ecard_driver icside_driver = {
852	.probe		= icside_probe,
853	.remove		= __devexit_p(icside_remove),
854	.shutdown	= icside_shutdown,
855	.id_table	= icside_ids,
856	.drv = {
857		.name	= "icside",
858	},
859};
860
861static int __init icside_init(void)
862{
863	return ecard_register_driver(&icside_driver);
864}
865
866MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
867MODULE_LICENSE("GPL");
868MODULE_DESCRIPTION("ICS IDE driver");
869
870module_init(icside_init);