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 EXPORT_SYMBOL(ssb_watchdog_timer_set); 33 34 u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask) 35 { 36 unsigned long flags; 37 u32 res = 0; 38 39 spin_lock_irqsave(&bus->gpio_lock, flags); 40 if (ssb_chipco_available(&bus->chipco)) 41 res = ssb_chipco_gpio_in(&bus->chipco, mask); 42 else if (ssb_extif_available(&bus->extif)) 43 res = ssb_extif_gpio_in(&bus->extif, mask); 44 else 45 SSB_WARN_ON(1); 46 spin_unlock_irqrestore(&bus->gpio_lock, flags); 47 48 return res; 49 } 50 EXPORT_SYMBOL(ssb_gpio_in); 51 52 u32 ssb_gpio_out(struct ssb_bus *bus, u32 mask, u32 value) 53 { 54 unsigned long flags; 55 u32 res = 0; 56 57 spin_lock_irqsave(&bus->gpio_lock, flags); 58 if (ssb_chipco_available(&bus->chipco)) 59 res = ssb_chipco_gpio_out(&bus->chipco, mask, value); 60 else if (ssb_extif_available(&bus->extif)) 61 res = ssb_extif_gpio_out(&bus->extif, mask, value); 62 else 63 SSB_WARN_ON(1); 64 spin_unlock_irqrestore(&bus->gpio_lock, flags); 65 66 return res; 67 } 68 EXPORT_SYMBOL(ssb_gpio_out); 69 70 u32 ssb_gpio_outen(struct ssb_bus *bus, u32 mask, u32 value) 71 { 72 unsigned long flags; 73 u32 res = 0; 74 75 spin_lock_irqsave(&bus->gpio_lock, flags); 76 if (ssb_chipco_available(&bus->chipco)) 77 res = ssb_chipco_gpio_outen(&bus->chipco, mask, value); 78 else if (ssb_extif_available(&bus->extif)) 79 res = ssb_extif_gpio_outen(&bus->extif, mask, value); 80 else 81 SSB_WARN_ON(1); 82 spin_unlock_irqrestore(&bus->gpio_lock, flags); 83 84 return res; 85 } 86 EXPORT_SYMBOL(ssb_gpio_outen); 87 88 u32 ssb_gpio_control(struct ssb_bus *bus, u32 mask, u32 value) 89 { 90 unsigned long flags; 91 u32 res = 0; 92 93 spin_lock_irqsave(&bus->gpio_lock, flags); 94 if (ssb_chipco_available(&bus->chipco)) 95 res = ssb_chipco_gpio_control(&bus->chipco, mask, value); 96 spin_unlock_irqrestore(&bus->gpio_lock, flags); 97 98 return res; 99 } 100 EXPORT_SYMBOL(ssb_gpio_control); 101 102 u32 ssb_gpio_intmask(struct ssb_bus *bus, u32 mask, u32 value) 103 { 104 unsigned long flags; 105 u32 res = 0; 106 107 spin_lock_irqsave(&bus->gpio_lock, flags); 108 if (ssb_chipco_available(&bus->chipco)) 109 res = ssb_chipco_gpio_intmask(&bus->chipco, mask, value); 110 else if (ssb_extif_available(&bus->extif)) 111 res = ssb_extif_gpio_intmask(&bus->extif, mask, value); 112 else 113 SSB_WARN_ON(1); 114 spin_unlock_irqrestore(&bus->gpio_lock, flags); 115 116 return res; 117 } 118 EXPORT_SYMBOL(ssb_gpio_intmask); 119 120 u32 ssb_gpio_polarity(struct ssb_bus *bus, u32 mask, u32 value) 121 { 122 unsigned long flags; 123 u32 res = 0; 124 125 spin_lock_irqsave(&bus->gpio_lock, flags); 126 if (ssb_chipco_available(&bus->chipco)) 127 res = ssb_chipco_gpio_polarity(&bus->chipco, mask, value); 128 else if (ssb_extif_available(&bus->extif)) 129 res = ssb_extif_gpio_polarity(&bus->extif, mask, value); 130 else 131 SSB_WARN_ON(1); 132 spin_unlock_irqrestore(&bus->gpio_lock, flags); 133 134 return res; 135 } 136 EXPORT_SYMBOL(ssb_gpio_polarity); 137 138 #ifdef CONFIG_SSB_DRIVER_GIGE 139 static int gige_pci_init_callback(struct ssb_bus *bus, unsigned long data) 140 { 141 struct pci_dev *pdev = (struct pci_dev *)data; 142 struct ssb_device *dev; 143 unsigned int i; 144 int res; 145 146 for (i = 0; i < bus->nr_devices; i++) { 147 dev = &(bus->devices[i]); 148 if (dev->id.coreid != SSB_DEV_ETHERNET_GBIT) 149 continue; 150 if (!dev->dev || 151 !dev->dev->driver || 152 !device_is_registered(dev->dev)) 153 continue; 154 res = ssb_gige_pcibios_plat_dev_init(dev, pdev); 155 if (res >= 0) 156 return res; 157 } 158 159 return -ENODEV; 160 } 161 #endif /* CONFIG_SSB_DRIVER_GIGE */ 162 163 int ssb_pcibios_plat_dev_init(struct pci_dev *dev) 164 { 165 int err; 166 167 err = ssb_pcicore_plat_dev_init(dev); 168 if (!err) 169 return 0; 170 #ifdef CONFIG_SSB_DRIVER_GIGE 171 err = ssb_for_each_bus_call((unsigned long)dev, gige_pci_init_callback); 172 if (err >= 0) 173 return err; 174 #endif 175 /* This is not a PCI device on any SSB device. */ 176 177 return -ENODEV; 178 } 179 180 #ifdef CONFIG_SSB_DRIVER_GIGE 181 static int gige_map_irq_callback(struct ssb_bus *bus, unsigned long data) 182 { 183 const struct pci_dev *pdev = (const struct pci_dev *)data; 184 struct ssb_device *dev; 185 unsigned int i; 186 int res; 187 188 for (i = 0; i < bus->nr_devices; i++) { 189 dev = &(bus->devices[i]); 190 if (dev->id.coreid != SSB_DEV_ETHERNET_GBIT) 191 continue; 192 if (!dev->dev || 193 !dev->dev->driver || 194 !device_is_registered(dev->dev)) 195 continue; 196 res = ssb_gige_map_irq(dev, pdev); 197 if (res >= 0) 198 return res; 199 } 200 201 return -ENODEV; 202 } 203 #endif /* CONFIG_SSB_DRIVER_GIGE */ 204 205 int ssb_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 206 { 207 int res; 208 209 /* Check if this PCI device is a device on a SSB bus or device 210 * and return the IRQ number for it. */ 211 212 res = ssb_pcicore_pcibios_map_irq(dev, slot, pin); 213 if (res >= 0) 214 return res; 215 #ifdef CONFIG_SSB_DRIVER_GIGE 216 res = ssb_for_each_bus_call((unsigned long)dev, gige_map_irq_callback); 217 if (res >= 0) 218 return res; 219 #endif 220 /* This is not a PCI device on any SSB device. */ 221 222 return -ENODEV; 223 } 224