From patchwork Tue May 30 12:38:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kiran Gunda X-Patchwork-Id: 9754511 X-Patchwork-Delegate: agross@codeaurora.org Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E98F3602B9 for ; Tue, 30 May 2017 12:40:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DBFED2846F for ; Tue, 30 May 2017 12:40:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D07A828485; Tue, 30 May 2017 12:40:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2ED942847D for ; Tue, 30 May 2017 12:40:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751858AbdE3MkD (ORCPT ); Tue, 30 May 2017 08:40:03 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:56938 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751834AbdE3MkA (ORCPT ); Tue, 30 May 2017 08:40:00 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 68B33600C9; Tue, 30 May 2017 12:39:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1496147999; bh=e6j38lqEuzRtwOc58SE7ghkKEpP5qM3nTzsRboa40PM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AH+NToKVwg4M0enAaNx/Mbpxlgcp9lIfEzTm1OIHg4UhgsP2AJqvPiKbaMve5SDD+ 46NBAicj8hT07hRe9c2Heu0KXpQjKXjCr9zOT8BPyks00RdSAhLCMWgOiWbBihwaJU rJiVlBnz4OudTrleQ2Fcfk8VLZSQOKc5l68bHDfE= Received: from kgunda-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: kgunda@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 06BCF6081B; Tue, 30 May 2017 12:39:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1496147998; bh=e6j38lqEuzRtwOc58SE7ghkKEpP5qM3nTzsRboa40PM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Eep9SGQs9rAJ68u7TgmxAck+O8l05CMm8KeCRKdgv5yEHSVqdmXJdpRY6thVnS31i SGyQgduD9HE3gPSZ/p8MuD+f0XZSOy8YP5Fk93J15msgxvY6Ut5aNgjmbH6BZ5zTGP 9icaBfT0NXUnV3Hm9ziCNIPkfedZ/9YQNVRt9aLg= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 06BCF6081B Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=kgunda@codeaurora.org From: Kiran Gunda To: Kiran Gunda , Abhijeet Dharmapurikar , Subbaraman Narayanamurthy , Christophe JAILLET , David Collins , linux-kernel@vger.kernel.org Cc: linux-arm-msm@vger.kernel.org, adharmap@quicinc.com, aghayal@qti.qualcomm.com, sboyd@codeaurora.org Subject: [PATCH V1 04/15] spmi: pmic-arb: optimize table lookups Date: Tue, 30 May 2017 18:08:52 +0530 Message-Id: <1496147943-25822-5-git-send-email-kgunda@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1496147943-25822-1-git-send-email-kgunda@codeaurora.org> References: <1496147943-25822-1-git-send-email-kgunda@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Abhijeet Dharmapurikar The current driver uses a mix of radix tree and a fwd lookup table to translate between apid and ppid. It is buggy and confusing. Instead simply use a radix tree for v1 hardware and use the forward lookup table for v2. Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Kiran Gunda --- drivers/spmi/spmi-pmic-arb.c | 144 ++++++++++++++++++++++++++----------------- 1 file changed, 88 insertions(+), 56 deletions(-) diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 7201611..6320f1f 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -164,6 +164,8 @@ struct spmi_pmic_arb { * on v2 offset of SPMI_PIC_IRQ_CLEARn. */ struct pmic_arb_ver_ops { + int (*ppid_to_apid)(struct spmi_pmic_arb *pa, u8 sid, u16 addr, + u8 *apid); int (*mode)(struct spmi_pmic_arb *dev, u8 sid, u16 addr, mode_t *mode); /* spmi commands (read_cmd, write_cmd, cmd) functionality */ @@ -657,42 +659,6 @@ struct spmi_pmic_arb_irq_spec { unsigned irq:3; }; -static int search_mapping_table(struct spmi_pmic_arb *pa, - struct spmi_pmic_arb_irq_spec *spec, - u8 *apid) -{ - u16 ppid = spec->slave << 8 | spec->per; - u32 *mapping_table = pa->mapping_table; - int index = 0, i; - u32 data; - - for (i = 0; i < SPMI_MAPPING_TABLE_TREE_DEPTH; ++i) { - if (!test_and_set_bit(index, pa->mapping_table_valid)) - mapping_table[index] = readl_relaxed(pa->cnfg + - SPMI_MAPPING_TABLE_REG(index)); - - data = mapping_table[index]; - - if (ppid & BIT(SPMI_MAPPING_BIT_INDEX(data))) { - if (SPMI_MAPPING_BIT_IS_1_FLAG(data)) { - index = SPMI_MAPPING_BIT_IS_1_RESULT(data); - } else { - *apid = SPMI_MAPPING_BIT_IS_1_RESULT(data); - return 0; - } - } else { - if (SPMI_MAPPING_BIT_IS_0_FLAG(data)) { - index = SPMI_MAPPING_BIT_IS_0_RESULT(data); - } else { - *apid = SPMI_MAPPING_BIT_IS_0_RESULT(data); - return 0; - } - } - } - - return -ENODEV; -} - static int qpnpint_irq_domain_dt_translate(struct irq_domain *d, struct device_node *controller, const u32 *intspec, @@ -702,7 +668,7 @@ static int qpnpint_irq_domain_dt_translate(struct irq_domain *d, { struct spmi_pmic_arb *pa = d->host_data; struct spmi_pmic_arb_irq_spec spec; - int err; + int rc; u8 apid; dev_dbg(&pa->spmic->dev, @@ -720,11 +686,14 @@ static int qpnpint_irq_domain_dt_translate(struct irq_domain *d, spec.per = intspec[1]; spec.irq = intspec[2]; - err = search_mapping_table(pa, &spec, &apid); - if (err) - return err; - - pa->apid_to_ppid[apid] = spec.slave << 8 | spec.per; + rc = pa->ver_ops->ppid_to_apid(pa, intspec[0], + (intspec[1] << 8), &apid); + if (rc < 0) { + dev_err(&pa->spmic->dev, + "failed to xlate sid = 0x%x, periph = 0x%x, irq = %x rc = %d\n", + intspec[0], intspec[1], intspec[2], rc); + return rc; + } /* Keep track of {max,min}_apid for bounding search during interrupt */ if (apid > pa->max_apid) @@ -758,6 +727,54 @@ static int qpnpint_irq_domain_map(struct irq_domain *d, } static int +pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pa, u8 sid, u16 addr, u8 *apid) +{ + u16 ppid = sid << 8 | ((addr >> 8) & 0xFF); + u32 *mapping_table = pa->mapping_table; + int index = 0, i; + u16 apid_valid; + u32 data; + + apid_valid = pa->ppid_to_apid[ppid]; + if (apid_valid & PMIC_ARB_CHAN_VALID) { + *apid = (apid_valid & ~PMIC_ARB_CHAN_VALID); + return 0; + } + + for (i = 0; i < SPMI_MAPPING_TABLE_TREE_DEPTH; ++i) { + if (!test_and_set_bit(index, pa->mapping_table_valid)) + mapping_table[index] = readl_relaxed(pa->cnfg + + SPMI_MAPPING_TABLE_REG(index)); + + data = mapping_table[index]; + + if (ppid & BIT(SPMI_MAPPING_BIT_INDEX(data))) { + if (SPMI_MAPPING_BIT_IS_1_FLAG(data)) { + index = SPMI_MAPPING_BIT_IS_1_RESULT(data); + } else { + *apid = SPMI_MAPPING_BIT_IS_1_RESULT(data); + pa->ppid_to_apid[ppid] + = *apid | PMIC_ARB_CHAN_VALID; + pa->apid_to_ppid[*apid] = ppid; + return 0; + } + } else { + if (SPMI_MAPPING_BIT_IS_0_FLAG(data)) { + index = SPMI_MAPPING_BIT_IS_0_RESULT(data); + } else { + *apid = SPMI_MAPPING_BIT_IS_0_RESULT(data); + pa->ppid_to_apid[ppid] + = *apid | PMIC_ARB_CHAN_VALID; + pa->apid_to_ppid[*apid] = ppid; + return 0; + } + } + } + + return -ENODEV; +} + +static int pmic_arb_mode_v1(struct spmi_pmic_arb *pa, u8 sid, u16 addr, mode_t *mode) { *mode = S_IRUSR | S_IWUSR; @@ -797,6 +814,7 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pa, u16 ppid) id = (regval >> 8) & PMIC_ARB_PPID_MASK; pa->ppid_to_apid[id] = apid | PMIC_ARB_CHAN_VALID; + pa->apid_to_ppid[apid] = id; if (id == ppid) { apid |= PMIC_ARB_CHAN_VALID; break; @@ -809,20 +827,35 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pa, u16 ppid) static int -pmic_arb_mode_v2(struct spmi_pmic_arb *pa, u8 sid, u16 addr, mode_t *mode) +pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pa, u8 sid, u16 addr, u8 *apid) { u16 ppid = (sid << 8) | (addr >> 8); - u16 apid; - u8 owner; + u16 apid_valid; - apid = pa->ppid_to_apid[ppid]; - if (!(apid & PMIC_ARB_CHAN_VALID)) + apid_valid = pa->ppid_to_apid[ppid]; + if (!(apid_valid & PMIC_ARB_CHAN_VALID)) + apid_valid = pmic_arb_find_apid(pa, ppid); + if (!(apid_valid & PMIC_ARB_CHAN_VALID)) return -ENODEV; + *apid = (apid_valid & ~PMIC_ARB_CHAN_VALID); + return 0; +} + +static int +pmic_arb_mode_v2(struct spmi_pmic_arb *pa, u8 sid, u16 addr, mode_t *mode) +{ + u8 apid; + u8 owner; + int rc; + + rc = pmic_arb_ppid_to_apid_v2(pa, sid, addr, &apid); + if (rc < 0) + return rc; + *mode = 0; *mode |= S_IRUSR; - apid &= ~PMIC_ARB_CHAN_VALID; owner = pa->apid_to_owner[apid]; if (owner == pa->ee) *mode |= S_IWUSR; @@ -833,15 +866,12 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pa, u16 ppid) static int pmic_arb_offset_v2(struct spmi_pmic_arb *pa, u8 sid, u16 addr, u32 *offset) { - u16 ppid = (sid << 8) | (addr >> 8); - u16 apid; + u8 apid; + int rc; - apid = pa->ppid_to_apid[ppid]; - if (!(apid & PMIC_ARB_CHAN_VALID)) - apid = pmic_arb_find_apid(pa, ppid); - if (!(apid & PMIC_ARB_CHAN_VALID)) - return -ENODEV; - apid &= ~PMIC_ARB_CHAN_VALID; + rc = pmic_arb_ppid_to_apid_v2(pa, sid, addr, &apid); + if (rc < 0) + return rc; *offset = 0x1000 * pa->ee + 0x8000 * apid; return 0; @@ -898,6 +928,7 @@ static u32 pmic_arb_irq_clear_v2(u8 n) } static const struct pmic_arb_ver_ops pmic_arb_v1 = { + .ppid_to_apid = pmic_arb_ppid_to_apid_v1, .mode = pmic_arb_mode_v1, .non_data_cmd = pmic_arb_non_data_cmd_v1, .offset = pmic_arb_offset_v1, @@ -909,6 +940,7 @@ static u32 pmic_arb_irq_clear_v2(u8 n) }; static const struct pmic_arb_ver_ops pmic_arb_v2 = { + .ppid_to_apid = pmic_arb_ppid_to_apid_v2, .mode = pmic_arb_mode_v2, .non_data_cmd = pmic_arb_non_data_cmd_v2, .offset = pmic_arb_offset_v2,