diff options
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/Kconfig | 1 | ||||
-rw-r--r-- | drivers/mfd/mfd-core.c | 30 |
2 files changed, 27 insertions, 4 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 8b56c1998ab2..d43876c6da23 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -7,6 +7,7 @@ menu "Multifunction device drivers" | |||
7 | 7 | ||
8 | config MFD_CORE | 8 | config MFD_CORE |
9 | tristate | 9 | tristate |
10 | select IRQ_DOMAIN | ||
10 | default n | 11 | default n |
11 | 12 | ||
12 | config MFD_88PM860X | 13 | config MFD_88PM860X |
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index ffc3d48676ae..0c3a01cde2f7 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/pm_runtime.h> | 18 | #include <linux/pm_runtime.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/irqdomain.h> | ||
22 | #include <linux/of.h> | ||
21 | 23 | ||
22 | int mfd_cell_enable(struct platform_device *pdev) | 24 | int mfd_cell_enable(struct platform_device *pdev) |
23 | { | 25 | { |
@@ -76,6 +78,8 @@ static int mfd_add_device(struct device *parent, int id, | |||
76 | { | 78 | { |
77 | struct resource *res; | 79 | struct resource *res; |
78 | struct platform_device *pdev; | 80 | struct platform_device *pdev; |
81 | struct device_node *np = NULL; | ||
82 | struct irq_domain *domain = NULL; | ||
79 | int ret = -ENOMEM; | 83 | int ret = -ENOMEM; |
80 | int r; | 84 | int r; |
81 | 85 | ||
@@ -89,6 +93,16 @@ static int mfd_add_device(struct device *parent, int id, | |||
89 | 93 | ||
90 | pdev->dev.parent = parent; | 94 | pdev->dev.parent = parent; |
91 | 95 | ||
96 | if (parent->of_node && cell->of_compatible) { | ||
97 | for_each_child_of_node(parent->of_node, np) { | ||
98 | if (of_device_is_compatible(np, cell->of_compatible)) { | ||
99 | pdev->dev.of_node = np; | ||
100 | domain = irq_find_host(parent->of_node); | ||
101 | break; | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | |||
92 | if (cell->pdata_size) { | 106 | if (cell->pdata_size) { |
93 | ret = platform_device_add_data(pdev, | 107 | ret = platform_device_add_data(pdev, |
94 | cell->platform_data, cell->pdata_size); | 108 | cell->platform_data, cell->pdata_size); |
@@ -112,10 +126,18 @@ static int mfd_add_device(struct device *parent, int id, | |||
112 | res[r].end = mem_base->start + | 126 | res[r].end = mem_base->start + |
113 | cell->resources[r].end; | 127 | cell->resources[r].end; |
114 | } else if (cell->resources[r].flags & IORESOURCE_IRQ) { | 128 | } else if (cell->resources[r].flags & IORESOURCE_IRQ) { |
115 | res[r].start = irq_base + | 129 | if (domain) { |
116 | cell->resources[r].start; | 130 | /* Unable to create mappings for IRQ ranges. */ |
117 | res[r].end = irq_base + | 131 | WARN_ON(cell->resources[r].start != |
118 | cell->resources[r].end; | 132 | cell->resources[r].end); |
133 | res[r].start = res[r].end = irq_create_mapping( | ||
134 | domain, cell->resources[r].start); | ||
135 | } else { | ||
136 | res[r].start = irq_base + | ||
137 | cell->resources[r].start; | ||
138 | res[r].end = irq_base + | ||
139 | cell->resources[r].end; | ||
140 | } | ||
119 | } else { | 141 | } else { |
120 | res[r].parent = cell->resources[r].parent; | 142 | res[r].parent = cell->resources[r].parent; |
121 | res[r].start = cell->resources[r].start; | 143 | res[r].start = cell->resources[r].start; |