Re: [PATCH] MAINTAINERS: ftm-quaddec: Fix typo in a filepath
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
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
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)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.
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
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
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
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.
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
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
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
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
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
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
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
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
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.
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
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
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
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
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
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
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
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
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
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
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
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
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