cancel_delayed_work_sync(&info->work);
 }
 
-static int spu_gov_govern(struct cpufreq_policy *policy, unsigned int event)
+static int spu_gov_start(struct cpufreq_policy *policy)
 {
        unsigned int cpu = policy->cpu;
-       struct spu_gov_info_struct *info, *affected_info;
+       struct spu_gov_info_struct *info = &per_cpu(spu_gov_info, cpu);
+       struct spu_gov_info_struct *affected_info;
        int i;
-       int ret = 0;
 
-       info = &per_cpu(spu_gov_info, cpu);
-
-       switch (event) {
-       case CPUFREQ_GOV_START:
-               if (!cpu_online(cpu)) {
-                       printk(KERN_ERR "cpu %d is not online\n", cpu);
-                       ret = -EINVAL;
-                       break;
-               }
+       if (!cpu_online(cpu)) {
+               printk(KERN_ERR "cpu %d is not online\n", cpu);
+               return -EINVAL;
+       }
 
-               if (!policy->cur) {
-                       printk(KERN_ERR "no cpu specified in policy\n");
-                       ret = -EINVAL;
-                       break;
-               }
+       if (!policy->cur) {
+               printk(KERN_ERR "no cpu specified in policy\n");
+               return -EINVAL;
+       }
 
-               /* initialize spu_gov_info for all affected cpus */
-               for_each_cpu(i, policy->cpus) {
-                       affected_info = &per_cpu(spu_gov_info, i);
-                       affected_info->policy = policy;
-               }
+       /* initialize spu_gov_info for all affected cpus */
+       for_each_cpu(i, policy->cpus) {
+               affected_info = &per_cpu(spu_gov_info, i);
+               affected_info->policy = policy;
+       }
 
-               info->poll_int = POLL_TIME;
+       info->poll_int = POLL_TIME;
 
-               /* setup timer */
-               spu_gov_init_work(info);
+       /* setup timer */
+       spu_gov_init_work(info);
 
-               break;
+       return 0;
+}
 
-       case CPUFREQ_GOV_STOP:
-               /* cancel timer */
-               spu_gov_cancel_work(info);
+static void spu_gov_stop(struct cpufreq_policy *policy)
+{
+       unsigned int cpu = policy->cpu;
+       struct spu_gov_info_struct *info = &per_cpu(spu_gov_info, cpu);
+       int i;
 
-               /* clean spu_gov_info for all affected cpus */
-               for_each_cpu (i, policy->cpus) {
-                       info = &per_cpu(spu_gov_info, i);
-                       info->policy = NULL;
-               }
+       /* cancel timer */
+       spu_gov_cancel_work(info);
 
-               break;
+       /* clean spu_gov_info for all affected cpus */
+       for_each_cpu (i, policy->cpus) {
+               info = &per_cpu(spu_gov_info, i);
+               info->policy = NULL;
        }
-
-       return ret;
 }
 
 static struct cpufreq_governor spu_governor = {
        .name = "spudemand",
-       .governor = spu_gov_govern,
+       .start = spu_gov_start,
+       .stop = spu_gov_stop,
        .owner = THIS_MODULE,
 };
 
 
 
        pr_debug("%s: for CPU %u\n", __func__, policy->cpu);
 
-       ret = policy->governor->governor(policy, CPUFREQ_GOV_POLICY_INIT);
-       if (ret) {
-               module_put(policy->governor->owner);
-               return ret;
+       if (policy->governor->init) {
+               ret = policy->governor->init(policy);
+               if (ret) {
+                       module_put(policy->governor->owner);
+                       return ret;
+               }
        }
 
        policy->governor->initialized++;
 
        pr_debug("%s: for CPU %u\n", __func__, policy->cpu);
 
-       policy->governor->governor(policy, CPUFREQ_GOV_POLICY_EXIT);
+       if (policy->governor->exit)
+               policy->governor->exit(policy);
 
        policy->governor->initialized--;
        module_put(policy->governor->owner);
        if (cpufreq_driver->get && !cpufreq_driver->setpolicy)
                cpufreq_update_current_freq(policy);
 
-       ret = policy->governor->governor(policy, CPUFREQ_GOV_START);
-       if (ret)
-               return ret;
+       if (policy->governor->start) {
+               ret = policy->governor->start(policy);
+               if (ret)
+                       return ret;
+       }
+
+       if (policy->governor->limits)
+               policy->governor->limits(policy);
 
-       policy->governor->governor(policy, CPUFREQ_GOV_LIMITS);
        return 0;
 }
 
 
        pr_debug("%s: for CPU %u\n", __func__, policy->cpu);
 
-       policy->governor->governor(policy, CPUFREQ_GOV_STOP);
+       if (policy->governor->stop)
+               policy->governor->stop(policy);
 }
 
 static void cpufreq_governor_limits(struct cpufreq_policy *policy)
 
        pr_debug("%s: for CPU %u\n", __func__, policy->cpu);
 
