Esempio n. 1
0
/*
 * Probe device tree for supported idle states
 */
static void __init pnv_probe_idle_states(void)
{
	struct device_node *np;
	int dt_idle_states;
	u32 *flags = NULL;
	int i;

	np = of_find_node_by_path("/ibm,opal/power-mgt");
	if (!np) {
		pr_warn("opal: PowerMgmt Node not found\n");
		goto out;
	}
	dt_idle_states = of_property_count_u32_elems(np,
			"ibm,cpu-idle-state-flags");
	if (dt_idle_states < 0) {
		pr_warn("cpuidle-powernv: no idle states found in the DT\n");
		goto out;
	}

	flags = kcalloc(dt_idle_states, sizeof(*flags),  GFP_KERNEL);

	if (of_property_read_u32_array(np,
			"ibm,cpu-idle-state-flags", flags, dt_idle_states)) {
		pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-flags in DT\n");
		goto out;
	}

	if (cpu_has_feature(CPU_FTR_ARCH_300)) {
		if (pnv_power9_idle_init(np, flags, dt_idle_states))
			goto out;
	}

	for (i = 0; i < dt_idle_states; i++)
		supported_cpuidle_states |= flags[i];

out:
	kfree(flags);
}
Esempio n. 2
0
static int mvebu_gicp_probe(struct platform_device *pdev)
{
	struct mvebu_gicp *gicp;
	struct irq_domain *inner_domain, *plat_domain, *parent_domain;
	struct device_node *node = pdev->dev.of_node;
	struct device_node *irq_parent_dn;
	int ret, i;

	gicp = devm_kzalloc(&pdev->dev, sizeof(*gicp), GFP_KERNEL);
	if (!gicp)
		return -ENOMEM;

	gicp->dev = &pdev->dev;
	spin_lock_init(&gicp->spi_lock);

	gicp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!gicp->res)
		return -ENODEV;

	ret = of_property_count_u32_elems(node, "marvell,spi-ranges");
	if (ret < 0)
		return ret;

	gicp->spi_ranges_cnt = ret / 2;

	gicp->spi_ranges =
		devm_kzalloc(&pdev->dev,
			     gicp->spi_ranges_cnt *
			     sizeof(struct mvebu_gicp_spi_range),
			     GFP_KERNEL);
	if (!gicp->spi_ranges)
		return -ENOMEM;

	for (i = 0; i < gicp->spi_ranges_cnt; i++) {
		of_property_read_u32_index(node, "marvell,spi-ranges",
					   i * 2,
					   &gicp->spi_ranges[i].start);

		of_property_read_u32_index(node, "marvell,spi-ranges",
					   i * 2 + 1,
					   &gicp->spi_ranges[i].count);

		gicp->spi_cnt += gicp->spi_ranges[i].count;
	}

	gicp->spi_bitmap = devm_kzalloc(&pdev->dev,
				BITS_TO_LONGS(gicp->spi_cnt) * sizeof(long),
				GFP_KERNEL);
	if (!gicp->spi_bitmap)
		return -ENOMEM;

	irq_parent_dn = of_irq_find_parent(node);
	if (!irq_parent_dn) {
		dev_err(&pdev->dev, "failed to find parent IRQ node\n");
		return -ENODEV;
	}

	parent_domain = irq_find_host(irq_parent_dn);
	if (!parent_domain) {
		dev_err(&pdev->dev, "failed to find parent IRQ domain\n");
		return -ENODEV;
	}

	inner_domain = irq_domain_create_hierarchy(parent_domain, 0,
						   gicp->spi_cnt,
						   of_node_to_fwnode(node),
						   &gicp_domain_ops, gicp);
	if (!inner_domain)
		return -ENOMEM;


	plat_domain = platform_msi_create_irq_domain(of_node_to_fwnode(node),
						     &gicp_msi_domain_info,
						     inner_domain);
	if (!plat_domain) {
		irq_domain_remove(inner_domain);
		return -ENOMEM;
	}

	platform_set_drvdata(pdev, gicp);

	return 0;
}
/**
 * ti_abb_init_table() - Initialize ABB table from device tree
 * @dev:	device
 * @abb:	pointer to the abb instance
 * @rinit_data:	regulator initdata
 *
 * Return: 0 on success or appropriate error value when fails
 */
