ide: remove ide_pci_enablebit_t typedef
[safe/jmp/linux-2.6] / drivers / macintosh / mediabay.c
index b8b5a2f..d7e46d3 100644 (file)
  *  as published by the Free Software Foundation; either version
  *  2 of the License, or (at your option) any later version.
  */
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
-#include <linux/hdreg.h>
 #include <linux/stddef.h>
 #include <linux/init.h>
 #include <linux/ide.h>
+#include <linux/kthread.h>
+#include <linux/mutex.h>
 #include <asm/prom.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
@@ -36,7 +36,6 @@
 
 
 #define MB_DEBUG
-#define MB_IGNORE_SIGNALS
 
 #ifdef MB_DEBUG
 #define MBDBG(fmt, arg...)     printk(KERN_INFO fmt , ## arg)
@@ -78,13 +77,16 @@ struct media_bay_info {
        int                             index;
        int                             cached_gpio;
        int                             sleeping;
-       struct semaphore                lock;
-#ifdef CONFIG_BLK_DEV_IDE
+       struct mutex                    lock;
+#ifdef CONFIG_BLK_DEV_IDE_PMAC
+       ide_hwif_t                      *cd_port;
        void __iomem                    *cd_base;
-       int                             cd_index;
        int                             cd_irq;
        int                             cd_retry;
 #endif
+#if defined(CONFIG_BLK_DEV_IDE_PMAC)
+       int                             cd_index;
+#endif
 };
 
 #define MAX_BAYS       2
@@ -92,7 +94,7 @@ struct media_bay_info {
 static struct media_bay_info media_bays[MAX_BAYS];
 int media_bay_count = 0;
 
-#ifdef CONFIG_BLK_DEV_IDE
+#ifdef CONFIG_BLK_DEV_IDE_PMAC
 /* check the busy bit in the media-bay ide interface
    (assumes the media-bay contains an ide device) */
 #define MB_IDE_READY(i)        ((readb(media_bays[i].cd_base + 0x70) & 0x80) == 0)
@@ -167,19 +169,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;
@@ -205,7 +207,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) {
@@ -224,7 +226,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) {
@@ -243,7 +245,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) {
@@ -267,7 +269,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) {
@@ -287,7 +289,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) {
@@ -307,7 +309,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) {
@@ -330,43 +332,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) {
@@ -382,7 +384,7 @@ static inline void __pmac set_mb_power(struct media_bay_info* bay, int onoff)
        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);
 
@@ -402,7 +404,7 @@ static void __pmac poll_media_bay(struct media_bay_info* bay)
                                set_mb_power(bay, id != MB_NO);
                                bay->content_id = id;
                                if (id == MB_NO) {
-#ifdef CONFIG_BLK_DEV_IDE
+#ifdef CONFIG_BLK_DEV_IDE_PMAC
                                        bay->cd_retry = 0;
 #endif
                                        printk(KERN_INFO "media bay %d is empty\n", bay->index);
@@ -415,9 +417,9 @@ static void __pmac poll_media_bay(struct media_bay_info* bay)
        }
 }
 
-int __pmac check_media_bay(struct device_node *which_bay, int what)
+#ifdef CONFIG_BLK_DEV_IDE_PMAC
+int check_media_bay(struct device_node *which_bay, int what)
 {
-#ifdef CONFIG_BLK_DEV_IDE
        int     i;
 
        for (i=0; i<media_bay_count; i++)
@@ -427,14 +429,12 @@ int __pmac check_media_bay(struct device_node *which_bay, int what)
                        media_bays[i].cd_index = -1;
                        return -EINVAL;
                }
-#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++)
@@ -444,52 +444,51 @@ int __pmac check_media_bay_by_base(unsigned long base, int what)
                        media_bays[i].cd_index = -1;
                        return -EINVAL;
                } 
-#endif
-       
+
        return -ENODEV;
 }
 
