From patchwork Mon Mar 2 11:29:11 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suzuki K Poulose X-Patchwork-Id: 5911731 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id B7CB59F373 for ; Mon, 2 Mar 2015 11:33:18 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AB92C20265 for ; Mon, 2 Mar 2015 11:33:17 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8E48B20268 for ; Mon, 2 Mar 2015 11:33:16 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YSOYT-000305-Vt; Mon, 02 Mar 2015 11:30:33 +0000 Received: from service87.mimecast.com ([91.220.42.44]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YSOXh-0001RS-4O for linux-arm-kernel@lists.infradead.org; Mon, 02 Mar 2015 11:29:48 +0000 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by service87.mimecast.com; Mon, 02 Mar 2015 11:29:20 +0000 Received: from e106634-lin.cambridge.arm.com ([10.1.255.212]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Mon, 2 Mar 2015 11:29:19 +0000 From: "Suzuki K. Poulose" To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 2/5] arm-cci: Abstract the CCI400 PMU speicific definitions Date: Mon, 2 Mar 2015 11:29:11 +0000 Message-Id: <1425295754-13376-3-git-send-email-suzuki.poulose@arm.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1425295754-13376-1-git-send-email-suzuki.poulose@arm.com> References: <1425295754-13376-1-git-send-email-suzuki.poulose@arm.com> X-OriginalArrivalTime: 02 Mar 2015 11:29:19.0336 (UTC) FILETIME=[1F985680:01D054DC] X-MC-Unique: 115030211292003601 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150302_032945_514831_0B2811A2 X-CRM114-Status: GOOD ( 10.84 ) X-Spam-Score: -2.3 (--) Cc: devicetree@vger.kernel.org, Lorenzo.Pieralisi@arm.com, Catalin.Marinas@arm.com, Pawel.Moll@arm.com, arnd@arndb.de, b.zolnierkie@samsung.com, Will.Deacon@arm.com, nico@linaro.org, Liviu.Dudau@arm.com, linux-kernel@vger.kernel.org, olof@lixom.net, kgene@kernel.org, Sudeep.Holla@arm.com, a.kesavan@samsung.com, "Suzuki K. Poulose" , Punit.Agrawal@arm.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: "Suzuki K. Poulose" CCI400 has different event specifications for PMU, for revsion0 and revision 1. As of now, we check the revision twice, for using the parameters for the PMU. This patch abstracts the details of the pmu models in a struct (cci_pmu_model) and stores the information in cci_pmu at initialisation time, avoiding multiple probe operations. This will also help us to add new PMU versions. Signed-off-by: Suzuki K. Poulose --- drivers/bus/arm-cci.c | 124 ++++++++++++++++++++++++++++++------------------- 1 file changed, 76 insertions(+), 48 deletions(-) diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index f27cf56..bec014b 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c @@ -79,19 +79,38 @@ static const struct of_device_id arm_cci_matches[] = { #define CCI_PMU_MAX_HW_EVENTS 5 /* CCI PMU has 4 counters + 1 cycle counter */ +/* Types of interfaces that can generate events */ +enum { + CCI_IF_SLAVE, + CCI_IF_MASTER, + CCI_IF_MAX, +}; + +struct event_range { + u32 min; + u32 max; +}; + struct cci_pmu_hw_events { struct perf_event *events[CCI_PMU_MAX_HW_EVENTS]; unsigned long used_mask[BITS_TO_LONGS(CCI_PMU_MAX_HW_EVENTS)]; raw_spinlock_t pmu_lock; }; +struct cci_pmu_model { + char *name; + struct event_range event_ranges[CCI_IF_MAX]; +}; + +static struct cci_pmu_model cci_pmu_models[]; + struct cci_pmu { void __iomem *base; struct pmu pmu; int nr_irqs; int irqs[CCI_PMU_MAX_HW_EVENTS]; unsigned long active_irqs; - struct pmu_port_event_ranges *port_ranges; + const struct cci_pmu_model *model; struct cci_pmu_hw_events hw_events; struct platform_device *plat_device; int num_events; @@ -152,47 +171,16 @@ enum cci400_perf_events { #define CCI_REV_R1_MASTER_PORT_MIN_EV 0x00 #define CCI_REV_R1_MASTER_PORT_MAX_EV 0x11 -struct pmu_port_event_ranges { - u8 slave_min; - u8 slave_max; - u8 master_min; - u8 master_max; -}; - -static struct pmu_port_event_ranges port_event_range[] = { - [CCI_REV_R0] = { - .slave_min = CCI_REV_R0_SLAVE_PORT_MIN_EV, - .slave_max = CCI_REV_R0_SLAVE_PORT_MAX_EV, - .master_min = CCI_REV_R0_MASTER_PORT_MIN_EV, - .master_max = CCI_REV_R0_MASTER_PORT_MAX_EV, - }, - [CCI_REV_R1] = { - .slave_min = CCI_REV_R1_SLAVE_PORT_MIN_EV, - .slave_max = CCI_REV_R1_SLAVE_PORT_MAX_EV, - .master_min = CCI_REV_R1_MASTER_PORT_MIN_EV, - .master_max = CCI_REV_R1_MASTER_PORT_MAX_EV, - }, -}; - -/* - * Export different PMU names for the different revisions so userspace knows - * because the event ids are different - */ -static char *const pmu_names[] = { - [CCI_REV_R0] = "CCI_400", - [CCI_REV_R1] = "CCI_400_r1", -}; - static int pmu_is_valid_slave_event(u8 ev_code) { - return pmu->port_ranges->slave_min <= ev_code && - ev_code <= pmu->port_ranges->slave_max; + return pmu->model->event_ranges[CCI_IF_SLAVE].min <= ev_code && + ev_code <= pmu->model->event_ranges[CCI_IF_SLAVE].max; } static int pmu_is_valid_master_event(u8 ev_code) { - return pmu->port_ranges->master_min <= ev_code && - ev_code <= pmu->port_ranges->master_max; + return pmu->model->event_ranges[CCI_IF_MASTER].min <= ev_code && + ev_code <= pmu->model->event_ranges[CCI_IF_MASTER].max; } static int pmu_validate_hw_event(u8 hw_event) @@ -234,11 +222,9 @@ static int probe_cci_revision(void) return CCI_REV_R1; } -static struct pmu_port_event_ranges *port_range_by_rev(void) +static const struct cci_pmu_model *probe_cci_model(struct platform_device *pdev) { - int rev = probe_cci_revision(); - - return &port_event_range[rev]; + return &cci_pmu_models[probe_cci_revision()]; } static int pmu_is_valid_counter(struct cci_pmu *cci_pmu, int idx) @@ -807,9 +793,9 @@ static const struct attribute_group *pmu_attr_groups[] = { static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev) { - char *name = pmu_names[probe_cci_revision()]; + char *name = cci_pmu->model->name; cci_pmu->pmu = (struct pmu) { - .name = pmu_names[probe_cci_revision()], + .name = cci_pmu->model->name, .task_ctx_nr = perf_invalid_context, .pmu_enable = cci_pmu_enable, .pmu_disable = cci_pmu_disable, @@ -862,6 +848,35 @@ static struct notifier_block cci_pmu_cpu_nb = { .priority = CPU_PRI_PERF + 1, }; +static struct cci_pmu_model cci_pmu_models[] = { + [CCI_REV_R0] = { + .name = "CCI_400", + .event_ranges = { + [CCI_IF_SLAVE] = { + CCI_REV_R0_SLAVE_PORT_MIN_EV, + CCI_REV_R0_SLAVE_PORT_MAX_EV, + }, + [CCI_IF_MASTER] = { + CCI_REV_R0_MASTER_PORT_MIN_EV, + CCI_REV_R0_MASTER_PORT_MAX_EV, + }, + }, + }, + [CCI_REV_R1] = { + .name = "CCI_400_r1", + .event_ranges = { + [CCI_IF_SLAVE] = { + CCI_REV_R1_SLAVE_PORT_MIN_EV, + CCI_REV_R1_SLAVE_PORT_MAX_EV, + }, + [CCI_IF_MASTER] = { + CCI_REV_R1_MASTER_PORT_MIN_EV, + CCI_REV_R1_MASTER_PORT_MAX_EV, + }, + }, + }, +}; + static const struct of_device_id arm_cci_pmu_matches[] = { { .compatible = "arm,cci-400-pmu", @@ -869,6 +884,16 @@ static const struct of_device_id arm_cci_pmu_matches[] = { {}, }; +static inline const struct cci_pmu_model *get_cci_model(struct platform_device *pdev) +{ + const struct of_device_id *match = of_match_node(arm_cci_pmu_matches, + pdev->dev.of_node); + if (!match) + return NULL; + + return probe_cci_model(pdev); +} + static bool is_duplicate_irq(int irq, int *irqs, int nr_irqs) { int i; @@ -884,11 +909,19 @@ static int cci_pmu_probe(struct platform_device *pdev) { struct resource *res; int i, ret, irq; + const struct cci_pmu_model *model; + + model = get_cci_model(pdev); + if (!model) { + dev_warn(&pdev->dev, "CCI PMU version not supported\n"); + return -EINVAL; + } pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL); if (!pmu) return -ENOMEM; + pmu->model = model; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); pmu->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(pmu->base)) @@ -920,12 +953,6 @@ static int cci_pmu_probe(struct platform_device *pdev) return -EINVAL; } - pmu->port_ranges = port_range_by_rev(); - if (!pmu->port_ranges) { - dev_warn(&pdev->dev, "CCI PMU version not supported\n"); - return -EINVAL; - } - raw_spin_lock_init(&pmu->hw_events.pmu_lock); mutex_init(&pmu->reserve_mutex); atomic_set(&pmu->active_events, 0); @@ -939,6 +966,7 @@ static int cci_pmu_probe(struct platform_device *pdev) if (ret) return ret; + pr_info("ARM %s PMU driver probed", pmu->model->name); return 0; }