temp revert rk change
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / wm831x-irq.c
index d33c6f28e916e95c54781df15939349dc26962f7..294183b6260b1facff3d26764eb3cea8c6d4b011 100755 (executable)
@@ -25,7 +25,7 @@
 #include <linux/mfd/wm831x/irq.h>
 
 #include <linux/delay.h>
-#include <linux/wakelock.h>
+
 /*
  * Since generic IRQs don't currently support interrupt controllers on
  * interrupt driven buses we don't use genirq but instead provide an
@@ -34,7 +34,6 @@
  * the static irq_data table we use to look up the data for individual
  * interrupts, but hopefully won't last too long.
  */
-#define WM831X_IRQ_TYPE IRQF_TRIGGER_LOW
 
 struct wm831x_irq_data {
        int primary;
@@ -42,12 +41,6 @@ struct wm831x_irq_data {
        int mask;
 };
 
-struct wm831x_handle_irq
-{      
-       int irq;
-       struct list_head        queue;
-};
-
 static struct wm831x_irq_data wm831x_irqs[] = {
        [WM831X_IRQ_TEMP_THW] = {
                .primary = WM831X_TEMP_INT,
@@ -384,7 +377,6 @@ static void wm831x_irq_unmask(unsigned int irq)
        struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq);
 
        wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
-       //printk("%s:irq=%d\n",__FUNCTION__,irq);
 }
 
 static void wm831x_irq_mask(unsigned int irq)
@@ -393,16 +385,6 @@ static void wm831x_irq_mask(unsigned int irq)
        struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq);
 
        wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
-       //printk("%s:irq=%d\n",__FUNCTION__,irq);
-}
-
-static void wm831x_irq_disable(unsigned int irq)
-{
-       struct wm831x *wm831x = get_irq_chip_data(irq);
-       struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq);
-
-       wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
-       //printk("%s:irq=%d\n",__FUNCTION__,irq);
 }
 
 static int wm831x_irq_set_type(unsigned int irq, unsigned int type)
@@ -411,14 +393,15 @@ static int wm831x_irq_set_type(unsigned int irq, unsigned int type)
        int val;
 
        irq = irq - wm831x->irq_base;
-       if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_12) {
+
+       if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) {
                /* Ignore internal-only IRQs */
                if (irq >= 0 && irq < WM831X_NUM_IRQS)
                        return 0;
                else
                        return -EINVAL;
        }
-       //printk("wm831x_irq_set_type:type=%x,irq=%d\n",type,irq);
+
        switch (type) {
        case IRQ_TYPE_EDGE_BOTH:
                val = WM831X_GPN_INT_MODE;
@@ -433,97 +416,29 @@ static int wm831x_irq_set_type(unsigned int irq, unsigned int type)
                return -EINVAL;
        }
 
-       return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + irq - 1,
+       return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + irq,
                               WM831X_GPN_INT_MODE | WM831X_GPN_POL, val);
 }
 
-static int wm831x_irq_set_wake(unsigned irq, unsigned state)
-{      
-       struct wm831x *wm831x = get_irq_chip_data(irq); 
-
-       //only wm831x irq
-       if ((irq > wm831x->irq_base + WM831X_IRQ_TEMP_THW) &&( irq < wm831x->irq_base + WM831X_NUM_IRQS)) 
-       {
-               if(state)
-               wm831x_irq_unmask(irq); 
-               else    
-               wm831x_irq_mask(irq);
-               return 0;
-       }
-       else
-       {
-               printk("%s:irq number err!irq=%d\n",__FUNCTION__,irq);
-               return -EINVAL;
-       }
-
-
-}
-
 static struct irq_chip wm831x_irq_chip = {
        .name = "wm831x",
        .bus_lock = wm831x_irq_lock,
        .bus_sync_unlock = wm831x_irq_sync_unlock,
-       .disable = wm831x_irq_disable,
        .mask = wm831x_irq_mask,
        .unmask = wm831x_irq_unmask,
        .set_type = wm831x_irq_set_type,
-       .set_wake       = wm831x_irq_set_wake,
 };
 
