Blame view

drivers/ide/buddha.c 5.57 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
58f189fcc   Bartlomiej Zolnierkiewicz   ide: delete filen...
2
   *  Amiga Buddha, Catweasel and X-Surf IDE Driver
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
   *
   *	Copyright (C) 1997, 2001 by Geert Uytterhoeven and others
   *
   *  This driver was written based on the specifications in README.buddha and
   *  the X-Surf info from Inside_XSurf.txt available at
   *  http://www.jschoenfeld.com
   *
   *  This file is subject to the terms and conditions of the GNU General Public
   *  License.  See the file COPYING in the main directory of this archive for
   *  more details.
   *
   *  TODO:
   *    - test it :-)
   *    - tune the timings using the speed-register
   */
  
  #include <linux/types.h>
  #include <linux/mm.h>
  #include <linux/interrupt.h>
  #include <linux/blkdev.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
25
  #include <linux/zorro.h>
  #include <linux/ide.h>
  #include <linux/init.h>
bff7832dd   Paul Gortmaker   ide/ata: Add modu...
26
  #include <linux/module.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
30
31
32
33
34
35
36
37
38
  
  #include <asm/amigahw.h>
  #include <asm/amigaints.h>
  
  
      /*
       *  The Buddha has 2 IDE interfaces, the Catweasel has 3, X-Surf has 2
       */
  
  #define BUDDHA_NUM_HWIFS	2
  #define CATWEASEL_NUM_HWIFS	3
  #define XSURF_NUM_HWIFS         2
