mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
synced 2025-09-02 16:44:59 +00:00
media: qcom: camss: Move VFE power-domain specifics into vfe.c
Moving the location of the hooks to VFE power domains has several advantages. 1. Separation of concerns and functional decomposition. vfe.c should be responsible for and know best how manage power-domains for a VFE, excising from camss.c follows this principle. 2. Embedding a pointer to genpd in struct camss_vfe{} meas that we can dispense with a bunch of kmalloc array inside of camss.c. 3. Splitting up titan top gdsc from vfe/ife gdsc provides a base for breaking up magic indexes in dtsi. Suggested-by: Matti Lehtimäki <matti.lehtimaki@gmail.com> Tested-by: Matti Lehtimäki <matti.lehtimaki@gmail.com> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
This commit is contained in:
parent
eb73facec2
commit
23aa4f0cd3
@ -14,6 +14,7 @@
|
|||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/pm_domain.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/spinlock_types.h>
|
#include <linux/spinlock_types.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
@ -1379,8 +1380,11 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
|
|||||||
if (!res->line_num)
|
if (!res->line_num)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (res->has_pd)
|
if (res->has_pd) {
|
||||||
vfe->genpd = camss->genpd[id];
|
vfe->genpd = dev_pm_domain_attach_by_id(camss->dev, id);
|
||||||
|
if (IS_ERR(vfe->genpd))
|
||||||
|
return PTR_ERR(vfe->genpd);
|
||||||
|
}
|
||||||
|
|
||||||
vfe->line_num = res->line_num;
|
vfe->line_num = res->line_num;
|
||||||
vfe->ops->subdev_init(dev, vfe);
|
vfe->ops->subdev_init(dev, vfe);
|
||||||
@ -1504,6 +1508,19 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* msm_vfe_genpd_cleanup - Cleanup VFE genpd linkages
|
||||||
|
* @vfe: VFE device
|
||||||
|
*/
|
||||||
|
void msm_vfe_genpd_cleanup(struct vfe_device *vfe)
|
||||||
|
{
|
||||||
|
if (vfe->genpd_link)
|
||||||
|
device_link_del(vfe->genpd_link);
|
||||||
|
|
||||||
|
if (vfe->genpd)
|
||||||
|
dev_pm_domain_detach(vfe->genpd, true);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vfe_link_setup - Setup VFE connections
|
* vfe_link_setup - Setup VFE connections
|
||||||
* @entity: Pointer to media entity structure
|
* @entity: Pointer to media entity structure
|
||||||
|
@ -159,6 +159,8 @@ struct camss_subdev_resources;
|
|||||||
int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
|
int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
|
||||||
const struct camss_subdev_resources *res, u8 id);
|
const struct camss_subdev_resources *res, u8 id);
|
||||||
|
|
||||||
|
void msm_vfe_genpd_cleanup(struct vfe_device *vfe);
|
||||||
|
|
||||||
int msm_vfe_register_entities(struct vfe_device *vfe,
|
int msm_vfe_register_entities(struct vfe_device *vfe,
|
||||||
struct v4l2_device *v4l2_dev);
|
struct v4l2_device *v4l2_dev);
|
||||||
|
|
||||||
|
@ -1486,7 +1486,9 @@ static const struct media_device_ops camss_media_ops = {
|
|||||||
|
|
||||||
static int camss_configure_pd(struct camss *camss)
|
static int camss_configure_pd(struct camss *camss)
|
||||||
{
|
{
|
||||||
|
const struct camss_resources *res = camss->res;
|
||||||
struct device *dev = camss->dev;
|
struct device *dev = camss->dev;
|
||||||
|
int vfepd_num;
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -1506,45 +1508,41 @@ static int camss_configure_pd(struct camss *camss)
|
|||||||
if (camss->genpd_num == 1)
|
if (camss->genpd_num == 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
camss->genpd = devm_kmalloc_array(dev, camss->genpd_num,
|
/* count the # of VFEs which have flagged power-domain */
|
||||||
sizeof(*camss->genpd), GFP_KERNEL);
|
for (vfepd_num = i = 0; i < camss->vfe_total_num; i++) {
|
||||||
if (!camss->genpd)
|
if (res->vfe_res[i].has_pd)
|
||||||
return -ENOMEM;
|
vfepd_num++;
|
||||||
|
}
|
||||||
|
|
||||||
camss->genpd_link = devm_kmalloc_array(dev, camss->genpd_num,
|
/*
|
||||||
sizeof(*camss->genpd_link),
|
* If the number of power-domains is greater than the number of VFEs
|
||||||
GFP_KERNEL);
|
* then the additional power-domain is for the entire CAMSS block.
|
||||||
if (!camss->genpd_link)
|
*/
|
||||||
return -ENOMEM;
|
if (!(camss->genpd_num > vfepd_num))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VFE power domains are in the beginning of the list, and while all
|
* VFE power domains are in the beginning of the list, and while all
|
||||||
* power domains should be attached, only if TITAN_TOP power domain is
|
* power domains should be attached, only if TITAN_TOP power domain is
|
||||||
* found in the list, it should be linked over here.
|
* found in the list, it should be linked over here.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < camss->genpd_num; i++) {
|
camss->genpd = dev_pm_domain_attach_by_id(camss->dev, camss->genpd_num - 1);
|
||||||
camss->genpd[i] = dev_pm_domain_attach_by_id(camss->dev, i);
|
if (IS_ERR(camss->genpd)) {
|
||||||
if (IS_ERR(camss->genpd[i])) {
|
ret = PTR_ERR(camss->genpd);
|
||||||
ret = PTR_ERR(camss->genpd[i]);
|
goto fail_pm;
|
||||||
goto fail_pm;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
camss->genpd_link = device_link_add(camss->dev, camss->genpd,
|
||||||
if (i > camss->res->vfe_num) {
|
DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
|
||||||
camss->genpd_link[i - 1] = device_link_add(camss->dev, camss->genpd[i - 1],
|
DL_FLAG_RPM_ACTIVE);
|
||||||
DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
|
if (!camss->genpd_link) {
|
||||||
DL_FLAG_RPM_ACTIVE);
|
ret = -EINVAL;
|
||||||
if (!camss->genpd_link[i - 1]) {
|
goto fail_pm;
|
||||||
ret = -EINVAL;
|
|
||||||
goto fail_pm;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_pm:
|
fail_pm:
|
||||||
for (--i ; i >= 0; i--)
|
dev_pm_domain_detach(camss->genpd, true);
|
||||||
dev_pm_domain_detach(camss->genpd[i], true);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1566,18 +1564,25 @@ static int camss_icc_get(struct camss *camss)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void camss_genpd_cleanup(struct camss *camss)
|
static void camss_genpd_subdevice_cleanup(struct camss *camss)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < camss->vfe_total_num; i++)
|
||||||
|
msm_vfe_genpd_cleanup(&camss->vfe[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void camss_genpd_cleanup(struct camss *camss)
|
||||||
|
{
|
||||||
if (camss->genpd_num == 1)
|
if (camss->genpd_num == 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (camss->genpd_num > camss->res->vfe_num)
|
camss_genpd_subdevice_cleanup(camss);
|
||||||
device_link_del(camss->genpd_link[camss->genpd_num - 1]);
|
|
||||||
|
|
||||||
for (i = 0; i < camss->genpd_num; i++)
|
if (camss->genpd_link)
|
||||||
dev_pm_domain_detach(camss->genpd[i], true);
|
device_link_del(camss->genpd_link);
|
||||||
|
|
||||||
|
dev_pm_domain_detach(camss->genpd, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -107,8 +107,8 @@ struct camss {
|
|||||||
struct vfe_device *vfe;
|
struct vfe_device *vfe;
|
||||||
atomic_t ref_count;
|
atomic_t ref_count;
|
||||||
int genpd_num;
|
int genpd_num;
|
||||||
struct device **genpd;
|
struct device *genpd;
|
||||||
struct device_link **genpd_link;
|
struct device_link *genpd_link;
|
||||||
struct icc_path *icc_path[ICC_SM8250_COUNT];
|
struct icc_path *icc_path[ICC_SM8250_COUNT];
|
||||||
const struct camss_resources *res;
|
const struct camss_resources *res;
|
||||||
unsigned int vfe_total_num;
|
unsigned int vfe_total_num;
|
||||||
|
Loading…
Reference in New Issue
Block a user