示例#1
0
static int exynos_cpufreq_probe(struct platform_device *pdev)
{
	struct device_node *cpus, *np;
	int ret = -EINVAL;

	exynos_info = kzalloc(sizeof(*exynos_info), GFP_KERNEL);
	if (!exynos_info)
		return -ENOMEM;

	exynos_info->dev = &pdev->dev;

	if (of_machine_is_compatible("samsung,exynos4210")) {
		exynos_info->type = EXYNOS_SOC_4210;
		ret = exynos4210_cpufreq_init(exynos_info);
	} else if (of_machine_is_compatible("samsung,exynos4212")) {
		exynos_info->type = EXYNOS_SOC_4212;
		ret = exynos4x12_cpufreq_init(exynos_info);
	} else if (of_machine_is_compatible("samsung,exynos4412")) {
		exynos_info->type = EXYNOS_SOC_4412;
		ret = exynos4x12_cpufreq_init(exynos_info);
	} else if (of_machine_is_compatible("samsung,exynos5250")) {
		exynos_info->type = EXYNOS_SOC_5250;
		ret = exynos5250_cpufreq_init(exynos_info);
	} else {
		pr_err("%s: Unknown SoC type\n", __func__);
		return -ENODEV;
	}

	if (ret)
		goto err_vdd_arm;

	if (exynos_info->set_freq == NULL) {
		dev_err(&pdev->dev, "No set_freq function (ERR)\n");
		goto err_vdd_arm;
	}

	arm_regulator = regulator_get(NULL, "vdd_arm");
	if (IS_ERR(arm_regulator)) {
		dev_err(&pdev->dev, "failed to get resource vdd_arm\n");
		goto err_vdd_arm;
	}

	/* Done here as we want to capture boot frequency */
	locking_frequency = clk_get_rate(exynos_info->cpu_clk) / 1000;

	ret = cpufreq_register_driver(&exynos_driver);
	if (ret)
		goto err_cpufreq_reg;

	cpus = of_find_node_by_path("/cpus");
	if (!cpus) {
		pr_err("failed to find cpus node\n");
		return 0;
	}

	np = of_get_next_child(cpus, NULL);
	if (!np) {
		pr_err("failed to find cpus child node\n");
		of_node_put(cpus);
		return 0;
	}

	if (of_find_property(np, "#cooling-cells", NULL)) {
		cdev = of_cpufreq_cooling_register(np,
						   cpu_present_mask);
		if (IS_ERR(cdev))
			pr_err("running cpufreq without cooling device: %ld\n",
			       PTR_ERR(cdev));
	}
	of_node_put(np);
	of_node_put(cpus);

	return 0;

err_cpufreq_reg:
	dev_err(&pdev->dev, "failed to register cpufreq driver\n");
	regulator_put(arm_regulator);
err_vdd_arm:
	kfree(exynos_info);
	return -EINVAL;
}
示例#2
0
static void __init kxtf9_init(void)
{
#ifdef CONFIG_ARM_OF
	struct device_node *node;
	const void *prop;
	int len = 0;

	node = of_find_node_by_path(DT_PATH_ACCELEROMETER);
	if (node) {
		prop = of_get_property(node,
				DT_PROP_ACCELEROMETER_AXIS_MAP_X, &len);
		if (prop && len)
			kxtf9_data.axis_map_x = *(u8 *)prop;
		prop = of_get_property(node,
				DT_PROP_ACCELEROMETER_AXIS_MAP_Y, &len);
		if (prop && len)
			kxtf9_data.axis_map_y = *(u8 *)prop;
		prop = of_get_property(node,
				DT_PROP_ACCELEROMETER_AXIS_MAP_Z, &len);
		if (prop && len)
			kxtf9_data.axis_map_z = *(u8 *)prop;
		prop = of_get_property(node,
				DT_PROP_ACCELEROMETER_NEGATE_X, &len);
		if (prop && len)
			kxtf9_data.negate_x = *(u8 *)prop;
		prop = of_get_property(node,
				DT_PROP_ACCELEROMETER_NEGATE_Y, &len);
		if (prop && len)
			kxtf9_data.negate_y = *(u8 *)prop;
		prop = of_get_property(node,
				DT_PROP_ACCELEROMETER_NEGATE_Z, &len);
		if (prop && len)
			kxtf9_data.negate_z = *(u8 *)prop;
		prop = of_get_property(node,
				DT_PROP_ACCELEROMETER_SENS_LOW, &len);
		if (prop && len)
				memcpy(kxtf9_data.sensitivity_low,
						(u8 *)prop, len);
		prop = of_get_property(node,
				DT_PROP_ACCELEROMETER_SENS_MEDIUM, &len);
		if (prop && len)
				memcpy(kxtf9_data.sensitivity_medium,
						(u8 *)prop, len);
		prop = of_get_property(node,
				DT_PROP_ACCELEROMETER_SENS_HIGH, &len);
		if (prop && len)
				memcpy(kxtf9_data.sensitivity_high,
						(u8 *)prop, len);
		of_node_put(node);
	}
#endif
    if (machine_is_tegra_daytona()) {
        kxtf9_data.gpio = TEGRA_KXTF9_INT_GPIO;
		kxtf9_data.negate_z = 0;
		/* Swap x and y */
		kxtf9_data.axis_map_x = 0;
		kxtf9_data.axis_map_y = 1;
		kxtf9_data.negate_y = 0;
		kxtf9_data.negate_x = 0;
    }
	else if (machine_is_etna()) {
        if (system_rev == 0x1100)
            kxtf9_data.gpio = TEGRA_KXTF9_INT_GPIO_ETNA_S1;
		kxtf9_data.negate_z = 1;
		/* Swap x and y */
		kxtf9_data.axis_map_x = 1;
		kxtf9_data.axis_map_y = 0;
		/* For P2A and above */
		if (HWREV_TYPE_IS_FINAL(system_rev) ||
			(HWREV_TYPE_IS_PORTABLE(system_rev) &&
			HWREV_REV(system_rev) >= HWREV_REV_2)) {
			kxtf9_data.negate_y = 0;
			kxtf9_data.negate_x = 0;
		}
	}
	else if (machine_is_sunfire()) {
		kxtf9_data.negate_z = 1;
		/* Swap x and y */
		kxtf9_data.axis_map_x = 1;
		kxtf9_data.axis_map_y = 0;

		kxtf9_data.negate_y = 0;
		kxtf9_data.negate_x = 0;
	}	
	gpio_request(kxtf9_data.gpio, "kxtf9 accelerometer int");
	gpio_direction_input(kxtf9_data.gpio);
//	omap_cfg_reg(AF9_34XX_GPIO22_DOWN);
}
示例#3
0
void rtas_progress(char *s, unsigned short hex)
{
	struct device_node *root;
	int width;
	const __be32 *p;
	char *os;
	static int display_character, set_indicator;
	static int display_width, display_lines, form_feed;
	static const int *row_width;
	static DEFINE_SPINLOCK(progress_lock);
	static int current_line;
	static int pending_newline = 0;  /* did last write end with unprinted newline? */

	if (!rtas.base)
		return;

	if (display_width == 0) {
		display_width = 0x10;
		if ((root = of_find_node_by_path("/rtas"))) {
			if ((p = of_get_property(root,
					"ibm,display-line-length", NULL)))
				display_width = be32_to_cpu(*p);
			if ((p = of_get_property(root,
					"ibm,form-feed", NULL)))
				form_feed = be32_to_cpu(*p);
			if ((p = of_get_property(root,
					"ibm,display-number-of-lines", NULL)))
				display_lines = be32_to_cpu(*p);
			row_width = of_get_property(root,
					"ibm,display-truncation-length", NULL);
			of_node_put(root);
		}
		display_character = rtas_token("display-character");
		set_indicator = rtas_token("set-indicator");
	}

	if (display_character == RTAS_UNKNOWN_SERVICE) {
		/* use hex display if available */
		if (set_indicator != RTAS_UNKNOWN_SERVICE)
			rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
		return;
	}

	spin_lock(&progress_lock);

	/*
	 * Last write ended with newline, but we didn't print it since
	 * it would just clear the bottom line of output. Print it now
	 * instead.
	 *
	 * If no newline is pending and form feed is supported, clear the
	 * display with a form feed; otherwise, print a CR to start output
	 * at the beginning of the line.
	 */
	if (pending_newline) {
		rtas_call(display_character, 1, 1, NULL, '\r');
		rtas_call(display_character, 1, 1, NULL, '\n');
		pending_newline = 0;
	} else {
		current_line = 0;
		if (form_feed)
			rtas_call(display_character, 1, 1, NULL,
				  (char)form_feed);
		else
			rtas_call(display_character, 1, 1, NULL, '\r');
	}
 
	if (row_width)
		width = row_width[current_line];
	else
		width = display_width;
	os = s;
	while (*os) {
		if (*os == '\n' || *os == '\r') {
			/* If newline is the last character, save it
			 * until next call to avoid bumping up the
			 * display output.
			 */
			if (*os == '\n' && !os[1]) {
				pending_newline = 1;
				current_line++;
				if (current_line > display_lines-1)
					current_line = display_lines-1;
				spin_unlock(&progress_lock);
				return;
			}
 
			/* RTAS wants CR-LF, not just LF */
 
			if (*os == '\n') {
				rtas_call(display_character, 1, 1, NULL, '\r');
				rtas_call(display_character, 1, 1, NULL, '\n');
			} else {
				/* CR might be used to re-draw a line, so we'll
				 * leave it alone and not add LF.
				 */
				rtas_call(display_character, 1, 1, NULL, *os);
			}
 
			if (row_width)
				width = row_width[current_line];
			else
				width = display_width;
		} else {
			width--;
			rtas_call(display_character, 1, 1, NULL, *os);
		}
 
		os++;
 
		/* if we overwrite the screen length */
		if (width <= 0)
			while ((*os != 0) && (*os != '\n') && (*os != '\r'))
				os++;
	}
 
	spin_unlock(&progress_lock);
}
示例#4
0
static void __init cpcap_of_init(void)
{
	int size, unit_size, i, count;
	struct device_node *node;
	const void *prop;
	struct device_node *bp_node;
	const void *bp_prop;
	char *cpcap_bp_model = "CDMA";
	
	static struct omap_spi_init_entry cpcap_spiinit_data[] = {  
		{CPCAP_REG_SDVSPLL,  0xDB04}, 
		{CPCAP_REG_S4C1, 0x4034},
		{CPCAP_REG_S4C2,  0x3434},
         {CPCAP_REG_MDLC,  0x0000}   } ;
	static struct omap_rgt_init_entry cpcap_reginitmode_data[] = {  
          {CPCAP_VCSI,     1800000,    1800000,    0x8,    0x00,    0x01,     0x01},
          {CPCAP_VDIG,    1875000,    1875000,    0x1,    0x01,    0x00,    0x01},
          {CPCAP_VRF1,    2775000,    2775000,    0x9,    0x01,    0x00,    0x01},
          {CPCAP_VRF2,    2775000,    2775000,    0x9,    0x01,    0x00,    0x01},
          {CPCAP_VRFREF,    2775000,    2775000,    0x9,    0x01,    0x00,    0x01},
          {CPCAP_VSIM,    1800000,    2900000,    0x9,    0x00,    0x00,    0x00},
          {CPCAP_VSIMCARD,    1800000,    2900000,    0x9,    0x00,    0x00,    0x00}  } ;
	static struct omap_rgt_mode_entry cpcap_regmode_data[] = {  
          {CPCAP_VCSI,        0x0043},
          {CPCAP_VDIG,        0x0082},
          {CPCAP_VRF1,        0x0024},
          {CPCAP_VRF2,        0x0001},
          {CPCAP_VRFREF,        0x0023},
          {CPCAP_VAUDIO,      0x0014},
	     {CPCAP_VHVIO,	      0x0012},
	     {CPCAP_VSIM,		0x0022},
	     {CPCAP_VSIMCARD,	0x0480}  } ;			
	static struct omap_rgt_mode_entry cpcap_regoffmode_data[] = {  {CPCAP_VCSI,  0x0041 } };
					
	bp_node = of_find_node_by_path(DT_PATH_CHOSEN);
	if (bp_node) {
		bp_prop = of_get_property(bp_node, DT_PROP_CHOSEN_BP, NULL);
		if (bp_prop)
			cpcap_bp_model = (char *)bp_prop;

		of_node_put(bp_node);
	}

	if (strcmp(cpcap_bp_model, "UMTS") >= 0)
		mapphone_cpcap_data.is_umts = 1;

	count = 4;
	printk(KERN_INFO "cpcap init size = %d\n", count);
	for (i = 0; i < count; i++)
		cpcap_spi_init((struct omap_spi_init_entry *)&cpcap_spiinit_data[i]);

	count = 7;
	printk(KERN_INFO "cpcap init size = %d\n", count);
	for (i = 0; i < count; i++)
		regulator_init((struct omap_rgt_init_entry *)&cpcap_reginitmode_data[i]);

	count = 9;
	printk(KERN_INFO "cpcap init size = %d\n", count);
	for (i = 0; i < count; i++)
		regulator_mode_init((struct omap_rgt_mode_entry *)&cpcap_regmode_data[i]);

	count = 1;
	printk(KERN_INFO "cpcap init size = %d\n", count);
	for (i = 0; i < count; i++)
		regulator_off_mode_init((struct omap_rgt_mode_entry *)&cpcap_regoffmode_data[i]);

	return;
}
示例#5
0
void __init opal_sys_param_init(void)
{
	struct device_node *sysparam;
	struct param_attr *attr;
	u32 *id, *size;
	int count, i;
	u8 *perm;

	if (!opal_kobj) {
		pr_warn("SYSPARAM: opal kobject is not available\n");
		goto out;
	}

	sysparam_kobj = kobject_create_and_add("sysparams", opal_kobj);
	if (!sysparam_kobj) {
		pr_err("SYSPARAM: Failed to create sysparam kobject\n");
		goto out;
	}

	/* Allocate big enough buffer for any get/set transactions */
	param_data_buf = kzalloc(MAX_PARAM_DATA_LEN, GFP_KERNEL);
	if (!param_data_buf) {
		pr_err("SYSPARAM: Failed to allocate memory for param data "
				"buf\n");
		goto out_kobj_put;
	}

	sysparam = of_find_node_by_path("/ibm,opal/sysparams");
	if (!sysparam) {
		pr_err("SYSPARAM: Opal sysparam node not found\n");
		goto out_param_buf;
	}

	if (!of_device_is_compatible(sysparam, "ibm,opal-sysparams")) {
		pr_err("SYSPARAM: Opal sysparam node not compatible\n");
		goto out_node_put;
	}

	/* Number of parameters exposed through DT */
	count = of_property_count_strings(sysparam, "param-name");
	if (count < 0) {
		pr_err("SYSPARAM: No string found of property param-name in "
				"the node %s\n", sysparam->name);
		goto out_node_put;
	}

	id = kzalloc(sizeof(*id) * count, GFP_KERNEL);
	if (!id) {
		pr_err("SYSPARAM: Failed to allocate memory to read parameter "
				"id\n");
		goto out_node_put;
	}

	size = kzalloc(sizeof(*size) * count, GFP_KERNEL);
	if (!size) {
		pr_err("SYSPARAM: Failed to allocate memory to read parameter "
				"size\n");
		goto out_free_id;
	}

	perm = kzalloc(sizeof(*perm) * count, GFP_KERNEL);
	if (!perm) {
		pr_err("SYSPARAM: Failed to allocate memory to read supported "
				"action on the parameter");
		goto out_free_size;
	}

	if (of_property_read_u32_array(sysparam, "param-id", id, count)) {
		pr_err("SYSPARAM: Missing property param-id in the DT\n");
		goto out_free_perm;
	}

	if (of_property_read_u32_array(sysparam, "param-len", size, count)) {
		pr_err("SYSPARAM: Missing propery param-len in the DT\n");
		goto out_free_perm;
	}


	if (of_property_read_u8_array(sysparam, "param-perm", perm, count)) {
		pr_err("SYSPARAM: Missing propery param-perm in the DT\n");
		goto out_free_perm;
	}

	attr = kzalloc(sizeof(*attr) * count, GFP_KERNEL);
	if (!attr) {
		pr_err("SYSPARAM: Failed to allocate memory for parameter "
				"attributes\n");
		goto out_free_perm;
	}

	/* For each of the parameters, populate the parameter attributes */
	for (i = 0; i < count; i++) {
		sysfs_attr_init(&attr[i].kobj_attr.attr);
		attr[i].param_id = id[i];
		attr[i].param_size = size[i];
		if (of_property_read_string_index(sysparam, "param-name", i,
				&attr[i].kobj_attr.attr.name))
			continue;

		/* If the parameter is read-only or read-write */
		switch (perm[i] & 3) {
		case OPAL_SYSPARAM_READ:
			attr[i].kobj_attr.attr.mode = S_IRUGO;
			break;
		case OPAL_SYSPARAM_WRITE:
			attr[i].kobj_attr.attr.mode = S_IWUGO;
			break;
		case OPAL_SYSPARAM_RW:
			attr[i].kobj_attr.attr.mode = S_IRUGO | S_IWUGO;
			break;
		default:
			break;
		}

		attr[i].kobj_attr.show = sys_param_show;
		attr[i].kobj_attr.store = sys_param_store;

		if (sysfs_create_file(sysparam_kobj, &attr[i].kobj_attr.attr)) {
			pr_err("SYSPARAM: Failed to create sysfs file %s\n",
					attr[i].kobj_attr.attr.name);
			goto out_free_attr;
		}
	}

	kfree(perm);
	kfree(size);
	kfree(id);
	of_node_put(sysparam);
	return;

out_free_attr:
	kfree(attr);
out_free_perm:
	kfree(perm);
out_free_size:
	kfree(size);
out_free_id:
	kfree(id);
out_node_put:
	of_node_put(sysparam);
out_param_buf:
	kfree(param_data_buf);
out_kobj_put:
	kobject_put(sysparam_kobj);
out:
	return;
}
示例#6
0
/* Function Description: Initialize i2c child device.
 * Return: None.
 */
