Skip to content

Commit

Permalink
greybus: core: add module abstraction
Browse files Browse the repository at this point in the history
Add Greybus module abstraction that will be used to implement controlled
module removal (eject) and represent module geometry.

Greybus module devices correspond to physical modules and have one or
more interfaces. Modules have an id that is identical to the id of their
primary interface, which in turn is the interface with lowest numbered
id. The module name is constructed from the bus and module id:

        <bus_id>-<module_id>

Interfaces, bundles, and control devices are consequently renamed as

        <bus_id>-<module_id>.<interface_id>
        <bus_id>-<module_id>.<interface_id>.<bundle_id>
        <bus_id>-<module_id>.<interface_id>.ctrl

As before, interface ids (and therefore in a sense now also module ids)
correspond to physical interface positions on the frame.

Modules have the following attributes:

        module_id
        num_interfaces

where module_id is the id of the module and num_interface the number of
interfaces the module has.

Note that until SVC module-size detection has been implemented, all
interfaces are considered to be part of 1x2 modules. Specifically, the
two interfaces of a 2x2 module will be presented as two 1x2 modules for
now.

Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
  • Loading branch information
Johan Hovold authored and Greg Kroah-Hartman committed Apr 25, 2016
1 parent 844fcbf commit b15d97d
Show file tree
Hide file tree
Showing 11 changed files with 333 additions and 96 deletions.
63 changes: 43 additions & 20 deletions drivers/staging/greybus/Documentation/sysfs-bus-greybus
Original file line number Diff line number Diff line change
Expand Up @@ -6,133 +6,156 @@ Description:
The "root" greybus device for the Greybus device tree, or bus,
where N is a dynamically assigned 1-based id.

What: /sys/bus/greybus/device/N-I
What: /sys/bus/greybus/device/N-M
Date: March 2016
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
A Module M on the bus N, where M is the 1-byte interface
ID of the module's primary interface.

What: /sys/bus/greybus/device/N-M/module_id
Date: March 2016
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
The ID of a Greybus module, corresponding to the ID of its
primary interface.

What: /sys/bus/greybus/device/N-M/num_interfaces
Date: March 2016
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
The number of interfaces of a module.

What: /sys/bus/greybus/device/N-M.I
Date: October 2015
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
An Interface I on the bus N, where I is the 1-byte interface
ID.
An Interface I on the bus N and module N-M, where I is the
1-byte interface ID.

What: /sys/bus/greybus/device/N-I/current_now
What: /sys/bus/greybus/device/N-M.I/current_now
Date: March 2016
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
Current measurement of the interface in microamps (uA)

What: /sys/bus/greybus/device/N-I/ddbl1_manufacturer_id
What: /sys/bus/greybus/device/N-M.I/ddbl1_manufacturer_id
Date: October 2015
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
Unipro Device Descriptor Block Level 1 manufacturer ID for the
greybus Interface.

What: /sys/bus/greybus/device/N-I/ddbl1_product_id
What: /sys/bus/greybus/device/N-M.I/ddbl1_product_id
Date: October 2015
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
Unipro Device Descriptor Block Level 1 product ID for the
greybus Interface.

What: /sys/bus/greybus/device/N-I/interface_id
What: /sys/bus/greybus/device/N-M.I/interface_id
Date: October 2015
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
The ID of a Greybus interface.

What: /sys/bus/greybus/device/N-I/power_now
What: /sys/bus/greybus/device/N-M.I/power_now
Date: March 2016
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
Power measurement of the interface in microwatts (uW)

What: /sys/bus/greybus/device/N-I/product_id
What: /sys/bus/greybus/device/N-M.I/product_id
Date: October 2015
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
Product ID of a Greybus interface.

What: /sys/bus/greybus/device/N-I/serial_number
What: /sys/bus/greybus/device/N-M.I/serial_number
Date: October 2015
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
Serial Number of the Greybus interface, represented by a 64 bit
hexadecimal number.

What: /sys/bus/greybus/device/N-I/vendor_id
What: /sys/bus/greybus/device/N-M.I/vendor_id
Date: October 2015
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
Vendor ID of a Greybus interface.

What: /sys/bus/greybus/device/N-I/version
What: /sys/bus/greybus/device/N-M.I/version
Date: October 2015
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
Interface version represented as <16 bit major number>.<16 bit
minor number>.

What: /sys/bus/greybus/device/N-I/voltage_now
What: /sys/bus/greybus/device/N-M.I/voltage_now
Date: March 2016
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
Voltage measurement of the interface in microvolts (uV)

