static int tmf8829_probe(tmf8829_chip *chip)
{
int error = -1;
void *poll_prop_ptr = NULL;
/* Platform Setup */
mutex_init(&chip->lock);
mutex_init(&chip->fifo_lock);
chip->pdata = &tmf8829_pdata;
error = tof_get_gpio_config(chip);
if (error) {
dev_err(&chip->client->dev, "Error gpio config.\n");
goto gpio_err;
}
if (writePin( chip->pdata->gpiod_enable, 1)) {
dev_err(&chip->client->dev, "Chip enable failed.\n");
goto gpio_err;
}
dev_info(&chip->client->dev, "Chip enable done.\n");
/* Setup IRQ Handling */
poll_prop_ptr = (void *)of_get_property(chip->client->dev.of_node, TOF_PROP_NAME_POLLIO, NULL);
chip->poll_period = poll_prop_ptr ? be32_to_cpup(poll_prop_ptr) : 0;
if(chip->poll_period == 0) { /* Use Interrupt I/O */
if (chip->pdata->gpiod_interrupt) {
error = tof_request_irq(chip);
if (error) {
dev_err(&chip->client->dev, "Interrupt request failed.\n");
goto gpio_err;
}
}
}
else { /* Polled I/O */
chip->app_poll_irq = kthread_run(tmf8829_app_poll_irq_thread, (void *)chip, "tof-irq_poll");
if (IS_ERR(chip->app_poll_irq)) {
dev_err(&chip->client->dev, "Error starting IRQ polling thread.\n");
error = PTR_ERR(chip->app_poll_irq);
goto gpio_err;
}
}
/* initialize kfifo for frame output */
INIT_KFIFO(chip->tof_output_fifo);
chip->tof_output_frame.frame.frameId = TMF8829_COM_RESULT__no_frame;
chip->tof_output_frame.frame.frameNumber = 0;
chip->tof_output_frame.frame.clkcorr_lsb = 0;
chip->tof_output_frame.frame.clkcorr_msb = 0;
chip->tof_output_frame.frame.reserved_0 = 0x77;
chip->tof_output_frame.frame.reserved_1 = 0x77;
chip->tof_output_frame.frame.payload_lsb = 0;
chip->tof_output_frame.frame.payload_msb = 0;
/* TMF8829 Setup */
AMS_MUTEX_LOCK(&chip->lock);
tmf8829Initialise(&chip->tof_core);
tmf8829SetLogLevel(&chip->tof_core, APP_LOG_LEVEL);
delayInMicroseconds(ENABLE_TIME_MS * 1000);
tmf8829PowerUp(&chip->tof_core);
if (tmf8829IsCpuReady(&chip->tof_core, CPU_READY_TIME_MS) == 0) {
dev_err(&chip->client->dev, "CPU is not ready.\n");
error = 5;
goto gen_err;
}
/* switch off unused communication interface */
#ifdef USE_I2C
error = tmf8829BootloaderCmdSpiOff(&chip->tof_core);
#endif
#ifdef USE_SPI
error = tmf8829BootloaderCmdI2cOff(&chip->tof_core);
#endif
if (error != BL_SUCCESS_OK) {
dev_err(&chip->client->dev, "error disable communication interface .\n");
goto gen_err;
}
error = firmware_download(&chip->client->dev);
if (error != 0) {
goto gen_err;
}
else {
dev_info(&chip->client->dev, "Firmware download done.\n");
}
if (tmf8829GetConfiguration(&chip->tof_core) != APP_SUCCESS_OK) {
dev_err(&chip->client->dev, "Read device configuration error.\n");
goto gen_err;
}
if (tmf8829ReadDeviceInfo( &chip->tof_core) != APP_SUCCESS_OK) {
dev_err(&chip->client->dev, "Read device information.\n");
goto gen_err;
}
chip->tof_core.cyclicRunning = 0;
tmf8829ClrAndEnableInterrupts( &chip->tof_core, TMF8829_APP_INT_ALL );
/* Sysfs Setup */
error = sysfs_create_groups(&chip->client->dev.kobj, tmf8829_attr_groups);
if (error) {
dev_err(&chip->client->dev, "Error creating sysfs attribute group.\n");
goto sysfs_err;
}
/* setup misc char device */
chip->tof_mdev.fops = &tof_miscdev_fops;
chip->tof_mdev.name = "tof_tmf8829";
chip->tof_mdev.minor = MISC_DYNAMIC_MINOR;
error = misc_register(&chip->tof_mdev);
if (error) {
dev_err(&chip->client->dev, "Error registering misc_dev.\n");
goto misc_reg_err;
}
dev_info(&chip->client->dev, "Probe pass.\n");
AMS_MUTEX_UNLOCK(&chip->lock);
return 0;
/* Probe error handling */
misc_reg_err:
sysfs_err:
sysfs_remove_groups(&chip->client->dev.kobj, tmf8829_attr_groups);
gen_err:
AMS_MUTEX_UNLOCK(&chip->lock);
if (chip->poll_period != 0) {
(void)kthread_stop(chip->app_poll_irq);
}
gpio_err:
enablePinLow(chip);
AMS_MUTEX_UNLOCK(&chip->lock);
return error;
}
In this function, the first four instances of goto gpio_err; are prior to the first instance of AMS_MUTEX_LOCK(&chip->lock); which leads to a disallowed release of a non-locked mutex.
In this function, the first four instances of
goto gpio_err;are prior to the first instance ofAMS_MUTEX_LOCK(&chip->lock);which leads to a disallowed release of a non-locked mutex.