123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- // 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);
- }
- static int thermal_mmio_get_temperature(struct thermal_zone_device *tz, int *temp)
- {
- int t;
- struct thermal_mmio *sensor = tz->devdata;
- t = sensor->read_mmio(sensor->mmio_base) & sensor->mask;
- t *= sensor->factor;
- *temp = t;
- return 0;
- }
- static const struct thermal_zone_device_ops thermal_mmio_ops = {
- .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);
- if (IS_ERR(sensor->mmio_base))
- 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;
- }
- }
- thermal_zone = devm_thermal_of_zone_register(&pdev->dev,
- 0,
- sensor,
- &thermal_mmio_ops);
- if (IS_ERR(thermal_zone)) {
- dev_err(&pdev->dev,
- "failed to register sensor (%ld)\n",
- PTR_ERR(thermal_zone));
- return PTR_ERR(thermal_zone);
- }
- thermal_mmio_get_temperature(thermal_zone, &temperature);
- 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 = thermal_mmio_id_table,
- },
- };
- module_platform_driver(thermal_mmio_driver);
- MODULE_AUTHOR("Talel Shenhar <[email protected]>");
- MODULE_DESCRIPTION("Thermal MMIO Driver");
- MODULE_LICENSE("GPL v2");
|