<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-stable.git/drivers/thermal, branch v4.9.166</title>
<subtitle>Linux kernel stable tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/'/>
<entry>
<title>drivers: thermal: int340x_thermal: Fix sysfs race condition</title>
<updated>2019-03-05T16:57:05+00:00</updated>
<author>
<name>Aaron Hill</name>
<email>aa1ronham@gmail.com</email>
</author>
<published>2018-12-24T19:23:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=311acb0a9fafffe472c0137e6e23fe13eccef724'/>
<id>311acb0a9fafffe472c0137e6e23fe13eccef724</id>
<content type='text'>
[ Upstream commit 129699bb8c7572106b5bbb2407c2daee4727ccad ]

Changes since V1:
* Use dev_info instead of printk
* Use dev_warn instead of BUG_ON

Previously, sysfs_create_group was called before all initialization had
fully run - specifically, before pci_set_drvdata was called. Since the
sysctl group is visible to userspace as soon as sysfs_create_group
returns, a small window of time existed during which a process could read
from an uninitialized/partially-initialized device.

This commit moves the creation of the sysctl group to after all
initialized is completed. This ensures that it's impossible for
userspace to read from a sysctl file before initialization has fully
completed.

To catch any future regressions, I've added a check to ensure
that proc_thermal_emum_mode is never PROC_THERMAL_NONE when a process
tries to read from a sysctl file. Previously, the aforementioned race
condition could result in the 'else' branch
running while PROC_THERMAL_NONE was set,
leading to a null pointer deference.

Signed-off-by: Aaron Hill &lt;aa1ronham@gmail.com&gt;
Signed-off-by: Zhang Rui &lt;rui.zhang@intel.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 129699bb8c7572106b5bbb2407c2daee4727ccad ]

Changes since V1:
* Use dev_info instead of printk
* Use dev_warn instead of BUG_ON

Previously, sysfs_create_group was called before all initialization had
fully run - specifically, before pci_set_drvdata was called. Since the
sysctl group is visible to userspace as soon as sysfs_create_group
returns, a small window of time existed during which a process could read
from an uninitialized/partially-initialized device.

This commit moves the creation of the sysctl group to after all
initialized is completed. This ensures that it's impossible for
userspace to read from a sysctl file before initialization has fully
completed.

To catch any future regressions, I've added a check to ensure
that proc_thermal_emum_mode is never PROC_THERMAL_NONE when a process
tries to read from a sysctl file. Previously, the aforementioned race
condition could result in the 'else' branch
running while PROC_THERMAL_NONE was set,
leading to a null pointer deference.

Signed-off-by: Aaron Hill &lt;aa1ronham@gmail.com&gt;
Signed-off-by: Zhang Rui &lt;rui.zhang@intel.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>thermal: int340x_thermal: Fix a NULL vs IS_ERR() check</title>
<updated>2019-03-05T16:57:04+00:00</updated>
<author>
<name>Dan Carpenter</name>
<email>dan.carpenter@oracle.com</email>
</author>
<published>2018-12-17T07:02:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=26e284fab2b42b96524794c04d0d7f099943bb79'/>
<id>26e284fab2b42b96524794c04d0d7f099943bb79</id>
<content type='text'>
[ Upstream commit 3fe931b31a4078395c1967f0495dcc9e5ec6b5e3 ]

The intel_soc_dts_iosf_init() function doesn't return NULL, it returns
error pointers.

Fixes: 4d0dd6c1576b ("Thermal/int340x/processor_thermal: Enable auxiliary DTS for Braswell")
Signed-off-by: Dan Carpenter &lt;dan.carpenter@oracle.com&gt;
Signed-off-by: Zhang Rui &lt;rui.zhang@intel.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 3fe931b31a4078395c1967f0495dcc9e5ec6b5e3 ]

The intel_soc_dts_iosf_init() function doesn't return NULL, it returns
error pointers.

Fixes: 4d0dd6c1576b ("Thermal/int340x/processor_thermal: Enable auxiliary DTS for Braswell")
Signed-off-by: Dan Carpenter &lt;dan.carpenter@oracle.com&gt;
Signed-off-by: Zhang Rui &lt;rui.zhang@intel.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>thermal: hwmon: inline helpers when CONFIG_THERMAL_HWMON is not set</title>
<updated>2019-02-12T18:44:59+00:00</updated>
<author>
<name>Eduardo Valentin</name>
<email>edubezval@gmail.com</email>
</author>
<published>2019-01-02T00:34:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=5bf9ca73e8beeb3948afeb062e688328496ece65'/>
<id>5bf9ca73e8beeb3948afeb062e688328496ece65</id>
<content type='text'>
commit 03334ba8b425b2ad275c8f390cf83c7b081c3095 upstream.

