12dfef650SFabio Estevam // SPDX-License-Identifier: GPL-2.0
22dfef650SFabio Estevam //
32dfef650SFabio Estevam // Copyright 2016 Freescale Semiconductor, Inc.
443528445SJia Hongtao 
551904045SAnson Huang #include <linux/clk.h>
643528445SJia Hongtao #include <linux/module.h>
743528445SJia Hongtao #include <linux/platform_device.h>
843528445SJia Hongtao #include <linux/err.h>
943528445SJia Hongtao #include <linux/io.h>
1043528445SJia Hongtao #include <linux/of.h>
1143528445SJia Hongtao #include <linux/of_address.h>
1243528445SJia Hongtao #include <linux/thermal.h>
1343528445SJia Hongtao 
1443528445SJia Hongtao #include "thermal_core.h"
1543528445SJia Hongtao 
1643528445SJia Hongtao #define SITES_MAX		16
179809797bSYuantian Tang #define TMR_DISABLE		0x0
189809797bSYuantian Tang #define TMR_ME			0x80000000
199809797bSYuantian Tang #define TMR_ALPF		0x0c000000
209809797bSYuantian Tang #define TMR_ALPF_V2		0x03000000
219809797bSYuantian Tang #define TMTMIR_DEFAULT	0x0000000f
229809797bSYuantian Tang #define TIER_DISABLE	0x0
239809797bSYuantian Tang #define TEUMR0_V2		0x51009c00
249809797bSYuantian Tang #define TMU_VER1		0x1
259809797bSYuantian Tang #define TMU_VER2		0x2
2643528445SJia Hongtao 
2743528445SJia Hongtao /*
2843528445SJia Hongtao  * QorIQ TMU Registers
2943528445SJia Hongtao  */
3043528445SJia Hongtao struct qoriq_tmu_site_regs {
3143528445SJia Hongtao 	u32 tritsr;		/* Immediate Temperature Site Register */
3243528445SJia Hongtao 	u32 tratsr;		/* Average Temperature Site Register */
3343528445SJia Hongtao 	u8 res0[0x8];
3443528445SJia Hongtao };
3543528445SJia Hongtao 
369809797bSYuantian Tang struct qoriq_tmu_regs_v1 {
3743528445SJia Hongtao 	u32 tmr;		/* Mode Register */
3843528445SJia Hongtao 	u32 tsr;		/* Status Register */
3943528445SJia Hongtao 	u32 tmtmir;		/* Temperature measurement interval Register */
4043528445SJia Hongtao 	u8 res0[0x14];
4143528445SJia Hongtao 	u32 tier;		/* Interrupt Enable Register */
4243528445SJia Hongtao 	u32 tidr;		/* Interrupt Detect Register */
4343528445SJia Hongtao 	u32 tiscr;		/* Interrupt Site Capture Register */
4443528445SJia Hongtao 	u32 ticscr;		/* Interrupt Critical Site Capture Register */
4543528445SJia Hongtao 	u8 res1[0x10];
4643528445SJia Hongtao 	u32 tmhtcrh;		/* High Temperature Capture Register */
4743528445SJia Hongtao 	u32 tmhtcrl;		/* Low Temperature Capture Register */
4843528445SJia Hongtao 	u8 res2[0x8];
4943528445SJia Hongtao 	u32 tmhtitr;		/* High Temperature Immediate Threshold */
5043528445SJia Hongtao 	u32 tmhtatr;		/* High Temperature Average Threshold */
5143528445SJia Hongtao 	u32 tmhtactr;	/* High Temperature Average Crit Threshold */
5243528445SJia Hongtao 	u8 res3[0x24];
5343528445SJia Hongtao 	u32 ttcfgr;		/* Temperature Configuration Register */
5443528445SJia Hongtao 	u32 tscfgr;		/* Sensor Configuration Register */
5543528445SJia Hongtao 	u8 res4[0x78];
5643528445SJia Hongtao 	struct qoriq_tmu_site_regs site[SITES_MAX];
5743528445SJia Hongtao 	u8 res5[0x9f8];
5843528445SJia Hongtao 	u32 ipbrr0;		/* IP Block Revision Register 0 */
5943528445SJia Hongtao 	u32 ipbrr1;		/* IP Block Revision Register 1 */
6043528445SJia Hongtao 	u8 res6[0x310];
619809797bSYuantian Tang 	u32 ttrcr[4];		/* Temperature Range Control Register */
629809797bSYuantian Tang };
639809797bSYuantian Tang 
649809797bSYuantian Tang struct qoriq_tmu_regs_v2 {
659809797bSYuantian Tang 	u32 tmr;		/* Mode Register */
669809797bSYuantian Tang 	u32 tsr;		/* Status Register */
679809797bSYuantian Tang 	u32 tmsr;		/* monitor site register */
689809797bSYuantian Tang 	u32 tmtmir;		/* Temperature measurement interval Register */
699809797bSYuantian Tang 	u8 res0[0x10];
709809797bSYuantian Tang 	u32 tier;		/* Interrupt Enable Register */
719809797bSYuantian Tang 	u32 tidr;		/* Interrupt Detect Register */
729809797bSYuantian Tang 	u8 res1[0x8];
739809797bSYuantian Tang 	u32 tiiscr;		/* interrupt immediate site capture register */
749809797bSYuantian Tang 	u32 tiascr;		/* interrupt average site capture register */
759809797bSYuantian Tang 	u32 ticscr;		/* Interrupt Critical Site Capture Register */
769809797bSYuantian Tang 	u32 res2;
779809797bSYuantian Tang 	u32 tmhtcr;		/* monitor high temperature capture register */
789809797bSYuantian Tang 	u32 tmltcr;		/* monitor low temperature capture register */
799809797bSYuantian Tang 	u32 tmrtrcr;	/* monitor rising temperature rate capture register */
809809797bSYuantian Tang 	u32 tmftrcr;	/* monitor falling temperature rate capture register */
819809797bSYuantian Tang 	u32 tmhtitr;	/* High Temperature Immediate Threshold */
829809797bSYuantian Tang 	u32 tmhtatr;	/* High Temperature Average Threshold */
839809797bSYuantian Tang 	u32 tmhtactr;	/* High Temperature Average Crit Threshold */
849809797bSYuantian Tang 	u32 res3;
859809797bSYuantian Tang 	u32 tmltitr;	/* monitor low temperature immediate threshold */
869809797bSYuantian Tang 	u32 tmltatr;	/* monitor low temperature average threshold register */
879809797bSYuantian Tang 	u32 tmltactr;	/* monitor low temperature average critical threshold */
889809797bSYuantian Tang 	u32 res4;
899809797bSYuantian Tang 	u32 tmrtrctr;	/* monitor rising temperature rate critical threshold */
909809797bSYuantian Tang 	u32 tmftrctr;	/* monitor falling temperature rate critical threshold*/
919809797bSYuantian Tang 	u8 res5[0x8];
929809797bSYuantian Tang 	u32 ttcfgr;	/* Temperature Configuration Register */
939809797bSYuantian Tang 	u32 tscfgr;	/* Sensor Configuration Register */
949809797bSYuantian Tang 	u8 res6[0x78];
959809797bSYuantian Tang 	struct qoriq_tmu_site_regs site[SITES_MAX];
969809797bSYuantian Tang 	u8 res7[0x9f8];
979809797bSYuantian Tang 	u32 ipbrr0;		/* IP Block Revision Register 0 */
989809797bSYuantian Tang 	u32 ipbrr1;		/* IP Block Revision Register 1 */
999809797bSYuantian Tang 	u8 res8[0x300];
1009809797bSYuantian Tang 	u32 teumr0;
1019809797bSYuantian Tang 	u32 teumr1;
1029809797bSYuantian Tang 	u32 teumr2;
1039809797bSYuantian Tang 	u32 res9;
1049809797bSYuantian Tang 	u32 ttrcr[4];	/* Temperature Range Control Register */
10543528445SJia Hongtao };
10643528445SJia Hongtao 
1077797ff42SYuantian Tang struct qoriq_tmu_data;
1087797ff42SYuantian Tang 
10943528445SJia Hongtao /*
11043528445SJia Hongtao  * Thermal zone data
11143528445SJia Hongtao  */
1127797ff42SYuantian Tang struct qoriq_sensor {
1137797ff42SYuantian Tang 	struct qoriq_tmu_data		*qdata;
1147797ff42SYuantian Tang 	int				id;
1157797ff42SYuantian Tang };
1167797ff42SYuantian Tang 
11743528445SJia Hongtao struct qoriq_tmu_data {
1189809797bSYuantian Tang 	int ver;
1199809797bSYuantian Tang 	struct qoriq_tmu_regs_v1 __iomem *regs;
1209809797bSYuantian Tang 	struct qoriq_tmu_regs_v2 __iomem *regs_v2;
12151904045SAnson Huang 	struct clk *clk;
12243528445SJia Hongtao 	bool little_endian;
1237797ff42SYuantian Tang 	struct qoriq_sensor	*sensor[SITES_MAX];
12443528445SJia Hongtao };
12543528445SJia Hongtao 
12643528445SJia Hongtao static void tmu_write(struct qoriq_tmu_data *p, u32 val, void __iomem *addr)
12743528445SJia Hongtao {
12843528445SJia Hongtao 	if (p->little_endian)
12943528445SJia Hongtao 		iowrite32(val, addr);
13043528445SJia Hongtao 	else
13143528445SJia Hongtao 		iowrite32be(val, addr);
13243528445SJia Hongtao }
13343528445SJia Hongtao 
13443528445SJia Hongtao static u32 tmu_read(struct qoriq_tmu_data *p, void __iomem *addr)
13543528445SJia Hongtao {
13643528445SJia Hongtao 	if (p->little_endian)
13743528445SJia Hongtao 		return ioread32(addr);
13843528445SJia Hongtao 	else
13943528445SJia Hongtao 		return ioread32be(addr);
14043528445SJia Hongtao }
14143528445SJia Hongtao 
14243528445SJia Hongtao static int tmu_get_temp(void *p, int *temp)
14343528445SJia Hongtao {
1447797ff42SYuantian Tang 	struct qoriq_sensor *qsensor = p;
1457797ff42SYuantian Tang 	struct qoriq_tmu_data *qdata = qsensor->qdata;
14643528445SJia Hongtao 	u32 val;
14743528445SJia Hongtao 
1487797ff42SYuantian Tang 	val = tmu_read(qdata, &qdata->regs->site[qsensor->id].tritsr);
14943528445SJia Hongtao 	*temp = (val & 0xff) * 1000;
15043528445SJia Hongtao 
15143528445SJia Hongtao 	return 0;
15243528445SJia Hongtao }
15343528445SJia Hongtao 
1547797ff42SYuantian Tang static const struct thermal_zone_of_device_ops tmu_tz_ops = {
1557797ff42SYuantian Tang 	.get_temp = tmu_get_temp,
1567797ff42SYuantian Tang };
1577797ff42SYuantian Tang 
1587797ff42SYuantian Tang static int qoriq_tmu_register_tmu_zone(struct platform_device *pdev)
15943528445SJia Hongtao {
1607797ff42SYuantian Tang 	struct qoriq_tmu_data *qdata = platform_get_drvdata(pdev);
1617797ff42SYuantian Tang 	int id, sites = 0;
16243528445SJia Hongtao 
1637797ff42SYuantian Tang 	for (id = 0; id < SITES_MAX; id++) {
16411ef00f7SAndrey Smirnov 		struct thermal_zone_device *tzd;
16511ef00f7SAndrey Smirnov 		int ret;
16611ef00f7SAndrey Smirnov 
1677797ff42SYuantian Tang 		qdata->sensor[id] = devm_kzalloc(&pdev->dev,
1687797ff42SYuantian Tang 				sizeof(struct qoriq_sensor), GFP_KERNEL);
1697797ff42SYuantian Tang 		if (!qdata->sensor[id])
1707797ff42SYuantian Tang 			return -ENOMEM;
17143528445SJia Hongtao 
1727797ff42SYuantian Tang 		qdata->sensor[id]->id = id;
1737797ff42SYuantian Tang 		qdata->sensor[id]->qdata = qdata;
17411ef00f7SAndrey Smirnov 
17511ef00f7SAndrey Smirnov 		tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, id,
17611ef00f7SAndrey Smirnov 							   qdata->sensor[id],
17711ef00f7SAndrey Smirnov 							   &tmu_tz_ops);
17811ef00f7SAndrey Smirnov 		ret = PTR_ERR_OR_ZERO(tzd);
17911ef00f7SAndrey Smirnov 		if (ret) {
18011ef00f7SAndrey Smirnov 			if (ret == -ENODEV)
1817797ff42SYuantian Tang 				continue;
1827797ff42SYuantian Tang 			else
18311ef00f7SAndrey Smirnov 				return ret;
18443528445SJia Hongtao 		}
18543528445SJia Hongtao 
1869809797bSYuantian Tang 		if (qdata->ver == TMU_VER1)
1877797ff42SYuantian Tang 			sites |= 0x1 << (15 - id);
1889809797bSYuantian Tang 		else
1899809797bSYuantian Tang 			sites |= 0x1 << id;
19043528445SJia Hongtao 	}
19143528445SJia Hongtao 
1927797ff42SYuantian Tang 	/* Enable monitoring */
1939809797bSYuantian Tang 	if (sites != 0) {
1949809797bSYuantian Tang 		if (qdata->ver == TMU_VER1) {
1959809797bSYuantian Tang 			tmu_write(qdata, sites | TMR_ME | TMR_ALPF,
1969809797bSYuantian Tang 					&qdata->regs->tmr);
1979809797bSYuantian Tang 		} else {
1989809797bSYuantian Tang 			tmu_write(qdata, sites, &qdata->regs_v2->tmsr);
1999809797bSYuantian Tang 			tmu_write(qdata, TMR_ME | TMR_ALPF_V2,
2009809797bSYuantian Tang 					&qdata->regs_v2->tmr);
2019809797bSYuantian Tang 		}
2029809797bSYuantian Tang 	}
20343528445SJia Hongtao 
2047797ff42SYuantian Tang 	return 0;
20543528445SJia Hongtao }
20643528445SJia Hongtao 
20743528445SJia Hongtao static int qoriq_tmu_calibration(struct platform_device *pdev)
20843528445SJia Hongtao {
20943528445SJia Hongtao 	int i, val, len;
21043528445SJia Hongtao 	u32 range[4];
21143528445SJia Hongtao 	const u32 *calibration;
21243528445SJia Hongtao 	struct device_node *np = pdev->dev.of_node;
21343528445SJia Hongtao 	struct qoriq_tmu_data *data = platform_get_drvdata(pdev);
21443528445SJia Hongtao 
2159809797bSYuantian Tang 	len = of_property_count_u32_elems(np, "fsl,tmu-range");
2169809797bSYuantian Tang 	if (len < 0 || len > 4) {
2179809797bSYuantian Tang 		dev_err(&pdev->dev, "invalid range data.\n");
2189809797bSYuantian Tang 		return len;
2199809797bSYuantian Tang 	}
2209809797bSYuantian Tang 
2219809797bSYuantian Tang 	val = of_property_read_u32_array(np, "fsl,tmu-range", range, len);
2229809797bSYuantian Tang 	if (val != 0) {
2239809797bSYuantian Tang 		dev_err(&pdev->dev, "failed to read range data.\n");
2249809797bSYuantian Tang 		return val;
22543528445SJia Hongtao 	}
22643528445SJia Hongtao 
22743528445SJia Hongtao 	/* Init temperature range registers */
2289809797bSYuantian Tang 	for (i = 0; i < len; i++)
2299809797bSYuantian Tang 		tmu_write(data, range[i], &data->regs->ttrcr[i]);
23043528445SJia Hongtao 
23143528445SJia Hongtao 	calibration = of_get_property(np, "fsl,tmu-calibration", &len);
23243528445SJia Hongtao 	if (calibration == NULL || len % 8) {
23343528445SJia Hongtao 		dev_err(&pdev->dev, "invalid calibration data.\n");
23443528445SJia Hongtao 		return -ENODEV;
23543528445SJia Hongtao 	}
23643528445SJia Hongtao 
23743528445SJia Hongtao 	for (i = 0; i < len; i += 8, calibration += 2) {
23843528445SJia Hongtao 		val = of_read_number(calibration, 1);
23943528445SJia Hongtao 		tmu_write(data, val, &data->regs->ttcfgr);
24043528445SJia Hongtao 		val = of_read_number(calibration + 1, 1);
24143528445SJia Hongtao 		tmu_write(data, val, &data->regs->tscfgr);
24243528445SJia Hongtao 	}
24343528445SJia Hongtao 
24443528445SJia Hongtao 	return 0;
24543528445SJia Hongtao }
24643528445SJia Hongtao 
24743528445SJia Hongtao static void qoriq_tmu_init_device(struct qoriq_tmu_data *data)
24843528445SJia Hongtao {
24943528445SJia Hongtao 	/* Disable interrupt, using polling instead */
25043528445SJia Hongtao 	tmu_write(data, TIER_DISABLE, &data->regs->tier);
25143528445SJia Hongtao 
25243528445SJia Hongtao 	/* Set update_interval */
2539809797bSYuantian Tang 	if (data->ver == TMU_VER1) {
25443528445SJia Hongtao 		tmu_write(data, TMTMIR_DEFAULT, &data->regs->tmtmir);
2559809797bSYuantian Tang 	} else {
2569809797bSYuantian Tang 		tmu_write(data, TMTMIR_DEFAULT, &data->regs_v2->tmtmir);
2579809797bSYuantian Tang 		tmu_write(data, TEUMR0_V2, &data->regs_v2->teumr0);
2589809797bSYuantian Tang 	}
25943528445SJia Hongtao 
26043528445SJia Hongtao 	/* Disable monitoring */
26143528445SJia Hongtao 	tmu_write(data, TMR_DISABLE, &data->regs->tmr);
26243528445SJia Hongtao }
26343528445SJia Hongtao 
26443528445SJia Hongtao static int qoriq_tmu_probe(struct platform_device *pdev)
26543528445SJia Hongtao {
26643528445SJia Hongtao 	int ret;
2679809797bSYuantian Tang 	u32 ver;
26843528445SJia Hongtao 	struct qoriq_tmu_data *data;
26943528445SJia Hongtao 	struct device_node *np = pdev->dev.of_node;
270e167dc43SAndrey Smirnov 	struct device *dev = &pdev->dev;
27143528445SJia Hongtao 
272e167dc43SAndrey Smirnov 	data = devm_kzalloc(dev, sizeof(struct qoriq_tmu_data),
27343528445SJia Hongtao 			    GFP_KERNEL);
27443528445SJia Hongtao 	if (!data)
27543528445SJia Hongtao 		return -ENOMEM;
27643528445SJia Hongtao 
27743528445SJia Hongtao 	platform_set_drvdata(pdev, data);
27843528445SJia Hongtao 
27943528445SJia Hongtao 	data->little_endian = of_property_read_bool(np, "little-endian");
28043528445SJia Hongtao 
2814d82000aSAnson Huang 	data->regs = devm_platform_ioremap_resource(pdev, 0);
2824d82000aSAnson Huang 	if (IS_ERR(data->regs)) {
283e167dc43SAndrey Smirnov 		dev_err(dev, "Failed to get memory region\n");
2844d82000aSAnson Huang 		return PTR_ERR(data->regs);
28543528445SJia Hongtao 	}
28643528445SJia Hongtao 
287e167dc43SAndrey Smirnov 	data->clk = devm_clk_get_optional(dev, NULL);
28851904045SAnson Huang 	if (IS_ERR(data->clk))
28951904045SAnson Huang 		return PTR_ERR(data->clk);
29051904045SAnson Huang 
29151904045SAnson Huang 	ret = clk_prepare_enable(data->clk);
29251904045SAnson Huang 	if (ret) {
293e167dc43SAndrey Smirnov 		dev_err(dev, "Failed to enable clock\n");
29451904045SAnson Huang 		return ret;
29551904045SAnson Huang 	}
29651904045SAnson Huang 
2979809797bSYuantian Tang 	/* version register offset at: 0xbf8 on both v1 and v2 */
2989809797bSYuantian Tang 	ver = tmu_read(data, &data->regs->ipbrr0);
2999809797bSYuantian Tang 	data->ver = (ver >> 8) & 0xff;
3009809797bSYuantian Tang 	if (data->ver == TMU_VER2)
3019809797bSYuantian Tang 		data->regs_v2 = (void __iomem *)data->regs;
3029809797bSYuantian Tang 
30343528445SJia Hongtao 	qoriq_tmu_init_device(data);	/* TMU initialization */
30443528445SJia Hongtao 
30543528445SJia Hongtao 	ret = qoriq_tmu_calibration(pdev);	/* TMU calibration */
30643528445SJia Hongtao 	if (ret < 0)
3074d82000aSAnson Huang 		goto err;
30843528445SJia Hongtao 
3097797ff42SYuantian Tang 	ret = qoriq_tmu_register_tmu_zone(pdev);
3107797ff42SYuantian Tang 	if (ret < 0) {
311e167dc43SAndrey Smirnov 		dev_err(dev, "Failed to register sensors\n");
3127797ff42SYuantian Tang 		ret = -ENODEV;
3134d82000aSAnson Huang 		goto err;
31443528445SJia Hongtao 	}
31543528445SJia Hongtao 
31643528445SJia Hongtao 	return 0;
31743528445SJia Hongtao 
3184d82000aSAnson Huang err:
31951904045SAnson Huang 	clk_disable_unprepare(data->clk);
32043528445SJia Hongtao 	platform_set_drvdata(pdev, NULL);
32143528445SJia Hongtao 
32243528445SJia Hongtao 	return ret;
32343528445SJia Hongtao }
32443528445SJia Hongtao 
32543528445SJia Hongtao static int qoriq_tmu_remove(struct platform_device *pdev)
32643528445SJia Hongtao {
32743528445SJia Hongtao 	struct qoriq_tmu_data *data = platform_get_drvdata(pdev);
32843528445SJia Hongtao 
32943528445SJia Hongtao 	/* Disable monitoring */
33043528445SJia Hongtao 	tmu_write(data, TMR_DISABLE, &data->regs->tmr);
33143528445SJia Hongtao 
33251904045SAnson Huang 	clk_disable_unprepare(data->clk);
33351904045SAnson Huang 
33443528445SJia Hongtao 	platform_set_drvdata(pdev, NULL);
33543528445SJia Hongtao 
33643528445SJia Hongtao 	return 0;
33743528445SJia Hongtao }
33843528445SJia Hongtao 
339aea59197SAnson Huang static int __maybe_unused qoriq_tmu_suspend(struct device *dev)
34043528445SJia Hongtao {
34143528445SJia Hongtao 	u32 tmr;
34243528445SJia Hongtao 	struct qoriq_tmu_data *data = dev_get_drvdata(dev);
34343528445SJia Hongtao 
34443528445SJia Hongtao 	/* Disable monitoring */
34543528445SJia Hongtao 	tmr = tmu_read(data, &data->regs->tmr);
34643528445SJia Hongtao 	tmr &= ~TMR_ME;
34743528445SJia Hongtao 	tmu_write(data, tmr, &data->regs->tmr);
34843528445SJia Hongtao 
34951904045SAnson Huang 	clk_disable_unprepare(data->clk);
35051904045SAnson Huang 
35143528445SJia Hongtao 	return 0;
35243528445SJia Hongtao }
35343528445SJia Hongtao 
354aea59197SAnson Huang static int __maybe_unused qoriq_tmu_resume(struct device *dev)
35543528445SJia Hongtao {
35643528445SJia Hongtao 	u32 tmr;
35751904045SAnson Huang 	int ret;
35843528445SJia Hongtao 	struct qoriq_tmu_data *data = dev_get_drvdata(dev);
35943528445SJia Hongtao 
36051904045SAnson Huang 	ret = clk_prepare_enable(data->clk);
36151904045SAnson Huang 	if (ret)
36251904045SAnson Huang 		return ret;
36351904045SAnson Huang 
36443528445SJia Hongtao 	/* Enable monitoring */
36543528445SJia Hongtao 	tmr = tmu_read(data, &data->regs->tmr);
36643528445SJia Hongtao 	tmr |= TMR_ME;
36743528445SJia Hongtao 	tmu_write(data, tmr, &data->regs->tmr);
36843528445SJia Hongtao 
36943528445SJia Hongtao 	return 0;
37043528445SJia Hongtao }
37143528445SJia Hongtao 
37243528445SJia Hongtao static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops,
37343528445SJia Hongtao 			 qoriq_tmu_suspend, qoriq_tmu_resume);
37443528445SJia Hongtao 
37543528445SJia Hongtao static const struct of_device_id qoriq_tmu_match[] = {
37643528445SJia Hongtao 	{ .compatible = "fsl,qoriq-tmu", },
3776017e2a9SAnson Huang 	{ .compatible = "fsl,imx8mq-tmu", },
37843528445SJia Hongtao 	{},
37943528445SJia Hongtao };
38043528445SJia Hongtao MODULE_DEVICE_TABLE(of, qoriq_tmu_match);
38143528445SJia Hongtao 
38243528445SJia Hongtao static struct platform_driver qoriq_tmu = {
38343528445SJia Hongtao 	.driver	= {
38443528445SJia Hongtao 		.name		= "qoriq_thermal",
38543528445SJia Hongtao 		.pm		= &qoriq_tmu_pm_ops,
38643528445SJia Hongtao 		.of_match_table	= qoriq_tmu_match,
38743528445SJia Hongtao 	},
38843528445SJia Hongtao 	.probe	= qoriq_tmu_probe,
38943528445SJia Hongtao 	.remove	= qoriq_tmu_remove,
39043528445SJia Hongtao };
39143528445SJia Hongtao module_platform_driver(qoriq_tmu);
39243528445SJia Hongtao 
39343528445SJia Hongtao MODULE_AUTHOR("Jia Hongtao <hongtao.jia@nxp.com>");
39443528445SJia Hongtao MODULE_DESCRIPTION("QorIQ Thermal Monitoring Unit driver");
39543528445SJia Hongtao MODULE_LICENSE("GPL v2");
396