0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include "bman_priv.h"
0032
0033 static struct bman_portal *affine_bportals[NR_CPUS];
0034 static struct cpumask portal_cpus;
0035 static int __bman_portals_probed;
0036
0037 static DEFINE_SPINLOCK(bman_lock);
0038
0039 static struct bman_portal *init_pcfg(struct bm_portal_config *pcfg)
0040 {
0041 struct bman_portal *p = bman_create_affine_portal(pcfg);
0042
0043 if (!p) {
0044 dev_crit(pcfg->dev, "%s: Portal failure on cpu %d\n",
0045 __func__, pcfg->cpu);
0046 return NULL;
0047 }
0048
0049 bman_p_irqsource_add(p, BM_PIRQ_RCRI);
0050 affine_bportals[pcfg->cpu] = p;
0051
0052 dev_info(pcfg->dev, "Portal initialised, cpu %d\n", pcfg->cpu);
0053
0054 return p;
0055 }
0056
0057 static int bman_offline_cpu(unsigned int cpu)
0058 {
0059 struct bman_portal *p = affine_bportals[cpu];
0060 const struct bm_portal_config *pcfg;
0061
0062 if (!p)
0063 return 0;
0064
0065 pcfg = bman_get_bm_portal_config(p);
0066 if (!pcfg)
0067 return 0;
0068
0069
0070 cpu = cpumask_any_but(cpu_online_mask, cpu);
0071 irq_set_affinity(pcfg->irq, cpumask_of(cpu));
0072 return 0;
0073 }
0074
0075 static int bman_online_cpu(unsigned int cpu)
0076 {
0077 struct bman_portal *p = affine_bportals[cpu];
0078 const struct bm_portal_config *pcfg;
0079
0080 if (!p)
0081 return 0;
0082
0083 pcfg = bman_get_bm_portal_config(p);
0084 if (!pcfg)
0085 return 0;
0086
0087 irq_set_affinity(pcfg->irq, cpumask_of(cpu));
0088 return 0;
0089 }
0090
0091 int bman_portals_probed(void)
0092 {
0093 return __bman_portals_probed;
0094 }
0095 EXPORT_SYMBOL_GPL(bman_portals_probed);
0096
0097 static int bman_portal_probe(struct platform_device *pdev)
0098 {
0099 struct device *dev = &pdev->dev;
0100 struct device_node *node = dev->of_node;
0101 struct bm_portal_config *pcfg;
0102 struct resource *addr_phys[2];
0103 int irq, cpu, err, i;
0104
0105 err = bman_is_probed();
0106 if (!err)
0107 return -EPROBE_DEFER;
0108 if (err < 0) {
0109 dev_err(&pdev->dev, "failing probe due to bman probe error\n");
0110 return -ENODEV;
0111 }
0112
0113 pcfg = devm_kmalloc(dev, sizeof(*pcfg), GFP_KERNEL);
0114 if (!pcfg) {
0115 __bman_portals_probed = -1;
0116 return -ENOMEM;
0117 }
0118
0119 pcfg->dev = dev;
0120
0121 addr_phys[0] = platform_get_resource(pdev, IORESOURCE_MEM,
0122 DPAA_PORTAL_CE);
0123 if (!addr_phys[0]) {
0124 dev_err(dev, "Can't get %pOF property 'reg::CE'\n", node);
0125 goto err_ioremap1;
0126 }
0127
0128 addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM,
0129 DPAA_PORTAL_CI);
0130 if (!addr_phys[1]) {
0131 dev_err(dev, "Can't get %pOF property 'reg::CI'\n", node);
0132 goto err_ioremap1;
0133 }
0134
0135 pcfg->cpu = -1;
0136
0137 irq = platform_get_irq(pdev, 0);
0138 if (irq <= 0)
0139 goto err_ioremap1;
0140 pcfg->irq = irq;
0141
0142 pcfg->addr_virt_ce = memremap(addr_phys[0]->start,
0143 resource_size(addr_phys[0]),
0144 QBMAN_MEMREMAP_ATTR);
0145 if (!pcfg->addr_virt_ce) {
0146 dev_err(dev, "memremap::CE failed\n");
0147 goto err_ioremap1;
0148 }
0149
0150 pcfg->addr_virt_ci = ioremap(addr_phys[1]->start,
0151 resource_size(addr_phys[1]));
0152 if (!pcfg->addr_virt_ci) {
0153 dev_err(dev, "ioremap::CI failed\n");
0154 goto err_ioremap2;
0155 }
0156
0157 spin_lock(&bman_lock);
0158 cpu = cpumask_first_zero(&portal_cpus);
0159 if (cpu >= nr_cpu_ids) {
0160 __bman_portals_probed = 1;
0161
0162 spin_unlock(&bman_lock);
0163 goto check_cleanup;
0164 }
0165
0166 cpumask_set_cpu(cpu, &portal_cpus);
0167 spin_unlock(&bman_lock);
0168 pcfg->cpu = cpu;
0169
0170 if (!init_pcfg(pcfg)) {
0171 dev_err(dev, "portal init failed\n");
0172 goto err_portal_init;
0173 }
0174
0175
0176 if (!cpu_online(cpu))
0177 bman_offline_cpu(cpu);
0178
0179 check_cleanup:
0180 if (__bman_portals_probed == 1 && bman_requires_cleanup()) {
0181
0182
0183
0184
0185 for (i = 0; i < BM_POOL_MAX; i++) {
0186 err = bm_shutdown_pool(i);
0187 if (err) {
0188 dev_err(dev, "Failed to shutdown bpool %d\n",
0189 i);
0190 goto err_portal_init;
0191 }
0192 }
0193 bman_done_cleanup();
0194 }
0195
0196 return 0;
0197
0198 err_portal_init:
0199 iounmap(pcfg->addr_virt_ci);
0200 err_ioremap2:
0201 memunmap(pcfg->addr_virt_ce);
0202 err_ioremap1:
0203 __bman_portals_probed = -1;
0204
0205 return -ENXIO;
0206 }
0207
0208 static const struct of_device_id bman_portal_ids[] = {
0209 {
0210 .compatible = "fsl,bman-portal",
0211 },
0212 {}
0213 };
0214 MODULE_DEVICE_TABLE(of, bman_portal_ids);
0215
0216 static struct platform_driver bman_portal_driver = {
0217 .driver = {
0218 .name = KBUILD_MODNAME,
0219 .of_match_table = bman_portal_ids,
0220 },
0221 .probe = bman_portal_probe,
0222 };
0223
0224 static int __init bman_portal_driver_register(struct platform_driver *drv)
0225 {
0226 int ret;
0227
0228 ret = platform_driver_register(drv);
0229 if (ret < 0)
0230 return ret;
0231
0232 ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
0233 "soc/qbman_portal:online",
0234 bman_online_cpu, bman_offline_cpu);
0235 if (ret < 0) {
0236 pr_err("bman: failed to register hotplug callbacks.\n");
0237 platform_driver_unregister(drv);
0238 return ret;
0239 }
0240 return 0;
0241 }
0242
0243 module_driver(bman_portal_driver,
0244 bman_portal_driver_register, platform_driver_unregister);