devfreq.c (e98bdb3059cbf2b1cd4261e126b08429f64466c3) | devfreq.c (4091fb95b5f8dea37568d1a94c8227244bade891) |
---|---|
1/* 2 * devfreq: Generic Dynamic Voltage and Frequency Scaling (DVFS) Framework 3 * for Non-CPU Devices. 4 * 5 * Copyright (C) 2011 Samsung Electronics 6 * MyungJoo Ham <myungjoo.ham@samsung.com> 7 * 8 * This program is free software; you can redistribute it and/or modify --- 97 unchanged lines hidden (view full) --- 106 profile->max_state, 107 sizeof(*profile->freq_table), 108 GFP_KERNEL); 109 if (!profile->freq_table) { 110 profile->max_state = 0; 111 return; 112 } 113 | 1/* 2 * devfreq: Generic Dynamic Voltage and Frequency Scaling (DVFS) Framework 3 * for Non-CPU Devices. 4 * 5 * Copyright (C) 2011 Samsung Electronics 6 * MyungJoo Ham <myungjoo.ham@samsung.com> 7 * 8 * This program is free software; you can redistribute it and/or modify --- 97 unchanged lines hidden (view full) --- 106 profile->max_state, 107 sizeof(*profile->freq_table), 108 GFP_KERNEL); 109 if (!profile->freq_table) { 110 profile->max_state = 0; 111 return; 112 } 113 |
114 rcu_read_lock(); | |
115 for (i = 0, freq = 0; i < profile->max_state; i++, freq++) { 116 opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &freq); 117 if (IS_ERR(opp)) { 118 devm_kfree(devfreq->dev.parent, profile->freq_table); 119 profile->max_state = 0; | 114 for (i = 0, freq = 0; i < profile->max_state; i++, freq++) { 115 opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &freq); 116 if (IS_ERR(opp)) { 117 devm_kfree(devfreq->dev.parent, profile->freq_table); 118 profile->max_state = 0; |
120 rcu_read_unlock(); | |
121 return; 122 } | 119 return; 120 } |
121 dev_pm_opp_put(opp); |
|
123 profile->freq_table[i] = freq; 124 } | 122 profile->freq_table[i] = freq; 123 } |
125 rcu_read_unlock(); | |
126} 127 128/** 129 * devfreq_update_status() - Update statistics of devfreq behavior 130 * @devfreq: the devfreq instance 131 * @freq: the update target frequency 132 */ | 124} 125 126/** 127 * devfreq_update_status() - Update statistics of devfreq behavior 128 * @devfreq: the devfreq instance 129 * @freq: the update target frequency 130 */ |
133static int devfreq_update_status(struct devfreq *devfreq, unsigned long freq) | 131int devfreq_update_status(struct devfreq *devfreq, unsigned long freq) |
134{ 135 int lev, prev_lev, ret = 0; 136 unsigned long cur_time; 137 138 cur_time = jiffies; 139 140 /* Immediately exit if previous_freq is not initialized yet. */ 141 if (!devfreq->previous_freq) --- 19 unchanged lines hidden (view full) --- 161 devfreq->profile->max_state) + lev]++; 162 devfreq->total_trans++; 163 } 164 165out: 166 devfreq->last_stat_updated = cur_time; 167 return ret; 168} | 132{ 133 int lev, prev_lev, ret = 0; 134 unsigned long cur_time; 135 136 cur_time = jiffies; 137 138 /* Immediately exit if previous_freq is not initialized yet. */ 139 if (!devfreq->previous_freq) --- 19 unchanged lines hidden (view full) --- 159 devfreq->profile->max_state) + lev]++; 160 devfreq->total_trans++; 161 } 162 163out: 164 devfreq->last_stat_updated = cur_time; 165 return ret; 166} |
167EXPORT_SYMBOL(devfreq_update_status); |
|
169 170/** 171 * find_devfreq_governor() - find devfreq governor from name 172 * @name: name of the governor 173 * 174 * Search the list of devfreq governors and return the matched 175 * governor's pointer. devfreq_list_lock should be held by the caller. 176 */ --- 292 unchanged lines hidden (view full) --- 469 mutex_lock(&devfreq->lock); 470 ret = update_devfreq(devfreq); 471 mutex_unlock(&devfreq->lock); 472 473 return ret; 474} 475 476/** | 168 169/** 170 * find_devfreq_governor() - find devfreq governor from name 171 * @name: name of the governor 172 * 173 * Search the list of devfreq governors and return the matched 174 * governor's pointer. devfreq_list_lock should be held by the caller. 175 */ --- 292 unchanged lines hidden (view full) --- 468 mutex_lock(&devfreq->lock); 469 ret = update_devfreq(devfreq); 470 mutex_unlock(&devfreq->lock); 471 472 return ret; 473} 474 475/** |
477 * _remove_devfreq() - Remove devfreq from the list and release its resources. 478 * @devfreq: the devfreq struct | 476 * devfreq_dev_release() - Callback for struct device to release the device. 477 * @dev: the devfreq device 478 * 479 * Remove devfreq from the list and release its resources. |
479 */ | 480 */ |
480static void _remove_devfreq(struct devfreq *devfreq) | 481static void devfreq_dev_release(struct device *dev) |
481{ | 482{ |
483 struct devfreq *devfreq = to_devfreq(dev); 484 |
|
482 mutex_lock(&devfreq_list_lock); 483 if (IS_ERR(find_device_devfreq(devfreq->dev.parent))) { 484 mutex_unlock(&devfreq_list_lock); 485 dev_warn(&devfreq->dev, "releasing devfreq which doesn't exist\n"); 486 return; 487 } 488 list_del(&devfreq->node); 489 mutex_unlock(&devfreq_list_lock); --- 5 unchanged lines hidden (view full) --- 495 if (devfreq->profile->exit) 496 devfreq->profile->exit(devfreq->dev.parent); 497 498 mutex_destroy(&devfreq->lock); 499 kfree(devfreq); 500} 501 502/** | 485 mutex_lock(&devfreq_list_lock); 486 if (IS_ERR(find_device_devfreq(devfreq->dev.parent))) { 487 mutex_unlock(&devfreq_list_lock); 488 dev_warn(&devfreq->dev, "releasing devfreq which doesn't exist\n"); 489 return; 490 } 491 list_del(&devfreq->node); 492 mutex_unlock(&devfreq_list_lock); --- 5 unchanged lines hidden (view full) --- 498 if (devfreq->profile->exit) 499 devfreq->profile->exit(devfreq->dev.parent); 500 501 mutex_destroy(&devfreq->lock); 502 kfree(devfreq); 503} 504 505/** |
503 * devfreq_dev_release() - Callback for struct device to release the device. 504 * @dev: the devfreq device 505 * 506 * This calls _remove_devfreq() if _remove_devfreq() is not called. 507 */ 508static void devfreq_dev_release(struct device *dev) 509{ 510 struct devfreq *devfreq = to_devfreq(dev); 511 512 _remove_devfreq(devfreq); 513} 514 515/** | |
516 * devfreq_add_device() - Add devfreq feature to the device 517 * @dev: the device to add devfreq feature. 518 * @profile: device-specific profile to run devfreq. 519 * @governor_name: name of the policy to choose frequency. 520 * @data: private data for the governor. The devfreq framework does not 521 * touch this value. 522 */ 523struct devfreq *devfreq_add_device(struct device *dev, 524 struct devfreq_dev_profile *profile, 525 const char *governor_name, 526 void *data) 527{ 528 struct devfreq *devfreq; 529 struct devfreq_governor *governor; | 506 * devfreq_add_device() - Add devfreq feature to the device 507 * @dev: the device to add devfreq feature. 508 * @profile: device-specific profile to run devfreq. 509 * @governor_name: name of the policy to choose frequency. 510 * @data: private data for the governor. The devfreq framework does not 511 * touch this value. 512 */ 513struct devfreq *devfreq_add_device(struct device *dev, 514 struct devfreq_dev_profile *profile, 515 const char *governor_name, 516 void *data) 517{ 518 struct devfreq *devfreq; 519 struct devfreq_governor *governor; |
520 static atomic_t devfreq_no = ATOMIC_INIT(-1); |
|
530 int err = 0; 531 532 if (!dev || !profile || !governor_name) { 533 dev_err(dev, "%s: Invalid parameters.\n", __func__); 534 return ERR_PTR(-EINVAL); 535 } 536 537 mutex_lock(&devfreq_list_lock); 538 devfreq = find_device_devfreq(dev); 539 mutex_unlock(&devfreq_list_lock); 540 if (!IS_ERR(devfreq)) { | 521 int err = 0; 522 523 if (!dev || !profile || !governor_name) { 524 dev_err(dev, "%s: Invalid parameters.\n", __func__); 525 return ERR_PTR(-EINVAL); 526 } 527 528 mutex_lock(&devfreq_list_lock); 529 devfreq = find_device_devfreq(dev); 530 mutex_unlock(&devfreq_list_lock); 531 if (!IS_ERR(devfreq)) { |
541 dev_err(dev, "%s: Unable to create devfreq for the device. It already has one.\n", __func__); | 532 dev_err(dev, "%s: Unable to create devfreq for the device.\n", 533 __func__); |
542 err = -EINVAL; 543 goto err_out; 544 } 545 546 devfreq = kzalloc(sizeof(struct devfreq), GFP_KERNEL); 547 if (!devfreq) { | 534 err = -EINVAL; 535 goto err_out; 536 } 537 538 devfreq = kzalloc(sizeof(struct devfreq), GFP_KERNEL); 539 if (!devfreq) { |
548 dev_err(dev, "%s: Unable to create devfreq for the device\n", 549 __func__); | |
550 err = -ENOMEM; 551 goto err_out; 552 } 553 554 mutex_init(&devfreq->lock); 555 mutex_lock(&devfreq->lock); 556 devfreq->dev.parent = dev; 557 devfreq->dev.class = devfreq_class; --- 6 unchanged lines hidden (view full) --- 564 devfreq->nb.notifier_call = devfreq_notifier_call; 565 566 if (!devfreq->profile->max_state && !devfreq->profile->freq_table) { 567 mutex_unlock(&devfreq->lock); 568 devfreq_set_freq_table(devfreq); 569 mutex_lock(&devfreq->lock); 570 } 571 | 540 err = -ENOMEM; 541 goto err_out; 542 } 543 544 mutex_init(&devfreq->lock); 545 mutex_lock(&devfreq->lock); 546 devfreq->dev.parent = dev; 547 devfreq->dev.class = devfreq_class; --- 6 unchanged lines hidden (view full) --- 554 devfreq->nb.notifier_call = devfreq_notifier_call; 555 556 if (!devfreq->profile->max_state && !devfreq->profile->freq_table) { 557 mutex_unlock(&devfreq->lock); 558 devfreq_set_freq_table(devfreq); 559 mutex_lock(&devfreq->lock); 560 } 561 |
572 dev_set_name(&devfreq->dev, "%s", dev_name(dev)); | 562 dev_set_name(&devfreq->dev, "devfreq%d", 563 atomic_inc_return(&devfreq_no)); |
573 err = device_register(&devfreq->dev); 574 if (err) { 575 mutex_unlock(&devfreq->lock); 576 goto err_out; 577 } 578 | 564 err = device_register(&devfreq->dev); 565 if (err) { 566 mutex_unlock(&devfreq->lock); 567 goto err_out; 568 } 569 |
579 devfreq->trans_table = devm_kzalloc(&devfreq->dev, sizeof(unsigned int) * | 570 devfreq->trans_table = devm_kzalloc(&devfreq->dev, 571 sizeof(unsigned int) * |
580 devfreq->profile->max_state * 581 devfreq->profile->max_state, 582 GFP_KERNEL); | 572 devfreq->profile->max_state * 573 devfreq->profile->max_state, 574 GFP_KERNEL); |
583 devfreq->time_in_state = devm_kzalloc(&devfreq->dev, sizeof(unsigned long) * | 575 devfreq->time_in_state = devm_kzalloc(&devfreq->dev, 576 sizeof(unsigned long) * |
584 devfreq->profile->max_state, 585 GFP_KERNEL); 586 devfreq->last_stat_updated = jiffies; 587 588 srcu_init_notifier_head(&devfreq->transition_notifier_list); 589 590 mutex_unlock(&devfreq->lock); 591 --- 342 unchanged lines hidden (view full) --- 934 governor = find_devfreq_governor(str_governor); 935 if (IS_ERR(governor)) { 936 ret = PTR_ERR(governor); 937 goto out; 938 } 939 if (df->governor == governor) { 940 ret = 0; 941 goto out; | 577 devfreq->profile->max_state, 578 GFP_KERNEL); 579 devfreq->last_stat_updated = jiffies; 580 581 srcu_init_notifier_head(&devfreq->transition_notifier_list); 582 583 mutex_unlock(&devfreq->lock); 584 --- 342 unchanged lines hidden (view full) --- 927 governor = find_devfreq_governor(str_governor); 928 if (IS_ERR(governor)) { 929 ret = PTR_ERR(governor); 930 goto out; 931 } 932 if (df->governor == governor) { 933 ret = 0; 934 goto out; |
935 } else if (df->governor->immutable || governor->immutable) { 936 ret = -EINVAL; 937 goto out; |
|
942 } 943 944 if (df->governor) { 945 ret = df->governor->event_handler(df, DEVFREQ_GOV_STOP, NULL); 946 if (ret) { 947 dev_warn(dev, "%s: Governor %s not stopped(%d)\n", 948 __func__, df->governor->name, ret); 949 goto out; --- 13 unchanged lines hidden (view full) --- 963 return ret; 964} 965static DEVICE_ATTR_RW(governor); 966 967static ssize_t available_governors_show(struct device *d, 968 struct device_attribute *attr, 969 char *buf) 970{ | 938 } 939 940 if (df->governor) { 941 ret = df->governor->event_handler(df, DEVFREQ_GOV_STOP, NULL); 942 if (ret) { 943 dev_warn(dev, "%s: Governor %s not stopped(%d)\n", 944 __func__, df->governor->name, ret); 945 goto out; --- 13 unchanged lines hidden (view full) --- 959 return ret; 960} 961static DEVICE_ATTR_RW(governor); 962 963static ssize_t available_governors_show(struct device *d, 964 struct device_attribute *attr, 965 char *buf) 966{ |
971 struct devfreq_governor *tmp_governor; | 967 struct devfreq *df = to_devfreq(d); |
972 ssize_t count = 0; 973 974 mutex_lock(&devfreq_list_lock); | 968 ssize_t count = 0; 969 970 mutex_lock(&devfreq_list_lock); |
975 list_for_each_entry(tmp_governor, &devfreq_governor_list, node) 976 count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), 977 "%s ", tmp_governor->name); | 971 972 /* 973 * The devfreq with immutable governor (e.g., passive) shows 974 * only own governor. 975 */ 976 if (df->governor->immutable) { 977 count = scnprintf(&buf[count], DEVFREQ_NAME_LEN, 978 "%s ", df->governor_name); 979 /* 980 * The devfreq device shows the registered governor except for 981 * immutable governors such as passive governor . 982 */ 983 } else { 984 struct devfreq_governor *governor; 985 986 list_for_each_entry(governor, &devfreq_governor_list, node) { 987 if (governor->immutable) 988 continue; 989 count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), 990 "%s ", governor->name); 991 } 992 } 993 |
978 mutex_unlock(&devfreq_list_lock); 979 980 /* Truncate the trailing space */ 981 if (count) 982 count--; 983 984 count += sprintf(&buf[count], "\n"); 985 --- 4 unchanged lines hidden (view full) --- 990static ssize_t cur_freq_show(struct device *dev, struct device_attribute *attr, 991 char *buf) 992{ 993 unsigned long freq; 994 struct devfreq *devfreq = to_devfreq(dev); 995 996 if (devfreq->profile->get_cur_freq && 997 !devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq)) | 994 mutex_unlock(&devfreq_list_lock); 995 996 /* Truncate the trailing space */ 997 if (count) 998 count--; 999 1000 count += sprintf(&buf[count], "\n"); 1001 --- 4 unchanged lines hidden (view full) --- 1006static ssize_t cur_freq_show(struct device *dev, struct device_attribute *attr, 1007 char *buf) 1008{ 1009 unsigned long freq; 1010 struct devfreq *devfreq = to_devfreq(dev); 1011 1012 if (devfreq->profile->get_cur_freq && 1013 !devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq)) |
998 return sprintf(buf, "%lu\n", freq); | 1014 return sprintf(buf, "%lu\n", freq); |
999 1000 return sprintf(buf, "%lu\n", devfreq->previous_freq); 1001} 1002static DEVICE_ATTR_RO(cur_freq); 1003 1004static ssize_t target_freq_show(struct device *dev, 1005 struct device_attribute *attr, char *buf) 1006{ --- 100 unchanged lines hidden (view full) --- 1107 char *buf) 1108{ 1109 struct devfreq *df = to_devfreq(d); 1110 struct device *dev = df->dev.parent; 1111 struct dev_pm_opp *opp; 1112 ssize_t count = 0; 1113 unsigned long freq = 0; 1114 | 1015 1016 return sprintf(buf, "%lu\n", devfreq->previous_freq); 1017} 1018static DEVICE_ATTR_RO(cur_freq); 1019 1020static ssize_t target_freq_show(struct device *dev, 1021 struct device_attribute *attr, char *buf) 1022{ --- 100 unchanged lines hidden (view full) --- 1123 char *buf) 1124{ 1125 struct devfreq *df = to_devfreq(d); 1126 struct device *dev = df->dev.parent; 1127 struct dev_pm_opp *opp; 1128 ssize_t count = 0; 1129 unsigned long freq = 0; 1130 |
1115 rcu_read_lock(); | |
1116 do { 1117 opp = dev_pm_opp_find_freq_ceil(dev, &freq); 1118 if (IS_ERR(opp)) 1119 break; 1120 | 1131 do { 1132 opp = dev_pm_opp_find_freq_ceil(dev, &freq); 1133 if (IS_ERR(opp)) 1134 break; 1135 |
1136 dev_pm_opp_put(opp); |
|
1121 count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), 1122 "%lu ", freq); 1123 freq++; 1124 } while (1); | 1137 count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), 1138 "%lu ", freq); 1139 freq++; 1140 } while (1); |
1125 rcu_read_unlock(); | |
1126 1127 /* Truncate the trailing space */ 1128 if (count) 1129 count--; 1130 1131 count += sprintf(&buf[count], "\n"); 1132 1133 return count; --- 74 unchanged lines hidden (view full) --- 1208 } 1209 devfreq_class->dev_groups = devfreq_groups; 1210 1211 return 0; 1212} 1213subsys_initcall(devfreq_init); 1214 1215/* | 1141 1142 /* Truncate the trailing space */ 1143 if (count) 1144 count--; 1145 1146 count += sprintf(&buf[count], "\n"); 1147 1148 return count; --- 74 unchanged lines hidden (view full) --- 1223 } 1224 devfreq_class->dev_groups = devfreq_groups; 1225 1226 return 0; 1227} 1228subsys_initcall(devfreq_init); 1229 1230/* |
1216 * The followings are helper functions for devfreq user device drivers with | 1231 * The following are helper functions for devfreq user device drivers with |
1217 * OPP framework. 1218 */ 1219 1220/** 1221 * devfreq_recommended_opp() - Helper function to get proper OPP for the 1222 * freq value given to target callback. 1223 * @dev: The devfreq user device. (parent of devfreq) 1224 * @freq: The frequency given to target function 1225 * @flags: Flags handed from devfreq framework. 1226 * | 1232 * OPP framework. 1233 */ 1234 1235/** 1236 * devfreq_recommended_opp() - Helper function to get proper OPP for the 1237 * freq value given to target callback. 1238 * @dev: The devfreq user device. (parent of devfreq) 1239 * @freq: The frequency given to target function 1240 * @flags: Flags handed from devfreq framework. 1241 * |
1227 * Locking: This function must be called under rcu_read_lock(). opp is a rcu 1228 * protected pointer. The reason for the same is that the opp pointer which is 1229 * returned will remain valid for use with opp_get_{voltage, freq} only while 1230 * under the locked area. The pointer returned must be used prior to unlocking 1231 * with rcu_read_unlock() to maintain the integrity of the pointer. | 1242 * The callers are required to call dev_pm_opp_put() for the returned OPP after 1243 * use. |
1232 */ 1233struct dev_pm_opp *devfreq_recommended_opp(struct device *dev, 1234 unsigned long *freq, 1235 u32 flags) 1236{ 1237 struct dev_pm_opp *opp; 1238 1239 if (flags & DEVFREQ_FLAG_LEAST_UPPER_BOUND) { --- 20 unchanged lines hidden (view full) --- 1260 * devfreq_register_opp_notifier() - Helper function to get devfreq notified 1261 * for any changes in the OPP availability 1262 * changes 1263 * @dev: The devfreq user device. (parent of devfreq) 1264 * @devfreq: The devfreq object. 1265 */ 1266int devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq) 1267{ | 1244 */ 1245struct dev_pm_opp *devfreq_recommended_opp(struct device *dev, 1246 unsigned long *freq, 1247 u32 flags) 1248{ 1249 struct dev_pm_opp *opp; 1250 1251 if (flags & DEVFREQ_FLAG_LEAST_UPPER_BOUND) { --- 20 unchanged lines hidden (view full) --- 1272 * devfreq_register_opp_notifier() - Helper function to get devfreq notified 1273 * for any changes in the OPP availability 1274 * changes 1275 * @dev: The devfreq user device. (parent of devfreq) 1276 * @devfreq: The devfreq object. 1277 */ 1278int devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq) 1279{ |
1268 struct srcu_notifier_head *nh; 1269 int ret = 0; 1270 1271 rcu_read_lock(); 1272 nh = dev_pm_opp_get_notifier(dev); 1273 if (IS_ERR(nh)) 1274 ret = PTR_ERR(nh); 1275 rcu_read_unlock(); 1276 if (!ret) 1277 ret = srcu_notifier_chain_register(nh, &devfreq->nb); 1278 1279 return ret; | 1280 return dev_pm_opp_register_notifier(dev, &devfreq->nb); |
1280} 1281EXPORT_SYMBOL(devfreq_register_opp_notifier); 1282 1283/** 1284 * devfreq_unregister_opp_notifier() - Helper function to stop getting devfreq 1285 * notified for any changes in the OPP 1286 * availability changes anymore. 1287 * @dev: The devfreq user device. (parent of devfreq) 1288 * @devfreq: The devfreq object. 1289 * 1290 * At exit() callback of devfreq_dev_profile, this must be included if 1291 * devfreq_recommended_opp is used. 1292 */ 1293int devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq) 1294{ | 1281} 1282EXPORT_SYMBOL(devfreq_register_opp_notifier); 1283 1284/** 1285 * devfreq_unregister_opp_notifier() - Helper function to stop getting devfreq 1286 * notified for any changes in the OPP 1287 * availability changes anymore. 1288 * @dev: The devfreq user device. (parent of devfreq) 1289 * @devfreq: The devfreq object. 1290 * 1291 * At exit() callback of devfreq_dev_profile, this must be included if 1292 * devfreq_recommended_opp is used. 1293 */ 1294int devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq) 1295{ |
1295 struct srcu_notifier_head *nh; 1296 int ret = 0; 1297 1298 rcu_read_lock(); 1299 nh = dev_pm_opp_get_notifier(dev); 1300 if (IS_ERR(nh)) 1301 ret = PTR_ERR(nh); 1302 rcu_read_unlock(); 1303 if (!ret) 1304 ret = srcu_notifier_chain_unregister(nh, &devfreq->nb); 1305 1306 return ret; | 1296 return dev_pm_opp_unregister_notifier(dev, &devfreq->nb); |
1307} 1308EXPORT_SYMBOL(devfreq_unregister_opp_notifier); 1309 1310static void devm_devfreq_opp_release(struct device *dev, void *res) 1311{ 1312 devfreq_unregister_opp_notifier(dev, *(struct devfreq **)res); 1313} 1314 --- 165 unchanged lines hidden --- | 1297} 1298EXPORT_SYMBOL(devfreq_unregister_opp_notifier); 1299 1300static void devm_devfreq_opp_release(struct device *dev, void *res) 1301{ 1302 devfreq_unregister_opp_notifier(dev, *(struct devfreq **)res); 1303} 1304 --- 165 unchanged lines hidden --- |