Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad972217 authored by Vinu Deokaran's avatar Vinu Deokaran Committed by Siddharth Zaveri
Browse files

msm: add display bridge abstraction driver



Add display bridge abstraction driver to provide an abstract interface
for different types of bridge chips used on MSM platforms. This
interface allows driver development for bridge chips from different
manufactorers while allowing users, of the funcationality provided by
these bridge chips, to re-use the same code across different boards.

Change-Id: I64457e3a44479a3b1be5482691d4727a86dc9b87
Signed-off-by: default avatarVinu Deokaran <vinud@codeaurora.org>
Signed-off-by: default avatarSiddharth Zaveri <szaveri@codeaurora.org>
parent 0d88d69d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
source "drivers/video/msm/msm_dba/Kconfig"

if FB_MSM
config FB_MSM_MDSS_COMMON
	bool
+1 −0
Original line number Diff line number Diff line
obj-$(CONFIG_FB_MSM_MDSS_COMMON) += mdss/
obj-$(CONFIG_MSM_DBA) += msm_dba/
+15 −0
Original line number Diff line number Diff line
#
# MSM DBA
#

config MSM_DBA
	bool "MSM Display Bridge Abstraction support"
	depends on ARM
	---help---
	  Support for MSM display bridge abstraction interface. MSM display
	  drivers can use the same interface to interact with different third
	  party bridge chips. Drivers implemented for third party bridge chips
	  should support this interface to allow display driver to control the
	  bridge chip. The MSM DBA driver maintains a list of devices supported
	  on the platform and allow clients to register and access these
	  devices.
+3 −0
Original line number Diff line number Diff line
obj-$(CONFIG_MSM_DBA) += msm_dba.o msm_dba_init.o msm_dba_helpers.o msm_dba_debug.o
clean:
	rm *.o
+146 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/err.h>

#include <video/msm_dba.h>
#include <msm_dba_internal.h>

static DEFINE_MUTEX(register_mutex);

void *msm_dba_register_client(struct msm_dba_reg_info *info,
			      struct msm_dba_ops *ops)
{
	int rc = 0;
	struct msm_dba_device_info *device = NULL;
	struct msm_dba_client_info *client = NULL;

	pr_debug("%s: ENTER\n", __func__);

	if (!info || !ops) {
		pr_err("%s: Invalid params\n", __func__);
		return ERR_PTR(-EINVAL);
	}

	mutex_lock(&register_mutex);

	pr_debug("%s: Client(%s) Chip(%s) Instance(%d)\n", __func__,
		 info->client_name, info->chip_name, info->instance_id);

	rc = msm_dba_get_probed_device(info, &device);
	if (rc) {
		pr_err("%s: Device not found (%s, %d)\n", __func__,
							 info->chip_name,
							 info->instance_id);
		mutex_unlock(&register_mutex);
		return ERR_PTR(rc);
	}

	pr_debug("%s: Client(%s) device found\n", __func__, info->client_name);

	client = kzalloc(sizeof(*client), GFP_KERNEL);
	if (!client) {
		mutex_unlock(&register_mutex);
		return ERR_PTR(-ENOMEM);
	}

	memset(client, 0x0, sizeof(*client));
	client->dev = device;
	strlcpy(client->client_name, info->client_name,
		MSM_DBA_CLIENT_NAME_LEN);

	client->cb = info->cb;
	client->cb_data = info->cb_data;

	mutex_lock_nested(&device->dev_mutex, SINGLE_DEPTH_NESTING);
	list_add(&client->list, &device->client_list);
	*ops = device->client_ops;
	mutex_unlock(&device->dev_mutex);

	if (device->reg_fxn) {
		rc = device->reg_fxn(client);
		if (rc) {
			pr_err("%s: Client register failed (%s, %d)\n",
			       __func__, info->chip_name, info->instance_id);
			kfree(client);
			mutex_unlock(&register_mutex);
			return ERR_PTR(rc);
		}
	}

	mutex_unlock(&register_mutex);

	pr_debug("%s: EXIT\n", __func__);
	return client;
}
EXPORT_SYMBOL(msm_dba_register_client);

int msm_dba_deregister_client(void *client)
{
	int rc = 0;
	struct msm_dba_client_info *handle = client;
	struct msm_dba_client_info *node = NULL;
	struct list_head *tmp = NULL;
	struct list_head *position = NULL;

	pr_debug("%s: ENTER\n", __func__);

	if (!handle) {
		pr_err("%s: Invalid Params\n", __func__);
		return -EINVAL;
	}

	mutex_lock(&register_mutex);

	pr_debug("%s: Client(%s) Chip(%s) Instance(%d)\n", __func__,
		 handle->client_name, handle->dev->chip_name,
		 handle->dev->instance_id);

	if (handle->dev->dereg_fxn) {
		rc = handle->dev->dereg_fxn(handle);
		if (rc) {
			pr_err("%s: Client deregister failed (%s)\n",
			       __func__, handle->client_name);
		}
	}

	mutex_lock_nested(&handle->dev->dev_mutex, SINGLE_DEPTH_NESTING);

	list_for_each_safe(position, tmp, &handle->dev->client_list) {

		node = list_entry(position, struct msm_dba_client_info, list);

		if (node == handle) {
			list_del(&node->list);
			break;
		}
	}

	mutex_unlock(&handle->dev->dev_mutex);

	kfree(handle);

	mutex_unlock(&register_mutex);

	pr_debug("%s: EXIT (%d)\n", __func__, rc);
	return rc;
}
EXPORT_SYMBOL(msm_dba_deregister_client);
Loading