diff --git a/drivers/staging/greybus/authentication.c b/drivers/staging/greybus/authentication.c index a4ac3bbdcb86..168626ba0c03 100644 --- a/drivers/staging/greybus/authentication.c +++ b/drivers/staging/greybus/authentication.c @@ -265,6 +265,7 @@ static long cap_ioctl_unlocked(struct file *file, unsigned int cmd, unsigned long arg) { struct gb_cap *cap = file->private_data; + struct gb_bundle *bundle = cap->connection->bundle; int ret = -ENODEV; /* @@ -278,8 +279,13 @@ static long cap_ioctl_unlocked(struct file *file, unsigned int cmd, * new operations. */ mutex_lock(&cap->mutex); - if (!cap->disabled) - ret = cap_ioctl(cap, cmd, (void __user *)arg); + if (!cap->disabled) { + ret = gb_pm_runtime_get_sync(bundle); + if (!ret) { + ret = cap_ioctl(cap, cmd, (void __user *)arg); + gb_pm_runtime_put_autosuspend(bundle); + } + } mutex_unlock(&cap->mutex); return ret; diff --git a/drivers/staging/greybus/fw-core.c b/drivers/staging/greybus/fw-core.c index 19f92fb0331b..56296db0b509 100644 --- a/drivers/staging/greybus/fw-core.c +++ b/drivers/staging/greybus/fw-core.c @@ -20,6 +20,27 @@ struct gb_fw_core { struct gb_connection *cap_connection; }; +#ifndef SPI_CORE_SUPPORT_PM +static int fw_spi_prepare_transfer_hardware(struct device *dev) +{ + return gb_pm_runtime_get_sync(to_gb_bundle(dev)); +} + +static void fw_spi_unprepare_transfer_hardware(struct device *dev) +{ + gb_pm_runtime_put_autosuspend(to_gb_bundle(dev)); +} + +static struct spilib_ops __spilib_ops = { + .prepare_transfer_hardware = fw_spi_prepare_transfer_hardware, + .unprepare_transfer_hardware = fw_spi_unprepare_transfer_hardware, +}; + +static struct spilib_ops *spilib_ops = &__spilib_ops; +#else +static struct spilib_ops *spilib_ops = NULL; +#endif + struct gb_connection *to_fw_mgmt_connection(struct device *dev) { struct gb_fw_core *fw_core = dev_get_drvdata(dev); @@ -38,7 +59,8 @@ static int gb_fw_spi_connection_init(struct gb_connection *connection) if (ret) return ret; - ret = gb_spilib_master_init(connection, &connection->bundle->dev, NULL); + ret = gb_spilib_master_init(connection, &connection->bundle->dev, + spilib_ops); if (ret) { gb_connection_disable(connection); return ret; @@ -206,6 +228,8 @@ static int gb_fw_core_probe(struct gb_bundle *bundle, greybus_set_drvdata(bundle, fw_core); + gb_pm_runtime_put_autosuspend(bundle); + return 0; err_exit_connections: @@ -225,6 +249,11 @@ err_destroy_connections: static void gb_fw_core_disconnect(struct gb_bundle *bundle) { struct gb_fw_core *fw_core = greybus_get_drvdata(bundle); + int ret; + + ret = gb_pm_runtime_get_sync(bundle); + if (ret) + gb_pm_runtime_get_noresume(bundle); gb_fw_mgmt_connection_exit(fw_core->mgmt_connection); gb_cap_connection_exit(fw_core->cap_connection); diff --git a/drivers/staging/greybus/fw-management.c b/drivers/staging/greybus/fw-management.c index ccd9d7c91416..2efe65cfd612 100644 --- a/drivers/staging/greybus/fw-management.c +++ b/drivers/staging/greybus/fw-management.c @@ -507,6 +507,7 @@ static long fw_mgmt_ioctl_unlocked(struct file *file, unsigned int cmd, unsigned long arg) { struct fw_mgmt *fw_mgmt = file->private_data; + struct gb_bundle *bundle = fw_mgmt->connection->bundle; int ret = -ENODEV; /* @@ -522,8 +523,13 @@ static long fw_mgmt_ioctl_unlocked(struct file *file, unsigned int cmd, * new operations. */ mutex_lock(&fw_mgmt->mutex); - if (!fw_mgmt->disabled) - ret = fw_mgmt_ioctl(fw_mgmt, cmd, (void __user *)arg); + if (!fw_mgmt->disabled) { + ret = gb_pm_runtime_get_sync(bundle); + if (!ret) { + ret = fw_mgmt_ioctl(fw_mgmt, cmd, (void __user *)arg); + gb_pm_runtime_put_autosuspend(bundle); + } + } mutex_unlock(&fw_mgmt->mutex); return ret;