drm/dsi: Get DSI host by DT device node

MIPI DSI devices are inherently aware of their host because they share a
parent-child hierarchy in the device tree.

Non-DSI drivers that create DSI device don't have this data. In order to
get this information, they require to a phandle to the DSI host in the
device tree.

Maintain a list of all the DSI hosts that are currently registered. This
list will be used to find the struct mipi_dsi_host corresponding to the
device tree node passed to of_find_mipi_dsi_host_by_node().

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
Archit Taneja 2016-02-12 14:48:34 +05:30 committed by Thierry Reding
parent 509e42ce04
commit 97b6ae50e0
2 changed files with 42 additions and 0 deletions

View File

@ -235,6 +235,37 @@ void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
} }
EXPORT_SYMBOL(mipi_dsi_device_unregister); EXPORT_SYMBOL(mipi_dsi_device_unregister);
static DEFINE_MUTEX(host_lock);
static LIST_HEAD(host_list);
/**
* of_find_mipi_dsi_host_by_node() - find the MIPI DSI host matching a
* device tree node
* @node: device tree node
*
* Returns:
* A pointer to the MIPI DSI host corresponding to @node or NULL if no
* such device exists (or has not been registered yet).
*/
struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node)
{
struct mipi_dsi_host *host;
mutex_lock(&host_lock);
list_for_each_entry(host, &host_list, list) {
if (host->dev->of_node == node) {
mutex_unlock(&host_lock);
return host;
}
}
mutex_unlock(&host_lock);
return NULL;
}
EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node);
int mipi_dsi_host_register(struct mipi_dsi_host *host) int mipi_dsi_host_register(struct mipi_dsi_host *host)
{ {
struct device_node *node; struct device_node *node;
@ -246,6 +277,10 @@ int mipi_dsi_host_register(struct mipi_dsi_host *host)
of_mipi_dsi_device_add(host, node); of_mipi_dsi_device_add(host, node);
} }
mutex_lock(&host_lock);
list_add_tail(&host->list, &host_list);
mutex_unlock(&host_lock);
return 0; return 0;
} }
EXPORT_SYMBOL(mipi_dsi_host_register); EXPORT_SYMBOL(mipi_dsi_host_register);
@ -262,6 +297,10 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
void mipi_dsi_host_unregister(struct mipi_dsi_host *host) void mipi_dsi_host_unregister(struct mipi_dsi_host *host)
{ {
device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn); device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn);
mutex_lock(&host_lock);
list_del_init(&host->list);
mutex_unlock(&host_lock);
} }
EXPORT_SYMBOL(mipi_dsi_host_unregister); EXPORT_SYMBOL(mipi_dsi_host_unregister);

View File

@ -96,14 +96,17 @@ struct mipi_dsi_host_ops {
* struct mipi_dsi_host - DSI host device * struct mipi_dsi_host - DSI host device
* @dev: driver model device node for this DSI host * @dev: driver model device node for this DSI host
* @ops: DSI host operations * @ops: DSI host operations
* @list: list management
*/ */
struct mipi_dsi_host { struct mipi_dsi_host {
struct device *dev; struct device *dev;
const struct mipi_dsi_host_ops *ops; const struct mipi_dsi_host_ops *ops;
struct list_head list;
}; };
int mipi_dsi_host_register(struct mipi_dsi_host *host); int mipi_dsi_host_register(struct mipi_dsi_host *host);
void mipi_dsi_host_unregister(struct mipi_dsi_host *host); void mipi_dsi_host_unregister(struct mipi_dsi_host *host);
struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
/* DSI mode flags */ /* DSI mode flags */