diff options
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r-- | drivers/spi/spi.c | 97 |
1 files changed, 40 insertions, 57 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index b08efe88ccd6..ba425b9c7700 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -676,11 +676,10 @@ struct spi_device *spi_new_device(struct spi_controller *ctlr, proxy->controller_data = chip->controller_data; proxy->controller_state = NULL; - if (chip->properties) { - status = device_add_properties(&proxy->dev, chip->properties); + if (chip->swnode) { + status = device_add_software_node(&proxy->dev, chip->swnode); if (status) { - dev_err(&ctlr->dev, - "failed to add properties to '%s': %d\n", + dev_err(&ctlr->dev, "failed to add software node to '%s': %d\n", chip->modalias, status); goto err_dev_put; } @@ -688,14 +687,12 @@ struct spi_device *spi_new_device(struct spi_controller *ctlr, status = spi_add_device(proxy); if (status < 0) - goto err_remove_props; + goto err_dev_put; return proxy; -err_remove_props: - if (chip->properties) - device_remove_properties(&proxy->dev); err_dev_put: + device_remove_software_node(&proxy->dev); spi_dev_put(proxy); return NULL; } @@ -719,6 +716,7 @@ void spi_unregister_device(struct spi_device *spi) } if (ACPI_COMPANION(&spi->dev)) acpi_device_clear_enumerated(ACPI_COMPANION(&spi->dev)); + device_remove_software_node(&spi->dev); device_unregister(&spi->dev); } EXPORT_SYMBOL_GPL(spi_unregister_device); @@ -755,7 +753,6 @@ static void spi_match_controller_to_boardinfo(struct spi_controller *ctlr, * * The board info passed can safely be __initdata ... but be careful of * any embedded pointers (platform_data, etc), they're copied as-is. - * Device properties are deep-copied though. * * Return: zero on success, else a negative error code. */ @@ -775,12 +772,6 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n) struct spi_controller *ctlr; memcpy(&bi->board_info, info, sizeof(*info)); - if (info->properties) { - bi->board_info.properties = - property_entries_dup(info->properties); - if (IS_ERR(bi->board_info.properties)) - return PTR_ERR(bi->board_info.properties); - } mutex_lock(&board_lock); list_add_tail(&bi->list, &board_list); @@ -795,15 +786,15 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n) /*-------------------------------------------------------------------------*/ -static void spi_set_cs(struct spi_device *spi, bool enable) +static void spi_set_cs(struct spi_device *spi, bool enable, bool force) { - bool enable1 = enable; + bool activate = enable; /* * Avoid calling into the driver (or doing delays) if the chip select * isn't actually changing from the last time this was called. */ - if ((spi->controller->last_cs_enable == enable) && + if (!force && (spi->controller->last_cs_enable == enable) && (spi->controller->last_cs_mode_high == (spi->mode & SPI_CS_HIGH))) return; @@ -812,7 +803,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable) if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) || !spi->controller->set_cs_timing) { - if (enable1) + if (activate) spi_delay_exec(&spi->controller->cs_setup, NULL); else spi_delay_exec(&spi->controller->cs_hold, NULL); @@ -825,8 +816,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable) if (!(spi->mode & SPI_NO_CS)) { if (spi->cs_gpiod) /* polarity handled by gpiolib */ - gpiod_set_value_cansleep(spi->cs_gpiod, - enable1); + gpiod_set_value_cansleep(spi->cs_gpiod, activate); else /* * invert the enable line, as active low is @@ -844,7 +834,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable) if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) || !spi->controller->set_cs_timing) { - if (!enable1) + if (!activate) spi_delay_exec(&spi->controller->cs_inactive, NULL); } } @@ -1253,7 +1243,7 @@ static int spi_transfer_one_message(struct spi_controller *ctlr, struct spi_statistics *statm = &ctlr->statistics; struct spi_statistics *stats = &msg->spi->statistics; - spi_set_cs(msg->spi, true); + spi_set_cs(msg->spi, true, false); SPI_STATISTICS_INCREMENT_FIELD(statm, messages); SPI_STATISTICS_INCREMENT_FIELD(stats, messages); @@ -1321,9 +1311,9 @@ fallback_pio: &msg->transfers)) { keep_cs = true; } else { - spi_set_cs(msg->spi, false); + spi_set_cs(msg->spi, false, false); _spi_transfer_cs_change_delay(msg, xfer); - spi_set_cs(msg->spi, true); + spi_set_cs(msg->spi, true, false); } } @@ -1332,7 +1322,7 @@ fallback_pio: out: if (ret != 0 || !keep_cs) - spi_set_cs(msg->spi, false); + spi_set_cs(msg->spi, false, false); if (msg->status == -EINPROGRESS) msg->status = ret; @@ -2496,6 +2486,7 @@ struct spi_controller *__devm_spi_alloc_controller(struct device *dev, ctlr = __spi_alloc_controller(dev, size, slave); if (ctlr) { + ctlr->devm_allocated = true; *ptr = ctlr; devres_add(dev, ptr); } else { @@ -2559,13 +2550,14 @@ static int spi_get_gpio_descs(struct spi_controller *ctlr) unsigned int num_cs_gpios = 0; nb = gpiod_count(dev, "cs"); - ctlr->num_chipselect = max_t(int, nb, ctlr->num_chipselect); - - /* No GPIOs at all is fine, else return the error */ - if (nb == 0 || nb == -ENOENT) - return 0; - else if (nb < 0) + if (nb < 0) { + /* No GPIOs at all is fine, else return the error */ + if (nb == -ENOENT) + return 0; return nb; + } + + ctlr->num_chipselect = max_t(int, nb, ctlr->num_chipselect); cs = devm_kcalloc(dev, ctlr->num_chipselect, sizeof(*cs), GFP_KERNEL); @@ -2802,9 +2794,9 @@ free_bus_id: } EXPORT_SYMBOL_GPL(spi_register_controller); -static void devm_spi_unregister(struct device *dev, void *res) +static void devm_spi_unregister(void *ctlr) { - spi_unregister_controller(*(struct spi_controller **)res); + spi_unregister_controller(ctlr); } /** @@ -2823,30 +2815,16 @@ static void devm_spi_unregister(struct device *dev, void *res) int devm_spi_register_controller(struct device *dev, struct spi_controller *ctlr) { - struct spi_controller **ptr; int ret; - ptr = devres_alloc(devm_spi_unregister, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return -ENOMEM; - ret = spi_register_controller(ctlr); - if (!ret) { - *ptr = ctlr; - devres_add(dev, ptr); - } else { - devres_free(ptr); - } + if (ret) + return ret; - return ret; + return devm_add_action_or_reset(dev, devm_spi_unregister, ctlr); } EXPORT_SYMBOL_GPL(devm_spi_register_controller); -static int devm_spi_match_controller(struct device *dev, void *res, void *ctlr) -{ - return *(struct spi_controller **)res == ctlr; -} - static int __unregister(struct device *dev, void *null) { spi_unregister_device(to_spi_device(dev)); @@ -2893,8 +2871,7 @@ void spi_unregister_controller(struct spi_controller *ctlr) /* Release the last reference on the controller if its driver * has not yet been converted to devm_spi_alloc_master/slave(). */ - if (!devres_find(ctlr->dev.parent, devm_spi_release_controller, - devm_spi_match_controller, ctlr)) + if (!ctlr->devm_allocated) put_device(&ctlr->dev); /* free bus id */ @@ -3178,7 +3155,6 @@ struct spi_replaced_transfers *spi_replace_transfers( /* clear cs_change and delay for all but the last */ if (i) { xfer->cs_change = false; - xfer->delay_usecs = 0; xfer->delay.value = 0; } } @@ -3402,8 +3378,15 @@ int spi_setup(struct spi_device *spi) mutex_lock(&spi->controller->io_mutex); - if (spi->controller->setup) + if (spi->controller->setup) { status = spi->controller->setup(spi); + if (status) { + mutex_unlock(&spi->controller->io_mutex); + dev_err(&spi->controller->dev, "Failed to setup device: %d\n", + status); + return status; + } + } if (spi->controller->auto_runtime_pm && spi->controller->set_cs) { status = pm_runtime_get_sync(spi->controller->dev.parent); @@ -3423,11 +3406,11 @@ int spi_setup(struct spi_device *spi) */ status = 0; - spi_set_cs(spi, false); + spi_set_cs(spi, false, true); pm_runtime_mark_last_busy(spi->controller->dev.parent); pm_runtime_put_autosuspend(spi->controller->dev.parent); } else { - spi_set_cs(spi, false); + spi_set_cs(spi, false, true); } mutex_unlock(&spi->controller->io_mutex); |