1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for HiSilicon PCIe tune and trace device
5 * Copyright (c) 2022 HiSilicon Technologies Co., Ltd.
6 * Author: Yicong Yang <yangyicong@hisilicon.com>
9 #include <linux/bitfield.h>
10 #include <linux/bitops.h>
11 #include <linux/cpuhotplug.h>
12 #include <linux/delay.h>
13 #include <linux/dma-mapping.h>
14 #include <linux/interrupt.h>
16 #include <linux/iommu.h>
17 #include <linux/iopoll.h>
18 #include <linux/module.h>
19 #include <linux/sysfs.h>
20 #include <linux/vmalloc.h>
24 /* Dynamic CPU hotplug state used by PTT */
25 static enum cpuhp_state hisi_ptt_pmu_online
;
27 static bool hisi_ptt_wait_tuning_finish(struct hisi_ptt
*hisi_ptt
)
31 return !readl_poll_timeout(hisi_ptt
->iobase
+ HISI_PTT_TUNING_INT_STAT
,
32 val
, !(val
& HISI_PTT_TUNING_INT_STAT_MASK
),
33 HISI_PTT_WAIT_POLL_INTERVAL_US
,
34 HISI_PTT_WAIT_TUNE_TIMEOUT_US
);
37 static ssize_t
hisi_ptt_tune_attr_show(struct device
*dev
,
38 struct device_attribute
*attr
,
41 struct hisi_ptt
*hisi_ptt
= to_hisi_ptt(dev_get_drvdata(dev
));
42 struct dev_ext_attribute
*ext_attr
;
43 struct hisi_ptt_tune_desc
*desc
;
47 ext_attr
= container_of(attr
, struct dev_ext_attribute
, attr
);
50 mutex_lock(&hisi_ptt
->tune_lock
);
52 reg
= readl(hisi_ptt
->iobase
+ HISI_PTT_TUNING_CTRL
);
53 reg
&= ~(HISI_PTT_TUNING_CTRL_CODE
| HISI_PTT_TUNING_CTRL_SUB
);
54 reg
|= FIELD_PREP(HISI_PTT_TUNING_CTRL_CODE
| HISI_PTT_TUNING_CTRL_SUB
,
56 writel(reg
, hisi_ptt
->iobase
+ HISI_PTT_TUNING_CTRL
);
58 /* Write all 1 to indicates it's the read process */
59 writel(~0U, hisi_ptt
->iobase
+ HISI_PTT_TUNING_DATA
);
61 if (!hisi_ptt_wait_tuning_finish(hisi_ptt
)) {
62 mutex_unlock(&hisi_ptt
->tune_lock
);
66 reg
= readl(hisi_ptt
->iobase
+ HISI_PTT_TUNING_DATA
);
67 reg
&= HISI_PTT_TUNING_DATA_VAL_MASK
;
68 val
= FIELD_GET(HISI_PTT_TUNING_DATA_VAL_MASK
, reg
);
70 mutex_unlock(&hisi_ptt
->tune_lock
);
71 return sysfs_emit(buf
, "%u\n", val
);
74 static ssize_t
hisi_ptt_tune_attr_store(struct device
*dev
,
75 struct device_attribute
*attr
,
76 const char *buf
, size_t count
)
78 struct hisi_ptt
*hisi_ptt
= to_hisi_ptt(dev_get_drvdata(dev
));
79 struct dev_ext_attribute
*ext_attr
;
80 struct hisi_ptt_tune_desc
*desc
;
84 ext_attr
= container_of(attr
, struct dev_ext_attribute
, attr
);
87 if (kstrtou16(buf
, 10, &val
))
90 mutex_lock(&hisi_ptt
->tune_lock
);
92 reg
= readl(hisi_ptt
->iobase
+ HISI_PTT_TUNING_CTRL
);
93 reg
&= ~(HISI_PTT_TUNING_CTRL_CODE
| HISI_PTT_TUNING_CTRL_SUB
);
94 reg
|= FIELD_PREP(HISI_PTT_TUNING_CTRL_CODE
| HISI_PTT_TUNING_CTRL_SUB
,
96 writel(reg
, hisi_ptt
->iobase
+ HISI_PTT_TUNING_CTRL
);
97 writel(FIELD_PREP(HISI_PTT_TUNING_DATA_VAL_MASK
, val
),
98 hisi_ptt
->iobase
+ HISI_PTT_TUNING_DATA
);
100 if (!hisi_ptt_wait_tuning_finish(hisi_ptt
)) {
101 mutex_unlock(&hisi_ptt
->tune_lock
);
105 mutex_unlock(&hisi_ptt
->tune_lock
);
109 #define HISI_PTT_TUNE_ATTR(_name, _val, _show, _store) \
110 static struct hisi_ptt_tune_desc _name##_desc = { \
112 .event_code = (_val), \
114 static struct dev_ext_attribute hisi_ptt_##_name##_attr = { \
115 .attr = __ATTR(_name, 0600, _show, _store), \
116 .var = &_name##_desc, \
119 #define HISI_PTT_TUNE_ATTR_COMMON(_name, _val) \
120 HISI_PTT_TUNE_ATTR(_name, _val, \
121 hisi_ptt_tune_attr_show, \
122 hisi_ptt_tune_attr_store)
125 * The value of the tuning event are composed of two parts: main event code
126 * in BIT[0,15] and subevent code in BIT[16,23]. For example, qox_tx_cpl is
127 * a subevent of 'Tx path QoS control' which for tuning the weight of Tx
128 * completion TLPs. See hisi_ptt.rst documentation for more information.
130 #define HISI_PTT_TUNE_QOS_TX_CPL (0x4 | (3 << 16))
131 #define HISI_PTT_TUNE_QOS_TX_NP (0x4 | (4 << 16))
132 #define HISI_PTT_TUNE_QOS_TX_P (0x4 | (5 << 16))
133 #define HISI_PTT_TUNE_RX_ALLOC_BUF_LEVEL (0x5 | (6 << 16))
134 #define HISI_PTT_TUNE_TX_ALLOC_BUF_LEVEL (0x5 | (7 << 16))
136 HISI_PTT_TUNE_ATTR_COMMON(qos_tx_cpl
, HISI_PTT_TUNE_QOS_TX_CPL
);
137 HISI_PTT_TUNE_ATTR_COMMON(qos_tx_np
, HISI_PTT_TUNE_QOS_TX_NP
);
138 HISI_PTT_TUNE_ATTR_COMMON(qos_tx_p
, HISI_PTT_TUNE_QOS_TX_P
);
139 HISI_PTT_TUNE_ATTR_COMMON(rx_alloc_buf_level
, HISI_PTT_TUNE_RX_ALLOC_BUF_LEVEL
);
140 HISI_PTT_TUNE_ATTR_COMMON(tx_alloc_buf_level
, HISI_PTT_TUNE_TX_ALLOC_BUF_LEVEL
);
142 static struct attribute
*hisi_ptt_tune_attrs
[] = {
143 &hisi_ptt_qos_tx_cpl_attr
.attr
.attr
,
144 &hisi_ptt_qos_tx_np_attr
.attr
.attr
,
145 &hisi_ptt_qos_tx_p_attr
.attr
.attr
,
146 &hisi_ptt_rx_alloc_buf_level_attr
.attr
.attr
,
147 &hisi_ptt_tx_alloc_buf_level_attr
.attr
.attr
,
151 static struct attribute_group hisi_ptt_tune_group
= {
153 .attrs
= hisi_ptt_tune_attrs
,
156 static u16
hisi_ptt_get_filter_val(u16 devid
, bool is_port
)
159 return BIT(HISI_PCIE_CORE_PORT_ID(devid
& 0xff));
164 static bool hisi_ptt_wait_trace_hw_idle(struct hisi_ptt
*hisi_ptt
)
168 return !readl_poll_timeout_atomic(hisi_ptt
->iobase
+ HISI_PTT_TRACE_STS
,
169 val
, val
& HISI_PTT_TRACE_IDLE
,
170 HISI_PTT_WAIT_POLL_INTERVAL_US
,
171 HISI_PTT_WAIT_TRACE_TIMEOUT_US
);
174 static void hisi_ptt_wait_dma_reset_done(struct hisi_ptt
*hisi_ptt
)
178 readl_poll_timeout_atomic(hisi_ptt
->iobase
+ HISI_PTT_TRACE_WR_STS
,
179 val
, !val
, HISI_PTT_RESET_POLL_INTERVAL_US
,
180 HISI_PTT_RESET_TIMEOUT_US
);
183 static void hisi_ptt_trace_end(struct hisi_ptt
*hisi_ptt
)
185 writel(0, hisi_ptt
->iobase
+ HISI_PTT_TRACE_CTRL
);
187 /* Mask the interrupt on the end */
188 writel(HISI_PTT_TRACE_INT_MASK_ALL
, hisi_ptt
->iobase
+ HISI_PTT_TRACE_INT_MASK
);
190 hisi_ptt
->trace_ctrl
.started
= false;
193 static int hisi_ptt_trace_start(struct hisi_ptt
*hisi_ptt
)
195 struct hisi_ptt_trace_ctrl
*ctrl
= &hisi_ptt
->trace_ctrl
;
199 /* Check device idle before start trace */
200 if (!hisi_ptt_wait_trace_hw_idle(hisi_ptt
)) {
201 pci_err(hisi_ptt
->pdev
, "Failed to start trace, the device is still busy\n");
205 ctrl
->started
= true;
207 /* Reset the DMA before start tracing */
208 val
= readl(hisi_ptt
->iobase
+ HISI_PTT_TRACE_CTRL
);
209 val
|= HISI_PTT_TRACE_CTRL_RST
;
210 writel(val
, hisi_ptt
->iobase
+ HISI_PTT_TRACE_CTRL
);
212 hisi_ptt_wait_dma_reset_done(hisi_ptt
);
214 val
= readl(hisi_ptt
->iobase
+ HISI_PTT_TRACE_CTRL
);
215 val
&= ~HISI_PTT_TRACE_CTRL_RST
;
216 writel(val
, hisi_ptt
->iobase
+ HISI_PTT_TRACE_CTRL
);
218 /* Reset the index of current buffer */
219 hisi_ptt
->trace_ctrl
.buf_index
= 0;
221 /* Zero the trace buffers */
222 for (i
= 0; i
< HISI_PTT_TRACE_BUF_CNT
; i
++)
223 memset(ctrl
->trace_buf
[i
].addr
, 0, HISI_PTT_TRACE_BUF_SIZE
);
225 /* Clear the interrupt status */
226 writel(HISI_PTT_TRACE_INT_STAT_MASK
, hisi_ptt
->iobase
+ HISI_PTT_TRACE_INT_STAT
);
227 writel(0, hisi_ptt
->iobase
+ HISI_PTT_TRACE_INT_MASK
);
229 /* Set the trace control register */
230 val
= FIELD_PREP(HISI_PTT_TRACE_CTRL_TYPE_SEL
, ctrl
->type
);
231 val
|= FIELD_PREP(HISI_PTT_TRACE_CTRL_RXTX_SEL
, ctrl
->direction
);
232 val
|= FIELD_PREP(HISI_PTT_TRACE_CTRL_DATA_FORMAT
, ctrl
->format
);
233 val
|= FIELD_PREP(HISI_PTT_TRACE_CTRL_TARGET_SEL
, hisi_ptt
->trace_ctrl
.filter
);
234 if (!hisi_ptt
->trace_ctrl
.is_port
)
235 val
|= HISI_PTT_TRACE_CTRL_FILTER_MODE
;
237 /* Start the Trace */
238 val
|= HISI_PTT_TRACE_CTRL_EN
;
239 writel(val
, hisi_ptt
->iobase
+ HISI_PTT_TRACE_CTRL
);
244 static int hisi_ptt_update_aux(struct hisi_ptt
*hisi_ptt
, int index
, bool stop
)
246 struct hisi_ptt_trace_ctrl
*ctrl
= &hisi_ptt
->trace_ctrl
;
247 struct perf_output_handle
*handle
= &ctrl
->handle
;
248 struct perf_event
*event
= handle
->event
;
249 struct hisi_ptt_pmu_buf
*buf
;
253 buf
= perf_get_aux(handle
);
254 if (!buf
|| !handle
->size
)
257 addr
= ctrl
->trace_buf
[ctrl
->buf_index
].addr
;
260 * If we're going to stop, read the size of already traced data from
261 * HISI_PTT_TRACE_WR_STS. Otherwise we're coming from the interrupt,
262 * the data size is always HISI_PTT_TRACE_BUF_SIZE.
267 reg
= readl(hisi_ptt
->iobase
+ HISI_PTT_TRACE_WR_STS
);
268 size
= FIELD_GET(HISI_PTT_TRACE_WR_STS_WRITE
, reg
);
270 size
= HISI_PTT_TRACE_BUF_SIZE
;
273 memcpy(buf
->base
+ buf
->pos
, addr
, size
);
277 * Always commit the data to the AUX buffer in time to make sure
278 * userspace got enough time to consume the data.
280 * If we're not going to stop, apply a new one and check whether
281 * there's enough room for the next trace.
283 perf_aux_output_end(handle
, size
);
285 buf
= perf_aux_output_begin(handle
, event
);
289 buf
->pos
= handle
->head
% buf
->length
;
290 if (buf
->length
- buf
->pos
< HISI_PTT_TRACE_BUF_SIZE
) {
291 perf_aux_output_end(handle
, 0);
299 static irqreturn_t
hisi_ptt_isr(int irq
, void *context
)
301 struct hisi_ptt
*hisi_ptt
= context
;
304 status
= readl(hisi_ptt
->iobase
+ HISI_PTT_TRACE_INT_STAT
);
305 if (!(status
& HISI_PTT_TRACE_INT_STAT_MASK
))
308 buf_idx
= ffs(status
) - 1;
310 /* Clear the interrupt status of buffer @buf_idx */
311 writel(status
, hisi_ptt
->iobase
+ HISI_PTT_TRACE_INT_STAT
);
314 * Update the AUX buffer and cache the current buffer index,
315 * as we need to know this and save the data when the trace
316 * is ended out of the interrupt handler. End the trace
317 * if the updating fails.
319 if (hisi_ptt_update_aux(hisi_ptt
, buf_idx
, false))
320 hisi_ptt_trace_end(hisi_ptt
);
322 hisi_ptt
->trace_ctrl
.buf_index
= (buf_idx
+ 1) % HISI_PTT_TRACE_BUF_CNT
;
327 static void hisi_ptt_irq_free_vectors(void *pdev
)
329 pci_free_irq_vectors(pdev
);
332 static int hisi_ptt_register_irq(struct hisi_ptt
*hisi_ptt
)
334 struct pci_dev
*pdev
= hisi_ptt
->pdev
;
337 ret
= pci_alloc_irq_vectors(pdev
, 1, 1, PCI_IRQ_MSI
);
339 pci_err(pdev
, "failed to allocate irq vector, ret = %d\n", ret
);
343 ret
= devm_add_action_or_reset(&pdev
->dev
, hisi_ptt_irq_free_vectors
, pdev
);
347 hisi_ptt
->trace_irq
= pci_irq_vector(pdev
, HISI_PTT_TRACE_DMA_IRQ
);
348 ret
= devm_request_irq(&pdev
->dev
, hisi_ptt
->trace_irq
, hisi_ptt_isr
,
349 IRQF_NOBALANCING
| IRQF_NO_THREAD
, DRV_NAME
,
352 pci_err(pdev
, "failed to request irq %d, ret = %d\n",
353 hisi_ptt
->trace_irq
, ret
);
360 static void hisi_ptt_del_free_filter(struct hisi_ptt
*hisi_ptt
,
361 struct hisi_ptt_filter_desc
*filter
)
364 hisi_ptt
->port_mask
&= ~hisi_ptt_get_filter_val(filter
->devid
, true);
366 list_del(&filter
->list
);
371 static struct hisi_ptt_filter_desc
*
372 hisi_ptt_alloc_add_filter(struct hisi_ptt
*hisi_ptt
, u16 devid
, bool is_port
)
374 struct hisi_ptt_filter_desc
*filter
;
375 u8 devfn
= devid
& 0xff;
378 filter_name
= kasprintf(GFP_KERNEL
, "%04x:%02x:%02x.%d", pci_domain_nr(hisi_ptt
->pdev
->bus
),
379 PCI_BUS_NUM(devid
), PCI_SLOT(devfn
), PCI_FUNC(devfn
));
381 pci_err(hisi_ptt
->pdev
, "failed to allocate name for filter %04x:%02x:%02x.%d\n",
382 pci_domain_nr(hisi_ptt
->pdev
->bus
), PCI_BUS_NUM(devid
),
383 PCI_SLOT(devfn
), PCI_FUNC(devfn
));
387 filter
= kzalloc(sizeof(*filter
), GFP_KERNEL
);
389 pci_err(hisi_ptt
->pdev
, "failed to add filter for %s\n",
395 filter
->name
= filter_name
;
396 filter
->is_port
= is_port
;
397 filter
->devid
= devid
;
399 if (filter
->is_port
) {
400 list_add_tail(&filter
->list
, &hisi_ptt
->port_filters
);
402 /* Update the available port mask */
403 hisi_ptt
->port_mask
|= hisi_ptt_get_filter_val(filter
->devid
, true);
405 list_add_tail(&filter
->list
, &hisi_ptt
->req_filters
);
411 static ssize_t
hisi_ptt_filter_show(struct device
*dev
, struct device_attribute
*attr
,
414 struct hisi_ptt_filter_desc
*filter
;
415 unsigned long filter_val
;
417 filter
= container_of(attr
, struct hisi_ptt_filter_desc
, attr
);
418 filter_val
= hisi_ptt_get_filter_val(filter
->devid
, filter
->is_port
) |
419 (filter
->is_port
? HISI_PTT_PMU_FILTER_IS_PORT
: 0);
421 return sysfs_emit(buf
, "0x%05lx\n", filter_val
);
424 static int hisi_ptt_create_rp_filter_attr(struct hisi_ptt
*hisi_ptt
,
425 struct hisi_ptt_filter_desc
*filter
)
427 struct kobject
*kobj
= &hisi_ptt
->hisi_ptt_pmu
.dev
->kobj
;
429 sysfs_attr_init(&filter
->attr
.attr
);
430 filter
->attr
.attr
.name
= filter
->name
;
431 filter
->attr
.attr
.mode
= 0400; /* DEVICE_ATTR_ADMIN_RO */
432 filter
->attr
.show
= hisi_ptt_filter_show
;
434 return sysfs_add_file_to_group(kobj
, &filter
->attr
.attr
,
435 HISI_PTT_RP_FILTERS_GRP_NAME
);
438 static void hisi_ptt_remove_rp_filter_attr(struct hisi_ptt
*hisi_ptt
,
439 struct hisi_ptt_filter_desc
*filter
)
441 struct kobject
*kobj
= &hisi_ptt
->hisi_ptt_pmu
.dev
->kobj
;
443 sysfs_remove_file_from_group(kobj
, &filter
->attr
.attr
,
444 HISI_PTT_RP_FILTERS_GRP_NAME
);
447 static int hisi_ptt_create_req_filter_attr(struct hisi_ptt
*hisi_ptt
,
448 struct hisi_ptt_filter_desc
*filter
)
450 struct kobject
*kobj
= &hisi_ptt
->hisi_ptt_pmu
.dev
->kobj
;
452 sysfs_attr_init(&filter
->attr
.attr
);
453 filter
->attr
.attr
.name
= filter
->name
;
454 filter
->attr
.attr
.mode
= 0400; /* DEVICE_ATTR_ADMIN_RO */
455 filter
->attr
.show
= hisi_ptt_filter_show
;
457 return sysfs_add_file_to_group(kobj
, &filter
->attr
.attr
,
458 HISI_PTT_REQ_FILTERS_GRP_NAME
);
461 static void hisi_ptt_remove_req_filter_attr(struct hisi_ptt
*hisi_ptt
,
462 struct hisi_ptt_filter_desc
*filter
)
464 struct kobject
*kobj
= &hisi_ptt
->hisi_ptt_pmu
.dev
->kobj
;
466 sysfs_remove_file_from_group(kobj
, &filter
->attr
.attr
,
467 HISI_PTT_REQ_FILTERS_GRP_NAME
);
470 static int hisi_ptt_create_filter_attr(struct hisi_ptt
*hisi_ptt
,
471 struct hisi_ptt_filter_desc
*filter
)
476 ret
= hisi_ptt_create_rp_filter_attr(hisi_ptt
, filter
);
478 ret
= hisi_ptt_create_req_filter_attr(hisi_ptt
, filter
);
481 pci_err(hisi_ptt
->pdev
, "failed to create sysfs attribute for filter %s\n",
487 static void hisi_ptt_remove_filter_attr(struct hisi_ptt
*hisi_ptt
,
488 struct hisi_ptt_filter_desc
*filter
)
491 hisi_ptt_remove_rp_filter_attr(hisi_ptt
, filter
);
493 hisi_ptt_remove_req_filter_attr(hisi_ptt
, filter
);
496 static void hisi_ptt_remove_all_filter_attributes(void *data
)
498 struct hisi_ptt_filter_desc
*filter
;
499 struct hisi_ptt
*hisi_ptt
= data
;
501 mutex_lock(&hisi_ptt
->filter_lock
);
503 list_for_each_entry(filter
, &hisi_ptt
->req_filters
, list
)
504 hisi_ptt_remove_filter_attr(hisi_ptt
, filter
);
506 list_for_each_entry(filter
, &hisi_ptt
->port_filters
, list
)
507 hisi_ptt_remove_filter_attr(hisi_ptt
, filter
);
509 hisi_ptt
->sysfs_inited
= false;
510 mutex_unlock(&hisi_ptt
->filter_lock
);
513 static int hisi_ptt_init_filter_attributes(struct hisi_ptt
*hisi_ptt
)
515 struct hisi_ptt_filter_desc
*filter
;
518 mutex_lock(&hisi_ptt
->filter_lock
);
521 * Register the reset callback in the first stage. In reset we traverse
522 * the filters list to remove the sysfs attributes so the callback can
523 * be called safely even without below filter attributes creation.
525 ret
= devm_add_action(&hisi_ptt
->pdev
->dev
,
526 hisi_ptt_remove_all_filter_attributes
,
531 list_for_each_entry(filter
, &hisi_ptt
->port_filters
, list
) {
532 ret
= hisi_ptt_create_filter_attr(hisi_ptt
, filter
);
537 list_for_each_entry(filter
, &hisi_ptt
->req_filters
, list
) {
538 ret
= hisi_ptt_create_filter_attr(hisi_ptt
, filter
);
543 hisi_ptt
->sysfs_inited
= true;
545 mutex_unlock(&hisi_ptt
->filter_lock
);
549 static void hisi_ptt_update_filters(struct work_struct
*work
)
551 struct delayed_work
*delayed_work
= to_delayed_work(work
);
552 struct hisi_ptt_filter_update_info info
;
553 struct hisi_ptt_filter_desc
*filter
;
554 struct hisi_ptt
*hisi_ptt
;
556 hisi_ptt
= container_of(delayed_work
, struct hisi_ptt
, work
);
558 if (!mutex_trylock(&hisi_ptt
->filter_lock
)) {
559 schedule_delayed_work(&hisi_ptt
->work
, HISI_PTT_WORK_DELAY_MS
);
563 while (kfifo_get(&hisi_ptt
->filter_update_kfifo
, &info
)) {
566 * Notify the users if failed to add this filter, others
567 * still work and available. See the comments in
568 * hisi_ptt_init_filters().
570 filter
= hisi_ptt_alloc_add_filter(hisi_ptt
, info
.devid
, info
.is_port
);
575 * If filters' sysfs entries hasn't been initialized,
576 * then we're still at probe stage. Add the filters to
577 * the list and later hisi_ptt_init_filter_attributes()
578 * will create sysfs attributes for all the filters.
580 if (hisi_ptt
->sysfs_inited
&&
581 hisi_ptt_create_filter_attr(hisi_ptt
, filter
)) {
582 hisi_ptt_del_free_filter(hisi_ptt
, filter
);
586 struct hisi_ptt_filter_desc
*tmp
;
587 struct list_head
*target_list
;
589 target_list
= info
.is_port
? &hisi_ptt
->port_filters
:
590 &hisi_ptt
->req_filters
;
592 list_for_each_entry_safe(filter
, tmp
, target_list
, list
)
593 if (filter
->devid
== info
.devid
) {
594 if (hisi_ptt
->sysfs_inited
)
595 hisi_ptt_remove_filter_attr(hisi_ptt
, filter
);
597 hisi_ptt_del_free_filter(hisi_ptt
, filter
);
603 mutex_unlock(&hisi_ptt
->filter_lock
);
607 * A PCI bus notifier is used here for dynamically updating the filter
610 static int hisi_ptt_notifier_call(struct notifier_block
*nb
, unsigned long action
,
613 struct hisi_ptt
*hisi_ptt
= container_of(nb
, struct hisi_ptt
, hisi_ptt_nb
);
614 struct hisi_ptt_filter_update_info info
;
615 struct pci_dev
*pdev
, *root_port
;
616 struct device
*dev
= data
;
619 pdev
= to_pci_dev(dev
);
620 root_port
= pcie_find_root_port(pdev
);
624 port_devid
= pci_dev_id(root_port
);
625 if (port_devid
< hisi_ptt
->lower_bdf
||
626 port_devid
> hisi_ptt
->upper_bdf
)
629 info
.is_port
= pci_pcie_type(pdev
) == PCI_EXP_TYPE_ROOT_PORT
;
630 info
.devid
= pci_dev_id(pdev
);
633 case BUS_NOTIFY_ADD_DEVICE
:
636 case BUS_NOTIFY_DEL_DEVICE
:
644 * The FIFO size is 16 which is sufficient for almost all the cases,
645 * since each PCIe core will have most 8 Root Ports (typically only
646 * 1~4 Root Ports). On failure log the failed filter and let user
649 if (kfifo_in_spinlocked(&hisi_ptt
->filter_update_kfifo
, &info
, 1,
650 &hisi_ptt
->filter_update_lock
))
651 schedule_delayed_work(&hisi_ptt
->work
, 0);
653 pci_warn(hisi_ptt
->pdev
,
654 "filter update fifo overflow for target %s\n",
660 static int hisi_ptt_init_filters(struct pci_dev
*pdev
, void *data
)
662 struct pci_dev
*root_port
= pcie_find_root_port(pdev
);
663 struct hisi_ptt_filter_desc
*filter
;
664 struct hisi_ptt
*hisi_ptt
= data
;
670 port_devid
= pci_dev_id(root_port
);
671 if (port_devid
< hisi_ptt
->lower_bdf
||
672 port_devid
> hisi_ptt
->upper_bdf
)
676 * We won't fail the probe if filter allocation failed here. The filters
677 * should be partial initialized and users would know which filter fails
678 * through the log. Other functions of PTT device are still available.
680 filter
= hisi_ptt_alloc_add_filter(hisi_ptt
, pci_dev_id(pdev
),
681 pci_pcie_type(pdev
) == PCI_EXP_TYPE_ROOT_PORT
);
688 static void hisi_ptt_release_filters(void *data
)
690 struct hisi_ptt_filter_desc
*filter
, *tmp
;
691 struct hisi_ptt
*hisi_ptt
= data
;
693 list_for_each_entry_safe(filter
, tmp
, &hisi_ptt
->req_filters
, list
)
694 hisi_ptt_del_free_filter(hisi_ptt
, filter
);
696 list_for_each_entry_safe(filter
, tmp
, &hisi_ptt
->port_filters
, list
)
697 hisi_ptt_del_free_filter(hisi_ptt
, filter
);
700 static int hisi_ptt_config_trace_buf(struct hisi_ptt
*hisi_ptt
)
702 struct hisi_ptt_trace_ctrl
*ctrl
= &hisi_ptt
->trace_ctrl
;
703 struct device
*dev
= &hisi_ptt
->pdev
->dev
;
706 ctrl
->trace_buf
= devm_kcalloc(dev
, HISI_PTT_TRACE_BUF_CNT
,
707 sizeof(*ctrl
->trace_buf
), GFP_KERNEL
);
708 if (!ctrl
->trace_buf
)
711 for (i
= 0; i
< HISI_PTT_TRACE_BUF_CNT
; ++i
) {
712 ctrl
->trace_buf
[i
].addr
= dmam_alloc_coherent(dev
, HISI_PTT_TRACE_BUF_SIZE
,
713 &ctrl
->trace_buf
[i
].dma
,
715 if (!ctrl
->trace_buf
[i
].addr
)
719 /* Configure the trace DMA buffer */
720 for (i
= 0; i
< HISI_PTT_TRACE_BUF_CNT
; i
++) {
721 writel(lower_32_bits(ctrl
->trace_buf
[i
].dma
),
722 hisi_ptt
->iobase
+ HISI_PTT_TRACE_ADDR_BASE_LO_0
+
723 i
* HISI_PTT_TRACE_ADDR_STRIDE
);
724 writel(upper_32_bits(ctrl
->trace_buf
[i
].dma
),
725 hisi_ptt
->iobase
+ HISI_PTT_TRACE_ADDR_BASE_HI_0
+
726 i
* HISI_PTT_TRACE_ADDR_STRIDE
);
728 writel(HISI_PTT_TRACE_BUF_SIZE
, hisi_ptt
->iobase
+ HISI_PTT_TRACE_ADDR_SIZE
);
733 static int hisi_ptt_init_ctrls(struct hisi_ptt
*hisi_ptt
)
735 struct pci_dev
*pdev
= hisi_ptt
->pdev
;
740 INIT_DELAYED_WORK(&hisi_ptt
->work
, hisi_ptt_update_filters
);
741 INIT_KFIFO(hisi_ptt
->filter_update_kfifo
);
742 spin_lock_init(&hisi_ptt
->filter_update_lock
);
744 INIT_LIST_HEAD(&hisi_ptt
->port_filters
);
745 INIT_LIST_HEAD(&hisi_ptt
->req_filters
);
746 mutex_init(&hisi_ptt
->filter_lock
);
748 ret
= hisi_ptt_config_trace_buf(hisi_ptt
);
753 * The device range register provides the information about the root
754 * ports which the RCiEP can control and trace. The RCiEP and the root
755 * ports which it supports are on the same PCIe core, with same domain
756 * number but maybe different bus number. The device range register
757 * will tell us which root ports we can support, Bit[31:16] indicates
758 * the upper BDF numbers of the root port, while Bit[15:0] indicates
761 reg
= readl(hisi_ptt
->iobase
+ HISI_PTT_DEVICE_RANGE
);
762 hisi_ptt
->upper_bdf
= FIELD_GET(HISI_PTT_DEVICE_RANGE_UPPER
, reg
);
763 hisi_ptt
->lower_bdf
= FIELD_GET(HISI_PTT_DEVICE_RANGE_LOWER
, reg
);
765 bus
= pci_find_bus(pci_domain_nr(pdev
->bus
), PCI_BUS_NUM(hisi_ptt
->upper_bdf
));
767 pci_walk_bus(bus
, hisi_ptt_init_filters
, hisi_ptt
);
769 ret
= devm_add_action_or_reset(&pdev
->dev
, hisi_ptt_release_filters
, hisi_ptt
);
773 hisi_ptt
->trace_ctrl
.on_cpu
= -1;
777 static ssize_t
cpumask_show(struct device
*dev
, struct device_attribute
*attr
,
780 struct hisi_ptt
*hisi_ptt
= to_hisi_ptt(dev_get_drvdata(dev
));
781 const cpumask_t
*cpumask
= cpumask_of_node(dev_to_node(&hisi_ptt
->pdev
->dev
));
783 return cpumap_print_to_pagebuf(true, buf
, cpumask
);
785 static DEVICE_ATTR_RO(cpumask
);
787 static struct attribute
*hisi_ptt_cpumask_attrs
[] = {
788 &dev_attr_cpumask
.attr
,
792 static const struct attribute_group hisi_ptt_cpumask_attr_group
= {
793 .attrs
= hisi_ptt_cpumask_attrs
,
797 * Bit 19 indicates the filter type, 1 for Root Port filter and 0 for Requester
798 * filter. Bit[15:0] indicates the filter value, for Root Port filter it's
799 * a bit mask of desired ports and for Requester filter it's the Requester ID
800 * of the desired PCIe function. Bit[18:16] is reserved for extension.
802 * See hisi_ptt.rst documentation for detailed information.
804 PMU_FORMAT_ATTR(filter
, "config:0-19");
805 PMU_FORMAT_ATTR(direction
, "config:20-23");
806 PMU_FORMAT_ATTR(type
, "config:24-31");
807 PMU_FORMAT_ATTR(format
, "config:32-35");
809 static struct attribute
*hisi_ptt_pmu_format_attrs
[] = {
810 &format_attr_filter
.attr
,
811 &format_attr_direction
.attr
,
812 &format_attr_type
.attr
,
813 &format_attr_format
.attr
,
817 static struct attribute_group hisi_ptt_pmu_format_group
= {
819 .attrs
= hisi_ptt_pmu_format_attrs
,
822 static ssize_t
hisi_ptt_filter_multiselect_show(struct device
*dev
,
823 struct device_attribute
*attr
,
826 struct dev_ext_attribute
*ext_attr
;
828 ext_attr
= container_of(attr
, struct dev_ext_attribute
, attr
);
829 return sysfs_emit(buf
, "%s\n", (char *)ext_attr
->var
);
832 static struct dev_ext_attribute root_port_filters_multiselect
= {
834 .attr
= { .name
= "multiselect", .mode
= 0400 },
835 .show
= hisi_ptt_filter_multiselect_show
,
840 static struct attribute
*hisi_ptt_pmu_root_ports_attrs
[] = {
841 &root_port_filters_multiselect
.attr
.attr
,
845 static struct attribute_group hisi_ptt_pmu_root_ports_group
= {
846 .name
= HISI_PTT_RP_FILTERS_GRP_NAME
,
847 .attrs
= hisi_ptt_pmu_root_ports_attrs
,
850 static struct dev_ext_attribute requester_filters_multiselect
= {
852 .attr
= { .name
= "multiselect", .mode
= 0400 },
853 .show
= hisi_ptt_filter_multiselect_show
,
858 static struct attribute
*hisi_ptt_pmu_requesters_attrs
[] = {
859 &requester_filters_multiselect
.attr
.attr
,
863 static struct attribute_group hisi_ptt_pmu_requesters_group
= {
864 .name
= HISI_PTT_REQ_FILTERS_GRP_NAME
,
865 .attrs
= hisi_ptt_pmu_requesters_attrs
,
868 static const struct attribute_group
*hisi_ptt_pmu_groups
[] = {
869 &hisi_ptt_cpumask_attr_group
,
870 &hisi_ptt_pmu_format_group
,
871 &hisi_ptt_tune_group
,
872 &hisi_ptt_pmu_root_ports_group
,
873 &hisi_ptt_pmu_requesters_group
,
877 static int hisi_ptt_trace_valid_direction(u32 val
)
880 * The direction values have different effects according to the data
881 * format (specified in the parentheses). TLP set A/B means different
882 * set of TLP types. See hisi_ptt.rst documentation for more details.
884 static const u32 hisi_ptt_trace_available_direction
[] = {
885 0, /* inbound(4DW) or reserved(8DW) */
886 1, /* outbound(4DW) */
887 2, /* {in, out}bound(4DW) or inbound(8DW), TLP set A */
888 3, /* {in, out}bound(4DW) or inbound(8DW), TLP set B */
892 for (i
= 0; i
< ARRAY_SIZE(hisi_ptt_trace_available_direction
); i
++) {
893 if (val
== hisi_ptt_trace_available_direction
[i
])
900 static int hisi_ptt_trace_valid_type(u32 val
)
902 /* Different types can be set simultaneously */
903 static const u32 hisi_ptt_trace_available_type
[] = {
904 1, /* posted_request */
905 2, /* non-posted_request */
914 * Walk the available list and clear the valid bits of
915 * the config. If there is any resident bit after the
916 * walk then the config is invalid.
918 for (i
= 0; i
< ARRAY_SIZE(hisi_ptt_trace_available_type
); i
++)
919 val
&= ~hisi_ptt_trace_available_type
[i
];
927 static int hisi_ptt_trace_valid_format(u32 val
)
929 static const u32 hisi_ptt_trace_availble_format
[] = {
935 for (i
= 0; i
< ARRAY_SIZE(hisi_ptt_trace_availble_format
); i
++) {
936 if (val
== hisi_ptt_trace_availble_format
[i
])
943 static int hisi_ptt_trace_valid_filter(struct hisi_ptt
*hisi_ptt
, u64 config
)
945 unsigned long val
, port_mask
= hisi_ptt
->port_mask
;
946 struct hisi_ptt_filter_desc
*filter
;
949 hisi_ptt
->trace_ctrl
.is_port
= FIELD_GET(HISI_PTT_PMU_FILTER_IS_PORT
, config
);
950 val
= FIELD_GET(HISI_PTT_PMU_FILTER_VAL_MASK
, config
);
953 * Port filters are defined as bit mask. For port filters, check
954 * the bits in the @val are within the range of hisi_ptt->port_mask
955 * and whether it's empty or not, otherwise user has specified
956 * some unsupported root ports.
958 * For Requester ID filters, walk the available filter list to see
959 * whether we have one matched.
961 mutex_lock(&hisi_ptt
->filter_lock
);
962 if (!hisi_ptt
->trace_ctrl
.is_port
) {
963 list_for_each_entry(filter
, &hisi_ptt
->req_filters
, list
) {
964 if (val
== hisi_ptt_get_filter_val(filter
->devid
, filter
->is_port
))
967 } else if (bitmap_subset(&val
, &port_mask
, BITS_PER_LONG
)) {
973 mutex_unlock(&hisi_ptt
->filter_lock
);
977 static void hisi_ptt_pmu_init_configs(struct hisi_ptt
*hisi_ptt
, struct perf_event
*event
)
979 struct hisi_ptt_trace_ctrl
*ctrl
= &hisi_ptt
->trace_ctrl
;
982 val
= FIELD_GET(HISI_PTT_PMU_FILTER_VAL_MASK
, event
->attr
.config
);
983 hisi_ptt
->trace_ctrl
.filter
= val
;
985 val
= FIELD_GET(HISI_PTT_PMU_DIRECTION_MASK
, event
->attr
.config
);
986 ctrl
->direction
= val
;
988 val
= FIELD_GET(HISI_PTT_PMU_TYPE_MASK
, event
->attr
.config
);
991 val
= FIELD_GET(HISI_PTT_PMU_FORMAT_MASK
, event
->attr
.config
);
995 static int hisi_ptt_pmu_event_init(struct perf_event
*event
)
997 struct hisi_ptt
*hisi_ptt
= to_hisi_ptt(event
->pmu
);
1001 if (event
->attr
.type
!= hisi_ptt
->hisi_ptt_pmu
.type
)
1004 if (event
->cpu
< 0) {
1005 dev_dbg(event
->pmu
->dev
, "Per-task mode not supported\n");
1009 if (event
->attach_state
& PERF_ATTACH_TASK
)
1012 ret
= hisi_ptt_trace_valid_filter(hisi_ptt
, event
->attr
.config
);
1016 val
= FIELD_GET(HISI_PTT_PMU_DIRECTION_MASK
, event
->attr
.config
);
1017 ret
= hisi_ptt_trace_valid_direction(val
);
1021 val
= FIELD_GET(HISI_PTT_PMU_TYPE_MASK
, event
->attr
.config
);
1022 ret
= hisi_ptt_trace_valid_type(val
);
1026 val
= FIELD_GET(HISI_PTT_PMU_FORMAT_MASK
, event
->attr
.config
);
1027 return hisi_ptt_trace_valid_format(val
);
1030 static void *hisi_ptt_pmu_setup_aux(struct perf_event
*event
, void **pages
,
1031 int nr_pages
, bool overwrite
)
1033 struct hisi_ptt_pmu_buf
*buf
;
1034 struct page
**pagelist
;
1038 dev_warn(event
->pmu
->dev
, "Overwrite mode is not supported\n");
1042 /* If the pages size less than buffers, we cannot start trace */
1043 if (nr_pages
< HISI_PTT_TRACE_TOTAL_BUF_SIZE
/ PAGE_SIZE
)
1046 buf
= kzalloc(sizeof(*buf
), GFP_KERNEL
);
1050 pagelist
= kcalloc(nr_pages
, sizeof(*pagelist
), GFP_KERNEL
);
1054 for (i
= 0; i
< nr_pages
; i
++)
1055 pagelist
[i
] = virt_to_page(pages
[i
]);
1057 buf
->base
= vmap(pagelist
, nr_pages
, VM_MAP
, PAGE_KERNEL
);
1063 buf
->nr_pages
= nr_pages
;
1064 buf
->length
= nr_pages
* PAGE_SIZE
;
1074 static void hisi_ptt_pmu_free_aux(void *aux
)
1076 struct hisi_ptt_pmu_buf
*buf
= aux
;
1082 static void hisi_ptt_pmu_start(struct perf_event
*event
, int flags
)
1084 struct hisi_ptt
*hisi_ptt
= to_hisi_ptt(event
->pmu
);
1085 struct perf_output_handle
*handle
= &hisi_ptt
->trace_ctrl
.handle
;
1086 struct hw_perf_event
*hwc
= &event
->hw
;
1087 struct device
*dev
= event
->pmu
->dev
;
1088 struct hisi_ptt_pmu_buf
*buf
;
1089 int cpu
= event
->cpu
;
1094 /* Serialize the perf process if user specified several CPUs */
1095 spin_lock(&hisi_ptt
->pmu_lock
);
1096 if (hisi_ptt
->trace_ctrl
.started
) {
1097 dev_dbg(dev
, "trace has already started\n");
1102 * Handle the interrupt on the same cpu which starts the trace to avoid
1103 * context mismatch. Otherwise we'll trigger the WARN from the perf
1104 * core in event_function_local(). If CPU passed is offline we'll fail
1105 * here, just log it since we can do nothing here.
1107 ret
= irq_set_affinity(hisi_ptt
->trace_irq
, cpumask_of(cpu
));
1109 dev_warn(dev
, "failed to set the affinity of trace interrupt\n");
1111 hisi_ptt
->trace_ctrl
.on_cpu
= cpu
;
1113 buf
= perf_aux_output_begin(handle
, event
);
1115 dev_dbg(dev
, "aux output begin failed\n");
1119 buf
->pos
= handle
->head
% buf
->length
;
1121 hisi_ptt_pmu_init_configs(hisi_ptt
, event
);
1123 ret
= hisi_ptt_trace_start(hisi_ptt
);
1125 dev_dbg(dev
, "trace start failed, ret = %d\n", ret
);
1126 perf_aux_output_end(handle
, 0);
1130 spin_unlock(&hisi_ptt
->pmu_lock
);
1133 event
->hw
.state
|= PERF_HES_STOPPED
;
1134 spin_unlock(&hisi_ptt
->pmu_lock
);
1137 static void hisi_ptt_pmu_stop(struct perf_event
*event
, int flags
)
1139 struct hisi_ptt
*hisi_ptt
= to_hisi_ptt(event
->pmu
);
1140 struct hw_perf_event
*hwc
= &event
->hw
;
1142 if (hwc
->state
& PERF_HES_STOPPED
)
1145 spin_lock(&hisi_ptt
->pmu_lock
);
1146 if (hisi_ptt
->trace_ctrl
.started
) {
1147 hisi_ptt_trace_end(hisi_ptt
);
1149 if (!hisi_ptt_wait_trace_hw_idle(hisi_ptt
))
1150 dev_warn(event
->pmu
->dev
, "Device is still busy\n");
1152 hisi_ptt_update_aux(hisi_ptt
, hisi_ptt
->trace_ctrl
.buf_index
, true);
1154 spin_unlock(&hisi_ptt
->pmu_lock
);
1156 hwc
->state
|= PERF_HES_STOPPED
;
1157 perf_event_update_userpage(event
);
1158 hwc
->state
|= PERF_HES_UPTODATE
;
1161 static int hisi_ptt_pmu_add(struct perf_event
*event
, int flags
)
1163 struct hisi_ptt
*hisi_ptt
= to_hisi_ptt(event
->pmu
);
1164 struct hw_perf_event
*hwc
= &event
->hw
;
1165 int cpu
= event
->cpu
;
1167 /* Only allow the cpus on the device's node to add the event */
1168 if (!cpumask_test_cpu(cpu
, cpumask_of_node(dev_to_node(&hisi_ptt
->pdev
->dev
))))
1171 hwc
->state
= PERF_HES_STOPPED
| PERF_HES_UPTODATE
;
1173 if (flags
& PERF_EF_START
) {
1174 hisi_ptt_pmu_start(event
, PERF_EF_RELOAD
);
1175 if (hwc
->state
& PERF_HES_STOPPED
)
1182 static void hisi_ptt_pmu_del(struct perf_event
*event
, int flags
)
1184 hisi_ptt_pmu_stop(event
, PERF_EF_UPDATE
);
1187 static void hisi_ptt_pmu_read(struct perf_event
*event
)
1191 static void hisi_ptt_remove_cpuhp_instance(void *hotplug_node
)
1193 cpuhp_state_remove_instance_nocalls(hisi_ptt_pmu_online
, hotplug_node
);
1196 static void hisi_ptt_unregister_pmu(void *pmu
)
1198 perf_pmu_unregister(pmu
);
1201 static int hisi_ptt_register_pmu(struct hisi_ptt
*hisi_ptt
)
1203 u16 core_id
, sicl_id
;
1208 ret
= cpuhp_state_add_instance_nocalls(hisi_ptt_pmu_online
,
1209 &hisi_ptt
->hotplug_node
);
1213 ret
= devm_add_action_or_reset(&hisi_ptt
->pdev
->dev
,
1214 hisi_ptt_remove_cpuhp_instance
,
1215 &hisi_ptt
->hotplug_node
);
1219 mutex_init(&hisi_ptt
->tune_lock
);
1220 spin_lock_init(&hisi_ptt
->pmu_lock
);
1222 hisi_ptt
->hisi_ptt_pmu
= (struct pmu
) {
1223 .module
= THIS_MODULE
,
1224 .parent
= &hisi_ptt
->pdev
->dev
,
1225 .capabilities
= PERF_PMU_CAP_EXCLUSIVE
| PERF_PMU_CAP_NO_EXCLUDE
,
1226 .task_ctx_nr
= perf_sw_context
,
1227 .attr_groups
= hisi_ptt_pmu_groups
,
1228 .event_init
= hisi_ptt_pmu_event_init
,
1229 .setup_aux
= hisi_ptt_pmu_setup_aux
,
1230 .free_aux
= hisi_ptt_pmu_free_aux
,
1231 .start
= hisi_ptt_pmu_start
,
1232 .stop
= hisi_ptt_pmu_stop
,
1233 .add
= hisi_ptt_pmu_add
,
1234 .del
= hisi_ptt_pmu_del
,
1235 .read
= hisi_ptt_pmu_read
,
1238 reg
= readl(hisi_ptt
->iobase
+ HISI_PTT_LOCATION
);
1239 core_id
= FIELD_GET(HISI_PTT_CORE_ID
, reg
);
1240 sicl_id
= FIELD_GET(HISI_PTT_SICL_ID
, reg
);
1242 pmu_name
= devm_kasprintf(&hisi_ptt
->pdev
->dev
, GFP_KERNEL
, "hisi_ptt%u_%u",
1247 ret
= perf_pmu_register(&hisi_ptt
->hisi_ptt_pmu
, pmu_name
, -1);
1251 return devm_add_action_or_reset(&hisi_ptt
->pdev
->dev
,
1252 hisi_ptt_unregister_pmu
,
1253 &hisi_ptt
->hisi_ptt_pmu
);
1256 static void hisi_ptt_unregister_filter_update_notifier(void *data
)
1258 struct hisi_ptt
*hisi_ptt
= data
;
1260 bus_unregister_notifier(&pci_bus_type
, &hisi_ptt
->hisi_ptt_nb
);
1262 /* Cancel any work that has been queued */
1263 cancel_delayed_work_sync(&hisi_ptt
->work
);
1266 /* Register the bus notifier for dynamically updating the filter list */
1267 static int hisi_ptt_register_filter_update_notifier(struct hisi_ptt
*hisi_ptt
)
1271 hisi_ptt
->hisi_ptt_nb
.notifier_call
= hisi_ptt_notifier_call
;
1272 ret
= bus_register_notifier(&pci_bus_type
, &hisi_ptt
->hisi_ptt_nb
);
1276 return devm_add_action_or_reset(&hisi_ptt
->pdev
->dev
,
1277 hisi_ptt_unregister_filter_update_notifier
,
1282 * The DMA of PTT trace can only use direct mappings due to some
1283 * hardware restriction. Check whether there is no IOMMU or the
1284 * policy of the IOMMU domain is passthrough, otherwise the trace
1287 * The PTT device is supposed to behind an ARM SMMUv3, which
1288 * should have passthrough the device by a quirk.
1290 static int hisi_ptt_check_iommu_mapping(struct pci_dev
*pdev
)
1292 struct iommu_domain
*iommu_domain
;
1294 iommu_domain
= iommu_get_domain_for_dev(&pdev
->dev
);
1295 if (!iommu_domain
|| iommu_domain
->type
== IOMMU_DOMAIN_IDENTITY
)
1301 static int hisi_ptt_probe(struct pci_dev
*pdev
,
1302 const struct pci_device_id
*id
)
1304 struct hisi_ptt
*hisi_ptt
;
1307 ret
= hisi_ptt_check_iommu_mapping(pdev
);
1309 pci_err(pdev
, "requires direct DMA mappings\n");
1313 hisi_ptt
= devm_kzalloc(&pdev
->dev
, sizeof(*hisi_ptt
), GFP_KERNEL
);
1317 hisi_ptt
->pdev
= pdev
;
1318 pci_set_drvdata(pdev
, hisi_ptt
);
1320 ret
= pcim_enable_device(pdev
);
1322 pci_err(pdev
, "failed to enable device, ret = %d\n", ret
);
1326 ret
= pcim_iomap_regions(pdev
, BIT(2), DRV_NAME
);
1328 pci_err(pdev
, "failed to remap io memory, ret = %d\n", ret
);
1332 hisi_ptt
->iobase
= pcim_iomap_table(pdev
)[2];
1334 ret
= dma_set_coherent_mask(&pdev
->dev
, DMA_BIT_MASK(64));
1336 pci_err(pdev
, "failed to set 64 bit dma mask, ret = %d\n", ret
);
1340 pci_set_master(pdev
);
1342 ret
= hisi_ptt_register_irq(hisi_ptt
);
1346 ret
= hisi_ptt_init_ctrls(hisi_ptt
);
1348 pci_err(pdev
, "failed to init controls, ret = %d\n", ret
);
1352 ret
= hisi_ptt_register_filter_update_notifier(hisi_ptt
);
1354 pci_warn(pdev
, "failed to register filter update notifier, ret = %d", ret
);
1356 ret
= hisi_ptt_register_pmu(hisi_ptt
);
1358 pci_err(pdev
, "failed to register PMU device, ret = %d", ret
);
1362 ret
= hisi_ptt_init_filter_attributes(hisi_ptt
);
1364 pci_err(pdev
, "failed to init sysfs filter attributes, ret = %d", ret
);
1371 static const struct pci_device_id hisi_ptt_id_tbl
[] = {
1372 { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI
, 0xa12e) },
1375 MODULE_DEVICE_TABLE(pci
, hisi_ptt_id_tbl
);
1377 static struct pci_driver hisi_ptt_driver
= {
1379 .id_table
= hisi_ptt_id_tbl
,
1380 .probe
= hisi_ptt_probe
,
1383 static int hisi_ptt_cpu_teardown(unsigned int cpu
, struct hlist_node
*node
)
1385 struct hisi_ptt
*hisi_ptt
;
1389 hisi_ptt
= hlist_entry_safe(node
, struct hisi_ptt
, hotplug_node
);
1390 src
= hisi_ptt
->trace_ctrl
.on_cpu
;
1391 dev
= hisi_ptt
->hisi_ptt_pmu
.dev
;
1393 if (!hisi_ptt
->trace_ctrl
.started
|| src
!= cpu
)
1396 target
= cpumask_any_but(cpumask_of_node(dev_to_node(&hisi_ptt
->pdev
->dev
)), cpu
);
1397 if (target
>= nr_cpu_ids
) {
1398 dev_err(dev
, "no available cpu for perf context migration\n");
1402 perf_pmu_migrate_context(&hisi_ptt
->hisi_ptt_pmu
, src
, target
);
1405 * Also make sure the interrupt bind to the migrated CPU as well. Warn
1406 * the user on failure here.
1408 if (irq_set_affinity(hisi_ptt
->trace_irq
, cpumask_of(target
)))
1409 dev_warn(dev
, "failed to set the affinity of trace interrupt\n");
1411 hisi_ptt
->trace_ctrl
.on_cpu
= target
;
1415 static int __init
hisi_ptt_init(void)
1419 ret
= cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN
, DRV_NAME
, NULL
,
1420 hisi_ptt_cpu_teardown
);
1423 hisi_ptt_pmu_online
= ret
;
1425 ret
= pci_register_driver(&hisi_ptt_driver
);
1427 cpuhp_remove_multi_state(hisi_ptt_pmu_online
);
1431 module_init(hisi_ptt_init
);
1433 static void __exit
hisi_ptt_exit(void)
1435 pci_unregister_driver(&hisi_ptt_driver
);
1436 cpuhp_remove_multi_state(hisi_ptt_pmu_online
);
1438 module_exit(hisi_ptt_exit
);
1440 MODULE_LICENSE("GPL");
1441 MODULE_AUTHOR("Yicong Yang <yangyicong@hisilicon.com>");
1442 MODULE_DESCRIPTION("Driver for HiSilicon PCIe tune and trace device");