diff options
Diffstat (limited to 'arch/s390/pci/pci.c')
-rw-r--r-- | arch/s390/pci/pci.c | 202 |
1 files changed, 111 insertions, 91 deletions
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 0c9a17780e4b..bf7c73d71eef 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
@@ -530,20 +530,6 @@ static void zpci_unmap_resources(struct zpci_dev *zdev) | |||
530 | } | 530 | } |
531 | } | 531 | } |
532 | 532 | ||
533 | struct zpci_dev *zpci_alloc_device(void) | ||
534 | { | ||
535 | struct zpci_dev *zdev; | ||
536 | |||
537 | /* Alloc memory for our private pci device data */ | ||
538 | zdev = kzalloc(sizeof(*zdev), GFP_KERNEL); | ||
539 | return zdev ? : ERR_PTR(-ENOMEM); | ||
540 | } | ||
541 | |||
542 | void zpci_free_device(struct zpci_dev *zdev) | ||
543 | { | ||
544 | kfree(zdev); | ||
545 | } | ||
546 | |||
547 | int pcibios_add_platform_entries(struct pci_dev *pdev) | 533 | int pcibios_add_platform_entries(struct pci_dev *pdev) |
548 | { | 534 | { |
549 | return zpci_sysfs_add_device(&pdev->dev); | 535 | return zpci_sysfs_add_device(&pdev->dev); |
@@ -579,37 +565,6 @@ static void zpci_irq_exit(void) | |||
579 | unregister_adapter_interrupt(&zpci_airq); | 565 | unregister_adapter_interrupt(&zpci_airq); |
580 | } | 566 | } |
581 | 567 | ||
582 | static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size, | ||
583 | unsigned long flags, int domain) | ||
584 | { | ||
585 | struct resource *r; | ||
586 | char *name; | ||
587 | int rc; | ||
588 | |||
589 | r = kzalloc(sizeof(*r), GFP_KERNEL); | ||
590 | if (!r) | ||
591 | return ERR_PTR(-ENOMEM); | ||
592 | r->start = start; | ||
593 | r->end = r->start + size - 1; | ||
594 | r->flags = flags; | ||
595 | r->parent = &iomem_resource; | ||
596 | name = kmalloc(18, GFP_KERNEL); | ||
597 | if (!name) { | ||
598 | kfree(r); | ||
599 | return ERR_PTR(-ENOMEM); | ||
600 | } | ||
601 | sprintf(name, "PCI Bus: %04x:%02x", domain, ZPCI_BUS_NR); | ||
602 | r->name = name; | ||
603 | |||
604 | rc = request_resource(&iomem_resource, r); | ||
605 | if (rc) { | ||
606 | kfree(r->name); | ||
607 | kfree(r); | ||
608 | return ERR_PTR(-ENOMEM); | ||
609 | } | ||
610 | return r; | ||
611 | } | ||
612 | |||
613 | static int zpci_alloc_iomap(struct zpci_dev *zdev) | 568 | static int zpci_alloc_iomap(struct zpci_dev *zdev) |
614 | { | 569 | { |
615 | int entry; | 570 | int entry; |
@@ -633,6 +588,82 @@ static void zpci_free_iomap(struct zpci_dev *zdev, int entry) | |||
633 | spin_unlock(&zpci_iomap_lock); | 588 | spin_unlock(&zpci_iomap_lock); |
634 | } | 589 | } |
635 | 590 | ||
591 | static struct resource *__alloc_res(struct zpci_dev *zdev, unsigned long start, | ||
592 | unsigned long size, unsigned long flags) | ||
593 | { | ||
594 | struct resource *r; | ||
595 | |||
596 | r = kzalloc(sizeof(*r), GFP_KERNEL); | ||
597 | if (!r) | ||
598 | return NULL; | ||
599 | |||
600 | r->start = start; | ||
601 | r->end = r->start + size - 1; | ||
602 | r->flags = flags; | ||
603 | r->name = zdev->res_name; | ||
604 | |||
605 | if (request_resource(&iomem_resource, r)) { | ||
606 | kfree(r); | ||
607 | return NULL; | ||
608 | } | ||
609 | return r; | ||
610 | } | ||
611 | |||
612 | static int zpci_setup_bus_resources(struct zpci_dev *zdev, | ||
613 | struct list_head *resources) | ||
614 | { | ||
615 | unsigned long addr, size, flags; | ||
616 | struct resource *res; | ||
617 | int i, entry; | ||
618 | |||
619 | snprintf(zdev->res_name, sizeof(zdev->res_name), | ||
620 | "PCI Bus %04x:%02x", zdev->domain, ZPCI_BUS_NR); | ||
621 | |||
622 | for (i = 0; i < PCI_BAR_COUNT; i++) { | ||
623 | if (!zdev->bars[i].size) | ||
624 | continue; | ||
625 | entry = zpci_alloc_iomap(zdev); | ||
626 | if (entry < 0) | ||
627 | return entry; | ||
628 | zdev->bars[i].map_idx = entry; | ||
629 | |||
630 | /* only MMIO is supported */ | ||
631 | flags = IORESOURCE_MEM; | ||
632 | if (zdev->bars[i].val & 8) | ||
633 | flags |= IORESOURCE_PREFETCH; | ||
634 | if (zdev->bars[i].val & 4) | ||
635 | flags |= IORESOURCE_MEM_64; | ||
636 | |||
637 | addr = ZPCI_IOMAP_ADDR_BASE + ((u64) entry << 48); | ||
638 | |||
639 | size = 1UL << zdev->bars[i].size; | ||
640 | |||
641 | res = __alloc_res(zdev, addr, size, flags); | ||
642 | if (!res) { | ||
643 | zpci_free_iomap(zdev, entry); | ||
644 | return -ENOMEM; | ||
645 | } | ||
646 | zdev->bars[i].res = res; | ||
647 | pci_add_resource(resources, res); | ||
648 | } | ||
649 | |||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | static void zpci_cleanup_bus_resources(struct zpci_dev *zdev) | ||
654 | { | ||
655 | int i; | ||
656 | |||
657 | for (i = 0; i < PCI_BAR_COUNT; i++) { | ||
658 | if (!zdev->bars[i].size) | ||
659 | continue; | ||
660 | |||
661 | zpci_free_iomap(zdev, zdev->bars[i].map_idx); | ||
662 | release_resource(zdev->bars[i].res); | ||
663 | kfree(zdev->bars[i].res); | ||
664 | } | ||
665 | } | ||
666 | |||
636 | int pcibios_add_device(struct pci_dev *pdev) | 667 | int pcibios_add_device(struct pci_dev *pdev) |
637 | { | 668 | { |
638 | struct zpci_dev *zdev = get_zdev(pdev); | 669 | struct zpci_dev *zdev = get_zdev(pdev); |
@@ -729,52 +760,6 @@ struct dev_pm_ops pcibios_pm_ops = { | |||
729 | }; | 760 | }; |
730 | #endif /* CONFIG_HIBERNATE_CALLBACKS */ | 761 | #endif /* CONFIG_HIBERNATE_CALLBACKS */ |
731 | 762 | ||
732 | static int zpci_scan_bus(struct zpci_dev *zdev) | ||
733 | { | ||
734 | struct resource *res; | ||
735 | LIST_HEAD(resources); | ||
736 | int i; | ||
737 | |||
738 | /* allocate mapping entry for each used bar */ | ||
739 | for (i = 0; i < PCI_BAR_COUNT; i++) { | ||
740 | unsigned long addr, size, flags; | ||
741 | int entry; | ||
742 | |||
743 | if (!zdev->bars[i].size) | ||
744 | continue; | ||
745 | entry = zpci_alloc_iomap(zdev); | ||
746 | if (entry < 0) | ||
747 | return entry; | ||
748 | zdev->bars[i].map_idx = entry; | ||
749 | |||
750 | /* only MMIO is supported */ | ||
751 | flags = IORESOURCE_MEM; | ||
752 | if (zdev->bars[i].val & 8) | ||
753 | flags |= IORESOURCE_PREFETCH; | ||
754 | if (zdev->bars[i].val & 4) | ||
755 | flags |= IORESOURCE_MEM_64; | ||
756 | |||
757 | addr = ZPCI_IOMAP_ADDR_BASE + ((u64) entry << 48); | ||
758 | |||
759 | size = 1UL << zdev->bars[i].size; | ||
760 | |||
761 | res = zpci_alloc_bus_resource(addr, size, flags, zdev->domain); | ||
762 | if (IS_ERR(res)) { | ||
763 | zpci_free_iomap(zdev, entry); | ||
764 | return PTR_ERR(res); | ||
765 | } | ||
766 | pci_add_resource(&resources, res); | ||
767 | } | ||
768 | |||
769 | zdev->bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, | ||
770 | zdev, &resources); | ||
771 | if (!zdev->bus) | ||
772 | return -EIO; | ||
773 | |||
774 | zdev->bus->max_bus_speed = zdev->max_bus_speed; | ||
775 | return 0; | ||
776 | } | ||
777 | |||
778 | static int zpci_alloc_domain(struct zpci_dev *zdev) | 763 | static int zpci_alloc_domain(struct zpci_dev *zdev) |
779 | { | 764 | { |
780 | spin_lock(&zpci_domain_lock); | 765 | spin_lock(&zpci_domain_lock); |
@@ -795,6 +780,41 @@ static void zpci_free_domain(struct zpci_dev *zdev) | |||
795 | spin_unlock(&zpci_domain_lock); | 780 | spin_unlock(&zpci_domain_lock); |
796 | } | 781 | } |
797 | 782 | ||
783 | void pcibios_remove_bus(struct pci_bus *bus) | ||
784 | { | ||
785 | struct zpci_dev *zdev = get_zdev_by_bus(bus); | ||
786 | |||
787 | zpci_exit_slot(zdev); | ||
788 | zpci_cleanup_bus_resources(zdev); | ||
789 | zpci_free_domain(zdev); | ||
790 | |||
791 | spin_lock(&zpci_list_lock); | ||
792 | list_del(&zdev->entry); | ||
793 | spin_unlock(&zpci_list_lock); | ||
794 | |||
795 | kfree(zdev); | ||
796 | } | ||
797 | |||
798 | static int zpci_scan_bus(struct zpci_dev *zdev) | ||
799 | { | ||
800 | LIST_HEAD(resources); | ||
801 | int ret; | ||
802 | |||
803 | ret = zpci_setup_bus_resources(zdev, &resources); | ||
804 | if (ret) | ||
805 | return ret; | ||
806 | |||
807 | zdev->bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, | ||
808 | zdev, &resources); | ||
809 | if (!zdev->bus) { | ||
810 | zpci_cleanup_bus_resources(zdev); | ||
811 | return -EIO; | ||
812 | } | ||
813 | |||
814 | zdev->bus->max_bus_speed = zdev->max_bus_speed; | ||
815 | return 0; | ||
816 | } | ||
817 | |||
798 | int zpci_enable_device(struct zpci_dev *zdev) | 818 | int zpci_enable_device(struct zpci_dev *zdev) |
799 | { | 819 | { |
800 | int rc; | 820 | int rc; |