aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/perf_event_mipsxx.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-14 16:05:21 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-14 16:05:21 -0500
commit4964e0664c80680fa6b28ef91381c076a5b25c2c (patch)
tree62099c5aaeee7274bcc66bcfba35d479affa97cf /arch/mips/kernel/perf_event_mipsxx.c
parent0a80939b3e6af4b0dc93bf88ec02fd7e90a16f1b (diff)
parent7bf6612e8a9d6a0b3b82e8e2611942be1258b307 (diff)
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (119 commits) MIPS: Delete unused function add_temporary_entry. MIPS: Set default pci cache line size. MIPS: Flush huge TLB MIPS: Octeon: Remove SYS_SUPPORTS_HIGHMEM. MIPS: Octeon: Add support for OCTEON II PCIe MIPS: Octeon: Update PCI Latency timer and enable more error reporting. MIPS: Alchemy: Update cpu-feature-overrides MIPS: Alchemy: db1200: Improve PB1200 detection. MIPS: Alchemy: merge Au1000 and Au1300-style IRQ controller code. MIPS: Alchemy: chain IRQ controllers to MIPS IRQ controller MIPS: Alchemy: irq: register pm at irq init time MIPS: Alchemy: Touchscreen support on DB1100 MIPS: Alchemy: Hook up IrDA on DB1000/DB1100 net/irda: convert au1k_ir to platform driver. MIPS: Alchemy: remove unused board headers MTD: nand: make au1550nd.c a platform_driver MIPS: Netlogic: Mark Netlogic chips as SMT capable MIPS: Netlogic: Add support for XLP 3XX cores MIPS: Netlogic: Merge some of XLR/XLP wakup code MIPS: Netlogic: Add default XLP config. ... Fix up trivial conflicts in arch/mips/kernel/{perf_event_mipsxx.c, traps.c} and drivers/tty/serial/Makefile
Diffstat (limited to 'arch/mips/kernel/perf_event_mipsxx.c')
-rw-r--r--arch/mips/kernel/perf_event_mipsxx.c72
1 files changed, 11 insertions, 61 deletions
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
index 315fc0b250f8..e3b897acfbc0 100644
--- a/arch/mips/kernel/perf_event_mipsxx.c
+++ b/arch/mips/kernel/perf_event_mipsxx.c
@@ -621,11 +621,6 @@ static int mipspmu_event_init(struct perf_event *event)
621 return -ENODEV; 621 return -ENODEV;
622 622
623 if (!atomic_inc_not_zero(&active_events)) { 623 if (!atomic_inc_not_zero(&active_events)) {
624 if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) {
625 atomic_dec(&active_events);
626 return -EINVAL;
627 }
628
629 mutex_lock(&pmu_reserve_mutex); 624 mutex_lock(&pmu_reserve_mutex);
630 if (atomic_read(&active_events) == 0) 625 if (atomic_read(&active_events) == 0)
631 err = mipspmu_get_irq(); 626 err = mipspmu_get_irq();
@@ -638,11 +633,7 @@ static int mipspmu_event_init(struct perf_event *event)
638 if (err) 633 if (err)
639 return err; 634 return err;
640 635
641 err = __hw_perf_event_init(event); 636 return __hw_perf_event_init(event);
642 if (err)
643 hw_perf_event_destroy(event);
644
645 return err;
646} 637}
647 638
648static struct pmu pmu = { 639static struct pmu pmu = {
@@ -712,18 +703,6 @@ static const struct mips_perf_event *mipspmu_map_cache_event(u64 config)
712 703
713} 704}
714 705
715static int validate_event(struct cpu_hw_events *cpuc,
716 struct perf_event *event)
717{
718 struct hw_perf_event fake_hwc = event->hw;
719
720 /* Allow mixed event group. So return 1 to pass validation. */
721 if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF)
722 return 1;
723
724 return mipsxx_pmu_alloc_counter(cpuc, &fake_hwc) >= 0;
725}
726
727static int validate_group(struct perf_event *event) 706static int validate_group(struct perf_event *event)
728{ 707{
729 struct perf_event *sibling, *leader = event->group_leader; 708 struct perf_event *sibling, *leader = event->group_leader;
@@ -731,15 +710,15 @@ static int validate_group(struct perf_event *event)
731 710
732 memset(&fake_cpuc, 0, sizeof(fake_cpuc)); 711 memset(&fake_cpuc, 0, sizeof(fake_cpuc));
733 712
734 if (!validate_event(&fake_cpuc, leader)) 713 if (mipsxx_pmu_alloc_counter(&fake_cpuc, &leader->hw) < 0)
735 return -EINVAL; 714 return -EINVAL;
736 715
737 list_for_each_entry(sibling, &leader->sibling_list, group_entry) { 716 list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
738 if (!validate_event(&fake_cpuc, sibling)) 717 if (mipsxx_pmu_alloc_counter(&fake_cpuc, &sibling->hw) < 0)
739 return -EINVAL; 718 return -EINVAL;
740 } 719 }
741 720
742 if (!validate_event(&fake_cpuc, event)) 721 if (mipsxx_pmu_alloc_counter(&fake_cpuc, &event->hw) < 0)
743 return -EINVAL; 722 return -EINVAL;
744 723
745 return 0; 724 return 0;
@@ -1279,13 +1258,14 @@ static int __hw_perf_event_init(struct perf_event *event)
1279 } 1258 }
1280 1259
1281 err = 0; 1260 err = 0;
1282 if (event->group_leader != event) { 1261 if (event->group_leader != event)
1283 err = validate_group(event); 1262 err = validate_group(event);
1284 if (err)
1285 return -EINVAL;
1286 }
1287 1263
1288 event->destroy = hw_perf_event_destroy; 1264 event->destroy = hw_perf_event_destroy;
1265
1266 if (err)
1267 event->destroy(event);
1268
1289 return err; 1269 return err;
1290} 1270}
1291 1271
@@ -1380,20 +1360,10 @@ static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev)
1380} 1360}
1381 1361
1382/* 24K */ 1362/* 24K */
1383#define IS_UNSUPPORTED_24K_EVENT(r, b) \
1384 ((b) == 12 || (r) == 151 || (r) == 152 || (b) == 26 || \
1385 (b) == 27 || (r) == 28 || (r) == 158 || (b) == 31 || \
1386 (b) == 32 || (b) == 34 || (b) == 36 || (r) == 168 || \
1387 (r) == 172 || (b) == 47 || ((b) >= 56 && (b) <= 63) || \
1388 ((b) >= 68 && (b) <= 127))
1389#define IS_BOTH_COUNTERS_24K_EVENT(b) \ 1363#define IS_BOTH_COUNTERS_24K_EVENT(b) \
1390 ((b) == 0 || (b) == 1 || (b) == 11) 1364 ((b) == 0 || (b) == 1 || (b) == 11)
1391 1365
1392/* 34K */ 1366/* 34K */
1393#define IS_UNSUPPORTED_34K_EVENT(r, b) \
1394 ((b) == 12 || (r) == 27 || (r) == 158 || (b) == 36 || \
1395 (b) == 38 || (r) == 175 || ((b) >= 56 && (b) <= 63) || \
1396 ((b) >= 68 && (b) <= 127))
1397#define IS_BOTH_COUNTERS_34K_EVENT(b) \ 1367#define IS_BOTH_COUNTERS_34K_EVENT(b) \
1398 ((b) == 0 || (b) == 1 || (b) == 11) 1368 ((b) == 0 || (b) == 1 || (b) == 11)
1399#ifdef CONFIG_MIPS_MT_SMP 1369#ifdef CONFIG_MIPS_MT_SMP
@@ -1406,20 +1376,10 @@ static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev)
1406#endif 1376#endif
1407 1377
1408/* 74K */ 1378/* 74K */
1409#define IS_UNSUPPORTED_74K_EVENT(r, b) \
1410 ((r) == 5 || ((r) >= 135 && (r) <= 137) || \
1411 ((b) >= 10 && (b) <= 12) || (b) == 22 || (b) == 27 || \
1412 (b) == 33 || (b) == 34 || ((b) >= 47 && (b) <= 49) || \
1413 (r) == 178 || (b) == 55 || (b) == 57 || (b) == 60 || \
1414 (b) == 61 || (r) == 62 || (r) == 191 || \
1415 ((b) >= 64 && (b) <= 127))
1416#define IS_BOTH_COUNTERS_74K_EVENT(b) \ 1379#define IS_BOTH_COUNTERS_74K_EVENT(b) \
1417 ((b) == 0 || (b) == 1) 1380 ((b) == 0 || (b) == 1)
1418 1381
1419/* 1004K */ 1382/* 1004K */
1420#define IS_UNSUPPORTED_1004K_EVENT(r, b) \
1421 ((b) == 12 || (r) == 27 || (r) == 158 || (b) == 38 || \
1422 (r) == 175 || (b) == 63 || ((b) >= 68 && (b) <= 127))
1423#define IS_BOTH_COUNTERS_1004K_EVENT(b) \ 1383#define IS_BOTH_COUNTERS_1004K_EVENT(b) \
1424 ((b) == 0 || (b) == 1 || (b) == 11) 1384 ((b) == 0 || (b) == 1 || (b) == 11)
1425#ifdef CONFIG_MIPS_MT_SMP 1385#ifdef CONFIG_MIPS_MT_SMP
@@ -1445,11 +1405,10 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
1445 unsigned int raw_id = config & 0xff; 1405 unsigned int raw_id = config & 0xff;
1446 unsigned int base_id = raw_id & 0x7f; 1406 unsigned int base_id = raw_id & 0x7f;
1447 1407
1408 raw_event.event_id = base_id;
1409
1448 switch (current_cpu_type()) { 1410 switch (current_cpu_type()) {
1449 case CPU_24K: 1411 case CPU_24K:
1450 if (IS_UNSUPPORTED_24K_EVENT(raw_id, base_id))
1451 return ERR_PTR(-EOPNOTSUPP);
1452 raw_event.event_id = base_id;
1453 if (IS_BOTH_COUNTERS_24K_EVENT(base_id)) 1412 if (IS_BOTH_COUNTERS_24K_EVENT(base_id))
1454 raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; 1413 raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
1455 else 1414 else
@@ -1464,9 +1423,6 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
1464#endif 1423#endif
1465 break; 1424 break;
1466 case CPU_34K: 1425 case CPU_34K:
1467 if (IS_UNSUPPORTED_34K_EVENT(raw_id, base_id))
1468 return ERR_PTR(-EOPNOTSUPP);
1469 raw_event.event_id = base_id;
1470 if (IS_BOTH_COUNTERS_34K_EVENT(base_id)) 1426 if (IS_BOTH_COUNTERS_34K_EVENT(base_id))
1471 raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; 1427 raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
1472 else 1428 else
@@ -1482,9 +1438,6 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
1482#endif 1438#endif
1483 break; 1439 break;
1484 case CPU_74K: 1440 case CPU_74K:
1485 if (IS_UNSUPPORTED_74K_EVENT(raw_id, base_id))
1486 return ERR_PTR(-EOPNOTSUPP);
1487 raw_event.event_id = base_id;
1488 if (IS_BOTH_COUNTERS_74K_EVENT(base_id)) 1441 if (IS_BOTH_COUNTERS_74K_EVENT(base_id))
1489 raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; 1442 raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
1490 else 1443 else
@@ -1495,9 +1448,6 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
1495#endif 1448#endif
1496 break; 1449 break;
1497 case CPU_1004K: 1450 case CPU_1004K:
1498 if (IS_UNSUPPORTED_1004K_EVENT(raw_id, base_id))
1499 return ERR_PTR(-EOPNOTSUPP);
1500 raw_event.event_id = base_id;
1501 if (IS_BOTH_COUNTERS_1004K_EVENT(base_id)) 1451 if (IS_BOTH_COUNTERS_1004K_EVENT(base_id))
1502 raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; 1452 raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
1503 else 1453 else