aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/sh/maple/maple.c978
-rw-r--r--include/linux/maple.h101
2 files changed, 543 insertions, 536 deletions
diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c
index e52a6296ca46..9c48ccc44c29 100644
--- a/drivers/sh/maple/maple.c
+++ b/drivers/sh/maple/maple.c
@@ -57,8 +57,8 @@ static int started, scanning, liststatus;
57static struct kmem_cache *maple_queue_cache; 57static struct kmem_cache *maple_queue_cache;
58 58
59struct maple_device_specify { 59struct maple_device_specify {
60 int port; 60 int port;
61 int unit; 61 int unit;
62}; 62};
63 63
64/** 64/**
@@ -68,22 +68,23 @@ struct maple_device_specify {
68 */ 68 */
69int maple_driver_register(struct device_driver *drv) 69int maple_driver_register(struct device_driver *drv)
70{ 70{
71 if (!drv) 71 if (!drv)
72 return -EINVAL; 72 return -EINVAL;
73 drv->bus = &maple_bus_type; 73 drv->bus = &maple_bus_type;
74 return driver_register(drv); 74 return driver_register(drv);
75} 75}
76
76EXPORT_SYMBOL_GPL(maple_driver_register); 77EXPORT_SYMBOL_GPL(maple_driver_register);
77 78
78/* set hardware registers to enable next round of dma */ 79/* set hardware registers to enable next round of dma */
79static void maplebus_dma_reset(void) 80static void maplebus_dma_reset(void)
80{ 81{
81 ctrl_outl(MAPLE_MAGIC, MAPLE_RESET); 82 ctrl_outl(MAPLE_MAGIC, MAPLE_RESET);
82 /* set trig type to 0 for software trigger, 1 for hardware (VBLANK) */ 83 /* set trig type to 0 for software trigger, 1 for hardware (VBLANK) */
83 ctrl_outl(1, MAPLE_TRIGTYPE); 84 ctrl_outl(1, MAPLE_TRIGTYPE);
84 ctrl_outl(MAPLE_2MBPS | MAPLE_TIMEOUT(50000), MAPLE_SPEED); 85 ctrl_outl(MAPLE_2MBPS | MAPLE_TIMEOUT(50000), MAPLE_SPEED);
85 ctrl_outl(PHYSADDR(maple_sendbuf), MAPLE_DMAADDR); 86 ctrl_outl(PHYSADDR(maple_sendbuf), MAPLE_DMAADDR);
86 ctrl_outl(1, MAPLE_ENABLE); 87 ctrl_outl(1, MAPLE_ENABLE);
87} 88}
88 89
89/** 90/**
@@ -94,27 +95,28 @@ static void maplebus_dma_reset(void)
94 * @function: the function code for the device 95 * @function: the function code for the device
95 */ 96 */
96void maple_getcond_callback(struct maple_device *dev, 97void maple_getcond_callback(struct maple_device *dev,
97 void (*callback) (struct mapleq * mq), 98 void (*callback) (struct mapleq * mq),
98 unsigned long interval, unsigned long function) 99 unsigned long interval, unsigned long function)
99{ 100{
100 dev->callback = callback; 101 dev->callback = callback;
101 dev->interval = interval; 102 dev->interval = interval;
102 dev->function = cpu_to_be32(function); 103 dev->function = cpu_to_be32(function);
103 dev->when = jiffies; 104 dev->when = jiffies;
104} 105}
106
105EXPORT_SYMBOL_GPL(maple_getcond_callback); 107EXPORT_SYMBOL_GPL(maple_getcond_callback);
106 108
107static int maple_dma_done(void) 109static int maple_dma_done(void)
108{ 110{
109 return (ctrl_inl(MAPLE_STATE) & 1) == 0; 111 return (ctrl_inl(MAPLE_STATE) & 1) == 0;
110} 112}
111 113
112static void maple_release_device(struct device *dev) 114static void maple_release_device(struct device *dev)
113{ 115{
114 if (dev->type) { 116 if (dev->type) {
115 kfree(dev->type->name); 117 kfree(dev->type->name);
116 kfree(dev->type); 118 kfree(dev->type);
117 } 119 }
118} 120}
119 121
120/** 122/**
@@ -123,60 +125,61 @@ static void maple_release_device(struct device *dev)
123 */ 125 */
124void maple_add_packet(struct mapleq *mq) 126void maple_add_packet(struct mapleq *mq)
125{ 127{
126 mutex_lock(&maple_list_lock); 128 mutex_lock(&maple_list_lock);
127 list_add(&mq->list, &maple_waitq); 129 list_add(&mq->list, &maple_waitq);
128 mutex_unlock(&maple_list_lock); 130 mutex_unlock(&maple_list_lock);
129} 131}
132
130EXPORT_SYMBOL_GPL(maple_add_packet); 133EXPORT_SYMBOL_GPL(maple_add_packet);
131 134
132static struct mapleq *maple_allocq(struct maple_device *dev) 135static struct mapleq *maple_allocq(struct maple_device *dev)
133{ 136{
134 struct mapleq *mq; 137 struct mapleq *mq;
135 138
136 mq = kmalloc(sizeof(*mq), GFP_KERNEL); 139 mq = kmalloc(sizeof(*mq), GFP_KERNEL);
137 if (!mq) 140 if (!mq)
138 return NULL; 141 return NULL;
139 142
140 mq->dev = dev; 143 mq->dev = dev;
141 mq->recvbufdcsp = kmem_cache_zalloc(maple_queue_cache, GFP_KERNEL); 144 mq->recvbufdcsp = kmem_cache_zalloc(maple_queue_cache, GFP_KERNEL);
142 mq->recvbuf = (void *) P2SEGADDR(mq->recvbufdcsp); 145 mq->recvbuf = (void *) P2SEGADDR(mq->recvbufdcsp);
143 if (!mq->recvbuf) { 146 if (!mq->recvbuf) {
144 kfree(mq); 147 kfree(mq);
145 return NULL; 148 return NULL;
146 } 149 }
147 150
148 return mq; 151 return mq;
149} 152}
150 153
151static struct maple_device *maple_alloc_dev(int port, int unit) 154static struct maple_device *maple_alloc_dev(int port, int unit)
152{ 155{
153 struct maple_device *dev; 156 struct maple_device *dev;
154 157
155 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 158 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
156 if (!dev) 159 if (!dev)
157 return NULL; 160 return NULL;
158 161
159 dev->port = port; 162 dev->port = port;
160 dev->unit = unit; 163 dev->unit = unit;
161 dev->mq = maple_allocq(dev); 164 dev->mq = maple_allocq(dev);
162 165
163 if (!dev->mq) { 166 if (!dev->mq) {
164 kfree(dev); 167 kfree(dev);
165 return NULL; 168 return NULL;
166 } 169 }
167 170
168 return dev; 171 return dev;
169} 172}
170 173
171static void maple_free_dev(struct maple_device *mdev) 174static void maple_free_dev(struct maple_device *mdev)
172{ 175{
173 if (!mdev) 176 if (!mdev)
174 return; 177 return;
175 if (mdev->mq) { 178 if (mdev->mq) {
176 kmem_cache_free(maple_queue_cache, mdev->mq->recvbufdcsp); 179 kmem_cache_free(maple_queue_cache, mdev->mq->recvbufdcsp);
177 kfree(mdev->mq); 180 kfree(mdev->mq);
178 } 181 }
179 kfree(mdev); 182 kfree(mdev);
180} 183}
181 184
182/* process the command queue into a maple command block 185/* process the command queue into a maple command block
@@ -184,153 +187,153 @@ static void maple_free_dev(struct maple_device *mdev)
184 */ 187 */
185static void maple_build_block(struct mapleq *mq) 188static void maple_build_block(struct mapleq *mq)
186{ 189{
187 int port, unit, from, to, len; 190 int port, unit, from, to, len;
188 unsigned long *lsendbuf = mq->sendbuf; 191 unsigned long *lsendbuf = mq->sendbuf;
189 192
190 port = mq->dev->port & 3; 193 port = mq->dev->port & 3;
191 unit = mq->dev->unit; 194 unit = mq->dev->unit;
192 len = mq->length; 195 len = mq->length;
193 from = port << 6; 196 from = port << 6;
194 to = (port << 6) | (unit > 0 ? (1 << (unit - 1)) & 0x1f : 0x20); 197 to = (port << 6) | (unit > 0 ? (1 << (unit - 1)) & 0x1f : 0x20);
195 198
196 *maple_lastptr &= 0x7fffffff; 199 *maple_lastptr &= 0x7fffffff;
197 maple_lastptr = maple_sendptr; 200 maple_lastptr = maple_sendptr;
198 201
199 *maple_sendptr++ = (port << 16) | len | 0x80000000; 202 *maple_sendptr++ = (port << 16) | len | 0x80000000;
200 *maple_sendptr++ = PHYSADDR(mq->recvbuf); 203 *maple_sendptr++ = PHYSADDR(mq->recvbuf);
201 *maple_sendptr++ = 204 *maple_sendptr++ =
202 mq->command | (to << 8) | (from << 16) | (len << 24); 205 mq->command | (to << 8) | (from << 16) | (len << 24);
203 206
204 while (len-- > 0) 207 while (len-- > 0)
205 *maple_sendptr++ = *lsendbuf++; 208 *maple_sendptr++ = *lsendbuf++;
206} 209}
207 210
208/* build up command queue */ 211/* build up command queue */
209static void maple_send(void) 212static void maple_send(void)
210{ 213{
211 int i; 214 int i;
212 int maple_packets; 215 int maple_packets;
213 struct mapleq *mq, *nmq; 216 struct mapleq *mq, *nmq;
214 217
215 if (!list_empty(&maple_sentq)) 218 if (!list_empty(&maple_sentq))
216 return; 219 return;
217 if (list_empty(&maple_waitq) || !maple_dma_done()) 220 if (list_empty(&maple_waitq) || !maple_dma_done())
218 return; 221 return;
219 maple_packets = 0; 222 maple_packets = 0;
220 maple_sendptr = maple_lastptr = maple_sendbuf; 223 maple_sendptr = maple_lastptr = maple_sendbuf;
221 list_for_each_entry_safe(mq, nmq, &maple_waitq, list) { 224 list_for_each_entry_safe(mq, nmq, &maple_waitq, list) {
222 maple_build_block(mq); 225 maple_build_block(mq);
223 list_move(&mq->list, &maple_sentq); 226 list_move(&mq->list, &maple_sentq);
224 if (maple_packets++ > MAPLE_MAXPACKETS) 227 if (maple_packets++ > MAPLE_MAXPACKETS)
225 break; 228 break;
226 } 229 }
227 if (maple_packets > 0) { 230 if (maple_packets > 0) {
228 for (i = 0; i < (1 << MAPLE_DMA_PAGES); i++) 231 for (i = 0; i < (1 << MAPLE_DMA_PAGES); i++)
229 dma_cache_sync(0, maple_sendbuf + i * PAGE_SIZE, 232 dma_cache_sync(0, maple_sendbuf + i * PAGE_SIZE,
230 PAGE_SIZE, DMA_BIDIRECTIONAL); 233 PAGE_SIZE, DMA_BIDIRECTIONAL);
231 } 234 }
232} 235}
233 236
234static int attach_matching_maple_driver(struct device_driver *driver, 237static int attach_matching_maple_driver(struct device_driver *driver,
235 void *devptr) 238 void *devptr)
236{ 239{
237 struct maple_driver *maple_drv; 240 struct maple_driver *maple_drv;
238 struct maple_device *mdev; 241 struct maple_device *mdev;
239 242
240 mdev = devptr; 243 mdev = devptr;
241 maple_drv = to_maple_driver(driver); 244 maple_drv = to_maple_driver(driver);
242 if (mdev->devinfo.function & be32_to_cpu(maple_drv->function)) { 245 if (mdev->devinfo.function & be32_to_cpu(maple_drv->function)) {
243 if (maple_drv->connect(mdev) == 0) { 246 if (maple_drv->connect(mdev) == 0) {
244 mdev->driver = maple_drv; 247 mdev->driver = maple_drv;
245 return 1; 248 return 1;
246 } 249 }
247 } 250 }
248 return 0; 251 return 0;
249} 252}
250 253
251static void maple_detach_driver(struct maple_device *mdev) 254static void maple_detach_driver(struct maple_device *mdev)
252{ 255{
253 if (!mdev) 256 if (!mdev)
254 return; 257 return;
255 if (mdev->driver) { 258 if (mdev->driver) {
256 if (mdev->driver->disconnect) 259 if (mdev->driver->disconnect)
257 mdev->driver->disconnect(mdev); 260 mdev->driver->disconnect(mdev);
258 } 261 }
259 mdev->driver = NULL; 262 mdev->driver = NULL;
260 if (mdev->registered) { 263 if (mdev->registered) {
261 maple_release_device(&mdev->dev); 264 maple_release_device(&mdev->dev);
262 device_unregister(&mdev->dev); 265 device_unregister(&mdev->dev);
263 } 266 }
264 mdev->registered = 0; 267 mdev->registered = 0;
265 maple_free_dev(mdev); 268 maple_free_dev(mdev);
266} 269}
267 270
268/* process initial MAPLE_COMMAND_DEVINFO for each device or port */ 271/* process initial MAPLE_COMMAND_DEVINFO for each device or port */
269static void maple_attach_driver(struct maple_device *dev) 272static void maple_attach_driver(struct maple_device *dev)
270{ 273{
271 char *p; 274 char *p;
272 275
273 char *recvbuf; 276 char *recvbuf;
274 unsigned long function; 277 unsigned long function;
275 int matched, retval; 278 int matched, retval;
276 279
277 recvbuf = dev->mq->recvbuf; 280 recvbuf = dev->mq->recvbuf;
278 memcpy(&dev->devinfo, recvbuf + 4, sizeof(dev->devinfo)); 281 memcpy(&dev->devinfo, recvbuf + 4, sizeof(dev->devinfo));
279 memcpy(dev->product_name, dev->devinfo.product_name, 30); 282 memcpy(dev->product_name, dev->devinfo.product_name, 30);
280 memcpy(dev->product_licence, dev->devinfo.product_licence, 60); 283 memcpy(dev->product_licence, dev->devinfo.product_licence, 60);
281 dev->product_name[30] = '\0'; 284 dev->product_name[30] = '\0';
282 dev->product_licence[60] = '\0'; 285 dev->product_licence[60] = '\0';
283 286
284 for (p = dev->product_name + 29; dev->product_name <= p; p--) 287 for (p = dev->product_name + 29; dev->product_name <= p; p--)
285 if (*p == ' ') 288 if (*p == ' ')
286 *p = '\0'; 289 *p = '\0';
287 else 290 else
288 break; 291 break;
289 292
290 for (p = dev->product_licence + 59; dev->product_licence <= p; p--) 293 for (p = dev->product_licence + 59; dev->product_licence <= p; p--)
291 if (*p == ' ') 294 if (*p == ' ')
292 *p = '\0'; 295 *p = '\0';
293 else 296 else
294 break; 297 break;
295 298
296 function = be32_to_cpu(dev->devinfo.function); 299 function = be32_to_cpu(dev->devinfo.function);
297 300
298 if (function > 0x200) { 301 if (function > 0x200) {
299 /* Do this silently - as not a real device */ 302 /* Do this silently - as not a real device */
300 function = 0; 303 function = 0;
301 dev->driver = &maple_dummy_driver; 304 dev->driver = &maple_dummy_driver;
302 sprintf(dev->dev.bus_id, "%d:0.port", dev->port); 305 sprintf(dev->dev.bus_id, "%d:0.port", dev->port);
303 } else { 306 } else {
304 printk(KERN_INFO 307 printk(KERN_INFO
305 "Maple bus at (%d, %d): Connected function 0x%lX\n", 308 "Maple bus at (%d, %d): Connected function 0x%lX\n",
306 dev->port, dev->unit, function); 309 dev->port, dev->unit, function);
307 310
308 matched = 311 matched =
309 bus_for_each_drv(&maple_bus_type, NULL, dev, 312 bus_for_each_drv(&maple_bus_type, NULL, dev,
310 attach_matching_maple_driver); 313 attach_matching_maple_driver);
311 314
312 if (matched == 0) { 315 if (matched == 0) {
313 /* Driver does not exist yet */ 316 /* Driver does not exist yet */
314 printk(KERN_INFO 317 printk(KERN_INFO
315 "No maple driver found for this device\n"); 318 "No maple driver found for this device\n");
316 dev->driver = &maple_dummy_driver; 319 dev->driver = &maple_dummy_driver;
317 } 320 }
318 321
319 sprintf(dev->dev.bus_id, "%d:0%d.%lX", dev->port, 322 sprintf(dev->dev.bus_id, "%d:0%d.%lX", dev->port,
320 dev->unit, function); 323 dev->unit, function);
321 } 324 }
322 dev->function = function; 325 dev->function = function;
323 dev->dev.bus = &maple_bus_type; 326 dev->dev.bus = &maple_bus_type;
324 dev->dev.parent = &maple_bus; 327 dev->dev.parent = &maple_bus;
325 dev->dev.release = &maple_release_device; 328 dev->dev.release = &maple_release_device;
326 retval = device_register(&dev->dev); 329 retval = device_register(&dev->dev);
327 if (retval) { 330 if (retval) {
328 printk(KERN_INFO 331 printk(KERN_INFO
329 "Maple bus: Attempt to register device (%x, %x) failed.\n", 332 "Maple bus: Attempt to register device (%x, %x) failed.\n",
330 dev->port, dev->unit); 333 dev->port, dev->unit);
331 maple_free_dev(dev); 334 maple_free_dev(dev);
332 } 335 }
333 dev->registered = 1; 336 dev->registered = 1;
334} 337}
335 338
336/* 339/*
@@ -340,270 +343,271 @@ static void maple_attach_driver(struct maple_device *dev)
340 */ 343 */
341static int detach_maple_device(struct device *device, void *portptr) 344static int detach_maple_device(struct device *device, void *portptr)
342{ 345{
343 struct maple_device_specify *ds; 346 struct maple_device_specify *ds;
344 struct maple_device *mdev; 347 struct maple_device *mdev;
345 348
346 ds = portptr; 349 ds = portptr;
347 mdev = to_maple_dev(device); 350 mdev = to_maple_dev(device);
348 if (mdev->port == ds->port && mdev->unit == ds->unit) 351 if (mdev->port == ds->port && mdev->unit == ds->unit)
349 return 1; 352 return 1;
350 return 0; 353 return 0;
351} 354}
352 355
353static int setup_maple_commands(struct device *device, void *ignored) 356static int setup_maple_commands(struct device *device, void *ignored)
354{ 357{
355 struct maple_device *maple_dev = to_maple_dev(device); 358 struct maple_device *maple_dev = to_maple_dev(device);
356 359
357 if ((maple_dev->interval > 0) 360 if ((maple_dev->interval > 0)
358 && time_after(jiffies, maple_dev->when)) { 361 && time_after(jiffies, maple_dev->when)) {
359 maple_dev->when = jiffies + maple_dev->interval; 362 maple_dev->when = jiffies + maple_dev->interval;
360 maple_dev->mq->command = MAPLE_COMMAND_GETCOND; 363 maple_dev->mq->command = MAPLE_COMMAND_GETCOND;
361 maple_dev->mq->sendbuf = &maple_dev->function; 364 maple_dev->mq->sendbuf = &maple_dev->function;
362 maple_dev->mq->length = 1; 365 maple_dev->mq->length = 1;
363 maple_add_packet(maple_dev->mq); 366 maple_add_packet(maple_dev->mq);
364 liststatus++; 367 liststatus++;
365 } else { 368 } else {
366 if (time_after(jiffies, maple_pnp_time)) { 369 if (time_after(jiffies, maple_pnp_time)) {
367 maple_dev->mq->command = MAPLE_COMMAND_DEVINFO; 370 maple_dev->mq->command = MAPLE_COMMAND_DEVINFO;
368 maple_dev->mq->length = 0; 371 maple_dev->mq->length = 0;
369 maple_add_packet(maple_dev->mq); 372 maple_add_packet(maple_dev->mq);
370 liststatus++; 373 liststatus++;
371 } 374 }
372 } 375 }
373 376
374 return 0; 377 return 0;
375} 378}
376 379
377/* VBLANK bottom half - implemented via workqueue */ 380/* VBLANK bottom half - implemented via workqueue */
378static void maple_vblank_handler(struct work_struct *work) 381static void maple_vblank_handler(struct work_struct *work)
379{ 382{
380 if (!maple_dma_done()) 383 if (!maple_dma_done())
381 return; 384 return;
382 if (!list_empty(&maple_sentq)) 385 if (!list_empty(&maple_sentq))
383 return; 386 return;
384 ctrl_outl(0, MAPLE_ENABLE); 387 ctrl_outl(0, MAPLE_ENABLE);
385 liststatus = 0; 388 liststatus = 0;
386 bus_for_each_dev(&maple_bus_type, NULL, NULL, 389 bus_for_each_dev(&maple_bus_type, NULL, NULL,
387 setup_maple_commands); 390 setup_maple_commands);
388 if (time_after(jiffies, maple_pnp_time)) 391 if (time_after(jiffies, maple_pnp_time))
389 maple_pnp_time = jiffies + MAPLE_PNP_INTERVAL; 392 maple_pnp_time = jiffies + MAPLE_PNP_INTERVAL;
390 if (liststatus && list_empty(&maple_sentq)) { 393 if (liststatus && list_empty(&maple_sentq)) {
391 INIT_LIST_HEAD(&maple_sentq); 394 INIT_LIST_HEAD(&maple_sentq);
392 maple_send(); 395 maple_send();
393 } 396 }
394 maplebus_dma_reset(); 397 maplebus_dma_reset();
395} 398}
396 399
397/* handle devices added via hotplugs - placing them on queue for DEVINFO*/ 400/* handle devices added via hotplugs - placing them on queue for DEVINFO*/
398static void maple_map_subunits(struct maple_device *mdev, int submask) 401static void maple_map_subunits(struct maple_device *mdev, int submask)
399{ 402{
400 int retval, k, devcheck; 403 int retval, k, devcheck;
401 struct maple_device *mdev_add; 404 struct maple_device *mdev_add;
402 struct maple_device_specify ds; 405 struct maple_device_specify ds;
403 406
404 for (k = 0; k < 5; k++) { 407 for (k = 0; k < 5; k++) {
405 ds.port = mdev->port; 408 ds.port = mdev->port;
406 ds.unit = k + 1; 409 ds.unit = k + 1;
407 retval = 410 retval =
408 bus_for_each_dev(&maple_bus_type, NULL, &ds, 411 bus_for_each_dev(&maple_bus_type, NULL, &ds,
409 detach_maple_device); 412 detach_maple_device);
410 if (retval) { 413 if (retval) {
411 submask = submask >> 1; 414 submask = submask >> 1;
412 continue; 415 continue;
413 } 416 }
414 devcheck = submask & 0x01; 417 devcheck = submask & 0x01;
415 if (devcheck) { 418 if (devcheck) {
416 mdev_add = maple_alloc_dev(mdev->port, k + 1); 419 mdev_add = maple_alloc_dev(mdev->port, k + 1);
417 if (!mdev_add) 420 if (!mdev_add)
418 return; 421 return;
419 mdev_add->mq->command = MAPLE_COMMAND_DEVINFO; 422 mdev_add->mq->command = MAPLE_COMMAND_DEVINFO;
420 mdev_add->mq->length = 0; 423 mdev_add->mq->length = 0;
421 maple_add_packet(mdev_add->mq); 424 maple_add_packet(mdev_add->mq);
422 scanning = 1; 425 scanning = 1;
423 } 426 }
424 submask = submask >> 1; 427 submask = submask >> 1;
425 } 428 }
426} 429}
427 430
428/* mark a device as removed */ 431/* mark a device as removed */
429static void maple_clean_submap(struct maple_device *mdev) 432static void maple_clean_submap(struct maple_device *mdev)
430{ 433{
431 int killbit; 434 int killbit;
432 435
433 killbit = (mdev->unit > 0 ? (1 << (mdev->unit - 1)) & 0x1f : 0x20); 436 killbit = (mdev->unit > 0 ? (1 << (mdev->unit - 1)) & 0x1f : 0x20);
434 killbit = ~killbit; 437 killbit = ~killbit;
435 killbit &= 0xFF; 438 killbit &= 0xFF;
436 subdevice_map[mdev->port] = subdevice_map[mdev->port] & killbit; 439 subdevice_map[mdev->port] = subdevice_map[mdev->port] & killbit;
437} 440}
438 441
439/* handle empty port or hotplug removal */ 442/* handle empty port or hotplug removal */
440static void maple_response_none(struct maple_device *mdev, 443static void maple_response_none(struct maple_device *mdev,
441 struct mapleq *mq) 444 struct mapleq *mq)
442{ 445{
443 if (mdev->unit != 0) { 446 if (mdev->unit != 0) {
444 list_del(&mq->list); 447 list_del(&mq->list);
445 maple_clean_submap(mdev); 448 maple_clean_submap(mdev);
446 printk(KERN_INFO 449 printk(KERN_INFO
447 "Maple bus device detaching at (%d, %d)\n", 450 "Maple bus device detaching at (%d, %d)\n",
448 mdev->port, mdev->unit); 451 mdev->port, mdev->unit);
449 maple_detach_driver(mdev); 452 maple_detach_driver(mdev);
450 return; 453 return;
451 } 454 }
452 if (!started) { 455 if (!started) {
453 printk(KERN_INFO "No maple devices attached to port %d\n", 456 printk(KERN_INFO "No maple devices attached to port %d\n",
454 mdev->port); 457 mdev->port);
455 return; 458 return;
456 } 459 }
457 maple_clean_submap(mdev); 460 maple_clean_submap(mdev);
458} 461}
459 462
460/* preprocess hotplugs or scans */ 463/* preprocess hotplugs or scans */
461static void maple_response_devinfo(struct maple_device *mdev, 464static void maple_response_devinfo(struct maple_device *mdev,
462 char *recvbuf) 465 char *recvbuf)
463{ 466{
464 char submask; 467 char submask;
465 if ((!started) || (scanning == 2)) { 468 if ((!started) || (scanning == 2)) {
466 maple_attach_driver(mdev); 469 maple_attach_driver(mdev);
467 return; 470 return;
468 } 471 }
469 if (mdev->unit == 0) { 472 if (mdev->unit == 0) {
470 submask = recvbuf[2] & 0x1F; 473 submask = recvbuf[2] & 0x1F;
471 if (submask ^ subdevice_map[mdev->port]) { 474 if (submask ^ subdevice_map[mdev->port]) {
472 maple_map_subunits(mdev, submask); 475 maple_map_subunits(mdev, submask);
473 subdevice_map[mdev->port] = submask; 476 subdevice_map[mdev->port] = submask;
474 } 477 }
475 } 478 }
476} 479}
477 480
478/* maple dma end bottom half - implemented via workqueue */ 481/* maple dma end bottom half - implemented via workqueue */
479static void maple_dma_handler(struct work_struct *work) 482static void maple_dma_handler(struct work_struct *work)
480{ 483{
481 struct mapleq *mq, *nmq; 484 struct mapleq *mq, *nmq;
482 struct maple_device *dev; 485 struct maple_device *dev;
483 char *recvbuf; 486 char *recvbuf;
484 enum maple_code code; 487 enum maple_code code;
485 488
486 if (!maple_dma_done()) 489 if (!maple_dma_done())
487 return; 490 return;
488 ctrl_outl(0, MAPLE_ENABLE); 491 ctrl_outl(0, MAPLE_ENABLE);
489 if (!list_empty(&maple_sentq)) { 492 if (!list_empty(&maple_sentq)) {
490 list_for_each_entry_safe(mq, nmq, &maple_sentq, list) { 493 list_for_each_entry_safe(mq, nmq, &maple_sentq, list) {
491 recvbuf = mq->recvbuf; 494 recvbuf = mq->recvbuf;
492 code = recvbuf[0]; 495 code = recvbuf[0];
493 dev = mq->dev; 496 dev = mq->dev;
494 switch (code) { 497 switch (code) {
495 case MAPLE_RESPONSE_NONE: 498 case MAPLE_RESPONSE_NONE:
496 maple_response_none(dev, mq); 499 maple_response_none(dev, mq);
497 break; 500 break;
498 501
499 case MAPLE_RESPONSE_DEVINFO: 502 case MAPLE_RESPONSE_DEVINFO:
500 maple_response_devinfo(dev, recvbuf); 503 maple_response_devinfo(dev, recvbuf);
501 break; 504 break;
502 505
503 case MAPLE_RESPONSE_DATATRF: 506 case MAPLE_RESPONSE_DATATRF:
504 if (dev->callback) 507 if (dev->callback)
505 dev->callback(mq); 508 dev->callback(mq);
506 break; 509 break;
507 510
508 case MAPLE_RESPONSE_FILEERR: 511 case MAPLE_RESPONSE_FILEERR:
509 case MAPLE_RESPONSE_AGAIN: 512 case MAPLE_RESPONSE_AGAIN:
510 case MAPLE_RESPONSE_BADCMD: 513 case MAPLE_RESPONSE_BADCMD:
511 case MAPLE_RESPONSE_BADFUNC: 514 case MAPLE_RESPONSE_BADFUNC:
512 printk(KERN_DEBUG 515 printk(KERN_DEBUG
513 "Maple non-fatal error 0x%X\n", 516 "Maple non-fatal error 0x%X\n",
514 code); 517 code);
515 break; 518 break;
516 519
517 case MAPLE_RESPONSE_ALLINFO: 520 case MAPLE_RESPONSE_ALLINFO:
518 printk(KERN_DEBUG 521 printk(KERN_DEBUG
519 "Maple - extended device information not supported\n"); 522 "Maple - extended device information not supported\n");
520 break; 523 break;
521 524
522 case MAPLE_RESPONSE_OK: 525 case MAPLE_RESPONSE_OK:
523 break; 526 break;
524 527
525 default: 528 default:
526 break; 529 break;
527 } 530 }
528 } 531 }
529 INIT_LIST_HEAD(&maple_sentq); 532 INIT_LIST_HEAD(&maple_sentq);
530 if (scanning == 1) { 533 if (scanning == 1) {
531 maple_send(); 534 maple_send();
532 scanning = 2; 535 scanning = 2;
533 } else 536 } else
534 scanning = 0; 537 scanning = 0;
535 538
536 if (started == 0) 539 if (started == 0)
537 started = 1; 540 started = 1;
538 } 541 }
539 maplebus_dma_reset(); 542 maplebus_dma_reset();
540} 543}
541 544
542static irqreturn_t maplebus_dma_interrupt(int irq, void *dev_id) 545static irqreturn_t maplebus_dma_interrupt(int irq, void *dev_id)
543{ 546{
544 /* Load everything into the bottom half */ 547 /* Load everything into the bottom half */
545 schedule_work(&maple_dma_process); 548 schedule_work(&maple_dma_process);
546 return IRQ_HANDLED; 549 return IRQ_HANDLED;
547} 550}
548 551
549static irqreturn_t maplebus_vblank_interrupt(int irq, void *dev_id) 552static irqreturn_t maplebus_vblank_interrupt(int irq, void *dev_id)
550{ 553{
551 schedule_work(&maple_vblank_process); 554 schedule_work(&maple_vblank_process);
552 return IRQ_HANDLED; 555 return IRQ_HANDLED;
553} 556}
554 557
555static struct irqaction maple_dma_irq = { 558static struct irqaction maple_dma_irq = {
556 .name = "maple bus DMA handler", 559 .name = "maple bus DMA handler",
557 .handler = maplebus_dma_interrupt, 560 .handler = maplebus_dma_interrupt,
558 .flags = IRQF_SHARED, 561 .flags = IRQF_SHARED,
559}; 562};
560 563
561static struct irqaction maple_vblank_irq = { 564static struct irqaction maple_vblank_irq = {
562 .name = "maple bus VBLANK handler", 565 .name = "maple bus VBLANK handler",
563 .handler = maplebus_vblank_interrupt, 566 .handler = maplebus_vblank_interrupt,
564 .flags = IRQF_SHARED, 567 .flags = IRQF_SHARED,
565}; 568};
566 569
567static int maple_set_dma_interrupt_handler(void) 570static int maple_set_dma_interrupt_handler(void)
568{ 571{
569 return setup_irq(HW_EVENT_MAPLE_DMA, &maple_dma_irq); 572 return setup_irq(HW_EVENT_MAPLE_DMA, &maple_dma_irq);
570} 573}
571 574
572static int maple_set_vblank_interrupt_handler(void) 575static int maple_set_vblank_interrupt_handler(void)
573{ 576{
574 return setup_irq(HW_EVENT_VSYNC, &maple_vblank_irq); 577 return setup_irq(HW_EVENT_VSYNC, &maple_vblank_irq);
575} 578}
576 579
577static int maple_get_dma_buffer(void) 580static int maple_get_dma_buffer(void)
578{ 581{
579 maple_sendbuf = 582 maple_sendbuf =
580 (void *) __get_free_pages(GFP_KERNEL | __GFP_ZERO, 583 (void *) __get_free_pages(GFP_KERNEL | __GFP_ZERO,
581 MAPLE_DMA_PAGES); 584 MAPLE_DMA_PAGES);
582 if (!maple_sendbuf) 585 if (!maple_sendbuf)
583 return -ENOMEM; 586 return -ENOMEM;
584 return 0; 587 return 0;
585} 588}
586 589
587static int match_maple_bus_driver(struct device *devptr, 590static int match_maple_bus_driver(struct device *devptr,
588 struct device_driver *drvptr) 591 struct device_driver *drvptr)
589{ 592{
590 struct maple_driver *maple_drv; 593 struct maple_driver *maple_drv;
591 struct maple_device *maple_dev; 594 struct maple_device *maple_dev;
592 595
593 maple_drv = container_of(drvptr, struct maple_driver, drv); 596 maple_drv = container_of(drvptr, struct maple_driver, drv);
594 maple_dev = container_of(devptr, struct maple_device, dev); 597 maple_dev = container_of(devptr, struct maple_device, dev);
595 /* Trap empty port case */ 598 /* Trap empty port case */
596 if (maple_dev->devinfo.function == 0xFFFFFFFF) 599 if (maple_dev->devinfo.function == 0xFFFFFFFF)
597 return 0; 600 return 0;
598 else if (maple_dev->devinfo.function & 601 else if (maple_dev->devinfo.function &
599 be32_to_cpu(maple_drv->function)) 602 be32_to_cpu(maple_drv->function))
600 return 1; 603 return 1;
601 return 0; 604 return 0;
602} 605}
603 606
604static int maple_bus_uevent(struct device *dev, struct kobj_uevent_env *env) 607static int maple_bus_uevent(struct device *dev,
608 struct kobj_uevent_env *env)
605{ 609{
606 return 0; 610 return 0;
607} 611}
608 612
609static void maple_bus_release(struct device *dev) 613static void maple_bus_release(struct device *dev)
@@ -611,124 +615,126 @@ static void maple_bus_release(struct device *dev)
611} 615}
612 616
613static struct maple_driver maple_dummy_driver = { 617static struct maple_driver maple_dummy_driver = {
614 .drv = { 618 .drv = {
615 .name = "maple_dummy_driver", 619 .name = "maple_dummy_driver",
616 .bus = &maple_bus_type, 620 .bus = &maple_bus_type,
617 }, 621 },
618}; 622};
619 623
620struct bus_type maple_bus_type = { 624struct bus_type maple_bus_type = {
621 .name = "maple", 625 .name = "maple",
622 .match = match_maple_bus_driver, 626 .match = match_maple_bus_driver,
623 .uevent = maple_bus_uevent, 627 .uevent = maple_bus_uevent,
624}; 628};
629
625EXPORT_SYMBOL_GPL(maple_bus_type); 630EXPORT_SYMBOL_GPL(maple_bus_type);
626 631
627static struct device maple_bus = { 632static struct device maple_bus = {
628 .bus_id = "maple", 633 .bus_id = "maple",
629 .release = maple_bus_release, 634 .release = maple_bus_release,
630}; 635};
631 636
632static int __init maple_bus_init(void) 637static int __init maple_bus_init(void)
633{ 638{
634 int retval, i; 639 int retval, i;
635 struct maple_device *mdev[MAPLE_PORTS]; 640 struct maple_device *mdev[MAPLE_PORTS];
636 ctrl_outl(0, MAPLE_STATE); 641 ctrl_outl(0, MAPLE_STATE);
637 642
638 retval = device_register(&maple_bus); 643 retval = device_register(&maple_bus);
639 if (retval) 644 if (retval)
640 goto cleanup; 645 goto cleanup;
641 646
642 retval = bus_register(&maple_bus_type); 647 retval = bus_register(&maple_bus_type);
643 if (retval) 648 if (retval)
644 goto cleanup_device; 649 goto cleanup_device;
645 650
646 retval = driver_register(&maple_dummy_driver.drv); 651 retval = driver_register(&maple_dummy_driver.drv);
647 652
648 if (retval) 653 if (retval)
649 goto cleanup_bus; 654 goto cleanup_bus;
650 655
651 /* allocate memory for maple bus dma */ 656 /* allocate memory for maple bus dma */
652 retval = maple_get_dma_buffer(); 657 retval = maple_get_dma_buffer();
653 if (retval) { 658 if (retval) {
654 printk(KERN_INFO 659 printk(KERN_INFO
655 "Maple bus: Failed to allocate Maple DMA buffers\n"); 660 "Maple bus: Failed to allocate Maple DMA buffers\n");
656 goto cleanup_basic; 661 goto cleanup_basic;
657 } 662 }
658 663
659 /* set up DMA interrupt handler */ 664 /* set up DMA interrupt handler */
660 retval = maple_set_dma_interrupt_handler(); 665 retval = maple_set_dma_interrupt_handler();
661 if (retval) { 666 if (retval) {
662 printk(KERN_INFO 667 printk(KERN_INFO
663 "Maple bus: Failed to grab maple DMA IRQ\n"); 668 "Maple bus: Failed to grab maple DMA IRQ\n");
664 goto cleanup_dma; 669 goto cleanup_dma;
665 } 670 }
666 671
667 /* set up VBLANK interrupt handler */ 672 /* set up VBLANK interrupt handler */
668 retval = maple_set_vblank_interrupt_handler(); 673 retval = maple_set_vblank_interrupt_handler();
669 if (retval) { 674 if (retval) {
670 printk(KERN_INFO "Maple bus: Failed to grab VBLANK IRQ\n"); 675 printk(KERN_INFO "Maple bus: Failed to grab VBLANK IRQ\n");
671 goto cleanup_irq; 676 goto cleanup_irq;
672 } 677 }
673 678
674 maple_queue_cache = 679 maple_queue_cache =
675 kmem_cache_create("maple_queue_cache", 0x400, 0, 680 kmem_cache_create("maple_queue_cache", 0x400, 0,
676 SLAB_HWCACHE_ALIGN, NULL); 681 SLAB_HWCACHE_ALIGN, NULL);
677 682
678 if (!maple_queue_cache) 683 if (!maple_queue_cache)
679 goto cleanup_bothirqs; 684 goto cleanup_bothirqs;
680 685
681 /* setup maple ports */ 686 /* setup maple ports */
682 for (i = 0; i < MAPLE_PORTS; i++) { 687 for (i = 0; i < MAPLE_PORTS; i++) {
683 mdev[i] = maple_alloc_dev(i, 0); 688 mdev[i] = maple_alloc_dev(i, 0);
684 if (!mdev[i]) { 689 if (!mdev[i]) {
685 while (i-- > 0) 690 while (i-- > 0)
686 maple_free_dev(mdev[i]); 691 maple_free_dev(mdev[i]);
687 goto cleanup_cache; 692 goto cleanup_cache;
688 } 693 }
689 mdev[i]->registered = 0; 694 mdev[i]->registered = 0;
690 mdev[i]->mq->command = MAPLE_COMMAND_DEVINFO; 695 mdev[i]->mq->command = MAPLE_COMMAND_DEVINFO;
691 mdev[i]->mq->length = 0; 696 mdev[i]->mq->length = 0;
692 maple_attach_driver(mdev[i]); 697 maple_attach_driver(mdev[i]);
693 maple_add_packet(mdev[i]->mq); 698 maple_add_packet(mdev[i]->mq);
694 subdevice_map[i] = 0; 699 subdevice_map[i] = 0;
695 } 700 }
696 701
697 /* setup maplebus hardware */ 702 /* setup maplebus hardware */
698 maplebus_dma_reset(); 703 maplebus_dma_reset();
699 704
700 /* initial detection */ 705 /* initial detection */
701 maple_send(); 706 maple_send();
702 707
703 maple_pnp_time = jiffies; 708 maple_pnp_time = jiffies;
704 709
705 printk(KERN_INFO "Maple bus core now registered.\n"); 710 printk(KERN_INFO "Maple bus core now registered.\n");
706 711
707 return 0; 712 return 0;
708 713
709cleanup_cache: 714 cleanup_cache:
710 kmem_cache_destroy(maple_queue_cache); 715 kmem_cache_destroy(maple_queue_cache);
711 716
712cleanup_bothirqs: 717 cleanup_bothirqs:
713 free_irq(HW_EVENT_VSYNC, 0); 718 free_irq(HW_EVENT_VSYNC, 0);
714 719
715cleanup_irq: 720 cleanup_irq:
716 free_irq(HW_EVENT_MAPLE_DMA, 0); 721 free_irq(HW_EVENT_MAPLE_DMA, 0);
717 722
718cleanup_dma: 723 cleanup_dma:
719 free_pages((unsigned long) maple_sendbuf, MAPLE_DMA_PAGES); 724 free_pages((unsigned long) maple_sendbuf, MAPLE_DMA_PAGES);
720 725
721cleanup_basic: 726 cleanup_basic:
722 driver_unregister(&maple_dummy_driver.drv); 727 driver_unregister(&maple_dummy_driver.drv);
723 728
724cleanup_bus: 729 cleanup_bus:
725 bus_unregister(&maple_bus_type); 730 bus_unregister(&maple_bus_type);
726 731
727cleanup_device: 732 cleanup_device:
728 device_unregister(&maple_bus); 733 device_unregister(&maple_bus);
729 734
730cleanup: 735 cleanup:
731 printk(KERN_INFO "Maple bus registration failed\n"); 736 printk(KERN_INFO "Maple bus registration failed\n");
732 return retval; 737 return retval;
733} 738}
739
734subsys_initcall(maple_bus_init); 740subsys_initcall(maple_bus_init);
diff --git a/include/linux/maple.h b/include/linux/maple.h
index bad9a7b319de..f82c17b77158 100644
--- a/include/linux/maple.h
+++ b/include/linux/maple.h
@@ -7,74 +7,75 @@ extern struct bus_type maple_bus_type;
7 7
8/* Maple Bus command and response codes */ 8/* Maple Bus command and response codes */
9enum maple_code { 9enum maple_code {
10 MAPLE_RESPONSE_FILEERR = -5, 10 MAPLE_RESPONSE_FILEERR = -5,
11 MAPLE_RESPONSE_AGAIN = -4, /* request should be retransmitted */ 11 MAPLE_RESPONSE_AGAIN = -4, /* request should be retransmitted */
12 MAPLE_RESPONSE_BADCMD = -3, 12 MAPLE_RESPONSE_BADCMD = -3,
13 MAPLE_RESPONSE_BADFUNC = -2, 13 MAPLE_RESPONSE_BADFUNC = -2,
14 MAPLE_RESPONSE_NONE = -1, /* unit didn't respond at all */ 14 MAPLE_RESPONSE_NONE = -1, /* unit didn't respond at all */
15 MAPLE_COMMAND_DEVINFO = 1, 15 MAPLE_COMMAND_DEVINFO = 1,
16 MAPLE_COMMAND_ALLINFO = 2, 16 MAPLE_COMMAND_ALLINFO = 2,
17 MAPLE_COMMAND_RESET = 3, 17 MAPLE_COMMAND_RESET = 3,
18 MAPLE_COMMAND_KILL = 4, 18 MAPLE_COMMAND_KILL = 4,
19 MAPLE_RESPONSE_DEVINFO = 5, 19 MAPLE_RESPONSE_DEVINFO = 5,
20 MAPLE_RESPONSE_ALLINFO = 6, 20 MAPLE_RESPONSE_ALLINFO = 6,
21 MAPLE_RESPONSE_OK = 7, 21 MAPLE_RESPONSE_OK = 7,
22 MAPLE_RESPONSE_DATATRF = 8, 22 MAPLE_RESPONSE_DATATRF = 8,
23 MAPLE_COMMAND_GETCOND = 9, 23 MAPLE_COMMAND_GETCOND = 9,
24 MAPLE_COMMAND_GETMINFO = 10, 24 MAPLE_COMMAND_GETMINFO = 10,
25 MAPLE_COMMAND_BREAD = 11, 25 MAPLE_COMMAND_BREAD = 11,
26 MAPLE_COMMAND_BWRITE = 12, 26 MAPLE_COMMAND_BWRITE = 12,
27 MAPLE_COMMAND_SETCOND = 14 27 MAPLE_COMMAND_SETCOND = 14
28}; 28};
29 29
30struct mapleq { 30struct mapleq {
31 struct list_head list; 31 struct list_head list;
32 struct maple_device *dev; 32 struct maple_device *dev;
33 void *sendbuf, *recvbuf, *recvbufdcsp; 33 void *sendbuf, *recvbuf, *recvbufdcsp;
34 unsigned char length; 34 unsigned char length;
35 enum maple_code command; 35 enum maple_code command;
36}; 36};
37 37
38struct maple_devinfo { 38struct maple_devinfo {
39 unsigned long function; 39 unsigned long function;
40 unsigned long function_data[3]; 40 unsigned long function_data[3];
41 unsigned char area_code; 41 unsigned char area_code;
42 unsigned char connector_directon; 42 unsigned char connector_directon;
43 char product_name[31]; 43 char product_name[31];
44 char product_licence[61]; 44 char product_licence[61];
45 unsigned short standby_power; 45 unsigned short standby_power;
46 unsigned short max_power; 46 unsigned short max_power;
47}; 47};
48 48
49struct maple_device { 49struct maple_device {
50 struct maple_driver *driver; 50 struct maple_driver *driver;
51 struct mapleq *mq; 51 struct mapleq *mq;
52 void *private_data; 52 void *private_data;
53 void (*callback) (struct mapleq * mq); 53 void (*callback) (struct mapleq * mq);
54 unsigned long when, interval, function; 54 unsigned long when, interval, function;
55 struct maple_devinfo devinfo; 55 struct maple_devinfo devinfo;
56 unsigned char port, unit; 56 unsigned char port, unit;
57 char product_name[32]; 57 char product_name[32];
58 char product_licence[64]; 58 char product_licence[64];
59 int registered; 59 int registered;
60 struct device dev; 60 struct device dev;
61}; 61};
62 62
63struct maple_driver { 63struct maple_driver {
64 unsigned long function; 64 unsigned long function;
65 int (*connect) (struct maple_device * dev); 65 int (*connect) (struct maple_device * dev);
66 void (*disconnect) (struct maple_device * dev); 66 void (*disconnect) (struct maple_device * dev);
67 struct device_driver drv; 67 struct device_driver drv;
68 int registered;
68}; 69};
69 70
70void maple_getcond_callback(struct maple_device *dev, 71void maple_getcond_callback(struct maple_device *dev,
71 void (*callback) (struct mapleq * mq), 72 void (*callback) (struct mapleq * mq),
72 unsigned long interval, 73 unsigned long interval,
73 unsigned long function); 74 unsigned long function);
74int maple_driver_register(struct device_driver *drv); 75int maple_driver_register(struct device_driver *drv);
75void maple_add_packet(struct mapleq *mq); 76void maple_add_packet(struct mapleq *mq);
76 77
77#define to_maple_dev(n) container_of(n, struct maple_device, dev) 78#define to_maple_dev(n) container_of(n, struct maple_device, dev)
78#define to_maple_driver(n) container_of(n, struct maple_driver, drv) 79#define to_maple_driver(n) container_of(n, struct maple_driver, drv)
79 80
80#endif /* __LINUX_MAPLE_H */ 81#endif /* __LINUX_MAPLE_H */