static int ti_abb_init_table(struct device *dev, struct ti_abb *abb,
			     struct regulator_init_data *rinit_data)
{
	struct ti_abb_info *info;
	const u32 num_values = 6;
	char *pname = "ti,abb_info";
	u32 i;
	unsigned int *volt_table;
	int num_entries, min_uV = INT_MAX, max_uV = 0;
	struct regulation_constraints *c = &rinit_data->constraints;

	/*
	 * Each abb_info is a set of n-tuple, where n is num_values, consisting
	 * of voltage and a set of detection logic for ABB information for that
	 * voltage to apply.
	 */
	num_entries = of_property_count_u32_elems(dev->of_node, pname);
	if (num_entries < 0) {
		dev_err(dev, "No '%s' property?\n", pname);
		return num_entries;
	}

	if (!num_entries || (num_entries % num_values)) {
		dev_err(dev, "All '%s' list entries need %d vals\n", pname,
			num_values);
		return -EINVAL;
	}
	num_entries /= num_values;

	info = devm_kzalloc(dev, sizeof(*info) * num_entries, GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	abb->info = info;

	volt_table = devm_kzalloc(dev, sizeof(unsigned int) * num_entries,
				  GFP_KERNEL);
	if (!volt_table)
		return -ENOMEM;

	abb->rdesc.n_voltages = num_entries;
	abb->rdesc.volt_table = volt_table;
	/* We do not know where the OPP voltage is at the moment */
	abb->current_info_idx = -EINVAL;

	for (i = 0; i < num_entries; i++, info++, volt_table++) {
		u32 efuse_offset, rbb_mask, fbb_mask, vset_mask;
		u32 efuse_val;

		/* NOTE: num_values should equal to entries picked up here */
		of_property_read_u32_index(dev->of_node, pname, i * num_values,
					   volt_table);
		of_property_read_u32_index(dev->of_node, pname,
					   i * num_values + 1, &info->opp_sel);
		of_property_read_u32_index(dev->of_node, pname,
					   i * num_values + 2, &efuse_offset);
		of_property_read_u32_index(dev->of_node, pname,
					   i * num_values + 3, &rbb_mask);
		of_property_read_u32_index(dev->of_node, pname,
					   i * num_values + 4, &fbb_mask);
		of_property_read_u32_index(dev->of_node, pname,
					   i * num_values + 5, &vset_mask);

		dev_dbg(dev,
			"[%d]v=%d ABB=%d ef=0x%x rbb=0x%x fbb=0x%x vset=0x%x\n",
			i, *volt_table, info->opp_sel, efuse_offset, rbb_mask,
			fbb_mask, vset_mask);

		/* Find min/max for voltage set */
		if (min_uV > *volt_table)
			min_uV = *volt_table;
		if (max_uV < *volt_table)
			max_uV = *volt_table;

		if (!abb->efuse_base) {
			/* Ignore invalid data, but warn to help cleanup */
			if (efuse_offset || rbb_mask || fbb_mask || vset_mask)
				dev_err(dev, "prop '%s': v=%d,bad efuse/mask\n",
					pname, *volt_table);
			goto check_abb;
		}

		efuse_val = readl(abb->efuse_base + efuse_offset);

		/* Use ABB recommendation from Efuse */
		if (efuse_val & rbb_mask)
			info->opp_sel = TI_ABB_SLOW_OPP;
		else if (efuse_val & fbb_mask)
			info->opp_sel = TI_ABB_FAST_OPP;
		else if (rbb_mask || fbb_mask)
			info->opp_sel = TI_ABB_NOMINAL_OPP;

		dev_dbg(dev,
			"[%d]v=%d efusev=0x%x final ABB=%d\n",
			i, *volt_table, efuse_val, info->opp_sel);

		/* Use recommended Vset bits from Efuse */
		if (!abb->ldo_base) {
			if (vset_mask)
				dev_err(dev, "prop'%s':v=%d vst=%x LDO base?\n",
					pname, *volt_table, vset_mask);
			continue;
		}
		info->vset = (efuse_val & vset_mask) >> __ffs(vset_mask);
		dev_dbg(dev, "[%d]v=%d vset=%x\n", i, *volt_table, info->vset);
check_abb:
		switch (info->opp_sel) {
		case TI_ABB_NOMINAL_OPP:
		case TI_ABB_FAST_OPP:
		case TI_ABB_SLOW_OPP:
			/* Valid values */
			break;
		default:
			dev_err(dev, "%s:[%d]v=%d, ABB=%d is invalid! Abort!\n",
				__func__, i, *volt_table, info->opp_sel);
			return -EINVAL;
		}
	}

	/* Setup the min/max voltage constraints from the supported list */
	c->min_uV = min_uV;
	c->max_uV = max_uV;

	return 0;
}
Esempio n. 4
0
static struct gpio_regulator_config *
of_get_gpio_regulator_config(struct device *dev, struct device_node *np,
			     const struct regulator_desc *desc)
{
	struct gpio_regulator_config *config;
	const char *regtype;
	int proplen, gpio, i;
	int ret;

	config = devm_kzalloc(dev,
			sizeof(struct gpio_regulator_config),
			GFP_KERNEL);
	if (!config)
		return ERR_PTR(-ENOMEM);

	config->init_data = of_get_regulator_init_data(dev, np, desc);
	if (!config->init_data)
		return ERR_PTR(-EINVAL);

	config->supply_name = config->init_data->constraints.name;

	if (of_property_read_bool(np, "enable-active-high"))
		config->enable_high = true;

	if (of_property_read_bool(np, "enable-at-boot"))
		config->enabled_at_boot = true;

	of_property_read_u32(np, "startup-delay-us", &config->startup_delay);

	config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0);
	if (config->enable_gpio < 0 && config->enable_gpio != -ENOENT)
		return ERR_PTR(config->enable_gpio);

