OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [macintosh/] [mediabay.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * Driver for the media bay on the PowerBook 3400 and 2400.
3
 *
4
 * Copyright (C) 1998 Paul Mackerras.
5
 *
6
 * Various evolutions by Benjamin Herrenschmidt & Henry Worth
7
 *
8
 *  This program is free software; you can redistribute it and/or
9
 *  modify it under the terms of the GNU General Public License
10
 *  as published by the Free Software Foundation; either version
11
 *  2 of the License, or (at your option) any later version.
12
 */
13
#define __KERNEL_SYSCALLS__
14
 
15
#include <linux/config.h>
16
#include <linux/types.h>
17
#include <linux/errno.h>
18
#include <linux/kernel.h>
19
#include <linux/delay.h>
20
#include <linux/sched.h>
21
#include <linux/timer.h>
22
#include <linux/hdreg.h>
23
#include <linux/stddef.h>
24
#include <linux/unistd.h>
25
#include <asm/prom.h>
26
#include <asm/pgtable.h>
27
#include <asm/io.h>
28
#include <asm/machdep.h>
29
#include <asm/pmac_feature.h>
30
#include <asm/mediabay.h>
31
#include <asm/sections.h>
32
#include <asm/ohare.h>
33
#include <asm/heathrow.h>
34
#include <asm/keylargo.h>
35
#include <linux/adb.h>
36
#include <linux/pmu.h>
37
 
38
#ifdef CONFIG_PMAC_PBOOK
39
static int mb_notify_sleep(struct pmu_sleep_notifier *self, int when);
40
static struct pmu_sleep_notifier mb_sleep_notifier = {
41
        mb_notify_sleep,
42
        SLEEP_LEVEL_MEDIABAY,
43
};
44
#endif
45
 
46
#undef MB_USE_INTERRUPTS
47
#define MB_DEBUG
48
#define MB_IGNORE_SIGNALS
49
 
50
#ifdef MB_DEBUG
51
#define MBDBG(fmt, arg...)      printk(KERN_INFO fmt , ## arg)
52
#else
53
#define MBDBG(fmt, arg...)      do { } while (0)
54
#endif
55
 
56
/* Type of media bay */
57
enum {
58
        mb_ohare,
59
        mb_heathrow,
60
        mb_keylargo
61
};
62
 
63
#define MB_FCR32(bay, r)        ((bay)->base + ((r) >> 2))
64
#define MB_FCR8(bay, r)         (((volatile u8*)((bay)->base)) + (r))
65
 
66
#define MB_IN32(bay,r)          (in_le32(MB_FCR32(bay,r)))
67
#define MB_OUT32(bay,r,v)       (out_le32(MB_FCR32(bay,r), (v)))
68
#define MB_BIS(bay,r,v)         (MB_OUT32((bay), (r), MB_IN32((bay), r) | (v)))
69
#define MB_BIC(bay,r,v)         (MB_OUT32((bay), (r), MB_IN32((bay), r) & ~(v)))
70
#define MB_IN8(bay,r)           (in_8(MB_FCR8(bay,r)))
71
#define MB_OUT8(bay,r,v)        (out_8(MB_FCR8(bay,r), (v)))
72
 
73
struct media_bay_info;
74
 
75
struct mb_ops {
76
        char*   name;
77
        u8      (*content)(struct media_bay_info* bay);
78
        void    (*power)(struct media_bay_info* bay, int on_off);
79
        int     (*setup_bus)(struct media_bay_info* bay, u8 device_id);
80
        void    (*un_reset)(struct media_bay_info* bay);
81
        void    (*un_reset_ide)(struct media_bay_info* bay);
82
};
83
 
84
struct media_bay_info {
85
        volatile u32*                   base;
86
        int                             content_id;
87
        int                             state;
88
        int                             last_value;
89
        int                             value_count;
90
        int                             timer;
91
        struct device_node*             dev_node;
92
        int                             mb_type;
93
        struct mb_ops*                  ops;
94
        int                             index;
95
        int                             cached_gpio;
96
#ifdef CONFIG_BLK_DEV_IDE
97
        unsigned long                   cd_base;
98
        int                             cd_index;
99
        int                             cd_irq;
100
        int                             cd_retry;
101
#endif
102
};
103
 
104
#define MAX_BAYS        2
105
 
106
static struct media_bay_info media_bays[MAX_BAYS];
107
int media_bay_count = 0;
108
 
109
#ifdef CONFIG_BLK_DEV_IDE
110
/* check the busy bit in the media-bay ide interface
111
   (assumes the media-bay contains an ide device) */
112
#define MB_IDE_READY(i) ((readb(media_bays[i].cd_base + 0x70) & 0x80) == 0)
113
#endif
114
 
115
/* Note: All delays are not in milliseconds and converted to HZ relative
116
 * values by the macro below
117
 */
118
#define MS_TO_HZ(ms)    ((ms * HZ) / 1000)
119
 
120
/*
121
 * Consider the media-bay ID value stable if it is the same for
122
 * this number of milliseconds
123
 */
124
#define MB_STABLE_DELAY 100
125
 
126
/* Wait after powering up the media bay this delay in ms
127
 * timeout bumped for some powerbooks
128
 */
129
#define MB_POWER_DELAY  200
130
 
131
/*
132
 * Hold the media-bay reset signal true for this many ticks
133
 * after a device is inserted before releasing it.
134
 */
135
#define MB_RESET_DELAY  40
136
 
137
/*
138
 * Wait this long after the reset signal is released and before doing
139
 * further operations. After this delay, the IDE reset signal is released
140
 * too for an IDE device
141
 */
142
#define MB_SETUP_DELAY  100
143
 
144
/*
145
 * Wait this many ticks after an IDE device (e.g. CD-ROM) is inserted
146
 * (or until the device is ready) before waiting for busy bit to disappear
147
 */
148
#define MB_IDE_WAIT     1000
149
 
150
/*
151
 * Timeout waiting for busy bit of an IDE device to go down
152
 */
153
#define MB_IDE_TIMEOUT  5000
154
 
155
/*
156
 * Max retries of the full power up/down sequence for an IDE device
157
 */
158
#define MAX_CD_RETRIES  3
159
 
160
/*
161
 * States of a media bay
162
 */
163
enum {
164
        mb_empty = 0,            /* Idle */
165
        mb_powering_up,         /* power bit set, waiting MB_POWER_DELAY */
166
        mb_enabling_bay,        /* enable bits set, waiting MB_RESET_DELAY */
167
        mb_resetting,           /* reset bit unset, waiting MB_SETUP_DELAY */
168
        mb_ide_resetting,       /* IDE reset bit unser, waiting MB_IDE_WAIT */
169
        mb_ide_waiting,         /* Waiting for BUSY bit to go away until MB_IDE_TIMEOUT */
170
        mb_up,                  /* Media bay full */
171
        mb_powering_down        /* Powering down (avoid too fast down/up) */
172
};
173
 
174
#define MB_POWER_SOUND          0x08
175
#define MB_POWER_FLOPPY         0x04
176
#define MB_POWER_ATA            0x02
177
#define MB_POWER_PCI            0x01
178
#define MB_POWER_OFF            0x00
179
 
180
/*
181
 * Functions for polling content of media bay
182
 */
183
 
184
static u8 __pmac
185
ohare_mb_content(struct media_bay_info *bay)
186
{
187
        return (MB_IN32(bay, OHARE_MBCR) >> 12) & 7;
188
}
189
 
190
static u8 __pmac
191
heathrow_mb_content(struct media_bay_info *bay)
192
{
193
        return (MB_IN32(bay, HEATHROW_MBCR) >> 12) & 7;
194
}
195
 
196
static u8 __pmac
197
keylargo_mb_content(struct media_bay_info *bay)
198
{
199
        int new_gpio;
200
 
201
        new_gpio = MB_IN8(bay, KL_GPIO_MEDIABAY_IRQ) & KEYLARGO_GPIO_INPUT_DATA;
202
        if (new_gpio) {
203
                bay->cached_gpio = new_gpio;
204
                return MB_NO;
205
        } else if (bay->cached_gpio != new_gpio) {
206
                MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_ENABLE);
207
                (void)MB_IN32(bay, KEYLARGO_MBCR);
208
                udelay(5);
209
                MB_BIC(bay, KEYLARGO_MBCR, 0x0000000F);
210
                (void)MB_IN32(bay, KEYLARGO_MBCR);
211
                udelay(5);
212
                bay->cached_gpio = new_gpio;
213
        }
214
        return (MB_IN32(bay, KEYLARGO_MBCR) >> 4) & 7;
215
}
216
 
