aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi.c19
-rw-r--r--include/linux/spi/spi.h5
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) { }
1581static int acpi_spi_add_resource(struct acpi_resource *ares, void *data) 1581static 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
542static inline void *spi_master_get_devdata(struct spi_master *master) 547static inline void *spi_master_get_devdata(struct spi_master *master)