static int wf_sat_probe()

in windfarm_smu_sat.c [192:317]


static int wf_sat_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct device_node *dev = client->dev.of_node;
	struct wf_sat *sat;
	struct wf_sat_sensor *sens;
	const u32 *reg;
	const char *loc;
	u8 chip, core;
	struct device_node *child;
	int shift, cpu, index;
	char *name;
	int vsens[2], isens[2];

	sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL);
	if (sat == NULL)
		return -ENOMEM;
	sat->nr = -1;
	sat->node = of_node_get(dev);
	kref_init(&sat->ref);
	mutex_init(&sat->mutex);
	sat->i2c = client;
	INIT_LIST_HEAD(&sat->sensors);
	i2c_set_clientdata(client, sat);

	vsens[0] = vsens[1] = -1;
	isens[0] = isens[1] = -1;
	for_each_child_of_node(dev, child) {
		reg = of_get_property(child, "reg", NULL);
		loc = of_get_property(child, "location", NULL);
		if (reg == NULL || loc == NULL)
			continue;

		/* the cooked sensors are between 0x30 and 0x37 */
		if (*reg < 0x30 || *reg > 0x37)
			continue;
		index = *reg - 0x30;

		/* expect location to be CPU [AB][01] ... */
		if (strncmp(loc, "CPU ", 4) != 0)
			continue;
		chip = loc[4] - 'A';
		core = loc[5] - '0';
		if (chip > 1 || core > 1) {
			printk(KERN_ERR "wf_sat_create: don't understand "
			       "location %s for %pOF\n", loc, child);
			continue;
		}
		cpu = 2 * chip + core;
		if (sat->nr < 0)
			sat->nr = chip;
		else if (sat->nr != chip) {
			printk(KERN_ERR "wf_sat_create: can't cope with "
			       "multiple CPU chips on one SAT (%s)\n", loc);
			continue;
		}

		if (of_node_is_type(child, "voltage-sensor")) {
			name = "cpu-voltage";
			shift = 4;
			vsens[core] = index;
		} else if (of_node_is_type(child, "current-sensor")) {
			name = "cpu-current";
			shift = 8;
			isens[core] = index;
		} else if (of_node_is_type(child, "temp-sensor")) {
			name = "cpu-temp";
			shift = 10;
		} else
			continue;	/* hmmm shouldn't happen */

		/* the +16 is enough for "cpu-voltage-n" */
		sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL);
		if (sens == NULL) {
			printk(KERN_ERR "wf_sat_create: couldn't create "
			       "%s sensor %d (no memory)\n", name, cpu);
			continue;
		}
		sens->index = index;
		sens->index2 = -1;
		sens->shift = shift;
		sens->sat = sat;
		sens->sens.ops = &wf_sat_ops;
		sens->sens.name = (char *) (sens + 1);
		snprintf((char *)sens->sens.name, 16, "%s-%d", name, cpu);

		if (wf_register_sensor(&sens->sens))
			kfree(sens);
		else {
			list_add(&sens->link, &sat->sensors);
			kref_get(&sat->ref);
		}
	}

	/* make the power sensors */
	for (core = 0; core < 2; ++core) {
		if (vsens[core] < 0 || isens[core] < 0)
			continue;
		cpu = 2 * sat->nr + core;
		sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL);
		if (sens == NULL) {
			printk(KERN_ERR "wf_sat_create: couldn't create power "
			       "sensor %d (no memory)\n", cpu);
			continue;
		}
		sens->index = vsens[core];
		sens->index2 = isens[core];
		sens->shift = 0;
		sens->sat = sat;
		sens->sens.ops = &wf_sat_ops;
		sens->sens.name = (char *) (sens + 1);
		snprintf((char *)sens->sens.name, 16, "cpu-power-%d", cpu);

		if (wf_register_sensor(&sens->sens))
			kfree(sens);
		else {
			list_add(&sens->link, &sat->sensors);
			kref_get(&sat->ref);
		}
	}

	if (sat->nr >= 0)
		sats[sat->nr] = sat;

	return 0;
}