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 thermal_zone_device	*tzd;
1147797ff42SYuantian Tang 	struct qoriq_tmu_data		*qdata;
1157797ff42SYuantian Tang 	int				id;
1167797ff42SYuantian Tang };
1177797ff42SYuantian Tang 
11843528445SJia Hongtao struct qoriq_tmu_data {
1199809797bSYuantian Tang 	int ver;
1209809797bSYuantian Tang 	struct qoriq_tmu_regs_v1 __iomem *regs;
1219809797bSYuantian Tang 	struct qoriq_tmu_regs_v2 __iomem *regs_v2;
12251904045SAnson Huang 	struct clk *clk;
12343528445SJia Hongtao 	bool little_endian;
1247797ff42SYuantian Tang 	struct qoriq_sensor	*sensor[SITES_MAX];
12543528445SJia Hongtao };
12643528445SJia Hongtao 
12743528445SJia Hongtao static void tmu_write(struct qoriq_tmu_data *p, u32 val, void __iomem *addr)
12843528445SJia Hongtao {
12943528445SJia Hongtao 	if (p->little_endian)
13043528445SJia Hongtao 		iowrite32(val, addr);
13143528445SJia Hongtao 	else
13243528445SJia Hongtao 		iowrite32be(val, addr);
13343528445SJia Hongtao }
13443528445SJia Hongtao 
13543528445SJia Hongtao static u32 tmu_read(struct qoriq_tmu_data *p, void __iomem *addr)
13643528445SJia Hongtao {
13743528445SJia Hongtao 	if (p->little_endian)
13843528445SJia Hongtao 		return ioread32(addr);
13943528445SJia Hongtao 	else
14043528445SJia Hongtao 		return ioread32be(addr);
14143528445SJia Hongtao }
14243528445SJia Hongtao 
14343528445SJia Hongtao static int tmu_get_temp(void *p, int *temp)
14443528445SJia Hongtao {
1457797ff42SYuantian Tang 	struct qoriq_sensor *qsensor = p;
1467797ff42SYuantian Tang 	struct qoriq_tmu_data *qdata = qsensor->qdata;
14743528445SJia Hongtao 	u32 val;
14843528445SJia Hongtao 
1497797ff42SYuantian Tang 	val = tmu_read(qdata, &qdata->regs->site[qsensor->id].tritsr);
15043528445SJia Hongtao 	*temp = (val & 0xff) * 1000;
15143528445SJia Hongtao 
15243528445SJia Hongtao 	return 0;
15343528445SJia Hongtao }
15443528445SJia Hongtao 
1557797ff42SYuantian Tang static const struct thermal_zone_of_device_ops tmu_tz_ops = {
1567797ff42SYuantian Tang 	.get_temp = tmu_get_temp,
1577797ff42SYuantian Tang };
1587797ff42SYuantian Tang 
1597797ff42SYuantian Tang static int qoriq_tmu_register_tmu_zone(struct platform_device *pdev)
16043528445SJia Hongtao {
1617797ff42SYuantian Tang 	struct qoriq_tmu_data *qdata = platform_get_drvdata(pdev);
1627797ff42SYuantian Tang 	int id, sites = 0;
16343528445SJia Hongtao 
1647797ff42SYuantian Tang 	for (id = 0; id < SITES_MAX; id++) {
1657797ff42SYuantian Tang 		qdata->sensor[id] = devm_kzalloc(&pdev->dev,
1667797ff42SYuantian Tang 				sizeof(struct qoriq_sensor), GFP_KERNEL);
1677797ff42SYuantian Tang 		if (!qdata->sensor[id])
1687797ff42SYuantian Tang 			return -ENOMEM;
16943528445SJia Hongtao 
1707797ff42SYuantian Tang 		qdata->sensor[id]->id = id;
1717797ff42SYuantian Tang 		qdata->sensor[id]->qdata = qdata;
1727797ff42SYuantian Tang 		qdata->sensor[id]->tzd = devm_thermal_zone_of_sensor_register(
1737797ff42SYuantian Tang 				&pdev->dev, id, qdata->sensor[id], &tmu_tz_ops);
1747797ff42SYuantian Tang 		if (IS_ERR(qdata->sensor[id]->tzd)) {
1757797ff42SYuantian Tang 			if (PTR_ERR(qdata->sensor[id]->tzd) == -ENODEV)
1767797ff42SYuantian Tang 				continue;
1777797ff42SYuantian Tang 			else
1787797ff42SYuantian Tang 				return PTR_ERR(qdata->sensor[id]->tzd);
17943528445SJia Hongtao 		}
18043528445SJia Hongtao 
1819809797bSYuantian Tang 		if (qdata->ver == TMU_VER1)
1827797ff42SYuantian Tang 			sites |= 0x1 << (15 - id);
1839809797bSYuantian Tang 		else
1849809797bSYuantian Tang 			sites |= 0x1 << id;
18543528445SJia Hongtao 	}
18643528445SJia Hongtao 
1877797ff42SYuantian Tang 	/* Enable monitoring */
1889809797bSYuantian Tang 	if (sites != 0) {
1899809797bSYuantian Tang 		if (qdata->ver == TMU_VER1) {
1909809797bSYuantian Tang 			tmu_write(qdata, sites | TMR_ME | TMR_ALPF,
1919809797bSYuantian Tang 					&qdata->regs->tmr);
1929809797bSYuantian Tang 		} else {
1939809797bSYuantian Tang 			tmu_write(qdata, sites, &qdata->regs_v2->tmsr);
1949809797bSYuantian Tang 			tmu_write(qdata, TMR_ME | TMR_ALPF_V2,
1959809797bSYuantian Tang 					&qdata->regs_v2->tmr);
1969809797bSYuantian Tang 		}
1979809797bSYuantian Tang 	}
19843528445SJia Hongtao 
1997797ff42SYuantian Tang 	return 0;
20043528445SJia Hongtao }
20143528445SJia Hongtao 
20243528445SJia Hongtao static int qoriq_tmu_calibration(struct platform_device *pdev)
20343528445SJia Hongtao {
20443528445SJia Hongtao 	int i, val, len;
20543528445SJia Hongtao 	u32 range[4];
20643528445SJia Hongtao 	const u32 *calibration;
20743528445SJia Hongtao 	struct device_node *np = pdev->dev.of_node;
20843528445SJia Hongtao 	struct qoriq_tmu_data *data = platform_get_drvdata(pdev);
20943528445SJia Hongtao 
2109809797bSYuantian Tang 	len = of_property_count_u32_elems(np, "fsl,tmu-range");
2119809797bSYuantian Tang 	if (len < 0 || len > 4) {
2129809797bSYuantian Tang 		dev_err(&pdev->dev, "invalid range data.\n");
2139809797bSYuantian Tang 		return len;
2149809797bSYuantian Tang 	}
2159809797bSYuantian Tang 
2169809797bSYuantian Tang 	val = of_property_read_u32_array(np, "fsl,tmu-range", range, len);
2179809797bSYuantian Tang 	if (val != 0) {
2189809797bSYuantian Tang 		dev_err(&pdev->dev, "failed to read range data.\n");
2199809797bSYuantian Tang 		return val;
22043528445SJia Hongtao 	}
22143528445SJia Hongtao 
22243528445SJia Hongtao 	/* Init temperature range registers */
2239809797bSYuantian Tang 	for (i = 0; i < len; i++)
2249809797bSYuantian Tang 		tmu_write(data, range[i], &data->regs->ttrcr[i]);
22543528445SJia Hongtao 
22643528445SJia Hongtao 	calibration = of_get_property(np, "fsl,tmu-calibration", &len);
22743528445SJia Hongtao 	if (calibration == NULL || len % 8) {
22843528445SJia Hongtao 		dev_err(&pdev->dev, "invalid calibration data.\n");
22943528445SJia Hongtao 		return -ENODEV;
23043528445SJia Hongtao 	}
23143528445SJia Hongtao 
23243528445SJia Hongtao 	for (i = 0; i < len; i += 8, calibration += 2) {
23343528445SJia Hongtao 		val = of_read_number(calibration, 1);
23443528445SJia Hongtao 		tmu_write(data, val, &data->regs->ttcfgr);
23543528445SJia Hongtao 		val = of_read_number(calibration + 1, 1);
23643528445SJia Hongtao 		tmu_write(data, val, &data->regs->tscfgr);
23743528445SJia Hongtao 	}
23843528445SJia Hongtao 
23943528445SJia Hongtao 	return 0;
24043528445SJia Hongtao }
24143528445SJia Hongtao 
24243528445SJia Hongtao static void qoriq_tmu_init_device(struct qoriq_tmu_data *data)
24343528445SJia Hongtao {
24443528445SJia Hongtao 	/* Disable interrupt, using polling instead */
24543528445SJia Hongtao 	tmu_write(data, TIER_DISABLE, &data->regs->tier);
24643528445SJia Hongtao 
24743528445SJia Hongtao 	/* Set update_interval */
2489809797bSYuantian Tang 	if (data->ver == TMU_VER1) {
24943528445SJia Hongtao 		tmu_write(data, TMTMIR_DEFAULT, &data->regs->tmtmir);
2509809797bSYuantian Tang 	} else {
2519809797bSYuantian Tang 		tmu_write(data, TMTMIR_DEFAULT, &data->regs_v2->tmtmir);
2529809797bSYuantian Tang 		tmu_write(data, TEUMR0_V2, &data->regs_v2->teumr0);
2539809797bSYuantian Tang 	}
25443528445SJia Hongtao 
25543528445SJia Hongtao 	/* Disable monitoring */
25643528445SJia Hongtao 	tmu_write(data, TMR_DISABLE, &data->regs->tmr);
25743528445SJia Hongtao }
25843528445SJia Hongtao 
25943528445SJia Hongtao static int qoriq_tmu_probe(struct platform_device *pdev)
26043528445SJia Hongtao {
26143528445SJia Hongtao 	int ret;
2629809797bSYuantian Tang 	u32 ver;
26343528445SJia Hongtao 	struct qoriq_tmu_data *data;
26443528445SJia Hongtao 	struct device_node *np = pdev->dev.of_node;
26543528445SJia Hongtao 
26643528445SJia Hongtao 	data = devm_kzalloc(&pdev->dev, sizeof(struct qoriq_tmu_data),
26743528445SJia Hongtao 			    GFP_KERNEL);
26843528445SJia Hongtao 	if (!data)
26943528445SJia Hongtao 		return -ENOMEM;
27043528445SJia Hongtao 
27143528445SJia Hongtao 	platform_set_drvdata(pdev, data);
27243528445SJia Hongtao 
27343528445SJia Hongtao 	data->little_endian = of_property_read_bool(np, "little-endian");
27443528445SJia Hongtao 
2754d82000aSAnson Huang 	data->regs = devm_platform_ioremap_resource(pdev, 0);
2764d82000aSAnson Huang 	if (IS_ERR(data->regs)) {
27743528445SJia Hongtao 		dev_err(&pdev->dev, "Failed to get memory region\n");
2784d82000aSAnson Huang 		return PTR_ERR(data->regs);
27943528445SJia Hongtao 	}
28043528445SJia Hongtao 
28151904045SAnson Huang 	data->clk = devm_clk_get_optional(&pdev->dev, NULL);
28251904045SAnson Huang 	if (IS_ERR(data->clk))
28351904045SAnson Huang 		return PTR_ERR(data->clk);
28451904045SAnson Huang 
28551904045SAnson Huang 	ret = clk_prepare_enable(data->clk);
28651904045SAnson Huang 	if (ret) {
28751904045SAnson Huang 		dev_err(&pdev->dev, "Failed to enable clock\n");
28851904045SAnson Huang 		return ret;
28951904045SAnson Huang 	}
29051904045SAnson Huang 
2919809797bSYuantian Tang 	/* version register offset at: 0xbf8 on both v1 and v2 */
2929809797bSYuantian Tang 	ver = tmu_read(data, &data->regs->ipbrr0);
2939809797bSYuantian Tang 	data->ver = (ver >> 8) & 0xff;
2949809797bSYuantian Tang 	if (data->ver == TMU_VER2)
2959809797bSYuantian Tang 		data->regs_v2 = (void __iomem *)data->regs;
2969809797bSYuantian Tang 
29743528445SJia Hongtao 	qoriq_tmu_init_device(data);	/* TMU initialization */
29843528445SJia Hongtao 
29943528445SJia Hongtao 	ret = qoriq_tmu_calibration(pdev);	/* TMU calibration */
30043528445SJia Hongtao 	if (ret < 0)
3014d82000aSAnson Huang 		goto err;
30243528445SJia Hongtao 
3037797ff42SYuantian Tang 	ret = qoriq_tmu_register_tmu_zone(pdev);
3047797ff42SYuantian Tang 	if (ret < 0) {
3057797ff42SYuantian Tang 		dev_err(&pdev->dev, "Failed to register sensors\n");
3067797ff42SYuantian Tang 		ret = -ENODEV;
3074d82000aSAnson Huang 		goto err;
30843528445SJia Hongtao 	}
30943528445SJia Hongtao 
31043528445SJia Hongtao 	return 0;
31143528445SJia Hongtao 
3124d82000aSAnson Huang err:
31351904045SAnson Huang 	clk_disable_unprepare(data->clk);
31443528445SJia Hongtao 	platform_set_drvdata(pdev, NULL);
31543528445SJia Hongtao 
31643528445SJia Hongtao 	return ret;
31743528445SJia Hongtao }
31843528445SJia Hongtao 
31943528445SJia Hongtao static int qoriq_tmu_remove(struct platform_device *pdev)
32043528445SJia Hongtao {
32143528445SJia Hongtao 	struct qoriq_tmu_data *data = platform_get_drvdata(pdev);
32243528445SJia Hongtao 
32343528445SJia Hongtao 	/* Disable monitoring */
32443528445SJia Hongtao 	tmu_write(data, TMR_DISABLE, &data->regs->tmr);
32543528445SJia Hongtao 
32651904045SAnson Huang 	clk_disable_unprepare(data->clk);
32751904045SAnson Huang 
32843528445SJia Hongtao 	platform_set_drvdata(pdev, NULL);
32943528445SJia Hongtao 
33043528445SJia Hongtao 	return 0;
33143528445SJia Hongtao }
33243528445SJia Hongtao 
333aea59197SAnson Huang static int __maybe_unused qoriq_tmu_suspend(struct device *dev)
33443528445SJia Hongtao {
33543528445SJia Hongtao 	u32 tmr;
33643528445SJia Hongtao 	struct qoriq_tmu_data *data = dev_get_drvdata(dev);
33743528445SJia Hongtao 
33843528445SJia Hongtao 	/* Disable monitoring */
33943528445SJia Hongtao 	tmr = tmu_read(data, &data->regs->tmr);
34043528445SJia Hongtao 	tmr &= ~TMR_ME;
34143528445SJia Hongtao 	tmu_write(data, tmr, &data->regs->tmr);
34243528445SJia Hongtao 
34351904045SAnson Huang 	clk_disable_unprepare(data->clk);
34451904045SAnson Huang 
34543528445SJia Hongtao 	return 0;
34643528445SJia Hongtao }
34743528445SJia Hongtao 
348aea59197SAnson Huang static int __maybe_unused qoriq_tmu_resume(struct device *dev)
34943528445SJia Hongtao {
35043528445SJia Hongtao 	u32 tmr;
35151904045SAnson Huang 	int ret;
35243528445SJia Hongtao 	struct qoriq_tmu_data *data = dev_get_drvdata(dev);
35343528445SJia Hongtao 
35451904045SAnson Huang 	ret = clk_prepare_enable(data->clk);
35551904045SAnson Huang 	if (ret)
35651904045SAnson Huang 		return ret;
35751904045SAnson Huang 
35843528445SJia Hongtao 	/* Enable monitoring */
35943528445SJia Hongtao 	tmr = tmu_read(data, &data->regs->tmr);
36043528445SJia Hongtao 	tmr |= TMR_ME;
36143528445SJia Hongtao 	tmu_write(data, tmr, &data->regs->tmr);
36243528445SJia Hongtao 
36343528445SJia Hongtao 	return 0;
36443528445SJia Hongtao }
36543528445SJia Hongtao 
36643528445SJia Hongtao static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops,
36743528445SJia Hongtao 			 qoriq_tmu_suspend, qoriq_tmu_resume);
36843528445SJia Hongtao 
36943528445SJia Hongtao static const struct of_device_id qoriq_tmu_match[] = {
37043528445SJia Hongtao 	{ .compatible = "fsl,qoriq-tmu", },
3716017e2a9SAnson Huang 	{ .compatible = "fsl,imx8mq-tmu", },
37243528445SJia Hongtao 	{},
37343528445SJia Hongtao };
37443528445SJia Hongtao MODULE_DEVICE_TABLE(of, qoriq_tmu_match);
37543528445SJia Hongtao 
37643528445SJia Hongtao static struct platform_driver qoriq_tmu = {
37743528445SJia Hongtao 	.driver	= {
37843528445SJia Hongtao 		.name		= "qoriq_thermal",
37943528445SJia Hongtao 		.pm		= &qoriq_tmu_pm_ops,
38043528445SJia Hongtao 		.of_match_table	= qoriq_tmu_match,
38143528445SJia Hongtao 	},
38243528445SJia Hongtao 	.probe	= qoriq_tmu_probe,
38343528445SJia Hongtao 	.remove	= qoriq_tmu_remove,
38443528445SJia Hongtao };
38543528445SJia Hongtao module_platform_driver(qoriq_tmu);
38643528445SJia Hongtao 
38743528445SJia Hongtao MODULE_AUTHOR("Jia Hongtao <hongtao.jia@nxp.com>");
38843528445SJia Hongtao MODULE_DESCRIPTION("QorIQ Thermal Monitoring Unit driver");
38943528445SJia Hongtao MODULE_LICENSE("GPL v2");
390