Beispiel #1
0
static void vio_fill_channel_info(struct mdesc_handle *hp, u64 mp,
				  struct vio_dev *vdev)
{
	u64 a;

	mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) {
		const u64 *chan_id;
		const u64 *irq;
		u64 target;

		target = mdesc_arc_target(hp, a);

		irq = mdesc_get_property(hp, target, "tx-ino", NULL);
		if (irq)
			vdev->tx_irq = sun4v_build_virq(cdev_cfg_handle, *irq);

		irq = mdesc_get_property(hp, target, "rx-ino", NULL);
		if (irq)
			vdev->rx_irq = sun4v_build_virq(cdev_cfg_handle, *irq);

		chan_id = mdesc_get_property(hp, target, "id", NULL);
		if (chan_id)
			vdev->channel_id = *chan_id;
	}
}
Beispiel #2
0
static struct vnet *vsw_get_vnet(struct mdesc_handle *hp,
				 u64 port_node,
				 u64 *handle)
{
	struct vnet *vp;
	struct vnet *iter;
	const u64 *local_mac = NULL;
	const u64 *cfghandle = NULL;
	u64 a;

	/* Get the parent virtual-network-switch macaddr and cfghandle */
	mdesc_for_each_arc(a, hp, port_node, MDESC_ARC_TYPE_BACK) {
		u64 target = mdesc_arc_target(hp, a);
		const char *name;

		name = mdesc_get_property(hp, target, "name", NULL);
		if (!name || strcmp(name, "virtual-network-switch"))
			continue;

		local_mac = mdesc_get_property(hp, target,
					       local_mac_prop, NULL);
		cfghandle = mdesc_get_property(hp, target,
					       cfg_handle_prop, NULL);
		break;
	}
Beispiel #3
0
static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
				      struct device *parent)
{
	const char *type, *compat, *bus_id_name;
	struct device_node *dp;
	struct vio_dev *vdev;
	int err, tlen, clen;
	const u64 *id, *cfg_handle;
	u64 a;

	type = mdesc_get_property(hp, mp, "device-type", &tlen);
	if (!type) {
		type = mdesc_get_property(hp, mp, "name", &tlen);
		if (!type) {
			type = mdesc_node_name(hp, mp);
			tlen = strlen(type) + 1;
		}
	}
	if (tlen > VIO_MAX_TYPE_LEN) {
		printk(KERN_ERR "VIO: Type string [%s] is too long.\n",
		       type);
		return NULL;
	}

	id = mdesc_get_property(hp, mp, "id", NULL);

	cfg_handle = NULL;
	mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) {
		u64 target;

		target = mdesc_arc_target(hp, a);
		cfg_handle = mdesc_get_property(hp, target,
						"cfg-handle", NULL);
		if (cfg_handle)
			break;
	}
Beispiel #4
0
static const u64 *parent_cfg_handle(struct mdesc_handle *hp, u64 node)
{
	const u64 *id;
	u64 a;

	id = NULL;
	mdesc_for_each_arc(a, hp, node, MDESC_ARC_TYPE_BACK) {
		u64 target;

		target = mdesc_arc_target(hp, a);
		id = mdesc_get_property(hp, target,
					"cfg-handle", NULL);
		if (id)
			break;
	}
Beispiel #5
0
static int __init sun4v_wdt_init(void)
{
	struct mdesc_handle *handle;
	u64 node;
	const u64 *value;
	int err = 0;
	unsigned long major = 1, minor = 1;

	/*
	 * There are 2 properties that can be set from the control
	 * domain for the watchdog.
	 * watchdog-resolution
	 * watchdog-max-timeout
	 *
	 * We can expect a handle to be returned otherwise something
	 * serious is wrong. Correct to return -ENODEV here.
	 */

	handle = mdesc_grab();
	if (!handle)
		return -ENODEV;

	node = mdesc_node_by_name(handle, MDESC_NODE_NULL, "platform");
	err = -ENODEV;
	if (node == MDESC_NODE_NULL)
		goto out_release;

	/*
	 * This is a safe way to validate if we are on the right
	 * platform.
	 */
	if (sun4v_hvapi_register(HV_GRP_CORE, major, &minor))
		goto out_hv_unreg;

	/* Allow value of watchdog-resolution up to 1s (default) */
	value = mdesc_get_property(handle, node, "watchdog-resolution", NULL);
	err = -EINVAL;
	if (value) {
		if (*value == 0 ||
		    *value > WDT_DEFAULT_RESOLUTION_MS)
			goto out_hv_unreg;
	}

	value = mdesc_get_property(handle, node, "watchdog-max-timeout", NULL);
	if (value) {
		/*
		 * If the property value (in ms) is smaller than
		 * min_timeout, return -EINVAL.
		 */
		if (*value < wdd.min_timeout * 1000)
			goto out_hv_unreg;

		/*
		 * If the property value is smaller than
		 * default max_timeout  then set watchdog max_timeout to
		 * the value of the property in seconds.
		 */
		if (*value < wdd.max_timeout * 1000)
			wdd.max_timeout = *value  / 1000;
	}

	watchdog_init_timeout(&wdd, timeout, NULL);

	watchdog_set_nowayout(&wdd, nowayout);

	err = watchdog_register_device(&wdd);
	if (err)
		goto out_hv_unreg;

	pr_info("initialized (timeout=%ds, nowayout=%d)\n",
		 wdd.timeout, nowayout);

	mdesc_release(handle);

	return 0;

out_hv_unreg:
	sun4v_hvapi_unregister(HV_GRP_CORE);

out_release:
	mdesc_release(handle);
	return err;
}