kern_cpu.c (1196826af5daa03fe50b8225aa42b3f53d72a7ce) | kern_cpu.c (67c8649f7fb5783bd325211ad1edaf06018fcb3e) |
---|---|
1/*- 2 * Copyright (c) 2004-2005 Nate Lawson (SDG) 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 48 unchanged lines hidden (view full) --- 57 58struct cpufreq_softc { 59 struct cf_level curr_level; 60 int curr_priority; 61 struct cf_level saved_level; 62 int saved_priority; 63 struct cf_level_lst all_levels; 64 int all_count; | 1/*- 2 * Copyright (c) 2004-2005 Nate Lawson (SDG) 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 48 unchanged lines hidden (view full) --- 57 58struct cpufreq_softc { 59 struct cf_level curr_level; 60 int curr_priority; 61 struct cf_level saved_level; 62 int saved_priority; 63 struct cf_level_lst all_levels; 64 int all_count; |
65 int max_mhz; |
|
65 device_t dev; 66 struct sysctl_ctx_list sysctl_ctx; 67}; 68 69struct cf_setting_array { 70 struct cf_setting sets[MAX_SETTINGS]; 71 int count; 72 TAILQ_ENTRY(cf_setting_array) link; --- 45 unchanged lines hidden (view full) --- 118 119 sc = device_get_softc(dev); 120 parent = device_get_parent(dev); 121 sc->dev = dev; 122 sysctl_ctx_init(&sc->sysctl_ctx); 123 TAILQ_INIT(&sc->all_levels); 124 sc->curr_level.total_set.freq = CPUFREQ_VAL_UNKNOWN; 125 sc->saved_level.total_set.freq = CPUFREQ_VAL_UNKNOWN; | 66 device_t dev; 67 struct sysctl_ctx_list sysctl_ctx; 68}; 69 70struct cf_setting_array { 71 struct cf_setting sets[MAX_SETTINGS]; 72 int count; 73 TAILQ_ENTRY(cf_setting_array) link; --- 45 unchanged lines hidden (view full) --- 119 120 sc = device_get_softc(dev); 121 parent = device_get_parent(dev); 122 sc->dev = dev; 123 sysctl_ctx_init(&sc->sysctl_ctx); 124 TAILQ_INIT(&sc->all_levels); 125 sc->curr_level.total_set.freq = CPUFREQ_VAL_UNKNOWN; 126 sc->saved_level.total_set.freq = CPUFREQ_VAL_UNKNOWN; |
127 sc->max_mhz = CPUFREQ_VAL_UNKNOWN; |
|
126 127 /* 128 * Only initialize one set of sysctls for all CPUs. In the future, 129 * if multiple CPUs can have different settings, we can move these 130 * sysctls to be under every CPU instead of just the first one. 131 */ 132 numdevs = devclass_get_count(cpufreq_dc); 133 if (numdevs > 1) --- 291 unchanged lines hidden (view full) --- 425 default: 426 error = EINVAL; 427 break; 428 } 429 if (error) 430 goto out; 431 } 432 | 128 129 /* 130 * Only initialize one set of sysctls for all CPUs. In the future, 131 * if multiple CPUs can have different settings, we can move these 132 * sysctls to be under every CPU instead of just the first one. 133 */ 134 numdevs = devclass_get_count(cpufreq_dc); 135 if (numdevs > 1) --- 291 unchanged lines hidden (view full) --- 427 default: 428 error = EINVAL; 429 break; 430 } 431 if (error) 432 goto out; 433 } 434 |
433 /* If there are no absolute levels, create a fake one at 100%. */ | 435 /* 436 * If there are no absolute levels, create a fake one at 100%. We 437 * then cache the clockrate for later use as our base frequency. 438 * 439 * XXX This assumes that the first time through, if we only have 440 * relative drivers, the CPU is currently running at 100%. 441 */ |
434 if (TAILQ_EMPTY(&sc->all_levels)) { | 442 if (TAILQ_EMPTY(&sc->all_levels)) { |
435 bzero(&sets[0], sizeof(*sets)); 436 pc = cpu_get_pcpu(dev); 437 if (pc == NULL) { 438 error = ENXIO; 439 goto out; | 443 if (sc->max_mhz == CPUFREQ_VAL_UNKNOWN) { 444 pc = cpu_get_pcpu(dev); 445 cpu_est_clockrate(pc->pc_cpuid, &rate); 446 sc->max_mhz = rate / 1000000; |
440 } | 447 } |
441 cpu_est_clockrate(pc->pc_cpuid, &rate); 442 sets[0].freq = rate / 1000000; | 448 memset(&sets[0], CPUFREQ_VAL_UNKNOWN, sizeof(*sets)); 449 sets[0].freq = sc->max_mhz; 450 sets[0].dev = NULL; |
443 error = cpufreq_insert_abs(sc, sets, 1); 444 if (error) 445 goto out; 446 } 447 448 /* Create a combined list of absolute + relative levels. */ 449 TAILQ_FOREACH(set_arr, &rel_sets, link) 450 cpufreq_expand_set(sc, set_arr); --- 281 unchanged lines hidden (view full) --- 732 free(levels, M_TEMP); 733 sbuf_delete(&sb); 734 return (error); 735} 736 737int 738cpufreq_register(device_t dev) 739{ | 451 error = cpufreq_insert_abs(sc, sets, 1); 452 if (error) 453 goto out; 454 } 455 456 /* Create a combined list of absolute + relative levels. */ 457 TAILQ_FOREACH(set_arr, &rel_sets, link) 458 cpufreq_expand_set(sc, set_arr); --- 281 unchanged lines hidden (view full) --- 740 free(levels, M_TEMP); 741 sbuf_delete(&sb); 742 return (error); 743} 744 745int 746cpufreq_register(device_t dev) 747{ |
748 struct cpufreq_softc *sc; |
|
740 device_t cf_dev, cpu_dev; 741 742 /* 743 * Add only one cpufreq device to each CPU. Currently, all CPUs 744 * must offer the same levels and be switched at the same time. 745 */ 746 cpu_dev = device_get_parent(dev); | 749 device_t cf_dev, cpu_dev; 750 751 /* 752 * Add only one cpufreq device to each CPU. Currently, all CPUs 753 * must offer the same levels and be switched at the same time. 754 */ 755 cpu_dev = device_get_parent(dev); |
747 if (device_find_child(cpu_dev, "cpufreq", -1)) | 756 if ((cf_dev = device_find_child(cpu_dev, "cpufreq", -1))) { 757 sc = device_get_softc(cf_dev); 758 sc->max_mhz = CPUFREQ_VAL_UNKNOWN; |
748 return (0); | 759 return (0); |
760 } |
|
749 750 /* Add the child device and possibly sysctls. */ 751 cf_dev = BUS_ADD_CHILD(cpu_dev, 0, "cpufreq", -1); 752 if (cf_dev == NULL) 753 return (ENOMEM); 754 device_quiet(cf_dev); 755 756 return (device_probe_and_attach(cf_dev)); --- 9 unchanged lines hidden (view full) --- 766 /* 767 * If this is the last cpufreq child device, remove the control 768 * device as well. We identify cpufreq children by calling a method 769 * they support. 770 */ 771 error = device_get_children(device_get_parent(dev), &devs, &devcount); 772 if (error) 773 return (error); | 761 762 /* Add the child device and possibly sysctls. */ 763 cf_dev = BUS_ADD_CHILD(cpu_dev, 0, "cpufreq", -1); 764 if (cf_dev == NULL) 765 return (ENOMEM); 766 device_quiet(cf_dev); 767 768 return (device_probe_and_attach(cf_dev)); --- 9 unchanged lines hidden (view full) --- 778 /* 779 * If this is the last cpufreq child device, remove the control 780 * device as well. We identify cpufreq children by calling a method 781 * they support. 782 */ 783 error = device_get_children(device_get_parent(dev), &devs, &devcount); 784 if (error) 785 return (error); |
774 cf_dev = devclass_get_device(cpufreq_dc, 0); | 786 cf_dev = device_find_child(device_get_parent(dev), "cpufreq", -1); |
775 cfcount = 0; 776 for (i = 0; i < devcount; i++) { 777 if (!device_is_attached(devs[i])) 778 continue; 779 count = 1; 780 if (CPUFREQ_DRV_SETTINGS(devs[i], &set, &count, &type) == 0) 781 cfcount++; 782 } 783 if (cfcount <= 1) 784 device_delete_child(device_get_parent(cf_dev), cf_dev); 785 free(devs, M_TEMP); 786 787 return (0); 788} | 787 cfcount = 0; 788 for (i = 0; i < devcount; i++) { 789 if (!device_is_attached(devs[i])) 790 continue; 791 count = 1; 792 if (CPUFREQ_DRV_SETTINGS(devs[i], &set, &count, &type) == 0) 793 cfcount++; 794 } 795 if (cfcount <= 1) 796 device_delete_child(device_get_parent(cf_dev), cf_dev); 797 free(devs, M_TEMP); 798 799 return (0); 800} |