* pm-omap:
  PM / AVS: SmartReflex: use devm_* API to initialize SmartReflex
  PM / AVS: SmartReflex: use omap_sr * for enable/disable interface
  PM / AVS: SmartReflex: use omap_sr * for minmax interfaces
  PM / AVS: SmartReflex: use omap_sr * for errgen interfaces
  PM / AVS: SmartReflex: fix driver name
  PM / AVS: SmartReflex: disable runtime PM on driver remove
  PM / AVS: SmartReflex: disable errgen before vpbound disable
This commit is contained in:
Rafael J. Wysocki 2013-06-28 13:01:22 +02:00
Родитель ceaed1e394 592a55d835
Коммит 52388492ea
3 изменённых файлов: 72 добавлений и 100 удалений

Просмотреть файл

@ -26,14 +26,14 @@ static int sr_class3_enable(struct omap_sr *sr)
}
omap_vp_enable(sr->voltdm);
return sr_enable(sr->voltdm, volt);
return sr_enable(sr, volt);
}
static int sr_class3_disable(struct omap_sr *sr, int is_volt_reset)
{
sr_disable_errgen(sr->voltdm);
sr_disable_errgen(sr);
omap_vp_disable(sr->voltdm);
sr_disable(sr->voltdm);
sr_disable(sr);
if (is_volt_reset)
voltdm_reset(sr->voltdm);
@ -42,7 +42,7 @@ static int sr_class3_disable(struct omap_sr *sr, int is_volt_reset)
static int sr_class3_configure(struct omap_sr *sr)
{
return sr_configure_errgen(sr->voltdm);
return sr_configure_errgen(sr);
}
/* SR class3 structure */

Просмотреть файл

@ -27,7 +27,8 @@
#include <linux/pm_runtime.h>
#include <linux/power/smartreflex.h>
#define SMARTREFLEX_NAME_LEN 16
#define DRIVER_NAME "smartreflex"
#define SMARTREFLEX_NAME_LEN 32
#define NVALUE_NAME_LEN 40
#define SR_DISABLE_TIMEOUT 200
@ -207,12 +208,11 @@ static void sr_stop_vddautocomp(struct omap_sr *sr)
static int sr_late_init(struct omap_sr *sr_info)
{
struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data;
struct resource *mem;
int ret = 0;
if (sr_class->notify && sr_class->notify_flags && sr_info->irq) {
ret = request_irq(sr_info->irq, sr_interrupt,
0, sr_info->name, sr_info);
ret = devm_request_irq(&sr_info->pdev->dev, sr_info->irq,
sr_interrupt, 0, sr_info->name, sr_info);
if (ret)
goto error;
disable_irq(sr_info->irq);
@ -224,14 +224,10 @@ static int sr_late_init(struct omap_sr *sr_info)
return ret;
error:
iounmap(sr_info->base);
mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
release_mem_region(mem->start, resource_size(mem));
list_del(&sr_info->node);
dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
"interrupt handler. Smartreflex will"
"not function as desired\n", __func__);
kfree(sr_info);
return ret;
}
@ -341,9 +337,9 @@ static struct omap_sr_nvalue_table *sr_retrieve_nvalue_row(
/* Public Functions */
/**
* sr_configure_errgen() - Configures the smrtreflex to perform AVS using the
* sr_configure_errgen() - Configures the SmartReflex to perform AVS using the
* error generator module.
* @voltdm: VDD pointer to which the SR module to be configured belongs to.
* @sr: SR module to be configured.
*
* This API is to be called from the smartreflex class driver to
* configure the error generator module inside the smartreflex module.
@ -352,17 +348,17 @@ static struct omap_sr_nvalue_table *sr_retrieve_nvalue_row(
* SR CLASS 2 can choose between ERROR module and MINMAXAVG
* module. Returns 0 on success and error value in case of failure.
*/
int sr_configure_errgen(struct voltagedomain *voltdm)
int sr_configure_errgen(struct omap_sr *sr)
{
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 voltdm not found\n", __func__);
return PTR_ERR(sr);
if (!sr) {
pr_warn("%s: NULL omap_sr from %pF\n", __func__,
(void *)_RET_IP_);
return -EINVAL;
}
if (!sr->clk_length)
@ -414,22 +410,22 @@ int sr_configure_errgen(struct voltagedomain *voltdm)
/**
* sr_disable_errgen() - Disables SmartReflex AVS module's errgen component
* @voltdm: VDD pointer to which the SR module to be configured belongs to.
* @sr: SR module to be configured.
*
* 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)
int sr_disable_errgen(struct omap_sr *sr)
{
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 voltdm not found\n", __func__);
return PTR_ERR(sr);
if (!sr) {
pr_warn("%s: NULL omap_sr from %pF\n", __func__,
(void *)_RET_IP_);
return -EINVAL;
}
switch (sr->ip_type) {
@ -449,19 +445,24 @@ int sr_disable_errgen(struct voltagedomain *voltdm)
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);
/*
* Disable the interrupts of ERROR module
* NOTE: modify is a read, modify,write - an implicit OCP barrier
* which is required is present here - sequencing is critical
* at this point (after errgen is disabled, vpboundint disable)
*/
sr_modify_reg(sr, errconfig_offs, vpboundint_en | vpboundint_st, 0);
return 0;
}
/**
* sr_configure_minmax() - Configures the smrtreflex to perform AVS using the
* sr_configure_minmax() - Configures the SmartReflex to perform AVS using the
* minmaxavg module.
* @voltdm: VDD pointer to which the SR module to be configured belongs to.
* @sr: SR module to be configured.
*
* This API is to be called from the smartreflex class driver to
* configure the minmaxavg module inside the smartreflex module.
@ -470,16 +471,16 @@ int sr_disable_errgen(struct voltagedomain *voltdm)
* SR CLASS 2 can choose between ERROR module and MINMAXAVG
* module. Returns 0 on success and error value in case of failure.
*/
int sr_configure_minmax(struct voltagedomain *voltdm)
int sr_configure_minmax(struct omap_sr *sr)
{
u32 sr_config, sr_avgwt;
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 voltdm not found\n", __func__);
return PTR_ERR(sr);
if (!sr) {
pr_warn("%s: NULL omap_sr from %pF\n", __func__,
(void *)_RET_IP_);
return -EINVAL;
}
if (!sr->clk_length)
@ -546,7 +547,7 @@ int sr_configure_minmax(struct voltagedomain *voltdm)
/**
* sr_enable() - Enables the smartreflex module.
* @voltdm: VDD pointer to which the SR module to be configured belongs to.
* @sr: pointer to which the SR module to be configured belongs to.
* @volt: The voltage at which the Voltage domain associated with
* the smartreflex module is operating at.
* This is required only to program the correct Ntarget value.
@ -555,16 +556,16 @@ int sr_configure_minmax(struct voltagedomain *voltdm)
* enable a smartreflex module. Returns 0 on success. Returns error
* value if the voltage passed is wrong or if ntarget value is wrong.
*/
int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
int sr_enable(struct omap_sr *sr, unsigned long volt)
{
struct omap_volt_data *volt_data;
struct omap_sr *sr = _sr_lookup(voltdm);
struct omap_sr_nvalue_table *nvalue_row;
int ret;
if (IS_ERR(sr)) {
pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
return PTR_ERR(sr);
if (!sr) {
pr_warn("%s: NULL omap_sr from %pF\n", __func__,
(void *)_RET_IP_);
return -EINVAL;
}
volt_data = omap_voltage_get_voltdata(sr->voltdm, volt);
@ -606,17 +607,16 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
/**
* sr_disable() - Disables the smartreflex module.
* @voltdm: VDD pointer to which the SR module to be configured belongs to.
* @sr: pointer to which the SR module to be configured belongs to.
*
* This API is to be called from the smartreflex class driver to
* disable a smartreflex module.
*/
void sr_disable(struct voltagedomain *voltdm)
void sr_disable(struct omap_sr *sr)
{
struct omap_sr *sr = _sr_lookup(voltdm);
if (IS_ERR(sr)) {
pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
if (!sr) {
pr_warn("%s: NULL omap_sr from %pF\n", __func__,
(void *)_RET_IP_);
return;
}
@ -847,34 +847,33 @@ static int __init omap_sr_probe(struct platform_device *pdev)
struct dentry *nvalue_dir;
int i, ret = 0;
sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
sr_info = devm_kzalloc(&pdev->dev, sizeof(struct omap_sr), GFP_KERNEL);
if (!sr_info) {
dev_err(&pdev->dev, "%s: unable to allocate sr_info\n",
__func__);
return -ENOMEM;
}
sr_info->name = devm_kzalloc(&pdev->dev,
SMARTREFLEX_NAME_LEN, GFP_KERNEL);
if (!sr_info->name) {
dev_err(&pdev->dev, "%s: unable to allocate SR instance name\n",
__func__);
return -ENOMEM;
}
platform_set_drvdata(pdev, sr_info);
if (!pdata) {
dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
ret = -EINVAL;
goto err_free_devinfo;
return -EINVAL;
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
ret = -ENODEV;
goto err_free_devinfo;
}
mem = request_mem_region(mem->start, resource_size(mem),
dev_name(&pdev->dev));
if (!mem) {
dev_err(&pdev->dev, "%s: no mem region\n", __func__);
ret = -EBUSY;
goto err_free_devinfo;
sr_info->base = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(sr_info->base)) {
dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
return PTR_ERR(sr_info->base);
}
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@ -882,13 +881,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
pm_runtime_irq_safe(&pdev->dev);
sr_info->name = kasprintf(GFP_KERNEL, "%s", pdata->name);
if (!sr_info->name) {
dev_err(&pdev->dev, "%s: Unable to alloc SR instance name\n",
__func__);
ret = -ENOMEM;
goto err_release_region;
}
snprintf(sr_info->name, SMARTREFLEX_NAME_LEN, "%s", pdata->name);
sr_info->pdev = pdev;
sr_info->srid = pdev->id;
@ -905,13 +898,6 @@ static int __init omap_sr_probe(struct platform_device *pdev)
sr_info->autocomp_active = false;
sr_info->ip_type = pdata->ip_type;
sr_info->base = ioremap(mem->start, resource_size(mem));
if (!sr_info->base) {
dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
ret = -ENOMEM;
goto err_free_name;
}
if (irq)
sr_info->irq = irq->start;
@ -927,7 +913,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
ret = sr_late_init(sr_info);
if (ret) {
pr_warning("%s: Error in SR late init\n", __func__);
goto err_iounmap;
goto err_list_del;
}
}
@ -938,7 +924,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
ret = PTR_ERR(sr_dbg_dir);
pr_err("%s:sr debugfs dir creation failed(%d)\n",
__func__, ret);
goto err_iounmap;
goto err_list_del;
}
}
@ -991,16 +977,8 @@ static int __init omap_sr_probe(struct platform_device *pdev)
err_debugfs:
debugfs_remove_recursive(sr_info->dbg_dir);
err_iounmap:
err_list_del:
list_del(&sr_info->node);
iounmap(sr_info->base);
err_free_name:
kfree(sr_info->name);
err_release_region:
release_mem_region(mem->start, resource_size(mem));
err_free_devinfo:
kfree(sr_info);
return ret;
}
@ -1008,7 +986,6 @@ static int omap_sr_remove(struct platform_device *pdev)
{
struct omap_sr_data *pdata = pdev->dev.platform_data;
struct omap_sr *sr_info;
struct resource *mem;
if (!pdata) {
dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
@ -1027,13 +1004,8 @@ static int omap_sr_remove(struct platform_device *pdev)
if (sr_info->dbg_dir)
debugfs_remove_recursive(sr_info->dbg_dir);
pm_runtime_disable(&pdev->dev);
list_del(&sr_info->node);
iounmap(sr_info->base);
kfree(sr_info->name);
kfree(sr_info);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(mem->start, resource_size(mem));
return 0;
}
@ -1064,7 +1036,7 @@ static struct platform_driver smartreflex_driver = {
.remove = omap_sr_remove,
.shutdown = omap_sr_shutdown,
.driver = {
.name = "smartreflex",
.name = DRIVER_NAME,
},
};

Просмотреть файл

@ -299,11 +299,11 @@ void omap_sr_disable_reset_volt(struct voltagedomain *voltdm);
void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data);
/* Smartreflex driver hooks to be called from Smartreflex class driver */
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);
int sr_enable(struct omap_sr *sr, unsigned long volt);
void sr_disable(struct omap_sr *sr);
int sr_configure_errgen(struct omap_sr *sr);
int sr_disable_errgen(struct omap_sr *sr);
int sr_configure_minmax(struct omap_sr *sr);
/* API to register the smartreflex class driver with the smartreflex driver */
int sr_register_class(struct omap_sr_class_data *class_data);