diff options
| -rw-r--r-- | drivers/spi/spi.c | 19 | ||||
| -rw-r--r-- | include/linux/spi/spi.h | 5 |
2 files changed, 23 insertions, 1 deletions
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) { } | |||
| 1581 | static int acpi_spi_add_resource(struct acpi_resource *ares, void *data) | 1581 | static int acpi_spi_add_resource(struct acpi_resource *ares, void *data) |
| 1582 | { | 1582 | { |
| 1583 | struct spi_device *spi = data; | 1583 | struct spi_device *spi = data; |
| 1584 | struct spi_master *master = spi->master; | ||
| 1584 | 1585 | ||
| 1585 | if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { | 1586 | if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { |
| 1586 | struct acpi_resource_spi_serialbus *sb; | 1587 | struct acpi_resource_spi_serialbus *sb; |
| 1587 | 1588 | ||
| 1588 | sb = &ares->data.spi_serial_bus; | 1589 | sb = &ares->data.spi_serial_bus; |
| 1589 | if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) { | 1590 | if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) { |
| 1590 | spi->chip_select = sb->device_selection; | 1591 | /* |
| 1592 | * ACPI DeviceSelection numbering is handled by the | ||
| 1593 | * host controller driver in Windows and can vary | ||
| 1594 | * from driver to driver. In Linux we always expect | ||
| 1595 | * 0 .. max - 1 so we need to ask the driver to | ||
| 1596 | * translate between the two schemes. | ||
| 1597 | */ | ||
| 1598 | if (master->fw_translate_cs) { | ||
| 1599 | int cs = master->fw_translate_cs(master, | ||
| 1600 | sb->device_selection); | ||
| 1601 | if (cs < 0) | ||
| 1602 | return cs; | ||
| 1603 | spi->chip_select = cs; | ||
| 1604 | } else { | ||
| 1605 | spi->chip_select = sb->device_selection; | ||
| 1606 | } | ||
| 1607 | |||
| 1591 | spi->max_speed_hz = sb->connection_speed; | 1608 | spi->max_speed_hz = sb->connection_speed; |
| 1592 | 1609 | ||
| 1593 | if (sb->clock_phase == ACPI_SPI_SECOND_PHASE) | 1610 | if (sb->clock_phase == ACPI_SPI_SECOND_PHASE) |
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 53be3a4c60cb..8a25e6c2fb56 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h | |||
| @@ -369,6 +369,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) | |||
| 369 | * @dma_rx: DMA receive channel | 369 | * @dma_rx: DMA receive channel |
| 370 | * @dummy_rx: dummy receive buffer for full-duplex devices | 370 | * @dummy_rx: dummy receive buffer for full-duplex devices |
| 371 | * @dummy_tx: dummy transmit buffer for full-duplex devices | 371 | * @dummy_tx: dummy transmit buffer for full-duplex devices |
| 372 | * @fw_translate_cs: If the boot firmware uses different numbering scheme | ||
| 373 | * what Linux expects, this optional hook can be used to translate | ||
| 374 | * between the two. | ||
| 372 | * | 375 | * |
| 373 | * Each SPI master controller can communicate with one or more @spi_device | 376 | * Each SPI master controller can communicate with one or more @spi_device |
| 374 | * children. These make a small bus, sharing MOSI, MISO and SCK signals | 377 | * children. These make a small bus, sharing MOSI, MISO and SCK signals |
| @@ -537,6 +540,8 @@ struct spi_master { | |||
| 537 | /* dummy data for full duplex devices */ | 540 | /* dummy data for full duplex devices */ |
| 538 | void *dummy_rx; | 541 | void *dummy_rx; |
| 539 | void *dummy_tx; | 542 | void *dummy_tx; |
| 543 | |||
| 544 | int (*fw_translate_cs)(struct spi_master *master, unsigned cs); | ||
| 540 | }; | 545 | }; |
| 541 | 546 | ||
| 542 | static inline void *spi_master_get_devdata(struct spi_master *master) | 547 | static inline void *spi_master_get_devdata(struct spi_master *master) |
