* [PATCH v4 0/2] PWM support for HiFive Unleashed @ 2019-01-21 10:20 ` Yash Shah 0 siblings, 0 replies; 10+ messages in thread From: Yash Shah @ 2019-01-21 10:20 UTC (permalink / raw) To: palmer, linux-pwm, linux-riscv Cc: thierry.reding, robh+dt, mark.rutland, devicetree, linux-kernel, sachin.ghadi, paul.walmsley, Yash Shah This patch series adds a PWM driver and DT documentation for HiFive Unleashed board. The patches are mostly based on Wesley's patch. v4 - Rename the property sifive,approx-period-ns to sifive,period-ns - Rename macros with appropriate names - Remove unused macros - Rename struct sifive_pwm_device to struct pwm_sifive_ddata - Rename function prefix as per driver name - Set deglitch bit before changing output waveform. - Other minor fixes based upon feedback on v3 v3 - Add a link to the reference manaul - Use appropriate apis for division operation - Add check for polarity - Enable clk before calling clk_get_rate - Other minor fixes based upon feedback on v2 V2 changed from V1: - Remove inclusion of dt-bindings/pwm/pwm.h - Remove artificial alignments - Replace ioread32/iowrite32 with readl/writel - Remove camelcase - Change dev_info to dev_dbg for unnecessary log - Correct typo in driver name - Remove use of of_match_ptr macro - Update the DT compatible strings and Add reference to a common versioning document Yash Shah (2): pwm: sifive: Add DT documentation for SiFive PWM Controller pwm: sifive: Add a driver for SiFive SoC PWM .../devicetree/bindings/pwm/pwm-sifive.txt | 37 +++ drivers/pwm/Kconfig | 11 + drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 262 +++++++++++++++++++++ 4 files changed, 311 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt create mode 100644 drivers/pwm/pwm-sifive.c -- 1.9.1 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 0/2] PWM support for HiFive Unleashed @ 2019-01-21 10:20 ` Yash Shah 0 siblings, 0 replies; 10+ messages in thread From: Yash Shah @ 2019-01-21 10:20 UTC (permalink / raw) To: palmer, linux-pwm, linux-riscv Cc: mark.rutland, devicetree, linux-kernel, robh+dt, sachin.ghadi, Yash Shah, thierry.reding, paul.walmsley This patch series adds a PWM driver and DT documentation for HiFive Unleashed board. The patches are mostly based on Wesley's patch. v4 - Rename the property sifive,approx-period-ns to sifive,period-ns - Rename macros with appropriate names - Remove unused macros - Rename struct sifive_pwm_device to struct pwm_sifive_ddata - Rename function prefix as per driver name - Set deglitch bit before changing output waveform. - Other minor fixes based upon feedback on v3 v3 - Add a link to the reference manaul - Use appropriate apis for division operation - Add check for polarity - Enable clk before calling clk_get_rate - Other minor fixes based upon feedback on v2 V2 changed from V1: - Remove inclusion of dt-bindings/pwm/pwm.h - Remove artificial alignments - Replace ioread32/iowrite32 with readl/writel - Remove camelcase - Change dev_info to dev_dbg for unnecessary log - Correct typo in driver name - Remove use of of_match_ptr macro - Update the DT compatible strings and Add reference to a common versioning document Yash Shah (2): pwm: sifive: Add DT documentation for SiFive PWM Controller pwm: sifive: Add a driver for SiFive SoC PWM .../devicetree/bindings/pwm/pwm-sifive.txt | 37 +++ drivers/pwm/Kconfig | 11 + drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 262 +++++++++++++++++++++ 4 files changed, 311 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt create mode 100644 drivers/pwm/pwm-sifive.c -- 1.9.1 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller 2019-01-21 10:20 ` Yash Shah @ 2019-01-21 10:20 ` Yash Shah -1 siblings, 0 replies; 10+ messages in thread From: Yash Shah @ 2019-01-21 10:20 UTC (permalink / raw) To: palmer, linux-pwm, linux-riscv Cc: thierry.reding, robh+dt, mark.rutland, devicetree, linux-kernel, sachin.ghadi, paul.walmsley, Yash Shah DT documentation for PWM controller added. Signed-off-by: Wesley W. Terpstra <wesley@sifive.com> [Atish: Compatible string update] Signed-off-by: Atish Patra <atish.patra@wdc.com> Signed-off-by: Yash Shah <yash.shah@sifive.com> --- .../devicetree/bindings/pwm/pwm-sifive.txt | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt new file mode 100644 index 0000000..b207908 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt @@ -0,0 +1,37 @@ +SiFive PWM controller + +Unlike most other PWM controllers, the SiFive PWM controller currently only +supports one period for all channels in the PWM. This is set globally in DTS. +The period also has significant restrictions on the values it can achieve, +which the driver rounds to the nearest achievable frequency. + +Required properties: +- compatible: Should be "sifive,pwmX" and "sifive,$socname-pwm". + Please refer to sifive-blocks-ip-versioning.txt for details. +- reg: physical base address and length of the controller's registers +- clocks: Should contain a clock identifier for the PWM's parent clock. +- #pwm-cells: Should be 2. + Refer to bindings/pwm/pwm.txt for details. +- sifive,period-ns: the driver will get as close to this period as it can +- interrupts: one interrupt per PWM channel + +PWM RTL that corresponds to the IP block version numbers can be found +here: + +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm + +Further information on the format of the IP +block-specific version numbers can be found in +Documentation/devicetree/bindings/sifive/sifive-blocks-ip-versioning.txt + +Examples: + +pwm: pwm@10020000 { + compatible = "sifive,fu540-c000-pwm","sifive,pwm0"; + reg = <0x0 0x10020000 0x0 0x1000>; + clocks = <&tlclk>; + interrupt-parent = <&plic>; + interrupts = <42 43 44 45>; + #pwm-cells = <2>; + sifive,period-ns = <1000000>; +}; -- 1.9.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller @ 2019-01-21 10:20 ` Yash Shah 0 siblings, 0 replies; 10+ messages in thread From: Yash Shah @ 2019-01-21 10:20 UTC (permalink / raw) To: palmer, linux-pwm, linux-riscv Cc: mark.rutland, devicetree, linux-kernel, robh+dt, sachin.ghadi, Yash Shah, thierry.reding, paul.walmsley DT documentation for PWM controller added. Signed-off-by: Wesley W. Terpstra <wesley@sifive.com> [Atish: Compatible string update] Signed-off-by: Atish Patra <atish.patra@wdc.com> Signed-off-by: Yash Shah <yash.shah@sifive.com> --- .../devicetree/bindings/pwm/pwm-sifive.txt | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt new file mode 100644 index 0000000..b207908 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt @@ -0,0 +1,37 @@ +SiFive PWM controller + +Unlike most other PWM controllers, the SiFive PWM controller currently only +supports one period for all channels in the PWM. This is set globally in DTS. +The period also has significant restrictions on the values it can achieve, +which the driver rounds to the nearest achievable frequency. + +Required properties: +- compatible: Should be "sifive,pwmX" and "sifive,$socname-pwm". + Please refer to sifive-blocks-ip-versioning.txt for details. +- reg: physical base address and length of the controller's registers +- clocks: Should contain a clock identifier for the PWM's parent clock. +- #pwm-cells: Should be 2. + Refer to bindings/pwm/pwm.txt for details. +- sifive,period-ns: the driver will get as close to this period as it can +- interrupts: one interrupt per PWM channel + +PWM RTL that corresponds to the IP block version numbers can be found +here: + +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm + +Further information on the format of the IP +block-specific version numbers can be found in +Documentation/devicetree/bindings/sifive/sifive-blocks-ip-versioning.txt + +Examples: + +pwm: pwm@10020000 { + compatible = "sifive,fu540-c000-pwm","sifive,pwm0"; + reg = <0x0 0x10020000 0x0 0x1000>; + clocks = <&tlclk>; + interrupt-parent = <&plic>; + interrupts = <42 43 44 45>; + #pwm-cells = <2>; + sifive,period-ns = <1000000>; +}; -- 1.9.1 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v4 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller 2019-01-21 10:20 ` Yash Shah @ 2019-01-21 14:59 ` Rob Herring -1 siblings, 0 replies; 10+ messages in thread From: Rob Herring @ 2019-01-21 14:59 UTC (permalink / raw) To: Yash Shah Cc: palmer, linux-pwm, linux-riscv, thierry.reding, mark.rutland, devicetree, linux-kernel, sachin.ghadi, paul.walmsley On Mon, Jan 21, 2019 at 03:50:42PM +0530, Yash Shah wrote: > DT documentation for PWM controller added. > > Signed-off-by: Wesley W. Terpstra <wesley@sifive.com> > [Atish: Compatible string update] > Signed-off-by: Atish Patra <atish.patra@wdc.com> > Signed-off-by: Yash Shah <yash.shah@sifive.com> > --- > .../devicetree/bindings/pwm/pwm-sifive.txt | 37 ++++++++++++++++++++++ > 1 file changed, 37 insertions(+) > create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > new file mode 100644 > index 0000000..b207908 > --- /dev/null > +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > @@ -0,0 +1,37 @@ > +SiFive PWM controller > + > +Unlike most other PWM controllers, the SiFive PWM controller currently only > +supports one period for all channels in the PWM. This is set globally in DTS. > +The period also has significant restrictions on the values it can achieve, > +which the driver rounds to the nearest achievable frequency. > + > +Required properties: > +- compatible: Should be "sifive,pwmX" and "sifive,$socname-pwm". The order here is wrong. You still need to enumeration valid version numbers. Is 'sifive,pwm20' valid? > + Please refer to sifive-blocks-ip-versioning.txt for details. > +- reg: physical base address and length of the controller's registers > +- clocks: Should contain a clock identifier for the PWM's parent clock. > +- #pwm-cells: Should be 2. > + Refer to bindings/pwm/pwm.txt for details. > +- sifive,period-ns: the driver will get as close to this period as it can > +- interrupts: one interrupt per PWM channel How many channels? If variable, is the a max number? > + > +PWM RTL that corresponds to the IP block version numbers can be found > +here: > + > +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm Put this in the description at the top. > + > +Further information on the format of the IP > +block-specific version numbers can be found in > +Documentation/devicetree/bindings/sifive/sifive-blocks-ip-versioning.txt You already said this. > + > +Examples: > + > +pwm: pwm@10020000 { > + compatible = "sifive,fu540-c000-pwm","sifive,pwm0"; Space after the ',' needed. > + reg = <0x0 0x10020000 0x0 0x1000>; > + clocks = <&tlclk>; > + interrupt-parent = <&plic>; > + interrupts = <42 43 44 45>; > + #pwm-cells = <2>; > + sifive,period-ns = <1000000>; > +}; > -- > 1.9.1 > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller @ 2019-01-21 14:59 ` Rob Herring 0 siblings, 0 replies; 10+ messages in thread From: Rob Herring @ 2019-01-21 14:59 UTC (permalink / raw) To: Yash Shah Cc: mark.rutland, linux-pwm, devicetree, palmer, linux-kernel, sachin.ghadi, thierry.reding, paul.walmsley, linux-riscv On Mon, Jan 21, 2019 at 03:50:42PM +0530, Yash Shah wrote: > DT documentation for PWM controller added. > > Signed-off-by: Wesley W. Terpstra <wesley@sifive.com> > [Atish: Compatible string update] > Signed-off-by: Atish Patra <atish.patra@wdc.com> > Signed-off-by: Yash Shah <yash.shah@sifive.com> > --- > .../devicetree/bindings/pwm/pwm-sifive.txt | 37 ++++++++++++++++++++++ > 1 file changed, 37 insertions(+) > create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > new file mode 100644 > index 0000000..b207908 > --- /dev/null > +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > @@ -0,0 +1,37 @@ > +SiFive PWM controller > + > +Unlike most other PWM controllers, the SiFive PWM controller currently only > +supports one period for all channels in the PWM. This is set globally in DTS. > +The period also has significant restrictions on the values it can achieve, > +which the driver rounds to the nearest achievable frequency. > + > +Required properties: > +- compatible: Should be "sifive,pwmX" and "sifive,$socname-pwm". The order here is wrong. You still need to enumeration valid version numbers. Is 'sifive,pwm20' valid? > + Please refer to sifive-blocks-ip-versioning.txt for details. > +- reg: physical base address and length of the controller's registers > +- clocks: Should contain a clock identifier for the PWM's parent clock. > +- #pwm-cells: Should be 2. > + Refer to bindings/pwm/pwm.txt for details. > +- sifive,period-ns: the driver will get as close to this period as it can > +- interrupts: one interrupt per PWM channel How many channels? If variable, is the a max number? > + > +PWM RTL that corresponds to the IP block version numbers can be found > +here: > + > +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm Put this in the description at the top. > + > +Further information on the format of the IP > +block-specific version numbers can be found in > +Documentation/devicetree/bindings/sifive/sifive-blocks-ip-versioning.txt You already said this. > + > +Examples: > + > +pwm: pwm@10020000 { > + compatible = "sifive,fu540-c000-pwm","sifive,pwm0"; Space after the ',' needed. > + reg = <0x0 0x10020000 0x0 0x1000>; > + clocks = <&tlclk>; > + interrupt-parent = <&plic>; > + interrupts = <42 43 44 45>; > + #pwm-cells = <2>; > + sifive,period-ns = <1000000>; > +}; > -- > 1.9.1 > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller 2019-01-21 14:59 ` Rob Herring @ 2019-01-24 8:58 ` Yash Shah -1 siblings, 0 replies; 10+ messages in thread From: Yash Shah @ 2019-01-24 8:58 UTC (permalink / raw) To: Rob Herring Cc: Palmer Dabbelt, linux-pwm, linux-riscv, Thierry Reding, mark.rutland, devicetree, linux-kernel, Sachin Ghadi, Paul Walmsley On Mon, Jan 21, 2019 at 8:29 PM Rob Herring <robh@kernel.org> wrote: > > On Mon, Jan 21, 2019 at 03:50:42PM +0530, Yash Shah wrote: > > DT documentation for PWM controller added. > > > > Signed-off-by: Wesley W. Terpstra <wesley@sifive.com> > > [Atish: Compatible string update] > > Signed-off-by: Atish Patra <atish.patra@wdc.com> > > Signed-off-by: Yash Shah <yash.shah@sifive.com> > > --- > > .../devicetree/bindings/pwm/pwm-sifive.txt | 37 ++++++++++++++++++++++ > > 1 file changed, 37 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > > > diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > new file mode 100644 > > index 0000000..b207908 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > @@ -0,0 +1,37 @@ > > +SiFive PWM controller > > + > > +Unlike most other PWM controllers, the SiFive PWM controller currently only > > +supports one period for all channels in the PWM. This is set globally in DTS. > > +The period also has significant restrictions on the values it can achieve, > > +which the driver rounds to the nearest achievable frequency. > > + > > +Required properties: > > +- compatible: Should be "sifive,pwmX" and "sifive,$socname-pwm". > > The order here is wrong. Will fix the order. > > You still need to enumeration valid version numbers. Is 'sifive,pwm20' > valid? Yes > > > + Please refer to sifive-blocks-ip-versioning.txt for details. > > +- reg: physical base address and length of the controller's registers > > +- clocks: Should contain a clock identifier for the PWM's parent clock. > > +- #pwm-cells: Should be 2. > > + Refer to bindings/pwm/pwm.txt for details. > > +- sifive,period-ns: the driver will get as close to this period as it can > > +- interrupts: one interrupt per PWM channel > > How many channels? If variable, is the a max number? Max 4 channels. > > > + > > +PWM RTL that corresponds to the IP block version numbers can be found > > +here: > > + > > +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm > > Put this in the description at the top. Sure. > > > + > > +Further information on the format of the IP > > +block-specific version numbers can be found in > > +Documentation/devicetree/bindings/sifive/sifive-blocks-ip-versioning.txt > > You already said this. Will remove redundant info. > > > + > > +Examples: > > + > > +pwm: pwm@10020000 { > > + compatible = "sifive,fu540-c000-pwm","sifive,pwm0"; > > Space after the ',' needed. Sure > > > + reg = <0x0 0x10020000 0x0 0x1000>; > > + clocks = <&tlclk>; > > + interrupt-parent = <&plic>; > > + interrupts = <42 43 44 45>; > > + #pwm-cells = <2>; > > + sifive,period-ns = <1000000>; > > +}; > > -- > > 1.9.1 > > Thanks for the feedback ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller @ 2019-01-24 8:58 ` Yash Shah 0 siblings, 0 replies; 10+ messages in thread From: Yash Shah @ 2019-01-24 8:58 UTC (permalink / raw) To: Rob Herring Cc: mark.rutland, linux-pwm, devicetree, Palmer Dabbelt, linux-kernel, Sachin Ghadi, Thierry Reding, Paul Walmsley, linux-riscv On Mon, Jan 21, 2019 at 8:29 PM Rob Herring <robh@kernel.org> wrote: > > On Mon, Jan 21, 2019 at 03:50:42PM +0530, Yash Shah wrote: > > DT documentation for PWM controller added. > > > > Signed-off-by: Wesley W. Terpstra <wesley@sifive.com> > > [Atish: Compatible string update] > > Signed-off-by: Atish Patra <atish.patra@wdc.com> > > Signed-off-by: Yash Shah <yash.shah@sifive.com> > > --- > > .../devicetree/bindings/pwm/pwm-sifive.txt | 37 ++++++++++++++++++++++ > > 1 file changed, 37 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > > > diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > new file mode 100644 > > index 0000000..b207908 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > @@ -0,0 +1,37 @@ > > +SiFive PWM controller > > + > > +Unlike most other PWM controllers, the SiFive PWM controller currently only > > +supports one period for all channels in the PWM. This is set globally in DTS. > > +The period also has significant restrictions on the values it can achieve, > > +which the driver rounds to the nearest achievable frequency. > > + > > +Required properties: > > +- compatible: Should be "sifive,pwmX" and "sifive,$socname-pwm". > > The order here is wrong. Will fix the order. > > You still need to enumeration valid version numbers. Is 'sifive,pwm20' > valid? Yes > > > + Please refer to sifive-blocks-ip-versioning.txt for details. > > +- reg: physical base address and length of the controller's registers > > +- clocks: Should contain a clock identifier for the PWM's parent clock. > > +- #pwm-cells: Should be 2. > > + Refer to bindings/pwm/pwm.txt for details. > > +- sifive,period-ns: the driver will get as close to this period as it can > > +- interrupts: one interrupt per PWM channel > > How many channels? If variable, is the a max number? Max 4 channels. > > > + > > +PWM RTL that corresponds to the IP block version numbers can be found > > +here: > > + > > +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm > > Put this in the description at the top. Sure. > > > + > > +Further information on the format of the IP > > +block-specific version numbers can be found in > > +Documentation/devicetree/bindings/sifive/sifive-blocks-ip-versioning.txt > > You already said this. Will remove redundant info. > > > + > > +Examples: > > + > > +pwm: pwm@10020000 { > > + compatible = "sifive,fu540-c000-pwm","sifive,pwm0"; > > Space after the ',' needed. Sure > > > + reg = <0x0 0x10020000 0x0 0x1000>; > > + clocks = <&tlclk>; > > + interrupt-parent = <&plic>; > > + interrupts = <42 43 44 45>; > > + #pwm-cells = <2>; > > + sifive,period-ns = <1000000>; > > +}; > > -- > > 1.9.1 > > Thanks for the feedback _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 2/2] pwm: sifive: Add a driver for SiFive SoC PWM 2019-01-21 10:20 ` Yash Shah @ 2019-01-21 10:20 ` Yash Shah -1 siblings, 0 replies; 10+ messages in thread From: Yash Shah @ 2019-01-21 10:20 UTC (permalink / raw) To: palmer, linux-pwm, linux-riscv Cc: thierry.reding, robh+dt, mark.rutland, devicetree, linux-kernel, sachin.ghadi, paul.walmsley, Yash Shah Adds a PWM driver for PWM chip present in SiFive's HiFive Unleashed SoC. Signed-off-by: Wesley W. Terpstra <wesley@sifive.com> [Atish: Various fixes and code cleanup] Signed-off-by: Atish Patra <atish.patra@wdc.com> Signed-off-by: Yash Shah <yash.shah@sifive.com> --- drivers/pwm/Kconfig | 11 ++ drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 262 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 274 insertions(+) create mode 100644 drivers/pwm/pwm-sifive.c diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index a8f47df..4a61d1a 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -380,6 +380,17 @@ config PWM_SAMSUNG To compile this driver as a module, choose M here: the module will be called pwm-samsung. +config PWM_SIFIVE + tristate "SiFive PWM support" + depends on OF + depends on COMMON_CLK + depends on RISCV || COMPILE_TEST + help + Generic PWM framework driver for SiFive SoCs. + + To compile this driver as a module, choose M here: the module + will be called pwm-sifive. + config PWM_SPEAR tristate "STMicroelectronics SPEAr PWM support" depends on PLAT_SPEAR diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 9c676a0..30089ca 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_PWM_RCAR) += pwm-rcar.o obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o +obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o obj-$(CONFIG_PWM_STI) += pwm-sti.o obj-$(CONFIG_PWM_STM32) += pwm-stm32.o diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c new file mode 100644 index 0000000..bbc4ae8 --- /dev/null +++ b/drivers/pwm/pwm-sifive.c @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2017-2018 SiFive + * For SiFive's PWM IP block documentation please refer Chapter 14 of + * Reference Manual : https://static.dev.sifive.com/FU540-C000-v1.0.pdf + */ +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pwm.h> +#include <linux/slab.h> + +/* Register offsets */ +#define PWM_SIFIVE_PWMCFG 0x0 +#define PWM_SIFIVE_PWMCOUNT 0x8 +#define PWM_SIFIVE_PWMS 0x10 +#define PWM_SIFIVE_PWMCMP0 0x20 + +/* PWMCFG fields */ +#define PWM_SIFIVE_PWMCFG_SCALE 0 +#define PWM_SIFIVE_PWMCFG_STICKY 8 +#define PWM_SIFIVE_PWMCFG_ZERO_CMP 9 +#define PWM_SIFIVE_PWMCFG_DEGLITCH 10 +#define PWM_SIFIVE_PWMCFG_EN_ALWAYS 12 +#define PWM_SIFIVE_PWMCFG_EN_ONCE 13 +#define PWM_SIFIVE_PWMCFG_CENTER 16 +#define PWM_SIFIVE_PWMCFG_GANG 24 +#define PWM_SIFIVE_PWMCFG_IP 28 + +/* SIZE_PWMCMP is used to calculate the offset for pwmcmpX registers */ +#define SIZE_PWMCMP 4 +#define CMPWIDTH 16 + +struct pwm_sifive_ddata { + struct pwm_chip chip; + struct notifier_block notifier; + struct clk *clk; + void __iomem *regs; + unsigned int approx_period; + unsigned int real_period; +}; + +static inline struct pwm_sifive_ddata *to_pwm_sifive_chip(struct pwm_chip *c) +{ + return container_of(c, struct pwm_sifive_ddata, chip); +} + +static void pwm_sifive_get_state(struct pwm_chip *chip, struct pwm_device *dev, + struct pwm_state *state) +{ + struct pwm_sifive_ddata *pwm = to_pwm_sifive_chip(chip); + u32 duty; + + duty = readl(pwm->regs + PWM_SIFIVE_PWMCMP0 + dev->hwpwm * SIZE_PWMCMP); + + state->period = pwm->real_period; + state->duty_cycle = ((u64)duty * pwm->real_period) >> CMPWIDTH; + state->polarity = PWM_POLARITY_INVERSED; + state->enabled = duty > 0; +} + +static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *dev, + struct pwm_state *state) +{ + struct pwm_sifive_ddata *pwm = to_pwm_sifive_chip(chip); + unsigned int duty_cycle; + u32 frac, val; + + if (state->polarity != PWM_POLARITY_INVERSED) + return -EINVAL; + + if (state->period != pwm->real_period) + return -EINVAL; + + duty_cycle = state->duty_cycle; + if (!state->enabled) + duty_cycle = 0; + + frac = div_u64((u64)duty_cycle * 0xFFFF, state->period); + frac = min(frac, 0xFFFFU); + + val = readl(pwm->regs + PWM_SIFIVE_PWMCFG); + val |= (1 << PWM_SIFIVE_PWMCFG_DEGLITCH); + writel(val, pwm->regs + PWM_SIFIVE_PWMCFG); + + writel(frac, pwm->regs + PWM_SIFIVE_PWMCMP0 + dev->hwpwm * SIZE_PWMCMP); + + val &= ~(1 << PWM_SIFIVE_PWMCFG_DEGLITCH); + writel(val, pwm->regs + PWM_SIFIVE_PWMCFG); + + if (state->enabled) + pwm_sifive_get_state(chip, dev, state); + + return 0; +} + +static const struct pwm_ops pwm_sifive_ops = { + .get_state = pwm_sifive_get_state, + .apply = pwm_sifive_apply, + .owner = THIS_MODULE, +}; + +static struct pwm_device *pwm_sifive_xlate(struct pwm_chip *chip, + const struct of_phandle_args *args) +{ + struct pwm_sifive_ddata *pwm = to_pwm_sifive_chip(chip); + struct pwm_device *dev; + + if (args->args[0] >= chip->npwm) + return ERR_PTR(-EINVAL); + + dev = pwm_request_from_chip(chip, args->args[0], NULL); + if (IS_ERR(dev)) + return dev; + + /* The period cannot be changed on a per-PWM basis */ + dev->args.period = pwm->real_period; + dev->args.polarity = PWM_POLARITY_NORMAL; + if (args->args[1] & PWM_POLARITY_INVERSED) + dev->args.polarity = PWM_POLARITY_INVERSED; + + return dev; +} + +static void pwm_sifive_update_clock(struct pwm_sifive_ddata *pwm, + unsigned long rate) +{ + /* (1 << (16+scale)) * 10^9/rate = real_period */ + unsigned long scale_pow = + (pwm->approx_period * (u64)rate) / NSEC_PER_SEC; + int scale = clamp(ilog2(scale_pow) - 16, 0, 0xf); + + writel((1 << PWM_SIFIVE_PWMCFG_EN_ALWAYS) | (scale << + PWM_SIFIVE_PWMCFG_SCALE), pwm->regs + PWM_SIFIVE_PWMCFG); + + /* As scale <= 15 the shift operation cannot overflow. */ + pwm->real_period = div64_ul(1000000000ULL << (16 + scale), rate); + dev_dbg(pwm->chip.dev, "New real_period = %u ns\n", pwm->real_period); +} + +static int pwm_sifive_clock_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct clk_notifier_data *ndata = data; + struct pwm_sifive_ddata *pwm = + container_of(nb, struct pwm_sifive_ddata, notifier); + + if (event == POST_RATE_CHANGE) + pwm_sifive_update_clock(pwm, ndata->new_rate); + + return NOTIFY_OK; +} + +static int pwm_sifive_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = pdev->dev.of_node; + struct pwm_sifive_ddata *pwm; + struct pwm_chip *chip; + struct resource *res; + int ret; + + pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL); + if (!pwm) + return -ENOMEM; + + chip = &pwm->chip; + chip->dev = dev; + chip->ops = &pwm_sifive_ops; + chip->of_xlate = pwm_sifive_xlate; + chip->of_pwm_n_cells = 2; + chip->base = -1; + chip->npwm = 4; + + ret = of_property_read_u32(node, "sifive,period-ns", + &pwm->approx_period); + + if (ret < 0) { + dev_err(dev, "Unable to read sifive,period-ns from DTS\n"); + return ret; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + pwm->regs = devm_ioremap_resource(dev, res); + if (IS_ERR(pwm->regs)) { + dev_err(dev, "Unable to map IO resources\n"); + return PTR_ERR(pwm->regs); + } + + pwm->clk = devm_clk_get(dev, NULL); + if (IS_ERR(pwm->clk)) { + if (PTR_ERR(pwm->clk) != -EPROBE_DEFER) + dev_err(dev, "Unable to find controller clock\n"); + return PTR_ERR(pwm->clk); + } + + ret = clk_prepare_enable(pwm->clk); + if (ret) { + dev_err(dev, "failed to enable clock for pwm: %d\n", ret); + return ret; + } + + /* Watch for changes to underlying clock frequency */ + pwm->notifier.notifier_call = pwm_sifive_clock_notifier; + ret = clk_notifier_register(pwm->clk, &pwm->notifier); + if (ret) { + dev_err(dev, "failed to register clock notifier: %d\n", ret); + goto disable_clk; + } + + /* Initialize PWM config */ + pwm_sifive_update_clock(pwm, clk_get_rate(pwm->clk)); + + ret = pwmchip_add(chip); + if (ret < 0) { + dev_err(dev, "cannot register PWM: %d\n", ret); + goto unregister_clk; + } + + platform_set_drvdata(pdev, pwm); + dev_dbg(dev, "SiFive PWM chip registered %d PWMs\n", chip->npwm); + + return 0; + +unregister_clk: + clk_notifier_unregister(pwm->clk, &pwm->notifier); +disable_clk: + clk_disable_unprepare(pwm->clk); + + return ret; +} + +static int pwm_sifive_remove(struct platform_device *dev) +{ + struct pwm_sifive_ddata *pwm = platform_get_drvdata(dev); + int ret; + + ret = pwmchip_remove(&pwm->chip); + clk_notifier_unregister(pwm->clk, &pwm->notifier); + clk_disable_unprepare(pwm->clk); + return ret; +} + +static const struct of_device_id pwm_sifive_of_match[] = { + { .compatible = "sifive,pwm0" }, + {}, +}; +MODULE_DEVICE_TABLE(of, pwm_sifive_of_match); + +static struct platform_driver pwm_sifive_driver = { + .probe = pwm_sifive_probe, + .remove = pwm_sifive_remove, + .driver = { + .name = "pwm-sifive", + .of_match_table = pwm_sifive_of_match, + }, +}; +module_platform_driver(pwm_sifive_driver); + +MODULE_DESCRIPTION("SiFive PWM driver"); +MODULE_LICENSE("GPL v2"); -- 1.9.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 2/2] pwm: sifive: Add a driver for SiFive SoC PWM @ 2019-01-21 10:20 ` Yash Shah 0 siblings, 0 replies; 10+ messages in thread From: Yash Shah @ 2019-01-21 10:20 UTC (permalink / raw) To: palmer, linux-pwm, linux-riscv Cc: mark.rutland, devicetree, linux-kernel, robh+dt, sachin.ghadi, Yash Shah, thierry.reding, paul.walmsley Adds a PWM driver for PWM chip present in SiFive's HiFive Unleashed SoC. Signed-off-by: Wesley W. Terpstra <wesley@sifive.com> [Atish: Various fixes and code cleanup] Signed-off-by: Atish Patra <atish.patra@wdc.com> Signed-off-by: Yash Shah <yash.shah@sifive.com> --- drivers/pwm/Kconfig | 11 ++ drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 262 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 274 insertions(+) create mode 100644 drivers/pwm/pwm-sifive.c diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index a8f47df..4a61d1a 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -380,6 +380,17 @@ config PWM_SAMSUNG To compile this driver as a module, choose M here: the module will be called pwm-samsung. +config PWM_SIFIVE + tristate "SiFive PWM support" + depends on OF + depends on COMMON_CLK + depends on RISCV || COMPILE_TEST + help + Generic PWM framework driver for SiFive SoCs. + + To compile this driver as a module, choose M here: the module + will be called pwm-sifive. + config PWM_SPEAR tristate "STMicroelectronics SPEAr PWM support" depends on PLAT_SPEAR diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 9c676a0..30089ca 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_PWM_RCAR) += pwm-rcar.o obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o +obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o obj-$(CONFIG_PWM_STI) += pwm-sti.o obj-$(CONFIG_PWM_STM32) += pwm-stm32.o diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c new file mode 100644 index 0000000..bbc4ae8 --- /dev/null +++ b/drivers/pwm/pwm-sifive.c @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2017-2018 SiFive + * For SiFive's PWM IP block documentation please refer Chapter 14 of + * Reference Manual : https://static.dev.sifive.com/FU540-C000-v1.0.pdf + */ +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pwm.h> +#include <linux/slab.h> + +/* Register offsets */ +#define PWM_SIFIVE_PWMCFG 0x0 +#define PWM_SIFIVE_PWMCOUNT 0x8 +#define PWM_SIFIVE_PWMS 0x10 +#define PWM_SIFIVE_PWMCMP0 0x20 + +/* PWMCFG fields */ +#define PWM_SIFIVE_PWMCFG_SCALE 0 +#define PWM_SIFIVE_PWMCFG_STICKY 8 +#define PWM_SIFIVE_PWMCFG_ZERO_CMP 9 +#define PWM_SIFIVE_PWMCFG_DEGLITCH 10 +#define PWM_SIFIVE_PWMCFG_EN_ALWAYS 12 +#define PWM_SIFIVE_PWMCFG_EN_ONCE 13 +#define PWM_SIFIVE_PWMCFG_CENTER 16 +#define PWM_SIFIVE_PWMCFG_GANG 24 +#define PWM_SIFIVE_PWMCFG_IP 28 + +/* SIZE_PWMCMP is used to calculate the offset for pwmcmpX registers */ +#define SIZE_PWMCMP 4 +#define CMPWIDTH 16 + +struct pwm_sifive_ddata { + struct pwm_chip chip; + struct notifier_block notifier; + struct clk *clk; + void __iomem *regs; + unsigned int approx_period; + unsigned int real_period; +}; + +static inline struct pwm_sifive_ddata *to_pwm_sifive_chip(struct pwm_chip *c) +{ + return container_of(c, struct pwm_sifive_ddata, chip); +} + +static void pwm_sifive_get_state(struct pwm_chip *chip, struct pwm_device *dev, + struct pwm_state *state) +{ + struct pwm_sifive_ddata *pwm = to_pwm_sifive_chip(chip); + u32 duty; + + duty = readl(pwm->regs + PWM_SIFIVE_PWMCMP0 + dev->hwpwm * SIZE_PWMCMP); + + state->period = pwm->real_period; + state->duty_cycle = ((u64)duty * pwm->real_period) >> CMPWIDTH; + state->polarity = PWM_POLARITY_INVERSED; + state->enabled = duty > 0; +} + +static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *dev, + struct pwm_state *state) +{ + struct pwm_sifive_ddata *pwm = to_pwm_sifive_chip(chip); + unsigned int duty_cycle; + u32 frac, val; + + if (state->polarity != PWM_POLARITY_INVERSED) + return -EINVAL; + + if (state->period != pwm->real_period) + return -EINVAL; + + duty_cycle = state->duty_cycle; + if (!state->enabled) + duty_cycle = 0; + + frac = div_u64((u64)duty_cycle * 0xFFFF, state->period); + frac = min(frac, 0xFFFFU); + + val = readl(pwm->regs + PWM_SIFIVE_PWMCFG); + val |= (1 << PWM_SIFIVE_PWMCFG_DEGLITCH); + writel(val, pwm->regs + PWM_SIFIVE_PWMCFG); + + writel(frac, pwm->regs + PWM_SIFIVE_PWMCMP0 + dev->hwpwm * SIZE_PWMCMP); + + val &= ~(1 << PWM_SIFIVE_PWMCFG_DEGLITCH); + writel(val, pwm->regs + PWM_SIFIVE_PWMCFG); + + if (state->enabled) + pwm_sifive_get_state(chip, dev, state); + + return 0; +} + +static const struct pwm_ops pwm_sifive_ops = { + .get_state = pwm_sifive_get_state, + .apply = pwm_sifive_apply, + .owner = THIS_MODULE, +}; + +static struct pwm_device *pwm_sifive_xlate(struct pwm_chip *chip, + const struct of_phandle_args *args) +{ + struct pwm_sifive_ddata *pwm = to_pwm_sifive_chip(chip); + struct pwm_device *dev; + + if (args->args[0] >= chip->npwm) + return ERR_PTR(-EINVAL); + + dev = pwm_request_from_chip(chip, args->args[0], NULL); + if (IS_ERR(dev)) + return dev; + + /* The period cannot be changed on a per-PWM basis */ + dev->args.period = pwm->real_period; + dev->args.polarity = PWM_POLARITY_NORMAL; + if (args->args[1] & PWM_POLARITY_INVERSED) + dev->args.polarity = PWM_POLARITY_INVERSED; + + return dev; +} + +static void pwm_sifive_update_clock(struct pwm_sifive_ddata *pwm, + unsigned long rate) +{ + /* (1 << (16+scale)) * 10^9/rate = real_period */ + unsigned long scale_pow = + (pwm->approx_period * (u64)rate) / NSEC_PER_SEC; + int scale = clamp(ilog2(scale_pow) - 16, 0, 0xf); + + writel((1 << PWM_SIFIVE_PWMCFG_EN_ALWAYS) | (scale << + PWM_SIFIVE_PWMCFG_SCALE), pwm->regs + PWM_SIFIVE_PWMCFG); + + /* As scale <= 15 the shift operation cannot overflow. */ + pwm->real_period = div64_ul(1000000000ULL << (16 + scale), rate); + dev_dbg(pwm->chip.dev, "New real_period = %u ns\n", pwm->real_period); +} + +static int pwm_sifive_clock_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct clk_notifier_data *ndata = data; + struct pwm_sifive_ddata *pwm = + container_of(nb, struct pwm_sifive_ddata, notifier); + + if (event == POST_RATE_CHANGE) + pwm_sifive_update_clock(pwm, ndata->new_rate); + + return NOTIFY_OK; +} + +static int pwm_sifive_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = pdev->dev.of_node; + struct pwm_sifive_ddata *pwm; + struct pwm_chip *chip; + struct resource *res; + int ret; + + pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL); + if (!pwm) + return -ENOMEM; + + chip = &pwm->chip; + chip->dev = dev; + chip->ops = &pwm_sifive_ops; + chip->of_xlate = pwm_sifive_xlate; + chip->of_pwm_n_cells = 2; + chip->base = -1; + chip->npwm = 4; + + ret = of_property_read_u32(node, "sifive,period-ns", + &pwm->approx_period); + + if (ret < 0) { + dev_err(dev, "Unable to read sifive,period-ns from DTS\n"); + return ret; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + pwm->regs = devm_ioremap_resource(dev, res); + if (IS_ERR(pwm->regs)) { + dev_err(dev, "Unable to map IO resources\n"); + return PTR_ERR(pwm->regs); + } + + pwm->clk = devm_clk_get(dev, NULL); + if (IS_ERR(pwm->clk)) { + if (PTR_ERR(pwm->clk) != -EPROBE_DEFER) + dev_err(dev, "Unable to find controller clock\n"); + return PTR_ERR(pwm->clk); + } + + ret = clk_prepare_enable(pwm->clk); + if (ret) { + dev_err(dev, "failed to enable clock for pwm: %d\n", ret); + return ret; + } + + /* Watch for changes to underlying clock frequency */ + pwm->notifier.notifier_call = pwm_sifive_clock_notifier; + ret = clk_notifier_register(pwm->clk, &pwm->notifier); + if (ret) { + dev_err(dev, "failed to register clock notifier: %d\n", ret); + goto disable_clk; + } + + /* Initialize PWM config */ + pwm_sifive_update_clock(pwm, clk_get_rate(pwm->clk)); + + ret = pwmchip_add(chip); + if (ret < 0) { + dev_err(dev, "cannot register PWM: %d\n", ret); + goto unregister_clk; + } + + platform_set_drvdata(pdev, pwm); + dev_dbg(dev, "SiFive PWM chip registered %d PWMs\n", chip->npwm); + + return 0; + +unregister_clk: + clk_notifier_unregister(pwm->clk, &pwm->notifier); +disable_clk: + clk_disable_unprepare(pwm->clk); + + return ret; +} + +static int pwm_sifive_remove(struct platform_device *dev) +{ + struct pwm_sifive_ddata *pwm = platform_get_drvdata(dev); + int ret; + + ret = pwmchip_remove(&pwm->chip); + clk_notifier_unregister(pwm->clk, &pwm->notifier); + clk_disable_unprepare(pwm->clk); + return ret; +} + +static const struct of_device_id pwm_sifive_of_match[] = { + { .compatible = "sifive,pwm0" }, + {}, +}; +MODULE_DEVICE_TABLE(of, pwm_sifive_of_match); + +static struct platform_driver pwm_sifive_driver = { + .probe = pwm_sifive_probe, + .remove = pwm_sifive_remove, + .driver = { + .name = "pwm-sifive", + .of_match_table = pwm_sifive_of_match, + }, +}; +module_platform_driver(pwm_sifive_driver); + +MODULE_DESCRIPTION("SiFive PWM driver"); +MODULE_LICENSE("GPL v2"); -- 1.9.1 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2019-01-24 8:59 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-01-21 10:20 [PATCH v4 0/2] PWM support for HiFive Unleashed Yash Shah 2019-01-21 10:20 ` Yash Shah 2019-01-21 10:20 ` [PATCH v4 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller Yash Shah 2019-01-21 10:20 ` Yash Shah 2019-01-21 14:59 ` Rob Herring 2019-01-21 14:59 ` Rob Herring 2019-01-24 8:58 ` Yash Shah 2019-01-24 8:58 ` Yash Shah 2019-01-21 10:20 ` [PATCH v4 2/2] pwm: sifive: Add a driver for SiFive SoC PWM Yash Shah 2019-01-21 10:20 ` Yash Shah
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.