* Re: [PATCH v2 3/3] Input: pwm-beeper: add optional amplifier regulator
From: David Lechner @ 2017-01-16 0:12 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: linux-input, devicetree, Rob Herring, Mark Rutland, linux-kernel
In-Reply-To: <20170114191943.GC31309@dtor-ws>
On 01/14/2017 01:19 PM, Dmitry Torokhov wrote:
> On Wed, Jan 11, 2017 at 02:02:01PM -0600, David Lechner wrote:
>> This adds an optional regulator to the pwm-beeper device. This regulator
>> acts as an amplifier. The amplifier is only enabled while beeping in order
>> to reduce power consumption.
>>
>> Tested on LEGO MINDSTORMS EV3, which has a speaker connected to PWM through
>> an amplifier.
>>
>> Signed-off-by: David Lechner <david@lechnology.com>
>> ---
>> drivers/input/misc/pwm-beeper.c | 29 ++++++++++++++++++++++++++++-
>> 1 file changed, 28 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c
>> index 30ac227..708e88e 100644
>> --- a/drivers/input/misc/pwm-beeper.c
>> +++ b/drivers/input/misc/pwm-beeper.c
>> @@ -14,6 +14,7 @@
>> */
>>
>> #include <linux/input.h>
>> +#include <linux/regulator/consumer.h>
>> #include <linux/module.h>
>> #include <linux/kernel.h>
>> #include <linux/of.h>
>> @@ -25,8 +26,10 @@
>> struct pwm_beeper {
>> struct input_dev *input;
>> struct pwm_device *pwm;
>> + struct regulator *reg;
>> struct work_struct work;
>> unsigned long period;
>> + bool reg_enabled;
>> };
>>
>> #define HZ_TO_NANOSECONDS(x) (1000000000UL/(x))
>> @@ -38,8 +41,20 @@ static void __pwm_beeper_set(struct pwm_beeper *beeper)
>> if (period) {
>> pwm_config(beeper->pwm, period / 2, period);
>> pwm_enable(beeper->pwm);
>> - } else
>> + if (beeper->reg) {
>> + int error;
>> +
>> + error = regulator_enable(beeper->reg);
>> + if (!error)
>> + beeper->reg_enabled = true;
>> + }
>> + } else {
>> + if (beeper->reg_enabled) {
>> + regulator_disable(beeper->reg);
>> + beeper->reg_enabled = false;
>> + }
>> pwm_disable(beeper->pwm);
>> + }
>> }
>>
>> static void pwm_beeper_work(struct work_struct *work)
>> @@ -82,6 +97,10 @@ static void pwm_beeper_stop(struct pwm_beeper *beeper)
>> {
>> cancel_work_sync(&beeper->work);
>>
>> + if (beeper->reg_enabled) {
>> + regulator_disable(beeper->reg);
>> + beeper->reg_enabled = false;
>> + }
>> if (beeper->period)
>> pwm_disable(beeper->pwm);
>> }
>> @@ -111,6 +130,14 @@ static int pwm_beeper_probe(struct platform_device *pdev)
>> return error;
>> }
>>
>> + beeper->reg = devm_regulator_get_optional(&pdev->dev, "amp");
>
> If you do not use optional regulator then you will not have to check if
> you have it or not everywhere: regulator core will give you a dummy that
> you can toggle to your heart's content.
Some months ago, I learned that if you are not using device tree and you
do not call regulator_has_full_constraints(), then you do not get a
dummy regulator. And here, we are only checking if the regulator exists
in one place. We will still need the checks for beeper->reg_enabled to
keep calls to regulator_enable() and regulator_disable() balanced.
On the other hand, it is recommended that you always call
regulator_has_full_constraints(), so I don't mind changing it if that is
what you think we should do. But, I don't really see much of an
advantage to changing it compared to the current implementation.
>
>> + error = PTR_ERR_OR_ZERO(beeper->reg);
>> + if (error) {
>> + if (error != -EPROBE_DEFER)
>> + dev_err(dev, "Failed to get amp regulator\n");
>> + return error;
>> + }
>> +
>> /*
>> * FIXME: pwm_apply_args() should be removed when switching to
>> * the atomic PWM API.
>> --
>> 2.7.4
>>
>
> Thanks.
>
^ permalink raw reply
* Re: [PATCH v2 3/3] Input: pwm-beeper: add optional amplifier regulator
From: Dmitry Torokhov @ 2017-01-16 0:34 UTC (permalink / raw)
To: David Lechner
Cc: linux-input, devicetree, Rob Herring, Mark Rutland, linux-kernel
In-Reply-To: <a907970d-3ab9-69df-9636-54c2b660cff9@lechnology.com>
On Sun, Jan 15, 2017 at 06:12:29PM -0600, David Lechner wrote:
> On 01/14/2017 01:19 PM, Dmitry Torokhov wrote:
> >On Wed, Jan 11, 2017 at 02:02:01PM -0600, David Lechner wrote:
> >>This adds an optional regulator to the pwm-beeper device. This regulator
> >>acts as an amplifier. The amplifier is only enabled while beeping in order
> >>to reduce power consumption.
> >>
> >>Tested on LEGO MINDSTORMS EV3, which has a speaker connected to PWM through
> >>an amplifier.
> >>
> >>Signed-off-by: David Lechner <david@lechnology.com>
> >>---
> >> drivers/input/misc/pwm-beeper.c | 29 ++++++++++++++++++++++++++++-
> >> 1 file changed, 28 insertions(+), 1 deletion(-)
> >>
> >>diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c
> >>index 30ac227..708e88e 100644
> >>--- a/drivers/input/misc/pwm-beeper.c
> >>+++ b/drivers/input/misc/pwm-beeper.c
> >>@@ -14,6 +14,7 @@
> >> */
> >>
> >> #include <linux/input.h>
> >>+#include <linux/regulator/consumer.h>
> >> #include <linux/module.h>
> >> #include <linux/kernel.h>
> >> #include <linux/of.h>
> >>@@ -25,8 +26,10 @@
> >> struct pwm_beeper {
> >> struct input_dev *input;
> >> struct pwm_device *pwm;
> >>+ struct regulator *reg;
> >> struct work_struct work;
> >> unsigned long period;
> >>+ bool reg_enabled;
> >> };
> >>
> >> #define HZ_TO_NANOSECONDS(x) (1000000000UL/(x))
> >>@@ -38,8 +41,20 @@ static void __pwm_beeper_set(struct pwm_beeper *beeper)
> >> if (period) {
> >> pwm_config(beeper->pwm, period / 2, period);
> >> pwm_enable(beeper->pwm);
> >>- } else
> >>+ if (beeper->reg) {
> >>+ int error;
> >>+
> >>+ error = regulator_enable(beeper->reg);
> >>+ if (!error)
> >>+ beeper->reg_enabled = true;
> >>+ }
> >>+ } else {
> >>+ if (beeper->reg_enabled) {
> >>+ regulator_disable(beeper->reg);
> >>+ beeper->reg_enabled = false;
> >>+ }
> >> pwm_disable(beeper->pwm);
> >>+ }
> >> }
> >>
> >> static void pwm_beeper_work(struct work_struct *work)
> >>@@ -82,6 +97,10 @@ static void pwm_beeper_stop(struct pwm_beeper *beeper)
> >> {
> >> cancel_work_sync(&beeper->work);
> >>
> >>+ if (beeper->reg_enabled) {
> >>+ regulator_disable(beeper->reg);
> >>+ beeper->reg_enabled = false;
> >>+ }
> >> if (beeper->period)
> >> pwm_disable(beeper->pwm);
> >> }
> >>@@ -111,6 +130,14 @@ static int pwm_beeper_probe(struct platform_device *pdev)
> >> return error;
> >> }
> >>
> >>+ beeper->reg = devm_regulator_get_optional(&pdev->dev, "amp");
> >
> >If you do not use optional regulator then you will not have to check if
> >you have it or not everywhere: regulator core will give you a dummy that
> >you can toggle to your heart's content.
>
> Some months ago, I learned that if you are not using device tree and
> you do not call regulator_has_full_constraints(), then you do not
> get a dummy regulator. And here, we are only checking if the
> regulator exists in one place. We will still need the checks for
> beeper->reg_enabled to keep calls to regulator_enable() and
> regulator_disable() balanced.
Why? You do not have checks for calls to pwm_enable() and pwm_disable(),
(or rather beeper->period is used as such flag) why regulator would be
any different?
>
> On the other hand, it is recommended that you always call
> regulator_has_full_constraints(), so I don't mind changing it if
> that is what you think we should do. But, I don't really see much of
> an advantage to changing it compared to the current implementation.
It greatly simplifies control flow in the driver (since I believe you
can get rid of the flags you introduced).
As far as arch not having full constraints - I am not sure if this makes
sense anymore. I am not quite sure what the original intent here was, we
should probably ask Mark Brown. But a lot of drivers do expect the dummy
substitution to imply work.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH 3/4] ARM64: dts: meson-gx-p23x-q20x: enable the Bluetooth module
From: Andreas Färber @ 2017-01-16 0:47 UTC (permalink / raw)
To: Martin Blumenstingl, linux-serial, linux-amlogic, jslaby, gregkh,
khilman, carlo
Cc: mark.rutland, devicetree, catalin.marinas, will.deacon, robh+dt,
linux-arm-kernel
In-Reply-To: <20170115223255.10350-4-martin.blumenstingl@googlemail.com>
Am 15.01.2017 um 23:32 schrieb Martin Blumenstingl:
> This takes the Bluetooth module out of reset (the reset line is
> connected to GPIOX_17) and enables uart_A which is used to configure the
> module.
> This is identical for all boards which inherit meson-gx-p23x-q20x:
> - GXL S905D P230
> - GXL S905D P231
> - GXM S912 Q200
> - GXM S912 Q201
>
> To get the HCI interface up one has to install bluez-utils and run:
> hciattach -s115200 /dev/ttyAML1 bcm43xx 2000000 flow -
>
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
> ---
> arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi | 12 +++++++++++-
> 1 file changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
> index 7a078bef04cd..7db779048091 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
> @@ -48,6 +48,7 @@
> / {
> aliases {
> serial0 = &uart_AO;
> + serial1 = &uart_A;
> };
>
> chosen {
> @@ -94,12 +95,21 @@
>
> sdio_pwrseq: sdio-pwrseq {
> compatible = "mmc-pwrseq-simple";
> - reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
> + reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>,
> + <&gpio GPIOX_17 GPIO_ACTIVE_LOW>;
> clocks = <&wifi32k>;
> clock-names = "ext_clock";
> };
> };
>
> +/* This is connected to the Bluetooth module of the wifi/BT combo chip: */
> +&uart_A {
> + status = "okay";
> + pinctrl-0 = <&uart_a_pins &uart_a_cts_rts_pins>;
Nit: <&uart_a_pins>, <&uart_a_cts_rts_pins> please, like you've done for
reset-gpios above.
Regards,
Andreas
> + pinctrl-names = "default";
> + uart-has-rtscts;
> +};
> +
> /* This UART is brought out to the DB9 connector */
> &uart_AO {
> status = "okay";
>
--
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
^ permalink raw reply
* Re: [PATCH v2 3/3] Input: pwm-beeper: add optional amplifier regulator
From: David Lechner @ 2017-01-16 1:04 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: linux-input, devicetree, Rob Herring, Mark Rutland, linux-kernel
In-Reply-To: <20170116003456.GH23285@dtor-ws>
On 01/15/2017 06:34 PM, Dmitry Torokhov wrote:
> On Sun, Jan 15, 2017 at 06:12:29PM -0600, David Lechner wrote:
>> On 01/14/2017 01:19 PM, Dmitry Torokhov wrote:
>>> On Wed, Jan 11, 2017 at 02:02:01PM -0600, David Lechner wrote:
>>>> This adds an optional regulator to the pwm-beeper device. This regulator
>>>> acts as an amplifier. The amplifier is only enabled while beeping in order
>>>> to reduce power consumption.
>>>>
>>>> Tested on LEGO MINDSTORMS EV3, which has a speaker connected to PWM through
>>>> an amplifier.
>>>>
>>>> Signed-off-by: David Lechner <david@lechnology.com>
>>>> ---
>>>> drivers/input/misc/pwm-beeper.c | 29 ++++++++++++++++++++++++++++-
>>>> 1 file changed, 28 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c
>>>> index 30ac227..708e88e 100644
>>>> --- a/drivers/input/misc/pwm-beeper.c
>>>> +++ b/drivers/input/misc/pwm-beeper.c
>>>> @@ -14,6 +14,7 @@
>>>> */
>>>>
>>>> #include <linux/input.h>
>>>> +#include <linux/regulator/consumer.h>
>>>> #include <linux/module.h>
>>>> #include <linux/kernel.h>
>>>> #include <linux/of.h>
>>>> @@ -25,8 +26,10 @@
>>>> struct pwm_beeper {
>>>> struct input_dev *input;
>>>> struct pwm_device *pwm;
>>>> + struct regulator *reg;
>>>> struct work_struct work;
>>>> unsigned long period;
>>>> + bool reg_enabled;
>>>> };
>>>>
>>>> #define HZ_TO_NANOSECONDS(x) (1000000000UL/(x))
>>>> @@ -38,8 +41,20 @@ static void __pwm_beeper_set(struct pwm_beeper *beeper)
>>>> if (period) {
>>>> pwm_config(beeper->pwm, period / 2, period);
>>>> pwm_enable(beeper->pwm);
>>>> - } else
>>>> + if (beeper->reg) {
>>>> + int error;
>>>> +
>>>> + error = regulator_enable(beeper->reg);
>>>> + if (!error)
>>>> + beeper->reg_enabled = true;
>>>> + }
>>>> + } else {
>>>> + if (beeper->reg_enabled) {
>>>> + regulator_disable(beeper->reg);
>>>> + beeper->reg_enabled = false;
>>>> + }
>>>> pwm_disable(beeper->pwm);
>>>> + }
>>>> }
>>>>
>>>> static void pwm_beeper_work(struct work_struct *work)
>>>> @@ -82,6 +97,10 @@ static void pwm_beeper_stop(struct pwm_beeper *beeper)
>>>> {
>>>> cancel_work_sync(&beeper->work);
>>>>
>>>> + if (beeper->reg_enabled) {
>>>> + regulator_disable(beeper->reg);
>>>> + beeper->reg_enabled = false;
>>>> + }
>>>> if (beeper->period)
>>>> pwm_disable(beeper->pwm);
>>>> }
>>>> @@ -111,6 +130,14 @@ static int pwm_beeper_probe(struct platform_device *pdev)
>>>> return error;
>>>> }
>>>>
>>>> + beeper->reg = devm_regulator_get_optional(&pdev->dev, "amp");
>>>
>>> If you do not use optional regulator then you will not have to check if
>>> you have it or not everywhere: regulator core will give you a dummy that
>>> you can toggle to your heart's content.
>>
>> Some months ago, I learned that if you are not using device tree and
>> you do not call regulator_has_full_constraints(), then you do not
>> get a dummy regulator. And here, we are only checking if the
>> regulator exists in one place. We will still need the checks for
>> beeper->reg_enabled to keep calls to regulator_enable() and
>> regulator_disable() balanced.
>
> Why? You do not have checks for calls to pwm_enable() and pwm_disable(),
> (or rather beeper->period is used as such flag) why regulator would be
> any different?
regulator_enable() has a __must_check attribute on it, so we get
compiler warnings if we do not check the return value. Also, if enabling
the regulator fails and returns an error, then calling
regulator_disable() later would cause an imbalance.
pwm_enable() and pwm_disable() work differently because they don't count
how many times they have been called. regulator_enable() and
regulator_disable(), on the other hand, work like reference counting.
>
>>
>> On the other hand, it is recommended that you always call
>> regulator_has_full_constraints(), so I don't mind changing it if
>> that is what you think we should do. But, I don't really see much of
>> an advantage to changing it compared to the current implementation.
>
> It greatly simplifies control flow in the driver (since I believe you
> can get rid of the flags you introduced).
>
> As far as arch not having full constraints - I am not sure if this makes
> sense anymore. I am not quite sure what the original intent here was, we
> should probably ask Mark Brown. But a lot of drivers do expect the dummy
> substitution to imply work.
I am OK with using the dummy regulator, but I don't see how I can get
rid of the beeper->reg_enabled flag.
^ permalink raw reply
* Re: [PATCH v11 02/12] drm/mediatek: add helpers for coverting from the generic components
From: CK Hu @ 2017-01-16 1:09 UTC (permalink / raw)
To: YT Shen
Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Philipp Zabel,
David Airlie, Rob Herring, Mark Rutland, Matthias Brugger,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w,
emil.l.velikov-Re5JQEeQqe8AvxtiuMwx3w,
thierry.reding-Re5JQEeQqe8AvxtiuMwx3w, Daniel Kurtz
In-Reply-To: <1484117473-46644-3-git-send-email-yt.shen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
On Wed, 2017-01-11 at 14:51 +0800, YT Shen wrote:
> define helpers for converting from 'mtk_ddp_comp' to 'mtk_disp_ovl'
> define helpers for converting from 'mtk_ddp_comp' to 'mtk_disp_rdma'
>
> Signed-off-by: YT Shen <yt.shen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
Acked-by CK Hu <ck.hu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> ---
> drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 15 +++++++++------
> drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 15 +++++++++------
> 2 files changed, 18 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index c703102..ce2759f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -57,6 +57,11 @@ struct mtk_disp_ovl {
> struct drm_crtc *crtc;
> };
>
> +static inline struct mtk_disp_ovl *comp_to_ovl(struct mtk_ddp_comp *comp)
> +{
> + return container_of(comp, struct mtk_disp_ovl, ddp_comp);
> +}
> +
> static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
> {
> struct mtk_disp_ovl *priv = dev_id;
> @@ -76,20 +81,18 @@ static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
> static void mtk_ovl_enable_vblank(struct mtk_ddp_comp *comp,
> struct drm_crtc *crtc)
> {
> - struct mtk_disp_ovl *priv = container_of(comp, struct mtk_disp_ovl,
> - ddp_comp);
> + struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
>
> - priv->crtc = crtc;
> + ovl->crtc = crtc;
> writel(0x0, comp->regs + DISP_REG_OVL_INTSTA);
> writel_relaxed(OVL_FME_CPL_INT, comp->regs + DISP_REG_OVL_INTEN);
> }
>
> static void mtk_ovl_disable_vblank(struct mtk_ddp_comp *comp)
> {
> - struct mtk_disp_ovl *priv = container_of(comp, struct mtk_disp_ovl,
> - ddp_comp);
> + struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
>
> - priv->crtc = NULL;
> + ovl->crtc = NULL;
> writel_relaxed(0x0, comp->regs + DISP_REG_OVL_INTEN);
> }
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> index 0df05f9..21eff6f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -49,6 +49,11 @@ struct mtk_disp_rdma {
> struct drm_crtc *crtc;
> };
>
> +static inline struct mtk_disp_rdma *comp_to_rdma(struct mtk_ddp_comp *comp)
> +{
> + return container_of(comp, struct mtk_disp_rdma, ddp_comp);
> +}
> +
> static irqreturn_t mtk_disp_rdma_irq_handler(int irq, void *dev_id)
> {
> struct mtk_disp_rdma *priv = dev_id;
> @@ -77,20 +82,18 @@ static void rdma_update_bits(struct mtk_ddp_comp *comp, unsigned int reg,
> static void mtk_rdma_enable_vblank(struct mtk_ddp_comp *comp,
> struct drm_crtc *crtc)
> {
> - struct mtk_disp_rdma *priv = container_of(comp, struct mtk_disp_rdma,
> - ddp_comp);
> + struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
>
> - priv->crtc = crtc;
> + rdma->crtc = crtc;
> rdma_update_bits(comp, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT,
> RDMA_FRAME_END_INT);
> }
>
> static void mtk_rdma_disable_vblank(struct mtk_ddp_comp *comp)
> {
> - struct mtk_disp_rdma *priv = container_of(comp, struct mtk_disp_rdma,
> - ddp_comp);
> + struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
>
> - priv->crtc = NULL;
> + rdma->crtc = NULL;
> rdma_update_bits(comp, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, 0);
> }
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [v2 2/3] ARM: dts: STM32 Add USB FS host mode support
From: Bruno Herrera @ 2017-01-16 2:09 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Maxime Coquelin, Alexandre Torgue
Cc: devicetree, Russell King, linux-arm-kernel, linux-kernel
In-Reply-To: <20170116020958.62767-1-bruherrera@gmail.com>
This patch adds the USB pins and nodes for USB HS/FS cores working at FS speed,
using embedded PHY.
Signed-off-by: Bruno Herrera <bruherrera@gmail.com>
---
arch/arm/boot/dts/stm32f429-disco.dts | 30 ++++++++++++++++++++++++++++++
arch/arm/boot/dts/stm32f429.dtsi | 35 ++++++++++++++++++++++++++++++++++-
arch/arm/boot/dts/stm32f469-disco.dts | 30 ++++++++++++++++++++++++++++++
3 files changed, 94 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/stm32f429-disco.dts b/arch/arm/boot/dts/stm32f429-disco.dts
index 7d0415e..374c5ed 100644
--- a/arch/arm/boot/dts/stm32f429-disco.dts
+++ b/arch/arm/boot/dts/stm32f429-disco.dts
@@ -88,6 +88,16 @@
gpios = <&gpioa 0 0>;
};
};
+
+ /* This turns on vbus for otg for host mode (dwc2) */
+ vcc5v_otg: vcc5v-otg-regulator {
+ compatible = "regulator-fixed";
+ gpio = <&gpioc 4 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usbotg_pwren_h>;
+ regulator-name = "vcc5_host1";
+ regulator-always-on;
+ };
};
&clk_hse {
@@ -99,3 +109,23 @@
pinctrl-names = "default";
status = "okay";
};
+
+&usbotg_hs {
+ compatible = "st,stm32-fsotg", "snps,dwc2";
+ dr_mode = "host";
+ pinctrl-0 = <&usbotg_fs_pins_b>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&pinctrl {
+ usb-host {
+ usbotg_pwren_h: usbotg-pwren-h {
+ pins {
+ pinmux = <STM32F429_PC4_FUNC_GPIO>;
+ bias-disable;
+ drive-push-pull;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index e4dae0e..bc07aa8 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -206,7 +206,7 @@
reg = <0x40007000 0x400>;
};
- pin-controller {
+ pinctrl: pin-controller {
#address-cells = <1>;
#size-cells = <1>;
compatible = "st,stm32f429-pinctrl";
@@ -316,6 +316,30 @@
};
};
+ usbotg_fs_pins_a: usbotg_fs@0 {
+ pins {
+ pinmux = <STM32F429_PA10_FUNC_OTG_FS_ID>,
+ <STM32F429_PA11_FUNC_OTG_FS_DM>,
+ <STM32F429_PA12_FUNC_OTG_FS_DP>;
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <2>;
+ };
+ };
+
+ usbotg_fs_pins_b: usbotg_fs@1 {
+ pins {
+ pinmux = <STM32F429_PB12_FUNC_OTG_HS_ID>,
+ <STM32F429_PB14_FUNC_OTG_HS_DM>,
+ <STM32F429_PB15_FUNC_OTG_HS_DP>;
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <2>;
+ };
+ };
+
+
+
usbotg_hs_pins_a: usbotg_hs@0 {
pins {
pinmux = <STM32F429_PH4_FUNC_OTG_HS_ULPI_NXT>,
@@ -420,6 +444,15 @@
status = "disabled";
};
+ usbotg_fs: usb@50000000 {
+ compatible = "st,stm32f4xx-fsotg", "snps,dwc2";
+ reg = <0x50000000 0x40000>;
+ interrupts = <67>;
+ clocks = <&rcc 0 39>;
+ clock-names = "otg";
+ status = "disabled";
+ };
+
rng: rng@50060800 {
compatible = "st,stm32-rng";
reg = <0x50060800 0x400>;
diff --git a/arch/arm/boot/dts/stm32f469-disco.dts b/arch/arm/boot/dts/stm32f469-disco.dts
index 8877c00..8ae6763 100644
--- a/arch/arm/boot/dts/stm32f469-disco.dts
+++ b/arch/arm/boot/dts/stm32f469-disco.dts
@@ -68,6 +68,17 @@
soc {
dma-ranges = <0xc0000000 0x0 0x10000000>;
};
+
+ /* This turns on vbus for otg for host mode (dwc2) */
+ vcc5v_otg: vcc5v-otg-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpiob 2 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usbotg_pwren_h>;
+ regulator-name = "vcc5_host1";
+ regulator-always-on;
+ };
};
&rcc {
@@ -81,3 +92,22 @@
&usart3 {
status = "okay";
};
+
+&usbotg_fs {
+ dr_mode = "host";
+ pinctrl-0 = <&usbotg_fs_pins_a>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&pinctrl {
+ usb-host {
+ usbotg_pwren_h: usbotg-pwren-h {
+ pins {
+ pinmux = <STM32F429_PB2_FUNC_GPIO>;
+ bias-disable;
+ drive-push-pull;
+ };
+ };
+ };
+};
--
2.10.1 (Apple Git-78)
^ permalink raw reply related
* [v2 3/3] dt-bindings: Document the STM32 USB OTG DWC2 core binding
From: Bruno Herrera @ 2017-01-16 2:09 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Rob Herring, Mark Rutland, linux-usb, devicetree, linux-kernel
In-Reply-To: <20170116020958.62767-1-bruherrera@gmail.com>
This patch adds the documentation for STM32F4x9 USB OTG FS/HS compatible strings.
Signed-off-by: Bruno Herrera <bruherrera@gmail.com>
---
Documentation/devicetree/bindings/usb/dwc2.txt | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt
index 6c7c2bce..637223a 100644
--- a/Documentation/devicetree/bindings/usb/dwc2.txt
+++ b/Documentation/devicetree/bindings/usb/dwc2.txt
@@ -14,6 +14,10 @@ Required properties:
- "amlogic,meson-gxbb-usb": The DWC2 USB controller instance in Amlogic S905 SoCs;
- "amcc,dwc-otg": The DWC2 USB controller instance in AMCC Canyonlands 460EX SoCs;
- snps,dwc2: A generic DWC2 USB controller with default parameters.
+ - "st,stm32f4xx-fsotg": The DWC2 USB FS/HS controller instance in STM32F4xx SoCs
+ configured in FS mode;
+ - "st,stm32f4xx-hsotg": The DWC2 USB HS controller instance in STM32F4xx SoCs
+ configured in HS mode;
- reg : Should contain 1 register range (address and length)
- interrupts : Should contain 1 interrupt
- clocks: clock provider specifier
--
2.10.1 (Apple Git-78)
^ permalink raw reply related
* Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip
From: Shawn Lin @ 2017-01-16 2:35 UTC (permalink / raw)
To: Matt Ranostay
Cc: shawn.lin, linux-wireless, Linux Kernel, linux-mmc, devicetree,
Tony Lindgren, Ulf Hansson
In-Reply-To: <CAJ_EiSQtPUwv9K7CbM5e_wnre6=qR=+hgtq-oVFub2phijvXgA@mail.gmail.com>
On 2017/1/16 5:41, Matt Ranostay wrote:
> On Thu, Jan 12, 2017 at 11:16 PM, Shawn Lin <shawn.lin@rock-chips.com> wrote:
>> On 2017/1/13 13:29, Matt Ranostay wrote:
>>>
>>> Allow power sequencing for the Marvell SD8787 Wifi/BT chip.
>>> This can be abstracted to other chipsets if needed in the future.
>>>
>>> Cc: Tony Lindgren <tony@atomide.com>
>>> Cc: Ulf Hansson <ulf.hansson@linaro.org>
>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>> ---
>>> drivers/mmc/core/Kconfig | 10 ++++
>>> drivers/mmc/core/Makefile | 1 +
>>> drivers/mmc/core/pwrseq_sd8787.c | 117
>>> +++++++++++++++++++++++++++++++++++++++
>>> 3 files changed, 128 insertions(+)
>>> create mode 100644 drivers/mmc/core/pwrseq_sd8787.c
>>>
>>> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
>>> index cdfa8520a4b1..fc1ecdaaa9ca 100644
>>> --- a/drivers/mmc/core/Kconfig
>>> +++ b/drivers/mmc/core/Kconfig
>>> @@ -12,6 +12,16 @@ config PWRSEQ_EMMC
>>> This driver can also be built as a module. If so, the module
>>> will be called pwrseq_emmc.
>>>
>>> +config PWRSEQ_SD8787
>>> + tristate "HW reset support for SD8787 BT + Wifi module"
>>> + depends on OF && (MWIFIEX || BT_MRVL_SDIO)
>>> + help
>>> + This selects hardware reset support for the SD8787 BT + Wifi
>>> + module. By default this option is set to n.
>>> +
>>> + This driver can also be built as a module. If so, the module
>>> + will be called pwrseq_sd8787.
>>> +
>>
>>
>> I don't like this way, as we have a chance to list lots
>> configure options here. wifi A,B,C,D...Z, all of them need a
>> new section here if needed?
>>
>> Instead, could you just extent pwrseq_simple.c and add you
>> .compatible = "mmc-pwrseq-sd8787", "mmc-pwrseq-simple"?
>
> You mean all the chipset pwrseqs linked into the pwrseq-simple module?
What I mean was if you just extent the pwrseq-simple a bit, you could
just add your chipset pwrseqs linked into the pwrseq-simple. But if you
need a different *pattern* of pwrseqs, you should need a new name, for
instance, pwrseq-sdio.c etc... But please don't use the name of
sd8787? So if I use a wifi named ABC but using the same pwrseq pattenr,
should I include your "mmc-pwrseq- sd8787" for that or I need a new
mmc-pwrseq-ABC.c?
>
> Ulf your thoughts on this?
>
>>
>>
>>
>>> config PWRSEQ_SIMPLE
>>> tristate "Simple HW reset support for MMC"
>>> default y
>>> diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
>>> index b2a257dc644f..0f81464fa824 100644
>>> --- a/drivers/mmc/core/Makefile
>>> +++ b/drivers/mmc/core/Makefile
>>> @@ -10,6 +10,7 @@ mmc_core-y := core.o bus.o host.o \
>>> quirks.o slot-gpio.o
>>> mmc_core-$(CONFIG_OF) += pwrseq.o
>>> obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o
>>> +obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o
>>> obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o
>>> mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
>>> obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
>>> diff --git a/drivers/mmc/core/pwrseq_sd8787.c
>>> b/drivers/mmc/core/pwrseq_sd8787.c
>>> new file mode 100644
>>> index 000000000000..f4080fe6439e
>>> --- /dev/null
>>> +++ b/drivers/mmc/core/pwrseq_sd8787.c
>>> @@ -0,0 +1,117 @@
>>> +/*
>>> + * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT + Wifi
>>> chip
>>> + *
>>> + * Copyright (C) 2016 Matt Ranostay <matt@ranostay.consulting>
>>> + *
>>> + * Based on the original work pwrseq_simple.c
>>> + * Copyright (C) 2014 Linaro Ltd
>>> + * Author: Ulf Hansson <ulf.hansson@linaro.org>
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License as published by
>>> + * the Free Software Foundation; either version 2 of the License, or
>>> + * (at your option) any later version.
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>>> + * GNU General Public License for more details.
>>> + *
>>> + */
>>> +
>>> +#include <linux/delay.h>
>>> +#include <linux/init.h>
>>> +#include <linux/kernel.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/module.h>
>>> +#include <linux/slab.h>
>>> +#include <linux/device.h>
>>> +#include <linux/err.h>
>>> +#include <linux/gpio/consumer.h>
>>> +
>>> +#include <linux/mmc/host.h>
>>> +
>>> +#include "pwrseq.h"
>>> +
>>> +struct mmc_pwrseq_sd8787 {
>>> + struct mmc_pwrseq pwrseq;
>>> + struct gpio_desc *reset_gpio;
>>> + struct gpio_desc *pwrdn_gpio;
>>> +};
>>> +
>>> +#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787,
>>> pwrseq)
>>> +
>>> +static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
>>> +{
>>> + struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
>>> +
>>> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
>>> +
>>> + msleep(300);
>>> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
>>> +}
>>> +
>>> +static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host)
>>> +{
>>> + struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
>>> +
>>> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0);
>>> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
>>> +}
>>> +
>>> +static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
>>> + .pre_power_on = mmc_pwrseq_sd8787_pre_power_on,
>>> + .power_off = mmc_pwrseq_sd8787_power_off,
>>> +};
>>> +
>>> +static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
>>> + { .compatible = "mmc-pwrseq-sd8787",},
>>> + {/* sentinel */},
>>> +};
>>> +MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
>>> +
>>> +static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
>>> +{
>>> + struct mmc_pwrseq_sd8787 *pwrseq;
>>> + struct device *dev = &pdev->dev;
>>> +
>>> + pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
>>> + if (!pwrseq)
>>> + return -ENOMEM;
>>> +
>>> + pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "pwrdn", GPIOD_OUT_LOW);
>>> + if (IS_ERR(pwrseq->pwrdn_gpio))
>>> + return PTR_ERR(pwrseq->pwrdn_gpio);
>>> +
>>> + pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
>>> + if (IS_ERR(pwrseq->reset_gpio))
>>> + return PTR_ERR(pwrseq->reset_gpio);
>>> +
>>> + pwrseq->pwrseq.dev = dev;
>>> + pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops;
>>> + pwrseq->pwrseq.owner = THIS_MODULE;
>>> + platform_set_drvdata(pdev, pwrseq);
>>> +
>>> + return mmc_pwrseq_register(&pwrseq->pwrseq);
>>> +}
>>> +
>>> +static int mmc_pwrseq_sd8787_remove(struct platform_device *pdev)
>>> +{
>>> + struct mmc_pwrseq_sd8787 *pwrseq = platform_get_drvdata(pdev);
>>> +
>>> + mmc_pwrseq_unregister(&pwrseq->pwrseq);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static struct platform_driver mmc_pwrseq_sd8787_driver = {
>>> + .probe = mmc_pwrseq_sd8787_probe,
>>> + .remove = mmc_pwrseq_sd8787_remove,
>>> + .driver = {
>>> + .name = "pwrseq_sd8787",
>>> + .of_match_table = mmc_pwrseq_sd8787_of_match,
>>> + },
>>> +};
>>> +
>>> +module_platform_driver(mmc_pwrseq_sd8787_driver);
>>> +MODULE_LICENSE("GPL v2");
>>>
>>
>>
>> --
>> Best Regards
>> Shawn Lin
>>
>
>
>
--
Best Regards
Shawn Lin
^ permalink raw reply
* Re: [PATCH v4 5/5] ARM: dts: mt2701: add iommu/smi dtsi node for mt2701
From: Honghui Zhang @ 2017-01-16 2:48 UTC (permalink / raw)
To: Matthias Brugger
Cc: joro-zLv9SwRftAIdnm+yROfE0A, treding-DDmLM1+adcrQT0dZR+AlfA,
mark.rutland-5wv7dgnIgG8, robh-DgEjT+Ai2ygdnm+yROfE0A,
robin.murphy-5wv7dgnIgG8, p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ,
devicetree-u79uwXL29TY76Z2rM5mHXA, pebolle-IWqWACnzNjzz+pZb47iToQ,
kendrick.hsu-NuS5LvNUpcJWk0Htik3J/w, arnd-r2nGTMty4D4,
srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, tfiga-hpIqsD4AKlfQT0dZR+AlfA,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, djkurtz-hpIqsD4AKlfQT0dZR+AlfA,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
l.stach-bIcnvbaLZ9MEGnE8C9+IrQ,
yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w,
eddie.huang-NuS5LvNUpcJWk0Htik3J/w,
youlin.pei-NuS5LvNUpcJWk0Htik3J/w, erin.lo-NuS5LvNUpcJWk0Htik3J/w
In-Reply-To: <5a45da57-9262-b1ff-1c6a-c5c211c1bfd4-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On Fri, 2017-01-13 at 15:54 +0100, Matthias Brugger wrote:
>
> On 04/07/16 10:00, Matthias Brugger wrote:
> >
> >
> > On 04/07/16 03:32, Honghui Zhang wrote:
> >> On Sun, 2016-07-03 at 21:12 +0200, Matthias Brugger wrote:
> >>>
> >>> On 07/03/2016 08:24 AM, Matthias Brugger wrote:
> >>>>
> >>>>
> >>>> On 06/08/2016 11:51 AM, honghui.zhang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org wrote:
> >>>>> From: Honghui Zhang <honghui.zhang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> >>>>>
> >>>>> Add the dtsi node of iommu and smi for mt2701.
> >>>>>
> >>>>> Signed-off-by: Honghui Zhang <honghui.zhang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> >>>>> ---
> >>>>> arch/arm/boot/dts/mt2701.dtsi | 51
> >>>>> +++++++++++++++++++++++++++++++++++++++++++
> >>>>> 1 file changed, 51 insertions(+)
> >>>>>
> >>>>
> >>>> Applied,
> >>>
> >>> Please resend the patch including the infracfg and mmsys node.
> >>>
> >>
> >> Hi, Matthias,
> >>
> >> Please hold this one.
> >> This one is based on CCF "arm: dts: mt2701: Add clock controller device
> >> nodes"[1] and power domain patch "Mediatek MT2701 SCPSYS power domain
> >> support v7"[2],
> >> But these two patchset are still being reviewed now.
> >>
> >> Do you think it's better that I send this one later after ccf and power
> >> domain patch got merged? I will send this patch later if it's OK with
> >> you.
> >>
> >
> > Sounds good.
>
> Applied now to v4.10-next/dts32
>
> Thanks.
>
Thanks.
> >
> > Thanks a lot,
> > Matthias
> >
> >> Thanks.
> >> [1] https://patchwork.kernel.org/patch/9109081
> >> [2]
> >> http://lists.infradead.org/pipermail/linux-mediatek/2016-May/005429.html
> >>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 2/6] arm: dts: mt2701: Add iommu/smi device node
From: Honghui Zhang @ 2017-01-16 2:54 UTC (permalink / raw)
To: Matthias Brugger
Cc: Erin Lo, srv_heupstream, devicetree, linux-arm-kernel,
linux-kernel, linux-mediatek
In-Reply-To: <02062506-f917-0140-4934-31d7d3317b80@gmail.com>
On Fri, 2017-01-13 at 16:05 +0100, Matthias Brugger wrote:
> Hi Erin,
>
> I just took the patch from Honghui he send in june.
> Please see my comment inline.
>
> On 13/01/17 09:42, Erin Lo wrote:
> > From: Honghui Zhang <honghui.zhang@mediatek.com>
> >
> > Add the device node of iommu and smi for MT2701.
> >
> > Signed-off-by: Honghui Zhang <honghui.zhang@mediatek.com>
> > Signed-off-by: Erin Lo <erin.lo@mediatek.com>
> > ---
> > arch/arm/boot/dts/mt2701.dtsi | 54 +++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 54 insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
> > index eb4c6fd..87be52c 100644
> > --- a/arch/arm/boot/dts/mt2701.dtsi
> > +++ b/arch/arm/boot/dts/mt2701.dtsi
> > @@ -17,6 +17,7 @@
> > #include <dt-bindings/interrupt-controller/irq.h>
> > #include <dt-bindings/interrupt-controller/arm-gic.h>
> > #include <dt-bindings/reset/mt2701-resets.h>
> > +#include <dt-bindings/memory/mt2701-larb-port.h>
> > #include "skeleton64.dtsi"
> > #include "mt2701-pinfunc.h"
> >
> > @@ -161,6 +162,16 @@
> > clock-names = "system-clk", "rtc-clk";
> > };
> >
> > + smi_common: smi@1000c000 {
> > + compatible = "mediatek,mt2701-smi-common";
> > + reg = <0 0x1000c000 0 0x1000>;
> > + clocks = <&infracfg CLK_INFRA_SMI>,
> > + <&mmsys CLK_MM_SMI_COMMON>,
> > + <&infracfg CLK_INFRA_SMI>;
> > + clock-names = "apb", "smi", "async";
> > + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>;
> > + };
> > +
> > sysirq: interrupt-controller@10200100 {
> > compatible = "mediatek,mt2701-sysirq",
> > "mediatek,mt6577-sysirq";
> > @@ -170,6 +181,16 @@
> > reg = <0 0x10200100 0 0x1c>;
> > };
> >
> > + iommu: mmsys_iommu@10205000 {
> > + compatible = "mediatek,mt2701-m4u";
> > + reg = <0 0x10205000 0 0x1000>;
> > + interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_LOW>;
> > + clocks = <&infracfg CLK_INFRA_M4U>;
> > + clock-names = "bclk";
> > + mediatek,larbs = <&larb0 &larb1 &larb2>;
> > + #iommu-cells = <1>;
> > + };
> > +
> > apmixedsys: syscon@10209000 {
> > compatible = "mediatek,mt2701-apmixedsys", "syscon";
> > reg = <0 0x10209000 0 0x1000>;
> > @@ -272,18 +293,51 @@
> > #clock-cells = <1>;
> > };
> >
> > + larb0: larb@14010000 {
> > + compatible = "mediatek,mt2701-smi-larb";
> > + reg = <0 0x14010000 0 0x1000>;
> > + mediatek,smi = <&smi_common>;
> > + mediatek,larbidx = <0>;
>
> Did I miss something? 'mediatek,larbidx' does not sound familiar to me.
>
Hi, Mathias,
It's my mistake, we found a bug need this to fix in smi driver,
but I mix those patches together and make it un-clear.
I will send new patch serial to add the 'mediatek,larbidx' later since
you have applied the last one.
thanks very much.
> Regards,
> Matthias
>
> > + clocks = <&mmsys CLK_MM_SMI_LARB0>,
> > + <&mmsys CLK_MM_SMI_LARB0>;
> > + clock-names = "apb", "smi";
> > + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>;
> > + };
> > +
> > imgsys: syscon@15000000 {
> > compatible = "mediatek,mt2701-imgsys", "syscon";
> > reg = <0 0x15000000 0 0x1000>;
> > #clock-cells = <1>;
> > };
> >
> > + larb2: larb@15001000 {
> > + compatible = "mediatek,mt2701-smi-larb";
> > + reg = <0 0x15001000 0 0x1000>;
> > + mediatek,smi = <&smi_common>;
> > + mediatek,larbidx = <2>;
> > + clocks = <&imgsys CLK_IMG_SMI_COMM>,
> > + <&imgsys CLK_IMG_SMI_COMM>;
> > + clock-names = "apb", "smi";
> > + power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
> > + };
> > +
> > vdecsys: syscon@16000000 {
> > compatible = "mediatek,mt2701-vdecsys", "syscon";
> > reg = <0 0x16000000 0 0x1000>;
> > #clock-cells = <1>;
> > };
> >
> > + larb1: larb@16010000 {
> > + compatible = "mediatek,mt2701-smi-larb";
> > + reg = <0 0x16010000 0 0x1000>;
> > + mediatek,smi = <&smi_common>;
> > + mediatek,larbidx = <1>;
> > + clocks = <&vdecsys CLK_VDEC_CKGEN>,
> > + <&vdecsys CLK_VDEC_LARB>;
> > + clock-names = "apb", "smi";
> > + power-domains = <&scpsys MT2701_POWER_DOMAIN_VDEC>;
> > + };
> > +
> > hifsys: syscon@1a000000 {
> > compatible = "mediatek,mt2701-hifsys", "syscon";
> > reg = <0 0x1a000000 0 0x1000>;
> >
^ permalink raw reply
* [PATCH v4 0/5] i2c: mux: pca954x: Add interrupt controller support
From: Phil Reid @ 2017-01-16 3:11 UTC (permalink / raw)
To: peda-koto5C5qi+TLoDKTGw+V6w, wsa-z923LK4zBo2bacvFa/9K2g,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
Various muxes can aggregate multiple interrupts from each i2c bus.
All of the muxes with interrupt support combine the active low irq lines
using an internal 'and' function and generate a combined active low
output. The muxes do provide the ability to read a control register to
determine which irq is active. By making the mux an irq controller isr
latenct can potentially be reduced by reading the status register and
then only calling the registered isr on that bus segment.
In addition an additional enable mask is added to work around devices
that assert irq immediately before being setup buy disabling the irq
from the mux until all devices are registered.
Changes from v3:
- p3: Add spin lock to irq mask / unmask.
- p4: Add Rob's ack.
Changes from v2:
- p1: Added Acked-by
- p5: fixup 2 typos
Changes from v1:
- Update for new ACPI table
- Fix typo in documentation
- Fix typo in function names
- Fix typo in irq name
- Added spaces around '+' / '='
- Change goto label names
- Change property name from i2c-mux-irq-mask-en to nxp,irq-mask-enable
- Change variable name irq_mask_en to irq_mask_enable
- Add commentt about irq_mask_enable
- Added Acked-By's
Phil Reid (5):
i2c: mux: pca954x: Add missing pca9542 definition to chip_desc
dt: bindings: i2c-mux-pca954x: Add documentation for interrupt
controller
i2c: mux: pca954x: Add interrupt controller support
dt: bindings: i2c-mux-pca954x: Add documentation for
i2c-mux-irq-mask-en
i2c: mux: pca954x: Add irq_mask_en to delay enabling irqs
.../devicetree/bindings/i2c/i2c-mux-pca954x.txt | 17 ++-
drivers/i2c/muxes/i2c-mux-pca954x.c | 170 ++++++++++++++++++++-
2 files changed, 182 insertions(+), 5 deletions(-)
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v4 1/5] i2c: mux: pca954x: Add missing pca9542 definition to chip_desc
From: Phil Reid @ 2017-01-16 3:11 UTC (permalink / raw)
To: peda, wsa, robh+dt, mark.rutland, preid, linux-i2c, devicetree
In-Reply-To: <1484536275-75995-1-git-send-email-preid@electromag.com.au>
The spec for the pca954x was missing. This chip is the same as the pca9540
except that it has interrupt lines. While the i2c_device_id table mapped
the pca9542 to the pca9540 definition the compatible table did not. In
preparation for irq support add the pca9542 definition.
Acked-by: Peter Rosin <peda@axentia.se>
Signed-off-by: Phil Reid <preid@electromag.com.au>
---
drivers/i2c/muxes/i2c-mux-pca954x.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index dd18b9c..bbf088e 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -84,6 +84,11 @@ struct pca954x {
.enable = 0x4,
.muxtype = pca954x_ismux,
},
+ [pca_9542] = {
+ .nchans = 2,
+ .enable = 0x4,
+ .muxtype = pca954x_ismux,
+ },
[pca_9543] = {
.nchans = 2,
.muxtype = pca954x_isswi,
@@ -110,7 +115,7 @@ struct pca954x {
static const struct i2c_device_id pca954x_id[] = {
{ "pca9540", pca_9540 },
- { "pca9542", pca_9540 },
+ { "pca9542", pca_9542 },
{ "pca9543", pca_9543 },
{ "pca9544", pca_9544 },
{ "pca9545", pca_9545 },
@@ -124,7 +129,7 @@ struct pca954x {
#ifdef CONFIG_ACPI
static const struct acpi_device_id pca954x_acpi_ids[] = {
{ .id = "PCA9540", .driver_data = pca_9540 },
- { .id = "PCA9542", .driver_data = pca_9540 },
+ { .id = "PCA9542", .driver_data = pca_9542 },
{ .id = "PCA9543", .driver_data = pca_9543 },
{ .id = "PCA9544", .driver_data = pca_9544 },
{ .id = "PCA9545", .driver_data = pca_9545 },
--
1.8.3.1
^ permalink raw reply related
* [PATCH v4 2/5] dt: bindings: i2c-mux-pca954x: Add documentation for interrupt controller
From: Phil Reid @ 2017-01-16 3:11 UTC (permalink / raw)
To: peda-koto5C5qi+TLoDKTGw+V6w, wsa-z923LK4zBo2bacvFa/9K2g,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1484536275-75995-1-git-send-email-preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO@public.gmane.org>
Various muxes can aggregate multiple irq lines and provide a control
register to determine the active line. Add bindings for interrupt
controller support.
Acked-by: Peter Rosin <peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Phil Reid <preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO@public.gmane.org>
---
Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
index cf53d5f..aa09704 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
@@ -19,7 +19,14 @@ Optional Properties:
- i2c-mux-idle-disconnect: Boolean; if defined, forces mux to disconnect all
children in idle state. This is necessary for example, if there are several
multiplexers on the bus and the devices behind them use same I2C addresses.
-
+ - interrupt-parent: Phandle for the interrupt controller that services
+ interrupts for this device.
+ - interrupts: Interrupt mapping for IRQ.
+ - interrupt-controller: Marks the device node as an interrupt controller.
+ - #interrupt-cells : Should be two.
+ - first cell is the pin number
+ - second cell is used to specify flags.
+ See also Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
Example:
@@ -29,6 +36,11 @@ Example:
#size-cells = <0>;
reg = <0x74>;
+ interrupt-parent = <&ipic>;
+ interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v4 3/5] i2c: mux: pca954x: Add interrupt controller support
From: Phil Reid @ 2017-01-16 3:11 UTC (permalink / raw)
To: peda-koto5C5qi+TLoDKTGw+V6w, wsa-z923LK4zBo2bacvFa/9K2g,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1484536275-75995-1-git-send-email-preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO@public.gmane.org>
Various muxes can aggregate multiple interrupts from each i2c bus.
All of the muxes with interrupt support combine the active low irq lines
using an internal 'and' function and generate a combined active low
output. The muxes do provide the ability to read a control register to
determine which irq is active. By making the mux an irq controller isr
latency can potentially be reduced by reading the status register and
then only calling the registered isr on that bus segment.
As there is no irq masking on the mux irq are disabled until irq_unmask is
called at least once.
Signed-off-by: Phil Reid <preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO@public.gmane.org>
---
drivers/i2c/muxes/i2c-mux-pca954x.c | 141 +++++++++++++++++++++++++++++++++++-
1 file changed, 139 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index bbf088e..f55da88 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -41,14 +41,20 @@
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/i2c/pca954x.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/of_irq.h>
#include <linux/pm.h>
#include <linux/slab.h>
+#include <linux/spinlock.h>
#define PCA954X_MAX_NCHANS 8
+#define PCA954X_IRQ_OFFSET 4
+
enum pca_type {
pca_9540,
pca_9542,
@@ -63,6 +69,7 @@ enum pca_type {
struct chip_desc {
u8 nchans;
u8 enable; /* used for muxes only */
+ u8 has_irq;
enum muxtype {
pca954x_ismux = 0,
pca954x_isswi
@@ -75,6 +82,10 @@ struct pca954x {
u8 last_chan; /* last register value */
u8 deselect;
struct i2c_client *client;
+
+ struct irq_domain *irq;
+ unsigned int irq_mask;
+ spinlock_t lock;
};
/* Provide specs for the PCA954x types we know about */
@@ -87,19 +98,23 @@ struct pca954x {
[pca_9542] = {
.nchans = 2,
.enable = 0x4,
+ .has_irq = 1,
.muxtype = pca954x_ismux,
},
[pca_9543] = {
.nchans = 2,
+ .has_irq = 1,
.muxtype = pca954x_isswi,
},
[pca_9544] = {
.nchans = 4,
.enable = 0x4,
+ .has_irq = 1,
.muxtype = pca954x_ismux,
},
[pca_9545] = {
.nchans = 4,
+ .has_irq = 1,
.muxtype = pca954x_isswi,
},
[pca_9547] = {
@@ -222,6 +237,114 @@ static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan)
return pca954x_reg_write(muxc->parent, client, data->last_chan);
}
+static irqreturn_t pca954x_irq_handler(int irq, void *dev_id)
+{
+ struct pca954x *data = dev_id;
+ unsigned int child_irq;
+ int ret, i, handled;
+
+ ret = i2c_smbus_read_byte(data->client);
+ if (ret < 0)
+ return IRQ_NONE;
+
+ for (i = 0; i < data->chip->nchans; i++) {
+ if (ret & BIT(PCA954X_IRQ_OFFSET + i)) {
+ child_irq = irq_linear_revmap(data->irq, i);
+ handle_nested_irq(child_irq);
+ handled++;
+ }
+ }
+ return handled ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static void pca954x_irq_mask(struct irq_data *idata)
+{
+ struct pca954x *data = irq_data_get_irq_chip_data(idata);
+ unsigned int pos = idata->hwirq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&data->lock, flags);
+
+ data->irq_mask &= ~BIT(pos);
+ if (!data->irq_mask)
+ disable_irq(data->client->irq);
+
+ spin_unlock_irqrestore(&data->lock, flags);
+}
+
+static void pca954x_irq_unmask(struct irq_data *idata)
+{
+ struct pca954x *data = irq_data_get_irq_chip_data(idata);
+ unsigned int pos = idata->hwirq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&data->lock, flags);
+
+ if (!data->irq_mask)
+ enable_irq(data->client->irq);
+ data->irq_mask |= BIT(pos);
+
+ spin_unlock_irqrestore(&data->lock, flags);
+}
+
+static int pca954x_irq_set_type(struct irq_data *idata, unsigned int type)
+{
+ if ((type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_LEVEL_LOW)
+ return -EINVAL;
+ return 0;
+}
+
+static struct irq_chip pca954x_irq_chip = {
+ .name = "i2c-mux-pca954x",
+ .irq_mask = pca954x_irq_mask,
+ .irq_unmask = pca954x_irq_unmask,
+ .irq_set_type = pca954x_irq_set_type,
+};
+
+static int pca954x_irq_setup(struct i2c_mux_core *muxc)
+{
+ struct pca954x *data = i2c_mux_priv(muxc);
+ struct i2c_client *client = data->client;
+ int c, err, irq;
+
+ if (!data->chip->has_irq || client->irq <= 0)
+ return 0;
+
+ spin_lock_init(&data->lock);
+
+ data->irq = irq_domain_add_linear(client->dev.of_node,
+ data->chip->nchans,
+ &irq_domain_simple_ops, data);
+ if (!data->irq)
+ return -ENODEV;
+
+ for (c = 0; c < data->chip->nchans; c++) {
+ irq = irq_create_mapping(data->irq, c);
+ irq_set_chip_data(irq, data);
+ irq_set_chip_and_handler(irq, &pca954x_irq_chip,
+ handle_simple_irq);
+ }
+
+ err = devm_request_threaded_irq(&client->dev, data->client->irq, NULL,
+ pca954x_irq_handler,
+ IRQF_ONESHOT | IRQF_SHARED,
+ "pca954x", data);
+ if (err)
+ goto err_req_irq;
+
+ disable_irq(data->client->irq);
+
+ return 0;
+err_req_irq:
+ for (c = 0; c < data->chip->nchans; c++) {
+ irq = irq_find_mapping(data->irq, c);
+ irq_dispose_mapping(irq);
+ }
+ irq_domain_remove(data->irq);
+
+ return err;
+}
+
/*
* I2C init/probing/exit functions
*/
@@ -286,6 +409,10 @@ static int pca954x_probe(struct i2c_client *client,
idle_disconnect_dt = of_node &&
of_property_read_bool(of_node, "i2c-mux-idle-disconnect");
+ ret = pca954x_irq_setup(muxc);
+ if (ret)
+ goto fail_del_adapters;
+
/* Now create an adapter for each channel */
for (num = 0; num < data->chip->nchans; num++) {
bool idle_disconnect_pd = false;
@@ -311,7 +438,7 @@ static int pca954x_probe(struct i2c_client *client,
dev_err(&client->dev,
"failed to register multiplexed adapter"
" %d as bus %d\n", num, force);
- goto virt_reg_failed;
+ goto fail_del_adapters;
}
}
@@ -322,7 +449,7 @@ static int pca954x_probe(struct i2c_client *client,
return 0;
-virt_reg_failed:
+fail_del_adapters:
i2c_mux_del_adapters(muxc);
return ret;
}
@@ -330,6 +457,16 @@ static int pca954x_probe(struct i2c_client *client,
static int pca954x_remove(struct i2c_client *client)
{
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
+ struct pca954x *data = i2c_mux_priv(muxc);
+ int c, irq;
+
+ if (data->irq) {
+ for (c = 0; c < data->chip->nchans; c++) {
+ irq = irq_find_mapping(data->irq, c);
+ irq_dispose_mapping(irq);
+ }
+ irq_domain_remove(data->irq);
+ }
i2c_mux_del_adapters(muxc);
return 0;
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v4 4/5] dt: bindings: i2c-mux-pca954x: Add documentation for i2c-mux-irq-mask-en
From: Phil Reid @ 2017-01-16 3:11 UTC (permalink / raw)
To: peda, wsa, robh+dt, mark.rutland, preid, linux-i2c, devicetree
In-Reply-To: <1484536275-75995-1-git-send-email-preid@electromag.com.au>
Unfortunately some hardware device will assert their irq line immediately
on power on and provide no mechanism to mask the irq. As the i2c muxes
provide no method to mask irq line this provides a work around by keeping
the parent irq masked until enough device drivers have loaded to service
all pending interrupts.
For example the the ltc1760 assert its SMBALERT irq immediately on power
on. With two ltc1760 attached to bus 0 & 1 on a pca954x mux when the first
device is registered irq are enabled and fire continuously as the second
device driver has not yet loaded. Setting this parameter to 0x3 while
delay the irq being enabled until both devices are ready.
Acked-by: Peter Rosin <peda@axentia.se>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Phil Reid <preid@electromag.com.au>
---
Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
index aa09704..6de1e8e 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
@@ -19,6 +19,8 @@ Optional Properties:
- i2c-mux-idle-disconnect: Boolean; if defined, forces mux to disconnect all
children in idle state. This is necessary for example, if there are several
multiplexers on the bus and the devices behind them use same I2C addresses.
+ - nxp,irq-mask-enable: BitMask; Defines a mask for which irq lines need to be
+ unmasked before the parent irq line in enabled.
- interrupt-parent: Phandle for the interrupt controller that services
interrupts for this device.
- interrupts: Interrupt mapping for IRQ.
@@ -36,6 +38,7 @@ Example:
#size-cells = <0>;
reg = <0x74>;
+ nxp,irq-mask-enable = <0x3>;
interrupt-parent = <&ipic>;
interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
--
1.8.3.1
^ permalink raw reply related
* [PATCH v4 5/5] i2c: mux: pca954x: Add irq_mask_en to delay enabling irqs
From: Phil Reid @ 2017-01-16 3:11 UTC (permalink / raw)
To: peda-koto5C5qi+TLoDKTGw+V6w, wsa-z923LK4zBo2bacvFa/9K2g,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1484536275-75995-1-git-send-email-preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO@public.gmane.org>
Unfortunately some hardware device will assert their irq line immediately
on power on and provide no mechanism to mask the irq. As the i2c muxes
provide no method to mask irq line this provides a work around by keeping
the parent irq masked until enough device drivers have loaded to service
all pending interrupts.
For example the the ltc1760 assert its SMBALERT irq immediately on power
on. With two ltc1760 attached to bus 0 & 1 on a pca954x mux when the first
device is registered irq are enabled and fire continuously as the second
device driver has not yet loaded. Setting this parameter to 0x3 while
delay the irq being enabled until both devices are ready.
Acked-by: Peter Rosin <peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>
Signed-off-by: Phil Reid <preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO@public.gmane.org>
---
drivers/i2c/muxes/i2c-mux-pca954x.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index f55da88..66f7ed8 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -76,6 +76,19 @@ struct chip_desc {
} muxtype;
};
+/*
+ * irq_mask_enable: Provides a mechanism to work around hardware that asserts
+ * their irq immediately on power on. It allows the enabling of the irq to be
+ * delayed until the corresponding bits in the the irq_mask are set thru
+ * irq_unmask.
+ * For example the ltc1760 assert its SMBALERT irq immediately on power on.
+ * With two ltc1760 attached to bus 0 & 1 on a pca954x mux when the first
+ * device is registered irq are enabled and fire continuously as the second
+ * device driver has not yet loaded. Setting this parameter to 0x3 while
+ * delay the irq being enabled until both devices are ready.
+ * This workaround will not work if two devices share an interrupt on the
+ * same bus segment.
+ */
struct pca954x {
const struct chip_desc *chip;
@@ -84,6 +97,7 @@ struct pca954x {
struct i2c_client *client;
struct irq_domain *irq;
+ unsigned int irq_mask_enable;
unsigned int irq_mask;
spinlock_t lock;
};
@@ -280,9 +294,12 @@ static void pca954x_irq_unmask(struct irq_data *idata)
spin_lock_irqsave(&data->lock, flags);
- if (!data->irq_mask)
+ if (!data->irq_mask_enable && !data->irq_mask)
enable_irq(data->client->irq);
data->irq_mask |= BIT(pos);
+ if (data->irq_mask_enable &&
+ (data->irq_mask & data->irq_mask) == data->irq_mask_enable)
+ enable_irq(data->client->irq);
spin_unlock_irqrestore(&data->lock, flags);
}
@@ -409,6 +426,9 @@ static int pca954x_probe(struct i2c_client *client,
idle_disconnect_dt = of_node &&
of_property_read_bool(of_node, "i2c-mux-idle-disconnect");
+ of_property_read_u32(of_node, "nxp,irq-mask-enable",
+ &data->irq_mask_enable);
+
ret = pca954x_irq_setup(muxc);
if (ret)
goto fail_del_adapters;
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH v2 6/6] arm: dts: mt2701: Add thermal device node.
From: Dawei Chien @ 2017-01-16 3:44 UTC (permalink / raw)
To: Matthias Brugger
Cc: Erin Lo, srv_heupstream, devicetree, linux-arm-kernel,
linux-kernel, linux-mediatek
In-Reply-To: <c8bbd4a4-2207-44f0-4462-3761c1d6c8a9@gmail.com>
On Fri, 2017-01-13 at 16:27 +0100, Matthias Brugger wrote:
>
> On 13/01/17 09:42, Erin Lo wrote:
> > From: Dawei Chien <dawei.chien@mediatek.com>
> >
> > Add thermal controller device nodes for MT2701.
> >
> > Signed-off-by: Dawei Chien <dawei.chien@mediatek.com>
> > Signed-off-by: Erin Lo <erin.lo@mediatek.com>
> > ---
> > arch/arm/boot/dts/mt2701.dtsi | 43 +++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 43 insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
> > index 3847f70..c43d5f8 100644
> > --- a/arch/arm/boot/dts/mt2701.dtsi
> > +++ b/arch/arm/boot/dts/mt2701.dtsi
> > @@ -89,6 +89,36 @@
> > clock-output-names = "rtc32k";
> > };
> >
> > + thermal-zones {
> > + cpu_thermal: cpu_thermal {
> > + polling-delay-passive = <1000>; /* milliseconds */
> > + polling-delay = <1000>; /* milliseconds */
> > +
> > + thermal-sensors = <&thermal 0>;
> > + sustainable-power = <1000>;
> > +
> > + trips {
> > + threshold: trip-point@0 {
> > + temperature = <68000>;
> > + hysteresis = <2000>;
> > + type = "passive";
> > + };
> > +
> > + target: trip-point@1 {
> > + temperature = <85000>;
> > + hysteresis = <2000>;
> > + type = "passive";
> > + };
> > +
> > + cpu_crit: cpu_crit@0 {
> > + temperature = <115000>;
> > + hysteresis = <2000>;
> > + type = "critical";
> > + };
> > + };
> > + };
> > + };
> > +
> > timer {
> > compatible = "arm,armv7-timer";
> > interrupt-parent = <&gic>;
> > @@ -270,6 +300,19 @@
> > status = "disabled";
> > };
> >
> > + thermal: thermal@1100b000 {
> > + #thermal-sensor-cells = <0>;
> > + compatible = "mediatek,mt2701-thermal";
> > + reg = <0 0x1100b000 0 0x1000>;
> > + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_LOW>;
> > + clocks = <&pericfg CLK_PERI_THERM>, <&pericfg CLK_PERI_AUXADC>;
> > + clock-names = "therm", "auxadc";
> > + resets = <&pericfg 0x10>;
>
> should be MT2701_PERI_AUXADC_SW_RST, right?
>
Thank you for your reminding, I didn't realize mt2701-resets.h upstream
already, I would update on next version, thank you.
resets = <&pericfg MT2701_PERI_AUXADC_SW_RST>;
> > + reset-names = "therm";
> > + mediatek,auxadc = <&auxadc>;
> > + mediatek,apmixedsys = <&apmixedsys>;
> > + };
> > +
> > nandc: nfi@1100d000 {
> > compatible = "mediatek,mt2701-nfc";
> > reg = <0 0x1100d000 0 0x1000>;
> >
^ permalink raw reply
* Re: [PATCH v2 6/6] arm: dts: mt2701: Add thermal device node.
From: Dawei Chien @ 2017-01-16 3:46 UTC (permalink / raw)
To: Matthias Brugger
Cc: Erin Lo, srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1484538290.13258.3.camel@mtksdaap41>
On Mon, 2017-01-16 at 11:44 +0800, Dawei Chien wrote:
> On Fri, 2017-01-13 at 16:27 +0100, Matthias Brugger wrote:
> >
> > On 13/01/17 09:42, Erin Lo wrote:
> > > From: Dawei Chien <dawei.chien-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > >
> > > Add thermal controller device nodes for MT2701.
> > >
> > > Signed-off-by: Dawei Chien <dawei.chien-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > > Signed-off-by: Erin Lo <erin.lo-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > > ---
> > > arch/arm/boot/dts/mt2701.dtsi | 43 +++++++++++++++++++++++++++++++++++++++++++
> > > 1 file changed, 43 insertions(+)
> > >
> > > diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
> > > index 3847f70..c43d5f8 100644
> > > --- a/arch/arm/boot/dts/mt2701.dtsi
> > > +++ b/arch/arm/boot/dts/mt2701.dtsi
> > > @@ -89,6 +89,36 @@
> > > clock-output-names = "rtc32k";
> > > };
> > >
> > > + thermal-zones {
> > > + cpu_thermal: cpu_thermal {
> > > + polling-delay-passive = <1000>; /* milliseconds */
> > > + polling-delay = <1000>; /* milliseconds */
> > > +
> > > + thermal-sensors = <&thermal 0>;
> > > + sustainable-power = <1000>;
> > > +
> > > + trips {
> > > + threshold: trip-point@0 {
> > > + temperature = <68000>;
> > > + hysteresis = <2000>;
> > > + type = "passive";
> > > + };
> > > +
> > > + target: trip-point@1 {
> > > + temperature = <85000>;
> > > + hysteresis = <2000>;
> > > + type = "passive";
> > > + };
> > > +
> > > + cpu_crit: cpu_crit@0 {
> > > + temperature = <115000>;
> > > + hysteresis = <2000>;
> > > + type = "critical";
> > > + };
> > > + };
> > > + };
> > > + };
> > > +
> > > timer {
> > > compatible = "arm,armv7-timer";
> > > interrupt-parent = <&gic>;
> > > @@ -270,6 +300,19 @@
> > > status = "disabled";
> > > };
> > >
> > > + thermal: thermal@1100b000 {
> > > + #thermal-sensor-cells = <0>;
> > > + compatible = "mediatek,mt2701-thermal";
> > > + reg = <0 0x1100b000 0 0x1000>;
> > > + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_LOW>;
> > > + clocks = <&pericfg CLK_PERI_THERM>, <&pericfg CLK_PERI_AUXADC>;
> > > + clock-names = "therm", "auxadc";
> > > + resets = <&pericfg 0x10>;
> >
> > should be MT2701_PERI_AUXADC_SW_RST, right?
> >
> Thank you for your reminding, I didn't realize mt2701-resets.h upstream
> already, I would update on next version, thank you.
>
> resets = <&pericfg MT2701_PERI_AUXADC_SW_RST>;
Actually, Should be MT2701_PERI_THERM_SW_RST.
resets = <&pericfg MT2701_PERI_THERM_SW_RST>;
> > > + reset-names = "therm";
> > > + mediatek,auxadc = <&auxadc>;
> > > + mediatek,apmixedsys = <&apmixedsys>;
> > > + };
> > > +
> > > nandc: nfi@1100d000 {
> > > compatible = "mediatek,mt2701-nfc";
> > > reg = <0 0x1100d000 0 0x1000>;
> > >
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 2/4] clk: samsung: Remove Exynos4415 driver (SoC not supported anymore)
From: Chanwoo Choi @ 2017-01-16 3:55 UTC (permalink / raw)
To: Krzysztof Kozlowski, Sylwester Nawrocki, Tomasz Figa,
Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kukjin Kim, Javier Martinez Canillas, Inki Dae, Joonyoung Shim,
Seung-Woo Kim, Kyungmin Park, Linus Walleij, linux-samsung-soc,
linux-clk, devicetree, linux-arm-kernel, linux-kernel, dri-devel,
linux-gpio
In-Reply-To: <20170114123642.15581-3-krzk@kernel.org>
Hi,
On 2017년 01월 14일 21:36, Krzysztof Kozlowski wrote:
> Support for Exynos4415 is going away because there are no internal nor
> external users.
>
> Since commit 46dcf0ff0de3 ("ARM: dts: exynos: Remove exynos4415.dtsi"),
> the platform cannot be instantiated so remove also the drivers.
>
> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
> ---
> .../devicetree/bindings/clock/exynos4415-clock.txt | 38 -
> drivers/clk/samsung/Makefile | 1 -
> drivers/clk/samsung/clk-exynos4415.c | 1022 --------------------
> include/dt-bindings/clock/exynos4415.h | 360 -------
> 4 files changed, 1421 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/clock/exynos4415-clock.txt
> delete mode 100644 drivers/clk/samsung/clk-exynos4415.c
> delete mode 100644 include/dt-bindings/clock/exynos4415.h
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
[snip]
--
Best Regards,
Chanwoo Choi
S/W Center, Samsung Electronics
^ permalink raw reply
* Re: [PATCH 3/4] pinctrl: samsung: Remove support for Exynos4415 (SoC not supported anymore)
From: Chanwoo Choi @ 2017-01-16 3:56 UTC (permalink / raw)
To: Krzysztof Kozlowski, Sylwester Nawrocki, Tomasz Figa,
Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kukjin Kim, Javier Martinez Canillas, Inki Dae, Joonyoung Shim,
Seung-Woo Kim, Kyungmin Park, Linus Walleij, linux-samsung-soc,
linux-clk, devicetree, linux-arm-kernel, linux-kernel, dri-devel,
linux-gpio
In-Reply-To: <20170114123642.15581-4-krzk@kernel.org>
On 2017년 01월 14일 21:36, Krzysztof Kozlowski wrote:
> Support for Exynos4415 is going away because there are no internal nor
> external users.
>
> Since commit 46dcf0ff0de3 ("ARM: dts: exynos: Remove exynos4415.dtsi"),
> the platform cannot be instantiated so remove also the drivers.
>
> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
> ---
> drivers/pinctrl/samsung/pinctrl-exynos.c | 75 -------------------------------
> drivers/pinctrl/samsung/pinctrl-samsung.c | 2 -
> drivers/pinctrl/samsung/pinctrl-samsung.h | 1 -
> 3 files changed, 78 deletions(-)
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
[snip]
--
Best Regards,
Chanwoo Choi
S/W Center, Samsung Electronics
^ permalink raw reply
* Re: [PATCH 1/4] ARM: EXYNOS: Remove Exynos4415 driver (SoC not supported anymore)
From: Chanwoo Choi @ 2017-01-16 3:56 UTC (permalink / raw)
To: Krzysztof Kozlowski, Sylwester Nawrocki, Tomasz Figa,
Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kukjin Kim, Javier Martinez Canillas, Inki Dae, Joonyoung Shim,
Seung-Woo Kim, Kyungmin Park, Linus Walleij, linux-samsung-soc,
linux-clk, devicetree, linux-arm-kernel, linux-kernel, dri-devel,
linux-gpio
In-Reply-To: <20170114123642.15581-2-krzk@kernel.org>
On 2017년 01월 14일 21:36, Krzysztof Kozlowski wrote:
> Support for Exynos4415 is going away because there are no internal nor
> external users.
>
> Since commit 46dcf0ff0de3 ("ARM: dts: exynos: Remove exynos4415.dtsi"),
> the platform cannot be instantiated so remove also the mach code.
>
> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
> ---
> arch/arm/mach-exynos/Kconfig | 5 -----
> arch/arm/mach-exynos/exynos.c | 1 -
> arch/arm/mach-exynos/suspend.c | 1 -
> 3 files changed, 7 deletions(-)
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
[snip]
--
Best Regards,
Chanwoo Choi
S/W Center, Samsung Electronics
^ permalink raw reply
* [PATCH v1 1/3] dt: bindings: add documentation for zx2967 family watchdog controller
From: Baoyou Xie @ 2017-01-16 4:19 UTC (permalink / raw)
To: jun.nie-QSEj5FYQhm4dnm+yROfE0A, wim-IQzOog9fTRqzQB+pC5nmwQ,
linux-0h96xk9xTtrk1uMJSBkQmQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
shawnguo-DgEjT+Ai2ygdnm+yROfE0A,
baoyou.xie-QSEj5FYQhm4dnm+yROfE0A,
xie.baoyou-Th6q7B73Y6EnDS1+zs4M5A,
chen.chaokai-Th6q7B73Y6EnDS1+zs4M5A,
wang.qiang01-Th6q7B73Y6EnDS1+zs4M5A
This patch adds dt-binding documentation for zx2967 family
watchdog controller.
Signed-off-by: Baoyou Xie <baoyou.xie-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
.../bindings/watchdog/zte,zx2967-wdt.txt | 29 ++++++++++++++++++++++
1 file changed, 29 insertions(+)
create mode 100644 Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt
diff --git a/Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt b/Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt
new file mode 100644
index 0000000..0fe0d40
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt
@@ -0,0 +1,29 @@
+ZTE zx2967 Watchdog timer
+
+Required properties:
+
+- compatible : should be one of the following.
+ * zte,zx296718-wdt
+- reg : Specifies base physical address and size of the registers.
+- clocks : Pairs of phandle and specifier referencing the controller's clocks.
+- clock-names: "wdtclk" for the watchdog clock.
+- resets : Reference to the reset controller controlling the watchdog
+ controller.
+- reset-names : Must include the following entries:
+ * wdtrst
+
+Optional properties:
+
+- reset-mask-config : Mask and configuare value that be wrote to aon-sysctrl.
+
+Example:
+
+wdt_ares: watchdog@1465000 {
+ compatible = "zte,zx296718-wdt";
+ reg = <0x1465000 0x1000>;
+ clocks = <&topcrm WDT_WCLK>;
+ clock-names = "wdtclk";
+ resets = <&toprst 35>;
+ reset-names = "wdtrst";
+ reset-mask-config = <1 0x115>;
+};
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v1 2/3] MAINTAINERS: add zx2967 watchdog controller driver to ARM ZTE architecture
From: Baoyou Xie @ 2017-01-16 4:19 UTC (permalink / raw)
To: jun.nie-QSEj5FYQhm4dnm+yROfE0A, wim-IQzOog9fTRqzQB+pC5nmwQ,
linux-0h96xk9xTtrk1uMJSBkQmQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
shawnguo-DgEjT+Ai2ygdnm+yROfE0A,
baoyou.xie-QSEj5FYQhm4dnm+yROfE0A,
xie.baoyou-Th6q7B73Y6EnDS1+zs4M5A,
chen.chaokai-Th6q7B73Y6EnDS1+zs4M5A,
wang.qiang01-Th6q7B73Y6EnDS1+zs4M5A
In-Reply-To: <1484540395-3335-1-git-send-email-baoyou.xie-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Add the zx2967 watchdog controller driver as maintained by ARM ZTE
architecture maintainers, as they're parts of the core IP.
Signed-off-by: Baoyou Xie <baoyou.xie-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
MAINTAINERS | 2 ++
1 file changed, 2 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 08f8155..77f0290 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1983,11 +1983,13 @@ F: drivers/clk/zte/
F: drivers/reset/reset-zx2967.c
F: drivers/soc/zte/
F: drivers/thermal/zx*
+F: drivers/watchdog/zx2967_wdt.c
F: Documentation/devicetree/bindings/arm/zte.txt
F: Documentation/devicetree/bindings/clock/zx296702-clk.txt
F: Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
F: Documentation/devicetree/bindings/soc/zte/
F: Documentation/devicetree/bindings/thermal/zx*
+F: Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt
F: include/dt-bindings/soc/zx*.h
ARM/ZYNQ ARCHITECTURE
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v1 3/3] watchdog: zx2967: add watchdog controller driver for ZTE's zx2967 family
From: Baoyou Xie @ 2017-01-16 4:19 UTC (permalink / raw)
To: jun.nie-QSEj5FYQhm4dnm+yROfE0A, wim-IQzOog9fTRqzQB+pC5nmwQ,
linux-0h96xk9xTtrk1uMJSBkQmQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
shawnguo-DgEjT+Ai2ygdnm+yROfE0A,
baoyou.xie-QSEj5FYQhm4dnm+yROfE0A,
xie.baoyou-Th6q7B73Y6EnDS1+zs4M5A,
chen.chaokai-Th6q7B73Y6EnDS1+zs4M5A,
wang.qiang01-Th6q7B73Y6EnDS1+zs4M5A
In-Reply-To: <1484540395-3335-1-git-send-email-baoyou.xie-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
This patch adds watchdog controller driver for ZTE's zx2967 family.
Signed-off-by: Baoyou Xie <baoyou.xie-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
drivers/watchdog/Kconfig | 10 ++
drivers/watchdog/Makefile | 1 +
drivers/watchdog/zx2967_wdt.c | 405 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 416 insertions(+)
create mode 100644 drivers/watchdog/zx2967_wdt.c
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 3eb58cb..79027da 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -714,6 +714,16 @@ config ASPEED_WATCHDOG
To compile this driver as a module, choose M here: the
module will be called aspeed_wdt.
+config ZX2967_WATCHDOG
+ tristate "ZTE zx2967 SoCs watchdog support"
+ depends on ARCH_ZX
+ select WATCHDOG_CORE
+ help
+ Say Y here to include support for the watchdog timer
+ in ZTE zx2967 SoCs.
+ To compile this driver as a module, choose M here: the
+ module will be called zx2967_wdt.
+
# AVR32 Architecture
config AT32AP700X_WDT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index caa9f4a..ea08925 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o
obj-$(CONFIG_ATLAS7_WATCHDOG) += atlas7_wdt.o
obj-$(CONFIG_RENESAS_WDT) += renesas_wdt.o
obj-$(CONFIG_ASPEED_WATCHDOG) += aspeed_wdt.o
+obj-$(CONFIG_ZX2967_WATCHDOG) += zx2967_wdt.o
# AVR32 Architecture
obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
diff --git a/drivers/watchdog/zx2967_wdt.c b/drivers/watchdog/zx2967_wdt.c
new file mode 100644
index 0000000..8791dd2
--- /dev/null
+++ b/drivers/watchdog/zx2967_wdt.c
@@ -0,0 +1,405 @@
+/*
+ * watchdog driver for ZTE's zx2967 family
+ *
+ * Copyright (C) 2017 ZTE Ltd.
+ *
+ * Author: Baoyou Xie <baoyou.xie-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/reset.h>
+#include <linux/watchdog.h>
+
+#define ZX2967_WDT_CFG_REG 0x4
+#define ZX2967_WDT_LOAD_REG 0x8
+#define ZX2967_WDT_REFRESH_REG 0x18
+#define ZX2967_WDT_START_REG 0x1c
+
+#define ZX2967_WDT_REFRESH_MASK 0x3f
+
+#define ZX2967_WDT_CFG_DIV(n) ((((n)&0xff) - 1) << 8)
+#define ZX2967_WDT_START_EN 0x1
+
+#define ZX2967_WDT_WRITEKEY 0x12340000
+
+#define ZX2967_WDT_DIV_DEFAULT 16
+#define ZX2967_WDT_DEFAULT_TIMEOUT 32
+#define ZX2967_WDT_MIN_TIMEOUT 1
+#define ZX2967_WDT_MAX_TIMEOUT 500
+#define ZX2967_WDT_MAX_COUNT 0xffff
+
+#define ZX2967_WDT_FLAG_REBOOT_MON (1 << 0)
+
+#define ZX2967_RESET_MASK_REG 0xb0
+
+#define zx2967_wdt_write_reg(v, r) \
+ writel((v) | ZX2967_WDT_WRITEKEY, r)
+#define zx2967_wdt_read_reg(r) readl(r)
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+static unsigned int timeout = ZX2967_WDT_DEFAULT_TIMEOUT;
+
+struct zx2967_wdt {
+ struct device *dev;
+ struct clk *clock;
+ void __iomem *reg_base;
+ unsigned int conf;
+ unsigned int load;
+ unsigned int flags;
+ spinlock_t lock;
+ struct watchdog_device wdt_device;
+ struct notifier_block restart_handler;
+ struct notifier_block reboot_handler;
+};
+
+static void zx2967_wdt_refresh(struct zx2967_wdt *wdt)
+{
+ unsigned int val;
+
+ spin_lock(&wdt->lock);
+
+ val = zx2967_wdt_read_reg(wdt->reg_base + ZX2967_WDT_REFRESH_REG);
+ val ^= ZX2967_WDT_REFRESH_MASK;
+ zx2967_wdt_write_reg(val, wdt->reg_base + ZX2967_WDT_REFRESH_REG);
+
+ spin_unlock(&wdt->lock);
+}
+
+static void __zx2967_wdt_stop(struct zx2967_wdt *wdt)
+{
+ unsigned int val;
+
+ spin_lock(&wdt->lock);
+
+ val = zx2967_wdt_read_reg(wdt->reg_base + ZX2967_WDT_START_REG);
+ val &= ~(ZX2967_WDT_START_EN);
+ zx2967_wdt_write_reg(val, wdt->reg_base + ZX2967_WDT_START_REG);
+
+ spin_unlock(&wdt->lock);
+}
+
+static void __zx2967_wdt_start(struct zx2967_wdt *wdt)
+{
+ unsigned int val;
+
+ spin_lock(&wdt->lock);
+
+ val = zx2967_wdt_read_reg(wdt->reg_base + ZX2967_WDT_START_REG);
+ val |= ZX2967_WDT_START_EN;
+ zx2967_wdt_write_reg(val, wdt->reg_base + ZX2967_WDT_START_REG);
+
+ spin_unlock(&wdt->lock);
+}
+
+static unsigned int
+__zx2967_wdt_set_timeout(struct zx2967_wdt *wdt, unsigned int timeout)
+{
+ unsigned int freq = clk_get_rate(wdt->clock);
+ unsigned int divisor = ZX2967_WDT_DIV_DEFAULT, count;
+
+ count = timeout * freq;
+ if (count > divisor * ZX2967_WDT_MAX_COUNT)
+ divisor = DIV_ROUND_UP(count, ZX2967_WDT_MAX_COUNT);
+ count = DIV_ROUND_UP(count, divisor);
+ zx2967_wdt_write_reg(ZX2967_WDT_CFG_DIV(divisor),
+ wdt->reg_base + ZX2967_WDT_CFG_REG);
+ zx2967_wdt_write_reg(count, wdt->reg_base + ZX2967_WDT_LOAD_REG);
+ zx2967_wdt_refresh(wdt);
+
+ wdt->load = count;
+ dev_info(wdt->dev, "count=%d, timeout=%d, divisor=%d\n",
+ count, timeout, divisor);
+
+ return (count * divisor) / freq;
+}
+
+static int zx2967_wdt_set_timeout(struct watchdog_device *wdd,
+ unsigned int timeout)
+{
+ struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ if (watchdog_timeout_invalid(&wdt->wdt_device, timeout)) {
+ dev_err(wdt->dev, "timeout %d is invalid\n", timeout);
+
+ return -EINVAL;
+ }
+
+ wdd->timeout = __zx2967_wdt_set_timeout(wdt, timeout);
+
+ return 0;
+}
+
+static int zx2967_wdt_start(struct watchdog_device *wdd)
+{
+ struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ __zx2967_wdt_stop(wdt);
+ zx2967_wdt_set_timeout(wdd, wdd->timeout);
+ __zx2967_wdt_start(wdt);
+
+ return 0;
+}
+
+static int zx2967_wdt_stop(struct watchdog_device *wdd)
+{
+ struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ __zx2967_wdt_stop(wdt);
+
+ return 0;
+}
+
+static int zx2967_wdt_keepalive(struct watchdog_device *wdd)
+{
+ struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ zx2967_wdt_refresh(wdt);
+
+ return 0;
+}
+
+#define ZX2967_WDT_OPTIONS \
+ (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE)
+static const struct watchdog_info zx2967_wdt_ident = {
+ .options = ZX2967_WDT_OPTIONS,
+ .firmware_version = 0,
+ .identity = "zx2967 watchdog",
+};
+
+static struct watchdog_ops zx2967_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = zx2967_wdt_start,
+ .stop = zx2967_wdt_stop,
+ .ping = zx2967_wdt_keepalive,
+ .set_timeout = zx2967_wdt_set_timeout,
+};
+
+static void zx2967_wdt_fix_sysdown(struct zx2967_wdt *wdt)
+{
+ __zx2967_wdt_stop(wdt);
+ __zx2967_wdt_set_timeout(wdt, 15);
+ __zx2967_wdt_start(wdt);
+}
+
+static int zx2967_wdt_notify_sys(struct notifier_block *this,
+ unsigned long code, void *unused)
+{
+ struct zx2967_wdt *wdt = container_of(this, struct zx2967_wdt,
+ reboot_handler);
+
+ wdt->flags |= ZX2967_WDT_FLAG_REBOOT_MON;
+ switch (code) {
+ case SYS_HALT:
+ case SYS_POWER_OFF:
+ case SYS_RESTART:
+ zx2967_wdt_fix_sysdown(wdt);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int zx2967_wdt_restart(struct notifier_block *this,
+ unsigned long mode, void *cmd)
+{
+ struct zx2967_wdt *wdt;
+
+ wdt = container_of(this, struct zx2967_wdt, restart_handler);
+
+ zx2967_wdt_stop(&wdt->wdt_device);
+
+ zx2967_wdt_write_reg(0x80, wdt->reg_base + ZX2967_WDT_LOAD_REG);
+ zx2967_wdt_refresh(wdt);
+ zx2967_wdt_write_reg(ZX2967_WDT_START_EN,
+ wdt->reg_base + ZX2967_WDT_START_REG);
+
+ zx2967_wdt_start(&wdt->wdt_device);
+ /* wait for reset*/
+ mdelay(500);
+
+ return NOTIFY_DONE;
+}
+
+static void zx2967_reset_mask_config(struct device *dev)
+{
+ struct device_node *np = NULL;
+ void __iomem *reg;
+ unsigned int val, mask, config, size;
+ const unsigned int *prop;
+
+ prop = of_get_property(dev->of_node, "reset-mask-config", &size);
+ if (size < (sizeof(*prop) * 2)) {
+ dev_err(dev, "bad data for reset-mask-config");
+ return;
+ }
+ config = be32_to_cpup(prop++);
+ mask = be32_to_cpup(prop);
+ np = of_find_compatible_node(NULL, NULL, "zte,aon-sysctrl");
+ if (!np) {
+ dev_err(dev, "Cannot found pcu device node\n");
+ return;
+ }
+ reg = of_iomap(np, 0) + ZX2967_RESET_MASK_REG;
+ of_node_put(np);
+
+ val = readl(reg);
+ val &= ~mask;
+ val |= config;
+ writel(val, reg);
+}
+
+static int zx2967_wdt_probe(struct platform_device *pdev)
+{
+ struct device *dev;
+ struct zx2967_wdt *wdt;
+ struct resource *base;
+ int err, ret = 0;
+ unsigned int rate, val;
+
+ struct reset_control *rstc;
+
+ dev = &pdev->dev;
+
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
+ if (!wdt) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ platform_set_drvdata(pdev, wdt);
+
+ wdt->dev = dev;
+ spin_lock_init(&wdt->lock);
+
+ wdt->wdt_device.info = &zx2967_wdt_ident;
+ wdt->wdt_device.ops = &zx2967_wdt_ops;
+ wdt->wdt_device.timeout = ZX2967_WDT_DEFAULT_TIMEOUT;
+ wdt->wdt_device.max_timeout = ZX2967_WDT_MAX_TIMEOUT;
+ wdt->wdt_device.min_timeout = ZX2967_WDT_MIN_TIMEOUT;
+ wdt->wdt_device.parent = &pdev->dev;
+
+ base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ wdt->reg_base = devm_ioremap_resource(dev, base);
+
+ if (of_find_property(dev->of_node, "reset-mask-config", NULL))
+ zx2967_reset_mask_config(dev);
+
+ wdt->reboot_handler.notifier_call = zx2967_wdt_notify_sys;
+ ret = register_reboot_notifier(&wdt->reboot_handler);
+ wdt->clock = devm_clk_get(dev, "wdtclk");
+ if (IS_ERR(wdt->clock)) {
+ dev_err(dev, "failed to find watchdog clock source\n");
+ ret = PTR_ERR(wdt->clock);
+ goto out;
+ }
+ ret = clk_prepare_enable(wdt->clock);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable clock\n");
+ goto out;
+ }
+
+ rate = clk_get_rate(wdt->clock);
+ if (rate == 24000000)
+ ret = clk_set_rate(wdt->clock, 32768);
+ rate = clk_get_rate(wdt->clock);
+
+ rstc = devm_reset_control_get(dev, "wdtrst");
+ if (!rstc) {
+ dev_info(dev, "rstc get failed");
+ } else {
+ reset_control_assert(rstc);
+ mdelay(10);
+ reset_control_deassert(rstc);
+ }
+
+ watchdog_set_drvdata(&wdt->wdt_device, wdt);
+
+ watchdog_init_timeout(&wdt->wdt_device, timeout, &pdev->dev);
+ watchdog_set_nowayout(&wdt->wdt_device, nowayout);
+
+ zx2967_wdt_stop(&wdt->wdt_device);
+
+ err = watchdog_register_device(&wdt->wdt_device);
+ if (unlikely(err)) {
+ ret = err;
+ goto fail_register;
+ }
+
+ wdt->restart_handler.notifier_call = zx2967_wdt_restart;
+ wdt->restart_handler.priority = 128;
+ ret = register_restart_handler(&wdt->restart_handler);
+ if (ret) {
+ pr_err("cannot register restart handler, %d\n", ret);
+ goto fail_restart;
+ }
+
+ val = zx2967_wdt_read_reg(wdt->reg_base + ZX2967_WDT_START_REG);
+ dev_info(&pdev->dev, "watchdog enabled (timeout=%d sec, nowayout=%d)",
+ wdt->wdt_device.timeout, nowayout);
+
+ return 0;
+
+fail_restart:
+ watchdog_unregister_device(&wdt->wdt_device);
+fail_register:
+ clk_disable_unprepare(wdt->clock);
+out:
+ return ret;
+}
+
+static int zx2967_wdt_remove(struct platform_device *pdev)
+{
+ struct zx2967_wdt *wdt = platform_get_drvdata(pdev);
+
+ unregister_restart_handler(&wdt->restart_handler);
+ watchdog_unregister_device(&wdt->wdt_device);
+ clk_disable_unprepare(wdt->clock);
+
+ return 0;
+}
+
+static void zx2967_wdt_shutdown(struct platform_device *pdev)
+{
+ struct zx2967_wdt *wdt = platform_get_drvdata(pdev);
+
+ if (!(wdt->flags & ZX2967_WDT_FLAG_REBOOT_MON))
+ zx2967_wdt_stop(&wdt->wdt_device);
+}
+
+static const struct of_device_id zx2967_wdt_match[] = {
+ { .compatible = "zte,zx296718-wdt", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, zx2967_wdt_match);
+
+static const struct platform_device_id zx2967_wdt_ids[] = {
+ { .name = "zx2967-wdt", },
+ {}
+};
+MODULE_DEVICE_TABLE(platform, zx2967_wdt_ids);
+
+static struct platform_driver zx2967_wdt_driver = {
+ .probe = zx2967_wdt_probe,
+ .remove = zx2967_wdt_remove,
+ .shutdown = zx2967_wdt_shutdown,
+ .id_table = zx2967_wdt_ids,
+ .driver = {
+ .name = "zx2967-wdt",
+ .of_match_table = of_match_ptr(zx2967_wdt_match),
+ },
+};
+module_platform_driver(zx2967_wdt_driver);
+
+MODULE_AUTHOR("Baoyou Xie <baoyou.xie-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>");
+MODULE_DESCRIPTION("ZTE zx2967 Watchdog Device Driver");
+MODULE_LICENSE("GPL");
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH 09/37] PCI: dwc: designware: Parse *num-lanes* property in dw_pcie_setup_rc
From: Kishon Vijay Abraham I @ 2017-01-16 5:19 UTC (permalink / raw)
To: Joao Pinto, Bjorn Helgaas, Jingoo Han, Arnd Bergmann
Cc: devicetree, linux-samsung-soc, linux-doc, linux-pci, nsekhar,
linux-kernel, linux-arm-kernel, linux-arm-msm, linux-omap,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <c3c55af3-29d1-dc59-3ae4-9a4132c99092@synopsys.com>
Hi,
On Friday 13 January 2017 10:43 PM, Joao Pinto wrote:
> Hi,
>
> Às 10:25 AM de 1/12/2017, Kishon Vijay Abraham I escreveu:
>> *num-lanes* dt property is parsed in dw_pcie_host_init. However
>> *num-lanes* property is applicable to both root complex mode and
>> endpoint mode. As a first step, move the parsing of this property
>> outside dw_pcie_host_init. This is in preparation for splitting
>> pcie-designware.c to pcie-designware.c and pcie-designware-host.c
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>> drivers/pci/dwc/pcie-designware.c | 18 +++++++++++-------
>> drivers/pci/dwc/pcie-designware.h | 1 -
>> 2 files changed, 11 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/pci/dwc/pcie-designware.c b/drivers/pci/dwc/pcie-designware.c
>> index 00a0fdc..89cdb6b 100644
>> --- a/drivers/pci/dwc/pcie-designware.c
>> +++ b/drivers/pci/dwc/pcie-designware.c
>> @@ -551,10 +551,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
>> }
>> }
>>
>> - ret = of_property_read_u32(np, "num-lanes", &pci->lanes);
>> - if (ret)
>> - pci->lanes = 0;
>> -
>> ret = of_property_read_u32(np, "num-viewport", &pci->num_viewport);
>> if (ret)
>> pci->num_viewport = 2;
>> @@ -751,18 +747,26 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
>>
>> void dw_pcie_setup_rc(struct pcie_port *pp)
>> {
>> + int ret;
>> + u32 lanes;
>> u32 val;
>> struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>> + struct device *dev = pci->dev;
>> + struct device_node *np = dev->of_node;
>>
>> /* get iATU unroll support */
>> pci->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pci);
>> dev_dbg(pci->dev, "iATU unroll: %s\n",
>> pci->iatu_unroll_enabled ? "enabled" : "disabled");
>>
>> + ret = of_property_read_u32(np, "num-lanes", &lanes);
>> + if (ret)
>> + lanes = 0;
>
> You moved from host_init to root complex setup function, which in my opinion did
> not improve (in this scope).
>
> I suggest that instead of making so much intermediary patches, which is nice to
> understand your development sequence, but hard to review. Wouldn't be better to
> condense some of the patches? We would have a cloear vision of the final product :)
I thought the other way. If squashing patches is easier to review, I'll do it.
Btw, thanks for reviewing.
Cheers
Kishon
^ permalink raw reply
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