Avoid warnings like this:
thermal_hwmon.h:29:1: warning: ‘thermal_remove_hwmon_sysfs’ defined but not used [-Wunused-function]
 thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)

Fixes: 0dd88793aacd ("thermal: hwmon: move hwmon support to single file")
Reviewed-by: Geert Uytterhoeven &lt;geert+renesas@glider.be&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 03334ba8b425b2ad275c8f390cf83c7b081c3095 upstream.

Avoid warnings like this:
thermal_hwmon.h:29:1: warning: ‘thermal_remove_hwmon_sysfs’ defined but not used [-Wunused-function]
 thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)

Fixes: 0dd88793aacd ("thermal: hwmon: move hwmon support to single file")
Reviewed-by: Geert Uytterhoeven &lt;geert+renesas@glider.be&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
<entry>
<title>thermal: generic-adc: Fix adc to temp interpolation</title>
<updated>2019-02-12T18:44:59+00:00</updated>
<author>
<name>Bjorn Andersson</name>
<email>bjorn.andersson@linaro.org</email>
</author>
<published>2018-12-24T07:26:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=5b4b5b96872fab94a22b0b2097045ac6fea7ab10'/>
<id>5b4b5b96872fab94a22b0b2097045ac6fea7ab10</id>
<content type='text'>
[ Upstream commit 9d216211fded20fff301d0317af3238d8383634c ]

First correct the edge case to return the last element if we're
outside the range, rather than at the last element, so that
interpolation is not omitted for points between the two last entries in
the table.

Then correct the formula to perform linear interpolation based the two
points surrounding the read ADC value. The indices for temp are kept as
"hi" and "lo" to pair with the adc indices, but there's no requirement
that the temperature is provided in descendent order. mult_frac() is
used to prevent issues with overflowing the int.

Cc: Laxman Dewangan &lt;ldewangan@nvidia.com&gt;
Signed-off-by: Bjorn Andersson &lt;bjorn.andersson@linaro.org&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 9d216211fded20fff301d0317af3238d8383634c ]

First correct the edge case to return the last element if we're
outside the range, rather than at the last element, so that
interpolation is not omitted for points between the two last entries in
the table.

Then correct the formula to perform linear interpolation based the two
points surrounding the read ADC value. The indices for temp are kept as
"hi" and "lo" to pair with the adc indices, but there's no requirement
that the temperature is provided in descendent order. mult_frac() is
used to prevent issues with overflowing the int.

Cc: Laxman Dewangan &lt;ldewangan@nvidia.com&gt;
Signed-off-by: Bjorn Andersson &lt;bjorn.andersson@linaro.org&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Thermal: do not clear passive state during system sleep</title>
<updated>2019-02-12T18:44:53+00:00</updated>
<author>
<name>Wei Wang</name>
<email>wvw@google.com</email>
</author>
<published>2018-11-07T22:36:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=a61cdb8ebcee13ec0ce1c9ea4e274a2d44a3bdf2'/>
<id>a61cdb8ebcee13ec0ce1c9ea4e274a2d44a3bdf2</id>
<content type='text'>
[ Upstream commit 964f4843a455d2ffb199512b08be8d5f077c4cac ]

commit ff140fea847e ("Thermal: handle thermal zone device properly
during system sleep") added PM hook to call thermal zone reset during
sleep. However resetting thermal zone will also clear the passive state
and thus cancel the polling queue which leads the passive cooling device
state not being cleared properly after sleep.

thermal_pm_notify =&gt; thermal_zone_device_reset set passive to 0
thermal_zone_trip_update will skip update passive as `old_target ==
instance-&gt;target'.
monitor_thermal_zone =&gt; thermal_zone_device_set_polling will cancel
tz-&gt;poll_queue, so the cooling device state will not be changed
afterwards.

Reported-by: Kame Wang &lt;kamewang@google.com&gt;
Signed-off-by: Wei Wang &lt;wvw@google.com&gt;
Signed-off-by: Zhang Rui &lt;rui.zhang@intel.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 964f4843a455d2ffb199512b08be8d5f077c4cac ]

commit ff140fea847e ("Thermal: handle thermal zone device properly
during system sleep") added PM hook to call thermal zone reset during
sleep. However resetting thermal zone will also clear the passive state
and thus cancel the polling queue which leads the passive cooling device
state not being cleared properly after sleep.

thermal_pm_notify =&gt; thermal_zone_device_reset set passive to 0
thermal_zone_trip_update will skip update passive as `old_target ==
instance-&gt;target'.
monitor_thermal_zone =&gt; thermal_zone_device_set_polling will cancel
tz-&gt;poll_queue, so the cooling device state will not be changed
afterwards.

Reported-by: Kame Wang &lt;kamewang@google.com&gt;
Signed-off-by: Wei Wang &lt;wvw@google.com&gt;
Signed-off-by: Zhang Rui &lt;rui.zhang@intel.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>thermal: of-thermal: disable passive polling when thermal zone is disabled</title>
<updated>2018-10-04T00:01:51+00:00</updated>
<author>
<name>Anson Huang</name>
<email>Anson.Huang@nxp.com</email>
</author>
<published>2018-07-30T16:56:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=6ad98847580cd20ead2bec0d717d13a1fc846753'/>
<id>6ad98847580cd20ead2bec0d717d13a1fc846753</id>
<content type='text'>
[ Upstream commit 152395fd03d4ce1e535a75cdbf58105e50587611 ]

When thermal zone is in passive mode, disabling its mode from
sysfs is NOT taking effect at all, it is still polling the
temperature of the disabled thermal zone and handling all thermal
trips, it makes user confused. The disabling operation should
disable the thermal zone behavior completely, for both active and
passive mode, this patch clears the passive_delay when thermal
zone is disabled and restores it when it is enabled.

Signed-off-by: Anson Huang &lt;Anson.Huang@nxp.com&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Sasha Levin &lt;alexander.levin@microsoft.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 152395fd03d4ce1e535a75cdbf58105e50587611 ]

