[SCSI] ufs: amend interrupt configuration
authorSeungwon Jeon <tgih.jun@samsung.com>
Wed, 26 Jun 2013 17:09:27 +0000 (22:39 +0530)
committerJames Bottomley <JBottomley@Parallels.com>
Fri, 28 Jun 2013 20:02:41 +0000 (13:02 -0700)
It makes interrupt setting more flexible especially
for disabling. And wrong bit mask is fixed for ver 1.0.
[17:16] is added for mask.

Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
Tested-by: Maya Erez <merez@codeaurora.org>
Signed-off-by: Santosh Y <santoshsy@gmail.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/ufs/ufshcd.c
drivers/scsi/ufs/ufshcd.h
drivers/scsi/ufs/ufshci.h

index 871c2f0568ae0df7763d21e0c4e2039b64153ee1..1f1e0851855582b04966dc3c5eb3dfdd002d2e89 100644 (file)
 
 #include "ufshcd.h"
 
+#define UFSHCD_ENABLE_INTRS    (UTP_TRANSFER_REQ_COMPL |\
+                                UTP_TASK_REQ_COMPL |\
+                                UFSHCD_ERROR_MASK)
+
 enum {
        UFSHCD_MAX_CHANNEL      = 0,
        UFSHCD_MAX_ID           = 1,
@@ -63,6 +67,20 @@ enum {
        INT_AGGR_CONFIG,
 };
 
+/**
+ * ufshcd_get_intr_mask - Get the interrupt bit mask
+ * @hba - Pointer to adapter instance
+ *
+ * Returns interrupt bit mask per version
+ */
+static inline u32 ufshcd_get_intr_mask(struct ufs_hba *hba)
+{
+       if (hba->ufs_version == UFSHCI_VERSION_10)
+               return INTERRUPT_MASK_ALL_VER_10;
+       else
+               return INTERRUPT_MASK_ALL_VER_11;
+}
+
 /**
  * ufshcd_get_ufs_version - Get the UFS version supported by the HBA
  * @hba - Pointer to adapter instance
@@ -389,25 +407,45 @@ static int ufshcd_map_sg(struct ufshcd_lrb *lrbp)
 }
 
 /**
- * ufshcd_int_config - enable/disable interrupts
+ * ufshcd_enable_intr - enable interrupts
  * @hba: per adapter instance
- * @option: interrupt option
+ * @intrs: interrupt bits
  */
-static void ufshcd_int_config(struct ufs_hba *hba, u32 option)
+static void ufshcd_enable_intr(struct ufs_hba *hba, u32 intrs)
 {
-       switch (option) {
-       case UFSHCD_INT_ENABLE:
-               ufshcd_writel(hba, hba->int_enable_mask, REG_INTERRUPT_ENABLE);
-               break;
-       case UFSHCD_INT_DISABLE:
-               if (hba->ufs_version == UFSHCI_VERSION_10)
-                       ufshcd_writel(hba, INTERRUPT_DISABLE_MASK_10,
-                                     REG_INTERRUPT_ENABLE);
-               else
-                       ufshcd_writel(hba, INTERRUPT_DISABLE_MASK_11,
-                                     REG_INTERRUPT_ENABLE);
-               break;
+       u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
+
+       if (hba->ufs_version == UFSHCI_VERSION_10) {
+               u32 rw;
+               rw = set & INTERRUPT_MASK_RW_VER_10;
+               set = rw | ((set ^ intrs) & intrs);
+       } else {
+               set |= intrs;
+       }
+
+       ufshcd_writel(hba, set, REG_INTERRUPT_ENABLE);
+}
+
+/**
+ * ufshcd_disable_intr - disable interrupts
+ * @hba: per adapter instance
+ * @intrs: interrupt bits
+ */
+static void ufshcd_disable_intr(struct ufs_hba *hba, u32 intrs)
+{
+       u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
+
+       if (hba->ufs_version == UFSHCI_VERSION_10) {
+               u32 rw;
+               rw = (set & INTERRUPT_MASK_RW_VER_10) &
+                       ~(intrs & INTERRUPT_MASK_RW_VER_10);
+               set = rw | ((set & intrs) & ~INTERRUPT_MASK_RW_VER_10);
+
+       } else {
+               set &= ~intrs;
        }
+
+       ufshcd_writel(hba, set, REG_INTERRUPT_ENABLE);
 }
 
 /**
@@ -709,8 +747,7 @@ static int ufshcd_dme_link_startup(struct ufs_hba *hba)
        uic_cmd->argument3 = 0;
 
        /* enable UIC related interrupts */
-       hba->int_enable_mask |= UIC_COMMAND_COMPL;
-       ufshcd_int_config(hba, UFSHCD_INT_ENABLE);
+       ufshcd_enable_intr(hba, UIC_COMMAND_COMPL);
 
        /* sending UIC commands to controller */
        ufshcd_send_uic_command(hba, uic_cmd);
@@ -757,13 +794,7 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba)
        }
 
        /* Enable required interrupts */
