static int kmx61_probe()

in imu/kmx61.c [1279:1416]


static int kmx61_probe(struct i2c_client *client,
		       const struct i2c_device_id *id)
{
	int ret;
	struct kmx61_data *data;
	const char *name = NULL;

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

	i2c_set_clientdata(client, data);
	data->client = client;

	mutex_init(&data->lock);

	if (id)
		name = id->name;
	else if (ACPI_HANDLE(&client->dev))
		name = kmx61_match_acpi_device(&client->dev);
	else
		return -ENODEV;

	data->acc_indio_dev =
		kmx61_indiodev_setup(data, &kmx61_acc_info,
				     kmx61_acc_channels,
				     ARRAY_SIZE(kmx61_acc_channels),
				     name);
	if (IS_ERR(data->acc_indio_dev))
		return PTR_ERR(data->acc_indio_dev);

	data->mag_indio_dev =
		kmx61_indiodev_setup(data, &kmx61_mag_info,
				     kmx61_mag_channels,
				     ARRAY_SIZE(kmx61_mag_channels),
				     name);
	if (IS_ERR(data->mag_indio_dev))
		return PTR_ERR(data->mag_indio_dev);

	ret = kmx61_chip_init(data);
	if (ret < 0)
		return ret;

	if (client->irq > 0) {
		ret = devm_request_threaded_irq(&client->dev, client->irq,
						kmx61_data_rdy_trig_poll,
						kmx61_event_handler,
						IRQF_TRIGGER_RISING,
						KMX61_IRQ_NAME,
						data);
		if (ret)
			goto err_chip_uninit;

		data->acc_dready_trig =
			kmx61_trigger_setup(data, data->acc_indio_dev,
					    "dready");
		if (IS_ERR(data->acc_dready_trig)) {
			ret = PTR_ERR(data->acc_dready_trig);
			goto err_chip_uninit;
		}

		data->mag_dready_trig =
			kmx61_trigger_setup(data, data->mag_indio_dev,
					    "dready");
		if (IS_ERR(data->mag_dready_trig)) {
			ret = PTR_ERR(data->mag_dready_trig);
			goto err_trigger_unregister_acc_dready;
		}

		data->motion_trig =
			kmx61_trigger_setup(data, data->acc_indio_dev,
					    "any-motion");
		if (IS_ERR(data->motion_trig)) {
			ret = PTR_ERR(data->motion_trig);
			goto err_trigger_unregister_mag_dready;
		}

		ret = iio_triggered_buffer_setup(data->acc_indio_dev,
						 &iio_pollfunc_store_time,
						 kmx61_trigger_handler,
						 NULL);
		if (ret < 0) {
			dev_err(&data->client->dev,
				"Failed to setup acc triggered buffer\n");
			goto err_trigger_unregister_motion;
		}

		ret = iio_triggered_buffer_setup(data->mag_indio_dev,
						 &iio_pollfunc_store_time,
						 kmx61_trigger_handler,
						 NULL);
		if (ret < 0) {
			dev_err(&data->client->dev,
				"Failed to setup mag triggered buffer\n");
			goto err_buffer_cleanup_acc;
		}
	}

	ret = pm_runtime_set_active(&client->dev);
	if (ret < 0)
		goto err_buffer_cleanup_mag;

	pm_runtime_enable(&client->dev);
	pm_runtime_set_autosuspend_delay(&client->dev, KMX61_SLEEP_DELAY_MS);
	pm_runtime_use_autosuspend(&client->dev);

	ret = iio_device_register(data->acc_indio_dev);
	if (ret < 0) {
		dev_err(&client->dev, "Failed to register acc iio device\n");
		goto err_buffer_cleanup_mag;
	}

	ret = iio_device_register(data->mag_indio_dev);
	if (ret < 0) {
		dev_err(&client->dev, "Failed to register mag iio device\n");
		goto err_iio_unregister_acc;
	}

	return 0;

err_iio_unregister_acc:
	iio_device_unregister(data->acc_indio_dev);
err_buffer_cleanup_mag:
	if (client->irq > 0)
		iio_triggered_buffer_cleanup(data->mag_indio_dev);
err_buffer_cleanup_acc:
	if (client->irq > 0)
		iio_triggered_buffer_cleanup(data->acc_indio_dev);
err_trigger_unregister_motion:
	iio_trigger_unregister(data->motion_trig);
err_trigger_unregister_mag_dready:
	iio_trigger_unregister(data->mag_dready_trig);
err_trigger_unregister_acc_dready:
	iio_trigger_unregister(data->acc_dready_trig);
err_chip_uninit:
	kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
	return ret;
}