	/* Fetch GPIOs. - optional property*/
	ret = of_gpio_count(np);
	if ((ret < 0) && (ret != -ENOENT))
		return ERR_PTR(ret);

	if (ret > 0) {
		config->nr_gpios = ret;
		config->gpios = devm_kzalloc(dev,
					sizeof(struct gpio) * config->nr_gpios,
					GFP_KERNEL);
		if (!config->gpios)
			return ERR_PTR(-ENOMEM);

		proplen = of_property_count_u32_elems(np, "gpios-states");
		/* optional property */
		if (proplen < 0)
			proplen = 0;

		if (proplen > 0 && proplen != config->nr_gpios) {
			dev_warn(dev, "gpios <-> gpios-states mismatch\n");
			proplen = 0;
		}

		for (i = 0; i < config->nr_gpios; i++) {
			gpio = of_get_named_gpio(np, "gpios", i);
			if (gpio < 0) {
				if (gpio != -ENOENT)
					return ERR_PTR(gpio);
				break;
			}
			config->gpios[i].gpio = gpio;
			if (proplen > 0) {
				of_property_read_u32_index(np, "gpios-states",
							   i, &ret);
				if (ret)
					config->gpios[i].flags =
							   GPIOF_OUT_INIT_HIGH;
			}
		}
	}

	/* Fetch states. */
	proplen = of_property_count_u32_elems(np, "states");
	if (proplen < 0) {
		dev_err(dev, "No 'states' property found\n");
		return ERR_PTR(-EINVAL);
	}

	config->states = devm_kzalloc(dev,
				sizeof(struct gpio_regulator_state)
				* (proplen / 2),
				GFP_KERNEL);
	if (!config->states)
		return ERR_PTR(-ENOMEM);

	for (i = 0; i < proplen / 2; i++) {
		of_property_read_u32_index(np, "states", i * 2,
					   &config->states[i].value);
		of_property_read_u32_index(np, "states", i * 2 + 1,
					   &config->states[i].gpios);
	}
	config->nr_states = i;

