2011-06-21 10:51:26 -03:00
/*
2012-08-14 17:31:16 -03:00
* linux / drivers / media / platform / s5p - mfc / s5p_mfc_pm . c
2011-06-21 10:51:26 -03:00
*
* Copyright ( c ) 2010 Samsung Electronics Co . , Ltd .
* http : //www.samsung.com/
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*/
# include <linux/clk.h>
# include <linux/err.h>
# include <linux/platform_device.h>
# ifdef CONFIG_PM_RUNTIME
# include <linux/pm_runtime.h>
# endif
# include "s5p_mfc_common.h"
# include "s5p_mfc_debug.h"
# include "s5p_mfc_pm.h"
# define MFC_GATE_CLK_NAME "mfc"
# define CLK_DEBUG
static struct s5p_mfc_pm * pm ;
static struct s5p_mfc_dev * p_dev ;
# ifdef CLK_DEBUG
2012-10-17 07:11:50 -03:00
static atomic_t clk_ref ;
2011-06-21 10:51:26 -03:00
# endif
int s5p_mfc_init_pm ( struct s5p_mfc_dev * dev )
{
int ret = 0 ;
pm = & dev - > pm ;
p_dev = dev ;
pm - > clock_gate = clk_get ( & dev - > plat_dev - > dev , MFC_GATE_CLK_NAME ) ;
if ( IS_ERR ( pm - > clock_gate ) ) {
mfc_err ( " Failed to get clock-gating control \n " ) ;
2012-02-16 10:51:56 -03:00
ret = PTR_ERR ( pm - > clock_gate ) ;
2011-06-21 10:51:26 -03:00
goto err_g_ip_clk ;
}
2012-02-16 10:51:56 -03:00
ret = clk_prepare ( pm - > clock_gate ) ;
if ( ret ) {
2013-01-02 05:13:33 -03:00
mfc_err ( " Failed to prepare clock-gating control \n " ) ;
2012-02-16 10:51:56 -03:00
goto err_p_ip_clk ;
}
2011-06-21 10:51:26 -03:00
atomic_set ( & pm - > power , 0 ) ;
# ifdef CONFIG_PM_RUNTIME
pm - > device = & dev - > plat_dev - > dev ;
pm_runtime_enable ( pm - > device ) ;
# endif
# ifdef CLK_DEBUG
atomic_set ( & clk_ref , 0 ) ;
# endif
return 0 ;
2012-02-16 10:51:56 -03:00
err_p_ip_clk :
2011-06-21 10:51:26 -03:00
clk_put ( pm - > clock_gate ) ;
err_g_ip_clk :
return ret ;
}
void s5p_mfc_final_pm ( struct s5p_mfc_dev * dev )
{
2012-02-16 10:51:56 -03:00
clk_unprepare ( pm - > clock_gate ) ;
2011-06-21 10:51:26 -03:00
clk_put ( pm - > clock_gate ) ;
# ifdef CONFIG_PM_RUNTIME
pm_runtime_disable ( pm - > device ) ;
# endif
}
int s5p_mfc_clock_on ( void )
{
int ret ;
# ifdef CLK_DEBUG
atomic_inc ( & clk_ref ) ;
2013-05-28 03:26:16 -03:00
mfc_debug ( 3 , " + %d \n " , atomic_read ( & clk_ref ) ) ;
2011-06-21 10:51:26 -03:00
# endif
ret = clk_enable ( pm - > clock_gate ) ;
return ret ;
}
void s5p_mfc_clock_off ( void )
{
# ifdef CLK_DEBUG
atomic_dec ( & clk_ref ) ;
2013-05-28 03:26:16 -03:00
mfc_debug ( 3 , " - %d \n " , atomic_read ( & clk_ref ) ) ;
2011-06-21 10:51:26 -03:00
# endif
clk_disable ( pm - > clock_gate ) ;
}
int s5p_mfc_power_on ( void )
{
# ifdef CONFIG_PM_RUNTIME
return pm_runtime_get_sync ( pm - > device ) ;
# else
atomic_set ( & pm - > power , 1 ) ;
return 0 ;
# endif
}
int s5p_mfc_power_off ( void )
{
# ifdef CONFIG_PM_RUNTIME
return pm_runtime_put_sync ( pm - > device ) ;
# else
atomic_set ( & pm - > power , 0 ) ;
return 0 ;
# endif
}