* [PATCH 2/4] clocksource: stm32: use prescaler to adjust the resolution
From: Benjamin Gaignard @ 2017-12-15 8:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215085247.14946-1-benjamin.gaignard@st.com>
Rather than use fixed prescaler values compute it to get a clock
as close as possible of 10KHz and a resolution of 0.1ms.
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
---
drivers/clocksource/timer-stm32.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c
index 23a321cca45b..de721d318065 100644
--- a/drivers/clocksource/timer-stm32.c
+++ b/drivers/clocksource/timer-stm32.c
@@ -37,6 +37,11 @@
#define TIM_EGR_UG BIT(0)
+#define MAX_TIM_PSC 0xFFFF
+
+/* Target a 10KHz clock to get a resolution of 0.1 ms */
+#define TARGETED_CLK_RATE 10000
+
static int stm32_clock_event_shutdown(struct clock_event_device *evt)
{
struct timer_of *to = to_timer_of(evt);
@@ -83,7 +88,7 @@ static irqreturn_t stm32_clock_event_handler(int irq, void *dev_id)
static void __init stm32_clockevent_init(struct timer_of *to)
{
unsigned long max_delta;
- int prescaler;
+ unsigned long prescaler;
to->clkevt.name = "stm32_clockevent";
to->clkevt.features = CLOCK_EVT_FEAT_PERIODIC;
@@ -96,13 +101,17 @@ static void __init stm32_clockevent_init(struct timer_of *to)
/* Detect whether the timer is 16 or 32 bits */
writel_relaxed(~0U, timer_of_base(to) + TIM_ARR);
max_delta = readl_relaxed(timer_of_base(to) + TIM_ARR);
- if (max_delta == ~0U) {
- prescaler = 1;
+ to->clkevt.rating = 50;
+ if (max_delta == ~0U)
to->clkevt.rating = 250;
- } else {
- prescaler = 1024;
- to->clkevt.rating = 50;
- }
+
+ /*
+ * Get the highest possible prescaler value to be as close
+ * as possible of TARGETED_CLK_RATE
+ */
+ prescaler = DIV_ROUND_CLOSEST(timer_of_rate(to), TARGETED_CLK_RATE);
+ if (prescaler > MAX_TIM_PSC)
+ prescaler = MAX_TIM_PSC;
writel_relaxed(0, timer_of_base(to) + TIM_ARR);
writel_relaxed(prescaler - 1, timer_of_base(to) + TIM_PSC);
--
2.15.0
^ permalink raw reply related
* [PATCH 1/4] clocksource: stm32: convert driver to timer_of
From: Benjamin Gaignard @ 2017-12-15 8:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215085247.14946-1-benjamin.gaignard@st.com>
Convert driver to use timer_of helpers. This allow to remove
custom proprietary structure.
Given counter number of bits (16 or 32) set a different
prescaler value and adjust timer_of rate, period and rating.
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
---
drivers/clocksource/Kconfig | 1 +
drivers/clocksource/timer-stm32.c | 179 +++++++++++++++-----------------------
2 files changed, 72 insertions(+), 108 deletions(-)
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index c729a88007d0..28bc55951512 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -269,6 +269,7 @@ config CLKSRC_STM32
bool "Clocksource for STM32 SoCs" if !ARCH_STM32
depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST)
select CLKSRC_MMIO
+ select TIMER_OF
config CLKSRC_MPS2
bool "Clocksource for MPS2 SoCs" if COMPILE_TEST
diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c
index 8f2423789ba9..23a321cca45b 100644
--- a/drivers/clocksource/timer-stm32.c
+++ b/drivers/clocksource/timer-stm32.c
@@ -16,6 +16,9 @@
#include <linux/of_irq.h>
#include <linux/clk.h>
#include <linux/reset.h>
+#include <linux/slab.h>
+
+#include "timer-of.h"
#define TIM_CR1 0x00
#define TIM_DIER 0x0c
@@ -34,157 +37,117 @@
#define TIM_EGR_UG BIT(0)
-struct stm32_clock_event_ddata {
- struct clock_event_device evtdev;
- unsigned periodic_top;
- void __iomem *base;
-};
-
-static int stm32_clock_event_shutdown(struct clock_event_device *evtdev)
+static int stm32_clock_event_shutdown(struct clock_event_device *evt)
{
- struct stm32_clock_event_ddata *data =
- container_of(evtdev, struct stm32_clock_event_ddata, evtdev);
- void *base = data->base;
+ struct timer_of *to = to_timer_of(evt);
+
+ writel_relaxed(0, timer_of_base(to) + TIM_CR1);
- writel_relaxed(0, base + TIM_CR1);
return 0;
}
-static int stm32_clock_event_set_periodic(struct clock_event_device *evtdev)
+static int stm32_clock_event_set_periodic(struct clock_event_device *evt)
{
- struct stm32_clock_event_ddata *data =
- container_of(evtdev, struct stm32_clock_event_ddata, evtdev);
- void *base = data->base;
+ struct timer_of *to = to_timer_of(evt);
+
+ writel_relaxed(timer_of_period(to), timer_of_base(to) + TIM_ARR);
+ writel_relaxed(TIM_CR1_ARPE | TIM_CR1_CEN, timer_of_base(to) + TIM_CR1);
- writel_relaxed(data->periodic_top, base + TIM_ARR);
- writel_relaxed(TIM_CR1_ARPE | TIM_CR1_CEN, base + TIM_CR1);
return 0;
}
static int stm32_clock_event_set_next_event(unsigned long evt,
- struct clock_event_device *evtdev)
+ struct clock_event_device *clkevt)
{
- struct stm32_clock_event_ddata *data =
- container_of(evtdev, struct stm32_clock_event_ddata, evtdev);
+ struct timer_of *to = to_timer_of(clkevt);
- writel_relaxed(evt, data->base + TIM_ARR);
+ writel_relaxed(evt, timer_of_base(to) + TIM_ARR);
writel_relaxed(TIM_CR1_ARPE | TIM_CR1_OPM | TIM_CR1_CEN,
- data->base + TIM_CR1);
+ timer_of_base(to) + TIM_CR1);
return 0;
}
static irqreturn_t stm32_clock_event_handler(int irq, void *dev_id)
{
- struct stm32_clock_event_ddata *data = dev_id;
+ struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+ struct timer_of *to = to_timer_of(evt);
- writel_relaxed(0, data->base + TIM_SR);
+ writel_relaxed(0, timer_of_base(to) + TIM_SR);
- data->evtdev.event_handler(&data->evtdev);
+ evt->event_handler(evt);
return IRQ_HANDLED;
}
-static struct stm32_clock_event_ddata clock_event_ddata = {
- .evtdev = {
- .name = "stm32 clockevent",
- .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
- .set_state_shutdown = stm32_clock_event_shutdown,
- .set_state_periodic = stm32_clock_event_set_periodic,
- .set_state_oneshot = stm32_clock_event_shutdown,
- .tick_resume = stm32_clock_event_shutdown,
- .set_next_event = stm32_clock_event_set_next_event,
- .rating = 200,
- },
-};
-
-static int __init stm32_clockevent_init(struct device_node *np)
+static void __init stm32_clockevent_init(struct timer_of *to)
{
- struct stm32_clock_event_ddata *data = &clock_event_ddata;
- struct clk *clk;
- struct reset_control *rstc;
- unsigned long rate, max_delta;
- int irq, ret, bits, prescaler = 1;
-
- clk = of_clk_get(np, 0);
- if (IS_ERR(clk)) {
- ret = PTR_ERR(clk);
- pr_err("failed to get clock for clockevent (%d)\n", ret);
- goto err_clk_get;
- }
-
- ret = clk_prepare_enable(clk);
- if (ret) {
- pr_err("failed to enable timer clock for clockevent (%d)\n",
- ret);
- goto err_clk_enable;
- }
+ unsigned long max_delta;
+ int prescaler;
- rate = clk_get_rate(clk);
-
- rstc = of_reset_control_get(np, NULL);
- if (!IS_ERR(rstc)) {
- reset_control_assert(rstc);
- reset_control_deassert(rstc);
- }
-
- data->base = of_iomap(np, 0);
- if (!data->base) {
- ret = -ENXIO;
- pr_err("failed to map registers for clockevent\n");
- goto err_iomap;
- }
-
- irq = irq_of_parse_and_map(np, 0);
- if (!irq) {
- ret = -EINVAL;
- pr_err("%pOF: failed to get irq.\n", np);
- goto err_get_irq;
- }
+ to->clkevt.name = "stm32_clockevent";
+ to->clkevt.features = CLOCK_EVT_FEAT_PERIODIC;
+ to->clkevt.set_state_shutdown = stm32_clock_event_shutdown;
+ to->clkevt.set_state_periodic = stm32_clock_event_set_periodic;
+ to->clkevt.set_state_oneshot = stm32_clock_event_shutdown;
+ to->clkevt.tick_resume = stm32_clock_event_shutdown;
+ to->clkevt.set_next_event = stm32_clock_event_set_next_event;
/* Detect whether the timer is 16 or 32 bits */
- writel_relaxed(~0U, data->base + TIM_ARR);
- max_delta = readl_relaxed(data->base + TIM_ARR);
+ writel_relaxed(~0U, timer_of_base(to) + TIM_ARR);
+ max_delta = readl_relaxed(timer_of_base(to) + TIM_ARR);
if (max_delta == ~0U) {
prescaler = 1;
- bits = 32;
+ to->clkevt.rating = 250;
} else {
prescaler = 1024;
- bits = 16;
+ to->clkevt.rating = 50;
}
- writel_relaxed(0, data->base + TIM_ARR);
- writel_relaxed(prescaler - 1, data->base + TIM_PSC);
- writel_relaxed(TIM_EGR_UG, data->base + TIM_EGR);
- writel_relaxed(TIM_DIER_UIE, data->base + TIM_DIER);
- writel_relaxed(0, data->base + TIM_SR);
+ writel_relaxed(0, timer_of_base(to) + TIM_ARR);
+ writel_relaxed(prescaler - 1, timer_of_base(to) + TIM_PSC);
+ writel_relaxed(TIM_EGR_UG, timer_of_base(to) + TIM_EGR);
+ writel_relaxed(TIM_DIER_UIE, timer_of_base(to) + TIM_DIER);
+ writel_relaxed(0, timer_of_base(to) + TIM_SR);
+
+ /* adjust rate and period given the prescaler value */
+ to->of_clk.rate = DIV_ROUND_CLOSEST(to->of_clk.rate, prescaler);
+ to->of_clk.period = DIV_ROUND_UP(to->of_clk.rate, HZ);
+
+ clockevents_config_and_register(&to->clkevt,
+ timer_of_rate(to), 0x1, max_delta);
+}
+
+static int __init stm32_timer_init(struct device_node *node)
+{
+ struct reset_control *rstc;
+ struct timer_of *to;
+ int ret;
+
+ to = kzalloc(sizeof(*to), GFP_KERNEL);
+ if (!to)
+ return -ENOMEM;
- data->periodic_top = DIV_ROUND_CLOSEST(rate, prescaler * HZ);
+ to->flags = TIMER_OF_IRQ | TIMER_OF_CLOCK | TIMER_OF_BASE;
+ to->of_irq.handler = stm32_clock_event_handler;
- clockevents_config_and_register(&data->evtdev,
- DIV_ROUND_CLOSEST(rate, prescaler),
- 0x1, max_delta);
+ ret = timer_of_init(node, to);
+ if (ret)
+ goto err;
- ret = request_irq(irq, stm32_clock_event_handler, IRQF_TIMER,
- "stm32 clockevent", data);
- if (ret) {
- pr_err("%pOF: failed to request irq.\n", np);
- goto err_get_irq;
+ rstc = of_reset_control_get(node, NULL);
+ if (!IS_ERR(rstc)) {
+ reset_control_assert(rstc);
+ reset_control_deassert(rstc);
}
- pr_info("%pOF: STM32 clockevent driver initialized (%d bits)\n",
- np, bits);
+ stm32_clockevent_init(to);
- return ret;
+ return 0;
-err_get_irq:
- iounmap(data->base);
-err_iomap:
- clk_disable_unprepare(clk);
-err_clk_enable:
- clk_put(clk);
-err_clk_get:
+err:
+ kfree(to);
return ret;
}
-TIMER_OF_DECLARE(stm32, "st,stm32-timer", stm32_clockevent_init);
+TIMER_OF_DECLARE(stm32, "st,stm32-timer", stm32_timer_init);
--
2.15.0
^ permalink raw reply related
* [PATCH 0/4] stm32 clocksource driver rework
From: Benjamin Gaignard @ 2017-12-15 8:52 UTC (permalink / raw)
To: linux-arm-kernel
version 10:
- do not remove 16 bits timer support
- use prescaler to get a 10KHz clock
version 9:
- rebased on timer/master where timer_of_cleanup() exist
- fix the comments done by Daniel on v8
- reword commits message to be more explicit about 16 bits counter issue
- add one patch about copyrights and licences
version 8:
- rebased on timers/core
- change timer_of_exit() name to timer_of_cleanup()
- update stm32 clocksource driver to use this function
version 7:
- reword "clocksource: stm32: only use 32 bits timers" commit message
to give more details about why 16 bits are problematics.
version 6:
- add dedicated patch min delta change
- rework commit messages, I hope it will be better now
- change new function name from timer_of_deinit to timer_of_exit
- make stm32_clock_event_set_next_event() safer like done in other
drivers
version 6:
- add timer_of_deinit function in core
- rework failure cases in probe function
version 5:
- rebase on top of timer/core branch
- rework commit message of the first patch
version 4:
- split patch in 3 parts
- convert code to timer_of
- only use 32 bits timers
- add clocksource support
version 3:
- fix comments done by Daniel
- use timer_of helper functions
version 2:
- fix uninitialized variable
Benjamin Gaignard (4):
clocksource: stm32: convert driver to timer_of
clocksource: stm32: use prescaler to adjust the resolution
clocksource: stm32: add clocksource support
clocksource: stm32: Update license and copyright
drivers/clocksource/Kconfig | 1 +
drivers/clocksource/timer-stm32.c | 258 +++++++++++++++++++++-----------------
2 files changed, 146 insertions(+), 113 deletions(-)
--
2.15.0
^ permalink raw reply
* [PATCH] ARM: dts: sun7i: Enable HDMI on pcDuino3 Nano
From: Tuomas Tynkkynen @ 2017-12-15 8:52 UTC (permalink / raw)
To: linux-arm-kernel
The board has a regular-sized HDMI connector, so enable the display
the pipeline and HDMI output for it.
Signed-off-by: Tuomas Tynkkynen <tuomas@tuxera.com>
---
arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts b/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts
index 39bc73db72e5..fb591f32252c 100644
--- a/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts
+++ b/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts
@@ -58,6 +58,17 @@
stdout-path = "serial0:115200n8";
};
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con_in: endpoint {
+ remote-endpoint = <&hdmi_out_con>;
+ };
+ };
+ };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -90,6 +101,10 @@
cpu-supply = <®_dcdc2>;
};
+&de {
+ status = "okay";
+};
+
&ehci0 {
status = "okay";
};
@@ -110,6 +125,16 @@
};
};
+&hdmi {
+ status = "okay";
+};
+
+&hdmi_out {
+ hdmi_out_con: endpoint {
+ remote-endpoint = <&hdmi_con_in>;
+ };
+};
+
&i2c0 {
pinctrl-names = "default";
pinctrl-0 = <&i2c0_pins_a>;
--
2.15.0
^ permalink raw reply related
* [PATCH] arm: dts: Remove leading 0x and 0s from bindings notation
From: Jesper Nilsson @ 2017-12-15 8:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171214165350.27850-1-malat@debian.org>
On Thu, Dec 14, 2017 at 05:53:48PM +0100, Mathieu Malaterre wrote:
> Improve the DTS files by removing all the leading "0x" and zeros to fix the
> following dtc warnings:
>
> Warning (unit_address_format): Node /XXX unit name should not have leading "0x"
>
> and
>
> Warning (unit_address_format): Node /XXX unit name should not have leading 0s
>
> Converted using the following command:
>
> find . -type f \( -iname *.dts -o -iname *.dtsi \) -exec sed -E -i -e "s/@0x([0-9a-fA-F\.]+)\s?\{/@\L\1 \{/g" -e "s/@0+([0-9a-fA-F\.]+)\s?\{/@\L\1 \{/g" {} +
>
> For simplicity, two sed expressions were used to solve each warnings separately.
>
> To make the regex expression more robust a few other issues were resolved,
> namely setting unit-address to lower case, and adding a whitespace before the
> the opening curly brace:
>
> https://elinux.org/Device_Tree_Linux#Linux_conventions
>
> This is a follow up to commit 4c9847b7375a ("dt-bindings: Remove leading 0x from bindings notation")
>
> Reported-by: David Daney <ddaney@caviumnetworks.com>
> Suggested-by: Rob Herring <robh@kernel.org>
> Signed-off-by: Mathieu Malaterre <malat@debian.org>
> ---
> arch/arm/boot/dts/artpec6.dtsi | 2 +-
Acked-by: Jesper Nilsson <jesper.nilsson@axis.com>
/^JN - Jesper Nilsson
--
Jesper Nilsson -- jesper.nilsson at axis.com
^ permalink raw reply
* [PATCH v3 01/11] dt-bindings: thermal: Describe Armada AP806 and CP110
From: Gregory CLEMENT @ 2017-12-15 8:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215093203.74b7a59c@xps13>
Hi Miquel,
On ven., d?c. 15 2017, Miquel RAYNAL <miquel.raynal@free-electrons.com> wrote:
> Hello Baruch,
>
> On Fri, 15 Dec 2017 10:27:59 +0200
> Baruch Siach <baruch@tkos.co.il> wrote:
>
>> Hi Miquel
>>
>> On Thu, Dec 14, 2017 at 11:30:01AM +0100, Miquel Raynal wrote:
>> > +- marvell,thermal-zone-name: The name to identify the thermal zone
>> > + within the sysfs, useful when multiple
>> > + thermal zones are registered (AP,
>> > CPx...).
>>
>> I don't think that would be acceptable. DT is about describing the
>> hardware. sysfs is a Linux implementation detail which is not tied to
>> any specific hardware. If this is accepted, the property should be
>> named 'linux,thermal-zone-name'.
>
> You are right the sysfs mention should not appear in the description.
>
> Otherwise for the naming I'm not sure "linux," is a valid prefix in
> that case.
Actually the choice between linux or marvell make me realize that there
is something wrong. Having a name associated to a device is something
pretty usual with the device tree, however it is as the class device
level, such as clock-names, line-name, or regulator-name. So in my
opinion if we want to support naming from device tree it would be done
for all the thermal device not just for the Marvell one.
However I don't think we need it. For example for the clocks we created
the name dynamically using of the base address of the register to keep
them unique.
Gregory
>
> Miqu?l
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH v3 01/11] dt-bindings: thermal: Describe Armada AP806 and CP110
From: Baruch Siach @ 2017-12-15 8:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215093203.74b7a59c@xps13>
HI Miqu?l
On Fri, Dec 15, 2017 at 09:32:03AM +0100, Miquel RAYNAL wrote:
> On Fri, 15 Dec 2017 10:27:59 +0200
> Baruch Siach <baruch@tkos.co.il> wrote:
> >
> > On Thu, Dec 14, 2017 at 11:30:01AM +0100, Miquel Raynal wrote:
> > > +- marvell,thermal-zone-name: The name to identify the thermal zone
> > > + within the sysfs, useful when multiple
> > > + thermal zones are registered (AP,
> > > CPx...).
> >
> > I don't think that would be acceptable. DT is about describing the
> > hardware. sysfs is a Linux implementation detail which is not tied to
> > any specific hardware. If this is accepted, the property should be
> > named 'linux,thermal-zone-name'.
>
> You are right the sysfs mention should not appear in the description.
My comment was not about the description language. I don't think that this
property is acceptable at all. But I'll let DT maintainers comment on that.
> Otherwise for the naming I'm not sure "linux," is a valid prefix in
> that case.
We use the 'linux' prefix for input key names and led triggers, for example.
baruch
--
http://baruch.siach.name/blog/ ~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -
^ permalink raw reply
* [PATCH v2 1/5] extcon: usbc-cros-ec: add support to notify USB type cables.
From: Chanwoo Choi @ 2017-12-15 8:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5A3385D0.2050308@samsung.com>
On 2017? 12? 15? 17:20, Chanwoo Choi wrote:
> On 2017? 12? 15? 17:14, Lee Jones wrote:
>>> On 2017? 12? 13? 19:32, Enric Balletbo i Serra wrote:
>>>> From: Benson Leung <bleung@chromium.org>
>>>>
>>>> Extend the driver to notify host and device type cables and the presence
>>>> of power.
>>>>
>>>> Signed-off-by: Benson Leung <bleung@chromium.org>
>>>> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
>>>> Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
>>>> ---
>>>> Changes since v1:
>>>> - Use the BIT macro. Requested by Lee Jones.
>>>> - Add the Reviewed-by: Chanwoo Choi.
>>>>
>>>> drivers/extcon/extcon-usbc-cros-ec.c | 142 ++++++++++++++++++++++++++++++++++-
>>>> include/linux/mfd/cros_ec_commands.h | 17 +++++
>>>> 2 files changed, 155 insertions(+), 4 deletions(-)
>>
>>> Looks good to me. After reviewing the Lee Jones,
>>> I'll take it on next branch.
>>
>> If you take it, you need to send me a pull-request to an immutable
>> branch.
>>
>> Acked-by: Lee Jones <lee.jones@linaro.org>
>>
>
> Sure. I'll send the immutable branch. Thanks.
>
Dear Lee,
I make the immutable branch (ib-extcon-mfd-4.16)
and send the following pull request.
The following changes since commit 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323:
Linux 4.15-rc1 (2017-11-26 16:01:47 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git ib-extcon-mfd-4.16
for you to fetch changes up to c7eb47f9e45226571be31212f6efd4b307d3b59d:
extcon: usbc-cros-ec: add support to notify USB type cables. (2017-12-15 17:21:49 +0900)
----------------------------------------------------------------
Benson Leung (1):
extcon: usbc-cros-ec: add support to notify USB type cables.
drivers/extcon/extcon-usbc-cros-ec.c | 142 ++++++++++++++++++++++++++++++++++-
include/linux/mfd/cros_ec_commands.h | 17 +++++
2 files changed, 155 insertions(+), 4 deletions(-)
--
Best Regards,
Chanwoo Choi
Samsung Electronics
^ permalink raw reply
* [PATCH v3 03/11] thermal: armada: Simplify the check of the validity bit
From: Baruch Siach @ 2017-12-15 8:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171214103011.24713-4-miquel.raynal@free-electrons.com>
Hi Miquel,
On Thu, Dec 14, 2017 at 11:30:03AM +0100, Miquel Raynal wrote:
> All Armada SoCs use one bit to declare if the sensor values are valid.
> This bit moves across the versions of the IP.
>
> The method until then was to do both a shift and compare with an useless
> flag of "0x1". It is clearer and quicker to directly save the value that
> must be ANDed instead of the bit position and do a single bitwise AND
> operation.
>
> Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
> ---
> drivers/thermal/armada_thermal.c | 12 +++++-------
> 1 file changed, 5 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
> index 6c4af2622d4f..26698f2d3ca7 100644
> --- a/drivers/thermal/armada_thermal.c
> +++ b/drivers/thermal/armada_thermal.c
> @@ -24,8 +24,6 @@
> #include <linux/of_device.h>
> #include <linux/thermal.h>
>
> -#define THERMAL_VALID_MASK 0x1
> -
> /* Thermal Manager Control and Status Register */
> #define PMU_TDC0_SW_RST_MASK (0x1 << 1)
> #define PMU_TM_DISABLE_OFFS 0
> @@ -67,7 +65,7 @@ struct armada_thermal_data {
> /* Register shift and mask to access the sensor temperature */
> unsigned int temp_shift;
> unsigned int temp_mask;
> - unsigned int is_valid_shift;
> + unsigned int is_valid_bit;
Type should be u32 now, I think.
> };
>
> static void armadaxp_init_sensor(struct platform_device *pdev,
> @@ -151,7 +149,7 @@ static bool armada_is_valid(struct armada_thermal_priv *priv)
> {
> unsigned long reg = readl_relaxed(priv->sensor);
u32 here also, I think. But that's unrelated to this patch.
> - return (reg >> priv->data->is_valid_shift) & THERMAL_VALID_MASK;
> + return reg & priv->data->is_valid_bit;
> }
>
> static int armada_get_temp(struct thermal_zone_device *thermal,
> @@ -199,7 +197,7 @@ static const struct armada_thermal_data armadaxp_data = {
> static const struct armada_thermal_data armada370_data = {
> .is_valid = armada_is_valid,
> .init_sensor = armada370_init_sensor,
> - .is_valid_shift = 9,
> + .is_valid_bit = BIT(9),
> .temp_shift = 10,
> .temp_mask = 0x1ff,
> .coef_b = 3153000000UL,
> @@ -210,7 +208,7 @@ static const struct armada_thermal_data armada370_data = {
> static const struct armada_thermal_data armada375_data = {
> .is_valid = armada_is_valid,
> .init_sensor = armada375_init_sensor,
> - .is_valid_shift = 10,
> + .is_valid_bit = BIT(10),
> .temp_shift = 0,
> .temp_mask = 0x1ff,
> .coef_b = 3171900000UL,
> @@ -221,7 +219,7 @@ static const struct armada_thermal_data armada375_data = {
> static const struct armada_thermal_data armada380_data = {
> .is_valid = armada_is_valid,
> .init_sensor = armada380_init_sensor,
> - .is_valid_shift = 10,
> + .is_valid_bit = BIT(10),
> .temp_shift = 0,
> .temp_mask = 0x3ff,
> .coef_b = 1172499100UL,
baruch
--
http://baruch.siach.name/blog/ ~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -
^ permalink raw reply
* [PATCH v3 01/11] dt-bindings: thermal: Describe Armada AP806 and CP110
From: Miquel RAYNAL @ 2017-12-15 8:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215082759.7t24ka3lpkulcb7r@tarshish>
Hello Baruch,
On Fri, 15 Dec 2017 10:27:59 +0200
Baruch Siach <baruch@tkos.co.il> wrote:
> Hi Miquel
>
> On Thu, Dec 14, 2017 at 11:30:01AM +0100, Miquel Raynal wrote:
> > +- marvell,thermal-zone-name: The name to identify the thermal zone
> > + within the sysfs, useful when multiple
> > + thermal zones are registered (AP,
> > CPx...).
>
> I don't think that would be acceptable. DT is about describing the
> hardware. sysfs is a Linux implementation detail which is not tied to
> any specific hardware. If this is accepted, the property should be
> named 'linux,thermal-zone-name'.
You are right the sysfs mention should not appear in the description.
Otherwise for the naming I'm not sure "linux," is a valid prefix in
that case.
Miqu?l
^ permalink raw reply
* [PATCH v3 01/11] dt-bindings: thermal: Describe Armada AP806 and CP110
From: Baruch Siach @ 2017-12-15 8:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171214103011.24713-2-miquel.raynal@free-electrons.com>
Hi Miquel
On Thu, Dec 14, 2017 at 11:30:01AM +0100, Miquel Raynal wrote:
> +- marvell,thermal-zone-name: The name to identify the thermal zone
> + within the sysfs, useful when multiple
> + thermal zones are registered (AP, CPx...).
I don't think that would be acceptable. DT is about describing the hardware.
sysfs is a Linux implementation detail which is not tied to any specific
hardware. If this is accepted, the property should be named
'linux,thermal-zone-name'.
baruch
--
http://baruch.siach.name/blog/ ~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -
^ permalink raw reply
* [PATCH v2 1/5] extcon: usbc-cros-ec: add support to notify USB type cables.
From: Chanwoo Choi @ 2017-12-15 8:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215081453.6jwjdetwe655imqo@dell>
On 2017? 12? 15? 17:14, Lee Jones wrote:
>> On 2017? 12? 13? 19:32, Enric Balletbo i Serra wrote:
>>> From: Benson Leung <bleung@chromium.org>
>>>
>>> Extend the driver to notify host and device type cables and the presence
>>> of power.
>>>
>>> Signed-off-by: Benson Leung <bleung@chromium.org>
>>> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
>>> Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
>>> ---
>>> Changes since v1:
>>> - Use the BIT macro. Requested by Lee Jones.
>>> - Add the Reviewed-by: Chanwoo Choi.
>>>
>>> drivers/extcon/extcon-usbc-cros-ec.c | 142 ++++++++++++++++++++++++++++++++++-
>>> include/linux/mfd/cros_ec_commands.h | 17 +++++
>>> 2 files changed, 155 insertions(+), 4 deletions(-)
>
>> Looks good to me. After reviewing the Lee Jones,
>> I'll take it on next branch.
>
> If you take it, you need to send me a pull-request to an immutable
> branch.
>
> Acked-by: Lee Jones <lee.jones@linaro.org>
>
Sure. I'll send the immutable branch. Thanks.
--
Best Regards,
Chanwoo Choi
Samsung Electronics
^ permalink raw reply
* [PATCH v2 1/5] extcon: usbc-cros-ec: add support to notify USB type cables.
From: Lee Jones @ 2017-12-15 8:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5A33702D.60004@samsung.com>
> On 2017? 12? 13? 19:32, Enric Balletbo i Serra wrote:
> > From: Benson Leung <bleung@chromium.org>
> >
> > Extend the driver to notify host and device type cables and the presence
> > of power.
> >
> > Signed-off-by: Benson Leung <bleung@chromium.org>
> > Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
> > Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
> > ---
> > Changes since v1:
> > - Use the BIT macro. Requested by Lee Jones.
> > - Add the Reviewed-by: Chanwoo Choi.
> >
> > drivers/extcon/extcon-usbc-cros-ec.c | 142 ++++++++++++++++++++++++++++++++++-
> > include/linux/mfd/cros_ec_commands.h | 17 +++++
> > 2 files changed, 155 insertions(+), 4 deletions(-)
> Looks good to me. After reviewing the Lee Jones,
> I'll take it on next branch.
If you take it, you need to send me a pull-request to an immutable
branch.
Acked-by: Lee Jones <lee.jones@linaro.org>
--
Lee Jones
Linaro Services Technical Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH net-next v6 1/2] dt-bindings: net: add DT bindings for Socionext UniPhier AVE
From: Kunihiko Hayashi @ 2017-12-15 8:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <7749e13a-56ef-0d43-1a41-dbd457227575@gmail.com>
Hello Florian,
On Thu, 14 Dec 2017 15:24:17 -0800 <f.fainelli@gmail.com> wrote:
>
>
> On 12/14/2017 02:05 AM, Kunihiko Hayashi wrote:
> > DT bindings for the AVE ethernet controller found on Socionext's
> > UniPhier platforms.
> >
> > Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
> > Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> > Acked-by: Rob Herring <robh@kernel.org>
> > ---
> > .../bindings/net/socionext,uniphier-ave4.txt | 48 ++++++++++++++++++++++
> > 1 file changed, 48 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt
> >
> > diff --git a/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt b/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt
> > new file mode 100644
> > index 0000000..4700377
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt
> > @@ -0,0 +1,48 @@
> > +* Socionext AVE ethernet controller
> > +
> > +This describes the devicetree bindings for AVE ethernet controller
> > +implemented on Socionext UniPhier SoCs.
> > +
> > +Required properties:
> > + - compatible: Should be
> > + - "socionext,uniphier-pro4-ave4" : for Pro4 SoC
> > + - "socionext,uniphier-pxs2-ave4" : for PXs2 SoC
> > + - "socionext,uniphier-ld11-ave4" : for LD11 SoC
> > + - "socionext,uniphier-ld20-ave4" : for LD20 SoC
> > + - reg: Address where registers are mapped and size of region.
> > + - interrupts: Should contain the MAC interrupt.
> > + - phy-mode: See ethernet.txt in the same directory. Allow to choose
> > + "rgmii", "rmii", or "mii" according to the PHY.
> > + - phy-handle: Should point to the external phy device.
> > + See ethernet.txt file in the same directory.
> > + - clocks: A phandle to the clock for the MAC.
> > +
> > +Optional properties:
> > + - resets: A phandle to the reset control for the MAC
> > + - local-mac-address: See ethernet.txt in the same directory.
> > +
> > +Required subnode:
> > + - mdio: Device tree subnode with the following required properties:
> > + - #address-cells: Must be <1>.
> > + - #size-cells: Must be <0>.
> > + - reg: phy ID number, usually a small integer.
>
> Almost, the "reg" property applies to the MDIO child nodes: the Ethernet
> PHYs/MDIO devices. For the MDIO controller itself, the "reg" property,
> if specified, would be relative to the Ethernet controller's base
> register address.
>
> Please drop this property's description here.
Thank you for pointing out.
Surely this MDIO node doesn't have own "reg" property, and this description
shows "reg" property of PHY device connected to the MDIO bus.
I'll remove the description.
Thank you,
> > +
> > +Example:
> > +
> > + ether: ethernet at 65000000 {
> > + compatible = "socionext,uniphier-ld20-ave4";
> > + reg = <0x65000000 0x8500>;
> > + interrupts = <0 66 4>;
> > + phy-mode = "rgmii";
> > + phy-handle = <ðphy>;
> > + clocks = <&sys_clk 6>;
> > + resets = <&sys_rst 6>;
> > + local-mac-address = [00 00 00 00 00 00];
> > + mdio {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > + ethphy: ethphy at 1 {
> > + reg = <1>;
> > + };
> > + };
> > + };
> >
>
> --
> Florian
---
Best Regards,
Kunihiko Hayashi
^ permalink raw reply
* [PATCH 04/27] clocksource/arm_arch_timer: Use timecounter_initialize interface
From: Sagar Arun Kamble @ 2017-12-15 7:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1513323522-15021-1-git-send-email-sagar.a.kamble@intel.com>
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update arch_timer_kvm_info
timecounter init with this new function.
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
drivers/clocksource/arm_arch_timer.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 31543e5..d96393f 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -910,10 +910,7 @@ static u64 arch_counter_get_cntvct_mem(void)
return ((u64) vct_hi << 32) | vct_lo;
}
-static struct arch_timer_kvm_info arch_timer_kvm_info = {
- .timecounter.cc.read = arch_counter_read_cc,
- .timecounter.cc.mask = CLOCKSOURCE_MASK(56),
-};
+static struct arch_timer_kvm_info arch_timer_kvm_info;
struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
{
@@ -923,7 +920,6 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
static void __init arch_counter_register(unsigned type)
{
u64 start_count;
- struct cyclecounter *cc = &arch_timer_kvm_info.timecounter.cc;
/* Register the CP15 based counter if we have one */
if (type & ARCH_TIMER_TYPE_CP15) {
@@ -943,9 +939,12 @@ static void __init arch_counter_register(unsigned type)
start_count = arch_timer_read_counter();
clocksource_register_hz(&clocksource_counter, arch_timer_rate);
- cc->mult = clocksource_counter.mult;
- cc->shift = clocksource_counter.shift;
- timecounter_init(&arch_timer_kvm_info.timecounter, start_count);
+ timecounter_initialize(&arch_timer_kvm_info.timecounter,
+ arch_counter_read_cc,
+ CLOCKSOURCE_MASK(56),
+ clocksource_counter.mult,
+ clocksource_counter.shift,
+ start_count);
/* 56 bits minimum, so we assume worst case rollover */
sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate);
--
1.9.1
^ permalink raw reply related
* [PATCH 01/27] timecounter: Make cyclecounter struct part of timecounter struct
From: Sagar Arun Kamble @ 2017-12-15 7:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1513323522-15021-1-git-send-email-sagar.a.kamble@intel.com>
There is no real need for the users of timecounters to define cyclecounter
and timecounter variables separately. Since timecounter will always be
based on cyclecounter, have cyclecounter struct as member of timecounter
struct.
v2: Rebase.
Suggested-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Stephen Boyd <sboyd@codeaurora.org>
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: netdev at vger.kernel.org
Cc: intel-wired-lan at lists.osuosl.org
Cc: linux-rdma at vger.kernel.org
Cc: alsa-devel at alsa-project.org
Cc: kvmarm at lists.cs.columbia.edu
Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> (Intel drivers)
---
arch/microblaze/kernel/timer.c | 20 ++++++------
drivers/clocksource/arm_arch_timer.c | 19 ++++++------
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 +-
drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 9 +++---
drivers/net/ethernet/amd/xgbe/xgbe.h | 1 -
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 1 -
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 20 ++++++------
drivers/net/ethernet/freescale/fec.h | 1 -
drivers/net/ethernet/freescale/fec_ptp.c | 30 +++++++++---------
drivers/net/ethernet/intel/e1000e/e1000.h | 1 -
drivers/net/ethernet/intel/e1000e/netdev.c | 27 ++++++++--------
drivers/net/ethernet/intel/e1000e/ptp.c | 2 +-
drivers/net/ethernet/intel/igb/igb.h | 1 -
drivers/net/ethernet/intel/igb/igb_ptp.c | 25 ++++++++-------
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 -
drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 17 +++++-----
drivers/net/ethernet/mellanox/mlx4/en_clock.c | 28 ++++++++---------
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 -
.../net/ethernet/mellanox/mlx5/core/lib/clock.c | 34 ++++++++++----------
drivers/net/ethernet/qlogic/qede/qede_ptp.c | 20 ++++++------
drivers/net/ethernet/ti/cpts.c | 36 ++++++++++++----------
drivers/net/ethernet/ti/cpts.h | 1 -
include/linux/mlx5/driver.h | 1 -
include/linux/timecounter.h | 4 +--
include/sound/hdaudio.h | 1 -
kernel/time/timecounter.c | 28 ++++++++---------
sound/hda/hdac_stream.c | 7 +++--
virt/kvm/arm/arch_timer.c | 6 ++--
28 files changed, 163 insertions(+), 182 deletions(-)
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index 7de941c..b7f89e9 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -199,27 +199,25 @@ static u64 xilinx_read(struct clocksource *cs)
return (u64)xilinx_clock_read();
}
-static struct timecounter xilinx_tc = {
- .cc = NULL,
-};
-
static u64 xilinx_cc_read(const struct cyclecounter *cc)
{
return xilinx_read(NULL);
}
-static struct cyclecounter xilinx_cc = {
- .read = xilinx_cc_read,
- .mask = CLOCKSOURCE_MASK(32),
- .shift = 8,
+static struct timecounter xilinx_tc = {
+ .cc.read = xilinx_cc_read,
+ .cc.mask = CLOCKSOURCE_MASK(32),
+ .cc.mult = 0,
+ .cc.shift = 8,
};
static int __init init_xilinx_timecounter(void)
{
- xilinx_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC,
- xilinx_cc.shift);
+ struct cyclecounter *cc = &xilinx_tc.cc;
+
+ cc->mult = div_sc(timer_clock_freq, NSEC_PER_SEC, cc->shift);
- timecounter_init(&xilinx_tc, &xilinx_cc, sched_clock());
+ timecounter_init(&xilinx_tc, sched_clock());
return 0;
}
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 57cb2f0..31543e5 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -179,11 +179,6 @@ static u64 arch_counter_read_cc(const struct cyclecounter *cc)
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-static struct cyclecounter cyclecounter __ro_after_init = {
- .read = arch_counter_read_cc,
- .mask = CLOCKSOURCE_MASK(56),
-};
-
struct ate_acpi_oem_info {
char oem_id[ACPI_OEM_ID_SIZE + 1];
char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
@@ -915,7 +910,10 @@ static u64 arch_counter_get_cntvct_mem(void)
return ((u64) vct_hi << 32) | vct_lo;
}
-static struct arch_timer_kvm_info arch_timer_kvm_info;
+static struct arch_timer_kvm_info arch_timer_kvm_info = {
+ .timecounter.cc.read = arch_counter_read_cc,
+ .timecounter.cc.mask = CLOCKSOURCE_MASK(56),
+};
struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
{
@@ -925,6 +923,7 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
static void __init arch_counter_register(unsigned type)
{
u64 start_count;
+ struct cyclecounter *cc = &arch_timer_kvm_info.timecounter.cc;
/* Register the CP15 based counter if we have one */
if (type & ARCH_TIMER_TYPE_CP15) {
@@ -943,10 +942,10 @@ static void __init arch_counter_register(unsigned type)
clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
start_count = arch_timer_read_counter();
clocksource_register_hz(&clocksource_counter, arch_timer_rate);
- cyclecounter.mult = clocksource_counter.mult;
- cyclecounter.shift = clocksource_counter.shift;
- timecounter_init(&arch_timer_kvm_info.timecounter,
- &cyclecounter, start_count);
+
+ cc->mult = clocksource_counter.mult;
+ cc->shift = clocksource_counter.shift;
+ timecounter_init(&arch_timer_kvm_info.timecounter, start_count);
/* 56 bits minimum, so we assume worst case rollover */
sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate);
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index e107e18..5005c87 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1622,8 +1622,7 @@ static int xgbe_config_tstamp(struct xgbe_prv_data *pdata,
xgbe_set_tstamp_time(pdata, 0, 0);
/* Initialize the timecounter */
- timecounter_init(&pdata->tstamp_tc, &pdata->tstamp_cc,
- ktime_to_ns(ktime_get_real()));
+ timecounter_init(&pdata->tstamp_tc, ktime_to_ns(ktime_get_real()));
return 0;
}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
index d06d260..5ea4edf 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
@@ -126,7 +126,7 @@ static u64 xgbe_cc_read(const struct cyclecounter *cc)
{
struct xgbe_prv_data *pdata = container_of(cc,
struct xgbe_prv_data,
- tstamp_cc);
+ tstamp_tc.cc);
u64 nsec;
nsec = pdata->hw_if.get_tstamp_time(pdata);
@@ -211,7 +211,7 @@ static int xgbe_settime(struct ptp_clock_info *info,
spin_lock_irqsave(&pdata->tstamp_lock, flags);
- timecounter_init(&pdata->tstamp_tc, &pdata->tstamp_cc, nsec);
+ timecounter_init(&pdata->tstamp_tc, nsec);
spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
@@ -228,7 +228,7 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata)
{
struct ptp_clock_info *info = &pdata->ptp_clock_info;
struct ptp_clock *clock;
- struct cyclecounter *cc = &pdata->tstamp_cc;
+ struct cyclecounter *cc = &pdata->tstamp_tc.cc;
u64 dividend;
snprintf(info->name, sizeof(info->name), "%s",
@@ -263,8 +263,7 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata)
cc->mult = 1;
cc->shift = 0;
- timecounter_init(&pdata->tstamp_tc, &pdata->tstamp_cc,
- ktime_to_ns(ktime_get_real()));
+ timecounter_init(&pdata->tstamp_tc, ktime_to_ns(ktime_get_real()));
/* Disable all timestamping to start */
XGMAC_IOWRITE(pdata, MAC_TSCR, 0);
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index ad102c8..2445103 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -1168,7 +1168,6 @@ struct xgbe_prv_data {
struct ptp_clock_info ptp_clock_info;
struct ptp_clock *ptp_clock;
struct hwtstamp_config tstamp_config;
- struct cyclecounter tstamp_cc;
struct timecounter tstamp_tc;
unsigned int tstamp_addend;
struct work_struct tx_tstamp_work;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 352beff..f164fe0 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1827,7 +1827,6 @@ struct bnx2x {
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_clock_info;
struct work_struct ptp_task;
- struct cyclecounter cyclecounter;
struct timecounter timecounter;
bool timecounter_init_done;
struct sk_buff *ptp_tx_skb;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 91e2a75..83624ad 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -13850,7 +13850,7 @@ static int bnx2x_ptp_settime(struct ptp_clock_info *ptp,
DP(BNX2X_MSG_PTP, "PTP settime called, ns = %llu\n", ns);
/* Re-init the timecounter */
- timecounter_init(&bp->timecounter, &bp->cyclecounter, ns);
+ timecounter_init(&bp->timecounter, ns);
return 0;
}
@@ -15254,7 +15254,7 @@ void bnx2x_set_rx_ts(struct bnx2x *bp, struct sk_buff *skb)
/* Read the PHC */
static u64 bnx2x_cyclecounter_read(const struct cyclecounter *cc)
{
- struct bnx2x *bp = container_of(cc, struct bnx2x, cyclecounter);
+ struct bnx2x *bp = container_of(cc, struct bnx2x, timecounter.cc);
int port = BP_PORT(bp);
u32 wb_data[2];
u64 phc_cycles;
@@ -15269,13 +15269,13 @@ static u64 bnx2x_cyclecounter_read(const struct cyclecounter *cc)
return phc_cycles;
}
-static void bnx2x_init_cyclecounter(struct bnx2x *bp)
+static void bnx2x_init_cyclecounter(struct cyclecounter *cc)
{
- memset(&bp->cyclecounter, 0, sizeof(bp->cyclecounter));
- bp->cyclecounter.read = bnx2x_cyclecounter_read;
- bp->cyclecounter.mask = CYCLECOUNTER_MASK(64);
- bp->cyclecounter.shift = 0;
- bp->cyclecounter.mult = 1;
+ memset(cc, 0, sizeof(*cc));
+ cc->read = bnx2x_cyclecounter_read;
+ cc->mask = CYCLECOUNTER_MASK(64);
+ cc->shift = 0;
+ cc->mult = 1;
}
static int bnx2x_send_reset_timesync_ramrod(struct bnx2x *bp)
@@ -15511,8 +15511,8 @@ void bnx2x_init_ptp(struct bnx2x *bp)
* unload / load (e.g. MTU change) while it is running.
*/
if (!bp->timecounter_init_done) {
- bnx2x_init_cyclecounter(bp);
- timecounter_init(&bp->timecounter, &bp->cyclecounter,
+ bnx2x_init_cyclecounter(&bp->timecounter.cc);
+ timecounter_init(&bp->timecounter,
ktime_to_ns(ktime_get_real()));
bp->timecounter_init_done = 1;
}
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 5385074..d54b501 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -549,7 +549,6 @@ struct fec_enet_private {
struct ptp_clock_info ptp_caps;
unsigned long last_overflow_check;
spinlock_t tmreg_lock;
- struct cyclecounter cc;
struct timecounter tc;
int rx_hwtstamp_filter;
u32 base_incval;
diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
index f814397..b1261d1 100644
--- a/drivers/net/ethernet/freescale/fec_ptp.c
+++ b/drivers/net/ethernet/freescale/fec_ptp.c
@@ -186,13 +186,14 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
* ptp counter, which maybe cause 32-bit wrap. Since the
* (NSEC_PER_SEC - (u32)ts.tv_nsec) is less than 2 second.
* We can ensure the wrap will not cause issue. If the offset
- * is bigger than fep->cc.mask would be a error.
+ * is bigger than fep->tc.cc.mask would be a error.
*/
- val &= fep->cc.mask;
+ val &= fep->tc.cc.mask;
writel(val, fep->hwp + FEC_TCCR(fep->pps_channel));
/* Calculate the second the compare event timestamp */
- fep->next_counter = (val + fep->reload_period) & fep->cc.mask;
+ fep->next_counter = (val + fep->reload_period) &
+ fep->tc.cc.mask;
/* * Enable compare event when overflow */
val = readl(fep->hwp + FEC_ATIME_CTRL);
@@ -211,7 +212,8 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
* the third timestamp. Refer the TCCR register detail in the spec.
*/
writel(fep->next_counter, fep->hwp + FEC_TCCR(fep->pps_channel));
- fep->next_counter = (fep->next_counter + fep->reload_period) & fep->cc.mask;
+ fep->next_counter = (fep->next_counter + fep->reload_period) &
+ fep->tc.cc.mask;
} else {
writel(0, fep->hwp + FEC_TCSR(fep->pps_channel));
}
@@ -233,7 +235,7 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
static u64 fec_ptp_read(const struct cyclecounter *cc)
{
struct fec_enet_private *fep =
- container_of(cc, struct fec_enet_private, cc);
+ container_of(cc, struct fec_enet_private, tc.cc);
const struct platform_device_id *id_entry =
platform_get_device_id(fep->pdev);
u32 tempval;
@@ -276,14 +278,14 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev)
writel(FEC_T_CTRL_ENABLE | FEC_T_CTRL_PERIOD_RST,
fep->hwp + FEC_ATIME_CTRL);
- memset(&fep->cc, 0, sizeof(fep->cc));
- fep->cc.read = fec_ptp_read;
- fep->cc.mask = CLOCKSOURCE_MASK(31);
- fep->cc.shift = 31;
- fep->cc.mult = FEC_CC_MULT;
+ memset(&fep->tc.cc, 0, sizeof(fep->tc.cc));
+ fep->tc.cc.read = fec_ptp_read;
+ fep->tc.cc.mask = CLOCKSOURCE_MASK(31);
+ fep->tc.cc.shift = 31;
+ fep->tc.cc.mult = FEC_CC_MULT;
/* reset the ns time counter */
- timecounter_init(&fep->tc, &fep->cc, ktime_to_ns(ktime_get_real()));
+ timecounter_init(&fep->tc, ktime_to_ns(ktime_get_real()));
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
}
@@ -434,11 +436,11 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp,
/* Get the timer value based on timestamp.
* Update the counter with the masked value.
*/
- counter = ns & fep->cc.mask;
+ counter = ns & fep->tc.cc.mask;
spin_lock_irqsave(&fep->tmreg_lock, flags);
writel(counter, fep->hwp + FEC_ATIME);
- timecounter_init(&fep->tc, &fep->cc, ns);
+ timecounter_init(&fep->tc, ns);
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
mutex_unlock(&fep->ptp_clk_mutex);
return 0;
@@ -570,7 +572,7 @@ static irqreturn_t fec_pps_interrupt(int irq, void *dev_id)
/* Update the counter; */
fep->next_counter = (fep->next_counter + fep->reload_period) &
- fep->cc.mask;
+ fep->tc.cc.mask;
event.type = PTP_CLOCK_PPS;
ptp_clock_event(fep->ptp_clock, &event);
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h
index 2311b31..b59f82a 100644
--- a/drivers/net/ethernet/intel/e1000e/e1000.h
+++ b/drivers/net/ethernet/intel/e1000e/e1000.h
@@ -340,7 +340,6 @@ struct e1000_adapter {
unsigned long tx_hwtstamp_start;
struct work_struct tx_hwtstamp_work;
spinlock_t systim_lock; /* protects SYSTIML/H regsters */
- struct cyclecounter cc;
struct timecounter tc;
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_clock_info;
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 9f18d39..c9f7ba3 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -3536,7 +3536,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca)
incperiod = INCPERIOD_96MHZ;
incvalue = INCVALUE_96MHZ;
shift = INCVALUE_SHIFT_96MHZ;
- adapter->cc.shift = shift + INCPERIOD_SHIFT_96MHZ;
+ adapter->tc.cc.shift = shift + INCPERIOD_SHIFT_96MHZ;
break;
case e1000_pch_lpt:
if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) {
@@ -3544,13 +3544,13 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca)
incperiod = INCPERIOD_96MHZ;
incvalue = INCVALUE_96MHZ;
shift = INCVALUE_SHIFT_96MHZ;
- adapter->cc.shift = shift + INCPERIOD_SHIFT_96MHZ;
+ adapter->tc.cc.shift = shift + INCPERIOD_SHIFT_96MHZ;
} else {
/* Stable 25MHz frequency */
incperiod = INCPERIOD_25MHZ;
incvalue = INCVALUE_25MHZ;
shift = INCVALUE_SHIFT_25MHZ;
- adapter->cc.shift = shift;
+ adapter->tc.cc.shift = shift;
}
break;
case e1000_pch_spt:
@@ -3559,7 +3559,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca)
incperiod = INCPERIOD_24MHZ;
incvalue = INCVALUE_24MHZ;
shift = INCVALUE_SHIFT_24MHZ;
- adapter->cc.shift = shift;
+ adapter->tc.cc.shift = shift;
break;
}
return -EINVAL;
@@ -3569,13 +3569,13 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca)
incperiod = INCPERIOD_24MHZ;
incvalue = INCVALUE_24MHZ;
shift = INCVALUE_SHIFT_24MHZ;
- adapter->cc.shift = shift;
+ adapter->tc.cc.shift = shift;
} else {
/* Stable 38400KHz frequency */
incperiod = INCPERIOD_38400KHZ;
incvalue = INCVALUE_38400KHZ;
shift = INCVALUE_SHIFT_38400KHZ;
- adapter->cc.shift = shift;
+ adapter->tc.cc.shift = shift;
}
break;
case e1000_82574:
@@ -3584,7 +3584,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca)
incperiod = INCPERIOD_25MHZ;
incvalue = INCVALUE_25MHZ;
shift = INCVALUE_SHIFT_25MHZ;
- adapter->cc.shift = shift;
+ adapter->tc.cc.shift = shift;
break;
default:
return -EINVAL;
@@ -3955,8 +3955,7 @@ static void e1000e_systim_reset(struct e1000_adapter *adapter)
/* reset the systim ns time counter */
spin_lock_irqsave(&adapter->systim_lock, flags);
- timecounter_init(&adapter->tc, &adapter->cc,
- ktime_to_ns(ktime_get_real()));
+ timecounter_init(&adapter->tc, ktime_to_ns(ktime_get_real()));
spin_unlock_irqrestore(&adapter->systim_lock, flags);
/* restore the previous hwtstamp configuration settings */
@@ -4389,7 +4388,7 @@ static u64 e1000e_sanitize_systim(struct e1000_hw *hw, u64 systim)
static u64 e1000e_cyclecounter_read(const struct cyclecounter *cc)
{
struct e1000_adapter *adapter = container_of(cc, struct e1000_adapter,
- cc);
+ tc.cc);
struct e1000_hw *hw = &adapter->hw;
u32 systimel, systimeh;
u64 systim;
@@ -4449,10 +4448,10 @@ static int e1000_sw_init(struct e1000_adapter *adapter)
/* Setup hardware time stamping cyclecounter */
if (adapter->flags & FLAG_HAS_HW_TIMESTAMP) {
- adapter->cc.read = e1000e_cyclecounter_read;
- adapter->cc.mask = CYCLECOUNTER_MASK(64);
- adapter->cc.mult = 1;
- /* cc.shift set in e1000e_get_base_tininca() */
+ adapter->tc.cc.read = e1000e_cyclecounter_read;
+ adapter->tc.cc.mask = CYCLECOUNTER_MASK(64);
+ adapter->tc.cc.mult = 1;
+ /* tc.cc.shift set in e1000e_get_base_tininca() */
spin_lock_init(&adapter->systim_lock);
INIT_WORK(&adapter->tx_hwtstamp_work, e1000e_tx_hwtstamp_work);
diff --git a/drivers/net/ethernet/intel/e1000e/ptp.c b/drivers/net/ethernet/intel/e1000e/ptp.c
index b366885..03d5f2a 100644
--- a/drivers/net/ethernet/intel/e1000e/ptp.c
+++ b/drivers/net/ethernet/intel/e1000e/ptp.c
@@ -222,7 +222,7 @@ static int e1000e_phc_settime(struct ptp_clock_info *ptp,
/* reset the timecounter */
spin_lock_irqsave(&adapter->systim_lock, flags);
- timecounter_init(&adapter->tc, &adapter->cc, ns);
+ timecounter_init(&adapter->tc, ns);
spin_unlock_irqrestore(&adapter->systim_lock, flags);
return 0;
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 9284569..4eac4f2 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -565,7 +565,6 @@ struct igb_adapter {
unsigned long last_rx_timestamp;
unsigned int ptp_flags;
spinlock_t tmreg_lock;
- struct cyclecounter cc;
struct timecounter tc;
u32 tx_hwtstamp_timeouts;
u32 tx_hwtstamp_skipped;
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
index 841c2a0..0745eff 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -79,7 +79,7 @@
/* SYSTIM read access for the 82576 */
static u64 igb_ptp_read_82576(const struct cyclecounter *cc)
{
- struct igb_adapter *igb = container_of(cc, struct igb_adapter, cc);
+ struct igb_adapter *igb = container_of(cc, struct igb_adapter, tc.cc);
struct e1000_hw *hw = &igb->hw;
u64 val;
u32 lo, hi;
@@ -96,7 +96,7 @@ static u64 igb_ptp_read_82576(const struct cyclecounter *cc)
/* SYSTIM read access for the 82580 */
static u64 igb_ptp_read_82580(const struct cyclecounter *cc)
{
- struct igb_adapter *igb = container_of(cc, struct igb_adapter, cc);
+ struct igb_adapter *igb = container_of(cc, struct igb_adapter, tc.cc);
struct e1000_hw *hw = &igb->hw;
u32 lo, hi;
u64 val;
@@ -330,7 +330,7 @@ static int igb_ptp_settime_82576(struct ptp_clock_info *ptp,
spin_lock_irqsave(&igb->tmreg_lock, flags);
- timecounter_init(&igb->tc, &igb->cc, ns);
+ timecounter_init(&igb->tc, ns);
spin_unlock_irqrestore(&igb->tmreg_lock, flags);
@@ -1126,10 +1126,10 @@ void igb_ptp_init(struct igb_adapter *adapter)
adapter->ptp_caps.gettime64 = igb_ptp_gettime_82576;
adapter->ptp_caps.settime64 = igb_ptp_settime_82576;
adapter->ptp_caps.enable = igb_ptp_feature_enable;
- adapter->cc.read = igb_ptp_read_82576;
- adapter->cc.mask = CYCLECOUNTER_MASK(64);
- adapter->cc.mult = 1;
- adapter->cc.shift = IGB_82576_TSYNC_SHIFT;
+ adapter->tc.cc.read = igb_ptp_read_82576;
+ adapter->tc.cc.mask = CYCLECOUNTER_MASK(64);
+ adapter->tc.cc.mult = 1;
+ adapter->tc.cc.shift = IGB_82576_TSYNC_SHIFT;
adapter->ptp_flags |= IGB_PTP_OVERFLOW_CHECK;
break;
case e1000_82580:
@@ -1145,10 +1145,10 @@ void igb_ptp_init(struct igb_adapter *adapter)
adapter->ptp_caps.gettime64 = igb_ptp_gettime_82576;
adapter->ptp_caps.settime64 = igb_ptp_settime_82576;
adapter->ptp_caps.enable = igb_ptp_feature_enable;
- adapter->cc.read = igb_ptp_read_82580;
- adapter->cc.mask = CYCLECOUNTER_MASK(IGB_NBITS_82580);
- adapter->cc.mult = 1;
- adapter->cc.shift = 0;
+ adapter->tc.cc.read = igb_ptp_read_82580;
+ adapter->tc.cc.mask = CYCLECOUNTER_MASK(IGB_NBITS_82580);
+ adapter->tc.cc.mult = 1;
+ adapter->tc.cc.shift = 0;
adapter->ptp_flags |= IGB_PTP_OVERFLOW_CHECK;
break;
case e1000_i210:
@@ -1289,8 +1289,7 @@ void igb_ptp_reset(struct igb_adapter *adapter)
igb_ptp_write_i210(adapter, &ts);
} else {
- timecounter_init(&adapter->tc, &adapter->cc,
- ktime_to_ns(ktime_get_real()));
+ timecounter_init(&adapter->tc, ktime_to_ns(ktime_get_real()));
}
out:
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 468c355..5c391a0 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -738,7 +738,6 @@ struct ixgbe_adapter {
unsigned long last_rx_ptp_check;
unsigned long last_rx_timestamp;
spinlock_t tmreg_lock;
- struct cyclecounter hw_cc;
struct timecounter hw_tc;
u32 base_incval;
u32 tx_hwtstamp_timeouts;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
index ae312c4..6e9f2c0 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -179,7 +179,7 @@
static void ixgbe_ptp_setup_sdp_x540(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
- int shift = adapter->hw_cc.shift;
+ int shift = adapter->hw_tc.cc.shift;
u32 esdp, tsauxc, clktiml, clktimh, trgttiml, trgttimh, rem;
u64 ns = 0, clock_edge = 0;
@@ -237,7 +237,7 @@ static void ixgbe_ptp_setup_sdp_x540(struct ixgbe_adapter *adapter)
/**
* ixgbe_ptp_read_X550 - read cycle counter value
- * @hw_cc: cyclecounter structure
+ * @cc: cyclecounter structure
*
* This function reads SYSTIME registers. It is called by the cyclecounter
* structure to convert from internal representation into nanoseconds. We need
@@ -245,10 +245,10 @@ static void ixgbe_ptp_setup_sdp_x540(struct ixgbe_adapter *adapter)
* result of SYSTIME is 32bits of "billions of cycles" and 32 bits of
* "cycles", rather than seconds and nanoseconds.
*/
-static u64 ixgbe_ptp_read_X550(const struct cyclecounter *hw_cc)
+static u64 ixgbe_ptp_read_X550(const struct cyclecounter *cc)
{
struct ixgbe_adapter *adapter =
- container_of(hw_cc, struct ixgbe_adapter, hw_cc);
+ container_of(cc, struct ixgbe_adapter, hw_tc.cc);
struct ixgbe_hw *hw = &adapter->hw;
struct timespec64 ts;
@@ -285,7 +285,7 @@ static u64 ixgbe_ptp_read_X550(const struct cyclecounter *hw_cc)
static u64 ixgbe_ptp_read_82599(const struct cyclecounter *cc)
{
struct ixgbe_adapter *adapter =
- container_of(cc, struct ixgbe_adapter, hw_cc);
+ container_of(cc, struct ixgbe_adapter, hw_tc.cc);
struct ixgbe_hw *hw = &adapter->hw;
u64 stamp = 0;
@@ -508,7 +508,7 @@ static int ixgbe_ptp_settime(struct ptp_clock_info *ptp,
/* reset the timecounter */
spin_lock_irqsave(&adapter->tmreg_lock, flags);
- timecounter_init(&adapter->hw_tc, &adapter->hw_cc, ns);
+ timecounter_init(&adapter->hw_tc, ns);
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
if (adapter->ptp_setup_sdp)
@@ -1164,7 +1164,7 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
/* need lock to prevent incorrect read while modifying cyclecounter */
spin_lock_irqsave(&adapter->tmreg_lock, flags);
- memcpy(&adapter->hw_cc, &cc, sizeof(adapter->hw_cc));
+ memcpy(&adapter->hw_tc.cc, &cc, sizeof(adapter->hw_tc.cc));
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
}
@@ -1195,8 +1195,7 @@ void ixgbe_ptp_reset(struct ixgbe_adapter *adapter)
ixgbe_ptp_start_cyclecounter(adapter);
spin_lock_irqsave(&adapter->tmreg_lock, flags);
- timecounter_init(&adapter->hw_tc, &adapter->hw_cc,
- ktime_to_ns(ktime_get_real()));
+ timecounter_init(&adapter->hw_tc, ktime_to_ns(ktime_get_real()));
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
adapter->last_overflow_check = jiffies;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
index 0247885..35987b5 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
@@ -38,13 +38,13 @@
/* mlx4_en_read_clock - read raw cycle counter (to be used by time counter)
*/
-static u64 mlx4_en_read_clock(const struct cyclecounter *tc)
+static u64 mlx4_en_read_clock(const struct cyclecounter *cc)
{
struct mlx4_en_dev *mdev =
- container_of(tc, struct mlx4_en_dev, cycles);
+ container_of(cc, struct mlx4_en_dev, clock.cc);
struct mlx4_dev *dev = mdev->dev;
- return mlx4_read_clock(dev) & tc->mask;
+ return mlx4_read_clock(dev) & cc->mask;
}
u64 mlx4_en_get_cqe_ts(struct mlx4_cqe *cqe)
@@ -138,7 +138,7 @@ static int mlx4_en_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta)
write_seqlock_irqsave(&mdev->clock_lock, flags);
timecounter_read(&mdev->clock);
- mdev->cycles.mult = neg_adj ? mult - diff : mult + diff;
+ mdev->clock.cc.mult = neg_adj ? mult - diff : mult + diff;
write_sequnlock_irqrestore(&mdev->clock_lock, flags);
return 0;
@@ -207,7 +207,7 @@ static int mlx4_en_phc_settime(struct ptp_clock_info *ptp,
/* reset the timecounter */
write_seqlock_irqsave(&mdev->clock_lock, flags);
- timecounter_init(&mdev->clock, &mdev->cycles, ns);
+ timecounter_init(&mdev->clock, ns);
write_sequnlock_irqrestore(&mdev->clock_lock, flags);
return 0;
@@ -274,17 +274,17 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
seqlock_init(&mdev->clock_lock);
- memset(&mdev->cycles, 0, sizeof(mdev->cycles));
- mdev->cycles.read = mlx4_en_read_clock;
- mdev->cycles.mask = CLOCKSOURCE_MASK(48);
- mdev->cycles.shift = freq_to_shift(dev->caps.hca_core_clock);
- mdev->cycles.mult =
- clocksource_khz2mult(1000 * dev->caps.hca_core_clock, mdev->cycles.shift);
- mdev->nominal_c_mult = mdev->cycles.mult;
+ memset(&mdev->clock.cc, 0, sizeof(mdev->clock.cc));
+ mdev->clock.cc.read = mlx4_en_read_clock;
+ mdev->clock.cc.mask = CLOCKSOURCE_MASK(48);
+ mdev->clock.cc.shift = freq_to_shift(dev->caps.hca_core_clock);
+ mdev->clock.cc.mult =
+ clocksource_khz2mult(1000 * dev->caps.hca_core_clock,
+ mdev->clock.cc.shift);
+ mdev->nominal_c_mult = mdev->clock.cc.mult;
write_seqlock_irqsave(&mdev->clock_lock, flags);
- timecounter_init(&mdev->clock, &mdev->cycles,
- ktime_to_ns(ktime_get_real()));
+ timecounter_init(&mdev->clock, ktime_to_ns(ktime_get_real()));
write_sequnlock_irqrestore(&mdev->clock_lock, flags);
/* Configure the PHC */
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 1856e27..e301dcf 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -422,7 +422,6 @@ struct mlx4_en_dev {
spinlock_t uar_lock;
u8 mac_removed[MLX4_MAX_PORTS + 1];
u32 nominal_c_mult;
- struct cyclecounter cycles;
seqlock_t clock_lock;
struct timecounter clock;
unsigned long last_overflow_check;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
index fa8aed6..8cb6838 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
@@ -64,7 +64,7 @@ enum {
static u64 read_internal_timer(const struct cyclecounter *cc)
{
- struct mlx5_clock *clock = container_of(cc, struct mlx5_clock, cycles);
+ struct mlx5_clock *clock = container_of(cc, struct mlx5_clock, tc.cc);
struct mlx5_core_dev *mdev = container_of(clock, struct mlx5_core_dev,
clock);
@@ -122,7 +122,7 @@ static int mlx5_ptp_settime(struct ptp_clock_info *ptp,
unsigned long flags;
write_lock_irqsave(&clock->lock, flags);
- timecounter_init(&clock->tc, &clock->cycles, ns);
+ timecounter_init(&clock->tc, ns);
write_unlock_irqrestore(&clock->lock, flags);
return 0;
@@ -177,8 +177,8 @@ static int mlx5_ptp_adjfreq(struct ptp_clock_info *ptp, s32 delta)
write_lock_irqsave(&clock->lock, flags);
timecounter_read(&clock->tc);
- clock->cycles.mult = neg_adj ? clock->nominal_c_mult - diff :
- clock->nominal_c_mult + diff;
+ clock->tc.cc.mult = neg_adj ? clock->nominal_c_mult - diff :
+ clock->nominal_c_mult + diff;
write_unlock_irqrestore(&clock->lock, flags);
return 0;
@@ -281,8 +281,8 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
write_lock_irqsave(&clock->lock, flags);
nsec_now = timecounter_cyc2time(&clock->tc, cycles_now);
nsec_delta = ns - nsec_now;
- cycles_delta = div64_u64(nsec_delta << clock->cycles.shift,
- clock->cycles.mult);
+ cycles_delta = div64_u64(nsec_delta << clock->tc.cc.shift,
+ clock->tc.cc.mult);
write_unlock_irqrestore(&clock->lock, flags);
time_stamp = cycles_now + cycles_delta;
field_select = MLX5_MTPPS_FS_PIN_MODE |
@@ -440,8 +440,8 @@ void mlx5_pps_event(struct mlx5_core_dev *mdev,
write_lock_irqsave(&clock->lock, flags);
nsec_now = timecounter_cyc2time(&clock->tc, cycles_now);
nsec_delta = ns - nsec_now;
- cycles_delta = div64_u64(nsec_delta << clock->cycles.shift,
- clock->cycles.mult);
+ cycles_delta = div64_u64(nsec_delta << clock->tc.cc.shift,
+ clock->tc.cc.mult);
clock->pps_info.start[pin] = cycles_now + cycles_delta;
schedule_work(&clock->pps_info.out_work);
write_unlock_irqrestore(&clock->lock, flags);
@@ -454,6 +454,7 @@ void mlx5_pps_event(struct mlx5_core_dev *mdev,
void mlx5_init_clock(struct mlx5_core_dev *mdev)
{
struct mlx5_clock *clock = &mdev->clock;
+ struct cyclecounter *cc = &clock->tc.cc;
u64 ns;
u64 frac = 0;
u32 dev_freq;
@@ -464,21 +465,18 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev)
return;
}
rwlock_init(&clock->lock);
- clock->cycles.read = read_internal_timer;
- clock->cycles.shift = MLX5_CYCLES_SHIFT;
- clock->cycles.mult = clocksource_khz2mult(dev_freq,
- clock->cycles.shift);
- clock->nominal_c_mult = clock->cycles.mult;
- clock->cycles.mask = CLOCKSOURCE_MASK(41);
+ cc->read = read_internal_timer;
+ cc->shift = MLX5_CYCLES_SHIFT;
+ cc->mult = clocksource_khz2mult(dev_freq, cc->shift);
+ clock->nominal_c_mult = cc->mult;
+ cc->mask = CLOCKSOURCE_MASK(41);
- timecounter_init(&clock->tc, &clock->cycles,
- ktime_to_ns(ktime_get_real()));
+ timecounter_init(&clock->tc, ktime_to_ns(ktime_get_real()));
/* Calculate period in seconds to call the overflow watchdog - to make
* sure counter is checked at least once every wrap around.
*/
- ns = cyclecounter_cyc2ns(&clock->cycles, clock->cycles.mask,
- frac, &frac);
+ ns = cyclecounter_cyc2ns(cc, cc->mask, frac, &frac);
do_div(ns, NSEC_PER_SEC / 2 / HZ);
clock->overflow_period = ns;
diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.c b/drivers/net/ethernet/qlogic/qede/qede_ptp.c
index 9b2280b..95bb8a8 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ptp.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.c
@@ -34,7 +34,6 @@
struct qede_ptp {
const struct qed_eth_ptp_ops *ops;
struct ptp_clock_info clock_info;
- struct cyclecounter cc;
struct timecounter tc;
struct ptp_clock *clock;
struct work_struct work;
@@ -132,7 +131,7 @@ static int qede_ptp_settime(struct ptp_clock_info *info,
/* Re-init the timecounter */
spin_lock_bh(&ptp->lock);
- timecounter_init(&ptp->tc, &ptp->cc, ns);
+ timecounter_init(&ptp->tc, ns);
spin_unlock_bh(&ptp->lock);
return 0;
@@ -196,7 +195,7 @@ static u64 qede_ptp_read_cc(const struct cyclecounter *cc)
u64 phc_cycles;
int rc;
- ptp = container_of(cc, struct qede_ptp, cc);
+ ptp = container_of(cc, struct qede_ptp, tc.cc);
edev = ptp->edev;
rc = ptp->ops->read_cc(edev->cdev, &phc_cycles);
if (rc)
@@ -428,14 +427,13 @@ static int qede_ptp_init(struct qede_dev *edev, bool init_tc)
* unload / load (e.g. MTU change) while it is running.
*/
if (init_tc) {
- memset(&ptp->cc, 0, sizeof(ptp->cc));
- ptp->cc.read = qede_ptp_read_cc;
- ptp->cc.mask = CYCLECOUNTER_MASK(64);
- ptp->cc.shift = 0;
- ptp->cc.mult = 1;
-
- timecounter_init(&ptp->tc, &ptp->cc,
- ktime_to_ns(ktime_get_real()));
+ memset(&ptp->tc.cc, 0, sizeof(ptp->tc.cc));
+ ptp->tc.cc.read = qede_ptp_read_cc;
+ ptp->tc.cc.mask = CYCLECOUNTER_MASK(64);
+ ptp->tc.cc.shift = 0;
+ ptp->tc.cc.mult = 1;
+
+ timecounter_init(&ptp->tc, ktime_to_ns(ktime_get_real()));
}
return rc;
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index e7b76f6..b8fe843 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -182,7 +182,7 @@ static u64 cpts_systim_read(const struct cyclecounter *cc)
u64 val = 0;
struct cpts_event *event;
struct list_head *this, *next;
- struct cpts *cpts = container_of(cc, struct cpts, cc);
+ struct cpts *cpts = container_of(cc, struct cpts, tc.cc);
cpts_write32(cpts, TS_PUSH, ts_push);
if (cpts_fifo_read(cpts, CPTS_EV_PUSH))
@@ -224,7 +224,7 @@ static int cpts_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
timecounter_read(&cpts->tc);
- cpts->cc.mult = neg_adj ? mult - diff : mult + diff;
+ cpts->tc.cc.mult = neg_adj ? mult - diff : mult + diff;
spin_unlock_irqrestore(&cpts->lock, flags);
@@ -268,7 +268,7 @@ static int cpts_ptp_settime(struct ptp_clock_info *ptp,
ns = timespec64_to_ns(ts);
spin_lock_irqsave(&cpts->lock, flags);
- timecounter_init(&cpts->tc, &cpts->cc, ns);
+ timecounter_init(&cpts->tc, ns);
spin_unlock_irqrestore(&cpts->lock, flags);
return 0;
@@ -447,7 +447,7 @@ int cpts_register(struct cpts *cpts)
cpts_write32(cpts, CPTS_EN, control);
cpts_write32(cpts, TS_PEND_EN, int_enable);
- timecounter_init(&cpts->tc, &cpts->cc, ktime_to_ns(ktime_get_real()));
+ timecounter_init(&cpts->tc, ktime_to_ns(ktime_get_real()));
cpts->clock = ptp_clock_register(&cpts->info, cpts->dev);
if (IS_ERR(cpts->clock)) {
@@ -486,6 +486,7 @@ void cpts_unregister(struct cpts *cpts)
static void cpts_calc_mult_shift(struct cpts *cpts)
{
+ struct cyclecounter *cc = &cpts->tc.cc;
u64 frac, maxsec, ns;
u32 freq;
@@ -494,7 +495,7 @@ static void cpts_calc_mult_shift(struct cpts *cpts)
/* Calc the maximum number of seconds which we can run before
* wrapping around.
*/
- maxsec = cpts->cc.mask;
+ maxsec = cc->mask;
do_div(maxsec, freq);
/* limit conversation rate to 10 sec as higher values will produce
* too small mult factors and so reduce the conversion accuracy
@@ -507,18 +508,19 @@ static void cpts_calc_mult_shift(struct cpts *cpts)
dev_info(cpts->dev, "cpts: overflow check period %lu (jiffies)\n",
cpts->ov_check_period);
- if (cpts->cc.mult || cpts->cc.shift)
+ if (cc->mult || cc->shift)
return;
- clocks_calc_mult_shift(&cpts->cc.mult, &cpts->cc.shift,
+ clocks_calc_mult_shift(&cc->mult, &cc->shift,
freq, NSEC_PER_SEC, maxsec);
frac = 0;
- ns = cyclecounter_cyc2ns(&cpts->cc, freq, cpts->cc.mask, &frac);
+ ns = cyclecounter_cyc2ns(cc, freq, cc->mask, &frac);
dev_info(cpts->dev,
"CPTS: ref_clk_freq:%u calc_mult:%u calc_shift:%u error:%lld nsec/sec\n",
- freq, cpts->cc.mult, cpts->cc.shift, (ns - NSEC_PER_SEC));
+ freq, cc->mult, cc->shift,
+ (ns - NSEC_PER_SEC));
}
static int cpts_of_parse(struct cpts *cpts, struct device_node *node)
@@ -527,13 +529,13 @@ static int cpts_of_parse(struct cpts *cpts, struct device_node *node)
u32 prop;
if (!of_property_read_u32(node, "cpts_clock_mult", &prop))
- cpts->cc.mult = prop;
+ cpts->tc.cc.mult = prop;
if (!of_property_read_u32(node, "cpts_clock_shift", &prop))
- cpts->cc.shift = prop;
+ cpts->tc.cc.shift = prop;
- if ((cpts->cc.mult && !cpts->cc.shift) ||
- (!cpts->cc.mult && cpts->cc.shift))
+ if ((cpts->tc.cc.mult && !cpts->tc.cc.shift) ||
+ (!cpts->tc.cc.mult && cpts->tc.cc.shift))
goto of_error;
return 0;
@@ -569,15 +571,15 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs,
clk_prepare(cpts->refclk);
- cpts->cc.read = cpts_systim_read;
- cpts->cc.mask = CLOCKSOURCE_MASK(32);
+ cpts->tc.cc.read = cpts_systim_read;
+ cpts->tc.cc.mask = CLOCKSOURCE_MASK(32);
cpts->info = cpts_info;
cpts_calc_mult_shift(cpts);
- /* save cc.mult original value as it can be modified
+ /* save tc.cc.mult original value as it can be modified
* by cpts_ptp_adjfreq().
*/
- cpts->cc_mult = cpts->cc.mult;
+ cpts->cc_mult = cpts->tc.cc.mult;
return cpts;
}
diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h
index 73d73fa..a7174eb 100644
--- a/drivers/net/ethernet/ti/cpts.h
+++ b/drivers/net/ethernet/ti/cpts.h
@@ -117,7 +117,6 @@ struct cpts {
struct ptp_clock *clock;
spinlock_t lock; /* protects time registers */
u32 cc_mult; /* for the nominal frequency */
- struct cyclecounter cc;
struct timecounter tc;
int phc_index;
struct clk *refclk;
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index a886b51..c81c615 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -780,7 +780,6 @@ struct mlx5_pps {
struct mlx5_clock {
rwlock_t lock;
- struct cyclecounter cycles;
struct timecounter tc;
struct hwtstamp_config hwtstamp_config;
u32 nominal_c_mult;
diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h
index 2496ad4..6daca06 100644
--- a/include/linux/timecounter.h
+++ b/include/linux/timecounter.h
@@ -62,7 +62,7 @@ struct cyclecounter {
* @frac: accumulated fractional nanoseconds
*/
struct timecounter {
- const struct cyclecounter *cc;
+ struct cyclecounter cc;
u64 cycle_last;
u64 nsec;
u64 mask;
@@ -98,7 +98,6 @@ static inline void timecounter_adjtime(struct timecounter *tc, s64 delta)
/**
* timecounter_init - initialize a time counter
* @tc: Pointer to time counter which is to be initialized/reset
- * @cc: A cycle counter, ready to be used.
* @start_tstamp: Arbitrary initial time stamp.
*
* After this call the current cycle register (roughly) corresponds to
@@ -106,7 +105,6 @@ static inline void timecounter_adjtime(struct timecounter *tc, s64 delta)
* the time stamp counter by the number of elapsed nanoseconds.
*/
extern void timecounter_init(struct timecounter *tc,
- const struct cyclecounter *cc,
u64 start_tstamp);
/**
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 68169e3..3061f44 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -445,7 +445,6 @@ struct hdac_stream {
unsigned long start_wallclk; /* start + minimum wallclk */
unsigned long period_wallclk; /* wallclk for period */
struct timecounter tc;
- struct cyclecounter cc;
int delay_negative_threshold;
struct list_head list;
diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c
index 8afd789..7919acb 100644
--- a/kernel/time/timecounter.c
+++ b/kernel/time/timecounter.c
@@ -18,11 +18,10 @@
#include <linux/export.h>
#include <linux/timecounter.h>
-void timecounter_init(struct timecounter *tc,
- const struct cyclecounter *cc,
- u64 start_tstamp)
+void timecounter_init(struct timecounter *tc, u64 start_tstamp)
{
- tc->cc = cc;
+ struct cyclecounter *cc = &tc->cc;
+
tc->cycle_last = cc->read(cc);
tc->nsec = start_tstamp;
tc->mask = (1ULL << cc->shift) - 1;
@@ -43,17 +42,18 @@ void timecounter_init(struct timecounter *tc,
*/
static u64 timecounter_read_delta(struct timecounter *tc)
{
+ struct cyclecounter *cc = &tc->cc;
u64 cycle_now, cycle_delta;
u64 ns_offset;
/* read cycle counter: */
- cycle_now = tc->cc->read(tc->cc);
+ cycle_now = cc->read(cc);
/* calculate the delta since the last timecounter_read_delta(): */
- cycle_delta = (cycle_now - tc->cycle_last) & tc->cc->mask;
+ cycle_delta = (cycle_now - tc->cycle_last) & cc->mask;
/* convert to nanoseconds: */
- ns_offset = cyclecounter_cyc2ns(tc->cc, cycle_delta,
+ ns_offset = cyclecounter_cyc2ns(cc, cycle_delta,
tc->mask, &tc->frac);
/* update time stamp of timecounter_read_delta() call: */
@@ -89,10 +89,10 @@ static u64 cc_cyc2ns_backwards(const struct cyclecounter *cc,
return ns;
}
-u64 timecounter_cyc2time(struct timecounter *tc,
- u64 cycle_tstamp)
+u64 timecounter_cyc2time(struct timecounter *tc, u64 cycle_tstamp)
{
- u64 delta = (cycle_tstamp - tc->cycle_last) & tc->cc->mask;
+ struct cyclecounter *cc = &tc->cc;
+ u64 delta = (cycle_tstamp - tc->cycle_last) & cc->mask;
u64 nsec = tc->nsec, frac = tc->frac;
/*
@@ -100,11 +100,11 @@ u64 timecounter_cyc2time(struct timecounter *tc,
* than tc->cycle_last, detect when it is too far in the
* future and treat it as old time stamp instead.
*/
- if (delta > tc->cc->mask / 2) {
- delta = (tc->cycle_last - cycle_tstamp) & tc->cc->mask;
- nsec -= cc_cyc2ns_backwards(tc->cc, delta, tc->mask, frac);
+ if (delta > cc->mask / 2) {
+ delta = (tc->cycle_last - cycle_tstamp) & cc->mask;
+ nsec -= cc_cyc2ns_backwards(cc, delta, tc->mask, frac);
} else {
- nsec += cyclecounter_cyc2ns(tc->cc, delta, tc->mask, &frac);
+ nsec += cyclecounter_cyc2ns(cc, delta, tc->mask, &frac);
}
return nsec;
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index e1472c7..9426c1a 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -467,7 +467,8 @@ int snd_hdac_stream_set_params(struct hdac_stream *azx_dev,
static u64 azx_cc_read(const struct cyclecounter *cc)
{
- struct hdac_stream *azx_dev = container_of(cc, struct hdac_stream, cc);
+ struct hdac_stream *azx_dev = container_of(cc, struct hdac_stream,
+ tc.cc);
return snd_hdac_chip_readl(azx_dev->bus, WALLCLK);
}
@@ -476,7 +477,7 @@ static void azx_timecounter_init(struct hdac_stream *azx_dev,
bool force, u64 last)
{
struct timecounter *tc = &azx_dev->tc;
- struct cyclecounter *cc = &azx_dev->cc;
+ struct cyclecounter *cc = &azx_dev->tc.cc;
u64 nsec;
cc->read = azx_cc_read;
@@ -496,7 +497,7 @@ static void azx_timecounter_init(struct hdac_stream *azx_dev,
cc->shift = 0;
nsec = 0; /* audio time is elapsed time since trigger */
- timecounter_init(tc, cc, nsec);
+ timecounter_init(tc, nsec);
if (force) {
/*
* force timecounter to use predefined value,
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index f9555b1..5683c0c 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -53,7 +53,7 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level,
u64 kvm_phys_timer_read(void)
{
- return timecounter->cc->read(timecounter->cc);
+ return timecounter->cc.read(&timecounter->cc);
}
static void soft_timer_start(struct hrtimer *hrt, u64 ns)
@@ -138,7 +138,7 @@ static u64 kvm_timer_compute_delta(struct arch_timer_context *timer_ctx)
if (now < cval) {
u64 ns;
- ns = cyclecounter_cyc2ns(timecounter->cc,
+ ns = cyclecounter_cyc2ns(&timecounter->cc,
cval - now,
timecounter->mask,
&timecounter->frac);
@@ -728,7 +728,7 @@ int kvm_timer_hyp_init(void)
info = arch_timer_get_kvm_info();
timecounter = &info->timecounter;
- if (!timecounter->cc) {
+ if (!timecounter->cc.mask) {
kvm_err("kvm_arch_timer: uninitialized timecounter\n");
return -ENODEV;
}
--
1.9.1
^ permalink raw reply related
* DT dtc warnings
From: Krzysztof Kozlowski @ 2017-12-15 7:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215072921.GJ2559@piout.net>
On Fri, Dec 15, 2017 at 8:29 AM, Alexandre Belloni
<alexandre.belloni@free-electrons.com> wrote:
> On 15/12/2017 at 08:23:39 +0100, Krzysztof Kozlowski wrote:
>> On Fri, Dec 15, 2017 at 12:02 AM, Fabio Estevam <festevam@gmail.com> wrote:
>> > On Thu, Dec 14, 2017 at 7:19 PM, Krzysztof Kozlowski <krzk@kernel.org> wrote:
>> >
>> >> Thanks for reply!
>> >>
>> >> Isn't this property of a SoC? The registers used by
>> >> syscon-poweroff/reboot are part of SoC power management unit. It does
>> >> not refer to any externals. Why then it should be put outside of soc?
>> >
>> > If these nodes have registers, then they should have a unit address
>> > and reg property.
>>
>> That's the point - they do not have unit address.
>>
>
> Should they be put under the syscon they are using?
They are not using syscon but regmap provided by such external IP
block (for example this:
http://elixir.free-electrons.com/linux/v4.15-rc3/source/arch/arm/boot/dts/exynos3250.dtsi#L153).
I guess you are proposing something like on imx7s:
http://elixir.free-electrons.com/linux/v4.15-rc3/source/arch/arm/boot/dts/imx7s.dtsi#L539
That makes sense... I am not sure how this would be related to the
warning itself but anyway it looks logically.
Best regards,
Krzysztof
^ permalink raw reply
* DT dtc warnings
From: Alexandre Belloni @ 2017-12-15 7:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAJKOXPeqm-KRnuc7uUena=iH+rYLzSVSCb-uSbLB4SdRGqLRtw@mail.gmail.com>
On 15/12/2017 at 08:23:39 +0100, Krzysztof Kozlowski wrote:
> On Fri, Dec 15, 2017 at 12:02 AM, Fabio Estevam <festevam@gmail.com> wrote:
> > On Thu, Dec 14, 2017 at 7:19 PM, Krzysztof Kozlowski <krzk@kernel.org> wrote:
> >
> >> Thanks for reply!
> >>
> >> Isn't this property of a SoC? The registers used by
> >> syscon-poweroff/reboot are part of SoC power management unit. It does
> >> not refer to any externals. Why then it should be put outside of soc?
> >
> > If these nodes have registers, then they should have a unit address
> > and reg property.
>
> That's the point - they do not have unit address.
>
Should they be put under the syscon they are using?
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* DT dtc warnings
From: Krzysztof Kozlowski @ 2017-12-15 7:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOMZO5CKPhQwdkYBeu74k=RYBxGhVf13nnrzHXUhq8LWk8yBSg@mail.gmail.com>
On Fri, Dec 15, 2017 at 12:02 AM, Fabio Estevam <festevam@gmail.com> wrote:
> On Thu, Dec 14, 2017 at 7:19 PM, Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
>> Thanks for reply!
>>
>> Isn't this property of a SoC? The registers used by
>> syscon-poweroff/reboot are part of SoC power management unit. It does
>> not refer to any externals. Why then it should be put outside of soc?
>
> If these nodes have registers, then they should have a unit address
> and reg property.
That's the point - they do not have unit address.
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH v2 1/3] mmc: dt-bindings: add mmc support to MT7623 SoC
From: Ulf Hansson @ 2017-12-15 7:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <86e53802-9bb4-35eb-66e1-f9a401e31863@gmail.com>
On 14 December 2017 at 12:16, Matthias Brugger <matthias.bgg@gmail.com> wrote:
> Hi Ulf,
>
> On 12/07/2017 07:43 AM, sean.wang at mediatek.com wrote:
>> From: Sean Wang <sean.wang@mediatek.com>
>>
>> Add the devicetree binding for MT7623 SoC using MT2701 as the fallback.
>>
>> Cc: devicetree at vger.kernel.org
>> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
>> Acked-by: Rob Herring <robh@kernel.org>
>> ---
>> Documentation/devicetree/bindings/mmc/mtk-sd.txt | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
>> index 72d2a73..9b80176 100644
>> --- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
>> +++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
>> @@ -12,6 +12,8 @@ Required properties:
>> "mediatek,mt8173-mmc": for mmc host ip compatible with mt8173
>> "mediatek,mt2701-mmc": for mmc host ip compatible with mt2701
>> "mediatek,mt2712-mmc": for mmc host ip compatible with mt2712
>> + "mediatek,mt7623-mmc", "mediatek,mt2701-mmc": for MT7623 SoC
>> +
>> - reg: physical base address of the controller and length
>> - interrupts: Should contain MSDC interrupt number
>> - clocks: Should contain phandle for the clock feeding the MMC controller
>>
>
> Are you fine to take this patch through your branch, or shall I take it through
> mine?
I have pick it up, thanks!
>
> @Sean it seems you forgot to send this patch to Ulf as well. In the future
> please take care to send the patch to all relevant people and mailinglist.
Yeah, thanks for looping me in this time!
Kind regards
Uffe
^ permalink raw reply
* [RFC PATCH 0/7] gpiolib: add bias support
From: Ludovic Desroches @ 2017-12-15 6:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171214160625.GG19186@lunn.ch>
Hi Andrew,
On Thu, Dec 14, 2017 at 05:06:25PM +0100, Andrew Lunn wrote:
> > I have not introduced a gpiod_set_bias() because I think the only place to
> > setup this is in the device tree. It's useless to setup a bias pull up if there
> > is an external pull up on the board.
>
> Hi Ludovic
>
> I have a use case where having gpiod_set_bias() would be good. The
> DLN2 is a USB device, which offers GPIO, I2C, and SPI services on its
> pins. It is a hot pluggable device, and i'm using it on Intel
> machines, making it double hard to use with Device Tree.
>
> It would be good to be able to set the pull up/down on the GPIO pins,
> probably from a small kernel module which calls gpiod_set_bias(), or
> via /sysfs.
Thanks for your feedback. I'll try to keep your need in mind for next
version or rework.
Ludovic
>
> Andrew
> --
> To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v2 1/5] extcon: usbc-cros-ec: add support to notify USB type cables.
From: Chanwoo Choi @ 2017-12-15 6:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171213103219.1464-1-enric.balletbo@collabora.com>
Hi Enric,
Looks good to me. After reviewing the Lee Jones,
I'll take it on next branch.
Regards,
Chanwoo Choi
On 2017? 12? 13? 19:32, Enric Balletbo i Serra wrote:
> From: Benson Leung <bleung@chromium.org>
>
> Extend the driver to notify host and device type cables and the presence
> of power.
>
> Signed-off-by: Benson Leung <bleung@chromium.org>
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
> Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
> ---
> Changes since v1:
> - Use the BIT macro. Requested by Lee Jones.
> - Add the Reviewed-by: Chanwoo Choi.
>
> drivers/extcon/extcon-usbc-cros-ec.c | 142 ++++++++++++++++++++++++++++++++++-
> include/linux/mfd/cros_ec_commands.h | 17 +++++
> 2 files changed, 155 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/extcon/extcon-usbc-cros-ec.c b/drivers/extcon/extcon-usbc-cros-ec.c
> index 6187f73..6721ab0 100644
> --- a/drivers/extcon/extcon-usbc-cros-ec.c
> +++ b/drivers/extcon/extcon-usbc-cros-ec.c
> @@ -34,16 +34,26 @@ struct cros_ec_extcon_info {
>
> struct notifier_block notifier;
>
> + unsigned int dr; /* data role */
> + bool pr; /* power role (true if VBUS enabled) */
> bool dp; /* DisplayPort enabled */
> bool mux; /* SuperSpeed (usb3) enabled */
> unsigned int power_type;
> };
>
> static const unsigned int usb_type_c_cable[] = {
> + EXTCON_USB,
> + EXTCON_USB_HOST,
> EXTCON_DISP_DP,
> EXTCON_NONE,
> };
>
> +enum usb_data_roles {
> + DR_NONE,
> + DR_HOST,
> + DR_DEVICE,
> +};
> +
> /**
> * cros_ec_pd_command() - Send a command to the EC.
> * @info: pointer to struct cros_ec_extcon_info
> @@ -150,6 +160,7 @@ static int cros_ec_usb_get_role(struct cros_ec_extcon_info *info,
> pd_control.port = info->port_id;
> pd_control.role = USB_PD_CTRL_ROLE_NO_CHANGE;
> pd_control.mux = USB_PD_CTRL_MUX_NO_CHANGE;
> + pd_control.swap = USB_PD_CTRL_SWAP_NONE;
> ret = cros_ec_pd_command(info, EC_CMD_USB_PD_CONTROL, 1,
> &pd_control, sizeof(pd_control),
> &resp, sizeof(resp));
> @@ -183,11 +194,72 @@ static int cros_ec_pd_get_num_ports(struct cros_ec_extcon_info *info)
> return resp.num_ports;
> }
>
> +static const char *cros_ec_usb_role_string(unsigned int role)
> +{
> + return role == DR_NONE ? "DISCONNECTED" :
> + (role == DR_HOST ? "DFP" : "UFP");
> +}
> +
> +static const char *cros_ec_usb_power_type_string(unsigned int type)
> +{
> + switch (type) {
> + case USB_CHG_TYPE_NONE:
> + return "USB_CHG_TYPE_NONE";
> + case USB_CHG_TYPE_PD:
> + return "USB_CHG_TYPE_PD";
> + case USB_CHG_TYPE_PROPRIETARY:
> + return "USB_CHG_TYPE_PROPRIETARY";
> + case USB_CHG_TYPE_C:
> + return "USB_CHG_TYPE_C";
> + case USB_CHG_TYPE_BC12_DCP:
> + return "USB_CHG_TYPE_BC12_DCP";
> + case USB_CHG_TYPE_BC12_CDP:
> + return "USB_CHG_TYPE_BC12_CDP";
> + case USB_CHG_TYPE_BC12_SDP:
> + return "USB_CHG_TYPE_BC12_SDP";
> + case USB_CHG_TYPE_OTHER:
> + return "USB_CHG_TYPE_OTHER";
> + case USB_CHG_TYPE_VBUS:
> + return "USB_CHG_TYPE_VBUS";
> + case USB_CHG_TYPE_UNKNOWN:
> + return "USB_CHG_TYPE_UNKNOWN";
> + default:
> + return "USB_CHG_TYPE_UNKNOWN";
> + }
> +}
> +
> +static bool cros_ec_usb_power_type_is_wall_wart(unsigned int type,
> + unsigned int role)
> +{
> + switch (type) {
> + /* FIXME : Guppy, Donnettes, and other chargers will be miscategorized
> + * because they identify with USB_CHG_TYPE_C, but we can't return true
> + * here from that code because that breaks Suzy-Q and other kinds of
> + * USB Type-C cables and peripherals.
> + */
> + case USB_CHG_TYPE_PROPRIETARY:
> + case USB_CHG_TYPE_BC12_DCP:
> + return true;
> + case USB_CHG_TYPE_PD:
> + case USB_CHG_TYPE_C:
> + case USB_CHG_TYPE_BC12_CDP:
> + case USB_CHG_TYPE_BC12_SDP:
> + case USB_CHG_TYPE_OTHER:
> + case USB_CHG_TYPE_VBUS:
> + case USB_CHG_TYPE_UNKNOWN:
> + case USB_CHG_TYPE_NONE:
> + default:
> + return false;
> + }
> +}
> +
> static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info,
> bool force)
> {
> struct device *dev = info->dev;
> int role, power_type;
> + unsigned int dr = DR_NONE;
> + bool pr = false;
> bool polarity = false;
> bool dp = false;
> bool mux = false;
> @@ -206,9 +278,12 @@ static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info,
> dev_err(dev, "failed getting role err = %d\n", role);
> return role;
> }
> + dev_dbg(dev, "disconnected\n");
> } else {
> int pd_mux_state;
>
> + dr = (role & PD_CTRL_RESP_ROLE_DATA) ? DR_HOST : DR_DEVICE;
> + pr = (role & PD_CTRL_RESP_ROLE_POWER);
> pd_mux_state = cros_ec_usb_get_pd_mux_state(info);
> if (pd_mux_state < 0)
> pd_mux_state = USB_PD_MUX_USB_ENABLED;
> @@ -216,20 +291,62 @@ static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info,
> dp = pd_mux_state & USB_PD_MUX_DP_ENABLED;
> mux = pd_mux_state & USB_PD_MUX_USB_ENABLED;
> hpd = pd_mux_state & USB_PD_MUX_HPD_IRQ;
> - }
>
> - if (force || info->dp != dp || info->mux != mux ||
> - info->power_type != power_type) {
> + dev_dbg(dev,
> + "connected role 0x%x pwr type %d dr %d pr %d pol %d mux %d dp %d hpd %d\n",
> + role, power_type, dr, pr, polarity, mux, dp, hpd);
> + }
>
> + /*
> + * When there is no USB host (e.g. USB PD charger),
> + * we are not really a UFP for the AP.
> + */
> + if (dr == DR_DEVICE &&
> + cros_ec_usb_power_type_is_wall_wart(power_type, role))
> + dr = DR_NONE;
> +
> + if (force || info->dr != dr || info->pr != pr || info->dp != dp ||
> + info->mux != mux || info->power_type != power_type) {
> + bool host_connected = false, device_connected = false;
> +
> + dev_dbg(dev, "Type/Role switch! type = %s role = %s\n",
> + cros_ec_usb_power_type_string(power_type),
> + cros_ec_usb_role_string(dr));
> + info->dr = dr;
> + info->pr = pr;
> info->dp = dp;
> info->mux = mux;
> info->power_type = power_type;
>
> - extcon_set_state(info->edev, EXTCON_DISP_DP, dp);
> + if (dr == DR_DEVICE)
> + device_connected = true;
> + else if (dr == DR_HOST)
> + host_connected = true;
>
> + extcon_set_state(info->edev, EXTCON_USB, device_connected);
> + extcon_set_state(info->edev, EXTCON_USB_HOST, host_connected);
> + extcon_set_state(info->edev, EXTCON_DISP_DP, dp);
> + extcon_set_property(info->edev, EXTCON_USB,
> + EXTCON_PROP_USB_VBUS,
> + (union extcon_property_value)(int)pr);
> + extcon_set_property(info->edev, EXTCON_USB_HOST,
> + EXTCON_PROP_USB_VBUS,
> + (union extcon_property_value)(int)pr);
> + extcon_set_property(info->edev, EXTCON_USB,
> + EXTCON_PROP_USB_TYPEC_POLARITY,
> + (union extcon_property_value)(int)polarity);
> + extcon_set_property(info->edev, EXTCON_USB_HOST,
> + EXTCON_PROP_USB_TYPEC_POLARITY,
> + (union extcon_property_value)(int)polarity);
> extcon_set_property(info->edev, EXTCON_DISP_DP,
> EXTCON_PROP_USB_TYPEC_POLARITY,
> (union extcon_property_value)(int)polarity);
> + extcon_set_property(info->edev, EXTCON_USB,
> + EXTCON_PROP_USB_SS,
> + (union extcon_property_value)(int)mux);
> + extcon_set_property(info->edev, EXTCON_USB_HOST,
> + EXTCON_PROP_USB_SS,
> + (union extcon_property_value)(int)mux);
> extcon_set_property(info->edev, EXTCON_DISP_DP,
> EXTCON_PROP_USB_SS,
> (union extcon_property_value)(int)mux);
> @@ -237,6 +354,8 @@ static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info,
> EXTCON_PROP_DISP_HPD,
> (union extcon_property_value)(int)hpd);
>
> + extcon_sync(info->edev, EXTCON_USB);
> + extcon_sync(info->edev, EXTCON_USB_HOST);
> extcon_sync(info->edev, EXTCON_DISP_DP);
>
> } else if (hpd) {
> @@ -322,13 +441,28 @@ static int extcon_cros_ec_probe(struct platform_device *pdev)
> return ret;
> }
>
> + extcon_set_property_capability(info->edev, EXTCON_USB,
> + EXTCON_PROP_USB_VBUS);
> + extcon_set_property_capability(info->edev, EXTCON_USB_HOST,
> + EXTCON_PROP_USB_VBUS);
> + extcon_set_property_capability(info->edev, EXTCON_USB,
> + EXTCON_PROP_USB_TYPEC_POLARITY);
> + extcon_set_property_capability(info->edev, EXTCON_USB_HOST,
> + EXTCON_PROP_USB_TYPEC_POLARITY);
> extcon_set_property_capability(info->edev, EXTCON_DISP_DP,
> EXTCON_PROP_USB_TYPEC_POLARITY);
> + extcon_set_property_capability(info->edev, EXTCON_USB,
> + EXTCON_PROP_USB_SS);
> + extcon_set_property_capability(info->edev, EXTCON_USB_HOST,
> + EXTCON_PROP_USB_SS);
> extcon_set_property_capability(info->edev, EXTCON_DISP_DP,
> EXTCON_PROP_USB_SS);
> extcon_set_property_capability(info->edev, EXTCON_DISP_DP,
> EXTCON_PROP_DISP_HPD);
>
> + info->dr = DR_NONE;
> + info->pr = false;
> +
> platform_set_drvdata(pdev, info);
>
> /* Get PD events from the EC */
> diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h
> index 2b16e95..a83f649 100644
> --- a/include/linux/mfd/cros_ec_commands.h
> +++ b/include/linux/mfd/cros_ec_commands.h
> @@ -2904,16 +2904,33 @@ enum usb_pd_control_mux {
> USB_PD_CTRL_MUX_AUTO = 5,
> };
>
> +enum usb_pd_control_swap {
> + USB_PD_CTRL_SWAP_NONE = 0,
> + USB_PD_CTRL_SWAP_DATA = 1,
> + USB_PD_CTRL_SWAP_POWER = 2,
> + USB_PD_CTRL_SWAP_VCONN = 3,
> + USB_PD_CTRL_SWAP_COUNT
> +};
> +
> struct ec_params_usb_pd_control {
> uint8_t port;
> uint8_t role;
> uint8_t mux;
> + uint8_t swap;
> } __packed;
>
> #define PD_CTRL_RESP_ENABLED_COMMS (1 << 0) /* Communication enabled */
> #define PD_CTRL_RESP_ENABLED_CONNECTED (1 << 1) /* Device connected */
> #define PD_CTRL_RESP_ENABLED_PD_CAPABLE (1 << 2) /* Partner is PD capable */
>
> +#define PD_CTRL_RESP_ROLE_POWER BIT(0) /* 0=SNK/1=SRC */
> +#define PD_CTRL_RESP_ROLE_DATA BIT(1) /* 0=UFP/1=DFP */
> +#define PD_CTRL_RESP_ROLE_VCONN BIT(2) /* Vconn status */
> +#define PD_CTRL_RESP_ROLE_DR_POWER BIT(3) /* Partner is dualrole power */
> +#define PD_CTRL_RESP_ROLE_DR_DATA BIT(4) /* Partner is dualrole data */
> +#define PD_CTRL_RESP_ROLE_USB_COMM BIT(5) /* Partner USB comm capable */
> +#define PD_CTRL_RESP_ROLE_EXT_POWERED BIT(6) /* Partner externally powerd */
> +
> struct ec_response_usb_pd_control_v1 {
> uint8_t enabled;
> uint8_t role;
>
--
Best Regards,
Chanwoo Choi
Samsung Electronics
^ permalink raw reply
* WARNING: suspicious RCU usage
From: Paul E. McKenney @ 2017-12-15 6:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171213091245.GH10595@n2100.armlinux.org.uk>
On Wed, Dec 13, 2017 at 09:12:45AM +0000, Russell King - ARM Linux wrote:
> On Tue, Dec 12, 2017 at 04:11:07PM -0200, Fabio Estevam wrote:
> > Hi Russell,
> >
> > On Tue, Dec 12, 2017 at 3:34 PM, Russell King - ARM Linux
> > <linux@armlinux.org.uk> wrote:
> >
> > > It's fundamentally unsafe.
> > >
> > > You need to test with CONFIG_BL_SWITCHER enabled - there's spinlocks
> > > in smp_call_function_single() path that are conditional on that symbol.
> > > If CONFIG_BL_SWITCHER is disabled, then the spinlocks are not present.
> >
> > Ok, just tested with CONFIG_BL_SWITCHER=y on a imx6q-cubox-i:
> >
> > # echo enabled > /sys/class/tty/ttymxc0/power/wakeup
> > # echo mem > /sys/power/state
> > [ 10.503462] PM: suspend entry (deep)
> > [ 10.507479] PM: Syncing filesystems ... done.
> > [ 10.555024] Freezing user space processes ... (elapsed 0.002 seconds) done.
> > [ 10.564511] OOM killer disabled.
> > [ 10.567760] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) d.
> > [ 10.577420] Suspending console(s) (use no_console_suspend to debug)
> > [ 10.657748] PM: suspend devices took 0.080 seconds
> > [ 10.669329] Disabling non-boot CPUs ...
> > [ 10.717049] IRQ17 no longer affine to CPU1
> > [ 10.837141] Enabling non-boot CPUs ...
> > [ 10.839386] CPU1 is up
> > [ 10.840342] CPU2 is up
> > [ 10.841300] CPU3 is up
> > [ 11.113735] mmc0: queuing unknown CIS tuple 0x80 (2 bytes)
> > [ 11.115676] mmc0: queuing unknown CIS tuple 0x80 (3 bytes)
> > [ 11.117595] mmc0: queuing unknown CIS tuple 0x80 (3 bytes)
> > [ 11.121014] mmc0: queuing unknown CIS tuple 0x80 (7 bytes)
> > [ 11.124454] mmc0: queuing unknown CIS tuple 0x80 (7 bytes)
> > [ 11.177299] ata1: SATA link down (SStatus 0 SControl 300)
> > [ 11.181930] PM: resume devices took 0.330 seconds
> > [ 11.243729] OOM killer enabled.
> > [ 11.246886] Restarting tasks ... done.
> > [ 11.253012] PM: suspend exit
>
> Right, one test. What makes this safe, and what does this prove?
>
> It's probably worth quoting a discussion I had with Will Deacon on
> this subject back in 2013 - it's on that complete(), but the points
> discussed there are entirely relevant to the spinlock in the GIC
> code.
>
> imx6 won't see a problem because you have additional synchronisation
> between the calling CPU and the dying CPU, so I'm afraid that any
> testing done on imx6 is meaningless wrt the safety of Paul's change
> from an architecture point of view.
>
> And that's the problem - once that complete() happens, the dying CPU
> can have power removed _at any moment_, and that could happen when
> the cache line for "cpu_map_lock" in drivers/irqchip/irq-gic.c is
> owned by the dying CPU.
>
> If you read the discussion below, that was one of Will's concerns
> with using complete() before we nailed down complete() works. I'm
> sorry, but I'm not wrapping this...
No worries! It is quite legible here. Additional questions and (you
guessed it!) another patch below.
> 18:00 < rmk> wildea01: can you think of any reason not to use flush_cache_louis() in cpu_die() ?
> 18:20 < wildea01> let me see...
> 18:20 < rmk> what I'm thinking of is:
> 18:20 < rmk> idle_task_exit();
> 18:20 < rmk> local_irq_disable();
> 18:20 < rmk> flush_cache_louis();
> 18:20 < rmk> mb();
> 18:20 < rmk> RCU_NONIDLE(complete(&cpu_died));
> 18:20 < rmk> mb();
> 18:20 < rmk> if (smp_ops.cpu_die)
> 18:20 < rmk> smp_ops.cpu_die(cpu);
> 18:21 < rmk> and then killing most of the flush_cache_all() calls in smp_ops.cpu_die()
> 18:22 < rmk> the only thing I haven't worked out is why some places disable the L1 cache and then flush - especially as that can make any dirty data in the L1 cache suddenly vanish from the CPUs visibility
> 18:22 < wildea01> might need to be careful with the completion
> 18:23 < rmk> that's why the mb() is there - another CPU will read the cpu_died thing which means it must have become visible to the other CPUs
> 18:24 < wildea01> but the cacheline could still be exclusive in our L1 I think
> 18:24 < rmk> how? surely it must have become shared because another CPU has read from it?
OK, I am taking this as meaning that is is OK for the outgoing CPU to
be powered off with unflushed data in its cache, as long as that data is
shared so that some other CPU has a copy. In that case, the disappearance
of the outgoing CPU's copy is a non-problem, correct?
> 18:25 < wildea01> I'm thinking of the spin lock -- can we guarantee that another core will have read that before we turn off our cache?
> 18:27 < rmk> well, can we get out of wait_for_completion without the spin lock having been unlocked?
> 18:27 < rmk> one of the points of completions is that it should be safe for stuff like this
> 18:59 < rmk> yes, one of the things that wait_for_completion/complete was invented for was for synchronising a kernel thread exit with cleaning up after it
> 19:01 < rmk> and if you look at the above functions, the spinlock can't be owned by the CPU calling complete() because wait_for_completion() must reacquire it after complete() has woken the wait_for_completion thread u p
> 19:04 < rmk> well, I just tried it out on omap4430 and it seems to work fine
> 19:04 < wildea01> rmk: but complete does a spin_unlock_irqrestore(&x->wait.lock, flags);, now if that sits exclusive in our cache and we power-off before the waiting CPU gets the lock, then we're dead
> 19:04 < rmk> yes it does, but...
> 19:04 < wildea01> maybe that's so incredibly unlikely that we don't mind
> 19:04 < rmk> the other CPU must exit wait_for_completion()
> 19:05 < rmk> which involves reading/writing that lock too
> 19:05 < rmk> spin_lock_irq(&x->wait.lock);
> 19:05 < rmk> } while (!x->done && timeout);
> 19:05 < rmk> __remove_wait_queue(&x->wait, &wait);
> 19:05 < rmk> }
> 19:05 < rmk> x->done--;
> 19:05 < rmk> return timeout ?: 1;
> 19:05 < rmk> spin_unlock_irq(&x->wait.lock);
> 19:06 < wildea01> hmm, where is that code?
> 19:06 < rmk> will all be executed on another CPU after that spin_unlock
> 19:06 < rmk> wait_for_completion->wait_for_common->__wait_for_common->do_wait_for_common
> 19:07 < wildea01> gotcha, I didn't go as far as do_wait_for_common
> 19:07 * wildea01 scrolls up
> 19:07 < rmk> the bits I quoted is the exit path from do_wait_for_common back to wait_for_completion
> 19:15 < wildea01> I guess the only bit I'm missing is why the the other CPU must exit wait_for_completion before we can proceed with the cpu_die
> 19:16 < rmk> wrong way round.
> 19:16 < rmk> complete() must exit completely and be visible before wait_for_completion can return
> 19:17 < rmk> so there's no way that platform_cpu_kill() can end up being called before that complete() has unlocked that spinlock
> 19:17 < rmk> and as platform_cpu_kill() is what should be removing power to the dead CPU
> 19:17 < wildea01> but I don't see how we can guarantee that the other guy has read it
> 19:17 < wildea01> he might be *just* about to read it
> 19:18 < wildea01> but it might not have happened
> 19:18 < rmk> if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) {
> 19:18 < rmk> }
> 19:18 < rmk> printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
> 19:18 < rmk> you can't get to that printk until complete() has unlocked the completions spinlock.
And a read-modify-write atomic (LDREX/STREX pair) is guaranteed to
pull the corresponding cache line out of the outgoing CPU's cache,
thus preserving the values in that cache line for posterity.
> 19:18 < wildea01> agreed
> 19:18 < rmk> and that unlock has become visible to the CPU executing the above code
> 19:19 < wildea01> wait a second: I'm assuming that cpu_die is killing the lights, which some people seem to do iirc?
> 19:20 < wildea01> if that's all done in platform_cpu_kill, then I think we're ok19:20 < wildea01> as you say
> 19:20 < rmk> indeed.
> 19:20 < rmk> it actually depends on how the offlining works.
> 19:20 < wildea01> so the question is: are there smp_ops.cpu_die which hit the power controller?
> 19:20 < rmk> yes, but weirdly... because the CPU goes into dead mode when it executes the WFI
> 19:21 < wildea01> yeah, there's some signal that goes high when that happens, so people like to tie that to the power switch
> 19:22 < rmk> but that is also fine, because if that's what triggers the power off, we will get there anyway (because platform_cpu_kill won't do that)
> 19:22 < rmk> err, won't kill the power
> 19:24 < wildea01> hmm, not sure I follow
> 19:24 < wildea01> highbank does what you're saying, so we could take that as an example
> 19:25 < wildea01> (pretending that the cache flush isn't there)
> 19:26 < rmk> ok.
> 19:26 < rmk> so what will happen is...
> 19:27 < rmk> one CPU (not the dying CPU) will end up calling __cpu_die()
> 19:27 < rmk> the dying CPU will call cpu_die()
> 19:27 < wildea01> yup
> 19:27 < rmk> lets call the first one the calling CPU (even though it may not be)
> 19:28 < wildea01> sure -- it's the guy waiting for the offline to happen
> 19:28 < rmk> the calling CPU calls into wait_for_completion_timeout() and sits there waiting for the dying CPU to call that complete()
> 19:28 < rmk> meanwhile, the dying CPU does the idle task exit, disables IRQs, and flushes its caches of any dirty data.
> 19:29 < rmk> now, the calling CPU has had to take the completion's spinlock, check the counter, release the spinlock, and is waiting for the completion...
> 19:30 < rmk> so, the dying CPU takes the spinlock, increments the counter, and triggers a wakeup of the calling CPU, and then releases the spinlock.
> 19:30 < wildea01> yep
> 19:30 < rmk> the dying CPU now has dirty cache lines again which it probably exclusively owns
> 19:30 < wildea01> at this point, can we assume that the calling CPU goes off to handle an interrupt or something?
> 19:31 < rmk> it can do, it could even be the scheduler IPI
> 19:31 < wildea01> good
> 19:31 < wildea01> so the dying CPU can proceed past the complete(, with the calling CPU occupied somewhere else
> 19:31 < rmk> it can do, yes.
> 19:32 < wildea01> and off into smp_ops.cpu_die => highbank_cpu_die
> 19:32 < rmk> *OH*, I see what you're getting at
> 19:32 < wildea01> :)
> 19:33 < rmk> hmm, how can we get around that...
> 19:34 < wildea01> it's tricky, because platform_cpu_kill runs on the caller cpu
> 19:34 < rmk> because, in the case where the power is cut from platform_cpu_kill(), the dying CPU can loose power at any point after that complete()
> 19:34 < wildea01> so we'd need to split up the `next wfi on core n should kill it' from the `here's my wfi'
> 19:36 < rmk> I think we could do another flush_cache_louis() after it
> 19:37 < rmk> if, in the case of platform_cpu_kill() doing the killing of the CPU, that should be fine.
So CPUs that power themselves off are responsible for flushing their own
caches. Makes sense.
> 19:37 < wildea01> actually... why do we even need the one before it?
> 19:37 < wildea01> why not just have one after the complete has returned?
> 19:37 < rmk> because if platform_cpu_kill() is the call which removes the power, we need to ensure the cache contents have been written out
> 19:38 < wildea01> ah yeah, I was thinking of requiring both the kill and the die in order for the powerdown, but that's not alwasy necessary
> 19:38 < wildea01> *always
> 19:38 < wildea01> last time I checked, nobody used plaform_cpu_kill
> 19:39 < rmk> umm, lots do
> 19:39 < rmk> and some do use it to do stuff
> 19:39 < wildea01> damn, I must've been thinking of something else
> 19:40 < rmk> well, imx and tegra seem to, but they have their own custom waits implemented probably because of the lack of cache handling in the generic code
> 19:42 < wildea01> I don't know enough about tegra to understand why their kill and die don't race
> 19:44 < rmk> ok, looking at the locking barrier doc, we don't need the mb() after the complete() call
> 19:44 < rmk> but I think to address your concern, we must have another flush_cache_louis() there
> 19:44 < wildea01> yeah, the unlock should give you that mb
> 19:45 < wildea01> just seems a shame to have two flushes when they're not usually both needed
> 19:45 < wildea01> (he assumes)
> 19:45 < wildea01> like I said, the tegra could looks broken to me
> 19:45 < wildea01> *code
> 19:45 < rmk> if we had a louis() version which could flush the cpu_died completion...
> 19:51 < wildea01> do we even need the mb before the complete?
> 19:52 < rmk> I've been debating about that, and I think not
> 19:52 < rmk> I'm just augmenting this with comments as well
> 19:53 < wildea01> good thinking, I think we've established that it's not simple to understand!
> 19:59 < rmk> http://www.home.arm.linux.org.uk/~rmk/misc/smp-hotplug.diff
> 19:59 < rmk> new version of it with lots of comments :)
> 20:03 < wildea01> looks good to me. The additional flush is a pity, but required, and it's hotplug-off anyway, so not exactly speedy
> 20:03 < wildea01> one typo in a comment: s/loosing/losing/
So for the lock word, the trick is that when acquiring the lock requires
an LDREX/STREX pair, the act of acquiring that lock will remove the lock
word from the outgoing CPU's cache. Cute!
Also, as long as a given cacheline is in shared state (so that there
is another copy of it in some other CPU's cache), it is OK to power off
the outgoing CPU without flushing that shared-state cacheline.
A few questions, as always, for the case where the outgoing CPU is
powered down before it executes any instructions following the return
from complete():
1. It is possible that complete() and the functions that it invokes
might write to the outgoing CPU's stack, which could result
in those lines becoming exclusive in the outgoing CPU's cache.
My guess is that the surviving CPU won't extract the corresponding
lines from the outgoing CPU's cache. Is this correct?
(I could imagine forgiving cache-coherence hardware just reading
old values from memory, which might be OK for the stack because
no one should care about the data that the outgoing CPU wrote
just before being powered off. Or maybe something else is
going on.)
2. The complete() function also updates the ->done field of the
completion structure. This is OK because it is in the same
cacheline as the lock?
3. The try_to_wake_up() function that can be invoked indirectly
by complete() writes to a number of fields in the task struct
of the task blocked in wait_for_completion(). What ensures
that the corresponding cachelines are flushed from the outgoing
CPU's cache? (I know that some of them are read by the scheduler
on the CPU on which the task is being awakened (which puts them
in shared state, thus preserving them), but it is not clear that
this is the case for all of them, particularly statistics.)
There are probably other questions, but those are the ones that come to
mind at the moment.
For your amusement, I have a patch below that takes a paranoid view of
the possible answers to these questions. This patch is untested and
probably does not even build. Plus its polling loop is quite naive.
On the other hand, given the info in the IRC log, it seems like it
should provide a very robust guarantee that no data gets stranded in
the outgoing CPU's cache.
Thanx, Paul
------------------------------------------------------------------------
commit 6c9e28385ce1417628c4f2e58c078b723f35d62a
Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Date: Mon Dec 11 09:40:58 2017 -0800
ARM: CPU hotplug: Delegate complete() to surviving CPU
The ARM implementation of arch_cpu_idle_dead() invokes complete(), but
does so after RCU has stopped watching the outgoing CPU, which results
in lockdep complaints because complete() invokes functions containing RCU
readers. In addition, if the outgoing CPU really were to consume several
seconds of its five-second allotted time, multiple RCU updates could
complete, possibly giving the outgoing CPU an inconsistent view of the
scheduler data structures on which complete() relies.
This (untested, probably does not build) commit avoids this problem by
polling the outgoing CPU. The polling strategy in this prototype patch
is quite naive, with one jiffy between each poll and without any sort of
adaptive spin phase. The key point is that the polling CPU uses xchg(),
which evicts the flag from the outgoing CPU's cache. The outgoing CPU
simply does a WRITE_ONCE(), which minimizes opportunities for other data
to get pulled into the outgoing CPU's cache. This pulling of values
from the outgoing CPU's cache is important because the outgoing CPU
might be unceremoniously powered off before it has time to execute any
code after the WRITE_ONCE().
Reported-by: Peng Fan <van.freenix@gmail.com>
Reported-by: Russell King - ARM Linux <linux@armlinux.org.uk>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: <linux-arm-kernel@lists.infradead.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index b4fbf00ee4ad..da363923503b 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -241,7 +241,7 @@ int __cpu_disable(void)
return 0;
}
-static DECLARE_COMPLETION(cpu_died);
+static char cpu_died;
/*
* called on the thread which is asking for a CPU to be shutdown -
@@ -249,7 +249,16 @@ static DECLARE_COMPLETION(cpu_died);
*/
void __cpu_die(unsigned int cpu)
{
- if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) {
+ unsigned long deadline = jiffies + msecs_to_jiffies(5000);
+ char ret;
+
+ while (time_before(jiffies, deadline)) {
+ ret = xchg(&cpu_died, 0);
+ if (ret)
+ break;
+ schedule_timeout_interruptible(1);
+ }
+ if (!ret) {
pr_err("CPU%u: cpu didn't die\n", cpu);
return;
}
@@ -295,7 +304,7 @@ void arch_cpu_idle_dead(void)
* this returns, power and/or clocks can be removed at any point
* from this CPU and its cache by platform_cpu_kill().
*/
- complete(&cpu_died);
+ WRITE_ONCE(cpu_died, 1);
/*
* Ensure that the cache lines associated with that completion are
^ permalink raw reply related
* mail-list subscription issue
From: Prabhakar Kushwaha @ 2017-12-15 6:24 UTC (permalink / raw)
To: linux-arm-kernel
Hello
We are not able to subscribe to mailto:linux-arm-kernel at lists.infradead.org.
We also tried on linux-mtd at lists.infradead.org.
We even tried with personal mail id but no success.
Seems specific to infradead.org.
Any pointers?
--prabhakar
^ permalink raw reply
* [PATCH v2 19/19] ARM: dts: aspeed-plametto: Add flash layout
From: Joel Stanley @ 2017-12-15 6:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215062443.23059-1-joel@jms.id.au>
The OpenBMC flash layout is used by Palmetto systems.
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts
index a8f0c046e83e..cc18137386f2 100644
--- a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts
@@ -34,6 +34,7 @@
status = "okay";
m25p,fast-read;
label = "bmc";
+#include "openbmc-flash-layout.dtsi"
};
};
--
2.14.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox