diff options
Diffstat (limited to 'drivers/ssb/embedded.c')
-rw-r--r-- | drivers/ssb/embedded.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/drivers/ssb/embedded.c b/drivers/ssb/embedded.c index d3ade821555c..7dc3a6b41397 100644 --- a/drivers/ssb/embedded.c +++ b/drivers/ssb/embedded.c | |||
@@ -10,6 +10,9 @@ | |||
10 | 10 | ||
11 | #include <linux/ssb/ssb.h> | 11 | #include <linux/ssb/ssb.h> |
12 | #include <linux/ssb/ssb_embedded.h> | 12 | #include <linux/ssb/ssb_embedded.h> |
13 | #include <linux/ssb/ssb_driver_pci.h> | ||
14 | #include <linux/ssb/ssb_driver_gige.h> | ||
15 | #include <linux/pci.h> | ||
13 | 16 | ||
14 | #include "ssb_private.h" | 17 | #include "ssb_private.h" |
15 | 18 | ||
@@ -130,3 +133,90 @@ u32 ssb_gpio_polarity(struct ssb_bus *bus, u32 mask, u32 value) | |||
130 | return res; | 133 | return res; |
131 | } | 134 | } |
132 | EXPORT_SYMBOL(ssb_gpio_polarity); | 135 | EXPORT_SYMBOL(ssb_gpio_polarity); |
136 | |||
137 | #ifdef CONFIG_SSB_DRIVER_GIGE | ||
138 | static int gige_pci_init_callback(struct ssb_bus *bus, unsigned long data) | ||
139 | { | ||
140 | struct pci_dev *pdev = (struct pci_dev *)data; | ||
141 | struct ssb_device *dev; | ||
142 | unsigned int i; | ||
143 | int res; | ||
144 | |||
145 | for (i = 0; i < bus->nr_devices; i++) { | ||
146 | dev = &(bus->devices[i]); | ||
147 | if (dev->id.coreid != SSB_DEV_ETHERNET_GBIT) | ||
148 | continue; | ||
149 | if (!dev->dev || | ||
150 | !dev->dev->driver || | ||
151 | !device_is_registered(dev->dev)) | ||
152 | continue; | ||
153 | res = ssb_gige_pcibios_plat_dev_init(dev, pdev); | ||
154 | if (res >= 0) | ||
155 | return res; | ||
156 | } | ||
157 | |||
158 | return -ENODEV; | ||
159 | } | ||
160 | #endif /* CONFIG_SSB_DRIVER_GIGE */ | ||
161 | |||
162 | int ssb_pcibios_plat_dev_init(struct pci_dev *dev) | ||
163 | { | ||
164 | int err; | ||
165 | |||
166 | err = ssb_pcicore_plat_dev_init(dev); | ||
167 | if (!err) | ||
168 | return 0; | ||
169 | #ifdef CONFIG_SSB_DRIVER_GIGE | ||
170 | err = ssb_for_each_bus_call((unsigned long)dev, gige_pci_init_callback); | ||
171 | if (err >= 0) | ||
172 | return err; | ||
173 | #endif | ||
174 | /* This is not a PCI device on any SSB device. */ | ||
175 | |||
176 | return -ENODEV; | ||
177 | } | ||
178 | |||
179 | #ifdef CONFIG_SSB_DRIVER_GIGE | ||
180 | static int gige_map_irq_callback(struct ssb_bus *bus, unsigned long data) | ||
181 | { | ||
182 | const struct pci_dev *pdev = (const struct pci_dev *)data; | ||
183 | struct ssb_device *dev; | ||
184 | unsigned int i; | ||
185 | int res; | ||
186 | |||
187 | for (i = 0; i < bus->nr_devices; i++) { | ||
188 | dev = &(bus->devices[i]); | ||
189 | if (dev->id.coreid != SSB_DEV_ETHERNET_GBIT) | ||
190 | continue; | ||
191 | if (!dev->dev || | ||
192 | !dev->dev->driver || | ||
193 | !device_is_registered(dev->dev)) | ||
194 | continue; | ||
195 | res = ssb_gige_map_irq(dev, pdev); | ||
196 | if (res >= 0) | ||
197 | return res; | ||
198 | } | ||
199 | |||
200 | return -ENODEV; | ||
201 | } | ||
202 | #endif /* CONFIG_SSB_DRIVER_GIGE */ | ||
203 | |||
204 | int ssb_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||
205 | { | ||
206 | int res; | ||
207 | |||
208 | /* Check if this PCI device is a device on a SSB bus or device | ||
209 | * and return the IRQ number for it. */ | ||
210 | |||
211 | res = ssb_pcicore_pcibios_map_irq(dev, slot, pin); | ||
212 | if (res >= 0) | ||
213 | return res; | ||
214 | #ifdef CONFIG_SSB_DRIVER_GIGE | ||
215 | res = ssb_for_each_bus_call((unsigned long)dev, gige_map_irq_callback); | ||
216 | if (res >= 0) | ||
217 | return res; | ||
218 | #endif | ||
219 | /* This is not a PCI device on any SSB device. */ | ||
220 | |||
221 | return -ENODEV; | ||
222 | } | ||