Re: [PATCH] MAINTAINERS: ftm-quaddec: Fix typo in a filepath

2019-08-13 Thread Patrick Havelange
On Tue, Aug 13, 2019 at 8:02 AM Denis Efremov  wrote:
>
> Fix typo (s/quadddec/quaddec/) in the path to the documentation.
>
> Cc: Patrick Havelange 
> Cc: Jonathan Cameron 
> Cc: linux-...@vger.kernel.org
> Fixes: 517b2d045aeb ("MAINTAINERS: add counter/ftm-quaddec driver entry")
> Signed-off-by: Denis Efremov 
Acked-by: Patrick Havelange 

> ---
>  MAINTAINERS | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 9b4717ea2cfe..f31b852acdf3 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6321,7 +6321,7 @@ FLEXTIMER FTM-QUADDEC DRIVER
>  M: Patrick Havelange 
>  L: linux-...@vger.kernel.org
>  S: Maintained
> -F: Documentation/ABI/testing/sysfs-bus-counter-ftm-quadddec
> +F: Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec
>  F: Documentation/devicetree/bindings/counter/ftm-quaddec.txt
>  F: drivers/counter/ftm-quaddec.c
>
> --
> 2.21.0
>


[PATCH v7 2/3] iio:temperature:max31856:Add device tree bind info

2019-03-26 Thread Patrick Havelange
From: Paresh Chaudhary 

This patch added device tree binding info for MAX31856 driver.

