root/drivers/ssb/embedded.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ssb_watchdog_timer_set
  2. ssb_watchdog_register
  3. ssb_gpio_in
  4. ssb_gpio_out
  5. ssb_gpio_outen
  6. ssb_gpio_control
  7. ssb_gpio_intmask
  8. ssb_gpio_polarity
  9. gige_pci_init_callback
  10. ssb_pcibios_plat_dev_init
  11. gige_map_irq_callback
  12. ssb_pcibios_map_irq

   1 /*
   2  * Sonics Silicon Backplane
   3  * Embedded systems support code
   4  *
   5  * Copyright 2005-2008, Broadcom Corporation
   6  * Copyright 2006-2008, Michael Buesch <m@bues.ch>
   7  * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
   8  *
   9  * Licensed under the GNU/GPL. See COPYING for details.
  10  */
  11 
  12 #include "ssb_private.h"
  13 
  14 #include <linux/export.h>
  15 #include <linux/platform_device.h>
  16 #include <linux/ssb/ssb.h>
  17 #include <linux/ssb/ssb_embedded.h>
  18 #include <linux/ssb/ssb_driver_pci.h>
  19 #include <linux/ssb/ssb_driver_gige.h>
  20 #include <linux/pci.h>
  21 
  22 
  23 int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks)
  24 {
  25         if (ssb_chipco_available(&bus->chipco)) {
  26                 ssb_chipco_watchdog_timer_set(&bus->chipco, ticks);
  27                 return 0;
  28         }
  29         if (ssb_extif_available(&bus->extif)) {
  30                 ssb_extif_watchdog_timer_set(&bus->extif, ticks);
  31                 return 0;
  32         }
  33         return -ENODEV;
  34 }
  35 EXPORT_SYMBOL(ssb_watchdog_timer_set);
  36 
  37 int ssb_watchdog_register(struct ssb_bus *bus)
  38 {
  39         struct bcm47xx_wdt wdt = {};
  40         struct platform_device *pdev;
  41 
  42         if (ssb_chipco_available(&bus->chipco)) {
  43                 wdt.driver_data = &bus->chipco;
  44                 wdt.timer_set = ssb_chipco_watchdog_timer_set_wdt;
  45                 wdt.timer_set_ms = ssb_chipco_watchdog_timer_set_ms;
  46                 wdt.max_timer_ms = bus->chipco.max_timer_ms;
  47         } else if (ssb_extif_available(&bus->extif)) {
  48                 wdt.driver_data = &bus->extif;
  49                 wdt.timer_set = ssb_extif_watchdog_timer_set_wdt;
  50                 wdt.timer_set_ms = ssb_extif_watchdog_timer_set_ms;
  51                 wdt.max_timer_ms = SSB_EXTIF_WATCHDOG_MAX_TIMER_MS;
  52         } else {
  53                 return -ENODEV;
  54         }
  55 
  56         pdev = platform_device_register_data(NULL, "bcm47xx-wdt",
  57                                              bus->busnumber, &wdt,
  58                                              sizeof(wdt));
  59         if (IS_ERR(pdev)) {
  60                 pr_debug("can not register watchdog device, err: %li\n",
  61                          PTR_ERR(pdev));
  62                 return PTR_ERR(pdev);
  63         }
  64 
  65         bus->watchdog = pdev;
  66         return 0;
  67 }
  68 
  69 u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask)
  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_in(&bus->chipco, mask);
  77         else if (ssb_extif_available(&bus->extif))
  78                 res = ssb_extif_gpio_in(&bus->extif, mask);
  79         else
  80                 WARN_ON(1);
  81         spin_unlock_irqrestore(&bus->gpio_lock, flags);
  82 
  83         return res;
  84 }
  85 EXPORT_SYMBOL(ssb_gpio_in);
  86 
  87 u32 ssb_gpio_out(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_out(&bus->chipco, mask, value);
  95         else if (ssb_extif_available(&bus->extif))
  96                 res = ssb_extif_gpio_out(&bus->extif, mask, value);
  97         else
  98                 WARN_ON(1);
  99         spin_unlock_irqrestore(&bus->gpio_lock, flags);
 100 
 101         return res;
 102 }
 103 EXPORT_SYMBOL(ssb_gpio_out);
 104 
 105 u32 ssb_gpio_outen(struct ssb_bus *bus, u32 mask, u32 value)
 106 {
 107         unsigned long flags;
 108         u32 res = 0;
 109 
 110         spin_lock_irqsave(&bus->gpio_lock, flags);
 111         if (ssb_chipco_available(&bus->chipco))
 112                 res = ssb_chipco_gpio_outen(&bus->chipco, mask, value);
 113         else if (ssb_extif_available(&bus->extif))
 114                 res = ssb_extif_gpio_outen(&bus->extif, mask, value);
 115         else
 116                 WARN_ON(1);
 117         spin_unlock_irqrestore(&bus->gpio_lock, flags);
 118 
 119         return res;
 120 }
 121 EXPORT_SYMBOL(ssb_gpio_outen);
 122 
 123 u32 ssb_gpio_control(struct ssb_bus *bus, u32 mask, u32 value)
 124 {
 125         unsigned long flags;
 126         u32 res = 0;
 127 
 128         spin_lock_irqsave(&bus->gpio_lock, flags);
 129         if (ssb_chipco_available(&bus->chipco))
 130                 res = ssb_chipco_gpio_control(&bus->chipco, mask, value);
 131         spin_unlock_irqrestore(&bus->gpio_lock, flags);
 132 
 133         return res;
 134 }
 135 EXPORT_SYMBOL(ssb_gpio_control);
 136 
 137 u32 ssb_gpio_intmask(struct ssb_bus *bus, u32 mask, u32 value)
 138 {
 139         unsigned long flags;
 140         u32 res = 0;
 141 
 142         spin_lock_irqsave(&bus->gpio_lock, flags);
 143         if (ssb_chipco_available(&bus->chipco))
 144                 res = ssb_chipco_gpio_intmask(&bus->chipco, mask, value);
 145         else if (ssb_extif_available(&bus->extif))
 146                 res = ssb_extif_gpio_intmask(&bus->extif, mask, value);
 147         else
 148                 WARN_ON(1);
 149         spin_unlock_irqrestore(&bus->gpio_lock, flags);
 150 
 151         return res;
 152 }
 153 EXPORT_SYMBOL(ssb_gpio_intmask);
 154 
 155 u32 ssb_gpio_polarity(struct ssb_bus *bus, u32 mask, u32 value)
 156 {
 157         unsigned long flags;
 158         u32 res = 0;
 159 
 160         spin_lock_irqsave(&bus->gpio_lock, flags);
 161         if (ssb_chipco_available(&bus->chipco))
 162                 res = ssb_chipco_gpio_polarity(&bus->chipco, mask, value);
 163         else if (ssb_extif_available(&bus->extif))
 164                 res = ssb_extif_gpio_polarity(&bus->extif, mask, value);
 165         else
 166                 WARN_ON(1);
 167         spin_unlock_irqrestore(&bus->gpio_lock, flags);
 168 
 169         return res;
 170 }
 171 EXPORT_SYMBOL(ssb_gpio_polarity);
 172 
 173 #ifdef CONFIG_SSB_DRIVER_GIGE
 174 static int gige_pci_init_callback(struct ssb_bus *bus, unsigned long data)
 175 {
 176         struct pci_dev *pdev = (struct pci_dev *)data;
 177         struct ssb_device *dev;
 178         unsigned int i;
 179         int res;
 180 
 181         for (i = 0; i < bus->nr_devices; i++) {
 182                 dev = &(bus->devices[i]);
 183                 if (dev->id.coreid != SSB_DEV_ETHERNET_GBIT)
 184                         continue;
 185                 if (!dev->dev ||
 186                     !dev->dev->driver ||
 187                     !device_is_registered(dev->dev))
 188                         continue;
 189                 res = ssb_gige_pcibios_plat_dev_init(dev, pdev);
 190                 if (res >= 0)
 191                         return res;
 192         }
 193 
 194         return -ENODEV;
 195 }
 196 #endif /* CONFIG_SSB_DRIVER_GIGE */
 197 
 198 int ssb_pcibios_plat_dev_init(struct pci_dev *dev)
 199 {
 200         int err;
 201 
 202         err = ssb_pcicore_plat_dev_init(dev);
 203         if (!err)
 204                 return 0;
 205 #ifdef CONFIG_SSB_DRIVER_GIGE
 206         err = ssb_for_each_bus_call((unsigned long)dev, gige_pci_init_callback);
 207         if (err >= 0)
 208                 return err;
 209 #endif
 210         /* This is not a PCI device on any SSB device. */
 211 
 212         return -ENODEV;
 213 }
 214 
 215 #ifdef CONFIG_SSB_DRIVER_GIGE
 216 static int gige_map_irq_callback(struct ssb_bus *bus, unsigned long data)
 217 {
 218         const struct pci_dev *pdev = (const struct pci_dev *)data;
 219         struct ssb_device *dev;
 220         unsigned int i;
 221         int res;
 222 
 223         for (i = 0; i < bus->nr_devices; i++) {
 224                 dev = &(bus->devices[i]);
 225                 if (dev->id.coreid != SSB_DEV_ETHERNET_GBIT)
 226                         continue;
 227                 if (!dev->dev ||
 228                     !dev->dev->driver ||
 229                     !device_is_registered(dev->dev))
 230                         continue;
 231                 res = ssb_gige_map_irq(dev, pdev);
 232                 if (res >= 0)
 233                         return res;
 234         }
 235 
 236         return -ENODEV;
 237 }
 238 #endif /* CONFIG_SSB_DRIVER_GIGE */
 239 
 240 int ssb_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 241 {
 242         int res;
 243 
 244         /* Check if this PCI device is a device on a SSB bus or device
 245          * and return the IRQ number for it. */
 246 
 247         res = ssb_pcicore_pcibios_map_irq(dev, slot, pin);
 248         if (res >= 0)
 249                 return res;
 250 #ifdef CONFIG_SSB_DRIVER_GIGE
 251         res = ssb_for_each_bus_call((unsigned long)dev, gige_map_irq_callback);
 252         if (res >= 0)
 253                 return res;
 254 #endif
 255         /* This is not a PCI device on any SSB device. */
 256 
 257         return -ENODEV;
 258 }

/* [<][>][^][v][top][bottom][index][help] */