This patch adds support for device registration of various smartreflex module present in the system. This patch introduces the platform data for smartreflex devices which include the efused n-target vaules, a parameter to indicate whether smartreflex autocompensation needs to be enabled on init or not. An API omap_enable_smartreflex_on_init is provided for the board files to enable smartreflex autocompensation during system boot up. Signed-off-by: Thara Gopinath <thara@xxxxxx> --- arch/arm/mach-omap2/Makefile | 2 +- arch/arm/mach-omap2/pm.c | 3 + arch/arm/mach-omap2/pm.h | 12 ++++ arch/arm/mach-omap2/sr_device.c | 131 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 147 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-omap2/sr_device.c diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index a14e98d..07205db 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -62,7 +62,7 @@ obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o voltage.o \ cpuidle34xx.o pm_bus.o obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o pm_bus.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o -obj-$(CONFIG_OMAP_SMARTREFLEX) += smartreflex.o +obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o AFLAGS_sleep24xx.o :=-Wa,-march=armv6 AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 1648a14..7c64533 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -22,6 +22,8 @@ #include <plat/clockdomain.h> #include <plat/voltage.h> +#include "pm.h" + static struct omap_device_pm_latency *pm_lats; static struct device *mpu_dev; @@ -149,6 +151,7 @@ postcore_initcall(omap2_common_pm_init); static int __init omap2_common_pm_late_init(void) { omap_voltage_late_init(); + omap_devinit_smartreflex(); return 0; } diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index a43e069..b19d46e 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -11,6 +11,7 @@ #ifndef __ARCH_ARM_MACH_OMAP2_PM_H #define __ARCH_ARM_MACH_OMAP2_PM_H +#include <linux/err.h> #include <plat/powerdomain.h> extern void *omap3_secure_ram_storage; @@ -99,4 +100,15 @@ extern unsigned int save_secure_ram_context_sz; extern unsigned int omap24xx_cpu_suspend_sz; extern unsigned int omap34xx_cpu_suspend_sz; +#ifdef CONFIG_OMAP_SMARTREFLEX +extern int omap_devinit_smartreflex(void); +extern void omap_enable_smartreflex_on_init(void); +#else +static inline int omap_devinit_smartreflex(void) +{ + return -EINVAL; +} + +static inline void omap_enable_smartreflex_on_init(void) {} +#endif #endif diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c new file mode 100644 index 0000000..9a3538f --- /dev/null +++ b/arch/arm/mach-omap2/sr_device.c @@ -0,0 +1,131 @@ +/* + * OMAP3/OMAP4 smartreflex device file + * + * Author: Thara Gopinath <thara@xxxxxx> + * + * Based originally on code from smartreflex.c + * Copyright (C) 2010 Texas Instruments, Inc. + * Thara Gopinath <thara@xxxxxx> + * + * Copyright (C) 2008 Nokia Corporation + * Kalle Jokiniemi + * + * Copyright (C) 2007 Texas Instruments, Inc. + * Lesly A M <x0080970@xxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/err.h> +#include <linux/slab.h> + +#include <plat/omap_device.h> +#include <plat/smartreflex.h> +#include <plat/voltage.h> + +#include "control.h" + +static bool sr_enable_on_init; + +static struct omap_device_pm_latency omap_sr_latency[] = { + { + .deactivate_func = omap_device_idle_hwmods, + .activate_func = omap_device_enable_hwmods, + .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST + }, +}; + +/* Read EFUSE values from control registers for OMAP3430 */ +static void __init sr_set_nvalues(struct omap_volt_data *volt_data, + struct omap_sr_data *sr_data) +{ + struct omap_sr_nvalue_table *nvalue_table; + int i, count = 0; + + while (volt_data[count].volt_nominal) + count++; + + nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count, + GFP_KERNEL); + + for (i = 0; i < count; i++) { + u32 v = omap_ctrl_readl(volt_data[i].sr_efuse_offs); + + nvalue_table[i].efuse_offs = volt_data[i].sr_efuse_offs; + nvalue_table[i].nvalue = v; + } + + sr_data->nvalue_table = nvalue_table; + sr_data->nvalue_count = count; +} + +static int sr_dev_init(struct omap_hwmod *oh, void *user) +{ + struct omap_sr_data *sr_data; + struct omap_device *od; + struct omap_volt_data *volt_data; + char *name = "smartreflex"; + static int i; + + sr_data = kzalloc(sizeof(struct omap_sr_data), GFP_KERNEL); + if (!sr_data) { + pr_err("%s: Unable to allocate memory for %s sr_data.Error!\n", + __func__, oh->name); + return -ENOMEM; + } + + if (!oh->vdd_name) { + pr_err("%s: No voltage domain specified for %s." + "Cannot initialize\n", __func__, oh->name); + goto exit; + } + + sr_data->ip_type = oh->class->rev; + sr_data->senn_mod = 0x1; + sr_data->senp_mod = 0x1; + + sr_data->voltdm = omap_voltage_domain_lookup(oh->vdd_name); + if (IS_ERR(sr_data->voltdm)) { + pr_err("%s: Unable to get voltage domain pointer for VDD %s\n", + __func__, oh->vdd_name); + goto exit; + } + + omap_voltage_get_volttable(sr_data->voltdm, &volt_data); + if (!volt_data) { + pr_warning("%s: No Voltage table registerd fo VDD%d." + "Something really wrong\n\n", __func__, i + 1); + goto exit; + } + + sr_set_nvalues(volt_data, sr_data); + + sr_data->enable_on_init = sr_enable_on_init; + + od = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data), + omap_sr_latency, + ARRAY_SIZE(omap_sr_latency), 0); + if (IS_ERR(od)) + pr_warning("%s: Could not build omap_device for %s: %s.\n\n", + __func__, name, oh->name); +exit: + i++; + kfree(sr_data); + return 0; +} + +/* + * API to be called from board files to enable smartreflex + * autocompensation at init. + */ +void __init omap_enable_smartreflex_on_init(void) +{ + sr_enable_on_init = true; +} + +int __init omap_devinit_smartreflex(void) +{ + return omap_hwmod_for_each_by_class("smartreflex", sr_dev_init, NULL); +} -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html