Commit Graph

48 Commits

Author SHA1 Message Date
Dmitry Baryshkov a649136b17 PM: runtime: add devm_pm_clk_create helper
A typical code pattern for pm_clk_create() call is to call it in the
_probe function and to call pm_clk_destroy() both from _probe error path
and from _remove function. For some drivers the whole remove function
would consist of the call to pm_remove_disable().

Add helper function to replace this bolierplate piece of code. Calling
devm_pm_clk_create() removes the need for calling pm_clk_destroy() both
in the probe()'s error path and in the remove() function.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://lore.kernel.org/r/20210731195034.979084-3-dmitry.baryshkov@linaro.org
Acked-by: Rafael J. Wysocki <rafael@kernel.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2021-08-26 11:28:07 -07:00
Pierre-Louis Bossart 33b688e385 PM: clk: remove kernel-doc warning
Remove make W=1 warning:

drivers/base/power/clock_ops.c:148: warning: expecting prototype for
pm_clk_enable(). Prototype was for __pm_clk_enable() instead

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-04-07 19:21:09 +02:00
Nicolas Pitre 0bfa0820c2 PM: clk: make PM clock layer compatible with clocks that must sleep
The clock API splits its interface into sleepable ant atomic contexts:

 - clk_prepare/clk_unprepare for stuff that might sleep

 - clk_enable_clk_disable for anything that may be done in atomic context

The code handling runtime PM for clocks only calls clk_disable() on
suspend requests, and clk_enable on resume requests. This means that
runtime PM with clock providers that only have the prepare/unprepare
methods implemented is basically useless.

Many clock implementations can't accommodate atomic contexts. This is
often the case when communication with the clock happens through another
subsystem like I2C or SCMI.

Let's make the clock PM code useful with such clocks by safely invoking
clk_prepare/clk_unprepare upon resume/suspend requests. Of course, when
such clocks are registered with the PM layer then pm_runtime_irq_safe()
can't be used, and neither pm_runtime_suspend() nor pm_runtime_resume()
may be invoked in atomic context.

For clocks that do implement the enable and disable methods then
everything just works as before.

A note on sparse:
According to https://lwn.net/Articles/109066/ there are things
that sparse can't cope with. In particular, pm_clk_op_lock() and
pm_clk_op_unlock() may or may not lock/unlock psd->lock depending on
some runtime condition. To work around that we tell it the lock is
always untaken for the purpose of static analisys.

Thanks to Naresh Kamboju for reporting issues with the initial patch.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
Tested-by: Naresh Kamboju <naresh.kamboju@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-01-27 19:29:32 +01:00
Geert Uytterhoeven 338c993f9a PM / clk: Remove error message on out-of-memory condition
There is no need to print an error message if kstrdup() fails, as the
memory allocation core already takes care of that.