What: /sys/bus/greybus/device/N-I.ctrl
What: /sys/bus/greybus/device/N-M.I.ctrl
Date: October 2015
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
Abstract control device for interface I that represents the
current mode of an enumerated Greybus interface.

What: /sys/bus/greybus/device/N-I.ctrl/product_string
What: /sys/bus/greybus/device/N-M.I.ctrl/product_string
Date: October 2015
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
Product ID string of a Greybus interface.

What: /sys/bus/greybus/device/N-I.ctrl/vendor_string
What: /sys/bus/greybus/device/N-M.I.ctrl/vendor_string
Date: October 2015
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
Vendor ID string of a Greybus interface.

What: /sys/bus/greybus/device/N-I.B
What: /sys/bus/greybus/device/N-M.I.B
Date: October 2015
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
A bundle B on the Interface I, B is replaced by a 1-byte
number representing the bundle.

What: /sys/bus/greybus/device/N-I.B/bundle_class
What: /sys/bus/greybus/device/N-M.I.B/bundle_class
Date: October 2015
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
The greybus class of the bundle B.

What: /sys/bus/greybus/device/N-I.B/bundle_id
What: /sys/bus/greybus/device/N-M.I.B/bundle_id
Date: October 2015
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
The interface-unique id of the bundle B.

What: /sys/bus/greybus/device/N-I.B/state
What: /sys/bus/greybus/device/N-M.I.B/state
Date: October 2015
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Expand Down
1 change: 1 addition & 0 deletions drivers/staging/greybus/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ greybus-y := core.o \
debugfs.o \
hd.o \
manifest.o \
module.o \
interface.o \
bundle.o \
connection.o \
Expand Down
11 changes: 11 additions & 0 deletions drivers/staging/greybus/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,20 @@ static int greybus_module_match(struct device *dev, struct device_driver *drv)
static int greybus_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct gb_host_device *hd;
struct gb_module *module = NULL;
struct gb_interface *intf = NULL;
struct gb_control *control = NULL;
struct gb_bundle *bundle = NULL;
struct gb_svc *svc = NULL;

