aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Reichel <sre@kernel.org>2014-03-28 17:54:25 -0400
committerSebastian Reichel <sre@kernel.org>2014-05-15 18:54:41 -0400
commit8491451024bcfabdcebd772ce9ec2fc5757acd42 (patch)
treeb8e73b934b21f47abacfd17fecc608dd2b140084
parenta088cf161cc87b39e83c7c53b9f239773422d212 (diff)
HSI: export method to (un)register clients
Expose method for registering and unregistering HSI clients, so that client drivers can register other client drivers. This is useful for HSI drivers, which want to use the functionality of other HSI drivers. For example the N900 modem driver can load HSI drivers for mcsaab protocol and speech protocol. Signed-off-by: Sebastian Reichel <sre@kernel.org> Reviewed-by: Pavel Machek <pavel@ucw.cz> Tested-By: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
-rw-r--r--drivers/hsi/hsi.c11
-rw-r--r--include/linux/hsi/hsi.h3
2 files changed, 11 insertions, 3 deletions
diff --git a/drivers/hsi/hsi.c b/drivers/hsi/hsi.c
index de2ad8f20d55..834a2d6b444e 100644
--- a/drivers/hsi/hsi.c
+++ b/drivers/hsi/hsi.c
@@ -69,14 +69,15 @@ static void hsi_client_release(struct device *dev)
69 kfree(cl); 69 kfree(cl);
70} 70}
71 71
72static void hsi_new_client(struct hsi_port *port, struct hsi_board_info *info) 72struct hsi_client *hsi_new_client(struct hsi_port *port,
73 struct hsi_board_info *info)
73{ 74{
74 struct hsi_client *cl; 75 struct hsi_client *cl;
75 size_t size; 76 size_t size;
76 77
77 cl = kzalloc(sizeof(*cl), GFP_KERNEL); 78 cl = kzalloc(sizeof(*cl), GFP_KERNEL);
78 if (!cl) 79 if (!cl)
79 return; 80 return NULL;
80 81
81 cl->tx_cfg = info->tx_cfg; 82 cl->tx_cfg = info->tx_cfg;
82 if (cl->tx_cfg.channels) { 83 if (cl->tx_cfg.channels) {
@@ -103,7 +104,10 @@ static void hsi_new_client(struct hsi_port *port, struct hsi_board_info *info)
103 pr_err("hsi: failed to register client: %s\n", info->name); 104 pr_err("hsi: failed to register client: %s\n", info->name);
104 put_device(&cl->device); 105 put_device(&cl->device);
105 } 106 }
107
108 return cl;
106} 109}
110EXPORT_SYMBOL_GPL(hsi_new_client);
107 111
108static void hsi_scan_board_info(struct hsi_controller *hsi) 112static void hsi_scan_board_info(struct hsi_controller *hsi)
109{ 113{
@@ -119,12 +123,13 @@ static void hsi_scan_board_info(struct hsi_controller *hsi)
119 } 123 }
120} 124}
121 125
122static int hsi_remove_client(struct device *dev, void *data __maybe_unused) 126int hsi_remove_client(struct device *dev, void *data __maybe_unused)
123{ 127{
124 device_unregister(dev); 128 device_unregister(dev);
125 129
126 return 0; 130 return 0;
127} 131}
132EXPORT_SYMBOL_GPL(hsi_remove_client);
128 133
129static int hsi_remove_port(struct device *dev, void *data __maybe_unused) 134static int hsi_remove_port(struct device *dev, void *data __maybe_unused)
130{ 135{
diff --git a/include/linux/hsi/hsi.h b/include/linux/hsi/hsi.h
index e3cff94bef04..e20a3999a696 100644
--- a/include/linux/hsi/hsi.h
+++ b/include/linux/hsi/hsi.h
@@ -296,6 +296,9 @@ struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags);
296void hsi_put_controller(struct hsi_controller *hsi); 296void hsi_put_controller(struct hsi_controller *hsi);
297int hsi_register_controller(struct hsi_controller *hsi); 297int hsi_register_controller(struct hsi_controller *hsi);
298void hsi_unregister_controller(struct hsi_controller *hsi); 298void hsi_unregister_controller(struct hsi_controller *hsi);
299struct hsi_client *hsi_new_client(struct hsi_port *port,
300 struct hsi_board_info *info);
301int hsi_remove_client(struct device *dev, void *data);
299void hsi_port_unregister_clients(struct hsi_port *port); 302void hsi_port_unregister_clients(struct hsi_port *port);
300 303
301static inline void hsi_controller_set_drvdata(struct hsi_controller *hsi, 304static inline void hsi_controller_set_drvdata(struct hsi_controller *hsi,