2 * arch/sh/kernel/cpu/bus.c
4 * Virtual bus for SuperH.
6 * Copyright (C) 2004 Paul Mundt
8 * Shamelessly cloned from arch/arm/mach-omap/bus.c, which was written
11 * Copyright (C) 2003 - 2004 Nokia Corporation
12 * Written by Tony Lindgren <tony@atomide.com>
13 * Portions of code based on sa1111.c.
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
20 #include <linux/kernel.h>
21 #include <linux/device.h>
22 #include <linux/init.h>
23 #include <linux/module.h>
24 #include <asm/bus-sh.h>
26 static int sh_bus_match(struct device
*dev
, struct device_driver
*drv
)
28 struct sh_driver
*shdrv
= to_sh_driver(drv
);
29 struct sh_dev
*shdev
= to_sh_dev(dev
);
31 return shdev
->dev_id
== shdrv
->dev_id
;
34 static int sh_bus_suspend(struct device
*dev
, pm_message_t state
)
36 struct sh_dev
*shdev
= to_sh_dev(dev
);
37 struct sh_driver
*shdrv
= to_sh_driver(dev
->driver
);
39 if (shdrv
&& shdrv
->suspend
)
40 return shdrv
->suspend(shdev
, state
);
45 static int sh_bus_resume(struct device
*dev
)
47 struct sh_dev
*shdev
= to_sh_dev(dev
);
48 struct sh_driver
*shdrv
= to_sh_driver(dev
->driver
);
50 if (shdrv
&& shdrv
->resume
)
51 return shdrv
->resume(shdev
);
56 static int sh_device_probe(struct device
*dev
)
58 struct sh_dev
*shdev
= to_sh_dev(dev
);
59 struct sh_driver
*shdrv
= to_sh_driver(dev
->driver
);
61 if (shdrv
&& shdrv
->probe
)
62 return shdrv
->probe(shdev
);
67 static int sh_device_remove(struct device
*dev
)
69 struct sh_dev
*shdev
= to_sh_dev(dev
);
70 struct sh_driver
*shdrv
= to_sh_driver(dev
->driver
);
72 if (shdrv
&& shdrv
->remove
)
73 return shdrv
->remove(shdev
);
78 static struct device sh_bus_devices
[SH_NR_BUSES
] = {
80 .bus_id
= SH_BUS_NAME_VIRT
,
84 struct bus_type sh_bus_types
[SH_NR_BUSES
] = {
86 .name
= SH_BUS_NAME_VIRT
,
87 .match
= sh_bus_match
,
88 .probe
= sh_bus_probe
,
89 .remove
= sh_bus_remove
,
90 .suspend
= sh_bus_suspend
,
91 .resume
= sh_bus_resume
,
95 int sh_device_register(struct sh_dev
*dev
)
100 if (dev
->bus_id
< 0 || dev
->bus_id
>= SH_NR_BUSES
) {
101 printk(KERN_ERR
"%s: bus_id invalid: %s bus: %d\n",
102 __FUNCTION__
, dev
->name
, dev
->bus_id
);
106 dev
->dev
.parent
= &sh_bus_devices
[dev
->bus_id
];
107 dev
->dev
.bus
= &sh_bus_types
[dev
->bus_id
];
109 /* This is needed for USB OHCI to work */
111 dev
->dev
.dma_mask
= dev
->dma_mask
;
112 if (dev
->coherent_dma_mask
)
113 dev
->dev
.coherent_dma_mask
= dev
->coherent_dma_mask
;
115 snprintf(dev
->dev
.bus_id
, BUS_ID_SIZE
, "%s%u",
116 dev
->name
, dev
->dev_id
);
118 printk(KERN_INFO
"Registering SH device '%s'. Parent at %s\n",
119 dev
->dev
.bus_id
, dev
->dev
.parent
->bus_id
);
121 return device_register(&dev
->dev
);
124 void sh_device_unregister(struct sh_dev
*dev
)
126 device_unregister(&dev
->dev
);
129 int sh_driver_register(struct sh_driver
*drv
)
134 if (drv
->bus_id
< 0 || drv
->bus_id
>= SH_NR_BUSES
) {
135 printk(KERN_ERR
"%s: bus_id invalid: bus: %d device %d\n",
136 __FUNCTION__
, drv
->bus_id
, drv
->dev_id
);
140 drv
->drv
.bus
= &sh_bus_types
[drv
->bus_id
];
142 return driver_register(&drv
->drv
);
145 void sh_driver_unregister(struct sh_driver
*drv
)
147 driver_unregister(&drv
->drv
);
150 static int __init
sh_bus_init(void)
154 for (i
= 0; i
< SH_NR_BUSES
; i
++) {
155 ret
= device_register(&sh_bus_devices
[i
]);
157 printk(KERN_ERR
"Unable to register bus device %s\n",
158 sh_bus_devices
[i
].bus_id
);
162 ret
= bus_register(&sh_bus_types
[i
]);
164 printk(KERN_ERR
"Unable to register bus %s\n",
165 sh_bus_types
[i
].name
);
166 device_unregister(&sh_bus_devices
[i
]);
170 printk(KERN_INFO
"SH Virtual Bus initialized\n");
175 static void __exit
sh_bus_exit(void)
179 for (i
= 0; i
< SH_NR_BUSES
; i
++) {
180 bus_unregister(&sh_bus_types
[i
]);
181 device_unregister(&sh_bus_devices
[i
]);
185 module_init(sh_bus_init
);
186 module_exit(sh_bus_exit
);
188 MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
189 MODULE_DESCRIPTION("SH Virtual Bus");
190 MODULE_LICENSE("GPL");
192 EXPORT_SYMBOL(sh_bus_types
);
193 EXPORT_SYMBOL(sh_device_register
);
194 EXPORT_SYMBOL(sh_device_unregister
);
195 EXPORT_SYMBOL(sh_driver_register
);
196 EXPORT_SYMBOL(sh_driver_unregister
);