PCI/MSI: Rename write_msi_msg() to pci_write_msi_msg()
[deliverable/linux.git] / drivers / pci / host / pcie-designware.c
index 34e736601259924852db9526449b1539e97c2c01..e03f4e7e1f7dfb854665d6230b3abac3700bf82f 100644 (file)
@@ -196,30 +196,6 @@ void dw_pcie_msi_init(struct pcie_port *pp)
        dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_HI, 4, 0);
 }
 
-static int find_valid_pos0(struct pcie_port *pp, int msgvec, int pos, int *pos0)
-{
-       int flag = 1;
-
-       do {
-               pos = find_next_zero_bit(pp->msi_irq_in_use,
-                               MAX_MSI_IRQS, pos);
-               /*if you have reached to the end then get out from here.*/
-               if (pos == MAX_MSI_IRQS)
-                       return -ENOSPC;
-               /*
-                * Check if this position is at correct offset.nvec is always a
-                * power of two. pos0 must be nvec bit aligned.
-                */
-               if (pos % msgvec)
-                       pos += msgvec - (pos % msgvec);
-               else
-                       flag = 0;
-       } while (flag);
-
-       *pos0 = pos;
-       return 0;
-}
-
 static void dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq)
 {
        unsigned int res, bit, val;
@@ -238,13 +214,14 @@ static void clear_irq_range(struct pcie_port *pp, unsigned int irq_base,
 
        for (i = 0; i < nvec; i++) {
                irq_set_msi_desc_off(irq_base, i, NULL);
-               clear_bit(pos + i, pp->msi_irq_in_use);
                /* Disable corresponding interrupt on MSI controller */
                if (pp->ops->msi_clear_irq)
                        pp->ops->msi_clear_irq(pp, pos + i);
                else
                        dw_pcie_msi_clear_irq(pp, pos + i);
        }
+
+       bitmap_release_region(pp->msi_irq_in_use, pos, order_base_2(nvec));
 }
 
 static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
@@ -260,26 +237,13 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
 
 static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
 {
-       int irq, pos0, pos1, i;
+       int irq, pos0, i;
        struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
 
-       pos0 = find_first_zero_bit(pp->msi_irq_in_use,
-                       MAX_MSI_IRQS);
-       if (pos0 % no_irqs) {
-               if (find_valid_pos0(pp, no_irqs, pos0, &pos0))
-                       goto no_valid_irq;
-       }
-       if (no_irqs > 1) {
-               pos1 = find_next_bit(pp->msi_irq_in_use,
-                               MAX_MSI_IRQS, pos0);
-               /* there must be nvec number of consecutive free bits */
-               while ((pos1 - pos0) < no_irqs) {
-                       if (find_valid_pos0(pp, no_irqs, pos1, &pos0))
-                               goto no_valid_irq;
-                       pos1 = find_next_bit(pp->msi_irq_in_use,
-                                       MAX_MSI_IRQS, pos0);
-               }
-       }
+       pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
+                                      order_base_2(no_irqs));
+       if (pos0 < 0)
+               goto no_valid_irq;
 
        irq = irq_find_mapping(pp->irq_domain, pos0);
        if (!irq)
@@ -297,7 +261,6 @@ static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
                        clear_irq_range(pp, irq, i, pos0);
                        goto no_valid_irq;
                }
-               set_bit(pos0 + i, pp->msi_irq_in_use);
                /*Enable corresponding interrupt in MSI interrupt controller */
                if (pp->ops->msi_set_irq)
                        pp->ops->msi_set_irq(pp, pos0 + i);
@@ -313,54 +276,17 @@ no_valid_irq:
        return -ENOSPC;
 }
 
-static void clear_irq(unsigned int irq)
-{
-       unsigned int pos, nvec;
-       struct msi_desc *msi;
-       struct pcie_port *pp;
-       struct irq_data *data = irq_get_irq_data(irq);
-
-       /* get the port structure */
-       msi = irq_data_get_msi(data);
-       pp = sys_to_pcie(msi->dev->bus->sysdata);
-
-       /* undo what was done in assign_irq */
-       pos = data->hwirq;
-       nvec = 1 << msi->msi_attrib.multiple;
-
-       clear_irq_range(pp, irq, nvec, pos);
-
-       /* all irqs cleared; reset attributes */
-       msi->irq = 0;
-       msi->msi_attrib.multiple = 0;
-}
-
-static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
+static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
                        struct msi_desc *desc)
 {
-       int irq, pos, msgvec;
-       u16 msg_ctr;
+       int irq, pos;
        struct msi_msg msg;
        struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
 
-       pci_read_config_word(pdev, desc->msi_attrib.pos+PCI_MSI_FLAGS,
-                               &msg_ctr);
-       msgvec = (msg_ctr&PCI_MSI_FLAGS_QSIZE) >> 4;
-       if (msgvec == 0)
-               msgvec = (msg_ctr & PCI_MSI_FLAGS_QMASK) >> 1;
-       if (msgvec > 5)
-               msgvec = 0;
-
-       irq = assign_irq((1 << msgvec), desc, &pos);
+       irq = assign_irq(1, desc, &pos);
        if (irq < 0)
                return irq;
 
-       /*
-        * write_msi_msg() will update PCI_MSI_FLAGS so there is
-        * no need to explicitly call pci_write_config_word().
-        */
-       desc->msi_attrib.multiple = msgvec;
-
        if (pp->ops->get_msi_addr)
                msg.address_lo = pp->ops->get_msi_addr(pp);
        else
@@ -372,17 +298,21 @@ static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
        else
                msg.data = pos;
 
-       write_msi_msg(irq, &msg);
+       pci_write_msi_msg(irq, &msg);
 
        return 0;
 }
 
-static void dw_msi_teardown_irq(struct msi_chip *chip, unsigned int irq)
+static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
 {
-       clear_irq(irq);
+       struct irq_data *data = irq_get_irq_data(irq);
+       struct msi_desc *msi = irq_data_get_msi(data);
+       struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
+
+       clear_irq_range(pp, irq, 1, data->hwirq);
 }
 
-static struct msi_chip dw_pcie_msi_chip = {
+static struct msi_controller dw_pcie_msi_chip = {
        .setup_irq = dw_msi_setup_irq,
        .teardown_irq = dw_msi_teardown_irq,
 };
@@ -568,6 +498,11 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
        val |= PORT_LOGIC_SPEED_CHANGE;
        dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
 
+#ifdef CONFIG_PCI_MSI
+       dw_pcie_msi_chip.dev = pp->dev;
+       dw_pci.msi_ctrl = &dw_pcie_msi_chip;
+#endif
+
        dw_pci.nr_controllers = 1;
        dw_pci.private_data = (void **)&pp;
 
@@ -817,21 +752,10 @@ static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
        return irq;
 }
 
-static void dw_pcie_add_bus(struct pci_bus *bus)
-{
-       if (IS_ENABLED(CONFIG_PCI_MSI)) {
-               struct pcie_port *pp = sys_to_pcie(bus->sysdata);
-
-               dw_pcie_msi_chip.dev = pp->dev;
-               bus->msi = &dw_pcie_msi_chip;
-       }
-}
-
 static struct hw_pci dw_pci = {
        .setup          = dw_pcie_setup,
        .scan           = dw_pcie_scan_bus,
        .map_irq        = dw_pcie_map_irq,
-       .add_bus        = dw_pcie_add_bus,
 };
 
 void dw_pcie_setup_rc(struct pcie_port *pp)
This page took 0.135784 seconds and 5 git commands to generate.