1 /* 2 * Sonics Silicon Backplane 3 * Embedded systems support code 4 * 5 * Copyright 2005-2008, Broadcom Corporation 6 * Copyright 2006-2008, Michael Buesch <mb@bu3sch.de> 7 * 8 * Licensed under the GNU/GPL. See COPYING for details. 9 */ 10 11 #include <linux/ssb/ssb.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> 16 17 #include "ssb_private.h" 18 19 20 int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks) 21 { 22 if (ssb_chipco_available(&bus->chipco)) { 23 ssb_chipco_watchdog_timer_set(&bus->chipco, ticks); 24 return 0; 25 } 26 if (ssb_extif_available(&bus->extif)) { 27 ssb_extif_watchdog_timer_set(&bus->extif, ticks); 28 return 0; 29 } 30 return -ENODEV; 31 } 32 33 u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask) 34 { 35 unsigned long flags; 36 u32 res = 0; 37 38 spin_lock_irqsave(&bus->gpio_lock, flags); 39 if (ssb_chipco_available(&bus->chipco)) 40 res = ssb_chipco_gpio_in(&bus->chipco, mask); 41 else if (ssb_extif_available(&bus->extif)) 42 res = ssb_extif_gpio_in(&bus->extif, mask); 43 else 44 SSB_WARN_ON(1); 45 spin_unlock_irqrestore(&bus->gpio_lock, flags); 46 47 return res; 48 } 49 EXPORT_SYMBOL(ssb_gpio_in); 50 51 u32 ssb_gpio_out(struct ssb_bus *bus, u32 mask, u32 value) 52 { 53 unsigned long flags; 54 u32 res = 0; 55 56 spin_lock_irqsave(&bus->gpio_lock, flags); 57 if (ssb_chipco_available(&bus->chipco)) 58 res = ssb_chipco_gpio_out(&bus->chipco, mask, value); 59 else if (ssb_extif_available(&bus->extif)) 60 res = ssb_extif_gpio_out(&bus->extif, mask, value); 61 else 62 SSB_WARN_ON(1); 63 spin_unlock_irqrestore(&bus->gpio_lock, flags); 64 65 return res; 66 } 67 EXPORT_SYMBOL(ssb_gpio_out); 68 69 u32 ssb_gpio_outen(struct ssb_bus *bus, u32 mask, u32 value) 70 { 71 unsigned long flags; 72 u32 res = 0; 73 74 spin_lock_irqsave(&bus->gpio_lock, flags); 75 if (ssb_chipco_available(&bus->chipco)) 76 res = ssb_chipco_gpio_outen(&bus->chipco, mask, value); 77 else if (ssb_extif_available(&bus->extif)) 78 res = ssb_extif_gpio_outen(&bus->extif, mask, value); 79 else 80 SSB_WARN_ON(1); 81 spin_unlock_irqrestore(&bus->gpio_lock, flags); 82 83 return res; 84 } 85 EXPORT_SYMBOL(ssb_gpio_outen); 86 87 u32 ssb_gpio_control(struct ssb_bus *bus, u32 mask, u32 value) 88 { 89 unsigned long flags; 90 u32 res = 0; 91 92 spin_lock_irqsave(&bus->gpio_lock, flags); 93 if (ssb_chipco_available(&bus->chipco)) 94 res = ssb_chipco_gpio_control(&bus->chipco, mask, value); 95 spin_unlock_irqrestore(&bus->gpio_lock, flags); 96 97 return res; 98 } 99 EXPORT_SYMBOL(ssb_gpio_control); 100 101 u32 ssb_gpio_intmask(struct ssb_bus *bus, u32 mask, u32 value) 102 { 103 unsigned long flags; 104 u32 res = 0; 105 106 spin_lock_irqsave(&bus->gpio_lock, flags); 107 if (ssb_chipco_available(&bus->chipco)) 108 res = ssb_chipco_gpio_intmask(&bus->chipco, mask, value); 109 else if (ssb_extif_available(&bus->extif)) 110 res = ssb_extif_gpio_intmask(&bus->extif, mask, value); 111 else 112 SSB_WARN_ON(1); 113 spin_unlock_irqrestore(&bus->gpio_lock, flags); 114 115 return res; 116 } 117 EXPORT_SYMBOL(ssb_gpio_intmask); 118 119 u32 ssb_gpio_polarity(struct ssb_bus *bus, u32 mask, u32 value) 120 { 121 unsigned long flags; 122 u32 res = 0; 123 124 spin_lock_irqsave(&bus->gpio_lock, flags); 125 if (ssb_chipco_available(&bus->chipco)) 126 res = ssb_chipco_gpio_polarity(&bus->chipco, mask, value); 127 else if (ssb_extif_available(&bus->extif)) 128 res = ssb_extif_gpio_polarity(&bus->extif, mask, value); 129 else 130 SSB_WARN_ON(1); 131 spin_unlock_irqrestore(&bus->gpio_lock, flags); 132 133 return res; 134 } 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 } 223