Blame view

drivers/nubus/bus.c 2.69 KB
7f86c765a   Finn Thain   nubus: Add suppor...
1
2
3
4
5
6
7
  // SPDX-License-Identifier: GPL-2.0
  //
  // Bus implementation for the NuBus subsystem.
  //
  // Copyright (C) 2017 Finn Thain
  
  #include <linux/device.h>
a8c5cb994   Finn Thain   nubus: Set defaul...
8
  #include <linux/dma-mapping.h>
7f86c765a   Finn Thain   nubus: Add suppor...
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  #include <linux/list.h>
  #include <linux/nubus.h>
  #include <linux/seq_file.h>
  #include <linux/slab.h>
  
  #define to_nubus_board(d)       container_of(d, struct nubus_board, dev)
  #define to_nubus_driver(d)      container_of(d, struct nubus_driver, driver)
  
  static int nubus_bus_match(struct device *dev, struct device_driver *driver)
  {
  	return 1;
  }
  
  static int nubus_device_probe(struct device *dev)
  {
  	struct nubus_driver *ndrv = to_nubus_driver(dev->driver);
  	int err = -ENODEV;
  
  	if (ndrv->probe)
  		err = ndrv->probe(to_nubus_board(dev));
  	return err;
  }
  
  static int nubus_device_remove(struct device *dev)
  {
  	struct nubus_driver *ndrv = to_nubus_driver(dev->driver);
  	int err = -ENODEV;
  
  	if (dev->driver && ndrv->remove)
  		err = ndrv->remove(to_nubus_board(dev));
  	return err;
  }
  
  struct bus_type nubus_bus_type = {
  	.name		= "nubus",
  	.match		= nubus_bus_match,
  	.probe		= nubus_device_probe,
  	.remove		= nubus_device_remove,
  };
  EXPORT_SYMBOL(nubus_bus_type);
  
  int nubus_driver_register(struct nubus_driver *ndrv)
  {
  	ndrv->driver.bus = &nubus_bus_type;
  	return driver_register(&ndrv->driver);
  }
  EXPORT_SYMBOL(nubus_driver_register);
  
  void nubus_driver_unregister(struct nubus_driver *ndrv)
  {
  	driver_unregister(&ndrv->driver);
  }
  EXPORT_SYMBOL(nubus_driver_unregister);
  
  static struct device nubus_parent = {
  	.init_name	= "nubus",
  };
bdeeed098   Finn Thain   nubus: Call bus_r...
66
  static int __init nubus_bus_register(void)
7f86c765a   Finn Thain   nubus: Add suppor...
67
  {
bdeeed098   Finn Thain   nubus: Call bus_r...
68
69
70
  	return bus_register(&nubus_bus_type);
  }
  postcore_initcall(nubus_bus_register);
7f86c765a   Finn Thain   nubus: Add suppor...
71

bdeeed098   Finn Thain   nubus: Call bus_r...
72
73
74
  int __init nubus_parent_device_register(void)
  {
  	return device_register(&nubus_parent);
7f86c765a   Finn Thain   nubus: Add suppor...
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
  }
  
  static void nubus_device_release(struct device *dev)
  {
  	struct nubus_board *board = to_nubus_board(dev);
  	struct nubus_rsrc *fres, *tmp;
  
  	list_for_each_entry_safe(fres, tmp, &nubus_func_rsrcs, list)
  		if (fres->board == board) {
  			list_del(&fres->list);
  			kfree(fres);
  		}
  	kfree(board);
  }
  
  int nubus_device_register(struct nubus_board *board)
  {
  	board->dev.parent = &nubus_parent;
  	board->dev.release = nubus_device_release;
  	board->dev.bus = &nubus_bus_type;
  	dev_set_name(&board->dev, "slot.%X", board->slot);
a8c5cb994   Finn Thain   nubus: Set defaul...
96
97
  	board->dev.dma_mask = &board->dev.coherent_dma_mask;
  	dma_set_mask(&board->dev, DMA_BIT_MASK(32));
7f86c765a   Finn Thain   nubus: Add suppor...
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
  	return device_register(&board->dev);
  }
  
  static int nubus_print_device_name_fn(struct device *dev, void *data)
  {
  	struct nubus_board *board = to_nubus_board(dev);
  	struct seq_file *m = data;
  
  	seq_printf(m, "Slot %X: %s
  ", board->slot, board->name);
  	return 0;
  }
  
  int nubus_proc_show(struct seq_file *m, void *data)
  {
  	return bus_for_each_dev(&nubus_bus_type, NULL, m,
  				nubus_print_device_name_fn);
  }