Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'pm-devfreq'

* pm-devfreq:
PM / devfreq: remove checks for CONFIG_EXYNOS_ASV
PM / devfreq: exynos5: Use devm_devfreq_* function using device resource management
PM / devfreq: exynos4: Use devm_devfreq_* function using device resource management
PM / devfreq: Add devm_devfreq_{register,unregister}_opp_notfier function
PM / devfreq: Add resource-managed function for devfreq device
PM / devfreq: Fix devfreq_remove_device() to improve the sequence of resource free
PM / devfreq: exynos: make more PPMU code common
PM / devfreq: exynos5: introduce struct busfreq_ppmu_data
PM / devfreq: exynos4: introduce struct busfreq_ppmu_data
PM / devfreq: exynos4: use common PPMU code
PM / devfreq: exynos5: Add CONFIG_PM_OPP dependency to fix probe fail
PM / devfreq: exynos5: Use SIMPLE_DEV_PM_OPS macro
PM / devfreq: exynos4: Add CONFIG_PM_OPP dependency to fix probe fail
PM / devfreq: exynos4: Use SIMPLE_DEV_PM_OPS macro
PM / devfreq: exynos4: Fix bug of resource leak and code clean on probe()

+316 -266
+3 -2
drivers/devfreq/Kconfig
··· 70 70 depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM 71 71 select ARCH_HAS_OPP 72 72 select DEVFREQ_GOV_SIMPLE_ONDEMAND 73 + select PM_OPP 73 74 help 74 75 This adds the DEVFREQ driver for Exynos4210 memory bus (vdd_int) 75 76 and Exynos4212/4412 memory interface and bus (vdd_mif + vdd_int). 76 77 It reads PPMU counters of memory controllers and adjusts 77 78 the operating frequencies and voltages with OPP support. 78 - To operate with optimal voltages, ASV support is required 79 - (CONFIG_EXYNOS_ASV). 79 + This does not yet operate with optimal voltages. 80 80 81 81 config ARM_EXYNOS5_BUS_DEVFREQ 82 82 bool "ARM Exynos5250 Bus DEVFREQ Driver" 83 83 depends on SOC_EXYNOS5250 84 84 select ARCH_HAS_OPP 85 85 select DEVFREQ_GOV_SIMPLE_ONDEMAND 86 + select PM_OPP 86 87 help 87 88 This adds the DEVFREQ driver for Exynos5250 bus interface (vdd_int). 88 89 It reads PPMU counters of memory controllers and adjusts the
+115 -10
drivers/devfreq/devfreq.c
··· 394 394 * @devfreq: the devfreq struct 395 395 * @skip: skip calling device_unregister(). 396 396 */ 397 - static void _remove_devfreq(struct devfreq *devfreq, bool skip) 397 + static void _remove_devfreq(struct devfreq *devfreq) 398 398 { 399 399 mutex_lock(&devfreq_list_lock); 400 400 if (IS_ERR(find_device_devfreq(devfreq->dev.parent))) { ··· 412 412 if (devfreq->profile->exit) 413 413 devfreq->profile->exit(devfreq->dev.parent); 414 414 415 - if (!skip && get_device(&devfreq->dev)) { 416 - device_unregister(&devfreq->dev); 417 - put_device(&devfreq->dev); 418 - } 419 - 420 415 mutex_destroy(&devfreq->lock); 421 416 kfree(devfreq); 422 417 } ··· 421 426 * @dev: the devfreq device 422 427 * 423 428 * This calls _remove_devfreq() if _remove_devfreq() is not called. 424 - * Note that devfreq_dev_release() could be called by _remove_devfreq() as 425 - * well as by others unregistering the device. 426 429 */ 427 430 static void devfreq_dev_release(struct device *dev) 428 431 { 429 432 struct devfreq *devfreq = to_devfreq(dev); 430 433 431 - _remove_devfreq(devfreq, true); 434 + _remove_devfreq(devfreq); 432 435 } 433 436 434 437 /** ··· 537 544 if (!devfreq) 538 545 return -EINVAL; 539 546 540 - _remove_devfreq(devfreq, false); 547 + device_unregister(&devfreq->dev); 548 + put_device(&devfreq->dev); 541 549 542 550 return 0; 543 551 } 544 552 EXPORT_SYMBOL(devfreq_remove_device); 553 + 554 + static int devm_devfreq_dev_match(struct device *dev, void *res, void *data) 555 + { 556 + struct devfreq **r = res; 557 + 558 + if (WARN_ON(!r || !*r)) 559 + return 0; 560 + 561 + return *r == data; 562 + } 563 + 564 + static void devm_devfreq_dev_release(struct device *dev, void *res) 565 + { 566 + devfreq_remove_device(*(struct devfreq **)res); 567 + } 568 + 569 + /** 570 + * devm_devfreq_add_device() - Resource-managed devfreq_add_device() 571 + * @dev: the device to add devfreq feature. 572 + * @profile: device-specific profile to run devfreq. 573 + * @governor_name: name of the policy to choose frequency. 574 + * @data: private data for the governor. The devfreq framework does not 575 + * touch this value. 576 + * 577 + * This function manages automatically the memory of devfreq device using device 578 + * resource management and simplify the free operation for memory of devfreq 579 + * device. 580 + */ 581 + struct devfreq *devm_devfreq_add_device(struct device *dev, 582 + struct devfreq_dev_profile *profile, 583 + const char *governor_name, 584 + void *data) 585 + { 586 + struct devfreq **ptr, *devfreq; 587 + 588 + ptr = devres_alloc(devm_devfreq_dev_release, sizeof(*ptr), GFP_KERNEL); 589 + if (!ptr) 590 + return ERR_PTR(-ENOMEM); 591 + 592 + devfreq = devfreq_add_device(dev, profile, governor_name, data); 593 + if (IS_ERR(devfreq)) { 594 + devres_free(ptr); 595 + return ERR_PTR(-ENOMEM); 596 + } 597 + 598 + *ptr = devfreq; 599 + devres_add(dev, ptr); 600 + 601 + return devfreq; 602 + } 603 + EXPORT_SYMBOL(devm_devfreq_add_device); 604 + 605 + /** 606 + * devm_devfreq_remove_device() - Resource-managed devfreq_remove_device() 607 + * @dev: the device to add devfreq feature. 608 + * @devfreq: the devfreq instance to be removed 609 + */ 610 + void devm_devfreq_remove_device(struct device *dev, struct devfreq *devfreq) 611 + { 612 + WARN_ON(devres_release(dev, devm_devfreq_dev_release, 613 + devm_devfreq_dev_match, devfreq)); 614 + } 615 + EXPORT_SYMBOL(devm_devfreq_remove_device); 545 616 546 617 /** 547 618 * devfreq_suspend_device() - Suspend devfreq of a device. ··· 1168 1111 1169 1112 return ret; 1170 1113 } 1114 + 1115 + static void devm_devfreq_opp_release(struct device *dev, void *res) 1116 + { 1117 + devfreq_unregister_opp_notifier(dev, *(struct devfreq **)res); 1118 + } 1119 + 1120 + /** 1121 + * devm_ devfreq_register_opp_notifier() 1122 + * - Resource-managed devfreq_register_opp_notifier() 1123 + * @dev: The devfreq user device. (parent of devfreq) 1124 + * @devfreq: The devfreq object. 1125 + */ 1126 + int devm_devfreq_register_opp_notifier(struct device *dev, 1127 + struct devfreq *devfreq) 1128 + { 1129 + struct devfreq **ptr; 1130 + int ret; 1131 + 1132 + ptr = devres_alloc(devm_devfreq_opp_release, sizeof(*ptr), GFP_KERNEL); 1133 + if (!ptr) 1134 + return -ENOMEM; 1135 + 1136 + ret = devfreq_register_opp_notifier(dev, devfreq); 1137 + if (ret) { 1138 + devres_free(ptr); 1139 + return ret; 1140 + } 1141 + 1142 + *ptr = devfreq; 1143 + devres_add(dev, ptr); 1144 + 1145 + return 0; 1146 + } 1147 + EXPORT_SYMBOL(devm_devfreq_register_opp_notifier); 1148 + 1149 + /** 1150 + * devm_devfreq_unregister_opp_notifier() 1151 + * - Resource-managed devfreq_unregister_opp_notifier() 1152 + * @dev: The devfreq user device. (parent of devfreq) 1153 + * @devfreq: The devfreq object. 1154 + */ 1155 + void devm_devfreq_unregister_opp_notifier(struct device *dev, 1156 + struct devfreq *devfreq) 1157 + { 1158 + WARN_ON(devres_release(dev, devm_devfreq_opp_release, 1159 + devm_devfreq_dev_match, devfreq)); 1160 + } 1161 + EXPORT_SYMBOL(devm_devfreq_unregister_opp_notifier); 1171 1162 1172 1163 MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); 1173 1164 MODULE_DESCRIPTION("devfreq class support");
+1 -1
drivers/devfreq/exynos/Makefile
··· 1 1 # Exynos DEVFREQ Drivers 2 - obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos4_bus.o 2 + obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos_ppmu.o exynos4_bus.o 3 3 obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ) += exynos_ppmu.o exynos5_bus.o
+59 -158
drivers/devfreq/exynos/exynos4_bus.c
··· 25 25 #include <linux/regulator/consumer.h> 26 26 #include <linux/module.h> 27 27 28 - /* Exynos4 ASV has been in the mailing list, but not upstreamed, yet. */ 29 - #ifdef CONFIG_EXYNOS_ASV 30 - extern unsigned int exynos_result_of_asv; 31 - #endif 32 - 33 28 #include <mach/map.h> 34 29 30 + #include "exynos_ppmu.h" 35 31 #include "exynos4_bus.h" 36 32 37 33 #define MAX_SAFEVOLT 1200000 /* 1.2V */ ··· 40 44 /* Assume that the bus is saturated if the utilization is 40% */ 41 45 #define BUS_SATURATION_RATIO 40 42 46 43 - enum ppmu_counter { 44 - PPMU_PMNCNT0 = 0, 45 - PPMU_PMCCNT1, 46 - PPMU_PMNCNT2, 47 - PPMU_PMNCNT3, 48 - PPMU_PMNCNT_MAX, 49 - }; 50 - struct exynos4_ppmu { 51 - void __iomem *hw_base; 52 - unsigned int ccnt; 53 - unsigned int event; 54 - unsigned int count[PPMU_PMNCNT_MAX]; 55 - bool ccnt_overflow; 56 - bool count_overflow[PPMU_PMNCNT_MAX]; 57 - }; 58 - 59 47 enum busclk_level_idx { 60 48 LV_0 = 0, 61 49 LV_1, ··· 48 68 LV_4, 49 69 _LV_END 50 70 }; 71 + 72 + enum exynos_ppmu_idx { 73 + PPMU_DMC0, 74 + PPMU_DMC1, 75 + PPMU_END, 76 + }; 77 + 51 78 #define EX4210_LV_MAX LV_2 52 79 #define EX4x12_LV_MAX LV_4 53 80 #define EX4210_LV_NUM (LV_2 + 1) ··· 78 91 struct regulator *vdd_int; 79 92 struct regulator *vdd_mif; /* Exynos4412/4212 only */ 80 93 struct busfreq_opp_info curr_oppinfo; 81 - struct exynos4_ppmu dmc[2]; 94 + struct busfreq_ppmu_data ppmu_data; 82 95 83 96 struct notifier_block pm_notifier; 84 97 struct mutex lock; ··· 86 99 /* Dividers calculated at boot/probe-time */ 87 100 unsigned int dmc_divtable[_LV_END]; /* DMC0 */ 88 101 unsigned int top_divtable[_LV_END]; 89 - }; 90 - 91 - struct bus_opp_table { 92 - unsigned int idx; 93 - unsigned long clk; 94 - unsigned long volt; 95 102 }; 96 103 97 104 /* 4210 controls clock of mif and voltage of int */ ··· 505 524 return 0; 506 525 } 507 526 508 - 509 - static void busfreq_mon_reset(struct busfreq_data *data) 510 - { 511 - unsigned int i; 512 - 513 - for (i = 0; i < 2; i++) { 514 - void __iomem *ppmu_base = data->dmc[i].hw_base; 515 - 516 - /* Reset PPMU */ 517 - __raw_writel(0x8000000f, ppmu_base + 0xf010); 518 - __raw_writel(0x8000000f, ppmu_base + 0xf050); 519 - __raw_writel(0x6, ppmu_base + 0xf000); 520 - __raw_writel(0x0, ppmu_base + 0xf100); 521 - 522 - /* Set PPMU Event */ 523 - data->dmc[i].event = 0x6; 524 - __raw_writel(((data->dmc[i].event << 12) | 0x1), 525 - ppmu_base + 0xfc); 526 - 527 - /* Start PPMU */ 528 - __raw_writel(0x1, ppmu_base + 0xf000); 529 - } 530 - } 531 - 532 - static void exynos4_read_ppmu(struct busfreq_data *data) 533 - { 534 - int i, j; 535 - 536 - for (i = 0; i < 2; i++) { 537 - void __iomem *ppmu_base = data->dmc[i].hw_base; 538 - u32 overflow; 539 - 540 - /* Stop PPMU */ 541 - __raw_writel(0x0, ppmu_base + 0xf000); 542 - 543 - /* Update local data from PPMU */ 544 - overflow = __raw_readl(ppmu_base + 0xf050); 545 - 546 - data->dmc[i].ccnt = __raw_readl(ppmu_base + 0xf100); 547 - data->dmc[i].ccnt_overflow = overflow & (1 << 31); 548 - 549 - for (j = 0; j < PPMU_PMNCNT_MAX; j++) { 550 - data->dmc[i].count[j] = __raw_readl( 551 - ppmu_base + (0xf110 + (0x10 * j))); 552 - data->dmc[i].count_overflow[j] = overflow & (1 << j); 553 - } 554 - } 555 - 556 - busfreq_mon_reset(data); 557 - } 558 - 559 527 static int exynos4x12_get_intspec(unsigned long mifclk) 560 528 { 561 529 int i = 0; ··· 628 698 return err; 629 699 } 630 700 631 - static int exynos4_get_busier_dmc(struct busfreq_data *data) 632 - { 633 - u64 p0 = data->dmc[0].count[0]; 634 - u64 p1 = data->dmc[1].count[0]; 635 - 636 - p0 *= data->dmc[1].ccnt; 637 - p1 *= data->dmc[0].ccnt; 638 - 639 - if (data->dmc[1].ccnt == 0) 640 - return 0; 641 - 642 - if (p0 > p1) 643 - return 0; 644 - return 1; 645 - } 646 - 647 701 static int exynos4_bus_get_dev_status(struct device *dev, 648 702 struct devfreq_dev_status *stat) 649 703 { 650 704 struct busfreq_data *data = dev_get_drvdata(dev); 651 - int busier_dmc; 652 - int cycles_x2 = 2; /* 2 x cycles */ 653 - void __iomem *addr; 654 - u32 timing; 655 - u32 memctrl; 705 + struct busfreq_ppmu_data *ppmu_data = &data->ppmu_data; 706 + int busier; 656 707 657 - exynos4_read_ppmu(data); 658 - busier_dmc = exynos4_get_busier_dmc(data); 708 + exynos_read_ppmu(ppmu_data); 709 + busier = exynos_get_busier_ppmu(ppmu_data); 659 710 stat->current_frequency = data->curr_oppinfo.rate; 660 711 661 - if (busier_dmc) 662 - addr = S5P_VA_DMC1; 663 - else 664 - addr = S5P_VA_DMC0; 665 - 666 - memctrl = __raw_readl(addr + 0x04); /* one of DDR2/3/LPDDR2 */ 667 - timing = __raw_readl(addr + 0x38); /* CL or WL/RL values */ 668 - 669 - switch ((memctrl >> 8) & 0xf) { 670 - case 0x4: /* DDR2 */ 671 - cycles_x2 = ((timing >> 16) & 0xf) * 2; 672 - break; 673 - case 0x5: /* LPDDR2 */ 674 - case 0x6: /* DDR3 */ 675 - cycles_x2 = ((timing >> 8) & 0xf) + ((timing >> 0) & 0xf); 676 - break; 677 - default: 678 - pr_err("%s: Unknown Memory Type(%d).\n", __func__, 679 - (memctrl >> 8) & 0xf); 680 - return -EINVAL; 681 - } 682 - 683 712 /* Number of cycles spent on memory access */ 684 - stat->busy_time = data->dmc[busier_dmc].count[0] / 2 * (cycles_x2 + 2); 713 + stat->busy_time = ppmu_data->ppmu[busier].count[PPMU_PMNCNT3]; 685 714 stat->busy_time *= 100 / BUS_SATURATION_RATIO; 686 - stat->total_time = data->dmc[busier_dmc].ccnt; 715 + stat->total_time = ppmu_data->ppmu[busier].ccnt; 687 716 688 717 /* If the counters have overflown, retry */ 689 - if (data->dmc[busier_dmc].ccnt_overflow || 690 - data->dmc[busier_dmc].count_overflow[0]) 718 + if (ppmu_data->ppmu[busier].ccnt_overflow || 719 + ppmu_data->ppmu[busier].count_overflow[0]) 691 720 return -EAGAIN; 692 721 693 722 return 0; 694 - } 695 - 696 - static void exynos4_bus_exit(struct device *dev) 697 - { 698 - struct busfreq_data *data = dev_get_drvdata(dev); 699 - 700 - devfreq_unregister_opp_notifier(dev, data->devfreq); 701 723 } 702 724 703 725 static struct devfreq_dev_profile exynos4_devfreq_profile = { ··· 657 775 .polling_ms = 50, 658 776 .target = exynos4_bus_target, 659 777 .get_dev_status = exynos4_bus_get_dev_status, 660 - .exit = exynos4_bus_exit, 661 778 }; 662 779 663 780 static int exynos4210_init_tables(struct busfreq_data *data) ··· 718 837 data->top_divtable[i] = tmp; 719 838 } 720 839 721 - #ifdef CONFIG_EXYNOS_ASV 722 - tmp = exynos4_result_of_asv; 723 - #else 840 + /* 841 + * TODO: init tmp based on busfreq_data 842 + * (device-tree or platform-data) 843 + */ 724 844 tmp = 0; /* Max voltages for the reliability of the unknown */ 725 - #endif 726 845 727 846 pr_debug("ASV Group of Exynos4 is %d\n", tmp); 728 847 /* Use merged grouping for voltage */ ··· 803 922 data->dmc_divtable[i] = tmp; 804 923 } 805 924 806 - #ifdef CONFIG_EXYNOS_ASV 807 - tmp = exynos4_result_of_asv; 808 - #else 809 925 tmp = 0; /* Max voltages for the reliability of the unknown */ 810 - #endif 811 926 812 927 if (tmp > 8) 813 928 tmp = 0; ··· 897 1020 static int exynos4_busfreq_probe(struct platform_device *pdev) 898 1021 { 899 1022 struct busfreq_data *data; 1023 + struct busfreq_ppmu_data *ppmu_data; 900 1024 struct dev_pm_opp *opp; 901 1025 struct device *dev = &pdev->dev; 902 1026 int err = 0; ··· 908 1030 return -ENOMEM; 909 1031 } 910 1032 1033 + ppmu_data = &data->ppmu_data; 1034 + ppmu_data->ppmu_end = PPMU_END; 1035 + ppmu_data->ppmu = devm_kzalloc(dev, 1036 + sizeof(struct exynos_ppmu) * PPMU_END, 1037 + GFP_KERNEL); 1038 + if (!ppmu_data->ppmu) { 1039 + dev_err(dev, "Failed to allocate memory for exynos_ppmu\n"); 1040 + return -ENOMEM; 1041 + } 1042 + 911 1043 data->type = pdev->id_entry->driver_data; 912 - data->dmc[0].hw_base = S5P_VA_DMC0; 913 - data->dmc[1].hw_base = S5P_VA_DMC1; 1044 + ppmu_data->ppmu[PPMU_DMC0].hw_base = S5P_VA_DMC0; 1045 + ppmu_data->ppmu[PPMU_DMC1].hw_base = S5P_VA_DMC1; 914 1046 data->pm_notifier.notifier_call = exynos4_busfreq_pm_notifier_event; 915 1047 data->dev = dev; 916 1048 mutex_init(&data->lock); ··· 936 1048 dev_err(dev, "Cannot determine the device id %d\n", data->type); 937 1049 err = -EINVAL; 938 1050 } 939 - if (err) 1051 + if (err) { 1052 + dev_err(dev, "Cannot initialize busfreq table %d\n", 1053 + data->type); 940 1054 return err; 1055 + } 941 1056 942 1057 data->vdd_int = devm_regulator_get(dev, "vdd_int"); 943 1058 if (IS_ERR(data->vdd_int)) { ··· 970 1079 971 1080 platform_set_drvdata(pdev, data); 972 1081 973 - busfreq_mon_reset(data); 974 - 975 - data->devfreq = devfreq_add_device(dev, &exynos4_devfreq_profile, 1082 + data->devfreq = devm_devfreq_add_device(dev, &exynos4_devfreq_profile, 976 1083 "simple_ondemand", NULL); 977 1084 if (IS_ERR(data->devfreq)) 978 1085 return PTR_ERR(data->devfreq); 979 1086 980 - devfreq_register_opp_notifier(dev, data->devfreq); 1087 + /* 1088 + * Start PPMU (Performance Profiling Monitoring Unit) to check 1089 + * utilization of each IP in the Exynos4 SoC. 1090 + */ 1091 + busfreq_mon_reset(ppmu_data); 981 1092 1093 + /* Register opp_notifier for Exynos4 busfreq */ 1094 + err = devm_devfreq_register_opp_notifier(dev, data->devfreq); 1095 + if (err < 0) { 1096 + dev_err(dev, "Failed to register opp notifier\n"); 1097 + return err; 1098 + } 1099 + 1100 + /* Register pm_notifier for Exynos4 busfreq */ 982 1101 err = register_pm_notifier(&data->pm_notifier); 983 1102 if (err) { 984 1103 dev_err(dev, "Failed to setup pm notifier\n"); 985 - devfreq_remove_device(data->devfreq); 986 1104 return err; 987 1105 } 988 1106 ··· 1002 1102 { 1003 1103 struct busfreq_data *data = platform_get_drvdata(pdev); 1004 1104 1105 + /* Unregister all of notifier chain */ 1005 1106 unregister_pm_notifier(&data->pm_notifier); 1006 - devfreq_remove_device(data->devfreq); 1007 1107 1008 1108 return 0; 1009 1109 } 1010 1110 1111 + #ifdef CONFIG_PM_SLEEP 1011 1112 static int exynos4_busfreq_resume(struct device *dev) 1012 1113 { 1013 1114 struct busfreq_data *data = dev_get_drvdata(dev); 1115 + struct busfreq_ppmu_data *ppmu_data = &data->ppmu_data; 1014 1116 1015 - busfreq_mon_reset(data); 1117 + busfreq_mon_reset(ppmu_data); 1016 1118 return 0; 1017 1119 } 1120 + #endif 1018 1121 1019 - static const struct dev_pm_ops exynos4_busfreq_pm = { 1020 - .resume = exynos4_busfreq_resume, 1021 - }; 1122 + static SIMPLE_DEV_PM_OPS(exynos4_busfreq_pm_ops, NULL, exynos4_busfreq_resume); 1022 1123 1023 1124 static const struct platform_device_id exynos4_busfreq_id[] = { 1024 1125 { "exynos4210-busfreq", TYPE_BUSF_EXYNOS4210 }, ··· 1035 1134 .driver = { 1036 1135 .name = "exynos4-busfreq", 1037 1136 .owner = THIS_MODULE, 1038 - .pm = &exynos4_busfreq_pm, 1137 + .pm = &exynos4_busfreq_pm_ops, 1039 1138 }, 1040 1139 }; 1041 1140
+36 -94
drivers/devfreq/exynos/exynos5_bus.c
··· 50 50 struct device *dev; 51 51 struct devfreq *devfreq; 52 52 struct regulator *vdd_int; 53 - struct exynos_ppmu ppmu[PPMU_END]; 53 + struct busfreq_ppmu_data ppmu_data; 54 54 unsigned long curr_freq; 55 55 bool disabled; 56 56 ··· 74 74 {LV_4, 100000, 1025000}, 75 75 {0, 0, 0}, 76 76 }; 77 - 78 - static void busfreq_mon_reset(struct busfreq_data_int *data) 79 - { 80 - unsigned int i; 81 - 82 - for (i = PPMU_RIGHT; i < PPMU_END; i++) { 83 - void __iomem *ppmu_base = data->ppmu[i].hw_base; 84 - 85 - /* Reset the performance and cycle counters */ 86 - exynos_ppmu_reset(ppmu_base); 87 - 88 - /* Setup count registers to monitor read/write transactions */ 89 - data->ppmu[i].event[PPMU_PMNCNT3] = RDWR_DATA_COUNT; 90 - exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3, 91 - data->ppmu[i].event[PPMU_PMNCNT3]); 92 - 93 - exynos_ppmu_start(ppmu_base); 94 - } 95 - } 96 - 97 - static void exynos5_read_ppmu(struct busfreq_data_int *data) 98 - { 99 - int i, j; 100 - 101 - for (i = PPMU_RIGHT; i < PPMU_END; i++) { 102 - void __iomem *ppmu_base = data->ppmu[i].hw_base; 103 - 104 - exynos_ppmu_stop(ppmu_base); 105 - 106 - /* Update local data from PPMU */ 107 - data->ppmu[i].ccnt = __raw_readl(ppmu_base + PPMU_CCNT); 108 - 109 - for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) { 110 - if (data->ppmu[i].event[j] == 0) 111 - data->ppmu[i].count[j] = 0; 112 - else 113 - data->ppmu[i].count[j] = 114 - exynos_ppmu_read(ppmu_base, j); 115 - } 116 - } 117 - 118 - busfreq_mon_reset(data); 119 - } 120 77 121 78 static int exynos5_int_setvolt(struct busfreq_data_int *data, 122 79 unsigned long volt) ··· 142 185 return err; 143 186 } 144 187 145 - static int exynos5_get_busier_dmc(struct busfreq_data_int *data) 146 - { 147 - int i, j; 148 - int busy = 0; 149 - unsigned int temp = 0; 150 - 151 - for (i = PPMU_RIGHT; i < PPMU_END; i++) { 152 - for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) { 153 - if (data->ppmu[i].count[j] > temp) { 154 - temp = data->ppmu[i].count[j]; 155 - busy = i; 156 - } 157 - } 158 - } 159 - 160 - return busy; 161 - } 162 - 163 188 static int exynos5_int_get_dev_status(struct device *dev, 164 189 struct devfreq_dev_status *stat) 165 190 { 166 191 struct platform_device *pdev = container_of(dev, struct platform_device, 167 192 dev); 168 193 struct busfreq_data_int *data = platform_get_drvdata(pdev); 194 + struct busfreq_ppmu_data *ppmu_data = &data->ppmu_data; 169 195 int busier_dmc; 170 196 171 - exynos5_read_ppmu(data); 172 - busier_dmc = exynos5_get_busier_dmc(data); 197 + exynos_read_ppmu(ppmu_data); 198 + busier_dmc = exynos_get_busier_ppmu(ppmu_data); 173 199 174 200 stat->current_frequency = data->curr_freq; 175 201 176 202 /* Number of cycles spent on memory access */ 177 - stat->busy_time = data->ppmu[busier_dmc].count[PPMU_PMNCNT3]; 203 + stat->busy_time = ppmu_data->ppmu[busier_dmc].count[PPMU_PMNCNT3]; 178 204 stat->busy_time *= 100 / INT_BUS_SATURATION_RATIO; 179 - stat->total_time = data->ppmu[busier_dmc].ccnt; 205 + stat->total_time = ppmu_data->ppmu[busier_dmc].ccnt; 180 206 181 207 return 0; 182 - } 183 - static void exynos5_int_exit(struct device *dev) 184 - { 185 - struct platform_device *pdev = container_of(dev, struct platform_device, 186 - dev); 187 - struct busfreq_data_int *data = platform_get_drvdata(pdev); 188 - 189 - devfreq_unregister_opp_notifier(dev, data->devfreq); 190 208 } 191 209 192 210 static struct devfreq_dev_profile exynos5_devfreq_int_profile = { ··· 169 237 .polling_ms = 100, 170 238 .target = exynos5_busfreq_int_target, 171 239 .get_dev_status = exynos5_int_get_dev_status, 172 - .exit = exynos5_int_exit, 173 240 }; 174 241 175 242 static int exynos5250_init_int_tables(struct busfreq_data_int *data) ··· 246 315 static int exynos5_busfreq_int_probe(struct platform_device *pdev) 247 316 { 248 317 struct busfreq_data_int *data; 318 + struct busfreq_ppmu_data *ppmu_data; 249 319 struct dev_pm_opp *opp; 250 320 struct device *dev = &pdev->dev; 251 321 struct device_node *np; ··· 262 330 return -ENOMEM; 263 331 } 264 332 333 + ppmu_data = &data->ppmu_data; 334 + ppmu_data->ppmu_end = PPMU_END; 335 + ppmu_data->ppmu = devm_kzalloc(dev, 336 + sizeof(struct exynos_ppmu) * PPMU_END, 337 + GFP_KERNEL); 338 + if (!ppmu_data->ppmu) { 339 + dev_err(dev, "Failed to allocate memory for exynos_ppmu\n"); 340 + return -ENOMEM; 341 + } 342 + 265 343 np = of_find_compatible_node(NULL, NULL, "samsung,exynos5250-ppmu"); 266 344 if (np == NULL) { 267 345 pr_err("Unable to find PPMU node\n"); 268 346 return -ENOENT; 269 347 } 270 348 271 - for (i = PPMU_RIGHT; i < PPMU_END; i++) { 349 + for (i = 0; i < ppmu_data->ppmu_end; i++) { 272 350 /* map PPMU memory region */ 273 - data->ppmu[i].hw_base = of_iomap(np, i); 274 - if (data->ppmu[i].hw_base == NULL) { 351 + ppmu_data->ppmu[i].hw_base = of_iomap(np, i); 352 + if (ppmu_data->ppmu[i].hw_base == NULL) { 275 353 dev_err(&pdev->dev, "failed to map memory region\n"); 276 354 return -ENOMEM; 277 355 } ··· 332 390 333 391 platform_set_drvdata(pdev, data); 334 392 335 - busfreq_mon_reset(data); 393 + busfreq_mon_reset(ppmu_data); 336 394 337 - data->devfreq = devfreq_add_device(dev, &exynos5_devfreq_int_profile, 395 + data->devfreq = devm_devfreq_add_device(dev, &exynos5_devfreq_int_profile, 338 396 "simple_ondemand", NULL); 397 + if (IS_ERR(data->devfreq)) 398 + return PTR_ERR(data->devfreq); 339 399 340 - if (IS_ERR(data->devfreq)) { 341 - err = PTR_ERR(data->devfreq); 342 - goto err_devfreq_add; 400 + err = devm_devfreq_register_opp_notifier(dev, data->devfreq); 401 + if (err < 0) { 402 + dev_err(dev, "Failed to register opp notifier\n"); 403 + return err; 343 404 } 344 - 345 - devfreq_register_opp_notifier(dev, data->devfreq); 346 405 347 406 err = register_pm_notifier(&data->pm_notifier); 348 407 if (err) { 349 408 dev_err(dev, "Failed to setup pm notifier\n"); 350 - goto err_devfreq_add; 409 + return err; 351 410 } 352 411 353 412 /* TODO: Add a new QOS class for int/mif bus */ 354 413 pm_qos_add_request(&data->int_req, PM_QOS_NETWORK_THROUGHPUT, -1); 355 414 356 415 return 0; 357 - 358 - err_devfreq_add: 359 - devfreq_remove_device(data->devfreq); 360 - return err; 361 416 } 362 417 363 418 static int exynos5_busfreq_int_remove(struct platform_device *pdev) ··· 363 424 364 425 pm_qos_remove_request(&data->int_req); 365 426 unregister_pm_notifier(&data->pm_notifier); 366 - devfreq_remove_device(data->devfreq); 367 427 368 428 return 0; 369 429 } 370 430 431 + #ifdef CONFIG_PM_SLEEP 371 432 static int exynos5_busfreq_int_resume(struct device *dev) 372 433 { 373 434 struct platform_device *pdev = container_of(dev, struct platform_device, 374 435 dev); 375 436 struct busfreq_data_int *data = platform_get_drvdata(pdev); 437 + struct busfreq_ppmu_data *ppmu_data = &data->ppmu_data; 376 438 377 - busfreq_mon_reset(data); 439 + busfreq_mon_reset(ppmu_data); 378 440 return 0; 379 441 } 380 - 381 442 static const struct dev_pm_ops exynos5_busfreq_int_pm = { 382 443 .resume = exynos5_busfreq_int_resume, 383 444 }; 445 + #endif 446 + static SIMPLE_DEV_PM_OPS(exynos5_busfreq_int_pm_ops, NULL, 447 + exynos5_busfreq_int_resume); 384 448 385 449 /* platform device pointer for exynos5 devfreq device. */ 386 450 static struct platform_device *exynos5_devfreq_pdev; ··· 394 452 .driver = { 395 453 .name = "exynos5-bus-int", 396 454 .owner = THIS_MODULE, 397 - .pm = &exynos5_busfreq_int_pm, 455 + .pm = &exynos5_busfreq_int_pm_ops, 398 456 }, 399 457 }; 400 458
+60
drivers/devfreq/exynos/exynos_ppmu.c
··· 54 54 55 55 return total; 56 56 } 57 + 58 + void busfreq_mon_reset(struct busfreq_ppmu_data *ppmu_data) 59 + { 60 + unsigned int i; 61 + 62 + for (i = 0; i < ppmu_data->ppmu_end; i++) { 63 + void __iomem *ppmu_base = ppmu_data->ppmu[i].hw_base; 64 + 65 + /* Reset the performance and cycle counters */ 66 + exynos_ppmu_reset(ppmu_base); 67 + 68 + /* Setup count registers to monitor read/write transactions */ 69 + ppmu_data->ppmu[i].event[PPMU_PMNCNT3] = RDWR_DATA_COUNT; 70 + exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3, 71 + ppmu_data->ppmu[i].event[PPMU_PMNCNT3]); 72 + 73 + exynos_ppmu_start(ppmu_base); 74 + } 75 + } 76 + 77 + void exynos_read_ppmu(struct busfreq_ppmu_data *ppmu_data) 78 + { 79 + int i, j; 80 + 81 + for (i = 0; i < ppmu_data->ppmu_end; i++) { 82 + void __iomem *ppmu_base = ppmu_data->ppmu[i].hw_base; 83 + 84 + exynos_ppmu_stop(ppmu_base); 85 + 86 + /* Update local data from PPMU */ 87 + ppmu_data->ppmu[i].ccnt = __raw_readl(ppmu_base + PPMU_CCNT); 88 + 89 + for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) { 90 + if (ppmu_data->ppmu[i].event[j] == 0) 91 + ppmu_data->ppmu[i].count[j] = 0; 92 + else 93 + ppmu_data->ppmu[i].count[j] = 94 + exynos_ppmu_read(ppmu_base, j); 95 + } 96 + } 97 + 98 + busfreq_mon_reset(ppmu_data); 99 + } 100 + 101 + int exynos_get_busier_ppmu(struct busfreq_ppmu_data *ppmu_data) 102 + { 103 + unsigned int count = 0; 104 + int i, j, busy = 0; 105 + 106 + for (i = 0; i < ppmu_data->ppmu_end; i++) { 107 + for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) { 108 + if (ppmu_data->ppmu[i].count[j] > count) { 109 + count = ppmu_data->ppmu[i].count[j]; 110 + busy = i; 111 + } 112 + } 113 + } 114 + 115 + return busy; 116 + }
+8
drivers/devfreq/exynos/exynos_ppmu.h
··· 69 69 bool count_overflow[PPMU_PMNCNT_MAX]; 70 70 }; 71 71 72 + struct busfreq_ppmu_data { 73 + struct exynos_ppmu *ppmu; 74 + int ppmu_end; 75 + }; 76 + 72 77 void exynos_ppmu_reset(void __iomem *ppmu_base); 73 78 void exynos_ppmu_setevent(void __iomem *ppmu_base, unsigned int ch, 74 79 unsigned int evt); 75 80 void exynos_ppmu_start(void __iomem *ppmu_base); 76 81 void exynos_ppmu_stop(void __iomem *ppmu_base); 77 82 unsigned int exynos_ppmu_read(void __iomem *ppmu_base, unsigned int ch); 83 + void busfreq_mon_reset(struct busfreq_ppmu_data *ppmu_data); 84 + void exynos_read_ppmu(struct busfreq_ppmu_data *ppmu_data); 85 + int exynos_get_busier_ppmu(struct busfreq_ppmu_data *ppmu_data); 78 86 #endif /* __DEVFREQ_EXYNOS_PPMU_H */
+34 -1
include/linux/devfreq.h
··· 181 181 const char *governor_name, 182 182 void *data); 183 183 extern int devfreq_remove_device(struct devfreq *devfreq); 184 + extern struct devfreq *devm_devfreq_add_device(struct device *dev, 185 + struct devfreq_dev_profile *profile, 186 + const char *governor_name, 187 + void *data); 188 + extern void devm_devfreq_remove_device(struct device *dev, 189 + struct devfreq *devfreq); 184 190 185 191 /* Supposed to be called by PM_SLEEP/PM_RUNTIME callbacks */ 186 192 extern int devfreq_suspend_device(struct devfreq *devfreq); ··· 199 193 struct devfreq *devfreq); 200 194 extern int devfreq_unregister_opp_notifier(struct device *dev, 201 195 struct devfreq *devfreq); 196 + extern int devm_devfreq_register_opp_notifier(struct device *dev, 197 + struct devfreq *devfreq); 198 + extern void devm_devfreq_unregister_opp_notifier(struct device *dev, 199 + struct devfreq *devfreq); 202 200 203 201 #if IS_ENABLED(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND) 204 202 /** ··· 230 220 const char *governor_name, 231 221 void *data) 232 222 { 233 - return NULL; 223 + return ERR_PTR(-ENOSYS); 234 224 } 235 225 236 226 static inline int devfreq_remove_device(struct devfreq *devfreq) 237 227 { 238 228 return 0; 229 + } 230 + 231 + static inline struct devfreq *devm_devfreq_add_device(struct device *dev, 232 + struct devfreq_dev_profile *profile, 233 + const char *governor_name, 234 + void *data) 235 + { 236 + return ERR_PTR(-ENOSYS); 237 + } 238 + 239 + static inline void devm_devfreq_remove_device(struct device *dev, 240 + struct devfreq *devfreq) 241 + { 239 242 } 240 243 241 244 static inline int devfreq_suspend_device(struct devfreq *devfreq) ··· 279 256 return -EINVAL; 280 257 } 281 258 259 + static inline int devm_devfreq_register_opp_notifier(struct device *dev, 260 + struct devfreq *devfreq) 261 + { 262 + return -EINVAL; 263 + } 264 + 265 + static inline void devm_devfreq_unregister_opp_notifier(struct device *dev, 266 + struct devfreq *devfreq) 267 + { 268 + } 282 269 #endif /* CONFIG_PM_DEVFREQ */ 283 270 284 271 #endif /* __LINUX_DEVFREQ_H__ */