if (is_gb_host_device(dev)) {
hd = to_gb_host_device(dev);
} else if (is_gb_module(dev)) {
module = to_gb_module(dev);
hd = module->hd;
} else if (is_gb_interface(dev)) {
intf = to_gb_interface(dev);
module = intf->module;
hd = intf->hd;
} else if (is_gb_control(dev)) {
control = to_gb_control(dev);
Expand All @@ -102,6 +107,7 @@ static int greybus_uevent(struct device *dev, struct kobj_uevent_env *env)
} else if (is_gb_bundle(dev)) {
bundle = to_gb_bundle(dev);
intf = bundle->intf;
module = intf->module;
hd = intf->hd;
} else if (is_gb_svc(dev)) {
svc = to_gb_svc(dev);
Expand All @@ -114,6 +120,11 @@ static int greybus_uevent(struct device *dev, struct kobj_uevent_env *env)
if (add_uevent_var(env, "BUS=%u", hd->bus_id))
return -ENOMEM;

if (module) {
if (add_uevent_var(env, "MODULE=%u", module->module_id))
return -ENOMEM;
}

if (intf) {
if (add_uevent_var(env, "INTERFACE=%u", intf->interface_id))
return -ENOMEM;
Expand Down
7 changes: 7 additions & 0 deletions drivers/staging/greybus/greybus.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "hd.h"
#include "svc.h"
#include "control.h"
#include "module.h"
#include "interface.h"
#include "bundle.h"
#include "connection.h"
Expand Down Expand Up @@ -112,6 +113,7 @@ struct dentry *gb_debugfs_get(void);
extern struct bus_type greybus_bus_type;

extern struct device_type greybus_hd_type;
extern struct device_type greybus_module_type;
extern struct device_type greybus_interface_type;
extern struct device_type greybus_control_type;
extern struct device_type greybus_bundle_type;
Expand All @@ -122,6 +124,11 @@ static inline int is_gb_host_device(const struct device *dev)
return dev->type == &greybus_hd_type;
}

static inline int is_gb_module(const struct device *dev)
{
return dev->type == &greybus_module_type;
}

static inline int is_gb_interface(const struct device *dev)
{
return dev->type == &greybus_interface_type;
Expand Down
2 changes: 1 addition & 1 deletion drivers/staging/greybus/hd.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ struct gb_host_device *gb_hd_create(struct gb_hd_driver *driver,
hd->bus_id = ret;

hd->driver = driver;
INIT_LIST_HEAD(&hd->interfaces);
INIT_LIST_HEAD(&hd->modules);
INIT_LIST_HEAD(&hd->connections);
ida_init(&hd->cport_id_map);
hd->buffer_size_max = buffer_size_max;
Expand Down
2 changes: 1 addition & 1 deletion drivers/staging/greybus/hd.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct gb_host_device {
int bus_id;
const struct gb_hd_driver *driver;

struct list_head interfaces;
struct list_head modules;
struct list_head connections;
struct ida cport_id_map;

Expand Down
40 changes: 12 additions & 28 deletions drivers/staging/greybus/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,21 +333,6 @@ static struct attribute *interface_attrs[] = {
};
ATTRIBUTE_GROUPS(interface);


// FIXME, odds are you don't want to call this function, rework the caller to
// not need it please.
struct gb_interface *gb_interface_find(struct gb_host_device *hd,
u8 interface_id)
{
struct gb_interface *intf;

list_for_each_entry(intf, &hd->interfaces, links)
if (intf->interface_id == interface_id)
return intf;

return NULL;
}

static void gb_interface_release(struct device *dev)
{
struct gb_interface *intf = to_gb_interface(dev);
Expand All @@ -371,36 +356,34 @@ struct device_type greybus_interface_type = {
*
* Returns a pointer to the new interfce or a null pointer if a
* failure occurs due to memory exhaustion.
*
* Locking: Caller ensures serialisation with gb_interface_remove and
* gb_interface_find.
*/
struct gb_interface *gb_interface_create(struct gb_host_device *hd,
struct gb_interface *gb_interface_create(struct gb_module *module,
u8 interface_id)
{
struct gb_host_device *hd = module->hd;
struct gb_interface *intf;

intf = kzalloc(sizeof(*intf), GFP_KERNEL);
if (!intf)
return NULL;

intf->hd = hd; /* XXX refcount? */
intf->module = module;
intf->interface_id = interface_id;
INIT_LIST_HEAD(&intf->bundles);
INIT_LIST_HEAD(&intf->manifest_descs);

/* Invalid device id to start with */
intf->device_id = GB_INTERFACE_DEVICE_ID_BAD;

intf->dev.parent = &hd->dev;
intf->dev.parent = &module->dev;
intf->dev.bus = &greybus_bus_type;
intf->dev.type = &greybus_interface_type;
intf->dev.groups = interface_groups;
intf->dev.dma_mask = hd->dev.dma_mask;
intf->dev.dma_mask = module->dev.dma_mask;
device_initialize(&intf->dev);
dev_set_name(&intf->dev, "%d-%d", hd->bus_id, interface_id);

list_add(&intf->links, &hd->interfaces);
dev_set_name(&intf->dev, "%s.%u", dev_name(&module->dev),
interface_id);

return intf;
}
Expand Down Expand Up @@ -579,15 +562,16 @@ int gb_interface_add(struct gb_interface *intf)
return 0;
}

/* Deregister an interface and drop its reference. */
void gb_interface_remove(struct gb_interface *intf)
/* Deregister an interface. */
void gb_interface_del(struct gb_interface *intf)
{
if (device_is_registered(&intf->dev)) {
device_del(&intf->dev);
dev_info(&intf->dev, "Interface removed\n");
}
}

list_del(&intf->links);

void gb_interface_put(struct gb_interface *intf)
{
put_device(&intf->dev);
}
8 changes: 5 additions & 3 deletions drivers/staging/greybus/interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ struct gb_interface {
struct gb_control *control;

struct list_head bundles;
struct list_head links; /* gb_host_device->interfaces */
struct list_head module_node;
struct list_head manifest_descs;
u8 interface_id; /* Physical location within the Endo */
u8 device_id;
Expand All @@ -35,6 +35,7 @@ struct gb_interface {
u16 version_minor;

struct gb_host_device *hd;
struct gb_module *module;

unsigned long quirks;

Expand All @@ -46,13 +47,14 @@ struct gb_interface {
struct gb_interface *gb_interface_find(struct gb_host_device *hd,
u8 interface_id);

struct gb_interface *gb_interface_create(struct gb_host_device *hd,
struct gb_interface *gb_interface_create(struct gb_module *module,
u8 interface_id);
int gb_interface_activate(struct gb_interface *intf);
void gb_interface_deactivate(struct gb_interface *intf);
int gb_interface_enable(struct gb_interface *intf);
void gb_interface_disable(struct gb_interface *intf);
int gb_interface_add(struct gb_interface *intf);
void gb_interface_remove(struct gb_interface *intf);
void gb_interface_del(struct gb_interface *intf);
void gb_interface_put(struct gb_interface *intf);

#endif /* __INTERFACE_H */
Loading

0 comments on commit b15d97d

Please sign in to comment.