-       hba->int_enable_mask |= (UTP_TRANSFER_REQ_COMPL |
-                                UIC_ERROR |
-                                UTP_TASK_REQ_COMPL |
-                                DEVICE_FATAL_ERROR |
-                                CONTROLLER_FATAL_ERROR |
-                                SYSTEM_BUS_FATAL_ERROR);
-       ufshcd_int_config(hba, UFSHCD_INT_ENABLE);
+       ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS);
 
        /* Configure interrupt aggregation */
        ufshcd_config_int_aggr(hba, INT_AGGR_CONFIG);
@@ -1570,7 +1601,7 @@ static void ufshcd_hba_free(struct ufs_hba *hba)
 void ufshcd_remove(struct ufs_hba *hba)
 {
        /* disable interrupts */
-       ufshcd_int_config(hba, UFSHCD_INT_DISABLE);
+       ufshcd_disable_intr(hba, hba->intr_mask);
 
        ufshcd_hba_stop(hba);
        ufshcd_hba_free(hba);
@@ -1628,6 +1659,9 @@ int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle,
        /* Get UFS version supported by the controller */
        hba->ufs_version = ufshcd_get_ufs_version(hba);
 
+       /* Get Interrupt bit mask per version */
+       hba->intr_mask = ufshcd_get_intr_mask(hba);
+
        /* Allocate memory for host memory space */
        err = ufshcd_memory_alloc(hba);
        if (err) {
index 807dd2d740d42f7879b97f754b82889781f97143..4213600b89d6891d5cf7d2f552cf088a7500ad12 100644 (file)
@@ -139,7 +139,7 @@ struct ufshcd_lrb {
  * @ufshcd_tm_wait_queue: wait queue for task management
  * @tm_condition: condition variable for task management
  * @ufshcd_state: UFSHCD states
- * @int_enable_mask: Interrupt Mask Bits
+ * @intr_mask: Interrupt Mask Bits
  * @uic_workq: Work queue for UIC completion handling
  * @feh_workq: Work queue for fatal controller error handling
  * @errors: HBA errors
@@ -176,7 +176,7 @@ struct ufs_hba {
        unsigned long tm_condition;
 
        u32 ufshcd_state;
-       u32 int_enable_mask;
+       u32 intr_mask;
 
        /* Work Queues */
        struct work_struct uic_workq;
index 0c164847a3ef0a775e8e6daac3419a20908ced60..d5c5f1482d7d7c0581a2a95f4f87057557016d18 100644 (file)
@@ -232,10 +232,11 @@ enum {
 /* Interrupt disable masks */
 enum {
        /* Interrupt disable mask for UFSHCI v1.0 */
-       INTERRUPT_DISABLE_MASK_10       = 0xFFFF,
+       INTERRUPT_MASK_ALL_VER_10       = 0x30FFF,
+       INTERRUPT_MASK_RW_VER_10        = 0x30000,
 
        /* Interrupt disable mask for UFSHCI v1.1 */
-       INTERRUPT_DISABLE_MASK_11       = 0x0,
+       INTERRUPT_MASK_ALL_VER_11       = 0x31FFF,
 };
 
 /*