34
34
35
35
#define IPA_AUTOSUSPEND_DELAY 500 /* milliseconds */
36
36
37
- /**
38
- * struct ipa_interconnect - IPA interconnect information
39
- * @path: Interconnect path
40
- * @average_bandwidth: Average interconnect bandwidth (KB/second)
41
- * @peak_bandwidth: Peak interconnect bandwidth (KB/second)
42
- */
43
- struct ipa_interconnect {
44
- struct icc_path * path ;
45
- u32 average_bandwidth ;
46
- u32 peak_bandwidth ;
47
- };
48
-
49
37
/**
50
38
* enum ipa_power_flag - IPA power flags
51
39
* @IPA_POWER_FLAG_RESUMED: Whether resume from suspend has been signaled
@@ -79,164 +67,78 @@ struct ipa_power {
79
67
spinlock_t spinlock ; /* used with STOPPED/STARTED power flags */
80
68
DECLARE_BITMAP (flags , IPA_POWER_FLAG_COUNT );
81
69
u32 interconnect_count ;
82
- struct ipa_interconnect * interconnect ;
70
+ struct icc_bulk_data interconnect [] ;
83
71
};
84
72
85
- static int ipa_interconnect_init_one (struct device * dev ,
86
- struct ipa_interconnect * interconnect ,
87
- const struct ipa_interconnect_data * data )
88
- {
89
- struct icc_path * path ;
90
-
91
- path = of_icc_get (dev , data -> name );
92
- if (IS_ERR (path )) {
93
- int ret = PTR_ERR (path );
94
-
95
- dev_err_probe (dev , ret , "error getting %s interconnect\n" ,
96
- data -> name );
97
-
98
- return ret ;
99
- }
100
-
101
- interconnect -> path = path ;
102
- interconnect -> average_bandwidth = data -> average_bandwidth ;
103
- interconnect -> peak_bandwidth = data -> peak_bandwidth ;
104
-
105
- return 0 ;
106
- }
107
-
108
- static void ipa_interconnect_exit_one (struct ipa_interconnect * interconnect )
109
- {
110
- icc_put (interconnect -> path );
111
- memset (interconnect , 0 , sizeof (* interconnect ));
112
- }
113
-
114
73
/* Initialize interconnects required for IPA operation */
115
- static int ipa_interconnect_init (struct ipa_power * power , struct device * dev ,
74
+ static int ipa_interconnect_init (struct ipa_power * power ,
116
75
const struct ipa_interconnect_data * data )
117
76
{
118
- struct ipa_interconnect * interconnect ;
119
- u32 count ;
120
- int ret ;
121
-
122
- count = power -> interconnect_count ;
123
- interconnect = kcalloc (count , sizeof (* interconnect ), GFP_KERNEL );
124
- if (!interconnect )
125
- return - ENOMEM ;
126
- power -> interconnect = interconnect ;
127
-
128
- while (count -- ) {
129
- ret = ipa_interconnect_init_one (dev , interconnect , data ++ );
130
- if (ret )
131
- goto out_unwind ;
132
- interconnect ++ ;
133
- }
134
-
135
- return 0 ;
136
-
137
- out_unwind :
138
- while (interconnect -- > power -> interconnect )
139
- ipa_interconnect_exit_one (interconnect );
140
- kfree (power -> interconnect );
141
- power -> interconnect = NULL ;
142
-
143
- return ret ;
144
- }
145
-
146
- /* Inverse of ipa_interconnect_init() */
147
- static void ipa_interconnect_exit (struct ipa_power * power )
148
- {
149
- struct ipa_interconnect * interconnect ;
150
-
151
- interconnect = power -> interconnect + power -> interconnect_count ;
152
- while (interconnect -- > power -> interconnect )
153
- ipa_interconnect_exit_one (interconnect );
154
- kfree (power -> interconnect );
155
- power -> interconnect = NULL ;
156
- }
157
-
158
- /* Currently we only use one bandwidth level, so just "enable" interconnects */
159
- static int ipa_interconnect_enable (struct ipa * ipa )
160
- {
161
- struct ipa_interconnect * interconnect ;
162
- struct ipa_power * power = ipa -> power ;
77
+ struct icc_bulk_data * interconnect ;
163
78
int ret ;
164
79
u32 i ;
165
80
166
- interconnect = power -> interconnect ;
81
+ /* Initialize our interconnect data array for bulk operations */
82
+ interconnect = & power -> interconnect [0 ];
167
83
for (i = 0 ; i < power -> interconnect_count ; i ++ ) {
168
- ret = icc_set_bw (interconnect -> path ,
169
- interconnect -> average_bandwidth ,
170
- interconnect -> peak_bandwidth );
171
- if (ret ) {
172
- dev_err (& ipa -> pdev -> dev ,
173
- "error %d enabling %s interconnect\n" ,
174
- ret , icc_get_name (interconnect -> path ));
175
- goto out_unwind ;
176
- }
84
+ /* interconnect->path is filled in by of_icc_bulk_get() */
85
+ interconnect -> name = data -> name ;
86
+ interconnect -> avg_bw = data -> average_bandwidth ;
87
+ interconnect -> peak_bw = data -> peak_bandwidth ;
88
+ data ++ ;
177
89
interconnect ++ ;
178
90
}
179
91
180
- return 0 ;
92
+ ret = of_icc_bulk_get (power -> dev , power -> interconnect_count ,
93
+ power -> interconnect );
94
+ if (ret )
95
+ return ret ;
181
96
182
- out_unwind :
183
- while (interconnect -- > power -> interconnect )
184
- (void )icc_set_bw (interconnect -> path , 0 , 0 );
97
+ /* All interconnects are initially disabled */
98
+ icc_bulk_disable (power -> interconnect_count , power -> interconnect );
99
+
100
+ /* Set the bandwidth values to be used when enabled */
101
+ ret = icc_bulk_set_bw (power -> interconnect_count , power -> interconnect );
102
+ if (ret )
103
+ icc_bulk_put (power -> interconnect_count , power -> interconnect );
185
104
186
105
return ret ;
187
106
}
188
107
189
- /* To disable an interconnect, we just its bandwidth to 0 */
190
- static int ipa_interconnect_disable (struct ipa * ipa )
108
+ /* Inverse of ipa_interconnect_init() */
109
+ static void ipa_interconnect_exit (struct ipa_power * power )
191
110
{
192
- struct ipa_interconnect * interconnect ;
193
- struct ipa_power * power = ipa -> power ;
194
- struct device * dev = & ipa -> pdev -> dev ;
195
- int result = 0 ;
196
- u32 count ;
197
- int ret ;
198
-
199
- count = power -> interconnect_count ;
200
- interconnect = power -> interconnect + count ;
201
- while (count -- ) {
202
- interconnect -- ;
203
- ret = icc_set_bw (interconnect -> path , 0 , 0 );
204
- if (ret ) {
205
- dev_err (dev , "error %d disabling %s interconnect\n" ,
206
- ret , icc_get_name (interconnect -> path ));
207
- /* Try to disable all; record only the first error */
208
- if (!result )
209
- result = ret ;
210
- }
211
- }
212
-
213
- return result ;
111
+ icc_bulk_put (power -> interconnect_count , power -> interconnect );
214
112
}
215
113
216
114
/* Enable IPA power, enabling interconnects and the core clock */
217
115
static int ipa_power_enable (struct ipa * ipa )
218
116
{
117
+ struct ipa_power * power = ipa -> power ;
219
118
int ret ;
220
119
221
- ret = ipa_interconnect_enable ( ipa );
120
+ ret = icc_bulk_enable ( power -> interconnect_count , power -> interconnect );
222
121
if (ret )
223
122
return ret ;
224
123
225
- ret = clk_prepare_enable (ipa -> power -> core );
124
+ ret = clk_prepare_enable (power -> core );
226
125
if (ret ) {
227
- dev_err (& ipa -> pdev -> dev , "error %d enabling core clock\n" , ret );
228
- (void )ipa_interconnect_disable (ipa );
126
+ dev_err (power -> dev , "error %d enabling core clock\n" , ret );
127
+ icc_bulk_disable (power -> interconnect_count ,
128
+ power -> interconnect );
229
129
}
230
130
231
131
return ret ;
232
132
}
233
133
234
134
/* Inverse of ipa_power_enable() */
235
- static int ipa_power_disable (struct ipa * ipa )
135
+ static void ipa_power_disable (struct ipa * ipa )
236
136
{
237
- clk_disable_unprepare ( ipa -> power -> core ) ;
137
+ struct ipa_power * power = ipa -> power ;
238
138
239
- return ipa_interconnect_disable (ipa );
139
+ clk_disable_unprepare (power -> core );
140
+
141
+ icc_bulk_disable (power -> interconnect_count , power -> interconnect );
240
142
}
241
143
242
144
static int ipa_runtime_suspend (struct device * dev )
@@ -250,7 +152,9 @@ static int ipa_runtime_suspend(struct device *dev)
250
152
gsi_suspend (& ipa -> gsi );
251
153
}
252
154
253
- return ipa_power_disable (ipa );
155
+ ipa_power_disable (ipa );
156
+
157
+ return 0 ;
254
158
}
255
159
256
160
static int ipa_runtime_resume (struct device * dev )
@@ -453,6 +357,7 @@ ipa_power_init(struct device *dev, const struct ipa_power_data *data)
453
357
{
454
358
struct ipa_power * power ;
455
359
struct clk * clk ;
360
+ size_t size ;
456
361
int ret ;
457
362
458
363
clk = clk_get (dev , "core" );
@@ -469,7 +374,8 @@ ipa_power_init(struct device *dev, const struct ipa_power_data *data)
469
374
goto err_clk_put ;
470
375
}
471
376
472
- power = kzalloc (sizeof (* power ), GFP_KERNEL );
377
+ size = data -> interconnect_count * sizeof (power -> interconnect [0 ]);
378
+ power = kzalloc (sizeof (* power ) + size , GFP_KERNEL );
473
379
if (!power ) {
474
380
ret = - ENOMEM ;
475
381
goto err_clk_put ;
@@ -479,7 +385,7 @@ ipa_power_init(struct device *dev, const struct ipa_power_data *data)
479
385
spin_lock_init (& power -> spinlock );
480
386
power -> interconnect_count = data -> interconnect_count ;
481
387
482
- ret = ipa_interconnect_init (power , dev , data -> interconnect_data );
388
+ ret = ipa_interconnect_init (power , data -> interconnect_data );
483
389
if (ret )
484
390
goto err_kfree ;
485
391
0 commit comments