Commit Graph

94 Commits

Author SHA1 Message Date
Eduardo Valentin 50e66c7ed8 drivers: thermal: add check when unregistering cpu cooling
This patch avoids NULL pointer accesses while unregistering
cpu cooling devices, in case a NULL pointer is received.

Cc: Zhang Rui <rui.zhang@intel.com>
Cc: linux-pm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
2013-09-03 09:10:34 -04:00
Lan Tianyu 044d5c26da Thermal/cpu_cooling: Return directly for the cpu out of allowed_cpus in the cpufreq_thermal_notifier()
cpufreq_thermal_notifier() is to change the cpu's cpufreq in the allowed_cpus mask
when associated thermal-cpufreq cdev's cooling state is changed. It's a cpufreq policy
notifier handler and it will be triggered even if those cpus out of allowed_cpus has
changed freq policy.

cpufreq_thermal_notifier() checks the policy->cpu. If it belongs to allowed_cpus,
change max_freq(default to 0) to the desire cpufreq value and pass 0 and max_freq
to cpufreq_verify_within_limits() as cpufreq scope. But if not, do nothing and
max_freq will remain 0. This will cause the cpufreq scope to become 0~0. This
is not right. This patch is to return directly after finding cpu not belonging
to allowed_cpus.

Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-08-15 15:25:08 +08:00
Shawn Guo 24c7a38172 thermal: cpu_cooling: fix 'descend' check in get_property()
The variable 'descend' is initialized as -1 in function get_property(),
and will never get any chance to be updated by the following code.

	if (freq != CPUFREQ_ENTRY_INVALID && descend != -1)
		descend = !!(freq > table[i].frequency);

