From 5a218ceba7b64f506bf4f004b04bb457c1805a62 Mon Sep 17 00:00:00 2001 From: Carlos Chinea Date: Wed, 4 Apr 2012 14:11:45 +0300 Subject: HSI: hsi: Rework hsi_controller release Use the proper release mechanism for hsi_controller and hsi_ports structures. Free the structures through their associated device release callbacks. Signed-off-by: Carlos Chinea Acked-by: Greg Kroah-Hartman Acked-by: Linus Walleij --- include/linux/hsi/hsi.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hsi/hsi.h b/include/linux/hsi/hsi.h index 4b178067f405..7f3b7262a2b6 100644 --- a/include/linux/hsi/hsi.h +++ b/include/linux/hsi/hsi.h @@ -270,13 +270,13 @@ struct hsi_controller { struct module *owner; unsigned int id; unsigned int num_ports; - struct hsi_port *port; + struct hsi_port **port; }; #define to_hsi_controller(dev) container_of(dev, struct hsi_controller, device) struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags); -void hsi_free_controller(struct hsi_controller *hsi); +void hsi_put_controller(struct hsi_controller *hsi); int hsi_register_controller(struct hsi_controller *hsi); void hsi_unregister_controller(struct hsi_controller *hsi); @@ -294,7 +294,7 @@ static inline void *hsi_controller_drvdata(struct hsi_controller *hsi) static inline struct hsi_port *hsi_find_port_num(struct hsi_controller *hsi, unsigned int num) { - return (num < hsi->num_ports) ? &hsi->port[num] : NULL; + return (num < hsi->num_ports) ? hsi->port[num] : NULL; } /* -- cgit v1.2.3 From ec1c56ff813a198d656d4aa42e5de03e45751bf8 Mon Sep 17 00:00:00 2001 From: Carlos Chinea Date: Wed, 11 Apr 2012 10:55:53 +0300 Subject: HSI: hsi: Rework hsi_event interface Remove custom hack and make use of the notifier chain interfaces for delivering events from the ports to their associated clients. Clients that want to receive port events need to register their callbacks using hsi_register_port_event(). The callbacks can be called in interrupt context. Use hsi_unregestier_port_event() to undo the registration. Signed-off-by: Carlos Chinea Acked-by: Greg Kroah-Hartman Acked-by: Linus Walleij --- include/linux/hsi/hsi.h | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hsi/hsi.h b/include/linux/hsi/hsi.h index 7f3b7262a2b6..56fae865e272 100644 --- a/include/linux/hsi/hsi.h +++ b/include/linux/hsi/hsi.h @@ -26,9 +26,9 @@ #include #include #include -#include #include #include +#include /* HSI message ttype */ #define HSI_MSG_READ 0 @@ -121,18 +121,18 @@ static inline int hsi_register_board_info(struct hsi_board_info const *info, * @device: Driver model representation of the device * @tx_cfg: HSI TX configuration * @rx_cfg: HSI RX configuration - * @hsi_start_rx: Called after incoming wake line goes high - * @hsi_stop_rx: Called after incoming wake line goes low + * @e_handler: Callback for handling port events (RX Wake High/Low) + * @pclaimed: Keeps tracks if the clients claimed its associated HSI port + * @nb: Notifier block for port events */ struct hsi_client { struct device device; struct hsi_config tx_cfg; struct hsi_config rx_cfg; - void (*hsi_start_rx)(struct hsi_client *cl); - void (*hsi_stop_rx)(struct hsi_client *cl); /* private: */ + void (*ehandler)(struct hsi_client *, unsigned long); unsigned int pclaimed:1; - struct list_head link; + struct notifier_block nb; }; #define to_hsi_client(dev) container_of(dev, struct hsi_client, device) @@ -147,6 +147,10 @@ static inline void *hsi_client_drvdata(struct hsi_client *cl) return dev_get_drvdata(&cl->device); } +int hsi_register_port_event(struct hsi_client *cl, + void (*handler)(struct hsi_client *, unsigned long)); +int hsi_unregister_port_event(struct hsi_client *cl); + /** * struct hsi_client_driver - Driver associated to an HSI client * @driver: Driver model representation of the driver @@ -214,8 +218,7 @@ void hsi_free_msg(struct hsi_msg *msg); * @start_tx: Callback to inform that a client wants to TX data * @stop_tx: Callback to inform that a client no longer wishes to TX data * @release: Callback to inform that a client no longer uses the port - * @clients: List of hsi_clients using the port. - * @clock: Lock to serialize access to the clients list. + * @n_head: Notifier chain for signaling port events to the clients. */ struct hsi_port { struct device device; @@ -231,14 +234,14 @@ struct hsi_port { int (*start_tx)(struct hsi_client *cl); int (*stop_tx)(struct hsi_client *cl); int (*release)(struct hsi_client *cl); - struct list_head clients; - spinlock_t clock; + /* private */ + struct atomic_notifier_head n_head; }; #define to_hsi_port(dev) container_of(dev, struct hsi_port, device) #define hsi_get_port(cl) to_hsi_port((cl)->device.parent) -void hsi_event(struct hsi_port *port, unsigned int event); +int hsi_event(struct hsi_port *port, unsigned long event); int hsi_claim_port(struct hsi_client *cl, unsigned int share); void hsi_release_port(struct hsi_client *cl); -- cgit v1.2.3