1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 /* 3 * Copyright 2014-2016 Freescale Semiconductor Inc. 4 * Copyright NXP 2016 5 * 6 */ 7 8 #include <linux/types.h> 9 #include <linux/init.h> 10 #include <linux/module.h> 11 #include <linux/platform_device.h> 12 #include <linux/interrupt.h> 13 #include <linux/msi.h> 14 #include <linux/dma-mapping.h> 15 #include <linux/delay.h> 16 #include <linux/io.h> 17 18 #include <linux/fsl/mc.h> 19 #include <soc/fsl/dpaa2-io.h> 20 21 #include "qbman-portal.h" 22 #include "dpio.h" 23 #include "dpio-cmd.h" 24 25 MODULE_LICENSE("Dual BSD/GPL"); 26 MODULE_AUTHOR("Freescale Semiconductor, Inc"); 27 MODULE_DESCRIPTION("DPIO Driver"); 28 29 struct dpio_priv { 30 struct dpaa2_io *io; 31 }; 32 33 static cpumask_var_t cpus_unused_mask; 34 35 static irqreturn_t dpio_irq_handler(int irq_num, void *arg) 36 { 37 struct device *dev = (struct device *)arg; 38 struct dpio_priv *priv = dev_get_drvdata(dev); 39 40 return dpaa2_io_irq(priv->io); 41 } 42 43 static void unregister_dpio_irq_handlers(struct fsl_mc_device *dpio_dev) 44 { 45 struct fsl_mc_device_irq *irq; 46 47 irq = dpio_dev->irqs[0]; 48 49 /* clear the affinity hint */ 50 irq_set_affinity_hint(irq->msi_desc->irq, NULL); 51 } 52 53 static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int cpu) 54 { 55 int error; 56 struct fsl_mc_device_irq *irq; 57 cpumask_t mask; 58 59 irq = dpio_dev->irqs[0]; 60 error = devm_request_irq(&dpio_dev->dev, 61 irq->msi_desc->irq, 62 dpio_irq_handler, 63 0, 64 dev_name(&dpio_dev->dev), 65 &dpio_dev->dev); 66 if (error < 0) { 67 dev_err(&dpio_dev->dev, 68 "devm_request_irq() failed: %d\n", 69 error); 70 return error; 71 } 72 73 /* set the affinity hint */ 74 cpumask_clear(&mask); 75 cpumask_set_cpu(cpu, &mask); 76 if (irq_set_affinity_hint(irq->msi_desc->irq, &mask)) 77 dev_err(&dpio_dev->dev, 78 "irq_set_affinity failed irq %d cpu %d\n", 79 irq->msi_desc->irq, cpu); 80 81 return 0; 82 } 83 84 static int dpaa2_dpio_probe(struct fsl_mc_device *dpio_dev) 85 { 86 struct dpio_attr dpio_attrs; 87 struct dpaa2_io_desc desc; 88 struct dpio_priv *priv; 89 int err = -ENOMEM; 90 struct device *dev = &dpio_dev->dev; 91 int possible_next_cpu; 92 93 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 94 if (!priv) 95 goto err_priv_alloc; 96 97 dev_set_drvdata(dev, priv); 98 99 err = fsl_mc_portal_allocate(dpio_dev, 0, &dpio_dev->mc_io); 100 if (err) { 101 dev_dbg(dev, "MC portal allocation failed\n"); 102 err = -EPROBE_DEFER; 103 goto err_priv_alloc; 104 } 105 106 err = dpio_open(dpio_dev->mc_io, 0, dpio_dev->obj_desc.id, 107 &dpio_dev->mc_handle); 108 if (err) { 109 dev_err(dev, "dpio_open() failed\n"); 110 goto err_open; 111 } 112 113 err = dpio_reset(dpio_dev->mc_io, 0, dpio_dev->mc_handle); 114 if (err) { 115 dev_err(dev, "dpio_reset() failed\n"); 116 goto err_reset; 117 } 118 119 err = dpio_get_attributes(dpio_dev->mc_io, 0, dpio_dev->mc_handle, 120 &dpio_attrs); 121 if (err) { 122 dev_err(dev, "dpio_get_attributes() failed %d\n", err); 123 goto err_get_attr; 124 } 125 desc.qman_version = dpio_attrs.qbman_version; 126 127 err = dpio_enable(dpio_dev->mc_io, 0, dpio_dev->mc_handle); 128 if (err) { 129 dev_err(dev, "dpio_enable() failed %d\n", err); 130 goto err_get_attr; 131 } 132 133 /* initialize DPIO descriptor */ 134 desc.receives_notifications = dpio_attrs.num_priorities ? 1 : 0; 135 desc.has_8prio = dpio_attrs.num_priorities == 8 ? 1 : 0; 136 desc.dpio_id = dpio_dev->obj_desc.id; 137 138 /* get the cpu to use for the affinity hint */ 139 possible_next_cpu = cpumask_first(cpus_unused_mask); 140 if (possible_next_cpu >= nr_cpu_ids) { 141 dev_err(dev, "probe failed. Number of DPIOs exceeds NR_CPUS.\n"); 142 err = -ERANGE; 143 goto err_allocate_irqs; 144 } 145 desc.cpu = possible_next_cpu; 146 cpumask_clear_cpu(possible_next_cpu, cpus_unused_mask); 147 148 /* 149 * Set the CENA regs to be the cache inhibited area of the portal to 150 * avoid coherency issues if a user migrates to another core. 151 */ 152 desc.regs_cena = devm_memremap(dev, dpio_dev->regions[1].start, 153 resource_size(&dpio_dev->regions[1]), 154 MEMREMAP_WC); 155 if (IS_ERR(desc.regs_cena)) { 156 dev_err(dev, "devm_memremap failed\n"); 157 err = PTR_ERR(desc.regs_cena); 158 goto err_allocate_irqs; 159 } 160 161 desc.regs_cinh = devm_ioremap(dev, dpio_dev->regions[1].start, 162 resource_size(&dpio_dev->regions[1])); 163 if (!desc.regs_cinh) { 164 err = -ENOMEM; 165 dev_err(dev, "devm_ioremap failed\n"); 166 goto err_allocate_irqs; 167 } 168 169 err = fsl_mc_allocate_irqs(dpio_dev); 170 if (err) { 171 dev_err(dev, "fsl_mc_allocate_irqs failed. err=%d\n", err); 172 goto err_allocate_irqs; 173 } 174 175 err = register_dpio_irq_handlers(dpio_dev, desc.cpu); 176 if (err) 177 goto err_register_dpio_irq; 178 179 priv->io = dpaa2_io_create(&desc, dev); 180 if (!priv->io) { 181 dev_err(dev, "dpaa2_io_create failed\n"); 182 err = -ENOMEM; 183 goto err_dpaa2_io_create; 184 } 185 186 dev_info(dev, "probed\n"); 187 dev_dbg(dev, " receives_notifications = %d\n", 188 desc.receives_notifications); 189 dpio_close(dpio_dev->mc_io, 0, dpio_dev->mc_handle); 190 191 return 0; 192 193 err_dpaa2_io_create: 194 unregister_dpio_irq_handlers(dpio_dev); 195 err_register_dpio_irq: 196 fsl_mc_free_irqs(dpio_dev); 197 err_allocate_irqs: 198 dpio_disable(dpio_dev->mc_io, 0, dpio_dev->mc_handle); 199 err_get_attr: 200 err_reset: 201 dpio_close(dpio_dev->mc_io, 0, dpio_dev->mc_handle); 202 err_open: 203 fsl_mc_portal_free(dpio_dev->mc_io); 204 err_priv_alloc: 205 return err; 206 } 207 208 /* Tear down interrupts for a given DPIO object */ 209 static void dpio_teardown_irqs(struct fsl_mc_device *dpio_dev) 210 { 211 unregister_dpio_irq_handlers(dpio_dev); 212 fsl_mc_free_irqs(dpio_dev); 213 } 214 215 static int dpaa2_dpio_remove(struct fsl_mc_device *dpio_dev) 216 { 217 struct device *dev; 218 struct dpio_priv *priv; 219 int err = 0, cpu; 220 221 dev = &dpio_dev->dev; 222 priv = dev_get_drvdata(dev); 223 cpu = dpaa2_io_get_cpu(priv->io); 224 225 dpaa2_io_down(priv->io); 226 227 dpio_teardown_irqs(dpio_dev); 228 229 cpumask_set_cpu(cpu, cpus_unused_mask); 230 231 err = dpio_open(dpio_dev->mc_io, 0, dpio_dev->obj_desc.id, 232 &dpio_dev->mc_handle); 233 if (err) { 234 dev_err(dev, "dpio_open() failed\n"); 235 goto err_open; 236 } 237 238 dpio_disable(dpio_dev->mc_io, 0, dpio_dev->mc_handle); 239 240 dpio_close(dpio_dev->mc_io, 0, dpio_dev->mc_handle); 241 242 fsl_mc_portal_free(dpio_dev->mc_io); 243 244 return 0; 245 246 err_open: 247 fsl_mc_portal_free(dpio_dev->mc_io); 248 249 return err; 250 } 251 252 static const struct fsl_mc_device_id dpaa2_dpio_match_id_table[] = { 253 { 254 .vendor = FSL_MC_VENDOR_FREESCALE, 255 .obj_type = "dpio", 256 }, 257 { .vendor = 0x0 } 258 }; 259 260 static struct fsl_mc_driver dpaa2_dpio_driver = { 261 .driver = { 262 .name = KBUILD_MODNAME, 263 .owner = THIS_MODULE, 264 }, 265 .probe = dpaa2_dpio_probe, 266 .remove = dpaa2_dpio_remove, 267 .match_id_table = dpaa2_dpio_match_id_table 268 }; 269 270 static int dpio_driver_init(void) 271 { 272 if (!zalloc_cpumask_var(&cpus_unused_mask, GFP_KERNEL)) 273 return -ENOMEM; 274 cpumask_copy(cpus_unused_mask, cpu_online_mask); 275 276 return fsl_mc_driver_register(&dpaa2_dpio_driver); 277 } 278 279 static void dpio_driver_exit(void) 280 { 281 free_cpumask_var(cpus_unused_mask); 282 fsl_mc_driver_unregister(&dpaa2_dpio_driver); 283 } 284 module_init(dpio_driver_init); 285 module_exit(dpio_driver_exit); 286