Forum: PC-Programmierung EmbeddedLinux iMX6: neue cpu policy bei reboot übernehmen


von And Z. (andifs)


Lesenswert?

Hallo,

bei unserem Board mit einem iMX6 und PMIC funktioniert der 
Software-Reboot nicht richtig. Als governor ist 'interactive' per 
default eingetragen. Wenn dieser die CPU Frequenz und Spannung(über 
PMIC) runterfährt, wird bei einem reboot der PMIC nicht mehr in einen 
default Zustand gesetzt (über I2C) und die CPU hat zu wenig Spannung bei 
booten und kann nicht mehr hochfahren.

Meine Idee war nun beim reboot den governor zu ändern und so den PMIC 
auf die richtige Versorgungsspannung zu setzen.
Ich hab das ganze schon ausprobiert. Wenn 'performance' Governor drin 
ist dann funktioniert der Software-Reboot super. Wenn 'powersave' drin 
ist dann kann der nicht mehr hochfahren.
Die aktuelle CPU Policy bekomme ich nun raus und kann auch eine neue 
policy erstellen und dieser dann den 'performance' Governor, der ja im 
system schon vorhanden ist, zuweisen.

Sieht ca so aus:
1
int mxc_reset_cpufreq(void)
2
{
3
  static struct cpufreq_policy *cur_cpu_policy;
4
  struct cpufreq_policy new_cpu_policy;
5
  static struct cpufreq_governor *avail_governor;
6
  const char *str_gov = "performance";
7
  int len = 0;
8
  
9
  len = strlen(str_gov);
10
  /* get the current cpufreq_policy and find
11
   * the 'performance' governor */
12
  cur_cpu_policy = cpufreq_cpu_get(0);
13
  avail_governor = __find_governor(str_gov);
14
15
  /*check if current governor is 'performance' */
16
  if(!strncasecmp(str_gov, cur_cpu_policy->governor->name,len)) {
17
    printk("GOV %s OK! Abbruch\n\n",cur_cpu_policy->governor->name);
18
//    return 0;
19
  }  
20
  /*check if 'perfomance' governor was found*/
21
  if(avail_governor == NULL) {
22
    printk("Cannot find gov: %s\n",str_gov);
23
    return -EINVAL;
24
  }
25
  /*copy current cpu policy*/
26
  memcpy(&new_cpu_policy,cur_cpu_policy,sizeof(struct cpufreq_policy));
27
  /*set 'performance' governor to new policy*/
28
  new_cpu_policy.governor = avail_governor;
29
    
30
  if(!cpufreq_set_policy(cur_cpu_policy, &new_cpu_policy))
31
  {
32
    cur_cpu_policy = cpufreq_cpu_get(0);
33
  }else{
34
    cur_cpu_policy = cpufreq_cpu_get(0); //TESTHALBER DRIN
35
  }
36
//HIER SIND AUCH NOCH PAAR PRINTKs DRIN...   
37
  
38
  
39
  return 0;
40
}

In der Funktion "cpufreq_set_policy(cur_cpu_policy, &new_cpu_policy)" 
wird die neue policy verifiziert mit "mxc_verify_speed" 
(arch/arm/plat-mxc/cpufreq.c) und "cpufreq_frequency_table_verify" 
(drivers/cpufreq/freq_table.c). So verstehe ich das zumindest....
In der letzteren Funktion wird mit "cpu_online(policy->cpu)" wohl irgend 
ein Zustand geprüft. Hierzu wird irgendeine cpu_online_mask oder sowas 
verwendet. Die Funktion gibt aber immer eine 0 zurück, sodass 
"cpufreq_frequency_table_verify" frühzeitig abbricht und der Governor 
nicht übernommen werden kann.

Mach ich das ganze übers terminal dann gibt die Funktion "cpu_online" 
eine 1 zurück und alles passt.

Warum gibt mir die Funktion eine 0 zurück? Kann mir bitte jemand 
helfen??
Wie kann ich beim SW-Reboot den governor umschalten?? (Ohne iwelche 
Skripte!!, im Kernel selbst)

Danke!


Andi

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.