From patchwork Wed Sep 23 08:28:58 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hongtao Jia X-Patchwork-Id: 521632 X-Patchwork-Delegate: scottwood@freescale.com Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 2DB1E14012C for ; Wed, 23 Sep 2015 18:50:54 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 0E6041A03AD for ; Wed, 23 Sep 2015 18:50:54 +1000 (AEST) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Received: from na01-by2-obe.outbound.protection.outlook.com (mail-by2on0113.outbound.protection.outlook.com [207.46.100.113]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 932531A001E for ; Wed, 23 Sep 2015 18:49:54 +1000 (AEST) Received: from BN3PR0301CA0033.namprd03.prod.outlook.com (10.160.180.171) by BN1PR03MB156.namprd03.prod.outlook.com (10.255.201.28) with Microsoft SMTP Server (TLS) id 15.1.274.16; Wed, 23 Sep 2015 08:34:59 +0000 Received: from BN1BFFO11FD047.protection.gbl (2a01:111:f400:7c10::1:157) by BN3PR0301CA0033.outlook.office365.com (2a01:111:e400:4000::43) with Microsoft SMTP Server (TLS) id 15.1.274.16 via Frontend Transport; Wed, 23 Sep 2015 08:35:00 +0000 Authentication-Results: spf=fail (sender IP is 192.88.158.2) smtp.mailfrom=freescale.com; freescale.mail.onmicrosoft.com; dkim=none (message not signed) header.d=none; freescale.mail.onmicrosoft.com; dmarc=none action=none header.from=freescale.com; Received-SPF: Fail (protection.outlook.com: domain of freescale.com does not designate 192.88.158.2 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.158.2; helo=az84smr01.freescale.net; Received: from az84smr01.freescale.net (192.88.158.2) by BN1BFFO11FD047.mail.protection.outlook.com (10.58.145.2) with Microsoft SMTP Server (TLS) id 15.1.274.4 via Frontend Transport; Wed, 23 Sep 2015 08:34:59 +0000 Received: from titan.ap.freescale.net ([10.192.208.233]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id t8N8Ytwd004048; Wed, 23 Sep 2015 01:34:56 -0700 From: Jia Hongtao To: Subject: [PATCH V3] thermal: qoriq: Add thermal management support Date: Wed, 23 Sep 2015 16:28:58 +0800 Message-ID: <1442996938-47147-1-git-send-email-hongtao.jia@freescale.com> X-Mailer: git-send-email 2.1.0.27.g96db324 X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1; BN1BFFO11FD047; 1:1efd9kibZW1T2oLQezLHL8cPcLwVXiuh+RLntA31QRc9gTeQcTVWQ9Z8opOkRuFjG+EhnJp73nnnQ6rRH4QBwc+Hsxa87vtwpLRN2OA8UNXEh769EUefIj1VvXzgPlOqp3jmAPwixUNMxn/RoM0VYTFgHYBbWWwQGw0CMwTJMRCrCD1mpaClMD5RQK+wZv5euaNMkhLLca+RUfEED5J6ofqiIDWNRErU6ib98CDGRS9NTil+ES4zcEBcZgLr2+6Q/c/qHslaCETRz2INScexq5rtePfajT/n+j87sCEJWCxS/qu3iheZlfZEQJmvFBYB/P774ThcEZ8zI1Pstch/3n8Ek1RfgxtCx5pvRj0DpNrHQszU4Ngbkb/HJajCYTaKZj3JoWuvtMWIOztyorkVgQ== X-Forefront-Antispam-Report: CIP:192.88.158.2; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019020)(6009001)(2980300002)(1110001)(1109001)(339900001)(189002)(199003)(69596002)(97736004)(107886002)(64706001)(50986999)(87936001)(62966003)(85426001)(46102003)(77096005)(5001960100002)(77156002)(92566002)(110136002)(5003940100001)(189998001)(86362001)(81156007)(575784001)(50466002)(4001540100001)(47776003)(229853001)(5001830100001)(19580395003)(106466001)(48376002)(68736005)(33646002)(50226001)(5001860100001)(2351001)(19580405001)(5007970100001)(6806005)(36756003)(105606002)(104016004)(2004002)(4001430100001)(473944003); DIR:OUT; SFP:1102; SCL:1; SRVR:BN1PR03MB156; H:az84smr01.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; MIME-Version: 1.0 X-Microsoft-Exchange-Diagnostics: 1; BN1PR03MB156; 2:FrJJN5GQgimgKhUwZwC4oWBH6312yHQBBwONSrUCZQ4CqLEpanRhi697+8vDirmac3oi1zfLhTMHmjh1/9ZC1fJZe9S7FxYZ0KEdXYgiYRsOHWECCjPk8xQNdLtk4KydteuHCQD55YszeXCzw0WA/6yq3H9B2TvnTuwLqrAgVNA=; 3:VtNmq15gsfjvl4stVTg3G7plqL63Zjshm/zcqUWx7xqiOYUVB670e1eBNvSH04YehpwxV3iMRdDUL7hA9+WEKqbiroiB59t7uAbEeUI7Pj23mH4GxAC/pnjrxsD+oXxmVIoqvVBF0O46c9kkPSjt1n4ZXmLPKE2PNvBVasNsi/ledLCbwvRWAVEoEm4wMJaI5vsFuZ4cpUK076VPZ0O8YwOR2BWXMXFEL2wHL+VZJbg=; 25:LwIHn5q7PiaI5f4wTrh5jJWo2ogp/4B5zfJQYcL6rTKgw556sCdqYlVo00BmTgHVC4PK+zPmWkDSqPAUGjHGgfydVplEtpQeDpHmgRY7ac63O0FIqraQzma0GGc39DNn7hlmdwJ3rNUQ3Mx1N9OCFZnkv84UUs949r+3aGsVBuYig4m18m0ebnRW08q4S50cBT9XfdikbJqIuhkJIHTrFwoG1LC/3gRZg8cxbMvZB6CL8k6w1v51rppQQZtpPyUH X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BN1PR03MB156; X-Microsoft-Exchange-Diagnostics: 1; BN1PR03MB156; 20:RgFSTrbDaDGQqSKJQ5wHTUY82fv0EPYLfRqkmwo2xGn+yGGS1SOKq/Ldp+Vu8D0IUaZhn4V7ueZpqgajV8dWp8r9u7sMEhaARhpwi06sYsolSbiRWxsfZ/SHVMIJRWFvGUQgYgOxz+rZtE6eCW6hqDBzTGIRkHBrLoJk5zFA4Ub6hYkb1oqqrgW5vezmoB4Mwx4exUowRWHxV2n5mz14rhPyCf5qdw+0SMuBhN512rUoSEje5ex1BsAbIBxueTM9aD/6hKldY1LyVostKP8ymqokHK7L0ALcSxm0Eh7SyLWOk1leHi5la+hlHUpsgG2JnVgsQHuMYmsllaYE6bVm9yFmd6azdqL5GaQAymkBX04=; 4:dkdmHe3o6BWcAyuUn3ZbEz7cZtgVArEWGkkYlNkIYs+TVDSeDnhR+ciq719yHxjG1h8Lkw6TVkebeNlhnvbPoS4SR+ChIZwcxThe9Nq56xxaPPDVB+/4P5kReOdhMQW7UBE90Hsy4c/Rl1jLKEsgW5VihDx9q5U6f867Ta2Fd4pnPcxrnHETjqjPMz2dLby0T4aZjRpAzv392ndNE9K8doRGBK0Diwjk5PdKwTZjXZh/JaCJ3/NKFBqkZQ2TRUrR/MRkU3pQ0MHCKXWzyTGyJig1TFJAXvynB8H/z7QcmeqULtNjYj/fAkWK1en382PVzIJEQqFo08QmXPOCqOnjIlOLCykMSfCzZkKvvG+lkU4= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(520078)(5005006)(8121501046)(3002001); SRVR:BN1PR03MB156; BCL:0; PCL:0; RULEID:; SRVR:BN1PR03MB156; X-Forefront-PRVS: 07083FF734 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BN1PR03MB156; 23:I4wtlcLaNHDC9rWCOwLhpyOjA6mZTe2zh9AiT59QoE?= =?us-ascii?Q?2yii+qGnWjsNHk2kJIdtfkcnOACdem3gesOMDh+fvhkyoFoHpkrvpmI6gXDk?= =?us-ascii?Q?LFx7gGkH2xxNydFtr4CAPfBv08A1GtC86c0fA/aPHaA94Hf4qy8Gnf3rDOHp?= =?us-ascii?Q?BmB6RBWJ66oFOx4LkrVRQAhMkOkK9dZxKmQiojzEaKcOaMj/hZOKN4yFL8Q9?= =?us-ascii?Q?kmOkBz/BS0lIWe9EgwMAsA0y4QauY1J46pdLE9k+9UzsS45fHhCvzshyHr7/?= =?us-ascii?Q?RLQhGGu3JAhbHBhScmFiB8eVdCP5jNH11zMFnb8mlefulCqEKXUCju/AWDpr?= =?us-ascii?Q?WSesBbBm8k3NAbrPy8ye76WzuTNfNFCMoI0EUiLzcA5hHUQXHfKDpxwCTg9y?= =?us-ascii?Q?rnxvpdQa0AzVfLNTgpFFdXuXGGWsYJdYJ0gZPJ8dugjBjxdfyTBpypQbkTBf?= =?us-ascii?Q?jx/j9aNo4PHQk88g/qTUVnqH7VvtIFHCQQovums1TYvVvAGStqmUfP6zDZCf?= =?us-ascii?Q?Z1Ux2202m31asJLxkQbWLMH1V3O5b9QAQBy/cJQ/pPk7M4xKt6I7pD1mZtgB?= =?us-ascii?Q?4pyHKUNXRrX8nx2SXg3ioG/Ixiv7tv6taKoqfNlgq7fEPaN0fvNbKdvwHpMq?= =?us-ascii?Q?ybpb6dCzHxZ3UUZr+H0tyy2ePWWXqVAGk+5ktQ3Ofyv9DC/Q7Bb6U7MpyUpc?= =?us-ascii?Q?XKp6OMmpiLXDyP4n5wXlSFdTZe/AW0YOkEJTc1OeW5Ti2P9hCYAVn9tU5Gtc?= =?us-ascii?Q?EzPlBNu4bPXkIBiWaJDnn4xoFo3SgSbyWbiYGav7CFbBE68a9HVOkF3ridpP?= =?us-ascii?Q?FpFVgB0ENPyCRZ0GWjkeuWeUBkqNGuYOVIsHRI/M0SGKSzszp1rDvQaUBYCP?= =?us-ascii?Q?0dI+BpGswlWCrY7h/fZjcaNrEEBeM8fRMtwqleKTnzcYT821Lm4WPbfuXmXX?= =?us-ascii?Q?oIec8R5H5W6df9DCH9hT1me+j2ZZ3qoLS9Mdtpdy3Y0jrKOpew/AjDzMCG4a?= =?us-ascii?Q?ATVEcv3tWGQWIR8mnY2gzYfKvBIYsSsEkQeZX9iaGfn6rkm4BBzq1nJDtV/4?= =?us-ascii?Q?TES3LHD1nH316tzD+T23GwocIhlLCGjzLjoNv9y1P38BnXesje9sozVFZ9ii?= =?us-ascii?Q?KdwtRV0kY5VQHVBAczeSHZpZMDYpxX6v6aP+aOmAyGQPWywV03b2xDmqERvs?= =?us-ascii?Q?XEt1GPdX8AVxYzgpTpidlWaTVOVg/M/XWpoR62idJkt/+XUbUhwQI2tXc/jK?= =?us-ascii?Q?biIkCDKN2BVqGCst8ZlC/U+QWIECq1Y92DBTF/?= X-Microsoft-Exchange-Diagnostics: 1; BN1PR03MB156; 5:rS0LlQQlnUEf6PmsYQU1DeVFvSmPFxK5piU42AF5YDDm7b7MTJwak/Qy3LuwBaIsKxWgB3koFD16mE8ho/31UYejEALBRuFtdiRIJOFDr+7ckdc0awI4wm2UKpI6PwVXiOpfeIKACrBolG8R+lymGw==; 24:nhQEoOqxEvuUYFcrAUJZqaZkINF29KW/cv23CvDhj8dUzhhXswxrOX6F02y7Fecmk9OZLNv3jBIkEnNBUJ8Ts8LXPZU+wQnH/iaput/T94Q=; 20:aI4+VdOHA4I6LlT0CsMvKSI8C+nobE7/SZ4axEZbFrQmJeF1HxKHWX914i8gT0Wv8qc0MaXqtxkuNijruaPnSQ== X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2015 08:34:59.9175 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d; Ip=[192.88.158.2]; Helo=[az84smr01.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN1PR03MB156 X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: scottwood@freescale.com, hongtao.jia@freescale.com, linuxppc-dev@lists.ozlabs.org, linux-pm@vger.kernel.org Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" This driver add thermal management support by enabling TMU (Thermal Monitoring Unit) on QorIQ platform. It's based on thermal of framework: - Trip points defined in device tree. - Cpufreq as cooling device registered in qoriq cpufreq driver. Signed-off-by: Jia Hongtao --- V3: Using thermal of framework. drivers/thermal/Kconfig | 11 ++ drivers/thermal/Makefile | 1 + drivers/thermal/qoriq_thermal.c | 267 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 279 insertions(+) create mode 100644 drivers/thermal/qoriq_thermal.c diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 0390044..c91041b 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -180,6 +180,17 @@ config IMX_THERMAL cpufreq is used as the cooling device to throttle CPUs when the passive trip is crossed. +config QORIQ_THERMAL + tristate "Freescale QorIQ Thermal Monitoring Unit" + depends on CPU_THERMAL + depends on THERMAL_OF + default n + help + Enable thermal management based on Freescale QorIQ Thermal Monitoring + Unit (TMU). It supports one critical trip point and one passive trip + point. The cpufreq is used as the cooling device to throttle CPUs when + the passive trip is crossed. + config SPEAR_THERMAL bool "SPEAr thermal sensor driver" depends on PLAT_SPEAR diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 26f1608..e55d703 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_DOVE_THERMAL) += dove_thermal.o obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o +obj-$(CONFIG_QORIQ_THERMAL) += qoriq_thermal.o obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c new file mode 100644 index 0000000..7c2a3261 --- /dev/null +++ b/drivers/thermal/qoriq_thermal.c @@ -0,0 +1,267 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +/* + * Based on Freescale QorIQ Thermal Monitoring Unit (TMU) + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "thermal_core.h" + +#define SITES_MAX 16 + +/* + * QorIQ TMU Registers + */ +struct qoriq_tmu_site_regs { + __be32 tritsr; /* Immediate Temperature Site Register */ + __be32 tratsr; /* Average Temperature Site Register */ + u8 res0[0x8]; +} __packed; + +struct qoriq_tmu_regs { + __be32 tmr; /* Mode Register */ +#define TMR_DISABLE 0x0 +#define TMR_ME 0x80000000 +#define TMR_ALPF 0x0c000000 +#define TMR_MSITE 0x00008000 /* Core temperature site */ +#define TMR_ALL (TMR_ME | TMR_ALPF | TMR_MSITE) + __be32 tsr; /* Status Register */ + __be32 tmtmir; /* Temperature measurement interval Register */ +#define TMTMIR_DEFAULT 0x00000007 + u8 res0[0x14]; + __be32 tier; /* Interrupt Enable Register */ +#define TIER_DISABLE 0x0 + __be32 tidr; /* Interrupt Detect Register */ + __be32 tiscr; /* Interrupt Site Capture Register */ + __be32 ticscr; /* Interrupt Critical Site Capture Register */ + u8 res1[0x10]; + __be32 tmhtcrh; /* High Temperature Capture Register */ + __be32 tmhtcrl; /* Low Temperature Capture Register */ + u8 res2[0x8]; + __be32 tmhtitr; /* High Temperature Immediate Threshold */ + __be32 tmhtatr; /* High Temperature Average Threshold */ + __be32 tmhtactr; /* High Temperature Average Crit Threshold */ + u8 res3[0x24]; + __be32 ttcfgr; /* Temperature Configuration Register */ + __be32 tscfgr; /* Sensor Configuration Register */ + u8 res4[0x78]; + struct qoriq_tmu_site_regs site[SITES_MAX]; + u8 res5[0x9f8]; + __be32 ipbrr0; /* IP Block Revision Register 0 */ + __be32 ipbrr1; /* IP Block Revision Register 1 */ + u8 res6[0x310]; + __be32 ttr0cr; /* Temperature Range 0 Control Register */ + __be32 ttr1cr; /* Temperature Range 1 Control Register */ + __be32 ttr2cr; /* Temperature Range 2 Control Register */ + __be32 ttr3cr; /* Temperature Range 3 Control Register */ +}; + +/* + * Thermal zone data + */ +struct qoriq_tmu_data { + struct thermal_zone_device *tz; + struct qoriq_tmu_regs __iomem *regs; +}; + +static int tmu_get_temp(void *p, int *temp) +{ + u8 val; + struct qoriq_tmu_data *data = p; + + val = ioread32be(&data->regs->site[0].tritsr); + *temp = (int)val * 1000; + + return 0; +} + +static int qoriq_tmu_calibration(struct platform_device *pdev) +{ + int i, val, len; + u32 range[4]; + const __be32 *calibration; + struct device_node *node = pdev->dev.of_node; + struct qoriq_tmu_data *data = platform_get_drvdata(pdev); + + /* Disable monitoring before calibration */ + iowrite32be(TMR_DISABLE, &data->regs->tmr); + + if (of_property_read_u32_array(node, "fsl,tmu-range", range, 4)) + return -1; + + /* Init temperature range registers */ + iowrite32be(range[0], &data->regs->ttr0cr); + iowrite32be(range[1], &data->regs->ttr1cr); + iowrite32be(range[2], &data->regs->ttr2cr); + iowrite32be(range[3], &data->regs->ttr3cr); + + calibration = of_get_property(node, "fsl,tmu-calibration", &len); + if (calibration == NULL) + return -1; + + for (i = 0; i < len; i += 8, calibration += 2) { + val = (int)of_read_number(calibration, 1); + iowrite32be(val, &data->regs->ttcfgr); + val = (int)of_read_number(calibration + 1, 1); + iowrite32be(val, &data->regs->tscfgr); + } + + return 0; +} + +static void qoriq_tmu_init_device(struct qoriq_tmu_data *data) +{ + /* Disable interrupt, using polling instead */ + iowrite32be(TIER_DISABLE, &data->regs->tier); + + /* Set update_interval */ + iowrite32be(TMTMIR_DEFAULT, &data->regs->tmtmir); + + /* Enable monitoring */ + iowrite32be(TMR_ALL, &data->regs->tmr); +} + +static struct thermal_zone_of_device_ops tmu_tz_ops = { + .get_temp = tmu_get_temp, +}; + +static int qoriq_tmu_probe(struct platform_device *pdev) +{ + int ret; + const struct thermal_trip *trip; + struct qoriq_tmu_data *data; + + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, "Device OF-Node is NULL"); + return -EFAULT; + } + + data = devm_kzalloc(&pdev->dev, sizeof(struct qoriq_tmu_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + platform_set_drvdata(pdev, data); + data->regs = of_iomap(pdev->dev.of_node, 0); + + if (!data->regs) { + dev_err(&pdev->dev, "Failed to get memory region\n"); + ret = -ENODEV; + goto err_iomap; + } + + ret = qoriq_tmu_calibration(pdev); /* TMU calibration */ + if (ret < 0) { + dev_err(&pdev->dev, "TMU calibration failed.\n"); + ret = -ENODEV; + goto err_iomap; + } + + qoriq_tmu_init_device(data); /* TMU initialization */ + + data->tz = thermal_zone_of_sensor_register(&pdev->dev, 0, + data, &tmu_tz_ops); + if (IS_ERR(data->tz)) { + ret = PTR_ERR(data->tz); + dev_err(&pdev->dev, + "Failed to register thermal zone device %d\n", ret); + goto err_thermal; + } + + trip = of_thermal_get_trip_points(data->tz); + + data->tz->ops->set_mode(data->tz, THERMAL_DEVICE_ENABLED); + + return 0; + +err_thermal: + iounmap(data->regs); + +err_iomap: + platform_set_drvdata(pdev, NULL); + devm_kfree(&pdev->dev, data); + + return ret; +} + +static int qoriq_tmu_remove(struct platform_device *pdev) +{ + struct qoriq_tmu_data *data = platform_get_drvdata(pdev); + + /* Disable monitoring */ + iowrite32be(TMR_DISABLE, &data->regs->tmr); + + thermal_zone_of_sensor_unregister(&pdev->dev, data->tz); + iounmap(data->regs); + + platform_set_drvdata(pdev, NULL); + devm_kfree(&pdev->dev, data); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int qoriq_tmu_suspend(struct device *dev) +{ + struct qoriq_tmu_data *data = dev_get_drvdata(dev); + + /* Disable monitoring */ + iowrite32be(TMR_DISABLE, &data->regs->tmr); + data->tz->ops->set_mode(data->tz, THERMAL_DEVICE_DISABLED); + + return 0; +} + +static int qoriq_tmu_resume(struct device *dev) +{ + struct qoriq_tmu_data *data = dev_get_drvdata(dev); + + /* Enable monitoring */ + iowrite32be(TMR_ALL, &data->regs->tmr); + data->tz->ops->set_mode(data->tz, THERMAL_DEVICE_ENABLED); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops, + qoriq_tmu_suspend, qoriq_tmu_resume); + +static const struct of_device_id qoriq_tmu_match[] = { + { .compatible = "fsl,qoriq-tmu", }, + {}, +}; + +static struct platform_driver qoriq_tmu = { + .driver = { + .name = "qoriq_thermal", + .pm = &qoriq_tmu_pm_ops, + .of_match_table = qoriq_tmu_match, + }, + .probe = qoriq_tmu_probe, + .remove = qoriq_tmu_remove, +}; +module_platform_driver(qoriq_tmu); + +MODULE_AUTHOR("Jia Hongtao "); +MODULE_DESCRIPTION("Freescale QorIQ Thermal Monitoring Unit driver"); +MODULE_LICENSE("GPL v2");