When thermal zone is in passive mode, disabling its mode from
sysfs is NOT taking effect at all, it is still polling the
temperature of the disabled thermal zone and handling all thermal
trips, it makes user confused. The disabling operation should
disable the thermal zone behavior completely, for both active and
passive mode, this patch clears the passive_delay when thermal
zone is disabled and restores it when it is enabled.

Signed-off-by: Anson Huang &lt;Anson.Huang@nxp.com&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Sasha Levin &lt;alexander.levin@microsoft.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>thermal: exynos: fix setting rising_threshold for Exynos5433</title>
<updated>2018-08-03T05:55:23+00:00</updated>
<author>
<name>Bartlomiej Zolnierkiewicz</name>
<email>b.zolnierkie@samsung.com</email>
</author>
<published>2018-04-26T11:51:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=3221a270e2c28cad0144421bd8a9a32c23d31e6c'/>
<id>3221a270e2c28cad0144421bd8a9a32c23d31e6c</id>
<content type='text'>
[ Upstream commit 8bfc218d0ebbabcba8ed2b8ec1831e0cf1f71629 ]

Add missing clearing of the previous value when setting rising
temperature threshold.

Signed-off-by: Bartlomiej Zolnierkiewicz &lt;b.zolnierkie@samsung.com&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Sasha Levin &lt;alexander.levin@microsoft.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 8bfc218d0ebbabcba8ed2b8ec1831e0cf1f71629 ]

Add missing clearing of the previous value when setting rising
temperature threshold.

Signed-off-by: Bartlomiej Zolnierkiewicz &lt;b.zolnierkie@samsung.com&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Sasha Levin &lt;alexander.levin@microsoft.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>thermal: exynos: Propagate error value from tmu_read()</title>
<updated>2018-05-16T08:08:44+00:00</updated>
<author>
<name>Marek Szyprowski</name>
<email>m.szyprowski@samsung.com</email>
</author>
<published>2018-04-16T10:11:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=5d1639dae65f6c8b1a71a84e11d29696b7915d34'/>
<id>5d1639dae65f6c8b1a71a84e11d29696b7915d34</id>
<content type='text'>
commit c8da6cdef57b459ac0fd5d9d348f8460a575ae90 upstream.

tmu_read() in case of Exynos4210 might return error for out of bound
values. Current code ignores such value, what leads to reporting critical
temperature value. Add proper error code propagation to exynos_get_temp()
function.

Signed-off-by: Marek Szyprowski &lt;m.szyprowski@samsung.com&gt;
CC: stable@vger.kernel.org # v4.6+
Signed-off-by: Bartlomiej Zolnierkiewicz &lt;b.zolnierkie@samsung.com&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit c8da6cdef57b459ac0fd5d9d348f8460a575ae90 upstream.

tmu_read() in case of Exynos4210 might return error for out of bound
values. Current code ignores such value, what leads to reporting critical
temperature value. Add proper error code propagation to exynos_get_temp()
function.

Signed-off-by: Marek Szyprowski &lt;m.szyprowski@samsung.com&gt;
CC: stable@vger.kernel.org # v4.6+
Signed-off-by: Bartlomiej Zolnierkiewicz &lt;b.zolnierkie@samsung.com&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
<entry>
<title>thermal: exynos: Reading temperature makes sense only when TMU is turned on</title>
<updated>2018-05-16T08:08:44+00:00</updated>
<author>
<name>Marek Szyprowski</name>
<email>m.szyprowski@samsung.com</email>
</author>
<published>2018-04-16T10:11:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=3cc96a4acf139c30ff5b4d0312fddaab082db699'/>
<id>3cc96a4acf139c30ff5b4d0312fddaab082db699</id>
<content type='text'>
commit 88fc6f73fddf64eb507b04f7b2bd01d7291db514 upstream.

