linux/drivers/ssb/embedded.c
<<
>>
Prefs
   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
  20int 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}
  32EXPORT_SYMBOL(ssb_watchdog_timer_set);
  33
  34u32 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}
  50EXPORT_SYMBOL(ssb_gpio_in);
  51
  52u32 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}
  68EXPORT_SYMBOL(ssb_gpio_out);
  69
  70u32 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}
  86EXPORT_SYMBOL(ssb_gpio_outen);
  87
  88u32 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}
 100EXPORT_SYMBOL(ssb_gpio_control);
 101
 102u32 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}
 118EXPORT_SYMBOL(ssb_gpio_intmask);
 119
 120u32 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}
 136EXPORT_SYMBOL(ssb_gpio_polarity);
 137
 138#ifdef CONFIG_SSB_DRIVER_GIGE
 139static 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
 163int 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
 181static 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
 205int 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