	config->type = REGULATOR_VOLTAGE;
	ret = of_property_read_string(np, "regulator-type", &regtype);
	if (ret >= 0) {
		if (!strncmp("voltage", regtype, 7))
			config->type = REGULATOR_VOLTAGE;
		else if (!strncmp("current", regtype, 7))
			config->type = REGULATOR_CURRENT;
		else
			dev_warn(dev, "Unknown regulator-type '%s'\n",
				 regtype);
	}

	return config;
}
Esempio n. 5
0
/*
 * Probe function to setup the device, input system and interrupt
 */
static int atmel_captouch_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	struct atmel_captouch_device *capdev;
	struct device *dev = &client->dev;
	struct device_node *node;
	int i;
	int err;

	if (!i2c_check_functionality(client->adapter,
				     I2C_FUNC_SMBUS_BYTE_DATA |
					I2C_FUNC_SMBUS_WORD_DATA |
					I2C_FUNC_SMBUS_I2C_BLOCK)) {
		dev_err(dev, "needed i2c functionality is not supported\n");
		return -EINVAL;
	}

	capdev = devm_kzalloc(dev, sizeof(*capdev), GFP_KERNEL);
	if (!capdev)
		return -ENOMEM;

	capdev->client = client;

	err = atmel_read(capdev, REG_KEY_STATE,
			    &capdev->prev_btn, sizeof(capdev->prev_btn));
	if (err) {
		dev_err(dev, "failed to read initial button state: %d\n", err);
		return err;
	}

	capdev->input = devm_input_allocate_device(dev);
	if (!capdev->input) {
		dev_err(dev, "failed to allocate input device\n");
		return -ENOMEM;
	}

	capdev->input->id.bustype = BUS_I2C;
	capdev->input->id.product = 0x880A;
	capdev->input->id.version = 0;
	capdev->input->name = "ATMegaXX Capacitive Button Controller";
	__set_bit(EV_KEY, capdev->input->evbit);

	node = dev->of_node;
	if (!node) {
		dev_err(dev, "failed to find matching node in device tree\n");
		return -EINVAL;
	}

	if (of_property_read_bool(node, "autorepeat"))
		__set_bit(EV_REP, capdev->input->evbit);

	capdev->num_btn = of_property_count_u32_elems(node, "linux,keymap");
	if (capdev->num_btn > MAX_NUM_OF_BUTTONS)
		capdev->num_btn = MAX_NUM_OF_BUTTONS;

	err = of_property_read_u32_array(node, "linux,keycodes",
					 capdev->keycodes,
					 capdev->num_btn);
	if (err) {
		dev_err(dev,
			"failed to read linux,keycode property: %d\n", err);
		return err;
	}

	for (i = 0; i < capdev->num_btn; i++)
		__set_bit(capdev->keycodes[i], capdev->input->keybit);

	capdev->input->keycode = capdev->keycodes;
	capdev->input->keycodesize = sizeof(capdev->keycodes[0]);
	capdev->input->keycodemax = capdev->num_btn;

	err = input_register_device(capdev->input);
	if (err)
		return err;

	err = devm_request_threaded_irq(dev, client->irq,
					NULL, atmel_captouch_isr,
					IRQF_ONESHOT,
					"atmel_captouch", capdev);
	if (err) {
		dev_err(dev, "failed to request irq %d: %d\n",
			client->irq, err);
		return err;
	}

	return 0;
}
Esempio n. 6
0
static int tsens_probe(struct platform_device *pdev)
{
	int ret, i, num;
	struct device *dev;
	struct device_node *np;
	struct tsens_sensor *s;
	struct tsens_device *tmdev;
	const struct of_device_id *id;

	if (pdev->dev.of_node)
		dev = &pdev->dev;
	else
		dev = pdev->dev.parent;

	np = dev->of_node;

	num = of_property_count_u32_elems(np, "qcom,tsens-slopes");
	if (num <= 0) {
		dev_err(dev, "invalid tsens slopes\n");
		return -EINVAL;
	}

	tmdev = devm_kzalloc(dev, sizeof(*tmdev) +
			     num * sizeof(*s), GFP_KERNEL);
	if (!tmdev)
		return -ENOMEM;

	tmdev->dev = dev;
	tmdev->num_sensors = num;

	for (i = 0, s = tmdev->sensor; i < tmdev->num_sensors; i++, s++)
		of_property_read_u32_index(np, "qcom,tsens-slopes", i,
					   &s->slope);

	id = of_match_node(tsens_table, np);
	if (id)
		tmdev->ops = id->data;
	else
		tmdev->ops = &ops_8960;

	if (!tmdev->ops || !tmdev->ops->init || !tmdev->ops->calibrate ||
	    !tmdev->ops->get_temp)
		return -EINVAL;

	ret = tmdev->ops->init(tmdev);
	if (ret < 0) {
		dev_err(dev, "tsens init failed\n");
		return ret;
	}

	ret = tmdev->ops->calibrate(tmdev);
	if (ret < 0) {
		dev_err(dev, "tsens calibration failed\n");
		return ret;
	}

	ret = tsens_register(tmdev);

	platform_set_drvdata(pdev, tmdev);

	return ret;
}
Esempio n. 7
0
int __init opal_event_init(void)
{
	struct device_node *dn, *opal_node;
	const char **names;
	u32 *irqs;
	int i, rc;

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

	/* If dn is NULL it means the domain won't be linked to a DT
	 * node so therefore irq_of_parse_and_map(...) wont work. But
	 * that shouldn't be problem because if we're running a
	 * version of skiboot that doesn't have the dn then the
	 * devices won't have the correct properties and will have to
	 * fall back to the legacy method (opal_event_request(...))
	 * anyway. */
	dn = of_find_compatible_node(NULL, NULL, "ibm,opal-event");
	opal_event_irqchip.domain = irq_domain_add_linear(dn, MAX_NUM_EVENTS,
				&opal_event_domain_ops, &opal_event_irqchip);
	of_node_put(dn);
	if (!opal_event_irqchip.domain) {
		pr_warn("opal: Unable to create irq domain\n");
		rc = -ENOMEM;
		goto out;
	}

	/* Get opal-interrupts property and names if present */
	rc = of_property_count_u32_elems(opal_node, "opal-interrupts");
	if (rc < 0)
		goto out;

	opal_irq_count = rc;
	pr_debug("Found %d interrupts reserved for OPAL\n", opal_irq_count);

	irqs = kcalloc(opal_irq_count, sizeof(*irqs), GFP_KERNEL);
	names = kcalloc(opal_irq_count, sizeof(*names), GFP_KERNEL);
	opal_irqs = kcalloc(opal_irq_count, sizeof(*opal_irqs), GFP_KERNEL);

	if (WARN_ON(!irqs || !names || !opal_irqs))
		goto out_free;

	rc = of_property_read_u32_array(opal_node, "opal-interrupts",
					irqs, opal_irq_count);
	if (rc < 0) {
		pr_err("Error %d reading opal-interrupts array\n", rc);
		goto out_free;
	}

	/* It's not an error for the names to be missing */
	of_property_read_string_array(opal_node, "opal-interrupts-names",
				      names, opal_irq_count);

	/* Install interrupt handlers */
	for (i = 0; i < opal_irq_count; i++) {
		unsigned int virq;
		char *name;

		/* Get hardware and virtual IRQ */
		virq = irq_create_mapping(NULL, irqs[i]);
		if (!virq) {
			pr_warn("Failed to map irq 0x%x\n", irqs[i]);
			continue;
		}

		if (names[i] && strlen(names[i]))
			name = kasprintf(GFP_KERNEL, "opal-%s", names[i]);
		else
			name = kasprintf(GFP_KERNEL, "opal");

		/* Install interrupt handler */
		rc = request_irq(virq, opal_interrupt, IRQF_TRIGGER_LOW,
				 name, NULL);
		if (rc) {
			irq_dispose_mapping(virq);
			pr_warn("Error %d requesting irq %d (0x%x)\n",
				 rc, virq, irqs[i]);
			continue;
		}

		/* Cache IRQ */
		opal_irqs[i] = virq;
	}

out_free:
	kfree(irqs);
	kfree(names);
out:
	of_node_put(opal_node);
	return rc;
}
Esempio n. 8
0
static int powernv_add_idle_states(void)
{
	struct device_node *power_mgt;
	int nr_idle_states = 1; /* Snooze */
	int dt_idle_states;
	u32 *latency_ns, *residency_ns, *flags;
	int i, rc;

	/* Currently we have snooze statically defined */

	power_mgt = of_find_node_by_path("/ibm,opal/power-mgt");
	if (!power_mgt) {
		pr_warn("opal: PowerMgmt Node not found\n");
		goto out;
	}

	/* Read values of any property to determine the num of idle states */
	dt_idle_states = of_property_count_u32_elems(power_mgt, "ibm,cpu-idle-state-flags");
	if (dt_idle_states < 0) {
		pr_warn("cpuidle-powernv: no idle states found in the DT\n");
		goto out;
	}

	flags = kzalloc(sizeof(*flags) * dt_idle_states, GFP_KERNEL);
	if (of_property_read_u32_array(power_mgt,
			"ibm,cpu-idle-state-flags", flags, dt_idle_states)) {
		pr_warn("cpuidle-powernv : missing ibm,cpu-idle-state-flags in DT\n");
		goto out_free_flags;
	}

	latency_ns = kzalloc(sizeof(*latency_ns) * dt_idle_states, GFP_KERNEL);
	rc = of_property_read_u32_array(power_mgt,
		"ibm,cpu-idle-state-latencies-ns", latency_ns, dt_idle_states);
	if (rc) {
		pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-latencies-ns in DT\n");
		goto out_free_latency;
	}

	residency_ns = kzalloc(sizeof(*residency_ns) * dt_idle_states, GFP_KERNEL);
	rc = of_property_read_u32_array(power_mgt,
		"ibm,cpu-idle-state-residency-ns", residency_ns, dt_idle_states);

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

		/*
		 * Cpuidle accepts exit_latency and target_residency in us.
		 * Use default target_residency values if f/w does not expose it.
		 */
		if (flags[i] & OPAL_PM_NAP_ENABLED) {
			/* Add NAP state */
			strcpy(powernv_states[nr_idle_states].name, "Nap");
			strcpy(powernv_states[nr_idle_states].desc, "Nap");
			powernv_states[nr_idle_states].flags = 0;
			powernv_states[nr_idle_states].target_residency = 100;
			powernv_states[nr_idle_states].enter = &nap_loop;
		}

		/*
		 * All cpuidle states with CPUIDLE_FLAG_TIMER_STOP set must come
		 * within this config dependency check.
		 */
#ifdef CONFIG_TICK_ONESHOT
		if (flags[i] & OPAL_PM_SLEEP_ENABLED ||
			flags[i] & OPAL_PM_SLEEP_ENABLED_ER1) {
			/* Add FASTSLEEP state */
			strcpy(powernv_states[nr_idle_states].name, "FastSleep");
			strcpy(powernv_states[nr_idle_states].desc, "FastSleep");
			powernv_states[nr_idle_states].flags = CPUIDLE_FLAG_TIMER_STOP;
			powernv_states[nr_idle_states].target_residency = 300000;
			powernv_states[nr_idle_states].enter = &fastsleep_loop;
		}
#endif
		powernv_states[nr_idle_states].exit_latency =
				((unsigned int)latency_ns[i]) / 1000;

		if (!rc) {
			powernv_states[nr_idle_states].target_residency =
				((unsigned int)residency_ns[i]) / 1000;
		}

		nr_idle_states++;
	}

	kfree(residency_ns);
out_free_latency:
	kfree(latency_ns);
out_free_flags:
	kfree(flags);
out:
	return nr_idle_states;
}