2019-05-28 19:57:21 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2011-02-14 13:17:12 +03:00
/*
2016-10-30 04:24:39 +03:00
* AB8500 system control driver
*
2011-02-14 13:17:12 +03:00
* Copyright ( C ) ST - Ericsson SA 2010
* Author : Mattias Nilsson < mattias . i . nilsson @ stericsson . com > for ST Ericsson .
*/
# include <linux/err.h>
2016-10-30 04:24:39 +03:00
# include <linux/init.h>
# include <linux/export.h>
2011-02-14 13:17:12 +03:00
# include <linux/platform_device.h>
2013-01-14 17:26:15 +04:00
# include <linux/pm.h>
2011-08-17 15:20:21 +04:00
# include <linux/reboot.h>
2013-01-14 17:26:15 +04:00
# include <linux/signal.h>
2011-08-17 15:20:21 +04:00
# include <linux/power_supply.h>
2011-02-14 13:17:12 +03:00
# include <linux/mfd/abx500.h>
2011-12-02 17:16:33 +04:00
# include <linux/mfd/abx500/ab8500.h>
# include <linux/mfd/abx500/ab8500-sysctrl.h>
2011-02-14 13:17:12 +03:00
2013-02-12 19:11:19 +04:00
/* RtcCtrl bits */
# define AB8500_ALARM_MIN_LOW 0x08
# define AB8500_ALARM_MIN_MID 0x09
# define RTC_CTRL 0x0B
# define RTC_ALARM_ENABLE 0x4
2011-02-14 13:17:12 +03:00
static struct device * sysctrl_dev ;
2013-04-26 16:17:15 +04:00
static void ab8500_power_off ( void )
2013-01-14 17:26:15 +04:00
{
sigset_t old ;
sigset_t all ;
mfd: ab8500-sysctrl: Fix Constify, printk => pr_info and formatting issues
WARNING: char * array declaration might be better as static const
+ static char *pss[] = {"ab8500_ac", "pm2301", "ab8500_usb"};
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then
pr_info(... to printk(KERN_INFO ...
+ printk(KERN_INFO
WARNING: quoted string split across lines
+ "Charger \"%s\" is connected with known battery."
+ " Rebooting.\n",
WARNING: quoted string split across lines
+ "unable to set sysClkReq%dRfClkBuf: "
+ "%d\n", j + 1, ret);
total: 0 errors, 4 warnings, 199 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 14:11:05 +03:00
static const char * const pss [ ] = { " ab8500_ac " , " pm2301 " , " ab8500_usb " } ;
2011-08-17 15:20:21 +04:00
int i ;
2011-08-17 17:58:52 +04:00
bool charger_present = false ;
union power_supply_propval val ;
struct power_supply * psy ;
int ret ;
2011-08-17 15:20:21 +04:00
2012-06-18 17:00:40 +04:00
if ( sysctrl_dev = = NULL ) {
pr_err ( " %s: sysctrl not initialized \n " , __func__ ) ;
return ;
}
2011-08-17 15:20:21 +04:00
/*
* If we have a charger connected and we ' re powering off ,
* reboot into charge - only mode .
*/
for ( i = 0 ; i < ARRAY_SIZE ( pss ) ; i + + ) {
psy = power_supply_get_by_name ( pss [ i ] ) ;
if ( ! psy )
continue ;
2011-08-17 17:58:52 +04:00
2015-03-12 10:44:07 +03:00
ret = power_supply_get_property ( psy , POWER_SUPPLY_PROP_ONLINE ,
& val ) ;
2015-03-12 10:44:19 +03:00
power_supply_put ( psy ) ;
2011-08-17 15:20:21 +04:00
if ( ! ret & & val . intval ) {
2011-08-17 17:58:52 +04:00
charger_present = true ;
break ;
}
}
if ( ! charger_present )
goto shutdown ;
/* Check if battery is known */
psy = power_supply_get_by_name ( " ab8500_btemp " ) ;
if ( psy ) {
2015-03-12 10:44:07 +03:00
ret = power_supply_get_property ( psy ,
POWER_SUPPLY_PROP_TECHNOLOGY , & val ) ;
2011-08-17 17:58:52 +04:00
if ( ! ret & & val . intval ! = POWER_SUPPLY_TECHNOLOGY_UNKNOWN ) {
mfd: ab8500-sysctrl: Fix Constify, printk => pr_info and formatting issues
WARNING: char * array declaration might be better as static const
+ static char *pss[] = {"ab8500_ac", "pm2301", "ab8500_usb"};
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then
pr_info(... to printk(KERN_INFO ...
+ printk(KERN_INFO
WARNING: quoted string split across lines
+ "Charger \"%s\" is connected with known battery."
+ " Rebooting.\n",
WARNING: quoted string split across lines
+ "unable to set sysClkReq%dRfClkBuf: "
+ "%d\n", j + 1, ret);
total: 0 errors, 4 warnings, 199 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 14:11:05 +03:00
pr_info ( " Charger '%s' is connected with known battery " ,
pss [ i ] ) ;
pr_info ( " - Rebooting. \n " ) ;
2011-08-18 12:14:38 +04:00
machine_restart ( " charging " ) ;
2011-08-17 15:20:21 +04:00
}
2015-03-12 10:44:19 +03:00
power_supply_put ( psy ) ;
2011-08-17 15:20:21 +04:00
}
2013-01-14 17:26:15 +04:00
2011-08-17 17:58:52 +04:00
shutdown :
2013-01-14 17:26:15 +04:00
sigfillset ( & all ) ;
if ( ! sigprocmask ( SIG_BLOCK , & all , & old ) ) {
( void ) ab8500_sysctrl_set ( AB8500_STW4500CTRL1 ,
AB8500_STW4500CTRL1_SWOFF |
AB8500_STW4500CTRL1_SWRESET4500N ) ;
( void ) sigprocmask ( SIG_SETMASK , & old , NULL ) ;
}
}
2011-02-14 13:17:12 +03:00
static inline bool valid_bank ( u8 bank )
{
return ( ( bank = = AB8500_SYS_CTRL1_BLOCK ) | |
( bank = = AB8500_SYS_CTRL2_BLOCK ) ) ;
}
int ab8500_sysctrl_read ( u16 reg , u8 * value )
{
u8 bank ;
if ( sysctrl_dev = = NULL )
2017-01-13 12:53:55 +03:00
return - EPROBE_DEFER ;
2011-02-14 13:17:12 +03:00
bank = ( reg > > 8 ) ;
if ( ! valid_bank ( bank ) )
return - EINVAL ;
return abx500_get_register_interruptible ( sysctrl_dev , bank ,
( u8 ) ( reg & 0xFF ) , value ) ;
}
2011-11-11 10:52:10 +04:00
EXPORT_SYMBOL ( ab8500_sysctrl_read ) ;
2011-02-14 13:17:12 +03:00
int ab8500_sysctrl_write ( u16 reg , u8 mask , u8 value )
{
u8 bank ;
if ( sysctrl_dev = = NULL )
2017-01-13 12:53:55 +03:00
return - EPROBE_DEFER ;
2011-02-14 13:17:12 +03:00
bank = ( reg > > 8 ) ;
2017-01-13 12:53:55 +03:00
if ( ! valid_bank ( bank ) ) {
pr_err ( " invalid bank \n " ) ;
2011-02-14 13:17:12 +03:00
return - EINVAL ;
2017-01-13 12:53:55 +03:00
}
2011-02-14 13:17:12 +03:00
return abx500_mask_and_set_register_interruptible ( sysctrl_dev , bank ,
( u8 ) ( reg & 0xFF ) , mask , value ) ;
}
2011-11-11 10:52:10 +04:00
EXPORT_SYMBOL ( ab8500_sysctrl_write ) ;
2011-02-14 13:17:12 +03:00
2012-11-19 22:23:04 +04:00
static int ab8500_sysctrl_probe ( struct platform_device * pdev )
2011-02-14 13:17:12 +03:00
{
2013-04-26 16:17:17 +04:00
sysctrl_dev = & pdev - > dev ;
2013-05-09 15:08:08 +04:00
if ( ! pm_power_off )
2013-01-14 17:26:15 +04:00
pm_power_off = ab8500_power_off ;
2011-09-27 11:23:56 +04:00
2011-02-14 13:17:12 +03:00
return 0 ;
}
2012-11-19 22:26:01 +04:00
static int ab8500_sysctrl_remove ( struct platform_device * pdev )
2011-02-14 13:17:12 +03:00
{
sysctrl_dev = NULL ;
2013-05-09 15:08:08 +04:00
if ( pm_power_off = = ab8500_power_off )
pm_power_off = NULL ;
2011-02-14 13:17:12 +03:00
return 0 ;
}
2017-01-13 12:53:55 +03:00
static const struct of_device_id ab8500_sysctrl_match [ ] = {
{ . compatible = " stericsson,ab8500-sysctrl " , } ,
{ }
} ;
2011-02-14 13:17:12 +03:00
static struct platform_driver ab8500_sysctrl_driver = {
. driver = {
. name = " ab8500-sysctrl " ,
2017-01-13 12:53:55 +03:00
. of_match_table = ab8500_sysctrl_match ,
2011-02-14 13:17:12 +03:00
} ,
. probe = ab8500_sysctrl_probe ,
2012-11-19 22:20:24 +04:00
. remove = ab8500_sysctrl_remove ,
2011-02-14 13:17:12 +03:00
} ;
static int __init ab8500_sysctrl_init ( void )
{
return platform_driver_register ( & ab8500_sysctrl_driver ) ;
}
2013-04-03 03:06:27 +04:00
arch_initcall ( ab8500_sysctrl_init ) ;