forked from projectara/greybus
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodule.c
More file actions
135 lines (109 loc) · 2.81 KB
/
Copy pathmodule.c
File metadata and controls
135 lines (109 loc) · 2.81 KB
1
2
3
4
5
6
7
8
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
* Greybus module code
*
* Copyright 2014 Google Inc.
* Copyright 2014 Linaro Ltd.
*
* Released under the GPLv2 only.
*/
#include "greybus.h"
/* module sysfs attributes */
#define gb_module_attr(field, type) \
static ssize_t field##_show(struct device *dev, \
struct device_attribute *attr, \
char *buf) \
{ \
struct gb_module *module = to_gb_module(dev); \
return sprintf(buf, "%"#type"\n", module->field); \
} \
static DEVICE_ATTR_RO(field)
// FIXME, do we really need this attribute?
gb_module_attr(module_id, x);
static ssize_t epm_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
// FIXME, implement something here
return sprintf(buf, "1\n");
}
static ssize_t epm_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
// FIXME, implement something here.
return 0;
}
static DEVICE_ATTR_RW(epm);
static struct attribute *module_attrs[] = {
&dev_attr_module_id.attr,
&dev_attr_epm.attr,
NULL,
};
ATTRIBUTE_GROUPS(module);
static void greybus_module_release(struct device *dev)
{
struct gb_module *module = to_gb_module(dev);
kfree(module);
}
struct device_type greybus_module_type = {
.name = "greybus_module",
.release = greybus_module_release,
};
static int module_find(struct device *dev, void *data)
{
struct gb_module *module;
u8 *module_id = data;
if (!is_gb_module(dev))
return 0;
module = to_gb_module(dev);
if (module->module_id == *module_id)
return 1;
return 0;
}
/*
* Search the list of modules in the system. If one is found, return it, with
* the reference count incremented.
*/
static struct gb_module *gb_module_find(u8 module_id)
{
struct device *dev;
struct gb_module *module = NULL;
dev = bus_find_device(&greybus_bus_type, NULL,
&module_id, module_find);
if (dev)
module = to_gb_module(dev);
return module;
}
static struct gb_module *gb_module_create(struct greybus_host_device *hd,
u8 module_id)
{
struct gb_module *module;
int retval;
module = kzalloc(sizeof(*module), GFP_KERNEL);
if (!module)
return NULL;
module->module_id = module_id;
module->dev.parent = hd->parent;
module->dev.bus = &greybus_bus_type;
module->dev.type = &greybus_module_type;
module->dev.groups = module_groups;
module->dev.dma_mask = hd->parent->dma_mask;
device_initialize(&module->dev);
dev_set_name(&module->dev, "%d", module_id);
retval = device_add(&module->dev);
if (retval) {
pr_err("failed to add module device for id 0x%02hhx\n",
module_id);
put_device(&module->dev);
kfree(module);
return NULL;
}
return module;
}
struct gb_module *gb_module_find_or_create(struct greybus_host_device *hd,
u8 module_id)
{
struct gb_module *module;
module = gb_module_find(module_id);
if (module)
return module;
return gb_module_create(hd, module_id);
}