From patchwork Fri Feb 10 16:47:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Herring X-Patchwork-Id: 93798 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp590762qgi; Fri, 10 Feb 2017 08:48:55 -0800 (PST) X-Received: by 10.98.111.194 with SMTP id k185mr11262415pfc.83.1486745334945; Fri, 10 Feb 2017 08:48:54 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l187si2137519pfl.162.2017.02.10.08.48.54; Fri, 10 Feb 2017 08:48:54 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752024AbdBJQsj (ORCPT + 7 others); Fri, 10 Feb 2017 11:48:39 -0500 Received: from mail-oi0-f67.google.com ([209.85.218.67]:36541 "EHLO mail-oi0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752502AbdBJQsE (ORCPT ); Fri, 10 Feb 2017 11:48:04 -0500 Received: by mail-oi0-f67.google.com with SMTP id u143so2905122oif.3; Fri, 10 Feb 2017 08:47:23 -0800 (PST) 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:in-reply-to :references; bh=HI+UB9kv0c39XyWTeE1QpPs++0v2QJDrZ0DQ/XVNPso=; b=VVG/eUwNtHbcL1zODzhUsA9js/uqpVMp2pto3+UlfahgQlBm1JJHMiEzRH918a5aq5 5+uolskoNOKaNNaHS0N6rF0gbhoF7l39kZidAKFebxbKs94cNdM/ZqMm8QHwyvJ8BCgZ uhzm1a2eb5A1apsCjQlk+Xuon1wtpbI9PnslrFsauWFO2ygvnHv4BJyMihSiyFFcaBSl /X0Rbjt7DHj18uYxWsb+IRiKg9ggIJjtiLHdVbGF73GUzPj1QDtRRkrPJQWM9cYELdMp zZdr5En3/fKxIzC5BtO15UZnEzqEl6oaRZAZzypvb3PFh+xK5DSQ47QLkwThT9YWkb65 M/tA== X-Gm-Message-State: AMke39k34kpzWUJkiSUkNvzgiOpT6xoYq3xP3pzDFm+S13hAyOyzR2GcCJYhswk1pzwfTg== X-Received: by 10.202.179.9 with SMTP id c9mr4529718oif.152.1486745243248; Fri, 10 Feb 2017 08:47:23 -0800 (PST) Received: from rob-hp-laptop.herring.priv (66-90-148-125.dyn.grandenetworks.net. [66.90.148.125]) by smtp.googlemail.com with ESMTPSA id r41sm1141714otc.40.2017.02.10.08.47.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 10 Feb 2017 08:47:22 -0800 (PST) From: Rob Herring To: David Gibson Cc: devicetree@vger.kernel.org, devicetree-compiler@vger.kernel.org Subject: [PATCH v2 4/4] checks: Add bus checks for PCI buses Date: Fri, 10 Feb 2017 10:47:17 -0600 Message-Id: <20170210164717.1234-5-robh@kernel.org> X-Mailer: git-send-email 2.10.1 In-Reply-To: <20170210164717.1234-1-robh@kernel.org> References: <20170210164717.1234-1-robh@kernel.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add PCI bridge and device node checks. We identify PCI bridges with 'device_type = "pci"' as only PCI bridges should set that property. For bridges, check that ranges is present and #address-cells and For devices, the primary check is the reg property and the unit address. Device unit addresses are in the form DD or DD,F where DD is the device 0-0x1f and F is the function 0-7. Signed-off-by: Rob Herring --- v2: - Remove bus_type functions. Combine test for bus_type and bridge check into single check. - Add a check that PCI bridge node name is pci or pcie. checks.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ dtc.h | 7 ++++++ 2 files changed, 90 insertions(+) -- 2.10.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/checks.c b/checks.c index 16d17d20caec..9ebb148f947a 100644 --- a/checks.c +++ b/checks.c @@ -702,6 +702,86 @@ static void check_ranges_format(struct check *c, struct dt_info *dti, } WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells); +static const struct bus_type pci_bus = { + .type = PCI_BUS_TYPE, +}; + +static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *node) +{ + struct property *prop; + + prop = get_property(node, "device_type"); + if (!prop || strcmp(prop->val.val, "pci")) + return; + + node->bus = &pci_bus; + + if (strncmp(node->name, "pci", node->basenamelen) && + strncmp(node->name, "pcie", node->basenamelen)) + FAIL(c, "Node %s node name is not \"pci\" or \"pcie\"", + node->fullpath); + + prop = get_property(node, "ranges"); + if (!prop) + FAIL(c, "Node %s missing ranges for PCI bridge (or not a bridge)", + node->fullpath); + + if (node_addr_cells(node) != 3) + FAIL(c, "Node %s incorrect #address-cells for PCI bridge", + node->fullpath); + if (node_size_cells(node) != 2) + FAIL(c, "Node %s incorrect #size-cells for PCI bridge", + node->fullpath); +} +WARNING(pci_bridge, check_pci_bridge, NULL, + &device_type_is_string, &addr_size_cells); + +static void check_pci_device(struct check *c, struct dt_info *dti, struct node *node) +{ + struct property *prop; + const char *unitname = get_unitname(node); + char unit_addr[5]; + unsigned int dev, func, reg; + + if (!node->parent || !node->parent->bus || + (node->parent->bus->type != PCI_BUS_TYPE)) + return; + + prop = get_property(node, "reg"); + if (!prop) + return; + + reg = fdt32_to_cpu(*((cell_t *)prop->val.val)); + + dev = (reg & 0xf800) >> 11; + func = (reg & 0x700) >> 8; + + if (reg & 0xff000000) + FAIL(c, "Node %s PCI reg address is not configuration space", + node->fullpath); + + if (dev > 0x1f) + FAIL(c, "Node %s PCI device number out of range", + node->fullpath); + if (func > 7) + FAIL(c, "Node %s PCI function number out of range", + node->fullpath); + + if (func == 0) { + snprintf(unit_addr, sizeof(unit_addr), "%x", dev); + if (!strcmp(unitname, unit_addr)) + return; + } + + snprintf(unit_addr, sizeof(unit_addr), "%x,%x", dev, func); + if (!strcmp(unitname, unit_addr)) + return; + + FAIL(c, "Node %s PCI unit address format error, expected \"%s\"", + node->fullpath, unit_addr); +} +WARNING(pci_device, check_pci_device, NULL, ®_format); + /* * Style checks */ @@ -775,6 +855,9 @@ static struct check *check_table[] = { &unit_address_vs_reg, &unit_address_format, + &pci_bridge, + &pci_device, + &avoid_default_addr_size, &obsolete_chosen_interrupt_controller, diff --git a/dtc.h b/dtc.h index c6f125c68ba8..c538ef4afafb 100644 --- a/dtc.h +++ b/dtc.h @@ -136,6 +136,12 @@ struct label { struct label *next; }; +#define PCI_BUS_TYPE 1 + +struct bus_type { + int type; +}; + struct property { bool deleted; char *name; @@ -162,6 +168,7 @@ struct node { int addr_cells, size_cells; struct label *labels; + const struct bus_type *bus; }; #define for_each_label_withdel(l0, l) \