-#if WM831X_IRQ_LIST
-static void wm831x_handle_worker(struct work_struct *work)
-{
-       struct wm831x *wm831x = container_of(work, struct wm831x, handle_work);
-       int irq;
-
-       while (1) {
-               unsigned long flags;
-               struct wm831x_handle_irq *hd = NULL;
-
-               spin_lock_irqsave(&wm831x->work_lock, flags);
-               if (!list_empty(&wm831x->handle_queue)) {
-                       hd = list_first_entry(&wm831x->handle_queue, struct wm831x_handle_irq, queue);
-                       list_del(&hd->queue);
-               }
-               spin_unlock_irqrestore(&wm831x->work_lock, flags);
-
-               if (!hd)        // trans_queue empty
-                       break;
-
-               irq = hd->irq;  //get wm831x intterupt status
-               //printk("%s:irq=%d\n",__FUNCTION__,irq);
-               
-               /*start to handle wm831x intterupt*/
-               handle_nested_irq(wm831x->irq_base + irq);
-       
-               kfree(hd);
-
-       }
-}
-#endif
-/* Main interrupt handling occurs in a workqueue since we need
- * interrupts enabled to interact with the chip. */
-static void wm831x_irq_worker(struct work_struct *work)
+/* The processing of the primary interrupt occurs in a thread so that
+ * we can interact with the device over I2C or SPI. */
+static irqreturn_t wm831x_irq_thread(int irq, void *data)
 {
-       struct wm831x *wm831x = container_of(work, struct wm831x, irq_work);
+       struct wm831x *wm831x = data;
        unsigned int i;
        int primary;
        int status_regs[WM831X_NUM_IRQ_REGS] = { 0 };
        int read[WM831X_NUM_IRQ_REGS] = { 0 };
        int *status;
-       unsigned long flags;
-       struct wm831x_handle_irq *hd;
-       int ret;
-
-#if (WM831X_IRQ_TYPE != IRQF_TRIGGER_LOW)
-       /*mask wm831x irq at first*/
-       ret = wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG,
-                             WM831X_IRQ_IM_MASK, WM831X_IRQ_IM_EANBLE);
-       if (ret < 0) {
-               dev_err(wm831x->dev, "Failed to mask irq: %d\n", ret);
-               goto out;
-       }
-#endif
 
        primary = wm831x_reg_read(wm831x, WM831X_SYSTEM_INTERRUPTS);
        if (primary < 0) {
@@ -531,15 +446,13 @@ static void wm831x_irq_worker(struct work_struct *work)
                        primary);
                goto out;
        }
-       
-       mutex_lock(&wm831x->irq_lock);
 
        for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) {
                int offset = wm831x_irqs[i].reg - 1;
-               
+
                if (!(primary & wm831x_irqs[i].primary))
                        continue;
-               
+
                status = &status_regs[offset];
 
                /* Hopefully there should only be one register to read
@@ -551,7 +464,7 @@ static void wm831x_irq_worker(struct work_struct *work)
                                dev_err(wm831x->dev,
                                        "Failed to read IRQ status: %d\n",
                                        *status);
-                               goto out_lock;
+                               goto out;
                        }
 
                        read[offset] = 1;
@@ -560,84 +473,18 @@ static void wm831x_irq_worker(struct work_struct *work)
                /* Report it if it isn't masked, or forget the status. */
                if ((*status & ~wm831x->irq_masks_cur[offset])
                    & wm831x_irqs[i].mask)
-               {
-                       #if WM831X_IRQ_LIST
-                       /*add intterupt handle on list*/
-                       hd = kzalloc(sizeof(struct wm831x_handle_irq), GFP_KERNEL);
-                       if (!hd)
-                       {
-                               printk("err:%s:ENOMEM\n",__FUNCTION__);
-                               return ;
-                       }
-                       
-                       if(i == WM831X_IRQ_ON)
-                       wake_lock(&wm831x->handle_wake);                //keep wake while handle WM831X_IRQ_ON
-                       hd->irq = i;
-                       spin_lock_irqsave(&wm831x->work_lock, flags);
-                       list_add_tail(&hd->queue, &wm831x->handle_queue);
-                       spin_unlock_irqrestore(&wm831x->work_lock, flags);
-                       queue_work(wm831x->handle_wq, &wm831x->handle_work);
-                       
-                       #else
-                       if(i == WM831X_IRQ_ON)
-                       wake_lock(&wm831x->handle_wake);                //keep wake while handle WM831X_IRQ_ON
                        handle_nested_irq(wm831x->irq_base + i);
-                       
-                       #endif
-               }
-                       
                else
                        *status &= ~wm831x_irqs[i].mask;
        }
-       
-out_lock:      
-       mutex_unlock(&wm831x->irq_lock);
-       
+
 out:
        for (i = 0; i < ARRAY_SIZE(status_regs); i++) {
                if (status_regs[i])
                        wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1 + i,
                                         status_regs[i]);
        }
