From 1763454123f6a4bdd236c9e11a66747e1bc705a2 Mon Sep 17 00:00:00 2001 From: "jonggab.park" Date: Fri, 28 Apr 2017 14:09:54 +0900 Subject: [PATCH] drm/tgm: add sub driver handling interface. It doesn't have the pp interface for the pp driver. And this patch is from product kernel. Change-Id: Iceb891e602fe6e6e246445b7d845927cc39a73c0 Signed-off-by: Jin-young Jeon Signed-off-by: Inki Dae --- drivers/gpu/drm/tgm/tgm_drv.c | 107 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/tgm/tgm_drv.h | 20 +++++++ 2 files changed, 127 insertions(+) diff --git a/drivers/gpu/drm/tgm/tgm_drv.c b/drivers/gpu/drm/tgm/tgm_drv.c index 2053b00cb47..bd8570042f5 100644 --- a/drivers/gpu/drm/tgm/tgm_drv.c +++ b/drivers/gpu/drm/tgm/tgm_drv.c @@ -30,6 +30,113 @@ struct component_dev { struct device *irq_dev; }; +static LIST_HEAD(tgm_subdrv_list); + +int tgm_subdrv_register(struct tgm_subdrv *subdrv) +{ + if (!subdrv) + return -EINVAL; + + list_add_tail(&subdrv->list, &tgm_subdrv_list); + + return 0; +} +EXPORT_SYMBOL_GPL(tgm_subdrv_register); + +int tgm_subdrv_unregister(struct tgm_subdrv *subdrv) +{ + if (!subdrv) + return -EINVAL; + + list_del(&subdrv->list); + + return 0; +} +EXPORT_SYMBOL_GPL(tgm_subdrv_unregister); + +int tgm_device_subdrv_probe(struct drm_device *dev) +{ + struct tgm_subdrv *subdrv, *n; + int err; + + if (!dev) + return -EINVAL; + + list_for_each_entry_safe(subdrv, n, &tgm_subdrv_list, list) { + if (subdrv->probe) { + subdrv->drm_dev = dev; + + /* + * this probe callback would be called by sub driver + * after setting of all resources to this sub driver, + * such as clock, irq and register map are done. + */ + err = subdrv->probe(dev, subdrv->dev); + if (err) { + DRM_DEBUG("exynos drm subdrv probe failed.\n"); + list_del(&subdrv->list); + continue; + } + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(tgm_device_subdrv_probe); + +int tgm_device_subdrv_remove(struct drm_device *dev) +{ + struct tgm_subdrv *subdrv; + + if (!dev) { + WARN(1, "Unexpected drm device unregister!\n"); + return -EINVAL; + } + + list_for_each_entry(subdrv, &tgm_subdrv_list, list) { + if (subdrv->remove) + subdrv->remove(dev, subdrv->dev); + } + + return 0; +} +EXPORT_SYMBOL_GPL(tgm_device_subdrv_remove); + +int tgm_subdrv_open(struct drm_device *dev, struct drm_file *file) +{ + struct tgm_subdrv *subdrv; + int ret; + + list_for_each_entry(subdrv, &tgm_subdrv_list, list) { + if (subdrv->open) { + ret = subdrv->open(dev, subdrv->dev, file); + if (ret) + goto err; + } + } + + return 0; + +err: + list_for_each_entry_reverse(subdrv, &subdrv->list, list) { + if (subdrv->close) + subdrv->close(dev, subdrv->dev, file); + } + return ret; +} +EXPORT_SYMBOL_GPL(tgm_subdrv_open); + +void tgm_subdrv_close(struct drm_device *dev, struct drm_file *file) +{ + struct tgm_subdrv *subdrv; + + list_for_each_entry(subdrv, &tgm_subdrv_list, list) { + if (subdrv->close) + subdrv->close(dev, subdrv->dev, file); + } +} +EXPORT_SYMBOL_GPL(tgm_subdrv_close); + static int tgm_drv_load(struct drm_device *drm_dev, unsigned long flags) { struct tgm_drv_private *dev_priv; diff --git a/drivers/gpu/drm/tgm/tgm_drv.h b/drivers/gpu/drm/tgm/tgm_drv.h index 5af11712b57..a0f0ce07dd1 100644 --- a/drivers/gpu/drm/tgm/tgm_drv.h +++ b/drivers/gpu/drm/tgm/tgm_drv.h @@ -33,9 +33,29 @@ struct tgm_drv_file_private { pid_t tgid; }; +struct tgm_subdrv { + struct list_head list; + struct device *dev; + struct drm_device *drm_dev; + + int (*probe)(struct drm_device *drm_dev, struct device *dev); + void (*remove)(struct drm_device *drm_dev, struct device *dev); + int (*open)(struct drm_device *drm_dev, struct device *dev, + struct drm_file *file); + void (*close)(struct drm_device *drm_dev, struct device *dev, + struct drm_file *file); +}; + int tgm_drv_component_add(struct device *dev, enum tgm_drv_dev_type dev_type); void tgm_drv_component_del(struct device *dev, enum tgm_drv_dev_type dev_type); +int tgm_subdrv_register(struct tgm_subdrv *drm_subdrv); +int tgm_subdrv_unregister(struct tgm_subdrv *drm_subdrv); +int tgm_device_subdrv_probe(struct drm_device *dev); +int tgm_device_subdrv_remove(struct drm_device *dev); +int tgm_subdrv_open(struct drm_device *dev, struct drm_file *file); +void tgm_subdrv_close(struct drm_device *dev, struct drm_file *file); + #endif /* _TGM_DRV_H_ */ -- 2.34.1