From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1161487AbbEELum (ORCPT ); Tue, 5 May 2015 07:50:42 -0400 Received: from eu-smtp-delivery-143.mimecast.com ([207.82.80.143]:32030 "EHLO eu-smtp-delivery-143.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752560AbbEELtZ (ORCPT ); Tue, 5 May 2015 07:49:25 -0400 From: "Suzuki K. Poulose" To: linux-arm-kernel@lists.infradead.org Cc: Arnd Bergmann , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Lorenzo Pieralisi , Olof Johansson , Pawel Moll , Punit Agrawal , Will Deacon , arm@kernel.org, "Suzuki K. Poulose" , Mark Rutland Subject: [PATCH 2/7] arm-cci: Cleanup PMU driver code Date: Tue, 5 May 2015 12:49:03 +0100 Message-Id: <1430826548-29960-3-git-send-email-suzuki.poulose@arm.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1430826548-29960-1-git-send-email-suzuki.poulose@arm.com> References: <1430826548-29960-1-git-send-email-suzuki.poulose@arm.com> X-OriginalArrivalTime: 05 May 2015 11:49:21.0865 (UTC) FILETIME=[86CBB390:01D08729] X-MC-Unique: JRKbovVkTtmSDBO2784dFQ-3 Content-Type: text/plain; charset=WINDOWS-1252 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by nfs id t45BonPq002215 From: "Suzuki K. Poulose" This patch gets rid of the global struct cci_pmu variable and makes the code use the cci_pmu explicitly. Makes code a bit more robust and reader friendly. Cc: Punit Agrawal Cc: Mark Rutland Cc: Will Deacon Signed-off-by: Suzuki K. Poulose --- drivers/bus/arm-cci.c | 142 ++++++++++++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 62 deletions(-) diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index 941b831..27cc200 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c @@ -124,9 +124,9 @@ struct cci_pmu { int num_events; atomic_t active_events; struct mutex reserve_mutex; + struct notifier_block cpu_nb; cpumask_t cpus; }; -static struct cci_pmu *pmu; #define to_cci_pmu(c) (container_of(c, struct cci_pmu, pmu)) @@ -179,7 +179,7 @@ enum cci400_perf_events { #define CCI_REV_R1_MASTER_PORT_MIN_EV 0x00 #define CCI_REV_R1_MASTER_PORT_MAX_EV 0x11 -static int pmu_validate_hw_event(unsigned long hw_event) +static int pmu_validate_hw_event(struct cci_pmu *cci_pmu, unsigned long hw_event) { u8 ev_source = CCI_PMU_EVENT_SOURCE(hw_event); u8 ev_code = CCI_PMU_EVENT_CODE(hw_event); @@ -207,8 +207,8 @@ static int pmu_validate_hw_event(unsigned long hw_event) return -ENOENT; } - if (ev_code >= pmu->model->event_ranges[if_type].min && - ev_code <= pmu->model->event_ranges[if_type].max) + if (ev_code >= cci_pmu->model->event_ranges[if_type].min && + ev_code <= cci_pmu->model->event_ranges[if_type].max) return hw_event; return -ENOENT; @@ -239,29 +239,31 @@ static int pmu_is_valid_counter(struct cci_pmu *cci_pmu, int idx) idx <= CCI_PMU_CNTR_LAST(cci_pmu); } -static u32 pmu_read_register(int idx, unsigned int offset) +static u32 pmu_read_register(struct cci_pmu *cci_pmu, int idx, unsigned int offset) { - return readl_relaxed(pmu->base + CCI_PMU_CNTR_BASE(idx) + offset); + return readl_relaxed(cci_pmu->base + CCI_PMU_CNTR_BASE(idx) + offset); } -static void pmu_write_register(u32 value, int idx, unsigned int offset) +static void pmu_write_register(struct cci_pmu *cci_pmu, u32 value, + int idx, unsigned int offset) { - return writel_relaxed(value, pmu->base + CCI_PMU_CNTR_BASE(idx) + offset); + return writel_relaxed(value, cci_pmu->base + + CCI_PMU_CNTR_BASE(idx) + offset); } -static void pmu_disable_counter(int idx) +static void pmu_disable_counter(struct cci_pmu *cci_pmu, int idx) { - pmu_write_register(0, idx, CCI_PMU_CNTR_CTRL); + pmu_write_register(cci_pmu, 0, idx, CCI_PMU_CNTR_CTRL); } -static void pmu_enable_counter(int idx) +static void pmu_enable_counter(struct cci_pmu *cci_pmu, int idx) { - pmu_write_register(1, idx, CCI_PMU_CNTR_CTRL); + pmu_write_register(cci_pmu, 1, idx, CCI_PMU_CNTR_CTRL); } -static void pmu_set_event(int idx, unsigned long event) +static void pmu_set_event(struct cci_pmu *cci_pmu, int idx, unsigned long event) { - pmu_write_register(event, idx, CCI_PMU_EVT_SEL); + pmu_write_register(cci_pmu, event, idx, CCI_PMU_EVT_SEL); } static u32 pmu_get_max_counters(void) @@ -306,7 +308,8 @@ static int pmu_map_event(struct perf_event *event) if (config == CCI_PMU_CYCLES) mapping = config; else - mapping = pmu_validate_hw_event(config); + mapping = pmu_validate_hw_event(to_cci_pmu(event->pmu), + config); return mapping; } @@ -319,7 +322,7 @@ static int pmu_request_irq(struct cci_pmu *cci_pmu, irq_handler_t handler) if (unlikely(!pmu_device)) return -ENODEV; - if (pmu->nr_irqs < 1) { + if (cci_pmu->nr_irqs < 1) { dev_err(&pmu_device->dev, "no irqs for CCI PMUs defined\n"); return -ENODEV; } @@ -331,16 +334,16 @@ static int pmu_request_irq(struct cci_pmu *cci_pmu, irq_handler_t handler) * * This should allow handling of non-unique interrupt for the counters. */ - for (i = 0; i < pmu->nr_irqs; i++) { - int err = request_irq(pmu->irqs[i], handler, IRQF_SHARED, + for (i = 0; i < cci_pmu->nr_irqs; i++) { + int err = request_irq(cci_pmu->irqs[i], handler, IRQF_SHARED, "arm-cci-pmu", cci_pmu); if (err) { dev_err(&pmu_device->dev, "unable to request IRQ%d for ARM CCI PMU counters\n", - pmu->irqs[i]); + cci_pmu->irqs[i]); return err; } - set_bit(i, &pmu->active_irqs); + set_bit(i, &cci_pmu->active_irqs); } return 0; @@ -350,11 +353,11 @@ static void pmu_free_irq(struct cci_pmu *cci_pmu) { int i; - for (i = 0; i < pmu->nr_irqs; i++) { - if (!test_and_clear_bit(i, &pmu->active_irqs)) + for (i = 0; i < cci_pmu->nr_irqs; i++) { + if (!test_and_clear_bit(i, &cci_pmu->active_irqs)) continue; - free_irq(pmu->irqs[i], cci_pmu); + free_irq(cci_pmu->irqs[i], cci_pmu); } } @@ -369,7 +372,7 @@ static u32 pmu_read_counter(struct perf_event *event) dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx); return 0; } - value = pmu_read_register(idx, CCI_PMU_CNTR); + value = pmu_read_register(cci_pmu, idx, CCI_PMU_CNTR); return value; } @@ -383,7 +386,7 @@ static void pmu_write_counter(struct perf_event *event, u32 value) if (unlikely(!pmu_is_valid_counter(cci_pmu, idx))) dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx); else - pmu_write_register(value, idx, CCI_PMU_CNTR); + pmu_write_register(cci_pmu, value, idx, CCI_PMU_CNTR); } static u64 pmu_event_update(struct perf_event *event) @@ -427,7 +430,7 @@ static irqreturn_t pmu_handle_irq(int irq_num, void *dev) { unsigned long flags; struct cci_pmu *cci_pmu = dev; - struct cci_pmu_hw_events *events = &pmu->hw_events; + struct cci_pmu_hw_events *events = &cci_pmu->hw_events; int idx, handled = IRQ_NONE; raw_spin_lock_irqsave(&events->pmu_lock, flags); @@ -446,11 +449,12 @@ static irqreturn_t pmu_handle_irq(int irq_num, void *dev) hw_counter = &event->hw; /* Did this counter overflow? */ - if (!(pmu_read_register(idx, CCI_PMU_OVRFLW) & + if (!(pmu_read_register(cci_pmu, idx, CCI_PMU_OVRFLW) & CCI_PMU_OVRFLW_FLAG)) continue; - pmu_write_register(CCI_PMU_OVRFLW_FLAG, idx, CCI_PMU_OVRFLW); + pmu_write_register(cci_pmu, CCI_PMU_OVRFLW_FLAG, idx, + CCI_PMU_OVRFLW); pmu_event_update(event); pmu_event_set_period(event); @@ -549,10 +553,10 @@ static void cci_pmu_start(struct perf_event *event, int pmu_flags) /* Configure the event to count, unless you are counting cycles */ if (idx != CCI_PMU_CYCLE_CNTR_IDX) - pmu_set_event(idx, hwc->config_base); + pmu_set_event(cci_pmu, idx, hwc->config_base); pmu_event_set_period(event); - pmu_enable_counter(idx); + pmu_enable_counter(cci_pmu, idx); raw_spin_unlock_irqrestore(&hw_events->pmu_lock, flags); } @@ -575,7 +579,7 @@ static void cci_pmu_stop(struct perf_event *event, int pmu_flags) * We always reprogram the counter, so ignore PERF_EF_UPDATE. See * cci_pmu_start() */ - pmu_disable_counter(idx); + pmu_disable_counter(cci_pmu, idx); pmu_event_update(event); hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; } @@ -779,20 +783,27 @@ static int cci_pmu_event_init(struct perf_event *event) return err; } -static ssize_t pmu_attr_cpumask_show(struct device *dev, +static ssize_t pmu_cpumask_attr_show(struct device *dev, struct device_attribute *attr, char *buf) { + struct dev_ext_attribute *eattr = container_of(attr, + struct dev_ext_attribute, attr); + struct cci_pmu *cci_pmu = eattr->var; + int n = scnprintf(buf, PAGE_SIZE - 1, "%*pbl", - cpumask_pr_args(&pmu->cpus)); + cpumask_pr_args(&cci_pmu->cpus)); buf[n++] = '\n'; buf[n] = '\0'; return n; } -static DEVICE_ATTR(cpumask, S_IRUGO, pmu_attr_cpumask_show, NULL); +static struct dev_ext_attribute pmu_cpumask_attr = { + __ATTR(cpumask, S_IRUGO, pmu_cpumask_attr_show, NULL), + NULL, /* Populated in cci_pmu_init */ +}; static struct attribute *pmu_attrs[] = { - &dev_attr_cpumask.attr, + &pmu_cpumask_attr.attr.attr, NULL, }; @@ -808,6 +819,8 @@ static const struct attribute_group *pmu_attr_groups[] = { static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev) { char *name = cci_pmu->model->name; + + pmu_cpumask_attr.var = cci_pmu; cci_pmu->pmu = (struct pmu) { .name = cci_pmu->model->name, .task_ctx_nr = perf_invalid_context, @@ -831,12 +844,14 @@ static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev) static int cci_pmu_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) { + struct cci_pmu *cci_pmu = container_of(self, + struct cci_pmu, cpu_nb); unsigned int cpu = (long)hcpu; unsigned int target; switch (action & ~CPU_TASKS_FROZEN) { case CPU_DOWN_PREPARE: - if (!cpumask_test_and_clear_cpu(cpu, &pmu->cpus)) + if (!cpumask_test_and_clear_cpu(cpu, &cci_pmu->cpus)) break; target = cpumask_any_but(cpu_online_mask, cpu); if (target < 0) // UP, last CPU @@ -845,7 +860,7 @@ static int cci_pmu_cpu_notifier(struct notifier_block *self, * TODO: migrate context once core races on event->ctx have * been fixed. */ - cpumask_set_cpu(target, &pmu->cpus); + cpumask_set_cpu(target, &cci_pmu->cpus); default: break; } @@ -853,15 +868,6 @@ static int cci_pmu_cpu_notifier(struct notifier_block *self, return NOTIFY_OK; } -static struct notifier_block cci_pmu_cpu_nb = { - .notifier_call = cci_pmu_cpu_notifier, - /* - * to migrate uncore events, our notifier should be executed - * before perf core's notifier. - */ - .priority = CPU_PRI_PERF + 1, -}; - static struct cci_pmu_model cci_pmu_models[] = { [CCI_REV_R0] = { .name = "CCI_400", @@ -935,6 +941,7 @@ static bool is_duplicate_irq(int irq, int *irqs, int nr_irqs) static int cci_pmu_probe(struct platform_device *pdev) { struct resource *res; + struct cci_pmu *cci_pmu; int i, ret, irq; const struct cci_pmu_model *model; @@ -944,30 +951,30 @@ static int cci_pmu_probe(struct platform_device *pdev) return -ENODEV; } - pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL); - if (!pmu) + cci_pmu = devm_kzalloc(&pdev->dev, sizeof(*cci_pmu), GFP_KERNEL); + if (!cci_pmu) return -ENOMEM; - pmu->model = model; + cci_pmu->model = model; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pmu->base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(pmu->base)) + cci_pmu->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(cci_pmu->base)) return -ENOMEM; /* * CCI PMU has 5 overflow signals - one per counter; but some may be tied * together to a common interrupt. */ - pmu->nr_irqs = 0; + cci_pmu->nr_irqs = 0; for (i = 0; i < CCI_PMU_MAX_HW_EVENTS; i++) { irq = platform_get_irq(pdev, i); if (irq < 0) break; - if (is_duplicate_irq(irq, pmu->irqs, pmu->nr_irqs)) + if (is_duplicate_irq(irq, cci_pmu->irqs, cci_pmu->nr_irqs)) continue; - pmu->irqs[pmu->nr_irqs++] = irq; + cci_pmu->irqs[cci_pmu->nr_irqs++] = irq; } /* @@ -980,20 +987,31 @@ static int cci_pmu_probe(struct platform_device *pdev) return -EINVAL; } - raw_spin_lock_init(&pmu->hw_events.pmu_lock); - mutex_init(&pmu->reserve_mutex); - atomic_set(&pmu->active_events, 0); - cpumask_set_cpu(smp_processor_id(), &pmu->cpus); + raw_spin_lock_init(&cci_pmu->hw_events.pmu_lock); + mutex_init(&cci_pmu->reserve_mutex); + atomic_set(&cci_pmu->active_events, 0); + cpumask_set_cpu(smp_processor_id(), &cci_pmu->cpus); - ret = register_cpu_notifier(&cci_pmu_cpu_nb); + cci_pmu->cpu_nb = (struct notifier_block) { + .notifier_call = cci_pmu_cpu_notifier, + /* + * to migrate uncore events, our notifier should be executed + * before perf core's notifier. + */ + .priority = CPU_PRI_PERF + 1, + }; + + ret = register_cpu_notifier(&cci_pmu->cpu_nb); if (ret) return ret; - ret = cci_pmu_init(pmu, pdev); - if (ret) + ret = cci_pmu_init(cci_pmu, pdev); + if (ret) { + unregister_cpu_notifier(&cci_pmu->cpu_nb); return ret; + } - pr_info("ARM %s PMU driver probed", pmu->model->name); + pr_info("ARM %s PMU driver probed", cci_pmu->model->name); return 0; } -- 1.7.9.5 From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Suzuki K. Poulose" Subject: [PATCH 2/7] arm-cci: Cleanup PMU driver code Date: Tue, 5 May 2015 12:49:03 +0100 Message-ID: <1430826548-29960-3-git-send-email-suzuki.poulose@arm.com> References: <1430826548-29960-1-git-send-email-suzuki.poulose@arm.com> Content-Type: text/plain; charset=WINDOWS-1252 Content-Transfer-Encoding: quoted-printable Return-path: In-Reply-To: <1430826548-29960-1-git-send-email-suzuki.poulose-5wv7dgnIgG8@public.gmane.org> Sender: devicetree-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org Cc: Arnd Bergmann , devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Lorenzo Pieralisi , Olof Johansson , Pawel Moll , Punit Agrawal , Will Deacon , arm-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org, "Suzuki K. Poulose" , Mark Rutland List-Id: devicetree@vger.kernel.org From: "Suzuki K. Poulose" This patch gets rid of the global struct cci_pmu variable and makes the code use the cci_pmu explicitly. Makes code a bit more robust and reader friendly. Cc: Punit Agrawal Cc: Mark Rutland Cc: Will Deacon Signed-off-by: Suzuki K. Poulose --- drivers/bus/arm-cci.c | 142 ++++++++++++++++++++++++++++-----------------= ---- 1 file changed, 80 insertions(+), 62 deletions(-) diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index 941b831..27cc200 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c @@ -124,9 +124,9 @@ struct cci_pmu { =09int num_events; =09atomic_t active_events; =09struct mutex reserve_mutex; +=09struct notifier_block cpu_nb; =09cpumask_t cpus; }; -static struct cci_pmu *pmu; =20 #define to_cci_pmu(c)=09(container_of(c, struct cci_pmu, pmu)) =20 @@ -179,7 +179,7 @@ enum cci400_perf_events { #define CCI_REV_R1_MASTER_PORT_MIN_EV=090x00 #define CCI_REV_R1_MASTER_PORT_MAX_EV=090x11 =20 -static int pmu_validate_hw_event(unsigned long hw_event) +static int pmu_validate_hw_event(struct cci_pmu *cci_pmu, unsigned long hw= _event) { =09u8 ev_source =3D CCI_PMU_EVENT_SOURCE(hw_event); =09u8 ev_code =3D CCI_PMU_EVENT_CODE(hw_event); @@ -207,8 +207,8 @@ static int pmu_validate_hw_event(unsigned long hw_event= ) =09=09return -ENOENT; =09} =20 -=09if (ev_code >=3D pmu->model->event_ranges[if_type].min && -=09=09ev_code <=3D pmu->model->event_ranges[if_type].max) +=09if (ev_code >=3D cci_pmu->model->event_ranges[if_type].min && +=09=09ev_code <=3D cci_pmu->model->event_ranges[if_type].max) =09=09return hw_event; =20 =09return -ENOENT; @@ -239,29 +239,31 @@ static int pmu_is_valid_counter(struct cci_pmu *cci_p= mu, int idx) =09=09idx <=3D CCI_PMU_CNTR_LAST(cci_pmu); } =20 -static u32 pmu_read_register(int idx, unsigned int offset) +static u32 pmu_read_register(struct cci_pmu *cci_pmu, int idx, unsigned in= t offset) { -=09return readl_relaxed(pmu->base + CCI_PMU_CNTR_BASE(idx) + offset); +=09return readl_relaxed(cci_pmu->base + CCI_PMU_CNTR_BASE(idx) + offset); } =20 -static void pmu_write_register(u32 value, int idx, unsigned int offset) +static void pmu_write_register(struct cci_pmu *cci_pmu, u32 value, +=09=09=09 int idx, unsigned int offset) { -=09return writel_relaxed(value, pmu->base + CCI_PMU_CNTR_BASE(idx) + offse= t); +=09return writel_relaxed(value, cci_pmu->base + +=09=09=09 CCI_PMU_CNTR_BASE(idx) + offset); } =20 -static void pmu_disable_counter(int idx) +static void pmu_disable_counter(struct cci_pmu *cci_pmu, int idx) { -=09pmu_write_register(0, idx, CCI_PMU_CNTR_CTRL); +=09pmu_write_register(cci_pmu, 0, idx, CCI_PMU_CNTR_CTRL); } =20 -static void pmu_enable_counter(int idx) +static void pmu_enable_counter(struct cci_pmu *cci_pmu, int idx) { -=09pmu_write_register(1, idx, CCI_PMU_CNTR_CTRL); +=09pmu_write_register(cci_pmu, 1, idx, CCI_PMU_CNTR_CTRL); } =20 -static void pmu_set_event(int idx, unsigned long event) +static void pmu_set_event(struct cci_pmu *cci_pmu, int idx, unsigned long = event) { -=09pmu_write_register(event, idx, CCI_PMU_EVT_SEL); +=09pmu_write_register(cci_pmu, event, idx, CCI_PMU_EVT_SEL); } =20 static u32 pmu_get_max_counters(void) @@ -306,7 +308,8 @@ static int pmu_map_event(struct perf_event *event) =09if (config =3D=3D CCI_PMU_CYCLES) =09=09mapping =3D config; =09else -=09=09mapping =3D pmu_validate_hw_event(config); +=09=09mapping =3D pmu_validate_hw_event(to_cci_pmu(event->pmu), +=09=09=09=09=09=09=09config); =20 =09return mapping; } @@ -319,7 +322,7 @@ static int pmu_request_irq(struct cci_pmu *cci_pmu, irq= _handler_t handler) =09if (unlikely(!pmu_device)) =09=09return -ENODEV; =20 -=09if (pmu->nr_irqs < 1) { +=09if (cci_pmu->nr_irqs < 1) { =09=09dev_err(&pmu_device->dev, "no irqs for CCI PMUs defined\n"); =09=09return -ENODEV; =09} @@ -331,16 +334,16 @@ static int pmu_request_irq(struct cci_pmu *cci_pmu, i= rq_handler_t handler) =09 * =09 * This should allow handling of non-unique interrupt for the counters. =09 */ -=09for (i =3D 0; i < pmu->nr_irqs; i++) { -=09=09int err =3D request_irq(pmu->irqs[i], handler, IRQF_SHARED, +=09for (i =3D 0; i < cci_pmu->nr_irqs; i++) { +=09=09int err =3D request_irq(cci_pmu->irqs[i], handler, IRQF_SHARED, =09=09=09=09"arm-cci-pmu", cci_pmu); =09=09if (err) { =09=09=09dev_err(&pmu_device->dev, "unable to request IRQ%d for ARM CCI PM= U counters\n", -=09=09=09=09pmu->irqs[i]); +=09=09=09=09cci_pmu->irqs[i]); =09=09=09return err; =09=09} =20 -=09=09set_bit(i, &pmu->active_irqs); +=09=09set_bit(i, &cci_pmu->active_irqs); =09} =20 =09return 0; @@ -350,11 +353,11 @@ static void pmu_free_irq(struct cci_pmu *cci_pmu) { =09int i; =20 -=09for (i =3D 0; i < pmu->nr_irqs; i++) { -=09=09if (!test_and_clear_bit(i, &pmu->active_irqs)) +=09for (i =3D 0; i < cci_pmu->nr_irqs; i++) { +=09=09if (!test_and_clear_bit(i, &cci_pmu->active_irqs)) =09=09=09continue; =20 -=09=09free_irq(pmu->irqs[i], cci_pmu); +=09=09free_irq(cci_pmu->irqs[i], cci_pmu); =09} } =20 @@ -369,7 +372,7 @@ static u32 pmu_read_counter(struct perf_event *event) =09=09dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", = idx); =09=09return 0; =09} -=09value =3D pmu_read_register(idx, CCI_PMU_CNTR); +=09value =3D pmu_read_register(cci_pmu, idx, CCI_PMU_CNTR); =20 =09return value; } @@ -383,7 +386,7 @@ static void pmu_write_counter(struct perf_event *event,= u32 value) =09if (unlikely(!pmu_is_valid_counter(cci_pmu, idx))) =09=09dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", = idx); =09else -=09=09pmu_write_register(value, idx, CCI_PMU_CNTR); +=09=09pmu_write_register(cci_pmu, value, idx, CCI_PMU_CNTR); } =20 static u64 pmu_event_update(struct perf_event *event) @@ -427,7 +430,7 @@ static irqreturn_t pmu_handle_irq(int irq_num, void *de= v) { =09unsigned long flags; =09struct cci_pmu *cci_pmu =3D dev; -=09struct cci_pmu_hw_events *events =3D &pmu->hw_events; +=09struct cci_pmu_hw_events *events =3D &cci_pmu->hw_events; =09int idx, handled =3D IRQ_NONE; =20 =09raw_spin_lock_irqsave(&events->pmu_lock, flags); @@ -446,11 +449,12 @@ static irqreturn_t pmu_handle_irq(int irq_num, void *= dev) =09=09hw_counter =3D &event->hw; =20 =09=09/* Did this counter overflow? */ -=09=09if (!(pmu_read_register(idx, CCI_PMU_OVRFLW) & +=09=09if (!(pmu_read_register(cci_pmu, idx, CCI_PMU_OVRFLW) & =09=09 CCI_PMU_OVRFLW_FLAG)) =09=09=09continue; =20 -=09=09pmu_write_register(CCI_PMU_OVRFLW_FLAG, idx, CCI_PMU_OVRFLW); +=09=09pmu_write_register(cci_pmu, CCI_PMU_OVRFLW_FLAG, idx, +=09=09=09=09=09=09=09CCI_PMU_OVRFLW); =20 =09=09pmu_event_update(event); =09=09pmu_event_set_period(event); @@ -549,10 +553,10 @@ static void cci_pmu_start(struct perf_event *event, i= nt pmu_flags) =20 =09/* Configure the event to count, unless you are counting cycles */ =09if (idx !=3D CCI_PMU_CYCLE_CNTR_IDX) -=09=09pmu_set_event(idx, hwc->config_base); +=09=09pmu_set_event(cci_pmu, idx, hwc->config_base); =20 =09pmu_event_set_period(event); -=09pmu_enable_counter(idx); +=09pmu_enable_counter(cci_pmu, idx); =20 =09raw_spin_unlock_irqrestore(&hw_events->pmu_lock, flags); } @@ -575,7 +579,7 @@ static void cci_pmu_stop(struct perf_event *event, int = pmu_flags) =09 * We always reprogram the counter, so ignore PERF_EF_UPDATE. See =09 * cci_pmu_start() =09 */ -=09pmu_disable_counter(idx); +=09pmu_disable_counter(cci_pmu, idx); =09pmu_event_update(event); =09hwc->state |=3D PERF_HES_STOPPED | PERF_HES_UPTODATE; } @@ -779,20 +783,27 @@ static int cci_pmu_event_init(struct perf_event *even= t) =09return err; } =20 -static ssize_t pmu_attr_cpumask_show(struct device *dev, +static ssize_t pmu_cpumask_attr_show(struct device *dev, =09=09=09=09 struct device_attribute *attr, char *buf) { +=09struct dev_ext_attribute *eattr =3D container_of(attr, +=09=09=09=09=09struct dev_ext_attribute, attr); +=09struct cci_pmu *cci_pmu =3D eattr->var; + =09int n =3D scnprintf(buf, PAGE_SIZE - 1, "%*pbl", -=09=09=09 cpumask_pr_args(&pmu->cpus)); +=09=09=09 cpumask_pr_args(&cci_pmu->cpus)); =09buf[n++] =3D '\n'; =09buf[n] =3D '\0'; =09return n; } =20 -static DEVICE_ATTR(cpumask, S_IRUGO, pmu_attr_cpumask_show, NULL); +static struct dev_ext_attribute pmu_cpumask_attr =3D { +=09__ATTR(cpumask, S_IRUGO, pmu_cpumask_attr_show, NULL), +=09NULL,=09=09/* Populated in cci_pmu_init */ +}; =20 static struct attribute *pmu_attrs[] =3D { -=09&dev_attr_cpumask.attr, +=09&pmu_cpumask_attr.attr.attr, =09NULL, }; =20 @@ -808,6 +819,8 @@ static const struct attribute_group *pmu_attr_groups[] = =3D { static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *p= dev) { =09char *name =3D cci_pmu->model->name; + +=09pmu_cpumask_attr.var =3D cci_pmu; =09cci_pmu->pmu =3D (struct pmu) { =09=09.name=09=09=3D cci_pmu->model->name, =09=09.task_ctx_nr=09=3D perf_invalid_context, @@ -831,12 +844,14 @@ static int cci_pmu_init(struct cci_pmu *cci_pmu, stru= ct platform_device *pdev) static int cci_pmu_cpu_notifier(struct notifier_block *self, =09=09=09=09unsigned long action, void *hcpu) { +=09struct cci_pmu *cci_pmu =3D container_of(self, +=09=09=09=09=09struct cci_pmu, cpu_nb); =09unsigned int cpu =3D (long)hcpu; =09unsigned int target; =20 =09switch (action & ~CPU_TASKS_FROZEN) { =09case CPU_DOWN_PREPARE: -=09=09if (!cpumask_test_and_clear_cpu(cpu, &pmu->cpus)) +=09=09if (!cpumask_test_and_clear_cpu(cpu, &cci_pmu->cpus)) =09=09=09break; =09=09target =3D cpumask_any_but(cpu_online_mask, cpu); =09=09if (target < 0) // UP, last CPU @@ -845,7 +860,7 @@ static int cci_pmu_cpu_notifier(struct notifier_block *= self, =09=09 * TODO: migrate context once core races on event->ctx have =09=09 * been fixed. =09=09 */ -=09=09cpumask_set_cpu(target, &pmu->cpus); +=09=09cpumask_set_cpu(target, &cci_pmu->cpus); =09default: =09=09break; =09} @@ -853,15 +868,6 @@ static int cci_pmu_cpu_notifier(struct notifier_block = *self, =09return NOTIFY_OK; } =20 -static struct notifier_block cci_pmu_cpu_nb =3D { -=09.notifier_call=09=3D cci_pmu_cpu_notifier, -=09/* -=09 * to migrate uncore events, our notifier should be executed -=09 * before perf core's notifier. -=09 */ -=09.priority=09=3D CPU_PRI_PERF + 1, -}; - static struct cci_pmu_model cci_pmu_models[] =3D { =09[CCI_REV_R0] =3D { =09=09.name =3D "CCI_400", @@ -935,6 +941,7 @@ static bool is_duplicate_irq(int irq, int *irqs, int nr= _irqs) static int cci_pmu_probe(struct platform_device *pdev) { =09struct resource *res; +=09struct cci_pmu *cci_pmu; =09int i, ret, irq; =09const struct cci_pmu_model *model; =20 @@ -944,30 +951,30 @@ static int cci_pmu_probe(struct platform_device *pdev= ) =09=09return -ENODEV; =09} =20 -=09pmu =3D devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL); -=09if (!pmu) +=09cci_pmu =3D devm_kzalloc(&pdev->dev, sizeof(*cci_pmu), GFP_KERNEL); +=09if (!cci_pmu) =09=09return -ENOMEM; =20 -=09pmu->model =3D model; +=09cci_pmu->model =3D model; =09res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); -=09pmu->base =3D devm_ioremap_resource(&pdev->dev, res); -=09if (IS_ERR(pmu->base)) +=09cci_pmu->base =3D devm_ioremap_resource(&pdev->dev, res); +=09if (IS_ERR(cci_pmu->base)) =09=09return -ENOMEM; =20 =09/* =09 * CCI PMU has 5 overflow signals - one per counter; but some may be ti= ed =09 * together to a common interrupt. =09 */ -=09pmu->nr_irqs =3D 0; +=09cci_pmu->nr_irqs =3D 0; =09for (i =3D 0; i < CCI_PMU_MAX_HW_EVENTS; i++) { =09=09irq =3D platform_get_irq(pdev, i); =09=09if (irq < 0) =09=09=09break; =20 -=09=09if (is_duplicate_irq(irq, pmu->irqs, pmu->nr_irqs)) +=09=09if (is_duplicate_irq(irq, cci_pmu->irqs, cci_pmu->nr_irqs)) =09=09=09continue; =20 -=09=09pmu->irqs[pmu->nr_irqs++] =3D irq; +=09=09cci_pmu->irqs[cci_pmu->nr_irqs++] =3D irq; =09} =20 =09/* @@ -980,20 +987,31 @@ static int cci_pmu_probe(struct platform_device *pdev= ) =09=09return -EINVAL; =09} =20 -=09raw_spin_lock_init(&pmu->hw_events.pmu_lock); -=09mutex_init(&pmu->reserve_mutex); -=09atomic_set(&pmu->active_events, 0); -=09cpumask_set_cpu(smp_processor_id(), &pmu->cpus); +=09raw_spin_lock_init(&cci_pmu->hw_events.pmu_lock); +=09mutex_init(&cci_pmu->reserve_mutex); +=09atomic_set(&cci_pmu->active_events, 0); +=09cpumask_set_cpu(smp_processor_id(), &cci_pmu->cpus); =20 -=09ret =3D register_cpu_notifier(&cci_pmu_cpu_nb); +=09cci_pmu->cpu_nb =3D (struct notifier_block) { +=09=09.notifier_call=09=3D cci_pmu_cpu_notifier, +=09=09/* +=09=09 * to migrate uncore events, our notifier should be executed +=09=09 * before perf core's notifier. +=09=09 */ +=09=09.priority=09=3D CPU_PRI_PERF + 1, +=09}; + +=09ret =3D register_cpu_notifier(&cci_pmu->cpu_nb); =09if (ret) =09=09return ret; =20 -=09ret =3D cci_pmu_init(pmu, pdev); -=09if (ret) +=09ret =3D cci_pmu_init(cci_pmu, pdev); +=09if (ret) { +=09=09unregister_cpu_notifier(&cci_pmu->cpu_nb); =09=09return ret; +=09} =20 -=09pr_info("ARM %s PMU driver probed", pmu->model->name); +=09pr_info("ARM %s PMU driver probed", cci_pmu->model->name); =09return 0; } =20 --=20 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html From mboxrd@z Thu Jan 1 00:00:00 1970 From: suzuki.poulose@arm.com (Suzuki K. Poulose) Date: Tue, 5 May 2015 12:49:03 +0100 Subject: [PATCH 2/7] arm-cci: Cleanup PMU driver code In-Reply-To: <1430826548-29960-1-git-send-email-suzuki.poulose@arm.com> References: <1430826548-29960-1-git-send-email-suzuki.poulose@arm.com> Message-ID: <1430826548-29960-3-git-send-email-suzuki.poulose@arm.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org From: "Suzuki K. Poulose" This patch gets rid of the global struct cci_pmu variable and makes the code use the cci_pmu explicitly. Makes code a bit more robust and reader friendly. Cc: Punit Agrawal Cc: Mark Rutland Cc: Will Deacon Signed-off-by: Suzuki K. Poulose --- drivers/bus/arm-cci.c | 142 ++++++++++++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 62 deletions(-) diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index 941b831..27cc200 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c @@ -124,9 +124,9 @@ struct cci_pmu { int num_events; atomic_t active_events; struct mutex reserve_mutex; + struct notifier_block cpu_nb; cpumask_t cpus; }; -static struct cci_pmu *pmu; #define to_cci_pmu(c) (container_of(c, struct cci_pmu, pmu)) @@ -179,7 +179,7 @@ enum cci400_perf_events { #define CCI_REV_R1_MASTER_PORT_MIN_EV 0x00 #define CCI_REV_R1_MASTER_PORT_MAX_EV 0x11 -static int pmu_validate_hw_event(unsigned long hw_event) +static int pmu_validate_hw_event(struct cci_pmu *cci_pmu, unsigned long hw_event) { u8 ev_source = CCI_PMU_EVENT_SOURCE(hw_event); u8 ev_code = CCI_PMU_EVENT_CODE(hw_event); @@ -207,8 +207,8 @@ static int pmu_validate_hw_event(unsigned long hw_event) return -ENOENT; } - if (ev_code >= pmu->model->event_ranges[if_type].min && - ev_code <= pmu->model->event_ranges[if_type].max) + if (ev_code >= cci_pmu->model->event_ranges[if_type].min && + ev_code <= cci_pmu->model->event_ranges[if_type].max) return hw_event; return -ENOENT; @@ -239,29 +239,31 @@ static int pmu_is_valid_counter(struct cci_pmu *cci_pmu, int idx) idx <= CCI_PMU_CNTR_LAST(cci_pmu); } -static u32 pmu_read_register(int idx, unsigned int offset) +static u32 pmu_read_register(struct cci_pmu *cci_pmu, int idx, unsigned int offset) { - return readl_relaxed(pmu->base + CCI_PMU_CNTR_BASE(idx) + offset); + return readl_relaxed(cci_pmu->base + CCI_PMU_CNTR_BASE(idx) + offset); } -static void pmu_write_register(u32 value, int idx, unsigned int offset) +static void pmu_write_register(struct cci_pmu *cci_pmu, u32 value, + int idx, unsigned int offset) { - return writel_relaxed(value, pmu->base + CCI_PMU_CNTR_BASE(idx) + offset); + return writel_relaxed(value, cci_pmu->base + + CCI_PMU_CNTR_BASE(idx) + offset); } -static void pmu_disable_counter(int idx) +static void pmu_disable_counter(struct cci_pmu *cci_pmu, int idx) { - pmu_write_register(0, idx, CCI_PMU_CNTR_CTRL); + pmu_write_register(cci_pmu, 0, idx, CCI_PMU_CNTR_CTRL); } -static void pmu_enable_counter(int idx) +static void pmu_enable_counter(struct cci_pmu *cci_pmu, int idx) { - pmu_write_register(1, idx, CCI_PMU_CNTR_CTRL); + pmu_write_register(cci_pmu, 1, idx, CCI_PMU_CNTR_CTRL); } -static void pmu_set_event(int idx, unsigned long event) +static void pmu_set_event(struct cci_pmu *cci_pmu, int idx, unsigned long event) { - pmu_write_register(event, idx, CCI_PMU_EVT_SEL); + pmu_write_register(cci_pmu, event, idx, CCI_PMU_EVT_SEL); } static u32 pmu_get_max_counters(void) @@ -306,7 +308,8 @@ static int pmu_map_event(struct perf_event *event) if (config == CCI_PMU_CYCLES) mapping = config; else - mapping = pmu_validate_hw_event(config); + mapping = pmu_validate_hw_event(to_cci_pmu(event->pmu), + config); return mapping; } @@ -319,7 +322,7 @@ static int pmu_request_irq(struct cci_pmu *cci_pmu, irq_handler_t handler) if (unlikely(!pmu_device)) return -ENODEV; - if (pmu->nr_irqs < 1) { + if (cci_pmu->nr_irqs < 1) { dev_err(&pmu_device->dev, "no irqs for CCI PMUs defined\n"); return -ENODEV; } @@ -331,16 +334,16 @@ static int pmu_request_irq(struct cci_pmu *cci_pmu, irq_handler_t handler) * * This should allow handling of non-unique interrupt for the counters. */ - for (i = 0; i < pmu->nr_irqs; i++) { - int err = request_irq(pmu->irqs[i], handler, IRQF_SHARED, + for (i = 0; i < cci_pmu->nr_irqs; i++) { + int err = request_irq(cci_pmu->irqs[i], handler, IRQF_SHARED, "arm-cci-pmu", cci_pmu); if (err) { dev_err(&pmu_device->dev, "unable to request IRQ%d for ARM CCI PMU counters\n", - pmu->irqs[i]); + cci_pmu->irqs[i]); return err; } - set_bit(i, &pmu->active_irqs); + set_bit(i, &cci_pmu->active_irqs); } return 0; @@ -350,11 +353,11 @@ static void pmu_free_irq(struct cci_pmu *cci_pmu) { int i; - for (i = 0; i < pmu->nr_irqs; i++) { - if (!test_and_clear_bit(i, &pmu->active_irqs)) + for (i = 0; i < cci_pmu->nr_irqs; i++) { + if (!test_and_clear_bit(i, &cci_pmu->active_irqs)) continue; - free_irq(pmu->irqs[i], cci_pmu); + free_irq(cci_pmu->irqs[i], cci_pmu); } } @@ -369,7 +372,7 @@ static u32 pmu_read_counter(struct perf_event *event) dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx); return 0; } - value = pmu_read_register(idx, CCI_PMU_CNTR); + value = pmu_read_register(cci_pmu, idx, CCI_PMU_CNTR); return value; } @@ -383,7 +386,7 @@ static void pmu_write_counter(struct perf_event *event, u32 value) if (unlikely(!pmu_is_valid_counter(cci_pmu, idx))) dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx); else - pmu_write_register(value, idx, CCI_PMU_CNTR); + pmu_write_register(cci_pmu, value, idx, CCI_PMU_CNTR); } static u64 pmu_event_update(struct perf_event *event) @@ -427,7 +430,7 @@ static irqreturn_t pmu_handle_irq(int irq_num, void *dev) { unsigned long flags; struct cci_pmu *cci_pmu = dev; - struct cci_pmu_hw_events *events = &pmu->hw_events; + struct cci_pmu_hw_events *events = &cci_pmu->hw_events; int idx, handled = IRQ_NONE; raw_spin_lock_irqsave(&events->pmu_lock, flags); @@ -446,11 +449,12 @@ static irqreturn_t pmu_handle_irq(int irq_num, void *dev) hw_counter = &event->hw; /* Did this counter overflow? */ - if (!(pmu_read_register(idx, CCI_PMU_OVRFLW) & + if (!(pmu_read_register(cci_pmu, idx, CCI_PMU_OVRFLW) & CCI_PMU_OVRFLW_FLAG)) continue; - pmu_write_register(CCI_PMU_OVRFLW_FLAG, idx, CCI_PMU_OVRFLW); + pmu_write_register(cci_pmu, CCI_PMU_OVRFLW_FLAG, idx, + CCI_PMU_OVRFLW); pmu_event_update(event); pmu_event_set_period(event); @@ -549,10 +553,10 @@ static void cci_pmu_start(struct perf_event *event, int pmu_flags) /* Configure the event to count, unless you are counting cycles */ if (idx != CCI_PMU_CYCLE_CNTR_IDX) - pmu_set_event(idx, hwc->config_base); + pmu_set_event(cci_pmu, idx, hwc->config_base); pmu_event_set_period(event); - pmu_enable_counter(idx); + pmu_enable_counter(cci_pmu, idx); raw_spin_unlock_irqrestore(&hw_events->pmu_lock, flags); } @@ -575,7 +579,7 @@ static void cci_pmu_stop(struct perf_event *event, int pmu_flags) * We always reprogram the counter, so ignore PERF_EF_UPDATE. See * cci_pmu_start() */ - pmu_disable_counter(idx); + pmu_disable_counter(cci_pmu, idx); pmu_event_update(event); hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; } @@ -779,20 +783,27 @@ static int cci_pmu_event_init(struct perf_event *event) return err; } -static ssize_t pmu_attr_cpumask_show(struct device *dev, +static ssize_t pmu_cpumask_attr_show(struct device *dev, struct device_attribute *attr, char *buf) { + struct dev_ext_attribute *eattr = container_of(attr, + struct dev_ext_attribute, attr); + struct cci_pmu *cci_pmu = eattr->var; + int n = scnprintf(buf, PAGE_SIZE - 1, "%*pbl", - cpumask_pr_args(&pmu->cpus)); + cpumask_pr_args(&cci_pmu->cpus)); buf[n++] = '\n'; buf[n] = '\0'; return n; } -static DEVICE_ATTR(cpumask, S_IRUGO, pmu_attr_cpumask_show, NULL); +static struct dev_ext_attribute pmu_cpumask_attr = { + __ATTR(cpumask, S_IRUGO, pmu_cpumask_attr_show, NULL), + NULL, /* Populated in cci_pmu_init */ +}; static struct attribute *pmu_attrs[] = { - &dev_attr_cpumask.attr, + &pmu_cpumask_attr.attr.attr, NULL, }; @@ -808,6 +819,8 @@ static const struct attribute_group *pmu_attr_groups[] = { static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev) { char *name = cci_pmu->model->name; + + pmu_cpumask_attr.var = cci_pmu; cci_pmu->pmu = (struct pmu) { .name = cci_pmu->model->name, .task_ctx_nr = perf_invalid_context, @@ -831,12 +844,14 @@ static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev) static int cci_pmu_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) { + struct cci_pmu *cci_pmu = container_of(self, + struct cci_pmu, cpu_nb); unsigned int cpu = (long)hcpu; unsigned int target; switch (action & ~CPU_TASKS_FROZEN) { case CPU_DOWN_PREPARE: - if (!cpumask_test_and_clear_cpu(cpu, &pmu->cpus)) + if (!cpumask_test_and_clear_cpu(cpu, &cci_pmu->cpus)) break; target = cpumask_any_but(cpu_online_mask, cpu); if (target < 0) // UP, last CPU @@ -845,7 +860,7 @@ static int cci_pmu_cpu_notifier(struct notifier_block *self, * TODO: migrate context once core races on event->ctx have * been fixed. */ - cpumask_set_cpu(target, &pmu->cpus); + cpumask_set_cpu(target, &cci_pmu->cpus); default: break; } @@ -853,15 +868,6 @@ static int cci_pmu_cpu_notifier(struct notifier_block *self, return NOTIFY_OK; } -static struct notifier_block cci_pmu_cpu_nb = { - .notifier_call = cci_pmu_cpu_notifier, - /* - * to migrate uncore events, our notifier should be executed - * before perf core's notifier. - */ - .priority = CPU_PRI_PERF + 1, -}; - static struct cci_pmu_model cci_pmu_models[] = { [CCI_REV_R0] = { .name = "CCI_400", @@ -935,6 +941,7 @@ static bool is_duplicate_irq(int irq, int *irqs, int nr_irqs) static int cci_pmu_probe(struct platform_device *pdev) { struct resource *res; + struct cci_pmu *cci_pmu; int i, ret, irq; const struct cci_pmu_model *model; @@ -944,30 +951,30 @@ static int cci_pmu_probe(struct platform_device *pdev) return -ENODEV; } - pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL); - if (!pmu) + cci_pmu = devm_kzalloc(&pdev->dev, sizeof(*cci_pmu), GFP_KERNEL); + if (!cci_pmu) return -ENOMEM; - pmu->model = model; + cci_pmu->model = model; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pmu->base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(pmu->base)) + cci_pmu->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(cci_pmu->base)) return -ENOMEM; /* * CCI PMU has 5 overflow signals - one per counter; but some may be tied * together to a common interrupt. */ - pmu->nr_irqs = 0; + cci_pmu->nr_irqs = 0; for (i = 0; i < CCI_PMU_MAX_HW_EVENTS; i++) { irq = platform_get_irq(pdev, i); if (irq < 0) break; - if (is_duplicate_irq(irq, pmu->irqs, pmu->nr_irqs)) + if (is_duplicate_irq(irq, cci_pmu->irqs, cci_pmu->nr_irqs)) continue; - pmu->irqs[pmu->nr_irqs++] = irq; + cci_pmu->irqs[cci_pmu->nr_irqs++] = irq; } /* @@ -980,20 +987,31 @@ static int cci_pmu_probe(struct platform_device *pdev) return -EINVAL; } - raw_spin_lock_init(&pmu->hw_events.pmu_lock); - mutex_init(&pmu->reserve_mutex); - atomic_set(&pmu->active_events, 0); - cpumask_set_cpu(smp_processor_id(), &pmu->cpus); + raw_spin_lock_init(&cci_pmu->hw_events.pmu_lock); + mutex_init(&cci_pmu->reserve_mutex); + atomic_set(&cci_pmu->active_events, 0); + cpumask_set_cpu(smp_processor_id(), &cci_pmu->cpus); - ret = register_cpu_notifier(&cci_pmu_cpu_nb); + cci_pmu->cpu_nb = (struct notifier_block) { + .notifier_call = cci_pmu_cpu_notifier, + /* + * to migrate uncore events, our notifier should be executed + * before perf core's notifier. + */ + .priority = CPU_PRI_PERF + 1, + }; + + ret = register_cpu_notifier(&cci_pmu->cpu_nb); if (ret) return ret; - ret = cci_pmu_init(pmu, pdev); - if (ret) + ret = cci_pmu_init(cci_pmu, pdev); + if (ret) { + unregister_cpu_notifier(&cci_pmu->cpu_nb); return ret; + } - pr_info("ARM %s PMU driver probed", pmu->model->name); + pr_info("ARM %s PMU driver probed", cci_pmu->model->name); return 0; } -- 1.7.9.5