-       policy->governor->governor(policy, CPUFREQ_GOV_LIMITS);
+       if (policy->governor->limits)
+               policy->governor->limits(policy);
 }
 
 int cpufreq_register_governor(struct cpufreq_governor *governor)
 
 }
 
 static struct dbs_governor cs_dbs_gov = {
-       .gov = {
-               .name = "conservative",
-               .governor = cpufreq_governor_dbs,
-               .max_transition_latency = TRANSITION_LATENCY_LIMIT,
-               .owner = THIS_MODULE,
-       },
+       .gov = CPUFREQ_DBS_GOVERNOR_INITIALIZER("conservative"),
        .kobj_type = { .default_attrs = cs_attributes },
        .gov_dbs_timer = cs_dbs_timer,
        .alloc = cs_alloc,
 
        gov->free(policy_dbs);
 }
 
-static int cpufreq_governor_init(struct cpufreq_policy *policy)
+int cpufreq_dbs_governor_init(struct cpufreq_policy *policy)
 {
        struct dbs_governor *gov = dbs_governor_of(policy);
        struct dbs_data *dbs_data;
        mutex_unlock(&gov_dbs_data_mutex);
        return ret;
 }
+EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_init);
 
-static int cpufreq_governor_exit(struct cpufreq_policy *policy)
+void cpufreq_dbs_governor_exit(struct cpufreq_policy *policy)
 {
        struct dbs_governor *gov = dbs_governor_of(policy);
        struct policy_dbs_info *policy_dbs = policy->governor_data;
        free_policy_dbs_info(policy_dbs, gov);
 
        mutex_unlock(&gov_dbs_data_mutex);
-       return 0;
 }
+EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_exit);
 
-static int cpufreq_governor_start(struct cpufreq_policy *policy)
+int cpufreq_dbs_governor_start(struct cpufreq_policy *policy)
 {
        struct dbs_governor *gov = dbs_governor_of(policy);
        struct policy_dbs_info *policy_dbs = policy->governor_data;
        gov_set_update_util(policy_dbs, sampling_rate);
        return 0;
 }
+EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_start);
 
-static int cpufreq_governor_stop(struct cpufreq_policy *policy)
+void cpufreq_dbs_governor_stop(struct cpufreq_policy *policy)
 {
        gov_cancel_work(policy);
-       return 0;
 }
+EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_stop);
 
-static int cpufreq_governor_limits(struct cpufreq_policy *policy)
+void cpufreq_dbs_governor_limits(struct cpufreq_policy *policy)
 {
        struct policy_dbs_info *policy_dbs = policy->governor_data;
 
        gov_update_sample_delay(policy_dbs, 0);
 
        mutex_unlock(&policy_dbs->timer_mutex);
-
-       return 0;
-}
-
-int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event)
-{
-       if (event == CPUFREQ_GOV_POLICY_INIT) {
-               return cpufreq_governor_init(policy);
-       } else if (policy->governor_data) {
-               switch (event) {
-               case CPUFREQ_GOV_POLICY_EXIT:
-                       return cpufreq_governor_exit(policy);
-               case CPUFREQ_GOV_START:
-                       return cpufreq_governor_start(policy);
-               case CPUFREQ_GOV_STOP:
-                       return cpufreq_governor_stop(policy);
-               case CPUFREQ_GOV_LIMITS:
-                       return cpufreq_governor_limits(policy);
-               }
-       }
-       return -EINVAL;
 }
