&dev_attr_description.attr,
NULL
};
-ATTRIBUTE_GROUPS(typec);
+
+static umode_t typec_is_visible(struct kobject *kobj, struct attribute *attr, int n)
+{
+ if (is_typec_partner_altmode(kobj_to_dev(kobj)))
+ return attr->mode;
+ return 0;
+}
+
+static const struct attribute_group typec_group = {
+ .is_visible = typec_is_visible,
+ .attrs = typec_attrs,
+};
+
+static const struct attribute_group *typec_groups[] = {
+ &typec_group,
+ NULL
+};
static int typec_match(struct device *dev, const struct device_driver *driver)
{
struct typec_altmode *altmode = to_typec_altmode(dev);
const struct typec_device_id *id;
+ if (!is_typec_partner_altmode(dev))
+ return 0;
+
for (id = drv->id_table; id->svid; id++)
if (id->svid == altmode->svid)
return 1;
{
const struct typec_altmode *altmode = to_typec_altmode(dev);
+ if (!is_typec_partner_altmode(dev))
+ return 0;
+
if (add_uevent_var(env, "SVID=%04X", altmode->svid))
return -ENOMEM;
#define to_altmode(d) container_of(d, struct altmode, adev)
extern const struct bus_type typec_bus;
-extern const struct device_type typec_altmode_dev_type;
+extern const struct device_type typec_port_altmode_dev_type;
+extern const struct device_type typec_plug_altmode_dev_type;
+extern const struct device_type typec_partner_altmode_dev_type;
-#define is_typec_altmode(_dev_) (_dev_->type == &typec_altmode_dev_type)
+#define is_typec_port_altmode(dev) ((dev)->type == &typec_port_altmode_dev_type)
+#define is_typec_plug_altmode(dev) ((dev)->type == &typec_plug_altmode_dev_type)
+#define is_typec_partner_altmode(dev) ((dev)->type == &typec_partner_altmode_dev_type)
#endif /* __USB_TYPEC_ALTMODE_H__ */
struct typec_altmode *adev = to_typec_altmode(dev);
const struct typec_device_id *id = data;
- if (!is_typec_altmode(dev))
+ if (!is_typec_port_altmode(dev))
return 0;
return (adev->svid == id->svid);
kfree(alt);
}
-const struct device_type typec_altmode_dev_type = {
- .name = "typec_alternate_mode",
+const struct device_type typec_port_altmode_dev_type = {
+ .name = "typec_port_alternate_mode",
+ .groups = typec_altmode_groups,
+ .release = typec_altmode_release,
+};
+
+const struct device_type typec_plug_altmode_dev_type = {
+ .name = "typec_plug_alternate_mode",
+ .groups = typec_altmode_groups,
+ .release = typec_altmode_release,
+};
+
+const struct device_type typec_partner_altmode_dev_type = {
+ .name = "typec_partner_alternate_mode",
.groups = typec_altmode_groups,
.release = typec_altmode_release,
};
static struct typec_altmode *
typec_register_altmode(struct device *parent,
- const struct typec_altmode_desc *desc)
+ const struct typec_altmode_desc *desc,
+ const struct device_type *type)
{
unsigned int id = altmode_id_get(parent);
bool is_port = is_typec_port(parent);
alt->adev.dev.parent = parent;
alt->adev.dev.groups = alt->groups;
- alt->adev.dev.type = &typec_altmode_dev_type;
+ alt->adev.dev.type = type;
dev_set_name(&alt->adev.dev, "%s.%u", dev_name(parent), id);
get_device(alt->adev.dev.parent);
if (!is_port)
typec_altmode_set_partner(alt);
- /* The partners are bind to drivers */
- if (is_typec_partner(parent))
- alt->adev.dev.bus = &typec_bus;
+ alt->adev.dev.bus = &typec_bus;
/* Plug alt modes need a class to generate udev events. */
if (is_typec_plug(parent))
typec_partner_register_altmode(struct typec_partner *partner,
const struct typec_altmode_desc *desc)
{
- return typec_register_altmode(&partner->dev, desc);
+ return typec_register_altmode(&partner->dev, desc, &typec_partner_altmode_dev_type);
}
EXPORT_SYMBOL_GPL(typec_partner_register_altmode);
typec_plug_register_altmode(struct typec_plug *plug,
const struct typec_altmode_desc *desc)
{
- return typec_register_altmode(&plug->dev, desc);
+ return typec_register_altmode(&plug->dev, desc, &typec_plug_altmode_dev_type);
}
EXPORT_SYMBOL_GPL(typec_plug_register_altmode);
return ERR_CAST(retimer);
}
- adev = typec_register_altmode(&port->dev, desc);
+ adev = typec_register_altmode(&port->dev, desc, &typec_port_altmode_dev_type);
if (IS_ERR(adev)) {
typec_retimer_put(retimer);
typec_mux_put(mux);