217
/*
218
 * Functions for powering up/down the bay, puts the bay device
219
 * into reset state as well
220
 */
221
 
222
static void __pmac
223
ohare_mb_power(struct media_bay_info* bay, int on_off)
224
{
225
        if (on_off) {
226
                /* Power up device, assert it's reset line */
227
                MB_BIC(bay, OHARE_FCR, OH_BAY_RESET_N);
228
                MB_BIC(bay, OHARE_FCR, OH_BAY_POWER_N);
229
        } else {
230
                /* Disable all devices */
231
                MB_BIC(bay, OHARE_FCR, OH_BAY_DEV_MASK);
232
                MB_BIC(bay, OHARE_FCR, OH_FLOPPY_ENABLE);
233
                /* Cut power from bay, release reset line */
234
                MB_BIS(bay, OHARE_FCR, OH_BAY_POWER_N);
235
                MB_BIS(bay, OHARE_FCR, OH_BAY_RESET_N);
236
                MB_BIS(bay, OHARE_FCR, OH_IDE1_RESET_N);
237
        }
238
        MB_BIC(bay, OHARE_MBCR, 0x00000F00);
239
}
240
 
241
static void __pmac
242
heathrow_mb_power(struct media_bay_info* bay, int on_off)
243
{
244
        if (on_off) {
245
                /* Power up device, assert it's reset line */
246
                MB_BIC(bay, HEATHROW_FCR, HRW_BAY_RESET_N);
247
                MB_BIC(bay, HEATHROW_FCR, HRW_BAY_POWER_N);
248
        } else {
249
                /* Disable all devices */
250
                MB_BIC(bay, HEATHROW_FCR, HRW_BAY_DEV_MASK);
251
                MB_BIC(bay, HEATHROW_FCR, HRW_SWIM_ENABLE);
252
                /* Cut power from bay, release reset line */
253
                MB_BIS(bay, HEATHROW_FCR, HRW_BAY_POWER_N);
254
                MB_BIS(bay, HEATHROW_FCR, HRW_BAY_RESET_N);
255
                MB_BIS(bay, HEATHROW_FCR, HRW_IDE1_RESET_N);
256
        }
257
        MB_BIC(bay, HEATHROW_MBCR, 0x00000F00);
258
}
259
 
