From a0a90718f18264dc904d34a580f332006f5561e9 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 8 Feb 2016 17:14:28 +0200 Subject: spi: Let drivers translate ACPI DeviceSelection to suitable Linux chip select In Windows it is up to the SPI host controller driver to handle the ACPI DeviceSelection as it likes. The SPI core does not take any part in it. This is different in Linux because we always expect to have chip select in range of 0 .. master->num_chipselect - 1. In order to support this in Linux we need a way to allow the driver to translate between ACPI DeviceSelection field and Linux chip select number so provide a new optional hook ->fw_translate_cs() that can be used by a driver to handle translation and call this hook if set during SPI slave ACPI enumeration. Signed-off-by: Mika Westerberg Reviewed-by: Jarkko Nikula Signed-off-by: Mark Brown --- drivers/spi/spi.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 47eff8012a77..2c0c26a57f03 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1581,13 +1581,30 @@ static void of_register_spi_devices(struct spi_master *master) { } static int acpi_spi_add_resource(struct acpi_resource *ares, void *data) { struct spi_device *spi = data; + struct spi_master *master = spi->master; if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { struct acpi_resource_spi_serialbus *sb; sb = &ares->data.spi_serial_bus; if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) { - spi->chip_select = sb->device_selection; + /* + * ACPI DeviceSelection numbering is handled by the + * host controller driver in Windows and can vary + * from driver to driver. In Linux we always expect + * 0 .. max - 1 so we need to ask the driver to + * translate between the two schemes. + */ + if (master->fw_translate_cs) { + int cs = master->fw_translate_cs(master, + sb->device_selection); + if (cs < 0) + return cs; + spi->chip_select = cs; + } else { + spi->chip_select = sb->device_selection; + } + spi->max_speed_hz = sb->connection_speed; if (sb->clock_phase == ACPI_SPI_SECOND_PHASE) -- cgit v1.2.3-55-g7522