Skip to content

Commit

Permalink
greybus: spilib: make spilib independent of gbphy
Browse files Browse the repository at this point in the history
spilib is used by multiple users currently (spi.c and fw-core.c) but
commit aa52b62a0556 broke that hierarchy and introduced gbphy dependent
code in spilib.

This may have unreliable consequences as we are doing following
operation unconditionally now:

	gbphy_dev = to_gbphy_dev(spi->parent);
	gbphy_runtime_get_sync(gbphy_dev);

which may not go well when the parent is of type &bundle->dev
(fw-core.c).

This patch introduces spilib_ops and lets the users of the core register
them. This shall have no functional change for the spi.c usecase and
shall fix the unreliable results for the fw-core.c usecase.

Tested by writing to mtd0 dev and verifying (with print messages) that
the below routines are getting called for a gpbridge-test module.

Fixes: aa52b62a0556 ("spi: Add runtime_pm support")
Signed-off-by: Viresh Kumar <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
vireshk authored and gregkh committed Jul 22, 2016
1 parent adac4b9 commit 92bcadd
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 15 deletions.
2 changes: 1 addition & 1 deletion drivers/staging/greybus/fw-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static int gb_fw_spi_connection_init(struct gb_connection *connection)
if (ret)
return ret;

ret = gb_spilib_master_init(connection, &connection->bundle->dev);
ret = gb_spilib_master_init(connection, &connection->bundle->dev, NULL);
if (ret) {
gb_connection_disable(connection);
return ret;
Expand Down
23 changes: 22 additions & 1 deletion drivers/staging/greybus/spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,27 @@
#include "gbphy.h"
#include "spilib.h"

#ifndef SPI_CORE_SUPPORT_PM
static int gbphy_spi_prepare_transfer_hardware(struct device *dev)
{
return gbphy_runtime_get_sync(to_gbphy_dev(dev));
}

static void gbphy_spi_unprepare_transfer_hardware(struct device *dev)
{
gbphy_runtime_put_autosuspend(to_gbphy_dev(dev));
}

static struct spilib_ops __spilib_ops = {
.prepare_transfer_hardware = gbphy_spi_prepare_transfer_hardware,
.unprepare_transfer_hardware = gbphy_spi_unprepare_transfer_hardware,
};

static struct spilib_ops *spilib_ops = &__spilib_ops;
#else
static struct spilib_ops *spilib_ops = NULL;
#endif

static int gb_spi_probe(struct gbphy_device *gbphy_dev,
const struct gbphy_device_id *id)
{
Expand All @@ -29,7 +50,7 @@ static int gb_spi_probe(struct gbphy_device *gbphy_dev,
if (ret)
goto exit_connection_destroy;

ret = gb_spilib_master_init(connection, &gbphy_dev->dev);
ret = gb_spilib_master_init(connection, &gbphy_dev->dev, spilib_ops);
if (ret)
goto exit_connection_disable;

Expand Down
28 changes: 16 additions & 12 deletions drivers/staging/greybus/spilib.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@

#include "greybus.h"
#include "spilib.h"
#include "gbphy.h"

struct gb_spilib {
struct gb_connection *connection;
struct device *parent;
struct spi_transfer *first_xfer;
struct spi_transfer *last_xfer;
struct spilib_ops *ops;
u32 rx_xfer_offset;
u32 tx_xfer_offset;
u32 last_xfer_size;
Expand Down Expand Up @@ -373,25 +373,21 @@ static int gb_spi_transfer_one_message(struct spi_master *master,
return ret;
}

#ifndef SPI_CORE_SUPPORT_PM
static int gb_spi_prepare_transfer_hardware(struct spi_master *master)
{
struct gb_spilib *spi = spi_master_get_devdata(master);
struct gbphy_device *gbphy_dev = to_gbphy_dev(spi->parent);

return gbphy_runtime_get_sync(gbphy_dev);
return spi->ops->prepare_transfer_hardware(spi->parent);
}

static int gb_spi_unprepare_transfer_hardware(struct spi_master *master)
{
struct gb_spilib *spi = spi_master_get_devdata(master);
struct gbphy_device *gbphy_dev = to_gbphy_dev(spi->parent);

gbphy_runtime_put_autosuspend(gbphy_dev);
spi->ops->unprepare_transfer_hardware(spi->parent);

return 0;
}
#endif

static int gb_spi_setup(struct spi_device *spi)
{
Expand Down Expand Up @@ -483,7 +479,8 @@ static int gb_spi_setup_device(struct gb_spilib *spi, u8 cs)
return 0;
}

int gb_spilib_master_init(struct gb_connection *connection, struct device *dev)
int gb_spilib_master_init(struct gb_connection *connection, struct device *dev,
struct spilib_ops *ops)
{
struct gb_spilib *spi;
struct spi_master *master;
Expand All @@ -501,6 +498,7 @@ int gb_spilib_master_init(struct gb_connection *connection, struct device *dev)
spi->connection = connection;
gb_connection_set_data(connection, master);
spi->parent = dev;
spi->ops = ops;

/* get master configuration */
ret = gb_spi_get_master_config(spi);
Expand All @@ -518,11 +516,17 @@ int gb_spilib_master_init(struct gb_connection *connection, struct device *dev)
master->setup = gb_spi_setup;
master->transfer_one_message = gb_spi_transfer_one_message;

#ifndef SPI_CORE_SUPPORT_PM
master->prepare_transfer_hardware = gb_spi_prepare_transfer_hardware;
master->unprepare_transfer_hardware =
if (ops && ops->prepare_transfer_hardware) {
master->prepare_transfer_hardware =
gb_spi_prepare_transfer_hardware;
}

if (ops && ops->unprepare_transfer_hardware) {
master->unprepare_transfer_hardware =
gb_spi_unprepare_transfer_hardware;
#else
}

#ifdef SPI_CORE_SUPPORT_PM
master->auto_runtime_pm = true;
#endif

Expand Down
8 changes: 7 additions & 1 deletion drivers/staging/greybus/spilib.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,15 @@
#ifndef __SPILIB_H
#define __SPILIB_H

struct device;
struct gb_connection;

int gb_spilib_master_init(struct gb_connection *connection, struct device *dev);
struct spilib_ops {
int (*prepare_transfer_hardware)(struct device *dev);
void (*unprepare_transfer_hardware)(struct device *dev);
};

int gb_spilib_master_init(struct gb_connection *connection, struct device *dev, struct spilib_ops *ops);
void gb_spilib_master_exit(struct gb_connection *connection);

#endif /* __SPILIB_H */

0 comments on commit 92bcadd

Please sign in to comment.