aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSricharan R <r.sricharan@ti.com>2013-11-26 08:38:23 -0500
committerNishanth Menon <nm@ti.com>2014-05-05 15:33:33 -0400
commit0659452dd2b2602058b80cfdcc673e98f2a67184 (patch)
tree388e6d8d848f72e2f61466169bec7057461d1e89
parent3340d739f8e1273abd408c59ad1843ea2ac35566 (diff)
bus: omap_l3_noc: use of_match_data to pick up SoC information
DRA7xx SoC has the same l3-noc interconnect ip (as OMAP4 and OMAP5), but AM437x SoC has just 2 modules instead of 3 which other SoCs have. So, stop using direct access of array indices and use of->match data and simplify implementation to benefit future usage. While at it, rename a few very generic variables to make them omap specific. This helps us differentiate from DRA7 and AM43xx data in the future. NOTE: None of the platforms that use omap_l3_noc are non-device tree anymore. So, it is safe to assume OF match here. Signed-off-by: Sricharan R <r.sricharan@ti.com> Signed-off-by: Rajendra Nayak <rnayak@ti.com> [nm@ti.com: split, refactor and optimize logic] Signed-off-by: Nishanth Menon <nm@ti.com> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Acked-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Tested-by: Darren Etheridge <detheridge@ti.com> Tested-by: Sekhar Nori <nsekhar@ti.com>
-rw-r--r--drivers/bus/omap_l3_noc.c55
-rw-r--r--drivers/bus/omap_l3_noc.h72
2 files changed, 84 insertions, 43 deletions
diff --git a/drivers/bus/omap_l3_noc.c b/drivers/bus/omap_l3_noc.c
index 7743e86e88b1..7e0a988ad579 100644
--- a/drivers/bus/omap_l3_noc.c
+++ b/drivers/bus/omap_l3_noc.c
@@ -14,12 +14,14 @@
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 */ 16 */
17#include <linux/module.h>
18#include <linux/init.h> 17#include <linux/init.h>
19#include <linux/io.h>
20#include <linux/platform_device.h>
21#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/io.h>
22#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/of_device.h>
23#include <linux/of.h>
24#include <linux/platform_device.h>
23#include <linux/slab.h> 25#include <linux/slab.h>
24 26
25#include "omap_l3_noc.h" 27#include "omap_l3_noc.h"
@@ -58,17 +60,18 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3)
58 void __iomem *l3_targ_stderr, *l3_targ_slvofslsb, *l3_targ_mstaddr; 60 void __iomem *l3_targ_stderr, *l3_targ_slvofslsb, *l3_targ_mstaddr;
59 char *target_name, *master_name = "UN IDENTIFIED"; 61 char *target_name, *master_name = "UN IDENTIFIED";
60 struct l3_target_data *l3_targ_inst; 62 struct l3_target_data *l3_targ_inst;
63 struct l3_masters_data *master;
61 64
62 /* Get the Type of interrupt */ 65 /* Get the Type of interrupt */
63 inttype = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR; 66 inttype = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR;
64 67
65 for (i = 0; i < L3_MODULES; i++) { 68 for (i = 0; i < l3->num_modules; i++) {
66 /* 69 /*
67 * Read the regerr register of the clock domain 70 * Read the regerr register of the clock domain
68 * to determine the source 71 * to determine the source
69 */ 72 */
70 base = l3->l3_base[i]; 73 base = l3->l3_base[i];
71 err_reg = readl_relaxed(base + l3_flagmux[i] + 74 err_reg = readl_relaxed(base + l3->l3_flagmux[i] +
72 L3_FLAGMUX_REGERR0 + (inttype << 3)); 75 L3_FLAGMUX_REGERR0 + (inttype << 3));
73 76
74 /* Get the corresponding error and analyse */ 77 /* Get the corresponding error and analyse */
@@ -79,7 +82,7 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3)
79 /* We DONOT expect err_src to go out of bounds */ 82 /* We DONOT expect err_src to go out of bounds */
80 BUG_ON(err_src > MAX_CLKDM_TARGETS); 83 BUG_ON(err_src > MAX_CLKDM_TARGETS);
81 84
82 l3_targ_inst = &l3_targ[i][err_src]; 85 l3_targ_inst = &l3->l3_targ[i][err_src];
83 target_name = l3_targ_inst->name; 86 target_name = l3_targ_inst->name;
84 l3_targ_base = base + l3_targ_inst->offset; 87 l3_targ_base = base + l3_targ_inst->offset;
85 88
@@ -101,7 +104,7 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3)
101 inttype ? "debug" : "application", 104 inttype ? "debug" : "application",
102 err_src, i, "(unclearable)"); 105 err_src, i, "(unclearable)");
103 106
104 mask_reg = base + l3_flagmux[i] + 107 mask_reg = base + l3->l3_flagmux[i] +
105 L3_FLAGMUX_MASK0 + (inttype << 3); 108 L3_FLAGMUX_MASK0 + (inttype << 3);
106 mask_val = readl_relaxed(mask_reg); 109 mask_val = readl_relaxed(mask_reg);
107 mask_val &= ~(1 << err_src); 110 mask_val &= ~(1 << err_src);
@@ -131,10 +134,12 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3)
131 break; 134 break;
132 135
133 case CUSTOM_ERROR: 136 case CUSTOM_ERROR:
134 for (k = 0; k < NUM_OF_L3_MASTERS; k++) { 137 for (k = 0, master = l3->l3_masters;
135 if (masterid == l3_masters[k].id) 138 k < l3->num_masters; k++, master++) {
136 master_name = 139 if (masterid == master->id) {
137 l3_masters[k].name; 140 master_name = master->name;
141 break;
142 }
138 } 143 }
139 WARN(true, "L3 custom error: MASTER:%s TARGET:%s\n", 144 WARN(true, "L3 custom error: MASTER:%s TARGET:%s\n",
140 master_name, target_name); 145 master_name, target_name);
@@ -154,20 +159,34 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3)
154 return IRQ_HANDLED; 159 return IRQ_HANDLED;
155} 160}
156 161
162static const struct of_device_id l3_noc_match[] = {
163 {.compatible = "ti,omap4-l3-noc", .data = &omap_l3_data},
164 {},
165};
166MODULE_DEVICE_TABLE(of, l3_noc_match);
167
157static int omap_l3_probe(struct platform_device *pdev) 168static int omap_l3_probe(struct platform_device *pdev)
158{ 169{
170 const struct of_device_id *of_id;
159 static struct omap_l3 *l3; 171 static struct omap_l3 *l3;
160 int ret, i; 172 int ret, i;
161 173
174 of_id = of_match_device(l3_noc_match, &pdev->dev);
175 if (!of_id) {
176 dev_err(&pdev->dev, "OF data missing\n");
177 return -EINVAL;
178 }
179
162 l3 = devm_kzalloc(&pdev->dev, sizeof(*l3), GFP_KERNEL); 180 l3 = devm_kzalloc(&pdev->dev, sizeof(*l3), GFP_KERNEL);
163 if (!l3) 181 if (!l3)
164 return -ENOMEM; 182 return -ENOMEM;
165 183
184 memcpy(l3, of_id->data, sizeof(*l3));
166 l3->dev = &pdev->dev; 185 l3->dev = &pdev->dev;
167 platform_set_drvdata(pdev, l3); 186 platform_set_drvdata(pdev, l3);
168 187
169 /* Get mem resources */ 188 /* Get mem resources */
170 for (i = 0; i < L3_MODULES; i++) { 189 for (i = 0; i < l3->num_modules; i++) {
171 struct resource *res = platform_get_resource(pdev, 190 struct resource *res = platform_get_resource(pdev,
172 IORESOURCE_MEM, i); 191 IORESOURCE_MEM, i);
173 192
@@ -199,22 +218,12 @@ static int omap_l3_probe(struct platform_device *pdev)
199 return ret; 218 return ret;
200} 219}
201 220
202#if defined(CONFIG_OF)
203static const struct of_device_id l3_noc_match[] = {
204 {.compatible = "ti,omap4-l3-noc", },
205 {},
206};
207MODULE_DEVICE_TABLE(of, l3_noc_match);
208#else
209#define l3_noc_match NULL
210#endif
211
212static struct platform_driver omap_l3_driver = { 221static struct platform_driver omap_l3_driver = {
213 .probe = omap_l3_probe, 222 .probe = omap_l3_probe,
214 .driver = { 223 .driver = {
215 .name = "omap_l3_noc", 224 .name = "omap_l3_noc",
216 .owner = THIS_MODULE, 225 .owner = THIS_MODULE,
217 .of_match_table = l3_noc_match, 226 .of_match_table = of_match_ptr(l3_noc_match),
218 }, 227 },
219}; 228};
220 229
diff --git a/drivers/bus/omap_l3_noc.h b/drivers/bus/omap_l3_noc.h
index 66caeceaf123..e60865fe5965 100644
--- a/drivers/bus/omap_l3_noc.h
+++ b/drivers/bus/omap_l3_noc.h
@@ -17,7 +17,9 @@
17#ifndef __OMAP_L3_NOC_H 17#ifndef __OMAP_L3_NOC_H
18#define __OMAP_L3_NOC_H 18#define __OMAP_L3_NOC_H
19 19
20#define L3_MODULES 3 20#define OMAP_L3_MODULES 3
21#define MAX_L3_MODULES 3
22
21#define CLEAR_STDERR_LOG (1 << 31) 23#define CLEAR_STDERR_LOG (1 << 31)
22#define CUSTOM_ERROR 0x2 24#define CUSTOM_ERROR 0x2
23#define STANDARD_ERROR 0x0 25#define STANDARD_ERROR 0x0
@@ -36,8 +38,6 @@
36 38
37#define MAX_CLKDM_TARGETS 31 39#define MAX_CLKDM_TARGETS 31
38 40
39#define NUM_OF_L3_MASTERS (sizeof(l3_masters)/sizeof(l3_masters[0]))
40
41/** 41/**
42 * struct l3_masters_data - L3 Master information 42 * struct l3_masters_data - L3 Master information
43 * @id: ID of the L3 Master 43 * @id: ID of the L3 Master
@@ -60,13 +60,47 @@ struct l3_target_data {
60 char *name; 60 char *name;
61}; 61};
62 62
63static u32 l3_flagmux[L3_MODULES] = { 63
64/**
65 * struct omap_l3 - Description of data relevant for L3 bus.
66 * @dev: device representing the bus (populated runtime)
67 * @l3_base: base addresses of modules (populated runtime)
68 * @l3_flag_mux: array containing offsets to flag mux per module
69 * offset from corresponding module base indexed per
70 * module.
71 * @num_modules: number of clock domains / modules.
72 * @l3_masters: array pointing to master data containing name and register
73 * offset for the master.
74 * @num_master: number of masters
75 * @l3_targ: array indexed by flagmux index (bit offset) pointing to the
76 * target data. unsupported ones are marked with
77 * L3_TARGET_NOT_SUPPORTED
78 * @debug_irq: irq number of the debug interrupt (populated runtime)
79 * @app_irq: irq number of the application interrupt (populated runtime)
80 */
81struct omap_l3 {
82 struct device *dev;
83
84 void __iomem *l3_base[MAX_L3_MODULES];
85 u32 *l3_flagmux;
86 int num_modules;
87
88 struct l3_masters_data *l3_masters;
89 int num_masters;
90
91 struct l3_target_data **l3_targ;
92
93 int debug_irq;
94 int app_irq;
95};
96
97static u32 omap_l3_flagmux[OMAP_L3_MODULES] = {
64 0x500, 98 0x500,
65 0x1000, 99 0x1000,
66 0X0200 100 0X0200
67}; 101};
68 102
69static struct l3_target_data l3_target_inst_data_clk1[MAX_CLKDM_TARGETS] = { 103static struct l3_target_data omap_l3_target_data_clk1[MAX_CLKDM_TARGETS] = {
70 {0x100, "DMM1",}, 104 {0x100, "DMM1",},
71 {0x200, "DMM2",}, 105 {0x200, "DMM2",},
72 {0x300, "ABE",}, 106 {0x300, "ABE",},
@@ -76,7 +110,7 @@ static struct l3_target_data l3_target_inst_data_clk1[MAX_CLKDM_TARGETS] = {
76 {0x900, "L4WAKEUP",}, 110 {0x900, "L4WAKEUP",},
77}; 111};
78 112
79static struct l3_target_data l3_target_inst_data_clk2[MAX_CLKDM_TARGETS] = { 113static struct l3_target_data omap_l3_target_data_clk2[MAX_CLKDM_TARGETS] = {
80 {0x500, "CORTEXM3",}, 114 {0x500, "CORTEXM3",},
81 {0x300, "DSS",}, 115 {0x300, "DSS",},
82 {0x100, "GPMC",}, 116 {0x100, "GPMC",},
@@ -100,13 +134,13 @@ static struct l3_target_data l3_target_inst_data_clk2[MAX_CLKDM_TARGETS] = {
100 {0x1700, "LLI",}, 134 {0x1700, "LLI",},
101}; 135};
102 136
103static struct l3_target_data l3_target_inst_data_clk3[MAX_CLKDM_TARGETS] = { 137static struct l3_target_data omap_l3_target_data_clk3[MAX_CLKDM_TARGETS] = {
104 {0x0100, "EMUSS",}, 138 {0x0100, "EMUSS",},
105 {0x0300, "DEBUG SOURCE",}, 139 {0x0300, "DEBUG SOURCE",},
106 {0x0, "HOST CLK3",}, 140 {0x0, "HOST CLK3",},
107}; 141};
108 142
109static struct l3_masters_data l3_masters[] = { 143static struct l3_masters_data omap_l3_masters[] = {
110 { 0x0 , "MPU"}, 144 { 0x0 , "MPU"},
111 { 0x10, "CS_ADP"}, 145 { 0x10, "CS_ADP"},
112 { 0x14, "xxx"}, 146 { 0x14, "xxx"},
@@ -134,20 +168,18 @@ static struct l3_masters_data l3_masters[] = {
134 { 0xC8, "USBHOSTFS"} 168 { 0xC8, "USBHOSTFS"}
135}; 169};
136 170
137static struct l3_target_data *l3_targ[L3_MODULES] = { 171static struct l3_target_data *omap_l3_targ[OMAP_L3_MODULES] = {
138 l3_target_inst_data_clk1, 172 omap_l3_target_data_clk1,
139 l3_target_inst_data_clk2, 173 omap_l3_target_data_clk2,
140 l3_target_inst_data_clk3, 174 omap_l3_target_data_clk3,
141}; 175};
142 176
143struct omap_l3 { 177static const struct omap_l3 omap_l3_data = {
144 struct device *dev; 178 .l3_flagmux = omap_l3_flagmux,
145 179 .num_modules = OMAP_L3_MODULES,
146 /* memory base */ 180 .l3_masters = omap_l3_masters,
147 void __iomem *l3_base[L3_MODULES]; 181 .num_masters = ARRAY_SIZE(omap_l3_masters),
148 182 .l3_targ = omap_l3_targ,
149 int debug_irq;
150 int app_irq;
151}; 183};
152 184
153#endif /* __OMAP_L3_NOC_H */ 185#endif /* __OMAP_L3_NOC_H */