mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-09-21 11:53:01 +00:00
761e4e57cd
boardinfo structure array populates slaves on the slimbus. Framework populates devices specified by the boardinfo array and the array is not referenced later. Also, while reallocating the array to populate slaves in the loop, make sure that the existing array is not leaked if reallocation fails during new slave addition. Change-Id: Ib7e289ee56c57cad2962529270d55bf4107961df Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
91 lines
2.3 KiB
C
91 lines
2.3 KiB
C
/* Copyright (c) 2012, 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.
|
|
*/
|
|
|
|
/* OF helpers for SLIMbus */
|
|
#include <linux/slimbus/slimbus.h>
|
|
#include <linux/irq.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of_irq.h>
|
|
#include <linux/of_slimbus.h>
|
|
|
|
int of_register_slim_devices(struct slim_controller *ctrl)
|
|
{
|
|
struct device_node *node;
|
|
struct slim_boardinfo *binfo = NULL;
|
|
struct slim_boardinfo *temp;
|
|
int n = 0;
|
|
int ret = 0;
|
|
|
|
if (!ctrl->dev.of_node)
|
|
return -EINVAL;
|
|
|
|
for_each_child_of_node(ctrl->dev.of_node, node) {
|
|
struct property *prop;
|
|
struct slim_device *slim;
|
|
char *name;
|
|
prop = of_find_property(node, "elemental-addr", NULL);
|
|
if (!prop || prop->length != 6) {
|
|
dev_err(&ctrl->dev, "of_slim: invalid E-addr");
|
|
continue;
|
|
}
|
|
name = kzalloc(SLIMBUS_NAME_SIZE, GFP_KERNEL);
|
|
if (!name) {
|
|
dev_err(&ctrl->dev, "of_slim: out of memory");
|
|
ret = -ENOMEM;
|
|
goto of_slim_err;
|
|
}
|
|
if (of_modalias_node(node, name, SLIMBUS_NAME_SIZE) < 0) {
|
|
dev_err(&ctrl->dev, "of_slim: modalias failure on %s\n",
|
|
node->full_name);
|
|
kfree(name);
|
|
continue;
|
|
}
|
|
slim = kzalloc(sizeof(struct slim_device), GFP_KERNEL);
|
|
if (!slim) {
|
|
dev_err(&ctrl->dev, "of_slim: out of memory");
|
|
ret = -ENOMEM;
|
|
kfree(name);
|
|
goto of_slim_err;
|
|
}
|
|
memcpy(slim->e_addr, prop->value, 6);
|
|
|
|
temp = krealloc(binfo, (n + 1) * sizeof(struct slim_boardinfo),
|
|
GFP_KERNEL);
|
|
if (!temp) {
|
|
dev_err(&ctrl->dev, "out of memory");
|
|
kfree(name);
|
|
kfree(slim);
|
|
ret = -ENOMEM;
|
|
goto of_slim_err;
|
|
}
|
|
binfo = temp;
|
|
|
|
slim->dev.of_node = of_node_get(node);
|
|
slim->name = (const char *)name;
|
|
binfo[n].bus_num = ctrl->nr;
|
|
binfo[n].slim_slave = slim;
|
|
n++;
|
|
}
|
|
ret = slim_register_board_info(binfo, n);
|
|
if (!ret)
|
|
goto of_slim_ret;
|
|
of_slim_err:
|
|
while (n-- > 0) {
|
|
kfree(binfo[n].slim_slave->name);
|
|
kfree(binfo[n].slim_slave);
|
|
}
|
|
of_slim_ret:
|
|
kfree(binfo);
|
|
return ret;
|
|
}
|