-EXPORT_SYMBOL_GPL(cpufreq_governor_dbs);
+EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_limits);
 
        return container_of(policy->governor, struct dbs_governor, gov);
 }
 
+/* Governor callback routines */
+int cpufreq_dbs_governor_init(struct cpufreq_policy *policy);
+void cpufreq_dbs_governor_exit(struct cpufreq_policy *policy);
+int cpufreq_dbs_governor_start(struct cpufreq_policy *policy);
+void cpufreq_dbs_governor_stop(struct cpufreq_policy *policy);
+void cpufreq_dbs_governor_limits(struct cpufreq_policy *policy);
+
+#define CPUFREQ_DBS_GOVERNOR_INITIALIZER(_name_)                       \
+       {                                                               \
+               .name = _name_,                                         \
+               .max_transition_latency = TRANSITION_LATENCY_LIMIT,     \
+               .owner = THIS_MODULE,                                   \
+               .init = cpufreq_dbs_governor_init,                      \
+               .exit = cpufreq_dbs_governor_exit,                      \
+               .start = cpufreq_dbs_governor_start,                    \
+               .stop = cpufreq_dbs_governor_stop,                      \
+               .limits = cpufreq_dbs_governor_limits,                  \
+       }
+
 /* Governor specific operations */
 struct od_ops {
        unsigned int (*powersave_bias_target)(struct cpufreq_policy *policy,
 };
 
 unsigned int dbs_update(struct cpufreq_policy *policy);
-int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event);
 void od_register_powersave_bias_handler(unsigned int (*f)
                (struct cpufreq_policy *, unsigned int, unsigned int),
                unsigned int powersave_bias);
 
 };
 
 static struct dbs_governor od_dbs_gov = {
-       .gov = {
-               .name = "ondemand",
-               .governor = cpufreq_governor_dbs,
-               .max_transition_latency = TRANSITION_LATENCY_LIMIT,
-               .owner = THIS_MODULE,
-       },
+       .gov = CPUFREQ_DBS_GOVERNOR_INITIALIZER("ondemand"),
        .kobj_type = { .default_attrs = od_attributes },
        .gov_dbs_timer = od_dbs_timer,
        .alloc = od_alloc,
 
 #include <linux/init.h>
 #include <linux/module.h>
 
-static int cpufreq_governor_performance(struct cpufreq_policy *policy,
-                                       unsigned int event)
+static void cpufreq_gov_performance_limits(struct cpufreq_policy *policy)
 {
-       switch (event) {
-       case CPUFREQ_GOV_LIMITS:
-               pr_debug("setting to %u kHz\n", policy->max);
-               __cpufreq_driver_target(policy, policy->max,
-                                               CPUFREQ_RELATION_H);
-               break;
-       default:
-               break;
-       }
-       return 0;
+       pr_debug("setting to %u kHz\n", policy->max);
+       __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H);
 }
 
 static struct cpufreq_governor cpufreq_gov_performance = {
        .name           = "performance",
-       .governor       = cpufreq_governor_performance,
        .owner          = THIS_MODULE,
+       .limits         = cpufreq_gov_performance_limits,
 };
 
 static int __init cpufreq_gov_performance_init(void)
 
 #include <linux/init.h>
 #include <linux/module.h>
 
-static int cpufreq_governor_powersave(struct cpufreq_policy *policy,
-                                       unsigned int event)
+static void cpufreq_gov_powersave_limits(struct cpufreq_policy *policy)
 {
-       switch (event) {
-       case CPUFREQ_GOV_LIMITS:
-               pr_debug("setting to %u kHz\n", policy->min);
-               __cpufreq_driver_target(policy, policy->min,
-                                               CPUFREQ_RELATION_L);
-               break;
-       default:
-               break;
-       }
-       return 0;
+       pr_debug("setting to %u kHz\n", policy->min);
+       __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L);
 }
 
 static struct cpufreq_governor cpufreq_gov_powersave = {
        .name           = "powersave",
-       .governor       = cpufreq_governor_powersave,
+       .limits         = cpufreq_gov_powersave_limits,
        .owner          = THIS_MODULE,
 };
 
 
        return 0;
 }
 
