blob: 07b7e444d766a8a39f833c9ff55a64a13461a74e [file] [log] [blame]
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -08001/*
2 * Greybus module code
3 *
4 * Copyright 2014 Google Inc.
5 * Copyright 2014 Linaro Ltd.
6 *
7 * Released under the GPLv2 only.
8 */
9
10#include "greybus.h"
11
12
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -080013/* module sysfs attributes */
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -080014static ssize_t epm_show(struct device *dev, struct device_attribute *attr,
15 char *buf)
16{
Greg Kroah-Hartman764e8242015-04-07 20:26:30 +020017 // FIXME
18 // Implement something here when we have a working control protocol
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -080019 return sprintf(buf, "1\n");
20}
21
22static ssize_t epm_store(struct device *dev, struct device_attribute *attr,
23 const char *buf, size_t size)
24{
Greg Kroah-Hartman764e8242015-04-07 20:26:30 +020025 // FIXME
26 // Implement something here when we have a working control protocol
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -080027 return 0;
28}
29static DEVICE_ATTR_RW(epm);
30
Greg Kroah-Hartman764e8242015-04-07 20:26:30 +020031static ssize_t power_control_show(struct device *dev,
32 struct device_attribute *addr, char *buf)
33{
34 // FIXME
35 // Implement something here when we have a working control protocol
36 return sprintf(buf, "1\n");
37}
38
39static ssize_t power_control_store(struct device *dev,
40 struct device_attribute *attr,
41 const char *buf, size_t size)
42{
43 // FIXME
44 // Implement something here when we have a working control protocol
45 return 0;
46}
47static DEVICE_ATTR_RW(power_control);
48
49static ssize_t present_show(struct device *dev,
50 struct device_attribute *addr, char *buf)
51{
52 // FIXME
53 // Implement something here when we have a working control protocol
54 return sprintf(buf, "1\n");
55}
56
57static ssize_t present_store(struct device *dev, struct device_attribute *attr,
58 const char *buf, size_t size)
59{
60 // FIXME
61 // Implement something here when we have a working control protocol
62 return 0;
63}
64static DEVICE_ATTR_RW(present);
65
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -080066static struct attribute *module_attrs[] = {
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -080067 &dev_attr_epm.attr,
Greg Kroah-Hartman764e8242015-04-07 20:26:30 +020068 &dev_attr_power_control.attr,
69 &dev_attr_present.attr,
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -080070 NULL,
71};
72ATTRIBUTE_GROUPS(module);
73
Viresh Kumarc16b63e82015-05-20 16:48:04 +053074static void gb_module_release(struct device *dev)
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -080075{
76 struct gb_module *module = to_gb_module(dev);
77
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -080078 kfree(module);
79}
80
81struct device_type greybus_module_type = {
82 .name = "greybus_module",
Viresh Kumarc16b63e82015-05-20 16:48:04 +053083 .release = gb_module_release,
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -080084};
85
Greg Kroah-Hartmana4d91502015-04-07 20:27:15 +020086struct module_find {
87 struct gb_endo *endo;
88 u8 module_id;
89};
90
Greg Kroah-Hartmane5646712014-12-24 13:01:46 -080091static int module_find(struct device *dev, void *data)
92{
93 struct gb_module *module;
Greg Kroah-Hartmana4d91502015-04-07 20:27:15 +020094 struct module_find *find = data;
Greg Kroah-Hartmane5646712014-12-24 13:01:46 -080095
96 if (!is_gb_module(dev))
97 return 0;
98
99 module = to_gb_module(dev);
Greg Kroah-Hartmana4d91502015-04-07 20:27:15 +0200100 if ((module->module_id == find->module_id) &&
101 (module->dev.parent == &find->endo->dev))
Greg Kroah-Hartmane5646712014-12-24 13:01:46 -0800102 return 1;
103
104 return 0;
105}
106
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -0800107/*
108 * Search the list of modules in the system. If one is found, return it, with
109 * the reference count incremented.
110 */
Greg Kroah-Hartmana4d91502015-04-07 20:27:15 +0200111struct gb_module *gb_module_find(struct greybus_host_device *hd, u8 module_id)
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -0800112{
Greg Kroah-Hartmane5646712014-12-24 13:01:46 -0800113 struct device *dev;
114 struct gb_module *module = NULL;
Greg Kroah-Hartmana4d91502015-04-07 20:27:15 +0200115 struct module_find find;
116
Viresh Kumar51e93ae2015-05-08 12:58:51 +0530117 if (!module_id)
118 return NULL;
119
Greg Kroah-Hartmana4d91502015-04-07 20:27:15 +0200120 find.module_id = module_id;
121 find.endo = hd->endo;
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -0800122
Greg Kroah-Hartmane5646712014-12-24 13:01:46 -0800123 dev = bus_find_device(&greybus_bus_type, NULL,
Greg Kroah-Hartmana4d91502015-04-07 20:27:15 +0200124 &find, module_find);
Greg Kroah-Hartmane5646712014-12-24 13:01:46 -0800125 if (dev)
126 module = to_gb_module(dev);
127
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -0800128 return module;
129}
130
Greg Kroah-Hartmana4d91502015-04-07 20:27:15 +0200131struct gb_module *gb_module_create(struct device *parent, u8 module_id)
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -0800132{
133 struct gb_module *module;
134 int retval;
135
136 module = kzalloc(sizeof(*module), GFP_KERNEL);
137 if (!module)
138 return NULL;
139
140 module->module_id = module_id;
Greg Kroah-Hartmana4d91502015-04-07 20:27:15 +0200141 module->dev.parent = parent;
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -0800142 module->dev.bus = &greybus_bus_type;
143 module->dev.type = &greybus_module_type;
144 module->dev.groups = module_groups;
Greg Kroah-Hartmana4d91502015-04-07 20:27:15 +0200145 module->dev.dma_mask = parent->dma_mask;
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -0800146 device_initialize(&module->dev);
147 dev_set_name(&module->dev, "%d", module_id);
148
149 retval = device_add(&module->dev);
150 if (retval) {
151 pr_err("failed to add module device for id 0x%02hhx\n",
152 module_id);
153 put_device(&module->dev);
154 kfree(module);
155 return NULL;
156 }
157
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -0800158 return module;
159}
160
Greg Kroah-Hartmana4d91502015-04-07 20:27:15 +0200161static int module_remove(struct device *dev, void *data)
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -0800162{
163 struct gb_module *module;
Greg Kroah-Hartmana4d91502015-04-07 20:27:15 +0200164 struct gb_endo *endo = data;
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -0800165
Greg Kroah-Hartmana4d91502015-04-07 20:27:15 +0200166 if (!is_gb_module(dev))
167 return 0;
Greg Kroah-Hartmandf671552014-12-21 14:10:26 -0800168
Greg Kroah-Hartmana4d91502015-04-07 20:27:15 +0200169 module = to_gb_module(dev);
170 if (module->dev.parent == &endo->dev)
Viresh Kumar2352a732015-04-02 17:53:47 +0530171 device_unregister(&module->dev);
Greg Kroah-Hartmana4d91502015-04-07 20:27:15 +0200172
173 return 0;
Viresh Kumar2352a732015-04-02 17:53:47 +0530174}
175
Greg Kroah-Hartmana4d91502015-04-07 20:27:15 +0200176void gb_module_remove_all(struct gb_endo *endo)
177{
178 bus_for_each_dev(&greybus_bus_type, NULL, endo, module_remove);
179}