Johnny Hughes
2019-02-04 c1f36c28393a7bb126cbf436cd6a4077a5b5c313
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
From b3db52952272989cfa614893148b4939cc51e982 Mon Sep 17 00:00:00 2001
From: Marcin Wojtas <mw@semihalf.com>
Date: Thu, 18 Jan 2018 13:31:40 +0100
Subject: [PATCH 23/46] device property: Introduce fwnode_irq_get()
 
Until now there were two very similar functions allowing
to get Linux IRQ number from ACPI handle (acpi_irq_get())
and OF node (of_irq_get()). The first one appeared to be used
only as a subroutine of platform_irq_get(), which (in the generic
code) limited IRQ obtaining from _CRS method only to nodes
associated to kernel's struct platform_device.
 
This patch introduces a new helper routine - fwnode_irq_get(),
which allows to get the IRQ number directly from the fwnode
to be used as common for OF/ACPI worlds. It is usable not
only for the parents fwnodes, but also for the child nodes
comprising their own _CRS methods with interrupts description.
 
In order to be able o satisfy compilation with !CONFIG_ACPI
and also simplify the new code, introduce a helper macro
(ACPI_HANDLE_FWNODE), with which it is possible to reach
an ACPI handle directly from its fwnode.
 
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 7c6c57f2ab2c5113844fe187a7c45c4bd76dc671)
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
---
 drivers/base/property.c  | 26 ++++++++++++++++++++++++++
 include/linux/acpi.h     |  3 +++
 include/linux/property.h |  2 ++
 3 files changed, 31 insertions(+)
 
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 9f69d18..3a20e2c 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -16,6 +16,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_graph.h>
+#include <linux/of_irq.h>
 #include <linux/property.h>
 #include <linux/etherdevice.h>
 #include <linux/phy.h>
@@ -1225,6 +1226,31 @@ void *device_get_mac_address(struct device *dev, char *addr, int alen)
 EXPORT_SYMBOL(device_get_mac_address);
 
 /**
+ * fwnode_irq_get - Get IRQ directly from a fwnode
+ * @fwnode:    Pointer to the firmware node
+ * @index:    Zero-based index of the IRQ
+ *
+ * Returns Linux IRQ number on success. Other values are determined
+ * accordingly to acpi_/of_ irq_get() operation.
+ */
+int fwnode_irq_get(struct fwnode_handle *fwnode, unsigned int index)
+{
+    struct device_node *of_node = to_of_node(fwnode);
+    struct resource res;
+    int ret;
+
+    if (IS_ENABLED(CONFIG_OF) && of_node)
+        return of_irq_get(of_node, index);
+
+    ret = acpi_irq_get(ACPI_HANDLE_FWNODE(fwnode), index, &res);
+    if (ret)
+        return ret;
+
+    return res.start;
+}
+EXPORT_SYMBOL(fwnode_irq_get);
+
+/**
  * device_graph_get_next_endpoint - Get next endpoint firmware node
  * @fwnode: Pointer to the parent firmware node
  * @prev: Previous endpoint node or %NULL to get the first
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 502af53..0c9ee53 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -56,6 +56,8 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev)
 #define ACPI_COMPANION_SET(dev, adev)    set_primary_fwnode(dev, (adev) ? \
     acpi_fwnode_handle(adev) : NULL)
 #define ACPI_HANDLE(dev)        acpi_device_handle(ACPI_COMPANION(dev))
+#define ACPI_HANDLE_FWNODE(fwnode)    \
+                acpi_device_handle(to_acpi_device_node(fwnode))
 
 static inline struct fwnode_handle *acpi_alloc_fwnode_static(void)
 {
@@ -626,6 +628,7 @@ int acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem, int *timer_count)
 #define ACPI_COMPANION(dev)        (NULL)
 #define ACPI_COMPANION_SET(dev, adev)    do { } while (0)
 #define ACPI_HANDLE(dev)        (NULL)
+#define ACPI_HANDLE_FWNODE(fwnode)    (NULL)
 #define ACPI_DEVICE_CLASS(_cls, _msk)    .cls = (0), .cls_msk = (0),
 
 struct fwnode_handle;
diff --git a/include/linux/property.h b/include/linux/property.h
index d29eef4..cd70998 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -103,6 +103,8 @@ struct fwnode_handle *device_get_named_child_node(struct device *dev,
 void fwnode_handle_get(struct fwnode_handle *fwnode);
 void fwnode_handle_put(struct fwnode_handle *fwnode);
 
+int fwnode_irq_get(struct fwnode_handle *fwnode, unsigned int index);
+
 unsigned int device_get_child_node_count(struct device *dev);
 
 static inline bool device_property_read_bool(struct device *dev,
-- 
2.7.4