#endif
 
 #ifdef CONFIG_ACPI
-static void acpi_spi_parse_apple_properties(struct spi_device *spi)
+struct acpi_spi_lookup {
+       struct spi_controller   *ctlr;
+       u32                     max_speed_hz;
+       u32                     mode;
+       int                     irq;
+       u8                      bits_per_word;
+       u8                      chip_select;
+};
+
+static void acpi_spi_parse_apple_properties(struct acpi_device *dev,
+                                           struct acpi_spi_lookup *lookup)
 {
-       struct acpi_device *dev = ACPI_COMPANION(&spi->dev);
        const union acpi_object *obj;
 
        if (!x86_apple_machine)
 
        if (!acpi_dev_get_property(dev, "spiSclkPeriod", ACPI_TYPE_BUFFER, &obj)
            && obj->buffer.length >= 4)
-               spi->max_speed_hz  = NSEC_PER_SEC / *(u32 *)obj->buffer.pointer;
+               lookup->max_speed_hz  = NSEC_PER_SEC / *(u32 *)obj->buffer.pointer;
 
        if (!acpi_dev_get_property(dev, "spiWordSize", ACPI_TYPE_BUFFER, &obj)
            && obj->buffer.length == 8)
-               spi->bits_per_word = *(u64 *)obj->buffer.pointer;
+               lookup->bits_per_word = *(u64 *)obj->buffer.pointer;
 
        if (!acpi_dev_get_property(dev, "spiBitOrder", ACPI_TYPE_BUFFER, &obj)
            && obj->buffer.length == 8 && !*(u64 *)obj->buffer.pointer)
-               spi->mode |= SPI_LSB_FIRST;
+               lookup->mode |= SPI_LSB_FIRST;
 
        if (!acpi_dev_get_property(dev, "spiSPO", ACPI_TYPE_BUFFER, &obj)
            && obj->buffer.length == 8 &&  *(u64 *)obj->buffer.pointer)
-               spi->mode |= SPI_CPOL;
+               lookup->mode |= SPI_CPOL;
 
        if (!acpi_dev_get_property(dev, "spiSPH", ACPI_TYPE_BUFFER, &obj)
            && obj->buffer.length == 8 &&  *(u64 *)obj->buffer.pointer)
-               spi->mode |= SPI_CPHA;
+               lookup->mode |= SPI_CPHA;
 }
 
 static int acpi_spi_add_resource(struct acpi_resource *ares, void *data)
 {
-       struct spi_device *spi = data;
-       struct spi_controller *ctlr = spi->controller;
+       struct acpi_spi_lookup *lookup = data;
+       struct spi_controller *ctlr = lookup->ctlr;
 
        if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
                struct acpi_resource_spi_serialbus *sb;
+               acpi_handle parent_handle;
+               acpi_status status;
 
                sb = &ares->data.spi_serial_bus;
                if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) {
+
+                       status = acpi_get_handle(NULL,
+                                                sb->resource_source.string_ptr,
+                                                &parent_handle);
+
+                       if (!status ||
+                           ACPI_HANDLE(ctlr->dev.parent) != parent_handle)
+                               return -ENODEV;
+
                        /*
                         * ACPI DeviceSelection numbering is handled by the
                         * host controller driver in Windows and can vary
                                                sb->device_selection);
                                if (cs < 0)
                                        return cs;
-                               spi->chip_select = cs;
+                               lookup->chip_select = cs;
                        } else {
-                               spi->chip_select = sb->device_selection;
+                               lookup->chip_select = sb->device_selection;
                        }
 
-                       spi->max_speed_hz = sb->connection_speed;
+                       lookup->max_speed_hz = sb->connection_speed;
 
                        if (sb->clock_phase == ACPI_SPI_SECOND_PHASE)
-                               spi->mode |= SPI_CPHA;
+                               lookup->mode |= SPI_CPHA;
                        if (sb->clock_polarity == ACPI_SPI_START_HIGH)
-                               spi->mode |= SPI_CPOL;
+                               lookup->mode |= SPI_CPOL;
                        if (sb->device_polarity == ACPI_SPI_ACTIVE_HIGH)
-                               spi->mode |= SPI_CS_HIGH;
+                               lookup->mode |= SPI_CS_HIGH;
                }
-       } else if (spi->irq < 0) {
+       } else if (lookup->irq < 0) {
                struct resource r;
 
                if (acpi_dev_resource_interrupt(ares, 0, &r))
-                       spi->irq = r.start;
+                       lookup->irq = r.start;
        }
 
        /* Always tell the ACPI core to skip this resource */
 static acpi_status acpi_register_spi_device(struct spi_controller *ctlr,
                                            struct acpi_device *adev)
 {
+       acpi_handle parent_handle = NULL;
        struct list_head resource_list;
+       struct acpi_spi_lookup lookup;
        struct spi_device *spi;
        int ret;
 
            acpi_device_enumerated(adev))
                return AE_OK;
 
-       spi = spi_alloc_device(ctlr);
-       if (!spi) {
-               dev_err(&ctlr->dev, "failed to allocate SPI device for %s\n",
-                       dev_name(&adev->dev));
-               return AE_NO_MEMORY;
-       }
-
-       ACPI_COMPANION_SET(&spi->dev, adev);
-       spi->irq = -1;
+       lookup.ctlr             = ctlr;
+       lookup.mode             = 0;
+       lookup.bits_per_word    = 0;
+       lookup.irq              = -1;
 
        INIT_LIST_HEAD(&resource_list);
        ret = acpi_dev_get_resources(adev, &resource_list,
-                                    acpi_spi_add_resource, spi);
+                                    acpi_spi_add_resource, &lookup);
        acpi_dev_free_resource_list(&resource_list);
 
