Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / macintosh / mediabay.c
index 12132c0..53c1c79 100644 (file)
@@ -45,7 +45,7 @@
 #endif
 
 #define MB_FCR32(bay, r)       ((bay)->base + ((r) >> 2))
-#define MB_FCR8(bay, r)                (((volatile u8*)((bay)->base)) + (r))
+#define MB_FCR8(bay, r)                (((volatile u8 __iomem *)((bay)->base)) + (r))
 
 #define MB_IN32(bay,r)         (in_le32(MB_FCR32(bay,r)))
 #define MB_OUT32(bay,r,v)      (out_le32(MB_FCR32(bay,r), (v)))
@@ -67,7 +67,7 @@ struct mb_ops {
 };
 
 struct media_bay_info {
-       volatile u32*                   base;
+       u32 __iomem                     *base;
        int                             content_id;
        int                             state;
        int                             last_value;
@@ -80,7 +80,7 @@ struct media_bay_info {
        int                             sleeping;
        struct semaphore                lock;
 #ifdef CONFIG_BLK_DEV_IDE
-       unsigned long                   cd_base;
+       void __iomem                    *cd_base;
        int                             cd_index;
        int                             cd_irq;
        int                             cd_retry;
@@ -98,11 +98,6 @@ int media_bay_count = 0;
 #define MB_IDE_READY(i)        ((readb(media_bays[i].cd_base + 0x70) & 0x80) == 0)
 #endif
 
-/* Note: All delays are not in milliseconds and converted to HZ relative
- * values by the macro below
- */
-#define MS_TO_HZ(ms)   ((ms * HZ + 999) / 1000)
-
 /*
  * Wait that number of ms between each step in normal polling mode
  */
@@ -172,19 +167,19 @@ enum {
  * Functions for polling content of media bay
  */
  
-static u8 __pmac
+static u8
 ohare_mb_content(struct media_bay_info *bay)
 {
        return (MB_IN32(bay, OHARE_MBCR) >> 12) & 7;
 }
 
-static u8 __pmac
+static u8
 heathrow_mb_content(struct media_bay_info *bay)
 {
        return (MB_IN32(bay, HEATHROW_MBCR) >> 12) & 7;
 }
 
-static u8 __pmac
+static u8
 keylargo_mb_content(struct media_bay_info *bay)
 {
        int new_gpio;
@@ -210,7 +205,7 @@ keylargo_mb_content(struct media_bay_info *bay)
  * into reset state as well
  */
 
-static void __pmac
+static void
 ohare_mb_power(struct media_bay_info* bay, int on_off)
 {
        if (on_off) {
@@ -229,7 +224,7 @@ ohare_mb_power(struct media_bay_info* bay, int on_off)
        MB_BIC(bay, OHARE_MBCR, 0x00000F00);
 }
 
-static void __pmac
+static void
 heathrow_mb_power(struct media_bay_info* bay, int on_off)
 {
        if (on_off) {
@@ -248,7 +243,7 @@ heathrow_mb_power(struct media_bay_info* bay, int on_off)
        MB_BIC(bay, HEATHROW_MBCR, 0x00000F00);
 }
 
-static void __pmac
+static void
 keylargo_mb_power(struct media_bay_info* bay, int on_off)
 {
        if (on_off) {
@@ -272,7 +267,7 @@ keylargo_mb_power(struct media_bay_info* bay, int on_off)
  * enable the related busses
  */
 
-static int __pmac
+static int
 ohare_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
 {
        switch(device_id) {
@@ -292,7 +287,7 @@ ohare_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
        return -ENODEV;
 }
 
-static int __pmac
+static int
 heathrow_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
 {
        switch(device_id) {
@@ -312,7 +307,7 @@ heathrow_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
        return -ENODEV;
 }
 
-static int __pmac
+static int
 keylargo_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
 {
        switch(device_id) {
@@ -335,43 +330,43 @@ keylargo_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
  * Functions for tweaking resets
  */
 
-static void __pmac
+static void
 ohare_mb_un_reset(struct media_bay_info* bay)
 {
        MB_BIS(bay, OHARE_FCR, OH_BAY_RESET_N);
 }
 
-static void __pmac keylargo_mb_init(struct media_bay_info *bay)
+static void keylargo_mb_init(struct media_bay_info *bay)
 {
        MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_ENABLE);
 }
 
-static void __pmac heathrow_mb_un_reset(struct media_bay_info* bay)
+static void heathrow_mb_un_reset(struct media_bay_info* bay)
 {
        MB_BIS(bay, HEATHROW_FCR, HRW_BAY_RESET_N);
 }
 
-static void __pmac keylargo_mb_un_reset(struct media_bay_info* bay)
+static void keylargo_mb_un_reset(struct media_bay_info* bay)
 {
        MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_RESET);
 }
 
-static void __pmac ohare_mb_un_reset_ide(struct media_bay_info* bay)
+static void ohare_mb_un_reset_ide(struct media_bay_info* bay)
 {
        MB_BIS(bay, OHARE_FCR, OH_IDE1_RESET_N);
 }
 
-static void __pmac heathrow_mb_un_reset_ide(struct media_bay_info* bay)
+static void heathrow_mb_un_reset_ide(struct media_bay_info* bay)
 {
        MB_BIS(bay, HEATHROW_FCR, HRW_IDE1_RESET_N);
 }
 
-static void __pmac keylargo_mb_un_reset_ide(struct media_bay_info* bay)
+static void keylargo_mb_un_reset_ide(struct media_bay_info* bay)
 {
        MB_BIS(bay, KEYLARGO_FCR1, KL1_EIDE0_RESET_N);
 }
 
-static inline void __pmac set_mb_power(struct media_bay_info* bay, int onoff)
+static inline void set_mb_power(struct media_bay_info* bay, int onoff)
 {
        /* Power up up and assert the bay reset line */
        if (onoff) {
@@ -384,17 +379,17 @@ static inline void __pmac set_mb_power(struct media_bay_info* bay, int onoff)
                bay->state = mb_powering_down;
                MBDBG("mediabay%d: powering down\n", bay->index);
        }
-       bay->timer = MS_TO_HZ(MB_POWER_DELAY);
+       bay->timer = msecs_to_jiffies(MB_POWER_DELAY);
 }
 
-static void __pmac poll_media_bay(struct media_bay_info* bay)
+static void poll_media_bay(struct media_bay_info* bay)
 {
        int id = bay->ops->content(bay);
 
        if (id == bay->last_value) {
                if (id != bay->content_id) {
-                       bay->value_count += MS_TO_HZ(MB_POLL_DELAY);
-                       if (bay->value_count >= MS_TO_HZ(MB_STABLE_DELAY)) {
+                       bay->value_count += msecs_to_jiffies(MB_POLL_DELAY);
+                       if (bay->value_count >= msecs_to_jiffies(MB_STABLE_DELAY)) {
                                /* If the device type changes without going thru
                                 * "MB_NO", we force a pass by "MB_NO" to make sure
                                 * things are properly reset
@@ -420,7 +415,7 @@ static void __pmac poll_media_bay(struct media_bay_info* bay)
        }
 }
 
-int __pmac check_media_bay(struct device_node *which_bay, int what)
+int check_media_bay(struct device_node *which_bay, int what)
 {
 #ifdef CONFIG_BLK_DEV_IDE
        int     i;
@@ -435,14 +430,15 @@ int __pmac check_media_bay(struct device_node *which_bay, int what)
 #endif /* CONFIG_BLK_DEV_IDE */
        return -ENODEV;
 }
+EXPORT_SYMBOL(check_media_bay);
 
-int __pmac check_media_bay_by_base(unsigned long base, int what)
+int check_media_bay_by_base(unsigned long base, int what)
 {
 #ifdef CONFIG_BLK_DEV_IDE
        int     i;
 
        for (i=0; i<media_bay_count; i++)
-               if (media_bays[i].mdev && base == media_bays[i].cd_base) {
+               if (media_bays[i].mdev && base == (unsigned long) media_bays[i].cd_base) {
                        if ((what == media_bays[i].content_id) && media_bays[i].state == mb_up)
                                return 0;
                        media_bays[i].cd_index = -1;
@@ -453,7 +449,7 @@ int __pmac check_media_bay_by_base(unsigned long base, int what)
        return -ENODEV;
 }
 
-int __pmac media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
+int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
        int irq, int index)
 {
 #ifdef CONFIG_BLK_DEV_IDE
@@ -467,7 +463,7 @@ int __pmac media_bay_set_ide_infos(struct device_node* which_bay, unsigned long
                        
                        down(&bay->lock);
 
-                       bay->cd_base    = base;
+                       bay->cd_base    = (void __iomem *) base;
                        bay->cd_irq     = irq;
 
                        if ((MB_CD != bay->content_id) || bay->state != mb_up) {
@@ -493,7 +489,7 @@ int __pmac media_bay_set_ide_infos(struct device_node* which_bay, unsigned long
        return -ENODEV;
 }
 
-static void __pmac media_bay_step(int i)
+static void media_bay_step(int i)
 {
        struct media_bay_info* bay = &media_bays[i];
 
@@ -503,7 +499,7 @@ static void __pmac media_bay_step(int i)
 
        /* If timer expired or polling IDE busy, run state machine */
        if ((bay->state != mb_ide_waiting) && (bay->timer != 0)) {
-               bay->timer -= MS_TO_HZ(MB_POLL_DELAY);
+               bay->timer -= msecs_to_jiffies(MB_POLL_DELAY);
                if (bay->timer > 0)
                        return;
                bay->timer = 0;
@@ -516,13 +512,13 @@ static void __pmac media_bay_step(int i)
                        set_mb_power(bay, 0);
                        break;
                }
-               bay->timer = MS_TO_HZ(MB_RESET_DELAY);
+               bay->timer = msecs_to_jiffies(MB_RESET_DELAY);
                bay->state = mb_enabling_bay;
                MBDBG("mediabay%d: enabling (kind:%d)\n", i, bay->content_id);
                break;
        case mb_enabling_bay:
                bay->ops->un_reset(bay);
-               bay->timer = MS_TO_HZ(MB_SETUP_DELAY);
+               bay->timer = msecs_to_jiffies(MB_SETUP_DELAY);
                bay->state = mb_resetting;
                MBDBG("mediabay%d: waiting reset (kind:%d)\n", i, bay->content_id);
                break;
@@ -536,7 +532,7 @@ static void __pmac media_bay_step(int i)
 #ifdef CONFIG_BLK_DEV_IDE
                MBDBG("mediabay%d: waiting IDE reset (kind:%d)\n", i, bay->content_id);
                bay->ops->un_reset_ide(bay);
-               bay->timer = MS_TO_HZ(MB_IDE_WAIT);
+               bay->timer = msecs_to_jiffies(MB_IDE_WAIT);
                bay->state = mb_ide_resetting;
 #else
                printk(KERN_DEBUG "media-bay %d is ide (not compiled in kernel)\n", i);
@@ -546,13 +542,13 @@ static void __pmac media_bay_step(int i)
            
 #ifdef CONFIG_BLK_DEV_IDE
        case mb_ide_resetting:
-               bay->timer = MS_TO_HZ(MB_IDE_TIMEOUT);
+               bay->timer = msecs_to_jiffies(MB_IDE_TIMEOUT);
                bay->state = mb_ide_waiting;
                MBDBG("mediabay%d: waiting IDE ready (kind:%d)\n", i, bay->content_id);
                break;
            
        case mb_ide_waiting:
-               if (bay->cd_base == 0) {
+               if (bay->cd_base == NULL) {
                        bay->timer = 0;
                        bay->state = mb_up;
                        MBDBG("mediabay%d: up before IDE init\n", i);
@@ -582,7 +578,7 @@ static void __pmac media_bay_step(int i)
                        }
                        break;
                } else if (bay->timer > 0)
-                       bay->timer -= MS_TO_HZ(MB_POLL_DELAY);
+                       bay->timer -= msecs_to_jiffies(MB_POLL_DELAY);
                if (bay->timer <= 0) {
                        printk("\nIDE Timeout in bay %d !, IDE state is: 0x%02x\n",
                               i, readb(bay->cd_base + 0x70));
@@ -623,7 +619,7 @@ static void __pmac media_bay_step(int i)
  * with the IDE driver.  It needs to be a thread because
  * ide_register can't be called from interrupt context.
  */
-static int __pmac media_bay_task(void *x)
+static int media_bay_task(void *x)
 {
        int     i;
 
@@ -640,18 +636,18 @@ static int __pmac media_bay_task(void *x)
                        up(&media_bays[i].lock);
                }
 
-               current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout(MS_TO_HZ(MB_POLL_DELAY));
+               msleep_interruptible(MB_POLL_DELAY);
                if (signal_pending(current))
                        return 0;
        }
 }
 
-static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_match *match)
+static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_device_id *match)
 {
        struct media_bay_info* bay;
-       volatile u32 *regbase;
+       u32 __iomem *regbase;
        struct device_node *ofnode;
+       unsigned long base;
        int i;
 
        ofnode = mdev->ofdev.node;
@@ -661,9 +657,11 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_ma
        if (macio_request_resources(mdev, "media-bay"))
                return -EBUSY;
        /* Media bay registers are located at the beginning of the
-         * mac-io chip, we get the parent address for now (hrm...)
+         * mac-io chip, for now, we trick and align down the first
+        * resource passed in
          */
-       regbase = (volatile u32 *)ioremap(ofnode->parent->addrs[0].address, 0x100);
+       base = macio_resource_start(mdev, 0) & 0xffff0000u;
+       regbase = (u32 __iomem *)ioremap(base, 0x100);
        if (regbase == NULL) {
                macio_release_resources(mdev);
                return -ENOMEM;
@@ -686,15 +684,13 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_ma
 
        /* Force an immediate detect */
        set_mb_power(bay, 0);
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(MS_TO_HZ(MB_POWER_DELAY));
+       msleep(MB_POWER_DELAY);
        bay->content_id = MB_NO;
        bay->last_value = bay->ops->content(bay);
-       bay->value_count = MS_TO_HZ(MB_STABLE_DELAY);
+       bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY);
        bay->state = mb_empty;
        do {
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(MS_TO_HZ(MB_POLL_DELAY));
+               msleep(MB_POLL_DELAY);
                media_bay_step(i);
        } while((bay->state != mb_empty) &&
                (bay->state != mb_up));
@@ -710,28 +706,27 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_ma
 
 }
 
-static int __pmac media_bay_suspend(struct macio_dev *mdev, u32 state)
+static int media_bay_suspend(struct macio_dev *mdev, pm_message_t state)
 {
        struct media_bay_info   *bay = macio_get_drvdata(mdev);
 
-       if (state != mdev->ofdev.dev.power_state && state >= 2) {
+       if (state.event != mdev->ofdev.dev.power.power_state.event && state.event == PM_EVENT_SUSPEND) {
                down(&bay->lock);
                bay->sleeping = 1;
                set_mb_power(bay, 0);
                up(&bay->lock);
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(MS_TO_HZ(MB_POLL_DELAY));
-               mdev->ofdev.dev.power_state = state;
+               msleep(MB_POLL_DELAY);
+               mdev->ofdev.dev.power.power_state = state;
        }
        return 0;
 }
 
-static int __pmac media_bay_resume(struct macio_dev *mdev)
+static int media_bay_resume(struct macio_dev *mdev)
 {
        struct media_bay_info   *bay = macio_get_drvdata(mdev);
 
-       if (mdev->ofdev.dev.power_state != 0) {
-               mdev->ofdev.dev.power_state = 0;
+       if (mdev->ofdev.dev.power.power_state.event != PM_EVENT_ON) {
+               mdev->ofdev.dev.power.power_state = PMSG_ON;
 
                /* We re-enable the bay using it's previous content
                   only if it did not change. Note those bozo timings,
@@ -740,8 +735,7 @@ static int __pmac media_bay_resume(struct macio_dev *mdev)
                /* Force MB power to 0 */
                down(&bay->lock);
                set_mb_power(bay, 0);
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(MS_TO_HZ(MB_POWER_DELAY));
+               msleep(MB_POWER_DELAY);
                if (bay->ops->content(bay) != bay->content_id) {
                        printk("mediabay%d: content changed during sleep...\n", bay->index);
                        up(&bay->lock);
@@ -749,14 +743,13 @@ static int __pmac media_bay_resume(struct macio_dev *mdev)
                }
                set_mb_power(bay, 1);
                bay->last_value = bay->content_id;
-               bay->value_count = MS_TO_HZ(MB_STABLE_DELAY);
-               bay->timer = MS_TO_HZ(MB_POWER_DELAY);
+               bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY);
+               bay->timer = msecs_to_jiffies(MB_POWER_DELAY);
 #ifdef CONFIG_BLK_DEV_IDE
                bay->cd_retry = 0;
 #endif
                do {
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       schedule_timeout(MS_TO_HZ(MB_POLL_DELAY));
+                       msleep(MB_POLL_DELAY);
                        media_bay_step(bay->index);
                } while((bay->state != mb_empty) &&
                        (bay->state != mb_up));
@@ -769,7 +762,7 @@ static int __pmac media_bay_resume(struct macio_dev *mdev)
 
 /* Definitions of "ops" structures.
  */
-static struct mb_ops ohare_mb_ops __pmacdata = {
+static struct mb_ops ohare_mb_ops = {
        .name           = "Ohare",
        .content        = ohare_mb_content,
        .power          = ohare_mb_power,
@@ -778,7 +771,7 @@ static struct mb_ops ohare_mb_ops __pmacdata = {
        .un_reset_ide   = ohare_mb_un_reset_ide,
 };
 
-static struct mb_ops heathrow_mb_ops __pmacdata = {
+static struct mb_ops heathrow_mb_ops = {
        .name           = "Heathrow",
        .content        = heathrow_mb_content,
        .power          = heathrow_mb_power,
@@ -787,7 +780,7 @@ static struct mb_ops heathrow_mb_ops __pmacdata = {
        .un_reset_ide   = heathrow_mb_un_reset_ide,
 };
 
-static struct mb_ops keylargo_mb_ops __pmacdata = {
+static struct mb_ops keylargo_mb_ops = {
        .name           = "KeyLargo",
        .init           = keylargo_mb_init,
        .content        = keylargo_mb_content,
@@ -806,23 +799,20 @@ static struct mb_ops keylargo_mb_ops __pmacdata = {
  * Therefore we do it all by polling the media bay once each tick.
  */
 
-static struct of_match media_bay_match[] =
+static struct of_device_id media_bay_match[] =
 {
        {
        .name           = "media-bay",
-       .type           = OF_ANY_MATCH,
        .compatible     = "keylargo-media-bay",
        .data           = &keylargo_mb_ops,
        },
        {
        .name           = "media-bay",
-       .type           = OF_ANY_MATCH,
        .compatible     = "heathrow-media-bay",
        .data           = &heathrow_mb_ops,
        },
        {
        .name           = "media-bay",
-       .type           = OF_ANY_MATCH,
        .compatible     = "ohare-media-bay",
        .data           = &ohare_mb_ops,
        },
@@ -849,8 +839,8 @@ static int __init media_bay_init(void)
                media_bays[i].cd_index          = -1;
 #endif
        }
-       if (_machine != _MACH_Pmac)
-               return -ENODEV;
+       if (!machine_is(powermac))
+               return 0;
 
        macio_register_driver(&media_bay_driver);