Signed-off-by: Paresh Chaudhary 
Signed-off-by: Matt Weber 
Signed-off-by: Patrick Havelange 
Reviewed-by: Rob Herring 
---
Changes
v1 -> v2
[Matt
 - Removed comment block and added possibilities of
   thermocouple type in device tree binding doc.

v2 -> v3
 - Rebased

v3 -> v4
 - Removed one-shot property related information.
 - Used standard name 'temp-sensor'

v4 -> v5
[Patrick
 - Rename thermocouple type to maxim,thermocouple-type for DT entry

v5 -> v6
[Patrick
 - use generic thermocouple-type for DT entry

v6 -> v7
[Patrick
 - None
---
 .../bindings/iio/temperature/max31856.txt | 24 +++
 1 file changed, 24 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/iio/temperature/max31856.txt

diff --git a/Documentation/devicetree/bindings/iio/temperature/max31856.txt 
b/Documentation/devicetree/bindings/iio/temperature/max31856.txt
new file mode 100644
index ..06ab43bb4de8
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/temperature/max31856.txt
@@ -0,0 +1,24 @@
+Maxim MAX31856 thermocouple support
+
+https://datasheets.maximintegrated.com/en/ds/MAX31856.pdf
+
+Optional property:
+   - thermocouple-type: Type of thermocouple (THERMOCOUPLE_TYPE_K if
+   omitted). Supported types are B, E, J, K, N, R, S, T.
+
+Required properties:
+   - compatible: must be "maxim,max31856"
+   - reg: SPI chip select number for the device
+   - spi-max-frequency: As per datasheet max. supported freq is 500
+   - spi-cpha: must be defined for max31856 to enable SPI mode 1
+
+   Refer to spi/spi-bus.txt for generic SPI slave bindings.
+
+ Example:
+   temp-sensor@0 {
+   compatible = "maxim,max31856";
+   reg = <0>;
+   spi-max-frequency = <500>;
+   spi-cpha;
+   thermocouple-type = ;
+   };
-- 
2.19.1



[PATCH v7 3/3] iio:temperature: Add MAX31856 thermocouple support

2019-03-26 Thread Patrick Havelange
From: Paresh Chaudhary 

This patch adds support for Maxim MAX31856 thermocouple
temperature sensor support.

More information can be found in:
https://www.maximintegrated.com/en/ds/MAX31856.pdf

NOTE: Driver support only Comparator Mode.

Signed-off-by: Paresh Chaudhary 
Signed-off-by: Matt Weber 
Signed-off-by: Patrick Havelange 
---
Changes
v1 -> v2
[Peter
1. Fixed all space & 'return' related comments
2. Removed 'sysfs_create_group' api  because
   iio_device_register function is handling sysfs entry
3. Return -EIO if there is any fault
4. Added check for 'read_size' before spi read call
5. Removed license text from the source file
6. Added .o file in alphabetic order
7. Used #defines instead of magic bits

v2 -> v3
[Jonathan
1. Used bool for fault_oc and fault_ovuv
2. Changed 'max31856_read' function and use byte array to
   store registers value.
3. Used 'GENMASK' where required
4. Changed logic 'max31856_thermocouple_read' function. Used
   array to read registers value.
5. Used 'devm_iio_device_register' and removed 'max31856_remove'.
6. Fixed other cosmetic changes.
7. Added 'sysfs-bus-iio-temperature-max31856' file and updated
   'MAINTAINERS' file.

v3 -> v4
[Jonathan
1. Removed unwanted logic
2. Updated code to handle return value of max31856_read call
3. Added devicetree id table
4. Removed one-shot support from driver as this support was not
   implemented with correct design.

v4 -> v5
[Patrick
1. Rename thermocouple type to maxim,thermocouple-type for DT entry
2. Don't cache values from the Fault Status Register
3. Simplify a bit max31856_init()
4. Use IIO_NO_MOD in switch case + default error case
5. Use dev_*() instead of pr_*()
6. Fix missing space in comments
7. Removed iio_info.driver_module assignment as no longer present
8. Don't keep read/write buffer into the internal driver struct
9. Updated kernel version, add missing space in documentation
   10. Updated (c) year
   11. Removed linux/init.h #include
   12. More use of BIT() macro
   13. Removed iio_chan_spec.address assignment as not used
   14. In max31856_thermocouple_read(), same switch case order as
   channels definition
   15. Refactor show_fault_*() functions
   16. Use u8 as register type in max31856_{read,write}()

v5 -> v6
[Patrick
1. Use generic thermocouple-type property
2. Fix doc for fault_ovuv entry
3. Add check for supported thermocouple-types in probe()

v6 -> v7
[Patrick
1. None
---
 .../sysfs-bus-iio-temperature-max31856|  24 ++
 drivers/iio/temperature/Kconfig   |  10 +
 drivers/iio/temperature/Makefile  |   1 +
 drivers/iio/temperature/max31856.c| 353 ++
 4 files changed, 388 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-temperature-max31856
 create mode 100644 drivers/iio/temperature/max31856.c

diff --git a/Documentation/ABI/testing/sysfs-bus-iio-temperature-max31856 
b/Documentation/ABI/testing/sysfs-bus-iio-temperature-max31856
new file mode 100644
index ..3b3509a3ef2f
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-iio-temperature-max31856
@@ -0,0 +1,24 @@
+What:  /sys/bus/iio/devices/iio:deviceX/fault_oc
+KernelVersion: 5.1
+Contact:   linux-...@vger.kernel.org
+Description:
+   Open-circuit fault. The detection of open-circuit faults,
+   such as those caused by broken thermocouple wires.
+   Reading returns either '1' or '0'.
+   '1' = An open circuit such as broken thermocouple wires
+ has been detected.
+   '0' = No open circuit or broken thermocouple wires are detected
+
+What:  /sys/bus/iio/devices/iio:deviceX/fault_ovuv
+KernelVersion: 5.1
+Contact:   linux-...@vger.kernel.org
+Description:
+   Overvoltage or Undervoltage Input Fault. The internal circuitry
+   is protected from excessive voltages applied to the thermocouple
+   cables by integrated MOSFETs at the T+ and T- inputs, and the
+   BIAS output. These MOSFETs turn off when the input voltage is
+   negative or greater than VDD.
+   Reading returns either '1' or '0'.
+   '1' = The input voltage is negative or greater than VDD.
+   '0' = The input voltage is positive and less than VDD (normal
+   state).
diff --git a/drivers/iio/temperature/Kconfig b/drivers/iio/temperature/Kconfig
index 82e4a62

[PATCH v7 1/3] dt-bindings: iio/temperature: Add thermocouple types (and doc)

2019-03-26 Thread Patrick Havelange
This patch introduces common thermocouple types used by various
temperature sensors. Also a brief documentation explaining this
"thermocouple-type" property.

Signed-off-by: Patrick Havelange 
---
Changes v7
 - Merge header and doc in same patch
 - Doc:add it's a single cell entry
 - Doc:removed non complete example

Changes v6
 - Add this file
---
 .../iio/temperature/temperature-bindings.txt |  7 +++
 .../dt-bindings/iio/temperature/thermocouple.h   | 16 
 2 files changed, 23 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/iio/temperature/temperature-bindings.txt
 create mode 100644 include/dt-bindings/iio/temperature/thermocouple.h

diff --git 
a/Documentation/devicetree/bindings/iio/temperature/temperature-bindings.txt 
b/Documentation/devicetree/bindings/iio/temperature/temperature-bindings.txt
new file mode 100644
index ..8f339cab74ae
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/temperature/temperature-bindings.txt
@@ -0,0 +1,7 @@
+If the temperature sensor device can be configured to use some specific
+thermocouple type, you can use the defined types provided in the file
+"include/dt-bindings/iio/temperature/thermocouple.h".
+
+Property:
+thermocouple-type: A single cell representing the type of the thermocouple
+   used by the device.
diff --git a/include/dt-bindings/iio/temperature/thermocouple.h 
b/include/dt-bindings/iio/temperature/thermocouple.h
new file mode 100644
index ..ce037f5238ac
--- /dev/null
+++ b/include/dt-bindings/iio/temperature/thermocouple.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _DT_BINDINGS_TEMPERATURE_THERMOCOUPLE_H
+#define _DT_BINDINGS_TEMPERATURE_THERMOCOUPLE_H
+
+
+#define THERMOCOUPLE_TYPE_B0x00
+#define THERMOCOUPLE_TYPE_E0x01
+#define THERMOCOUPLE_TYPE_J0x02
+#define THERMOCOUPLE_TYPE_K0x03
+#define THERMOCOUPLE_TYPE_N0x04
+#define THERMOCOUPLE_TYPE_R0x05
+#define THERMOCOUPLE_TYPE_S0x06
+#define THERMOCOUPLE_TYPE_T0x07
+
+#endif /* _DT_BINDINGS_TEMPERATURE_THERMOCOUPLE_H */
-- 
2.19.1



Re: [PATCH net 1/4] net: freescale/fman: Split the main resource region reservation

2020-12-08 Thread Patrick Havelange

On 2020-12-03 16:47, Madalin Bucur wrote:

-Original Message-
From: Patrick Havelange 
Sent: 03 December 2020 15:51
To: Madalin Bucur ; David S. Miller
; Jakub Kicinski ;
net...@vger.kernel.org; linux-kernel@vger.kernel.org
Cc: Patrick Havelange 
Subject: [PATCH net 1/4] net: freescale/fman: Split the main resource
region reservation

The main fman driver is only using some parts of the fman memory
region.
Split the reservation of the main region in 2, so that the other
regions that will be used by fman-port and fman-mac drivers can
be reserved properly and not be in conflict with the main fman
reservation.

Signed-off-by: Patrick Havelange 


I think the problem you are trying to work on here is that the device
tree entry that describes the FMan IP allots to the parent FMan device the
whole memory-mapped registers area, as described in the device datasheet.
The smaller FMan building blocks (ports, MDIO controllers, etc.) are
each using a nested subset of this memory-mapped registers area.
While this hierarchical depiction of the hardware has not posed a problem
to date, it is possible to cause issues if both the FMan driver and any
of the sub-blocks drivers are trying to exclusively reserve the registers
area. I'm assuming this is the problem you are trying to address here,
besides the stack corruption issue.


Yes exactly.
I did not add this behaviour (having a main region and subdrivers using 
subregions), I'm just trying to correct what is already there.
For example: this is some content of /proc/iomem for one board I'm 
working with, with the current existing code:

ffe40-ffe4fdfff : fman
  ffe4e-ffe4e0fff : mac
  ffe4e2000-ffe4e2fff : mac
  ffe4e4000-ffe4e4fff : mac
  ffe4e6000-ffe4e6fff : mac
  ffe4e8000-ffe4e8fff : mac

and now with my patches:
ffe40-ffe4fdfff : /soc@ffe00/fman@40
  ffe40-ffe480fff : fman
  ffe488000-ffe488fff : fman-port
  ffe489000-ffe489fff : fman-port
  ffe48a000-ffe48afff : fman-port
  ffe48b000-ffe48bfff : fman-port
  ffe48c000-ffe48cfff : fman-port
  ffe4a8000-ffe4a8fff : fman-port
  ffe4a9000-ffe4a9fff : fman-port
  ffe4aa000-ffe4aafff : fman-port
  ffe4ab000-ffe4abfff : fman-port
  ffe4ac000-ffe4acfff : fman-port
  ffe4c-ffe4d : fman
  ffe4e-ffe4e0fff : mac
  ffe4e2000-ffe4e2fff : mac
  ffe4e4000-ffe4e4fff : mac
  ffe4e6000-ffe4e6fff : mac
  ffe4e8000-ffe4e8fff : mac


While for the latter I think we can
put together a quick fix, for the former I'd like to take a bit of time
to select the best fix, if one is really needed. So, please, let's split
the two problems and first address the incorrect stack memory use.


I have no idea how you can fix it without a (more correct this time) 
dummy region passed as parameter (and you don't want to use the first 
patch). But then it will be useless to do the call anyway, as it won't 
do any proper verification at all, so it could also be removed entirely, 
which begs the question, why do it at all in the first place (the 
devm_request_mem_region).


I'm not an expert in that part of the code so feel free to correct me if 
I missed something.


BR,

Patrick H.


Re: [PATCH net 1/4] net: freescale/fman: Split the main resource region reservation

2020-12-09 Thread Patrick Havelange

area. I'm assuming this is the problem you are trying to address here,
besides the stack corruption issue.


Yes exactly.
I did not add this behaviour (having a main region and subdrivers using
subregions), I'm just trying to correct what is already there.
For example: this is some content of /proc/iomem for one board I'm
working with, with the current existing code:
ffe40-ffe4fdfff : fman
ffe4e-ffe4e0fff : mac
ffe4e2000-ffe4e2fff : mac
ffe4e4000-ffe4e4fff : mac
ffe4e6000-ffe4e6fff : mac
ffe4e8000-ffe4e8fff : mac

and now with my patches:
ffe40-ffe4fdfff : /soc@ffe00/fman@40
ffe40-ffe480fff : fman
ffe488000-ffe488fff : fman-port
ffe489000-ffe489fff : fman-port
ffe48a000-ffe48afff : fman-port
ffe48b000-ffe48bfff : fman-port
ffe48c000-ffe48cfff : fman-port
ffe4a8000-ffe4a8fff : fman-port
ffe4a9000-ffe4a9fff : fman-port
ffe4aa000-ffe4aafff : fman-port
ffe4ab000-ffe4abfff : fman-port
ffe4ac000-ffe4acfff : fman-port
ffe4c-ffe4d : fman
ffe4e-ffe4e0fff : mac
ffe4e2000-ffe4e2fff : mac
ffe4e4000-ffe4e4fff : mac
ffe4e6000-ffe4e6fff : mac
ffe4e8000-ffe4e8fff : mac


While for the latter I think we can
put together a quick fix, for the former I'd like to take a bit of time
to select the best fix, if one is really needed. So, please, let's split
the two problems and first address the incorrect stack memory use.


I have no idea how you can fix it without a (more correct this time)
dummy region passed as parameter (and you don't want to use the first
patch). But then it will be useless to do the call anyway, as it won't
do any proper verification at all, so it could also be removed entirely,
which begs the question, why do it at all in the first place (the
devm_request_mem_region).

I'm not an expert in that part of the code so feel free to correct me if
I missed something.

BR,

Patrick H.


Hi, Patrick,

the DPAA entities are described in the device tree. Adding some hardcoding in
the driver is not really the solution for this problem. And I'm not sure we have


I'm not seeing any problem here, the offsets used by the fman driver 
were already there, I just reorganized them in 2 blocks.



a clear problem statement to start with. Can you help me on that part?


- The current call to __devm_request_region in fman_port.c is not correct.

One way to fix this is to use devm_request_mem_region, however this 
requires that the main fman would not be reserving the whole region. 
This leads to the second problem:

- Make sure the main fman driver is not reserving the whole region.

Is that clearer like this ?

Patrick H.



Madalin



Re: [PATCH net 1/4] net: freescale/fman: Split the main resource region reservation

2020-12-10 Thread Patrick Havelange

On 2020-12-09 19:55, Madalin Bucur wrote:

-Original Message-
From: Patrick Havelange 
Sent: 09 December 2020 16:17
To: Madalin Bucur ; David S. Miller
; Jakub Kicinski ;
net...@vger.kernel.org; linux-kernel@vger.kernel.org
Subject: Re: [PATCH net 1/4] net: freescale/fman: Split the main resource
region reservation


area. I'm assuming this is the problem you are trying to address here,
besides the stack corruption issue.


Yes exactly.
I did not add this behaviour (having a main region and subdrivers using
subregions), I'm just trying to correct what is already there.
For example: this is some content of /proc/iomem for one board I'm
working with, with the current existing code:
ffe40-ffe4fdfff : fman
 ffe4e-ffe4e0fff : mac
 ffe4e2000-ffe4e2fff : mac
 ffe4e4000-ffe4e4fff : mac
 ffe4e6000-ffe4e6fff : mac
 ffe4e8000-ffe4e8fff : mac

and now with my patches:
ffe40-ffe4fdfff : /soc@ffe00/fman@40
 ffe40-ffe480fff : fman
 ffe488000-ffe488fff : fman-port
 ffe489000-ffe489fff : fman-port
 ffe48a000-ffe48afff : fman-port
 ffe48b000-ffe48bfff : fman-port
 ffe48c000-ffe48cfff : fman-port
 ffe4a8000-ffe4a8fff : fman-port
 ffe4a9000-ffe4a9fff : fman-port
 ffe4aa000-ffe4aafff : fman-port
 ffe4ab000-ffe4abfff : fman-port
 ffe4ac000-ffe4acfff : fman-port
 ffe4c-ffe4d : fman
 ffe4e-ffe4e0fff : mac
 ffe4e2000-ffe4e2fff : mac
 ffe4e4000-ffe4e4fff : mac
 ffe4e6000-ffe4e6fff : mac
 ffe4e8000-ffe4e8fff : mac


While for the latter I think we can
put together a quick fix, for the former I'd like to take a bit of

time

to select the best fix, if one is really needed. So, please, let's

split

the two problems and first address the incorrect stack memory use.


I have no idea how you can fix it without a (more correct this time)
dummy region passed as parameter (and you don't want to use the first
patch). But then it will be useless to do the call anyway, as it won't
do any proper verification at all, so it could also be removed entirely,
which begs the question, why do it at all in the first place (the
devm_request_mem_region).

I'm not an expert in that part of the code so feel free to correct me

if

I missed something.

BR,

Patrick H.


Hi, Patrick,

the DPAA entities are described in the device tree. Adding some

hardcoding in

the driver is not really the solution for this problem. And I'm not sure

we have

I'm not seeing any problem here, the offsets used by the fman driver
were already there, I just reorganized them in 2 blocks.


a clear problem statement to start with. Can you help me on that part?


- The current call to __devm_request_region in fman_port.c is not correct.

One way to fix this is to use devm_request_mem_region, however this
requires that the main fman would not be reserving the whole region.
This leads to the second problem:
- Make sure the main fman driver is not reserving the whole region.

Is that clearer like this ?

Patrick H.


Hi,



The overlapping IO areas result from the device tree description, that in turn
mimics the HW description in the manual. If we really want to remove the 
nesting,
we should change the device trees, not the drivers.


But then that change would not be compatible with the existing device 
trees in already existing hardware. I'm not sure how to handle that case 
properly.



If we want to hack it,
instead of splitting ioremaps, we can reserve 4 kB in the FMan driver,
and keep the ioremap as it is now, with the benefit of less code churn.


but then the ioremap and the memory reservation do not match. Why bother 
at all then with the mem reservation, just ioremap only and be done with 
it. What I'm saying is, I don't see the point of having a "fake" 
reservation call if it does not correspond that what is being used.



In the end, what the reservation is trying to achieve is to make sure there
is a single driver controlling a certain peripeheral, and this basic
requirement would be addressed by that change plus devm_of_iomap() for child
devices (ports, MACs).


Again, correct me if I'm wrong, but with the fake mem reservation, it 
would *not* make sure that a single driver is controlling a certain 
peripheral.


My point is, either have a *correct* mem reservation, or don't have one 
at all. There is no point in trying to cheat the system.


Patrick H.



Madalin



[PATCH net 0/4] freescale/fman: remove usage of __devm_request_region

2020-12-03 Thread Patrick Havelange
Hello, 

This patch series is solving a bug inside 
ethernet/freescale/fman/fman_port.c caused by an incorrect usage of
__devm_request_region.
The bug came from the fact that the resource given as parameter to the
function __devm_request_region is on the stack, leading to an invalid
pointer being stored inside the devres structure, and the new resource
pointer being lost.
In order to solve this, it is first necessary to make the regular call
devm_request_mem_region work.
This call cannot work as is, because the main fman driver has already
reserved the memory region used by the fman_port driver.

Thus the first action is to split the memory region reservation done in
the main fman driver in two, so that the regions used by fman_port will
not be reserved. The main memory regions have also been reduced to not
request the memory regions used by fman_mac.

Once this first step is done, regular usage of devm_request_mem_region
can be done.
This also leads to a bit of code removal done in the last patch.

1. fman: split the memory region of the main fman driver, so the memory that
will be used by fman_port & fman_mac will not be already reserved.

2. fman_port: replace call of __devm_request_region to devm_request_mem_region

3. fman_mac: replace call of __devm_request_region to devm_request_mem_region

4. the code is now simplified a bit, there is no need to store the main region
anymore

The whole point of this series is to be able to apply the patch N°2.
Since N°3 is a similar change, let's do it at the same time.

I think they all should be part of the same series.

Patrick Havelange (4):
  net: freescale/fman: Split the main resource region reservation
  net: freescale/fman-port: remove direct use of __devm_request_region
  net: freescale/fman-mac: remove direct use of __devm_request_region
  net: freescale/fman: remove fman_get_mem_region

 drivers/net/ethernet/freescale/fman/fman.c| 120 +-
 drivers/net/ethernet/freescale/fman/fman.h|  11 +-
 .../net/ethernet/freescale/fman/fman_port.c   |   6 +-
 drivers/net/ethernet/freescale/fman/mac.c |   8 +-
 4 files changed, 75 insertions(+), 70 deletions(-)


base-commit: 832e09798c261cf58de3a68cfcc6556408c16a5a
-- 
2.17.1



[PATCH net 1/4] net: freescale/fman: Split the main resource region reservation

2020-12-03 Thread Patrick Havelange
The main fman driver is only using some parts of the fman memory
region.
Split the reservation of the main region in 2, so that the other
regions that will be used by fman-port and fman-mac drivers can
be reserved properly and not be in conflict with the main fman
reservation.

Signed-off-by: Patrick Havelange 
---
 drivers/net/ethernet/freescale/fman/fman.c | 103 +
 drivers/net/ethernet/freescale/fman/fman.h |   9 +-
 2 files changed, 69 insertions(+), 43 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index ce0a121580f6..2e85209d560d 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -58,12 +58,15 @@
 /* Modules registers offsets */
 #define BMI_OFFSET 0x0008
 #define QMI_OFFSET 0x00080400
-#define KG_OFFSET  0x000C1000
-#define DMA_OFFSET 0x000C2000
-#define FPM_OFFSET 0x000C3000
-#define IMEM_OFFSET0x000C4000
-#define HWP_OFFSET 0x000C7000
-#define CGP_OFFSET 0x000DB000
+#define SIZE_REGION_0  0x00081000
+#define POL_OFFSET 0x000C
+#define KG_OFFSET_FROM_POL 0x1000
+#define DMA_OFFSET_FROM_POL0x2000
+#define FPM_OFFSET_FROM_POL0x3000
+#define IMEM_OFFSET_FROM_POL   0x4000
+#define HWP_OFFSET_FROM_POL0x7000
+#define CGP_OFFSET_FROM_POL0x0001B000
+#define SIZE_REGION_FROM_POL   0x0002
 
 /* Exceptions bit map */
 #define EX_DMA_BUS_ERROR   0x8000
@@ -1433,7 +1436,7 @@ static int clear_iram(struct fman *fman)
struct fman_iram_regs __iomem *iram;
int i, count;
 
-   iram = fman->base_addr + IMEM_OFFSET;
+   iram = fman->base_addr_pol + IMEM_OFFSET_FROM_POL;
 
/* Enable the auto-increment */
iowrite32be(IRAM_IADD_AIE, &iram->iadd);
@@ -1710,11 +1713,8 @@ static int set_num_of_open_dmas(struct fman *fman, u8 
port_id,
 
 static int fman_config(struct fman *fman)
 {
-   void __iomem *base_addr;
int err;
 
-   base_addr = fman->dts_params.base_addr;
-
fman->state = kzalloc(sizeof(*fman->state), GFP_KERNEL);
if (!fman->state)
goto err_fm_state;
@@ -1740,13 +1740,14 @@ static int fman_config(struct fman *fman)
fman->state->res = fman->dts_params.res;
fman->exception_cb = fman_exceptions;
fman->bus_error_cb = fman_bus_error;
-   fman->fpm_regs = base_addr + FPM_OFFSET;
-   fman->bmi_regs = base_addr + BMI_OFFSET;
-   fman->qmi_regs = base_addr + QMI_OFFSET;
-   fman->dma_regs = base_addr + DMA_OFFSET;
-   fman->hwp_regs = base_addr + HWP_OFFSET;
-   fman->kg_regs = base_addr + KG_OFFSET;
-   fman->base_addr = base_addr;
+   fman->fpm_regs = fman->dts_params.base_addr_pol + FPM_OFFSET_FROM_POL;
+   fman->bmi_regs = fman->dts_params.base_addr_0 + BMI_OFFSET;
+   fman->qmi_regs = fman->dts_params.base_addr_0 + QMI_OFFSET;
+   fman->dma_regs = fman->dts_params.base_addr_pol + DMA_OFFSET_FROM_POL;
+   fman->hwp_regs = fman->dts_params.base_addr_pol + HWP_OFFSET_FROM_POL;
+   fman->kg_regs = fman->dts_params.base_addr_pol + KG_OFFSET_FROM_POL;
+   fman->base_addr_0 = fman->dts_params.base_addr_0;
+   fman->base_addr_pol = fman->dts_params.base_addr_pol;
 
spin_lock_init(&fman->spinlock);
fman_defconfig(fman->cfg);
@@ -1937,8 +1938,8 @@ static int fman_init(struct fman *fman)
fman->state->exceptions &= ~FMAN_EX_QMI_SINGLE_ECC;
 
/* clear CPG */
-   memset_io((void __iomem *)(fman->base_addr + CGP_OFFSET), 0,
- fman->state->fm_port_num_of_cg);
+   memset_io((void __iomem *)(fman->base_addr_pol + CGP_OFFSET_FROM_POL),
+ 0, fman->state->fm_port_num_of_cg);
 
/* Save LIODN info before FMan reset
 * Skipping non-existent port 0 (i = 1)
@@ -2717,13 +2718,11 @@ static struct fman *read_dts_node(struct 
platform_device *of_dev)
 {
struct fman *fman;
struct device_node *fm_node, *muram_node;
-   struct resource *res;
+   struct resource *tmp_res, *main_res;
u32 val, range[2];
int err, irq;
struct clk *clk;
u32 clk_rate;
-   phys_addr_t phys_base_addr;
-   resource_size_t mem_size;
 
fman = kzalloc(sizeof(*fman), GFP_KERNEL);
if (!fman)
@@ -2740,34 +2739,31 @@ static struct fman *read_dts_node(struct 
platform_device *of_dev)
fman->dts_params.id = (u8)val;
 
/* Get the FM interrupt */
-   res = platform_get_resource(of_dev, IORESOURCE_IRQ, 0);
-   if (!res) {
+   tmp_res = platform_get_resource(of_dev, IORESOURCE_IRQ, 0);
+   if (!tmp_res) {
dev_err(&of_dev->dev

[PATCH net 2/4] net: freescale/fman-port: remove direct use of __devm_request_region

2020-12-03 Thread Patrick Havelange
This driver was directly calling __devm_request_region with a specific
resource on the stack as parameter. This is invalid as
__devm_request_region expects the given resource passed as parameter
to live longer than the call itself, as the pointer to the resource
will be stored inside the internal struct used by the devres
management.

In addition to this issue, a related bug has been found by kmemleak
with this trace :
unreferenced object 0xc001efc01880 (size 64):
  comm "swapper/0", pid 1, jiffies 4294669078 (age 3620.536s)
  hex dump (first 32 bytes):
00 00 00 0f fe 4a c0 00 00 00 00 0f fe 4a cf ff  .J...J..
c0 00 00 00 00 ee 9d 98 00 00 00 00 80 00 02 00  
  backtrace:
[] .alloc_resource+0xb8/0xe0
[] .__request_region+0x70/0x1c4
[] .__devm_request_region+0x8c/0x138
[] .fman_port_probe+0x170/0x420
[] .platform_drv_probe+0x84/0x108
[] .driver_probe_device+0x2c4/0x394
[] .__driver_attach+0x124/0x128
[] .bus_for_each_dev+0xb4/0x110
[] .driver_attach+0x34/0x4c
[] .bus_add_driver+0x264/0x2a4
[] .driver_register+0x94/0x160
[] .__platform_driver_register+0x60/0x7c
[] .fman_port_load+0x28/0x64
[] .do_one_initcall+0xd4/0x1a8
[] .kernel_init_freeable+0x1bc/0x2a4
[] .kernel_init+0x24/0x138

Indeed, the new resource (created in __request_region) will be linked
to the given resource living on the stack, which will end its lifetime
after the function calling __devm_request_region has finished.
Meaning the new resource allocated is no longer reachable.

Now that the main fman driver is no longer reserving the region
used by fman-port, this previous hack is no longer needed
and we can use the regular call to devm_request_mem_region instead,
solving those bugs at the same time.

Signed-off-by: Patrick Havelange 
---
 drivers/net/ethernet/freescale/fman/fman_port.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c 
b/drivers/net/ethernet/freescale/fman/fman_port.c
index d9baac0dbc7d..354974939d9d 100644
--- a/drivers/net/ethernet/freescale/fman/fman_port.c
+++ b/drivers/net/ethernet/freescale/fman/fman_port.c
@@ -1878,10 +1878,10 @@ static int fman_port_probe(struct platform_device 
*of_dev)
 
of_node_put(port_node);
 
-   dev_res = __devm_request_region(port->dev, &res, res.start,
-   resource_size(&res), "fman-port");
+   dev_res = devm_request_mem_region(port->dev, res.start,
+ resource_size(&res), "fman-port");
if (!dev_res) {
-   dev_err(port->dev, "%s: __devm_request_region() failed\n",
+   dev_err(port->dev, "%s: devm_request_mem_region() failed\n",
__func__);
err = -EINVAL;
goto free_port;
-- 
2.17.1



[PATCH net 4/4] net: freescale/fman: remove fman_get_mem_region

2020-12-03 Thread Patrick Havelange
This function is no longer used, so we can remove it.
The pointer to the resource that was kept inside
struct fman_state_struct can also be removed for the same reason.

Signed-off-by: Patrick Havelange 
---
 drivers/net/ethernet/freescale/fman/fman.c | 17 -
 drivers/net/ethernet/freescale/fman/fman.h |  2 --
 2 files changed, 19 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index 2e85209d560d..bf78e12a1683 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -531,8 +531,6 @@ struct fman_state_struct {
 
u32 qman_channel_base;
u32 num_of_qman_channels;
-
-   struct resource *res;
 };
 
 /* Structure that holds FMan initial configuration */
@@ -1737,7 +1735,6 @@ static int fman_config(struct fman *fman)
fman->state->qman_channel_base = fman->dts_params.qman_channel_base;
fman->state->num_of_qman_channels =
fman->dts_params.num_of_qman_channels;
-   fman->state->res = fman->dts_params.res;
fman->exception_cb = fman_exceptions;
fman->bus_error_cb = fman_bus_error;
fman->fpm_regs = fman->dts_params.base_addr_pol + FPM_OFFSET_FROM_POL;
@@ -2405,20 +2402,6 @@ u32 fman_get_qman_channel_id(struct fman *fman, u32 
port_id)
 }
 EXPORT_SYMBOL(fman_get_qman_channel_id);
 
-/**
- * fman_get_mem_region
- * @fman:  A Pointer to FMan device
- *
- * Get FMan memory region
- *
- * Return: A structure with FMan memory region information
- */
-struct resource *fman_get_mem_region(struct fman *fman)
-{
-   return fman->state->res;
-}
-EXPORT_SYMBOL(fman_get_mem_region);
-
 /* Bootargs defines */
 /* Extra headroom for RX buffers - Default, min and max */
 #define FSL_FM_RX_EXTRA_HEADROOM   64
diff --git a/drivers/net/ethernet/freescale/fman/fman.h 
b/drivers/net/ethernet/freescale/fman/fman.h
index e6b339c57230..e326aa37b8b2 100644
--- a/drivers/net/ethernet/freescale/fman/fman.h
+++ b/drivers/net/ethernet/freescale/fman/fman.h
@@ -398,8 +398,6 @@ int fman_set_mac_max_frame(struct fman *fman, u8 mac_id, 
u16 mfl);
 
 u32 fman_get_qman_channel_id(struct fman *fman, u32 port_id);
 
-struct resource *fman_get_mem_region(struct fman *fman);
-
 u16 fman_get_max_frm(void);
 
 int fman_get_rx_extra_headroom(void);
-- 
2.17.1



[PATCH net 3/4] net: freescale/fman-mac: remove direct use of __devm_request_region

2020-12-03 Thread Patrick Havelange
Since the main fman driver is no longer reserving the complete fman
memory region, it is no longer needed to use a custom call to
__devm_request_region, so replace it with devm_request_mem_region

Signed-off-by: Patrick Havelange 
---
 drivers/net/ethernet/freescale/fman/mac.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/mac.c 
b/drivers/net/ethernet/freescale/fman/mac.c
index 901749a7a318..35ca5aed 100644
--- a/drivers/net/ethernet/freescale/fman/mac.c
+++ b/drivers/net/ethernet/freescale/fman/mac.c
@@ -690,12 +690,10 @@ static int mac_probe(struct platform_device *_of_dev)
goto _return_of_get_parent;
}
 
-   mac_dev->res = __devm_request_region(dev,
-fman_get_mem_region(priv->fman),
-res.start, resource_size(&res),
-"mac");
+   mac_dev->res = devm_request_mem_region(dev, res.start,
+  resource_size(&res), "mac");
if (!mac_dev->res) {
-   dev_err(dev, "__devm_request_mem_region(mac) failed\n");
+   dev_err(dev, "devm_request_mem_region(mac) failed\n");
err = -EBUSY;
goto _return_of_get_parent;
}
-- 
2.17.1



Re: [PATCH 2/4] net: freescale/fman-port: remove direct use of __devm_request_region

2020-12-03 Thread Patrick Havelange

On 2020-12-03 09:44, Madalin Bucur wrote:

-Original Message-
From: Patrick Havelange 
Sent: 02 December 2020 18:16
To: Madalin Bucur ; David S. Miller
; Jakub Kicinski ;
net...@vger.kernel.org; linux-kernel@vger.kernel.org
Cc: Patrick Havelange 
Subject: [PATCH 2/4] net: freescale/fman-port: remove direct use of
__devm_request_region

This driver was directly calling __devm_request_region with a specific
resource on the stack as parameter. This is invalid as
__devm_request_region expects the given resource passed as parameter
to live longer than the call itself, as the pointer to the resource
will be stored inside the internal struct used by the devres
management.

In addition to this issue, a related bug has been found by kmemleak
with this trace :
unreferenced object 0xc001efc01880 (size 64):
   comm "swapper/0", pid 1, jiffies 4294669078 (age 3620.536s)
   hex dump (first 32 bytes):
 00 00 00 0f fe 4a c0 00 00 00 00 0f fe 4a cf ff  .J...J..
 c0 00 00 00 00 ee 9d 98 00 00 00 00 80 00 02 00  
   backtrace:
 [] .alloc_resource+0xb8/0xe0
 [] .__request_region+0x70/0x1c4
 [] .__devm_request_region+0x8c/0x138
 [] .fman_port_probe+0x170/0x420
 [] .platform_drv_probe+0x84/0x108
 [] .driver_probe_device+0x2c4/0x394
 [] .__driver_attach+0x124/0x128
 [] .bus_for_each_dev+0xb4/0x110
 [] .driver_attach+0x34/0x4c
 [] .bus_add_driver+0x264/0x2a4
 [] .driver_register+0x94/0x160
 [] .__platform_driver_register+0x60/0x7c
 [] .fman_port_load+0x28/0x64
 [] .do_one_initcall+0xd4/0x1a8
 [] .kernel_init_freeable+0x1bc/0x2a4
 [] .kernel_init+0x24/0x138

Indeed, the new resource (created in __request_region) will be linked
to the given resource living on the stack, which will end its lifetime
after the function calling __devm_request_region has finished.
Meaning the new resource allocated is no longer reachable.

Now that the main fman driver is no longer reserving the region
used by fman-port, this previous hack is no longer needed
and we can use the regular call to devm_request_mem_region instead,
solving those bugs at the same time.

Signed-off-by: Patrick Havelange 
---
  drivers/net/ethernet/freescale/fman/fman_port.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c
b/drivers/net/ethernet/freescale/fman/fman_port.c
index d9baac0dbc7d..354974939d9d 100644
--- a/drivers/net/ethernet/freescale/fman/fman_port.c
+++ b/drivers/net/ethernet/freescale/fman/fman_port.c
@@ -1878,10 +1878,10 @@ static int fman_port_probe(struct platform_device
*of_dev)

of_node_put(port_node);

-   dev_res = __devm_request_region(port->dev, &res, res.start,
-   resource_size(&res), "fman-port");
+   dev_res = devm_request_mem_region(port->dev, res.start,
+ resource_size(&res), "fman-port");
if (!dev_res) {
-   dev_err(port->dev, "%s: __devm_request_region() failed\n",
+   dev_err(port->dev, "%s: devm_request_mem_region() failed\n",
__func__);
err = -EINVAL;
goto free_port;
--
2.17.1


Hi Patrick,

please send a fix for the issue, targeting the net tree, separate from the
other change you are trying to introduce. We need a better explanation for
the latter and it should go through the net-next tree, if accepted.


Hello,

I've resent the series with a cover letter having a bit more 
explanations. I think all the patches should be applied on net, as they 
are linked to the same issue/resolution, and are not independent.


BR,

Patrick H.


Re: [PATCH net 1/4] net: freescale/fman: Split the main resource region reservation

2020-12-10 Thread Patrick Havelange

On 2020-12-10 10:05, Madalin Bucur wrote:

-Original Message-
From: Patrick Havelange 


[snipped]



But then that change would not be compatible with the existing device
trees in already existing hardware. I'm not sure how to handle that case
properly.


One needs to be backwards compatible with the old device trees, so we do not
really have a simple answer, I know.


If we want to hack it,
instead of splitting ioremaps, we can reserve 4 kB in the FMan driver,
and keep the ioremap as it is now, with the benefit of less code churn.


but then the ioremap and the memory reservation do not match. Why bother
at all then with the mem reservation, just ioremap only and be done with
it. What I'm saying is, I don't see the point of having a "fake"
reservation call if it does not correspond that what is being used.


The reservation is not fake, it just covering the first portion of the ioremap.
Another hypothetical FMan driver would presumably reserve and ioremap starting
from the same point, thus the desired error would be met.

Regarding removing reservation altogether, yes, we can do that, in the child
device drivers. That will fix that use after free issue you've found and align
with the custom, hierarchical structure of the FMan devices/drivers. But would
leave them without the double use guard we have when using the reservation.


In the end, what the reservation is trying to achieve is to make sure

there

is a single driver controlling a certain peripeheral, and this basic
requirement would be addressed by that change plus devm_of_iomap() for

child

devices (ports, MACs).


Again, correct me if I'm wrong, but with the fake mem reservation, it
would *not* make sure that a single driver is controlling a certain
peripheral.


Actually, it would. If the current FMan driver reserves the first part of the 
FMan
memory, then another FMan driver (I do not expect a random driver trying to map 
the
FMan register area)


Ha!, now I understand your point. I still think it is not a clean 
solution, as the reservation do not match the ioremap usage.



would likely try to use that same part (with the same or
a different size, it does not matter, there will be an error anyway) and the
reservation attempt will fail. If we fix the child device drivers, then they
will have normal mappings and reservations.


My point is, either have a *correct* mem reservation, or don't have one
at all. There is no point in trying to cheat the system.


Now we do not have correct reservations for the child devices because the
parent takes it all for himself. Reduce the parent reservation and make room
for correct reservations for the child. The two-sections change you've made may
try to be correct but it's overkill for the purpose of detecting double use.


But it is not overkill if we want to detect potential subdrivers mapping 
sections that would not start at the main fman region (but still part of 
the main fman region).



And I also find the patch to obfuscate the already not so readable code so I'd
opt for a simpler fix.


As said already, I'm not in favor of having a reservation that do not 
match the real usage.


And in my opinion, having a mismatch with the mem reservation and the 
mem usage is also the kind of obfuscation that we want to avoid.


Yes now the code is slightly more complex, but it is also slightly more 
correct.


I'm not seeing currently another way on how to make it simpler *and* 
correct at the same time.


Patrick H.



Madalin



[PATCH 1/4] net: freescale/fman: Split the main resource region reservation

2020-12-02 Thread Patrick Havelange
The main fman driver is only using some parts of the fman memory
region.
Split the reservation of the main region in 2, so that the other
regions that will be used by fman-port and fman-mac drivers can
be reserved properly and not be in conflict with the main fman
reservation.

Signed-off-by: Patrick Havelange 
---
 drivers/net/ethernet/freescale/fman/fman.c | 103 +
 drivers/net/ethernet/freescale/fman/fman.h |   9 +-
 2 files changed, 69 insertions(+), 43 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index ce0a121580f6..2e85209d560d 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -58,12 +58,15 @@
 /* Modules registers offsets */
 #define BMI_OFFSET 0x0008
 #define QMI_OFFSET 0x00080400
-#define KG_OFFSET  0x000C1000
-#define DMA_OFFSET 0x000C2000
-#define FPM_OFFSET 0x000C3000
-#define IMEM_OFFSET0x000C4000
-#define HWP_OFFSET 0x000C7000
-#define CGP_OFFSET 0x000DB000
+#define SIZE_REGION_0  0x00081000
+#define POL_OFFSET 0x000C
+#define KG_OFFSET_FROM_POL 0x1000
+#define DMA_OFFSET_FROM_POL0x2000
+#define FPM_OFFSET_FROM_POL0x3000
+#define IMEM_OFFSET_FROM_POL   0x4000
+#define HWP_OFFSET_FROM_POL0x7000
+#define CGP_OFFSET_FROM_POL0x0001B000
+#define SIZE_REGION_FROM_POL   0x0002
 
 /* Exceptions bit map */
 #define EX_DMA_BUS_ERROR   0x8000
@@ -1433,7 +1436,7 @@ static int clear_iram(struct fman *fman)
struct fman_iram_regs __iomem *iram;
int i, count;
 
-   iram = fman->base_addr + IMEM_OFFSET;
+   iram = fman->base_addr_pol + IMEM_OFFSET_FROM_POL;
 
/* Enable the auto-increment */
iowrite32be(IRAM_IADD_AIE, &iram->iadd);
@@ -1710,11 +1713,8 @@ static int set_num_of_open_dmas(struct fman *fman, u8 
port_id,
 
 static int fman_config(struct fman *fman)
 {
-   void __iomem *base_addr;
int err;
 
-   base_addr = fman->dts_params.base_addr;
-
fman->state = kzalloc(sizeof(*fman->state), GFP_KERNEL);
if (!fman->state)
goto err_fm_state;
@@ -1740,13 +1740,14 @@ static int fman_config(struct fman *fman)
fman->state->res = fman->dts_params.res;
fman->exception_cb = fman_exceptions;
fman->bus_error_cb = fman_bus_error;
-   fman->fpm_regs = base_addr + FPM_OFFSET;
-   fman->bmi_regs = base_addr + BMI_OFFSET;
-   fman->qmi_regs = base_addr + QMI_OFFSET;
-   fman->dma_regs = base_addr + DMA_OFFSET;
-   fman->hwp_regs = base_addr + HWP_OFFSET;
-   fman->kg_regs = base_addr + KG_OFFSET;
-   fman->base_addr = base_addr;
+   fman->fpm_regs = fman->dts_params.base_addr_pol + FPM_OFFSET_FROM_POL;
+   fman->bmi_regs = fman->dts_params.base_addr_0 + BMI_OFFSET;
+   fman->qmi_regs = fman->dts_params.base_addr_0 + QMI_OFFSET;
+   fman->dma_regs = fman->dts_params.base_addr_pol + DMA_OFFSET_FROM_POL;
+   fman->hwp_regs = fman->dts_params.base_addr_pol + HWP_OFFSET_FROM_POL;
+   fman->kg_regs = fman->dts_params.base_addr_pol + KG_OFFSET_FROM_POL;
+   fman->base_addr_0 = fman->dts_params.base_addr_0;
+   fman->base_addr_pol = fman->dts_params.base_addr_pol;
 
spin_lock_init(&fman->spinlock);
fman_defconfig(fman->cfg);
@@ -1937,8 +1938,8 @@ static int fman_init(struct fman *fman)
fman->state->exceptions &= ~FMAN_EX_QMI_SINGLE_ECC;
 
/* clear CPG */
-   memset_io((void __iomem *)(fman->base_addr + CGP_OFFSET), 0,
- fman->state->fm_port_num_of_cg);
+   memset_io((void __iomem *)(fman->base_addr_pol + CGP_OFFSET_FROM_POL),
+ 0, fman->state->fm_port_num_of_cg);
 
/* Save LIODN info before FMan reset
 * Skipping non-existent port 0 (i = 1)
@@ -2717,13 +2718,11 @@ static struct fman *read_dts_node(struct 
platform_device *of_dev)
 {
struct fman *fman;
struct device_node *fm_node, *muram_node;
-   struct resource *res;
+   struct resource *tmp_res, *main_res;
u32 val, range[2];
int err, irq;
struct clk *clk;
u32 clk_rate;
-   phys_addr_t phys_base_addr;
-   resource_size_t mem_size;
 
fman = kzalloc(sizeof(*fman), GFP_KERNEL);
if (!fman)
@@ -2740,34 +2739,31 @@ static struct fman *read_dts_node(struct 
platform_device *of_dev)
fman->dts_params.id = (u8)val;
 
/* Get the FM interrupt */
-   res = platform_get_resource(of_dev, IORESOURCE_IRQ, 0);
-   if (!res) {
+   tmp_res = platform_get_resource(of_dev, IORESOURCE_IRQ, 0);
+   if (!tmp_res) {
dev_err(&of_dev->dev

[PATCH 4/4] net: freescale/fman: remove fman_get_mem_region

2020-12-02 Thread Patrick Havelange
This function is no longer used, so we can remove it.
The pointer to the resource that was kept inside
struct fman_state_struct can also be removed for the same reason.

Signed-off-by: Patrick Havelange 
---
 drivers/net/ethernet/freescale/fman/fman.c | 17 -
 drivers/net/ethernet/freescale/fman/fman.h |  2 --
 2 files changed, 19 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index 2e85209d560d..bf78e12a1683 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -531,8 +531,6 @@ struct fman_state_struct {
 
u32 qman_channel_base;
u32 num_of_qman_channels;
-
-   struct resource *res;
 };
 
 /* Structure that holds FMan initial configuration */
@@ -1737,7 +1735,6 @@ static int fman_config(struct fman *fman)
fman->state->qman_channel_base = fman->dts_params.qman_channel_base;
fman->state->num_of_qman_channels =
fman->dts_params.num_of_qman_channels;
-   fman->state->res = fman->dts_params.res;
fman->exception_cb = fman_exceptions;
fman->bus_error_cb = fman_bus_error;
fman->fpm_regs = fman->dts_params.base_addr_pol + FPM_OFFSET_FROM_POL;
@@ -2405,20 +2402,6 @@ u32 fman_get_qman_channel_id(struct fman *fman, u32 
port_id)
 }
 EXPORT_SYMBOL(fman_get_qman_channel_id);
 
-/**
- * fman_get_mem_region
- * @fman:  A Pointer to FMan device
- *
- * Get FMan memory region
- *
- * Return: A structure with FMan memory region information
- */
-struct resource *fman_get_mem_region(struct fman *fman)
-{
-   return fman->state->res;
-}
-EXPORT_SYMBOL(fman_get_mem_region);
-
 /* Bootargs defines */
 /* Extra headroom for RX buffers - Default, min and max */
 #define FSL_FM_RX_EXTRA_HEADROOM   64
diff --git a/drivers/net/ethernet/freescale/fman/fman.h 
b/drivers/net/ethernet/freescale/fman/fman.h
index e6b339c57230..e326aa37b8b2 100644
--- a/drivers/net/ethernet/freescale/fman/fman.h
+++ b/drivers/net/ethernet/freescale/fman/fman.h
@@ -398,8 +398,6 @@ int fman_set_mac_max_frame(struct fman *fman, u8 mac_id, 
u16 mfl);
 
 u32 fman_get_qman_channel_id(struct fman *fman, u32 port_id);
 
-struct resource *fman_get_mem_region(struct fman *fman);
-
 u16 fman_get_max_frm(void);
 
 int fman_get_rx_extra_headroom(void);
-- 
2.17.1



[PATCH 2/4] net: freescale/fman-port: remove direct use of __devm_request_region

2020-12-02 Thread Patrick Havelange
This driver was directly calling __devm_request_region with a specific
resource on the stack as parameter. This is invalid as
__devm_request_region expects the given resource passed as parameter
to live longer than the call itself, as the pointer to the resource
will be stored inside the internal struct used by the devres
management.

In addition to this issue, a related bug has been found by kmemleak
with this trace :
unreferenced object 0xc001efc01880 (size 64):
  comm "swapper/0", pid 1, jiffies 4294669078 (age 3620.536s)
  hex dump (first 32 bytes):
00 00 00 0f fe 4a c0 00 00 00 00 0f fe 4a cf ff  .J...J..
c0 00 00 00 00 ee 9d 98 00 00 00 00 80 00 02 00  
  backtrace:
[] .alloc_resource+0xb8/0xe0
[] .__request_region+0x70/0x1c4
[] .__devm_request_region+0x8c/0x138
[] .fman_port_probe+0x170/0x420
[] .platform_drv_probe+0x84/0x108
[] .driver_probe_device+0x2c4/0x394
[] .__driver_attach+0x124/0x128
[] .bus_for_each_dev+0xb4/0x110
[] .driver_attach+0x34/0x4c
[] .bus_add_driver+0x264/0x2a4
[] .driver_register+0x94/0x160
[] .__platform_driver_register+0x60/0x7c
[] .fman_port_load+0x28/0x64
[] .do_one_initcall+0xd4/0x1a8
[] .kernel_init_freeable+0x1bc/0x2a4
[] .kernel_init+0x24/0x138

Indeed, the new resource (created in __request_region) will be linked
to the given resource living on the stack, which will end its lifetime
after the function calling __devm_request_region has finished.
Meaning the new resource allocated is no longer reachable.

Now that the main fman driver is no longer reserving the region
used by fman-port, this previous hack is no longer needed
and we can use the regular call to devm_request_mem_region instead,
solving those bugs at the same time.

Signed-off-by: Patrick Havelange 
---
 drivers/net/ethernet/freescale/fman/fman_port.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c 
b/drivers/net/ethernet/freescale/fman/fman_port.c
index d9baac0dbc7d..354974939d9d 100644
--- a/drivers/net/ethernet/freescale/fman/fman_port.c
+++ b/drivers/net/ethernet/freescale/fman/fman_port.c
@@ -1878,10 +1878,10 @@ static int fman_port_probe(struct platform_device 
*of_dev)
 
of_node_put(port_node);
 
-   dev_res = __devm_request_region(port->dev, &res, res.start,
-   resource_size(&res), "fman-port");
+   dev_res = devm_request_mem_region(port->dev, res.start,
+ resource_size(&res), "fman-port");
if (!dev_res) {
-   dev_err(port->dev, "%s: __devm_request_region() failed\n",
+   dev_err(port->dev, "%s: devm_request_mem_region() failed\n",
__func__);
err = -EINVAL;
goto free_port;
-- 
2.17.1



[PATCH 3/4] net: freescale/fman-mac: remove direct use of __devm_request_region

2020-12-02 Thread Patrick Havelange
Since the main fman driver is no longer reserving the complete fman
memory region, it is no longer needed to use a custom call to
__devm_request_region, so replace it with devm_request_mem_region

Signed-off-by: Patrick Havelange 
---
 drivers/net/ethernet/freescale/fman/mac.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/mac.c 
b/drivers/net/ethernet/freescale/fman/mac.c
index 901749a7a318..35ca5aed 100644
--- a/drivers/net/ethernet/freescale/fman/mac.c
+++ b/drivers/net/ethernet/freescale/fman/mac.c
@@ -690,12 +690,10 @@ static int mac_probe(struct platform_device *_of_dev)
goto _return_of_get_parent;
}
 
-   mac_dev->res = __devm_request_region(dev,
-fman_get_mem_region(priv->fman),
-res.start, resource_size(&res),
-"mac");
+   mac_dev->res = devm_request_mem_region(dev, res.start,
+  resource_size(&res), "mac");
if (!mac_dev->res) {
-   dev_err(dev, "__devm_request_mem_region(mac) failed\n");
+   dev_err(dev, "devm_request_mem_region(mac) failed\n");
err = -EBUSY;
goto _return_of_get_parent;
}
-- 
2.17.1



[PATCH 1/1] counter/ftm-quaddec: Add missing dependencies in Kconfig

2019-06-04 Thread Patrick Havelange
This driver uses devm_ioremap and of* functions. This fixes a
linking failure with e.g. ARCH=um.

Reported-by: kbuild test robot 
Signed-off-by: Patrick Havelange 
---
 drivers/counter/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig
index 233ac305d878..c9e3f5c98484 100644
--- a/drivers/counter/Kconfig
+++ b/drivers/counter/Kconfig
@@ -50,6 +50,7 @@ config STM32_LPTIMER_CNT
 
 config FTM_QUADDEC
tristate "Flex Timer Module Quadrature decoder driver"
+   depends on HAS_IOMEM && OF
help
  Select this option to enable the Flex Timer Quadrature decoder
  driver.
-- 
2.19.1



[PATCH] ARM: dts: ls1021a: Add memory controller

2018-12-11 Thread Patrick Havelange
The LS1021A has a memory controller that supports EDAC. This commit
adds an entry for it.

Signed-off-by: Patrick Havelange 
---
 arch/arm/boot/dts/ls1021a.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index bdd6e66a79ad..a877c32bff20 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -125,6 +125,13 @@
interrupt-parent = <&gic>;
ranges;
 
+   ddr: memory-controller@108 {
+   compatible = "fsl,qoriq-memory-controller";
+   reg = <0x0 0x108 0x0 0x1000>;
+   interrupts = ;
+   big-endian;
+   };
+
gic: interrupt-controller@140 {
compatible = "arm,gic-400", "arm,cortex-a7-gic";
#interrupt-cells = <3>;
-- 
2.17.1



[PATCH v5 1/2] iio:temperature:max31856:Add device tree bind info

2019-02-26 Thread Patrick Havelange
From: Paresh Chaudhary 

This patch added device tree binding info for MAX31856 driver.

Signed-off-by: Paresh Chaudhary 
Signed-off-by: Matt Weber 
Signed-off-by: Patrick Havelange 
---
Changes
v1 -> v2
[Matt
 - Removed comment block and added possibilities of
   thermocouple type in device tree binding doc.

v2 -> v3
 - Rebased

v3 -> v4
 - Removed one-shot property related information.
 - Used standard name 'temp-sensor'

v4 -> v5
[Patrick
 - Rename thermocouple type to maxim,thermocouple-type for DT entry
---
 .../bindings/iio/temperature/max31856.txt | 29 +++
 1 file changed, 29 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/iio/temperature/max31856.txt

diff --git a/Documentation/devicetree/bindings/iio/temperature/max31856.txt 
b/Documentation/devicetree/bindings/iio/temperature/max31856.txt
new file mode 100644
index ..b4396069b8fa
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/temperature/max31856.txt
@@ -0,0 +1,29 @@
+Maxim MAX31856 thermocouple support
+
+https://datasheets.maximintegrated.com/en/ds/MAX31856.pdf
+
+Required properties:
+   - compatible: must be "maxim,max31856"
+   - reg: SPI chip select number for the device
+   - spi-max-frequency: As per datasheet max. supported freq is 500
+   - spi-cpha: must be defined for max31856 to enable SPI mode 1
+   - maxim,thermocouple-type: Type of thermocouple (By default is K-Type)
+   0x00 : TYPE_B
+   0x01 : TYPE_E
+   0x02 : TYPE_J
+   0x03 : TYPE_K (default)
+   0x04 : TYPE_N
+   0x05 : TYPE_R
+   0x06 : TYPE_S
+   0x07 : TYPE_T
+
+   Refer to spi/spi-bus.txt for generic SPI slave bindings.
+
+ Example:
+   temp-sensor@0 {
+   compatible = "maxim,max31856";
+   reg = <0>;
+   spi-max-frequency = <500>;
+   spi-cpha;
+   maxim,thermocouple-type = <0x03>;
+   };
-- 
2.19.1



[PATCH v5 2/2] iio:temperature: Add MAX31856 thermocouple support

2019-02-26 Thread Patrick Havelange
From: Paresh Chaudhary 

This patch adds support for Maxim MAX31856 thermocouple
temperature sensor support.

More information can be found in:
https://www.maximintegrated.com/en/ds/MAX31856.pdf

NOTE: Driver support only Comparator Mode.

Signed-off-by: Paresh Chaudhary 
Signed-off-by: Matt Weber 
Signed-off-by: Patrick Havelange 
---
Changes
v1 -> v2
[Peter
1. Fixed all space & 'return' related comments
2. Removed 'sysfs_create_group' api  because
   iio_device_register function is handling sysfs entry
3. Return -EIO if there is any fault
4. Added check for 'read_size' before spi read call
5. Removed license text from the source file
6. Added .o file in alphabetic order
7. Used #defines instead of magic bits

v2 -> v3
[Jonathan
1. Used bool for fault_oc and fault_ovuv
2. Changed 'max31856_read' function and use byte array to
   store registers value.
3. Used 'GENMASK' where required
4. Changed logic 'max31856_thermocouple_read' function. Used
   array to read registers value.
5. Used 'devm_iio_device_register' and removed 'max31856_remove'.
6. Fixed other cosmetic changes.
7. Added 'sysfs-bus-iio-temperature-max31856' file and updated
   'MAINTAINERS' file.

v3 -> v4
[Jonathan
1. Removed unwanted logic
2. Updated code to handle return value of max31856_read call
3. Added devicetree id table
4. Removed one-shot support from driver as this support was not
   implemented with correct design.

v4 -> v5
[Patrick
1. Rename thermocouple type to maxim,thermocouple-type for DT entry
2. Don't cache values from the Fault Status Register
3. Simplify a bit max31856_init()
4. Use IIO_NO_MOD in switch case + default error case
5. Use dev_*() instead of pr_*()
6. Fix missing space in comments
7. Removed iio_info.driver_module assignment as no longer present
8. Don't keep read/write buffer into the internal driver struct
9. Updated kernel version, add missing space in documentation
   10. Updated (c) year
   11. Removed linux/init.h #include
   12. More use of BIT() macro
   13. Removed iio_chan_spec.address assignment as not used
   14. In max31856_thermocouple_read(), same switch case order as
   channels definition
   15. Refactor show_fault_*() functions
   16. Use u8 as register type in max31856_{read,write}()
---
 .../sysfs-bus-iio-temperature-max31856|  23 ++
 drivers/iio/temperature/Kconfig   |  10 +
 drivers/iio/temperature/Makefile  |   1 +
 drivers/iio/temperature/max31856.c| 332 ++
 4 files changed, 366 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-temperature-max31856
 create mode 100644 drivers/iio/temperature/max31856.c

diff --git a/Documentation/ABI/testing/sysfs-bus-iio-temperature-max31856 
b/Documentation/ABI/testing/sysfs-bus-iio-temperature-max31856
new file mode 100644
index ..22659c91262c
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-iio-temperature-max31856
@@ -0,0 +1,23 @@
+What:  /sys/bus/iio/devices/iio:deviceX/fault_oc
+KernelVersion: 5.1
+Contact:   linux-...@vger.kernel.org
+Description:
+   Open-circuit fault. The detection of open-circuit faults,
+   such as those caused by broken thermocouple wires.
+   Reading returns either '1' or '0'.
+   '1' = An open circuit such as broken thermocouple wires
+ has been detected.
+   '0' = No open circuit or broken thermocouple wires are detected
+
+What:  /sys/bus/iio/devices/iio:deviceX/fault_ovuv
+KernelVersion: 5.1
+Contact:   linux-...@vger.kernel.org
+Description:
+   Overvoltage or Undervoltage Input Fault. The internal circuitry
+   is protected from excessive voltages applied to the thermocouple
+   cables by integrated MOSFETs at the T+ and T- inputs, and the
+   BIAS output. These MOSFETs turn off when the input voltage is
+   negative or greater than VDD.
+   Reading returns either '1' or '0'.
+   '1' = The input voltage is negative or greater than VDD.
+   '0' = The input voltage is positive and less than VDD (default).
diff --git a/drivers/iio/temperature/Kconfig b/drivers/iio/temperature/Kconfig
index 82e4a62745e2..c66eeb23615b 100644
--- a/drivers/iio/temperature/Kconfig
+++ b/drivers/iio/temperature/Kconfig
@@ -97,4 +97,14 @@ config TSYS02D
  This driver can also be built as a module. If so, the module will
  be called

Re: [PATCH v5 1/2] iio:temperature:max31856:Add device tree bind info

2019-02-28 Thread Patrick Havelange
On Thu, Feb 28, 2019 at 12:59 AM Rob Herring  wrote:
>
> On Tue, Feb 26, 2019 at 04:02:13PM +0100, Patrick Havelange wrote:
> > From: Paresh Chaudhary 
> >
> > This patch added device tree binding info for MAX31856 driver.
> >
> > Signed-off-by: Paresh Chaudhary 
> > Signed-off-by: Matt Weber 
> > Signed-off-by: Patrick Havelange 
> > ---
> > Changes
> > v1 -> v2
> > [Matt
> >  - Removed comment block and added possibilities of
> >thermocouple type in device tree binding doc.
> >
> > v2 -> v3
> >  - Rebased
> >
> > v3 -> v4
> >  - Removed one-shot property related information.
> >  - Used standard name 'temp-sensor'
> >
> > v4 -> v5
> > [Patrick
> >  - Rename thermocouple type to maxim,thermocouple-type for DT entry
> > ---
> >  .../bindings/iio/temperature/max31856.txt | 29 +++
> >  1 file changed, 29 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/iio/temperature/max31856.txt
> >
> > diff --git a/Documentation/devicetree/bindings/iio/temperature/max31856.txt 
> > b/Documentation/devicetree/bindings/iio/temperature/max31856.txt
> > new file mode 100644
> > index ..b4396069b8fa
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/iio/temperature/max31856.txt
> > @@ -0,0 +1,29 @@
> > +Maxim MAX31856 thermocouple support
> > +
> > +https://datasheets.maximintegrated.com/en/ds/MAX31856.pdf
> > +
> > +Required properties:
> > + - compatible: must be "maxim,max31856"
> > + - reg: SPI chip select number for the device
> > + - spi-max-frequency: As per datasheet max. supported freq is 500
> > + - spi-cpha: must be defined for max31856 to enable SPI mode 1
> > + - maxim,thermocouple-type: Type of thermocouple (By default is K-Type)
> > + 0x00 : TYPE_B
> > + 0x01 : TYPE_E
> > + 0x02 : TYPE_J
> > + 0x03 : TYPE_K (default)
> > + 0x04 : TYPE_N
> > + 0x05 : TYPE_R
> > + 0x06 : TYPE_S
> > + 0x07 : TYPE_T
>
> These appear to be standard types. Perhaps this should be a common
> property instead?

A remark on the v4 of the patch recommended to add a vendor prefix. It
also mentioned that it could be done as a generic type with a
translation layer for each driver.
Maybe this generic type could be introduced in a separate patch, or
when another driver also uses that kind of thermocouple-type, as there
is no other use of it for the moment it seems.


>
> > +
> > + Refer to spi/spi-bus.txt for generic SPI slave bindings.
> > +
> > + Example:
> > + temp-sensor@0 {
> > + compatible = "maxim,max31856";
> > + reg = <0>;
> > + spi-max-frequency = <500>;
> > + spi-cpha;
> > + maxim,thermocouple-type = <0x03>;
> > + };
> > --
> > 2.19.1
> >


[PATCH 1/1] ARM: dts: ls1021a: add nodes for PWMs

2018-11-27 Thread Patrick Havelange
The LS1021A has 8 possible PWMs, so adding them (disabled by default)

Signed-off-by: Patrick Havelange 
---
 arch/arm/boot/dts/ls1021a.dtsi | 96 ++
 1 file changed, 96 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index bdd6e66a79ad..d3014da9a66b 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -525,6 +525,102 @@
status = "disabled";
};
 
+   pwm0: pwm@29d {
+   compatible = "fsl,vf610-ftm-pwm";
+   #pwm-cells = <3>;
+   reg = <0x0 0x29d 0x0 0x1>;
+   clock-names = "ftm_sys", "ftm_ext",
+   "ftm_fix", "ftm_cnt_clk_en";
+   clocks = <&clockgen 4 1>, <&clockgen 4 1>,
+   <&clockgen 4 1>, <&clockgen 4 1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   pwm1: pwm@29e {
+   compatible = "fsl,vf610-ftm-pwm";
+   #pwm-cells = <3>;
+   reg = <0x0 0x29e 0x0 0x1>;
+   clock-names = "ftm_sys", "ftm_ext",
+   "ftm_fix", "ftm_cnt_clk_en";
+   clocks = <&clockgen 4 1>, <&clockgen 4 1>,
+   <&clockgen 4 1>, <&clockgen 4 1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   pwm2: pwm@29f {
+   compatible = "fsl,vf610-ftm-pwm";
+   #pwm-cells = <3>;
+   reg = <0x0 0x29f 0x0 0x1>;
+   clock-names = "ftm_sys", "ftm_ext",
+   "ftm_fix", "ftm_cnt_clk_en";
+   clocks = <&clockgen 4 1>, <&clockgen 4 1>,
+   <&clockgen 4 1>, <&clockgen 4 1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   pwm3: pwm@2a0 {
+   compatible = "fsl,vf610-ftm-pwm";
+   #pwm-cells = <3>;
+   reg = <0x0 0x2a0 0x0 0x1>;
+   clock-names = "ftm_sys", "ftm_ext",
+   "ftm_fix", "ftm_cnt_clk_en";
+   clocks = <&clockgen 4 1>, <&clockgen 4 1>,
+   <&clockgen 4 1>, <&clockgen 4 1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   pwm4: pwm@2a1 {
+   compatible = "fsl,vf610-ftm-pwm";
+   #pwm-cells = <3>;
+   reg = <0x0 0x2a1 0x0 0x1>;
+   clock-names = "ftm_sys", "ftm_ext",
+   "ftm_fix", "ftm_cnt_clk_en";
+   clocks = <&clockgen 4 1>, <&clockgen 4 1>,
+   <&clockgen 4 1>, <&clockgen 4 1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   pwm5: pwm@2a2 {
+   compatible = "fsl,vf610-ftm-pwm";
+   #pwm-cells = <3>;
+   reg = <0x0 0x2a2 0x0 0x1>;
+   clock-names = "ftm_sys", "ftm_ext",
+   "ftm_fix", "ftm_cnt_clk_en";
+   clocks = <&clockgen 4 1>, <&clockgen 4 1>,
+   <&clockgen 4 1>, <&clockgen 4 1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   pwm6: pwm@2a3 {
+   compatible = "fsl,vf610-ftm-pwm";
+   #pwm-cells = <3>;
+   reg = <0x0 0x2a3 0x0 0x1>;
+   clock-names = "ftm_sys", "ftm_ext",
+   "ftm_fix", "ftm_cnt_clk_en";
+   clocks = <&clockgen 4 1>, <&clockgen 4 1>,
+   <&clockge

Re: [PATCH 5/8] iio/counter: add FlexTimer Module Quadrature decoder counter driver

2019-02-22 Thread Patrick Havelange
Hi Jonathan,

Thanks for your comments, I'll make a new version of the patch based
on your input.

William, I'll rebase the next version on top of your branch.

I'm glad the counter subsystem effort is progressing :)


Patrick Havelange.

On Thu, Feb 21, 2019 at 9:27 AM William Breathitt Gray
 wrote:
>
> On Thu, Feb 21, 2019 at 10:09:54AM +0900, William Breathitt Gray wrote:
> > On Wed, Feb 20, 2019 at 04:41:54PM +, Jonathan Cameron wrote:
> > > On Mon, 18 Feb 2019 15:03:18 +0100
> > > Patrick Havelange  wrote:
> > >
> > > > This driver exposes the counter for the quadrature decoder of the
> > > > FlexTimer Module, present in the LS1021A soc.
> > > >
> > > > Signed-off-by: Patrick Havelange 
> > > > Reviewed-by: Esben Haabendal 
> > > Given you cc'd William, I'm guessing you know about the counter
> > > subsystem effort.  I would really rather not take any drivers
> > > into IIO if we have any hope of getting that upstreamed soon
> > > (which I personally think we do and should!).  The reason is
> > > we end up having to maintain old ABI just because someone might be using
> > > it and it makes the drivers very messy.
> > >
> > > I'll review as is though as may be there are some elements that will
> > > cross over.
> > >
> > > Comments inline.  William: Looks like a straight forward conversion if
> > > it makes sense to get this lined up as part of your initial submission?
> > > You have quite a few drivers so I wouldn't have said it needs to be there
> > > at the start, but good to have it soon after.
> > >
> > > Jonathan
> >
> > I agree, we should try to merge this as part of Counter subsystem
> > introduction rather than as another IIO Counter driver. As we determined
> > when adding support for the STM32 timers, the existing IIO Counter API
> > is fundamentally unsuitable for representing counter devices. So
> > regardless of how a new Counter API is merged, the existing IIO Counter
> > API must be deprecated.
> >
> > Patrick, I apologize for the confusion this has caused. Would you be
> > able to convert this driver to use the proposed Counter subsystem API
> > from this patchset that I believe you encountered before:
> > https://marc.info/?l=linux-arm-kernel&m=153229982404051
> >
> > Although it was last updated in October, I believe you should be able to
> > rebase that Counter subsystem introduction patchset cleanly on top of
> > the IIO tree (if there are any merge conflicts send me an email). Take a
> > look at the generic-counter.rst file under the Documentation/driver-api/
> > directory for an overview of the API; the counter drivers under the
> > drivers/counter/ directory also make good references.
> >
> > If you have any difficulties understanding the API, or any other
> > troubles, don't hesitate to ask. Hopefully, I've made the documentation
> > clear enough to make the conversion of this driver quick and easy -- and
> > if not, then it's something I need to fix, so let me know. :-)
> >
> > William Breathitt Gray
>
> Patrick,
>
> It looks like there were some minor conflicts with the v9 patchset, so
> I've rebased it on top of the latest iio tree testing branch and
> resolved the conflicts in my personal repository. Please pull from my
> personal repository at https://gitlab.com/vilhelmgray/iio.git and base
> your patches on top of the generic_counter_v10 branch.
>
> William Breathitt Gray


[PATCH 5/8] iio/counter: add FlexTimer Module Quadrature decoder counter driver

2019-02-18 Thread Patrick Havelange
This driver exposes the counter for the quadrature decoder of the
FlexTimer Module, present in the LS1021A soc.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
 drivers/iio/counter/Kconfig   |  10 +
 drivers/iio/counter/Makefile  |   1 +
 drivers/iio/counter/ftm-quaddec.c | 294 ++
 3 files changed, 305 insertions(+)
 create mode 100644 drivers/iio/counter/ftm-quaddec.c

diff --git a/drivers/iio/counter/Kconfig b/drivers/iio/counter/Kconfig
index bf1e559ad7cd..4641cb2e752a 100644
--- a/drivers/iio/counter/Kconfig
+++ b/drivers/iio/counter/Kconfig
@@ -31,4 +31,14 @@ config STM32_LPTIMER_CNT
 
  To compile this driver as a module, choose M here: the
  module will be called stm32-lptimer-cnt.
+
+config FTM_QUADDEC
+   tristate "Flex Timer Module Quadrature decoder driver"
+   help
+ Select this option to enable the Flex Timer Quadrature decoder
+ driver.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ftm-quaddec.
+
 endmenu
diff --git a/drivers/iio/counter/Makefile b/drivers/iio/counter/Makefile
index 1b9a896eb488..757c1f4196af 100644
--- a/drivers/iio/counter/Makefile
+++ b/drivers/iio/counter/Makefile
@@ -6,3 +6,4 @@
 
 obj-$(CONFIG_104_QUAD_8)   += 104-quad-8.o
 obj-$(CONFIG_STM32_LPTIMER_CNT)+= stm32-lptimer-cnt.o
+obj-$(CONFIG_FTM_QUADDEC)  += ftm-quaddec.o
diff --git a/drivers/iio/counter/ftm-quaddec.c 
b/drivers/iio/counter/ftm-quaddec.c
new file mode 100644
index ..ca7e55a9ab3f
--- /dev/null
+++ b/drivers/iio/counter/ftm-quaddec.c
@@ -0,0 +1,294 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Flex Timer Module Quadrature decoder
+ *
+ * This module implements a driver for decoding the FTM quadrature
+ * of ex. a LS1021A
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct ftm_quaddec {
+   struct platform_device *pdev;
+   void __iomem *ftm_base;
+   bool big_endian;
+   struct mutex ftm_quaddec_mutex;
+};
+
+#define HASFLAGS(flag, bits) ((flag & bits) ? 1 : 0)
+
+#define DEFAULT_POLL_INTERVAL100 /* in msec */
+
+static void ftm_read(struct ftm_quaddec *ftm, uint32_t offset, uint32_t *data)
+{
+   if (ftm->big_endian)
+   *data = ioread32be(ftm->ftm_base + offset);
+   else
+   *data = ioread32(ftm->ftm_base + offset);
+}
+
+static void ftm_write(struct ftm_quaddec *ftm, uint32_t offset, uint32_t data)
+{
+   if (ftm->big_endian)
+   iowrite32be(data, ftm->ftm_base + offset);
+   else
+   iowrite32(data, ftm->ftm_base + offset);
+}
+
+/* take mutex
+ * call ftm_clear_write_protection
+ * update settings
+ * call ftm_set_write_protection
+ * release mutex
+ */
+static void ftm_clear_write_protection(struct ftm_quaddec *ftm)
+{
+   uint32_t flag;
+
+   /* First see if it is enabled */
+   ftm_read(ftm, FTM_FMS, &flag);
+
+   if (flag & FTM_FMS_WPEN) {
+   ftm_read(ftm, FTM_MODE, &flag);
+   ftm_write(ftm, FTM_MODE, flag | FTM_MODE_WPDIS);
+   }
+}
+
+static void ftm_set_write_protection(struct ftm_quaddec *ftm)
+{
+   ftm_write(ftm, FTM_FMS, FTM_FMS_WPEN);
+}
+
+static void ftm_reset_counter(struct ftm_quaddec *ftm)
+{
+   /* Reset hardware counter to CNTIN */
+   ftm_write(ftm, FTM_CNT, 0x0);
+}
+
+static void ftm_quaddec_init(struct ftm_quaddec *ftm)
+{
+   ftm_clear_write_protection(ftm);
+
+   /* Do not write in the region from the CNTIN register through the
+* PWMLOAD register when FTMEN = 0.
+*/
+   ftm_write(ftm, FTM_MODE, FTM_MODE_FTMEN); /* enable FTM */
+   ftm_write(ftm, FTM_CNTIN, 0x); /* zero init value */
+   ftm_write(ftm, FTM_MOD, 0x);/* max overflow value */
+   ftm_write(ftm, FTM_CNT, 0x0);   /* reset counter value */
+   ftm_write(ftm, FTM_SC, FTM_SC_PS_1);/* prescale with x1 */
+   /* Select quad mode */
+   ftm_write(ftm, FTM_QDCTRL, FTM_QDCTRL_QUADEN);
+
+   /* Unused features and reset to default section */
+   ftm_write(ftm, FTM_POL, 0x0); /* polarity is active high */
+   ftm_write(ftm, FTM_FLTCTRL, 0x0); /* all faults disabled */
+   ftm_write(ftm, FTM_SYNCONF, 0x0); /* disable all sync */
+   ftm_write(ftm, FTM_SYNC, 0x);
+
+   /* Lock the FTM */
+   ftm_set_write_protection(ftm);
+}
+
+static int ftm_quaddec_read_raw(struct iio_dev *indio_dev,
+   struct iio_chan_spec const *chan,
+   int *val, int *val2, long mask)
+{
+   struct ftm_quaddec *ftm = iio_priv(indio_dev);
+   uint32_t counter;
+
+   switch (mask) {
+   case IIO_CHAN_INFO_RAW:
+   ftm_read(ftm, FTM_CN

[PATCH 7/8] dt-bindings: iio/counter: ftm-quaddec: add poll-interval parameter

2019-02-18 Thread Patrick Havelange
New optional parameter supported by updated driver.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
 .../devicetree/bindings/iio/counter/ftm-quaddec.txt   | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/iio/counter/ftm-quaddec.txt 
b/Documentation/devicetree/bindings/iio/counter/ftm-quaddec.txt
index 4d18cd722074..60554e6c4367 100644
--- a/Documentation/devicetree/bindings/iio/counter/ftm-quaddec.txt
+++ b/Documentation/devicetree/bindings/iio/counter/ftm-quaddec.txt
@@ -6,8 +6,14 @@ Required properties:
 - compatible:  Must be "fsl,ftm-quaddec".
 - reg: Must be set to the memory region of the flextimer.
 
-Optional property:
+Optional properties:
 - big-endian:  Access the device registers in big-endian mode.
+- poll-intervalPoll interval time in milliseconds for detecting
+   the under/overflow of the counter. Default value
+   is 100.
+   A value of 0 disables polling. This value can also
+   be set at runtime, but not to less than this initial
+   value (except 0 for disabling).
 
 Example:
counter0: counter@29d {
-- 
2.17.1



[PATCH 3/8] drivers/clocksource: timer-fsl-ftm: use common header for FlexTimer #defines

2019-02-18 Thread Patrick Havelange
Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
 drivers/clocksource/timer-fsl-ftm.c | 15 ++-
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/drivers/clocksource/timer-fsl-ftm.c 
b/drivers/clocksource/timer-fsl-ftm.c
index 846d18daf893..e1c34b2f53a5 100644
--- a/drivers/clocksource/timer-fsl-ftm.c
+++ b/drivers/clocksource/timer-fsl-ftm.c
@@ -19,20 +19,9 @@
 #include 
 #include 
 #include 
+#include 
 
-#define FTM_SC 0x00
-#define FTM_SC_CLK_SHIFT   3
-#define FTM_SC_CLK_MASK(0x3 << FTM_SC_CLK_SHIFT)
-#define FTM_SC_CLK(c)  ((c) << FTM_SC_CLK_SHIFT)
-#define FTM_SC_PS_MASK 0x7
-#define FTM_SC_TOIEBIT(6)
-#define FTM_SC_TOF BIT(7)
-
-#define FTM_CNT0x04
-#define FTM_MOD0x08
-#define FTM_CNTIN  0x4C
-
-#define FTM_PS_MAX 7
+#define FTM_SC_CLK(c)  ((c) << FTM_SC_CLK_MASK_SHIFT)
 
 struct ftm_clock_device {
void __iomem *clksrc_base;
-- 
2.17.1



[PATCH 8/8] iio/counter/ftm-quaddec: add handling of under/overflow of the counter.

2019-02-18 Thread Patrick Havelange
This is implemented by polling the counter value. A new parameter
"poll-interval" can be set in the device tree, or can be changed
at runtime. The reason for the polling is to avoid interrupts flooding.
If the quadrature input is going up and down around the overflow value
(or around 0), the interrupt will be triggering all the time. Thus,
polling is an easy way to handle overflow in a consistent way.
Polling can still be disabled by setting poll-interval to 0.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
 drivers/iio/counter/ftm-quaddec.c | 199 +-
 1 file changed, 193 insertions(+), 6 deletions(-)

diff --git a/drivers/iio/counter/ftm-quaddec.c 
b/drivers/iio/counter/ftm-quaddec.c
index ca7e55a9ab3f..3a0395c3ef33 100644
--- a/drivers/iio/counter/ftm-quaddec.c
+++ b/drivers/iio/counter/ftm-quaddec.c
@@ -25,11 +25,33 @@
 
 struct ftm_quaddec {
struct platform_device *pdev;
+   struct delayed_work delayedcounterwork;
void __iomem *ftm_base;
bool big_endian;
+
+   /* Offset added to the counter to adjust for overflows of the
+* 16 bit HW counter. Only the 16 MSB are set.
+*/
+   uint32_t counteroffset;
+
+   /* Store the counter on each read, this is used to detect
+* if the counter readout if we over or underflow
+*/
+   uint8_t lastregion;
+
+   /* Poll-interval, in ms before delayed work must poll counter */
+   uint16_t poll_interval;
+
struct mutex ftm_quaddec_mutex;
 };
 
+struct counter_result {
+   /* 16 MSB are from the counteroffset
+* 16 LSB are from the hardware counter
+*/
+   uint32_t value;
+};
+
 #define HASFLAGS(flag, bits) ((flag & bits) ? 1 : 0)
 
 #define DEFAULT_POLL_INTERVAL100 /* in msec */
@@ -74,8 +96,75 @@ static void ftm_set_write_protection(struct ftm_quaddec *ftm)
ftm_write(ftm, FTM_FMS, FTM_FMS_WPEN);
 }
 
+/* must be called with mutex locked */
+static void ftm_work_reschedule(struct ftm_quaddec *ftm)
+{
+   cancel_delayed_work(&ftm->delayedcounterwork);
+   if (ftm->poll_interval > 0)
+   schedule_delayed_work(&ftm->delayedcounterwork,
+  msecs_to_jiffies(ftm->poll_interval));
+}
+
+/* Reports the hardware counter added the offset counter.
+ *
+ * The quadrature decodes does not use interrupts, because it cannot be
+ * guaranteed that the counter won't flip between 0x and 0x at a high
+ * rate, causing Real Time performance degration. Instead the counter must be
+ * read frequently enough - the assumption is 150 KHz input can be handled with
+ * 100 ms read cycles.
+ */
+static void ftm_work_counter(struct ftm_quaddec *ftm,
+struct counter_result *returndata)
+{
+   /* only 16bits filled in*/
+   uint32_t hwcounter;
+   uint8_t currentregion;
+
+   mutex_lock(&ftm->ftm_quaddec_mutex);
+
+   ftm_read(ftm, FTM_CNT, &hwcounter);
+
+   /* Divide the counter in four regions:
+*   0x-0x4000-0x8000-0xC000-0x
+* When the hwcounter changes between region 0 and 3 there is an
+* over/underflow
+*/
+   currentregion = hwcounter / 0x4000;
+
+   if (ftm->lastregion == 3 && currentregion == 0)
+   ftm->counteroffset += 0x1;
+
+   if (ftm->lastregion == 0 && currentregion == 3)
+   ftm->counteroffset -= 0x1;
+
+   ftm->lastregion = currentregion;
+
+   if (returndata)
+   returndata->value = ftm->counteroffset + hwcounter;
+
+   ftm_work_reschedule(ftm);
+
+   mutex_unlock(&ftm->ftm_quaddec_mutex);
+}
+
+/* wrapper around the real function */
+static void ftm_work_counter_delay(struct work_struct *workptr)
+{
+   struct delayed_work *work;
+   struct ftm_quaddec *ftm;
+
+   work = container_of(workptr, struct delayed_work, work);
+   ftm = container_of(work, struct ftm_quaddec, delayedcounterwork);
+
+   ftm_work_counter(ftm, NULL);
+}
+
+/* must be called with mutex locked */
 static void ftm_reset_counter(struct ftm_quaddec *ftm)
 {
+   ftm->counteroffset = 0;
+   ftm->lastregion = 0;
+
/* Reset hardware counter to CNTIN */
ftm_write(ftm, FTM_CNT, 0x0);
 }
@@ -110,18 +199,91 @@ static int ftm_quaddec_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask)
 {
struct ftm_quaddec *ftm = iio_priv(indio_dev);
-   uint32_t counter;
+   struct counter_result counter;
 
switch (mask) {
case IIO_CHAN_INFO_RAW:
-   ftm_read(ftm, FTM_CNT, &counter);
-   *val = counter;
+   case IIO_CHAN_INFO_PROCESSED:
+   ftm_work_counter(ftm, &counter);
+   if (mask == IIO_CHAN_INFO_RAW)
+   counter.value &= 0x;
+

[PATCH 6/8] LS1021A: dtsi: add ftm quad decoder entries

2019-02-18 Thread Patrick Havelange
Add the 4 Quadrature counters for this board.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
 arch/arm/boot/dts/ls1021a.dtsi | 28 
 1 file changed, 28 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index ed0941292172..0168fb62590a 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -433,6 +433,34 @@
status = "disabled";
};
 
+   counter0: counter@29d {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x29d 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   counter1: counter@29e {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x29e 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   counter2: counter@29f {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x29f 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   counter3: counter@2a0 {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x2a0 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
+
gpio0: gpio@230 {
compatible = "fsl,ls1021a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x230 0x0 0x1>;
-- 
2.17.1



[PATCH 2/8] drivers/pwm: pwm-fsl-ftm: use common header for FlexTimer #defines

2019-02-18 Thread Patrick Havelange
This also fixes the wrong value for the previously defined
FTM_MODE_INIT macro (it was not used).

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
 drivers/pwm/pwm-fsl-ftm.c | 44 +--
 1 file changed, 1 insertion(+), 43 deletions(-)

diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c
index 883378d055c6..f21ea1b97116 100644
--- a/drivers/pwm/pwm-fsl-ftm.c
+++ b/drivers/pwm/pwm-fsl-ftm.c
@@ -22,51 +22,9 @@
 #include 
 #include 
 #include 
+#include 
 
-#define FTM_SC 0x00
-#define FTM_SC_CLK_MASK_SHIFT  3
-#define FTM_SC_CLK_MASK(3 << FTM_SC_CLK_MASK_SHIFT)
 #define FTM_SC_CLK(c)  (((c) + 1) << FTM_SC_CLK_MASK_SHIFT)
-#define FTM_SC_PS_MASK 0x7
-
-#define FTM_CNT0x04
-#define FTM_MOD0x08
-
-#define FTM_CSC_BASE   0x0C
-#define FTM_CSC_MSBBIT(5)
-#define FTM_CSC_MSABIT(4)
-#define FTM_CSC_ELSB   BIT(3)
-#define FTM_CSC_ELSA   BIT(2)
-#define FTM_CSC(_channel)  (FTM_CSC_BASE + ((_channel) * 8))
-
-#define FTM_CV_BASE0x10
-#define FTM_CV(_channel)   (FTM_CV_BASE + ((_channel) * 8))
-
-#define FTM_CNTIN  0x4C
-#define FTM_STATUS 0x50
-
-#define FTM_MODE   0x54
-#define FTM_MODE_FTMEN BIT(0)
-#define FTM_MODE_INIT  BIT(2)
-#define FTM_MODE_PWMSYNC   BIT(3)
-
-#define FTM_SYNC   0x58
-#define FTM_OUTINIT0x5C
-#define FTM_OUTMASK0x60
-#define FTM_COMBINE0x64
-#define FTM_DEADTIME   0x68
-#define FTM_EXTTRIG0x6C
-#define FTM_POL0x70
-#define FTM_FMS0x74
-#define FTM_FILTER 0x78
-#define FTM_FLTCTRL0x7C
-#define FTM_QDCTRL 0x80
-#define FTM_CONF   0x84
-#define FTM_FLTPOL 0x88
-#define FTM_SYNCONF0x8C
-#define FTM_INVCTRL0x90
-#define FTM_SWOCTRL0x94
-#define FTM_PWMLOAD0x98
 
 enum fsl_pwm_clk {
FSL_PWM_CLK_SYS,
-- 
2.17.1



[PATCH 4/8] dt-bindings: iio/counter: ftm-quaddec

2019-02-18 Thread Patrick Havelange
FlexTimer quadrature decoder driver.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
 .../bindings/iio/counter/ftm-quaddec.txt   | 18 ++
 1 file changed, 18 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/iio/counter/ftm-quaddec.txt

diff --git a/Documentation/devicetree/bindings/iio/counter/ftm-quaddec.txt 
b/Documentation/devicetree/bindings/iio/counter/ftm-quaddec.txt
new file mode 100644
index ..4d18cd722074
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/counter/ftm-quaddec.txt
@@ -0,0 +1,18 @@
+FlexTimer Quadrature decoder counter
+
+This driver exposes a simple counter for the quadrature decoder mode.
+
+Required properties:
+- compatible:  Must be "fsl,ftm-quaddec".
+- reg: Must be set to the memory region of the flextimer.
+
+Optional property:
+- big-endian:  Access the device registers in big-endian mode.
+
+Example:
+   counter0: counter@29d {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x29d 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
-- 
2.17.1



[PATCH 1/8] include/fsl: add common FlexTimer #defines in a separate header.

2019-02-18 Thread Patrick Havelange
Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
 include/linux/fsl/ftm.h | 88 +
 1 file changed, 88 insertions(+)
 create mode 100644 include/linux/fsl/ftm.h

diff --git a/include/linux/fsl/ftm.h b/include/linux/fsl/ftm.h
new file mode 100644
index ..d59011acf66c
--- /dev/null
+++ b/include/linux/fsl/ftm.h
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+#ifndef __FSL_FTM_H__
+#define __FSL_FTM_H__
+
+#define FTM_SC   0x0 /* Status And Control */
+#define FTM_CNT  0x4 /* Counter */
+#define FTM_MOD  0x8 /* Modulo */
+
+#define FTM_CNTIN0x4C /* Counter Initial Value */
+#define FTM_STATUS   0x50 /* Capture And Compare Status */
+#define FTM_MODE 0x54 /* Features Mode Selection */
+#define FTM_SYNC 0x58 /* Synchronization */
+#define FTM_OUTINIT  0x5C /* Initial State For Channels Output */
+#define FTM_OUTMASK  0x60 /* Output Mask */
+#define FTM_COMBINE  0x64 /* Function For Linked Channels */
+#define FTM_DEADTIME 0x68 /* Deadtime Insertion Control */
+#define FTM_EXTTRIG  0x6C /* FTM External Trigger */
+#define FTM_POL  0x70 /* Channels Polarity */
+#define FTM_FMS  0x74 /* Fault Mode Status */
+#define FTM_FILTER   0x78 /* Input Capture Filter Control */
+#define FTM_FLTCTRL  0x7C /* Fault Control */
+#define FTM_QDCTRL   0x80 /* Quadrature Decoder Control And Status */
+#define FTM_CONF 0x84 /* Configuration */
+#define FTM_FLTPOL   0x88 /* FTM Fault Input Polarity */
+#define FTM_SYNCONF  0x8C /* Synchronization Configuration */
+#define FTM_INVCTRL  0x90 /* FTM Inverting Control */
+#define FTM_SWOCTRL  0x94 /* FTM Software Output Control */
+#define FTM_PWMLOAD  0x98 /* FTM PWM Load */
+
+#define FTM_SC_CLK_MASK_SHIFT  3
+#define FTM_SC_CLK_MASK(3 << FTM_SC_CLK_MASK_SHIFT)
+#define FTM_SC_TOF 0x80
+#define FTM_SC_TOIE0x40
+#define FTM_SC_CPWMS   0x20
+#define FTM_SC_CLKS0x18
+#define FTM_SC_PS_10x0
+#define FTM_SC_PS_20x1
+#define FTM_SC_PS_40x2
+#define FTM_SC_PS_80x3
+#define FTM_SC_PS_16   0x4
+#define FTM_SC_PS_32   0x5
+#define FTM_SC_PS_64   0x6
+#define FTM_SC_PS_128  0x7
+#define FTM_SC_PS_MASK 0x7
+
+#define FTM_MODE_FAULTIE   0x80
+#define FTM_MODE_FAULTM0x60
+#define FTM_MODE_CAPTEST   0x10
+#define FTM_MODE_PWMSYNC   0x8
+#define FTM_MODE_WPDIS 0x4
+#define FTM_MODE_INIT  0x2
+#define FTM_MODE_FTMEN 0x1
+
+/* NXP Errata: The PHAFLTREN and PHBFLTREN bits are tide to zero internally
+ * and these bits cannot be set. Flextimer cannot use Filter in
+ * Quadrature Decoder Mode.
+ * https://community.nxp.com/thread/467648#comment-1010319
+ */
+#define FTM_QDCTRL_PHAFLTREN   0x80
+#define FTM_QDCTRL_PHBFLTREN   0x40
+#define FTM_QDCTRL_PHAPOL  0x20
+#define FTM_QDCTRL_PHBPOL  0x10
+#define FTM_QDCTRL_QUADMODE0x8
+#define FTM_QDCTRL_QUADDIR 0x4
+#define FTM_QDCTRL_TOFDIR  0x2
+#define FTM_QDCTRL_QUADEN  0x1
+
+#define FTM_FMS_FAULTF 0x80
+#define FTM_FMS_WPEN   0x40
+#define FTM_FMS_FAULTIN0x10
+#define FTM_FMS_FAULTF30x8
+#define FTM_FMS_FAULTF20x4
+#define FTM_FMS_FAULTF10x2
+#define FTM_FMS_FAULTF00x1
+
+#define FTM_CSC_BASE   0xC
+#define FTM_CSC_MSB0x20
+#define FTM_CSC_MSA0x10
+#define FTM_CSC_ELSB   0x8
+#define FTM_CSC_ELSA   0x4
+#define FTM_CSC(_channel)  (FTM_CSC_BASE + ((_channel) * 8))
+
+#define FTM_CV_BASE0x10
+#define FTM_CV(_channel)   (FTM_CV_BASE + ((_channel) * 8))
+
+#define FTM_PS_MAX 7
+
+#endif
-- 
2.17.1



Re: [PATCH 5/8] iio/counter: add FlexTimer Module Quadrature decoder counter driver

2019-03-04 Thread Patrick Havelange
On Wed, Feb 20, 2019 at 5:42 PM Jonathan Cameron  wrote:
[skipped]
> > +
> > +struct ftm_quaddec {
> > + struct platform_device *pdev;
> > + void __iomem *ftm_base;
> > + bool big_endian;
>
> I'm curious. What is the benefit of running in big endian mode?

It is based on the same behaviour as in drivers/clocksource/timer-fsl-ftm.c
The FlexTimer itself on the board I'm testing it with is working in
big endian mode, so this mode is required.

> > +static ssize_t ftm_write_reset(struct iio_dev *indio_dev,
> > + uintptr_t private,
> > + struct iio_chan_spec const *chan,
> > + const char *buf, size_t len)
> > +{
> > + struct ftm_quaddec *ftm = iio_priv(indio_dev);
> > +
> > + /* Only "counter reset" is supported for now */
> > + if (!sysfs_streq(buf, "0")) {
> > + dev_warn(&ftm->pdev->dev, "Reset only accepts '0'\n");
> > + return -EINVAL;
>
> Why not just make the channel attribute itself writeable given we are
> setting it to 0?

Good idea, I'll see if this can be applied in the new subsystem.

[skipped]

All other comments are Acked.


[PATCH v2 7/7] LS1021A: dtsi: add ftm quad decoder entries

2019-03-06 Thread Patrick Havelange
Add the 4 Quadrature counters for this board.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
Changes v2
 - None
---
 arch/arm/boot/dts/ls1021a.dtsi | 28 
 1 file changed, 28 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index ed0941292172..0168fb62590a 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -433,6 +433,34 @@
status = "disabled";
};
 
+   counter0: counter@29d {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x29d 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   counter1: counter@29e {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x29e 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   counter2: counter@29f {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x29f 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   counter3: counter@2a0 {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x2a0 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
+
gpio0: gpio@230 {
compatible = "fsl,ls1021a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x230 0x0 0x1>;
-- 
2.19.1



[PATCH v2 5/7] counter: add FlexTimer Module Quadrature decoder counter driver

2019-03-06 Thread Patrick Havelange
This driver exposes the counter for the quadrature decoder of the
FlexTimer Module, present in the LS1021A soc.

Signed-off-by: Patrick Havelange 
---
Changes v2
 - Rebased on new counter subsystem
 - Cleaned up included headers
 - Use devm_ioremap()
 - Correct order of devm_ and unmanaged resources
---
 drivers/counter/Kconfig   |   9 +
 drivers/counter/Makefile  |   1 +
 drivers/counter/ftm-quaddec.c | 356 ++
 3 files changed, 366 insertions(+)
 create mode 100644 drivers/counter/ftm-quaddec.c

diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig
index 87c491a19c63..233ac305d878 100644
--- a/drivers/counter/Kconfig
+++ b/drivers/counter/Kconfig
@@ -48,4 +48,13 @@ config STM32_LPTIMER_CNT
  To compile this driver as a module, choose M here: the
  module will be called stm32-lptimer-cnt.
 
+config FTM_QUADDEC
+   tristate "Flex Timer Module Quadrature decoder driver"
+   help
+ Select this option to enable the Flex Timer Quadrature decoder
+ driver.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ftm-quaddec.
+
 endif # COUNTER
diff --git a/drivers/counter/Makefile b/drivers/counter/Makefile
index 5589976d37f8..0c9e622a6bea 100644
--- a/drivers/counter/Makefile
+++ b/drivers/counter/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_COUNTER) += counter.o
 obj-$(CONFIG_104_QUAD_8)   += 104-quad-8.o
 obj-$(CONFIG_STM32_TIMER_CNT)  += stm32-timer-cnt.o
 obj-$(CONFIG_STM32_LPTIMER_CNT)+= stm32-lptimer-cnt.o
+obj-$(CONFIG_FTM_QUADDEC)  += ftm-quaddec.o
diff --git a/drivers/counter/ftm-quaddec.c b/drivers/counter/ftm-quaddec.c
new file mode 100644
index ..1bc9e075a386
--- /dev/null
+++ b/drivers/counter/ftm-quaddec.c
@@ -0,0 +1,356 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Flex Timer Module Quadrature decoder
+ *
+ * This module implements a driver for decoding the FTM quadrature
+ * of ex. a LS1021A
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct ftm_quaddec {
+   struct counter_device counter;
+   struct platform_device *pdev;
+   void __iomem *ftm_base;
+   bool big_endian;
+   struct mutex ftm_quaddec_mutex;
+};
+
+static void ftm_read(struct ftm_quaddec *ftm, uint32_t offset, uint32_t *data)
+{
+   if (ftm->big_endian)
+   *data = ioread32be(ftm->ftm_base + offset);
+   else
+   *data = ioread32(ftm->ftm_base + offset);
+}
+
+static void ftm_write(struct ftm_quaddec *ftm, uint32_t offset, uint32_t data)
+{
+   if (ftm->big_endian)
+   iowrite32be(data, ftm->ftm_base + offset);
+   else
+   iowrite32(data, ftm->ftm_base + offset);
+}
+
+/*
+ * take mutex
+ * call ftm_clear_write_protection
+ * update settings
+ * call ftm_set_write_protection
+ * release mutex
+ */
+static void ftm_clear_write_protection(struct ftm_quaddec *ftm)
+{
+   uint32_t flag;
+
+   /* First see if it is enabled */
+   ftm_read(ftm, FTM_FMS, &flag);
+
+   if (flag & FTM_FMS_WPEN) {
+   ftm_read(ftm, FTM_MODE, &flag);
+   ftm_write(ftm, FTM_MODE, flag | FTM_MODE_WPDIS);
+   }
+}
+
+static void ftm_set_write_protection(struct ftm_quaddec *ftm)
+{
+   ftm_write(ftm, FTM_FMS, FTM_FMS_WPEN);
+}
+
+static void ftm_reset_counter(struct ftm_quaddec *ftm)
+{
+   /* Reset hardware counter to CNTIN */
+   ftm_write(ftm, FTM_CNT, 0x0);
+}
+
+static void ftm_quaddec_init(struct ftm_quaddec *ftm)
+{
+   ftm_clear_write_protection(ftm);
+
+   /*
+* Do not write in the region from the CNTIN register through the
+* PWMLOAD register when FTMEN = 0.
+*/
+   ftm_write(ftm, FTM_MODE, FTM_MODE_FTMEN);
+   ftm_write(ftm, FTM_CNTIN, 0x);
+   ftm_write(ftm, FTM_MOD, 0x);
+   ftm_write(ftm, FTM_CNT, 0x0);
+   ftm_write(ftm, FTM_SC, FTM_SC_PS_1);
+
+   /* Select quad mode */
+   ftm_write(ftm, FTM_QDCTRL, FTM_QDCTRL_QUADEN);
+
+   /* Unused features and reset to default section */
+   ftm_write(ftm, FTM_POL, 0x0);
+   ftm_write(ftm, FTM_FLTCTRL, 0x0);
+   ftm_write(ftm, FTM_SYNCONF, 0x0);
+   ftm_write(ftm, FTM_SYNC, 0x);
+
+   /* Lock the FTM */
+   ftm_set_write_protection(ftm);
+}
+
+static void ftm_quaddec_disable(struct ftm_quaddec *ftm)
+{
+   ftm_write(ftm, FTM_MODE, 0);
+}
+
+static int ftm_quaddec_get_prescaler(struct counter_device *counter,
+struct counter_count *count,
+size_t *cnt_mode)
+{
+   struct ftm_quaddec *ftm = counter->priv;
+   uint32_t scflags;
+
+   ftm_read(ftm, FTM_SC, &scflags);
+
+   *cnt_mode = scflags & FTM_SC_PS_MASK;
+
+   return 0;
+}
+
+static int ftm_quaddec_set_prescaler(struct counter_device *counter,
+

[PATCH v2 4/7] dt-bindings: counter: ftm-quaddec

2019-03-06 Thread Patrick Havelange
FlexTimer quadrature decoder driver.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
Changes v2
 - None
---
 .../bindings/counter/ftm-quaddec.txt   | 18 ++
 1 file changed, 18 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/counter/ftm-quaddec.txt

diff --git a/Documentation/devicetree/bindings/counter/ftm-quaddec.txt 
b/Documentation/devicetree/bindings/counter/ftm-quaddec.txt
new file mode 100644
index ..4d18cd722074
--- /dev/null
+++ b/Documentation/devicetree/bindings/counter/ftm-quaddec.txt
@@ -0,0 +1,18 @@
+FlexTimer Quadrature decoder counter
+
+This driver exposes a simple counter for the quadrature decoder mode.
+
+Required properties:
+- compatible:  Must be "fsl,ftm-quaddec".
+- reg: Must be set to the memory region of the flextimer.
+
+Optional property:
+- big-endian:  Access the device registers in big-endian mode.
+
+Example:
+   counter0: counter@29d {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x29d 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
-- 
2.19.1



[PATCH v2 0/7] FlexTimer Module Quadrature decoder counter

2019-03-06 Thread Patrick Havelange
This patch serie is to be applied on top of 
https://patchwork.kernel.org/project/linux-iio/list/?series=147
(a more recent version of the serie is available here : 
https://gitlab.com/vilhelmgray/iio/tree/generic_counter_v10 )

Main changes in v2: 
The code is a bit simpler, thanks to more use of devm_* functions.
The polling/32bit signed version has been dropped, as not needed and
no other driver is doing that.


Patrick Havelange (7):
  include/fsl: add common FlexTimer #defines in a separate header.
  drivers/pwm: pwm-fsl-ftm: use common header for FlexTimer #defines
  drivers/clocksource: timer-fsl-ftm: use common header for FlexTimer
#defines
  dt-bindings: counter: ftm-quaddec
  counter: add FlexTimer Module Quadrature decoder counter driver
  counter: ftm-quaddec: Documentation: Add specific counter sysfs
documentation
  LS1021A: dtsi: add ftm quad decoder entries

 .../ABI/testing/sysfs-bus-counter-ftm-quaddec |  16 +
 .../bindings/counter/ftm-quaddec.txt  |  18 +
 arch/arm/boot/dts/ls1021a.dtsi|  28 ++
 drivers/clocksource/timer-fsl-ftm.c   |  15 +-
 drivers/counter/Kconfig   |   9 +
 drivers/counter/Makefile  |   1 +
 drivers/counter/ftm-quaddec.c | 356 ++
 drivers/pwm/pwm-fsl-ftm.c |  44 +--
 include/linux/fsl/ftm.h   |  88 +
 9 files changed, 519 insertions(+), 56 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec
 create mode 100644 Documentation/devicetree/bindings/counter/ftm-quaddec.txt
 create mode 100644 drivers/counter/ftm-quaddec.c
 create mode 100644 include/linux/fsl/ftm.h

-- 
2.19.1



[PATCH v2 3/7] drivers/clocksource: timer-fsl-ftm: use common header for FlexTimer #defines

2019-03-06 Thread Patrick Havelange
Common #defines have been moved to "linux/fsl/ftm.h". Thus making use of
this file.
Also FTM_SC_CLK_SHIFT has been renamed to FTM_SC_CLK_MASK_SHIFT.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
Changes v2
 - None
---
 drivers/clocksource/timer-fsl-ftm.c | 15 ++-
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/drivers/clocksource/timer-fsl-ftm.c 
b/drivers/clocksource/timer-fsl-ftm.c
index 846d18daf893..e1c34b2f53a5 100644
--- a/drivers/clocksource/timer-fsl-ftm.c
+++ b/drivers/clocksource/timer-fsl-ftm.c
@@ -19,20 +19,9 @@
 #include 
 #include 
 #include 
+#include 
 
-#define FTM_SC 0x00
-#define FTM_SC_CLK_SHIFT   3
-#define FTM_SC_CLK_MASK(0x3 << FTM_SC_CLK_SHIFT)
-#define FTM_SC_CLK(c)  ((c) << FTM_SC_CLK_SHIFT)
-#define FTM_SC_PS_MASK 0x7
-#define FTM_SC_TOIEBIT(6)
-#define FTM_SC_TOF BIT(7)
-
-#define FTM_CNT0x04
-#define FTM_MOD0x08
-#define FTM_CNTIN  0x4C
-
-#define FTM_PS_MAX 7
+#define FTM_SC_CLK(c)  ((c) << FTM_SC_CLK_MASK_SHIFT)
 
 struct ftm_clock_device {
void __iomem *clksrc_base;
-- 
2.19.1



[PATCH v2 6/7] counter: ftm-quaddec: Documentation: Add specific counter sysfs documentation

2019-03-06 Thread Patrick Havelange
This adds documentation for the specific prescaler entry.

Signed-off-by: Patrick Havelange 
---
Changes v2
 - Add doc for prescaler entry
---
 .../ABI/testing/sysfs-bus-counter-ftm-quaddec| 16 
 1 file changed, 16 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec

diff --git a/Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec 
b/Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec
new file mode 100644
index ..2da629d6d485
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec
@@ -0,0 +1,16 @@
+What:  /sys/bus/counter/devices/counterX/countY/prescaler_available
+KernelVersion: 5.1
+Contact:   linux-...@vger.kernel.org
+Description:
+   Discrete set of available values for the respective Count Y
+   configuration are listed in this file. Values are delimited by
+   newline characters.
+
+What:  /sys/bus/counter/devices/counterX/countY/prescaler
+KernelVersion: 5.1
+Contact:   linux-...@vger.kernel.org
+Description:
+   Configure the prescaler value associated with Count Y.
+   On the FlexTimer, the counter clock source passes through a
+   prescaler that is a 7-bit counter. This acts like a clock
+   divider.
-- 
2.19.1



[PATCH v2 2/7] drivers/pwm: pwm-fsl-ftm: use common header for FlexTimer #defines

2019-03-06 Thread Patrick Havelange
This also fixes the wrong value for the previously defined
FTM_MODE_INIT macro (it was not used).

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
Changes v2
 - None
---
 drivers/pwm/pwm-fsl-ftm.c | 44 +--
 1 file changed, 1 insertion(+), 43 deletions(-)

diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c
index 883378d055c6..f21ea1b97116 100644
--- a/drivers/pwm/pwm-fsl-ftm.c
+++ b/drivers/pwm/pwm-fsl-ftm.c
@@ -22,51 +22,9 @@
 #include 
 #include 
 #include 
+#include 
 
-#define FTM_SC 0x00
-#define FTM_SC_CLK_MASK_SHIFT  3
-#define FTM_SC_CLK_MASK(3 << FTM_SC_CLK_MASK_SHIFT)
 #define FTM_SC_CLK(c)  (((c) + 1) << FTM_SC_CLK_MASK_SHIFT)
-#define FTM_SC_PS_MASK 0x7
-
-#define FTM_CNT0x04
-#define FTM_MOD0x08
-
-#define FTM_CSC_BASE   0x0C
-#define FTM_CSC_MSBBIT(5)
-#define FTM_CSC_MSABIT(4)
-#define FTM_CSC_ELSB   BIT(3)
-#define FTM_CSC_ELSA   BIT(2)
-#define FTM_CSC(_channel)  (FTM_CSC_BASE + ((_channel) * 8))
-
-#define FTM_CV_BASE0x10
-#define FTM_CV(_channel)   (FTM_CV_BASE + ((_channel) * 8))
-
-#define FTM_CNTIN  0x4C
-#define FTM_STATUS 0x50
-
-#define FTM_MODE   0x54
-#define FTM_MODE_FTMEN BIT(0)
-#define FTM_MODE_INIT  BIT(2)
-#define FTM_MODE_PWMSYNC   BIT(3)
-
-#define FTM_SYNC   0x58
-#define FTM_OUTINIT0x5C
-#define FTM_OUTMASK0x60
-#define FTM_COMBINE0x64
-#define FTM_DEADTIME   0x68
-#define FTM_EXTTRIG0x6C
-#define FTM_POL0x70
-#define FTM_FMS0x74
-#define FTM_FILTER 0x78
-#define FTM_FLTCTRL0x7C
-#define FTM_QDCTRL 0x80
-#define FTM_CONF   0x84
-#define FTM_FLTPOL 0x88
-#define FTM_SYNCONF0x8C
-#define FTM_INVCTRL0x90
-#define FTM_SWOCTRL0x94
-#define FTM_PWMLOAD0x98
 
 enum fsl_pwm_clk {
FSL_PWM_CLK_SYS,
-- 
2.19.1



[PATCH v2 1/7] include/fsl: add common FlexTimer #defines in a separate header.

2019-03-06 Thread Patrick Havelange
Several files are/will be using the same #defines to use the Flextimer
module. Regroup them in a common file.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
Changes v2
 - Commit message
---
 include/linux/fsl/ftm.h | 88 +
 1 file changed, 88 insertions(+)
 create mode 100644 include/linux/fsl/ftm.h

diff --git a/include/linux/fsl/ftm.h b/include/linux/fsl/ftm.h
new file mode 100644
index ..d59011acf66c
--- /dev/null
+++ b/include/linux/fsl/ftm.h
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+#ifndef __FSL_FTM_H__
+#define __FSL_FTM_H__
+
+#define FTM_SC   0x0 /* Status And Control */
+#define FTM_CNT  0x4 /* Counter */
+#define FTM_MOD  0x8 /* Modulo */
+
+#define FTM_CNTIN0x4C /* Counter Initial Value */
+#define FTM_STATUS   0x50 /* Capture And Compare Status */
+#define FTM_MODE 0x54 /* Features Mode Selection */
+#define FTM_SYNC 0x58 /* Synchronization */
+#define FTM_OUTINIT  0x5C /* Initial State For Channels Output */
+#define FTM_OUTMASK  0x60 /* Output Mask */
+#define FTM_COMBINE  0x64 /* Function For Linked Channels */
+#define FTM_DEADTIME 0x68 /* Deadtime Insertion Control */
+#define FTM_EXTTRIG  0x6C /* FTM External Trigger */
+#define FTM_POL  0x70 /* Channels Polarity */
+#define FTM_FMS  0x74 /* Fault Mode Status */
+#define FTM_FILTER   0x78 /* Input Capture Filter Control */
+#define FTM_FLTCTRL  0x7C /* Fault Control */
+#define FTM_QDCTRL   0x80 /* Quadrature Decoder Control And Status */
+#define FTM_CONF 0x84 /* Configuration */
+#define FTM_FLTPOL   0x88 /* FTM Fault Input Polarity */
+#define FTM_SYNCONF  0x8C /* Synchronization Configuration */
+#define FTM_INVCTRL  0x90 /* FTM Inverting Control */
+#define FTM_SWOCTRL  0x94 /* FTM Software Output Control */
+#define FTM_PWMLOAD  0x98 /* FTM PWM Load */
+
+#define FTM_SC_CLK_MASK_SHIFT  3
+#define FTM_SC_CLK_MASK(3 << FTM_SC_CLK_MASK_SHIFT)
+#define FTM_SC_TOF 0x80
+#define FTM_SC_TOIE0x40
+#define FTM_SC_CPWMS   0x20
+#define FTM_SC_CLKS0x18
+#define FTM_SC_PS_10x0
+#define FTM_SC_PS_20x1
+#define FTM_SC_PS_40x2
+#define FTM_SC_PS_80x3
+#define FTM_SC_PS_16   0x4
+#define FTM_SC_PS_32   0x5
+#define FTM_SC_PS_64   0x6
+#define FTM_SC_PS_128  0x7
+#define FTM_SC_PS_MASK 0x7
+
+#define FTM_MODE_FAULTIE   0x80
+#define FTM_MODE_FAULTM0x60
+#define FTM_MODE_CAPTEST   0x10
+#define FTM_MODE_PWMSYNC   0x8
+#define FTM_MODE_WPDIS 0x4
+#define FTM_MODE_INIT  0x2
+#define FTM_MODE_FTMEN 0x1
+
+/* NXP Errata: The PHAFLTREN and PHBFLTREN bits are tide to zero internally
+ * and these bits cannot be set. Flextimer cannot use Filter in
+ * Quadrature Decoder Mode.
+ * https://community.nxp.com/thread/467648#comment-1010319
+ */
+#define FTM_QDCTRL_PHAFLTREN   0x80
+#define FTM_QDCTRL_PHBFLTREN   0x40
+#define FTM_QDCTRL_PHAPOL  0x20
+#define FTM_QDCTRL_PHBPOL  0x10
+#define FTM_QDCTRL_QUADMODE0x8
+#define FTM_QDCTRL_QUADDIR 0x4
+#define FTM_QDCTRL_TOFDIR  0x2
+#define FTM_QDCTRL_QUADEN  0x1
+
+#define FTM_FMS_FAULTF 0x80
+#define FTM_FMS_WPEN   0x40
+#define FTM_FMS_FAULTIN0x10
+#define FTM_FMS_FAULTF30x8
+#define FTM_FMS_FAULTF20x4
+#define FTM_FMS_FAULTF10x2
+#define FTM_FMS_FAULTF00x1
+
+#define FTM_CSC_BASE   0xC
+#define FTM_CSC_MSB0x20
+#define FTM_CSC_MSA0x10
+#define FTM_CSC_ELSB   0x8
+#define FTM_CSC_ELSA   0x4
+#define FTM_CSC(_channel)  (FTM_CSC_BASE + ((_channel) * 8))
+
+#define FTM_CV_BASE0x10
+#define FTM_CV(_channel)   (FTM_CV_BASE + ((_channel) * 8))
+
+#define FTM_PS_MAX 7
+
+#endif
-- 
2.19.1



[PATCH v6 3/4] iio:temperature:max31856:Add device tree bind info

2019-03-07 Thread Patrick Havelange
From: Paresh Chaudhary 

This patch added device tree binding info for MAX31856 driver.

Signed-off-by: Paresh Chaudhary 
Signed-off-by: Matt Weber 
Signed-off-by: Patrick Havelange 
---
Changes
v1 -> v2
[Matt
 - Removed comment block and added possibilities of
   thermocouple type in device tree binding doc.

v2 -> v3
 - Rebased

v3 -> v4
 - Removed one-shot property related information.
 - Used standard name 'temp-sensor'

v4 -> v5
[Patrick
 - Rename thermocouple type to maxim,thermocouple-type for DT entry

v5 -> v6
[Patrick
 - use generic thermocouple-type for DT entry
---
 .../bindings/iio/temperature/max31856.txt | 24 +++
 1 file changed, 24 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/iio/temperature/max31856.txt

diff --git a/Documentation/devicetree/bindings/iio/temperature/max31856.txt 
b/Documentation/devicetree/bindings/iio/temperature/max31856.txt
new file mode 100644
index ..06ab43bb4de8
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/temperature/max31856.txt
@@ -0,0 +1,24 @@
+Maxim MAX31856 thermocouple support
+
+https://datasheets.maximintegrated.com/en/ds/MAX31856.pdf
+
+Optional property:
+   - thermocouple-type: Type of thermocouple (THERMOCOUPLE_TYPE_K if
+   omitted). Supported types are B, E, J, K, N, R, S, T.
+
+Required properties:
+   - compatible: must be "maxim,max31856"
+   - reg: SPI chip select number for the device
+   - spi-max-frequency: As per datasheet max. supported freq is 500
+   - spi-cpha: must be defined for max31856 to enable SPI mode 1
+
+   Refer to spi/spi-bus.txt for generic SPI slave bindings.
+
+ Example:
+   temp-sensor@0 {
+   compatible = "maxim,max31856";
+   reg = <0>;
+   spi-max-frequency = <500>;
+   spi-cpha;
+   thermocouple-type = ;
+   };
-- 
2.19.1



[PATCH v6 2/4] dt-bindings: iio/temperature: Add doc for thermocouple-type

2019-03-07 Thread Patrick Havelange
This explains the new generic property "thermocouple-type" that
can be used with temperature sensors.

Signed-off-by: Patrick Havelange 
---
Changes v6
 - Add this file
---
 .../bindings/iio/temperature/temperature-bindings.txt | 11 +++
 1 file changed, 11 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/iio/temperature/temperature-bindings.txt

diff --git 
a/Documentation/devicetree/bindings/iio/temperature/temperature-bindings.txt 
b/Documentation/devicetree/bindings/iio/temperature/temperature-bindings.txt
new file mode 100644
index ..69a6441d8083
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/temperature/temperature-bindings.txt
@@ -0,0 +1,11 @@
+If the temperature sensor device can be configured to use some specific
+thermocouple type, you can use the defined types provided in the file
+"include/dt-bindings/iio/temperature/thermocouple.h".
+
+Optional property:
+thermocouple-type: The type of the thermocouple used by the device.
+
+For example:
+   device {
+   thermocouple-type =  ;
+   };
-- 
2.19.1



[PATCH v6 1/4] dt-bindings: iio/temperature: Add thermocouple types

2019-03-07 Thread Patrick Havelange
This patch introduces common thermocouple types used by various
temperature sensors.

Signed-off-by: Patrick Havelange 
---
Changes v6
 - Add this file
---
 .../dt-bindings/iio/temperature/thermocouple.h   | 16 
 1 file changed, 16 insertions(+)
 create mode 100644 include/dt-bindings/iio/temperature/thermocouple.h

diff --git a/include/dt-bindings/iio/temperature/thermocouple.h 
b/include/dt-bindings/iio/temperature/thermocouple.h
new file mode 100644
index ..ce037f5238ac
--- /dev/null
+++ b/include/dt-bindings/iio/temperature/thermocouple.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _DT_BINDINGS_TEMPERATURE_THERMOCOUPLE_H
+#define _DT_BINDINGS_TEMPERATURE_THERMOCOUPLE_H
+
+
+#define THERMOCOUPLE_TYPE_B0x00
+#define THERMOCOUPLE_TYPE_E0x01
+#define THERMOCOUPLE_TYPE_J0x02
+#define THERMOCOUPLE_TYPE_K0x03
+#define THERMOCOUPLE_TYPE_N0x04
+#define THERMOCOUPLE_TYPE_R0x05
+#define THERMOCOUPLE_TYPE_S0x06
+#define THERMOCOUPLE_TYPE_T0x07
+
+#endif /* _DT_BINDINGS_TEMPERATURE_THERMOCOUPLE_H */
-- 
2.19.1



[PATCH v6 4/4] iio:temperature: Add MAX31856 thermocouple support

2019-03-07 Thread Patrick Havelange
From: Paresh Chaudhary 

This patch adds support for Maxim MAX31856 thermocouple
temperature sensor support.

More information can be found in:
https://www.maximintegrated.com/en/ds/MAX31856.pdf

NOTE: Driver support only Comparator Mode.

Signed-off-by: Paresh Chaudhary 
Signed-off-by: Matt Weber 
Signed-off-by: Patrick Havelange 
---
Changes
v1 -> v2
[Peter
1. Fixed all space & 'return' related comments
2. Removed 'sysfs_create_group' api  because
   iio_device_register function is handling sysfs entry
3. Return -EIO if there is any fault
4. Added check for 'read_size' before spi read call
5. Removed license text from the source file
6. Added .o file in alphabetic order
7. Used #defines instead of magic bits

v2 -> v3
[Jonathan
1. Used bool for fault_oc and fault_ovuv
2. Changed 'max31856_read' function and use byte array to
   store registers value.
3. Used 'GENMASK' where required
4. Changed logic 'max31856_thermocouple_read' function. Used
   array to read registers value.
5. Used 'devm_iio_device_register' and removed 'max31856_remove'.
6. Fixed other cosmetic changes.
7. Added 'sysfs-bus-iio-temperature-max31856' file and updated
   'MAINTAINERS' file.

v3 -> v4
[Jonathan
1. Removed unwanted logic
2. Updated code to handle return value of max31856_read call
3. Added devicetree id table
4. Removed one-shot support from driver as this support was not
   implemented with correct design.

v4 -> v5
[Patrick
1. Rename thermocouple type to maxim,thermocouple-type for DT entry
2. Don't cache values from the Fault Status Register
3. Simplify a bit max31856_init()
4. Use IIO_NO_MOD in switch case + default error case
5. Use dev_*() instead of pr_*()
6. Fix missing space in comments
7. Removed iio_info.driver_module assignment as no longer present
8. Don't keep read/write buffer into the internal driver struct
9. Updated kernel version, add missing space in documentation
   10. Updated (c) year
   11. Removed linux/init.h #include
   12. More use of BIT() macro
   13. Removed iio_chan_spec.address assignment as not used
   14. In max31856_thermocouple_read(), same switch case order as
   channels definition
   15. Refactor show_fault_*() functions
   16. Use u8 as register type in max31856_{read,write}()

v5 -> v6
[Patrick
1. Use generic thermocouple-type property
2. Fix doc for fault_ovuv entry
3. Add check for supported thermocouple-types in probe()
---
 .../sysfs-bus-iio-temperature-max31856|  24 ++
 drivers/iio/temperature/Kconfig   |  10 +
 drivers/iio/temperature/Makefile  |   1 +
 drivers/iio/temperature/max31856.c| 353 ++
 4 files changed, 388 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-temperature-max31856
 create mode 100644 drivers/iio/temperature/max31856.c

diff --git a/Documentation/ABI/testing/sysfs-bus-iio-temperature-max31856 
b/Documentation/ABI/testing/sysfs-bus-iio-temperature-max31856
new file mode 100644
index ..3b3509a3ef2f
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-iio-temperature-max31856
@@ -0,0 +1,24 @@
+What:  /sys/bus/iio/devices/iio:deviceX/fault_oc
+KernelVersion: 5.1
+Contact:   linux-...@vger.kernel.org
+Description:
+   Open-circuit fault. The detection of open-circuit faults,
+   such as those caused by broken thermocouple wires.
+   Reading returns either '1' or '0'.
+   '1' = An open circuit such as broken thermocouple wires
+ has been detected.
+   '0' = No open circuit or broken thermocouple wires are detected
+
+What:  /sys/bus/iio/devices/iio:deviceX/fault_ovuv
+KernelVersion: 5.1
+Contact:   linux-...@vger.kernel.org
+Description:
+   Overvoltage or Undervoltage Input Fault. The internal circuitry
+   is protected from excessive voltages applied to the thermocouple
+   cables by integrated MOSFETs at the T+ and T- inputs, and the
+   BIAS output. These MOSFETs turn off when the input voltage is
+   negative or greater than VDD.
+   Reading returns either '1' or '0'.
+   '1' = The input voltage is negative or greater than VDD.
+   '0' = The input voltage is positive and less than VDD (normal
+   state).
diff --git a/drivers/iio/temperature/Kconfig b/drivers/iio/temperature/Kconfig
index 82e4a62745e2..c66eeb23615b 100644
--- 

[PATCH] EDAC: Add mention of LS1021A inside comments of fsl_ddr_edac driver

2018-12-19 Thread Patrick Havelange
The Freescale ddr driver also works on the LS1021A board.

Signed-off-by: Patrick Havelange 
---
 drivers/edac/fsl_ddr_edac.c | 4 ++--
 drivers/edac/fsl_ddr_edac.h | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/edac/fsl_ddr_edac.c b/drivers/edac/fsl_ddr_edac.c
index efc8276d1d9c..5c11f3637651 100644
--- a/drivers/edac/fsl_ddr_edac.c
+++ b/drivers/edac/fsl_ddr_edac.c
@@ -2,8 +2,8 @@
  * Freescale Memory Controller kernel module
  *
  * Support Power-based SoCs including MPC85xx, MPC86xx, MPC83xx and
- * ARM-based Layerscape SoCs including LS2xxx. Originally split
- * out from mpc85xx_edac EDAC driver.
+ * ARM-based Layerscape SoCs including LS2xxx and LS1021A. Originally
+ * split out from mpc85xx_edac EDAC driver.
  *
  * Parts Copyrighted (c) 2013 by Freescale Semiconductor, Inc.
  *
diff --git a/drivers/edac/fsl_ddr_edac.h b/drivers/edac/fsl_ddr_edac.h
index 4ccee292eff1..589b9b4a5e8a 100644
--- a/drivers/edac/fsl_ddr_edac.h
+++ b/drivers/edac/fsl_ddr_edac.h
@@ -2,8 +2,8 @@
  * Freescale Memory Controller kernel module
  *
  * Support  Power-based SoCs including MPC85xx, MPC86xx, MPC83xx and
- * ARM-based Layerscape SoCs including LS2xxx. Originally split
- * out from mpc85xx_edac EDAC driver.
+ * ARM-based Layerscape SoCs including LS2xxx and LS1021A. Originally
+ * split out from mpc85xx_edac EDAC driver.
  *
  * Author: Dave Jiang 
  *
-- 
2.17.1



Re: [PATCH] counter/ftm-quaddec: Use device-managed registration API

2019-07-25 Thread Patrick Havelange
Hello,

Comments inline

On Thu, Jul 25, 2019 at 10:55 AM Chuhong Yuan  wrote:
>
> Make use of devm_counter_register.
> Then we can remove redundant unregistration API
> usage to make code simpler.
>
> Signed-off-by: Chuhong Yuan 
> ---
>  drivers/counter/ftm-quaddec.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/drivers/counter/ftm-quaddec.c b/drivers/counter/ftm-quaddec.c
> index 68a9b7393457..bccbca8681b6 100644
> --- a/drivers/counter/ftm-quaddec.c
> +++ b/drivers/counter/ftm-quaddec.c
> @@ -317,7 +317,7 @@ static int ftm_quaddec_probe(struct platform_device *pdev)
>
> ftm_quaddec_init(ftm);
>
> -   ret = counter_register(&ftm->counter);
> +   ret = devm_counter_register(&pdev->dev, &ftm->counter);
> if (ret)
> ftm_quaddec_disable(ftm);
>
> @@ -328,8 +328,6 @@ static int ftm_quaddec_remove(struct platform_device 
> *pdev)
>  {
> struct ftm_quaddec *ftm = platform_get_drvdata(pdev);
>
> -   counter_unregister(&ftm->counter);
> -

The orders of (de)initialization should be kept symmetrical.
In this case, now that counter_unregister() will be called via devm,
it will be executed after ftm_quaddec_remove()

This introduces a race condition where the ftm-quaddec is disabled but
the counter entry itself is not.

Somebody else (William?) should confirm this.


> ftm_quaddec_disable(ftm);
>
> return 0;
> --
> 2.20.1
>


Re: [PATCH v2] counter/ftm-quaddec: Use device-managed registration API

2019-07-26 Thread Patrick Havelange
Hello,

On Fri, Jul 26, 2019 at 4:28 AM Chuhong Yuan  wrote:
>
> Make use of devm_counter_register.
> Then we can remove redundant unregistration API
> usage to make code simpler.
>
> Signed-off-by: Chuhong Yuan 
> ---
> Changes in v2:
>   - Use devm_add_action_or_reset to keep
> resource release order.

This is better now indeed.

However it seems there is an issue with the mail/patch format, I'm
unable to apply it with git am, and if you look at
https://lore.kernel.org/patchwork/patch/1105782/ the diff section is
missing the beginning of the patch. I don't know why, but I think it
should be looked into.

Otherwise, it's fine by me.

Regards,

Patrick Havelange


>   - _remove() function is redundant now,
> delete it.
>
>  drivers/counter/ftm-quaddec.c | 31 +++
>  1 file changed, 11 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/counter/ftm-quaddec.c b/drivers/counter/ftm-quaddec.c
> index 68a9b7393457..76c70a6c3593 100644
> --- a/drivers/counter/ftm-quaddec.c
> +++ b/drivers/counter/ftm-quaddec.c
> @@ -100,16 +100,17 @@ static void ftm_quaddec_init(struct ftm_quaddec *ftm)
> ftm_set_write_protection(ftm);
>  }
>
> -static void ftm_quaddec_disable(struct ftm_quaddec *ftm)
> +static void ftm_quaddec_disable(void *ftm)
>  {
> -   ftm_clear_write_protection(ftm);
> -   ftm_write(ftm, FTM_MODE, 0);
> -   ftm_write(ftm, FTM_QDCTRL, 0);
> +   struct ftm_quaddec *ftm_qua = ftm;
>
> +   ftm_clear_write_protection(ftm_qua);
> +   ftm_write(ftm_qua, FTM_MODE, 0);
> +   ftm_write(ftm_qua, FTM_QDCTRL, 0);
> /*
>  * This is enough to disable the counter. No clock has been
>  * selected by writing to FTM_SC in init()
>  */
> -   ftm_set_write_protection(ftm);
> +   ftm_set_write_protection(ftm_qua);
>  }
>
>  static int ftm_quaddec_get_prescaler(struct counter_device *counter,
> @@ -316,22 +317,13 @@ static int ftm_quaddec_probe(struct platform_device 
> *pdev)
> mutex_init(&ftm->ftm_quaddec_mutex);
>
> ftm_quaddec_init(ftm);
> -
> -   ret = counter_register(&ftm->counter);
> +   ret = devm_add_action_or_reset(&pdev->dev, ftm_quaddec_disable, ftm);
> if (ret)
> -   ftm_quaddec_disable(ftm);
> -
> -   return ret;
> -}
> -
> -static int ftm_quaddec_remove(struct platform_device *pdev)
> -{
> -   struct ftm_quaddec *ftm = platform_get_drvdata(pdev);
> -
> -   counter_unregister(&ftm->counter);
> -
> -   ftm_quaddec_disable(ftm);
> +   return ret;
>
> +   ret = devm_counter_register(&pdev->dev, &ftm->counter);
> +   if (ret)
> +   return ret;
> return 0;
>  }
>
> @@ -346,7 +338,6 @@ static struct platform_driver ftm_quaddec_driver = {
> .of_match_table = ftm_quaddec_match,
> },
> .probe = ftm_quaddec_probe,
> -   .remove = ftm_quaddec_remove,
>  };
>
>  module_platform_driver(ftm_quaddec_driver);
> --
> 2.20.1
>


Re: [PATCH v2] counter/ftm-quaddec: Use device-managed registration API

2019-07-29 Thread Patrick Havelange
On Fri, Jul 26, 2019 at 3:39 PM Chuhong Yuan  wrote:
>
> Make use of devm_counter_register.
> Then we can remove redundant unregistration API
> usage to make code simpler.
>
> Signed-off-by: Chuhong Yuan 

Reviewed-by: Patrick Havelange 

Maybe a bit too late, sorry for that. Thanks for the patch.

Patrick H.

> ---
> Changes in v2:
>   - Use devm_add_action_or_reset to keep
> resource release order.
>   - remove() function is redundant now,
> delete it.
>
>  drivers/counter/ftm-quaddec.c | 30 --
>  1 file changed, 12 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/counter/ftm-quaddec.c b/drivers/counter/ftm-quaddec.c
> index 68a9b7393457..4046aa9f9234 100644
> --- a/drivers/counter/ftm-quaddec.c
> +++ b/drivers/counter/ftm-quaddec.c
> @@ -100,16 +100,18 @@ static void ftm_quaddec_init(struct ftm_quaddec *ftm)
> ftm_set_write_protection(ftm);
>  }
>
> -static void ftm_quaddec_disable(struct ftm_quaddec *ftm)
> +static void ftm_quaddec_disable(void *ftm)
>  {
> -   ftm_clear_write_protection(ftm);
> -   ftm_write(ftm, FTM_MODE, 0);
> -   ftm_write(ftm, FTM_QDCTRL, 0);
> +   struct ftm_quaddec *ftm_qua = ftm;
> +
> +   ftm_clear_write_protection(ftm_qua);
> +   ftm_write(ftm_qua, FTM_MODE, 0);
> +   ftm_write(ftm_qua, FTM_QDCTRL, 0);
> /*
>  * This is enough to disable the counter. No clock has been
>  * selected by writing to FTM_SC in init()
>  */
> -   ftm_set_write_protection(ftm);
> +   ftm_set_write_protection(ftm_qua);
>  }
>
>  static int ftm_quaddec_get_prescaler(struct counter_device *counter,
> @@ -317,20 +319,13 @@ static int ftm_quaddec_probe(struct platform_device 
> *pdev)
>
> ftm_quaddec_init(ftm);
>
> -   ret = counter_register(&ftm->counter);
> +   ret = devm_add_action_or_reset(&pdev->dev, ftm_quaddec_disable, ftm);
> if (ret)
> -   ftm_quaddec_disable(ftm);
> -
> -   return ret;
> -}
> +   return ret;
>
> -static int ftm_quaddec_remove(struct platform_device *pdev)
> -{
> -   struct ftm_quaddec *ftm = platform_get_drvdata(pdev);
> -
> -   counter_unregister(&ftm->counter);
> -
> -   ftm_quaddec_disable(ftm);
> +   ret = devm_counter_register(&pdev->dev, &ftm->counter);
> +   if (ret)
> +   return ret;
>
> return 0;
>  }
> @@ -346,7 +341,6 @@ static struct platform_driver ftm_quaddec_driver = {
> .of_match_table = ftm_quaddec_match,
> },
> .probe = ftm_quaddec_probe,
> -   .remove = ftm_quaddec_remove,
>  };
>
>  module_platform_driver(ftm_quaddec_driver);
> --
> 2.20.1
>


[PATCH 1/1] counter/ftm-quaddec: Add missing '>' in MODULE_AUTHOR

2019-06-18 Thread Patrick Havelange
The last '>' chars were missing in the MODULE_AUTHOR entries.

Reported-by: Randy Dunlap 
Fixes: a3b9a99980d9 ("counter: add FlexTimer Module Quadrature decoder counter 
driver")
Signed-off-by: Patrick Havelange 
---
 drivers/counter/ftm-quaddec.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/counter/ftm-quaddec.c b/drivers/counter/ftm-quaddec.c
index c83c8875bf82..68a9b7393457 100644
--- a/drivers/counter/ftm-quaddec.c
+++ b/drivers/counter/ftm-quaddec.c
@@ -352,5 +352,5 @@ static struct platform_driver ftm_quaddec_driver = {
 module_platform_driver(ftm_quaddec_driver);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kjeld Flarup ");
+MODULE_AUTHOR("Patrick Havelange ");
-- 
2.19.1



[PATCH 1/2] pwm: pwm-fsl-ftm: more relaxed permissions for updating period

2019-06-12 Thread Patrick Havelange
The Flextimer has only one period for several channels. The PWM
subsystem doesn't allow to model something like that. The current
implementation simply disallows changing the period once it has
been set, having as a side effect that you need to enable and
disable the PWM if you want to change the period.

The driver should allow as much freedom as possible for configuring
the period and duty cycle. Therefore, this patch reworks the code
to allow the following:

- period and duty_cycle can be set at will when the pwm is disabled;
- when enabling a pwm, verify that the period is either not set yet,
  or the same as the other already enabled pwm(s), and fail if not;
- allow to change the period on the fly when the pwm is the only one
  enabled.

It also allows to have different periods configured for different pwms.
Only one period can be used at a time, thus the first pwm to be enabled
will set that period, only other pwms with that same period can be
enabled at the same time. To use another pwm with another period, the
enabled pwms must be disabled first.

Example scenario :
echo 500 > pwm0/period  #OK
echo 100 > pwm0/duty_cycle  #OK
echo 100 > pwm1/period  #OK
echo 100 > pwm1/duty_cycle  #OK
echo 1 > pwm0/enable#OK
echo 1 > pwm1/enable#FAIL (pwm0/period != pwm1/period)
echo 0 > pwm0/enable#OK
echo 1 > pwm1/enable#OK
echo 100 > pwm0/period  #OK
echo 200 > pwm0/period  #OK
echo 1 > pwm0/enable#FAIL (pwm0/period != pwm1/period)
echo 200 > pwm1/period  #OK (pwm1 still running, changed on the fly)
echo 1 > pwm0/enable#OK (now pwm0/period == pwm1/period)
echo 300 > pwm1/period  #FAIL (other pwms running)
echo 0 > pwm0/enable#OK
echo 300 > pwm1/period  #OK (only this pwm running)

Adapting the code to satisfy these constraints turned up a number of
additional issues with the current implementation:
- the prescaler value 0 was not used (when it could have been);
- when setting the period was not possible, the internal state was
  inconsistent;
- the maximal value for configuring the period was never used;

Since all of these interact with each other, rather than trying to fix
each individual issue, this patch reworks how the period and duty cycle are
set entirely, with the following additional improvements:
- implement the new apply() method instead of the individual methods;
- return the exact used period/duty_cycle values;
- more coherent argument types for period, duty_cycle;

Signed-off-by: Patrick Havelange 
---
 drivers/pwm/pwm-fsl-ftm.c | 364 +++---
 1 file changed, 183 insertions(+), 181 deletions(-)

diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c
index a39b48839df7..cd5fe39ab95d 100644
--- a/drivers/pwm/pwm-fsl-ftm.c
+++ b/drivers/pwm/pwm-fsl-ftm.c
@@ -34,17 +34,19 @@ struct fsl_ftm_soc {
bool has_enable_bits;
 };
 
+struct fsl_pwm_periodcfg {
+   enum fsl_pwm_clk clk_select;
+   unsigned int clk_ps;
+   unsigned int mod_period;
+};
+
 struct fsl_pwm_chip {
struct pwm_chip chip;
-
struct mutex lock;
-
-   unsigned int cnt_select;
-   unsigned int clk_ps;
-
struct regmap *regmap;
 
-   int period_ns;
+   /* This value is valid iff a pwm is running */
+   struct fsl_pwm_periodcfg period;
 
struct clk *ipg_clk;
struct clk *clk[FSL_PWM_CLK_MAX];
@@ -57,6 +59,18 @@ static inline struct fsl_pwm_chip *to_fsl_chip(struct 
pwm_chip *chip)
return container_of(chip, struct fsl_pwm_chip, chip);
 }
 
+static bool fsl_pwm_periodcfg_are_equal(const struct fsl_pwm_periodcfg *a,
+   const struct fsl_pwm_periodcfg *b)
+{
+   if (a->clk_select != b->clk_select)
+   return false;
+   if (a->clk_ps != b->clk_ps)
+   return false;
+   if (a->mod_period != b->mod_period)
+   return false;
+   return true;
+}
+
 static int fsl_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
 {
int ret;
@@ -87,89 +101,58 @@ static void fsl_pwm_free(struct pwm_chip *chip, struct 
pwm_device *pwm)
clk_disable_unprepare(fpc->ipg_clk);
 }
 
-static int fsl_pwm_calculate_default_ps(struct fsl_pwm_chip *fpc,
-   enum fsl_pwm_clk index)
+static unsigned int fsl_pwm_ticks_to_ns(struct fsl_pwm_chip *fpc,
+ unsigned int ticks)
 {
-   unsigned long sys_rate, cnt_rate;
-   unsigned long long ratio;
-
-   sys_rate = clk_get_rate(fpc->clk[FSL_PWM_CLK_SYS]);
-   if (!sys_rate)
-   return -EINVAL;
-
-   cnt_rate = clk_get_rate(fpc->clk[fpc->cnt_select]);
-   if (!cnt_rate)
-   return -EINVAL;
-
-   switch (index) {
-   case FSL_PWM_CLK_SYS:
-

[PATCH 2/2] pwm: pwm-fsl-ftm: Use write protection for prescaler & polarity

2019-06-12 Thread Patrick Havelange
Modifying the prescaler or polarity value must be done with the
write protection disabled. Currently this is working by chance as
the write protection is in a disabled state by default.
This patch makes sure that we enable/disable the write protection
when needed.

Signed-off-by: Patrick Havelange 
---
 drivers/pwm/pwm-fsl-ftm.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c
index cd5fe39ab95d..e955b1cdfd2f 100644
--- a/drivers/pwm/pwm-fsl-ftm.c
+++ b/drivers/pwm/pwm-fsl-ftm.c
@@ -59,6 +59,21 @@ static inline struct fsl_pwm_chip *to_fsl_chip(struct 
pwm_chip *chip)
return container_of(chip, struct fsl_pwm_chip, chip);
 }
 
+static void ftm_clear_write_protection(struct fsl_pwm_chip *fpc)
+{
+   u32 val;
+
+   regmap_read(fpc->regmap, FTM_FMS, &val);
+   if (val & FTM_FMS_WPEN)
+   regmap_update_bits(fpc->regmap, FTM_MODE, FTM_MODE_WPDIS,
+  FTM_MODE_WPDIS);
+}
+
+static void ftm_set_write_protection(struct fsl_pwm_chip *fpc)
+{
+   regmap_update_bits(fpc->regmap, FTM_FMS, FTM_FMS_WPEN, FTM_FMS_WPEN);
+}
+
 static bool fsl_pwm_periodcfg_are_equal(const struct fsl_pwm_periodcfg *a,
const struct fsl_pwm_periodcfg *b)
 {
@@ -253,6 +268,8 @@ static int fsl_pwm_apply_config(struct fsl_pwm_chip *fpc,
do_write_period = true;
}
 
+   ftm_clear_write_protection(fpc);
+
if (do_write_period) {
regmap_update_bits(fpc->regmap, FTM_SC, FTM_SC_CLK_MASK,
   FTM_SC_CLK(periodcfg.clk_select));
@@ -279,6 +296,8 @@ static int fsl_pwm_apply_config(struct fsl_pwm_chip *fpc,
   fpc->period.mod_period + 1);
newstate->duty_cycle = fsl_pwm_ticks_to_ns(fpc, duty);
 
+   ftm_set_write_protection(fpc);
+
return 0;
 }
 
@@ -359,6 +378,8 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
 static bool fsl_pwm_volatile_reg(struct device *dev, unsigned int reg)
 {
switch (reg) {
+   case FTM_FMS:
+   case FTM_MODE:
case FTM_CNT:
return true;
}
-- 
2.19.1



[PATCH 1/1] MAINTAINERS: add counter/ftm-quaddec driver entry

2019-06-12 Thread Patrick Havelange
Adding myself as maintainer for this driver

Signed-off-by: Patrick Havelange 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 57f496cff999..6671854098d6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6218,6 +6218,14 @@ M:   Philip Kelleher 
 S: Maintained
 F: drivers/block/rsxx/
 
+FLEXTIMER FTM-QUADDEC DRIVER
+M: Patrick Havelange 
+L: linux-...@vger.kernel.org
+S: Maintained
+F: Documentation/ABI/testing/sysfs-bus-counter-ftm-quadddec
+F: Documentation/devicetree/bindings/counter/ftm-quaddec.txt
+F: drivers/counter/ftm-quaddec.c
+
 FLOPPY DRIVER
 M: Jiri Kosina 
 T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/floppy.git
-- 
2.19.1