|
@@ -991,114 +991,6 @@ h_error:
|
|
return -EINVAL;
|
|
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)
|
|
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);
|
|
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 */
|
|
#else /* CONFIG_PCI_MSI */
|
|
static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
|
|
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++;
|
|
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
|
|
/* Like PSYCHO and SCHIZO we have a 2GB aligned area
|
|
* for memory space.
|
|
* for memory space.
|
|
*/
|
|
*/
|