static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child,
				   struct i2c_child_t *pchild)
{
	int len, i, tbls_size = 0;
	struct device_node *dp = edev_child->prom_node;
	const void *pval;

	/* Get device address. */
	pval = of_get_property(dp, "reg", &len);
	memcpy(&pchild->addr, pval, len);

	/* Get tables property.  Read firmware temperature tables. */
	pval = of_get_property(dp, "translation", &len);
	if (pval && len > 0) {
		memcpy(pchild->tblprop_array, pval, len);
                pchild->total_tbls = len / sizeof(struct pcf8584_tblprop);
		for (i = 0; i < pchild->total_tbls; i++) {
			if ((pchild->tblprop_array[i].size + pchild->tblprop_array[i].offset) > tbls_size) {
				tbls_size = pchild->tblprop_array[i].size + pchild->tblprop_array[i].offset;
			}
		}

                pchild->tables = kmalloc(tbls_size, GFP_KERNEL);
		if (pchild->tables == NULL){
			printk("envctrl: Failed to allocate table.\n");
			return;
		}
		pval = of_get_property(dp, "tables", &len);
                if (!pval || len <= 0) {
			printk("envctrl: Failed to get table.\n");
			return;
		}
		memcpy(pchild->tables, pval, len);
	}

	/* SPARCengine ASM Reference Manual (ref. SMI doc 805-7581-04)
	 * sections 2.5, 3.5, 4.5 state node 0x70 for CP1400/1500 is
	 * "For Factory Use Only."
	 *
	 * We ignore the node on these platforms by assigning the
	 * 'NULL' monitor type.
	 */
	if (ENVCTRL_CPCI_IGNORED_NODE == pchild->addr) {
		struct device_node *root_node;
		int len;

		root_node = of_find_node_by_path("/");
		if (!strcmp(root_node->name, "SUNW,UltraSPARC-IIi-cEngine")) {
			for (len = 0; len < PCF8584_MAX_CHANNELS; ++len) {
				pchild->mon_type[len] = ENVCTRL_NOMON;
			}
			return;
		}
	}

	/* Get the monitor channels. */
	pval = of_get_property(dp, "channels-in-use", &len);
	memcpy(pchild->chnl_array, pval, len);
	pchild->total_chnls = len / sizeof(struct pcf8584_channel);

