[PATCH linux 4/5] spi: aspeed: Handle custom decoding ranges

Naresh Solanki naresh.solanki at 9elements.com
Wed Jun 29 15:46:39 AEST 2022


Verified for its working.
Thanks


On Tue, 28 Jun 2022 at 21:51, Cédric Le Goater <clg at kaod.org> wrote:

> "ranges" predefines settings of the decoding ranges for each CS. If
> found in the DT, the driver applies the settings at probe time. The
> default behavior is to set the decoding range of each CS using the
> flash device size when the spi slave is setup.
>
> Cc: Naresh Solanki <naresh.solanki at 9elements.com>
> Cc: Chin-Ting Kuo <chin-ting_kuo at aspeedtech.com>
> Signed-off-by: Cédric Le Goater <clg at kaod.org>
> ---
>  drivers/spi/spi-aspeed-smc.c | 63 +++++++++++++++++++++++++++++++++++-
>  1 file changed, 62 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
> index 1611c354c31f..791cbf753a85 100644
> --- a/drivers/spi/spi-aspeed-smc.c
> +++ b/drivers/spi/spi-aspeed-smc.c
> @@ -101,6 +101,7 @@ struct aspeed_spi {
>         u32                      clk_freq;
>
>         struct aspeed_spi_chip   chips[ASPEED_SPI_MAX_NUM_CS];
> +       bool                     fixed_windows;
>  };
>
>  static u32 aspeed_spi_get_io_mode(const struct spi_mem_op *op)
> @@ -574,7 +575,8 @@ static int aspeed_spi_dirmap_create(struct
> spi_mem_dirmap_desc *desc)
>         if (op->data.dir != SPI_MEM_DATA_IN)
>                 return -EOPNOTSUPP;
>
> -       aspeed_spi_chip_adjust_window(chip, desc->info.offset,
> desc->info.length);
> +       if (!aspi->fixed_windows)
> +               aspeed_spi_chip_adjust_window(chip, desc->info.offset,
> desc->info.length);
>
>         if (desc->info.length > chip->ahb_window_size)
>                 dev_warn(aspi->dev, "CE%d window (%dMB) too small for
> mapping",
> @@ -749,6 +751,61 @@ static const struct attribute_group
> aspeed_spi_attribute_group = {
>         .attrs = aspeed_spi_attributes
>  };
>
> +static int aspeed_spi_chip_read_ranges(struct device_node *node, struct
> aspeed_spi *aspi)
> +{
> +       const char *range_prop = "ranges";
> +       struct property *prop;
> +       struct aspeed_spi_window ranges[ASPEED_SPI_MAX_NUM_CS];
> +       int prop_size;
> +       int count;
> +       int ret;
> +       int i;
> +
> +       prop = of_find_property(node, range_prop, &prop_size);
> +       if (!prop)
> +               return 0;
> +
> +       count = prop_size / sizeof(*ranges);
> +       if (count > aspi->data->max_cs) {
> +               dev_err(aspi->dev, "invalid '%s' property %d\n",
> range_prop, count);
> +               return -EINVAL;
> +       }
> +
> +       if (count < aspi->data->max_cs)
> +               dev_dbg(aspi->dev, "'%s' property does not cover all CE\n",
> +                       range_prop);
> +
> +       ret = of_property_read_u32_array(node, range_prop, (u32 *)ranges,
> count * 4);
> +       if (ret)
> +               return ret;
> +
> +       dev_info(aspi->dev, "Using preset decoding ranges\n");
> +       for (i = 0; i < count; i++) {
> +               struct aspeed_spi_window *win = &ranges[i];
> +
> +               if (win->cs > aspi->data->max_cs) {
> +                       dev_err(aspi->dev, "CE%d range is invalid",
> win->cs);
> +                       return -EINVAL;
> +               }
> +
> +               /* Trim top bit of the address to keep offset */
> +               win->offset &= aspi->ahb_window_size - 1;
> +
> +               /* Minimal check */
> +               if (win->offset + win->size > aspi->ahb_window_size) {
> +                       dev_warn(aspi->dev, "CE%d range is too large",
> win->cs);
> +                               return -EINVAL;
> +               }
> +
> +               ret = aspeed_spi_set_window(aspi, win);
> +               if (ret)
> +                       return ret;
> +       }
> +
> +       aspi->fixed_windows = true;
> +       return 0;
> +}
> +
>  static int aspeed_spi_probe(struct platform_device *pdev)
>  {
>         struct device *dev = &pdev->dev;
> @@ -806,6 +863,10 @@ static int aspeed_spi_probe(struct platform_device
> *pdev)
>                 return ret;
>         }
>
> +       ret = aspeed_spi_chip_read_ranges(dev->of_node, aspi);
> +       if (ret)
> +               return ret;
> +
>         /* IRQ is for DMA, which the driver doesn't support yet */
>
>         ctlr->mode_bits = SPI_RX_DUAL | SPI_TX_DUAL | data->mode_bits;
> --
> 2.35.3
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/openbmc/attachments/20220629/4c8c8e43/attachment-0001.htm>


More information about the openbmc mailing list