Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9870c4c authored by David S. Miller's avatar David S. Miller
Browse files

[SPARC64]: Move {setup,teardown}_msi_irq into pci_pbm_info.

parent f1cd8de2
Loading
Loading
Loading
Loading
+5 −11
Original line number Diff line number Diff line
@@ -1092,17 +1092,12 @@ EXPORT_SYMBOL(pci_domain_nr);
int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
{
	struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
	struct pci_controller_info *p = pbm->parent;
	int virt_irq, err;
	int virt_irq;

	if (!pbm->msi_num || !p->setup_msi_irq)
	if (!pbm->setup_msi_irq)
		return -EINVAL;

	err = p->setup_msi_irq(&virt_irq, pdev, desc);
	if (err)
		return err;

	return 0;
	return pbm->setup_msi_irq(&virt_irq, pdev, desc);
}

void arch_teardown_msi_irq(unsigned int virt_irq)
@@ -1110,12 +1105,11 @@ void arch_teardown_msi_irq(unsigned int virt_irq)
	struct msi_desc *entry = get_irq_msi(virt_irq);
	struct pci_dev *pdev = entry->dev;
	struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
	struct pci_controller_info *p = pbm->parent;

	if (!pbm->msi_num || !p->setup_msi_irq)
	if (!pbm->teardown_msi_irq)
		return;

	return p->teardown_msi_irq(virt_irq, pdev);
	return pbm->teardown_msi_irq(virt_irq, pdev);
}
#endif /* !(CONFIG_PCI_MSI) */

+111 −113
Original line number Diff line number Diff line
@@ -991,114 +991,6 @@ static int msi_queue_alloc(struct pci_pbm_info *pbm)
	return -EINVAL;
}

static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
{
	const u32 *val;
	int len;

	val = of_get_property(pbm->prom_node, "#msi-eqs", &len);
	if (!val || len != 4)
		goto no_msi;
	pbm->msiq_num = *val;
	if (pbm->msiq_num) {
		const struct msiq_prop {
			u32 first_msiq;
			u32 num_msiq;
			u32 first_devino;
		} *mqp;
		const struct msi_range_prop {
			u32 first_msi;
			u32 num_msi;
		} *mrng;
		const struct addr_range_prop {
			u32 msi32_high;
			u32 msi32_low;
			u32 msi32_len;
			u32 msi64_high;
			u32 msi64_low;
			u32 msi64_len;
		} *arng;

		val = of_get_property(pbm->prom_node, "msi-eq-size", &len);
		if (!val || len != 4)
			goto no_msi;

		pbm->msiq_ent_count = *val;

		mqp = of_get_property(pbm->prom_node,
				      "msi-eq-to-devino", &len);
		if (!mqp || len != sizeof(struct msiq_prop))
			goto no_msi;

		pbm->msiq_first = mqp->first_msiq;
		pbm->msiq_first_devino = mqp->first_devino;

		val = of_get_property(pbm->prom_node, "#msi", &len);
		if (!val || len != 4)
			goto no_msi;
		pbm->msi_num = *val;

		mrng = of_get_property(pbm->prom_node, "msi-ranges", &len);
		if (!mrng || len != sizeof(struct msi_range_prop))
			goto no_msi;
		pbm->msi_first = mrng->first_msi;

		val = of_get_property(pbm->prom_node, "msi-data-mask", &len);
		if (!val || len != 4)
			goto no_msi;
		pbm->msi_data_mask = *val;

		val = of_get_property(pbm->prom_node, "msix-data-width", &len);
		if (!val || len != 4)
			goto no_msi;
		pbm->msix_data_width = *val;

		arng = of_get_property(pbm->prom_node, "msi-address-ranges",
				       &len);
		if (!arng || len != sizeof(struct addr_range_prop))
			goto no_msi;
		pbm->msi32_start = ((u64)arng->msi32_high << 32) |
			(u64) arng->msi32_low;
		pbm->msi64_start = ((u64)arng->msi64_high << 32) |
			(u64) arng->msi64_low;
		pbm->msi32_len = arng->msi32_len;
		pbm->msi64_len = arng->msi64_len;

		if (msi_bitmap_alloc(pbm))
			goto no_msi;

		if (msi_queue_alloc(pbm)) {
			msi_bitmap_free(pbm);
			goto no_msi;
		}

		printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] "
		       "devino[0x%x]\n",
		       pbm->name,
		       pbm->msiq_first, pbm->msiq_num,
		       pbm->msiq_ent_count,
		       pbm->msiq_first_devino);
		printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] "
		       "width[%u]\n",
		       pbm->name,
		       pbm->msi_first, pbm->msi_num, pbm->msi_data_mask,
		       pbm->msix_data_width);
		printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] "
		       "addr64[0x%lx:0x%x]\n",
		       pbm->name,
		       pbm->msi32_start, pbm->msi32_len,
		       pbm->msi64_start, pbm->msi64_len);
		printk(KERN_INFO "%s: MSI queues at RA [%p]\n",
		       pbm->name,
		       pbm->msi_queues);
	}

	return;

no_msi:
	pbm->msiq_num = 0;
	printk(KERN_INFO "%s: No MSI support.\n", pbm->name);
}

