aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/macintosh/adb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/macintosh/adb.c')
-rw-r--r--drivers/macintosh/adb.c174
1 files changed, 78 insertions, 96 deletions
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index b7adde4324e4..7ce0ea64465c 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -35,6 +35,7 @@
35#include <linux/spinlock.h> 35#include <linux/spinlock.h>
36#include <linux/completion.h> 36#include <linux/completion.h>
37#include <linux/device.h> 37#include <linux/device.h>
38#include <linux/kthread.h>
38 39
39#include <asm/uaccess.h> 40#include <asm/uaccess.h>
40#include <asm/semaphore.h> 41#include <asm/semaphore.h>
@@ -82,21 +83,11 @@ struct adb_driver *adb_controller;
82BLOCKING_NOTIFIER_HEAD(adb_client_list); 83BLOCKING_NOTIFIER_HEAD(adb_client_list);
83static int adb_got_sleep; 84static int adb_got_sleep;
84static int adb_inited; 85static int adb_inited;
85static pid_t adb_probe_task_pid;
86static DECLARE_MUTEX(adb_probe_mutex); 86static DECLARE_MUTEX(adb_probe_mutex);
87static struct completion adb_probe_task_comp;
88static int sleepy_trackpad; 87static int sleepy_trackpad;
89static int autopoll_devs; 88static int autopoll_devs;
90int __adb_probe_sync; 89int __adb_probe_sync;
91 90
92#ifdef CONFIG_PM_SLEEP
93static void adb_notify_sleep(struct pmu_sleep_notifier *self, int when);
94static struct pmu_sleep_notifier adb_sleep_notifier = {
95 adb_notify_sleep,
96 SLEEP_LEVEL_ADB,
97};
98#endif
99
100static int adb_scan_bus(void); 91static int adb_scan_bus(void);
101static int do_adb_reset_bus(void); 92static int do_adb_reset_bus(void);
102static void adbdev_init(void); 93static void adbdev_init(void);
@@ -134,16 +125,6 @@ static void printADBreply(struct adb_request *req)
134} 125}
135#endif 126#endif
136 127
137
138static __inline__ void adb_wait_ms(unsigned int ms)
139{
140 if (current->pid && adb_probe_task_pid &&
141 adb_probe_task_pid == current->pid)
142 msleep(ms);
143 else
144 mdelay(ms);
145}
146
147static int adb_scan_bus(void) 128static int adb_scan_bus(void)
148{ 129{
149 int i, highFree=0, noMovement; 130 int i, highFree=0, noMovement;
@@ -248,13 +229,10 @@ static int adb_scan_bus(void)
248static int 229static int
249adb_probe_task(void *x) 230adb_probe_task(void *x)
250{ 231{
251 strcpy(current->comm, "kadbprobe");
252
253 printk(KERN_INFO "adb: starting probe task...\n"); 232 printk(KERN_INFO "adb: starting probe task...\n");
254 do_adb_reset_bus(); 233 do_adb_reset_bus();
255 printk(KERN_INFO "adb: finished probe task...\n"); 234 printk(KERN_INFO "adb: finished probe task...\n");
256 235
257 adb_probe_task_pid = 0;
258 up(&adb_probe_mutex); 236 up(&adb_probe_mutex);
259 237
260 return 0; 238 return 0;
@@ -263,7 +241,7 @@ adb_probe_task(void *x)
263static void 241static void
264__adb_probe_task(struct work_struct *bullshit) 242__adb_probe_task(struct work_struct *bullshit)
265{ 243{
266 adb_probe_task_pid = kernel_thread(adb_probe_task, NULL, SIGCHLD | CLONE_KERNEL); 244 kthread_run(adb_probe_task, NULL, "kadbprobe");
267} 245}
268 246
269static DECLARE_WORK(adb_reset_work, __adb_probe_task); 247static DECLARE_WORK(adb_reset_work, __adb_probe_task);
@@ -281,6 +259,36 @@ adb_reset_bus(void)
281 return 0; 259 return 0;
282} 260}
283 261
262#ifdef CONFIG_PM
263/*
264 * notify clients before sleep
265 */
266static int adb_suspend(struct platform_device *dev, pm_message_t state)
267{
268 adb_got_sleep = 1;
269 /* We need to get a lock on the probe thread */
270 down(&adb_probe_mutex);
271 /* Stop autopoll */
272 if (adb_controller->autopoll)
273 adb_controller->autopoll(0);
274 blocking_notifier_call_chain(&adb_client_list, ADB_MSG_POWERDOWN, NULL);
275
276 return 0;
277}
278
279/*
280 * reset bus after sleep
281 */
282static int adb_resume(struct platform_device *dev)
283{
284 adb_got_sleep = 0;
285 up(&adb_probe_mutex);
286 adb_reset_bus();
287
288 return 0;
289}
290#endif /* CONFIG_PM */
291
284int __init adb_init(void) 292int __init adb_init(void)
285{ 293{
286 struct adb_driver *driver; 294 struct adb_driver *driver;
@@ -313,15 +321,12 @@ int __init adb_init(void)
313 printk(KERN_WARNING "Warning: no ADB interface detected\n"); 321 printk(KERN_WARNING "Warning: no ADB interface detected\n");
314 adb_controller = NULL; 322 adb_controller = NULL;
315 } else { 323 } else {
316#ifdef CONFIG_PM_SLEEP
317 pmu_register_sleep_notifier(&adb_sleep_notifier);
318#endif /* CONFIG_PM */
319#ifdef CONFIG_PPC 324#ifdef CONFIG_PPC
320 if (machine_is_compatible("AAPL,PowerBook1998") || 325 if (machine_is_compatible("AAPL,PowerBook1998") ||
321 machine_is_compatible("PowerBook1,1")) 326 machine_is_compatible("PowerBook1,1"))
322 sleepy_trackpad = 1; 327 sleepy_trackpad = 1;
323#endif /* CONFIG_PPC */ 328#endif /* CONFIG_PPC */
324 init_completion(&adb_probe_task_comp); 329
325 adbdev_init(); 330 adbdev_init();
326 adb_reset_bus(); 331 adb_reset_bus();
327 } 332 }
@@ -330,33 +335,6 @@ int __init adb_init(void)
330 335
331__initcall(adb_init); 336__initcall(adb_init);
332 337
333#ifdef CONFIG_PM
334/*
335 * notify clients before sleep and reset bus afterwards
336 */
337void
338adb_notify_sleep(struct pmu_sleep_notifier *self, int when)
339{
340 switch (when) {
341 case PBOOK_SLEEP_REQUEST:
342 adb_got_sleep = 1;
343 /* We need to get a lock on the probe thread */
344 down(&adb_probe_mutex);
345 /* Stop autopoll */
346 if (adb_controller->autopoll)
347 adb_controller->autopoll(0);
348 blocking_notifier_call_chain(&adb_client_list,
349 ADB_MSG_POWERDOWN, NULL);
350 break;
351 case PBOOK_WAKE:
352 adb_got_sleep = 0;
353 up(&adb_probe_mutex);
354 adb_reset_bus();
355 break;
356 }
357}
358#endif /* CONFIG_PM */
359
360static int 338static int
361do_adb_reset_bus(void) 339do_adb_reset_bus(void)
362{ 340{
@@ -373,7 +351,7 @@ do_adb_reset_bus(void)
373 351
374 if (sleepy_trackpad) { 352 if (sleepy_trackpad) {
375 /* Let the trackpad settle down */ 353 /* Let the trackpad settle down */
376 adb_wait_ms(500); 354 msleep(500);
377 } 355 }
378 356
379 down(&adb_handler_sem); 357 down(&adb_handler_sem);
@@ -389,7 +367,7 @@ do_adb_reset_bus(void)
389 367
390 if (sleepy_trackpad) { 368 if (sleepy_trackpad) {
391 /* Let the trackpad settle down */ 369 /* Let the trackpad settle down */
392 adb_wait_ms(1500); 370 msleep(1500);
393 } 371 }
394 372
395 if (!ret) { 373 if (!ret) {
@@ -413,41 +391,27 @@ adb_poll(void)
413 adb_controller->poll(); 391 adb_controller->poll();
414} 392}
415 393
416static void 394static void adb_sync_req_done(struct adb_request *req)
417adb_probe_wakeup(struct adb_request *req)
418{ 395{
419 complete(&adb_probe_task_comp); 396 struct completion *comp = req->arg;
420}
421 397
422/* Static request used during probe */ 398 complete(comp);
423static struct adb_request adb_sreq; 399}
424static unsigned long adb_sreq_lock; // Use semaphore ! */
425 400
426int 401int
427adb_request(struct adb_request *req, void (*done)(struct adb_request *), 402adb_request(struct adb_request *req, void (*done)(struct adb_request *),
428 int flags, int nbytes, ...) 403 int flags, int nbytes, ...)
429{ 404{
430 va_list list; 405 va_list list;
431 int i, use_sreq; 406 int i;
432 int rc; 407 int rc;
408 struct completion comp;
433 409
434 if ((adb_controller == NULL) || (adb_controller->send_request == NULL)) 410 if ((adb_controller == NULL) || (adb_controller->send_request == NULL))
435 return -ENXIO; 411 return -ENXIO;
436 if (nbytes < 1) 412 if (nbytes < 1)
437 return -EINVAL; 413 return -EINVAL;
438 if (req == NULL && (flags & ADBREQ_NOSEND)) 414
439 return -EINVAL;
440
441 if (req == NULL) {
442 if (test_and_set_bit(0,&adb_sreq_lock)) {
443 printk("adb.c: Warning: contention on static request !\n");
444 return -EPERM;
445 }
446 req = &adb_sreq;
447 flags |= ADBREQ_SYNC;
448 use_sreq = 1;
449 } else
450 use_sreq = 0;
451 req->nbytes = nbytes+1; 415 req->nbytes = nbytes+1;
452 req->done = done; 416 req->done = done;
453 req->reply_expected = flags & ADBREQ_REPLY; 417 req->reply_expected = flags & ADBREQ_REPLY;
@@ -460,25 +424,18 @@ adb_request(struct adb_request *req, void (*done)(struct adb_request *),
460 if (flags & ADBREQ_NOSEND) 424 if (flags & ADBREQ_NOSEND)
461 return 0; 425 return 0;
462 426
463 /* Synchronous requests send from the probe thread cause it to 427 /* Synchronous requests block using an on-stack completion */
464 * block. Beware that the "done" callback will be overriden ! 428 if (flags & ADBREQ_SYNC) {
465 */ 429 WARN_ON(done);
466 if ((flags & ADBREQ_SYNC) && 430 req->done = adb_sync_req_done;
467 (current->pid && adb_probe_task_pid && 431 req->arg = &comp;
468 adb_probe_task_pid == current->pid)) { 432 init_completion(&comp);
469 req->done = adb_probe_wakeup;
470 rc = adb_controller->send_request(req, 0);
471 if (rc || req->complete)
472 goto bail;
473 wait_for_completion(&adb_probe_task_comp);
474 rc = 0;
475 goto bail;
476 } 433 }
477 434
478 rc = adb_controller->send_request(req, flags & ADBREQ_SYNC); 435 rc = adb_controller->send_request(req, 0);
479bail: 436
480 if (use_sreq) 437 if ((flags & ADBREQ_SYNC) && !rc && !req->complete)
481 clear_bit(0, &adb_sreq_lock); 438 wait_for_completion(&comp);
482 439
483 return rc; 440 return rc;
484} 441}
@@ -864,7 +821,29 @@ static const struct file_operations adb_fops = {
864 .release = adb_release, 821 .release = adb_release,
865}; 822};
866 823
867static void 824static struct platform_driver adb_pfdrv = {
825 .driver = {
826 .name = "adb",
827 },
828#ifdef CONFIG_PM
829 .suspend = adb_suspend,
830 .resume = adb_resume,
831#endif
832};
833
834static struct platform_device adb_pfdev = {
835 .name = "adb",
836};
837
838static int __init
839adb_dummy_probe(struct platform_device *dev)
840{
841 if (dev == &adb_pfdev)
842 return 0;
843 return -ENODEV;
844}
845
846static void __init
868adbdev_init(void) 847adbdev_init(void)
869{ 848{
870 if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) { 849 if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) {
@@ -876,4 +855,7 @@ adbdev_init(void)
876 if (IS_ERR(adb_dev_class)) 855 if (IS_ERR(adb_dev_class))
877 return; 856 return;
878 device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), "adb"); 857 device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), "adb");
858
859 platform_device_register(&adb_pfdev);
860 platform_driver_probe(&adb_pfdrv, adb_dummy_probe);
879} 861}