260
static void __pmac
261
keylargo_mb_power(struct media_bay_info* bay, int on_off)
262
{
263
        if (on_off) {
264
                /* Power up device, assert it's reset line */
265
                MB_BIC(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_RESET);
266
                MB_BIC(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_POWER);
267
        } else {
268
                /* Disable all devices */
269
                MB_BIC(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK);
270
                MB_BIC(bay, KEYLARGO_FCR1, KL1_EIDE0_ENABLE);
271
                /* Cut power from bay, release reset line */
272
                MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_POWER);
273
                MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_RESET);
274
                MB_BIS(bay, KEYLARGO_FCR1, KL1_EIDE0_RESET_N);
275
        }
276
        MB_BIC(bay, KEYLARGO_MBCR, 0x0000000F);
277
}
278
 
279
/*
280
 * Functions for configuring the media bay for a given type of device,
281
 * enable the related busses
282
 */
283
 
284
static int __pmac
285
ohare_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
286
{
287
        switch(device_id) {
288
                case MB_FD:
289
                case MB_FD1:
290
                        MB_BIS(bay, OHARE_FCR, OH_BAY_FLOPPY_ENABLE);
291
                        MB_BIS(bay, OHARE_FCR, OH_FLOPPY_ENABLE);
292
                        return 0;
293
                case MB_CD:
294
                        MB_BIC(bay, OHARE_FCR, OH_IDE1_RESET_N);
295
                        MB_BIS(bay, OHARE_FCR, OH_BAY_IDE_ENABLE);
296
                        return 0;
297
                case MB_PCI:
298
                        MB_BIS(bay, OHARE_FCR, OH_BAY_PCI_ENABLE);
299
                        return 0;
300
        }
301
        return -ENODEV;
302
}
303
 
