From: jonggab.park Date: Fri, 28 Apr 2017 05:09:54 +0000 (+0900) Subject: drm/tgm: add sub driver handling interface. X-Git-Tag: submit/tizen/20170710.052339~13 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1763454123f6a4bdd236c9e11a66747e1bc705a2;p=profile%2Fwearable%2Fplatform%2Fkernel%2Flinux-3.18-exynos7270.git 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 --- 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_ */