ebc7318578cb9965423b5e2debd57e0f57bbb97b
[openwrt/staging/xback.git] /
1 From e618447cf492d04415007336eec025fae6e9a2ea Mon Sep 17 00:00:00 2001
2 From: Lorenzo Bianconi <lorenzo@kernel.org>
3 Date: Thu, 1 Aug 2024 16:35:08 +0200
4 Subject: [PATCH 6/8] net: airoha: Allow mapping IO region for multiple qdma
5 controllers
6
7 Map MMIO regions of both qdma controllers available on EN7581 SoC.
8 Run airoha_hw_cleanup routine for both QDMA controllers available on
9 EN7581 SoC removing airoha_eth module or in airoha_probe error path.
10 This is a preliminary patch to support multi-QDMA controllers.
11
12 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
13 Link: https://patch.msgid.link/a734ae608da14b67ae749b375d880dbbc70868ea.1722522582.git.lorenzo@kernel.org
14 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
15 ---
16 drivers/net/ethernet/mediatek/airoha_eth.c | 56 ++++++++++++----------
17 1 file changed, 32 insertions(+), 24 deletions(-)
18
19 --- a/drivers/net/ethernet/mediatek/airoha_eth.c
20 +++ b/drivers/net/ethernet/mediatek/airoha_eth.c
21 @@ -2024,15 +2024,25 @@ static irqreturn_t airoha_irq_handler(in
22 }
23
24 static int airoha_qdma_init(struct platform_device *pdev,
25 - struct airoha_eth *eth)
26 + struct airoha_eth *eth,
27 + struct airoha_qdma *qdma)
28 {
29 - struct airoha_qdma *qdma = &eth->qdma[0];
30 - int err;
31 + int err, id = qdma - &eth->qdma[0];
32 + const char *res;
33
34 spin_lock_init(&qdma->irq_lock);
35 qdma->eth = eth;
36
37 - qdma->irq = platform_get_irq(pdev, 0);
38 + res = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d", id);
39 + if (!res)
40 + return -ENOMEM;
41 +
42 + qdma->regs = devm_platform_ioremap_resource_byname(pdev, res);
43 + if (IS_ERR(qdma->regs))
44 + return dev_err_probe(eth->dev, PTR_ERR(qdma->regs),
45 + "failed to iomap qdma%d regs\n", id);
46 +
47 + qdma->irq = platform_get_irq(pdev, 4 * id);
48 if (qdma->irq < 0)
49 return qdma->irq;
50
51 @@ -2053,19 +2063,13 @@ static int airoha_qdma_init(struct platf
52 if (err)
53 return err;
54
55 - err = airoha_qdma_hw_init(qdma);
56 - if (err)
57 - return err;
58 -
59 - set_bit(DEV_STATE_INITIALIZED, &eth->state);
60 -
61 - return 0;
62 + return airoha_qdma_hw_init(qdma);
63 }
64
65 static int airoha_hw_init(struct platform_device *pdev,
66 struct airoha_eth *eth)
67 {
68 - int err;
69 + int err, i;
70
71 /* disable xsi */
72 reset_control_bulk_assert(ARRAY_SIZE(eth->xsi_rsts), eth->xsi_rsts);
73 @@ -2079,12 +2083,19 @@ static int airoha_hw_init(struct platfor
74 if (err)
75 return err;
76
77 - return airoha_qdma_init(pdev, eth);
78 + for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) {
79 + err = airoha_qdma_init(pdev, eth, &eth->qdma[i]);
80 + if (err)
81 + return err;
82 + }
83 +
84 + set_bit(DEV_STATE_INITIALIZED, &eth->state);
85 +
86 + return 0;
87 }
88
89 -static void airoha_hw_cleanup(struct airoha_eth *eth)
90 +static void airoha_hw_cleanup(struct airoha_qdma *qdma)
91 {
92 - struct airoha_qdma *qdma = &eth->qdma[0];
93 int i;
94
95 for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
96 @@ -2645,13 +2656,6 @@ static int airoha_probe(struct platform_
97 return dev_err_probe(eth->dev, PTR_ERR(eth->fe_regs),
98 "failed to iomap fe regs\n");
99
100 - eth->qdma[0].regs = devm_platform_ioremap_resource_byname(pdev,
101 - "qdma0");
102 - if (IS_ERR(eth->qdma[0].regs))
103 - return dev_err_probe(eth->dev,
104 - PTR_ERR(eth->qdma[0].regs),
105 - "failed to iomap qdma regs\n");
106 -
107 eth->rsts[0].id = "fe";
108 eth->rsts[1].id = "pdma";
109 eth->rsts[2].id = "qdma";
110 @@ -2707,7 +2711,9 @@ static int airoha_probe(struct platform_
111 return 0;
112
113 error:
114 - airoha_hw_cleanup(eth);
115 + for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
116 + airoha_hw_cleanup(&eth->qdma[i]);
117 +
118 for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
119 struct airoha_gdm_port *port = eth->ports[i];
120
121 @@ -2725,7 +2731,9 @@ static void airoha_remove(struct platfor
122 struct airoha_eth *eth = platform_get_drvdata(pdev);
123 int i;
124
125 - airoha_hw_cleanup(eth);
126 + for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
127 + airoha_hw_cleanup(&eth->qdma[i]);
128 +
129 for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
130 struct airoha_gdm_port *port = eth->ports[i];
131