304
static int __pmac
305
heathrow_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
306
{
307
        switch(device_id) {
308
                case MB_FD:
309
                case MB_FD1:
310
                        MB_BIS(bay, HEATHROW_FCR, HRW_BAY_FLOPPY_ENABLE);
311
                        MB_BIS(bay, HEATHROW_FCR, HRW_SWIM_ENABLE);
312
                        return 0;
313
                case MB_CD:
314
                        MB_BIC(bay, HEATHROW_FCR, HRW_IDE1_RESET_N);
315
                        MB_BIS(bay, HEATHROW_FCR, HRW_BAY_IDE_ENABLE);
316
                        return 0;
317
                case MB_PCI:
318
                        MB_BIS(bay, HEATHROW_FCR, HRW_BAY_PCI_ENABLE);
319
                        return 0;
320
        }
321
        return -ENODEV;
322
}
323
 
324
static int __pmac
325
keylargo_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
326
{
327
        switch(device_id) {
328
                case MB_CD:
329
                        MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE);
330
                        MB_BIC(bay, KEYLARGO_FCR1, KL1_EIDE0_RESET_N);
331
                        MB_BIS(bay, KEYLARGO_FCR1, KL1_EIDE0_ENABLE);
332
                        return 0;
333
                case MB_PCI:
334
                        MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_PCI_ENABLE);
335
                        return 0;
336
                case MB_SOUND:
337
                        MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_SOUND_ENABLE);
338
                        return 0;
339
        }
340
        return -ENODEV;
341
}
342
 
343
/*
344
 * Functions for tweaking resets
345
 */
346
 
347
static void __pmac
348
ohare_mb_un_reset(struct media_bay_info* bay)
349
{
350
        MB_BIS(bay, OHARE_FCR, OH_BAY_RESET_N);
351
}
352
 
353
static void __pmac
354
heathrow_mb_un_reset(struct media_bay_info* bay)
355
{
356
        MB_BIS(bay, HEATHROW_FCR, HRW_BAY_RESET_N);
357
}
358
 
359
static void __pmac
360
keylargo_mb_un_reset(struct media_bay_info* bay)
361
{
362
        MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_RESET);
363
}
364
 
365
static void __pmac
366
ohare_mb_un_reset_ide(struct media_bay_info* bay)
367
{
368
        MB_BIS(bay, OHARE_FCR, OH_IDE1_RESET_N);
369
}
370
 
371
static void __pmac
372
heathrow_mb_un_reset_ide(struct media_bay_info* bay)
373
{
374
        MB_BIS(bay, HEATHROW_FCR, HRW_IDE1_RESET_N);
375
}
376
 
377
static void __pmac
378
keylargo_mb_un_reset_ide(struct media_bay_info* bay)
379
{
380
        MB_BIS(bay, KEYLARGO_FCR1, KL1_EIDE0_RESET_N);
381
}
382
 
383
static inline void __pmac
384
set_mb_power(struct media_bay_info* bay, int onoff)
385
{
386
        /* Power up up and assert the bay reset line */
387
        if (onoff) {
388
                bay->ops->power(bay, 1);
389
                bay->state = mb_powering_up;
390
                MBDBG("mediabay%d: powering up\n", bay->index);
391
        } else {
392
                /* Make sure everything is powered down & disabled */
393
                bay->ops->power(bay, 0);
394
                bay->state = mb_powering_down;
395
                MBDBG("mediabay%d: powering down\n", bay->index);
396
        }
397
        bay->timer = MS_TO_HZ(MB_POWER_DELAY);
398
}
399
 
