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/err.h> 743528445SJia Hongtao #include <linux/io.h> 8ce68eecaSAnson Huang #include <linux/module.h> 943528445SJia Hongtao #include <linux/of.h> 10ce68eecaSAnson Huang #include <linux/platform_device.h> 114316237bSAndrey Smirnov #include <linux/regmap.h> 124316237bSAndrey Smirnov #include <linux/sizes.h> 1343528445SJia Hongtao #include <linux/thermal.h> 1447fa116eSYuantian Tang #include <linux/units.h> 1543528445SJia Hongtao 16fd843309SAndrey Smirnov #include "thermal_hwmon.h" 1743528445SJia Hongtao 1843528445SJia Hongtao #define SITES_MAX 16 199809797bSYuantian Tang #define TMR_DISABLE 0x0 209809797bSYuantian Tang #define TMR_ME 0x80000000 219809797bSYuantian Tang #define TMR_ALPF 0x0c000000 229809797bSYuantian Tang #define TMR_ALPF_V2 0x03000000 239809797bSYuantian Tang #define TMTMIR_DEFAULT 0x0000000f 249809797bSYuantian Tang #define TIER_DISABLE 0x0 259809797bSYuantian Tang #define TEUMR0_V2 0x51009c00 2647fa116eSYuantian Tang #define TMSARA_V2 0xe 279809797bSYuantian Tang #define TMU_VER1 0x1 289809797bSYuantian Tang #define TMU_VER2 0x2 2943528445SJia Hongtao 304316237bSAndrey Smirnov #define REGS_TMR 0x000 /* Mode Register */ 314316237bSAndrey Smirnov #define TMR_DISABLE 0x0 324316237bSAndrey Smirnov #define TMR_ME 0x80000000 334316237bSAndrey Smirnov #define TMR_ALPF 0x0c000000 344316237bSAndrey Smirnov 354316237bSAndrey Smirnov #define REGS_TMTMIR 0x008 /* Temperature measurement interval Register */ 364316237bSAndrey Smirnov #define TMTMIR_DEFAULT 0x0000000f 374316237bSAndrey Smirnov 384316237bSAndrey Smirnov #define REGS_V2_TMSR 0x008 /* monitor site register */ 394316237bSAndrey Smirnov 404316237bSAndrey Smirnov #define REGS_V2_TMTMIR 0x00c /* Temperature measurement interval Register */ 414316237bSAndrey Smirnov 424316237bSAndrey Smirnov #define REGS_TIER 0x020 /* Interrupt Enable Register */ 434316237bSAndrey Smirnov #define TIER_DISABLE 0x0 444316237bSAndrey Smirnov 454316237bSAndrey Smirnov 464316237bSAndrey Smirnov #define REGS_TTCFGR 0x080 /* Temperature Configuration Register */ 474316237bSAndrey Smirnov #define REGS_TSCFGR 0x084 /* Sensor Configuration Register */ 484316237bSAndrey Smirnov 494316237bSAndrey Smirnov #define REGS_TRITSR(n) (0x100 + 16 * (n)) /* Immediate Temperature 504316237bSAndrey Smirnov * Site Register 5143528445SJia Hongtao */ 5236564d7eSAndrey Smirnov #define TRITSR_V BIT(31) 5347fa116eSYuantian Tang #define REGS_V2_TMSAR(n) (0x304 + 16 * (n)) /* TMU monitoring 5447fa116eSYuantian Tang * site adjustment register 5547fa116eSYuantian Tang */ 564316237bSAndrey Smirnov #define REGS_TTRnCR(n) (0xf10 + 4 * (n)) /* Temperature Range n 574316237bSAndrey Smirnov * Control Register 584316237bSAndrey Smirnov */ 594316237bSAndrey Smirnov #define REGS_IPBRR(n) (0xbf8 + 4 * (n)) /* IP Block Revision 604316237bSAndrey Smirnov * Register n 614316237bSAndrey Smirnov */ 624316237bSAndrey Smirnov #define REGS_V2_TEUMR(n) (0xf00 + 4 * (n)) 6343528445SJia Hongtao 6443528445SJia Hongtao /* 6543528445SJia Hongtao * Thermal zone data 6643528445SJia Hongtao */ 677797ff42SYuantian Tang struct qoriq_sensor { 687797ff42SYuantian Tang int id; 697797ff42SYuantian Tang }; 707797ff42SYuantian Tang 7143528445SJia Hongtao struct qoriq_tmu_data { 729809797bSYuantian Tang int ver; 734316237bSAndrey Smirnov struct regmap *regmap; 7451904045SAnson Huang struct clk *clk; 75b319da1bSAndrey Smirnov struct qoriq_sensor sensor[SITES_MAX]; 7643528445SJia Hongtao }; 7743528445SJia Hongtao 78b319da1bSAndrey Smirnov static struct qoriq_tmu_data *qoriq_sensor_to_data(struct qoriq_sensor *s) 79b319da1bSAndrey Smirnov { 80b319da1bSAndrey Smirnov return container_of(s, struct qoriq_tmu_data, sensor[s->id]); 81b319da1bSAndrey Smirnov } 82b319da1bSAndrey Smirnov 833e7494b4SDaniel Lezcano static int tmu_get_temp(struct thermal_zone_device *tz, int *temp) 8443528445SJia Hongtao { 855f68d078SDaniel Lezcano struct qoriq_sensor *qsensor = thermal_zone_device_priv(tz); 86b319da1bSAndrey Smirnov struct qoriq_tmu_data *qdata = qoriq_sensor_to_data(qsensor); 8743528445SJia Hongtao u32 val; 8836564d7eSAndrey Smirnov /* 8936564d7eSAndrey Smirnov * REGS_TRITSR(id) has the following layout: 9036564d7eSAndrey Smirnov * 9147fa116eSYuantian Tang * For TMU Rev1: 9236564d7eSAndrey Smirnov * 31 ... 7 6 5 4 3 2 1 0 9336564d7eSAndrey Smirnov * V TEMP 9436564d7eSAndrey Smirnov * 9536564d7eSAndrey Smirnov * Where V bit signifies if the measurement is ready and is 9636564d7eSAndrey Smirnov * within sensor range. TEMP is an 8 bit value representing 9747fa116eSYuantian Tang * temperature in Celsius. 9847fa116eSYuantian Tang 9947fa116eSYuantian Tang * For TMU Rev2: 10047fa116eSYuantian Tang * 31 ... 8 7 6 5 4 3 2 1 0 10147fa116eSYuantian Tang * V TEMP 10247fa116eSYuantian Tang * 10347fa116eSYuantian Tang * Where V bit signifies if the measurement is ready and is 10447fa116eSYuantian Tang * within sensor range. TEMP is an 9 bit value representing 10547fa116eSYuantian Tang * temperature in KelVin. 10636564d7eSAndrey Smirnov */ 107*9301575dSPeng Fan 108*9301575dSPeng Fan regmap_read(qdata->regmap, REGS_TMR, &val); 109*9301575dSPeng Fan if (!(val & TMR_ME)) 110*9301575dSPeng Fan return -EAGAIN; 111*9301575dSPeng Fan 11236564d7eSAndrey Smirnov if (regmap_read_poll_timeout(qdata->regmap, 11336564d7eSAndrey Smirnov REGS_TRITSR(qsensor->id), 11436564d7eSAndrey Smirnov val, 11536564d7eSAndrey Smirnov val & TRITSR_V, 11636564d7eSAndrey Smirnov USEC_PER_MSEC, 11736564d7eSAndrey Smirnov 10 * USEC_PER_MSEC)) 11836564d7eSAndrey Smirnov return -ENODATA; 11943528445SJia Hongtao 12047fa116eSYuantian Tang if (qdata->ver == TMU_VER1) 12147fa116eSYuantian Tang *temp = (val & GENMASK(7, 0)) * MILLIDEGREE_PER_DEGREE; 12247fa116eSYuantian Tang else 12347fa116eSYuantian Tang *temp = kelvin_to_millicelsius(val & GENMASK(8, 0)); 12443528445SJia Hongtao 12543528445SJia Hongtao return 0; 12643528445SJia Hongtao } 12743528445SJia Hongtao 1283e7494b4SDaniel Lezcano static const struct thermal_zone_device_ops tmu_tz_ops = { 1297797ff42SYuantian Tang .get_temp = tmu_get_temp, 1307797ff42SYuantian Tang }; 1317797ff42SYuantian Tang 13203036625SAndrey Smirnov static int qoriq_tmu_register_tmu_zone(struct device *dev, 13303036625SAndrey Smirnov struct qoriq_tmu_data *qdata) 13443528445SJia Hongtao { 135*9301575dSPeng Fan int id, sites = 0; 13643528445SJia Hongtao 1377797ff42SYuantian Tang for (id = 0; id < SITES_MAX; id++) { 13811ef00f7SAndrey Smirnov struct thermal_zone_device *tzd; 139b319da1bSAndrey Smirnov struct qoriq_sensor *sensor = &qdata->sensor[id]; 14011ef00f7SAndrey Smirnov int ret; 14111ef00f7SAndrey Smirnov 142d6fb0564SAndrey Smirnov sensor->id = id; 14311ef00f7SAndrey Smirnov 1443e7494b4SDaniel Lezcano tzd = devm_thermal_of_zone_register(dev, id, 145d6fb0564SAndrey Smirnov sensor, 14611ef00f7SAndrey Smirnov &tmu_tz_ops); 14711ef00f7SAndrey Smirnov ret = PTR_ERR_OR_ZERO(tzd); 14811ef00f7SAndrey Smirnov if (ret) { 14911ef00f7SAndrey Smirnov if (ret == -ENODEV) 1507797ff42SYuantian Tang continue; 15145038e03SAndrey Smirnov 15211ef00f7SAndrey Smirnov return ret; 15343528445SJia Hongtao } 154fd843309SAndrey Smirnov 155*9301575dSPeng Fan if (qdata->ver == TMU_VER1) 156*9301575dSPeng Fan sites |= 0x1 << (15 - id); 157*9301575dSPeng Fan else 158*9301575dSPeng Fan sites |= 0x1 << id; 159*9301575dSPeng Fan 1604a16c190SDaniel Lezcano if (devm_thermal_add_hwmon_sysfs(dev, tzd)) 161fd843309SAndrey Smirnov dev_warn(dev, 162fd843309SAndrey Smirnov "Failed to add hwmon sysfs attributes\n"); 163*9301575dSPeng Fan } 164fd843309SAndrey Smirnov 165*9301575dSPeng Fan if (sites) { 166*9301575dSPeng Fan if (qdata->ver == TMU_VER1) { 167*9301575dSPeng Fan regmap_write(qdata->regmap, REGS_TMR, TMR_ME | TMR_ALPF | sites); 168*9301575dSPeng Fan } else { 169*9301575dSPeng Fan regmap_write(qdata->regmap, REGS_V2_TMSR, sites); 170*9301575dSPeng Fan regmap_write(qdata->regmap, REGS_TMR, TMR_ME | TMR_ALPF_V2); 171*9301575dSPeng Fan } 1729809797bSYuantian Tang } 17343528445SJia Hongtao 1747797ff42SYuantian Tang return 0; 17543528445SJia Hongtao } 17643528445SJia Hongtao 1778e1cda35SAndrey Smirnov static int qoriq_tmu_calibration(struct device *dev, 1788e1cda35SAndrey Smirnov struct qoriq_tmu_data *data) 17943528445SJia Hongtao { 18043528445SJia Hongtao int i, val, len; 18143528445SJia Hongtao u32 range[4]; 18243528445SJia Hongtao const u32 *calibration; 1838e1cda35SAndrey Smirnov struct device_node *np = dev->of_node; 18443528445SJia Hongtao 1859809797bSYuantian Tang len = of_property_count_u32_elems(np, "fsl,tmu-range"); 1869809797bSYuantian Tang if (len < 0 || len > 4) { 1878e1cda35SAndrey Smirnov dev_err(dev, "invalid range data.\n"); 1889809797bSYuantian Tang return len; 1899809797bSYuantian Tang } 1909809797bSYuantian Tang 1919809797bSYuantian Tang val = of_property_read_u32_array(np, "fsl,tmu-range", range, len); 1929809797bSYuantian Tang if (val != 0) { 1938e1cda35SAndrey Smirnov dev_err(dev, "failed to read range data.\n"); 1949809797bSYuantian Tang return val; 19543528445SJia Hongtao } 19643528445SJia Hongtao 19743528445SJia Hongtao /* Init temperature range registers */ 1989809797bSYuantian Tang for (i = 0; i < len; i++) 1994316237bSAndrey Smirnov regmap_write(data->regmap, REGS_TTRnCR(i), range[i]); 20043528445SJia Hongtao 20143528445SJia Hongtao calibration = of_get_property(np, "fsl,tmu-calibration", &len); 20243528445SJia Hongtao if (calibration == NULL || len % 8) { 2038e1cda35SAndrey Smirnov dev_err(dev, "invalid calibration data.\n"); 20443528445SJia Hongtao return -ENODEV; 20543528445SJia Hongtao } 20643528445SJia Hongtao 20743528445SJia Hongtao for (i = 0; i < len; i += 8, calibration += 2) { 20843528445SJia Hongtao val = of_read_number(calibration, 1); 2094316237bSAndrey Smirnov regmap_write(data->regmap, REGS_TTCFGR, val); 21043528445SJia Hongtao val = of_read_number(calibration + 1, 1); 2114316237bSAndrey Smirnov regmap_write(data->regmap, REGS_TSCFGR, val); 21243528445SJia Hongtao } 21343528445SJia Hongtao 21443528445SJia Hongtao return 0; 21543528445SJia Hongtao } 21643528445SJia Hongtao 21743528445SJia Hongtao static void qoriq_tmu_init_device(struct qoriq_tmu_data *data) 21843528445SJia Hongtao { 21943528445SJia Hongtao /* Disable interrupt, using polling instead */ 2204316237bSAndrey Smirnov regmap_write(data->regmap, REGS_TIER, TIER_DISABLE); 22143528445SJia Hongtao 22243528445SJia Hongtao /* Set update_interval */ 2234316237bSAndrey Smirnov 2249809797bSYuantian Tang if (data->ver == TMU_VER1) { 2254316237bSAndrey Smirnov regmap_write(data->regmap, REGS_TMTMIR, TMTMIR_DEFAULT); 2269809797bSYuantian Tang } else { 2274316237bSAndrey Smirnov regmap_write(data->regmap, REGS_V2_TMTMIR, TMTMIR_DEFAULT); 2284316237bSAndrey Smirnov regmap_write(data->regmap, REGS_V2_TEUMR(0), TEUMR0_V2); 2299809797bSYuantian Tang } 23043528445SJia Hongtao 23143528445SJia Hongtao /* Disable monitoring */ 2324316237bSAndrey Smirnov regmap_write(data->regmap, REGS_TMR, TMR_DISABLE); 23343528445SJia Hongtao } 23443528445SJia Hongtao 2354316237bSAndrey Smirnov static const struct regmap_range qoriq_yes_ranges[] = { 2364316237bSAndrey Smirnov regmap_reg_range(REGS_TMR, REGS_TSCFGR), 2374316237bSAndrey Smirnov regmap_reg_range(REGS_TTRnCR(0), REGS_TTRnCR(3)), 2384316237bSAndrey Smirnov regmap_reg_range(REGS_V2_TEUMR(0), REGS_V2_TEUMR(2)), 23947fa116eSYuantian Tang regmap_reg_range(REGS_V2_TMSAR(0), REGS_V2_TMSAR(15)), 2404316237bSAndrey Smirnov regmap_reg_range(REGS_IPBRR(0), REGS_IPBRR(1)), 2414316237bSAndrey Smirnov /* Read only registers below */ 2424316237bSAndrey Smirnov regmap_reg_range(REGS_TRITSR(0), REGS_TRITSR(15)), 2434316237bSAndrey Smirnov }; 2444316237bSAndrey Smirnov 2454316237bSAndrey Smirnov static const struct regmap_access_table qoriq_wr_table = { 2464316237bSAndrey Smirnov .yes_ranges = qoriq_yes_ranges, 2474316237bSAndrey Smirnov .n_yes_ranges = ARRAY_SIZE(qoriq_yes_ranges) - 1, 2484316237bSAndrey Smirnov }; 2494316237bSAndrey Smirnov 2504316237bSAndrey Smirnov static const struct regmap_access_table qoriq_rd_table = { 2514316237bSAndrey Smirnov .yes_ranges = qoriq_yes_ranges, 2524316237bSAndrey Smirnov .n_yes_ranges = ARRAY_SIZE(qoriq_yes_ranges), 2534316237bSAndrey Smirnov }; 2544316237bSAndrey Smirnov 25585f0b61aSAnson Huang static void qoriq_tmu_action(void *p) 25685f0b61aSAnson Huang { 25785f0b61aSAnson Huang struct qoriq_tmu_data *data = p; 25885f0b61aSAnson Huang 25985f0b61aSAnson Huang regmap_write(data->regmap, REGS_TMR, TMR_DISABLE); 26085f0b61aSAnson Huang clk_disable_unprepare(data->clk); 26185f0b61aSAnson Huang } 26285f0b61aSAnson Huang 26343528445SJia Hongtao static int qoriq_tmu_probe(struct platform_device *pdev) 26443528445SJia Hongtao { 26543528445SJia Hongtao int ret; 2669809797bSYuantian Tang u32 ver; 26743528445SJia Hongtao struct qoriq_tmu_data *data; 26843528445SJia Hongtao struct device_node *np = pdev->dev.of_node; 269e167dc43SAndrey Smirnov struct device *dev = &pdev->dev; 2704316237bSAndrey Smirnov const bool little_endian = of_property_read_bool(np, "little-endian"); 2714316237bSAndrey Smirnov const enum regmap_endian format_endian = 2724316237bSAndrey Smirnov little_endian ? REGMAP_ENDIAN_LITTLE : REGMAP_ENDIAN_BIG; 2734316237bSAndrey Smirnov const struct regmap_config regmap_config = { 2744316237bSAndrey Smirnov .reg_bits = 32, 2754316237bSAndrey Smirnov .val_bits = 32, 2764316237bSAndrey Smirnov .reg_stride = 4, 2774316237bSAndrey Smirnov .rd_table = &qoriq_rd_table, 2784316237bSAndrey Smirnov .wr_table = &qoriq_wr_table, 2794316237bSAndrey Smirnov .val_format_endian = format_endian, 2804316237bSAndrey Smirnov .max_register = SZ_4K, 2814316237bSAndrey Smirnov }; 2824316237bSAndrey Smirnov void __iomem *base; 28343528445SJia Hongtao 284e167dc43SAndrey Smirnov data = devm_kzalloc(dev, sizeof(struct qoriq_tmu_data), 28543528445SJia Hongtao GFP_KERNEL); 28643528445SJia Hongtao if (!data) 28743528445SJia Hongtao return -ENOMEM; 28843528445SJia Hongtao 2894316237bSAndrey Smirnov base = devm_platform_ioremap_resource(pdev, 0); 2904316237bSAndrey Smirnov ret = PTR_ERR_OR_ZERO(base); 2914316237bSAndrey Smirnov if (ret) { 292e167dc43SAndrey Smirnov dev_err(dev, "Failed to get memory region\n"); 2934316237bSAndrey Smirnov return ret; 2944316237bSAndrey Smirnov } 2954316237bSAndrey Smirnov 2964316237bSAndrey Smirnov data->regmap = devm_regmap_init_mmio(dev, base, ®map_config); 2974316237bSAndrey Smirnov ret = PTR_ERR_OR_ZERO(data->regmap); 2984316237bSAndrey Smirnov if (ret) { 2994316237bSAndrey Smirnov dev_err(dev, "Failed to init regmap (%d)\n", ret); 3004316237bSAndrey Smirnov return ret; 30143528445SJia Hongtao } 30243528445SJia Hongtao 303e167dc43SAndrey Smirnov data->clk = devm_clk_get_optional(dev, NULL); 30451904045SAnson Huang if (IS_ERR(data->clk)) 30551904045SAnson Huang return PTR_ERR(data->clk); 30651904045SAnson Huang 30751904045SAnson Huang ret = clk_prepare_enable(data->clk); 30851904045SAnson Huang if (ret) { 309e167dc43SAndrey Smirnov dev_err(dev, "Failed to enable clock\n"); 31051904045SAnson Huang return ret; 31151904045SAnson Huang } 31251904045SAnson Huang 31385f0b61aSAnson Huang ret = devm_add_action_or_reset(dev, qoriq_tmu_action, data); 31485f0b61aSAnson Huang if (ret) 31585f0b61aSAnson Huang return ret; 31685f0b61aSAnson Huang 3179809797bSYuantian Tang /* version register offset at: 0xbf8 on both v1 and v2 */ 3184316237bSAndrey Smirnov ret = regmap_read(data->regmap, REGS_IPBRR(0), &ver); 3194316237bSAndrey Smirnov if (ret) { 3204316237bSAndrey Smirnov dev_err(&pdev->dev, "Failed to read IP block version\n"); 3214316237bSAndrey Smirnov return ret; 3224316237bSAndrey Smirnov } 3239809797bSYuantian Tang data->ver = (ver >> 8) & 0xff; 3249809797bSYuantian Tang 32543528445SJia Hongtao qoriq_tmu_init_device(data); /* TMU initialization */ 32643528445SJia Hongtao 3278e1cda35SAndrey Smirnov ret = qoriq_tmu_calibration(dev, data); /* TMU calibration */ 32843528445SJia Hongtao if (ret < 0) 32985f0b61aSAnson Huang return ret; 33043528445SJia Hongtao 33103036625SAndrey Smirnov ret = qoriq_tmu_register_tmu_zone(dev, data); 3327797ff42SYuantian Tang if (ret < 0) { 333e167dc43SAndrey Smirnov dev_err(dev, "Failed to register sensors\n"); 33443528445SJia Hongtao return ret; 33543528445SJia Hongtao } 33643528445SJia Hongtao 33785f0b61aSAnson Huang platform_set_drvdata(pdev, data); 33851904045SAnson Huang 33943528445SJia Hongtao return 0; 34043528445SJia Hongtao } 34143528445SJia Hongtao 342aea59197SAnson Huang static int __maybe_unused qoriq_tmu_suspend(struct device *dev) 34343528445SJia Hongtao { 34443528445SJia Hongtao struct qoriq_tmu_data *data = dev_get_drvdata(dev); 3454316237bSAndrey Smirnov int ret; 34643528445SJia Hongtao 3474316237bSAndrey Smirnov ret = regmap_update_bits(data->regmap, REGS_TMR, TMR_ME, 0); 3484316237bSAndrey Smirnov if (ret) 3494316237bSAndrey Smirnov return ret; 35043528445SJia Hongtao 35151904045SAnson Huang clk_disable_unprepare(data->clk); 35251904045SAnson Huang 35343528445SJia Hongtao return 0; 35443528445SJia Hongtao } 35543528445SJia Hongtao 356aea59197SAnson Huang static int __maybe_unused qoriq_tmu_resume(struct device *dev) 35743528445SJia Hongtao { 35851904045SAnson Huang int ret; 35943528445SJia Hongtao struct qoriq_tmu_data *data = dev_get_drvdata(dev); 36043528445SJia Hongtao 36151904045SAnson Huang ret = clk_prepare_enable(data->clk); 36251904045SAnson Huang if (ret) 36351904045SAnson Huang return ret; 36451904045SAnson Huang 36543528445SJia Hongtao /* Enable monitoring */ 3664316237bSAndrey Smirnov return regmap_update_bits(data->regmap, REGS_TMR, TMR_ME, TMR_ME); 36743528445SJia Hongtao } 36843528445SJia Hongtao 36943528445SJia Hongtao static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops, 37043528445SJia Hongtao qoriq_tmu_suspend, qoriq_tmu_resume); 37143528445SJia Hongtao 37243528445SJia Hongtao static const struct of_device_id qoriq_tmu_match[] = { 37343528445SJia Hongtao { .compatible = "fsl,qoriq-tmu", }, 3746017e2a9SAnson Huang { .compatible = "fsl,imx8mq-tmu", }, 37543528445SJia Hongtao {}, 37643528445SJia Hongtao }; 37743528445SJia Hongtao MODULE_DEVICE_TABLE(of, qoriq_tmu_match); 37843528445SJia Hongtao 37943528445SJia Hongtao static struct platform_driver qoriq_tmu = { 38043528445SJia Hongtao .driver = { 38143528445SJia Hongtao .name = "qoriq_thermal", 38243528445SJia Hongtao .pm = &qoriq_tmu_pm_ops, 38343528445SJia Hongtao .of_match_table = qoriq_tmu_match, 38443528445SJia Hongtao }, 38543528445SJia Hongtao .probe = qoriq_tmu_probe, 38643528445SJia Hongtao }; 38743528445SJia Hongtao module_platform_driver(qoriq_tmu); 38843528445SJia Hongtao 38943528445SJia Hongtao MODULE_AUTHOR("Jia Hongtao <hongtao.jia@nxp.com>"); 39043528445SJia Hongtao MODULE_DESCRIPTION("QorIQ Thermal Monitoring Unit driver"); 39143528445SJia Hongtao MODULE_LICENSE("GPL v2"); 392