4 * Copyright 2014-2015 Google Inc.
5 * Copyright 2014-2015 Linaro Ltd.
7 * Released under the GPLv2 only.
11 #include "greybus_trace.h"
13 static ssize_t
bundle_class_show(struct device
*dev
,
14 struct device_attribute
*attr
, char *buf
)
16 struct gb_bundle
*bundle
= to_gb_bundle(dev
);
18 return sprintf(buf
, "0x%02x\n", bundle
->class);
20 static DEVICE_ATTR_RO(bundle_class
);
22 static ssize_t
bundle_id_show(struct device
*dev
,
23 struct device_attribute
*attr
, char *buf
)
25 struct gb_bundle
*bundle
= to_gb_bundle(dev
);
27 return sprintf(buf
, "%u\n", bundle
->id
);
29 static DEVICE_ATTR_RO(bundle_id
);
31 static ssize_t
state_show(struct device
*dev
, struct device_attribute
*attr
,
34 struct gb_bundle
*bundle
= to_gb_bundle(dev
);
36 if (bundle
->state
== NULL
)
37 return sprintf(buf
, "\n");
39 return sprintf(buf
, "%s\n", bundle
->state
);
42 static ssize_t
state_store(struct device
*dev
, struct device_attribute
*attr
,
43 const char *buf
, size_t size
)
45 struct gb_bundle
*bundle
= to_gb_bundle(dev
);
48 bundle
->state
= kstrdup(buf
, GFP_KERNEL
);
52 /* Tell userspace that the file contents changed */
53 sysfs_notify(&bundle
->dev
.kobj
, NULL
, "state");
57 static DEVICE_ATTR_RW(state
);
59 static struct attribute
*bundle_attrs
[] = {
60 &dev_attr_bundle_class
.attr
,
61 &dev_attr_bundle_id
.attr
,
66 ATTRIBUTE_GROUPS(bundle
);
68 static struct gb_bundle
*gb_bundle_find(struct gb_interface
*intf
,
71 struct gb_bundle
*bundle
;
73 list_for_each_entry(bundle
, &intf
->bundles
, links
) {
74 if (bundle
->id
== bundle_id
)
81 static void gb_bundle_release(struct device
*dev
)
83 struct gb_bundle
*bundle
= to_gb_bundle(dev
);
85 trace_gb_bundle_release(bundle
);
88 kfree(bundle
->cport_desc
);
93 static void gb_bundle_disable_all_connections(struct gb_bundle
*bundle
)
95 struct gb_connection
*connection
;
97 list_for_each_entry(connection
, &bundle
->connections
, bundle_links
)
98 gb_connection_disable(connection
);
101 static void gb_bundle_enable_all_connections(struct gb_bundle
*bundle
)
103 struct gb_connection
*connection
;
105 list_for_each_entry(connection
, &bundle
->connections
, bundle_links
)
106 gb_connection_enable(connection
);
109 static int gb_bundle_suspend(struct device
*dev
)
111 struct gb_bundle
*bundle
= to_gb_bundle(dev
);
112 const struct dev_pm_ops
*pm
= dev
->driver
->pm
;
115 if (pm
&& pm
->runtime_suspend
) {
116 ret
= pm
->runtime_suspend(&bundle
->dev
);
120 gb_bundle_disable_all_connections(bundle
);
123 ret
= gb_control_bundle_suspend(bundle
->intf
->control
, bundle
->id
);
125 if (pm
&& pm
->runtime_resume
)
126 ret
= pm
->runtime_resume(dev
);
128 gb_bundle_enable_all_connections(bundle
);
136 static int gb_bundle_resume(struct device
*dev
)
138 struct gb_bundle
*bundle
= to_gb_bundle(dev
);
139 const struct dev_pm_ops
*pm
= dev
->driver
->pm
;
142 ret
= gb_control_bundle_resume(bundle
->intf
->control
, bundle
->id
);
146 if (pm
&& pm
->runtime_resume
) {
147 ret
= pm
->runtime_resume(dev
);
151 gb_bundle_enable_all_connections(bundle
);
157 static int gb_bundle_idle(struct device
*dev
)
159 pm_runtime_mark_last_busy(dev
);
160 pm_request_autosuspend(dev
);
166 static const struct dev_pm_ops gb_bundle_pm_ops
= {
167 SET_RUNTIME_PM_OPS(gb_bundle_suspend
, gb_bundle_resume
, gb_bundle_idle
)
170 struct device_type greybus_bundle_type
= {
171 .name
= "greybus_bundle",
172 .release
= gb_bundle_release
,
173 .pm
= &gb_bundle_pm_ops
,
177 * Create a gb_bundle structure to represent a discovered
178 * bundle. Returns a pointer to the new bundle or a null
179 * pointer if a failure occurs due to memory exhaustion.
181 struct gb_bundle
*gb_bundle_create(struct gb_interface
*intf
, u8 bundle_id
,
184 struct gb_bundle
*bundle
;
186 if (bundle_id
== BUNDLE_ID_NONE
) {
187 dev_err(&intf
->dev
, "can't use bundle id %u\n", bundle_id
);
192 * Reject any attempt to reuse a bundle id. We initialize
193 * these serially, so there's no need to worry about keeping
194 * the interface bundle list locked here.
196 if (gb_bundle_find(intf
, bundle_id
)) {
197 dev_err(&intf
->dev
, "duplicate bundle id %u\n", bundle_id
);
201 bundle
= kzalloc(sizeof(*bundle
), GFP_KERNEL
);
206 bundle
->id
= bundle_id
;
207 bundle
->class = class;
208 INIT_LIST_HEAD(&bundle
->connections
);
210 bundle
->dev
.parent
= &intf
->dev
;
211 bundle
->dev
.bus
= &greybus_bus_type
;
212 bundle
->dev
.type
= &greybus_bundle_type
;
213 bundle
->dev
.groups
= bundle_groups
;
214 bundle
->dev
.dma_mask
= intf
->dev
.dma_mask
;
215 device_initialize(&bundle
->dev
);
216 dev_set_name(&bundle
->dev
, "%s.%d", dev_name(&intf
->dev
), bundle_id
);
218 list_add(&bundle
->links
, &intf
->bundles
);
220 trace_gb_bundle_create(bundle
);
225 int gb_bundle_add(struct gb_bundle
*bundle
)
229 ret
= device_add(&bundle
->dev
);
231 dev_err(&bundle
->dev
, "failed to register bundle: %d\n", ret
);
235 trace_gb_bundle_add(bundle
);
241 * Tear down a previously set up bundle.
243 void gb_bundle_destroy(struct gb_bundle
*bundle
)
245 trace_gb_bundle_destroy(bundle
);
247 if (device_is_registered(&bundle
->dev
))
248 device_del(&bundle
->dev
);
250 list_del(&bundle
->links
);
252 put_device(&bundle
->dev
);