From: Piyush Malgujar <pmalgujar@xxxxxxxxxxx> These changes enables to read the configs from ACPI tables as required for successful probing in ACPI uefi environment. In case of ACPI disabled/dts based environment, it will continue to read configs from dts as before Signed-off-by: Piyush Malgujar <pmalgujar@xxxxxxxxxxx> Signed-off-by: Witold Sadowski <wsadowski@xxxxxxxxxxx> --- drivers/spi/spi-cadence-xspi.c | 97 +++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c index 5d36f9177f3c..e4ebfad8a1cb 100644 --- a/drivers/spi/spi-cadence-xspi.c +++ b/drivers/spi/spi-cadence-xspi.c @@ -2,6 +2,7 @@ // Cadence XSPI flash controller driver // Copyright (C) 2020-21 Cadence +#include <linux/acpi.h> #include <linux/completion.h> #include <linux/delay.h> #include <linux/err.h> @@ -14,6 +15,7 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/property.h> #include <linux/spi/spi.h> #include <linux/spi/spi-mem.h> #include <linux/bitfield.h> @@ -700,6 +702,67 @@ static int cdns_xspi_mem_op(struct cdns_xspi_dev *cdns_xspi, (dir != SPI_MEM_NO_DATA)); } +#ifdef CONFIG_ACPI +static bool cdns_xspi_supports_op(struct spi_mem *mem, + const struct spi_mem_op *op) +{ + struct spi_device *spi = mem->spi; + const union acpi_object *obj; + struct acpi_device *adev; + + adev = ACPI_COMPANION(&spi->dev); + + if (!acpi_dev_get_property(adev, "spi-tx-bus-width", ACPI_TYPE_INTEGER, + &obj)) { + switch (obj->integer.value) { + case 1: + break; + case 2: + spi->mode |= SPI_TX_DUAL; + break; + case 4: + spi->mode |= SPI_TX_QUAD; + break; + case 8: + spi->mode |= SPI_TX_OCTAL; + break; + default: + dev_warn(&spi->dev, + "spi-tx-bus-width %lld not supported\n", + obj->integer.value); + break; + } + } + + if (!acpi_dev_get_property(adev, "spi-rx-bus-width", ACPI_TYPE_INTEGER, + &obj)) { + switch (obj->integer.value) { + case 1: + break; + case 2: + spi->mode |= SPI_RX_DUAL; + break; + case 4: + spi->mode |= SPI_RX_QUAD; + break; + case 8: + spi->mode |= SPI_RX_OCTAL; + break; + default: + dev_warn(&spi->dev, + "spi-rx-bus-width %lld not supported\n", + obj->integer.value); + break; + } + } + + if (!spi_mem_default_supports_op(mem, op)) + return false; + + return true; +} +#endif + static int cdns_xspi_mem_op_execute(struct spi_mem *mem, const struct spi_mem_op *op) { @@ -723,6 +786,9 @@ static int cdns_xspi_adjust_mem_op_size(struct spi_mem *mem, struct spi_mem_op * } static const struct spi_controller_mem_ops cadence_xspi_mem_ops = { +#ifdef CONFIG_ACPI + .supports_op = cdns_xspi_supports_op, +#endif .exec_op = cdns_xspi_mem_op_execute, .adjust_op_size = cdns_xspi_adjust_mem_op_size, }; @@ -774,21 +840,20 @@ static irqreturn_t cdns_xspi_irq_handler(int this_irq, void *dev) static int cdns_xspi_of_get_plat_data(struct platform_device *pdev) { - struct device_node *node_prop = pdev->dev.of_node; - struct device_node *node_child; + struct fwnode_handle *fwnode_child; unsigned int cs; - for_each_child_of_node(node_prop, node_child) { - if (!of_device_is_available(node_child)) + device_for_each_child_node(&pdev->dev, fwnode_child) { + if (!fwnode_device_is_available(fwnode_child)) continue; - if (of_property_read_u32(node_child, "reg", &cs)) { + if (fwnode_property_read_u32(fwnode_child, "reg", &cs)) { dev_err(&pdev->dev, "Couldn't get memory chip select\n"); - of_node_put(node_child); + fwnode_handle_put(fwnode_child); return -ENXIO; } else if (cs >= CDNS_XSPI_MAX_BANKS) { dev_err(&pdev->dev, "reg (cs) parameter value too large\n"); - of_node_put(node_child); + fwnode_handle_put(fwnode_child); return -ENXIO; } } @@ -924,6 +989,21 @@ static int cdns_xspi_probe(struct platform_device *pdev) return 0; } +#ifdef CONFIG_ACPI +static const struct acpi_device_id cdns_xspi_acpi_match[] = { + { + .id = "cdns,xspi-nor", + .driver_data = (kernel_ulong_t) &cdns_driver_data, + }, + { + .id = "mrvl,xspi-nor", + .driver_data = (kernel_ulong_t) &mrvl_driver_data, + }, + {}, +}; +MODULE_DEVICE_TABLE(acpi, cdns_xspi_acpi_match); +#endif + static const struct of_device_id cdns_xspi_of_match[] = { { .compatible = "cdns,xspi-nor", @@ -942,6 +1022,9 @@ static struct platform_driver cdns_xspi_platform_driver = { .driver = { .name = CDNS_XSPI_NAME, .of_match_table = cdns_xspi_of_match, +#ifdef CONFIG_ACPI + .acpi_match_table = cdns_xspi_acpi_match, +#endif }, }; -- 2.43.0