Skip to content

Commit 63f13b2

Browse files
committed
Merge branch 'net-ipa-use-bulk-interconnect-interfaces'
Alex Elder says: ==================== net: ipa: use bulk interconnect interfaces The IPA code currently enables and disables interconnects by setting the bandwidth of each to a non-zero value, or to zero. The interconnect API now supports enable/disable functions, so we can use those instead. In addition, the interconnect API provides bulk interfaces that allow all interconnects to be operated on at once. This series converts the IPA driver to use the bulk enable and disable interfaces. In the process it uses some existing data structures rather than defining new ones. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents c17c405 + 37e0cf3 commit 63f13b2

File tree

1 file changed

+42
-136
lines changed

1 file changed

+42
-136
lines changed

drivers/net/ipa/ipa_power.c

Lines changed: 42 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,6 @@
3434

3535
#define IPA_AUTOSUSPEND_DELAY 500 /* milliseconds */
3636

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-
4937
/**
5038
* enum ipa_power_flag - IPA power flags
5139
* @IPA_POWER_FLAG_RESUMED: Whether resume from suspend has been signaled
@@ -79,164 +67,78 @@ struct ipa_power {
7967
spinlock_t spinlock; /* used with STOPPED/STARTED power flags */
8068
DECLARE_BITMAP(flags, IPA_POWER_FLAG_COUNT);
8169
u32 interconnect_count;
82-
struct ipa_interconnect *interconnect;
70+
struct icc_bulk_data interconnect[];
8371
};
8472

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-
11473
/* 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,
11675
const struct ipa_interconnect_data *data)
11776
{
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;
16378
int ret;
16479
u32 i;
16580

166-
interconnect = power->interconnect;
81+
/* Initialize our interconnect data array for bulk operations */
82+
interconnect = &power->interconnect[0];
16783
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++;
17789
interconnect++;
17890
}
17991

180-
return 0;
92+
ret = of_icc_bulk_get(power->dev, power->interconnect_count,
93+
power->interconnect);
94+
if (ret)
95+
return ret;
18196

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);
185104

186105
return ret;
187106
}
188107

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)
191110
{
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);
214112
}
215113

216114
/* Enable IPA power, enabling interconnects and the core clock */
217115
static int ipa_power_enable(struct ipa *ipa)
218116
{
117+
struct ipa_power *power = ipa->power;
219118
int ret;
220119

221-
ret = ipa_interconnect_enable(ipa);
120+
ret = icc_bulk_enable(power->interconnect_count, power->interconnect);
222121
if (ret)
223122
return ret;
224123

225-
ret = clk_prepare_enable(ipa->power->core);
124+
ret = clk_prepare_enable(power->core);
226125
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);
229129
}
230130

231131
return ret;
232132
}
233133

234134
/* Inverse of ipa_power_enable() */
235-
static int ipa_power_disable(struct ipa *ipa)
135+
static void ipa_power_disable(struct ipa *ipa)
236136
{
237-
clk_disable_unprepare(ipa->power->core);
137+
struct ipa_power *power = ipa->power;
238138

239-
return ipa_interconnect_disable(ipa);
139+
clk_disable_unprepare(power->core);
140+
141+
icc_bulk_disable(power->interconnect_count, power->interconnect);
240142
}
241143

242144
static int ipa_runtime_suspend(struct device *dev)
@@ -250,7 +152,9 @@ static int ipa_runtime_suspend(struct device *dev)
250152
gsi_suspend(&ipa->gsi);
251153
}
252154

253-
return ipa_power_disable(ipa);
155+
ipa_power_disable(ipa);
156+
157+
return 0;
254158
}
255159

256160
static int ipa_runtime_resume(struct device *dev)
@@ -453,6 +357,7 @@ ipa_power_init(struct device *dev, const struct ipa_power_data *data)
453357
{
454358
struct ipa_power *power;
455359
struct clk *clk;
360+
size_t size;
456361
int ret;
457362

458363
clk = clk_get(dev, "core");
@@ -469,7 +374,8 @@ ipa_power_init(struct device *dev, const struct ipa_power_data *data)
469374
goto err_clk_put;
470375
}
471376

472-
power = kzalloc(sizeof(*power), GFP_KERNEL);
377+
size = data->interconnect_count * sizeof(power->interconnect[0]);
378+
power = kzalloc(sizeof(*power) + size, GFP_KERNEL);
473379
if (!power) {
474380
ret = -ENOMEM;
475381
goto err_clk_put;
@@ -479,7 +385,7 @@ ipa_power_init(struct device *dev, const struct ipa_power_data *data)
479385
spin_lock_init(&power->spinlock);
480386
power->interconnect_count = data->interconnect_count;
481387

482-
ret = ipa_interconnect_init(power, dev, data->interconnect_data);
388+
ret = ipa_interconnect_init(power, data->interconnect_data);
483389
if (ret)
484390
goto err_kfree;
485391

0 commit comments

Comments
 (0)