400
static void __pmac
401
poll_media_bay(struct media_bay_info* bay)
402
{
403
        int id = bay->ops->content(bay);
404
 
405
        if (id == bay->last_value) {
406
            if (id != bay->content_id
407
                && ++bay->value_count >= MS_TO_HZ(MB_STABLE_DELAY)) {
408
                /* If the device type changes without going thru "MB_NO", we force
409
                   a pass by "MB_NO" to make sure things are properly reset */
410
                if ((id != MB_NO) && (bay->content_id != MB_NO)) {
411
                    id = MB_NO;
412
                    MBDBG("mediabay%d: forcing MB_NO\n", bay->index);
413
                }
414
                MBDBG("mediabay%d: switching to %d\n", bay->index, id);
415
                set_mb_power(bay, id != MB_NO);
416
                bay->content_id = id;
417
                if (id == MB_NO) {
418
#ifdef CONFIG_BLK_DEV_IDE
419
                    bay->cd_retry = 0;
420
#endif
421
                    printk(KERN_INFO "media bay %d is empty\n", bay->index);
422
                }
423
            }
424
        } else {
425
                bay->last_value = id;
426
                bay->value_count = 0;
427
        }
428
}
429
 
430
int __pmac
431
check_media_bay(struct device_node *which_bay, int what)
432
{
433
#ifdef CONFIG_BLK_DEV_IDE
434
        int     i;
435
 
436
        for (i=0; i<media_bay_count; i++)
437
                if (which_bay == media_bays[i].dev_node)
438
                {
439
                        if ((what == media_bays[i].content_id) && media_bays[i].state == mb_up)
440
                                return 0;
441
                        media_bays[i].cd_index = -1;
442
                        return -EINVAL;
443
                }
444
#endif /* CONFIG_BLK_DEV_IDE */
445
        return -ENODEV;
446
}
447
 
448
int __pmac
449
check_media_bay_by_base(unsigned long base, int what)
450
{
451
#ifdef CONFIG_BLK_DEV_IDE
452
        int     i;
453
 
454
        for (i=0; i<media_bay_count; i++)
455
                if (base == media_bays[i].cd_base)
456
                {
457
                        if ((what == media_bays[i].content_id) && media_bays[i].state == mb_up)
458
                                return 0;
459
                        media_bays[i].cd_index = -1;
460
                        return -EINVAL;
461
                }
462
#endif
463
 
464
        return -ENODEV;
465
}
466
 
467
int __pmac
468
media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
469
        int irq, int index)
470
{
471
#ifdef CONFIG_BLK_DEV_IDE
472
        int     i;
473
 
474
        for (i=0; i<media_bay_count; i++)
475
                if (which_bay == media_bays[i].dev_node)
476
                {
477
                        int timeout = 5000;
478
 
479
                        media_bays[i].cd_base   = base;
480
                        media_bays[i].cd_irq    = irq;
481
 
482
                        if ((MB_CD != media_bays[i].content_id) || media_bays[i].state != mb_up)
483
                                return 0;
484
 
485
                        printk(KERN_DEBUG "Registered ide %d for media bay %d\n", index, i);
486
                        do {
487
                                if (MB_IDE_READY(i)) {
488
                                        media_bays[i].cd_index  = index;
489
                                        return 0;
490
                                }
491
                                mdelay(1);
492
                        } while(--timeout);
493
                        printk(KERN_DEBUG "Timeount waiting IDE in bay %d\n", i);
494
                        return -ENODEV;
495
                }
496
#endif
497
 
498
        return -ENODEV;
499
}
500
 