Note that commit 59d84ca8c4 ("PM / OPP / clk: Remove unnecessary
OOM message") already removed similar error messages, but this one was
forgotten.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2019-05-28 19:40:21 +02:00
Kefeng Wang 7e186d9de9 drivers: base: power: clock_ops: Use of_clk_get_parent_count()
Use of_clk_get_parent_count() instead of open coding.

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2019-05-28 19:38:47 +02:00
Greg Kroah-Hartman 5de363b66a drivers: base: power: add proper SPDX identifiers on files that did not have them.
There were a few files in the driver core power code that did not have
SPDX identifiers on them, so fix that up.  At the same time, remove the
"free form" text that specified the license of the file, as that is
impossible for any tool to properly parse.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-04-04 20:03:40 +02:00
Aditya Pakki 40619f7dd3 PM: clock_ops: fix missing clk_prepare() return value check
clk_prepare() can fail, so check its status and if it fails,
issue an error message and change the clock_entry_status to
PCE_STATUS_ERROR.

Signed-off-by: Aditya Pakki <pakki001@umn.edu>
[ rjw: Subject ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2019-01-18 11:47:07 +01:00
Dan Carpenter 5e2e2f9f76 PM / clk: signedness bug in of_pm_clk_add_clks()
"count" needs to be signed for the error handling to work.  I made "i"
signed as well so they match.

Fixes: 02113ba93e (PM / clk: Add support for obtaining clocks from device-tree)
Cc: 4.6+ <stable@vger.kernel.org> # 4.6+
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2018-08-24 11:52:34 +02:00
Jon Hunter 498b5fdd40 PM / clk: Add support for adding a specific clock from device-tree
Some drivers using the PM clocks framework need to add specific clocks
from device-tree using a name by calling the functions
of_clk_get_by_name() and then pm_clk_add_clk(). Rather than having
drivers call both functions, add a helper function of_pm_clk_add_clk()
that will call these functions so drivers can call a single function
to add a specific clock from device-tree.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-06-28 00:42:10 +02:00
Paul Gortmaker 29b968b2af PM / clk: export symbols for existing pm_clk_<...> API fcns
While trying to convert a DMA driver from bool to tristate, we
encountered the following:

ERROR: "pm_clk_add_clk" [drivers/dma/tegra210-adma.ko] undefined!
ERROR: "pm_clk_create" [drivers/dma/tegra210-adma.ko] undefined!
ERROR: "pm_clk_destroy" [drivers/dma/tegra210-adma.ko] undefined!
ERROR: "pm_clk_suspend" [drivers/dma/tegra210-adma.ko] undefined!
ERROR: "pm_clk_resume" [drivers/dma/tegra210-adma.ko] undefined!

Since in principle there is nothing preventing these functions
from being used in modular code as well as builtin, we add the
export of them.  We expand the scope to also include:

   pm_clk_add
   of_pm_clk_add_clks
   pm_clk_remove
   pm_clk_remove_clk
   pm_clk_init
   pm_clk_runtime_suspend
   pm_clk_runtime_resume
   pm_clk_add_notifier

...since these functions are also non-static and presumably form
part of the existing API used by other drivers that may become
modular in the future.

Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-06-15 01:42:15 +02:00
Colin Ian King 0b26985a7d PM / clk: ensure we don't allocate a -ve size of count clks
It is entirely possible for of_count_phandle_wit_args to
return a -ve error return value so we need to check for this
otherwise we end up allocating a negative number of clk objects.

Signed-off-by: Colin Ian King <colin.king@canonical.com>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-04-26 21:11:35 +02:00
Jon Hunter 02113ba93e PM / clk: Add support for obtaining clocks from device-tree
The PM clocks framework requires clients to pass either a con-id or a
valid clk pointer in order to add a clock to a device. Add a new
function of_pm_clk_add_clks() to allows device clocks to be retrieved
from device-tree and populated for a given device. Note that it is
not necessary to make the compilation of this new function dependent
upon CONFIG_OF because there are stubs functions for the device-tree
APIs used.

In order to handle errors encountered when adding clocks from
device-tree, add a function pm_clk_remove_clk() to remove any clocks
(using a pointer to the clk structure) that have been added
successfully before the error occurred.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-03-17 02:32:04 +01:00
Tomeu Vizoso 989561de9b PM / Domains: add setter for dev.pm_domain
Adds a function that sets the pointer to dev_pm_domain in struct device
and that warns if the device has already finished probing. The reason
why we want to enforce that is because in the general case that can
cause problems and also that we can simplify code quite a bit if we can
always assume that.

This patch also changes all current code that directly sets the
dev.pm_domain pointer.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-01-08 01:12:06 +01:00
Andy Shevchenko d35818a915 PM / clk: don't leave clocks enabled when driver not bound
There is a new notification BUS_NOTIFY_DRIVER_NOT_BOUND that is issued when
driver fails during binding. In such case pm_clk_notify(), when PM_CLK=n,
leaves clocks enabled. Undo operations that have been done in
BUS_NOTIFY_BIND_DRIVER case.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-01-08 01:08:27 +01:00
Linus Torvalds b44a3d2a85 Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver updates from Olof Johansson:
 "As we've enabled multiplatform kernels on ARM, and greatly done away
  with the contents under arch/arm/mach-*, there's still need for
  SoC-related drivers to go somewhere.

  Many of them go in through other driver trees, but we still have
  drivers/soc to hold some of the "doesn't fit anywhere" lowlevel code
  that might be shared between ARM and ARM64 (or just in general makes
  sense to not have under the architecture directory).

  This branch contains mostly such code:

   - Drivers for qualcomm SoCs for SMEM, SMD and SMD-RPM, used to
     communicate with power management blocks on these SoCs for use by
     clock, regulator and bus frequency drivers.

   - Allwinner Reduced Serial Bus driver, again used to communicate with
     PMICs.

   - Drivers for ARM's SCPI (System Control Processor).  Not to be
     confused with PSCI (Power State Coordination Interface).  SCPI is
     used to communicate with the assistant embedded cores doing power
     management, and we have yet to see how many of them will implement
     this for their hardware vs abstracting in other ways (or not at all
     like in the past).

   - To make confusion between SCPI and PSCI more likely, this release
     also includes an update of PSCI to interface version 1.0.

   - Rockchip support for power domains.

   - A driver to talk to the firmware on Raspberry Pi"

* tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (57 commits)
  soc: qcom: smd-rpm: Correct size of outgoing message
  bus: sunxi-rsb: Add driver for Allwinner Reduced Serial Bus
  bus: sunxi-rsb: Add Allwinner Reduced Serial Bus (RSB) controller bindings
  ARM: bcm2835: add mutual inclusion protection
  drivers: psci: make PSCI 1.0 functions initialization version dependent
  dt-bindings: Correct paths in Rockchip power domains binding document
  soc: rockchip: power-domain: don't try to print the clock name in error case
  soc: qcom/smem: add HWSPINLOCK dependency
  clk: berlin: add cpuclk
  ARM: berlin: dts: add CLKID_CPU for BG2Q
  ARM: bcm2835: Add the Raspberry Pi firmware driver
  soc: qcom: smem: Move RPM message ram out of smem DT node
  soc: qcom: smd-rpm: Correct the active vs sleep state flagging
  soc: qcom: smd: delete unneeded of_node_put
  firmware: qcom-scm: build for correct architecture level
  soc: qcom: smd: Correct SMEM items for upper channels
  qcom-scm: add missing prototype for qcom_scm_is_available()
  qcom-scm: fix endianess issue in __qcom_scm_is_call_available
  soc: qcom: smd: Reject send of too big packets
  soc: qcom: smd: Handle big endian CPUs
  ...
2015-11-10 15:00:03 -08:00
Geert Uytterhoeven a617561651 PM / clk: Fix broken build due to non-matching code and header #ifdefs
If an architecture's main Kconfig file doesn't include
kernel/power/Kconfig, but CONFIG_PM=y and HAVE_CLK=y (e.g. m68knommu
allmodconfig):

    drivers/base/power/clock_ops.c: In function ‘__pm_clk_add’:
    drivers/base/power/clock_ops.c:106: error: ‘struct pm_subsys_data’ has no member named ‘clock_list’
    drivers/base/power/clock_ops.c: At top level:
    drivers/base/power/clock_ops.c:120: error: redefinition of ‘pm_clk_add’
    include/linux/pm_clock.h:64: error: previous definition of ‘pm_clk_add’ was here
    drivers/base/power/clock_ops.c:135: error: redefinition of ‘pm_clk_add_clk’
    include/linux/pm_clock.h:69: error: previous definition of ‘pm_clk_add_clk’ was here
    drivers/base/power/clock_ops.c:171: error: redefinition of ‘pm_clk_remove’
    include/linux/pm_clock.h:73: error: previous definition of ‘pm_clk_remove’ was here
    drivers/base/power/clock_ops.c: In function ‘pm_clk_remove’:
    drivers/base/power/clock_ops.c:180: error: ‘struct pm_subsys_data’ has no member named ‘clock_list’
    drivers/base/power/clock_ops.c:180: error: ‘struct pm_subsys_data’ has no member named ‘clock_list’
    drivers/base/power/clock_ops.c: At top level:
    drivers/base/power/clock_ops.c:207: error: redefinition of ‘pm_clk_init’
    include/linux/pm_clock.h:54: error: previous definition of ‘pm_clk_init’ was here
    drivers/base/power/clock_ops.c: In function ‘pm_clk_init’:
    drivers/base/power/clock_ops.c:210: error: ‘struct pm_subsys_data’ has no member named ‘clock_list’
    drivers/base/power/clock_ops.c: At top level:
    drivers/base/power/clock_ops.c:221: error: redefinition of ‘pm_clk_create’
    include/linux/pm_clock.h:57: error: previous definition of ‘pm_clk_create’ was here
    drivers/base/power/clock_ops.c:234: error: redefinition of ‘pm_clk_destroy’
    include/linux/pm_clock.h:61: error: previous definition of ‘pm_clk_destroy’ was here
    drivers/base/power/clock_ops.c: In function ‘pm_clk_destroy’:
    drivers/base/power/clock_ops.c:246: error: ‘struct pm_subsys_data’ has no member named ‘clock_list’
    drivers/base/power/clock_ops.c:246: error: ‘struct pm_subsys_data’ has no member named ‘clock_list’
    drivers/base/power/clock_ops.c: At top level:
    drivers/base/power/clock_ops.c:263: error: expected identifier or ‘(’ before ‘void’
    drivers/base/power/clock_ops.c:263: error: expected ‘)’ before numeric constant
    drivers/base/power/clock_ops.c:293: error: expected identifier or ‘(’ before ‘void’
    drivers/base/power/clock_ops.c:293: error: expected ‘)’ before numeric constant
    drivers/base/power/clock_ops.c: In function ‘pm_clk_runtime_suspend’:
    drivers/base/power/clock_ops.c:384: error: called object ‘0u’ is not a function
    drivers/base/power/clock_ops.c: In function ‘pm_clk_runtime_resume’:
    drivers/base/power/clock_ops.c:400: error: called object ‘0u’ is not a function

This happens because:
  - drivers/base/power/clock_ops.c depends on CONFIG_HAVE_CLK,
  - the failing code inside clock_ops.c additionally depends on
    CONFIG_PM,
  - the forward declarations and other definitions in <linux/pm_clock.h>
    depend on CONFIG_PM_CLK,
  - CONFIG_PM_CLK is defined as PM && HAVE_CLK in kernel/power/Kconfig,
    but it is not included on all architectures.

Fix this by protecting the failing code inside clock_ops.c by
CONFIG_PM_CLK instead of CONFIG_PM, so it matches <linux/pm_clock.h>.

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-10-28 04:30:44 +01:00
Stephen Boyd 772b05086d PM / clk: Do not __clk_get passed in clock-references
Clock references are on a per-user basis now, so they are not supposed
to be refcounted by itself anymore. Therefore multiple cascaded get and
put calls will fail.

When a clock reference gets passed into pm_clk_add_clk we can assume
that the pm clock handling will take control of the clock reference,
so after this functions returns the caller should've given up control
of that handle.

So remove the additional call to __clk_get() in __pm_clk_add().

The only current user of pm_clk_add_clk is drivers/clk/shmobile/clk-mstp.c
which already follows this paradigm by only getting the clock but not
puting it after passing the reference into pm_clk_add_clk.

In the error case the caller is expected to clean up the clock, as it
may very well try to do something different if pm_clk_add_clk() fails.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
[add commit-message]
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-10-06 09:46:24 +02:00
Colin Ian King f4745a9278 PM / clk: don't return int on __pm_clk_enable()
Static analysis by cppcheck found an issue that was recently introduced by
commit 471f7707b6 ("PM / clock_ops: make __pm_clk_enable more generic")
where a return status in ret was not being initialised and garbage
being returned when ce->status >= PCE_STATUS_ERROR.

The fact that ret is not being checked by the caller and that
ret is only used internally __pm_clk_enable() to check if clk_enable()
was OK means we can ignore returning it instead turn
__pm_clk_enable() into function with a void return.

Fixes: 471f7707b6 ("PM / clock_ops: make __pm_clk_enable more generic")
Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-07-17 22:58:13 +02:00
Geert Uytterhoeven f17f4adfe4 PM / clk: Print acquired clock name in addition to con_id
Currently the con_id of the acquired clock is printed for debugging
purposes.  But in several cases, the con_id is NULL, which doesn't
provide much debugging information when printed.  These cases are:
  - When explicitly passing a NULL con_id (which means the first clock
    tied to the device, if available),
  - When not using pm_clk_add(), but pm_clk_add_clk() (which takes a
    "struct clk *" directly).

Hence print the actual clock name in addition to (and not instead of;
thanks Grygorii Strashko!) the con_id.

Note that the clock name is not available with legacy clock frameworks,
and the hex pointer address will be printed instead.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Grygorii Strashko <grygorii.strashko@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-06-15 22:38:40 +02:00
Geert Uytterhoeven 3fc3a0be0d PM / clk: Fix clock error check in __pm_clk_add()
In the final iteration of commit 245bd6f6af ("PM / clock_ops: Add
pm_clk_add_clk()"), a refcount increment was added by Grygorii Strashko.
However, the accompanying IS_ERR() check operates on the wrong clock
pointer, which is always zero at this point, i.e. not an error.
This may lead to a NULL pointer dereference later, when __clk_get()
tries to dereference an error pointer.

Check the passed clock pointer instead to fix this.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Fixes: 245bd6f6af ("PM / clock_ops: Add pm_clk_add_clk()")
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-19 15:13:19 +02:00
Rajendra Nayak 75f504004a PM / clock_ops: Provide default runtime ops to users
Most users of PM clocks do the extact same things in the runtime
suspend/resume callbacks. Provide them USE_PM_CLK_RUNTIME_OPS so
as to avoid/remove boilerplate code.

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Reviewed-by: Kevin Hilman <khilman@linaro.org>
Acked-by: Santosh Shilimkar <ssantosh@kernel.org>
Acked-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-12 23:55:37 +02:00
Quentin Lambert 59d84ca8c4 PM / OPP / clk: Remove unnecessary OOM message
This patch reduces the kernel size by removing error messages that duplicate
the normal OOM message.

A simplified version of the semantic patch that finds this problem is as
follows: (http://coccinelle.lip6.fr)

@@
identifier f,print,l;
expression e;
constant char[] c;
@@

e = \(kzalloc\|kmalloc\|devm_kzalloc\|devm_kmalloc\)(...);
if (e == NULL) {
  <+...
-  print(...,c,...);
  ... when any
(
  goto l;
|
  return ...;
)
  ...+> }

Signed-off-by: Quentin Lambert <lambert.quentin@gmail.com>
Acked-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-12 02:00:52 +01:00
Rafael J. Wysocki d30d819dc8 PM: Drop CONFIG_PM_RUNTIME from the driver core
After commit b2b49ccbdd (PM: Kconfig: Set PM_RUNTIME if PM_SLEEP is
selected) PM_RUNTIME is always set if PM is set, so quite a few
depend on CONFIG_PM or even may be dropped entirely in some cases.

Replace CONFIG_PM_RUNTIME with CONFIG_PM in the PM core code.

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Kevin Hilman <khilman@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-12-04 00:46:58 +01:00
Strashko, Grygorii 471f7707b6 PM / clock_ops: make __pm_clk_enable more generic
Now there are two places in code which do the same things,
so allow __pm_clk_enable() to accept pointer on pm_clock_entry
structure as second parameter instead of pointer on clock and
remove duplicated code.

Also, updated function intended to be used by following patch.

Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-11-07 01:47:48 +01:00
Geert Uytterhoeven 245bd6f6af PM / clock_ops: Add pm_clk_add_clk()
The existing pm_clk_add() allows to pass a clock by con_id. However,
when referring to a specific clock from DT, no con_id is available.

Add pm_clk_add_clk(), which allows to specify the struct clk * directly.
The will will increment refcount on clock pointer, so the caller has
to use clk_put() on clock pointer when done.

Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Reviewed-by: Kevin Hilman <khilman@linaro.org>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-11-07 01:46:51 +01:00