	for (i = 0; i < pchild->total_chnls; i++) {
		switch (pchild->chnl_array[i].type) {
		case PCF8584_TEMP_TYPE:
			envctrl_init_adc(pchild, dp);
			break;

		case PCF8584_GLOBALADDR_TYPE:
			envctrl_init_globaladdr(pchild);
			i = pchild->total_chnls;
			break;

		case PCF8584_FANSTAT_TYPE:
			envctrl_init_fanstat(pchild);
			i = pchild->total_chnls;
			break;

		case PCF8584_VOLTAGE_TYPE:
			if (pchild->i2ctype == I2C_ADC) {
				envctrl_init_adc(pchild,dp);
			} else {
				envctrl_init_voltage_status(pchild);
			}
			i = pchild->total_chnls;
			break;

		default:
			break;
		};
	}
}
static int vib_of_init(struct vibrator *vib, int vib_nr)
{
	struct device_node *node;
	const void *prop = NULL;
	const char *name;
	int len = 0 ;
	char dt_path_vib[sizeof(DT_PATH_VIB) + 3];

	snprintf(dt_path_vib, sizeof(DT_PATH_VIB) + 2, "%s%1d",
		DT_PATH_VIB, vib_nr % MAX_VIBS);
	node = of_find_node_by_path(dt_path_vib);
	if (!node)
		return -ENODEV;

	if (of_property_read_u32(node, DT_PROP_VIB_TYPE, &vib->type)) {
		zfprintk("DT vibrator type read error\n");
		return -ENODEV;
	}
	if ((vib->type != VIB_TYPE_GENENIC_ROTARY)
		&& (vib->type != VIB_TYPE_GENENIC_LINEAR))
		return -ENODEV;

	if (of_property_read_u32_array(node, VIB_EN,
					(u32 *)(&vib->ctrl.vib_en.of), 4)) {
		zfprintk("DT vibrator VIB_EN settings read error\n");
		return -ENODEV;
	}
	vib->ctrl.vib_en.name = VIB_EN;
	vib->ctrl.vib_en.signal_type = SIGNAL_ENABLE;
	if (vib_signal_init(&vib->ctrl.vib_en)) {
		zfprintk("vib_en init failed\n");
		return -ENODEV;
	}
	prop = of_get_property(node, "pwm", &len);
	if (prop && len) {
		int j = len / sizeof(struct vib_pwm);
		if (j > MAX_PWMS)
			j = MAX_PWMS;
		if (of_property_read_u32_array(node, "pwm",
					(u32 *)(&vib->ctrl.vib_pwm), j*4)) {
			zfprintk("DT vibrator PWM settings read error\n");
			return -ENODEV;
		}
	} else {
		zfprintk("pwm not found in %s\n", dt_path_vib);
		return -ENODEV;
	}

	if (of_property_read_u32_array(node, VIB_DIR,
					(u32 *)(&vib->ctrl.vib_dir.of), 4)) {
		zfprintk("DT vibrator VIB_DIR settings read error\n");
		if (vib->type == VIB_TYPE_GENENIC_LINEAR) {
			zfprintk("vib_dir not found in %s\n", dt_path_vib);
			return -ENODEV;
		}
	} else {
		vib->ctrl.vib_dir.name = VIB_DIR;
		vib->ctrl.vib_dir.signal_type = SIGNAL_DIRECTION;
		if (vib_signal_init(&vib->ctrl.vib_dir)) {
			zfprintk("vib_dir init failed\n");
			return -ENODEV;
		}
	}

	if (!of_property_read_string(node, "regulator", &name)) {
		strlcpy(vib->reg.name, name, sizeof(vib->reg.name));
		of_property_read_u32(node, "deferred_off",
					&vib->reg.deferred_off);
		vib->reg.volt[0].time =  MAX_TIMEOUT;
		vib->reg.volt[0].min_uV = 2800000;
		vib->reg.volt[0].max_uV = 2800000;

		prop = of_get_property(node, "voltage", &len);
		if (prop && len) {
			int j = len / sizeof(struct vib_voltage);
			if (j > MAX_VOLT)
				j = MAX_VOLT;
			of_property_read_u32_array(node, "voltage",
					(u32 *)(&vib->reg.volt), j*3);
		}
	}

	if (of_property_read_u32(node, "min", &vib->min_us))
		vib->min_us = MIN_TIMEOUT;

	if (of_property_read_u32(node, "max", &vib->max_us))
		vib->max_us = MAX_TIMEOUT;
	of_node_put(node);
	return 0;
}
static void __init sc8830_init_late(void)
{
	of_platform_populate(of_find_node_by_path("/sprd-audio-devices"),
			of_sprd_late_bus_match_table, NULL, NULL);
}
示例#9
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);
示例#10
0
static int d7s_probe(struct platform_device *op)
{
	struct device_node *opts;
	int err = -EINVAL;
	struct d7s *p;
	u8 regs;

	if (d7s_device)
		goto out;

	p = kzalloc(sizeof(*p), GFP_KERNEL);
	err = -ENOMEM;
	if (!p)
		goto out;

	p->regs = of_ioremap(&op->resource[0], 0, sizeof(u8), "d7s");
	if (!p->regs) {
		printk(KERN_ERR PFX "Cannot map chip registers\n");
		goto out_free;
	}

	err = misc_register(&d7s_miscdev);
	if (err) {
		printk(KERN_ERR PFX "Unable to acquire miscdevice minor %i\n",
		       D7S_MINOR);
		goto out_iounmap;
	}

	/* OBP option "d7s-flipped?" is honored as default for the
	 * device, and reset default when detached
	 */
	regs = readb(p->regs);
	opts = of_find_node_by_path("/options");
	if (opts &&
	    of_get_property(opts, "d7s-flipped?", NULL))
		p->flipped = true;

	if (p->flipped)
		regs |= D7S_FLIP;
	else
		regs &= ~D7S_FLIP;

	writeb(regs,  p->regs);

	printk(KERN_INFO PFX "7-Segment Display%s at [%s:0x%llx] %s\n",
	       op->dev.of_node->full_name,
	       (regs & D7S_FLIP) ? " (FLIPPED)" : "",
	       op->resource[0].start,
	       sol_compat ? "in sol_compat mode" : "");

	dev_set_drvdata(&op->dev, p);
	d7s_device = p;
	err = 0;

out:
	return err;

out_iounmap:
	of_iounmap(&op->resource[0], p->regs, sizeof(u8));

out_free:
	kfree(p);
	goto out;
}
static int bootlog_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct bootlog_platform_data *pdata = pdev->dev.platform_data;
	struct device_node *node;

	unsigned long paddr, size;
	char *buffer, *token;
	int err;

	node = of_find_node_by_path("/chosen");
	if (node == NULL) {
		pr_err("%s: of_find_node_by_path failed\n", __func__);
		return -EINVAL;
	}

	if (!pdata) {
		err = bootlog_parse_dt(dev, node);
		if (err < 0)
			return err;

		pdata = pdev->dev.platform_data;
		if (!pdata){
			pr_err("%s: failed to read platform_data's pointer\n", __func__);
			return 0;
		}
	}

	paddr = pdata->paddr;
	size = pdata->size;

	if (!request_mem_region(paddr, size, "persistent_ram")) {
		pr_err("request mem region (0x%llx@0x%llx) failed\n",
				(unsigned long long)size,
				(unsigned long long)paddr);
		return -EINVAL;
	}

	bootlog_buf = (struct log_buffer *)ioremap(paddr, size);
	if (bootlog_buf == NULL) {
		pr_info("%s: failed to map memory\n", __func__);
		return 0;
	}

	if (bootlog_buf->sig != LOGBUF_SIG) {
		pr_info("bootlog_buf->sig is not valid (%x)\n",
				bootlog_buf->sig);
		return -EINVAL;
	}

	pr_info("%s: start %d\n", __func__, bootlog_buf->start);
	pr_info("%s: size %d\n", __func__, bootlog_buf->size);
	pr_info("-------------------------------------------------\n");
	pr_info("below logs are got from bootloader\n");
	pr_info("-------------------------------------------------\n");
	pr_info("\n");

	buffer = (char *)bootlog_buf->data;
	buffer[pdata->size - sizeof(struct log_buffer) - 1] = '\0';

	while (1) {
		token = strsep(&buffer, "\n");
		if (!token) {
			pr_info("%s: token %p\n", __func__, token);
			break;
		}
		pr_info("%s\n", token);
	}

	pr_info("-------------------------------------------------\n");

	iounmap(bootlog_buf);
	release_region(paddr, size);

	return 0;
}
示例#12
0
static int initialize_i2c_bus_info
(
	int bus_num,
	struct i2c_board_info *board_info,
	int info_size,
	struct i2c_board_info *master_board_info,
	int master_info_size
)
{
	int dev_cnt = 0;
	struct device_node *bus_node;
	const void *feat_prop;
	char *device_names;
	char dev_name[I2C_MAX_DEV_NAME_LEN];
	int device_name_len, i, j;
	struct i2c_board_info *master_entry;
	char prop_name[I2C_BUS_PROP_NAME_LEN];

	j = 0;

	bus_node = of_find_node_by_path(DT_PATH_I2C);
	if (bus_node == NULL || board_info == NULL)
		return dev_cnt;

	snprintf(prop_name, I2C_BUS_PROP_NAME_LEN,
		"bus%1ddevices", bus_num);

	feat_prop = of_get_property(bus_node,
			prop_name, NULL);
	if (NULL != feat_prop) {
		device_names = (char *)feat_prop;
		printk(KERN_INFO
			"I2C-%d devices: %s\n", bus_num, device_names);
		device_name_len = strlen(device_names);

		memset(dev_name, 0x0, I2C_MAX_DEV_NAME_LEN);

		for (i = 0; i < device_name_len; i++) {

			if (device_names[i] != '\0' &&
				device_names[i] != ',')
				dev_name[j++] = device_names[i];
			/* parse for ',' in string */
			if (device_names[i] == ',' ||
				(i == device_name_len-1)) {

				if (dev_cnt < info_size) {
					master_entry =
						get_board_info(dev_name,
							bus_num,
							master_board_info,
							master_info_size);
					if (master_entry != NULL) {
						memcpy(
							&board_info[dev_cnt++],
							master_entry,
							sizeof(
							struct i2c_board_info));
						printk(KERN_INFO
							"%s -> I2C bus-%d\n",
							master_entry->type,
							bus_num);

					}
					j = 0;
					memset(
							dev_name,
							0x0,
							I2C_MAX_DEV_NAME_LEN);
				}
			}
		}
	}
	return dev_cnt;
}
示例#13
0
void __init mapphone_touch_init(struct i2c_board_info *i2c_info)
{
	int err = 0;
	struct device_node *dtnodes[5] = {
		NULL, NULL, NULL, NULL, NULL};
	struct touch_platform_data *tpdata = NULL;

	printk(KERN_INFO "%s: Starting touch init...\n", __func__);

	if (i2c_info == NULL) {
		printk(KERN_ERR "%s: NULL i2c_board_info pointer passed.\n",
			__func__);
		goto touch_init_fail;
	}

	dtnodes[0] = of_find_node_by_path("/System@0/I2C@0/Touch@0");
	if (dtnodes[0] == NULL) {
		/* Normally this is a fatal error */
		mapphone_legacy_qtouch_init(i2c_info); /* Legacy support */
		mapphone_legacy_qtouch_gpio_init(i2c_info);
		mapphone_legacy_qtouch_vkeys_init();  /* Legacy support */
		goto legacy_qtouch_complete;  /* Legacy support */
	}

	tpdata = kzalloc(sizeof(struct touch_platform_data), GFP_KERNEL);
	if (tpdata == NULL) {
		printk(KERN_ERR "%s: Unable to create platform data.\n",
			__func__);
		err = -ENOMEM;
		goto touch_init_fail;
	}

	dtnodes[1] = of_find_node_by_path("/System@0/I2C@0/Touch@0/Driver@0");
	if (dtnodes[1] == NULL) {
		printk(KERN_ERR "%s: Driver@0 node is missing.\n", __func__);
		err = -ENOENT;
		goto touch_init_fail;
	} else {
		err = mapphone_touch_driver_settings_init(tpdata, dtnodes[1],
				i2c_info);
		if (err < 0)
			goto touch_init_fail;
	}

	dtnodes[2] = of_find_node_by_path("/System@0/I2C@0/Touch@0/IC@0");
	if (dtnodes[2] == NULL) {
		printk(KERN_ERR "%s: IC@0 node is missing.\n", __func__);
		err = -ENOENT;
		goto touch_init_fail;
	} else {
		err = mapphone_touch_ic_settings_init(tpdata, dtnodes[2],
				i2c_info);
		if (err < 0)
			goto touch_init_fail;
	}

	dtnodes[3] = of_find_node_by_path("/System@0/I2C@0/Touch@0/Firmware@0");
	if (dtnodes[3] == NULL) {
		printk(KERN_ERR "%s: Firmware@0 node is missing.\n", __func__);
		err = -ENOENT;
		goto touch_init_fail;
	} else {
		err = mapphone_touch_firmware_init(tpdata, dtnodes[3]);
		if (err < 0)
			goto touch_init_fail;
	}

	dtnodes[4] =
		of_find_node_by_path("/System@0/I2C@0/Touch@0/Framework@0");
	if (dtnodes[4] == NULL) {
		printk(KERN_ERR "%s: Framework@0 node is missing.\n", __func__);
		err = -ENOENT;
		goto touch_init_fail;
	} else {
		err = mapphone_touch_framework_settings_init(
			tpdata, dtnodes[4]);
		if (err < 0)
			goto touch_init_fail;
	}

	err = mapphone_touch_gpio_init(i2c_info);
	if (err < 0)
		goto touch_init_fail;

	if (tpdata->frmwrk->enable_vkeys) {
		err = mapphone_touch_vkeys_init(dtnodes[4], i2c_info);
		if (err < 0)
			goto touch_init_fail;
	}

	tpdata->hw_reset = mapphone_touch_reset;
	tpdata->hw_recov = mapphone_touch_recovery;
	tpdata->irq_stat = mapphone_touch_irq_status;

	i2c_info->platform_data = tpdata;
	goto touch_init_pass;

touch_init_fail:
	mapphone_touch_free(tpdata, &dtnodes[0]);
	printk(KERN_ERR
		"%s: Touch init failed for %s driver with error code %d.\n",
		__func__, i2c_info->type, err);
	return;

touch_init_pass:
	printk(KERN_INFO "%s: Touch init successful for %s driver.\n",
		__func__, i2c_info->type);
legacy_qtouch_complete:  /* Legacy support */
	return;
}
示例#14
0
static void __init mapphone_legacy_qtouch_init(struct i2c_board_info *i2c_info)
{
	int len = 0;
	struct device_node *touch_node;
	const void *touch_prop;
	const uint32_t *touch_val;

	printk(KERN_INFO "%s: Selecting legacy qtouch driver.\n",
		__func__);

	touch_node = of_find_node_by_path(DT_PATH_TOUCH);
	if (touch_node == NULL) {
		printk(KERN_INFO "%s: No device tree data available.\n",
			__func__);
		goto mapphone_legacy_qtouch_init_ret;
	}

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_KEYMAP, &len);
	if (touch_prop && len && (0 == len % sizeof(struct vkey))) {
			mapphone_legacy_qtouch_data.vkeys.count =
				len / sizeof(struct vkey);
			mapphone_legacy_qtouch_data.vkeys.keys =
				(struct vkey *)touch_prop;
	}

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_I2C_ADDRESS,
		&len);
	if (touch_prop)
		i2c_info->addr = *((int *)touch_prop);
	else
		i2c_info->addr = 0x11;

	touch_prop = of_get_property(touch_node,
		DT_PROP_TOUCH_BOOT_I2C_ADDRESS, &len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.boot_i2c_addr =
			*((int *)touch_prop);
	}

	touch_val = of_get_property(touch_node, DT_PROP_TOUCH_CHECKSUM, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.nv_checksum = *touch_val;

	touch_val = of_get_property(touch_node, DT_PROP_TOUCH_FLAGS, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.flags = *touch_val;

	touch_val = of_get_property(touch_node, DT_PROP_TOUCH_ABS_MIN_X, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.abs_min_x = *touch_val;

	touch_val = of_get_property(touch_node, DT_PROP_TOUCH_ABS_MAX_X, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.abs_max_x = *touch_val;

	touch_val = of_get_property(touch_node, DT_PROP_TOUCH_ABS_MIN_Y, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.abs_min_y = *touch_val;

	touch_val = of_get_property(touch_node, DT_PROP_TOUCH_ABS_MAX_Y, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.abs_max_y = *touch_val;

	touch_val = of_get_property(touch_node, DT_PROP_TOUCH_ABS_MIN_P, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.abs_min_p = *touch_val;

	touch_val = of_get_property(touch_node, DT_PROP_TOUCH_ABS_MAX_P, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.abs_max_p = *touch_val;

	touch_val = of_get_property(touch_node, DT_PROP_TOUCH_ABS_MIN_W, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.abs_min_w = *touch_val;

	touch_val = of_get_property(touch_node, DT_PROP_TOUCH_ABS_MAX_W, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.abs_max_w = *touch_val;

	touch_val = of_get_property(touch_node, DT_PROP_TOUCH_FUZZ_X, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.fuzz_x = *touch_val;

	touch_val = of_get_property(touch_node, DT_PROP_TOUCH_FUZZ_Y, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.fuzz_y = *touch_val;

	touch_val = of_get_property(touch_node, DT_PROP_TOUCH_FUZZ_P, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.fuzz_p = *touch_val;

	touch_val = of_get_property(touch_node, DT_PROP_TOUCH_FUZZ_W, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.fuzz_w = *touch_val;

	touch_val = of_get_property(touch_node, DT_PROP_TOUCH_X_DELTA, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.x_delta = *touch_val;

	touch_val = of_get_property(touch_node, DT_PROP_TOUCH_Y_DELTA, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.y_delta = *touch_val;

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_T15, &len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.key_array.cfg =
			(struct qtm_touch_keyarray_cfg *)touch_prop;
	}

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_KEY_ARRAY_MAP,
		&len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.key_array.keys =
			(struct qtouch_key *)touch_prop;
	}

	touch_val = of_get_property(touch_node,
		DT_PROP_TOUCH_KEY_ARRAY_COUNT, &len);
	if (touch_val && len)
		mapphone_legacy_qtouch_data.key_array.num_keys = *touch_val;

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_T7, &len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.power_cfg =
			*(struct qtm_gen_power_cfg *)touch_prop;
	}

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_T8, &len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.acquire_cfg =
			*(struct qtm_gen_acquire_cfg *)touch_prop;
	}

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_T9, &len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.multi_touch_cfg =
			*(struct qtm_touch_multi_cfg *)touch_prop;
	}

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_T17, &len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.linear_tbl_cfg =
			*(struct qtm_proci_linear_tbl_cfg *)touch_prop;
	}

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_T18, &len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.comms_config_cfg =
			*(struct spt_comms_config_cfg *)touch_prop;
	}

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_T19, &len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.gpio_pwm_cfg =
			*(struct qtm_spt_gpio_pwm_cfg *)touch_prop;
	}


	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_T20, &len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.grip_suppression_cfg =
		*(struct qtm_proci_grip_suppression_cfg *)touch_prop;
	}

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_T22, &len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.noise_suppression_cfg =
			*(struct qtm_procg_noise_suppression_cfg *)touch_prop;
	}

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_T23, &len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.touch_proximity_cfg =
			*(struct qtm_touch_proximity_cfg *)touch_prop;
	}

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_T24, &len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.one_touch_gesture_proc_cfg =
		*(struct qtm_proci_one_touch_gesture_proc_cfg *)touch_prop;
	}

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_T25, &len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.self_test_cfg =
			*(struct qtm_spt_self_test_cfg *)touch_prop;
	}

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_T27, &len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.two_touch_gesture_proc_cfg =
		*(struct qtm_proci_two_touch_gesture_proc_cfg *)touch_prop;
	}

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_T28, &len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.cte_config_cfg =
			*(struct qtm_spt_cte_config_cfg *)touch_prop;
	}

	touch_prop = of_get_property(touch_node, DT_PROP_TOUCH_T36, &len);
	if (touch_prop) {
		mapphone_legacy_qtouch_data.noise1_suppression_cfg =
			*(struct qtm_proci_noise1_suppression_cfg *)touch_prop;
	}

	of_node_put(touch_node);

	strncpy((char *) &i2c_info->type, QTOUCH_TS_NAME, I2C_NAME_SIZE);
	i2c_info->type[I2C_NAME_SIZE-1] = '\0';

	i2c_info->platform_data = &mapphone_legacy_qtouch_data;

mapphone_legacy_qtouch_init_ret:
	return;
}
示例#15
0
void sunserial_console_termios(struct console *con, struct device_node *uart_dp)
{
	const char *mode, *s;
	char mode_prop[] = "ttyX-mode";
	int baud, bits, stop, cflag;
	char parity;

	if (!strcmp(uart_dp->name, "rsc") ||
	    !strcmp(uart_dp->name, "rsc-console") ||
	    !strcmp(uart_dp->name, "rsc-control")) {
		mode = of_get_property(uart_dp,
				       "ssp-console-modes", NULL);
		if (!mode)
			mode = "115200,8,n,1,-";
	} else if (!strcmp(uart_dp->name, "lom-console")) {
		mode = "9600,8,n,1,-";
	} else {
		struct device_node *dp;
		char c;

		c = 'a';
		if (of_console_options)
			c = *of_console_options;

		mode_prop[3] = c;

		dp = of_find_node_by_path("/options");
		mode = of_get_property(dp, mode_prop, NULL);
		if (!mode)
			mode = "9600,8,n,1,-";
	}

	cflag = CREAD | HUPCL | CLOCAL;

	s = mode;
	baud = simple_strtoul(s, NULL, 0);
	s = strchr(s, ',');
	bits = simple_strtoul(++s, NULL, 0);
	s = strchr(s, ',');
	parity = *(++s);
	s = strchr(s, ',');
	stop = simple_strtoul(++s, NULL, 0);
	s = strchr(s, ',');
	/* XXX handshake is not handled here. */

	switch (baud) {
		case 150: cflag |= B150; break;
		case 300: cflag |= B300; break;
		case 600: cflag |= B600; break;
		case 1200: cflag |= B1200; break;
		case 2400: cflag |= B2400; break;
		case 4800: cflag |= B4800; break;
		case 9600: cflag |= B9600; break;
		case 19200: cflag |= B19200; break;
		case 38400: cflag |= B38400; break;
		case 57600: cflag |= B57600; break;
		case 115200: cflag |= B115200; break;
		case 230400: cflag |= B230400; break;
		case 460800: cflag |= B460800; break;
		default: baud = 9600; cflag |= B9600; break;
	}

	switch (bits) {
		case 5: cflag |= CS5; break;
		case 6: cflag |= CS6; break;
		case 7: cflag |= CS7; break;
		case 8: cflag |= CS8; break;
		default: cflag |= CS8; break;
	}

	switch (parity) {
		case 'o': cflag |= (PARENB | PARODD); break;
		case 'e': cflag |= PARENB; break;
		case 'n': default: break;
	}

	switch (stop) {
		case 2: cflag |= CSTOPB; break;
		case 1: default: break;
	}

	con->cflag = cflag;
}
static int __init wd_init(void)
{
	struct device_node *node;
	int rc;

	node = of_find_node_by_path("/wd@0");
	if (!node) {
		pr_err("Find node by path failed.\n");
		return -ENOENT;
	}

	wd = kzalloc(sizeof(struct _wd), GFP_KERNEL);
	if (!wd)
		return -ENOMEM;
	wd->gpio_clock = be32_to_cpup(of_get_property(node, "wd,gpio_clock", NULL));
	wd->gpio_inhib = be32_to_cpup(of_get_property(node, "wd,gpio_inhib", NULL));
	wd->gpio_trig = be32_to_cpup(of_get_property(node, "wd,gpio_trig", NULL));
	wd->period_s = be32_to_cpup(of_get_property(node, "wd,period_s", NULL));
	wd->last_trig_s = jiffies / HZ;

	if (!(gpio_is_valid(wd->gpio_inhib))
		|| !(gpio_is_valid(wd->gpio_clock))
		|| !(gpio_is_valid(wd->gpio_trig))) {
		pr_err("GPIO are not valid (problem with device tree ?)\n");
		rc = -EACCES;
		goto free_mem;
	}

	rc = gpio_request_one(wd->gpio_clock, GPIOF_IN, "wd-clock");
	if (rc < 0) {
		pr_err("wd-clock GPIO not available\n");
		goto free_mem;
	}

	rc = gpio_request_one(wd->gpio_inhib ,GPIOF_IN, "wd-inhib");
	if (rc < 0) {
		pr_err("wd-inhib GPIO not available\n");
		goto free_gpio_clock;
	}

	rc = gpio_request_one(wd->gpio_trig, GPIOF_OUT_INIT_LOW, "wd-trig");
	if (rc < 0) {
		pr_err("wd-trig GPIO not available\n");
		goto free_gpio_inhib;
	}

	wd_trig();

	wd->kobj = kobject_create_and_add("watchdog", kernel_kobj->parent);
	if (!wd->kobj) {
		pr_err("Kobject creation failed\n");
		rc = -ENOMEM;
		goto free_gpio_trig;
	}

	if (sysfs_create_group(wd->kobj, &wd_attr_group)) {
		pr_err("Sysfs group creation failed\n");
		rc = -ENOMEM;
		goto put_kobj;
	}

	return 0;

put_kobj:
	kobject_put(wd->kobj);
free_gpio_trig:
	gpio_free(wd->gpio_trig);
free_gpio_inhib:
	gpio_free(wd->gpio_inhib);
free_gpio_clock:
	gpio_free(wd->gpio_clock);
free_mem:
	kfree(wd);

	return rc;
}
示例#17
0
static int __init opal_init(void)
{
	struct device_node *np, *consoles;
	const __be32 *irqs;
	int rc, i, irqlen;

	opal_node = of_find_node_by_path("/ibm,opal");
	if (!opal_node) {
		pr_warn("opal: Node not found\n");
		return -ENODEV;
	}

	/* Register OPAL consoles if any ports */
	if (firmware_has_feature(FW_FEATURE_OPALv2))
		consoles = of_find_node_by_path("/ibm,opal/consoles");
	else
		consoles = of_node_get(opal_node);
	if (consoles) {
		for_each_child_of_node(consoles, np) {
			if (strcmp(np->name, "serial"))
				continue;
			of_platform_device_create(np, NULL, NULL);
		}
		of_node_put(consoles);
	}

	/* Find all OPAL interrupts and request them */
	irqs = of_get_property(opal_node, "opal-interrupts", &irqlen);
	pr_debug("opal: Found %d interrupts reserved for OPAL\n",
		 irqs ? (irqlen / 4) : 0);
	opal_irq_count = irqlen / 4;
	opal_irqs = kzalloc(opal_irq_count * sizeof(unsigned int), GFP_KERNEL);
	for (i = 0; irqs && i < (irqlen / 4); i++, irqs++) {
		unsigned int hwirq = be32_to_cpup(irqs);
		unsigned int irq = irq_create_mapping(NULL, hwirq);
		if (irq == NO_IRQ) {
			pr_warning("opal: Failed to map irq 0x%x\n", hwirq);
			continue;
		}
		rc = request_irq(irq, opal_interrupt, 0, "opal", NULL);
		if (rc)
			pr_warning("opal: Error %d requesting irq %d"
				   " (0x%x)\n", rc, irq, hwirq);
		opal_irqs[i] = irq;
	}

	/* Create "opal" kobject under /sys/firmware */
	rc = opal_sysfs_init();
	if (rc == 0) {
		/* Setup dump region interface */
		opal_dump_region_init();
		/* Setup error log interface */
		rc = opal_elog_init();
		/* Setup code update interface */
		opal_flash_init();
		/* Setup platform dump extract interface */
		opal_platform_dump_init();
		/* Setup system parameters interface */
		opal_sys_param_init();
		/* Setup message log interface. */
		opal_msglog_init();
	}

	return 0;
}
示例#18
0
static void __init ap_init_of(void)
{
	unsigned long sc_dec;
	struct device_node *root;
	struct device_node *syscon;
	struct device *parent;
	struct soc_device *soc_dev;
	struct soc_device_attribute *soc_dev_attr;
	u32 ap_sc_id;
	int err;
	int i;

	/* Here we create an SoC device for the root node */
	root = of_find_node_by_path("/");
	if (!root)
		return;
	syscon = of_find_node_by_path("/syscon");
	if (!syscon)
		return;

	ap_syscon_base = of_iomap(syscon, 0);
	if (!ap_syscon_base)
		return;

	ap_sc_id = readl(ap_syscon_base);

	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
	if (!soc_dev_attr)
		return;

	err = of_property_read_string(root, "compatible",
				      &soc_dev_attr->soc_id);
	if (err)
		return;
	err = of_property_read_string(root, "model", &soc_dev_attr->machine);
	if (err)
		return;
	soc_dev_attr->family = "Integrator";
	soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c",
					   'A' + (ap_sc_id & 0x0f));

	soc_dev = soc_device_register(soc_dev_attr);
	if (IS_ERR(soc_dev)) {
		kfree(soc_dev_attr->revision);
		kfree(soc_dev_attr);
		return;
	}

	parent = soc_device_to_device(soc_dev);
	integrator_init_sysfs(parent, ap_sc_id);

	of_platform_populate(root, of_default_bus_match_table,
			ap_auxdata_lookup, parent);

	sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET);
	for (i = 0; i < 4; i++) {
		struct lm_device *lmdev;

		if ((sc_dec & (16 << i)) == 0)
			continue;

		lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL);
		if (!lmdev)
			continue;

		lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
		lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
		lmdev->resource.flags = IORESOURCE_MEM;
		lmdev->irq = IRQ_AP_EXPINT0 + i;
		lmdev->id = i;

		lm_device_register(lmdev);
	}
}
示例#19
0
void udbg_scc_init(int force_scc)
{
	const u32 *reg;
	unsigned long addr;
	struct device_node *stdout = NULL, *escc = NULL, *macio = NULL;
	struct device_node *ch, *ch_def = NULL, *ch_a = NULL;
	const char *path;
	int i, x;

	escc = of_find_node_by_name(NULL, "escc");
	if (escc == NULL)
		goto bail;
	macio = of_get_parent(escc);
	if (macio == NULL)
		goto bail;
	path = of_get_property(of_chosen, "linux,stdout-path", NULL);
	if (path != NULL)
		stdout = of_find_node_by_path(path);
	for (ch = NULL; (ch = of_get_next_child(escc, ch)) != NULL;) {
		if (ch == stdout)
			ch_def = of_node_get(ch);
		if (strcmp(ch->name, "ch-a") == 0)
			ch_a = of_node_get(ch);
	}
	if (ch_def == NULL && !force_scc)
		goto bail;

	ch = ch_def ? ch_def : ch_a;

	/* Get address within mac-io ASIC */
	reg = of_get_property(escc, "reg", NULL);
	if (reg == NULL)
		goto bail;
	addr = reg[0];

	/* Get address of mac-io PCI itself */
	reg = of_get_property(macio, "assigned-addresses", NULL);
	if (reg == NULL)
		goto bail;
	addr += reg[2];

	/* Lock the serial port */
	pmac_call_feature(PMAC_FTR_SCC_ENABLE, ch,
			  PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);

	if (ch == ch_a)
		addr += 0x20;
	sccc = ioremap(addr & PAGE_MASK, PAGE_SIZE) ;
	sccc += addr & ~PAGE_MASK;
	sccd = sccc + 0x10;

	mb();

	for (i = 20000; i != 0; --i)
		x = in_8(sccc);
	out_8(sccc, 0x09);		/* reset A or B side */
	out_8(sccc, 0xc0);

	/* If SCC was the OF output port, read the BRG value, else
	 * Setup for 38400 or 57600 8N1 depending on the machine
	 */
	if (ch_def != NULL) {
		out_8(sccc, 13);
		scc_inittab[1] = in_8(sccc);
		out_8(sccc, 12);
		scc_inittab[3] = in_8(sccc);
	} else if (machine_is_compatible("RackMac1,1")
		   || machine_is_compatible("RackMac1,2")
		   || machine_is_compatible("MacRISC4")) {
		/* Xserves and G5s default to 57600 */
		scc_inittab[1] = 0;
		scc_inittab[3] = 0;
	} else {
		/* Others default to 38400 */
		scc_inittab[1] = 0;
		scc_inittab[3] = 1;
	}

	for (i = 0; i < sizeof(scc_inittab); ++i)
		out_8(sccc, scc_inittab[i]);


	udbg_putc = udbg_scc_putc;
	udbg_getc = udbg_scc_getc;
	udbg_getc_poll = udbg_scc_getc_poll;

	udbg_puts("Hello World !\n");

 bail:
	of_node_put(macio);
	of_node_put(escc);
	of_node_put(stdout);
	of_node_put(ch_def);
	of_node_put(ch_a);
}
static int mapphone_dt_get_dsi_panel_info(void)
{
	struct device_node *panel_node;
	const void *panel_prop;
	int disp_intf;
	int len = 0;

	PANELDBG("dt_get_dsi_panel_info()\n");

	/* return err if fail to open DT */
	panel_node = of_find_node_by_path(DT_PATH_DISPLAY1);
	if (panel_node == NULL)
		return -ENODEV;

	/* Retrieve the panel information */
	panel_prop = of_get_property(panel_node, "dsi_clk_lane", NULL);
	if (panel_prop != NULL)
		mapphone_lcd_device.phy.dsi.clk_lane = *(u8 *)panel_prop;

	panel_prop = of_get_property(panel_node, "dsi_clk_pol", NULL);
	if (panel_prop != NULL)
		mapphone_lcd_device.phy.dsi.clk_pol = *(u8 *)panel_prop;

	panel_prop = of_get_property(panel_node, "dsi_data1_lane", NULL);
	if (panel_prop != NULL)
		mapphone_lcd_device.phy.dsi.data1_lane = *(u8 *)panel_prop;

	panel_prop = of_get_property(panel_node, "dsi_data1_pol", NULL);
	if (panel_prop != NULL)
		mapphone_lcd_device.phy.dsi.data1_pol = *(u8 *)panel_prop;

	panel_prop = of_get_property(panel_node, "dsi_data2_lane", NULL);
	if (panel_prop != NULL)
		mapphone_lcd_device.phy.dsi.data2_lane = *(u8 *)panel_prop;

	panel_prop = of_get_property(panel_node, "dsi_data2_pol", NULL);
	if (panel_prop != NULL)
		mapphone_lcd_device.phy.dsi.data2_pol = *(u8 *)panel_prop;

	panel_prop = of_get_property(panel_node, "gpio_reset", NULL);
	if (panel_prop != NULL)
		mapphone_panel_data.reset_gpio = *(u32 *)panel_prop;

	panel_prop = of_get_property(panel_node, "displ_pwr_sup", &len);
	if ((panel_prop != NULL) && len) {
		strncpy(mapphone_displ_pwr_sup, (char *)panel_prop,
			sizeof(mapphone_displ_pwr_sup) - 1);
		mapphone_displ_pwr_sup[sizeof(mapphone_displ_pwr_sup) - 1]
			= '\0';
	}

	panel_prop = of_get_property(panel_node, "displ_pwr_sup_en", NULL);
	if (panel_prop != NULL)
		mapphone_displ_pwr_sup_en = *(u32 *)panel_prop;

	panel_prop = of_get_property(panel_node, "type", NULL);
	if (panel_prop != NULL)
		mapphone_lcd_device.panel.panel_id = *(u32 *)panel_prop;

	panel_prop = of_get_property(panel_node, "regn", NULL);
	if (panel_prop != NULL)
		mapphone_lcd_device.phy.dsi.div.regn = *(u16 *)panel_prop;

	panel_prop = of_get_property(panel_node, "regm", NULL);
	if (panel_prop != NULL)
		mapphone_lcd_device.phy.dsi.div.regm = *(u16 *)panel_prop;

	panel_prop = of_get_property(panel_node, "regm3", NULL);
	if (panel_prop != NULL)
		mapphone_lcd_device.phy.dsi.div.regm_dispc = *(u16 *)panel_prop;

	panel_prop = of_get_property(panel_node, "regm4", NULL);
	if (panel_prop != NULL)
		mapphone_lcd_device.phy.dsi.div.regm_dsi = *(u16 *)panel_prop;

	panel_prop = of_get_property(panel_node, "lp_clk_div", NULL);
	if (panel_prop != NULL)
		mapphone_lcd_device.phy.dsi.div.lp_clk_div = *(u16 *)panel_prop;

	panel_prop = of_get_property(panel_node, "lck_div", NULL);
	if (panel_prop != NULL)
		mapphone_lcd_device.phy.dsi.div.lck_div = *(u16 *)panel_prop;

	panel_prop = of_get_property(panel_node, "pck_div", NULL);
	if (panel_prop != NULL)
		mapphone_lcd_device.phy.dsi.div.pck_div = *(u16 *)panel_prop;

	panel_prop = of_get_property(panel_node, "disp_intf", NULL);
	if (panel_prop != NULL) {
		disp_intf = *(u8 *)panel_prop;

		if ((disp_intf == OMAP_DSS_DISP_INTF_MIPI_VP_CM) ||
			(disp_intf == OMAP_DSS_DISP_INTF_MIPI_L4_CM))
			mapphone_lcd_device.phy.dsi.xfer_mode =
				OMAP_DSI_XFER_CMD_MODE;
		else if ((disp_intf == OMAP_DSS_DISP_INTF_MIPI_VP_VM) ||
			(disp_intf == OMAP_DSS_DISP_INTF_MIPI_L4_VM))
			mapphone_lcd_device.phy.dsi.xfer_mode =
				OMAP_DSI_XFER_VIDEO_MODE;
		else {
			printk(KERN_ERR "Invalid disp_intf in dt = %d\n",
				disp_intf);
			return -ENODEV;
		}
	}

	of_node_put(panel_node);

	return 0;
}
示例#21
0
static int
oh_port_probe(struct platform_device *_of_dev)
{
	struct device		*dpa_oh_dev;
	struct device_node	*dpa_oh_node;
	int			 lenp, _errno = 0, fq_idx, n_size, i, ret;
	const phandle		*oh_port_handle, *bpool_handle;
	struct platform_device	*oh_of_dev;
	struct device_node	*oh_node, *bpool_node = NULL, *root_node;
	struct device		*oh_dev;
	struct dpa_oh_config_s	*oh_config = NULL;
	uint32_t		*oh_all_queues;
	uint32_t		*oh_tx_queues;
	uint32_t		 queues_count;
	uint32_t		 crt_fqid_base;
	uint32_t		 crt_fq_count;
	bool			frag_enabled = false;
	struct fm_port_params	oh_port_tx_params;
	struct fm_port_pcd_param	oh_port_pcd_params;
	struct dpa_buffer_layout_s buf_layout;
	/* True if the current partition owns the OH port. */
	bool init_oh_port;
	const struct of_device_id *match;
	uint32_t crt_ext_pools_count, ext_pool_size;
	const unsigned int *port_id;
	const unsigned int *channel_id;
	const uint32_t		*bpool_cfg;
	const uint32_t		*bpid;

	memset(&oh_port_tx_params, 0, sizeof(oh_port_tx_params));
	dpa_oh_dev = &_of_dev->dev;
	dpa_oh_node = dpa_oh_dev->of_node;
	BUG_ON(dpa_oh_node == NULL);

	match = of_match_device(oh_port_match_table, dpa_oh_dev);
	if (!match)
		return -EINVAL;

	dev_dbg(dpa_oh_dev, "Probing OH port...\n");

	/*
	 * Find the referenced OH node
	 */

	oh_port_handle = of_get_property(dpa_oh_node,
		"fsl,fman-oh-port", &lenp);
	if (oh_port_handle == NULL) {
		dev_err(dpa_oh_dev, "No OH port handle found in node %s\n",
			dpa_oh_node->full_name);
		return -EINVAL;
	}

	BUG_ON(lenp % sizeof(*oh_port_handle));
	if (lenp != sizeof(*oh_port_handle)) {
		dev_err(dpa_oh_dev, "Found %lu OH port bindings in node %s,"
			" only 1 phandle is allowed.\n",
			(unsigned long int)(lenp / sizeof(*oh_port_handle)),
			dpa_oh_node->full_name);
		return -EINVAL;
	}

	/* Read configuration for the OH port */
	oh_node = of_find_node_by_phandle(*oh_port_handle);
	if (oh_node == NULL) {
		dev_err(dpa_oh_dev, "Can't find OH node referenced from "
			"node %s\n", dpa_oh_node->full_name);
		return -EINVAL;
	}
	dev_info(dpa_oh_dev, "Found OH node handle compatible with %s.\n",
		match->compatible);

	port_id = of_get_property(oh_node, "cell-index", &lenp);

	if (port_id == NULL) {
		dev_err(dpa_oh_dev, "No port id found in node %s\n",
			dpa_oh_node->full_name);
		_errno = -EINVAL;
		goto return_kfree;
	}

	BUG_ON(lenp % sizeof(*port_id));

	oh_of_dev = of_find_device_by_node(oh_node);
	BUG_ON(oh_of_dev == NULL);
	oh_dev = &oh_of_dev->dev;

	/*
	 * The OH port must be initialized exactly once.
	 * The following scenarios are of interest:
	 *	- the node is Linux-private (will always initialize it);
	 *	- the node is shared between two Linux partitions
	 *	  (only one of them will initialize it);
	 *	- the node is shared between a Linux and a LWE partition
	 *	  (Linux will initialize it) - "fsl,dpa-oh-shared"
	 */

	/* Check if the current partition owns the OH port
	 * and ought to initialize it. It may be the case that we leave this
	 * to another (also Linux) partition. */
	init_oh_port = strcmp(match->compatible, "fsl,dpa-oh-shared");

	/* If we aren't the "owner" of the OH node, we're done here. */
	if (!init_oh_port) {
		dev_dbg(dpa_oh_dev, "Not owning the shared OH port %s, "
			"will not initialize it.\n", oh_node->full_name);
		of_node_put(oh_node);
		return 0;
	}

	/* Allocate OH dev private data */
	oh_config = devm_kzalloc(dpa_oh_dev, sizeof(*oh_config), GFP_KERNEL);
	if (oh_config == NULL) {
		dev_err(dpa_oh_dev, "Can't allocate private data for "
			"OH node %s referenced from node %s!\n",
			oh_node->full_name, dpa_oh_node->full_name);
		_errno = -ENOMEM;
		goto return_kfree;
	}

	/*
	 * Read FQ ids/nums for the DPA OH node
	 */
	oh_all_queues = (uint32_t *)of_get_property(dpa_oh_node,
		"fsl,qman-frame-queues-oh", &lenp);
	if (oh_all_queues == NULL) {
		dev_err(dpa_oh_dev, "No frame queues have been "
			"defined for OH node %s referenced from node %s\n",
			oh_node->full_name, dpa_oh_node->full_name);
		_errno = -EINVAL;
		goto return_kfree;
	}

	/* Check that the OH error and default FQs are there */
	BUG_ON(lenp % (2 * sizeof(*oh_all_queues)));
	queues_count = lenp / (2 * sizeof(*oh_all_queues));
	if (queues_count != 2) {
		dev_err(dpa_oh_dev, "Error and Default queues must be "
			"defined for OH node %s referenced from node %s\n",
			oh_node->full_name, dpa_oh_node->full_name);
		_errno = -EINVAL;
		goto return_kfree;
	}

	/* Read the FQIDs defined for this OH port */
	dev_dbg(dpa_oh_dev, "Reading %d queues...\n", queues_count);
	fq_idx = 0;

	/* Error FQID - must be present */
	crt_fqid_base = oh_all_queues[fq_idx++];
	crt_fq_count = oh_all_queues[fq_idx++];
	if (crt_fq_count != 1) {
		dev_err(dpa_oh_dev, "Only 1 Error FQ allowed in OH node %s "
			"referenced from node %s (read: %d FQIDs).\n",
			oh_node->full_name, dpa_oh_node->full_name,
			crt_fq_count);
		_errno = -EINVAL;
		goto return_kfree;
	}
	oh_config->error_fqid = crt_fqid_base;
	dev_dbg(dpa_oh_dev, "Read Error FQID 0x%x for OH port %s.\n",
		oh_config->error_fqid, oh_node->full_name);

	/* Default FQID - must be present */
	crt_fqid_base = oh_all_queues[fq_idx++];
	crt_fq_count = oh_all_queues[fq_idx++];
	if (crt_fq_count != 1) {
		dev_err(dpa_oh_dev, "Only 1 Default FQ allowed "
			"in OH node %s referenced from %s (read: %d FQIDs).\n",
			oh_node->full_name, dpa_oh_node->full_name,
			crt_fq_count);
		_errno = -EINVAL;
		goto return_kfree;
	}
	oh_config->default_fqid = crt_fqid_base;
	dev_dbg(dpa_oh_dev, "Read Default FQID 0x%x for OH port %s.\n",
		oh_config->default_fqid, oh_node->full_name);

	/* TX FQID - presence is optional */
	oh_tx_queues = (uint32_t *)of_get_property(dpa_oh_node,
		"fsl,qman-frame-queues-tx", &lenp);
	if (oh_tx_queues == NULL) {
		dev_dbg(dpa_oh_dev, "No tx queues have been "
		"defined for OH node %s referenced from node %s\n",
			oh_node->full_name, dpa_oh_node->full_name);
		goto config_port;
	}

	/* Check that queues-tx has only a base and a count defined */
	BUG_ON(lenp % (2 * sizeof(*oh_tx_queues)));
	queues_count = lenp / (2 * sizeof(*oh_tx_queues));
	if (queues_count != 1) {
		dev_err(dpa_oh_dev, "TX queues must be defined in"
			"only one <base count> tuple for OH node %s "
			"referenced from node %s\n",
			oh_node->full_name, dpa_oh_node->full_name);
		_errno = -EINVAL;
		goto return_kfree;
	}

	/* Read channel id for the queues */
	channel_id = of_get_property(oh_node, "fsl,qman-channel-id", &lenp);
	if (channel_id == NULL) {
		dev_err(dpa_oh_dev, "No channel id found in node %s\n",
			dpa_oh_node->full_name);
		_errno = -EINVAL;
		goto return_kfree;
	}
	BUG_ON(lenp % sizeof(*channel_id));

	fq_idx = 0;
	crt_fqid_base = oh_tx_queues[fq_idx++];
	crt_fq_count = oh_tx_queues[fq_idx++];
	oh_config->egress_cnt = crt_fq_count;

	/* Allocate TX queues */
	dev_dbg(dpa_oh_dev, "Allocating %d queues for TX...\n", crt_fq_count);
	oh_config->egress_fqs = devm_kzalloc(dpa_oh_dev,
		crt_fq_count * sizeof(struct qman_fq), GFP_KERNEL);
	if (oh_config->egress_fqs == NULL) {
		dev_err(dpa_oh_dev, "Can't allocate private data for "
			"TX queues for OH node %s referenced from node %s!\n",
			oh_node->full_name, dpa_oh_node->full_name);
		_errno = -ENOMEM;
		goto return_kfree;
	}

	/* Create TX queues */
	for (i = 0; i < crt_fq_count; i++) {
		ret = oh_fq_create(oh_config->egress_fqs + i,
			crt_fqid_base + i, *channel_id, 3);
		if (ret != 0) {
			dev_err(dpa_oh_dev, "Unable to create TX frame "
				"queue %d for OH node %s referenced "
				"from node %s!\n",
				crt_fqid_base + i, oh_node->full_name,
				dpa_oh_node->full_name);
			_errno = -EINVAL;
			goto return_kfree;
		}
	}

config_port:
	/* Get a handle to the fm_port so we can set
	 * its configuration params */
	oh_config->oh_port = fm_port_bind(oh_dev);
	if (oh_config->oh_port == NULL) {
		dev_err(dpa_oh_dev, "NULL drvdata from fm port dev %s!\n",
			oh_node->full_name);
		_errno = -EINVAL;
		goto return_kfree;
	}

	oh_set_buffer_layout(oh_config->oh_port, &buf_layout);
	bpool_handle = of_get_property(dpa_oh_node,
			"fsl,bman-buffer-pools", &lenp);

	if (bpool_handle == NULL) {
		dev_info(dpa_oh_dev, "OH port %s has no buffer pool. Fragmentation will not be enabled\n",
			oh_node->full_name);
		goto init_port;
	}

	/* used for reading ext_pool_size*/
	root_node = of_find_node_by_path("/");
	if (root_node == NULL) {
		dev_err(dpa_oh_dev, "of_find_node_by_path(/) failed\n");
		_errno = -EINVAL;
		goto return_kfree;
	}

	n_size = of_n_size_cells(root_node);
	of_node_put(root_node);

	crt_ext_pools_count = lenp / sizeof(phandle);
	dev_dbg(dpa_oh_dev, "OH port number of pools = %u\n",
					crt_ext_pools_count);

	oh_port_tx_params.num_pools = crt_ext_pools_count;

	for (i = 0; i < crt_ext_pools_count; i++) {
		bpool_node = of_find_node_by_phandle(bpool_handle[i]);
		if (bpool_node == NULL) {
			dev_err(dpa_oh_dev, "Invalid Buffer pool node\n");
			_errno = -EINVAL;
			goto return_kfree;
		}

		bpid = of_get_property(bpool_node, "fsl,bpid", &lenp);
		if ((bpid == NULL) || (lenp != sizeof(*bpid))) {
			dev_err(dpa_oh_dev, "Invalid Buffer pool Id\n");
			_errno = -EINVAL;
			goto return_kfree;
		}

		oh_port_tx_params.pool_param[i].id = *bpid;
		dev_dbg(dpa_oh_dev, "OH port bpool id = %u\n", *bpid);

		bpool_cfg = of_get_property(bpool_node,
				"fsl,bpool-ethernet-cfg", &lenp);
		if (bpool_cfg == NULL) {
			dev_err(dpa_oh_dev, "Invalid Buffer pool config params\n");
			_errno = -EINVAL;
			goto return_kfree;
		}

		of_read_number(bpool_cfg, n_size);
		ext_pool_size = of_read_number(bpool_cfg + n_size, n_size);
		oh_port_tx_params.pool_param[i].size = ext_pool_size;
		dev_dbg(dpa_oh_dev, "OH port bpool size = %u\n",
			ext_pool_size);
		of_node_put(bpool_node);

	}

	if (buf_layout.data_align != FRAG_DATA_ALIGN ||
	    buf_layout.manip_extra_space != FRAG_MANIP_SPACE)
		goto init_port;

	frag_enabled = true;
	dev_info(dpa_oh_dev, "IP Fragmentation enabled for OH port %d",
		     *port_id);

init_port:
	of_node_put(oh_node);
	/* Set Tx params */
	dpaa_eth_init_port(tx, oh_config->oh_port, oh_port_tx_params,
		oh_config->error_fqid, oh_config->default_fqid, (&buf_layout),
		frag_enabled);
	/* Set PCD params */
	oh_port_pcd_params.cba = oh_alloc_pcd_fqids;
	oh_port_pcd_params.cbf = oh_free_pcd_fqids;
	oh_port_pcd_params.dev = dpa_oh_dev;
	fm_port_pcd_bind(oh_config->oh_port, &oh_port_pcd_params);

	dev_set_drvdata(dpa_oh_dev, oh_config);

	/* Enable the OH port */
	_errno = fm_port_enable(oh_config->oh_port);
	if (_errno)
		goto return_kfree;

	dev_info(dpa_oh_dev, "OH port %s enabled.\n", oh_node->full_name);

	return 0;

return_kfree:
	if (bpool_node)
		of_node_put(bpool_node);
	if (oh_node)
		of_node_put(oh_node);
	if (oh_config && oh_config->egress_fqs)
		devm_kfree(dpa_oh_dev, oh_config->egress_fqs);
	devm_kfree(dpa_oh_dev, oh_config);
	return _errno;
}
static int mapphone_dt_get_panel_info(void)
{
	struct device_node *panel_node;
	const void *panel_prop;
	int panel_pixel_fmt;
	int pixel_size = 24;
	struct mapphone_dsi_panel_data *panel_data =
		(struct mapphone_dsi_panel_data *)mapphone_lcd_device.data;

	PANELDBG("mapphone_dt_get_panel_info\n");

	panel_node = of_find_node_by_path(DT_PATH_DISPLAY1);
	if (panel_node != NULL) {
		/* Retrieve the panel DSI timing */
		panel_prop = of_get_property(panel_node, "width", NULL);
		if (panel_prop != NULL)
			mapphone_panel_timings.x_res = *(u16 *)panel_prop;

		panel_prop = of_get_property(panel_node, "height", NULL);
		if (panel_prop != NULL)
			mapphone_panel_timings.y_res = *(u16 *)panel_prop;

		panel_prop = of_get_property(panel_node,
						"dispc_timing_hfp", NULL);
		if (panel_prop != NULL)
			mapphone_panel_timings.hfp = *(u16 *)panel_prop;

		panel_prop = of_get_property(panel_node,
						"dispc_timing_hsw", NULL);
		if (panel_prop != NULL)
			mapphone_panel_timings.hsw = *(u16 *)panel_prop;

		panel_prop = of_get_property(panel_node,
						"dispc_timing_hbp", NULL);
		if (panel_prop != NULL)
			mapphone_panel_timings.hbp = *(u16 *)panel_prop;

		panel_prop = of_get_property(panel_node,
						"dispc_timing_vfp", NULL);
		if (panel_prop != NULL)
			mapphone_panel_timings.vfp = *(u16 *)panel_prop;

		panel_prop = of_get_property(panel_node,
						"dispc_timing_vsw", NULL);
		if (panel_prop != NULL)
			mapphone_panel_timings.vsw = *(u16 *)panel_prop;

		panel_prop = of_get_property(panel_node,
						"dispc_timing_vbp", NULL);
		if (panel_prop != NULL)
			mapphone_panel_timings.vbp = *(u16 *)panel_prop;

		panel_prop = of_get_property(panel_node,
						"phy_width_mm", NULL);
		if (panel_prop != NULL)
			mapphone_panel_timings.w = *(u16 *)panel_prop;

		panel_prop = of_get_property(panel_node,
						"phy_height_mm", NULL);
		if (panel_prop != NULL)
			mapphone_panel_timings.h = *(u16 *)panel_prop;

		panel_prop = of_get_property(panel_node,
						"te_support", NULL);
		if (panel_prop != NULL)
			panel_data->te_support = *(u32 *)panel_prop;

		panel_prop = of_get_property(panel_node,
						"te_scan_line", NULL);
		if (panel_prop != NULL)
			panel_data->te_scan_line =  *(u32 *)panel_prop;

		panel_prop = of_get_property(panel_node, "te_type", NULL);
		if (panel_prop != NULL)
			panel_data->te_type = *(enum omap_dsi_te_type *)
				panel_prop;

		panel_prop = of_get_property(panel_node, "pixel_fmt", NULL);
		if (panel_prop != NULL) {
			panel_pixel_fmt = *(u32 *)panel_prop;
			if (panel_pixel_fmt == OMAP_DSS_DISP_PXL_FMT_RGB888)
				pixel_size = 24;
			else if (panel_pixel_fmt ==
					OMAP_DSS_DISP_PXL_FMT_RGB565)
				pixel_size = 16;
			else {
				printk(KERN_ERR " Invalid panel_pxl_fmt=%d",
							panel_pixel_fmt);
				return -ENODEV;
			}
		}

		of_node_put(panel_node);

		mapphone_lcd_device.ctrl.pixel_size  =  pixel_size;
		mapphone_lcd_device.panel.timings  =  mapphone_panel_timings;

	}

	return panel_node ? 0 : -ENODEV;

}
示例#23
0
/*
 * find the byte channel handle to use for the console
 *
 * The byte channel to be used for the console is specified via a "stdout"
 * property in the /chosen node.
 *
 * For compatible with legacy device trees, we also look for a "stdout" alias.
 */
static int find_console_handle(void)
{
	struct device_node *np, *np2;
	const char *sprop = NULL;
	const uint32_t *iprop;

	np = of_find_node_by_path("/chosen");
	if (np)
		sprop = of_get_property(np, "stdout-path", NULL);

	if (!np || !sprop) {
		of_node_put(np);
		np = of_find_node_by_name(NULL, "aliases");
		if (np)
			sprop = of_get_property(np, "stdout", NULL);
	}

	if (!sprop) {
		of_node_put(np);
		return 0;
	}

	/* We don't care what the aliased node is actually called.  We only
	 * care if it's compatible with "epapr,hv-byte-channel", because that
	 * indicates that it's a byte channel node.  We use a temporary
	 * variable, 'np2', because we can't release 'np' until we're done with
	 * 'sprop'.
	 */
	np2 = of_find_node_by_path(sprop);
	of_node_put(np);
	np = np2;
	if (!np) {
		pr_warning("ehv-bc: stdout node '%s' does not exist\n", sprop);
		return 0;
	}

	/* Is it a byte channel? */
	if (!of_device_is_compatible(np, "epapr,hv-byte-channel")) {
		of_node_put(np);
		return 0;
	}

	stdout_irq = irq_of_parse_and_map(np, 0);
	if (stdout_irq == NO_IRQ) {
		pr_err("ehv-bc: no 'interrupts' property in %s node\n", sprop);
		of_node_put(np);
		return 0;
	}

	/*
	 * The 'hv-handle' property contains the handle for this byte channel.
	 */
	iprop = of_get_property(np, "hv-handle", NULL);
	if (!iprop) {
		pr_err("ehv-bc: no 'hv-handle' property in %s node\n",
		       np->name);
		of_node_put(np);
		return 0;
	}
	stdout_bc = be32_to_cpu(*iprop);

	of_node_put(np);
	return 1;
}
static int mapphone_dt_get_hdtv_info(void)
{
	struct device_node *panel_node;
	const void *panel_prop;
	struct omap_ovl2mgr_mapping *read_ovl2mgr_mapping = NULL;
	int len = 0, i = 0;

	PANELDBG("dt_get_hdtv_info()\n");

	/* return err if fail to open DT */
	panel_node = of_find_node_by_path(DT_PATH_DISPLAY2);
	if (panel_node == NULL)
		return -ENODEV;

	panel_prop = of_get_property(panel_node, "max_width", NULL);
	if (panel_prop != NULL)
		mapphone_hdtv_device.panel.timings.x_res = *(u32 *)panel_prop;

	panel_prop = of_get_property(panel_node, "max_height", NULL);
	if (panel_prop != NULL)
		mapphone_hdtv_device.panel.timings.y_res = *(u32 *)panel_prop;

	if (mapphone_hdtv_device.panel.timings.x_res > 2048)
		mapphone_hdtv_device.panel.timings.x_res = 1920;

	if (mapphone_hdtv_device.panel.timings.y_res > 2048)
		mapphone_hdtv_device.panel.timings.x_res = 1080;

	/* Get the mapping data for the overlay to map to its manager*/
	panel_prop = of_get_property(panel_node, "overlay_mgr_mapping", &len);
	mapphone_dss_data.ovl2mgr_mapping_cnt = 0;

	if (len)
		mapphone_dss_data.ovl2mgr_mapping_cnt = len /
			sizeof(struct omap_ovl2mgr_mapping);

	if (panel_prop != NULL) {
		read_ovl2mgr_mapping =
			(struct omap_ovl2mgr_mapping *)panel_prop;

		for (i = 0; i < mapphone_dss_data.ovl2mgr_mapping_cnt; i++) {
			mapphone_dss_data.ovl2mgr_mapping[i].overlay_idx =
				read_ovl2mgr_mapping[i].overlay_idx;
			mapphone_dss_data.ovl2mgr_mapping[i].overlay_mgr =
				read_ovl2mgr_mapping[i].overlay_mgr;
			PANELDBG("Mapping data for overlay %u"
					" is to manager %u\n",
			mapphone_dss_data.ovl2mgr_mapping[i].overlay_idx,
			mapphone_dss_data.ovl2mgr_mapping[i].overlay_mgr);
		}
	} else {
		PANELDBG("Panel property is 0 for ovl to mgr mapping\n");
	}

	PANELDBG("Getting the xres = %u yres = %u\n",
		mapphone_hdtv_device.panel.timings.x_res,
		mapphone_hdtv_device.panel.timings.y_res);

	panel_prop = of_get_property(panel_node, "gpio_pwr_en", NULL);
	if (panel_prop != NULL)
		mapphone_hdmi_5v_enable = *(u32 *)panel_prop;

	panel_prop = of_get_property(panel_node, "dac_reg_name", NULL);
	if (panel_prop != NULL) {
		strncpy(mapphone_hdmi_dac_reg_name,
				(char *)panel_prop,
				(HDMI_DAC_REGULATOR_NAME_SIZE));
		mapphone_hdmi_dac_reg_name \
			[HDMI_DAC_REGULATOR_NAME_SIZE] = '\0';
	}

	of_node_put(panel_node);
	return 0;
}
示例#25
0
文件: devtree.c 项目: xtra72/s805
/*
 * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree
 * and builds the cpu logical map array containing MPIDR values related to
 * logical cpus
 *
 * Updates the cpu possible mask with the number of parsed cpu nodes
 */