This makes function get_property() return the wrong frequency for given
cooling level if the frequency table is sorted in ascending.  Fix it
by correcting the 'descend' check in if-condition to 'descend == -1'.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-05-28 14:49:31 +08:00
Eduardo Valentin 5fda7f680a thermal: cpu_cooling: alignment improvements
Improve code readiness by changing alignments so that
they match open parenthesis, like checkpatch.pl --strict
suggests.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-27 09:25:55 +08:00
Eduardo Valentin ef5e2124ec thermal: cpu_cooling: remove checkpatch.pl warning
Simple code style fix.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-27 09:25:51 +08:00
Eduardo Valentin e45a643002 thermal: cpu_cooling: remove trailing blank line
Remove unnecessary blank line.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-27 09:25:47 +08:00
Eduardo Valentin d8892a01b1 thermal: cpu_cooling: align on open parenthesis
Improve code readiness by remove checkpatch.pl warnings
on get_property function.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-27 09:25:43 +08:00
Eduardo Valentin 1b9e352659 thermal: cpu_cooling: standardize comment style
There are at least three patterns for oneline comments in this
file. This patch changes them to one single pattern

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-27 09:25:38 +08:00
Eduardo Valentin 79491e53dc thermal: cpu_cooling: standardize end of function
Just for code readiness, this patch makes all functions
on this file to have a blank line before their returns.
Now, some functions follow this pattern, and others will
not have a blank line. So, this patch makes it a single
pattern.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-27 09:25:32 +08:00
Eduardo Valentin 79d264016a thermal: cpu_cooling: remove trailing white spaces
Remove unnecessary white spaces.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-27 09:25:24 +08:00
Eduardo Valentin 67d0b2a826 thermal: cpu_cooling: remove unused symbols
The list is not needed so far. Thus removing it.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:44 +08:00
Eduardo Valentin 2d9bf71c12 thermal: cpu_cooling: remove not needed curl brackets
Just for style purposes, remove extra curl brackets.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:43 +08:00
Eduardo Valentin 99871a714b thermal: cpu_cooling: use snprintf instead of sprintf
Limit the amount of bytes written to dev_name by
secure writing with snprintf.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:43 +08:00
Eduardo Valentin 135266b4ea thermal: cpu_cooling: update kernel-doc comment for cpufreq_cooling_unregister
Update comments for this exported function.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:42 +08:00
Eduardo Valentin 12cb08ba50 thermal: cpu_cooling: update kernel-doc for cpufreq_cooling_register
Add proper documentation for exported function cpufreq_cooling_register.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:42 +08:00
Eduardo Valentin 56e05fdb6d thermal: cpu_cooling: update documentation for cpufreq_set_cur_state
Update documentation for cpufreq_set_cur_state callback.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:42 +08:00
Eduardo Valentin 3672552dc0 thermal: cpu_cooling: update documentation for cpufreq_get_cur_state
Update documentation for cpufreq_get_cur_state callback.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:41 +08:00
Eduardo Valentin 62c00421b3 thermal: cpu_cooling: update documentation for cpufreq_get_max_state
Update documentation for cpufreq_get_max_state callback.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:41 +08:00
Eduardo Valentin bab3055472 thermal: cpu_cooling: update documentation for cpufreq_thermal_notifier
Update kernel-doc comment and documentation for cpufreq_thermal_notifier.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:40 +08:00
Eduardo Valentin 4b33deb547 thermal: cpu_cooling: update documentation for cpufreq_apply_cooling
Update kernel-doc comments for cpufreq_apply_cooling function.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:39 +08:00
Eduardo Valentin 41518c41dd thermal: cpu_cooling: improve documentation for get_cpu_frequency
Fix kernel-doc warning on get_cpu_frequency and improve
documentation comments.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:39 +08:00
Eduardo Valentin 44952d338a thermal: cpu_cooling: document cpufreq_get_cooling_level
Add documentation for cpufreq_get_cooling_level. As this
is an exported function, it has to be documented.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:38 +08:00
Eduardo Valentin 2d6f28fedc thermal: cpu_cooling: add documentation for get_property
As this is one of the central functions of this file,
it deserves a proper documentation. This patch improves
the existing comment to format it as a kernel-doc style.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:38 +08:00
Eduardo Valentin 82b9ee402f thermal: cpu_cooling: fix kernel doc for is_cpufreq_valid
Update documentation for is_cpufreq_valid function so
that kernel-doc does not complain about return value.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:38 +08:00
Eduardo Valentin 4469b99743 thermal: cpu_cooling: remove compiler warning
level will be used only if GET_FREQ mode is requested.
There is no potential harm with current code. But for
cleaning the compilation log, this patch initializes
level to zero.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:37 +08:00
Eduardo Valentin 243dbd9c60 thermal: cpu_cooling: use EXPORT_SYMBOL_GPL
Restrict the usage to GPL modules.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:37 +08:00
Eduardo Valentin 3b3c074855 thermal: cpu_cooling: fix kernel_doc for cpufreq_cooling_device
Simple fixes for making kernel_doc happy about
struct cpufreq_cooling_device. Includes also a minor
spelling fix.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:34:36 +08:00
Eduardo Valentin 25c52afe1c thermal: cpu_cooling: remove unused headers
Remove some unused header files.

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-25 00:33:58 +08:00
Dan Carpenter 4f89038f17 Thermal: cpufreq cooling: endian bug in cpufreq_get_max_state()
This code doesn't work on big endian systems because we're storing low
values in the high bits of the unsigned long.  It makes it a very high
value instead.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-04-17 23:43:31 +08:00
Zhang Rui d13cb03aef Merge branch 'thermal' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux into next
Conflicts:
	drivers/thermal/cpu_cooling.c
2013-04-15 09:26:58 +08:00
Laurent Navet [Mali] bde0066309 drivers: thermal: cpu_cooling: fix checkpatch warning
- WARNING: Avoid CamelCase: <maskPtr>

Signed-off-by: Laurent Navet <laurent.navet@gmail.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-03-26 17:26:19 +08:00
Zhang Rui 57df810693 Thermal: exynos: fix cooling state translation
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Tested-by: Amit Daniel kachhap <amit.daniel@samsung.com>
2013-03-26 14:33:50 +08:00
Zhang Rui fc35b35cbe Thermal: cpufreq cooling: fix parsing per_cpu cpufreq_frequency_table
cpufreq cooling uses different frequencies as different cooling states.

But the per_cpu cpufreq_frequency_table may contain duplicate,
invalid entries, and it may be in either ascending or descending order.
And currently, code for parsing the per_cpu cpufreq_frequency_table
is used in several places and inconsistent.

