On 9/03/23 07:28, Bao D. Nguyen wrote: > Add supporting functions to handle ufs abort in mcq mode. > > Signed-off-by: Bao D. Nguyen <quic_nguyenb@xxxxxxxxxxx> > --- > drivers/ufs/core/ufs-mcq.c | 181 +++++++++++++++++++++++++++++++++++++++++ > drivers/ufs/core/ufshcd-priv.h | 14 ++++ > drivers/ufs/core/ufshcd.c | 3 +- > include/ufs/ufshcd.h | 1 + > include/ufs/ufshci.h | 16 ++++ > 5 files changed, 214 insertions(+), 1 deletion(-) > > diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c > index 31df052..4c33c1a 100644 > --- a/drivers/ufs/core/ufs-mcq.c > +++ b/drivers/ufs/core/ufs-mcq.c > @@ -12,6 +12,9 @@ > #include <linux/module.h> > #include <linux/platform_device.h> > #include "ufshcd-priv.h" > +#include <linux/delay.h> > +#include <scsi/scsi_cmnd.h> > +#include <linux/bitfield.h> > > #define MAX_QUEUE_SUP GENMASK(7, 0) > #define UFS_MCQ_MIN_RW_QUEUES 2 > @@ -27,6 +30,9 @@ > #define MCQ_ENTRY_SIZE_IN_DWORD 8 > #define CQE_UCD_BA GENMASK_ULL(63, 7) > > +/* Max mcq register polling time in millisecond unit */ > +#define MCQ_POLL_MS 500 > + > static int rw_queue_count_set(const char *val, const struct kernel_param *kp) > { > return param_set_uint_minmax(val, kp, UFS_MCQ_MIN_RW_QUEUES, > @@ -429,3 +435,178 @@ int ufshcd_mcq_init(struct ufs_hba *hba) > host->host_tagset = 1; > return 0; > } > + > +static int ufshcd_mcq_poll_register(void __iomem *reg, u32 mask, > + u32 val, unsigned long timeout_ms) > +{ > + unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); > + int err = 0; > + > + /* ignore bits that we don't intend to wait on */ > + val = val & mask; > + > + while ((readl(reg) & mask) != val) { > + usleep_range(10, 50); > + if (time_after(jiffies, timeout)) { > + err = -ETIMEDOUT; > + break; > + } > + } Should be able to use a macro from include/linux/iopoll.h here > + > + return err; > +}