Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mcb: Add support for shared PCI IRQs

Add support for shared PCI IRQs to mcb and mcb-pci.

Signed-off-by: Johannes Thumshirn <johannes.thumshirn@men.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Johannes Thumshirn and committed by
Greg Kroah-Hartman
4ec65b77 2e1c951f

+36 -7
+15 -5
drivers/mcb/mcb-core.c
··· 183 183 * 184 184 * Allocate a new @mcb_bus. 185 185 */ 186 - struct mcb_bus *mcb_alloc_bus(void) 186 + struct mcb_bus *mcb_alloc_bus(struct device *carrier) 187 187 { 188 188 struct mcb_bus *bus; 189 189 int bus_nr; 190 190 191 191 bus = kzalloc(sizeof(struct mcb_bus), GFP_KERNEL); 192 192 if (!bus) 193 - return NULL; 193 + return ERR_PTR(-ENOMEM); 194 194 195 195 bus_nr = ida_simple_get(&mcb_ida, 0, 0, GFP_KERNEL); 196 196 if (bus_nr < 0) { ··· 200 200 201 201 INIT_LIST_HEAD(&bus->children); 202 202 bus->bus_nr = bus_nr; 203 - 203 + bus->carrier = carrier; 204 204 return bus; 205 205 } 206 206 EXPORT_SYMBOL_GPL(mcb_alloc_bus); ··· 378 378 } 379 379 EXPORT_SYMBOL_GPL(mcb_release_mem); 380 380 381 + static int __mcb_get_irq(struct mcb_device *dev) 382 + { 383 + struct resource *irq = &dev->irq; 384 + 385 + return irq->start; 386 + } 387 + 381 388 /** 382 389 * mcb_get_irq() - Get device's IRQ number 383 390 * @dev: The @mcb_device the IRQ is for ··· 393 386 */ 394 387 int mcb_get_irq(struct mcb_device *dev) 395 388 { 396 - struct resource *irq = &dev->irq; 389 + struct mcb_bus *bus = dev->bus; 397 390 398 - return irq->start; 391 + if (bus->get_irq) 392 + return bus->get_irq(dev); 393 + 394 + return __mcb_get_irq(dev); 399 395 } 400 396 EXPORT_SYMBOL_GPL(mcb_get_irq); 401 397
+16 -1
drivers/mcb/mcb-pci.c
··· 20 20 void __iomem *base; 21 21 }; 22 22 23 + static int mcb_pci_get_irq(struct mcb_device *mdev) 24 + { 25 + struct mcb_bus *mbus = mdev->bus; 26 + struct device *dev = mbus->carrier; 27 + struct pci_dev *pdev = to_pci_dev(dev); 28 + 29 + return pdev->irq; 30 + } 31 + 23 32 static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 24 33 { 25 34 struct priv *priv; ··· 76 67 77 68 pci_set_drvdata(pdev, priv); 78 69 79 - priv->bus = mcb_alloc_bus(); 70 + priv->bus = mcb_alloc_bus(&pdev->dev); 71 + if (IS_ERR(priv->bus)) { 72 + ret = PTR_ERR(priv->bus); 73 + goto err_drvdata; 74 + } 75 + 76 + priv->bus->get_irq = mcb_pci_get_irq; 80 77 81 78 ret = chameleon_parse_cells(priv->bus, mapbase, priv->base); 82 79 if (ret < 0)
+5 -1
include/linux/mcb.h
··· 16 16 #include <linux/irqreturn.h> 17 17 18 18 struct mcb_driver; 19 + struct mcb_device; 19 20 20 21 /** 21 22 * struct mcb_bus - MEN Chameleon Bus ··· 24 23 * @dev: pointer to carrier device 25 24 * @children: the child busses 26 25 * @bus_nr: mcb bus number 26 + * @get_irq: callback to get IRQ number 27 27 */ 28 28 struct mcb_bus { 29 29 struct list_head children; 30 30 struct device dev; 31 + struct device *carrier; 31 32 int bus_nr; 33 + int (*get_irq)(struct mcb_device *dev); 32 34 }; 33 35 #define to_mcb_bus(b) container_of((b), struct mcb_bus, dev) 34 36 ··· 109 105 module_driver(__mcb_driver, mcb_register_driver, mcb_unregister_driver); 110 106 extern void mcb_bus_add_devices(const struct mcb_bus *bus); 111 107 extern int mcb_device_register(struct mcb_bus *bus, struct mcb_device *dev); 112 - extern struct mcb_bus *mcb_alloc_bus(void); 108 + extern struct mcb_bus *mcb_alloc_bus(struct device *carrier); 113 109 extern struct mcb_bus *mcb_bus_get(struct mcb_bus *bus); 114 110 extern void mcb_bus_put(struct mcb_bus *bus); 115 111 extern struct mcb_device *mcb_alloc_dev(struct mcb_bus *bus);