-int __pmac media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
-       int irq, int index)
+int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
+                           int irq, ide_hwif_t *hwif)
 {
-#ifdef CONFIG_BLK_DEV_IDE
        int     i;
 
        for (i=0; i<media_bay_count; i++) {
                struct media_bay_info* bay = &media_bays[i];
 
                if (bay->mdev && which_bay == bay->mdev->ofdev.node) {
-                       int timeout = 5000;
+                       int timeout = 5000, index = hwif->index;
                        
-                       down(&bay->lock);
+                       mutex_lock(&bay->lock);
 
+                       bay->cd_port    = hwif;
                        bay->cd_base    = (void __iomem *) base;
                        bay->cd_irq     = irq;
 
                        if ((MB_CD != bay->content_id) || bay->state != mb_up) {
-                               up(&bay->lock);
+                               mutex_unlock(&bay->lock);
                                return 0;
                        }
                        printk(KERN_DEBUG "Registered ide%d for media bay %d\n", index, i);
                        do {
                                if (MB_IDE_READY(i)) {
                                        bay->cd_index   = index;
-                                       up(&bay->lock);
+                                       mutex_unlock(&bay->lock);
                                        return 0;
                                }
                                mdelay(1);
                        } while(--timeout);
                        printk(KERN_DEBUG "Timeount waiting IDE in bay %d\n", i);
-                       up(&bay->lock);
+                       mutex_unlock(&bay->lock);
                        return -ENODEV;
                }
        }
-#endif /* CONFIG_BLK_DEV_IDE */
-       
+
        return -ENODEV;
 }
+#endif /* CONFIG_BLK_DEV_IDE_PMAC */
 
-static void __pmac media_bay_step(int i)
+static void media_bay_step(int i)
 {
        struct media_bay_info* bay = &media_bays[i];
 
@@ -522,14 +521,13 @@ static void __pmac media_bay_step(int i)
                bay->state = mb_resetting;
                MBDBG("mediabay%d: waiting reset (kind:%d)\n", i, bay->content_id);
                break;
-           
        case mb_resetting:
                if (bay->content_id != MB_CD) {
                        MBDBG("mediabay%d: bay is up (kind:%d)\n", i, bay->content_id);
                        bay->state = mb_up;
                        break;
                }
-#ifdef CONFIG_BLK_DEV_IDE
+#ifdef CONFIG_BLK_DEV_IDE_PMAC
                MBDBG("mediabay%d: waiting IDE reset (kind:%d)\n", i, bay->content_id);
                bay->ops->un_reset_ide(bay);
                bay->timer = msecs_to_jiffies(MB_IDE_WAIT);
@@ -537,16 +535,14 @@ static void __pmac media_bay_step(int i)
 #else
                printk(KERN_DEBUG "media-bay %d is ide (not compiled in kernel)\n", i);
                set_mb_power(bay, 0);
-#endif /* CONFIG_BLK_DEV_IDE */
+#endif /* CONFIG_BLK_DEV_IDE_PMAC */
                break;
-           
-#ifdef CONFIG_BLK_DEV_IDE
+#ifdef CONFIG_BLK_DEV_IDE_PMAC
        case mb_ide_resetting:
                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 == NULL) {
                        bay->timer = 0;
@@ -557,14 +553,11 @@ static void __pmac media_bay_step(int i)
                        bay->timer = 0;
                        bay->state = mb_up;
                        if (bay->cd_index < 0) {
-                               hw_regs_t hw;
-
                                printk("mediabay %d, registering IDE...\n", i);
                                pmu_suspend();
-                               ide_init_hwif_ports(&hw, (unsigned long) bay->cd_base, (unsigned long) 0, NULL);
-                               hw.irq = bay->cd_irq;
-                               hw.chipset = ide_pmac;
-                               bay->cd_index = ide_register_hw(&hw, NULL);
+                               ide_port_scan(bay->cd_port);
+                               if (bay->cd_port->present)
+                                       bay->cd_index = bay->cd_port->index;
                                pmu_resume();
                        }
                        if (bay->cd_index == -1) {
@@ -587,15 +580,14 @@ static void __pmac media_bay_step(int i)
                        bay->timer = 0;
                }
                break;
-#endif /* CONFIG_BLK_DEV_IDE */
-
+#endif /* CONFIG_BLK_DEV_IDE_PMAC */
        case mb_powering_down:
                bay->state = mb_empty;
-#ifdef CONFIG_BLK_DEV_IDE
+#ifdef CONFIG_BLK_DEV_IDE_PMAC
                if (bay->cd_index >= 0) {
                        printk(KERN_DEBUG "Unregistering mb %d ide, index:%d\n", i,
                               bay->cd_index);
-                       ide_unregister(bay->cd_index);
+                       ide_port_unregister_devices(bay->cd_port);
                        bay->cd_index = -1;
                }
                if (bay->cd_retry) {
@@ -607,7 +599,7 @@ static void __pmac media_bay_step(int i)
                                bay->content_id = MB_NO;
                        }
                }
