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

Cédric Le Goater clg at kaod.org
Fri Jul 1 03:23:38 AEST 2022


On 6/29/22 07:46, Naresh Solanki wrote:
> Verified for its working.

Thanks for the test ! When we upstream, a Tested-by tag would
be nice to have.

C.

> Thanks
> 
> 
> On Tue, 28 Jun 2022 at 21:51, Cédric Le Goater <clg at kaod.org <mailto: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 <mailto:naresh.solanki at 9elements.com>>
>     Cc: Chin-Ting Kuo <chin-ting_kuo at aspeedtech.com <mailto:chin-ting_kuo at aspeedtech.com>>
>     Signed-off-by: Cédric Le Goater <clg at kaod.org <mailto: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
> 



More information about the openbmc mailing list