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