2 * Greybus driver and device API
4 * Copyright 2014 Google Inc.
6 * Released under the GPLv2 only.
9 #ifndef __LINUX_GREYBUS_H
10 #define __LINUX_GREYBUS_H
14 #include <linux/kernel.h>
15 #include <linux/types.h>
16 #include <linux/list.h>
17 #include <linux/slab.h>
18 #include <linux/device.h>
19 #include <linux/module.h>
20 #include <linux/idr.h>
22 #include "kernel_ver.h"
23 #include "greybus_id.h"
24 #include "greybus_manifest.h"
26 #include "interface_block.h"
27 #include "interface.h"
28 #include "connection.h"
30 #include "operation.h"
33 /* Matches up with the Greybus Protocol specification document */
34 #define GREYBUS_VERSION_MAJOR 0x00
35 #define GREYBUS_VERSION_MINOR 0x01
37 #define GREYBUS_DEVICE_ID_MATCH_DEVICE \
38 (GREYBUS_DEVICE_ID_MATCH_VENDOR | GREYBUS_DEVICE_ID_MATCH_PRODUCT)
40 #define GREYBUS_DEVICE(v, p) \
41 .match_flags = GREYBUS_DEVICE_ID_MATCH_DEVICE, \
45 #define GREYBUS_DEVICE_SERIAL(s) \
46 .match_flags = GREYBUS_DEVICE_ID_MATCH_SERIAL, \
49 /* XXX I couldn't get my Kconfig file to be noticed for out-of-tree build */
50 #ifndef CONFIG_HOST_DEV_CPORT_ID_MAX
51 #define CONFIG_HOST_DEV_CPORT_ID_MAX 128
52 #endif /* !CONFIG_HOST_DEV_CPORT_ID_MAX */
54 /* Maximum number of CPorts usable by a host device */
55 /* XXX This should really be determined by the AP module manifest */
56 #define HOST_DEV_CPORT_ID_MAX CONFIG_HOST_DEV_CPORT_ID_MAX
57 #define CPORT_ID_BAD U16_MAX /* UniPro max id is 4095 */
59 /* For SP1 hardware, we are going to "hardcode" each device to have all logical
60 * blocks in order to be able to address them as one unified "unit". Then
61 * higher up layers will then be able to talk to them as one logical block and
62 * properly know how they are hooked together (i.e. which i2c port is on the
63 * same module as the gpio pins, etc.)
65 * So, put the "private" data structures here in greybus.h and link to them off
66 * of the "main" gb_module structure.
69 struct greybus_host_device;
73 * When the Greybus code allocates a buffer it sets aside bytes
74 * prior to the beginning of the payload area for the host device's
75 * exclusive use. The size is specified by hd->buffer_headroom, and
76 * which can't be greater than GB_BUFFER_HEADROOM_MAX.
78 #define GB_BUFFER_HEADROOM_MAX sizeof(u64)
80 /* Buffers allocated from the host driver will be aligned to this multiple */
81 #define GB_BUFFER_ALIGN sizeof(u32)
83 /* Greybus "Host driver" structure, needed by a host controller driver to be
84 * able to handle both SVC control as well as "real" greybus messages
86 struct greybus_host_driver {
89 void *(*buffer_send)(struct greybus_host_device *hd, u16 dest_cport_id,
90 void *buffer, size_t buffer_size, gfp_t gfp_mask);
91 void (*buffer_cancel)(void *cookie);
92 int (*submit_svc)(struct svc_msg *svc_msg,
93 struct greybus_host_device *hd);
96 struct greybus_host_device {
98 struct device *parent;
99 const struct greybus_host_driver *driver;
101 struct list_head modules;
102 struct list_head connections;
103 struct ida cport_id_map;
106 /* Host device buffer constraints */
107 size_t buffer_headroom;
108 size_t buffer_size_max;
110 /* Private data for the host driver */
111 unsigned long hd_priv[0] __aligned(sizeof(s64));
114 struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *hd,
115 struct device *parent);
116 void greybus_remove_hd(struct greybus_host_device *hd);
118 struct greybus_driver {
121 int (*probe)(struct gb_interface_block *gb_ib,
122 const struct greybus_interface_block_id *id);
123 void (*disconnect)(struct gb_interface_block *gb_ib);
125 int (*suspend)(struct gb_interface_block *gb_ib, pm_message_t message);
126 int (*resume)(struct gb_interface_block *gb_ib);
128 const struct greybus_interface_block_id *id_table;
130 struct device_driver driver;
132 #define to_greybus_driver(d) container_of(d, struct greybus_driver, driver)
134 /* Don't call these directly, use the module_greybus_driver() macro instead */
135 int greybus_register_driver(struct greybus_driver *driver,
136 struct module *module, const char *mod_name);
137 void greybus_deregister(struct greybus_driver *driver);
139 /* define to get proper THIS_MODULE and KBUILD_MODNAME values */
140 #define greybus_register(driver) \
141 greybus_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
144 * module_greybus_driver() - Helper macro for registering a Greybus driver
145 * @__greybus_driver: greybus_driver structure
147 * Helper macro for Greybus drivers to set up proper module init / exit
148 * functions. Replaces module_init() and module_exit() and keeps people from
149 * printing pointless things to the kernel log when their driver is loaded.
151 #define module_greybus_driver(__greybus_driver) \
152 module_driver(__greybus_driver, greybus_register, greybus_deregister)
154 int greybus_disabled(void);
156 /* Internal functions to gb module, move to internal .h file eventually. */
158 void gb_add_module(struct greybus_host_device *hd, u8 module_id,
160 void gb_remove_module(struct greybus_host_device *hd, u8 module_id);
161 void gb_remove_modules(struct greybus_host_device *hd);
163 int greybus_svc_in(struct greybus_host_device *hd, u8 *data, int length);
164 int gb_ap_init(void);
165 void gb_ap_exit(void);
166 int gb_debugfs_init(void);
167 void gb_debugfs_cleanup(void);
169 extern struct bus_type greybus_bus_type;
171 int gb_uart_device_init(struct gb_connection *connection);
172 void gb_uart_device_exit(struct gb_connection *connection);
174 int svc_set_route_send(struct gb_interface *interface,
175 struct greybus_host_device *hd);
177 extern struct device_type greybus_interface_block_type;
178 extern struct device_type greybus_interface_type;
179 extern struct device_type greybus_connection_type;
181 static inline int is_gb_interface_block(const struct device *dev)
183 return dev->type == &greybus_interface_block_type;
186 static inline int is_gb_interface(const struct device *dev)
188 return dev->type == &greybus_interface_type;
191 static inline int is_gb_connection(const struct device *dev)
193 return dev->type == &greybus_connection_type;
196 #endif /* __KERNEL__ */
197 #endif /* __LINUX_GREYBUS_H */