Mike Turquette <mturque...@ti.com> writes:

> Introduce notifier infrastructure for VDD voltage transitions.  Users can
> register a notifier prior to a VDD's volt_scale function getting called
> (VOLTSCALE_PRECHANGE) or after the VDD has been scaled
> (VOLTSCALE_POSTCHANGE).
>
> Signed-off-by: Mike Turquette <mturque...@ti.com>
> ---
> All patches in this series based on PM branch (b6fb54b) plus Vishwa's 13
> OMAP3 DVFS patches (http://marc.info/?l=linux-omap&m=129561825804975&w=2).
> Only validated on Zoom3 since OMAP4 DVFS patches were not available.
>
>  arch/arm/mach-omap2/voltage.c             |   47 
> ++++++++++++++++++++++++++++-
>  arch/arm/plat-omap/include/plat/voltage.h |   30 ++++++++++++++++++
>  2 files changed, 76 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
> index a0bd73b..0cbc58a 100644
> --- a/arch/arm/mach-omap2/voltage.c
> +++ b/arch/arm/mach-omap2/voltage.c
> @@ -729,6 +729,9 @@ static int __init omap3_vdd_data_configure(struct 
> omap_vdd_info *vdd)
>               return -EINVAL;
>       }
>  
> +     /* initialize the voltage change notifier chain */
> +     srcu_init_notifier_head(&vdd->volt_change_notify_chain);
> +

An explanation for the choice of SRCU notifiers would be useful.

Kevin

>       if (!strcmp(vdd->voltdm.name, "mpu")) {
>               if (cpu_is_omap3630()) {
>                       vdd->volt_data = omap36xx_vddmpu_volt_data;
> @@ -912,6 +915,9 @@ static int __init omap4_vdd_data_configure(struct 
> omap_vdd_info *vdd)
>               return -EINVAL;
>       }
>  
> +     /* initialize the voltage change notifier chain */
> +     srcu_init_notifier_head(&vdd->volt_change_notify_chain);
> +
>       if (!strcmp(vdd->voltdm.name, "mpu")) {
>               vdd->volt_data = omap44xx_vdd_mpu_volt_data;
>               vdd->vp_reg.tranxdone_status =
> @@ -1201,7 +1207,9 @@ void omap_vp_disable(struct voltagedomain *voltdm)
>  int omap_voltage_scale_vdd(struct voltagedomain *voltdm,
>               unsigned long target_volt)
>  {
> +     int ret;
>       struct omap_vdd_info *vdd;
> +     struct omap_volt_change_info v_info;
>  
>       if (!voltdm || IS_ERR(voltdm)) {
>               pr_warning("%s: VDD specified does not exist!\n", __func__);
> @@ -1216,7 +1224,20 @@ int omap_voltage_scale_vdd(struct voltagedomain 
> *voltdm,
>               return -ENODATA;
>       }
>  
> -     return vdd->volt_scale(vdd, target_volt);
> +     /* load notifier chain data */
> +     v_info.target_volt = target_volt;
> +     v_info.vdd = vdd;
> +
> +     srcu_notifier_call_chain(&vdd->volt_change_notify_chain,
> +                     VOLTSCALE_PRECHANGE, (void *)&v_info);
> +
> +     ret = vdd->volt_scale(vdd, target_volt);
> +
> +     if (!ret)
> +             srcu_notifier_call_chain(&vdd->volt_change_notify_chain,
> +                             VOLTSCALE_POSTCHANGE, (void *)&v_info);
> +
> +     return ret;
>  }
>  
>  /**
> @@ -1437,6 +1458,30 @@ struct voltagedomain *omap_voltage_domain_lookup(char 
> *name)
>       return ERR_PTR(-EINVAL);
>  }
>  
> +int omap_voltage_register_notifier(struct omap_vdd_info *vdd,
> +             struct notifier_block *nb)
> +{
> +     if (!vdd || IS_ERR(vdd)) {
> +             pr_warning("%s: invalid VDD specified\n", __func__);
> +             return -EINVAL;
> +     }
> +
> +     return srcu_notifier_chain_register(&vdd->volt_change_notify_chain,
> +                     nb);
> +}
> +
> +int omap_voltage_unregister_notifier(struct omap_vdd_info *vdd,
> +             struct notifier_block *nb)
> +{
> +     if (!vdd || IS_ERR(vdd)) {
> +             pr_warning("%s: invalid VDD specified\n", __func__);
> +             return -EINVAL;
> +     }
> +
> +     return srcu_notifier_chain_unregister(&vdd->volt_change_notify_chain,
> +                     nb);
> +}
> +
>  /**
>   * omap_voltage_late_init() - Init the various voltage parameters
>   *
> diff --git a/arch/arm/plat-omap/include/plat/voltage.h 
> b/arch/arm/plat-omap/include/plat/voltage.h
> index e0b7f22..017e65b 100644
> --- a/arch/arm/plat-omap/include/plat/voltage.h
> +++ b/arch/arm/plat-omap/include/plat/voltage.h
> @@ -15,10 +15,14 @@
>  #define __ARCH_ARM_MACH_OMAP2_VOLTAGE_H
>  
>  #include <linux/err.h>
> +#include <linux/notifier.h>
>  
>  #define VOLTSCALE_VPFORCEUPDATE              1
>  #define VOLTSCALE_VCBYPASS           2
>  
> +#define VOLTSCALE_PRECHANGE          0
> +#define VOLTSCALE_POSTCHANGE         1
> +
>  /*
>   * OMAP3 GENERIC setup times. Revisit to see if these needs to be
>   * passed from board or PMIC file
> @@ -249,6 +253,7 @@ struct omap_vdd_info {
>       struct vc_reg_info vc_reg;
>       struct voltagedomain voltdm;
>       struct omap_vdd_dep_info *dep_vdd_info;
> +     struct srcu_notifier_head volt_change_notify_chain;
>       int nr_dep_vdd;
>       struct dentry *debug_dir;
>       u32 curr_volt;
> @@ -261,6 +266,17 @@ struct omap_vdd_info {
>               unsigned long target_volt);
>  };
>  
> +/**
> + * omap_volt_change_info - container used by voltage notifier chain
> + *
> + * @vdd_info         : the voltage domain affected by the transition
> + * @target_volt              : voltage the affected domain is transitioning 
> to
> + */
> +struct omap_volt_change_info {
> +     unsigned long target_volt;
> +     struct omap_vdd_info *vdd;
> +};
> +
>  unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm);
>  void omap_vp_enable(struct voltagedomain *voltdm);
>  void omap_vp_disable(struct voltagedomain *voltdm);
> @@ -280,6 +296,10 @@ void omap_change_voltscale_method(struct voltagedomain 
> *voltdm,
>               int voltscale_method);
>  /* API to get the voltagedomain pointer */
>  struct voltagedomain *omap_voltage_domain_lookup(char *name);
> +int omap_voltage_register_notifier(struct omap_vdd_info *vdd,
> +             struct notifier_block *nb);
> +int omap_voltage_unregister_notifier(struct omap_vdd_info *vdd,
> +             struct notifier_block *nb);
>  
>  int omap_voltage_late_init(void);
>  #else
> @@ -298,6 +318,16 @@ static inline struct voltagedomain 
> *omap_voltage_domain_lookup(char *name)
>  {
>       return ERR_PTR(-EINVAL);
>  }
> +static inline int omap_voltage_register_notifier(struct omap_vdd_info *vdd,
> +             struct notifier block *nb)
> +{
> +     return 0;
> +}
> +static inline int omap_voltage_unregister_notifier(struct omap_vdd_info *vdd,
> +             struct notifier block *nb)
> +{
> +     return 0;
> +}
>  #endif
>  
>  #endif
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to