501
static void __pmac
502
media_bay_step(int i)
503
{
504
        struct media_bay_info* bay = &media_bays[i];
505
 
506
        /* We don't poll when powering down */
507
        if (bay->state != mb_powering_down)
508
            poll_media_bay(bay);
509
 
510
        /* If timer expired or polling IDE busy, run state machine */
511
        if ((bay->state != mb_ide_waiting) && (bay->timer != 0) && ((--bay->timer) != 0))
512
            return;
513
 
514
        switch(bay->state) {
515
        case mb_powering_up:
516
                if (bay->ops->setup_bus(bay, bay->last_value) < 0) {
517
                        MBDBG("mediabay%d: device not supported (kind:%d)\n", i, bay->content_id);
518
                        set_mb_power(bay, 0);
519
                        break;
520
                }
521
                bay->timer = MS_TO_HZ(MB_RESET_DELAY);
522
                bay->state = mb_enabling_bay;
523
                MBDBG("mediabay%d: enabling (kind:%d)\n", i, bay->content_id);
524
                break;
525
        case mb_enabling_bay:
526
                bay->ops->un_reset(bay);
527
                bay->timer = MS_TO_HZ(MB_SETUP_DELAY);
528
                bay->state = mb_resetting;
529
                MBDBG("mediabay%d: waiting reset (kind:%d)\n", i, bay->content_id);
530
                break;
531
 
532
        case mb_resetting:
533
                if (bay->content_id != MB_CD) {
534
                        MBDBG("mediabay%d: bay is up (kind:%d)\n", i, bay->content_id);
535
                        bay->state = mb_up;
536
                        break;
537
                }
538
#ifdef CONFIG_BLK_DEV_IDE
539
                MBDBG("mediabay%d: waiting IDE reset (kind:%d)\n", i, bay->content_id);
540
                bay->ops->un_reset_ide(bay);
541
                bay->timer = MS_TO_HZ(MB_IDE_WAIT);
542
                bay->state = mb_ide_resetting;
543
#else
544
                printk(KERN_DEBUG "media-bay %d is ide (not compiled in kernel)\n", i);
545
                set_mb_power(bay, 0);
546
#endif /* CONFIG_BLK_DEV_IDE */
547
                break;
548
 
549
#ifdef CONFIG_BLK_DEV_IDE
550
        case mb_ide_resetting:
551
                bay->timer = MS_TO_HZ(MB_IDE_TIMEOUT);
552
                bay->state = mb_ide_waiting;
553
                MBDBG("mediabay%d: waiting IDE ready (kind:%d)\n", i, bay->content_id);
554
                break;
555
 
556
        case mb_ide_waiting:
557
                if (bay->cd_base == 0) {
558
                        bay->timer = 0;
559
                        bay->state = mb_up;
560
                        MBDBG("mediabay%d: up before IDE init\n", i);
561
                        break;
562
                } else if (MB_IDE_READY(i)) {
563
                        bay->timer = 0;
564
                        bay->state = mb_up;
565
                        if (bay->cd_index < 0) {
566
                                pmu_suspend();
567
                                bay->cd_index = ide_register(bay->cd_base, 0, bay->cd_irq);
568
                                pmu_resume();
569
                        }
570
                        if (bay->cd_index == -1) {
571
                                /* We eventually do a retry */
572
                                bay->cd_retry++;
573
                                printk("IDE register error\n");
574
                                set_mb_power(bay, 0);
575
                        } else {
576
                                printk(KERN_DEBUG "media-bay %d is ide %d\n", i, bay->cd_index);
577
                                MBDBG("mediabay %d IDE ready\n", i);
578
                        }
579
                        break;
580
                } else if (bay->timer > 0)
581
                        bay->timer--;
582
                if (bay->timer == 0) {
583
                        printk("\nIDE Timeout in bay %d !\n", i);
584
                        MBDBG("mediabay%d: nIDE Timeout !\n", i);
585
                        set_mb_power(bay, 0);
586
                }
587
                break;
588
#endif /* CONFIG_BLK_DEV_IDE */
589
 
590
        case mb_powering_down:
591
                bay->state = mb_empty;
592
#ifdef CONFIG_BLK_DEV_IDE
593
                if (bay->cd_index >= 0) {
594
                        printk(KERN_DEBUG "Unregistering mb %d ide, index:%d\n", i,
595
                               bay->cd_index);
596
                        ide_unregister(bay->cd_index);
597
                        bay->cd_index = -1;
598
                }
599
                if (bay->cd_retry) {
600
                        if (bay->cd_retry > MAX_CD_RETRIES) {
601
                                /* Should add an error sound (sort of beep in dmasound) */
602
                                printk("\nmedia-bay %d, IDE device badly inserted or unrecognised\n", i);
603
                        } else {
604
                                /* Force a new power down/up sequence */
605
                                bay->content_id = MB_NO;
606
                        }
607
                }
608
#endif /* CONFIG_BLK_DEV_IDE */    
609
                MBDBG("mediabay%d: end of power down\n", i);
610
                break;
611
        }
612
}
613
 
614
/*
615
 * This procedure runs as a kernel thread to poll the media bay
616
 * once each tick and register and unregister the IDE interface
617
 * with the IDE driver.  It needs to be a thread because
618
 * ide_register can't be called from interrupt context.
619
 */
