1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * arch/arm/mach-orion5x/rd88f5182-setup.c 4 * 5 * Marvell Orion-NAS Reference Design Setup 6 * 7 * Maintainer: Ronen Shitrit <rshitrit@marvell.com> 8 */ 9 #include <linux/gpio.h> 10 #include <linux/kernel.h> 11 #include <linux/init.h> 12 #include <linux/platform_device.h> 13 #include <linux/pci.h> 14 #include <linux/irq.h> 15 #include <asm/mach-types.h> 16 #include <asm/mach/arch.h> 17 #include <asm/mach/pci.h> 18 #include "common.h" 19 #include "orion5x.h" 20 21 /***************************************************************************** 22 * RD-88F5182 Info 23 ****************************************************************************/ 24 25 /* 26 * PCI 27 */ 28 29 #define RD88F5182_PCI_SLOT0_OFFS 7 30 #define RD88F5182_PCI_SLOT0_IRQ_A_PIN 7 31 #define RD88F5182_PCI_SLOT0_IRQ_B_PIN 6 32 33 /***************************************************************************** 34 * PCI 35 ****************************************************************************/ 36 37 static void __init rd88f5182_pci_preinit(void) 38 { 39 int pin; 40 41 /* 42 * Configure PCI GPIO IRQ pins 43 */ 44 pin = RD88F5182_PCI_SLOT0_IRQ_A_PIN; 45 if (gpio_request(pin, "PCI IntA") == 0) { 46 if (gpio_direction_input(pin) == 0) { 47 irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); 48 } else { 49 printk(KERN_ERR "rd88f5182_pci_preinit failed to " 50 "set_irq_type pin %d\n", pin); 51 gpio_free(pin); 52 } 53 } else { 54 printk(KERN_ERR "rd88f5182_pci_preinit failed to request gpio %d\n", pin); 55 } 56 57 pin = RD88F5182_PCI_SLOT0_IRQ_B_PIN; 58 if (gpio_request(pin, "PCI IntB") == 0) { 59 if (gpio_direction_input(pin) == 0) { 60 irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); 61 } else { 62 printk(KERN_ERR "rd88f5182_pci_preinit failed to " 63 "set_irq_type pin %d\n", pin); 64 gpio_free(pin); 65 } 66 } else { 67 printk(KERN_ERR "rd88f5182_pci_preinit failed to gpio_request %d\n", pin); 68 } 69 } 70 71 static int __init rd88f5182_pci_map_irq(const struct pci_dev *dev, u8 slot, 72 u8 pin) 73 { 74 int irq; 75 76 /* 77 * Check for devices with hard-wired IRQs. 78 */ 79 irq = orion5x_pci_map_irq(dev, slot, pin); 80 if (irq != -1) 81 return irq; 82 83 /* 84 * PCI IRQs are connected via GPIOs 85 */ 86 switch (slot - RD88F5182_PCI_SLOT0_OFFS) { 87 case 0: 88 if (pin == 1) 89 return gpio_to_irq(RD88F5182_PCI_SLOT0_IRQ_A_PIN); 90 else 91 return gpio_to_irq(RD88F5182_PCI_SLOT0_IRQ_B_PIN); 92 default: 93 return -1; 94 } 95 } 96 97 static struct hw_pci rd88f5182_pci __initdata = { 98 .nr_controllers = 2, 99 .preinit = rd88f5182_pci_preinit, 100 .setup = orion5x_pci_sys_setup, 101 .scan = orion5x_pci_sys_scan_bus, 102 .map_irq = rd88f5182_pci_map_irq, 103 }; 104 105 static int __init rd88f5182_pci_init(void) 106 { 107 if (of_machine_is_compatible("marvell,rd-88f5182-nas")) 108 pci_common_init(&rd88f5182_pci); 109 110 return 0; 111 } 112 113 subsys_initcall(rd88f5182_pci_init); 114