Exemplo n.º 1
0
static int of_set_property(void *blob,
				int nodeoffset,
				char *property_name,
				void *value,
				int valuelen)
{
	int property_offset;
	int ret;

	/* If find the property name in the dt blob, update its value,
	 * else to add this property
	 */
	ret = of_get_property_offset_by_name(blob, nodeoffset,
					property_name, &property_offset);
	if (ret) {
		ret = of_add_property(blob, nodeoffset,
				property_name, value, valuelen);
		if (ret)
			dbg_info("DT: fail to add property\n");

		return ret;
	}

	ret = of_update_property_value(blob, property_offset, value, valuelen);
	if (ret) {
		dbg_info("DT: fail to update property\n");
		return ret;
	}

	return 0;
}
Exemplo n.º 2
0
/**
 * omap_get_timer_dt - get a timer using device-tree
 * @match	- device-tree match structure for matching a device type
 * @property	- optional timer property to match
 *
 * Helper function to get a timer during early boot using device-tree for use
 * as kernel system timer. Optionally, the property argument can be used to
 * select a timer with a specific property. Once a timer is found then mark
 * the timer node in device-tree as disabled, to prevent the kernel from
 * registering this timer as a platform device and so no one else can use it.
 */
static struct device_node * __init omap_get_timer_dt(struct of_device_id *match,
						     const char *property)
{
	struct device_node *np;

	for_each_matching_node(np, match) {
		if (!of_device_is_available(np))
			continue;

		if (property && !of_get_property(np, property, NULL))
			continue;

		of_add_property(np, &device_disabled);
		return np;
	}

	return NULL;
}
Exemplo n.º 3
0
/*
 * of_update_property - Update a property in a node, if the property does
 * not exist, add it.
 *
 * Note that we don't actually remove it, since we have given out
 * who-knows-how-many pointers to the data using get-property.
 * Instead we just move the property to the "dead properties" list,
 * and add the new property to the property list
 */
int of_update_property(struct device_node *np, struct property *newprop)
{
	struct property **next, *oldprop;
	unsigned long flags;
	int rc, found = 0;

	rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop);
	if (rc)
		return rc;

	if (!newprop->name)
		return -EINVAL;

	oldprop = of_find_property(np, newprop->name, NULL);
	if (!oldprop)
		return of_add_property(np, newprop);

	raw_spin_lock_irqsave(&devtree_lock, flags);
	next = &np->properties;
	while (*next) {
		if (*next == oldprop) {
			/* found the node */
			newprop->next = oldprop->next;
			*next = newprop;
			oldprop->next = np->deadprops;
			np->deadprops = oldprop;
			found = 1;
			break;
		}
		next = &(*next)->next;
	}
	raw_spin_unlock_irqrestore(&devtree_lock, flags);

	if (!found)
		return -ENODEV;

#ifdef CONFIG_PROC_DEVICETREE
	/* try to add to proc as well if it was initialized */
	if (np->pde)
		proc_device_tree_update_prop(np->pde, newprop, oldprop);
#endif /* CONFIG_PROC_DEVICETREE */

	return 0;
}
static int __init update_target_node_from_overlay(
		struct device_node *target, struct device_node *overlay)
{
	struct property *prop;
	struct property *tprop;
	struct property *new_prop;
	int lenp = 0;
	int ret;

	for_each_property_of_node(overlay, prop) {
		/* Skip those we do not want to proceed */
		if (!strcmp(prop->name, "name") ||
			!strcmp(prop->name, "phandle") ||
			!strcmp(prop->name, "linux,phandle"))
				continue;
		tprop = of_find_property(target, prop->name, &lenp);
		if (!tprop) {
			ret = of_add_property(target, prop);
			if (ret < 0) {
				pr_err("Prop %s can not be added on node %s\n",
					prop->name, target->full_name);
				return ret;
			}
		} else {
			new_prop = __of_copy_property(prop, GFP_KERNEL);
			if (!new_prop) {
				pr_err("Prop %s can not be duplicated\n",
					prop->name);
				return -EINVAL;
			}
			ret = of_update_property(target, new_prop);
			if (ret < 0) {
				pr_err("Prop %s can not be updated on node %s\n",
					prop->name, target->full_name);
				return ret;
			}
		}
	}
	return 0;
}
Exemplo n.º 5
0
/**
 * omap_get_timer_dt - get a timer using device-tree
 * @match	- device-tree match structure for matching a device type
 * @property	- optional timer property to match
 *
 * Helper function to get a timer during early boot using device-tree for use
 * as kernel system timer. Optionally, the property argument can be used to
 * select a timer with a specific property. Once a timer is found then mark
 * the timer node in device-tree as disabled, to prevent the kernel from
 * registering this timer as a platform device and so no one else can use it.
 */
