forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/hwtracing/intel_th/core.c
....@@ -439,6 +439,7 @@
439439 unsigned nres;
440440 unsigned type;
441441 unsigned otype;
442
+ bool mknode;
442443 unsigned scrpd;
443444 int id;
444445 } intel_th_subdevices[] = {
....@@ -446,9 +447,9 @@
446447 .nres = 1,
447448 .res = {
448449 {
449
- /* Handle TSCU from GTH driver */
450
+ /* Handle TSCU and CTS from GTH driver */
450451 .start = REG_GTH_OFFSET,
451
- .end = REG_TSCU_OFFSET + REG_TSCU_LENGTH - 1,
452
+ .end = REG_CTS_OFFSET + REG_CTS_LENGTH - 1,
452453 .flags = IORESOURCE_MEM,
453454 },
454455 },
....@@ -473,6 +474,7 @@
473474 .name = "msc",
474475 .id = 0,
475476 .type = INTEL_TH_OUTPUT,
477
+ .mknode = true,
476478 .otype = GTH_MSU,
477479 .scrpd = SCRPD_MEM_IS_PRIM_DEST | SCRPD_MSC0_IS_ENABLED,
478480 },
....@@ -493,6 +495,7 @@
493495 .name = "msc",
494496 .id = 1,
495497 .type = INTEL_TH_OUTPUT,
498
+ .mknode = true,
496499 .otype = GTH_MSU,
497500 .scrpd = SCRPD_MEM_IS_PRIM_DEST | SCRPD_MSC1_IS_ENABLED,
498501 },
....@@ -505,13 +508,31 @@
505508 .flags = IORESOURCE_MEM,
506509 },
507510 {
508
- .start = 1, /* use resource[1] */
511
+ .start = TH_MMIO_SW,
509512 .end = 0,
510513 .flags = IORESOURCE_MEM,
511514 },
512515 },
513516 .id = -1,
514517 .name = "sth",
518
+ .type = INTEL_TH_SOURCE,
519
+ },
520
+ {
521
+ .nres = 2,
522
+ .res = {
523
+ {
524
+ .start = REG_STH_OFFSET,
525
+ .end = REG_STH_OFFSET + REG_STH_LENGTH - 1,
526
+ .flags = IORESOURCE_MEM,
527
+ },
528
+ {
529
+ .start = TH_MMIO_RTIT,
530
+ .end = 0,
531
+ .flags = IORESOURCE_MEM,
532
+ },
533
+ },
534
+ .id = -1,
535
+ .name = "rtit",
515536 .type = INTEL_TH_SOURCE,
516537 },
517538 {
....@@ -598,7 +619,6 @@
598619 struct intel_th_device *thdev;
599620 struct resource res[3];
600621 unsigned int req = 0;
601
- bool is64bit = false;
602622 int r, err;
603623
604624 thdev = intel_th_device_alloc(th, subdev->type, subdev->name,
....@@ -608,18 +628,12 @@
608628
609629 thdev->drvdata = th->drvdata;
610630
611
- for (r = 0; r < th->num_resources; r++)
612
- if (th->resource[r].flags & IORESOURCE_MEM_64) {
613
- is64bit = true;
614
- break;
615
- }
616
-
617631 memcpy(res, subdev->res,
618632 sizeof(struct resource) * subdev->nres);
619633
620634 for (r = 0; r < subdev->nres; r++) {
621635 struct resource *devres = th->resource;
622
- int bar = 0; /* cut subdevices' MMIO from resource[0] */
636
+ int bar = TH_MMIO_CONFIG;
623637
624638 /*
625639 * Take .end == 0 to mean 'take the whole bar',
....@@ -628,8 +642,9 @@
628642 */
629643 if (!res[r].end && res[r].flags == IORESOURCE_MEM) {
630644 bar = res[r].start;
631
- if (is64bit)
632
- bar *= 2;
645
+ err = -ENODEV;
646
+ if (bar >= th->num_resources)
647
+ goto fail_put_device;
633648 res[r].start = 0;
634649 res[r].end = resource_size(&devres[bar]) - 1;
635650 }
....@@ -641,7 +656,12 @@
641656 dev_dbg(th->dev, "%s:%d @ %pR\n",
642657 subdev->name, r, &res[r]);
643658 } else if (res[r].flags & IORESOURCE_IRQ) {
644
- res[r].start = th->irq;
659
+ /*
660
+ * Only pass on the IRQ if we have useful interrupts:
661
+ * the ones that can be configured via MINTCTL.
662
+ */
663
+ if (INTEL_TH_CAP(th, has_mintctl) && th->irq != -1)
664
+ res[r].start = th->irq;
645665 }
646666 }
647667
....@@ -650,7 +670,8 @@
650670 goto fail_put_device;
651671
652672 if (subdev->type == INTEL_TH_OUTPUT) {
653
- thdev->dev.devt = MKDEV(th->major, th->num_thdevs);
673
+ if (subdev->mknode)
674
+ thdev->dev.devt = MKDEV(th->major, th->num_thdevs);
654675 thdev->output.type = subdev->otype;
655676 thdev->output.port = -1;
656677 thdev->output.scratchpad = subdev->scrpd;
....@@ -767,20 +788,18 @@
767788
768789 thdev = intel_th_subdevice_alloc(th, subdev);
769790 /* note: caller should free subdevices from th::thdev[] */
770
- if (IS_ERR(thdev))
791
+ if (IS_ERR(thdev)) {
792
+ /* ENODEV for individual subdevices is allowed */
793
+ if (PTR_ERR(thdev) == -ENODEV)
794
+ continue;
795
+
771796 return PTR_ERR(thdev);
797
+ }
772798
773799 th->thdev[th->num_thdevs++] = thdev;
774800 }
775801
776802 return 0;
777
-}
778
-
779
-static int match_devt(struct device *dev, void *data)
780
-{
781
- dev_t devt = (dev_t)(unsigned long)data;
782
-
783
- return dev->devt == devt;
784803 }
785804
786805 static int intel_th_output_open(struct inode *inode, struct file *file)
....@@ -790,9 +809,7 @@
790809 struct device *dev;
791810 int err;
792811
793
- dev = bus_find_device(&intel_th_bus, NULL,
794
- (void *)(unsigned long)inode->i_rdev,
795
- match_devt);
812
+ dev = bus_find_device_by_devt(&intel_th_bus, inode->i_rdev);
796813 if (!dev || !dev->driver)
797814 return -ENODEV;
798815
....@@ -818,26 +835,37 @@
818835 .llseek = noop_llseek,
819836 };
820837
838
+static irqreturn_t intel_th_irq(int irq, void *data)
839
+{
840
+ struct intel_th *th = data;
841
+ irqreturn_t ret = IRQ_NONE;
842
+ struct intel_th_driver *d;
843
+ int i;
844
+
845
+ for (i = 0; i < th->num_thdevs; i++) {
846
+ if (th->thdev[i]->type != INTEL_TH_OUTPUT)
847
+ continue;
848
+
849
+ d = to_intel_th_driver(th->thdev[i]->dev.driver);
850
+ if (d && d->irq)
851
+ ret |= d->irq(th->thdev[i]);
852
+ }
853
+
854
+ return ret;
855
+}
856
+
821857 /**
822858 * intel_th_alloc() - allocate a new Intel TH device and its subdevices
823859 * @dev: parent device
824
- * @devres: parent's resources
825
- * @ndevres: number of resources
860
+ * @devres: resources indexed by th_mmio_idx
826861 * @irq: irq number
827862 */
828863 struct intel_th *
829864 intel_th_alloc(struct device *dev, struct intel_th_drvdata *drvdata,
830
- struct resource *devres, unsigned int ndevres, int irq)
865
+ struct resource *devres, unsigned int ndevres)
831866 {
867
+ int err, r, nr_mmios = 0;
832868 struct intel_th *th;
833
- int err, r;
834
-
835
- if (irq == -1)
836
- for (r = 0; r < ndevres; r++)
837
- if (devres[r].flags & IORESOURCE_IRQ) {
838
- irq = devres[r].start;
839
- break;
840
- }
841869
842870 th = kzalloc(sizeof(*th), GFP_KERNEL);
843871 if (!th)
....@@ -855,12 +883,33 @@
855883 err = th->major;
856884 goto err_ida;
857885 }
886
+ th->irq = -1;
858887 th->dev = dev;
859888 th->drvdata = drvdata;
860889
861
- th->resource = devres;
862
- th->num_resources = ndevres;
863
- th->irq = irq;
890
+ for (r = 0; r < ndevres; r++)
891
+ switch (devres[r].flags & IORESOURCE_TYPE_BITS) {
892
+ case IORESOURCE_MEM:
893
+ th->resource[nr_mmios++] = devres[r];
894
+ break;
895
+ case IORESOURCE_IRQ:
896
+ err = devm_request_irq(dev, devres[r].start,
897
+ intel_th_irq, IRQF_SHARED,
898
+ dev_name(dev), th);
899
+ if (err)
900
+ goto err_chrdev;
901
+
902
+ if (th->irq == -1)
903
+ th->irq = devres[r].start;
904
+ th->num_irqs++;
905
+ break;
906
+ default:
907
+ dev_warn(dev, "Unknown resource type %lx\n",
908
+ devres[r].flags);
909
+ break;
910
+ }
911
+
912
+ th->num_resources = nr_mmios;
864913
865914 dev_set_drvdata(dev, th);
866915
....@@ -876,6 +925,10 @@
876925 }
877926
878927 return th;
928
+
929
+err_chrdev:
930
+ __unregister_chrdev(th->major, 0, TH_POSSIBLE_OUTPUTS,
931
+ "intel_th/output");
879932
880933 err_ida:
881934 ida_simple_remove(&intel_th_ida, th->id);
....@@ -901,6 +954,9 @@
901954 }
902955
903956 th->num_thdevs = 0;
957
+
958
+ for (i = 0; i < th->num_irqs; i++)
959
+ devm_free_irq(th->dev, th->irq + i, th);
904960
905961 pm_runtime_get_sync(th->dev);
906962 pm_runtime_forbid(th->dev);
....@@ -937,6 +993,27 @@
937993 EXPORT_SYMBOL_GPL(intel_th_trace_enable);
938994
939995 /**
996
+ * intel_th_trace_switch() - execute a switch sequence
997
+ * @thdev: output device that requests tracing switch
998
+ */
999
+int intel_th_trace_switch(struct intel_th_device *thdev)
1000
+{
1001
+ struct intel_th_device *hub = to_intel_th_device(thdev->dev.parent);
1002
+ struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver);
1003
+
1004
+ if (WARN_ON_ONCE(hub->type != INTEL_TH_SWITCH))
1005
+ return -EINVAL;
1006
+
1007
+ if (WARN_ON_ONCE(thdev->type != INTEL_TH_OUTPUT))
1008
+ return -EINVAL;
1009
+
1010
+ hubdrv->trig_switch(hub, &thdev->output);
1011
+
1012
+ return 0;
1013
+}
1014
+EXPORT_SYMBOL_GPL(intel_th_trace_switch);
1015
+
1016
+/**
9401017 * intel_th_trace_disable() - disable tracing for an output device
9411018 * @thdev: output device that requests tracing be disabled
9421019 */