116 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.4 */5 6#include <linux/module.h>7#include <linux/of_address.h>8#include <linux/platform_device.h>9#include <linux/thermal.h>10 11struct thermal_mmio {12 void __iomem *mmio_base;13 u32 (*read_mmio)(void __iomem *mmio_base);14 u32 mask;15 int factor;16};17 18static u32 thermal_mmio_readb(void __iomem *mmio_base)19{20 return readb(mmio_base);21}22 23static int thermal_mmio_get_temperature(struct thermal_zone_device *tz, int *temp)24{25 int t;26 struct thermal_mmio *sensor = thermal_zone_device_priv(tz);27 28 t = sensor->read_mmio(sensor->mmio_base) & sensor->mask;29 t *= sensor->factor;30 31 *temp = t;32 33 return 0;34}35 36static const struct thermal_zone_device_ops thermal_mmio_ops = {37 .get_temp = thermal_mmio_get_temperature,38};39 40static int thermal_mmio_probe(struct platform_device *pdev)41{42 struct thermal_mmio *sensor;43 int (*sensor_init_func)(struct platform_device *pdev,44 struct thermal_mmio *sensor);45 struct thermal_zone_device *thermal_zone;46 int ret;47 int temperature;48 49 sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL);50 if (!sensor)51 return -ENOMEM;52 53 sensor->mmio_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);54 if (IS_ERR(sensor->mmio_base))55 return PTR_ERR(sensor->mmio_base);56 57 sensor_init_func = device_get_match_data(&pdev->dev);58 if (sensor_init_func) {59 ret = sensor_init_func(pdev, sensor);60 if (ret) {61 dev_err(&pdev->dev,62 "failed to initialize sensor (%d)\n",63 ret);64 return ret;65 }66 }67 68 thermal_zone = devm_thermal_of_zone_register(&pdev->dev,69 0,70 sensor,71 &thermal_mmio_ops);72 if (IS_ERR(thermal_zone)) {73 dev_err(&pdev->dev,74 "failed to register sensor (%ld)\n",75 PTR_ERR(thermal_zone));76 return PTR_ERR(thermal_zone);77 }78 79 thermal_mmio_get_temperature(thermal_zone, &temperature);80 dev_info(&pdev->dev,81 "thermal mmio sensor %s registered, current temperature: %d\n",82 pdev->name, temperature);83 84 return 0;85}86 87static int al_thermal_init(struct platform_device *pdev,88 struct thermal_mmio *sensor)89{90 sensor->read_mmio = thermal_mmio_readb;91 sensor->mask = 0xff;92 sensor->factor = 1000;93 94 return 0;95}96 97static const struct of_device_id thermal_mmio_id_table[] = {98 { .compatible = "amazon,al-thermal", .data = al_thermal_init},99 {}100};101MODULE_DEVICE_TABLE(of, thermal_mmio_id_table);102 103static struct platform_driver thermal_mmio_driver = {104 .probe = thermal_mmio_probe,105 .driver = {106 .name = "thermal-mmio",107 .of_match_table = thermal_mmio_id_table,108 },109};110 111module_platform_driver(thermal_mmio_driver);112 113MODULE_AUTHOR("Talel Shenhar <talel@amazon.com>");114MODULE_DESCRIPTION("Thermal MMIO Driver");115MODULE_LICENSE("GPL v2");116