c97c6aca7   Bartlomiej Zolnierkiewicz   ide: pass hw_regs...
39
  #define MAX_NUM_HWIFS		3
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
      /*
       *  Bases of the IDE interfaces (relative to the board address)
       */
  
  #define BUDDHA_BASE1	0x800
  #define BUDDHA_BASE2	0xa00
  #define BUDDHA_BASE3	0xc00
  
  #define XSURF_BASE1     0xb000 /* 2.5" Interface */
  #define XSURF_BASE2     0xd000 /* 3.5" Interface */
  
  static u_int buddha_bases[CATWEASEL_NUM_HWIFS] __initdata = {
      BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3
  };
  
  static u_int xsurf_bases[XSURF_NUM_HWIFS] __initdata = {
       XSURF_BASE1, XSURF_BASE2
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
59
60
      /*
       *  Offsets from one of the above bases
       */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  #define BUDDHA_CONTROL	0x11a
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
  
      /*
       *  Other registers
       */
  
  #define BUDDHA_IRQ1	0xf00		/* MSB = 1, Harddisk is source of */
  #define BUDDHA_IRQ2	0xf40		/* interrupt */
  #define BUDDHA_IRQ3	0xf80
  
  #define XSURF_IRQ1      0x7e
  #define XSURF_IRQ2      0x7e
  
  static int buddha_irqports[CATWEASEL_NUM_HWIFS] __initdata = {
      BUDDHA_IRQ1, BUDDHA_IRQ2, BUDDHA_IRQ3
  };
  
  static int xsurf_irqports[XSURF_NUM_HWIFS] __initdata = {
      XSURF_IRQ1, XSURF_IRQ2
  };
  
  #define BUDDHA_IRQ_MR	0xfc0		/* master interrupt enable */
  
  
      /*
       *  Board information
       */
  
  typedef enum BuddhaType_Enum {
      BOARD_BUDDHA, BOARD_CATWEASEL, BOARD_XSURF
  } BuddhaType;
c99c92c58   Bartlomiej Zolnierkiewicz   ide: print banner...
92
  static const char *buddha_board_name[] = { "Buddha", "Catweasel", "X-Surf" };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
94
95
96
  
      /*
       *  Check and acknowledge the interrupt status
       */
f4d3ffa52   Sergei Shtylyov   ide: move ack_int...
97
  static int buddha_test_irq(ide_hwif_t *hwif)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
98
99
  {
      unsigned char ch;
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
100
      ch = z_readb(hwif->io_ports.irq_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
103
104
      if (!(ch & 0x80))
  	    return 0;
      return 1;
  }
eba8999ce   Sergei Shtylyov   ide: move IRQ cle...
105
  static void xsurf_clear_irq(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106
  {
eba8999ce   Sergei Shtylyov   ide: move IRQ cle...
107
108
109
110
      /*
       * X-Surf needs 0 written to IRQ register to ensure ISA bit A11 stays at 0
       */
      z_writeb(0, drive->hwif->io_ports.irq_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
  }
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
112
  static void __init buddha_setup_ports(struct ide_hw *hw, unsigned long base,
f4d3ffa52   Sergei Shtylyov   ide: move ack_int...
113
  				      unsigned long ctl, unsigned long irq_port)
29dd59755   Bartlomiej Zolnierkiewicz   ide: remove ide_s...
114
115
116
117
  {
  	int i;
  
  	memset(hw, 0, sizeof(*hw));
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
118
  	hw->io_ports.data_addr = base;
29dd59755   Bartlomiej Zolnierkiewicz   ide: remove ide_s...
119
120
  
  	for (i = 1; i < 8; i++)
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
121
  		hw->io_ports_array[i] = base + 2 + i * 4;
29dd59755   Bartlomiej Zolnierkiewicz   ide: remove ide_s...
122

4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
123
124
  	hw->io_ports.ctl_addr = ctl;
  	hw->io_ports.irq_addr = irq_port;
29dd59755   Bartlomiej Zolnierkiewicz   ide: remove ide_s...
125
126
  
  	hw->irq = IRQ_AMIGA_PORTS;
29dd59755   Bartlomiej Zolnierkiewicz   ide: remove ide_s...
127
  }
f4d3ffa52   Sergei Shtylyov   ide: move ack_int...
128
129
130
  static const struct ide_port_ops buddha_port_ops = {
  	.test_irq		= buddha_test_irq,
  };
eba8999ce   Sergei Shtylyov   ide: move IRQ cle...
131
132
  static const struct ide_port_ops xsurf_port_ops = {
  	.clear_irq		= xsurf_clear_irq,
f4d3ffa52   Sergei Shtylyov   ide: move ack_int...
133
  	.test_irq		= buddha_test_irq,
eba8999ce   Sergei Shtylyov   ide: move IRQ cle...
134
  };
0e78a54fb   Bartlomiej Zolnierkiewicz   buddha: use struc...
135
  static const struct ide_port_info buddha_port_info = {
f4d3ffa52   Sergei Shtylyov   ide: move ack_int...
136
  	.port_ops		= &buddha_port_ops,
09a3e7918   Bartlomiej Zolnierkiewicz   ide: make m68k ho...
137
  	.host_flags		= IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
255115fb3   Bartlomiej Zolnierkiewicz   ide: allow host d...
138
  	.irq_flags		= IRQF_SHARED,
29e52cf79   Bartlomiej Zolnierkiewicz   ide: remove chips...
139
  	.chipset		= ide_generic,
0e78a54fb   Bartlomiej Zolnierkiewicz   buddha: use struc...
140
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
142
143
      /*
       *  Probe for a Buddha or Catweasel IDE interface
       */
ade2daf9c   Bartlomiej Zolnierkiewicz   ide: make remaini...
144
  static int __init buddha_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
147
148
  	struct zorro_dev *z = NULL;
  	u_long buddha_board = 0;
  	BuddhaType type;
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
149
  	int buddha_num_hwifs, i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
150
151
152
  
  	while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
  		unsigned long board;
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
153
  		struct ide_hw hw[MAX_NUM_HWIFS], *hws[MAX_NUM_HWIFS];
eba8999ce   Sergei Shtylyov   ide: move IRQ cle...
154
  		struct ide_port_info d = buddha_port_info;
8ac4ce742   Bartlomiej Zolnierkiewicz   ide: fix host dri...
155

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
157
158
159
160
161
162
163
164
  		if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) {
  			buddha_num_hwifs = BUDDHA_NUM_HWIFS;
  			type=BOARD_BUDDHA;
  		} else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL) {
  			buddha_num_hwifs = CATWEASEL_NUM_HWIFS;
  			type=BOARD_CATWEASEL;
  		} else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF) {
  			buddha_num_hwifs = XSURF_NUM_HWIFS;
  			type=BOARD_XSURF;
eba8999ce   Sergei Shtylyov   ide: move IRQ cle...
165
  			d.port_ops = &xsurf_port_ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166
167
168
169
  		} else 
  			continue;
  		
  		board = z->resource.start;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
  		if(type != BOARD_XSURF) {
  			if (!request_mem_region(board+BUDDHA_BASE1, 0x800, "IDE"))
  				continue;
  		} else {
  			if (!request_mem_region(board+XSURF_BASE1, 0x1000, "IDE"))
  				continue;
  			if (!request_mem_region(board+XSURF_BASE2, 0x1000, "IDE"))
  				goto fail_base2;
  			if (!request_mem_region(board+XSURF_IRQ1, 0x8, "IDE")) {
  				release_mem_region(board+XSURF_BASE2, 0x1000);
  fail_base2:
  				release_mem_region(board+XSURF_BASE1, 0x1000);
  				continue;
  			}
  		}	  
  		buddha_board = ZTWO_VADDR(board);
  		
  		/* write to BUDDHA_IRQ_MR to enable the board IRQ */
  		/* X-Surf doesn't have this.  IRQs are always on */
  		if (type != BOARD_XSURF)
  			z_writeb(0, buddha_board+BUDDHA_IRQ_MR);
c99c92c58   Bartlomiej Zolnierkiewicz   ide: print banner...
191
192
193
194
  
  		printk(KERN_INFO "ide: %s IDE controller
  ",
  				 buddha_board_name[type]);
29dd59755   Bartlomiej Zolnierkiewicz   ide: remove ide_s...
195
196
  		for (i = 0; i < buddha_num_hwifs; i++) {
  			unsigned long base, ctl, irq_port;
29dd59755   Bartlomiej Zolnierkiewicz   ide: remove ide_s...
197
198
199
200
201
  
  			if (type != BOARD_XSURF) {
  				base = buddha_board + buddha_bases[i];
  				ctl = base + BUDDHA_CONTROL;
  				irq_port = buddha_board + buddha_irqports[i];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202
  			} else {
29dd59755   Bartlomiej Zolnierkiewicz   ide: remove ide_s...
203
204
205
206
  				base = buddha_board + xsurf_bases[i];
  				/* X-Surf has no CS1* (Control/AltStat) */
  				ctl = 0;
  				irq_port = buddha_board + xsurf_irqports[i];
29dd59755   Bartlomiej Zolnierkiewicz   ide: remove ide_s...
207
  			}
f4d3ffa52   Sergei Shtylyov   ide: move ack_int...
208
  			buddha_setup_ports(&hw[i], base, ctl, irq_port);
fd9bb5394   Bartlomiej Zolnierkiewicz   ide: add ->fixup ...
209

48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
210
  			hws[i] = &hw[i];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
  		}
8ac4ce742   Bartlomiej Zolnierkiewicz   ide: fix host dri...
212

eba8999ce   Sergei Shtylyov   ide: move IRQ cle...
213
  		ide_host_add(&d, hws, i, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
  	}
ade2daf9c   Bartlomiej Zolnierkiewicz   ide: make remaini...
215
216
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217
  }
ade2daf9c   Bartlomiej Zolnierkiewicz   ide: make remaini...
218
219
  
  module_init(buddha_init);
c5daf1aa2   Adrian Bunk   ide/legacy/buddha...
220
221
  
  MODULE_LICENSE("GPL");