void __init arm_dt_init_cpu_maps(void)
{
	/*
	 * Temp logical map is initialized with UINT_MAX values that are
	 * considered invalid logical map entries since the logical map must
	 * contain a list of MPIDR[23:0] values where MPIDR[31:24] must
	 * read as 0.
	 */
	struct device_node *cpu, *cpus;
	u32 i, j, cpuidx = 1;
	u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;

	u32 tmp_map[NR_CPUS] = { [0 ... NR_CPUS-1] = UINT_MAX };
	bool bootcpu_valid = false;
	cpus = of_find_node_by_path("/cpus");

	if (!cpus)
		return;

	for_each_child_of_node(cpus, cpu) {
		u32 hwid;

		pr_debug(" * %s...\n", cpu->full_name);
		/*
		 * A device tree containing CPU nodes with missing "reg"
		 * properties is considered invalid to build the
		 * cpu_logical_map.
		 */
		if (of_property_read_u32(cpu, "reg", &hwid)) {
			pr_debug(" * %s missing reg property\n",
				     cpu->full_name);
			return;
		}

		/*
		 * 8 MSBs must be set to 0 in the DT since the reg property
		 * defines the MPIDR[23:0].
		 */
		if (hwid & ~MPIDR_HWID_BITMASK)
			return;

		/*
		 * Duplicate MPIDRs are a recipe for disaster.
		 * Scan all initialized entries and check for
		 * duplicates. If any is found just bail out.
		 * temp values were initialized to UINT_MAX
		 * to avoid matching valid MPIDR[23:0] values.
		 */
		for (j = 0; j < cpuidx; j++)
			if (WARN(tmp_map[j] == hwid, "Duplicate /cpu reg "
						     "properties in the DT\n"))
				return;

		/*
		 * Build a stashed array of MPIDR values. Numbering scheme
		 * requires that if detected the boot CPU must be assigned
		 * logical id 0. Other CPUs get sequential indexes starting
		 * from 1. If a CPU node with a reg property matching the
		 * boot CPU MPIDR is detected, this is recorded so that the
		 * logical map built from DT is validated and can be used
		 * to override the map created in smp_setup_processor_id().
		 */
		if (hwid == mpidr) {
			i = 0;
			bootcpu_valid = true;
		} else {
			i = cpuidx++;
		}

		if (WARN(cpuidx > nr_cpu_ids, "DT /cpu %u nodes greater than "
					       "max cores %u, capping them\n",
					       cpuidx, nr_cpu_ids)) {
			cpuidx = nr_cpu_ids;
			break;
		}

		tmp_map[i] = hwid;
	}
示例#26
0
void __init hvc_vio_init_early(void)
{
	struct device_node *stdout_node;
	const u32 *termno;
	const char *name;
	const struct hv_ops *ops;

	/* find the boot console from /chosen/stdout */
	if (!of_chosen)
		return;
	name = of_get_property(of_chosen, "linux,stdout-path", NULL);
	if (name == NULL)
		return;
	stdout_node = of_find_node_by_path(name);
	if (!stdout_node)
		return;
	name = of_get_property(stdout_node, "name", NULL);
	if (!name) {
		printk(KERN_WARNING "stdout node missing 'name' property!\n");
		goto out;
	}

	/* Check if it's a virtual terminal */
	if (strncmp(name, "vty", 3) != 0)
		goto out;
	termno = of_get_property(stdout_node, "reg", NULL);
	if (termno == NULL)
		goto out;
	hvterm_priv0.termno = *termno;
	spin_lock_init(&hvterm_priv0.buf_lock);
	hvterm_privs[0] = &hvterm_priv0;

	/* Check the protocol */
	if (of_device_is_compatible(stdout_node, "hvterm1")) {
		hvterm_priv0.proto = HV_PROTOCOL_RAW;
		ops = &hvterm_raw_ops;
	}
	else if (of_device_is_compatible(stdout_node, "hvterm-protocol")) {
		hvterm_priv0.proto = HV_PROTOCOL_HVSI;
		ops = &hvterm_hvsi_ops;
		hvsilib_init(&hvterm_priv0.hvsi, hvc_get_chars, hvc_put_chars,
			     hvterm_priv0.termno, 1);
		/* HVSI, perform the handshake now */
		hvsilib_establish(&hvterm_priv0.hvsi);
	} else
		goto out;
	udbg_putc = udbg_hvc_putc;
	udbg_getc = udbg_hvc_getc;
	udbg_getc_poll = udbg_hvc_getc_poll;
#ifdef HVC_OLD_HVSI
	/* When using the old HVSI driver don't register the HVC
	 * backend for HVSI, only do udbg
	 */
	if (hvterm_priv0.proto == HV_PROTOCOL_HVSI)
		goto out;
#endif
	add_preferred_console("hvc", 0, NULL);
	hvc_instantiate(0, 0, ops);
out:
	of_node_put(stdout_node);
}
示例#27
0
static int ti_cpufreq_init(void)
{
	u32 version[VERSION_COUNT];
	struct device_node *np;
	const struct of_device_id *match;
	struct ti_cpufreq_data *opp_data;
	int ret;

	np = of_find_node_by_path("/");
	match = of_match_node(ti_cpufreq_of_match, np);
	if (!match)
		return -ENODEV;

	opp_data = kzalloc(sizeof(*opp_data), GFP_KERNEL);
	if (!opp_data)
		return -ENOMEM;

	opp_data->soc_data = match->data;

	opp_data->cpu_dev = get_cpu_device(0);
	if (!opp_data->cpu_dev) {
		pr_err("%s: Failed to get device for CPU0\n", __func__);
		return -ENODEV;
	}

	opp_data->opp_node = dev_pm_opp_of_get_opp_desc_node(opp_data->cpu_dev);
	if (!opp_data->opp_node) {
		dev_info(opp_data->cpu_dev,
			 "OPP-v2 not supported, cpufreq-dt will attempt to use legacy tables.\n");
		goto register_cpufreq_dt;
	}

	ret = ti_cpufreq_setup_syscon_register(opp_data);
	if (ret)
		goto fail_put_node;

	/*
	 * OPPs determine whether or not they are supported based on
	 * two metrics:
	 *	0 - SoC Revision
	 *	1 - eFuse value
	 */
	ret = ti_cpufreq_get_rev(opp_data, &version[0]);
	if (ret)
		goto fail_put_node;

	ret = ti_cpufreq_get_efuse(opp_data, &version[1]);
	if (ret)
		goto fail_put_node;

	ret = PTR_ERR_OR_ZERO(dev_pm_opp_set_supported_hw(opp_data->cpu_dev,
							  version, VERSION_COUNT));
	if (ret) {
		dev_err(opp_data->cpu_dev,
			"Failed to set supported hardware\n");
		goto fail_put_node;
	}

	of_node_put(opp_data->opp_node);

register_cpufreq_dt:
	platform_device_register_simple("cpufreq-dt", -1, NULL, 0);

	return 0;

fail_put_node:
	of_node_put(opp_data->opp_node);

	return ret;
}
示例#28
0
static int __init meson_mx_socinfo_init(void)
{
	struct soc_device_attribute *soc_dev_attr;
	struct soc_device *soc_dev;
	struct device_node *np;
	struct regmap *assist_regmap, *bootrom_regmap, *analog_top_regmap;
	unsigned int major_ver, misc_ver, metal_rev = 0;
	int ret;

	assist_regmap =
		syscon_regmap_lookup_by_compatible("amlogic,meson-mx-assist");
	if (IS_ERR(assist_regmap))
		return PTR_ERR(assist_regmap);

	bootrom_regmap =
		syscon_regmap_lookup_by_compatible("amlogic,meson-mx-bootrom");
	if (IS_ERR(bootrom_regmap))
		return PTR_ERR(bootrom_regmap);

	np = of_find_matching_node(NULL, meson_mx_socinfo_analog_top_ids);
	if (np) {
		analog_top_regmap = syscon_node_to_regmap(np);
		if (IS_ERR(analog_top_regmap))
			return PTR_ERR(analog_top_regmap);

		ret = regmap_read(analog_top_regmap,
				  MESON_MX_ANALOG_TOP_METAL_REVISION,
				  &metal_rev);
		if (ret)
			return ret;
	}

	ret = regmap_read(assist_regmap, MESON_MX_ASSIST_HW_REV, &major_ver);
	if (ret < 0)
		return ret;

	ret = regmap_read(bootrom_regmap, MESON_MX_BOOTROM_MISC_VER,
			  &misc_ver);
	if (ret < 0)
		return ret;

	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
	if (!soc_dev_attr)
		return -ENODEV;

	soc_dev_attr->family = "Amlogic Meson";

	np = of_find_node_by_path("/");
	of_property_read_string(np, "model", &soc_dev_attr->machine);
	of_node_put(np);

	soc_dev_attr->revision = meson_mx_socinfo_revision(major_ver, misc_ver,
							   metal_rev);
	soc_dev_attr->soc_id = meson_mx_socinfo_soc_id(major_ver, metal_rev);

	soc_dev = soc_device_register(soc_dev_attr);
	if (IS_ERR(soc_dev)) {
		kfree_const(soc_dev_attr->revision);
		kfree_const(soc_dev_attr->soc_id);
		kfree(soc_dev_attr);
		return PTR_ERR(soc_dev);
	}

	dev_info(soc_device_to_device(soc_dev), "Amlogic %s %s detected\n",
		 soc_dev_attr->soc_id, soc_dev_attr->revision);

	return 0;
}
static int vib_of_init(struct vibrator *vib, int vib_nr)
{
	struct device_node *node;
	const void *prop = NULL;
	int len = 0;
	char dt_path_vib[sizeof(DT_PATH_VIB) + 3];

	snprintf(dt_path_vib, sizeof(DT_PATH_VIB) + 2, "%s%1d",
		DT_PATH_VIB, vib_nr % MAX_VIBS);
	node = of_find_node_by_path(dt_path_vib);
	if (!node)
		return -ENODEV;

	prop = of_get_property(node, DT_PROP_VIB_TYPE, &len);
	if (prop && len)
		vib->type = *((int *)prop);
	else
		return -ENODEV;

	if ((vib->type != VIB_TYPE_GENENIC_ROTARY)
		&& (vib->type != VIB_TYPE_GENENIC_LINEAR))
		return -ENODEV;

	prop = of_get_property(node, VIB_EN, &len);
	if (prop && len) {
		vib->ctrl.vib_en.of = *((struct vib_of_signal *)prop);
		vib->ctrl.vib_en.name = VIB_EN;
		vib->ctrl.vib_en.signal_type = SIGNAL_ENABLE;
		if (vib_signal_init(&vib->ctrl.vib_en)) {
			zfprintk("vib_en init failed\n");
			return -ENODEV;
		}
	} else {
		zfprintk("vib_en not found in %s\n", dt_path_vib);
		return -ENODEV;
	}

	prop = of_get_property(node, "pwm", &len);
	if (prop && len) {
		int i, j = len / sizeof(struct vib_pwm);
		dprintk("pwm len %d size %d\n", len,
				len/sizeof(struct vib_pwm));
		if (j > MAX_PWMS)
			j = MAX_PWMS;
		for (i = 0; i < j; i++)
			vib->ctrl.vib_pwm[i] = *(((struct vib_pwm *)prop) + i);
	} else {
		zfprintk("pwm not found in %s\n", dt_path_vib);
		return -ENODEV;
	}

	prop = of_get_property(node, VIB_DIR, &len);
	if (prop && len) {
		vib->ctrl.vib_dir.of = *((struct vib_of_signal *)prop);
		vib->ctrl.vib_dir.name = VIB_DIR;
		vib->ctrl.vib_dir.signal_type = SIGNAL_DIRECTION;
		if (vib_signal_init(&vib->ctrl.vib_dir)) {
			zfprintk("vib_dir init failed\n");
			return -ENODEV;
		}
	} else {
		if (vib->type == VIB_TYPE_GENENIC_LINEAR) {
			zfprintk("vib_dir not found in %s\n", dt_path_vib);
			return -ENODEV;
		}
	}

	prop = of_get_property(node, "regulator", &len);
	if (prop && len) {
		strncpy(vib->reg.name, (char *)prop,
				REGULATOR_NAME_SIZE - 1);
		vib->reg.name[REGULATOR_NAME_SIZE - 1] = '\0';

		prop = of_get_property(node, "deferred_off", &len);
		if (prop && len) {
			vib->reg.deferred_off = *(u32 *)prop;
			zfprintk("deferred_off %u\n", vib->reg.deferred_off);
		}
		vib->reg.volt[0].time =  MAX_TIMEOUT;
		vib->reg.volt[0].min_uV = 2800000;
		vib->reg.volt[0].max_uV = 2800000;

		prop = of_get_property(node, "voltage", &len);
		if (prop && len) {
			int i, j = len / sizeof(struct vib_voltage);
			dprintk("voltage len %d size %d\n", len,
				len/sizeof(struct vib_voltage));
			if (j > MAX_VOLT)
				j = MAX_VOLT;
			for (i = 0; i < j; i++)
				vib->reg.volt[i] =
					*(((struct vib_voltage *)prop) + i);
		}
	}

	prop = of_get_property(node, "min", &len);
	if (prop && len)
		vib->min_us = *((unsigned int *)prop);
	else
		vib->min_us = MIN_TIMEOUT;

	prop = of_get_property(node, "max", &len);
	if (prop && len)
		vib->max_us = *((unsigned int *)prop);
	else
		vib->max_us = MAX_TIMEOUT;

	of_node_put(node);
	return 0;
}
示例#30
0
static void __init mpc885ads_setup_arch(void)
{
	struct device_node *np;

	cpm_reset();
	init_ioports();

	np = of_find_compatible_node(NULL, NULL, "fsl,mpc885ads-bcsr");
	if (!np) {
		printk(KERN_CRIT "Could not find fsl,mpc885ads-bcsr node\n");
		return;
	}

	bcsr = of_iomap(np, 0);
	bcsr5 = of_iomap(np, 1);
	of_node_put(np);

	if (!bcsr || !bcsr5) {
		printk(KERN_CRIT "Could not remap BCSR\n");
		return;
	}

	clrbits32(&bcsr[1], BCSR1_RS232EN_1);
#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
	setbits32(&bcsr[1], BCSR1_RS232EN_2);
#else
	clrbits32(&bcsr[1], BCSR1_RS232EN_2);
#endif

	clrbits32(bcsr5, BCSR5_MII1_EN);
	setbits32(bcsr5, BCSR5_MII1_RST);
	udelay(1000);
	clrbits32(bcsr5, BCSR5_MII1_RST);

#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
	clrbits32(bcsr5, BCSR5_MII2_EN);
	setbits32(bcsr5, BCSR5_MII2_RST);
	udelay(1000);
	clrbits32(bcsr5, BCSR5_MII2_RST);
#else
	setbits32(bcsr5, BCSR5_MII2_EN);
#endif

#ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3
	clrbits32(&bcsr[4], BCSR4_ETH10_RST);
	udelay(1000);
	setbits32(&bcsr[4], BCSR4_ETH10_RST);

	setbits32(&bcsr[1], BCSR1_ETHEN);

	np = of_find_node_by_path("/soc@ff000000/cpm@9c0/serial@a80");
#else
	np = of_find_node_by_path("/soc@ff000000/cpm@9c0/ethernet@a40");
#endif

	/* The SCC3 enet registers overlap the SMC1 registers, so
	 * one of the two must be removed from the device tree.
	 */

	if (np) {
		of_detach_node(np);
		of_node_put(np);
	}
}