lkml.org 
[lkml]   [2015]   [Nov]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v5 04/11] scsi: ufs: add quirk to fix mishandling utrlclr/utmrlclr
    Date
    From: Seungwon Jeon <essuuj@gmail.com>

    In the right behavior, setting the bit to '0' indicates clear and
    '1' indicates no change. If host contoller handles this the other way,
    UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR can be used.

    Signed-off-by: Seungwon Jeon <essuuj@gmail.com>
    Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
    ---
    drivers/scsi/ufs/ufshcd.c | 21 +++++++++++++++++++--
    drivers/scsi/ufs/ufshcd.h | 5 +++++
    2 files changed, 24 insertions(+), 2 deletions(-)

    diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
    index 587a9c8fbfe9..2b16eb363203 100644
    --- a/drivers/scsi/ufs/ufshcd.c
    +++ b/drivers/scsi/ufs/ufshcd.c
    @@ -356,7 +356,24 @@ static inline void ufshcd_put_tm_slot(struct ufs_hba *hba, int slot)
    */
    static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos)
    {
    - ufshcd_writel(hba, ~(1 << pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR);
    + if (hba->quirks & UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR)
    + ufshcd_writel(hba, (1 << pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR);
    + else
    + ufshcd_writel(hba, ~(1 << pos),
    + REG_UTP_TRANSFER_REQ_LIST_CLEAR);
    +}
    +
    +/**
    + * ufshcd_utmrl_clear - Clear a bit in UTRMLCLR register
    + * @hba: per adapter instance
    + * @pos: position of the bit to be cleared
    + */
    +static inline void ufshcd_utmrl_clear(struct ufs_hba *hba, u32 pos)
    +{
    + if (hba->quirks & UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR)
    + ufshcd_writel(hba, (1 << pos), REG_UTP_TASK_REQ_LIST_CLEAR);
    + else
    + ufshcd_writel(hba, ~(1 << pos), REG_UTP_TASK_REQ_LIST_CLEAR);
    }

    /**
    @@ -3685,7 +3702,7 @@ static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag)
    goto out;

    spin_lock_irqsave(hba->host->host_lock, flags);
    - ufshcd_writel(hba, ~(1 << tag), REG_UTP_TASK_REQ_LIST_CLEAR);
    + ufshcd_utmrl_clear(hba, tag);
    spin_unlock_irqrestore(hba->host->host_lock, flags);

    /* poll for max. 1 sec to clear door bell register by h/w */
    diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
    index 6cd542a803d5..d625d01110b0 100644
    --- a/drivers/scsi/ufs/ufshcd.h
    +++ b/drivers/scsi/ufs/ufshcd.h
    @@ -474,6 +474,11 @@ struct ufs_hba {
    */
    #define UFSHCI_QUIRK_BYTE_ALIGN_UTRD UFS_BIT(6)

    + /*
    + * Cleaer handling for transfer/task request list is just opposite.
    + */
    + #define UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR UFS_BIT(7)
    +
    unsigned int quirks; /* Deviations from standard UFSHCI spec. */

    wait_queue_head_t tm_wq;
    --
    1.7.10.4


    \
     
     \ /
      Last update: 2015-11-09 07:21    [W:2.636 / U:0.252 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site