620
static int __pmac
621
media_bay_task(void *x)
622
{
623
        int     i;
624
 
625
        strcpy(current->comm, "media-bay");
626
#ifdef MB_IGNORE_SIGNALS
627
        sigfillset(&current->blocked);
628
#endif
629
 
630
        for (;;) {
631
                for (i = 0; i < media_bay_count; ++i)
632
                        media_bay_step(i);
633
 
634
                current->state = TASK_INTERRUPTIBLE;
635
                schedule_timeout(1);
636
                if (signal_pending(current))
637
                        return 0;
638
        }
639
}
640
 
641
#ifdef MB_USE_INTERRUPTS
642
static void __pmac
643
media_bay_intr(int irq, void *devid, struct pt_regs *regs)
644
{
645
}
646
#endif
647
 
648
#ifdef CONFIG_PMAC_PBOOK
649
/*
650
 * notify clients before sleep and reset bus afterwards
651
 */
652
int __pmac
653
mb_notify_sleep(struct pmu_sleep_notifier *self, int when)
654
{
655
        struct media_bay_info* bay;
656
        int i;
657
 
658
        switch (when) {
659
        case PBOOK_SLEEP_REQUEST:
660
        case PBOOK_SLEEP_REJECT:
661
                break;
662
 
663
        case PBOOK_SLEEP_NOW:
664
                for (i=0; i<media_bay_count; i++) {
665
                        bay = &media_bays[i];
666
                        set_mb_power(bay, 0);
667
                        mdelay(10);
668
                }
669
                break;
670
        case PBOOK_WAKE:
671
                for (i=0; i<media_bay_count; i++) {
672
                        bay = &media_bays[i];
673
                        /* We re-enable the bay using it's previous content
674
                           only if it did not change. Note those bozo timings,
675
                           they seem to help the 3400 get it right.
676
                         */
677
                        /* Force MB power to 0 */
678
                        set_mb_power(bay, 0);
679
                        mdelay(MB_POWER_DELAY);
680
                        if (bay->ops->content(bay) != bay->content_id)
681
                                continue;
682
                        set_mb_power(bay, 1);
683
                        bay->last_value = bay->content_id;
684
                        bay->value_count = MS_TO_HZ(MB_STABLE_DELAY);
685
                        bay->timer = MS_TO_HZ(MB_POWER_DELAY);
686
#ifdef CONFIG_BLK_DEV_IDE
687
                        bay->cd_retry = 0;
688
#endif
689
                        do {
690
                                mdelay(1000/HZ);
691
                                media_bay_step(i);
692
                        } while((media_bays[i].state != mb_empty) &&
693
                                (media_bays[i].state != mb_up));
694
                }
695
                break;
696
        }
697
        return PBOOK_SLEEP_OK;
698
}
699
#endif /* CONFIG_PMAC_PBOOK */
700
 
701
 
702
/* Definitions of "ops" structures.
703
 */
704
static struct mb_ops ohare_mb_ops __pmacdata = {
705
        name:           "Ohare",
706
        content:        ohare_mb_content,
707
        power:          ohare_mb_power,
708
        setup_bus:      ohare_mb_setup_bus,
709
        un_reset:       ohare_mb_un_reset,
710
        un_reset_ide:   ohare_mb_un_reset_ide,
711
};
712
 
713
static struct mb_ops heathrow_mb_ops __pmacdata = {
714
        name:           "Heathrow",
715
        content:        heathrow_mb_content,
716
        power:          heathrow_mb_power,
717
        setup_bus:      heathrow_mb_setup_bus,
718
        un_reset:       heathrow_mb_un_reset,
719
        un_reset_ide:   heathrow_mb_un_reset_ide,
720
};
721
 
722
static struct mb_ops keylargo_mb_ops __pmacdata = {
723
        name:           "KeyLargo",
724
        content:        keylargo_mb_content,
725
        power:          keylargo_mb_power,
726
        setup_bus:      keylargo_mb_setup_bus,
727
        un_reset:       keylargo_mb_un_reset,
728
        un_reset_ide:   keylargo_mb_un_reset_ide,
729
};
730
 
