* @count: Clocking reference count
* @mutex: Protects clock enable/disable
* @core: IPA core clock
+ * @interconnect_count: Number of elements in interconnect[]
* @interconnect: Interconnect array
*/
struct ipa_clock {
refcount_t count;
struct mutex mutex; /* protects clock enable/disable */
struct clk *core;
- struct ipa_interconnect interconnect[IPA_INTERCONNECT_COUNT];
+ u32 interconnect_count;
+ struct ipa_interconnect *interconnect;
};
static int ipa_interconnect_init_one(struct device *dev,
const struct ipa_interconnect_data *data)
{
struct ipa_interconnect *interconnect;
+ u32 count;
int ret;
- interconnect = &clock->interconnect[IPA_INTERCONNECT_MEMORY];
- ret = ipa_interconnect_init_one(dev, interconnect, data++);
- if (ret)
- return ret;
-
- interconnect = &clock->interconnect[IPA_INTERCONNECT_IMEM];
- ret = ipa_interconnect_init_one(dev, interconnect, data++);
- if (ret)
- goto err_memory_path_put;
-
- interconnect = &clock->interconnect[IPA_INTERCONNECT_IMEM];
- ret = ipa_interconnect_init_one(dev, interconnect, data++);
- if (ret)
- goto err_imem_path_put;
+ count = clock->interconnect_count;
+ interconnect = kcalloc(count, sizeof(*interconnect), GFP_KERNEL);
+ if (!interconnect)
+ return -ENOMEM;
+ clock->interconnect = interconnect;
+
+ while (count--) {
+ ret = ipa_interconnect_init_one(dev, interconnect, data++);
+ if (ret)
+ goto out_unwind;
+ interconnect++;
+ }
return 0;
-err_imem_path_put:
- interconnect = &clock->interconnect[IPA_INTERCONNECT_IMEM];
- ipa_interconnect_exit_one(interconnect);
-err_memory_path_put:
- interconnect = &clock->interconnect[IPA_INTERCONNECT_MEMORY];
- ipa_interconnect_exit_one(interconnect);
+out_unwind:
+ while (interconnect-- > clock->interconnect)
+ ipa_interconnect_exit_one(interconnect);
+ kfree(clock->interconnect);
+ clock->interconnect = NULL;
return ret;
}
{
struct ipa_interconnect *interconnect;
- interconnect = &clock->interconnect[IPA_INTERCONNECT_CONFIG];
- ipa_interconnect_exit_one(interconnect);
- interconnect = &clock->interconnect[IPA_INTERCONNECT_IMEM];
- ipa_interconnect_exit_one(interconnect);
- interconnect = &clock->interconnect[IPA_INTERCONNECT_MEMORY];
- ipa_interconnect_exit_one(interconnect);
+ interconnect = clock->interconnect + clock->interconnect_count;
+ while (interconnect-- > clock->interconnect)
+ ipa_interconnect_exit_one(interconnect);
+ kfree(clock->interconnect);
+ clock->interconnect = NULL;
}
/* Currently we only use one bandwidth level, so just "enable" interconnects */
struct ipa_interconnect *interconnect;
struct ipa_clock *clock = ipa->clock;
int ret;
-
- interconnect = &clock->interconnect[IPA_INTERCONNECT_MEMORY];
- ret = icc_set_bw(interconnect->path, interconnect->average_bandwidth,
- interconnect->peak_bandwidth);
- if (ret)
- return ret;
-
- interconnect = &clock->interconnect[IPA_INTERCONNECT_IMEM];
- ret = icc_set_bw(interconnect->path, interconnect->average_bandwidth,
- interconnect->peak_bandwidth);
- if (ret)
- goto err_memory_path_disable;
-
- interconnect = &clock->interconnect[IPA_INTERCONNECT_CONFIG];
- ret = icc_set_bw(interconnect->path, interconnect->average_bandwidth,
- interconnect->peak_bandwidth);
- if (ret)
- goto err_imem_path_disable;
+ u32 i;
+
+ interconnect = clock->interconnect;
+ for (i = 0; i < clock->interconnect_count; i++) {
+ ret = icc_set_bw(interconnect->path,
+ interconnect->average_bandwidth,
+ interconnect->peak_bandwidth);
+ if (ret)
+ goto out_unwind;
+ interconnect++;
+ }
return 0;
-err_imem_path_disable:
- interconnect = &clock->interconnect[IPA_INTERCONNECT_IMEM];
- (void)icc_set_bw(interconnect->path, 0, 0);
-err_memory_path_disable:
- interconnect = &clock->interconnect[IPA_INTERCONNECT_MEMORY];
- (void)icc_set_bw(interconnect->path, 0, 0);
+out_unwind:
+ while (interconnect-- > clock->interconnect)
+ (void)icc_set_bw(interconnect->path, 0, 0);
return ret;
}
struct ipa_interconnect *interconnect;
struct ipa_clock *clock = ipa->clock;
int result = 0;
+ u32 count;
int ret;
- interconnect = &clock->interconnect[IPA_INTERCONNECT_MEMORY];
- ret = icc_set_bw(interconnect->path, 0, 0);
- if (ret)
- result = ret;
-
- interconnect = &clock->interconnect[IPA_INTERCONNECT_IMEM];
- ret = icc_set_bw(interconnect->path, 0, 0);
- if (ret && !result)
- result = ret;
-
- interconnect = &clock->interconnect[IPA_INTERCONNECT_IMEM];
- ret = icc_set_bw(interconnect->path, 0, 0);
- if (ret && !result)
- result = ret;
+ count = clock->interconnect_count;
+ interconnect = clock->interconnect + count;
+ while (count--) {
+ interconnect--;
+ ret = icc_set_bw(interconnect->path, 0, 0);
+ if (ret && !result)
+ result = ret;
+ }
if (result)
dev_err(&ipa->pdev->dev,
goto err_clk_put;
}
clock->core = clk;
+ clock->interconnect_count = data->interconnect_count;
- ret = ipa_interconnect_init(clock, dev, data->interconnect);
+ ret = ipa_interconnect_init(clock, dev, data->interconnect_data);
if (ret)
goto err_kfree;
.smem_size = 0x00002000,
};
+/* Interconnect bandwidths are in 1000 byte/second units */
+static struct ipa_interconnect_data ipa_interconnect_data[] = {
+ {
+ .name = "memory",
+ .peak_bandwidth = 465000, /* 465 MBps */
+ .average_bandwidth = 80000, /* 80 MBps */
+ },
+ /* Average bandwidth is unused for the next two interconnects */
+ {
+ .name = "imem",
+ .peak_bandwidth = 68570, /* 68.570 MBps */
+ .average_bandwidth = 0, /* unused */
+ },
+ {
+ .name = "config",
+ .peak_bandwidth = 30000, /* 30 MBps */
+ .average_bandwidth = 0, /* unused */
+ },
+};
+
static struct ipa_clock_data ipa_clock_data = {
.core_clock_rate = 100 * 1000 * 1000, /* Hz */
- /* Interconnect bandwidths are in 1000 byte/second units */
- .interconnect = {
- [IPA_INTERCONNECT_MEMORY] = {
- .name = "memory",
- .peak_bandwidth = 465000, /* 465 MBps */
- .average_bandwidth = 80000, /* 80 MBps */
- },
- /* Average bandwidth unused for the next two interconnects */
- [IPA_INTERCONNECT_IMEM] = {
- .name = "imem",
- .peak_bandwidth = 68570, /* 68.57 MBps */
- .average_bandwidth = 0, /* unused */
- },
- [IPA_INTERCONNECT_CONFIG] = {
- .name = "config",
- .peak_bandwidth = 30000, /* 30 MBps */
- .average_bandwidth = 0, /* unused */
- },
- },
+ .interconnect_count = ARRAY_SIZE(ipa_interconnect_data),
+ .interconnect_data = ipa_interconnect_data,
};
/* Configuration data for the SC7180 SoC. */
.smem_size = 0x00002000,
};
+/* Interconnect bandwidths are in 1000 byte/second units */
+static struct ipa_interconnect_data ipa_interconnect_data[] = {
+ {
+ .name = "memory",
+ .peak_bandwidth = 600000, /* 600 MBps */
+ .average_bandwidth = 80000, /* 80 MBps */
+ },
+ /* Average bandwidth is unused for the next two interconnects */
+ {
+ .name = "imem",
+ .peak_bandwidth = 350000, /* 350 MBps */
+ .average_bandwidth = 0, /* unused */
+ },
+ {
+ .name = "config",
+ .peak_bandwidth = 40000, /* 40 MBps */
+ .average_bandwidth = 0, /* unused */
+ },
+};
+
static struct ipa_clock_data ipa_clock_data = {
.core_clock_rate = 75 * 1000 * 1000, /* Hz */
- /* Interconnect bandwidths are in 1000 byte/second units */
- .interconnect = {
- [IPA_INTERCONNECT_MEMORY] = {
- .name = "memory",
- .peak_bandwidth = 600000, /* 600 MBps */
- .average_bandwidth = 80000, /* 80 MBps */
- },
- /* Average bandwidth unused for the next two interconnects */
- [IPA_INTERCONNECT_IMEM] = {
- .name = "imem",
- .peak_bandwidth = 350000, /* 350 MBps */
- .average_bandwidth = 0, /* unused */
- },
- [IPA_INTERCONNECT_CONFIG] = {
- .name = "config",
- .peak_bandwidth = 40000, /* 40 MBps */
- .average_bandwidth = 0, /* unused */
- },
- },
+ .interconnect_count = ARRAY_SIZE(ipa_interconnect_data),
+ .interconnect_data = ipa_interconnect_data,
};
/* Configuration data for the SDM845 SoC. */