Loading Documentation/devicetree/bindings/esoc/esoc_client.txt 0 → 100644 +58 −0 Original line number Diff line number Diff line == Introduction == In case of multiple external socs each exposing more than one interface to a primary SOC, it is possible for the different interface drivers/clients to expect notifications regarding the state of the external soc that they are interested in. In some cases clients may need notifications of the status of multiple external socs. The bindings referred to below enable a client device to register for notifications from multiple external socs. == Esoc client devices == For each esoc client device, every external soc that it is associated with, is assigned an integer id. These ids start at 0 and are contiguous. Each id represents a unique external soc. Each external soc is additionally assigned a name. An additional property is used to spcify the names. A mapping is performed from the name to the id. Required properties: esoc-0: A phandle pointing to the esoc node that the esoc client is interested in. esoc-names: A list of string names for all the esocs that a given client is interested in. Must have atleast one name corresponding to esoc-0. Optional properties: esoc-1: A phandle to the external soc, mapping to the second name in esoc-names. ... esoc-n: A phandle to the nth external soc mapping to the nth name in the esoc-names == Example == esoc_a { compatible = "esoc_mdm"; .... ... .. }; esoc_b { compatible = "esoc_wlan"; .. .. }; pcie@0x0001 { compatible = "esoc-pcie-client" .... .. .. esoc-names = "mdm", "wlan"; esoc-0 = <&esoc_a>; esoc-1 = <&esoc_b>; .. .. }; drivers/esoc/Kconfig +9 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,15 @@ config ESOC_DEV for the external soc. It can receive event notifications from the control link. config ESOC_CLIENT bool "ESOC client interface" depends on OF help Say yes here to enable client interface for external socs. Clients can specify the external soc that they are interested in by using device tree phandles. Based on this, clients can register for notifications from a specific soc. config ESOC_DEBUG bool "ESOC debug support" help Loading drivers/esoc/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -3,5 +3,6 @@ ccflags-$(CONFIG_ESOC_DEBUG) := -DDEBUG obj-$(CONFIG_ESOC) += esoc_bus.o obj-$(CONFIG_ESOC_DEV) += esoc_dev.o obj-$(CONFIG_ESOC_CLIENT) += esoc_client.o obj-$(CONFIG_ESOC_MDM_4x) += esoc-mdm-4x.o obj-$(CONFIG_ESOC_MDM_DRV) += esoc-mdm-drv.o drivers/esoc/esoc.h +13 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ struct esoc_eng { * @compat_data: compat data of esoc driver. * @subsys_desc: descriptor for subsystem restart * @subsys_dev: ssr device handle. * @np: device tree node for esoc_clink. */ struct esoc_clink { const char *name; Loading @@ -73,6 +74,7 @@ struct esoc_clink { void *compat_data; struct subsys_desc subsys; struct subsys_device *subsys_dev; struct device_node *np; }; /** Loading Loading @@ -125,6 +127,7 @@ int esoc_dev_init(void); void esoc_clink_unregister(struct esoc_clink *esoc_dev); int esoc_clink_register(struct esoc_clink *esoc_dev); struct esoc_clink *get_esoc_clink(int id); struct esoc_clink *get_esoc_clink_by_node(struct device_node *node); void put_esoc_clink(struct esoc_clink *esoc_clink); void *get_esoc_clink_data(struct esoc_clink *esoc); void set_esoc_clink_data(struct esoc_clink *esoc, void *data); Loading @@ -147,4 +150,14 @@ void *esoc_get_drv_data(struct esoc_clink *esoc_clink); int esoc_clink_register_ssr(struct esoc_clink *esoc_clink); int esoc_clink_request_ssr(struct esoc_clink *esoc_clink); void esoc_clink_unregister_ssr(struct esoc_clink *esoc_clink); /* client notification */ #ifdef CONFIG_ESOC_CLIENT void notify_esoc_clients(struct esoc_clink *esoc_clink, unsigned long evt); #else static inline void notify_esoc_clients(struct esoc_clink *esoc_clink, unsigned long evt) { return; } #endif #endif drivers/esoc/esoc_bus.c +27 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,19 @@ static int esoc_clink_match_id(struct device *dev, void *id) return 0; } static int esoc_clink_match_node(struct device *dev, void *id) { struct esoc_clink *esoc_clink = to_esoc_clink(dev); struct device_node *node = id; if (esoc_clink->np == node) { if (!try_module_get(esoc_clink->owner)) return 0; return 1; } return 0; } void esoc_for_each_dev(void *data, int (*fn)(struct device *dev, void *)) { int ret; Loading @@ -123,6 +136,19 @@ struct esoc_clink *get_esoc_clink(int id) } EXPORT_SYMBOL(get_esoc_clink); struct esoc_clink *get_esoc_clink_by_node(struct device_node *node) { struct esoc_clink *esoc_clink; struct device *dev; dev = bus_find_device(&esoc_bus_type, NULL, node, esoc_clink_match_node); if (IS_ERR(dev)) return NULL; esoc_clink = to_esoc_clink(dev); return esoc_clink; } void put_esoc_clink(struct esoc_clink *esoc_clink) { module_put(esoc_clink->owner); Loading Loading @@ -176,6 +202,7 @@ void esoc_clink_evt_notify(enum esoc_evt evt, struct esoc_clink *esoc_clink) unsigned long flags; spin_lock_irqsave(&esoc_clink->notify_lock, flags); notify_esoc_clients(esoc_clink, evt); if (esoc_clink->req_eng && esoc_clink->req_eng->handle_clink_evt) esoc_clink->req_eng->handle_clink_evt(evt, esoc_clink->req_eng); if (esoc_clink->cmd_eng && esoc_clink->cmd_eng->handle_clink_evt) Loading Loading
Documentation/devicetree/bindings/esoc/esoc_client.txt 0 → 100644 +58 −0 Original line number Diff line number Diff line == Introduction == In case of multiple external socs each exposing more than one interface to a primary SOC, it is possible for the different interface drivers/clients to expect notifications regarding the state of the external soc that they are interested in. In some cases clients may need notifications of the status of multiple external socs. The bindings referred to below enable a client device to register for notifications from multiple external socs. == Esoc client devices == For each esoc client device, every external soc that it is associated with, is assigned an integer id. These ids start at 0 and are contiguous. Each id represents a unique external soc. Each external soc is additionally assigned a name. An additional property is used to spcify the names. A mapping is performed from the name to the id. Required properties: esoc-0: A phandle pointing to the esoc node that the esoc client is interested in. esoc-names: A list of string names for all the esocs that a given client is interested in. Must have atleast one name corresponding to esoc-0. Optional properties: esoc-1: A phandle to the external soc, mapping to the second name in esoc-names. ... esoc-n: A phandle to the nth external soc mapping to the nth name in the esoc-names == Example == esoc_a { compatible = "esoc_mdm"; .... ... .. }; esoc_b { compatible = "esoc_wlan"; .. .. }; pcie@0x0001 { compatible = "esoc-pcie-client" .... .. .. esoc-names = "mdm", "wlan"; esoc-0 = <&esoc_a>; esoc-1 = <&esoc_b>; .. .. };
drivers/esoc/Kconfig +9 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,15 @@ config ESOC_DEV for the external soc. It can receive event notifications from the control link. config ESOC_CLIENT bool "ESOC client interface" depends on OF help Say yes here to enable client interface for external socs. Clients can specify the external soc that they are interested in by using device tree phandles. Based on this, clients can register for notifications from a specific soc. config ESOC_DEBUG bool "ESOC debug support" help Loading
drivers/esoc/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -3,5 +3,6 @@ ccflags-$(CONFIG_ESOC_DEBUG) := -DDEBUG obj-$(CONFIG_ESOC) += esoc_bus.o obj-$(CONFIG_ESOC_DEV) += esoc_dev.o obj-$(CONFIG_ESOC_CLIENT) += esoc_client.o obj-$(CONFIG_ESOC_MDM_4x) += esoc-mdm-4x.o obj-$(CONFIG_ESOC_MDM_DRV) += esoc-mdm-drv.o
drivers/esoc/esoc.h +13 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ struct esoc_eng { * @compat_data: compat data of esoc driver. * @subsys_desc: descriptor for subsystem restart * @subsys_dev: ssr device handle. * @np: device tree node for esoc_clink. */ struct esoc_clink { const char *name; Loading @@ -73,6 +74,7 @@ struct esoc_clink { void *compat_data; struct subsys_desc subsys; struct subsys_device *subsys_dev; struct device_node *np; }; /** Loading Loading @@ -125,6 +127,7 @@ int esoc_dev_init(void); void esoc_clink_unregister(struct esoc_clink *esoc_dev); int esoc_clink_register(struct esoc_clink *esoc_dev); struct esoc_clink *get_esoc_clink(int id); struct esoc_clink *get_esoc_clink_by_node(struct device_node *node); void put_esoc_clink(struct esoc_clink *esoc_clink); void *get_esoc_clink_data(struct esoc_clink *esoc); void set_esoc_clink_data(struct esoc_clink *esoc, void *data); Loading @@ -147,4 +150,14 @@ void *esoc_get_drv_data(struct esoc_clink *esoc_clink); int esoc_clink_register_ssr(struct esoc_clink *esoc_clink); int esoc_clink_request_ssr(struct esoc_clink *esoc_clink); void esoc_clink_unregister_ssr(struct esoc_clink *esoc_clink); /* client notification */ #ifdef CONFIG_ESOC_CLIENT void notify_esoc_clients(struct esoc_clink *esoc_clink, unsigned long evt); #else static inline void notify_esoc_clients(struct esoc_clink *esoc_clink, unsigned long evt) { return; } #endif #endif
drivers/esoc/esoc_bus.c +27 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,19 @@ static int esoc_clink_match_id(struct device *dev, void *id) return 0; } static int esoc_clink_match_node(struct device *dev, void *id) { struct esoc_clink *esoc_clink = to_esoc_clink(dev); struct device_node *node = id; if (esoc_clink->np == node) { if (!try_module_get(esoc_clink->owner)) return 0; return 1; } return 0; } void esoc_for_each_dev(void *data, int (*fn)(struct device *dev, void *)) { int ret; Loading @@ -123,6 +136,19 @@ struct esoc_clink *get_esoc_clink(int id) } EXPORT_SYMBOL(get_esoc_clink); struct esoc_clink *get_esoc_clink_by_node(struct device_node *node) { struct esoc_clink *esoc_clink; struct device *dev; dev = bus_find_device(&esoc_bus_type, NULL, node, esoc_clink_match_node); if (IS_ERR(dev)) return NULL; esoc_clink = to_esoc_clink(dev); return esoc_clink; } void put_esoc_clink(struct esoc_clink *esoc_clink) { module_put(esoc_clink->owner); Loading Loading @@ -176,6 +202,7 @@ void esoc_clink_evt_notify(enum esoc_evt evt, struct esoc_clink *esoc_clink) unsigned long flags; spin_lock_irqsave(&esoc_clink->notify_lock, flags); notify_esoc_clients(esoc_clink, evt); if (esoc_clink->req_eng && esoc_clink->req_eng->handle_clink_evt) esoc_clink->req_eng->handle_clink_evt(evt, esoc_clink->req_eng); if (esoc_clink->cmd_eng && esoc_clink->cmd_eng->handle_clink_evt) Loading