static struct device_node * __init omap_get_timer_dt(const struct of_device_id *match,
						     const char *property)
{
	struct device_node *np;

	for_each_matching_node(np, match) {
		if (!of_device_is_available(np))
			continue;

		if (property && !of_get_property(np, property, NULL))
			continue;

		if (!property && (of_get_property(np, "ti,timer-alwon", NULL) ||
				  of_get_property(np, "ti,timer-dsp", NULL) ||
				  of_get_property(np, "ti,timer-pwm", NULL) ||
				  of_get_property(np, "ti,timer-secure", NULL)))
			continue;

		of_add_property(np, &device_disabled);
		return np;
	}

	return NULL;
}
Exemplo n.º 6
0
static void disable_serial_gpio(void)
{
	struct device_node *np_tx, *np_rx, *np_tx_def, *np_rx_def;
	struct property *pp;
	static u32 pin_func_val;
	static struct property pin_func = {
		.name = "qcom,pin-func",
		.value = &pin_func_val,
		.length = sizeof(pin_func_val),
	};
	static struct property output_low = {
		.name = "output-low",
		.value = NULL,
		.length = 0,
	};
	static struct property bias_disable = {
		.name = "bias-disable",
		.value = NULL,
		.length = 0,
	};

	np_tx = of_find_node_by_path(
			"/soc/pinctrl@fd510000/msm_gpio_4");
	if (!np_tx) {
		pr_err("couldn't find msm_gpio_4 node\n");
		return;
	}

	np_rx = of_find_node_by_path(
			"/soc/pinctrl@fd510000/msm_gpio_5");
	if (!np_rx) {
		pr_err("couldn't find msm_gpio_5 node\n");
		goto err0;
	}

	of_update_property(np_tx, &pin_func);
	of_update_property(np_rx, &pin_func);

	np_tx_def = of_find_node_by_name(np_tx, "default");
	if (!np_tx_def) {
		pr_err("couldn't find msm_gpio_4_def node\n");
		goto err1;
	}

	np_rx_def = of_find_node_by_name(np_rx, "default");
	if (!np_rx_def) {
		pr_err("couldn't find msm_gpio_5_def node\n");
		goto err2;
	}

	of_add_property(np_tx_def, &output_low);

	pp = of_find_property(np_rx_def, "bias-pull-up", NULL);
	if (pp) {
		of_remove_property(np_rx_def, pp);
		of_add_property(np_rx_def, &bias_disable);
	}
	of_add_property(np_rx_def, &output_low);

	of_node_put(np_rx_def);
err2:
	of_node_put(np_tx_def);
err1:
	of_node_put(np_rx);
err0:
	of_node_put(np_tx);
	return;
}

static int __init init_console_setup(void)
{
	if (need_serial_console) {
		pr_info("Adding %s%d as preferred console\n",
			CONSOLE_NAME, CONSOLE_IX);
		add_preferred_console(CONSOLE_NAME,
			CONSOLE_IX,
			CONSOLE_OPTIONS);
	} else {
		struct device_node *np;
		static struct property serial_con_status = {
			.name = "status",
			.value = "disabled",
			.length = sizeof("disabled"),
		};

		np = of_find_node_by_path("/soc/serial@f991e000");
		if (!np) {
			pr_err("couldn't find /soc/serial@f991e000 node\n");
			return -EINVAL;
		}

		pr_info("disabling %s node", np->full_name);
		of_update_property(np, &serial_con_status);
		of_node_put(np);
		disable_serial_gpio();
	}

	return 0;
}
early_initcall(init_console_setup);