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_get_attributes(dpio_dev->mc_io, 0, dpio_dev->mc_handle, 114 &dpio_attrs); 115 if (err) { 116 dev_err(dev, "dpio_get_attributes() failed %d\n", err); 117 goto err_get_attr; 118 } 119 desc.qman_version = dpio_attrs.qbman_version; 120 121 err = dpio_enable(dpio_dev->mc_io, 0, dpio_dev->mc_handle); 122 if (err) { 123 dev_err(dev, "dpio_enable() failed %d\n", err); 124 goto err_get_attr; 125 } 126 127 /* initialize DPIO descriptor */ 128 desc.receives_notifications = dpio_attrs.num_priorities ? 1 : 0; 129 desc.has_8prio = dpio_attrs.num_priorities == 8 ? 1 : 0; 130 desc.dpio_id = dpio_dev->obj_desc.id; 131 132 /* get the cpu to use for the affinity hint */ 133 possible_next_cpu = cpumask_first(cpus_unused_mask); 134 if (possible_next_cpu >= nr_cpu_ids) { 135 dev_err(dev, "probe failed. Number of DPIOs exceeds NR_CPUS.\n"); 136 err = -ERANGE; 137 goto err_allocate_irqs; 138 } 139 desc.cpu = possible_next_cpu; 140 cpumask_clear_cpu(possible_next_cpu, cpus_unused_mask); 141 142 /* 143 * Set the CENA regs to be the cache inhibited area of the portal to 144 * avoid coherency issues if a user migrates to another core. 145 */ 146 desc.regs_cena = devm_memremap(dev, dpio_dev->regions[1].start, 147 resource_size(&dpio_dev->regions[1]), 148 MEMREMAP_WC); 149 if (IS_ERR(desc.regs_cena)) { 150 dev_err(dev, "devm_memremap failed\n"); 151 err = PTR_ERR(desc.regs_cena); 152 goto err_allocate_irqs; 153 } 154 155 desc.regs_cinh = devm_ioremap(dev, dpio_dev->regions[1].start, 156 resource_size(&dpio_dev->regions[1])); 157 if (!desc.regs_cinh) { 158 err = -ENOMEM; 159 dev_err(dev, "devm_ioremap failed\n"); 160 goto err_allocate_irqs; 161 } 162 163 err = fsl_mc_allocate_irqs(dpio_dev); 164 if (err) { 165 dev_err(dev, "fsl_mc_allocate_irqs failed. err=%d\n", err); 166 goto err_allocate_irqs; 167 } 168 169 err = register_dpio_irq_handlers(dpio_dev, desc.cpu); 170 if (err) 171 goto err_register_dpio_irq; 172 173 priv->io = dpaa2_io_create(&desc); 174 if (!priv->io) { 175 dev_err(dev, "dpaa2_io_create failed\n"); 176 err = -ENOMEM; 177 goto err_dpaa2_io_create; 178 } 179 180 dev_info(dev, "probed\n"); 181 dev_dbg(dev, " receives_notifications = %d\n", 182 desc.receives_notifications); 183 dpio_close(dpio_dev->mc_io, 0, dpio_dev->mc_handle); 184 fsl_mc_portal_free(dpio_dev->mc_io); 185 186 return 0; 187 188 err_dpaa2_io_create: 189 unregister_dpio_irq_handlers(dpio_dev); 190 err_register_dpio_irq: 191 fsl_mc_free_irqs(dpio_dev); 192 err_allocate_irqs: 193 dpio_disable(dpio_dev->mc_io, 0, dpio_dev->mc_handle); 194 err_get_attr: 195 dpio_close(dpio_dev->mc_io, 0, dpio_dev->mc_handle); 196 err_open: 197 fsl_mc_portal_free(dpio_dev->mc_io); 198 err_priv_alloc: 199 return err; 200 } 201 202 /* Tear down interrupts for a given DPIO object */ 203 static void dpio_teardown_irqs(struct fsl_mc_device *dpio_dev) 204 { 205 unregister_dpio_irq_handlers(dpio_dev); 206 fsl_mc_free_irqs(dpio_dev); 207 } 208 209 static int dpaa2_dpio_remove(struct fsl_mc_device *dpio_dev) 210 { 211 struct device *dev; 212 struct dpio_priv *priv; 213 int err = 0, cpu; 214 215 dev = &dpio_dev->dev; 216 priv = dev_get_drvdata(dev); 217 218 dpaa2_io_down(priv->io); 219 220 dpio_teardown_irqs(dpio_dev); 221 222 cpu = dpaa2_io_get_cpu(priv->io); 223 cpumask_set_cpu(cpu, cpus_unused_mask); 224 225 err = fsl_mc_portal_allocate(dpio_dev, 0, &dpio_dev->mc_io); 226 if (err) { 227 dev_err(dev, "MC portal allocation failed\n"); 228 goto err_mcportal; 229 } 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 err_mcportal: 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