diff mbox series

[2/2] scsi: ufs: Clean up ufshcd_exit_clk_scaling/gating()

Message ID 1607520942-22254-3-git-send-email-cang@codeaurora.org (mailing list archive)
State Superseded
Headers show
Series Two changes related with UFS clock scaling | expand

Commit Message

Can Guo Dec. 9, 2020, 1:35 p.m. UTC
ufshcd_hba_exit() is always called after ufshcd_exit_clk_scaling() and
ufshcd_exit_clk_gating(), so move ufshcd_exit_clk_scaling/gating() to
ufshcd_hba_exit().

Signed-off-by: Can Guo <cang@codeaurora.org>

Comments

Bean Huo Dec. 10, 2020, 6:03 p.m. UTC | #1
On Wed, 2020-12-09 at 05:35 -0800, Can Guo wrote:
> ufshcd_hba_exit() is always called after ufshcd_exit_clk_scaling()
> and
> ufshcd_exit_clk_gating(), so move ufshcd_exit_clk_scaling/gating() to
> ufshcd_hba_exit().
> 
> Signed-off-by: Can Guo <cang@codeaurora.org>
> 
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index 12266bd..41a12d6 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -1846,11 +1846,14 @@ static void ufshcd_init_clk_scaling(struct
> ufs_hba *hba)
>         snprintf(wq_name, sizeof(wq_name), "ufs_clkscaling_%d",
>                  hba->host->host_no);
>         hba->clk_scaling.workq =
> create_singlethread_workqueue(wq_name);
> +
> +       hba->clk_scaling.is_initialized = true;
>  }
>  
>  static void ufshcd_exit_clk_scaling(struct ufs_hba *hba)
>  {
> -       if (!ufshcd_is_clkscaling_supported(hba))
> +       if (!ufshcd_is_clkscaling_supported(hba) ||
> +           !hba->clk_scaling.is_initialized)
>                 return;
>  
>         if (hba->devfreq)
> @@ -1894,12 +1897,16 @@ static void ufshcd_init_clk_gating(struct
> ufs_hba *hba)
>         hba->clk_gating.enable_attr.attr.mode = 0644;
>         if (device_create_file(hba->dev, &hba-
> >clk_gating.enable_attr))
>                 dev_err(hba->dev, "Failed to create sysfs for
> clkgate_enable\n");
> +
> +       hba->clk_gating.is_initialized = true;
>  }

you don't need these two is_initialized at all. they are only be false
when scaling/gating is not supported??

Bean
Can Guo Dec. 11, 2020, 1:11 a.m. UTC | #2
On 2020-12-11 02:03, Bean Huo wrote:
> On Wed, 2020-12-09 at 05:35 -0800, Can Guo wrote:
>> ufshcd_hba_exit() is always called after ufshcd_exit_clk_scaling()
>> and
>> ufshcd_exit_clk_gating(), so move ufshcd_exit_clk_scaling/gating() to
>> ufshcd_hba_exit().
>> 
>> Signed-off-by: Can Guo <cang@codeaurora.org>
>> 
>> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
>> index 12266bd..41a12d6 100644
>> --- a/drivers/scsi/ufs/ufshcd.c
>> +++ b/drivers/scsi/ufs/ufshcd.c
>> @@ -1846,11 +1846,14 @@ static void ufshcd_init_clk_scaling(struct
>> ufs_hba *hba)
>>         snprintf(wq_name, sizeof(wq_name), "ufs_clkscaling_%d",
>>                  hba->host->host_no);
>>         hba->clk_scaling.workq =
>> create_singlethread_workqueue(wq_name);
>> +
>> +       hba->clk_scaling.is_initialized = true;
>>  }
>> 
>>  static void ufshcd_exit_clk_scaling(struct ufs_hba *hba)
>>  {
>> -       if (!ufshcd_is_clkscaling_supported(hba))
>> +       if (!ufshcd_is_clkscaling_supported(hba) ||
>> +           !hba->clk_scaling.is_initialized)
>>                 return;
>> 
>>         if (hba->devfreq)
>> @@ -1894,12 +1897,16 @@ static void ufshcd_init_clk_gating(struct
>> ufs_hba *hba)
>>         hba->clk_gating.enable_attr.attr.mode = 0644;
>>         if (device_create_file(hba->dev, &hba-
>> >clk_gating.enable_attr))
>>                 dev_err(hba->dev, "Failed to create sysfs for
>> clkgate_enable\n");
>> +
>> +       hba->clk_gating.is_initialized = true;
>>  }
> 
> you don't need these two is_initialized at all. they are only be false
> when scaling/gating is not supported??
> 
> Bean

In the case of scaling/gating are supported, the flags are used in
ufshcd_exit_clk_scaling/gating() - when ufshcd_hba_exit() calls
ufshcd_exit_clk_scaling/gating(), the two funcs need to make sure
they really have something to remove, otherwise NULL pointer issues.

Can Guo.
diff mbox series

Patch

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 12266bd..41a12d6 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1846,11 +1846,14 @@  static void ufshcd_init_clk_scaling(struct ufs_hba *hba)
 	snprintf(wq_name, sizeof(wq_name), "ufs_clkscaling_%d",
 		 hba->host->host_no);
 	hba->clk_scaling.workq = create_singlethread_workqueue(wq_name);
+
+	hba->clk_scaling.is_initialized = true;
 }
 
 static void ufshcd_exit_clk_scaling(struct ufs_hba *hba)
 {
-	if (!ufshcd_is_clkscaling_supported(hba))
+	if (!ufshcd_is_clkscaling_supported(hba) ||
+	    !hba->clk_scaling.is_initialized)
 		return;
 
 	if (hba->devfreq)
@@ -1894,12 +1897,16 @@  static void ufshcd_init_clk_gating(struct ufs_hba *hba)
 	hba->clk_gating.enable_attr.attr.mode = 0644;
 	if (device_create_file(hba->dev, &hba->clk_gating.enable_attr))
 		dev_err(hba->dev, "Failed to create sysfs for clkgate_enable\n");
+
+	hba->clk_gating.is_initialized = true;
 }
 
 static void ufshcd_exit_clk_gating(struct ufs_hba *hba)
 {
-	if (!ufshcd_is_clkgating_allowed(hba))
+	if (!ufshcd_is_clkgating_allowed(hba) ||
+	    !hba->clk_gating.is_initialized)
 		return;
+
 	device_remove_file(hba->dev, &hba->clk_gating.delay_attr);
 	device_remove_file(hba->dev, &hba->clk_gating.enable_attr);
 	cancel_work_sync(&hba->clk_gating.ungate_work);
@@ -7764,7 +7771,6 @@  static void ufshcd_async_scan(void *data, async_cookie_t cookie)
 	 */
 	if (ret) {
 		pm_runtime_put_sync(hba->dev);
-		ufshcd_exit_clk_scaling(hba);
 		ufshcd_hba_exit(hba);
 	}
 }
