0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/types.h>
0010 #include <linux/errno.h>
0011 #include <linux/kernel.h>
0012 #include <linux/delay.h>
0013 #include <linux/sched.h>
0014 #include <linux/timer.h>
0015 #include <linux/stddef.h>
0016 #include <linux/init.h>
0017 #include <linux/kthread.h>
0018 #include <linux/mutex.h>
0019 #include <linux/pgtable.h>
0020
0021 #include <asm/io.h>
0022 #include <asm/machdep.h>
0023 #include <asm/pmac_feature.h>
0024 #include <asm/mediabay.h>
0025 #include <asm/sections.h>
0026 #include <asm/ohare.h>
0027 #include <asm/heathrow.h>
0028 #include <asm/keylargo.h>
0029 #include <linux/adb.h>
0030 #include <linux/pmu.h>
0031
0032 #define MB_FCR32(bay, r) ((bay)->base + ((r) >> 2))
0033 #define MB_FCR8(bay, r) (((volatile u8 __iomem *)((bay)->base)) + (r))
0034
0035 #define MB_IN32(bay,r) (in_le32(MB_FCR32(bay,r)))
0036 #define MB_OUT32(bay,r,v) (out_le32(MB_FCR32(bay,r), (v)))
0037 #define MB_BIS(bay,r,v) (MB_OUT32((bay), (r), MB_IN32((bay), r) | (v)))
0038 #define MB_BIC(bay,r,v) (MB_OUT32((bay), (r), MB_IN32((bay), r) & ~(v)))
0039 #define MB_IN8(bay,r) (in_8(MB_FCR8(bay,r)))
0040 #define MB_OUT8(bay,r,v) (out_8(MB_FCR8(bay,r), (v)))
0041
0042 struct media_bay_info;
0043
0044 struct mb_ops {
0045 char* name;
0046 void (*init)(struct media_bay_info *bay);
0047 u8 (*content)(struct media_bay_info *bay);
0048 void (*power)(struct media_bay_info *bay, int on_off);
0049 int (*setup_bus)(struct media_bay_info *bay, u8 device_id);
0050 void (*un_reset)(struct media_bay_info *bay);
0051 void (*un_reset_ide)(struct media_bay_info *bay);
0052 };
0053
0054 struct media_bay_info {
0055 u32 __iomem *base;
0056 int content_id;
0057 int state;
0058 int last_value;
0059 int value_count;
0060 int timer;
0061 struct macio_dev *mdev;
0062 const struct mb_ops* ops;
0063 int index;
0064 int cached_gpio;
0065 int sleeping;
0066 int user_lock;
0067 struct mutex lock;
0068 };
0069
0070 #define MAX_BAYS 2
0071
0072 static struct media_bay_info media_bays[MAX_BAYS];
0073 static int media_bay_count = 0;
0074
0075
0076
0077
0078 #define MB_POLL_DELAY 25
0079
0080
0081
0082
0083
0084 #define MB_STABLE_DELAY 100
0085
0086
0087
0088
0089 #define MB_POWER_DELAY 200
0090
0091
0092
0093
0094
0095 #define MB_RESET_DELAY 50
0096
0097
0098
0099
0100
0101
0102 #define MB_SETUP_DELAY 100
0103
0104
0105
0106
0107
0108 #define MB_IDE_WAIT 1000
0109
0110
0111
0112
0113 enum {
0114 mb_empty = 0,
0115 mb_powering_up,
0116 mb_enabling_bay,
0117 mb_resetting,
0118 mb_ide_resetting,
0119 mb_up,
0120 mb_powering_down
0121 };
0122
0123 #define MB_POWER_SOUND 0x08
0124 #define MB_POWER_FLOPPY 0x04
0125 #define MB_POWER_ATA 0x02
0126 #define MB_POWER_PCI 0x01
0127 #define MB_POWER_OFF 0x00
0128
0129
0130
0131
0132
0133 static u8
0134 ohare_mb_content(struct media_bay_info *bay)
0135 {
0136 return (MB_IN32(bay, OHARE_MBCR) >> 12) & 7;
0137 }
0138
0139 static u8
0140 heathrow_mb_content(struct media_bay_info *bay)
0141 {
0142 return (MB_IN32(bay, HEATHROW_MBCR) >> 12) & 7;
0143 }
0144
0145 static u8
0146 keylargo_mb_content(struct media_bay_info *bay)
0147 {
0148 int new_gpio;
0149
0150 new_gpio = MB_IN8(bay, KL_GPIO_MEDIABAY_IRQ) & KEYLARGO_GPIO_INPUT_DATA;
0151 if (new_gpio) {
0152 bay->cached_gpio = new_gpio;
0153 return MB_NO;
0154 } else if (bay->cached_gpio != new_gpio) {
0155 MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_ENABLE);
0156 (void)MB_IN32(bay, KEYLARGO_MBCR);
0157 udelay(5);
0158 MB_BIC(bay, KEYLARGO_MBCR, 0x0000000F);
0159 (void)MB_IN32(bay, KEYLARGO_MBCR);
0160 udelay(5);
0161 bay->cached_gpio = new_gpio;
0162 }
0163 return (MB_IN32(bay, KEYLARGO_MBCR) >> 4) & 7;
0164 }
0165
0166
0167
0168
0169
0170
0171 static void
0172 ohare_mb_power(struct media_bay_info* bay, int on_off)
0173 {
0174 if (on_off) {
0175
0176 MB_BIC(bay, OHARE_FCR, OH_BAY_RESET_N);
0177 MB_BIC(bay, OHARE_FCR, OH_BAY_POWER_N);
0178 } else {
0179
0180 MB_BIC(bay, OHARE_FCR, OH_BAY_DEV_MASK);
0181 MB_BIC(bay, OHARE_FCR, OH_FLOPPY_ENABLE);
0182
0183 MB_BIS(bay, OHARE_FCR, OH_BAY_POWER_N);
0184 MB_BIS(bay, OHARE_FCR, OH_BAY_RESET_N);
0185 MB_BIS(bay, OHARE_FCR, OH_IDE1_RESET_N);
0186 }
0187 MB_BIC(bay, OHARE_MBCR, 0x00000F00);
0188 }
0189
0190 static void
0191 heathrow_mb_power(struct media_bay_info* bay, int on_off)
0192 {
0193 if (on_off) {
0194
0195 MB_BIC(bay, HEATHROW_FCR, HRW_BAY_RESET_N);
0196 MB_BIC(bay, HEATHROW_FCR, HRW_BAY_POWER_N);
0197 } else {
0198
0199 MB_BIC(bay, HEATHROW_FCR, HRW_BAY_DEV_MASK);
0200 MB_BIC(bay, HEATHROW_FCR, HRW_SWIM_ENABLE);
0201
0202 MB_BIS(bay, HEATHROW_FCR, HRW_BAY_POWER_N);
0203 MB_BIS(bay, HEATHROW_FCR, HRW_BAY_RESET_N);
0204 MB_BIS(bay, HEATHROW_FCR, HRW_IDE1_RESET_N);
0205 }
0206 MB_BIC(bay, HEATHROW_MBCR, 0x00000F00);
0207 }
0208
0209 static void
0210 keylargo_mb_power(struct media_bay_info* bay, int on_off)
0211 {
0212 if (on_off) {
0213
0214 MB_BIC(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_RESET);
0215 MB_BIC(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_POWER);
0216 } else {
0217
0218 MB_BIC(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK);
0219 MB_BIC(bay, KEYLARGO_FCR1, KL1_EIDE0_ENABLE);
0220
0221 MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_POWER);
0222 MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_RESET);
0223 MB_BIS(bay, KEYLARGO_FCR1, KL1_EIDE0_RESET_N);
0224 }
0225 MB_BIC(bay, KEYLARGO_MBCR, 0x0000000F);
0226 }
0227
0228
0229
0230
0231
0232
0233 static int
0234 ohare_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
0235 {
0236 switch(device_id) {
0237 case MB_FD:
0238 case MB_FD1:
0239 MB_BIS(bay, OHARE_FCR, OH_BAY_FLOPPY_ENABLE);
0240 MB_BIS(bay, OHARE_FCR, OH_FLOPPY_ENABLE);
0241 return 0;
0242 case MB_CD:
0243 MB_BIC(bay, OHARE_FCR, OH_IDE1_RESET_N);
0244 MB_BIS(bay, OHARE_FCR, OH_BAY_IDE_ENABLE);
0245 return 0;
0246 case MB_PCI:
0247 MB_BIS(bay, OHARE_FCR, OH_BAY_PCI_ENABLE);
0248 return 0;
0249 }
0250 return -ENODEV;
0251 }
0252
0253 static int
0254 heathrow_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
0255 {
0256 switch(device_id) {
0257 case MB_FD:
0258 case MB_FD1:
0259 MB_BIS(bay, HEATHROW_FCR, HRW_BAY_FLOPPY_ENABLE);
0260 MB_BIS(bay, HEATHROW_FCR, HRW_SWIM_ENABLE);
0261 return 0;
0262 case MB_CD:
0263 MB_BIC(bay, HEATHROW_FCR, HRW_IDE1_RESET_N);
0264 MB_BIS(bay, HEATHROW_FCR, HRW_BAY_IDE_ENABLE);
0265 return 0;
0266 case MB_PCI:
0267 MB_BIS(bay, HEATHROW_FCR, HRW_BAY_PCI_ENABLE);
0268 return 0;
0269 }
0270 return -ENODEV;
0271 }
0272
0273 static int
0274 keylargo_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
0275 {
0276 switch(device_id) {
0277 case MB_CD:
0278 MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE);
0279 MB_BIC(bay, KEYLARGO_FCR1, KL1_EIDE0_RESET_N);
0280 MB_BIS(bay, KEYLARGO_FCR1, KL1_EIDE0_ENABLE);
0281 return 0;
0282 case MB_PCI:
0283 MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_PCI_ENABLE);
0284 return 0;
0285 case MB_SOUND:
0286 MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_SOUND_ENABLE);
0287 return 0;
0288 }
0289 return -ENODEV;
0290 }
0291
0292
0293
0294
0295
0296 static void
0297 ohare_mb_un_reset(struct media_bay_info* bay)
0298 {
0299 MB_BIS(bay, OHARE_FCR, OH_BAY_RESET_N);
0300 }
0301
0302 static void keylargo_mb_init(struct media_bay_info *bay)
0303 {
0304 MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_ENABLE);
0305 }
0306
0307 static void heathrow_mb_un_reset(struct media_bay_info* bay)
0308 {
0309 MB_BIS(bay, HEATHROW_FCR, HRW_BAY_RESET_N);
0310 }
0311
0312 static void keylargo_mb_un_reset(struct media_bay_info* bay)
0313 {
0314 MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_RESET);
0315 }
0316
0317 static void ohare_mb_un_reset_ide(struct media_bay_info* bay)
0318 {
0319 MB_BIS(bay, OHARE_FCR, OH_IDE1_RESET_N);
0320 }
0321
0322 static void heathrow_mb_un_reset_ide(struct media_bay_info* bay)
0323 {
0324 MB_BIS(bay, HEATHROW_FCR, HRW_IDE1_RESET_N);
0325 }
0326
0327 static void keylargo_mb_un_reset_ide(struct media_bay_info* bay)
0328 {
0329 MB_BIS(bay, KEYLARGO_FCR1, KL1_EIDE0_RESET_N);
0330 }
0331
0332 static inline void set_mb_power(struct media_bay_info* bay, int onoff)
0333 {
0334
0335 if (onoff) {
0336 bay->ops->power(bay, 1);
0337 bay->state = mb_powering_up;
0338 pr_debug("mediabay%d: powering up\n", bay->index);
0339 } else {
0340
0341 bay->ops->power(bay, 0);
0342 bay->state = mb_powering_down;
0343 pr_debug("mediabay%d: powering down\n", bay->index);
0344 }
0345 bay->timer = msecs_to_jiffies(MB_POWER_DELAY);
0346 }
0347
0348 static void poll_media_bay(struct media_bay_info* bay)
0349 {
0350 int id = bay->ops->content(bay);
0351
0352 static char *mb_content_types[] = {
0353 "a floppy drive",
0354 "a floppy drive",
0355 "an unsupported audio device",
0356 "an ATA device",
0357 "an unsupported PCI device",
0358 "an unknown device",
0359 };
0360
0361 if (id != bay->last_value) {
0362 bay->last_value = id;
0363 bay->value_count = 0;
0364 return;
0365 }
0366 if (id == bay->content_id)
0367 return;
0368
0369 bay->value_count += msecs_to_jiffies(MB_POLL_DELAY);
0370 if (bay->value_count >= msecs_to_jiffies(MB_STABLE_DELAY)) {
0371
0372
0373
0374
0375 if ((id != MB_NO) && (bay->content_id != MB_NO)) {
0376 id = MB_NO;
0377 pr_debug("mediabay%d: forcing MB_NO\n", bay->index);
0378 }
0379 pr_debug("mediabay%d: switching to %d\n", bay->index, id);
0380 set_mb_power(bay, id != MB_NO);
0381 bay->content_id = id;
0382 if (id >= MB_NO || id < 0)
0383 printk(KERN_INFO "mediabay%d: Bay is now empty\n", bay->index);
0384 else
0385 printk(KERN_INFO "mediabay%d: Bay contains %s\n",
0386 bay->index, mb_content_types[id]);
0387 }
0388 }
0389
0390 int check_media_bay(struct macio_dev *baydev)
0391 {
0392 struct media_bay_info* bay;
0393 int id;
0394
0395 if (baydev == NULL)
0396 return MB_NO;
0397
0398
0399
0400
0401
0402
0403 bay = macio_get_drvdata(baydev);
0404 if (bay == NULL)
0405 return MB_NO;
0406 id = bay->content_id;
0407 if (bay->state != mb_up)
0408 return MB_NO;
0409 if (id == MB_FD1)
0410 return MB_FD;
0411 return id;
0412 }
0413 EXPORT_SYMBOL_GPL(check_media_bay);
0414
0415 void lock_media_bay(struct macio_dev *baydev)
0416 {
0417 struct media_bay_info* bay;
0418
0419 if (baydev == NULL)
0420 return;
0421 bay = macio_get_drvdata(baydev);
0422 if (bay == NULL)
0423 return;
0424 mutex_lock(&bay->lock);
0425 bay->user_lock = 1;
0426 }
0427 EXPORT_SYMBOL_GPL(lock_media_bay);
0428
0429 void unlock_media_bay(struct macio_dev *baydev)
0430 {
0431 struct media_bay_info* bay;
0432
0433 if (baydev == NULL)
0434 return;
0435 bay = macio_get_drvdata(baydev);
0436 if (bay == NULL)
0437 return;
0438 if (bay->user_lock) {
0439 bay->user_lock = 0;
0440 mutex_unlock(&bay->lock);
0441 }
0442 }
0443 EXPORT_SYMBOL_GPL(unlock_media_bay);
0444
0445 static int mb_broadcast_hotplug(struct device *dev, void *data)
0446 {
0447 struct media_bay_info* bay = data;
0448 struct macio_dev *mdev;
0449 struct macio_driver *drv;
0450 int state;
0451
0452 if (dev->bus != &macio_bus_type)
0453 return 0;
0454
0455 state = bay->state == mb_up ? bay->content_id : MB_NO;
0456 if (state == MB_FD1)
0457 state = MB_FD;
0458 mdev = to_macio_device(dev);
0459 drv = to_macio_driver(dev->driver);
0460 if (dev->driver && drv->mediabay_event)
0461 drv->mediabay_event(mdev, state);
0462 return 0;
0463 }
0464
0465 static void media_bay_step(int i)
0466 {
0467 struct media_bay_info* bay = &media_bays[i];
0468
0469
0470 if (bay->state != mb_powering_down)
0471 poll_media_bay(bay);
0472
0473
0474 if (bay->timer != 0) {
0475 bay->timer -= msecs_to_jiffies(MB_POLL_DELAY);
0476 if (bay->timer > 0)
0477 return;
0478 bay->timer = 0;
0479 }
0480
0481 switch(bay->state) {
0482 case mb_powering_up:
0483 if (bay->ops->setup_bus(bay, bay->last_value) < 0) {
0484 pr_debug("mediabay%d: device not supported (kind:%d)\n",
0485 i, bay->content_id);
0486 set_mb_power(bay, 0);
0487 break;
0488 }
0489 bay->timer = msecs_to_jiffies(MB_RESET_DELAY);
0490 bay->state = mb_enabling_bay;
0491 pr_debug("mediabay%d: enabling (kind:%d)\n", i, bay->content_id);
0492 break;
0493 case mb_enabling_bay:
0494 bay->ops->un_reset(bay);
0495 bay->timer = msecs_to_jiffies(MB_SETUP_DELAY);
0496 bay->state = mb_resetting;
0497 pr_debug("mediabay%d: releasing bay reset (kind:%d)\n",
0498 i, bay->content_id);
0499 break;
0500 case mb_resetting:
0501 if (bay->content_id != MB_CD) {
0502 pr_debug("mediabay%d: bay is up (kind:%d)\n", i,
0503 bay->content_id);
0504 bay->state = mb_up;
0505 device_for_each_child(&bay->mdev->ofdev.dev,
0506 bay, mb_broadcast_hotplug);
0507 break;
0508 }
0509 pr_debug("mediabay%d: releasing ATA reset (kind:%d)\n",
0510 i, bay->content_id);
0511 bay->ops->un_reset_ide(bay);
0512 bay->timer = msecs_to_jiffies(MB_IDE_WAIT);
0513 bay->state = mb_ide_resetting;
0514 break;
0515
0516 case mb_ide_resetting:
0517 pr_debug("mediabay%d: bay is up (kind:%d)\n", i, bay->content_id);
0518 bay->state = mb_up;
0519 device_for_each_child(&bay->mdev->ofdev.dev,
0520 bay, mb_broadcast_hotplug);
0521 break;
0522
0523 case mb_powering_down:
0524 bay->state = mb_empty;
0525 device_for_each_child(&bay->mdev->ofdev.dev,
0526 bay, mb_broadcast_hotplug);
0527 pr_debug("mediabay%d: end of power down\n", i);
0528 break;
0529 }
0530 }
0531
0532
0533
0534
0535
0536
0537
0538 static int media_bay_task(void *x)
0539 {
0540 int i;
0541
0542 while (!kthread_should_stop()) {
0543 for (i = 0; i < media_bay_count; ++i) {
0544 mutex_lock(&media_bays[i].lock);
0545 if (!media_bays[i].sleeping)
0546 media_bay_step(i);
0547 mutex_unlock(&media_bays[i].lock);
0548 }
0549
0550 msleep_interruptible(MB_POLL_DELAY);
0551 }
0552 return 0;
0553 }
0554
0555 static int media_bay_attach(struct macio_dev *mdev,
0556 const struct of_device_id *match)
0557 {
0558 struct media_bay_info* bay;
0559 u32 __iomem *regbase;
0560 struct device_node *ofnode;
0561 unsigned long base;
0562 int i;
0563
0564 ofnode = mdev->ofdev.dev.of_node;
0565
0566 if (macio_resource_count(mdev) < 1)
0567 return -ENODEV;
0568 if (macio_request_resources(mdev, "media-bay"))
0569 return -EBUSY;
0570
0571
0572
0573
0574 base = macio_resource_start(mdev, 0) & 0xffff0000u;
0575 regbase = (u32 __iomem *)ioremap(base, 0x100);
0576 if (regbase == NULL) {
0577 macio_release_resources(mdev);
0578 return -ENOMEM;
0579 }
0580
0581 i = media_bay_count++;
0582 bay = &media_bays[i];
0583 bay->mdev = mdev;
0584 bay->base = regbase;
0585 bay->index = i;
0586 bay->ops = match->data;
0587 bay->sleeping = 0;
0588 mutex_init(&bay->lock);
0589
0590
0591 if (bay->ops->init)
0592 bay->ops->init(bay);
0593
0594 printk(KERN_INFO "mediabay%d: Registered %s media-bay\n", i, bay->ops->name);
0595
0596
0597 set_mb_power(bay, 0);
0598 msleep(MB_POWER_DELAY);
0599 bay->content_id = MB_NO;
0600 bay->last_value = bay->ops->content(bay);
0601 bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY);
0602 bay->state = mb_empty;
0603
0604
0605 macio_set_drvdata(mdev, bay);
0606
0607
0608 if (i == 0)
0609 kthread_run(media_bay_task, NULL, "media-bay");
0610
0611 return 0;
0612
0613 }
0614
0615 static int media_bay_suspend(struct macio_dev *mdev, pm_message_t state)
0616 {
0617 struct media_bay_info *bay = macio_get_drvdata(mdev);
0618
0619 if (state.event != mdev->ofdev.dev.power.power_state.event
0620 && (state.event & PM_EVENT_SLEEP)) {
0621 mutex_lock(&bay->lock);
0622 bay->sleeping = 1;
0623 set_mb_power(bay, 0);
0624 mutex_unlock(&bay->lock);
0625 msleep(MB_POLL_DELAY);
0626 mdev->ofdev.dev.power.power_state = state;
0627 }
0628 return 0;
0629 }
0630
0631 static int media_bay_resume(struct macio_dev *mdev)
0632 {
0633 struct media_bay_info *bay = macio_get_drvdata(mdev);
0634
0635 if (mdev->ofdev.dev.power.power_state.event != PM_EVENT_ON) {
0636 mdev->ofdev.dev.power.power_state = PMSG_ON;
0637
0638
0639
0640
0641
0642
0643 mutex_lock(&bay->lock);
0644 set_mb_power(bay, 0);
0645 msleep(MB_POWER_DELAY);
0646 if (bay->ops->content(bay) != bay->content_id) {
0647 printk("mediabay%d: Content changed during sleep...\n", bay->index);
0648 mutex_unlock(&bay->lock);
0649 return 0;
0650 }
0651 set_mb_power(bay, 1);
0652 bay->last_value = bay->content_id;
0653 bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY);
0654 bay->timer = msecs_to_jiffies(MB_POWER_DELAY);
0655 do {
0656 msleep(MB_POLL_DELAY);
0657 media_bay_step(bay->index);
0658 } while((bay->state != mb_empty) &&
0659 (bay->state != mb_up));
0660 bay->sleeping = 0;
0661 mutex_unlock(&bay->lock);
0662 }
0663 return 0;
0664 }
0665
0666
0667
0668
0669 static const struct mb_ops ohare_mb_ops = {
0670 .name = "Ohare",
0671 .content = ohare_mb_content,
0672 .power = ohare_mb_power,
0673 .setup_bus = ohare_mb_setup_bus,
0674 .un_reset = ohare_mb_un_reset,
0675 .un_reset_ide = ohare_mb_un_reset_ide,
0676 };
0677
0678 static const struct mb_ops heathrow_mb_ops = {
0679 .name = "Heathrow",
0680 .content = heathrow_mb_content,
0681 .power = heathrow_mb_power,
0682 .setup_bus = heathrow_mb_setup_bus,
0683 .un_reset = heathrow_mb_un_reset,
0684 .un_reset_ide = heathrow_mb_un_reset_ide,
0685 };
0686
0687 static const struct mb_ops keylargo_mb_ops = {
0688 .name = "KeyLargo",
0689 .init = keylargo_mb_init,
0690 .content = keylargo_mb_content,
0691 .power = keylargo_mb_power,
0692 .setup_bus = keylargo_mb_setup_bus,
0693 .un_reset = keylargo_mb_un_reset,
0694 .un_reset_ide = keylargo_mb_un_reset_ide,
0695 };
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706 static const struct of_device_id media_bay_match[] =
0707 {
0708 {
0709 .name = "media-bay",
0710 .compatible = "keylargo-media-bay",
0711 .data = &keylargo_mb_ops,
0712 },
0713 {
0714 .name = "media-bay",
0715 .compatible = "heathrow-media-bay",
0716 .data = &heathrow_mb_ops,
0717 },
0718 {
0719 .name = "media-bay",
0720 .compatible = "ohare-media-bay",
0721 .data = &ohare_mb_ops,
0722 },
0723 {},
0724 };
0725
0726 static struct macio_driver media_bay_driver =
0727 {
0728 .driver = {
0729 .name = "media-bay",
0730 .of_match_table = media_bay_match,
0731 },
0732 .probe = media_bay_attach,
0733 .suspend = media_bay_suspend,
0734 .resume = media_bay_resume
0735 };
0736
0737 static int __init media_bay_init(void)
0738 {
0739 int i;
0740
0741 for (i=0; i<MAX_BAYS; i++) {
0742 memset((char *)&media_bays[i], 0, sizeof(struct media_bay_info));
0743 media_bays[i].content_id = -1;
0744 }
0745 if (!machine_is(powermac))
0746 return 0;
0747
0748 macio_register_driver(&media_bay_driver);
0749
0750 return 0;
0751 }
0752
0753 device_initcall(media_bay_init);