summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2016-03-30 19:47:04 -0400
committerTakashi Iwai <tiwai@suse.de>2016-03-31 09:36:18 -0400
commit923f92ebb43e7a09915a5708d4805c1e099db46c (patch)
tree09bc1375e8c2992fec3bf9d6b109d624dbf5dd94
parent0eced45ca60666aff4c12f31fef4005ae37e859e (diff)
ALSA: firewire-lib: add new function to schedule a work for sound card registration
In former commit, ALSA dice driver postpone sound card registration after IEEE 1394 bus is calm. This idea has advantages for the other drivers. This commit adds a helper function for it to firewire-lib module. The function is really for the specific purpose. Callers should initialize delayed work structure with callback function. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/firewire/dice/dice.c23
-rw-r--r--sound/firewire/lib.c32
-rw-r--r--sound/firewire/lib.h3
3 files changed, 38 insertions, 20 deletions
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c
index 53ca441ea9b9..96fe68f42e5d 100644
--- a/sound/firewire/dice/dice.c
+++ b/sound/firewire/dice/dice.c
@@ -20,8 +20,6 @@ MODULE_LICENSE("GPL v2");
20#define WEISS_CATEGORY_ID 0x00 20#define WEISS_CATEGORY_ID 0x00
21#define LOUD_CATEGORY_ID 0x10 21#define LOUD_CATEGORY_ID 0x10
22 22
23#define PROBE_DELAY_MS (2 * MSEC_PER_SEC)
24
25/* 23/*
26 * Some models support several isochronous channels, while these streams are not 24 * Some models support several isochronous channels, while these streams are not
27 * always available. In this case, add the model name to this list. 25 * always available. In this case, add the model name to this list.
@@ -235,27 +233,12 @@ static void do_registration(struct work_struct *work)
235error: 233error:
236 snd_dice_stream_destroy_duplex(dice); 234 snd_dice_stream_destroy_duplex(dice);
237 snd_dice_transaction_destroy(dice); 235 snd_dice_transaction_destroy(dice);
236 snd_dice_stream_destroy_duplex(dice);
238 snd_card_free(dice->card); 237 snd_card_free(dice->card);
239 dev_info(&dice->unit->device, 238 dev_info(&dice->unit->device,
240 "Sound card registration failed: %d\n", err); 239 "Sound card registration failed: %d\n", err);
241} 240}
242 241
243static void schedule_registration(struct snd_dice *dice)
244{
245 struct fw_card *fw_card = fw_parent_device(dice->unit)->card;
246 u64 now, delay;
247
248 now = get_jiffies_64();
249 delay = fw_card->reset_jiffies + msecs_to_jiffies(PROBE_DELAY_MS);
250
251 if (time_after64(delay, now))
252 delay -= now;
253 else
254 delay = 0;
255
256 mod_delayed_work(system_wq, &dice->dwork, delay);
257}
258
259static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) 242static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
260{ 243{
261 struct snd_dice *dice; 244 struct snd_dice *dice;
@@ -280,7 +263,7 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
280 263
281 /* Allocate and register this sound card later. */ 264 /* Allocate and register this sound card later. */
282 INIT_DEFERRABLE_WORK(&dice->dwork, do_registration); 265 INIT_DEFERRABLE_WORK(&dice->dwork, do_registration);
283 schedule_registration(dice); 266 snd_fw_schedule_registration(unit, &dice->dwork);
284 267
285 return 0; 268 return 0;
286} 269}
@@ -311,7 +294,7 @@ static void dice_bus_reset(struct fw_unit *unit)
311 294
312 /* Postpone a workqueue for deferred registration. */ 295 /* Postpone a workqueue for deferred registration. */
313 if (!dice->registered) 296 if (!dice->registered)
314 schedule_registration(dice); 297 snd_fw_schedule_registration(unit, &dice->dwork);
315 298
316 /* The handler address register becomes initialized. */ 299 /* The handler address register becomes initialized. */
317 snd_dice_transaction_reinit(dice); 300 snd_dice_transaction_reinit(dice);
diff --git a/sound/firewire/lib.c b/sound/firewire/lib.c
index f80aafa44c89..ca4dfcf43175 100644
--- a/sound/firewire/lib.c
+++ b/sound/firewire/lib.c
@@ -67,6 +67,38 @@ int snd_fw_transaction(struct fw_unit *unit, int tcode,
67} 67}
68EXPORT_SYMBOL(snd_fw_transaction); 68EXPORT_SYMBOL(snd_fw_transaction);
69 69
70#define PROBE_DELAY_MS (2 * MSEC_PER_SEC)
71
72/**
73 * snd_fw_schedule_registration - schedule work for sound card registration
74 * @unit: an instance for unit on IEEE 1394 bus
75 * @dwork: delayed work with callback function
76 *
77 * This function is not designed for general purposes. When new unit is
78 * connected to IEEE 1394 bus, the bus is under bus-reset state because of
79 * topological change. In this state, units tend to fail both of asynchronous
80 * and isochronous communication. To avoid this problem, this function is used
81 * to postpone sound card registration after the state. The callers must
82 * set up instance of delayed work in advance.
83 */
84void snd_fw_schedule_registration(struct fw_unit *unit,
85 struct delayed_work *dwork)
86{
87 u64 now, delay;
88
89 now = get_jiffies_64();
90 delay = fw_parent_device(unit)->card->reset_jiffies
91 + msecs_to_jiffies(PROBE_DELAY_MS);
92
93 if (time_after64(delay, now))
94 delay -= now;
95 else
96 delay = 0;
97
98 mod_delayed_work(system_wq, dwork, delay);
99}
100EXPORT_SYMBOL(snd_fw_schedule_registration);
101
70static void async_midi_port_callback(struct fw_card *card, int rcode, 102static void async_midi_port_callback(struct fw_card *card, int rcode,
71 void *data, size_t length, 103 void *data, size_t length,
72 void *callback_data) 104 void *callback_data)
diff --git a/sound/firewire/lib.h b/sound/firewire/lib.h
index f3f6f84c48d6..f6769312ebfc 100644
--- a/sound/firewire/lib.h
+++ b/sound/firewire/lib.h
@@ -22,6 +22,9 @@ static inline bool rcode_is_permanent_error(int rcode)
22 return rcode == RCODE_TYPE_ERROR || rcode == RCODE_ADDRESS_ERROR; 22 return rcode == RCODE_TYPE_ERROR || rcode == RCODE_ADDRESS_ERROR;
23} 23}
24 24
25void snd_fw_schedule_registration(struct fw_unit *unit,
26 struct delayed_work *dwork);
27
25struct snd_fw_async_midi_port; 28struct snd_fw_async_midi_port;
26typedef int (*snd_fw_async_midi_port_fill)( 29typedef int (*snd_fw_async_midi_port_fill)(
27 struct snd_rawmidi_substream *substream, 30 struct snd_rawmidi_substream *substream,