2019-04-11 13:22:48 +03:00
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2019 Amazon . com , Inc . or its affiliates . All Rights Reserved .
*/
# include <linux/module.h>
# include <linux/of_address.h>
# include <linux/platform_device.h>
# include <linux/thermal.h>
struct thermal_mmio {
void __iomem * mmio_base ;
u32 ( * read_mmio ) ( void __iomem * mmio_base ) ;
u32 mask ;
int factor ;
} ;
static u32 thermal_mmio_readb ( void __iomem * mmio_base )
{
return readb ( mmio_base ) ;
}
2022-08-05 01:43:22 +03:00
static int thermal_mmio_get_temperature ( struct thermal_zone_device * tz , int * temp )
2019-04-11 13:22:48 +03:00
{
int t ;
2022-08-05 01:43:22 +03:00
struct thermal_mmio * sensor = tz - > devdata ;
2019-04-11 13:22:48 +03:00
t = sensor - > read_mmio ( sensor - > mmio_base ) & sensor - > mask ;
t * = sensor - > factor ;
* temp = t ;
return 0 ;
}
2022-08-05 01:43:22 +03:00
static const struct thermal_zone_device_ops thermal_mmio_ops = {
2019-04-11 13:22:48 +03:00
. get_temp = thermal_mmio_get_temperature ,
} ;
static int thermal_mmio_probe ( struct platform_device * pdev )
{
struct resource * resource ;
struct thermal_mmio * sensor ;
int ( * sensor_init_func ) ( struct platform_device * pdev ,
struct thermal_mmio * sensor ) ;
struct thermal_zone_device * thermal_zone ;
int ret ;
int temperature ;
sensor = devm_kzalloc ( & pdev - > dev , sizeof ( * sensor ) , GFP_KERNEL ) ;
if ( ! sensor )
return - ENOMEM ;
resource = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
sensor - > mmio_base = devm_ioremap_resource ( & pdev - > dev , resource ) ;
2021-04-08 13:01:44 +03:00
if ( IS_ERR ( sensor - > mmio_base ) )
2019-04-11 13:22:48 +03:00
return PTR_ERR ( sensor - > mmio_base ) ;
sensor_init_func = device_get_match_data ( & pdev - > dev ) ;
if ( sensor_init_func ) {
ret = sensor_init_func ( pdev , sensor ) ;
if ( ret ) {
dev_err ( & pdev - > dev ,
" failed to initialize sensor (%d) \n " ,
ret ) ;
return ret ;
}
}
2022-08-05 01:43:22 +03:00
thermal_zone = devm_thermal_of_zone_register ( & pdev - > dev ,
0 ,
sensor ,
& thermal_mmio_ops ) ;
2019-04-11 13:22:48 +03:00
if ( IS_ERR ( thermal_zone ) ) {
dev_err ( & pdev - > dev ,
" failed to register sensor (%ld) \n " ,
PTR_ERR ( thermal_zone ) ) ;
return PTR_ERR ( thermal_zone ) ;
}
2022-08-05 01:43:22 +03:00
thermal_mmio_get_temperature ( thermal_zone , & temperature ) ;
2019-04-11 13:22:48 +03:00
dev_info ( & pdev - > dev ,
" thermal mmio sensor %s registered, current temperature: %d \n " ,
pdev - > name , temperature ) ;
return 0 ;
}
static int al_thermal_init ( struct platform_device * pdev ,
struct thermal_mmio * sensor )
{
sensor - > read_mmio = thermal_mmio_readb ;
sensor - > mask = 0xff ;
sensor - > factor = 1000 ;
return 0 ;
}
static const struct of_device_id thermal_mmio_id_table [ ] = {
{ . compatible = " amazon,al-thermal " , . data = al_thermal_init } ,
{ }
} ;
MODULE_DEVICE_TABLE ( of , thermal_mmio_id_table ) ;
static struct platform_driver thermal_mmio_driver = {
. probe = thermal_mmio_probe ,
. driver = {
. name = " thermal-mmio " ,
. of_match_table = of_match_ptr ( thermal_mmio_id_table ) ,
} ,
} ;
module_platform_driver ( thermal_mmio_driver ) ;
MODULE_AUTHOR ( " Talel Shenhar <talel@amazon.com> " ) ;
MODULE_DESCRIPTION ( " Thermal MMIO Driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;