-static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
-                                  unsigned int event)
+static void cpufreq_userspace_policy_exit(struct cpufreq_policy *policy)
+{
+       mutex_lock(&userspace_mutex);
+       kfree(policy->governor_data);
+       policy->governor_data = NULL;
+       mutex_unlock(&userspace_mutex);
+}
+
+static int cpufreq_userspace_policy_start(struct cpufreq_policy *policy)
 {
        unsigned int *setspeed = policy->governor_data;
-       unsigned int cpu = policy->cpu;
-       int rc = 0;
 
-       if (event == CPUFREQ_GOV_POLICY_INIT)
-               return cpufreq_userspace_policy_init(policy);
+       BUG_ON(!policy->cur);
+       pr_debug("started managing cpu %u\n", policy->cpu);
 
-       if (!setspeed)
-               return -EINVAL;
-
-       switch (event) {
-       case CPUFREQ_GOV_POLICY_EXIT:
-               mutex_lock(&userspace_mutex);
-               policy->governor_data = NULL;
-               kfree(setspeed);
-               mutex_unlock(&userspace_mutex);
-               break;
-       case CPUFREQ_GOV_START:
-               BUG_ON(!policy->cur);
-               pr_debug("started managing cpu %u\n", cpu);
-
-               mutex_lock(&userspace_mutex);
-               per_cpu(cpu_is_managed, cpu) = 1;
-               *setspeed = policy->cur;
-               mutex_unlock(&userspace_mutex);
-               break;
-       case CPUFREQ_GOV_STOP:
-               pr_debug("managing cpu %u stopped\n", cpu);
-
-               mutex_lock(&userspace_mutex);
-               per_cpu(cpu_is_managed, cpu) = 0;
-               *setspeed = 0;
-               mutex_unlock(&userspace_mutex);
-               break;
-       case CPUFREQ_GOV_LIMITS:
-               mutex_lock(&userspace_mutex);
-               pr_debug("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n",
-                       cpu, policy->min, policy->max, policy->cur, *setspeed);
-
-               if (policy->max < *setspeed)
-                       __cpufreq_driver_target(policy, policy->max,
-                                               CPUFREQ_RELATION_H);
-               else if (policy->min > *setspeed)
-                       __cpufreq_driver_target(policy, policy->min,
-                                               CPUFREQ_RELATION_L);
-               else
-                       __cpufreq_driver_target(policy, *setspeed,
-                                               CPUFREQ_RELATION_L);
-               mutex_unlock(&userspace_mutex);
-               break;
-       }
-       return rc;
+       mutex_lock(&userspace_mutex);
+       per_cpu(cpu_is_managed, policy->cpu) = 1;
+       *setspeed = policy->cur;
+       mutex_unlock(&userspace_mutex);
+       return 0;
+}
+
+static void cpufreq_userspace_policy_stop(struct cpufreq_policy *policy)
+{
+       unsigned int *setspeed = policy->governor_data;
+
+       pr_debug("managing cpu %u stopped\n", policy->cpu);
+
+       mutex_lock(&userspace_mutex);
+       per_cpu(cpu_is_managed, policy->cpu) = 0;
+       *setspeed = 0;
+       mutex_unlock(&userspace_mutex);
+}
+
+static void cpufreq_userspace_policy_limits(struct cpufreq_policy *policy)
+{
+       unsigned int *setspeed = policy->governor_data;
+
+       mutex_lock(&userspace_mutex);
+
+       pr_debug("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n",
+                policy->cpu, policy->min, policy->max, policy->cur, *setspeed);
+
+       if (policy->max < *setspeed)
+               __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H);
+       else if (policy->min > *setspeed)
+               __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L);
+       else
+               __cpufreq_driver_target(policy, *setspeed, CPUFREQ_RELATION_L);
+
+       mutex_unlock(&userspace_mutex);
 }
 
 static struct cpufreq_governor cpufreq_gov_userspace = {
        .name           = "userspace",
-       .governor       = cpufreq_governor_userspace,
+       .init           = cpufreq_userspace_policy_init,
+       .exit           = cpufreq_userspace_policy_exit,
+       .start          = cpufreq_userspace_policy_start,
+       .stop           = cpufreq_userspace_policy_stop,
+       .limits         = cpufreq_userspace_policy_limits,
        .store_setspeed = cpufreq_set,
        .show_setspeed  = show_speed,
        .owner          = THIS_MODULE,
 
 #define MIN_LATENCY_MULTIPLIER         (20)
 #define TRANSITION_LATENCY_LIMIT       (10 * 1000 * 1000)
 
-/* Governor Events */
-#define CPUFREQ_GOV_START      1
-#define CPUFREQ_GOV_STOP       2
-#define CPUFREQ_GOV_LIMITS     3
-#define CPUFREQ_GOV_POLICY_INIT        4
-#define CPUFREQ_GOV_POLICY_EXIT        5
-
 struct cpufreq_governor {
        char    name[CPUFREQ_NAME_LEN];
        int     initialized;
-       int     (*governor)     (struct cpufreq_policy *policy,
-                                unsigned int event);
+       int     (*init)(struct cpufreq_policy *policy);
+       void    (*exit)(struct cpufreq_policy *policy);
+       int     (*start)(struct cpufreq_policy *policy);
+       void    (*stop)(struct cpufreq_policy *policy);
+       void    (*limits)(struct cpufreq_policy *policy);
        ssize_t (*show_setspeed)        (struct cpufreq_policy *policy,
                                         char *buf);
        int     (*store_setspeed)       (struct cpufreq_policy *policy,
 
        return ret;
 }
 
-static int sugov_exit(struct cpufreq_policy *policy)
+static void sugov_exit(struct cpufreq_policy *policy)
 {
        struct sugov_policy *sg_policy = policy->governor_data;
        struct sugov_tunables *tunables = sg_policy->tunables;
        mutex_unlock(&global_tunables_lock);
 
        sugov_policy_free(sg_policy);
-       return 0;
 }
 
 static int sugov_start(struct cpufreq_policy *policy)
        return 0;
 }
 
-static int sugov_stop(struct cpufreq_policy *policy)
+static void sugov_stop(struct cpufreq_policy *policy)
 {
        struct sugov_policy *sg_policy = policy->governor_data;
        unsigned int cpu;
 
        irq_work_sync(&sg_policy->irq_work);
        cancel_work_sync(&sg_policy->work);
-       return 0;
 }
 
-static int sugov_limits(struct cpufreq_policy *policy)
+static void sugov_limits(struct cpufreq_policy *policy)
 {
        struct sugov_policy *sg_policy = policy->governor_data;
 
        }
 
        sg_policy->need_freq_update = true;
-       return 0;
-}
-
-int sugov_governor(struct cpufreq_policy *policy, unsigned int event)
-{
-       if (event == CPUFREQ_GOV_POLICY_INIT) {
-               return sugov_init(policy);
-       } else if (policy->governor_data) {
-               switch (event) {
-               case CPUFREQ_GOV_POLICY_EXIT:
-                       return sugov_exit(policy);
-               case CPUFREQ_GOV_START:
-                       return sugov_start(policy);
-               case CPUFREQ_GOV_STOP:
-                       return sugov_stop(policy);
-               case CPUFREQ_GOV_LIMITS:
-                       return sugov_limits(policy);
-               }
-       }
-       return -EINVAL;
 }
 
 static struct cpufreq_governor schedutil_gov = {
        .name = "schedutil",
-       .governor = sugov_governor,
        .owner = THIS_MODULE,
+       .init = sugov_init,
+       .exit = sugov_exit,
+       .start = sugov_start,
+       .stop = sugov_stop,
+       .limits = sugov_limits,
 };
 
 static int __init sugov_module_init(void)