|
@@ -90,8 +90,6 @@ static int aead_pri = 150;
|
|
|
module_param(aead_pri, int, 0644);
|
|
|
MODULE_PARM_DESC(aead_pri, "Priority for AEAD algos");
|
|
|
|
|
|
-#define MAX_SPUS 16
|
|
|
-
|
|
|
/* A type 3 BCM header, expected to precede the SPU header for SPU-M.
|
|
|
* Bits 3 and 4 in the first byte encode the channel number (the dma ringset).
|
|
|
* 0x60 - ring 0
|
|
@@ -120,7 +118,7 @@ static u8 select_channel(void)
|
|
|
{
|
|
|
u8 chan_idx = atomic_inc_return(&iproc_priv.next_chan);
|
|
|
|
|
|
- return chan_idx % iproc_priv.spu.num_spu;
|
|
|
+ return chan_idx % iproc_priv.spu.num_chan;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -4528,8 +4526,13 @@ static void spu_functions_register(struct device *dev,
|
|
|
*/
|
|
|
static int spu_mb_init(struct device *dev)
|
|
|
{
|
|
|
- struct mbox_client *mcl = &iproc_priv.mcl[iproc_priv.spu.num_spu];
|
|
|
- int err;
|
|
|
+ struct mbox_client *mcl = &iproc_priv.mcl;
|
|
|
+ int err, i;
|
|
|
+
|
|
|
+ iproc_priv.mbox = devm_kcalloc(dev, iproc_priv.spu.num_chan,
|
|
|
+ sizeof(struct mbox_chan *), GFP_KERNEL);
|
|
|
+ if (!iproc_priv.mbox)
|
|
|
+ return -ENOMEM;
|
|
|
|
|
|
mcl->dev = dev;
|
|
|
mcl->tx_block = false;
|
|
@@ -4538,25 +4541,33 @@ static int spu_mb_init(struct device *dev)
|
|
|
mcl->rx_callback = spu_rx_callback;
|
|
|
mcl->tx_done = NULL;
|
|
|
|
|
|
- iproc_priv.mbox[iproc_priv.spu.num_spu] =
|
|
|
- mbox_request_channel(mcl, 0);
|
|
|
- if (IS_ERR(iproc_priv.mbox[iproc_priv.spu.num_spu])) {
|
|
|
- err = (int)PTR_ERR(iproc_priv.mbox[iproc_priv.spu.num_spu]);
|
|
|
- dev_err(dev,
|
|
|
- "Mbox channel %d request failed with err %d",
|
|
|
- iproc_priv.spu.num_spu, err);
|
|
|
- iproc_priv.mbox[iproc_priv.spu.num_spu] = NULL;
|
|
|
- return err;
|
|
|
+ for (i = 0; i < iproc_priv.spu.num_chan; i++) {
|
|
|
+ iproc_priv.mbox[i] = mbox_request_channel(mcl, i);
|
|
|
+ if (IS_ERR(iproc_priv.mbox[i])) {
|
|
|
+ err = (int)PTR_ERR(iproc_priv.mbox[i]);
|
|
|
+ dev_err(dev,
|
|
|
+ "Mbox channel %d request failed with err %d",
|
|
|
+ i, err);
|
|
|
+ iproc_priv.mbox[i] = NULL;
|
|
|
+ goto free_channels;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
+free_channels:
|
|
|
+ for (i = 0; i < iproc_priv.spu.num_chan; i++) {
|
|
|
+ if (iproc_priv.mbox[i])
|
|
|
+ mbox_free_channel(iproc_priv.mbox[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ return err;
|
|
|
}
|
|
|
|
|
|
static void spu_mb_release(struct platform_device *pdev)
|
|
|
{
|
|
|
int i;
|
|
|
|
|
|
- for (i = 0; i < iproc_priv.spu.num_spu; i++)
|
|
|
+ for (i = 0; i < iproc_priv.spu.num_chan; i++)
|
|
|
mbox_free_channel(iproc_priv.mbox[i]);
|
|
|
}
|
|
|
|
|
@@ -4567,7 +4578,7 @@ static void spu_counters_init(void)
|
|
|
|
|
|
atomic_set(&iproc_priv.session_count, 0);
|
|
|
atomic_set(&iproc_priv.stream_count, 0);
|
|
|
- atomic_set(&iproc_priv.next_chan, (int)iproc_priv.spu.num_spu);
|
|
|
+ atomic_set(&iproc_priv.next_chan, (int)iproc_priv.spu.num_chan);
|
|
|
atomic64_set(&iproc_priv.bytes_in, 0);
|
|
|
atomic64_set(&iproc_priv.bytes_out, 0);
|
|
|
for (i = 0; i < SPU_OP_NUM; i++) {
|
|
@@ -4809,8 +4820,11 @@ static int spu_dt_read(struct platform_device *pdev)
|
|
|
struct resource *spu_ctrl_regs;
|
|
|
const struct of_device_id *match;
|
|
|
const struct spu_type_subtype *matched_spu_type;
|
|
|
- void __iomem *spu_reg_vbase[MAX_SPUS];
|
|
|
- int err;
|
|
|
+ struct device_node *dn = pdev->dev.of_node;
|
|
|
+ int err, i;
|
|
|
+
|
|
|
+ /* Count number of mailbox channels */
|
|
|
+ spu->num_chan = of_count_phandle_with_args(dn, "mboxes", "#mbox-cells");
|
|
|
|
|
|
match = of_match_device(of_match_ptr(bcm_spu_dt_ids), dev);
|
|
|
if (!match) {
|
|
@@ -4820,41 +4834,24 @@ static int spu_dt_read(struct platform_device *pdev)
|
|
|
|
|
|
matched_spu_type = match->data;
|
|
|
|
|
|
- if (iproc_priv.spu.num_spu > 1) {
|
|
|
- /* If this is 2nd or later SPU, make sure it's same type */
|
|
|
- if ((spu->spu_type != matched_spu_type->type) ||
|
|
|
- (spu->spu_subtype != matched_spu_type->subtype)) {
|
|
|
- err = -EINVAL;
|
|
|
- dev_err(&pdev->dev, "Multiple SPU types not allowed");
|
|
|
- return err;
|
|
|
- }
|
|
|
- } else {
|
|
|
- /* Record type of first SPU */
|
|
|
- spu->spu_type = matched_spu_type->type;
|
|
|
- spu->spu_subtype = matched_spu_type->subtype;
|
|
|
- }
|
|
|
+ spu->spu_type = matched_spu_type->type;
|
|
|
+ spu->spu_subtype = matched_spu_type->subtype;
|
|
|
|
|
|
- /* Get and map SPU registers */
|
|
|
- spu_ctrl_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
|
- if (!spu_ctrl_regs) {
|
|
|
- err = -EINVAL;
|
|
|
- dev_err(&pdev->dev, "Invalid/missing registers for SPU\n");
|
|
|
- return err;
|
|
|
- }
|
|
|
+ i = 0;
|
|
|
+ for (i = 0; (i < MAX_SPUS) && ((spu_ctrl_regs =
|
|
|
+ platform_get_resource(pdev, IORESOURCE_MEM, i)) != NULL); i++) {
|
|
|
|
|
|
- spu_reg_vbase[iproc_priv.spu.num_spu] =
|
|
|
- devm_ioremap_resource(dev, spu_ctrl_regs);
|
|
|
- if (IS_ERR(spu_reg_vbase[iproc_priv.spu.num_spu])) {
|
|
|
- err = PTR_ERR(spu_reg_vbase[iproc_priv.spu.num_spu]);
|
|
|
- dev_err(&pdev->dev, "Failed to map registers: %d\n",
|
|
|
- err);
|
|
|
- spu_reg_vbase[iproc_priv.spu.num_spu] = NULL;
|
|
|
- return err;
|
|
|
+ spu->reg_vbase[i] = devm_ioremap_resource(dev, spu_ctrl_regs);
|
|
|
+ if (IS_ERR(spu->reg_vbase[i])) {
|
|
|
+ err = PTR_ERR(spu->reg_vbase[i]);
|
|
|
+ dev_err(&pdev->dev, "Failed to map registers: %d\n",
|
|
|
+ err);
|
|
|
+ spu->reg_vbase[i] = NULL;
|
|
|
+ return err;
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- dev_dbg(dev, "SPU %d detected.", iproc_priv.spu.num_spu);
|
|
|
-
|
|
|
- spu->reg_vbase[iproc_priv.spu.num_spu] = spu_reg_vbase;
|
|
|
+ spu->num_spu = i;
|
|
|
+ dev_dbg(dev, "Device has %d SPUs", spu->num_spu);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -4865,8 +4862,8 @@ int bcm_spu_probe(struct platform_device *pdev)
|
|
|
struct spu_hw *spu = &iproc_priv.spu;
|
|
|
int err = 0;
|
|
|
|
|
|
- iproc_priv.pdev[iproc_priv.spu.num_spu] = pdev;
|
|
|
- platform_set_drvdata(iproc_priv.pdev[iproc_priv.spu.num_spu],
|
|
|
+ iproc_priv.pdev = pdev;
|
|
|
+ platform_set_drvdata(iproc_priv.pdev,
|
|
|
&iproc_priv);
|
|
|
|
|
|
err = spu_dt_read(pdev);
|
|
@@ -4877,12 +4874,6 @@ int bcm_spu_probe(struct platform_device *pdev)
|
|
|
if (err < 0)
|
|
|
goto failure;
|
|
|
|
|
|
- iproc_priv.spu.num_spu++;
|
|
|
-
|
|
|
- /* If already initialized, we've just added another SPU and are done */
|
|
|
- if (iproc_priv.inited)
|
|
|
- return 0;
|
|
|
-
|
|
|
if (spu->spu_type == SPU_TYPE_SPUM)
|
|
|
iproc_priv.bcm_hdr_len = 8;
|
|
|
else if (spu->spu_type == SPU_TYPE_SPU2)
|
|
@@ -4898,8 +4889,6 @@ int bcm_spu_probe(struct platform_device *pdev)
|
|
|
if (err < 0)
|
|
|
goto fail_reg;
|
|
|
|
|
|
- iproc_priv.inited = true;
|
|
|
-
|
|
|
return 0;
|
|
|
|
|
|
fail_reg:
|