Quoting Maulik Shah (2019-08-13 01:24:42) > diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c > index e278fc11fe5c..bd8e9f1a43b4 100644 > --- a/drivers/soc/qcom/rpmh-rsc.c > +++ b/drivers/soc/qcom/rpmh-rsc.c > @@ -498,6 +498,32 @@ static int tcs_ctrl_write(struct rsc_drv *drv, const struct tcs_request *msg) > return ret; > } > > +/** > + * rpmh_rsc_ctrlr_is_idle: Check if any of the AMCs are busy. > + * > + * @drv: The controller > + * > + * Returns false if the TCSes are engaged in handling requests, > + * True if controller is idle. > + */ > +static bool rpmh_rsc_ctrlr_is_idle(struct rsc_drv *drv) > +{ > + int m; > + struct tcs_group *tcs = get_tcs_of_type(drv, ACTIVE_TCS); > + bool ret = true; > + > + spin_lock(&drv->lock); > + for (m = tcs->offset; m < tcs->offset + tcs->num_tcs; m++) { > + if (!tcs_is_free(drv, m)) { Isn't this a copy of an existing function in the rpmh driver? > + ret = false; > + break; > + } > + } > + spin_unlock(&drv->lock); > + > + return ret; > +} > + > /** > * rpmh_rsc_write_ctrl_data: Write request to the controller > * > @@ -521,6 +547,65 @@ int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg) > return tcs_ctrl_write(drv, msg); > } > > +int rpmh_domain_power_off(struct generic_pm_domain *rsc_pd) > +{ > + struct rsc_drv *drv = container_of(rsc_pd, struct rsc_drv, rsc_pd); > + int ret = 0; > + > + /* > + * RPMh domain can not be powered off when there is pending ACK for > + * ACTIVE_TCS request. Exit when controller is busy. > + */ > + > + ret = rpmh_rsc_ctrlr_is_idle(drv); > + if (!ret) > + goto exit; return 0? Shouldn't it return some negative value? > + > + ret = rpmh_flush(&drv->client); > + if (ret) > + goto exit; Why not just return rpmh_flush(...)? The usage of goto in this function is entirely unnecessary. > + > +exit: > + return ret; > +} > + > +static int rpmh_probe_power_domain(struct platform_device *pdev, > + struct rsc_drv *drv) > +{ > + int ret = -ENOMEM; > + struct generic_pm_domain *rsc_pd = &drv->rsc_pd; > + struct device_node *dn = pdev->dev.of_node; > + > + rsc_pd->name = kasprintf(GFP_KERNEL, "%s", dn->name); > + if (!rsc_pd->name) > + goto exit; return -ENOMEM; > + > + rsc_pd->name = kbasename(rsc_pd->name); > + rsc_pd->power_off = rpmh_domain_power_off; > + rsc_pd->flags |= GENPD_FLAG_IRQ_SAFE; > + > + ret = pm_genpd_init(rsc_pd, NULL, false); > + if (ret) > + goto free_name; > + > + ret = of_genpd_add_provider_simple(dn, rsc_pd); > + if (ret) > + goto remove_pd; > + > + pr_debug("init PM domain %s\n", rsc_pd->name); > + > + return ret; ret = of_genpd_add_provider_simple(...) if (!ret) return 0; Drop the pr_debug(), it's not useful. > + > +remove_pd: > + pm_genpd_remove(rsc_pd); > + > +free_name: > + kfree(rsc_pd->name); > + > +exit: > + return ret; Please remove newlines between labels above.