Now introduce new code to
1. get the maximum cooling states
2. translate cooling state to cpu frequency
3. translate cpu frequency to cooling state
in one place,
with the correct logic of handling per_cpu cpufreq_frequency_table.

Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Tested-by: Amit Daniel kachhap <amit.daniel@samsung.com>
2013-03-26 14:33:43 +08:00
Linus Torvalds 2af78448ff Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
Pull thermal management updates from Zhang Rui:
 "Highlights:

   - introduction of Dove thermal sensor driver.

   - introduction of Kirkwood thermal sensor driver.

   - introduction of intel_powerclamp thermal cooling device driver.

   - add interrupt and DT support for rcar thermal driver.

   - add thermal emulation support which allows platform thermal driver
     to do software/hardware emulation for thermal issues."

* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux: (36 commits)
  thermal: rcar: remove __devinitconst
  thermal: return an error on failure to register thermal class
  Thermal: rename thermal governor Kconfig option to avoid generic naming
  thermal: exynos: Use the new thermal trend type for quick cooling action.
  Thermal: exynos: Add support for temperature falling interrupt.
  Thermal: Dove: Add Themal sensor support for Dove.
  thermal: Add support for the thermal sensor on Kirkwood SoCs
  thermal: rcar: add Device Tree support
  thermal: rcar: remove machine_power_off() from rcar_thermal_notify()
  thermal: rcar: add interrupt support
  thermal: rcar: add read/write functions for common/priv data
  thermal: rcar: multi channel support
  thermal: rcar: use mutex lock instead of spin lock
  thermal: rcar: enable CPCTL to use hardware TSC deciding
  thermal: rcar: use parenthesis on macro
  Thermal: fix a build warning when CONFIG_THERMAL_EMULATION cleared
  Thermal: fix a wrong comment
  thermal: sysfs: Add a new sysfs node emul_temp for thermal emulation
  PM: intel_powerclamp: off by one in start_power_clamp()
  thermal: exynos: Miscellaneous fixes to support falling threshold interrupt
  ...
2013-02-28 19:48:26 -08:00
Tejun Heo 6deb69face thermal: convert to idr_alloc()
Convert to the much saner new idr interface.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-27 19:10:19 -08:00
Zhang Rui 475f41c3ab Thermal: fix a wrong comment
"level" parameter of get_cpu_frequency equals cooling state
of cpu cooling device, and it starts from 0.

Fix the misleading comment.

Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2013-02-06 14:13:56 +08:00
Eduardo Valentin 3778ff5c70 thermal: cpu cooling: use const parameter while registering
There are predefined cpu_masks that are const data structures.
This patch changes the cpu cooling register function so that
those const cpu_masks can be used, without compilation warnings.

include/linux/cpumask.h

 * The following particular system cpumasks and operations manage
 * possible, present, active and online cpus.
 *
 *     cpu_possible_mask- has bit 'cpu' set iff cpu is populatable
 *     cpu_present_mask - has bit 'cpu' set iff cpu is populated
 *     cpu_online_mask  - has bit 'cpu' set iff cpu available to scheduler
 *     cpu_active_mask  - has bit 'cpu' set iff cpu available to migration
 *

Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2012-11-22 15:59:47 +08:00
Sachin Kamat a0f846c23c thermal: cpu_cooling: Make 'notify_device' static
Silences the following sparse warning:

drivers/thermal/cpu_cooling.c:67:31: warning:
symbol 'notify_device' was not declared. Should it be static?

Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2012-11-15 16:48:40 +08:00
hongbo.zhang 160b7d8048 Thermal: Remove the cooling_cpufreq_list.
Problem of using this list is that the cpufreq_get_max_state callback will be
called when register cooling device by thermal_cooling_device_register, but
this list isn't ready at this moment. What's more, there is no need to maintain
such a list, we can get cpufreq_cooling_device instance by the private
thermal_cooling_device.devdata.

Signed-off-by: hongbo.zhang <hongbo.zhang@linaro.com>
Reviewed-by: Francesco Lavra <francescolavra.fl@gmail.com>
Reviewed-by: Amit Daniel Kachhap <amit.kachhap@linaro.org>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2012-11-07 14:52:27 +08:00
hongbo.zhang 9c51b05a78 Thermal: fix bug of counting cpu frequencies.
In the while loop for counting cpu frequencies, if table[i].frequency equals
CPUFREQ_ENTRY_INVALID, index i won't be increased, so this leads to an endless
loop, what's more the index i cannot be referred as cpu frequencies number if
there is CPUFREQ_ENTRY_INVALID case.

