1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright 2014-2015 Google Inc.
6 * Copyright 2014-2015 Linaro Ltd.
9 #include <linux/greybus.h>
10 #include "greybus_trace.h"
12 static ssize_t
bundle_class_show(struct device
*dev
,
13 struct device_attribute
*attr
, char *buf
)
15 struct gb_bundle
*bundle
= to_gb_bundle(dev
);
17 return sprintf(buf
, "0x%02x\n", bundle
->class);
19 static DEVICE_ATTR_RO(bundle_class
);
21 static ssize_t
bundle_id_show(struct device
*dev
,
22 struct device_attribute
*attr
, char *buf
)
24 struct gb_bundle
*bundle
= to_gb_bundle(dev
);
26 return sprintf(buf
, "%u\n", bundle
->id
);
28 static DEVICE_ATTR_RO(bundle_id
);
30 static ssize_t
state_show(struct device
*dev
, struct device_attribute
*attr
,
33 struct gb_bundle
*bundle
= to_gb_bundle(dev
);
36 return sprintf(buf
, "\n");
38 return sprintf(buf
, "%s\n", bundle
->state
);
41 static ssize_t
state_store(struct device
*dev
, struct device_attribute
*attr
,
42 const char *buf
, size_t size
)
44 struct gb_bundle
*bundle
= to_gb_bundle(dev
);
47 bundle
->state
= kstrdup(buf
, GFP_KERNEL
);
51 /* Tell userspace that the file contents changed */
52 sysfs_notify(&bundle
->dev
.kobj
, NULL
, "state");
56 static DEVICE_ATTR_RW(state
);
58 static struct attribute
*bundle_attrs
[] = {
59 &dev_attr_bundle_class
.attr
,
60 &dev_attr_bundle_id
.attr
,
65 ATTRIBUTE_GROUPS(bundle
);
67 static struct gb_bundle
*gb_bundle_find(struct gb_interface
*intf
,
70 struct gb_bundle
*bundle
;
72 list_for_each_entry(bundle
, &intf
->bundles
, links
) {
73 if (bundle
->id
== bundle_id
)
80 static void gb_bundle_release(struct device
*dev
)
82 struct gb_bundle
*bundle
= to_gb_bundle(dev
);
84 trace_gb_bundle_release(bundle
);
87 kfree(bundle
->cport_desc
);
92 static void gb_bundle_disable_all_connections(struct gb_bundle
*bundle
)
94 struct gb_connection
*connection
;
96 list_for_each_entry(connection
, &bundle
->connections
, bundle_links
)
97 gb_connection_disable(connection
);
100 static void gb_bundle_enable_all_connections(struct gb_bundle
*bundle
)
102 struct gb_connection
*connection
;
104 list_for_each_entry(connection
, &bundle
->connections
, bundle_links
)
105 gb_connection_enable(connection
);
108 static int gb_bundle_suspend(struct device
*dev
)
110 struct gb_bundle
*bundle
= to_gb_bundle(dev
);
111 const struct dev_pm_ops
*pm
= dev
->driver
->pm
;
114 if (pm
&& pm
->runtime_suspend
) {
115 ret
= pm
->runtime_suspend(&bundle
->dev
);
119 gb_bundle_disable_all_connections(bundle
);
122 ret
= gb_control_bundle_suspend(bundle
->intf
->control
, bundle
->id
);
124 if (pm
&& pm
->runtime_resume
)
125 ret
= pm
->runtime_resume(dev
);
127 gb_bundle_enable_all_connections(bundle
);
135 static int gb_bundle_resume(struct device
*dev
)
137 struct gb_bundle
*bundle
= to_gb_bundle(dev
);
138 const struct dev_pm_ops
*pm
= dev
->driver
->pm
;
141 ret
= gb_control_bundle_resume(bundle
->intf
->control
, bundle
->id
);
145 if (pm
&& pm
->runtime_resume
) {
146 ret
= pm
->runtime_resume(dev
);
150 gb_bundle_enable_all_connections(bundle
);
156 static int gb_bundle_idle(struct device
*dev
)
158 pm_runtime_mark_last_busy(dev
);
159 pm_request_autosuspend(dev
);
165 static const struct dev_pm_ops gb_bundle_pm_ops
= {
166 SET_RUNTIME_PM_OPS(gb_bundle_suspend
, gb_bundle_resume
, gb_bundle_idle
)
169 struct device_type greybus_bundle_type
= {
170 .name
= "greybus_bundle",
171 .release
= gb_bundle_release
,
172 .pm
= &gb_bundle_pm_ops
,
176 * Create a gb_bundle structure to represent a discovered
177 * bundle. Returns a pointer to the new bundle or a null
178 * pointer if a failure occurs due to memory exhaustion.
180 struct gb_bundle
*gb_bundle_create(struct gb_interface
*intf
, u8 bundle_id
,
183 struct gb_bundle
*bundle
;
185 if (bundle_id
== BUNDLE_ID_NONE
) {
186 dev_err(&intf
->dev
, "can't use bundle id %u\n", bundle_id
);
191 * Reject any attempt to reuse a bundle id. We initialize
192 * these serially, so there's no need to worry about keeping
193 * the interface bundle list locked here.
195 if (gb_bundle_find(intf
, bundle_id
)) {
196 dev_err(&intf
->dev
, "duplicate bundle id %u\n", bundle_id
);
200 bundle
= kzalloc(sizeof(*bundle
), GFP_KERNEL
);
205 bundle
->id
= bundle_id
;
206 bundle
->class = class;
207 INIT_LIST_HEAD(&bundle
->connections
);
209 bundle
->dev
.parent
= &intf
->dev
;
210 bundle
->dev
.bus
= &greybus_bus_type
;
211 bundle
->dev
.type
= &greybus_bundle_type
;
212 bundle
->dev
.groups
= bundle_groups
;
213 bundle
->dev
.dma_mask
= intf
->dev
.dma_mask
;
214 device_initialize(&bundle
->dev
);
215 dev_set_name(&bundle
->dev
, "%s.%d", dev_name(&intf
->dev
), bundle_id
);
217 list_add(&bundle
->links
, &intf
->bundles
);
219 trace_gb_bundle_create(bundle
);
224 int gb_bundle_add(struct gb_bundle
*bundle
)
228 ret
= device_add(&bundle
->dev
);
230 dev_err(&bundle
->dev
, "failed to register bundle: %d\n", ret
);
234 trace_gb_bundle_add(bundle
);
240 * Tear down a previously set up bundle.
242 void gb_bundle_destroy(struct gb_bundle
*bundle
)
244 trace_gb_bundle_destroy(bundle
);
246 if (device_is_registered(&bundle
->dev
))
247 device_del(&bundle
->dev
);
249 list_del(&bundle
->links
);
251 put_device(&bundle
->dev
);