From patchwork Sun Dec 27 13:12:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hongtao Wu X-Patchwork-Id: 1420735 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=hu5tebPb; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4D3h2K0hwZz9sWM for ; Mon, 28 Dec 2020 00:13:29 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726182AbgL0NNP (ORCPT ); Sun, 27 Dec 2020 08:13:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55518 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726075AbgL0NNN (ORCPT ); Sun, 27 Dec 2020 08:13:13 -0500 Received: from mail-pg1-x52c.google.com (mail-pg1-x52c.google.com [IPv6:2607:f8b0:4864:20::52c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C1060C061795; Sun, 27 Dec 2020 05:12:32 -0800 (PST) Received: by mail-pg1-x52c.google.com with SMTP id p18so5755276pgm.11; Sun, 27 Dec 2020 05:12:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=tg20jcKJdNMzDs8lrF5E15qRBXlejHgS8UGhy/VgAws=; b=hu5tebPbN+KZQQdIE3nFYBToxMTqh8Zy9ATAd2QewZGA0KMnEA/C5z/fQWXj3lw52y OxqWOr21AewD+8kFvEK5x0g/K/lhhM7egc5QLjq0/iXuqzpIayZR//1nrgWBAB/jr6dH SXxj7EUuWH0EI8/5O+1ngIVGS1k80Km6hx6hCPo6rQZ1U2064Ru2qsB5UgF/9HH3OFbd TRxQxQ/yTh9MD0Lf8BJbTDPv1Nvk2dpJTxx6J6rX17TViHbMj7zqwAIHRO1cs+p3bKjj 04j3zRalaHXFWo4f66azIQyTeboJBcZ40w+nsAO1MgqU+EEZ9CAXNRp5DtPyJ7I27cuu grdg== 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=tg20jcKJdNMzDs8lrF5E15qRBXlejHgS8UGhy/VgAws=; b=cUw74z4+8TJ+qUkdz52ROnP3/SOW/RCadxS5gycVpK45IIuX8STpjqpPW6vfv43SNZ lu5e1aMb9hCNOMOAL7IxlqG+wvqrGeha94BBt7cSrbMBTo2OqVrkE7vTB5rKUE7tq7uu bjPddVmq/jCv+6m2qDf3sFWaOIj8Fc4EvdG7iRTdKSghpHsd2fzZOEDsJjJ/nj9z57jz Ip6W1iE5Zn7sOdmvCsr1NF419sNZs3OTPhNqXbtW+aUWojsOd4XmHnNq8356qecAigzV PHNxMA7T9DKw3xaBHMNqBDThebsfNws2fptIMkdnAHhGRM9AzgdkIBUdU+7TNaZvp+c3 2+Aw== X-Gm-Message-State: AOAM5315cJDj7m9zWoPzA5cUXDwV0Ugqoltg2C6M+XM1osegtJbhjAWQ MARCRzDUU14ftQXqV5NQcs+qJi2B7D4= X-Google-Smtp-Source: ABdhPJygwf6lozBT3u0G6JO9r0Oo/BC7ibt3zh1kZdHG2BKidZmJk5RP9oNsAOCyDUJDxe50csWNdA== X-Received: by 2002:a63:fa0b:: with SMTP id y11mr7377162pgh.35.1609074752328; Sun, 27 Dec 2020 05:12:32 -0800 (PST) Received: from sh05419pcu.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id j15sm33510269pfn.180.2020.12.27.05.12.28 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 27 Dec 2020 05:12:31 -0800 (PST) From: Hongtao Wu To: Lorenzo Pieralisi , Rob Herring Cc: Orson Zhai , Baolin Wang , Chunyan Zhang , linux-pci@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Hongtao Wu Subject: [PATCH v4 1/2] dt-bindings: PCI: sprd: Document Unisoc PCIe RC host controller Date: Sun, 27 Dec 2020 21:12:13 +0800 Message-Id: <1609074734-9336-2-git-send-email-wuht06@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1609074734-9336-1-git-send-email-wuht06@gmail.com> References: <1609074734-9336-1-git-send-email-wuht06@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Hongtao Wu This series adds PCIe bindings for Unisoc SoCs. This controller is based on DesignWare PCIe IP. Signed-off-by: Hongtao Wu --- .../devicetree/bindings/pci/sprd-pcie.yaml | 91 ++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/sprd-pcie.yaml -- 2.7.4 diff --git a/Documentation/devicetree/bindings/pci/sprd-pcie.yaml b/Documentation/devicetree/bindings/pci/sprd-pcie.yaml new file mode 100644 index 0000000..fe47172 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/sprd-pcie.yaml @@ -0,0 +1,91 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pci/sprd-pcie.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: SoC PCIe Host Controller Device Tree Bindings + +maintainers: + - Hongtao Wu + +allOf: + - $ref: /schemas/pci/pci-bus.yaml# + +properties: + compatible: + items: + - const: sprd,ums9520-pcie + + reg: + minItems: 2 + items: + - description: Controller control and status registers. + - description: PCIe configuration registers. + + reg-names: + items: + - const: dbi + - const: config + + ranges: + maxItems: 2 + + num-lanes: + maximum: 1 + description: Number of lanes to use for this port. + + interrupts: + minItems: 1 + description: Builtin MSI controller and PCIe host controller. + + interrupt-names: + items: + - const: msi + + sprd,regmap-aon: + $ref: '/schemas/types.yaml#/definitions/phandle' + description: + Phandle to the AON system controller node (to access the + AON_ACCESS_PCIE_EN register on ums9520). + sprd,regmap-pmu: + $ref: '/schemas/types.yaml#/definitions/phandle' + description: + Phandle to the PMU system controller node (to access the PERST_N_ASSERT + register on ums9520). + +required: + - compatible + - reg + - reg-names + - num-lanes + - ranges + - interrupts + - interrupt-names + +examples: + - | + #include + + ipa { + #address-cells = <2>; + #size-cells = <2>; + + pcie0: pcie@2b100000 { + compatible = "sprd,ums9520-pcie"; + reg = <0x0 0x2b100000 0x0 0x2000>, + <0x2 0x00000000 0x0 0x2000>; + reg-names = "dbi", "config"; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges = <0x01000000 0x0 0x00000000 0x2 0x00002000 0x0 0x00010000>, + <0x03000000 0x0 0x10000000 0x2 0x10000000 0x1 0xefffffff>; + num-lanes = <1>; + interrupts = ; + interrupt-names = "msi"; + + sprd,regmap-aon = <&aon_regs>; + sprd,regmap-pmu = <&pmu_regs>; + }; + }; From patchwork Sun Dec 27 13:12:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hongtao Wu X-Patchwork-Id: 1420736 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=aYes0di6; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4D3h2L0gLxz9sWM for ; Mon, 28 Dec 2020 00:13:30 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726239AbgL0NNU (ORCPT ); Sun, 27 Dec 2020 08:13:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55540 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726075AbgL0NNT (ORCPT ); Sun, 27 Dec 2020 08:13:19 -0500 Received: from mail-pg1-x532.google.com (mail-pg1-x532.google.com [IPv6:2607:f8b0:4864:20::532]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E09FC061796; Sun, 27 Dec 2020 05:12:39 -0800 (PST) Received: by mail-pg1-x532.google.com with SMTP id v19so5750500pgj.12; Sun, 27 Dec 2020 05:12:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Xw698ctg4Ze5W/87ncdseRGuPD3JOZ7supZFvs8H2cs=; b=aYes0di6R9cfdicrdrnlyqNKjnK3j5UBd8sqnUDAuUhXHQUBDcCRkXtlLLGZ2jLSSU Nxuoig4YBixSEM4sXg0g6vcKuv13/rB+Bt9Qe38YUOneCa9h/8xait/0KiPqMQ179Q0K TtgcEI4qRWQbxZUylLXXD2QBEOwpyyo2N9IH2dRC0kHMj+ylEafrPQ9Uvi62+MXPp1hM 7Cc/IDOWPT2Ca7TtOm2GNcwN2GgJmJdNjNW1cc87y3Pyd4XNPdVLL+hGLAyTonhbgpBX GNdPSwOVdi9hjYCgenOSeoTB5OIlUzCnD485ud8gNP70AXSzi6Nt2OjOrpo8LY0QnY1c I7gQ== 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=Xw698ctg4Ze5W/87ncdseRGuPD3JOZ7supZFvs8H2cs=; b=WgDoDa9FNKIMIHytzf1V7HUYcydlzeqd0rojZID6/nfJgnA7LV5/li6NF47olpkIbJ Xgti9CPF77HmcqWwACr6Ol/mB/UPZxrhx/VMhhR67to7pQJpDvlfCjqKjOp9gRWGvBJ9 26DxPWWiomvNYyd5Z3/UlPsK1fO4/aINsjLsWh2GD2DdV3uuVq94olpf0tOGkXs9pQ6V sifrjm3ax3+CwL1VtQ/IPd8fDKOv1Wo1XcQCIwCPGfhNF3q+Pg/eTrYQbStXZscC9VOd Y6lNa2jzv01shQoiGBwp7ERNqt75Kwv/HYHIY490FoxBiW0JdbwgtsgNEFsOvbTCwZAX 0ngg== X-Gm-Message-State: AOAM531/I6s3m0byD0pvxInkhcnhUZUCIHxGuRSmuWwVf+rHr+slLV8c IMiJPIL4VBjcyW/q1L0VTk8= X-Google-Smtp-Source: ABdhPJzLtjgx9rKXpftJQ3M/AjVwh3tS1Wft+TcpWG+nBi1kpACgdGxw5oQ6D2Jyk2AqBILEbaqIDA== X-Received: by 2002:a62:83cf:0:b029:1a8:3b72:ebb7 with SMTP id h198-20020a6283cf0000b02901a83b72ebb7mr37230156pfe.25.1609074759171; Sun, 27 Dec 2020 05:12:39 -0800 (PST) Received: from sh05419pcu.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id j15sm33510269pfn.180.2020.12.27.05.12.35 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 27 Dec 2020 05:12:38 -0800 (PST) From: Hongtao Wu To: Lorenzo Pieralisi , Rob Herring Cc: Orson Zhai , Baolin Wang , Chunyan Zhang , linux-pci@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Hongtao Wu Subject: [PATCH v4 2/2] PCI: sprd: Add support for Unisoc SoCs' PCIe controller Date: Sun, 27 Dec 2020 21:12:14 +0800 Message-Id: <1609074734-9336-3-git-send-email-wuht06@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1609074734-9336-1-git-send-email-wuht06@gmail.com> References: <1609074734-9336-1-git-send-email-wuht06@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Hongtao Wu This series adds PCIe controller driver for Unisoc SoCs. This controller is based on DesignWare PCIe IP. Signed-off-by: Hongtao Wu --- drivers/pci/controller/dwc/Kconfig | 12 ++ drivers/pci/controller/dwc/Makefile | 1 + drivers/pci/controller/dwc/pcie-sprd.c | 293 +++++++++++++++++++++++++++++++++ 3 files changed, 306 insertions(+) create mode 100644 drivers/pci/controller/dwc/pcie-sprd.c -- 2.7.4 diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig index 22c5529..61f0b79 100644 --- a/drivers/pci/controller/dwc/Kconfig +++ b/drivers/pci/controller/dwc/Kconfig @@ -318,4 +318,16 @@ config PCIE_AL required only for DT-based platforms. ACPI platforms with the Annapurna Labs PCIe controller don't need to enable this. +config PCIE_SPRD + tristate "Unisoc PCIe controller - Host Mode" + depends on ARCH_SPRD || COMPILE_TEST + depends on PCI_MSI_IRQ_DOMAIN + select PCIE_DW_HOST + help + Unisoc PCIe controller uses the DesignWare core. It can be configured + as an Endpoint (EP) or a Root complex (RC). In order to enable host + mode (the controller works as RC), PCIE_SPRD must be selected. + Say Y or M here if you want to PCIe RC controller support on Unisoc + SoCs. + endmenu diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile index a751553..eb546e9 100644 --- a/drivers/pci/controller/dwc/Makefile +++ b/drivers/pci/controller/dwc/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_PCI_MESON) += pci-meson.o obj-$(CONFIG_PCIE_TEGRA194) += pcie-tegra194.o obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o +obj-$(CONFIG_PCIE_SPRD) += pcie-sprd.o # The following drivers are for devices that use the generic ACPI # pci_root.c driver but don't support standard ECAM config access. diff --git a/drivers/pci/controller/dwc/pcie-sprd.c b/drivers/pci/controller/dwc/pcie-sprd.c new file mode 100644 index 0000000..27d7231 --- /dev/null +++ b/drivers/pci/controller/dwc/pcie-sprd.c @@ -0,0 +1,293 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PCIe host controller driver for Unisoc SoCs + * + * Copyright (C) 2020-2021 Unisoc, Inc. + * + * Author: Hongtao Wu + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pcie-designware.h" + +/* aon apb syscon */ +#define IPA_ACCESS_CFG 0xcd8 +#define AON_ACCESS_PCIE_EN BIT(1) + +/* pmu apb syscon */ +#define SNPS_PCIE3_SLP_CTRL 0xac +#define PERST_N_ASSERT BIT(1) +#define PERST_N_AUTO_EN BIT(0) +#define PD_PCIE_CFG_0 0x3e8 +#define PCIE_FORCE_SHUTDOWN BIT(25) + +#define PCIE_SS_REG_BASE 0xE00 +#define APB_CLKFREQ_TIMEOUT 0x4 +#define BUSERR_EN BIT(12) +#define APB_TIMER_DIS BIT(10) +#define APB_TIMER_LIMIT GENMASK(31, 16) + +#define PE0_GEN_CTRL_3 0x58 +#define LTSSM_EN BIT(0) + +struct sprd_pcie_soc_data { + u32 syscon_offset; +}; + +static const struct sprd_pcie_soc_data ums9520_syscon_data = { + .syscon_offset = 0x1000, /* The offset of set/clear register */ +}; + +struct sprd_pcie { + u32 syscon_offset; + struct device *dev; + struct dw_pcie *pci; + struct regmap *aon_map; + struct regmap *pmu_map; + const struct sprd_pcie_soc_data *socdata; +}; + +enum sprd_pcie_syscon_type { + normal_syscon, /* it's not a set/clear register */ + set_syscon, /* set a set/clear register */ + clr_syscon, /* clear a set/clear register */ +}; + +static void sprd_pcie_buserr_enable(struct dw_pcie *pci) +{ + u32 val; + + val = dw_pcie_readl_dbi(pci, PCIE_SS_REG_BASE + APB_CLKFREQ_TIMEOUT); + val &= ~APB_TIMER_DIS; + val |= BUSERR_EN; + val |= APB_TIMER_LIMIT & (0x1f4 << 16); + dw_pcie_writel_dbi(pci, PCIE_SS_REG_BASE + APB_CLKFREQ_TIMEOUT, val); +} + +static void sprd_pcie_ltssm_enable(struct dw_pcie *pci, bool enable) +{ + u32 val; + + val = dw_pcie_readl_dbi(pci, PCIE_SS_REG_BASE + PE0_GEN_CTRL_3); + if (enable) + dw_pcie_writel_dbi(pci, PCIE_SS_REG_BASE + PE0_GEN_CTRL_3, + val | LTSSM_EN); + else + dw_pcie_writel_dbi(pci, PCIE_SS_REG_BASE + PE0_GEN_CTRL_3, + val & ~LTSSM_EN); +} + +static int sprd_pcie_syscon_set(struct sprd_pcie *ctrl, struct regmap *map, + u32 reg, u32 mask, u32 val, + enum sprd_pcie_syscon_type type) +{ + int ret = 0; + u32 read_val; + u32 offset = ctrl->syscon_offset; + struct device *dev = ctrl->pci->dev; + + /* + * Each set/clear register has three registers: + * reg: base register + * reg + offset: set register + * reg + offset * 2: clear register + */ + switch (type) { + case normal_syscon: + ret = regmap_read(map, reg, &read_val); + if (ret) { + dev_err(dev, "failed to read register 0x%x\n", reg); + return ret; + } + read_val &= ~mask; + read_val |= (val & mask); + ret = regmap_write(map, reg, read_val); + break; + case set_syscon: + reg = reg + offset; + ret = regmap_write(map, reg, val); + break; + case clr_syscon: + reg = reg + offset * 2; + ret = regmap_write(map, reg, val); + break; + default: + break; + } + + if (ret) + dev_err(dev, "failed to write register 0x%x\n", reg); + + return ret; +} + +static int sprd_pcie_perst_assert(struct sprd_pcie *ctrl) +{ + return sprd_pcie_syscon_set(ctrl, ctrl->pmu_map, SNPS_PCIE3_SLP_CTRL, + PERST_N_ASSERT, PERST_N_ASSERT, set_syscon); +} + +static int sprd_pcie_perst_deassert(struct sprd_pcie *ctrl) +{ + int ret; + + ret = sprd_pcie_syscon_set(ctrl, ctrl->pmu_map, SNPS_PCIE3_SLP_CTRL, + PERST_N_ASSERT, 0, clr_syscon); + usleep_range(2000, 3000); + + return ret; +} + +static int sprd_pcie_power_on(struct platform_device *pdev) +{ + int ret; + struct sprd_pcie *ctrl = platform_get_drvdata(pdev); + struct dw_pcie *pci = ctrl->pci; + + ret = sprd_pcie_syscon_set(ctrl, ctrl->aon_map, PD_PCIE_CFG_0, + PCIE_FORCE_SHUTDOWN, 0, clr_syscon); + if (ret) + return ret; + + ret = sprd_pcie_syscon_set(ctrl, ctrl->aon_map, IPA_ACCESS_CFG, + AON_ACCESS_PCIE_EN, AON_ACCESS_PCIE_EN, + set_syscon); + if (ret) + return ret; + + ret = sprd_pcie_perst_deassert(ctrl); + if (ret) + return ret; + + sprd_pcie_buserr_enable(pci); + sprd_pcie_ltssm_enable(pci, true); + + return ret; +} + +static int sprd_pcie_power_off(struct platform_device *pdev) +{ + struct sprd_pcie *ctrl = platform_get_drvdata(pdev); + struct dw_pcie *pci = ctrl->pci; + + sprd_pcie_ltssm_enable(pci, false); + + sprd_pcie_perst_assert(ctrl); + sprd_pcie_syscon_set(ctrl, ctrl->aon_map, PD_PCIE_CFG_0, + PCIE_FORCE_SHUTDOWN, PCIE_FORCE_SHUTDOWN, + set_syscon); + sprd_pcie_syscon_set(ctrl, ctrl->aon_map, IPA_ACCESS_CFG, + AON_ACCESS_PCIE_EN, 0, clr_syscon); + + return 0; +} + +static int sprd_add_pcie_port(struct platform_device *pdev) +{ + struct sprd_pcie *ctrl = platform_get_drvdata(pdev); + struct dw_pcie *pci = ctrl->pci; + struct pcie_port *pp = &pci->pp; + + return dw_pcie_host_init(pp); +} + +static int sprd_pcie_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct sprd_pcie *ctrl; + struct dw_pcie *pci; + int ret; + + ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); + if (!ctrl) + return -ENOMEM; + + ctrl->socdata = + (struct sprd_pcie_soc_data *)of_device_get_match_data(dev); + if (!ctrl->socdata) { + dev_warn(dev, + "using the default set/clear register offset address"); + ctrl->syscon_offset = 0x1000; + } + ctrl->syscon_offset = ctrl->socdata->syscon_offset; + + ctrl->aon_map = syscon_regmap_lookup_by_phandle(dev->of_node, + "sprd, regmap-aon"); + if (IS_ERR(ctrl->aon_map)) { + dev_err(dev, "failed to get syscon regmap aon\n"); + ret = PTR_ERR(ctrl->aon_map); + goto err; + } + + ctrl->pmu_map = syscon_regmap_lookup_by_phandle(dev->of_node, + "sprd, regmap-pmu"); + if (IS_ERR(ctrl->pmu_map)) { + dev_err(dev, "failed to get syscon regmap pmu\n"); + ret = PTR_ERR(ctrl->pmu_map); + goto err; + } + + pci = ctrl->pci; + pci->dev = dev; + + platform_set_drvdata(pdev, ctrl); + + ret = sprd_pcie_power_on(pdev); + if (ret < 0) { + dev_err(dev, "failed to power on, return %d\n", + ret); + goto err_power_off; + } + + ret = sprd_add_pcie_port(pdev); + if (ret) { + dev_warn(dev, "failed to initialize RC controller\n"); + return ret; + } + + return 0; + +err_power_off: + sprd_pcie_power_off(pdev); +err: + return ret; +} + +static int sprd_pcie_remove(struct platform_device *pdev) +{ + sprd_pcie_power_off(pdev); + + return 0; +} + +static const struct of_device_id sprd_pcie_of_match[] = { + { + .compatible = "sprd,ums9520-pcie", + .data = &ums9520_syscon_data, + }, + {}, +}; + +static struct platform_driver sprd_pcie_driver = { + .probe = sprd_pcie_probe, + .remove = __exit_p(sprd_pcie_remove), + .driver = { + .name = "sprd-pcie", + .of_match_table = sprd_pcie_of_match, + }, +}; + +module_platform_driver(sprd_pcie_driver); + +MODULE_DESCRIPTION("Unisoc PCIe host controller driver"); +MODULE_LICENSE("GPL v2");