1 /* 2 * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. 3 * 4 * Author: Tony Li <tony.li@freescale.com> 5 * Jason Jin <Jason.jin@freescale.com> 6 * 7 * The hwirq alloc and free code reuse from sysdev/mpic_msi.c 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License 11 * as published by the Free Software Foundation; version 2 of the 12 * License. 13 * 14 */ 15 #include <linux/irq.h> 16 #include <linux/bootmem.h> 17 #include <linux/msi.h> 18 #include <linux/pci.h> 19 #include <linux/slab.h> 20 #include <linux/of_platform.h> 21 #include <sysdev/fsl_soc.h> 22 #include <asm/prom.h> 23 #include <asm/hw_irq.h> 24 #include <asm/ppc-pci.h> 25 #include <asm/mpic.h> 26 #include "fsl_msi.h" 27 #include "fsl_pci.h" 28 29 LIST_HEAD(msi_head); 30 31 struct fsl_msi_feature { 32 u32 fsl_pic_ip; 33 u32 msiir_offset; /* Offset of MSIIR, relative to start of MSIR bank */ 34 }; 35 36 struct fsl_msi_cascade_data { 37 struct fsl_msi *msi_data; 38 int index; 39 }; 40 41 static inline u32 fsl_msi_read(u32 __iomem *base, unsigned int reg) 42 { 43 return in_be32(base + (reg >> 2)); 44 } 45 46 /* 47 * We do not need this actually. The MSIR register has been read once 48 * in the cascade interrupt. So, this MSI interrupt has been acked 49 */ 50 static void fsl_msi_end_irq(struct irq_data *d) 51 { 52 } 53 54 static struct irq_chip fsl_msi_chip = { 55 .irq_mask = mask_msi_irq, 56 .irq_unmask = unmask_msi_irq, 57 .irq_ack = fsl_msi_end_irq, 58 .name = "FSL-MSI", 59 }; 60 61 static int fsl_msi_host_map(struct irq_host *h, unsigned int virq, 62 irq_hw_number_t hw) 63 { 64 struct fsl_msi *msi_data = h->host_data; 65 struct irq_chip *chip = &fsl_msi_chip; 66 67 irq_set_status_flags(virq, IRQ_TYPE_EDGE_FALLING); 68 69 irq_set_chip_data(virq, msi_data); 70 irq_set_chip_and_handler(virq, chip, handle_edge_irq); 71 72 return 0; 73 } 74 75 static struct irq_host_ops fsl_msi_host_ops = { 76 .map = fsl_msi_host_map, 77 }; 78 79 static int fsl_msi_init_allocator(struct fsl_msi *msi_data) 80 { 81 int rc; 82 83 rc = msi_bitmap_alloc(&msi_data->bitmap, NR_MSI_IRQS, 84 msi_data->irqhost->of_node); 85 if (rc) 86 return rc; 87 88 rc = msi_bitmap_reserve_dt_hwirqs(&msi_data->bitmap); 89 if (rc < 0) { 90 msi_bitmap_free(&msi_data->bitmap); 91 return rc; 92 } 93 94 return 0; 95 } 96 97 static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type) 98 { 99 if (type == PCI_CAP_ID_MSIX) 100 pr_debug("fslmsi: MSI-X untested, trying anyway.\n"); 101 102 return 0; 103 } 104 105 static void fsl_teardown_msi_irqs(struct pci_dev *pdev) 106 { 107 struct msi_desc *entry; 108 struct fsl_msi *msi_data; 109 110 list_for_each_entry(entry, &pdev->msi_list, list) { 111 if (entry->irq == NO_IRQ) 112 continue; 113 msi_data = irq_get_chip_data(entry->irq); 114 irq_set_msi_desc(entry->irq, NULL); 115 msi_bitmap_free_hwirqs(&msi_data->bitmap, 116 virq_to_hw(entry->irq), 1); 117 irq_dispose_mapping(entry->irq); 118 } 119 120 return; 121 } 122 123 static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, 124 struct msi_msg *msg, 125 struct fsl_msi *fsl_msi_data) 126 { 127 struct fsl_msi *msi_data = fsl_msi_data; 128 struct pci_controller *hose = pci_bus_to_host(pdev->bus); 129 u64 address; /* Physical address of the MSIIR */ 130 int len; 131 const u64 *reg; 132 133 /* If the msi-address-64 property exists, then use it */ 134 reg = of_get_property(hose->dn, "msi-address-64", &len); 135 if (reg && (len == sizeof(u64))) 136 address = be64_to_cpup(reg); 137 else 138 address = fsl_pci_immrbar_base(hose) + msi_data->msiir_offset; 139 140 msg->address_lo = lower_32_bits(address); 141 msg->address_hi = upper_32_bits(address); 142 143 msg->data = hwirq; 144 145 pr_debug("%s: allocated srs: %d, ibs: %d\n", 146 __func__, hwirq / IRQS_PER_MSI_REG, hwirq % IRQS_PER_MSI_REG); 147 } 148 149 static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) 150 { 151 int rc, hwirq = -ENOMEM; 152 unsigned int virq; 153 struct msi_desc *entry; 154 struct msi_msg msg; 155 struct fsl_msi *msi_data; 156 157 list_for_each_entry(entry, &pdev->msi_list, list) { 158 list_for_each_entry(msi_data, &msi_head, list) { 159 hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); 160 if (hwirq >= 0) 161 break; 162 } 163 164 if (hwirq < 0) { 165 rc = hwirq; 166 pr_debug("%s: fail allocating msi interrupt\n", 167 __func__); 168 goto out_free; 169 } 170 171 virq = irq_create_mapping(msi_data->irqhost, hwirq); 172 173 if (virq == NO_IRQ) { 174 pr_debug("%s: fail mapping hwirq 0x%x\n", 175 __func__, hwirq); 176 msi_bitmap_free_hwirqs(&msi_data->bitmap, hwirq, 1); 177 rc = -ENOSPC; 178 goto out_free; 179 } 180 /* chip_data is msi_data via host->hostdata in host->map() */ 181 irq_set_msi_desc(virq, entry); 182 183 fsl_compose_msi_msg(pdev, hwirq, &msg, msi_data); 184 write_msi_msg(virq, &msg); 185 } 186 return 0; 187 188 out_free: 189 /* free by the caller of this function */ 190 return rc; 191 } 192 193 static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) 194 { 195 struct irq_chip *chip = irq_desc_get_chip(desc); 196 struct irq_data *idata = irq_desc_get_irq_data(desc); 197 unsigned int cascade_irq; 198 struct fsl_msi *msi_data; 199 int msir_index = -1; 200 u32 msir_value = 0; 201 u32 intr_index; 202 u32 have_shift = 0; 203 struct fsl_msi_cascade_data *cascade_data; 204 205 cascade_data = irq_get_handler_data(irq); 206 msi_data = cascade_data->msi_data; 207 208 raw_spin_lock(&desc->lock); 209 if ((msi_data->feature & FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) { 210 if (chip->irq_mask_ack) 211 chip->irq_mask_ack(idata); 212 else { 213 chip->irq_mask(idata); 214 chip->irq_ack(idata); 215 } 216 } 217 218 if (unlikely(irqd_irq_inprogress(idata))) 219 goto unlock; 220 221 msir_index = cascade_data->index; 222 223 if (msir_index >= NR_MSI_REG) 224 cascade_irq = NO_IRQ; 225 226 irqd_set_chained_irq_inprogress(idata); 227 switch (msi_data->feature & FSL_PIC_IP_MASK) { 228 case FSL_PIC_IP_MPIC: 229 msir_value = fsl_msi_read(msi_data->msi_regs, 230 msir_index * 0x10); 231 break; 232 case FSL_PIC_IP_IPIC: 233 msir_value = fsl_msi_read(msi_data->msi_regs, msir_index * 0x4); 234 break; 235 } 236 237 while (msir_value) { 238 intr_index = ffs(msir_value) - 1; 239 240 cascade_irq = irq_linear_revmap(msi_data->irqhost, 241 msir_index * IRQS_PER_MSI_REG + 242 intr_index + have_shift); 243 if (cascade_irq != NO_IRQ) 244 generic_handle_irq(cascade_irq); 245 have_shift += intr_index + 1; 246 msir_value = msir_value >> (intr_index + 1); 247 } 248 irqd_clr_chained_irq_inprogress(idata); 249 250 switch (msi_data->feature & FSL_PIC_IP_MASK) { 251 case FSL_PIC_IP_MPIC: 252 chip->irq_eoi(idata); 253 break; 254 case FSL_PIC_IP_IPIC: 255 if (!irqd_irq_disabled(idata) && chip->irq_unmask) 256 chip->irq_unmask(idata); 257 break; 258 } 259 unlock: 260 raw_spin_unlock(&desc->lock); 261 } 262 263 static int fsl_of_msi_remove(struct platform_device *ofdev) 264 { 265 struct fsl_msi *msi = platform_get_drvdata(ofdev); 266 int virq, i; 267 struct fsl_msi_cascade_data *cascade_data; 268 269 if (msi->list.prev != NULL) 270 list_del(&msi->list); 271 for (i = 0; i < NR_MSI_REG; i++) { 272 virq = msi->msi_virqs[i]; 273 if (virq != NO_IRQ) { 274 cascade_data = irq_get_handler_data(virq); 275 kfree(cascade_data); 276 irq_dispose_mapping(virq); 277 } 278 } 279 if (msi->bitmap.bitmap) 280 msi_bitmap_free(&msi->bitmap); 281 iounmap(msi->msi_regs); 282 kfree(msi); 283 284 return 0; 285 } 286 287 static int __devinit fsl_msi_setup_hwirq(struct fsl_msi *msi, 288 struct platform_device *dev, 289 int offset, int irq_index) 290 { 291 struct fsl_msi_cascade_data *cascade_data = NULL; 292 int virt_msir; 293 294 virt_msir = irq_of_parse_and_map(dev->dev.of_node, irq_index); 295 if (virt_msir == NO_IRQ) { 296 dev_err(&dev->dev, "%s: Cannot translate IRQ index %d\n", 297 __func__, irq_index); 298 return 0; 299 } 300 301 cascade_data = kzalloc(sizeof(struct fsl_msi_cascade_data), GFP_KERNEL); 302 if (!cascade_data) { 303 dev_err(&dev->dev, "No memory for MSI cascade data\n"); 304 return -ENOMEM; 305 } 306 307 msi->msi_virqs[irq_index] = virt_msir; 308 cascade_data->index = offset; 309 cascade_data->msi_data = msi; 310 irq_set_handler_data(virt_msir, cascade_data); 311 irq_set_chained_handler(virt_msir, fsl_msi_cascade); 312 313 return 0; 314 } 315 316 static const struct of_device_id fsl_of_msi_ids[]; 317 static int __devinit fsl_of_msi_probe(struct platform_device *dev) 318 { 319 const struct of_device_id *match; 320 struct fsl_msi *msi; 321 struct resource res; 322 int err, i, j, irq_index, count; 323 int rc; 324 const u32 *p; 325 struct fsl_msi_feature *features; 326 int len; 327 u32 offset; 328 static const u32 all_avail[] = { 0, NR_MSI_IRQS }; 329 330 match = of_match_device(fsl_of_msi_ids, &dev->dev); 331 if (!match) 332 return -EINVAL; 333 features = match->data; 334 335 printk(KERN_DEBUG "Setting up Freescale MSI support\n"); 336 337 msi = kzalloc(sizeof(struct fsl_msi), GFP_KERNEL); 338 if (!msi) { 339 dev_err(&dev->dev, "No memory for MSI structure\n"); 340 return -ENOMEM; 341 } 342 platform_set_drvdata(dev, msi); 343 344 msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR, 345 NR_MSI_IRQS, &fsl_msi_host_ops, 0); 346 347 if (msi->irqhost == NULL) { 348 dev_err(&dev->dev, "No memory for MSI irqhost\n"); 349 err = -ENOMEM; 350 goto error_out; 351 } 352 353 /* Get the MSI reg base */ 354 err = of_address_to_resource(dev->dev.of_node, 0, &res); 355 if (err) { 356 dev_err(&dev->dev, "%s resource error!\n", 357 dev->dev.of_node->full_name); 358 goto error_out; 359 } 360 361 msi->msi_regs = ioremap(res.start, resource_size(&res)); 362 if (!msi->msi_regs) { 363 dev_err(&dev->dev, "ioremap problem failed\n"); 364 goto error_out; 365 } 366 367 msi->feature = features->fsl_pic_ip; 368 369 msi->irqhost->host_data = msi; 370 371 msi->msiir_offset = features->msiir_offset + (res.start & 0xfffff); 372 373 rc = fsl_msi_init_allocator(msi); 374 if (rc) { 375 dev_err(&dev->dev, "Error allocating MSI bitmap\n"); 376 goto error_out; 377 } 378 379 p = of_get_property(dev->dev.of_node, "msi-available-ranges", &len); 380 if (p && len % (2 * sizeof(u32)) != 0) { 381 dev_err(&dev->dev, "%s: Malformed msi-available-ranges property\n", 382 __func__); 383 err = -EINVAL; 384 goto error_out; 385 } 386 387 if (!p) { 388 p = all_avail; 389 len = sizeof(all_avail); 390 } 391 392 for (irq_index = 0, i = 0; i < len / (2 * sizeof(u32)); i++) { 393 if (p[i * 2] % IRQS_PER_MSI_REG || 394 p[i * 2 + 1] % IRQS_PER_MSI_REG) { 395 printk(KERN_WARNING "%s: %s: msi available range of %u at %u is not IRQ-aligned\n", 396 __func__, dev->dev.of_node->full_name, 397 p[i * 2 + 1], p[i * 2]); 398 err = -EINVAL; 399 goto error_out; 400 } 401 402 offset = p[i * 2] / IRQS_PER_MSI_REG; 403 count = p[i * 2 + 1] / IRQS_PER_MSI_REG; 404 405 for (j = 0; j < count; j++, irq_index++) { 406 err = fsl_msi_setup_hwirq(msi, dev, offset + j, irq_index); 407 if (err) 408 goto error_out; 409 } 410 } 411 412 list_add_tail(&msi->list, &msi_head); 413 414 /* The multiple setting ppc_md.setup_msi_irqs will not harm things */ 415 if (!ppc_md.setup_msi_irqs) { 416 ppc_md.setup_msi_irqs = fsl_setup_msi_irqs; 417 ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs; 418 ppc_md.msi_check_device = fsl_msi_check_device; 419 } else if (ppc_md.setup_msi_irqs != fsl_setup_msi_irqs) { 420 dev_err(&dev->dev, "Different MSI driver already installed!\n"); 421 err = -ENODEV; 422 goto error_out; 423 } 424 return 0; 425 error_out: 426 fsl_of_msi_remove(dev); 427 return err; 428 } 429 430 static const struct fsl_msi_feature mpic_msi_feature = { 431 .fsl_pic_ip = FSL_PIC_IP_MPIC, 432 .msiir_offset = 0x140, 433 }; 434 435 static const struct fsl_msi_feature ipic_msi_feature = { 436 .fsl_pic_ip = FSL_PIC_IP_IPIC, 437 .msiir_offset = 0x38, 438 }; 439 440 static const struct of_device_id fsl_of_msi_ids[] = { 441 { 442 .compatible = "fsl,mpic-msi", 443 .data = (void *)&mpic_msi_feature, 444 }, 445 { 446 .compatible = "fsl,ipic-msi", 447 .data = (void *)&ipic_msi_feature, 448 }, 449 {} 450 }; 451 452 static struct platform_driver fsl_of_msi_driver = { 453 .driver = { 454 .name = "fsl-msi", 455 .owner = THIS_MODULE, 456 .of_match_table = fsl_of_msi_ids, 457 }, 458 .probe = fsl_of_msi_probe, 459 .remove = fsl_of_msi_remove, 460 }; 461 462 static __init int fsl_of_msi_init(void) 463 { 464 return platform_driver_register(&fsl_of_msi_driver); 465 } 466 467 subsys_initcall(fsl_of_msi_init); 468