1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <linux/export.h>
3 #include <linux/kernel.h>
4 #include <linux/init.h>
5 #include <linux/slab.h>
7 #include <asm/addrspace.h>
8 #include <asm/paccess.h>
9 #include <asm/gio_device.h>
10 #include <asm/sgi/gio.h>
11 #include <asm/sgi/hpc3.h>
12 #include <asm/sgi/mc.h>
13 #include <asm/sgi/ip22.h>
15 static const struct bus_type gio_bus_type
;
20 } gio_name_table
[] = {
21 { .name
= "SGI Impact", .id
= 0x10 },
22 { .name
= "Phobos G160", .id
= 0x35 },
23 { .name
= "Phobos G130", .id
= 0x36 },
24 { .name
= "Phobos G100", .id
= 0x37 },
25 { .name
= "Set Engineering GFE", .id
= 0x38 },
27 { .name
= "SGI Newport", .id
= 0x7e },
28 { .name
= "SGI GR2/GR3", .id
= 0x7f },
31 static void gio_bus_release(struct device
*dev
)
36 static struct device gio_bus
= {
38 .release
= &gio_bus_release
,
42 * gio_match_device - Tell if an of_device structure has a matching
44 * @ids: array of of device match structures to search in
45 * @dev: the of device structure to match against
47 * Used by a driver to check whether an of_device present in the
48 * system is in its list of supported devices.
50 static const struct gio_device_id
*
51 gio_match_device(const struct gio_device_id
*match
,
52 const struct gio_device
*dev
)
54 const struct gio_device_id
*ids
;
56 for (ids
= match
; ids
->id
!= 0xff; ids
++)
57 if (ids
->id
== dev
->id
.id
)
63 struct gio_device
*gio_dev_get(struct gio_device
*dev
)
69 tmp
= get_device(&dev
->dev
);
71 return to_gio_device(tmp
);
75 EXPORT_SYMBOL_GPL(gio_dev_get
);
77 void gio_dev_put(struct gio_device
*dev
)
80 put_device(&dev
->dev
);
82 EXPORT_SYMBOL_GPL(gio_dev_put
);
85 * gio_release_dev - free an gio device structure when all users of it are finished.
86 * @dev: device that's been disconnected
88 * Will be called only by the device core when all users of this gio device are
91 void gio_release_dev(struct device
*dev
)
93 struct gio_device
*giodev
;
95 giodev
= to_gio_device(dev
);
98 EXPORT_SYMBOL_GPL(gio_release_dev
);
100 int gio_device_register(struct gio_device
*giodev
)
102 giodev
->dev
.bus
= &gio_bus_type
;
103 giodev
->dev
.parent
= &gio_bus
;
104 return device_register(&giodev
->dev
);
106 EXPORT_SYMBOL_GPL(gio_device_register
);
108 void gio_device_unregister(struct gio_device
*giodev
)
110 device_unregister(&giodev
->dev
);
112 EXPORT_SYMBOL_GPL(gio_device_unregister
);
114 static int gio_bus_match(struct device
*dev
, const struct device_driver
*drv
)
116 struct gio_device
*gio_dev
= to_gio_device(dev
);
117 struct gio_driver
*gio_drv
= to_gio_driver(drv
);
119 return gio_match_device(gio_drv
->id_table
, gio_dev
) != NULL
;
122 static int gio_device_probe(struct device
*dev
)
125 struct gio_driver
*drv
;
126 struct gio_device
*gio_dev
;
127 const struct gio_device_id
*match
;
129 drv
= to_gio_driver(dev
->driver
);
130 gio_dev
= to_gio_device(dev
);
135 gio_dev_get(gio_dev
);
137 match
= gio_match_device(drv
->id_table
, gio_dev
);
139 error
= drv
->probe(gio_dev
, match
);
141 gio_dev_put(gio_dev
);
146 static void gio_device_remove(struct device
*dev
)
148 struct gio_device
*gio_dev
= to_gio_device(dev
);
149 struct gio_driver
*drv
= to_gio_driver(dev
->driver
);
152 drv
->remove(gio_dev
);
155 static void gio_device_shutdown(struct device
*dev
)
157 struct gio_device
*gio_dev
= to_gio_device(dev
);
158 struct gio_driver
*drv
= to_gio_driver(dev
->driver
);
160 if (dev
->driver
&& drv
->shutdown
)
161 drv
->shutdown(gio_dev
);
164 static ssize_t
modalias_show(struct device
*dev
, struct device_attribute
*a
,
167 struct gio_device
*gio_dev
= to_gio_device(dev
);
169 return sysfs_emit(buf
, "gio:%x\n", gio_dev
->id
.id
);
171 static DEVICE_ATTR_RO(modalias
);
173 static ssize_t
name_show(struct device
*dev
,
174 struct device_attribute
*attr
, char *buf
)
176 struct gio_device
*giodev
;
178 giodev
= to_gio_device(dev
);
179 return sysfs_emit(buf
, "%s\n", giodev
->name
);
181 static DEVICE_ATTR_RO(name
);
183 static ssize_t
id_show(struct device
*dev
,
184 struct device_attribute
*attr
, char *buf
)
186 struct gio_device
*giodev
;
188 giodev
= to_gio_device(dev
);
189 return sysfs_emit(buf
, "%x\n", giodev
->id
.id
);
191 static DEVICE_ATTR_RO(id
);
193 static struct attribute
*gio_dev_attrs
[] = {
194 &dev_attr_modalias
.attr
,
199 ATTRIBUTE_GROUPS(gio_dev
);
201 static int gio_device_uevent(const struct device
*dev
, struct kobj_uevent_env
*env
)
203 const struct gio_device
*gio_dev
= to_gio_device(dev
);
205 add_uevent_var(env
, "MODALIAS=gio:%x", gio_dev
->id
.id
);
209 int gio_register_driver(struct gio_driver
*drv
)
211 /* initialize common driver fields */
212 if (!drv
->driver
.name
)
213 drv
->driver
.name
= drv
->name
;
214 if (!drv
->driver
.owner
)
215 drv
->driver
.owner
= drv
->owner
;
216 drv
->driver
.bus
= &gio_bus_type
;
218 /* register with core */
219 return driver_register(&drv
->driver
);
221 EXPORT_SYMBOL_GPL(gio_register_driver
);
223 void gio_unregister_driver(struct gio_driver
*drv
)
225 driver_unregister(&drv
->driver
);
227 EXPORT_SYMBOL_GPL(gio_unregister_driver
);
229 void gio_set_master(struct gio_device
*dev
)
231 u32 tmp
= sgimc
->giopar
;
233 switch (dev
->slotno
) {
235 tmp
|= SGIMC_GIOPAR_MASTERGFX
;
238 tmp
|= SGIMC_GIOPAR_MASTEREXP0
;
241 tmp
|= SGIMC_GIOPAR_MASTEREXP1
;
246 EXPORT_SYMBOL_GPL(gio_set_master
);
248 static void ip22_gio_set_64bit(int slotno
)
250 u32 tmp
= sgimc
->giopar
;
254 tmp
|= SGIMC_GIOPAR_GFX64
;
257 tmp
|= SGIMC_GIOPAR_EXP064
;
260 tmp
|= SGIMC_GIOPAR_EXP164
;
266 static int ip22_gio_id(unsigned long addr
, u32
*res
)
275 ptr32
= (void *)CKSEG1ADDR(addr
);
276 if (!get_dbe(tmp32
, ptr32
)) {
278 * We got no DBE, but this doesn't mean anything.
279 * If GIO is pipelined (which can't be disabled
280 * for GFX slot) we don't get a DBE, but we see
281 * the transfer size as data. So we do an 8bit
282 * and a 16bit access and check whether the common
285 ptr8
= (void *)CKSEG1ADDR(addr
+ 3);
286 if (get_dbe(tmp8
, ptr8
)) {
288 * 32bit access worked, but 8bit doesn't
289 * so we don't see phantom reads on
290 * a pipelined bus, but a real card which
291 * doesn't support 8 bit reads
296 ptr16
= (void *)CKSEG1ADDR(addr
+ 2);
297 get_dbe(tmp16
, ptr16
);
298 if (tmp8
== (tmp16
& 0xff) &&
299 tmp8
== (tmp32
& 0xff) &&
300 tmp16
== (tmp32
& 0xffff)) {
305 return 0; /* nothing here */
308 #define HQ2_MYSTERY_OFFS 0x6A07C
309 #define NEWPORT_USTATUS_OFFS 0xF133C
311 static int ip22_is_gr2(unsigned long addr
)
316 /* HQ2 only allows 32bit accesses */
317 ptr
= (void *)CKSEG1ADDR(addr
+ HQ2_MYSTERY_OFFS
);
318 if (!get_dbe(tmp
, ptr
)) {
319 if (tmp
== 0xdeadbeef)
326 static void ip22_check_gio(int slotno
, unsigned long addr
, int irq
)
328 const char *name
= "Unknown";
329 struct gio_device
*gio_dev
;
334 /* first look for GR2/GR3 by checking mystery register */
335 if (ip22_is_gr2(addr
))
338 if (!ip22_gio_id(addr
, &tmp
)) {
340 * no GIO signature at start address of slot
341 * since Newport doesn't have one, we check if
342 * user status register is readable
344 if (ip22_gio_id(addr
+ NEWPORT_USTATUS_OFFS
, &tmp
))
352 if (tmp
& GIO_32BIT_ID
) {
353 if (tmp
& GIO_64BIT_IFACE
)
354 ip22_gio_set_64bit(slotno
);
356 for (i
= 0; i
< ARRAY_SIZE(gio_name_table
); i
++) {
357 if (id
== gio_name_table
[i
].id
) {
358 name
= gio_name_table
[i
].name
;
362 printk(KERN_INFO
"GIO: slot %d : %s (id %x)\n",
364 gio_dev
= kzalloc(sizeof *gio_dev
, GFP_KERNEL
);
367 gio_dev
->name
= name
;
368 gio_dev
->slotno
= slotno
;
370 gio_dev
->resource
.start
= addr
;
371 gio_dev
->resource
.end
= addr
+ 0x3fffff;
372 gio_dev
->resource
.flags
= IORESOURCE_MEM
;
374 dev_set_name(&gio_dev
->dev
, "%d", slotno
);
375 gio_device_register(gio_dev
);
377 printk(KERN_INFO
"GIO: slot %d : Empty\n", slotno
);
380 static const struct bus_type gio_bus_type
= {
382 .dev_groups
= gio_dev_groups
,
383 .match
= gio_bus_match
,
384 .probe
= gio_device_probe
,
385 .remove
= gio_device_remove
,
386 .shutdown
= gio_device_shutdown
,
387 .uevent
= gio_device_uevent
,
390 static struct resource gio_bus_resource
= {
391 .start
= GIO_SLOT_GFX_BASE
,
392 .end
= GIO_SLOT_GFX_BASE
+ 0x9fffff,
394 .flags
= IORESOURCE_MEM
,
397 static int __init
ip22_gio_init(void)
399 unsigned int pbdma __maybe_unused
;
402 ret
= device_register(&gio_bus
);
404 put_device(&gio_bus
);
408 ret
= bus_register(&gio_bus_type
);
410 request_resource(&iomem_resource
, &gio_bus_resource
);
411 printk(KERN_INFO
"GIO: Probing bus...\n");
413 if (ip22_is_fullhouse()) {
415 ip22_check_gio(0, GIO_SLOT_GFX_BASE
, SGI_GIO_1_IRQ
);
416 ip22_check_gio(1, GIO_SLOT_EXP0_BASE
, SGI_GIO_1_IRQ
);
418 /* Indy/Challenge S */
419 if (get_dbe(pbdma
, (unsigned int *)&hpc3c1
->pbdma
[1]))
420 ip22_check_gio(0, GIO_SLOT_GFX_BASE
,
422 ip22_check_gio(1, GIO_SLOT_EXP0_BASE
, SGI_GIOEXP0_IRQ
);
423 ip22_check_gio(2, GIO_SLOT_EXP1_BASE
, SGI_GIOEXP1_IRQ
);
426 device_unregister(&gio_bus
);
431 subsys_initcall(ip22_gio_init
);