When thermal sensor is not yet enabled, reading temperature might return
random value. This might even result in stopping system booting when such
temperature is higher than the critical value. Fix this by checking if TMU
has been actually enabled before reading the temperature.

This change fixes booting of Exynos4210-based board with TMU enabled (for
example Samsung Trats board), which was broken since v4.4 kernel release.

Signed-off-by: Marek Szyprowski &lt;m.szyprowski@samsung.com&gt;
Fixes: 9e4249b40340 ("thermal: exynos: Fix first temperature read after registering sensor")
CC: stable@vger.kernel.org # v4.6+
Signed-off-by: Bartlomiej Zolnierkiewicz &lt;b.zolnierkie@samsung.com&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 88fc6f73fddf64eb507b04f7b2bd01d7291db514 upstream.

When thermal sensor is not yet enabled, reading temperature might return
random value. This might even result in stopping system booting when such
temperature is higher than the critical value. Fix this by checking if TMU
has been actually enabled before reading the temperature.

This change fixes booting of Exynos4210-based board with TMU enabled (for
example Samsung Trats board), which was broken since v4.4 kernel release.

Signed-off-by: Marek Szyprowski &lt;m.szyprowski@samsung.com&gt;
Fixes: 9e4249b40340 ("thermal: exynos: Fix first temperature read after registering sensor")
CC: stable@vger.kernel.org # v4.6+
Signed-off-by: Bartlomiej Zolnierkiewicz &lt;b.zolnierkie@samsung.com&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
<entry>
<title>thermal: imx: Fix race condition in imx_thermal_probe()</title>
<updated>2018-04-24T07:34:14+00:00</updated>
<author>
<name>Mikhail Lappo</name>
<email>mikhail.lappo@esrlabs.com</email>
</author>
<published>2018-02-02T18:17:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=a84a584c08783919a0e138e1e15ee2c45cdc0751'/>
<id>a84a584c08783919a0e138e1e15ee2c45cdc0751</id>
<content type='text'>
commit cf1ba1d73a33944d8c1a75370a35434bf146b8a7 upstream.

When device boots with T &gt; T_trip_1 and requests interrupt,
the race condition takes place. The interrupt comes before
THERMAL_DEVICE_ENABLED is set. This leads to an attempt to
reading sensor value from irq and disabling the sensor, based on
the data-&gt;mode field, which expected to be THERMAL_DEVICE_ENABLED,
but still stays as THERMAL_DEVICE_DISABLED. Afher this issue
sensor is never re-enabled, as the driver state is wrong.

Fix this problem by setting the 'data' members prior to
requesting the interrupts.

Fixes: 37713a1e8e4c ("thermal: imx: implement thermal alarm interrupt handling")
Cc: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Mikhail Lappo &lt;mikhail.lappo@esrlabs.com&gt;
Signed-off-by: Fabio Estevam &lt;fabio.estevam@nxp.com&gt;
Reviewed-by: Philipp Zabel &lt;p.zabel@pengutronix.de&gt;
Acked-by: Dong Aisheng &lt;aisheng.dong@nxp.com&gt;
Signed-off-by: Zhang Rui &lt;rui.zhang@intel.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit cf1ba1d73a33944d8c1a75370a35434bf146b8a7 upstream.

When device boots with T &gt; T_trip_1 and requests interrupt,
the race condition takes place. The interrupt comes before
THERMAL_DEVICE_ENABLED is set. This leads to an attempt to
reading sensor value from irq and disabling the sensor, based on
the data-&gt;mode field, which expected to be THERMAL_DEVICE_ENABLED,
but still stays as THERMAL_DEVICE_DISABLED. Afher this issue
sensor is never re-enabled, as the driver state is wrong.

Fix this problem by setting the 'data' members prior to
requesting the interrupts.

Fixes: 37713a1e8e4c ("thermal: imx: implement thermal alarm interrupt handling")
Cc: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Mikhail Lappo &lt;mikhail.lappo@esrlabs.com&gt;
Signed-off-by: Fabio Estevam &lt;fabio.estevam@nxp.com&gt;
Reviewed-by: Philipp Zabel &lt;p.zabel@pengutronix.de&gt;
Acked-by: Dong Aisheng &lt;aisheng.dong@nxp.com&gt;
Signed-off-by: Zhang Rui &lt;rui.zhang@intel.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
</feed>