static int alloc_msi(struct pci_pbm_info *pbm)
{
@@ -1217,6 +1109,117 @@ static void pci_sun4v_teardown_msi_irq(unsigned int virt_irq,
	 */
	sun4v_destroy_msi(virt_irq);
}

static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
{
	const u32 *val;
	int len;

	val = of_get_property(pbm->prom_node, "#msi-eqs", &len);
	if (!val || len != 4)
		goto no_msi;
	pbm->msiq_num = *val;
	if (pbm->msiq_num) {
		const struct msiq_prop {
			u32 first_msiq;
			u32 num_msiq;
			u32 first_devino;
		} *mqp;
		const struct msi_range_prop {
			u32 first_msi;
			u32 num_msi;
		} *mrng;
		const struct addr_range_prop {
			u32 msi32_high;
			u32 msi32_low;
			u32 msi32_len;
			u32 msi64_high;
			u32 msi64_low;
			u32 msi64_len;
		} *arng;

		val = of_get_property(pbm->prom_node, "msi-eq-size", &len);
		if (!val || len != 4)
			goto no_msi;

		pbm->msiq_ent_count = *val;

		mqp = of_get_property(pbm->prom_node,
				      "msi-eq-to-devino", &len);
		if (!mqp || len != sizeof(struct msiq_prop))
			goto no_msi;

		pbm->msiq_first = mqp->first_msiq;
		pbm->msiq_first_devino = mqp->first_devino;

		val = of_get_property(pbm->prom_node, "#msi", &len);
		if (!val || len != 4)
			goto no_msi;
		pbm->msi_num = *val;

		mrng = of_get_property(pbm->prom_node, "msi-ranges", &len);
		if (!mrng || len != sizeof(struct msi_range_prop))
			goto no_msi;
		pbm->msi_first = mrng->first_msi;

		val = of_get_property(pbm->prom_node, "msi-data-mask", &len);
		if (!val || len != 4)
			goto no_msi;
		pbm->msi_data_mask = *val;

		val = of_get_property(pbm->prom_node, "msix-data-width", &len);
		if (!val || len != 4)
			goto no_msi;
		pbm->msix_data_width = *val;

		arng = of_get_property(pbm->prom_node, "msi-address-ranges",
				       &len);
		if (!arng || len != sizeof(struct addr_range_prop))
			goto no_msi;
		pbm->msi32_start = ((u64)arng->msi32_high << 32) |
			(u64) arng->msi32_low;
		pbm->msi64_start = ((u64)arng->msi64_high << 32) |
			(u64) arng->msi64_low;
		pbm->msi32_len = arng->msi32_len;
		pbm->msi64_len = arng->msi64_len;

		if (msi_bitmap_alloc(pbm))
			goto no_msi;

		if (msi_queue_alloc(pbm)) {
			msi_bitmap_free(pbm);
			goto no_msi;
		}

		printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] "
		       "devino[0x%x]\n",
		       pbm->name,
		       pbm->msiq_first, pbm->msiq_num,
		       pbm->msiq_ent_count,
		       pbm->msiq_first_devino);
		printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] "
		       "width[%u]\n",
		       pbm->name,
		       pbm->msi_first, pbm->msi_num, pbm->msi_data_mask,
		       pbm->msix_data_width);
		printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] "
		       "addr64[0x%lx:0x%x]\n",
		       pbm->name,
		       pbm->msi32_start, pbm->msi32_len,
		       pbm->msi64_start, pbm->msi64_len);
		printk(KERN_INFO "%s: MSI queues at RA [%p]\n",
		       pbm->name,
		       pbm->msi_queues);
	}
	pbm->setup_msi_irq = pci_sun4v_setup_msi_irq;
	pbm->teardown_msi_irq = pci_sun4v_teardown_msi_irq;

	return;

no_msi:
	pbm->msiq_num = 0;
	printk(KERN_INFO "%s: No MSI support.\n", pbm->name);
}
#else /* CONFIG_PCI_MSI */
static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
{
@@ -1303,11 +1306,6 @@ void sun4v_pci_init(struct device_node *dp, char *model_name)

	p->index = pci_num_controllers++;

#ifdef CONFIG_PCI_MSI
	p->setup_msi_irq = pci_sun4v_setup_msi_irq;
	p->teardown_msi_irq = pci_sun4v_teardown_msi_irq;
#endif

	/* Like PSYCHO and SCHIZO we have a 2GB aligned area
	 * for memory space.
	 */
+3 −7
Original line number Diff line number Diff line
@@ -103,6 +103,9 @@ struct pci_pbm_info {
	u32				msi64_len;
	void				*msi_queues;
	unsigned long			*msi_bitmap;
	int (*setup_msi_irq)(unsigned int *virt_irq_p, struct pci_dev *pdev,
			     struct msi_desc *entry);
	void (*teardown_msi_irq)(unsigned int virt_irq, struct pci_dev *pdev);
#endif /* !(CONFIG_PCI_MSI) */

	/* This PBM's streaming buffer. */
@@ -128,13 +131,6 @@ struct pci_controller_info {
	/* The PCI bus modules controlled by us. */
	struct pci_pbm_info		pbm_A;
	struct pci_pbm_info		pbm_B;

	/* Operations which are controller specific. */
#ifdef CONFIG_PCI_MSI
	int (*setup_msi_irq)(unsigned int *virt_irq_p, struct pci_dev *pdev,
			     struct msi_desc *entry);
	void (*teardown_msi_irq)(unsigned int virt_irq, struct pci_dev *pdev);
#endif
};

#endif /* !(__SPARC64_PBM_H) */