-       
-#if (WM831X_IRQ_TYPE != IRQF_TRIGGER_LOW)      
-       ret = wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG,
-                             WM831X_IRQ_IM_MASK, 0);
-       if (ret < 0) {
-               dev_err(wm831x->dev, "Failed to open irq: %d\n", ret);
-       }
-#endif
-#if (WM831X_IRQ_TYPE == IRQF_TRIGGER_LOW)
-       enable_irq(wm831x->irq);        
-#endif
-       wake_unlock(&wm831x->irq_wake);
 
-}
-/* The processing of the primary interrupt occurs in a thread so that
- * we can interact with the device over I2C or SPI. */
-static irqreturn_t wm831x_irq_thread(int irq, void *data)
-{
-       struct wm831x *wm831x = data;
-       int msdelay = 0;
-       /* Shut the interrupt to the CPU up and schedule the actual
-        * handler; we can't check that the IRQ is asserted. */
-#if (WM831X_IRQ_TYPE == IRQF_TRIGGER_LOW)
-       disable_irq_nosync(irq);
-#endif
-       wake_lock(&wm831x->irq_wake);
-       if(wm831x->flag_suspend)
-       {
-               spin_lock(&wm831x->flag_lock);
-               wm831x->flag_suspend = 0;
-               spin_unlock(&wm831x->flag_lock);
-               msdelay = 50;   //wait for spi/i2c resume
-               printk("%s:msdelay=%d\n",__FUNCTION__,msdelay);
-       }
-       else
-               msdelay = 0;
-               
-       queue_delayed_work(wm831x->irq_wq, &wm831x->irq_work, msecs_to_jiffies(msdelay));
-       //printk("%s\n",__FUNCTION__);
        return IRQ_HANDLED;
 }
 
@@ -645,7 +492,7 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
 {
        struct wm831x_pdata *pdata = wm831x->dev->platform_data;
        int i, cur_irq, ret;
-       printk( "wm831x_irq_init:irq=%d,%d\n",irq,pdata->irq_base);
+
        mutex_init(&wm831x->irq_lock);
 
        /* Mask the individual interrupt sources */
@@ -668,30 +515,9 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
                return 0;
        }
 
-       wm831x->irq_wq = create_singlethread_workqueue("wm831x-irq");
-       if (!wm831x->irq_wq) {
-               dev_err(wm831x->dev, "Failed to allocate IRQ worker\n");
-               return -ESRCH;
-       }
-
-       
        wm831x->irq = irq;
-       wm831x->flag_suspend = 0;
        wm831x->irq_base = pdata->irq_base;
-       INIT_DELAYED_WORK(&wm831x->irq_work, wm831x_irq_worker);
-       wake_lock_init(&wm831x->irq_wake, WAKE_LOCK_SUSPEND, "wm831x_irq_wake");
-       wake_lock_init(&wm831x->handle_wake, WAKE_LOCK_SUSPEND, "wm831x_handle_wake");
-#if WM831X_IRQ_LIST
-       wm831x->handle_wq = create_rt_workqueue("wm831x_handle_wq");
-       if (!wm831x->handle_wq) {
-               printk("cannot create workqueue\n");
-               return -EBUSY;
-       }
-       INIT_WORK(&wm831x->handle_work, wm831x_handle_worker);
-       INIT_LIST_HEAD(&wm831x->handle_queue);
 
-#endif
-       
        /* Register them with genirq */
        for (cur_irq = wm831x->irq_base;
             cur_irq < ARRAY_SIZE(wm831x_irqs) + wm831x->irq_base;
@@ -709,22 +535,16 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
                set_irq_noprobe(cur_irq);
 #endif
        }
-#if (WM831X_IRQ_TYPE == IRQF_TRIGGER_LOW)
-       ret = request_threaded_irq(wm831x->irq, wm831x_irq_thread, NULL, 
-                                IRQF_TRIGGER_LOW| IRQF_ONESHOT,//IRQF_TRIGGER_FALLING, // 
-                                  "wm831x", wm831x);
-#else
-       ret = request_threaded_irq(wm831x->irq, wm831x_irq_thread, NULL, 
-                                IRQF_TRIGGER_FALLING, //IRQF_TRIGGER_LOW| IRQF_ONESHOT,// 
+
+       ret = request_threaded_irq(irq, NULL, wm831x_irq_thread,
+                                  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
                                   "wm831x", wm831x);
-#endif
        if (ret != 0) {
                dev_err(wm831x->dev, "Failed to request IRQ %d: %d\n",
-                       wm831x->irq, ret);
+                       irq, ret);
                return ret;
        }
 
-       enable_irq_wake(wm831x->irq); // so wm831x irq can wake up system
        /* Enable top level interrupts, we mask at secondary level */
        wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0);