aboutsummaryrefslogtreecommitdiff
path: root/drivers/video/mxc/mxc_dispdrv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/mxc/mxc_dispdrv.c')
-rw-r--r--drivers/video/mxc/mxc_dispdrv.c94
1 files changed, 45 insertions, 49 deletions
diff --git a/drivers/video/mxc/mxc_dispdrv.c b/drivers/video/mxc/mxc_dispdrv.c
index 06b7af944f5..b455a6ab06f 100644
--- a/drivers/video/mxc/mxc_dispdrv.c
+++ b/drivers/video/mxc/mxc_dispdrv.c
@@ -22,8 +22,9 @@
* Move all dev_suspend() things into fb_notifier for SUSPEND, if there is;
* Move all dev_resume() things into fb_notifier for RESUME, if there is;
*
- * ipuv3 fb driver could call mxc_dispdrv_init(setting) before a fb need be added, with fbi param
- * passing by setting, after mxc_dispdrv_init() return, FB driver should get the basic setting
+ * ipuv3 fb driver could call mxc_dispdrv_gethandle(name, setting) before a fb
+ * need be added, with fbi param passing by setting, after
+ * mxc_dispdrv_gethandle() return, FB driver should get the basic setting
* about fbi info and ipuv3-hw (ipu_id and disp_id).
*
* @ingroup Framebuffer
@@ -42,16 +43,15 @@ static LIST_HEAD(dispdrv_list);
static DEFINE_MUTEX(dispdrv_lock);
struct mxc_dispdrv_entry {
- const char *name;
- struct list_head list;
- int (*init) (struct mxc_dispdrv_entry *);
- void (*deinit) (struct mxc_dispdrv_entry *);
+ /* Note: drv always the first element */
+ struct mxc_dispdrv_driver *drv;
bool active;
struct mxc_dispdrv_setting setting;
void *priv;
+ struct list_head list;
};
-struct mxc_dispdrv_entry *mxc_dispdrv_register(struct mxc_dispdrv_driver *drv)
+struct mxc_dispdrv_handle *mxc_dispdrv_register(struct mxc_dispdrv_driver *drv)
{
struct mxc_dispdrv_entry *new;
@@ -63,23 +63,20 @@ struct mxc_dispdrv_entry *mxc_dispdrv_register(struct mxc_dispdrv_driver *drv)
return ERR_PTR(-ENOMEM);
}
- new->name = drv->name;
- new->init = drv->init;
- new->deinit = drv->deinit;
-
+ new->drv = drv;
list_add_tail(&new->list, &dispdrv_list);
mutex_unlock(&dispdrv_lock);
- return new;
+ return (struct mxc_dispdrv_handle *)new;
}
EXPORT_SYMBOL_GPL(mxc_dispdrv_register);
-int mxc_dispdrv_unregister(struct mxc_dispdrv_entry *entry)
+int mxc_dispdrv_unregister(struct mxc_dispdrv_handle *handle)
{
+ struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
+
if (entry) {
mutex_lock(&dispdrv_lock);
- if (entry->active && entry->deinit)
- entry->deinit(entry);
list_del(&entry->list);
mutex_unlock(&dispdrv_lock);
kfree(entry);
@@ -89,41 +86,48 @@ int mxc_dispdrv_unregister(struct mxc_dispdrv_entry *entry)
}
EXPORT_SYMBOL_GPL(mxc_dispdrv_unregister);
-int mxc_dispdrv_init(char *name, struct mxc_dispdrv_setting *setting)
+struct mxc_dispdrv_handle *mxc_dispdrv_gethandle(char *name,
+ struct mxc_dispdrv_setting *setting)
{
- int ret = 0, found = 0;
- struct mxc_dispdrv_entry *disp;
+ int ret, found = 0;
+ struct mxc_dispdrv_entry *entry;
mutex_lock(&dispdrv_lock);
- list_for_each_entry(disp, &dispdrv_list, list) {
- if (!strcmp(disp->name, name)) {
- if (disp->init) {
- memcpy(&disp->setting, setting,
- sizeof(struct mxc_dispdrv_setting));
- ret = disp->init(disp);
- if (ret >= 0) {
- disp->active = true;
- /* setting may need fix-up */
- memcpy(setting, &disp->setting,
- sizeof(struct mxc_dispdrv_setting));
- found = 1;
- break;
- }
+ list_for_each_entry(entry, &dispdrv_list, list) {
+ if (!strcmp(entry->drv->name, name) && (entry->drv->init)) {
+ ret = entry->drv->init((struct mxc_dispdrv_handle *)
+ entry, setting);
+ if (ret >= 0) {
+ entry->active = true;
+ found = 1;
+ break;
}
}
}
- if (!found)
- ret = -EINVAL;
-
mutex_unlock(&dispdrv_lock);
- return ret;
+ return found ? (struct mxc_dispdrv_handle *)entry:ERR_PTR(-ENODEV);
+}
+EXPORT_SYMBOL_GPL(mxc_dispdrv_gethandle);
+
+void mxc_dispdrv_puthandle(struct mxc_dispdrv_handle *handle)
+{
+ struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
+
+ mutex_lock(&dispdrv_lock);
+ if (entry && entry->active && entry->drv->deinit) {
+ entry->drv->deinit(handle);
+ entry->active = false;
+ }
+ mutex_unlock(&dispdrv_lock);
}
-EXPORT_SYMBOL_GPL(mxc_dispdrv_init);
+EXPORT_SYMBOL_GPL(mxc_dispdrv_puthandle);
-int mxc_dispdrv_setdata(struct mxc_dispdrv_entry *entry, void *data)
+int mxc_dispdrv_setdata(struct mxc_dispdrv_handle *handle, void *data)
{
+ struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
+
if (entry) {
entry->priv = data;
return 0;
@@ -132,21 +136,13 @@ int mxc_dispdrv_setdata(struct mxc_dispdrv_entry *entry, void *data)
}
EXPORT_SYMBOL_GPL(mxc_dispdrv_setdata);
-void *mxc_dispdrv_getdata(struct mxc_dispdrv_entry *entry)
+void *mxc_dispdrv_getdata(struct mxc_dispdrv_handle *handle)
{
+ struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
+
if (entry) {
return entry->priv;
} else
return ERR_PTR(-EINVAL);
}
EXPORT_SYMBOL_GPL(mxc_dispdrv_getdata);
-
-struct mxc_dispdrv_setting
- *mxc_dispdrv_getsetting(struct mxc_dispdrv_entry *entry)
-{
- if (entry) {
- return &entry->setting;
- } else
- return ERR_PTR(-EINVAL);
-}
-EXPORT_SYMBOL_GPL(mxc_dispdrv_getsetting);