From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4CB38413D6F for ; Tue, 16 Jun 2026 09:26:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781601973; cv=none; b=SV7MSVGYVc+OCT2vHywBDdmMWkUqY8Qw5ZTwnrLS2OKAJEPCslME8nbDeWf76E2k+vtWj9iB4Ljz/i7MQPgtBvm194b0pVNDMWqVsVS1kPfEMTpz5yE5LwFgSKxgPjh/7s1RA5QFnawSYOPBU11zIrx45YVKcX5lGdhH5GJAup8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781601973; c=relaxed/simple; bh=itbCX+K13JF6uUB7SNxRN4m64XA2MR8iGs/BblPnjA8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QmG+6Z+b6/Xx9A0qOf0Y/fB4IyI645OApegcn3wLLbY34D+oSaqhf3fFAUhk9ZlwSlP/NV94viBfdi7RhkGNdWOLuEpmVso6JmEEGkXuHQFyJWfk62FqkDrWFh7GjFhNpD3HWAfEN2UU281OCnnzvYMkF3Z6iVdMFEWL5Xt3xD4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=mTbPVpt6; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=A2/3OdH+; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="mTbPVpt6"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="A2/3OdH+" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 65G64rtD2912921 for ; Tue, 16 Jun 2026 09:26:10 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= O1fxxQckMesfjpPmPTUR+YdqKgcA3suaRxhIluX0dhA=; b=mTbPVpt6J7ZAgTAZ bTwYOD7Ma67YgwA45QSUtJXgl11n1DcdlSH1qGeQ10dOBqSz+9JsmsXQlkNYDLBc oQT2RoPpNGC8iyEFx+HWjH/yMi7nbxaSPViub3BeRzZTpUrlWQkLmL5izwqxvbUK DIio4luES1Hxtl7LRp4TyYZQn+KXJnVim1Vw4+NatNncrNYVw4RId/fjQs58uQjO N3S35K8RiHWO66VIEHwcwfalIZME3u2QomxUWVFAnJGhhRuIKQW6GcAYSwCB1dbW 9DOjyBiXqY1l4zT9ei+QzUWjdywfhHkV0UbW8hkxPdijcR/g+mQr7Fy5kS19OZjE 8TmfVw== Received: from mail-pj1-f72.google.com (mail-pj1-f72.google.com [209.85.216.72]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4ety52s93b-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Tue, 16 Jun 2026 09:26:10 +0000 (GMT) Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-37c64f7ff48so128123a91.2 for ; Tue, 16 Jun 2026 02:26:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1781601969; x=1782206769; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=O1fxxQckMesfjpPmPTUR+YdqKgcA3suaRxhIluX0dhA=; b=A2/3OdH+6Gh1YMmrLW35c9taZpvhwYz16uDKHobDlFe3YSMfpSmK082Mq0YLIAZeKW 3VPK8+R6z28fU/7a84riF8EsxQNPTA4tMadVMBUvwbJmoSX8zVfOuKanGxO+28I/fsWQ +Rf0TvGFF5bDr38kramc0qH4TZ8nbsiiMMhL6ESElHPJW4PHGBTC0R9qFvpo5Zsiv2wi 8vxVmpSQqvD7KaT1I2lw0D5ewb0DQTLpqn41cgJqbaV8fTh4RLeDZrLkwdd09nwKw3Lt oDW8mPgU7vAkz5nUKU28lfviU4lFrUpI/AN5jJQ/sowVY9ohIUkO5ZPxZHUhzxjJRtgv SQBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781601969; x=1782206769; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=O1fxxQckMesfjpPmPTUR+YdqKgcA3suaRxhIluX0dhA=; b=aXPLycc3QyiVU9DfWwdifwjo8+dEnCPZGYBuarQO4nHUrcUhPFE4ivPdPd/50qKbxu 5cHfKqIj3JVw1PvlDxSH1tHFktbsRH8PSGgOc+UhFT8jBGEJitjRqTLUUwr+5oRoA7M2 CcGdaXg5jwkylFGB4PsEb2subd0SnB/yQ4c7F/TueyTkpWuEnW6hnjYXjLpyBF//LGdD h5sUGoftfNljsXbRIJ0UCrh1ss0Js2I3XVlqouykpEgT93X1Zjt0603a6pe89NQouWSO J3oc8WN8JmOkd4CvWYYmaW18J9Rk6z9ey7R9GP3gVY3E/yC1aGGDhL5pvsTovXx6Fq2/ q1JA== X-Forwarded-Encrypted: i=1; AFNElJ90o1Wp+Z3m6arojkeJeSkspX7F1LXcLDfl8JwxOF8WinbJSHLj6Qb5+i223Gux7xekIE7YLdly2S3qPIc=@vger.kernel.org X-Gm-Message-State: AOJu0YyrwuisRbxpugOYcLsIbBCyBwQ0v33SIpygtaQyNlEw9CNn2b+Q tM0vehAOs5W+iy6bPatGiO2UcnKithaSy1BtIJePdyd8yqkQEgYBGFigsJAOkroWXTc2yUua+P9 Ni65aGTZscBrExzd/64JhZB+NAQ/wqg/ndl6Isfz5dc4Bh/heEFFy/WAcznfYHTNUH2Y= X-Gm-Gg: Acq92OHxgsKWdco8nnEuHp0lS0624O/XkBA6aldYfjv2v4VBwpgoVJCqpp/fC/OS1kp flbmRo2eS3D3JCdg8FYutWbvko3SUxizHGEF8VssNrCZ/uKUXBuQopJtj/M7g2ON85REVENUSoY bAmS7wK6L2ZwbVwGxFRLeJwajNh4BZTm9SLnH+HX1ro3yhW+YrXZ8g8mhbBslaC06qsziDuJFBO 52/m5bw9WrLwI8ZAXSCDfgzdQVfnl9oGnAtDV+0aTI/9nSYEf/HYE6NGECEUUyTE/706qDjNNGK M3f/7C70Vl5deXM7gnh33ty5w7h/icUL8hGRcxyKJPSkzJ8O8vUrRM0cvz8GxNLvPQQ4WRIuLcW jx2Fsi55DAoZEDJ1MXN18jF1URcjh6di+MIJUmjHwny4kUdLH8w== X-Received: by 2002:a17:903:2304:b0:2c0:eee2:fc40 with SMTP id d9443c01a7336-2c41050b417mr195047095ad.3.1781601969200; Tue, 16 Jun 2026 02:26:09 -0700 (PDT) X-Received: by 2002:a17:903:2304:b0:2c0:eee2:fc40 with SMTP id d9443c01a7336-2c41050b417mr195046815ad.3.1781601968701; Tue, 16 Jun 2026 02:26:08 -0700 (PDT) Received: from hu-mkshah-hyd.qualcomm.com ([202.46.22.19]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2c42f2e586bsm130042025ad.12.2026.06.16.02.26.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Jun 2026 02:26:08 -0700 (PDT) From: Maulik Shah Date: Tue, 16 Jun 2026 14:55:51 +0530 Subject: [PATCH v3 1/8] irqchip/qcom-pdc: restructure version support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260616-hamoa_pdc_v3-v3-1-4d8e1504ea75@oss.qualcomm.com> References: <20260616-hamoa_pdc_v3-v3-0-4d8e1504ea75@oss.qualcomm.com> In-Reply-To: <20260616-hamoa_pdc_v3-v3-0-4d8e1504ea75@oss.qualcomm.com> To: Bjorn Andersson , Konrad Dybcio , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Thomas Gleixner , Linus Walleij Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-gpio@vger.kernel.org, Sneh Mankad , Maulik Shah X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1781601959; l=13648; i=maulik.shah@oss.qualcomm.com; s=20240109; h=from:subject:message-id; bh=itbCX+K13JF6uUB7SNxRN4m64XA2MR8iGs/BblPnjA8=; b=KqKSABi8iCI00DEJLgxDcNHuSfh+jOw0osabAo04jVZD5aNMxhIA6HMCZuzXxQzNQi8pnXuCz srsE6xjE5IzC+eDJrFINY3jMfDSADHtrmuNDM6lWwe/y7cyDzoATKQN X-Developer-Key: i=maulik.shah@oss.qualcomm.com; a=ed25519; pk=bd9h5FIIliUddIk8p3BlQWBlzKEQ/YW5V+fe759hTWQ= X-Proofpoint-Spam-Info: AW1haW4tMjYwNjE2MDA5NCBTYWx0ZWRfXyBBHNqXmz3+S 0RwT0pTpV0gXY1jnUMZ0RK6ZllhFahsacYJ+u9sZpxwCJcQ52bbK8pN9+zL5IFpoBJONSapXHZd kAcf2b79WCzzGHv8vk7pQF1ylxc+Pok= X-Authority-Analysis: v=2.4 cv=FJwrAeos c=1 sm=1 tr=0 ts=6a3116b2 cx=c_pps a=RP+M6JBNLl+fLTcSJhASfg==:117 a=fChuTYTh2wq5r3m49p7fHw==:17 a=IkcTkHD0fZMA:10 a=FelO9ux0wxsA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=gowsoOTTUOVcmtlkKump:22 a=EUspDBNiAAAA:8 a=xNiqBINRuVKY77TANa4A:9 a=QEXdDO2ut3YA:10 a=iS9zxrgQBfv6-_F4QbHw:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjE2MDA5NCBTYWx0ZWRfX0OxQM5Fp8Xys K0uuhMiUUiYXI96kJhsirIje7eUu1VXfh4ByiffO/y4iOvkF2hpigcIdhNNxSnzTwqQaaZcPlvu VZ1WqHddaFctT47LDJOUHJmnuiJ2Jgou+kgIseuUyrzBmnvlRVgIzlqE1TQhshWA/Ldo8owE8+D TTlKsH7XAnPjYWlyOqTur1ySnP3RSn7lpbxciIUh0gUTTyKADb0b0SS2WM5VtO4cyRHEsxbWz0M jNRlR3Vdp+WklCwFCg3lfAQsIwE/6PGdowUC8JEWREa0U33ISeJD3l9vEXDhz7Ax3HSyTuFEw86 ygtxJmBkreOQNWV6ivZdnWi9u0lERiKxyb65QtQpbT+7ecM7z+hXMfqoDm52o2xzjxalG8XRRDB 0ye4H8XdlerX6IzZ+UdnFtN/HzYy6WvVA6ROnh33rK0/6J70ArHVee7n2Uj2s9YgL/cbT1OHtSL fVHcggIYyq4cOwamBdQ== X-Proofpoint-ORIG-GUID: xnttqDKZZ4Z4xk43mOQQhGVMYUrTDzGD X-Proofpoint-GUID: xnttqDKZZ4Z4xk43mOQQhGVMYUrTDzGD X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-16_02,2026-06-15_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 lowpriorityscore=0 spamscore=0 phishscore=0 malwarescore=0 impostorscore=0 adultscore=0 suspectscore=0 bulkscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606040000 definitions=main-2606160094 PDC irqchip updates IRQ_ENABLE and IRQ_CFG and for three different versions v2.7, v3.0 and v3.2. These registers are organized in H/W as below on various SoCs. +---------------------------------------------------------------+ | SM8350, SM8450 | SM8550, Hamoa | SM8650, SM8750 | |---------------------------------------------------------------| | v2.7 | v3.0 | v3.2 | |---------------------------------------------------------------| | IRQ_ENABLE_BANK | IRQ_ENABLE_BANK | NA | |---------------------------------------------------------------| | IRQ_CFG | IRQ_CFG | IRQ_CFG | | | | | | | | [31:6] Unused | | | [31:5] Unused | [5] GPIO_STATUS | | | [4] GPIO_STATUS| [4] GPIO_MASK | | [31:3] Unused | [3] GPIO_MASK | [3] IRQ_ENABLE | | [0:2] Type | [0:2] Type | [0:2] Type | +---------------------------------------------------------------| All SoCs PDC irqchip supports "pass through mode" in which all interrupts are forwarded to the GIC without any latching at PDC H/W. So far irqchip did not utilize GPIO_STATUS and GPIO_MASK from IRQ_CFG register for v3.0 and v3.2 since they are only needed to be configured when PDC runs in specific mode named "second level interrupt controller" where it can latch the GPIO interrupts in GPIO_STATUS and forward GPIO interrupts to GIC as LEVEL_HIGH type SPI interrupt. All the SoCs defaulted to pass through mode with the exception of some x1e. x1e PDC may be set to secondary controller mode for builds on CRD boards whereas it may be set to pass through mode for IoT-EVK boards. Restructure in preparation to add the second level interrupt controller mode utilizing GPIO_STATUS and GPIO_MASK bits which changed the bit positions between v3.0 and v3.2. No functional impact with the change. Signed-off-by: Maulik Shah --- drivers/irqchip/qcom-pdc.c | 207 ++++++++++++++++++++++++++++++++------------- 1 file changed, 149 insertions(+), 58 deletions(-) diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c index 2014dbb0bc43..23276325211d 100644 --- a/drivers/irqchip/qcom-pdc.c +++ b/drivers/irqchip/qcom-pdc.c @@ -21,21 +21,12 @@ #include #include -#define PDC_MAX_GPIO_IRQS 256 -#define PDC_DRV_SIZE 0x10000 - -/* Valid only on HW version < 3.2 */ -#define IRQ_ENABLE_BANK 0x10 -#define IRQ_ENABLE_BANK_MAX (IRQ_ENABLE_BANK + BITS_TO_BYTES(PDC_MAX_GPIO_IRQS)) +#define PDC_MAX_IRQS 256 +#define IRQ_ENABLE_BANK_MAX BITS_TO_BYTES(PDC_MAX_IRQS) #define IRQ_ENABLE_BANK_INDEX_MASK GENMASK(31, 5) #define IRQ_ENABLE_BANK_BIT_MASK GENMASK(4, 0) -#define IRQ_i_CFG 0x110 - -/* Valid only on HW version >= 3.2 */ -#define IRQ_i_CFG_IRQ_ENABLE 3 - -#define IRQ_i_CFG_TYPE_MASK GENMASK(2, 0) +#define PDC_DRV_SIZE 0x10000 #define PDC_VERSION_REG 0x1000 #define PDC_VERSION_MAJOR GENMASK(23, 16) #define PDC_VERSION_MINOR GENMASK(15, 8) @@ -46,6 +37,98 @@ /* Notable PDC versions */ #define PDC_VERSION_3_2 PDC_VERSION(3, 2, 0) +#define PDC_VERSION_3_0 PDC_VERSION(3, 0, 0) +#define PDC_VERSION_2_7 PDC_VERSION(2, 7, 0) + +/* + * PDC H/W registers layout per version: + * + * IRQ_ENABLE_BANK[b], b = 0....BITS_TO_BYTES(PDC_MAX_IRQS) + * IRQ_CFG[n], n = 0....PDC_MAX_IRQS + * + * +---------------------------------------------------------------+ + * | v2.7 | v3.0 | v3.2 | + * |---------------------------------------------------------------| + * | BASE | BASE | BASE | + * |---------------------------------------------------------------| + * | | + * | IRQ_ENABLE_BANK | IRQ_ENABLE_BANK | NA | + * |---------------------------------------------------------------| + * | IRQ_CFG | IRQ_CFG | IRQ_CFG | + * | | | | + * | | | [31:6] Unused | + * | | [31:5] Unused | [5] GPIO_STATUS | + * | | [4] GPIO_STATUS| [4] GPIO_MASK | + * | [31:3] Unused | [3] GPIO_MASK | [3] IRQ_ENABLE | + * | [0:2] Type | [0:2] Type | [0:2] Type | + * +---------------------------------------------------------------+ + */ + +/** + * struct pdc_regs: PDC registers location + * + * @irq_en_reg: IRQ_ENABLE_BANK register location + * @irq_cfg_reg: IRQ_CFG register location + */ +struct pdc_regs { + u32 irq_en_reg; + u32 irq_cfg_reg; +}; + +/** + * struct pdc_irq_cfg: bit fields for PDC IRQ_CFG register + * + * @irq_enable: bit number for IRQ_ENABLE field + * @irq_type: GENMASK for IRQ_TYPE field + */ +struct pdc_irq_cfg { + u32 irq_enable; + u32 irq_type; +}; + +/** + * struct pdc_desc: PDC driver state + * + * @base: PDC base register for DRV2 / HLOS + * @prev_base: PDC DRV1 base, applicable only for x1e RTL bug. + * @version: PDC version + * @regs: PDC regs (IRQ_ENABLE_BANK and IRQ_CFG) + * @cfg_fields: Fields of IRQ_CFG reg + */ +struct pdc_desc { + void __iomem *base; + void __iomem *prev_base; + u32 version; + const struct pdc_regs *regs; + const struct pdc_irq_cfg *cfg_fields; +}; + +static const struct pdc_regs pdc_v3_2 = { + .irq_cfg_reg = 0x110, +}; + +static const struct pdc_irq_cfg pdc_cfg_v3_2 = { + .irq_enable = 3, + .irq_type = GENMASK(2, 0), +}; + +static const struct pdc_regs pdc_v3_0 = { + .irq_en_reg = 0x10, + .irq_cfg_reg = 0x110, +}; + +static const struct pdc_irq_cfg pdc_cfg_v3_0 = { + .irq_type = GENMASK(2, 0), +}; + +static const struct pdc_regs pdc_v2_7 = { + .irq_en_reg = 0x10, + .irq_cfg_reg = 0x110, +}; + +static const struct pdc_irq_cfg pdc_cfg_v2_7 = { + .irq_type = GENMASK(2, 0), +}; struct pdc_pin_region { u32 pin_base; @@ -56,12 +139,11 @@ struct pdc_pin_region { #define pin_to_hwirq(r, p) ((r)->parent_base + (p) - (r)->pin_base) static DEFINE_RAW_SPINLOCK(pdc_lock); -static void __iomem *pdc_base; -static void __iomem *pdc_prev_base; static struct pdc_pin_region *pdc_region; static int pdc_region_cnt; static unsigned int pdc_version; static bool pdc_x1e_quirk; +static struct pdc_desc *pdc; static void pdc_base_reg_write(void __iomem *base, int reg, u32 i, u32 val) { @@ -70,12 +152,12 @@ static void pdc_base_reg_write(void __iomem *base, int reg, u32 i, u32 val) static void pdc_reg_write(int reg, u32 i, u32 val) { - pdc_base_reg_write(pdc_base, reg, i, val); + pdc_base_reg_write(pdc->base, reg, i, val); } static u32 pdc_reg_read(int reg, u32 i) { - return readl_relaxed(pdc_base + reg + i * sizeof(u32)); + return readl_relaxed(pdc->base + reg + i * sizeof(u32)); } static void pdc_x1e_irq_enable_write(u32 bank, u32 enable) @@ -86,24 +168,24 @@ static void pdc_x1e_irq_enable_write(u32 bank, u32 enable) switch (bank) { case 0 ... 1: /* Use previous DRV (client) region and shift to bank 3-4 */ - base = pdc_prev_base; + base = pdc->prev_base; bank += 3; break; case 2 ... 4: /* Use our own region and shift to bank 0-2 */ - base = pdc_base; + base = pdc->base; bank -= 2; break; case 5: /* No fixup required for bank 5 */ - base = pdc_base; + base = pdc->base; break; default: WARN_ON(1); return; } - pdc_base_reg_write(base, IRQ_ENABLE_BANK, bank, enable); + pdc_base_reg_write(base, pdc->regs->irq_en_reg, bank, enable); } static void pdc_enable_intr_bank(int pin_out, bool on) @@ -114,21 +196,21 @@ static void pdc_enable_intr_bank(int pin_out, bool on) index = FIELD_GET(IRQ_ENABLE_BANK_INDEX_MASK, pin_out); mask = FIELD_GET(IRQ_ENABLE_BANK_BIT_MASK, pin_out); - enable = pdc_reg_read(IRQ_ENABLE_BANK, index); + enable = pdc_reg_read(pdc->regs->irq_en_reg, index); __assign_bit(mask, &enable, on); if (pdc_x1e_quirk) pdc_x1e_irq_enable_write(index, enable); else - pdc_reg_write(IRQ_ENABLE_BANK, index, enable); + pdc_reg_write(pdc->regs->irq_en_reg, index, enable); } static void pdc_enable_intr_cfg(int pin_out, bool on) { - unsigned long enable = pdc_reg_read(IRQ_i_CFG, pin_out); + unsigned long enable = pdc_reg_read(pdc->regs->irq_cfg_reg, pin_out); - __assign_bit(IRQ_i_CFG_IRQ_ENABLE, &enable, on); - pdc_reg_write(IRQ_i_CFG, pin_out, enable); + __assign_bit(pdc->cfg_fields->irq_enable, &enable, on); + pdc_reg_write(pdc->regs->irq_cfg_reg, pin_out, enable); } static void __pdc_enable_intr(int pin_out, bool on) @@ -224,9 +306,9 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) return -EINVAL; } - old_pdc_type = pdc_reg_read(IRQ_i_CFG, d->hwirq); - pdc_type |= (old_pdc_type & ~IRQ_i_CFG_TYPE_MASK); - pdc_reg_write(IRQ_i_CFG, d->hwirq, pdc_type); + old_pdc_type = pdc_reg_read(pdc->regs->irq_cfg_reg, d->hwirq); + pdc_type |= (old_pdc_type & ~pdc->cfg_fields->irq_type); + pdc_reg_write(pdc->regs->irq_cfg_reg, d->hwirq, pdc_type); ret = irq_chip_set_type_parent(d, type); if (ret) @@ -327,7 +409,7 @@ static const struct irq_domain_ops qcom_pdc_ops = { .free = irq_domain_free_irqs_common, }; -static int pdc_setup_pin_mapping(struct device_node *np) +static int pdc_setup_pin_mapping(struct device *dev, struct device_node *np) { int ret, n, i; @@ -336,7 +418,8 @@ static int pdc_setup_pin_mapping(struct device_node *np) return -EINVAL; pdc_region_cnt = n / 3; - pdc_region = kzalloc_objs(*pdc_region, pdc_region_cnt); + pdc_region = devm_kcalloc(dev, pdc_region_cnt, sizeof(*pdc_region), + GFP_KERNEL); if (!pdc_region) { pdc_region_cnt = 0; return -ENOMEM; @@ -366,11 +449,11 @@ static int pdc_setup_pin_mapping(struct device_node *np) return 0; } - static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *parent) { struct irq_domain *parent_domain, *pdc_domain; struct device_node *node = pdev->dev.of_node; + struct device *dev = &pdev->dev; resource_size_t res_size; struct resource res; int ret; @@ -383,6 +466,30 @@ static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *pare if (res_size > resource_size(&res)) pr_warn("%pOF: invalid reg size, please fix DT\n", node); + pdc = devm_kzalloc(dev, sizeof(*pdc), GFP_KERNEL); + if (!pdc) + return -ENOMEM; + + pdc->base = devm_ioremap(dev, res.start, res_size); + if (!pdc->base) { + pr_err("%pOF: unable to map PDC registers\n", node); + return -ENXIO; + } + + pdc->version = pdc_reg_read(PDC_VERSION_REG, 0); + + if (pdc->version >= PDC_VERSION_3_2) { + pdc->cfg_fields = &pdc_cfg_v3_2; + pdc->regs = &pdc_v3_2; + } else if (pdc->version < PDC_VERSION_3_2 && + pdc->version >= PDC_VERSION_3_0) { + pdc->cfg_fields = &pdc_cfg_v3_0; + pdc->regs = &pdc_v3_0; + } else { + pdc->cfg_fields = &pdc_cfg_v2_7; + pdc->regs = &pdc_v2_7; + } + /* * PDC has multiple DRV regions, each one provides the same set of * registers for a particular client in the system. Due to a hardware @@ -392,8 +499,9 @@ static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *pare * region with the expected offset to preserve support for old DTs. */ if (of_device_is_compatible(node, "qcom,x1e80100-pdc")) { - pdc_prev_base = ioremap(res.start - PDC_DRV_SIZE, IRQ_ENABLE_BANK_MAX); - if (!pdc_prev_base) { + pdc->prev_base = devm_ioremap(dev, res.start - PDC_DRV_SIZE, + pdc->regs->irq_en_reg + IRQ_ENABLE_BANK_MAX); + if (!pdc->prev_base) { pr_err("%pOF: unable to map previous PDC DRV region\n", node); return -ENXIO; } @@ -401,48 +509,31 @@ static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *pare pdc_x1e_quirk = true; } - pdc_base = ioremap(res.start, res_size); - if (!pdc_base) { - pr_err("%pOF: unable to map PDC registers\n", node); - ret = -ENXIO; - goto fail; - } - - pdc_version = pdc_reg_read(PDC_VERSION_REG, 0); - parent_domain = irq_find_host(parent); if (!parent_domain) { pr_err("%pOF: unable to find PDC's parent domain\n", node); - ret = -ENXIO; - goto fail; + return -ENXIO; } - ret = pdc_setup_pin_mapping(node); + ret = pdc_setup_pin_mapping(dev, node); if (ret) { pr_err("%pOF: failed to init PDC pin-hwirq mapping\n", node); - goto fail; + return ret; } pdc_domain = irq_domain_create_hierarchy(parent_domain, - IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP, - PDC_MAX_GPIO_IRQS, - of_fwnode_handle(node), - &qcom_pdc_ops, NULL); + IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP, + PDC_MAX_IRQS, + of_fwnode_handle(node), + &qcom_pdc_ops, NULL); if (!pdc_domain) { pr_err("%pOF: PDC domain add failed\n", node); - ret = -ENOMEM; - goto fail; + return -ENOMEM; } irq_domain_update_bus_token(pdc_domain, DOMAIN_BUS_WAKEUP); return 0; - -fail: - kfree(pdc_region); - iounmap(pdc_base); - iounmap(pdc_prev_base); - return ret; } IRQCHIP_PLATFORM_DRIVER_BEGIN(qcom_pdc) -- 2.43.0