ANDROID: scsi: ufs: Make CONFIG_SCSI_UFS_HPB compatible with the GKI
Move the ufshpb_dev member into a new structure such that enabling HPB does not affect the layout of other members of struct ufs_hba. This change does not affect the ABI since UFS HPB support is currently disabled. The only function that allocates a struct ufs_hba instance is ufshcd_alloc_host() and that function allocates struct ufs_hba dynamically. Modify that function such that it also allocates memory for the HPB data if necessary. Bug: 194163838 Bug: 195507090 Test: Built the kernel with this patch applied and installed it on an Android device. Change-Id: Ia4c5ba07ae343576373ec116553c5fdee8f75a94 Signed-off-by: Bart Van Assche <bvanassche@google.com>
This commit is contained in:
@@ -9313,7 +9313,7 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
host = scsi_host_alloc(&ufshcd_driver_template,
|
host = scsi_host_alloc(&ufshcd_driver_template,
|
||||||
sizeof(struct ufs_hba));
|
sizeof(struct ufs_hba_with_hpb));
|
||||||
if (!host) {
|
if (!host) {
|
||||||
dev_err(dev, "scsi_host_alloc failed\n");
|
dev_err(dev, "scsi_host_alloc failed\n");
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
|
@@ -912,7 +912,8 @@ struct ufs_hba {
|
|||||||
bool wb_enabled;
|
bool wb_enabled;
|
||||||
struct delayed_work rpm_dev_flush_recheck_work;
|
struct delayed_work rpm_dev_flush_recheck_work;
|
||||||
|
|
||||||
#ifdef CONFIG_SCSI_UFS_HPB
|
#if 0
|
||||||
|
/* This has been moved into struct ufs_hba_with_hpb. */
|
||||||
struct ufshpb_dev_info ufshpb_dev;
|
struct ufshpb_dev_info ufshpb_dev;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -934,6 +935,17 @@ struct ufs_hba {
|
|||||||
ANDROID_KABI_RESERVE(4);
|
ANDROID_KABI_RESERVE(4);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compared to the upstream equivalent, @hpb_dev has been moved from struct
|
||||||
|
* ufs_hba into struct ufs_hba_with_hpb to satisfy the Android ABI checks.
|
||||||
|
*/
|
||||||
|
struct ufs_hba_with_hpb {
|
||||||
|
struct ufs_hba hba;
|
||||||
|
#ifdef CONFIG_SCSI_UFS_HPB
|
||||||
|
struct ufshpb_dev_info hpb_dev;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
/* Returns true if clocks can be gated. Otherwise false */
|
/* Returns true if clocks can be gated. Otherwise false */
|
||||||
static inline bool ufshcd_is_clkgating_allowed(struct ufs_hba *hba)
|
static inline bool ufshcd_is_clkgating_allowed(struct ufs_hba *hba)
|
||||||
{
|
{
|
||||||
|
@@ -35,15 +35,20 @@ static struct workqueue_struct *ufshpb_wq;
|
|||||||
static void ufshpb_update_active_info(struct ufshpb_lu *hpb, int rgn_idx,
|
static void ufshpb_update_active_info(struct ufshpb_lu *hpb, int rgn_idx,
|
||||||
int srgn_idx);
|
int srgn_idx);
|
||||||
|
|
||||||
|
static inline struct ufshpb_dev_info *ufs_hba_to_hpb(struct ufs_hba *hba)
|
||||||
|
{
|
||||||
|
return &container_of(hba, struct ufs_hba_with_hpb, hba)->hpb_dev;
|
||||||
|
}
|
||||||
|
|
||||||
bool ufshpb_is_allowed(struct ufs_hba *hba)
|
bool ufshpb_is_allowed(struct ufs_hba *hba)
|
||||||
{
|
{
|
||||||
return !(hba->ufshpb_dev.hpb_disabled);
|
return !(ufs_hba_to_hpb(hba)->hpb_disabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* HPB version 1.0 is called as legacy version. */
|
/* HPB version 1.0 is called as legacy version. */
|
||||||
bool ufshpb_is_legacy(struct ufs_hba *hba)
|
bool ufshpb_is_legacy(struct ufs_hba *hba)
|
||||||
{
|
{
|
||||||
return hba->ufshpb_dev.is_legacy;
|
return ufs_hba_to_hpb(hba)->is_legacy;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ufshpb_lu *ufshpb_get_hpb_data(struct scsi_device *sdev)
|
static struct ufshpb_lu *ufshpb_get_hpb_data(struct scsi_device *sdev)
|
||||||
@@ -2743,8 +2748,7 @@ void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
hpb = ufshpb_alloc_hpb_lu(hba, sdev, &hba->ufshpb_dev,
|
hpb = ufshpb_alloc_hpb_lu(hba, sdev, ufs_hba_to_hpb(hba), &hpb_lu_info);
|
||||||
&hpb_lu_info);
|
|
||||||
if (!hpb)
|
if (!hpb)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@@ -2753,7 +2757,7 @@ void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
/* All LUs are initialized */
|
/* All LUs are initialized */
|
||||||
if (atomic_dec_and_test(&hba->ufshpb_dev.slave_conf_cnt))
|
if (atomic_dec_and_test(&ufs_hba_to_hpb(hba)->slave_conf_cnt))
|
||||||
ufshpb_hpb_lu_prepared(hba);
|
ufshpb_hpb_lu_prepared(hba);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2810,7 +2814,7 @@ release_mctx_cache:
|
|||||||
|
|
||||||
void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf)
|
void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf)
|
||||||
{
|
{
|
||||||
struct ufshpb_dev_info *hpb_info = &hba->ufshpb_dev;
|
struct ufshpb_dev_info *hpb_info = ufs_hba_to_hpb(hba);
|
||||||
int max_active_rgns = 0;
|
int max_active_rgns = 0;
|
||||||
int hpb_num_lu;
|
int hpb_num_lu;
|
||||||
|
|
||||||
@@ -2836,7 +2840,7 @@ void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf)
|
|||||||
|
|
||||||
void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf)
|
void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf)
|
||||||
{
|
{
|
||||||
struct ufshpb_dev_info *hpb_dev_info = &hba->ufshpb_dev;
|
struct ufshpb_dev_info *hpb_dev_info = ufs_hba_to_hpb(hba);
|
||||||
int version, ret;
|
int version, ret;
|
||||||
u32 max_hpb_single_cmd = HPB_MULTI_CHUNK_LOW;
|
u32 max_hpb_single_cmd = HPB_MULTI_CHUNK_LOW;
|
||||||
|
|
||||||
@@ -2873,7 +2877,7 @@ void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf)
|
|||||||
|
|
||||||
void ufshpb_init(struct ufs_hba *hba)
|
void ufshpb_init(struct ufs_hba *hba)
|
||||||
{
|
{
|
||||||
struct ufshpb_dev_info *hpb_dev_info = &hba->ufshpb_dev;
|
struct ufshpb_dev_info *hpb_dev_info = ufs_hba_to_hpb(hba);
|
||||||
int try;
|
int try;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user