diff options
Diffstat (limited to 'drivers/hwtracing/ptt/hisi_ptt.c')
| -rw-r--r-- | drivers/hwtracing/ptt/hisi_ptt.c | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c index ba081b6d2435..3090479a2979 100644 --- a/drivers/hwtracing/ptt/hisi_ptt.c +++ b/drivers/hwtracing/ptt/hisi_ptt.c @@ -183,6 +183,10 @@ static void hisi_ptt_wait_dma_reset_done(struct hisi_ptt *hisi_ptt) static void hisi_ptt_trace_end(struct hisi_ptt *hisi_ptt) { writel(0, hisi_ptt->iobase + HISI_PTT_TRACE_CTRL); + + /* Mask the interrupt on the end */ + writel(HISI_PTT_TRACE_INT_MASK_ALL, hisi_ptt->iobase + HISI_PTT_TRACE_INT_MASK); + hisi_ptt->trace_ctrl.started = false; } @@ -270,15 +274,14 @@ static int hisi_ptt_update_aux(struct hisi_ptt *hisi_ptt, int index, bool stop) buf->pos += size; /* - * Just commit the traced data if we're going to stop. Otherwise if the - * resident AUX buffer cannot contain the data of next trace buffer, - * apply a new one. + * Always commit the data to the AUX buffer in time to make sure + * userspace got enough time to consume the data. + * + * If we're not going to stop, apply a new one and check whether + * there's enough room for the next trace. */ - if (stop) { - perf_aux_output_end(handle, buf->pos); - } else if (buf->length - buf->pos < HISI_PTT_TRACE_BUF_SIZE) { - perf_aux_output_end(handle, buf->pos); - + perf_aux_output_end(handle, size); + if (!stop) { buf = perf_aux_output_begin(handle, event); if (!buf) return -EINVAL; @@ -342,9 +345,9 @@ static int hisi_ptt_register_irq(struct hisi_ptt *hisi_ptt) return ret; hisi_ptt->trace_irq = pci_irq_vector(pdev, HISI_PTT_TRACE_DMA_IRQ); - ret = devm_request_threaded_irq(&pdev->dev, hisi_ptt->trace_irq, - NULL, hisi_ptt_isr, 0, - DRV_NAME, hisi_ptt); + ret = devm_request_irq(&pdev->dev, hisi_ptt->trace_irq, hisi_ptt_isr, + IRQF_NOBALANCING | IRQF_NO_THREAD, DRV_NAME, + hisi_ptt); if (ret) { pci_err(pdev, "failed to request irq %d, ret = %d\n", hisi_ptt->trace_irq, ret); @@ -618,13 +621,13 @@ static int hisi_ptt_notifier_call(struct notifier_block *nb, unsigned long actio if (!root_port) return 0; - port_devid = PCI_DEVID(root_port->bus->number, root_port->devfn); + port_devid = pci_dev_id(root_port); if (port_devid < hisi_ptt->lower_bdf || port_devid > hisi_ptt->upper_bdf) return 0; info.is_port = pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT; - info.devid = PCI_DEVID(pdev->bus->number, pdev->devfn); + info.devid = pci_dev_id(pdev); switch (action) { case BUS_NOTIFY_ADD_DEVICE: @@ -664,7 +667,7 @@ static int hisi_ptt_init_filters(struct pci_dev *pdev, void *data) if (!root_port) return 0; - port_devid = PCI_DEVID(root_port->bus->number, root_port->devfn); + port_devid = pci_dev_id(root_port); if (port_devid < hisi_ptt->lower_bdf || port_devid > hisi_ptt->upper_bdf) return 0; @@ -674,7 +677,7 @@ static int hisi_ptt_init_filters(struct pci_dev *pdev, void *data) * should be partial initialized and users would know which filter fails * through the log. Other functions of PTT device are still available. */ - filter = hisi_ptt_alloc_add_filter(hisi_ptt, PCI_DEVID(pdev->bus->number, pdev->devfn), + filter = hisi_ptt_alloc_add_filter(hisi_ptt, pci_dev_id(pdev), pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT); if (!filter) return -ENOMEM; @@ -995,13 +998,16 @@ static int hisi_ptt_pmu_event_init(struct perf_event *event) int ret; u32 val; + if (event->attr.type != hisi_ptt->hisi_ptt_pmu.type) + return -ENOENT; + if (event->cpu < 0) { dev_dbg(event->pmu->dev, "Per-task mode not supported\n"); return -EOPNOTSUPP; } - if (event->attr.type != hisi_ptt->hisi_ptt_pmu.type) - return -ENOENT; + if (event->attach_state & PERF_ATTACH_TASK) + return -EOPNOTSUPP; ret = hisi_ptt_trace_valid_filter(hisi_ptt, event->attr.config); if (ret < 0) @@ -1178,6 +1184,10 @@ static void hisi_ptt_pmu_del(struct perf_event *event, int flags) hisi_ptt_pmu_stop(event, PERF_EF_UPDATE); } +static void hisi_ptt_pmu_read(struct perf_event *event) +{ +} + static void hisi_ptt_remove_cpuhp_instance(void *hotplug_node) { cpuhp_state_remove_instance_nocalls(hisi_ptt_pmu_online, hotplug_node); @@ -1211,6 +1221,7 @@ static int hisi_ptt_register_pmu(struct hisi_ptt *hisi_ptt) hisi_ptt->hisi_ptt_pmu = (struct pmu) { .module = THIS_MODULE, + .parent = &hisi_ptt->pdev->dev, .capabilities = PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_NO_EXCLUDE, .task_ctx_nr = perf_sw_context, .attr_groups = hisi_ptt_pmu_groups, @@ -1221,6 +1232,7 @@ static int hisi_ptt_register_pmu(struct hisi_ptt *hisi_ptt) .stop = hisi_ptt_pmu_stop, .add = hisi_ptt_pmu_add, .del = hisi_ptt_pmu_del, + .read = hisi_ptt_pmu_read, }; reg = readl(hisi_ptt->iobase + HISI_PTT_LOCATION); |
