Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp745668imm; Tue, 5 Jun 2018 03:55:35 -0700 (PDT) X-Google-Smtp-Source: ADUXVKKAAfaUJEpfV6VQEce4ADWYzlBP1Vy68hlrUoIdQ0Qmw18OGdbVZb6azeS4oGE4ujVDfDTI X-Received: by 2002:a17:902:74cc:: with SMTP id f12-v6mr26007116plt.7.1528196135084; Tue, 05 Jun 2018 03:55:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528196135; cv=none; d=google.com; s=arc-20160816; b=MX9YXnesE25SE7azY8yVBPTxgBnRwEiOXHJcS9NLZyElQFWUf5v/niFMr0lOD4pRBj EL6WhqgT6FwHCCiRv2mpXuZa+zXAiGb+pL+5lfxdgIOc8teGea8ugEXTKDy70LQYw1oU jd0fAJ6WREERe3+bhanp5snR4UJpLT9oOcVWSAzZGlB8irqnUiCToCoOpRQv0SWtEmcs gVt4J2OZENFUOvs3GyU/dxmiccte2YBHAL79Y6gk746uLmmslIK5VftV2GhQ8Ox2QdLa MbFvpIA3ElG3nX0YUpxlccsquq9HDGNGte5WDIajtkTCUcZ6RMyFmD7/IW7a8PDnP9/t b84w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-language:thread-index :content-transfer-encoding:mime-version:message-id:date:subject :in-reply-to:references:cc:to:from:dmarc-filter:dkim-signature :dkim-signature:arc-authentication-results; bh=fXAplTe/l+SpPsWFkpNxzRqmoTKWp8g0xmfTIoVe1Ak=; b=qXWNqJb2A5uw8X2LmVmk37ROkkqH7HOuxelE2PPH1knqlV3caOGmXA0dhlJh528ygY oszNWdCeJpJqaKeAERWfn6j+5dnOnOqPi55wN5sI8+ibo96TdQo2bEnSubMgKUu1XQv9 +Hry7hY+vYyrkoqVRhUgk7rGU9wqpVe3R64rvGEuW7uftLv6Q8/T90vo7M1SZG5BignG KIRwBv2tR6/HUkVrdltUr3JgorKOpZcCp/YF8FOR97rH7tn44qe1ZDoFL8dbzLUIH0jU SaSty4nTl6t2StfMTjFljwUm71snrNQLThAj/1xfYtE1YyywiQMCrAVjlPdwJ362M3hL DByg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=dkfi9n0B; dkim=pass header.i=@codeaurora.org header.s=default header.b=igN9+Sx0; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u74-v6si38310551pgc.186.2018.06.05.03.55.20; Tue, 05 Jun 2018 03:55:35 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=dkfi9n0B; dkim=pass header.i=@codeaurora.org header.s=default header.b=igN9+Sx0; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751775AbeFEKyn (ORCPT + 99 others); Tue, 5 Jun 2018 06:54:43 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:60876 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751502AbeFEKym (ORCPT ); Tue, 5 Jun 2018 06:54:42 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id BA685605BD; Tue, 5 Jun 2018 10:54:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1528196081; bh=v4DNMFrARBauYgt4hBjskJ7YObDsS83Bc013LDwX6t8=; h=From:To:Cc:References:In-Reply-To:Subject:Date:From; b=dkfi9n0BmukP/a2oMDHVuWi5xs3KGxbhZFLTD2aqEdFEmNyv40bIHqtGKZgnbK2Aq jY4sn9p870vuOhRkLDwTMf16HxzUnIh6j19yGcQNTbT7vM2udEtp5et8DM5MarXjYa 9bb1C7Ssx/3cu88kHkeE/TObAfxFr/tud1fPjVQo= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-0.6 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,TVD_RCVD_SINGLE,T_DKIM_INVALID autolearn=no autolearn_force=no version=3.4.0 Received: from SAYALIL (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: sayalil@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 5A9B960261; Tue, 5 Jun 2018 10:54:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1528196080; bh=v4DNMFrARBauYgt4hBjskJ7YObDsS83Bc013LDwX6t8=; h=From:To:Cc:References:In-Reply-To:Subject:Date:From; b=igN9+Sx025Y277t7fS2DKnBG1gB7nCaXUtcbNCI/m5/Q/yutuNu4boLryHEHhjaHT XoOAvIzY97j87nEXz0fAmqf29BVqB7rgtvb2tXXj/O7fBk+ediwiySOjbuwcGGaoQQ A4QVcJRZ5Zt9MPmGa2wGbyOJ2hynqpeJo4jR14ao= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 5A9B960261 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=sayalil@codeaurora.org From: "sayali" To: "'Kyuho Choi'" Cc: , , , , , , , , , , "'open list'" References: <1527849774-7623-1-git-send-email-sayalil@codeaurora.org> <1527849774-7623-3-git-send-email-sayalil@codeaurora.org> In-Reply-To: Subject: RE: [PATCH V1 2/3] scsi: ufs: Add ufs provisioning support Date: Tue, 5 Jun 2018 16:24:33 +0530 Message-ID: <000a01d3fcbb$99c254d0$cd46fe70$@codeaurora.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Mailer: Microsoft Outlook 16.0 Thread-Index: AQKGja9h2+sAa9B7VDYjBpPLWNjYigHtkbPiAq5DGKCix3uVwA== Content-Language: en-us Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org -----Original Message----- From: Kyuho Choi [mailto:chlrbgh0@gmail.com]=20 Sent: Saturday, June 02, 2018 12:06 PM To: Sayali Lokhande Cc: subhashj@codeaurora.org; cang@codeaurora.org; = vivek.gautam@codeaurora.org; rnayak@codeaurora.org; = vinholikatti@gmail.com; jejb@linux.vnet.ibm.com; = martin.petersen@oracle.com; asutoshd@codeaurora.org; = evgreen@chromium.org; linux-scsi@vger.kernel.org; open list = Subject: Re: [PATCH V1 2/3] scsi: ufs: Add ufs provisioning support Sayali, On 6/1/18, Sayali Lokhande wrote: > A new api ufshcd_do_config_device() is added in driver to suppoet UFS=20 > provisioning at runtime. Sysfs support is added to trigger=20 > provisioning. > Device and Unit configurable parameters are parsed from vendor=20 > specific provisioning data or file and passed via sysfs at runtime to=20 > provision ufs device. > > Signed-off-by: Sayali Lokhande > --- > drivers/scsi/ufs/ufs.h | 28 +++++++ > drivers/scsi/ufs/ufshcd.c | 200 > ++++++++++++++++++++++++++++++++++++++++++++++ > drivers/scsi/ufs/ufshcd.h | 1 + > 3 files changed, 229 insertions(+) > > diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index=20 > e15deb0..1f99904 100644 > --- a/drivers/scsi/ufs/ufs.h > +++ b/drivers/scsi/ufs/ufs.h > @@ -333,6 +333,7 @@ enum { > UFSHCD_AMP =3D 3, > }; > > +#define UFS_BLOCK_SIZE 4096 > #define POWER_DESC_MAX_SIZE 0x62 > #define POWER_DESC_MAX_ACTV_ICC_LVLS 16 > > @@ -425,6 +426,33 @@ enum { > MASK_TM_SERVICE_RESP =3D 0xFF, > }; > > +struct ufs_unit_desc { > + u8 bLUEnable; /* 1 for enabled LU */ > + u8 bBootLunID; /* 0 for using this LU for boot */ > + u8 bLUWriteProtect; /* 1 =3D power on WP, 2 =3D permanent = WP */ > + u8 bMemoryType; /* 0 for enhanced memory type */ > + u32 dNumAllocUnits; /* Number of alloc unit for this LU = */ > + u8 bDataReliability; /* 0 for reliable write support */ > + u8 bLogicalBlockSize; /* See section 13.2.3 of UFS standard = */ > + u8 bProvisioningType; /* 0 for thin provisioning */ > + u16 wContextCapabilities; /* refer Unit Descriptor Description = */ > +}; > + > +struct ufs_config_descr { > + u8 bNumberLU; /* Total number of active LUs */ > + u8 bBootEnable; /* enabling device for partial init = */ > + u8 bDescrAccessEn; /* desc access during partial init */ > + u8 bInitPowerMode; /* Initial device power mode */ > + u8 bHighPriorityLUN; /* LUN of the high priority LU */ > + u8 bSecureRemovalType; /* Erase config for data removal */ > + u8 bInitActiveICCLevel; /* ICC level after reset */ > + u16 wPeriodicRTCUpdate; /* 0 to set a priodic RTC update rate = */ > + u32 bConfigDescrLock; /* 1 to lock Configation Descriptor = */ > + u32 qVendorConfigCode; /* Vendor specific configuration code = */ > + struct ufs_unit_desc unit[8]; > + u8 lun_to_grow; > +}; > + > /* Task management service response */ enum { > UPIU_TASK_MANAGEMENT_FUNC_COMPL =3D 0x00, > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c=20 > index 3669bc4..3fd29e0 100644 > --- a/drivers/scsi/ufs/ufshcd.c > +++ b/drivers/scsi/ufs/ufshcd.c > @@ -237,6 +237,7 @@ static int ufshcd_config_pwr_mode(struct ufs_hba = *hba, > struct ufs_pa_layer_attr *desired_pwr_mode); static int=20 > ufshcd_change_power_mode(struct ufs_hba *hba, > struct ufs_pa_layer_attr *pwr_mode); > +static int ufshcd_do_config_device(struct ufs_hba *hba); > static inline bool ufshcd_valid_tag(struct ufs_hba *hba, int tag) { > return tag >=3D 0 && tag < hba->nutrs; @@ -3063,6 +3064,14 @@ static = > inline int ufshcd_read_power_desc(struct ufs_hba *hba, > return ufshcd_read_desc(hba, QUERY_DESC_IDN_POWER, 0, buf, size); } > > +static inline int ufshcd_read_geometry_desc(struct ufs_hba *hba, > + u8 *buf, > + u32 size) > +{ > + return ufshcd_read_desc(hba, QUERY_DESC_IDN_GEOMETRY, 0, buf, size); = > +} > + > + > static int ufshcd_read_device_desc(struct ufs_hba *hba, u8 *buf, u32=20 > size) { > return ufshcd_read_desc(hba, QUERY_DESC_IDN_DEVICE, 0, buf, size);=20 > @@ -6354,6 +6363,197 @@ static int ufshcd_set_dev_ref_clk(struct=20 > ufs_hba *hba, u32 ref_clk_freq) } > > /** > + * ufshcd_do_config_device - API function for UFS provisioning > + * hba: per-adapter instance > + * Returns 0 for success, non-zero in case of failure. > + */ > +static int ufshcd_do_config_device(struct ufs_hba *hba) { > + struct ufs_config_descr *cfg =3D &hba->cfgs; > + int buff_len =3D QUERY_DESC_CONFIGURATION_DEF_SIZE; > + u8 desc_buf[QUERY_DESC_CONFIGURATION_DEF_SIZE] =3D {0}; > + int i, ret =3D 0; > + int lun_to_grow =3D -1; > + u64 qTotalRawDeviceCapacity; > + u16 wEnhanced1CapAdjFac, wEnhanced2CapAdjFac; > + u32 dEnhanced1MaxNAllocU, dEnhanced2MaxNAllocU; > + size_t alloc_units, units_to_create =3D 0; > + size_t capacity_to_alloc_factor; > + size_t enhanced1_units =3D 0, enhanced2_units =3D 0; > + size_t conversion_ratio =3D 1; > + u8 *pt; > + u32 blocks_per_alloc_unit =3D 1024; > + int geo_len =3D hba->desc_size.geom_desc; > + u8 geo_buf[hba->desc_size.geom_desc]; > + unsigned int max_partitions =3D 8; > + > + WARN_ON(!hba || !cfg); > + ufshcd_set_dev_ref_clk(hba, REF_CLK_FREQ_19_2_MHZ); Why you try to change the device refclk in here?. You need to check = about ufs power mode before change the ufs device's refclk. The refclk = change function wokring fine even when the ufs device in HS mode?. As I = understood, refclk change in HS are not guaranteed by MPHY spec. [Sayali] Agreed. I need not again set ref_clk here before runtime = provisioning every time, as I am setting ref_clk during probe in = ufshcd_probe_hba() .=20 It anyway does nothing here as ref_clk in device will be already set = before, so it just returns. Will remove setting ref_clk from here in my = next patchset.=20 > + > + ret =3D ufshcd_read_geometry_desc(hba, geo_buf, geo_len); > + if (ret) { > + dev_err(hba->dev, "%s: Failed getting geometry_desc %d\n", > + __func__, ret); > + return ret; > + } > + > + /* > + * Get Geomtric parameters like total configurable memory > + * quantity (Offset 0x04 to 0x0b), Capacity Adjustment > + * Factors (Offset 0x30, 0x31, 0x36, 0x37), Max allocation > + * units (Offset 0x2c to 0x2f, 0x32 to 0x35) used to configure > + * the device logical units. > + */ > + qTotalRawDeviceCapacity =3D > + (uint64_t)geo_buf[0x0b] | ((uint64_t)geo_buf[0x0a] << 8) | > + ((uint64_t)geo_buf[0x09] << 16) | > + ((uint64_t)geo_buf[0x08] << 24) | > + ((uint64_t)geo_buf[0x07] << 32) | > + ((uint64_t)geo_buf[0x06] << 40) | > + ((uint64_t)geo_buf[0x05] << 48) | > + ((uint64_t)geo_buf[0x04] << 56); > + wEnhanced1CapAdjFac =3D > + (uint16_t)geo_buf[0x31] | ((uint16_t)geo_buf[0x30] << 8); > + wEnhanced2CapAdjFac =3D > + (uint16_t)geo_buf[0x37] | ((uint16_t)geo_buf[0x36] << 8); > + dEnhanced1MaxNAllocU =3D > + (uint32_t)geo_buf[0x2f] | ((uint32_t)geo_buf[0x2e] << 8) | > + ((uint32_t)geo_buf[0x2d] << 16) | > + ((uint32_t)geo_buf[0x2c] << 24); > + dEnhanced2MaxNAllocU =3D > + (uint32_t)geo_buf[0x35] | ((uint32_t)geo_buf[0x34] << 8) | > + ((uint32_t)geo_buf[0x33] << 16) | > + ((uint32_t)geo_buf[0x32] << 24); > + > + capacity_to_alloc_factor =3D > + (blocks_per_alloc_unit * UFS_BLOCK_SIZE) / 512; > + > + if (qTotalRawDeviceCapacity % capacity_to_alloc_factor !=3D 0) { > + dev_err(hba->dev, > + "%s: Raw capacity(%llu) not multiple of alloc factor(%zu)\n", > + __func__, qTotalRawDeviceCapacity, > + capacity_to_alloc_factor); > + return -EINVAL; > + } > + alloc_units =3D (qTotalRawDeviceCapacity / = capacity_to_alloc_factor); > + units_to_create =3D 0; > + enhanced1_units =3D enhanced2_units =3D 0; > + > + /* > + * Calculate number of allocation units to be assigned to a logical = unit > + * considering the capacity adjustment factor of respective memory = type. > + */ > + for (i =3D 0; i < (max_partitions - 1) && > + units_to_create <=3D alloc_units; i++) { > + if ((cfg->unit[i].dNumAllocUnits % blocks_per_alloc_unit) =3D=3D 0) > + cfg->unit[i].dNumAllocUnits /=3D blocks_per_alloc_unit; > + else > + cfg->unit[i].dNumAllocUnits =3D > + cfg->unit[i].dNumAllocUnits / blocks_per_alloc_unit + 1; > + > + if (cfg->unit[i].bMemoryType =3D=3D 0) > + units_to_create +=3D cfg->unit[i].dNumAllocUnits; > + else if (cfg->unit[i].bMemoryType =3D=3D 3) { > + enhanced1_units +=3D cfg->unit[i].dNumAllocUnits; > + cfg->unit[i].dNumAllocUnits *=3D > + (wEnhanced1CapAdjFac / 0x100); > + units_to_create +=3D cfg->unit[i].dNumAllocUnits; > + } else if (cfg->unit[i].bMemoryType =3D=3D 4) { > + enhanced2_units +=3D cfg->unit[i].dNumAllocUnits; > + cfg->unit[i].dNumAllocUnits *=3D > + (wEnhanced1CapAdjFac / 0x100); > + units_to_create +=3D cfg->unit[i].dNumAllocUnits; > + } else { > + dev_err(hba->dev, "%s: Unsupported memory type %d\n", > + __func__, cfg->unit[i].bMemoryType); > + return -EINVAL; > + } > + } > + if (enhanced1_units > dEnhanced1MaxNAllocU) { > + dev_err(hba->dev, "%s: size %zu exceeds max enhanced1 area size = %u\n", > + __func__, enhanced1_units, dEnhanced1MaxNAllocU); > + return -ERANGE; > + } > + if (enhanced2_units > dEnhanced2MaxNAllocU) { > + dev_err(hba->dev, "%s: size %zu exceeds max enhanced2 area size = %u\n", > + __func__, enhanced2_units, dEnhanced2MaxNAllocU); > + return -ERANGE; > + } > + if (units_to_create > alloc_units) { > + dev_err(hba->dev, "%s: Specified size %zu exceeds device size = %zu\n", > + __func__, units_to_create, alloc_units); > + return -ERANGE; > + } > + lun_to_grow =3D cfg->lun_to_grow; > + if (lun_to_grow !=3D -1) { > + if (cfg->unit[i].bMemoryType =3D=3D 0) > + conversion_ratio =3D 1; > + else if (cfg->unit[i].bMemoryType =3D=3D 3) > + conversion_ratio =3D (wEnhanced1CapAdjFac / 0x100); > + else if (cfg->unit[i].bMemoryType =3D=3D 4) > + conversion_ratio =3D (wEnhanced2CapAdjFac / 0x100); > + > + cfg->unit[lun_to_grow].dNumAllocUnits +=3D > + ((alloc_units - units_to_create) / conversion_ratio); > + dev_dbg(hba->dev, "%s: conversion_ratio %zu for lun %d\n", > + __func__, conversion_ratio, i); > + } > + > + /* Fill in the buffer with configuration data */ > + pt =3D desc_buf; > + *pt++ =3D 0x90; // bLength > + *pt++ =3D 0x01; // bDescriptorType > + *pt++ =3D 0; // Reserved in UFS2.0 and onward > + *pt++ =3D cfg->bBootEnable; > + *pt++ =3D cfg->bDescrAccessEn; > + *pt++ =3D cfg->bInitPowerMode; > + *pt++ =3D cfg->bHighPriorityLUN; > + *pt++ =3D cfg->bSecureRemovalType; > + *pt++ =3D cfg->bInitActiveICCLevel; > + *pt++ =3D (cfg->wPeriodicRTCUpdate >> 8) & 0xff; > + *pt++ =3D cfg->wPeriodicRTCUpdate & 0xff; > + pt =3D pt + 5; // Reserved fields set to 0 > + > + /* Fill in the buffer with per logical unit data */ > + for (i =3D 0; i < UFS_UPIU_MAX_GENERAL_LUN; i++) { > + *pt++ =3D cfg->unit[i].bLUEnable; > + *pt++ =3D cfg->unit[i].bBootLunID; > + *pt++ =3D cfg->unit[i].bLUWriteProtect; > + *pt++ =3D cfg->unit[i].bMemoryType; > + *pt++ =3D (cfg->unit[i].dNumAllocUnits >> 24) & 0xff; > + *pt++ =3D (cfg->unit[i].dNumAllocUnits >> 16) & 0xff; > + *pt++ =3D (cfg->unit[i].dNumAllocUnits >> 8) & 0xff; > + *pt++ =3D (cfg->unit[i].dNumAllocUnits) & 0xff; > + *pt++ =3D cfg->unit[i].bDataReliability; > + *pt++ =3D cfg->unit[i].bLogicalBlockSize; > + *pt++ =3D cfg->unit[i].bProvisioningType; > + *pt++ =3D (cfg->unit[i].wContextCapabilities >> 8) & 0xff; > + *pt++ =3D cfg->unit[i].wContextCapabilities; > + pt =3D pt + 3; // Reserved fields set to 0 > + } > + > + ret =3D ufshcd_query_descriptor_retry(hba, = UPIU_QUERY_OPCODE_WRITE_DESC, > + QUERY_DESC_IDN_CONFIGURATION, 0, 0, desc_buf, &buff_len); > + > + if (ret) { > + dev_err(hba->dev, "%s: Failed writing descriptor. desc_idn %d,=20 > +opcode %x > ret %d\n", > + __func__, QUERY_DESC_IDN_CONFIGURATION, > + UPIU_QUERY_OPCODE_WRITE_DESC, ret); > + return ret; > + } > + > + if (cfg->bConfigDescrLock =3D=3D 1) { > + ret =3D ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, > + QUERY_ATTR_IDN_CONF_DESC_LOCK, 0, 0, &cfg->bConfigDescrLock); > + if (ret) > + dev_err(hba->dev, "%s: Failed writing bConfigDescrLock %d\n", > + __func__, ret); > + } > + > + return ret; > +} > + > +/** > * ufshcd_probe_hba - probe hba to detect device and initialize > * @hba: per-adapter instance > * > diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h=20 > index b026ad8..982bfdf 100644 > --- a/drivers/scsi/ufs/ufshcd.h > +++ b/drivers/scsi/ufs/ufshcd.h > @@ -549,6 +549,7 @@ struct ufs_hba { > unsigned int irq; > bool is_irq_enabled; > u32 dev_ref_clk_freq; > + struct ufs_config_descr cfgs; > > /* Interrupt aggregation support is broken */ > #define UFSHCD_QUIRK_BROKEN_INTR_AGGR 0x1 > -- > The Qualcomm Innovation Center, Inc. is a member of the Code Aurora=20 > Forum, a Linux Foundation Collaborative Project > >