-       acpi_spi_parse_apple_properties(spi);
+       if (ret < 0)
+               /* found SPI in _CRS but it points to another controller */
+               return AE_OK;
 
-       if (ret < 0 || !spi->max_speed_hz) {
-               spi_dev_put(spi);
+       if (!lookup.max_speed_hz &&
+           !ACPI_FAILURE(acpi_get_parent(adev->handle, &parent_handle)) &&
+           ACPI_HANDLE(ctlr->dev.parent) == parent_handle) {
+               /* Apple does not use _CRS but nested devices for SPI slaves */
+               acpi_spi_parse_apple_properties(adev, &lookup);
+       }
+
+       if (!lookup.max_speed_hz)
                return AE_OK;
+
+       spi = spi_alloc_device(ctlr);
+       if (!spi) {
+               dev_err(&ctlr->dev, "failed to allocate SPI device for %s\n",
+                       dev_name(&adev->dev));
+               return AE_NO_MEMORY;
        }
 
+       ACPI_COMPANION_SET(&spi->dev, adev);
+       spi->max_speed_hz       = lookup.max_speed_hz;
+       spi->mode               = lookup.mode;
+       spi->irq                = lookup.irq;
+       spi->bits_per_word      = lookup.bits_per_word;
+       spi->chip_select        = lookup.chip_select;
+
        acpi_set_modalias(adev, acpi_device_hid(adev), spi->modalias,
                          sizeof(spi->modalias));
 
        return acpi_register_spi_device(ctlr, adev);
 }
 
+#define SPI_ACPI_ENUMERATE_MAX_DEPTH           32
+
 static void acpi_register_spi_devices(struct spi_controller *ctlr)
 {
        acpi_status status;
        if (!handle)
                return;
 
-       status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+       status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+                                    SPI_ACPI_ENUMERATE_MAX_DEPTH,
                                     acpi_spi_add_device, NULL, ctlr, NULL);
        if (ACPI_FAILURE(status))
                dev_warn(&ctlr->dev, "failed to enumerate SPI slaves\n");