From patchwork Tue May 28 16:40:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 165312 Delivered-To: patch@linaro.org Received: by 2002:a92:9e1a:0:0:0:0:0 with SMTP id q26csp8718676ili; Tue, 28 May 2019 09:40:48 -0700 (PDT) X-Google-Smtp-Source: APXvYqw6ZjMBmruXmsz0UHNwYa1q+R7nGGPEnivVnJfhpDHRgg/4iLR2Lx2Nmr+tnpAr4CoeTMWO X-Received: by 2002:a17:902:934b:: with SMTP id g11mr31613890plp.289.1559061648197; Tue, 28 May 2019 09:40:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559061648; cv=none; d=google.com; s=arc-20160816; b=E8jCa6JoCAcV6CQ/hJWnO+fzF1oIV/oHZp5FMPm+G7T0tpa7We3kx8/1fizQjx0wtB MGlNAwTP/UAyVg2FU1B9IaW67tI0Z1ogVxIRGZcr/fbyFo01yKshVrVGRwF28elH09PD RW+f9zIP9k+iOVub7mfyUNleAnXZ9JU2Xf4yuYcQPBBQto5RXzHmnyeaQVRmvZHrECPY s1Pgquscuv+gQ0y4uUUUxooTgU63wkwYtkneCdru/J1tPMmd2u2iIQ8wHpRZq87d98HQ EdB2Z8MFQ/W3LyfT9mrNQIEy3GOOEI8vC0NnjqH7RATLQEqq3aWc1+c8Lxdiw9AEoIhi pecg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=ej81fOB8PClma2q551Mc3W9H8PCahAPhKY1SnLKkbyI=; b=lYzWLMOzFTDLX17Q6VJo1T2PB6kFfLpL6PARjck0D5BEuS3GV5BDmJhXZLdk/+OV3v 8V1uspBJb2t0K1RBagIfKKtZN5QaZnSm1FNlv6pFCgZzrC++6mLnGCeOBOVvAwrDY4tv hDweBTdoEbjiSENIMq1CW7NuFb8/ZehxI/dwLjfy1CUJKFTlbie3sS3VoasHHOGeFAF0 JBPA9bu9mwa58ZOyS83GZjejyX9qTAkDYIBL424T+rxSDVOphmMDetOeU7RV98fu4lbs HpIPBimuFc5qZ9/RNLRdLC8eQSf8Vv6/kjj0beFicY4ANDAM8SumBCdcDlcxhNZE2Gvg K1RQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=OulgYt0n; spf=pass (google.com: best guess record for domain of linux-spi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-spi-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t25si22800091pgk.442.2019.05.28.09.40.47; Tue, 28 May 2019 09:40:48 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-spi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=OulgYt0n; spf=pass (google.com: best guess record for domain of linux-spi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-spi-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726371AbfE1Qkr (ORCPT + 1 other); Tue, 28 May 2019 12:40:47 -0400 Received: from mail-wm1-f65.google.com ([209.85.128.65]:52831 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726362AbfE1Qkr (ORCPT ); Tue, 28 May 2019 12:40:47 -0400 Received: by mail-wm1-f65.google.com with SMTP id y3so3705070wmm.2 for ; Tue, 28 May 2019 09:40:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=ej81fOB8PClma2q551Mc3W9H8PCahAPhKY1SnLKkbyI=; b=OulgYt0n8ruauMW/L6BJZJFgRbD8bKzL5B4LXPshMIERSdxYW3kgAKV/lvlHlC8UY7 2YQyuxCX+sraQBkubdedG46TkyGY1QzkU8S0/gcktNhPcajaHioM3YddSlHo/I7zoNIw DBl/UoNeJ9cSsKNQRWc7dyyDJZxUIuq2/pk3WfQzR6ZueIHtZ3Oio2/xTqyHwZrwY89A zmfurxN2HREHG8E0mm/7P5qXvBUFjpp3aVq/2MUnj15kDTSTFhkIf7dGuViUwKbqOAiG lxINfNuQ0gYYLeeBQsMH72hqhJr7B4bJd5MFUCOU/dn5m3Y3F03knpUCKLCXB2qF4S7z dm7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=ej81fOB8PClma2q551Mc3W9H8PCahAPhKY1SnLKkbyI=; b=dKl+Oe3ejmQFiwgSKPgcn0Ymj+2pqvCcvgNhQACOEBt7EHsdt8sMZvTMTEoe2aioIB zMq5704ifbg8mbWXZWHT07jMTTT7LNt57TpZUV37TLUvatUWVdHqKPO8ySXrGmM5x3Ey e4tKBYNvn+KtXCpmKqg+iFatIu/uiZjp62j4g69NUWwSwUodALDpaCuvYnlnDFCO8njS bEFjfL8TMKxX1CT8fk2u9qW6DxFtvwEnVnMWyczHFSZv9nZEnQ5WqAPrpOsSJwvmXgla 5yPSBkZouYTR8TOcmlfu/8L4EeKZSIe42frF37zTQpi3LXfvZ2GUWteHZiwdIPVzS+PQ 0bkQ== X-Gm-Message-State: APjAAAUgSN4PiS7sBuVlK2s21j6ylupkBGhDjhq7KELUuvhvbyUNMZqy 05glTBYBAdqB2ZcLbJccLrreJH0LY3bbUg== X-Received: by 2002:a1c:e183:: with SMTP id y125mr3860136wmg.152.1559061643779; Tue, 28 May 2019 09:40:43 -0700 (PDT) Received: from sudo.home ([2a01:cb1d:112:6f00:c8c7:f81b:b165:1aa7]) by smtp.gmail.com with ESMTPSA id q11sm3503196wmc.15.2019.05.28.09.40.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 May 2019 09:40:42 -0700 (PDT) From: Ard Biesheuvel To: linux-spi@vger.kernel.org Cc: broonie@kernel.org, mika.westerberg@linux.intel.com, andy.shevchenko@gmail.com, masahisa.kojima@linaro.org, Ard Biesheuvel Subject: [RFC PATCH] spi/acpi: enumerate all SPI slaves in the namespace Date: Tue, 28 May 2019 18:40:40 +0200 Message-Id: <20190528164040.6781-1-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Currently, the ACPI enumeration that takes place when registering a SPI master only considers immediate child devices in the ACPI namespace, rather than checking the ResourceSource field in the SpiSerialBus() resource descriptor. This is incorrect: SPI slaves could reside anywhere in the ACPI namespace, and so we should enumerate the entire namespace and look for any device that refers to the newly registered SPI master in its resource descriptor. In order to prevent potential regressions, retain the old code and run it first. Only then, enumerate the entire namespace. Note that this could result in child devices wrongly being associated with a SPI master but this can only occur if a SPI master has a child device representing a SPI slave that is connected to another master. Signed-off-by: Ard Biesheuvel --- drivers/spi/spi.c | 75 ++++++++++++++++++-- 1 file changed, 69 insertions(+), 6 deletions(-) -- 2.20.1 diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 5e75944ad5d1..d2f4332d9cc3 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1882,10 +1882,6 @@ static acpi_status acpi_register_spi_device(struct spi_controller *ctlr, struct spi_device *spi; int ret; - if (acpi_bus_get_status(adev) || !adev->status.present || - 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", @@ -1927,18 +1923,64 @@ static acpi_status acpi_register_spi_device(struct spi_controller *ctlr, return AE_OK; } +static acpi_status acpi_spi_add_child_device(acpi_handle handle, u32 level, + void *data, void **return_value) +{ + struct spi_controller *ctlr = data; + struct acpi_device *adev; + + if (acpi_bus_get_device(handle, &adev) || + acpi_bus_get_status(adev) || + !adev->status.present || + acpi_device_enumerated(adev)) + return AE_OK; + + return acpi_register_spi_device(ctlr, adev); +} + +static int acpi_spi_check_parent(struct acpi_resource *ares, void *data) +{ + struct acpi_resource_spi_serialbus *sb; + + if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) + return 1; + + sb = &ares->data.spi_serial_bus; + + /* check whether this resource refers our controller */ + acpi_get_handle(NULL, sb->resource_source.string_ptr, data); + return 1; +} + static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level, void *data, void **return_value) { struct spi_controller *ctlr = data; + acpi_handle parent_handle = NULL; + struct list_head resource_list; struct acpi_device *adev; + int ret; - if (acpi_bus_get_device(handle, &adev)) + if (acpi_bus_get_device(handle, &adev) || + acpi_bus_get_status(adev) || + !adev->status.present || + acpi_device_enumerated(adev)) + return AE_OK; + + INIT_LIST_HEAD(&resource_list); + ret = acpi_dev_get_resources(adev, &resource_list, + acpi_spi_check_parent, + &parent_handle); + acpi_dev_free_resource_list(&resource_list); + + if (ret < 0 || ACPI_HANDLE(ctlr->dev.parent) != parent_handle) return AE_OK; 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; @@ -1948,10 +1990,31 @@ static void acpi_register_spi_devices(struct spi_controller *ctlr) if (!handle) return; + /* + * Enumerate child nodes of this controller. This logic is retained to + * prevent potential regressions on systems where the ResourceSource of + * a device's SpiSerialBus() resource does not refer to the parent SPI + * controller device. + */ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, + acpi_spi_add_child_device, NULL, ctlr, + NULL); + if (ACPI_FAILURE(status)) { + dev_warn(&ctlr->dev, "failed to enumerate SPI children\n"); + return; + } + + /* + * Walk the entire namespace and enumerate all devices containing a + * SpiSerialBus() resource whose ResourceSource argument refers to this + * SPI controller device. + */ + 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"); + dev_warn(&ctlr->dev, + "failed to enumerate SPI slaves in the ACPI namespace\n"); } #else static inline void acpi_register_spi_devices(struct spi_controller *ctlr) {}