@@ -8201,12 +8207,12 @@  static int ufshcd_hba_init(struct ufs_hba *hba)
 static void ufshcd_hba_exit(struct ufs_hba *hba)
 {
 	if (hba->is_powered) {
+		ufshcd_exit_clk_scaling(hba);
+		ufshcd_exit_clk_gating(hba);
+		if (hba->eh_wq)
+			destroy_workqueue(hba->eh_wq);
 		ufshcd_variant_hba_exit(hba);
 		ufshcd_setup_vreg(hba, false);
-		ufshcd_suspend_clkscaling(hba);
-		if (ufshcd_is_clkscaling_supported(hba))
-			if (hba->devfreq)
-				ufshcd_suspend_clkscaling(hba);
 		ufshcd_setup_clocks(hba, false);
 		ufshcd_setup_hba_vreg(hba, false);
 		hba->is_powered = false;
@@ -8955,13 +8961,9 @@  void ufshcd_remove(struct ufs_hba *hba)
 	blk_mq_free_tag_set(&hba->tmf_tag_set);
 	blk_cleanup_queue(hba->cmd_queue);
 	scsi_remove_host(hba->host);
-	destroy_workqueue(hba->eh_wq);
 	/* disable interrupts */
 	ufshcd_disable_intr(hba, hba->intr_mask);
 	ufshcd_hba_stop(hba);
-
-	ufshcd_exit_clk_scaling(hba);
-	ufshcd_exit_clk_gating(hba);
 	ufshcd_hba_exit(hba);
 }
 EXPORT_SYMBOL_GPL(ufshcd_remove);
@@ -9160,7 +9162,7 @@  int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
 	err = devm_request_irq(dev, irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba);
 	if (err) {
 		dev_err(hba->dev, "request irq failed\n");
-		goto exit_gating;
+		goto out_disable;
 	} else {
 		hba->is_irq_enabled = true;
 	}
@@ -9168,7 +9170,7 @@  int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
 	err = scsi_add_host(host, hba->dev);
 	if (err) {
 		dev_err(hba->dev, "scsi_add_host failed\n");
-		goto exit_gating;
+		goto out_disable;
 	}
 
 	hba->cmd_queue = blk_mq_init_queue(&hba->host->tag_set);
@@ -9251,10 +9253,6 @@  int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
 	blk_cleanup_queue(hba->cmd_queue);
 out_remove_scsi_host:
 	scsi_remove_host(hba->host);
-exit_gating:
-	ufshcd_exit_clk_scaling(hba);
-	ufshcd_exit_clk_gating(hba);
-	destroy_workqueue(hba->eh_wq);
 out_disable:
 	hba->is_irq_enabled = false;
 	ufshcd_hba_exit(hba);
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 9fcecba..3c57847 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -347,6 +347,7 @@  enum clk_gating_state {
  * @delay_attr: sysfs attribute to control delay_attr
  * @enable_attr: sysfs attribute to enable/disable clock gating
  * @is_enabled: Indicates the current status of clock gating
+ * @is_initialized: Indicates whether clock gating is initialized or not
  * @active_reqs: number of requests that are pending and should be waited for
  * completion before gating clocks.
  */
@@ -359,6 +360,7 @@  struct ufs_clk_gating {
 	struct device_attribute delay_attr;
 	struct device_attribute enable_attr;
 	bool is_enabled;
+	bool is_initialized;
 	int active_reqs;
 	struct workqueue_struct *clk_gating_workq;
 };
@@ -384,6 +386,7 @@  struct ufs_saved_pwr_info {
  * @resume_work: worker to resume devfreq
  * @is_enabled: tracks if scaling is currently enabled or not
  * @is_allowed: tracks if scaling is currently allowed or not
+ * @is_initialized: Indicates whether clock scaling is initialized or not
  * @is_busy_started: tracks if busy period has started or not
  * @is_suspended: tracks if devfreq is suspended or not
  */
@@ -399,6 +402,7 @@  struct ufs_clk_scaling {
 	struct work_struct resume_work;
 	bool is_enabled;
 	bool is_allowed;
+	bool is_initialized;
 	bool is_busy_started;
 	bool is_suspended;
 };