diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-09-05 16:33:08 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-09-05 16:33:08 +0200 |
commit | 5677655a73ebe9b6e684ac5b03c4f09e4f42efe4 (patch) | |
tree | be2a8f64ee2de8b359d89d6babe08cb7834327ab | |
parent | 3855909df106be73e38fb6e2f88fcad70fdd15d5 (diff) | |
download | ltsi-kernel-5677655a73ebe9b6e684ac5b03c4f09e4f42efe4.tar.gz |
More renesas fixes
15 files changed, 1321 insertions, 0 deletions
diff --git a/patches.renesas/.0046-drm-rcar-du-Remove-test-for-impossible-error-conditi.patch.swp b/patches.renesas/.0046-drm-rcar-du-Remove-test-for-impossible-error-conditi.patch.swp Binary files differnew file mode 100644 index 00000000000000..be26270122adfa --- /dev/null +++ b/patches.renesas/.0046-drm-rcar-du-Remove-test-for-impossible-error-conditi.patch.swp diff --git a/patches.renesas/clk-cs2000-add-suspend-resume-feature.patch b/patches.renesas/clk-cs2000-add-suspend-resume-feature.patch new file mode 100644 index 00000000000000..2510ac65f637ba --- /dev/null +++ b/patches.renesas/clk-cs2000-add-suspend-resume-feature.patch @@ -0,0 +1,73 @@ +From horms@vergenet.net Tue Sep 5 10:07:48 2017 +From: Simon Horman <horms@verge.net.au> +Date: Tue, 5 Sep 2017 10:06:48 +0200 +Subject: [PATCH 13/13] clk: cs2000: add Suspend/Resume feature +To: Greg KH <gregkh@linuxfoundation.org> +Cc: ltsi-dev@lists.linuxfoundation.org, linux-renesas-soc@vger.kernel.org, Magnus Damm <magnus.damm@gmail.com> +Message-ID: <1504598808-19810-14-git-send-email-horms@verge.net.au> + + +From: Khiem Nguyen <khiem.nguyen.xt@rvc.renesas.com> + +CS2000 needs re-setup when redume, otherwise, it can't +handle correct clock rate. + +Signed-off-by: Khiem Nguyen <khiem.nguyen.xt@rvc.renesas.com> +[Kuninori: cleanup original patch] +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> + +(cherry picked from commit c567fb37f123511d752a454fb11d8bcaf46a7895) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/clk/clk-cs2000-cp.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +--- a/drivers/clk/clk-cs2000-cp.c ++++ b/drivers/clk/clk-cs2000-cp.c +@@ -59,6 +59,10 @@ struct cs2000_priv { + struct i2c_client *client; + struct clk *clk_in; + struct clk *ref_clk; ++ ++ /* suspend/resume */ ++ unsigned long saved_rate; ++ unsigned long saved_parent_rate; + }; + + static const struct of_device_id cs2000_of_match[] = { +@@ -286,6 +290,9 @@ static int __cs2000_set_rate(struct cs20 + if (ret < 0) + return ret; + ++ priv->saved_rate = rate; ++ priv->saved_parent_rate = parent_rate; ++ + return 0; + } + +@@ -489,9 +496,24 @@ probe_err: + return ret; + } + ++static int cs2000_resume(struct device *dev) ++{ ++ struct cs2000_priv *priv = dev_get_drvdata(dev); ++ int ch = 0; /* it uses ch0 only at this point */ ++ ++ return __cs2000_set_rate(priv, ch, ++ priv->saved_rate, ++ priv->saved_parent_rate); ++} ++ ++static const struct dev_pm_ops cs2000_pm_ops = { ++ .resume_early = cs2000_resume, ++}; ++ + static struct i2c_driver cs2000_driver = { + .driver = { + .name = "cs2000-cp", ++ .pm = &cs2000_pm_ops, + .of_match_table = cs2000_of_match, + }, + .probe = cs2000_probe, diff --git a/patches.renesas/thermal-rcar_gen3_thermal-add-delay-in-.thermal_init-on-r8a7796.patch b/patches.renesas/thermal-rcar_gen3_thermal-add-delay-in-.thermal_init-on-r8a7796.patch new file mode 100644 index 00000000000000..f983fb6c9c89f4 --- /dev/null +++ b/patches.renesas/thermal-rcar_gen3_thermal-add-delay-in-.thermal_init-on-r8a7796.patch @@ -0,0 +1,49 @@ +From horms@vergenet.net Tue Sep 5 10:07:31 2017 +From: Simon Horman <horms@verge.net.au> +Date: Tue, 5 Sep 2017 10:06:38 +0200 +Subject: [PATCH 03/13] thermal: rcar_gen3_thermal: add delay in .thermal_init on r8a7796 +To: Greg KH <gregkh@linuxfoundation.org> +Cc: ltsi-dev@lists.linuxfoundation.org, linux-renesas-soc@vger.kernel.org, Magnus Damm <magnus.damm@gmail.com> +Message-ID: <1504598808-19810-4-git-send-email-horms@verge.net.au> + + +From: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> + +The .thermal_init needs to be delayed a short amount of time to allow +for the TEMP register to contain something useful. If it's not delayed +these warnings are common during boot: + +thermal thermal_zone0: failed to read out thermal zone (-5) +thermal thermal_zone1: failed to read out thermal zone (-5) +thermal thermal_zone2: failed to read out thermal zone (-5) + +The warnings are triggered by the first call to .get_temp() while the +TEMP register contains 0 and rcar_gen3_thermal_get_temp() returns -EIO +since a TEMP value of 0 will result in a temperature reading which is +out of specifications. + +This should have been done in the initial commit which adds the driver +as the same issue was found and corrected for r8a7795. + +Fixes: 564e73d283af9d4c ("thermal: rcar_gen3_thermal: Add R-Car Gen3 thermal driver") +Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> +Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> +Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com> +Signed-off-by: Eduardo Valentin <edubezval@gmail.com> +(cherry picked from commit 78aefd2d5911c4e0b5dc0b0578b3b8c7673be1d2) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/thermal/rcar_gen3_thermal.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/thermal/rcar_gen3_thermal.c ++++ b/drivers/thermal/rcar_gen3_thermal.c +@@ -222,6 +222,8 @@ static void r8a7796_thermal_init(struct + reg_val = rcar_gen3_thermal_read(tsc, REG_GEN3_THCTR); + reg_val |= THCTR_THSST; + rcar_gen3_thermal_write(tsc, REG_GEN3_THCTR, reg_val); ++ ++ usleep_range(1000, 2000); + } + + static const struct rcar_gen3_thermal_data r8a7795_data = { diff --git a/patches.renesas/thermal-rcar_gen3_thermal-add-r-car-gen3-thermal-driver.patch b/patches.renesas/thermal-rcar_gen3_thermal-add-r-car-gen3-thermal-driver.patch new file mode 100644 index 00000000000000..d79677a9b2c32c --- /dev/null +++ b/patches.renesas/thermal-rcar_gen3_thermal-add-r-car-gen3-thermal-driver.patch @@ -0,0 +1,398 @@ +From horms@vergenet.net Tue Sep 5 10:07:28 2017 +From: Simon Horman <horms@verge.net.au> +Date: Tue, 5 Sep 2017 10:06:37 +0200 +Subject: [PATCH 02/13] thermal: rcar_gen3_thermal: Add R-Car Gen3 thermal driver +To: Greg KH <gregkh@linuxfoundation.org> +Cc: ltsi-dev@lists.linuxfoundation.org, linux-renesas-soc@vger.kernel.org, Magnus Damm <magnus.damm@gmail.com> +Message-ID: <1504598808-19810-3-git-send-email-horms@verge.net.au> + + +From: Wolfram Sang <wsa+renesas@sang-engineering.com> + +Add support for R-Car Gen3 thermal sensors. Polling only for now, +interrupts will be added incrementally. Same goes for reading fuses. +This is documented already, but no hardware available for now. + +Signed-off-by: Hien Dang <hien.dang.eb@renesas.com> +Signed-off-by: Thao Nguyen <thao.nguyen.yb@rvc.renesas.com> +Signed-off-by: Khiem Nguyen <khiem.nguyen.xt@renesas.com> +Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> +[Niklas: document and rework temperature calculation] +Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> +Signed-off-by: Eduardo Valentin <edubezval@gmail.com> + +(cherry picked from commit 564e73d283af9d4c1d642079d5c7ac601876162f) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/thermal/Kconfig | 9 + drivers/thermal/Makefile | 1 + drivers/thermal/rcar_gen3_thermal.c | 335 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 345 insertions(+) + create mode 100644 drivers/thermal/rcar_gen3_thermal.c + +--- a/drivers/thermal/Kconfig ++++ b/drivers/thermal/Kconfig +@@ -243,6 +243,15 @@ config RCAR_THERMAL + Enable this to plug the R-Car thermal sensor driver into the Linux + thermal framework. + ++config RCAR_GEN3_THERMAL ++ tristate "Renesas R-Car Gen3 thermal driver" ++ depends on ARCH_RENESAS || COMPILE_TEST ++ depends on HAS_IOMEM ++ depends on OF ++ help ++ Enable this to plug the R-Car Gen3 thermal sensor driver into the Linux ++ thermal framework. ++ + config KIRKWOOD_THERMAL + tristate "Temperature sensor on Marvell Kirkwood SoCs" + depends on MACH_KIRKWOOD || COMPILE_TEST +--- a/drivers/thermal/Makefile ++++ b/drivers/thermal/Makefile +@@ -30,6 +30,7 @@ obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qc + obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o + obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o + obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o ++obj-$(CONFIG_RCAR_GEN3_THERMAL) += rcar_gen3_thermal.o + obj-$(CONFIG_KIRKWOOD_THERMAL) += kirkwood_thermal.o + obj-y += samsung/ + obj-$(CONFIG_DOVE_THERMAL) += dove_thermal.o +--- /dev/null ++++ b/drivers/thermal/rcar_gen3_thermal.c +@@ -0,0 +1,335 @@ ++/* ++ * R-Car Gen3 THS thermal sensor driver ++ * Based on rcar_thermal.c and work from Hien Dang and Khiem Nguyen. ++ * ++ * Copyright (C) 2016 Renesas Electronics Corporation. ++ * Copyright (C) 2016 Sang Engineering ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that 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. ++ * ++ */ ++#include <linux/delay.h> ++#include <linux/err.h> ++#include <linux/interrupt.h> ++#include <linux/io.h> ++#include <linux/module.h> ++#include <linux/mutex.h> ++#include <linux/of_device.h> ++#include <linux/platform_device.h> ++#include <linux/pm_runtime.h> ++#include <linux/thermal.h> ++ ++/* Register offsets */ ++#define REG_GEN3_IRQSTR 0x04 ++#define REG_GEN3_IRQMSK 0x08 ++#define REG_GEN3_IRQCTL 0x0C ++#define REG_GEN3_IRQEN 0x10 ++#define REG_GEN3_IRQTEMP1 0x14 ++#define REG_GEN3_IRQTEMP2 0x18 ++#define REG_GEN3_IRQTEMP3 0x1C ++#define REG_GEN3_CTSR 0x20 ++#define REG_GEN3_THCTR 0x20 ++#define REG_GEN3_TEMP 0x28 ++#define REG_GEN3_THCODE1 0x50 ++#define REG_GEN3_THCODE2 0x54 ++#define REG_GEN3_THCODE3 0x58 ++ ++/* CTSR bits */ ++#define CTSR_PONM BIT(8) ++#define CTSR_AOUT BIT(7) ++#define CTSR_THBGR BIT(5) ++#define CTSR_VMEN BIT(4) ++#define CTSR_VMST BIT(1) ++#define CTSR_THSST BIT(0) ++ ++/* THCTR bits */ ++#define THCTR_PONM BIT(6) ++#define THCTR_THSST BIT(0) ++ ++#define CTEMP_MASK 0xFFF ++ ++#define MCELSIUS(temp) ((temp) * 1000) ++#define GEN3_FUSE_MASK 0xFFF ++ ++#define TSC_MAX_NUM 3 ++ ++/* Structure for thermal temperature calculation */ ++struct equation_coefs { ++ int a1; ++ int b1; ++ int a2; ++ int b2; ++}; ++ ++struct rcar_gen3_thermal_tsc { ++ void __iomem *base; ++ struct thermal_zone_device *zone; ++ struct equation_coefs coef; ++ struct mutex lock; ++}; ++ ++struct rcar_gen3_thermal_priv { ++ struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM]; ++}; ++ ++struct rcar_gen3_thermal_data { ++ void (*thermal_init)(struct rcar_gen3_thermal_tsc *tsc); ++}; ++ ++static inline u32 rcar_gen3_thermal_read(struct rcar_gen3_thermal_tsc *tsc, ++ u32 reg) ++{ ++ return ioread32(tsc->base + reg); ++} ++ ++static inline void rcar_gen3_thermal_write(struct rcar_gen3_thermal_tsc *tsc, ++ u32 reg, u32 data) ++{ ++ iowrite32(data, tsc->base + reg); ++} ++ ++/* ++ * Linear approximation for temperature ++ * ++ * [reg] = [temp] * a + b => [temp] = ([reg] - b) / a ++ * ++ * The constants a and b are calculated using two triplets of int values PTAT ++ * and THCODE. PTAT and THCODE can either be read from hardware or use hard ++ * coded values from driver. The formula to calculate a and b are taken from ++ * BSP and sparsely documented and understood. ++ * ++ * Examining the linear formula and the formula used to calculate constants a ++ * and b while knowing that the span for PTAT and THCODE values are between ++ * 0x000 and 0xfff the largest integer possible is 0xfff * 0xfff == 0xffe001. ++ * Integer also needs to be signed so that leaves 7 bits for binary ++ * fixed point scaling. ++ */ ++ ++#define FIXPT_SHIFT 7 ++#define FIXPT_INT(_x) ((_x) << FIXPT_SHIFT) ++#define FIXPT_DIV(_a, _b) DIV_ROUND_CLOSEST(((_a) << FIXPT_SHIFT), (_b)) ++#define FIXPT_TO_MCELSIUS(_x) ((_x) * 1000 >> FIXPT_SHIFT) ++ ++#define RCAR3_THERMAL_GRAN 500 /* mili Celsius */ ++ ++/* no idea where these constants come from */ ++#define TJ_1 96 ++#define TJ_3 -41 ++ ++static void rcar_gen3_thermal_calc_coefs(struct equation_coefs *coef, ++ int *ptat, int *thcode) ++{ ++ int tj_2; ++ ++ /* TODO: Find documentation and document constant calculation formula */ ++ ++ /* ++ * Division is not scaled in BSP and if scaled it might overflow ++ * the dividend (4095 * 4095 << 14 > INT_MAX) so keep it unscaled ++ */ ++ tj_2 = (FIXPT_INT((ptat[1] - ptat[2]) * 137) ++ / (ptat[0] - ptat[2])) - FIXPT_INT(41); ++ ++ coef->a1 = FIXPT_DIV(FIXPT_INT(thcode[1] - thcode[2]), ++ tj_2 - FIXPT_INT(TJ_3)); ++ coef->b1 = FIXPT_INT(thcode[2]) - coef->a1 * TJ_3; ++ ++ coef->a2 = FIXPT_DIV(FIXPT_INT(thcode[1] - thcode[0]), ++ tj_2 - FIXPT_INT(TJ_1)); ++ coef->b2 = FIXPT_INT(thcode[0]) - coef->a2 * TJ_1; ++} ++ ++static int rcar_gen3_thermal_round(int temp) ++{ ++ int result, round_offs; ++ ++ round_offs = temp >= 0 ? RCAR3_THERMAL_GRAN / 2 : ++ -RCAR3_THERMAL_GRAN / 2; ++ result = (temp + round_offs) / RCAR3_THERMAL_GRAN; ++ return result * RCAR3_THERMAL_GRAN; ++} ++ ++static int rcar_gen3_thermal_get_temp(void *devdata, int *temp) ++{ ++ struct rcar_gen3_thermal_tsc *tsc = devdata; ++ int mcelsius, val1, val2; ++ u32 reg; ++ ++ /* Read register and convert to mili Celsius */ ++ mutex_lock(&tsc->lock); ++ ++ reg = rcar_gen3_thermal_read(tsc, REG_GEN3_TEMP) & CTEMP_MASK; ++ ++ val1 = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b1, tsc->coef.a1); ++ val2 = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b2, tsc->coef.a2); ++ mcelsius = FIXPT_TO_MCELSIUS((val1 + val2) / 2); ++ ++ mutex_unlock(&tsc->lock); ++ ++ /* Make sure we are inside specifications */ ++ if ((mcelsius < MCELSIUS(-40)) || (mcelsius > MCELSIUS(125))) ++ return -EIO; ++ ++ /* Round value to device granularity setting */ ++ *temp = rcar_gen3_thermal_round(mcelsius); ++ ++ return 0; ++} ++ ++static struct thermal_zone_of_device_ops rcar_gen3_tz_of_ops = { ++ .get_temp = rcar_gen3_thermal_get_temp, ++}; ++ ++static void r8a7795_thermal_init(struct rcar_gen3_thermal_tsc *tsc) ++{ ++ rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_THBGR); ++ rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, 0x0); ++ ++ usleep_range(1000, 2000); ++ ++ rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_PONM); ++ rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0x3F); ++ rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, ++ CTSR_PONM | CTSR_AOUT | CTSR_THBGR | CTSR_VMEN); ++ ++ usleep_range(100, 200); ++ ++ rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, ++ CTSR_PONM | CTSR_AOUT | CTSR_THBGR | CTSR_VMEN | ++ CTSR_VMST | CTSR_THSST); ++ ++ usleep_range(1000, 2000); ++} ++ ++static void r8a7796_thermal_init(struct rcar_gen3_thermal_tsc *tsc) ++{ ++ u32 reg_val; ++ ++ reg_val = rcar_gen3_thermal_read(tsc, REG_GEN3_THCTR); ++ reg_val &= ~THCTR_PONM; ++ rcar_gen3_thermal_write(tsc, REG_GEN3_THCTR, reg_val); ++ ++ usleep_range(1000, 2000); ++ ++ rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0x3F); ++ reg_val = rcar_gen3_thermal_read(tsc, REG_GEN3_THCTR); ++ reg_val |= THCTR_THSST; ++ rcar_gen3_thermal_write(tsc, REG_GEN3_THCTR, reg_val); ++} ++ ++static const struct rcar_gen3_thermal_data r8a7795_data = { ++ .thermal_init = r8a7795_thermal_init, ++}; ++ ++static const struct rcar_gen3_thermal_data r8a7796_data = { ++ .thermal_init = r8a7796_thermal_init, ++}; ++ ++static const struct of_device_id rcar_gen3_thermal_dt_ids[] = { ++ { .compatible = "renesas,r8a7795-thermal", .data = &r8a7795_data}, ++ { .compatible = "renesas,r8a7796-thermal", .data = &r8a7796_data}, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids); ++ ++static int rcar_gen3_thermal_remove(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ ++ pm_runtime_put(dev); ++ pm_runtime_disable(dev); ++ ++ return 0; ++} ++ ++static int rcar_gen3_thermal_probe(struct platform_device *pdev) ++{ ++ struct rcar_gen3_thermal_priv *priv; ++ struct device *dev = &pdev->dev; ++ struct resource *res; ++ struct thermal_zone_device *zone; ++ int ret, i; ++ const struct rcar_gen3_thermal_data *match_data = ++ of_device_get_match_data(dev); ++ ++ /* default values if FUSEs are missing */ ++ /* TODO: Read values from hardware on supported platforms */ ++ int ptat[3] = { 2351, 1509, 435 }; ++ int thcode[TSC_MAX_NUM][3] = { ++ { 3248, 2800, 2221 }, ++ { 3245, 2795, 2216 }, ++ { 3250, 2805, 2237 }, ++ }; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, priv); ++ ++ pm_runtime_enable(dev); ++ pm_runtime_get_sync(dev); ++ ++ for (i = 0; i < TSC_MAX_NUM; i++) { ++ struct rcar_gen3_thermal_tsc *tsc; ++ ++ tsc = devm_kzalloc(dev, sizeof(*tsc), GFP_KERNEL); ++ if (!tsc) { ++ ret = -ENOMEM; ++ goto error_unregister; ++ } ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, i); ++ if (!res) ++ break; ++ ++ tsc->base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(tsc->base)) { ++ ret = PTR_ERR(tsc->base); ++ goto error_unregister; ++ } ++ ++ priv->tscs[i] = tsc; ++ mutex_init(&tsc->lock); ++ ++ match_data->thermal_init(tsc); ++ rcar_gen3_thermal_calc_coefs(&tsc->coef, ptat, thcode[i]); ++ ++ zone = devm_thermal_zone_of_sensor_register(dev, i, tsc, ++ &rcar_gen3_tz_of_ops); ++ if (IS_ERR(zone)) { ++ dev_err(dev, "Can't register thermal zone\n"); ++ ret = PTR_ERR(zone); ++ goto error_unregister; ++ } ++ tsc->zone = zone; ++ } ++ ++ return 0; ++ ++error_unregister: ++ rcar_gen3_thermal_remove(pdev); ++ ++ return ret; ++} ++ ++static struct platform_driver rcar_gen3_thermal_driver = { ++ .driver = { ++ .name = "rcar_gen3_thermal", ++ .of_match_table = rcar_gen3_thermal_dt_ids, ++ }, ++ .probe = rcar_gen3_thermal_probe, ++ .remove = rcar_gen3_thermal_remove, ++}; ++module_platform_driver(rcar_gen3_thermal_driver); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("R-Car Gen3 THS thermal sensor driver"); ++MODULE_AUTHOR("Wolfram Sang <wsa+renesas@sang-engineering.com>"); diff --git a/patches.renesas/thermal-rcar_gen3_thermal-add-suspend-and-resume-support.patch b/patches.renesas/thermal-rcar_gen3_thermal-add-suspend-and-resume-support.patch new file mode 100644 index 00000000000000..877784afc22a6d --- /dev/null +++ b/patches.renesas/thermal-rcar_gen3_thermal-add-suspend-and-resume-support.patch @@ -0,0 +1,85 @@ +From horms@vergenet.net Tue Sep 5 10:07:50 2017 +From: Simon Horman <horms@verge.net.au> +Date: Tue, 5 Sep 2017 10:06:44 +0200 +Subject: [PATCH 09/13] thermal: rcar_gen3_thermal: add suspend and resume support +To: Greg KH <gregkh@linuxfoundation.org> +Cc: ltsi-dev@lists.linuxfoundation.org, linux-renesas-soc@vger.kernel.org, Magnus Damm <magnus.damm@gmail.com> +Message-ID: <1504598808-19810-10-git-send-email-horms@verge.net.au> + + +From: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> + +To restore operation it's easiest to reinitialise all TSCs. In order to +do this the current trip window needs to be stored in the TSC structure +so that it can be restored upon resume. + +Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> +Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com> +Signed-off-by: Eduardo Valentin <edubezval@gmail.com> +(cherry picked from commit 75f78d6d9eb793d141affaa5a76f20ce1d6ae5c9) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/thermal/rcar_gen3_thermal.c | 35 +++++++++++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +--- a/drivers/thermal/rcar_gen3_thermal.c ++++ b/drivers/thermal/rcar_gen3_thermal.c +@@ -82,6 +82,8 @@ struct rcar_gen3_thermal_tsc { + void __iomem *base; + struct thermal_zone_device *zone; + struct equation_coefs coef; ++ int low; ++ int high; + }; + + struct rcar_gen3_thermal_priv { +@@ -217,6 +219,9 @@ static int rcar_gen3_thermal_set_trips(v + rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP2, + rcar_gen3_thermal_mcelsius_to_temp(tsc, high)); + ++ tsc->low = low; ++ tsc->high = high; ++ + return 0; + } + +@@ -454,9 +459,39 @@ error_unregister: + return ret; + } + ++static int __maybe_unused rcar_gen3_thermal_suspend(struct device *dev) ++{ ++ struct rcar_gen3_thermal_priv *priv = dev_get_drvdata(dev); ++ ++ rcar_thermal_irq_set(priv, false); ++ ++ return 0; ++} ++ ++static int __maybe_unused rcar_gen3_thermal_resume(struct device *dev) ++{ ++ struct rcar_gen3_thermal_priv *priv = dev_get_drvdata(dev); ++ unsigned int i; ++ ++ for (i = 0; i < priv->num_tscs; i++) { ++ struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; ++ ++ priv->data->thermal_init(tsc); ++ rcar_gen3_thermal_set_trips(tsc, tsc->low, tsc->high); ++ } ++ ++ rcar_thermal_irq_set(priv, true); ++ ++ return 0; ++} ++ ++static SIMPLE_DEV_PM_OPS(rcar_gen3_thermal_pm_ops, rcar_gen3_thermal_suspend, ++ rcar_gen3_thermal_resume); ++ + static struct platform_driver rcar_gen3_thermal_driver = { + .driver = { + .name = "rcar_gen3_thermal", ++ .pm = &rcar_gen3_thermal_pm_ops, + .of_match_table = rcar_gen3_thermal_dt_ids, + }, + .probe = rcar_gen3_thermal_probe, diff --git a/patches.renesas/thermal-rcar_gen3_thermal-check-that-tsc-exists-before-memory-allocation.patch b/patches.renesas/thermal-rcar_gen3_thermal-check-that-tsc-exists-before-memory-allocation.patch new file mode 100644 index 00000000000000..e04184832085fb --- /dev/null +++ b/patches.renesas/thermal-rcar_gen3_thermal-check-that-tsc-exists-before-memory-allocation.patch @@ -0,0 +1,48 @@ +From horms@vergenet.net Tue Sep 5 10:07:57 2017 +From: Simon Horman <horms@verge.net.au> +Date: Tue, 5 Sep 2017 10:06:40 +0200 +Subject: [PATCH 05/13] thermal: rcar_gen3_thermal: check that TSC exists before memory allocation +To: Greg KH <gregkh@linuxfoundation.org> +Cc: ltsi-dev@lists.linuxfoundation.org, linux-renesas-soc@vger.kernel.org, Magnus Damm <magnus.damm@gmail.com> +Message-ID: <1504598808-19810-6-git-send-email-horms@verge.net.au> + + +From: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> + +Move the check for a TSC resource before allocating memory for a new +TSC. If no TSC is found there is little point in allocating memory for +it. + +Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> +Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> +Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com> +Signed-off-by: Eduardo Valentin <edubezval@gmail.com> +(cherry picked from commit d51546c0db975a4750161d17eef62dfcf9eedc90) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/thermal/rcar_gen3_thermal.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/thermal/rcar_gen3_thermal.c ++++ b/drivers/thermal/rcar_gen3_thermal.c +@@ -276,16 +276,16 @@ static int rcar_gen3_thermal_probe(struc + for (i = 0; i < TSC_MAX_NUM; i++) { + struct rcar_gen3_thermal_tsc *tsc; + ++ res = platform_get_resource(pdev, IORESOURCE_MEM, i); ++ if (!res) ++ break; ++ + tsc = devm_kzalloc(dev, sizeof(*tsc), GFP_KERNEL); + if (!tsc) { + ret = -ENOMEM; + goto error_unregister; + } + +- res = platform_get_resource(pdev, IORESOURCE_MEM, i); +- if (!res) +- break; +- + tsc->base = devm_ioremap_resource(dev, res); + if (IS_ERR(tsc->base)) { + ret = PTR_ERR(tsc->base); diff --git a/patches.renesas/thermal-rcar_gen3_thermal-document-the-r-car-gen3.patch b/patches.renesas/thermal-rcar_gen3_thermal-document-the-r-car-gen3.patch new file mode 100644 index 00000000000000..afe445312dac4f --- /dev/null +++ b/patches.renesas/thermal-rcar_gen3_thermal-document-the-r-car-gen3.patch @@ -0,0 +1,82 @@ +From horms@vergenet.net Tue Sep 5 10:07:30 2017 +From: Simon Horman <horms@verge.net.au> +Date: Tue, 5 Sep 2017 10:06:36 +0200 +Subject: [PATCH 01/13] thermal: rcar_gen3_thermal: Document the R-Car Gen3 +To: Greg KH <gregkh@linuxfoundation.org> +Cc: ltsi-dev@lists.linuxfoundation.org, linux-renesas-soc@vger.kernel.org, Magnus Damm <magnus.damm@gmail.com> +Message-ID: <1504598808-19810-2-git-send-email-horms@verge.net.au> + + +From: Wolfram Sang <wsa+renesas@sang-engineering.com> + +Signed-off-by: Hien Dang <hien.dang.eb@renesas.com> +Signed-off-by: Khiem Nguyen <khiem.nguyen.xt@renesas.com> +Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> +Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> +Signed-off-by: Eduardo Valentin <edubezval@gmail.com> +(cherry picked from commit b022e9b9d0e67f4cba62bc790bd387e23c29dc6c) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt | 56 ++++++++++ + 1 file changed, 56 insertions(+) + create mode 100644 Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt + +--- /dev/null ++++ b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt +@@ -0,0 +1,56 @@ ++* DT bindings for Renesas R-Car Gen3 Thermal Sensor driver ++ ++On R-Car Gen3 SoCs, the thermal sensor controllers (TSC) control the thermal ++sensors (THS) which are the analog circuits for measuring temperature (Tj) ++inside the LSI. ++ ++Required properties: ++- compatible : "renesas,<soctype>-thermal", ++ Examples with soctypes are: ++ - "renesas,r8a7795-thermal" (R-Car H3) ++ - "renesas,r8a7796-thermal" (R-Car M3-W) ++- reg : Address ranges of the thermal registers. Each sensor ++ needs one address range. Sorting must be done in ++ increasing order according to datasheet, i.e. ++ TSC1, TSC2, ... ++- clocks : Must contain a reference to the functional clock. ++- #thermal-sensor-cells : must be <1>. ++ ++Optional properties: ++ ++- interrupts : interrupts routed to the TSC (3 for H3 and M3-W) ++- power-domain : Must contain a reference to the power domain. This ++ property is mandatory if the thermal sensor instance ++ is part of a controllable power domain. ++ ++Example: ++ ++ tsc: thermal@e6198000 { ++ compatible = "renesas,r8a7795-thermal"; ++ reg = <0 0xe6198000 0 0x68>, ++ <0 0xe61a0000 0 0x5c>, ++ <0 0xe61a8000 0 0x5c>; ++ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cpg CPG_MOD 522>; ++ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; ++ #thermal-sensor-cells = <1>; ++ status = "okay"; ++ }; ++ ++ thermal-zones { ++ sensor_thermal1: sensor-thermal1 { ++ polling-delay-passive = <250>; ++ polling-delay = <1000>; ++ thermal-sensors = <&tsc 0>; ++ ++ trips { ++ sensor1_crit: sensor1-crit { ++ temperature = <90000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ }; diff --git a/patches.renesas/thermal-rcar_gen3_thermal-enable-hardware-interrupts-for-trip-points.patch b/patches.renesas/thermal-rcar_gen3_thermal-enable-hardware-interrupts-for-trip-points.patch new file mode 100644 index 00000000000000..a7e68c8810cc66 --- /dev/null +++ b/patches.renesas/thermal-rcar_gen3_thermal-enable-hardware-interrupts-for-trip-points.patch @@ -0,0 +1,256 @@ +From horms@vergenet.net Tue Sep 5 10:07:47 2017 +From: Simon Horman <horms@verge.net.au> +Date: Tue, 5 Sep 2017 10:06:42 +0200 +Subject: [PATCH 07/13] thermal: rcar_gen3_thermal: enable hardware interrupts for trip points +To: Greg KH <gregkh@linuxfoundation.org> +Cc: ltsi-dev@lists.linuxfoundation.org, linux-renesas-soc@vger.kernel.org, Magnus Damm <magnus.damm@gmail.com> +Message-ID: <1504598808-19810-8-git-send-email-horms@verge.net.au> + + +From: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> + +Enable hardware trip points by implementing the set_trips callback. The +thermal core will take care of setting the initial trip point window and +to update it once the driver reports a TSC has moved outside it. + +The interrupt structure for this device is a bit odd. There is not a +dedicated IRQ for each TSC, instead the interrupts are shared between +all TSCs. IRQn is fired if the temp monitored in IRQTEMPn is reached in +any of the TSCs, example IRQ3 is fired if temperature in IRQTEMP3 is +reached in either TSC0, TSC1 or TSC2. + +For this reason the usage of interrupts in this driver is an all-on or +all-off design. When an interrupt happens all TSCs are checked and all +thermal zones are updated. This could be refined to be more fine grained +but the thermal core takes care of only updating the thermal zones that +have left their trip point window. + +Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> +Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com> +Signed-off-by: Eduardo Valentin <edubezval@gmail.com> +(cherry picked from commit 7d4b269776ec67c1b7d83c6c727a2771e5f39d12) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/thermal/rcar_gen3_thermal.c | 132 +++++++++++++++++++++++++++++++++++- + 1 file changed, 131 insertions(+), 1 deletion(-) + +--- a/drivers/thermal/rcar_gen3_thermal.c ++++ b/drivers/thermal/rcar_gen3_thermal.c +@@ -23,8 +23,11 @@ + #include <linux/of_device.h> + #include <linux/platform_device.h> + #include <linux/pm_runtime.h> ++#include <linux/spinlock.h> + #include <linux/thermal.h> + ++#include "thermal_core.h" ++ + /* Register offsets */ + #define REG_GEN3_IRQSTR 0x04 + #define REG_GEN3_IRQMSK 0x08 +@@ -40,6 +43,14 @@ + #define REG_GEN3_THCODE2 0x54 + #define REG_GEN3_THCODE3 0x58 + ++/* IRQ{STR,MSK,EN} bits */ ++#define IRQ_TEMP1 BIT(0) ++#define IRQ_TEMP2 BIT(1) ++#define IRQ_TEMP3 BIT(2) ++#define IRQ_TEMPD1 BIT(3) ++#define IRQ_TEMPD2 BIT(4) ++#define IRQ_TEMPD3 BIT(5) ++ + /* CTSR bits */ + #define CTSR_PONM BIT(8) + #define CTSR_AOUT BIT(7) +@@ -76,6 +87,7 @@ struct rcar_gen3_thermal_tsc { + struct rcar_gen3_thermal_priv { + struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM]; + unsigned int num_tscs; ++ spinlock_t lock; /* Protect interrupts on and off */ + }; + + struct rcar_gen3_thermal_data { +@@ -113,6 +125,7 @@ static inline void rcar_gen3_thermal_wri + + #define FIXPT_SHIFT 7 + #define FIXPT_INT(_x) ((_x) << FIXPT_SHIFT) ++#define INT_FIXPT(_x) ((_x) >> FIXPT_SHIFT) + #define FIXPT_DIV(_a, _b) DIV_ROUND_CLOSEST(((_a) << FIXPT_SHIFT), (_b)) + #define FIXPT_TO_MCELSIUS(_x) ((_x) * 1000 >> FIXPT_SHIFT) + +@@ -178,10 +191,87 @@ static int rcar_gen3_thermal_get_temp(vo + return 0; + } + ++static int rcar_gen3_thermal_mcelsius_to_temp(struct rcar_gen3_thermal_tsc *tsc, ++ int mcelsius) ++{ ++ int celsius, val1, val2; ++ ++ celsius = DIV_ROUND_CLOSEST(mcelsius, 1000); ++ val1 = celsius * tsc->coef.a1 + tsc->coef.b1; ++ val2 = celsius * tsc->coef.a2 + tsc->coef.b2; ++ ++ return INT_FIXPT((val1 + val2) / 2); ++} ++ ++static int rcar_gen3_thermal_set_trips(void *devdata, int low, int high) ++{ ++ struct rcar_gen3_thermal_tsc *tsc = devdata; ++ ++ low = clamp_val(low, -40000, 125000); ++ high = clamp_val(high, -40000, 125000); ++ ++ rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP1, ++ rcar_gen3_thermal_mcelsius_to_temp(tsc, low)); ++ ++ rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP2, ++ rcar_gen3_thermal_mcelsius_to_temp(tsc, high)); ++ ++ return 0; ++} ++ + static struct thermal_zone_of_device_ops rcar_gen3_tz_of_ops = { + .get_temp = rcar_gen3_thermal_get_temp, ++ .set_trips = rcar_gen3_thermal_set_trips, + }; + ++static void rcar_thermal_irq_set(struct rcar_gen3_thermal_priv *priv, bool on) ++{ ++ unsigned int i; ++ u32 val = on ? IRQ_TEMPD1 | IRQ_TEMP2 : 0; ++ ++ for (i = 0; i < priv->num_tscs; i++) ++ rcar_gen3_thermal_write(priv->tscs[i], REG_GEN3_IRQMSK, val); ++} ++ ++static irqreturn_t rcar_gen3_thermal_irq(int irq, void *data) ++{ ++ struct rcar_gen3_thermal_priv *priv = data; ++ u32 status; ++ int i, ret = IRQ_HANDLED; ++ ++ spin_lock(&priv->lock); ++ for (i = 0; i < priv->num_tscs; i++) { ++ status = rcar_gen3_thermal_read(priv->tscs[i], REG_GEN3_IRQSTR); ++ rcar_gen3_thermal_write(priv->tscs[i], REG_GEN3_IRQSTR, 0); ++ if (status) ++ ret = IRQ_WAKE_THREAD; ++ } ++ ++ if (ret == IRQ_WAKE_THREAD) ++ rcar_thermal_irq_set(priv, false); ++ ++ spin_unlock(&priv->lock); ++ ++ return ret; ++} ++ ++static irqreturn_t rcar_gen3_thermal_irq_thread(int irq, void *data) ++{ ++ struct rcar_gen3_thermal_priv *priv = data; ++ unsigned long flags; ++ int i; ++ ++ for (i = 0; i < priv->num_tscs; i++) ++ thermal_zone_device_update(priv->tscs[i]->zone, ++ THERMAL_EVENT_UNSPECIFIED); ++ ++ spin_lock_irqsave(&priv->lock, flags); ++ rcar_thermal_irq_set(priv, true); ++ spin_unlock_irqrestore(&priv->lock, flags); ++ ++ return IRQ_HANDLED; ++} ++ + static void r8a7795_thermal_init(struct rcar_gen3_thermal_tsc *tsc) + { + rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_THBGR); +@@ -190,7 +280,11 @@ static void r8a7795_thermal_init(struct + usleep_range(1000, 2000); + + rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_PONM); ++ + rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0x3F); ++ rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, 0); ++ rcar_gen3_thermal_write(tsc, REG_GEN3_IRQEN, IRQ_TEMPD1 | IRQ_TEMP2); ++ + rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, + CTSR_PONM | CTSR_AOUT | CTSR_THBGR | CTSR_VMEN); + +@@ -214,6 +308,9 @@ static void r8a7796_thermal_init(struct + usleep_range(1000, 2000); + + rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0x3F); ++ rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, 0); ++ rcar_gen3_thermal_write(tsc, REG_GEN3_IRQEN, IRQ_TEMPD1 | IRQ_TEMP2); ++ + reg_val = rcar_gen3_thermal_read(tsc, REG_GEN3_THCTR); + reg_val |= THCTR_THSST; + rcar_gen3_thermal_write(tsc, REG_GEN3_THCTR, reg_val); +@@ -252,7 +349,8 @@ static int rcar_gen3_thermal_probe(struc + struct device *dev = &pdev->dev; + struct resource *res; + struct thermal_zone_device *zone; +- int ret, i; ++ int ret, irq, i; ++ char *irqname; + const struct rcar_gen3_thermal_data *match_data = + of_device_get_match_data(dev); + +@@ -269,8 +367,32 @@ static int rcar_gen3_thermal_probe(struc + if (!priv) + return -ENOMEM; + ++ spin_lock_init(&priv->lock); ++ + platform_set_drvdata(pdev, priv); + ++ /* ++ * Request 2 (of the 3 possible) IRQs, the driver only needs to ++ * to trigger on the low and high trip points of the current ++ * temp window at this point. ++ */ ++ for (i = 0; i < 2; i++) { ++ irq = platform_get_irq(pdev, i); ++ if (irq < 0) ++ return irq; ++ ++ irqname = devm_kasprintf(dev, GFP_KERNEL, "%s:ch%d", ++ dev_name(dev), i); ++ if (!irqname) ++ return -ENOMEM; ++ ++ ret = devm_request_threaded_irq(dev, irq, rcar_gen3_thermal_irq, ++ rcar_gen3_thermal_irq_thread, ++ IRQF_SHARED, irqname, priv); ++ if (ret) ++ return ret; ++ } ++ + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + +@@ -306,6 +428,12 @@ static int rcar_gen3_thermal_probe(struc + goto error_unregister; + } + tsc->zone = zone; ++ ++ ret = of_thermal_get_ntrips(tsc->zone); ++ if (ret < 0) ++ goto error_unregister; ++ ++ dev_info(dev, "TSC%d: Loaded %d trip points\n", i, ret); + } + + priv->num_tscs = i; +@@ -315,6 +443,8 @@ static int rcar_gen3_thermal_probe(struc + goto error_unregister; + } + ++ rcar_thermal_irq_set(priv, true); ++ + return 0; + + error_unregister: diff --git a/patches.renesas/thermal-rcar_gen3_thermal-record-and-check-number-of-tscs-found.patch b/patches.renesas/thermal-rcar_gen3_thermal-record-and-check-number-of-tscs-found.patch new file mode 100644 index 00000000000000..aa17004144a93a --- /dev/null +++ b/patches.renesas/thermal-rcar_gen3_thermal-record-and-check-number-of-tscs-found.patch @@ -0,0 +1,49 @@ +From horms@vergenet.net Tue Sep 5 10:07:56 2017 +From: Simon Horman <horms@verge.net.au> +Date: Tue, 5 Sep 2017 10:06:41 +0200 +Subject: [PATCH 06/13] thermal: rcar_gen3_thermal: record and check number of TSCs found +To: Greg KH <gregkh@linuxfoundation.org> +Cc: ltsi-dev@lists.linuxfoundation.org, linux-renesas-soc@vger.kernel.org, Magnus Damm <magnus.damm@gmail.com> +Message-ID: <1504598808-19810-7-git-send-email-horms@verge.net.au> + + +From: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> + +Record how many TSCs are found in struct rcar_gen3_thermal_priv, this is +needed to be able to add hardware interrupts for trip points later. Also +add a check to make sure at least one TSC is found. + +Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> +Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> +Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com> +Signed-off-by: Eduardo Valentin <edubezval@gmail.com> +(cherry picked from commit 97dad1f1d2b3f2a2a77551849357b7ac38b0b6ff) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/thermal/rcar_gen3_thermal.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/thermal/rcar_gen3_thermal.c ++++ b/drivers/thermal/rcar_gen3_thermal.c +@@ -75,6 +75,7 @@ struct rcar_gen3_thermal_tsc { + + struct rcar_gen3_thermal_priv { + struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM]; ++ unsigned int num_tscs; + }; + + struct rcar_gen3_thermal_data { +@@ -307,6 +308,13 @@ static int rcar_gen3_thermal_probe(struc + tsc->zone = zone; + } + ++ priv->num_tscs = i; ++ ++ if (!priv->num_tscs) { ++ ret = -ENODEV; ++ goto error_unregister; ++ } ++ + return 0; + + error_unregister: diff --git a/patches.renesas/thermal-rcar_gen3_thermal-remove-unneeded-mutex.patch b/patches.renesas/thermal-rcar_gen3_thermal-remove-unneeded-mutex.patch new file mode 100644 index 00000000000000..f6a7b1a764f7e7 --- /dev/null +++ b/patches.renesas/thermal-rcar_gen3_thermal-remove-unneeded-mutex.patch @@ -0,0 +1,68 @@ +From horms@vergenet.net Tue Sep 5 10:07:29 2017 +From: Simon Horman <horms@verge.net.au> +Date: Tue, 5 Sep 2017 10:06:39 +0200 +Subject: [PATCH 04/13] thermal: rcar_gen3_thermal: remove unneeded mutex +To: Greg KH <gregkh@linuxfoundation.org> +Cc: ltsi-dev@lists.linuxfoundation.org, linux-renesas-soc@vger.kernel.org, Magnus Damm <magnus.damm@gmail.com> +Message-ID: <1504598808-19810-5-git-send-email-horms@verge.net.au> + + +From: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> + +There is no point in protecting a register read with a lock. This is +most likely a leftover from when the driver was reworked before being +submitted for upstream. + +Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> +Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> +Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com> +Signed-off-by: Eduardo Valentin <edubezval@gmail.com> +(cherry picked from commit 100cfbcf2580b0605f50af32fefd9c8d1d8357fb) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/thermal/rcar_gen3_thermal.c | 7 ------- + 1 file changed, 7 deletions(-) + +--- a/drivers/thermal/rcar_gen3_thermal.c ++++ b/drivers/thermal/rcar_gen3_thermal.c +@@ -20,7 +20,6 @@ + #include <linux/interrupt.h> + #include <linux/io.h> + #include <linux/module.h> +-#include <linux/mutex.h> + #include <linux/of_device.h> + #include <linux/platform_device.h> + #include <linux/pm_runtime.h> +@@ -72,7 +71,6 @@ struct rcar_gen3_thermal_tsc { + void __iomem *base; + struct thermal_zone_device *zone; + struct equation_coefs coef; +- struct mutex lock; + }; + + struct rcar_gen3_thermal_priv { +@@ -163,16 +161,12 @@ static int rcar_gen3_thermal_get_temp(vo + u32 reg; + + /* Read register and convert to mili Celsius */ +- mutex_lock(&tsc->lock); +- + reg = rcar_gen3_thermal_read(tsc, REG_GEN3_TEMP) & CTEMP_MASK; + + val1 = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b1, tsc->coef.a1); + val2 = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b2, tsc->coef.a2); + mcelsius = FIXPT_TO_MCELSIUS((val1 + val2) / 2); + +- mutex_unlock(&tsc->lock); +- + /* Make sure we are inside specifications */ + if ((mcelsius < MCELSIUS(-40)) || (mcelsius > MCELSIUS(125))) + return -EIO; +@@ -299,7 +293,6 @@ static int rcar_gen3_thermal_probe(struc + } + + priv->tscs[i] = tsc; +- mutex_init(&tsc->lock); + + match_data->thermal_init(tsc); + rcar_gen3_thermal_calc_coefs(&tsc->coef, ptat, thcode[i]); diff --git a/patches.renesas/thermal-rcar_gen3_thermal-store-device-match-data-in-private-structure.patch b/patches.renesas/thermal-rcar_gen3_thermal-store-device-match-data-in-private-structure.patch new file mode 100644 index 00000000000000..f7222a3a6adef8 --- /dev/null +++ b/patches.renesas/thermal-rcar_gen3_thermal-store-device-match-data-in-private-structure.patch @@ -0,0 +1,61 @@ +From horms@vergenet.net Tue Sep 5 10:07:52 2017 +From: Simon Horman <horms@verge.net.au> +Date: Tue, 5 Sep 2017 10:06:43 +0200 +Subject: [PATCH 08/13] thermal: rcar_gen3_thermal: store device match data in private structure +To: Greg KH <gregkh@linuxfoundation.org> +Cc: ltsi-dev@lists.linuxfoundation.org, linux-renesas-soc@vger.kernel.org, Magnus Damm <magnus.damm@gmail.com> +Message-ID: <1504598808-19810-9-git-send-email-horms@verge.net.au> + + +From: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> + +The device match data needs to be accessible outside the probe function, +store it in the private data structure. + +Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> +Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> +Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com> +Signed-off-by: Eduardo Valentin <edubezval@gmail.com> +(cherry picked from commit cc4d072b66298716484f5c78d782c64509f4b6d9) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/thermal/rcar_gen3_thermal.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/thermal/rcar_gen3_thermal.c ++++ b/drivers/thermal/rcar_gen3_thermal.c +@@ -88,6 +88,7 @@ struct rcar_gen3_thermal_priv { + struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM]; + unsigned int num_tscs; + spinlock_t lock; /* Protect interrupts on and off */ ++ const struct rcar_gen3_thermal_data *data; + }; + + struct rcar_gen3_thermal_data { +@@ -351,8 +352,6 @@ static int rcar_gen3_thermal_probe(struc + struct thermal_zone_device *zone; + int ret, irq, i; + char *irqname; +- const struct rcar_gen3_thermal_data *match_data = +- of_device_get_match_data(dev); + + /* default values if FUSEs are missing */ + /* TODO: Read values from hardware on supported platforms */ +@@ -367,6 +366,8 @@ static int rcar_gen3_thermal_probe(struc + if (!priv) + return -ENOMEM; + ++ priv->data = of_device_get_match_data(dev); ++ + spin_lock_init(&priv->lock); + + platform_set_drvdata(pdev, priv); +@@ -417,7 +418,7 @@ static int rcar_gen3_thermal_probe(struc + + priv->tscs[i] = tsc; + +- match_data->thermal_init(tsc); ++ priv->data->thermal_init(tsc); + rcar_gen3_thermal_calc_coefs(&tsc->coef, ptat, thcode[i]); + + zone = devm_thermal_zone_of_sensor_register(dev, i, tsc, diff --git a/patches.renesas/usb-host-ehci-platform-fix-usb-1.1-device-is-not-connected-in-system-resume.patch b/patches.renesas/usb-host-ehci-platform-fix-usb-1.1-device-is-not-connected-in-system-resume.patch new file mode 100644 index 00000000000000..5dd80b2e0aae98 --- /dev/null +++ b/patches.renesas/usb-host-ehci-platform-fix-usb-1.1-device-is-not-connected-in-system-resume.patch @@ -0,0 +1,64 @@ +From horms@vergenet.net Tue Sep 5 10:07:53 2017 +From: Simon Horman <horms@verge.net.au> +Date: Tue, 5 Sep 2017 10:06:45 +0200 +Subject: [PATCH 10/13] usb: host: ehci-platform: fix usb 1.1 device is not connected in system resume +To: Greg KH <gregkh@linuxfoundation.org> +Cc: ltsi-dev@lists.linuxfoundation.org, linux-renesas-soc@vger.kernel.org, Magnus Damm <magnus.damm@gmail.com> +Message-ID: <1504598808-19810-11-git-send-email-horms@verge.net.au> + + +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> + +This patch fixes an issue that a usb 1.1 device is not connected in +system resume and then the following message appeared if debug messages +are enabled: + usb 2-1: Waited 2000ms for CONNECT + +To resolve this issue, the EHCI controller must be resumed after its +companion controllers. So, this patch adds such code on the driver. + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit d4d75128b8fd727d42c775a16b41634d09409dba) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/usb/host/ehci-platform.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/usb/host/ehci-platform.c ++++ b/drivers/usb/host/ehci-platform.c +@@ -34,6 +34,7 @@ + #include <linux/usb.h> + #include <linux/usb/hcd.h> + #include <linux/usb/ehci_pdriver.h> ++#include <linux/usb/of.h> + + #include "ehci.h" + +@@ -297,6 +298,7 @@ static int ehci_platform_probe(struct pl + goto err_power; + + device_wakeup_enable(hcd->self.controller); ++ device_enable_async_suspend(hcd->self.controller); + platform_set_drvdata(dev, hcd); + + return err; +@@ -370,6 +372,7 @@ static int ehci_platform_resume(struct d + struct usb_ehci_pdata *pdata = dev_get_platdata(dev); + struct platform_device *pdev = to_platform_device(dev); + struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); ++ struct device *companion_dev; + + if (pdata->power_on) { + int err = pdata->power_on(pdev); +@@ -377,6 +380,10 @@ static int ehci_platform_resume(struct d + return err; + } + ++ companion_dev = usb_of_get_companion_dev(hcd->self.controller); ++ if (companion_dev) ++ device_pm_wait_for_dev(hcd->self.controller, companion_dev); ++ + ehci_resume(hcd, priv->reset_on_resume); + return 0; + } diff --git a/patches.renesas/usb-host-ehci-platform-set-hcd-phy-to-avoid-phy_get-in-usb_add_hcd.patch b/patches.renesas/usb-host-ehci-platform-set-hcd-phy-to-avoid-phy_get-in-usb_add_hcd.patch new file mode 100644 index 00000000000000..de18f084dce535 --- /dev/null +++ b/patches.renesas/usb-host-ehci-platform-set-hcd-phy-to-avoid-phy_get-in-usb_add_hcd.patch @@ -0,0 +1,37 @@ +From horms@vergenet.net Tue Sep 5 10:07:49 2017 +From: Simon Horman <horms@verge.net.au> +Date: Tue, 5 Sep 2017 10:06:46 +0200 +Subject: [PATCH 11/13] usb: host: ehci-platform: set hcd->phy to avoid phy_get() in usb_add_hcd() +To: Greg KH <gregkh@linuxfoundation.org> +Cc: ltsi-dev@lists.linuxfoundation.org, linux-renesas-soc@vger.kernel.org, Magnus Damm <magnus.damm@gmail.com> +Message-ID: <1504598808-19810-12-git-send-email-horms@verge.net.au> + + +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> + +This patch sets hcd->phy from own phy context to avoid phy_get() +in usb_add_hcd(). Since core/hcd.c manages the phy only in +usb_add_hcd() and usb_remove_hcd(), there is difficult to manage +the phy in suspend/resume. + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 42a58c9949ddf16e557f5c2e22566f3440e7b60f) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/usb/host/ehci-platform.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/host/ehci-platform.c ++++ b/drivers/usb/host/ehci-platform.c +@@ -221,6 +221,9 @@ static int ehci_platform_probe(struct pl + if (IS_ERR(priv->phys[phy_num])) { + err = PTR_ERR(priv->phys[phy_num]); + goto err_put_hcd; ++ } else if (!hcd->phy) { ++ /* Avoiding phy_get() in usb_add_hcd() */ ++ hcd->phy = priv->phys[phy_num]; + } + } + diff --git a/patches.renesas/usb-host-ohci-platform-set-hcd-phy-to-avoid-phy_get-in-usb_add_hcd.patch b/patches.renesas/usb-host-ohci-platform-set-hcd-phy-to-avoid-phy_get-in-usb_add_hcd.patch new file mode 100644 index 00000000000000..5f6d78afd01c93 --- /dev/null +++ b/patches.renesas/usb-host-ohci-platform-set-hcd-phy-to-avoid-phy_get-in-usb_add_hcd.patch @@ -0,0 +1,37 @@ +From horms@vergenet.net Tue Sep 5 10:07:51 2017 +From: Simon Horman <horms@verge.net.au> +Date: Tue, 5 Sep 2017 10:06:47 +0200 +Subject: [PATCH 12/13] usb: host: ohci-platform: set hcd->phy to avoid phy_get() in usb_add_hcd() +To: Greg KH <gregkh@linuxfoundation.org> +Cc: ltsi-dev@lists.linuxfoundation.org, linux-renesas-soc@vger.kernel.org, Magnus Damm <magnus.damm@gmail.com> +Message-ID: <1504598808-19810-13-git-send-email-horms@verge.net.au> + + +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> + +This patch sets hcd->phy from own phy context to avoid phy_get() +in usb_add_hcd(). Since core/hcd.c manages the phy only in +usb_add_hcd() and usb_remove_hcd(), there is difficult to manage +the phy in suspend/resume. + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit d3d6ef1fb908b286a610fe063613e519bc50178b) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/usb/host/ohci-platform.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/host/ohci-platform.c ++++ b/drivers/usb/host/ohci-platform.c +@@ -183,6 +183,9 @@ static int ohci_platform_probe(struct pl + if (IS_ERR(priv->phys[phy_num])) { + err = PTR_ERR(priv->phys[phy_num]); + goto err_put_hcd; ++ } else if (!hcd->phy) { ++ /* Avoiding phy_get() in usb_add_hcd() */ ++ hcd->phy = priv->phys[phy_num]; + } + } + @@ -849,6 +849,20 @@ patches.renesas/0284-ARM-dts-genmai-Enable-rtc-and-rtc_x1-clock.patch patches.renesas/0285-ARM-dts-r8a7790-Drop-_clk-suffix-from-external-CAN-c.patch patches.renesas/0286-ARM-dts-r8a7791-Drop-_clk-suffix-from-external-CAN-c.patch +patches.renesas/thermal-rcar_gen3_thermal-document-the-r-car-gen3.patch +patches.renesas/thermal-rcar_gen3_thermal-add-r-car-gen3-thermal-driver.patch +patches.renesas/thermal-rcar_gen3_thermal-add-delay-in-.thermal_init-on-r8a7796.patch +patches.renesas/thermal-rcar_gen3_thermal-remove-unneeded-mutex.patch +patches.renesas/thermal-rcar_gen3_thermal-check-that-tsc-exists-before-memory-allocation.patch +patches.renesas/thermal-rcar_gen3_thermal-record-and-check-number-of-tscs-found.patch +patches.renesas/thermal-rcar_gen3_thermal-enable-hardware-interrupts-for-trip-points.patch +patches.renesas/thermal-rcar_gen3_thermal-store-device-match-data-in-private-structure.patch +patches.renesas/thermal-rcar_gen3_thermal-add-suspend-and-resume-support.patch +patches.renesas/usb-host-ehci-platform-fix-usb-1.1-device-is-not-connected-in-system-resume.patch +patches.renesas/usb-host-ehci-platform-set-hcd-phy-to-avoid-phy_get-in-usb_add_hcd.patch +patches.renesas/usb-host-ohci-platform-set-hcd-phy-to-avoid-phy_get-in-usb_add_hcd.patch +patches.renesas/clk-cs2000-add-suspend-resume-feature.patch + ############################################################################# # SoCFPGA patches patches.socfpga/0001-ARM-dts-socfpga-enable-arm-shared-override-in-the-pl.patch |