Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux-drm-fsl-dcu.git] / drivers / scsi / aacraid / sa.c
index a534549082057972ee2df5e0575b32b139e986fd..8535db068c2f7de3dcd51a824a2ad47064083414 100644 (file)
@@ -46,7 +46,7 @@
 
 #include "aacraid.h"
 
-static irqreturn_t aac_sa_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t aac_sa_intr(int irq, void *dev_id)
 {
        struct aac_dev *dev = dev_id;
        unsigned short intstat, mask;
@@ -66,11 +66,11 @@ static irqreturn_t aac_sa_intr(int irq, void *dev_id, struct pt_regs *regs)
                        sa_writew(dev, DoorbellClrReg_p, PrintfReady); /* clear PrintfReady */
                        sa_writew(dev, DoorbellReg_s, PrintfDone);
                } else if (intstat & DOORBELL_1) {      // dev -> Host Normal Command Ready
-                       aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
                        sa_writew(dev, DoorbellClrReg_p, DOORBELL_1);
+                       aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
                } else if (intstat & DOORBELL_2) {      // dev -> Host Normal Response Ready
-                       aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
                        sa_writew(dev, DoorbellClrReg_p, DOORBELL_2);
+                       aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
                } else if (intstat & DOORBELL_3) {      // dev -> Host Normal Command Not Full
                        sa_writew(dev, DoorbellClrReg_p, DOORBELL_3);
                } else if (intstat & DOORBELL_4) {      // dev -> Host Normal Response Not Full
@@ -91,6 +91,17 @@ static void aac_sa_disable_interrupt (struct aac_dev *dev)
        sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
 }
 
+/**
+ *     aac_sa_enable_interrupt -       enable interrupt
+ *     @dev: Which adapter to enable.
+ */
+
+static void aac_sa_enable_interrupt (struct aac_dev *dev)
+{
+       sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 |
+                               DOORBELL_2 | DOORBELL_3 | DOORBELL_4));
+}
+
 /**
  *     aac_sa_notify_adapter           -       handle adapter notification
  *     @dev:   Adapter that notification is for
@@ -280,6 +291,21 @@ static int aac_sa_check_health(struct aac_dev *dev)
        return 0;
 }
 
+/**
+ *     aac_sa_ioremap
+ *     @size: mapping resize request
+ *
+ */
+static int aac_sa_ioremap(struct aac_dev * dev, u32 size)
+{
+       if (!size) {
+               iounmap(dev->regs.sa);
+               return 0;
+       }
+       dev->base = dev->regs.sa = ioremap(dev->scsi_host_ptr->base, size);
+       return (dev->base == NULL) ? -1 : 0;
+}
+
 /**
  *     aac_sa_init     -       initialize an ARM based AAC card
  *     @dev: device to configure
@@ -299,6 +325,11 @@ int aac_sa_init(struct aac_dev *dev)
        instance = dev->id;
        name     = dev->name;
 
+       if (aac_sa_ioremap(dev, dev->base_size)) {
+               printk(KERN_WARNING "%s: unable to map adapter.\n", name);
+               goto error_iounmap;
+       }
+
        /*
         *      Check to see if the board failed any self tests.
         */
@@ -318,18 +349,13 @@ int aac_sa_init(struct aac_dev *dev)
         *      Wait for the adapter to be up and running. Wait up to 3 minutes.
         */
        while (!(sa_readl(dev, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
-               if (time_after(jiffies, start+180*HZ)) {
+               if (time_after(jiffies, start+startup_timeout*HZ)) {
                        status = sa_readl(dev, Mailbox7);
                        printk(KERN_WARNING "%s%d: adapter kernel failed to start, init status = %lx.\n", 
                                        name, instance, status);
                        goto error_iounmap;
                }
-               schedule_timeout_uninterruptible(1);
-       }
-
-       if (request_irq(dev->scsi_host_ptr->irq, aac_sa_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev ) < 0) {
-               printk(KERN_WARNING "%s%d: Interrupt unavailable.\n", name, instance);
-               goto error_iounmap;
+               msleep(1);
        }
 
        /*
@@ -338,20 +364,30 @@ int aac_sa_init(struct aac_dev *dev)
 
        dev->a_ops.adapter_interrupt = aac_sa_interrupt_adapter;
        dev->a_ops.adapter_disable_int = aac_sa_disable_interrupt;
+       dev->a_ops.adapter_enable_int = aac_sa_enable_interrupt;
        dev->a_ops.adapter_notify = aac_sa_notify_adapter;
        dev->a_ops.adapter_sync_cmd = sa_sync_cmd;
        dev->a_ops.adapter_check_health = aac_sa_check_health;
+       dev->a_ops.adapter_intr = aac_sa_intr;
+       dev->a_ops.adapter_ioremap = aac_sa_ioremap;
 
        /*
         *      First clear out all interrupts.  Then enable the one's that 
         *      we can handle.
         */
-       sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
-       sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 | 
-                               DOORBELL_2 | DOORBELL_3 | DOORBELL_4));
+       aac_adapter_disable_int(dev);
+       aac_adapter_enable_int(dev);
 
        if(aac_init_adapter(dev) == NULL)
                goto error_irq;
+       if (request_irq(dev->scsi_host_ptr->irq, dev->a_ops.adapter_intr,
+                       IRQF_SHARED|IRQF_DISABLED,
+                       "aacraid", (void *)dev ) < 0) {
+               printk(KERN_WARNING "%s%d: Interrupt unavailable.\n",
+                       name, instance);
+               goto error_iounmap;
+       }
+       aac_adapter_enable_int(dev);
 
        /*
         *      Tell the adapter that all is configure, and it can start 
@@ -361,7 +397,7 @@ int aac_sa_init(struct aac_dev *dev)
        return 0;
 
 error_irq:
-       sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
+       aac_sa_disable_interrupt(dev);
        free_irq(dev->scsi_host_ptr->irq, (void *)dev);
 
 error_iounmap: