Loading arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +27 −4 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include "omap_hwmod_common_data.h" #include "smartreflex.h" #include "prm-regbits-34xx.h" #include "cm-regbits-34xx.h" #include "wd_timer.h" Loading Loading @@ -376,6 +377,16 @@ static struct omap_hwmod_ocp_if omap3_l4_core__i2c3 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; static struct omap_hwmod_irq_info omap3_smartreflex_mpu_irqs[] = { { .irq = 18}, { .irq = -1 } }; static struct omap_hwmod_irq_info omap3_smartreflex_core_irqs[] = { { .irq = 19}, { .irq = -1 } }; /* L4 CORE -> SR1 interface */ static struct omap_hwmod_addr_space omap3_sr1_addr_space[] = { { Loading Loading @@ -2664,6 +2675,10 @@ static struct omap_hwmod_class omap36xx_smartreflex_hwmod_class = { }; /* SR1 */ static struct omap_smartreflex_dev_attr sr1_dev_attr = { .sensor_voltdm_name = "mpu_iva", }; static struct omap_hwmod_ocp_if *omap3_sr1_slaves[] = { &omap3_l4_core__sr1, }; Loading @@ -2672,7 +2687,6 @@ static struct omap_hwmod omap34xx_sr1_hwmod = { .name = "sr1_hwmod", .class = &omap34xx_smartreflex_hwmod_class, .main_clk = "sr1_fck", .vdd_name = "mpu_iva", .prcm = { .omap2 = { .prcm_reg_id = 1, Loading @@ -2684,6 +2698,8 @@ static struct omap_hwmod omap34xx_sr1_hwmod = { }, .slaves = omap3_sr1_slaves, .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves), .dev_attr = &sr1_dev_attr, .mpu_irqs = omap3_smartreflex_mpu_irqs, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; Loading @@ -2691,7 +2707,6 @@ static struct omap_hwmod omap36xx_sr1_hwmod = { .name = "sr1_hwmod", .class = &omap36xx_smartreflex_hwmod_class, .main_clk = "sr1_fck", .vdd_name = "mpu_iva", .prcm = { .omap2 = { .prcm_reg_id = 1, Loading @@ -2703,9 +2718,15 @@ static struct omap_hwmod omap36xx_sr1_hwmod = { }, .slaves = omap3_sr1_slaves, .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves), .dev_attr = &sr1_dev_attr, .mpu_irqs = omap3_smartreflex_mpu_irqs, }; /* SR2 */ static struct omap_smartreflex_dev_attr sr2_dev_attr = { .sensor_voltdm_name = "core", }; static struct omap_hwmod_ocp_if *omap3_sr2_slaves[] = { &omap3_l4_core__sr2, }; Loading @@ -2714,7 +2735,6 @@ static struct omap_hwmod omap34xx_sr2_hwmod = { .name = "sr2_hwmod", .class = &omap34xx_smartreflex_hwmod_class, .main_clk = "sr2_fck", .vdd_name = "core", .prcm = { .omap2 = { .prcm_reg_id = 1, Loading @@ -2726,6 +2746,8 @@ static struct omap_hwmod omap34xx_sr2_hwmod = { }, .slaves = omap3_sr2_slaves, .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves), .dev_attr = &sr2_dev_attr, .mpu_irqs = omap3_smartreflex_core_irqs, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; Loading @@ -2733,7 +2755,6 @@ static struct omap_hwmod omap36xx_sr2_hwmod = { .name = "sr2_hwmod", .class = &omap36xx_smartreflex_hwmod_class, .main_clk = "sr2_fck", .vdd_name = "core", .prcm = { .omap2 = { .prcm_reg_id = 1, Loading @@ -2745,6 +2766,8 @@ static struct omap_hwmod omap36xx_sr2_hwmod = { }, .slaves = omap3_sr2_slaves, .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves), .dev_attr = &sr2_dev_attr, .mpu_irqs = omap3_smartreflex_core_irqs, }; /* Loading arch/arm/mach-omap2/omap_hwmod_44xx_data.c +16 −3 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ #include "omap_hwmod_common_data.h" #include "smartreflex.h" #include "cm1_44xx.h" #include "cm2_44xx.h" #include "prm44xx.h" Loading Loading @@ -3963,6 +3964,10 @@ static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = { }; /* smartreflex_core */ static struct omap_smartreflex_dev_attr smartreflex_core_dev_attr = { .sensor_voltdm_name = "core", }; static struct omap_hwmod omap44xx_smartreflex_core_hwmod; static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = { { .irq = 19 + OMAP44XX_IRQ_GIC_START }, Loading Loading @@ -3999,7 +4004,6 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = { .mpu_irqs = omap44xx_smartreflex_core_irqs, .main_clk = "smartreflex_core_fck", .vdd_name = "core", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET, Loading @@ -4009,9 +4013,14 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = { }, .slaves = omap44xx_smartreflex_core_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_slaves), .dev_attr = &smartreflex_core_dev_attr, }; /* smartreflex_iva */ static struct omap_smartreflex_dev_attr smartreflex_iva_dev_attr = { .sensor_voltdm_name = "iva", }; static struct omap_hwmod omap44xx_smartreflex_iva_hwmod; static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = { { .irq = 102 + OMAP44XX_IRQ_GIC_START }, Loading Loading @@ -4047,7 +4056,6 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = { .clkdm_name = "l4_ao_clkdm", .mpu_irqs = omap44xx_smartreflex_iva_irqs, .main_clk = "smartreflex_iva_fck", .vdd_name = "iva", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET, Loading @@ -4057,9 +4065,14 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = { }, .slaves = omap44xx_smartreflex_iva_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_slaves), .dev_attr = &smartreflex_iva_dev_attr, }; /* smartreflex_mpu */ static struct omap_smartreflex_dev_attr smartreflex_mpu_dev_attr = { .sensor_voltdm_name = "mpu", }; static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod; static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = { { .irq = 18 + OMAP44XX_IRQ_GIC_START }, Loading Loading @@ -4095,7 +4108,6 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = { .clkdm_name = "l4_ao_clkdm", .mpu_irqs = omap44xx_smartreflex_mpu_irqs, .main_clk = "smartreflex_mpu_fck", .vdd_name = "mpu", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET, Loading @@ -4105,6 +4117,7 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = { }, .slaves = omap44xx_smartreflex_mpu_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_slaves), .dev_attr = &smartreflex_mpu_dev_attr, }; /* Loading arch/arm/mach-omap2/smartreflex-class3.c +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ static int sr_class3_enable(struct voltagedomain *voltdm) static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset) { sr_disable_errgen(voltdm); omap_vp_disable(voltdm); sr_disable(voltdm); if (is_volt_reset) Loading arch/arm/mach-omap2/smartreflex.c +168 −59 Original line number Diff line number Diff line Loading @@ -36,6 +36,12 @@ #define SR_DISABLE_TIMEOUT 200 struct omap_sr { struct list_head node; struct platform_device *pdev; struct omap_sr_nvalue_table *nvalue_table; struct voltagedomain *voltdm; struct dentry *dbg_dir; unsigned int irq; int srid; int ip_type; int nvalue_count; Loading @@ -49,13 +55,7 @@ struct omap_sr { u32 senp_avgweight; u32 senp_mod; u32 senn_mod; unsigned int irq; void __iomem *base; struct platform_device *pdev; struct list_head node; struct omap_sr_nvalue_table *nvalue_table; struct voltagedomain *voltdm; struct dentry *dbg_dir; }; /* sr_list contains all the instances of smartreflex module */ Loading @@ -74,10 +74,6 @@ static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask, u32 value) { u32 reg_val; u32 errconfig_offs = 0, errconfig_mask = 0; reg_val = __raw_readl(sr->base + offset); reg_val &= ~mask; /* * Smartreflex error config register is special as it contains Loading @@ -88,16 +84,15 @@ static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask, * if they are currently set, but does allow the caller to write * those bits. */ if (sr->ip_type == SR_TYPE_V1) { errconfig_offs = ERRCONFIG_V1; errconfig_mask = ERRCONFIG_STATUS_V1_MASK; } else if (sr->ip_type == SR_TYPE_V2) { errconfig_offs = ERRCONFIG_V2; errconfig_mask = ERRCONFIG_VPBOUNDINTST_V2; } if (sr->ip_type == SR_TYPE_V1 && offset == ERRCONFIG_V1) mask |= ERRCONFIG_STATUS_V1_MASK; else if (sr->ip_type == SR_TYPE_V2 && offset == ERRCONFIG_V2) mask |= ERRCONFIG_VPBOUNDINTST_V2; if (offset == errconfig_offs) reg_val &= ~errconfig_mask; reg_val = __raw_readl(sr->base + offset); reg_val &= ~mask; value &= mask; reg_val |= value; Loading Loading @@ -128,21 +123,28 @@ static struct omap_sr *_sr_lookup(struct voltagedomain *voltdm) static irqreturn_t sr_interrupt(int irq, void *data) { struct omap_sr *sr_info = (struct omap_sr *)data; struct omap_sr *sr_info = data; u32 status = 0; if (sr_info->ip_type == SR_TYPE_V1) { switch (sr_info->ip_type) { case SR_TYPE_V1: /* Read the status bits */ status = sr_read_reg(sr_info, ERRCONFIG_V1); /* Clear them by writing back */ sr_write_reg(sr_info, ERRCONFIG_V1, status); } else if (sr_info->ip_type == SR_TYPE_V2) { break; case SR_TYPE_V2: /* Read the status bits */ status = sr_read_reg(sr_info, IRQSTATUS); /* Clear them by writing back */ sr_write_reg(sr_info, IRQSTATUS, status); break; default: dev_err(&sr_info->pdev->dev, "UNKNOWN IP type %d\n", sr_info->ip_type); return IRQ_NONE; } if (sr_class->notify) Loading @@ -166,6 +168,7 @@ static void sr_set_clk_length(struct omap_sr *sr) __func__); return; } sys_clk_speed = clk_get_rate(sys_ck); clk_put(sys_ck); Loading Loading @@ -267,7 +270,7 @@ static int sr_late_init(struct omap_sr *sr_info) goto error; } ret = request_irq(sr_info->irq, sr_interrupt, 0, name, (void *)sr_info); 0, name, sr_info); if (ret) goto error; disable_irq(sr_info->irq); Loading @@ -288,12 +291,15 @@ static int sr_late_init(struct omap_sr *sr_info) "not function as desired\n", __func__); kfree(name); kfree(sr_info); return ret; } static void sr_v1_disable(struct omap_sr *sr) { int timeout = 0; int errconf_val = ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST | ERRCONFIG_MCUBOUNDINTST; /* Enable MCUDisableAcknowledge interrupt */ sr_modify_reg(sr, ERRCONFIG_V1, Loading @@ -302,13 +308,13 @@ static void sr_v1_disable(struct omap_sr *sr) /* SRCONFIG - disable SR */ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0); /* Disable all other SR interrupts and clear the status */ /* Disable all other SR interrupts and clear the status as needed */ if (sr_read_reg(sr, ERRCONFIG_V1) & ERRCONFIG_VPBOUNDINTST_V1) errconf_val |= ERRCONFIG_VPBOUNDINTST_V1; sr_modify_reg(sr, ERRCONFIG_V1, (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1), (ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST | ERRCONFIG_MCUBOUNDINTST | ERRCONFIG_VPBOUNDINTST_V1)); errconf_val); /* * Wait for SR to be disabled. Loading Loading @@ -337,9 +343,17 @@ static void sr_v2_disable(struct omap_sr *sr) /* SRCONFIG - disable SR */ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0); /* Disable all other SR interrupts and clear the status */ /* * Disable all other SR interrupts and clear the status * write to status register ONLY on need basis - only if status * is set. */ if (sr_read_reg(sr, ERRCONFIG_V2) & ERRCONFIG_VPBOUNDINTST_V2) sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2, ERRCONFIG_VPBOUNDINTST_V2); else sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2, 0x0); sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT | IRQENABLE_MCUBOUNDSINT)); Loading Loading @@ -398,15 +412,16 @@ static u32 sr_retrieve_nvalue(struct omap_sr *sr, u32 efuse_offs) */ int sr_configure_errgen(struct voltagedomain *voltdm) { u32 sr_config, sr_errconfig, errconfig_offs, vpboundint_en; u32 vpboundint_st, senp_en = 0, senn_en = 0; u32 sr_config, sr_errconfig, errconfig_offs; u32 vpboundint_en, vpboundint_st; u32 senp_en = 0, senn_en = 0; u8 senp_shift, senn_shift; struct omap_sr *sr = _sr_lookup(voltdm); if (IS_ERR(sr)) { pr_warning("%s: omap_sr struct for sr_%s not found\n", __func__, voltdm->name); return -EINVAL; return PTR_ERR(sr); } if (!sr->clk_length) Loading @@ -418,20 +433,23 @@ int sr_configure_errgen(struct voltagedomain *voltdm) sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) | SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN; if (sr->ip_type == SR_TYPE_V1) { switch (sr->ip_type) { case SR_TYPE_V1: sr_config |= SRCONFIG_DELAYCTRL; senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT; senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT; errconfig_offs = ERRCONFIG_V1; vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1; vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1; } else if (sr->ip_type == SR_TYPE_V2) { break; case SR_TYPE_V2: senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT; senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT; errconfig_offs = ERRCONFIG_V2; vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2; vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2; } else { break; default: dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" "module without specifying the ip\n", __func__); return -EINVAL; Loading @@ -447,8 +465,55 @@ int sr_configure_errgen(struct voltagedomain *voltdm) sr_errconfig); /* Enabling the interrupts if the ERROR module is used */ sr_modify_reg(sr, errconfig_offs, vpboundint_en, (vpboundint_en | vpboundint_st)); sr_modify_reg(sr, errconfig_offs, (vpboundint_en | vpboundint_st), vpboundint_en); return 0; } /** * sr_disable_errgen() - Disables SmartReflex AVS module's errgen component * @voltdm: VDD pointer to which the SR module to be configured belongs to. * * This API is to be called from the smartreflex class driver to * disable the error generator module inside the smartreflex module. * * Returns 0 on success and error value in case of failure. */ int sr_disable_errgen(struct voltagedomain *voltdm) { u32 errconfig_offs; u32 vpboundint_en, vpboundint_st; struct omap_sr *sr = _sr_lookup(voltdm); if (IS_ERR(sr)) { pr_warning("%s: omap_sr struct for sr_%s not found\n", __func__, voltdm->name); return PTR_ERR(sr); } switch (sr->ip_type) { case SR_TYPE_V1: errconfig_offs = ERRCONFIG_V1; vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1; vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1; break; case SR_TYPE_V2: errconfig_offs = ERRCONFIG_V2; vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2; vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2; break; default: dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" "module without specifying the ip\n", __func__); return -EINVAL; } /* Disable the interrupts of ERROR module */ sr_modify_reg(sr, errconfig_offs, vpboundint_en | vpboundint_st, 0); /* Disable the Sensor and errorgen */ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN, 0); return 0; } Loading @@ -475,7 +540,7 @@ int sr_configure_minmax(struct voltagedomain *voltdm) if (IS_ERR(sr)) { pr_warning("%s: omap_sr struct for sr_%s not found\n", __func__, voltdm->name); return -EINVAL; return PTR_ERR(sr); } if (!sr->clk_length) Loading @@ -488,14 +553,17 @@ int sr_configure_minmax(struct voltagedomain *voltdm) SRCONFIG_SENENABLE | (sr->accum_data << SRCONFIG_ACCUMDATA_SHIFT); if (sr->ip_type == SR_TYPE_V1) { switch (sr->ip_type) { case SR_TYPE_V1: sr_config |= SRCONFIG_DELAYCTRL; senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT; senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT; } else if (sr->ip_type == SR_TYPE_V2) { break; case SR_TYPE_V2: senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT; senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT; } else { break; default: dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" "module without specifying the ip\n", __func__); return -EINVAL; Loading @@ -511,20 +579,27 @@ int sr_configure_minmax(struct voltagedomain *voltdm) * Enabling the interrupts if MINMAXAVG module is used. * TODO: check if all the interrupts are mandatory */ if (sr->ip_type == SR_TYPE_V1) { switch (sr->ip_type) { case SR_TYPE_V1: sr_modify_reg(sr, ERRCONFIG_V1, (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUBOUNDINTEN), (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST | ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST)); } else if (sr->ip_type == SR_TYPE_V2) { break; case SR_TYPE_V2: sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUACCUMINT | IRQSTATUS_MCVALIDINT | IRQSTATUS_MCBOUNDSINT | IRQSTATUS_MCUDISABLEACKINT); sr_write_reg(sr, IRQENABLE_SET, IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT | IRQENABLE_MCUBOUNDSINT | IRQENABLE_MCUDISABLEACKINT); break; default: dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" "module without specifying the ip\n", __func__); return -EINVAL; } return 0; Loading @@ -543,15 +618,15 @@ int sr_configure_minmax(struct voltagedomain *voltdm) */ int sr_enable(struct voltagedomain *voltdm, unsigned long volt) { u32 nvalue_reciprocal; struct omap_volt_data *volt_data; struct omap_sr *sr = _sr_lookup(voltdm); u32 nvalue_reciprocal; int ret; if (IS_ERR(sr)) { pr_warning("%s: omap_sr struct for sr_%s not found\n", __func__, voltdm->name); return -EINVAL; return PTR_ERR(sr); } volt_data = omap_voltage_get_voltdata(sr->voltdm, volt); Loading @@ -559,7 +634,7 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt) if (IS_ERR(volt_data)) { dev_warn(&sr->pdev->dev, "%s: Unable to get voltage table" "for nominal voltage %ld\n", __func__, volt); return -ENODATA; return PTR_ERR(volt_data); } nvalue_reciprocal = sr_retrieve_nvalue(sr, volt_data->sr_efuse_offs); Loading Loading @@ -617,10 +692,17 @@ void sr_disable(struct voltagedomain *voltdm) * disable the clocks. */ if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE) { if (sr->ip_type == SR_TYPE_V1) switch (sr->ip_type) { case SR_TYPE_V1: sr_v1_disable(sr); else if (sr->ip_type == SR_TYPE_V2) break; case SR_TYPE_V2: sr_v2_disable(sr); break; default: dev_err(&sr->pdev->dev, "UNKNOWN IP type %d\n", sr->ip_type); } } pm_runtime_put_sync_suspend(&sr->pdev->dev); Loading Loading @@ -779,10 +861,10 @@ void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data) sr_pmic_data = pmic_data; } /* PM Debug Fs enteries to enable disable smartreflex. */ /* PM Debug FS entries to enable and disable smartreflex. */ static int omap_sr_autocomp_show(void *data, u64 *val) { struct omap_sr *sr_info = (struct omap_sr *) data; struct omap_sr *sr_info = data; if (!sr_info) { pr_warning("%s: omap_sr struct not found\n", __func__); Loading @@ -796,7 +878,7 @@ static int omap_sr_autocomp_show(void *data, u64 *val) static int omap_sr_autocomp_store(void *data, u64 val) { struct omap_sr *sr_info = (struct omap_sr *) data; struct omap_sr *sr_info = data; if (!sr_info) { pr_warning("%s: omap_sr struct not found\n", __func__); Loading @@ -804,7 +886,7 @@ static int omap_sr_autocomp_store(void *data, u64 val) } /* Sanity check */ if (val && (val != 1)) { if (val > 1) { pr_warning("%s: Invalid argument %lld\n", __func__, val); return -EINVAL; } Loading @@ -825,7 +907,7 @@ DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show, static int __init omap_sr_probe(struct platform_device *pdev) { struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); struct omap_sr *sr_info; struct omap_sr_data *pdata = pdev->dev.platform_data; struct resource *mem, *irq; struct dentry *nvalue_dir; Loading @@ -833,12 +915,15 @@ static int __init omap_sr_probe(struct platform_device *pdev) int i, ret = 0; char *name; sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); if (!sr_info) { dev_err(&pdev->dev, "%s: unable to allocate sr_info\n", __func__); return -ENOMEM; } platform_set_drvdata(pdev, sr_info); if (!pdata) { dev_err(&pdev->dev, "%s: platform data missing\n", __func__); ret = -EINVAL; Loading Loading @@ -904,7 +989,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__); if (!sr_dbg_dir) { sr_dbg_dir = debugfs_create_dir("smartreflex", NULL); if (!sr_dbg_dir) { if (IS_ERR_OR_NULL(sr_dbg_dir)) { ret = PTR_ERR(sr_dbg_dir); pr_err("%s:sr debugfs dir creation failed(%d)\n", __func__, ret); Loading @@ -921,7 +1006,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) } sr_info->dbg_dir = debugfs_create_dir(name, sr_dbg_dir); kfree(name); if (IS_ERR(sr_info->dbg_dir)) { if (IS_ERR_OR_NULL(sr_info->dbg_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", __func__); ret = PTR_ERR(sr_info->dbg_dir); Loading @@ -938,7 +1023,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) &sr_info->err_minlimit); nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir); if (IS_ERR(nvalue_dir)) { if (IS_ERR_OR_NULL(nvalue_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory" "for n-values\n", __func__); ret = PTR_ERR(nvalue_dir); Loading Loading @@ -994,7 +1079,7 @@ static int __devexit omap_sr_remove(struct platform_device *pdev) if (IS_ERR(sr_info)) { dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", __func__); return -EINVAL; return PTR_ERR(sr_info); } if (sr_info->autocomp_active) Loading @@ -1011,8 +1096,32 @@ static int __devexit omap_sr_remove(struct platform_device *pdev) return 0; } static void __devexit omap_sr_shutdown(struct platform_device *pdev) { struct omap_sr_data *pdata = pdev->dev.platform_data; struct omap_sr *sr_info; if (!pdata) { dev_err(&pdev->dev, "%s: platform data missing\n", __func__); return; } sr_info = _sr_lookup(pdata->voltdm); if (IS_ERR(sr_info)) { dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", __func__); return; } if (sr_info->autocomp_active) sr_stop_vddautocomp(sr_info); return; } static struct platform_driver smartreflex_driver = { .remove = __devexit_p(omap_sr_remove), .shutdown = __devexit_p(omap_sr_shutdown), .driver = { .name = "smartreflex", }, Loading Loading @@ -1042,12 +1151,12 @@ static int __init sr_init(void) return 0; } late_initcall(sr_init); static void __exit sr_exit(void) { platform_driver_unregister(&smartreflex_driver); } late_initcall(sr_init); module_exit(sr_exit); MODULE_DESCRIPTION("OMAP Smartreflex Driver"); Loading arch/arm/mach-omap2/smartreflex.h +10 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,15 @@ struct omap_sr_pmic_data { void (*sr_pmic_init) (void); }; /** * struct omap_smartreflex_dev_attr - Smartreflex Device attribute. * * @sensor_voltdm_name: Name of voltdomain of SR instance */ struct omap_smartreflex_dev_attr { const char *sensor_voltdm_name; }; #ifdef CONFIG_OMAP_SMARTREFLEX /* * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR. Loading Loading @@ -231,6 +240,7 @@ void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data); int sr_enable(struct voltagedomain *voltdm, unsigned long volt); void sr_disable(struct voltagedomain *voltdm); int sr_configure_errgen(struct voltagedomain *voltdm); int sr_disable_errgen(struct voltagedomain *voltdm); int sr_configure_minmax(struct voltagedomain *voltdm); /* API to register the smartreflex class driver with the smartreflex driver */ Loading Loading
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +27 −4 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include "omap_hwmod_common_data.h" #include "smartreflex.h" #include "prm-regbits-34xx.h" #include "cm-regbits-34xx.h" #include "wd_timer.h" Loading Loading @@ -376,6 +377,16 @@ static struct omap_hwmod_ocp_if omap3_l4_core__i2c3 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; static struct omap_hwmod_irq_info omap3_smartreflex_mpu_irqs[] = { { .irq = 18}, { .irq = -1 } }; static struct omap_hwmod_irq_info omap3_smartreflex_core_irqs[] = { { .irq = 19}, { .irq = -1 } }; /* L4 CORE -> SR1 interface */ static struct omap_hwmod_addr_space omap3_sr1_addr_space[] = { { Loading Loading @@ -2664,6 +2675,10 @@ static struct omap_hwmod_class omap36xx_smartreflex_hwmod_class = { }; /* SR1 */ static struct omap_smartreflex_dev_attr sr1_dev_attr = { .sensor_voltdm_name = "mpu_iva", }; static struct omap_hwmod_ocp_if *omap3_sr1_slaves[] = { &omap3_l4_core__sr1, }; Loading @@ -2672,7 +2687,6 @@ static struct omap_hwmod omap34xx_sr1_hwmod = { .name = "sr1_hwmod", .class = &omap34xx_smartreflex_hwmod_class, .main_clk = "sr1_fck", .vdd_name = "mpu_iva", .prcm = { .omap2 = { .prcm_reg_id = 1, Loading @@ -2684,6 +2698,8 @@ static struct omap_hwmod omap34xx_sr1_hwmod = { }, .slaves = omap3_sr1_slaves, .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves), .dev_attr = &sr1_dev_attr, .mpu_irqs = omap3_smartreflex_mpu_irqs, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; Loading @@ -2691,7 +2707,6 @@ static struct omap_hwmod omap36xx_sr1_hwmod = { .name = "sr1_hwmod", .class = &omap36xx_smartreflex_hwmod_class, .main_clk = "sr1_fck", .vdd_name = "mpu_iva", .prcm = { .omap2 = { .prcm_reg_id = 1, Loading @@ -2703,9 +2718,15 @@ static struct omap_hwmod omap36xx_sr1_hwmod = { }, .slaves = omap3_sr1_slaves, .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves), .dev_attr = &sr1_dev_attr, .mpu_irqs = omap3_smartreflex_mpu_irqs, }; /* SR2 */ static struct omap_smartreflex_dev_attr sr2_dev_attr = { .sensor_voltdm_name = "core", }; static struct omap_hwmod_ocp_if *omap3_sr2_slaves[] = { &omap3_l4_core__sr2, }; Loading @@ -2714,7 +2735,6 @@ static struct omap_hwmod omap34xx_sr2_hwmod = { .name = "sr2_hwmod", .class = &omap34xx_smartreflex_hwmod_class, .main_clk = "sr2_fck", .vdd_name = "core", .prcm = { .omap2 = { .prcm_reg_id = 1, Loading @@ -2726,6 +2746,8 @@ static struct omap_hwmod omap34xx_sr2_hwmod = { }, .slaves = omap3_sr2_slaves, .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves), .dev_attr = &sr2_dev_attr, .mpu_irqs = omap3_smartreflex_core_irqs, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; Loading @@ -2733,7 +2755,6 @@ static struct omap_hwmod omap36xx_sr2_hwmod = { .name = "sr2_hwmod", .class = &omap36xx_smartreflex_hwmod_class, .main_clk = "sr2_fck", .vdd_name = "core", .prcm = { .omap2 = { .prcm_reg_id = 1, Loading @@ -2745,6 +2766,8 @@ static struct omap_hwmod omap36xx_sr2_hwmod = { }, .slaves = omap3_sr2_slaves, .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves), .dev_attr = &sr2_dev_attr, .mpu_irqs = omap3_smartreflex_core_irqs, }; /* Loading
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +16 −3 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ #include "omap_hwmod_common_data.h" #include "smartreflex.h" #include "cm1_44xx.h" #include "cm2_44xx.h" #include "prm44xx.h" Loading Loading @@ -3963,6 +3964,10 @@ static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = { }; /* smartreflex_core */ static struct omap_smartreflex_dev_attr smartreflex_core_dev_attr = { .sensor_voltdm_name = "core", }; static struct omap_hwmod omap44xx_smartreflex_core_hwmod; static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = { { .irq = 19 + OMAP44XX_IRQ_GIC_START }, Loading Loading @@ -3999,7 +4004,6 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = { .mpu_irqs = omap44xx_smartreflex_core_irqs, .main_clk = "smartreflex_core_fck", .vdd_name = "core", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET, Loading @@ -4009,9 +4013,14 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = { }, .slaves = omap44xx_smartreflex_core_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_slaves), .dev_attr = &smartreflex_core_dev_attr, }; /* smartreflex_iva */ static struct omap_smartreflex_dev_attr smartreflex_iva_dev_attr = { .sensor_voltdm_name = "iva", }; static struct omap_hwmod omap44xx_smartreflex_iva_hwmod; static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = { { .irq = 102 + OMAP44XX_IRQ_GIC_START }, Loading Loading @@ -4047,7 +4056,6 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = { .clkdm_name = "l4_ao_clkdm", .mpu_irqs = omap44xx_smartreflex_iva_irqs, .main_clk = "smartreflex_iva_fck", .vdd_name = "iva", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET, Loading @@ -4057,9 +4065,14 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = { }, .slaves = omap44xx_smartreflex_iva_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_slaves), .dev_attr = &smartreflex_iva_dev_attr, }; /* smartreflex_mpu */ static struct omap_smartreflex_dev_attr smartreflex_mpu_dev_attr = { .sensor_voltdm_name = "mpu", }; static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod; static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = { { .irq = 18 + OMAP44XX_IRQ_GIC_START }, Loading Loading @@ -4095,7 +4108,6 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = { .clkdm_name = "l4_ao_clkdm", .mpu_irqs = omap44xx_smartreflex_mpu_irqs, .main_clk = "smartreflex_mpu_fck", .vdd_name = "mpu", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET, Loading @@ -4105,6 +4117,7 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = { }, .slaves = omap44xx_smartreflex_mpu_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_slaves), .dev_attr = &smartreflex_mpu_dev_attr, }; /* Loading
arch/arm/mach-omap2/smartreflex-class3.c +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ static int sr_class3_enable(struct voltagedomain *voltdm) static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset) { sr_disable_errgen(voltdm); omap_vp_disable(voltdm); sr_disable(voltdm); if (is_volt_reset) Loading
arch/arm/mach-omap2/smartreflex.c +168 −59 Original line number Diff line number Diff line Loading @@ -36,6 +36,12 @@ #define SR_DISABLE_TIMEOUT 200 struct omap_sr { struct list_head node; struct platform_device *pdev; struct omap_sr_nvalue_table *nvalue_table; struct voltagedomain *voltdm; struct dentry *dbg_dir; unsigned int irq; int srid; int ip_type; int nvalue_count; Loading @@ -49,13 +55,7 @@ struct omap_sr { u32 senp_avgweight; u32 senp_mod; u32 senn_mod; unsigned int irq; void __iomem *base; struct platform_device *pdev; struct list_head node; struct omap_sr_nvalue_table *nvalue_table; struct voltagedomain *voltdm; struct dentry *dbg_dir; }; /* sr_list contains all the instances of smartreflex module */ Loading @@ -74,10 +74,6 @@ static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask, u32 value) { u32 reg_val; u32 errconfig_offs = 0, errconfig_mask = 0; reg_val = __raw_readl(sr->base + offset); reg_val &= ~mask; /* * Smartreflex error config register is special as it contains Loading @@ -88,16 +84,15 @@ static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask, * if they are currently set, but does allow the caller to write * those bits. */ if (sr->ip_type == SR_TYPE_V1) { errconfig_offs = ERRCONFIG_V1; errconfig_mask = ERRCONFIG_STATUS_V1_MASK; } else if (sr->ip_type == SR_TYPE_V2) { errconfig_offs = ERRCONFIG_V2; errconfig_mask = ERRCONFIG_VPBOUNDINTST_V2; } if (sr->ip_type == SR_TYPE_V1 && offset == ERRCONFIG_V1) mask |= ERRCONFIG_STATUS_V1_MASK; else if (sr->ip_type == SR_TYPE_V2 && offset == ERRCONFIG_V2) mask |= ERRCONFIG_VPBOUNDINTST_V2; if (offset == errconfig_offs) reg_val &= ~errconfig_mask; reg_val = __raw_readl(sr->base + offset); reg_val &= ~mask; value &= mask; reg_val |= value; Loading Loading @@ -128,21 +123,28 @@ static struct omap_sr *_sr_lookup(struct voltagedomain *voltdm) static irqreturn_t sr_interrupt(int irq, void *data) { struct omap_sr *sr_info = (struct omap_sr *)data; struct omap_sr *sr_info = data; u32 status = 0; if (sr_info->ip_type == SR_TYPE_V1) { switch (sr_info->ip_type) { case SR_TYPE_V1: /* Read the status bits */ status = sr_read_reg(sr_info, ERRCONFIG_V1); /* Clear them by writing back */ sr_write_reg(sr_info, ERRCONFIG_V1, status); } else if (sr_info->ip_type == SR_TYPE_V2) { break; case SR_TYPE_V2: /* Read the status bits */ status = sr_read_reg(sr_info, IRQSTATUS); /* Clear them by writing back */ sr_write_reg(sr_info, IRQSTATUS, status); break; default: dev_err(&sr_info->pdev->dev, "UNKNOWN IP type %d\n", sr_info->ip_type); return IRQ_NONE; } if (sr_class->notify) Loading @@ -166,6 +168,7 @@ static void sr_set_clk_length(struct omap_sr *sr) __func__); return; } sys_clk_speed = clk_get_rate(sys_ck); clk_put(sys_ck); Loading Loading @@ -267,7 +270,7 @@ static int sr_late_init(struct omap_sr *sr_info) goto error; } ret = request_irq(sr_info->irq, sr_interrupt, 0, name, (void *)sr_info); 0, name, sr_info); if (ret) goto error; disable_irq(sr_info->irq); Loading @@ -288,12 +291,15 @@ static int sr_late_init(struct omap_sr *sr_info) "not function as desired\n", __func__); kfree(name); kfree(sr_info); return ret; } static void sr_v1_disable(struct omap_sr *sr) { int timeout = 0; int errconf_val = ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST | ERRCONFIG_MCUBOUNDINTST; /* Enable MCUDisableAcknowledge interrupt */ sr_modify_reg(sr, ERRCONFIG_V1, Loading @@ -302,13 +308,13 @@ static void sr_v1_disable(struct omap_sr *sr) /* SRCONFIG - disable SR */ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0); /* Disable all other SR interrupts and clear the status */ /* Disable all other SR interrupts and clear the status as needed */ if (sr_read_reg(sr, ERRCONFIG_V1) & ERRCONFIG_VPBOUNDINTST_V1) errconf_val |= ERRCONFIG_VPBOUNDINTST_V1; sr_modify_reg(sr, ERRCONFIG_V1, (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1), (ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST | ERRCONFIG_MCUBOUNDINTST | ERRCONFIG_VPBOUNDINTST_V1)); errconf_val); /* * Wait for SR to be disabled. Loading Loading @@ -337,9 +343,17 @@ static void sr_v2_disable(struct omap_sr *sr) /* SRCONFIG - disable SR */ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0); /* Disable all other SR interrupts and clear the status */ /* * Disable all other SR interrupts and clear the status * write to status register ONLY on need basis - only if status * is set. */ if (sr_read_reg(sr, ERRCONFIG_V2) & ERRCONFIG_VPBOUNDINTST_V2) sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2, ERRCONFIG_VPBOUNDINTST_V2); else sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2, 0x0); sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT | IRQENABLE_MCUBOUNDSINT)); Loading Loading @@ -398,15 +412,16 @@ static u32 sr_retrieve_nvalue(struct omap_sr *sr, u32 efuse_offs) */ int sr_configure_errgen(struct voltagedomain *voltdm) { u32 sr_config, sr_errconfig, errconfig_offs, vpboundint_en; u32 vpboundint_st, senp_en = 0, senn_en = 0; u32 sr_config, sr_errconfig, errconfig_offs; u32 vpboundint_en, vpboundint_st; u32 senp_en = 0, senn_en = 0; u8 senp_shift, senn_shift; struct omap_sr *sr = _sr_lookup(voltdm); if (IS_ERR(sr)) { pr_warning("%s: omap_sr struct for sr_%s not found\n", __func__, voltdm->name); return -EINVAL; return PTR_ERR(sr); } if (!sr->clk_length) Loading @@ -418,20 +433,23 @@ int sr_configure_errgen(struct voltagedomain *voltdm) sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) | SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN; if (sr->ip_type == SR_TYPE_V1) { switch (sr->ip_type) { case SR_TYPE_V1: sr_config |= SRCONFIG_DELAYCTRL; senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT; senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT; errconfig_offs = ERRCONFIG_V1; vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1; vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1; } else if (sr->ip_type == SR_TYPE_V2) { break; case SR_TYPE_V2: senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT; senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT; errconfig_offs = ERRCONFIG_V2; vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2; vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2; } else { break; default: dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" "module without specifying the ip\n", __func__); return -EINVAL; Loading @@ -447,8 +465,55 @@ int sr_configure_errgen(struct voltagedomain *voltdm) sr_errconfig); /* Enabling the interrupts if the ERROR module is used */ sr_modify_reg(sr, errconfig_offs, vpboundint_en, (vpboundint_en | vpboundint_st)); sr_modify_reg(sr, errconfig_offs, (vpboundint_en | vpboundint_st), vpboundint_en); return 0; } /** * sr_disable_errgen() - Disables SmartReflex AVS module's errgen component * @voltdm: VDD pointer to which the SR module to be configured belongs to. * * This API is to be called from the smartreflex class driver to * disable the error generator module inside the smartreflex module. * * Returns 0 on success and error value in case of failure. */ int sr_disable_errgen(struct voltagedomain *voltdm) { u32 errconfig_offs; u32 vpboundint_en, vpboundint_st; struct omap_sr *sr = _sr_lookup(voltdm); if (IS_ERR(sr)) { pr_warning("%s: omap_sr struct for sr_%s not found\n", __func__, voltdm->name); return PTR_ERR(sr); } switch (sr->ip_type) { case SR_TYPE_V1: errconfig_offs = ERRCONFIG_V1; vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1; vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1; break; case SR_TYPE_V2: errconfig_offs = ERRCONFIG_V2; vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2; vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2; break; default: dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" "module without specifying the ip\n", __func__); return -EINVAL; } /* Disable the interrupts of ERROR module */ sr_modify_reg(sr, errconfig_offs, vpboundint_en | vpboundint_st, 0); /* Disable the Sensor and errorgen */ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN, 0); return 0; } Loading @@ -475,7 +540,7 @@ int sr_configure_minmax(struct voltagedomain *voltdm) if (IS_ERR(sr)) { pr_warning("%s: omap_sr struct for sr_%s not found\n", __func__, voltdm->name); return -EINVAL; return PTR_ERR(sr); } if (!sr->clk_length) Loading @@ -488,14 +553,17 @@ int sr_configure_minmax(struct voltagedomain *voltdm) SRCONFIG_SENENABLE | (sr->accum_data << SRCONFIG_ACCUMDATA_SHIFT); if (sr->ip_type == SR_TYPE_V1) { switch (sr->ip_type) { case SR_TYPE_V1: sr_config |= SRCONFIG_DELAYCTRL; senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT; senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT; } else if (sr->ip_type == SR_TYPE_V2) { break; case SR_TYPE_V2: senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT; senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT; } else { break; default: dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" "module without specifying the ip\n", __func__); return -EINVAL; Loading @@ -511,20 +579,27 @@ int sr_configure_minmax(struct voltagedomain *voltdm) * Enabling the interrupts if MINMAXAVG module is used. * TODO: check if all the interrupts are mandatory */ if (sr->ip_type == SR_TYPE_V1) { switch (sr->ip_type) { case SR_TYPE_V1: sr_modify_reg(sr, ERRCONFIG_V1, (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUBOUNDINTEN), (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST | ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST)); } else if (sr->ip_type == SR_TYPE_V2) { break; case SR_TYPE_V2: sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUACCUMINT | IRQSTATUS_MCVALIDINT | IRQSTATUS_MCBOUNDSINT | IRQSTATUS_MCUDISABLEACKINT); sr_write_reg(sr, IRQENABLE_SET, IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT | IRQENABLE_MCUBOUNDSINT | IRQENABLE_MCUDISABLEACKINT); break; default: dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" "module without specifying the ip\n", __func__); return -EINVAL; } return 0; Loading @@ -543,15 +618,15 @@ int sr_configure_minmax(struct voltagedomain *voltdm) */ int sr_enable(struct voltagedomain *voltdm, unsigned long volt) { u32 nvalue_reciprocal; struct omap_volt_data *volt_data; struct omap_sr *sr = _sr_lookup(voltdm); u32 nvalue_reciprocal; int ret; if (IS_ERR(sr)) { pr_warning("%s: omap_sr struct for sr_%s not found\n", __func__, voltdm->name); return -EINVAL; return PTR_ERR(sr); } volt_data = omap_voltage_get_voltdata(sr->voltdm, volt); Loading @@ -559,7 +634,7 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt) if (IS_ERR(volt_data)) { dev_warn(&sr->pdev->dev, "%s: Unable to get voltage table" "for nominal voltage %ld\n", __func__, volt); return -ENODATA; return PTR_ERR(volt_data); } nvalue_reciprocal = sr_retrieve_nvalue(sr, volt_data->sr_efuse_offs); Loading Loading @@ -617,10 +692,17 @@ void sr_disable(struct voltagedomain *voltdm) * disable the clocks. */ if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE) { if (sr->ip_type == SR_TYPE_V1) switch (sr->ip_type) { case SR_TYPE_V1: sr_v1_disable(sr); else if (sr->ip_type == SR_TYPE_V2) break; case SR_TYPE_V2: sr_v2_disable(sr); break; default: dev_err(&sr->pdev->dev, "UNKNOWN IP type %d\n", sr->ip_type); } } pm_runtime_put_sync_suspend(&sr->pdev->dev); Loading Loading @@ -779,10 +861,10 @@ void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data) sr_pmic_data = pmic_data; } /* PM Debug Fs enteries to enable disable smartreflex. */ /* PM Debug FS entries to enable and disable smartreflex. */ static int omap_sr_autocomp_show(void *data, u64 *val) { struct omap_sr *sr_info = (struct omap_sr *) data; struct omap_sr *sr_info = data; if (!sr_info) { pr_warning("%s: omap_sr struct not found\n", __func__); Loading @@ -796,7 +878,7 @@ static int omap_sr_autocomp_show(void *data, u64 *val) static int omap_sr_autocomp_store(void *data, u64 val) { struct omap_sr *sr_info = (struct omap_sr *) data; struct omap_sr *sr_info = data; if (!sr_info) { pr_warning("%s: omap_sr struct not found\n", __func__); Loading @@ -804,7 +886,7 @@ static int omap_sr_autocomp_store(void *data, u64 val) } /* Sanity check */ if (val && (val != 1)) { if (val > 1) { pr_warning("%s: Invalid argument %lld\n", __func__, val); return -EINVAL; } Loading @@ -825,7 +907,7 @@ DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show, static int __init omap_sr_probe(struct platform_device *pdev) { struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); struct omap_sr *sr_info; struct omap_sr_data *pdata = pdev->dev.platform_data; struct resource *mem, *irq; struct dentry *nvalue_dir; Loading @@ -833,12 +915,15 @@ static int __init omap_sr_probe(struct platform_device *pdev) int i, ret = 0; char *name; sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); if (!sr_info) { dev_err(&pdev->dev, "%s: unable to allocate sr_info\n", __func__); return -ENOMEM; } platform_set_drvdata(pdev, sr_info); if (!pdata) { dev_err(&pdev->dev, "%s: platform data missing\n", __func__); ret = -EINVAL; Loading Loading @@ -904,7 +989,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__); if (!sr_dbg_dir) { sr_dbg_dir = debugfs_create_dir("smartreflex", NULL); if (!sr_dbg_dir) { if (IS_ERR_OR_NULL(sr_dbg_dir)) { ret = PTR_ERR(sr_dbg_dir); pr_err("%s:sr debugfs dir creation failed(%d)\n", __func__, ret); Loading @@ -921,7 +1006,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) } sr_info->dbg_dir = debugfs_create_dir(name, sr_dbg_dir); kfree(name); if (IS_ERR(sr_info->dbg_dir)) { if (IS_ERR_OR_NULL(sr_info->dbg_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", __func__); ret = PTR_ERR(sr_info->dbg_dir); Loading @@ -938,7 +1023,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) &sr_info->err_minlimit); nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir); if (IS_ERR(nvalue_dir)) { if (IS_ERR_OR_NULL(nvalue_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory" "for n-values\n", __func__); ret = PTR_ERR(nvalue_dir); Loading Loading @@ -994,7 +1079,7 @@ static int __devexit omap_sr_remove(struct platform_device *pdev) if (IS_ERR(sr_info)) { dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", __func__); return -EINVAL; return PTR_ERR(sr_info); } if (sr_info->autocomp_active) Loading @@ -1011,8 +1096,32 @@ static int __devexit omap_sr_remove(struct platform_device *pdev) return 0; } static void __devexit omap_sr_shutdown(struct platform_device *pdev) { struct omap_sr_data *pdata = pdev->dev.platform_data; struct omap_sr *sr_info; if (!pdata) { dev_err(&pdev->dev, "%s: platform data missing\n", __func__); return; } sr_info = _sr_lookup(pdata->voltdm); if (IS_ERR(sr_info)) { dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", __func__); return; } if (sr_info->autocomp_active) sr_stop_vddautocomp(sr_info); return; } static struct platform_driver smartreflex_driver = { .remove = __devexit_p(omap_sr_remove), .shutdown = __devexit_p(omap_sr_shutdown), .driver = { .name = "smartreflex", }, Loading Loading @@ -1042,12 +1151,12 @@ static int __init sr_init(void) return 0; } late_initcall(sr_init); static void __exit sr_exit(void) { platform_driver_unregister(&smartreflex_driver); } late_initcall(sr_init); module_exit(sr_exit); MODULE_DESCRIPTION("OMAP Smartreflex Driver"); Loading
arch/arm/mach-omap2/smartreflex.h +10 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,15 @@ struct omap_sr_pmic_data { void (*sr_pmic_init) (void); }; /** * struct omap_smartreflex_dev_attr - Smartreflex Device attribute. * * @sensor_voltdm_name: Name of voltdomain of SR instance */ struct omap_smartreflex_dev_attr { const char *sensor_voltdm_name; }; #ifdef CONFIG_OMAP_SMARTREFLEX /* * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR. Loading Loading @@ -231,6 +240,7 @@ void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data); int sr_enable(struct voltagedomain *voltdm, unsigned long volt); void sr_disable(struct voltagedomain *voltdm); int sr_configure_errgen(struct voltagedomain *voltdm); int sr_disable_errgen(struct voltagedomain *voltdm); int sr_configure_minmax(struct voltagedomain *voltdm); /* API to register the smartreflex class driver with the smartreflex driver */ Loading