Add support for Thermal and CMT
Subsystems (4)
v2 cover Add support for Thermal and CMT
This patch series add support for thermal and CMT.
This patchset is rebased on top of the previous patch set
0001-pinctrl-sh-pfc-r8a7791-Add-can_clk-function.patch to 0058-thermal-rcar_thermal-don-t-open-code-of_device_get_m.patch
V1-->V2
* Incorporated thermal related review comments
* Added CMT support
Biju Das (2):
dt-bindings: thermal: rcar: Add device tree support for r8a7743
ARM: dts: r8a7743: Add thermal device to DT
Bui Duc Phuc (1):
thermal: rcar_thermal: don't call thermal_zone_device_unregister when
USE_OF_THERMAL
Dirk Behme (1):
thermal: rcar_thermal: Fix priv->zone error handling
Eduardo Valentin (1):
thermal: convert rcar_thermal to use
devm_thermal_zone_of_sensor_register
Fabrizio Castro (2):
ARM: dts: r8a7743: Add CMT SoC specific support
ARM: dts: iwg20m: Enable cmt0
Kuninori Morimoto (1):
thermal: rcar-thermal: enable hwmon when
thermal_zone_of_sensor_register is used
Laxman Dewangan (1):
thermal: of-thermal: Add devm version of
thermal_zone_of_sensor_register
Nicolai Stange (2):
clocksource: sh_cmt: Compute rate before registration again clockevents/drivers/sh_cmt: Set ->min_delta_ticks and
->max_delta_ticks
.../devicetree/bindings/thermal/rcar-thermal.txt | 1 + arch/arm/boot/dts/r8a7743-iwg20m.dtsi | 4 ++ arch/arm/boot/dts/r8a7743.dtsi | 67 ++++++++++++++++++ drivers/clocksource/sh_cmt.c | 47 +++++++------ drivers/thermal/of-thermal.c | 81 ++++++++++++++++++++++ drivers/thermal/rcar_thermal.c | 26 +++++-- include/linux/thermal.h | 18 +++++ 7 files changed, 220 insertions(+), 24 deletions(-)
Signature · 1 line
2.7.4
PATCH v2 1/11 thermal: of-thermal: Add devm version of thermal_zone_of_sensor_register
From: Laxman Dewangan <[email protected]>
Add resource managed version of thermal_zone_of_sensor_register() and thermal_zone_of_sensor_unregister().
This helps in reducing the code size in error path, remove of driver remove callbacks and making proper sequence for deallocations.
--- drivers/thermal/of-thermal.c | 81 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/thermal.h | 18 ++++++++++ 2 files changed, 99 insertions(+)
drivers/thermal/of-thermal.c +81 -0
@@ -559,6 +559,87 @@ void thermal_zone_of_sensor_unregister(struct device *dev, }EXPORT_SYMBOL_GPL (thermal_zone_of_sensor_unregister); +static void devm_thermal_zone_of_sensor_release (struct device *dev,void *res) +{ +thermal_zone_of_sensor_unregister (dev, + *(struct thermal_zone_device **)res); +} + +static int devm_thermal_zone_of_sensor_match (struct device *dev,void *res, +void *data) +{ +struct thermal_zone_device **r = res; + +if (WARN_ON (!r || !*r)) +return 0 ; + +return *r == data; +} + +/** +* devm_thermal_zone_of_sensor_register - Resource managed version of +* thermal_zone_of_sensor_register() +* @dev: a valid struct device pointer of a sensor device. Must contain +* a valid .of_node, for the sensor node. +* @sensor_id: a sensor identifier, in case the sensor IP has more +* than one sensors +* @data: a private pointer (owned by the caller) that will be passed +* back, when a temperature reading is needed. +* @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp. +* +* Refer thermal_zone_of_sensor_register() for more details. +* +* Return: On success returns a valid struct thermal_zone_device, +* otherwise, it returns a corresponding ERR_PTR(). Caller must +* check the return value with help of IS_ERR() helper. +* Registered hermal_zone_device device will automatically be +* released when device is unbounded. +*/ +struct thermal_zone_device *devm_thermal_zone_of_sensor_register ( +struct device *dev,int sensor_id, +void *data,const struct thermal_zone_of_device_ops *ops) +{ +struct thermal_zone_device **ptr, *tzd; + + ptr =devres_alloc (devm_thermal_zone_of_sensor_release,sizeof (*ptr), +GFP_KERNEL ); +if (!ptr) +return ERR_PTR (-ENOMEM ); + + tzd =thermal_zone_of_sensor_register (dev, sensor_id, data, ops); +if (IS_ERR (tzd)) { +devres_free (ptr); +return tzd; + } + + *ptr = tzd; +devres_add (dev, ptr); + +return tzd; +} +EXPORT_SYMBOL_GPL (devm_thermal_zone_of_sensor_register); + +/** +* devm_thermal_zone_of_sensor_unregister - Resource managed version of +* thermal_zone_of_sensor_unregister(). +* @dev: Device for which which resource was allocated. +* @tzd: a pointer to struct thermal_zone_device where the sensor is registered. +* +* This function removes the sensor callbacks and private data from the +* thermal zone device registered with devm_thermal_zone_of_sensor_register() +* API. It will also silent the zone by remove the .get_temp() and .get_trend() +* thermal zone device callbacks. +* Normally this function will not need to be called and the resource +* management code will ensure that the resource is freed. +*/ +void devm_thermal_zone_of_sensor_unregister (struct device *dev, +struct thermal_zone_device *tzd) +{ +WARN_ON (devres_release (dev, devm_thermal_zone_of_sensor_release, + devm_thermal_zone_of_sensor_match, tzd)); +} +EXPORT_SYMBOL_GPL (devm_thermal_zone_of_sensor_unregister); +/*** functions parsing device tree nodes ***/ /**
include/linux/thermal.h +18 -0
@@ -364,6 +364,11 @@ thermal_zone_of_sensor_register(struct device *dev, int id, void *data, const struct thermal_zone_of_device_ops *ops);void thermal_zone_of_sensor_unregister (struct device *dev,struct thermal_zone_device *tz); +struct thermal_zone_device *devm_thermal_zone_of_sensor_register ( +struct device *dev,int id,void *data, +const struct thermal_zone_of_device_ops *ops); +void devm_thermal_zone_of_sensor_unregister (struct device *dev, +struct thermal_zone_device *tz);#else static inline struct thermal_zone_device * thermal_zone_of_sensor_register(struct device *dev, int id, void *data,
@@ -378,6 +383,19 @@ void thermal_zone_of_sensor_unregister(struct device *dev, { } +static inline struct thermal_zone_device *devm_thermal_zone_of_sensor_register ( +struct device *dev,int id,void *data, +const struct thermal_zone_of_device_ops *ops) +{ +return ERR_PTR (-ENODEV ); +} + +static inline +void devm_thermal_zone_of_sensor_unregister (struct device *dev, +struct thermal_zone_device *tz) +{ +} +#endif #if IS_ENABLED (CONFIG_THERMAL )
Signature · 1 line
2.7.4
PATCH v2 2/11 thermal: convert rcar_thermal to use devm_thermal_zone_of_sensor_register
In reply to Biju DasFrom: Eduardo Valentin <[email protected]>
This changes the driver to use the devm_ version
of thermal_zone_of_sensor_register and cleans
up the local points and unregister calls.
--- drivers/thermal/rcar_thermal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/thermal/rcar_thermal.c +1 -1
@@ -492,7 +492,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) goto error_unregister;if (of_data ==USE_OF_THERMAL ) - priv->zone =thermal_zone_of_sensor_register ( + priv->zone =devm_thermal_zone_of_sensor_register ( dev, i, priv, &rcar_thermal_zone_of_ops);else
Signature · 1 line
2.7.4
PATCH v2 3/11 thermal: rcar_thermal: Fix priv->zone error handling
In reply to Biju DasFrom: Dirk Behme <[email protected]>
In case thermal_zone_xxx_register() returns an error, priv->zone isn't NULL any more, but contains the error code.
This is passed to thermal_zone_device_unregister(), then. This checks for priv->zone being NULL, but the error code is != NULL. So it works with the error code as a pointer. Crashing immediately.
To fix this, reset priv->zone to NULL before entering rcar_gen3_thermal_remove().
--- drivers/thermal/rcar_thermal.c | 1 + 1 file changed, 1 insertion(+)
drivers/thermal/rcar_thermal.c +1 -0
@@ -504,6 +504,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)if (IS_ERR (priv->zone)) {dev_err (dev,"can't register thermal zone\n" ); ret =PTR_ERR (priv->zone); + priv->zone =NULL ; goto error_unregister; }
Signature · 1 line
2.7.4
PATCH v2 4/11 thermal: rcar-thermal: enable hwmon when thermal_zone_of_sensor_register is used
In reply to Biju DasFrom: Kuninori Morimoto <[email protected]>
rcar-thermal is supporting both thermal_zone_of_sensor_register() and thermal_zone_device_register(). But thermal_zone_of_sensor_register() doesn't enable hwmon as default.
This patch enables it to keep compatibility
--- drivers/thermal/rcar_thermal.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
drivers/thermal/rcar_thermal.c +18 -2
@@ -31,6 +31,8 @@#include <linux/spinlock.h> #include <linux/thermal.h> +#include "thermal_hwmon.h" +#define IDLE_INTERVAL 5000#define COMMON_STR 0x00
@@ -75,6 +77,8 @@ struct rcar_thermal_priv {#define rcar_priv_to_dev (priv) ((priv)->common->dev)#define rcar_has_irq_support (priv) ((priv)->common->base)#define rcar_id_to_shift (priv) ((priv)->id * 8) +#define rcar_of_data (dev) ((unsigned long)of_device_get_match_data(dev)) +#define rcar_use_of_thermal (dev) (rcar_of_data(dev) == USE_OF_THERMAL)#define USE_OF_THERMAL 1static const struct of_device_id rcar_thermal_dt_ids[] = {
@@ -416,6 +420,8 @@ static int rcar_thermal_remove(struct platform_device *pdev)rcar_thermal_for_each_priv (priv, common) {rcar_thermal_irq_disable (priv);thermal_zone_device_unregister (priv->zone); +if (rcar_use_of_thermal (dev)) +thermal_remove_hwmon_sysfs (priv->zone); }pm_runtime_put (dev);
@@ -430,7 +436,6 @@ static int rcar_thermal_probe(struct platform_device *pdev)struct rcar_thermal_priv *priv;struct device *dev = &pdev->dev;struct resource *res, *irq; -unsigned long of_data = (unsigned long )of_device_get_match_data (dev);int mres =0 ;int i;int ret = -ENODEV ;
@@ -491,7 +496,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)if (ret <0 ) goto error_unregister; -if (of_data ==USE_OF_THERMAL ) +if (rcar_use_of_thermal (dev)) priv->zone =devm_thermal_zone_of_sensor_register ( dev, i, priv, &rcar_thermal_zone_of_ops);
@@ -508,6 +513,17 @@ static int rcar_thermal_probe(struct platform_device *pdev) goto error_unregister; } +if (rcar_use_of_thermal (dev)) { +/* +* thermal_zone doesn't enable hwmon as default, +* but, enable it here to keep compatible +*/ + priv->zone->tzp->no_hwmon = false; + ret =thermal_add_hwmon_sysfs (priv->zone); +if (ret) + goto error_unregister; + } +rcar_thermal_irq_enable (priv);list_move_tail (&priv->list, &common->head);
Signature · 1 line
2.7.4
PATCH v2 5/11 thermal: rcar_thermal: don't call thermal_zone_device_unregister when USE_OF_THERMAL
In reply to Biju DasFrom: Bui Duc Phuc <[email protected]>
devm_thermal_zone_of_sensor_register() case doesn't need to call thermal_zone_device_unregister().
Otherwise, rcar-thermal can't register thermal zone again after rebind. This patch fixes it.
--- drivers/thermal/rcar_thermal.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/thermal/rcar_thermal.c +2 -1
@@ -419,9 +419,10 @@ static int rcar_thermal_remove(struct platform_device *pdev)rcar_thermal_for_each_priv (priv, common) {rcar_thermal_irq_disable (priv); -thermal_zone_device_unregister (priv->zone);if (rcar_use_of_thermal (dev))thermal_remove_hwmon_sysfs (priv->zone); +else +thermal_zone_device_unregister (priv->zone); }pm_runtime_put (dev);
Signature · 1 line
2.7.4
PATCH v2 6/11 dt-bindings: thermal: rcar: Add device tree support for r8a7743
In reply to Biju DasAdd thermal sensor support for r8a7743 SoC. The Renesas RZ/G1M (r8a7743) thermal sensor module is identical to the R-Car Gen2 family.
No driver change is needed due to the fallback compatible value "renesas,rcar-gen2-thermal".
--- Documentation/devicetree/bindings/thermal/rcar-thermal.txt | 1 + 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/thermal/rcar-thermal.txt +1 -0
@@ -6,6 +6,7 @@ Required properties: "renesas,rcar-thermal" (without thermal-zone) as fallback. Examples with soctypes are: - "renesas,thermal-r8a73a4" (R-Mobile APE6) + - "renesas,thermal-r8a7743" (RZ/G1M) - "renesas,thermal-r8a7779" (R-Car H1) - "renesas,thermal-r8a7790" (R-Car H2) - "renesas,thermal-r8a7791" (R-Car M2-W)
Signature · 1 line
2.7.4
PATCH v2 7/11 ARM: dts: r8a7743: Add thermal device to DT
In reply to Biju DasThis patch instantiates the thermal sensor module with thermal-zone support.
This patch is based on the commit cac68a56e34b
("ARM: dts: r8a7791: enable to use thermal-zone") by Kuninori Morimoto.
(updated clocks and power-domains property.removed resets property)
--- arch/arm/boot/dts/r8a7743.dtsi | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
arch/arm/boot/dts/r8a7743.dtsi +31 -0
@@ -237,6 +237,37 @@ power-domains = <&cpg_clocks>; }; + thermal: thermal at e61f0000 { + compatible = "renesas,thermal-r8a7743", + "renesas,rcar-gen2-thermal", + "renesas,rcar-thermal"; + reg = <0 0xe61f0000 0 0x10>, <0 0xe61f0100 0 0x38>; + interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp5_clks R8A7743_CLK_THERMAL>; + power-domains = <&cpg_clocks>; + #thermal-sensor-cells = <0>; + }; + + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + + thermal-sensors = <&thermal>; + + trips { + cpu-crit { + temperature = <95000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + }; + }; + }; + timer { compatible = "arm,armv7-timer"; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
Signature · 1 line
2.7.4
PATCH v2 7/11 ARM: dts: r8a7743: Add thermal device to DT
Quoted 2 lines · Biju Das
This patch instantiates the thermal sensor module with thermal-zone support.
The thermal-zones node this adds was later moved by commit b9db3affbcdc ("ARM: dts: r8a7743: move timer and thermal-zones nodes out of bus"). Do you think that is worth applying too?
Ben.
Quoted 11 lines
This patch is based on the commit
cac68a56e34b
("ARM: dts: r8a7791: enable to use thermal-zone") by Kuninori Morimoto.Signed-off-by Biju Das <[email protected]>Reviewed-by Fabrizio Castro <[email protected]>Reviewed-by Geert Uytterhoeven <[email protected]>Signed-off-by Simon Horman <[email protected]>(cherry picked from commit 6c76b4f7d89e89f0ae405dfc7a64c6d2b5d02813)(updated clocks and power-domains property.removed resets property)
Signed-off-by Biju Das <[email protected]>Reviewed-by Fabrizio Castro <[email protected]>
[...]
Signature · 4 lines
Ben Hutchings, Software Developer ? Codethink Ltd
https://www.codethink.co.uk/ Dale House, 35 Dale Street
Manchester, M1 2HF, United Kingdom
We respect your privacy.?? See https://www.codethink.co.uk/privacy.htmlPATCH v2 7/11 ARM: dts: r8a7743: Add thermal device to DT
Hello Ben,
Thanks for the feedback.
Quoted 8 lines
-----Original Message-----
From: Ben Hutchings [mailto:ben.hutchings at codethink.co.uk]
Sent: 30 May 2018 19:44
To: Biju Das <[email protected]>
Cc: Chris Paterson <[email protected]>; Fabrizio Castro <[email protected]>; cip-dev at lists.cip-project.org
Subject: Re: [PATCH v2 07/11] ARM: dts: r8a7743: Add thermal device to DT
Quoted 7 lines
Quoted 2 lines · Biju Das
This patch instantiates the thermal sensor module with thermal-zone support.
The thermal-zones node this adds was later moved by commit
b9db3affbcdc("ARM: dts: r8a7743: move timer and thermal-zones nodes out of bus"). Do you think that is worth applying too?
I believe this patch is to fix the "make dtbs W=1" warnings which is not triggered with 4.4 kernel. Other than thermal-zones, we also need to move timer nodes out of bus.
There is another patch in upstream which is for sorting nodes.
I think we can combine this 2 patches at later stage.
What is your thoughts on this?
[>] regards,
Biju
Quoted 11 lines
Quoted 11 lines
This patch is based on the commit
cac68a56e34b
("ARM: dts: r8a7791: enable to use thermal-zone") by Kuninori Morimoto.Signed-off-by Biju Das <[email protected]>Reviewed-by Fabrizio Castro <[email protected]>Reviewed-by Geert Uytterhoeven <[email protected]>Signed-off-by Simon Horman <[email protected]> (cherrypicked from commit
6c76b4f7d89e89f0ae405dfc7a64c6d2b5d02813) (updated clocks and power-domains property.removed resets property)Signed-off-by Biju Das <[email protected]>Reviewed-by Fabrizio Castro <[email protected]>
Quoted 2 lines
[...]
Renesas Electronics Europe Ltd, Dukes Meadow, Millboard Road, Bourne End, Buckinghamshire, SL8 5FH, UK. Registered in England & Wales under Registered No. 04586709.
PATCH v2 8/11 clocksource: sh_cmt: Compute rate before registration again
In reply to Biju DasFrom: Nicolai Stange <[email protected]>
With the upcoming NTP correction related rate adjustments to be implemented in the clockevents core, the latter needs to get informed about every rate change of a clockevent device made after its registration.
Currently, sh_cmt violates this requirement in that it registers its clockevent device with a dummy rate and sets its final ->mult and ->shift values from its ->set_state_oneshot() and ->set_state_periodic() functions respectively.
This patch moves the setting of the clockevent device's ->mult and ->shift values to before its registration.
Note that there has been some back and forth regarding this question with respect to the clocksource also provided by this driver:
commit f4d7c3565c16 ("clocksource: sh_cmt: compute mult and shift before
registration")
moves the rate determination from the clocksource's ->enable() function to before its registration. OTOH, the later
commit 3593f5fe40a1 ("clocksource: sh_cmt: __clocksource_updatefreq_hz()
update")
basically reverts this, saying
"Without this patch the old code uses clocksource_register() together
with a hack that assumes a never changing clock rate."
However, I checked all current sh_cmt users in arch/sh as well as in arch/arm/mach-shmobile carefully and right now, none of them changes any rate in any clock tree relevant to sh_cmt after their respective time_init(). Since all sh_cmt instances are created after time_init(), none of them should ever observe any clock rate changes.
What's more, both, a clocksource as well as a clockevent device, can immediately get selected for use at their registration and thus, enabled at this point already. So it's probably safer to assume a "never changing clock rate" here.
- Move the struct sh_cmt_channel's ->rate member to struct sh_cmt_device:
it's a property of the underlying clock which is in turn specific to the sh_cmt_device.
- Determine the ->rate value in sh_cmt_setup() at device probing rather than at first usage.
- Set the clockevent device's ->mult and ->shift values right before its registration.
- Although not strictly necessary for the upcoming clockevent core changes, set the clocksource's rate at its registration for consistency.
--- drivers/clocksource/sh_cmt.c | 45 ++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-)
drivers/clocksource/sh_cmt.c +25 -20
@@ -103,7 +103,6 @@ struct sh_cmt_channel {unsigned long match_value;unsigned long next_match_value;unsigned long max_match_value; -unsigned long rate;raw_spinlock_t lock;struct clock_event_device ced;struct clocksource cs;
@@ -118,6 +117,7 @@ struct sh_cmt_device {void __iomem *mapbase;struct clk *clk; +unsigned long rate;raw_spinlock_t lock;/* Protect the shared start/stop register */
@@ -320,7 +320,7 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)raw_spin_unlock_irqrestore (&ch->cmt->lock, flags); } -static int sh_cmt_enable (struct sh_cmt_channel *ch,unsigned long *rate) +static int sh_cmt_enable (struct sh_cmt_channel *ch) {int k, ret;
@@ -340,11 +340,9 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)/* configure channel, periodic mode and maximum timeout */ if (ch->cmt->info->width ==16 ) { - *rate =clk_get_rate (ch->cmt->clk) /512 ;sh_cmt_write_cmcsr (ch,SH_CMT16_CMCSR_CMIE |SH_CMT16_CMCSR_CKS512 ); }else { - *rate =clk_get_rate (ch->cmt->clk) /8 ; sh_cmt_write_cmcsr(ch, SH_CMT32_CMCSR_CMM | SH_CMT32_CMCSR_CMTOUT_IE | SH_CMT32_CMCSR_CMR_IRQ |
@@ -572,7 +570,7 @@ static int sh_cmt_start(struct sh_cmt_channel *ch, unsigned long flag)raw_spin_lock_irqsave (&ch->lock, flags);if (!(ch->flags & (FLAG_CLOCKEVENT |FLAG_CLOCKSOURCE ))) - ret =sh_cmt_enable (ch, &ch->rate); + ret =sh_cmt_enable (ch);if (ret) goto out;
@@ -640,10 +638,9 @@ static int sh_cmt_clocksource_enable(struct clocksource *cs) ch->total_cycles =0 ; ret =sh_cmt_start (ch,FLAG_CLOCKSOURCE ); -if (!ret) { -__clocksource_update_freq_hz (cs, ch->rate); +if (!ret) ch->cs_enabled = true; - } +return ret; }
@@ -697,8 +694,7 @@ static int sh_cmt_register_clocksource(struct sh_cmt_channel *ch,dev_info (&ch->cmt->pdev->dev,"ch%u: used as clock source\n" , ch->index); -/* Register with dummy 1 Hz value, gets updated in ->enable() */ -clocksource_register_hz (cs,1 ); +clocksource_register_hz (cs, ch->cmt->rate);return 0 ; }
@@ -709,19 +705,10 @@ static struct sh_cmt_channel *ced_to_sh_cmt(struct clock_event_device *ced)static void sh_cmt_clock_event_start (struct sh_cmt_channel *ch,int periodic) { -struct clock_event_device *ced = &ch->ced; -sh_cmt_start (ch,FLAG_CLOCKEVENT ); -/* TODO: calculate good shift from rate and counter bit width */ - - ced->shift =32 ; - ced->mult =div_sc (ch->rate,NSEC_PER_SEC , ced->shift); - ced->max_delta_ns =clockevent_delta2ns (ch->max_match_value, ced); - ced->min_delta_ns =clockevent_delta2ns (0x1f , ced); -if (periodic) -sh_cmt_set_next (ch, ((ch->rate +HZ /2 ) /HZ ) -1 ); +sh_cmt_set_next (ch, ((ch->cmt->rate +HZ /2 ) /HZ ) -1 );else sh_cmt_set_next (ch, ch->max_match_value); }
@@ -824,6 +811,12 @@ static int sh_cmt_register_clockevent(struct sh_cmt_channel *ch, ced->suspend = sh_cmt_clock_event_suspend; ced->resume = sh_cmt_clock_event_resume; +/* TODO: calculate good shift from rate and counter bit width */ + ced->shift =32 ; + ced->mult =div_sc (ch->cmt->rate,NSEC_PER_SEC , ced->shift); + ced->max_delta_ns =clockevent_delta2ns (ch->max_match_value, ced); + ced->min_delta_ns =clockevent_delta2ns (0x1f , ced); +dev_info (&ch->cmt->pdev->dev,"ch%u: used for clock events\n" , ch->index);clockevents_register_device (ced);
@@ -996,6 +989,18 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)if (ret <0 ) goto err_clk_put; +/* Determine clock rate. */ + ret =clk_enable (cmt->clk); +if (ret <0 ) + goto err_clk_unprepare; + +if (cmt->info->width ==16 ) + cmt->rate =clk_get_rate (cmt->clk) /512 ; +else + cmt->rate =clk_get_rate (cmt->clk) /8 ; + +clk_disable (cmt->clk); +/* Map the memory resource(s). */ ret =sh_cmt_map_memory (cmt);if (ret <0 )
Signature · 1 line
2.7.4
PATCH v2 9/11 clockevents/drivers/sh_cmt: Set ->min_delta_ticks and ->max_delta_ticks
In reply to Biju DasFrom: Nicolai Stange <[email protected]>
In preparation for making the clockevents core NTP correction aware, all clockevent device drivers must set ->min_delta_ticks and ->max_delta_ticks rather than ->min_delta_ns and ->max_delta_ns: a clockevent device's rate is going to change dynamically and thus, the ratio of ns to ticks ceases to stay invariant.
Make the sh_cmt clockevent driver initialize these fields properly.
This patch alone doesn't introduce any change in functionality as the clockevents core still looks exclusively at the (untouched) ->min_delta_ns and ->max_delta_ns. As soon as this has changed, a followup patch will purge the initialization of ->min_delta_ns and ->max_delta_ns from this driver.
--- drivers/clocksource/sh_cmt.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/clocksource/sh_cmt.c +2 -0
@@ -815,7 +815,9 @@ static int sh_cmt_register_clockevent(struct sh_cmt_channel *ch, ced->shift =32 ; ced->mult =div_sc (ch->cmt->rate,NSEC_PER_SEC , ced->shift); ced->max_delta_ns =clockevent_delta2ns (ch->max_match_value, ced); + ced->max_delta_ticks = ch->max_match_value; ced->min_delta_ns =clockevent_delta2ns (0x1f , ced); + ced->min_delta_ticks =0x1f ;dev_info (&ch->cmt->pdev->dev,"ch%u: used for clock events\n" , ch->index);
Signature · 1 line
2.7.4
PATCH v2 10/11 ARM: dts: r8a7743: Add CMT SoC specific support
In reply to Biju DasFrom: Fabrizio Castro <[email protected]>
Add CMT[01] support to SoC DT.
(updated clocks and power-domains property.removed resets property. Changed the compatible string due to the commit 8d50e9476bb4 ("clocksource/drivers/sh_cmt: Mark "renesas, cmt-48-gen2" deprecated"). Added renesas,channels-mask property which is removed based on the commit 4e18111ff38f0664 ("devicetree:bindings: Remove deprecated properties"))
--- arch/arm/boot/dts/r8a7743.dtsi | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
arch/arm/boot/dts/r8a7743.dtsi +36 -0
@@ -1653,6 +1653,42 @@ status = "disabled"; }; + cmt0: timer at ffca0000 { + compatible = "renesas,cmt-48-r8a7743", + "renesas,cmt-48-gen2"; + reg = <0 0xffca0000 0 0x1004>; + interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp1_clks R8A7743_CLK_CMT0>; + clock-names = "fck"; + power-domains = <&cpg_clocks>; + + renesas,channels-mask = <0x60>; + + status = "disabled"; + }; + + cmt1: timer at e6130000 { + compatible = "renesas,cmt-48-r8a7743", + "renesas,cmt-48-gen2"; + reg = <0 0xe6130000 0 0x1004>; + interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7743_CLK_CMT1>; + clock-names = "fck"; + power-domains = <&cpg_clocks>; + + renesas,channels-mask = <0xff>; + + status = "disabled"; + }; + rcar_sound: sound at ec500000 { /* * #sound-dai-cells is required
Signature · 1 line
2.7.4
PATCH v2 11/11 ARM: dts: iwg20m: Enable cmt0
In reply to Biju DasFrom: Fabrizio Castro <[email protected]>
This patch enables cmt0 support from within the iwg20m SoM dtsi.
--- arch/arm/boot/dts/r8a7743-iwg20m.dtsi | 4 ++++ 1 file changed, 4 insertions(+)
arch/arm/boot/dts/r8a7743-iwg20m.dtsi +4 -0
@@ -34,6 +34,10 @@ }; }; +&cmt0 { + status = "okay"; +}; + &extal_clk { clock-frequency = <20000000>; };
Signature · 1 line
2.7.4