Signed-off-by: hongbo.zhang <hongbo.zhang@linaro.com>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Amit Daniel Kachhap <amit.kachhap@linaro.org>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2012-11-07 14:49:43 +08:00
hongbo.zhang 6b6519df84 Thermal: add indent for code alignment.
The curly bracket should be aligned with corresponding if else statements.

Signed-off-by: hongbo.zhang <hongbo.zhang@linaro.com>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2012-11-07 14:49:25 +08:00
Len Brown 29b19e2504 Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux into thermal
Conflicts:
	drivers/staging/omap-thermal/omap-thermal-common.
		OMAP supplied dummy TC1 and TC2,
		at the same time that the thermal tree removed them
		from thermal_zone_device_register()

	drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
		propogate the upstream MAX_IDR_LEVEL re-name
			to prevent a build failure

	Previously-fixed-by: Stephen Rothwell <sfr@canb.auug.org.au>

Signed-off-by: Len Brown <len.brown@intel.com>
2012-10-09 01:35:52 -04:00
Jonghwa Lee a4b6fec977 Thermal: Fix bug on cpu_cooling, cooling device's id conflict problem.
This patch fixes small bug on cpu_cooling. CPU cooling device has own
id generated with idr mathod. However in the previous version, it swapped
to all same id at last stage of probing as 0. This makes id's collision and
also occures error when it releases that id.

Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
2012-09-27 14:11:22 +08:00
Amit Daniel Kachhap 0236141837 thermal: add generic cpufreq cooling implementation
This patchset introduces a new generic cooling device based on cpufreq
that can be used on non-ACPI platforms.  As a proof of concept, we have
drivers for the following platforms using this mechanism now:

 * Samsung Exynos (Exynos4 and Exynos5) in the current patchset.
 * Freescale i.MX (git://git.linaro.org/people/amitdanielk/linux.git imx6q_thermal)

There is a small change in cpufreq cooling registration APIs, so a minor
change is needed for Freescale platforms.

Brief Description:

1) The generic cooling devices code is placed inside driver/thermal/*
   as placing inside acpi folder will need un-necessary enabling of acpi
   code.  This code is architecture independent.

2) This patchset adds generic cpu cooling low level implementation
   through frequency clipping.  In future, other cpu related cooling
   devices may be added here.  An ACPI version of this already exists
   (drivers/acpi/processor_thermal.c) .But this will be useful for
   platforms like ARM using the generic thermal interface along with the
   generic cpu cooling devices.  The cooling device registration API's
   return cooling device pointers which can be easily binded with the
   thermal zone trip points.  The important APIs exposed are,

   a) struct thermal_cooling_device *cpufreq_cooling_register(
        struct cpumask *clip_cpus)
   b) void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)

3) Samsung exynos platform thermal implementation is done using the
   generic cpu cooling APIs and the new trip type.  The temperature sensor
   driver present in the hwmon folder(registered as hwmon driver) is moved
   to thermal folder and registered as a thermal driver.

A simple data/control flow diagrams is shown below,

Core Linux thermal <----->  Exynos thermal interface <----- Temperature Sensor
          |                             |
         \|/                            |
  Cpufreq cooling device <---------------

TODO:
*Will send the DT enablement patches later after the driver is merged.

This patch:

Add support for generic cpu thermal cooling low level implementations
using frequency scaling up/down based on the registration parameters.
Different cpu related cooling devices can be registered by the user and
the binding of these cooling devices to the corresponding trip points can
be easily done as the registration APIs return the cooling device pointer.
The user of these APIs are responsible for passing clipping frequency .
The drivers can also register to recieve notification about any cooling
action called.

[akpm@linux-foundation.org: fix comment layout]
Signed-off-by: Amit Daniel Kachhap <amit.kachhap@linaro.org>
Cc: Guenter Roeck <guenter.roeck@ericsson.com>
Cc: SangWook Ju <sw.ju@samsung.com>
Cc: Durgadoss <durgadoss.r@intel.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: Kyungmin Park <kmpark@infradead.org>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2012-09-24 14:44:38 +08:00