1131377Stjr// SPDX-License-Identifier: GPL-2.0
2311285Sdelphij/*
3131377Stjr * Greybus "Core"
417651Speter *
517651Speter * Copyright 2014-2015 Google Inc.
6131377Stjr * Copyright 2014-2015 Linaro Ltd.
7131377Stjr */
8131377Stjr
9131377Stjr#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10131377Stjr
11131377Stjr#define CREATE_TRACE_POINTS
12131377Stjr#include <linux/greybus.h>
13131377Stjr#include "greybus_trace.h"
14131377Stjr
15131377Stjr#define GB_BUNDLE_AUTOSUSPEND_MS	3000
16131377Stjr
17131377Stjr/* Allow greybus to be disabled at boot if needed */
18131377Stjrstatic bool nogreybus;
19131377Stjr#ifdef MODULE
20131377Stjrmodule_param(nogreybus, bool, 0444);
21131377Stjr#else
22131377Stjrcore_param(nogreybus, nogreybus, bool, 0444);
23131377Stjr#endif
24131377Stjrint greybus_disabled(void)
25131377Stjr{
26131377Stjr	return nogreybus;
27131377Stjr}
28131377StjrEXPORT_SYMBOL_GPL(greybus_disabled);
29131377Stjr
30131377Stjrstatic int is_gb_host_device(const struct device *dev)
31131377Stjr{
32131377Stjr	return dev->type == &greybus_hd_type;
33131377Stjr}
34131377Stjr
35131377Stjrstatic int is_gb_module(const struct device *dev)
36131377Stjr{
37131377Stjr	return dev->type == &greybus_module_type;
38131377Stjr}
39131377Stjr
40131377Stjrstatic int is_gb_interface(const struct device *dev)
41131377Stjr{
42131377Stjr	return dev->type == &greybus_interface_type;
43131377Stjr}
44131377Stjr
45131377Stjrstatic int is_gb_control(const struct device *dev)
46131377Stjr{
47131377Stjr	return dev->type == &greybus_control_type;
48205194Sdelphij}
49131377Stjr
50131377Stjrstatic int is_gb_bundle(const struct device *dev)
51131377Stjr{
52131377Stjr	return dev->type == &greybus_bundle_type;
53131377Stjr}
54131377Stjr
55131377Stjrstatic int is_gb_svc(const struct device *dev)
56131377Stjr{
57131377Stjr	return dev->type == &greybus_svc_type;
58131377Stjr}
59131377Stjr
60131377Stjrstatic bool greybus_match_one_id(struct gb_bundle *bundle,
61131377Stjr				 const struct greybus_bundle_id *id)
62131377Stjr{
63131377Stjr	if ((id->match_flags & GREYBUS_ID_MATCH_VENDOR) &&
64131377Stjr	    (id->vendor != bundle->intf->vendor_id))
65131377Stjr		return false;
66131377Stjr
67131377Stjr	if ((id->match_flags & GREYBUS_ID_MATCH_PRODUCT) &&
68131377Stjr	    (id->product != bundle->intf->product_id))
69131377Stjr		return false;
70131377Stjr
71131377Stjr	if ((id->match_flags & GREYBUS_ID_MATCH_CLASS) &&
72131377Stjr	    (id->class != bundle->class))
73131377Stjr		return false;
74131377Stjr
75131377Stjr	return true;
76131377Stjr}
77131377Stjr
78131377Stjrstatic const struct greybus_bundle_id *
79131377Stjrgreybus_match_id(struct gb_bundle *bundle, const struct greybus_bundle_id *id)
80131377Stjr{
81131377Stjr	if (!id)
82131377Stjr		return NULL;
8317651Speter
84131377Stjr	for (; id->vendor || id->product || id->class || id->driver_info;
85131377Stjr									id++) {
86131377Stjr		if (greybus_match_one_id(bundle, id))
8717651Speter			return id;
88131377Stjr	}
89131377Stjr
90131377Stjr	return NULL;
91131377Stjr}
92131377Stjr
9317651Speterstatic int greybus_match_device(struct device *dev, struct device_driver *drv)
94131377Stjr{
95311285Sdelphij	struct greybus_driver *driver = to_greybus_driver(drv);
96131377Stjr	struct gb_bundle *bundle;
97250224Sdelphij	const struct greybus_bundle_id *id;
98250224Sdelphij
99131377Stjr	if (!is_gb_bundle(dev))
100131377Stjr		return 0;
101131377Stjr
102250224Sdelphij	bundle = to_gb_bundle(dev);
103131377Stjr
10417651Speter	id = greybus_match_id(bundle, driver->id_table);
105311285Sdelphij	if (id)
106311285Sdelphij		return 1;
107311285Sdelphij	/* FIXME - Dynamic ids? */
108311285Sdelphij	return 0;
109311285Sdelphij}
110311285Sdelphij
111311285Sdelphijstatic int greybus_uevent(const struct device *dev, struct kobj_uevent_env *env)
112311285Sdelphij{
113311285Sdelphij	const struct gb_host_device *hd;
114311285Sdelphij	const struct gb_module *module = NULL;
115311285Sdelphij	const struct gb_interface *intf = NULL;
116311285Sdelphij	const struct gb_control *control = NULL;
117311285Sdelphij	const struct gb_bundle *bundle = NULL;
118311285Sdelphij	const struct gb_svc *svc = NULL;
119230837Sdelphij
120131377Stjr	if (is_gb_host_device(dev)) {
121131377Stjr		hd = to_gb_host_device(dev);
122131377Stjr	} else if (is_gb_module(dev)) {
12333904Ssteve		module = to_gb_module(dev);
124311285Sdelphij		hd = module->hd;
125131377Stjr	} else if (is_gb_interface(dev)) {
126131377Stjr		intf = to_gb_interface(dev);
127131377Stjr		module = intf->module;
128230837Sdelphij		hd = intf->hd;
129230837Sdelphij	} else if (is_gb_control(dev)) {
130131377Stjr		control = to_gb_control(dev);
131131377Stjr		intf = control->intf;
132131377Stjr		module = intf->module;
133157043Sdes		hd = intf->hd;
134157043Sdes	} else if (is_gb_bundle(dev)) {
135131377Stjr		bundle = to_gb_bundle(dev);
136131377Stjr		intf = bundle->intf;
137131377Stjr		module = intf->module;
138205194Sdelphij		hd = intf->hd;
139205194Sdelphij	} else if (is_gb_svc(dev)) {
140131377Stjr		svc = to_gb_svc(dev);
141131377Stjr		hd = svc->hd;
142131377Stjr	} else {
14333904Ssteve		dev_WARN(dev, "uevent for unknown greybus device \"type\"!\n");
144230837Sdelphij		return -EINVAL;
145230837Sdelphij	}
146230837Sdelphij
147230837Sdelphij	if (add_uevent_var(env, "BUS=%u", hd->bus_id))
148230837Sdelphij		return -ENOMEM;
149311285Sdelphij
150230837Sdelphij	if (module) {
151230837Sdelphij		if (add_uevent_var(env, "MODULE=%u", module->module_id))
152230837Sdelphij			return -ENOMEM;
153230837Sdelphij	}
154230837Sdelphij
155230837Sdelphij	if (intf) {
156230837Sdelphij		if (add_uevent_var(env, "INTERFACE=%u", intf->interface_id))
157205194Sdelphij			return -ENOMEM;
158157043Sdes		if (add_uevent_var(env, "GREYBUS_ID=%08x/%08x",
159205194Sdelphij				   intf->vendor_id, intf->product_id))
160157043Sdes			return -ENOMEM;
161205194Sdelphij	}
162157043Sdes
163157043Sdes	if (bundle) {
164205194Sdelphij		// FIXME
165311285Sdelphij		// add a uevent that can "load" a bundle type
166157043Sdes		// This is what we need to bind a driver to so use the info
167205194Sdelphij		// in gmod here as well
168205194Sdelphij
169205194Sdelphij		if (add_uevent_var(env, "BUNDLE=%u", bundle->id))
170205194Sdelphij			return -ENOMEM;
171205194Sdelphij		if (add_uevent_var(env, "BUNDLE_CLASS=%02x", bundle->class))
172205194Sdelphij			return -ENOMEM;
173205194Sdelphij	}
174311285Sdelphij
175205194Sdelphij	return 0;
176205194Sdelphij}
177205194Sdelphij
178205194Sdelphijstatic void greybus_shutdown(struct device *dev)
179205194Sdelphij{
180205194Sdelphij	if (is_gb_host_device(dev)) {
181205194Sdelphij		struct gb_host_device *hd;
182205194Sdelphij
183205194Sdelphij		hd = to_gb_host_device(dev);
184205194Sdelphij		gb_hd_shutdown(hd);
185205194Sdelphij	}
186205194Sdelphij}
187205194Sdelphij
188205194Sdelphijconst struct bus_type greybus_bus_type = {
189205194Sdelphij	.name =		"greybus",
190205194Sdelphij	.match =	greybus_match_device,
191205194Sdelphij	.uevent =	greybus_uevent,
192205194Sdelphij	.shutdown =	greybus_shutdown,
193157043Sdes};
194157043Sdes
195131377Stjrstatic int greybus_probe(struct device *dev)
196131377Stjr{
197131377Stjr	struct greybus_driver *driver = to_greybus_driver(dev->driver);
198131377Stjr	struct gb_bundle *bundle = to_gb_bundle(dev);
199131377Stjr	const struct greybus_bundle_id *id;
200131377Stjr	int retval;
201205194Sdelphij
202131377Stjr	/* match id */
20317651Speter	id = greybus_match_id(bundle, driver->id_table);
204131377Stjr	if (!id)
205131377Stjr		return -ENODEV;
206131377Stjr
207131377Stjr	retval = pm_runtime_get_sync(&bundle->intf->dev);
208131377Stjr	if (retval < 0) {
209131377Stjr		pm_runtime_put_noidle(&bundle->intf->dev);
210230837Sdelphij		return retval;
211230837Sdelphij	}
212230837Sdelphij
213131377Stjr	retval = gb_control_bundle_activate(bundle->intf->control, bundle->id);
214131377Stjr	if (retval) {
215230837Sdelphij		pm_runtime_put(&bundle->intf->dev);
216131377Stjr		return retval;
217230837Sdelphij	}
218230837Sdelphij
219230837Sdelphij	/*
220230837Sdelphij	 * Unbound bundle devices are always deactivated. During probe, the
221230837Sdelphij	 * Runtime PM is set to enabled and active and the usage count is
222230837Sdelphij	 * incremented. If the driver supports runtime PM, it should call
223131377Stjr	 * pm_runtime_put() in its probe routine and pm_runtime_get_sync()
224131377Stjr	 * in remove routine.
225131377Stjr	 */
226131377Stjr	pm_runtime_set_autosuspend_delay(dev, GB_BUNDLE_AUTOSUSPEND_MS);
227157043Sdes	pm_runtime_use_autosuspend(dev);
228311285Sdelphij	pm_runtime_get_noresume(dev);
229205194Sdelphij	pm_runtime_set_active(dev);
230311285Sdelphij	pm_runtime_enable(dev);
231205194Sdelphij
232205194Sdelphij	retval = driver->probe(bundle, id);
233131377Stjr	if (retval) {
234131377Stjr		/*
235131377Stjr		 * Catch buggy drivers that fail to destroy their connections.
236205194Sdelphij		 */
237131377Stjr		WARN_ON(!list_empty(&bundle->connections));
23817651Speter
239131377Stjr		gb_control_bundle_deactivate(bundle->intf->control, bundle->id);
240131377Stjr
241131377Stjr		pm_runtime_disable(dev);
242131377Stjr		pm_runtime_set_suspended(dev);
24317651Speter		pm_runtime_put_noidle(dev);
244131377Stjr		pm_runtime_dont_use_autosuspend(dev);
24517651Speter		pm_runtime_put(&bundle->intf->dev);
24617651Speter
247205194Sdelphij		return retval;
248205194Sdelphij	}
249205194Sdelphij
250205194Sdelphij	pm_runtime_put(&bundle->intf->dev);
251205194Sdelphij
252205194Sdelphij	return 0;
253205194Sdelphij}
254311285Sdelphij
255205194Sdelphijstatic int greybus_remove(struct device *dev)
256205194Sdelphij{
257205194Sdelphij	struct greybus_driver *driver = to_greybus_driver(dev->driver);
258205194Sdelphij	struct gb_bundle *bundle = to_gb_bundle(dev);
259205194Sdelphij	struct gb_connection *connection;
260205194Sdelphij	int retval;
261311285Sdelphij
262205194Sdelphij	retval = pm_runtime_get_sync(dev);
263311285Sdelphij	if (retval < 0)
264311285Sdelphij		dev_err(dev, "failed to resume bundle: %d\n", retval);
265205194Sdelphij
266205194Sdelphij	/*
267205194Sdelphij	 * Disable (non-offloaded) connections early in case the interface is
268131377Stjr	 * already gone to avoid unceccessary operation timeouts during
269131377Stjr	 * driver disconnect. Otherwise, only disable incoming requests.
270131377Stjr	 */
271131377Stjr	list_for_each_entry(connection, &bundle->connections, bundle_links) {
272131377Stjr		if (gb_connection_is_offloaded(connection))
273131377Stjr			continue;
274131377Stjr
275131377Stjr		if (bundle->intf->disconnected)
276131377Stjr			gb_connection_disable_forced(connection);
277131377Stjr		else
278131377Stjr			gb_connection_disable_rx(connection);
279131377Stjr	}
280131377Stjr
281131377Stjr	driver->disconnect(bundle);
282131377Stjr
283131377Stjr	/* Catch buggy drivers that fail to destroy their connections. */
284131377Stjr	WARN_ON(!list_empty(&bundle->connections));
28517651Speter
286131377Stjr	if (!bundle->intf->disconnected)
287131377Stjr		gb_control_bundle_deactivate(bundle->intf->control, bundle->id);
288131377Stjr
289131377Stjr	pm_runtime_put_noidle(dev);
290131377Stjr	pm_runtime_disable(dev);
291131377Stjr	pm_runtime_set_suspended(dev);
292131377Stjr	pm_runtime_dont_use_autosuspend(dev);
293131377Stjr	pm_runtime_put_noidle(dev);
294131377Stjr
295131377Stjr	return 0;
296131377Stjr}
297131377Stjr
298131377Stjrint greybus_register_driver(struct greybus_driver *driver, struct module *owner,
299131377Stjr			    const char *mod_name)
300131377Stjr{
301131377Stjr	int retval;
302131377Stjr
303131377Stjr	if (greybus_disabled())
304131377Stjr		return -ENODEV;
305131377Stjr
306131377Stjr	driver->driver.bus = &greybus_bus_type;
307131377Stjr	driver->driver.name = driver->name;
308131377Stjr	driver->driver.probe = greybus_probe;
309131377Stjr	driver->driver.remove = greybus_remove;
310131377Stjr	driver->driver.owner = owner;
311131377Stjr	driver->driver.mod_name = mod_name;
312131377Stjr
313131377Stjr	retval = driver_register(&driver->driver);
314131377Stjr	if (retval)
315131377Stjr		return retval;
316131377Stjr
317131377Stjr	pr_info("registered new driver %s\n", driver->name);
318131377Stjr	return 0;
31917651Speter}
32017651SpeterEXPORT_SYMBOL_GPL(greybus_register_driver);
321131377Stjr
322131377Stjrvoid greybus_deregister_driver(struct greybus_driver *driver)
32317651Speter{
324131377Stjr	driver_unregister(&driver->driver);
325131377Stjr}
326131377StjrEXPORT_SYMBOL_GPL(greybus_deregister_driver);
327131377Stjr
328131377Stjrstatic int __init gb_init(void)
32917651Speter{
330131377Stjr	int retval;
33117651Speter
332131377Stjr	if (greybus_disabled())
333131377Stjr		return -ENODEV;
334131377Stjr
335131377Stjr	BUILD_BUG_ON(CPORT_ID_MAX >= (long)CPORT_ID_BAD);
336131377Stjr
33717651Speter	gb_debugfs_init();
338131377Stjr
33917651Speter	retval = bus_register(&greybus_bus_type);
340131377Stjr	if (retval) {
341131377Stjr		pr_err("bus_register failed (%d)\n", retval);
342131377Stjr		goto error_bus;
343131377Stjr	}
344131377Stjr
345131377Stjr	retval = gb_hd_init();
34617651Speter	if (retval) {
347131377Stjr		pr_err("gb_hd_init failed (%d)\n", retval);
348131377Stjr		goto error_hd;
349131377Stjr	}
350131377Stjr
351131377Stjr	retval = gb_operation_init();
352131377Stjr	if (retval) {
353131377Stjr		pr_err("gb_operation_init failed (%d)\n", retval);
354131377Stjr		goto error_operation;
355131377Stjr	}
356131377Stjr	return 0;	/* Success */
357131377Stjr
358131377Stjrerror_operation:
359131377Stjr	gb_hd_exit();
360131377Stjrerror_hd:
361131377Stjr	bus_unregister(&greybus_bus_type);
362230837Sdelphijerror_bus:
363230837Sdelphij	gb_debugfs_cleanup();
364131377Stjr
365131377Stjr	return retval;
366131377Stjr}
367131377Stjrmodule_init(gb_init);
368131377Stjr
369131377Stjrstatic void __exit gb_exit(void)
370131377Stjr{
371131377Stjr	gb_operation_exit();
372131377Stjr	gb_hd_exit();
373131377Stjr	bus_unregister(&greybus_bus_type);
374131377Stjr	gb_debugfs_cleanup();
375131377Stjr	tracepoint_synchronize_unregister();
376131377Stjr}
377131377Stjrmodule_exit(gb_exit);
378131377StjrMODULE_LICENSE("GPL v2");
37917651SpeterMODULE_AUTHOR("Greg Kroah-Hartman <gregkh@linuxfoundation.org>");
380131377Stjr