2018-09-26 18:27:40 +03:00
// SPDX-License-Identifier: GPL-2.0
2016-11-07 23:11:47 +03:00
/*
2018-09-26 18:27:40 +03:00
* Intel BXT Whiskey Cove PMIC TMU driver
2016-11-07 23:11:47 +03:00
*
* Copyright ( C ) 2016 Intel Corporation . All rights reserved .
*
* This driver adds TMU ( Time Management Unit ) support for Intel BXT platform .
* It enables the alarm wake - up functionality in the TMU unit of Whiskey Cove
* PMIC .
*/
# include <linux/module.h>
2018-06-20 08:47:28 +03:00
# include <linux/mod_devicetable.h>
2016-11-07 23:11:47 +03:00
# include <linux/interrupt.h>
# include <linux/platform_device.h>
# include <linux/mfd/intel_soc_pmic.h>
# define BXTWC_TMUIRQ 0x4fb6
# define BXTWC_MIRQLVL1 0x4e0e
# define BXTWC_MTMUIRQ_REG 0x4fb7
# define BXTWC_MIRQLVL1_MTMU BIT(1)
# define BXTWC_TMU_WK_ALRM BIT(1)
# define BXTWC_TMU_SYS_ALRM BIT(2)
# define BXTWC_TMU_ALRM_MASK (BXTWC_TMU_WK_ALRM | BXTWC_TMU_SYS_ALRM)
# define BXTWC_TMU_ALRM_IRQ (BXTWC_TMU_WK_ALRM | BXTWC_TMU_SYS_ALRM)
struct wcove_tmu {
int irq ;
struct device * dev ;
struct regmap * regmap ;
} ;
static irqreturn_t bxt_wcove_tmu_irq_handler ( int irq , void * data )
{
struct wcove_tmu * wctmu = data ;
unsigned int tmu_irq ;
/* Read TMU interrupt reg */
regmap_read ( wctmu - > regmap , BXTWC_TMUIRQ , & tmu_irq ) ;
if ( tmu_irq & BXTWC_TMU_ALRM_IRQ ) {
/* clear TMU irq */
regmap_write ( wctmu - > regmap , BXTWC_TMUIRQ , tmu_irq ) ;
return IRQ_HANDLED ;
}
return IRQ_NONE ;
}
static int bxt_wcove_tmu_probe ( struct platform_device * pdev )
{
struct intel_soc_pmic * pmic = dev_get_drvdata ( pdev - > dev . parent ) ;
struct regmap_irq_chip_data * regmap_irq_chip ;
struct wcove_tmu * wctmu ;
int ret , virq , irq ;
wctmu = devm_kzalloc ( & pdev - > dev , sizeof ( * wctmu ) , GFP_KERNEL ) ;
if ( ! wctmu )
return - ENOMEM ;
wctmu - > dev = & pdev - > dev ;
wctmu - > regmap = pmic - > regmap ;
irq = platform_get_irq ( pdev , 0 ) ;
if ( irq < 0 ) {
dev_err ( & pdev - > dev , " invalid irq %d \n " , irq ) ;
return irq ;
}
regmap_irq_chip = pmic - > irq_chip_data_tmu ;
virq = regmap_irq_get_virq ( regmap_irq_chip , irq ) ;
if ( virq < 0 ) {
dev_err ( & pdev - > dev ,
" failed to get virtual interrupt=%d \n " , irq ) ;
return virq ;
}
ret = devm_request_threaded_irq ( & pdev - > dev , virq ,
NULL , bxt_wcove_tmu_irq_handler ,
IRQF_ONESHOT , " bxt_wcove_tmu " , wctmu ) ;
if ( ret ) {
dev_err ( & pdev - > dev , " request irq failed: %d,virq: %d \n " ,
ret , virq ) ;
return ret ;
}
wctmu - > irq = virq ;
/* Unmask TMU second level Wake & System alarm */
regmap_update_bits ( wctmu - > regmap , BXTWC_MTMUIRQ_REG ,
BXTWC_TMU_ALRM_MASK , 0 ) ;
platform_set_drvdata ( pdev , wctmu ) ;
return 0 ;
}
static int bxt_wcove_tmu_remove ( struct platform_device * pdev )
{
struct wcove_tmu * wctmu = platform_get_drvdata ( pdev ) ;
unsigned int val ;
/* Mask TMU interrupts */
regmap_read ( wctmu - > regmap , BXTWC_MIRQLVL1 , & val ) ;
regmap_write ( wctmu - > regmap , BXTWC_MIRQLVL1 ,
val | BXTWC_MIRQLVL1_MTMU ) ;
regmap_read ( wctmu - > regmap , BXTWC_MTMUIRQ_REG , & val ) ;
regmap_write ( wctmu - > regmap , BXTWC_MTMUIRQ_REG ,
val | BXTWC_TMU_ALRM_MASK ) ;
return 0 ;
}
# ifdef CONFIG_PM_SLEEP
static int bxtwc_tmu_suspend ( struct device * dev )
{
struct wcove_tmu * wctmu = dev_get_drvdata ( dev ) ;
enable_irq_wake ( wctmu - > irq ) ;
return 0 ;
}
static int bxtwc_tmu_resume ( struct device * dev )
{
struct wcove_tmu * wctmu = dev_get_drvdata ( dev ) ;
disable_irq_wake ( wctmu - > irq ) ;
return 0 ;
}
# endif
static SIMPLE_DEV_PM_OPS ( bxtwc_tmu_pm_ops , bxtwc_tmu_suspend , bxtwc_tmu_resume ) ;
static const struct platform_device_id bxt_wcove_tmu_id_table [ ] = {
{ . name = " bxt_wcove_tmu " } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( platform , bxt_wcove_tmu_id_table ) ;
static struct platform_driver bxt_wcove_tmu_driver = {
. probe = bxt_wcove_tmu_probe ,
. remove = bxt_wcove_tmu_remove ,
. driver = {
. name = " bxt_wcove_tmu " ,
. pm = & bxtwc_tmu_pm_ops ,
} ,
. id_table = bxt_wcove_tmu_id_table ,
} ;
module_platform_driver ( bxt_wcove_tmu_driver ) ;
MODULE_LICENSE ( " GPL v2 " ) ;
MODULE_AUTHOR ( " Nilesh Bacchewar <nilesh.bacchewar@intel.com> " ) ;
MODULE_DESCRIPTION ( " BXT Whiskey Cove TMU Driver " ) ;