static int lm90_probe()

in lm90.c [1858:2000]


static int lm90_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct i2c_adapter *adapter = client->adapter;
	struct hwmon_channel_info *info;
	struct regulator *regulator;
	struct device *hwmon_dev;
	struct lm90_data *data;
	int err;

	regulator = devm_regulator_get(dev, "vcc");
	if (IS_ERR(regulator))
		return PTR_ERR(regulator);

	err = regulator_enable(regulator);
	if (err < 0) {
		dev_err(dev, "Failed to enable regulator: %d\n", err);
		return err;
	}

	err = devm_add_action_or_reset(dev, lm90_regulator_disable, regulator);
	if (err)
		return err;

	data = devm_kzalloc(dev, sizeof(struct lm90_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->client = client;
	i2c_set_clientdata(client, data);
	mutex_init(&data->update_lock);

	/* Set the device type */
	if (client->dev.of_node)
		data->kind = (enum chips)of_device_get_match_data(&client->dev);
	else
		data->kind = i2c_match_id(lm90_id, client)->driver_data;
	if (data->kind == adm1032) {
		if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
			client->flags &= ~I2C_CLIENT_PEC;
	}

	/*
	 * Different devices have different alarm bits triggering the
	 * ALERT# output
	 */
	data->alert_alarms = lm90_params[data->kind].alert_alarms;

	/* Set chip capabilities */
	data->flags = lm90_params[data->kind].flags;

	data->chip.ops = &lm90_ops;
	data->chip.info = data->info;

	data->info[0] = HWMON_CHANNEL_INFO(chip,
		HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL | HWMON_C_ALARMS);
	data->info[1] = &data->temp_info;

	info = &data->temp_info;
	info->type = hwmon_temp;
	info->config = data->channel_config;

	data->channel_config[0] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
		HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM;
	data->channel_config[1] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
		HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM | HWMON_T_FAULT;

	if (data->flags & LM90_HAVE_CRIT) {
		data->channel_config[0] |= HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_CRIT_HYST;
		data->channel_config[1] |= HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_CRIT_HYST;
	}

	if (data->flags & LM90_HAVE_OFFSET)
		data->channel_config[1] |= HWMON_T_OFFSET;

	if (data->flags & LM90_HAVE_EMERGENCY) {
		data->channel_config[0] |= HWMON_T_EMERGENCY |
			HWMON_T_EMERGENCY_HYST;
		data->channel_config[1] |= HWMON_T_EMERGENCY |
			HWMON_T_EMERGENCY_HYST;
	}

	if (data->flags & LM90_HAVE_EMERGENCY_ALARM) {
		data->channel_config[0] |= HWMON_T_EMERGENCY_ALARM;
		data->channel_config[1] |= HWMON_T_EMERGENCY_ALARM;
	}

	if (data->flags & LM90_HAVE_TEMP3) {
		data->channel_config[2] = HWMON_T_INPUT |
			HWMON_T_MIN | HWMON_T_MAX |
			HWMON_T_CRIT | HWMON_T_CRIT_HYST |
			HWMON_T_EMERGENCY | HWMON_T_EMERGENCY_HYST |
			HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM |
			HWMON_T_CRIT_ALARM | HWMON_T_EMERGENCY_ALARM |
			HWMON_T_FAULT;
	}

	data->reg_local_ext = lm90_params[data->kind].reg_local_ext;

	/* Set maximum conversion rate */
	data->max_convrate = lm90_params[data->kind].max_convrate;

	/* Initialize the LM90 chip */
	err = lm90_init_client(client, data);
	if (err < 0) {
		dev_err(dev, "Failed to initialize device\n");
		return err;
	}

	/*
	 * The 'pec' attribute is attached to the i2c device and thus created
	 * separately.
	 */
	if (client->flags & I2C_CLIENT_PEC) {
		err = device_create_file(dev, &dev_attr_pec);
		if (err)
			return err;
		err = devm_add_action_or_reset(dev, lm90_remove_pec, dev);
		if (err)
			return err;
	}

	hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
							 data, &data->chip,
							 NULL);
	if (IS_ERR(hwmon_dev))
		return PTR_ERR(hwmon_dev);

	data->hwmon_dev = hwmon_dev;

	if (client->irq) {
		dev_dbg(dev, "IRQ: %d\n", client->irq);
		err = devm_request_threaded_irq(dev, client->irq,
						NULL, lm90_irq_thread,
						IRQF_ONESHOT, "lm90", client);
		if (err < 0) {
			dev_err(dev, "cannot request IRQ %d\n", client->irq);
			return err;
		}
	}

	return 0;
}