Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ip22-gio.c
Go to the documentation of this file.
1 #include <linux/export.h>
2 #include <linux/kernel.h>
3 #include <linux/init.h>
4 #include <linux/slab.h>
5 
6 #include <asm/addrspace.h>
7 #include <asm/paccess.h>
8 #include <asm/gio_device.h>
9 #include <asm/sgi/gio.h>
10 #include <asm/sgi/hpc3.h>
11 #include <asm/sgi/mc.h>
12 #include <asm/sgi/ip22.h>
13 
14 static struct bus_type gio_bus_type;
15 
16 static struct {
17  const char *name;
19 } gio_name_table[] = {
20  { .name = "SGI Impact", .id = 0x10 },
21  { .name = "Phobos G160", .id = 0x35 },
22  /* fake IDs */
23  { .name = "SGI Newport", .id = 0x7e },
24  { .name = "SGI GR2/GR3", .id = 0x7f },
25 };
26 
27 static struct device gio_bus = {
28  .init_name = "gio",
29 };
30 
40 const struct gio_device_id *gio_match_device(const struct gio_device_id *match,
41  const struct gio_device *dev)
42 {
43  const struct gio_device_id *ids;
44 
45  for (ids = match; ids->id != 0xff; ids++)
46  if (ids->id == dev->id.id)
47  return ids;
48 
49  return NULL;
50 }
52 
54 {
55  struct device *tmp;
56 
57  if (!dev)
58  return NULL;
59  tmp = get_device(&dev->dev);
60  if (tmp)
61  return to_gio_device(tmp);
62  else
63  return NULL;
64 }
66 
67 void gio_dev_put(struct gio_device *dev)
68 {
69  if (dev)
70  put_device(&dev->dev);
71 }
73 
81 void gio_release_dev(struct device *dev)
82 {
83  struct gio_device *giodev;
84 
85  giodev = to_gio_device(dev);
86  kfree(giodev);
87 }
89 
90 int gio_device_register(struct gio_device *giodev)
91 {
92  giodev->dev.bus = &gio_bus_type;
93  giodev->dev.parent = &gio_bus;
94  return device_register(&giodev->dev);
95 }
97 
98 void gio_device_unregister(struct gio_device *giodev)
99 {
100  device_unregister(&giodev->dev);
101 }
103 
104 static int gio_bus_match(struct device *dev, struct device_driver *drv)
105 {
106  struct gio_device *gio_dev = to_gio_device(dev);
107  struct gio_driver *gio_drv = to_gio_driver(drv);
108 
109  return gio_match_device(gio_drv->id_table, gio_dev) != NULL;
110 }
111 
112 static int gio_device_probe(struct device *dev)
113 {
114  int error = -ENODEV;
115  struct gio_driver *drv;
116  struct gio_device *gio_dev;
117  const struct gio_device_id *match;
118 
119  drv = to_gio_driver(dev->driver);
120  gio_dev = to_gio_device(dev);
121 
122  if (!drv->probe)
123  return error;
124 
125  gio_dev_get(gio_dev);
126 
127  match = gio_match_device(drv->id_table, gio_dev);
128  if (match)
129  error = drv->probe(gio_dev, match);
130  if (error)
131  gio_dev_put(gio_dev);
132 
133  return error;
134 }
135 
136 static int gio_device_remove(struct device *dev)
137 {
138  struct gio_device *gio_dev = to_gio_device(dev);
139  struct gio_driver *drv = to_gio_driver(dev->driver);
140 
141  if (dev->driver && drv->remove)
142  drv->remove(gio_dev);
143  return 0;
144 }
145 
146 static int gio_device_suspend(struct device *dev, pm_message_t state)
147 {
148  struct gio_device *gio_dev = to_gio_device(dev);
149  struct gio_driver *drv = to_gio_driver(dev->driver);
150  int error = 0;
151 
152  if (dev->driver && drv->suspend)
153  error = drv->suspend(gio_dev, state);
154  return error;
155 }
156 
157 static int gio_device_resume(struct device *dev)
158 {
159  struct gio_device *gio_dev = to_gio_device(dev);
160  struct gio_driver *drv = to_gio_driver(dev->driver);
161  int error = 0;
162 
163  if (dev->driver && drv->resume)
164  error = drv->resume(gio_dev);
165  return error;
166 }
167 
168 static void gio_device_shutdown(struct device *dev)
169 {
170  struct gio_device *gio_dev = to_gio_device(dev);
171  struct gio_driver *drv = to_gio_driver(dev->driver);
172 
173  if (dev->driver && drv->shutdown)
174  drv->shutdown(gio_dev);
175 }
176 
177 static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
178  char *buf)
179 {
180  struct gio_device *gio_dev = to_gio_device(dev);
181  int len = snprintf(buf, PAGE_SIZE, "gio:%x\n", gio_dev->id.id);
182 
183  return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
184 }
185 
186 static ssize_t name_show(struct device *dev,
187  struct device_attribute *attr, char *buf)
188 {
189  struct gio_device *giodev;
190 
191  giodev = to_gio_device(dev);
192  return sprintf(buf, "%s", giodev->name);
193 }
194 
195 static ssize_t id_show(struct device *dev,
196  struct device_attribute *attr, char *buf)
197 {
198  struct gio_device *giodev;
199 
200  giodev = to_gio_device(dev);
201  return sprintf(buf, "%x", giodev->id.id);
202 }
203 
204 static struct device_attribute gio_dev_attrs[] = {
205  __ATTR_RO(modalias),
206  __ATTR_RO(name),
207  __ATTR_RO(id),
208  __ATTR_NULL,
209 };
210 
211 static int gio_device_uevent(struct device *dev, struct kobj_uevent_env *env)
212 {
213  struct gio_device *gio_dev = to_gio_device(dev);
214 
215  add_uevent_var(env, "MODALIAS=gio:%x", gio_dev->id.id);
216  return 0;
217 }
218 
220 {
221  /* initialize common driver fields */
222  if (!drv->driver.name)
223  drv->driver.name = drv->name;
224  if (!drv->driver.owner)
225  drv->driver.owner = drv->owner;
226  drv->driver.bus = &gio_bus_type;
227 
228  /* register with core */
229  return driver_register(&drv->driver);
230 }
232 
234 {
235  driver_unregister(&drv->driver);
236 }
238 
239 void gio_set_master(struct gio_device *dev)
240 {
241  u32 tmp = sgimc->giopar;
242 
243  switch (dev->slotno) {
244  case 0:
245  tmp |= SGIMC_GIOPAR_MASTERGFX;
246  break;
247  case 1:
249  break;
250  case 2:
252  break;
253  }
254  sgimc->giopar = tmp;
255 }
257 
259 {
260  u32 tmp = sgimc->giopar;
261 
262  switch (slotno) {
263  case 0:
264  tmp |= SGIMC_GIOPAR_GFX64;
265  break;
266  case 1:
267  tmp |= SGIMC_GIOPAR_EXP064;
268  break;
269  case 2:
270  tmp |= SGIMC_GIOPAR_EXP164;
271  break;
272  }
273  sgimc->giopar = tmp;
274 }
275 
276 static int ip22_gio_id(unsigned long addr, u32 *res)
277 {
278  u8 tmp8;
279  u8 tmp16;
280  u32 tmp32;
281  u8 *ptr8;
282  u16 *ptr16;
283  u32 *ptr32;
284 
285  ptr32 = (void *)CKSEG1ADDR(addr);
286  if (!get_dbe(tmp32, ptr32)) {
287  /*
288  * We got no DBE, but this doesn't mean anything.
289  * If GIO is pipelined (which can't be disabled
290  * for GFX slot) we don't get a DBE, but we see
291  * the transfer size as data. So we do an 8bit
292  * and a 16bit access and check whether the common
293  * data matches
294  */
295  ptr8 = (void *)CKSEG1ADDR(addr + 3);
296  get_dbe(tmp8, ptr8);
297  ptr16 = (void *)CKSEG1ADDR(addr + 2);
298  get_dbe(tmp16, ptr16);
299  if (tmp8 == (tmp16 & 0xff) &&
300  tmp8 == (tmp32 & 0xff) &&
301  tmp16 == (tmp32 & 0xffff)) {
302  *res = tmp32;
303  return 1;
304  }
305  }
306  return 0; /* nothing here */
307 }
308 
309 #define HQ2_MYSTERY_OFFS 0x6A07C
310 #define NEWPORT_USTATUS_OFFS 0xF133C
311 
312 static int ip22_is_gr2(unsigned long addr)
313 {
314  u32 tmp;
315  u32 *ptr;
316 
317  /* HQ2 only allows 32bit accesses */
318  ptr = (void *)CKSEG1ADDR(addr + HQ2_MYSTERY_OFFS);
319  if (!get_dbe(tmp, ptr)) {
320  if (tmp == 0xdeadbeef)
321  return 1;
322  }
323  return 0;
324 }
325 
326 
327 static void ip22_check_gio(int slotno, unsigned long addr)
328 {
329  const char *name = "Unknown";
330  struct gio_device *gio_dev;
331  u32 tmp;
332  __u8 id;
333  int i;
334 
335  /* first look for GR2/GR3 by checking mystery register */
336  if (ip22_is_gr2(addr))
337  tmp = 0x7f;
338  else {
339  if (!ip22_gio_id(addr, &tmp)) {
340  /*
341  * no GIO signature at start address of slot, but
342  * Newport doesn't have one, so let's check usea
343  * status register
344  */
345  if (ip22_gio_id(addr + NEWPORT_USTATUS_OFFS, &tmp))
346  tmp = 0x7e;
347  else
348  tmp = 0;
349  }
350  }
351  if (tmp) {
352  id = GIO_ID(tmp);
353  if (tmp & GIO_32BIT_ID) {
354  if (tmp & GIO_64BIT_IFACE)
355  ip22_gio_set_64bit(slotno);
356  }
357  for (i = 0; i < ARRAY_SIZE(gio_name_table); i++) {
358  if (id == gio_name_table[i].id) {
359  name = gio_name_table[i].name;
360  break;
361  }
362  }
363  printk(KERN_INFO "GIO: slot %d : %s (id %x)\n",
364  slotno, name, id);
365  gio_dev = kzalloc(sizeof *gio_dev, GFP_KERNEL);
366  gio_dev->name = name;
367  gio_dev->slotno = slotno;
368  gio_dev->id.id = id;
369  gio_dev->resource.start = addr;
370  gio_dev->resource.end = addr + 0x3fffff;
371  gio_dev->resource.flags = IORESOURCE_MEM;
372  dev_set_name(&gio_dev->dev, "%d", slotno);
373  gio_device_register(gio_dev);
374  } else
375  printk(KERN_INFO "GIO: slot %d : Empty\n", slotno);
376 }
377 
378 static struct bus_type gio_bus_type = {
379  .name = "gio",
380  .dev_attrs = gio_dev_attrs,
381  .match = gio_bus_match,
382  .probe = gio_device_probe,
383  .remove = gio_device_remove,
384  .suspend = gio_device_suspend,
385  .resume = gio_device_resume,
386  .shutdown = gio_device_shutdown,
387  .uevent = gio_device_uevent,
388 };
389 
390 static struct resource gio_bus_resource = {
391  .start = GIO_SLOT_GFX_BASE,
392  .end = GIO_SLOT_GFX_BASE + 0x9fffff,
393  .name = "GIO Bus",
394  .flags = IORESOURCE_MEM,
395 };
396 
398 {
399  unsigned int pbdma __maybe_unused;
400  int ret;
401 
402  ret = device_register(&gio_bus);
403  if (ret)
404  return ret;
405 
406  ret = bus_register(&gio_bus_type);
407  if (!ret) {
408  request_resource(&iomem_resource, &gio_bus_resource);
409  printk(KERN_INFO "GIO: Probing bus...\n");
410 
411  if (ip22_is_fullhouse() ||
412  !get_dbe(pbdma, (unsigned int *)&hpc3c1->pbdma[1])) {
413  /* Indigo2 and ChallengeS */
414  ip22_check_gio(0, GIO_SLOT_GFX_BASE);
415  ip22_check_gio(1, GIO_SLOT_EXP0_BASE);
416  } else {
417  /* Indy */
418  ip22_check_gio(0, GIO_SLOT_GFX_BASE);
419  ip22_check_gio(1, GIO_SLOT_EXP0_BASE);
420  ip22_check_gio(2, GIO_SLOT_EXP1_BASE);
421  }
422  } else
423  device_unregister(&gio_bus);
424 
425  return ret;
426 }
427