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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [macintosh/] [mediabay.c] - Blame information for rev 62

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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