media: camss: Allocate power domain resources dynamically

To simplify the driver's maintenance it makes sense to escape from
hardcoded numbers of power domain resources per platform and statical
allocation of the resources. For instance on a QCOM SM8450 platform
the number of CAMSS power domains shall be bumped up to 6, also notably
CAMSS on MSM8916 has only one power domain, however it expects to get 2,
and thus it should result in a runtime error on driver probe.

The change fixes an issue mentioned above and gives more flexibility
to support more platforms in future.

Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
This commit is contained in:
Vladimir Zapolskiy 2022-05-12 09:23:18 +01:00 коммит произвёл Mauro Carvalho Chehab
Родитель bb45f5433f
Коммит 6b1814e269
2 изменённых файлов: 24 добавлений и 21 удалений

Просмотреть файл

@ -1452,19 +1452,31 @@ static const struct media_device_ops camss_media_ops = {
static int camss_configure_pd(struct camss *camss)
{
int nbr_pm_domains = 0;
struct device *dev = camss->dev;
int last_pm_domain = 0;
int i;
int ret;
if (camss->version == CAMSS_8x96 ||
camss->version == CAMSS_660)
nbr_pm_domains = PM_DOMAIN_GEN1_COUNT;
else if (camss->version == CAMSS_845 ||
camss->version == CAMSS_8250)
nbr_pm_domains = PM_DOMAIN_GEN2_COUNT;
camss->genpd_num = of_count_phandle_with_args(dev->of_node,
"power-domains",
"#power-domain-cells");
if (camss->genpd_num < 0) {
dev_err(dev, "Power domains are not defined for camss\n");
return camss->genpd_num;
}
for (i = 0; i < nbr_pm_domains; i++) {
camss->genpd = devm_kmalloc_array(dev, camss->genpd_num,
sizeof(*camss->genpd), GFP_KERNEL);
if (!camss->genpd)
return -ENOMEM;
camss->genpd_link = devm_kmalloc_array(dev, camss->genpd_num,
sizeof(*camss->genpd_link),
GFP_KERNEL);
if (!camss->genpd_link)
return -ENOMEM;
for (i = 0; i < camss->genpd_num; i++) {
camss->genpd[i] = dev_pm_domain_attach_by_id(camss->dev, i);
if (IS_ERR(camss->genpd[i])) {
ret = PTR_ERR(camss->genpd[i]);
@ -1689,7 +1701,6 @@ err_free:
void camss_delete(struct camss *camss)
{
int nbr_pm_domains = 0;
int i;
v4l2_device_unregister(&camss->v4l2_dev);
@ -1698,14 +1709,7 @@ void camss_delete(struct camss *camss)
pm_runtime_disable(camss->dev);
if (camss->version == CAMSS_8x96 ||
camss->version == CAMSS_660)
nbr_pm_domains = PM_DOMAIN_GEN1_COUNT;
else if (camss->version == CAMSS_845 ||
camss->version == CAMSS_8250)
nbr_pm_domains = PM_DOMAIN_GEN2_COUNT;
for (i = 0; i < nbr_pm_domains; i++) {
for (i = 0; i < camss->genpd_num; i++) {
device_link_del(camss->genpd_link[i]);
dev_pm_domain_detach(camss->genpd[i], true);
}

Просмотреть файл

@ -69,9 +69,7 @@ struct resources_icc {
enum pm_domain {
PM_DOMAIN_VFE0 = 0,
PM_DOMAIN_VFE1 = 1,
PM_DOMAIN_GEN1_COUNT = 2, /* CAMSS series of ISPs */
PM_DOMAIN_VFELITE = 2, /* VFELITE / TOP GDSC */
PM_DOMAIN_GEN2_COUNT = 3, /* Titan series of ISPs */
};
enum camss_version {
@ -101,8 +99,9 @@ struct camss {
int vfe_num;
struct vfe_device *vfe;
atomic_t ref_count;
struct device *genpd[PM_DOMAIN_GEN2_COUNT];
struct device_link *genpd_link[PM_DOMAIN_GEN2_COUNT];
int genpd_num;
struct device **genpd;
struct device_link **genpd_link;
struct icc_path *icc_path[ICC_SM8250_COUNT];
struct icc_bw_tbl icc_bw_tbl[ICC_SM8250_COUNT];
};