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