-#endif /* CONFIG_BLK_DEV_IDE */    
+#endif /* CONFIG_BLK_DEV_IDE_PMAC */
                MBDBG("mediabay%d: end of power down\n", i);
                break;
        }
@@ -619,34 +611,29 @@ 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;
 
-       strcpy(current->comm, "media-bay");
-#ifdef MB_IGNORE_SIGNALS
-       sigfillset(&current->blocked);
-#endif
-
-       for (;;) {
+       while (!kthread_should_stop()) {
                for (i = 0; i < media_bay_count; ++i) {
-                       down(&media_bays[i].lock);
+                       mutex_lock(&media_bays[i].lock);
                        if (!media_bays[i].sleeping)
                                media_bay_step(i);
-                       up(&media_bays[i].lock);
+                       mutex_unlock(&media_bays[i].lock);
                }
 
                msleep_interruptible(MB_POLL_DELAY);
-               if (signal_pending(current))
-                       return 0;
        }
+       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;
        u32 __iomem *regbase;
        struct device_node *ofnode;
+       unsigned long base;
        int i;
 
        ofnode = mdev->ofdev.node;
@@ -656,10 +643,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 = (u32 __iomem *)
-               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;
@@ -672,7 +660,7 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_ma
        bay->index = i;
        bay->ops = match->data;
        bay->sleeping = 0;
-       init_MUTEX(&bay->lock);
+       mutex_init(&bay->lock);
 
        /* Init HW probing */
        if (bay->ops->init)
@@ -698,52 +686,53 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_ma
 
        /* Startup kernel thread */
        if (i == 0)
-               kernel_thread(media_bay_task, NULL, CLONE_KERNEL);
+               kthread_run(media_bay_task, NULL, "media-bay");
 
        return 0;
 
 }
 
-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.power_state && state == PM_SUSPEND_MEM) {
-               down(&bay->lock);
+       if (state.event != mdev->ofdev.dev.power.power_state.event
+           && (state.event & PM_EVENT_SLEEP)) {
+               mutex_lock(&bay->lock);
                bay->sleeping = 1;
                set_mb_power(bay, 0);
-               up(&bay->lock);
+               mutex_unlock(&bay->lock);
                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.power_state != 0) {
-               mdev->ofdev.dev.power.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,
                   they seem to help the 3400 get it right.
                 */
                /* Force MB power to 0 */
-               down(&bay->lock);
+               mutex_lock(&bay->lock);
                set_mb_power(bay, 0);
                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);
+                       mutex_unlock(&bay->lock);
                        return 0;
                }
                set_mb_power(bay, 1);
                bay->last_value = bay->content_id;
                bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY);
                bay->timer = msecs_to_jiffies(MB_POWER_DELAY);
-#ifdef CONFIG_BLK_DEV_IDE
+#ifdef CONFIG_BLK_DEV_IDE_PMAC
                bay->cd_retry = 0;
 #endif
                do {
@@ -752,7 +741,7 @@ static int __pmac media_bay_resume(struct macio_dev *mdev)
                } while((bay->state != mb_empty) &&
                        (bay->state != mb_up));
                bay->sleeping = 0;
-               up(&bay->lock);
+               mutex_unlock(&bay->lock);
        }
        return 0;
 }
@@ -760,7 +749,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,
@@ -769,7 +758,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,
@@ -778,7 +767,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,
@@ -797,23 +786,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,
        },
@@ -836,12 +822,12 @@ static int __init media_bay_init(void)
        for (i=0; i<MAX_BAYS; i++) {
                memset((char *)&media_bays[i], 0, sizeof(struct media_bay_info));
                media_bays[i].content_id        = -1;
-#ifdef CONFIG_BLK_DEV_IDE
+#ifdef CONFIG_BLK_DEV_IDE_PMAC
                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);