731
/*
732
 * It seems that the bit for the media-bay interrupt in the IRQ_LEVEL
733
 * register is always set when there is something in the media bay.
734
 * This causes problems for the interrupt code if we attach an interrupt
735
 * handler to the media-bay interrupt, because it tends to go into
736
 * an infinite loop calling the media bay interrupt handler.
737
 * Therefore we do it all by polling the media bay once each tick.
738
 */
739
 
740
void __pmac
741
media_bay_init(void)
742
{
743
        struct device_node *np;
744
        int             n,i;
745
 
746
        for (i=0; i<MAX_BAYS; i++) {
747
                memset((char *)&media_bays[i], 0, sizeof(struct media_bay_info));
748
                media_bays[i].content_id        = -1;
749
#ifdef CONFIG_BLK_DEV_IDE
750
                media_bays[i].cd_index          = -1;
751
#endif
752
        }
753
 
754
        np = find_devices("media-bay");
755
        n = 0;
756
        while(np && (n<MAX_BAYS)) {
757
                struct media_bay_info* bay = &media_bays[n];
758
                if (!np->parent || np->n_addrs == 0 || !request_OF_resource(np, 0, NULL)) {
759
                        np = np->next;
760
                        printk(KERN_ERR "mediabay: Can't request IO resource !\n");
761
                        continue;
762
                }
763
                bay->mb_type = mb_ohare;
764
 
765
                if (device_is_compatible(np, "keylargo-media-bay")) {
766
                        bay->mb_type = mb_keylargo;
767
                        bay->ops = &keylargo_mb_ops;
768
                } else if (device_is_compatible(np, "heathrow-media-bay")) {
769
                        bay->mb_type = mb_heathrow;
770
                        bay->ops = &heathrow_mb_ops;
771
                } else if (device_is_compatible(np, "ohare-media-bay")) {
772
                        bay->mb_type = mb_ohare;
773
                        bay->ops = &ohare_mb_ops;
774
                } else {
775
                        printk(KERN_ERR "media-bay: Unknown bay type !\n");
776
                        np = np->next;
777
                        continue;
778
                }
779
                bay->base = (volatile u32*)ioremap(np->parent->addrs[0].address, 0x1000);
780
 
781
                /* Enable probe logic on keylargo */
782
                if (bay->mb_type == mb_keylargo)
783
                        MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_ENABLE);
784
#ifdef MB_USE_INTERRUPTS
785
                if (np->n_intrs == 0) {
786
                        printk(KERN_ERR "media-bay %d has no irq\n",n);
787
                        np = np->next;
788
                        continue;
789
                }
790
 
791
                if (request_irq(np->intrs[0].line, media_bay_intr, 0, "Media bay", (void *)n)) {
792
                        printk(KERN_ERR "Couldn't get IRQ %d for media bay %d\n",
793
                                np->intrs[0].line, n);
794
                        np = np->next;
795
                        continue;
796
                }
797
#endif  
798
                media_bay_count++;
799
 
800
                printk(KERN_INFO "mediabay%d: Registered %s media-bay\n", n, bay->ops->name);
801
                bay->dev_node = np;
802
                bay->index = n;
803
 
804
                /* Force an immediate detect */
805
                set_mb_power(bay, 0);
806
                mdelay(MB_POWER_DELAY);
807
                bay->content_id = MB_NO;
808
                bay->last_value = bay->ops->content(bay);
809
                bay->value_count = MS_TO_HZ(MB_STABLE_DELAY);
810
                bay->state = mb_empty;
811
                do {
812
                        mdelay(1000/HZ);
813
                        media_bay_step(n);
814
                } while((bay->state != mb_empty) &&
815
                        (bay->state != mb_up));
816
 
817
                n++;
818
                np=np->next;
819
        }
820
 
821
        if (media_bay_count)
822
        {
823
#ifdef CONFIG_PMAC_PBOOK
824
                pmu_register_sleep_notifier(&mb_sleep_notifier);
825
#endif /* CONFIG_PMAC_PBOOK */
826
 
827
                if (kernel_thread(media_bay_task, NULL,
828
                              CLONE_FS | CLONE_FILES | CLONE_SIGHAND) < 0)
829
                        printk(KERN_ERR "media-bay: Cannot create polling thread !\n");
830
        }
831
}
832
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.