[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