[PATCH linux dev-5.7 v2 6/7] spi: fsi: Check mux status before transfers
Joel Stanley
joel at jms.id.au
Thu Aug 13 13:45:11 AEST 2020
On Thu, 30 Jul 2020 at 22:03, Eddie James <eajames at linux.ibm.com> wrote:
>
> The SPI controllers are not accessible if the mux isn't set. Therefore,
> check the mux status before starting a transfer and fail out if it isn't
> set.
>
> Signed-off-by: Eddie James <eajames at linux.ibm.com>
> ---
> drivers/spi/spi-fsi.c | 40 +++++++++++++++++++++++++++-------------
> 1 file changed, 27 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/spi/spi-fsi.c b/drivers/spi/spi-fsi.c
> index 53cfa201e187..8949a64ec87d 100644
> --- a/drivers/spi/spi-fsi.c
> +++ b/drivers/spi/spi-fsi.c
> @@ -12,6 +12,7 @@
>
> #define FSI_ENGID_SPI 0x23
> #define FSI_MBOX_ROOT_CTRL_8 0x2860
> +#define FSI_MBOX_ROOT_CTRL_8_SPI 0xf0000000
Could be called SPI_MUX or something similar.
>
> #define FSI2SPI_DATA0 0x00
> #define FSI2SPI_DATA1 0x04
> @@ -84,6 +85,26 @@ struct fsi_spi_sequence {
> u64 data;
> };
>
> +static int fsi_spi_check_mux(struct fsi_device *fsi, struct device *dev)
> +{
> + int rc;
> + u32 root_ctrl_8;
> + __be32 root_ctrl_8_be;
> +
> + rc = fsi_slave_read(fsi->slave, FSI_MBOX_ROOT_CTRL_8, &root_ctrl_8_be,
> + sizeof(root_ctrl_8_be));
> + if (rc)
> + return rc;
> +
> + root_ctrl_8 = be32_to_cpu(root_ctrl_8_be);
> + dev_dbg(dev, "Root control register 8: %08x\n", root_ctrl_8);
> + if ((root_ctrl_8 & FSI_MBOX_ROOT_CTRL_8_SPI) ==
> + FSI_MBOX_ROOT_CTRL_8_SPI)
> + return 0;
> +
> + return -ENOLINK;
We bubble this error up to device drivers. Are they ok with ENOLINK?
> +}
> +
> static int fsi_spi_check_status(struct fsi_spi *ctx)
> {
> int rc;
> @@ -449,11 +470,15 @@ static int fsi_spi_transfer_init(struct fsi_spi *ctx)
> static int fsi_spi_transfer_one_message(struct spi_controller *ctlr,
> struct spi_message *mesg)
> {
> - int rc = 0;
> + int rc;
> u8 seq_slave = SPI_FSI_SEQUENCE_SEL_SLAVE(mesg->spi->chip_select + 1);
> struct spi_transfer *transfer;
> struct fsi_spi *ctx = spi_controller_get_devdata(ctlr);
>
> + rc = fsi_spi_check_mux(ctx->fsi, ctx->dev);
> + if (rc)
> + return rc;
> +
> list_for_each_entry(transfer, &mesg->transfers, transfer_list) {
> struct fsi_spi_sequence seq;
> struct spi_transfer *next = NULL;
> @@ -537,24 +562,13 @@ static size_t fsi_spi_max_transfer_size(struct spi_device *spi)
> static int fsi_spi_probe(struct device *dev)
> {
> int rc;
> - u32 root_ctrl_8;
> struct device_node *np;
> int num_controllers_registered = 0;
> struct fsi_device *fsi = to_fsi_dev(dev);
>
> - /*
> - * Check the SPI mux before attempting to probe. If the mux isn't set
> - * then the SPI controllers can't access their slave devices.
> - */
> - rc = fsi_slave_read(fsi->slave, FSI_MBOX_ROOT_CTRL_8, &root_ctrl_8,
> - sizeof(root_ctrl_8));
> + rc = fsi_spi_check_mux(fsi, dev);
> if (rc)
> - return rc;
> -
> - if (!root_ctrl_8) {
> - dev_dbg(dev, "SPI mux not set, aborting probe.\n");
Should we make this a dev_warn so it's clear why the driver did not "work"?
> return -ENODEV;
> - }
>
> for_each_available_child_of_node(dev->of_node, np) {
> u32 base;
> --
> 2.24.0
>
More information about the openbmc
mailing list