* [PATCH v6 5/8] coresight: use const for device_node structures
From: Leo Yan @ 2017-04-06 13:30 UTC (permalink / raw)
To: Jonathan Corbet, Rob Herring, Mark Rutland, Wei Xu,
Catalin Marinas, Will Deacon, Andy Gross, David Brown,
Mathieu Poirier, Suzuki K Poulose, Stephen Boyd, linux-doc,
linux-kernel, devicetree, linux-arm-kernel, linux-arm-msm,
linux-soc, Mike Leach, Sudeep Holla
Cc: Leo Yan
In-Reply-To: <1491485461-22800-1-git-send-email-leo.yan@linaro.org>
Almost low level functions from open firmware have used const to
qualify device_node structures, so add const for device_node
parameters in of_coresight related functions.
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
drivers/hwtracing/coresight/of_coresight.c | 6 +++---
include/linux/coresight.h | 8 ++++----
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
index 78d2399..46eec0f 100644
--- a/drivers/hwtracing/coresight/of_coresight.c
+++ b/drivers/hwtracing/coresight/of_coresight.c
@@ -52,7 +52,7 @@ of_coresight_get_endpoint_device(struct device_node *endpoint)
endpoint, of_dev_node_match);
}
-static void of_coresight_get_ports(struct device_node *node,
+static void of_coresight_get_ports(const struct device_node *node,
int *nr_inport, int *nr_outport)
{
struct device_node *ep = NULL;
@@ -101,7 +101,7 @@ static int of_coresight_alloc_memory(struct device *dev,
return 0;
}
-int of_coresight_get_cpu(struct device_node *node)
+int of_coresight_get_cpu(const struct device_node *node)
{
int cpu;
bool found;
@@ -128,7 +128,7 @@ int of_coresight_get_cpu(struct device_node *node)
EXPORT_SYMBOL_GPL(of_coresight_get_cpu);
struct coresight_platform_data *of_get_coresight_platform_data(
- struct device *dev, struct device_node *node)
+ struct device *dev, const struct device_node *node)
{
int i = 0, ret = 0;
struct coresight_platform_data *pdata;
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index bf96678..4915254 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -263,13 +263,13 @@ static inline int coresight_timeout(void __iomem *addr, u32 offset,
#endif
#ifdef CONFIG_OF
-extern int of_coresight_get_cpu(struct device_node *node);
+extern int of_coresight_get_cpu(const struct device_node *node);
extern struct coresight_platform_data *of_get_coresight_platform_data(
- struct device *dev, struct device_node *node);
+ struct device *dev, const struct device_node *node);
#else
-static inline int of_coresight_get_cpu(struct device_node *node) { return 0; }
+static inline int of_coresight_get_cpu(const struct device_node *node) { return 0; }
static inline struct coresight_platform_data *of_get_coresight_platform_data(
- struct device *dev, struct device_node *node) { return NULL; }
+ struct device *dev, const struct device_node *node) { return NULL; }
#endif
#ifdef CONFIG_PID_NS
--
2.7.4
^ permalink raw reply related
* [PATCH v6 4/8] coresight: refactor with function of_coresight_get_cpu
From: Leo Yan @ 2017-04-06 13:30 UTC (permalink / raw)
To: Jonathan Corbet, Rob Herring, Mark Rutland, Wei Xu,
Catalin Marinas, Will Deacon, Andy Gross, David Brown,
Mathieu Poirier, Suzuki K Poulose, Stephen Boyd, linux-doc,
linux-kernel, devicetree, linux-arm-kernel, linux-arm-msm,
linux-soc, Mike Leach, Sudeep Holla
Cc: Leo Yan
In-Reply-To: <1491485461-22800-1-git-send-email-leo.yan@linaro.org>
This is refactor to add function of_coresight_get_cpu(), so it's used to
retrieve CPU id for coresight component. Finally can use it as a common
function for multiple places.
Suggested-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
drivers/hwtracing/coresight/of_coresight.c | 43 +++++++++++++++++++-----------
include/linux/coresight.h | 2 ++
2 files changed, 30 insertions(+), 15 deletions(-)
diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
index 1a77280..78d2399 100644
--- a/drivers/hwtracing/coresight/of_coresight.c
+++ b/drivers/hwtracing/coresight/of_coresight.c
@@ -101,15 +101,39 @@ static int of_coresight_alloc_memory(struct device *dev,
return 0;
}
+int of_coresight_get_cpu(struct device_node *node)
+{
+ int cpu;
+ bool found;
+ struct device_node *dn, *np;
+
+ dn = of_parse_phandle(node, "cpu", 0);
+
+ /* Affinity defaults to CPU0 */
+ if (!dn)
+ return 0;
+
+ for_each_possible_cpu(cpu) {
+ np = of_cpu_device_node_get(cpu);
+ found = (dn == np);
+ of_node_put(np);
+ if (found)
+ break;
+ }
+ of_node_put(dn);
+
+ /* Affinity to CPU0 if no cpu nodes are found */
+ return found ? cpu : 0;
+}
+EXPORT_SYMBOL_GPL(of_coresight_get_cpu);
+
struct coresight_platform_data *of_get_coresight_platform_data(
struct device *dev, struct device_node *node)
{
- int i = 0, ret = 0, cpu;
+ int i = 0, ret = 0;
struct coresight_platform_data *pdata;
struct of_endpoint endpoint, rendpoint;
struct device *rdev;
- bool found;
- struct device_node *dn, *np;
struct device_node *ep = NULL;
struct device_node *rparent = NULL;
struct device_node *rport = NULL;
@@ -176,18 +200,7 @@ struct coresight_platform_data *of_get_coresight_platform_data(
} while (ep);
}
- dn = of_parse_phandle(node, "cpu", 0);
- for_each_possible_cpu(cpu) {
- np = of_cpu_device_node_get(cpu);
- found = (dn == np);
- of_node_put(np);
- if (found)
- break;
- }
- of_node_put(dn);
-
- /* Affinity to CPU0 if no cpu nodes are found */
- pdata->cpu = found ? cpu : 0;
+ pdata->cpu = of_coresight_get_cpu(node);
return pdata;
}
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 2a5982c..bf96678 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -263,9 +263,11 @@ static inline int coresight_timeout(void __iomem *addr, u32 offset,
#endif
#ifdef CONFIG_OF
+extern int of_coresight_get_cpu(struct device_node *node);
extern struct coresight_platform_data *of_get_coresight_platform_data(
struct device *dev, struct device_node *node);
#else
+static inline int of_coresight_get_cpu(struct device_node *node) { return 0; }
static inline struct coresight_platform_data *of_get_coresight_platform_data(
struct device *dev, struct device_node *node) { return NULL; }
#endif
--
2.7.4
^ permalink raw reply related
* [PATCH v6 3/8] coresight: of_get_coresight_platform_data: Add missing of_node_put
From: Leo Yan @ 2017-04-06 13:30 UTC (permalink / raw)
To: Jonathan Corbet, Rob Herring, Mark Rutland, Wei Xu,
Catalin Marinas, Will Deacon, Andy Gross, David Brown,
Mathieu Poirier, Suzuki K Poulose, Stephen Boyd, linux-doc,
linux-kernel, devicetree, linux-arm-kernel, linux-arm-msm,
linux-soc, Mike Leach, Sudeep Holla
Cc: Leo Yan
In-Reply-To: <1491485461-22800-1-git-send-email-leo.yan@linaro.org>
From: Suzuki K Poulose <suzuki.poulose@arm.com>
The of_get_coresight_platform_data iterates over the possible CPU nodes
to find a given cpu phandle. However it does not drop the reference
to the node pointer returned by the of_get_coresight_platform_data.
This patch also introduces another minor fix is to use
of_cpu_device_node_get() to replace of_get_cpu_node().
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
[Leo: minor tweaks for of_get_coresight_platform_data]
Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
drivers/hwtracing/coresight/of_coresight.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
index 629e031..1a77280 100644
--- a/drivers/hwtracing/coresight/of_coresight.c
+++ b/drivers/hwtracing/coresight/of_coresight.c
@@ -108,7 +108,8 @@ struct coresight_platform_data *of_get_coresight_platform_data(
struct coresight_platform_data *pdata;
struct of_endpoint endpoint, rendpoint;
struct device *rdev;
- struct device_node *dn;
+ bool found;
+ struct device_node *dn, *np;
struct device_node *ep = NULL;
struct device_node *rparent = NULL;
struct device_node *rport = NULL;
@@ -175,17 +176,19 @@ struct coresight_platform_data *of_get_coresight_platform_data(
} while (ep);
}
- /* Affinity defaults to CPU0 */
- pdata->cpu = 0;
dn = of_parse_phandle(node, "cpu", 0);
- for (cpu = 0; dn && cpu < nr_cpu_ids; cpu++) {
- if (dn == of_get_cpu_node(cpu, NULL)) {
- pdata->cpu = cpu;
+ for_each_possible_cpu(cpu) {
+ np = of_cpu_device_node_get(cpu);
+ found = (dn == np);
+ of_node_put(np);
+ if (found)
break;
- }
}
of_node_put(dn);
+ /* Affinity to CPU0 if no cpu nodes are found */
+ pdata->cpu = found ? cpu : 0;
+
return pdata;
}
EXPORT_SYMBOL_GPL(of_get_coresight_platform_data);
--
2.7.4
^ permalink raw reply related
* [PATCH v6 2/8] doc: Add documentation for Coresight CPU debug
From: Leo Yan @ 2017-04-06 13:30 UTC (permalink / raw)
To: Jonathan Corbet, Rob Herring, Mark Rutland, Wei Xu,
Catalin Marinas, Will Deacon, Andy Gross, David Brown,
Mathieu Poirier, Suzuki K Poulose, Stephen Boyd, linux-doc,
linux-kernel, devicetree, linux-arm-kernel, linux-arm-msm,
linux-soc, Mike Leach, Sudeep Holla
Cc: Leo Yan
In-Reply-To: <1491485461-22800-1-git-send-email-leo.yan@linaro.org>
Update kernel-parameters.txt to add new parameter:
coresight_cpu_debug.enable is a knob to enable debugging at boot time.
Add detailed documentation, which contains the implementation, Mike
Leach excellent summary for "clock and power domain". At the end some
examples on how to enable the debugging functionality are provided.
Suggested-by: Mike Leach <mike.leach@linaro.org>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
Documentation/admin-guide/kernel-parameters.txt | 7 +
Documentation/trace/coresight-cpu-debug.txt | 173 ++++++++++++++++++++++++
2 files changed, 180 insertions(+)
create mode 100644 Documentation/trace/coresight-cpu-debug.txt
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index facc20a..cf90146 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -650,6 +650,13 @@
/proc/<pid>/coredump_filter.
See also Documentation/filesystems/proc.txt.
+ coresight_cpu_debug.enable
+ [ARM,ARM64]
+ Format: <bool>
+ Enable/disable the CPU sampling based debugging.
+ 0: default value, disable debugging
+ 1: enable debugging at boot time
+
cpuidle.off=1 [CPU_IDLE]
disable the cpuidle sub-system
diff --git a/Documentation/trace/coresight-cpu-debug.txt b/Documentation/trace/coresight-cpu-debug.txt
new file mode 100644
index 0000000..e7ad05e
--- /dev/null
+++ b/Documentation/trace/coresight-cpu-debug.txt
@@ -0,0 +1,173 @@
+ Coresight CPU Debug Module
+ ==========================
+
+ Author: Leo Yan <leo.yan@linaro.org>
+ Date: April 5th, 2017
+
+Introduction
+------------
+
+Coresight CPU debug module is defined in ARMv8-a architecture reference manual
+(ARM DDI 0487A.k) Chapter 'Part H: External debug', the CPU can integrate
+debug module and it is mainly used for two modes: self-hosted debug and
+external debug. Usually the external debug mode is well known as the external
+debugger connects with SoC from JTAG port; on the other hand the program can
+explore debugging method which rely on self-hosted debug mode, this document
+is to focus on this part.
+
+The debug module provides sample-based profiling extension, which can be used
+to sample CPU program counter, secure state and exception level, etc; usually
+every CPU has one dedicated debug module to be connected. Based on self-hosted
+debug mechanism, Linux kernel can access these related registers from mmio
+region when the kernel panic happens. The callback notifier for kernel panic
+will dump related registers for every CPU; finally this is good for assistant
+analysis for panic.
+
+
+Implementation
+--------------
+
+- During driver registration, use EDDEVID and EDDEVID1 two device ID
+ registers to decide if sample-based profiling is implemented or not. On some
+ platforms this hardware feature is fully or partialy implemented; and if
+ this feature is not supported then registration will fail.
+
+- When write this doc, the debug driver mainly relies on three sampling
+ registers. The kernel panic callback notifier gathers info from EDPCSR
+ EDVIDSR and EDCIDSR; from EDPCSR we can get program counter, EDVIDSR has
+ information for secure state, exception level, bit width, etc; EDCIDSR is
+ context ID value which contains the sampled value of CONTEXTIDR_EL1.
+
+- The driver supports CPU running mode with either AArch64 or AArch32. The
+ registers naming convention is a bit different between them, AArch64 uses
+ 'ED' for register prefix (ARM DDI 0487A.k, chapter H9.1) and AArch32 uses
+ 'DBG' as prefix (ARM DDI 0487A.k, chapter G5.1). The driver is unified to
+ use AArch64 naming convention.
+
+- ARMv8-a (ARM DDI 0487A.k) and ARMv7-a (ARM DDI 0406C.b) have different
+ register bits definition. So the driver consolidates two difference:
+
+ If PCSROffset=0b0000. ARMv8-a doesn't apply offset on PCSR, but ARMv7-a
+ defines "PCSR samples are offset by a value that depends on the instruction
+ set state". For ARMv7-a, the driver checks furthermore if CPU runs with ARM
+ or thumb instruction set and calibrate PCSR value, the detailed description
+ for offset is in ARMv7-a ARM (ARM DDI 0406C.b) chapter C11.11.34 "DBGPCSR,
+ Program Counter Sampling Register".
+
+ If PCSROffset=0b0010, ARMv8-a defines "EDPCSR implemented, and samples have
+ no offset applied and do not sample the instruction set state in AArch32
+ state". So for the case when CPU runs with AArch32 state and PCSROffset=
+ 0b0010, the driver considers PCSR doesn't really work.
+
+
+Clock and power domain
+----------------------
+
+Before accessing debug registers, we should ensure the clock and power domain
+have been enabled properly. In ARMv8-a ARM (ARM DDI 0487A.k) chapter 'H9.1
+Debug registers', the debug registers are spread into two domains: the debug
+domain and the CPU domain.
+
+ +---------------+
+ | |
+ | |
+ +----------+--+ |
+ dbg_clk -->| |**| |<-- cpu_clk
+ | Debug |**| CPU |
+ dbg_pd -->| |**| |<-- cpu_pd
+ +----------+--+ |
+ | |
+ | |
+ +---------------+
+
+For debug domain, the user uses DT binding "clocks" and "power-domains" to
+specify the corresponding clock source and power supply for the debug logic.
+The driver calls the pm_runtime_{put|get} operations as needed to handle the
+debug power domain.
+
+For CPU domain, the different SoC designs have different power management
+schemes and finally this heavily impacts external debug module. So we can
+divide into below cases:
+
+- On systems with a sane power controller which can behave correctly with
+ respect to CPU power domain, the CPU power domain can be controlled by
+ register EDPRCR in driver. The driver firstly writes bit EDPRCR.COREPURQ
+ to power up the CPU, and then writes bit EDPRCR.CORENPDRQ for emulation
+ of CPU power down. As result, this can ensure the CPU power domain is
+ powered on properly during the period when access debug related registers;
+
+- Some designs will power down an entire cluster if all CPUs on the cluster
+ are powered down - including the parts of the debug registers that should
+ remain powered in the debug power domain. The bits in EDPRCR are not
+ respected in these cases, so these designs do not really support debug over
+ power down in the way that the CoreSight / Debug designers anticipated.
+ This means that even checking EDPRSR has the potential to cause a bus hang
+ if the target register is unpowered.
+
+ In this case, accessing to the debug registers while they are not powered
+ is a recipe for disaster; so we need preventing CPU low power states at boot
+ time or when user enable module at the run time. Please see chapter
+ "How to use the module" for detailed usage info for this.
+
+
+Device Tree Bindings
+--------------------
+
+See Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt for details.
+
+
+How to use the module
+---------------------
+
+If you want to enable debugging functionality at boot time, you can add
+"coresight_cpu_debug.enable=1" to the kernel command line parameter.
+
+The driver also can work as module, so can enable the debugging when insmod
+module:
+# insmod coresight_cpu_debug.ko debug=1
+
+When boot time or insmod module you have not enabled the debugging, the driver
+uses the debugfs file system to provide a knob to dynamically enable or disable
+debugging:
+
+To enable it, write a '1' into /sys/kernel/debug/coresight_cpu_debug/enable:
+# echo 1 > /sys/kernel/debug/coresight_cpu_debug/enable
+
+To disable it, write a '0' into /sys/kernel/debug/coresight_cpu_debug/enable:
+# echo 0 > /sys/kernel/debug/coresight_cpu_debug/enable
+
+As explained in chapter "Clock and power domain", if you are working on one
+platform which has idle states to power off debug logic and the power
+controller cannot work well for the request from EDPRCR, then you should
+firstly constraint CPU idle states before enable CPU debugging feature; so can
+ensure the accessing to debug logic.
+
+If you want to limit idle states at boot time, you can use "nohlt" or
+"cpuidle.off=1" in the kernel command line.
+
+At the runtime you can disable idle states with below methods:
+
+Set latency request to /dev/cpu_dma_latency to disable all CPUs specific idle
+states (if latency = 0uS then disable all idle states):
+# echo "what_ever_latency_you_need_in_uS" > /dev/cpu_dma_latency
+
+Disable specific CPU's specific idle state:
+# echo 1 > /sys/devices/system/cpu/cpu$cpu/cpuidle/state$state/disable
+
+
+Output format
+-------------
+
+Here is an example of the debugging output format:
+
+ARM external debug module:
+CPU[0]:
+ EDPRSR: 0000000b (Power:On DLK:Unlock)
+ EDPCSR: [<ffff00000808eb54>] handle_IPI+0xe4/0x150
+ EDCIDSR: 00000000
+ EDVIDSR: 90000000 (State:Non-secure Mode:EL1/0 Width:64bits VMID:0)
+CPU[1]:
+ EDPRSR: 0000000b (Power:On DLK:Unlock)
+ EDPCSR: [<ffff0000087a64c0>] debug_notifier_call+0x108/0x288
+ EDCIDSR: 00000000
+ EDVIDSR: 90000000 (State:Non-secure Mode:EL1/0 Width:64bits VMID:0)
--
2.7.4
^ permalink raw reply related
* [PATCH v6 1/8] coresight: bindings for CPU debug module
From: Leo Yan @ 2017-04-06 13:30 UTC (permalink / raw)
To: Jonathan Corbet, Rob Herring, Mark Rutland, Wei Xu,
Catalin Marinas, Will Deacon, Andy Gross, David Brown,
Mathieu Poirier, Suzuki K Poulose, Stephen Boyd, linux-doc,
linux-kernel, devicetree, linux-arm-kernel, linux-arm-msm,
linux-soc, Mike Leach, Sudeep Holla
Cc: Leo Yan
In-Reply-To: <1491485461-22800-1-git-send-email-leo.yan@linaro.org>
According to ARMv8 architecture reference manual (ARM DDI 0487A.k)
Chapter 'Part H: External debug', the CPU can integrate debug module
and it can support self-hosted debug and external debug. Especially
for supporting self-hosted debug, this means the program can access
the debug module from mmio region; and usually the mmio region is
integrated with coresight.
So add document for binding debug component, includes binding to APB
clock; and also need specify the CPU node which the debug module is
dedicated to specific CPU.
Suggested-by: Mike Leach <mike.leach@linaro.org>
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
.../bindings/arm/coresight-cpu-debug.txt | 49 ++++++++++++++++++++++
1 file changed, 49 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt
diff --git a/Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt b/Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt
new file mode 100644
index 0000000..2982912
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt
@@ -0,0 +1,49 @@
+* CoreSight CPU Debug Component:
+
+CoreSight CPU debug component are compliant with the ARMv8 architecture
+reference manual (ARM DDI 0487A.k) Chapter 'Part H: External debug'. The
+external debug module is mainly used for two modes: self-hosted debug and
+external debug, and it can be accessed from mmio region from Coresight
+and eventually the debug module connects with CPU for debugging. And the
+debug module provides sample-based profiling extension, which can be used
+to sample CPU program counter, secure state and exception level, etc;
+usually every CPU has one dedicated debug module to be connected.
+
+Required properties:
+
+- compatible : should be "arm,coresight-cpu-debug"; supplemented with
+ "arm,primecell" since this driver is using the AMBA bus
+ interface.
+
+- reg : physical base address and length of the register set.
+
+- clocks : the clock associated to this component.
+
+- clock-names : the name of the clock referenced by the code. Since we are
+ using the AMBA framework, the name of the clock providing
+ the interconnect should be "apb_pclk" and the clock is
+ mandatory. The interface between the debug logic and the
+ processor core is clocked by the internal CPU clock, so it
+ is enabled with CPU clock by default.
+
+- cpu : the CPU phandle the debug module is affined to. When omitted
+ the module is considered to belong to CPU0.
+
+Optional properties:
+
+- power-domains: a phandle to the debug power domain. We use "power-domains"
+ binding to turn on the debug logic if it has own dedicated
+ power domain and if necessary to use "cpuidle.off=1" or
+ "nohlt" in the kernel command line or sysfs node to
+ constrain idle states to ensure registers in the CPU power
+ domain are accessible.
+
+Example:
+
+ debug@f6590000 {
+ compatible = "arm,coresight-cpu-debug","arm,primecell";
+ reg = <0 0xf6590000 0 0x1000>;
+ clocks = <&sys_ctrl HI6220_DAPB_CLK>;
+ clock-names = "apb_pclk";
+ cpu = <&cpu0>;
+ };
--
2.7.4
^ permalink raw reply related
* [PATCH v6 0/8] coresight: enable debug module
From: Leo Yan @ 2017-04-06 13:30 UTC (permalink / raw)
To: Jonathan Corbet, Rob Herring, Mark Rutland, Wei Xu,
Catalin Marinas, Will Deacon, Andy Gross, David Brown,
Mathieu Poirier, Suzuki K Poulose, Stephen Boyd,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
linux-soc-u79uwXL29TY76Z2rM5mHXA, Mike Leach, Sudeep Holla
Cc: Leo Yan
ARMv8 architecture reference manual (ARM DDI 0487A.k) Chapter H7 "The
Sample-based Profiling Extension" has description for sampling
registers, we can utilize these registers to check program counter
value with combined CPU exception level, secure state, etc. So this is
helpful for CPU lockup bugs, e.g. if one CPU has run into infinite loop
with IRQ disabled; the 'hang' CPU cannot switch context and handle any
interrupt, so it cannot handle SMP call for stack dump, etc.
This patch series is to enable coresight debug module with sample-based
registers and register call back notifier for PCSR register dumping
when panic happens, so we can see below dumping info for panic; and
this patch series has considered the conditions for access permission
for debug registers self, so this can avoid access debug registers when
CPU power domain is off; the driver also try to figure out the CPU is
in secure or non-secure state.
Patch 0001 is to document the dt binding; patch 0002 is to document
boot parameters used in kernel command line and add one detailed
document to describe the Coresight debug module implementation, the
clock and power domain impaction on the driver, some examples for
usage.
Patch 0003 is used to fix the func of_get_coresight_platform_data()
doesn't properly drop the reference to the CPU node pointer; and
patch 0004 is refactor to add new function of_coresight_get_cpu().
Patch 0005 is to add const quality to structure device_node.
Patch 0006 is the driver for CPU debug module.
Patch 0007 in this series are to enable debug unit on 96boards Hikey,
Patch 0008 is to enable debug on 96boards DB410c. Have verified on both
two boards.
We can enable debugging with two methods, adding parameters into kernel
command line for build-in module:
coresight_cpu_debug.enable=1
Or we can wait the system has booted up to use debugfs nodes to enable
debugging:
# echo 1 > /sys/kernel/debug/coresight_cpu_debug/enable
As result we can get below log after input command:
echo c > /proc/sysrq-trigger:
ARM external debug module:
CPU[0]:
EDPRSR: 0000000b (Power:On DLK:Unlock)
EDPCSR: [<ffff00000808eb54>] handle_IPI+0xe4/0x150
EDCIDSR: 00000000
EDVIDSR: 90000000 (State:Non-secure Mode:EL1/0 Width:64bits VMID:0)
CPU[1]:
EDPRSR: 0000000b (Power:On DLK:Unlock)
EDPCSR: [<ffff0000087a64c0>] debug_notifier_call+0x108/0x288
EDCIDSR: 00000000
EDVIDSR: 90000000 (State:Non-secure Mode:EL1/0 Width:64bits VMID:0)
[...]
Changes from v5:
* According to Suzuki and Mathieu suggestions, refined debug module
driver to drop unused structure members, refactored initialization
code to distinguish hardware implementation features, refactored
flow for forcing CPU powered up, supported pm_runtime operations.
* Added one new doc file: Documentation/trace/coresight-cpu-debug.txt,
which is used to describe detailed info for implementation, clock
and power domain impaction on debug module, and exmaples for common
usage.
* Removed "idle constraints" from debug driver.
Changes from v4:
* This version is mainly credit to ARM colleagues many contribution
ideas for better quality (Thanks a lot Suzuki, Mike and Sudeep!).
* According to Suzuki suggestion, refined debug module driver to avoid
memory leak for drvdata struct, handle PCSAMPLE_MODE=1, use flag
drvdata.pc_has_offset to indicate if PCSR has offset, minor fixes.
* According to Mathieu suggestion, refined dt binding description.
* Changed driver to support module mode;
* According to Mike suggestion and very appreciate the pseudo code,
added support to force CPU powered up with register EDPRCR;
* According to discussions, added command line and debugfs nodes to
support enabling debugging for boot time, or later can dynamically
enable/disable debugging by debugfs.
* According to Rob Herring suggestion, one minor fixes in DT binding.
* According to Stephen Boyd suggestion, add const quality to structure
device_node. And used use of_cpu_device_node_get() to replace
of_get_cpu_node() in patch 0003.
Changes from v3:
* Added Suzuki K Poulose's patch to fix issue for the func
of_get_coresight_platform_data() doesn't properly drop the reference
to the CPU node pointer.
* According to Suzuki suggestion, added code to handl the corner case
for ARMv8 CPU with aarch32 mode.
* According to Suzuki suggestion, changed compatible string to
"arm,coresight-cpu-debug".
* According to Mathieu suggestion, added "power-domains" as optional
properties.
Changes from v2:
* According to Mathieu Poirier suggestion, applied some minor fixes.
* Added two extra patches for enabling debug module on Hikey.
Changes from v1:
* According to Mike Leach suggestion, removed the binding for debug
module clocks which have been directly provided by CPU clocks.
* According to Mathieu Poirier suggestion, added function
of_coresight_get_cpu() and some minor refactors for debug module
driver.
Changes from RFC:
* According to Mike Leach suggestion, added check for EDPRSR to avoid
lockup; added supporting EDVIDSR and EDCIDSR registers.
* According to Mark Rutland and Mathieu Poirier suggestion, rewrote
the documentation for DT binding.
* According to Mark and Mathieu suggestion, refined debug driver.
Leo Yan (7):
coresight: bindings for CPU debug module
doc: Add documentation for Coresight CPU debug
coresight: refactor with function of_coresight_get_cpu
coresight: use const for device_node structures
coresight: add support for CPU debug module
arm64: dts: hi6220: register debug module
arm64: dts: qcom: msm8916: Add debug unit
Suzuki K Poulose (1):
coresight: of_get_coresight_platform_data: Add missing of_node_put
Documentation/admin-guide/kernel-parameters.txt | 7 +
.../bindings/arm/coresight-cpu-debug.txt | 49 ++
Documentation/trace/coresight-cpu-debug.txt | 173 ++++++
arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 64 ++
arch/arm64/boot/dts/qcom/msm8916.dtsi | 32 +
drivers/hwtracing/coresight/Kconfig | 14 +
drivers/hwtracing/coresight/Makefile | 1 +
drivers/hwtracing/coresight/coresight-cpu-debug.c | 667 +++++++++++++++++++++
drivers/hwtracing/coresight/of_coresight.c | 44 +-
include/linux/coresight.h | 6 +-
10 files changed, 1041 insertions(+), 16 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt
create mode 100644 Documentation/trace/coresight-cpu-debug.txt
create mode 100644 drivers/hwtracing/coresight/coresight-cpu-debug.c
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 3/4] pwm: tegra: Add DT binding details to configure pin in suspends/resume
From: Laxman Dewangan @ 2017-04-06 13:19 UTC (permalink / raw)
To: Thierry Reding, Jon Hunter
Cc: robh+dt, mark.rutland, linux-pwm, devicetree, linux-tegra,
linux-kernel, Linus Walleij
In-Reply-To: <20170406130315.GB7784@ulmo.ba.sec>
On Thursday 06 April 2017 06:33 PM, Thierry Reding wrote:
> * PGP Signed by an unknown key
>
> On Thu, Apr 06, 2017 at 09:57:09AM +0100, Jon Hunter wrote:
>> On 05/04/17 15:13, Laxman Dewangan wrote:
>>> +state of the system. The configuration of pin is provided via the pinctrl
>>> +DT node as detailed in the pinctrl DT binding document
>>> + Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
>>> +
>>> +The PWM node will have following optional properties.
>>> +pinctrl-names: Pin state names. Must be "suspend" and "resume".
>> Why not just use the pre-defined names here? There is a pre-defined name
>> for "default", "idle" and "sleep" and then you can use the following
>> APIs and avoid the lookup of the state ...
>>
>> pinctrl_pm_select_default_state()
>> pinctrl_pm_select_idle_state()
>> pinctrl_pm_select_sleep_state()
>>
>> Note for i2c [0][1], I used "default" as the active/on state (which I
>> know is not that descriptive) and then used 'idle' as the suspended
>> state. This way we don't need any custom names.
> Agreed, I think that's how these states are meant to be used.
I did quick grep for the pinctrl_pm_select_* functions in the code tree
and found usage of these APIs in some of the places.
I am taking the reference of i2c-st, i2c-nomadic and
extcon/extcon-usb-gpio.c drivers and from this the interpretation is
default state: When interface active and transfer need to be done in IO
interface.
idle state: Active state of the system but interface is not active, put
in non-active state of the interface.
sleep state: When system entering into suspend and IO interface is going
to be inactive.
So in PWM case, we will need the "default" and "sleep" state.
In suspend(), set the "sleep" state and in resume, set the "default" state.
+ Linus W as I refereed his st/nomadik driver for reference.
^ permalink raw reply
* [PATCH v2 8/8] v4l: Remove V4L2 OF framework in favour of V4L2 fwnode framework
From: Sakari Ailus @ 2017-04-06 13:12 UTC (permalink / raw)
To: linux-media; +Cc: linux-acpi, devicetree, laurent.pinchart
In-Reply-To: <1491484330-12040-1-git-send-email-sakari.ailus@linux.intel.com>
All drivers have been converted from V4L2 OF to V4L2 fwnode. The V4L2 OF
framework is now unused. Remove it.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
drivers/media/v4l2-core/Makefile | 3 -
drivers/media/v4l2-core/v4l2-of.c | 327 --------------------------------------
include/media/v4l2-of.h | 128 ---------------
3 files changed, 458 deletions(-)
delete mode 100644 drivers/media/v4l2-core/v4l2-of.c
delete mode 100644 include/media/v4l2-of.h
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index cf77a63..098ad5f 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -10,9 +10,6 @@ videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
ifeq ($(CONFIG_COMPAT),y)
videodev-objs += v4l2-compat-ioctl32.o
endif
-ifeq ($(CONFIG_OF),y)
- videodev-objs += v4l2-of.o
-endif
obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o
ifeq ($(CONFIG_TRACEPOINTS),y)
videodev-objs += vb2-trace.o v4l2-trace.o
diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c
deleted file mode 100644
index 4f59f44..0000000
--- a/drivers/media/v4l2-core/v4l2-of.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * V4L2 OF binding parsing library
- *
- * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
- * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
- *
- * Copyright (C) 2012 Renesas Electronics Corp.
- * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/types.h>
-
-#include <media/v4l2-of.h>
-
-static int v4l2_of_parse_csi_bus(const struct device_node *node,
- struct v4l2_of_endpoint *endpoint)
-{
- struct v4l2_of_bus_mipi_csi2 *bus = &endpoint->bus.mipi_csi2;
- struct property *prop;
- bool have_clk_lane = false;
- unsigned int flags = 0, lanes_used = 0;
- u32 v;
-
- prop = of_find_property(node, "data-lanes", NULL);
- if (prop) {
- const __be32 *lane = NULL;
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(bus->data_lanes); i++) {
- lane = of_prop_next_u32(prop, lane, &v);
- if (!lane)
- break;
-
- if (lanes_used & BIT(v))
- pr_warn("%s: duplicated lane %u in data-lanes\n",
- node->full_name, v);
- lanes_used |= BIT(v);
-
- bus->data_lanes[i] = v;
- }
- bus->num_data_lanes = i;
- }
-
- prop = of_find_property(node, "lane-polarities", NULL);
- if (prop) {
- const __be32 *polarity = NULL;
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(bus->lane_polarities); i++) {
- polarity = of_prop_next_u32(prop, polarity, &v);
- if (!polarity)
- break;
- bus->lane_polarities[i] = v;
- }
-
- if (i < 1 + bus->num_data_lanes /* clock + data */) {
- pr_warn("%s: too few lane-polarities entries (need %u, got %u)\n",
- node->full_name, 1 + bus->num_data_lanes, i);
- return -EINVAL;
- }
- }
-
- if (!of_property_read_u32(node, "clock-lanes", &v)) {
- if (lanes_used & BIT(v))
- pr_warn("%s: duplicated lane %u in clock-lanes\n",
- node->full_name, v);
- lanes_used |= BIT(v);
-
- bus->clock_lane = v;
- have_clk_lane = true;
- }
-
- if (of_get_property(node, "clock-noncontinuous", &v))
- flags |= V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK;
- else if (have_clk_lane || bus->num_data_lanes > 0)
- flags |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
-
- bus->flags = flags;
- endpoint->bus_type = V4L2_MBUS_CSI2;
-
- return 0;
-}
-
-static void v4l2_of_parse_parallel_bus(const struct device_node *node,
- struct v4l2_of_endpoint *endpoint)
-{
- struct v4l2_of_bus_parallel *bus = &endpoint->bus.parallel;
- unsigned int flags = 0;
- u32 v;
-
- if (!of_property_read_u32(node, "hsync-active", &v))
- flags |= v ? V4L2_MBUS_HSYNC_ACTIVE_HIGH :
- V4L2_MBUS_HSYNC_ACTIVE_LOW;
-
- if (!of_property_read_u32(node, "vsync-active", &v))
- flags |= v ? V4L2_MBUS_VSYNC_ACTIVE_HIGH :
- V4L2_MBUS_VSYNC_ACTIVE_LOW;
-
- if (!of_property_read_u32(node, "field-even-active", &v))
- flags |= v ? V4L2_MBUS_FIELD_EVEN_HIGH :
- V4L2_MBUS_FIELD_EVEN_LOW;
- if (flags)
- endpoint->bus_type = V4L2_MBUS_PARALLEL;
- else
- endpoint->bus_type = V4L2_MBUS_BT656;
-
- if (!of_property_read_u32(node, "pclk-sample", &v))
- flags |= v ? V4L2_MBUS_PCLK_SAMPLE_RISING :
- V4L2_MBUS_PCLK_SAMPLE_FALLING;
-
- if (!of_property_read_u32(node, "data-active", &v))
- flags |= v ? V4L2_MBUS_DATA_ACTIVE_HIGH :
- V4L2_MBUS_DATA_ACTIVE_LOW;
-
- if (of_get_property(node, "slave-mode", &v))
- flags |= V4L2_MBUS_SLAVE;
- else
- flags |= V4L2_MBUS_MASTER;
-
- if (!of_property_read_u32(node, "bus-width", &v))
- bus->bus_width = v;
-
- if (!of_property_read_u32(node, "data-shift", &v))
- bus->data_shift = v;
-
- if (!of_property_read_u32(node, "sync-on-green-active", &v))
- flags |= v ? V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH :
- V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW;
-
- bus->flags = flags;
-
-}
-
-/**
- * v4l2_of_parse_endpoint() - parse all endpoint node properties
- * @node: pointer to endpoint device_node
- * @endpoint: pointer to the V4L2 OF endpoint data structure
- *
- * All properties are optional. If none are found, we don't set any flags.
- * This means the port has a static configuration and no properties have
- * to be specified explicitly.
- * If any properties that identify the bus as parallel are found and
- * slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if we recognise
- * the bus as serial CSI-2 and clock-noncontinuous isn't set, we set the
- * V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag.
- * The caller should hold a reference to @node.
- *
- * NOTE: This function does not parse properties the size of which is
- * variable without a low fixed limit. Please use
- * v4l2_of_alloc_parse_endpoint() in new drivers instead.
- *
- * Return: 0 on success or a negative error code on failure.
- */
-int v4l2_of_parse_endpoint(const struct device_node *node,
- struct v4l2_of_endpoint *endpoint)
-{
- int rval;
-
- of_graph_parse_endpoint(node, &endpoint->base);
- /* Zero fields from bus_type to until the end */
- memset(&endpoint->bus_type, 0, sizeof(*endpoint) -
- offsetof(typeof(*endpoint), bus_type));
-
- rval = v4l2_of_parse_csi_bus(node, endpoint);
- if (rval)
- return rval;
- /*
- * Parse the parallel video bus properties only if none
- * of the MIPI CSI-2 specific properties were found.
- */
- if (endpoint->bus.mipi_csi2.flags == 0)
- v4l2_of_parse_parallel_bus(node, endpoint);
-
- return 0;
-}
-EXPORT_SYMBOL(v4l2_of_parse_endpoint);
-
-/*
- * v4l2_of_free_endpoint() - free the endpoint acquired by
- * v4l2_of_alloc_parse_endpoint()
- * @endpoint - the endpoint the resources of which are to be released
- *
- * It is safe to call this function with NULL argument or on an
- * endpoint the parsing of which failed.
- */
-void v4l2_of_free_endpoint(struct v4l2_of_endpoint *endpoint)
-{
- if (IS_ERR_OR_NULL(endpoint))
- return;
-
- kfree(endpoint->link_frequencies);
- kfree(endpoint);
-}
-EXPORT_SYMBOL(v4l2_of_free_endpoint);
-
-/**
- * v4l2_of_alloc_parse_endpoint() - parse all endpoint node properties
- * @node: pointer to endpoint device_node
- *
- * All properties are optional. If none are found, we don't set any flags.
- * This means the port has a static configuration and no properties have
- * to be specified explicitly.
- * If any properties that identify the bus as parallel are found and
- * slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if we recognise
- * the bus as serial CSI-2 and clock-noncontinuous isn't set, we set the
- * V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag.
- * The caller should hold a reference to @node.
- *
- * v4l2_of_alloc_parse_endpoint() has two important differences to
- * v4l2_of_parse_endpoint():
- *
- * 1. It also parses variable size data and
- *
- * 2. The memory it has allocated to store the variable size data must
- * be freed using v4l2_of_free_endpoint() when no longer needed.
- *
- * Return: Pointer to v4l2_of_endpoint if successful, on error a
- * negative error code.
- */
-struct v4l2_of_endpoint *v4l2_of_alloc_parse_endpoint(
- const struct device_node *node)
-{
- struct v4l2_of_endpoint *endpoint;
- int len;
- int rval;
-
- endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL);
- if (!endpoint)
- return ERR_PTR(-ENOMEM);
-
- rval = v4l2_of_parse_endpoint(node, endpoint);
- if (rval < 0)
- goto out_err;
-
- if (of_get_property(node, "link-frequencies", &len)) {
- endpoint->link_frequencies = kmalloc(len, GFP_KERNEL);
- if (!endpoint->link_frequencies) {
- rval = -ENOMEM;
- goto out_err;
- }
-
- endpoint->nr_of_link_frequencies =
- len / sizeof(*endpoint->link_frequencies);
-
- rval = of_property_read_u64_array(
- node, "link-frequencies", endpoint->link_frequencies,
- endpoint->nr_of_link_frequencies);
- if (rval < 0)
- goto out_err;
- }
-
- return endpoint;
-
-out_err:
- v4l2_of_free_endpoint(endpoint);
- return ERR_PTR(rval);
-}
-EXPORT_SYMBOL(v4l2_of_alloc_parse_endpoint);
-
-/**
- * v4l2_of_parse_link() - parse a link between two endpoints
- * @node: pointer to the endpoint at the local end of the link
- * @link: pointer to the V4L2 OF link data structure
- *
- * Fill the link structure with the local and remote nodes and port numbers.
- * The local_node and remote_node fields are set to point to the local and
- * remote port's parent nodes respectively (the port parent node being the
- * parent node of the port node if that node isn't a 'ports' node, or the
- * grand-parent node of the port node otherwise).
- *
- * A reference is taken to both the local and remote nodes, the caller must use
- * v4l2_of_put_link() to drop the references when done with the link.
- *
- * Return: 0 on success, or -ENOLINK if the remote endpoint can't be found.
- */
-int v4l2_of_parse_link(const struct device_node *node,
- struct v4l2_of_link *link)
-{
- struct device_node *np;
-
- memset(link, 0, sizeof(*link));
-
- np = of_get_parent(node);
- of_property_read_u32(np, "reg", &link->local_port);
- np = of_get_next_parent(np);
- if (of_node_cmp(np->name, "ports") == 0)
- np = of_get_next_parent(np);
- link->local_node = np;
-
- np = of_parse_phandle(node, "remote-endpoint", 0);
- if (!np) {
- of_node_put(link->local_node);
- return -ENOLINK;
- }
-
- np = of_get_parent(np);
- of_property_read_u32(np, "reg", &link->remote_port);
- np = of_get_next_parent(np);
- if (of_node_cmp(np->name, "ports") == 0)
- np = of_get_next_parent(np);
- link->remote_node = np;
-
- return 0;
-}
-EXPORT_SYMBOL(v4l2_of_parse_link);
-
-/**
- * v4l2_of_put_link() - drop references to nodes in a link
- * @link: pointer to the V4L2 OF link data structure
- *
- * Drop references to the local and remote nodes in the link. This function must
- * be called on every link parsed with v4l2_of_parse_link().
- */
-void v4l2_of_put_link(struct v4l2_of_link *link)
-{
- of_node_put(link->local_node);
- of_node_put(link->remote_node);
-}
-EXPORT_SYMBOL(v4l2_of_put_link);
diff --git a/include/media/v4l2-of.h b/include/media/v4l2-of.h
deleted file mode 100644
index 4dc34b2..0000000
--- a/include/media/v4l2-of.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * V4L2 OF binding parsing library
- *
- * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
- * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
- *
- * Copyright (C) 2012 Renesas Electronics Corp.
- * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- */
-#ifndef _V4L2_OF_H
-#define _V4L2_OF_H
-
-#include <linux/list.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/of_graph.h>
-
-#include <media/v4l2-mediabus.h>
-
-struct device_node;
-
-/**
- * struct v4l2_of_bus_mipi_csi2 - MIPI CSI-2 bus data structure
- * @flags: media bus (V4L2_MBUS_*) flags
- * @data_lanes: an array of physical data lane indexes
- * @clock_lane: physical lane index of the clock lane
- * @num_data_lanes: number of data lanes
- * @lane_polarities: polarity of the lanes. The order is the same of
- * the physical lanes.
- */
-struct v4l2_of_bus_mipi_csi2 {
- unsigned int flags;
- unsigned char data_lanes[4];
- unsigned char clock_lane;
- unsigned short num_data_lanes;
- bool lane_polarities[5];
-};
-
-/**
- * struct v4l2_of_bus_parallel - parallel data bus data structure
- * @flags: media bus (V4L2_MBUS_*) flags
- * @bus_width: bus width in bits
- * @data_shift: data shift in bits
- */
-struct v4l2_of_bus_parallel {
- unsigned int flags;
- unsigned char bus_width;
- unsigned char data_shift;
-};
-
-/**
- * struct v4l2_of_endpoint - the endpoint data structure
- * @base: struct of_endpoint containing port, id, and local of_node
- * @bus_type: bus type
- * @bus: bus configuration data structure
- * @link_frequencies: array of supported link frequencies
- * @nr_of_link_frequencies: number of elements in link_frequenccies array
- */
-struct v4l2_of_endpoint {
- struct of_endpoint base;
- /* Fields below this line will be zeroed by v4l2_of_parse_endpoint() */
- enum v4l2_mbus_type bus_type;
- union {
- struct v4l2_of_bus_parallel parallel;
- struct v4l2_of_bus_mipi_csi2 mipi_csi2;
- } bus;
- u64 *link_frequencies;
- unsigned int nr_of_link_frequencies;
-};
-
-/**
- * struct v4l2_of_link - a link between two endpoints
- * @local_node: pointer to device_node of this endpoint
- * @local_port: identifier of the port this endpoint belongs to
- * @remote_node: pointer to device_node of the remote endpoint
- * @remote_port: identifier of the port the remote endpoint belongs to
- */
-struct v4l2_of_link {
- struct device_node *local_node;
- unsigned int local_port;
- struct device_node *remote_node;
- unsigned int remote_port;
-};
-
-#ifdef CONFIG_OF
-int v4l2_of_parse_endpoint(const struct device_node *node,
- struct v4l2_of_endpoint *endpoint);
-struct v4l2_of_endpoint *v4l2_of_alloc_parse_endpoint(
- const struct device_node *node);
-void v4l2_of_free_endpoint(struct v4l2_of_endpoint *endpoint);
-int v4l2_of_parse_link(const struct device_node *node,
- struct v4l2_of_link *link);
-void v4l2_of_put_link(struct v4l2_of_link *link);
-#else /* CONFIG_OF */
-
-static inline int v4l2_of_parse_endpoint(const struct device_node *node,
- struct v4l2_of_endpoint *link)
-{
- return -ENOSYS;
-}
-
-static inline struct v4l2_of_endpoint *v4l2_of_alloc_parse_endpoint(
- const struct device_node *node)
-{
- return NULL;
-}
-
-static inline void v4l2_of_free_endpoint(struct v4l2_of_endpoint *endpoint)
-{
-}
-
-static inline int v4l2_of_parse_link(const struct device_node *node,
- struct v4l2_of_link *link)
-{
- return -ENOSYS;
-}
-
-static inline void v4l2_of_put_link(struct v4l2_of_link *link)
-{
-}
-
-#endif /* CONFIG_OF */
-
-#endif /* _V4L2_OF_H */
--
2.7.4
^ permalink raw reply related
* [PATCH v2 7/8] docs-rst: media: Switch documentation to V4L2 fwnode API
From: Sakari Ailus @ 2017-04-06 13:12 UTC (permalink / raw)
To: linux-media; +Cc: linux-acpi, devicetree, laurent.pinchart
In-Reply-To: <1491484330-12040-1-git-send-email-sakari.ailus@linux.intel.com>
Instead of including the V4L2 OF header in ReST documentation, use the
V4L2 fwnode header instead.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
Documentation/media/kapi/v4l2-core.rst | 2 +-
Documentation/media/kapi/v4l2-fwnode.rst | 3 +++
Documentation/media/kapi/v4l2-of.rst | 3 ---
3 files changed, 4 insertions(+), 4 deletions(-)
create mode 100644 Documentation/media/kapi/v4l2-fwnode.rst
delete mode 100644 Documentation/media/kapi/v4l2-of.rst
diff --git a/Documentation/media/kapi/v4l2-core.rst b/Documentation/media/kapi/v4l2-core.rst
index e967715..1bc8a14 100644
--- a/Documentation/media/kapi/v4l2-core.rst
+++ b/Documentation/media/kapi/v4l2-core.rst
@@ -19,7 +19,7 @@ Video2Linux devices
v4l2-mc
v4l2-mediabus
v4l2-mem2mem
- v4l2-of
+ v4l2-fwnode
v4l2-rect
v4l2-tuner
v4l2-common
diff --git a/Documentation/media/kapi/v4l2-fwnode.rst b/Documentation/media/kapi/v4l2-fwnode.rst
new file mode 100644
index 0000000..6c8bccd
--- /dev/null
+++ b/Documentation/media/kapi/v4l2-fwnode.rst
@@ -0,0 +1,3 @@
+V4L2 fwnode kAPI
+^^^^^^^^^^^^^^^^
+.. kernel-doc:: include/media/v4l2-fwnode.h
diff --git a/Documentation/media/kapi/v4l2-of.rst b/Documentation/media/kapi/v4l2-of.rst
deleted file mode 100644
index 1ddf76b..0000000
--- a/Documentation/media/kapi/v4l2-of.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-V4L2 Open Firmware kAPI
-^^^^^^^^^^^^^^^^^^^^^^^
-.. kernel-doc:: include/media/v4l2-of.h
--
2.7.4
^ permalink raw reply related
* [PATCH v2 6/8] v4l: media/drv-intf/soc_mediabus.h: include dependent header file
From: Sakari Ailus @ 2017-04-06 13:12 UTC (permalink / raw)
To: linux-media; +Cc: linux-acpi, devicetree, laurent.pinchart
In-Reply-To: <1491484330-12040-1-git-send-email-sakari.ailus@linux.intel.com>
media/drv-intf/soc_mediabus.h does depend on struct v4l2_mbus_config which
is defined in media/v4l2-mediabus.h. Include it.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
include/media/drv-intf/soc_mediabus.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/media/drv-intf/soc_mediabus.h b/include/media/drv-intf/soc_mediabus.h
index 2ff7737..0449788 100644
--- a/include/media/drv-intf/soc_mediabus.h
+++ b/include/media/drv-intf/soc_mediabus.h
@@ -14,6 +14,8 @@
#include <linux/videodev2.h>
#include <linux/v4l2-mediabus.h>
+#include <media/v4l2-mediabus.h>
+
/**
* enum soc_mbus_packing - data packing types on the media-bus
* @SOC_MBUS_PACKING_NONE: no packing, bit-for-bit transfer to RAM, one
--
2.7.4
^ permalink raw reply related
* [PATCH v2 5/8] v4l: Switch from V4L2 OF not V4L2 fwnode API
From: Sakari Ailus @ 2017-04-06 13:12 UTC (permalink / raw)
To: linux-media-u79uwXL29TY76Z2rM5mHXA
Cc: linux-acpi-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw
In-Reply-To: <1491484330-12040-1-git-send-email-sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Switch users of the v4l2_of_ APIs to the more generic v4l2_fwnode_ APIs.
Existing OF matching continues to be supported. omap3isp and smiapp
drivers are converted to fwnode matching as well.
Signed-off-by: Sakari Ailus <sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Acked-by: Benoit Parrot <bparrot-l0cyMroinI0@public.gmane.org> # i2c/ov2569.c, am437x/am437x-vpfe.c and ti-vpe/cal.c
---
drivers/media/i2c/Kconfig | 9 ++++
drivers/media/i2c/adv7604.c | 7 +--
drivers/media/i2c/mt9v032.c | 7 +--
drivers/media/i2c/ov2659.c | 8 +--
drivers/media/i2c/s5c73m3/s5c73m3-core.c | 7 +--
drivers/media/i2c/s5k5baf.c | 6 +--
drivers/media/i2c/smiapp/Kconfig | 1 +
drivers/media/i2c/smiapp/smiapp-core.c | 29 ++++++-----
drivers/media/i2c/tc358743.c | 11 ++--
drivers/media/i2c/tvp514x.c | 6 +--
drivers/media/i2c/tvp5150.c | 7 +--
drivers/media/i2c/tvp7002.c | 6 +--
drivers/media/platform/Kconfig | 3 ++
drivers/media/platform/am437x/Kconfig | 1 +
drivers/media/platform/am437x/am437x-vpfe.c | 8 +--
drivers/media/platform/atmel/Kconfig | 1 +
drivers/media/platform/atmel/atmel-isc.c | 8 +--
drivers/media/platform/exynos4-is/Kconfig | 2 +
drivers/media/platform/exynos4-is/media-dev.c | 6 +--
drivers/media/platform/exynos4-is/mipi-csis.c | 6 +--
drivers/media/platform/omap3isp/isp.c | 71 +++++++++++++-------------
drivers/media/platform/pxa_camera.c | 7 +--
drivers/media/platform/rcar-vin/Kconfig | 1 +
drivers/media/platform/rcar-vin/rcar-core.c | 6 +--
drivers/media/platform/soc_camera/Kconfig | 1 +
drivers/media/platform/soc_camera/atmel-isi.c | 7 +--
drivers/media/platform/soc_camera/soc_camera.c | 3 +-
drivers/media/platform/ti-vpe/cal.c | 11 ++--
drivers/media/platform/xilinx/Kconfig | 1 +
drivers/media/platform/xilinx/xilinx-vipp.c | 59 +++++++++++----------
include/media/v4l2-fwnode.h | 4 +-
31 files changed, 176 insertions(+), 134 deletions(-)
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index cee1dae..6b2423a 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -210,6 +210,7 @@ config VIDEO_ADV7604
depends on GPIOLIB || COMPILE_TEST
select HDMI
select MEDIA_CEC_EDID
+ select V4L2_FWNODE
---help---
Support for the Analog Devices ADV7604 video decoder.
@@ -324,6 +325,7 @@ config VIDEO_TC358743
tristate "Toshiba TC358743 decoder"
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
select HDMI
+ select V4L2_FWNODE
---help---
Support for the Toshiba TC358743 HDMI to MIPI CSI-2 bridge.
@@ -333,6 +335,7 @@ config VIDEO_TC358743
config VIDEO_TVP514X
tristate "Texas Instruments TVP514x video decoder"
depends on VIDEO_V4L2 && I2C
+ select V4L2_FWNODE
---help---
This is a Video4Linux2 sensor-level driver for the TI TVP5146/47
decoder. It is currently working with the TI OMAP3 camera
@@ -344,6 +347,7 @@ config VIDEO_TVP514X
config VIDEO_TVP5150
tristate "Texas Instruments TVP5150 video decoder"
depends on VIDEO_V4L2 && I2C
+ select V4L2_FWNODE
---help---
Support for the Texas Instruments TVP5150 video decoder.
@@ -353,6 +357,7 @@ config VIDEO_TVP5150
config VIDEO_TVP7002
tristate "Texas Instruments TVP7002 video decoder"
depends on VIDEO_V4L2 && I2C
+ select V4L2_FWNODE
---help---
Support for the Texas Instruments TVP7002 video decoder.
@@ -524,6 +529,7 @@ config VIDEO_OV2659
tristate "OmniVision OV2659 sensor support"
depends on VIDEO_V4L2 && I2C
depends on MEDIA_CAMERA_SUPPORT
+ select V4L2_FWNODE
---help---
This is a Video4Linux2 sensor-level driver for the OmniVision
OV2659 camera.
@@ -616,6 +622,7 @@ config VIDEO_MT9V032
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
depends on MEDIA_CAMERA_SUPPORT
select REGMAP_I2C
+ select V4L2_FWNODE
---help---
This is a Video4Linux2 sensor-level driver for the Micron
MT9V032 752x480 CMOS sensor.
@@ -663,6 +670,7 @@ config VIDEO_S5K4ECGX
config VIDEO_S5K5BAF
tristate "Samsung S5K5BAF sensor support"
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ select V4L2_FWNODE
---help---
This is a V4L2 sensor-level driver for Samsung S5K5BAF 2M
camera sensor with an embedded SoC image signal processor.
@@ -673,6 +681,7 @@ source "drivers/media/i2c/et8ek8/Kconfig"
config VIDEO_S5C73M3
tristate "Samsung S5C73M3 sensor support"
depends on I2C && SPI && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ select V4L2_FWNODE
---help---
This is a V4L2 sensor-level driver for Samsung S5C73M3
8 Mpixel camera.
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index d8bf435..9281e54 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -33,6 +33,7 @@
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/of_graph.h>
#include <linux/slab.h>
#include <linux/v4l2-dv-timings.h>
#include <linux/videodev2.h>
@@ -45,7 +46,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-dv-timings.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
static int debug;
module_param(debug, int, 0644);
@@ -3069,7 +3070,7 @@ MODULE_DEVICE_TABLE(of, adv76xx_of_id);
static int adv76xx_parse_dt(struct adv76xx_state *state)
{
- struct v4l2_of_endpoint bus_cfg;
+ struct v4l2_fwnode_endpoint bus_cfg;
struct device_node *endpoint;
struct device_node *np;
unsigned int flags;
@@ -3083,7 +3084,7 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
if (!endpoint)
return -EINVAL;
- ret = v4l2_of_parse_endpoint(endpoint, &bus_cfg);
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), &bus_cfg);
if (ret) {
of_node_put(endpoint);
return ret;
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 2e7a6e6..8a43064 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -19,6 +19,7 @@
#include <linux/log2.h>
#include <linux/mutex.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
@@ -28,7 +29,7 @@
#include <media/i2c/mt9v032.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
/* The first four rows are black rows. The active area spans 753x481 pixels. */
@@ -979,7 +980,7 @@ static struct mt9v032_platform_data *
mt9v032_get_pdata(struct i2c_client *client)
{
struct mt9v032_platform_data *pdata = NULL;
- struct v4l2_of_endpoint endpoint;
+ struct v4l2_fwnode_endpoint endpoint;
struct device_node *np;
struct property *prop;
@@ -990,7 +991,7 @@ mt9v032_get_pdata(struct i2c_client *client)
if (!np)
return NULL;
- if (v4l2_of_parse_endpoint(np, &endpoint) < 0)
+ if (v4l2_fwnode_endpoint_parse(of_fwnode_handle(np), &endpoint) < 0)
goto done;
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
index 6e63672..545ca3f 100644
--- a/drivers/media/i2c/ov2659.c
+++ b/drivers/media/i2c/ov2659.c
@@ -42,9 +42,9 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-image-sizes.h>
#include <media/v4l2-mediabus.h>
-#include <media/v4l2-of.h>
#include <media/v4l2-subdev.h>
#define DRIVER_NAME "ov2659"
@@ -1346,7 +1346,7 @@ static struct ov2659_platform_data *
ov2659_get_pdata(struct i2c_client *client)
{
struct ov2659_platform_data *pdata;
- struct v4l2_of_endpoint *bus_cfg;
+ struct v4l2_fwnode_endpoint *bus_cfg;
struct device_node *endpoint;
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
@@ -1356,7 +1356,7 @@ ov2659_get_pdata(struct i2c_client *client)
if (!endpoint)
return NULL;
- bus_cfg = v4l2_of_alloc_parse_endpoint(endpoint);
+ bus_cfg = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(endpoint));
if (IS_ERR(bus_cfg)) {
pdata = NULL;
goto done;
@@ -1376,7 +1376,7 @@ ov2659_get_pdata(struct i2c_client *client)
pdata->link_frequency = bus_cfg->link_frequencies[0];
done:
- v4l2_of_free_endpoint(bus_cfg);
+ v4l2_fwnode_endpoint_free(bus_cfg);
of_node_put(endpoint);
return pdata;
}
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 3844853..f434fb2 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -24,6 +24,7 @@
#include <linux/media.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
+#include <linux/of_graph.h>
#include <linux/regulator/consumer.h>
#include <linux/sizes.h>
#include <linux/slab.h>
@@ -35,7 +36,7 @@
#include <media/v4l2-subdev.h>
#include <media/v4l2-mediabus.h>
#include <media/i2c/s5c73m3.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include "s5c73m3.h"
@@ -1602,7 +1603,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state)
const struct s5c73m3_platform_data *pdata = dev->platform_data;
struct device_node *node = dev->of_node;
struct device_node *node_ep;
- struct v4l2_of_endpoint ep;
+ struct v4l2_fwnode_endpoint ep;
int ret;
if (!node) {
@@ -1639,7 +1640,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state)
return 0;
}
- ret = v4l2_of_parse_endpoint(node_ep, &ep);
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node_ep), &ep);
of_node_put(node_ep);
if (ret)
return ret;
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index db82ed0..962051b 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -30,7 +30,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-mediabus.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
static int debug;
module_param(debug, int, 0644);
@@ -1841,7 +1841,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
{
struct device_node *node = dev->of_node;
struct device_node *node_ep;
- struct v4l2_of_endpoint ep;
+ struct v4l2_fwnode_endpoint ep;
int ret;
if (!node) {
@@ -1868,7 +1868,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
return -EINVAL;
}
- ret = v4l2_of_parse_endpoint(node_ep, &ep);
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node_ep), &ep);
of_node_put(node_ep);
if (ret)
return ret;
diff --git a/drivers/media/i2c/smiapp/Kconfig b/drivers/media/i2c/smiapp/Kconfig
index 3149cda..f59718d 100644
--- a/drivers/media/i2c/smiapp/Kconfig
+++ b/drivers/media/i2c/smiapp/Kconfig
@@ -3,5 +3,6 @@ config VIDEO_SMIAPP
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAVE_CLK
depends on MEDIA_CAMERA_SUPPORT
select VIDEO_SMIAPP_PLL
+ select V4L2_FWNODE
---help---
This is a generic driver for SMIA++/SMIA camera modules.
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index f4e92bd..4e28220 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -27,12 +27,13 @@
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
+#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/smiapp.h>
#include <linux/v4l2-mediabus.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-of.h>
#include "smiapp.h"
@@ -2784,19 +2785,20 @@ static int __maybe_unused smiapp_resume(struct device *dev)
static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev)
{
struct smiapp_hwconfig *hwcfg;
- struct v4l2_of_endpoint *bus_cfg;
- struct device_node *ep;
+ struct v4l2_fwnode_endpoint *bus_cfg;
+ struct fwnode_handle *ep;
+ struct fwnode_handle *fwn = dev_fwnode(dev);
int i;
int rval;
- if (!dev->of_node)
+ if (!fwn)
return dev->platform_data;
- ep = of_graph_get_next_endpoint(dev->of_node, NULL);
+ ep = fwnode_graph_get_next_endpoint(fwn, NULL);
if (!ep)
return NULL;
- bus_cfg = v4l2_of_alloc_parse_endpoint(ep);
+ bus_cfg = v4l2_fwnode_endpoint_alloc_parse(ep);
if (IS_ERR(bus_cfg))
goto out_err;
@@ -2817,11 +2819,10 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev)
dev_dbg(dev, "lanes %u\n", hwcfg->lanes);
/* NVM size is not mandatory */
- of_property_read_u32(dev->of_node, "nokia,nvm-size",
- &hwcfg->nvm_size);
+ fwnode_property_read_u32(fwn, "nokia,nvm-size", &hwcfg->nvm_size);
- rval = of_property_read_u32(dev->of_node, "clock-frequency",
- &hwcfg->ext_clk);
+ rval = fwnode_property_read_u32(fwn, "clock-frequency",
+ &hwcfg->ext_clk);
if (rval) {
dev_warn(dev, "can't get clock-frequency\n");
goto out_err;
@@ -2846,13 +2847,13 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev)
dev_dbg(dev, "freq %d: %lld\n", i, hwcfg->op_sys_clock[i]);
}
- v4l2_of_free_endpoint(bus_cfg);
- of_node_put(ep);
+ v4l2_fwnode_endpoint_free(bus_cfg);
+ fwnode_handle_put(ep);
return hwcfg;
out_err:
- v4l2_of_free_endpoint(bus_cfg);
- of_node_put(ep);
+ v4l2_fwnode_endpoint_free(bus_cfg);
+ fwnode_handle_put(ep);
return NULL;
}
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index bf9d925..c4c894b 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -33,6 +33,7 @@
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
+#include <linux/of_graph.h>
#include <linux/videodev2.h>
#include <linux/workqueue.h>
#include <linux/v4l2-dv-timings.h>
@@ -41,7 +42,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/i2c/tc358743.h>
#include "tc358743_regs.h"
@@ -76,7 +77,7 @@ static const struct v4l2_dv_timings_cap tc358743_timings_cap = {
struct tc358743_state {
struct tc358743_platform_data pdata;
- struct v4l2_of_bus_mipi_csi2 bus;
+ struct v4l2_fwnode_bus_mipi_csi2 bus;
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_ctrl_handler hdl;
@@ -1695,7 +1696,7 @@ static void tc358743_gpio_reset(struct tc358743_state *state)
static int tc358743_probe_of(struct tc358743_state *state)
{
struct device *dev = &state->i2c_client->dev;
- struct v4l2_of_endpoint *endpoint;
+ struct v4l2_fwnode_endpoint *endpoint;
struct device_node *ep;
struct clk *refclk;
u32 bps_pr_lane;
@@ -1715,7 +1716,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
return -EINVAL;
}
- endpoint = v4l2_of_alloc_parse_endpoint(ep);
+ endpoint = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep));
if (IS_ERR(endpoint)) {
dev_err(dev, "failed to parse endpoint\n");
return PTR_ERR(endpoint);
@@ -1803,7 +1804,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
disable_clk:
clk_disable_unprepare(refclk);
free_endpoint:
- v4l2_of_free_endpoint(endpoint);
+ v4l2_fwnode_endpoint_free(endpoint);
return ret;
}
#else
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index 07853d2..ad2df99 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -38,7 +38,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
#include <media/v4l2-mediabus.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-ctrls.h>
#include <media/i2c/tvp514x.h>
#include <media/media-entity.h>
@@ -998,7 +998,7 @@ static struct tvp514x_platform_data *
tvp514x_get_pdata(struct i2c_client *client)
{
struct tvp514x_platform_data *pdata = NULL;
- struct v4l2_of_endpoint bus_cfg;
+ struct v4l2_fwnode_endpoint bus_cfg;
struct device_node *endpoint;
unsigned int flags;
@@ -1009,7 +1009,7 @@ tvp514x_get_pdata(struct i2c_client *client)
if (!endpoint)
return NULL;
- if (v4l2_of_parse_endpoint(endpoint, &bus_cfg))
+ if (v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), &bus_cfg))
goto done;
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 48646a7..dff30a0 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -12,10 +12,11 @@
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
+#include <linux/of_graph.h>
#include <media/v4l2-async.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-mc.h>
#include "tvp5150_reg.h"
@@ -1358,7 +1359,7 @@ static int tvp5150_init(struct i2c_client *c)
static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np)
{
- struct v4l2_of_endpoint bus_cfg;
+ struct v4l2_fwnode_endpoint bus_cfg;
struct device_node *ep;
#ifdef CONFIG_MEDIA_CONTROLLER
struct device_node *connectors, *child;
@@ -1373,7 +1374,7 @@ static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np)
if (!ep)
return -EINVAL;
- ret = v4l2_of_parse_endpoint(ep, &bus_cfg);
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &bus_cfg);
if (ret)
goto err;
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index 4c11901..a26c1a3 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
@@ -33,7 +33,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include "tvp7002_reg.h"
@@ -889,7 +889,7 @@ static const struct v4l2_subdev_ops tvp7002_ops = {
static struct tvp7002_config *
tvp7002_get_pdata(struct i2c_client *client)
{
- struct v4l2_of_endpoint bus_cfg;
+ struct v4l2_fwnode_endpoint bus_cfg;
struct tvp7002_config *pdata = NULL;
struct device_node *endpoint;
unsigned int flags;
@@ -901,7 +901,7 @@ tvp7002_get_pdata(struct i2c_client *client)
if (!endpoint)
return NULL;
- if (v4l2_of_parse_endpoint(endpoint, &bus_cfg))
+ if (v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), &bus_cfg))
goto done;
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index ab0bb48..10862f0 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -82,6 +82,7 @@ config VIDEO_OMAP3
select ARM_DMA_USE_IOMMU
select VIDEOBUF2_DMA_CONTIG
select MFD_SYSCON
+ select V4L2_FWNODE
---help---
Driver for an OMAP 3 camera controller.
@@ -97,6 +98,7 @@ config VIDEO_PXA27x
depends on PXA27x || COMPILE_TEST
select VIDEOBUF2_DMA_SG
select SG_SPLIT
+ select V4L2_FWNODE
---help---
This is a v4l2 driver for the PXA27x Quick Capture Interface
@@ -127,6 +129,7 @@ config VIDEO_TI_CAL
depends on SOC_DRA7XX || COMPILE_TEST
depends on HAS_DMA
select VIDEOBUF2_DMA_CONTIG
+ select V4L2_FWNODE
default n
---help---
Support for the TI CAL (Camera Adaptation Layer) block
diff --git a/drivers/media/platform/am437x/Kconfig b/drivers/media/platform/am437x/Kconfig
index 42d9c18..160e77e 100644
--- a/drivers/media/platform/am437x/Kconfig
+++ b/drivers/media/platform/am437x/Kconfig
@@ -3,6 +3,7 @@ config VIDEO_AM437X_VPFE
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA
depends on SOC_AM43XX || COMPILE_TEST
select VIDEOBUF2_DMA_CONTIG
+ select V4L2_FWNODE
help
Support for AM437x Video Processing Front End based Video
Capture Driver.
diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c
index 05489a4..3eb0bd2 100644
--- a/drivers/media/platform/am437x/am437x-vpfe.c
+++ b/drivers/media/platform/am437x/am437x-vpfe.c
@@ -26,6 +26,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/of_graph.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -36,7 +37,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include "am437x-vpfe.h"
@@ -2419,7 +2420,7 @@ static struct vpfe_config *
vpfe_get_pdata(struct platform_device *pdev)
{
struct device_node *endpoint = NULL;
- struct v4l2_of_endpoint bus_cfg;
+ struct v4l2_fwnode_endpoint bus_cfg;
struct vpfe_subdev_info *sdinfo;
struct vpfe_config *pdata;
unsigned int flags;
@@ -2463,7 +2464,8 @@ vpfe_get_pdata(struct platform_device *pdev)
sdinfo->vpfe_param.if_type = VPFE_RAW_BAYER;
}
- err = v4l2_of_parse_endpoint(endpoint, &bus_cfg);
+ err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
+ &bus_cfg);
if (err) {
dev_err(&pdev->dev, "Could not parse the endpoint\n");
goto done;
diff --git a/drivers/media/platform/atmel/Kconfig b/drivers/media/platform/atmel/Kconfig
index 867dca2..3dbc89c 100644
--- a/drivers/media/platform/atmel/Kconfig
+++ b/drivers/media/platform/atmel/Kconfig
@@ -4,6 +4,7 @@ config VIDEO_ATMEL_ISC
depends on ARCH_AT91 || COMPILE_TEST
select VIDEOBUF2_DMA_CONTIG
select REGMAP_MMIO
+ select V4L2_FWNODE
help
This module makes the ATMEL Image Sensor Controller available
as a v4l2 device.
\ No newline at end of file
diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c
index b380a7d..8e78da2 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -32,6 +32,7 @@
#include <linux/math64.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
@@ -42,7 +43,7 @@
#include <media/v4l2-event.h>
#include <media/v4l2-image-sizes.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
#include <media/videobuf2-dma-contig.h>
@@ -1683,7 +1684,7 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
{
struct device_node *np = dev->of_node;
struct device_node *epn = NULL, *rem;
- struct v4l2_of_endpoint v4l2_epn;
+ struct v4l2_fwnode_endpoint v4l2_epn;
struct isc_subdev_entity *subdev_entity;
unsigned int flags;
int ret;
@@ -1702,7 +1703,8 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
continue;
}
- ret = v4l2_of_parse_endpoint(epn, &v4l2_epn);
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(epn),
+ &v4l2_epn);
if (ret) {
of_node_put(rem);
ret = -EINVAL;
diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig
index 57d42c6..c480efb 100644
--- a/drivers/media/platform/exynos4-is/Kconfig
+++ b/drivers/media/platform/exynos4-is/Kconfig
@@ -4,6 +4,7 @@ config VIDEO_SAMSUNG_EXYNOS4_IS
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
depends on OF && COMMON_CLK
+ select V4L2_FWNODE
help
Say Y here to enable camera host interface devices for
Samsung S5P and EXYNOS SoC series.
@@ -32,6 +33,7 @@ config VIDEO_S5P_MIPI_CSIS
tristate "S5P/EXYNOS MIPI-CSI2 receiver (MIPI-CSIS) driver"
depends on REGULATOR
select GENERIC_PHY
+ select V4L2_FWNODE
help
This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC MIPI-CSI2
receiver (MIPI-CSIS) devices.
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index e82450e9..4a1808c 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -29,7 +29,7 @@
#include <linux/slab.h>
#include <media/v4l2-async.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/media-device.h>
#include <media/drv-intf/exynos-fimc.h>
@@ -388,7 +388,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
{
struct fimc_source_info *pd = &fmd->sensor[index].pdata;
struct device_node *rem, *ep, *np;
- struct v4l2_of_endpoint endpoint;
+ struct v4l2_fwnode_endpoint endpoint;
int ret;
/* Assume here a port node can have only one endpoint node. */
@@ -396,7 +396,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
if (!ep)
return 0;
- ret = v4l2_of_parse_endpoint(ep, &endpoint);
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &endpoint);
if (ret) {
of_node_put(ep);
return ret;
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index f819b29..98c8987 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -30,7 +30,7 @@
#include <linux/spinlock.h>
#include <linux/videodev2.h>
#include <media/drv-intf/exynos-fimc.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
#include "mipi-csis.h"
@@ -718,7 +718,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
struct csis_state *state)
{
struct device_node *node = pdev->dev.of_node;
- struct v4l2_of_endpoint endpoint;
+ struct v4l2_fwnode_endpoint endpoint;
int ret;
if (of_property_read_u32(node, "clock-frequency",
@@ -735,7 +735,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
return -EINVAL;
}
/* Get port node and validate MIPI-CSI channel id. */
- ret = v4l2_of_parse_endpoint(node, &endpoint);
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &endpoint);
if (ret)
goto err;
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 084ecf4a..95850b9 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -55,6 +55,7 @@
#include <linux/module.h>
#include <linux/omap-iommu.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/sched.h>
@@ -63,9 +64,9 @@
#include <asm/dma-iommu.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mc.h>
-#include <media/v4l2-of.h>
#include "isp.h"
#include "ispreg.h"
@@ -2024,43 +2025,42 @@ enum isp_of_phy {
ISP_OF_PHY_CSIPHY2,
};
-static int isp_of_parse_node(struct device *dev, struct device_node *node,
- struct isp_async_subdev *isd)
+static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwn,
+ struct isp_async_subdev *isd)
{
struct isp_bus_cfg *buscfg = &isd->bus;
- struct v4l2_of_endpoint vep;
+ struct v4l2_fwnode_endpoint vfwn;
unsigned int i;
int ret;
- ret = v4l2_of_parse_endpoint(node, &vep);
+ ret = v4l2_fwnode_endpoint_parse(fwn, &vfwn);
if (ret)
return ret;
- dev_dbg(dev, "parsing endpoint %s, interface %u\n", node->full_name,
- vep.base.port);
+ dev_dbg(dev, "interface %u\n", vfwn.base.port);
- switch (vep.base.port) {
+ switch (vfwn.base.port) {
case ISP_OF_PHY_PARALLEL:
buscfg->interface = ISP_INTERFACE_PARALLEL;
buscfg->bus.parallel.data_lane_shift =
- vep.bus.parallel.data_shift;
+ vfwn.bus.parallel.data_shift;
buscfg->bus.parallel.clk_pol =
- !!(vep.bus.parallel.flags
+ !!(vfwn.bus.parallel.flags
& V4L2_MBUS_PCLK_SAMPLE_FALLING);
buscfg->bus.parallel.hs_pol =
- !!(vep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW);
+ !!(vfwn.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW);
buscfg->bus.parallel.vs_pol =
- !!(vep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW);
+ !!(vfwn.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW);
buscfg->bus.parallel.fld_pol =
- !!(vep.bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW);
+ !!(vfwn.bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW);
buscfg->bus.parallel.data_pol =
- !!(vep.bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW);
+ !!(vfwn.bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW);
break;
case ISP_OF_PHY_CSIPHY1:
case ISP_OF_PHY_CSIPHY2:
/* FIXME: always assume CSI-2 for now. */
- switch (vep.base.port) {
+ switch (vfwn.base.port) {
case ISP_OF_PHY_CSIPHY1:
buscfg->interface = ISP_INTERFACE_CSI2C_PHY1;
break;
@@ -2068,18 +2068,18 @@ static int isp_of_parse_node(struct device *dev, struct device_node *node,
buscfg->interface = ISP_INTERFACE_CSI2A_PHY2;
break;
}
- buscfg->bus.csi2.lanecfg.clk.pos = vep.bus.mipi_csi2.clock_lane;
+ buscfg->bus.csi2.lanecfg.clk.pos = vfwn.bus.mipi_csi2.clock_lane;
buscfg->bus.csi2.lanecfg.clk.pol =
- vep.bus.mipi_csi2.lane_polarities[0];
+ vfwn.bus.mipi_csi2.lane_polarities[0];
dev_dbg(dev, "clock lane polarity %u, pos %u\n",
buscfg->bus.csi2.lanecfg.clk.pol,
buscfg->bus.csi2.lanecfg.clk.pos);
for (i = 0; i < ISP_CSIPHY2_NUM_DATA_LANES; i++) {
buscfg->bus.csi2.lanecfg.data[i].pos =
- vep.bus.mipi_csi2.data_lanes[i];
+ vfwn.bus.mipi_csi2.data_lanes[i];
buscfg->bus.csi2.lanecfg.data[i].pol =
- vep.bus.mipi_csi2.lane_polarities[i + 1];
+ vfwn.bus.mipi_csi2.lane_polarities[i + 1];
dev_dbg(dev, "data lane %u polarity %u, pos %u\n", i,
buscfg->bus.csi2.lanecfg.data[i].pol,
buscfg->bus.csi2.lanecfg.data[i].pos);
@@ -2094,18 +2094,17 @@ static int isp_of_parse_node(struct device *dev, struct device_node *node,
break;
default:
- dev_warn(dev, "%s: invalid interface %u\n", node->full_name,
- vep.base.port);
+ dev_warn(dev, "invalid interface %u\n", vfwn.base.port);
break;
}
return 0;
}
-static int isp_of_parse_nodes(struct device *dev,
- struct v4l2_async_notifier *notifier)
+static int isp_fwnodes_parse(struct device *dev,
+ struct v4l2_async_notifier *notifier)
{
- struct device_node *node = NULL;
+ struct fwnode_handle *fwn = NULL;
notifier->subdevs = devm_kcalloc(
dev, ISP_MAX_SUBDEVS, sizeof(*notifier->subdevs), GFP_KERNEL);
@@ -2113,7 +2112,8 @@ static int isp_of_parse_nodes(struct device *dev,
return -ENOMEM;
while (notifier->num_subdevs < ISP_MAX_SUBDEVS &&
- (node = of_graph_get_next_endpoint(dev->of_node, node))) {
+ (fwn = fwnode_graph_get_next_endpoint(dev_fwnode(dev),
+ fwn))) {
struct isp_async_subdev *isd;
isd = devm_kzalloc(dev, sizeof(*isd), GFP_KERNEL);
@@ -2122,23 +2122,24 @@ static int isp_of_parse_nodes(struct device *dev,
notifier->subdevs[notifier->num_subdevs] = &isd->asd;
- if (isp_of_parse_node(dev, node, isd))
+ if (isp_fwnode_parse(dev, fwn, isd))
goto error;
- isd->asd.match.of.node = of_graph_get_remote_port_parent(node);
- if (!isd->asd.match.of.node) {
+ isd->asd.match.fwnode.fwn =
+ fwnode_graph_get_remote_port_parent(fwn);
+ if (!isd->asd.match.fwnode.fwn) {
dev_warn(dev, "bad remote port parent\n");
goto error;
}
- isd->asd.match_type = V4L2_ASYNC_MATCH_OF;
+ isd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
notifier->num_subdevs++;
}
return notifier->num_subdevs;
error:
- of_node_put(node);
+ fwnode_handle_put(fwn);
return -EINVAL;
}
@@ -2209,8 +2210,8 @@ static int isp_probe(struct platform_device *pdev)
return -ENOMEM;
}
- ret = of_property_read_u32(pdev->dev.of_node, "ti,phy-type",
- &isp->phy_type);
+ ret = fwnode_property_read_u32(dev_fwnode(&pdev->dev),
+ "ti,phy-type", &isp->phy_type);
if (ret)
return ret;
@@ -2219,12 +2220,12 @@ static int isp_probe(struct platform_device *pdev)
if (IS_ERR(isp->syscon))
return PTR_ERR(isp->syscon);
- ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 1,
- &isp->syscon_offset);
+ ret = of_property_read_u32_index(pdev->dev.of_node,
+ "syscon", 1, &isp->syscon_offset);
if (ret)
return ret;
- ret = isp_of_parse_nodes(&pdev->dev, &isp->notifier);
+ ret = isp_fwnodes_parse(&pdev->dev, &isp->notifier);
if (ret < 0)
return ret;
diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c
index 929006f..1ad4cf9 100644
--- a/drivers/media/platform/pxa_camera.c
+++ b/drivers/media/platform/pxa_camera.c
@@ -25,6 +25,7 @@
#include <linux/mm.h>
#include <linux/moduleparam.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/time.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
@@ -39,7 +40,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/videobuf2-dma-sg.h>
@@ -2236,7 +2237,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
{
u32 mclk_rate;
struct device_node *remote, *np = dev->of_node;
- struct v4l2_of_endpoint ep;
+ struct v4l2_fwnode_endpoint ep;
int err = of_property_read_u32(np, "clock-frequency",
&mclk_rate);
if (!err) {
@@ -2250,7 +2251,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
return -EINVAL;
}
- err = v4l2_of_parse_endpoint(np, &ep);
+ err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(np), &ep);
if (err) {
dev_err(dev, "could not parse endpoint\n");
goto out;
diff --git a/drivers/media/platform/rcar-vin/Kconfig b/drivers/media/platform/rcar-vin/Kconfig
index 111d2a1..af4c98b 100644
--- a/drivers/media/platform/rcar-vin/Kconfig
+++ b/drivers/media/platform/rcar-vin/Kconfig
@@ -3,6 +3,7 @@ config VIDEO_RCAR_VIN
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && MEDIA_CONTROLLER
depends on ARCH_RENESAS || COMPILE_TEST
select VIDEOBUF2_DMA_CONTIG
+ select V4L2_FWNODE
---help---
Support for Renesas R-Car Video Input (VIN) driver.
Supports R-Car Gen2 SoCs.
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 098a0b1..72903fc 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -21,7 +21,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include "rcar-vin.h"
@@ -118,10 +118,10 @@ static int rvin_digitial_parse_v4l2(struct rvin_dev *vin,
struct device_node *ep,
struct v4l2_mbus_config *mbus_cfg)
{
- struct v4l2_of_endpoint v4l2_ep;
+ struct v4l2_fwnode_endpoint v4l2_ep;
int ret;
- ret = v4l2_of_parse_endpoint(ep, &v4l2_ep);
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &v4l2_ep);
if (ret) {
vin_err(vin, "Could not parse v4l2 endpoint\n");
return -EINVAL;
diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
index 2728276..7009e5b 100644
--- a/drivers/media/platform/soc_camera/Kconfig
+++ b/drivers/media/platform/soc_camera/Kconfig
@@ -32,6 +32,7 @@ config VIDEO_ATMEL_ISI
depends on ARCH_AT91 || COMPILE_TEST
depends on HAS_DMA
select VIDEOBUF2_DMA_CONTIG
+ select V4L2_FWNODE
---help---
This module makes the ATMEL Image Sensor Interface available
as a v4l2 device.
diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c
index 46de657..f9f2ad6 100644
--- a/drivers/media/platform/soc_camera/atmel-isi.c
+++ b/drivers/media/platform/soc_camera/atmel-isi.c
@@ -19,13 +19,14 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <media/soc_camera.h>
#include <media/drv-intf/soc_mediabus.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/videobuf2-dma-contig.h>
#include "atmel-isi.h"
@@ -974,7 +975,7 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
struct platform_device *pdev)
{
struct device_node *np= pdev->dev.of_node;
- struct v4l2_of_endpoint ep;
+ struct v4l2_fwnode_endpoint ep;
int err;
/* Default settings for ISI */
@@ -987,7 +988,7 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
return -EINVAL;
}
- err = v4l2_of_parse_endpoint(np, &ep);
+ err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(np), &ep);
of_node_put(np);
if (err) {
dev_err(&pdev->dev, "Could not parse the endpoint\n");
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index 3c9421f..0997d074 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -23,6 +23,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
@@ -36,7 +37,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-dev.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/videobuf2-v4l2.h>
/* Default to VGA resolution */
diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c
index 7a058b6..f72f541 100644
--- a/drivers/media/platform/ti-vpe/cal.c
+++ b/drivers/media/platform/ti-vpe/cal.c
@@ -21,7 +21,7 @@
#include <linux/of_device.h>
#include <linux/of_graph.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-async.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
@@ -270,7 +270,7 @@ struct cal_ctx {
struct video_device vdev;
struct v4l2_async_notifier notifier;
struct v4l2_subdev *sensor;
- struct v4l2_of_endpoint endpoint;
+ struct v4l2_fwnode_endpoint endpoint;
struct v4l2_async_subdev asd;
struct v4l2_async_subdev *asd_list[1];
@@ -608,7 +608,8 @@ static void csi2_lane_config(struct cal_ctx *ctx)
u32 val = reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port));
u32 lane_mask = CAL_CSI2_COMPLEXIO_CFG_CLOCK_POSITION_MASK;
u32 polarity_mask = CAL_CSI2_COMPLEXIO_CFG_CLOCK_POL_MASK;
- struct v4l2_of_bus_mipi_csi2 *mipi_csi2 = &ctx->endpoint.bus.mipi_csi2;
+ struct v4l2_fwnode_bus_mipi_csi2 *mipi_csi2 =
+ &ctx->endpoint.bus.mipi_csi2;
int lane;
set_field(&val, mipi_csi2->clock_lane + 1, lane_mask);
@@ -1643,7 +1644,7 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst)
struct platform_device *pdev = ctx->dev->pdev;
struct device_node *ep_node, *port, *remote_ep,
*sensor_node, *parent;
- struct v4l2_of_endpoint *endpoint;
+ struct v4l2_fwnode_endpoint *endpoint;
struct v4l2_async_subdev *asd;
u32 regval = 0;
int ret, index, found_port = 0, lane;
@@ -1706,7 +1707,7 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst)
ctx_dbg(3, ctx, "can't get remote-endpoint\n");
goto cleanup_exit;
}
- v4l2_of_parse_endpoint(remote_ep, endpoint);
+ v4l2_fwnode_endpoint_parse(of_fwnode_handle(remote_ep), endpoint);
if (endpoint->bus_type != V4L2_MBUS_CSI2) {
ctx_err(ctx, "Port:%d sub-device %s is not a CSI2 device\n",
diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig
index 84bae79..a5d21b7 100644
--- a/drivers/media/platform/xilinx/Kconfig
+++ b/drivers/media/platform/xilinx/Kconfig
@@ -2,6 +2,7 @@ config VIDEO_XILINX
tristate "Xilinx Video IP (EXPERIMENTAL)"
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA
select VIDEOBUF2_DMA_CONTIG
+ select V4L2_FWNODE
---help---
Driver for Xilinx Video IP Pipelines
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index feb3b2f..6a2721b 100644
--- a/drivers/media/platform/xilinx/xilinx-vipp.c
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -22,7 +22,7 @@
#include <media/v4l2-async.h>
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include "xilinx-dma.h"
#include "xilinx-vipp.h"
@@ -74,7 +74,7 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
struct media_pad *local_pad;
struct media_pad *remote_pad;
struct xvip_graph_entity *ent;
- struct v4l2_of_link link;
+ struct v4l2_fwnode_link link;
struct device_node *ep = NULL;
struct device_node *next;
int ret = 0;
@@ -92,7 +92,7 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
dev_dbg(xdev->dev, "processing endpoint %s\n", ep->full_name);
- ret = v4l2_of_parse_link(ep, &link);
+ ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link);
if (ret < 0) {
dev_err(xdev->dev, "failed to parse link for %s\n",
ep->full_name);
@@ -103,9 +103,10 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
* the link.
*/
if (link.local_port >= local->num_pads) {
- dev_err(xdev->dev, "invalid port number %u on %s\n",
- link.local_port, link.local_node->full_name);
- v4l2_of_put_link(&link);
+ dev_err(xdev->dev, "invalid port number %u for %s\n",
+ link.local_port,
+ to_of_node(link.local_node)->full_name);
+ v4l2_fwnode_put_link(&link);
ret = -EINVAL;
break;
}
@@ -114,25 +115,28 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
if (local_pad->flags & MEDIA_PAD_FL_SINK) {
dev_dbg(xdev->dev, "skipping sink port %s:%u\n",
- link.local_node->full_name, link.local_port);
- v4l2_of_put_link(&link);
+ to_of_node(link.local_node)->full_name,
+ link.local_port);
+ v4l2_fwnode_put_link(&link);
continue;
}
/* Skip DMA engines, they will be processed separately. */
- if (link.remote_node == xdev->dev->of_node) {
+ if (link.remote_node == of_fwnode_handle(xdev->dev->of_node)) {
dev_dbg(xdev->dev, "skipping DMA port %s:%u\n",
- link.local_node->full_name, link.local_port);
- v4l2_of_put_link(&link);
+ to_of_node(link.local_node)->full_name,
+ link.local_port);
+ v4l2_fwnode_put_link(&link);
continue;
}
/* Find the remote entity. */
- ent = xvip_graph_find_entity(xdev, link.remote_node);
+ ent = xvip_graph_find_entity(xdev,
+ to_of_node(link.remote_node));
if (ent == NULL) {
dev_err(xdev->dev, "no entity found for %s\n",
- link.remote_node->full_name);
- v4l2_of_put_link(&link);
+ to_of_node(link.remote_node)->full_name);
+ v4l2_fwnode_put_link(&link);
ret = -ENODEV;
break;
}
@@ -141,15 +145,16 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
if (link.remote_port >= remote->num_pads) {
dev_err(xdev->dev, "invalid port number %u on %s\n",
- link.remote_port, link.remote_node->full_name);
- v4l2_of_put_link(&link);
+ link.remote_port,
+ to_of_node(link.remote_node)->full_name);
+ v4l2_fwnode_put_link(&link);
ret = -EINVAL;
break;
}
remote_pad = &remote->pads[link.remote_port];
- v4l2_of_put_link(&link);
+ v4l2_fwnode_put_link(&link);
/* Create the media link. */
dev_dbg(xdev->dev, "creating %s:%u -> %s:%u link\n",
@@ -194,7 +199,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
struct media_pad *source_pad;
struct media_pad *sink_pad;
struct xvip_graph_entity *ent;
- struct v4l2_of_link link;
+ struct v4l2_fwnode_link link;
struct device_node *ep = NULL;
struct device_node *next;
struct xvip_dma *dma;
@@ -213,7 +218,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
dev_dbg(xdev->dev, "processing endpoint %s\n", ep->full_name);
- ret = v4l2_of_parse_link(ep, &link);
+ ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link);
if (ret < 0) {
dev_err(xdev->dev, "failed to parse link for %s\n",
ep->full_name);
@@ -225,7 +230,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
if (dma == NULL) {
dev_err(xdev->dev, "no DMA engine found for port %u\n",
link.local_port);
- v4l2_of_put_link(&link);
+ v4l2_fwnode_put_link(&link);
ret = -EINVAL;
break;
}
@@ -234,19 +239,21 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
dma->video.name);
/* Find the remote entity. */
- ent = xvip_graph_find_entity(xdev, link.remote_node);
+ ent = xvip_graph_find_entity(xdev,
+ to_of_node(link.remote_node));
if (ent == NULL) {
dev_err(xdev->dev, "no entity found for %s\n",
- link.remote_node->full_name);
- v4l2_of_put_link(&link);
+ to_of_node(link.remote_node)->full_name);
+ v4l2_fwnode_put_link(&link);
ret = -ENODEV;
break;
}
if (link.remote_port >= ent->entity->num_pads) {
dev_err(xdev->dev, "invalid port number %u on %s\n",
- link.remote_port, link.remote_node->full_name);
- v4l2_of_put_link(&link);
+ link.remote_port,
+ to_of_node(link.remote_node)->full_name);
+ v4l2_fwnode_put_link(&link);
ret = -EINVAL;
break;
}
@@ -263,7 +270,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
sink_pad = &dma->pad;
}
- v4l2_of_put_link(&link);
+ v4l2_fwnode_put_link(&link);
/* Create the media link. */
dev_dbg(xdev->dev, "creating %s:%u -> %s:%u link\n",
diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
index a675d8a..bc9cf51 100644
--- a/include/media/v4l2-fwnode.h
+++ b/include/media/v4l2-fwnode.h
@@ -17,10 +17,10 @@
#ifndef _V4L2_FWNODE_H
#define _V4L2_FWNODE_H
+#include <linux/errno.h>
+#include <linux/fwnode.h>
#include <linux/list.h>
#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/of_graph.h>
#include <media/v4l2-mediabus.h>
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 4/8] v4l: async: Provide interoperability between OF and fwnode matching
From: Sakari Ailus @ 2017-04-06 13:12 UTC (permalink / raw)
To: linux-media; +Cc: linux-acpi, devicetree, laurent.pinchart
In-Reply-To: <1491484330-12040-1-git-send-email-sakari.ailus@linux.intel.com>
OF and fwnode support are separated in V4L2 and individual drivers may
implement one of them. Sub-devices do not match with a notifier
expecting sub-devices with fwnodes, nor the other way around.
Fix this by checking for sub-device's of_node field in fwnode match and
fwnode field in OF match.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
drivers/media/v4l2-core/v4l2-async.c | 26 +++++++++++++++++++++++---
include/media/v4l2-async.h | 2 +-
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index 384ad5e..7f5d804 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -14,6 +14,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/types.h>
@@ -40,15 +41,34 @@ static bool match_devname(struct v4l2_subdev *sd,
return !strcmp(asd->match.device_name.name, dev_name(sd->dev));
}
+static bool fwnode_cmp(struct fwnode_handle *one,
+ struct fwnode_handle *theother)
+{
+ if (!one || !theother)
+ return false;
+
+ if (one->type != theother->type)
+ return false;
+
+ if (is_of_node(one))
+ return !of_node_cmp(of_node_full_name(to_of_node(one)),
+ of_node_full_name(to_of_node(theother)));
+ else
+ return one == theother;
+}
+
static bool match_of(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
{
- return !of_node_cmp(of_node_full_name(sd->of_node),
- of_node_full_name(asd->match.of.node));
+ return fwnode_cmp(sd->of_node ?
+ of_fwnode_handle(sd->of_node) : sd->fwnode,
+ of_fwnode_handle(asd->match.of.node));
}
static bool match_fwnode(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
{
- return sd->fwnode == asd->match.fwnode.fwn;
+ return fwnode_cmp(sd->of_node ?
+ of_fwnode_handle(sd->of_node) : sd->fwnode,
+ asd->match.fwnode.fwn);
}
static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index 8f552d2..df8b682 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -57,7 +57,7 @@ struct v4l2_async_subdev {
enum v4l2_async_match_type match_type;
union {
struct {
- const struct device_node *node;
+ struct device_node *node;
} of;
struct {
struct fwnode_handle *fwn;
--
2.7.4
^ permalink raw reply related
* [PATCH v2 3/8] v4l: async: Add fwnode match support
From: Sakari Ailus @ 2017-04-06 13:12 UTC (permalink / raw)
To: linux-media-u79uwXL29TY76Z2rM5mHXA
Cc: linux-acpi-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw
In-Reply-To: <1491484330-12040-1-git-send-email-sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Add fwnode matching to complement OF node matching. And fwnode may also be
an OF node.
Signed-off-by: Sakari Ailus <sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
---
drivers/media/v4l2-core/v4l2-async.c | 12 ++++++++++++
include/media/v4l2-async.h | 5 +++++
include/media/v4l2-subdev.h | 3 +++
3 files changed, 20 insertions(+)
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index 96cc733..384ad5e 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -46,6 +46,11 @@ static bool match_of(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
of_node_full_name(asd->match.of.node));
}
+static bool match_fwnode(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
+{
+ return sd->fwnode == asd->match.fwnode.fwn;
+}
+
static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
{
if (!asd->match.custom.match)
@@ -80,6 +85,9 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *
case V4L2_ASYNC_MATCH_OF:
match = match_of;
break;
+ case V4L2_ASYNC_MATCH_FWNODE:
+ match = match_fwnode;
+ break;
default:
/* Cannot happen, unless someone breaks us */
WARN_ON(true);
@@ -158,6 +166,7 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
case V4L2_ASYNC_MATCH_DEVNAME:
case V4L2_ASYNC_MATCH_I2C:
case V4L2_ASYNC_MATCH_OF:
+ case V4L2_ASYNC_MATCH_FWNODE:
break;
default:
dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL,
@@ -282,6 +291,9 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
*/
if (!sd->of_node && sd->dev)
sd->of_node = sd->dev->of_node;
+ if (!sd->fwnode && sd->dev)
+ sd->fwnode = sd->dev->of_node ?
+ &sd->dev->of_node->fwnode : sd->dev->fwnode;
mutex_lock(&list_lock);
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index 8e2a236..8f552d2 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -32,6 +32,7 @@ struct v4l2_async_notifier;
* @V4L2_ASYNC_MATCH_DEVNAME: Match will use the device name
* @V4L2_ASYNC_MATCH_I2C: Match will check for I2C adapter ID and address
* @V4L2_ASYNC_MATCH_OF: Match will use OF node
+ * @V4L2_ASYNC_MATCH_FWNODE: Match will use firmware node
*
* This enum is used by the asyncrhronous sub-device logic to define the
* algorithm that will be used to match an asynchronous device.
@@ -41,6 +42,7 @@ enum v4l2_async_match_type {
V4L2_ASYNC_MATCH_DEVNAME,
V4L2_ASYNC_MATCH_I2C,
V4L2_ASYNC_MATCH_OF,
+ V4L2_ASYNC_MATCH_FWNODE,
};
/**
@@ -58,6 +60,9 @@ struct v4l2_async_subdev {
const struct device_node *node;
} of;
struct {
+ struct fwnode_handle *fwn;
+ } fwnode;
+ struct {
const char *name;
} device_name;
struct {
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 0ab1c5d..5f1669c 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -788,6 +788,8 @@ struct v4l2_subdev_platform_data {
* @devnode: subdev device node
* @dev: pointer to the physical device, if any
* @of_node: The device_node of the subdev, usually the same as dev->of_node.
+ * @fwnode: The fwnode_handle of the subdev, usually the same as
+ * either dev->of_node->fwnode or dev->fwnode (whichever is non-NULL).
* @async_list: Links this subdev to a global subdev_list or @notifier->done
* list.
* @asd: Pointer to respective &struct v4l2_async_subdev.
@@ -819,6 +821,7 @@ struct v4l2_subdev {
struct video_device *devnode;
struct device *dev;
struct device_node *of_node;
+ struct fwnode_handle *fwnode;
struct list_head async_list;
struct v4l2_async_subdev *asd;
struct v4l2_async_notifier *notifier;
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 2/8] v4l: fwnode: Support generic fwnode for parsing standardised properties
From: Sakari Ailus @ 2017-04-06 13:12 UTC (permalink / raw)
To: linux-media-u79uwXL29TY76Z2rM5mHXA
Cc: linux-acpi-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw
In-Reply-To: <1491484330-12040-1-git-send-email-sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
The fwnode_handle is a more generic way than OF device_node to describe
firmware nodes. Instead of the OF API, use more generic fwnode API to
obtain the same information.
As the V4L2 fwnode support will be required by a small minority of e.g.
ACPI based systems (the same might actually go for OF), make this a module
instead of embedding it in the videodev module.
Signed-off-by: Sakari Ailus <sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
---
drivers/media/v4l2-core/Kconfig | 3 +
drivers/media/v4l2-core/Makefile | 1 +
drivers/media/v4l2-core/v4l2-fwnode.c | 353 ++++++++++++++++++++++++++++++++++
include/media/v4l2-fwnode.h | 104 ++++++++++
4 files changed, 461 insertions(+)
create mode 100644 drivers/media/v4l2-core/v4l2-fwnode.c
create mode 100644 include/media/v4l2-fwnode.h
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 6b1b78f..a35c336 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -55,6 +55,9 @@ config V4L2_FLASH_LED_CLASS
When in doubt, say N.
+config V4L2_FWNODE
+ tristate
+
# Used by drivers that need Videobuf modules
config VIDEOBUF_GEN
tristate
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index 795a535..cf77a63 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -13,6 +13,7 @@ endif
ifeq ($(CONFIG_OF),y)
videodev-objs += v4l2-of.o
endif
+obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o
ifeq ($(CONFIG_TRACEPOINTS),y)
videodev-objs += vb2-trace.o v4l2-trace.o
endif
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
new file mode 100644
index 0000000..4f69b11
--- /dev/null
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -0,0 +1,353 @@
+/*
+ * V4L2 fwnode binding parsing library
+ *
+ * Copyright (c) 2016 Intel Corporation.
+ * Author: Sakari Ailus <sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
+ *
+ * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+ *
+ * Copyright (C) 2012 Renesas Electronics Corp.
+ * Author: Guennadi Liakhovetski <g.liakhovetski-Mmb7MZpHnFY@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ */
+#include <linux/acpi.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/property.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <media/v4l2-fwnode.h>
+
+static int v4l2_fwnode_endpoint_parse_csi_bus(struct fwnode_handle *fwn,
+ struct v4l2_fwnode_endpoint *vfwn)
+{
+ struct v4l2_fwnode_bus_mipi_csi2 *bus = &vfwn->bus.mipi_csi2;
+ bool have_clk_lane = false;
+ unsigned int flags = 0, lanes_used = 0;
+ unsigned int i;
+ u32 v;
+ int rval;
+
+ rval = fwnode_property_read_u32_array(fwn, "data-lanes", NULL, 0);
+ if (rval > 0) {
+ u32 array[ARRAY_SIZE(bus->data_lanes)];
+
+ bus->num_data_lanes =
+ min_t(int, ARRAY_SIZE(bus->data_lanes), rval);
+
+ fwnode_property_read_u32_array(
+ fwn, "data-lanes", array, bus->num_data_lanes);
+
+ for (i = 0; i < bus->num_data_lanes; i++) {
+ if (lanes_used & BIT(array[i]))
+ pr_warn("duplicated lane %u in data-lanes\n",
+ array[i]);
+ lanes_used |= BIT(array[i]);
+
+ bus->data_lanes[i] = array[i];
+ }
+ }
+
+ rval = fwnode_property_read_u32_array(fwn, "lane-polarities", NULL, 0);
+ if (rval > 0) {
+ u32 array[ARRAY_SIZE(bus->lane_polarities)];
+
+ if (rval < 1 + bus->num_data_lanes /* clock + data */) {
+ pr_warn("too few lane-polarities entries (need %u, got %u)\n",
+ 1 + bus->num_data_lanes, rval);
+ return -EINVAL;
+ }
+
+ fwnode_property_read_u32_array(
+ fwn, "lane-polarities", array, 1 + bus->num_data_lanes);
+
+ for (i = 0; i < 1 + bus->num_data_lanes; i++)
+ bus->lane_polarities[i] = array[i];
+ }
+
+ if (!fwnode_property_read_u32(fwn, "clock-lanes", &v)) {
+ if (lanes_used & BIT(v))
+ pr_warn("duplicated lane %u in clock-lanes\n", v);
+ lanes_used |= BIT(v);
+
+ bus->clock_lane = v;
+ have_clk_lane = true;
+ }
+
+ if (fwnode_property_present(fwn, "clock-noncontinuous"))
+ flags |= V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK;
+ else if (have_clk_lane || bus->num_data_lanes > 0)
+ flags |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+
+ bus->flags = flags;
+ vfwn->bus_type = V4L2_MBUS_CSI2;
+
+ return 0;
+}
+
+static void v4l2_fwnode_endpoint_parse_parallel_bus(
+ struct fwnode_handle *fwn, struct v4l2_fwnode_endpoint *vfwn)
+{
+ struct v4l2_fwnode_bus_parallel *bus = &vfwn->bus.parallel;
+ unsigned int flags = 0;
+ u32 v;
+
+ if (!fwnode_property_read_u32(fwn, "hsync-active", &v))
+ flags |= v ? V4L2_MBUS_HSYNC_ACTIVE_HIGH :
+ V4L2_MBUS_HSYNC_ACTIVE_LOW;
+
+ if (!fwnode_property_read_u32(fwn, "vsync-active", &v))
+ flags |= v ? V4L2_MBUS_VSYNC_ACTIVE_HIGH :
+ V4L2_MBUS_VSYNC_ACTIVE_LOW;
+
+ if (!fwnode_property_read_u32(fwn, "field-even-active", &v))
+ flags |= v ? V4L2_MBUS_FIELD_EVEN_HIGH :
+ V4L2_MBUS_FIELD_EVEN_LOW;
+ if (flags)
+ vfwn->bus_type = V4L2_MBUS_PARALLEL;
+ else
+ vfwn->bus_type = V4L2_MBUS_BT656;
+
+ if (!fwnode_property_read_u32(fwn, "pclk-sample", &v))
+ flags |= v ? V4L2_MBUS_PCLK_SAMPLE_RISING :
+ V4L2_MBUS_PCLK_SAMPLE_FALLING;
+
+ if (!fwnode_property_read_u32(fwn, "data-active", &v))
+ flags |= v ? V4L2_MBUS_DATA_ACTIVE_HIGH :
+ V4L2_MBUS_DATA_ACTIVE_LOW;
+
+ if (fwnode_property_present(fwn, "slave-mode"))
+ flags |= V4L2_MBUS_SLAVE;
+ else
+ flags |= V4L2_MBUS_MASTER;
+
+ if (!fwnode_property_read_u32(fwn, "bus-width", &v))
+ bus->bus_width = v;
+
+ if (!fwnode_property_read_u32(fwn, "data-shift", &v))
+ bus->data_shift = v;
+
+ if (!fwnode_property_read_u32(fwn, "sync-on-green-active", &v))
+ flags |= v ? V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH :
+ V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW;
+
+ bus->flags = flags;
+
+}
+
+/**
+ * v4l2_fwnode_endpoint_parse() - parse all fwnode node properties
+ * @fwn: pointer to fwnode_handle
+ * @vfwn: pointer to the V4L2 fwnode data structure
+ *
+ * All properties are optional. If none are found, we don't set any flags.
+ * This means the port has a static configuration and no properties have
+ * to be specified explicitly.
+ * If any properties that identify the bus as parallel are found and
+ * slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if we recognise
+ * the bus as serial CSI-2 and clock-noncontinuous isn't set, we set the
+ * V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag.
+ * The caller should hold a reference to @node.
+ *
+ * NOTE: This function does not parse properties the size of which is
+ * variable without a low fixed limit. Please use
+ * v4l2_fwnode_endpoint_alloc_parse() in new drivers instead.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwn,
+ struct v4l2_fwnode_endpoint *vfwn)
+{
+ int rval;
+
+ fwnode_graph_parse_endpoint(fwn, &vfwn->base);
+
+ /* Zero fields from bus_type to until the end */
+ memset(&vfwn->bus_type, 0, sizeof(*vfwn) -
+ offsetof(typeof(*vfwn), bus_type));
+
+ rval = v4l2_fwnode_endpoint_parse_csi_bus(fwn, vfwn);
+ if (rval)
+ return rval;
+ /*
+ * Parse the parallel video bus properties only if none
+ * of the MIPI CSI-2 specific properties were found.
+ */
+ if (vfwn->bus.mipi_csi2.flags == 0)
+ v4l2_fwnode_endpoint_parse_parallel_bus(fwn, vfwn);
+
+ return 0;
+}
+EXPORT_SYMBOL(v4l2_fwnode_endpoint_parse);
+
+/*
+ * v4l2_fwnode_endpoint_free() - free the V4L2 fwnode acquired by
+ * v4l2_fwnode_endpoint_alloc_parse()
+ * @fwn - the V4L2 fwnode the resources of which are to be released
+ *
+ * It is safe to call this function with NULL argument or on an
+ * V4L2 fwnode the parsing of which failed.
+ */
+void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vfwn)
+{
+ if (IS_ERR_OR_NULL(vfwn))
+ return;
+
+ kfree(vfwn->link_frequencies);
+ kfree(vfwn);
+}
+EXPORT_SYMBOL(v4l2_fwnode_endpoint_free);
+
+/**
+ * v4l2_fwnode_endpoint_alloc_parse() - parse all fwnode node properties
+ * @node: pointer to fwnode_handle
+ *
+ * All properties are optional. If none are found, we don't set any flags.
+ * This means the port has a static configuration and no properties have
+ * to be specified explicitly.
+ * If any properties that identify the bus as parallel are found and
+ * slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if we recognise
+ * the bus as serial CSI-2 and clock-noncontinuous isn't set, we set the
+ * V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag.
+ * The caller should hold a reference to @node.
+ *
+ * v4l2_fwnode_endpoint_alloc_parse() has two important differences to
+ * v4l2_fwnode_endpoint_parse():
+ *
+ * 1. It also parses variable size data and
+ *
+ * 2. The memory it has allocated to store the variable size data must
+ * be freed using v4l2_fwnode_endpoint_free() when no longer needed.
+ *
+ * Return: Pointer to v4l2_fwnode_endpoint if successful, on error a
+ * negative error code.
+ */
+struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse(
+ struct fwnode_handle *fwn)
+{
+ struct v4l2_fwnode_endpoint *vfwn;
+ int rval;
+
+ vfwn = kzalloc(sizeof(*vfwn), GFP_KERNEL);
+ if (!vfwn)
+ return ERR_PTR(-ENOMEM);
+
+ rval = v4l2_fwnode_endpoint_parse(fwn, vfwn);
+ if (rval < 0)
+ goto out_err;
+
+ rval = fwnode_property_read_u64_array(fwn, "link-frequencies",
+ NULL, 0);
+
+ if (rval < 0)
+ goto out_err;
+
+ vfwn->link_frequencies =
+ kmalloc_array(rval, sizeof(*vfwn->link_frequencies),
+ GFP_KERNEL);
+ if (!vfwn->link_frequencies) {
+ rval = -ENOMEM;
+ goto out_err;
+ }
+
+ vfwn->nr_of_link_frequencies = rval;
+
+ rval = fwnode_property_read_u64_array(
+ fwn, "link-frequencies", vfwn->link_frequencies,
+ vfwn->nr_of_link_frequencies);
+ if (rval < 0)
+ goto out_err;
+
+ return vfwn;
+
+out_err:
+ v4l2_fwnode_endpoint_free(vfwn);
+ return ERR_PTR(rval);
+}
+EXPORT_SYMBOL(v4l2_fwnode_endpoint_alloc_parse);
+
+/**
+ * v4l2_fwnode_endpoint_parse_link() - parse a link between two endpoints
+ * @node: pointer to the fwnode at the local end of the link
+ * @link: pointer to the V4L2 fwnode link data structure
+ *
+ * Fill the link structure with the local and remote nodes and port numbers.
+ * The local_node and remote_node fields are set to point to the local and
+ * remote port's parent nodes respectively (the port parent node being the
+ * parent node of the port node if that node isn't a 'ports' node, or the
+ * grand-parent node of the port node otherwise).
+ *
+ * A reference is taken to both the local and remote nodes, the caller
+ * must use v4l2_fwnode_endpoint_put_link() to drop the references
+ * when done with the link.
+ *
+ * Return: 0 on success, or -ENOLINK if the remote fwnode can't be found.
+ */
+int v4l2_fwnode_parse_link(struct fwnode_handle *__fwn,
+ struct v4l2_fwnode_link *link)
+{
+ struct fwnode_handle *fwn;
+ const char *port_prop = is_of_node(__fwn) ? "reg" : "port";
+
+ memset(link, 0, sizeof(*link));
+
+ fwn = fwnode_get_parent(__fwn);
+ fwnode_property_read_u32(fwn, port_prop, &link->local_port);
+ fwn = fwnode_get_next_parent(fwn);
+ if (is_of_node(fwn)) {
+ if (of_node_cmp(to_of_node(fwn)->name, "ports") == 0)
+ fwn = fwnode_get_next_parent(fwn);
+ } else {
+ /* The "ports" node is always there in ACPI. */
+ fwn = fwnode_get_next_parent(fwn);
+ }
+ link->local_node = fwn;
+
+ fwn = fwnode_graph_get_remote_endpoint(fwn);
+ if (!fwn) {
+ fwnode_handle_put(fwn);
+ return -ENOLINK;
+ }
+
+ fwn = fwnode_get_parent(fwn);
+ fwnode_property_read_u32(fwn, port_prop, &link->remote_port);
+ fwn = fwnode_get_next_parent(fwn);
+ if (is_of_node(fwn)) {
+ if (of_node_cmp(to_of_node(fwn)->name, "ports") == 0)
+ fwn = fwnode_get_next_parent(fwn);
+ } else {
+ /* The "ports" node is always there in ACPI. */
+ fwn = fwnode_get_next_parent(fwn);
+ }
+ link->remote_node = fwn;
+
+ return 0;
+}
+EXPORT_SYMBOL(v4l2_fwnode_parse_link);
+
+/**
+ * v4l2_fwnode_put_link() - drop references to nodes in a link
+ * @link: pointer to the V4L2 fwnode link data structure
+ *
+ * Drop references to the local and remote nodes in the link. This
+ * function must be called on every link parsed with
+ * v4l2_fwnode_parse_link().
+ */
+void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link)
+{
+ fwnode_handle_put(link->local_node);
+ fwnode_handle_put(link->remote_node);
+}
+EXPORT_SYMBOL(v4l2_fwnode_put_link);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sakari Ailus <sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>");
+MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>");
+MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski-Mmb7MZpHnFY@public.gmane.org>");
diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
new file mode 100644
index 0000000..a675d8a
--- /dev/null
+++ b/include/media/v4l2-fwnode.h
@@ -0,0 +1,104 @@
+/*
+ * V4L2 fwnode binding parsing library
+ *
+ * Copyright (c) 2016 Intel Corporation.
+ * Author: Sakari Ailus <sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
+ *
+ * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+ *
+ * Copyright (C) 2012 Renesas Electronics Corp.
+ * Author: Guennadi Liakhovetski <g.liakhovetski-Mmb7MZpHnFY@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ */
+#ifndef _V4L2_FWNODE_H
+#define _V4L2_FWNODE_H
+
+#include <linux/list.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/of_graph.h>
+
+#include <media/v4l2-mediabus.h>
+
+struct fwnode_handle;
+
+/**
+ * struct v4l2_fwnode_bus_mipi_csi2 - MIPI CSI-2 bus data structure
+ * @flags: media bus (V4L2_MBUS_*) flags
+ * @data_lanes: an array of physical data lane indexes
+ * @clock_lane: physical lane index of the clock lane
+ * @num_data_lanes: number of data lanes
+ * @lane_polarities: polarity of the lanes. The order is the same of
+ * the physical lanes.
+ */
+struct v4l2_fwnode_bus_mipi_csi2 {
+ unsigned int flags;
+ unsigned char data_lanes[4];
+ unsigned char clock_lane;
+ unsigned short num_data_lanes;
+ bool lane_polarities[5];
+};
+
+/**
+ * struct v4l2_fwnode_bus_parallel - parallel data bus data structure
+ * @flags: media bus (V4L2_MBUS_*) flags
+ * @bus_width: bus width in bits
+ * @data_shift: data shift in bits
+ */
+struct v4l2_fwnode_bus_parallel {
+ unsigned int flags;
+ unsigned char bus_width;
+ unsigned char data_shift;
+};
+
+/**
+ * struct v4l2_fwnode_endpoint - the endpoint data structure
+ * @base: fwnode endpoint of the v4l2_fwnode
+ * @bus_type: bus type
+ * @bus: bus configuration data structure
+ * @link_frequencies: array of supported link frequencies
+ * @nr_of_link_frequencies: number of elements in link_frequenccies array
+ */
+struct v4l2_fwnode_endpoint {
+ struct fwnode_endpoint base;
+ /*
+ * Fields below this line will be zeroed by
+ * v4l2_fwnode_parse_endpoint()
+ */
+ enum v4l2_mbus_type bus_type;
+ union {
+ struct v4l2_fwnode_bus_parallel parallel;
+ struct v4l2_fwnode_bus_mipi_csi2 mipi_csi2;
+ } bus;
+ u64 *link_frequencies;
+ unsigned int nr_of_link_frequencies;
+};
+
+/**
+ * struct v4l2_fwnode_link - a link between two endpoints
+ * @local_node: pointer to device_node of this endpoint
+ * @local_port: identifier of the port this endpoint belongs to
+ * @remote_node: pointer to device_node of the remote endpoint
+ * @remote_port: identifier of the port the remote endpoint belongs to
+ */
+struct v4l2_fwnode_link {
+ struct fwnode_handle *local_node;
+ unsigned int local_port;
+ struct fwnode_handle *remote_node;
+ unsigned int remote_port;
+};
+
+int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwn,
+ struct v4l2_fwnode_endpoint *vfwn);
+struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse(
+ struct fwnode_handle *fwn);
+void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vfwn);
+int v4l2_fwnode_parse_link(struct fwnode_handle *fwn,
+ struct v4l2_fwnode_link *link);
+void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link);
+
+#endif /* _V4L2_FWNODE_H */
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 1/8] v4l: flash led class: Use fwnode_handle instead of device_node in init
From: Sakari Ailus @ 2017-04-06 13:12 UTC (permalink / raw)
To: linux-media; +Cc: linux-acpi, devicetree, laurent.pinchart
In-Reply-To: <1491484330-12040-1-git-send-email-sakari.ailus@linux.intel.com>
Pass the more generic fwnode_handle to the init function than the
device_node.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
drivers/leds/leds-aat1290.c | 5 +++--
drivers/leds/leds-max77693.c | 5 +++--
drivers/media/v4l2-core/v4l2-flash-led-class.c | 11 ++++++-----
include/media/v4l2-flash-led-class.h | 4 ++--
4 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/drivers/leds/leds-aat1290.c b/drivers/leds/leds-aat1290.c
index def3cf9..a21e192 100644
--- a/drivers/leds/leds-aat1290.c
+++ b/drivers/leds/leds-aat1290.c
@@ -503,8 +503,9 @@ static int aat1290_led_probe(struct platform_device *pdev)
aat1290_init_v4l2_flash_config(led, &led_cfg, &v4l2_sd_cfg);
/* Create V4L2 Flash subdev. */
- led->v4l2_flash = v4l2_flash_init(dev, sub_node, fled_cdev, NULL,
- &v4l2_flash_ops, &v4l2_sd_cfg);
+ led->v4l2_flash = v4l2_flash_init(dev, of_fwnode_handle(sub_node),
+ fled_cdev, NULL, &v4l2_flash_ops,
+ &v4l2_sd_cfg);
if (IS_ERR(led->v4l2_flash)) {
ret = PTR_ERR(led->v4l2_flash);
goto error_v4l2_flash_init;
diff --git a/drivers/leds/leds-max77693.c b/drivers/leds/leds-max77693.c
index 1eb58ef..2d3062d 100644
--- a/drivers/leds/leds-max77693.c
+++ b/drivers/leds/leds-max77693.c
@@ -930,8 +930,9 @@ static int max77693_register_led(struct max77693_sub_led *sub_led,
max77693_init_v4l2_flash_config(sub_led, led_cfg, &v4l2_sd_cfg);
/* Register in the V4L2 subsystem. */
- sub_led->v4l2_flash = v4l2_flash_init(dev, sub_node, fled_cdev, NULL,
- &v4l2_flash_ops, &v4l2_sd_cfg);
+ sub_led->v4l2_flash = v4l2_flash_init(dev, of_fwnode_handle(sub_node),
+ fled_cdev, NULL, &v4l2_flash_ops,
+ &v4l2_sd_cfg);
if (IS_ERR(sub_led->v4l2_flash)) {
ret = PTR_ERR(sub_led->v4l2_flash);
goto err_v4l2_flash_init;
diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c
index 794e563..f430c89 100644
--- a/drivers/media/v4l2-core/v4l2-flash-led-class.c
+++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
+#include <linux/property.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <media/v4l2-flash-led-class.h>
@@ -612,7 +613,7 @@ static const struct v4l2_subdev_internal_ops v4l2_flash_subdev_internal_ops = {
static const struct v4l2_subdev_ops v4l2_flash_subdev_ops;
struct v4l2_flash *v4l2_flash_init(
- struct device *dev, struct device_node *of_node,
+ struct device *dev, struct fwnode_handle *fwn,
struct led_classdev_flash *fled_cdev,
struct led_classdev_flash *iled_cdev,
const struct v4l2_flash_ops *ops,
@@ -638,7 +639,7 @@ struct v4l2_flash *v4l2_flash_init(
v4l2_flash->iled_cdev = iled_cdev;
v4l2_flash->ops = ops;
sd->dev = dev;
- sd->of_node = of_node ? of_node : led_cdev->dev->of_node;
+ sd->fwnode = fwn ? fwn : dev_fwnode(led_cdev->dev);
v4l2_subdev_init(sd, &v4l2_flash_subdev_ops);
sd->internal_ops = &v4l2_flash_subdev_internal_ops;
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
@@ -654,7 +655,7 @@ struct v4l2_flash *v4l2_flash_init(
if (ret < 0)
goto err_init_controls;
- of_node_get(sd->of_node);
+ fwnode_handle_get(sd->fwnode);
ret = v4l2_async_register_subdev(sd);
if (ret < 0)
@@ -663,7 +664,7 @@ struct v4l2_flash *v4l2_flash_init(
return v4l2_flash;
err_async_register_sd:
- of_node_put(sd->of_node);
+ fwnode_handle_put(sd->fwnode);
v4l2_ctrl_handler_free(sd->ctrl_handler);
err_init_controls:
media_entity_cleanup(&sd->entity);
@@ -683,7 +684,7 @@ void v4l2_flash_release(struct v4l2_flash *v4l2_flash)
v4l2_async_unregister_subdev(sd);
- of_node_put(sd->of_node);
+ fwnode_handle_put(sd->fwnode);
v4l2_ctrl_handler_free(sd->ctrl_handler);
media_entity_cleanup(&sd->entity);
diff --git a/include/media/v4l2-flash-led-class.h b/include/media/v4l2-flash-led-class.h
index b0fe4d6..5695853 100644
--- a/include/media/v4l2-flash-led-class.h
+++ b/include/media/v4l2-flash-led-class.h
@@ -108,7 +108,7 @@ static inline struct v4l2_flash *v4l2_ctrl_to_v4l2_flash(struct v4l2_ctrl *c)
/**
* v4l2_flash_init - initialize V4L2 flash led sub-device
* @dev: flash device, e.g. an I2C device
- * @of_node: of_node of the LED, may be NULL if the same as device's
+ * @fwn: fwnode_handle of the LED, may be NULL if the same as device's
* @fled_cdev: LED flash class device to wrap
* @iled_cdev: LED flash class device representing indicator LED associated
* with fled_cdev, may be NULL
@@ -122,7 +122,7 @@ static inline struct v4l2_flash *v4l2_ctrl_to_v4l2_flash(struct v4l2_ctrl *c)
* PTR_ERR() to obtain the numeric return value.
*/
struct v4l2_flash *v4l2_flash_init(
- struct device *dev, struct device_node *of_node,
+ struct device *dev, struct fwnode_handle *fwn,
struct led_classdev_flash *fled_cdev,
struct led_classdev_flash *iled_cdev,
const struct v4l2_flash_ops *ops,
--
2.7.4
^ permalink raw reply related
* [PATCH v2 0/9] V4L2 fwnode support
From: Sakari Ailus @ 2017-04-06 13:12 UTC (permalink / raw)
To: linux-media-u79uwXL29TY76Z2rM5mHXA
Cc: linux-acpi-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw
(Resending, got one list address wrong. Apologies for the noise...)
Hello everyone,
This patchset adds support for fwnode to V4L2. Besides OF, also ACPI based
systems can be supported this way. By using V4L2 fwnode, the individual
drivers do not need to be aware of the underlying firmware implementation.
The patchset also removes specific V4L2 OF support and converts the
affected drivers to use V4L2 fwnode.
The patchset depends on another patchset here:
<URL:http://www.spinics.net/lists/linux-acpi/msg72973.html>
v1 of the set can be found here:
<URL:http://www.spinics.net/lists/linux-media/msg111073.html>
changes since v1:
- Use existing dev_fwnode() instead of device_fwnode_handle() added by the
ACPI graph patchset,
- Fix too long line of ^'s in ReST documentation and
- Drop the patch rearranging the header files. It'd better go in
separately, if at all.
Sakari Ailus (8):
v4l: flash led class: Use fwnode_handle instead of device_node in init
v4l: fwnode: Support generic fwnode for parsing standardised
properties
v4l: async: Add fwnode match support
v4l: async: Provide interoperability between OF and fwnode matching
v4l: Switch from V4L2 OF not V4L2 fwnode API
v4l: media/drv-intf/soc_mediabus.h: include dependent header file
docs-rst: media: Switch documentation to V4L2 fwnode API
v4l: Remove V4L2 OF framework in favour of V4L2 fwnode framework
Documentation/media/kapi/v4l2-core.rst | 2 +-
Documentation/media/kapi/v4l2-fwnode.rst | 3 +
Documentation/media/kapi/v4l2-of.rst | 3 -
drivers/leds/leds-aat1290.c | 5 +-
drivers/leds/leds-max77693.c | 5 +-
drivers/media/i2c/Kconfig | 9 +
drivers/media/i2c/adv7604.c | 7 +-
drivers/media/i2c/mt9v032.c | 7 +-
drivers/media/i2c/ov2659.c | 8 +-
drivers/media/i2c/s5c73m3/s5c73m3-core.c | 7 +-
drivers/media/i2c/s5k5baf.c | 6 +-
drivers/media/i2c/smiapp/Kconfig | 1 +
drivers/media/i2c/smiapp/smiapp-core.c | 29 +-
drivers/media/i2c/tc358743.c | 11 +-
drivers/media/i2c/tvp514x.c | 6 +-
drivers/media/i2c/tvp5150.c | 7 +-
drivers/media/i2c/tvp7002.c | 6 +-
drivers/media/platform/Kconfig | 3 +
drivers/media/platform/am437x/Kconfig | 1 +
drivers/media/platform/am437x/am437x-vpfe.c | 8 +-
drivers/media/platform/atmel/Kconfig | 1 +
drivers/media/platform/atmel/atmel-isc.c | 8 +-
drivers/media/platform/exynos4-is/Kconfig | 2 +
drivers/media/platform/exynos4-is/media-dev.c | 6 +-
drivers/media/platform/exynos4-is/mipi-csis.c | 6 +-
drivers/media/platform/omap3isp/isp.c | 71 ++---
drivers/media/platform/pxa_camera.c | 7 +-
drivers/media/platform/rcar-vin/Kconfig | 1 +
drivers/media/platform/rcar-vin/rcar-core.c | 6 +-
drivers/media/platform/soc_camera/Kconfig | 1 +
drivers/media/platform/soc_camera/atmel-isi.c | 7 +-
drivers/media/platform/soc_camera/soc_camera.c | 3 +-
drivers/media/platform/ti-vpe/cal.c | 11 +-
drivers/media/platform/xilinx/Kconfig | 1 +
drivers/media/platform/xilinx/xilinx-vipp.c | 59 +++--
drivers/media/v4l2-core/Kconfig | 3 +
drivers/media/v4l2-core/Makefile | 4 +-
drivers/media/v4l2-core/v4l2-async.c | 36 ++-
drivers/media/v4l2-core/v4l2-flash-led-class.c | 11 +-
drivers/media/v4l2-core/v4l2-fwnode.c | 353 +++++++++++++++++++++++++
drivers/media/v4l2-core/v4l2-of.c | 327 -----------------------
include/media/drv-intf/soc_mediabus.h | 2 +
include/media/v4l2-async.h | 7 +-
include/media/v4l2-flash-led-class.h | 4 +-
include/media/v4l2-fwnode.h | 104 ++++++++
include/media/v4l2-of.h | 128 ---------
include/media/v4l2-subdev.h | 3 +
47 files changed, 698 insertions(+), 608 deletions(-)
create mode 100644 Documentation/media/kapi/v4l2-fwnode.rst
delete mode 100644 Documentation/media/kapi/v4l2-of.rst
create mode 100644 drivers/media/v4l2-core/v4l2-fwnode.c
delete mode 100644 drivers/media/v4l2-core/v4l2-of.c
create mode 100644 include/media/v4l2-fwnode.h
delete mode 100644 include/media/v4l2-of.h
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v2 8/8] v4l: Remove V4L2 OF framework in favour of V4L2 fwnode framework
From: Sakari Ailus @ 2017-04-06 13:10 UTC (permalink / raw)
To: linux-media-8fOc0yYH5q9zeIdxy0IIJw
Cc: linux-acpi-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw
In-Reply-To: <1491484249-11964-1-git-send-email-sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
All drivers have been converted from V4L2 OF to V4L2 fwnode. The V4L2 OF
framework is now unused. Remove it.
Signed-off-by: Sakari Ailus <sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
---
drivers/media/v4l2-core/Makefile | 3 -
drivers/media/v4l2-core/v4l2-of.c | 327 --------------------------------------
include/media/v4l2-of.h | 128 ---------------
3 files changed, 458 deletions(-)
delete mode 100644 drivers/media/v4l2-core/v4l2-of.c
delete mode 100644 include/media/v4l2-of.h
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index cf77a63..098ad5f 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -10,9 +10,6 @@ videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
ifeq ($(CONFIG_COMPAT),y)
videodev-objs += v4l2-compat-ioctl32.o
endif
-ifeq ($(CONFIG_OF),y)
- videodev-objs += v4l2-of.o
-endif
obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o
ifeq ($(CONFIG_TRACEPOINTS),y)
videodev-objs += vb2-trace.o v4l2-trace.o
diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c
deleted file mode 100644
index 4f59f44..0000000
--- a/drivers/media/v4l2-core/v4l2-of.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * V4L2 OF binding parsing library
- *
- * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
- * Author: Sylwester Nawrocki <s.nawrocki-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
- *
- * Copyright (C) 2012 Renesas Electronics Corp.
- * Author: Guennadi Liakhovetski <g.liakhovetski-Mmb7MZpHnFY@public.gmane.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/types.h>
-
-#include <media/v4l2-of.h>
-
-static int v4l2_of_parse_csi_bus(const struct device_node *node,
- struct v4l2_of_endpoint *endpoint)
-{
- struct v4l2_of_bus_mipi_csi2 *bus = &endpoint->bus.mipi_csi2;
- struct property *prop;
- bool have_clk_lane = false;
- unsigned int flags = 0, lanes_used = 0;
- u32 v;
-
- prop = of_find_property(node, "data-lanes", NULL);
- if (prop) {
- const __be32 *lane = NULL;
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(bus->data_lanes); i++) {
- lane = of_prop_next_u32(prop, lane, &v);
- if (!lane)
- break;
-
- if (lanes_used & BIT(v))
- pr_warn("%s: duplicated lane %u in data-lanes\n",
- node->full_name, v);
- lanes_used |= BIT(v);
-
- bus->data_lanes[i] = v;
- }
- bus->num_data_lanes = i;
- }
-
- prop = of_find_property(node, "lane-polarities", NULL);
- if (prop) {
- const __be32 *polarity = NULL;
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(bus->lane_polarities); i++) {
- polarity = of_prop_next_u32(prop, polarity, &v);
- if (!polarity)
- break;
- bus->lane_polarities[i] = v;
- }
-
- if (i < 1 + bus->num_data_lanes /* clock + data */) {
- pr_warn("%s: too few lane-polarities entries (need %u, got %u)\n",
- node->full_name, 1 + bus->num_data_lanes, i);
- return -EINVAL;
- }
- }
-
- if (!of_property_read_u32(node, "clock-lanes", &v)) {
- if (lanes_used & BIT(v))
- pr_warn("%s: duplicated lane %u in clock-lanes\n",
- node->full_name, v);
- lanes_used |= BIT(v);
-
- bus->clock_lane = v;
- have_clk_lane = true;
- }
-
- if (of_get_property(node, "clock-noncontinuous", &v))
- flags |= V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK;
- else if (have_clk_lane || bus->num_data_lanes > 0)
- flags |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
-
- bus->flags = flags;
- endpoint->bus_type = V4L2_MBUS_CSI2;
-
- return 0;
-}
-
-static void v4l2_of_parse_parallel_bus(const struct device_node *node,
- struct v4l2_of_endpoint *endpoint)
-{
- struct v4l2_of_bus_parallel *bus = &endpoint->bus.parallel;
- unsigned int flags = 0;
- u32 v;
-
- if (!of_property_read_u32(node, "hsync-active", &v))
- flags |= v ? V4L2_MBUS_HSYNC_ACTIVE_HIGH :
- V4L2_MBUS_HSYNC_ACTIVE_LOW;
-
- if (!of_property_read_u32(node, "vsync-active", &v))
- flags |= v ? V4L2_MBUS_VSYNC_ACTIVE_HIGH :
- V4L2_MBUS_VSYNC_ACTIVE_LOW;
-
- if (!of_property_read_u32(node, "field-even-active", &v))
- flags |= v ? V4L2_MBUS_FIELD_EVEN_HIGH :
- V4L2_MBUS_FIELD_EVEN_LOW;
- if (flags)
- endpoint->bus_type = V4L2_MBUS_PARALLEL;
- else
- endpoint->bus_type = V4L2_MBUS_BT656;
-
- if (!of_property_read_u32(node, "pclk-sample", &v))
- flags |= v ? V4L2_MBUS_PCLK_SAMPLE_RISING :
- V4L2_MBUS_PCLK_SAMPLE_FALLING;
-
- if (!of_property_read_u32(node, "data-active", &v))
- flags |= v ? V4L2_MBUS_DATA_ACTIVE_HIGH :
- V4L2_MBUS_DATA_ACTIVE_LOW;
-
- if (of_get_property(node, "slave-mode", &v))
- flags |= V4L2_MBUS_SLAVE;
- else
- flags |= V4L2_MBUS_MASTER;
-
- if (!of_property_read_u32(node, "bus-width", &v))
- bus->bus_width = v;
-
- if (!of_property_read_u32(node, "data-shift", &v))
- bus->data_shift = v;
-
- if (!of_property_read_u32(node, "sync-on-green-active", &v))
- flags |= v ? V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH :
- V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW;
-
- bus->flags = flags;
-
-}
-
-/**
- * v4l2_of_parse_endpoint() - parse all endpoint node properties
- * @node: pointer to endpoint device_node
- * @endpoint: pointer to the V4L2 OF endpoint data structure
- *
- * All properties are optional. If none are found, we don't set any flags.
- * This means the port has a static configuration and no properties have
- * to be specified explicitly.
- * If any properties that identify the bus as parallel are found and
- * slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if we recognise
- * the bus as serial CSI-2 and clock-noncontinuous isn't set, we set the
- * V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag.
- * The caller should hold a reference to @node.
- *
- * NOTE: This function does not parse properties the size of which is
- * variable without a low fixed limit. Please use
- * v4l2_of_alloc_parse_endpoint() in new drivers instead.
- *
- * Return: 0 on success or a negative error code on failure.
- */
-int v4l2_of_parse_endpoint(const struct device_node *node,
- struct v4l2_of_endpoint *endpoint)
-{
- int rval;
-
- of_graph_parse_endpoint(node, &endpoint->base);
- /* Zero fields from bus_type to until the end */
- memset(&endpoint->bus_type, 0, sizeof(*endpoint) -
- offsetof(typeof(*endpoint), bus_type));
-
- rval = v4l2_of_parse_csi_bus(node, endpoint);
- if (rval)
- return rval;
- /*
- * Parse the parallel video bus properties only if none
- * of the MIPI CSI-2 specific properties were found.
- */
- if (endpoint->bus.mipi_csi2.flags == 0)
- v4l2_of_parse_parallel_bus(node, endpoint);
-
- return 0;
-}
-EXPORT_SYMBOL(v4l2_of_parse_endpoint);
-
-/*
- * v4l2_of_free_endpoint() - free the endpoint acquired by
- * v4l2_of_alloc_parse_endpoint()
- * @endpoint - the endpoint the resources of which are to be released
- *
- * It is safe to call this function with NULL argument or on an
- * endpoint the parsing of which failed.
- */
-void v4l2_of_free_endpoint(struct v4l2_of_endpoint *endpoint)
-{
- if (IS_ERR_OR_NULL(endpoint))
- return;
-
- kfree(endpoint->link_frequencies);
- kfree(endpoint);
-}
-EXPORT_SYMBOL(v4l2_of_free_endpoint);
-
-/**
- * v4l2_of_alloc_parse_endpoint() - parse all endpoint node properties
- * @node: pointer to endpoint device_node
- *
- * All properties are optional. If none are found, we don't set any flags.
- * This means the port has a static configuration and no properties have
- * to be specified explicitly.
- * If any properties that identify the bus as parallel are found and
- * slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if we recognise
- * the bus as serial CSI-2 and clock-noncontinuous isn't set, we set the
- * V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag.
- * The caller should hold a reference to @node.
- *
- * v4l2_of_alloc_parse_endpoint() has two important differences to
- * v4l2_of_parse_endpoint():
- *
- * 1. It also parses variable size data and
- *
- * 2. The memory it has allocated to store the variable size data must
- * be freed using v4l2_of_free_endpoint() when no longer needed.
- *
- * Return: Pointer to v4l2_of_endpoint if successful, on error a
- * negative error code.
- */
-struct v4l2_of_endpoint *v4l2_of_alloc_parse_endpoint(
- const struct device_node *node)
-{
- struct v4l2_of_endpoint *endpoint;
- int len;
- int rval;
-
- endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL);
- if (!endpoint)
- return ERR_PTR(-ENOMEM);
-
- rval = v4l2_of_parse_endpoint(node, endpoint);
- if (rval < 0)
- goto out_err;
-
- if (of_get_property(node, "link-frequencies", &len)) {
- endpoint->link_frequencies = kmalloc(len, GFP_KERNEL);
- if (!endpoint->link_frequencies) {
- rval = -ENOMEM;
- goto out_err;
- }
-
- endpoint->nr_of_link_frequencies =
- len / sizeof(*endpoint->link_frequencies);
-
- rval = of_property_read_u64_array(
- node, "link-frequencies", endpoint->link_frequencies,
- endpoint->nr_of_link_frequencies);
- if (rval < 0)
- goto out_err;
- }
-
- return endpoint;
-
-out_err:
- v4l2_of_free_endpoint(endpoint);
- return ERR_PTR(rval);
-}
-EXPORT_SYMBOL(v4l2_of_alloc_parse_endpoint);
-
-/**
- * v4l2_of_parse_link() - parse a link between two endpoints
- * @node: pointer to the endpoint at the local end of the link
- * @link: pointer to the V4L2 OF link data structure
- *
- * Fill the link structure with the local and remote nodes and port numbers.
- * The local_node and remote_node fields are set to point to the local and
- * remote port's parent nodes respectively (the port parent node being the
- * parent node of the port node if that node isn't a 'ports' node, or the
- * grand-parent node of the port node otherwise).
- *
- * A reference is taken to both the local and remote nodes, the caller must use
- * v4l2_of_put_link() to drop the references when done with the link.
- *
- * Return: 0 on success, or -ENOLINK if the remote endpoint can't be found.
- */
-int v4l2_of_parse_link(const struct device_node *node,
- struct v4l2_of_link *link)
-{
- struct device_node *np;
-
- memset(link, 0, sizeof(*link));
-
- np = of_get_parent(node);
- of_property_read_u32(np, "reg", &link->local_port);
- np = of_get_next_parent(np);
- if (of_node_cmp(np->name, "ports") == 0)
- np = of_get_next_parent(np);
- link->local_node = np;
-
- np = of_parse_phandle(node, "remote-endpoint", 0);
- if (!np) {
- of_node_put(link->local_node);
- return -ENOLINK;
- }
-
- np = of_get_parent(np);
- of_property_read_u32(np, "reg", &link->remote_port);
- np = of_get_next_parent(np);
- if (of_node_cmp(np->name, "ports") == 0)
- np = of_get_next_parent(np);
- link->remote_node = np;
-
- return 0;
-}
-EXPORT_SYMBOL(v4l2_of_parse_link);
-
-/**
- * v4l2_of_put_link() - drop references to nodes in a link
- * @link: pointer to the V4L2 OF link data structure
- *
- * Drop references to the local and remote nodes in the link. This function must
- * be called on every link parsed with v4l2_of_parse_link().
- */
-void v4l2_of_put_link(struct v4l2_of_link *link)
-{
- of_node_put(link->local_node);
- of_node_put(link->remote_node);
-}
-EXPORT_SYMBOL(v4l2_of_put_link);
diff --git a/include/media/v4l2-of.h b/include/media/v4l2-of.h
deleted file mode 100644
index 4dc34b2..0000000
--- a/include/media/v4l2-of.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * V4L2 OF binding parsing library
- *
- * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
- * Author: Sylwester Nawrocki <s.nawrocki-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
- *
- * Copyright (C) 2012 Renesas Electronics Corp.
- * Author: Guennadi Liakhovetski <g.liakhovetski-Mmb7MZpHnFY@public.gmane.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- */
-#ifndef _V4L2_OF_H
-#define _V4L2_OF_H
-
-#include <linux/list.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/of_graph.h>
-
-#include <media/v4l2-mediabus.h>
-
-struct device_node;
-
-/**
- * struct v4l2_of_bus_mipi_csi2 - MIPI CSI-2 bus data structure
- * @flags: media bus (V4L2_MBUS_*) flags
- * @data_lanes: an array of physical data lane indexes
- * @clock_lane: physical lane index of the clock lane
- * @num_data_lanes: number of data lanes
- * @lane_polarities: polarity of the lanes. The order is the same of
- * the physical lanes.
- */
-struct v4l2_of_bus_mipi_csi2 {
- unsigned int flags;
- unsigned char data_lanes[4];
- unsigned char clock_lane;
- unsigned short num_data_lanes;
- bool lane_polarities[5];
-};
-
-/**
- * struct v4l2_of_bus_parallel - parallel data bus data structure
- * @flags: media bus (V4L2_MBUS_*) flags
- * @bus_width: bus width in bits
- * @data_shift: data shift in bits
- */
-struct v4l2_of_bus_parallel {
- unsigned int flags;
- unsigned char bus_width;
- unsigned char data_shift;
-};
-
-/**
- * struct v4l2_of_endpoint - the endpoint data structure
- * @base: struct of_endpoint containing port, id, and local of_node
- * @bus_type: bus type
- * @bus: bus configuration data structure
- * @link_frequencies: array of supported link frequencies
- * @nr_of_link_frequencies: number of elements in link_frequenccies array
- */
-struct v4l2_of_endpoint {
- struct of_endpoint base;
- /* Fields below this line will be zeroed by v4l2_of_parse_endpoint() */
- enum v4l2_mbus_type bus_type;
- union {
- struct v4l2_of_bus_parallel parallel;
- struct v4l2_of_bus_mipi_csi2 mipi_csi2;
- } bus;
- u64 *link_frequencies;
- unsigned int nr_of_link_frequencies;
-};
-
-/**
- * struct v4l2_of_link - a link between two endpoints
- * @local_node: pointer to device_node of this endpoint
- * @local_port: identifier of the port this endpoint belongs to
- * @remote_node: pointer to device_node of the remote endpoint
- * @remote_port: identifier of the port the remote endpoint belongs to
- */
-struct v4l2_of_link {
- struct device_node *local_node;
- unsigned int local_port;
- struct device_node *remote_node;
- unsigned int remote_port;
-};
-
-#ifdef CONFIG_OF
-int v4l2_of_parse_endpoint(const struct device_node *node,
- struct v4l2_of_endpoint *endpoint);
-struct v4l2_of_endpoint *v4l2_of_alloc_parse_endpoint(
- const struct device_node *node);
-void v4l2_of_free_endpoint(struct v4l2_of_endpoint *endpoint);
-int v4l2_of_parse_link(const struct device_node *node,
- struct v4l2_of_link *link);
-void v4l2_of_put_link(struct v4l2_of_link *link);
-#else /* CONFIG_OF */
-
-static inline int v4l2_of_parse_endpoint(const struct device_node *node,
- struct v4l2_of_endpoint *link)
-{
- return -ENOSYS;
-}
-
-static inline struct v4l2_of_endpoint *v4l2_of_alloc_parse_endpoint(
- const struct device_node *node)
-{
- return NULL;
-}
-
-static inline void v4l2_of_free_endpoint(struct v4l2_of_endpoint *endpoint)
-{
-}
-
-static inline int v4l2_of_parse_link(const struct device_node *node,
- struct v4l2_of_link *link)
-{
- return -ENOSYS;
-}
-
-static inline void v4l2_of_put_link(struct v4l2_of_link *link)
-{
-}
-
-#endif /* CONFIG_OF */
-
-#endif /* _V4L2_OF_H */
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 7/8] docs-rst: media: Switch documentation to V4L2 fwnode API
From: Sakari Ailus @ 2017-04-06 13:10 UTC (permalink / raw)
To: linux-media; +Cc: linux-acpi, devicetree, laurent.pinchart
In-Reply-To: <1491484249-11964-1-git-send-email-sakari.ailus@linux.intel.com>
Instead of including the V4L2 OF header in ReST documentation, use the
V4L2 fwnode header instead.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
Documentation/media/kapi/v4l2-core.rst | 2 +-
Documentation/media/kapi/v4l2-fwnode.rst | 3 +++
Documentation/media/kapi/v4l2-of.rst | 3 ---
3 files changed, 4 insertions(+), 4 deletions(-)
create mode 100644 Documentation/media/kapi/v4l2-fwnode.rst
delete mode 100644 Documentation/media/kapi/v4l2-of.rst
diff --git a/Documentation/media/kapi/v4l2-core.rst b/Documentation/media/kapi/v4l2-core.rst
index e967715..1bc8a14 100644
--- a/Documentation/media/kapi/v4l2-core.rst
+++ b/Documentation/media/kapi/v4l2-core.rst
@@ -19,7 +19,7 @@ Video2Linux devices
v4l2-mc
v4l2-mediabus
v4l2-mem2mem
- v4l2-of
+ v4l2-fwnode
v4l2-rect
v4l2-tuner
v4l2-common
diff --git a/Documentation/media/kapi/v4l2-fwnode.rst b/Documentation/media/kapi/v4l2-fwnode.rst
new file mode 100644
index 0000000..6c8bccd
--- /dev/null
+++ b/Documentation/media/kapi/v4l2-fwnode.rst
@@ -0,0 +1,3 @@
+V4L2 fwnode kAPI
+^^^^^^^^^^^^^^^^
+.. kernel-doc:: include/media/v4l2-fwnode.h
diff --git a/Documentation/media/kapi/v4l2-of.rst b/Documentation/media/kapi/v4l2-of.rst
deleted file mode 100644
index 1ddf76b..0000000
--- a/Documentation/media/kapi/v4l2-of.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-V4L2 Open Firmware kAPI
-^^^^^^^^^^^^^^^^^^^^^^^
-.. kernel-doc:: include/media/v4l2-of.h
--
2.7.4
^ permalink raw reply related
* [PATCH v2 6/8] v4l: media/drv-intf/soc_mediabus.h: include dependent header file
From: Sakari Ailus @ 2017-04-06 13:10 UTC (permalink / raw)
To: linux-media; +Cc: linux-acpi, devicetree, laurent.pinchart
In-Reply-To: <1491484249-11964-1-git-send-email-sakari.ailus@linux.intel.com>
media/drv-intf/soc_mediabus.h does depend on struct v4l2_mbus_config which
is defined in media/v4l2-mediabus.h. Include it.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
include/media/drv-intf/soc_mediabus.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/media/drv-intf/soc_mediabus.h b/include/media/drv-intf/soc_mediabus.h
index 2ff7737..0449788 100644
--- a/include/media/drv-intf/soc_mediabus.h
+++ b/include/media/drv-intf/soc_mediabus.h
@@ -14,6 +14,8 @@
#include <linux/videodev2.h>
#include <linux/v4l2-mediabus.h>
+#include <media/v4l2-mediabus.h>
+
/**
* enum soc_mbus_packing - data packing types on the media-bus
* @SOC_MBUS_PACKING_NONE: no packing, bit-for-bit transfer to RAM, one
--
2.7.4
^ permalink raw reply related
* [PATCH v2 5/8] v4l: Switch from V4L2 OF not V4L2 fwnode API
From: Sakari Ailus @ 2017-04-06 13:10 UTC (permalink / raw)
To: linux-media; +Cc: linux-acpi, devicetree, laurent.pinchart
In-Reply-To: <1491484249-11964-1-git-send-email-sakari.ailus@linux.intel.com>
Switch users of the v4l2_of_ APIs to the more generic v4l2_fwnode_ APIs.
Existing OF matching continues to be supported. omap3isp and smiapp
drivers are converted to fwnode matching as well.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Acked-by: Benoit Parrot <bparrot@ti.com> # i2c/ov2569.c, am437x/am437x-vpfe.c and ti-vpe/cal.c
---
drivers/media/i2c/Kconfig | 9 ++++
drivers/media/i2c/adv7604.c | 7 +--
drivers/media/i2c/mt9v032.c | 7 +--
drivers/media/i2c/ov2659.c | 8 +--
drivers/media/i2c/s5c73m3/s5c73m3-core.c | 7 +--
drivers/media/i2c/s5k5baf.c | 6 +--
drivers/media/i2c/smiapp/Kconfig | 1 +
drivers/media/i2c/smiapp/smiapp-core.c | 29 ++++++-----
drivers/media/i2c/tc358743.c | 11 ++--
drivers/media/i2c/tvp514x.c | 6 +--
drivers/media/i2c/tvp5150.c | 7 +--
drivers/media/i2c/tvp7002.c | 6 +--
drivers/media/platform/Kconfig | 3 ++
drivers/media/platform/am437x/Kconfig | 1 +
drivers/media/platform/am437x/am437x-vpfe.c | 8 +--
drivers/media/platform/atmel/Kconfig | 1 +
drivers/media/platform/atmel/atmel-isc.c | 8 +--
drivers/media/platform/exynos4-is/Kconfig | 2 +
drivers/media/platform/exynos4-is/media-dev.c | 6 +--
drivers/media/platform/exynos4-is/mipi-csis.c | 6 +--
drivers/media/platform/omap3isp/isp.c | 71 +++++++++++++-------------
drivers/media/platform/pxa_camera.c | 7 +--
drivers/media/platform/rcar-vin/Kconfig | 1 +
drivers/media/platform/rcar-vin/rcar-core.c | 6 +--
drivers/media/platform/soc_camera/Kconfig | 1 +
drivers/media/platform/soc_camera/atmel-isi.c | 7 +--
drivers/media/platform/soc_camera/soc_camera.c | 3 +-
drivers/media/platform/ti-vpe/cal.c | 11 ++--
drivers/media/platform/xilinx/Kconfig | 1 +
drivers/media/platform/xilinx/xilinx-vipp.c | 59 +++++++++++----------
include/media/v4l2-fwnode.h | 4 +-
31 files changed, 176 insertions(+), 134 deletions(-)
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index cee1dae..6b2423a 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -210,6 +210,7 @@ config VIDEO_ADV7604
depends on GPIOLIB || COMPILE_TEST
select HDMI
select MEDIA_CEC_EDID
+ select V4L2_FWNODE
---help---
Support for the Analog Devices ADV7604 video decoder.
@@ -324,6 +325,7 @@ config VIDEO_TC358743
tristate "Toshiba TC358743 decoder"
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
select HDMI
+ select V4L2_FWNODE
---help---
Support for the Toshiba TC358743 HDMI to MIPI CSI-2 bridge.
@@ -333,6 +335,7 @@ config VIDEO_TC358743
config VIDEO_TVP514X
tristate "Texas Instruments TVP514x video decoder"
depends on VIDEO_V4L2 && I2C
+ select V4L2_FWNODE
---help---
This is a Video4Linux2 sensor-level driver for the TI TVP5146/47
decoder. It is currently working with the TI OMAP3 camera
@@ -344,6 +347,7 @@ config VIDEO_TVP514X
config VIDEO_TVP5150
tristate "Texas Instruments TVP5150 video decoder"
depends on VIDEO_V4L2 && I2C
+ select V4L2_FWNODE
---help---
Support for the Texas Instruments TVP5150 video decoder.
@@ -353,6 +357,7 @@ config VIDEO_TVP5150
config VIDEO_TVP7002
tristate "Texas Instruments TVP7002 video decoder"
depends on VIDEO_V4L2 && I2C
+ select V4L2_FWNODE
---help---
Support for the Texas Instruments TVP7002 video decoder.
@@ -524,6 +529,7 @@ config VIDEO_OV2659
tristate "OmniVision OV2659 sensor support"
depends on VIDEO_V4L2 && I2C
depends on MEDIA_CAMERA_SUPPORT
+ select V4L2_FWNODE
---help---
This is a Video4Linux2 sensor-level driver for the OmniVision
OV2659 camera.
@@ -616,6 +622,7 @@ config VIDEO_MT9V032
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
depends on MEDIA_CAMERA_SUPPORT
select REGMAP_I2C
+ select V4L2_FWNODE
---help---
This is a Video4Linux2 sensor-level driver for the Micron
MT9V032 752x480 CMOS sensor.
@@ -663,6 +670,7 @@ config VIDEO_S5K4ECGX
config VIDEO_S5K5BAF
tristate "Samsung S5K5BAF sensor support"
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ select V4L2_FWNODE
---help---
This is a V4L2 sensor-level driver for Samsung S5K5BAF 2M
camera sensor with an embedded SoC image signal processor.
@@ -673,6 +681,7 @@ source "drivers/media/i2c/et8ek8/Kconfig"
config VIDEO_S5C73M3
tristate "Samsung S5C73M3 sensor support"
depends on I2C && SPI && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ select V4L2_FWNODE
---help---
This is a V4L2 sensor-level driver for Samsung S5C73M3
8 Mpixel camera.
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index d8bf435..9281e54 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -33,6 +33,7 @@
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/of_graph.h>
#include <linux/slab.h>
#include <linux/v4l2-dv-timings.h>
#include <linux/videodev2.h>
@@ -45,7 +46,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-dv-timings.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
static int debug;
module_param(debug, int, 0644);
@@ -3069,7 +3070,7 @@ MODULE_DEVICE_TABLE(of, adv76xx_of_id);
static int adv76xx_parse_dt(struct adv76xx_state *state)
{
- struct v4l2_of_endpoint bus_cfg;
+ struct v4l2_fwnode_endpoint bus_cfg;
struct device_node *endpoint;
struct device_node *np;
unsigned int flags;
@@ -3083,7 +3084,7 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
if (!endpoint)
return -EINVAL;
- ret = v4l2_of_parse_endpoint(endpoint, &bus_cfg);
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), &bus_cfg);
if (ret) {
of_node_put(endpoint);
return ret;
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 2e7a6e6..8a43064 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -19,6 +19,7 @@
#include <linux/log2.h>
#include <linux/mutex.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
@@ -28,7 +29,7 @@
#include <media/i2c/mt9v032.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
/* The first four rows are black rows. The active area spans 753x481 pixels. */
@@ -979,7 +980,7 @@ static struct mt9v032_platform_data *
mt9v032_get_pdata(struct i2c_client *client)
{
struct mt9v032_platform_data *pdata = NULL;
- struct v4l2_of_endpoint endpoint;
+ struct v4l2_fwnode_endpoint endpoint;
struct device_node *np;
struct property *prop;
@@ -990,7 +991,7 @@ mt9v032_get_pdata(struct i2c_client *client)
if (!np)
return NULL;
- if (v4l2_of_parse_endpoint(np, &endpoint) < 0)
+ if (v4l2_fwnode_endpoint_parse(of_fwnode_handle(np), &endpoint) < 0)
goto done;
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
index 6e63672..545ca3f 100644
--- a/drivers/media/i2c/ov2659.c
+++ b/drivers/media/i2c/ov2659.c
@@ -42,9 +42,9 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-image-sizes.h>
#include <media/v4l2-mediabus.h>
-#include <media/v4l2-of.h>
#include <media/v4l2-subdev.h>
#define DRIVER_NAME "ov2659"
@@ -1346,7 +1346,7 @@ static struct ov2659_platform_data *
ov2659_get_pdata(struct i2c_client *client)
{
struct ov2659_platform_data *pdata;
- struct v4l2_of_endpoint *bus_cfg;
+ struct v4l2_fwnode_endpoint *bus_cfg;
struct device_node *endpoint;
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
@@ -1356,7 +1356,7 @@ ov2659_get_pdata(struct i2c_client *client)
if (!endpoint)
return NULL;
- bus_cfg = v4l2_of_alloc_parse_endpoint(endpoint);
+ bus_cfg = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(endpoint));
if (IS_ERR(bus_cfg)) {
pdata = NULL;
goto done;
@@ -1376,7 +1376,7 @@ ov2659_get_pdata(struct i2c_client *client)
pdata->link_frequency = bus_cfg->link_frequencies[0];
done:
- v4l2_of_free_endpoint(bus_cfg);
+ v4l2_fwnode_endpoint_free(bus_cfg);
of_node_put(endpoint);
return pdata;
}
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 3844853..f434fb2 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -24,6 +24,7 @@
#include <linux/media.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
+#include <linux/of_graph.h>
#include <linux/regulator/consumer.h>
#include <linux/sizes.h>
#include <linux/slab.h>
@@ -35,7 +36,7 @@
#include <media/v4l2-subdev.h>
#include <media/v4l2-mediabus.h>
#include <media/i2c/s5c73m3.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include "s5c73m3.h"
@@ -1602,7 +1603,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state)
const struct s5c73m3_platform_data *pdata = dev->platform_data;
struct device_node *node = dev->of_node;
struct device_node *node_ep;
- struct v4l2_of_endpoint ep;
+ struct v4l2_fwnode_endpoint ep;
int ret;
if (!node) {
@@ -1639,7 +1640,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state)
return 0;
}
- ret = v4l2_of_parse_endpoint(node_ep, &ep);
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node_ep), &ep);
of_node_put(node_ep);
if (ret)
return ret;
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index db82ed0..962051b 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -30,7 +30,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-mediabus.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
static int debug;
module_param(debug, int, 0644);
@@ -1841,7 +1841,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
{
struct device_node *node = dev->of_node;
struct device_node *node_ep;
- struct v4l2_of_endpoint ep;
+ struct v4l2_fwnode_endpoint ep;
int ret;
if (!node) {
@@ -1868,7 +1868,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
return -EINVAL;
}
- ret = v4l2_of_parse_endpoint(node_ep, &ep);
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node_ep), &ep);
of_node_put(node_ep);
if (ret)
return ret;
diff --git a/drivers/media/i2c/smiapp/Kconfig b/drivers/media/i2c/smiapp/Kconfig
index 3149cda..f59718d 100644
--- a/drivers/media/i2c/smiapp/Kconfig
+++ b/drivers/media/i2c/smiapp/Kconfig
@@ -3,5 +3,6 @@ config VIDEO_SMIAPP
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAVE_CLK
depends on MEDIA_CAMERA_SUPPORT
select VIDEO_SMIAPP_PLL
+ select V4L2_FWNODE
---help---
This is a generic driver for SMIA++/SMIA camera modules.
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index f4e92bd..4e28220 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -27,12 +27,13 @@
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
+#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/smiapp.h>
#include <linux/v4l2-mediabus.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-of.h>
#include "smiapp.h"
@@ -2784,19 +2785,20 @@ static int __maybe_unused smiapp_resume(struct device *dev)
static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev)
{
struct smiapp_hwconfig *hwcfg;
- struct v4l2_of_endpoint *bus_cfg;
- struct device_node *ep;
+ struct v4l2_fwnode_endpoint *bus_cfg;
+ struct fwnode_handle *ep;
+ struct fwnode_handle *fwn = dev_fwnode(dev);
int i;
int rval;
- if (!dev->of_node)
+ if (!fwn)
return dev->platform_data;
- ep = of_graph_get_next_endpoint(dev->of_node, NULL);
+ ep = fwnode_graph_get_next_endpoint(fwn, NULL);
if (!ep)
return NULL;
- bus_cfg = v4l2_of_alloc_parse_endpoint(ep);
+ bus_cfg = v4l2_fwnode_endpoint_alloc_parse(ep);
if (IS_ERR(bus_cfg))
goto out_err;
@@ -2817,11 +2819,10 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev)
dev_dbg(dev, "lanes %u\n", hwcfg->lanes);
/* NVM size is not mandatory */
- of_property_read_u32(dev->of_node, "nokia,nvm-size",
- &hwcfg->nvm_size);
+ fwnode_property_read_u32(fwn, "nokia,nvm-size", &hwcfg->nvm_size);
- rval = of_property_read_u32(dev->of_node, "clock-frequency",
- &hwcfg->ext_clk);
+ rval = fwnode_property_read_u32(fwn, "clock-frequency",
+ &hwcfg->ext_clk);
if (rval) {
dev_warn(dev, "can't get clock-frequency\n");
goto out_err;
@@ -2846,13 +2847,13 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev)
dev_dbg(dev, "freq %d: %lld\n", i, hwcfg->op_sys_clock[i]);
}
- v4l2_of_free_endpoint(bus_cfg);
- of_node_put(ep);
+ v4l2_fwnode_endpoint_free(bus_cfg);
+ fwnode_handle_put(ep);
return hwcfg;
out_err:
- v4l2_of_free_endpoint(bus_cfg);
- of_node_put(ep);
+ v4l2_fwnode_endpoint_free(bus_cfg);
+ fwnode_handle_put(ep);
return NULL;
}
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index bf9d925..c4c894b 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -33,6 +33,7 @@
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
+#include <linux/of_graph.h>
#include <linux/videodev2.h>
#include <linux/workqueue.h>
#include <linux/v4l2-dv-timings.h>
@@ -41,7 +42,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/i2c/tc358743.h>
#include "tc358743_regs.h"
@@ -76,7 +77,7 @@ static const struct v4l2_dv_timings_cap tc358743_timings_cap = {
struct tc358743_state {
struct tc358743_platform_data pdata;
- struct v4l2_of_bus_mipi_csi2 bus;
+ struct v4l2_fwnode_bus_mipi_csi2 bus;
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_ctrl_handler hdl;
@@ -1695,7 +1696,7 @@ static void tc358743_gpio_reset(struct tc358743_state *state)
static int tc358743_probe_of(struct tc358743_state *state)
{
struct device *dev = &state->i2c_client->dev;
- struct v4l2_of_endpoint *endpoint;
+ struct v4l2_fwnode_endpoint *endpoint;
struct device_node *ep;
struct clk *refclk;
u32 bps_pr_lane;
@@ -1715,7 +1716,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
return -EINVAL;
}
- endpoint = v4l2_of_alloc_parse_endpoint(ep);
+ endpoint = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep));
if (IS_ERR(endpoint)) {
dev_err(dev, "failed to parse endpoint\n");
return PTR_ERR(endpoint);
@@ -1803,7 +1804,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
disable_clk:
clk_disable_unprepare(refclk);
free_endpoint:
- v4l2_of_free_endpoint(endpoint);
+ v4l2_fwnode_endpoint_free(endpoint);
return ret;
}
#else
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index 07853d2..ad2df99 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -38,7 +38,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
#include <media/v4l2-mediabus.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-ctrls.h>
#include <media/i2c/tvp514x.h>
#include <media/media-entity.h>
@@ -998,7 +998,7 @@ static struct tvp514x_platform_data *
tvp514x_get_pdata(struct i2c_client *client)
{
struct tvp514x_platform_data *pdata = NULL;
- struct v4l2_of_endpoint bus_cfg;
+ struct v4l2_fwnode_endpoint bus_cfg;
struct device_node *endpoint;
unsigned int flags;
@@ -1009,7 +1009,7 @@ tvp514x_get_pdata(struct i2c_client *client)
if (!endpoint)
return NULL;
- if (v4l2_of_parse_endpoint(endpoint, &bus_cfg))
+ if (v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), &bus_cfg))
goto done;
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 48646a7..dff30a0 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -12,10 +12,11 @@
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
+#include <linux/of_graph.h>
#include <media/v4l2-async.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-mc.h>
#include "tvp5150_reg.h"
@@ -1358,7 +1359,7 @@ static int tvp5150_init(struct i2c_client *c)
static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np)
{
- struct v4l2_of_endpoint bus_cfg;
+ struct v4l2_fwnode_endpoint bus_cfg;
struct device_node *ep;
#ifdef CONFIG_MEDIA_CONTROLLER
struct device_node *connectors, *child;
@@ -1373,7 +1374,7 @@ static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np)
if (!ep)
return -EINVAL;
- ret = v4l2_of_parse_endpoint(ep, &bus_cfg);
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &bus_cfg);
if (ret)
goto err;
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index 4c11901..a26c1a3 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
@@ -33,7 +33,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include "tvp7002_reg.h"
@@ -889,7 +889,7 @@ static const struct v4l2_subdev_ops tvp7002_ops = {
static struct tvp7002_config *
tvp7002_get_pdata(struct i2c_client *client)
{
- struct v4l2_of_endpoint bus_cfg;
+ struct v4l2_fwnode_endpoint bus_cfg;
struct tvp7002_config *pdata = NULL;
struct device_node *endpoint;
unsigned int flags;
@@ -901,7 +901,7 @@ tvp7002_get_pdata(struct i2c_client *client)
if (!endpoint)
return NULL;
- if (v4l2_of_parse_endpoint(endpoint, &bus_cfg))
+ if (v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), &bus_cfg))
goto done;
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index ab0bb48..10862f0 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -82,6 +82,7 @@ config VIDEO_OMAP3
select ARM_DMA_USE_IOMMU
select VIDEOBUF2_DMA_CONTIG
select MFD_SYSCON
+ select V4L2_FWNODE
---help---
Driver for an OMAP 3 camera controller.
@@ -97,6 +98,7 @@ config VIDEO_PXA27x
depends on PXA27x || COMPILE_TEST
select VIDEOBUF2_DMA_SG
select SG_SPLIT
+ select V4L2_FWNODE
---help---
This is a v4l2 driver for the PXA27x Quick Capture Interface
@@ -127,6 +129,7 @@ config VIDEO_TI_CAL
depends on SOC_DRA7XX || COMPILE_TEST
depends on HAS_DMA
select VIDEOBUF2_DMA_CONTIG
+ select V4L2_FWNODE
default n
---help---
Support for the TI CAL (Camera Adaptation Layer) block
diff --git a/drivers/media/platform/am437x/Kconfig b/drivers/media/platform/am437x/Kconfig
index 42d9c18..160e77e 100644
--- a/drivers/media/platform/am437x/Kconfig
+++ b/drivers/media/platform/am437x/Kconfig
@@ -3,6 +3,7 @@ config VIDEO_AM437X_VPFE
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA
depends on SOC_AM43XX || COMPILE_TEST
select VIDEOBUF2_DMA_CONTIG
+ select V4L2_FWNODE
help
Support for AM437x Video Processing Front End based Video
Capture Driver.
diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c
index 05489a4..3eb0bd2 100644
--- a/drivers/media/platform/am437x/am437x-vpfe.c
+++ b/drivers/media/platform/am437x/am437x-vpfe.c
@@ -26,6 +26,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/of_graph.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -36,7 +37,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include "am437x-vpfe.h"
@@ -2419,7 +2420,7 @@ static struct vpfe_config *
vpfe_get_pdata(struct platform_device *pdev)
{
struct device_node *endpoint = NULL;
- struct v4l2_of_endpoint bus_cfg;
+ struct v4l2_fwnode_endpoint bus_cfg;
struct vpfe_subdev_info *sdinfo;
struct vpfe_config *pdata;
unsigned int flags;
@@ -2463,7 +2464,8 @@ vpfe_get_pdata(struct platform_device *pdev)
sdinfo->vpfe_param.if_type = VPFE_RAW_BAYER;
}
- err = v4l2_of_parse_endpoint(endpoint, &bus_cfg);
+ err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
+ &bus_cfg);
if (err) {
dev_err(&pdev->dev, "Could not parse the endpoint\n");
goto done;
diff --git a/drivers/media/platform/atmel/Kconfig b/drivers/media/platform/atmel/Kconfig
index 867dca2..3dbc89c 100644
--- a/drivers/media/platform/atmel/Kconfig
+++ b/drivers/media/platform/atmel/Kconfig
@@ -4,6 +4,7 @@ config VIDEO_ATMEL_ISC
depends on ARCH_AT91 || COMPILE_TEST
select VIDEOBUF2_DMA_CONTIG
select REGMAP_MMIO
+ select V4L2_FWNODE
help
This module makes the ATMEL Image Sensor Controller available
as a v4l2 device.
\ No newline at end of file
diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c
index b380a7d..8e78da2 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -32,6 +32,7 @@
#include <linux/math64.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
@@ -42,7 +43,7 @@
#include <media/v4l2-event.h>
#include <media/v4l2-image-sizes.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
#include <media/videobuf2-dma-contig.h>
@@ -1683,7 +1684,7 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
{
struct device_node *np = dev->of_node;
struct device_node *epn = NULL, *rem;
- struct v4l2_of_endpoint v4l2_epn;
+ struct v4l2_fwnode_endpoint v4l2_epn;
struct isc_subdev_entity *subdev_entity;
unsigned int flags;
int ret;
@@ -1702,7 +1703,8 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
continue;
}
- ret = v4l2_of_parse_endpoint(epn, &v4l2_epn);
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(epn),
+ &v4l2_epn);
if (ret) {
of_node_put(rem);
ret = -EINVAL;
diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig
index 57d42c6..c480efb 100644
--- a/drivers/media/platform/exynos4-is/Kconfig
+++ b/drivers/media/platform/exynos4-is/Kconfig
@@ -4,6 +4,7 @@ config VIDEO_SAMSUNG_EXYNOS4_IS
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
depends on OF && COMMON_CLK
+ select V4L2_FWNODE
help
Say Y here to enable camera host interface devices for
Samsung S5P and EXYNOS SoC series.
@@ -32,6 +33,7 @@ config VIDEO_S5P_MIPI_CSIS
tristate "S5P/EXYNOS MIPI-CSI2 receiver (MIPI-CSIS) driver"
depends on REGULATOR
select GENERIC_PHY
+ select V4L2_FWNODE
help
This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC MIPI-CSI2
receiver (MIPI-CSIS) devices.
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index e82450e9..4a1808c 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -29,7 +29,7 @@
#include <linux/slab.h>
#include <media/v4l2-async.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/media-device.h>
#include <media/drv-intf/exynos-fimc.h>
@@ -388,7 +388,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
{
struct fimc_source_info *pd = &fmd->sensor[index].pdata;
struct device_node *rem, *ep, *np;
- struct v4l2_of_endpoint endpoint;
+ struct v4l2_fwnode_endpoint endpoint;
int ret;
/* Assume here a port node can have only one endpoint node. */
@@ -396,7 +396,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
if (!ep)
return 0;
- ret = v4l2_of_parse_endpoint(ep, &endpoint);
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &endpoint);
if (ret) {
of_node_put(ep);
return ret;
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index f819b29..98c8987 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -30,7 +30,7 @@
#include <linux/spinlock.h>
#include <linux/videodev2.h>
#include <media/drv-intf/exynos-fimc.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
#include "mipi-csis.h"
@@ -718,7 +718,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
struct csis_state *state)
{
struct device_node *node = pdev->dev.of_node;
- struct v4l2_of_endpoint endpoint;
+ struct v4l2_fwnode_endpoint endpoint;
int ret;
if (of_property_read_u32(node, "clock-frequency",
@@ -735,7 +735,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
return -EINVAL;
}
/* Get port node and validate MIPI-CSI channel id. */
- ret = v4l2_of_parse_endpoint(node, &endpoint);
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &endpoint);
if (ret)
goto err;
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 084ecf4a..95850b9 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -55,6 +55,7 @@
#include <linux/module.h>
#include <linux/omap-iommu.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/sched.h>
@@ -63,9 +64,9 @@
#include <asm/dma-iommu.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mc.h>
-#include <media/v4l2-of.h>
#include "isp.h"
#include "ispreg.h"
@@ -2024,43 +2025,42 @@ enum isp_of_phy {
ISP_OF_PHY_CSIPHY2,
};
-static int isp_of_parse_node(struct device *dev, struct device_node *node,
- struct isp_async_subdev *isd)
+static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwn,
+ struct isp_async_subdev *isd)
{
struct isp_bus_cfg *buscfg = &isd->bus;
- struct v4l2_of_endpoint vep;
+ struct v4l2_fwnode_endpoint vfwn;
unsigned int i;
int ret;
- ret = v4l2_of_parse_endpoint(node, &vep);
+ ret = v4l2_fwnode_endpoint_parse(fwn, &vfwn);
if (ret)
return ret;
- dev_dbg(dev, "parsing endpoint %s, interface %u\n", node->full_name,
- vep.base.port);
+ dev_dbg(dev, "interface %u\n", vfwn.base.port);
- switch (vep.base.port) {
+ switch (vfwn.base.port) {
case ISP_OF_PHY_PARALLEL:
buscfg->interface = ISP_INTERFACE_PARALLEL;
buscfg->bus.parallel.data_lane_shift =
- vep.bus.parallel.data_shift;
+ vfwn.bus.parallel.data_shift;
buscfg->bus.parallel.clk_pol =
- !!(vep.bus.parallel.flags
+ !!(vfwn.bus.parallel.flags
& V4L2_MBUS_PCLK_SAMPLE_FALLING);
buscfg->bus.parallel.hs_pol =
- !!(vep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW);
+ !!(vfwn.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW);
buscfg->bus.parallel.vs_pol =
- !!(vep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW);
+ !!(vfwn.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW);
buscfg->bus.parallel.fld_pol =
- !!(vep.bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW);
+ !!(vfwn.bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW);
buscfg->bus.parallel.data_pol =
- !!(vep.bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW);
+ !!(vfwn.bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW);
break;
case ISP_OF_PHY_CSIPHY1:
case ISP_OF_PHY_CSIPHY2:
/* FIXME: always assume CSI-2 for now. */
- switch (vep.base.port) {
+ switch (vfwn.base.port) {
case ISP_OF_PHY_CSIPHY1:
buscfg->interface = ISP_INTERFACE_CSI2C_PHY1;
break;
@@ -2068,18 +2068,18 @@ static int isp_of_parse_node(struct device *dev, struct device_node *node,
buscfg->interface = ISP_INTERFACE_CSI2A_PHY2;
break;
}
- buscfg->bus.csi2.lanecfg.clk.pos = vep.bus.mipi_csi2.clock_lane;
+ buscfg->bus.csi2.lanecfg.clk.pos = vfwn.bus.mipi_csi2.clock_lane;
buscfg->bus.csi2.lanecfg.clk.pol =
- vep.bus.mipi_csi2.lane_polarities[0];
+ vfwn.bus.mipi_csi2.lane_polarities[0];
dev_dbg(dev, "clock lane polarity %u, pos %u\n",
buscfg->bus.csi2.lanecfg.clk.pol,
buscfg->bus.csi2.lanecfg.clk.pos);
for (i = 0; i < ISP_CSIPHY2_NUM_DATA_LANES; i++) {
buscfg->bus.csi2.lanecfg.data[i].pos =
- vep.bus.mipi_csi2.data_lanes[i];
+ vfwn.bus.mipi_csi2.data_lanes[i];
buscfg->bus.csi2.lanecfg.data[i].pol =
- vep.bus.mipi_csi2.lane_polarities[i + 1];
+ vfwn.bus.mipi_csi2.lane_polarities[i + 1];
dev_dbg(dev, "data lane %u polarity %u, pos %u\n", i,
buscfg->bus.csi2.lanecfg.data[i].pol,
buscfg->bus.csi2.lanecfg.data[i].pos);
@@ -2094,18 +2094,17 @@ static int isp_of_parse_node(struct device *dev, struct device_node *node,
break;
default:
- dev_warn(dev, "%s: invalid interface %u\n", node->full_name,
- vep.base.port);
+ dev_warn(dev, "invalid interface %u\n", vfwn.base.port);
break;
}
return 0;
}
-static int isp_of_parse_nodes(struct device *dev,
- struct v4l2_async_notifier *notifier)
+static int isp_fwnodes_parse(struct device *dev,
+ struct v4l2_async_notifier *notifier)
{
- struct device_node *node = NULL;
+ struct fwnode_handle *fwn = NULL;
notifier->subdevs = devm_kcalloc(
dev, ISP_MAX_SUBDEVS, sizeof(*notifier->subdevs), GFP_KERNEL);
@@ -2113,7 +2112,8 @@ static int isp_of_parse_nodes(struct device *dev,
return -ENOMEM;
while (notifier->num_subdevs < ISP_MAX_SUBDEVS &&
- (node = of_graph_get_next_endpoint(dev->of_node, node))) {
+ (fwn = fwnode_graph_get_next_endpoint(dev_fwnode(dev),
+ fwn))) {
struct isp_async_subdev *isd;
isd = devm_kzalloc(dev, sizeof(*isd), GFP_KERNEL);
@@ -2122,23 +2122,24 @@ static int isp_of_parse_nodes(struct device *dev,
notifier->subdevs[notifier->num_subdevs] = &isd->asd;
- if (isp_of_parse_node(dev, node, isd))
+ if (isp_fwnode_parse(dev, fwn, isd))
goto error;
- isd->asd.match.of.node = of_graph_get_remote_port_parent(node);
- if (!isd->asd.match.of.node) {
+ isd->asd.match.fwnode.fwn =
+ fwnode_graph_get_remote_port_parent(fwn);
+ if (!isd->asd.match.fwnode.fwn) {
dev_warn(dev, "bad remote port parent\n");
goto error;
}
- isd->asd.match_type = V4L2_ASYNC_MATCH_OF;
+ isd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
notifier->num_subdevs++;
}
return notifier->num_subdevs;
error:
- of_node_put(node);
+ fwnode_handle_put(fwn);
return -EINVAL;
}
@@ -2209,8 +2210,8 @@ static int isp_probe(struct platform_device *pdev)
return -ENOMEM;
}
- ret = of_property_read_u32(pdev->dev.of_node, "ti,phy-type",
- &isp->phy_type);
+ ret = fwnode_property_read_u32(dev_fwnode(&pdev->dev),
+ "ti,phy-type", &isp->phy_type);
if (ret)
return ret;
@@ -2219,12 +2220,12 @@ static int isp_probe(struct platform_device *pdev)
if (IS_ERR(isp->syscon))
return PTR_ERR(isp->syscon);
- ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 1,
- &isp->syscon_offset);
+ ret = of_property_read_u32_index(pdev->dev.of_node,
+ "syscon", 1, &isp->syscon_offset);
if (ret)
return ret;
- ret = isp_of_parse_nodes(&pdev->dev, &isp->notifier);
+ ret = isp_fwnodes_parse(&pdev->dev, &isp->notifier);
if (ret < 0)
return ret;
diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c
index 929006f..1ad4cf9 100644
--- a/drivers/media/platform/pxa_camera.c
+++ b/drivers/media/platform/pxa_camera.c
@@ -25,6 +25,7 @@
#include <linux/mm.h>
#include <linux/moduleparam.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/time.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
@@ -39,7 +40,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/videobuf2-dma-sg.h>
@@ -2236,7 +2237,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
{
u32 mclk_rate;
struct device_node *remote, *np = dev->of_node;
- struct v4l2_of_endpoint ep;
+ struct v4l2_fwnode_endpoint ep;
int err = of_property_read_u32(np, "clock-frequency",
&mclk_rate);
if (!err) {
@@ -2250,7 +2251,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
return -EINVAL;
}
- err = v4l2_of_parse_endpoint(np, &ep);
+ err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(np), &ep);
if (err) {
dev_err(dev, "could not parse endpoint\n");
goto out;
diff --git a/drivers/media/platform/rcar-vin/Kconfig b/drivers/media/platform/rcar-vin/Kconfig
index 111d2a1..af4c98b 100644
--- a/drivers/media/platform/rcar-vin/Kconfig
+++ b/drivers/media/platform/rcar-vin/Kconfig
@@ -3,6 +3,7 @@ config VIDEO_RCAR_VIN
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && MEDIA_CONTROLLER
depends on ARCH_RENESAS || COMPILE_TEST
select VIDEOBUF2_DMA_CONTIG
+ select V4L2_FWNODE
---help---
Support for Renesas R-Car Video Input (VIN) driver.
Supports R-Car Gen2 SoCs.
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 098a0b1..72903fc 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -21,7 +21,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include "rcar-vin.h"
@@ -118,10 +118,10 @@ static int rvin_digitial_parse_v4l2(struct rvin_dev *vin,
struct device_node *ep,
struct v4l2_mbus_config *mbus_cfg)
{
- struct v4l2_of_endpoint v4l2_ep;
+ struct v4l2_fwnode_endpoint v4l2_ep;
int ret;
- ret = v4l2_of_parse_endpoint(ep, &v4l2_ep);
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &v4l2_ep);
if (ret) {
vin_err(vin, "Could not parse v4l2 endpoint\n");
return -EINVAL;
diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
index 2728276..7009e5b 100644
--- a/drivers/media/platform/soc_camera/Kconfig
+++ b/drivers/media/platform/soc_camera/Kconfig
@@ -32,6 +32,7 @@ config VIDEO_ATMEL_ISI
depends on ARCH_AT91 || COMPILE_TEST
depends on HAS_DMA
select VIDEOBUF2_DMA_CONTIG
+ select V4L2_FWNODE
---help---
This module makes the ATMEL Image Sensor Interface available
as a v4l2 device.
diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c
index 46de657..f9f2ad6 100644
--- a/drivers/media/platform/soc_camera/atmel-isi.c
+++ b/drivers/media/platform/soc_camera/atmel-isi.c
@@ -19,13 +19,14 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <media/soc_camera.h>
#include <media/drv-intf/soc_mediabus.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/videobuf2-dma-contig.h>
#include "atmel-isi.h"
@@ -974,7 +975,7 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
struct platform_device *pdev)
{
struct device_node *np= pdev->dev.of_node;
- struct v4l2_of_endpoint ep;
+ struct v4l2_fwnode_endpoint ep;
int err;
/* Default settings for ISI */
@@ -987,7 +988,7 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
return -EINVAL;
}
- err = v4l2_of_parse_endpoint(np, &ep);
+ err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(np), &ep);
of_node_put(np);
if (err) {
dev_err(&pdev->dev, "Could not parse the endpoint\n");
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index 3c9421f..0997d074 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -23,6 +23,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
@@ -36,7 +37,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-dev.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/videobuf2-v4l2.h>
/* Default to VGA resolution */
diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c
index 7a058b6..f72f541 100644
--- a/drivers/media/platform/ti-vpe/cal.c
+++ b/drivers/media/platform/ti-vpe/cal.c
@@ -21,7 +21,7 @@
#include <linux/of_device.h>
#include <linux/of_graph.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-async.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
@@ -270,7 +270,7 @@ struct cal_ctx {
struct video_device vdev;
struct v4l2_async_notifier notifier;
struct v4l2_subdev *sensor;
- struct v4l2_of_endpoint endpoint;
+ struct v4l2_fwnode_endpoint endpoint;
struct v4l2_async_subdev asd;
struct v4l2_async_subdev *asd_list[1];
@@ -608,7 +608,8 @@ static void csi2_lane_config(struct cal_ctx *ctx)
u32 val = reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port));
u32 lane_mask = CAL_CSI2_COMPLEXIO_CFG_CLOCK_POSITION_MASK;
u32 polarity_mask = CAL_CSI2_COMPLEXIO_CFG_CLOCK_POL_MASK;
- struct v4l2_of_bus_mipi_csi2 *mipi_csi2 = &ctx->endpoint.bus.mipi_csi2;
+ struct v4l2_fwnode_bus_mipi_csi2 *mipi_csi2 =
+ &ctx->endpoint.bus.mipi_csi2;
int lane;
set_field(&val, mipi_csi2->clock_lane + 1, lane_mask);
@@ -1643,7 +1644,7 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst)
struct platform_device *pdev = ctx->dev->pdev;
struct device_node *ep_node, *port, *remote_ep,
*sensor_node, *parent;
- struct v4l2_of_endpoint *endpoint;
+ struct v4l2_fwnode_endpoint *endpoint;
struct v4l2_async_subdev *asd;
u32 regval = 0;
int ret, index, found_port = 0, lane;
@@ -1706,7 +1707,7 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst)
ctx_dbg(3, ctx, "can't get remote-endpoint\n");
goto cleanup_exit;
}
- v4l2_of_parse_endpoint(remote_ep, endpoint);
+ v4l2_fwnode_endpoint_parse(of_fwnode_handle(remote_ep), endpoint);
if (endpoint->bus_type != V4L2_MBUS_CSI2) {
ctx_err(ctx, "Port:%d sub-device %s is not a CSI2 device\n",
diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig
index 84bae79..a5d21b7 100644
--- a/drivers/media/platform/xilinx/Kconfig
+++ b/drivers/media/platform/xilinx/Kconfig
@@ -2,6 +2,7 @@ config VIDEO_XILINX
tristate "Xilinx Video IP (EXPERIMENTAL)"
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA
select VIDEOBUF2_DMA_CONTIG
+ select V4L2_FWNODE
---help---
Driver for Xilinx Video IP Pipelines
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index feb3b2f..6a2721b 100644
--- a/drivers/media/platform/xilinx/xilinx-vipp.c
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -22,7 +22,7 @@
#include <media/v4l2-async.h>
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-of.h>
+#include <media/v4l2-fwnode.h>
#include "xilinx-dma.h"
#include "xilinx-vipp.h"
@@ -74,7 +74,7 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
struct media_pad *local_pad;
struct media_pad *remote_pad;
struct xvip_graph_entity *ent;
- struct v4l2_of_link link;
+ struct v4l2_fwnode_link link;
struct device_node *ep = NULL;
struct device_node *next;
int ret = 0;
@@ -92,7 +92,7 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
dev_dbg(xdev->dev, "processing endpoint %s\n", ep->full_name);
- ret = v4l2_of_parse_link(ep, &link);
+ ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link);
if (ret < 0) {
dev_err(xdev->dev, "failed to parse link for %s\n",
ep->full_name);
@@ -103,9 +103,10 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
* the link.
*/
if (link.local_port >= local->num_pads) {
- dev_err(xdev->dev, "invalid port number %u on %s\n",
- link.local_port, link.local_node->full_name);
- v4l2_of_put_link(&link);
+ dev_err(xdev->dev, "invalid port number %u for %s\n",
+ link.local_port,
+ to_of_node(link.local_node)->full_name);
+ v4l2_fwnode_put_link(&link);
ret = -EINVAL;
break;
}
@@ -114,25 +115,28 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
if (local_pad->flags & MEDIA_PAD_FL_SINK) {
dev_dbg(xdev->dev, "skipping sink port %s:%u\n",
- link.local_node->full_name, link.local_port);
- v4l2_of_put_link(&link);
+ to_of_node(link.local_node)->full_name,
+ link.local_port);
+ v4l2_fwnode_put_link(&link);
continue;
}
/* Skip DMA engines, they will be processed separately. */
- if (link.remote_node == xdev->dev->of_node) {
+ if (link.remote_node == of_fwnode_handle(xdev->dev->of_node)) {
dev_dbg(xdev->dev, "skipping DMA port %s:%u\n",
- link.local_node->full_name, link.local_port);
- v4l2_of_put_link(&link);
+ to_of_node(link.local_node)->full_name,
+ link.local_port);
+ v4l2_fwnode_put_link(&link);
continue;
}
/* Find the remote entity. */
- ent = xvip_graph_find_entity(xdev, link.remote_node);
+ ent = xvip_graph_find_entity(xdev,
+ to_of_node(link.remote_node));
if (ent == NULL) {
dev_err(xdev->dev, "no entity found for %s\n",
- link.remote_node->full_name);
- v4l2_of_put_link(&link);
+ to_of_node(link.remote_node)->full_name);
+ v4l2_fwnode_put_link(&link);
ret = -ENODEV;
break;
}
@@ -141,15 +145,16 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
if (link.remote_port >= remote->num_pads) {
dev_err(xdev->dev, "invalid port number %u on %s\n",
- link.remote_port, link.remote_node->full_name);
- v4l2_of_put_link(&link);
+ link.remote_port,
+ to_of_node(link.remote_node)->full_name);
+ v4l2_fwnode_put_link(&link);
ret = -EINVAL;
break;
}
remote_pad = &remote->pads[link.remote_port];
- v4l2_of_put_link(&link);
+ v4l2_fwnode_put_link(&link);
/* Create the media link. */
dev_dbg(xdev->dev, "creating %s:%u -> %s:%u link\n",
@@ -194,7 +199,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
struct media_pad *source_pad;
struct media_pad *sink_pad;
struct xvip_graph_entity *ent;
- struct v4l2_of_link link;
+ struct v4l2_fwnode_link link;
struct device_node *ep = NULL;
struct device_node *next;
struct xvip_dma *dma;
@@ -213,7 +218,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
dev_dbg(xdev->dev, "processing endpoint %s\n", ep->full_name);
- ret = v4l2_of_parse_link(ep, &link);
+ ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link);
if (ret < 0) {
dev_err(xdev->dev, "failed to parse link for %s\n",
ep->full_name);
@@ -225,7 +230,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
if (dma == NULL) {
dev_err(xdev->dev, "no DMA engine found for port %u\n",
link.local_port);
- v4l2_of_put_link(&link);
+ v4l2_fwnode_put_link(&link);
ret = -EINVAL;
break;
}
@@ -234,19 +239,21 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
dma->video.name);
/* Find the remote entity. */
- ent = xvip_graph_find_entity(xdev, link.remote_node);
+ ent = xvip_graph_find_entity(xdev,
+ to_of_node(link.remote_node));
if (ent == NULL) {
dev_err(xdev->dev, "no entity found for %s\n",
- link.remote_node->full_name);
- v4l2_of_put_link(&link);
+ to_of_node(link.remote_node)->full_name);
+ v4l2_fwnode_put_link(&link);
ret = -ENODEV;
break;
}
if (link.remote_port >= ent->entity->num_pads) {
dev_err(xdev->dev, "invalid port number %u on %s\n",
- link.remote_port, link.remote_node->full_name);
- v4l2_of_put_link(&link);
+ link.remote_port,
+ to_of_node(link.remote_node)->full_name);
+ v4l2_fwnode_put_link(&link);
ret = -EINVAL;
break;
}
@@ -263,7 +270,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
sink_pad = &dma->pad;
}
- v4l2_of_put_link(&link);
+ v4l2_fwnode_put_link(&link);
/* Create the media link. */
dev_dbg(xdev->dev, "creating %s:%u -> %s:%u link\n",
diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
index a675d8a..bc9cf51 100644
--- a/include/media/v4l2-fwnode.h
+++ b/include/media/v4l2-fwnode.h
@@ -17,10 +17,10 @@
#ifndef _V4L2_FWNODE_H
#define _V4L2_FWNODE_H
+#include <linux/errno.h>
+#include <linux/fwnode.h>
#include <linux/list.h>
#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/of_graph.h>
#include <media/v4l2-mediabus.h>
--
2.7.4
^ permalink raw reply related
* [PATCH v2 4/8] v4l: async: Provide interoperability between OF and fwnode matching
From: Sakari Ailus @ 2017-04-06 13:10 UTC (permalink / raw)
To: linux-media; +Cc: linux-acpi, devicetree, laurent.pinchart
In-Reply-To: <1491484249-11964-1-git-send-email-sakari.ailus@linux.intel.com>
OF and fwnode support are separated in V4L2 and individual drivers may
implement one of them. Sub-devices do not match with a notifier
expecting sub-devices with fwnodes, nor the other way around.
Fix this by checking for sub-device's of_node field in fwnode match and
fwnode field in OF match.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
drivers/media/v4l2-core/v4l2-async.c | 26 +++++++++++++++++++++++---
include/media/v4l2-async.h | 2 +-
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index 384ad5e..7f5d804 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -14,6 +14,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/types.h>
@@ -40,15 +41,34 @@ static bool match_devname(struct v4l2_subdev *sd,
return !strcmp(asd->match.device_name.name, dev_name(sd->dev));
}
+static bool fwnode_cmp(struct fwnode_handle *one,
+ struct fwnode_handle *theother)
+{
+ if (!one || !theother)
+ return false;
+
+ if (one->type != theother->type)
+ return false;
+
+ if (is_of_node(one))
+ return !of_node_cmp(of_node_full_name(to_of_node(one)),
+ of_node_full_name(to_of_node(theother)));
+ else
+ return one == theother;
+}
+
static bool match_of(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
{
- return !of_node_cmp(of_node_full_name(sd->of_node),
- of_node_full_name(asd->match.of.node));
+ return fwnode_cmp(sd->of_node ?
+ of_fwnode_handle(sd->of_node) : sd->fwnode,
+ of_fwnode_handle(asd->match.of.node));
}
static bool match_fwnode(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
{
- return sd->fwnode == asd->match.fwnode.fwn;
+ return fwnode_cmp(sd->of_node ?
+ of_fwnode_handle(sd->of_node) : sd->fwnode,
+ asd->match.fwnode.fwn);
}
static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index 8f552d2..df8b682 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -57,7 +57,7 @@ struct v4l2_async_subdev {
enum v4l2_async_match_type match_type;
union {
struct {
- const struct device_node *node;
+ struct device_node *node;
} of;
struct {
struct fwnode_handle *fwn;
--
2.7.4
^ permalink raw reply related
* [PATCH v2 3/8] v4l: async: Add fwnode match support
From: Sakari Ailus @ 2017-04-06 13:10 UTC (permalink / raw)
To: linux-media; +Cc: linux-acpi, devicetree, laurent.pinchart
In-Reply-To: <1491484249-11964-1-git-send-email-sakari.ailus@linux.intel.com>
Add fwnode matching to complement OF node matching. And fwnode may also be
an OF node.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
drivers/media/v4l2-core/v4l2-async.c | 12 ++++++++++++
include/media/v4l2-async.h | 5 +++++
include/media/v4l2-subdev.h | 3 +++
3 files changed, 20 insertions(+)
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index 96cc733..384ad5e 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -46,6 +46,11 @@ static bool match_of(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
of_node_full_name(asd->match.of.node));
}
+static bool match_fwnode(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
+{
+ return sd->fwnode == asd->match.fwnode.fwn;
+}
+
static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
{
if (!asd->match.custom.match)
@@ -80,6 +85,9 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *
case V4L2_ASYNC_MATCH_OF:
match = match_of;
break;
+ case V4L2_ASYNC_MATCH_FWNODE:
+ match = match_fwnode;
+ break;
default:
/* Cannot happen, unless someone breaks us */
WARN_ON(true);
@@ -158,6 +166,7 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
case V4L2_ASYNC_MATCH_DEVNAME:
case V4L2_ASYNC_MATCH_I2C:
case V4L2_ASYNC_MATCH_OF:
+ case V4L2_ASYNC_MATCH_FWNODE:
break;
default:
dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL,
@@ -282,6 +291,9 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
*/
if (!sd->of_node && sd->dev)
sd->of_node = sd->dev->of_node;
+ if (!sd->fwnode && sd->dev)
+ sd->fwnode = sd->dev->of_node ?
+ &sd->dev->of_node->fwnode : sd->dev->fwnode;
mutex_lock(&list_lock);
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index 8e2a236..8f552d2 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -32,6 +32,7 @@ struct v4l2_async_notifier;
* @V4L2_ASYNC_MATCH_DEVNAME: Match will use the device name
* @V4L2_ASYNC_MATCH_I2C: Match will check for I2C adapter ID and address
* @V4L2_ASYNC_MATCH_OF: Match will use OF node
+ * @V4L2_ASYNC_MATCH_FWNODE: Match will use firmware node
*
* This enum is used by the asyncrhronous sub-device logic to define the
* algorithm that will be used to match an asynchronous device.
@@ -41,6 +42,7 @@ enum v4l2_async_match_type {
V4L2_ASYNC_MATCH_DEVNAME,
V4L2_ASYNC_MATCH_I2C,
V4L2_ASYNC_MATCH_OF,
+ V4L2_ASYNC_MATCH_FWNODE,
};
/**
@@ -58,6 +60,9 @@ struct v4l2_async_subdev {
const struct device_node *node;
} of;
struct {
+ struct fwnode_handle *fwn;
+ } fwnode;
+ struct {
const char *name;
} device_name;
struct {
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 0ab1c5d..5f1669c 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -788,6 +788,8 @@ struct v4l2_subdev_platform_data {
* @devnode: subdev device node
* @dev: pointer to the physical device, if any
* @of_node: The device_node of the subdev, usually the same as dev->of_node.
+ * @fwnode: The fwnode_handle of the subdev, usually the same as
+ * either dev->of_node->fwnode or dev->fwnode (whichever is non-NULL).
* @async_list: Links this subdev to a global subdev_list or @notifier->done
* list.
* @asd: Pointer to respective &struct v4l2_async_subdev.
@@ -819,6 +821,7 @@ struct v4l2_subdev {
struct video_device *devnode;
struct device *dev;
struct device_node *of_node;
+ struct fwnode_handle *fwnode;
struct list_head async_list;
struct v4l2_async_subdev *asd;
struct v4l2_async_notifier *notifier;
--
2.7.4
^ permalink raw reply related
* [PATCH v2 2/8] v4l: fwnode: Support generic fwnode for parsing standardised properties
From: Sakari Ailus @ 2017-04-06 13:10 UTC (permalink / raw)
To: linux-media; +Cc: linux-acpi, devicetree, laurent.pinchart
In-Reply-To: <1491484249-11964-1-git-send-email-sakari.ailus@linux.intel.com>
The fwnode_handle is a more generic way than OF device_node to describe
firmware nodes. Instead of the OF API, use more generic fwnode API to
obtain the same information.
As the V4L2 fwnode support will be required by a small minority of e.g.
ACPI based systems (the same might actually go for OF), make this a module
instead of embedding it in the videodev module.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
drivers/media/v4l2-core/Kconfig | 3 +
drivers/media/v4l2-core/Makefile | 1 +
drivers/media/v4l2-core/v4l2-fwnode.c | 353 ++++++++++++++++++++++++++++++++++
include/media/v4l2-fwnode.h | 104 ++++++++++
4 files changed, 461 insertions(+)
create mode 100644 drivers/media/v4l2-core/v4l2-fwnode.c
create mode 100644 include/media/v4l2-fwnode.h
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 6b1b78f..a35c336 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -55,6 +55,9 @@ config V4L2_FLASH_LED_CLASS
When in doubt, say N.
+config V4L2_FWNODE
+ tristate
+
# Used by drivers that need Videobuf modules
config VIDEOBUF_GEN
tristate
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index 795a535..cf77a63 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -13,6 +13,7 @@ endif
ifeq ($(CONFIG_OF),y)
videodev-objs += v4l2-of.o
endif
+obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o
ifeq ($(CONFIG_TRACEPOINTS),y)
videodev-objs += vb2-trace.o v4l2-trace.o
endif
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
new file mode 100644
index 0000000..4f69b11
--- /dev/null
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -0,0 +1,353 @@
+/*
+ * V4L2 fwnode binding parsing library
+ *
+ * Copyright (c) 2016 Intel Corporation.
+ * Author: Sakari Ailus <sakari.ailus@linux.intel.com>
+ *
+ * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * Copyright (C) 2012 Renesas Electronics Corp.
+ * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ */
+#include <linux/acpi.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/property.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <media/v4l2-fwnode.h>
+
+static int v4l2_fwnode_endpoint_parse_csi_bus(struct fwnode_handle *fwn,
+ struct v4l2_fwnode_endpoint *vfwn)
+{
+ struct v4l2_fwnode_bus_mipi_csi2 *bus = &vfwn->bus.mipi_csi2;
+ bool have_clk_lane = false;
+ unsigned int flags = 0, lanes_used = 0;
+ unsigned int i;
+ u32 v;
+ int rval;
+
+ rval = fwnode_property_read_u32_array(fwn, "data-lanes", NULL, 0);
+ if (rval > 0) {
+ u32 array[ARRAY_SIZE(bus->data_lanes)];
+
+ bus->num_data_lanes =
+ min_t(int, ARRAY_SIZE(bus->data_lanes), rval);
+
+ fwnode_property_read_u32_array(
+ fwn, "data-lanes", array, bus->num_data_lanes);
+
+ for (i = 0; i < bus->num_data_lanes; i++) {
+ if (lanes_used & BIT(array[i]))
+ pr_warn("duplicated lane %u in data-lanes\n",
+ array[i]);
+ lanes_used |= BIT(array[i]);
+
+ bus->data_lanes[i] = array[i];
+ }
+ }
+
+ rval = fwnode_property_read_u32_array(fwn, "lane-polarities", NULL, 0);
+ if (rval > 0) {
+ u32 array[ARRAY_SIZE(bus->lane_polarities)];
+
+ if (rval < 1 + bus->num_data_lanes /* clock + data */) {
+ pr_warn("too few lane-polarities entries (need %u, got %u)\n",
+ 1 + bus->num_data_lanes, rval);
+ return -EINVAL;
+ }
+
+ fwnode_property_read_u32_array(
+ fwn, "lane-polarities", array, 1 + bus->num_data_lanes);
+
+ for (i = 0; i < 1 + bus->num_data_lanes; i++)
+ bus->lane_polarities[i] = array[i];
+ }
+
+ if (!fwnode_property_read_u32(fwn, "clock-lanes", &v)) {
+ if (lanes_used & BIT(v))
+ pr_warn("duplicated lane %u in clock-lanes\n", v);
+ lanes_used |= BIT(v);
+
+ bus->clock_lane = v;
+ have_clk_lane = true;
+ }
+
+ if (fwnode_property_present(fwn, "clock-noncontinuous"))
+ flags |= V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK;
+ else if (have_clk_lane || bus->num_data_lanes > 0)
+ flags |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+
+ bus->flags = flags;
+ vfwn->bus_type = V4L2_MBUS_CSI2;
+
+ return 0;
+}
+
+static void v4l2_fwnode_endpoint_parse_parallel_bus(
+ struct fwnode_handle *fwn, struct v4l2_fwnode_endpoint *vfwn)
+{
+ struct v4l2_fwnode_bus_parallel *bus = &vfwn->bus.parallel;
+ unsigned int flags = 0;
+ u32 v;
+
+ if (!fwnode_property_read_u32(fwn, "hsync-active", &v))
+ flags |= v ? V4L2_MBUS_HSYNC_ACTIVE_HIGH :
+ V4L2_MBUS_HSYNC_ACTIVE_LOW;
+
+ if (!fwnode_property_read_u32(fwn, "vsync-active", &v))
+ flags |= v ? V4L2_MBUS_VSYNC_ACTIVE_HIGH :
+ V4L2_MBUS_VSYNC_ACTIVE_LOW;
+
+ if (!fwnode_property_read_u32(fwn, "field-even-active", &v))
+ flags |= v ? V4L2_MBUS_FIELD_EVEN_HIGH :
+ V4L2_MBUS_FIELD_EVEN_LOW;
+ if (flags)
+ vfwn->bus_type = V4L2_MBUS_PARALLEL;
+ else
+ vfwn->bus_type = V4L2_MBUS_BT656;
+
+ if (!fwnode_property_read_u32(fwn, "pclk-sample", &v))
+ flags |= v ? V4L2_MBUS_PCLK_SAMPLE_RISING :
+ V4L2_MBUS_PCLK_SAMPLE_FALLING;
+
+ if (!fwnode_property_read_u32(fwn, "data-active", &v))
+ flags |= v ? V4L2_MBUS_DATA_ACTIVE_HIGH :
+ V4L2_MBUS_DATA_ACTIVE_LOW;
+
+ if (fwnode_property_present(fwn, "slave-mode"))
+ flags |= V4L2_MBUS_SLAVE;
+ else
+ flags |= V4L2_MBUS_MASTER;
+
+ if (!fwnode_property_read_u32(fwn, "bus-width", &v))
+ bus->bus_width = v;
+
+ if (!fwnode_property_read_u32(fwn, "data-shift", &v))
+ bus->data_shift = v;
+
+ if (!fwnode_property_read_u32(fwn, "sync-on-green-active", &v))
+ flags |= v ? V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH :
+ V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW;
+
+ bus->flags = flags;
+
+}
+
+/**
+ * v4l2_fwnode_endpoint_parse() - parse all fwnode node properties
+ * @fwn: pointer to fwnode_handle
+ * @vfwn: pointer to the V4L2 fwnode data structure
+ *
+ * All properties are optional. If none are found, we don't set any flags.
+ * This means the port has a static configuration and no properties have
+ * to be specified explicitly.
+ * If any properties that identify the bus as parallel are found and
+ * slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if we recognise
+ * the bus as serial CSI-2 and clock-noncontinuous isn't set, we set the
+ * V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag.
+ * The caller should hold a reference to @node.
+ *
+ * NOTE: This function does not parse properties the size of which is
+ * variable without a low fixed limit. Please use
+ * v4l2_fwnode_endpoint_alloc_parse() in new drivers instead.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwn,
+ struct v4l2_fwnode_endpoint *vfwn)
+{
+ int rval;
+
+ fwnode_graph_parse_endpoint(fwn, &vfwn->base);
+
+ /* Zero fields from bus_type to until the end */
+ memset(&vfwn->bus_type, 0, sizeof(*vfwn) -
+ offsetof(typeof(*vfwn), bus_type));
+
+ rval = v4l2_fwnode_endpoint_parse_csi_bus(fwn, vfwn);
+ if (rval)
+ return rval;
+ /*
+ * Parse the parallel video bus properties only if none
+ * of the MIPI CSI-2 specific properties were found.
+ */
+ if (vfwn->bus.mipi_csi2.flags == 0)
+ v4l2_fwnode_endpoint_parse_parallel_bus(fwn, vfwn);
+
+ return 0;
+}
+EXPORT_SYMBOL(v4l2_fwnode_endpoint_parse);
+
+/*
+ * v4l2_fwnode_endpoint_free() - free the V4L2 fwnode acquired by
+ * v4l2_fwnode_endpoint_alloc_parse()
+ * @fwn - the V4L2 fwnode the resources of which are to be released
+ *
+ * It is safe to call this function with NULL argument or on an
+ * V4L2 fwnode the parsing of which failed.
+ */
+void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vfwn)
+{
+ if (IS_ERR_OR_NULL(vfwn))
+ return;
+
+ kfree(vfwn->link_frequencies);
+ kfree(vfwn);
+}
+EXPORT_SYMBOL(v4l2_fwnode_endpoint_free);
+
+/**
+ * v4l2_fwnode_endpoint_alloc_parse() - parse all fwnode node properties
+ * @node: pointer to fwnode_handle
+ *
+ * All properties are optional. If none are found, we don't set any flags.
+ * This means the port has a static configuration and no properties have
+ * to be specified explicitly.
+ * If any properties that identify the bus as parallel are found and
+ * slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if we recognise
+ * the bus as serial CSI-2 and clock-noncontinuous isn't set, we set the
+ * V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag.
+ * The caller should hold a reference to @node.
+ *
+ * v4l2_fwnode_endpoint_alloc_parse() has two important differences to
+ * v4l2_fwnode_endpoint_parse():
+ *
+ * 1. It also parses variable size data and
+ *
+ * 2. The memory it has allocated to store the variable size data must
+ * be freed using v4l2_fwnode_endpoint_free() when no longer needed.
+ *
+ * Return: Pointer to v4l2_fwnode_endpoint if successful, on error a
+ * negative error code.
+ */
+struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse(
+ struct fwnode_handle *fwn)
+{
+ struct v4l2_fwnode_endpoint *vfwn;
+ int rval;
+
+ vfwn = kzalloc(sizeof(*vfwn), GFP_KERNEL);
+ if (!vfwn)
+ return ERR_PTR(-ENOMEM);
+
+ rval = v4l2_fwnode_endpoint_parse(fwn, vfwn);
+ if (rval < 0)
+ goto out_err;
+
+ rval = fwnode_property_read_u64_array(fwn, "link-frequencies",
+ NULL, 0);
+
+ if (rval < 0)
+ goto out_err;
+
+ vfwn->link_frequencies =
+ kmalloc_array(rval, sizeof(*vfwn->link_frequencies),
+ GFP_KERNEL);
+ if (!vfwn->link_frequencies) {
+ rval = -ENOMEM;
+ goto out_err;
+ }
+
+ vfwn->nr_of_link_frequencies = rval;
+
+ rval = fwnode_property_read_u64_array(
+ fwn, "link-frequencies", vfwn->link_frequencies,
+ vfwn->nr_of_link_frequencies);
+ if (rval < 0)
+ goto out_err;
+
+ return vfwn;
+
+out_err:
+ v4l2_fwnode_endpoint_free(vfwn);
+ return ERR_PTR(rval);
+}
+EXPORT_SYMBOL(v4l2_fwnode_endpoint_alloc_parse);
+
+/**
+ * v4l2_fwnode_endpoint_parse_link() - parse a link between two endpoints
+ * @node: pointer to the fwnode at the local end of the link
+ * @link: pointer to the V4L2 fwnode link data structure
+ *
+ * Fill the link structure with the local and remote nodes and port numbers.
+ * The local_node and remote_node fields are set to point to the local and
+ * remote port's parent nodes respectively (the port parent node being the
+ * parent node of the port node if that node isn't a 'ports' node, or the
+ * grand-parent node of the port node otherwise).
+ *
+ * A reference is taken to both the local and remote nodes, the caller
+ * must use v4l2_fwnode_endpoint_put_link() to drop the references
+ * when done with the link.
+ *
+ * Return: 0 on success, or -ENOLINK if the remote fwnode can't be found.
+ */
+int v4l2_fwnode_parse_link(struct fwnode_handle *__fwn,
+ struct v4l2_fwnode_link *link)
+{
+ struct fwnode_handle *fwn;
+ const char *port_prop = is_of_node(__fwn) ? "reg" : "port";
+
+ memset(link, 0, sizeof(*link));
+
+ fwn = fwnode_get_parent(__fwn);
+ fwnode_property_read_u32(fwn, port_prop, &link->local_port);
+ fwn = fwnode_get_next_parent(fwn);
+ if (is_of_node(fwn)) {
+ if (of_node_cmp(to_of_node(fwn)->name, "ports") == 0)
+ fwn = fwnode_get_next_parent(fwn);
+ } else {
+ /* The "ports" node is always there in ACPI. */
+ fwn = fwnode_get_next_parent(fwn);
+ }
+ link->local_node = fwn;
+
+ fwn = fwnode_graph_get_remote_endpoint(fwn);
+ if (!fwn) {
+ fwnode_handle_put(fwn);
+ return -ENOLINK;
+ }
+
+ fwn = fwnode_get_parent(fwn);
+ fwnode_property_read_u32(fwn, port_prop, &link->remote_port);
+ fwn = fwnode_get_next_parent(fwn);
+ if (is_of_node(fwn)) {
+ if (of_node_cmp(to_of_node(fwn)->name, "ports") == 0)
+ fwn = fwnode_get_next_parent(fwn);
+ } else {
+ /* The "ports" node is always there in ACPI. */
+ fwn = fwnode_get_next_parent(fwn);
+ }
+ link->remote_node = fwn;
+
+ return 0;
+}
+EXPORT_SYMBOL(v4l2_fwnode_parse_link);
+
+/**
+ * v4l2_fwnode_put_link() - drop references to nodes in a link
+ * @link: pointer to the V4L2 fwnode link data structure
+ *
+ * Drop references to the local and remote nodes in the link. This
+ * function must be called on every link parsed with
+ * v4l2_fwnode_parse_link().
+ */
+void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link)
+{
+ fwnode_handle_put(link->local_node);
+ fwnode_handle_put(link->remote_node);
+}
+EXPORT_SYMBOL(v4l2_fwnode_put_link);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
+MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
+MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
new file mode 100644
index 0000000..a675d8a
--- /dev/null
+++ b/include/media/v4l2-fwnode.h
@@ -0,0 +1,104 @@
+/*
+ * V4L2 fwnode binding parsing library
+ *
+ * Copyright (c) 2016 Intel Corporation.
+ * Author: Sakari Ailus <sakari.ailus@linux.intel.com>
+ *
+ * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * Copyright (C) 2012 Renesas Electronics Corp.
+ * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ */
+#ifndef _V4L2_FWNODE_H
+#define _V4L2_FWNODE_H
+
+#include <linux/list.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/of_graph.h>
+
+#include <media/v4l2-mediabus.h>
+
+struct fwnode_handle;
+
+/**
+ * struct v4l2_fwnode_bus_mipi_csi2 - MIPI CSI-2 bus data structure
+ * @flags: media bus (V4L2_MBUS_*) flags
+ * @data_lanes: an array of physical data lane indexes
+ * @clock_lane: physical lane index of the clock lane
+ * @num_data_lanes: number of data lanes
+ * @lane_polarities: polarity of the lanes. The order is the same of
+ * the physical lanes.
+ */
+struct v4l2_fwnode_bus_mipi_csi2 {
+ unsigned int flags;
+ unsigned char data_lanes[4];
+ unsigned char clock_lane;
+ unsigned short num_data_lanes;
+ bool lane_polarities[5];
+};
+
+/**
+ * struct v4l2_fwnode_bus_parallel - parallel data bus data structure
+ * @flags: media bus (V4L2_MBUS_*) flags
+ * @bus_width: bus width in bits
+ * @data_shift: data shift in bits
+ */
+struct v4l2_fwnode_bus_parallel {
+ unsigned int flags;
+ unsigned char bus_width;
+ unsigned char data_shift;
+};
+
+/**
+ * struct v4l2_fwnode_endpoint - the endpoint data structure
+ * @base: fwnode endpoint of the v4l2_fwnode
+ * @bus_type: bus type
+ * @bus: bus configuration data structure
+ * @link_frequencies: array of supported link frequencies
+ * @nr_of_link_frequencies: number of elements in link_frequenccies array
+ */
+struct v4l2_fwnode_endpoint {
+ struct fwnode_endpoint base;
+ /*
+ * Fields below this line will be zeroed by
+ * v4l2_fwnode_parse_endpoint()
+ */
+ enum v4l2_mbus_type bus_type;
+ union {
+ struct v4l2_fwnode_bus_parallel parallel;
+ struct v4l2_fwnode_bus_mipi_csi2 mipi_csi2;
+ } bus;
+ u64 *link_frequencies;
+ unsigned int nr_of_link_frequencies;
+};
+
+/**
+ * struct v4l2_fwnode_link - a link between two endpoints
+ * @local_node: pointer to device_node of this endpoint
+ * @local_port: identifier of the port this endpoint belongs to
+ * @remote_node: pointer to device_node of the remote endpoint
+ * @remote_port: identifier of the port the remote endpoint belongs to
+ */
+struct v4l2_fwnode_link {
+ struct fwnode_handle *local_node;
+ unsigned int local_port;
+ struct fwnode_handle *remote_node;
+ unsigned int remote_port;
+};
+
+int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwn,
+ struct v4l2_fwnode_endpoint *vfwn);
+struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse(
+ struct fwnode_handle *fwn);
+void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vfwn);
+int v4l2_fwnode_parse_link(struct fwnode_handle *fwn,
+ struct v4l2_fwnode_link *link);
+void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link);
+
+#endif /* _V4L2_FWNODE_H */
--
2.7.4
^ permalink raw reply related
* [PATCH v2 1/8] v4l: flash led class: Use fwnode_handle instead of device_node in init
From: Sakari Ailus @ 2017-04-06 13:10 UTC (permalink / raw)
To: linux-media-8fOc0yYH5q9zeIdxy0IIJw
Cc: linux-acpi-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw
In-Reply-To: <1491484249-11964-1-git-send-email-sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Pass the more generic fwnode_handle to the init function than the
device_node.
Signed-off-by: Sakari Ailus <sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
---
drivers/leds/leds-aat1290.c | 5 +++--
drivers/leds/leds-max77693.c | 5 +++--
drivers/media/v4l2-core/v4l2-flash-led-class.c | 11 ++++++-----
include/media/v4l2-flash-led-class.h | 4 ++--
4 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/drivers/leds/leds-aat1290.c b/drivers/leds/leds-aat1290.c
index def3cf9..a21e192 100644
--- a/drivers/leds/leds-aat1290.c
+++ b/drivers/leds/leds-aat1290.c
@@ -503,8 +503,9 @@ static int aat1290_led_probe(struct platform_device *pdev)
aat1290_init_v4l2_flash_config(led, &led_cfg, &v4l2_sd_cfg);
/* Create V4L2 Flash subdev. */
- led->v4l2_flash = v4l2_flash_init(dev, sub_node, fled_cdev, NULL,
- &v4l2_flash_ops, &v4l2_sd_cfg);
+ led->v4l2_flash = v4l2_flash_init(dev, of_fwnode_handle(sub_node),
+ fled_cdev, NULL, &v4l2_flash_ops,
+ &v4l2_sd_cfg);
if (IS_ERR(led->v4l2_flash)) {
ret = PTR_ERR(led->v4l2_flash);
goto error_v4l2_flash_init;
diff --git a/drivers/leds/leds-max77693.c b/drivers/leds/leds-max77693.c
index 1eb58ef..2d3062d 100644
--- a/drivers/leds/leds-max77693.c
+++ b/drivers/leds/leds-max77693.c
@@ -930,8 +930,9 @@ static int max77693_register_led(struct max77693_sub_led *sub_led,
max77693_init_v4l2_flash_config(sub_led, led_cfg, &v4l2_sd_cfg);
/* Register in the V4L2 subsystem. */
- sub_led->v4l2_flash = v4l2_flash_init(dev, sub_node, fled_cdev, NULL,
- &v4l2_flash_ops, &v4l2_sd_cfg);
+ sub_led->v4l2_flash = v4l2_flash_init(dev, of_fwnode_handle(sub_node),
+ fled_cdev, NULL, &v4l2_flash_ops,
+ &v4l2_sd_cfg);
if (IS_ERR(sub_led->v4l2_flash)) {
ret = PTR_ERR(sub_led->v4l2_flash);
goto err_v4l2_flash_init;
diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c
index 794e563..f430c89 100644
--- a/drivers/media/v4l2-core/v4l2-flash-led-class.c
+++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
+#include <linux/property.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <media/v4l2-flash-led-class.h>
@@ -612,7 +613,7 @@ static const struct v4l2_subdev_internal_ops v4l2_flash_subdev_internal_ops = {
static const struct v4l2_subdev_ops v4l2_flash_subdev_ops;
struct v4l2_flash *v4l2_flash_init(
- struct device *dev, struct device_node *of_node,
+ struct device *dev, struct fwnode_handle *fwn,
struct led_classdev_flash *fled_cdev,
struct led_classdev_flash *iled_cdev,
const struct v4l2_flash_ops *ops,
@@ -638,7 +639,7 @@ struct v4l2_flash *v4l2_flash_init(
v4l2_flash->iled_cdev = iled_cdev;
v4l2_flash->ops = ops;
sd->dev = dev;
- sd->of_node = of_node ? of_node : led_cdev->dev->of_node;
+ sd->fwnode = fwn ? fwn : dev_fwnode(led_cdev->dev);
v4l2_subdev_init(sd, &v4l2_flash_subdev_ops);
sd->internal_ops = &v4l2_flash_subdev_internal_ops;
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
@@ -654,7 +655,7 @@ struct v4l2_flash *v4l2_flash_init(
if (ret < 0)
goto err_init_controls;
- of_node_get(sd->of_node);
+ fwnode_handle_get(sd->fwnode);
ret = v4l2_async_register_subdev(sd);
if (ret < 0)
@@ -663,7 +664,7 @@ struct v4l2_flash *v4l2_flash_init(
return v4l2_flash;
err_async_register_sd:
- of_node_put(sd->of_node);
+ fwnode_handle_put(sd->fwnode);
v4l2_ctrl_handler_free(sd->ctrl_handler);
err_init_controls:
media_entity_cleanup(&sd->entity);
@@ -683,7 +684,7 @@ void v4l2_flash_release(struct v4l2_flash *v4l2_flash)
v4l2_async_unregister_subdev(sd);
- of_node_put(sd->of_node);
+ fwnode_handle_put(sd->fwnode);
v4l2_ctrl_handler_free(sd->ctrl_handler);
media_entity_cleanup(&sd->entity);
diff --git a/include/media/v4l2-flash-led-class.h b/include/media/v4l2-flash-led-class.h
index b0fe4d6..5695853 100644
--- a/include/media/v4l2-flash-led-class.h
+++ b/include/media/v4l2-flash-led-class.h
@@ -108,7 +108,7 @@ static inline struct v4l2_flash *v4l2_ctrl_to_v4l2_flash(struct v4l2_ctrl *c)
/**
* v4l2_flash_init - initialize V4L2 flash led sub-device
* @dev: flash device, e.g. an I2C device
- * @of_node: of_node of the LED, may be NULL if the same as device's
+ * @fwn: fwnode_handle of the LED, may be NULL if the same as device's
* @fled_cdev: LED flash class device to wrap
* @iled_cdev: LED flash class device representing indicator LED associated
* with fled_cdev, may be NULL
@@ -122,7 +122,7 @@ static inline struct v4l2_flash *v4l2_ctrl_to_v4l2_flash(struct v4l2_ctrl *c)
* PTR_ERR() to obtain the numeric return value.
*/
struct v4l2_flash *v4l2_flash_init(
- struct device *dev, struct device_node *of_node,
+ struct device *dev, struct fwnode_handle *fwn,
struct led_classdev_flash *fled_cdev,
struct led_classdev_flash *iled_cdev,
const struct v4l2_flash_ops *ops,
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 0/9] V4L2 fwnode support
From: Sakari Ailus @ 2017-04-06 13:10 UTC (permalink / raw)
To: linux-media-8fOc0yYH5q9zeIdxy0IIJw
Cc: linux-acpi-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw
Hello everyone,
This patchset adds support for fwnode to V4L2. Besides OF, also ACPI based
systems can be supported this way. By using V4L2 fwnode, the individual
drivers do not need to be aware of the underlying firmware implementation.
The patchset also removes specific V4L2 OF support and converts the
affected drivers to use V4L2 fwnode.
The patchset depends on another patchset here:
<URL:http://www.spinics.net/lists/linux-acpi/msg72973.html>
v1 of the set can be found here:
<URL:http://www.spinics.net/lists/linux-media/msg111073.html>
changes since v1:
- Use existing dev_fwnode() instead of device_fwnode_handle() added by the
ACPI graph patchset,
- Fix too long line of ^'s in ReST documentation.
Sakari Ailus (8):
v4l: flash led class: Use fwnode_handle instead of device_node in init
v4l: fwnode: Support generic fwnode for parsing standardised
properties
v4l: async: Add fwnode match support
v4l: async: Provide interoperability between OF and fwnode matching
v4l: Switch from V4L2 OF not V4L2 fwnode API
v4l: media/drv-intf/soc_mediabus.h: include dependent header file
docs-rst: media: Switch documentation to V4L2 fwnode API
v4l: Remove V4L2 OF framework in favour of V4L2 fwnode framework
Documentation/media/kapi/v4l2-core.rst | 2 +-
Documentation/media/kapi/v4l2-fwnode.rst | 3 +
Documentation/media/kapi/v4l2-of.rst | 3 -
drivers/leds/leds-aat1290.c | 5 +-
drivers/leds/leds-max77693.c | 5 +-
drivers/media/i2c/Kconfig | 9 +
drivers/media/i2c/adv7604.c | 7 +-
drivers/media/i2c/mt9v032.c | 7 +-
drivers/media/i2c/ov2659.c | 8 +-
drivers/media/i2c/s5c73m3/s5c73m3-core.c | 7 +-
drivers/media/i2c/s5k5baf.c | 6 +-
drivers/media/i2c/smiapp/Kconfig | 1 +
drivers/media/i2c/smiapp/smiapp-core.c | 29 +-
drivers/media/i2c/tc358743.c | 11 +-
drivers/media/i2c/tvp514x.c | 6 +-
drivers/media/i2c/tvp5150.c | 7 +-
drivers/media/i2c/tvp7002.c | 6 +-
drivers/media/platform/Kconfig | 3 +
drivers/media/platform/am437x/Kconfig | 1 +
drivers/media/platform/am437x/am437x-vpfe.c | 8 +-
drivers/media/platform/atmel/Kconfig | 1 +
drivers/media/platform/atmel/atmel-isc.c | 8 +-
drivers/media/platform/exynos4-is/Kconfig | 2 +
drivers/media/platform/exynos4-is/media-dev.c | 6 +-
drivers/media/platform/exynos4-is/mipi-csis.c | 6 +-
drivers/media/platform/omap3isp/isp.c | 71 ++---
drivers/media/platform/pxa_camera.c | 7 +-
drivers/media/platform/rcar-vin/Kconfig | 1 +
drivers/media/platform/rcar-vin/rcar-core.c | 6 +-
drivers/media/platform/soc_camera/Kconfig | 1 +
drivers/media/platform/soc_camera/atmel-isi.c | 7 +-
drivers/media/platform/soc_camera/soc_camera.c | 3 +-
drivers/media/platform/ti-vpe/cal.c | 11 +-
drivers/media/platform/xilinx/Kconfig | 1 +
drivers/media/platform/xilinx/xilinx-vipp.c | 59 +++--
drivers/media/v4l2-core/Kconfig | 3 +
drivers/media/v4l2-core/Makefile | 4 +-
drivers/media/v4l2-core/v4l2-async.c | 36 ++-
drivers/media/v4l2-core/v4l2-flash-led-class.c | 11 +-
drivers/media/v4l2-core/v4l2-fwnode.c | 353 +++++++++++++++++++++++++
drivers/media/v4l2-core/v4l2-of.c | 327 -----------------------
include/media/drv-intf/soc_mediabus.h | 2 +
include/media/v4l2-async.h | 7 +-
include/media/v4l2-flash-led-class.h | 4 +-
include/media/v4l2-fwnode.h | 104 ++++++++
include/media/v4l2-of.h | 128 ---------
include/media/v4l2-subdev.h | 3 +
47 files changed, 698 insertions(+), 608 deletions(-)
create mode 100644 Documentation/media/kapi/v4l2-fwnode.rst
delete mode 100644 Documentation/media/kapi/v4l2-of.rst
create mode 100644 drivers/media/v4l2-core/v4l2-fwnode.c
delete mode 100644 drivers/media/v4l2-core/v4l2-of.c
create mode 100644 include/media/v4l2-fwnode.h
delete mode 100644 include/media/v4l2-of.h
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox