Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
embedded.c
Go to the documentation of this file.
1 /*
2  * Sonics Silicon Backplane
3  * Embedded systems support code
4  *
5  * Copyright 2005-2008, Broadcom Corporation
6  * Copyright 2006-2008, Michael Buesch <[email protected]>
7  *
8  * Licensed under the GNU/GPL. See COPYING for details.
9  */
10 
11 #include <linux/export.h>
12 #include <linux/ssb/ssb.h>
13 #include <linux/ssb/ssb_embedded.h>
16 #include <linux/pci.h>
17 
18 #include "ssb_private.h"
19 
20 
22 {
23  if (ssb_chipco_available(&bus->chipco)) {
25  return 0;
26  }
27  if (ssb_extif_available(&bus->extif)) {
28  ssb_extif_watchdog_timer_set(&bus->extif, ticks);
29  return 0;
30  }
31  return -ENODEV;
32 }
34 
36 {
37  unsigned long flags;
38  u32 res = 0;
39 
40  spin_lock_irqsave(&bus->gpio_lock, flags);
41  if (ssb_chipco_available(&bus->chipco))
42  res = ssb_chipco_gpio_in(&bus->chipco, mask);
43  else if (ssb_extif_available(&bus->extif))
44  res = ssb_extif_gpio_in(&bus->extif, mask);
45  else
46  SSB_WARN_ON(1);
47  spin_unlock_irqrestore(&bus->gpio_lock, flags);
48 
49  return res;
50 }
52 
54 {
55  unsigned long flags;
56  u32 res = 0;
57 
58  spin_lock_irqsave(&bus->gpio_lock, flags);
59  if (ssb_chipco_available(&bus->chipco))
60  res = ssb_chipco_gpio_out(&bus->chipco, mask, value);
61  else if (ssb_extif_available(&bus->extif))
62  res = ssb_extif_gpio_out(&bus->extif, mask, value);
63  else
64  SSB_WARN_ON(1);
65  spin_unlock_irqrestore(&bus->gpio_lock, flags);
66 
67  return res;
68 }
70 
72 {
73  unsigned long flags;
74  u32 res = 0;
75 
76  spin_lock_irqsave(&bus->gpio_lock, flags);
77  if (ssb_chipco_available(&bus->chipco))
78  res = ssb_chipco_gpio_outen(&bus->chipco, mask, value);
79  else if (ssb_extif_available(&bus->extif))
80  res = ssb_extif_gpio_outen(&bus->extif, mask, value);
81  else
82  SSB_WARN_ON(1);
83  spin_unlock_irqrestore(&bus->gpio_lock, flags);
84 
85  return res;
86 }
88 
90 {
91  unsigned long flags;
92  u32 res = 0;
93 
94  spin_lock_irqsave(&bus->gpio_lock, flags);
95  if (ssb_chipco_available(&bus->chipco))
96  res = ssb_chipco_gpio_control(&bus->chipco, mask, value);
97  spin_unlock_irqrestore(&bus->gpio_lock, flags);
98 
99  return res;
100 }
102 
104 {
105  unsigned long flags;
106  u32 res = 0;
107 
108  spin_lock_irqsave(&bus->gpio_lock, flags);
109  if (ssb_chipco_available(&bus->chipco))
110  res = ssb_chipco_gpio_intmask(&bus->chipco, mask, value);
111  else if (ssb_extif_available(&bus->extif))
112  res = ssb_extif_gpio_intmask(&bus->extif, mask, value);
113  else
114  SSB_WARN_ON(1);
115  spin_unlock_irqrestore(&bus->gpio_lock, flags);
116 
117  return res;
118 }
120 
122 {
123  unsigned long flags;
124  u32 res = 0;
125 
126  spin_lock_irqsave(&bus->gpio_lock, flags);
127  if (ssb_chipco_available(&bus->chipco))
128  res = ssb_chipco_gpio_polarity(&bus->chipco, mask, value);
129  else if (ssb_extif_available(&bus->extif))
130  res = ssb_extif_gpio_polarity(&bus->extif, mask, value);
131  else
132  SSB_WARN_ON(1);
133  spin_unlock_irqrestore(&bus->gpio_lock, flags);
134 
135  return res;
136 }
138 
139 #ifdef CONFIG_SSB_DRIVER_GIGE
140 static int gige_pci_init_callback(struct ssb_bus *bus, unsigned long data)
141 {
142  struct pci_dev *pdev = (struct pci_dev *)data;
143  struct ssb_device *dev;
144  unsigned int i;
145  int res;
146 
147  for (i = 0; i < bus->nr_devices; i++) {
148  dev = &(bus->devices[i]);
149  if (dev->id.coreid != SSB_DEV_ETHERNET_GBIT)
150  continue;
151  if (!dev->dev ||
152  !dev->dev->driver ||
153  !device_is_registered(dev->dev))
154  continue;
155  res = ssb_gige_pcibios_plat_dev_init(dev, pdev);
156  if (res >= 0)
157  return res;
158  }
159 
160  return -ENODEV;
161 }
162 #endif /* CONFIG_SSB_DRIVER_GIGE */
163 
165 {
166  int err;
167 
168  err = ssb_pcicore_plat_dev_init(dev);
169  if (!err)
170  return 0;
171 #ifdef CONFIG_SSB_DRIVER_GIGE
172  err = ssb_for_each_bus_call((unsigned long)dev, gige_pci_init_callback);
173  if (err >= 0)
174  return err;
175 #endif
176  /* This is not a PCI device on any SSB device. */
177 
178  return -ENODEV;
179 }
180 
181 #ifdef CONFIG_SSB_DRIVER_GIGE
182 static int gige_map_irq_callback(struct ssb_bus *bus, unsigned long data)
183 {
184  const struct pci_dev *pdev = (const struct pci_dev *)data;
185  struct ssb_device *dev;
186  unsigned int i;
187  int res;
188 
189  for (i = 0; i < bus->nr_devices; i++) {
190  dev = &(bus->devices[i]);
191  if (dev->id.coreid != SSB_DEV_ETHERNET_GBIT)
192  continue;
193  if (!dev->dev ||
194  !dev->dev->driver ||
195  !device_is_registered(dev->dev))
196  continue;
197  res = ssb_gige_map_irq(dev, pdev);
198  if (res >= 0)
199  return res;
200  }
201 
202  return -ENODEV;
203 }
204 #endif /* CONFIG_SSB_DRIVER_GIGE */
205 
206 int ssb_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
207 {
208  int res;
209 
210  /* Check if this PCI device is a device on a SSB bus or device
211  * and return the IRQ number for it. */
212 
213  res = ssb_pcicore_pcibios_map_irq(dev, slot, pin);
214  if (res >= 0)
215  return res;
216 #ifdef CONFIG_SSB_DRIVER_GIGE
217  res = ssb_for_each_bus_call((unsigned long)dev, gige_map_irq_callback);
218  if (res >= 0)
219  return res;
220 #endif
221  /* This is not a PCI device on any SSB device. */
222 
223  return -ENODEV;
224 }